UFO
Cal_Wind.cc
Go to the documentation of this file.
1 /*
2  * (C) Crown copyright 2020, Met Office
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 #include "ufo/utils/Constants.h"
10 
12 
13 
14 namespace ufo {
15 
16 /************************************************************************************/
17 // Cal_WindSpeedAndDirection
18 /************************************************************************************/
19 
20 static TransformMaker<Cal_WindSpeedAndDirection>
21  makerCal_WindSpeedAndDirection_("WindSpeedAndDirection");
22 
24  const VariableTransformsParameters &options, const ObsFilterData &data,
25  const std::shared_ptr<ioda::ObsDataVector<int>> &flags)
26  : TransformBase(options, data, flags) {
27 }
28 
29 /************************************************************************************/
30 
31 void Cal_WindSpeedAndDirection::runTransform(const std::vector<bool> &apply) {
32  oops::Log::trace() << " --> Retrieve wind speed and direction"
33  << std::endl;
34  oops::Log::trace() << " --> method: " << method() << std::endl;
35  oops::Log::trace() << " --> obsName: " << obsName() << std::endl;
36 
37  const size_t nlocs = obsdb_.nlocs();
38 
39  std::vector<float> u, v;
40  getObservation("ObsValue", "eastward_wind",
41  u, true);
42  getObservation("ObsValue", "northward_wind",
43  v, true);
44 
45  if (!oops::allVectorsSameNonZeroSize(u, v)) {
46  oops::Log::warning() << "Vector sizes: "
47  << oops::listOfVectorSizes(u, v)
48  << std::endl;
49  throw eckit::BadValue("At least one vector is the wrong size or empty out of "
50  "U, and V", Here());
51  }
52 
53  std::vector<float> windSpeed(nlocs), windFromDirection(nlocs);
54  windSpeed.assign(nlocs, missingValueFloat);
55  windFromDirection.assign(nlocs, missingValueFloat);
56 
57  // Loop over all obs
58  for (size_t jobs = 0; jobs < nlocs; ++jobs) {
59  // if the data have been excluded by the where statement
60  if (!apply[jobs]) continue;
61 
62  // Calculate wind vector
63  if (u[jobs] != missingValueFloat && v[jobs] != missingValueFloat) {
64  windFromDirection[jobs] = formulas::GetWindDirection(u[jobs], v[jobs]);
65  windSpeed[jobs] = formulas::GetWindSpeed(u[jobs], v[jobs]);
66  }
67  }
68  // put new variable at existing locations
69  putObservation("wind_speed", windSpeed);
70  putObservation("wind_from_direction", windFromDirection);
71 }
72 
73 /************************************************************************************/
74 // Cal_WindComponents
75 /************************************************************************************/
77  makerCal_WindComponents_("WindComponents");
78 
80  const VariableTransformsParameters &options,
81  const ObsFilterData &data,
82  const std::shared_ptr<ioda::ObsDataVector<int>> &flags)
83  : TransformBase(options, data, flags) {}
84 
85 /************************************************************************************/
86 
87 void Cal_WindComponents::runTransform(const std::vector<bool> &apply) {
88  oops::Log::trace() << " --> Retrieve wind component"
89  << std::endl;
90  oops::Log::trace() << " --> method: " << method() << std::endl;
91  oops::Log::trace() << " --> obsName: " << obsName() << std::endl;
92 
93  const size_t nlocs = obsdb_.nlocs();
94 
95  std::vector<float> windSpeed, windFromDirection;
96  getObservation("ObsValue", "wind_speed",
97  windSpeed, true);
98  getObservation("ObsValue", "wind_from_direction",
99  windFromDirection, true);
100 
101  if (!oops::allVectorsSameNonZeroSize(windSpeed, windFromDirection)) {
102  oops::Log::warning() << "Vector sizes: "
103  << oops::listOfVectorSizes(windSpeed, windFromDirection)
104  << std::endl;
105  throw eckit::BadValue("At least one vector is the wrong size or empty out of "
106  "wind speed, and direction", Here());
107  }
108 
109  std::vector<float> u(nlocs), v(nlocs);
110  u.assign(nlocs, missingValueFloat);
111  v.assign(nlocs, missingValueFloat);
112 
113  // Loop over all obs
114  for (size_t jobs = 0; jobs < nlocs; ++jobs) {
115  // if the data have been excluded by the where statement
116  if (!apply[jobs]) continue;
117 
118  // Calculate wind vector
119  if (windFromDirection[jobs] != missingValueFloat &&
120  windSpeed[jobs] != missingValueFloat && windSpeed[jobs] >= 0) {
121  u[jobs] = formulas::GetWind_U(windSpeed[jobs], windFromDirection[jobs]);
122  v[jobs] = formulas::GetWind_V(windSpeed[jobs], windFromDirection[jobs]);
123  }
124  }
125 
126  // put new variable at existing locations
127  putObservation("eastward_wind", u);
128  putObservation("northward_wind", v);
129 }
130 } // namespace ufo
131 
void runTransform(const std::vector< bool > &apply) override
Run variable conversion.
Definition: Cal_Wind.cc:87
Cal_WindComponents(const VariableTransformsParameters &options, const ObsFilterData &data, const std::shared_ptr< ioda::ObsDataVector< int >> &flags)
Definition: Cal_Wind.cc:79
Cal_WindSpeedAndDirection(const VariableTransformsParameters &options, const ObsFilterData &data, const std::shared_ptr< ioda::ObsDataVector< int >> &flags)
Definition: Cal_Wind.cc:23
void runTransform(const std::vector< bool > &apply) override
Run variable conversion.
Definition: Cal_Wind.cc:31
ObsFilterData provides access to all data related to an ObsFilter.
Base class for variable conversion.
Definition: TransformBase.h:53
std::string obsName() const
subclasses to access the observation name
formulas::MethodFormulation method() const
subclasses to access Method and formualtion used for the calculation
void putObservation(const std::string &varName, const std::vector< T > &obsVector)
Save a transformed variable to the DerivedObsValue group of the obs space.
const float missingValueFloat
Missing value (float)
ioda::ObsSpace & obsdb_
Observation space.
void getObservation(const std::string &originalTag, const std::string &varName, std::vector< T > &obsVector, bool require=false) const
templated function for float, int data types
Definition: TransformBase.h:94
Transform maker.
Options controlling the operation of the variablestansform filter.
float GetWind_U(float windSpeed, float windFromDirection)
Get eastward (u) wind component from wind speed and direction.
Definition: Formulas.cc:347
float GetWindDirection(float u, float v)
Converts u and v wind component into wind direction.
Definition: Formulas.cc:323
float GetWind_V(float windSpeed, float windFromDirection)
Get northward (v) wind component from wind speed and direction.
Definition: Formulas.cc:359
float GetWindSpeed(float u, float v)
Converts u and v wind component into wind speed.
Definition: Formulas.cc:337
integer function nlocs(this)
Return the number of observational locations in this Locations object.
Definition: RunCRTM.h:27
static TransformMaker< Cal_WindSpeedAndDirection > makerCal_WindSpeedAndDirection_("WindSpeedAndDirection")
static TransformMaker< Cal_WindComponents > makerCal_WindComponents_("WindComponents")