UFO
ProfilePressure.cc
Go to the documentation of this file.
1 /*
2  * (C) Crown copyright 2020, 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 namespace ufo {
11 
12  static ProfileCheckMaker<ProfilePressure>
13  makerProfilePressure_("Pressure");
14 
17  : ProfileCheckBase(options)
18  {}
19 
21  {
22  oops::Log::debug() << " Pressure calculations" << std::endl;
23 
24  const int numProfileLevels = profileDataHandler.getNumProfileLevels();
25 
26  // Retrieve the observed geopotential height and associated metadata.
27  std::vector <float> &zObs =
28  profileDataHandler.get<float>(ufo::VariableNames::obs_geopotential_height);
29  const std::vector <int> &ObsType =
30  profileDataHandler.get<int>(ufo::VariableNames::ObsType);
31  std::vector <int> &ReportFlags =
32  profileDataHandler.get<int>(ufo::VariableNames::qcflags_observation_report);
33 
34  if (!oops::allVectorsSameNonZeroSize(zObs, ObsType, ReportFlags)) {
35  oops::Log::warning() << "At least one vector is the wrong size. "
36  << "Profile pressure routine will not run." << std::endl;
37  oops::Log::warning() << "Vector sizes: "
38  << oops::listOfVectorSizes(zObs, ObsType, ReportFlags)
39  << std::endl;
40  return;
41  }
42 
43  // Retrieve the model background fields.
44  const std::vector <float> &orogGeoVaLs =
46  const std::vector <float> &pressureGeoVaLs =
48 
49  if (!oops::allVectorsSameNonZeroSize(orogGeoVaLs, pressureGeoVaLs)) {
50  oops::Log::warning() << "At least one GeoVaLs vector is the wrong size. "
51  << "Profile pressure routine will not run." << std::endl;
52  oops::Log::warning() << "Vector sizes: "
53  << oops::listOfVectorSizes(orogGeoVaLs, pressureGeoVaLs)
54  << std::endl;
55  return;
56  }
57 
58  // Retrive the vector of observed pressures.
59  std::vector <float> &pressures =
60  profileDataHandler.get<float>(ufo::VariableNames::obs_air_pressure);
61  // If pressures have not been recorded, initialise the vector with missing values.
62  if (pressures.empty())
63  pressures.assign(numProfileLevels, missingValueFloat);
64 
65  // Determine whether the instrument that recorded this profile had a pressure sensor.
66  const bool ObsHasNoPressureSensor =
72 
73  // Determine whether all levels have a valid pressure.
74  const int NumValidPLevels = std::count_if(pressures.begin(), pressures.end(),
75  [](float PLev){return PLev >= 0;});
76  bool AllLevelsHaveValidP = NumValidPLevels == numProfileLevels;
77  // Allow a small amount of flexibility for BUFR sondes.
80  AllLevelsHaveValidP = NumValidPLevels >= std::max(numProfileLevels - 2,
81  static_cast<int>(round(numProfileLevels
82  * 0.98)));
83  }
84 
85  // Set a QC flag for wind profilers and for BUFR sondes for which not
86  // all levels have a valid pressure.
88  (!AllLevelsHaveValidP && (ObsType[0] == MetOfficeObsIDs::AtmosphericProfile::Sonde ||
90  for (int jlev = 0; jlev < numProfileLevels; ++jlev) {
92  }
93  }
94 
95  // Determine whether any values of geopotential height are missing.
96  const int NumValidZLevels = std::count_if(zObs.begin(), zObs.end(),
97  [](float ZLev){return ZLev >= 0.0;});
98  const bool AllLevelsHaveValidZ = NumValidZLevels == numProfileLevels;
99 
100  // Override AllLevelsHaveValidP if the observation has been flagged as having no pressure sensor
101  // either in this routine or in an earlier one.
102  // In this case the pressures will be (re)calculated from the geopotential heights.
103  // This aims to improved the accuracy of the reported pressures if they are already present.
104  if (AllLevelsHaveValidP &&
106  AllLevelsHaveValidZ) {
107  AllLevelsHaveValidP = false;
108  }
109 
110  // Perform this for instruments without a pressure sensor
111  // that do not have a valid pressure on all levels.
112  // In all other cases assume pressure is already fine.
113  if (ObsHasNoPressureSensor &&
114  !AllLevelsHaveValidP) {
115  // Compute model heights on rho and theta levels.
116  // todo(ctgh): This could be performed when retrieving the GeoVaLs.
117  // zThetaGeoVaLs are not used further in this routine but do appear elsewhere in the code.
118  std::vector <float> zRhoGeoVaLs;
119  std::vector <float> zThetaGeoVaLs;
121  orogGeoVaLs[0],
122  zRhoGeoVaLs,
123  zThetaGeoVaLs);
124  // Compute observation pressures based on vertical interpolation from model heights.
126  pressureGeoVaLs,
127  zObs,
128  pressures);
129  }
130  }
131 } // namespace ufo
Options controlling the operation of the ConventionalProfileProcessing filter.
DataHandlerParameters DHParameters
Parameters related to profile data handler.
ModelParameters ModParameters
Parameters related to the model.
Profile QC checker base class.
const float missingValueFloat
Missing value (float)
const ConventionalProfileProcessingParameters & options_
Configurable parameters.
Retrieve and store data for individual profiles. To do this, first the vector of values in the entire...
std::vector< T > & get(const std::string &fullname)
std::vector< float > & getGeoVaLVector(const std::string &variableName)
Get GeoVaLs for a particular profile.
int getNumProfileLevels() const
Return number of levels to which QC checks should be applied.
void runCheck(ProfileDataHandler &profileDataHandler) override
Run check.
ProfilePressure(const ConventionalProfileProcessingParameters &options)
@ NoPressureSensor
No PILOT pressure sensor.
Definition: RunCRTM.h:27
static ProfileCheckMaker< ProfilePressure > makerProfilePressure_("Pressure")
void profileVerticalInterpolation(const std::vector< float > &coordIn, const std::vector< float > &valuesIn, const std::vector< float > &coordOut, std::vector< float > &valuesOut, const ProfileInterpolation::InterpolationMethod interpMethod, const ProfileInterpolation::CoordinateOrder coordOrder, const ProfileInterpolation::OutOfBoundsTreatment outOfBounds)
void CalculateModelHeight(const ModelParameters &options, const float orogGeoVaLs, std::vector< float > &zRhoGeoVaLs, std::vector< float > &zThetaGeoVaLs)
Calculate model heights on rho and theta levels. The calculation uses the terrain-following height co...
static constexpr const char *const qcflags_observation_report
Definition: VariableNames.h:98
static constexpr const char *const geovals_orog
static constexpr const char *const obs_geopotential_height
Definition: VariableNames.h:23
static constexpr const char *const geovals_pressure
static constexpr const char *const ObsType
Definition: VariableNames.h:87
static constexpr const char *const obs_air_pressure
Definition: VariableNames.h:18