FV3 Bundle
ObsVector.cc
Go to the documentation of this file.
1 /*
2  * (C) Copyright 2017 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 "ioda/ObsVector.h"
9 
10 #include <math.h>
11 #include <limits>
12 #include <random>
13 
14 #include "eckit/mpi/Comm.h"
15 #include "oops/util/abor1_cpp.h"
16 #include "oops/util/Logger.h"
17 
18 #include "ioda/constants.h"
19 #include "ioda/ObsSpace.h"
20 
21 namespace ioda {
22 // -----------------------------------------------------------------------------
23 ObsVector::ObsVector(const ObsSpace & obsdb) : obsdb_(obsdb), values_(obsdb_.nobs()) {
24  oops::Log::debug() << "ObsVector constructed with " << values_.size()
25  << " elements." << std::endl;
26 }
27 // -----------------------------------------------------------------------------
28 ObsVector::ObsVector(const ObsVector & other, const bool copy)
29  : obsdb_(other.obsdb_), values_(obsdb_.nobs()) {
30  oops::Log::debug() << "ObsVector copy constructed with " << values_.size()
31  << " elements." << std::endl;
32  if (copy) values_ = other.values_;
33 }
34 // -----------------------------------------------------------------------------
36 }
37 // -----------------------------------------------------------------------------
39  values_ = rhs.values_;
40  return *this;
41 }
42 // -----------------------------------------------------------------------------
43 ObsVector & ObsVector::operator*= (const double & zz) {
44  for (size_t jj = 0; jj < values_.size() ; ++jj) {
45  if (values_[jj] != missing_value) {
46  values_[jj] = zz * values_[jj];
47  }
48  }
49  return *this;
50 }
51 // -----------------------------------------------------------------------------
53  const size_t nn = values_.size();
54  ASSERT(rhs.values_.size() == nn);
55  for (size_t jj = 0; jj < nn ; ++jj) {
56  if (values_[jj] == missing_value || rhs.values_[jj] == missing_value) {
57  values_[jj] = missing_value;
58  } else {
59  values_[jj] += rhs.values_[jj];
60  }
61  }
62  return *this;
63 }
64 // -----------------------------------------------------------------------------
66  const size_t nn = values_.size();
67  ASSERT(rhs.values_.size() == nn);
68  for (size_t jj = 0; jj < nn ; ++jj) {
69  if (values_[jj] == missing_value || rhs.values_[jj] == missing_value) {
70  values_[jj] = missing_value;
71  } else {
72  values_[jj] -= rhs.values_[jj];
73  }
74  }
75  return *this;
76 }
77 // -----------------------------------------------------------------------------
79  const size_t nn = values_.size();
80  ASSERT(rhs.values_.size() == nn);
81  for (size_t jj = 0; jj < nn ; ++jj) {
82  if (values_[jj] == missing_value || rhs.values_[jj] == missing_value) {
83  values_[jj] = missing_value;
84  } else {
85  values_[jj] *= rhs.values_[jj];
86  }
87  }
88  return *this;
89 }
90 // -----------------------------------------------------------------------------
92  const size_t nn = values_.size();
93  ASSERT(rhs.values_.size() == nn);
94  for (size_t jj = 0; jj < nn ; ++jj) {
95  if (values_[jj] == missing_value || rhs.values_[jj] == missing_value) {
96  values_[jj] = missing_value;
97  } else {
98  values_[jj] /= rhs.values_[jj];
99  }
100  }
101  return *this;
102 }
103 // -----------------------------------------------------------------------------
105  for (size_t jj = 0; jj < values_.size() ; ++jj) {
106  values_[jj] = 0.0;
107  }
108 }
109 // -----------------------------------------------------------------------------
110 void ObsVector::axpy(const double & zz, const ObsVector & rhs) {
111  const size_t nn = values_.size();
112  ASSERT(rhs.values_.size() == nn);
113  for (size_t jj = 0; jj < nn ; ++jj) {
114  if (values_[jj] == missing_value || rhs.values_[jj] == missing_value) {
115  values_[jj] = missing_value;
116  } else {
117  values_[jj] += zz * rhs.values_[jj];
118  }
119  }
120 }
121 // -----------------------------------------------------------------------------
123  for (size_t jj = 0; jj < values_.size() ; ++jj) {
124  if (values_[jj] != missing_value) {
125  values_[jj] = 1.0 / values_[jj];
126  }
127  }
128 }
129 // -----------------------------------------------------------------------------
131  static std::mt19937 generator(1);
132  static std::normal_distribution<double> distribution(0.0, 1.0);
133  for (size_t jj = 0; jj < values_.size() ; ++jj) {
134  values_[jj] = distribution(generator);
135  }
136 }
137 // -----------------------------------------------------------------------------
138 double ObsVector::dot_product_with(const ObsVector & other) const {
139  const size_t nn = values_.size();
140  ASSERT(other.values_.size() == nn);
141  double zz = 0.0;
142  for (size_t jj = 0; jj < nn ; ++jj) {
143  if (values_[jj] != missing_value && other.values_[jj] != missing_value) {
144  zz += values_[jj] * other.values_[jj];
145  }
146  }
147  obsdb_.comm().allReduceInPlace(zz, eckit::mpi::sum());
148  return zz;
149 }
150 // -----------------------------------------------------------------------------
151 double ObsVector::rms() const {
152  double zrms = 0.0;
153  int nobs = 0;
154  for (size_t jj = 0; jj < values_.size() ; ++jj) {
155  if (values_[jj] != missing_value) {
156  zrms += values_[jj] * values_[jj];
157  ++nobs;
158  }
159  }
160  obsdb_.comm().allReduceInPlace(zrms, eckit::mpi::sum());
161  obsdb_.comm().allReduceInPlace(nobs, eckit::mpi::sum());
162  if (nobs > 0) zrms = sqrt(zrms / static_cast<double>(nobs));
163  return zrms;
164 }
165 // -----------------------------------------------------------------------------
166 void ObsVector::read(const std::string & name) {
168 }
169 // -----------------------------------------------------------------------------
170 void ObsVector::save(const std::string & name) const {
172 }
173 // -----------------------------------------------------------------------------
174 unsigned int ObsVector::nobs() const {
175  int nobs = 0;
176  for (size_t jj = 0; jj < values_.size() ; ++jj) {
177  if (values_[jj] != missing_value) {
178  ++nobs;
179  }
180  }
181  obsdb_.comm().allReduceInPlace(nobs, eckit::mpi::sum());
182  return nobs;
183 }
184 // -----------------------------------------------------------------------------
185 void ObsVector::print(std::ostream & os) const {
186  double zmin = std::numeric_limits<double>::max();
187  double zmax = std::numeric_limits<double>::lowest();
188  double zrms = 0.0;
189  int nobs = 0;
190  for (size_t jj = 0; jj < values_.size() ; ++jj) {
191  if (values_[jj] != missing_value) {
192  if (values_[jj] < zmin) zmin = values_[jj];
193  if (values_[jj] > zmax) zmax = values_[jj];
194  zrms += values_[jj] * values_[jj];
195  ++nobs;
196  }
197  }
198  obsdb_.comm().allReduceInPlace(zmin, eckit::mpi::min());
199  obsdb_.comm().allReduceInPlace(zmax, eckit::mpi::max());
200  obsdb_.comm().allReduceInPlace(zrms, eckit::mpi::sum());
201  obsdb_.comm().allReduceInPlace(nobs, eckit::mpi::sum());
202  if (nobs > 0) zrms = sqrt(zrms / static_cast<double>(nobs));
203  os << obsdb_.obsname() << " nobs= " << nobs << " Min="
204  << zmin << ", Max=" << zmax << ", Average=" << zrms;
205 }
206 // -----------------------------------------------------------------------------
207 
208 } // namespace ioda
void axpy(const double &, const ObsVector &)
Definition: ObsVector.cc:110
void read(const std::string &)
Definition: ObsVector.cc:166
unsigned int nobs() const
Definition: ObsVector.cc:174
ObsVector class to handle vectors in observation space for IODA.
std::vector< double > values_
Vector data.
const std::string & obsname() const
void save(const std::string &) const
Definition: ObsVector.cc:170
subroutine, public copy(self, rhs)
const eckit::mpi::Comm & comm() const
ObsVector & operator+=(const ObsVector &)
Definition: ObsVector.cc:52
Wrapper around ObsHelpQG, mostly to hide the factory.
character(len=32) name
void getObsVector(const std::string &, std::vector< double > &) const
Definition: ObsSpace.cc:46
ObsVector & operator=(const ObsVector &)
Definition: ObsVector.cc:38
logical debug
Definition: mpp.F90:1297
ObsVector & operator*=(const double &)
Definition: ObsVector.cc:43
const ObsSpace & obsdb_
Associate ObsSpace object.
ObsVector & operator-=(const ObsVector &)
Definition: ObsVector.cc:65
ObsVector(const ObsSpace &)
Definition: ObsVector.cc:23
double dot_product_with(const ObsVector &) const
Definition: ObsVector.cc:138
void putObsVector(const std::string &, const std::vector< double > &) const
Definition: ObsSpace.cc:52
void print(std::ostream &) const
Definition: ObsVector.cc:185
#define max(a, b)
Definition: mosaic_util.h:33
#define min(a, b)
Definition: mosaic_util.h:32
ObsVector & operator/=(const ObsVector &)
Definition: ObsVector.cc:91
const double missing_value
Definition: constants.h:12
double rms() const
Definition: ObsVector.cc:151