-
Uwe Schulzweida authoredUwe Schulzweida authored
cdo_def_options.cc 20.75 KiB
#include <csignal>
#include "cdo_def_options.h"
#include "cdo_getopt.h"
#include "percentiles.h"
#include "cdo_options.h"
#include "cdo_default_values.h"
#include "util_string.h"
#include "cdo_features.h"
#include "griddes.h"
#include "cdo_output.h"
#include "param_conversion.h"
#include "cdo_settings.h"
#include "cdi.h"
#include "datetime.h"
#include "table.h"
#include "mpim_grid/mpim_grid.h"
#include "grid_pointsearch.h"
#include "institution.h"
#include "cdo_zaxis.h"
#include "chunkspec.h"
static void
set_chunkspec_parameter(std::string const &argument)
{
auto chunkSpec = cdo::parse_chunkspec_parameter(argument);
if (chunkSpec.t) Options::cdoChunkSizeDimT = chunkSpec.t;
if (chunkSpec.z) Options::cdoChunkSizeDimZ = chunkSpec.z;
if (chunkSpec.y) Options::cdoChunkSizeDimY = chunkSpec.y;
if (chunkSpec.x) Options::cdoChunkSizeDimX = chunkSpec.x;
}
void
setup_options()
{
CLIOptions::option("envvars")
->add_effect([&]() { CLIOptions::print_envvars = true; })
->aborts_program(true)
->set_category("Info")
->add_help("Prints the environment variables of CDO.");
CLIOptions::option("settings")
->add_effect([&]() { CLIOptions::print_settings = true; })
->aborts_program(true)
->set_category("Info")
->add_help("Prints the settings of CDO.");
CLIOptions::option("debug", "d")
->add_effect([&]() {
unsigned cdoDebugLevel = 0;
unsigned cdiDebugLevel = 0;
cdo::parse_debug_arguments({ "1" }, cdoDebugLevel, cdiDebugLevel);
cdiDebug(cdiDebugLevel);
cdo::set_debug(cdoDebugLevel);
cdo::features::version();
})
->set_category("Output")
->add_help("Pring all available debug messages");
CLIOptions::option("scoped_debug", "D")
->describe_argument("comma seperated scopes")
->set_category("Output")
->on_empty_argument([]() {
std::cerr << "No debug level given please choose: " << std::endl;
print_debug_options();
exit(EXIT_SUCCESS);
})
->add_effect([&](const std::string &argument) {
auto tokens = split_string(argument, ",");
if (tokens.empty())
{
print_debug_options();
exit(EXIT_SUCCESS);
}
unsigned cdoDebugLevel = 0;
unsigned cdiDebugLevel = 0;
cdo::parse_debug_arguments(tokens, cdoDebugLevel, cdiDebugLevel);
cdiDebug(cdiDebugLevel);
cdo::set_debug(cdoDebugLevel);
cdo::features::version();
})
->add_help("Multiple scopes simultaneously possible. Use this option without arguments to get a list of possible scopes");
CLIOptions::option("worker")
->describe_argument("num")
->add_effect([&](const std::string &argument) { Options::numStreamWorker = parameter_to_int(argument); })
->set_category("Multi Threading")
->add_help("Number of worker to decode/decompress GRIB records.");
CLIOptions::option("precision")
->describe_argument("float_digits[,double_digits]")
->add_effect([&](const std::string &argument) { cdo::set_digits(argument); })
->set_category("Numeric")
->add_help("Precision to use in displaying floating-point data (default: 7,15).");
CLIOptions::option("percentile")
->describe_argument("method")
->set_category("Numeric")
->add_effect([&](const std::string &argument) { percentile_set_method(argument); })
->add_help("Methods: nrank, nist, rtype8, <NumPy method (linear|lower|higher|nearest|...)>");
CLIOptions::option("netcdf_hdr_pad")
->describe_argument("nbr")
->add_effect([&](const std::string &argument) {
int netcdf_hdr_pad = parameter_to_bytes(argument);
if (netcdf_hdr_pad >= 0) cdo::netcdf_hdr_pad = netcdf_hdr_pad;
})
->add_help("Pad NetCDF output header with nbr bytes.");
CLIOptions::option("use_fftw")
->describe_argument("false|true")
->add_effect([&](const std::string &argument) { Options::Use_FFTW = (int) parameter_to_bool(argument); })
->add_help("Sets fftw usage.");
CLIOptions::option("config")
->describe_argument("all|all-json|<specific_feature_name>")
->add_effect([&](const std::string &argument) { cdo::features::print_config(argument); })
->on_empty_argument([&]() { cdo::features::print_argument_options(); })
->aborts_program(true)
->set_category("Info")
->add_help("Prints all features and the enabled status.", "Use option <all> to see explicit feature names.");
CLIOptions::option("pointsearchmethod")
->set_internal(true)
->describe_argument("<kdtree|nanoflann|spherepart|full>")
->set_category("Search Methods")
->add_effect([&](const std::string &argument) { set_pointsearch_method(argument); })
->add_help("Sets the point search method.");
CLIOptions::option("gridsearchradius")
->describe_argument("degrees[0..180]")
->set_category("Search Methods")
->add_effect([&](const std::string &argument) {
auto fval = radius_str_to_deg(argument);
if (fval < 0 || fval > 180) cdo_abort("%s=%g out of bounds (0-180 deg)!", "gridsearchradius", fval);
cdo_set_search_radius(fval);
})
->add_help("Sets the grid search radius (0-180 deg).");
CLIOptions::option("remap_weights")
->describe_argument("false|true")
->add_effect([&](const std::string &argument) {
auto intarg = parameter_to_bool(argument);
if (intarg != 0 && intarg != 1) cdo_abort("Unsupported value for option --remap_weights %d [false|true]", intarg);
Options::REMAP_genweights = intarg;
})
->add_help("Generate remap weights (default: 1).");
CLIOptions::option("no_remap_weights")
->add_effect([&]() { Options::REMAP_genweights = 0; })
->add_help("Switch off generation of remap weights.");
CLIOptions::option("enableexcept")
->describe_argument("except")
->set_category("Numeric")
->add_effect([&](const std::string &argument) {
auto except = cdo::evaluate_except_options(argument);
if (except < 0) cdo_abort("option --%s: unsupported argument: %s", "enableexcept", argument);
cdo::set_feenableexcept(except);
if (signal(SIGFPE, cdo::signal_handler) == SIG_ERR) cdo_warning("can't catch SIGFPE!");
})
->add_help("Set individual floating-point traps ", "(DIVBYZERO, INEXACT, INVALID, OVERFLOW, UNDERFLOW, ALL_EXCEPT)");
CLIOptions::option("timestat_date")
->describe_argument("srcdate")
->add_effect([&](const std::string &argument) { set_timestat_date(argument); })
->add_help("Target timestamp (temporal statistics): ", "first, middle, midhigh or last source timestep.");
CLIOptions::option("ignore_time_bounds")
->add_effect([&]() {
extern bool CDO_Ignore_Time_Bounds;
CDO_Ignore_Time_Bounds = true;
})
->add_help("Ignores time bounds for time range statistics.");
CLIOptions::option("use_time_bounds")
->add_effect([&]() {
extern bool CDO_Use_Time_Bounds;
CDO_Use_Time_Bounds = true;
})
->add_help("Enables use of timebounds.");
CLIOptions::option("cmor")->add_effect([&]() { Options::CMOR_Mode = 1; })->add_help("CMOR conform NetCDF output.");
CLIOptions::option("reduce_dim")->add_effect([&]() { Options::CDO_Reduce_Dim = 1; })->add_help("Reduce NetCDF dimensions.");
CLIOptions::option("float")
->add_effect([&]() { Options::CDO_Memtype = MemType::Float; })
->set_category("Numeric")
->add_help("Using single precision floats for data in memory.");
CLIOptions::option("single")
->add_effect([&]() { Options::CDO_Memtype = MemType::Float; })
->set_category("Numeric")
->add_help("Using single precision floats for data in memory.");
CLIOptions::option("double")
->add_effect([&]() { Options::CDO_Memtype = MemType::Double; })
->set_category("Numeric")
->add_help("Using double precision floats for data in memory.");
CLIOptions::option("rusage")
->add_effect([&]() { Options::CDO_Rusage = 1; })
->add_help("Print information about resource utilization.")
->set_category("Info");
CLIOptions::option("pedantic")->add_effect([&]() { MpMO::enable_pedantic(true); })->add_help("Warnings count as errors.");
CLIOptions::option("eccodes")
->add_effect([&]() { cdiDefGlobal("ECCODES_GRIB1", true); })
->set_category("Format Specific")
->add_help("Use ecCodes to decode/encode GRIB1 messages.");
CLIOptions::option("format", "f")
->describe_argument("grb1|grb2|nc1|nc2|nc4|nc4c|nc5|nczarr|srv|ext|ieg")
->add_effect([&](const std::string &argument) { cdo::set_default_filetype(argument); })
->add_help("Format of the output file.");
CLIOptions::option("history")
->add_effect([&]() { Options::CDO_Append_History = true; })
->set_category("History")
->add_help("Do append to NetCDF \"history\" global attribute.");
CLIOptions::option("no_history")
->add_effect([&]() { Options::CDO_Append_History = false; })
->set_category("History")
->add_help("Do not append to NetCDF \"history\" global attribute.");
CLIOptions::option("version", "V")
->add_effect([&]() { cdo::features::version(); })
->aborts_program(true)
->set_category("Info")
->add_help("Print the version number.");
CLIOptions::option("absolute_taxis", "a")
->add_effect([&]() {
if (CdoDefault::TaxisType == TAXIS_RELATIVE)
cdo_abort("option --%s: can't be combined with option --%s", "absolute_taxis (-a)", "relative_taxis (-r)");
CdoDefault::TaxisType = TAXIS_ABSOLUTE;
})
->add_help("Generate an absolute time axis.");
CLIOptions::option("force")->add_effect([&]() { Options::force = true; })->add_help("Forcing a CDO process.");
CLIOptions::option("fast")
->set_internal(true)
->add_effect([&]() {
Options::fast = true;
Options::lazyGridLoad = true;
cdiDefGlobal("NETCDF_LAZY_GRID_LOAD", true);
})
->add_help("If available, use a faster method even if it requires more memory.");
CLIOptions::option("lazy_grid_load")
->set_internal(true)
->describe_argument("false|true")
->add_effect([&](const std::string &argument) { Options::lazyGridLoad = parameter_to_bool(argument); })
->add_help("Enable/disable lazy grid load");
// clang-format off
CLIOptions::option("default_datatype", "b")
->describe_argument("nbits")
->set_category("Numeric")
->add_effect([&](const std::string &argument) { cdo::set_default_datatype(argument); })
->add_help("Set the number of bits for the output precision",
" I8|I16|I32|F32|F64 for nc1,nc2,nc4,nc4c,nc5,nczarr;",
" U8|U16|U32 for nc4,nc4c,nc5;",
" F32|F64 for grb2,srv,ext,ieg;",
" P1 - P24 for grb1,grb2");
// clang-format on
CLIOptions::option("check_data_range", "c")
->add_effect([&]() { Options::CheckDatarange = true; })
->add_help("Enables checks for data overflow.");
CLIOptions::option("grid", "g")
->describe_argument("grid")
->add_effect([&](const std::string &argument) { cdo_set_grids(argument); })
->add_help("Set default grid name or file. Available grids: ",
"global_<DXY>, zonal_<DY>, r<NX>x<NY>, lon=<LON>/lat=<LAT>, F<XXX>, gme<NI>, hpz<ZOOM>");
CLIOptions::option("institution", "i")
->describe_argument("institute_name")
->add_effect([&](const std::string &argument) { define_institution(argument); })
->add_help("Sets institution name.");
CLIOptions::option("chunktype", "k")
->describe_argument("auto|grid|lines")
->set_category("Format Specific")
->add_effect([&](const std::string &argument) { cdo::set_chunktype(argument); })
->add_help("NetCDF4 chunk type (x/y dimension).");
CLIOptions::option("chunksize")
->describe_argument("size")
->set_category("Format Specific")
->add_effect([&](const std::string &argument) {
int chunkSize = parameter_to_bytes(argument);
if (chunkSize >= 0) Options::cdoChunkSize = chunkSize;
})
->add_help("NetCDF4 chunk size (x/y dimension).");
CLIOptions::option("chunkspec")
->describe_argument("spec")
->set_category("Format Specific")
->add_effect([&](const std::string &argument) { set_chunkspec_parameter(argument); })
->add_help("NetCDF4 specify chunking for dimensions (x/y/z/t).");
CLIOptions::option("copy_chunkspec")
->set_category("Format Specific")
->add_effect([&]() { cdiDefGlobal("COPY_CHUNKSPEC", true); })
->add_help("Copy chunk specification.");
CLIOptions::option("remove_chunkspec")
->set_category("Format Specific")
->add_effect([&]() { cdiDefGlobal("REMOVE_CHUNKSPEC", true); })
->add_help("Remove chunk specification.");
CLIOptions::option("lock_io", "L")->add_effect([&]() { Threading::cdoLockIO = true; })->add_help("Lock IO (sequential access).");
CLIOptions::option("zaxis", "l")
->describe_argument("zaxis")
->add_effect([&](const std::string &argument) { cdo_set_zaxes(argument); })
->add_help("Set default zaxis name or file.");
CLIOptions::option("set_missval", "m")
->describe_argument("missval")
->add_effect([&](const std::string &argument) {
auto [success, mv] = string_to_floating<double>(argument);
if (success)
{
Debug("set missval of cdi to: %f", mv);
cdiDefMissval(mv);
}
else { cdo_abort("Could not convert %s to double", argument); }
})
->add_help("Set the missing value of non NetCDF files (default: " + get_scientific(cdiInqMissval()) + ").");
CLIOptions::option("has_missval", "M")
->add_effect([&]() { cdiDefGlobal("HAVE_MISSVAL", true); })
->add_help("Set HAS_MISSVAL to true.");
CLIOptions::option("varnames", "n")
->set_internal(true)
->describe_argument("<varname| file>")
->add_effect([&](const std::string &argument) { Options::cdoVarnames = split_string(argument, ","); })
->add_help("Set default varnames or file.");
CLIOptions::option("num_threads", "P")
->describe_argument("nthreads")
->add_effect([&](const std::string &argument) { Threading::ompNumUserRequestedThreads = parameter_to_int(argument); })
->set_category("Multi Threading")
->add_help("Set number of OpenMP threads.");
CLIOptions::option("async_read", "p")
->set_internal(true)
->add_effect([&]() {
Options::CDO_Async_Read = true;
Options::CDO_task = true;
})
->set_category("Multi Threading")
->add_help("Enables parallel read.");
CLIOptions::option("sortname", "Q")
->add_effect([&]() { cdiDefGlobal("SORTNAME", true); })
->set_category("Format Specific")
->add_help("Alphanumeric sorting of NetCDF parameter names.");
CLIOptions::option("seed")
->describe_argument("seed")
->set_category("Numeric")
->add_effect([&](const std::string &argument) {
int intarg = parameter_to_int(argument);
if (intarg < 0) cdo_abort("Unsupported value for option --seed %d [>=0]", intarg);
Options::Random_Seed = intarg;
})
->add_help("Seed for a new sequence of pseudo-random numbers. <seed> must be >= 0");
CLIOptions::option("regular", "R")
->add_effect([&]() {
Options::cdoRegulargrid = true;
cdiDefGlobal("REGULARGRID", true);
})
->set_category("CGRIBEX")
->add_help("Convert GRIB1 data from global reduced to regular Gaussian grid (cgribex only).");
CLIOptions::option("relative_taxis", "r")
->add_effect([&]() {
if (CdoDefault::TaxisType == TAXIS_ABSOLUTE)
cdo_abort("option --%s: can't be combined with option --%s", "relative_taxis (-r)", "absolute_taxis (-a)");
CdoDefault::TaxisType = TAXIS_RELATIVE;
})
->add_help("Generate a relative time axis.");
CLIOptions::option("cdo_diagnostic", "S")
->add_effect([&]() { Options::cdoDiag = true; })
->add_help("Create an extra output stream for the module TIMSTAT. This stream",
"contains the number of non missing values for each output period.");
CLIOptions::option("silent", "s")
->add_effect([&]() {
Options::silentMode = true;
MpMO::enable_silent_mode(Options::silentMode);
})
->set_category("Output")
->add_help("Silent mode.");
CLIOptions::option("timer", "T")->add_effect([&]() { Options::Timer = true; })->add_help("Enable timer.");
CLIOptions::option("table", "t")
->describe_argument("codetab")
->set_category("CGRIBEX")
->add_effect([&](const std::string &argument) { CdoDefault::TableID = cdo::define_table(argument); })
->add_help("Set GRIB1 default parameter code table name or file (cgribex only).",
cdo::predefined_tables(CLIOptions::padding));
CLIOptions::option("sortparam")->add_effect([]() { cdiDefGlobal("SORTPARAM", true); });
CLIOptions::option("verbose", "v")
->add_effect([&]() {
Options::cdoVerbose = true;
MpMO::enable_verbose(true);
CLIOptions::print_envvars = true;
gridEnableVerbose(Options::cdoVerbose);
})
->add_help("Print extra details for some operators.");
CLIOptions::option("disable_warnings", "w")
->add_effect([&]() { // disable warning messages
MpMO::enable_warnings(false);
extern int _Verbose; // CDI Warnings
_Verbose = 0;
})
->set_category("Output")
->add_help("Disable warning messages.");
CLIOptions::option("par_io", "X")
->set_internal(true)
->add_effect([&]() {
Options::cdoParIO = true; // multi threaded I/O
})
->add_help("Enables multithreaded I/O.")
->set_category("Multi Threading");
CLIOptions::option("shuffle")
->add_effect([&]() { Options::cdoShuffle = true; })
->set_category("Compression")
->add_help("Specify shuffling of variable data bytes before compression (NetCDF)");
CLIOptions::option("compress", "Z")
->add_effect([&]() { Options::cdoCompress = true; })
->set_category("Compression")
->add_help("Enables compression. Default = SZIP");
CLIOptions::option("filter", "F")
->describe_argument("filterspec")
->add_effect([&](const std::string &argument) { cdo::set_filterspec(argument); })
->set_category("Compression")
->add_help("NetCDF4 filter specification");
CLIOptions::option("compression_type", "z")
->describe_argument("aec|jpeg|zip[_1-9]|zstd[1-19]")
->set_category("Compression")
->add_effect([&](const std::string &argument) { cdo::set_compression_type(argument); })
->add_help("aec AEC compression of GRIB2 records", "jpeg JPEG compression of GRIB2 records",
"zip[_1-9] Deflate compression of NetCDF4 variables", "zstd[_1-19] Zstandard compression of NetCDF4 variables");
CLIOptions::option("nsb")
->set_internal(true)
->describe_argument("1-23")
->add_effect([&](const std::string &argument) { Options::nsb = parameter_to_int(argument); })
->set_category("Numeric")
->add_help("Number of significant bits used for bit-rounding.");
CLIOptions::option("show_available_options")
->set_internal(true)
->aborts_program(true)
->set_category("Info")
->add_effect([&]() { CLIOptions::print_available_options(); })
->add_help("Shows all available optins and prints all shortforms, only internal use for testing.");
#ifdef HIRLAM_EXTENSIONS
CLIOptions::option("Dkext")
->describe_argument("debLev")
->set_category("Hirlam Extension")
->add_effect([&](const std::string &argument) {
auto extDebugVal = parameter_to_int(argument);
if (extDebugVal > 0)
{
extern int cdiDebugExt;
cdoDebugExt = extDebugVal;
cdiDebugExt = extDebugVal;
}
})
->add_help("Setting debugLevel for extensions.");
CLIOptions::option("outputGribDataScanningMode")
->describe_argument("mode")
->set_category("Hirlam Extension")
->add_effect([&](const std::string &argument) {
auto scanningModeValue = parameter_to_int(argument);
if (cdoDebugExt) printf("scanningModeValue=%d\n", scanningModeValue);
if ((scanningModeValue == 0) || (scanningModeValue == 64) || (scanningModeValue == 96))
{
streamGrbDefDataScanningMode(scanningModeValue); // -1: not used; allowed modes: <0,
// 64, 96>; Default is 64
}
else
{
cdo_warning("Warning: %d not in allowed modes: <0, 64, 96>; Using default: 64\n", scanningModeValue);
streamGrbDefDataScanningMode(64);
}
})
->add_help("Setting grib scanning mode for data in output file <0, 64, 96>.", "Default is 64");
#endif // HIRLAM_EXTENSIONS
}