13 #include "eckit/config/Configuration.h"
15 #include "ioda/ObsDataVector.h"
16 #include "ioda/ObsSpace.h"
17 #include "ioda/ObsVector.h"
18 #include "oops/base/Variables.h"
19 #include "oops/interface/ObsFilter.h"
20 #include "oops/util/Logger.h"
21 #include "oops/util/missingValues.h"
35 : obsdb_(obsdb), config_(config), nogeovals_(), nodiags_(), flags_(qcflags),
36 observed_(obsdb.obsvariables())
38 oops::Log::trace() <<
"QCmanager::QCmanager starting " <<
config_ << std::endl;
45 ASSERT(obserr->nvars() ==
observed_.size());
46 ASSERT(obserr->nlocs() ==
obsdb_.nlocs());
48 const float rmiss = util::missingValue(rmiss);
49 const int imiss = util::missingValue(imiss);
53 for (
size_t jv = 0; jv <
observed_.size(); ++jv) {
54 for (
size_t jobs = 0; jobs <
obsdb_.nlocs(); ++jobs) {
55 if ((*
flags_)[jv][jobs] == imiss || obs[jv][jobs] == rmiss || (*obserr)[jv][jobs] == rmiss) {
61 oops::Log::trace() <<
"QCmanager::QCmanager done" << std::endl;
67 oops::Log::trace() <<
"QCmanager postFilter" << std::endl;
71 for (
size_t jv = 0; jv <
observed_.size(); ++jv) {
72 for (
size_t jobs = 0; jobs <
obsdb_.nlocs(); ++jobs) {
73 size_t iobs =
observed_.size() * jobs + jv;
79 oops::Log::trace() <<
"QCmanager postFilter done" << std::endl;
85 oops::Log::trace() <<
"QCmanager::~QCmanager starting" << std::endl;
86 oops::Log::info() << *
this;
87 oops::Log::trace() <<
"QCmanager::~QCmanager done" << std::endl;
93 for (
size_t jj = 0; jj <
observed_.size(); ++jj) {
94 size_t iobs =
obsdb_.nlocs();
113 for (
size_t jobs = 0; jobs < iobs; ++jobs) {
127 if ((*
flags_)[jj][jobs] == 76 || (*
flags_)[jj][jobs] == 77) ++ignss;
133 if (
obsdb_.isDistributed()) {
134 obsdb_.comm().allReduceInPlace(iobs, eckit::mpi::sum());
135 obsdb_.comm().allReduceInPlace(ipass, eckit::mpi::sum());
136 obsdb_.comm().allReduceInPlace(imiss, eckit::mpi::sum());
137 obsdb_.comm().allReduceInPlace(ipreq, eckit::mpi::sum());
138 obsdb_.comm().allReduceInPlace(ibnds, eckit::mpi::sum());
139 obsdb_.comm().allReduceInPlace(iwhit, eckit::mpi::sum());
140 obsdb_.comm().allReduceInPlace(iblck, eckit::mpi::sum());
141 obsdb_.comm().allReduceInPlace(iherr, eckit::mpi::sum());
142 obsdb_.comm().allReduceInPlace(ifgss, eckit::mpi::sum());
143 obsdb_.comm().allReduceInPlace(iclw, eckit::mpi::sum());
144 obsdb_.comm().allReduceInPlace(
iprof, eckit::mpi::sum());
145 obsdb_.comm().allReduceInPlace(ignss, eckit::mpi::sum());
146 obsdb_.comm().allReduceInPlace(ithin, eckit::mpi::sum());
147 obsdb_.comm().allReduceInPlace(idiffref, eckit::mpi::sum());
148 obsdb_.comm().allReduceInPlace(iseaice, eckit::mpi::sum());
149 obsdb_.comm().allReduceInPlace(itrack, eckit::mpi::sum());
150 obsdb_.comm().allReduceInPlace(ibuddy, eckit::mpi::sum());
151 obsdb_.comm().allReduceInPlace(idydx, eckit::mpi::sum());
154 if (
obsdb_.comm().rank() == 0) {
155 const std::string info =
"QC " +
flags_->obstype() +
" " +
observed_[jj] +
": ";
156 if (imiss > 0) os << info << imiss <<
" missing values." << std::endl;
157 if (ipreq > 0) os << info << ipreq <<
" rejected by pre QC." << std::endl;
158 if (ibnds > 0) os << info << ibnds <<
" out of bounds." << std::endl;
159 if (iwhit > 0) os << info << iwhit <<
" out of domain of use." << std::endl;
160 if (iblck > 0) os << info << iblck <<
" black-listed." << std::endl;
161 if (iherr > 0) os << info << iherr <<
" H(x) failed." << std::endl;
162 if (ithin > 0) os << info << ithin <<
" removed by thinning." << std::endl;
163 if (idydx > 0) os << info << idydx <<
" dy/dx out of valid range." << std::endl;
164 if (iclw > 0) os << info << iclw <<
" removed by cloud liquid water check." << std::endl;
165 if (
iprof > 0) os << info <<
iprof <<
" removed by profile consistency check." << std::endl;
166 if (ifgss > 0) os << info << ifgss <<
" rejected by first-guess check." << std::endl;
167 if (ignss > 0) os << info << ignss <<
" rejected by GNSSRO reality check." << std::endl;
168 if (idiffref > 0) os << info << idiffref <<
" rejected by difference check." << std::endl;
169 if (iseaice > 0) os << info << iseaice <<
" removed by sea ice check." << std::endl;
170 if (itrack > 0) os << info << itrack <<
" removed by track check." << std::endl;
171 if (ibuddy > 0) os << info << ibuddy <<
" removed by buddy check." << std::endl;
173 os << info << ipass <<
" passed out of " << iobs <<
" observations." << std::endl;
176 ASSERT(ipass + imiss + ipreq + ibnds + iwhit + iblck + iherr + ithin + iclw +
iprof + ifgss + \
177 ignss + idiffref + iseaice + itrack + ibuddy + idydx == iobs);