OOPS
oops/interface/ObsVector.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_INTERFACE_OBSVECTOR_H_
12 #define OOPS_INTERFACE_OBSVECTOR_H_
13 
14 #include <Eigen/Dense>
15 #include <math.h>
16 #include <memory>
17 #include <ostream>
18 #include <string>
19 #include <utility>
20 
23 #include "oops/util/gatherPrint.h"
24 #include "oops/util/Logger.h"
25 #include "oops/util/ObjectCounter.h"
26 #include "oops/util/Printable.h"
27 #include "oops/util/Timer.h"
28 
29 namespace eckit {
30  class Configuration;
31 }
32 
33 namespace util {
34  class DateTime;
35 }
36 
37 namespace oops {
38 
39 namespace interface {
40 
41 // -----------------------------------------------------------------------------
42 /// \brief Holds observation vector (e.g. vector of observation values, or of computed H(x))
43 // -----------------------------------------------------------------------------
44 
45 template <typename OBS>
46 class ObsVector : public util::Printable,
47  private util::ObjectCounter<ObsVector<OBS> > {
48  typedef typename OBS::ObsVector ObsVector_;
49 
50  public:
51  static const std::string classname() {return "oops::ObsVector";}
52 
53  /// Creates vector from \p obsspace. If \p name is specified, reads the
54  /// specified \p name variable from \p obsspace. Otherwise, zero vector is created.
55  explicit ObsVector(const ObsSpace<OBS> & obsspace, const std::string name = "");
56 
57  /// Wraps an existing ObsVector_.
58  /// This wrapping constructor doesn't need to be implemented in an ObsVector implementation.
59  /// \param obsvector The vector to wrap.
60  explicit ObsVector(std::unique_ptr<ObsVector_> obsvector);
61  /// Copy constructor
62  ObsVector(const ObsVector &);
63  /// Destructor (defined explicitly for timing and tracing)
64  ~ObsVector();
65 
66  /// Accessor
67  ObsVector_ & obsvector() {return *data_;}
68  /// Const accessor
69  const ObsVector_ & obsvector() const {return *data_;}
70 
71  /// Linear algebra operators
72  ObsVector & operator = (const ObsVector &);
73  ObsVector & operator*= (const double &);
74  ObsVector & operator+= (const ObsVector &);
75  ObsVector & operator-= (const ObsVector &);
76  ObsVector & operator*= (const ObsVector &);
77  ObsVector & operator/= (const ObsVector &);
78  /// Add \p zz * \p rhs to the ObsVector.
79  void axpy(const double & zz, const ObsVector & rhs);
80 
81  /// Pack observations local to this MPI task into an Eigen vector
82  /// (excluding vector elements that are masked out: where \p mask is a missing value)
83  Eigen::VectorXd packEigen(const ObsVector & mask) const;
84  /// Number of non-masked out observations local to this MPI task
85  /// (size of an Eigen vector returned by `packEigen`)
86  size_t packEigenSize(const ObsVector & mask) const;
87 
88  /// Zero out this ObsVector
89  void zero();
90  /// Set this ObsVector to ones (used in tests)
91  void ones();
92  /// Set each value in this ObsVector to its inverse
93  void invert();
94  /// Set each value in this ObsVector to a random value
95  void random();
96 
97  /// Return the dot product between this ObsVector and another one \p other
98  double dot_product_with(const ObsVector & other) const;
99  /// Return this ObsVector rms
100  double rms() const;
101  /// Mask out elements of the vector where \p mask is > 0
102  void mask(const ObsDataVector<OBS, int> & mask);
103  /// Mask out elements of the vector where \p mask is a missing value
104  void mask(const ObsVector & mask);
105  /// Assignment operator from \p rhs ObsDataVector<OBS, float>
107 
108  /// Save this ObsVector as group \p name in the ObsSpace
109  void save(const std::string &) const;
110  /// Fill ObsVector with data with group \p name from the associated ObsSpace
111  void read(const std::string &);
112 
113  /// Number of non-masked out observations (across all MPI tasks)
114  unsigned int nobs() const;
115 
116  private:
117  void print(std::ostream &) const;
118  std::unique_ptr<ObsVector_> data_;
119 };
120 
121 // -----------------------------------------------------------------------------
122 template <typename OBS>
123 ObsVector<OBS>::ObsVector(const ObsSpace<OBS> & os, const std::string name)
124  : data_() {
125  Log::trace() << "ObsVector<OBS>::ObsVector starting " << name << std::endl;
126  util::Timer timer(classname(), "ObsVector");
127  data_.reset(new ObsVector_(os.obsspace(), name));
128  this->setObjectSize(data_->size() * sizeof(double));
129  Log::trace() << "ObsVector<OBS>::ObsVector done" << std::endl;
130 }
131 // -----------------------------------------------------------------------------
132 template <typename OBS>
133 ObsVector<OBS>::ObsVector(std::unique_ptr<ObsVector_> obsvector)
134  : data_(std::move(obsvector)) {
135  Log::trace() << "ObsVector<OBS>::ObsVector starting " << std::endl;
136  util::Timer timer(classname(), "ObsVector");
137  this->setObjectSize(data_->size() * sizeof(double));
138  Log::trace() << "ObsVector<OBS>::ObsVector done" << std::endl;
139 }
140 // -----------------------------------------------------------------------------
141 template <typename OBS>
142 ObsVector<OBS>::ObsVector(const ObsVector & other): data_() {
143  Log::trace() << "ObsVector<OBS>::ObsVector starting" << std::endl;
144  util::Timer timer(classname(), "ObsVector");
145  data_.reset(new ObsVector_(*other.data_));
146  this->setObjectSize(data_->size() * sizeof(double));
147  Log::trace() << "ObsVector<OBS>::ObsVector done" << std::endl;
148 }
149 // -----------------------------------------------------------------------------
150 template <typename OBS>
152  Log::trace() << "ObsVector<OBS>::~ObsVector starting" << std::endl;
153  util::Timer timer(classname(), "~ObsVector");
154  data_.reset();
155  Log::trace() << "ObsVector<OBS>::~ObsVector done" << std::endl;
156 }
157 // -----------------------------------------------------------------------------
158 template <typename OBS>
160  Log::trace() << "ObsVector<OBS>::operator= starting" << std::endl;
161  util::Timer timer(classname(), "operator=");
162 
163  *data_ = *rhs.data_;
164 
165  Log::trace() << "ObsVector<OBS>::operator= done" << std::endl;
166  return *this;
167 }
168 // -----------------------------------------------------------------------------
169 template <typename OBS>
171  Log::trace() << "ObsVector<OBS>::operator*= starting" << std::endl;
172  util::Timer timer(classname(), "operator*=");
173 
174  *data_ *= zz;
175 
176  Log::trace() << "ObsVector<OBS>::operator*= done" << std::endl;
177  return *this;
178 }
179 // -----------------------------------------------------------------------------
180 template <typename OBS>
182  Log::trace() << "ObsVector<OBS>::operator+= starting" << std::endl;
183  util::Timer timer(classname(), "operator+=");
184 
185  *data_ += *rhs.data_;
186 
187  Log::trace() << "ObsVector<OBS>::operator+= done" << std::endl;
188  return *this;
189 }
190 // -----------------------------------------------------------------------------
191 template <typename OBS>
193  Log::trace() << "ObsVector<OBS>::operator-= starting" << std::endl;
194  util::Timer timer(classname(), "operator-=");
195 
196  *data_ -= *rhs.data_;
197 
198  Log::trace() << "ObsVector<OBS>::operator-= done" << std::endl;
199  return *this;
200 }
201 // -----------------------------------------------------------------------------
202 template <typename OBS>
204  Log::trace() << "ObsVector<OBS>::operator*= starting" << std::endl;
205  util::Timer timer(classname(), "operator*=");
206 
207  *data_ *= *rhs.data_;
208 
209  Log::trace() << "ObsVector<OBS>::operator*= done" << std::endl;
210  return *this;
211 }
212 // -----------------------------------------------------------------------------
213 template <typename OBS>
215  Log::trace() << "ObsVector<OBS>::operator/= starting" << std::endl;
216  util::Timer timer(classname(), "operator/=");
217 
218  *data_ /= *rhs.data_;
219 
220  Log::trace() << "ObsVector<OBS>::operator/= done" << std::endl;
221  return *this;
222 }
223 // -----------------------------------------------------------------------------
224 template <typename OBS>
226  Log::trace() << "ObsVector<OBS>::zero starting" << std::endl;
227  util::Timer timer(classname(), "zero");
228 
229  data_->zero();
230 
231  Log::trace() << "ObsVector<OBS>::zero done" << std::endl;
232 }
233 // -----------------------------------------------------------------------------
234 template <typename OBS>
236  Log::trace() << "ObsVector<OBS>::ones starting" << std::endl;
237  util::Timer timer(classname(), "ones");
238 
239  data_->ones();
240 
241  Log::trace() << "ObsVector<OBS>::ones done" << std::endl;
242 }
243 // -----------------------------------------------------------------------------
244 template <typename OBS>
245 void ObsVector<OBS>::axpy(const double & zz, const ObsVector & rhs) {
246  Log::trace() << "ObsVector<OBS>::axpy starting" << std::endl;
247  util::Timer timer(classname(), "axpy");
248 
249  data_->axpy(zz, *rhs.data_);
250 
251  Log::trace() << "ObsVector<OBS>::axpy done" << std::endl;
252 }
253 // -----------------------------------------------------------------------------
254 template <typename OBS>
256  Log::trace() << "ObsVector<OBS>::invert starting" << std::endl;
257  util::Timer timer(classname(), "invert");
258 
259  data_->invert();
260 
261  Log::trace() << "ObsVector<OBS>::invert done" << std::endl;
262 }
263 // -----------------------------------------------------------------------------
264 template <typename OBS>
266  Log::trace() << "ObsVector<OBS>::random starting" << std::endl;
267  util::Timer timer(classname(), "random");
268 
269  data_->random();
270 
271  Log::trace() << "ObsVector<OBS>::random done" << std::endl;
272 }
273 // -----------------------------------------------------------------------------
274 template <typename OBS>
275 double ObsVector<OBS>::dot_product_with(const ObsVector & other) const {
276  Log::trace() << "ObsVector<OBS>::dot_product starting" << std::endl;
277  util::Timer timer(classname(), "dot_product");
278 
279  double zz = data_->dot_product_with(*other.data_);
280 
281  Log::trace() << "ObsVector<OBS>::dot_product done" << std::endl;
282  return zz;
283 }
284 // -----------------------------------------------------------------------------
285 template <typename OBS>
287  Log::trace() << "ObsVector<OBS>::mask starting" << std::endl;
288  util::Timer timer(classname(), "mask");
289  data_->mask(qc.obsdatavector());
290  Log::trace() << "ObsVector<OBS>::mask done" << std::endl;
291 }
292 // -----------------------------------------------------------------------------
293 template <typename OBS>
294 void ObsVector<OBS>::mask(const ObsVector & mask) {
295  Log::trace() << "ObsVector<OBS>::mask(ObsVector) starting" << std::endl;
296  util::Timer timer(classname(), "mask(ObsVector)");
297  data_->mask(mask.obsvector());
298  Log::trace() << "ObsVector<OBS>::mask(ObsVector) done" << std::endl;
299 }
300 // -----------------------------------------------------------------------------
301 template <typename OBS>
303  Log::trace() << "ObsVector<OBS>::operator= starting" << std::endl;
304  util::Timer timer(classname(), "operator=");
305  *data_ = rhs.obsdatavector();
306  Log::trace() << "ObsVector<OBS>::operator= done" << std::endl;
307  return *this;
308 }
309 // -----------------------------------------------------------------------------
310 template <typename OBS>
311 double ObsVector<OBS>::rms() const {
312  Log::trace() << "ObsVector<OBS>::rms starting" << std::endl;
313  util::Timer timer(classname(), "rms");
314 
315  double zz = data_->rms();
316 
317  Log::trace() << "ObsVector<OBS>::rms done" << std::endl;
318  return zz;
319 }
320 // -----------------------------------------------------------------------------
321 template <typename OBS>
322 unsigned int ObsVector<OBS>::nobs() const {
323  int nobs = data_->nobs();
324  return nobs;
325 }
326 // -----------------------------------------------------------------------------
327 template <typename OBS>
328 void ObsVector<OBS>::print(std::ostream & os) const {
329  Log::trace() << "ObsVector<OBS>::print starting" << std::endl;
330  util::Timer timer(classname(), "print");
331  os << *data_;
332  Log::trace() << "ObsVector<OBS>::print done" << std::endl;
333 }
334 // -----------------------------------------------------------------------------
335 template <typename OBS>
336 void ObsVector<OBS>::save(const std::string & name) const {
337  Log::trace() << "ObsVector<OBS>::save starting " << name << std::endl;
338  util::Timer timer(classname(), "save");
339 
340  data_->save(name);
341 
342  Log::trace() << "ObsVector<OBS>::save done" << std::endl;
343 }
344 // -----------------------------------------------------------------------------
345 template <typename OBS>
346 Eigen::VectorXd ObsVector<OBS>::packEigen(const ObsVector & mask) const {
347  Log::trace() << "ObsVector<OBS>::packEigen starting " << std::endl;
348  util::Timer timer(classname(), "packEigen");
349 
350  Eigen::VectorXd vec = data_->packEigen(mask.obsvector());
351 
352  Log::trace() << "ObsVector<OBS>::packEigen done" << std::endl;
353  return vec;
354 }
355 // -----------------------------------------------------------------------------
356 template <typename OBS>
357 size_t ObsVector<OBS>::packEigenSize(const ObsVector & mask) const {
358  Log::trace() << "ObsVector<OBS>::packEigenSize starting " << std::endl;
359  util::Timer timer(classname(), "packEigenSize");
360 
361  size_t len = data_->packEigenSize(mask.obsvector());
362 
363  Log::trace() << "ObsVector<OBS>::packEigen done" << std::endl;
364  return len;
365 }
366 // -----------------------------------------------------------------------------
367 template <typename OBS>
368 void ObsVector<OBS>::read(const std::string & name) {
369  Log::trace() << "ObsVector<OBS>::read starting " << name << std::endl;
370  util::Timer timer(classname(), "read");
371 
372  data_->read(name);
373 
374  Log::trace() << "ObsVector<OBS>::read done" << std::endl;
375 }
376 // -----------------------------------------------------------------------------
377 
378 } // namespace interface
379 
380 } // namespace oops
381 
382 #endif // OOPS_INTERFACE_OBSVECTOR_H_
ObsDataVector is a vector templated on data type, in the observation space.
ObsDataVec_ & obsdatavector()
Accessor to the data.
ObsSpace_ & obsspace() const
Interfacing.
Holds observation vector (e.g. vector of observation values, or of computed H(x))
void ones()
Set this ObsVector to ones (used in tests)
void print(std::ostream &) const
double rms() const
Return this ObsVector rms.
Eigen::VectorXd packEigen(const ObsVector &mask) const
const ObsVector_ & obsvector() const
Const accessor.
ObsVector & operator-=(const ObsVector &)
void mask(const ObsDataVector< OBS, int > &mask)
Mask out elements of the vector where mask is > 0.
ObsVector & operator+=(const ObsVector &)
unsigned int nobs() const
Number of non-masked out observations (across all MPI tasks)
ObsVector & operator*=(const double &)
static const std::string classname()
std::unique_ptr< ObsVector_ > data_
ObsVector_ & obsvector()
Accessor.
double dot_product_with(const ObsVector &other) const
Return the dot product between this ObsVector and another one other.
ObsVector & operator/=(const ObsVector &)
void random()
Set each value in this ObsVector to a random value.
size_t packEigenSize(const ObsVector &mask) const
~ObsVector()
Destructor (defined explicitly for timing and tracing)
void save(const std::string &) const
Save this ObsVector as group name in the ObsSpace.
ObsVector & operator=(const ObsVector &)
Linear algebra operators.
void read(const std::string &)
Fill ObsVector with data with group name from the associated ObsSpace.
void axpy(const double &zz, const ObsVector &rhs)
Add zz * rhs to the ObsVector.
void invert()
Set each value in this ObsVector to its inverse.
void zero()
Zero out this ObsVector.
ObsVector(const ObsSpace< OBS > &obsspace, const std::string name="")
Definition: FieldL95.h:22
The namespace for the main oops code.
Definition: TLML95.h:34