NASA Logo
Ocean Color Science Software

ocssw V2022
expand3D.cpp
Go to the documentation of this file.
1 #include "expand3D.hpp"
2 #include "sensorInfo.h"
3 #include <limits>
4 #include "find_variable.hpp"
5 
6 namespace {
7 std::unordered_map<std::string, std::string> l3d_to_l2_prod_map;
8 std::unordered_map<std::string, float> l3d_wave_attr;
9 std::unordered_map<std::string, std::pair<int, int>> l3d_indexes;
10 std::unordered_map<std::string, std::vector<int>> three_dims_prod_wavelength;
11 std::unordered_map<std::string, std::vector<float>> three_d_original_prod_wavelength;
12 std::unordered_set<std::string> original_l2_products;
13 std::unordered_map<std::string, std::pair<float, float>> min_max_values;
14 std::unordered_set<int> wavelength_all;
16 int sensorID;
17 bool ini_3d{false};
18 bool use_l2_flags{false};
19 
20 template <class T, class F>
21 std::vector<F> vector_rounder(const std::vector<T> &inp) {
22  std::vector<F> result(inp.size());
23  std::transform(inp.begin(), inp.end(), result.begin(),
24  [](const auto &c) { return static_cast<F>(std ::round(c)); });
25  return result;
26 }
27 
28 } // namespace
29 
30 void parse_colon_range(const std::string &wv_range, const std::unordered_map<int, int> &wv3d_list,
31  std::vector<int> &wv_requested_vals, std::vector<int> &wv_requested_indexes,
32  std::unordered_set<int> &wv_requested_vals_lookup) {
33  std::vector<std::string> result_colon;
34  boost::split(result_colon, wv_range, boost::is_any_of(":"), boost::algorithm::token_compress_on);
35  if (result_colon.size() != 2) {
36  EXIT_LOG(std::cerr << "--Error-- : The range must be supplied in the form nnn:nnn. The input "
37  << wv_range << " does not match the format" << std::endl)
38  }
39  try {
40  int min_wv = boost::lexical_cast<int>(result_colon.at(0));
41  int max_wv = boost::lexical_cast<int>(result_colon.at(1));
42  if (wv3d_list.count(min_wv) == 0) {
43  EXIT_LOG(std::cerr << "--Error-- : Start range value not found : " << min_wv << std::endl)
44  }
45  if (wv3d_list.count(max_wv) == 0) {
46  EXIT_LOG(std::cerr << "--Error-- : End range value not found : " << max_wv << std::endl)
47  }
48  for (int wv = min_wv; wv <= max_wv; wv++) {
49  if (wv3d_list.count(wv) > 0) {
50  if (wv_requested_vals_lookup.count(wv) == 0) {
51  wv_requested_vals.push_back(wv);
52  wv_requested_indexes.push_back(wv3d_list.at(wv));
53  wv_requested_vals_lookup.insert(wv);
54  }
55  }
56  }
57  } catch (const boost::bad_lexical_cast &error_boost) {
58  EXIT_LOG(std::cerr << "--Error-- : Conversion failed for WV3D : " << error_boost.what() << std::endl)
59  }
60 };
70 void parse_wv_list(const std::string &wv_list, const std::unordered_map<int, int> &wv3d_list,
71  std::vector<int> &wv_requested_vals, std::vector<int> &wv_requested_indexes,
72  bool exit_on_not_found) {
73  std::vector<std::string> result_comma;
74  std::unordered_set<int> wv_requested_vals_lookup;
75  boost::split(result_comma, wv_list, boost::is_any_of(", "), boost::algorithm::token_compress_on);
76  try {
77  std::for_each(result_comma.begin(), result_comma.end(), [&](const std::string &wv_str) {
78  if (boost::contains(wv_str, ":"))
79  parse_colon_range(wv_str, wv3d_list, wv_requested_vals, wv_requested_indexes,
80  wv_requested_vals_lookup);
81  else {
82  int wv = boost::lexical_cast<int>(wv_str);
83  if (wv3d_list.count(wv) > 0) {
84  if (wv_requested_vals_lookup.count(wv) == 0) {
85  wv_requested_vals.push_back(wv);
86  wv_requested_indexes.push_back(wv3d_list.at(wv));
87  wv_requested_vals_lookup.insert(wv);
88  }
89  } else if (exit_on_not_found) {
90  EXIT_LOG(std::cerr << "--Error-- : Wavelength " << wv << " nm "
91  << "not found");
92  }
93  }
94  });
95  } catch (const boost::bad_lexical_cast &error_boost) {
96  EXIT_LOG(std::cerr << "--Error-- : Conversion failed for WV3D : " << error_boost.what() << std::endl)
97  }
98  std::cout << "\n";
99 }
100 
101 std::vector<std::string> create_min_max_values(const std::vector<std::string> &products_requested_separated,
102  productInfo_t *info) {
103  std::vector<std::string> output_expanded_products;
104 
105  for (const auto &prod_with_min_max : products_requested_separated) {
106  std::vector<std::string> prod_data;
107  float max_val_preset, min_val_preset;
108  boost::algorithm::split(prod_data, prod_with_min_max, boost::is_any_of("="),
109  boost::token_compress_on); // products_requested}
110  {
111  if (findProductInfo(prod_data.at(0).c_str(), sensorID, info)) {
112  min_val_preset = info->validMin;
113  max_val_preset = info->validMax;
114  } else {
115  min_val_preset = 0.0;
116  max_val_preset = std::numeric_limits<float>::max();
117  }
118  }
119  if (prod_data.size() > 1) {
120  output_expanded_products.push_back(prod_data.at(0));
121  std::vector<std::string> min_max_sep;
122  boost::algorithm::split(min_max_sep, prod_data.at(1), boost::is_any_of(":"),
123  boost::token_compress_on); // products_requested}
124  if (min_max_sep.size() == 1) {
125  min_max_values[prod_data.at(0)] = {std::stof(min_max_sep.at(0)), max_val_preset};
126  } else if (min_max_sep.size() == 2) {
127  float max_val =
128  min_max_sep.at(1).length() > 0 ? std::stof(min_max_sep.at(1)) : max_val_preset;
129  float min_val =
130  min_max_sep.at(0).length() > 0 ? std::stof(min_max_sep.at(0)) : min_val_preset;
131  min_max_values[prod_data.at(0)] = {min_val, max_val};
132  } else {
133  EXIT_LOG(std::cerr << "--Error-- : Can't parse the product " << prod_with_min_max
134  << std::endl)
135  }
136  } else {
137  output_expanded_products.push_back(prod_with_min_max);
138  min_max_values[prod_with_min_max] = {min_val_preset, max_val_preset};
139  }
140  }
141 
142  return output_expanded_products;
143 }
144 
146  productInfo_t *info = nullptr) {
147  if (findProductInfo(prod_3d.c_str(), sensorID, info)) {
148  std::string prefix = info->prefix;
149  std::string suffix = info->suffix;
150  return prefix + "_" + wv + suffix;
151  }
152  return prod_3d + "_" + wv;
153 }
154 
155 std::string get_3d_product_name(const std::string &prod_3d, int wv, productInfo_t *info = nullptr) {
156  return get_3d_product_name(prod_3d, std::to_string(wv), info);
157 }
158 
159 std::string get_3d_product_name(const std::string &prod_3d, int *wv, productInfo_t *info = nullptr) {
160  std::vector<std::string> parsed_product;
161  boost::algorithm::split(parsed_product, prod_3d, boost::is_any_of("_"));
162  std::string return_string;
163  for (size_t i = 0; i < parsed_product.size(); i++) {
164  try {
165  int wv_3d = std::stoi(parsed_product.at(i));
166  if (wavelength_all.find(wv_3d) != wavelength_all.end()) {
167  // check if the name does exist
168  std::string name_l2 = parsed_product.at(0);
169  for (size_t k = 1; k < i; k++) {
170  name_l2 += "_" + parsed_product.at(k);
171  }
172  for (size_t k = i + 1; k < parsed_product.size(); k++) {
173  name_l2 += "_" + parsed_product.at(k);
174  }
175  return_string = name_l2;
176  if (findProductInfo(return_string.c_str(), sensorID, info)) {
177  std::string prefix = info->prefix;
178  std::string suffix = info->suffix;
179  return_string = prefix + suffix;
180  }
181  if (original_l2_products.count(name_l2) || original_l2_products.count(return_string)) {
182  *wv = wv_3d;
183  break;
184  }
185  }
186  } catch (...) {
187  }
188  }
189  return return_string;
190 }
191 
197 void expand_l2_requested(std::vector<std::string> &products_requested_separated, productInfo_t *info) {
198  std::unordered_set<std::string> remove;
199  std::vector<std::string> add_3d_expanded;
200  for (auto &prod : products_requested_separated) {
201  if (three_dims_prod_wavelength.count(prod) > 0) {
202  remove.insert(prod);
203  std::vector<int> &wavelengths_3d = three_dims_prod_wavelength[prod];
204  for (const auto &wv : wavelengths_3d) {
205  std::string exp3d_name =
206  get_3d_product_name(prod, wv, info); // prod + "_" + std::to_string(wv);
207  add_3d_expanded.push_back(exp3d_name);
208  min_max_values[exp3d_name] = min_max_values.at(prod);
209  }
210  }
211  }
212 
213  if (!remove.empty()) {
214  for (const auto &rem : remove) {
215  // std::cout << "All wavelength will be binned and sent to output for " << rem << std::endl;
216  auto it =
217  std::find(products_requested_separated.begin(), products_requested_separated.end(), rem);
218  products_requested_separated.erase(it);
219  }
220  for (const auto &prod_exp_3d : add_3d_expanded) {
221  products_requested_separated.push_back(prod_exp_3d);
222  }
223  }
224 }
225 
235 void set_mapper(const std::string &input_file_name, std::string &products_requested,
236  std::vector<std::string> &products_requested_separated,
237  const std::string &requested_wavelengths) {
238  ini_3d = true;
239  netCDF::NcFile l2_file(input_file_name, netCDF::NcFile::read);
240  l2_file.getAtt("instrument").getValues(instrument);
241  l2_file.getAtt("platform").getValues(platform);
243  // set 3d and 2d products
244  {
245  std::multimap<std::string, netCDF::NcVar> vars = find_all_variables(l2_file);
246  for (const auto &var : vars) {
247  const auto dims = var.second.getDims();
248  if (dims.size() <= 1)
249  continue;
250  if (dims.size() == 3) {
251  std::string dim_name = dims[2].getName();
252  int dim_id = dims[2].getId();
253  size_t dim_size = dims[2].getSize();
254  // get variable name using dimension
255  const std::string &variable_3d = dim_name;
256  netCDF::NcVar nc_var = find_nc_variable_cpp(variable_3d, l2_file);
257  int dim_3d_id = -1;
258  size_t dim_3d_size = 0;
259  if (!nc_var.isNull()) {
260  dim_3d_id = nc_var.getDims().at(0).getId();
261  dim_3d_size = nc_var.getDims().at(0).getSize();
262  }
263  if (nc_var.isNull() || dim_3d_id != dim_id || dim_3d_size != dim_size) {
264  netCDF::NcGroup parent_grp = var.second.getParentGroup();
265  nc_var = find_nc_variable_cpp("wavelength", parent_grp);
266  }
267  // third dimension is not wavelength
268  if (nc_var.isNull()) {
269  std::cout << "Variable " << var.second.getName()
270  << " is 3D dimensional but no suitable wavelength set was found" << std::endl;
271  continue;
272  }
273  std::vector<int> waves;
274  std::vector<float> waves_original;
275  if (nc_var.getType() == netCDF::ncFloat) {
276  std::vector<float> temp_(dim_size);
277  nc_var.getVar(temp_.data());
278  waves = vector_rounder<float, int>(temp_);
279  std::copy(temp_.begin(), temp_.end(), std::back_inserter(waves_original));
280  } else if (nc_var.getType() == netCDF::ncDouble) {
281  std::vector<double> temp_(dim_size);
282  nc_var.getVar(temp_.data());
283  waves = vector_rounder<double, int>(temp_);
284  std::copy(temp_.begin(), temp_.end(), std::back_inserter(waves_original));
285  } else if (nc_var.getType() == netCDF::ncInt) {
286  waves.resize(dim_size);
287  nc_var.getVar(waves.data());
288  std::copy(waves.begin(), waves.end(), std::back_inserter(waves_original));
289  }
290  three_dims_prod_wavelength[var.first] = waves;
291  three_d_original_prod_wavelength[var.first] = waves_original;
292  for (auto &wv_ : waves)
293  wavelength_all.insert(wv_);
294  }
295  original_l2_products.insert(var.first);
296  }
297  }
298  // read dimensions and set wavelength needed.
299  for (auto &var_dim : three_dims_prod_wavelength) {
300  if (requested_wavelengths != "ALL") {
301  std::unordered_map<int, int> wv_3d_val_index;
302  std::vector<int> &wavelengths_3d = var_dim.second;
303  int count = 0;
304  std::for_each(wavelengths_3d.begin(), wavelengths_3d.end(), [&](const int &val) {
305  wv_3d_val_index.insert({val, count});
306  count++;
307  });
308  std::vector<int> wv_requested_indexes;
309  wavelengths_3d.clear();
310  parse_wv_list(requested_wavelengths, wv_3d_val_index, wavelengths_3d, wv_requested_indexes,
311  false);
312  }
313  }
314  {
315  boost::algorithm::split(products_requested_separated, products_requested, boost::is_any_of(", "),
316  boost::token_compress_on); // products_requested
317  productInfo_t *info = allocateProductInfo();
318  products_requested_separated = create_min_max_values(products_requested_separated, info);
319  // l2->l2 3d wavelength expansion
320  expand_l2_requested(products_requested_separated, info);
321  {
322  for (const auto &prod : products_requested_separated) {
323  if (original_l2_products.count(prod)) {
324  l3d_to_l2_prod_map[prod] = prod;
325  l3d_indexes[prod] = {0, 1};
326  continue;
327  }
328  {
329  int wv_num = -1;
330  std::string original_2_prod_name = get_3d_product_name(prod, &wv_num, info);
331  // original_2_prod_name should be a 3D poduct
332  if (original_l2_products.count(original_2_prod_name)) {
333  // const auto wv_str = parsed_product.at(len_of_underscore_sep - 1);
334  try {
335  // const int wv_num = std::stoi(wv_str);
336  int index = -1;
337  if (three_dims_prod_wavelength.count(original_2_prod_name)) {
338  std::vector<int> &wavelengths_3d =
339  three_dims_prod_wavelength[original_2_prod_name];
340  auto it = std::find(wavelengths_3d.begin(), wavelengths_3d.end(), wv_num);
341  if (it == wavelengths_3d.end()) {
342  EXIT_LOG(std::cerr << "--Error-- : Wavelength not found; product = "
343  << prod << ", wavelength = " << wv_num
344  << ", L2 file = " << input_file_name << std::endl)
345  }
346  index = it - wavelengths_3d.begin();
347  l3d_indexes[prod] = {index, index + 1};
348  l3d_to_l2_prod_map[prod] = original_2_prod_name;
349  std::vector<float> &wavelengths_original =
350  three_d_original_prod_wavelength[original_2_prod_name];
351  l3d_wave_attr[prod] = wavelengths_original[index];
352  } else {
353  EXIT_LOG(std::cerr << "--Error-- : product = " << prod << " must be 3d"
354  << std::endl)
355  }
356 
357  } catch (const std::exception &e) {
358  EXIT_LOG(std::cerr << e.what() << '\n')
359  }
360  } else {
361  EXIT_LOG(std::cerr << "--Error-- : Product not found = " << prod
362  << ", L2 file = " << input_file_name << std::endl)
363  }
364  }
365  }
366  }
367  freeProductInfo(info);
368  }
369 
370  l2_file.close();
371 }
372 
373 int32_t get_l2prod_index(const l2_prod &l2, const char *prodname) {
374  int32_t index;
375  for (index = 0; index < l2.nprod; index++)
376  if (strcmp(prodname, l2.prodname[index]) == 0)
377  break;
378  if (index == l2.nprod)
379  index = -1;
380  return index;
381 }
382 
383 void set_prodname_3d_to_l2(const std::vector<std::string> &prodparam, l2_prod &l2_str,
384  std::vector<std::string> &l2_prodname, std::vector<std::string> &l3_prodname,
385  std::vector<int32_t> &thirdDimId, std::vector<float> &min_value,
386  std::vector<float> &max_value) {
387  for (const auto &prod_name : prodparam) {
388  int32_t l2_iprod = get_l2prod_index(l2_str, prod_name.c_str());
389  if (l2_iprod == -1) {
390  printf("--Error-- Product: %s was not found in the L2 file: %s. See line %d in %s\n",
391  prod_name.c_str(), l2_str.filename, __LINE__, __FILE__);
392  exit(EXIT_FAILURE);
393  }
394  int32_t tmpThirdDim = l2_str.thirdDim[l2_iprod];
395  if (tmpThirdDim == 1) {
396  l2_prodname.push_back(prod_name);
397  l3_prodname.push_back(prod_name);
398  thirdDimId.push_back(0);
399  min_value.push_back(min_max_values.at(prod_name).first);
400  max_value.push_back(min_max_values.at(prod_name).second);
401  } else {
402  EXIT_LOG(std::cerr << "--Error--: All products must be 2D. Error for " << prod_name << std::endl)
403  }
404  } /* iprod loop */
405 }
406 
407 bool set_l2_flags_use(const std::string &flagsuse) {
408  if (!flagsuse.empty())
409  use_l2_flags = true;
410  return use_l2_flags;
411 }
412 
413 void l3_l2_conversion(char **inp3, char **out2) {
414  if (ini_3d) {
415  *out2 = &l3d_to_l2_prod_map.at(*inp3)[0];
416  } else {
417  *out2 = *inp3;
418  }
419 }
420 
421 float l3_attr(const std::string &inp3) {
422  if (l3d_wave_attr.count(inp3))
423  return l3d_wave_attr.at(inp3);
424  else
425  return BAD_FLT;
426 }
427 
428 void l3_l2_index(char **inp3, int *start, int *count) {
429  if (ini_3d) {
430  *start = l3d_indexes.at(*inp3).first;
431  *count = l3d_indexes.at(*inp3).second - l3d_indexes.at(*inp3).first;
432  }
433 }
435  return ini_3d ? 1 : 0;
436 }
438  int ans = use_l2_flags ? 1 : 0;
439  if (!ini_3d)
440  return true;
441  return ans;
442 }
an array had not been initialized Several spelling and grammar corrections were which is read from the appropriate MCF the above metadata values were hard coded A problem calculating the average background DN for SWIR bands when the moon is in the space view port was corrected The new algorithm used to calculate the average background DN for all reflective bands when the moon is in the space view port is now the same as the algorithm employed by the thermal bands For non SWIR changes in the averages are typically less than Also for non SWIR the black body DNs remain a backup in case the SV DNs are not available For SWIR the changes in computed averages were larger because the old which used the black body suffered from contamination by the micron leak As a consequence of the if SV DNs are not available for the SWIR the EV pixels will not be the granule time is used to identify the appropriate tables within the set given for one LUT the first two or last two tables respectively will be used for the interpolation If there is only one LUT in the set of it will be treated as a constant LUT The manner in which Earth View data is checked for saturation was changed Previously the raw Earth View DNs and Space View DNs were checked against the lookup table values contained in the table dn_sat The change made is to check the raw Earth and Space View DNs to be sure they are less than the maximum saturation value and to check the Space View subtracted Earth View dns against a set of values contained in the new lookup table dn_sat_ev The metadata configuration and ASSOCIATEDINSTRUMENTSHORTNAME from the MOD02HKM product The same metatdata with extensions and were removed from the MOD021KM and MOD02OBC products ASSOCIATEDSENSORSHORTNAME was set to MODIS in all products These changes are reflected in new File Specification which users may consult for exact the pow functions were eliminated in Emissive_Cal and Emissive bands replaced by more efficient code Other calculations throughout the code were also made more efficient Aside from a few round off there was no difference to the product The CPU time decreased by about for a day case and for a night case A minor bug in calculating the uncertainty index for emissive bands was corrected The frame index(0-based) was previously being used the frame number(1-based) should have been used. There were only a few minor changes to the uncertainty index(maximum of 1 digit). 3. Some inefficient arrays(Sigma_RVS_norm_sq) were eliminated and some code lines in Preprocess_L1A_Data were moved into Process_OBCEng_Emiss. There were no changes to the product. Required RAM was reduced by 20 MB. Now
void freeProductInfo(productInfo_t *info)
int instrumentPlatform2SensorId(const char *instrument, const char *platform)
Definition: sensorInfo.c:405
int32_t get_l2prod_index(const l2_prod &l2, const char *prodname)
Definition: expand3D.cpp:373
@ string
int get_set_flag()
Definition: expand3D.cpp:434
def remove(file_to_delete)
Definition: ProcUtils.py:319
netCDF::NcVar find_nc_variable_cpp(const std::string &var_name, T &nc_file)
#define EXIT_LOG(...)
Definition: Log.hpp:26
void l3_l2_conversion(char **inp3, char **out2)
Definition: expand3D.cpp:413
void l3_l2_index(char **inp3, int *start, int *count)
Definition: expand3D.cpp:428
std::multimap< std::string, netCDF::NcVar > find_all_variables(T &nc_id)
std::string get_3d_product_name(const std::string &prod_3d, const std::string &wv, productInfo_t *info=nullptr)
Definition: expand3D.cpp:145
productInfo_t * allocateProductInfo()
void expand_l2_requested(std::vector< std::string > &products_requested_separated, productInfo_t *info)
The user can supply a 3D product such as "Lt" or "Rrs" and they will be expanded: Rrs_449 etc.
Definition: expand3D.cpp:197
void set_prodname_3d_to_l2(const std::vector< std::string > &prodparam, l2_prod &l2_str, std::vector< std::string > &l2_prodname, std::vector< std::string > &l3_prodname, std::vector< int32_t > &thirdDimId, std::vector< float > &min_value, std::vector< float > &max_value)
Definition: expand3D.cpp:383
std::vector< float32 > min_value
Definition: l2bin.cpp:100
bool set_l2_flags_use(const std::string &flagsuse)
Definition: expand3D.cpp:407
@ info
info severity
int findProductInfo(const char *productName, int sensorId, productInfo_t *info)
std::vector< int32_t > thirdDimId
Definition: l2bin.cpp:99
#define BAD_FLT
Definition: jplaeriallib.h:19
void copy(double **aout, double **ain, int n)
void parse_colon_range(const std::string &wv_range, const std::unordered_map< int, int > &wv3d_list, std::vector< int > &wv_requested_vals, std::vector< int > &wv_requested_indexes, std::unordered_set< int > &wv_requested_vals_lookup)
Definition: expand3D.cpp:30
float l3_attr(const std::string &inp3)
Definition: expand3D.cpp:421
no change in intended resolving MODur00064 Corrected handling of bad ephemeris attitude resolving resolving GSFcd00179 Corrected handling of fill values for[Sensor|Solar][Zenith|Azimuth] resolving MODxl01751 Changed to validate LUT version against a value retrieved from the resolving MODxl02056 Changed to calculate Solar Diffuser angles without adjustment for estimated post launch changes in the MODIS orientation relative to incidentally resolving defects MODxl01766 Also resolves MODxl01947 Changed to ignore fill values in SCI_ABNORM and SCI_STATE rather than treating them as resolving MODxl01780 Changed to use spacecraft ancillary data to recognise when the mirror encoder data is being set by side A or side B and to change calculations accordingly This removes the need for seperate LUTs for Side A and Side B data it makes the new LUTs incompatible with older versions of the and vice versa Also resolves MODxl01685 A more robust GRing algorithm is being which will create a non default GRing anytime there s even a single geolocated pixel in a granule Removed obsolete messages from seed as required for compatibility with version of the SDP toolkit Corrected test output file names to end in per delivery and then split off a new MYD_PR03 pcf file for Aqua Added AssociatedPlatformInstrumentSensor to the inventory metadata in MOD01 mcf and MOD03 mcf Created new versions named MYD01 mcf and MYD03 where AssociatedPlatformShortName is rather than Terra The program itself has been changed to read the Satellite Instrument validate it against the input L1A and LUT and to use it determine the correct files to retrieve the ephemeris and attitude data from Changed to produce a LocalGranuleID starting with MYD03 if run on Aqua data Added the Scan Type file attribute to the Geolocation copied from the L1A and attitude_angels to radians rather than degrees The accumulation of Cumulated gflags was moved from GEO_validate_earth_location c to GEO_locate_one_scan c
Definition: HISTORY.txt:464
std::vector< std::string > create_min_max_values(const std::vector< std::string > &products_requested_separated, productInfo_t *info)
Definition: expand3D.cpp:101
int i
Definition: decode_rs.h:71
std::vector< float32 > max_value
Definition: l2bin.cpp:100
int32_t sensorID[MAXNFILES]
Definition: l2bin.cpp:91
int k
Definition: decode_rs.h:73
int get_l2_flag_use()
Definition: expand3D.cpp:437
void set_mapper(const std::string &input_file_name, std::string &products_requested, std::vector< std::string > &products_requested_separated, const std::string &requested_wavelengths)
readL2, openL2 uses the maps from this module. If the module is not initialized, the function read an...
Definition: expand3D.cpp:235
void parse_wv_list(const std::string &wv_list, const std::unordered_map< int, int > &wv3d_list, std::vector< int > &wv_requested_vals, std::vector< int > &wv_requested_indexes, bool exit_on_not_found)
Definition: expand3D.cpp:70
l2prod max
int count
Definition: decode_rs.h:79