UFO
SlantPathLocations.cc
Go to the documentation of this file.
1 /*
2  * (C) Copyright 2021 Met Office UK
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 
8 #include <string>
9 
10 #include "ioda/ObsSpace.h"
11 
12 #include "oops/util/missingValues.h"
13 
14 #include "ufo/GeoVaLs.h"
16 
17 namespace ufo {
18 
19  std::vector<std::size_t> getSlantPathLocations(const ioda::ObsSpace & odb,
20  const GeoVaLs & gv,
21  const std::vector<std::size_t> & locs,
22  const std::string & modelVerticalCoord,
23  const int itermax) {
24  const float missing = util::missingValue(missing);
25 
26  // Get observed pressure.
27  std::vector<float> pressure_obs(odb.nlocs());
28  odb.get_db("MetaData", "air_pressure", pressure_obs);
29 
30  // If the pressure GeoVaL is not present, return an empty vector.
31  // todo(ctgh): eventually throw an exception here.
32  // This will be dealt with in a future PR.
33  if (!gv.has(modelVerticalCoord)) return {};
34  // Number of levels for model pressure.
35  const std::size_t nlevs_p = gv.nlevs(modelVerticalCoord);
36  // Vector storing location for each level along the slant path.
37  // Initially the first location in the profile is used everywhere.
38  std::vector<std::size_t> slant_path_location(nlevs_p, locs.front());
39  // Vector used to store different pressure GeoVaLs.
40  std::vector <float> pressure_gv(nlevs_p);
41 
42  // Loop over model levels and find intersection of profile with model layer boundary.
43  // This can be performed multiple times in order to account for slanted model levels.
44  std::size_t idxstart = 0; // Starting index for loop over levels.
45  // This counter records locations in the slanted profile.
46  // It is initialised at the first location in the original profile.
47  std::size_t jlocslant = locs.front();
48  // Loop over each model level in turn.
49  for (std::size_t mlev = 0; mlev < nlevs_p; ++mlev) {
50  for (int iter = 0; iter <= itermax; ++iter) {
51  // Get the GeoVaL that corresponds to the current slanted profile location.
52  gv.getAtLocation(pressure_gv, modelVerticalCoord, jlocslant);
53  // Define an iteration-specific location that is initialised to the
54  // current slanted profile location.
55  std::size_t jlociter = jlocslant;
56  // Determine the intersection of the observed profile with the current model level.
57  // The intersection is taken to be the location with the largest observed pressure
58  // that is less than or equal to the model pressure at this level.
59  for (std::size_t idx = idxstart; idx < locs.size(); ++idx) {
60  // Intersection location.
61  const std::size_t jlocintersect = locs[idx];
62  // If pressure has not been recorded, move to the next level.
63  if (pressure_obs[jlocintersect] == missing) continue;
64  // Break from the loop if the observed pressure is lower than
65  // the pressure of this model level.
66  if (pressure_obs[jlocintersect] <= pressure_gv[mlev]) break;
67  // Update the iteration-specific location with the new intersection location.
68  jlociter = jlocintersect;
69  // Update the loop starting index when the last iteration is reached.
70  if (iter == itermax) idxstart = idx;
71  }
72  // Modify the slanted location in the original profile.
73  jlocslant = jlociter;
74  if (iter == itermax) {
75  // Record the value of the slant path location at this model level and all above.
76  // This ensures that missing values are dealt with correctly.
77  for (std::size_t mlevcolumn = mlev; mlevcolumn < nlevs_p; ++mlevcolumn)
78  slant_path_location[mlevcolumn] = jlocslant;
79  }
80  }
81  }
82 
83  return slant_path_location;
84  }
85 } // 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
bool has(const std::string &var) const
void getAtLocation(std::vector< double > &, const std::string &, const int) const
Get GeoVaLs at a specified location.
Definition: GeoVaLs.cc:380
constexpr int missing
Definition: QCflags.h:20
Definition: RunCRTM.h:27
std::vector< std::size_t > getSlantPathLocations(const ioda::ObsSpace &odb, const GeoVaLs &gv, const std::vector< std::size_t > &locs, const std::string &modelVerticalCoord, const int itermax)