UFO
ObsCompositeTLAD.cc
Go to the documentation of this file.
1 /*
2  * (C) Crown copyright 2021, Met Office
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 
9 
10 #include <ostream>
11 #include <utility>
12 
13 #include "ioda/ObsSpace.h"
14 #include "ioda/ObsVector.h"
15 
16 #include "oops/base/Variables.h"
17 #include "oops/util/Logger.h"
18 
20 #include "ufo/GeoVaLs.h"
21 
22 namespace ufo {
23 
24 // -----------------------------------------------------------------------------
26 // -----------------------------------------------------------------------------
27 
28 ObsCompositeTLAD::ObsCompositeTLAD(const ioda::ObsSpace & odb, const Parameters_ & parameters)
30 {
31  oops::Log::trace() << "ObsCompositeTLAD constructor starting" << std::endl;
32 
33  for (const eckit::LocalConfiguration &operatorConfig : parameters.components.value()) {
35  operatorParams.validateAndDeserialize(operatorConfig);
36  std::unique_ptr<LinearObsOperatorBase> op(
38  requiredVars_ += op->requiredVars();
39  components_.push_back(std::move(op));
40  }
41 
42  oops::Log::trace() << "ObsCompositeTLAD created." << std::endl;
43 }
44 
45 // -----------------------------------------------------------------------------
46 
48  oops::Log::trace() << "ObsCompositeTLAD destructed" << std::endl;
49 }
50 
51 // -----------------------------------------------------------------------------
52 
53 void ObsCompositeTLAD::setTrajectory(const GeoVaLs & geovals, ObsDiagnostics & ydiags) {
54  oops::Log::trace() << "ObsCompositeTLAD: setTrajectory entered" << std::endl;
55 
56  for (const std::unique_ptr<LinearObsOperatorBase> &component : components_)
57  component->setTrajectory(geovals, ydiags);
58 
59  oops::Log::trace() << "ObsCompositeTLAD: setTrajectory exit " << std::endl;
60 }
61 
62 // -----------------------------------------------------------------------------
63 
64 void ObsCompositeTLAD::simulateObsTL(const GeoVaLs & geovals, ioda::ObsVector & ovec) const {
65  oops::Log::trace() << "ObsCompositeTLAD: simulateObsTL entered" << std::endl;
66 
67  for (const std::unique_ptr<LinearObsOperatorBase> &component : components_)
68  component->simulateObsTL(geovals, ovec);
69 
70  oops::Log::trace() << "ObsCompositeTLAD: simulateObsTL exit " << std::endl;
71 }
72 
73 // -----------------------------------------------------------------------------
74 
75 void ObsCompositeTLAD::simulateObsAD(GeoVaLs & geovals, const ioda::ObsVector & ovec) const {
76  oops::Log::trace() << "ObsCompositeTLAD: simulateObsAD entered" << std::endl;
77 
78  for (const std::unique_ptr<LinearObsOperatorBase> &component : components_)
79  component->simulateObsAD(geovals, ovec);
80 
81  oops::Log::trace() << "ObsCompositeTLAD: simulateObsAD exit " << std::endl;
82 }
83 
84 // -----------------------------------------------------------------------------
85 
86 oops::Variables ObsCompositeTLAD::simulatedVars() const {
87  // Merge the lists of variables simulated by all components, ensuring that there are
88  // no overlaps.
89  oops::Variables vars;
90  for (const std::unique_ptr<LinearObsOperatorBase> &component : components_) {
91  oops::Variables componentVars;
92  // We use += rather than = to make sure componentVars contains no duplicate entries.
93  componentVars += component->simulatedVars();
94  const size_t oldSize = vars.size();
95  vars += componentVars;
96  if (vars.size() != oldSize + componentVars.size())
97  // We don't want multiple components to write to the same row in the H(x) array.
98  throw eckit::UserError("Multiple components simulate the same variables", Here());
99  }
100  return vars;
101 }
102 
103 // -----------------------------------------------------------------------------
104 
105 void ObsCompositeTLAD::print(std::ostream & os) const {
106  os << "ObsComposite with the following components:\n";
107  for (size_t i = 0; i < components_.size(); ++i) {
108  os << " - " << *components_[i];
109  if (i != components_.size() - 1)
110  os << '\n';
111  }
112 }
113 
114 // -----------------------------------------------------------------------------
115 
116 } // namespace ufo
GeoVaLs: geophysical values at locations.
static LinearObsOperatorBase * create(const ioda::ObsSpace &, const ObsOperatorParametersBase &)
Create and return a new linear observation operator.
Contains a polymorphic parameter holding an instance of a subclass of ObsOperatorParametersBase.
oops::RequiredPolymorphicParameter< ObsOperatorParametersBase, LinearObsOperatorFactory > operatorParameters
Configuration options recognized by the Composite operator.
oops::RequiredParameter< std::vector< eckit::LocalConfiguration > > components
A list of configuration options for each operator used to simulate a subset of variables.
oops::Variables requiredVars_
ObsCompositeTLAD(const ioda::ObsSpace &, const Parameters_ &)
oops::Variables simulatedVars() const override
List of variables simulated by this operator.
void simulateObsTL(const GeoVaLs &, ioda::ObsVector &) const override
std::vector< std::unique_ptr< LinearObsOperatorBase > > components_
void simulateObsAD(GeoVaLs &, const ioda::ObsVector &) const override
void setTrajectory(const GeoVaLs &, ObsDiagnostics &) override
Obs Operator.
void print(std::ostream &) const override
Definition: RunCRTM.h:27
static LinearObsOperatorMaker< ObsCompositeTLAD > makerCompositeTL_("Composite")