UFO
ObsProfileAverage.cc
Go to the documentation of this file.
1 /*
2  * (C) Copyright 2021 UK 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 <algorithm>
11 #include <ostream>
12 #include <utility>
13 #include <vector>
14 
15 #include "ioda/ObsVector.h"
16 
17 #include "oops/base/Variables.h"
18 #include "oops/util/Logger.h"
19 
20 #include "ufo/GeoVaLs.h"
21 #include "ufo/Locations.h"
22 #include "ufo/ObsDiagnostics.h"
23 
24 namespace ufo {
25 
26 // -----------------------------------------------------------------------------
28 // -----------------------------------------------------------------------------
29 
30 ObsProfileAverage::ObsProfileAverage(const ioda::ObsSpace & odb,
31  const eckit::Configuration & config)
32  : ObsOperatorBase(odb, config), odb_(odb), data_(odb, config)
33 {
34  oops::Log::trace() << "ObsProfileAverage constructed" << std::endl;
35 }
36 
37 // -----------------------------------------------------------------------------
38 
40  oops::Log::trace() << "ObsProfileAverage destructed" << std::endl;
41 }
42 
43 // -----------------------------------------------------------------------------
44 
45 void ObsProfileAverage::simulateObs(const GeoVaLs & gv, ioda::ObsVector & ovec,
46  ObsDiagnostics & ydiags) const {
47  oops::Log::trace() << "ObsProfileAverage: simulateObs started" << std::endl;
48 
49  // Cache the GeoVaLs the first time this function is called.
50  data_.cacheGeoVaLs(gv);
51 
52  // Get correspondence between record numbers and indices in the total sample.
53  const std::vector<std::size_t> &recnums = odb_.recidx_all_recnums();
54 
55  // Number of profiles in the original ObsSpace.
56  const std::size_t nprofs = recnums.size() / 2;
57 
58  // Loop over profiles.
59  for (std::size_t jprof = 0; jprof < nprofs; ++jprof) {
60  oops::Log::debug() << "Profile " << (jprof + 1) << " / " << nprofs << std::endl;
61 
62  // Get locations of profile in the original ObsSpace and
63  // the corresponding profile in the extended ObsSpace.
64  // Assuming the extended ObsSpace has been configured correctly, which is
65  // checked in the constructor of the data_ member variable,
66  // the profile in the extended ObsSpace is always located
67  // nprofs positions further on than the profile in the original ObsSpace.
68  const std::vector<std::size_t> &locsOriginal = odb_.recidx_vector(recnums[jprof]);
69  const std::vector<std::size_t> &locsExtended = odb_.recidx_vector(recnums[jprof + nprofs]);
70 
71  // Retrieve slant path locations.
72  const std::vector<std::size_t>& slant_path_location =
73  data_.getSlantPathLocations(locsOriginal, locsExtended);
74 
75  // Fill H(x) vector for each variable.
76  for (int jvar : data_.operatorVarIndices()) {
77  const auto& variable = ovec.varnames().variables()[jvar];
78  // Number of levels for this variable.
79  const std::size_t nlevs_var = gv.nlevs(variable);
80  // GeoVaL vector for this variable.
81  std::vector<double> var_gv(nlevs_var);
82  // For each level:
83  // - get the relevant slant path location,
84  // - retrieve the GeoVaL at that location,
85  // - fill H(x) with the relevant level in the GeoVaL.
86  for (std::size_t mlev = 0; mlev < nlevs_var; ++mlev) {
87  const std::size_t jloc = slant_path_location[mlev];
88  gv.getAtLocation(var_gv, variable, jloc);
89  ovec[locsExtended[mlev] * ovec.nvars() + jvar] = var_gv[mlev];
90  }
91  }
92  }
93 
94  oops::Log::trace() << "ObsProfileAverage: simulateObs finished" << std::endl;
95 }
96 
97 // -----------------------------------------------------------------------------
98 
99 void ObsProfileAverage::print(std::ostream & os) const {
100  data_.print(os);
101 }
102 
103 // -----------------------------------------------------------------------------
104 
105 } // namespace ufo
GeoVaLs: geophysical values at locations.
size_t nlevs(const std::string &var) const
Return number of levels for a specified variable.
Definition: GeoVaLs.cc:310
void getAtLocation(std::vector< double > &, const std::string &, const int) const
Get GeoVaLs at a specified location.
Definition: GeoVaLs.cc:380
std::vector< std::size_t > getSlantPathLocations(const std::vector< std::size_t > &locsOriginal, const std::vector< std::size_t > &locsExtended) const
void cacheGeoVaLs(const GeoVaLs &gv) const
Cache the initial values of the GeoVaLs.
const std::vector< int > & operatorVarIndices() const
Return operator variable indices for the operator.
void print(std::ostream &os) const
Print operator configuration options.
ObsProfileAverageData data_
Data handler for the ProfileAverage operator and TL/AD code.
void simulateObs(const GeoVaLs &, ioda::ObsVector &, ObsDiagnostics &) const override
Obs Operator.
void print(std::ostream &) const override
ObsProfileAverage(const ioda::ObsSpace &, const eckit::Configuration &)
const ioda::ObsSpace & odb_
ObsSpace.
Definition: RunCRTM.h:27
static ObsOperatorMaker< ObsProfileAverage > obsProfileAverageMaker_("ProfileAverage")