PISM, A Parallel Ice Sheet Model  stable v2.1-1-g6902d5502 committed by Ed Bueler on 2023-12-20 08:38:27 -0800
Config.cc
Go to the documentation of this file.
1 /* Copyright (C) 2014, 2015, 2016, 2017, 2019, 2021, 2023 PISM Authors
2  *
3  * This file is part of PISM.
4  *
5  * PISM is free software; you can redistribute it and/or modify it under the
6  * terms of the GNU General Public License as published by the Free Software
7  * Foundation; either version 3 of the License, or (at your option) any later
8  * version.
9  *
10  * PISM is distributed in the hope that it will be useful, but WITHOUT ANY
11  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13  * details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with PISM; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18  */
19 
20 #include "pism/util/Config.hh"
21 #include "pism/util/io/File.hh"
22 #include "pism/util/pism_options.hh"
23 #include "pism/util/error_handling.hh"
24 #include "pism/util/io/io_helpers.hh"
25 #include "pism/util/Logger.hh"
26 #include "pism/pism_config.hh" // pism::config_file
27 #include "pism/util/io/IO_Flags.hh"
28 
29 namespace pism {
30 
31 NetCDFConfig::NetCDFConfig(MPI_Comm com, const std::string &name, units::System::Ptr system)
32  : Config(system),
33  m_com(com),
34  m_data(name, system) {
35 }
36 
38 }
39 
40 bool NetCDFConfig::is_set_impl(const std::string &name) const {
41  return m_data.has_attribute(name);
42 }
43 
44 // doubles
45 
46 double NetCDFConfig::get_number_impl(const std::string &name) const {
47  const auto &doubles = m_data.all_doubles();
48  if (doubles.find(name) != doubles.end()) {
49  return m_data.get_number(name);
50  }
51 
53  "parameter '%s' is unset. (Parameters read from '%s'.)",
54  name.c_str(), m_config_filename.c_str());
55 
56  return 0; // can't happen
57 }
58 
59 std::vector<double> NetCDFConfig::get_numbers_impl(const std::string &name) const {
60  const auto& doubles = m_data.all_doubles();
61  if (doubles.find(name) != doubles.end()) {
62  return m_data.get_numbers(name);
63  }
64 
66  "parameter '%s' is unset. (Parameters read from '%s'.)",
67  name.c_str(), m_config_filename.c_str());
68 
69  return {}; // can't happen
70 }
71 
73  Doubles result;
74 
75  for (const auto& d : m_data.all_doubles()) {
76  result[d.first] = d.second;
77  }
78  return result;
79 }
80 
81 
82 void NetCDFConfig::set_number_impl(const std::string &name, double value) {
83  m_data.set_number(name, value);
84 }
85 
86 void NetCDFConfig::set_numbers_impl(const std::string &name,
87  const std::vector<double> &values) {
88  m_data.set_numbers(name, values);
89 }
90 
91 // strings
92 
93 std::string NetCDFConfig::get_string_impl(const std::string &name) const {
94  const auto& strings = m_data.all_strings();
95  if (strings.find(name) != strings.end()) {
96  return m_data[name];
97  }
98 
100  "Parameter '%s' was not set. (Read from '%s'.)\n", name.c_str(),
101  m_config_filename.c_str());
102 
103  return std::string(); // will never happen
104 }
105 
107  auto strings = m_data.all_strings();
108  Strings result;
109 
110  for (const auto& s : strings) {
111  std::string name = s.first;
112  std::string value = s.second;
113 
114  auto k = strings.find(name + "_type");
115  if (k != strings.end() and k->second == "flag") {
116  // Flags are stored as strings. Skip them.
117  continue;
118  }
119 
120  result[name] = value;
121  }
122  return result;
123 }
124 
125 void NetCDFConfig::set_string_impl(const std::string &name, const std::string &value) {
126  m_data[name] = value;
127 }
128 
129 // flags
130 
131 static bool string_is_false(const std::string &value) {
132  return value == "false" or value == "off" or value == "no";
133 }
134 
135 static bool string_is_true(const std::string &value) {
136  return value == "true" or value == "on" or value == "yes";
137 }
138 
139 bool NetCDFConfig::get_flag_impl(const std::string &name) const {
140  const auto &strings = m_data.all_strings();
141  auto j = strings.find(name);
142  if (j != strings.end()) {
143 
144  const std::string &value = j->second;
145 
146  if (string_is_false(value)) {
147  return false;
148  }
149 
150  if (string_is_true(value)) {
151  return true;
152  }
153 
154  throw RuntimeError::formatted(PISM_ERROR_LOCATION, "Parameter '%s' (%s) cannot be interpreted as a flag.\n"
155  "Please make sure that it is set to one of 'true', 'yes', 'on', 'false', 'no', 'off'.",
156  name.c_str(), value.c_str());
157  }
158 
159  throw RuntimeError::formatted(PISM_ERROR_LOCATION, "Parameter '%s' was not set. (Read from '%s'.)",
160  name.c_str(), m_config_filename.c_str());
161 
162  return true; // will never happen
163 }
164 
166  Flags result;
167 
168  for (const auto& b : m_data.all_strings()) {
169  std::string name = b.first;
170  std::string value = b.second;
171 
172  if (string_is_true(value)) {
173  result[name] = true;
174  } else if (string_is_false(value)) {
175  result[name] = false;
176  }
177  }
178  return result;
179 }
180 
181 //! Set a value of a flag flag.
182 void NetCDFConfig::set_flag_impl(const std::string &name, bool value) {
183  m_data[name] = value ? "true" : "false";
184 }
185 
186 // file I/O
187 
188 //! Read flag flags and double parameters from a NetCDF file.
189 /*!
190  Erases all the present parameters before reading.
191 */
192 void NetCDFConfig::read_impl(const File &nc) {
193 
195 
197 }
198 
199 //! Write a config variable to a file (with all its attributes).
200 void NetCDFConfig::write_impl(const File &nc) const {
201 
202  bool variable_exists = nc.find_variable(m_data.get_name());
203 
204  if (not variable_exists) {
206 
208  } else {
210  }
211 }
212 
213 
214 //! Config that respects command-line options and stores data in a NetCDF variable.
216  const std::string &variable_name,
217  const std::string &option,
218  units::System::Ptr system)
219  : NetCDFConfig(com, variable_name, system),
220  m_option(option) {
221  // empty
222 }
223 
224 void DefaultConfig::init(const Logger &log, bool use_default_path) {
226  "Name of the file to read " + m_data.get_name() + " from",
227  pism::config_file);
228  if (use_default_path or file.is_set()) {
229  this->read(m_com, file);
230  log.message(2, "Reading configuration parameters (%s) from file '%s'.\n",
231  m_data.get_name().c_str(), file->c_str());
232  }
233 }
234 
236  this->init(log, true);
237 }
238 
239 void DefaultConfig::init(const Logger &log) {
240  this->init(log, false);
241 }
242 
243 } // end of namespace pism
std::map< std::string, std::string > Strings
std::map< std::string, std::vector< double > > Doubles
void read(MPI_Comm com, const std::string &filename)
std::map< std::string, bool > Flags
A class for storing and accessing PISM configuration flags and parameters.
DefaultConfig(MPI_Comm com, const std::string &variable_name, const std::string &option, units::System::Ptr unit_system)
Config that respects command-line options and stores data in a NetCDF variable.
Definition: Config.cc:215
void init_with_default(const Logger &log)
Initialize (use default path if no option was set).
Definition: Config.cc:235
std::string m_option
Definition: Config.hh:89
void init(const Logger &log)
Initialize (leave empty if no option was set).
Definition: Config.cc:239
VariableLookupData find_variable(const std::string &short_name, const std::string &std_name) const
Find a variable using its standard name and/or short name.
Definition: File.cc:361
std::string filename() const
Definition: File.cc:307
void define_variable(const std::string &name, io::Type nctype, const std::vector< std::string > &dims) const
Define a variable.
Definition: File.cc:573
High-level PISM I/O class.
Definition: File.hh:56
void message(int threshold, const char format[],...) const __attribute__((format(printf
Print a message to the log.
Definition: Logger.cc:49
A basic logging class.
Definition: Logger.hh:40
bool get_flag_impl(const std::string &name) const
Definition: Config.cc:139
void set_numbers_impl(const std::string &name, const std::vector< double > &values)
Definition: Config.cc:86
bool is_set_impl(const std::string &name) const
Definition: Config.cc:40
VariableMetadata m_data
Definition: Config.hh:64
MPI_Comm m_com
Definition: Config.hh:63
Doubles all_doubles_impl() const
Definition: Config.cc:72
void set_number_impl(const std::string &name, double value)
Definition: Config.cc:82
NetCDFConfig(MPI_Comm com, const std::string &name, units::System::Ptr unit_system)
Definition: Config.cc:31
void set_flag_impl(const std::string &name, bool value)
Set a value of a flag flag.
Definition: Config.cc:182
std::string get_string_impl(const std::string &name) const
Definition: Config.cc:93
double get_number_impl(const std::string &name) const
Definition: Config.cc:46
void write_impl(const File &nc) const
Write a config variable to a file (with all its attributes).
Definition: Config.cc:200
void set_string_impl(const std::string &name, const std::string &value)
Definition: Config.cc:125
Strings all_strings_impl() const
Definition: Config.cc:106
Flags all_flags_impl() const
Definition: Config.cc:165
std::vector< double > get_numbers_impl(const std::string &name) const
Definition: Config.cc:59
std::string m_config_filename
the name of the file this config database was initialized from
Definition: Config.hh:67
void read_impl(const File &nc)
Read flag flags and double parameters from a NetCDF file.
Definition: Config.cc:192
A class for reading, writing and accessing PISM configuration flags and parameters.
Definition: Config.hh:34
static RuntimeError formatted(const ErrorLocation &location, const char format[],...) __attribute__((format(printf
build a RuntimeError with a formatted message
VariableMetadata & set_number(const std::string &name, double value)
Set a scalar attribute to a single (scalar) value.
double get_number(const std::string &name) const
Get a single-valued scalar attribute.
const std::map< std::string, std::string > & all_strings() const
std::vector< double > get_numbers(const std::string &name) const
Get an array-of-doubles attribute.
bool has_attribute(const std::string &name) const
VariableMetadata & set_numbers(const std::string &name, const std::vector< double > &values)
Set a scalar attribute to a single (scalar) value.
std::string get_name() const
const std::map< std::string, std::vector< double > > & all_doubles() const
bool is_set() const
Definition: options.hh:35
std::shared_ptr< System > Ptr
Definition: Units.hh:47
#define PISM_ERROR_LOCATION
void write_attributes(const File &file, const VariableMetadata &variable, io::Type nctype)
Write variable attributes to a NetCDF file.
Definition: io_helpers.cc:1200
@ PISM_DOUBLE
Definition: IO_Flags.hh:52
@ PISM_BYTE
Definition: IO_Flags.hh:47
void read_attributes(const File &file, const std::string &variable_name, VariableMetadata &variable)
Definition: io_helpers.cc:1162
static bool string_is_false(const std::string &value)
Definition: Config.cc:131
static const double k
Definition: exactTestP.cc:42
static bool string_is_true(const std::string &value)
Definition: Config.cc:135