UFO
Cal_HeightFromPressure.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 #include "ufo/utils/Constants.h"
10 
11 namespace ufo {
12 /************************************************************************************/
13 // Cal_HeightFromPressure
14 /************************************************************************************/
15 static TransformMaker<Cal_HeightFromPressure>
16  makerCal_HeightFromPressure_("HeightFromPressure");
17 
19  const VariableTransformsParameters &options,
20  const ObsFilterData &data,
21  const std::shared_ptr<ioda::ObsDataVector<int>> &flags)
22  : TransformBase(options, data, flags) {}
23 
24 /************************************************************************************/
25 
26 void Cal_HeightFromPressure::runTransform(const std::vector<bool> &apply) {
27  oops::Log::trace() << " Retrieve Height From Pressure" << std::endl;
28 
29  std::vector<float> geopotentialHeight;
30  std::vector<float> airPressure;
31  bool hasBeenUpdated = false;
32 
33  const size_t nlocs_ = obsdb_.nlocs();
34 
35  ioda::ObsSpace::RecIdxIter irec;
36 
37  // 1. Obtain air pressure from the ObsSpace.
38  // Two possible pressure variables are searched for:
39  // - air_pressure,
40  // - air_pressure_levels.
41  // If neither is present an exception is thrown.
42 
43  // Do the pressure, and derived height, lie on staggered levels?
44  bool staggeredLevels = false;
45 
46  getObservation("MetaData", "air_pressure", airPressure);
47  if (airPressure.empty()) {
48  getObservation("MetaData", "air_pressure_levels", airPressure);
49  if (airPressure.empty()) {
50  oops::Log::warning() << "Air pressure vector is empty. "
51  << "Check will not be performed." << std::endl;
52  throw eckit::BadValue("Air pressure vector is empty ", Here());
53  }
54  staggeredLevels = true;
55  }
56 
57  // 2. Initialise the output array
58  // -------------------------------------------------------------------------------
59  if (staggeredLevels)
60  getObservation("MetaData", "geopotential_height_levels", geopotentialHeight);
61  else
62  getObservation("MetaData", "geopotential_height", geopotentialHeight);
63 
64  if (geopotentialHeight.empty()) {
65  geopotentialHeight = std::vector<float>(nlocs_);
66  std::fill(geopotentialHeight.begin(), geopotentialHeight.end(), missingValueFloat);
67  }
68 
69  // 3. Loop over each record
70  // -------------------------------------------------------------------------------------
71  for (irec = obsdb_.recidx_begin(); irec != obsdb_.recidx_end(); ++irec) {
72  const std::vector<std::size_t> &rSort = obsdb_.recidx_vector(irec);
73  size_t ilocs = 0;
74 
75  // 3.1 Loop over each record
76  for (ilocs = 0; ilocs < rSort.size(); ++ilocs) {
77  // Cycle if the data have been excluded by the where statement
78  if (!apply[rSort[ilocs]]) continue;
79 
80  // Cycle if geopotential height is valid
81  if (geopotentialHeight[rSort[ilocs]] != missingValueFloat) continue;
82 
83  geopotentialHeight[rSort[ilocs]] = formulas::Pressure_To_Height(
84  airPressure[rSort[ilocs]], method());
85 
86  hasBeenUpdated = true;
87  }
88  }
89 
90  if (hasBeenUpdated) {
91  // If the geopotential height was updated, save it as a DerivedValue.
92  if (staggeredLevels)
93  obsdb_.put_db(outputTag, "geopotential_height_levels", geopotentialHeight);
94  else
95  obsdb_.put_db(outputTag, "geopotential_height", geopotentialHeight);
96  }
97 }
98 } // namespace ufo
99 
Cal_HeightFromPressure(const VariableTransformsParameters &options, const ObsFilterData &data, const std::shared_ptr< ioda::ObsDataVector< int >> &flags)
void runTransform(const std::vector< bool > &apply) override
Run variable conversion.
ObsFilterData provides access to all data related to an ObsFilter.
Base class for variable conversion.
Definition: TransformBase.h:53
formulas::MethodFormulation method() const
subclasses to access Method and formualtion used for the calculation
const std::string outputTag
output tag for derived parameters
const float missingValueFloat
Missing value (float)
ioda::ObsSpace & obsdb_
Observation space.
void getObservation(const std::string &originalTag, const std::string &varName, std::vector< T > &obsVector, bool require=false) const
templated function for float, int data types
Definition: TransformBase.h:94
Options controlling the operation of the variablestansform filter.
float Pressure_To_Height(float pressure, MethodFormulation method)
Converts pressure to height.
Definition: Formulas.cc:271
Definition: RunCRTM.h:27
static TransformMaker< Cal_HeightFromPressure > makerCal_HeightFromPressure_("HeightFromPressure")