UFO
ProfileDataHolder.h
Go to the documentation of this file.
1 /*
2  * (C) Copyright 2021, 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_PROFILEDATAHOLDER_H_
9 #define UFO_PROFILE_PROFILEDATAHOLDER_H_
10 
11 #include <string>
12 #include <unordered_map>
13 #include <utility>
14 #include <vector>
15 
16 #include "boost/variant.hpp"
17 
20 
21 namespace ufo {
22 
24 
25  /// \brief Profile data holder class.
26  ///
27  /// \details Stores data for a single profile.
28  /// Each profile is filled with a user-specified list of variables that are transferred
29  /// from an associated ProfileDataHandler.
30  /// A collection of ProfileDataHolders can be used in checks that act on the entire
31  /// sample of profiles at once (unlike checks that act on each profile individually,
32  /// in which case the ProfileDataHandler can be used).
33  /// This class can also be used to modify the values in the associated ProfileDataHandler,
34  /// which is necessary when updating values in the entire sample.
36  public:
37  explicit ProfileDataHolder(ProfileDataHandler &profileDataHandler);
38 
39  /// Fill profile with data.
40  void fill(const std::vector <std::string> &variableNamesInt,
41  const std::vector <std::string> &variableNamesFloat,
42  const std::vector <std::string> &variableNamesString,
43  const std::vector <std::string> &variableNamesGeoVaLs,
44  const std::vector <std::string> &variableNamesObsDiags);
45 
46  /// Retrieve a vector if it is present. If not, throw an exception.
47  template <typename T>
48  std::vector <T>& get(const std::string &fullname)
49  {
50  auto it_profileData = profileData_.find(fullname);
51  if (it_profileData != profileData_.end()) {
52  // If the type T is incorrect then boost::get will return an exception;
53  // provide additional information if that occurs.
54  try {
55  return boost::get<std::vector<T>> (it_profileData->second);
56  } catch (boost::bad_get) {
57  throw eckit::BadParameter("Template parameter passed to boost::get for " +
58  fullname + " probably has the wrong type", Here());
59  }
60  } else {
61  throw eckit::BadValue("Variable " + fullname + " not present in profile. "
62  "Please add it to the relevant argument in the call "
63  "to produceProfileVector()", Here());
64  }
65  }
66 
67  /// Retrieve a GeoVaL vector if it is present. If not, throw an exception.
68  std::vector <float>& getGeoVaLVector(const std::string& fullname);
69 
70  /// Retrieve an ObsDiag vector if it is present. If not, throw an exception.
71  std::vector <float>& getObsDiagVector(const std::string& fullname);
72 
73  /// Set values in a vector.
74  template <typename T>
75  void set(const std::string &fullname, std::vector<T> &&vec_in)
76  {
77  // Check whether vector is already in map.
78  auto it_profileData = profileData_.find(fullname);
79  if (it_profileData != profileData_.end()) {
80  // Replace vector in map.
81  it_profileData->second = std::move(vec_in);
82  } else {
83  // Add vector to map.
84  profileData_.emplace(fullname, std::move(vec_in));
85  }
86  }
87 
88  /// Get number of profile levels for this profile.
89  int getNumProfileLevels() const {return static_cast<int>(numProfileLevels_);}
90 
91  /// Move all values to the associated ProfileDataHandler.
92  void moveValuesToHandler();
93 
94  /// Check this profile is in the expected ObsSpace section (original or extended).
96 
97  private:
98  /// Number of profile levels
99  std::size_t numProfileLevels_;
100 
101  /// Container of each variable in the current profile.
102  std::unordered_map <std::string, boost::variant
103  <std::vector <int>, std::vector <float>, std::vector <std::string>>> profileData_;
104 
105  /// Container of GeoVaLs in the current profile.
106  std::unordered_map <std::string, std::vector <float>> profileGeoVaLs_;
107 
108  /// Container of ObsDiags in the current profile.
109  std::unordered_map <std::string, std::vector <float>> profileObsDiags_;
110 
111  /// Profile data handler
113 
114  /// Names of int variables
115  std::vector <std::string> variableNamesInt_;
116 
117  /// Names of float variables
118  std::vector <std::string> variableNamesFloat_;
119 
120  /// Names of string variables
121  std::vector <std::string> variableNamesString_;
122 
123  /// Names of GeoVaLs
124  std::vector <std::string> variableNamesGeoVaLs_;
125 
126  /// Names of ObsDiags
127  std::vector <std::string> variableNamesObsDiags_;
128  };
129 } // namespace ufo
130 
131 #endif // UFO_PROFILE_PROFILEDATAHOLDER_H_
Retrieve and store data for individual profiles. To do this, first the vector of values in the entire...
Profile data holder class.
std::vector< std::string > variableNamesInt_
Names of int variables.
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.
ProfileDataHolder(ProfileDataHandler &profileDataHandler)
int getNumProfileLevels() const
Get number of profile levels for this profile.
std::vector< float > & getObsDiagVector(const std::string &fullname)
Retrieve an ObsDiag vector if it is present. If not, throw an exception.
void moveValuesToHandler()
Move all values to the associated ProfileDataHandler.
std::vector< T > & get(const std::string &fullname)
Retrieve a vector if it is present. If not, throw an exception.
std::vector< std::string > variableNamesGeoVaLs_
Names of GeoVaLs.
ProfileDataHandler & profileDataHandler_
Profile data handler.
void set(const std::string &fullname, std::vector< T > &&vec_in)
Set values in a vector.
std::size_t numProfileLevels_
Number of profile levels.
void fill(const std::vector< std::string > &variableNamesInt, const std::vector< std::string > &variableNamesFloat, const std::vector< std::string > &variableNamesString, const std::vector< std::string > &variableNamesGeoVaLs, const std::vector< std::string > &variableNamesObsDiags)
Fill profile with data.
std::vector< std::string > variableNamesFloat_
Names of float variables.
std::vector< std::string > variableNamesString_
Names of string variables.
std::unordered_map< std::string, std::vector< float > > profileGeoVaLs_
Container of GeoVaLs in the current profile.
std::vector< float > & getGeoVaLVector(const std::string &fullname)
Retrieve a GeoVaL vector if it is present. If not, throw an exception.
std::vector< std::string > variableNamesObsDiags_
Names of ObsDiags.
void checkObsSpaceSection(ufo::ObsSpaceSection section)
Check this profile is in the expected ObsSpace section (original or extended).
std::unordered_map< std::string, std::vector< float > > profileObsDiags_
Container of ObsDiags in the current profile.
Definition: RunCRTM.h:27