UFO
InflateError.cc
Go to the documentation of this file.
1 /*
2  * (C) Copyright 2019 UCAR
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 
9 
10 #include <algorithm>
11 #include <set>
12 
13 #include "ioda/ObsDataVector.h"
14 #include "oops/base/Variables.h"
15 #include "oops/util/IntSetParser.h"
17 #include "ufo/filters/QCflags.h"
18 #include "ufo/utils/StringUtils.h"
19 
20 namespace ufo {
21 
22 // -----------------------------------------------------------------------------
23 
25 
26 // -----------------------------------------------------------------------------
27 
28 InflateError::InflateError(const eckit::Configuration & conf)
29  : allvars_(), conf_(conf) {
30  if (conf_.has("inflation variable")) {
31  allvars_ += Variable(conf_.getSubConfiguration("inflation variable"));
32  }
33  ASSERT(conf_.has("inflation variable") || conf_.has("inflation factor"));
34 }
35 
36 // -----------------------------------------------------------------------------
37 
38 void InflateError::apply(const Variables & vars,
39  const std::vector<std::vector<bool>> & flagged,
40  const ObsFilterData & data,
42  ioda::ObsDataVector<float> & obserr) const {
43  oops::Log::debug() << " InflateError input obserr: " << obserr << std::endl;
44  // If float factor is specified
45  if (conf_.has("inflation factor")) {
46  float factor = conf_.getFloat("inflation factor");
47  for (size_t jv = 0; jv < vars.nvars(); ++jv) {
48  size_t iv = obserr.varnames().find(vars.variable(jv).variable());
49  size_t kv = flags.varnames().find(vars.variable(jv).variable());
50  for (size_t jobs = 0; jobs < obserr.nlocs(); ++jobs) {
51  if (flagged[iv][jobs] && flags[kv][jobs] == QCflags::pass) {
52  obserr[iv][jobs] *= factor;
53  }
54  }
55  }
56  // If variable is specified
57  } else if (conf_.has("inflation variable")) {
58  Variable factorvar(conf_.getSubConfiguration("inflation variable"));
59  ASSERT(factorvar.size() == 1 || factorvar.size() == vars.nvars());
60  ioda::ObsDataVector<float> factors(data.obsspace(), factorvar.toOopsVariables());
61  data.get(factorvar, factors);
62 
63  // if inflation factor is 1D variable, apply the same inflation factor to all variables
64  // factor_jv = {0, 0, 0, ..., 0} for all nvars
65  std::vector<size_t> factor_jv(vars.nvars(), 0);
66 
67  // if multiple variables are in the inflation factor, apply different factors to different
68  // variables
69  // factor_jv = {0, 1, 2, ..., nvars-1}
70  if (factorvar.size() == vars.nvars()) {
71  std::iota(factor_jv.begin(), factor_jv.end(), 0);
72  }
73 
74  // loop over all variables to update
75  for (size_t jv = 0; jv < vars.nvars(); ++jv) {
76  // find current variable index in obserr
77  size_t iv = obserr.varnames().find(vars.variable(jv).variable());
78  size_t kv = flags.varnames().find(vars.variable(jv).variable());
79  for (size_t jobs = 0; jobs < obserr.nlocs(); ++jobs) {
80  if (flagged[iv][jobs] && flags[kv][jobs] == QCflags::pass) {
81  obserr[iv][jobs] *= factors[factor_jv[jv]][jobs];
82  }
83  }
84  }
85  }
86  oops::Log::debug() << " InflateError output obserr: " << obserr << std::endl;
87 }
88 
89 // -----------------------------------------------------------------------------
90 
91 } // namespace ufo
ufo::InflateError::conf_
const eckit::LocalConfiguration conf_
Definition: InflateError.h:35
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_radiancerttov_utils_mod::debug
logical, public debug
Definition: ufo_radiancerttov_utils_mod.F90:100
ufo::ObsFilterData::obsspace
ioda::ObsSpace & obsspace() const
Returns reference to ObsSpace associated with ObsFilterData.
Definition: src/ufo/filters/ObsFilterData.h:84
ufo::Variable::size
size_t size() const
Definition: Variable.cc:79
ufo::Variable::toOopsVariables
oops::Variables toOopsVariables() const
Definition: Variable.cc:129
ufo::InflateError::apply
void apply(const Variables &, const std::vector< std::vector< bool >> &, const ObsFilterData &, ioda::ObsDataVector< int > &, ioda::ObsDataVector< float > &) const override
compute the diagnostic
Definition: InflateError.cc:38
ufo
Definition: RunCRTM.h:27
InflateError.h
ufo::FilterActionMaker
Definition: FilterActionBase.h:60
QCflags.h
ufo::Variable::variable
const std::string & variable() const
Definition: Variable.cc:100
ufo::InflateError::allvars_
Variables allvars_
Definition: InflateError.h:33
StringUtils.h
ufo::InflateError::InflateError
InflateError(const eckit::Configuration &)
Definition: InflateError.cc:28
ioda::ObsDataVector< int >
ufo::Variables::variable
Variable variable(const size_t) const
Definition: Variables.cc:114
ObsFilterData.h
ufo::ObsFilterData::get
void get(const Variable &, std::vector< float > &) const
Gets requested data from ObsFilterData.
Definition: ObsFilterData.cc:130
ufo::makerInflateErr_
static FilterActionMaker< InflateError > makerInflateErr_("inflate error")
ufo::Variable
Definition: Variable.h:23
ufo::ObsFilterData
ObsFilterData provides access to all data related to an ObsFilter.
Definition: src/ufo/filters/ObsFilterData.h:40
conf
Definition: conf.py:1