UFO
LinearObsOperatorBase.h
Go to the documentation of this file.
1 /*
2  * (C) Copyright 2017-2021 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 UFO_LINEAROBSOPERATORBASE_H_
9 #define UFO_LINEAROBSOPERATORBASE_H_
10 
11 #include <map>
12 #include <memory>
13 #include <string>
14 #include <vector>
15 
16 #include <boost/noncopyable.hpp>
17 
18 #include "eckit/config/Configuration.h"
19 #include "ioda/ObsSpace.h"
20 #include "oops/base/Variables.h"
21 #include "oops/util/AssociativeContainers.h"
22 #include "oops/util/parameters/ConfigurationParameter.h"
23 #include "oops/util/parameters/HasParameters_.h"
24 #include "oops/util/parameters/Parameters.h"
25 #include "oops/util/parameters/ParametersOrConfiguration.h"
26 #include "oops/util/parameters/RequiredPolymorphicParameter.h"
27 #include "oops/util/Printable.h"
29 
30 namespace ioda {
31 class ObsVector;
32 }
33 
34 namespace ufo {
35 class GeoVaLs;
36 class ObsDiagnostics;
37 
38 // -----------------------------------------------------------------------------
39 /// Base class for linear observation operators
40 ///
41 /// Note: subclasses can opt to extract their settings either from
42 /// a Configuration object or from a subclass of ObsOperatorParametersBase.
43 ///
44 /// In the former case, they should provide a constructor with the following signature:
45 ///
46 /// SubclassName(const ioda::ObsSpace &, const eckit::Configuration &);
47 ///
48 /// In the latter case, the implementer should first define a subclass of ObsOperatorParametersBase
49 /// holding the settings of the operator in question. The LinearObsOperatorBase subclass should
50 /// then typedef `Parameters_` to the name of the ObsOperatorParametersBase subclass and provide a
51 /// constructor with the following signature:
52 ///
53 /// SubclassName(const ioda::ObsSpace &, const Parameters_ &);
54 class LinearObsOperatorBase : public util::Printable,
55  private boost::noncopyable {
56  public:
57  explicit LinearObsOperatorBase(const ioda::ObsSpace & odb)
58  : odb_(odb) {}
60 
61 /// Obs Operator
62  virtual void setTrajectory(const GeoVaLs &, ObsDiagnostics &) = 0;
63  virtual void simulateObsTL(const GeoVaLs &, ioda::ObsVector &) const = 0;
64  virtual void simulateObsAD(GeoVaLs &, const ioda::ObsVector &) const = 0;
65 
66 /// Operator input required from Model
67  virtual const oops::Variables & requiredVars() const = 0;
68 
69 /// \brief List of variables simulated by this operator.
70 ///
71 /// The default implementation returns the list of all simulated variables in the ObsSpace.
72  virtual oops::Variables simulatedVars() const;
73 
74 /// \brief The space containing the observations to be simulated by this operator.
75  const ioda::ObsSpace &obsspace() const { return odb_; }
76 
77  private:
78  virtual void print(std::ostream &) const = 0;
79 
80  private:
81  const ioda::ObsSpace & odb_;
82 };
83 
84 // -----------------------------------------------------------------------------
85 
87 
88 // -----------------------------------------------------------------------------
89 
90 /// \brief Contains a polymorphic parameter holding an instance of a subclass of
91 /// ObsOperatorParametersBase.
92 class LinearObsOperatorParametersWrapper : public oops::Parameters {
93  OOPS_CONCRETE_PARAMETERS(LinearObsOperatorParametersWrapper, Parameters)
94  public:
95  /// After deserialization, holds an instance of a subclass of ObsOperatorParametersBase
96  /// controlling the behavior of a linear observation operator. The type of the subclass is
97  /// determined by the value of the "name" key in the Configuration object from which this object
98  /// is deserialized.
99  oops::RequiredPolymorphicParameter<ObsOperatorParametersBase, LinearObsOperatorFactory>
100  operatorParameters{"name", this};
101 };
102 
103 // -----------------------------------------------------------------------------
104 
105 /// Linear obs operator factory
107  public:
108  /// \brief Create and return a new linear observation operator.
109  ///
110  /// The type of the operator is determined by the `name` attribute of \p params. \p params must
111  /// be an instance of the subclass of ObsOperatorParametersBase associated with that operator,
112  /// otherwise an exception will be thrown.
113  static LinearObsOperatorBase * create(const ioda::ObsSpace &, const ObsOperatorParametersBase &);
114 
115  /// \brief Create and return an instance of the subclass of ObsOperatorParametersBase
116  /// storing parameters of linear observation operators of the specified type.
117  static std::unique_ptr<ObsOperatorParametersBase> createParameters(
118  const std::string &name);
119 
120  /// \brief Return the names of all operators that can be created by one of the registered makers.
121  static std::vector<std::string> getMakerNames() {
122  return oops::keys(getMakers());
123  }
124 
125  virtual ~LinearObsOperatorFactory() = default;
126 
127  protected:
128  /// \brief Register a maker able to create linear observation operators of type \p name.
129  explicit LinearObsOperatorFactory(const std::string &name);
130 
131  private:
132  virtual LinearObsOperatorBase * make(const ioda::ObsSpace &,
133  const ObsOperatorParametersBase &) = 0;
134 
135  virtual std::unique_ptr<ObsOperatorParametersBase> makeParameters() const = 0;
136 
137  static std::map < std::string, LinearObsOperatorFactory * > & getMakers() {
138  static std::map < std::string, LinearObsOperatorFactory * > makers_;
139  return makers_;
140  }
141 };
142 
143 // -----------------------------------------------------------------------------
144 
145 template<class T>
147  /// Defined as T::Parameters_ if T defines a Parameters_ type; otherwise as
148  /// GenericObsOperatorParameters.
149  typedef oops::TParameters_IfAvailableElseFallbackType_t<T, GenericObsOperatorParameters>
151 
152  LinearObsOperatorBase * make(const ioda::ObsSpace & odb,
153  const ObsOperatorParametersBase & params) override {
154  const auto &stronglyTypedParams = dynamic_cast<const Parameters_&>(params);
155  return new T(odb,
156  oops::parametersOrConfiguration<oops::HasParameters_<T>::value>(
157  stronglyTypedParams));
158  }
159 
160  std::unique_ptr<ObsOperatorParametersBase> makeParameters() const override {
161  return std::make_unique<Parameters_>();
162  }
163 
164  public:
165  explicit LinearObsOperatorMaker(const std::string & name) : LinearObsOperatorFactory(name) {}
166 };
167 
168 // -----------------------------------------------------------------------------
169 
170 } // namespace ufo
171 
172 #endif // UFO_LINEAROBSOPERATORBASE_H_
GeoVaLs: geophysical values at locations.
virtual void setTrajectory(const GeoVaLs &, ObsDiagnostics &)=0
Obs Operator.
virtual void simulateObsTL(const GeoVaLs &, ioda::ObsVector &) const =0
virtual oops::Variables simulatedVars() const
List of variables simulated by this operator.
LinearObsOperatorBase(const ioda::ObsSpace &odb)
const ioda::ObsSpace & odb_
const ioda::ObsSpace & obsspace() const
The space containing the observations to be simulated by this operator.
virtual void simulateObsAD(GeoVaLs &, const ioda::ObsVector &) const =0
virtual void print(std::ostream &) const =0
virtual const oops::Variables & requiredVars() const =0
Operator input required from Model.
Linear obs operator factory.
virtual ~LinearObsOperatorFactory()=default
virtual LinearObsOperatorBase * make(const ioda::ObsSpace &, const ObsOperatorParametersBase &)=0
static std::unique_ptr< ObsOperatorParametersBase > createParameters(const std::string &name)
Create and return an instance of the subclass of ObsOperatorParametersBase storing parameters of line...
LinearObsOperatorFactory(const std::string &name)
Register a maker able to create linear observation operators of type name.
static std::vector< std::string > getMakerNames()
Return the names of all operators that can be created by one of the registered makers.
virtual std::unique_ptr< ObsOperatorParametersBase > makeParameters() const =0
static std::map< std::string, LinearObsOperatorFactory * > & getMakers()
static LinearObsOperatorBase * create(const ioda::ObsSpace &, const ObsOperatorParametersBase &)
Create and return a new linear observation operator.
oops::TParameters_IfAvailableElseFallbackType_t< T, GenericObsOperatorParameters > Parameters_
LinearObsOperatorBase * make(const ioda::ObsSpace &odb, const ObsOperatorParametersBase &params) override
LinearObsOperatorMaker(const std::string &name)
std::unique_ptr< ObsOperatorParametersBase > makeParameters() const override
Contains a polymorphic parameter holding an instance of a subclass of ObsOperatorParametersBase.
oops::RequiredPolymorphicParameter< ObsOperatorParametersBase, LinearObsOperatorFactory > operatorParameters
Base class of classes storing configuration parameters of specific observation operators and linear o...
Forward declarations.
Definition: ObsAodExt.h:25
Definition: RunCRTM.h:27