UFO
LapseRate.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 #include <fstream>
8 #include <iterator>
9 #include <string>
10 
12 
13 #include "ioda/ObsSpace.h"
14 
15 #include "oops/base/Variables.h"
16 #include "oops/util/abor1_cpp.h"
17 #include "oops/util/Logger.h"
18 
19 #include "ufo/GeoVaLs.h"
20 #include "ufo/ObsDiagnostics.h"
21 
22 namespace ufo {
23 
25 
26 // -----------------------------------------------------------------------------
27 
28 LapseRate::LapseRate(const eckit::Configuration & conf, const std::vector<int> & jobs)
29  : PredictorBase(conf, jobs), order_(1)
30 {
31  // get the order if it is provided in options
32  if (conf.has("predictor.options.order")) {
33  conf.get("predictor.options.order", order_);
34 
35  // override the predictor name for differentiable
36  name() = name() + "_order_" + std::to_string(order_);
37  }
38 
39  // required variables
40  geovars_ += oops::Variables({"air_temperature",
41  "air_pressure",
42  "average_surface_temperature_within_field_of_view"});
43  if (jobs.size() > 0) {
44  hdiags_ += oops::Variables({"transmittances_of_atmosphere_layer"}, jobs);
45  } else {
46  oops::Log::error() << "Channels size is ZERO !" << std::endl;
47  ABORT("Channels size is ZERO !");
48  }
49 
50  // This is a very preliminary method, please revisit
51  // more flexibilites are needed
52  if (conf.has("predictor.options.tlapse")) {
53  const std::string tlapse_file = conf.getString("predictor.options.tlapse");
54  std::ifstream infile(tlapse_file);
55  std::string nusis; // sensor/instrument/satellite
56  int nuchan; // channel number
57  float tlapse;
58 
59  if (infile.is_open()) {
60  while (!infile.eof()) {
61  infile >> nusis;
62  infile >> nuchan;
63  infile >> tlapse;
64  tlapmean_[nuchan] = tlapse;
65  }
66  infile.close();
67  } else {
68  oops::Log::error() << "Unable to open file : "
69  << tlapse_file << std::endl;
70  ABORT("Unable to open tlap file ");
71  }
72  } else {
73  oops::Log::error() << "tlapse file is not provided !" << std::endl;
74  ABORT("tlapse file is not provided !");
75  }
76 }
77 
78 // -----------------------------------------------------------------------------
79 
80 void LapseRate::compute(const ioda::ObsSpace & odb,
81  const GeoVaLs & geovals,
82  const ObsDiagnostics & ydiags,
83  ioda::ObsVector & out) const {
84  const std::size_t njobs = jobs_.size();
85  const std::size_t nlocs = odb.nlocs();
86 
87  // assure shape of out
88  ASSERT(out.nlocs() == nlocs);
89 
90  // common vectors storage
91  std::vector <float> pred(nlocs, 0.0);
92 
93  // retrieve the average surface temperature
94  std::vector<float> tsavg5(nlocs, 0.0);
95  geovals.get(tsavg5, "average_surface_temperature_within_field_of_view");
96 
97  // Retrieve the transmittances_of_atmosphere_layer from Hdiag
98  std::vector<std::vector<std::vector<float>>> ptau5;
99  std::vector<std::vector<float>> tmpvar;
100 
101  std::string hdiags;
102  for (std::size_t jb = 0; jb < njobs; ++jb) {
103  hdiags = "transmittances_of_atmosphere_layer_" + std::to_string(jobs_[jb]);
104  tmpvar.clear();
105  for (std::size_t js = 0; js < ydiags.nlevs(hdiags); ++js) {
106  ydiags.get(pred, hdiags, js+1);
107  tmpvar.push_back(pred);
108  }
109  ptau5.push_back(tmpvar);
110  }
111 
112  // Retrieve the temperature
113  std::vector<std::vector<float>> tvp;
114  std::size_t nlevs = geovals.nlevs("air_temperature");
115  for (std::size_t js = 0; js < nlevs; ++js) {
116  geovals.get(pred, "air_temperature", js+1);
117  tvp.push_back(pred);
118  }
119  nlevs = geovals.nlevs("air_pressure");
120  float tlapchn;
121 
122  // sort out the tlapmean based on jobs
123  std::vector<float> tlap;
124  for (std::size_t jb = 0; jb < njobs; ++jb) {
125  auto it = tlapmean_.find(jobs_[jb]);
126  if (it != tlapmean_.end()) {
127  tlap.push_back(it->second);
128  } else {
129  oops::Log::error() << "Could not locate tlapemean for channel: " << jobs_[jb] << std::endl;
130  ABORT("Could not locate tlapemean value");
131  }
132  }
133 
134  for (std::size_t jl = 0; jl < nlocs; ++jl) {
135  for (std::size_t jb = 0; jb < njobs; ++jb) {
136  tlapchn = (ptau5[jb][nlevs-2][jl]-ptau5[jb][nlevs-1][jl])*(tsavg5[jl]-tvp[nlevs-2][jl]);
137  for (std::size_t k = 1; k < nlevs-1; ++k) {
138  tlapchn = tlapchn+(ptau5[jb][nlevs-k-2][jl]-ptau5[jb][nlevs-k-1][jl])*
139  (tvp[nlevs-k][jl]-tvp[nlevs-k-2][jl]);
140  }
141  out[jl*njobs+jb] = pow((tlapchn - tlap[jb]), order_);
142  }
143  }
144 }
145 
146 // -----------------------------------------------------------------------------
147 
148 } // namespace ufo
ufo::ObsDiagnostics::nlevs
size_t nlevs(const std::string &) const
Definition: ObsDiagnostics.cc:45
ufo::PredictorBase::hdiags_
oops::Variables hdiags_
required ObsDiagnostics
Definition: PredictorBase.h:62
ufo::LapseRate::tlapmean_
std::map< int, float > tlapmean_
Definition: LapseRate.h:41
ufo
Definition: RunCRTM.h:27
ufo::PredictorBase::name
std::string & name()
predictor name
Definition: PredictorBase.h:56
ufo::GeoVaLs::get
void get(std::vector< float > &, const std::string &) const
Return all values for a specific 2D variable.
Definition: GeoVaLs.cc:268
ufo::PredictorMaker
Definition: PredictorBase.h:89
ufo::makerFuncLapseRate_
static PredictorMaker< LapseRate > makerFuncLapseRate_("lapse_rate")
ufo::PredictorBase::geovars_
oops::Variables geovars_
required GeoVaLs
Definition: PredictorBase.h:61
ufo::ObsDiagnostics
Definition: src/ufo/ObsDiagnostics.h:35
ufo::LapseRate::compute
void compute(const ioda::ObsSpace &, const GeoVaLs &, const ObsDiagnostics &, ioda::ObsVector &) const override
compute the predictor
Definition: LapseRate.cc:80
ufo::PredictorBase
Base class for computing predictors.
Definition: PredictorBase.h:38
ufo::GeoVaLs
GeoVaLs: geophysical values at locations.
Definition: src/ufo/GeoVaLs.h:39
ufo::LapseRate::LapseRate
LapseRate(const eckit::Configuration &, const std::vector< int > &)
Definition: LapseRate.cc:28
ufo::ObsDiagnostics::get
void get(std::vector< float > &, const std::string &) const
Definition: ObsDiagnostics.cc:51
ufo::PredictorBase::jobs_
const std::vector< int > jobs_
jobs(channels)
Definition: PredictorBase.h:60
LapseRate.h
ufo::GeoVaLs::nlevs
size_t nlevs(const std::string &var) const
Return number of levels for a specified variable.
Definition: GeoVaLs.cc:259
ufo::LapseRate::order_
int order_
Definition: LapseRate.h:42
conf
Definition: conf.py:1