UFO
ProfileCheckValidator.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 
8 #include <algorithm>
9 #include <map>
10 #include <memory>
11 #include <string>
12 
13 #include "eckit/exception/Exceptions.h"
14 
15 #include "oops/util/Logger.h"
16 
19 
20 #include "ufo/utils/StringUtils.h"
21 
22 namespace ufo {
24  ProfileDataHandler &profileDataHandler)
25  : options_(options),
26  profileDataHandler_(profileDataHandler)
27  {
28  // Set offsets due to C++ and Fortran array index starting values
35 
36  // List of checks performed
37  std::vector <std::string> checks = options_.Checks.value();
38 
39  // Loop over each check and populate lists of integer and float values to compare
40  for (const auto& check : checks) {
41  if (check == "Basic") {
42  } else if (check == "SamePDiffT") {
43  valuesToCompare_int_.insert({
47  } else if (check == "Sign") {
48  valuesToCompare_int_.insert({
52  } else if (check == "UnstableLayer") {
53  valuesToCompare_int_.insert({
57  valuesToCompare_float_.insert({
59  } else if (check == "Interpolation") {
60  valuesToCompare_int_.insert({
72  valuesToCompare_float_.insert({
75  } else if (check == "Hydrostatic") {
76  valuesToCompare_int_.insert({
86  valuesToCompare_float_.insert({
89  } else if (check == "UInterp") {
90  valuesToCompare_int_.insert({
100  valuesToCompare_float_.insert({
104  } else if (check == "RH") {
105  valuesToCompare_int_.insert({
114  valuesToCompare_float_.insert({
121  } else if (check == "Time") {
122  valuesToCompare_int_.insert({
125  } else if (check == "PermanentReject") {
126  valuesToCompare_int_.insert({
132  } else if (check.find("Background") != std::string::npos) {
133  valuesToCompare_int_.insert({
139  valuesToCompare_float_.insert({
150  }
151  }
152  }
153 
154  /// Comparison of single values
155  template <typename T>
156  void ProfileCheckValidator::compareOutput(const std::string &desc,
157  const T val1,
158  const T val2,
159  const int offset,
160  const float tol,
161  int &n)
162  {
163  if (!differenceWithinTol(val1, val2 + offset, tol)) {
164  oops::Log::debug() << "Mismatch for " << desc << " (OPS, this code): "
165  << val1 << ", " << val2 + offset << std::endl;
166  n++;
167  }
168  }
169 
170  /// Comparison of vectors of values
171  template <typename T>
172  void ProfileCheckValidator::compareOutput(const std::string &desc,
173  const std::vector <T> &vec1,
174  const std::vector <T> &vec2,
175  const int offset,
176  const float tol,
177  int &n)
178  {
179  // Do not compare vectors if at least one is empty
180  if (oops::anyVectorEmpty(vec1, vec2))
181  {
182  if (vec1.empty())
183  oops::Log::debug() << "Vector of " << desc << " in OPS output is empty" << std::endl;
184  if (vec2.empty())
185  oops::Log::debug() << "Vector of " << desc << " in this code is empty" << std::endl;
186  return;
187  }
188  // Compare vector elements up to the smaller of the two sizes.
189  const size_t vecsize = std::min(vec1.size(), vec2.size());
190  for (size_t jvec = 0; jvec < vecsize; ++jvec) {
191  if (!differenceWithinTol(vec1[jvec], vec2[jvec] + offset, tol)) {
192  oops::Log::debug() << "Mismatch for " << desc << "[" << jvec << "] "
193  << "(OPS, this code): " << vec1[jvec] << ", "
194  << vec2[jvec] + offset << std::endl;
195  n++;
196  }
197  }
198  }
199 
201  {
202  oops::Log::debug() << " Comparing values against OPS equivalents..." << std::endl;
203 
204  // Reset number of mismatches for this profile
205  nMismatches_ = 0;
206 
207  float tol = options_.Comparison_Tol.value(); // Comparison tolerance
208 
209  // Compare integer values obtained in this code and OPS
210  for (const auto& valueToCompare_int : valuesToCompare_int_) {
211  std::string varname;
212  std::string groupname;
213  ufo::splitVarGroup(valueToCompare_int, varname, groupname);
214  std::string varname_OPS = "OPS_" + valueToCompare_int;
215  if (groupname == "Counters") {
216  /// Special case: OPS counters have one value per profile level,
217  /// and are in the MetaData rather than the Counters group.
218  /// This avoids the (default) treatment which assumes
219  /// that variables in the Counters group have one value per profile.
220  varname_OPS = "OPS_" + varname + "@MetaData";
221  }
222 
223  // Obtain values for comparison
224  const std::vector <int> &values_thiscode =
225  profileDataHandler_.get<int>(valueToCompare_int);
226  const std::vector <int> &values_OPS =
227  profileDataHandler_.get<int>(varname_OPS);
228 
229  // Account for potential offset between values in this code and OPS
230  int offset = 0;
231 
232  // Offsets due to C++ and Fortran array indices
233  auto comparison_offsets_it = comparison_offsets_.find(valueToCompare_int);
234  if (comparison_offsets_it != comparison_offsets_.end())
235  offset = comparison_offsets_it->second;
236 
237  // Offsets due to particular counters being accumulated over profiles in OPS
238  // (and not in this code). NumAnyErrors is not included.
239  if (groupname == "Counters" && varname != "NumAnyErrors")
240  offset = cumulativeCounters_[valueToCompare_int];
241 
242  // Only the first element of each counter is compared;
243  // in all other cases tne entire vectors are compared.
244  if (groupname == "Counters") {
245  if (!oops::anyVectorEmpty(values_OPS, values_thiscode))
246  compareOutput(valueToCompare_int, values_OPS[0], values_thiscode[0],
247  offset, tol, nMismatches_);
248  } else {
249  compareOutput(valueToCompare_int, values_OPS, values_thiscode,
250  offset, tol, nMismatches_);
251  }
252 
253  // Increment cumulative counters. NumAnyErrors is not included.
254  if (groupname == "Counters" && varname != "NumAnyErrors")
255  cumulativeCounters_[valueToCompare_int] += values_thiscode[0];
256  }
257 
258  // Compare float values obtained in this code and OPS
259  for (const auto& valueToCompare_float : valuesToCompare_float_) {
260  const std::vector <float> &values_thiscode =
261  profileDataHandler_.get<float>(valueToCompare_float);
262  const std::vector <float> &values_OPS =
263  profileDataHandler_.get<float>("OPS_" + valueToCompare_float);
264  compareOutput(valueToCompare_float, values_OPS, values_thiscode,
265  0, tol, nMismatches_);
266  }
267 
268  oops::Log::debug() << " ... all comparisons done ("
269  << nMismatches_ << " mismatches)" << std::endl;
270  }
271 } // namespace ufo
272 
273 
ufo::VariableNames::counter_NumAnyErrors
static constexpr const char *const counter_NumAnyErrors
Definition: VariableNames.h:101
ufo::ProfileCheckValidator::profileDataHandler_
ProfileDataHandler & profileDataHandler_
Profile data handler.
Definition: ProfileCheckValidator.h:67
ufo::ProfileDataHandler
Retrieve and store data for individual profiles. To do this, first the vector of values in the entire...
Definition: ProfileDataHandler.h:40
ufo::ProfileCheckValidator::cumulativeCounters_
std::map< std::string, int > cumulativeCounters_
Counters that are accumulated across profiles.
Definition: ProfileCheckValidator.h:70
ufo::VariableNames::pgebd_air_temperature
static constexpr const char *const pgebd_air_temperature
Definition: VariableNames.h:67
ufo::ProfileCheckValidator::nMismatches_
int nMismatches_
Number of mismatches between this code and OPS (separate for each profile).
Definition: ProfileCheckValidator.h:73
ufo::VariableNames::HydError
static constexpr const char *const HydError
Definition: VariableNames.h:130
ufo::VariableNames::StdLev
static constexpr const char *const StdLev
Definition: VariableNames.h:132
ufo::ProfileCheckValidator::differenceWithinTol
bool differenceWithinTol(const T A, const T B, const float tol=1e-10) const
Determine difference between two values within a certain tolerance.
Definition: ProfileCheckValidator.h:59
ufo_geovals_mod::check
subroutine check(action, status)
Definition: ufo_geovals_mod.F90:1146
ufo::VariableNames::pgebd_relative_humidity
static constexpr const char *const pgebd_relative_humidity
Definition: VariableNames.h:69
ufo::VariableNames::IndStd
static constexpr const char *const IndStd
Definition: VariableNames.h:135
ufo::splitVarGroup
void splitVarGroup(const std::string &vargrp, std::string &var, std::string &grp)
Definition: StringUtils.cc:19
ufo::VariableNames::qcflags_northward_wind
static constexpr const char *const qcflags_northward_wind
Definition: VariableNames.h:96
ufo::ProfileCheckValidator::ProfileCheckValidator
ProfileCheckValidator(const ProfileConsistencyCheckParameters &options, ProfileDataHandler &profileDataHandler)
Definition: ProfileCheckValidator.cc:23
ufo::VariableNames::pge_northward_wind
static constexpr const char *const pge_northward_wind
Definition: VariableNames.h:61
ufo::ProfileCheckValidator::options_
const ProfileConsistencyCheckParameters & options_
Configurable parameters.
Definition: ProfileCheckValidator.h:64
ufo::ProfileConsistencyCheckParameters::Checks
oops::Parameter< std::vector< std::string > > Checks
List of checks to perform.
Definition: ProfileConsistencyCheckParameters.h:45
ufo::VariableNames::tbk
static constexpr const char *const tbk
Definition: VariableNames.h:147
ufo_radiancerttov_utils_mod::debug
logical, public debug
Definition: ufo_radiancerttov_utils_mod.F90:100
ufo::VariableNames::qcflags_eastward_wind
static constexpr const char *const qcflags_eastward_wind
Definition: VariableNames.h:95
ufo::VariableNames::PBottom
static constexpr const char *const PBottom
Definition: VariableNames.h:131
ufo::VariableNames::counter_NumHydErrObs
static constexpr const char *const counter_NumHydErrObs
Definition: VariableNames.h:107
ufo::VariableNames::ETol
static constexpr const char *const ETol
Definition: VariableNames.h:127
ufo::ProfileCheckValidator::valuesToCompare_float_
std::set< std::string > valuesToCompare_float_
Float values to compare.
Definition: ProfileCheckValidator.h:79
ufo::VariableNames::pge_geopotential_height
static constexpr const char *const pge_geopotential_height
Definition: VariableNames.h:62
ufo::VariableNames::Temp
static constexpr const char *const Temp
Definition: VariableNames.h:144
ufo::VariableNames::qcflags_relative_humidity
static constexpr const char *const qcflags_relative_humidity
Definition: VariableNames.h:93
ufo::ProfileCheckValidator::compareOutput
void compareOutput(const std::string &desc, const T val1, const T val2, const int offset, const float tol, int &n)
Compare values with specified offset and tolerance.
Definition: ProfileCheckValidator.cc:156
ufo::VariableNames::LogP
static constexpr const char *const LogP
Definition: VariableNames.h:140
ufo::VariableNames::pge_air_temperature
static constexpr const char *const pge_air_temperature
Definition: VariableNames.h:57
ufo::VariableNames::vInterp
static constexpr const char *const vInterp
Definition: VariableNames.h:139
ufo::VariableNames::counter_TotCFlags
static constexpr const char *const counter_TotCFlags
Definition: VariableNames.h:114
ufo::VariableNames::qcflags_geopotential_height
static constexpr const char *const qcflags_geopotential_height
Definition: VariableNames.h:94
ufo::VariableNames::LevErrors
static constexpr const char *const LevErrors
Definition: VariableNames.h:136
ufo
Definition: RunCRTM.h:27
ufo::VariableNames::SigBelow
static constexpr const char *const SigBelow
Definition: VariableNames.h:134
ufo::VariableNames::counter_TotLFlags
static constexpr const char *const counter_TotLFlags
Definition: VariableNames.h:116
ufo::VariableNames::counter_NumSamePErrObs
static constexpr const char *const counter_NumSamePErrObs
Definition: VariableNames.h:102
ufo::ProfileCheckValidator::comparison_offsets_
std::map< std::string, int > comparison_offsets_
Definition: ProfileCheckValidator.h:83
ufo::VariableNames::counter_Num925Miss
static constexpr const char *const counter_Num925Miss
Definition: VariableNames.h:104
ufo::VariableNames::td
static constexpr const char *const td
Definition: VariableNames.h:146
ufo::VariableNames::uInterp
static constexpr const char *const uInterp
Definition: VariableNames.h:138
ufo::VariableNames::Press
static constexpr const char *const Press
Definition: VariableNames.h:143
ufo::VariableNames::tInterp
static constexpr const char *const tInterp
Definition: VariableNames.h:137
ufo::ProfileCheckValidator::valuesToCompare_int_
std::set< std::string > valuesToCompare_int_
Integer values to compare.
Definition: ProfileCheckValidator.h:76
ufo::VariableNames::DC
static constexpr const char *const DC
Definition: VariableNames.h:126
ufo::VariableNames::counter_NumStdMiss
static constexpr const char *const counter_NumStdMiss
Definition: VariableNames.h:106
ufo::ProfileConsistencyCheckParameters
Options controlling the operation of the ProfileConsistencyChecks filter.
Definition: ProfileConsistencyCheckParameters.h:33
ufo::VariableNames::counter_TotHProfs
static constexpr const char *const counter_TotHProfs
Definition: VariableNames.h:113
ufo::VariableNames::counter_TotCProfs
static constexpr const char *const counter_TotCProfs
Definition: VariableNames.h:112
ufo::VariableNames::rhbk
static constexpr const char *const rhbk
Definition: VariableNames.h:148
ProfileCheckValidator.h
ufo::VariableNames::counter_NumInterpErrObs
static constexpr const char *const counter_NumInterpErrObs
Definition: VariableNames.h:110
ufo::VariableNames::counter_NumInterpErrors
static constexpr const char *const counter_NumInterpErrors
Definition: VariableNames.h:109
StringUtils.h
ufo::VariableNames::counter_NumSuperadiabat
static constexpr const char *const counter_NumSuperadiabat
Definition: VariableNames.h:103
ufo::VariableNames::counter_NumSignChange
static constexpr const char *const counter_NumSignChange
Definition: VariableNames.h:111
ufo::VariableNames::NumStd
static constexpr const char *const NumStd
Definition: VariableNames.h:141
ufo::ProfileCheckValidator::validate
void validate()
Validate check results against OPS values.
Definition: ProfileCheckValidator.cc:200
ufo::VariableNames::pge_eastward_wind
static constexpr const char *const pge_eastward_wind
Definition: VariableNames.h:60
ufo::VariableNames::qcflags_air_temperature
static constexpr const char *const qcflags_air_temperature
Definition: VariableNames.h:92
ufo::VariableNames::counter_TotHFlags
static constexpr const char *const counter_TotHFlags
Definition: VariableNames.h:115
ufo::VariableNames::pgebd_northward_wind
static constexpr const char *const pgebd_northward_wind
Definition: VariableNames.h:73
ufo::VariableNames::Indx
static constexpr const char *const Indx
Definition: VariableNames.h:150
VariableNames.h
ufo::VariableNames::FlagH
static constexpr const char *const FlagH
Definition: VariableNames.h:149
ufo::ProfileDataHandler::get
std::vector< T > & get(const std::string &fullname)
Definition: ProfileDataHandler.h:53
ufo::VariableNames::counter_Num100Miss
static constexpr const char *const counter_Num100Miss
Definition: VariableNames.h:105
ufo::VariableNames::SigAbove
static constexpr const char *const SigAbove
Definition: VariableNames.h:133
ufo::VariableNames::pge_relative_humidity
static constexpr const char *const pge_relative_humidity
Definition: VariableNames.h:58
ufo::VariableNames::pgebd_eastward_wind
static constexpr const char *const pgebd_eastward_wind
Definition: VariableNames.h:71
ufo::ProfileConsistencyCheckParameters::Comparison_Tol
oops::Parameter< float > Comparison_Tol
Tolerance for absolute difference comparisions.
Definition: ProfileConsistencyCheckParameters.h:324
ufo::VariableNames::NumSig
static constexpr const char *const NumSig
Definition: VariableNames.h:142
ufo::VariableNames::pgebd_geopotential_height
static constexpr const char *const pgebd_geopotential_height
Definition: VariableNames.h:75
ufo::VariableNames::counter_NumIntHydErrors
static constexpr const char *const counter_NumIntHydErrors
Definition: VariableNames.h:108
ufo::VariableNames::rh
static constexpr const char *const rh
Definition: VariableNames.h:145