OOPS
ObsLocalizationBase.h
Go to the documentation of this file.
1 /*
2  * (C) Copyright 2020-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 OOPS_BASE_OBSLOCALIZATIONBASE_H_
9 #define OOPS_BASE_OBSLOCALIZATIONBASE_H_
10 
11 #include <map>
12 #include <memory>
13 #include <string>
14 #include <boost/noncopyable.hpp>
15 
16 #include "eckit/config/Configuration.h"
17 #include "oops/base/ObsVector.h"
20 #include "oops/util/Printable.h"
21 
22 namespace oops {
23 
24 /// Base class for observation-space localization.
25 /// Defines the interfaces for observation space localization.
26 /// Use this class as a base class for OBS- and MODEL-specific implementations.
27 template<typename MODEL, typename OBS>
28 class ObsLocalizationBase : public util::Printable,
29  private boost::noncopyable {
30  typedef typename MODEL::GeometryIterator GeometryIterator_;
31  typedef typename OBS::ObsVector ObsVector_;
32  public:
33  ObsLocalizationBase() = default;
34  virtual ~ObsLocalizationBase() = default;
35 
36  /// compute obs-space localization: fill \p locfactor with observation-space
37  /// localization values between observations and \p point in model-space.
38  /// Set \p locfactor to missing value for observations that are not local.
39  /// Method used in oops. Calls `computeLocalization` abstract method, and
40  /// passes OBS- and MODEL-specific classes to the OBS- and MODEL-specific
41  /// implementations of ObsLocalization.
43  ObsVector<OBS> & locfactor) const {
44  computeLocalization(point.geometryiter(), locfactor.obsvector());
45  }
46 
47  /// compute obs-space localization: fill \p locfactor with observation-space
48  /// localization values between observations and \p point in model-space.
49  /// Set \p locfactor to missing value for observations that are not local.
50  virtual void computeLocalization(const GeometryIterator_ & point,
51  ObsVector_ & locfactor) const = 0;
52 };
53 
54 // =============================================================================
55 
56 /// ObsLocalization Factory
57 template <typename MODEL, typename OBS>
60  public:
61  static std::unique_ptr<ObsLocalizationBase<MODEL, OBS>> create(const eckit::Configuration &,
62  const ObsSpace_ &);
63  protected:
64  explicit ObsLocalizationFactory(const std::string &);
65  private:
66  virtual ObsLocalizationBase<MODEL, OBS> * make(const eckit::Configuration &,
67  const ObsSpace_ &) = 0;
68  static std::map < std::string, ObsLocalizationFactory<MODEL, OBS> * > & getMakers() {
69  static std::map < std::string, ObsLocalizationFactory<MODEL, OBS> * > makers_;
70  return makers_;
71  }
72 };
73 
74 // -----------------------------------------------------------------------------
75 
76 template<class MODEL, class OBS, class T>
77 class ObsLocalizationMaker : public ObsLocalizationFactory<MODEL, OBS> {
79  virtual ObsLocalizationBase<MODEL, OBS> * make(const eckit::Configuration & conf,
80  const ObsSpace_ & obspace)
81  { return new T(conf, obspace.obsspace()); }
82  public:
83  explicit ObsLocalizationMaker(const std::string & name) :
84  ObsLocalizationFactory<MODEL, OBS>(name) {}
85 };
86 
87 // -----------------------------------------------------------------------------
88 
89 template <typename MODEL, typename OBS>
91  if (getMakers().find(name) != getMakers().end()) {
92  throw std::runtime_error(name + " already registered in obs localization factory.");
93  }
94  getMakers()[name] = this;
95 }
96 
97 // -----------------------------------------------------------------------------
98 
99 template <typename MODEL, typename OBS>
100 std::unique_ptr<ObsLocalizationBase<MODEL, OBS>> ObsLocalizationFactory<MODEL, OBS>::create(
101  const eckit::Configuration & conf, const ObsSpace_ & obspace) {
102  Log::trace() << "ObsLocalizationBase<MODEL, OBS>::create starting" << std::endl;
103  const std::string id = conf.getString("localization method");
104  typename std::map<std::string, ObsLocalizationFactory<MODEL, OBS>*>::iterator
105  jloc = getMakers().find(id);
106  if (jloc == getMakers().end()) {
107  throw std::runtime_error(id + " does not exist in obs localization factory.");
108  }
109  std::unique_ptr<ObsLocalizationBase<MODEL, OBS>> ptr(jloc->second->make(conf, obspace));
110  Log::trace() << "ObsLocalizationBase<MODEL, OBS>::create done" << std::endl;
111  return ptr;
112 }
113 
114 // -----------------------------------------------------------------------------
115 
116 } // namespace oops
117 
118 #endif // OOPS_BASE_OBSLOCALIZATIONBASE_H_
const GeometryIterator_ & geometryiter() const
Interfacing.
MODEL::GeometryIterator GeometryIterator_
void computeLocalization(const GeometryIterator< MODEL > &point, ObsVector< OBS > &locfactor) const
virtual ~ObsLocalizationBase()=default
virtual void computeLocalization(const GeometryIterator_ &point, ObsVector_ &locfactor) const =0
ObsLocalization Factory.
virtual ObsLocalizationBase< MODEL, OBS > * make(const eckit::Configuration &, const ObsSpace_ &)=0
ObsLocalizationFactory(const std::string &)
static std::unique_ptr< ObsLocalizationBase< MODEL, OBS > > create(const eckit::Configuration &, const ObsSpace_ &)
static std::map< std::string, ObsLocalizationFactory< MODEL, OBS > * > & getMakers()
ObsLocalizationMaker(const std::string &name)
virtual ObsLocalizationBase< MODEL, OBS > * make(const eckit::Configuration &conf, const ObsSpace_ &obspace)
ObsSpace_ & obsspace() const
Interfacing.
ObsVector class used in oops; subclass of interface class interface::ObsVector.
ObsVector_ & obsvector()
Accessor.
The namespace for the main oops code.