1 /* 2 This file is part of CDO. CDO is a collection of Operators to manipulate and analyse Climate model Data. 3 4 Author: Uwe Schulzweida 5 6 */ 7 #ifndef DATARANGELIST_H 8 #define DATARANGELIST_H 9 10 #include <cdi.h> 11 #include <cstddef> 12 #include "cdo_output.h" 13 #include "varray.h" 14 15 struct Datarange 16 { 17 bool check_datarange; 18 size_t gridsize; 19 int datatype; 20 double missval; 21 double addoffset; 22 double scalefactor; 23 DatarangeDatarange24 Datarange() : check_datarange(false), gridsize(0), datatype(0), missval(0), addoffset(0), scalefactor(1){}; 25 26 template <typename T> 27 void checkDatarangeDatarange28 checkDatarange(T *array, size_t nmiss) 29 { 30 const auto mm = nmiss ? varray_min_max_mv(gridsize, array, (T)missval) : varray_min_max(gridsize, array); 31 const auto numberOfValues = nmiss ? mm.n : gridsize; 32 33 if (numberOfValues > 0) 34 { 35 auto smin = (mm.min - addoffset) / scalefactor; 36 auto smax = (mm.max - addoffset) / scalefactor; 37 38 if (datatype == CDI_DATATYPE_INT8 || datatype == CDI_DATATYPE_UINT8 || datatype == CDI_DATATYPE_INT16 39 || datatype == CDI_DATATYPE_UINT16) 40 { 41 smin = (int) std::lround(smin); 42 smax = (int) std::lround(smax); 43 } 44 45 double vmin = 0.0, vmax = 0.0; 46 // clang-format off 47 if (datatype == CDI_DATATYPE_INT8 ) { vmin = -128.0; vmax = 127.0; } 48 else if (datatype == CDI_DATATYPE_UINT8 ) { vmin = 0.0; vmax = 255.0; } 49 else if (datatype == CDI_DATATYPE_INT16 ) { vmin = -32768.0; vmax = 32767.0; } 50 else if (datatype == CDI_DATATYPE_UINT16) { vmin = 0.0; vmax = 65535.0; } 51 else if (datatype == CDI_DATATYPE_INT32 ) { vmin = -2147483648.0; vmax = 2147483647.0; } 52 else if (datatype == CDI_DATATYPE_UINT32) { vmin = 0.0; vmax = 4294967295.0; } 53 else if (datatype == CDI_DATATYPE_FLT32 ) { vmin = -3.40282e+38; vmax = 3.40282e+38; } 54 else { vmin = -1.e+300; vmax = 1.e+300; } 55 // clang-format on 56 57 if (smin < vmin || smax > vmax) 58 cdo_warning("Some data values (min=%g max=%g) are outside the\n" 59 " valid range (%g - %g) of the used output precision!\n" 60 " Use the CDO option%s -b F64 to increase the output precision.", 61 smin, smax, vmin, vmax, (datatype == CDI_DATATYPE_FLT32) ? "" : " -b F32 or"); 62 } 63 } 64 }; 65 66 #endif 67