22 static ProfileCheckMaker<ProfileAverageTemperature>
35 std::vector <std::string> variableNamesInt =
41 std::vector <std::string> variableNamesFloat =
53 std::vector <std::string> variableNamesGeoVaLs =
57 variableNamesInt.insert
58 (variableNamesInt.end(),
59 {
"OPS_" + std::string(ufo::VariableNames::modellevels_average_air_temperature_qcflags)});
60 variableNamesFloat.insert
61 (variableNamesFloat.end(),
62 {
"OPS_" + std::string(ufo::VariableNames::modellevels_air_temperature_derived),
64 + std::string(ufo::VariableNames::modellevels_average_air_temperature_derived)});
65 variableNamesGeoVaLs.insert
66 (variableNamesGeoVaLs.end(),
67 {ufo::VariableNames::geovals_air_temperature,
68 ufo::VariableNames::geovals_average_air_temperature,
69 ufo::VariableNames::geovals_average_air_temperature_qcflags});
72 std::vector <ProfileDataHolder> profiles =
82 const size_t halfnprofs = profileDataHandler.
getObsdb().nrecs() / 2;
83 for (
size_t jprof = 0; jprof < halfnprofs; ++jprof) {
84 oops::Log::debug() <<
" Profile " << (jprof + 1) <<
" / " << halfnprofs << std::endl;
85 auto& profileOriginal = profiles[jprof];
86 auto& profileExtended = profiles[jprof + halfnprofs];
93 for (
size_t jprof = 0; jprof < halfnprofs * 2; ++jprof) {
112 if (numProfileLevels <= 1)
115 const std::vector <float> &tObs =
117 const std::vector <float> &tPGEBd =
119 std::vector <int> &tFlags =
121 std::vector <int> &rhFlags =
123 const std::vector <float> &tObsCorrection =
125 std::vector <int> &NumGapsT =
128 if (!oops::allVectorsSameNonZeroSize(tObs, tPGEBd, tFlags, rhFlags, tObsCorrection)) {
129 oops::Log::warning() <<
"At least one vector is the wrong size. "
130 <<
"Temperature averaging will not be performed." << std::endl;
131 oops::Log::warning() <<
"Vector sizes: "
132 << oops::listOfVectorSizes(tObs, tPGEBd, tFlags, rhFlags, tObsCorrection)
143 const std::vector <float> &potempGeoVaLs =
145 if (potempGeoVaLs.empty())
146 throw eckit::BadValue(
"Potential temperature GeoVaLs vector is empty.", Here());
147 const size_t numModelLevels = potempGeoVaLs.size();
150 const std::vector <float> &ExnerPA =
152 const std::vector <float> &ExnerPB =
154 const std::vector <float> &LogPA =
156 const std::vector <float> &LogPB =
158 const std::vector <float> &RepLogP =
160 const std::vector <float> &BigGap =
163 if (!oops::allVectorsSameNonZeroSize(ExnerPA, LogPA) ||
164 !oops::allVectorsSameNonZeroSize(ExnerPB, LogPB) ||
165 !oops::allVectorsSameNonZeroSize(RepLogP, BigGap)) {
166 std::stringstream errorMessage;
167 errorMessage <<
"At least one model-level vector is the wrong size. "
168 <<
"Ensure that the AveragePressure routine has been run before this one."
170 errorMessage <<
"Vector sizes: "
171 << oops::listOfVectorSizes(ExnerPA, LogPA,
175 throw eckit::BadValue(errorMessage.str(), Here());
179 std::vector <float> tObsFinal;
184 for (
size_t jlev = 0; jlev < numProfileLevels; ++jlev) {
195 std::vector <float> tModObs;
196 std::vector <int> tFlagsModObs;
197 std::vector <float> LogP_Min;
198 std::vector <float> LogP_Max;
216 if (NumGaps > 0) NumGapsT[0]++;
221 std::vector <float> tModBkg = potempGeoVaLs;
222 std::transform(ExnerPB.begin(), ExnerPB.end(), tModBkg.begin(), tModBkg.begin(),
223 [
this](
float ExnerPBLev,
float potempLev)
224 {return potempLev != missingValueFloat && ExnerPBLev != missingValueFloat ?
225 potempLev * ExnerPBLev : missingValueFloat;});
234 for (
int JLev = 0; JLev < numModelLevels; ++JLev) {
238 LogP_Max[JLev] == LogP_Min[JLev])
242 const double DLogP = LogP_Max[JLev] - LogP_Min[JLev];
243 if (JLev < numModelLevels - 1) {
246 if (DLogP < 0.995 * (LogPA[JLev] - LogPA[JLev + 1])) {
248 const int MLev1 = std::max(JLev - 1, 0);
250 const int MLev2 = std::min(JLev + 1,
static_cast<int>(numModelLevels) - 1);
263 const double DExner =
270 potempGeoVaLs[JLev] * (ExnerPA[JLev] - ExnerPA[JLev + 1]) /
273 const double ModLogP_mid = 0.5 * (LogPA[JLev] + LogPA[JLev + 1]);
275 const double TGrad = (tModBkg[MLev1] - tModBkg[MLev2]) / (LogPB[MLev1] - LogPB[MLev2]);
277 const double TMax = TLev + (LogP_Min[JLev] - ModLogP_mid) * TGrad;
279 const double TMin = TLev + (LogP_Max[JLev] - ModLogP_mid) * TGrad;
281 const double potempBk =
284 const double Tinc = (potemp - potempBk) * ExnerPB[JLev];
286 tModObs[JLev] = tModBkg[JLev] + Tinc;
291 const double DExner = ExnerPA[JLev] - ExnerPA[JLev + 1];
293 const double potemp =
296 tModObs[JLev] = potemp * ExnerPB[JLev];
300 const double DExner =
306 tModObs[JLev] = potemp * ExnerPB[JLev];
311 profileExtended.
set<
float>
315 profileExtended.
set<
float>
319 profileExtended.
set<
int>
330 std::move(
profile.getGeoVaLVector
335 std::move(
profile.getGeoVaLVector
340 const std::vector <float>& average_air_temperature_qcflags_float =
343 std::vector <int> average_air_temperature_qcflags_int
344 (average_air_temperature_qcflags_float.begin(),
345 average_air_temperature_qcflags_float.end());
346 std::replace(average_air_temperature_qcflags_int.begin(),
347 average_air_temperature_qcflags_int.end(),
352 std::move(average_air_temperature_qcflags_int));
Options controlling the operation of the ConventionalProfileProcessing filter.
oops::Parameter< bool > compareWithOPS
Compare with OPS values?
oops::Parameter< float > AvgT_SondeDZFraction
oops::Parameter< float > AvgT_PGEskip
void runCheck(ProfileDataHandler &profileDataHandler) override
void runCheckOnProfiles(ProfileDataHolder &profileOriginal, ProfileDataHolder &profileExtended)
ProfileAverageTemperature(const ConventionalProfileProcessingParameters &options)
void fillValidationData(ProfileDataHolder &profileDataHolder)
Fill variables in validator (for comparison with OPS output).
Profile QC checker base class.
const float missingValueFloat
Missing value (float)
const ConventionalProfileProcessingParameters & options_
Configurable parameters.
void correctVector(const std::vector< T > &v1, const std::vector< T > &v2, std::vector< T > &vout)
Apply correction to vector of values.
Retrieve and store data for individual profiles. To do this, first the vector of values in the entire...
void updateAllProfiles(std::vector< ProfileDataHolder > &profiles)
Read values from a collection of profiles and update information related to each one.
std::vector< ProfileDataHolder > produceProfileVector(const std::vector< std::string > &variableNamesInt, const std::vector< std::string > &variableNamesFloat, const std::vector< std::string > &variableNamesString, const std::vector< std::string > &variableNamesGeoVaLs, const std::vector< std::string > &variableNamesObsDiags)
Produce a vector of all profiles, loading the requested variables into each one.
ioda::ObsSpace & getObsdb()
Return obsdb.
Profile data holder class.
int getNumProfileLevels() const
Get number of profile levels for this profile.
std::vector< T > & get(const std::string &fullname)
Retrieve a vector if it is present. If not, throw an exception.
void set(const std::string &fullname, std::vector< T > &&vec_in)
Set values in a vector.
std::vector< float > & getGeoVaLVector(const std::string &fullname)
Retrieve a GeoVaL vector if it is present. If not, throw an exception.
void checkObsSpaceSection(ufo::ObsSpaceSection section)
Check this profile is in the expected ObsSpace section (original or extended).
@ FinalRejectFlag
Final QC flag.
void calculateVerticalAverage(const std::vector< int > &flagsIn, const std::vector< float > &valuesIn, const std::vector< float > &coordIn, const std::vector< float > &bigGap, const std::vector< float > &coordOut, float DZFrac, ProfileAveraging::Method method, std::vector< int > &flagsOut, std::vector< float > &valuesOut, int &numGaps, std::vector< float > *coordMax, std::vector< float > *coordMin)
Profile vertical averaging onto model levels.
static ProfileCheckMaker< ProfileAverageTemperature > makerProfileAverageTemperature_("AverageTemperature")
static constexpr double rd_over_cp
static constexpr double pref
static constexpr const char *const extended_obs_space
static constexpr const char *const modellevels_ExnerP_derived
static constexpr const char *const obs_air_temperature
static constexpr const char *const bigPgaps_derived
static constexpr const char *const modellevels_logP_derived
static constexpr const char *const geovals_average_air_temperature
static constexpr const char *const qcflags_relative_humidity
static constexpr const char *const geovals_potential_temperature
static constexpr const char *const LogP_derived
static constexpr const char *const modellevels_logP_rho_derived
static constexpr const char *const modellevels_ExnerP_rho_derived
static constexpr const char *const pgebd_air_temperature
static constexpr const char *const geovals_average_air_temperature_qcflags
static constexpr const char *const modellevels_air_temperature_derived
static constexpr const char *const counter_NumGapsT
static constexpr const char *const geovals_air_temperature
static constexpr const char *const qcflags_air_temperature
static constexpr const char *const modellevels_average_air_temperature_derived
static constexpr const char *const obscorrection_air_temperature
static constexpr const char *const modellevels_average_air_temperature_qcflags