OOPS
HofX.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_HOFX_H_
13 #define OOPS_RUNS_HOFX_H_
14 
15 #include <string>
16 
17 #include "eckit/config/LocalConfiguration.h"
18 #include "eckit/exception/Exceptions.h"
21 #include "oops/base/ObsErrors.h"
22 #include "oops/base/Observations.h"
23 #include "oops/base/ObsSpaces.h"
25 #include "oops/base/StateInfo.h"
28 #include "oops/interface/Model.h"
29 #include "oops/interface/State.h"
30 #include "oops/mpi/mpi.h"
31 #include "oops/runs/Application.h"
32 #include "oops/util/DateTime.h"
33 #include "oops/util/Duration.h"
34 #include "oops/util/Logger.h"
35 
36 namespace oops {
37 
38 /// Application runs model forecast from "initial condition" for the "forecast length"
39 /// and computes H(x) on the run. If "obspert" is specified in the config, the resulting
40 /// H(x) is perturbed. It is saved as "hofx" by default, or as specified "hofx group name"
41 template <typename MODEL, typename OBS> class HofX : public Application {
48 
49  public:
50 // -----------------------------------------------------------------------------
51  explicit HofX(const eckit::mpi::Comm & comm = oops::mpi::world()) : Application(comm) {
52  instantiateObsErrorFactory<OBS>();
53  instantiateObsFilterFactory<OBS>();
54  }
55 // -----------------------------------------------------------------------------
56  virtual ~HofX() = default;
57 // -----------------------------------------------------------------------------
58  int execute(const eckit::Configuration & fullConfig) const {
59 // Setup observation window
60  const util::Duration winlen(fullConfig.getString("window length"));
61  const util::DateTime winbgn(fullConfig.getString("window begin"));
62  const util::DateTime winend(winbgn + winlen);
63  Log::info() << "Observation window from " << winbgn << " to " << winend << std::endl;
64 
65 // Setup geometry
66  const eckit::LocalConfiguration geometryConfig(fullConfig, "geometry");
67  const Geometry_ geometry(geometryConfig, this->getComm());
68 
69 // Setup Model
70  const eckit::LocalConfiguration modelConfig(fullConfig, "model");
71  const Model_ model(geometry, modelConfig);
72 
73 // Setup initial state
74  const eckit::LocalConfiguration initialConfig(fullConfig, "initial condition");
75  State_ xx(geometry, initialConfig);
76  const util::Duration flength(fullConfig.getString("forecast length"));
77  Log::test() << "Initial state: " << xx << std::endl;
78 
79 // Check that window specified for forecast is at least the same as obs window
80  if (winbgn < xx.validTime() || winend > xx.validTime() + flength) {
81  Log::error() << "Observation window can not be outside of forecast window." << std::endl;
82  Log::error() << "Obs window: " << winbgn << " to " << winend << std::endl;
83  Log::error() << "Forecast runs from: " << xx.validTime() << " for " << flength << std::endl;
84  throw eckit::BadValue("Observation window can not be outside of forecast window.");
85  }
86 
87 // Setup forecast outputs
89 
90  eckit::LocalConfiguration prtConf;
91  fullConfig.get("prints", prtConf);
92  post.enrollProcessor(new StateInfo<State_>("fc", prtConf));
93 
94 // Setup observations
95  ObsSpaces_ obspace(fullConfig, this->getComm(), winbgn, winend);
96 
97 // Setup and run observer
98  CalcHofX<MODEL, OBS> hofx(obspace, geometry, fullConfig);
99  Observations_ yobs = hofx.compute(model, xx, post, flength);
100  hofx.saveQcFlags("EffectiveQC");
101  hofx.saveObsErrors("EffectiveError");
102 
103  Log::test() << "Final state: " << xx << std::endl;
104  Log::test() << "H(x): " << std::endl << yobs << "End H(x)" << std::endl;
105 
106 // Perturb H(x) if needed (can be used for generating obs in OSSE: perturbed H(x) could be saved
107 // as ObsValue if "hofx group name" == ObsValue.
108  bool obspert = fullConfig.getBool("obs perturbations", false);
109  if (obspert) {
110  ObsErrors_ matR(fullConfig, obspace);
111  yobs.perturb(matR);
112  Log::test() << "Perturbed H(x): " << std::endl << yobs << "End Perturbed H(x)" << std::endl;
113  }
114 
115 // Save H(x) either as observations (if "make obs" == true) or as "hofx"
116  const bool makeobs = fullConfig.getBool("make obs", false);
117  if (makeobs) {
118  yobs.save("ObsValue");
119  } else {
120  yobs.save("hofx");
121  }
122 
123  return 0;
124  }
125 // -----------------------------------------------------------------------------
126  private:
127  std::string appname() const {
128  return "oops::HofX<" + MODEL::name() + ", " + OBS::name() + ">";
129  }
130 // -----------------------------------------------------------------------------
131 };
132 
133 } // namespace oops
134 
135 #endif // OOPS_RUNS_HOFX_H_
oops::HofX::Model_
Model< MODEL > Model_
Definition: HofX.h:43
oops::State::validTime
const util::DateTime validTime() const
Time.
Definition: oops/interface/State.h:60
oops
The namespace for the main oops code.
Definition: ErrorCovarianceL95.cc:22
instantiateObsFilterFactory.h
oops::Observations::perturb
void perturb(const ObsErrors_ &)
Perturbations.
Definition: Observations.h:198
oops::HofX::ObsSpaces_
ObsSpaces< OBS > ObsSpaces_
Definition: HofX.h:46
oops::CalcHofX
Computes observation operator (while running model, or with State4D)
Definition: CalcHofX.h:38
ObsSpaces.h
mpi.h
model
Definition: l95/defaults/model.py:1
oops::CalcHofX::saveQcFlags
void saveQcFlags(const std::string &) const
saves QC flags to ObsSpaces
Definition: CalcHofX.h:154
oops::HofX::Geometry_
Geometry< MODEL > Geometry_
Definition: HofX.h:42
oops::HofX::appname
std::string appname() const
Definition: HofX.h:127
oops::ObsErrors
\biref Container for ObsErrors for all observation types that are used in DA
Definition: ObsErrors.h:33
oops::HofX::ObsErrors_
ObsErrors< OBS > ObsErrors_
Definition: HofX.h:45
instantiateObsErrorFactory.h
oops::HofX::HofX
HofX(const eckit::mpi::Comm &comm=oops::mpi::world())
Definition: HofX.h:51
oops::HofX::Observations_
Observations< OBS > Observations_
Definition: HofX.h:44
oops::CalcHofX::compute
const Observations_ & compute(const Model_ &, State_ &, PostProcessor_ &, const util::Duration &)
Computes 4D H(x) (running the model)
Definition: CalcHofX.h:105
Observations.h
oops::PostProcessor::enrollProcessor
void enrollProcessor(PostBase_ *pp)
Definition: PostProcessor.h:38
ObsErrors.h
Application.h
oops::Application::getComm
const eckit::mpi::Comm & getComm() const
Definition: Application.h:36
PostProcessor.h
oops::CalcHofX::saveObsErrors
void saveObsErrors(const std::string &) const
saves obs error variances (modified in QC) to ObsSpaces
Definition: CalcHofX.h:163
oops::StateInfo
Handles writing-out of forecast fields.
Definition: StateInfo.h:28
oops::Geometry
Geometry class used in oops; subclass of interface class above.
Definition: oops/interface/Geometry.h:189
Model.h
oops::Observations
Observations Class.
Definition: oops/base/Departures.h:30
StateInfo.h
oops::State
Encapsulates the model state.
Definition: CostJbState.h:28
oops::Application
Definition: Application.h:29
oops::PostProcessor
Control model post processing.
Definition: PostProcessor.h:30
State.h
oops::mpi::world
const eckit::mpi::Comm & world()
Default communicator with all MPI tasks (ie MPI_COMM_WORLD)
Definition: oops/mpi/mpi.cc:22
oops::HofX
Definition: HofX.h:41
oops::HofX::execute
int execute(const eckit::Configuration &fullConfig) const
Definition: HofX.h:58
oops::ObsSpaces
Definition: ObsSpaces.h:41
compare.error
int error
Definition: compare.py:168
oops::Model
Encapsulates the nonlinear forecast model Note: to see methods that need to be implemented in the for...
Definition: oops/interface/Model.h:54
oops::HofX::State_
State< MODEL > State_
Definition: HofX.h:47
CalcHofX.h
oops::HofX::~HofX
virtual ~HofX()=default
Geometry.h
oops::Observations::save
void save(const std::string &) const
Save/read observations values.
Definition: Observations.h:153