OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
Product.hpp
Go to the documentation of this file.
1 
2 #ifndef FOCS_PRODUCT
3 #define FOCS_PRODUCT
4 
5 
6 #include "StringUtils.hpp"
7 
8 #include <iostream>
9 
10 #include <algorithm>
11 #include <complex>
12 #include <cstdint>
13 #include <functional>
14 #include <set>
15 #include <string>
16 #include <typeinfo>
17 #include <vector>
18 
19 // #include <boost/algorithm/string.hpp>
20 #include <boost/algorithm/string/predicate.hpp>
21 #include <boost/variant.hpp>
22 #include <boost/variant/get.hpp>
23 #include <boost/variant/variant_fwd.hpp>
24 
25 namespace focs {
26  // TODO: change attributes to use std::multimap, which will take care of the vector crap
27  // (assuming I don't need more than one dimension for an attribute)?
28  // For now, the NetCdf reader just makes a comma-separated string out of non-scalar attributes.
29  // Stuff downstream can use the StringUtils::stov functions to undo it.
30 
31 
32  using AttributeType = boost::variant<char, std::string, float, double, long double,
33  int8_t, int16_t, int32_t, int64_t, uint8_t, uint16_t, uint32_t, uint64_t>;
34  // std::vector<std::string>, std::vector<float>, std::vector<double>, std::vector<long double>,
35  // std::vector<int8_t>, std::vector<int16_t>, std::vector<int32_t>, std::vector<int64_t>,
36  // std::vector<uint8_t>, std::vector<uint16_t>, std::vector<uint32_t>, std::vector<uint64_t>>;
37 
38 
39  class Attribute {
40  public:
41  Attribute(const std::string& name, AttributeType value) : name_{name}, value_{value}{}
42 
43  const std::string& name() const {return name_;}
44  const AttributeType& value() const {return value_;}
45  const AttributeType& operator*() const {return value_;}
46 
47  double as_double() const {
48  return boost::apply_visitor(AsDouble{}, value_);
49  }
50 
52  return boost::apply_visitor(AsString{}, value_);
53  }
54 
55  template<typename T>
56  std::vector<T> as_vector() const {
57  return boost::apply_visitor(AsVector<T>{}, value_);
58  }
59 
60  friend std::ostream& operator<<(std::ostream& out, const Attribute& attribute){
61  out << attribute.name_ << "=";
62  boost::apply_visitor(Print{out}, attribute.value_);
63  return out;
64  }
65 
66  friend bool operator<(const Attribute& left, const Attribute& right){
67  // if (left.name_ != right.name_){
68  if (!boost::iequals(left.name_, right.name_)){
69  return left.name_ < right.name_;
70  }
71  return boost::apply_visitor(LessThan{}, left.value_, right.value_);
72  }
73 
74  friend bool operator==(const Attribute& left, const std::string& name){
75  // return (left.name_ == name);
76  return boost::iequals(left.name_, name);
77  }
78  friend bool operator==(const Attribute& left, const Attribute& right){
79  // if (left.name_ != right.name_){
80  if (!boost::iequals(left.name_, right.name_)){
81  return false;
82  }
83  return boost::apply_visitor(Equals{}, left.value_, right.value_);
84  }
85  static Attribute parse(const std::string& input){
86  auto equals = input.find_first_of('=');
87  size_t name_start = 0;
88  while (input[name_start] == ' '){
89  name_start++;
90  }
91  size_t name_end = equals;
92  while (input[name_end - 1] == ' '){
93  name_end--;
94  }
95  std::string name(input, name_start, name_end - name_start);
96 
97  while (input[++equals] == ' ');
98 
99  switch (input[equals]){
100  case '"':
101  return Attribute{name, input.substr(equals+1, input.size() - equals - 2)};
102  case '\'':
103  return Attribute{name, input[equals+1]};
104  default:
105  // TODO
106  // This should probably utilize value suffixes, like C (e.g., to force float, 5f)
107  // I also should check for bad parses
108  if (input.substr(equals) == "true"){
109  return Attribute{name, true};
110  } else if (input.substr(equals) == "false"){
111  return Attribute{name, false};
112  } else if (input.find_first_of('.') == std::string::npos){
113  return Attribute{name, std::stoi(input.substr(equals))};
114  } else {
115  return Attribute{name, std::stof(input.substr(equals))};
116  }
117  }
118  }
119 
120 
121  private:
122  std::string name_;
123  AttributeType value_;
124  struct Print : public boost::static_visitor<void> {
125  public:
126  Print(std::ostream& out_) : out{out_} {}
127 
128  void operator()(std::string s) const {
129  out << '"' << s << '"';
130  }
131  void operator()(uint8_t i) const {
132  out << static_cast<int>(i);
133  }
134  void operator()(int8_t i) const {
135  out << static_cast<int>(i);
136  }
137  void operator()(char c) const {
138  out << '\'' << c << '\'';
139  }
140  template <typename T>
141  void operator()(T s) const {
142  out << s;
143  }
144  private:
145  std::ostream& out{std::cout};
146  };
147  struct AsDouble : public boost::static_visitor<double> {
148  public:
149  AsDouble() {}
150  template <typename T>
151  double operator()(T s) const {
152  return s;
153  }
154  double operator()(std::string s) const {
155  return std::stod(s);
156  }
157  };
158  struct AsString : public boost::static_visitor<std::string> {
159  public:
160  AsString() {}
161  template <typename T>
162  std::string operator()(T s) const {
163  return std::to_string(s);
164  }
165  std::string operator()(std::string s) const {
166  return s;
167  }
168  };
169  template<typename T>
170  struct AsVector : public boost::static_visitor<std::vector<T>> {
171  public:
172  AsVector() {}
173  template <typename I>
174  std::vector<T> operator()(I s) const {
175  return std::vector<T>(s);
176  }
177  std::vector<T> operator()(std::string s) const {
178  return focs::StringUtils::stov<T>(s);
179  }
180  };
181 
182  struct Equals : public boost::static_visitor<bool> {
183  template <typename T>
184  bool operator() (T a, T b) const { return a == b; }
185  bool operator()(const std::string& a, const std::string& b) const { return a == b; }
186 
187  template <typename T>
188  bool operator()(std::string, T) const { return false; /* throw std::invalid_argument("Can't compare std::string to non-std::string"); */ }
189  template <typename T>
190  bool operator()(T, std::string) const { return false; /* throw std::invalid_argument("Can't compare std::string to non-std::string"); */ }
191 
192  // Integer comparison (extra work to avoid signed/unsigned comparison)
194  bool operator() (T a, U b) const { return a == b; }
196  bool operator() (T a, U b) const {
197  if (b < 0){
198  return false;
199  }
200  return static_cast<U>(a) == b;
201  }
203  bool operator() (T a, U b) const {
204  if (a < 0){
205  return false;
206  }
207  return a == static_cast<T>(b);
208  }
209 
210  // Non-integer comparison
212  bool operator() (T a, U b) const { return std::abs(a - b) < 0.000001; }
214  bool operator() (T a, U b) const { return std::abs(static_cast<double>(a) - b) < 0.000001; }
216  bool operator() (T a, U b) const { return std::abs(a - static_cast<double>(b)) < 0.000001; }
217  };
218  struct LessThan : public boost::static_visitor<bool> {
219  template <typename T>
220  bool operator() (T a, T b) const { return a < b; }
221  bool operator()(const std::string& a, const std::string& b) const { return a < b; }
222 
223  template <typename T>
224  bool operator()(std::string, T) const { return false; /* throw std::invalid_argument("Can't compare std::string to non-std::string"); */ }
225  template <typename T>
226  bool operator()(T, std::string) const { return false; /* throw std::invalid_argument("Can't compare std::string to non-std::string"); */ }
227 
228  // Integer comparison (extra work to avoid signed/unsigned comparison)
230  bool operator() (T a, U b) const { return a < b; }
232  bool operator() (T a, U b) const {
233  if (b < 0){
234  return false;
235  }
236  return static_cast<U>(a) < b;
237  }
239  bool operator() (T a, U b) const {
240  if (a < 0){
241  return true;
242  }
243  return a < static_cast<T>(b);
244  }
245 
246  // Non-integer comparison
248  bool operator() (T a, U b) const { return a < b; }
250  bool operator() (T a, U b) const { return static_cast<double>(a) < b; }
252  bool operator() (T a, U b) const { return a < static_cast<double>(b); }
253  };
254  };
256  public:
258  virtual bool matches(const Attribute& attribute) const {(void)attribute; return false;}
259  friend std::ostream& operator<<(std::ostream& out, const AttributeCondition&){return out << "unknown condition";}
260  };
262  public:
263  AttributeWild(const std::string& name) : name_{name} {}
264  virtual ~AttributeWild() override {}
265  bool matches(const Attribute& attribute) const override {
266  return attribute.name() == name_;
267  }
268  friend std::ostream& operator<<(std::ostream& out, const AttributeWild& condition){
269  return out << condition.name_ << "=*";
270  }
271  private:
272  std::string name_;
273  };
274  template<typename T=double>
276  public:
277  // AttributeRange(const std::string& name, T min, T max) : name_{name}, min_{min}, max_{max} {}
278  AttributeRange(const std::string& name, T min, T max) : name_{name}, between_{Between<T>(min, max)} {}
279  virtual ~AttributeRange() override {}
280  bool matches(const Attribute& attribute) const override {
281  return attribute.name() == name_ && boost::apply_visitor(between_, attribute.value());
282  }
283  // friend std::ostream& operator<<(std::ostream& out, const AttributeRange& condition){
284  // // return out name_ << ": " << condition.between_.min_ << " - " << condition.between_.max_;
285  // return out name_ << " between stuff";
286  // }
287  private:
288  template<typename B>
289  struct Between : public boost::static_visitor<bool> {
290  Between(B min, B max) : min_{min}, max_{max} {}
291  B min_;
292  B max_;
293 
294  bool operator()(const std::string&) const { return false; }
295  template <typename V>
296  bool operator() (V a) const { return !(a < min_ || a > max_); }
297  };
298 
299  std::string name_;
300  Between<T> between_;
301  };
302  class BaseVariable;
303  class Product {
304  public:
307 
308  Product(std::string name, const std::initializer_list<Attribute>&& attributes) : name_{name}, attributes_{attributes} {}
309  Product(std::string name, const std::set<Attribute>& attributes) : name_{name}, attributes_{attributes} {}
310 
311  Product(std::string name, const std::set<Attribute>&& attributes, std::vector<std::shared_ptr<AttributeCondition>>&& conditions) : name_{name}, attributes_{attributes}, conditions_{std::move(conditions)} {}
312  Product(std::string name, const std::set<Attribute>& attributes, const std::vector<std::shared_ptr<AttributeCondition>>&& conditions) : name_{name}, attributes_{attributes}, conditions_{conditions} {}
313 
314  Product(std::string name, const std::vector<std::shared_ptr<AttributeCondition>>& conditions) : name_{name}, conditions_{conditions} {}
315  Product(std::string name, std::vector<std::shared_ptr<AttributeCondition>>&& conditions) : name_{name}, conditions_{std::move(conditions)} {}
316 
317 
318  // void name(const std::string& name) {name_.assign(name);}
319  void name(std::string name) {name_ = name;}
320  const std::string& name() const {return name_;}
321 
322  auto& attributes() {return attributes_;}
323  auto& conditions() {return conditions_;}
324 
325  auto& attributes() const {return attributes_;}
326  auto& conditions() const {return conditions_;}
327 
328  // void add_attribute(std::unique_ptr<Attribute> attr){attributes_.insert(attributes_.end(), std::move(attr));}
329  void add_attribute(const Attribute& attr){attributes_.insert(attributes_.end(), attr);}
330 
331  friend bool operator==(const Product& me, const Product& other){
332  // return me.name() == other.name() &&
333  return boost::iequals(me.name(), other.name()) &&
334  std::is_permutation(other.attributes().cbegin(), other.attributes().cend(), me.attributes().cbegin(), me.attributes().cend()) &&
335  std::is_permutation(other.conditions().cbegin(), other.conditions().cend(), me.conditions().cbegin(), me.conditions().cend());
336  }
337  bool matches(const std::vector<Product>& other) const {
338  for (const auto& o : other){
339  if (matches(o)){
340  return true;
341  }
342  }
343  return false;
344  }
345  bool matches(const Product& other) const {
346  // std::cout << "product.matches\n";
347  // std::cout << "other name: " << other.name() << "\n";
348  // std::cout << "this name length: " << name().length() << "\n";
349  // std::cout << "this name substr: " << name().substr(0, 1) << "\n";
350  // std::cout << "this name: " << name() << "\n";
351  if (boost::iequals(name(), other.name())){
352  // if (name() == other.name()){
353  // std::cout << "names match\n";
354  const auto& match_atts = other.attributes();
355 
356  bool all_matches = std::all_of(match_atts.cbegin(), match_atts.cend(), [this](const auto& o){return attributes_.find(o) != attributes_.end();});
357  // bool all_matches = true;
358  // for (const auto& a : match_atts){
359  // if (attributes_.find(a) == attributes_.end()){
360  // std::cout << "Missing " << a << "\n";
361  // return false;
362  // }
363  // }
364  if (all_matches){
365  // std::cout << "all attributes matched, checking conditions\n";
366  all_matches = std::all_of(conditions_.cbegin(), conditions_.cend(), [&match_atts](const auto& c){
367  auto i = std::find_if(match_atts.cbegin(), match_atts.cend(), [&c](const auto& o){return c->matches(o);});
368  return i != match_atts.end();
369  });
370  }
371  return all_matches;
372  }
373  // std::cout << "no match\n";
374  return false;
375  }
376  friend std::ostream& operator<<(std::ostream& out, const Product& product){
377  out << product.name_;
378  if (product.attributes().size() != 0 || product.conditions().size()){
379  out << "[";
380  bool printed_first = false;
381  for (auto it = product.attributes().cbegin(); it != product.attributes().cend(); ++it){
382  if (printed_first){
383  out << ',';
384  }
385  out << *it;
386  printed_first = true;
387  }
388  for (auto it = product.conditions().cbegin(); it != product.conditions().cend(); ++it){
389  if (printed_first){
390  out << ',';
391  }
392  out << **it;
393  printed_first = true;
394  }
395  out << "]";
396  }
397  return out;
398  }
399  void variable(BaseVariable* variable) {variable_ = variable;}
400  BaseVariable* variable() const {return variable_;}
401 
402  static size_t skip_passed_char(const std::string& input, size_t pos, char c, bool in_quotes=false){
403  while (pos < input.size()){
404  if (input[pos] == c){
405  return pos + 1;
406  } else if (input[pos] == '\\'){
407  pos += 2;
408  } else if (in_quotes){
409  pos++;
410  } else {
411  switch (input[pos]){
412  case '\'':
413  pos = skip_passed_char(input, pos + 1, '\'', true);
414  break;
415  case '"':
416  pos = skip_passed_char(input, pos + 1, '"', true);
417  break;
418  default:
419  pos++;
420  }
421  }
422  }
423  return std::string::npos;
424  }
425  static std::vector<Product> parse_list(const std::string& input){
426  std::vector<Product> ret{};
427 
428  size_t product_start = 0;
429  auto current_pos = product_start;
430  while (current_pos != std::string::npos && current_pos < input.size()){
431  if (input[current_pos] == ','){
432  ret.push_back(parse(input.substr(product_start, current_pos - product_start)));
433  current_pos++;
434  product_start = current_pos;
435  } else if (input[current_pos] == '\''){
436  current_pos = skip_passed_char(input, current_pos + 1, '\'', true);
437  } else if (input[current_pos] == '"'){
438  current_pos = skip_passed_char(input, current_pos + 1, '"', true);
439  } else if (input[current_pos] == '['){
440  current_pos = skip_passed_char(input, current_pos + 1, ']');
441  } else {
442  current_pos++;
443  }
444  }
445  if (current_pos != product_start){
446  ret.push_back(parse(input.substr(product_start, current_pos - product_start)));
447  }
448  return ret;
449  }
450  static Product parse(const std::string& input){
451  auto attribute_bracket = input.find_first_of('[');
452 
453  size_t name_start = 0;
454  while (input[name_start] == ' '){
455  name_start++;
456  }
457  size_t name_end = attribute_bracket;
458  if (attribute_bracket == std::string::npos){
459  name_end = input.size();
460  }
461  while (input[name_end - 1] == ' '){
462  name_end--;
463  }
464 
465  if (attribute_bracket == std::string::npos){
466  if (name_start == 0 && name_end == attribute_bracket){
467  return Product{input};
468  }
469  return Product{input.substr(name_start, name_end - name_start)};
470  }
471  std::string name(input, name_start, name_end - name_start);
472 
473  std::set<Attribute> attributes{};
474 
475  auto param_start = attribute_bracket + 1;
476  auto current_pos = param_start;
477  while (current_pos != std::string::npos && current_pos < input.size()){
478  if (input[current_pos] == ']'){
479  if (current_pos != param_start){
480  attributes.insert(Attribute::parse(input.substr(param_start, current_pos - param_start)));
481  }
482  break;
483  }
484  if (input[current_pos] == ','){
485  attributes.insert(Attribute::parse(input.substr(param_start, current_pos - param_start)));
486  current_pos++;
487  param_start = current_pos;
488  } else if (input[current_pos] == '\''){
489  current_pos = skip_passed_char(input, current_pos + 1, '\'', true);
490  } else if (input[current_pos] == '"'){
491  current_pos = skip_passed_char(input, current_pos + 1, '"', true);
492  } else {
493  current_pos++;
494  }
495  }
496  return Product{name, attributes};
497  }
498  private:
499  std::string name_{"unspecified"};
500  std::set<Attribute> attributes_{};
501  std::vector<std::shared_ptr<AttributeCondition>> conditions_{}; // pointer for hierarchy, shared for copy-able
502  std::set<Attribute> configuration_{};
503  BaseVariable* variable_{nullptr};
504 
505 
506  // static bool attributes_equal( const std::unique_ptr<Attribute>& left, const std::unique_ptr<Attribute>& right){return *left == *right;}
507  // static bool attributes_equal( const Attribute& left, const Attribute& right){return left == right;}
508  // static bool attributes_equal( const std::unique_ptr<Attribute>& left, const std::unique_ptr<Attribute>& right){return *left == *right;}
509  // static bool attributes_equal( const std::unique_ptr<Attribute>& left, const std::unique_ptr<Attribute>& right){return *left == *right;}
510 
511 
512  };
513 } // namespace focs
514 
515 #endif // FOCS_PRODUCT
516 
int32 value
Definition: Granule.c:1235
Product(std::string name, const std::set< Attribute > &attributes, const std::vector< std::shared_ptr< AttributeCondition >> &&conditions)
Definition: Product.hpp:312
friend std::ostream & operator<<(std::ostream &out, const Attribute &attribute)
Definition: Product.hpp:60
Attribute(const std::string &name, AttributeType value)
Definition: Product.hpp:41
float * vector(long nl, long nh)
Definition: nrutil.c:15
std::vector< T > as_vector() const
Definition: Product.hpp:56
bool matches(const Attribute &attribute) const override
Definition: Product.hpp:280
AttributeRange(const std::string &name, T min, T max)
Definition: Product.hpp:278
bool matches(const Product &other) const
Definition: Product.hpp:345
void name(std::string name)
Definition: Product.hpp:319
AttributeWild(const std::string &name)
Definition: Product.hpp:263
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 out
Definition: HISTORY.txt:422
double as_double() const
Definition: Product.hpp:47
friend bool operator<(const Attribute &left, const Attribute &right)
Definition: Product.hpp:66
virtual ~AttributeCondition()
Definition: Product.hpp:257
float32 * pos
Definition: l1_czcs_hdf.c:35
friend std::ostream & operator<<(std::ostream &out, const AttributeCondition &)
Definition: Product.hpp:259
@ string
bool matches(const std::vector< Product > &other) const
Definition: Product.hpp:337
friend bool operator==(const Attribute &left, const std::string &name)
Definition: Product.hpp:74
instr * input
Product(std::string name)
Definition: Product.hpp:306
boost::variant< char, std::string, float, double, long double, int8_t, int16_t, int32_t, int64_t, uint8_t, uint16_t, uint32_t, uint64_t > AttributeType
Definition: Product.hpp:33
friend std::ostream & operator<<(std::ostream &out, const AttributeWild &condition)
Definition: Product.hpp:268
const std::string & name() const
Definition: Product.hpp:320
Product(std::string name, const std::set< Attribute > &attributes)
Definition: Product.hpp:309
static size_t skip_passed_char(const std::string &input, size_t pos, char c, bool in_quotes=false)
Definition: Product.hpp:402
#define I
virtual ~AttributeRange() override
Definition: Product.hpp:279
#define max(A, B)
Definition: main_biosmap.c:61
integer, parameter double
static std::vector< Product > parse_list(const std::string &input)
Definition: Product.hpp:425
Product(std::string name, const std::initializer_list< Attribute > &&attributes)
Definition: Product.hpp:308
void variable(BaseVariable *variable)
Definition: Product.hpp:399
const std::string & name() const
Definition: Product.hpp:43
#define min(A, B)
Definition: main_biosmap.c:62
static Attribute parse(const std::string &input)
Definition: Product.hpp:85
data_t b[NROOTS+1]
Definition: decode_rs.h:77
auto & conditions()
Definition: Product.hpp:323
bool matches(const Attribute &attribute) const override
Definition: Product.hpp:265
virtual ~AttributeWild() override
Definition: Product.hpp:264
friend std::ostream & operator<<(std::ostream &out, const Product &product)
Definition: Product.hpp:376
virtual bool matches(const Attribute &attribute) const
Definition: Product.hpp:258
#define Between(a, x, b)
Definition: setflags_l2.c:120
const AttributeType & value() const
Definition: Product.hpp:44
Product(std::string name, const std::set< Attribute > &&attributes, std::vector< std::shared_ptr< AttributeCondition >> &&conditions)
Definition: Product.hpp:311
auto & conditions() const
Definition: Product.hpp:326
data_t s[NROOTS]
Definition: decode_rs.h:75
auto & attributes() const
Definition: Product.hpp:325
auto & attributes()
Definition: Product.hpp:322
friend bool operator==(const Product &me, const Product &other)
Definition: Product.hpp:331
static Product parse(const std::string &input)
Definition: Product.hpp:450
Product(std::string name, std::vector< std::shared_ptr< AttributeCondition >> &&conditions)
Definition: Product.hpp:315
void add_attribute(const Attribute &attr)
Definition: Product.hpp:329
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
const AttributeType & operator*() const
Definition: Product.hpp:45
#define abs(a)
Definition: misc.h:90
int i
Definition: decode_rs.h:71
friend bool operator==(const Attribute &left, const Attribute &right)
Definition: Product.hpp:78
std::string as_string() const
Definition: Product.hpp:51
PGE01 indicating that PGE02 PGE01 V6 for and PGE01 V2 for MOD03 were used to produce the granule By convention adopted in all MODIS Terra PGE02 code versions are The fourth digit of the PGE02 version denotes the LUT version used to produce the granule The source of the metadata environment variable ProcessingCenter was changed from a QA LUT value to the Process Configuration A sign used in error in the second order term was changed to a
Definition: HISTORY.txt:424
HISTORY txt for MOD_PR01(step one of PGE01) History follows the following convention needed due to new Aqua ReprocessingActual and the expected LUT revision number from PCF Changed to use PGE version for ProductionHistory Added Archive including ProcessingEnvironment Corrected handling of bad to resovle GSFcd02514 Changed to check staged LUT revision number versus the expected LUT revision number from thereby resolving defect report MODxl02056 This change also avoids the memory access violation reported in MODur00039 Changed the way output arrays were initialized with fill to be more but placed into the L1A output product and thought of as valid packets These packets had an invalid frame count in them and since only the last valid packet of any specific type gets it frame count data written to the output product
Definition: HISTORY.txt:176
BaseVariable * variable() const
Definition: Product.hpp:400
Product(std::string name, const std::vector< std::shared_ptr< AttributeCondition >> &conditions)
Definition: Product.hpp:314
a context in which it is NOT documented to do so subscript which cannot be easily calculated when extracting TONS attitude data from the Terra L0 files Corrected several defects in extraction of entrained ephemeris and and as HDF file attributes
Definition: HISTORY.txt:65