UFO
SatWindsSPDBCheck.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 <vector>
13 
14 #include "ioda/ObsDataVector.h"
15 #include "oops/util/missingValues.h"
16 #include "ufo/filters/Variable.h"
17 
18 namespace ufo {
19 
21 
22 // -----------------------------------------------------------------------------
23 
24 SatWindsSPDBCheck::SatWindsSPDBCheck(const eckit::LocalConfiguration & conf)
25  : invars_() {
26  oops::Log::debug() << "SatWindsSPDBCheck: config = " << conf << std::endl;
27  // Initialize options
28  options_.deserialize(conf);
29 
30  // Initialize error_min, and max from options. Make sure they are sane.
31  const float error_min = options_.error_min.value();
32  const float error_max = options_.error_max.value();
33  ASSERT(error_min < error_max);
34 
35  // We need to retrieve the observed wind components.
36  invars_ += Variable("eastward_wind@ObsValue");
37  invars_ += Variable("northward_wind@ObsValue");
38 
39  // Typical use would be HofX group, but during testing, we include option for GsiHofX
40  std::string test_hofx = options_.test_hofx.value();
41  invars_ += Variable("eastward_wind@" + test_hofx);
42  invars_ += Variable("northward_wind@" + test_hofx);
43 
44  // The starting (un-inflated) value of obserror. If running in sequence of filters,
45  // then it is probably found in ObsErrorData, otherwise, it is probably ObsError.
46  const std::string errgrp = options_.original_obserr.value();
47  invars_ += Variable("eastward_wind@"+errgrp);
48 
49  // TODO(gthompsn): Need to include a check that whatever HofX/obserr group name used exists.
50 }
51 
52 // -----------------------------------------------------------------------------
53 
54 SatWindsSPDBCheck::~SatWindsSPDBCheck() {}
55 
56 // -----------------------------------------------------------------------------
57 
58 void SatWindsSPDBCheck::compute(const ObsFilterData & in,
59  ioda::ObsDataVector<float> & out) const {
60  const size_t nlocs = in.nlocs();
61  const float missing = util::missingValue(missing);
62  float spdb = 0.0f;
63  float residual = 0.0f;
64  float obserr = 1.0f;
65 
66  // Ensure that only one output variable is expected.
67  ASSERT(out.nvars() == 1);
68 
69  // Get min, max, gross error values
70  const float error_min = options_.error_min.value();
71  const float error_max = options_.error_max.value();
72 
73  // Retrieve SatWinds observations of wind components
74  std::vector<float> u, v;
75  in.get(Variable("eastward_wind@ObsValue"), u);
76  in.get(Variable("northward_wind@ObsValue"), v);
77  // Retrieve Model HofX wind components
78  std::string test_hofx = options_.test_hofx.value();
79  std::vector<float> um, vm;
80  in.get(Variable("eastward_wind@" + test_hofx), um);
81  in.get(Variable("northward_wind@" + test_hofx), vm);
82 
83  // Get original ObsError of eastward_wind (would make little sense if diff from northward)
84  std::vector<float> currentObserr(nlocs);
85  const std::string errgrp = options_.original_obserr.value();
86  in.get(Variable("eastward_wind@"+errgrp), currentObserr);
87 
88  for (size_t jj = 0; jj < nlocs; ++jj) {
89  out[0][jj] = 0.0f;
90  if (u[jj] != missing && v[jj] != missing) {
91  spdb = sqrt(u[jj]*u[jj]+v[jj]*v[jj]) - sqrt(um[jj]*um[jj]+vm[jj]*vm[jj]);
92  if (spdb < 0.0f) {
93  obserr = currentObserr[jj];
94  obserr = std::max(error_min, std::min(obserr, error_max));
95  residual = sqrt((u[jj]-um[jj])*(u[jj]-um[jj]) + (v[jj]-vm[jj])*(v[jj]-vm[jj]));
96  out[0][jj] = residual/obserr;
97  }
98  }
99  }
100 }
101 
102 // -----------------------------------------------------------------------------
103 
104 const ufo::Variables & SatWindsSPDBCheck::requiredVariables() const {
105  return invars_;
106 }
107 
108 // -----------------------------------------------------------------------------
109 
110 } // namespace ufo
constexpr int missing
Definition: QCflags.h:20
integer function nlocs(this)
Return the number of observational locations in this Locations object.
Definition: RunCRTM.h:27
static ObsFunctionMaker< SatWindsSPDBCheck > makerObsFuncSatWindsSPDBCheck_("SatWindsSPDBCheck")