/* label.c ********************************************************************************
* 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';
}
/*******************************************************************************
*/