UFO
ProfileDataHandler.h
Go to the documentation of this file.
1 /*
2  * (C) Crown copyright 2020, Met Office
3  *
4  * This software is licensed under the terms of the Apache Licence Version 2.0
5  * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
6  */
7 
8 #ifndef UFO_PROFILE_PROFILEDATAHANDLER_H_
9 #define UFO_PROFILE_PROFILEDATAHANDLER_H_
10 
11 #include <string>
12 #include <unordered_map>
13 #include <utility>
14 #include <vector>
15 
16 #include "boost/variant.hpp"
17 
18 #include "ioda/ObsDataVector.h"
19 #include "ioda/ObsSpace.h"
20 
21 #include "oops/util/CompareNVectors.h"
22 #include "oops/util/missingValues.h"
23 
27 
29 #include "ufo/utils/StringUtils.h"
30 
31 namespace ioda {
32  class ObsSpace;
33 }
34 
35 namespace ufo {
36 
37  /// \brief Retrieve and store data for individual profiles.
38  /// To do this, first the vector of values in the entire data sample is retrieved
39  /// then the relevant data corresponding to this profile are extracted.
41  public:
42  ProfileDataHandler(ioda::ObsSpace &obsdb,
43  const DataHandlerParameters &options,
44  EntireSampleDataHandler &entireSampleDataHandler,
45  const ProfileIndices &profileIndices);
46 
47  /// Retrieve a vector containing the requested variable for the current profile.
48  /// -# If the variable has previously been placed in a vector, return the vector.
49  /// -# Otherwise obtain the vector from the entire data sample, as long as the entire sample
50  /// is not empty.
51  /// Also store the name of the variable, enabling it to be retrieved later.
52  template <typename T>
53  std::vector<T>& get(const std::string &fullname)
54  {
55  // Determine variable and group names, optional, and number of entries per profile.
56  std::string varname;
57  std::string groupname;
58  ufo::splitVarGroup(fullname, varname, groupname);
59  const bool optional = options_.getOptional(groupname);
60  const size_t entriesPerProfile = options_.getEntriesPerProfile(groupname);
61 
62  if (profileData_.find(fullname) != profileData_.end()) {
63  // If the vector is already present, return it.
64  // If the type T is incorrect then boost::get will return an exception;
65  // provide additional information if that occurs.
66  try {
67  return boost::get<std::vector<T>> (profileData_[fullname]);
68  } catch (boost::bad_get) {
69  throw eckit::BadParameter("Template parameter passed to boost::get"
70  " probably has the wrong type", Here());
71  }
72  } else {
73  std::vector <T> vec_prof; // Vector storing data for current profile.
74  // Retrieve variable vector from entire sample.
75  const std::vector <T> &vec_all = entireSampleDataHandler_.get<T>(fullname);
76  // Only proceed if the vector is not empty.
77  if (!vec_all.empty()) {
79  for (const auto& profileIndex : profileIndicesInEntireSample_)
80  vec_prof.emplace_back(vec_all[profileIndex]);
81  }
82  // Add vector to map (even if it is empty).
83  profileData_.emplace(fullname, std::move(vec_prof));
84  return boost::get<std::vector<T>> (profileData_[fullname]);
85  }
86  }
87 
88  /// Directly set a vector for the current profile.
89  /// Typically used to store variables that are used locally in checks
90  /// (e.g. intermediate values).
91  template <typename T>
92  void set(const std::string &fullname, std::vector<T> &&vec_in)
93  {
94  // Check whether vector is already in map.
95  if (profileData_.find(fullname) != profileData_.end()) {
96  // Replace vector in map.
97  profileData_[fullname] = vec_in;
98  } else {
99  // Add vector to map.
100  profileData_.emplace(fullname, vec_in);
101  }
102  }
103 
104  /// Reset profile information (vectors and corresponding names).
105  /// This should be called every time a new profile will be retrieved.
106  void reset();
107 
108  /// Transfer values from one vector to another (as long as neither is empty).
109  template <typename T>
110  void updateValueIfPresent(const std::vector <T> &vecIn, const size_t &idxIn,
111  std::vector <T> &vecOut, const size_t &idxOut)
112  {
113  // Ensure neither vector is empty.
114  if (oops::anyVectorEmpty(vecIn, vecOut)) return;
115  vecOut[idxOut] = vecIn[idxIn];
116  }
117 
118  /// If any variables in the current profile were modified by the checks,
119  /// the equivalent variables in the entire sample are set to the modified values.
120  /// The variables that are (potentially) modified are hardcoded but this could be
121  /// changed to a configurable list if requred.
122  void updateEntireSampleData();
123 
124  /// Set final report flags based on the NumAnyErrors counter.
125  void setFinalReportFlags();
126 
127  /// Update the 'flagged' vector based on any flags that may have changed during the checks.
128  /// The QC flag group is hardocded but this could be changed to
129  /// a configurable value if required.
130  void setFlagged(const size_t nvars, std::vector<std::vector<bool>> &flagged);
131 
132  /// Get indices in entire sample corresponding to current profile.
133  void getProfileIndicesInEntireSample(const std::string& groupname);
134 
135  /// Return obsdb
136  ioda::ObsSpace &getObsdb() {return obsdb_;}
137 
138  private:
139  /// Container of each variable in the current profile.
140  std::unordered_map <std::string, boost::variant
141  <std::vector <int>, std::vector <float>, std::vector <std::string>>> profileData_;
142 
143  /// Observation database.
144  ioda::ObsSpace &obsdb_;
145 
146  /// Configurable parameters.
148 
149  /// Class that handles the entire data sample.
151 
152  /// Class that handles profile indices.
154 
155  /// Indices in the entire data sample that correspond to the current profile.
156  std::vector <size_t> profileIndicesInEntireSample_;
157  };
158 } // namespace ufo
159 
160 #endif // UFO_PROFILE_PROFILEDATAHANDLER_H_
ufo::ProfileDataHandler
Retrieve and store data for individual profiles. To do this, first the vector of values in the entire...
Definition: ProfileDataHandler.h:40
ufo::ProfileDataHandler::updateValueIfPresent
void updateValueIfPresent(const std::vector< T > &vecIn, const size_t &idxIn, std::vector< T > &vecOut, const size_t &idxOut)
Transfer values from one vector to another (as long as neither is empty).
Definition: ProfileDataHandler.h:110
MetOfficeQCFlags.h
DataHandlerParameters.h
ufo::ProfileDataHandler::profileIndicesInEntireSample_
std::vector< size_t > profileIndicesInEntireSample_
Indices in the entire data sample that correspond to the current profile.
Definition: ProfileDataHandler.h:156
ufo::ProfileIndices
Determine indices of observations making up individual profiles. The indices are computed with respec...
Definition: ProfileIndices.h:39
ufo::ProfileDataHandler::getObsdb
ioda::ObsSpace & getObsdb()
Return obsdb.
Definition: ProfileDataHandler.h:136
ufo::splitVarGroup
void splitVarGroup(const std::string &vargrp, std::string &var, std::string &grp)
Definition: StringUtils.cc:19
ufo::ProfileDataHandler::entireSampleDataHandler_
EntireSampleDataHandler & entireSampleDataHandler_
Class that handles the entire data sample.
Definition: ProfileDataHandler.h:150
ProfileIndices.h
ioda
Definition: ObsAtmSfcInterp.h:24
ufo
Definition: RunCRTM.h:27
ufo::ProfileDataHandler::options_
const DataHandlerParameters & options_
Configurable parameters.
Definition: ProfileDataHandler.h:147
ufo::ProfileDataHandler::setFinalReportFlags
void setFinalReportFlags()
Set final report flags based on the NumAnyErrors counter.
Definition: ProfileDataHandler.cc:74
ufo::ProfileDataHandler::profileIndices_
const ProfileIndices & profileIndices_
Class that handles profile indices.
Definition: ProfileDataHandler.h:153
ufo::DataHandlerParameters
Options controlling the operation of the EntireSampleDataHandler and ProfileDataHandler classes.
Definition: DataHandlerParameters.h:25
ufo::ProfileDataHandler::updateEntireSampleData
void updateEntireSampleData()
Definition: ProfileDataHandler.cc:44
EntireSampleDataHandler.h
ufo::EntireSampleDataHandler
Retrieve and store data for entire sample. This class uses lazy loading; vectors of variables are ret...
Definition: EntireSampleDataHandler.h:42
ufo::ProfileDataHandler::getProfileIndicesInEntireSample
void getProfileIndicesInEntireSample(const std::string &groupname)
Get indices in entire sample corresponding to current profile.
Definition: ProfileDataHandler.cc:27
ufo::DataHandlerParameters::getOptional
bool getOptional(const std::string &groupname) const
Determine whether a variable group is optional or not.
Definition: DataHandlerParameters.h:30
StringUtils.h
ufo::DataHandlerParameters::getEntriesPerProfile
size_t getEntriesPerProfile(const std::string &groupname) const
Determine number of entries per profile for a variable group.
Definition: DataHandlerParameters.h:40
ufo::ProfileDataHandler::profileData_
std::unordered_map< std::string, boost::variant< std::vector< int >, std::vector< float >, std::vector< std::string > > > profileData_
Container of each variable in the current profile.
Definition: ProfileDataHandler.h:141
ufo::EntireSampleDataHandler::get
std::vector< T > & get(const std::string &fullname)
Definition: EntireSampleDataHandler.h:56
ufo::ProfileDataHandler::get
std::vector< T > & get(const std::string &fullname)
Definition: ProfileDataHandler.h:53
ufo::ProfileDataHandler::ProfileDataHandler
ProfileDataHandler(ioda::ObsSpace &obsdb, const DataHandlerParameters &options, EntireSampleDataHandler &entireSampleDataHandler, const ProfileIndices &profileIndices)
Definition: ProfileDataHandler.cc:12
ufo::ProfileDataHandler::set
void set(const std::string &fullname, std::vector< T > &&vec_in)
Definition: ProfileDataHandler.h:92
ufo::ProfileDataHandler::setFlagged
void setFlagged(const size_t nvars, std::vector< std::vector< bool >> &flagged)
Definition: ProfileDataHandler.cc:87
ufo::ProfileDataHandler::obsdb_
ioda::ObsSpace & obsdb_
Observation database.
Definition: ProfileDataHandler.h:144
ufo::ProfileDataHandler::reset
void reset()
Definition: ProfileDataHandler.cc:22