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