27#include "pism/util/VariableMetadata.hh"
29#include "pism/util/Logger.hh"
30#include "pism/util/error_handling.hh"
31#include "pism/util/io/File.hh"
32#include "pism/util/io/IO_Flags.hh"
39 : m_n_spatial_dims(ndims),
41 m_time_dependent(false),
44 m_attributes.unit_system = std::move(system);
54VariableMetadata::VariableMetadata(
const std::string &name,
55 const std::vector<std::tuple<std::string, int> > &dimensions,
56 std::shared_ptr<units::System> system)
65 const Grid &grid,
const std::vector<double> &levels)
75 {
"x", system, (
int)grid.Mx(),
true}};
79 x[
"long_name"] =
"X-coordinate in Cartesian system";
80 x[
"standard_name"] =
"projection_x_coordinate";
82 x[
"spacing_meters"] = { grid.dx() };
86 y[
"long_name"] =
"Y-coordinate in Cartesian system";
87 y[
"standard_name"] =
"projection_y_coordinate";
89 y[
"spacing_meters"] = { grid.dy() };
96 z[
"long_name"] =
"Z-coordinate in Cartesian system";
101 auto nlevels = z.length();
103 double dz_max = nlevels > 1 ?
levels[1] -
levels[0] : 0.0;
106 for (
int k = 0;
k < nlevels - 1; ++
k) {
108 dz_max = std::max(dz_max, dz);
109 dz_min = std::min(dz_min, dz);
112 z[
"spacing_min_meters"] = { dz_min };
113 z[
"spacing_max_meters"] = { dz_max };
132 std::vector<std::string> result;
134 result.emplace_back(dim.get_name());
149 if (dim.get_name() == name) {
202 const char *
units = units_string.c_str(), *name = name_string.c_str(), *file = filename.c_str();
208 if ((min < valid_min - eps) or (max > valid_max + eps)) {
211 "some values of '%s' in '%s' are outside the valid range [%e, %e] (%s).\n"
212 "computed min = %e %s, computed max = %e %s",
213 name, file, valid_min, valid_max, units, min, units, max, units);
217 if (min < valid_min - eps) {
220 "some values of '%s' in '%s' are less than the valid minimum (%e %s).\n"
221 "computed min = %e %s, computed max = %e %s",
222 name, file, valid_min, units, min, units, max, units);
226 if (max > valid_max + eps) {
229 "some values of '%s' in '%s' are greater than the valid maximum (%e %s).\n"
230 "computed min = %e %s, computed max = %e %s",
231 name, file, valid_max, units, min, units, max, units);
237 int length,
bool coordinate_variable)
238 :
VariableMetadata(name, system), m_length(length), m_coordinate_variable(coordinate_variable) {
263 std::string spacer(name.size(),
' ');
269 range =
pism::printf(
"constant %9.3f %s", min, units.c_str());
271 range =
pism::printf(
"min = %9.3f, max = %9.3f %s", min, max, units.c_str());
277 name.c_str(), info.c_str(), spacer.c_str(), range.c_str());
283 if (name !=
"units" and (j->second).empty()) {
337 return (j->second)[0];
341 "variable \"%s\" does not have a double attribute \"%s\"",
382 if (name ==
"units") {
388 }
else if (name ==
"output_units") {
391 if (not value.empty()) {
397 "units \"%s\" and \"%s\" are not compatible",
401 }
else if (name ==
"short_name") {
415 if (name ==
"short_name") {
433 size_t max_name_length = 0;
434 for (
const auto &s : strings) {
435 max_name_length = std::max(max_name_length, s.first.size());
437 for (
const auto &d : doubles) {
438 max_name_length = std::max(max_name_length, d.first.size());
442 for (
const auto &s : strings) {
443 std::string name = s.first;
444 std::string value = s.second;
445 std::string padding(max_name_length - name.size(),
' ');
451 log.
message(verbosity_threshold,
" %s%s = \"%s\"\n",
452 name.c_str(), padding.c_str(), value.c_str());
456 for (
const auto &d : doubles) {
457 std::string name = d.first;
458 std::vector<double> values = d.second;
459 std::string padding(max_name_length - name.size(),
' ');
461 if (values.empty()) {
465 const double large = 1.0e7;
466 const double small = 1.0e-4;
467 if ((std::fabs(values[0]) >= large) || (std::fabs(values[0]) <= small)) {
469 log.
message(verbosity_threshold,
" %s%s = %12.3e\n",
470 name.c_str(), padding.c_str(), values[0]);
472 log.
message(verbosity_threshold,
" %s%s = %12.5f\n",
473 name.c_str(), padding.c_str(), values[0]);
484 : m_name(std::move(a.m_name)), m_var(a.m_var) {
489ConstAttribute::operator std::string()
const {
490 return m_var->get_string(m_name);
494 auto values = m_var->get_numbers(m_name);
495 if (values.size() == 1) {
499 "%s:%s has more than one value",
500 m_var->get_name().c_str(), m_name.c_str());
503ConstAttribute::operator std::vector<double> ()
const {
504 return m_var->get_numbers(m_name);
void operator=(const std::string &value)
ConstAttribute(const ConstAttribute &)=delete
Describes the PISM grid and the distribution of data across processors.
void message(int threshold, const char format[],...) const __attribute__((format(printf
Print a message to the log.
static RuntimeError formatted(const ErrorLocation &location, const char format[],...) __attribute__((format(printf
build a RuntimeError with a formatted message
std::shared_ptr< units::System > unit_system
The unit system to use.
bool is_set(const std::string &name) const
std::map< std::string, std::string > strings
string and boolean attributes
std::map< std::string, std::vector< double > > numbers
scalar and array attributes
std::shared_ptr< System > Ptr
#define PISM_ERROR_LOCATION
bool are_convertible(const Unit &u1, const Unit &u2)
std::string printf(const char *format,...)