IODA Bundle
Observer.h
Go to the documentation of this file.
1 /*
2  * (C) Copyright 2020 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 #ifndef OOPS_BASE_OBSERVER_H_
8 #define OOPS_BASE_OBSERVER_H_
9 
10 #include <algorithm>
11 #include <memory>
12 #include <string>
13 #include <vector>
14 
15 #include "eckit/config/LocalConfiguration.h"
16 
17 #include "oops/base/Geometry.h"
18 #include "oops/base/GetValuePost.h"
19 #include "oops/base/ObsError.h"
20 #include "oops/base/ObsFilters.h"
21 #include "oops/base/Variables.h"
22 #include "oops/interface/GeoVaLs.h"
30 #include "oops/util/Logger.h"
31 #include "oops/util/parameters/Parameter.h"
32 #include "oops/util/parameters/Parameters.h"
33 #include "oops/util/parameters/RequiredParameter.h"
34 
35 namespace oops {
36 
37 template <typename OBS>
38 class ObserverParameters : public Parameters {
39  OOPS_CONCRETE_PARAMETERS(ObserverParameters, Parameters)
40 
41  public:
42  oops::RequiredParameter<eckit::LocalConfiguration> obsOperator{"obs operator", this};
43  oops::Parameter<std::vector<ObsFilterParametersWrapper<OBS>>> obsFilters{"obs filters", {}, this};
44  oops::Parameter<eckit::LocalConfiguration> getValues{
45  "get values", eckit::LocalConfiguration(), this};
46  oops::Parameter<eckit::LocalConfiguration> linearGetValues{
47  "linear get values", eckit::LocalConfiguration(), this};
48 };
49 
50 // -----------------------------------------------------------------------------
51 
52 /// \brief Computes observation operator, applying bias correction and QC filters
53 template <typename MODEL, typename OBS>
54 class Observer {
68 
69  public:
70 /// \brief Initializes ObsOperators, Locations, and QC data
71  Observer(const ObsSpace_ &, const Parameters_ &);
72 
73 /// \brief Initializes variables, obs bias, obs filters (could be different for
74 /// different iterations
75  std::shared_ptr<GetValPost_> initialize(const Geometry_ &, const ObsAuxCtrl_ &,
76  ObsError_ &, const eckit::Configuration &);
77 
78 /// \brief Computes H(x) from the filled in GeoVaLs
79  void finalize(ObsVector_ &);
80 
81  private:
83  const ObsSpace_ & obspace_; // ObsSpace used in H(x)
84  std::unique_ptr<ObsOperator_> obsop_; // Obs operator
85  std::unique_ptr<Locations_> locations_; // locations
86  const ObsAuxCtrl_ * ybias_; // Obs bias
87  ObsError_ * Rmat_; // Obs error covariance
88  std::unique_ptr<ObsFilters_> filters_; // QC filters
89  std::unique_ptr<ObsVector_> obserr_; // Obs error std dev
90  std::shared_ptr<GetValPost_> getvals_; // Postproc passed to the model during integration.
91  std::shared_ptr<ObsDataInt_> qcflags_; // QC flags (should not be a pointer)
93  std::unique_ptr<eckit::LocalConfiguration> iterconf_;
94 };
95 
96 // -----------------------------------------------------------------------------
97 
98 template <typename MODEL, typename OBS>
100  : parameters_(params), obspace_(obspace), obsop_(), locations_(),
101  ybias_(nullptr), filters_(), qcflags_(), initialized_(false)
102 {
103  Log::trace() << "Observer::Observer start" << std::endl;
104  /// Set up observation operators
107 
108  Log::trace() << "Observer::Observer done" << std::endl;
109 }
110 
111 // -----------------------------------------------------------------------------
112 
113 template <typename MODEL, typename OBS>
114 std::shared_ptr<GetValuePost<MODEL, OBS>>
116  ObsError_ & R, const eckit::Configuration & conf) {
117  Log::trace() << "Observer<MODEL, OBS>::initialize start" << std::endl;
118 // Save information for finalize
119  iterconf_.reset(new eckit::LocalConfiguration(conf));
120  ybias_ = &ybias;
121  Rmat_ = &R;
122  obserr_.reset(new ObsVector_(Rmat_->obserrors()));
123 
124 // Set up QC filters and run preprocess
125  const int iterfilt = iterconf_->getInt("iteration", 0);
126  filters_.reset(new ObsFilters_(obspace_, parameters_.obsFilters,
127  qcflags_, *obserr_, iterfilt));
128  filters_->preProcess();
129 
130  locations_.reset(new Locations_(obsop_->locations()));
131 
132 // Set up variables that will be requested from the model
133  Variables geovars;
134  geovars += obsop_->requiredVars();
135  geovars += ybias_->requiredVars();
136  geovars += filters_->requiredVars();
137 
138 // Set up GetValues
139  getvals_.reset(new GetValPost_(parameters_.getValues, geom, obspace_.windowStart(),
140  obspace_.windowEnd(), *locations_, geovars));
141 
142  initialized_ = true;
143  Log::trace() << "Observer<MODEL, OBS>::initialize done" << std::endl;
144  return getvals_;
145 }
146 
147 // -----------------------------------------------------------------------------
148 
149 template <typename MODEL, typename OBS>
151  oops::Log::trace() << "Observer<MODEL, OBS>::finalize start" << std::endl;
152  ASSERT(initialized_);
153 
154  // GetValues releases GeoVaLs, Observer takes ownership
155  std::unique_ptr<GeoVaLs_> geovals = getvals_->releaseGeoVaLs();
156 
157  /// Call prior filters
158  filters_->priorFilter(*geovals);
159 
160  /// Setup diagnostics
161  Variables vars;
162  vars += filters_->requiredHdiagnostics();
163  vars += ybias_->requiredHdiagnostics();
164  ObsDiags_ ydiags(obspace_, *locations_, vars);
165 
166  /// Compute H(x)
167  obsop_->simulateObs(*geovals, yobsim, *ybias_, ydiags);
168 
169  /// Call posterior filters
170  filters_->postFilter(yobsim, ydiags);
171 
172  // Update R with obs errors that filters might have updated
173  Rmat_->update(*obserr_);
174 
175  // Save current obs, obs error estimates and QC flags (for diagnostics use only)
176  std::string siter = "";
177  if (iterconf_->has("iteration")) siter = iterconf_->getString("iteration");
178 
179  if (iterconf_->getBool("save qc", true)) {
180  const std::string qcname = "EffectiveQC" + siter;
181  qcflags_->save(qcname);
182  }
183  if (iterconf_->getBool("save hofx", true)) {
184  const std::string obsname = "hofx" + siter;
185  yobsim.save(obsname);
186  }
187  if (iterconf_->getBool("save obs errors", true)) {
188  const std::string errname = "EffectiveError" + siter;
189  Rmat_->save(errname);
190  }
191 
192  Log::info() << "Observer::finalize QC = " << *qcflags_ << std::endl;
193 
194  initialized_ = false;
195  Log::trace() << "Observer<MODEL, OBS>::finalize done" << std::endl;
196 }
197 
198 // -----------------------------------------------------------------------------
199 
200 } // namespace oops
201 
202 #endif // OOPS_BASE_OBSERVER_H_
Geometry class used in oops; subclass of interface class interface::Geometry.
Fills GeoVaLs with requested variables at requested locations during model run.
Definition: GetValuePost.h:35
Locations of observations for observation operator.
Observation error covariance matrix of observations from a single ObsSpace.
Definition: ObsError.h:29
Holds observation filters (usually QC) for one observation type.
Definition: ObsFilters.h:36
const Variables & obsvariables() const
void save(const std::string &) const
Computes observation operator, applying bias correction and QC filters.
Definition: Observer.h:54
bool initialized_
Definition: Observer.h:92
Geometry< MODEL > Geometry_
Definition: Observer.h:55
ObsVector< OBS > ObsVector_
Definition: Observer.h:67
ObsDiagnostics< OBS > ObsDiags_
Definition: Observer.h:61
std::unique_ptr< eckit::LocalConfiguration > iterconf_
Definition: Observer.h:93
std::unique_ptr< ObsFilters_ > filters_
Definition: Observer.h:88
ObsDataVector< OBS, int > ObsDataInt_
Definition: Observer.h:60
std::shared_ptr< GetValPost_ > getvals_
Definition: Observer.h:90
GeoVaLs< OBS > GeoVaLs_
Definition: Observer.h:56
std::shared_ptr< ObsDataInt_ > qcflags_
Definition: Observer.h:91
Parameters_ parameters_
Definition: Observer.h:82
ObsError_ * Rmat_
Definition: Observer.h:87
ObsError< OBS > ObsError_
Definition: Observer.h:62
std::unique_ptr< ObsOperator_ > obsop_
Definition: Observer.h:84
const ObsSpace_ & obspace_
Definition: Observer.h:83
ObserverParameters< OBS > Parameters_
Definition: Observer.h:63
ObsAuxControl< OBS > ObsAuxCtrl_
Definition: Observer.h:59
const ObsAuxCtrl_ * ybias_
Definition: Observer.h:86
ObsFilters< OBS > ObsFilters_
Definition: Observer.h:64
Locations< OBS > Locations_
Definition: Observer.h:58
std::unique_ptr< ObsVector_ > obserr_
Definition: Observer.h:89
Observer(const ObsSpace_ &, const Parameters_ &)
Initializes ObsOperators, Locations, and QC data.
Definition: Observer.h:99
std::shared_ptr< GetValPost_ > initialize(const Geometry_ &, const ObsAuxCtrl_ &, ObsError_ &, const eckit::Configuration &)
Initializes variables, obs bias, obs filters (could be different for different iterations.
Definition: Observer.h:115
ObsSpace< OBS > ObsSpace_
Definition: Observer.h:66
GetValuePost< MODEL, OBS > GetValPost_
Definition: Observer.h:57
std::unique_ptr< Locations_ > locations_
Definition: Observer.h:85
void finalize(ObsVector_ &)
Computes H(x) from the filled in GeoVaLs.
Definition: Observer.h:150
ObsOperator< OBS > ObsOperator_
Definition: Observer.h:65
oops::Parameter< std::vector< ObsFilterParametersWrapper< OBS > > > obsFilters
Definition: Observer.h:43
oops::Parameter< eckit::LocalConfiguration > linearGetValues
Definition: Observer.h:46
oops::RequiredParameter< eckit::LocalConfiguration > obsOperator
Definition: Observer.h:42
oops::Parameter< eckit::LocalConfiguration > getValues
Definition: Observer.h:44
The namespace for the main oops code.