16 #include "ioda/ObsDataVector.h"
17 #include "oops/util/IntSetParser.h"
18 #include "oops/util/missingValues.h"
24 static ObsFunctionMaker<ObsErrorModelRamp>
29 ObsErrorModelRamp::ObsErrorModelRamp(
const eckit::LocalConfiguration config)
32 options_.deserialize(config);
35 eckit::LocalConfiguration yconf;
36 yconf.set(
"name", classname());
37 if (options_.chlist.value() != boost::none) {
38 yconf.set(
"channels", options_.chlist.value().get());
40 yconf.set(
"options", config);
44 const Variable &xvar = options_.xvar.value();
45 ASSERT(xvar.size() == 1 ||
46 xvar.size() == yvar.size());
50 const std::vector<float> &x0 = options_.x0.value();
51 const std::vector<float> &x1 = options_.x1.value();
52 const std::vector<float> &err0 = options_.err0.value();
53 const std::vector<float> &err1 = options_.err1.value();
56 ASSERT(yvar.size() == x0.size());
57 ASSERT(yvar.size() == x1.size());
58 ASSERT(yvar.size() == err0.size());
59 ASSERT(yvar.size() == err1.size());
60 for (
size_t i = 0; i < yvar.size(); ++i) {
61 ASSERT(x1[i] >= x0[i]);
62 ASSERT(err0[i] > 0.0);
63 ASSERT(err1[i] > 0.0);
65 if (options_.x2.value() != boost::none && options_.err2.value() != boost::none) {
66 const std::vector<float> &x2 = options_.x2.value().get();
67 const std::vector<float> &err2 = options_.err2.value().get();
68 ASSERT(x2.size() == yvar.size());
69 ASSERT(err2.size() == yvar.size());
70 for (
size_t i = 0; i < yvar.size(); ++i) {
71 ASSERT(x2[i] >= x1[i]);
72 ASSERT(err2[i] > 0.0);
79 ObsErrorModelRamp::~ObsErrorModelRamp() {}
83 void ObsErrorModelRamp::compute(
const ObsFilterData & in,
88 const std::vector<float> &x0 = options_.x0.value();
89 const std::vector<float> &x1 = options_.x1.value();
90 const std::vector<float> &err0 = options_.err0.value();
91 const std::vector<float> &err1 = options_.err1.value();
94 ASSERT(out.nvars() == x0.size());
97 const Variable &xvar = options_.xvar.value();
102 if (options_.save) xvals.save(
"ObsFunction");
107 std::vector<float> x2;
108 std::vector<float> err2;
109 bool cal_err2_x2 =
false;
111 if (options_.x2.value() != boost::none && options_.err2.value() != boost::none) {
112 x2 = options_.x2.value().get();
113 err2 = options_.x2.value().get();
117 for (
size_t jvar = 0; jvar < out.nvars(); ++jvar) {
118 size_t ivar = std::min(jvar, xvar.size() - 1);
121 if (x1[jvar] > x0[jvar]) {
122 slope = (err1[jvar] - err0[jvar]) / (x1[jvar] - x0[jvar]);
127 if (x2[jvar] > x1[jvar]) {
128 slope2 = (err2[jvar] - err1[jvar]) / (x2[jvar] - x1[jvar]);
135 for (
size_t iloc = 0; iloc < in.nlocs(); ++iloc) {
137 if (xvals[ivar][iloc] !=
missing) {
138 if (xvals[ivar][iloc] <= x0[jvar]) {
139 out[jvar][iloc] = err0[jvar];
140 }
else if (xvals[ivar][iloc] < x1[jvar] && slope !=
missing) {
141 out[jvar][iloc] = err0[jvar] + slope * (xvals[ivar][iloc] - x0[jvar]);
142 }
else if (cal_err2_x2) {
143 if (xvals[ivar][iloc] < x2[jvar] && slope2 !=
missing) {
144 out[jvar][iloc] = err1[jvar] + slope2 * (xvals[ivar][iloc] - x1[jvar]);
146 out[jvar][iloc] = err2[jvar];
149 out[jvar][iloc] = err1[jvar];
158 const ufo::Variables & ObsErrorModelRamp::requiredVariables()
const {
static ObsFunctionMaker< ObsErrorModelRamp > makerRamp_("ObsErrorModelRamp")