15 #include "ioda/ObsDataVector.h"
16 #include "oops/util/missingValues.h"
26 WindDirAngleDiff::WindDirAngleDiff(
const eckit::LocalConfiguration & conf)
30 options_.deserialize(conf);
33 invars_ +=
Variable(
"eastward_wind@ObsValue");
34 invars_ +=
Variable(
"northward_wind@ObsValue");
37 std::string test_hofx = options_.test_hofx.value();
38 invars_ +=
Variable(
"eastward_wind@" + test_hofx);
39 invars_ +=
Variable(
"northward_wind@" + test_hofx);
46 WindDirAngleDiff::~WindDirAngleDiff() {}
50 void WindDirAngleDiff::compute(
const ObsFilterData & in,
52 const size_t nlocs = in.nlocs();
57 ASSERT(out.nvars() == 1);
60 const float min_uv = std::max(0.0001f, options_.minimum_uv.value());
63 std::vector<float> u, v;
64 in.get(Variable(
"eastward_wind@ObsValue"), u);
65 in.get(Variable(
"northward_wind@ObsValue"), v);
67 std::string test_hofx = options_.test_hofx.value();
68 std::vector<float> um, vm;
69 in.get(Variable(
"eastward_wind@" + test_hofx), um);
70 in.get(Variable(
"northward_wind@" + test_hofx), vm);
72 double wdir_obs, wdir_model;
74 for (
size_t jj = 0; jj <
nlocs; ++jj) {
79 wdir_obs = std::atan2(-u[jj], -v[jj])*deg;
80 wdir_model = std::atan2(-um[jj], -vm[jj])*deg;
81 out[0][jj] = std::min({
std::abs(wdir_obs-wdir_model),
83 std::abs(wdir_obs-wdir_model-360.0)});
93 const ufo::Variables & WindDirAngleDiff::requiredVariables()
const {
real(kind_real), parameter, public rad2deg
integer function nlocs(this)
Return the number of observational locations in this Locations object.
util::Duration abs(const util::Duration &duration)
static ObsFunctionMaker< WindDirAngleDiff > makerObsFuncWindDirAngleDiff_("WindDirAngleDiff")