Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • mpim-sw/cdo
1 result
Show changes
Commits on Source (76)
2023-09-05 Uwe Schulzweida
* Using YAC version 3.0.1
* Version 2.2.2 release
2023-07-17 Uwe Schulzweida
* Ymonstat: set default timestat date to LAST (bug fix)
2023-07-14 Uwe Schulzweida
* yearminidx/yearmaxidx: remove change of datatype to CDI_DATATYPE_INT32 (bug fix)
2023-07-13 Uwe Schulzweida
* selgridcell: add point coodinate for healpix grids
2023-07-11 Uwe Schulzweida
* remapnn: print node information of source grid in verbose mode
2023-07-07 Uwe Schulzweida
* Expr: add function cdoy() (day of year) and cdpy() (days_per_year)
2023-07-06 Uwe Schulzweida
* Module Ymonarith: failed with more than one variable in release 2.2.0 (bug fix)
* Module Compc: unpack vlist
* Remove packing attributes scale_factor/add_offset if option -b is set
2023-06-30 Uwe Schulzweida
* zonmedian: add support for missing values
* mermedian: add support for missing values
* fldmedian: add support for missing values
* median: add support for missing values
* ap2pl: add support for full and half pressure fields in the same input file
2023-06-29 Uwe Schulzweida
......
......@@ -14,6 +14,12 @@ Version 2.3.0 (21 October 2023):
* Add module Ymoncomp - Multi-year monthly comparison (operators: ymoneq ymonne ymonle ymonlt ymonge ymongt)
Fixed bugs:
Version 2.2.2 (5 September 2023):
Fixed bugs:
* Module Ymonarith: failed with more than one variable in release 2.2.0
* median: add support for missing values
Version 2.2.1 (29 June 2023):
New features:
......@@ -25,7 +31,7 @@ Version 2.2.1 (29 June 2023):
* gh2hl: add support for NextGems3 healpix/zarr data
* gendis: add support for neighbors parameter
Fixed bugs:
* Reading of remap weight files failed in release 2.2.0
* Reading of older remap weight files failed in release 2.2.0
* Module splittime failed in release 2.2.0
* Timstat: memType missmatch with option --worker
......
......@@ -225,6 +225,14 @@ case "${HOSTNAME}" in
CPPFLAGS="-DWARN_UNUSED" \
CXX=g++ CXXFLAGS="-g -pipe -Wall -Wextra -Wshadow -Wfloat-equal -pedantic -O3 -march=native -flto" \
CC=gcc CFLAGS="-g -pipe -Wall -Wextra -Wshadow -Wfloat-equal -pedantic -O3 -march=native -flto"
elif test "$COMP" = gnu_sanitize ; then
${CONFPATH}configure --prefix=$HOME/local \
--enable-maintainer-mode \
$CDOLIBS \
LDFLAGS="$LDFLAGS" \
CPPFLAGS="-DWARN_UNUSED" \
CXX=g++ CXXFLAGS="-g -pipe -Wall -Wextra -Wshadow -Wfloat-equal -pedantic -O3 -march=native -fsanitize=address" \
CC=gcc CFLAGS="-g -pipe -Wall -Wextra -Wshadow -Wfloat-equal -pedantic -O3 -march=native -fsanitize=address"
elif test "$COMP" = gnu ; then
${CONFPATH}configure --prefix=$HOME/local \
--enable-maintainer-mode \
......
......@@ -231,6 +231,7 @@ AC_CONFIG_FILES([test/pytest/cdoTest.py
test/pytest/Gridarea.py.test
test/pytest/Gridboxstat.py.test
test/pytest/Importcmsaf.py.test
test/pytest/Intgrid.py.test
test/pytest/Inttime.py.test
test/pytest/Intyear.py.test
test/pytest/Isosurface.py.test
......@@ -246,6 +247,7 @@ AC_CONFIG_FILES([test/pytest/cdoTest.py
test/pytest/Monarith.py.test
test/pytest/Multiyearstat.py.test
test/pytest/Ninfo.py.test
test/pytest/Pack.py.test
test/pytest/Percentile.py.test
test/pytest/Read_grib.py.test
test/pytest/Read_netcdf.py.test
......
......@@ -353,7 +353,7 @@ after_setNextDate(AfterControl *globs)
}
if (nrecs == 0) break;
const auto vDateTime = taxisInqVdatetime(globs->taxisID);
auto vDateTime = taxisInqVdatetime(globs->taxisID);
after_setDateTime(&globs->NextDate, vDateTime);
for (int i = 0; i < nrqh; ++i)
......@@ -391,7 +391,7 @@ after_readTimestep(void *arg)
{
streamInqRecord(globs->istreamID, &varID, &levelID);
const auto code = vlistInqVarCode(globs->ivlistID, varID);
auto code = vlistInqVarCode(globs->ivlistID, varID);
if (code <= 0 || code >= MaxCodes) continue;
// Skip records containing unneeded codes
......@@ -399,14 +399,14 @@ after_readTimestep(void *arg)
vlistInqVar(globs->ivlistID, varID, &gridID, &zaxisID, &timeID);
const auto leveltype = zaxisInqType(zaxisID);
auto leveltype = zaxisInqType(zaxisID);
// Skip records with unselected levels
int levelOffset = -1;
// if ( vars[code].ozaxisID != vars[code].izaxisID && ! Lhybrid2pressure )
if ((vars[code].ozaxisID != vars[code].izaxisID) && (leveltype == ZAXIS_PRESSURE))
{
const auto level = (int) zaxisInqLevel(zaxisID, levelID);
auto level = (int) zaxisInqLevel(zaxisID, levelID);
for (int i = 0; i < globs->NumLevelRequest; ++i)
{
if (IS_EQUAL(globs->LevelRequest[i], level))
......@@ -465,7 +465,7 @@ after_defineNextTimestep(const AfterControl &globs)
{
if (otsID == 0)
{
const auto nvars = vlistNvars(globs.ovlistID);
auto nvars = vlistNvars(globs.ovlistID);
if (nvars == 0) afterAbort("No variable selected!");
vlistDefTaxis(globs.ovlistID, globs.taxisID2);
streamDefVlist(globs.ostreamID, globs.ovlistID);
......@@ -579,7 +579,7 @@ after_control(AfterControl &globs, struct Variable *vars)
nrecs = streamInqTimestep(globs.istreamID, TsID);
if (nrecs == 0) break;
const auto vDateTime = taxisInqVdatetime(globs.taxisID);
auto vDateTime = taxisInqVdatetime(globs.taxisID);
after_setDateTime(&globs.StartDate, vDateTime);
after_setDateTime(&globs.NewDate, vDateTime);
......@@ -595,8 +595,8 @@ after_control(AfterControl &globs, struct Variable *vars)
TsID++;
}
const auto taxis_is_relative = (taxisInqType(globs.taxisID) == TAXIS_RELATIVE);
const auto rDateTime = taxis_is_relative ? taxisInqRdatetime(globs.taxisID) : after_getDateTime(globs.StartDate);
auto taxis_is_relative = (taxisInqType(globs.taxisID) == TAXIS_RELATIVE);
auto rDateTime = taxis_is_relative ? taxisInqRdatetime(globs.taxisID) : after_getDateTime(globs.StartDate);
if (filetype_is_netcdf(ofiletype))
{
......@@ -694,8 +694,8 @@ after_setLevel(AfterControl &globs)
// default height level
long hlevelDefault[] = { 0, 1000, 2000, 5000, 10000, 15000, 20000, 25000, 30000 };
const int numplevelDefault = sizeof(plevelDefault) / sizeof(plevelDefault[0]);
const int numhlevelDefault = sizeof(hlevelDefault) / sizeof(hlevelDefault[0]);
int numplevelDefault = sizeof(plevelDefault) / sizeof(plevelDefault[0]);
int numhlevelDefault = sizeof(hlevelDefault) / sizeof(hlevelDefault[0]);
if (iVertID != -1)
if (zaxisInqType(iVertID) == ZAXIS_HYBRID && globs.Type > 20) Lhybrid2pressure = true;
......@@ -1051,11 +1051,11 @@ after_setCodes(const AfterControl &globs, struct Variable *vars, int maxCodes, i
longname[0] = 0;
int tableID;
int table = 0;
const auto varID = vars[code].ivarID;
auto varID = vars[code].ivarID;
if (varID == CDI_UNDEFID)
{
const auto modelID = vlistInqVarModel(globs.ivlistID, 0);
auto modelID = vlistInqVarModel(globs.ivlistID, 0);
table = 128;
tableID = tableInq(modelID, table, nullptr);
......@@ -1159,9 +1159,9 @@ after_parini(AfterControl &globs, struct Variable *vars)
if (globs.Mean >= 2) afterAbort("Namelist parameter MEAN=%d out of bounds (0:1)", globs.Mean);
const auto fileFormat = scan_par(globs.Verbose, namelist, "format", -1);
const auto gribFormat = scan_par_obsolete(namelist, "grib", 0);
const auto cdfFormat = scan_par_obsolete(namelist, "netcdf", 0);
auto fileFormat = scan_par(globs.Verbose, namelist, "format", -1);
auto gribFormat = scan_par_obsolete(namelist, "grib", 0);
auto cdfFormat = scan_par_obsolete(namelist, "netcdf", 0);
if (gribFormat && cdfFormat) afterAbort("GRIB or NetCDF?");
......@@ -1181,7 +1181,7 @@ after_parini(AfterControl &globs, struct Variable *vars)
if (gribFormat) ofiletype = CDI_FILETYPE_GRB;
if (cdfFormat) ofiletype = CDI_FILETYPE_NC;
const int precision = scan_par(globs.Verbose, namelist, "precision", 0);
int precision = scan_par(globs.Verbose, namelist, "precision", 0);
if (precision) switch (precision)
{
case 8: DataType = CDI_DATATYPE_PACK8; break;
......@@ -1262,10 +1262,10 @@ after_precntl(AfterControl &globs, struct Variable *vars)
int nhzaxis = 0;
int FieldDim = 0;
const auto nvars = vlistNvars(globs.ivlistID);
const auto ngrids = vlistNgrids(globs.ivlistID);
const auto nverts = vlistNzaxis(globs.ivlistID);
const auto ntsteps = vlistNtsteps(globs.ivlistID);
auto nvars = vlistNvars(globs.ivlistID);
auto ngrids = vlistNgrids(globs.ivlistID);
auto nverts = vlistNzaxis(globs.ivlistID);
auto ntsteps = vlistNtsteps(globs.ivlistID);
if (globs.Debug)
{
......@@ -1277,9 +1277,9 @@ after_precntl(AfterControl &globs, struct Variable *vars)
for (int index = 0; index < ngrids; ++index)
{
const auto gridID = vlistGrid(globs.ivlistID, index);
const auto gridtype = gridInqType(gridID);
const int datasize = gridInqSize(gridID);
auto gridID = vlistGrid(globs.ivlistID, index);
auto gridtype = gridInqType(gridID);
int datasize = gridInqSize(gridID);
if (datasize > FieldDim) FieldDim = datasize;
......@@ -1321,9 +1321,9 @@ after_precntl(AfterControl &globs, struct Variable *vars)
for (int index = 0; index < nverts; ++index)
{
const auto zaxisID = vlistZaxis(globs.ivlistID, index);
const auto leveltype = zaxisInqType(zaxisID);
const auto numlevel = zaxisInqSize(zaxisID);
auto zaxisID = vlistZaxis(globs.ivlistID, index);
auto leveltype = zaxisInqType(zaxisID);
auto numlevel = zaxisInqSize(zaxisID);
/*
printf("leveltype : %d %d\n", leveltype, zaxisInqSize(zaxisID));
*/
......@@ -1402,8 +1402,8 @@ after_precntl(AfterControl &globs, struct Variable *vars)
if (globs.Verbose)
{
const auto instID = vlistInqVarInstitut(globs.ivlistID, 0);
const auto modelID = vlistInqVarModel(globs.ivlistID, 0);
auto instID = vlistInqVarInstitut(globs.ivlistID, 0);
auto modelID = vlistInqVarModel(globs.ivlistID, 0);
lprintf(stdout);
fprintf(stdout, " Institute : ");
......@@ -1436,15 +1436,15 @@ after_precntl(AfterControl &globs, struct Variable *vars)
{
int gridID, zaxisID, timeID;
vlistInqVar(globs.ivlistID, varID, &gridID, &zaxisID, &timeID);
const auto code = vlistInqVarCode(globs.ivlistID, varID);
auto code = vlistInqVarCode(globs.ivlistID, varID);
if (code <= 0 || code >= MaxCodes)
{
cdo_warning("Code number %d out of range, variable ignored!", code);
continue;
}
const auto gridtype = gridInqType(gridID);
const auto numlevel = zaxisInqSize(zaxisID);
const auto leveltype = zaxisInqType(zaxisID);
auto gridtype = gridInqType(gridID);
auto numlevel = zaxisInqSize(zaxisID);
auto leveltype = zaxisInqType(zaxisID);
vars[code].ivarID = varID;
vars[code].igridID = gridID;
......@@ -1485,8 +1485,8 @@ after_postcntl(const AfterControl &globs, struct Variable *vars)
for (int code = 0; code < MaxCodes; ++code)
if (vars[code].detected)
{
const auto gridID = vars[code].igridID;
const auto zaxisID = vars[code].izaxisID;
auto gridID = vars[code].igridID;
auto zaxisID = vars[code].izaxisID;
zaxisName(zaxisInqType(zaxisID), zaxistypename);
fprintf(stderr, " Detected Code %3d grid %-8s size %5zu level %2d %-8s\n", code, gridNamePtr(gridInqType(gridID)),
gridInqSize(gridID), zaxisInqSize(zaxisID), zaxistypename);
......@@ -1503,9 +1503,9 @@ after_postcntl(const AfterControl &globs, struct Variable *vars)
name[0] = 0;
longname[0] = 0;
units[0] = 0;
const auto ivarID = vars[code].ivarID;
const auto ogridID = vars[code].ogridID;
const auto ozaxisID = vars[code].ozaxisID;
auto ivarID = vars[code].ivarID;
auto ogridID = vars[code].ogridID;
auto ozaxisID = vars[code].ozaxisID;
if (ogridID == -1)
{
......@@ -1522,8 +1522,8 @@ after_postcntl(const AfterControl &globs, struct Variable *vars)
continue;
}
const auto instID = vlistInqVarInstitut(globs.ivlistID, ivarID);
const auto modelID = vlistInqVarModel(globs.ivlistID, ivarID);
auto instID = vlistInqVarInstitut(globs.ivlistID, ivarID);
auto modelID = vlistInqVarModel(globs.ivlistID, ivarID);
auto tableID = vlistInqVarTable(globs.ivlistID, ivarID);
vars[code].missval = vlistInqVarMissval(globs.ivlistID, ivarID);
......@@ -1545,7 +1545,7 @@ after_postcntl(const AfterControl &globs, struct Variable *vars)
if (globs.Mean != 2)
{
vlistDefTaxis(globs.ovlistID, globs.taxisID2);
const auto ovarID = vlistDefVar(globs.ovlistID, ogridID, ozaxisID, TIME_VARYING);
auto ovarID = vlistDefVar(globs.ovlistID, ogridID, ozaxisID, TIME_VARYING);
if (globs.Mean) vlistDefVarTsteptype(globs.ovlistID, ovarID, TSTEP_AVG);
vlistDefVarCode(globs.ovlistID, ovarID, code);
vars[code].ovarID = ovarID;
......@@ -1562,7 +1562,7 @@ after_postcntl(const AfterControl &globs, struct Variable *vars)
if (globs.Mean >= 2)
{
vlistDefTaxis(globs.ovlistID2, globs.taxisID2);
const auto ovarID2 = vlistDefVar(globs.ovlistID2, ogridID, ozaxisID, TIME_VARYING);
auto ovarID2 = vlistDefVar(globs.ovlistID2, ogridID, ozaxisID, TIME_VARYING);
if (globs.Mean) vlistDefVarTsteptype(globs.ovlistID2, ovarID2, TSTEP_AVG);
vlistDefVarCode(globs.ovlistID2, ovarID2, code);
vars[code].ovarID2 = ovarID2;
......@@ -1582,8 +1582,8 @@ after_postcntl(const AfterControl &globs, struct Variable *vars)
for (int code = 0; code < MaxCodes; ++code)
if (vars[code].selected)
{
const auto gridID = vars[code].ogridID;
const auto zaxisID = vars[code].ozaxisID;
auto gridID = vars[code].ogridID;
auto zaxisID = vars[code].ozaxisID;
zaxisName(zaxisInqType(zaxisID), zaxistypename);
fprintf(stderr, " Selected Code %3d grid %-8s size %5zu level %2d %-8s\n", code, gridNamePtr(gridInqType(gridID)),
gridInqSize(gridID), zaxisInqSize(zaxisID), zaxistypename);
......@@ -1626,25 +1626,6 @@ after_readVct(AfterControl &globs, const char *vctfile)
std::fclose(fp);
}
static void
after_control_init(AfterControl &globs)
{
globs.AnalysisData = 0; // 0 = ECHAM Data, 1 = ECMWF Spectral Analyses
globs.DayIn = 0; // day increment of infiles if Multi = true
globs.Debug = false;
globs.extrapolate = true;
globs.szip = false;
globs.istreamID = CDI_UNDEFID;
globs.ostreamID = CDO_STREAM_UNDEF;
globs.ostreamID2 = CDO_STREAM_UNDEF;
globs.ivlistID = CDI_UNDEFID;
globs.ovlistID = CDI_UNDEFID;
globs.ovlistID2 = CDI_UNDEFID;
globs.taxisID = -1;
globs.taxisID2 = -1;
}
static void
after_variable_init(struct Variable *vars)
{
......@@ -1787,18 +1768,6 @@ after_processing(AfterControl &globs, struct Variable *vars)
process_def_var_num(vlistNvars(globs.ivlistID));
streamClose(globs.istreamID);
if (globs.rcoslat) Free(globs.rcoslat);
if (globs.coslat) Free(globs.coslat);
if (globs.DerivationFactor) Free(globs.DerivationFactor);
if (globs.Field) Free(globs.Field);
if (globs.poli) Free(globs.poli);
if (globs.pold) Free(globs.pold);
if (globs.pdev) Free(globs.pdev);
if (globs.pol2) Free(globs.pol2);
if (globs.pol3) Free(globs.pol3);
}
class ModuleAfterburner
......@@ -1814,8 +1783,6 @@ public:
lstdout = !Options::silentMode;
after_control_init(globs);
globs.Verbose = Options::cdoVerbose;
if (cdo_operator_argc() == 1) after_readVct(globs, cdo_operator_argv(0).c_str());
......@@ -1826,7 +1793,7 @@ public:
if (CdoDefault::FileType != CDI_UNDEFID) ofiletype = CdoDefault::FileType;
const auto streamCnt = cdo_stream_cnt();
auto streamCnt = cdo_stream_cnt();
auto nfiles = streamCnt - 1;
ofileidx = nfiles;
......@@ -1843,11 +1810,13 @@ public:
for (int i = 0; i < globs.Nfiles; ++i) printf("files %d %s\n", i + 1, ifiles[i]);
}
}
void
run()
{
after_processing(globs, vars);
}
void
close()
{
......@@ -1866,5 +1835,6 @@ Afterburner(void *process)
afterburner.init(process);
afterburner.run();
afterburner.close();
return nullptr;
}
This diff is collapsed.
......@@ -78,6 +78,7 @@ public:
auto vlistID1 = cdo_stream_inq_vlist(streamID1);
auto vlistID2 = vlistDuplicate(vlistID1);
vlist_unpack(vlistID2);
taxisID1 = vlistInqTaxis(vlistID1);
taxisID2 = taxisDuplicate(taxisID1);
......@@ -92,6 +93,7 @@ public:
streamID2 = cdo_open_write(1);
cdo_def_vlist(streamID2, vlistID2);
}
void
run()
{
......@@ -120,13 +122,13 @@ public:
auto hasMissvals = (nmiss > 0 || dbl_is_equal(rc, missval));
// clang-format off
if (operFunc == FieldFunc_EQ) func_compc(hasMissvals, ngp, missval, vaIn, rcv, vaOut, binary_op_EQ);
else if (operFunc == FieldFunc_NE) func_compc(hasMissvals, ngp, missval, vaIn, rcv, vaOut, binary_op_NE);
else if (operFunc == FieldFunc_LE) func_compc(hasMissvals, ngp, missval, vaIn, rcv, vaOut, binary_op_LE);
else if (operFunc == FieldFunc_LT) func_compc(hasMissvals, ngp, missval, vaIn, rcv, vaOut, binary_op_LT);
else if (operFunc == FieldFunc_GE) func_compc(hasMissvals, ngp, missval, vaIn, rcv, vaOut, binary_op_GE);
else if (operFunc == FieldFunc_GT) func_compc(hasMissvals, ngp, missval, vaIn, rcv, vaOut, binary_op_GT);
else cdo_abort("Operator not implemented!");
if (operFunc == FieldFunc_EQ) func_compc(hasMissvals, ngp, missval, vaIn, rcv, vaOut, binary_op_EQ);
else if (operFunc == FieldFunc_NE) func_compc(hasMissvals, ngp, missval, vaIn, rcv, vaOut, binary_op_NE);
else if (operFunc == FieldFunc_LE) func_compc(hasMissvals, ngp, missval, vaIn, rcv, vaOut, binary_op_LE);
else if (operFunc == FieldFunc_LT) func_compc(hasMissvals, ngp, missval, vaIn, rcv, vaOut, binary_op_LT);
else if (operFunc == FieldFunc_GE) func_compc(hasMissvals, ngp, missval, vaIn, rcv, vaOut, binary_op_GE);
else if (operFunc == FieldFunc_GT) func_compc(hasMissvals, ngp, missval, vaIn, rcv, vaOut, binary_op_GT);
else cdo_abort("Operator not implemented!");
// clang-format on
nmiss = varray_num_mv(ngp, vaOut, missval);
......@@ -137,6 +139,7 @@ public:
tsID++;
}
}
void
close()
{
......@@ -154,6 +157,5 @@ Compc(void *process)
compc.init(process);
compc.run();
compc.close();
return nullptr;
}
......@@ -339,6 +339,7 @@ addWithFrequency(const std::vector<std::string> &params, const char *operatorNam
return opID;
}
#include <functional>
template <typename Request>
class EcaIndicies
......@@ -350,10 +351,10 @@ protected:
virtual void init(void *process) = 0;
public:
/* clang-format off */
// clang-format off
void run() { eca_func(request); }
void close() { cdo_finish(); }
/* clang-format on */
// clang-format on
};
class EcaIndicies1 : public EcaIndicies<ECA_REQUEST_1>
......@@ -361,16 +362,19 @@ class EcaIndicies1 : public EcaIndicies<ECA_REQUEST_1>
public:
EcaIndicies1() : EcaIndicies<ECA_REQUEST_1>(eca1) {}
};
class EcaIndicies2 : public EcaIndicies<ECA_REQUEST_2>
{
public:
EcaIndicies2() : EcaIndicies<ECA_REQUEST_2>(eca2) {}
};
class EcaIndicies3 : public EcaIndicies<ECA_REQUEST_3>
{
public:
EcaIndicies3() : EcaIndicies<ECA_REQUEST_3>(eca3) {}
};
class EcaIndicies4 : public EcaIndicies<ECA_REQUEST_4>
{
public:
......@@ -420,6 +424,7 @@ public:
request.var2.h3 = vfarnum;
}
};
void *
EcaCfd(void *process)
{
......@@ -477,6 +482,7 @@ public:
request.var2.h3 = vfarnum;
}
};
void *
EcaCsu(void *process)
{
......@@ -489,9 +495,9 @@ EcaCsu(void *process)
class ModuleEcaCwdi : public EcaIndicies2
{
int argN = 6;
double argT = 5.0;
char longname[sizeof(CWDI_LONGNAME) + 80];
public:
void
......@@ -516,7 +522,6 @@ public:
cdo_operator_add("eca_cwdi", 0, CMP_DATE, nullptr);
}
char longname[sizeof(CWDI_LONGNAME) + 80];
sprintf(longname, CWDI_LONGNAME, argN, argT);
request.var1.name = CWDI_NAME;
......@@ -537,6 +542,7 @@ public:
request.var2.h2 = vfarnum;
}
};
void *
EcaCwdi(void *process)
{
......@@ -550,6 +556,7 @@ EcaCwdi(void *process)
class ModuleEcaCwfi : public EcaIndicies2
{
int argN = 6;
char longname[sizeof(CWFI_LONGNAME) + 40];
public:
void
......@@ -573,11 +580,9 @@ public:
OPID_ETC = cdo_operator_add("etccdi_csdi", 0, CMP_YEAR, nullptr);
}
char longname[sizeof(CWFI_LONGNAME) + 40];
sprintf(longname, CWFI_LONGNAME, argN);
if (OPID_ECA == cdo_operator_id())
{
sprintf(longname, CWFI_LONGNAME, argN);
request.var1.name = CWFI_NAME;
request.var1.longname = longname;
request.var1.units = CWFI_UNITS;
......@@ -603,6 +608,7 @@ public:
request.var2.h2 = vfarnum;
}
};
void *
EcaCwfi(void *process)
{
......@@ -631,6 +637,7 @@ public:
request.f3 = field2_sub;
}
};
void *
EcaEtr(void *process)
{
......@@ -643,7 +650,6 @@ EcaEtr(void *process)
class ModuleEcaFd : public EcaIndicies1
{
public:
void
init(void *process)
......@@ -707,6 +713,7 @@ class ModuleEcaGsl : public EcaIndicies4
int argN = 6;
double argT = 5.0;
double minLandFraction = 0.5;
char longname[sizeof(GSL_LONGNAME) + 160];
public:
void
......@@ -719,7 +726,6 @@ public:
if (cdo_operator_argc() > 1) argT = parameter_to_double(cdo_operator_argv(1));
if (cdo_operator_argc() > 2) minLandFraction = parameter_to_double(cdo_operator_argv(2));
char longname[sizeof(GSL_LONGNAME) + 160];
sprintf(longname, GSL_LONGNAME, argN, argT, argN, argT);
request.name = GSL_NAME;
......@@ -737,6 +743,7 @@ public:
request.consecutiveDays = argN;
}
};
void *
EcaGsl(void *process)
{
......@@ -794,6 +801,7 @@ class ModuleEcaHwdi : public EcaIndicies2
{
int argN = 6;
double argT = 5.0;
char longname[sizeof(HWDI_LONGNAME) + 80];
public:
void
......@@ -816,7 +824,6 @@ public:
cdo_operator_add("eca_hwdi", 0, CMP_DATE, nullptr);
}
char longname[sizeof(HWDI_LONGNAME) + 80];
sprintf(longname, HWDI_LONGNAME, argN, argT);
request.var1.name = HWDI_NAME;
......@@ -837,6 +844,7 @@ public:
request.var2.h2 = vfarnum;
}
};
void *
EcaHwdi(void *process)
{
......@@ -850,6 +858,7 @@ EcaHwdi(void *process)
class ModuleEcaHwfi : public EcaIndicies2
{
int argN = 6;
char longname[sizeof(HWFI_LONGNAME) + 40];
public:
void
......@@ -873,11 +882,9 @@ public:
OPID_ETC = cdo_operator_add("etccdi_wsdi", 0, CMP_YEAR, nullptr);
}
char longname[sizeof(HWFI_LONGNAME) + 40];
sprintf(longname, HWFI_LONGNAME, argN);
if (OPID_ECA == cdo_operator_id())
{
sprintf(longname, HWFI_LONGNAME, argN);
request.var1.name = HWFI_NAME;
request.var1.longname = longname;
request.var1.units = HWFI_UNITS;
......@@ -903,6 +910,7 @@ public:
request.var2.h2 = vfarnum;
}
};
void *
EcaHwfi(void *process)
{
......@@ -962,9 +970,11 @@ EcaId(void *process)
ecaId.close();
return nullptr;
}
class ModuleEcaSu : public EcaIndicies1
{
double argT = 25.0;
char longname[sizeof(SU_LONGNAME) + 40];
public:
void
......@@ -987,11 +997,9 @@ public:
OPID_ETC = cdo_operator_add("etccdi_su", 0, CMP_YEAR, nullptr);
}
char longname[sizeof(SU_LONGNAME) + 40];
sprintf(longname, SU_LONGNAME, argT);
if (OPID_ECA == cdo_operator_id())
{
sprintf(longname, SU_LONGNAME, argT);
request.var1.name = SU_NAME;
request.var1.longname = longname;
request.var1.refdate = ECA_refdate;
......@@ -1069,6 +1077,7 @@ public:
request.var1.epilog = PERCENT_OF_TIME;
}
};
void *
EcaTg90p(void *process)
{
......@@ -1127,6 +1136,7 @@ public:
request.var1.epilog = PERCENT_OF_TIME;
}
};
void *
EcaTn90p(void *process)
{
......@@ -1140,6 +1150,7 @@ EcaTn90p(void *process)
class ModuleEcaTr : public EcaIndicies1
{
double argT = 20.0;
char longname[1024];
public:
void
......@@ -1162,13 +1173,11 @@ public:
OPID_ETC = cdo_operator_add("etccdi_tr", 0, CMP_YEAR, nullptr);
}
char tr_longname[1024];
sprintf(tr_longname, TR_LONGNAME, argT);
if (OPID_ECA == cdo_operator_id())
{
sprintf(longname, TR_LONGNAME, argT);
request.var1.name = TR_NAME;
request.var1.longname = tr_longname;
request.var1.longname = longname;
request.var1.units = TR_UNITS;
request.var1.refdate = ECA_refdate;
}
......@@ -1215,6 +1224,7 @@ public:
request.var1.epilog = PERCENT_OF_TIME;
}
};
void *
EcaTx10p(void *process)
{
......@@ -1255,6 +1265,7 @@ public:
request.var1.epilog = PERCENT_OF_TIME;
}
};
void *
EcaTx90p(void *process)
{
......@@ -1271,6 +1282,9 @@ class ModuleEcaCdd : public EcaIndicies1
{
double threshold = 1;
int ndays = 5;
char cdd_longname[1024];
char cdd_longname2[1024];
char cdd_name2[1024];
public:
void
......@@ -1301,9 +1315,6 @@ public:
OPID_ETC = cdo_operator_add("etccdi_cdd", 0, CMP_YEAR, nullptr);
}
char cdd_longname[1024];
char cdd_longname2[1024];
char cdd_name2[1024];
sprintf(cdd_longname, CDD_LONGNAME, threshold);
sprintf(cdd_longname2, CDD_LONGNAME2, ndays);
sprintf(cdd_name2, CDD_NAME2, ndays);
......@@ -1335,6 +1346,7 @@ public:
request.var2.h3 = vfarnum;
}
};
void *
EcaCdd(void *process)
{
......@@ -1349,6 +1361,9 @@ class ModuleEcaCwd : public EcaIndicies1
{
double threshold = 1;
int ndays = 5;
char cwd_longname[1024];
char cwd_longname2[1024];
char cwd_name2[1024];
public:
void
......@@ -1380,9 +1395,6 @@ public:
OPID_ETC = cdo_operator_add("etccdi_cwd", 0, CMP_YEAR, nullptr);
}
char cwd_longname[1024];
char cwd_longname2[1024];
char cwd_name2[1024];
sprintf(cwd_longname, CWD_LONGNAME, threshold);
sprintf(cwd_longname2, CWD_LONGNAME2, ndays);
sprintf(cwd_name2, CWD_NAME2, ndays);
......@@ -1413,6 +1425,7 @@ public:
request.var2.h3 = vfarnum;
}
};
void *
EcaCwd(void *process)
{
......@@ -1447,23 +1460,23 @@ public:
if (kv && kv->nvalues > 0)
{
// clang-format off
if (kv->values[0] == "month") datelenOp = CMP_MONTH;
else if (kv->values[0] == "year") datelenOp = CMP_YEAR;
if (kv->values[0] == "month") datelenOp = CMP_MONTH;
else if (kv->values[0] == "year") datelenOp = CMP_YEAR;
// clang-format on
}
}
}
// clang-format off
const auto ECA_PD = cdo_operator_add("eca_pd", 0, datelenOp, nullptr);
const auto ETCCDI_PD = cdo_operator_add("etccdi_r1mm", 0, datelenOp, nullptr);
const auto ECA_R10MM = cdo_operator_add("eca_r10mm", 0, datelenOp, nullptr);
const auto ETCCDI_R10MM = cdo_operator_add("etccdi_r10mm", 0, datelenOp, nullptr);
const auto ECA_R20MM = cdo_operator_add("eca_r20mm", 0, datelenOp, nullptr);
const auto ETCCDI_R20MM = cdo_operator_add("etccdi_r20mm", 0, datelenOp, nullptr);
auto ECA_PD = cdo_operator_add("eca_pd", 0, datelenOp, nullptr);
auto ETCCDI_PD = cdo_operator_add("etccdi_r1mm", 0, datelenOp, nullptr);
auto ECA_R10MM = cdo_operator_add("eca_r10mm", 0, datelenOp, nullptr);
auto ETCCDI_R10MM = cdo_operator_add("etccdi_r10mm", 0, datelenOp, nullptr);
auto ECA_R20MM = cdo_operator_add("eca_r20mm", 0, datelenOp, nullptr);
auto ETCCDI_R20MM = cdo_operator_add("etccdi_r20mm", 0, datelenOp, nullptr);
// clang-format on
const auto operatorID = cdo_operator_id();
auto operatorID = cdo_operator_id();
if (operatorID == ECA_PD || operatorID == ETCCDI_PD)
{
......@@ -1563,6 +1576,7 @@ public:
request.var1.epilog = PERCENT_OF_TIME;
}
};
void *
EcaR75p(void *process)
{
......@@ -1654,6 +1668,7 @@ public:
request.var1.epilog = PERCENT_OF_TIME;
}
};
void *
EcaR95p(void *process)
{
......@@ -1820,6 +1835,8 @@ EcaR99ptot(void *process)
class ModuleEcaRr1 : public EcaIndicies1
{
char longname[1024];
public:
void
init(void *process)
......@@ -1842,11 +1859,10 @@ public:
cdo_operator_add("eca_rr1", 0, CMP_DATE, nullptr);
}
char lnamebuffer[1024];
sprintf(lnamebuffer, RR1_LONGNAME, threshold);
sprintf(longname, RR1_LONGNAME, threshold);
request.var1.name = RR1_NAME;
request.var1.longname = lnamebuffer;
request.var1.longname = longname;
request.var1.units = RR1_UNITS;
request.var1.f1 = vfarselgec;
request.var1.f1arg = threshold;
......@@ -1916,6 +1932,8 @@ EcaRx1day(void *process)
class ModuleEcaRx5day : public EcaIndicies1
{
char longname2[sizeof(RX5DAY_LONGNAME2) + 40];
public:
void
init(void *process)
......@@ -1947,8 +1965,7 @@ public:
OPID_ETC = cdo_operator_add("etccdi_rx5day", 0, CMP_YEAR, nullptr);
}
char longname[sizeof(RX5DAY_LONGNAME2) + 40];
sprintf(longname, RX5DAY_LONGNAME2, argX);
sprintf(longname2, RX5DAY_LONGNAME2, argX);
if (OPID_ECA == cdo_operator_id())
{
......@@ -1966,7 +1983,7 @@ public:
}
request.var1.f2 = field2_max;
request.var2.name = RX5DAY_NAME2;
request.var2.longname = longname;
request.var2.longname = longname2;
request.var2.units = RX5DAY_UNITS2;
request.var2.h1 = vfarselgec;
request.var2.h1arg = argX;
......@@ -1986,7 +2003,7 @@ EcaRx5day(void *process)
class ModuleEcaSdii : public EcaIndicies1
{
char lnamebuffer[1024];
char longname[1024];
double threshold = 1;
public:
......@@ -1996,9 +2013,9 @@ public:
cdo_initialize(process);
int OPID_ECA = 0, OPID_ETC = 0;
if (cdo_operator_argc() > 2)
cdo_abort("Too many arguments!");
else if (cdo_operator_argc() > 1)
if (cdo_operator_argc() > 2) cdo_abort("Too many arguments!");
if (cdo_operator_argc() > 1)
{
auto params = cdo_get_oper_argv();
params = std::vector<std::string>(params.begin() + 1, params.end());
......@@ -2012,11 +2029,11 @@ public:
if (cdo_operator_argc() == 1) threshold = parameter_to_double(cdo_operator_argv(0));
}
sprintf(lnamebuffer, SDII_LONGNAME, threshold);
if (OPID_ECA == cdo_operator_id())
{
sprintf(longname, SDII_LONGNAME, threshold);
request.var1.name = SDII_NAME;
request.var1.longname = lnamebuffer;
request.var1.longname = longname;
request.var1.units = SDII_UNITS;
}
else if (OPID_ETC == cdo_operator_id())
......@@ -2032,6 +2049,7 @@ public:
request.var1.epilog = MEAN;
}
};
void *
EcaSdii(void *process)
{
......@@ -2063,6 +2081,7 @@ public:
request.var1.f4 = vfarnum;
}
};
void *
Fdns(void *process)
{
......@@ -2076,6 +2095,7 @@ Fdns(void *process)
class ModuleStrwin : public EcaIndicies1
{
double maxWind = 10.5;
char longname[sizeof(STRWIN_LONGNAME) + 40];
public:
void
......@@ -2097,7 +2117,6 @@ public:
cdo_operator_add("strwin", 0, CMP_DATE, nullptr);
}
char longname[sizeof(STRWIN_LONGNAME) + 40];
sprintf(longname, STRWIN_LONGNAME, maxWind);
request.var1.name = STRWIN_NAME;
......@@ -2116,6 +2135,7 @@ public:
request.var2.h3 = field2_max;
}
};
void *
Strwin(void *process)
{
......@@ -2159,6 +2179,7 @@ public:
request.var2.h3 = field2_max;
}
};
void *
Strbre(void *process)
{
......@@ -2245,6 +2266,7 @@ public:
request.var2.h3 = field2_max;
}
};
void *
Hurr(void *process)
{
......@@ -2252,5 +2274,5 @@ Hurr(void *process)
hurr.init(process);
hurr.run();
hurr.close();
return 0;
return nullptr;
}
......@@ -36,6 +36,7 @@
#include "cdo_zaxis.h"
#include "cdi_lockedIO.h"
#include "util_string.h"
#include "datetime.h"
void gridcell_areas(int gridID, Varray<double> &array);
int get_surface_ID(int vlistID); // from Vertstat.cc
......@@ -320,6 +321,10 @@ set_date_and_time(ParamEntry &varts, int calendar, int tsID, const CdiDateTime &
varts.data[CoordIndex::SECOND] = second;
varts.data[CoordIndex::MINUTE] = minute;
varts.data[CoordIndex::HOUR] = hour;
varts.data[CoordIndex::CALENDAR] = calendar;
varts.data[CoordIndex::DOY] = day_of_year(calendar, cdiDate_get(vDateTime.date));
varts.data[CoordIndex::DPY] = days_per_year(calendar, year);
}
static void
......
......@@ -126,46 +126,65 @@ check_radius_range(double radius, const char *name)
if (radius < 0.0 || radius > 180.0) cdo_abort("%s=%g out of bounds (0-180 deg)!", name, radius);
}
void *
Getgridcell(void *process)
class ModuleGetgridcell
{
cdo_initialize(process);
CdoStreamID streamID1;
int gridID1;
GridPoint gridPoint;
cdo_operator_add("gridcellindex", 0, 0, "lon/lat coordinate of a single cell");
public:
void
init(void *process)
{
cdo_initialize(process);
auto gridPoint = get_parameter();
cdo_operator_add("gridcellindex", 0, 0, "lon/lat coordinate of a single cell");
check_radius_range(gridPoint.radius, "radius");
check_radius_range(gridPoint.arc_radius, "arc_radius");
gridPoint = get_parameter();
if (Options::cdoVerbose) print_parameter(gridPoint);
check_radius_range(gridPoint.radius, "radius");
check_radius_range(gridPoint.arc_radius, "arc_radius");
auto streamID1 = cdo_open_read(0);
if (Options::cdoVerbose) print_parameter(gridPoint);
auto vlistID1 = cdo_stream_inq_vlist(streamID1);
streamID1 = cdo_open_read(0);
auto ngrids = vlistNgrids(vlistID1);
if (ngrids != 1) cdo_abort("Too many different grids!");
auto vlistID1 = cdo_stream_inq_vlist(streamID1);
auto gridID1 = vlistGrid(vlistID1, 0);
auto ngrids = vlistNgrids(vlistID1);
if (ngrids != 1) cdo_abort("Too many different grids!");
int64_t cellIdx = -1;
gridID1 = vlistGrid(vlistID1, 0);
}
void
run()
{
int64_t cellIdx = -1;
if (is_healpix_grid(gridID1))
{
auto [nside, order] = cdo::get_healpix_params(gridID1);
cellIdx = hp_lonlat_to_index(order, nside, DEG2RAD * gridPoint.lon, DEG2RAD * gridPoint.lat);
}
else { cellIdx = lonlat_to_index(gridID1, gridPoint); }
if (is_healpix_grid(gridID1))
{
auto [nside, order] = cdo::get_healpix_params(gridID1);
cellIdx = hp_lonlat_to_index(order, nside, DEG2RAD * gridPoint.lon, DEG2RAD * gridPoint.lat);
}
else
{
cellIdx = lonlat_to_index(gridID1, gridPoint);
}
printf("%ld\n", (long)cellIdx + 1);
printf("%ld\n", (long) cellIdx + 1);
}
void
close()
{
cdo_stream_close(streamID1);
cdo_stream_close(streamID1);
cdo_finish();
}
};
cdo_finish();
void *
Getgridcell(void *process)
{
ModuleGetgridcell getgridcell;
getgridcell.init(process);
getgridcell.run();
getgridcell.close();
return nullptr;
}
......@@ -21,12 +21,6 @@
#include <mpim_grid.h>
#include "constants.h"
static inline double
orthodrome(double px1, double py1, double px2, double py2)
{
return std::acos(std::sin(py1) * std::sin(py2) + std::cos(py1) * std::cos(py2) * std::cos(px2 - px1));
}
double gridGetPlanetRadius(int gridID);
double
......@@ -272,6 +266,7 @@ public:
gridsize = gridInqSize(gridID);
array = Varray<double>(gridsize);
}
void
run()
{
......@@ -310,6 +305,7 @@ public:
cdo_def_record(streamID2, 0, 0);
cdo_write_record(streamID2, &array[0], 0);
}
void
close()
{
......@@ -319,14 +315,13 @@ public:
cdo_finish();
}
};
void *
Gridcell(void *process)
{
ModuleGridcell gridcell;
gridcell.init(process);
gridcell.run();
gridcell.close();
return nullptr;
}
......@@ -294,86 +294,120 @@ hp_define_grid(int gridID1, HealpixParams &params)
return gridIDout;
}
void *
Healpix(void *process)
class ModuleHealpix
{
cdo_initialize(process);
CdoStreamID streamID1;
int taxisID1;
CdoStreamID streamID2;
int taxisID2;
int vlistID2;
bool doDegrade;
Field field1;
Field field2;
// clang-format off
HealpixParams params;
VarList varList1;
VarList varList2;
public:
void
init(void *process)
{
cdo_initialize(process);
// clang-format off
cdo_operator_add("hpupgrade", 0, 0, nullptr);
auto HPDEGRADE = cdo_operator_add("hpdegrade", 0, 0, nullptr);
// clang-format on
auto operatorID = cdo_operator_id();
auto doDegrade = (operatorID == HPDEGRADE);
// clang-format on
auto params = get_parameter();
params.doDegrade = doDegrade;
verify_parameter(params);
auto operatorID = cdo_operator_id();
doDegrade = (operatorID == HPDEGRADE);
auto streamID1 = cdo_open_read(0);
auto vlistID1 = cdo_stream_inq_vlist(streamID1);
auto taxisID1 = vlistInqTaxis(vlistID1);
params = get_parameter();
params.doDegrade = doDegrade;
verify_parameter(params);
auto ngrids = vlistNgrids(vlistID1);
if (ngrids > 1) cdo_abort("Too many different grids!");
streamID1 = cdo_open_read(0);
auto vlistID1 = cdo_stream_inq_vlist(streamID1);
taxisID1 = vlistInqTaxis(vlistID1);
auto gridID = vlistGrid(vlistID1, 0);
if (!is_healpix_grid(gridID)) cdo_abort("Input grid is not healpix!");
auto ngrids = vlistNgrids(vlistID1);
if (ngrids > 1) cdo_abort("Too many different grids!");
auto vlistID2 = vlistDuplicate(vlistID1);
auto taxisID2 = taxisDuplicate(taxisID1);
vlistDefTaxis(vlistID2, taxisID2);
auto gridID = vlistGrid(vlistID1, 0);
if (!is_healpix_grid(gridID)) cdo_abort("Input grid is not healpix!");
auto gridID2 = hp_define_grid(gridID, params);
for (int index = 0; index < ngrids; ++index) vlistChangeGridIndex(vlistID2, index, gridID2);
vlistID2 = vlistDuplicate(vlistID1);
taxisID2 = taxisDuplicate(taxisID1);
vlistDefTaxis(vlistID2, taxisID2);
VarList varList1, varList2;
varListInit(varList1, vlistID1);
varListInit(varList2, vlistID2);
auto gridID2 = hp_define_grid(gridID, params);
for (int index = 0; index < ngrids; ++index) vlistChangeGridIndex(vlistID2, index, gridID2);
auto streamID2 = cdo_open_write(1);
cdo_def_vlist(streamID2, vlistID2);
varListInit(varList1, vlistID1);
varListInit(varList2, vlistID2);
Field field1, field2;
streamID2 = cdo_open_write(1);
cdo_def_vlist(streamID2, vlistID2);
}
void
run()
{
int tsID1 = 0;
while (true)
{
auto nrecs = cdo_stream_inq_timestep(streamID1, tsID1);
if (nrecs == 0) break;
int tsID1 = 0;
while (true)
{
auto nrecs = cdo_stream_inq_timestep(streamID1, tsID1);
if (nrecs == 0) break;
cdo_taxis_copy_timestep(taxisID2, taxisID1);
cdo_def_timestep(streamID2, tsID1);
cdo_taxis_copy_timestep(taxisID2, taxisID1);
cdo_def_timestep(streamID2, tsID1);
for (int recID = 0; recID < nrecs; ++recID)
{
int varID, levelID;
cdo_inq_record(streamID1, &varID, &levelID);
field1.init(varList1[varID]);
cdo_read_record(streamID1, field1);
for (int recID = 0; recID < nrecs; ++recID)
{
int varID, levelID;
cdo_inq_record(streamID1, &varID, &levelID);
field1.init(varList1[varID]);
cdo_read_record(streamID1, field1);
field2.init(varList2[varID]);
field2.init(varList2[varID]);
if (params.orderIn == HpOrder::Ring) ring_to_nested(field1, params.nsideIn);
if (params.orderIn == HpOrder::Ring) ring_to_nested(field1, params.nsideIn);
doDegrade ? hp_degrade(field1, field2, params) : hp_upgrade(field1, field2, params);
doDegrade ? hp_degrade(field1, field2, params) : hp_upgrade(field1, field2, params);
if (params.orderOut == HpOrder::Ring) nested_to_ring(field2, params.nsideOut);
if (params.orderOut == HpOrder::Ring) nested_to_ring(field2, params.nsideOut);
cdo_def_record(streamID2, varID, levelID);
cdo_write_record(streamID2, field2);
}
cdo_def_record(streamID2, varID, levelID);
cdo_write_record(streamID2, field2);
}
tsID1++;
}
}
void
close()
{
tsID1++;
}
cdo_stream_close(streamID1);
cdo_stream_close(streamID2);
cdo_stream_close(streamID1);
cdo_stream_close(streamID2);
vlistDestroy(vlistID2);
vlistDestroy(vlistID2);
cdo_finish();
}
};
cdo_finish();
void *
Healpix(void *process)
{
ModuleHealpix healpix;
healpix.init(process);
healpix.run();
healpix.close();
return nullptr;
}
......@@ -89,102 +89,124 @@ compute_stat_real(const Field &field, LonginfoStat &infostat, size_t gridsize)
return imiss;
}
void *
Longinfo(void *process)
class ModuleLonginfo
{
char paramstr[32];
CdoStreamID streamID;
cdo_initialize(process);
// clang-format off
cdo_operator_add("linfo", 0, 0, nullptr);
// clang-format on
operator_check_argc(0);
auto streamID = cdo_open_read(0);
auto vlistID = cdo_stream_inq_vlist(streamID);
auto taxisID = vlistInqTaxis(vlistID);
int taxisID;
int vlistID;
VarList varList;
varListInit(varList, vlistID);
Field field;
int tsID = 0;
while (true)
{
auto nrecs = cdo_stream_inq_timestep(streamID, tsID);
if (nrecs == 0) break;
fprintf(stdout, "timestep: %d\n", tsID + 1);
auto vDateTime = taxisInqVdatetime(taxisID);
fprintf(stdout, "\tdateTime: %s\n\n", datetime_to_string(vDateTime).c_str());
for (int recID = 0; recID < nrecs; ++recID)
{
fprintf(stdout, "\tfield: %d of %d\n", recID + 1, nrecs);
int varID, levelID;
cdo_inq_record(streamID, &varID, &levelID);
const auto &var = varList[varID];
auto dig = (var.datatype == CDI_DATATYPE_FLT64) ? Options::CDO_dbl_digits : Options::CDO_flt_digits;
fprintf(stdout, "\t\tvarIndex: %d\n", varID + 1);
fprintf(stdout, "\t\tlevelIndex: %d\n", levelID + 1);
fprintf(stdout, "\t\tlevel: %.*g\n", dig, cdo_zaxis_inq_level(var.zaxisID, levelID));
fprintf(stdout, "\t\tname: %s\n", var.name.c_str());
if (var.longname.size()) fprintf(stdout, "\t\tlongname: \"%s\"\n", var.longname.c_str());
if (var.units.size()) fprintf(stdout, "\t\tunits: \"%s\"\n", var.units.c_str());
cdiParamToString(var.param, paramstr, sizeof(paramstr));
if (paramstr[0] && paramstr[0] != '-') fprintf(stdout, "\t\tparam: %s\n", paramstr);
field.init(var);
cdo_read_record(streamID, field);
auto nmiss = field.nmiss;
LonginfoStat infostat;
fprintf(stdout, "\t\tdataType: %s\n", cdo::datatype_to_cstr(var.datatype));
fprintf(stdout, "\t\tmemoryType: %s\n", (var.memType == MemType::Float) ? "float" : "double");
fprintf(stdout, "\t\tgridsize: %zu\n", var.gridsize);
fprintf(stdout, "\t\tnumMiss: %zu\n", nmiss);
fprintf(stdout, "\t\tmissval: %.*g\n", dig, var.missval);
double addoffset = 0.0, scalefactor = 1.0;
auto haveAddoffset = (cdiInqKeyFloat(vlistID, varID, CDI_KEY_ADDOFFSET, &addoffset) == CDI_NOERR);
auto haveScalefactor = (cdiInqKeyFloat(vlistID, varID, CDI_KEY_SCALEFACTOR, &scalefactor) == CDI_NOERR);
if (haveAddoffset) fprintf(stdout, "\t\taddoffset: %.*g\n", dig, addoffset);
if (haveScalefactor) fprintf(stdout, "\t\tscalefactor: %.*g\n", dig, scalefactor);
auto imiss = compute_stat_real(field, infostat, var.gridsize);
if (infostat.nvals > 1)
{
fprintf(stdout, "\t\trange: %.*g\n", dig, infostat.max - infostat.min);
fprintf(stdout, "\t\tminimum: %.*g\n", dig, infostat.min);
fprintf(stdout, "\t\tmaximum: %.*g\n", dig, infostat.max);
fprintf(stdout, "\t\taverage: %.*g\n", dig, infostat.sum / infostat.nvals);
fprintf(stdout, "\t\tmedian: %.*g\n", dig, field_median(field));
fprintf(stdout, "\t\tstandardDev: %.*g\n", dig, field_std1(field));
fprintf(stdout, "\t\tskewness: %.*g\n", dig, field_skew(field));
fprintf(stdout, "\t\tkurtosis: %.*g\n", dig, field_kurt(field));
}
else if (infostat.nvals == 1) { fprintf(stdout, "\t\tvalue: %g\n", infostat.sum); }
cdoPrintAttributes(stdout, vlistID, varID, 16);
}
// if (imiss != nmiss && nmiss) cdo_warning("Found %zu of %zu missing values!", imiss, nmiss);
tsID++;
}
cdo_stream_close(streamID);
public:
void
init(void *process)
{
cdo_initialize(process);
cdo_finish();
// clang-format off
cdo_operator_add("linfo", 0, 0, nullptr);
// clang-format on
operator_check_argc(0);
streamID = cdo_open_read(0);
vlistID = cdo_stream_inq_vlist(streamID);
taxisID = vlistInqTaxis(vlistID);
varListInit(varList, vlistID);
}
void
run()
{
int tsID = 0;
while (true)
{
auto nrecs = cdo_stream_inq_timestep(streamID, tsID);
if (nrecs == 0) break;
fprintf(stdout, "timestep: %d\n", tsID + 1);
auto vDateTime = taxisInqVdatetime(taxisID);
fprintf(stdout, "\tdateTime: %s\n\n", datetime_to_string(vDateTime).c_str());
for (int recID = 0; recID < nrecs; ++recID)
{
fprintf(stdout, "\tfield: %d of %d\n", recID + 1, nrecs);
int varID, levelID;
cdo_inq_record(streamID, &varID, &levelID);
const auto &var = varList[varID];
auto dig = (var.datatype == CDI_DATATYPE_FLT64) ? Options::CDO_dbl_digits : Options::CDO_flt_digits;
fprintf(stdout, "\t\tvarIndex: %d\n", varID + 1);
fprintf(stdout, "\t\tlevelIndex: %d\n", levelID + 1);
fprintf(stdout, "\t\tlevel: %.*g\n", dig, cdo_zaxis_inq_level(var.zaxisID, levelID));
fprintf(stdout, "\t\tname: %s\n", var.name.c_str());
if (var.longname.size()) fprintf(stdout, "\t\tlongname: \"%s\"\n", var.longname.c_str());
if (var.units.size()) fprintf(stdout, "\t\tunits: \"%s\"\n", var.units.c_str());
cdiParamToString(var.param, paramstr, sizeof(paramstr));
if (paramstr[0] && paramstr[0] != '-') fprintf(stdout, "\t\tparam: %s\n", paramstr);
field.init(var);
cdo_read_record(streamID, field);
auto nmiss = field.nmiss;
LonginfoStat infostat;
fprintf(stdout, "\t\tdataType: %s\n", cdo::datatype_to_cstr(var.datatype));
fprintf(stdout, "\t\tmemoryType: %s\n", (var.memType == MemType::Float) ? "float" : "double");
fprintf(stdout, "\t\tgridsize: %zu\n", var.gridsize);
fprintf(stdout, "\t\tnumMiss: %zu\n", nmiss);
fprintf(stdout, "\t\tmissval: %.*g\n", dig, var.missval);
double addoffset = 0.0, scalefactor = 1.0;
auto haveAddoffset = (cdiInqKeyFloat(vlistID, varID, CDI_KEY_ADDOFFSET, &addoffset) == CDI_NOERR);
auto haveScalefactor = (cdiInqKeyFloat(vlistID, varID, CDI_KEY_SCALEFACTOR, &scalefactor) == CDI_NOERR);
if (haveAddoffset) fprintf(stdout, "\t\taddoffset: %.*g\n", dig, addoffset);
if (haveScalefactor) fprintf(stdout, "\t\tscalefactor: %.*g\n", dig, scalefactor);
auto imiss = compute_stat_real(field, infostat, var.gridsize);
if (infostat.nvals > 1)
{
fprintf(stdout, "\t\trange: %.*g\n", dig, infostat.max - infostat.min);
fprintf(stdout, "\t\tminimum: %.*g\n", dig, infostat.min);
fprintf(stdout, "\t\tmaximum: %.*g\n", dig, infostat.max);
fprintf(stdout, "\t\taverage: %.*g\n", dig, infostat.sum / infostat.nvals);
fprintf(stdout, "\t\tmedian: %.*g\n", dig, field_median(field));
fprintf(stdout, "\t\tstandardDev: %.*g\n", dig, field_std1(field));
fprintf(stdout, "\t\tskewness: %.*g\n", dig, field_skew(field));
fprintf(stdout, "\t\tkurtosis: %.*g\n", dig, field_kurt(field));
}
else if (infostat.nvals == 1) { fprintf(stdout, "\t\tvalue: %g\n", infostat.sum); }
cdoPrintAttributes(stdout, vlistID, varID, 16);
}
// if (imiss != nmiss && nmiss) cdo_warning("Found %zu of %zu missing values!", imiss, nmiss);
tsID++;
}
}
void
close()
{
cdo_stream_close(streamID);
cdo_finish();
}
};
void *
Longinfo(void *process)
{
ModuleLonginfo longinfo;
longinfo.init(process);
longinfo.run();
longinfo.close();
return nullptr;
}
......@@ -454,7 +454,6 @@ cdo_SOURCES += Adisit.cc \
Splittime.cc \
Splityear.cc \
Tee.cc \
Templates.cc \
Test.cc \
Tests.cc \
Timcount.cc \
......
......@@ -198,7 +198,7 @@ class ModuleMrotuv
double missval2;
int nlevs;
int gridsize;
size_t gridsize;
size_t nlon;
size_t nlat;
......
......@@ -26,7 +26,7 @@
#include "field_functions.h"
static int
get_type_values(const int datatype, double &tmin, double &tmax, double &tmv)
get_type_values(int datatype, double &tmin, double &tmax, double &tmv)
{
int status = 0;
......@@ -47,7 +47,7 @@ get_type_values(const int datatype, double &tmin, double &tmax, double &tmv)
}
static int
compute_scale_and_offset(const int datatype, const double fmin, const double fmax, double &scaleFactor, double &addOffset)
compute_scale_and_offset(int datatype, double fmin, double fmax, double &scaleFactor, double &addOffset)
{
scaleFactor = 1.0;
addOffset = 0.0;
......@@ -78,7 +78,7 @@ field_min_max(Field &field)
}
static void
fieldChangeMissval(Field &field, double missval1, double missval2)
field_change_missval(Field &field, double missval1, double missval2)
{
auto len = field.size;
......@@ -118,7 +118,6 @@ public:
void
init(void *process)
{
cdo_initialize(process);
operator_check_argc(0);
......@@ -132,12 +131,25 @@ public:
taxisID2 = taxisDuplicate(taxisID1);
vlistDefTaxis(vlistID2, taxisID2);
streamID2 = cdo_open_write(1);
varListInit(varList, vlistID1);
nvars = vlistNvars(vlistID1);
streamID2 = cdo_open_write(1);
if (CdoDefault::DataType != CDI_UNDEFID)
{
// 32-bit float routing error with CDI_DATATYPE_INT32|CDI_DATATYPE_UINT32
if (CdoDefault::DataType == CDI_DATATYPE_FLT64 || CdoDefault::DataType == CDI_DATATYPE_FLT32 ||
CdoDefault::DataType == CDI_DATATYPE_INT32 || CdoDefault::DataType == CDI_DATATYPE_UINT32)
{
cdo_warning("Changed default output datatype to int16");
CdoDefault::DataType = datatype;
}
else { datatype = CdoDefault::DataType; }
}
}
void
run()
{
......@@ -168,17 +180,6 @@ public:
auto nts = tsID;
if (CdoDefault::DataType != CDI_UNDEFID)
{
if (CdoDefault::DataType == CDI_DATATYPE_FLT64 || CdoDefault::DataType == CDI_DATATYPE_FLT32)
{
cdo_warning("Changed default output datatype to int16");
CdoDefault::DataType = datatype;
}
else { datatype = CdoDefault::DataType; }
}
CdoDefault::DataType = datatype;
constexpr double undefValue = 1.0e300;
for (int varID = 0; varID < nvars; ++varID)
......@@ -229,7 +230,7 @@ public:
if (t > 0 && var.isConstant) continue;
auto &field = vars[t][varID][levelID];
if (field.nmiss) fieldChangeMissval(field, var.missval, missval2);
if (field.nmiss) field_change_missval(field, var.missval, missval2);
}
}
}
......@@ -237,10 +238,10 @@ public:
if (hasValidData)
{
auto memTypeIsFloat = (var.memType == MemType::Float);
double scaleFactor, addOffset;
if (!compute_scale_and_offset(datatype, fmin, fmax, scaleFactor, addOffset))
{
auto memTypeIsFloat = (var.memType == MemType::Float);
cdiDefKeyFloat(vlistID2, varID, CDI_KEY_ADDOFFSET, memTypeIsFloat ? (float) addOffset : addOffset);
cdiDefKeyFloat(vlistID2, varID, CDI_KEY_SCALEFACTOR, memTypeIsFloat ? (float) scaleFactor : scaleFactor);
}
......@@ -270,12 +271,15 @@ public:
}
}
}
void
close()
{
cdo_stream_close(streamID2);
cdo_stream_close(streamID1);
vlistDestroy(vlistID2);
cdo_finish();
}
};
......@@ -287,5 +291,6 @@ Pack(void *process)
pack.init(process);
pack.run();
pack.close();
return nullptr;
}
This diff is collapsed.
......@@ -511,13 +511,13 @@ remap_kernel(int operfunc, const Varray<size_t> &adds, size_t &nmiss2, Field &fi
{
auto v1 = vec1[adds[k]];
fieldvec[k] = v1;
if (DBL_IS_EQUAL(v1, missval)) field.nmiss++;
if (dbl_is_equal(v1, missval)) field.nmiss++;
}
field.size = nvalues;
field.missval = missval;
value = field_function(field, operfunc);
if (DBL_IS_EQUAL(value, missval)) nmiss2++;
if (dbl_is_equal(value, missval)) nmiss2++;
}
else
{
......
......@@ -45,181 +45,220 @@ add_operators(void)
// clang-format on
}
void *
Remapweights(void *argument)
class ModuleRemapweights
{
RemapSwitches remapSwitches;
int numNeighbors = 0;
cdo_initialize(argument);
CdoStreamID streamID1;
int vlistID1;
int gridID2;
add_operators();
Field field1;
auto operatorID = cdo_operator_id();
auto operfunc = cdo_operator_f1(operatorID);
auto writeRemapWeightsOnly = true;
int operfunc;
remap_set_int(REMAP_WRITE_REMAP, writeRemapWeightsOnly);
RemapType remap;
RemapMethod mapType;
auto remapParams = remap_get_params();
remap_set_params(remapParams);
auto extrapolateIsSet = (remapParams.extrapolate != -1);
auto remapExtrapolate = extrapolateIsSet ? (bool) remapParams.extrapolate : remap_func_is_dist(operfunc);
VarList varList1;
Varray<short> imask;
std::vector<bool> remapGrids;
if (Options::cdoVerbose) cdo_print("Extrapolation %s!", remapExtrapolate ? "enabled" : "disabled");
RemapParams remapParams;
bool useMask;
bool extrapolateIsSet;
bool remapExtrapolate;
bool needGradients;
bool remap_genweights = true;
int remapOrder;
NormOpt normOpt;
public:
void
init(void *process)
{
operator_input_arg("grid description file or name");
if (operfunc == GENDIS && cdo_operator_argc() == 2)
{
auto inum = parameter_to_int(cdo_operator_argv(1));
if (inum < 1) cdo_abort("Number of nearest neighbors out of range (>0)!");
numNeighbors = inum;
}
else
{
operator_check_argc(1);
}
}
cdo_initialize(process);
auto gridID2 = cdo_define_grid(cdo_operator_argv(0));
if (gridInqType(gridID2) == GRID_GENERIC) cdo_abort("Unsupported target grid type (generic)!");
add_operators();
auto streamID1 = cdo_open_read(0);
auto operatorID = cdo_operator_id();
operfunc = cdo_operator_f1(operatorID);
auto writeRemapWeightsOnly = true;
auto vlistID1 = cdo_stream_inq_vlist(streamID1);
remap_set_int(REMAP_WRITE_REMAP, writeRemapWeightsOnly);
VarList varList1;
varListInit(varList1, vlistID1);
remapParams = remap_get_params();
remap_set_params(remapParams);
extrapolateIsSet = (remapParams.extrapolate != -1);
remapExtrapolate = extrapolateIsSet ? (bool) remapParams.extrapolate : remap_func_is_dist(operfunc);
auto remapGrids = remap_set_grids(vlistID1, varList1);
if (Options::cdoVerbose) cdo_print("Extrapolation %s!", remapExtrapolate ? "enabled" : "disabled");
auto numRemapGrids = std::count_if(remapGrids.begin(), remapGrids.end(), [](auto flag) { return (flag == true); });
if (numRemapGrids == 0) cdo_abort("No remappable grid found!");
{
operator_input_arg("grid description file or name");
if (operfunc == GENDIS && cdo_operator_argc() == 2)
{
auto inum = parameter_to_int(cdo_operator_argv(1));
if (inum < 1) cdo_abort("Number of nearest neighbors out of range (>0)!");
numNeighbors = inum;
}
else { operator_check_argc(1); }
}
RemapType remap;
gridID2 = cdo_define_grid(cdo_operator_argv(0));
if (gridInqType(gridID2) == GRID_GENERIC) cdo_abort("Unsupported target grid type (generic)!");
constexpr auto remap_genweights = true;
streamID1 = cdo_open_read(0);
remapSwitches = remap_operfunc_to_maptype(operfunc);
if (numNeighbors) remapSwitches.numNeighbors = numNeighbors;
vlistID1 = cdo_stream_inq_vlist(streamID1);
auto mapType = remapSwitches.mapType;
auto remapOrder = remapSwitches.remapOrder;
varListInit(varList1, vlistID1);
bool useMask = !(!remap_genweights
&& (mapType == RemapMethod::BILINEAR || mapType == RemapMethod::BICUBIC || mapType == RemapMethod::DISTWGT
|| mapType == RemapMethod::CONSERV));
remapGrids = remap_set_grids(vlistID1, varList1);
remap_set_int(REMAP_GENWEIGHTS, (int) remap_genweights);
auto numRemapGrids = std::count_if(remapGrids.begin(), remapGrids.end(), [](auto flag) { return (flag == true); });
if (numRemapGrids == 0) cdo_abort("No remappable grid found!");
NormOpt normOpt(NormOpt::NONE);
if (mapType == RemapMethod::CONSERV_SCRIP || mapType == RemapMethod::CONSERV) normOpt = remap_get_normOpt();
remapSwitches = remap_operfunc_to_maptype(operfunc);
if (numNeighbors) remapSwitches.numNeighbors = numNeighbors;
auto needGradients = (mapType == RemapMethod::BICUBIC);
if ((mapType == RemapMethod::CONSERV_SCRIP || mapType == RemapMethod::CONSERV) && remapOrder == 2)
{
if (Options::cdoVerbose) cdo_print("Second order remapping");
needGradients = true;
}
mapType = remapSwitches.mapType;
remapOrder = remapSwitches.remapOrder;
useMask = !(!remap_genweights
&& (mapType == RemapMethod::BILINEAR || mapType == RemapMethod::BICUBIC || mapType == RemapMethod::DISTWGT
|| mapType == RemapMethod::CONSERV));
Field field1;
remap_set_int(REMAP_GENWEIGHTS, (int) remap_genweights);
Varray<short> imask;
normOpt = NormOpt(NormOpt::NONE);
if (mapType == RemapMethod::CONSERV_SCRIP || mapType == RemapMethod::CONSERV) normOpt = remap_get_normOpt();
int tsID = 0;
auto nrecs = cdo_stream_inq_timestep(streamID1, tsID);
needGradients = (mapType == RemapMethod::BICUBIC);
if ((mapType == RemapMethod::CONSERV_SCRIP || mapType == RemapMethod::CONSERV) && remapOrder == 2)
{
if (Options::cdoVerbose) cdo_print("Second order remapping");
needGradients = true;
}
}
for (int recID = 0; recID < nrecs; ++recID)
{
int varID, levelID;
cdo_inq_record(streamID1, &varID, &levelID);
field1.init(varList1[varID]);
cdo_read_record(streamID1, field1);
auto nmiss1 = useMask ? field1.nmiss : 0;
void
run()
{
int tsID = 0;
auto nrecs = cdo_stream_inq_timestep(streamID1, tsID);
auto gridID = varList1[varID].gridID;
auto missval = varList1[varID].missval;
auto gridsize = varList1[varID].gridsize;
for (int recID = 0; recID < nrecs; ++recID)
{
int varID, levelID;
cdo_inq_record(streamID1, &varID, &levelID);
field1.init(varList1[varID]);
cdo_read_record(streamID1, field1);
auto nmiss1 = useMask ? field1.nmiss : 0;
if (remapGrids[vlistGridIndex(vlistID1, gridID)])
{
if (mapType != RemapMethod::CONSERV_SCRIP && mapType != RemapMethod::CONSERV && gridInqType(gridID) == GRID_GME)
cdo_abort("Only conservative remapping is available to remap between GME grids!");
auto gridID = varList1[varID].gridID;
auto missval = varList1[varID].missval;
auto gridsize = varList1[varID].gridsize;
if (gridIsCircular(gridID) && !extrapolateIsSet) remapExtrapolate = true;
if (remapGrids[vlistGridIndex(vlistID1, gridID)])
{
if (mapType != RemapMethod::CONSERV_SCRIP && mapType != RemapMethod::CONSERV && gridInqType(gridID) == GRID_GME)
cdo_abort("Only conservative remapping is available to remap between GME grids!");
imask.resize(gridsize, 1);
if (gridIsCircular(gridID) && !extrapolateIsSet) remapExtrapolate = true;
if (nmiss1) remap_set_mask(gridsize, field1, missval, imask);
imask.resize(gridsize, 1);
// remap.srcGrid.luse_cell_area = false;
// remap.tgtGrid.luse_cell_area = false;
if (nmiss1) remap_set_mask(gridsize, field1, missval, imask);
auto numSearchBins = remapParams.numSearchBins;
if (gridInqType(gridID) != GRID_UNSTRUCTURED && !remapParams.numSearchBinsIsSet)
{
numSearchBins = (!remapExtrapolate && mapType == RemapMethod::DISTWGT) ? 1 : remap_gen_numbins(gridInqYsize(gridID));
}
// remap.srcGrid.luse_cell_area = false;
// remap.tgtGrid.luse_cell_area = false;
remap_set_int(REMAP_NUM_SRCH_BINS, numSearchBins);
auto numSearchBins = remapParams.numSearchBins;
if (gridInqType(gridID) != GRID_UNSTRUCTURED && !remapParams.numSearchBinsIsSet)
{
numSearchBins
= (!remapExtrapolate && mapType == RemapMethod::DISTWGT) ? 1 : remap_gen_numbins(gridInqYsize(gridID));
}
remap.vars.normOpt = normOpt;
remap.vars.pinit = false;
remap_set_int(REMAP_NUM_SRCH_BINS, numSearchBins);
if ((mapType == RemapMethod::BILINEAR || mapType == RemapMethod::BICUBIC)
&& (gridInqType(gridID) == GRID_GME || gridInqType(gridID) == GRID_UNSTRUCTURED))
cdo_abort("Bilinear/bicubic interpolation doesn't support unstructured source grids!");
remap.vars.normOpt = normOpt;
remap.vars.pinit = false;
// Initialize grid information for both grids
remap_init_grids(mapType, remapExtrapolate, gridID, remap.srcGrid, gridID2, remap.tgtGrid);
remap_search_init(mapType, remap.search, remap.srcGrid, remap.tgtGrid);
if ((mapType == RemapMethod::BILINEAR || mapType == RemapMethod::BICUBIC)
&& (gridInqType(gridID) == GRID_GME || gridInqType(gridID) == GRID_UNSTRUCTURED))
cdo_abort("Bilinear/bicubic interpolation doesn't support unstructured source grids!");
remap.gridID = gridID;
remap.nmiss = nmiss1;
// Initialize grid information for both grids
remap_init_grids(mapType, remapExtrapolate, gridID, remap.srcGrid, gridID2, remap.tgtGrid);
remap_search_init(mapType, remap.search, remap.srcGrid, remap.tgtGrid);
if (gridInqType(gridID) == GRID_GME)
{
for (size_t i = 0, j = 0; i < gridsize; ++i)
if (remap.srcGrid.vgpm[i]) imask[j++] = imask[i];
}
remap.gridID = gridID;
remap.nmiss = nmiss1;
varray_copy(remap.srcGrid.size, imask, remap.srcGrid.mask);
if (gridInqType(gridID) == GRID_GME)
{
for (size_t i = 0, j = 0; i < gridsize; ++i)
if (remap.srcGrid.vgpm[i]) imask[j++] = imask[i];
}
if (mapType == RemapMethod::CONSERV_SCRIP || mapType == RemapMethod::CONSERV)
{
varray_fill(remap.srcGrid.cell_area, 0.0);
varray_fill(remap.srcGrid.cell_frac, 0.0);
varray_fill(remap.tgtGrid.cell_area, 0.0);
}
varray_fill(remap.tgtGrid.cell_frac, 0.0);
varray_copy(remap.srcGrid.size, imask, remap.srcGrid.mask);
// initialize some remapping variables
remap_vars_init(mapType, remapOrder, remap.vars);
if (mapType == RemapMethod::CONSERV_SCRIP || mapType == RemapMethod::CONSERV)
{
varray_fill(remap.srcGrid.cell_area, 0.0);
varray_fill(remap.srcGrid.cell_frac, 0.0);
varray_fill(remap.tgtGrid.cell_area, 0.0);
}
varray_fill(remap.tgtGrid.cell_frac, 0.0);
remap_print_info(operfunc, remap_genweights, remap.srcGrid, remap.tgtGrid, nmiss1, remapSwitches.numNeighbors);
// initialize some remapping variables
remap_vars_init(mapType, remapOrder, remap.vars);
if (needGradients && remap.srcGrid.rank != 2 && remapOrder == 2)
{
cdo_abort("Second order remapping is not available for unstructured grids!");
}
remap_print_info(operfunc, remap_genweights, remap.srcGrid, remap.tgtGrid, nmiss1, remapSwitches.numNeighbors);
remap_gen_weights(remapParams.sortMode, remapSwitches, remap);
if (needGradients && remap.srcGrid.rank != 2 && remapOrder == 2)
{
cdo_abort("Second order remapping is not available for unstructured grids!");
}
break;
}
}
remap_gen_weights(remapParams.sortMode, remapSwitches, remap);
remap_write_data_scrip(cdo_get_stream_name(1), remapSwitches, remap.srcGrid, remap.tgtGrid, remap.vars);
break;
}
}
remap_write_data_scrip(cdo_get_stream_name(1), remapSwitches, remap.srcGrid, remap.tgtGrid, remap.vars);
}
void
close()
{
cdo_stream_close(streamID1);
cdo_stream_close(streamID1);
remap_vars_free(remap.vars);
remap_grid_free(remap.srcGrid);
remap_grid_free(remap.tgtGrid);
remap_search_free(remap.search);
remap_vars_free(remap.vars);
remap_grid_free(remap.srcGrid);
remap_grid_free(remap.tgtGrid);
remap_search_free(remap.search);
cdo_finish();
}
};
void *
Remapweights(void *process)
{
ModuleRemapweights remapweights;
cdo_finish();
remapweights.init(process);
remapweights.run();
remapweights.close();
return nullptr;
}
......@@ -32,7 +32,6 @@ class ModuleReplace
int taxisID3;
int taxisID1;
int nts;
int nts2;
int vars1[MaxVars], vars2[MaxVars];
......