-
Notifications
You must be signed in to change notification settings - Fork 0
/
arrcol_struct.pro
368 lines (312 loc) · 13.2 KB
/
arrcol_struct.pro
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
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
;------------------------------------------------------------------------------
; NAME: ARRCOL_STRUCT
;
; PURPOSE: To construct and IDL structure for a given ARRAY/COLLECTION
; object; intended for use with ARRCOLPDS.PRO
;
; CALLING SEQUENCE: Result = ARRCOL_STRUCT(label, objindex)
;
; INPUTS:
; Label: String array containing ARRAY/COLLECTION header definitions
; Objindex: Integer specifying the index in the label where the
; ARRAY/COLLECTION object starts
; OUTPUTS:
; Result: ARRAY/COLLECTION idl structure constructed from
; designated record
;
; EXAMPLE:
; To construct and IDL structure for VEGA1 PUMA data:
; IDL> label = headpds('mod0bin0.lbl')
; IDL> result = arrcol_struct(label, 20)
;
; IDL> help, /st, result
; ** Structure <820a61c>, 3 tags, length=637248, data length=635454, refs=1:
; FLAG INT 1
; RECORD_ARRAY STRUCT -> <Anonymous> Array[895]
; COUNT INT 23
;
; PROCEDURES USED: ARRAY_STRUCT, COLL_STRUCT, ELEM_STRUCT, GET_INDEX, OBJPDS,
; PDSPAR, REMOVE
;
; MODIFICATION HISTORY:
; Written by Puneet Khetarpal [January 23, 2005]
;
;------------------------------------------------------------------------------
;-- level 3 -------------------------------------------------------------------
;------------------------------------------------------------------------------
; precondition: label is a viable PDS label; cur_ind and end_index are
; viable start and end indices for the current object being processed
; postcondition: the name value is extracted from the label for the
; current object and returned.
function extract_name, label, objindex, end_index
; initialize variable:
flag = 0 ; name keyword found flag (0: not found, 1: found)
; obtain all names keyword values from label:
names = pdspar (label, "NAME", count=name_count, index=name_index)
if (name_count gt 0) then begin
; obtain index of object just below objindex object:
objects = pdspar(label, "OBJECT", count=objcnt, index=objindices)
objpos = where(objindices gt objindex, cnt)
; get names within the current object and next object indices:
if (cnt gt 0) then begin
greatindex = objindices[objpos[0]]
pos = where (name_index gt objindex and name_index lt $
greatindex, ncnt)
endif else begin
pos = where (name_index gt objindex and name_index lt $
end_index, ncnt)
endelse
; check if there was a name keyword found:
if (ncnt gt 0) then begin
name = names[pos[0]]
flag = 1
endif
endif
if (~flag) then begin
print, "Error: missing required NAME keyword from ARRAY/COLLECTION"
return, "-1"
endif
; convert name to a valid idl name:
pattern = ['"', '(', ')', ',', '.', "'"]
name = remove(name, pattern)
name = idl_validname(name, /convert_all)
return, name
end
;-----------------------------------------------------------------------------
; precondition: label is a viable PDS label; cur_ind and end_index are
; viable start and end indices for the current object being processed
; postcondition: the bytes value is extracted from the label for the
; current object and returned
function extract_bytes, label, cur_ind, end_index
; extract all bytes keyword values from the label:
bytes_all = pdspar (label, "BYTES", count=byte_count, index=byte_index)
if (byte_count eq 0) then begin
print, "Error: missing required BYTES keyword from label"
return, -1
endif else begin
; obtain index of object just below objindex object:
objects = pdspar(label, "OBJECT", count=objcnt, index=objindices)
objpos = where (objindices gt cur_ind, cnt)
; get bytes within the current object and next object indices:
if (cnt gt 0) then begin
greatindex = objindices[objpos[0]]
pos = where (byte_index gt cur_ind and byte_index lt $
greatindex, bcnt)
endif else begin
pos = where (byte_index gt cur_ind and byte_index lt $
end_index, bcnt)
endelse
; check if there was a byte keyword found:
if (bcnt eq 0) then begin
print, "Error: missing required BYTES keyword in ELEMENT/" + $
"COLLECTION object"
return, -1
endif else begin
bytes = fix(clean(bytes_all[pos[0]],/space),type=3)
endelse
endelse
; check validity of bytes value:
if (bytes le 0) then begin
print, "Error: invalid BYTES keyword value specified: " + $
clean(string(bytes), /space)
return, -1
endif
return, bytes
end
;-----------------------------------------------------------------------------
; precondition: label is a viable PDS label; cur_ind and end_index are
; viable start and end indices for the current object being
; processed
; postcondition: the start_byte value is extracted from the label for
; the current object and returned
function extract_start_byte, label, cur_ind, end_index
; initialize variable:
start_byte = -1
; obtain all start_byte keyword values from the label:
start_all = pdspar(label, "START_BYTE", count=startcount, index=startindex)
if (startcount gt 0) then begin
; obtain index of object just below current object:
objects = pdspar(label, "OBJECT", count=objcnt, index=objindices)
objpos = where(objindices gt cur_ind, cnt)
if (cnt gt 0) then begin
greatindex = objindices[objpos[0]]
startpos = where (startindex gt cur_ind and startindex lt $
greatindex)
endif else begin
startpos = where(startindex gt cur_ind and startindex lt end_index)
endelse
; check if there was a start byte keyword found:
if (startpos[0] gt 0) then begin
start_byte = fix(clean(start_all[startpos[0]],/space),type=3)
endif
endif
return, start_byte
end
;-- level 2 -------------------------------------------------------------------
;------------------------------------------------------------------------------
; precondition: object1 and object2 are idl structures containing
; fields of "array", "index", and "count", where the latter former two
; are string and long arrays, respectively.
; postcondition: the object arrays and indices are sorted using
; sequential sort, and returned as a signle idl structure with the
; same fields.
function sort_objects, object1, object2
; initialize variables:
array = [object1.array, object2.array]
index = [object1.index, object2.index]
count = object1.count + object2.count
; go through the indicies and perform sequential sort:
for i = 0, count - 1 do begin
min = i
for j = i + 1, count - 1 do begin
if (index[j] lt index[min]) then begin
min = j
endif
endfor
temp1 = index[i]
temp2 = array[i]
index[i] = index[min]
array[i] = array[min]
index[min] = temp1
array[min] = temp2
endfor
; create structure:
objects = create_struct("array", array, "index", index, "count", count)
return, objects
end
;-----------------------------------------------------------------------------
; precondition: objectname is a scalar string
; postcondition: the objectname is tested for being an element or not,
; return 1 if it is, 0 otherwise.
function is_element, objectname
; find whether the object is an ELEMENT
flag = 0
;; A. Cardesin, 2005-03-29;
;; check wether the string "ELEMENT" is at the end of the objectname.
pos = strpos(objectname, "ELEMENT")
length = strlen(objectname)
if (pos NE -1)&&(pos EQ length-7) then flag = 1
return, flag
end
;-----------------------------------------------------------------------------
; precondition: objectname is a scalar string
; postcondition: the objectname is tested for being an array or not,
; return 1 if it is, 0 otherwise.
function is_array, objectname
; find whether the object is an ARRAY
flag = 0
;; A. Cardesin, 2005-03-29; correction for MEX/SPICAM/UV channel
;; check wether the string "ARRAY" is at the end of the objectname.
pos = strpos(objectname, "ARRAY")
length = strlen(objectname)
if (pos NE -1)&&(pos EQ length-5) then flag = 1
return, flag
end
;-----------------------------------------------------------------------------
; precondition: objectname is a scalar string
; postcondition: the objectname is tested for being a collection or
; not, return 1 if it is, 0 otherwise.
function is_collection, objectname
; find whether the object is a collection
flag = 0
;; A. Cardesin, 2005-03-29;
;; check wether the string "COLLECTION" is at the end of the objectname.
pos = strpos(objectname, "COLLECTION")
length = strlen(objectname)
if (pos NE -1)&&(pos EQ length-10) then flag = 1
return, flag
end
;-- level 1 -------------------------------------------------------------------
;------------------------------------------------------------------------------
; precondition: label is a viable PDS label; objindex is a viable
; start index for current array/collection object
; postcondition: all subobjects associated with the current object are
; extracted, sorted by index order, and returned as a structure
function get_subobjects, label, objindex
; initialize variables:
objstruct = {flag: 1}
; obtain the end object index for the current objindex:
eobjindex = get_index(label, objindex)
if (eobjindex eq -1) then goto, endfunction
; obtain all objects and element objects from label and combine them:
objects = objpds(label, "ALL")
if (objects.flag eq -1) then goto, endfunction
elementobjects = objpds(label, "ELEMENT")
if (elementobjects.flag eq -1) then begin
print, "Error: no sub-objects found for current ARRAY or COLLECTION"
goto, endfunction
endif
objects = sort_objects(objects, elementobjects)
; extract all objects from the label between objindex and eobjindex:
pos = where(objects.index ge objindex and objects.index lt eobjindex, cnt)
if (cnt eq 0) then begin
print, "Error: no sub-objects found for current ARRAY or COLLECTION"
goto, endfunction
endif else begin
objstruct = create_struct(objstruct, "array", objects.array[pos], $
"index", objects.index[pos], "count", n_elements(pos))
endelse
return, objstruct
endfunction:
objstruct.flag = -1
return, objstruct
end
;-----------------------------------------------------------------------------
; precondition: label is a viable PDS label; objects contains all
; viable objects/subobjects of current array/collection object to be
; read
; postcondition: all the objects and subobjects are processed
; recursively and the structures are populated and returned
function process_structs, label, objects
; initialize variables:
struct = {flag: 1}
count = 0 ; counter for object index
flag = 1 ; flag to determine whether all objects have been
; compiled into the structure
; go through each sub object and compile the object structure:
while (flag) do begin
if (is_element(objects.array[count])) then begin
temp_struct = elem_struct(label,objects.index[count])
count = count + 1
endif else if (is_collection(objects.array[count])) then begin
temp_struct = coll_struct (label,objects, count)
endif else if (is_array(objects.array[count])) then begin
temp_struct = arr_struct (label,objects, count)
endif else begin
print, "Error: invalid PDS object found in label for processing."
goto, endfunction
endelse
; check for structure flag:
if (temp_struct.flag eq -1) then goto, endfunction
struct = create_struct(struct, temp_struct.name, temp_struct.element)
if (count eq objects.count) then begin
flag = 0
endif
endwhile
struct = create_struct(struct, "count", count)
return, struct
endfunction:
struct.flag = -1
return, struct
end
;-- level 0 -------------------------------------------------------------------
;------------------------------------------------------------------------------
; precondition: label is a viable PDS label, and objindex is a viable
; start index of the current array/collection object
; postcondition: the idl structure to be read from the label is
; constructed and returned
function arrcol_struct, label, objindex
; error protection:
on_error, 1
; check for the number of arguments:
if (n_params() lt 2) then begin
print, "Syntax: structure = arrcol_struct(label, objindex)"
return, -1
endif
; get sub objects for the current objindex:
objects = get_subobjects (label, objindex)
if (objects.flag eq -1) then return, objects
; compile object structure:
struct = process_structs (label, objects)
return, struct
end