IODA
ObsDataVector.h
Go to the documentation of this file.
1 /*
2  * (C) Copyright 2018-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 #ifndef OBSDATAVECTOR_H_
9 #define OBSDATAVECTOR_H_
10 
11 #include <cmath>
12 #include <limits>
13 #include <ostream>
14 #include <string>
15 #include <vector>
16 
17 #include <boost/math/special_functions/fpclassify.hpp>
18 
19 #include "eckit/exception/Exceptions.h"
20 #include "eckit/mpi/Comm.h"
21 
22 #include "oops/base/Variables.h"
23 #include "oops/util/Logger.h"
24 #include "oops/util/missingValues.h"
25 #include "oops/util/ObjectCounter.h"
26 #include "oops/util/Printable.h"
27 
28 #include "ioda/ObsSpace.h"
29 
30 namespace ioda {
31 
32 //-----------------------------------------------------------------------------
33 
34 template <typename DATATYPE> using ObsDataRow = std::vector<DATATYPE>;
35 
36 //-----------------------------------------------------------------------------
37 //! ObsDataVector<DATATYPE> handles vectors of data of type DATATYPE in observation space
38 
39 template<typename DATATYPE>
40 class ObsDataVector: public util::Printable,
41  private util::ObjectCounter<ObsDataVector<DATATYPE> > {
42  public:
43  static const std::string classname() {return "ioda::ObsDataVector";}
44 
45  ObsDataVector(ObsSpace &, const oops::Variables &,
46  const std::string & grp = "", const bool fail = true);
47  ObsDataVector(ObsSpace &, const std::string &,
48  const std::string & grp = "", const bool fail = true);
51 
53 
54  void zero();
55  void mask(const ObsDataVector<int> &);
56 
57  void read(const std::string &, const bool fail = true); // only used in GNSSRO QC
58  void save(const std::string &) const;
59 
60 // Methods below are used by UFO but not by OOPS
61  size_t nvars() const {return nvars_;} // Size in (local) memory
62  size_t nlocs() const {return nlocs_;} // Size in (local) memory
63  bool has(const std::string & vargrp) const {return obsvars_.has(vargrp);}
64 
65  const ObsDataRow<DATATYPE> & operator[](const size_t ii) const {return rows_.at(ii);}
66  ObsDataRow<DATATYPE> & operator[](const size_t ii) {return rows_.at(ii);}
67 
68  const ObsDataRow<DATATYPE> & operator[](const std::string var) const
69  {return rows_.at(obsvars_.find(var));}
70  ObsDataRow<DATATYPE> & operator[](const std::string var) {return rows_.at(obsvars_.find(var));}
71 
72  const std::string & obstype() const {return obsdb_.obsname();}
73  const oops::Variables & varnames() const {return obsvars_;}
74 
75  private:
76  void print(std::ostream &) const;
77 
79  oops::Variables obsvars_;
80  size_t nvars_;
81  size_t nlocs_;
82  std::vector<ObsDataRow<DATATYPE> > rows_;
83  const DATATYPE missing_;
84 };
85 
86 // -----------------------------------------------------------------------------
87 template <typename DATATYPE>
88 ObsDataVector<DATATYPE>::ObsDataVector(ObsSpace & obsdb, const oops::Variables & vars,
89  const std::string & grp, const bool fail)
90  : obsdb_(obsdb), obsvars_(vars), nvars_(obsvars_.size()),
91  nlocs_(obsdb_.nlocs()), rows_(nvars_),
92  missing_(util::missingValue(missing_))
93 {
94  oops::Log::trace() << "ObsDataVector::ObsDataVector start" << std::endl;
95  for (size_t jj = 0; jj < nvars_; ++jj) {
96  rows_[jj].resize(nlocs_);
97  }
98  if (!grp.empty()) this->read(grp, fail);
99  oops::Log::trace() << "ObsDataVector::ObsDataVector done" << std::endl;
100 }
101 // -----------------------------------------------------------------------------
102 template <typename DATATYPE>
103 ObsDataVector<DATATYPE>::ObsDataVector(ObsSpace & obsdb, const std::string & var,
104  const std::string & grp, const bool fail)
105  : obsdb_(obsdb), obsvars_(std::vector<std::string>(1, var)), nvars_(1),
106  nlocs_(obsdb_.nlocs()), rows_(1),
107  missing_(util::missingValue(missing_))
108 {
109  oops::Log::trace() << "ObsDataVector::ObsDataVector start" << std::endl;
110  rows_[0].resize(nlocs_);
111  if (!grp.empty()) this->read(grp, fail);
112  oops::Log::trace() << "ObsDataVector::ObsDataVector done" << std::endl;
113 }
114 // -----------------------------------------------------------------------------
115 template <typename DATATYPE>
117  : obsdb_(other.obsdb_), obsvars_(other.obsvars_), nvars_(other.nvars_),
118  nlocs_(other.nlocs_), rows_(other.rows_), missing_(util::missingValue(missing_)) {
119  oops::Log::trace() << "ObsDataVector copied" << std::endl;
120 }
121 // -----------------------------------------------------------------------------
122 template <typename DATATYPE>
124 // -----------------------------------------------------------------------------
125 template <typename DATATYPE>
127  oops::Log::trace() << "ObsDataVector::operator= start" << std::endl;
128  ASSERT(&obsdb_ == &rhs.obsdb_);
129  obsvars_ = rhs.obsvars_;
130  nvars_ = rhs.nvars_;
131  nlocs_ = rhs.nlocs_;
132  rows_ = rhs.rows_;
133  oops::Log::trace() << "ObsDataVector::operator= done" << std::endl;
134  return *this;
135 }
136 // -----------------------------------------------------------------------------
137 template <typename DATATYPE>
139  for (size_t jv = 0; jv < nvars_; ++jv) {
140  for (size_t jj = 0; jj < nlocs_; ++jj) {
141  rows_.at(jv).at(jj) = static_cast<DATATYPE>(0);
142  }
143  }
144 }
145 // -----------------------------------------------------------------------------
146 template <typename DATATYPE>
148  ASSERT(nvars_ == flags.nvars());
149  ASSERT(nlocs_ == flags.nlocs());
150  for (size_t jv = 0; jv < nvars_; ++jv) {
151  for (size_t jj = 0; jj < nlocs_; ++jj) {
152  if (flags[jv][jj] > 0) rows_.at(jv).at(jj) = missing_;
153  }
154  }
155 }
156 // -----------------------------------------------------------------------------
157 template <typename DATATYPE>
158 void ObsDataVector<DATATYPE>::read(const std::string & name, const bool fail) {
159  oops::Log::trace() << "ObsDataVector::read, name = " << name << std::endl;
160  const DATATYPE missing = util::missingValue(missing);
161  std::vector<DATATYPE> tmp(nlocs_);
162 
163  for (size_t jv = 0; jv < nvars_; ++jv) {
164  if (fail || obsdb_.has(name, obsvars_.variables()[jv])) {
165  obsdb_.get_db(name, obsvars_.variables()[jv], tmp);
166  for (size_t jj = 0; jj < nlocs_; ++jj) {
167  rows_.at(jv).at(jj) = tmp.at(jj);
168  }
169  }
170  }
171 }
172 // -----------------------------------------------------------------------------
173 template <typename DATATYPE>
174 void ObsDataVector<DATATYPE>::save(const std::string & name) const {
175  oops::Log::trace() << "ObsDataVector::save, name = " << name << std::endl;
176  std::vector<DATATYPE> tmp(nlocs_);
177  for (size_t jv = 0; jv < nvars_; ++jv) {
178  for (size_t jj = 0; jj < nlocs_; ++jj) {
179  tmp.at(jj) = rows_.at(jv).at(jj);
180  }
181  obsdb_.put_db(name, obsvars_.variables()[jv], tmp);
182  }
183 }
184 // -----------------------------------------------------------------------------
185 template <typename DATATYPE>
186 void ObsDataVector<DATATYPE>::print(std::ostream & os) const {
187  const DATATYPE missing = util::missingValue(missing);
188  for (size_t jv = 0; jv < nvars_; ++jv) {
189  DATATYPE zmin = std::numeric_limits<DATATYPE>::max();
190  DATATYPE zmax = std::numeric_limits<DATATYPE>::lowest();
191  int nobs = 0;
192  int nloc = nlocs_;
193  for (size_t jj = 0; jj < nlocs_; ++jj) {
194  DATATYPE zz = rows_.at(jv).at(jj);
195  if (zz != missing) {
196  if (zz < zmin) zmin = zz;
197  if (zz > zmax) zmax = zz;
198  ++nobs;
199  }
200  }
201  if (obsdb_.isDistributed()) {
202  obsdb_.comm().allReduceInPlace(zmin, eckit::mpi::min());
203  obsdb_.comm().allReduceInPlace(zmax, eckit::mpi::max());
204  obsdb_.comm().allReduceInPlace(nobs, eckit::mpi::sum());
205  obsdb_.comm().allReduceInPlace(nloc, eckit::mpi::sum());
206  }
207  os << obsdb_.obsname() << " " << obsvars_[jv] << " nlocs = " << nloc
208  << ", nobs= " << nobs << " Min=" << zmin << ", Max=" << zmax << std::endl;
209  }
210 }
211 // -----------------------------------------------------------------------------
212 } // namespace ioda
213 
214 #endif // OBSDATAVECTOR_H_
ioda::ObsDataVector::ObsDataVector
ObsDataVector(ObsSpace &, const oops::Variables &, const std::string &grp="", const bool fail=true)
Definition: ObsDataVector.h:88
ioda::ObsDataVector::nlocs
size_t nlocs() const
Definition: ObsDataVector.h:62
ioda::ObsDataVector::~ObsDataVector
~ObsDataVector()
Definition: ObsDataVector.h:123
ObsSpace.h
ioda::ObsDataVector::rows_
std::vector< ObsDataRow< DATATYPE > > rows_
Definition: ObsDataVector.h:82
ioda::ObsDataVector::zero
void zero()
Definition: ObsDataVector.h:138
ioda::ObsDataVector::operator=
ObsDataVector & operator=(const ObsDataVector &)
Definition: ObsDataVector.h:126
ioda::ObsDataVector::save
void save(const std::string &) const
Definition: ObsDataVector.h:174
ioda::ObsDataVector::classname
static const std::string classname()
Definition: ObsDataVector.h:43
ioda::ObsDataVector::obsdb_
ObsSpace & obsdb_
Definition: ObsDataVector.h:78
ioda::ObsDataVector::print
void print(std::ostream &) const
Definition: ObsDataVector.h:186
ioda::ObsDataRow
std::vector< DATATYPE > ObsDataRow
Definition: ObsDataVector.h:34
ioda::ObsDataVector::nlocs_
size_t nlocs_
Definition: ObsDataVector.h:81
ioda
Definition: IodaUtils.cc:13
ioda::ObsDataVector::varnames
const oops::Variables & varnames() const
Definition: ObsDataVector.h:73
ioda::ObsDataVector::nvars_
size_t nvars_
Definition: ObsDataVector.h:80
ioda::ObsDataVector::obsvars_
oops::Variables obsvars_
Definition: ObsDataVector.h:79
ioda::ObsDataVector::mask
void mask(const ObsDataVector< int > &)
Definition: ObsDataVector.h:147
ioda::ObsDataVector::operator[]
const ObsDataRow< DATATYPE > & operator[](const size_t ii) const
Definition: ObsDataVector.h:65
ioda::ObsDataVector::missing_
const DATATYPE missing_
Definition: ObsDataVector.h:83
ioda::ObsSpace::obsname
const std::string & obsname() const
Definition: src/ObsSpace.h:97
ioda::ObsDataVector::read
void read(const std::string &, const bool fail=true)
Definition: ObsDataVector.h:158
ioda::ObsDataVector
ObsDataVector<DATATYPE> handles vectors of data of type DATATYPE in observation space.
Definition: ObsDataVector.h:41
ioda::ObsDataVector::obstype
const std::string & obstype() const
Definition: ObsDataVector.h:72
ioda::ObsDataVector::nvars
size_t nvars() const
Definition: ObsDataVector.h:61
ioda::ObsDataVector::has
bool has(const std::string &vargrp) const
Definition: ObsDataVector.h:63
ioda::ObsDataVector::operator[]
ObsDataRow< DATATYPE > & operator[](const size_t ii)
Definition: ObsDataVector.h:66
ioda::ObsDataVector::operator[]
ObsDataRow< DATATYPE > & operator[](const std::string var)
Definition: ObsDataVector.h:70
ioda::ObsSpace
Observation Space View.
Definition: src/ObsSpace.h:35
ioda::ObsDataVector::operator[]
const ObsDataRow< DATATYPE > & operator[](const std::string var) const
Definition: ObsDataVector.h:68