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