OOPS
oops/base/Variables.cc
Go to the documentation of this file.
1 /*
2  * (C) Copyright 2017-2018 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 "oops/base/Variables.h"
9 
10 #include <algorithm>
11 #include <iostream>
12 #include <set>
13 #include <string>
14 #include <vector>
15 
16 #include "eckit/config/Configuration.h"
17 #include "eckit/exception/Exceptions.h"
18 #include "eckit/types/Types.h"
19 
20 #include "oops/util/IntSetParser.h"
21 #include "oops/util/Logger.h"
22 
23 // -----------------------------------------------------------------------------
24 namespace oops {
25 // -----------------------------------------------------------------------------
26 
28  : convention_(""), vars_(0) {
29  Log::trace() << "Variables::Variables" << std::endl;
30 }
31 
32 // -----------------------------------------------------------------------------
33 
34 Variables::Variables(const eckit::Configuration & conf, const std::string & name)
35  : convention_(""), vars_(0), channels_(0) {
36  Log::trace() << "Variables::Variables start " << conf << std::endl;
37  std::vector<std::string> vars;
38  conf.get(name, vars);
39  if (vars.size() == 0) {
40  Log::error() << name << " not found in " << conf << std::endl;
41  throw eckit::BadParameter("Undefined variable: '" + name + "'");
42  }
43  // hack to read channels
44  if (conf.has("channels")) {
45  std::string chlist = conf.getString("channels");
46  std::set<int> channels = parseIntSet(chlist);
47  std::copy(channels.begin(), channels.end(), std::back_inserter(channels_));
48  // assuming the same channel subsetting applies to all variables
49  for (size_t jvar = 0; jvar < vars.size(); ++jvar) {
50  for (size_t jch = 0; jch < channels_.size(); ++jch) {
51  vars_.push_back(vars[jvar]+"_"+std::to_string(channels_[jch]));
52  }
53  }
54  } else {
55  vars_ = vars;
56  }
57  Log::trace() << "Variables::Variables done" << std::endl;
58 }
59 
60 // -----------------------------------------------------------------------------
61 
62 Variables::Variables(const std::vector<std::string> & vars, const std::string & conv)
63  : convention_(conv), vars_(vars) {
64  Log::trace() << "Variables::Variables start " << vars << std::endl;
65  Log::trace() << "Variables::Variables done" << std::endl;
66 }
67 
68 // -----------------------------------------------------------------------------
69 
70 Variables::Variables(const std::vector<std::string> & vars, const std::vector<int> channels)
71  : convention_(""), vars_(0), channels_(channels) {
72  Log::trace() << "Variables::Variables start " << vars << " @ " << channels << std::endl;
73  for (size_t jvar = 0; jvar < vars.size(); ++jvar) {
74  for (size_t jch = 0; jch < channels_.size(); ++jch) {
75  vars_.push_back(vars[jvar]+"_"+std::to_string(channels_[jch]));
76  }
77  }
78  Log::trace() << "Variables::Variables done" << std::endl;
79 }
80 
81 // -----------------------------------------------------------------------------
82 
84  : convention_(other.convention_), vars_(other.vars_), channels_(other.channels_)
85 {}
86 
87 // -----------------------------------------------------------------------------
88 
90  ASSERT(convention_ == rhs.convention_);
91  vars_.insert(vars_.end(), rhs.vars_.begin(), rhs.vars_.end());
92  // revisit late, should we add channels this way ?
93  channels_.insert(channels_.end(), rhs.channels_.begin(), rhs.channels_.end());
94  // remove duplicated variables and channels
95  std::sort(vars_.begin(), vars_.end());
96  vars_.erase(std::unique(vars_.begin(), vars_.end() ), vars_.end());
97  std::sort(channels_.begin(), channels_.end());
98  channels_.erase(std::unique(channels_.begin(), channels_.end() ), channels_.end());
99  return *this;
100 }
101 
102 // -----------------------------------------------------------------------------
103 
104 bool Variables::operator==(const Variables & rhs) const {
105  return convention_ == rhs.convention_
106  && vars_ == rhs.vars_
107  && channels_ == rhs.channels_;
108 }
109 
110 // -----------------------------------------------------------------------------
111 
112 bool Variables::operator<=(const Variables & rhs) const {
113  ASSERT(convention_ == rhs.convention_);
114  ASSERT(channels_.empty());
115  bool is_in_rhs = true;
116  for (size_t jj = 0; jj < vars_.size(); ++jj) {
117  is_in_rhs = is_in_rhs && rhs.has(vars_[jj]);
118  }
119  return is_in_rhs;
120 }
121 
122 // -----------------------------------------------------------------------------
123 
124 bool Variables::has(const std::string & var) const {
125  bool found = false;
126  for (size_t jj = 0; jj < vars_.size(); ++jj) {
127  found = found || vars_[jj] == var;
128  }
129  return found;
130 }
131 
132 // -----------------------------------------------------------------------------
133 
134 size_t Variables::find(const std::string & var) const {
135  size_t ii = vars_.size();
136  for (size_t jj = 0; jj < vars_.size(); ++jj) {
137  if (vars_[jj] == var) ii = jj;
138  }
139  ASSERT(ii < vars_.size());
140  return ii;
141 }
142 
143 // -----------------------------------------------------------------------------
144 
145 void Variables::push_back(const std::string & vname) {
146  vars_.push_back(vname);
147 }
148 
149 // -----------------------------------------------------------------------------
150 
152 
153 // -----------------------------------------------------------------------------
154 
155 void Variables::print(std::ostream & os) const {
156  os << vars_.size() << " variables: ";
157  for (size_t jj = 0; jj < vars_.size(); ++jj) {
158  if (jj > 0) os << ", ";
159  os << vars_[jj];
160  }
161  if (!convention_.empty()) os << " (" << convention_ << ")";
162 }
163 
164 // -----------------------------------------------------------------------------
165 
166 } // namespace oops
oops
The namespace for the main oops code.
Definition: ErrorCovarianceL95.cc:22
oops::Variables::channels_
std::vector< int > channels_
Definition: oops/base/Variables.h:55
oops::Variables::~Variables
~Variables()
Definition: oops/base/Variables.cc:151
oops::Variables::operator+=
Variables & operator+=(const Variables &)
Definition: oops/base/Variables.cc:89
oops::Variables::has
bool has(const std::string &) const
Definition: oops/base/Variables.cc:124
oops::Variables::Variables
Variables()
Definition: oops/base/Variables.cc:27
oops::Variables::print
void print(std::ostream &) const
Definition: oops/base/Variables.cc:155
oops::Variables::operator==
bool operator==(const Variables &) const
Definition: oops/base/Variables.cc:104
oops::Variables::find
size_t find(const std::string &) const
Definition: oops/base/Variables.cc:134
oops::Variables::operator<=
bool operator<=(const Variables &) const
Definition: oops/base/Variables.cc:112
oops::Variables::vars_
std::vector< std::string > vars_
Definition: oops/base/Variables.h:54
oops::Variables::convention_
std::string convention_
Definition: oops/base/Variables.h:53
oops::Variables::push_back
void push_back(const std::string &)
Definition: oops/base/Variables.cc:145
oops::Variables::channels
const std::vector< int > & channels() const
Definition: oops/base/Variables.h:46
oops::Variables
Definition: oops/base/Variables.h:23
compare.error
int error
Definition: compare.py:168
Variables.h