1 /*
2 This file is part of CDO. CDO is a collection of Operators to manipulate and analyse Climate model Data.
3
4 Author: Uwe Schulzweida
5
6 */
7
8 #include <cstdlib>
9 #include <string>
10
11 #include "cdo_options.h"
12 #include "cdo_output.h"
13 #include "process_int.h"
14 #include "pmlist.h"
15 #include "convert_units.h"
16 #include "param_conversion.h"
17 #include "parse_literals.h"
18 #include "cdo_cmor.h"
19 #include "cdo_cdi_wrapper.h"
20
21 int string_to_param(const char *paramstr);
22
23 void
mapvar(int vlistID,int varID,const KeyValues & kv,const std::string & key,CmorVar * var,bool & lvalid_min,bool & lvalid_max,int ptab,bool isnPtmodeName)24 mapvar(int vlistID, int varID, const KeyValues &kv, const std::string &key, CmorVar *var, bool &lvalid_min, bool &lvalid_max,
25 int ptab, bool isnPtmodeName)
26 {
27 const char *value = (kv.nvalues > 0) ? kv.values[0].c_str() : nullptr;
28 const bool lv1 = (kv.nvalues == 1);
29
30 // printf("key=%s value=%s\n", key, value ? value : "");
31
32 // clang-format off
33 if (!var)
34 {
35 if (key == "cn")
36 {
37 char name[CDI_MAX_NAME];
38 vlistInqVarName(vlistID, varID, name);
39 if (name[0] != 0) cdiDefAttTxt(vlistID, varID, "original_name", (int) strlen(name), parameter_to_word(name));
40 cdiDefKeyString(vlistID, varID, CDI_KEY_NAME, parameter_to_word(value));
41 }
42 else if (key == "u")
43 cdiDefKeyString(vlistID, varID, CDI_KEY_UNITS, value);
44 else if (key == "cm")
45 cdiDefAttTxt(vlistID, varID, "cell_methods", (int) strlen(value), value);
46 else if (key == "ca")
47 cdiDefAttTxt(vlistID, varID, "character_axis", (int) strlen(value), value);
48 else if (key == "za")
49 cdiDefAttTxt(vlistID, varID, "z_axis", (int) strlen(value), value);
50 else if (key == "vc")
51 cdiDefAttTxt(vlistID, varID, "variable_comment", (int) strlen(value), value);
52 else if (key == "p")
53 {
54 if (!isspace(value[0])) cdiDefAttTxt(vlistID, varID, "positive", (int) strlen(value), value);
55 }
56 else
57 {
58 if (Options::cdoVerbose) cdo_print("In applying the mapping table:\n Key: '%s' is ignored.", key);
59 }
60 }
61 else
62 {
63 if (lv1 && key == "standard_name") cdiDefKeyString(vlistID, varID, CDI_KEY_STDNAME, value);
64 else if (lv1 && key == "long_name") cdiDefKeyString(vlistID, varID, CDI_KEY_LONGNAME, value);
65 else if (lv1 && key == "units") cdiDefKeyString(vlistID, varID, CDI_KEY_UNITS, value);
66 else if (lv1 && key == "name")
67 {
68 if (isnPtmodeName) cdiDefKeyString(vlistID, varID, CDI_KEY_NAME, parameter_to_word(value));
69 }
70 else if (lv1 && key == "out_name")
71 {
72 const auto outname = parameter_to_word(value);
73 if (!cdo_cmpstr(var->name, outname))
74 {
75 cdiDefKeyString(vlistID, varID, CDI_KEY_NAME, outname);
76 cdiDefAttTxt(vlistID, varID, "original_name", (int) strlen(var->name), var->name);
77 }
78 }
79 else if (lv1 && key == "param")
80 vlistDefVarParam(vlistID, varID, string_to_param(parameter_to_word(value)));
81 else if (lv1 && key == "out_param")
82 vlistDefVarParam(vlistID, varID, string_to_param(parameter_to_word(value)));
83 else if (lv1 && key == "code")
84 vlistDefVarParam(vlistID, varID, cdiEncodeParam(parameter_to_int(value), ptab, 255));
85 else if (lv1 && key == "out_code")
86 vlistDefVarParam(vlistID, varID, cdiEncodeParam(parameter_to_int(value), ptab, 255));
87 else if (lv1 && key == "uvRelativeToGrid")
88 cdiDefKeyInt(vlistID, varID, CDI_KEY_UVRELATIVETOGRID, parameter_to_bool(value));
89 else if (lv1 && key == "comment")
90 cdiDefAttTxt(vlistID, varID, key.c_str(), (int) strlen(value), value);
91 else if (lv1 && key == "chunktype") ;
92 else if (lv1 && key == "cell_methods")
93 cdiDefAttTxt(vlistID, varID, key.c_str(), (int) strlen(value), value);
94 else if (lv1 && key == "cell_measures")
95 cdiDefAttTxt(vlistID, varID, key.c_str(), (int) strlen(value), value);
96 else if (lv1 && key == "delete") var->remove = parameter_to_bool(value);
97 else if (lv1 && key == "convert") var->convert = parameter_to_bool(value);
98 else if (lv1 && key == "factor")
99 {
100 var->lfactor = true;
101 var->factor = parameter_to_double(value);
102 if (Options::cdoVerbose) cdo_print("%s - scale factor %g", var->name, var->factor);
103 }
104 else if (lv1 && (key == "missval" || key == "missing_value"))
105 {
106 const auto missval = parameter_to_double(value);
107 const auto missval_old = vlistInqVarMissval(vlistID, varID);
108 if (!DBL_IS_EQUAL(missval, missval_old))
109 {
110 if (Options::cdoVerbose) cdo_print("%s - change missval from %g to %g", var->name, missval_old, missval);
111 var->changemissval = true;
112 var->missval_old = missval_old;
113 vlistDefVarMissval(vlistID, varID, missval);
114 }
115 }
116 else if (lv1 && key == "valid_min")
117 {
118 lvalid_min = true;
119 var->valid_min = parameter_to_double(value);
120 }
121 else if (lv1 && key == "valid_max")
122 {
123 lvalid_max = true;
124 var->valid_max = parameter_to_double(value);
125 }
126 else if (lv1 && key == "ok_min_mean_abs")
127 {
128 var->check_min_mean_abs = true;
129 var->ok_min_mean_abs = parameter_to_double(value);
130 }
131 else if (lv1 && key == "ok_max_mean_abs")
132 {
133 var->check_max_mean_abs = true;
134 var->ok_max_mean_abs = parameter_to_double(value);
135 }
136 else if (lv1 && (key == "datatype" || key == "type"))
137 {
138 const auto datatype = cdo_str_to_datatype(parameter_to_word(value));
139 if (datatype != -1) vlistDefVarDatatype(vlistID, varID, datatype);
140 }
141 else if (lv1 && key == "dimensions")
142 {
143 }
144 else
145 {
146 const auto &values = kv.values;
147 const auto &rvalue = kv.values[0];
148 int nvalues = kv.nvalues;
149 if (nvalues == 1 && rvalue.empty()) nvalues = 0;
150
151 const int dtype = literals_find_datatype(nvalues, values);
152
153 if (dtype == CDI_DATATYPE_INT8 || dtype == CDI_DATATYPE_INT16 || dtype == CDI_DATATYPE_INT32)
154 {
155 std::vector<int> ivals(nvalues);
156 for (int i = 0; i < nvalues; ++i) ivals[i] = literal_to_int(values[i]);
157 cdiDefAttInt(vlistID, varID, key.c_str(), dtype, nvalues, ivals.data());
158 }
159 else if (dtype == CDI_DATATYPE_FLT32 || dtype == CDI_DATATYPE_FLT64)
160 {
161 std::vector<double> dvals(nvalues);
162 for (int i = 0; i < nvalues; ++i) dvals[i] = literal_to_double(values[i]);
163 cdiDefAttFlt(vlistID, varID, key.c_str(), dtype, nvalues, dvals.data());
164 }
165 else
166 {
167 const int len = (int)rvalue.size();
168 cdiDefAttTxt(vlistID, varID, key.c_str(), len, rvalue.c_str());
169 }
170 }
171 }
172 // clang-format on
173 }
174