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 #include "focs/NVector.hpp"
6 #include <iostream>
7 #include <string>
8 #include <unordered_map>
9 #include <vector>
10 #include "genutils.h"
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 ~VariableScaler(){}
31  virtual T apply(const T& data) {return data;}
32 };
33 template<typename T>
35  public:
36  SlopeInterceptScaler(double slope, double intercept) : slope_{slope}, intercept_{intercept} {}
37  T apply(const T& data) override {
38  return slope_ * data + intercept_;
39  }
40  private:
41  double slope_;
42  double intercept_;
43 };
44 template<typename T>
45 class VariableFill {
46  public:
48  virtual ~VariableFill(){}
49  virtual bool is_fill(const T&) {return false;}
50 };
51 template<typename T>
52 class VariableFillValue : public VariableFill<T> {
53  public:
54  VariableFillValue(T value) : value_{value} {}
55  bool is_fill(const T& data) override {
56  return data == value_;
57  }
58  private:
59  T value_;
60 };
61 template<typename T>
62 class VariableFillRange : public VariableFill<T> {
63  public:
64  VariableFillRange(T min, T max) : min_{min}, max_{max} {}
65  bool is_fill(const T& data) override {
66  return !(data < min_ || data > max_);
67  }
68  private:
69  T min_;
70  T max_;
71 };
72 class BaseVariable {
73  public:
74  // typedef void base_type;
75  // typedef void type;
76 
77  BaseVariable() = default;
79  virtual ~BaseVariable(){}
80 
81  std::unordered_map<std::string, std::string>::const_iterator attributes_begin() const {return attributes_.begin();}
82  std::unordered_map<std::string, std::string>::const_iterator attributes_end() const {return attributes_.end();}
83 
84  auto& attributes(){return attributes_;}
85  auto& dimensions(){return dimensions_;}
86 
87  virtual void* _data(){return nullptr;}
88  virtual const void* _data() const { return nullptr; }
89  bool has_data() const {return _data() != nullptr;}
90 
91  const Product& provides(){ return provides_; }
94  const Product& provides() const { return provides_; }
95 
96  const auto& name(){
97  return provides().name();
98  }
99 
100  bool matches(const Product& needs) const { return provides_.matches(needs); }
101  bool matches(const BaseVariable& needs) const { return provides_.matches(needs.provides()); }
102 
103  virtual OcType get_type() const { return OcType::Unknown; }
104  virtual size_t dimension_count() const { return 0; }
105 
107  void geospatial(OcGeospatialType geo_type) { geo_type_ = geo_type; }
108 
109  virtual void rotate(const size_t number_of_lines){ (void) number_of_lines; }
110 
111  template<typename T>
112  OcType get_type(T) const {
114  return OcType::Char;
116  return OcType::String;
117  } else if (std::is_same<T, float>::value){
118  return OcType::Float;
119  } else if (std::is_same<T, double>::value){
120  return OcType::Double;
122  return OcType::LongDouble;
123  } else if (std::is_same<T, int8_t>::value){
124  return OcType::Int8;
126  return OcType::Int16;
128  return OcType::Int32;
130  return OcType::Int64;
132  return OcType::Uint8;
134  return OcType::Uint16;
136  return OcType::Uint32;
138  return OcType::Uint64;
139  }
140  return OcType::Unknown;
141  }
142 
143  netCDF::NcType type_to_nc(){
144  switch (get_type()){
145  case OcType::Char:
146  return netCDF::NcType::nc_CHAR;
147  case OcType::String:
148  return netCDF::NcType::nc_STRING;
149  case OcType::Float:
150  return netCDF::NcType::nc_FLOAT;
151  case OcType::Double:
152  return netCDF::NcType::nc_DOUBLE;
153  case OcType::LongDouble:
154  return netCDF::NcType::nc_DOUBLE;
155  case OcType::Int8:
156  return netCDF::NcType::nc_BYTE;
157  case OcType::Int16:
158  return netCDF::NcType::nc_SHORT;
159  case OcType::Int32:
160  return netCDF::NcType::nc_INT;
161  case OcType::Int64:
162  return netCDF::NcType::nc_INT64;
163  case OcType::Uint8:
164  return netCDF::NcType::nc_UBYTE;
165  case OcType::Uint16:
166  return netCDF::NcType::nc_USHORT;
167  case OcType::Uint32:
168  return netCDF::NcType::nc_UINT;
169  case OcType::Uint64:
170  return netCDF::NcType::nc_UINT64;
171  case OcType::Unknown:
172  return netCDF::NcType::nc_OPAQUE;
173  }
174  return {};
175  }
176 
177  protected:
179  std::unordered_map<std::string, std::string> attributes_{};
180  std::vector<std::pair<std::string, size_t>> dimensions_{};
181  OcGeospatialType geo_type_{OcGeospatialType::Yes}; // only FileReaders will be making data not based on a DataRecord, which makes them geospatial by nature
182 };
183 
184 template<typename T, size_t Dims>
185 class Variable : public BaseVariable {
186  public:
187  typedef T base_type;
188  typedef typename NVector<T, Dims>::type type;
189 
192  Variable(const type&& data) : data_{data} {}
193  const void* _data() const override {
194  return static_cast<const void*>(&data_);
195  }
196  void* _data() override {
197  return static_cast<void*>(&data_);
198  }
199  const type& data() const {
200  return data_;
201  }
202  type& data(){
203  return data_;
204  }
205  auto& operator[](const size_t i){
206  return data_[i];
207  }
208 
209  OcType get_type() const override { return BaseVariable::get_type(T{}); }
210  size_t dimension_count() const override { return Dims; }
211 
212  VariableFill<T>* fill_value() const { return fill_value_.get(); }
213  void fill_value(std::unique_ptr<VariableFill<T>>&& fill_value) { fill_value_ = std::move(fill_value); }
214  void fill_value(const T& fill_value) { fill_value_ = std::make_unique<VariableFillValue<T>>(fill_value); }
215 
216  void scaler(std::unique_ptr<VariableScaler<T>>&& scaler){scaler_ = std::move(scaler);}
217  VariableScaler<T>* scaler(){return scaler_.get();}
218 
219  bool is_fill_value(const T& value){
220  if (fill_value_){
221  return fill_value_->is_fill(value);
222  }
223  return false;
224  }
225  template<typename TT>
226  bool is_fill_value(const TT& value){
227  if (fill_value_){
228  return fill_value_->is_fill(value);
229  }
230  return false;
231  }
233  void apply_scaling(TT* v, const size_t count){
234  if (scaler_){
235  for (size_t i=0;i<count;i++){
236  if (is_fill_value(v[i])){
237  v[i] = BAD_FLT;
238  } else {
239  v[i] = scaler_->apply(v[i]);
240  }
241  }
242  }
243  }
245  void apply_scaling(TT* v, const size_t count){
246  if (scaler_){
247  for (size_t i=0;i<count;i++){
248  if (is_fill_value(v[i])){
249  v[i] = BAD_FLT;
250  } else {
251  v[i] = scaler_->apply(v[i]);
252  }
253  }
254  }
255  }
257  void apply_scaling(TT* v, const size_t count){
258  if (scaler_){
259  for (size_t i=0;i<count;i++){
260  if (is_fill_value(v[i])){
261  v[i] = BAD_FLT;
262  } else {
263  v[i] = scaler_->apply(v[i]);
264  }
265  }
266  }
267  }
269  void apply_scaling(TT* v, const size_t count){
270  if (scaler_){
271  for (size_t i=0;i<count;i++){
272  if (!is_fill_value(v[i])){
273  v[i] = scaler_->apply(v[i]);
274  }
275  }
276  }
277  }
278  virtual void rotate(const size_t number_of_lines) override {
279  if (Dims == 2){
280  switch (is_geospatial()){
283  {
284  using std::swap;
285  const size_t swap_start = data_.size() - number_of_lines;
286  // std::cout << "Rotation, starting at " << swap_start << "\n";
287  for (size_t i=0;i<number_of_lines;i++){
288  swap(data_[i], data_[swap_start + i]);
289  }
290  }
291  break;
292  default:
293  break;
294  }
295  }
296  }
297  protected:
299  // FillValueT fill_value_{std::numeric_limits<FillValueT>::max};
300  std::unique_ptr<VariableScaler<T>> scaler_{};
301  std::unique_ptr<VariableFill<T>> fill_value_{};
302 };
303 template<typename T>
304 std::ostream& operator<<(std::ostream& os, const Variable<T, 2>& v){
305  os << "focs::Variable{" << v.provides() << ", ";
306  const size_t max_i = v.data().size() - 1;
307  const size_t max_j = v.data()[0].size() - 1;
308  // os << "(" << max_i << "x" << max_j << "), ";
309  os << "[\n";
310  for (size_t i=0;i<=max_i;i++){
311  os << "\t[";
312  for (size_t j=0;j<=max_j;j++){
313  os << v.data()[i][j];
314  if (j != max_j){
315  os << ", ";
316  }
317  }
318  os << "]";
319  if (i != max_i){
320  os << ",";
321  }
322  os << "\n";
323  }
324  os << "]}";
325  return os;
326 }
327 
328 } // namespace focs
329 
330 #endif // FOCS_VARIABLE
std::vector< std::pair< std::string, size_t > > dimensions_
Definition: Variable.hpp:180
int32 value
Definition: Granule.c:1235
VariableFillValue(T value)
Definition: Variable.hpp:54
BaseVariable(const Product &provides)
Definition: Variable.hpp:78
bool is_fill(const T &data) override
Definition: Variable.hpp:65
void apply_scaling(TT *v, const size_t count)
Definition: Variable.hpp:233
std::unordered_map< std::string, std::string > attributes_
Definition: Variable.hpp:179
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
netCDF::NcType type_to_nc()
Definition: Variable.hpp:143
Product & get_product()
Definition: Variable.hpp:92
void name(std::string name)
Definition: Product.hpp:560
VariableFill< T > * fill_value() const
Definition: Variable.hpp:212
std::unique_ptr< VariableScaler< T > > scaler_
Definition: Variable.hpp:300
virtual ~VariableFill()
Definition: Variable.hpp:48
virtual void rotate(const size_t number_of_lines) override
Definition: Variable.hpp:278
virtual bool is_fill(const T &)
Definition: Variable.hpp:49
void fill_value(std::unique_ptr< VariableFill< T >> &&fill_value)
Definition: Variable.hpp:213
NVector< T, Dims >::type type
Definition: Variable.hpp:188
bool matches(const BaseVariable &needs) const
Definition: Variable.hpp:101
std::unordered_map< std::string, std::string >::const_iterator attributes_begin() const
Definition: Variable.hpp:81
auto & attributes()
Definition: Variable.hpp:84
virtual ~VariableScaler()
Definition: Variable.hpp:30
bool matches(const std::vector< Product > &other) const
Definition: Product.hpp:578
size_t dimension_count() const override
Definition: Variable.hpp:210
OcGeospatialType geo_type_
Definition: Variable.hpp:181
std::vector< typename NVector< T, Dims - 1 >::type > type
Definition: NVector.hpp:6
virtual ~BaseVariable()
Definition: Variable.hpp:79
std::ostream & operator<<(std::ostream &os, const std::vector< T > &data) noexcept
Definition: Product.hpp:159
OcGeospatialType
Definition: Variable.hpp:22
T apply(const T &data) override
Definition: Variable.hpp:37
VariableScaler< T > * scaler()
Definition: Variable.hpp:217
void provides(const Product &provides)
Definition: Variable.hpp:93
void fill_value(const T &fill_value)
Definition: Variable.hpp:214
OcType get_type(T) const
Definition: Variable.hpp:112
type & data()
Definition: Variable.hpp:202
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:205
std::unordered_map< std::string, std::string >::const_iterator attributes_end() const
Definition: Variable.hpp:82
float32 slope[]
Definition: l2lists.h:30
#define max(A, B)
Definition: main_biosmap.c:61
auto & dimensions()
Definition: Variable.hpp:85
Variable(const Product &provides)
Definition: Variable.hpp:191
BaseVariable()=default
float32 intercept[]
Definition: l2lists.h:44
void geospatial(OcGeospatialType geo_type)
Definition: Variable.hpp:107
void scaler(std::unique_ptr< VariableScaler< T >> &&scaler)
Definition: Variable.hpp:216
OcType
Definition: Variable.hpp:15
virtual void rotate(const size_t number_of_lines)
Definition: Variable.hpp:109
virtual size_t dimension_count() const
Definition: Variable.hpp:104
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:199
virtual OcType get_type() const
Definition: Variable.hpp:103
#define BAD_FLT
Definition: jplaeriallib.h:19
virtual T apply(const T &data)
Definition: Variable.hpp:31
std::unique_ptr< VariableFill< T > > fill_value_
Definition: Variable.hpp:301
const auto & name()
Definition: Variable.hpp:96
bool is_fill(const T &data) override
Definition: Variable.hpp:55
bool is_fill_value(const TT &value)
Definition: Variable.hpp:226
const void * _data() const override
Definition: Variable.hpp:193
bool has_data() const
Definition: Variable.hpp:89
bool is_fill_value(const T &value)
Definition: Variable.hpp:219
virtual void * _data()
Definition: Variable.hpp:87
OcGeospatialType is_geospatial() const
Definition: Variable.hpp:106
const Product & provides()
Definition: Variable.hpp:91
const Product & provides() const
Definition: Variable.hpp:94
void * _data() override
Definition: Variable.hpp:196
virtual const void * _data() const
Definition: Variable.hpp:88
bool matches(const Product &needs) const
Definition: Variable.hpp:100
int i
Definition: decode_rs.h:71
Variable(const type &&data)
Definition: Variable.hpp:192
OcType get_type() const override
Definition: Variable.hpp:209
SlopeInterceptScaler(double slope, double intercept)
Definition: Variable.hpp:36
VariableFillRange(T min, T max)
Definition: Variable.hpp:64
int count
Definition: decode_rs.h:79