IODA Bundle
HofX4D.h
Go to the documentation of this file.
1 /*
2  * (C) Copyright 2009-2016 ECMWF.
3  * (C) Copyright 2020-2020 UCAR.
4  *
5  * This software is licensed under the terms of the Apache Licence Version 2.0
6  * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
7  * In applying this licence, ECMWF does not waive the privileges and immunities
8  * granted to it by virtue of its status as an intergovernmental organisation nor
9  * does it submit to any jurisdiction.
10  */
11 
12 #ifndef OOPS_RUNS_HOFX4D_H_
13 #define OOPS_RUNS_HOFX4D_H_
14 
15 #include <string>
16 #include <vector>
17 
18 #include "eckit/config/LocalConfiguration.h"
19 #include "eckit/exception/Exceptions.h"
20 #include "oops/base/Geometry.h"
22 #include "oops/base/Model.h"
24 #include "oops/base/ObsErrors.h"
25 #include "oops/base/Observations.h"
26 #include "oops/base/Observers.h"
27 #include "oops/base/ObsSpaces.h"
29 #include "oops/base/State.h"
30 #include "oops/base/StateInfo.h"
33 #include "oops/mpi/mpi.h"
34 #include "oops/runs/Application.h"
35 #include "oops/util/algorithms.h"
36 #include "oops/util/DateTime.h"
37 #include "oops/util/Duration.h"
38 #include "oops/util/Logger.h"
39 #include "oops/util/parameters/OptionalParameter.h"
40 #include "oops/util/parameters/Parameter.h"
41 #include "oops/util/parameters/Parameters.h"
42 #include "oops/util/parameters/RequiredParameter.h"
43 
44 namespace oops {
45 
46 // -----------------------------------------------------------------------------
47 
48 /// \brief Options controlling the processing of observations from a single obs space.
49 template <typename OBS>
50 class ObsTypeParameters : public oops::Parameters {
51  OOPS_CONCRETE_PARAMETERS(ObsTypeParameters, Parameters)
52 
53  public:
55 
56  /// Options used to configure the observation space.
57  oops::RequiredParameter<eckit::LocalConfiguration> obsSpace{"obs space", this};
58 
59  /// Options used to configure the observation operator, observation filters and GetValues.
61 
62  /// Options used to configure the observation error model.
63  oops::Parameter<eckit::LocalConfiguration> obsError{
64  "obs error", eckit::LocalConfiguration(), this};
65 
66  /// Options used to configure bias correction.
67  oops::Parameter<ObsAuxControlParameters_> obsBias{"obs bias", {}, this};
68 };
69 
70 // -----------------------------------------------------------------------------
71 
72 /// \brief Top-level options taken by the HofX4D application.
73 template <typename MODEL, typename OBS>
74 class HofX4DParameters : public oops::Parameters {
75  OOPS_CONCRETE_PARAMETERS(HofX4DParameters, Parameters)
76 
77  public:
80 
81  /// Only observations taken at times lying in the (`window begin`, `window begin` + `window
82  /// length`] interval will be included in observation spaces.
83  oops::RequiredParameter<util::DateTime> windowBegin{"window begin", this};
84  oops::RequiredParameter<util::Duration> windowLength{"window length", this};
85 
86  /// Forecast length.
87  oops::RequiredParameter<util::Duration> forecastLength{"forecast length", this};
88 
89  /// A list whose elements determine treatment of observations from individual observation spaces.
90  oops::Parameter<std::vector<ObsTypeParameters<OBS>>> observations{"observations", {}, this};
91 
92  /// Geometry parameters.
93  oops::RequiredParameter<GeometryParameters_> geometry{"geometry", this};
94 
95  /// Model parameters.
96  oops::RequiredParameter<ModelParameters_> model{"model", this};
97 
98  /// Initial state parameters.
99  oops::RequiredParameter<eckit::LocalConfiguration> initialCondition{"initial condition", this};
100 
101  /// Options passed to the object writing out forecast fields.
102  oops::Parameter<eckit::LocalConfiguration> prints{"prints", eckit::LocalConfiguration(), this};
103 
104  /// Whether to perturb the H(x) vector before saving.
105  oops::Parameter<bool> obsPerturbations{"obs perturbations", false, this};
106 
107  /// Whether to save the H(x) vector as ObsValues.
108  oops::Parameter<bool> makeObs{"make obs", false, this};
109 
110  /// Parameters used by regression tests comparing results produced by the application against
111  /// known good outputs.
112  oops::Parameter<eckit::LocalConfiguration> test{"test", eckit::LocalConfiguration(), this};
113 };
114 
115 // -----------------------------------------------------------------------------
116 
117 /// Application runs model forecast from "initial condition" for the "forecast length"
118 /// and computes H(x) on the run. If "obspert" is specified in the config, the resulting
119 /// H(x) is perturbed. It is saved as "hofx" by default, or as specified "hofx group name"
120 template <typename MODEL, typename OBS> class HofX4D : public Application {
130 
135 
136  public:
137 // -----------------------------------------------------------------------------
138  explicit HofX4D(const eckit::mpi::Comm & comm = oops::mpi::world()) : Application(comm) {
139  instantiateObsErrorFactory<OBS>();
140  instantiateObsFilterFactory<OBS>();
141  }
142 // -----------------------------------------------------------------------------
143  virtual ~HofX4D() = default;
144 // -----------------------------------------------------------------------------
145  int execute(const eckit::Configuration & fullConfig) const {
146 // Deserialize parameters
148  params.validateAndDeserialize(fullConfig);
149 
150 // Setup observation window
151  const util::Duration &winlen = params.windowLength;
152  const util::DateTime &winbgn = params.windowBegin;
153  const util::DateTime winend(winbgn + winlen);
154  Log::info() << "Observation window from " << winbgn << " to " << winend << std::endl;
155 
156 // Setup geometry
157  const Geometry_ geometry(params.geometry, this->getComm(), oops::mpi::myself());
158 
159 // Setup Model
160  const Model_ model(geometry, params.model.value().modelParameters);
161 
162 // Setup initial state
163  State_ xx(geometry, params.initialCondition);
164  ModelAux_ moderr(geometry, params.initialCondition);
165  const util::Duration &flength = params.forecastLength;
166  Log::test() << "Initial state: " << xx << std::endl;
167 
168 // Check that window specified for forecast is at least the same as obs window
169  if (winbgn < xx.validTime() || winend > xx.validTime() + flength) {
170  Log::error() << "Observation window can not be outside of forecast window." << std::endl;
171  Log::error() << "Obs window: " << winbgn << " to " << winend << std::endl;
172  Log::error() << "Forecast runs from: " << xx.validTime() << " for " << flength << std::endl;
173  throw eckit::BadValue("Observation window can not be outside of forecast window.");
174  }
175 
176 // Setup forecast outputs
178 
179  post.enrollProcessor(new StateInfo<State_>("fc", params.prints));
180 
181 // Setup observations
182 
183  const eckit::LocalConfiguration obsConfig(fullConfig, "observations");
184  ObsSpaces_ obspaces(obsConfig, this->getComm(), winbgn, winend);
185 
186  const std::vector<ObsAuxControlParameters_> obsauxParams = util::transformVector(
187  params.observations.value(),
188  [](const ObsTypeParameters_ & obsTypeParams) { return obsTypeParams.obsBias.value(); });
189  ObsAux_ obsaux(obspaces, obsauxParams);
190 
191  ObsErrors_ Rmat(obsConfig, obspaces);
192 
193 // Setup and initialize observer
194  std::vector<ObserverParameters_> observerParams = util::transformVector(
195  params.observations.value(),
196  [](const ObsTypeParameters_ & obsTypeParams) { return obsTypeParams.observer; });
197  Observers_ hofx(obspaces, observerParams);
198  hofx.initialize(geometry, obsaux, Rmat, post);
199 
200 // run the model and compute H(x)
201  model.forecast(xx, moderr, flength, post);
202  Log::test() << "Final state: " << xx << std::endl;
203 
204 // Get observations from observer
205  Observations_ yobs(obspaces);
206  hofx.finalize(yobs);
207  Log::test() << "H(x): " << std::endl << yobs << "End H(x)" << std::endl;
208 
209 // Perturb H(x) if needed (can be used for generating obs in OSSE: perturbed H(x) could be saved
210 // as ObsValue if "hofx group name" == ObsValue.
211  if (params.obsPerturbations) {
212  yobs.perturb(Rmat);
213  Log::test() << "Perturbed H(x): " << std::endl << yobs << "End Perturbed H(x)" << std::endl;
214  }
215 
216 // Save H(x) as observations (if "make obs" == true)
217  if (params.makeObs) yobs.save("ObsValue");
218  obspaces.save();
219 
220  return 0;
221  }
222 // -----------------------------------------------------------------------------
223  private:
224  std::string appname() const {
225  return "oops::HofX4D<" + MODEL::name() + ", " + OBS::name() + ">";
226  }
227 // -----------------------------------------------------------------------------
228 };
229 
230 } // namespace oops
231 
232 #endif // OOPS_RUNS_HOFX4D_H_
program test
const eckit::mpi::Comm & getComm() const
Definition: Application.h:36
Geometry class used in oops; subclass of interface class interface::Geometry.
interface::Geometry< MODEL >::Parameters_ Parameters_
HofX4D(const eckit::mpi::Comm &comm=oops::mpi::world())
Definition: HofX4D.h:138
int execute(const eckit::Configuration &fullConfig) const
Definition: HofX4D.h:145
ObserverParameters< OBS > ObserverParameters_
Definition: HofX4D.h:133
Observations< OBS > Observations_
Definition: HofX4D.h:125
Observers< MODEL, OBS > Observers_
Definition: HofX4D.h:127
Model< MODEL > Model_
Definition: HofX4D.h:122
ModelAuxControl< MODEL > ModelAux_
Definition: HofX4D.h:123
ObsSpaces< OBS > ObsSpaces_
Definition: HofX4D.h:128
HofX4DParameters< MODEL, OBS > HofX4DParameters_
Definition: HofX4D.h:131
virtual ~HofX4D()=default
State< MODEL > State_
Definition: HofX4D.h:129
std::string appname() const
Definition: HofX4D.h:224
ObsTypeParameters< OBS > ObsTypeParameters_
Definition: HofX4D.h:134
Geometry< MODEL > Geometry_
Definition: HofX4D.h:121
ObsErrors< OBS > ObsErrors_
Definition: HofX4D.h:126
ObsAuxControl< OBS >::Parameters_ ObsAuxControlParameters_
Definition: HofX4D.h:132
ObsAuxControls< OBS > ObsAux_
Definition: HofX4D.h:124
Top-level options taken by the HofX4D application.
Definition: HofX4D.h:74
oops::Parameter< std::vector< ObsTypeParameters< OBS > > > observations
A list whose elements determine treatment of observations from individual observation spaces.
Definition: HofX4D.h:90
oops::RequiredParameter< eckit::LocalConfiguration > initialCondition
Initial state parameters.
Definition: HofX4D.h:99
oops::RequiredParameter< util::DateTime > windowBegin
Definition: HofX4D.h:83
oops::RequiredParameter< ModelParameters_ > model
Model parameters.
Definition: HofX4D.h:96
oops::Parameter< eckit::LocalConfiguration > prints
Options passed to the object writing out forecast fields.
Definition: HofX4D.h:102
Geometry< MODEL >::Parameters_ GeometryParameters_
Definition: HofX4D.h:78
oops::RequiredParameter< util::Duration > forecastLength
Forecast length.
Definition: HofX4D.h:87
oops::Parameter< bool > obsPerturbations
Whether to perturb the H(x) vector before saving.
Definition: HofX4D.h:105
oops::RequiredParameter< util::Duration > windowLength
Definition: HofX4D.h:84
ModelParametersWrapper< MODEL > ModelParameters_
Definition: HofX4D.h:79
oops::RequiredParameter< GeometryParameters_ > geometry
Geometry parameters.
Definition: HofX4D.h:93
oops::Parameter< bool > makeObs
Whether to save the H(x) vector as ObsValues.
Definition: HofX4D.h:108
Abstract nonlinear forecast model used by high level algorithms and applications.
void forecast(State_ &xx, const ModelAux_ &, const util::Duration &len, PostProcessor< State_ > &post) const
Run the forecast from state xx for len time, with post postprocessors Does not need to be implemented...
Contains a polymorphic parameter holding an instance of a subclass of ModelParametersBase.
ObsAuxControl_::Parameters_ Parameters_
Container for ObsErrors for all observation types that are used in DA.
Definition: ObsErrors.h:32
void save() const
Save files.
Definition: ObsSpaces.h:95
Options controlling the processing of observations from a single obs space.
Definition: HofX4D.h:50
oops::RequiredParameter< eckit::LocalConfiguration > obsSpace
Options used to configure the observation space.
Definition: HofX4D.h:57
oops::Parameter< ObsAuxControlParameters_ > obsBias
Options used to configure bias correction.
Definition: HofX4D.h:67
ObsAuxControl< OBS >::Parameters_ ObsAuxControlParameters_
Definition: HofX4D.h:54
ObserverParameters< OBS > observer
Options used to configure the observation operator, observation filters and GetValues.
Definition: HofX4D.h:60
oops::Parameter< eckit::LocalConfiguration > obsError
Options used to configure the observation error model.
Definition: HofX4D.h:63
Observations Class.
Definition: Observations.h:35
void save(const std::string &) const
Save/read observations values.
Definition: Observations.h:141
void perturb(const ObsErrors_ &)
Perturbations.
Definition: Observations.h:186
Computes observation operator (from GeoVaLs), applies bias correction and runs QC filters.
Definition: Observers.h:36
void initialize(const Geometry_ &, const ObsAuxCtrls_ &, ObsErrors_ &, PostProc_ &, const eckit::Configuration &=eckit::LocalConfiguration())
Initializes variables, obs bias, obs filters (could be different for different iterations.
Definition: Observers.h:98
void finalize(Observations_ &)
Computes H(x) from the filled in GeoVaLs.
Definition: Observers.h:115
Control model post processing.
Definition: PostProcessor.h:30
void enrollProcessor(PostBase_ *pp)
Definition: PostProcessor.h:38
State class used in oops; subclass of interface class interface::State.
Handles writing-out of forecast fields.
Definition: StateInfo.h:28
const util::DateTime validTime() const
Accessor to the time of this State.
const eckit::mpi::Comm & myself()
Default communicator with each MPI task by itself.
Definition: oops/mpi/mpi.cc:90
const eckit::mpi::Comm & world()
Default communicator with all MPI tasks (ie MPI_COMM_WORLD)
Definition: oops/mpi/mpi.cc:84
The namespace for the main oops code.