TECA
The Toolkit for Extreme Climate Analysis
teca_cartesian_mesh_source.h
1 #ifndef teca_cartesian_mesh_source_h
2 #define teca_cartesian_mesh_source_h
3 
4 #include "teca_config.h"
5 #include "teca_algorithm.h"
6 #include "teca_metadata.h"
7 
8 #include <functional>
9 #include <map>
10 #include <utility>
11 
12 TECA_SHARED_OBJECT_FORWARD_DECL(teca_cartesian_mesh_source)
13 
14 /** The signature of the callback used to specify user defined fields.
15  * f(x, y, z, t) -> w
16  * Given spatial coordinate axes x,y,z and the time t, return the
17  * 3D field w.
18  */
19 using field_generator_callback = std::function<p_teca_variant_array(
21  const const_p_teca_variant_array &, double)>;
22 
23 /** An object that bundles field name, the metadata attributes needed for I/O,
24  * and a field generator callback. Use this with append_field_generator
25  */
27 {
28  std::string name;
29  teca_metadata attributes;
30  field_generator_callback generator;
31 };
32 
34 
35 inline
36 bool operator==(const field_generator &l, const field_generator &r)
37 {
38  return l.name == r.name;
39 }
40 
41 inline
42 bool operator!=(const field_generator &l, const field_generator &r)
43 {
44  return l.name != r.name;
45 }
46 
47 /** @brief
48  * An algorithm that generates a teca_cartesian_mesh of the requested
49  * spatial and temporal dimensions with optional user defined fields.
50  *
51  * @details
52  * User defined fields are specified by passing callbacks and metadata
53  * via field_generator and append_field_generator
54  *
55  * The spatial and temporal dimensions are set by the combination of
56  * whole_extent and bounds.
57  *
58  * The names of coordinate axes are set by the combination
59  * of x_axis_variable, y_axis_variable, z_axis_variable,
60  * and t_axis_variable
61  *
62  * The units of the coordinate axes are set by the combination of
63  * x_axis_units, y_axis_units, z_axis_units, calendar,
64  * and time_units.
65  */
67 {
68 public:
69  TECA_ALGORITHM_STATIC_NEW(teca_cartesian_mesh_source)
70  TECA_ALGORITHM_DELETE_COPY_ASSIGN(teca_cartesian_mesh_source)
71  TECA_ALGORITHM_CLASS_NAME(teca_cartesian_mesh_source)
73 
74  // report/initialize to/from Boost program options
75  // objects.
76  TECA_GET_ALGORITHM_PROPERTIES_DESCRIPTION()
77  TECA_SET_ALGORITHM_PROPERTIES()
78 
79  /** @name coordinate_type_code
80  * set/get the type code for generated coordinates. The default is a 64 bit
81  * floating point type. Use teca_variant_array_code<NT>::get() to get
82  * specific type codes for C++ POD types NT.
83  */
84  ///@{
85  TECA_ALGORITHM_PROPERTY(unsigned int, coordinate_type_code)
86  ///@}
87 
88  /** @name field_type_code
89  * set/get the type code for generated fields. The default is a 64 bit
90  * floating point type. Use teca_variant_array_code<NT>::get() to get
91  * specific type codes for C++ POD types NT.
92  */
93  ///@{
94  TECA_ALGORITHM_PROPERTY(unsigned int, field_type_code)
95  ///@}
96 
97  /** @name whole_extent
98  * set/get the global index space extent of the data. the extents are
99  * given by 8 values, 6 spatial plus 2 temporal, in the following order
100  * [i0 i1 j0 j1 k0 k1 q0 q1] This should be the same on all ranks
101  */
102  ///@{
103  TECA_ALGORITHM_VECTOR_PROPERTY(unsigned long, whole_extent)
104 
105  /** Set the spatial extents from a metadata object following the
106  * conventions defined by the teca_cf_reader. If three_d is true the
107  * extents in the z-direction are copied, otherwise they are set to 0.
108  * Returns zero if successful and non-zero if the supplied metadata is
109  * missing any of the requisite information.
110  **/
111  int set_spatial_extents(const teca_metadata &md, bool three_d = true);
112  ///@}
113 
114  /** @name bounds
115  * set/get the global bounds of the data. the bounds are 8 values 6 spatial
116  * plus 2 temporal in the following order. [x0 x1 y0 y1 z0 z1 t0 t1]
117  * this should be the same on all ranks.
118  */
119  ///@{
120  TECA_ALGORITHM_VECTOR_PROPERTY(double, bound)
121 
122  /** Set the spatial bounds from a metadata object following the conventions
123  * defined by the teca_cf_reader. Returns zero if successful and
124  * non-zero if the supplied metadata is missing any of the requisite
125  * information.
126  */
127  int set_spatial_bounds(const teca_metadata &md, bool three_d = true);
128 
129  ///@}
130 
131  /** @name x_axis_variable
132  * set the name of the variable to use for the coordinate axes and
133  * optionally associated attributes.
134  */
135  ///@{
136  /** set the name of the t_axis_variable */
137  void set_x_axis_variable(const std::string &name);
138 
139  /** Set the name of the variable and its attributes. See
140  * teca_array_attributes for more information.
141  */
142  void set_x_axis_variable(const std::string &name, const teca_metadata &atts);
143 
144  /** Set the name of the variable and its attributes using conventions
145  * defined by the teca_cf_reader. Returns zero if successful and
146  * non-zero if the supplied metadata is missing any of the requisite
147  * information.
148  */
149  int set_x_axis_variable(const teca_metadata &md);
150  ///@}
151 
152  /** @name y_axis_variable
153  * set the name of the variable to use for the coordinate axes and
154  * optionally associated attributes.
155  */
156  ///@{
157  /** set the name of the y_axis_variable */
158  void set_y_axis_variable(const std::string &name);
159 
160  /** Set the name of the variable and its attributes. See
161  * teca_array_attributes for more information.
162  */
163  void set_y_axis_variable(const std::string &name, const teca_metadata &atts);
164 
165  /** Set the name of the variable and its attributes using conventions
166  * defined by the teca_cf_reader. Returns zero if successful and
167  * non-zero if the supplied metadata is missing any of the requisite
168  * information.
169  */
170  int set_y_axis_variable(const teca_metadata &md);
171  ///@}
172 
173  /** @name z_axis_variable
174  * set the name of the variable to use for the coordinate axes and
175  * optionally associated attributes.
176  */
177  ///@{
178  /** set the name of the z_axis_variable */
179  void set_z_axis_variable(const std::string &name);
180 
181  /** Set the name of the variable and its attributes. See
182  * teca_array_attributes for more information.
183  */
184  void set_z_axis_variable(const std::string &name, const teca_metadata &atts);
185 
186  /** Set the name of the variable and its attributes using conventions
187  * defined by the teca_cf_reader. Returns zero if successful and
188  * non-zero if the supplied metadata is missing any of the requisite
189  * information.
190  */
191  int set_z_axis_variable(const teca_metadata &md);
192  ///@}
193 
194  /** @name t_axis_variable
195  * set the name of the variable to use for the coordinate axes and
196  * optionally associated attributes.
197  */
198  ///@{
199  /** set the name of the t_axis_variable */
200  void set_t_axis_variable(const std::string &name);
201 
202  /** Set the calendar, and time units of the t_axis_variable */
203  void set_calendar(const std::string &calendar, const std::string &units);
204 
205  /** Set the name of the variable and its attributes. See
206  * teca_array_attributes for more information.
207  */
208  void set_t_axis_variable(const std::string &name,
209  const teca_metadata &atts);
210 
211  /** Set the name of the variable and its attributes using conventions
212  * defined by the teca_cf_reader. Returns zero if successful and
213  * non-zero if the supplied metadata is missing any of the requisite
214  * information.
215  */
216  int set_t_axis_variable(const teca_metadata &md);
217 
218  /** Set the time axis using coordinate conventions defined by the
219  * teca_cf_reader. When a time axis is provided values are served up from
220  * the array rather than being generated. Execution control keys are also
221  * made use of if present. Returns zero if successful and non-zero if the
222  * supplied metadata is missing any of the requisite information.
223  */
224  int set_t_axis(const teca_metadata &md);
225 
226  /** Set the time axis directly. When a time axis is provided values are
227  * served up from the array rather than being generated. Execution control
228  * keys are also made use of if present.
229  */
230  void set_t_axis(const p_teca_variant_array &t);
231  ///@}
232 
233  /** @name output_metadata
234  * Set the output metadata directly. The provided metadata must contain
235  * "coordinates" as defined by the teca_cf_reader because these are
236  * required for mesh generation. Pipeline execution control keys as defined
237  * by teca_index_executive are also required. Calendaring metadata is
238  * recommended. A copy of the passed object is made but "variables" are
239  * replaced with those generated by this class, if any. As a result be sure
240  * to specifiy field generators before calling this method. Returns 0 if
241  * successful, and non-zero if the supplied metadata doesn't contain the
242  * expected information. No error messages are sent to the terminal.
243  */
244  ///@{
245  int set_output_metadata(const teca_metadata &md);
246  ///@}
247 
248  /** @name append_field_generator
249  * set a callback function f(x,y,z,t) that generates a field named name
250  * x,y,z are coordinate axes in variant arrays, t is the double precision
251  * time value.
252  */
253  ///@{
254  void append_field_generator(const std::string &name,
255  const teca_metadata &atts, field_generator_callback &callback);
256  ///@}
257 
258  /** @name field_generator
259  * Set/get the named callbacks that generate fields on the mesh. These
260  * should be packaged in the field_generator struct so that field name
261  * and attributes for I/O are provided together with the callback.
262  */
263  ///@{
264  TECA_ALGORITHM_VECTOR_PROPERTY(field_generator_t, field_generator)
265  ///@}
266 
267 protected:
269 
270 private:
271  using teca_algorithm::get_output_metadata;
272 
273  /// implements the report phase of pipeline execution
274  teca_metadata get_output_metadata(unsigned int port,
275  const std::vector<teca_metadata> &input_md) override;
276 
277  /// implements the execute phase of pipeline execution
278  const_p_teca_dataset execute(unsigned int port,
279  const std::vector<const_p_teca_dataset> &input_data,
280  const teca_metadata &request) override;
281 
282  /// updates the modification state
283  void set_modified() override;
284 
285  /// clears cached metadata in response to modification of algorithm properties
286  void clear_cached_metadata();
287 
288 private:
289  unsigned int coordinate_type_code;
290  unsigned int field_type_code;
291  std::string x_axis_variable;
292  std::string y_axis_variable;
293  std::string z_axis_variable;
294  std::string t_axis_variable;
295  teca_metadata x_axis_attributes;
296  teca_metadata y_axis_attributes;
297  teca_metadata z_axis_attributes;
298  teca_metadata t_axis_attributes;
299  std::vector<unsigned long> whole_extents;
300  std::vector<double> bounds;
301 
302  std::vector<field_generator_t> field_generators;
303 
304  struct internals_t;
305  internals_t *internals;
306 };
307 
308 #endif
teca_metadata
A generic container for meta data in the form of name=value pairs.
Definition: teca_metadata.h:21
field_generator
Definition: teca_cartesian_mesh_source.h:26
const_p_teca_variant_array
std::shared_ptr< const teca_variant_array > const_p_teca_variant_array
Definition: teca_variant_array.h:27
teca_cartesian_mesh_source
An algorithm that generates a teca_cartesian_mesh of the requested spatial and temporal dimensions wi...
Definition: teca_cartesian_mesh_source.h:66
p_teca_variant_array
std::shared_ptr< teca_variant_array > p_teca_variant_array
Definition: teca_variant_array.h:27
teca_error::TECA_EXPORT
p_teca_error_handler error_handler TECA_EXPORT
The global error handler instance.
teca_algorithm
The interface to TECA pipeline architecture.
Definition: teca_algorithm.h:237