UFO
GeoVaLs.cc
Go to the documentation of this file.
1 /*
2  * (C) Copyright 2017-2019 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 
8 #include "ufo/GeoVaLs.h"
9 
10 #include <iomanip>
11 #include <vector>
12 
13 #include "eckit/config/Configuration.h"
14 #include "eckit/exception/Exceptions.h"
15 
16 #include "oops/base/Variables.h"
17 #include "oops/util/Logger.h"
18 
19 #include "ufo/Fortran.h"
20 #include "ufo/Locations.h"
21 
22 namespace ufo {
23 
24 // -----------------------------------------------------------------------------
25 /*! \brief Default constructor - does not allocate fields
26 */
27 GeoVaLs::GeoVaLs(const eckit::mpi::Comm & comm)
28  : keyGVL_(-1), comm_(comm)
29 {
30  oops::Log::trace() << "GeoVaLs default constructor starting" << std::endl;
32  oops::Log::trace() << "GeoVaLs default constructor end" << std::endl;
33 }
34 
35 // -----------------------------------------------------------------------------
36 /*! \brief Constructor given Locations and Variables
37  *
38  * \details This ufo::GeoVaLs constructor is typically used to initialize
39  * GeoVaLs for the full time window (ufo::Locations hold all locations within
40  * data assimilation window) and all variables (oops::Variables hold all
41  * variables specified by the ObsOperator as input varialbes. Note that
42  * nothing is allocated in the constructor currently, and getValues is
43  * responsible for allocation
44  *
45  */
46 GeoVaLs::GeoVaLs(const Locations & locs, const oops::Variables & vars)
47  : keyGVL_(-1), vars_(vars), comm_(locs.getComm())
48 {
49  oops::Log::trace() << "GeoVaLs contructor starting" << std::endl;
51  oops::Log::trace() << "GeoVaLs contructor key = " << keyGVL_ << std::endl;
52 }
53 
54 // -----------------------------------------------------------------------------
55 /*! \brief Constructor for tests
56  *
57  * \details This ufo::GeoVaLs constructor is typically used in tests, GeoVaLs
58  * are read from the file.
59  */
60 GeoVaLs::GeoVaLs(const eckit::Configuration & config,
61  const ioda::ObsSpace & obspace,
62  const oops::Variables & vars)
63  : keyGVL_(-1), vars_(vars), comm_(obspace.comm())
64 {
65  oops::Log::trace() << "GeoVaLs constructor config starting" << std::endl;
67  // only read if there are variables specified
68  if (vars_.size() > 0) ufo_geovals_read_file_f90(keyGVL_, config, obspace, vars_);
69  oops::Log::trace() << "GeoVaLs contructor config key = " << keyGVL_ << std::endl;
70 }
71 // -----------------------------------------------------------------------------
72 /*! \brief Construct a new GeoVaLs with just one location
73 *
74 * \details This ufo::GeoVaLs constructor takes a GeoVaLs object and an index to
75 * create a new GeoVaLs with just one location
76 */
77 GeoVaLs::GeoVaLs(const GeoVaLs & other, const int & index)
78  : keyGVL_(-1), vars_(other.vars_), comm_(other.comm_)
79 {
80  oops::Log::trace() << "GeoVaLs copy one GeoVaLs constructor starting" << std::endl;
82  int fort_index = index + 1; // Fortran numbers from 1
83  ufo_geovals_copy_one_f90(keyGVL_, other.keyGVL_, fort_index);
84  oops::Log::trace() << "GeoVaLs copy one GeoVaLs constructor key = " << keyGVL_ << std::endl;
85 }
86 // -----------------------------------------------------------------------------
87 /*! \brief Copy constructor */
88 
89 GeoVaLs::GeoVaLs(const GeoVaLs & other)
90  : keyGVL_(-1), vars_(other.vars_), comm_(other.comm_)
91 {
92  oops::Log::trace() << "GeoVaLs copy constructor starting" << std::endl;
95  oops::Log::trace() << "GeoVaLs copy constructor key = " << keyGVL_ << std::endl;
96 }
97 // -----------------------------------------------------------------------------
98 /*? \brief Destructor */
100  oops::Log::trace() << "GeoVaLs destructor starting" << std::endl;
102  oops::Log::trace() << "GeoVaLs destructor done" << std::endl;
103 }
104 // -----------------------------------------------------------------------------
105 /*! \brief Zero out the GeoVaLs */
107  oops::Log::trace() << "GeoVaLs::zero starting" << std::endl;
109  oops::Log::trace() << "GeoVaLs::zero done" << std::endl;
110 }
111 // -----------------------------------------------------------------------------
112 /*! \brief Reorder GeoVaLs in vertical dimension based on vertical coordinate variable */
113 void GeoVaLs::reorderzdir(const std::string & varname, const std::string & vardir) {
114  oops::Log::trace() << "GeoVaLs::reorderzdir starting" << std::endl;
115  ufo_geovals_reorderzdir_f90(keyGVL_, varname.size(), varname.c_str(),
116  vardir.size(), vardir.c_str());
117  oops::Log::trace() << "GeoVaLs::reorderzdir done" << std::endl;
118 }
119 // -----------------------------------------------------------------------------
120 /*! \brief Calculate rms */
121 double GeoVaLs::rms() const {
122  oops::Log::trace() << "GeoVaLs::rms starting" << std::endl;
123  double zz;
125  oops::Log::trace() << "GeoVaLs::rms done" << std::endl;
126  return zz;
127 }
128 // -----------------------------------------------------------------------------
129 /*! \brief Calculate normalized rms */
130 double GeoVaLs::normalizedrms(const GeoVaLs & other) const {
131  oops::Log::trace() << "GeoVaLs::normalizerms starting" << std::endl;
132  GeoVaLs temp_gval(*this);
133  ufo_geovals_normalize_f90(temp_gval.keyGVL_, other.keyGVL_);
134  double zz = temp_gval.rms();
135  oops::Log::trace() << "GeoVaLs::normalizerms done" << std::endl;
136  return zz;
137 }
138 // -----------------------------------------------------------------------------
139 /*! \brief Randomize GeoVaLs */
141  oops::Log::trace() << "GeoVaLs::random starting" << std::endl;
143  oops::Log::trace() << "GeoVaLs::random done" << std::endl;
144 }
145 // -----------------------------------------------------------------------------
146 /*! \brief Multiply by a constant scalar */
147 GeoVaLs & GeoVaLs::operator*=(const double zz) {
148  oops::Log::trace() << "GeoVaLs::operator*= starting" << std::endl;
150  oops::Log::trace() << "GeoVaLs::operator*= done" << std::endl;
151  return *this;
152 }
153 // -----------------------------------------------------------------------------
154 /*! \brief Multiply by a constant scalar for each profile */
155 GeoVaLs & GeoVaLs::operator*=(const std::vector<float> & vals) {
156  oops::Log::trace() << "GeoVaLs::operator*= starting" << std::endl;
157  size_t nlocs;
159  oops::Log::trace() << "vals, nlocs = " << vals.size() << " " << nlocs << std::endl;
160  ASSERT(vals.size() == nlocs);
161  ufo_geovals_profmult_f90(keyGVL_, nlocs, vals[0]);
162  oops::Log::trace() << "GeoVaLs::operator*= done" << std::endl;
163  return *this;
164 }
165 // -----------------------------------------------------------------------------
166 /*! \brief Copy operator */
168  oops::Log::trace() << "GeoVaLs::operator= starting" << std::endl;
170  oops::Log::trace() << "GeoVaLs::operator= done" << std::endl;
171  return *this;
172 }
173 // -----------------------------------------------------------------------------
174 /*! \brief Add another GeoVaLs */
176  oops::Log::trace() << "GeoVaLs::operator+= starting" << std::endl;
178  oops::Log::trace() << "GeoVaLs::operator+= done" << std::endl;
179  return *this;
180 }
181 // -----------------------------------------------------------------------------
182 /*! \brief Subtract another GeoVaLs */
184  oops::Log::trace() << "GeoVaLs::operator-= starting" << std::endl;
186  oops::Log::trace() << "GeoVaLs::operator-= done" << std::endl;
187  return *this;
188 }
189 // -----------------------------------------------------------------------------
190 /*! \brief Multiply another GeoVaLs */
192  oops::Log::trace() << "GeoVaLs::operator*= starting" << std::endl;
194  oops::Log::trace() << "GeoVaLs::operator*= done" << std::endl;
195  return *this;
196 }
197 // -----------------------------------------------------------------------------
198 /*! \brief Scalar product of two GeoVaLs */
199 double GeoVaLs::dot_product_with(const GeoVaLs & other) const {
200  oops::Log::trace() << "GeoVaLs::dot_product_with starting" << std::endl;
201  double zz;
203  oops::Log::trace() << "GeoVaLs::dot_product_with done" << std::endl;
204  return zz;
205 }
206 // -----------------------------------------------------------------------------
207 /*! \brief Split two GeoVaLs */
208 void GeoVaLs::split(GeoVaLs & other1, GeoVaLs & other2) const {
209  oops::Log::trace() << "GeoVaLs::split GeoVaLs into 2" << std::endl;
210  ufo_geovals_split_f90(keyGVL_, other1.keyGVL_, other2.keyGVL_);
211  oops::Log::trace() << "GeoVaLs::split GeoVaLs into 2" << std::endl;
212  return;
213 }
214 // -----------------------------------------------------------------------------
215 /*! \brief Merge two GeoVaLs */
216 void GeoVaLs::merge(const GeoVaLs & other1, const GeoVaLs & other2) {
217  oops::Log::trace() << "GeoVaLs::merge 2 GeoVaLs" << std::endl;
218  ufo_geovals_merge_f90(keyGVL_, other1.keyGVL_, other2.keyGVL_);
219  oops::Log::trace() << "GeoVaLs::merge 2 GeoVaLs" << std::endl;
220  return;
221 }
222 // -----------------------------------------------------------------------------
223 /*! \brief Output GeoVaLs to a stream */
224 void GeoVaLs::print(std::ostream & os) const {
225  int nn;
226  double zmin, zmax, zrms;
227 
228  os << "GeoVaLs: variables = " << vars_ << std::endl;
229  for (size_t jv = 0; jv < vars_.size(); ++jv) {
230  int nv = jv;
231  ufo_geovals_minmaxavg_f90(keyGVL_, nn, nv, zmin, zmax, zrms);
232  os << "GeoVaLs: nobs= " << nn << " " << vars_[jv] << " Min=" << zmin << ", Max=" << zmax
233  << ", RMS=" << zrms << std::endl;
234  }
235 
236  /*! Verbose print statement (debug mode)
237  *
238  * \detail If the min value across all variables is positive, then this may be
239  * an error measurement. If so, compute the rms over the vertical profile and
240  * tell the user where the maximum rms value occurs, in terms of the
241  * observation number and the variable number. This is intended to help
242  * with debugging.
243  */
244 
245  if (zmin >= 0.0) {
246  double mxval;
247  int ivar, iobs;
248 
249  ufo_geovals_maxloc_f90(keyGVL_, mxval, iobs, ivar);
250 
251  oops::Log::debug() << "GeoVaLs: Maximum Value (vertical rms) = "
252  << std::setprecision(4)
253  << mxval << " for observation = " << iobs
254  << " and variable = " << ivar << std::endl;
255  }
256 }
257 // -----------------------------------------------------------------------------
258 /*! \brief Return number of levels for a specified variable */
259 size_t GeoVaLs::nlevs(const std::string & var) const {
260  oops::Log::trace() << "GeoVaLs::nlevs starting" << std::endl;
261  int nlevs;
262  ufo_geovals_nlevs_f90(keyGVL_, var.size(), var.c_str(), nlevs);
263  oops::Log::trace() << "GeoVaLs::nlevs done" << std::endl;
264  return nlevs;
265 }
266 // -----------------------------------------------------------------------------
267 /*! \brief Return all values for a specific 2D variable */
268 void GeoVaLs::get(std::vector<float> & vals, const std::string & var) const {
269  oops::Log::trace() << "GeoVaLs::get 2D starting" << std::endl;
270  size_t nlocs;
272  ASSERT(vals.size() == nlocs);
273  ufo_geovals_get2d_f90(keyGVL_, var.size(), var.c_str(), nlocs, vals[0]);
274  oops::Log::trace() << "GeoVaLs::get 2D done" << std::endl;
275 }
276 // -----------------------------------------------------------------------------
277 /*! \brief Return all values for a specific variable and level */
278 void GeoVaLs::get(std::vector<float> & vals, const std::string & var, const int lev) const {
279  oops::Log::trace() << "GeoVaLs::get starting" << std::endl;
280  size_t nlocs;
282  ASSERT(vals.size() == nlocs);
283  ufo_geovals_get_f90(keyGVL_, var.size(), var.c_str(), lev, nlocs, vals[0]);
284  oops::Log::trace() << "GeoVaLs::get done" << std::endl;
285 }
286 // -----------------------------------------------------------------------------
287 /*! \brief Return all values for a specific variable and level */
288 void GeoVaLs::get(std::vector<double> & vals, const std::string & var, const int lev) const {
289  oops::Log::trace() << "GeoVaLs::get starting" << std::endl;
290  size_t nlocs;
292  ASSERT(vals.size() == nlocs);
293  ufo_geovals_getdouble_f90(keyGVL_, var.size(), var.c_str(), lev, nlocs, vals[0]);
294  oops::Log::trace() << "GeoVaLs::get done" << std::endl;
295 }
296 // -----------------------------------------------------------------------------
297 /*! \brief Put values for a specific variable and level */
298 void GeoVaLs::put(const std::vector<double> & vals, const std::string & var, const int lev) const {
299  oops::Log::trace() << "GeoVaLs::put starting" << std::endl;
300  size_t nlocs;
302  ASSERT(vals.size() == nlocs);
303  ufo_geovals_putdouble_f90(keyGVL_, var.size(), var.c_str(), lev, nlocs, vals[0]);
304  oops::Log::trace() << "GeoVaLs::get done" << std::endl;
305 }
306 // -----------------------------------------------------------------------------
307 /*! \brief Read GeoVaLs from the file */
308 void GeoVaLs::read(const eckit::Configuration & config,
309  const ioda::ObsSpace & obspace) {
310  oops::Log::trace() << "GeoVaLs::read starting" << std::endl;
311  ufo_geovals_read_file_f90(keyGVL_, config, obspace, vars_);
312  oops::Log::trace() << "GeoVaLs::read done" << std::endl;
313 }
314 // -----------------------------------------------------------------------------
315 /*! \brief Write GeoVaLs to the file */
316 void GeoVaLs::write(const eckit::Configuration & config) const {
317  oops::Log::trace() << "GeoVaLs::write starting" << std::endl;
319  oops::Log::trace() << "GeoVaLs::write done" << std::endl;
320 }
321 // -----------------------------------------------------------------------------
322 } // namespace ufo
ufo::GeoVaLs::split
void split(GeoVaLs &, GeoVaLs &) const
Split two GeoVaLs.
Definition: GeoVaLs.cc:208
ufo::GeoVaLs::random
void random()
Randomize GeoVaLs.
Definition: GeoVaLs.cc:140
ufo::ufo_geovals_dotprod_f90
void ufo_geovals_dotprod_f90(const F90goms &, const F90goms &, double &, const eckit::mpi::Comm &)
ufo::ufo_geovals_random_f90
void ufo_geovals_random_f90(const F90goms &)
ufo::ufo_geovals_get_f90
void ufo_geovals_get_f90(const F90goms &, const int &, const char *, const int &, const int &, float &)
ufo::ufo_geovals_putdouble_f90
void ufo_geovals_putdouble_f90(const F90goms &, const int &, const char *, const int &, const int &, const double &)
ufo::ufo_geovals_schurmult_f90
void ufo_geovals_schurmult_f90(const F90goms &, const F90goms &)
ufo::ufo_geovals_default_constr_f90
void ufo_geovals_default_constr_f90(F90goms &)
Interface to Fortran UFO GeoVals routines.
ufo::ufo_geovals_assign_f90
void ufo_geovals_assign_f90(const F90goms &, const F90goms &)
ufo::GeoVaLs::reorderzdir
void reorderzdir(const std::string &, const std::string &)
Reorder GeoVaLs in vertical dimension based on vertical coordinate variable.
Definition: GeoVaLs.cc:113
Fortran.h
ufo::GeoVaLs::comm_
const eckit::mpi::Comm & comm_
Definition: src/ufo/GeoVaLs.h:88
ufo_radiancerttov_utils_mod::debug
logical, public debug
Definition: ufo_radiancerttov_utils_mod.F90:100
ufo::GeoVaLs::zero
void zero()
Zero out the GeoVaLs.
Definition: GeoVaLs.cc:106
ufo::Locations
Locations class to handle locations for UFO.
Definition: src/ufo/Locations.h:32
ufo::GeoVaLs::keyGVL_
F90goms keyGVL_
Definition: src/ufo/GeoVaLs.h:86
ufo::ufo_geovals_nlevs_f90
void ufo_geovals_nlevs_f90(const F90goms &, const int &, const char *, int &)
ufo
Definition: RunCRTM.h:27
ufo::ufo_geovals_reorderzdir_f90
void ufo_geovals_reorderzdir_f90(const F90goms &, const int &, const char *, const int &, const char *)
ufo::ufo_geovals_merge_f90
void ufo_geovals_merge_f90(const F90goms &, const F90goms &, const F90goms &)
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::ufo_geovals_maxloc_f90
void ufo_geovals_maxloc_f90(const F90goms &, double &, int &, int &)
ufo::ufo_geovals_diff_f90
void ufo_geovals_diff_f90(const F90goms &, const F90goms &)
ufo::GeoVaLs::operator-=
GeoVaLs & operator-=(const GeoVaLs &)
Subtract another GeoVaLs.
Definition: GeoVaLs.cc:183
ufo::ufo_geovals_scalmult_f90
void ufo_geovals_scalmult_f90(const F90goms &, const double &)
ufo::ufo_geovals_minmaxavg_f90
void ufo_geovals_minmaxavg_f90(const F90goms &, int &, int &, double &, double &, double &)
ufo::GeoVaLs::normalizedrms
double normalizedrms(const GeoVaLs &) const
Calculate normalized rms.
Definition: GeoVaLs.cc:130
ufo::GeoVaLs::operator=
GeoVaLs & operator=(const GeoVaLs &)
Copy operator.
Definition: GeoVaLs.cc:167
ufo::ufo_geovals_copy_f90
void ufo_geovals_copy_f90(const F90goms &, F90goms &)
ufo::GeoVaLs::GeoVaLs
GeoVaLs(const eckit::mpi::Comm &)
Default constructor - does not allocate fields.
Definition: GeoVaLs.cc:27
ufo::ufo_geovals_setup_f90
void ufo_geovals_setup_f90(F90goms &, const F90locs &, const oops::Variables &)
ufo::ufo_geovals_getdouble_f90
void ufo_geovals_getdouble_f90(const F90goms &, const int &, const char *, const int &, const int &, double &)
ufo::GeoVaLs::put
void put(const std::vector< double > &, const std::string &, const int) const
Put values for a specific variable and level.
Definition: GeoVaLs.cc:298
ufo::Locations::nobs
int nobs() const
Definition: Locations.cc:97
ufo::ufo_geovals_profmult_f90
void ufo_geovals_profmult_f90(const F90goms &, const int &, const float &)
ufo::GeoVaLs::operator+=
GeoVaLs & operator+=(const GeoVaLs &)
Add another GeoVaLs.
Definition: GeoVaLs.cc:175
ufo::ufo_geovals_normalize_f90
void ufo_geovals_normalize_f90(const F90goms &, const F90goms &)
ufo::ufo_geovals_read_file_f90
void ufo_geovals_read_file_f90(const F90goms &, const eckit::Configuration &, const ioda::ObsSpace &, const oops::Variables &)
ufo::GeoVaLs
GeoVaLs: geophysical values at locations.
Definition: src/ufo/GeoVaLs.h:39
ufo::GeoVaLs::~GeoVaLs
~GeoVaLs()
Definition: GeoVaLs.cc:99
ufo::ufo_geovals_write_file_f90
void ufo_geovals_write_file_f90(const F90goms &, const eckit::Configuration &, const eckit::mpi::Comm &)
ufo::ufo_geovals_delete_f90
void ufo_geovals_delete_f90(F90goms &)
ufo::GeoVaLs::write
void write(const eckit::Configuration &) const
Write GeoVaLs to the file.
Definition: GeoVaLs.cc:316
ufo::GeoVaLs::vars_
oops::Variables vars_
Definition: src/ufo/GeoVaLs.h:87
ufo::ufo_geovals_get2d_f90
void ufo_geovals_get2d_f90(const F90goms &, const int &, const char *, const int &, float &)
ufo::ufo_geovals_nlocs_f90
void ufo_geovals_nlocs_f90(const F90goms &, size_t &)
ufo::GeoVaLs::rms
double rms() const
Calculate rms.
Definition: GeoVaLs.cc:121
ufo::GeoVaLs::print
void print(std::ostream &) const
Output GeoVaLs to a stream.
Definition: GeoVaLs.cc:224
ufo::ufo_geovals_copy_one_f90
void ufo_geovals_copy_one_f90(F90goms &, const F90goms &, int &)
ufo::ufo_geovals_split_f90
void ufo_geovals_split_f90(const F90goms &, const F90goms &, const F90goms &)
ufo::GeoVaLs::read
void read(const eckit::Configuration &, const ioda::ObsSpace &)
Read GeoVaLs from the file.
Definition: GeoVaLs.cc:308
ufo::GeoVaLs::nlevs
size_t nlevs(const std::string &var) const
Return number of levels for a specified variable.
Definition: GeoVaLs.cc:259
ufo::GeoVaLs::merge
void merge(const GeoVaLs &, const GeoVaLs &)
Merge two GeoVaLs.
Definition: GeoVaLs.cc:216
ufo::ufo_geovals_rms_f90
void ufo_geovals_rms_f90(const F90goms &, double &)
ufo::GeoVaLs::dot_product_with
double dot_product_with(const GeoVaLs &) const
Scalar product of two GeoVaLs.
Definition: GeoVaLs.cc:199
ufo::GeoVaLs::operator*=
GeoVaLs & operator*=(const double)
Multiply by a constant scalar.
Definition: GeoVaLs.cc:147
ufo::ufo_geovals_zero_f90
void ufo_geovals_zero_f90(const F90goms &)
ufo::ufo_geovals_add_f90
void ufo_geovals_add_f90(const F90goms &, const F90goms &)