OOPS
Departures.h
Go to the documentation of this file.
1 /*
2  * (C) Copyright 2009-2016 ECMWF.
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  * In applying this licence, ECMWF does not waive the privileges and immunities
7  * granted to it by virtue of its status as an intergovernmental organisation nor
8  * does it submit to any jurisdiction.
9  */
10 
11 #ifndef OOPS_BASE_DEPARTURES_H_
12 #define OOPS_BASE_DEPARTURES_H_
13 
14 #include <Eigen/Dense>
15 #include <cstddef>
16 #include <iostream>
17 #include <memory>
18 #include <numeric>
19 #include <string>
20 #include <vector>
21 
23 #include "oops/base/ObsSpaces.h"
24 #include "oops/base/ObsVector.h"
26 #include "oops/util/dot_product.h"
27 #include "oops/util/Logger.h"
28 
29 namespace oops {
30 
31 template<typename OBS> class Observations;
32 
33 /// Difference between two observation vectors.
34 /*!
35  * A departure is the difference between two observations.
36  * The archetypal example is \f$ \mathbf{y} - {\cal H}(\mathbf{x}) \f$.
37  *
38  * Keeping an observation space vector here is necessary for the implementation
39  * of generic observation error covariance matrices.
40  */
41 
42 // -----------------------------------------------------------------------------
43 template <typename OBS>
47  template <typename DATA> using ObsData_ = ObsDataVector<OBS, DATA>;
48  template <typename DATA> using ObsDataVec_ = std::vector<std::shared_ptr<ObsData_<DATA>>>;
49 
50  public:
51 /// \brief create Departures for all obs (read from ObsSpace if \p name is specified)
52  explicit Departures(const ObsSpaces_ &, const std::string & name = "");
53 
54 /// Access
55  size_t size() const {return dep_.size();}
56  ObsVector_ & operator[](const size_t ii) {return dep_.at(ii);}
57  const ObsVector_ & operator[](const size_t ii) const {return dep_.at(ii);}
58 
59 // Linear algebra operators
60  Departures & operator+=(const Departures &);
61  Departures & operator-=(const Departures &);
62  Departures & operator*=(const double &);
63  Departures & operator*=(const Departures &);
64  Departures & operator/=(const Departures &);
65  void zero();
66  void ones();
67  void random();
68  void invert();
69  void axpy(const double &, const Departures &);
70  double dot_product_with(const Departures &) const;
71  double rms() const;
72 /// Return number of departures (excluding departures that are masked out)
73  size_t nobs() const;
74 
75 /// Mask out departures where the passed in qc flags are > 0
76  void mask(ObsDataVec_<int>);
77 /// Mask out departures where \p mask has missing values
78  void mask(const Departures & mask);
79 
80 /// Pack departures in an Eigen vector (excluding departures that are masked out)
81  Eigen::VectorXd packEigen(const Departures &) const;
82 /// Size of departures packed into an Eigen vector
83  size_t packEigenSize(const Departures &) const;
84 
85 /// Save departures values
86  void save(const std::string &) const;
87 
88  private:
89  void print(std::ostream &) const;
90 
91 /// Data
92  std::vector<ObsVector_> dep_;
93 };
94 
95 // =============================================================================
96 
97 template<typename OBS>
99  const std::string & name): dep_()
100 {
101  dep_.reserve(obsdb.size());
102  for (size_t jj = 0; jj < obsdb.size(); ++jj) {
103  dep_.emplace_back(obsdb[jj], name);
104  }
105  Log::trace() << "Departures created" << std::endl;
106 }
107 // -----------------------------------------------------------------------------
108 template<typename OBS>
110  for (size_t jj = 0; jj < dep_.size(); ++jj) {
111  dep_[jj] += rhs[jj];
112  }
113  return *this;
114 }
115 // -----------------------------------------------------------------------------
116 template<typename OBS>
118  for (size_t jj = 0; jj < dep_.size(); ++jj) {
119  dep_[jj] -= rhs[jj];
120  }
121  return *this;
122 }
123 // -----------------------------------------------------------------------------
124 template<typename OBS>
126  for (size_t jj = 0; jj < dep_.size(); ++jj) {
127  dep_[jj] *= zz;
128  }
129  return *this;
130 }
131 // -----------------------------------------------------------------------------
132 template<typename OBS>
134  for (size_t jj = 0; jj < dep_.size(); ++jj) {
135  dep_[jj] *= rhs[jj];
136  }
137  return *this;
138 }
139 // -----------------------------------------------------------------------------
140 template<typename OBS>
142  for (size_t jj = 0; jj < dep_.size(); ++jj) {
143  dep_[jj] /= rhs[jj];
144  }
145  return *this;
146 }
147 // -----------------------------------------------------------------------------
148 template<typename OBS>
150  for (size_t jj = 0; jj < dep_.size(); ++jj) {
151  dep_[jj].zero();
152  }
153 }
154 // -----------------------------------------------------------------------------
155 template<typename OBS>
157  for (auto & dep : dep_) {
158  dep.ones();
159  }
160 }
161 // -----------------------------------------------------------------------------
162 template<typename OBS>
164  for (size_t jj = 0; jj < dep_.size(); ++jj) {
165  dep_[jj].random();
166  }
167 }
168 // -----------------------------------------------------------------------------
169 template<typename OBS>
171  for (size_t jj = 0; jj < dep_.size(); ++jj) {
172  dep_[jj].invert();
173  }
174 }
175 // -----------------------------------------------------------------------------
176 template<typename OBS>
177 void Departures<OBS>::axpy(const double & zz, const Departures & rhs) {
178  for (size_t jj = 0; jj < dep_.size(); ++jj) {
179  dep_[jj].axpy(zz, rhs[jj]);
180  }
181 }
182 // -----------------------------------------------------------------------------
183 template<typename OBS>
184 double Departures<OBS>::dot_product_with(const Departures & other) const {
185  double zz = 0.0;
186  for (size_t jj = 0; jj < dep_.size(); ++jj) {
187  zz += dot_product(dep_[jj], other[jj]);
188  }
189  return zz;
190 }
191 // -----------------------------------------------------------------------------
192 template<typename OBS>
193 double Departures<OBS>::rms() const {
194  double zz = 0.0;
195  if (nobs() > 0) zz = sqrt(dot_product_with(*this) / this->nobs());
196  return zz;
197 }
198 // -----------------------------------------------------------------------------
199 template<typename OBS>
200 size_t Departures<OBS>::nobs() const {
201  size_t nobs = 0;
202  for (size_t jj = 0; jj < dep_.size(); ++jj) {
203  nobs += dep_[jj].nobs();
204  }
205  return nobs;
206 }
207 // -----------------------------------------------------------------------------
208 template<typename OBS>
210  for (size_t ii = 0; ii < dep_.size(); ++ii) {
211  dep_[ii].mask(*qcflags[ii]);
212  }
213 }
214 // -----------------------------------------------------------------------------
215 template<typename OBS>
216 void Departures<OBS>::mask(const Departures & mask) {
217  for (size_t ii = 0; ii < dep_.size(); ++ii) {
218  dep_[ii].mask(mask[ii]);
219  }
220 }
221 // -----------------------------------------------------------------------------
222 template <typename OBS>
223 Eigen::VectorXd Departures<OBS>::packEigen(const Departures & mask) const {
224  std::vector<size_t> len(dep_.size());
225  for (size_t idep = 0; idep < dep_.size(); ++idep) {
226  len[idep] = dep_[idep].packEigenSize(mask[idep]);
227  }
228  size_t all_len = std::accumulate(len.begin(), len.end(), 0);
229 
230  Eigen::VectorXd vec(all_len);
231  size_t ii = 0;
232  for (size_t idep = 0; idep < dep_.size(); ++idep) {
233  vec.segment(ii, len[idep]) = dep_[idep].packEigen(mask[idep]);
234  ii += len[idep];
235  }
236  return vec;
237 }
238 // -----------------------------------------------------------------------------
239 template <typename OBS>
240 size_t Departures<OBS>::packEigenSize(const Departures & mask) const {
241  size_t len = 0;
242  for (size_t idep = 0; idep < dep_.size(); ++idep) {
243  len += dep_[idep].packEigenSize(mask[idep]);
244  }
245  return len;
246 }
247 // -----------------------------------------------------------------------------
248 template <typename OBS>
249 void Departures<OBS>::save(const std::string & name) const {
250  for (size_t jj = 0; jj < dep_.size(); ++jj) {
251  dep_[jj].save(name);
252  }
253 }
254 // -----------------------------------------------------------------------------
255 template <typename OBS>
256 void Departures<OBS>::print(std::ostream & os) const {
257  for (size_t jj = 0; jj < dep_.size(); ++jj) {
258  os << dep_[jj] << std::endl;
259  }
260 }
261 // -----------------------------------------------------------------------------
262 } // namespace oops
263 
264 #endif // OOPS_BASE_DEPARTURES_H_
Difference between two observation vectors.
Definition: Departures.h:44
Departures & operator*=(const double &)
Definition: Departures.h:125
std::vector< std::shared_ptr< ObsData_< DATA > >> ObsDataVec_
Definition: Departures.h:48
void save(const std::string &) const
Save departures values.
Definition: Departures.h:249
double dot_product_with(const Departures &) const
Definition: Departures.h:184
double rms() const
Definition: Departures.h:193
void mask(ObsDataVec_< int >)
Mask out departures where the passed in qc flags are > 0.
Definition: Departures.h:209
size_t nobs() const
Return number of departures (excluding departures that are masked out)
Definition: Departures.h:200
Departures & operator/=(const Departures &)
Definition: Departures.h:141
ObsVector< OBS > ObsVector_
Definition: Departures.h:46
size_t size() const
Access.
Definition: Departures.h:55
ObsSpaces< OBS > ObsSpaces_
Definition: Departures.h:45
void axpy(const double &, const Departures &)
Definition: Departures.h:177
Departures(const ObsSpaces_ &, const std::string &name="")
create Departures for all obs (read from ObsSpace if name is specified)
Definition: Departures.h:98
ObsVector_ & operator[](const size_t ii)
Definition: Departures.h:56
void print(std::ostream &) const
Definition: Departures.h:256
std::vector< ObsVector_ > dep_
Data.
Definition: Departures.h:92
Eigen::VectorXd packEigen(const Departures &) const
Pack departures in an Eigen vector (excluding departures that are masked out)
Definition: Departures.h:223
Departures & operator-=(const Departures &)
Definition: Departures.h:117
const ObsVector_ & operator[](const size_t ii) const
Definition: Departures.h:57
Departures & operator+=(const Departures &)
Definition: Departures.h:109
size_t packEigenSize(const Departures &) const
Size of departures packed into an Eigen vector.
Definition: Departures.h:240
Abstract base class for quantities.
ObsDataVector is a vector templated on data type, in the observation space.
std::size_t size() const
Access.
Definition: ObsSpaces.h:61
ObsVector class used in oops; subclass of interface class interface::ObsVector.
The namespace for the main oops code.