OOPS
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/ObsVector.h"
22 #include "oops/base/Variables.h"
23 #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  typedef typename OBS::ObsOperator::Parameters_ ObsOperatorParameters_;
42 
43  public:
44  oops::RequiredParameter<ObsOperatorParameters_> obsOperator{"obs operator", this};
45  oops::Parameter<std::vector<ObsFilterParametersWrapper<OBS>>> obsFilters{"obs filters", {}, this};
46  oops::Parameter<eckit::LocalConfiguration> getValues{
47  "get values", eckit::LocalConfiguration(), this};
48  oops::Parameter<eckit::LocalConfiguration> linearGetValues{
49  "linear get values", eckit::LocalConfiguration(), this};
50 };
51 
52 // -----------------------------------------------------------------------------
53 
54 /// \brief Computes observation operator, applying bias correction and QC filters
55 template <typename MODEL, typename OBS>
56 class Observer {
70 
71  public:
72 /// \brief Initializes ObsOperators, Locations, and QC data
73  Observer(const ObsSpace_ &, const Parameters_ &);
74 
75 /// \brief Initializes variables, obs bias, obs filters (could be different for
76 /// different iterations
77  std::shared_ptr<GetValPost_> initialize(const Geometry_ &, const ObsAuxCtrl_ &,
78  ObsError_ &, const eckit::Configuration &);
79 
80 /// \brief Computes H(x) from the filled in GeoVaLs
81  void finalize(ObsVector_ &);
82 
83  private:
85  const ObsSpace_ & obspace_; // ObsSpace used in H(x)
86  std::unique_ptr<ObsOperator_> obsop_; // Obs operator
87  std::unique_ptr<Locations_> locations_; // locations
88  const ObsAuxCtrl_ * biascoeff_; // bias coefficients
89  ObsError_ * Rmat_; // Obs error covariance
90  std::unique_ptr<ObsFilters_> filters_; // QC filters
91  std::unique_ptr<ObsVector_> obserr_; // Obs error std dev
92  std::shared_ptr<GetValPost_> getvals_; // Postproc passed to the model during integration.
93  std::shared_ptr<ObsDataInt_> qcflags_; // QC flags (should not be a pointer)
95  std::unique_ptr<eckit::LocalConfiguration> iterconf_;
96 };
97 
98 // -----------------------------------------------------------------------------
99 
100 template <typename MODEL, typename OBS>
101 Observer<MODEL, OBS>::Observer(const ObsSpace_ & obspace, const Parameters_ & params)
102  : parameters_(params), obspace_(obspace), obsop_(), locations_(),
103  biascoeff_(nullptr), filters_(), qcflags_(), initialized_(false)
104 {
105  Log::trace() << "Observer::Observer start" << std::endl;
106  /// Set up observation operators
109 
110  Log::trace() << "Observer::Observer done" << std::endl;
111 }
112 
113 // -----------------------------------------------------------------------------
114 
115 template <typename MODEL, typename OBS>
116 std::shared_ptr<GetValuePost<MODEL, OBS>>
118  ObsError_ & R, const eckit::Configuration & conf) {
119  Log::trace() << "Observer<MODEL, OBS>::initialize start" << std::endl;
120 // Save information for finalize
121  iterconf_.reset(new eckit::LocalConfiguration(conf));
122  biascoeff_ = &biascoeff;
123  Rmat_ = &R;
124  obserr_.reset(new ObsVector_(Rmat_->obserrors()));
125 
126 // Set up QC filters and run preprocess
127  const int iterfilt = iterconf_->getInt("iteration", 0);
128  filters_.reset(new ObsFilters_(obspace_, parameters_.obsFilters,
129  qcflags_, *obserr_, iterfilt));
130  filters_->preProcess();
131 
132  locations_.reset(new Locations_(obsop_->locations()));
133 
134 // Set up variables that will be requested from the model
135  Variables geovars;
136  geovars += obsop_->requiredVars();
137  geovars += biascoeff_->requiredVars();
138  geovars += filters_->requiredVars();
139 
140 // Set up GetValues
141  getvals_.reset(new GetValPost_(parameters_.getValues, geom, obspace_.windowStart(),
142  obspace_.windowEnd(), *locations_, geovars));
143 
144  initialized_ = true;
145  Log::trace() << "Observer<MODEL, OBS>::initialize done" << std::endl;
146  return getvals_;
147 }
148 
149 // -----------------------------------------------------------------------------
150 
151 template <typename MODEL, typename OBS>
153  oops::Log::trace() << "Observer<MODEL, OBS>::finalize start" << std::endl;
154  ASSERT(initialized_);
155 
156  // GetValues releases GeoVaLs, Observer takes ownership
157  std::unique_ptr<GeoVaLs_> geovals = getvals_->releaseGeoVaLs();
158 
159  /// Call prior filters
160  filters_->priorFilter(*geovals);
161 
162  /// Setup diagnostics
163  Variables vars;
164  vars += filters_->requiredHdiagnostics();
165  vars += biascoeff_->requiredHdiagnostics();
166  ObsDiags_ ydiags(obspace_, *locations_, vars);
167 
168  // Setup bias vector
169  ObsVector_ ybias(obspace_);
170  ybias.zero();
171 
172  /// Compute H(x)
173  obsop_->simulateObs(*geovals, yobsim, *biascoeff_, ybias, ydiags);
174 
175  /// Call posterior filters
176  filters_->postFilter(yobsim, ybias, ydiags);
177 
178  // Update R with obs errors that filters might have updated
179  Rmat_->update(*obserr_);
180 
181  // Save current obs, obs error estimates and QC flags (for diagnostics use only)
182  std::string siter = "";
183  if (iterconf_->has("iteration")) siter = iterconf_->getString("iteration");
184 
185  if (iterconf_->getBool("save qc", true)) {
186  const std::string qcname = "EffectiveQC" + siter;
187  qcflags_->save(qcname);
188  }
189  if (iterconf_->getBool("save hofx", true)) {
190  const std::string obsname = "hofx" + siter;
191  yobsim.save(obsname);
192  }
193  if (iterconf_->getBool("save obs errors", true)) {
194  const std::string errname = "EffectiveError" + siter;
195  Rmat_->save(errname);
196  }
197  if (iterconf_->getBool("save obs bias", true)) {
198  const std::string biasname = "ObsBias" + siter;
199  ybias.save(biasname);
200  }
201 
202  Log::info() << "Observer::finalize QC = " << *qcflags_ << std::endl;
203 
204  initialized_ = false;
205  Log::trace() << "Observer<MODEL, OBS>::finalize done" << std::endl;
206 }
207 
208 // -----------------------------------------------------------------------------
209 
210 } // namespace oops
211 
212 #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.
Auxiliary state related to observations, templated on <OBS>
ObsDataVector is a vector templated on data type, in the observation space.
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
MODEL-agnostic part of nonlinear observation (forward) operator. The full nonlinear observation opera...
const Variables & obsvariables() const
ObsVector class used in oops; subclass of interface class interface::ObsVector.
Computes observation operator, applying bias correction and QC filters.
Definition: Observer.h:56
bool initialized_
Definition: Observer.h:94
Geometry< MODEL > Geometry_
Definition: Observer.h:57
ObsVector< OBS > ObsVector_
Definition: Observer.h:69
ObsDiagnostics< OBS > ObsDiags_
Definition: Observer.h:63
std::unique_ptr< eckit::LocalConfiguration > iterconf_
Definition: Observer.h:95
std::unique_ptr< ObsFilters_ > filters_
Definition: Observer.h:90
ObsDataVector< OBS, int > ObsDataInt_
Definition: Observer.h:62
std::shared_ptr< GetValPost_ > getvals_
Definition: Observer.h:92
GeoVaLs< OBS > GeoVaLs_
Definition: Observer.h:58
std::shared_ptr< ObsDataInt_ > qcflags_
Definition: Observer.h:93
Parameters_ parameters_
Definition: Observer.h:84
const ObsAuxCtrl_ * biascoeff_
Definition: Observer.h:88
ObsError_ * Rmat_
Definition: Observer.h:89
ObsError< OBS > ObsError_
Definition: Observer.h:64
std::unique_ptr< ObsOperator_ > obsop_
Definition: Observer.h:86
const ObsSpace_ & obspace_
Definition: Observer.h:85
ObserverParameters< OBS > Parameters_
Definition: Observer.h:65
ObsAuxControl< OBS > ObsAuxCtrl_
Definition: Observer.h:61
ObsFilters< OBS > ObsFilters_
Definition: Observer.h:66
Locations< OBS > Locations_
Definition: Observer.h:60
std::unique_ptr< ObsVector_ > obserr_
Definition: Observer.h:91
Observer(const ObsSpace_ &, const Parameters_ &)
Initializes ObsOperators, Locations, and QC data.
Definition: Observer.h:101
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:117
ObsSpace< OBS > ObsSpace_
Definition: Observer.h:68
GetValuePost< MODEL, OBS > GetValPost_
Definition: Observer.h:59
std::unique_ptr< Locations_ > locations_
Definition: Observer.h:87
void finalize(ObsVector_ &)
Computes H(x) from the filled in GeoVaLs.
Definition: Observer.h:152
ObsOperator< OBS > ObsOperator_
Definition: Observer.h:67
oops::Parameter< std::vector< ObsFilterParametersWrapper< OBS > > > obsFilters
Definition: Observer.h:45
oops::Parameter< eckit::LocalConfiguration > linearGetValues
Definition: Observer.h:48
oops::RequiredParameter< ObsOperatorParameters_ > obsOperator
Definition: Observer.h:44
OBS::ObsOperator::Parameters_ ObsOperatorParameters_
Definition: Observer.h:41
oops::Parameter< eckit::LocalConfiguration > getValues
Definition: Observer.h:46
void save(const std::string &) const
Save this ObsVector as group name in the ObsSpace.
void zero()
Zero out this ObsVector.
The namespace for the main oops code.