IODA Bundle
interface/ObsErrorBase.h
Go to the documentation of this file.
1 /*
2  * (C) Crown 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 OOPS_INTERFACE_OBSERRORBASE_H_
9 #define OOPS_INTERFACE_OBSERRORBASE_H_
10 
11 #include <memory>
12 #include <string>
13 
14 #include "eckit/system/ResourceUsage.h"
15 
19 #include "oops/util/ObjectCounter.h"
20 #include "oops/util/Printable.h"
21 
22 namespace eckit {
23  class Configuration;
24 }
25 
26 namespace oops {
27 
28 namespace interface {
29 
30 // -----------------------------------------------------------------------------
31 /// \brief Base class for OBS-specific implementations of the ObsError interface.
32 ///
33 /// interface::ObsErrorBase overrides oops::ObsErrorBase methods to pass OBS-specific
34 /// implementations of ObsVector to OBS-specific implementations of ObsError.
35 ///
36 /// Note: subclasses need to provide a constructor with the following signature:
37 ///
38 /// ObsErrorBase(const eckit::Configuration &config, OBS::ObsSpace &obsspace,
39 /// const eckit::mpi::Comm &timeComm);
40 ///
41 /// and pass \c timeComm to the constructor of this class.
42 template <typename OBS>
43 class ObsErrorBase : public oops::ObsErrorBase<OBS> {
44  typedef typename OBS::ObsSpace ObsSpace_;
45  typedef typename OBS::ObsVector ObsVector_;
46 
47  public:
48  explicit ObsErrorBase(const eckit::mpi::Comm &timeComm)
49  : timeComm_(timeComm) {}
50 
51  // Overrides of oops::ObsErrorBase methods, converting between oops interface classes and
52  // OBS-specific classes operated upon by OBS-specific implementations of the ObsError interface.
53 
54  void multiply(ObsVector<OBS> &dy) const final {
55  this->multiply(dy.obsvector());
56  }
57 
58  void inverseMultiply(ObsVector<OBS> &dy) const final {
59  this->inverseMultiply(dy.obsvector());
60  }
61 
62  void randomize(ObsVector<OBS> &dy) const final {
63  this->randomize(dy.obsvector());
64  }
65 
66  ObsVector<OBS> obserrors() const final {
67  return ObsVector<OBS>(this->getObsErrors(), timeComm_);
68  }
69 
70  void update(const ObsVector<OBS> &dy) final {
71  this->update(dy.obsvector());
72  }
73 
76  }
77 
78  // The methods below need to be overridden in subclasses (along with save(), getRMSE() and
79  // print(), methods inherited from parent classes that neither take nor return instances of oops
80  // interface classes and therefore are still abstract).
81 
82  /// Multiply a Departure \p dy by \f$R\f$.
83  virtual void multiply(ObsVector_ &dy) const = 0;
84 
85  /// Multiply a Departure \p dy by \f$R^{-1}\f$.
86  virtual void inverseMultiply(ObsVector_ &dy) const = 0;
87 
88  /// Generate a random perturbation in \p dy.
89  virtual void randomize(ObsVector_ &dy) const = 0;
90 
91  /// Return a copy of obs error std. dev. If this ObsVector_ is modified (e.g. by obs filters),
92  /// it should be passed back to update() to ensure the covariance matrix stays consistent.
93  virtual std::unique_ptr<ObsVector_> getObsErrors() const = 0;
94 
95  /// Set the diagonal of the covariance matrix to \p stddev squared.
96  virtual void update(const ObsVector_ &stddev) = 0;
97 
98  /// Return the vector of inverse obs error variances.
99  virtual std::unique_ptr<ObsVector_> getInverseVariance() const = 0;
100 
101  private:
102  const eckit::mpi::Comm & timeComm_;
103 };
104 
105 // =============================================================================
106 
107 /// \brief A subclass of ObsErrorFactory able to create instances of T (a concrete subclass of
108 /// interface::ObsErrorBase<OBS>). Passes OBS::ObsSpace to the constructor of T.
109 template <class OBS, class T>
110 class ObsErrorMaker : public ObsErrorFactory<OBS> {
111  public:
115 
116  explicit ObsErrorMaker(const std::string & name) : ObsErrorFactory_(name) {}
117 
118  private:
119  std::unique_ptr<ObsErrorBase_> make(const eckit::Configuration & conf,
120  const ObsSpace_ & obsspace) override {
121  return std::make_unique<T>(conf, obsspace.obsspace(), obsspace.timeComm());
122  }
123 };
124 
125 // -----------------------------------------------------------------------------
126 
127 } // namespace interface
128 
129 } // namespace oops
130 
131 #endif // OOPS_INTERFACE_OBSERRORBASE_H_
Base class for generic implementations of observation error covariance matrices.
A factory creating instances of concrete subclasses of ObsErrorBase.
Base class for OBS-specific implementations of the ObsError interface.
void randomize(ObsVector< OBS > &dy) const final
Generate random perturbation in dy.
virtual void multiply(ObsVector_ &dy) const =0
Multiply a Departure dy by .
void multiply(ObsVector< OBS > &dy) const final
Multiply a Departure dy by .
virtual std::unique_ptr< ObsVector_ > getObsErrors() const =0
ObsVector< OBS > obserrors() const final
virtual void inverseMultiply(ObsVector_ &dy) const =0
Multiply a Departure dy by .
const eckit::mpi::Comm & timeComm_
ObsErrorBase(const eckit::mpi::Comm &timeComm)
ObsVector< OBS > inverseVariance() const final
Return the vector of inverse obs error variances.
virtual std::unique_ptr< ObsVector_ > getInverseVariance() const =0
Return the vector of inverse obs error variances.
virtual void randomize(ObsVector_ &dy) const =0
Generate a random perturbation in dy.
virtual void update(const ObsVector_ &stddev)=0
Set the diagonal of the covariance matrix to stddev squared.
void update(const ObsVector< OBS > &dy) final
Set the diagonal of the covariance matrix to stddev squared.
void inverseMultiply(ObsVector< OBS > &dy) const final
Multiply a Departure dy by .
A subclass of ObsErrorFactory able to create instances of T (a concrete subclass of interface::ObsErr...
std::unique_ptr< ObsErrorBase_ > make(const eckit::Configuration &conf, const ObsSpace_ &obsspace) override
ObsErrorMaker(const std::string &name)
oops::ObsErrorBase< OBS > ObsErrorBase_
oops::ObsErrorFactory< OBS > ObsErrorFactory_
The namespace for the main oops code.