;***************************************************************************** ; ; File: OAL_IDL_interface.pro ; ; Description: This file contains IDL routines for the IDL interface of ; the PDS OAL (Object Access Library) and L3 (Label Library Lite). ; These wrappers allow users to write application code in IDL just as ; they would in C, call OAL and L3 routines from IDL, and get PDS ; objects into IDL variables. ; The OA library, L3 and OAL_IDL_interface.c must be compiled and ; linked into a shareable, dynamically-linked library using the ; provided Makefile. Internally the interface code uses the IDL ; function CALL_EXTERNAL to call routines in the library. ; ; Supported Platforms: ; The interface has been tested on the following platforms: ; ; 1) Sun SPARCstation/SunOS & Solaris ; 2) SGI/IRIX ; 3) Dec Alpha/OSF ; 4) PowerMacintosh/CodeWarrier ; ; Installation: ; THERE ARE TWO PLACES IN THIS FILE YOU MUST EDIT WHEN YOU FIRST USE ; THE CODE OR MOVE THE SHARED OBJECT FILE TO A NEW LOCATION: ; ; 1. Change OAL_SHARED_LIB_NAME in OaIDLCall (the first routine ; below this header) to be the path name of your shared ; libary file. ; 2. Change LABEL_DIR in OaIDLReadObject (the last routine in ; this file, just above the global variable/enumerated type ; declarations) to point to the directory where OAL and L3 ; can write error files to (ODL_ERRORS.TXT and OAL_ERRORS.TXT). ; 3. If the first call you're making isn't to OaIDLReadObject, then it ; is advisable to call OaRouteErrorMessages in order to prevent ; screen output. This is important, because otherwise OAL's ; error reporting function, OaReportError, will attempt to write to ; standard error output, which IDL does not like (it eventually ; crashes or hangs, depending on platform). Example call: ; ; Z = OaRouteErrorMessages( LABEL_DIR + 'OAL_ERRORS.TXT', 0) ; ; Routines: ; The IDL routines in this file are: ; ; OaIDLCall ; OaIDLGetOaObjectStruct ; OaIDLGetODLTreeNodeStruct ; OaIDLGetProfile ; OaIDLSetProfile ; IDL-callable wrappers for OAL C macros ; IDL-callable wrappers for OA Object Layer routines ; IDL-callable wrappers for L3 routines ; OaIDLGetObjectData ; OaIDLVariabletoOaObject ; OaIDLReadObject ; ; Author: Steve Monk, University of Colorado LASP ; ; Creation Date: 7 Feb 1996 ; Last Modified: 4 Mar 1996 ; ; History: ; ; Creation - Most of these routines were part of Release 1.1 of the OA ; library. ; ; Notes: ; ; 1) Pointers: ; Pointers returned from OAL and L3 are stored in IDL 'double' variables. ; This scheme makes the interface run on all platforms, notably the Dec ; Alpha, which uses 8-byte pointers. A NULL pointer is represented by ; 0.0. These pointers are inscrutable within IDL; they can only be ; stored, perhaps compared, and become useful only when passed back into ; OAL, L3 and other interface functions. ; ; 2) OA_OBJECT and ODLTREE structures: ; Functions are provided to get the fields of OA_OBJECT structures and ; ODLTREE structures into IDL. Although individual node pointers can be ; stored in IDL, the actual linked tree structure is not directly ; accessible in IDL. This is not a limitation, because all L3 tree ; manipulation functions can be called from IDL. ; ; 3) Calling sequences: ; OAL and L3 functions can be called from IDL code by using the same ; function name and closest IDL equivalents of the function's C arguments, ; as documented in the OAL and L3 User's Guides. The IDL routines which ; are called are referred to as "wrappers", since they contain only a short ; bit of code around the call to the actual C function. All the wrappers ; cast IDL integer and long variables to the type required by the C ; function, so the user does not need to worry about whether to pass an ; IDL int or long. ; ; 4) Function naming conventions: ; All OAL and L3 functions are named the same as in C (as documented ; in the OAL and L3 User's Guides) and start with "Oa" or "Odl". ; Functions which are part of the interface itself start with "OaIDL", ; and are not normally called by users, except for OaIDLGetObjectData and ; OaIDLVariabletoOaObject, which translate OA object data to and from IDL ; variables. ; ; 5) Enumerated types commonly used in calling OAL routines are available in ; IDL via the !OA system variable. ; Enumerated types for L3 are available in the !ODL system variable. ; Examples: ; ; In C code you use: In IDL code you use: ; OA_BINARY_INTERCHANGE_FORMAT !OA.BINARY_INTERCHANGE_FORMAT ; OA_IMAGE !OA.IMAGE ; OA_MSB_INTEGER !OA.MSB_INTEGER ; ODL_RECURSIVE_DOWN !ODL.RECURSIVE_DOWN ; ODL_EXPAND_STRUCTURE !ODL.EXPAND_STRUCTURE ; ; 6) Data from an in-memory OA object can be gotton into an IDL variable via ; the OaIDLGetObjectData function. ; - IMAGES and HISTOGRAMS are gotton into IDL array variables, two- and ; one dimensional respectively. ; - TABLE-like objects are gotton into IDL array of structures. The number ; of elements in the array equals the number of rows; each structure ; contains a row of data, with structure tags named according to the ; NAME keyword in the corresponding ODL tree. TABLES with any level of ; nested CONTAINERS are supported (they become nested structures). ; ; 7) An IDL variable can be gotton into an OA Object via the ; OaIDLVariabletoOaObject function. An IDL array variable can be gotton ; into an IMAGE or HISTOGRAM OA object. An IDL structure variable is ; gotton into a TABLE object. ** THIS IS NOT FULLY IMPLEMENTED YET ** ; ; 8) A simple user interface is provided with the function OaIDLReadObject. ; When called without keywords, this prompts the user for a PDS file name, ; prints the object names of the main objects in the file, and prompts the ; user to enter an object name. Then it reads in the object, and returns ; it, after translating it into an IDL variable. The object is now ; available for manipulation in IDL. ; ; 9) For information on the internal design of the interface, see ; OAL_IDL_interface.c. ; ;***************************************************************************** ;***************************************************************************** ; ; Routine: OaIDLCall ; ; Description: This IDL function makes the actual CALL_EXTERNAL call. ; It is called by all the IDL wrapper routines in this ; interface. It should not be called directly by users. ; ; Author: Steve Monk, University of Colorado LASP ; ; Creation Date: 7 Feb 1996 ; Last Modified: 7 Feb 1996 ; ; History: ; ; Creation - This routine was part of the Release 1.1 of the OA library. ; ; Input: The first argument is the name of the OAL, L3 or IDL interface ; function; subsequent arguments are the same as the corresponding C ; functions, as documented in the OAL and L3 User's Guides, or ; as required by the internal interface function. ; ; Output: If the return value of the C function is a (char *), then it is ; returned through CALL_EXTERNAL as an IDL string; otherwise, the ; last argument must be an IDL variable of the type expected to be ; returned by the C function, and the IDL string returned can be ; ignored. This scheme is compatible with the IBM-PC, which can't ; return doubles, and is also a good way to make an IDL string out ; of a C string. ; ; Notes: ; ;***************************************************************************** function OaIDLCall, PROC_NAME, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11 ; OAL_SHARED_LIB_NAME must point to the shared library file containing the ; entire OA library and the C interface routines from OAL_IDL_interface.c ; (On UNIX platforms the Makefile will create oal_idl.so for you.) ; ; *** CHANGE THIS WHENEVER YOU MOVE THIS CODE!! *** case 1 of (!VERSION.arch eq 'mipseb'): begin ;SGI OAL_SHARED_LIB_NAME = '/miranda2/monk/oal/idl/oal_idl.so' end (!VERSION.arch eq 'sparc'): begin ;Sun SPARCstation OAL_SHARED_LIB_NAME = '/kitron3/monk/oal/oal_idl.so' end (!VERSION.arch eq 'alpha' and !VERSION.os eq 'OSF'): begin ;Dec Alpha/OSF OAL_SHARED_LIB_NAME = '/usr/users/monks/oal/idl/oal_idl.so' end (!VERSION.arch eq 'vax'): begin ;VAX/VMS VMS_LOGICAL_TRANSLATION = '' Z = trnlog( 'OAL_SHARED_LIB_NAME', VMS_LOGICAL_TRANSLATION) if VMS_LOGICAL_TRANSLATION eq '' then begin setlog, 'OAL_SHARED_LIB_NAME', 'diska:[monk.oal.idl]oal_idl.exe' endif OAL_SHARED_LIB_NAME = 'OAL_SHARED_LIB_NAME' end else: begin ;Macintosh OAL_SHARED_LIB_NAME = 'MacT06-2:OAL:oal_idl.so' end endcase N = n_params() - 1 if !VERSION.arch eq 'vax' then begin ;VAX/VMS case N of 0: return, call_external( OAL_SHARED_LIB_NAME, 'OaIDLCall',1,PROC_NAME, $ /S_VALUE) 1: return, call_external( OAL_SHARED_LIB_NAME, 'OaIDLCall',2,PROC_NAME, $ P1, /S_VALUE) 2: return, call_external( OAL_SHARED_LIB_NAME, 'OaIDLCall',3,PROC_NAME, $ P1, P2, /S_VALUE) 3: return, call_external( OAL_SHARED_LIB_NAME, 'OaIDLCall',4,PROC_NAME, $ P1, P2, P3, /S_VALUE) 4: return, call_external( OAL_SHARED_LIB_NAME, 'OaIDLCall',5,PROC_NAME, $ P1, P2, P3, P4, /S_VALUE) 5: return, call_external( OAL_SHARED_LIB_NAME, 'OaIDLCall',6,PROC_NAME, $ P1, P2, P3, P4, P5, /S_VALUE) 6: return, call_external( OAL_SHARED_LIB_NAME, 'OaIDLCall',7,PROC_NAME, $ P1, P2, P3, P4, P5, P6, /S_VALUE) 7: return, call_external( OAL_SHARED_LIB_NAME, 'OaIDLCall',8,PROC_NAME, $ P1, P2, P3, P4, P5, P6, P7, /S_VALUE) 8: return, call_external( OAL_SHARED_LIB_NAME, 'OaIDLCall',9,PROC_NAME, $ P1, P2, P3, P4, P5, P6, P7, P8, /S_VALUE) 9: return, call_external( OAL_SHARED_LIB_NAME, 'OaIDLCall',10,PROC_NAME, $ P1, P2, P3, P4, P5, P6, P7, P8, P9, /S_VALUE) 10: return, call_external( OAL_SHARED_LIB_NAME, 'OaIDLCall',11,PROC_NAME, $ P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, $ /S_VALUE) 11: return, call_external( OAL_SHARED_LIB_NAME, 'OaIDLCall',12,PROC_NAME, $ P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, $ /S_VALUE) endcase endif else begin ;UNIX, Macintosh, IBM-PC case N of 0: return, call_external( OAL_SHARED_LIB_NAME, 'OaIDLCall', PROC_NAME, $ /S_VALUE) 1: return, call_external( OAL_SHARED_LIB_NAME, 'OaIDLCall', PROC_NAME, $ P1, /S_VALUE) 2: return, call_external( OAL_SHARED_LIB_NAME, 'OaIDLCall', PROC_NAME, $ P1, P2, /S_VALUE) 3: return, call_external( OAL_SHARED_LIB_NAME, 'OaIDLCall', PROC_NAME, $ P1, P2, P3, /S_VALUE) 4: return, call_external( OAL_SHARED_LIB_NAME, 'OaIDLCall', PROC_NAME, $ P1, P2, P3, P4, /S_VALUE) 5: return, call_external( OAL_SHARED_LIB_NAME, 'OaIDLCall', PROC_NAME, $ P1, P2, P3, P4, P5, /S_VALUE) 6: return, call_external( OAL_SHARED_LIB_NAME, 'OaIDLCall', PROC_NAME, $ P1, P2, P3, P4, P5, P6, /S_VALUE) 7: return, call_external( OAL_SHARED_LIB_NAME, 'OaIDLCall', PROC_NAME, $ P1, P2, P3, P4, P5, P6, P7, /S_VALUE) 8: return, call_external( OAL_SHARED_LIB_NAME, 'OaIDLCall', PROC_NAME, $ P1, P2, P3, P4, P5, P6, P7, P8, /S_VALUE) 9: return, call_external( OAL_SHARED_LIB_NAME, 'OaIDLCall', PROC_NAME, $ P1, P2, P3, P4, P5, P6, P7, P8, P9, /S_VALUE) 10: return, call_external( OAL_SHARED_LIB_NAME, 'OaIDLCall', PROC_NAME, $ P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, $ /S_VALUE) 11: return, call_external( OAL_SHARED_LIB_NAME, 'OaIDLCall', PROC_NAME, $ P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11,$ /S_VALUE) endcase endelse end ;***************************************************************************** ; ; Routine: OaIDLGetOaObjectStruct ; ; Description: This IDL function gets useful the fields of an OA_OBJECT C ; structure into an IDL structure. ; ; Author: Steve Monk, University of Colorado LASP ; ; Creation Date: 14 Feb 1996 ; Last Modified: 14 Feb 1996 ; ; History: ; ; Creation - This routine was part of the Release 1.1 of the OA library. ; ; Input: ; ; Output: ; ; Notes: ; ;***************************************************************************** function OaIDLGetOaObjectStruct, OA_OBJECT ODLTREE = double(0.0) DATA_PTR = double(0.0) SIZ = long(0) Z = OaIDLCall( 'OaIDLGetOaObjectStruct', OA_OBJECT, ODLTREE, DATA_PTR, SIZ) S = {oa_object_struct, ODLTREE : ODLTREE, $ DATA_PTR : DATA_PTR, $ SIZE : SIZ} return, S end ;***************************************************************************** ; ; Routine: OaIDLGetODLTreeNodeStruct ; ; Description: This IDL function gets useful the fields of an ODLTREE ; structure into an IDL structure. ; ; Author: Steve Monk, University of Colorado LASP ; ; Creation Date: 14 Feb 1996 ; Last Modified: 14 Feb 1996 ; ; History: ; ; Creation - This routine was part of the Release 1.1 of the OA library. ; ; Input: ; ; Output: ; ; Notes: ; ;***************************************************************************** function OaIDLGetODLTreeNodeStruct, ODLTREE CLASS_NAME = OaIDLCall( 'OaIDLGetODLTreeNodeStruct', ODLTREE, 'class_name') PRE_COMMENT = OaIDLCall( 'OaIDLGetODLTreeNodeStruct', ODLTREE, 'pre_comment') LINE_COMMENT = OaIDLCall( 'OaIDLGetODLTreeNodeStruct', ODLTREE, 'line_comment') POST_COMMENT = OaIDLCall( 'OaIDLGetODLTreeNodeStruct', ODLTREE, 'post_comment') END_COMMENT = OaIDLCall( 'OaIDLGetODLTreeNodeStruct', ODLTREE, 'end_comment') FILE_NAME = OaIDLCall( 'OaIDLGetODLTreeNodeStruct', ODLTREE, 'file_name') CHILD_COUNT = long(0) PARENT = double(0.0) LEFT_SIBLING = double(0.0) RIGHT_SIBLING = double(0.0) FIRST_CHILD = double(0.0) LAST_CHILD = double(0.0) FIRST_KEYWORD = double(0.0) LAST_KEYWORD = double(0.0) Z = OaIDLCall( 'OaIDLGetODLTreeNodeStruct', ODLTREE, ' ', CHILD_COUNT, $ PARENT, LEFT_SIBLING, RIGHT_SIBLING, FIRST_CHILD, LAST_CHILD, $ FIRST_KEYWORD, LAST_KEYWORD) S = {ODLTREE_node_struct, CLASS_NAME : CLASS_NAME, $ PRE_COMMENT : PRE_COMMENT, $ LINE_COMMENT : LINE_COMMENT, $ POST_COMMENT : POST_COMMENT, $ END_COMMENT : END_COMMENT, $ FILE_NAME : FILE_NAME, $ CHILD_COUNT : CHILD_COUNT, $ PARENT : PARENT, $ LEFT_SIBLING : LEFT_SIBLING, $ RIGHT_SIBLING : RIGHT_SIBLING, $ FIRST_CHILD : FIRST_CHILD, $ LAST_CHILD : LAST_CHILD, $ FIRST_KEYWORD : FIRST_KEYWORD, $ LAST_KEYWORD : LAST_KEYWORD} return, S end ;***************************************************************************** ; ; Routine: OaIDLGetProfile ; ; Description: This IDL procedure gets the fields of the OAL global profile ; structure into an IDL structure. ; ; Author: Steve Monk, University of Colorado LASP ; ; Creation Date: 14 Feb 1996 ; Last Modified: 14 Feb 1996 ; ; History: ; ; Creation - This routine was part of the Release 1.1 of the OA library. ; ; Input: ; ; Output: ; ; Notes: ; ;***************************************************************************** pro OaIDLGetProfile, PROFILE DST_FORMAT_FOR_ASCII_SRC = long(0) DST_FORMAT_FOR_BINARY_SRC = long(0) DST_ALIGNMENT_TYPE = long(0) DATA_TRANSLATION_PROFILE = long(0) CHECK_ASCII_WRITES = long(0) Z = OaIDLCall( 'OaIDLGetProfile', DST_FORMAT_FOR_ASCII_SRC, $ DST_FORMAT_FOR_BINARY_SRC, $ DST_ALIGNMENT_TYPE, $ DATA_TRANSLATION_PROFILE, $ CHECK_ASCII_WRITES) S = {profile_struct, DST_FORMAT_FOR_ASCII_SRC : DST_FORMAT_FOR_ASCII_SRC, $ DST_FORMAT_FOR_BINARY_SRC : DST_FORMAT_FOR_BINARY_SRC, $ DST_ALIGNMENT_TYPE : DST_ALIGNMENT_TYPE, $ DATA_TRANSLATION_PROFILE : DATA_TRANSLATION_PROFILE, $ CHECK_ASCII_WRITES : CHECK_ASCII_WRITES} PROFILE = S end ;***************************************************************************** ; ; Routine: OaIDLSetProfile ; ; Description: This IDL procedure sets the fields of the OAL global profile ; structure to the values passed in the input IDL structure. ; ; Author: Steve Monk, University of Colorado LASP ; ; Creation Date: 14 Feb 1996 ; Last Modified: 14 Feb 1996 ; ; History: ; ; Creation - This routine was part of the Release 1.1 of the OA library. ; ; Input: ; ; Output: ; ; Notes: ; ;***************************************************************************** pro OaIDLSetProfile, PROFILE DST_FORMAT_FOR_ASCII_SRC = long( PROFILE.dst_format_for_ascii_src) DST_FORMAT_FOR_BINARY_SRC = long( PROFILE.dst_format_for_binary_src) DST_ALIGNMENT_TYPE = long( PROFILE.dst_alignment_type) DATA_TRANSLATION_PROFILE = long( PROFILE.data_translation_profile) CHECK_ASCII_WRITES = long( PROFILE.check_ascii_writes) Z = OaIDLCall( 'OaIDLSetProfile', DST_FORMAT_FOR_ASCII_SRC, $ DST_FORMAT_FOR_BINARY_SRC, $ DST_ALIGNMENT_TYPE, $ DATA_TRANSLATION_PROFILE, $ CHECK_ASCII_WRITES) end ;***************************************************************************** ; Wrappers for macros. ;***************************************************************************** function LeftmostChild, ODLTREENODE ODLTREENODE_RESULT = double(0.0) Z = OaIDLCall( 'LeftmostChild', ODLTREENODE, ODLTREENODE_RESULT) return, ODLTREENODE_RESULT end function RightmostChild, ODLTREENODE ODLTREENODE_RESULT = double(0.0) Z = OaIDLCall( 'RightmostChild', ODLTREENODE, ODLTREENODE_RESULT) return, ODLTREENODE_RESULT end function LeftSibling, ODLTREENODE ODLTREENODE_RESULT = double(0.0) Z = OaIDLCall( 'LeftSibling', ODLTREENODE, ODLTREENODE_RESULT) return, ODLTREENODE_RESULT end function RightSibling, ODLTREENODE ODLTREENODE_RESULT = double(0.0) Z = OaIDLCall( 'RightSibling', ODLTREENODE, ODLTREENODE_RESULT) return, ODLTREENODE_RESULT end function Parent, ODLTREENODE ODLTREENODE_RESULT = double(0.0) Z = OaIDLCall( 'Parent', ODLTREENODE, ODLTREENODE_RESULT) return, ODLTREENODE_RESULT end ;***************************************************************************** ; Wrappers for OAL functions. ;***************************************************************************** function OaRouteErrorMessages, MESSAGE_FNAME, MESSAGE_FPTR RESULT = 0L Z = OaIDLCall( 'OaRouteErrorMessages', MESSAGE_FNAME, MESSAGE_FPTR, RESULT) return, RESULT end function OaParseLabelFile, FILESPEC, ERRFILESPEC, EXPAND, NOMSGS ODLTREE = double(0.0) Z = OaIDLCall( 'OaParseLabelFile', FILESPEC, ERRFILESPEC, long( EXPAND), $ long( NOMSGS), ODLTREE) return, ODLTREE end function OaReadObject, OBJECT_NODE OA_OBJECT = double(0.0) Z = OaIDLCall( 'OaReadObject', OBJECT_NODE, OA_OBJECT) return, OA_OBJECT end function OaKwdValuetoLong, KWD_NAME, ODLTREENODE, VALUE VALUE = long(0) RESULT = long(0) Z = OaIDLCall( 'OaKwdValuetoLong', KWD_NAME, ODLTREENODE, VALUE, RESULT) return, RESULT end function OaKwdValuetoStr, KWD_NAME, ODLTREENODE, VALUE RESULT = long(0) VALUE = OaIDLCall( 'OaKwdValuetoStr', KWD_NAME, ODLTREENODE, RESULT) return, RESULT end function OaGetSubCollection, OA_OBJECT, SUBOBJECT_NODE RESULT = double(0.0) Z = OaIDLCall( 'OaGetSubCollection', OA_OBJECT, SUBOBJECT_NODE, RESULT) return, RESULT end function OaGetSubTable, TABLE_OBJECT, START_ROW, STOP_ROW, SUBOBJECT_NODES, $ N_SUBOBJECT_NODES RESULT = double(0.0) Z = OaIDLCall( 'OaGetSubTable', TABLE_OBJECT, long( START_ROW), $ long(STOP_ROW), SUBOBJECT_NODES, $ long( N_SUBOBJECT_NODES), RESULT) return, RESULT end function OaReadSubTable, TABLE_NODE, START_ROW, STOP_ROW, SUBOBJECT_NODES, $ N_SUBOBJECT_NODES RESULT = double(0.0) Z = OaIDLCall( 'OaReadSubTable', TABLE_NODE, long( START_ROW), $ long( STOP_ROW), SUBOBJECT_NODES, $ long( N_SUBOBJECT_NODES), RESULT) return, RESULT end function OaObjectClasstoStr, OA_OBJECT_CLASS return, OaIDLCall( 'OaObjectClasstoStr', long( OA_OBJECT_CLASS)) end function OaGetObjectClass, ODLTREENODE RESULT = long(0) Z = OaIDLCall( 'OaGetObjectClass', ODLTREENODE, RESULT) return, RESULT end function OaUnravelContainer, TABLE_OBJECT RESULT = double(0.0) Z = OaIDLCall( 'OaUnravelContainer', TABLE_OBJECT, RESULT) return, RESULT end function OaAddContainerAroundTable, TABLE_OBJECT RESULT = double(0.0) Z = OaIDLCall( 'OaAddContainerAroundTable', TABLE_OBJECT, RESULT) return, RESULT end function OaAddLineTerminatorstoTable, TABLE_OBJECT RESULT = double(0.0) Z = OaIDLCall( 'OaAddLineTerminatorstoTable', TABLE_OBJECT, RESULT) return, RESULT end function OaCloseImage, IMAGE_HANDLE_OBJECT RESULT = long(0) Z = OaIDLCall( 'OaCloseImage', IMAGE_HANDLE_OBJECT, RESULT) return, RESULT end function OaCloseOutputFile, FILE_OBJECT, LABEL_FILESPEC RESULT = long(0) Z = OaIDLCall( 'OaCloseOutputFile', FILE_OBJECT, LABEL_FILESPEC, RESULT) return, RESULT end function OaConvertImagetoArray, SIMPLE_IMAGE RESULT = double(0.0) Z = OaIDLCall( 'OaConvertImagetoArray', SIMPLE_IMAGE, RESULT) return, RESULT end function OaConvertObject, OBJECT RESULT = double(0.0) Z = OaIDLCall( 'OaConvertObject', OBJECT, RESULT) return, RESULT end function OaConvertObjecttoOneType, OBJECT, DATA_TYPE, BYTES, RESCALE RESULT = double(0.0) Z = OaIDLCall( 'OaConvertObjecttoOneType', OBJECT, DATA_TYPE, long( BYTES), $ long( RESCALE), RESULT) return, RESULT end function OaCopyObject, OBJECT RESULT = double(0.0) Z = OaIDLCall( 'OaCopyObject', OBJECT, RESULT) return, RESULT end function OaCreateAttachedLabel, ODLTREE, LABEL_FILESPEC, $ ATTACHED_LABEL_FILESPEC RESULT = long(0) Z = OaIDLCall( 'OaCreateAttachedLabel', double( ODLTREE), LABEL_FILESPEC, $ ATTACHED_LABEL_FILESPEC, RESULT) return, RESULT end function OaDeleteColumn, OA_OBJECT, INPUT_NODE RESULT = double(0.0) Z = OaIDLCall( 'OaDeleteColumn', OA_OBJECT, INPUT_NODE, RESULT) return, RESULT end function OaDeleteObject, OBJECT RESULT = long(0) Z = OaIDLCall( 'OaDeleteObject', OBJECT, RESULT) return, RESULT end function OaDeleteRow, TABLE_OBJECT, ROW RESULT = double(0.0) Z = OaIDLCall( 'OaDeleteRow', TABLE_OBJECT, long( ROW), RESULT) return, RESULT end function OaGetFileKeywords, ODLTREENODE, LABEL_FILENAME, DATA_FILENAME, $ RECORD_TYPE, RECORD_BYTES, FILE_RECORDS, $ OBJECT_INTERCHANGE_FORMAT RESULT = long(0) LABEL_FILENAME = OaIDLCall( 'OaGetFileKeywords', 'label_filename', $ ODLTREENODE, long( RECORD_TYPE), $ long( RECORD_BYTES), long( FILE_RECORDS), $ RESULT) DATA_FILENAME = OaIDLCall( 'OaGetFileKeywords', 'data_filename') return, RESULT end function OaGetPartialImage, SIMPLE_IMAGE, START_LINE, STOP_LINE, $ START_SAMPLE, STOP_SAMPLE RESULT = double(0.0) Z = OaIDLCall( 'OaGetPartialImage', SIMPLE_IMAGE, long( START_LINE), $ long( STOP_LINE), long( START_SAMPLE), $ long( STOP_SAMPLE), RESULT) return, RESULT end function OaImportColumn, DATA_PTR, ROWS, ITEMS, ITEM_BYTES, DATA_TYPE, $ INTERCHANGE_FORMAT, NAME RESULT = double(0.0) Z = OaIDLCall( 'OaImportColumn', DATA_PTR, long( ROWS), long( ITEMS), $ long( ITEM_BYTES), DATA_TYPE, $ long( INTERCHANGE_FORMAT), NAME, RESULT) return, RESULT end function OaImportHistogram, DATA_PTR, ITEMS, ITEM_BYTES, DATA_TYPE, $ INTERCHANGE_FORMAT RESULT = double(0.0) Z = OaIDLCall( 'OaImportHistogram', DATA_PTR, long( ITEMS), $ long( ITEM_BYTES), DATA_TYPE, $ long( INTERCHANGE_FORMAT), RESULT) return, RESULT end function OaImportImage, DATA_PTR, LINES, LINE_SAMPLES, SAMPLE_TYPE, SAMPLE_BITS RESULT = double(0.0) Z = OaIDLCall( 'OaImportImage', DATA_PTR, long( LINES), long( LINE_SAMPLES),$ SAMPLE_TYPE, long( SAMPLE_BITS), RESULT) return, RESULT end function OaJoinTables, TABLE_A, TABLE_B, OPTION RESULT = double(0.0) Z = OaIDLCall( 'OaJoinTables', TABLE_A, TABLE_B, long( OPTION), RESULT) return, RESULT end function OaOpenImage, INPUT_NODE, BAND RESULT = double(0.0) Z = OaIDLCall( 'OaOpenImage', INPUT_NODE, long( BAND), RESULT) return, RESULT end function OaOpenOutputFile, DATA_FILENAME, RECORD_TYPE, RECORD_BYTES RESULT = double(0.0) Z = OaIDLCall( 'OaOpenOutputFile', DATA_FILENAME, long( RECORD_TYPE), $ long( RECORD_BYTES), RESULT) return, RESULT end function OaReadImage, IMAGE_NODE, BAND RESULT = double(0.0) Z = OaIDLCall( 'OaReadImage', IMAGE_NODE, long( BAND), RESULT) return, RESULT end function OaReadImageFromQube, QUBE_NODE, BAND RESULT = double(0.0) Z = OaIDLCall( 'OaReadImageFromQube', QUBE_NODE, long( BAND), RESULT) return, RESULT end function OaReadSpectrumFromImage, IMAGE_NODE, LINE, SAMPLE RESULT = double(0.0) Z = OaIDLCall( 'OaReadSpectrumFromImage', IMAGE_NODE, long( LINE), $ long( SAMPLE), RESULT) return, RESULT end function OaReadSpectrumFromQube, QUBE_NODE, LINE, SAMPLE RESULT = double(0.0) Z = OaIDLCall( 'OaReadSpectrumFromQube', QUBE_NODE, long( LINE), $ long( SAMPLE), RESULT) return, RESULT end function OaReadPartialImage, OA_OBJECT, START_LINE, STOP_LINE, START_SAMPLE, $ STOP_SAMPLE RESULT = double(0.0) Z = OaIDLCall( 'OaReadPartialImage', OA_OBJECT, long( START_LINE), $ long( STOP_LINE), long( START_SAMPLE), $ long( STOP_SAMPLE), RESULT) return, RESULT end function OaReportError, INPUT_ERROR_STRING RESULT = long(0) Z = OaIDLCall( 'OaReportError', INPUT_ERROR_STRING, RESULT) return, RESULT end function OaTransposeTable, TABLE_OBJECT RESULT = double(0.0) Z = OaIDLCall( 'OaTransposeTable', TABLE_OBJECT, RESULT) return, RESULT end function OaWriteObject, FILE_OBJECT, OBJECT RESULT = long(0) Z = OaIDLCall( 'OaWriteObject', FILE_OBJECT, OBJECT, RESULT) return, RESULT end function OaCopyTree, INPUT_NODE, OPTIONS RESULT = double(0.0) Z = OaIDLCall( 'OaCopyTree', INPUT_NODE, long( OPTIONS), RESULT) return, RESULT end function OaDeleteKwd, KWD_NAME, ODLTREENODE RESULT = long(0) Z = OaIDLCall( 'OaDeleteKwd', KWD_NAME, ODLTREENODE, RESULT) return, RESULT end function OaGetObjectInterchangeFormat, TLO_OBJECT_NODE RESULT = long(0) Z = OaIDLCall( 'OaGetObjectInterchangeFormat', TLO_OBJECT_NODE, RESULT) return, RESULT end function OaGetImageKeywords, IMAGE_NODE, LINES, LINE_SAMPLES, SAMPLE_BITS, $ SAMPLE_TYPE_STR, BANDS, BAND_STORAGE_TYPE, $ LINE_PREFIX_BYTES, LINE_SUFFIX_BYTES, $ ENCODING_TYPE RESULT = long(0) SAMPLE_TYPE_STR = OaIDLCall( 'OaGetImageKeywords', IMAGE_NODE, $ long( LINES), long( LINE_SAMPLES), $ long( SAMPLE_BITS), long( BANDS), $ long( BAND_STORAGE_TYPE), $ long( LINE_PREFIX_BYTES), $ long( LINE_SUFFIX_BYTES), $ long( ENCODING_TYPE), RESULT) return, RESULT end function OaGetTableKeywords, ODLTREENODE, ROWS, ROW_BYTES, ROW_PREFIX_BYTES, $ ROW_SUFFIX_BYTES, INTERCHANGE_FORMAT, $ TABLE_STORAGE_TYPE RESULT = long(0) Z = OaIDLCall( 'OaGetTableKeywords', ODLTREENODE, long( ROWS), $ long( ROW_BYTES), long( ROW_PREFIX_BYTES), $ long( ROW_SUFFIX_BYTES), long( INTERCHANGE_FORMAT), $ long( TABLE_STORAGE_TYPE), RESULT) return, RESULT end function OaLongtoKwdValue, KWD_NAME, ODLTREENODE, KEYWORD_VALUE RESULT = long(0) Z = OaIDLCall( 'OaLongtoKwdValue', KWD_NAME, ODLTREENODE, $ long( KEYWORD_VALUE), RESULT) return, RESULT end function OaPDSDataTypetoStr, PDS_DATA_TYPE return, OaIDLCall( 'OaPDSDataTypetoStr', long( PDS_DATA_TYPE)) end function OaSequencetoLongArray, KWD_NAME, ODLTREENODE, ARRAY, SEQUENCE_ITEMS RESULT = long(0) Z = OaIDLCall( 'OaSequencetoLongArray', 'first call', KWD_NAME, ODLTREENODE,$ long( SEQUENCE_ITEMS), RESULT) ARRAY = lonarr( SEQUENCE_ITEMS) Z = OaIDLCall( 'OaSequencetoLongArray', 'second call', ARRAY) return, RESULT end function OaSequencetoStrArray, KWD_NAME, ODLTREENODE, STR_ARRAY, SEQUENCE_ITEMS RESULT = long(0) Z = OaIDLCall( 'OaSequencetoStrArray', long(0), KWD_NAME, ODLTREENODE, $ long( SEQUENCE_ITEMS), RESULT) if SEQUENCE_ITEMS > 0 then begin STR_ARRAY = strarr( SEQUENCE_ITEMS) STR_ARRAY(0) = Z for I=1,SEQUENCE_ITEMS-1 do begin STR_ARRAY(I) = OaIDLCall( 'OaSequencetoStrArray', long(I)) endfor endif return, RESULT end function OaStrtoKwdValue, KWD_NAME, ODLTREENODE, STR RESULT = long(0) Z = OaIDLCall( 'OaStrtoKwdValue', KWD_NAME, ODLTREENODE, STR, RESULT) return, RESULT end function OaStrtoPDSDataType, STR, INTERCHANGE_FORMAT RESULT = long(0) Z = OaIDLCall( 'OaStrtoPDSDataType', STR, long( INTERCHANGE_FORMAT)) return, RESULT end ;***************************************************************************** ; Wrappers for L3 functions. ;***************************************************************************** function OdlFindObjDesc, START_OBJECT, OBJECT_CLASS, KEYWORD_NAME, $ KEYWORD_VALUE, OBJECT_POSITION, SEARCH_SCOPE ODLTREE = double(0.0) Z = OaIDLCall( 'OdlFindObjDesc', START_OBJECT, OBJECT_CLASS, KEYWORD_NAME, $ KEYWORD_VALUE, long( OBJECT_POSITION), $ long( SEARCH_SCOPE), ODLTREE) return, ODLTREE end function OdlGetObjDescClassName, OBJECT return, OaIDLCall( 'OdlGetObjDescClassName', OBJECT) end function OdlNextObjDesc, OBJECT, ROOT_LEVEL, SEARCH_SCOPE ODLTREE = double(0.0) Z = OaIDLCall( 'OdlNextObjDesc', OBJECT, long( ROOT_LEVEL), $ long( SEARCH_SCOPE), ODLTREE) return, ODLTREE end function OdlCutObjDesc, OBJECT ODLTREE = double(0.0) Z = OaIDLCall( 'OdlCutObjDesc', OBJECT, ODLTREE) return, ODLTREE end function OdlPasteObjDesc, NEW_OBJECT, PARENT_OBJECT ODLTREE = double(0.0) Z = OaIDLCall( 'OdlPasteObjDesc', NEW_OBJECT, PARENT_OBJECT, ODLTREE) return, ODLTREE end function OdlPasteObjDescBefore, NEW_OBJECT, OLD_OBJECT ODLTREE = double(0.0) Z = OaIDLCall( 'OdlPasteObjDescBefore', NEW_OBJECT, OLD_OBJECT, ODLTREE) return, ODLTREE end function OdlPasteObjDescAfter, NEW_OBJECT, OLD_OBJECT ODLTREE = double(0.0) Z = OaIDLCall( 'OdlPasteObjDescAfter', NEW_OBJECT, OLD_OBJECT, ODLTREE) return, ODLTREE end function OdlCopyObjDesc, OBJECT ODLTREE = double(0.0) Z = OaIDLCall( 'OdlCopyObjDesc', OBJECT, ODLTREE) return, ODLTREE end function OdlNewObjDesc, OBJECT_CLASS, PRE_COMMENT, LINE_COMMENT, POST_COMMENT,$ END_COMMENT, FILE_NAME, IS_A_GROUP, LINE_NUMBER ODLTREE = double(0.0) Z = OaIDLCall( 'OdlNewObjDesc', OBJECT_CLASS, PRE_COMMENT, LINE_COMMENT, $ POST_COMMENT, END_COMMENT, FILE_NAME, $ long( IS_A_GROUP), long( LINE_NUMBER), $ ODLTREE) return, ODLTREE end function OdlGetObjDescChildCount, OBJECT RESULT = long(0) Z = OaIDLCall( 'OdlCopyObjDesc', OBJECT, RESULT) return, RESULT end function OdlFindKwd, START_OBJECT, KEYWORD_NAME, KEYWORD_VALUE, $ KEYWORD_POSITION, SEARCH_SCOPE RESULT = double(0.0) Z = OaIDLCall( 'OdlFindKwd', START_OBJECT, KEYWORD_NAME, KEYWORD_VALUE, $ long( KEYWORD_POSITION), long( SEARCH_SCOPE), $ RESULT) return, RESULT end function OdlNextKwd, START_OBJECT, KEYWORD_NAME, KEYWORD_VALUE, $ KEYWORD_POSITION, SEARCH_SCOPE RESULT = double(0.0) Z = OaIDLCall( 'OdlNextKwd', START_OBJECT, KEYWORD_NAME, KEYWORD_VALUE, $ long( KEYWORD_POSITION), long( SEARCH_SCOPE), $ RESULT) return, RESULT end function OdlCutKwd, KEYWORD RESULT = double(0.0) Z = OaIDLCall( 'OdlCutKwd', KEYWORD, RESULT) return, RESULT end function OdlPasteKwd, KEYWORD, OBJECT RESULT = double(0.0) Z = OaIDLCall( 'OdlPasteKwd', KEYWORD, OBJECT, RESULT) return, RESULT end function OdlPasteKwdBefore, NEW_KEYWORD, OLD_KEYWORD RESULT = double(0.0) Z = OaIDLCall( 'OdlPasteKwdBefore', NEW_KEYWORD, OLD_KEYWORD, RESULT) return, RESULT end function OdlPasteKwdAfter, NEW_KEYWORD, OLD_KEYWORD RESULT = double(0.0) Z = OaIDLCall( 'OdlPasteKwdAfter', NEW_KEYWORD, OLD_KEYWORD, RESULT) return, RESULT end function OdlCopyKwd, KEYWORD RESULT = double(0.0) Z = OaIDLCall( 'OdlCopyKwd', KEYWORD, RESULT) return, RESULT end function OdlNewKwd, KEYWORD_NAME, VALUE_TEXT, PRE_COMMENT, LINE_COMMENT, $ FILE_NAME, LINE_NUMBER RESULT = double(0.0) Z = OaIDLCall( 'OdlNewKwd', KEYWORD_NAME, VALUE_TEXT, PRE_COMMENT, $ LINE_COMMENT, FILE_NAME, long( LINE_NUMBER), $ RESULT) return, RESULT end function OdlGetFirstKwd, OBJECT RESULT = double(0.0) Z = OaIDLCall( 'OdlGetFirstKwd', OBJECT, RESULT) return, RESULT end function OdlGetNextKwd, KEYWORD RESULT = double(0.0) Z = OaIDLCall( 'OdlGetNextKwd', KEYWORD, RESULT) return, RESULT end function OdlCopyKwd, KEYWORD RESULT = double(0.0) Z = OaIDLCall( 'OdlCopyKwd', KEYWORD, RESULT) return, RESULT end function OdlFreeTree, OBJECT RESULT = double(0.0) Z = OaIDLCall( 'OdlFreeTree', OBJECT, RESULT) return, RESULT end function OdlFreeKwd, KEYWORD RESULT = double(0.0) Z = OaIDLCall( 'OdlFreeKwd', KEYWORD, RESULT) return, RESULT end function OdlGetNextKwd, KEYWORD RESULT = double(0.0) Z = OaIDLCall( 'OdlGetNextKwd', KEYWORD, RESULT) return, RESULT end function OdlPrintLabel, OBJECT, MESSAGE_FNAME, MESSAGE_FPTR, ROOT_LEVEL, $ OPTIONS Z = OaIDLCall( 'OdlPrintLabel', OBJECT, MESSAGE_FNAME, MESSAGE_FPTR, $ long( ROOT_LEVEL), long( OPTIONS)) return, 0 end function OdlGetKwdValue, KEYWORD return, OaIDLCall( 'OdlGetKwdValue', KEYWORD) end function OdlGetKwdValueType, KEYWORD RESULT = long(0) Z = OaIDLCall( 'OdlGetKwdValueType', KEYWORD, RESULT) return, RESULT end function OdlGetKwdUnit, KEYWORD return, OaIDLCall( 'OdlGetKwdUnit', KEYWORD) end function OdlGetKwdName, KEYWORD return, OaIDLCall( 'OdlGetKwdName', KEYWORD) end function OdlFreeAllKwds, OBJECT RESULT = double(0.0) Z = OaIDLCall( 'OdlFreeAllKwds', OBJECT, RESULT) return, RESULT end ;***************************************************************************** ; ; Routine: OaIDLGetObjectData ; ; Description: This IDL function gets the data part of an OA object into an ; IDL variable. It does nothing with the ODL tree part. ; - An IMAGE object goes into a two-dimensional IDL array. ; - A HISTOGRAM object goes into a one-dimensional IDL array. ; - A TABLE-like object goes into an IDL array of structures, ; with as many elements as there are rows in the TABLE. ; Each structure tag corresponds to a COLUMN in the TABLE, ; or a CONTAINER, in which case the structure tag is a nested ; structure. ; - An ARRAY object goes into an IDL array of structures if the ; ARRAY has a COLLECTION under it (just like a TABLE) ; otherwise into an IDL array of scalars. ; ; Author: Steve Monk, University of Colorado LASP ; ; Creation Date: 14 Feb 1996 ; Last Modified: 14 Feb 1996 ; ; History: ; ; Creation - This routine was part of the Release 1.1 of the OA library. ; ; Input: ; ; Output: ; ; Notes: ; ; 1) When getting a complex object such as a TABLE or COLLECTION, this routine ; calls itself recursively to get each subobject (COLUMN, CONTAINER, ARRAY, ; COLLECTION etc.) individually. ; ;***************************************************************************** function OaIDLGetObjectData, OA_OBJECT, RECURSIVE=RECURSIVE if OA_OBJECT eq 0 then return,0 IDL_VARIABLE = 0 ; Find out how this OA_OBJECT will be encapsulated into an IDL variable, by ; calling a function which is the equivalent of the IDL 'SIZE' function, but ; operates on an OA_OBJECT instead of on an IDL variable, and tells us what ; type of IDL variable to put the OA_OBJECT in. SIZ = lonarr(20) Z = OaIDLCall( 'OaIDLSize', OA_OBJECT, SIZ) TYPE_CODE = SIZ( SIZ(0) + 1) ; If the type code indicates a 'simple' object, then build up an IDL command ; which creates an appropriately typed array variable to copy the object data ; to. If the type code indicates a 'complex' object, then build up a ; structure by calling OaIDLGetObjectData recursively to extract and copy the ; object data for each subobject individually. if TYPE_CODE ne 8 then begin ;Simple object, so put into IDL array variable. case TYPE_CODE of 1: SYSTEM_STR = 'bytarr(' 2: SYSTEM_STR = 'intarr(' 3: SYSTEM_STR = 'lonarr(' 4: SYSTEM_STR = 'fltarr(' 5: SYSTEM_STR = 'dblarr(' 7: SYSTEM_STR = 'bytarr(' else: return,0 ; Unknown object type endcase if SIZ(0) eq 0 then begin ;Object data is a scalar (single value), SYSTEM_STR = SYSTEM_STR + '1' ;so array has a single element. endif else begin ;Object data is an array. SYSTEM_STR = SYSTEM_STR + strtrim( SIZ(1),2) for I=2,SIZ(0) do begin ;Copy array dimensions into string. SYSTEM_STR = SYSTEM_STR + ',' + strtrim( SIZ(I),2) endfor endelse SYSTEM_STR = 'IDL_VARIABLE = ' + SYSTEM_STR + ')' Z = execute( SYSTEM_STR) if Z ne 1 then return,0 ; Copy the OA_OBJECT's object data into the IDL array. The memory malloc'ed ; by OAL can't be used in IDL because IDL uses different, incompatible memory ; management routines. (It works for awhile, then IDL crashes!) Z = OaIDLCall( 'OaIDLCopyObjectDatatoIDLVariable', OA_OBJECT, IDL_VARIABLE) if Z ne 'OK' then return,0 OA_OBJECT_STRUCT = OaIDLGetOaObjectStruct( OA_OBJECT) if TYPE_CODE eq 7 then begin ;Special case for string data ; Convert bytarr(LEN,) to strarr(). For example, convert ; bytarr(LEN,ROWS) to strarr(ROWS) or bytarr(LEN,Y,ROWS) to strarr(Y,ROWS), ; which happens when an ASCII COLUMN has repetitions. More dimensions are ; possible with ARRAYS: only 2 and 3 are supported for now (should use ; execute() to handle the general case...). Higher dimensioned bytarrs ; will stay bytarrs. if SIZ(0) eq 2 then begin TMP = strarr( SIZ(2)) for I=0,SIZ(2)-1 do TMP(I) = string(IDL_VARIABLE(*,I)) IDL_VARIABLE = TMP endif if SIZ(0) eq 3 then begin TMP = strarr( SIZ(2), SIZ(3)) for I=0,SIZ(3)-1 do begin for J=0,SIZ(2)-1 do begin TMP(J,I) = string(IDL_VARIABLE(*,J,I)) endfor endfor IDL_VARIABLE = TMP endif endif ;end if TYPE_CODE = 7 (string) ; If our simple object is a TABLE-like object, and the call we're in ; isn't a recursive call, then transpose the variable we got above into an ; IDL array of structures, and return it. Otherwise return it in its ; present form to the caller. if not keyword_set( RECURSIVE) then begin OA_OBJECT_STRUCT = OaIDLGetOaObjectStruct( OA_OBJECT) OBJECT_CLASS_ENUM = OaGetObjectClass( OA_OBJECT_STRUCT.odltree) CLASS_NAME = OaObjectClasstoStr( OBJECT_CLASS_ENUM) if CLASS_NAME eq 'TABLE' or CLASS_NAME eq 'SPECTRUM' or $ CLASS_NAME eq 'SERIES' or CLASS_NAME eq 'PALETTE' or $ CLASS_NAME eq 'GAZETTEER' then begin ; Get a structure tag name from the NAME keyword of the COLUMN node if ; the keyword exists, otherwise from the class_name. Make sure it starts ; with a letter. CURRENT_NODE = LeftmostChild( OA_OBJECT_STRUCT.odltree) if CURRENT_NODE eq 0 then return,0 TAG_NAME = '' Z = OaKwdValuetoStr( 'NAME', CURRENT_NODE, TAG_NAME) if TAG_NAME eq '' then begin TAG_NAME = OdlGetObjDescClassName( CURRENT_NODE) endif TAG_NAME = strupcase( TAG_NAME) FIRST_LETTER = strmid( TAG_NAME, 0, 1) if FIRST_LETTER lt 'A' or FIRST_LETTER gt 'Z' then begin TAG_NAME = 'A_' + TAG_NAME endif ; Case 1: Change the xxxARR( X) to structARR( X) with one xxx as the ; only structure element. ; Case 2: Change the xxxARR( X,Y) to structARR( Y) with xxxARR( X) as ; the only structure element. SIZ = size( IDL_VARIABLE) N_DIMS = SIZ(0) case N_DIMS of 1: begin S = create_struct( TAG_NAME, IDL_VARIABLE(0)) S = replicate( S, SIZ(1)) S(*).(0) = IDL_VARIABLE end 2: begin S = create_struct( TAG_NAME, IDL_VARIABLE(*,0)) S = replicate( S, SIZ(2)) S(*).(0) = IDL_VARIABLE end endcase return, S endif endif return, IDL_VARIABLE endif else begin ;Complex object, so put into an IDL structure. STRUCT = 0 ; Set CURRENT_NODE to left-most child under the root of the OA_OBJECT's ; ODL tree. (Guaranteed to have a left-most child because OaIDLSize ; identified it as a complex object.) IDL_VARIABLE = 0 OA_OBJECT_STRUCT = OaIDLGetOaObjectStruct( OA_OBJECT) ROOT_NODE = OA_OBJECT_STRUCT.odltree OBJECT_CLASS_ENUM = OaGetObjectClass( OA_OBJECT_STRUCT.odltree) ROOT_CLASS_NAME = OaObjectClasstoStr( OBJECT_CLASS_ENUM) if ROOT_CLASS_NAME eq 'TABLE' or ROOT_CLASS_NAME eq 'SPECTRUM' or $ ROOT_CLASS_NAME eq 'GAZETTEER' or ROOT_CLASS_NAME eq 'PALETTE' or $ ROOT_CLASS_NAME eq 'SERIES' or ROOT_CLASS_NAME eq 'COLLECTION' then begin CURRENT_NODE = LeftmostChild( ROOT_NODE) endif if ROOT_CLASS_NAME eq 'ARRAY' then begin CURRENT_NODE = OdlFindObjDesc( ROOT_NODE, "*COLLECTION", '', '', 0, 0) CURRENT_NODE = LeftmostChild( CURRENT_NODE) endif while CURRENT_NODE ne 0 do begin ; Extract the sub-object described by the current node from the OA_OBJECT, ; and get it into an IDL variable via a recursive call to this function. if ROOT_CLASS_NAME eq 'TABLE' or ROOT_CLASS_NAME eq 'SPECTRUM' or $ ROOT_CLASS_NAME eq 'SERIES' or ROOT_CLASS_NAME eq 'PALETTE' or $ ROOT_CLASS_NAME eq 'GAZETTEER' then begin ; Current sub-object is a COLUMN or CONTAINER, so use OaGetSubTable etc. ; to extract it. Z = OaKwdValuetoLong( 'ROWS', ROOT_NODE, ROWS) if Z ne 0 then return,0 SUB_TABLE = OaGetSubTable( OA_OBJECT, 1, ROWS, [CURRENT_NODE], 1) OBJECT_CLASS_ENUM = OaGetObjectClass( CURRENT_NODE) CLASS_NAME = OaObjectClasstoStr( OBJECT_CLASS_ENUM) if CLASS_NAME eq 'CONTAINER' then begin SUB_TABLE = OaUnravelContainer( SUB_TABLE) IDL_VARIABLE = call_function( 'OaIDLGetObjectData', SUB_TABLE, $ /RECURSIVE) ; Change from a one-dimensional array to a two-dimensional array, ; i.e. add back the CONTAINER's REPETITIONS. N = n_elements( IDL_VARIABLE) TMP = replicate( IDL_VARIABLE(0), N/ROWS, ROWS) NN = indgen(N) TMP( NN) = IDL_VARIABLE( NN) IDL_VARIABLE = TMP TMP = 0 endif else begin IDL_VARIABLE = call_function( 'OaIDLGetObjectData', SUB_TABLE, $ /RECURSIVE) endelse endif if ROOT_CLASS_NAME eq 'ARRAY' or ROOT_CLASS_NAME eq 'COLLECTION' then begin ; Current sub-object a child of a COLLECTION, so use OaGetSubCollection ; to extract the current subobject. SUB_OBJECT = OaGetSubCollection( OA_OBJECT, CURRENT_NODE) IDL_VARIABLE = call_function( 'OaIDLGetObjectData', SUB_OBJECT, $ /RECURSIVE) endif ; Get a name for this sub-object to use as its structure tag, and take ; care not to duplicate an existing tag or use a tag which doesn't ; start with a letter. The tag comes from the NAME keyword, if it exists, ; otherwise from the class_name. If the tag duplicates an existing tag, ; append a number, e.g. '_2' or '_3' after it, until it's unique. TAG_NAME = '' Z = OaKwdValuetoStr( 'NAME', CURRENT_NODE, TAG_NAME) if TAG_NAME eq '' then begin TAG_NAME = OdlGetObjDescClassName( CURRENT_NODE) endif TAG_NAME = strupcase( TAG_NAME) FIRST_LETTER = strmid( TAG_NAME, 0, 1) if FIRST_LETTER eq '"' or FIRST_LETTER eq '''' then begin TAG_NAME = strmid( TAG_NAME, 1, strlen( TAG_NAME)-1) endif FIRST_LETTER = strmid( TAG_NAME, 0, 1) LAST_LETTER = strmid( TAG_NAME, strlen( TAG_NAME)-1, 1) if LAST_LETTER eq '"' or LAST_LETTER eq '''' then begin TAG_NAME = strmid( TAG_NAME, 0, strlen( TAG_NAME)-1) endif if FIRST_LETTER lt 'A' or FIRST_LETTER gt 'Z' then begin TAG_NAME = 'A_' + TAG_NAME endif SIZ = size( STRUCT) if SIZ(2) ne 8 then begin ;Structure hasn't been created yet, so do it. STRUCT = create_struct( TAG_NAME, IDL_VARIABLE) endif else begin ;Add new tag/field to structure. DUPLICATE_TAGS = 1 NUM = 2 while DUPLICATE_TAGS gt 0 do begin W = where( tag_names( STRUCT) eq TAG_NAME, DUPLICATE_TAGS) if DUPLICATE_TAGS gt 0 then begin TAG_NAME = TAG_NAME + '_' + strtrim(NUM,2) NUM = NUM + 1 endif endwhile STRUCT = create_struct( STRUCT, TAG_NAME, IDL_VARIABLE) endelse CURRENT_NODE = RightSibling( CURRENT_NODE) endwhile ; Transpose STRUCT, a struct containing arrays, into S, an array of structs. ; Use the same tag names, but instead of assigning the whole array to the ; tag, assign only the first element of the array; then replicate this ; structure N times, and copy the data to it. S = 0 T_NAMES = tag_names( STRUCT) for I=0,n_tags( STRUCT)-1 do begin SIZ = size( STRUCT.(I)) case SIZ(0) of 1: begin if I eq 0 then begin S = create_struct( T_NAMES(I), STRUCT.(I)(0)) N = SIZ(1) endif else begin S = create_struct( S, T_NAMES(I), STRUCT.(I)(0)) endelse end 2: begin if I eq 0 then begin S = create_struct( T_NAMES(I), STRUCT.(I)(*,0)) N = SIZ(2) endif else begin S = create_struct( S, T_NAMES(I), STRUCT.(I)(*,0)) endelse end endcase endfor S = replicate( S, N) ; Copy the data from STRUCT into S. for I=0,n_tags( STRUCT)-1 do begin SIZ = size( STRUCT.(I)) case SIZ(0) of 1: begin for J=0,N-1 do begin S(J).(I) = STRUCT.(I)(J) endfor end 2: begin for J=0,N-1 do begin S(J).(I) = STRUCT.(I)(*,J) endfor end endcase endfor return, S endelse end ;***************************************************************************** ; ; Routine: OaIDLVariabletoOaObject ; ; Description: This IDL function creates an OA_OBJECT from an IDL variable. ; The new OA_OBJECT is allocated by OAL, and can be manipulated ; using OAL routines like any other OA object. ; ; Author: Steve Monk, University of Colorado LASP ; ; Creation Date: 29 Feb 1996 ; Last Modified: 29 Feb 1996 ; ; History: ; ; Creation - This routine was part of the Release 1.1 of the OA library. ; ; Input: ; ; IDL_VARIABLE - An IDL variable, whose type must agree with CLASS_NAME, as ; described below. ; ; CLASS_NAME - indicates what class of OA object to create, and must agree ; with the type of the IDL_VARIABLE input as follows: ; - If CLASS_NAME is 'TABLE', or some other TABLE-like ; object name, then IDL_VARIABLE must be an array of ; structures. ; - If CLASS_NAME is: ; 'HISTOGRAM' - IDL_VARIABLE must be a one-dimensional array ; of scalars. ; 'IMAGE' - IDL_VARIABLE must be a two-dimensional ; of scalars. ; ; The following IDL keywords can be used to set values of keywords in the ; ODL tree of the new OA Object; each IDL keyword has the same name ; as the corresponding ODL keyword name. If not set, defaults are used ; when required. These keywords are used internally, in the recursive ; calls this function makes to itself. ; ; NAME - a text string, default is 'NO_NAME' ; DESCRIPTION - a text string, default is NULL. ; ; Output: The function returns an OA_OBJECT descriptor pointer (i.e. an ; IDL double). If unsuccessful, this will be 0.0. ; ; Notes: ; ; 1) In most cases, the returned OA_OBJECT is either implicitly binary or has ; an INTERCHANGE_FORMAT keyword set to "BINARY". If the caller knows all ; the components of the IDL_VARIABLE input were strings, then the caller ; can add or change the INTERCHANGE_FORMAT keyword to "ASCII" in the ; object's ODL tree. No data types are changed by this function, so if ; IDL_VARIABLE contained only strings, the output OA_OBJECT will too. ; ;***************************************************************************** function OaIDLVariabletoOaObject, IDL_VARIABLE, CLASS_NAME, $ DESCRIPTION=DESCRIPTION, NAME=NAME ; This structure allows the code below to look up the number of bytes and ; OAL data type, given an IDL type code returned by the SIZE function. TYPE_XLAT = replicate( {type_xlat, BYTES : 0, DATA_TYPE : ''}, 6) case 1 of (!VERSION.arch eq 'mipseb' or $ !VERSION.arch eq 'sparc' or $ !VERSION.arch eq 'PowerMac'): begin ;SGI, Sun SPARCstation, Macintosh TYPE_XLAT(0) = {type_xlat, 0, 'UNDEFINED'} ;IDL undefined variable TYPE_XLAT(1) = {type_xlat, 1, 'INTEGER'} ;IDL byte TYPE_XLAT(2) = {type_xlat, 2, 'MSB_INTEGER'} ;IDL integer TYPE_XLAT(3) = {type_xlat, 4, 'MSB_INTEGER'} ;IDL long TYPE_XLAT(4) = {type_xlat, 4, 'IEEE_REAL'} ;IDL float TYPE_XLAT(5) = {type_xlat, 8, 'IEEE_REAL'} ;IDL double end (!VERSION.arch eq 'alpha' and !VERSION.os eq 'OSF'): begin ;Dec Alpha/OSF TYPE_XLAT(0) = {type_xlat, 0, 'UNDEFINED'} ;IDL undefined variable TYPE_XLAT(1) = {type_xlat, 1, 'INTEGER'} ;IDL byte TYPE_XLAT(2) = {type_xlat, 2, 'LSB_INTEGER'} ;IDL integer TYPE_XLAT(3) = {type_xlat, 4, 'LSB_INTEGER'} ;IDL long TYPE_XLAT(4) = {type_xlat, 4, 'PC_REAL'} ;IDL float TYPE_XLAT(5) = {type_xlat, 8, 'PC_REAL'} ;IDL double end else: return,0.0 endcase SIZ = size( IDL_VARIABLE) TYPE_CODE = SIZ( SIZ(0) + 1) if TYPE_CODE eq 0 then return,0.0 ;Input variable is undefined. case 1 of (CLASS_NAME eq 'HISTOGRAM'): begin if SIZ(0) ne 1 then return,0.0 ;Must be one-dimensional array. if TYPE_CODE eq 8 then return,0.0 ;Can't be an array of structures. if TYPE_CODE eq 7 then begin ;Convert strings to bytarrs. V = byte( IDL_VARIABLE) ;If strings are different lengths, this W = where( V eq 0, COUNT) ;pads shorter strings with 0's, so need to if COUNT gt 0 then begin ;replace 0's by spaces (ASCII code = 32). V(W) = 32 endif VSIZ = size(V) OA_OBJECT = OaImportHistogram( V, VSIZ(2), VSIZ(1), 'CHARACTER', 1) return, OA_OBJECT endif else begin ;HISTOGRAM is in binary interchange format. OA_OBJECT = OaImportHistogram( IDL_VARIABLE, SIZ(1), $ TYPE_XLAT( TYPE_CODE).bytes, $ TYPE_XLAT( TYPE_CODE).data_type, 2) return, OA_OBJECT endelse end (CLASS_NAME eq 'IMAGE'): begin if SIZ(0) ne 2 then return,0.0 ;Must be a two-dimensional array. if TYPE_CODE lt 1 or TYPE_CODE gt 5 then return,0.0 ;Wrong type for IMAGE OA_OBJECT = OaIDLImportImage( IDL_VARIABLE, SIZ(2), SIZ(1), $ TYPE_XLAT( TYPE_CODE).data_type, $ TYPE_XLAT( TYPE_CODE).bytes * 8) if OA_OBJECT eq 0 then return,0.0 ;Probably out of memory. if keyword_set( DESCRIPTION) then begin OA_OBJECT_STRUCT = OaIDLGetOaObjectStruct( OA_OBJECT) Z = OaStrtoKwdValue( 'DESCRIPTION', OA_OBJECT_STRUCT.odltree, $ DESCRIPTION) endif return,OA_OBJECT end (CLASS_NAME eq 'ARRAY'): begin return,0.0 ;Not implemented yet. end (CLASS_NAME eq 'TABLE' or CLASS_NAME eq 'SPECTRUM' or $ CLASS_NAME eq 'SERIES' or CLASS_NAME eq 'PALETTE' or $ CLASS_NAME eq 'GAZETTEER'): begin if TYPE_CODE ne 8 then return,0.0 ;Must be an IDL array of structures. N_SUBOBJECTS = n_tags( IDL_VARIABLE) SUBOBJECT_NAMES = tag_names( IDL_VARIABLE) ROWS = n_elements( IDL_VARIABLE) OA_OBJECT = 0.0 ; Loop through all the structure tags. Import each one individually into ; an OA_OBJECT which is a TABLE with a single COLUMN or CONTAINER, and join ; this OA_OBJECT to the main OA_OBJECT being built up. for I=0,N_SUBOBJECTS-1 do begin IDL_SUBOBJECT = IDL_VARIABLE(*).(I) SIZ = size( IDL_SUBOBJECT) TYPE_CODE = SIZ( SIZ(0) + 1) if TYPE_CODE eq 8 then begin ;Import CONTAINER via a recursive call. ; IDL_SUBOBJECT is a currently a structARR( REPETITIONS, ROWS) and ; needs to be changed to a structARR( REPETITIONS * ROWS) to be ; accepted as a TABLE in the recursive call, so change it: N = n_elements( IDL_SUBOBJECT) TMP = replicate( IDL_SUBOBJECT(0), N) for J=0,N-1 do begin TMP(J) = IDL_SUBOBJECT(J) endfor IDL_SUBOBJECT = TMP TMP = 0 SUB_OBJECT = call_function( 'OaIDLVariabletoOaObject', IDL_SUBOBJECT, $ 'TABLE') if SUB_OBJECT eq 0 then return,0.0 ;Probably out of memory. SUB_OBJECT = OaAddContainerAroundTable( SUB_OBJECT) if SUB_OBJECT eq 0 then return,0.0 ;Probably out of memory. ; The OaAddContainerAroundTable call sets ROWS=1, so change it back to ; the original ROWS, and adjust ROW_BYTES and the CONTAINER's ; REPETITIONS accordingly; also give the CONTAINER node a name (the ; structure tag name). OA_OBJECT_STRUCT = OaIDLGetOaObjectStruct( SUB_OBJECT) Z = OaLongtoKwdValue( 'ROWS', OA_OBJECT_STRUCT.odltree, ROWS) Z = OaKwdValuetoLong( 'ROW_BYTES', OA_OBJECT_STRUCT.odltree, ROW_BYTES) Z = OaLongtoKwdValue( 'ROW_BYTES', OA_OBJECT_STRUCT.odltree, $ ROW_BYTES/ROWS) CONTAINER_NODE = LeftmostChild( OA_OBJECT_STRUCT.odltree) Z = OaLongtoKwdValue( 'REPETITIONS', CONTAINER_NODE, N/ROWS) Z = OaStrtoKwdValue( 'NAME', CONTAINER_NODE, SUBOBJECT_NAMES(I)) if OA_OBJECT eq 0 then begin ;OA_OBJECT not created yet. OA_OBJECT = SUB_OBJECT endif else begin OA_OBJECT = OaJoinTables( OA_OBJECT, SUB_OBJECT, 1) endelse endif else begin ;Import a COLUMN if SIZ(0) gt 2 then return,0.0 ;Too many dimensions for a COLUMN. if TYPE_CODE eq 7 then begin ;Convert string(s) to bytarr. V = byte( IDL_SUBOBJECT) ;If strings are different lengths, this W = where( V eq 0, COUNT) ;pads shorter strings with 0's, so need if COUNT gt 0 then begin ;to replace 0's by spaces (ASCII code 32) V(W) = 32 endif VSIZ = size(V) ;Guaranteed to be a bytarr, not a scalar, case VSIZ(0) of ;even if IDL_SUBOBJECT's strlen is 1. 1: begin ;IDL_SUBOBJECT is a scalar string, so V ITEM_BYTES = VSIZ(1) ;is a bytarr( LEN); only one row. ITEMS = 1 ROWS = 1 end 2: begin ;IDL_SUBOBJECT is a strarr( ROWS), so V ITEM_BYTES = VSIZ(1) ;is a bytarr( LEN, ROWS). ITEMS = 1 ROWS = VSIZ(2) end 3: begin ;IDL_SUBOBJECT is a strarr( ITEMS, ROWS), ITEM_BYTES = VSIZ(1) ;so V is a bytarr( LEN, ITEMS, ROWS). ITEMS = VSIZ(2) ROWS = VSIZ(3) end endcase DATA_TYPE = 'CHARACTER' IDL_SUBOBJECT = V endif else begin ;end section for strings case SIZ(0) of 0: begin ;IDL_SUBOBJECT is a scalar numeric value, ITEMS = 1 ;so only one item, one row. ROWS = 1 end 1: begin ;IDL_SUBOBJECT is a XXXarr( ROWS) ITEMS = 1 ROWS = SIZ(1) end 2: begin ;IDL_SUBOBJECT is a XXXarr( ITEMS, ROWS) ITEMS = SIZ(1) ROWS = SIZ(2) end endcase ITEM_BYTES = TYPE_XLAT( TYPE_CODE).bytes DATA_TYPE = TYPE_XLAT( TYPE_CODE).data_type endelse ;end else COLUMN contained numeric types, not strings SUB_OBJECT = OaImportColumn( IDL_SUBOBJECT, ROWS, ITEMS, ITEM_BYTES, $ DATA_TYPE, 2, SUBOBJECT_NAMES(I)) if SUB_OBJECT eq 0 then return,0.0 ;Probably out of memory. if OA_OBJECT eq 0 then begin ;OA_OBJECT not created yet. OA_OBJECT = SUB_OBJECT endif else begin OA_OBJECT = OaJoinTables( OA_OBJECT, SUB_OBJECT, 1) endelse if OA_OBJECT eq 0 then return,0.0 ;Probably out of memory. endelse ;input IDL variable was an array or scalar, not a structure. endfor ;end loop through IDL variable's structure tags return,OA_OBJECT end ;end case for TABLE-like object. else: begin ;Unknown CLASS_NAME return,0.0 end endcase end ;***************************************************************************** ; ; Routine: OaIDLReadObject ; ; Description: This is a user interface to read a PDS object into an ; IDL variable, and is provided as a useful example of ; using OAL from IDL. When called without keywords, it prompts ; the user for a PDS label file and reads in the label; then ; it prompts the user for an object to read in, reads it, and ; converts it to an IDL variable. ; ; Author: Steve Monk, University of Colorado LASP ; ; Creation Date: 29 Feb 1996 ; Last Modified: 29 Feb 1996 ; ; History: ; ; Creation - This routine was part of the Release 1.1 of the OA library. ; ; Input: ; ; If the following IDL keyword(s) are present, their values will be used ; instead of interactively prompting the user. ; ; FILE_NAME - The name of or path to the PDS label file, e.g. ; '../labels/BROWSE.LBL' ; ; OBJECT_NAME - The name of the object, as it appears in the label file, ; e.g. 'IMAGE_HISTOGRAM'. ; ; BAND - If the input object is a multi-band IMAGE or QUBE, this ; is the band to read in, e.g. BAND=2 ; ; Output: ; ; IDL_VARIABLE - An IDL variable with the object data for the object read ; in. ; ; OA_OBJECT - Optional argument; if present, the OA_OBJECT pointer is ; returned in it, which can then be passed to other OAL ; functions. If not present, the OA_OBJECT is deleted ; before returning. ; ; ; Notes: ; ;***************************************************************************** pro OaIDLReadObject, IDL_OBJECT, OA_OBJECT, FILE_NAME=FILE_NAME, $ OBJECT_NAME=OBJECT_NAME,BAND=BAND IDL_OBJECT = 0 ; Define the directory for ODL_ERRORS.TXT and OAL_ERRORS.TXT to be written to. ; ; *** YOU MUST CHANGE THIS WHENEVER YOU MOVE THIS CODE!! *** case 1 of (!VERSION.arch eq 'mipseb'): begin ;SGI LABEL_DIR = '/miranda2/monk/oal/idl/' end (!VERSION.arch eq 'sparc'): begin ;Sun SPARCstation LABEL_DIR = '/kitron3/monk/oal/lbls/' end (!VERSION.arch eq 'alpha' and !VERSION.os eq 'OSF'): begin ;Dec Alpha/OSF LABEL_DIR = '/usr/users/monks/oal/lbls/' end (!VERSION.arch eq 'PowerMac'): begin ;Power Macintosh LABEL_DIR = 'MacT06-2:OAL:' end else: begin print,'OaIDL interface not yet ported to this platform: ' + !VERSION.arch return end endcase ;Prompt user for file name, unless passed in FILE_NAME keyword. if n_elements( FILE_NAME) eq 0 then begin print,format='($,"Enter PDS label spec")' FILE_NAME = '' read, FILE_NAME endif ;Have to route error messages to a file, because OaReportError's printf's ;crash IDL on some platforms (Macintosh). Z = OaRouteErrorMessages( LABEL_DIR + 'OAL_ERRORS.TXT', 0) ROOT_NODE = OaParseLabelFile( FILE_NAME, LABEL_DIR + 'ODL_ERRORS.TXT', 1, 0) if ROOT_NODE eq 0 then begin print,'OaParseLabelFile returned NULL for file: >', FILE_NAME,'<' return endif if n_elements( OBJECT_NAME) eq 0 then begin ;Prompt user with list of objects, and ask which object to read in. OBJECT_NAMES = '' ODLTREE_NODE = LeftmostChild( ROOT_NODE) while ODLTREE_NODE ne 0 do begin OBJECT_NAMES = OBJECT_NAMES + ' ' + OdlGetObjDescClassName( ODLTREE_NODE) ODLTREE_NODE = RightSibling( ODLTREE_NODE) endwhile OBJECT_NAMES = strmid( OBJECT_NAMES, 2, strlen( OBJECT_NAMES)-2) print,'Objects are: ' + OBJECT_NAMES print,format='($,"Enter object name")' OBJECT_NAME = '' read,OBJECT_NAME OBJECT_NAME = strupcase( OBJECT_NAME) endif ; Find the ODLTREE node with this name. ODLTREE_NODE = OdlFindObjDesc( ROOT_NODE, OBJECT_NAME, '', '', 0, 0) if ODLTREE_NODE eq 0 then begin print,'OdlFindObjDesc could not find ' + OBJECT_NAME + ' node!' return endif ;Read in the object. if n_elements( BAND) gt 0 then begin ;BAND keyword was set OBJECT_CLASS = OaGetObjectClass( ODLTREE_NODE) if OBJECT_CLASS eq 14 then begin ;14 because !OA.QUBE not defined yet. OA_OBJECT = OaReadImageFromQube( ODLTREE_NODE, BAND) endif if OBJECT_CLASS eq 12 then begin ;12 because !OA.IMAGE not defined yet. OA_OBJECT = OaReadImage( ODLTREE_NODE, BAND) endif endif else begin OA_OBJECT = OaReadObject( ODLTREE_NODE) endelse if OA_OBJECT eq 0 then begin print,'OaReadObject returned NULL!' return endif ;Convert the object to the IDL variable to be returned. IDL_OBJECT = OaIDLGetObjectData( OA_OBJECT) ; If the optional argument OA_OBJECT wasn't passed in, free OA_OBJECT. if n_params() eq 1 then begin Z = OaDeleteObject( OA_OBJECT) endif end ;***************************************************************************** ; This is a main program which gets run when this file is compiled via ; .run OAL_IDL_interface.pro. It defines two new read-only IDL system ; variables (if they're not already defined), !OA and !ODL, which are ; structures containing values for useful enumerated types used in OAL and ; L3 applications. WARNING! IF THESE ENUMS ARE CHANGED IN THE C CODE ; THEY MUST ALSO BE CHANGED HERE!!! ;***************************************************************************** defsysv, '!OA', EXISTS=EXISTS if EXISTS ne 1 then begin defsysv, '!OA',{oa_enum_struct, $ UNKNOWN_INTERCHANGE_FORMAT : 0, $ ASCII_INTERCHANGE_FORMAT : 1, $ BINARY_INTERCHANGE_FORMAT : 2, $ UNKNOWN_CLASS : 0, $ ALIAS : 1, $ ARRAY : 2, $ BIT_COLUMN : 3, $ BIT_ELEMENT : 4, $ COLLECTION : 5, $ COLUMN : 6, $ CONTAINER : 7, $ ELEMENT : 8, $ GAZETTEER : 9, $ HISTOGRAM : 10, $ HISTORY : 11, $ IMAGE : 12, $ PALETTE : 13, $ QUBE : 14, $ SERIES : 15, $ SPECTRUM : 16, $ TABLE : 17, $ ADD_ROWS : 0, $ ADD_COLUMNS : 1, $ UNKNOWN_TABLE_STORAGE_TYPE : 0, $ ROW_MAJOR : 1, $ COLUMN_MAJOR : 2, $ UNKNOWN_RECORD_TYPE : 0, $ FIXED_LENGTH : 1, $ STREAM : 2, $ VARIABLE_LENGTH : 3, $ UNDEFINED_RECORD_TYPE : 4, $ NO_ALIGN : 0, $ ALIGN_EVEN : 1, $ ALIGN_RISC : 2, $ ALPHA_OSF : 2, $ ALPHA_VMS : 0, $ IBM_PC : 2, $ MAC_IEEE : 1, $ SGI : 1, $ SUN3 : 1, $ SUN4 : 1, $ ULTRIX : 2, $ VAX : 0, $ ASCII_REAL : 99, $ ASCII_INTEGER : 1, $ ASCII_COMPLEX : 2, $ BIT_STRING : 3, $ BOOLEAN : 4, $ CHARACTER : 5, $ COMPLEX : 6, $ DATE : 7, $ FLOAT : 8, $ IBM_COMPLEX : 9, $ IBM_INTEGER : 10, $ IBM_REAL : 27, $ IBM_UNSIGNED_INTEGER : 11, $ IEEE_COMPLEX : 6, $ IEEE_REAL : 8, $ INTEGER : 16, $ LSB_BIT_STRING : 13, $ LSB_INTEGER : 14, $ LSB_UNSIGNED_INTEGER : 15, $ MAC_COMPLEX : 6, $ MAC_INTEGER : 16, $ MAC_REAL : 8, $ MAC_UNSIGNED_INTEGER : 17, $ MSB_BIT_STRING : 3, $ MSB_INTEGER : 16, $ MSB_UNSIGNED_INTEGER : 17, $ PC_COMPLEX : 18, $ PC_INTEGER : 14, $ PC_REAL : 19, $ PC_UNSIGNED_INTEGER : 15, $ REAL : 8, $ SUN_COMPLEX : 6, $ SUN_INTEGER : 16, $ SUN_REAL : 8, $ SUN_UNSIGNED_INTEGER : 17, $ TIME : 20, $ UNSIGNED_INTEGER : 17, $ VAX_BIT_STRING : 13, $ VAX_COMPLEX : 21, $ VAX_DOUBLE : 22, $ VAX_INTEGER : 14, $ VAX_REAL : 22, $ VAX_UNSIGNED_INTEGER : 15, $ VAXG_COMPLEX : 25, $ VAXG_REAL : 26, $ UNKNOWN_DATA_TYPE : 0, $ STRIP_KEYWORDS : 1, $ STRIP_COMMENTS : 2, $ STRIP_SDT_NODES : 3}, 1 ;1 = Read-only system variable endif defsysv, '!ODL', EXISTS=EXISTS if EXISTS ne 1 then begin defsysv, '!ODL',{odl_enum_struct, $ ODL_NOEXPAND : 0, $ ODL_EXPAND_STRUCTURE : 1, $ ODL_EXPAND_CATALOG : 2, $ ODL_RECURSIVE_DOWN : 0, $ ODL_TO_END : 1, $ ODL_CHILDREN_ONLY : 2, $ ODL_SIBLINGS_ONLY : 3, $ ODL_THIS_OBJECT : 4}, 1 ;1 = Read-only system variable endif end