OOPS
ObsAuxControls.h
Go to the documentation of this file.
1 /*
2  * (C) Copyright 2017-2019 UCAR
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 OOPS_BASE_OBSAUXCONTROLS_H_
9 #define OOPS_BASE_OBSAUXCONTROLS_H_
10 
11 #include <iostream>
12 #include <memory>
13 #include <string>
14 #include <vector>
15 
16 #include "oops/base/ObsSpaces.h"
18 #include "oops/util/ConfigFunctions.h"
19 #include "oops/util/Logger.h"
20 #include "oops/util/parameters/Parameters.h"
21 #include "oops/util/Printable.h"
22 
23 namespace oops {
24 
25 // -----------------------------------------------------------------------------
26 /// \brief Holds a vector of ObsAuxControl
27 // -----------------------------------------------------------------------------
28 
29 template <typename OBS>
30 class ObsAuxControls : public util::Printable {
34 
35  public:
36  static const std::string classname() {return "oops::ObsAuxControls";}
37 
38  ObsAuxControls(const ObsSpaces_ &, const eckit::Configuration &);
39  ObsAuxControls(const ObsSpaces_ &, const std::vector<Parameters_> &);
40  explicit ObsAuxControls(const ObsAuxControls &, const bool copy = true);
42 
43 /// Access
44  std::size_t size() const {return auxs_.size();}
45  const ObsAuxControl_ & operator[](const std::size_t ii) const {return *auxs_.at(ii);}
46  ObsAuxControl_ & operator[](const std::size_t ii) {return *auxs_.at(ii);}
47 
48 /// I/O and diagnostics
49  void read(const eckit::Configuration &);
50  void write(const eckit::Configuration &) const;
51  double norm() const;
52 
54 
55  private:
56  void print(std::ostream &) const;
57  std::vector<std::unique_ptr<ObsAuxControl_> > auxs_;
58 };
59 
60 // =============================================================================
61 
62 template<typename OBS>
64  const std::vector<Parameters_> & params)
65  : auxs_(0)
66 {
67  ASSERT(odb.size() == params.size());
68  for (std::size_t jobs = 0; jobs < params.size(); ++jobs) {
69  auxs_.push_back(
70  std::unique_ptr<ObsAuxControl_>(new ObsAuxControl_(odb[jobs], params[jobs])));
71  }
72 }
73 
74 // -----------------------------------------------------------------------------
75 
76 template<typename OBS>
77 ObsAuxControls<OBS>::ObsAuxControls(const ObsSpaces_ & odb, const eckit::Configuration & conf)
78  : ObsAuxControls(odb,
79  // Split conf into subconfigurations, extract the "obs bias" section from each
80  // of them, then validate and deserialize that section into a Parameters_ object
81  validateAndDeserialize<Parameters_>(util::vectoriseAndFilter(conf, "obs bias")))
82 {}
83 
84 // -----------------------------------------------------------------------------
85 
86 template<typename OBS>
87 ObsAuxControls<OBS>::ObsAuxControls(const ObsAuxControls & other, const bool copy)
88  : auxs_(other.size())
89 {
90  Log::trace() << "ObsAuxControls<OBS>::ObsAuxControls copy starting" << std::endl;
91  for (std::size_t jobs = 0; jobs < other.size(); ++jobs) {
92  auxs_[jobs].reset(new ObsAuxControl_(other[jobs], copy));
93  }
94  Log::trace() << "ObsAuxControls<OBS>::ObsAuxControls copy done" << std::endl;
95 }
96 
97 // -----------------------------------------------------------------------------
98 
99 template<typename OBS>
101  Log::trace() << "ObsAuxControls<OBS>::~ObsAuxControls starting" << std::endl;
102  for (std::size_t jobs = 0; jobs < auxs_.size(); ++jobs) auxs_[jobs].reset();
103  Log::trace() << "ObsAuxControls<OBS>::~ObsAuxControls done" << std::endl;
104 }
105 
106 // -----------------------------------------------------------------------------
107 
108 template<typename OBS>
109 void ObsAuxControls<OBS>::read(const eckit::Configuration & conf) {
110  Log::trace() << "ObsAuxControls<OBS>::read starting" << std::endl;
111  std::vector<eckit::LocalConfiguration> obsconfs = conf.getSubConfigurations("observations");
112  ASSERT(obsconfs.size() == auxs_.size());
113  for (std::size_t jobs = 0; jobs < auxs_.size(); ++jobs) {
114  eckit::LocalConfiguration obsauxconf = obsconfs[jobs].getSubConfiguration("obs bias");
115  Parameters_ params;
116  params.validateAndDeserialize(obsauxconf);
117  auxs_[jobs]->read(params);
118  }
119  Log::trace() << "ObsAuxControls<OBS>::read done" << std::endl;
120 }
121 
122 // -----------------------------------------------------------------------------
123 
124 template<typename OBS>
125 void ObsAuxControls<OBS>::write(const eckit::Configuration & conf) const {
126  Log::trace() << "ObsAuxControls<OBS>::write starting" << std::endl;
127  std::vector<eckit::LocalConfiguration> obsconfs = conf.getSubConfigurations("observations");
128  ASSERT(obsconfs.size() == auxs_.size());
129  for (std::size_t jobs = 0; jobs < auxs_.size(); ++jobs) {
130  eckit::LocalConfiguration obsauxconf = obsconfs[jobs].getSubConfiguration("obs bias");
131  Parameters_ params;
132  params.validateAndDeserialize(obsauxconf);
133  auxs_[jobs]->write(params);
134  }
135  Log::trace() << "ObsAuxControls<OBS>::write done" << std::endl;
136 }
137 
138 // -----------------------------------------------------------------------------
139 
140 template<typename OBS>
142  Log::trace() << "ObsAuxControls<OBS>::norm starting" << std::endl;
143  double zz = static_cast<double>(0.0);
144  std::size_t ii = 0;
145  double norm;
146  for (std::size_t jobs = 0; jobs < auxs_.size(); ++jobs) {
147  norm = auxs_[jobs]->norm();
148  if (norm > 0.0) {
149  zz += norm*norm;
150  ++ii;
151  }
152  }
153  Log::trace() << "ObsAuxControls<OBS>::norm done" << std::endl;
154  return std::sqrt(zz/ii);
155 }
156 
157 // -----------------------------------------------------------------------------
158 
159 template<typename OBS>
160 void ObsAuxControls<OBS>::print(std::ostream & os) const {
161  for (const auto & aux : auxs_) {
162  os << *aux << std::endl;
163  }
164 }
165 
166 // -----------------------------------------------------------------------------
167 
168 } // namespace oops
169 
170 #endif // OOPS_BASE_OBSAUXCONTROLS_H_
Auxiliary state related to observations, templated on <OBS>
ObsAuxControl_::Parameters_ Parameters_
Holds a vector of ObsAuxControl.
void read(const eckit::Configuration &)
I/O and diagnostics.
std::vector< std::unique_ptr< ObsAuxControl_ > > auxs_
const ObsAuxControl_ & operator[](const std::size_t ii) const
ObsSpaces< OBS > ObsSpaces_
void write(const eckit::Configuration &) const
void print(std::ostream &) const
ObsAuxControl_::Parameters_ Parameters_
ObsAuxControls(const ObsSpaces_ &, const eckit::Configuration &)
ObsAuxControl< OBS > ObsAuxControl_
double norm() const
std::size_t size() const
Access.
ObsAuxControls & operator=(const ObsAuxControls &)
static const std::string classname()
ObsAuxControl_ & operator[](const std::size_t ii)
std::size_t size() const
Access.
Definition: ObsSpaces.h:61
The namespace for the main oops code.
Definition: TLML95.h:34