13 #include "eckit/config/LocalConfiguration.h"
14 #include "ioda/distribution/DistributionUtils.h"
17 #include "oops/base/Variables.h"
18 #include "oops/util/abor1_cpp.h"
19 #include "oops/util/Logger.h"
20 #include "oops/util/missingValues.h"
21 #include "oops/util/Random.h"
26 const std::string &
name)
27 : obsdb_(obsdb), obsvars_(obsdb.obsvariables()),
28 nvars_(obsvars_.variables().size()), nlocs_(obsdb_.nlocs()),
29 values_(nlocs_ * nvars_),
30 missing_(
util::missingValue(missing_)) {
31 oops::Log::trace() <<
"ObsVector::ObsVector " <<
name << std::endl;
36 : obsdb_(other.obsdb_), obsvars_(other.obsvars_), nvars_(other.nvars_),
37 nlocs_(other.nlocs_), values_(nlocs_ * nvars_), missing_(other.missing_) {
39 oops::Log::trace() <<
"ObsVector copied " << std::endl;
51 for (
size_t jj = 0; jj <
values_.size() ; ++jj) {
60 const size_t nn =
values_.size();
61 ASSERT(rhs.
values_.size() == nn);
62 for (
size_t jj = 0; jj < nn ; ++jj) {
73 const size_t nn =
values_.size();
74 ASSERT(rhs.
values_.size() == nn);
75 for (
size_t jj = 0; jj < nn ; ++jj) {
86 const size_t nn =
values_.size();
87 ASSERT(rhs.
values_.size() == nn);
88 for (
size_t jj = 0; jj < nn ; ++jj) {
99 const size_t nn =
values_.size();
100 ASSERT(rhs.
values_.size() == nn);
101 for (
size_t jj = 0; jj < nn ; ++jj) {
112 for (
size_t jj = 0; jj <
values_.size() ; ++jj) {
122 const size_t nn =
values_.size();
123 ASSERT(rhs.
values_.size() == nn);
124 for (
size_t jj = 0; jj < nn ; ++jj) {
135 ASSERT(beta.size() ==
nvars_);
138 for (
size_t jloc = 0; jloc <
nlocs_; ++jloc) {
139 for (
size_t jvar = 0; jvar <
nvars_; ++jvar, ++ivec) {
150 for (
size_t jj = 0; jj <
values_.size() ; ++jj) {
158 util::NormalDistribution<double> x(
values_.size(), 0.0, 1.0, this->getSeed());
159 for (
size_t jj = 0; jj <
values_.size() ; ++jj) {
170 std::vector<double> result(
nvars_, 0);
171 for (
size_t jvar = 0; jvar <
nvars_; ++jvar) {
175 std::vector<double> x1(
nlocs_);
176 std::vector<double> x2(
nlocs_);
177 for (
size_t jloc = 0; jloc <
nlocs_; ++jloc) {
189 if (nobs > 0) zrms = sqrt(zrms /
static_cast<double>(
nobs));
195 oops::Log::trace() <<
"ObsVector::read, name = " <<
name << std::endl;
206 std::vector<double> tmp(
nlocs);
207 for (std::size_t jv = 0; jv <
nvars_; ++jv) {
210 for (std::size_t jj = 0; jj <
nlocs; ++jj) {
211 std::size_t ivec = jv + (jj *
nvars_);
218 oops::Log::trace() <<
"ObsVector::save, name = " <<
name << std::endl;
225 for (std::size_t jv = 0; jv <
nvars_; ++jv) {
226 std::vector<double> tmp(
nlocs);
227 for (std::size_t jj = 0; jj < tmp.size(); ++jj) {
228 ivec = jv + (jj *
nvars_);
236 const size_t nn =
values_.size();
237 assert(
mask.values_.size() == nn);
239 for (
size_t jj = 0; jj < nn; ++jj) {
246 const size_t nn =
values_.size();
247 assert(
mask.values_.size() == nn);
250 for (
size_t jj = 0; jj < nn; ++jj) {
259 oops::Log::trace() <<
"ObsVector::operator= start" << std::endl;
263 const float fmiss = util::missingValue(fmiss);
264 const double dmiss = util::missingValue(dmiss);
266 for (
size_t jl = 0; jl <
nlocs_; ++jl) {
267 for (
size_t jv = 0; jv <
nvars_; ++jv) {
268 if (rhs[jv][jl] == fmiss) {
271 values_[ii] =
static_cast<double>(rhs[jv][jl]);
276 oops::Log::trace() <<
"ObsVector::operator= done" << std::endl;
282 oops::Log::trace() <<
"ObsVector::mask" << std::endl;
285 for (
size_t jj = 0; jj < flags.
nlocs(); ++jj) {
286 for (
size_t jv = 0; jv < flags.
nvars(); ++jv) {
294 const size_t nn =
values_.size();
295 assert(
mask.values_.size() == nn);
296 for (
size_t jj = 0; jj < nn; ++jj) {
316 double zmin = std::numeric_limits<double>::max();
317 double zmax = std::numeric_limits<double>::lowest();
320 for (
size_t jj = 0; jj <
values_.size() ; ++jj) {
327 obsdb_.distribution()->min(zmin);
328 obsdb_.distribution()->max(zmax);
331 os <<
obsdb_.obsname() <<
" nobs= " <<
nobs <<
" Min="
332 << zmin <<
", Max=" << zmax <<
", RMS=" << zrms << std::endl;
334 os <<
obsdb_.obsname() <<
": No observations." << std::endl;
ObsDataVector<DATATYPE> handles vectors of data of type DATATYPE in observation space.
const ObsSpace & space() const
ObsVector class to handle vectors in observation space for IODA.
void read(const std::string &)
std::size_t nlocs() const
void mask(const ObsDataVector< int > &mask)
Set this ObsVector values to missing where mask is non-zero.
void save(const std::string &) const
ObsSpace & obsdb_
Associate ObsSpace object.
void axpy(const double &beta, const ObsVector &y)
adds beta * y to the current vector
ObsVector & operator*=(const double &)
ObsVector & operator/=(const ObsVector &)
ObsVector(ObsSpace &, const std::string &name="")
void ones()
set all elements to one (used in tests)
unsigned int nobs() const
Number of active observations (missing values not included) across all MPI tasks.
ObsVector & operator=(const ObsVector &)
Eigen::VectorXd packEigen(const ObsVector &mask) const
ObsVector & operator-=(const ObsVector &)
oops::Variables obsvars_
Variables.
const double & toFortran() const
double dot_product_with(const ObsVector &other) const
global (across all MPI tasks) dot product of this with other
size_t packEigenSize(const ObsVector &mask) const
const double missing_
Missing data mark.
void print(std::ostream &) const
std::vector< double > multivar_dot_product_with(const ObsVector &other) const
std::vector< double > values_
Vector data.
ObsVector & operator+=(const ObsVector &)
std::size_t nvars_
Number of variables.
double dotProduct(const Distribution &dist, std::size_t numVariables, const std::vector< double > &v1, const std::vector< double > &v2)
std::size_t globalNumNonMissingObs(const Distribution &dist, std::size_t numVariables, const std::vector< double > &v)