From b12a6be8f52c1aa2e6e9218e4265c33e7eecdf8a Mon Sep 17 00:00:00 2001 From: Matthias Puchner <github@mpuchner.de> Date: Thu, 20 May 2021 12:27:52 +0200 Subject: [PATCH] add convenience functions to axis classes; rectified error texts necessary for later refactoring --- Base/Axis/ConstKBinAxis.cpp | 32 ++++++++++++++++------------- Base/Axis/ConstKBinAxis.h | 3 ++- Base/Axis/CustomBinAxis.cpp | 10 +++++++-- Base/Axis/CustomBinAxis.h | 3 ++- Base/Axis/FixedBinAxis.cpp | 38 +++++++++++++++++++++++------------ Base/Axis/FixedBinAxis.h | 3 ++- Base/Axis/IAxis.cpp | 21 +++++++++++++++++-- Base/Axis/IAxis.h | 14 +++++++++++-- Base/Axis/PointwiseAxis.cpp | 19 +++++++++++------- Base/Axis/PointwiseAxis.h | 4 ++-- Base/Axis/VariableBinAxis.cpp | 36 ++++++++++++++++++--------------- Base/Axis/VariableBinAxis.h | 3 ++- 12 files changed, 124 insertions(+), 62 deletions(-) diff --git a/Base/Axis/ConstKBinAxis.cpp b/Base/Axis/ConstKBinAxis.cpp index f85afab72b2..9a60913bc7f 100644 --- a/Base/Axis/ConstKBinAxis.cpp +++ b/Base/Axis/ConstKBinAxis.cpp @@ -45,19 +45,24 @@ ConstKBinAxis* ConstKBinAxis::clone() const return new ConstKBinAxis(getName(), m_nbins, m_start, m_end); } -ConstKBinAxis* ConstKBinAxis::createClippedAxis(double left, double right) const +ConstKBinAxis* ConstKBinAxis::createClippedAxis(double lower, double upper) const { - if (left >= right) + return static_cast<ConstKBinAxis*>(IAxis::createClippedAxis(lower, upper)); +} + +void ConstKBinAxis::clip(double lower, double upper) +{ + if (lower >= upper) throw std::runtime_error( - "ConstKBinAxis::createClippedAxis() -> Error. 'left'' should be smaller than 'right'"); + "ConstKBinAxis::clip() -> Error. 'lower' should be smaller than 'upper'"); - if (left < lowerBound()) - left = bin(0).center(); - if (right >= upperBound()) - right = bin(size() - 1).center(); + if (lower < lowerBound()) + lower = bin(0).center(); + if (upper >= upperBound()) + upper = bin(size() - 1).center(); - size_t nbin1 = findClosestIndex(left); - size_t nbin2 = findClosestIndex(right); + size_t nbin1 = findClosestIndex(lower); + size_t nbin2 = findClosestIndex(upper); size_t new_nbins = nbin2 - nbin1 + 1; std::vector<double> new_boundaries; @@ -66,11 +71,10 @@ ConstKBinAxis* ConstKBinAxis::createClippedAxis(double left, double right) const new_boundaries.push_back(old_boundaries[nbin1 + i]); } - ConstKBinAxis* result = new ConstKBinAxis(getName(), new_nbins); - result->m_start = new_boundaries.front(); - result->m_end = new_boundaries.back(); - result->setBinBoundaries(new_boundaries); - return result; + m_nbins = new_nbins; + m_start = new_boundaries.front(); + m_end = new_boundaries.back(); + setBinBoundaries(new_boundaries); } bool ConstKBinAxis::equals(const IAxis& other) const diff --git a/Base/Axis/ConstKBinAxis.h b/Base/Axis/ConstKBinAxis.h index 61bb459bc36..c210243939d 100644 --- a/Base/Axis/ConstKBinAxis.h +++ b/Base/Axis/ConstKBinAxis.h @@ -32,7 +32,8 @@ public: ConstKBinAxis* clone() const override; - ConstKBinAxis* createClippedAxis(double left, double right) const override; + ConstKBinAxis* createClippedAxis(double lower, double upper) const override; + virtual void clip(double lower, double upper) override; protected: ConstKBinAxis(const std::string& name, size_t nbins); diff --git a/Base/Axis/CustomBinAxis.cpp b/Base/Axis/CustomBinAxis.cpp index 60ffa025623..d76b4a4372d 100644 --- a/Base/Axis/CustomBinAxis.cpp +++ b/Base/Axis/CustomBinAxis.cpp @@ -60,9 +60,15 @@ std::vector<double> CustomBinAxis::binCenters() const return m_bin_centers; } -CustomBinAxis* CustomBinAxis::createClippedAxis(double /* left */, double /* right */) const +CustomBinAxis* CustomBinAxis::createClippedAxis(double /* lower */, double /* upper */) const { - throw std::runtime_error("VariableBinAxis::CustomBinAxis() -> Error." + throw std::runtime_error("CustomBinAxis::createClippedAxis() -> Error." + " Not implemented."); +} + +void CustomBinAxis::clip(double /* lower */, double /* upper */) +{ + throw std::runtime_error("CustomBinAxis::clip() -> Error." " Not implemented."); } diff --git a/Base/Axis/CustomBinAxis.h b/Base/Axis/CustomBinAxis.h index 31e051d2048..2e4a0c82f8d 100644 --- a/Base/Axis/CustomBinAxis.h +++ b/Base/Axis/CustomBinAxis.h @@ -37,7 +37,8 @@ public: std::vector<double> binCenters() const; - CustomBinAxis* createClippedAxis(double left, double right) const; + CustomBinAxis* createClippedAxis(double lower, double upper) const override; + virtual void clip(double lower, double upper) override; protected: void print(std::ostream& ostr) const; diff --git a/Base/Axis/FixedBinAxis.cpp b/Base/Axis/FixedBinAxis.cpp index b41ef06d077..ba743d387ef 100644 --- a/Base/Axis/FixedBinAxis.cpp +++ b/Base/Axis/FixedBinAxis.cpp @@ -80,21 +80,33 @@ std::vector<double> FixedBinAxis::binBoundaries() const return result; } -FixedBinAxis* FixedBinAxis::createClippedAxis(double left, double right) const +FixedBinAxis* FixedBinAxis::createClippedAxis(double lower, double upper) const { - if (left >= right) - throw std::runtime_error("FixedBinAxis::createClippedAxis() -> Error. " - "'left' should be smaller than 'right'"); - - if (left < lowerBound()) - left = bin(0).center(); - if (right >= upperBound()) - right = bin(size() - 1).center(); - - size_t nbin1 = findClosestIndex(left); - size_t nbin2 = findClosestIndex(right); + return static_cast<FixedBinAxis*>(IAxis::createClippedAxis(lower, upper)); +} - return new FixedBinAxis(getName(), nbin2 - nbin1 + 1, bin(nbin1).m_lower, bin(nbin2).m_upper); +void FixedBinAxis::clip(double lower, double upper) +{ + if (lower >= upper) + throw std::runtime_error( + "FixedBinAxis::clip() -> Error. 'lower' should be smaller than 'upper'"); + + if (lower < lowerBound()) + lower = bin(0).center(); + if (upper >= upperBound()) + upper = bin(size() - 1).center(); + + const size_t nbin1 = findClosestIndex(lower); + const size_t nbin2 = findClosestIndex(upper); + + // create tmp vars until everything is calculated, otherwise the calculation will be corrupted + // by partially changed values + const auto newStart = bin(nbin1).m_lower; + const auto newEnd = bin(nbin2).m_upper; + + m_nbins = nbin2 - nbin1 + 1; + m_start = newStart; + m_end = newEnd; } void FixedBinAxis::print(std::ostream& ostr) const diff --git a/Base/Axis/FixedBinAxis.h b/Base/Axis/FixedBinAxis.h index 3bd6063a1bb..5440635d09c 100644 --- a/Base/Axis/FixedBinAxis.h +++ b/Base/Axis/FixedBinAxis.h @@ -49,7 +49,8 @@ public: std::vector<double> binBoundaries() const; - FixedBinAxis* createClippedAxis(double left, double right) const; + FixedBinAxis* createClippedAxis(double lower, double upper) const override; + void clip(double lower, double upper) override; protected: void print(std::ostream& ostr) const; diff --git a/Base/Axis/IAxis.cpp b/Base/Axis/IAxis.cpp index c1c772d6bcb..9431c618d66 100644 --- a/Base/Axis/IAxis.cpp +++ b/Base/Axis/IAxis.cpp @@ -29,9 +29,21 @@ std::vector<double> IAxis::binBoundaries() const throw std::runtime_error("IAxis::binBoundaries() -> Error. Not implemented."); } -IAxis* IAxis::createClippedAxis(double /* left */, double /* right */) const +IAxis* IAxis::createClippedAxis(double lower, double upper) const { - throw std::runtime_error("IAxis::createClippedAxis() -> Error. Not implemented."); + auto newAxis = clone(); + newAxis->clip(lower, upper); + return newAxis; +} + +void IAxis::clip(double lower, double upper) +{ + throw std::runtime_error("IAxis::clip() -> Error. Not implemented."); +} + +void IAxis::clip(const std::pair<double, double> bounds) +{ + return clip(bounds.first, bounds.second); } bool IAxis::contains(double value) const @@ -39,6 +51,11 @@ bool IAxis::contains(double value) const return value >= lowerBound() && value < upperBound(); } +std::pair<double, double> IAxis::bounds() const +{ + return {lowerBound(), upperBound()}; +} + double IAxis::span() const { return upperBound() - lowerBound(); diff --git a/Base/Axis/IAxis.h b/Base/Axis/IAxis.h index ca2c3b0eaf4..f8604160f17 100644 --- a/Base/Axis/IAxis.h +++ b/Base/Axis/IAxis.h @@ -44,6 +44,10 @@ public: //! Returns value of last point of axis virtual double upperBound() const = 0; + //! Returns lower and upper bound in a pair. + //! first is lower, second is upper. + std::pair<double, double> bounds() const; + //! Returns distance from first to last point double span() const; @@ -72,10 +76,16 @@ public: virtual bool contains(double value) const; //! Creates a new clipped axis - virtual IAxis* createClippedAxis(double left, double right) const; + virtual IAxis* createClippedAxis(double lower, double upper) const; + + //! Clips this axis to the given values + virtual void clip(double lower, double upper); + + //! Convenience overload to clip this axis to the given values. + //! bounds.first is lower, bounds.second is upper value. + void clip(const std::pair<double, double> bounds); //! test for equality - //! bool operator==(const IAxis& right) const { return equals(right); } bool operator!=(const IAxis& right) const { return !(*this == right); } diff --git a/Base/Axis/PointwiseAxis.cpp b/Base/Axis/PointwiseAxis.cpp index 567ca3353d9..021799a3451 100644 --- a/Base/Axis/PointwiseAxis.cpp +++ b/Base/Axis/PointwiseAxis.cpp @@ -70,17 +70,22 @@ std::vector<double> PointwiseAxis::binBoundaries() const return result; } -PointwiseAxis* PointwiseAxis::createClippedAxis(double left, double right) const +PointwiseAxis* PointwiseAxis::createClippedAxis(double lower, double upper) const { - if (left >= right) - throw std::runtime_error("Error in PointwiseAxis::createClippedAxis: " - "'left' should be smaller than 'right'"); + return static_cast<PointwiseAxis*>(IAxis::createClippedAxis(lower, upper)); +} + +void PointwiseAxis::clip(double lower, double upper) +{ + if (lower >= upper) + throw std::runtime_error( + "PointwiseAxis::clip() -> Error. 'lower' should be smaller than 'upper'"); using diff_t = std::vector<double>::iterator::difference_type; - auto begin = m_coordinates.begin() + static_cast<diff_t>(findClosestIndex(left)); - auto end = m_coordinates.begin() + static_cast<diff_t>(findClosestIndex(right)) + 1; + const auto begin = m_coordinates.begin() + static_cast<diff_t>(findClosestIndex(lower)); + const auto end = m_coordinates.begin() + static_cast<diff_t>(findClosestIndex(upper)) + 1; - return new PointwiseAxis(getName(), std::vector<double>(begin, end)); + m_coordinates = std::vector<double>(begin, end); } void PointwiseAxis::print(std::ostream& ostr) const diff --git a/Base/Axis/PointwiseAxis.h b/Base/Axis/PointwiseAxis.h index 9a74bdc3208..0e321bda786 100644 --- a/Base/Axis/PointwiseAxis.h +++ b/Base/Axis/PointwiseAxis.h @@ -75,8 +75,8 @@ public: std::vector<double> binBoundaries() const override; - //! Creates a new clipped axis - PointwiseAxis* createClippedAxis(double left, double right) const override; + PointwiseAxis* createClippedAxis(double lower, double upper) const override; + virtual void clip(double lower, double upper) override; private: void print(std::ostream& ostr) const override; diff --git a/Base/Axis/VariableBinAxis.cpp b/Base/Axis/VariableBinAxis.cpp index c5f70197029..a3017ddb117 100644 --- a/Base/Axis/VariableBinAxis.cpp +++ b/Base/Axis/VariableBinAxis.cpp @@ -97,28 +97,32 @@ std::vector<double> VariableBinAxis::binCenters() const return result; } -VariableBinAxis* VariableBinAxis::createClippedAxis(double left, double right) const +VariableBinAxis* VariableBinAxis::createClippedAxis(double lower, double upper) const { + return static_cast<VariableBinAxis*>(IAxis::createClippedAxis(lower, upper)); +} - if (left >= right) - throw std::runtime_error("VariableBinAxis::createClippedAxis() -> Error. " - "'left'' should be smaller than 'right'"); +void VariableBinAxis::clip(double lower, double upper) +{ + if (lower >= upper) + throw std::runtime_error("VariableBinAxis::clip() -> Error. " + "'lower' should be smaller than 'upper'"); - if (left < lowerBound()) - left = bin(0).center(); - if (right >= upperBound()) - right = bin(size() - 1).center(); + if (lower < lowerBound()) + lower = bin(0).center(); + if (upper >= upperBound()) + upper = bin(size() - 1).center(); - size_t nbin1 = findClosestIndex(left); - size_t nbin2 = findClosestIndex(right); + const size_t nbin1 = findClosestIndex(lower); + const size_t nbin2 = findClosestIndex(upper); + const size_t new_nbins = nbin2 - nbin1 + 1; - size_t new_nbins = nbin2 - nbin1 + 1; std::vector<double> new_boundaries; - for (size_t i = 0; i < new_nbins + 1; ++i) { + for (size_t i = 0; i < new_nbins + 1; ++i) new_boundaries.push_back(m_bin_boundaries[nbin1 + i]); - } - return new VariableBinAxis(getName(), new_nbins, new_boundaries); + m_nbins = new_nbins; + setBinBoundaries(new_boundaries); } void VariableBinAxis::print(std::ostream& ostr) const @@ -156,7 +160,7 @@ void VariableBinAxis::setBinBoundaries(const std::vector<double>& bin_boundaries std::sort(vec_sorted.begin(), vec_sorted.end()); for (size_t i = 0; i < bin_boundaries.size(); ++i) { if (vec_sorted[i] != bin_boundaries[i]) - throw std::runtime_error("VariableBinAxis::VariableBinAxis() -> Error. " + throw std::runtime_error("VariableBinAxis::setBinBoundaries() -> Error. " "Array with bin edges is not sorted."); } @@ -164,7 +168,7 @@ void VariableBinAxis::setBinBoundaries(const std::vector<double>& bin_boundaries vec.erase(std::unique(vec.begin(), vec.end()), vec.end()); if (vec.size() != bin_boundaries.size()) - throw std::runtime_error("VariableBinAxis::VariableBinAxis() -> Error. " + throw std::runtime_error("VariableBinAxis::setBinBoundaries() -> Error. " "Array with bin edges contains repeating values."); m_bin_boundaries = bin_boundaries; diff --git a/Base/Axis/VariableBinAxis.h b/Base/Axis/VariableBinAxis.h index cae3dc33233..a1b7e855a00 100644 --- a/Base/Axis/VariableBinAxis.h +++ b/Base/Axis/VariableBinAxis.h @@ -49,7 +49,8 @@ public: std::vector<double> binCenters() const; std::vector<double> binBoundaries() const { return m_bin_boundaries; } - virtual VariableBinAxis* createClippedAxis(double left, double right) const; + virtual VariableBinAxis* createClippedAxis(double lower, double upper) const override; + virtual void clip(double lower, double upper) override; protected: VariableBinAxis(const std::string& name, size_t nbins = 0); -- GitLab