geogread.pro
8.55 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
;+
; NAME:
; GEOGREAD
;
; AUTHOR:
; Craig B. Markwardt, NASA/GSFC Code 662, Greenbelt, MD 20770
; craigm@lheamail.gsfc.nasa.gov
; UPDATED VERSIONs can be found on my WEB PAGE:
; http://cow.physics.wisc.edu/~craigm/idl/idl.html
;
; PURPOSE:
; Read gravity model from disk file
;
; MAJOR TOPICS:
; Physics, Gravity, Geodesy, Spacecraft Navigation
;
; CALLING SEQUENCE:
; GEOGREAD, ROOTFILE, MODEL [, STATUS=STATUS, ERRMSG=ERRMSG,
; /COEFF_ERR]
;
; DESCRIPTION:
;
; GEOGREAD reads a gravity model from a disk file. The gravity
; model must have already been prepared. There are a number of
; freely available models.
;
; Each model must have a "description" file which describes, in IDL
; syntax, the name, content and format of the model file. The
; ROOTFILE parameter is the name of this description file. The
; description must provide the name of the model file (the FILENAME
; field), which must reside in the same directory.
;
; FILE FORMAT:
;
; The format of the description file (and hence also the format of
; the structure returned in GEOGMOD), is as follows, an example
; modified from egm96.desc:
;
; { $
; name: 'EGM96', $ ;; Title of the model
; type: 'GRAVITY', $ ;; Type of model 'GRAVITY' or 'BFIELD'
; filename: 'EGM96.GEO', $ ;; Model coefficient file name (same dir)
; reference: 'Lemoine, ...' ;; Complete literature reference
; url: 'ftp://ftp.csr.utexas.edu/pub/grav/EGM96.GEO.Z', $ ;; Source URL
; nmax: 360L, $ ;; Maximum order (inclusive)
; mmax: 360L, $ ;; Maximum degree (inclusive)
; normalized: 1, $ ;; Coefficients are normalized (1=yes, 0=no)
; mu: 398600.44150D+09, $ ;; GM for central body [m^3/s^2]
; a: 6378136.30d, $ ;; Mean equatorial radius [m]
; tide: 'ZERO', $ ;; Tide system (ZERO, FREE, or MEAN)
; epoch: 1986.0d, $ ;; Epoch of model coefficients (Julian year)
; C21: -.1869876359548955D-09,$ ;; C21 coefficient (if not in Cnm table)
; S21: .1195280120306540D-08,$ ;; S21 coefficient (if not in Cnm table)
; C20_dot: 1.16275534D-11,$ ;; C20 rate (unitless; yr^-1)
; C21_dot: -0.32d-11, $ ;; C21 rate (unitless; yr^-1)
; S21_dot: +1.62d-11, $ ;; S21 rate (unitless; yr^-1)
; rowstart: 4L, $ ;; Coefficient starting row (first row = 0)
; nrows: 65338L, $ ;; Number of coefficient rows in file
; ncolrange: [6,8], $ ;; Column range for degree (first col = 0)
; mcolrange: [9,11], $ ;; " " " order
; Ccolrange: [12,30], $ ;; " " " C coefficients
; Scolrange: [31,49], $ ;; " " " S coefficients
; dCcolrange: [50,62], $ ;; " " " C std deviation
; dScolrange: [63,75] $ ;; " " " S std deviation
; }
;
; The xCOLRANGE fields describe which character columns in the model
; file, inclusive, contain the quantity of interest. You can use a
; text editor which reports the column number to find these values.
; Exclude any character columns that contain field delimiters such
; as commas.
;
; Since the C21 and S21 coefficients are commonly not included in
; the table itself, their values are allowed to be specified in the
; description file. If the coefficients *are* in the table, then
; they must be set to zero in the description file to avoid double
; computations. The coefficient rates can be used to extrapolate to
; different epochs from the reference epoch (specified by EPOCH).
;
;
; INPUTS:
;
; ROOTFILE - scalar string, the name of the model description file.
;
; GEOGMOD - upon return, an IDL structure containing the model
; information. In addition to the fields listed above,
; other fields are appended which contain (pointers to)
; the coefficient data, etc.
;
; KEYWORD PARAMETERS:
;
; STATUS - upon return, a status indicator. A value of 1 is OK, 0
; indicates an error condition.
;
; ERRMSG - upon return, an error message, if any. If no error
; occurred, then ERRMSG is set to ''.
;
; CEOFF_ERR - if set, then coefficient standard deviations are also
; read in.q
;
;
; EXAMPLE:
; GEOGREAD, 'egm96', egm96
; GEOGRAV, egm96, r, phi, a
;
; Read the gravity model "EGM96" and evaluate it at position "R" in
; body coordinates. The potential and acceleration are returned in
; PHI and A.
;
; MODIFICATION HISTORY:
; Documentation additions, CM, 26 Sep 2004
;
; $Id: geogread.pro,v 1.3 2004/09/26 14:58:19 craigm Exp $
;
;-
; Copyright (C) 2004, Craig Markwardt
; This software is provided as is without any warranty whatsoever.
; Permission to use, copy, modify, and distribute modified or
; unmodified copies is granted, provided this copyright and disclaimer
; are included unchanged.
;-
pro geogread, rootfile, geogmod, status=status, errmsg=errmsg, $
coeff_err=cerr
status = 0
errmsg = ''
if n_params() EQ 0 then begin
message, 'USAGE: GEOGREAD, ROOTFILE, GEOGMOD [, STATUS=, ERRMSG=]', /info
return
endif
openr, unit, rootfile, /get_lun, error=err
if err NE 0 then begin
errmsg = 'ERROR: could not open '+rootfile
return
endif
rootstr = ''
on_ioerror, DONE_ROOTFILE
while NOT eof(unit) do begin
s = ''
readf, unit, s
s = strtrim(s,2)
if s NE '' then begin
p = strpos(s, '$')
if p GE 0 then s = strtrim(strmid(s,0,p),2)
p = strpos(s, ';')
if p GE 0 then s = strtrim(strmid(s,0,p),2)
if s NE '' then rootstr = rootstr + s
endif
endwhile
DONE_ROOTFILE:
free_lun, unit
if rootstr EQ '' then begin
errmsg = 'ERROR: no data found in '+rootfile
return
endif
temp = strlowcase(rootstr)
if strpos(temp,'execute') GE 0 OR strpos(temp,'call_') GE 0 $
OR strpos(temp,'spawn') GE 0 OR strpos(temp,'openw') GE 0 then begin
errmsg = 'ERROR: '+rootfile+' contains insecure commands'
return
endif
cmdstr = 'geogmod = '+rootstr
dummy = execute(cmdstr)
if dummy NE 1 then begin
errmsg = 'ERROR: could not parse structure in '+rootfile
return
endif
sz = size(geogmod)
if sz(sz(0)+1) NE 8 then begin
errmsg = 'ERROR: structure not found in '+rootfile
return
endif
tn = strlowcase(tag_names(geogmod))
if max(tn EQ 'filename') EQ 0 OR max(tn EQ 'type') EQ 0 OR $
max(tn EQ 'a') EQ 0 OR max(tn EQ 'mu') EQ 0 OR $
max(tn EQ 'nmax') EQ 0 OR max(tn EQ 'mmax') EQ 0 OR $
max(tn EQ 'nrows') EQ 0 OR max(tn EQ 'rowstart') EQ 0 OR $
max(tn EQ 'ncolrange') EQ 0 OR max(tn EQ 'mcolrange') EQ 0 OR $
max(tn EQ 'ccolrange') EQ 0 OR max(tn EQ 'scolrange') EQ 0 then begin
errmsg = 'ERROR: structure did not contain required fields in '+rootfile
return
endif
ps = path_sep()
p = rstrpos(rootfile, ps)
if p GE 0 then path = strmid(rootfile,0,p+1) $
else path = ''
file = path + geogmod.filename
openr, unit, file, /get_lun, error=err
if err NE 0 then begin
errmsg = 'ERROR: could not open '+file
return
endif
nrows = geogmod.nrows
reading = 1
on_ioerror, DONE_READING
str = strarr(geogmod.rowstart)
readf, unit, str
str = strarr(nrows)
readf, unit, str
reading = 0
DONE_READING:
free_lun, unit
if reading then begin
errmsg = 'ERROR: could not read coefficient rows from '+file
return
endif
rng = geogmod.ncolrange & n = long(strmid(str,rng(0),rng(1)-rng(0)+1))
rng = geogmod.mcolrange & m = long(strmid(str,rng(0),rng(1)-rng(0)+1))
rng = geogmod.Ccolrange & C = double(strmid(str,rng(0), rng(1)-rng(0)+1))
rng = geogmod.Scolrange & S = double(strmid(str,rng(0), rng(1)-rng(0)+1))
if keyword_set(cerr) then begin
rng = geogmod.dCcolrange & dC = double(strmid(str,rng(0), rng(1)-rng(0)+1))
rng = geogmod.dScolrange & dS = double(strmid(str,rng(0), rng(1)-rng(0)+1))
endif
str = 0
Cnm = dblarr(geogmod.nmax+1,geogmod.mmax+1)
Snm = Cnm
if keyword_set(cerr) then begin
dCnm = Cnm
dSnm = Cnm
dCnm(n,m) = temporary(dC) & dSnm(n,m) = temporary(dS)
endif
Cnm(0,0) = 1
Cnm(n,m) = temporary(C) & Snm(n,m) = temporary(S)
geogmod = create_struct(geogmod, $
'Cnm', ptr_new(Cnm, /no_copy), $
'Snm', ptr_new(Snm, /no_copy))
if keyword_set(cerr) then begin
geogmod = create_struct(geogmod, $
'dCnm', ptr_new(dCnm, /no_copy), $
'dSnm', ptr_new(dSnm, /no_copy))
endif
return
end