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"
26 static ObsFunctionMaker<ObsErrorModelQuad>
37 eckit::LocalConfiguration yconf;
42 yconf.set(
"options", config);
47 ASSERT(xvar.
size() == 1 ||
52 const std::vector<float> &a =
options_.
a.value();
53 const std::vector<float> &b =
options_.
b.value();
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)
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]);
86 const std::vector<float> &a =
options_.
a.value();
87 const std::vector<float> &b =
options_.
b.value();
92 ASSERT(out.nvars() == a.size());
104 for (
size_t jvar = 0; jvar < out.nvars(); ++jvar) {
105 size_t ivar = std::min(jvar, xvar.
size() - 1);
109 if (a[jvar] < 0.0f) {
112 x0 = x1 - sqrt((err0[jvar] - c) / a[jvar]);
116 x1 = x0 + sqrt((err1[jvar] - c) / a[jvar]);
120 for (
size_t iloc = 0; iloc < in.
nlocs(); ++iloc) {
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;
128 out[jvar][iloc] = err1[jvar];