OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
DataProvider.hpp
Go to the documentation of this file.
1 #ifndef FOCS_DATAPROVIDER
2 #define FOCS_DATAPROVIDER
3 
4 #include "DataRecord.hpp"
5 #include "KvStore.hpp"
6 #include "Product.hpp"
7 
8 #include <algorithm>
9 #include <string>
10 #include <unordered_set>
11 #include <utility>
12 #include <vector>
13 
14 #include <iostream>
15 
16 namespace focs {
17  class DataProvider; // circular dependency
20  std::unordered_set<Product*> provide{};
21  std::unordered_set<std::shared_ptr<Product>> need{};
22  bool is_input{false}; // obsolete?
23  bool is_output{false}; // obsolete?
24 
25  bool provides(const std::shared_ptr<Product> needle) const {
26  return std::find_if(provide.cbegin(), provide.cend(), [&needle](const auto* haystack){return haystack->matches(*needle);}) != provide.cend();
27  }
28  void update_needs(std::vector<std::shared_ptr<Product>> new_needs) {
29  for (auto& n : new_needs){
31  }
32  }
33  std::shared_ptr<Product> add_or_find_need(std::shared_ptr<Product> new_need) {
34  auto it = std::find_if(need.cbegin(), need.cend(), [&new_need](const auto& this_need){return *this_need == *new_need;});
35  if (it == need.cend()){
36  need.insert(new_need);
37  return new_need;
38  }
39  return *it;
40  }
41  DataProviderPathPart(DataProvider* provider_) : provider{provider_} {}
42  DataProviderPathPart(DataProvider* provider_, std::unordered_set<Product*> provide_) : provider{provider_}, provide{provide_} {
43  std::cout << "Creating path part, " << provide.size() << "\n";
44  }
45  DataProviderPathPart(DataProvider* provider_, bool is_input_) : provider{provider_}, is_input{is_input_} {} // obsolete
46  DataProviderPathPart(DataProvider* provider_, bool is_input_, bool is_output_) : provider{provider_}, is_input{is_input_}, is_output{is_output_} {} // obsolete
47  };
48 
49  // given to initialize data providers after a processing path has been chosen
51  public:
53  std::vector<std::shared_ptr<DataProviderPathPart>>& processing_path_) : data_record{data_record_}, processing_path{processing_path_} {}
54 
57  std::vector<std::shared_ptr<DataProviderPathPart>>& processing_path;
58  };
59  class DataProvider {
60  public:
61  DataProvider(const std::string& name, const std::string& description) : name_{name}, description_{description} {}
63 
64  virtual ~DataProvider();
65 
66  const std::string& name() const {return name_;}
67  const std::string& description() const {return description_;}
68 
69  // virtual std::unique_ptr<DataProvider> create(DataProviderConfiguration& configuration) = 0;
70 
71  virtual void pre_initialize(DataProviderConfiguration& configuration){(void)configuration;}
72  virtual void initialize(DataProviderConfiguration& configuration, std::unordered_set<Product*>& provide){(void)configuration;(void)provide;}
73  virtual void post_initialize(DataProviderConfiguration& configuration){(void)configuration;}
74  virtual void finalize(){}
75 
76  virtual void process_tile(DataProviderConfiguration& configuration, DataRecord &data_record, TileParameters& tile_params) = 0;
77 
78  virtual std::vector<Product>& provides();
79  virtual void set_needs(std::unordered_set<std::shared_ptr<Product>>& provide){(void)provide;} // only providers that dynamically create needs/provides during path searching need to utilize this
80  virtual std::vector<std::shared_ptr<Product>>& needs();
81  virtual std::vector<std::shared_ptr<Product>> needs(std::unordered_set<Product*>& provide){ // TODO: should this get renamed?
82  (void)provide;
83  return needs();
84  }
85 
86  virtual size_t kernel_size() const { return 1; }
87 
88 
89  //TODO: fulfills needs to be overloadable for providers that only need to check certain attributes.
90  // These won't have to be a perfect match because they may be able to assume that the rest of the attributes will be filled in by whatever they require.
91 
92  virtual bool fulfills(const Product& other) {
93  return contains(provides(), other);
94  }
95  bool fulfills(const std::vector<std::shared_ptr<Product>>& other) {
96  return contains_all(provides(), other);
97  }
98  bool fulfills(DataProvider& other) {
99  return contains_all(provides(), other.needs());
100  }
101  bool is_fulfilled_by(const std::vector<Product>& other) {
102  return contains_all(other, needs());
103  }
105  return contains_all(other.provides(), needs());
106  }
107  bool partially_fulfills(const Product& other) { // convenience
108  return fulfills(other);
109  }
110  bool partially_fulfills(const std::vector<std::shared_ptr<Product>>& other) {
111  return contains_any(provides(), other);
112  }
114  return contains_any(provides(), other.needs());
115  }
116  bool partially_fulfills(const std::vector<DataProvider*> other) {
117  return std::any_of(other.cbegin(), other.cend(), [&](const auto& o){ return contains_any(this->provides(), o->needs()); });
118  }
119  bool is_partially_fulfilled_by(const std::vector<Product>& other) {
120  return contains_any(other, needs());
121  }
123  return contains_any(other.provides(), needs());
124  }
125  // This one is weird, see is_contained_in below
126  bool is_partially_fulfilled_by(const Product& other) {
127  return is_contained_in(other, needs());
128  }
129 
130  static std::vector<std::shared_ptr<DataProviderPathPart>> processing_paths(
131  KvStore& configuration,
132  std::vector<DataProvider*>& input,
133  std::vector<DataProvider*>& data_providers,
134  std::vector<DataProvider*>& output);
135 
136  private:
137  std::string name_{};
138  std::string description_{};
139 
140  static bool contains_all(const std::vector<Product>& haystack, const std::vector<std::shared_ptr<Product>>& needles) {
141  for (auto& needle : needles){
142  if (!contains(haystack, *needle)){
143  return false;
144  }
145  }
146  return true;
147  }
148  static bool contains_any(const std::vector<Product>& haystack, const std::vector<std::shared_ptr<Product>>& needles) {
149  for (auto& needle : needles){
150  if (contains(haystack, *needle)){
151  return true;
152  }
153  }
154  return false;
155  }
156  static bool contains(const std::vector<Product>& haystack, const Product& needle) {
157  for (auto& hay : haystack){
158  if (hay.matches(needle)){
159  return true;
160  }
161  }
162  return false;
163  }
164 
165  // This naming is a bit weird due to Product::match being
166  // asymmetrical. The only time this is used, we're checking if any
167  // needed product is fulfilled by an input product that is
168  // provided.
169  static bool is_contained_in(const Product& hay, const std::vector<std::shared_ptr<Product>>& needles){
170  for (auto& needle : needles){
171  if (hay.matches(*needle)){
172  return true;
173  }
174  }
175  return false;
176  }
177  };
178 
179 } // namespace focs
180 
181 std::ostream& operator<<(std::ostream& out, focs::DataProvider& in);
182 
183 #endif // FOCS_DATAPROVIDER
184 
bool partially_fulfills(const Product &other)
virtual void set_needs(std::unordered_set< std::shared_ptr< Product >> &provide)
virtual std::vector< std::shared_ptr< Product > > needs(std::unordered_set< Product * > &provide)
std::unordered_set< Product * > provide
virtual void finalize()
virtual std::vector< Product > & provides()
float * vector(long nl, long nh)
Definition: nrutil.c:15
DataProvider(const std::string &name, const std::string &description)
DataProvider(const std::string &name)
std::ostream & operator<<(std::ostream &out, focs::DataProvider &in)
std::shared_ptr< Product > add_or_find_need(std::shared_ptr< Product > new_need)
bool is_partially_fulfilled_by(const std::vector< Product > &other)
bool fulfills(DataProvider &other)
DataProviderPathPart(DataProvider *provider_)
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
const std::string & name() const
virtual void post_initialize(DataProviderConfiguration &configuration)
u5 which has been done in the LOCALGRANULEID metadata should have an extension NRT It is requested to identify the NRT production Changes from v6 which may affect scientific output
Definition: HISTORY.txt:186
bool provides(const std::shared_ptr< Product > needle) const
Key-value file reader (commonly called par files)
Definition: KvStore.hpp:35
@ string
bool is_fulfilled_by(DataProvider &other)
virtual ~DataProvider()
virtual void process_tile(DataProviderConfiguration &configuration, DataRecord &data_record, TileParameters &tile_params)=0
bool is_partially_fulfilled_by(DataProvider &other)
bool partially_fulfills(const std::vector< std::shared_ptr< Product >> &other)
bool is_partially_fulfilled_by(const Product &other)
virtual std::vector< std::shared_ptr< Product > > & needs()
DataProviderPathPart(DataProvider *provider_, bool is_input_)
static std::vector< std::shared_ptr< DataProviderPathPart > > processing_paths(KvStore &configuration, std::vector< DataProvider * > &input, std::vector< DataProvider * > &data_providers, std::vector< DataProvider * > &output)
bool partially_fulfills(const std::vector< DataProvider * > other)
virtual void pre_initialize(DataProviderConfiguration &configuration)
virtual size_t kernel_size() const
DataProviderPathPart(DataProvider *provider_, bool is_input_, bool is_output_)
bool fulfills(const std::vector< std::shared_ptr< Product >> &other)
virtual void initialize(DataProviderConfiguration &configuration, std::unordered_set< Product * > &provide)
const std::string & description() const
bool partially_fulfills(DataProvider &other)
std::unordered_set< std::shared_ptr< Product > > need
bool is_fulfilled_by(const std::vector< Product > &other)
virtual bool fulfills(const Product &other)
DataProviderPathPart(DataProvider *provider_, std::unordered_set< Product * > provide_)
DataProviderConfiguration(DataRecord &data_record_, std::vector< std::shared_ptr< DataProviderPathPart >> &processing_path_)
std::vector< std::shared_ptr< DataProviderPathPart > > & processing_path
void update_needs(std::vector< std::shared_ptr< Product >> new_needs)