OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
Variable.hpp
Go to the documentation of this file.
1 #ifndef FOCS_VARIABLE
2 #define FOCS_VARIABLE
3 
4 #include "Product.hpp"
5 
6 #include <iostream>
7 #include <string>
8 #include <unordered_map>
9 #include <vector>
10 
11 namespace focs {
12 
13 //TODO: change attributes to share with product attributes, or at least copy the theory
14 
15 enum class OcType {
17  Int8, Int16, Int32, Int64,
19  Unknown
20 };
21 // Geospatial = the data moves throughout reading tiles
22 enum class OcGeospatialType {
23  Yes, Line, Pixel, No
24 };
25 
26 template<typename T>
28  public:
30  virtual T apply(const T& data) {return data;}
31 };
32 template<typename T>
34  public:
35  SlopeInterceptScaler(double slope, double intercept) : slope_{slope}, intercept_{intercept} {}
36  T apply(const T& data) override {
37  return slope_ * data + intercept_;
38  }
39  private:
40  double slope_;
41  double intercept_;
42 };
43 template<typename T>
44 class VariableFill {
45  public:
47  virtual bool is_fill(const T&) {return false;}
48 };
49 template<typename T>
50 class VariableFillValue : public VariableFill<T> {
51  public:
52  VariableFillValue(T value) : value_{value} {}
53  bool is_fill(const T& data) override {
54  return data == value_;
55  // if (std::is_floating_point<TT>::value){
56  // // std::cout << "In FP is_fill_value: std::abs(" << value << " - " << fill_value_ << ") = " << (std::abs(value - fill_value_) < 0.001) << "\n";
57  // return std::abs(value - fill_value_) < 0.1; // TODO: this epsilon is nonsensical
58  // } else {
59  // return value == fill_value_;
60  // }
61  }
62  private:
63  T value_;
64 };
65 template<typename T>
66 class VariableFillRange : public VariableFill<T> {
67  public:
68  VariableFillRange(T min, T max) : min_{min}, max_{max} {}
69  bool is_fill(const T& data) override {
70  return !(data < min_ || data > max_);
71  }
72  private:
73  T min_;
74  T max_;
75 };
76 class BaseVariable {
77  public:
78  // typedef void base_type;
79  // typedef void type;
80 
81  BaseVariable() = default;
83  virtual ~BaseVariable(){}
84 
85  std::unordered_map<std::string, std::string>::const_iterator attributes_begin() const {return attributes_.begin();}
86  std::unordered_map<std::string, std::string>::const_iterator attributes_end() const {return attributes_.end();}
87 
88  auto& attributes(){return attributes_;}
89  auto& dimensions(){return dimensions_;}
90 
91  virtual void* _data(){return nullptr;}
92  virtual const void* _data() const { return nullptr; }
93  bool has_data() const {return _data() != nullptr;}
94 
95  const Product& provides(){ return provides_; }
97  const Product& provides() const { return provides_; }
98 
99  const auto& name(){
100  return provides().name();
101  }
102 
103  bool matches(const Product& needs) const { return provides_.matches(needs); }
104  bool matches(const BaseVariable& needs) const { return provides_.matches(needs.provides()); }
105 
106  virtual OcType get_type() const { return OcType::Unknown; }
107  virtual size_t dimension_count() const { return 0; }
108 
110  void geospatial(OcGeospatialType geo_type) { geo_type_ = geo_type; }
111 
112  virtual void rotate(const size_t number_of_lines){ (void) number_of_lines; }
113 
114  template<typename T>
115  OcType get_type(T) const {
117  return OcType::Char;
119  return OcType::String;
120  } else if (std::is_same<T, float>::value){
121  return OcType::Float;
122  } else if (std::is_same<T, double>::value){
123  return OcType::Double;
125  return OcType::LongDouble;
126  } else if (std::is_same<T, int8_t>::value){
127  return OcType::Int8;
129  return OcType::Int16;
131  return OcType::Int32;
133  return OcType::Int64;
135  return OcType::Uint8;
137  return OcType::Uint16;
139  return OcType::Uint32;
141  return OcType::Uint64;
142  }
143  return OcType::Unknown;
144  }
145 
147  switch (get_type()){
148  case OcType::Char:
149  return "char";
150  case OcType::String:
151  return "string";
152  case OcType::Float:
153  return "float";
154  case OcType::Double:
155  return "double";
156  case OcType::LongDouble:
157  return "long double";
158  case OcType::Int8:
159  return "int8";
160  case OcType::Int16:
161  return "int16";
162  case OcType::Int32:
163  return "int32";
164  case OcType::Int64:
165  return ":int64";
166  case OcType::Uint8:
167  return "uint8";
168  case OcType::Uint16:
169  return "uint16";
170  case OcType::Uint32:
171  return "uint32";
172  case OcType::Uint64:
173  return "uint64";
174  case OcType::Unknown:
175  return "unknown";
176  }
177  return "really unknown";
178  }
179 
180  protected:
182  std::unordered_map<std::string, std::string> attributes_{};
183  std::vector<std::pair<std::string, size_t>> dimensions_{};
184  OcGeospatialType geo_type_{OcGeospatialType::Yes}; // only FileReaders will be making data not based on a DataRecord, which makes them geospatial by nature
185 };
186 
187 template<typename T, size_t Dims>
188 struct NVector {
189  typedef std::vector<typename NVector<T, Dims-1>::type> type;
190  int dimensions = Dims;
191 };
192 template<typename T>
193 struct NVector<T, 0> {
194  typedef T type;
195 };
196 // usage: NVector<2, double>::type == 2D vector of doubles
197 
198 template<typename T, size_t Dims>
199 class Variable : public BaseVariable {
200  public:
201  typedef T base_type;
202  typedef typename NVector<T, Dims>::type type;
203 
206  Variable(const type&& data) : data_{data} {}
207  const void* _data() const override {
208  return static_cast<const void*>(&data_);
209  }
210  void* _data() override {
211  return static_cast<void*>(&data_);
212  }
213  const type& data() const {
214  return data_;
215  }
216  type& data(){
217  return data_;
218  }
219  auto& operator[](const size_t i){
220  return data_[i];
221  }
222 
223  OcType get_type() const override { return BaseVariable::get_type(T{}); }
224  size_t dimension_count() const override { return Dims; }
225 
226  VariableFill<T>* fill_value() const { return fill_value_.get(); }
227  void fill_value(std::unique_ptr<VariableFill<T>>&& fill_value) { fill_value_ = std::move(fill_value); }
228  void fill_value(const T& fill_value) { fill_value_ = std::make_unique<VariableFillValue<T>>(fill_value); }
229 
230  void scaler(std::unique_ptr<VariableScaler<T>>&& scaler){scaler_ = std::move(scaler);}
231  VariableScaler<T>* scaler(){return scaler_.get();}
232 
233  // virtual bool is_fill_value(T value){
234  // return value == fill_value_;
235  // }
236  bool is_fill_value(const T& value){
237  if (fill_value_){
238  return fill_value_->is_fill(value);
239  }
240  return false;
241  }
242  template<typename TT>
243  bool is_fill_value(const TT& value){
244  if (fill_value_){
245  return fill_value_->is_fill(value);
246  }
247  return false;
248  }
249  // void apply_scaling(std::string* v, const size_t count){
250  // if (scaler_){
251  // for (size_t i=0;i<count;i++){
252  // if (is_fill_value(v[i])){
253  // // v[i] = ;
254  // } else {
255  // v[i] = scaler_->apply(v[i]);
256  // }
257  // }
258  // }
259  // }
260  // template<typename T, typename std::enable_if<!std::is_arithmetic<T>::value>::type* = nullptr>
262  void apply_scaling(TT* v, const size_t count){
263  if (scaler_){
264  for (size_t i=0;i<count;i++){
265  if (is_fill_value(v[i])){
266  v[i] = std::nan("");
267  } else {
268  v[i] = scaler_->apply(v[i]);
269  }
270  }
271  }
272  }
274  void apply_scaling(TT* v, const size_t count){
275  if (scaler_){
276  for (size_t i=0;i<count;i++){
277  if (is_fill_value(v[i])){
278  v[i] = std::nanl("");
279  } else {
280  v[i] = scaler_->apply(v[i]);
281  }
282  }
283  }
284  }
286  void apply_scaling(TT* v, const size_t count){
287  if (scaler_){
288  for (size_t i=0;i<count;i++){
289  if (is_fill_value(v[i])){
290  v[i] = std::nanf("");
291  } else {
292  v[i] = scaler_->apply(v[i]);
293  }
294  }
295  }
296  }
298  void apply_scaling(TT* v, const size_t count){
299  if (scaler_){
300  for (size_t i=0;i<count;i++){
301  if (!is_fill_value(v[i])){
302  v[i] = scaler_->apply(v[i]);
303  }
304  }
305  }
306  }
307  virtual void rotate(const size_t number_of_lines) override {
308  if (Dims == 2){
309  switch (is_geospatial()){
312  {
313  using std::swap;
314  const size_t swap_start = data_.size() - number_of_lines;
315  // std::cout << "Rotation, starting at " << swap_start << "\n";
316  for (size_t i=0;i<number_of_lines;i++){
317  swap(data_[i], data_[swap_start + i]);
318  }
319  }
320  break;
321  default:
322  break;
323  }
324  }
325  }
326  protected:
328  // FillValueT fill_value_{std::numeric_limits<FillValueT>::max};
329  std::unique_ptr<VariableScaler<T>> scaler_{};
330  std::unique_ptr<VariableFill<T>> fill_value_{};
331 };
332 template<typename T>
333 std::ostream& operator<<(std::ostream& os, const Variable<T, 2>& v){
334  os << "focs::Variable{" << v.provides() << ", ";
335  const size_t max_i = v.data().size() - 1;
336  const size_t max_j = v.data()[0].size() - 1;
337  // os << "(" << max_i << "x" << max_j << "), ";
338  os << "[\n";
339  for (size_t i=0;i<=max_i;i++){
340  os << "\t[";
341  for (size_t j=0;j<=max_j;j++){
342  os << v.data()[i][j];
343  if (j != max_j){
344  os << ", ";
345  }
346  }
347  os << "]";
348  if (i != max_i){
349  os << ",";
350  }
351  os << "\n";
352  }
353  os << "]}";
354  return os;
355 }
356 
357 } // namespace focs
358 
359 #endif // FOCS_VARIABLE
std::vector< std::pair< std::string, size_t > > dimensions_
Definition: Variable.hpp:183
int32 value
Definition: Granule.c:1235
VariableFillValue(T value)
Definition: Variable.hpp:52
BaseVariable(const Product &provides)
Definition: Variable.hpp:82
bool is_fill(const T &data) override
Definition: Variable.hpp:69
void apply_scaling(TT *v, const size_t count)
Definition: Variable.hpp:262
std::unordered_map< std::string, std::string > attributes_
Definition: Variable.hpp:182
MOD_PR03 Production as they are both run by PGE01 It processes every granule that MOD_PR01 produces See MOD_PR01_pr txt for the actual timing since they are imposed by MOD_PR01 s needs
Definition: MOD_PR03_pr.txt:7
int j
Definition: decode_rs.h:73
float * vector(long nl, long nh)
Definition: nrutil.c:15
void name(std::string name)
Definition: Product.hpp:319
const std::string type_to_string()
Definition: Variable.hpp:146
VariableFill< T > * fill_value() const
Definition: Variable.hpp:226
std::unique_ptr< VariableScaler< T > > scaler_
Definition: Variable.hpp:329
virtual void rotate(const size_t number_of_lines) override
Definition: Variable.hpp:307
virtual bool is_fill(const T &)
Definition: Variable.hpp:47
void fill_value(std::unique_ptr< VariableFill< T >> &&fill_value)
Definition: Variable.hpp:227
NVector< T, Dims >::type type
Definition: Variable.hpp:202
bool matches(const BaseVariable &needs) const
Definition: Variable.hpp:104
std::unordered_map< std::string, std::string >::const_iterator attributes_begin() const
Definition: Variable.hpp:85
auto & attributes()
Definition: Variable.hpp:88
@ string
bool matches(const std::vector< Product > &other) const
Definition: Product.hpp:337
size_t dimension_count() const override
Definition: Variable.hpp:224
OcGeospatialType geo_type_
Definition: Variable.hpp:184
virtual ~BaseVariable()
Definition: Variable.hpp:83
OcGeospatialType
Definition: Variable.hpp:22
T apply(const T &data) override
Definition: Variable.hpp:36
VariableScaler< T > * scaler()
Definition: Variable.hpp:231
void provides(const Product &provides)
Definition: Variable.hpp:96
void fill_value(const T &fill_value)
Definition: Variable.hpp:228
OcType get_type(T) const
Definition: Variable.hpp:115
type & data()
Definition: Variable.hpp:216
subroutine os(tamoy, trmoy, pizmoy, tamoyp, trmoyp, palt, phirad, nt, mu, np, rm, gb, rp, xl)
Definition: 6sm1.f:5484
auto & operator[](const size_t i)
Definition: Variable.hpp:219
std::unordered_map< std::string, std::string >::const_iterator attributes_end() const
Definition: Variable.hpp:86
float32 slope[]
Definition: l2lists.h:30
#define max(A, B)
Definition: main_biosmap.c:61
auto & dimensions()
Definition: Variable.hpp:89
Variable(const Product &provides)
Definition: Variable.hpp:205
BaseVariable()=default
float32 intercept[]
Definition: l2lists.h:44
void geospatial(OcGeospatialType geo_type)
Definition: Variable.hpp:110
void scaler(std::unique_ptr< VariableScaler< T >> &&scaler)
Definition: Variable.hpp:230
OcType
Definition: Variable.hpp:15
virtual void rotate(const size_t number_of_lines)
Definition: Variable.hpp:112
std::vector< typename NVector< T, Dims-1 >::type > type
Definition: Variable.hpp:189
virtual size_t dimension_count() const
Definition: Variable.hpp:107
no change in intended resolving MODur00064 Corrected handling of bad ephemeris attitude data
Definition: HISTORY.txt:356
#define min(A, B)
Definition: main_biosmap.c:62
const type & data() const
Definition: Variable.hpp:213
virtual OcType get_type() const
Definition: Variable.hpp:106
virtual T apply(const T &data)
Definition: Variable.hpp:30
std::unique_ptr< VariableFill< T > > fill_value_
Definition: Variable.hpp:330
const auto & name()
Definition: Variable.hpp:99
bool is_fill(const T &data) override
Definition: Variable.hpp:53
bool is_fill_value(const TT &value)
Definition: Variable.hpp:243
const void * _data() const override
Definition: Variable.hpp:207
bool has_data() const
Definition: Variable.hpp:93
bool is_fill_value(const T &value)
Definition: Variable.hpp:236
virtual void * _data()
Definition: Variable.hpp:91
OcGeospatialType is_geospatial() const
Definition: Variable.hpp:109
const Product & provides()
Definition: Variable.hpp:95
std::ostream & operator<<(std::ostream &out, const SensorDirectory &in)
const Product & provides() const
Definition: Variable.hpp:97
void * _data() override
Definition: Variable.hpp:210
virtual const void * _data() const
Definition: Variable.hpp:92
bool matches(const Product &needs) const
Definition: Variable.hpp:103
int i
Definition: decode_rs.h:71
Variable(const type &&data)
Definition: Variable.hpp:206
OcType get_type() const override
Definition: Variable.hpp:223
SlopeInterceptScaler(double slope, double intercept)
Definition: Variable.hpp:35
VariableFillRange(T min, T max)
Definition: Variable.hpp:68
int count
Definition: decode_rs.h:79