CODAS WORKING DATABASE ---------------------- USER MANUAL ----------- The working database contains data (ADCP, CTD, etc.) currently being worked on. The system is composed of a set of data blocks and a corresponding directory. Both the directory and the blocks reside on disk as stream files. The data are accessed through a set of standard access routines written in C which can be called from either C or FORTRAN programs. Conceptual organization: --------------------- | BLOCK DIRECTORY | --------------------- . . | . . . . | . . | ============= | BLOCK | ============= | ----------------------- | PROFILE DIRECTORY | ----------------------- . . | . . . . | . . | ================== | PROFILE | ================== | --------------------- | DATA DIRECTORY | --------------------- | ================== | PROFILE DATA | ================== ACCESS TO WORKING CODAS DATABASE -------------------------------- DATA TYPES IN CODAS DATABASE: ============================ Every datum (data structure) contained in the database is identified by a numeric code. The following codes have been established: code data DBADD DBGET DBPUT ----------------------------------------------------------------------------- 0 - 99 USER DEFINED DATA YES YES YES 100 DATASET ID NO YES NO 101 PRODUCER ID NO YES NO 102 PROFILE TIME NO YES NO 103 PROFILE POSITION YES YES YES 104 BLOCK DATA MASK NO YES NO 105 BLOCK DATA PROCESSING MASK YES YES YES 106 DEPTH RANGE YES YES YES 200 DATABASE VERSION NO YES NO 201 PRODUCER HOST NO YES NO 202 DATABASE NUMBER NO YES NO 203 BLOCK/PROFILE NUMBER NO YES NO 300 BLOCK DIRECTORY FILE NO YES NO 301 CURRENT BLOCK FILE NO YES NO 302 PRODUCER DEFINITION FILE NO NO NO 303 TEMPORARY DATA FILE NO NO NO 304 BLOCK DIRECTORY HEADER NO YES NO 305 BLOCK DIRECTORY NO NO NO 306 BLOCK HEADER NO YES NO 307 DATA LIST NO NO NO 308 PROFILE DIRECTORY NO NO NO 309 DATA DIRECTORY NO NO NO 310 PROFILE DATA NO NO NO 311 PRODUCER DEFINITION NO NO NO 312 STRUCTURE DEFINITION NO YES YES 313 STRUCTURE FORMATS NO NO NO BAD/MISSING DATA: ================ A bad or missing datum is represented by the maximum value of its corresponding data type: for BYTE -- 127 UBYTE -- 255 SHORT -- 32767 USHORT -- 65535 (-1 in FORTRAN) LONG -- 2^31 - 1 ULONG -- 2^32 - 1 (-1 in FORTRAN) FLOAT -- roughly 10^38 DOUBLE -- roughly 10^38 FORTRAN REPRESENTATION OF DATA: ============================== 1 - TIME DATA: Time is expressed as a 6-element array of INTEGER*2. INTEGER*2 TIME(6) Where: TIME(1) --- year (whole year not only the last 2 digits) TIME(2) --- month TIME(3) --- day TIME(4) --- hour TIME(5) --- minute TIME(6) --- second 2 - POSITION DATA Position is expressed as an 8-element array of INTEGER*2. INTEGER*2 LATLON(8) Where: LATLON(1) -- longitude degrees LATLON(2) -- longitude minutes LATLON(3) -- longitude seconds LATLON(4) -- longitude hundredths of a second LATLON(5) -- latitude degrees (if < 0 South) LATLON(6) -- latitude minutes LATLON(7) -- latitude seconds LATLON(8) -- latitude hundredths of a second 3 - USER DEFINED DATA The producer definition file contains a description of these data. Just remember the following equivalences: BYTE --- is the same as --- BYTE CHAR --- " " " " --- CHARACTER*1 SHORT --- " " " " --- INTEGER*2 LONG --- " " " " --- INTEGER*4 FLOAT --- " " " " --- REAL*4 DOUBLE --- " " " " --- REAL*8 TEXT --- " " " " --- CHARACTER*1 For UBYTE, USHORT, and ULONG, it is easier and safer to use a REAL*4 and invoke the scaling functions to convert to and from the unsigned C data types. 4 - NAMES AND FILE NAMES When calling database routines that require string arguments (e.g., DBOPEN and DBCREATE), the character array containing the string argument should be passed by reference. 5 - ALL OTHER PARAMETERS Any other parameter to a database routine should be of type INTEGER. By default they will be INTEGER*4 in the VAX and INTEGER*2 in PC's. ERROR CODES: ============ Error codes returned by database access routines are of two types: User errors and Database errors. User errors are given as a positive number. The section captioned USER ERROR gives a description of these errors. Database errors (internal problems in database) are given by a negative number containing two pieces of information: (-IERR) / 1000 gives the database internal error code. See section DATABASE INTERNAL ERRORS. (-IERR) mod 1000 gives the data structure being accessed when failure occurred. See the section on DATA TYPES IN ADCP DATABASE. When Database errors occur, report the value of IERR to the database manager. Most likely you don't have privilege for accessing database files, or you gave the wrong database name, or your computer has insufficient memory. USER ERROR: code description ------------------- 0 - OK: Operation was completed successfully. 1 - INVALID_DATABASE_NUMBER: A database number outside the range 1 - 5 was specified in the call to DBOPEN, DBCREATE or DBSET. 2 - DB_IS_NOT_OPEN: Attempt to access a database that has not been opened. 3 - DB_ALREADY_OPEN Attempt to open/create a database that is already open. 4 - NO_OPEN_FOR_WRITE Attempt to modify (DBPUT) a database that is open for read only. 5 - NO_OPEN_FOR_CREATE Attempt to add data to a database not opened by DBCREATE. 6 - OPEN_FOR_CREATE Attempt to access a database opened by DBCREATE. 7 - DATABASE_IS_EMPTY Database contains no data blocks. 8 - INCORRECT_DATABASE_VERSION Database was created using a different (2. or older) version of CODAS. 9 - UNEXPECTED_STRUCTURE_SIZE Differences in machine alignment make it impossible to run CODAS. 11 - NO_BLOCK_IS_OPEN Attempt to access block data when no block has been located. 12 - NO_PROFILE_IS_OPEN Attempt to access profile data when no profile has been located. 13 - NO_NEW_BLOCK_IS_OPEN Attempt to add block/profile data before calling DBNEWBLK. 14 - NO_NEW_PROFILE_IS_OPEN Attempt to add profile data before calling DBNEWPRF. 15 - NEW_BLOCK_IS_OPEN Block must be terminated by DBENDBLK before attempted operation. 16 - NEW_PROFILE_IS_OPEN Profile must be terminated by DBENDPRF before attempted operation. 21 - BLOCK_DIR_IS_FULL No more blocks can be added. Database should be closed by DBCLOSE. 22 - BLOCK_IS_FULL No more profiles can be added to current block. Block should be closed by DBENDBLK and subsequent profiles added to a new block. 23 - INSUFFICIENT_SPACE Not enough space was reserved during database creation to DBPUT so many bytes. 31 - INVALID_TYPE_REQUEST An invalid type was specified in call to DBSRCH, DBADD, DBGET or DBPUT. 32 - INVALID_TIME An invalid time was used in call to DBNEWPRF or DBSRCH. 33 - INVALID_POSITION An invalid time was used in call to DBADD, DBGET or DBPUT. 34 - INVALID_VALUE_TYPE An invalid value type was specified in producer definition. 35 - INVALID_ACCESS_TYPE An invalid access type was specified in producer definition. 36 - NO_SUCH_BLOCK_PROFILE A non-existing block/profile number was specified for DBSRCH. 37 - INVALID_BUFFER_SIZE The size of the user array to hold user-defined data retrieved from the database is less than zero. 41 - SEARCH_BEYOND_END Attempt to search/move beyond end of database. 42 - SEARCH_BEFORE_BEGINNING Attempt to search/move before beginning of database. 51 - ZERO_SCALE Attempt to divide by a zero scale factor. 61 - PATHNAME_TOO_LONG Length of database pathname exceeds 31-character maximum. 62 - DBNAME_TOO_LONG Length of database name exceeds maximum defined by MAX_DBNAME_LENGTH in DBEXT.H (system-dependent parameter). 70 - UNDEFINED STRUCTURE Attempt to display structure with no definition and number of bytes unknown; attempt to convert structure with no structure definition. Provide an external structure definition file containing the structure's definition. 71 - UNKNOWN_HOST_ERROR Attempt to access database created by unrecognized machine. 72 - INCOMPATIBLE_HOST_ERROR Attempt to access database created by different machine. Use MKBLKDIR.EXE to convert database blocks across machines. 73 - STRUCTURE_NOT_PRESENT Attempt to DBPUT a structure definition for a structure that had not been defined at the time of database creation. 80 - FORMAT_ERROR Structure format supplied does not match structure definition. Check element names for exact spelling, etc. DATABASE INTERNAL ERRORS: code description -------------------- -2 - UNABLE_TO_OPEN A file could not be opened because it does not exist or due to insufficient privilege. -3 - FILE_DOES_NOT_EXIST -4 - FILE_ALREADY_EXISTS Attempt to create a file that already exists. -5 - FILE_PROTECTION_ERROR Attempt to access/create a file without sufficient privilege. -6 - READ_ERROR Error reading file. -7 - WRITE_ERROR Error writing file. -8 - SEEK_ERROR Error positioning in file. -9 - CLOSE_ERROR Error closing file. -10 - INSUFFICIENT_MEMORY Not enough memory for attempted operation. MISSING/BAD DATA: Missing or bad data are stored as: for BYTE datum is bad if = 127 for UBYTE datum is bad if = 255 for SHORT datum is bad if = 32767 for USHORT datum is bad if = 65535 for LONG datum is bad if = 2,147,483,647 for ULONG datum is bad if = 4,294,967,295 for FLOAT datum is bad if = 1.0e37 for DOUBLE datum is bad if = 1.0e37 ACCESS ROUTINES: The following subroutines can be used from within a FORTRAN/C program for accessing the CODAS database library. Your program should be linked as: LINK program-obj-module-name,[the-directory-name]DBLIB/LIB Description of access routines: ----------- DATABASE ACCESS ROUTINES ----------- - void DBOPEN(int *IDBID, char *DBNAME, int *IACCMOD, int *IMEMMOD, int *IERR) for VAX/VMS FORTRAN: SUBROUTINE DBOPEN (IDBID, %REF(DBNAME), IACCMOD, IMEMMOD, IERR) It opens an existing database for READ/MODIFY access. It loads the database directories and sets the access data structures. After the call, the database pointer is positioned at the first profile of the first block (block 0, profile 0). This subroutine must be the first one called in order to access an existing database. Arguments: Input: IDBID - The database number (1 - 5). DBNAME - Character string with the name of the database block directory file. The name can be up to 40 characters long. There must be at least 1 space following the name and no spaces before it. The string may be passed as a constant (i.e. 'WEP '), a CHARACTER variable or in a numeric array (i.e., read with format A). The compiler option %REF is needed for constant or CHARACTER strings. For systems with tree-directories like DOS or VAX/VMS you should give the path as part of the name. ex. for DOS 'C:\MYDATA\WEP ' for VMS 'DISK$USER:[WEPOCS.CABRERA.MWADCP]WEP ' IMEMMOD - If 0, the database will not load directories into memory; otherwise block and profile directories will be kept in memory. IMEMMOD = 0 should be used when memory is limited (i.e., in PCs) at the expense of a slower access time. IACCMOD - If 0, the database will be open for READ_ONLY; otherwise it will be open for READ_WRITE. Output: IERR - Resulting error code. - void DBSET(int *IDBID, int *IERR) for VAX/VMS FORTRAN: SUBROUTINE DBSET (IDBID, IERR) It makes database IDBID the current database. This database must already be open. Arguments: Input: IDBID - Number of new current database. Output: IERR - Resulting error code. - void DBCLOSE(int *IERR) for VAX/VMS FORTRAN: SUBROUTINE DBCLOSE (IERR) It closes the database. Arguments: Output: IERR - Resulting error code. - void DBSRCH(int *ITYPE, char *PARAMS, int *IERR) for VAX/VMS FORTRAN: SUBROUTINE DBSRCH (ITYPE, PARAMS, IERR) It positions the database at a specific profile (random access). Arguments: Input: ITYPE - Type of search. As of now, only search by time of profile (ITYPE = 1) and search by block/profile number (ITYPE = 2) are implemented. PARAMS - Search parameters. For ITYPE = 1, PARAMS is a time/date array. In this case DBSRCH will position the database at the first profile whose time is >= than the time in PARAMS. For ITYPE = 2, PARAMS is 2-element integer array with the block and profile numbers. In this case, DBSRCH will position the database at this block/ profile if it exists. Output: IERR - Resulting error code. Notes: If a time search goes before the first time in the database, this subroutine will leave the database pointer positioned at the first profile. If a time search goes beyond the last time in the database, the database pointer will be left at the last profile. Search for a non-existent block/profile will leave the database pointer at the profile at which it was positioned prior to the search. - void DBMOVE(int *ISTEPS, int *IERR) for VAX/VMS FORTRAN: SUBROUTINE DBMOVE (ISTEPS, IERR) It positions the database at ISTEPS profiles from the current profile. Arguments: Input: ISTEPS - Number of profiles to advance. ex. ISTEPS = 1 advances to next profile (in time) ex. ISTEPS = 12 advances 12 profiles ex. ISTEPS = -7 goes back 7 profiles Output: IERR - Resulting error code. Notes: As with DBSRCH, moves beyond either end of the database will leave the database pointer at the first or last profile. - void DBGET(int *ITYPE, char *DATA, unsigned int *N, int *IERR) void DBGET_F(int *ITYPE, float *DATA, unsigned int *N, int *IERR) for VAX/VMS FORTRAN: SUBROUTINE DBGET (ITYPE, DATA, N, IERR) SUBROUTINE DBGET_F (ITYPE, DATA, N, IERR) These retrieve specific data from the database. DBGET_F also provides automatic conversion/rescaling of the data to floating point values. Arguments: Input: ITYPE - Data type. DATA - Name of array/scalar variable where requested data will be stored. You are responsible for declaring enough elements in the case of arrays. N - Number of bytes to retrieve, in the case of DBGET Number of floating point values to retrieve, for DBGET_F Output: IERR - Resulting error code. - void DBPUT(int *ITYPE, char *DATA, unsigned int *N, int *IERR) void DBPUT_F(int *ITYPE, float *DATA, unsigned int *N, unsigned int *NBAD, int *IERR) for VAX/VMS FORTRAN: SUBROUTINE DBPUT (ITYPE, DATA, N, IERR) SUBROUTINE DBPUT_F (ITYPE, DATA, N, NBAD, IERR) These rewrite specific data to the database. DBPUT_F also provides automatic conversion/rescaling of floating point values to the data types used in the database. Arguments: Input: ITYPE - Data type. DATA - Name of array where requested data is stored. N - Number of bytes to rewrite, in the case of DBPUT Number of floating point values to rewrite, for DBPUT_F Output: NBAD - Number of values set to BAD due to conversion/rescaling to values outside range of database data type. IERR - Resulting error code. Notes: You must be careful when using these subroutines. If profile data is going to be modified, you should make sure that the database is positioned at the right profile. Ex. If you want to de-mean U profiles you would proceed as follows: 1 - Lock on a profile by calling DBSRCH and/or DBMOVE. 2 - Retrieve U by calling DBGET. 3 - De-mean U in your program. 4 - Re-store U by calling DBPUT. If you used DBSRCH or DBMOVE in between steps 2 and 4 you should re-locate the original profile before step 4. - void DBLOADSD(char *FILENAME, int *IERR) for VAX/VMS FORTRAN: SUBROUTINE DBLOADSD (%REF(FILENAME), IERR) This loads structure definitions from an external file. See the section below on EXTERNAL STRUCTURE DEFINITION FILE. Arguments: Input: FILENAME - Name of structure definition file to be loaded. Output: IERR - Resulting error code. - void DBPRTSTR(char *DATA, char *NAME, unsigned int *NBYTES) for VAX/VMS FORTRAN: SUBROUTINE DBPRTSTR(DATA, %REF(NAME), NBYTES) This is used to print structures or arrays of structures. The is used to locate the structure definition in order to print the structure elements in readable fashion; if the structure definition is not located, the structure is printed as an array of unsigned bytes. Arguments: Input: DATA - address of the structure buffer NAME - name of structure NBYTES - pointer to number of bytes in data buffer Output: Structure is displayed on screen. - int DBERROR(int *IERR, char *MESSAGE) for VAX/VMS FORTRAN: FUNCTION DBERROR(IERR, %REF(MESSAGE)) This is used to check the error code after a preceding database function call. If an error is detected, it prints a brief description of the error, and any accompanying . Arguments: Input: IERR - address of the error code MESSAGE - any message to be printed in case of error NULL, if none desired Output: Returns the error code (0 if none). An error message is displayed on the screen, if the error code is nonzero; no effect otherwise. ----------- DATABASE CREATION ROUTINES ------------- - void DBCREATE(int *IDBID, char *DBNAME, char *PRDFILE, int *IMEMMOD, int *IERR) for VAX/VMS FORTRAN: SUBROUTINE DBCREATE (IDBID, %REF(DBNAME), %REF(PRDFILE), IMEMMOD, IERR) It creates a new database or opens an existing one for ADD/DELETE access. It loads the database directories and set the access data structures. Arguments: Input: IDBID - The database number (1 - 5). DBNAME - Character string with the name of the database block directory file. PRDFILE - Name of file containing the producer definition. See section below on PRODUCER DEFINITION FILE. IMEMMOD - If 0, the database will not load directories into memory; otherwise block and profile directories will be kept in memory. Output: IERR - Resulting error code. - void DBNEWBLK(int *IERR) for VAX/VMS FORTRAN: SUBROUTINE DBNEWBLK (IERR) It creates a new block in the database and leaves it ready for adding block data. Arguments: Output: IERR - Resulting error code. - void DBENDBLK(int *IERR) for VAX/VMS FORTRAN: SUBROUTINE DBENDBLK (IERR) It terminates a new block in the database. Arguments: Output: IERR - Resulting error code. - void DBNEWPRF(char *TIME, int *IERR) for VAX/VMS FORTRAN: SUBROUTINE DBNEWPRF (TIME, IERR) It creates a new profile in the current new block and leaves it ready for adding profile data. Arguments: Input: TIME - Time of profile. It is a year,month,day,hour,min,sec structure ( INTEGER*2 TIME(6) ). Output: IERR - Resulting error code. - void DBENDPRF(int *IERR) for VAX/VMS FORTRAN: SUBROUTINE DBENDPRF (IERR) It terminates a new profile in the database. Arguments: Output: IERR - Resulting error code. - void DBADD(int *ITYPE, char *DATA, unsigned int *N, int *IERR) void DBADD_F(int *ITYPE, float *DATA, unsigned int *N, unsigned int *NBAD, int *IERR) for VAX/VMS FORTRAN: SUBROUTINE DBADD (ITYPE, DATA, N, IERR) SUBROUTINE DBADD_F (ITYPE, DATA, N, NBAD, IERR) These add specific data to the database. DBADD_F also provides automatic conversion/rescaling of floating point values to the data types used in the database. Arguments: Input: ITYPE - Data type. DATA - Name of array where requested data is stored. N - Number of bytes to add, in the case of DBADD Number of floating point values to add, for DBADD_F Output: NBAD - Number of data values set to BAD due to rescaling/ conversion to values outside range of data type. IERR - Resulting error code. The Producer Definition File ============================ The producer definition file is a text file that is required as input whenever a CODAS database is to be created, whether from raw Ping data files (LOADPING), ASCII text files (LOAD_ASC), or from existing CODAS block files (MKBLKDIR, DB2TODB3). It provides information pertinent to the characteristics of the database to be created: the instrument used in data gathering, dataset identification, the variables to be loaded, etc. Hence, it is also an important part of the documentation for a database, and is best kept together with the database itself. The producer definition file contains both required parameters and optional parameters. The required parameters must appear first and in a fixed order. The optional parameters follow. In either case, each parameter must be preceded by the appropriate keyword and at least one space. Comments may appear anywhere, as long as they are enclosed between a /* and */. For an example of the producer definition file, see \CODAS3\ADCP\DEMO\MWADCP.DEF. Required parameters. ------------------- Required parameters provide essential information for identifying and classifying a given CODAS database. The following parameters, therefore, must always be present in the producer definition file in the indicated order: Keyword Parameter Example ------- ----------------- DATASET_ID ADCP-VM PRODUCER_ID 32R2MW0001 BLOCK_DIR_TYPE 0 PROFILE_DIR_TYPE 3 Each keyword is scanned for (case-sensitive!) in this order and the following noncomment word is interpreted accordingly. DATASET_ID. This is a string for identifying the type of instrument used to gather data. The string has a maximum length of 31 characters (including spaces following the first non-whitespace character), where the first 8 are the instrument name, and the remainder are currently unassigned and may be used for any other qualifiers. In the example above, the instrument name is ADCP-VM, indicating an Acoustic Doppler Current Profiler (Vessel-Mounted) was used. Following are names that can be used for the indicated instrument, based on common terminology: Name Instrument ---- ---------- ADCP-VM vessel-mounted ADCP ADCP-BM bottom-mounted ADCP ADCP-MO moored ADCP XBT XBT CTD CTD CTD-ROS CTD with bottle samples ACOUS-DS acoustic dropsonde (Pegasus, WH) IES inverted echo sounder MCM moored current meter SSP sub-surface pressure gauge TIDE tide gauge It should be noted that any database may contain data from more than one instrument/source, such as navigational instruments, weather observations, and so forth; the DATASET_ID identifies only the primary instrument. PRODUCER_ID. This is a string for identifying the institution responsible for the data collected. The string has a maximum length of 31 characters (including any spaces following the first non-whitespace character). The 31-character string has been subdivided into the following fields: Character Position Encodes --------- ------- 1 - 2 country 3 - 4 institution 5 - 6 platform 7 - 10 instrument code 11 - 32 unassigned The first three fields above (country, institution, and platform) use the standard NODC codes. In the example above, 32R2MW is the NODC code for the United States (32), University of Hawaii (R2), and the R/V Moana Wave (MW). (The United States has two country codes under the NODC system: 31 and 32. Either one may be used.) The fourth field, instrument code, should be based on the institution's (or principal investigator's) own coding system, to provide unique identification for each of its own instruments. Some sequential numbering system will do. Duplication of numbers across instrument types should not pose significant problems, since the instrument name in the DATASET_ID can provide differentiation. BLOCK_DIR_TYPE. The block directory type is intended for distinguishing different types of CODAS block directories. At present, there is only one such type, designated by the integer 0. PROFILE_DIR_TYPE. The profile directory type is intended for distinguishing different types of CODAS profile directories. Each entry in the profile directory provides values for key variables for each profile in that file; which key variables are included in the profile directory depends on the manner in which the data have been gathered. At present, there are three different types of CODAS profile directories: Type Key(s) ---- ------ 0 time 1 time & position 2 time & depth range 3 time, depth range, & position Hence, data gathered from a fixed installation would not require position as a key variable in the profile directory. Moving installations, on the other hand, would require a position key. A similar distinction may be drawn for the depth range key. It is best to include only those keys that would vary from profile to profile, since each additional key increases storage space requirements. Optional Parameters. ------------------- These parameters identify and classify the variables in a CODAS database, and may also be used to define the elements for structure data types, if present, for proper interpretation during access and conversions. They may appear in any order or not at all, depending on the kind of data present. They use the following keywords: Keyword Parameter Example ------- ----------------- BLOCK_VAR 35 STRUCT CONFIGURATION_1 0 1 none UNUSED 36 STRUCT CONFIGURATION_2 0 1 none PROFILE_VAR 37 STRUCT ANCILLARY_1 0 1 none DEFINE_STRUCT CONFIGURATION_1 23 BLOCK_VAR. This keyword is used to declare that the indicated variable is present in the CODAS database and is constant across profiles within a given block file (it varies only across blocks). Its syntax is given by: BLOCK_VAR ------ Each variable in a CODAS database must be assigned a unique identification number. In fact, we prescribe an entire numbering scheme that covers most variables that we anticipate to be included in any type of oceanographic application. This is given by the file \CODAS3\INCLUDE\DATA_ID.H and also the example producer definition file, \CODAS3\DOC\OCEANDAT.DEF. The identification numbers run from 0 to a maximum of 32767. It is recommended that the user adopt a similar numbering scheme as provided in DATA_ID.H for consistency, and use the unassigned numbers for variables that may not be on that list. ------------ The indicates what type of values the variable may assume. It must be given by any one of the following reserved words: Reserved C language FORTRAN Word Equivalent Equivalent -------- ---------- ---------- CHAR char CHARACTER*1 BYTE char CHARACTER*1 UBYTE unsigned char CHARACTER*1 SHORT short int INTEGER*2 USHORT unsigned short int INTEGER*2 LONG long int INTEGER*4 ULONG unsigned long int INTEGER*4 FLOAT float REAL*4 DOUBLE double REAL*8 COMPLEX struct {float real; float imaginary} ARRAY OF REAL*4 TEXT char[] (string) ARRAY OF CHARACTER STRUCT struct ARRAY OF CHARACTER EQUIVALENCE ... It should be noted that the FORTRAN equivalences given above are not quite accurate because certain C language data types are not available in FORTRAN. For example, FORTRAN does not have unsigned data types, in which case, one has the option of using the signed data type equivalent given above and remember to interpret the negative signs appropriately, or using the signed data type directly following, e.g., using a FLOAT for ULONG or a LONG for USHORT. While the latter option avoids sign confusion, it adds to either space requirements or level of complexity. Another C data type not available in FORTRAN is "struct", which can be approximated as an array of character, appropriate portions of which are equated to the appropriate element type using the EQUIVALENCE statement. For example, suppose the C structure is defined as: struct { SHORT first_good_bin, last_good_bin; FLOAT U_ship_absolute, V_ship_absolute; SHORT user_flag_1, user_flag_2, user_flag_3, user_flag_4; } acc_var; A FORTRAN program may access the same structure using the following declaration: CHARACTER(20) ACCVAR INTEGER*2 FGB, LGB REAL*4 USA, VSA INTEGER*2 UF1, UF2, UF3, UF4 EQUIVALENCE (ACCVAR(1), FGB), (ACCVAR(3), LGB), & (ACCVAR(5), USA), (ACCVAR(9), VSA), & (ACCVAR(13), UF1), (ACCVAR(15), UF2), & (ACCVAR(17), UF3), (ACCVAR(19), UF4) For each of the simple numeric value types above, the following byte sizes and hence, anticipated ranges are observed: Value Size in Type Bytes Anticipated Range ----- ------- ----------------- BYTE 1 -128 to +127 UBYTE 1 0 to +255 SHORT 2 -32768 to +32767 USHORT 2 0 to +65535 LONG 4 -2,147,483,648 to +2,147,483,647 ULONG 4 0 to +4,294,967,295 FLOAT 4 -1.0e38 to +1.0e38 DOUBLE 8 -1.0e38 to +1.0e38 Note that the actual ranges for FLOATs and DOUBLEs are implementation-dependent and that the anticipated ranges represent an approximate minimum among various machines tested. At this point, it is not relevant to indicate the size of arrays, if any. That is done during the actual loading of the database. --------------- The is a unique string that matches a given . Each name should contain only alphanumeric characters and underscores. The maximum number of characters is 19. See the file \CODAS3\INCLUDE\DATA_ID.H for a list of recommended variable names and their identification numbers that the user can select from. One may use the unassigned numbers for new variable names, if a suitable one is not found in that file. , and ----------------------------- The and are given by floating point numbers separated by a space. The is specified as a string (11-character maximum) with no embedded spaces. Units should be mks or one of a few special oceanographic variables. The basic unit specifications that have been defined so far are: m meters s seconds kg kilograms C degrees C dbar decibars dyn_m dynamic meters ppt parts per thousand none no standard unit, or irrelevant Undoubtedly, more will be added. Specifications should be as simple as possible in any case. Exponents should be given by a simple positive integer following the unit. Numerator and denominator are separated by "/". If units are irrelevant for a given variable, then they should be specified as "none", NOT left blank. The offset and scale are used for automatically converting data between the form in which they are actually stored in the database and the form indicated by the units, when the user so specifies (see DBADD_F, DBGET_F, and DBPUT_F). If there is a perfect match between these two forms, then the offset and scale should be designated as 0 and 1, respectively. A major reason for rescaling data is to economize on storage. For example, U-component velocities expressed in meters/second would require FLOATs (4 bytes) in order to preserve precision. Rescaling with an offset of 0 and a scale of .001 would permit compressing storage requirements to 2-byte SHORTs. PROFILE_VAR. This keyword is used to declare that the indicated variable is present in the CODAS database and that it varies across profiles. It should be followed by the following parameters: PROFILE_VAR See the section on BLOCK_VAR above for a description of each of the parameters. It should be noted that declaring a variable to be PROFILE_VAR, rather than BLOCK_VAR, causes it to be stored with each profile in a given block file. Hence, a variable whose value(s) does not vary across profiles is best declared as BLOCK_VAR in order to save space. UNUSED. This keyword is used to declare that the indicated variable is not present in the CODAS database. Actually, one has the option of leaving out the variable from the producer definition file in order to indicate this, resulting in quicker processing of the file and very minor space saving. The preferred alternative, however, is to leave the variable in and declare it as UNUSED, in order to preserve the original file contents as much as possible. DEFINE_STRUCT. This keyword is used to indicate that a structure-type variable is about to be defined. The variable may either be one of the BLOCK_VAR or PROFILE_VAR structure-type variables, or a structure-type element occurring in another structure definition. It does not make sense to define UNUSED structure-type variables as this would result in unnecessarily larger block files and probably slower access. A structure definition consists of a list of element specifications that comprise the structure. Its syntax is given by either of the following forms, depending on what level of structure-type variable is being defined: DEFINE_STRUCT DEFINE_STRUCT The or must exactly match its initial occurrence in order to establish the association with the structure definition. The parameter signifies how many elements comprise the structure, as indicated by the number of ELEM statements that must directly follow the DEFINE_STRUCT statement. The syntax of the ELEM statement is: ELEM For example: ELEM 1 FLOAT avg_interval s ELEM 1 SHORT num_bins none ------- This parameter indicates whether the element is single-valued or an array of the indicated value type. ------------ This parameter indicates the type of values that the element may assume. It follows the specifications described above for the value type parameter in a BLOCK_VAR statement. -------------- This is a string that will be used to reference the particular element. It follows the specifications described above for the variable name parameter in a BLOCK_VAR statement. ------- This is a string that indicates the unit of measure used for the given element value. It follows the specifications described above for the units parameter in a BLOCK_VAR statement. The External Structure Definition File ====================================== The external structure definition file is an optional file that is useful for accessing a database that has structure-type variables. It permits: 1) printing the contents of structure-type variables in readable format, in case the structure definition was not loaded into the database at the time of creation. 2) providing a new structure definition for use during current access, overriding that stored in the database at the time of creation. 3) specifying print formats to override the default. An external structure definition file therefore uses two major types of statements: DEFINE_STRUCT DEFINE_FORMAT In both cases, the refers to a structure-type variable, or a structure-type element occurring in another structure-type variable or element. (That is, the latter can be nested several levels deep.) The parameter signifies the number of elements that comprise the structure, which should match the number of lower-level statements (ELEM, FORMAT) that immediately follow. See the file \CODAS3\UTIL\MORE_SD.DAT for an example of an external structure definition file. DEFINE_STRUCT. The DEFINE_STRUCT statement has two options: 1) it can look exactly like that described under the DEFINE_STRUCT section on the producer definition file. 2) each ELEM statement in the above version can be followed by a FORMAT statement indicating the printing format to be used for that element in place of the default. A FORMAT statement in this case would look like: FORMAT "" --------------- The is a C language type format string that may contain plain and escape characters, and conversion specifications. The quotation marks must be provided to delimit the string contents. See any C reference manual for further details. ------------ The is used to control scrolling when printing is directed to the screen. The following values may be used (case is irrelevant here): PAUSE GO PAUSE means that the program will stop after printing that particular element, and will resume printing the remaining elements only after the user presses the enter key. GO means that the program should continue with printing the subsequent element. --------------------- The print function name is used to indicate whether a special printing function should be used in place of the default generic "fprintf" function in the C language. This is useful when the element value stored must undergo some conversion prior to printing. For example, if an element contains latitude measured in hundredths of a degree, one may want to convert it to the usual degree-minutes-seconds- hundredths format and have it printed accordingly. A set of CODAS printing functions have such conversions built in and may be used for this parameter: Print Function Name What It Does ------------------- ------------ print_bit_pattern it takes a ULONG value and prints it as 32 bits prpckt it takes a ULONG time expressed in hundredths of a second and prints it in yyyy/mm/dd hh:mm:ss.hh format prpckp it takes a ULONG position expressed in hundredths of a degree and prints it in ddd' mm" hh.ss format print_ymdhms_time it prints a YMDHMS_TIME_TYPE structure in yyyy/mm/dd hh:mm:ss.hh format print_dmsh_position it prints a DMSH_POSITION_TYPE structure in ddd' mm" hh.ss format NULL uses default printing function fprintf For example: ELEM 1 FLOAT snd_spd_used m/s FORMAT "\nsound speed used.......... %6.2e m/s" GO NULL The element snd_spd_used is declared as a FLOAT. When printing this element, a new line is used and the indicated label is printed first, prior to printing the value in exponential notation with field width of 6 and 2 decimal places followed by the unit of measure. The GO indicates that there should be no pause in screen output between printing this element and the succeeding one. The NULL indicates that the default printing function be used. DEFINE_FORMAT. This statement is used to define a printing format for a structure whose definition has already been indicated elsewhere, either inside the block file structure definitions, or in another DEFINE_STRUCT statement in an external structure definition file. As mentioned, its syntax is given by: DEFINE_FORMAT It is immediately followed by FORMAT statements, each of which provides the printing format for the corresponding element in the structure. Note that the ordering of FORMAT statements should match the arrangements of elements in the structure and that there should be a one-to-one correspondence between the FORMAT statement and the elements in the structure. The FORMAT statement has a slightly different form when used with the DEFINE_FORMAT statement: FORMAT "" "" The additional parameter is the name of the structure element corresponding to the FORMAT statement and is used to match up the format with the element. Hence, it must exactly match the structure definition element name.