Skip to content
Snippets Groups Projects
Commit 56cecc5a authored by Uwe Schulzweida's avatar Uwe Schulzweida
Browse files

Added Setfilter.cc

parent 12e9e5f0
No related branches found
No related tags found
1 merge request!235M214003/develop
Subproject commit 0a881a7616e54470456f94182aecb32572a43c2b
Subproject commit 6d57f10aca3841639ed2671c6e78f5dee4c1496c
......@@ -433,6 +433,7 @@ cdo_SOURCES += Adisit.cc \
Set.cc \
Setattribute.cc \
Setbox.cc \
Setfilter.cc \
Setgrid.cc \
Setgridcell.cc \
Sethalo.cc \
......
/*
This file is part of CDO. CDO is a collection of Operators to manipulate and analyse Climate model Data.
Author: Uwe Schulzweida
*/
#include <cdi.h>
#include "process_int.h"
#include "cdo_options.h"
#include "pmlist.h"
#include "param_conversion.h"
#include "progress.h"
struct SetfilterParams
{
std::string filename;
};
static SetfilterParams
get_parameter()
{
SetfilterParams params;
auto pargc = cdo_operator_argc();
if (pargc)
{
const auto &pargv = cdo_get_oper_argv();
KVList kvlist;
kvlist.name = cdo_module_name();
if (kvlist.parse_arguments(pargv) != 0) cdo_abort("Parse error!");
if (Options::cdoVerbose) kvlist.print();
for (const auto &kv : kvlist)
{
const auto &key = kv.key;
if (kv.nvalues > 1) cdo_abort("Too many values for parameter key >%s<!", key);
if (kv.nvalues < 1) cdo_abort("Missing value for parameter key >%s<!", key);
const auto &value = kv.values[0];
// clang-format off
if (key == "filename") params.filename = parameter_to_word(value);
else cdo_abort("Invalid parameter key >%s<!", key);
// clang-format on
}
}
return params;
}
static std::vector<std::string>
get_vars_filter(const VarList &varList, const std::string &filename)
{
auto numVars = varList.numVars();
std::vector<std::string> varsFilter(numVars);
if (filename.size())
{
auto fp = std::fopen(filename.c_str(), "r");
if (fp == nullptr) cdo_abort("Open failed on: %s\n", filename);
PMList pmlist;
pmlist.read_namelist(fp, filename.c_str());
auto &kvlist = pmlist.front();
std::fclose(fp);
if (Options::cdoVerbose) kvlist.print();
for (const auto &kv : kvlist)
{
const auto &key = kv.key;
if (kv.nvalues > 1) cdo_abort("Too many values for parameter key >%s<!", key);
if (kv.nvalues < 1) cdo_abort("Missing value for parameter key >%s<!", key);
for (const auto &var : varList.vars)
{
if (key == var.name)
{
const auto &value = kv.values[0];
auto filter = parameter_to_word(value);
varsFilter[var.ID] = filter;
}
}
}
}
return varsFilter;
}
static void
set_key_filterspec(int vlistID, int varID, const std::string &filterSpec)
{
cdiDefKeyString(vlistID, varID, CDI_KEY_FILTERSPEC, filterSpec.c_str());
}
class Setfilter : public Process
{
public:
using Process::Process;
inline static CdoModule module = {
.name = "Setfilter",
.operators = { { "setfilter" } },
.aliases = {},
.mode = EXPOSED, // Module mode: 0:intern 1:extern
.number = CDI_REAL, // Allowed number type
.constraints = { 1, 1, NoRestriction },
};
inline static RegisterEntry<Setfilter> registration = RegisterEntry<Setfilter>(module);
CdoStreamID streamID1;
int taxisID1;
CdoStreamID streamID2;
int taxisID2;
int vlistID2;
VarList varList1;
public:
void
init() override
{
auto params = get_parameter();
streamID1 = cdo_open_read(0);
auto vlistID1 = cdo_stream_inq_vlist(streamID1);
taxisID1 = vlistInqTaxis(vlistID1);
varList1 = VarList(vlistID1);
auto varsFilter = get_vars_filter(varList1, params.filename);
vlistID2 = vlistDuplicate(vlistID1);
taxisID2 = taxisDuplicate(taxisID1);
vlistDefTaxis(vlistID2, taxisID2);
auto numVars = varList1.numVars();
for (int varID = 0; varID < numVars; ++varID)
{
if (varsFilter[varID].size() > 0) set_key_filterspec(vlistID2, varID, varsFilter[varID]);
}
streamID2 = cdo_open_write(1);
cdo_def_vlist(streamID2, vlistID2);
}
void
run() override
{
Field field;
auto numVars = varList1.numVars();
auto numSteps = varList1.numSteps();
cdo::Progress progress;
int tsID = 0;
while (true)
{
auto nrecs = cdo_stream_inq_timestep(streamID1, tsID);
if (nrecs == 0) break;
cdo_taxis_copy_timestep(taxisID2, taxisID1);
cdo_def_timestep(streamID2, tsID);
for (int recID = 0; recID < nrecs; ++recID)
{
auto fstatus = (tsID + (recID + 1.0) / nrecs) / numSteps;
if (numSteps > 0) progress.update(fstatus);
auto [varID, levelID] = cdo_inq_record(streamID1);
cdo_def_record(streamID2, varID, levelID);
const auto &var = varList1.vars[varID];
field.init(var);
cdo_read_record(streamID1, field);
cdo_write_record(streamID2, field);
}
tsID++;
}
}
void
close() override
{
cdo_stream_close(streamID1);
cdo_stream_close(streamID2);
vlistDestroy(vlistID2);
}
};
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment