From b4e05f34f7a3bbbaa62e909a2e6b88209763c4d3 Mon Sep 17 00:00:00 2001 From: Uwe Schulzweida <uwe.schulzweida@mpimet.mpg.de> Date: Thu, 13 Mar 2025 12:09:25 +0100 Subject: [PATCH 01/10] config/default: changed netcdf library on levante --- config/default | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/config/default b/config/default index b98fb1231..759af6655 100755 --- a/config/default +++ b/config/default @@ -369,7 +369,8 @@ case "${HOSTNAME}" in # NETCDFPATH=/sw/spack-levante/netcdf-c-4.8.1-qk24yp # HDF5PATH=/sw/spack-levante/hdf5-1.12.1-akf2kp levante*) - NETCDFPATH=/sw/spack-levante/netcdf-c-4.9.3-dp4zi4 + #NETCDFPATH=/sw/spack-levante/netcdf-c-4.9.3-dp4zi4 + NETCDFPATH=/sw/spack-levante/netcdf-c-4.9.3-wdybfq UDUNITS2PATH=/sw/spack-levante/udunits-2.2.28-da6pla FFTW3PATH=/sw/spack-levante/fftw-3.3.10-fnfhvr ECCODESPATH=/sw/spack-levante/eccodes-2.32.5-ly6tko @@ -378,7 +379,6 @@ case "${HOSTNAME}" in #PROJPATH=/sw/spack-levante/proj-8.1.0-i6a6ah CDOLIBS="--with-eccodes=$ECCODESPATH \ --with-netcdf=$NETCDFPATH \ - --with-hdf5=$HDF5PATH \ --with-udunits2=$UDUNITS2PATH \ --with-fftw3 \ --with-szlib=$SZPATH \ @@ -392,7 +392,6 @@ case "${HOSTNAME}" in LDFLAGS="$LDFLAGS -L$SZPATH/lib64 -Wl,-rpath,$SZPATH/lib64" LDFLAGS="$LDFLAGS -L$NETCDFPATH/lib64 -Wl,-rpath,$NETCDFPATH/lib64" # LDFLAGS="$LDFLAGS -Wl,-rpath,/sw/spack-levante/hdf-4.2.16-2-h6elwi/lib" - LDFLAGS="$LDFLAGS -Wl,-rpath,$HDF5PATH/lib" LDFLAGS="$LDFLAGS -Wl,-rpath,$UDUNITS2PATH/lib" # LDFLAGS="$LDFLAGS -Wl,-rpath,$PROJPATH/lib" LDFLAGS="$LDFLAGS -L$FFTW3PATH/lib -Wl,-rpath,$FFTW3PATH/lib" -- GitLab From de8756c440d7a990fa07d212424d849e839f993b Mon Sep 17 00:00:00 2001 From: Uwe Schulzweida <uwe.schulzweida@mpimet.mpg.de> Date: Fri, 14 Mar 2025 08:38:49 +0100 Subject: [PATCH 02/10] cat, mergetime: unpack input data --- ChangeLog | 4 ++++ src/Cat.cc | 1 + src/Merge.cc | 2 ++ src/Mergetime.cc | 1 + 4 files changed, 8 insertions(+) diff --git a/ChangeLog b/ChangeLog index 2d0b7415e..247c0c56f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2025-03-14 Uwe Schulzweida + + * cat, mergetime: unpack input data + 2025-03-05 Uwe Schulzweida * Using CDI library version 2.5.1 diff --git a/src/Cat.cc b/src/Cat.cc index 6fa6ad56d..0c1cfb9ca 100644 --- a/src/Cat.cc +++ b/src/Cat.cc @@ -103,6 +103,7 @@ public: streamMode = StreamMode::CREATE; streamID2 = cdo_open_write(numFiles); vlistID2 = vlistDuplicate(vlistID1); + vlist_unpack(vlistID2); taxisID2 = taxisDuplicate(taxisID1); vlistDefTaxis(vlistID2, taxisID2); diff --git a/src/Merge.cc b/src/Merge.cc index 0728fed89..1345bf4b8 100644 --- a/src/Merge.cc +++ b/src/Merge.cc @@ -189,6 +189,8 @@ public: vlistMerge(vlistID2, vlistIDs[im]); } + vlist_unpack(vlistID2); + int numConstVars = 0; for (int im = 0; im < numMerge; ++im) { diff --git a/src/Mergetime.cc b/src/Mergetime.cc index a3574f37b..5304e9cc9 100644 --- a/src/Mergetime.cc +++ b/src/Mergetime.cc @@ -288,6 +288,7 @@ public: : ((mapFlag == MapFlag::Intersect) ? streamInfoList[vlistFileIDmin].vlistID : streamInfoList[vlistFileIDmax].vlistID); vlistID2 = vlistDuplicate(vlistID1); + vlist_unpack(vlistID2); auto taxisID1 = vlistInqTaxis(si.vlistID); taxisID2 = taxisDuplicate(taxisID1); vlistDefTaxis(vlistID2, taxisID2); -- GitLab From 1f32133cb138db09c139b8488f8e57819a5cc7a5 Mon Sep 17 00:00:00 2001 From: Uwe Schulzweida <uwe.schulzweida@mpimet.mpg.de> Date: Fri, 14 Mar 2025 18:16:23 +0100 Subject: [PATCH 03/10] enable-hirlam-extensions failed since release 2.5.1 (bug fix) --- ChangeLog | 1 + configure.ac | 2 +- libcdi | 2 +- src/cdo.cc | 4 ---- src/cdo_def_options.cc | 4 ++++ src/vertical_interp.cc | 2 +- 6 files changed, 8 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 247c0c56f..59a1af4eb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,7 @@ 2025-03-14 Uwe Schulzweida * cat, mergetime: unpack input data + * enable-hirlam-extensions failed since release 2.5.1 (bug fix) 2025-03-05 Uwe Schulzweida diff --git a/configure.ac b/configure.ac index 075839b1f..20a557a12 100644 --- a/configure.ac +++ b/configure.ac @@ -5,7 +5,7 @@ # libtool 2.4.2 AC_PREREQ([2.69]) -AC_INIT([cdo],[2.5.1],[https://mpimet.mpg.de/cdo]) +AC_INIT([cdo],[2.5.2],[https://mpimet.mpg.de/cdo]) AC_DEFINE_UNQUOTED(CDO, ["$PACKAGE_VERSION"], [CDO version]) diff --git a/libcdi b/libcdi index b9a7b1f01..6729bee6d 160000 --- a/libcdi +++ b/libcdi @@ -1 +1 @@ -Subproject commit b9a7b1f01600456c195ea4b1611098e0d39cdfe7 +Subproject commit 6729bee6d0a040c99d0f6aac7d768b1adb5a81ee diff --git a/src/cdo.cc b/src/cdo.cc index 042d8bc7b..8e258f153 100644 --- a/src/cdo.cc +++ b/src/cdo.cc @@ -53,10 +53,6 @@ cdo_exit(std::string msg = "") static bool applyDryRun = false; -#ifdef HIRLAM_EXTENSIONS -extern "C" void streamGrbDefDataScanningMode(int scanmode); -#endif - static void cdo_display_syntax_help(std::string const &help, FILE *p_target) { diff --git a/src/cdo_def_options.cc b/src/cdo_def_options.cc index 5884f029c..28d9eb824 100644 --- a/src/cdo_def_options.cc +++ b/src/cdo_def_options.cc @@ -19,6 +19,10 @@ #include "cdo_zaxis.h" #include "chunkspec.h" +#ifdef HIRLAM_EXTENSIONS +extern "C" void streamGrbDefDataScanningMode(int scanmode); +#endif + static void set_chunkspec_parameter(std::string const &argument) { diff --git a/src/vertical_interp.cc b/src/vertical_interp.cc index 13a266fa7..111a21da8 100644 --- a/src/vertical_interp.cc +++ b/src/vertical_interp.cc @@ -171,7 +171,7 @@ extrapolate_Z(double pres, double halfPress, double fullPress, double geop, doub if (tmsl > ztlim && tstar <= ztlim) tmsl = ztlim; - if (tmsl - tstar < 0.000001 && tstar - tmsl < 0.000001) + if ((tmsl - tstar) < 0.000001 && (tstar - tmsl) < 0.000001) alpha = 0.0; else if (geop > 0.0001 || geop < -0.0001) alpha = PlanetRD * (tmsl - tstar) / geop; -- GitLab From bf71e9ac0670a23b557f0cf8b4c417b319801945 Mon Sep 17 00:00:00 2001 From: Uwe Schulzweida <uwe.schulzweida@mpimet.mpg.de> Date: Sat, 15 Mar 2025 17:47:20 +0100 Subject: [PATCH 04/10] timpctl: Missing error handling for CDO_PCTL_NBINS>32768 (bug fix) --- ChangeLog | 4 + src/Timpctl.cc | 1 - src/percentiles_hist.cc | 168 ++++++++++++++++++++-------------------- src/percentiles_hist.h | 42 +++++----- 4 files changed, 109 insertions(+), 106 deletions(-) diff --git a/ChangeLog b/ChangeLog index 59a1af4eb..449802dd9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2025-03-15 Uwe Schulzweida + + * timpctl: Missing error handling for CDO_PCTL_NBINS>32768 (bug fix) + 2025-03-14 Uwe Schulzweida * cat, mergetime: unpack input data diff --git a/src/Timpctl.cc b/src/Timpctl.cc index 4cf13f1d4..8dd8fcc61 100644 --- a/src/Timpctl.cc +++ b/src/Timpctl.cc @@ -185,7 +185,6 @@ public: { field1.init(var1); cdo_read_field(streamID1, field1); - hset.addVarLevelValues(varID, levelID, field1); } } diff --git a/src/percentiles_hist.cc b/src/percentiles_hist.cc index 8705ee1de..4a5f01151 100644 --- a/src/percentiles_hist.cc +++ b/src/percentiles_hist.cc @@ -22,7 +22,7 @@ #define SHR_PTR(p) ((unsigned short *) (p)) static int -histGetEnvNBins() +histGetEnvNumBins() { constexpr int NBINS_DEFAULT = 101; constexpr int NBINS_MINIMUM = 11; @@ -34,47 +34,47 @@ histGetEnvNBins() template <typename T> static void -hist_init_bins(int nbins, T *bins) +hist_init_bins(int numBins, T *bins) { - for (int i = 0; i < nbins; ++i) bins[i] = 0; + for (int i = 0; i < numBins; ++i) bins[i] = 0; } static void histDefBounds(HistogramEntry &hist, float a, float b) { - assert(hist.nbins > 0); + assert(hist.numBins > 0); hist.nsamp = 0; hist.min = std::min(a, b); hist.max = std::max(a, b); - hist.step = (hist.max - hist.min) / hist.nbins; + hist.step = (hist.max - hist.min) / hist.numBins; if (hist.isUint32) - hist_init_bins(hist.nbins, INT_PTR(hist.ptr)); + hist_init_bins(hist.numBins, INT_PTR(hist.ptr)); else - hist_init_bins(hist.nbins, SHR_PTR(hist.ptr)); + hist_init_bins(hist.numBins, SHR_PTR(hist.ptr)); } static inline int -calc_bin(int nbins, float histMin, float histStep, float value) +calc_bin(int numBins, float histMin, float histStep, float value) { - return (histStep > 0.0f) ? std::min((int) ((value - histMin) / histStep), nbins - 1) : 0; + return (histStep > 0.0f) ? std::min((int) ((value - histMin) / histStep), numBins - 1) : 0; } template <typename T> static void histBinAddValue(HistogramEntry &hist, T *bins, float value) { - auto bin = calc_bin(hist.nbins, hist.min, hist.step, value); - if (bin >= 0 && bin < hist.nbins) bins[bin]++; + auto bin = calc_bin(hist.numBins, hist.min, hist.step, value); + if (bin >= 0 && bin < hist.numBins) bins[bin]++; } template <typename T> static void histBinSubValue(HistogramEntry &hist, T *bins, float value) { - auto bin = calc_bin(hist.nbins, hist.min, hist.step, value); - if (bin >= 0 && bin < hist.nbins && bins[bin] > 0) bins[bin]--; + auto bin = calc_bin(hist.numBins, hist.min, hist.step, value); + if (bin >= 0 && bin < hist.numBins && bins[bin] > 0) bins[bin]--; } static void @@ -88,9 +88,9 @@ histBin(HistogramEntry &hist) for (int i = 0; i < hist.nsamp; ++i) values[i] = fltptr[i]; if (hist.isUint32) - hist_init_bins(hist.nbins, INT_PTR(hist.ptr)); + hist_init_bins(hist.numBins, INT_PTR(hist.ptr)); else - hist_init_bins(hist.nbins, SHR_PTR(hist.ptr)); + hist_init_bins(hist.numBins, SHR_PTR(hist.ptr)); if (hist.isUint32) for (int i = 0; i < hist.nsamp; ++i) histBinAddValue(hist, INT_PTR(hist.ptr), values[i]); @@ -101,7 +101,7 @@ histBin(HistogramEntry &hist) static int histReset(HistogramEntry &hist) { - assert(hist.nbins > 0); + assert(hist.numBins > 0); if (hist.nsamp < hist.capacity) { @@ -110,9 +110,9 @@ histReset(HistogramEntry &hist) else { if (hist.isUint32) - for (int i = 0; i < hist.nbins; ++i) INT_PTR(hist.ptr)[i] = 0; + for (int i = 0; i < hist.numBins; ++i) INT_PTR(hist.ptr)[i] = 0; else - for (int i = 0; i < hist.nbins; ++i) SHR_PTR(hist.ptr)[i] = 0; + for (int i = 0; i < hist.numBins; ++i) SHR_PTR(hist.ptr)[i] = 0; } hist.nsamp = 0; @@ -132,7 +132,7 @@ histCheckValue(const HistogramEntry &hist, float &value) static int histAddValue(HistogramEntry &hist, float value) { - assert(hist.nbins > 0); + assert(hist.numBins > 0); // if (is_equal(hist.min, hist.max)) return 0; @@ -178,7 +178,7 @@ histRemoveValue(HistogramEntry &hist, float value) static int histSubValue(HistogramEntry &hist, float value) { - assert(hist.nbins > 0); + assert(hist.numBins > 0); if (is_equal(hist.min, hist.max)) return 0; @@ -211,7 +211,7 @@ histGetBin(int nbins, double s, const T *ptr) while (count < s); assert(i > 0); - assert(i - 1 < nbins); + assert((i - 1) < nbins); assert(ptr[i - 1] > 0); double t = (count - s) / ptr[i - 1]; @@ -223,7 +223,7 @@ static double histGetPercentile(const HistogramEntry &hist, double p) { assert(hist.nsamp > 0); - assert(hist.nbins > 0); + assert(hist.numBins > 0); assert(p >= 0.0); assert(p <= 100.0); @@ -233,12 +233,12 @@ histGetPercentile(const HistogramEntry &hist, double p) if (lprint && Options::cdoVerbose) { lprint = false; - cdo_print("Using percentile method: histogram with %d bins", hist.nbins); + cdo_print("Using percentile method: histogram with %d bins", hist.numBins); } double s = hist.nsamp * (p / 100.0); - auto bin = hist.isUint32 ? histGetBin(hist.nbins, s, INT_PTR(hist.ptr)) : histGetBin(hist.nbins, s, SHR_PTR(hist.ptr)); + auto bin = hist.isUint32 ? histGetBin(hist.numBins, s, INT_PTR(hist.ptr)) : histGetBin(hist.numBins, s, SHR_PTR(hist.ptr)); // assert(hist.step > 0.0f); @@ -248,37 +248,37 @@ histGetPercentile(const HistogramEntry &hist, double p) } void -HistogramSet::createVarLevels(int varID, int nlevels, size_t nhists) +HistogramSet::createVarLevels(int varID, int numLevels, size_t numHists) { - auto nbins = histGetEnvNBins(); + auto numBins = histGetEnvNumBins(); - assert(nbins > 0); - assert(nlevels > 0); - assert(nhists > 0); + assert(numBins > 0); + assert(numLevels > 0); + assert(numHists > 0); - if (varID < 0 || varID >= nvars) cdo_abort("Illegal argument: varID %d is undefined (%s)", varID, __func__); + if (varID < 0 || varID >= numVars) cdo_abort("Illegal argument: varID %d is undefined (%s)", varID, __func__); - this->var_nlevels[varID] = nlevels; - this->var_nhists[varID] = nhists; - this->histograms[varID].resize(nlevels); + this->var_numLevels[varID] = numLevels; + this->var_numHists[varID] = numHists; + this->histograms[varID].resize(numLevels); - for (int levelID = 0; levelID < nlevels; ++levelID) + for (int levelID = 0; levelID < numLevels; ++levelID) { - this->histograms[varID][levelID].resize(nhists); + this->histograms[varID][levelID].resize(numHists); auto &hists = this->histograms[varID][levelID]; - for (size_t histID = 0; histID < nhists; histID++) + for (size_t histID = 0; histID < numHists; histID++) { hists[histID].min = 0.0f; hists[histID].max = 0.0f; hists[histID].step = 0.0f; - hists[histID].nbins = nbins; + hists[histID].numBins = numBins; hists[histID].nsamp = 0; - auto isUint32 = (this->nsteps >= USHRT_MAX); + auto isUint32 = (this->numSteps >= USHRT_MAX); auto vsize = isUint32 ? sizeof(unsigned int) : sizeof(unsigned short); hists[histID].isUint32 = isUint32; - hists[histID].capacity = FLT_CAPACITY(nbins, vsize); - hists[histID].ptr = std::malloc(nbins * vsize); + hists[histID].capacity = FLT_CAPACITY(numBins, vsize); + hists[histID].ptr = std::malloc(numBins * vsize); if (hists[histID].ptr == nullptr) cdo_abort("Not enough memory (%s)", __func__); } } @@ -286,12 +286,12 @@ HistogramSet::createVarLevels(int varID, int nlevels, size_t nhists) template <typename T1, typename T2> static void -def_bounds(size_t nhists, std::vector<HistogramEntry> &hists, const Varray<T1> &v1, const Varray<T2> &v2, float mv1, float mv2) +def_bounds(size_t numHists, std::vector<HistogramEntry> &hists, Varray<T1> const &v1, Varray<T2> const &v2, float mv1, float mv2) { assert(!v1.empty()); assert(!v2.empty()); - for (size_t i = 0; i < nhists; ++i) + for (size_t i = 0; i < numHists; ++i) { float a = v1[i]; float b = v2[i]; @@ -306,26 +306,26 @@ def_bounds(size_t nhists, std::vector<HistogramEntry> &hists, const Varray<T1> & void HistogramSet::defVarLevelBounds(int varID, int levelID, Field const &field1, Field const &field2) { - if (varID < 0 || varID >= nvars) cdo_abort("Illegal argument: varID %d is undefined (%s)", varID, __func__); + if (varID < 0 || varID >= numVars) cdo_abort("Illegal argument: varID %d is undefined (%s)", varID, __func__); - auto nlevels = this->var_nlevels[varID]; - if (levelID < 0 || levelID >= nlevels) cdo_abort("Illegal argument: levelID %d is undefined (%s)", levelID, __func__); + auto numLevels = this->var_numLevels[varID]; + if (levelID < 0 || levelID >= numLevels) cdo_abort("Illegal argument: levelID %d is undefined (%s)", levelID, __func__); - auto nhists = this->var_nhists[varID]; - if (nhists != gridInqSize(field1.grid) || nhists != gridInqSize(field2.grid)) cdo_abort("Grids are different (%s)", __func__); + auto numHists = this->var_numHists[varID]; + if (numHists != gridInqSize(field1.grid) || numHists != gridInqSize(field2.grid)) cdo_abort("Grids are different (%s)", __func__); auto &hists = this->histograms[varID][levelID]; float mv1 = (float) field1.missval; float mv2 = (float) field2.missval; - auto func = [&](auto const &v1, auto const &v2) { def_bounds(nhists, hists, v1, v2, mv1, mv2); }; + auto func = [&](auto const &v1, auto const &v2) { def_bounds(numHists, hists, v1, v2, mv1, mv2); }; field_operation2(func, field1, field2); } template <typename T> static int -histAddVarLevelValues(size_t nhists, std::vector<HistogramEntry> &hists, Varray<T> const &v, size_t numMissVals, double missval) +histAddVarLevelValues(size_t numHists, std::vector<HistogramEntry> &hists, Varray<T> const &v, size_t numMissVals, double missval) { T mv = missval; assert(!v.empty()); @@ -333,12 +333,12 @@ histAddVarLevelValues(size_t nhists, std::vector<HistogramEntry> &hists, Varray< int nign = 0; if (numMissVals) { - for (size_t i = 0; i < nhists; ++i) + for (size_t i = 0; i < numHists; ++i) if (fp_is_not_equal(v[i], mv)) nign += histAddValue(hists[i], v[i]); } else { - for (size_t i = 0; i < nhists; ++i) nign += histAddValue(hists[i], v[i]); + for (size_t i = 0; i < numHists; ++i) nign += histAddValue(hists[i], v[i]); } return nign; @@ -346,7 +346,7 @@ histAddVarLevelValues(size_t nhists, std::vector<HistogramEntry> &hists, Varray< template <typename T> static int -histSubVarLevelValues(size_t nhists, std::vector<HistogramEntry> &hists, Varray<T> const &v, size_t numMissVals, double missval) +histSubVarLevelValues(size_t numHists, std::vector<HistogramEntry> &hists, Varray<T> const &v, size_t numMissVals, double missval) { T mv = missval; assert(!v.empty()); @@ -354,12 +354,12 @@ histSubVarLevelValues(size_t nhists, std::vector<HistogramEntry> &hists, Varray< int nign = 0; if (numMissVals) { - for (size_t i = 0; i < nhists; ++i) + for (size_t i = 0; i < numHists; ++i) if (fp_is_not_equal(v[i], mv)) nign += histSubValue(hists[i], v[i]); } else { - for (size_t i = 0; i < nhists; ++i) nign += histSubValue(hists[i], v[i]); + for (size_t i = 0; i < numHists; ++i) nign += histSubValue(hists[i], v[i]); } return nign; @@ -368,21 +368,21 @@ histSubVarLevelValues(size_t nhists, std::vector<HistogramEntry> &hists, Varray< int HistogramSet::addVarLevelValues(int varID, int levelID, Field const &field) { - if (varID < 0 || varID >= nvars) cdo_abort("Illegal argument: varID %d is undefined (%s)", varID, __func__); + if (varID < 0 || varID >= numVars) cdo_abort("Illegal argument: varID %d is undefined (%s)", varID, __func__); - auto nlevels = this->var_nlevels[varID]; - if (levelID < 0 || levelID >= nlevels) cdo_abort("Illegal argument: levelID %d is undefined (%s)", levelID, __func__); + auto numLevels = this->var_numLevels[varID]; + if (levelID < 0 || levelID >= numLevels) cdo_abort("Illegal argument: levelID %d is undefined (%s)", levelID, __func__); - auto nhists = this->var_nhists[varID]; - if (nhists != gridInqSize(field.grid)) cdo_abort("Grids are different (%s)", __func__); + auto numHists = this->var_numHists[varID]; + if (numHists != gridInqSize(field.grid)) cdo_abort("Grids are different (%s)", __func__); auto &hists = this->histograms[varID][levelID]; - auto func = [&](auto &v, auto numMissVals, double mv) { return histAddVarLevelValues(nhists, hists, v, numMissVals, mv); }; + auto func = [&](auto &v, auto numMissVals, double mv) { return histAddVarLevelValues(numHists, hists, v, numMissVals, mv); }; auto nign = field_operation(func, field, field.numMissVals, field.missval); if (nign) { - cdo_warning("%d out of %d grid values are out of bounds and have been ignored (%s)", nign, nhists, __func__); + cdo_warning("%d out of %d grid values are out of bounds and have been ignored (%s)", nign, numHists, __func__); return 1; } @@ -392,21 +392,21 @@ HistogramSet::addVarLevelValues(int varID, int levelID, Field const &field) int HistogramSet::subVarLevelValues(int varID, int levelID, Field const &field) { - if (varID < 0 || varID >= nvars) cdo_abort("Illegal argument: varID %d is undefined (%s)", varID, __func__); + if (varID < 0 || varID >= numVars) cdo_abort("Illegal argument: varID %d is undefined (%s)", varID, __func__); - auto nlevels = this->var_nlevels[varID]; - if (levelID < 0 || levelID >= nlevels) cdo_abort("Illegal argument: levelID %d is undefined (%s)", levelID, __func__); + auto numLevels = this->var_numLevels[varID]; + if (levelID < 0 || levelID >= numLevels) cdo_abort("Illegal argument: levelID %d is undefined (%s)", levelID, __func__); - auto nhists = this->var_nhists[varID]; - if (nhists != gridInqSize(field.grid)) cdo_abort("Grids are different (%s)", __func__); + auto numHists = this->var_numHists[varID]; + if (numHists != gridInqSize(field.grid)) cdo_abort("Grids are different (%s)", __func__); auto &hists = this->histograms[varID][levelID]; - auto func = [&](auto &v, auto numMissVals, double mv) { return histSubVarLevelValues(nhists, hists, v, numMissVals, mv); }; + auto func = [&](auto &v, auto numMissVals, double mv) { return histSubVarLevelValues(numHists, hists, v, numMissVals, mv); }; auto nign = field_operation(func, field, field.numMissVals, field.missval); if (nign) { - cdo_warning("%d out of %d grid values are out of bounds and have been ignored (%s)", nign, nhists, __func__); + cdo_warning("%d out of %d grid values are out of bounds and have been ignored (%s)", nign, numHists, __func__); return 1; } @@ -416,33 +416,33 @@ HistogramSet::subVarLevelValues(int varID, int levelID, Field const &field) void HistogramSet::reset(int varID, int levelID) { - assert(nvars > 0); + assert(numVars > 0); - if (varID < 0 || varID >= nvars) cdo_abort("Illegal argument: varID %d is undefined (%s)", varID, __func__); + if (varID < 0 || varID >= numVars) cdo_abort("Illegal argument: varID %d is undefined (%s)", varID, __func__); - auto nlevels = this->var_nlevels[varID]; - assert(nlevels > 0); + auto numLevels = this->var_numLevels[varID]; + assert(numLevels > 0); - if (levelID < 0 || levelID >= nlevels) cdo_abort("Illegal argument: levelID %d is undefined (%s)", levelID, __func__); + if (levelID < 0 || levelID >= numLevels) cdo_abort("Illegal argument: levelID %d is undefined (%s)", levelID, __func__); - auto nhists = this->var_nhists[varID]; - assert(nhists > 0); + auto numHists = this->var_numHists[varID]; + assert(numHists > 0); auto &hists = this->histograms[varID][levelID]; - for (size_t i = 0; i < nhists; ++i) histReset(hists[i]); + for (size_t i = 0; i < numHists; ++i) histReset(hists[i]); } */ template <typename T> static size_t -calcPercentile(size_t nhists, const std::vector<HistogramEntry> &hists, double p, Varray<T> &v, double missval) +calcPercentile(size_t numHists, const std::vector<HistogramEntry> &hists, double p, Varray<T> &v, double missval) { T mv = missval; assert(!v.empty()); size_t numMissVals = 0; - for (size_t i = 0; i < nhists; ++i) + for (size_t i = 0; i < numHists; ++i) { if (hists[i].nsamp) { v[i] = histGetPercentile(hists[i], p); } else @@ -458,16 +458,16 @@ calcPercentile(size_t nhists, const std::vector<HistogramEntry> &hists, double p void HistogramSet::getVarLevelPercentiles(Field &field, int varID, int levelID, double p) { - if (varID < 0 || varID >= nvars) cdo_abort("Illegal argument: varID %d is undefined (%s)", varID, __func__); + if (varID < 0 || varID >= numVars) cdo_abort("Illegal argument: varID %d is undefined (%s)", varID, __func__); - auto nlevels = this->var_nlevels[varID]; - if (levelID < 0 || levelID >= nlevels) cdo_abort("Illegal argument: levelID %d is undefined (%s)", levelID, __func__); + auto numLevels = this->var_numLevels[varID]; + if (levelID < 0 || levelID >= numLevels) cdo_abort("Illegal argument: levelID %d is undefined (%s)", levelID, __func__); - auto nhists = this->var_nhists[varID]; - if (nhists != gridInqSize(field.grid)) cdo_abort("Grids are different (%s)", __func__); + auto numHists = this->var_numHists[varID]; + if (numHists != gridInqSize(field.grid)) cdo_abort("Grids are different (%s)", __func__); auto const &hists = this->histograms[varID][levelID]; - auto func = [&](auto &v, double mv) { return calcPercentile(nhists, hists, p, v, mv); }; + auto func = [&](auto &v, double mv) { return calcPercentile(numHists, hists, p, v, mv); }; field.numMissVals = field_operation(func, field, field.missval); } diff --git a/src/percentiles_hist.h b/src/percentiles_hist.h index 4f9a444c5..14dc48025 100644 --- a/src/percentiles_hist.h +++ b/src/percentiles_hist.h @@ -14,7 +14,7 @@ struct HistogramEntry float step = 0.0f; int nsamp = 0; int capacity = 0; - short nbins = 0; + int numBins = 0; bool isUint32 = false; }; @@ -27,57 +27,57 @@ HistogramSet // clang-format on { private: - int nvars = 0; - int nsteps = 0; - std::vector<int> var_nlevels; - std::vector<size_t> var_nhists; + int numVars = 0; + int numSteps = 0; + std::vector<int> var_numLevels; + std::vector<size_t> var_numHists; std::vector<std::vector<std::vector<HistogramEntry>>> histograms; void init() { - var_nlevels.resize(nvars, 0); - var_nhists.resize(nvars, 0); - histograms.resize(nvars); + var_numLevels.resize(numVars, 0); + var_numHists.resize(numVars, 0); + histograms.resize(numVars); } public: HistogramSet() {} - explicit HistogramSet(int _nvars) : nvars(_nvars) + explicit HistogramSet(int _numVars) : numVars(_numVars) { - assert(nvars > 0); + assert(numVars > 0); init(); } - HistogramSet(int _nvars, int _nsteps) : nvars(_nvars), nsteps(_nsteps) + HistogramSet(int _numVars, int _numSteps) : numVars(_numVars), numSteps(_numSteps) { - assert(nvars > 0); + assert(numVars > 0); init(); } void - create(int _nvars, int _nsteps = 0) + create(int _numVars, int _numSteps = 0) { - nvars = _nvars; - nsteps = _nsteps; - assert(nvars > 0); + numVars = _numVars; + numSteps = _numSteps; + assert(numVars > 0); init(); } ~HistogramSet() { - for (auto varID = nvars; varID-- > 0;) + for (auto varID = numVars; varID-- > 0;) { - auto nhists = this->var_nhists[varID]; - for (auto levelID = this->var_nlevels[varID]; levelID-- > 0;) + auto numHists = this->var_numHists[varID]; + for (auto levelID = this->var_numLevels[varID]; levelID-- > 0;) { - for (auto histID = nhists; histID-- > 0;) std::free(this->histograms[varID][levelID][histID].ptr); + for (auto histID = numHists; histID-- > 0;) std::free(this->histograms[varID][levelID][histID].ptr); } } } - void createVarLevels(int varID, int nlevels, size_t nhists); + void createVarLevels(int varID, int numLevels, size_t numHists); void defVarLevelBounds(int varID, int levelID, Field const &field1, Field const &field2); int addVarLevelValues(int varID, int levelID, Field const &field); int subVarLevelValues(int varID, int levelID, Field const &field); -- GitLab From 09e1eea45ea5717bd4ea0faa764740047c65cda9 Mon Sep 17 00:00:00 2001 From: Uwe Schulzweida <uwe.schulzweida@mpimet.mpg.de> Date: Mon, 17 Mar 2025 13:51:51 +0100 Subject: [PATCH 05/10] Detrend: failed if missing_value is between 0 and numSteps (bug fix) --- ChangeLog | 2 +- NEWS | 5 +++++ src/Detrend.cc | 8 ++++---- src/Trend.cc | 4 ++-- src/field_trend.cc | 6 +++--- 5 files changed, 15 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index 449802dd9..211f29c28 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,6 @@ 2025-03-15 Uwe Schulzweida - * timpctl: Missing error handling for CDO_PCTL_NBINS>32768 (bug fix) + * timpctl: Short integer overflow for CDO_PCTL_NBINS>32768 (bug fix) 2025-03-14 Uwe Schulzweida diff --git a/NEWS b/NEWS index ef15a1a5a..c27aea57a 100644 --- a/NEWS +++ b/NEWS @@ -3,11 +3,16 @@ CDO NEWS Improvement +Version 2.5.2 (15 Mar 2025): + New features: * option --chunkspec to define chunkSize of t and z dimension New operators: * air_density * setchunkspec - Specify chunking + Fixed bugs: + * timpctl: Short integer overflow for CDO_PCTL_NBINS>32768 + * enable-hirlam-extensions failed since release 2.5.1 Version 2.5.1 (5 Mar 2025): diff --git a/src/Detrend.cc b/src/Detrend.cc index c6043e01a..89a1d300f 100644 --- a/src/Detrend.cc +++ b/src/Detrend.cc @@ -129,11 +129,11 @@ public: auto const &zn = work[4][varID][levelID].vec_d; auto trend_kernel = [&](auto i, auto is_EQ) { - auto temp1 = SUBM(sumjx[i], DIVM(MULM(sumj[i], sumx[i]), zn[i])); - auto temp2 = SUBM(sumjj[i], DIVM(MULM(sumj[i], sumj[i]), zn[i])); + auto temp1 = SUBM(sumjx[i], DIVX(MULM(sumj[i], sumx[i]), zn[i])); + auto temp2 = SUBM(sumjj[i], DIVX(MULM(sumj[i], sumj[i]), zn[i])); auto temp3 = DIVM(temp1, temp2); - paramA[i] = SUBM(DIVM(sumx[i], zn[i]), MULM(DIVM(sumj[i], zn[i]), temp3)); + paramA[i] = SUBM(DIVX(sumx[i], zn[i]), MULM(DIVX(sumj[i], zn[i]), temp3)); paramB[i] = temp3; }; @@ -146,7 +146,7 @@ public: } static void - vars_sub_trend(FieldVector3D &work, FieldVector2D &varsData, const VarList &varList, double zj) + vars_sub_trend(FieldVector3D &work, FieldVector2D &varsData, VarList const &varList, double zj) { auto numVars = varList.numVars(); for (int varID = 0; varID < numVars; ++varID) diff --git a/src/Trend.cc b/src/Trend.cc index 9c9099163..ea2badeb0 100644 --- a/src/Trend.cc +++ b/src/Trend.cc @@ -123,7 +123,7 @@ public: } void - write_output(const FieldVector3D &work) + write_output(FieldVector3D const &work) { Field field2, field3; @@ -198,7 +198,7 @@ public: } static void - fields_calc_trend_sum(FieldVector3D &work, const FieldVector2D &fields2D, const std::vector<FieldInfo> &fieldInfoList, + fields_calc_trend_sum(FieldVector3D &work, FieldVector2D const &fields2D, std::vector<FieldInfo> const &fieldInfoList, double zj) noexcept { for (auto const &fieldInfo : fieldInfoList) diff --git a/src/field_trend.cc b/src/field_trend.cc index 9155952d0..a1da6d78d 100644 --- a/src/field_trend.cc +++ b/src/field_trend.cc @@ -99,11 +99,11 @@ calc_trend_param(const FieldVector3D &work, Field ¶mA, Field ¶mB, int va auto const &zn = work[4][varID][levelID].vec_d; auto trend_kernel = [&](auto i, auto is_EQ) { - auto temp1 = SUBM(sumjx[i], DIVM(MULM(sumj[i], sumx[i]), zn[i])); - auto temp2 = SUBM(sumjj[i], DIVM(MULM(sumj[i], sumj[i]), zn[i])); + auto temp1 = SUBM(sumjx[i], DIVX(MULM(sumj[i], sumx[i]), zn[i])); + auto temp2 = SUBM(sumjj[i], DIVX(MULM(sumj[i], sumj[i]), zn[i])); auto temp3 = DIVM(temp1, temp2); - paramA.vec_d[i] = SUBM(DIVM(sumx[i], zn[i]), MULM(DIVM(sumj[i], zn[i]), temp3)); + paramA.vec_d[i] = SUBM(DIVX(sumx[i], zn[i]), MULM(DIVX(sumj[i], zn[i]), temp3)); paramB.vec_d[i] = temp3; }; -- GitLab From 4bc11fcc3b2a20846286bc0ed873026bafd84158 Mon Sep 17 00:00:00 2001 From: Uwe Schulzweida <uwe.schulzweida@mpimet.mpg.de> Date: Mon, 17 Mar 2025 14:24:36 +0100 Subject: [PATCH 06/10] Replace DIVM() by DIVX() --- src/Timstat2.cc | 10 +++++----- src/Timstat3.cc | 22 +++++++++++----------- src/fieldc.cc | 4 ++-- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/Timstat2.cc b/src/Timstat2.cc index fc688dfe2..873933689 100644 --- a/src/Timstat2.cc +++ b/src/Timstat2.cc @@ -99,11 +99,11 @@ correlation(size_t gridsize, double missval, const Varray<size_t> &nofvals, Varr { double dnvals = nvals; auto temp0 = MULM(work[0][i], work[1][i]); - auto temp1 = SUBM(work[4][i], DIVM(temp0, dnvals)); + auto temp1 = SUBM(work[4][i], DIVX(temp0, dnvals)); auto temp2 = MULM(work[0][i], work[0][i]); auto temp3 = MULM(work[1][i], work[1][i]); - auto temp4 = SUBM(work[2][i], DIVM(temp2, dnvals)); - auto temp5 = SUBM(work[3][i], DIVM(temp3, dnvals)); + auto temp4 = SUBM(work[2][i], DIVX(temp2, dnvals)); + auto temp5 = SUBM(work[3][i], DIVX(temp3, dnvals)); auto temp6 = MULM(temp4, temp5); cor = DIVM(temp1, SQRTM(temp6)); @@ -194,8 +194,8 @@ covariance(size_t gridsize, double missval, const Varray<size_t> &nofvals, Varra if (nvals > 0) { double dnvals = nvals; - auto temp = DIVM(MULM(work[0][i], work[1][i]), dnvals * dnvals); - covar = SUBM(DIVM(work[2][i], dnvals), temp); + auto temp = DIVX(MULM(work[0][i], work[1][i]), dnvals * dnvals); + covar = SUBM(DIVX(work[2][i], dnvals), temp); if (fp_is_equal(covar, missval)) numMissVals++; } else diff --git a/src/Timstat3.cc b/src/Timstat3.cc index 86e954305..819978fae 100644 --- a/src/Timstat3.cc +++ b/src/Timstat3.cc @@ -29,8 +29,8 @@ varquot2test(double rconst, double risk, size_t gridsize, double missval, Varray auto missval2 = missval; auto varquot2test_kernel = [&](auto i, auto is_EQ) { - auto temp0 = DIVM(MULM(work[0][i], work[0][i]), work[2][i]); - auto temp1 = DIVM(MULM(work[3][i], work[3][i]), work[5][i]); + auto temp0 = DIVX(MULM(work[0][i], work[0][i]), work[2][i]); + auto temp1 = DIVX(MULM(work[3][i], work[3][i]), work[5][i]); auto temp2 = SUBM(work[1][i], temp0); auto temp3 = SUBM(work[4][i], temp1); auto statistic = DIVM(temp2, ADDM(temp2, MULM(rconst, temp3))); @@ -64,23 +64,23 @@ meandiff2test(double rconst, double risk, size_t gridsize, double missval, Varra auto meandiff2test_kernel = [&](auto i, auto is_EQ) { double temp0 = 0.0; double degOfFreedom = -NIN; - auto tmp = DIVM(MULM(work[0][i], work[0][i]), work[2][i]); - temp0 = ADDM(temp0, DIVM(SUBM(work[1][i], tmp), varFactor[0])); + auto tmp = DIVX(MULM(work[0][i], work[0][i]), work[2][i]); + temp0 = ADDM(temp0, DIVX(SUBM(work[1][i], tmp), varFactor[0])); degOfFreedom = ADDM(degOfFreedom, work[2][i]); - tmp = DIVM(MULM(work[3][i], work[3][i]), work[5][i]); - temp0 = ADDM(temp0, DIVM(SUBM(work[4][i], tmp), varFactor[1])); + tmp = DIVX(MULM(work[3][i], work[3][i]), work[5][i]); + temp0 = ADDM(temp0, DIVX(SUBM(work[4][i], tmp), varFactor[1])); degOfFreedom = ADDM(degOfFreedom, work[5][i]); if (fp_is_not_equal(temp0, missval1) && temp0 < 0) temp0 = 0; // This is possible because of rounding errors - auto stddevEstimator = SQRTM(DIVM(temp0, degOfFreedom)); + auto stddevEstimator = SQRTM(DIVX(temp0, degOfFreedom)); auto meanEstimator = -rconst; - meanEstimator = ADDM(meanEstimator, MULM(meanFactor[0], DIVM(work[0][i], work[2][i]))); - meanEstimator = ADDM(meanEstimator, MULM(meanFactor[1], DIVM(work[3][i], work[5][i]))); + meanEstimator = ADDM(meanEstimator, MULM(meanFactor[0], DIVX(work[0][i], work[2][i]))); + meanEstimator = ADDM(meanEstimator, MULM(meanFactor[1], DIVX(work[3][i], work[5][i]))); double temp1 = 0.0; - temp1 = ADDM(temp1, DIVM(factor1, work[2][i])); - temp1 = ADDM(temp1, DIVM(factor2, work[5][i])); + temp1 = ADDM(temp1, DIVX(factor1, work[2][i])); + temp1 = ADDM(temp1, DIVX(factor2, work[5][i])); auto norm = SQRTM(temp1); auto temp2 = DIVM(DIVM(meanEstimator, norm), stddevEstimator); diff --git a/src/fieldc.cc b/src/fieldc.cc index 6c9e8d093..995219107 100644 --- a/src/fieldc.cc +++ b/src/fieldc.cc @@ -40,11 +40,11 @@ fieldc_div(Varray<T> &v, size_t len, size_t numMissVals, double missval, double { auto is_EQ = fp_is_equal; T missval1 = missval; - T missval2 = missval; + // T missval2 = missval; if (numMissVals || is_equal(rconst, 0)) { - for (size_t i = 0; i < len; ++i) v[i] = DIVM(v[i], rconst); + for (size_t i = 0; i < len; ++i) v[i] = DIVX(v[i], rconst); if (is_equal(rconst, 0)) numMissVals = len; } -- GitLab From 01671651e584b67c2cfa185cadeb9735a5bee2fc Mon Sep 17 00:00:00 2001 From: Uwe Schulzweida <uwe.schulzweida@mpimet.mpg.de> Date: Mon, 17 Mar 2025 20:26:56 +0100 Subject: [PATCH 07/10] Replaced DIVX() by DIVMX() --- src/Detrend.cc | 6 +++--- src/Timstat2.cc | 10 +++++----- src/Timstat3.cc | 22 +++++++++++----------- src/arithmetic.h | 2 ++ src/field_trend.cc | 6 +++--- src/fieldc.cc | 2 +- 6 files changed, 25 insertions(+), 23 deletions(-) diff --git a/src/Detrend.cc b/src/Detrend.cc index 89a1d300f..ce349c32c 100644 --- a/src/Detrend.cc +++ b/src/Detrend.cc @@ -129,11 +129,11 @@ public: auto const &zn = work[4][varID][levelID].vec_d; auto trend_kernel = [&](auto i, auto is_EQ) { - auto temp1 = SUBM(sumjx[i], DIVX(MULM(sumj[i], sumx[i]), zn[i])); - auto temp2 = SUBM(sumjj[i], DIVX(MULM(sumj[i], sumj[i]), zn[i])); + auto temp1 = SUBM(sumjx[i], DIVMX(MULM(sumj[i], sumx[i]), zn[i])); + auto temp2 = SUBM(sumjj[i], DIVMX(MULM(sumj[i], sumj[i]), zn[i])); auto temp3 = DIVM(temp1, temp2); - paramA[i] = SUBM(DIVX(sumx[i], zn[i]), MULM(DIVX(sumj[i], zn[i]), temp3)); + paramA[i] = SUBM(DIVMX(sumx[i], zn[i]), MULM(DIVMX(sumj[i], zn[i]), temp3)); paramB[i] = temp3; }; diff --git a/src/Timstat2.cc b/src/Timstat2.cc index 873933689..fb6a10024 100644 --- a/src/Timstat2.cc +++ b/src/Timstat2.cc @@ -99,11 +99,11 @@ correlation(size_t gridsize, double missval, const Varray<size_t> &nofvals, Varr { double dnvals = nvals; auto temp0 = MULM(work[0][i], work[1][i]); - auto temp1 = SUBM(work[4][i], DIVX(temp0, dnvals)); + auto temp1 = SUBM(work[4][i], DIVMX(temp0, dnvals)); auto temp2 = MULM(work[0][i], work[0][i]); auto temp3 = MULM(work[1][i], work[1][i]); - auto temp4 = SUBM(work[2][i], DIVX(temp2, dnvals)); - auto temp5 = SUBM(work[3][i], DIVX(temp3, dnvals)); + auto temp4 = SUBM(work[2][i], DIVMX(temp2, dnvals)); + auto temp5 = SUBM(work[3][i], DIVMX(temp3, dnvals)); auto temp6 = MULM(temp4, temp5); cor = DIVM(temp1, SQRTM(temp6)); @@ -194,8 +194,8 @@ covariance(size_t gridsize, double missval, const Varray<size_t> &nofvals, Varra if (nvals > 0) { double dnvals = nvals; - auto temp = DIVX(MULM(work[0][i], work[1][i]), dnvals * dnvals); - covar = SUBM(DIVX(work[2][i], dnvals), temp); + auto temp = DIVMX(MULM(work[0][i], work[1][i]), dnvals * dnvals); + covar = SUBM(DIVMX(work[2][i], dnvals), temp); if (fp_is_equal(covar, missval)) numMissVals++; } else diff --git a/src/Timstat3.cc b/src/Timstat3.cc index 819978fae..ca8869b70 100644 --- a/src/Timstat3.cc +++ b/src/Timstat3.cc @@ -29,8 +29,8 @@ varquot2test(double rconst, double risk, size_t gridsize, double missval, Varray auto missval2 = missval; auto varquot2test_kernel = [&](auto i, auto is_EQ) { - auto temp0 = DIVX(MULM(work[0][i], work[0][i]), work[2][i]); - auto temp1 = DIVX(MULM(work[3][i], work[3][i]), work[5][i]); + auto temp0 = DIVMX(MULM(work[0][i], work[0][i]), work[2][i]); + auto temp1 = DIVMX(MULM(work[3][i], work[3][i]), work[5][i]); auto temp2 = SUBM(work[1][i], temp0); auto temp3 = SUBM(work[4][i], temp1); auto statistic = DIVM(temp2, ADDM(temp2, MULM(rconst, temp3))); @@ -64,23 +64,23 @@ meandiff2test(double rconst, double risk, size_t gridsize, double missval, Varra auto meandiff2test_kernel = [&](auto i, auto is_EQ) { double temp0 = 0.0; double degOfFreedom = -NIN; - auto tmp = DIVX(MULM(work[0][i], work[0][i]), work[2][i]); - temp0 = ADDM(temp0, DIVX(SUBM(work[1][i], tmp), varFactor[0])); + auto tmp = DIVMX(MULM(work[0][i], work[0][i]), work[2][i]); + temp0 = ADDM(temp0, DIVMX(SUBM(work[1][i], tmp), varFactor[0])); degOfFreedom = ADDM(degOfFreedom, work[2][i]); - tmp = DIVX(MULM(work[3][i], work[3][i]), work[5][i]); - temp0 = ADDM(temp0, DIVX(SUBM(work[4][i], tmp), varFactor[1])); + tmp = DIVMX(MULM(work[3][i], work[3][i]), work[5][i]); + temp0 = ADDM(temp0, DIVMX(SUBM(work[4][i], tmp), varFactor[1])); degOfFreedom = ADDM(degOfFreedom, work[5][i]); if (fp_is_not_equal(temp0, missval1) && temp0 < 0) temp0 = 0; // This is possible because of rounding errors - auto stddevEstimator = SQRTM(DIVX(temp0, degOfFreedom)); + auto stddevEstimator = SQRTM(DIVMX(temp0, degOfFreedom)); auto meanEstimator = -rconst; - meanEstimator = ADDM(meanEstimator, MULM(meanFactor[0], DIVX(work[0][i], work[2][i]))); - meanEstimator = ADDM(meanEstimator, MULM(meanFactor[1], DIVX(work[3][i], work[5][i]))); + meanEstimator = ADDM(meanEstimator, MULM(meanFactor[0], DIVMX(work[0][i], work[2][i]))); + meanEstimator = ADDM(meanEstimator, MULM(meanFactor[1], DIVMX(work[3][i], work[5][i]))); double temp1 = 0.0; - temp1 = ADDM(temp1, DIVX(factor1, work[2][i])); - temp1 = ADDM(temp1, DIVX(factor2, work[5][i])); + temp1 = ADDM(temp1, DIVMX(factor1, work[2][i])); + temp1 = ADDM(temp1, DIVMX(factor2, work[5][i])); auto norm = SQRTM(temp1); auto temp2 = DIVM(DIVM(meanEstimator, norm), stddevEstimator); diff --git a/src/arithmetic.h b/src/arithmetic.h index 600117b93..2b4e9f3d4 100644 --- a/src/arithmetic.h +++ b/src/arithmetic.h @@ -20,6 +20,7 @@ const auto mulm = [](auto x, auto y, auto mvx, auto mvy, auto is_EQ) { return (i const auto divm = [](auto x, auto y, auto mvx, auto mvy, auto is_EQ) { return (is_EQ(x, mvx) || is_EQ(y, mvy) || is_EQ(y, 0)) ? mvx : x / y; }; const auto powm = [](auto x, auto y, auto mvx, auto mvy, auto is_EQ) { return (is_EQ(x, mvx) || is_EQ(y, mvy)) ? mvx : std::pow(x, y); }; const auto sqrtm = [](auto x, auto mvx, auto is_EQ) { return (is_EQ(x, mvx) || x < 0) ? mvx : std::sqrt(x); }; +const auto divmx = [](auto x, auto y, auto mvx, auto is_EQ) { return (is_EQ(x, mvx) || is_EQ(y, 0)) ? mvx : x / y; }; const auto divx = [](auto x, auto y, auto mvx, auto is_EQ) { return is_EQ(y, 0) ? mvx : x / y; }; } @@ -36,6 +37,7 @@ const auto SQRT = arithmetic::sqrt; #define DIVM(x, y) arithmetic::divm(x, y, missval1, missval2, is_EQ) #define POWM(x, y) arithmetic::powm(x, y, missval1, missval2, is_EQ) #define SQRTM(x) arithmetic::sqrtm(x, missval1, is_EQ) +#define DIVMX(x, y) arithmetic::divmx(x, y, missval1, is_EQ) #define DIVX(x, y) arithmetic::divx(x, y, missval1, is_EQ) // clang-format on diff --git a/src/field_trend.cc b/src/field_trend.cc index a1da6d78d..4800e9c76 100644 --- a/src/field_trend.cc +++ b/src/field_trend.cc @@ -99,11 +99,11 @@ calc_trend_param(const FieldVector3D &work, Field ¶mA, Field ¶mB, int va auto const &zn = work[4][varID][levelID].vec_d; auto trend_kernel = [&](auto i, auto is_EQ) { - auto temp1 = SUBM(sumjx[i], DIVX(MULM(sumj[i], sumx[i]), zn[i])); - auto temp2 = SUBM(sumjj[i], DIVX(MULM(sumj[i], sumj[i]), zn[i])); + auto temp1 = SUBM(sumjx[i], DIVMX(MULM(sumj[i], sumx[i]), zn[i])); + auto temp2 = SUBM(sumjj[i], DIVMX(MULM(sumj[i], sumj[i]), zn[i])); auto temp3 = DIVM(temp1, temp2); - paramA.vec_d[i] = SUBM(DIVX(sumx[i], zn[i]), MULM(DIVX(sumj[i], zn[i]), temp3)); + paramA.vec_d[i] = SUBM(DIVMX(sumx[i], zn[i]), MULM(DIVMX(sumj[i], zn[i]), temp3)); paramB.vec_d[i] = temp3; }; diff --git a/src/fieldc.cc b/src/fieldc.cc index 995219107..ef7008490 100644 --- a/src/fieldc.cc +++ b/src/fieldc.cc @@ -44,7 +44,7 @@ fieldc_div(Varray<T> &v, size_t len, size_t numMissVals, double missval, double if (numMissVals || is_equal(rconst, 0)) { - for (size_t i = 0; i < len; ++i) v[i] = DIVX(v[i], rconst); + for (size_t i = 0; i < len; ++i) v[i] = DIVMX(v[i], rconst); if (is_equal(rconst, 0)) numMissVals = len; } -- GitLab From 3319914180020899cba3084ef5c3647650eb6ba8 Mon Sep 17 00:00:00 2001 From: Uwe Schulzweida <uwe.schulzweida@mpimet.mpg.de> Date: Thu, 20 Mar 2025 14:08:16 +0100 Subject: [PATCH 08/10] grid_gme: cleanup --- src/Timstat2.cc | 2 +- src/Vertintml.cc | 6 +- src/grid_gme.cc | 305 ++++++++++++++++-------------------- src/knndata.cc | 2 +- src/percentiles.cc | 4 +- src/printinfo.cc | 14 +- src/remap_method_conserv.cc | 2 +- src/statistic.cc | 2 +- 8 files changed, 148 insertions(+), 189 deletions(-) diff --git a/src/Timstat2.cc b/src/Timstat2.cc index fb6a10024..c10304d97 100644 --- a/src/Timstat2.cc +++ b/src/Timstat2.cc @@ -111,7 +111,7 @@ correlation(size_t gridsize, double missval, const Varray<size_t> &nofvals, Varr if (fp_is_equal(cor, missval)) numMissVals++; - pvalue = (nvals <= 2) ? missval : ((fabs(cor) < 1) ? calc_pvalue(cor, nvals) : 1); + pvalue = (nvals <= 2) ? missval : ((std::fabs(cor) < 1) ? calc_pvalue(cor, nvals) : 1); } else { diff --git a/src/Vertintml.cc b/src/Vertintml.cc index 377325442..8fd50db07 100644 --- a/src/Vertintml.cc +++ b/src/Vertintml.cc @@ -83,7 +83,7 @@ static void check_range(double rmin, double rmax, ForwardIt first, ForwardIt last, std::string const &name) { const auto [min, max] = std::minmax_element(first, last); - if (fabs(*max - *min) <= 1.0e-9 || (*min < rmin) || (*max > rmax)) + if (std::fabs(*max - *min) <= 1.0e-9 || (*min < rmin) || (*max > rmax)) cdo_warning("%s out of range (%g - %g) min=%g max=%g", name, rmin, rmax, *min, *max); } @@ -459,7 +459,7 @@ pressure_level_interpolation(Varray<double> &pressureLevels, bool useHeightLevel { cdo_def_field(streamID2, varID, levelID); cdo_write_field(streamID2, interpVars[varID] ? vardata2[varID] : vardata1[varID], levelID, - varnumMissVals[varID][levelID]); + varnumMissVals[varID][levelID]); } } } @@ -667,7 +667,7 @@ height_level_interpolation(Varray<double> &heightLevels, bool extrapolate) { cdo_def_field(streamID2, varID, levelID); cdo_write_field(streamID2, interpVars[varID] ? vardata2[varID] : vardata1[varID], levelID, - varnumMissVals[varID][levelID]); + varnumMissVals[varID][levelID]); } } } diff --git a/src/grid_gme.cc b/src/grid_gme.cc index 8d50127c6..a7ddc92a3 100644 --- a/src/grid_gme.cc +++ b/src/grid_gme.cc @@ -26,7 +26,7 @@ struct array struct cart { - double x[3] = { 0 }; + double x[3] = { 0, 0, 0 }; }; struct geo @@ -42,15 +42,15 @@ struct polygon struct geo boundary[6]; }; -static const double pid5 = 0.2 * M_PI; -// const double pid180 = 180.0/M_PI; +constexpr double pid5 = 0.2 * M_PI; +// constexpr double pid180 = 180.0/M_PI; -static const int ispokes[12] = { +constexpr int ispokes[12] = { 1, 0, -1, -1, 0, 1, 0, 1, 1, 0, -1, -1, }; -static const int pentagon = 5; -static const int hexagon = 6; +constexpr int pentagon = 5; +constexpr int hexagon = 6; /*****************************************************************************/ @@ -92,16 +92,11 @@ gme_factorni(int kni, int *kni2, int *kni3) *kni3 = *kni3 + 1; mx = mx / 3; } - else - { /* error return */ - } + else { /* error return */ } } - /* kni3 must not be greater than */ - - if (*kni3 > 1) - { /* error return */ - } + // kni3 must not be greater than + if (*kni3 > 1) { /* error return */ } } /*****************************************************************************/ @@ -109,14 +104,14 @@ gme_factorni(int kni, int *kni2, int *kni3) static int pow_ii(int x, int n) { - int pow; - if (n <= 0) { if (n == 0 || x == 1) return 1; if (x != -1) return (x == 0) ? 1 / x : 0; n = -n; } + + int pow; for (pow = 1;;) { if (n & 01) pow *= x; @@ -139,9 +134,9 @@ circum_center(struct cart *v0, struct cart *v1, struct cart *v2) struct cart e2; struct cart cu; - double *ptmp1 = ((double *) e1.x); - double *ptmp2 = ((double *) v1->x); - double *ptmp3 = ((double *) v0->x); + double *ptmp1 = e1.x; + double *ptmp2 = v1->x; + double *ptmp3 = v0->x; for (int j = 0; j < 3; ++j) { @@ -153,9 +148,9 @@ circum_center(struct cart *v0, struct cart *v1, struct cart *v2) ptmp2++; } - ptmp1 = ((double *) e2.x); - ptmp2 = ((double *) v2->x); - ptmp3 = ((double *) v0->x); + ptmp1 = e2.x; + ptmp2 = v2->x; + ptmp3 = v0->x; for (int j = 0; j < 3; ++j) { { @@ -170,10 +165,10 @@ circum_center(struct cart *v0, struct cart *v1, struct cart *v2) cu.x[1] = e1.x[2] * e2.x[0] - e1.x[0] * e2.x[2]; cu.x[2] = e1.x[0] * e2.x[1] - e1.x[1] * e2.x[0]; - const auto cnorm = std::sqrt(cu.x[0] * cu.x[0] + cu.x[1] * cu.x[1] + cu.x[2] * cu.x[2]); + auto cnorm = std::sqrt(cu.x[0] * cu.x[0] + cu.x[1] * cu.x[1] + cu.x[2] * cu.x[2]); - ptmp1 = ((double *) center.x); - ptmp2 = ((double *) cu.x); + ptmp1 = center.x; + ptmp2 = cu.x; for (int j = 0; j < 3; ++j) { { @@ -191,10 +186,10 @@ circum_center(struct cart *v0, struct cart *v1, struct cart *v2) static struct cart gc2cc(struct geo *position) { - const auto sln = std::sin(position->lon); - const auto cln = std::cos(position->lon); - const auto slt = std::sin(position->lat); - const auto clt = std::cos(position->lat); + auto sln = std::sin(position->lon); + auto cln = std::cos(position->lon); + auto slt = std::sin(position->lat); + auto clt = std::cos(position->lat); struct cart x; x.x[0] = cln * clt; @@ -211,21 +206,21 @@ cc2gc(struct cart *x) { struct geo position; - if (fabs(x->x[0]) <= 0.0) { position.lon = (x->x[1] >= 0.0) ? 0.5 * M_PI : 1.5 * M_PI; } + if (std::fabs(x->x[0]) <= 0.0) { position.lon = (x->x[1] >= 0.0) ? 0.5 * M_PI : 1.5 * M_PI; } else { - const auto tln = x->x[1] / x->x[0]; + auto tln = x->x[1] / x->x[0]; position.lon = std::atan(tln); if (x->x[0] < 0.0) position.lon += M_PI; if (position.lon < 0.0) position.lon += 2 * M_PI; } - const auto r = std::sqrt(x->x[0] * x->x[0] + x->x[1] * x->x[1]); + auto r = std::sqrt(x->x[0] * x->x[0] + x->x[1] * x->x[1]); - if (fabs(r) <= 0.0) { position.lat = (x->x[2] > 0.0) ? 0.5 * M_PI : -0.5 * M_PI; } + if (std::fabs(r) <= 0.0) { position.lat = (x->x[2] > 0.0) ? 0.5 * M_PI : -0.5 * M_PI; } else { - const auto tlt = x->x[2] / r; + auto tlt = x->x[2] / r; position.lat = std::atan(tlt); } @@ -244,7 +239,6 @@ boundary(struct polygon *poly, int kip1s, int kip1e, int kip2s, int kip2e, int k struct cart x2; struct cart v[6]; - int j1, j2, jd; int jm, jm1, jm2; struct array polyinfo; @@ -276,11 +270,11 @@ boundary(struct polygon *poly, int kip1s, int kip1e, int kip2s, int kip2e, int k tmp5 = polyinfo.dim[2].mult; tmp3 = polyinfo.offset; - for (jd = 1; jd <= knd; jd++) + for (int jd = 1; jd <= knd; jd++) { - for (j2 = kip2s; j2 <= kip2e; ++j2) + for (int j2 = kip2s; j2 <= kip2e; ++j2) { - for (j1 = kip1s; j1 <= kip1e; ++j1) + for (int j1 = kip1s; j1 <= kip1e; ++j1) { ptmp1 = &poly[j1 + tmp4 * j2 + tmp5 * jd + tmp3]; c = gc2cc(&ptmp1->center); @@ -311,9 +305,6 @@ neighbours(double *px1, double *px2, int kipx1s, int kipx1e, int kipx2s, int kip int kip1e, int kip2s, int kip2e, int knd) { struct polygon *ptmp1; - - int j1, j2, jd, jm, js1, js2; - struct array px1info, px2info, polyinfo; int tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9; @@ -394,26 +385,22 @@ neighbours(double *px1, double *px2, int kipx1s, int kipx1e, int kipx2s, int kip tmp15 = polyinfo.dim[2].mult; tmp13 = polyinfo.offset; - for (jd = 1; jd <= kndx; jd++) + for (int jd = 1; jd <= kndx; jd++) { - for (j2 = kipx2s + 1; j2 <= kipx2e - 1; ++j2) + for (int j2 = kipx2s + 1; j2 <= kipx2e - 1; ++j2) { - for (j1 = kipx1s + 1; j1 <= kipx1e - 1; ++j1) + for (int j1 = kipx1s + 1; j1 <= kipx1e - 1; ++j1) { - ptmp1 = &poly[j1 + tmp14 * j2 + tmp15 * jd + tmp13]; - ptmp1->center.lon = px1[j1 + tmp4 * j2 + tmp5 * jd + tmp3]; ptmp1->center.lat = px2[j1 + tmp9 * j2 + tmp10 * jd + tmp8]; if (j1 == kipx1s + 1 && j2 == kipx2s + 1) { - ptmp1->type = pentagon; - for (jm = 1; jm <= 5; jm++) + for (int jm = 1; jm <= 5; jm++) { - if (jd < 6) { ptmp1->boundary[jm - 1].lon = px1[kipx1s + 1 + tmp4 * (kipx2s + 2) + tmp5 * (jm) + tmp3]; @@ -428,7 +415,6 @@ neighbours(double *px1, double *px2, int kipx1s, int kipx1e, int kipx2s, int kip } else if (j1 == kipx1e - 1 && j2 == kipx2s + 1) { - ptmp1->type = pentagon; ptmp1->boundary[0].lon = px1[kipx1e - 1 + tmp4 * (kipx2s + 2) + tmp5 * jd + tmp3]; @@ -444,7 +430,6 @@ neighbours(double *px1, double *px2, int kipx1s, int kipx1e, int kipx2s, int kip } else if (j1 == kipx1s + 1 && j2 == kipx2e - 1) { - ptmp1->type = pentagon; ptmp1->boundary[0].lon = px1[kipx1s + 2 + tmp4 * (kipx2e - 2) + tmp5 * jd + tmp3]; @@ -460,7 +445,6 @@ neighbours(double *px1, double *px2, int kipx1s, int kipx1e, int kipx2s, int kip } else if (j1 == kipx1e - 1 && j2 == kipx2e - 1) { - ptmp1->type = pentagon; ptmp1->boundary[0].lon = px1[kipx1e + tmp4 * (kipx2e) + tmp5 * jd + tmp3]; @@ -476,15 +460,12 @@ neighbours(double *px1, double *px2, int kipx1s, int kipx1e, int kipx2s, int kip } else { - - for (jm = 1; jm <= 6; jm++) + for (int jm = 1; jm <= 6; jm++) { - ptmp1->type = hexagon; - js1 = j1 + ispokes[jm - 1]; - js2 = j2 + ispokes[jm + 5]; - + int js1 = j1 + ispokes[jm - 1]; + int js2 = j2 + ispokes[jm + 5]; ptmp1->boundary[jm - 1].lon = px1[js1 + tmp4 * js2 + tmp5 * jd + tmp3]; ptmp1->boundary[jm - 1].lat = px2[js1 + tmp9 * js2 + tmp10 * jd + tmp8]; } @@ -502,10 +483,6 @@ static void xd(double *p, int kip1s, int kip1e, int kip2s, int kip2e, int knd, double *px, int kipx1s, int kipx1e, int kipx2s, int kipx2e, int kndx) { - int mi1sm1, mi1ep1, mi2sm1, mi2ep1; - int mns, mpe, mpw, maw, mae, mpp; - int j, j1, j2, jd; - struct array pinfo, pxinfo; int tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9, tmp10; @@ -563,28 +540,28 @@ xd(double *p, int kip1s, int kip1e, int kip2s, int kip2e, int knd, double *px, i // tmp2 = pxinfo.dim[1].extent; // tmp6 = pxinfo.dim[2].extent; - for (jd = 1; jd <= knd; jd++) + for (int jd = 1; jd <= knd; jd++) { - for (j2 = kip2s; j2 <= kip2e; ++j2) + for (int j2 = kip2s; j2 <= kip2e; ++j2) { - for (j1 = kip1s; j1 <= kip1e; ++j1) { px[j1 + tmp9 * j2 + tmp10 * jd + tmp8] = p[j1 + tmp4 * j2 + tmp5 * jd + tmp3]; } + for (int j1 = kip1s; j1 <= kip1e; ++j1) { px[j1 + tmp9 * j2 + tmp10 * jd + tmp8] = p[j1 + tmp4 * j2 + tmp5 * jd + tmp3]; } } } - mi1sm1 = kip1s - 1; - mi1ep1 = kip1e + 1; - mi2sm1 = kip2s - 1; - mi2ep1 = kip2e + 1; + int mi1sm1 = kip1s - 1; + int mi1ep1 = kip1e + 1; + int mi2sm1 = kip2s - 1; + int mi2ep1 = kip2e + 1; - for (jd = 1; jd <= knd; jd++) + for (int jd = 1; jd <= knd; jd++) { - mns = (jd - 1) / 5; - mpe = jd + 1 - (jd / (5 * (1 + mns))) * 5; - mpw = jd - 1 + ((mns * 10 + 6 - jd) / (5 * (1 + mns))) * 5; - mae = jd + 5 - 9 * mns - 5 * (jd / 10); - maw = jd + 4 + ((6 - jd) / 5) * 5 - 9 * mns; - mpp = jd + 3 - ((jd + 2) / 5) * 5 + 5 * mns; - for (j = kip2s; j <= kip1e; ++j) + int mns = (jd - 1) / 5; + int mpe = jd + 1 - (jd / (5 * (1 + mns))) * 5; + int mpw = jd - 1 + ((mns * 10 + 6 - jd) / (5 * (1 + mns))) * 5; + int mae = jd + 5 - 9 * mns - 5 * (jd / 10); + int maw = jd + 4 + ((6 - jd) / 5) * 5 - 9 * mns; + int mpp = jd + 3 - ((jd + 2) / 5) * 5 + 5 * mns; + for (int j = kip2s; j <= kip1e; ++j) { px[j + tmp9 * mi2sm1 + tmp10 * jd + tmp8] = p[kip1s + 1 + tmp4 * j + tmp5 * mpw + tmp3]; px[mi1sm1 + tmp9 * (j + 1) + tmp10 * jd + tmp8] = p[j - 1 + tmp4 * (kip2s + 1) + tmp5 * mpe + tmp3]; @@ -613,10 +590,6 @@ static void tricntr(double *pxn, int kig1s, int kig1e, int kig2s, int kig2e, int knd, int kjd, int kni) { (void) knd; - double r1, r2, r3; - - int mi1, mi2; - double zxnorm; int id1 = kig1e - kig1s + 1; int id2 = id1 * (kig2e - kig2s + 1); @@ -625,8 +598,8 @@ tricntr(double *pxn, int kig1s, int kig1e, int kig2s, int kig2e, int knd, int kj for (int j = 1; j <= 2; ++j) { - mi1 = j * kni / 3; - mi2 = (j - 1) * kni + 1; + int mi1 = j * kni / 3; + int mi2 = (j - 1) * kni + 1; pxn[mi1 + id1 * (mi1 + 1) + id2 * 1 + id3 * kjd + ioffset] = pxn[mi2 - 1 + id1 * (mi2) + id2 * 1 + id3 * kjd + ioffset] + pxn[kni + id1 * 1 + id2 * 1 + id3 * kjd + ioffset] + pxn[0 + id1 * (kni + 1) + id2 * 1 + id3 * kjd + ioffset]; @@ -638,10 +611,10 @@ tricntr(double *pxn, int kig1s, int kig1e, int kig2s, int kig2e, int knd, int kj + pxn[0 + id1 * (kni + 1) + id2 * 3 + id3 * kjd + ioffset]; /* Normalize to unit-sphere */ - r1 = pxn[mi1 + id1 * (mi1 + 1) + id2 * 1 + id3 * kjd + ioffset]; - r2 = pxn[mi1 + id1 * (mi1 + 1) + id2 * 2 + id3 * kjd + ioffset]; - r3 = pxn[mi1 + id1 * (mi1 + 1) + id2 * 3 + id3 * kjd + ioffset]; - zxnorm = 1.0 / std::sqrt(r1 * r1 + r2 * r2 + r3 * r3); + double r1 = pxn[mi1 + id1 * (mi1 + 1) + id2 * 1 + id3 * kjd + ioffset]; + double r2 = pxn[mi1 + id1 * (mi1 + 1) + id2 * 2 + id3 * kjd + ioffset]; + double r3 = pxn[mi1 + id1 * (mi1 + 1) + id2 * 3 + id3 * kjd + ioffset]; + double zxnorm = 1.0 / std::sqrt(r1 * r1 + r2 * r2 + r3 * r3); pxn[mi1 + id1 * (mi1 + 1) + id2 * 1 + id3 * kjd + ioffset] = zxnorm * pxn[mi1 + id1 * (mi1 + 1) + id2 * 1 + id3 * kjd + ioffset]; @@ -675,15 +648,14 @@ gcpt(double *pxn, int kig1s, int kig1e, int kig2s, int kig2e, int knd, int kjd, double zchord = std::sqrt((r1 * r1) + (r2 * r2) + (r3 * r3)); - /* Calculate "ztheta", the great circle angle between x1 and x2 */ + // Calculate "ztheta", the great circle angle between x1 and x2 double ztheta = 2.0 * std::asin(zchord * 0.5); - /* Calculate the weighting factors which follow from the condition */ - /* that x is a point on the unit-sphere, too. */ + // Calculate the weighting factors which follow from the condition that x is a point on the unit-sphere, too. double zbeta = std::sin(pgamma * ztheta) / std::sin(ztheta); double zalpha = std::sin((1.0 - pgamma) * ztheta) / std::sin(ztheta); - /* Store the (x,y,z) coordinates of the point x into the array pxn */ + // Store the (x,y,z) coordinates of the point x into the array pxn pxn[ki + id1 * kj + id2 * 1 + id3 * kjd + ioffset] = zalpha * pxn[ki1 + id1 * kj1 + id2 * 1 + id3 * kjd + ioffset] + zbeta * pxn[ki2 + id1 * kj2 + id2 * 1 + id3 * kjd + ioffset]; pxn[ki + id1 * kj + id2 * 2 + id3 * kjd + ioffset] = zalpha * pxn[ki1 + id1 * kj1 + id2 * 2 + id3 * kjd + ioffset] @@ -700,17 +672,14 @@ static void glo_coor(double *pxn, double *prlon, double *prlat, int kig1s, int kig1e, int kig2s, int kig2e, int knd, int kni2, int kni3) { double zsgn; - int j1, j2; double zrlon; - int jb, jd, ml, mm; + int ml, mm; double zgamma; int mi1, mi2, ml2, ml3; /* - * Calculate the Cartesian coordinates of the gridpoints of the - * icosahedral grid on the unit sphere. The grid resolution - * corresponds to a subdivision of the edges of the original - * icosahedral triangles into mni equal parts. + * Calculate the Cartesian coordinates of the gridpoints of the icosahedral grid on the unit sphere. + * The grid resolution corresponds to a subdivision of the edges of the original icosahedral triangles into mni equal parts. */ std::vector<int> mcosv(knd); @@ -729,7 +698,7 @@ glo_coor(double *pxn, double *prlon, double *prlat, int kig1s, int kig1e, int ki /* Compute the local array mcosv, i.e. the meridian angle locations */ - for (jd = 1; jd <= knd; ++jd) + for (int jd = 1; jd <= knd; ++jd) { if (jd % 2 == 1) { mcosv[(jd + 1) / 2 - 1] = jd - 2 - knd * ((jd - 1) / 7); } else { mcosv[jd / 2 + 4] = jd - 2 - knd * ((jd - 1) / 7); } @@ -740,9 +709,8 @@ glo_coor(double *pxn, double *prlon, double *prlat, int kig1s, int kig1e, int ki /* coordinates and then iteratively bisecting them kni2 times. */ /* First a trisection is performed, if required (kni3=1). */ - for (jd = 1; jd <= knd; ++jd) + for (int jd = 1; jd <= knd; ++jd) { - /* Toggle the hemisphere */ if (jd >= 6) { zsgn = -1.0; } else { zsgn = 1.0; } @@ -786,9 +754,9 @@ glo_coor(double *pxn, double *prlon, double *prlat, int kig1s, int kig1e, int ki ml3 = mni / 3; /* Trisect the rows of the diamond. */ - for (j1 = 1; j1 <= 2; ++j1) + for (int j1 = 1; j1 <= 2; ++j1) { - for (j2 = 1; j2 <= 2; ++j2) + for (int j2 = 1; j2 <= 2; ++j2) { mi1 = (j1 - 1) * mni; mi2 = j2 * ml3 + 1; @@ -798,9 +766,9 @@ glo_coor(double *pxn, double *prlon, double *prlat, int kig1s, int kig1e, int ki } /* Trisect the columns of the diamond. */ - for (j1 = 1; j1 <= 2; ++j1) + for (int j1 = 1; j1 <= 2; ++j1) { - for (j2 = 1; j2 <= 2; ++j2) + for (int j2 = 1; j2 <= 2; ++j2) { mi1 = j2 * ml3; mi2 = (j1 - 1) * mni + 1; @@ -810,7 +778,7 @@ glo_coor(double *pxn, double *prlon, double *prlat, int kig1s, int kig1e, int ki } /* Trisect the diagonal of the diamond. */ - for (j2 = 1; j2 <= 2; ++j2) + for (int j2 = 1; j2 <= 2; ++j2) { mi1 = mni - j2 * ml3; mi2 = j2 * ml3 + 1; @@ -826,17 +794,16 @@ glo_coor(double *pxn, double *prlon, double *prlat, int kig1s, int kig1e, int ki /* Find the coordinates of the triangle nodes by iteratively */ /* bisecting the diamond intervals. */ - for (jb = 0; jb <= kni2 - 1; ++jb) + for (int jb = 0; jb <= kni2 - 1; ++jb) { mm = pow_ii(3, kni3) * pow_ii(2, jb); ml = mni / mm; ml2 = ml / 2; - /* Compute the rows of the diamond. */ - - for (j1 = 1; j1 <= mm + 1; ++j1) + // Compute the rows of the diamond. + for (int j1 = 1; j1 <= mm + 1; ++j1) { - for (j2 = 1; j2 <= mm; ++j2) + for (int j2 = 1; j2 <= mm; ++j2) { mi1 = (j1 - 1) * ml; mi2 = (j2 - 1) * ml + ml2 + 1; @@ -844,11 +811,10 @@ glo_coor(double *pxn, double *prlon, double *prlat, int kig1s, int kig1e, int ki } } - /* Compute the columns of diamond. */ - - for (j1 = 1; j1 <= mm + 1; ++j1) + // Compute the columns of diamond. + for (int j1 = 1; j1 <= mm + 1; ++j1) { - for (j2 = 1; j2 <= mm; ++j2) + for (int j2 = 1; j2 <= mm; ++j2) { mi1 = (j2 - 1) * ml + ml2; mi2 = (j1 - 1) * ml + 1; @@ -856,11 +822,10 @@ glo_coor(double *pxn, double *prlon, double *prlat, int kig1s, int kig1e, int ki } } - /* Compute the diagonals of the diamond. */ - - for (j1 = 1; j1 <= mm; ++j1) + // Compute the diagonals of the diamond. + for (int j1 = 1; j1 <= mm; ++j1) { - for (j2 = 1; j2 <= mm; ++j2) + for (int j2 = 1; j2 <= mm; ++j2) { mi1 = (j1 - 1) * ml + ml2; mi2 = (j2 - 1) * ml + ml2 + 1; @@ -872,19 +837,19 @@ glo_coor(double *pxn, double *prlon, double *prlat, int kig1s, int kig1e, int ki /***********************************************************************/ /* Set pxn to 0 if it is less than 2.5 e-14 to avoid round-off errors */ - for (j2 = kig2s; j2 <= kig2e; ++j2) + for (int j2 = kig2s; j2 <= kig2e; ++j2) { - for (j1 = kig1s; j1 <= kig1e; ++j1) + for (int j1 = kig1s; j1 <= kig1e; ++j1) { - if (fabs(pxn[j1 + id1 * j2 + id2 * 1 + id3 * jd + ioffset]) < 2.5e-14) + if (std::fabs(pxn[j1 + id1 * j2 + id2 * 1 + id3 * jd + ioffset]) < 2.5e-14) { pxn[j1 + id1 * j2 + id2 * 1 + id3 * jd + ioffset] = 0.0; } - if (fabs(pxn[j1 + id1 * j2 + id2 * 2 + id3 * jd + ioffset]) < 2.5e-14) + if (std::fabs(pxn[j1 + id1 * j2 + id2 * 2 + id3 * jd + ioffset]) < 2.5e-14) { pxn[j1 + id1 * j2 + id2 * 2 + id3 * jd + ioffset] = 0.0; } - if (fabs(pxn[j1 + id1 * j2 + id2 * 3 + id3 * jd + ioffset]) < 2.5e-14) + if (std::fabs(pxn[j1 + id1 * j2 + id2 * 3 + id3 * jd + ioffset]) < 2.5e-14) { pxn[j1 + id1 * j2 + id2 * 3 + id3 * jd + ioffset] = 0.0; } @@ -896,30 +861,27 @@ glo_coor(double *pxn, double *prlon, double *prlat, int kig1s, int kig1e, int ki /* Calculate the longitude "prlon" and the latitude "prlat"; */ /* only for the core of the diamonds, not the extended ones. */ - for (jd = 1; jd <= knd; ++jd) + for (int jd = 1; jd <= knd; ++jd) { - for (j2 = kig2s; j2 <= kig2e; ++j2) + for (int j2 = kig2s; j2 <= kig2e; ++j2) { - for (j1 = kig1s; j1 <= kig1e; ++j1) + for (int j1 = kig1s; j1 <= kig1e; ++j1) { - prlon[j1 + id1 * j2 + id2 * jd + joffset] = atan2(pxn[j1 + id1 * j2 + id2 * 2 + id3 * jd + ioffset], - pxn[j1 + id1 * j2 + id2 * 1 + id3 * jd + ioffset] + 1.0e-20); + prlon[j1 + id1 * j2 + id2 * jd + joffset] = std::atan2(pxn[j1 + id1 * j2 + id2 * 2 + id3 * jd + ioffset], + pxn[j1 + id1 * j2 + id2 * 1 + id3 * jd + ioffset] + 1.0e-20); prlat[j1 + id1 * j2 + id2 * jd + joffset] = std::asin(pxn[j1 + id1 * j2 + id2 * 3 + id3 * jd + ioffset]); } } } return; -} /* glo_coor */ +} // glo_coor /*****************************************************************************/ static void initmask(int *mask, int ni, int nd) { - int tmp1, tmp2, /*tmp3, tmp4, tmp5,*/ tmp6, tmp7, tmp8, tmp9; - - int *ptmp1; char *ptmp2; struct array section; @@ -927,12 +889,12 @@ initmask(int *mask, int ni, int nd) maskinfo.offset = 0; maskinfo.dim[0].lower = 0; - tmp1 = ni + 1; + int tmp1 = ni + 1; if (tmp1 < 0) tmp1 = 0; maskinfo.dim[0].extent = tmp1; maskinfo.dim[0].mult = 1; maskinfo.offset -= 0; - tmp2 = tmp1; + int tmp2 = tmp1; maskinfo.dim[1].lower = 1; tmp1 = ni + 1; if (tmp1 < 0) tmp1 = 0; @@ -951,14 +913,14 @@ initmask(int *mask, int ni, int nd) // tmp3 = maskinfo.offset; tmp1 = maskinfo.dim[0].extent; tmp2 = maskinfo.dim[1].extent; - tmp9 = maskinfo.dim[2].extent; + int tmp9 = maskinfo.dim[2].extent; - ptmp1 = mask; - for (tmp8 = 0; tmp8 < tmp9; tmp8++) + int *ptmp1 = mask; + for (int tmp8 = 0; tmp8 < tmp9; tmp8++) { - for (tmp7 = 0; tmp7 < tmp2; tmp7++) + for (int tmp7 = 0; tmp7 < tmp2; tmp7++) { - for (tmp6 = 0; tmp6 < tmp1; tmp6++) *ptmp1++ = 1; + for (int tmp6 = 0; tmp6 < tmp1; tmp6++) *ptmp1++ = 1; } } @@ -977,7 +939,7 @@ initmask(int *mask, int ni, int nd) tmp1 *= maskinfo.dim[0].extent; tmp1 *= maskinfo.dim[1].extent; ptmp1 += tmp1 * (jd - 1); - for (tmp6 = 0; tmp6 < tmp2; tmp6++) *ptmp1++ = 0; + for (int tmp6 = 0; tmp6 < tmp2; tmp6++) *ptmp1++ = 0; break; case 5: tmp1 = 1; @@ -987,7 +949,7 @@ initmask(int *mask, int ni, int nd) tmp1 *= maskinfo.dim[0].extent; tmp1 *= maskinfo.dim[1].extent; ptmp1 += tmp1 * (jd - 1); - for (tmp6 = 0; tmp6 < tmp2; tmp6++) *ptmp1++ = 0; + for (int tmp6 = 0; tmp6 < tmp2; tmp6++) *ptmp1++ = 0; tmp1 = 4; section.addr = (char *) mask; @@ -1002,7 +964,7 @@ initmask(int *mask, int ni, int nd) section.addr += tmp1 * (jd - 1); tmp2 = section.dim[0].extent; ptmp2 = section.addr; - for (tmp6 = 0; tmp6 < tmp2; tmp6++) + for (int tmp6 = 0; tmp6 < tmp2; tmp6++) { *((int *) ptmp2) = 0; ptmp2 += section.dim[0].mult; @@ -1018,7 +980,7 @@ initmask(int *mask, int ni, int nd) ptmp1 += tmp1 * ni; tmp1 *= maskinfo.dim[1].extent; ptmp1 += tmp1 * (jd - 1); - for (tmp6 = 0; tmp6 < tmp2; tmp6++) *ptmp1++ = 0; + for (int tmp6 = 0; tmp6 < tmp2; tmp6++) *ptmp1++ = 0; tmp1 = 4; section.addr = (char *) mask; @@ -1034,7 +996,7 @@ initmask(int *mask, int ni, int nd) section.addr += tmp1 * (jd - 1); tmp2 = section.dim[0].extent; ptmp2 = section.addr; - for (tmp6 = 0; tmp6 < tmp2; tmp6++) + for (int tmp6 = 0; tmp6 < tmp2; tmp6++) { *((int *) ptmp2) = 0; ptmp2 += section.dim[0].mult; @@ -1050,7 +1012,7 @@ initmask(int *mask, int ni, int nd) tmp1 *= maskinfo.dim[0].extent; tmp1 *= maskinfo.dim[1].extent; ptmp1 += tmp1 * (jd - 1); - for (tmp6 = 0; tmp6 < tmp2; tmp6++) *ptmp1++ = 0; + for (int tmp6 = 0; tmp6 < tmp2; tmp6++) *ptmp1++ = 0; tmp1 = 1; ptmp1 = mask; @@ -1060,7 +1022,7 @@ initmask(int *mask, int ni, int nd) ptmp1 += tmp1 * ni; tmp1 *= maskinfo.dim[1].extent; ptmp1 += tmp1 * (jd - 1); - for (tmp6 = 0; tmp6 < tmp2; tmp6++) *ptmp1++ = 0; + for (int tmp6 = 0; tmp6 < tmp2; tmp6++) *ptmp1++ = 0; tmp1 = 4; section.addr = (char *) mask; @@ -1076,7 +1038,7 @@ initmask(int *mask, int ni, int nd) section.addr += tmp1 * (jd - 1); tmp2 = section.dim[0].extent; ptmp2 = section.addr; - for (tmp6 = 0; tmp6 < tmp2; tmp6++) + for (int tmp6 = 0; tmp6 < tmp2; tmp6++) { *((int *) ptmp2) = 0; ptmp2 += section.dim[0].mult; @@ -1091,7 +1053,7 @@ initmask(int *mask, int ni, int nd) tmp1 *= maskinfo.dim[0].extent; tmp1 *= maskinfo.dim[1].extent; ptmp1 += tmp1 * (jd - 1); - for (tmp6 = 0; tmp6 < tmp2; tmp6++) *ptmp1++ = 0; + for (int tmp6 = 0; tmp6 < tmp2; tmp6++) *ptmp1++ = 0; tmp1 = 1; ptmp1 = mask; @@ -1101,7 +1063,7 @@ initmask(int *mask, int ni, int nd) ptmp1 += tmp1 * ni; tmp1 *= maskinfo.dim[1].extent; ptmp1 += tmp1 * (jd - 1); - for (tmp6 = 0; tmp6 < tmp2; tmp6++) *ptmp1++ = 0; + for (int tmp6 = 0; tmp6 < tmp2; tmp6++) *ptmp1++ = 0; tmp1 = 4; section.addr = (char *) mask; @@ -1116,7 +1078,7 @@ initmask(int *mask, int ni, int nd) section.addr += tmp1 * (jd - 1); tmp2 = section.dim[0].extent; ptmp2 = section.addr; - for (tmp6 = 0; tmp6 < tmp2; tmp6++) + for (int tmp6 = 0; tmp6 < tmp2; tmp6++) { *((int *) ptmp2) = 0; ptmp2 += section.dim[0].mult; @@ -1136,7 +1098,7 @@ initmask(int *mask, int ni, int nd) section.addr += tmp1 * (jd - 1); tmp2 = section.dim[0].extent; ptmp2 = section.addr; - for (tmp6 = 0; tmp6 < tmp2; tmp6++) + for (int tmp6 = 0; tmp6 < tmp2; tmp6++) { *((int *) ptmp2) = 0; ptmp2 += section.dim[0].mult; @@ -1154,8 +1116,6 @@ template <typename T> void gme_grid_restore(T *p, int ni, int nd) { - int j; - struct array pinfo; pinfo.offset = 0; @@ -1191,30 +1151,30 @@ gme_grid_restore(T *p, int ni, int nd) case 2: case 3: case 4: - for (j = 0; j <= ni; ++j) p[j + tmp4 + tmp5 * jd + tmp3] = p[tmp4 * (j + 1) + tmp5 * (jd - 1) + tmp3]; + for (int j = 0; j <= ni; ++j) p[j + tmp4 + tmp5 * jd + tmp3] = p[tmp4 * (j + 1) + tmp5 * (jd - 1) + tmp3]; break; case 5: - for (j = 0; j <= ni; ++j) p[j + tmp4 + tmp5 * jd + tmp3] = p[tmp4 * (j + 1) + tmp5 * (jd - 1) + tmp3]; - for (j = 0; j <= ni; ++j) p[tmp4 * (j + 1) + tmp5 * 5 + tmp3] = p[j + tmp4 + tmp5 + tmp3]; + for (int j = 0; j <= ni; ++j) p[j + tmp4 + tmp5 * jd + tmp3] = p[tmp4 * (j + 1) + tmp5 * (jd - 1) + tmp3]; + for (int j = 0; j <= ni; ++j) p[tmp4 * (j + 1) + tmp5 * 5 + tmp3] = p[j + tmp4 + tmp5 + tmp3]; break; case 6: - for (j = 0; j <= ni; ++j) p[j + tmp4 * (ni + 1) + tmp5 * 6 + tmp3] = p[ni + tmp4 * (ni + 1 - j) + tmp5 * 2 + tmp3]; - for (j = 0; j <= ni; ++j) p[ni + tmp4 * (j + 1) + tmp5 * 6 + tmp3] = p[ni - j + tmp4 * (ni + 1) + tmp5 + tmp3]; + for (int j = 0; j <= ni; ++j) p[j + tmp4 * (ni + 1) + tmp5 * 6 + tmp3] = p[ni + tmp4 * (ni + 1 - j) + tmp5 * 2 + tmp3]; + for (int j = 0; j <= ni; ++j) p[ni + tmp4 * (j + 1) + tmp5 * 6 + tmp3] = p[ni - j + tmp4 * (ni + 1) + tmp5 + tmp3]; break; case 7: case 8: case 9: - for (j = 0; j <= ni; ++j) + for (int j = 0; j <= ni; ++j) p[j + tmp4 * (ni + 1) + tmp5 * jd + tmp3] = p[ni + tmp4 * (ni + 1 - j) + tmp5 * (jd - 4) + tmp3]; - for (j = 0; j <= ni; ++j) + for (int j = 0; j <= ni; ++j) p[ni + tmp4 * (j + 1) + tmp5 * jd + tmp3] = p[ni - j + tmp4 * (ni + 1) + tmp5 * (jd - 5) + tmp3]; - for (j = 0; j <= ni; ++j) p[j + tmp4 + tmp5 * jd + tmp3] = p[tmp4 * (j + 1) + tmp5 * (jd - 1) + tmp3]; + for (int j = 0; j <= ni; ++j) p[j + tmp4 + tmp5 * jd + tmp3] = p[tmp4 * (j + 1) + tmp5 * (jd - 1) + tmp3]; break; case 10: - for (j = 0; j <= ni; ++j) p[j + tmp4 + tmp5 * 10 + tmp3] = p[tmp4 * (j + 1) + tmp5 * 9 + tmp3]; - for (j = 0; j <= ni; ++j) p[tmp4 * (j + 1) + tmp5 * 10 + tmp3] = p[j + tmp4 + tmp5 * 6 + tmp3]; - for (j = 0; j <= ni; ++j) p[j + tmp4 * (ni + 1) + tmp5 * 10 + tmp3] = p[ni + tmp4 * (ni + 1 - j) + tmp5 + tmp3]; - for (j = 0; j <= ni; ++j) p[ni + tmp4 * (j + 1) + tmp5 * 10 + tmp3] = p[ni - j + tmp4 * (ni + 1) + tmp5 * 5 + tmp3]; + for (int j = 0; j <= ni; ++j) p[j + tmp4 + tmp5 * 10 + tmp3] = p[tmp4 * (j + 1) + tmp5 * 9 + tmp3]; + for (int j = 0; j <= ni; ++j) p[tmp4 * (j + 1) + tmp5 * 10 + tmp3] = p[j + tmp4 + tmp5 * 6 + tmp3]; + for (int j = 0; j <= ni; ++j) p[j + tmp4 * (ni + 1) + tmp5 * 10 + tmp3] = p[ni + tmp4 * (ni + 1 - j) + tmp5 + tmp3]; + for (int j = 0; j <= ni; ++j) p[ni + tmp4 * (j + 1) + tmp5 * 10 + tmp3] = p[ni - j + tmp4 * (ni + 1) + tmp5 * 5 + tmp3]; break; } } @@ -1232,7 +1192,7 @@ void gme_grid(int withBounds, size_t gridsize, double *rlon, double *rlat, double *blon, double *blat, int *imask, int ni, int nd, int ni2, int ni3) { - /* check gridsize */ + // check gridsize if ((size_t) (ni + 1) * (ni + 1) * nd != gridsize) { fprintf(stderr, "gme_grid: Calculation of the global GME grid failed (ni=%d)!\n", ni); @@ -1290,7 +1250,6 @@ main(int argc, char *argv[]) { int ni2, ni3; int im1s, im1e, im2s, im2e; - int j1, j2, jd; int nd = 10; int ni = 2; @@ -1361,11 +1320,11 @@ main(int argc, char *argv[]) exit(-1); } - for (jd = 1; jd <= nd; jd++) + for (int jd = 1; jd <= nd; jd++) { - for (j2 = 1; j2 <= ni + 1; ++j2) + for (int j2 = 1; j2 <= ni + 1; ++j2) { - for (j1 = 0; j1 <= ni; ++j1) + for (int j1 = 0; j1 <= ni; ++j1) { if (mask[j1 + id1 * j2 + id2 * jd + ioffset]) { @@ -1393,11 +1352,11 @@ main(int argc, char *argv[]) double total_area = 0.0; - for (jd = 1; jd <= nd; jd++) + for (int jd = 1; jd <= nd; jd++) { - for (j2 = 1; j2 <= ni + 1; ++j2) + for (int j2 = 1; j2 <= ni + 1; ++j2) { - for (j1 = 0; j1 <= ni; ++j1) + for (int j1 = 0; j1 <= ni; ++j1) { area[j1 + id1 * j2 + id2 * jd + ioffset] = 0.0; if (mask[j1 + id1 * j2 + id2 * jd + ioffset]) diff --git a/src/knndata.cc b/src/knndata.cc index 1759b509d..435eabb18 100644 --- a/src/knndata.cc +++ b/src/knndata.cc @@ -163,7 +163,7 @@ KnnData::compute_weights_gauss() // If the sum of the weights is very low, which can happen in case // the target point is very far away from the group source points. - if (fabs(weights_sum) < 1e-9) + if (std::fabs(weights_sum) < 1e-9) { // Due to limited accuracy the exact contribution of each source // point cannot be computed. Therefore, the normalisation would diff --git a/src/percentiles.cc b/src/percentiles.cc index 2fd9db8e2..d85433e0c 100644 --- a/src/percentiles.cc +++ b/src/percentiles.cc @@ -152,7 +152,7 @@ percentile_numpy(T *array, size_t n, double quantile) constexpr double fuzz = 4.0 * std::numeric_limits<double>::epsilon(); size_t j = std::floor(nppn + fuzz); // m = a + probs*(1 - a - b) double h = nppn - j; - if (fabs(h) < fuzz) h = 0.0; + if (std::fabs(h) < fuzz) h = 0.0; if (h > 0.0 && h < 1.0) percentil = (1.0 - h) * get_nth_element(array, n, j - 1) + h * get_nth_element(array, n, j); else @@ -165,7 +165,7 @@ percentile_numpy(T *array, size_t n, double quantile) size_t j = std::floor(nppm); double h = (numpyMethod == NumpyMethod::inverted_cdf) ? (nppm > j) : (numpyMethod == NumpyMethod::averaged_inverted_cdf) ? ((nppm > j) + 1.0) / 2.0 - : ((fabs(nppm - j) > 0.0) | ((j % 2) == 1)); + : ((std::fabs(nppm - j) > 0.0) | ((j % 2) == 1)); if (h > 0.0 && h < 1.0) percentil = (1.0 - h) * get_nth_element(array, n, j - 1) + h * get_nth_element(array, n, j); else diff --git a/src/printinfo.cc b/src/printinfo.cc index 13e17dbc8..1965812e9 100644 --- a/src/printinfo.cc +++ b/src/printinfo.cc @@ -183,9 +183,9 @@ calc_curvi_xinc(int gridID) { Varray<double> xvals(xsize); for (size_t i = 0; i < xsize; ++i) xvals[i] = xvals2D[i]; - xinc = fabs(xvals[xsize - 1] - xvals[0]) / (xsize - 1); + xinc = std::fabs(xvals[xsize - 1] - xvals[0]) / (xsize - 1); for (size_t i = 1; i < xsize; ++i) - if (fabs(fabs(xvals[i - 1] - xvals[i]) - xinc) > 0.005 * xinc) + if (std::fabs(std::fabs(xvals[i - 1] - xvals[i]) - xinc) > 0.005 * xinc) { xinc = 0.0; break; @@ -216,9 +216,9 @@ calc_curvi_yinc(int gridID) { Varray<double> yvals(ysize); for (size_t i = 0; i < ysize; ++i) yvals[i] = yvals2D[i * xsize]; - yinc = fabs(yvals[ysize - 1] - yvals[0]) / (ysize - 1); + yinc = std::fabs(yvals[ysize - 1] - yvals[0]) / (ysize - 1); for (size_t i = 1; i < ysize; ++i) - if (fabs(fabs(yvals[i - 1] - yvals[i]) - yinc) > 0.005 * yinc) + if (std::fabs(std::fabs(yvals[i - 1] - yvals[i]) - yinc) > 0.005 * yinc) { yinc = 0.0; break; @@ -480,7 +480,7 @@ printZaxisBoundsInfo(int zaxisID, int dig, int levelsize, double zinc, std::stri { auto level1 = zaxisInqLbound(zaxisID, 0); auto level2 = zaxisInqUbound(zaxisID, 0); - if (!(levelsize == 1 && is_equal(level1, level2) && fabs(level1) <= 0)) + if (!(levelsize == 1 && is_equal(level1, level2) && std::fabs(level1) <= 0)) { fprintf(stdout, "%33s : ", "bounds"); fprintf(stdout, "%.*g-%.*g", dig, level1, dig, level2); @@ -526,7 +526,7 @@ printZaxisLevelInfo(int levelsize, int zaxisID, int zaxistype, double &zinc, int Varray<double> levels(levelsize); zaxisInqLevels(zaxisID, levels.data()); - if (!(zaxisTypeIsSingleLayer(zaxistype) && levelsize == 1 && fabs(levels[0]) <= 0)) + if (!(zaxisTypeIsSingleLayer(zaxistype) && levelsize == 1 && std::fabs(levels[0]) <= 0)) { auto zfirst = levels[0]; auto zlast = levels[levelsize - 1]; @@ -534,7 +534,7 @@ printZaxisLevelInfo(int levelsize, int zaxisID, int zaxistype, double &zinc, int { zinc = (levels[levelsize - 1] - levels[0]) / (levelsize - 1); for (int levelID = 2; levelID < levelsize; ++levelID) - if (fabs(fabs(levels[levelID] - levels[levelID - 1]) - zinc) > 0.001 * zinc) + if (std::fabs(std::fabs(levels[levelID] - levels[levelID - 1]) - zinc) > 0.001 * zinc) { zinc = 0; break; diff --git a/src/remap_method_conserv.cc b/src/remap_method_conserv.cc index a7c3fc508..711d4ae64 100644 --- a/src/remap_method_conserv.cc +++ b/src/remap_method_conserv.cc @@ -59,7 +59,7 @@ get_edge_direction(const double *ref_corner, double *corner_a, double *corner_b) // if the reference corner is directly on the edge // (for small angles sin(x)==x) - if (fabs(angle) < yac_angle_tol) return 0.0; + if (std::fabs(angle) < yac_angle_tol) return 0.0; return copysign(1.0, angle); } diff --git a/src/statistic.cc b/src/statistic.cc index 3e13208e9..c713459c6 100644 --- a/src/statistic.cc +++ b/src/statistic.cc @@ -449,7 +449,7 @@ beta_distr_inv(double a, double b, double p) x = xx; } #if 0 - for (x_l = 0, x_r = 1; fabs(x_l - x_r) > eps; + for (x_l = 0, x_r = 1; std::fabs(x_l - x_r) > eps; x = (x_l+x_r) / 2.0, (beta_distr(a, b, x) < p) ? (x_l=x):(x_r=x)); #endif -- GitLab From 2256e6ce9a2955018cb1c8f04df0a86d7ba761ac Mon Sep 17 00:00:00 2001 From: Uwe Schulzweida <uwe.schulzweida@mpimet.mpg.de> Date: Thu, 20 Mar 2025 20:26:10 +0100 Subject: [PATCH 09/10] gme_grid: check if calculation of coordinates failed --- ChangeLog | 4 ++ src/grid_gme.cc | 159 +++++++++++++++++++++++------------------------- 2 files changed, 80 insertions(+), 83 deletions(-) diff --git a/ChangeLog b/ChangeLog index 211f29c28..4ba6c738a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2025-03-20 Uwe Schulzweida + + * gme_grid: check if calculation of coordinates failed + 2025-03-15 Uwe Schulzweida * timpctl: Short integer overflow for CDO_PCTL_NBINS>32768 (bug fix) diff --git a/src/grid_gme.cc b/src/grid_gme.cc index a7ddc92a3..864dc87d6 100644 --- a/src/grid_gme.cc +++ b/src/grid_gme.cc @@ -635,16 +635,19 @@ gcpt(double *pxn, int kig1s, int kig1e, int kig2s, int kig2e, int knd, int kjd, { (void) knd; - /* Calculate "zchord", the Cartesian distance between x1 and x2 */ + // Calculate "zchord", the Cartesian distance between x1 and x2 int id1 = kig1e - kig1s + 1; int id2 = id1 * (kig2e - kig2s + 1); int id3 = id2 * 3; int ioffset = -(id1 + id2 + id3); - double r1 = (pxn[ki2 + id1 * kj2 + id2 * 1 + id3 * kjd + ioffset] - pxn[ki1 + id1 * kj1 + id2 * 1 + id3 * kjd + ioffset]); - double r2 = (pxn[ki2 + id1 * kj2 + id2 * 2 + id3 * kjd + ioffset] - pxn[ki1 + id1 * kj1 + id2 * 2 + id3 * kjd + ioffset]); - double r3 = (pxn[ki2 + id1 * kj2 + id2 * 3 + id3 * kjd + ioffset] - pxn[ki1 + id1 * kj1 + id2 * 3 + id3 * kjd + ioffset]); + int kij = ki + id1 * kj + id3 * kjd + ioffset; + int kij1 = ki1 + id1 * kj1 + id3 * kjd + ioffset; + int kij2 = ki2 + id1 * kj2 + id3 * kjd + ioffset; + double r1 = (pxn[kij2 + id2 * 1] - pxn[kij1 + id2 * 1]); + double r2 = (pxn[kij2 + id2 * 2] - pxn[kij1 + id2 * 2]); + double r3 = (pxn[kij2 + id2 * 3] - pxn[kij1 + id2 * 3]); double zchord = std::sqrt((r1 * r1) + (r2 * r2) + (r3 * r3)); @@ -656,27 +659,18 @@ gcpt(double *pxn, int kig1s, int kig1e, int kig2s, int kig2e, int knd, int kjd, double zalpha = std::sin((1.0 - pgamma) * ztheta) / std::sin(ztheta); // Store the (x,y,z) coordinates of the point x into the array pxn - pxn[ki + id1 * kj + id2 * 1 + id3 * kjd + ioffset] = zalpha * pxn[ki1 + id1 * kj1 + id2 * 1 + id3 * kjd + ioffset] - + zbeta * pxn[ki2 + id1 * kj2 + id2 * 1 + id3 * kjd + ioffset]; - pxn[ki + id1 * kj + id2 * 2 + id3 * kjd + ioffset] = zalpha * pxn[ki1 + id1 * kj1 + id2 * 2 + id3 * kjd + ioffset] - + zbeta * pxn[ki2 + id1 * kj2 + id2 * 2 + id3 * kjd + ioffset]; - pxn[ki + id1 * kj + id2 * 3 + id3 * kjd + ioffset] = zalpha * pxn[ki1 + id1 * kj1 + id2 * 3 + id3 * kjd + ioffset] - + zbeta * pxn[ki2 + id1 * kj2 + id2 * 3 + id3 * kjd + ioffset]; + pxn[kij + id2 * 1] = zalpha * pxn[kij1 + id2 * 1] + zbeta * pxn[kij2 + id2 * 1]; + pxn[kij + id2 * 2] = zalpha * pxn[kij1 + id2 * 2] + zbeta * pxn[kij2 + id2 * 2]; + pxn[kij + id2 * 3] = zalpha * pxn[kij1 + id2 * 3] + zbeta * pxn[kij2 + id2 * 3]; return; -} /* gcpt */ +} // gcpt /****************************************************************************/ static void glo_coor(double *pxn, double *prlon, double *prlat, int kig1s, int kig1e, int kig2s, int kig2e, int knd, int kni2, int kni3) { - double zsgn; - double zrlon; - int ml, mm; - double zgamma; - int mi1, mi2, ml2, ml3; - /* * Calculate the Cartesian coordinates of the gridpoints of the icosahedral grid on the unit sphere. * The grid resolution corresponds to a subdivision of the edges of the original icosahedral triangles into mni equal parts. @@ -689,15 +683,13 @@ glo_coor(double *pxn, double *prlon, double *prlat, int kig1s, int kig1e, int ki int ioffset = -(id1 + id2 + id3); int joffset = -(id1 + id2); - /* Compute angles associated with the icosahedron. */ - + // Compute angles associated with the icosahedron. double zw = std::acos(1.0 / (std::sin(pid5) * 2.0)) * 2.0; double zcosw = std::cos(zw); double zsinw = std::sin(zw); int mni = pow_ii(2, kni2) * pow_ii(3, kni3); - /* Compute the local array mcosv, i.e. the meridian angle locations */ - + // Compute the local array mcosv, i.e. the meridian angle locations for (int jd = 1; jd <= knd; ++jd) { if (jd % 2 == 1) { mcosv[(jd + 1) / 2 - 1] = jd - 2 - knd * ((jd - 1) / 7); } @@ -708,105 +700,102 @@ glo_coor(double *pxn, double *prlon, double *prlat, int kig1s, int kig1e, int ki /* Loop over the ten diamonds computing diamond vertices (x,y,z) */ /* coordinates and then iteratively bisecting them kni2 times. */ /* First a trisection is performed, if required (kni3=1). */ - for (int jd = 1; jd <= knd; ++jd) { - /* Toggle the hemisphere */ - if (jd >= 6) { zsgn = -1.0; } - else { zsgn = 1.0; } + // Toggle the hemisphere + double zsgn = (jd >= 6) ? -1.0 : 1.0; - /* Compute the meridian angle for each diamond "home" vertex. */ - zrlon = mcosv[jd - 1] * pid5; + // Compute the meridian angle for each diamond "home" vertex. + double zrlon = mcosv[jd - 1] * pid5; /* Every diamond has one vertex at a pole (N or S). */ /* Label this point (0,1,,) in each diamond, and */ /* initialize it to have the (x,y,z) coordinates of */ /* the pole point on the unit sphere. */ - pxn[0 + id1 * 1 + id2 * 1 + id3 * jd + ioffset] = 0.0; - pxn[0 + id1 * 1 + id2 * 2 + id3 * jd + ioffset] = 0.0; - pxn[0 + id1 * 1 + id2 * 3 + id3 * jd + ioffset] = zsgn; + int offset = id3 * jd + ioffset; + pxn[0 + id1 + id2 * 1 + offset] = 0.0; + pxn[0 + id1 + id2 * 2 + offset] = 0.0; + pxn[0 + id1 + id2 * 3 + offset] = zsgn; /* Now initialize the (x,y,z) coordinates of the "home" vertex, */ /* which defines which diamond we are talking about, and label */ /* this point (mni,1,,). */ - pxn[mni + id1 * 1 + id2 * 1 + id3 * jd + ioffset] = zsinw * std::cos(zrlon); - pxn[mni + id1 * 1 + id2 * 2 + id3 * jd + ioffset] = zsinw * std::sin(zrlon); - pxn[mni + id1 * 1 + id2 * 3 + id3 * jd + ioffset] = zcosw * zsgn; + pxn[mni + id1 + id2 * 1 + offset] = zsinw * std::cos(zrlon); + pxn[mni + id1 + id2 * 2 + offset] = zsinw * std::sin(zrlon); + pxn[mni + id1 + id2 * 3 + offset] = zcosw * zsgn; /* Next initialize the (x,y,z) coordinates for the corner of the */ /* diamond on the same latitude as the (mni,1,,) vertex, which */ /* is (0,mni+1,,) */ - pxn[0 + id1 * (mni + 1) + id2 * 1 + id3 * jd + ioffset] = zsinw * std::cos(zrlon + 2 * pid5); - pxn[0 + id1 * (mni + 1) + id2 * 2 + id3 * jd + ioffset] = zsinw * std::sin(zrlon + 2 * pid5); - pxn[0 + id1 * (mni + 1) + id2 * 3 + id3 * jd + ioffset] = zcosw * zsgn; + pxn[0 + id1 * (mni + 1) + id2 * 1 + offset] = zsinw * std::cos(zrlon + 2 * pid5); + pxn[0 + id1 * (mni + 1) + id2 * 2 + offset] = zsinw * std::sin(zrlon + 2 * pid5); + pxn[0 + id1 * (mni + 1) + id2 * 3 + offset] = zcosw * zsgn; /* Initialize the last diamond vertex, which is located */ /* in the opposite hemisphere as (mni,mni+1,,) */ - pxn[mni + id1 * (mni + 1) + id2 * 1 + id3 * jd + ioffset] = zsinw * std::cos(zrlon + pid5); - pxn[mni + id1 * (mni + 1) + id2 * 2 + id3 * jd + ioffset] = zsinw * std::sin(zrlon + pid5); - pxn[mni + id1 * (mni + 1) + id2 * 3 + id3 * jd + ioffset] = -(zcosw * zsgn); + pxn[mni + id1 * (mni + 1) + id2 * 1 + offset] = zsinw * std::cos(zrlon + pid5); + pxn[mni + id1 * (mni + 1) + id2 * 2 + offset] = zsinw * std::sin(zrlon + pid5); + pxn[mni + id1 * (mni + 1) + id2 * 3 + offset] = -(zcosw * zsgn); /***********************************************************************/ /* First a trisection is performed, if required (kni3=1). */ - if (kni3 == 1) { - ml3 = mni / 3; + int ml3 = mni / 3; - /* Trisect the rows of the diamond. */ + // Trisect the rows of the diamond. for (int j1 = 1; j1 <= 2; ++j1) { for (int j2 = 1; j2 <= 2; ++j2) { - mi1 = (j1 - 1) * mni; - mi2 = j2 * ml3 + 1; - zgamma = (double) j2 / 3.0; + int mi1 = (j1 - 1) * mni; + int mi2 = j2 * ml3 + 1; + double zgamma = (double) j2 / 3.0; gcpt(pxn, kig1s, kig1e, kig2s, kig2e, knd, jd, zgamma, mi1, 1, mi1, mni + 1, mi1, mi2); } } - /* Trisect the columns of the diamond. */ + // Trisect the columns of the diamond. for (int j1 = 1; j1 <= 2; ++j1) { for (int j2 = 1; j2 <= 2; ++j2) { - mi1 = j2 * ml3; - mi2 = (j1 - 1) * mni + 1; - zgamma = (double) j2 / 3.0; + int mi1 = j2 * ml3; + int mi2 = (j1 - 1) * mni + 1; + double zgamma = (double) j2 / 3.0; gcpt(pxn, kig1s, kig1e, kig2s, kig2e, knd, jd, zgamma, 0, mi2, mni, mi2, mi1, mi2); } } - /* Trisect the diagonal of the diamond. */ + // Trisect the diagonal of the diamond. for (int j2 = 1; j2 <= 2; ++j2) { - mi1 = mni - j2 * ml3; - mi2 = j2 * ml3 + 1; - zgamma = (double) j2 / (float) 3.; + int mi1 = mni - j2 * ml3; + int mi2 = j2 * ml3 + 1; + double zgamma = (double) j2 / 3.0; gcpt(pxn, kig1s, kig1e, kig2s, kig2e, knd, jd, zgamma, mni, 1, 0, mni + 1, mi1, mi2); } - /* Compute coordinates of icosahedral triangle centers. */ + // Compute coordinates of icosahedral triangle centers. tricntr(pxn, kig1s, kig1e, kig2s, kig2e, knd, jd, mni); } /***********************************************************************/ /* Find the coordinates of the triangle nodes by iteratively */ /* bisecting the diamond intervals. */ - for (int jb = 0; jb <= kni2 - 1; ++jb) { - mm = pow_ii(3, kni3) * pow_ii(2, jb); - ml = mni / mm; - ml2 = ml / 2; + int mm = pow_ii(3, kni3) * pow_ii(2, jb); + int ml = mni / mm; + int ml2 = ml / 2; // Compute the rows of the diamond. for (int j1 = 1; j1 <= mm + 1; ++j1) { for (int j2 = 1; j2 <= mm; ++j2) { - mi1 = (j1 - 1) * ml; - mi2 = (j2 - 1) * ml + ml2 + 1; + int mi1 = (j1 - 1) * ml; + int mi2 = (j2 - 1) * ml + ml2 + 1; gcpt(pxn, kig1s, kig1e, kig2s, kig2e, knd, jd, 0.5, mi1, mi2 - ml2, mi1, mi2 + ml2, mi1, mi2); } } @@ -816,8 +805,8 @@ glo_coor(double *pxn, double *prlon, double *prlat, int kig1s, int kig1e, int ki { for (int j2 = 1; j2 <= mm; ++j2) { - mi1 = (j2 - 1) * ml + ml2; - mi2 = (j1 - 1) * ml + 1; + int mi1 = (j2 - 1) * ml + ml2; + int mi2 = (j1 - 1) * ml + 1; gcpt(pxn, kig1s, kig1e, kig2s, kig2e, knd, jd, 0.5, mi1 - ml2, mi2, mi1 + ml2, mi2, mi1, mi2); } } @@ -827,8 +816,8 @@ glo_coor(double *pxn, double *prlon, double *prlat, int kig1s, int kig1e, int ki { for (int j2 = 1; j2 <= mm; ++j2) { - mi1 = (j1 - 1) * ml + ml2; - mi2 = (j2 - 1) * ml + ml2 + 1; + int mi1 = (j1 - 1) * ml + ml2; + int mi2 = (j2 - 1) * ml + ml2 + 1; gcpt(pxn, kig1s, kig1e, kig2s, kig2e, knd, jd, 0.5, mi1 - ml2, mi2 + ml2, mi1 + ml2, mi2 - ml2, mi1, mi2); } } @@ -836,23 +825,14 @@ glo_coor(double *pxn, double *prlon, double *prlat, int kig1s, int kig1e, int ki /***********************************************************************/ /* Set pxn to 0 if it is less than 2.5 e-14 to avoid round-off errors */ - for (int j2 = kig2s; j2 <= kig2e; ++j2) { for (int j1 = kig1s; j1 <= kig1e; ++j1) { - if (std::fabs(pxn[j1 + id1 * j2 + id2 * 1 + id3 * jd + ioffset]) < 2.5e-14) - { - pxn[j1 + id1 * j2 + id2 * 1 + id3 * jd + ioffset] = 0.0; - } - if (std::fabs(pxn[j1 + id1 * j2 + id2 * 2 + id3 * jd + ioffset]) < 2.5e-14) - { - pxn[j1 + id1 * j2 + id2 * 2 + id3 * jd + ioffset] = 0.0; - } - if (std::fabs(pxn[j1 + id1 * j2 + id2 * 3 + id3 * jd + ioffset]) < 2.5e-14) - { - pxn[j1 + id1 * j2 + id2 * 3 + id3 * jd + ioffset] = 0.0; - } + int j12 = j1 + id1 * j2; + if (std::fabs(pxn[j12 + id2 * 1 + offset]) < 2.5e-14) { pxn[j12 + id2 * 1 + offset] = 0.0; } + if (std::fabs(pxn[j12 + id2 * 2 + offset]) < 2.5e-14) { pxn[j12 + id2 * 2 + offset] = 0.0; } + if (std::fabs(pxn[j12 + id2 * 3 + offset]) < 2.5e-14) { pxn[j12 + id2 * 3 + offset] = 0.0; } } } } @@ -863,18 +843,17 @@ glo_coor(double *pxn, double *prlon, double *prlat, int kig1s, int kig1e, int ki for (int jd = 1; jd <= knd; ++jd) { + int offset = id3 * jd + ioffset; for (int j2 = kig2s; j2 <= kig2e; ++j2) { for (int j1 = kig1s; j1 <= kig1e; ++j1) { - prlon[j1 + id1 * j2 + id2 * jd + joffset] = std::atan2(pxn[j1 + id1 * j2 + id2 * 2 + id3 * jd + ioffset], - pxn[j1 + id1 * j2 + id2 * 1 + id3 * jd + ioffset] + 1.0e-20); - prlat[j1 + id1 * j2 + id2 * jd + joffset] = std::asin(pxn[j1 + id1 * j2 + id2 * 3 + id3 * jd + ioffset]); + int j12offset = j1 + id1 * j2 + id2 * jd + joffset; + prlon[j12offset] = std::atan2(pxn[j1 + id1 * j2 + id2 * 2 + offset], pxn[j1 + id1 * j2 + id2 * 1 + offset] + 1.0e-20); + prlat[j12offset] = std::asin(pxn[j1 + id1 * j2 + id2 * 3 + offset]); } } } - - return; } // glo_coor /*****************************************************************************/ @@ -1204,7 +1183,7 @@ gme_grid(int withBounds, size_t gridsize, double *rlon, double *rlat, double *bl exit(-1); } - std::vector<double> xn(gridsize * 3); + std::vector<double> xn(gridsize * 3, 0.0); std::vector<double> rlonx((ni + 3) * (ni + 3) * nd); std::vector<double> rlatx((ni + 3) * (ni + 3) * nd); @@ -1215,6 +1194,20 @@ gme_grid(int withBounds, size_t gridsize, double *rlon, double *rlat, double *bl glo_coor(xn.data(), rlon, rlat, im1s, im1e, im2s, im2e, nd, ni2, ni3); + // check coordinates + size_t inull = 0; + for (size_t i = 0; i < gridsize; ++i) + { + if ((xn[i * 3 + 0] == 0.0 || std::isnan(xn[i * 3 + 0])) && (xn[i * 3 + 1] == 0.0 || std::isnan(xn[i * 3 + 1])) + && (xn[i * 3 + 2] == 0.0 || std::isnan(xn[i * 3 + 2]))) + inull++; + } + if (inull > gridsize / 4) + { + fprintf(stderr, "gme_grid: Coordinates calculation of the global GME grid failed (ni=%d)!\n", ni); + exit(-1); + } + xd(rlon, im1s, im1e, im2s, im2e, nd, rlonx.data(), im1s - 1, im1e + 1, im2s - 1, im2e + 1, nd); xd(rlat, im1s, im1e, im2s, im2e, nd, rlatx.data(), im1s - 1, im1e + 1, im2s - 1, im2e + 1, nd); -- GitLab From b7ffc33ee86b1b47978885112b5416cd79811d2b Mon Sep 17 00:00:00 2001 From: Uwe Schulzweida <uwe.schulzweida@mpimet.mpg.de> Date: Thu, 20 Mar 2025 20:29:27 +0100 Subject: [PATCH 10/10] gme_grid: check if calculation of coordinates failed --- src/grid_gme.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/grid_gme.cc b/src/grid_gme.cc index 864dc87d6..4696e13b9 100644 --- a/src/grid_gme.cc +++ b/src/grid_gme.cc @@ -1198,8 +1198,9 @@ gme_grid(int withBounds, size_t gridsize, double *rlon, double *rlat, double *bl size_t inull = 0; for (size_t i = 0; i < gridsize; ++i) { - if ((xn[i * 3 + 0] == 0.0 || std::isnan(xn[i * 3 + 0])) && (xn[i * 3 + 1] == 0.0 || std::isnan(xn[i * 3 + 1])) - && (xn[i * 3 + 2] == 0.0 || std::isnan(xn[i * 3 + 2]))) + if ((std::fabs(xn[i * 3 + 0]) <= 0 || std::isnan(xn[i * 3 + 0])) + && (std::fabs(xn[i * 3 + 1]) <= 0 || std::isnan(xn[i * 3 + 1])) + && (std::fabs(xn[i * 3 + 2]) <= 0 || std::isnan(xn[i * 3 + 2]))) inull++; } if (inull > gridsize / 4) -- GitLab