;----------------------------------------------------------------------------- ; NAME: ARRCOLASCPDS ; ; PURPOSE: To read a PDS ASCII ARRAY or COLLECTION object into an idl structure ; ; CALLING SEQUENCE: Result = ARRCOLASCPDS (filename, label, objindex [,/SILENT]) ; ; INPUTS: ; Filename: Scalar string containing the name of the PDS file to read ; Label: String array containing the ARRAY/COLLECTION header definition ; Objindex: Integer specifying the starting index of the current ; ARRAY/COLLECTION object in the label array to be read. ; ; OUTPUTS: ; Result: idl structure constructed from designated record ; ; OPTIONAL INPUTS: ; SILENT: suppresses any messages from the procedure ; ; PROCEDURES USED: ; Functions: CLEAN, GET_INDEX, OBJPDS, PDSPAR, POINTPDS ; ; MODIFICATION HISTORY: ; Written by: Unknown [< Jan 22, 2013] ; Last modified: never ; ; For a complete list of modifications, see changelog.txt file. ; ;----------------------------------------------------------------------------- forward_function create_array, create_collection function obtain_arrcol_architecture, label, objindex, end_objindex ; initialize architecture: arch = "MSB" ; obtain the first data type object for an ELEMENT subobject: data_all = pdspar(label, "DATA_TYPE", count=data_count, index=data_index) pos = where(data_index gt objindex and data_index lt end_objindex, cnt) data_type = data_all[pos[0]] if ((strpos(data_type, "LSB") gt -1) || (strpos(data_type,"PC") gt -1) || $ (strpos(data_type, "VAX") gt -1)) then begin arch = "LSB" endif return, arch end function extract_object_name, label, objindex ; initialize variables: objectname = "-1" ; obtain the line of objindex and split into two using '=': line = label[objindex] if (!version.release gt 5.2) then begin segs = strsplit(line, '=', /extract) endif else begin segs = str_sep(line, '=') ; obsolete in IDL v. > 5.2 endelse ; clean the second element of separated line objectname = clean(segs[1],/space) return, objectname end 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 function is_object,objectname,object result = strtrim(strmid(objectname,strpos(objectname,object)),2) eq object return, result end function create_element,label,objects,soindex,eoindex start_byte = pdspar(label[soindex:eoindex], 'START_BYTE') bytes = pdspar(label[soindex:eoindex], 'BYTES') data_type = pdspar(label[soindex:eoindex], 'DATA_TYPE') format = pdspar(label[soindex:eoindex], 'FORMAT') name = strupcase(strtrim(pdspar(label[soindex:eoindex], 'NAME'))) name = strmid(name,1,strlen(name)-2) result = create_struct(name,bytarr(bytes),'delimiter',0B) return, result end function create_collection,label,objects,soindex,eoindex pos = where(objects.index gt soindex and objects.index lt eoindex, cnt) for i=0,cnt-1 do begin index = pos[i] if (is_object(objects.array[index],'ELEMENT')) then begin end_objindex = get_index(label, objects.index[index]) temp = create_element(label, objects, objects.index[index], end_objindex) endif else if (is_object(objects.array[index],'ARRAY')) then begin end_objindex = get_index(label, objects.index[index]) temp = create_array(label, objects, objects.index[index], end_objindex) i = i+1 endif else if (is_object(objects.array[index],'COLLECTION')) then begin end_objindex = get_index(label, objects.index[index]) temp = create_collection(label, objects,objects.index[index], end_objindex) endif result = (n_elements(result) eq 0) ? create_struct('element'+strtrim(string(i),2),temp) : create_struct(result,'element'+strtrim(string(i),2),temp) endfor return, result end function create_array,label,objects,soindex,eoindex pos = where(objects.index gt soindex and objects.index lt eoindex, cnt) subobject_index = objects.index(pos[0]) subobject_eindex = get_index(label, subobject_index) if (is_object(objects.array(pos[0]),'ELEMENT')) then begin end_objindex = get_index(label, objects.index(pos[0])) temp = create_element(label, objects, objects.index(pos[0]), end_objindex) endif else if (is_object(objects.array(pos[0]),'ARRAY')) then begin end_objindex = get_index(label, objects.index(pos[0])) temp = create_array(label, objects, objects.index(pos[0]), end_objindex) endif else if (is_object(objects.array(pos[0]),'COLLECTION')) then begin end_objindex = get_index(label, objects.index(pos[0])) temp = create_collection(label, objects,objects.index(pos[0]), end_objindex) endif axes = pdspar(label[soindex:eoindex], 'AXES') axes = uint(axes[0]) axis_items = strtrim(pdspar(label[soindex:eoindex], 'AXIS_ITEMS'),2) if (axes gt 1) then begin axis_items = strmid(axis_items,strpos(axis_items,'(')+1,strlen(axis_items)-2) axis_items = uint(strsplit(axis_items,',',/EXTRACT)) endif else axis_items = uint(axis_items[0]) case axes of 1: result = replicate(temp,axis_items[0]) 2: result = replicate(temp,axis_items[0],axis_items[1]) 3: result = replicate(temp,axis_items[0],axis_items[1],axis_items[2]) 4: result = replicate(temp,axis_items[0],axis_items[1],axis_items[2],axis_items[3]) endcase return, result end function get_subobjects_arrcol, label, start_index, end_index objects = objpds(label, "ALL") elementobjects = objpds(label, "ELEMENT") objects = sort_objects(objects, elementobjects) return,objects end function organize_struct, structure, name names = tag_names(structure) for i=0,n_tags(structure)-1 do begin if (names(i) eq 'DELIMITER') then continue if (size(structure.(i),/type) eq 8) then temp = organize_struct(structure.(i),names(i)) $ else begin temp = create_struct(names(i),STRING(structure.(i))) endelse result = (n_elements(result) gt 0) ? create_struct(result,temp) : create_struct(temp) endfor return,result end function organize_data, read_struct if (size(read_struct,/type) eq 8) then begin result = organize_struct(read_struct) endif return, result end function arrcolascpds, filename, label, objindex, SILENT=silent ; error protection: on_error, 1 ; check for the number of arguments: if (n_params() lt 3) then begin print, "Syntax: result = arrcolpds(file, label, objectindex, /SILENT)" goto, endfunction endif st = keyword_set(SILENT) ; obtain end object index: end_objindex = get_index(label, objindex) if (end_objindex eq -1) then begin goto, endfunction endif ; obtain object name at objindex: objname = extract_object_name(label, objindex) ;; Create structure to read data in objects = get_subobjects_arrcol(label, objindex, end_objindex) if (is_object(objects.array[0],'ARRAY')) then begin end_objindex = get_index(label, objects.index[0]) read_struct = create_array(label, objects, objects.index[0], end_objindex) endif else if (is_object(objects.array[0],'COLLECTION')) then begin end_objindex = get_index(label, objects.index[0]) read_struct = create_collection(label, objects,objects.index[0], end_objindex) endif ; obtain object pointer: pointer = pointpds(label, filename, objname) if (pointer.flag eq -1) then goto, endfunction ; obtain array / collection data architecture: arch = obtain_arrcol_architecture(label, objindex, end_objindex) ; read the structure off the file: if (~st) then begin print, "Now reading ARRAY/COLLECTION object" endif if (arch eq "MSB") then begin openr, unit, pointer.datafile, /get_lun, /swap_if_little_endian endif else begin openr, unit, pointer.datafile, /get_lun, /swap_if_big_endian endelse point_lun, unit, pointer.skip if (n_elements(read_struct) gt 1) then $ for i=0ULL,n_elements(read_struct)-2 do begin first = (n_elements(first) eq 0) ? [read_struct(i)] : [first,read_struct(i)] endfor last = read_struct(n_elements(read_struct)-1) if ((n_elements(first) ne 0)) then readu,unit,first ;; Remove last delimiter from last structure element before reading from file data_length = n_tags(last,/data_length) last_data = bytarr(data_length-1) ;; last delimiter does not exist in file readu,unit,last_data last_data = [last_data,44B] reads,last_data,last result = ((n_elements(first) eq 0)) ? [last] : [first,last] close, unit free_lun, unit data = organize_data(result) return, data endfunction: return, -1 end