UFO
BackgroundCheck.cc
Go to the documentation of this file.
1 /* * (C) Copyright 2017-2018 UCAR
2  *
3  * This software is licensed under the terms of the Apache Licence Version 2.0
4  * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
5  */
6 
8 
9 #include <algorithm>
10 #include <cmath>
11 #include <iomanip>
12 #include <iostream>
13 #include <limits>
14 #include <set>
15 #include <string>
16 #include <vector>
17 
18 #include "eckit/config/Configuration.h"
19 
20 #include "ioda/ObsDataVector.h"
21 #include "ioda/ObsSpace.h"
22 
23 #include "oops/interface/ObsFilter.h"
24 #include "oops/util/abor1_cpp.h"
25 #include "oops/util/IntSetParser.h"
26 #include "oops/util/Logger.h"
27 
29 #include "ufo/filters/QCflags.h"
30 
31 namespace ufo {
32 
33 // -----------------------------------------------------------------------------
34 
35 BackgroundCheck::BackgroundCheck(ioda::ObsSpace & obsdb, const eckit::Configuration & config,
36  std::shared_ptr<ioda::ObsDataVector<int> > flags,
37  std::shared_ptr<ioda::ObsDataVector<float> > obserr)
38  : FilterBase(obsdb, config, flags, obserr),
39  abs_threshold_(config_.getString("absolute threshold", "")),
40  threshold_(config_.getString("threshold", "")),
41  function_abs_threshold_()
42 {
43  oops::Log::trace() << "BackgroundCheck constructor" << std::endl;
44 
45  if (config_.has("function absolute threshold")) {
46  std::vector<eckit::LocalConfiguration> threshconfs;
47  config_.get("function absolute threshold", threshconfs);
48  function_abs_threshold_ = threshconfs[0].getString("name");
49  allvars_ += ufo::Variables(threshconfs);
50  }
51  allvars_ += Variables(filtervars_, "HofX");
52  ASSERT(abs_threshold_ != "" || threshold_ != "" || function_abs_threshold_ != "");
53 }
54 
55 // -----------------------------------------------------------------------------
56 
58  oops::Log::trace() << "BackgroundCheck destructed" << std::endl;
59 }
60 
61 // -----------------------------------------------------------------------------
62 
63 void BackgroundCheck::applyFilter(const std::vector<bool> & apply,
64  const Variables & filtervars,
65  std::vector<std::vector<bool>> & flagged) const {
66  oops::Log::trace() << "BackgroundCheck postFilter" << std::endl;
67  const oops::Variables observed = obsdb_.obsvariables();
68  const float missing = util::missingValue(missing);
69 
70  oops::Log::debug() << "BackgroundCheck obserr: " << *obserr_;
71 
72  ioda::ObsDataVector<float> obs(obsdb_, filtervars.toOopsVariables(), "ObsValue");
73  ioda::ObsDataVector<float> bias(obsdb_, filtervars.toOopsVariables(), "ObsBias", false);
74 
75 // Get function absolute threshold
76  if (function_abs_threshold_ != "") {
77  ASSERT(abs_threshold_ == "" && threshold_ == "");
78 // Get function absolute threshold info from configuration
79  std::vector<eckit::LocalConfiguration> threshconfs;
80  config_.get("function absolute threshold", threshconfs);
81  Variable rtvar(threshconfs[0]);
82  ioda::ObsDataVector<float> function_abs_threshold(obsdb_, rtvar.toOopsVariables());
83  data_.get(rtvar, function_abs_threshold);
84 
85  Variables varhofx(filtervars_, "HofX");
86  for (size_t jv = 0; jv < filtervars.nvars(); ++jv) {
87  size_t iv = observed.find(filtervars.variable(jv).variable());
88 // H(x)
89  std::vector<float> hofx;
90  data_.get(varhofx.variable(jv), hofx);
91  for (size_t jobs = 0; jobs < obsdb_.nlocs(); ++jobs) {
92  if (apply[jobs] && (*flags_)[iv][jobs] == QCflags::pass) {
93  ASSERT((*obserr_)[iv][jobs] != util::missingValue((*obserr_)[iv][jobs]));
94  ASSERT(obs[jv][jobs] != util::missingValue(obs[jv][jobs]));
95  ASSERT(hofx[jobs] != util::missingValue(hofx[jobs]));
96 
97 // Threshold for current observation
98  float zz = function_abs_threshold[jv][jobs];
99 
100 // Apply bias correction
101  float yy = obs[jv][jobs] - bias[jv][jobs];
102 
103 // Check distance from background
104  if (std::abs(static_cast<float>(hofx[jobs]) - yy) > zz) flagged[jv][jobs] = true;
105  }
106  }
107  }
108  } else {
109  ASSERT(function_abs_threshold_ == "");
110  Variables varhofx(filtervars_, "HofX");
111  for (size_t jv = 0; jv < filtervars.nvars(); ++jv) {
112  size_t iv = observed.find(filtervars.variable(jv).variable());
113 // H(x)
114  std::vector<float> hofx;
115  data_.get(varhofx.variable(jv), hofx);
116 
117 // Threshold for current variable
118  std::vector<float> abs_thr(obsdb_.nlocs(), std::numeric_limits<float>::max());
119  std::vector<float> thr(obsdb_.nlocs(), std::numeric_limits<float>::max());
122 
123  for (size_t jobs = 0; jobs < obsdb_.nlocs(); ++jobs) {
124  if (apply[jobs] && (*flags_)[iv][jobs] == QCflags::pass) {
125  size_t iobs = observed.size() * jobs + iv;
126  ASSERT((*obserr_)[iv][jobs] != util::missingValue((*obserr_)[iv][jobs]));
127  ASSERT(obs[jv][jobs] != util::missingValue(obs[jv][jobs]));
128  ASSERT(hofx[jobs] != util::missingValue(hofx[jobs]));
129 
130 // Threshold for current observation
131  float zz = (thr[jobs] == std::numeric_limits<float>::max()) ? abs_thr[jobs] :
132  std::min(abs_thr[jobs], thr[jobs] * (*obserr_)[iv][jobs]);
133  ASSERT(zz < std::numeric_limits<float>::max() && zz > 0.0);
134 
135 // Apply bias correction
136  float yy = obs[jv][jobs] - bias[jv][jobs];
137 
138 // Check distance from background
139  if (std::abs(static_cast<float>(hofx[jobs]) - yy) > zz) flagged[jv][jobs] = true;
140  }
141  }
142  }
143  }
144 }
145 
146 // -----------------------------------------------------------------------------
147 
148 void BackgroundCheck::print(std::ostream & os) const {
149  os << "BackgroundCheck::print not yet implemented ";
150 }
151 
152 // -----------------------------------------------------------------------------
153 
154 } // namespace ufo
ufo::Variables::nvars
size_t nvars() const
Definition: Variables.cc:104
ufo::QCflags::pass
constexpr int pass
Definition: QCflags.h:14
ufo::Variables
Definition: src/ufo/filters/Variables.h:24
ufo::BackgroundCheck::threshold_
const std::string threshold_
Definition: BackgroundCheck.h:50
ufo_radiancerttov_utils_mod::debug
logical, public debug
Definition: ufo_radiancerttov_utils_mod.F90:100
ufo::FilterBase::obsdb_
ioda::ObsSpace & obsdb_
Definition: FilterBase.h:59
ufo::BackgroundCheck::abs_threshold_
const std::string abs_threshold_
Definition: BackgroundCheck.h:49
ufo::BackgroundCheck::print
void print(std::ostream &) const override
Definition: BackgroundCheck.cc:148
getScalarOrFilterData.h
ufo::FilterBase
FilterBase: Base class for UFO QC filters.
Definition: FilterBase.h:42
BackgroundCheck.h
ufo::Variable::toOopsVariables
oops::Variables toOopsVariables() const
Definition: Variable.cc:129
ufo
Definition: RunCRTM.h:27
ufo::FilterBase::obserr_
std::shared_ptr< ioda::ObsDataVector< float > > obserr_
Definition: FilterBase.h:62
ufo::FilterBase::data_
ObsFilterData data_
Definition: FilterBase.h:65
ufo::BackgroundCheck::applyFilter
void applyFilter(const std::vector< bool > &, const Variables &, std::vector< std::vector< bool >> &) const override
Definition: BackgroundCheck.cc:63
ufo::FilterBase::allvars_
ufo::Variables allvars_
Definition: FilterBase.h:63
ufo::BackgroundCheck::BackgroundCheck
BackgroundCheck(ioda::ObsSpace &, const eckit::Configuration &, std::shared_ptr< ioda::ObsDataVector< int > >, std::shared_ptr< ioda::ObsDataVector< float > >)
Definition: BackgroundCheck.cc:35
ufo::FilterBase::flags_
std::shared_ptr< ioda::ObsDataVector< int > > flags_
Definition: FilterBase.h:61
ufo::QCflags::missing
constexpr int missing
Definition: QCflags.h:15
ufo::BackgroundCheck::~BackgroundCheck
~BackgroundCheck()
Definition: BackgroundCheck.cc:57
ufo::Variables::toOopsVariables
oops::Variables toOopsVariables() const
Definition: Variables.cc:144
QCflags.h
ufo::abs
util::Duration abs(const util::Duration &duration)
Definition: TrackCheckUtils.h:31
ufo::Variable::variable
const std::string & variable() const
Definition: Variable.cc:100
ufo::FilterBase::filtervars_
ufo::Variables filtervars_
Definition: FilterBase.h:64
ioda::ObsDataVector< int >
ufo::Variables::variable
Variable variable(const size_t) const
Definition: Variables.cc:114
ufo::FilterBase::config_
const eckit::LocalConfiguration config_
Definition: FilterBase.h:60
ufo::getScalarOrFilterData
std::vector< float > getScalarOrFilterData(const std::string &strfactor, const ObsFilterData &data)
Function to fill in a vector with either a scalar or data from ObsFilterData.
Definition: getScalarOrFilterData.cc:21
ufo::ObsFilterData::get
void get(const Variable &, std::vector< float > &) const
Gets requested data from ObsFilterData.
Definition: ObsFilterData.cc:130
ufo::BackgroundCheck::function_abs_threshold_
std::string function_abs_threshold_
Definition: BackgroundCheck.h:51
ufo::Variable
Definition: Variable.h:23