8 #ifndef OBSDATAVECTOR_H_
9 #define OBSDATAVECTOR_H_
17 #include <boost/math/special_functions/fpclassify.hpp>
19 #include "eckit/exception/Exceptions.h"
20 #include "eckit/mpi/Comm.h"
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"
28 #include "ioda/distribution/Accumulator.h"
29 #include "ioda/distribution/DistributionUtils.h"
37 template <
typename DATATYPE>
using ObsDataRow = std::vector<DATATYPE>;
42 template<
typename DATATYPE>
44 private util::ObjectCounter<ObsDataVector<DATATYPE> > {
46 static const std::string
classname() {
return "ioda::ObsDataVector";}
49 const std::string & grp =
"",
const bool fail =
true);
51 const std::string & grp =
"",
const bool fail =
true);
61 void read(
const std::string &,
const bool fail =
true);
62 void save(
const std::string &)
const;
68 bool has(
const std::string & vargrp)
const {
return obsvars_.has(vargrp);}
81 void print(std::ostream &)
const;
87 std::vector<ObsDataRow<DATATYPE> >
rows_;
92 template <
typename DATATYPE>
94 const std::string & grp,
const bool fail)
95 : obsdb_(obsdb), obsvars_(vars), nvars_(obsvars_.size()),
96 nlocs_(obsdb_.nlocs()), rows_(nvars_),
97 missing_(
util::missingValue(missing_))
99 oops::Log::trace() <<
"ObsDataVector::ObsDataVector start" << std::endl;
100 for (
size_t jj = 0; jj <
nvars_; ++jj) {
103 if (!grp.empty()) this->
read(grp, fail);
104 oops::Log::trace() <<
"ObsDataVector::ObsDataVector done" << std::endl;
107 template <
typename DATATYPE>
109 const std::string & grp,
const bool fail)
110 : obsdb_(obsdb), obsvars_(std::vector<std::string>(1, var)), nvars_(1),
111 nlocs_(obsdb_.nlocs()), rows_(1),
112 missing_(
util::missingValue(missing_))
114 oops::Log::trace() <<
"ObsDataVector::ObsDataVector start" << std::endl;
116 if (!grp.empty()) this->
read(grp, fail);
117 oops::Log::trace() <<
"ObsDataVector::ObsDataVector done" << std::endl;
120 template <
typename DATATYPE>
122 : obsdb_(vect.space()), obsvars_(vect.varnames()), nvars_(vect.nvars()), nlocs_(vect.nlocs()),
123 rows_(nvars_), missing_(
util::missingValue(missing_))
125 oops::Log::trace() <<
"ObsDataVector::ObsDataVector ObsVector start" << std::endl;
126 const double dmiss = util::missingValue(dmiss);
127 for (
size_t jv = 0; jv <
nvars_; ++jv) {
131 for (
size_t jl = 0; jl <
nlocs_; ++jl) {
132 for (
size_t jv = 0; jv <
nvars_; ++jv) {
133 if (vect[ii] == dmiss) {
136 rows_[jv][jl] =
static_cast<DATATYPE
>(vect[ii]);
141 oops::Log::trace() <<
"ObsDataVector::ObsDataVector ObsVector done" << std::endl;
144 template <
typename DATATYPE>
146 : obsdb_(other.obsdb_), obsvars_(other.obsvars_), nvars_(other.nvars_),
147 nlocs_(other.nlocs_), rows_(other.rows_), missing_(
util::missingValue(missing_)) {
148 oops::Log::trace() <<
"ObsDataVector copied" << std::endl;
151 template <
typename DATATYPE>
154 template <
typename DATATYPE>
156 oops::Log::trace() <<
"ObsDataVector::operator= start" << std::endl;
157 ASSERT(&obsdb_ == &rhs.
obsdb_);
162 oops::Log::trace() <<
"ObsDataVector::operator= done" << std::endl;
166 template <
typename DATATYPE>
168 for (
size_t jv = 0; jv < nvars_; ++jv) {
169 for (
size_t jj = 0; jj < nlocs_; ++jj) {
170 rows_.at(jv).at(jj) =
static_cast<DATATYPE
>(0);
175 template <
typename DATATYPE>
177 ASSERT(nvars_ == flags.
nvars());
178 ASSERT(nlocs_ == flags.
nlocs());
179 for (
size_t jv = 0; jv < nvars_; ++jv) {
180 for (
size_t jj = 0; jj < nlocs_; ++jj) {
181 if (flags[jv][jj] > 0) rows_.at(jv).at(jj) = missing_;
186 template <
typename DATATYPE>
188 oops::Log::trace() <<
"ObsDataVector::read, name = " <<
name << std::endl;
189 const DATATYPE missing = util::missingValue(missing);
194 std::vector<DATATYPE> tmp(nlocs_);
196 for (
size_t jv = 0; jv < nvars_; ++jv) {
197 if (fail || obsdb_.has(
name, obsvars_.variables()[jv])) {
198 obsdb_.get_db(
name, obsvars_.variables()[jv], tmp);
199 for (
size_t jj = 0; jj < nlocs_; ++jj) {
200 rows_.at(jv).at(jj) = tmp.at(jj);
207 template <
typename DATATYPE>
209 oops::Log::trace() <<
"ObsDataVector::save, name = " <<
name << std::endl;
210 std::vector<DATATYPE> tmp(nlocs_);
211 for (
size_t jv = 0; jv < nvars_; ++jv) {
212 for (std::size_t jj = 0; jj < tmp.size(); ++jj) {
213 tmp.at(jj) = rows_.at(jv).at(jj);
215 obsdb_.put_db(
name, obsvars_.variables()[jv], tmp);
226 template <
typename DATATYPE>
230 for (
size_t jv = 0; jv < obsdatavector.
nvars(); ++jv) {
231 int nloc = obsdb.globalNumLocs();
234 obsdatavector.
nvars(), obsdatavector[jv]);
236 os << obsdb.obsname() <<
" " << obsdatavector.
varnames()[jv] <<
" nlocs = " << nloc
237 <<
", nobs = " << nobs << std::endl;
248 template <
typename DATATYPE>
252 const DATATYPE missing = util::missingValue(missing);
253 for (
size_t jv = 0; jv < obsdatavector.
nvars(); ++jv) {
254 DATATYPE zmin = std::numeric_limits<DATATYPE>::max();
255 DATATYPE zmax = std::numeric_limits<DATATYPE>::lowest();
256 std::unique_ptr<Accumulator<DATATYPE>> accumulator =
257 obsdb.distribution()->createAccumulator<DATATYPE>();
258 int nloc = obsdb.globalNumLocs();
260 const std::vector<DATATYPE> &vector = obsdatavector[jv];
261 for (
size_t jj = 0; jj < obsdatavector.
nlocs(); ++jj) {
262 DATATYPE zz = vector.at(jj);
264 if (zz < zmin) zmin = zz;
265 if (zz > zmax) zmax = zz;
266 accumulator->addTerm(jj, zz);
270 obsdb.distribution()->min(zmin);
271 obsdb.distribution()->max(zmax);
272 DATATYPE zsum = accumulator->computeResult();
275 os << std::endl << obsdb.obsname() <<
" " << obsdatavector.
varnames()[jv]
276 <<
" nlocs = " << nloc <<
", nobs = " << nobs;
278 os <<
", min = " << zmin <<
", max = " << zmax <<
", avg = " << zsum/nobs;
280 os <<
" : No observations.";
286 template <
typename DATATYPE>
ObsDataVector<DATATYPE> handles vectors of data of type DATATYPE in observation space.
void mask(const ObsDataVector< int > &)
ObsDataRow< DATATYPE > & operator[](const std::string var)
const oops::Variables & varnames() const
void print(std::ostream &) const
const ObsSpace & space() const
static const std::string classname()
bool has(const std::string &vargrp) const
const ObsDataRow< DATATYPE > & operator[](const std::string var) const
const ObsDataRow< DATATYPE > & operator[](const size_t ii) const
ObsDataVector & operator=(const ObsDataVector &)
ObsDataRow< DATATYPE > & operator[](const size_t ii)
std::vector< ObsDataRow< DATATYPE > > rows_
void save(const std::string &) const
ObsDataVector(ObsSpace &, const oops::Variables &, const std::string &grp="", const bool fail=true)
const std::string & obstype() const
void read(const std::string &, const bool fail=true)
ObsVector class to handle vectors in observation space for IODA.
void printNonnumericObsDataVectorStats(const ObsDataVector< DATATYPE > &obsdatavector, const ObsSpace &obsdb, std::ostream &os)
std::vector< DATATYPE > ObsDataRow
std::size_t globalNumNonMissingObs(const Distribution &dist, std::size_t numVariables, const std::vector< double > &v)
void printNumericObsDataVectorStats(const ObsDataVector< DATATYPE > &obsdatavector, const ObsSpace &obsdb, std::ostream &os)