Commit 5ae7fed8 authored by Uwe Schulzweida's avatar Uwe Schulzweida
Browse files

Setpartab: added support for user defined attributes.

parent 779df611
2016-10-31 Uwe Schulzweida
* Setpartab: added support for user defined attributes
2016-10-20 Uwe Schulzweida
* New operator cmorlite: apply variable_entry of cmor tables
......
......@@ -79,15 +79,7 @@ typedef struct
} var_t;
static
void defineVarAttText(int vlistID2, int varID, const char *attname, const char *atttext)
{
int len = strlen(atttext);
cdiDefAttTxt(vlistID2, varID, attname, len, atttext);
}
static
void defineVarUnits(var_t *vars, int vlistID2, int varID, const char *units)
void cdo_define_var_units(var_t *var, int vlistID2, int varID, const char *units)
{
char units_old[CDI_MAX_NAME];
......@@ -99,13 +91,82 @@ void defineVarUnits(var_t *vars, int vlistID2, int varID, const char *units)
{
if ( len1 > 0 && len2 > 0 )
{
vars[varID].changeunits = true;
strcpy(vars[varID].units_old, units_old);
strcpy(vars[varID].units, units);
var->changeunits = true;
strcpy(var->units_old, units_old);
strcpy(var->units, units);
}
vlistDefVarUnits(vlistID2, varID, units);
defineVarAttText(vlistID2, varID, "original_units", units_old);
cdiDefAttTxt(vlistID2, varID, "original_units", (int)strlen(units_old), units_old);
}
}
void cdo_check_data(int vlistID2, int varID2, var_t *var, long gridsize, double missval, double *array)
{
char varname[CDI_MAX_NAME];
int nvals = 0;
double amean = 0, aval;
double amin = 1.e300;
double amax = -1.e300;
for ( long i = 0; i < gridsize; ++i )
{
aval = array[i];
if ( !DBL_IS_EQUAL(aval, missval) )
{
if ( aval < amin ) amin = aval;
if ( aval > amax ) amax = aval;
amean += aval;
nvals++;
}
}
if ( nvals > 0 ) amean /= nvals;
int n_lower_min = 0;
int n_greater_max = 0;
for ( long i = 0; i < gridsize; ++i )
{
aval = array[i];
if ( !DBL_IS_EQUAL(aval, missval) )
{
if ( aval < var->valid_min ) n_lower_min++;
if ( aval > var->valid_max ) n_greater_max++;
}
}
vlistInqVarName(vlistID2, varID2, varname);
if ( n_lower_min > 0 )
cdoWarning("Invalid value(s) detected for variable '%s': %i values were lower than minimum valid value (%.4g).",
varname, n_lower_min, var->valid_min);
if ( n_greater_max > 0 )
cdoWarning("Invalid value(s) detected for variable '%s': %i values were greater than maximum valid value (%.4g).",
varname, n_greater_max, var->valid_max);
amean = fabs(amean);
if ( var->check_min_mean_abs )
{
if ( amean < .1*var->ok_min_mean_abs )
cdoWarning("Invalid Absolute Mean for variable '%s' (%.5g) is lower by more than an order of magnitude than minimum allowed: %.4g",
varname, amean, var->ok_min_mean_abs);
if ( amean < var->ok_min_mean_abs)
cdoWarning("Invalid Absolute Mean for variable '%s' (%.5g) is lower than minimum allowed: %.4g",
varname, amean, var->ok_min_mean_abs);
}
if ( var->check_max_mean_abs )
{
if ( amean > 10.*var->ok_max_mean_abs )
cdoWarning("Invalid Absolute Mean for variable '%s' (%.5g) is greater by more than an order of magnitude than maximum allowed: %.4g",
varname, amean, var->ok_max_mean_abs);
if ( amean > var->ok_max_mean_abs )
cdoWarning("Invalid Absolute Mean for variable '%s' (%.5g) is greater than maximum allowed: %.4g",
varname, amean, var->ok_max_mean_abs);
}
}
......@@ -137,16 +198,17 @@ void apply_cmor_table(const char *filename, int nvars, int vlistID2, var_t *vars
for ( int varID = 0; varID < nvars; varID++ )
{
var_t *var = &vars[varID];
vlistInqVarName(vlistID2, varID, varname);
strcpy(vars[varID].name, varname);
strcpy(var->name, varname);
if ( lmissval )
{
double missval_old = vlistInqVarMissval(vlistID2, varID);
if ( ! DBL_IS_EQUAL(missval, missval_old) )
{
vars[varID].changemissval = true;
vars[varID].missval_old = missval_old;
var->changemissval = true;
var->missval_old = missval_old;
vlistDefVarMissval(vlistID2, varID, missval);
}
}
......@@ -154,9 +216,6 @@ void apply_cmor_table(const char *filename, int nvars, int vlistID2, var_t *vars
list_t *kvl = pml_search_kvl_ventry(pml, "name", varname, nventry, ventry);
if ( kvl )
{
// int pnum, ptab, pdum;
// cdiDecodeParam(vlistInqVarParam(vlistID2, varID), &pnum, &ptab, &pdum);
// const int nkv = list_size(kvl);
bool lvalid_min = false, lvalid_max = false;
for ( listNode_t *kvnode = kvl->head; kvnode; kvnode = kvnode->next )
......@@ -170,27 +229,25 @@ void apply_cmor_table(const char *filename, int nvars, int vlistID2, var_t *vars
if ( STR_IS_EQ(key, "standard_name") ) vlistDefVarStdname(vlistID2, varID, value);
else if ( STR_IS_EQ(key, "long_name") ) vlistDefVarLongname(vlistID2, varID, value);
else if ( STR_IS_EQ(key, "units") ) defineVarUnits(vars, vlistID2, varID, value);
else if ( STR_IS_EQ(key, "units") ) cdo_define_var_units(var, vlistID2, varID, value);
else if ( STR_IS_EQ(key, "name") ) /*vlistDefVarName(vlistID2, varID, parameter2word(value))*/;
else if ( STR_IS_EQ(key, "out_name") )
{
vlistDefVarName(vlistID2, varID, parameter2word(value));
defineVarAttText(vlistID2, varID, "original_name", vars[varID].name);
cdiDefAttTxt(vlistID2, varID, "original_name", (int)strlen(var->name), var->name);
}
else if ( STR_IS_EQ(key, "param") ) vlistDefVarParam(vlistID2, varID, stringToParam(parameter2word(value)));
else if ( STR_IS_EQ(key, "out_param") ) vlistDefVarParam(vlistID2, varID, stringToParam(parameter2word(value)));
// else if ( STR_IS_EQ(key, "code") ) vlistDefVarParam(vlistID2, varID, cdiEncodeParam(parameter2int(value), ptab, 255));
// else if ( STR_IS_EQ(key, "out_code") ) vlistDefVarParam(vlistID2, varID, cdiEncodeParam(parameter2int(value), ptab, 255));
else if ( STR_IS_EQ(key, "comment") ) defineVarAttText(vlistID2, varID, "comment", value);
else if ( STR_IS_EQ(key, "cell_methods") ) defineVarAttText(vlistID2, varID, "cell_methods", value);
else if ( STR_IS_EQ(key, "cell_measures") ) defineVarAttText(vlistID2, varID, "cell_measures", value);
else if ( STR_IS_EQ(key, "delete") ) vars[varID].remove = parameter2bool(value);
else if ( STR_IS_EQ(key, "convert") ) vars[varID].convert = parameter2bool(value);
else if ( STR_IS_EQ(key, "comment") ) cdiDefAttTxt(vlistID2, varID, key, (int)strlen(value), value);
else if ( STR_IS_EQ(key, "cell_methods") ) cdiDefAttTxt(vlistID2, varID, key, (int)strlen(value), value);
else if ( STR_IS_EQ(key, "cell_measures") ) cdiDefAttTxt(vlistID2, varID, key, (int)strlen(value), value);
else if ( STR_IS_EQ(key, "delete") ) var->remove = parameter2bool(value);
else if ( STR_IS_EQ(key, "convert") ) var->convert = parameter2bool(value);
else if ( STR_IS_EQ(key, "factor") )
{
vars[varID].lfactor = true;
vars[varID].factor = parameter2double(value);
if ( cdoVerbose ) cdoPrint("%s - scale factor %g", varname, vars[varID].factor);
var->lfactor = true;
var->factor = parameter2double(value);
if ( cdoVerbose ) cdoPrint("%s - scale factor %g", varname, var->factor);
}
else if ( STR_IS_EQ(key, "missval") )
{
......@@ -199,30 +256,30 @@ void apply_cmor_table(const char *filename, int nvars, int vlistID2, var_t *vars
if ( ! DBL_IS_EQUAL(missval, missval_old) )
{
if ( cdoVerbose ) cdoPrint("%s - change missval from %g to %g", varname, missval_old, missval);
vars[varID].changemissval = true;
vars[varID].missval_old = missval_old;
var->changemissval = true;
var->missval_old = missval_old;
vlistDefVarMissval(vlistID2, varID, missval);
}
}
else if ( STR_IS_EQ(key, "valid_min") )
{
lvalid_min = true;
vars[varID].valid_min = parameter2double(value);
var->valid_min = parameter2double(value);
}
else if ( STR_IS_EQ(key, "valid_max") )
{
lvalid_max = true;
vars[varID].valid_max = parameter2double(value);
var->valid_max = parameter2double(value);
}
else if ( STR_IS_EQ(key, "ok_min_mean_abs") )
{
vars[varID].check_min_mean_abs = true;
vars[varID].ok_min_mean_abs = parameter2double(value);
var->check_min_mean_abs = true;
var->ok_min_mean_abs = parameter2double(value);
}
else if ( STR_IS_EQ(key, "ok_max_mean_abs") )
{
vars[varID].check_max_mean_abs = true;
vars[varID].ok_max_mean_abs = parameter2double(value);
var->check_max_mean_abs = true;
var->ok_max_mean_abs = parameter2double(value);
}
else if ( STR_IS_EQ(key, "datatype") || STR_IS_EQ(key, "type") )
{
......@@ -235,7 +292,7 @@ void apply_cmor_table(const char *filename, int nvars, int vlistID2, var_t *vars
}
}
if ( lvalid_min && lvalid_max ) vars[varID].checkvalid = true;
if ( lvalid_min && lvalid_max ) var->checkvalid = true;
}
else
{
......@@ -246,75 +303,6 @@ void apply_cmor_table(const char *filename, int nvars, int vlistID2, var_t *vars
list_destroy(pml);
}
static
void check_data(int vlistID2, int varID2, int varID, var_t *vars, long gridsize, double missval, double *array)
{
char varname[CDI_MAX_NAME];
int nvals = 0;
double amean = 0, aval;
double amin = 1.e300;
double amax = -1.e300;
for ( long i = 0; i < gridsize; ++i )
{
aval = array[i];
if ( !DBL_IS_EQUAL(aval, missval) )
{
if ( aval < amin ) amin = aval;
if ( aval > amax ) amax = aval;
amean += aval;
nvals++;
}
}
if ( nvals > 0 ) amean /= nvals;
int n_lower_min = 0;
int n_greater_max = 0;
for ( long i = 0; i < gridsize; ++i )
{
aval = array[i];
if ( !DBL_IS_EQUAL(aval, missval) )
{
if ( aval < vars[varID].valid_min ) n_lower_min++;
if ( aval > vars[varID].valid_max ) n_greater_max++;
}
}
vlistInqVarName(vlistID2, varID2, varname);
if ( n_lower_min > 0 )
cdoWarning("Invalid value(s) detected for variable '%s': %i values were lower than minimum valid value (%.4g).",
varname, n_lower_min, vars[varID].valid_min);
if ( n_greater_max > 0 )
cdoWarning("Invalid value(s) detected for variable '%s': %i values were greater than maximum valid value (%.4g).",
varname, n_greater_max, vars[varID].valid_max);
amean = fabs(amean);
if ( vars[varID].check_min_mean_abs )
{
if ( amean < .1*vars[varID].ok_min_mean_abs )
cdoWarning("Invalid Absolute Mean for variable '%s' (%.5g) is lower by more than an order of magnitude than minimum allowed: %.4g",
varname, amean, vars[varID].ok_min_mean_abs);
if ( amean < vars[varID].ok_min_mean_abs)
cdoWarning("Invalid Absolute Mean for variable '%s' (%.5g) is lower than minimum allowed: %.4g",
varname, amean, vars[varID].ok_min_mean_abs);
}
if ( vars[varID].check_max_mean_abs )
{
if ( amean > 10.*vars[varID].ok_max_mean_abs )
cdoWarning("Invalid Absolute Mean for variable '%s' (%.5g) is greater by more than an order of magnitude than maximum allowed: %.4g",
varname, amean, vars[varID].ok_max_mean_abs);
if ( amean > vars[varID].ok_max_mean_abs )
cdoWarning("Invalid Absolute Mean for variable '%s' (%.5g) is greater than maximum allowed: %.4g",
varname, amean, vars[varID].ok_max_mean_abs);
}
}
void *CMOR_lite(void *argument)
{
......@@ -428,12 +416,13 @@ void *CMOR_lite(void *argument)
{
streamInqRecord(streamID1, &varID, &levelID);
var_t *var = &vars[varID];
int varID2 = varID;
int levelID2 = levelID;
if ( delvars )
{
if ( vars[varID].remove ) continue;
if ( var->remove ) continue;
if ( vlistInqFlag(vlistID1, varID, levelID) == TRUE )
{
......@@ -450,47 +439,47 @@ void *CMOR_lite(void *argument)
gridsize = gridInqSize(vlistInqVarGrid(vlistID2, varID2));
if ( vlistInqVarNumber(vlistID2, varID2) != CDI_REAL ) gridsize *= 2;
if ( nmiss > 0 && vars[varID].changemissval )
if ( nmiss > 0 && var->changemissval )
{
for ( long i = 0; i < gridsize; ++i )
{
if ( DBL_IS_EQUAL(array[i], vars[varID].missval_old) ) array[i] = missval;
if ( DBL_IS_EQUAL(array[i], var->missval_old) ) array[i] = missval;
}
}
if ( vars[varID].lfactor )
if ( var->lfactor )
{
for ( long i = 0; i < gridsize; ++i )
{
if ( !DBL_IS_EQUAL(array[i], missval) ) array[i] *= vars[varID].factor;
if ( !DBL_IS_EQUAL(array[i], missval) ) array[i] *= var->factor;
}
}
#if defined(HAVE_UDUNITS2)
if ( vars[varID].changeunits )
if ( var->changeunits )
{
int nerr = 0;
for ( long i = 0; i < gridsize; ++i )
{
if ( !DBL_IS_EQUAL(array[i], missval) )
{
array[i] = cv_convert_double((const cv_converter*)vars[varID].ut_converter, array[i]);
array[i] = cv_convert_double((const cv_converter*)var->ut_converter, array[i]);
if ( ut_get_status() != UT_SUCCESS ) nerr++;
}
}
if ( nerr )
{
cdoWarning("Udunits: Error converting units from [%s] to [%s], parameter: %s",
vars[varID].units_old, vars[varID].units, vars[varID].name);
vars[varID].changeunits = false;
var->units_old, var->units, var->name);
var->changeunits = false;
}
}
#endif
streamWriteRecord(streamID2, array, nmiss);
if ( vars[varID].checkvalid || vars[varID].check_min_mean_abs || vars[varID].check_max_mean_abs )
check_data(vlistID2, varID2, varID, vars, gridsize, missval, array);
if ( var->checkvalid || var->check_min_mean_abs || var->check_max_mean_abs )
cdo_check_data(vlistID2, varID2, var, gridsize, missval, array);
}
tsID1++;
}
......
......@@ -100,6 +100,7 @@ libcdo_la_SOURCES = \
par_io.h \
parse_cmor_table.c \
parse_namelist.c \
parse_literal.c \
percentiles_hist.c \
percentiles_hist.h \
percentiles.c \
......
......@@ -128,9 +128,10 @@ am_libcdo_la_OBJECTS = libcdo_la-cdo_pthread.lo libcdo_la-cdo_vlist.lo \
libcdo_la-modules.lo libcdo_la-namelist.lo libcdo_la-nml.lo \
libcdo_la-normal.lo libcdo_la-nth_element.lo \
libcdo_la-par_io.lo libcdo_la-parse_cmor_table.lo \
libcdo_la-parse_namelist.lo libcdo_la-percentiles_hist.lo \
libcdo_la-percentiles.lo libcdo_la-pipe.lo libcdo_la-pml.lo \
libcdo_la-pmlist.lo libcdo_la-process.lo libcdo_la-pstream.lo \
libcdo_la-parse_namelist.lo libcdo_la-parse_literal.lo \
libcdo_la-percentiles_hist.lo libcdo_la-percentiles.lo \
libcdo_la-pipe.lo libcdo_la-pml.lo libcdo_la-pmlist.lo \
libcdo_la-process.lo libcdo_la-pstream.lo \
libcdo_la-pthread_debug.lo libcdo_la-readline.lo \
libcdo_la-realtime.lo libcdo_la-remaplib.lo \
libcdo_la-remapsort.lo libcdo_la-remap_scrip_io.lo \
......@@ -519,20 +520,21 @@ libcdo_la_SOURCES = cdo_int.h compare.h cdo_pthread.c cdo_vlist.c \
list.c list.h merge_sort2.c merge_sort2.h modules.c modules.h \
namelist.c namelist.h nml.c nml.h normal.c nth_element.c \
nth_element.h operator_help.h par_io.c par_io.h \
parse_cmor_table.c parse_namelist.c percentiles_hist.c \
percentiles_hist.h percentiles.c percentiles.h pipe.c pipe.h \
pml.c pml.h pmlist.c pmlist.h pragma_omp_atomic_update.h \
printinfo.h process.c process.h pstream.c pstream.h \
pstream_write.h pstream_int.h pthread_debug.c pthread_debug.h \
readline.c realtime.c remap.h remaplib.c remapsort.c \
remap_scrip_io.c remap_search_reg2d.c remap_search_latbins.c \
remap_store_link.c remap_store_link.h remap_store_link_cnsrv.c \
remap_store_link_cnsrv.h remap_conserv.c remap_conserv_scrip.c \
remap_distwgt.c remap_bicubic_scrip.c remap_bilinear_scrip.c \
stdnametable.c stdnametable.h specspace.c specspace.h \
statistic.c statistic.h table.c text.c text.h timebase.h \
timer.c userlog.c uthash.h util.c util.h zaxis.c json/jsmn.h \
json/jsmn.c kdtreelib/kdtree.h kdtreelib/kdtree_cartesian.c \
parse_cmor_table.c parse_namelist.c parse_literal.c \
percentiles_hist.c percentiles_hist.h percentiles.c \
percentiles.h pipe.c pipe.h pml.c pml.h pmlist.c pmlist.h \
pragma_omp_atomic_update.h printinfo.h process.c process.h \
pstream.c pstream.h pstream_write.h pstream_int.h \
pthread_debug.c pthread_debug.h readline.c realtime.c remap.h \
remaplib.c remapsort.c remap_scrip_io.c remap_search_reg2d.c \
remap_search_latbins.c remap_store_link.c remap_store_link.h \
remap_store_link_cnsrv.c remap_store_link_cnsrv.h \
remap_conserv.c remap_conserv_scrip.c remap_distwgt.c \
remap_bicubic_scrip.c remap_bilinear_scrip.c stdnametable.c \
stdnametable.h specspace.c specspace.h statistic.c statistic.h \
table.c text.c text.h timebase.h timer.c userlog.c uthash.h \
util.c util.h zaxis.c json/jsmn.h json/jsmn.c \
kdtreelib/kdtree.h kdtreelib/kdtree_cartesian.c \
kdtreelib/kdtree_common.c kdtreelib/kdtree_spherical.c \
kdtreelib/qsort.c kdtreelib/pmergesort.c kdtreelib/pqueue.c \
kdtreelib/pqueue.h clipping/clipping.c clipping/clipping.h \
......@@ -1048,6 +1050,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcdo_la-nth_element.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcdo_la-par_io.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcdo_la-parse_cmor_table.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcdo_la-parse_literal.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcdo_la-parse_namelist.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcdo_la-percentiles.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcdo_la-percentiles_hist.Plo@am__quote@
......@@ -1517,6 +1520,13 @@ libcdo_la-parse_namelist.lo: parse_namelist.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-parse_namelist.lo `test -f 'parse_namelist.c' || echo '$(srcdir)/'`parse_namelist.c
libcdo_la-parse_literal.lo: parse_literal.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-parse_literal.lo -MD -MP -MF $(DEPDIR)/libcdo_la-parse_literal.Tpo -c -o libcdo_la-parse_literal.lo `test -f 'parse_literal.c' || echo '$(srcdir)/'`parse_literal.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-parse_literal.Tpo $(DEPDIR)/libcdo_la-parse_literal.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='parse_literal.c' object='libcdo_la-parse_literal.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-parse_literal.lo `test -f 'parse_literal.c' || echo '$(srcdir)/'`parse_literal.c
libcdo_la-percentiles_hist.lo: percentiles_hist.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-percentiles_hist.lo -MD -MP -MF $(DEPDIR)/libcdo_la-percentiles_hist.Tpo -c -o libcdo_la-percentiles_hist.lo `test -f 'percentiles_hist.c' || echo '$(srcdir)/'`percentiles_hist.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-percentiles_hist.Tpo $(DEPDIR)/libcdo_la-percentiles_hist.Plo
......
......@@ -65,35 +65,9 @@ typedef struct
} var_t;
static
void defineVarAttText(int vlistID2, int varID, const char *attname, const char *atttext)
{
int len = strlen(atttext);
cdiDefAttTxt(vlistID2, varID, attname, len, atttext);
}
static
void defineVarUnits(var_t *vars, int vlistID2, int varID, const char *units)
{
char units_old[CDI_MAX_NAME];
void cdo_define_var_units(var_t *var, int vlistID2, int varID, const char *units);
void cdo_check_data(int vlistID2, int varID2, var_t *var, long gridsize, double missval, double *array);
vlistInqVarUnits(vlistID2, varID, units_old);
size_t len1 = strlen(units_old);
size_t len2 = strlen(units);
if ( strcmp(units, units_old) != 0 )
{
if ( len1 > 0 && len2 > 0 )
{
vars[varID].changeunits = true;
strcpy(vars[varID].units_old, units_old);
strcpy(vars[varID].units, units);
}
vlistDefVarUnits(vlistID2, varID, units);
defineVarAttText(vlistID2, varID, "original_units", units_old);
}
}
static
void read_partab(pt_mode_t ptmode, const char *filename, int nvars, int vlistID2, var_t *vars)
......@@ -125,16 +99,17 @@ void read_partab(pt_mode_t ptmode, const char *filename, int nvars, int vlistID2
for ( int varID = 0; varID < nvars; varID++ )
{
var_t *var = &vars[varID];
vlistInqVarName(vlistID2, varID, varname);
strcpy(vars[varID].name, varname);
strcpy(var->name, varname);
if ( lmissval )
{
double missval_old = vlistInqVarMissval(vlistID2, varID);
if ( ! DBL_IS_EQUAL(missval, missval_old) )
{
vars[varID].changemissval = true;
vars[varID].missval_old = missval_old;
var->changemissval = true;
var->missval_old = missval_old;
vlistDefVarMissval(vlistID2, varID, missval);
}
}
......@@ -190,79 +165,126 @@ void read_partab(pt_mode_t ptmode, const char *filename, int nvars, int vlistID2
{
keyValues_t *kv = *(keyValues_t **)kvnode->data;
const char *key = kv->key;
const char *value = (kv->nvalues == 1) ? kv->values[0] : NULL;
const char *value = (kv->nvalues > 0) ? kv->values[0] : NULL;
if ( !value ) continue;
// printf("key=%s value=%s\n", key, value);
if ( STR_IS_EQ(key, "standard_name") ) vlistDefVarStdname(vlistID2, varID, value);
else if ( STR_IS_EQ(key, "long_name") ) vlistDefVarLongname(vlistID2, varID, value);
else if ( STR_IS_EQ(key, "units") ) defineVarUnits(vars, vlistID2, varID, value);
else if ( STR_IS_EQ(key, "units") ) cdo_define_var_units(var, vlistID2, varID, value);
else if ( STR_IS_EQ(key, "name") ) /*vlistDefVarName(vlistID2, varID, parameter2word(value))*/;
else if ( STR_IS_EQ(key, "out_name") )
{
vlistDefVarName(vlistID2, varID, parameter2word(value));
defineVarAttText(vlistID2, varID, "original_name", vars[varID].name);
cdiDefAttTxt(vlistID2, varID, "original_name", (int)strlen(var->name), var->name);
}
else if ( STR_IS_EQ(key, "param") ) vlistDefVarParam(vlistID2, varID, stringToParam(parameter2word(value)));
else if ( STR_IS_EQ(key, "out_param") ) vlistDefVarParam(vlistID2, varID, stringToParam(parameter2word(value)));
else if ( STR_IS_EQ(key, "code") ) vlistDefVarParam(vlistID2, varID, cdiEncodeParam(parameter2int(value), ptab, 255));
else if ( STR_IS_EQ(key, "out_code") ) vlistDefVarParam(vlistID2, varID, cdiEncodeParam(parameter2int(value), ptab, 255));
else if ( STR_IS_EQ(key, "comment") ) defineVarAttText(vlistID2, varID, "comment", value);
else if ( STR_IS_EQ(key, "cell_methods") ) defineVarAttText(vlistID2, varID, "cell_methods", value);
else if ( STR_IS_EQ(key, "cell_measures") ) defineVarAttText(vlistID2, varID, "cell_measures", value);
else if ( STR_IS_EQ(key, "delete") ) vars[varID].remove = parameter2bool(value);
else if ( STR_IS_EQ(key, "convert") ) vars[varID].convert = parameter2bool(value);
else if ( STR_IS_EQ(key, "comment") ) cdiDefAttTxt(vlistID2, varID, key, (int)strlen(value), value);
else if ( STR_IS_EQ(key, "cell_methods") ) cdiDefAttTxt(vlistID2, varID, key, (int)strlen(value), value);
else if ( STR_IS_EQ(key, "cell_measures") ) cdiDefAttTxt(vlistID2, varID, key, (int)strlen(value), value);
else if ( STR_IS_EQ(key, "delete") ) var->remove = parameter2bool(value);
else if ( STR_IS_EQ(key, "convert") ) var->convert = parameter2bool(value);
else if ( STR_IS_EQ(key, "factor") )
{
vars[varID].lfactor = true;
vars[varID].factor = parameter2double(value);
if ( cdoVerbose ) cdoPrint("%s - scale factor %g", varname, vars[varID].factor);
var->lfactor = true;
var->factor = parameter2double(value);
if ( cdoVerbose ) cdoPrint("%s - scale factor %g", varname, var->factor);
}
else if ( STR_IS_EQ(key, "missval") )
else if ( STR_IS_EQ(key, "missval") || STR_IS_EQ(key, "missing_value") )
{
double missval = parameter2double(value);
double missval_old = vlistInqVarMissval(vlistID2, varID);
if ( ! DBL_IS_EQUAL(missval, missval_old) )
{
if ( cdoVerbose ) cdoPrint("%s - change missval from %g to %g", varname, missval_old, missval);
vars[varID].changemissval = true;
vars[varID].missval_old = missval_old;
var->changemissval = true;
var->missval_old = missval_old;
vlistDefVarMissval(vlistID2, varID, missval);
}
}
else if ( STR_IS_EQ(key, "valid_min") )
{
lvalid_min = true;
vars[varID].valid_min = parameter2double(value);
var->valid_min = parameter2double(value);
}
else if ( STR_IS_EQ(key, "valid_max") )
{
lvalid_max = true;
vars[varID].valid_max = parameter2double(value);
var->valid_max = parameter2double(value);
}
else if ( STR_IS_EQ(key, "ok_min_mean_abs") )
{
vars[varID].check_min_mean_abs = true;
vars[varID].ok_min_mean_abs = parameter2double(value);
var->check_min_mean_abs = true;
var->ok_min_mean_abs = parameter2double(value);
}
else if ( STR_IS_EQ(key, "ok_max_mean_abs") )
{
vars[varID].check_max_mean_abs = true;
vars[varID].ok_max_mean_abs = parameter2double(value);
var->check_max_mean_abs = true;
var->ok_max_mean_abs = parameter2double(value);
}
else if ( STR_IS_EQ(key, "datatype") || STR_IS_EQ(key, "type") )
{
int datatype = str2datatype(parameter2word(value));
if ( datatype != -1 ) vlistDefVarDatatype(vlistID2, varID, datatype);
}