/*
******************************************************************************** * label.c -- Routines for PDS label objects * * User routines: * Pro_OpenLabel() creates a PDS label object. * Pro_LabelCount() returns the number of tables/columns/items. * Pro_LabelName() returns the name of a table/column. * Pro_LabelFind() returns the index of a named table/column. * Pro_LabelSampling() returns the sampling parameters of a column. * Pro_LabelInt() returns the integer value of a label keyword. * Pro_LabelFloat() returns the floating point value of a keyword. * Pro_LabelString() returns the string value of a keyword. * * Programmer routines: * XPro_LabelInfo() returns the key parameters of a column. * * Neil Heather & Mark Showalter, PDS Ring-Moon Systems Node, March 1998. *******************************************************************************/ #include <stdio.h> #include <string.h> #include <math.h> #include "profile.h" #include "fortran.h" #include "oal.h" /************************* * Data type definitions * *************************/ typedef struct ZPRO_COLUMN_STRUCT { ODLTREE odltree; RL_CHAR name[PRO_NAMELEN+1]; RL_INT4 items; /* Default: 1 */ RL_FLT8 missing; /* Default: -HUGE_VAL */ RL_FLT8 invalid; /* Default: -HUGE_VAL */ RL_FLT8 offset; /* Default: 0.0 */ RL_FLT8 scale; /* Default: 1.0 */ } ZPRO_COLUMN; typedef struct ZPRO_TABLE_STRUCT { ODLTREE odltree; RL_CHAR name[PRO_NAMELEN+1]; RL_CHAR xname[PRO_NAMELEN+1]; RL_INT4 nrows, ncolumns; RL_FLT8 x1, x2, dx; ZPRO_COLUMN *columns; } ZPRO_TABLE; typedef struct ZPRO_LABEL_STRUCT { XPRO_CLASS class; ODLTREE odltree; /* the root node of the label file */ RL_CHAR filename[PRO_FILELEN+1]; RL_INT4 ntables; ZPRO_TABLE *tables; } ZPRO_LABEL; /******************************** * Internal function prototypes * ********************************/ static void ZPro_FreeLabel RL_PROTO((RL_VOID *pointer)); static void ZPro_PrintLabel RL_PROTO((RL_VOID *pointer)); static ZPRO_LABEL *ZPro_LabelPtr RL_PROTO((PRO_OBJECT *object)); static ZPRO_TABLE *ZPro_TablePtr RL_PROTO((PRO_OBJECT *object, RL_INT4 ntable)); static ZPRO_COLUMN *ZPro_ColumnPtr RL_PROTO((PRO_OBJECT *object, RL_INT4 ntable, RL_INT4 ncolumn)); static RL_BOOL ZPro_GetParam RL_PROTO((ODLTREE odltree, RL_CHAR *name, RL_CHAR **ptr)); static RL_BOOL ZPro_GetInt RL_PROTO((ODLTREE odltree, RL_CHAR *name, RL_INT4 *value)); static RL_BOOL ZPro_GetFloat RL_PROTO((ODLTREE odltree, RL_CHAR *name, RL_FLT8 *value)); static RL_BOOL ZPro_GetString RL_PROTO((ODLTREE odltree, RL_CHAR *name, RL_CHAR *value, RL_INT4 maxlen)); static void ZPro_DefInt RL_PROTO((ODLTREE odltree, RL_CHAR *name, RL_INT4 dfault, RL_INT4 *value)); static void ZPro_DefFloat RL_PROTO((ODLTREE odltree, RL_CHAR *name, RL_FLT8 dfault, RL_FLT8 *value)); static void ZPro_DefFloat2 RL_PROTO((ODLTREE odltree, RL_CHAR *name1, RL_CHAR *name2, RL_FLT8 dfault, RL_FLT8 *value)); static void ZPro_DefString RL_PROTO((ODLTREE odltree, RL_CHAR *name, RL_CHAR *dfault, RL_CHAR *value, RL_INT4 maxlen)); static void ZPro_DefName RL_PROTO((ODLTREE odltree, RL_CHAR *name, RL_CHAR *unit, RL_CHAR *dfault, RL_CHAR *value, RL_INT4 maxlen)); /******************** * Static variables * ********************/ static XPRO_CLASS label_class = {XPRO_LABEL_CLASS, "PDS label", NULL}; #define TEMP_MAXLEN 255 static RL_CHAR temp_name[TEMP_MAXLEN+1]; /********************* * Macro definitions * *********************/ #define SUPPRESS_MESSAGES 1 /* ******************************************************************************** * EXPORTED USER ROUTINES ******************************************************************************** *$ Component_name: * Pro_OpenLabel (label.c) *$ Abstract: * This routine opens the specified PDS label file and creates a label * object. *$ Keywords: * PROFILE * C, PUBLIC, SUBROUTINE *$ Declarations: * PRO_OBJECT *Pro_OpenLabel(labelfile) * RL_CHAR *labelfile; *$ Inputs: * *labelfile name of PDS label file. *$ Outputs: * none *$ Returns: * pointer to a new label object. *$ Detailed_description: * This routine opens the specified PDS label file and creates a label * object. It parses the label to find the TABLE and SERIES objects. Use * Pro_ColumnSeries() (see column.c) to create a series object from one of * the columns. *$ External_references: * Profile toolkit, Object Access library. *$ Side_effects: * Memory is allocated. The label file is opened. *$ Examples: * This snippet of code creates a label object for a PDS file called * "table.tab": * * PRO_OBJECT *label; * * label = Pro_OpenLabel("table.tab"); *$ Error_handling: * Profile library error handling is in effect. * * Conditions raised: * PRO_SETUP_FAILURE if the label cannot be read or parsed or has no * TABLE or SERIES objects. *$ Limitations: * none *$ Author_and_institution: * Mark R. Showalter * NASA/Ames Research Center *$ Version_and_date: * 1.0: March 1998 *$ Change_history: * none *******************************************************************************/ PRO_OBJECT *Pro_OpenLabel(labelfile) RL_CHAR *labelfile; { ODLTREE root_node, node; PRO_OBJECT *new; ZPRO_LABEL *label; ZPRO_TABLE *table; ZPRO_COLUMN *column; RL_INT4 i, j, ntables, nseries; /**************************** * Read and parse the label * ****************************/ root_node = OaParseLabelFile(labelfile, NULL, ODL_EXPAND_STRUCTURE, (unsigned short) SUPPRESS_MESSAGES); if (root_node != NULL) root_node = OaConvertLabel(root_node); if (root_node == NULL || (oa_errno >= 500 && oa_errno < 900)) { (void) sprintf(xpro_message, "label parsing failure\n\ Unable to read/parse label in file \"%s\"\n\ OA Library error code %d", labelfile, oa_errno); RL_RaiseError("PRO_SETUP_FAILURE", xpro_message); if (root_node != NULL) OdlFreeTree(root_node); return NULL; } /********************************** * Count the SERIES & TABLE nodes * **********************************/ for (i=1; ; i++) { node = OdlFindObjDesc(root_node, "*SERIES", NULL, NULL, (unsigned long) i, ODL_RECURSIVE_DOWN); if (node == NULL) break; } ntables = i - 1; for (i=1; ; i++) { node = OdlFindObjDesc(root_node, "*TABLE", NULL, NULL, (unsigned long) i, ODL_RECURSIVE_DOWN); if (node == NULL) break; } ntables += i - 1; if (ntables == 0) { (void) sprintf(xpro_message, "label setup failure\n\ No TABLE or SERIES objects found in label \"%s\"", labelfile); RL_RaiseError("PRO_SETUP_FAILURE", xpro_message); OdlFreeTree(root_node); return NULL; } /*************************************** * Initialize the ZPRO_LABEL structure * ***************************************/ label = (ZPRO_LABEL *) XRL_Malloc(sizeof(ZPRO_LABEL)); if (label == NULL) return NULL; label->class = label_class; label->odltree = root_node; (void) strncpy(label->filename, labelfile, PRO_FILELEN); label->filename[PRO_FILELEN] = '\0'; label->ntables = ntables; label->tables = (struct ZPRO_TABLE_STRUCT *) XRL_Malloc(ntables * sizeof(ZPRO_TABLE)); if (label->tables == NULL) { ZPro_FreeLabel((RL_VOID *) label); return NULL; } /***************************************** * Fill in the SERIES and TABLE pointers * *****************************************/ for (i=1; ; i++) { node = OdlFindObjDesc(root_node, "*SERIES", NULL, NULL, (unsigned long) i, ODL_RECURSIVE_DOWN); if (node == NULL) break; label->tables[i-1].odltree = node; } nseries = i - 1; for (i=1; ; i++) { node = OdlFindObjDesc(root_node, "*TABLE", NULL, NULL, (unsigned long) i, ODL_RECURSIVE_DOWN); if (node == NULL) break; label->tables[nseries + i-1].odltree = node; } /***************************** * Fill each table structure * *****************************/ for (i=0; i < ntables; i++) { table = &(label->tables[i]); node = table->odltree; ZPro_DefString(node, "NAME", "", table->name, PRO_NAMELEN); ZPro_DefInt(node, "ROWS", 1, &(table->nrows)); ZPro_DefInt(node, "COLUMNS", 1, &(table->ncolumns)); ZPro_DefFloat2(node, "MINIMUM_SAMPLING_PARAMETER", "START_SAMPLING_PARAMETER", 1., &(table->x1)); ZPro_DefFloat2(node, "MAXIMUM_SAMPLING_PARAMETER", "STOP_SAMPLING_PARAMETER", (RL_FLT8) table->nrows, &(table->x2)); ZPro_DefFloat(node, "SAMPLING_PARAMETER_INTERVAL", 1., &(table->dx)); ZPro_DefName(node, "SAMPLING_PARAMETER_NAME", "SAMPLING_PARAMETER_UNIT", "ROW_INDEX", table->xname, PRO_NAMELEN); /****************************** * Allocate column structures * ******************************/ table->columns = (struct ZPRO_COLUMN_STRUCT *) XRL_Malloc(table->ncolumns * sizeof(ZPRO_COLUMN)); if (table->columns == NULL) { ZPro_FreeLabel((RL_VOID *) label); return NULL; } /********************************************** * For each table, fill each column structure * **********************************************/ for (j=1; j <= table->ncolumns; j++) { node = OdlFindObjDesc(table->odltree, "*COLUMN", NULL, NULL, (unsigned long) j, ODL_RECURSIVE_DOWN); /* ODL_THIS_OBJECT doesn't work! */ if (node == NULL) { /* This should never happen */ label->tables[i].ncolumns = j-1; break; } column = &(table->columns[j-1]); column->odltree = node; (void) sprintf(xpro_message, "COLUMN_%d", j); ZPro_DefName(node, "NAME", "UNIT", xpro_message, column->name, PRO_NAMELEN); ZPro_DefInt(node, "ITEMS", 1, &(column->items)); ZPro_DefFloat2(node, "MISSING_CONSTANT", "MISSING", -HUGE_VAL, &(column->missing)); ZPro_DefFloat2(node, "INVALID_CONSTANT", "INVALID", -HUGE_VAL, &(column->invalid)); ZPro_DefFloat(node, "OFFSET", 0., &(column->offset)); ZPro_DefFloat(node, "SCALING_FACTOR", 1., &(column->scale)); } } /********************* * Create new object * *********************/ new = XPro_MakeObject(0., 0., ZPro_FreeLabel, ZPro_PrintLabel, (RL_VOID *) label); return new; } /* ******************************************************************************** *$ Component_name: * Pro_LabelCount (label.c) *$ Abstract: * This routine returns the number of tables in a PDS label object, the * number of columns in a table, or the number of items in a column. *$ Keywords: * PROFILE, SERIES, LABEL * C, PUBLIC, SUBROUTINE *$ Declarations: * RL_INT4 Pro_LabelCount(object, ntable, ncolumn) * PRO_OBJECT *object; * RL_INT4 ntable, ncolumn; *$ Inputs: * object pointer to the PDS label object. * ntable index of the selected table (0 or 1...n). * ncolumn index of the selected column (0 or 1...n). *$ Outputs: * none *$ Returns: * If ntable is zero, this is the number of tables in the label; * If ncolumn is zero, this is the number of columns in the selected table; * Otherwise, this is the number of items in the selected column. *$ Detailed_description: * This routine returns the number of tables in a PDS label object, the * number of columns in a table, or the number of items in a column. * * The quantity returned depends on the which input parameters are set to * zero. If ntable is zero, the total number of PDS TABLE and SERIES * objects is returned. Otherwise, ntable is the index (starting with 1) * of the selected table. If ncolumn is zero, the number of PDS COLUMN * objects in the selected table is returned. Otherwise, ncolumn is the * index (starting with 1) of the selected column and the number of ITEMs * in the column is returned. *$ External_references: * Profile toolkit *$ Side_effects: * none *$ Examples: * Suppose the PDS label associated with an object looks like this: * * ^TIME_SERIES = "FOOBAR.TAB" * ^DATA_TABLE = "FOOBAR.DAT" * ^IMAGE = "FOOBAR.IMG" * OBJECT = TIME_SERIES * ... (3 columns defined, each with 1 item) * END_OBJECT = TIME_SERIES * OBJECT = DATA_TABLE * ... (1 column defined, with 600 items) * END_OBJECT = DATA_TABLE * OBJECT = IMAGE * ... * END_OBJECT = IMAGE * END * * Then Pro_LabelCount(label, 0, 0) returns 2 (number of tables or series); * Pro_LabelCount(label, 1, 0) returns 3 (columns in TIME_SERIES); * Pro_LabelCount(label, 1, 1) returns 1 (items in column); * Pro_LabelCount(label, 2, 1) returns 600 (items in column); *$ Error_handling: * Profile library error handling is in effect. * * Conditions raised: * PRO_CLASS_ERROR if object is NULL or is not a PDS label. * PRO_DOMAIN_ERROR if the table or column index is out of range. *$ Limitations: * none *$ Author_and_institution: * Mark R. Showalter * NASA/Ames Research Center *$ Version_and_date: * 1.0: March 1998 *$ Change_history: * none *******************************************************************************/ RL_INT4 Pro_LabelCount(object, ntable, ncolumn) PRO_OBJECT *object; RL_INT4 ntable, ncolumn; { ZPRO_LABEL *label; ZPRO_TABLE *table; ZPRO_COLUMN *column; /********************** * Return table count * **********************/ if (ntable == 0) { label = ZPro_LabelPtr(object); if (label == NULL) return 0; return label->ntables; } /********************************* * Otherwise return column count * *********************************/ if (ncolumn == 0) { table = ZPro_TablePtr(object, ntable); if (table == NULL) return 0; return table->ncolumns; } /******************************* * Otherwise return item count * *******************************/ column = ZPro_ColumnPtr(object, ntable, ncolumn); if (column == NULL) return 0; return column->items; } /* ******************************************************************************** *$ Component_name: * Pro_LabelName (label.c) *$ Abstract: * This routine returns the name of the specified table or column. *$ Keywords: * PROFILE, SERIES, LABEL * C, PUBLIC, SUBROUTINE *$ Declarations: * RL_CHAR *Pro_LabelName(object, ntable, ncolumn) * PRO_OBJECT *object; * RL_INT4 ntable, ncolumn; *$ Inputs: * object pointer to the PDS label object. * ntable index of selected table (1...n). * ncolumn index of the selected column (0 or 1...n). *$ Outputs: * none *$ Returns: * a pointer to a (read-only) string containing the desired name. * If ncolumn is zero, this is the name of the selected table; otherwise, * this is the name of the selected column. *$ Detailed_description: * This routine returns the name of the specified table or column. * * The quantity returned depends on the which input parameters are set to * zero. If ncolumn is zero, the name of the PDS TABLE or SERIES object is * returned; otherwise, ncolumn is the index (starting with 1) of the * selected column and the routine returns the column's name. * * COLUMN names are defined by the PDS label's NAME field, followed by a * space and (if present) the PDS label's UNIT field in parentheses. *$ External_references: * Profile toolkit *$ Side_effects: * none *$ Examples: * Suppose the PDS label associated with an object looks like this: * * ^SERIES = "PS1G02.TAB" * OBJECT = SERIES * NAME = OCCULTATION_GEOMETRY * SAMPLING_PARAMETER_NAME = RECORD_INDEX * SAMPLING_PARAMETER_UNIT = 'N/A' * START_SAMPLING_PARAMETER = -16. * STOP_SAMPLING_PARAMETER = 1296. * SAMPLING_PARAMETER_INTERVAL = 1.0 * OBJECT = COLUMN * NAME = RECORD_INDEX * UNIT = 'N/A' * END_OBJECT = COLUMN * OBJECT = COLUMN * NAME = INTERCEPT_RADIUS * UNIT = "km" * END_OBJECT = COLUMN * END_OBJECT = SERIES * END * * Then Pro_LabelName(label, 1, 0) returns "OCCULTATION_GEOMETRY"; * Pro_LabelName(label, 1, 1) returns "RECORD_INDEX"; * Pro_LabelName(label, 1, 2) returns "INTERCEPT_RADIUS (km)" *$ Error_handling: * Profile library error handling is in effect. * * Conditions raised: * PRO_CLASS_ERROR if object is NULL or is not a PDS label. * PRO_DOMAIN_ERROR if the table or column index is out of range. *$ Limitations: * none *$ Author_and_institution: * Mark R. Showalter * NASA/Ames Research Center *$ Version_and_date: * 1.0: March 1998 *$ Change_history: * none *******************************************************************************/ RL_CHAR *Pro_LabelName(object, ntable, ncolumn) PRO_OBJECT *object; RL_INT4 ntable, ncolumn; { ZPRO_TABLE *table; ZPRO_COLUMN *column; /********************* * Return table name * *********************/ if (ncolumn == 0) { table = ZPro_TablePtr(object, ntable); if (table == NULL) return NULL; return table->name; } /******************************** * Otherwise return column name * ********************************/ column = ZPro_ColumnPtr(object, ntable, ncolumn); if (column == NULL) return NULL; return column->name; } /* ******************************************************************************** *$ Component_name: * Pro_LabelXName (label.c) *$ Abstract: * This routine returns the name of a table's X-coordinate. *$ Keywords: * PROFILE, SERIES, LABEL * C, PUBLIC, SUBROUTINE *$ Declarations: * RL_CHAR *Pro_LabelXName(object, ntable) * PRO_OBJECT *object; * RL_INT4 ntable; *$ Inputs: * object pointer to the PDS label object. * ntable index of selected table (1...n). *$ Outputs: * none *$ Returns: * a pointer to a (read-only) string containing the desired name, or NULL * on a non-fatal error. *$ Detailed_description: * This routine returns the name of a table's X-coordinate. Names are * defined by the PDS label's SAMPLING_PARAMETER_NAME field, followed by a * space and (if present) the PDS label's SAMPLING_PARAMETER_UNIT field in * parentheses. *$ External_references: * Profile toolkit *$ Side_effects: * none *$ Examples: * Suppose the PDS label associated with an object looks like this: * * ^SERIES = "PS1G02.TAB" * OBJECT = SERIES * NAME = OCCULTATION_GEOMETRY * SAMPLING_PARAMETER_NAME = RECORD_INDEX * SAMPLING_PARAMETER_UNIT = 'N/A' * START_SAMPLING_PARAMETER = -16. * STOP_SAMPLING_PARAMETER = 1296. * SAMPLING_PARAMETER_INTERVAL = 1.0 * OBJECT = COLUMN * NAME = RECORD_INDEX * UNIT = 'N/A' * END_OBJECT = COLUMN * OBJECT = COLUMN * NAME = INTERCEPT_RADIUS * UNIT = "km" * END_OBJECT = COLUMN * END_OBJECT = SERIES * END * * Then Pro_LabelXName(label, 1) returns "RECORD_INDEX" *$ Error_handling: * Profile library error handling is in effect. * * Conditions raised: * PRO_CLASS_ERROR if object is NULL or is not a PDS label. * PRO_DOMAIN_ERROR if the table index is out of range. *$ Limitations: * none *$ Author_and_institution: * Mark R. Showalter * NASA/Ames Research Center *$ Version_and_date: * 1.0: March 1998 *$ Change_history: * none *******************************************************************************/ RL_CHAR *Pro_LabelXName(object, ntable) PRO_OBJECT *object; RL_INT4 ntable; { ZPRO_TABLE *table; ZPRO_COLUMN *column; table = ZPro_TablePtr(object, ntable); if (table == NULL) return NULL; return table->xname; } /* ******************************************************************************** *$ Component_name: * Pro_LabelFind (label.c) *$ Abstract: * This routine returns the index of the named table or column. *$ Keywords: * PROFILE, SERIES, LABEL * C, PUBLIC, SUBROUTINE *$ Declarations: * RL_INT4 Pro_LabelFind(object, ntable, name) * PRO_OBJECT *object; * RL_INT4 ntable; * RL_CHAR *name; *$ Inputs: * object pointer to the PDS label object. * ntable index of selected table (1...n). * name name of the table or column to find. For columns, this * string can optionally exclude units inside parentheses. *$ Outputs: * none *$ Returns: * index (1...n) of the selected table or column; 0 if not found. * If ntable is zero, this is the index of the table with the given name; * otherwise, this is the index of the column with the given name. *$ Detailed_description: * This routine returns the index of the named table or column. * * The quantity returned depends on the which input parameters are set to * zero. If ntable is zero, the index (starting with 1) of the table with * the given name is returned. Otherwise, ntable is the index of the * selected table and the number returned is the index of the column with * the given name. For columns, if the name string does not contain units * (inside parentheses), then any units in the column name are ignored. *$ External_references: * Profile toolkit *$ Side_effects: * none *$ Examples: * Suppose the PDS label associated with an object looks like this: * * ^SERIES = "PS1G02.TAB" * OBJECT = SERIES * NAME = OCCULTATION_GEOMETRY * SAMPLING_PARAMETER_NAME = RECORD_INDEX * SAMPLING_PARAMETER_UNIT = 'N/A' * START_SAMPLING_PARAMETER = -16. * STOP_SAMPLING_PARAMETER = 1296. * SAMPLING_PARAMETER_INTERVAL = 1.0 * OBJECT = COLUMN * NAME = RECORD_INDEX * UNIT = 'N/A' * END_OBJECT = COLUMN * OBJECT = COLUMN * NAME = INTERCEPT_RADIUS * UNIT = "km" * END_OBJECT = COLUMN * END_OBJECT = SERIES * END * * Then Pro_LabelFind(label, 0, "OCCULTATION_GEOMETRY") returns 1; * Pro_LabelFind(label, 1, "RECORD_INDEX") returns 1; * Pro_LabelFind(label, 1, "INTERCEPT_RADIUS (km)") returns 2; * Pro_LabelFind(label, 1, "INTERCEPT_RADIUS") returns 2; *$ Error_handling: * Profile library error handling is in effect. * * Conditions raised: * PRO_CLASS_ERROR if object is NULL or is not a PDS label. * PRO_DOMAIN_ERROR if the table index is out of range. * PRO_NOT_FOUND if no table or column of the given name exists. *$ Limitations: * none *$ Author_and_institution: * Mark R. Showalter * NASA/Ames Research Center *$ Version_and_date: * 1.0: March 1998 *$ Change_history: * none *******************************************************************************/ RL_INT4 Pro_LabelFind(object, ntable, name) PRO_OBJECT *object; RL_INT4 ntable; RL_CHAR *name; { RL_INT4 ntables, ncolumns, lname, i; RL_BOOL hasunits; RL_CHAR *comp; ZPRO_LABEL *label; /********************************** * Search for matching table name * **********************************/ if (ntable == 0) { ntables = Pro_LabelCount(object, 0, 0); for (i=1; i<=ntables; i++) { if (strcmp(name, Pro_LabelName(object,i,0)) == 0) return i; } /* If no match is found, report error */ label = ZPro_LabelPtr(object); (void) sprintf(xpro_message, "named table not found\n\ label contains no table named \"%s\"\n\ label file = \"%s\"", name, label->filename); RL_RaiseError("PRO_NOT_FOUND", xpro_message); return 0; } /********************************************* * Otherwise search for matching column name * *********************************************/ /* Check for units in match string */ hasunits = (strchr(name, '(') != NULL); lname = strlen(name); /* Search for matching table name */ ncolumns = Pro_LabelCount(object, ntable, 0); for (i=1; i<=ncolumns; i++) { comp = Pro_LabelName(object,ntable,i); /* If match string has units, check for exact match */ if (hasunits) { if (strcmp(name, comp) == 0) return i; } /* Otherwise, match up to end, paren, or blank+paren */ else { if (strncmp(name, comp, lname) == 0) { if (comp[lname] == '\0' || comp[lname] == '(') return i; if (comp[lname] == ' ' && comp[lname+1] == '(') return i; } } } /* If no match is found, report error */ label = ZPro_LabelPtr(object); (void) sprintf(xpro_message, "named column not found\n\ table #%d contains no column named \"%s\"\n\ label file = \"%s\"", ntable, name, label->filename); RL_RaiseError("PRO_NOT_FOUND", xpro_message); return 0; } /* ******************************************************************************** *$ Component_name: * Pro_LabelSampling (label.c) *$ Abstract: * This routine returns the sampling parameters used by a specified table * or column. *$ Keywords: * PROFILE, SERIES, LABEL * C, PUBLIC, SUBROUTINE *$ Declarations: * RL_INT4 Pro_LabelSampling(object, ntable, ncolumn, nitem, * x1, x2, dx) * PRO_OBJECT *object; * RL_INT4 ntable, ncolumn, nitem; * RL_FLT8 *x1, *x2, *dx; *$ Inputs: * object pointer to the PDS label object. * ntable index of selected table (1...n). * ncolumn index of the selected column (1...n) or 0 for row * sampling. * nitem index of selected item, or 0 for all. *$ Outputs: * *x1 first sampling parameter; not returned if x1==NULL. * *x2 last sampling parameter; not returned if x2==NULL. * *dx interval between samples; not returned if dx==NULL. *$ Returns: * the number of samples in selected column/item pair; 0 on error. *$ Detailed_description: * This routine returns the sampling parameters used by a specified table * or column. * * If nitem is nonzero, then it is assumed that the only a single item per * row is to be used; in this case the sampling parameters for the column * match those for the row. However, if nitem is zero in a column that * contains multiple items, then the items are treated as subsamples, so * the sample interval is correspondingly reduced. * * Note that the row sampling parameters are returned if ncolumn is zero. *$ External_references: * Profile toolkit *$ Side_effects: * none *$ Examples: * Suppose the PDS label associated with an object looks like this: * * ^SERIES = "PS1G02.TAB" * OBJECT = SERIES * SAMPLING_PARAMETER_NAME = RECORD_INDEX * SAMPLING_PARAMETER_UNIT = 'N/A' * START_SAMPLING_PARAMETER = -16. * STOP_SAMPLING_PARAMETER = 1296. * SAMPLING_PARAMETER_INTERVAL = 1.0 * OBJECT = COLUMN * ITEMS = 1 * END_OBJECT = COLUMN * OBJECT = COLUMN * ITEMS = 100 * END_OBJECT = COLUMN * END_OBJECT = SERIES * END * * Then Pro_LabelSampling(label, 1, 1, 1, &x1, &x2, &dx) * sets x1=-16., x2=1296., dx=1., returns 1313; * Pro_LabelSampling(label, 1, 1, 0, &x1, &x2, &dx) * sets x1=-16., x2=1296., dx=1., returns 1313; * Pro_LabelSampling(label, 1, 2, 1, &x1, &x2, &dx) * sets x1=-16., x2=1296., dx=1., returns 1313; * Pro_LabelSampling(label, 1, 2, 0, &x1, &x2, &dx) * sets x1=-16., x2=1296.99, dx=0.01, returns 131300 *$ Error_handling: * Profile library error handling is in effect. * * Conditions raised: * PRO_CLASS_ERROR if object is NULL or is not a PDS label. * PRO_DOMAIN_ERROR if table, column or item index is out of range. *$ Limitations: * none *$ Author_and_institution: * Mark R. Showalter * NASA/Ames Research Center *$ Version_and_date: * 1.0: March 1998 *$ Change_history: * none *******************************************************************************/ RL_INT4 Pro_LabelSampling(object, ntable, ncolumn, nitem, x1, x2, dx) PRO_OBJECT *object; RL_INT4 ntable, ncolumn, nitem; RL_FLT8 *x1, *x2, *dx; { ZPRO_TABLE *table; ZPRO_COLUMN *column; RL_FLT8 scaled_dx; RL_INT4 nrows; /************** * Find table * **************/ table = ZPro_TablePtr(object, ntable); if (table == NULL) return 0; scaled_dx = table->dx; nrows = table->nrows; /********************************************* * Find column and optional expansion factor * *********************************************/ if (ncolumn != 0) { column = ZPro_ColumnPtr(object, ntable, ncolumn); if (column == NULL) return 0; if (nitem < 0 || nitem > column->items) XPro_IDomainError("item index", object, 1, column->items, nitem); if (nitem == 0) { scaled_dx /= column->items; nrows *= column->items; } } /***************** * Return values * *****************/ if (x1 != NULL) *x1 = table->x1; if (x2 != NULL) *x2 = table->x2 + (table->dx - scaled_dx); if (dx != NULL) *dx = scaled_dx; return nrows; } /* ******************************************************************************** *$ Component_name: * Pro_LabelInt (label.c) *$ Abstract: * This routine returns the integer value of a specified keyword in a PDS * label. *$ Keywords: * PROFILE, SERIES, LABEL * C, PUBLIC, SUBROUTINE *$ Declarations: * RL_INT4 Pro_LabelInt(object, ntable, ncolumn, keyword, dfault, * raise_error) * PRO_OBJECT *object; * RL_INT4 ntable, ncolumn, dfault; * RL_CHAR *keyword; * RL_BOOL raise_error; *$ Inputs: * object pointer to the PDS label object. * ntable table index, or 0 to search among top keywords only. * ncolumn column index, or 0 to search among table keywords only. * keyword keyword name. * dfault default value to return on error. * raise_error TRUE to raise PRO_EVALUATION_FAILURE on error; * FALSE otherwise. *$ Outputs: * none *$ Returns: * integer value of the keyword; default value on non-fatal error. *$ Detailed_description: * This routine returns the integer value of a specified keyword in a PDS * label. * * What section of the label is searched depends on the values of the * ntable and ncolumn parameters. If ntable is zero, then only the * keywords at the top of the PDS label (above any PDS OBJECTs) are * searched. If ntable is nonzero but ncolumn is zero, then the keywords * inside the TABLE/SERIES object but above the COLUMN objects are * searched, followed by the keywords at the top of the label. If both * ntable and nseries are nonzero, then the keywords in the selected * COLUMN object are searched, followed by the keywords in the selected * TABLE/SERIES object, followed by the keywords at the top of the label. * * If the keyword is not found in the PDS label, or is found but is not a * valid integer, the default value is returned. In this case, error code * PRO_EVALUATION_FAILURE if the raise_error parameter is TRUE; otherwise * no error condition is raised. *$ External_references: * Profile toolkit, Object Access library. *$ Side_effects: * none *$ Examples: * Suppose the PDS label associated with an object looks like this: * * FOO = 1313 * ABC = "DEF" * OBJECT = SERIES * FOO = 1000 * BAR = 999 * OBJECT = COLUMN * FOO = 3 * END_OBJECT = COLUMN * END_OBJECT = SERIES * END * * Then Pro_LabelInt(label, 1, 1, "FOO", -99, TRUE) returns 3; * Pro_LabelInt(label, 1, 0, "FOO", -99, TRUE) returns 1000; * Pro_LabelInt(label, 0, 0, "FOO", -99, TRUE) returns 1313; * Pro_LabelInt(label, 1, 1, "BAR", -99, TRUE) returns 999; * Pro_LabelInt(label, 1, 0, "BAR", -99, TRUE) returns 999; * Pro_LabelInt(label, 0, 0, "BAR", -99, TRUE) raises * PRO_EVALUATION_FAILURE and returns -99; * Pro_LabelInt(label, 0, 0, "BAR", -99, FALSE) returns -99; * Pro_LabelInt(label, 0, 0, "ABC", -99, TRUE) raises * PRO_EVALUATION_FAILURE and returns -99; * Pro_LabelInt(label, 0, 0, "ABC", -99, FALSE) returns -99; *$ Error_handling: * Profile library error handling is in effect. * * Conditions raised: * PRO_CLASS_ERROR if object is NULL or is not a PDS label. * PRO_DOMAIN_ERROR if the table/column index is out of range. * PRO_EVALUATION_FAILURE raised optionally, if the named keyword is not * found or is not a valid integer. *$ Limitations: * none *$ Author_and_institution: * Mark R. Showalter * NASA/Ames Research Center *$ Version_and_date: * 1.0: March 1998 *$ Change_history: * none *******************************************************************************/ RL_INT4 Pro_LabelInt(object, ntable, ncolumn, keyword, dfault, raise_error) PRO_OBJECT *object; RL_INT4 ntable, ncolumn, dfault; RL_CHAR *keyword; RL_BOOL raise_error; { ZPRO_COLUMN *column; ZPRO_TABLE *table; ZPRO_LABEL *label; RL_BOOL status; RL_INT4 value; if (ntable > 0) { /* Search column object if necessary */ if (ncolumn > 0) { column = ZPro_ColumnPtr(object, ntable, ncolumn); if (column == NULL) return dfault; status = ZPro_GetInt(column->odltree, keyword, &value); if (status) return value; } /* Search table object if necessary */ table = ZPro_TablePtr(object, ntable); if (table == NULL) return dfault; status = ZPro_GetInt(table->odltree, keyword, &value); if (status) return value; } /* Search root object if necessary */ label = ZPro_LabelPtr(object); if (label == NULL) return dfault; status = ZPro_GetInt(label->odltree, keyword, &value); if (status) return value; /* Raise error if necessary */ if (raise_error) { (void) sprintf(xpro_message, "\ keyword not found or not a valid integer\n\ label file = \"%s\"\n\ table = %d; column = %d; keyword = \"%s\"", label->filename, ntable, ncolumn, keyword); RL_RaiseError("PRO_EVALUATION_FAILURE", xpro_message); } return dfault; } /* ******************************************************************************** *$ Component_name: * Pro_LabelFloat (label.c) *$ Abstract: * This routine returns the floating-point value of a specified keyword in * a PDS label. *$ Keywords: * PROFILE, SERIES, LABEL * C, PUBLIC, SUBROUTINE *$ Declarations: * RL_FLT8 Pro_LabelFloat(object, ntable, ncolumn, keyword, dfault, * raise_error) * PRO_OBJECT *object; * RL_INT4 ntable, ncolumn; * RL_CHAR *keyword; * RL_FLT8 dfault; * RL_BOOL raise_error; *$ Inputs: * object pointer to the PDS label object. * ntable table index, or 0 to search among top keywords only. * ncolumn column index, or 0 to search among table keywords only. * keyword keyword name. * dfault default value to return on error. * raise_error TRUE to raise PRO_EVALUATION_FAILURE on error; * FALSE otherwise. *$ Outputs: * none *$ Returns: * floating-point value of the keyword; default value on non-fatal error. *$ Detailed_description: * This routine returns the floating-point value of a specified keyword in * a PDS label. * * What section of the label is searched depends on the values of the * ntable and ncolumn parameters. If ntable is zero, then only the * keywords at the top of the PDS label (above any PDS OBJECTs) are * searched. If ntable is nonzero but ncolumn is zero, then the keywords * inside the TABLE/SERIES object but above the COLUMN objects are * searched, followed by the keywords at the top of the label. If both * ntable and nseries are nonzero, then the keywords in the selected * COLUMN object are searched, followed by the keywords in the selected * TABLE/SERIES object, followed by the keywords at the top of the label. * * If the keyword is not found in the PDS label, or is found but is not a * valid floating-point number, the default value is returned. In this * case, error code PRO_EVALUATION_FAILURE if the raise_error parameter is * TRUE; otherwise no error condition is raised. *$ External_references: * Profile toolkit, Object Access library. *$ Side_effects: * none *$ Examples: * Suppose the PDS label associated with an object looks like this: * * FOO = 313. * ABC = "DEF" * OBJECT = SERIES * FOO = 100 * BAR = 999 * OBJECT = COLUMN * FOO = 3. * END_OBJECT = COLUMN * END_OBJECT = SERIES * END * * Then Pro_LabelFloat(label, 1, 1, "FOO", -99., TRUE) returns 3.; * Pro_LabelFloat(label, 1, 0, "FOO", -99., TRUE) returns 100.; * Pro_LabelFloat(label, 0, 0, "FOO", -99., TRUE) returns 313.; * Pro_LabelFloat(label, 1, 1, "BAR", -99., TRUE) returns 999.; * Pro_LabelFloat(label, 1, 0, "BAR", -99., TRUE) returns 999.; * Pro_LabelFloat(label, 0, 0, "BAR", -99., TRUE) raises * PRO_EVALUATION_FAILURE and returns -99.; * Pro_LabelFloat(label, 0, 0, "BAR", -99., FALSE) returns -99.; * Pro_LabelFloat(label, 0, 0, "ABC", -99., TRUE) raises * PRO_EVALUATION_FAILURE and returns -99.; * Pro_LabelFloat(label, 0, 0, "ABC", -99., FALSE) returns -99.; *$ Error_handling: * Profile library error handling is in effect. * * Conditions raised: * PRO_CLASS_ERROR if object is NULL or is not a PDS label. * PRO_DOMAIN_ERROR if the table/column index is out of range. * PRO_EVALUATION_FAILURE raised optionally, if the named keyword is not * found or is not a valid floating-point number. *$ Limitations: * none *$ Author_and_institution: * Mark R. Showalter * NASA/Ames Research Center *$ Version_and_date: * 1.0: March 1998 *$ Change_history: * none *******************************************************************************/ RL_FLT8 Pro_LabelFloat(object, ntable, ncolumn, keyword, dfault, raise_error) PRO_OBJECT *object; RL_INT4 ntable, ncolumn; RL_CHAR *keyword; RL_FLT8 dfault; RL_BOOL raise_error; { ZPRO_COLUMN *column; ZPRO_TABLE *table; ZPRO_LABEL *label; RL_BOOL status; RL_FLT8 value; if (ntable > 0) { /* Search column object if necessary */ if (ncolumn > 0) { column = ZPro_ColumnPtr(object, ntable, ncolumn); if (column == NULL) return dfault; status = ZPro_GetFloat(column->odltree, keyword, &value); if (status) return value; } /* Search table object if necessary */ table = ZPro_TablePtr(object, ntable); if (table == NULL) return dfault; status = ZPro_GetFloat(table->odltree, keyword, &value); if (status) return value; } /* Search root object if necessary */ label = ZPro_LabelPtr(object); if (label == NULL) return dfault; status = ZPro_GetFloat(label->odltree, keyword, &value); if (status) return value; /* Raise error if necessary */ if (raise_error) { (void) sprintf(xpro_message, "\ keyword not found or not a valid floating-point value\n\ label file = \"%s\"\n\ table = %d; column = %d; keyword = \"%s\"", label->filename, ntable, ncolumn, keyword); RL_RaiseError("PRO_EVALUATION_FAILURE", xpro_message); } return dfault; } /* ******************************************************************************** *$ Component_name: * Pro_LabelString (label.c) *$ Abstract: * This routine returns a pointer to the character string value of the * specified keyword in a PDS label. *$ Keywords: * PROFILE, SERIES, LABEL * C, PUBLIC, SUBROUTINE *$ Declarations: * RL_CHAR *Pro_LabelString(object, ntable, ncolumn, keyword, * dfault, raise_error) * PRO_OBJECT *object; * RL_INT4 ntable, ncolumn; * RL_CHAR *keyword, *dfault; * RL_BOOL raise_error; *$ Inputs: * object pointer to the PDS label object. * ntable table index, or 0 to search among top keywords only. * ncolumn column index, or 0 to search among table keywords only. * keyword keyword name. * dfault default string to return on error. * raise_error TRUE to raise PRO_EVALUATION_FAILURE on error; * FALSE otherwise. *$ Outputs: * none *$ Returns: * pointer to a (read-only) string containing the value of keyword; a * pointer to the default string on error. The string is truncated if * necessary after 255 characters (plus the final '\0'). *$ Detailed_description: * This routine returns a pointer to the character string value of the * specified keyword in a PDS label. Quotes (single or double) are * stripped away if present. * * What section of the label is searched depends on the values of the * ntable and ncolumn parameters. If ntable is zero, then only the * keywords at the top of the PDS label (above any PDS OBJECTs) are * searched. If ntable is nonzero but ncolumn is zero, then the keywords * inside the TABLE/SERIES object but above the COLUMN objects are * searched, followed by the keywords at the top of the label. If both * ntable and nseries are nonzero, then the keywords in the selected * COLUMN object are searched, followed by the keywords in the selected * TABLE/SERIES object, followed by the keywords at the top of the label. * * If the keyword is not found in the PDS label, or is found but is not a * valid string, the default value is returned. In this case, error code * PRO_EVALUATION_FAILURE if the raise_error parameter is TRUE; otherwise * no error condition is raised. *$ External_references: * Profile toolkit, Object Access library. *$ Side_effects: * none *$ Examples: * Suppose the PDS label associated with an object looks like this: * * FOO = 313 * OBJECT = SERIES * FOO = ABC * BAR = 999 * OBJECT = COLUMN * FOO = "Bar" * END_OBJECT = COLUMN * END_OBJECT = SERIES * END * * Then Pro_LabelString(label, 1, 1, "FOO", "xx", TRUE) returns "Bar"; * Pro_LabelString(label, 1, 0, "FOO", "xx", TRUE) returns "ABC"; * Pro_LabelString(label, 0, 0, "FOO", "xx", TRUE) returns "313"; * Pro_LabelString(label, 1, 1, "BAR", "xx", TRUE) returns "999"; * Pro_LabelString(label, 1, 0, "BAR", "xx", TRUE) returns "999"; * Pro_LabelString(label, 0, 0, "BAR", "xx", TRUE) raises * PRO_EVALUATION_FAILURE and returns "xx"; * Pro_LabelString(label, 0, 0, "BAR", "xx", FALSE) returns "xx"; *$ Error_handling: * Profile library error handling is in effect. * * Conditions raised: * PRO_CLASS_ERROR if object is NULL or is not a PDS label. * PRO_DOMAIN_ERROR if the table/column index is out of range. * PRO_EVALUATION_FAILURE raised optionally, if the named keyword is not * found or is not a valid string. *$ Limitations: * Returned strings are limited to 255 characters, plus final null * character. *$ Author_and_institution: * Mark R. Showalter * NASA/Ames Research Center *$ Version_and_date: * 1.0: March 1998 *$ Change_history: * none *******************************************************************************/ RL_CHAR *Pro_LabelString(object, ntable, ncolumn, keyword, dfault, raise_error) PRO_OBJECT *object; RL_INT4 ntable, ncolumn; RL_CHAR *keyword, *dfault; RL_BOOL raise_error; { ZPRO_COLUMN *column; ZPRO_TABLE *table; ZPRO_LABEL *label; RL_BOOL status; /* Anticipate failure */ strncpy(temp_name, dfault, TEMP_MAXLEN); temp_name[TEMP_MAXLEN] = '\0'; if (ntable > 0) { /* Search column object if necessary */ if (ncolumn > 0) { column = ZPro_ColumnPtr(object, ntable, ncolumn); if (column == NULL) return temp_name; status = ZPro_GetString(column->odltree, keyword, temp_name, TEMP_MAXLEN); if (status) return temp_name; } /* Search table object if necessary */ table = ZPro_TablePtr(object, ntable); if (table == NULL) return temp_name; status = ZPro_GetString(table->odltree, keyword, temp_name, TEMP_MAXLEN); if (status) return temp_name; } /* Search root object if necessary */ label = ZPro_LabelPtr(object); if (label == NULL) return temp_name; status = ZPro_GetString(label->odltree, keyword, temp_name, TEMP_MAXLEN); if (status) return temp_name; /* Raise error if necessary */ if (raise_error) { (void) sprintf(xpro_message, "\ keyword not found or not a valid string\n\ label file = \"%s\"\n\ table = %d; column = %d; keyword = \"%s\"", label->filename, ntable, ncolumn, keyword); RL_RaiseError("PRO_EVALUATION_FAILURE", xpro_message); } return temp_name; } /* ******************************************************************************** * PROGRAMMER ROUTINES ******************************************************************************** * XPro_LabelInfo(object, ntable, ncolumn, tabletree, columntree, * rows, items, x1, x2, dx, xname, yname, * missing, invalid, offset, scale) * * This routine fetches information on a given table and column. * * Input: * object PDS label object. * ntable table index [1...n]. * column column index [1...n]. * * Output: * *tabletree pointer to the ODLTREE of the table. * *columntree pointer to the ODLTREE of the column. * *rows number of rows. * *items number of items. * *x1, *x2, *dx column sampling. * xname name of the x-coordinate. * yname name of the y-coordinate. * *missing missing flag value. * *invalid invalid flag value. * *offset offset to apply to tabulated values. * *scale scale factor to apply to tabulated values. * * Return: TRUE if all is well; FALSE if an error occurred. * * Errors: * PRO_CLASS_ERROR if object is NULL or not a PDS label object. * PRO_DOMAIN_ERROR if the table/column index is out of range. *******************************************************************************/ RL_BOOL XPro_LabelInfo(object, ntable, ncolumn, tabletree, columntree, rows, items, x1, x2, dx, xname, yname, missing, invalid, offset, scale) PRO_OBJECT *object; RL_INT4 ntable, ncolumn, *rows, *items; RL_FLT8 *x1, *x2, *dx, *missing, *invalid, *offset, *scale; RL_VOID **tabletree, **columntree; RL_CHAR **xname, **yname; { ZPRO_COLUMN *column; ZPRO_TABLE *table; column = (ZPRO_COLUMN *) ZPro_ColumnPtr(object, ntable, ncolumn); if (column == NULL) return FALSE; *items = column->items; *missing = column->missing; *invalid = column->invalid; *offset = column->offset; *scale = column->scale; *yname = column->name; *columntree = (RL_VOID *) column->odltree; table = ZPro_TablePtr(object, ntable); *rows = table->nrows; *x1 = table->x1; *x2 = table->x2; *dx = table->dx; *xname = table->xname; *tabletree = (RL_VOID *) table->odltree; return TRUE; } /* ******************************************************************************** * INTERNAL ROUTINES ******************************************************************************** * ZPro_FreeLabel(pointer) * * This routine closes the PDS label and frees the data structures in memory * associated with it. * * Input: * label pointer to the PDS label object. * * Side Effects: memory is freed. *******************************************************************************/ static void ZPro_FreeLabel(pointer) RL_VOID *pointer; { ZPRO_LABEL *label; RL_INT4 i, j; label = (ZPRO_LABEL *) pointer; if (label == NULL) return; if (label->tables != NULL) { for (i=0; i<label->ntables; i++) XRL_Free(label->tables[i].columns); XRL_Free(label->tables); } OdlFreeTree(label->odltree); XRL_Free(label); } /* ******************************************************************************** * ZPro_PrintLabel(pointer) * * This routine prints out information about a PDS label object. * * Input: * pointer pointer to the PDS label object. *******************************************************************************/ static void ZPro_PrintLabel(pointer) RL_VOID *pointer; { ZPRO_LABEL *label; ZPRO_TABLE *table; ZPRO_COLUMN *column; RL_INT4 i, j; label = (ZPRO_LABEL *) pointer; /* Make sure object is not NULL */ if (label == NULL) { printf("PRINT ERROR: PDS label pointer is NULL\n"); return; } /* Make sure object is a PDS label */ if (label->class.id != XPRO_LABEL_CLASS) { printf("PRINT ERROR: Object is not a PDS label\n"); return; } /* Print object info... */ for (i=1; i <= label->ntables; i++) { table = &(label->tables[i-1]); printf("\nTable #%d: %s\n", i, table->name); printf(" rows = %d (%g to %g by %g)\n", table->nrows, table->x1, table->x2, table->dx); printf(" xname = %s\n", table->xname); for (j=1; j <= table->ncolumns; j++) { column = &(table->columns[j-1]); printf(" Column #%d: %s\n", j, column->name); if (column->items != 1) printf(" items = %d\n", column->items); if (column->missing != -HUGE_VAL) printf(" missing = %g\n", column->missing); if (column->invalid != -HUGE_VAL) printf(" invalid = %g\n", column->invalid); if (column->offset != 0. || column->scale != 1.) printf(" scaling = %g * x + %g\n", column->scale, column->offset); } } } /* ******************************************************************************** * ZPro_LabelPtr(object) * * This internal routine returns a pointer to the object's ZPRO_LABEL data * structure. * * Input: * object pointer to a PDS label object. * * Return: pointer to ZPRO_LABEL structure, or NULL on error. * * Errors: * PRO_CLASS_ERROR if object is NULL or not a PDS label. *******************************************************************************/ static ZPRO_LABEL *ZPro_LabelPtr(object) PRO_OBJECT *object; { ZPRO_LABEL *label; /* Find PDS label object pointer */ label = (ZPRO_LABEL *) XPro_ObjectPtr(object); /* Make sure object is not NULL */ if (label == NULL) { XPro_NullError("PDS label", object); return NULL; } /* Make sure object is a PDS label */ if (label->class.id != XPRO_LABEL_CLASS) { XPro_ClassError("PDS label", object); return NULL; } return (ZPRO_LABEL *) object->class.pointer; } /* ******************************************************************************** * ZPro_TablePtr(object, ntable) * * This internal routine returns a pointer to the a selected ZPRO_TABLE data * structure. * * Input: * object pointer to a PDS label object. * ntable table index [1...n]. * * Return: pointer to ZPRO_TABLE structure, or NULL on error. * * Errors: * PRO_CLASS_ERROR if object is NULL or not a PDS label. * PRO_DOMAIN_ERROR if the table index is out of range. *******************************************************************************/ static ZPRO_TABLE *ZPro_TablePtr(object, ntable) PRO_OBJECT *object; RL_INT4 ntable; { ZPRO_LABEL *label; /* Find PDS label object pointer */ label = ZPro_LabelPtr(object); if (label == NULL) return NULL; /* Check the table index */ if (ntable < 1 || ntable > label->ntables) { XPro_IDomainError("table index", object, 1, label->ntables, ntable); return NULL; } return &(label->tables[ntable-1]); } /* ******************************************************************************** * ZPro_ColumnPtr(object, ntable, ncolumn) * * This internal routine returns a pointer to a selected ZPRO_COLUMN data * structure. * * Input: * object pointer to a PDS label object. * ntable table index [1...n]. * ncolumn column index [1...n]. * * Return: pointer to ZPRO_LABEL structure, or NULL on error. * * Errors: * PRO_CLASS_ERROR if object is NULL or not a PDS label. * PRO_DOMAIN_ERROR if the table/column index is out of range. *******************************************************************************/ static ZPRO_COLUMN *ZPro_ColumnPtr(object, ntable, ncolumn) PRO_OBJECT *object; RL_INT4 ntable, ncolumn; { ZPRO_TABLE *table; table = ZPro_TablePtr(object, ntable); if (table == NULL) return NULL; /* Check the column index */ if (ncolumn < 1 || ncolumn > table->ncolumns) { XPro_IDomainError("column index", object, 1, table->ncolumns, ncolumn); return NULL; } return &(table->columns[ncolumn-1]); } /* ******************************************************************************** * ZPro_GetParam(odltree, name, ptr) * * This internal routine finds a specified keyword in a PDS object. * * Input: * odltree pointer to the ODL tree. * name name of keyword for which to search. * ptr pointer where the resultant string is stored. * * Return: TRUE if keyword is found; FALSE otherwise. *******************************************************************************/ static RL_BOOL ZPro_GetParam(odltree, name, ptr) ODLTREE odltree; RL_CHAR *name; RL_CHAR **ptr; { KEYWORD *kwdptr; RL_CHAR *string; kwdptr = OdlFindKwd(odltree, name, NULL, (unsigned long) 0, ODL_THIS_OBJECT); string = OdlGetKwdName(kwdptr); if (string == NULL) { *ptr = NULL; return FALSE; } *ptr = OdlGetKwdValue(kwdptr); return (*ptr != NULL); } /* ******************************************************************************** * ZPro_GetInt(odltree, name, value) * * This internal routine finds the integer value of a specified keyword in a PDS * label. * * Input: * odltree pointer to the object. * name name of keyword for which to search. * * Output{ * *value value of integer, unchanged on error. * * Return: TRUE if value is found and is a valid integer; * FALSE otherwise. *******************************************************************************/ static RL_BOOL ZPro_GetInt(odltree, name, value) ODLTREE odltree; RL_CHAR *name; RL_INT4 *value; { RL_BOOL status; RL_CHAR *string; char *ptr; RL_INT4 rval; status = ZPro_GetParam(odltree, name, &string); if (!status) return FALSE; rval = strtol(string, &ptr, 10); if ((rval == 0) && (string == ptr)) { return FALSE; } else { *value = rval; return TRUE; } } /* ******************************************************************************** * ZPro_GetFloat(odltree, name, value) * * This internal routine finds the floating point value of a specified keyword in * a PDS label. * * Input: * odltree pointer to the object. * name name of keyword for which to search. * * Output: * *value floating-point value; unchanged on error. * * Return: TRUE if value is found and is a valid float; * FALSE otherwise. *******************************************************************************/ static RL_BOOL ZPro_GetFloat(odltree, name, value) ODLTREE odltree; RL_CHAR *name; RL_FLT8 *value; { RL_BOOL status; RL_CHAR *string; char *ptr; RL_FLT8 rval; status = ZPro_GetParam(odltree, name, &string); if (!status) { return FALSE; } rval = strtod(string, &ptr); if ((rval == 0.) && (string == ptr)) { return FALSE; } else { *value = rval; return TRUE; } } /* ******************************************************************************** * ZPro_GetString(odltree, name, value, maxlen) * * This internal routine finds the string value of a specified keyword in a PDS * object. It strips away surrounding quotes if necessary. * * Input: * odltree pointer to the ODL tree. * name name of keyword for which to search. * maxlen maximum string length returned, excluding final '\0'. * * Output: * *value string found, truncated if necessary; unchanged on * error. * * Return: TRUE if value is found; FALSE otherwise. *******************************************************************************/ static RL_BOOL ZPro_GetString(odltree, name, value, maxlen) ODLTREE odltree; RL_CHAR *name, *value; RL_INT4 maxlen; { RL_BOOL status; RL_CHAR *string; RL_INT4 len; status = ZPro_GetParam(odltree, name, &string); if ((!status) || (string == NULL)) { return FALSE; } if ((string[0] == '\"') || (string[0] == '\'')) { len = strlen(string) - 2; if (len > maxlen) len = maxlen; strncpy(value, &string[1], len); value[len] = '\0'; } else { strncpy(value, &string[0], maxlen); value[maxlen] = '\0'; } return TRUE; } /* ******************************************************************************** * ZPro_DefInt(odltree, name, dfault, value) * * This internal routine finds the integer value of a specified keyword in a PDS * label. If the value is not found, it returns a default value. * * Input: * odltree pointer to the object. * name name of keyword for which to search. * dfault default integer value. * *value value of integer. *******************************************************************************/ static void ZPro_DefInt(odltree, name, dfault, value) ODLTREE odltree; RL_CHAR *name; RL_INT4 dfault, *value; { RL_BOOL status; status = ZPro_GetInt(odltree, name, value); if (!status) *value = dfault; } /* ******************************************************************************** * ZPro_DefFloat(odltree, name, dfault, value) * * This internal routine finds the floating-point value of a specified keyword in * a PDS label. If the value is not found, it returns a default value. * * Input: * odltree pointer to the object. * name name of keyword for which to search. * dfault default floating-point value. * *value floating-point value found. *******************************************************************************/ static void ZPro_DefFloat(odltree, name, dfault, value) ODLTREE odltree; RL_CHAR *name; RL_FLT8 dfault, *value; { RL_BOOL status; status = ZPro_GetFloat(odltree, name, value); if (!status) *value = dfault; } /* ******************************************************************************** * ZPro_DefFloat2(odltree, name1, name2, dfault, value) * * This internal routine finds the floating-point value of either of a specified * pair of possible keywords in a PDS label. If neither value is found, it * returns a default value. * * Input: * odltree pointer to the object. * name1, name2 names of keywords for which to search. * dfault default floating-point value. * *value floating-point value found. *******************************************************************************/ static void ZPro_DefFloat2(odltree, name1, name2, dfault, value) ODLTREE odltree; RL_CHAR *name1, *name2; RL_FLT8 dfault, *value; { RL_BOOL status; status = ZPro_GetFloat(odltree, name1, value); if (status) return; ZPro_DefFloat(odltree, name2, dfault, value); } /* ******************************************************************************** * ZPro_DefString(odltree, name, dfault, value, maxlen) * * This internal routine finds the string value of a specified keyword in a PDS * object. It strips away surrounding quotes if necessary. If the value is not * found, a default string is returned. * * Input: * odltree pointer to the ODL tree. * name name of keyword for which to search. * *dfault default string. * *value string found, truncated if necessary. * maxlen maximum string length returned, excluding final '\0'. *******************************************************************************/ static void ZPro_DefString(odltree, name, dfault, value, maxlen) ODLTREE odltree; RL_CHAR *name, *dfault, *value; RL_INT4 maxlen; { RL_BOOL status; status = ZPro_GetString(odltree, name, value, maxlen); if (!status) { strncpy(value, dfault, maxlen); value[maxlen] = '\0'; } } /* ******************************************************************************** * ZPro_DefName(odltree, name, unit, dfault, value, maxlen) * * This internal routine finds the string value of a specified keyword and * merges it with an optional set of units in a PDS object. It strips away any * surrounding quotes if necessary. If the value is not found, a default string * is returned. * * Input: * odltree pointer to the ODL tree. * name name keyword for which to search. * name unit keyword for which to search. * *dfault default string. * *value string found, truncated if necessary. * maxlen maximum string length returned, excluding final '\0'. *******************************************************************************/ static void ZPro_DefName(odltree, name, unit, dfault, value, maxlen) ODLTREE odltree; RL_CHAR *name, *unit, *dfault, *value; RL_INT4 maxlen; { RL_CHAR temp1[PRO_NAMELEN+1], temp2[PRO_NAMELEN+1]; ZPro_DefString(odltree, name, dfault, temp1, PRO_NAMELEN); ZPro_DefString(odltree, unit, "N/A", temp2, PRO_NAMELEN); if (strcmp(temp2, "N/A") == 0) { strncpy(value, temp1, maxlen); } else { (void) sprintf(xpro_message, "%s (%s)", temp1, temp2); strncpy(value, xpro_message, maxlen); } value[maxlen] = '\0'; } /* ******************************************************************************** * FORTRAN INTERFACE ROUTINES ******************************************************************************** *$ Component_name: * FPro_OpenLabel (label.c, fprofile.for) *$ Abstract: * This routine opens the specified PDS label file and creates a label * object. *$ Keywords: * PROFILE, LABEL * FORTRAN, PUBLIC, SUBROUTINE *$ Declarations: * integer*4 function FPro_OpenLabel(labelfile) * character*(*) labelfile *$ Inputs: * labelfile name of PDS label file. *$ Outputs: * none *$ Returns: * a FORTRAN pointer to the new label object. *$ Detailed_description: * This routine opens the specified PDS label file and creates a label * object. It parses the label to find the TABLE and SERIES objects. Use * Pro_ColumnSeries() (see column.c) to create a series object from one of * the columns. *$ External_references: * Profile toolkit, Object Access library. *$ Side_effects: * Memory is allocated. The label file is opened. *$ Examples: * This snippet of code creates a label object for a PDS file called * "table.tab": * * integer*4 label * * label = FPro_OpenLabel('table.tab') *$ Error_handling: * Profile library error handling is in effect. * * Conditions raised: * PRO_SETUP_FAILURE if the label cannot be read or parsed or has no * TABLE or SERIES objects. *$ Limitations: * file names are limited to 255 characters. *$ Author_and_institution: * Mark R. Showalter * NASA/Ames Research Center *$ Version_and_date: * 1.0: March 1998 *$ Change_history: * none ******************************************************************************** * Note: GPro_OpenLabel() defined here is the intermediary routine between * FPro_OpenLabel() and Pro_OpenLabel(), allowing for the fact that strings * cannot be passed directly between FORTRAN and C. See fprofile.for for the * rest of the code. * * integer*4 function GPro_OpenLabel(labelfile) * byte labelfile(*) *******************************************************************************/ RL_INT4 FORTRAN_NAME(gpro_openlabel) (labelfile) RL_CHAR *labelfile; { RL_VOID *ptr; RL_INT4 index; /* Call function */ ptr = (RL_VOID *) Pro_OpenLabel(labelfile); if (ptr == NULL) return 0; /* Save new pointer */ index = FORT_AddPointer(ptr); if (index == 0) Pro_FreeObject((PRO_OBJECT *) ptr); return index; } /* ******************************************************************************** *$ Component_name: * FPro_LabelCount (label.c) *$ Abstract: * This routine returns the number of tables in a PDS label object, the * number of columns in a table, or the number of items in a column. *$ Keywords: * PROFILE, SERIES, LABEL * FORTRAN, PUBLIC, SUBROUTINE *$ Declarations: * integer*4 function FPro_LabelCount(object, ntable, ncolumn) * integer*4 object, ntable, ncolumn *$ Inputs: * object FORTRAN pointer to the PDS label object. * ntable index of the selected table (0 or 1...n). * ncolumn index of the selected column (0 or 1...n). *$ Outputs: * none *$ Returns: * If ntable is zero, this is the number of tables in the label; * If ncolumn is zero, this is the number of columns in the selected table; * Otherwise, this is the number of items in the selected column. *$ Detailed_description: * This routine returns the number of tables in a PDS label object, the * number of columns in a table, or the number of items in a column. * * The quantity returned depends on the which input parameters are set to * zero. If ntable is zero, the total number of PDS TABLE and SERIES * objects is returned. Otherwise, ntable is the index (starting with 1) * of the selected table. If ncolumn is zero, the number of PDS COLUMN * objects in the selected table is returned. Otherwise, ncolumn is the * index (starting with 1) of the selected column and the number of ITEMs * in the column is returned. *$ External_references: * Profile toolkit *$ Side_effects: * none *$ Examples: * Suppose the PDS label associated with an object looks like this: * * ^TIME_SERIES = "FOOBAR.TAB" * ^DATA_TABLE = "FOOBAR.DAT" * ^IMAGE = "FOOBAR.IMG" * OBJECT = TIME_SERIES * ... (3 columns defined, each with 1 item) * END_OBJECT = TIME_SERIES * OBJECT = DATA_TABLE * ... (1 column defined, with 600 items) * END_OBJECT = DATA_TABLE * OBJECT = IMAGE * ... * END_OBJECT = IMAGE * END * * Then FPro_LabelCount(label, 0, 0) returns 2 (number of tables/series); * FPro_LabelCount(label, 1, 0) returns 3 (columns in TIME_SERIES); * FPro_LabelCount(label, 1, 1) returns 1 (items in column); * FPro_LabelCount(label, 2, 1) returns 600 (items in column); *$ Error_handling: * Profile library error handling is in effect. * * Conditions raised: * PRO_CLASS_ERROR if object is NULL or is not a PDS label. * PRO_DOMAIN_ERROR if the table or column index is out of range. * FORTRAN_POINTER_ERROR if object is not a valid FORTRAN object pointer. *$ Limitations: * none *$ Author_and_institution: * Mark R. Showalter * NASA/Ames Research Center *$ Version_and_date: * 1.0: March 1998 *$ Change_history: * none *******************************************************************************/ RL_INT4 FORTRAN_NAME(fpro_labelcount) (object, ntable, ncolumn) RL_INT4 *object; RL_INT4 *ntable, *ncolumn; { RL_VOID *ptr; /* Look up label pointer */ ptr = FORT_GetPointer(*object); if (ptr == NULL) return 0; /* Call function */ return Pro_LabelCount((PRO_OBJECT *) ptr, *ntable, *ncolumn); } /* ******************************************************************************** *$ Component_name: * FPro_LabelName (label.c, fprofile.for) *$ Abstract: * This routine returns the name of the specified table or column. *$ Keywords: * PROFILE, SERIES, LABEL * FORTRAN, PUBLIC, SUBROUTINE *$ Declarations: * subroutine FPro_LabelName(object, ntable, ncolumn, name) * integer*4 object, ntable, ncolumn * character*(*) name *$ Inputs: * object FORTRAN pointer to the PDS label object. * ntable index of selected table (1...n). * ncolumn index of the selected column (0 or 1...n). *$ Outputs: * name desired name. If ncolumn==0, this is the name of the * selected table; otherwise, this is the name of the * selected column. *$ Returns: * none *$ Detailed_description: * This routine returns the name of the specified table or column. * * The quantity returned depends on the which input parameters are set to * zero. If ncolumn is zero, the name of the PDS TABLE or SERIES object is * returned; otherwise, ncolumn is the index (starting with 1) of the * selected column and the routine returns the column's name. * * COLUMN names are defined by the PDS label's NAME field, followed by a * space and (if present) the PDS label's UNIT field in parentheses. *$ External_references: * Profile toolkit *$ Side_effects: * none *$ Examples: * Suppose the PDS label associated with an object looks like this: * * ^SERIES = "PS1G02.TAB" * OBJECT = SERIES * NAME = OCCULTATION_GEOMETRY * SAMPLING_PARAMETER_NAME = RECORD_INDEX * SAMPLING_PARAMETER_UNIT = 'N/A' * START_SAMPLING_PARAMETER = -16. * STOP_SAMPLING_PARAMETER = 1296. * SAMPLING_PARAMETER_INTERVAL = 1.0 * OBJECT = COLUMN * NAME = RECORD_INDEX * UNIT = 'N/A' * END_OBJECT = COLUMN * OBJECT = COLUMN * NAME = INTERCEPT_RADIUS * UNIT = "km" * END_OBJECT = COLUMN * END_OBJECT = SERIES * END * * Then FPro_LabelName(label, 1, 0, name) sets name='OCCULTATION_GEOMETRY'; * FPro_LabelName(label, 1, 1, name) sets name='RECORD_INDEX'; * FPro_LabelName(label, 1, 2, name) sets name='INTERCEPT_RADIUS (km)' *$ Error_handling: * Profile library error handling is in effect. * * Conditions raised: * PRO_CLASS_ERROR if object is NULL or is not a PDS label. * PRO_DOMAIN_ERROR if the table or column index is out of range. * FORTRAN_POINTER_ERROR if object is not a valid FORTRAN pointer. *$ Limitations: * none *$ Author_and_institution: * Mark R. Showalter * NASA/Ames Research Center *$ Version_and_date: * 1.0: March 1998 *$ Change_history: * none ******************************************************************************** * Note: GPro_LabelName() defined here is the intermediary routine between * FPro_LabelName() and Pro_LabelName(), allowing for the fact that strings * cannot be passed directly between FORTRAN and C. See fprofile.for for the * rest of the code. * * subroutine GPro_LabelName(object, ntable, ncolumn, buffer, lbuffer) * integer*4 object, ntable, ncolumn, lbuffer * byte buffer(*) *******************************************************************************/ void FORTRAN_NAME(gpro_labelname) (object, ntable, ncolumn, buffer, lbuffer) RL_INT4 *object, *ntable, *ncolumn, *lbuffer; RL_CHAR *buffer; { RL_VOID *ptr; /* Look up label pointer */ ptr = FORT_GetPointer(*object); if (ptr == NULL) { buffer[0] = '\0'; return; } /* Call function */ strncpy(buffer, Pro_LabelName((PRO_OBJECT *) ptr, *ntable, *ncolumn), *lbuffer-1); buffer[*lbuffer-1] = '\0'; } /* ******************************************************************************** *$ Component_name: * FPro_LabelXName (label.c, fprofile.for) *$ Abstract: * This routine returns the name of a table's X-coordinate. *$ Keywords: * PROFILE, SERIES, LABEL * FORTRAN, PUBLIC, SUBROUTINE *$ Declarations: * subroutine FPro_LabelXName(object, ntable, name) * integer*4 object, ntable * character*(*) name *$ Inputs: * object FORTRAN pointer to the PDS label object. * ntable index of selected table (1...n). *$ Outputs: * name desired name, or blank on non-fatal error. *$ Returns: * none *$ Detailed_description: * This routine returns the name of a table's X-coordinate. Names are * defined by the PDS label's SAMPLING_PARAMETER_NAME field, followed by a * space and (if present) the PDS label's SAMPLING_PARAMETER_UNIT field in * parentheses. *$ External_references: * Profile toolkit *$ Side_effects: * none *$ Examples: * Suppose the PDS label associated with an object looks like this: * * ^SERIES = "PS1G02.TAB" * OBJECT = SERIES * NAME = OCCULTATION_GEOMETRY * SAMPLING_PARAMETER_NAME = RECORD_INDEX * SAMPLING_PARAMETER_UNIT = 'N/A' * START_SAMPLING_PARAMETER = -16. * STOP_SAMPLING_PARAMETER = 1296. * SAMPLING_PARAMETER_INTERVAL = 1.0 * OBJECT = COLUMN * NAME = RECORD_INDEX * UNIT = 'N/A' * END_OBJECT = COLUMN * OBJECT = COLUMN * NAME = INTERCEPT_RADIUS * UNIT = "km" * END_OBJECT = COLUMN * END_OBJECT = SERIES * END * * Then FPro_LabelXName(label, 1, name) sets name='RECORD_INDEX'. *$ Error_handling: * Profile library error handling is in effect. * * Conditions raised: * PRO_CLASS_ERROR if object is NULL or is not a PDS label. * PRO_DOMAIN_ERROR if the table index is out of range. * FORTRAN_POINTER_ERROR if object is not a valid FORTRAN pointer. *$ Limitations: * none *$ Author_and_institution: * Mark R. Showalter * NASA/Ames Research Center *$ Version_and_date: * 1.0: March 1998 *$ Change_history: * none ******************************************************************************** * Note: GPro_LabelXName() defined here is the intermediary routine between * FPro_LabelXName() and Pro_LabelXName(), allowing for the fact that strings * cannot be passed directly between FORTRAN and C. See fprofile.for for the * rest of the code. * * subroutine GPro_LabelXName(object, ntable, buffer, lbuffer) * integer*4 object, ntable, lbuffer * byte buffer(*) *******************************************************************************/ void FORTRAN_NAME(gpro_labelxname) (object, ntable, buffer, lbuffer) RL_INT4 *object, *ntable, *lbuffer; RL_CHAR *buffer; { RL_VOID *ptr; /* Look up label pointer */ ptr = FORT_GetPointer(*object); if (ptr == NULL) { buffer[0] = '\0'; return; } /* Call function */ strncpy(buffer, Pro_LabelXName((PRO_OBJECT *) ptr, *ntable), *lbuffer-1); buffer[*lbuffer-1] = '\0'; } /* ******************************************************************************** *$ Component_name: * FPro_LabelFind (label.c, fprofile.for) *$ Abstract: * This routine returns the index of the named table or column. *$ Keywords: * PROFILE, SERIES, LABEL * FORTRAN, PUBLIC, SUBROUTINE *$ Declarations: * integer*4 function FPro_LabelFind(object, ntable, name) * integer*4 object, ntable * character*(*) name *$ Inputs: * object FORTRAN pointer to the PDS label object. * ntable index of selected table (1...n). * name name of the table or column to find. For columns, this * string can optionally exclude units inside parentheses. *$ Outputs: * none *$ Returns: * index (1...n) of the selected table or column; 0 if not found. * If ntable is zero, this is the index of the table with the given name; * otherwise, this is the index of the column with the given name. *$ Detailed_description: * This routine returns the index of the named table or column. * * The quantity returned depends on the which input parameters are set to * zero. If ntable is zero, the index (starting with 1) of the table with * the given name is returned. Otherwise, ntable is the index of the * selected table and the number returned is the index of the column with * the given name. For columns, if the name string does not contain units * (inside parentheses), then any units in the column name are ignored. *$ External_references: * Profile toolkit *$ Side_effects: * none *$ Examples: * Suppose the PDS label associated with an object looks like this: * * ^SERIES = "PS1G02.TAB" * OBJECT = SERIES * NAME = OCCULTATION_GEOMETRY * SAMPLING_PARAMETER_NAME = RECORD_INDEX * SAMPLING_PARAMETER_UNIT = 'N/A' * START_SAMPLING_PARAMETER = -16. * STOP_SAMPLING_PARAMETER = 1296. * SAMPLING_PARAMETER_INTERVAL = 1.0 * OBJECT = COLUMN * NAME = RECORD_INDEX * UNIT = 'N/A' * END_OBJECT = COLUMN * OBJECT = COLUMN * NAME = INTERCEPT_RADIUS * UNIT = "km" * END_OBJECT = COLUMN * END_OBJECT = SERIES * END * * Then FPro_LabelFind(label, 0, 'OCCULTATION_GEOMETRY') returns 1; * FPro_LabelFind(label, 1, 'RECORD_INDEX') returns 1; * FPro_LabelFind(label, 1, 'INTERCEPT_RADIUS (km)') returns 2; * FPro_LabelFind(label, 1, 'INTERCEPT_RADIUS') returns 2; *$ Error_handling: * Profile library error handling is in effect. * * Conditions raised: * PRO_CLASS_ERROR if object is NULL or is not a PDS label. * PRO_DOMAIN_ERROR if the table index is out of range. * PRO_NOT_FOUND if no table or column of the given name exists. * FORTRAN_POINTER_ERROR if object is not a valid FORTRAN pointer. *$ Limitations: * none *$ Author_and_institution: * Mark R. Showalter * NASA/Ames Research Center *$ Version_and_date: * 1.0: March 1998 *$ Change_history: * none ******************************************************************************** * Note: GPro_LabelFind() defined here is the intermediary routine between * FPro_LabelFind() and Pro_LabelFind(), allowing for the fact that strings * cannot be passed directly between FORTRAN and C. See fprofile.for for the * rest of the code. * * integer*4 function GPro_LabelFind(object, ntable, buffer) * integer*4 object * byte buffer(*) *******************************************************************************/ RL_INT4 FORTRAN_NAME(gpro_labelfind) (object, ntable, buffer) RL_INT4 *object, *ntable; RL_CHAR *buffer; { RL_VOID *ptr; /* Look up label pointer */ ptr = FORT_GetPointer(*object); if (ptr == NULL) return 0; /* Call function */ return Pro_LabelFind((PRO_OBJECT *) ptr, *ntable, buffer); } /* ******************************************************************************** *$ Component_name: * FPro_LabelSampling (label.c) *$ Abstract: * This routine returns the sampling parameters used by a specified table * or column. *$ Keywords: * PROFILE, SERIES, LABEL * FORTRAN, PUBLIC, SUBROUTINE *$ Declarations: * integer*4 function FPro_LabelSampling(object, ntable, ncolumn, nitem, * x1, x2, dx) * integer*4 object, ntable, ncolumn, nitem * real*8 x1, x2, dx *$ Inputs: * object FORTRAN pointer to the PDS label object. * ntable index of selected table (1...n). * ncolumn index of the selected column (1...n) or 0 for row * sampling. * nitem index of selected item, or 0 for all. *$ Outputs: * x1 first sampling parameter. * x2 last sampling parameter. * dx interval between samples. *$ Returns: * the number of samples in selected column/item pair; 0 on error. *$ Detailed_description: * This routine returns the sampling parameters used by a specified table * or column. * * If nitem is nonzero, then it is assumed that the only a single item per * row is to be used; in this case the sampling parameters for the column * match those for the row. However, if nitem is zero in a column that * contains multiple items, then the items are treated as subsamples, so * the sample interval is correspondingly reduced. * * Note that the row sampling parameters are returned if ncolumn is zero. *$ External_references: * Profile toolkit *$ Side_effects: * none *$ Examples: * Suppose the PDS label associated with an object looks like this: * * ^SERIES = "PS1G02.TAB" * OBJECT = SERIES * SAMPLING_PARAMETER_NAME = RECORD_INDEX * SAMPLING_PARAMETER_UNIT = 'N/A' * START_SAMPLING_PARAMETER = -16. * STOP_SAMPLING_PARAMETER = 1296. * SAMPLING_PARAMETER_INTERVAL = 1.0 * OBJECT = COLUMN * ITEMS = 1 * END_OBJECT = COLUMN * OBJECT = COLUMN * ITEMS = 100 * END_OBJECT = COLUMN * END_OBJECT = SERIES * END * * Then FPro_LabelSampling(label, 1, 1, 1, x1, x2, dx) * sets x1=-16.d0, x2=1296.d0, dx=1.d0, returns 1313; * FPro_LabelSampling(label, 1, 1, 0, x1, x2, dx) * sets x1=-16.d0, x2=1296.d0, dx=1.d0, returns 1313; * FPro_LabelSampling(label, 1, 2, 1, x1, x2, dx) * sets x1=-16.d0, x2=1296.d0, dx=1.d0, returns 1313; * FPro_LabelSampling(label, 1, 2, 0, x1, x2, dx) * sets x1=-16.d0, x2=1296.99d0, dx=0.01d0, returns 131300 *$ Error_handling: * Profile library error handling is in effect. * * Conditions raised: * PRO_CLASS_ERROR if object is NULL or is not a PDS label. * PRO_DOMAIN_ERROR if table, column or item index is out of range. * FORTRAN_POINTER_ERROR if object is not a valid FORTRAN object pointer. *$ Limitations: * none *$ Author_and_institution: * Mark R. Showalter * NASA/Ames Research Center *$ Version_and_date: * 1.0: March 1998 *$ Change_history: * none *******************************************************************************/ RL_INT4 FORTRAN_NAME(fpro_labelsampling) (object, ntable, ncolumn, nitem, x1, x2, dx) RL_INT4 *object, *ntable, *ncolumn, *nitem; RL_FLT8 *x1, *x2, *dx; { RL_VOID *ptr; /* Look up label pointer */ ptr = FORT_GetPointer(*object); if (ptr == NULL) return 0; /* Call function */ return Pro_LabelSampling((PRO_OBJECT *) ptr, *ntable, *ncolumn, *nitem, x1, x2, dx); } /* ******************************************************************************** *$ Component_name: * FPro_LabelInt (label.c, fprofile.for) *$ Abstract: * This routine returns the integer value of a specified keyword in a PDS * label. *$ Keywords: * PROFILE, SERIES, LABEL * FORTRAN, PUBLIC, SUBROUTINE *$ Declarations: * integer*4 function FPro_LabelInt(object, table, column, * keyword, default, raise_error) * integer*4 object, table, column, default * character*(*) keyword * logical*4 raise_error *$ Inputs: * object FORTRAN pointer to the PDS label object. * ntable table index, or 0 to search among top keywords only. * ncolumn column index, or 0 to search among table keywords only. * keyword keyword name. * dfault default value to return on error. * raise_error .TRUE. to raise PRO_EVALUATION_FAILURE on error; * .FALSE. otherwise. *$ Outputs: * none *$ Returns: * integer value of the keyword; default value on non-fatal error. *$ Detailed_description: * This routine returns the integer value of a specified keyword in a PDS * label. * * What section of the label is searched depends on the values of the * ntable and ncolumn parameters. If ntable is zero, then only the * keywords at the top of the PDS label (above any PDS OBJECTs) are * searched. If ntable is nonzero but ncolumn is zero, then the keywords * inside the TABLE/SERIES object but above the COLUMN objects are * searched, followed by the keywords at the top of the label. If both * ntable and nseries are nonzero, then the keywords in the selected * COLUMN object are searched, followed by the keywords in the selected * TABLE/SERIES object, followed by the keywords at the top of the label. * * If the keyword is not found in the PDS label, or is found but is not a * valid integer, the default value is returned. In this case, error code * PRO_EVALUATION_FAILURE if the raise_error parameter is TRUE; otherwise * no error condition is raised. *$ External_references: * Profile toolkit, Object Access library. *$ Side_effects: * none *$ Examples: * Suppose the PDS label associated with an object looks like this: * * FOO = 1313 * ABC = "DEF" * OBJECT = SERIES * FOO = 1000 * BAR = 999 * OBJECT = COLUMN * FOO = 3 * END_OBJECT = COLUMN * END_OBJECT = SERIES * END * * Then FPro_LabelInt(label, 1, 1, 'FOO', -99, .TRUE.) returns 3; * FPro_LabelInt(label, 1, 0, 'FOO', -99, .TRUE.) returns 1000; * FPro_LabelInt(label, 0, 0, 'FOO', -99, .TRUE.) returns 1313; * FPro_LabelInt(label, 1, 1, 'BAR', -99, .TRUE.) returns 999; * FPro_LabelInt(label, 1, 0, 'BAR', -99, .TRUE.) returns 999; * FPro_LabelInt(label, 0, 0, 'BAR', -99, .TRUE.) raises * PRO_EVALUATION_FAILURE and returns -99; * FPro_LabelInt(label, 0, 0, 'BAR', -99, .FALSE.) returns -99; * FPro_LabelInt(label, 0, 0, 'ABC', -99, .TRUE.) raises * PRO_EVALUATION_FAILURE and returns -99; * FPro_LabelInt(label, 0, 0, 'ABC', -99, .FALSE.) returns -99; *$ Error_handling: * Profile library error handling is in effect. * * Conditions raised: * PRO_CLASS_ERROR if object is NULL or is not a PDS label. * PRO_DOMAIN_ERROR if the table/column index is out of range. * PRO_EVALUATION_FAILURE raised optionally, if the named keyword is not * found or is not a valid integer. * FORTRAN_POINTER_ERROR if object is not a valid FORTRAN pointer. *$ Limitations: * none *$ Author_and_institution: * Mark R. Showalter * NASA/Ames Research Center *$ Version_and_date: * 1.0: March 1998 *$ Change_history: * none ******************************************************************************** * Note: GPro_LabelInt() defined here is the intermediary routine between * FPro_LabelInt() and Pro_LabelInt(), allowing for the fact that strings cannot * be passed directly between FORTRAN and C. See fprofile.for for the rest of * the code. * * integer*4 function GPro_LabelInt(object, ntable, ncolumn, keyword, * default, raise_error) * integer*4 object, ntable, ncolumn, default * byte keyword(*) * logical*4 raise_error *******************************************************************************/ RL_INT4 FORTRAN_NAME(gpro_labelint) (object, ntable, ncolumn, keyword, dfault, raise_error) RL_INT4 *object, *ntable, *ncolumn, *dfault, *raise_error; RL_CHAR *keyword; { RL_VOID *ptr; /* Look up label pointer */ ptr = FORT_GetPointer(*object); if (ptr == NULL) return 0; /* Call function */ return Pro_LabelInt((PRO_OBJECT *) ptr, *ntable, *ncolumn, keyword, *dfault, (RL_BOOL) *raise_error); } /* ******************************************************************************** *$ Component_name: * FPro_LabelFloat (label.c, fprofile.for) *$ Abstract: * This routine returns the floating-point value of a specified keyword in * a PDS label. *$ Keywords: * PROFILE, SERIES, LABEL * FORTRAN, PUBLIC, SUBROUTINE *$ Declarations: * real*8 function FPro_LabelFloat(object, table, column, * keyword, default, raise_error) * integer*4 object, table, column * character*(*) keyword * real*8 default * logical*4 raise_error *$ Inputs: * object FORTRAN pointer to the PDS label object. * ntable table index, or 0 to search among top keywords only. * ncolumn column index, or 0 to search among table keywords only. * keyword keyword name. * dfault default value to return on error. * raise_error .TRUE. to raise PRO_EVALUATION_FAILURE on error; * .FALSE. otherwise. *$ Outputs: * none *$ Returns: * floating-point value of the keyword; default value on non-fatal error. *$ Detailed_description: * This routine returns the floating-point value of a specified keyword in * a PDS label. * * What section of the label is searched depends on the values of the * ntable and ncolumn parameters. If ntable is zero, then only the * keywords at the top of the PDS label (above any PDS OBJECTs) are * searched. If ntable is nonzero but ncolumn is zero, then the keywords * inside the TABLE/SERIES object but above the COLUMN objects are * searched, followed by the keywords at the top of the label. If both * ntable and nseries are nonzero, then the keywords in the selected * COLUMN object are searched, followed by the keywords in the selected * TABLE/SERIES object, followed by the keywords at the top of the label. * * If the keyword is not found in the PDS label, or is found but is not a * valid floating-point number, the default value is returned. In this * case, error code PRO_EVALUATION_FAILURE if the raise_error parameter is * TRUE; otherwise no error condition is raised. *$ External_references: * Profile toolkit, Object Access library. *$ Side_effects: * none *$ Examples: * Suppose the PDS label associated with an object looks like this: * * FOO = 313. * ABC = "DEF" * OBJECT = SERIES * FOO = 100 * BAR = 999 * OBJECT = COLUMN * FOO = 3. * END_OBJECT = COLUMN * END_OBJECT = SERIES * END * * Then FPro_LabelFloat(label, 1, 1, 'FOO', -99.d0, .TRUE.) returns 3.d0; * FPro_LabelFloat(label, 1, 0, 'FOO', -99.d0, .TRUE.) returns 100.d0; * FPro_LabelFloat(label, 0, 0, 'FOO', -99.d0, .TRUE.) returns 313.d0; * FPro_LabelFloat(label, 1, 1, 'BAR', -99.d0, .TRUE.) returns 999.d0; * FPro_LabelFloat(label, 1, 0, 'BAR', -99.d0, .TRUE.) returns 999.d0; * FPro_LabelFloat(label, 0, 0, 'BAR', -99.d0, .TRUE.) raises * PRO_EVALUATION_FAILURE and returns -99.d0; * FPro_LabelFloat(label, 0, 0, 'BAR', -99.d0, .FALSE.) returns -99.d0; * FPro_LabelFloat(label, 0, 0, 'ABC', -99.d0, .TRUE.) raises * PRO_EVALUATION_FAILURE and returns -99.d0; * FPro_LabelFloat(label, 0, 0, 'ABC', -99.d0, .FALSE.) returns -99.d0; *$ Error_handling: * Profile library error handling is in effect. * * Conditions raised: * PRO_CLASS_ERROR if object is NULL or is not a PDS label. * PRO_DOMAIN_ERROR if the table/column index is out of range. * PRO_EVALUATION_FAILURE raised optionally, if the named keyword is not * found or is not a valid floating-point number. * FORTRAN_POINTER_ERROR if object is not a valid FORTRAN pointer. *$ Limitations: * none *$ Author_and_institution: * Mark R. Showalter * NASA/Ames Research Center *$ Version_and_date: * 1.0: March 1998 *$ Change_history: * none ******************************************************************************** * Note: GPro_LabelFloat() defined here is the intermediary routine between * FPro_LabelFloat() and Pro_LabelFloat(), allowing for the fact that strings * cannot be passed directly between FORTRAN and C. See fprofile.for for the * rest of the code. * * real*8 function GPro_LabelFloat(object, ntable, ncolumn, keyword, * default, raise_error) * integer*4 object, ntable, ncolumn, raise_error * byte keyword(*) * real*8 default *******************************************************************************/ RL_FLT8 FORTRAN_NAME(gpro_labelfloat) (object, ntable, ncolumn, keyword, dfault, raise_error) RL_INT4 *object, *ntable, *ncolumn, *raise_error; RL_CHAR *keyword; RL_FLT8 *dfault; { RL_VOID *ptr; /* Look up label pointer */ ptr = FORT_GetPointer(*object); if (ptr == NULL) return 0.; /* Call function */ return Pro_LabelFloat((PRO_OBJECT *) ptr, *ntable, *ncolumn, keyword, *dfault, (RL_BOOL) *raise_error); } /* ******************************************************************************** *$ Component_name: * FPro_LabelString (label.c, fprofile.for) *$ Abstract: * This routine returns a pointer to the character string value of the * specified keyword in a PDS label. *$ Keywords: * PROFILE, SERIES, LABEL * FORTRAN, PUBLIC, SUBROUTINE *$ Declarations: * subroutine FPro_LabelString(object, table, column, * keyword, default, raise_error, value) * integer*4 object, table, column * character*(*) keyword, default, value * logical*4 raise_error *$ Inputs: * object FORTRAN pointer to the PDS label object. * ntable table index, or 0 to search among top keywords only. * ncolumn column index, or 0 to search among table keywords only. * keyword keyword name. * dfault default string to return on error. * raise_error .TRUE. to raise PRO_EVALUATION_FAILURE on error; * .FALSE. otherwise. *$ Outputs: * value string containing the value of keyword; default string * on error. The string is truncated if necessary after * 255 characters. *$ Returns: * none *$ Detailed_description: * This routine returns a pointer to the character string value of the * specified keyword in a PDS label. Quotes (single or double) are * stripped away if present. * * What section of the label is searched depends on the values of the * ntable and ncolumn parameters. If ntable is zero, then only the * keywords at the top of the PDS label (above any PDS OBJECTs) are * searched. If ntable is nonzero but ncolumn is zero, then the keywords * inside the TABLE/SERIES object but above the COLUMN objects are * searched, followed by the keywords at the top of the label. If both * ntable and nseries are nonzero, then the keywords in the selected * COLUMN object are searched, followed by the keywords in the selected * TABLE/SERIES object, followed by the keywords at the top of the label. * * If the keyword is not found in the PDS label, or is found but is not a * valid string, the default value is returned. In this case, error code * PRO_EVALUATION_FAILURE if the raise_error parameter is TRUE; otherwise * no error condition is raised. *$ External_references: * Profile toolkit, Object Access library. *$ Side_effects: * none *$ Examples: * Suppose the PDS label associated with an object looks like this: * * FOO = 313 * OBJECT = SERIES * FOO = ABC * BAR = 999 * OBJECT = COLUMN * FOO = "Bar" * END_OBJECT = COLUMN * END_OBJECT = SERIES * END * * Then FPro_LabelString(label, 1, 1, 'FOO', 'xx', .TRUE., value) * sets value = 'Bar'; * FPro_LabelString(label, 1, 0, 'FOO', 'xx', .TRUE., value) * sets value = 'ABC'; * FPro_LabelString(label, 0, 0, 'FOO', 'xx', .TRUE., value) * sets value = '313'; * FPro_LabelString(label, 1, 1, 'BAR', 'xx', .TRUE., value) * sets value = '999'; * FPro_LabelString(label, 1, 0, 'BAR', 'xx', .TRUE., value) * sets value = '999'; * FPro_LabelString(label, 0, 0, 'BAR', 'xx', .TRUE., value) * raises PRO_EVALUATION_FAILURE and sets value = 'xx'; * FPro_LabelString(label, 0, 0, 'BAR', 'xx', .FALSE., value) * sets value = 'xx'. *$ Error_handling: * Profile library error handling is in effect. * * Conditions raised: * PRO_CLASS_ERROR if object is NULL or is not a PDS label. * PRO_DOMAIN_ERROR if the table/column index is out of range. * PRO_EVALUATION_FAILURE raised optionally, if the named keyword is not * found or is not a valid string. * FORTRAN_POINTER_ERROR if object is not a valid FORTRAN pointer. *$ Limitations: * Returned strings are limited to 255 characters. *$ Author_and_institution: * Mark R. Showalter * NASA/Ames Research Center *$ Version_and_date: * 1.0: March 1998 *$ Change_history: * none ******************************************************************************** * Note: GPro_LabelString() defined here is the intermediary routine between * FPro_LabelString() and Pro_LabelString(), allowing for the fact that strings * cannot be passed directly between FORTRAN and C. See fprofile.for for the * rest of the code. * * subroutine GPro_LabelString(object, ntable, ncolumn, keyword, default, * raise_error, buffer, lbuffer) * integer*4 object, ntable, ncolumn, lbuffer, raise_error * byte keyword(*), buffer(*), default(*) *******************************************************************************/ void FORTRAN_NAME(gpro_labelstring) (object, ntable, ncolumn, keyword, dfault, raise_error, buffer, lbuffer) RL_INT4 *object, *ntable, *ncolumn, *raise_error, *lbuffer; RL_CHAR *keyword, *dfault, *buffer; { RL_VOID *ptr; RL_CHAR *string; /* Look up label pointer */ ptr = FORT_GetPointer(*object); if (ptr == NULL) { buffer[0] = '\0'; return; } /* Call function */ string = Pro_LabelString((PRO_OBJECT *) ptr, *ntable, *ncolumn, keyword, dfault, (RL_BOOL) *raise_error); strncpy(buffer, string, *lbuffer-1); buffer[*lbuffer] = '\0'; } /********************************************************************************/