UFO
TropopauseEstimate.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 <ctime>
13 #include <iomanip>
14 #include <sstream>
15 
16 #include "eckit/exception/Exceptions.h"
17 
18 #include "oops/util/DateTime.h"
19 #include "oops/util/missingValues.h"
20 
21 #include "ufo/filters/Variable.h"
22 
23 namespace ufo {
24 
26 
27 // -----------------------------------------------------------------------------
28 
29 TropopauseEstimate::TropopauseEstimate(const eckit::LocalConfiguration & conf)
30  : invars_() {
31  oops::Log::debug() << "TropopauseEstimate: config = " << conf << std::endl;
32  // Initialize options
33  options_.deserialize(conf);
34 
35  // We must know the datetime of each observation
36  invars_ += Variable("datetime@MetaData");
37  // We must know the latitude of each observation
38  invars_ += Variable("latitude@MetaData");
39 
40  if (options_.convert_p2z.value())
41  oops::Log::debug() << " TropopauseEstimate: will convert pres to height" << std::endl;
42 }
43 
44 // -----------------------------------------------------------------------------
45 
46 TropopauseEstimate::~TropopauseEstimate() {}
47 
48 // -----------------------------------------------------------------------------
49 
50 void TropopauseEstimate::compute(const ObsFilterData & in,
51  ioda::ObsDataVector<float> & out) const {
52  const size_t nlocs = in.nlocs();
53  const float missing = util::missingValue(missing);
54 
55  // Ensure that only one output variable is expected.
56  ASSERT(out.nvars() == 1);
57 
58  // Retrieve the options of tropo_equator, tropo_pole, convert_p2z.
59  const float tropo_equator = options_.tropo_equator.value();
60  const float tropo_pole = options_.tropo_pole.value();
61  bool convert_p2z = options_.convert_p2z.value();
62 
63  // Retrieve the datetime and latitude.
64  std::vector<float> latitude;
65  in.get(Variable("latitude@MetaData"), latitude);
66  std::vector<util::DateTime> datetimes;
67  in.get(Variable("datetime@MetaData"), datetimes);
68 
69  // If datetimes is empty, then we should just exit because there is nothing we can do otherwise.
70  if (datetimes.empty()) {
71  return;
72  }
73 
74  int year, month, day, hour, minute, second, day_peak;
75  float slope, tropo_start, season_factor;
76  std::vector<float> answer(nlocs);
77 
78  // Taking a small short-cut. Rather than loop through all datetimes, we
79  // get only the first one to compute the day of the year.
80  datetimes[0].toYYYYMMDDhhmmss(year, month, day, hour, minute, second);
81  const util::DateTime firstDayOfYear(year, 1, 1, 0, 0, 0);
82  const int day_of_year = (datetimes[0] - firstDayOfYear).toSeconds() / (24*3600);
83 
84  // Iterate over the observation points.
85  for (size_t jj = 0; jj < nlocs; ++jj) {
86  if (latitude[jj] > 0.0) {
87  day_peak = 203;
88  } else {
89  day_peak = 21;
90  }
91  slope = std::max(0.0, (std::abs(latitude[jj])-15.0)/(90.0-15.0));
92  tropo_start = (tropo_pole-tropo_equator)*slope + tropo_equator;
93  season_factor = std::cos((day_of_year - day_peak)*0.5f*0.0174533f);
94  answer[jj] = tropo_start + season_factor*5000.0;
95 
96  // If needed, convert pressure to height.
97  if (convert_p2z) answer[jj] = 44307.692*(1.0 - pow(answer[jj]/101325.0f, 0.19f));
98 
99  out[0][jj] = answer[jj];
100  }
101 
102  // TODO(gthompsn): Need to add units or other attributes in the future.
103  // varname = "TropopausePressure"; units = "Pa"; or height and meters.
104  if (options_.save) {
105  out.save("DerivedValue");
106  }
107 }
108 
109 // -----------------------------------------------------------------------------
110 
111 const ufo::Variables & TropopauseEstimate::requiredVariables() const {
112  return invars_;
113 }
114 
115 // -----------------------------------------------------------------------------
116 
117 } // 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< TropopauseEstimate > makerObsFuncTropopauseEstimate_("TropopauseEstimate")
util::Duration abs(const util::Duration &duration)