Loading [MathJax]/extensions/tex2jax.js
PISM, A Parallel Ice Sheet Model 2.2.2-d6b3a29ca committed by Constantine Khrulev on 2025-03-28
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
VariableMetadata.hh
Go to the documentation of this file.
1// Copyright (C) 2009--2018, 2020, 2021, 2022, 2023, 2024, 2024 Constantine Khroulev
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#ifndef PISM_VARIABLEMETADATA_H
20#define PISM_VARIABLEMETADATA_H
21
22#include <set>
23#include <map>
24#include <vector>
25#include <string>
26
27#include "pism/util/Units.hh"
28
29namespace pism {
30namespace io {
31enum Type : int;
32}
33
34class Logger;
35
36//! @brief A class for handling variable metadata, reading, writing and converting
37//! from input units and to output units.
38/*! A NetCDF variable can have any number of attributes, but some of them get
39 special treatment:
40
41 - units: specifies internal units. When read, a variable is
42 converted to these units. When written, it is converted from these
43 to output_units.
44
45 - output_units: is never written to a file; replaces 'units'
46 in the output file.
47
48 - valid_min, valid_max: specify the valid range of a variable. Are
49 read from an input file *only* if not specified previously. If
50 both are set, then valid_range is used in the output instead.
51
52 Also:
53
54 - empty string attributes are ignored (they are not written to the
55 output file and has_attribute("foo") returns false if "foo" is
56 absent or equal to an empty string).
57
58 Typical attributes stored here:
59
60 - long_name
61 - standard_name
62 - units
63 - output_units (saved to files as "units")
64
65 Use the `name` of "PISM_GLOBAL" to read and write global attributes.
66 (See also File.)
67
68*/
69
70class VariableMetadata;
71
73public:
74 friend class VariableMetadata;
77
78 operator std::string() const;
79 operator double() const;
80 operator std::vector<double> () const;
81protected:
82 ConstAttribute(const VariableMetadata *var, const std::string &name);
83 ConstAttribute(ConstAttribute&& a) noexcept;
84
85 std::string m_name;
87};
88
89class Attribute : public ConstAttribute {
90public:
91 friend class VariableMetadata;
92 void operator=(const std::string &value);
93 void operator=(const std::initializer_list<double> &value);
94 void operator=(const std::vector<double> &value);
95private:
97};
98
100public:
101 VariableMetadata(const std::string &name, units::System::Ptr system, unsigned int ndims = 0);
102 virtual ~VariableMetadata() = default;
103
104 Attribute operator[](const std::string &name) {
105 return Attribute(this, name);
106 }
107
108 ConstAttribute operator[](const std::string &name) const {
109 return ConstAttribute(this, name);
110 }
111
112 // setters for common attributes
113
114 VariableMetadata &long_name(const std::string &input) {
115 return set_string("long_name", input);
116 }
117
118 VariableMetadata &standard_name(const std::string &input) {
119 return set_string("standard_name", input);
120 }
121
122 VariableMetadata &units(const std::string &input) {
123 return set_string("units", input);
124 }
125
126 VariableMetadata &output_units(const std::string &input) {
127 return set_string("output_units", input);
128 }
129
130 // getters and setters
131 double get_number(const std::string &name) const;
132 VariableMetadata &set_number(const std::string &name, double value);
133
134 std::vector<double> get_numbers(const std::string &name) const;
135 VariableMetadata &set_numbers(const std::string &name, const std::vector<double> &values);
136
137 std::string get_name() const;
138 VariableMetadata &set_name(const std::string &name);
139
140 std::string get_string(const std::string &name) const;
141 VariableMetadata &set_string(const std::string &name, const std::string &value);
142 VariableMetadata &set_units_without_validation(const std::string &value);
143
144 bool get_time_independent() const;
146
149
150 //! Clear all attributes
152
153 // more getters
155
156 unsigned int n_spatial_dimensions() const;
157
158 bool has_attribute(const std::string &name) const;
159 bool has_attributes() const;
160
161 const std::map<std::string, std::string> &all_strings() const;
162 const std::map<std::string, std::vector<double> > &all_doubles() const;
163
164 void report_to_stdout(const Logger &log, int verbosity_threshold) const;
165 void check_range(const std::string &filename, double min, double max) const;
166 void report_range(const Logger &log, double min, double max) const;
167
168protected:
169 unsigned int m_n_spatial_dims;
170
171private:
172 //! @brief The unit system to use.
174
175 //! string and boolean attributes
176 std::map<std::string, std::string> m_strings;
177
178 //! scalar and array attributes
179 std::map<std::string, std::vector<double> > m_doubles;
180 std::string m_short_name;
182
184};
185
186//! Spatial NetCDF variable (corresponding to a 2D or 3D scalar field).
188public:
189 SpatialVariableMetadata(units::System::Ptr system, const std::string &name,
190 const std::vector<double> &zlevels = {0.0});
191 virtual ~SpatialVariableMetadata() = default;
192
193 const std::vector<double>& levels() const;
194
198
199 const VariableMetadata& x() const;
200 const VariableMetadata& y() const;
201 const VariableMetadata& z() const;
202
203private:
205 std::vector<double> m_zlevels;
206};
207
208} // end of namespace pism
209
210#endif // PISM_VARIABLEMETADATA_H
void operator=(const std::string &value)
ConstAttribute(const ConstAttribute &)=delete
VariableMetadata * m_var
ConstAttribute & operator=(const ConstAttribute &)=delete
A basic logging class.
Definition Logger.hh:40
std::vector< double > m_zlevels
const std::vector< double > & levels() const
virtual ~SpatialVariableMetadata()=default
Spatial NetCDF variable (corresponding to a 2D or 3D scalar field).
VariableMetadata & clear()
Clear all attributes.
Attribute operator[](const std::string &name)
void report_to_stdout(const Logger &log, int verbosity_threshold) const
ConstAttribute operator[](const std::string &name) const
VariableMetadata & long_name(const std::string &input)
VariableMetadata & units(const std::string &input)
VariableMetadata & set_name(const std::string &name)
VariableMetadata & standard_name(const std::string &input)
unsigned int n_spatial_dimensions() const
VariableMetadata & set_number(const std::string &name, double value)
Set a scalar attribute to a single (scalar) value.
units::System::Ptr m_unit_system
The unit system to use.
double get_number(const std::string &name) const
Get a single-valued scalar attribute.
std::string get_string(const std::string &name) const
Get a string attribute.
virtual ~VariableMetadata()=default
const std::map< std::string, std::string > & all_strings() const
void report_range(const Logger &log, double min, double max) const
Report the range of a global Vec v.
std::map< std::string, std::string > m_strings
string and boolean attributes
VariableMetadata & output_units(const std::string &input)
units::System::Ptr unit_system() const
io::Type get_output_type() const
std::map< std::string, std::vector< double > > m_doubles
scalar and array attributes
bool get_time_independent() const
VariableMetadata & set_units_without_validation(const std::string &value)
std::vector< double > get_numbers(const std::string &name) const
Get an array-of-doubles attribute.
VariableMetadata & set_output_type(io::Type type)
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
VariableMetadata & set_string(const std::string &name, const std::string &value)
Set a string attribute.
void check_range(const std::string &filename, double min, double max) const
Check if the range [min, max] is a subset of [valid_min, valid_max].
const std::map< std::string, std::vector< double > > & all_doubles() const
VariableMetadata & set_time_independent(bool flag)
std::shared_ptr< System > Ptr
Definition Units.hh:47