UFO
ObsErrorModelQuad.cc
Go to the documentation of this file.
1 /*
2  * (C) Copyright 2020 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 <cmath>
12 #include <set>
13 #include <string>
14 #include <vector>
15 
16 #include "ioda/ObsDataVector.h"
17 #include "oops/util/CompareNVectors.h"
18 #include "oops/util/IntSetParser.h"
19 #include "oops/util/Logger.h"
20 #include "oops/util/PropertiesOfNVectors.h"
21 #include "ufo/filters/Variable.h"
22 #include "ufo/utils/Constants.h"
23 
24 namespace ufo {
25 
26 static ObsFunctionMaker<ObsErrorModelQuad>
27  makerQuad_("ObsErrorModelQuad");
28 
29 // -----------------------------------------------------------------------------
30 
31 ObsErrorModelQuad::ObsErrorModelQuad(const eckit::LocalConfiguration & config)
32  : invars_() {
33  // Initialize options
34  options_.deserialize(config);
35 
36  // Initialize y-variable
37  eckit::LocalConfiguration yconf;
38  yconf.set("name", classname());
39  if (options_.chlist.value() != boost::none) {
40  yconf.set("channels", options_.chlist.value().get());
41  }
42  yconf.set("options", config);
43  Variable yvar(yconf);
44 
45  // Initialize x-variable
46  const Variable &xvar = options_.xvar.value();
47  ASSERT(xvar.size() == 1 ||
48  xvar.size() == yvar.size());
49  invars_ += xvar;
50 
51  // Get piece-wise parameters from options
52  const std::vector<float> &a = options_.a.value();
53  const std::vector<float> &b = options_.b.value();
54  const std::vector<float> &err0 = options_.err0.value();
55  const std::vector<float> &err1 = options_.err1.value();
56 
57  // Check parameter sizes/values
58  if (!oops::allVectorsSameNonZeroSize(a, b, err0, err1)) {
59  oops::Log::warning() << "At least one vector is the wrong size. "
60  << "Check will not be performed." << std::endl;
61  oops::Log::warning() << "Vector sizes: "
62  << oops::listOfVectorSizes(a, b, err0, err1)
63  << std::endl;
64  return;
65  }
66 
67  for (size_t i = 0; i < yvar.size(); ++i) {
68  ASSERT(abs(a[i]) > 0.0);
69  ASSERT(err0[i] > 0.0);
70  ASSERT(err1[i] > 0.0);
71  ASSERT(err1[i] >= err0[i]);
72  }
73 }
74 
75 // -----------------------------------------------------------------------------
76 
78 
79 // -----------------------------------------------------------------------------
80 
82  ioda::ObsDataVector<float> & out) const {
83  const float missing = util::missingValue(missing);
84 
85  // Get piece-wise parameters from options
86  const std::vector<float> &a = options_.a.value();
87  const std::vector<float> &b = options_.b.value();
88  const std::vector<float> &err0 = options_.err0.value();
89  const std::vector<float> &err1 = options_.err1.value();
90 
91  // Check out size
92  ASSERT(out.nvars() == a.size());
93 
94  // Compute x values
95  const Variable &xvar = options_.xvar.value();
97  in.get(xvar, xvals);
98 
99  // Optional save of the xfunc values
100  if (options_.save) xvals.save("ObsFunction");
101 
102  float x0, x1, c;
103 
104  for (size_t jvar = 0; jvar < out.nvars(); ++jvar) {
105  size_t ivar = std::min(jvar, xvar.size() - 1);
106 
107  // Calculate the inflection point x-values (x0, x1)
108  // and quadratic apex y-value (c)
109  if (a[jvar] < 0.0f) {
110  c = err1[jvar];
111  x1 = b[jvar];
112  x0 = x1 - sqrt((err0[jvar] - c) / a[jvar]);
113  } else {
114  c = err0[jvar];
115  x0 = b[jvar];
116  x1 = x0 + sqrt((err1[jvar] - c) / a[jvar]);
117  }
118 
119  // Calculate piece-wise function value across locations
120  for (size_t iloc = 0; iloc < in.nlocs(); ++iloc) {
121  out[jvar][iloc] = missing;
122  if (xvals[ivar][iloc] != missing) {
123  if (xvals[ivar][iloc] <= x0) {
124  out[jvar][iloc] = err0[jvar];
125  } else if (xvals[ivar][iloc] < x1) {
126  out[jvar][iloc] = a[jvar] * pow(xvals[ivar][iloc] - b[jvar], 2) + c;
127  } else {
128  out[jvar][iloc] = err1[jvar];
129  }
130  }
131  }
132  }
133 }
134 
135 // -----------------------------------------------------------------------------
136 
138  return invars_;
139 }
140 
141 // -----------------------------------------------------------------------------
142 
143 } // namespace ufo
ufo::ObsErrorModelQuad::compute
void compute(const ObsFilterData &, ioda::ObsDataVector< float > &) const
compute the result of the function
Definition: ObsErrorModelQuad.cc:81
ufo::ObsErrorModelQuadParameters::save
oops::Parameter< bool > save
whether to save the xfunc values to the ObsSpace
Definition: ObsErrorModelQuad.h:48
ufo::ObsErrorModelQuad::invars_
ufo::Variables invars_
Definition: ObsErrorModelQuad.h:127
ufo::ObsFilterData::nlocs
size_t nlocs() const
Returns number of locations.
Definition: ObsFilterData.cc:66
ufo::Variables
Definition: src/ufo/filters/Variables.h:24
ufo::ObsErrorModelQuad::options_
ObsErrorModelQuadParameters options_
Definition: ObsErrorModelQuad.h:128
ufo::ObsErrorModelQuadParameters::err1
oops::RequiredParameter< std::vector< float > > err1
y-coordinate of the upper piecewise inflection point
Definition: ObsErrorModelQuad.h:46
ufo::ObsFilterData::obsspace
ioda::ObsSpace & obsspace() const
Returns reference to ObsSpace associated with ObsFilterData.
Definition: src/ufo/filters/ObsFilterData.h:84
ufo::ObsErrorModelQuadParameters::a
oops::RequiredParameter< std::vector< float > > a
curvature of the quadratic function
Definition: ObsErrorModelQuad.h:40
ufo::Variable::size
size_t size() const
Definition: Variable.cc:79
ufo::Variable::toOopsVariables
oops::Variables toOopsVariables() const
Definition: Variable.cc:129
ufo::ObsErrorModelQuadParameters::b
oops::RequiredParameter< std::vector< float > > b
x-coordinate of the quadratic function apex
Definition: ObsErrorModelQuad.h:42
ufo
Definition: RunCRTM.h:27
ufo::ObsErrorModelQuad::~ObsErrorModelQuad
~ObsErrorModelQuad()
Definition: ObsErrorModelQuad.cc:77
ufo::QCflags::missing
constexpr int missing
Definition: QCflags.h:15
ufo::makerQuad_
static ObsFunctionMaker< ObsErrorModelQuad > makerQuad_("ObsErrorModelQuad")
ufo::abs
util::Duration abs(const util::Duration &duration)
Definition: TrackCheckUtils.h:31
ufo::ObsErrorModelQuadParameters::xvar
oops::RequiredParameter< Variable > xvar
x variable of the piece-wise function
Definition: ObsErrorModelQuad.h:33
ufo::ObsErrorModelQuad::classname
static const std::string classname()
Definition: ObsErrorModelQuad.h:118
ioda::ObsDataVector
Definition: BackgroundCheck.h:26
ufo::ObsErrorModelQuad::ObsErrorModelQuad
ObsErrorModelQuad(const eckit::LocalConfiguration &)
Definition: ObsErrorModelQuad.cc:31
ObsErrorModelQuad.h
ufo::ObsErrorModelQuad::requiredVariables
const ufo::Variables & requiredVariables() const
geovals required to compute the function
Definition: ObsErrorModelQuad.cc:137
ufo::ObsErrorModelQuadParameters::err0
oops::RequiredParameter< std::vector< float > > err0
y-coordinate of the lower piecewise inflection point
Definition: ObsErrorModelQuad.h:44
Constants.h
ufo::ObsFilterData::get
void get(const Variable &, std::vector< float > &) const
Gets requested data from ObsFilterData.
Definition: ObsFilterData.cc:130
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
Variable.h
ufo::ObsErrorModelQuadParameters::chlist
oops::OptionalParameter< std::string > chlist
Definition: ObsErrorModelQuad.h:38