27 const std::vector <float> &pressures =
29 const std::vector <float> &tObs =
31 const std::vector <float> &tBkg =
33 const std::vector <float> &zObs =
35 const std::vector <float> &zBkg =
37 std::vector <int> &tFlags =
39 std::vector <int> &zFlags =
41 std::vector <int> &NumAnyErrors =
43 std::vector <int> &Num925Miss =
45 std::vector <int> &Num100Miss =
47 std::vector <int> &NumStdMiss =
49 std::vector <int> &NumHydErrObs =
51 std::vector <int> &NumIntHydErrors =
53 const std::vector <float> &tObsCorrection =
55 std::vector <float> &zObsCorrection =
58 if (!oops::allVectorsSameNonZeroSize(pressures, tObs, tBkg, zObs, zBkg, tFlags, zFlags,
59 tObsCorrection, zObsCorrection)) {
60 oops::Log::warning() <<
"At least one vector is the wrong size. "
61 <<
"Check will not be performed." << std::endl;
62 oops::Log::warning() <<
"Vector sizes: "
63 << oops::listOfVectorSizes(pressures, tObs, tBkg, zObs, zBkg, tFlags,
64 zFlags, tObsCorrection, zObsCorrection)
69 std::vector <float> tObsFinal;
72 calcStdLevels(numProfileLevels, pressures, tObsFinal, tFlags);
84 for (
int jlevstd = 1; jlevstd <
NumStd_; ++jlevstd) {
86 int jlevB =
StdLev_[jlevstd - 1];
89 if (
IndStd_[jlevstd - 1] == -1) {
90 if (std::fabs(pressures[jlevB] - pressures[jlev]) >
108 <<
"P = " << pressures[jlev] * 0.01 <<
"hPa, tObs = "
112 <<
"P = " << pressures[jlevB] * 0.01 <<
"hPa, tObs = "
118 <<
"IndStd[" << jlevstd - 1 <<
"] = "
119 <<
IndStd_[jlevstd - 1] << std::endl;
124 D_[jlevstd] =
DC_[jlevstd] *
125 (tObsFinal[jlevB] + tObsFinal[jlev]);
129 float DB =
DC_[jlevstd] * (1.0 + TRatio) *
131 float DA =
DC_[jlevstd] * (1.0 / TRatio + 1.0) *
138 ETol_[jlevstd] = std::max(std::min(
ETol_[jlevstd], ETolMax), ETolMin);
139 E_[jlevstd] = zObs[jlev] - zObs[jlevB] -
D_[jlevstd];
140 if (std::fabs(
E_[jlevstd]) >
ETol_[jlevstd]) {
150 oops::Log::debug() <<
" -> removed interpolation flag on level " << jlevB << std::endl;
159 for (
int jlevstd = 2; jlevstd <
NumStd_; ++jlevstd) {
161 if (eckit::types::is_approximately_equal(
DC_[jlevstd - 1], 0.0f) ||
162 eckit::types::is_approximately_equal(
DC_[jlevstd], 0.0f))
continue;
164 int jlevB =
StdLev_[jlevstd - 1];
177 << jlev <<
" and " << jlevB << std::endl;
189 float EDC1 =
E_[jlevstd - 1] *
DC_[jlevstd];
190 float EDC2 =
E_[jlevstd] *
DC_[jlevstd - 1];
191 float MinAbsEDC = std::min(std::fabs(EDC1), std::fabs(EDC2));
193 *
DC_[jlevstd] *
DC_[jlevstd - 1];
194 float AbsEDCDiff = std::fabs(EDC1 - EDC2);
196 *
DC_[jlevstd] *
DC_[jlevstd - 1];
198 float MinAbsE = std::min(std::fabs(
E_[jlevstd - 1]), std::fabs(
E_[jlevstd]));
201 if (jlevstd <
NumStd_ - 1) ENext =
E_[jlevstd + 1];
204 if ((std::fabs(
E_[jlevstd - 1] +
E_[jlevstd]) <=
207 (std::fabs(
E_[jlevstd - 1] +
E_[jlevstd]) <=
211 oops::Log::debug() <<
" -> Failed hydrostatic check (height error) on level "
212 << jlevB << std::endl;
215 float Corr = 0.5 * (
E_[jlevstd] -
E_[jlevstd - 1]);
216 float CorrApp = 100.0 * std::round(Corr / 100.0);
219 <<
"hPa, zObs = " << zObs[jlevB] <<
"m, "
220 <<
"Z Correction? " << Corr <<
"m"
221 <<
", rounded = " << CorrApp <<
"m" << std::endl;
222 if (CorrApp != 0.0) {
225 zObsCorrection[jlevB] = CorrApp;
226 oops::Log::debug() <<
" -> Uncorrected zObs: " << zObs[jlevB] <<
"m" << std::endl;
229 << zObs[jlevB] + zObsCorrection[jlevB] <<
"m" << std::endl;
237 std::fabs(
E_[jlevstd - 1] +
E_[jlevstd] + ENext) <=
245 oops::Log::debug() <<
" -> Failed hydrostatic check (height error) on levels "
246 << jlevB <<
" and " << jlev << std::endl;
248 float Corr = -
E_[jlevstd - 1];
249 oops::Log::debug() <<
" -> P = " << pressures[jlevB] * 0.01 <<
"hPa, zObs = "
250 << zObs[jlevB] <<
"m, "
251 <<
"Z Correction? " << Corr <<
"m" << std::endl;
253 oops::Log::debug() <<
" -> P = " << pressures[jlev] * 0.01 <<
"hPa, zObs = "
254 << zObs[jlev] <<
"m, "
255 <<
"Z Correction? " << Corr <<
"m" << std::endl;
259 AbsEDCDiff <= CorrDiffThreshDC &&
260 MinAbsEDC >= CorrMinThreshDC) {
265 oops::Log::debug() <<
" -> Failed hydrostatic check (temperature error) on level "
266 << jlevB << std::endl;
269 float Corr1 =
E_.at(jlevstd - 1) /
DC_.at(jlevstd - 1);
270 float Corr2 =
E_.at(jlevstd) /
DC_.at(jlevstd);
271 float Corr = 0.5 * (Corr1 + Corr2);
272 oops::Log::debug() <<
" -> P = " << pressures[jlevB] * 0.01 <<
"hPa, tObs = "
274 <<
"T Correction? " << Corr <<
"C, "
275 <<
" Corr1, Corr2 = "
276 << Corr1 <<
"C, " << Corr2 <<
"C , DC[" << jlevstd - 1
277 <<
"], DC[" << jlevstd <<
"] = "
278 <<
DC_[jlevstd - 1] <<
", " <<
DC_[jlevstd]
288 NumIntHydErrors[0]++;
290 << SigB <<
" " << SigA << std::endl;
302 <<
"(bottom level error in T or Z) on level " << L1 << std::endl;
309 <<
"? P = " << pressures[L1] * 0.01 <<
"hPa, zObs = "
310 << zObs[L1] <<
"m, zBkg = " << zBkg[L1]
312 << zObs[L1] +
E_[jlevstd - 1] <<
"m" << std::endl;
320 <<
"(error in all subsequent heights) on level "
321 << jlevB << std::endl;
323 }
else if (
HydError_[jlevstd - 1] == 3) {
328 <<
"(T and/or Z error) on level " << jlevB << std::endl;
338 <<
"(top level error in T or Z) on level " << jlev << std::endl;
343 for (
int jlevstd = 0; jlevstd <
NumStd_; ++jlevstd) {
348 <<
"P = " << pressures[jlev] * 0.01 <<
"hPa, tObs = "
351 <<
"zObs = " << zObs[jlev] <<
"m, zBkg = " << zBkg[jlev] <<
"m, "
352 <<
"D = " <<
D_[jlevstd] <<
", E = " <<
E_[jlevstd]
353 <<
", ETol = " <<
ETol_[jlevstd] <<
", DC = " <<
DC_[jlevstd]
354 <<
", HydDesc = " <<
HydDesc_[HydType] <<
" " << std::endl;
Options controlling the operation of the ConventionalProfileProcessing filter.
oops::Parameter< bool > HCheck_CorrectZ
Correct zObs in the hydrostatic check?
oops::Parameter< float > HCheck_ETolMaxPThresh
oops::Parameter< float > HCheck_ETolMin
oops::Parameter< float > HCheck_MinAbsEThreshLarger
oops::Parameter< float > HCheck_SurfacePThresh
Surface P threshold for hydrostatic check (Pa)
oops::Parameter< float > HCheck_MinAbsEThreshT
oops::Parameter< float > HCheck_ETolMaxLarger
oops::Parameter< std::vector< std::string > > HydDesc
Hydrostatic error descriptions.
oops::Parameter< float > HCheck_EThreshB
oops::Parameter< float > HCheck_ESumNextThresh
oops::Parameter< float > HCheck_ESumThresh
oops::Parameter< float > HCheck_ETolMult
oops::Parameter< float > HCheck_EThresh
oops::Parameter< float > HCheck_ESumThreshLarger
oops::Parameter< float > HCheck_ETolMax
oops::Parameter< float > HCheck_MinAbsEThresh
oops::Parameter< float > HCheck_CorrMinThresh
oops::Parameter< float > HCheck_CorrThresh
oops::Parameter< float > HCheck_CorrDiffThresh
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.
std::vector< std::string > HydDesc_
Hydrostatic error descriptions.
std::vector< float > ETol_
Thickness tolerance.
std::vector< float > DC_
Constant in thickness calculation.
ProfileCheckHydrostatic(const ConventionalProfileProcessingParameters &options)
void fillValidationData(ProfileDataHandler &profileDataHandler) override
Fill variables in validator.
std::vector< int > HydError_
Hydrostatic flag by level.
std::vector< float > E_
Thickness 'error'.
std::vector< float > D_
Thickness calculated from temepature.
void runCheck(ProfileDataHandler &profileDataHandler) override
Run check.
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)
void set(const std::string &fullname, std::vector< T > &&vec_in)
int getNumProfileLevels() const
Return number of levels to which QC checks should be applied.
Calculate standard levels.
int Ind925_
Standard level index closest to 925 hPa.
int Ind100_
Standard level index closest to 100 hPa.
std::vector< int > StdLev_
Index of standard levels.
void findHCheckStdLevs()
Compute indices of particular standard levels for the hydrostatic check.
void calcStdLevels(const int numProfileLevels, const std::vector< float > &pressures, const std::vector< float > &tObs, const std::vector< int > &tFlags)
Calculate standard levels.
std::vector< float > LogP_
Log(Pressure) - used for vertical interpolation.
int NumStd_
Number of standard levels.
std::vector< int > IndStd_
Indices of standard levels.
std::vector< int > SigBelow_
Significant level below standard level.
std::vector< int > SigAbove_
Significant level above standard level.
@ InterpolationFlag
Interpolation check flag.
@ HydrostaticFlag
Hydrostatic check flag.
@ SurfaceLevelFlag
Surface Level.
@ FinalRejectFlag
Final QC flag.
@ DataCorrectFlag
Eg sign correction.
static ProfileCheckMaker< ProfileCheckHydrostatic > makerProfileCheckHydrostatic_("Hydrostatic")
static constexpr double rd_over_cp
static constexpr double rd_over_g
static constexpr double t0c
static constexpr const char *const ETol
static constexpr const char *const D
static constexpr const char *const hofx_air_temperature
static constexpr const char *const obs_air_temperature
static constexpr const char *const counter_NumAnyErrors
static constexpr const char *const counter_NumHydErrObs
static constexpr const char *const E
static constexpr const char *const HydError
static constexpr const char *const obs_geopotential_height
static constexpr const char *const DC
static constexpr const char *const counter_NumStdMiss
static constexpr const char *const hofx_geopotential_height
static constexpr const char *const counter_Num100Miss
static constexpr const char *const obs_air_pressure
static constexpr const char *const qcflags_air_temperature
static constexpr const char *const obscorrection_air_temperature
static constexpr const char *const counter_Num925Miss
static constexpr const char *const counter_NumIntHydErrors
static constexpr const char *const obscorrection_geopotential_height
static constexpr const char *const qcflags_geopotential_height