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"
34 template <
typename DATATYPE>
using ObsDataRow = std::vector<DATATYPE>;
39 template<
typename DATATYPE>
41 private util::ObjectCounter<ObsDataVector<DATATYPE> > {
43 static const std::string
classname() {
return "ioda::ObsDataVector";}
46 const std::string & grp =
"",
const bool fail =
true);
48 const std::string & grp =
"",
const bool fail =
true);
57 void read(
const std::string &,
const bool fail =
true);
58 void save(
const std::string &)
const;
63 bool has(
const std::string & vargrp)
const {
return obsvars_.has(vargrp);}
76 void print(std::ostream &)
const;
82 std::vector<ObsDataRow<DATATYPE> >
rows_;
87 template <
typename DATATYPE>
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_))
94 oops::Log::trace() <<
"ObsDataVector::ObsDataVector start" << std::endl;
95 for (
size_t jj = 0; jj <
nvars_; ++jj) {
98 if (!grp.empty()) this->
read(grp, fail);
99 oops::Log::trace() <<
"ObsDataVector::ObsDataVector done" << std::endl;
102 template <
typename DATATYPE>
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_))
109 oops::Log::trace() <<
"ObsDataVector::ObsDataVector start" << std::endl;
111 if (!grp.empty()) this->
read(grp, fail);
112 oops::Log::trace() <<
"ObsDataVector::ObsDataVector done" << std::endl;
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;
122 template <
typename DATATYPE>
125 template <
typename DATATYPE>
127 oops::Log::trace() <<
"ObsDataVector::operator= start" << std::endl;
128 ASSERT(&obsdb_ == &rhs.
obsdb_);
133 oops::Log::trace() <<
"ObsDataVector::operator= done" << std::endl;
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);
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_;
157 template <
typename DATATYPE>
159 oops::Log::trace() <<
"ObsDataVector::read, name = " << name << std::endl;
160 const DATATYPE missing = util::missingValue(missing);
161 std::vector<DATATYPE> tmp(nlocs_);
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);
173 template <
typename DATATYPE>
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);
181 obsdb_.put_db(name, obsvars_.variables()[jv], tmp);
185 template <
typename DATATYPE>
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();
193 for (
size_t jj = 0; jj < nlocs_; ++jj) {
194 DATATYPE zz = rows_.at(jv).at(jj);
196 if (zz < zmin) zmin = zz;
197 if (zz > zmax) zmax = zz;
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());
207 os << obsdb_.obsname() <<
" " << obsvars_[jv] <<
" nlocs = " << nloc
208 <<
", nobs= " << nobs <<
" Min=" << zmin <<
", Max=" << zmax << std::endl;
214 #endif // OBSDATAVECTOR_H_