-
Oliver Heidmann authoredOliver Heidmann authored
cdo_options.cc 6.00 KiB
/*
This file is part of CDO. CDO is a collection of Operators to manipulate and analyse Climate model Data.
Author: Uwe Schulzweida
*/
#include "config.h"
#include <cdi.h>
#include "cdo_options.h"
#include "cdo_timer.h"
#include "util_string.h"
#include "cdo_output.h"
#include <cstring>
#include <algorithm>
namespace cdo
{
iTimer readTimer;
iTimer writeTimer;
} // namespace cdo
namespace cdo
{
const char *progname;
const char *Version = "Climate Data Operators version " VERSION " (https://mpimet.mpg.de/cdo)";
std::string FileSuffix;
bool stdinIsTerminal = false;
bool stdoutIsTerminal = false;
bool stderrIsTerminal = false;
} // namespace cdo
namespace Options
{
long coresize = 0;
int numStreamWorker = 0;
int nsb = 0; // Number of significant bits
bool benchmark = false;
bool silentMode = false;
bool test = false;
bool fast = false;
bool force = false;
// NetCDF4/HDF5 filter
std::string filterSpec;
int cdoShuffle = 0;
bool cdoCompress = false;
int cdoCompType = CDI_COMPRESS_NONE;
int cdoCompLevel = 0;
bool cdoInteractive = false;
bool cdoVerbose = false;
int cdoExitStatus = 0;
bool Timer = false;
bool CheckDatarange = false;
int CDO_flt_digits = 7; // TODO:rename
int CDO_dbl_digits = 15; // TODO:rename
bool Use_FFTW = true;
bool VersionInfo = true;
int CMOR_Mode = false;
bool cdoDiag = false;
MemType CDO_Memtype(MemType::Native);
bool CDO_Parallel_Read = false;
int CDO_Reduce_Dim = false;
int CDO_Append_History = true;
bool CDO_Reset_History = false;
bool CDO_task = false;
unsigned Random_Seed = 1;
int cdoChunkType = CDI_UNDEFID;
int cdoChunkSize = CDI_UNDEFID;
bool cdoOverwriteMode = false;
bool cdoParIO = false;
bool cdoRegulargrid = false;
std::vector<std::string> cdoVarnames;
size_t
cdo_num_varnames()
{
return cdoVarnames.size();
}
bool REMAP_genweights = true;
const char *cdoExpName = nullptr;
} // namespace Options
namespace Threading
{
int ompNumThreads = 1;
bool cdoLockIO = false;
} // namespace Threading
const char *
cdo_comment(void)
{
return cdo::Version;
}
static bool
filetype_has_szip(int filetype)
{
return (filetype == CDI_FILETYPE_GRB || filetype == CDI_FILETYPE_GRB2 || filetype == CDI_FILETYPE_NC4
|| filetype != CDI_FILETYPE_NC4C);
}
static bool
filetype_has_zip(int filetype)
{
return (filetype == CDI_FILETYPE_NC4 || filetype == CDI_FILETYPE_NC4C || filetype == CDI_FILETYPE_NCZARR);
}
void
set_compression(int streamID, int filetype)
{
if (Options::cdoCompress)
{
if (filetype == CDI_FILETYPE_GRB || filetype == CDI_FILETYPE_GRB2)
{
Options::cdoCompType = CDI_COMPRESS_SZIP;
Options::cdoCompLevel = 0;
}
else if (filetype == CDI_FILETYPE_NC4 || filetype == CDI_FILETYPE_NC4C || filetype == CDI_FILETYPE_NCZARR)
{
Options::cdoCompType = CDI_COMPRESS_ZIP;
Options::cdoCompLevel = 1;
}
}
if (Options::cdoCompType != CDI_COMPRESS_NONE)
{
/* streamDefShuffle(streamID, Options::cdoShuffle);*/
streamDefCompType(streamID, Options::cdoCompType);
streamDefCompLevel(streamID, Options::cdoCompLevel);
if (Options::cdoCompType == CDI_COMPRESS_SZIP && !filetype_has_szip(filetype))
cdo_warning("SZIP compression not available for non GRIB/NetCDF4 data!");
if (Options::cdoCompType == CDI_COMPRESS_JPEG && filetype != CDI_FILETYPE_GRB2)
cdo_warning("JPEG compression not available for non GRIB2 data!");
if (Options::cdoCompType == CDI_COMPRESS_ZIP && !filetype_has_zip(filetype))
cdo_warning("Deflate compression not available for non NetCDF4 data!");
}
if (Options::filterSpec.size() > 0) { streamDefFilter(streamID, Options::filterSpec.c_str()); }
}
static double pointSearchRadius = 180.0; // default point search radius in degrees
// set point search radius in degrees
void
cdo_set_search_radius(double searchRadius)
{
pointSearchRadius = searchRadius;
}
// get point search radius in degrees
double
cdo_get_search_radius(void)
{
auto searchRadius = pointSearchRadius;
searchRadius = std::clamp(searchRadius, 0.0, 180.0);
return searchRadius;
}
void
cdo_print_attributes(FILE *fp, int cdiID, int varID, int nblanks)
{
int natts;
cdiInqNatts(cdiID, varID, &natts);
for (int ia = 0; ia < natts; ++ia)
{
char attname[CDI_MAX_NAME];
int atttype, attlen;
cdiInqAtt(cdiID, varID, ia, attname, &atttype, &attlen);
if (atttype == CDI_DATATYPE_INT8 || atttype == CDI_DATATYPE_UINT8 || atttype == CDI_DATATYPE_INT16
|| atttype == CDI_DATATYPE_UINT16 || atttype == CDI_DATATYPE_INT32 || atttype == CDI_DATATYPE_UINT32)
{
std::vector<int> attint(attlen);
cdiInqAttInt(cdiID, varID, attname, attlen, attint.data());
fprintf(fp, "%*s", nblanks, "");
fprintf(fp, "%s = ", attname);
for (int i = 0; i < attlen; ++i)
{
if (i) fprintf(fp, ", ");
fprintf(fp, "%d", attint[i]);
}
fprintf(fp, "\n");
}
else if (atttype == CDI_DATATYPE_FLT32 || atttype == CDI_DATATYPE_FLT64)
{
char fltstr[128];
std::vector<double> attflt(attlen);
cdiInqAttFlt(cdiID, varID, attname, attlen, attflt.data());
fprintf(fp, "%*s", nblanks, "");
fprintf(fp, "%s = ", attname);
for (int i = 0; i < attlen; ++i)
{
if (i) fprintf(fp, ", ");
if (atttype == CDI_DATATYPE_FLT32)
fprintf(fp, "%sf", double_to_att_str(Options::CDO_flt_digits, fltstr, sizeof(fltstr), attflt[i]));
else
fprintf(fp, "%s", double_to_att_str(Options::CDO_dbl_digits, fltstr, sizeof(fltstr), attflt[i]));
}
fprintf(fp, "\n");
}
else if (atttype == CDI_DATATYPE_TXT)
{
std::vector<char> atttxt(attlen + 1);
cdiInqAttTxt(cdiID, varID, attname, attlen, atttxt.data());
atttxt[attlen] = 0;
fprintf(fp, "%*s", nblanks, "");
fprintf(fp, "%s = \"%s\"\n", attname, atttxt.data());
}
}
}