1 #ifndef teca_cartesian_mesh_util_h
2 #define teca_cartesian_mesh_util_h
6 #include "teca_config.h"
7 #include "teca_cartesian_mesh.h"
11 #include "teca_metadata.h"
12 #include "teca_array_attributes.h"
16 #include <type_traits>
25 #if defined(TECA_HAS_CUDA)
26 #define TECA_TARGET __host__ __device__
33 std::setprecision(std::numeric_limits<T>::digits10 + 1)
50 template <
typename n_t>
53 #define declare_equal_tt(cpp_t, atol, rtol) \
56 struct equal_tt<cpp_t> \
58 TECA_TARGET static cpp_t absTol() { return atol; } \
59 TECA_TARGET static cpp_t relTol() { return rtol; } \
62 declare_equal_tt(
float, 10.0f*std::numeric_limits<float>::epsilon(),
63 std::numeric_limits<float>::epsilon())
65 declare_equal_tt(
double, 10.0*std::numeric_limits<
double>::epsilon(),
66 std::numeric_limits<
float>::epsilon())
68 declare_equal_tt(
long double, std::numeric_limits<
double>::epsilon(),
69 std::numeric_limits<
double>::epsilon())
78 typename std::enable_if<std::is_floating_point<T>::value>::type* = 0)
81 T diff = std::abs(a - b);
97 bool equal(T a, T b, T relTol = 0, T absTol = 0,
98 typename std::enable_if<std::is_integral<T>::value>::type* = 0)
109 template <
typename T>
110 bool equal(T a, T b, std::string &diagnostic,
112 typename std::enable_if<std::is_floating_point<T>::value>::type* = 0)
115 T diff = std::abs(a - b);
121 bb = (bb > aa) ? bb : aa;
126 T eps = std::numeric_limits<T>::epsilon();
127 std::ostringstream os;
129 <<
" relTol=" <<
max_prec(T) << relTol
130 <<
" absTol=" <<
max_prec(T) << absTol
132 <<
" |a-b|/eps=" <<
max_prec(T) << diff/eps
133 <<
" max(|a|,|b|)*relTol=" <<
max_prec(T) << cc
134 <<
" |a-b|/max(|a|,|b|)=" <<
max_prec(T) << diff/bb
135 <<
" eps(" <<
typeid(a).name() <<
sizeof(T) <<
")="
137 diagnostic = os.str();
145 template <
typename T>
146 bool equal(T a, T b, std::string &diagnostic, T relTol = 0, T absTol = 0,
147 typename std::enable_if<std::is_integral<T>::value>::type* = 0)
154 std::ostringstream os;
155 os <<
typeid(a).name() <<
sizeof(T) <<
" " << a <<
" != " << b;
156 diagnostic = os.str();
176 length_missmatch = 2,
191 double absTol,
double relTol,
int &errorNo,
192 std::string &errorStr);
195 template<
typename data_t>
197 {
static bool eval(
const data_t &l,
const data_t &r) {
return l <= r; } };
200 template<
typename data_t>
202 {
static bool eval(
const data_t &l,
const data_t &r) {
return l >= r; } };
205 template<
typename data_t>
207 {
static bool eval(
const data_t &l,
const data_t &r) {
return l < r; } };
210 template<
typename data_t>
212 {
static bool eval(
const data_t &l,
const data_t &r) {
return l > r; } };
215 template<
typename data_t>
227 static unsigned long get_id(
bool lower,
228 unsigned long m_0,
unsigned long m_1)
237 template<
typename data_t>
249 static unsigned long get_id(
bool lower,
250 unsigned long m_0,
unsigned long m_1)
264 template <
typename data_t,
typename bracket_t = ascend_bracket<data_t>>
267 data_t val,
bool lower,
unsigned long &
id)
269 unsigned long m_0 = (r + l)/2;
270 unsigned long m_1 = m_0 + 1;
283 if (bracket_t::comp0_t::eval(val,
data[m_0]) &&
284 bracket_t::comp1_t::eval(val,
data[m_1]))
293 id = bracket_t::get_id(lower, m_0, m_1);
297 if (bracket_t::comp1_t::eval(val,
data[m_0]))
300 return teca_coordinate_util::index_of<data_t, bracket_t>(
301 data, l, m_0, val, lower,
id);
306 return teca_coordinate_util::index_of<data_t, bracket_t>(
307 data, m_1, r, val, lower,
id);
317 template <
typename T>
319 int index_of(
const T *
data,
size_t l,
size_t r, T val,
unsigned long &
id)
321 unsigned long m_0 = (r + l)/2;
322 unsigned long m_1 = m_0 + 1;
327 if (
equal(val,
data[m_0], T(8)*std::numeric_limits<T>::epsilon()))
336 if (
equal(val,
data[m_0], T(8)*std::numeric_limits<T>::epsilon()))
342 if (
equal(val,
data[m_1], T(8)*std::numeric_limits<T>::epsilon()))
410 unsigned long *extent);
423 template <
typename coord_t>
426 const coord_t *px,
unsigned long nx,
unsigned long *extent)
439 const coord_t eps8 = coord_t(8)*std::numeric_limits<coord_t>::epsilon();
441 unsigned long high_i = nx - 1;
444 coord_t low_x =
static_cast<coord_t
>(bounds[0]);
445 coord_t high_x =
static_cast<coord_t
>(bounds[1]);
446 bool slice_x =
equal(low_x, high_x, eps8);
448 if (((nx > 1) && (((px[high_i] > px[0]) &&
451 ((px[high_i] < px[0]) &&
455 TECA_ERROR(<<
"requested subset [" << bounds[0] <<
", " << bounds[1] <<
", "
456 <<
"] is not contained in the current dataset bounds [" << px[0] <<
", "
457 << px[high_i] <<
"]")
469 int index_of(
const const_p_teca_cartesian_mesh &mesh, T x, T y, T z,
470 unsigned long &i,
unsigned long &j,
unsigned long &k)
476 VARIANT_ARRAY_DISPATCH_FP(xc.get(),
478 assert_type<TT>(yc, zc);
482 sp_zc, p_zc] = get_host_accessible<CTT>(xc, yc, zc);
486 unsigned long nx = xc->size();
487 unsigned long ny = yc->size();
488 unsigned long nz = zc->size();
514 bool lower,
bool clamp,
const std::string &calendar,
515 const std::string &units,
const std::string &
date,
516 unsigned long &step);
524 const std::string &units,
const std::string &format, std::string &
date);
533 template <
typename int_t>
536 unsigned long &n_entities, std::vector<unsigned long> &counts,
537 std::vector<unsigned long> &offsets, std::vector<unsigned long> &ids)
543 unsigned long n_m1 = n_rows - 1;
544 for (
unsigned long i = 0; i < n_m1; ++i)
546 ids[i] = n_entities - 1;
547 if (index[i] != index[i+1])
550 ids[n_m1] = n_entities - 1;
553 counts.resize(n_entities);
555 for (
unsigned long i = 0; i < n_entities; ++i)
558 while ((q < n_m1) && (index[q] == index[q+1]))
567 offsets.resize(n_entities);
569 for (
unsigned long i = 1; i < n_entities; ++i)
570 offsets[i] = offsets[i-1] + counts[i-1];
583 template<
typename CT,
typename DT>
586 const CT *p_x,
const CT *p_y,
const CT *p_z,
587 const DT *p_data,
unsigned long ihi,
unsigned long jhi,
588 unsigned long khi,
unsigned long nx,
unsigned long nxy,
605 unsigned long ii = std::min(i + 1, ihi);
606 unsigned long jj = std::min(j + 1, jhi);
607 unsigned long kk = std::min(k + 1, khi);
610 unsigned long p = (cx - p_x[i]) <= (p_x[ii] - cx) ? i : ii;
611 unsigned long q = (cy - p_y[j]) <= (p_y[jj] - cy) ? j : jj;
612 unsigned long r = (cz - p_z[k]) <= (p_z[kk] - cz) ? k : kk;
615 val = p_data[p + nx*q + nxy*r];
631 template<
typename coord_t,
typename data_t>
634 const coord_t *p_y,
const data_t *p_data,
unsigned long ihi,
635 unsigned long jhi,
unsigned long nx, data_t &val)
649 unsigned long ii = std::min(i + 1, ihi);
650 unsigned long jj = std::min(j + 1, jhi);
653 unsigned long p = (cx - p_x[i]) <= (p_x[ii] - cx) ? i : ii;
654 unsigned long q = (cy - p_y[j]) <= (p_y[jj] - cy) ? j : jj;
657 val = p_data[p + nx*q];
672 template<
typename CT,
typename DT>
675 const CT *p_x,
const CT *p_y,
const CT *p_z,
676 const DT *p_data,
unsigned long ihi,
unsigned long jhi,
677 unsigned long khi,
unsigned long nx,
unsigned long nxy,
694 unsigned long ii = std::min(i + 1, ihi);
695 unsigned long jj = std::min(j + 1, jhi);
696 unsigned long kk = std::min(k + 1, khi);
699 CT wx = ii == i ? 0 : (cx - p_x[i])/(p_x[ii] - p_x[i]);
700 CT wy = jj == j ? 0 : (cy - p_y[j])/(p_y[jj] - p_y[j]);
701 CT wz = kk == k ? 0 : (cz - p_z[k])/(p_z[kk] - p_z[k]);
708 val = vx*vy*vz*p_data[ i + j*nx + k*nxy]
709 + wx*vy*vz*p_data[ii + j*nx + k*nxy]
710 + wx*wy*vz*p_data[ii + jj*nx + k*nxy]
711 + vx*wy*vz*p_data[ i + jj*nx + k*nxy]
712 + vx*vy*wz*p_data[ i + j*nx + kk*nxy]
713 + wx*vy*wz*p_data[ii + j*nx + kk*nxy]
714 + wx*wy*wz*p_data[ii + jj*nx + kk*nxy]
715 + vx*wy*wz*p_data[ i + jj*nx + kk*nxy];
732 template<
typename CT,
typename DT>
735 const DT *p_data,
unsigned long ihi,
unsigned long jhi,
736 unsigned long nx, DT &val)
750 unsigned long ii = std::min(i + 1, ihi);
751 unsigned long jj = std::min(j + 1, jhi);
754 CT wx = ii == i ? 0 : (cx - p_x[i])/(p_x[ii] - p_x[i]);
755 CT wy = jj == j ? 0 : (cy - p_y[j])/(p_y[jj] - p_y[j]);
761 val = vx*vy*p_data[ i + j*nx]
762 + wx*vy*p_data[ii + j*nx]
763 + wx*wy*p_data[ii + jj*nx]
764 + vx*wy*p_data[ i + jj*nx];
776 template<
typename CT,
typename DT>
777 int operator()(CT tx, CT ty, CT tz,
const CT *sx,
const CT *sy,
778 const CT *sz,
const DT *sa,
unsigned long ihi,
unsigned long jhi,
779 unsigned long khi,
unsigned long nx,
unsigned long nxy, DT &ta)
782 sx,sy,sz,sa, ihi,jhi,khi, nx,nxy, ta);
786 template<
typename CT,
typename DT>
787 int operator()(CT tx, CT ty,
const CT *sx,
const CT *sy,
788 const DT *sa,
unsigned long ihi,
unsigned long jhi,
789 unsigned long nx, DT &ta)
792 sx,sy,sa, ihi,jhi, nx, ta);
800 template<
typename CT,
typename DT>
801 int operator()(CT tx, CT ty, CT tz,
const CT *sx,
const CT *sy,
802 const CT *sz,
const DT *sa,
unsigned long ihi,
unsigned long jhi,
803 unsigned long khi,
unsigned long nx,
unsigned long nxy, DT &ta)
806 sx,sy,sz,sa, ihi,jhi,khi, nx,nxy, ta);
810 template<
typename CT,
typename DT>
811 int operator()(CT tx, CT ty,
const CT *sx,
const CT *sy,
812 const DT *sa,
unsigned long ihi,
unsigned long jhi,
813 unsigned long nx, DT &ta)
816 sx,sy,sa, ihi,jhi, nx, ta);
825 template <
typename num_t>
831 case teca_array_attributes::invalid_value:
832 TECA_ERROR(
"detected invalid_value in centering")
835 case teca_array_attributes::cell_centering:
837 case teca_array_attributes::x_face_centering:
840 case teca_array_attributes::y_face_centering:
843 case teca_array_attributes::z_face_centering:
846 case teca_array_attributes::x_edge_centering:
850 case teca_array_attributes::y_edge_centering:
854 case teca_array_attributes::z_edge_centering:
858 case teca_array_attributes::point_centering:
863 case teca_array_attributes::no_centering:
866 TECA_ERROR(
"this centering is undefined " << centering)
879 unsigned long *whole_extent,
double *bounds);
890 template <
typename num_t>
894 if ((part[0] >= whole[0]) && (part[0] <= whole[1]) &&
895 (part[1] >= whole[0]) && (part[1] <= whole[1]) &&
896 (part[2] >= whole[2]) && (part[2] <= whole[3]) &&
897 (part[3] >= whole[2]) && (part[3] <= whole[3]) &&
898 (part[4] >= whole[4]) && (part[4] <= whole[5]) &&
899 (part[5] >= whole[4]) && (part[5] <= whole[5]))
908 template <
typename num_t>
910 int covers(
const num_t *whole,
const num_t *part)
912 bool x_ascend = whole[0] <= whole[1];
913 bool y_ascend = whole[2] <= whole[3];
914 bool z_ascend = whole[4] <= whole[5];
916 (part[0] >= whole[0]) && (part[0] <= whole[1]) &&
917 (part[1] >= whole[0]) && (part[1] <= whole[1])) ||
919 (part[0] <= whole[0]) && (part[0] >= whole[1]) &&
920 (part[1] <= whole[0]) && (part[1] >= whole[1]))) &&
922 (part[2] >= whole[2]) && (part[2] <= whole[3]) &&
923 (part[3] >= whole[2]) && (part[3] <= whole[3])) ||
925 (part[2] <= whole[2]) && (part[2] >= whole[3]) &&
926 (part[3] <= whole[2]) && (part[3] >= whole[3]))) &&
928 (part[4] >= whole[4]) && (part[4] <= whole[5]) &&
929 (part[5] >= whole[4]) && (part[5] <= whole[5])) ||
931 (part[4] <= whole[4]) && (part[4] >= whole[5]) &&
932 (part[5] <= whole[4]) && (part[5] >= whole[5]))))
940 template <
typename num_t>
944 if ((((whole[0] <= whole[1]) && (part[0] <= part[1])) ||
945 ((whole[0] >= whole[1]) && (part[0] >= part[1]))) &&
946 (((whole[2] <= whole[3]) && (part[2] <= part[3])) ||
947 ((whole[2] >= whole[3]) && (part[2] >= part[3]))) &&
948 (((whole[4] <= whole[5]) && (part[4] <= part[5])) ||
949 ((whole[4] >= whole[5]) && (part[4] >= part[5]))))
962 unsigned long nz_max,
unsigned long *extent,
bool verbose);
970 unsigned long nz_max,
unsigned long *extent,
bool verbose);
979 const std::string &a_name,
const std::string a_units,
984 const std::string &a_name,
const std::string &a_units,
990 length_missmatch = 2,
993 unsupported_type = 5,
1003 double a_abs_tol,
double a_rel_tol,
1004 std::string &errorStr);
1008 std::string m_reference_source;
1009 std::string m_reference_name;
1010 std::string m_reference_units;
1012 std::vector<const_p_teca_variant_array> m_arrays;
1013 std::vector<std::string> m_array_sources;
1014 std::vector<std::string> m_array_names;
1015 std::vector<std::string> m_array_units;
1036 bool provides_time);
1045 bool provides_geometry);
1054 bool provides_geometry);
1063 bool provides_geometry);
1078 double m_absolute_tolerance;
1079 double m_relative_tolerance;
1097 template <
typename T,
size_t N>
1100 return std::vector<T>(arr.begin(), arr.end());
1104 template <
typename T,
size_t N>
1107 std::array<T,N> arr;
1108 size_t m = vec.size();
1109 for (
size_t i = 0; i < N && i < m; ++i)
1117 template <
typename T>
1120 return as_array<T,6>(vec);
1126 template <
typename T>
1129 return as_array<T,2>(vec);
1135 template <
typename T>
1138 return {arr[0], arr[1], arr[2], arr[3], arr[4], arr[5]};
1148 int split_dir,
unsigned long min_size);
1168 int split_x,
int split_y,
int split_z,
unsigned long min_size_x,
1169 unsigned long min_size_y,
unsigned long min_size_z,
1170 std::deque<spatial_extent_t> &blocks);
1190 long n_temporal_blocks,
long temporal_block_size,
1191 std::vector<temporal_extent_t> &temporal_blocks);
1205 const std::vector<std::pair<long, long>> &step_extents,
1218 template <
typename coord_t>
1221 const coord_t &left_tile,
const coord_t &right_tile)
1223 int_tile[0] = std::max(left_tile[0], right_tile[0]);
1224 int_tile[1] = std::min(left_tile[1], right_tile[1]);
1225 int_tile[2] = std::max(left_tile[2], right_tile[2]);
1226 int_tile[3] = std::min(left_tile[3], right_tile[3]);
1233 template <
typename coord_t>
1237 return (tile[0] > tile[1]) || (tile[2] > tile[3]);
Check that cooridnate arrays from different sources match a refrence array.
Definition: teca_coordinate_util.h:1022
int add_x_coordinate_axis(const std::string &source, const teca_metadata &coords, const teca_metadata &atts, bool provides_geometry)
int add_y_coordinate_axis(const std::string &source, const teca_metadata &coords, const teca_metadata &atts, bool provides_geometry)
int add_time_axis(const std::string &source, const teca_metadata &coords, const teca_metadata &atts, bool provides_time)
int validate_spatial_coordinate_axes(std::string &errorStr)
int validate_time_axis(std::string &errorStr)
int add_z_coordinate_axis(const std::string &source, const teca_metadata &coords, const teca_metadata &atts, bool provides_geometry)
compares a set of arrays against a reference array
Definition: teca_coordinate_util.h:975
void append_array(const std::string &a_source, const std::string &a_name, const std::string &a_units, const const_p_teca_variant_array &a_array)
add an array to check against the reference
void set_reference_array(const std::string &a_source, const std::string &a_name, const std::string a_units, const const_p_teca_variant_array &a_array)
set the array to which others will be compared to
int validate(const std::string &a_descriptor, double a_abs_tol, double a_rel_tol, std::string &errorStr)
hamr::buffer_allocator allocator
allocator types
Definition: teca_variant_array.h:46
TECA_EXPORT int date(double val, int *year, int *month, int *day, int *hour, int *minute, double *second, const char *dataunits, const char *calendar_name)
Codes dealing with operations on coordinate systems.
Definition: teca_coordinate_util.h:37
TECA_EXPORT bool equal(const const_p_teca_variant_array &array1, const const_p_teca_variant_array &array2, double absTol, double relTol, int &errorNo, std::string &errorStr)
TECA_EXPORT int interpolate_linear(CT cx, CT cy, const CT *p_x, const CT *p_y, const DT *p_data, unsigned long ihi, unsigned long jhi, unsigned long nx, DT &val)
Definition: teca_coordinate_util.h:734
TECA_EXPORT int validate_centering(int centering)
return 0 if the centering is one of the values defined in teca_array_attributes
std::array< unsigned long, 2 > temporal_extent_t
Definition: teca_coordinate_util.h:1094
TECA_EXPORT int split(spatial_extent_t &block_1, spatial_extent_t &block_2, int split_dir, unsigned long min_size)
TECA_EXPORT void get_table_offsets(const int_t *index, unsigned long n_rows, unsigned long &n_entities, std::vector< unsigned long > &counts, std::vector< unsigned long > &offsets, std::vector< unsigned long > &ids)
Definition: teca_coordinate_util.h:535
TECA_EXPORT int partition(const temporal_extent_t &temporal_extent, long n_temporal_blocks, long temporal_block_size, std::vector< temporal_extent_t > &temporal_blocks)
TECA_EXPORT int convert_cell_extent(num_t *extent, int centering)
convert from a cell extent to a face, edge or point centered extent
Definition: teca_coordinate_util.h:827
TECA_EXPORT int get_cartesian_mesh_bounds(const const_p_teca_variant_array x, const const_p_teca_variant_array y, const const_p_teca_variant_array z, double *bounds)
get the mesh's bounds from the coordinate axis arrays
TECA_EXPORT int interpolate_nearest(CT cx, CT cy, CT cz, const CT *p_x, const CT *p_y, const CT *p_z, const DT *p_data, unsigned long ihi, unsigned long jhi, unsigned long khi, unsigned long nx, unsigned long nxy, DT &val)
Definition: teca_coordinate_util.h:585
TECA_EXPORT int bounds_to_extent(const double *bounds, const coord_t *px, unsigned long nx, unsigned long *extent)
Definition: teca_coordinate_util.h:425
TECA_EXPORT int index_of(const const_p_teca_cartesian_mesh &mesh, T x, T y, T z, unsigned long &i, unsigned long &j, unsigned long &k)
Definition: teca_coordinate_util.h:469
TECA_EXPORT int time_step_of(const const_p_teca_variant_array &time, bool lower, bool clamp, const std::string &calendar, const std::string &units, const std::string &date, unsigned long &step)
spatial_extent_t as_spatial_extent(const T arr[6])
Definition: teca_coordinate_util.h:1136
std::vector< T > as_vector(const std::array< T, N > &arr)
converts a std::array to a std:vector
Definition: teca_coordinate_util.h:1098
TECA_EXPORT int same_orientation(const num_t *whole, const num_t *part)
Definition: teca_coordinate_util.h:942
TECA_EXPORT bool empty_tile(const coord_t &tile)
Definition: teca_coordinate_util.h:1235
TECA_EXPORT int clamp_dimensions_of_one(unsigned long nx_max, unsigned long ny_max, unsigned long nz_max, unsigned long *extent, bool verbose)
spatial_extent_t as_temporal_extent(const std::vector< T > &vec)
Definition: teca_coordinate_util.h:1127
std::array< T, N > as_array(const std::vector< T > &vec)
converts a std::vector to a std::array
Definition: teca_coordinate_util.h:1105
TECA_EXPORT int interpolate_nearest(coord_t cx, coord_t cy, const coord_t *p_x, const coord_t *p_y, const data_t *p_data, unsigned long ihi, unsigned long jhi, unsigned long nx, data_t &val)
Definition: teca_coordinate_util.h:633
TECA_EXPORT int get_cartesian_mesh_extent(const teca_metadata &md, unsigned long *whole_extent, double *bounds)
TECA_EXPORT int index_of(const data_t *data, unsigned long l, unsigned long r, data_t val, bool lower, unsigned long &id)
Definition: teca_coordinate_util.h:266
TECA_EXPORT int find_extent_containing_step(long step, const std::vector< std::pair< long, long >> &step_extents, long &index)
TECA_EXPORT int covers(const num_t *whole, const num_t *part)
Definition: teca_coordinate_util.h:910
TECA_EXPORT int covers_ascending(const num_t *whole, const num_t *part)
Definition: teca_coordinate_util.h:892
struct TECA_EXPORT interpolate_t
A functor templated on order of accuracy for above Cartesian mesh interpolants.
Definition: teca_coordinate_util.h:770
TECA_EXPORT int interpolate_linear(CT cx, CT cy, CT cz, const CT *p_x, const CT *p_y, const CT *p_z, const DT *p_data, unsigned long ihi, unsigned long jhi, unsigned long khi, unsigned long nx, unsigned long nxy, DT &val)
Definition: teca_coordinate_util.h:674
TECA_EXPORT int validate_extent(unsigned long nx_max, unsigned long ny_max, unsigned long nz_max, unsigned long *extent, bool verbose)
TECA_EXPORT coord_t & intersect_tiles(coord_t &int_tile, const coord_t &left_tile, const coord_t &right_tile)
Definition: teca_coordinate_util.h:1220
TECA_EXPORT int time_to_string(double val, const std::string &calendar, const std::string &units, const std::string &format, std::string &date)
std::array< unsigned long, 6 > spatial_extent_t
Definition: teca_coordinate_util.h:1089
p_teca_error_handler error_handler TECA_EXPORT
The global error handler instance.
some functions helping us manipulate teca_variant_array
Definition: teca_variant_array_util.h:14
auto data(V &&... args)
Definition: teca_variant_array_util.h:255
void sync_host_access_any(const array_t &... arrays)
Definition: teca_variant_array_util.h:29
comparator implementing bracket for ascending input arrays
Definition: teca_coordinate_util.h:217
comparator implementing bracket for descending input arrays
Definition: teca_coordinate_util.h:239
Definition: teca_coordinate_util.h:173
traits classes used to get default tolerances for comparing numbers of a given precision.
Definition: teca_coordinate_util.h:51
Greater than or equal to predicate.
Definition: teca_coordinate_util.h:202
Greater than predicate.
Definition: teca_coordinate_util.h:212
Less than or equal to predicate.
Definition: teca_coordinate_util.h:197
Less than predicate.
Definition: teca_coordinate_util.h:207
#define TECA_ERROR(_msg)
Constructs an error message and sends it to the stderr stream.
Definition: teca_common.h:161
#define max_prec(T)
For printing data as ASCII with the maximum supported numerical precision.
Definition: teca_coordinate_util.h:32
std::shared_ptr< const teca_variant_array > const_p_teca_variant_array
Definition: teca_variant_array.h:27