diff --git a/Base/Axis/ConstKBinAxis.cpp b/Base/Axis/ConstKBinAxis.cpp index f85afab72b2448ba83d0fd77f373f405eee23db3..9a60913bc7fd9976d98ace7adeee7e58ac8400e8 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 61bb459bc3658c72ff9547305e5f045f622ba8be..c210243939d40f701d220c50e35494b631491e37 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 60ffa025623f24eaa65ff92f331ac431448d31d4..d76b4a4372df5876289d9fcdd07939af45e3b70b 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 31e051d20480d6835643fa81de8ced18b1cada05..2e4a0c82f8dc0505bfddebd409bc1263f7bf24bd 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 b41ef06d07740cd7b294bc1ed69c66ef06499863..ba743d387effedefbd3081ccae5e9342b5bebe09 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 3bd6063a1bbdda85e9fdd78aff66ee28b7812905..5440635d09c6b75c7e2a5700ddf9a5ccc575397e 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 c1c772d6bcb6573cc48e796ece5cd12eb07bdf65..9431c618d6612dfb01159e5f3460ab4d2936d353 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 ca2c3b0eaf4c701cdbbfb7769aa5f27a81f09e5c..f8604160f1705ef21f2fe20d4a1dd6b92cb11dc5 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 567ca3353d95a7cb5bc491b446453ec7809e5232..021799a34511168e8d4e39ed89931fd1a3f83888 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 9a74bdc3208e5694e4c1f4bcd2abd90be0ddb359..0e321bda78620565dea65b3dc05481c31236d44e 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 c5f7019702973f74cafb8d5faeb9d32085df202b..a3017ddb11736123003519aa8ef78211c21a164b 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 cae3dc332333062a2641fbc4cdf5e1a2bc1cb7ac..a1b7e855a002e5d4284f9b7cd3454e64af0157ff 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);