From b62b24162aaa640da6888cfd3e7a05ca889827bb Mon Sep 17 00:00:00 2001 From: Gennady Pospelov <g.pospelov@fz-juelich.de> Date: Mon, 11 Aug 2014 17:37:26 +0200 Subject: [PATCH] Clip functionality for IAxis family. --- Core/Samples/inc/Samples.h | 1 - Core/Tools/inc/ConstKBinAxis.h | 4 ++ Core/Tools/inc/CustomBinAxis.h | 2 + Core/Tools/inc/FixedBinAxis.h | 2 + Core/Tools/inc/IAxis.h | 9 ++++ Core/Tools/inc/IntensityDataFunctions.h | 3 ++ Core/Tools/inc/VariableBinAxis.h | 2 + Core/Tools/src/ConstKBinAxis.cpp | 37 ++++++++++++++ Core/Tools/src/CustomBinAxis.cpp | 5 ++ Core/Tools/src/FixedBinAxis.cpp | 14 ++++++ Core/Tools/src/IntensityDataFunctions.cpp | 11 ++++ Core/Tools/src/VariableBinAxis.cpp | 21 ++++++++ Tests/UnitTests/TestCore/ConstKBinAxisTest.h | 50 +++++++------------ Tests/UnitTests/TestCore/FixedBinAxisTest.h | 20 ++++++++ .../UnitTests/TestCore/VariableBinAxisTest.h | 34 +++++++++++++ 15 files changed, 183 insertions(+), 32 deletions(-) diff --git a/Core/Samples/inc/Samples.h b/Core/Samples/inc/Samples.h index 81dd0b244ac..7202787246f 100644 --- a/Core/Samples/inc/Samples.h +++ b/Core/Samples/inc/Samples.h @@ -17,7 +17,6 @@ #define SAMPLES_H #include "Crystal.h" -#include "MaterialManager.h" #include "Layer.h" #include "LayerInterface.h" #include "MultiLayer.h" diff --git a/Core/Tools/inc/ConstKBinAxis.h b/Core/Tools/inc/ConstKBinAxis.h index 8f9f46b0295..c4a5a6c3fa6 100644 --- a/Core/Tools/inc/ConstKBinAxis.h +++ b/Core/Tools/inc/ConstKBinAxis.h @@ -36,7 +36,11 @@ public: ConstKBinAxis *clone() const; + ConstKBinAxis *createClippedAxis(double left, double right) const; + protected: + ConstKBinAxis(const std::string &name, size_t nbins); + void print(std::ostream& ostr) const; bool equals(const IAxis& other) const; diff --git a/Core/Tools/inc/CustomBinAxis.h b/Core/Tools/inc/CustomBinAxis.h index c34881cdc77..3500fe663ba 100644 --- a/Core/Tools/inc/CustomBinAxis.h +++ b/Core/Tools/inc/CustomBinAxis.h @@ -42,6 +42,8 @@ public: std::vector<double > getBinCenters() const; + CustomBinAxis *createClippedAxis(double left, double right) const; + protected: void print(std::ostream& ostr) const; bool equals(const IAxis& other) const; diff --git a/Core/Tools/inc/FixedBinAxis.h b/Core/Tools/inc/FixedBinAxis.h index 24bd37ccf5a..002f8ed1ccf 100644 --- a/Core/Tools/inc/FixedBinAxis.h +++ b/Core/Tools/inc/FixedBinAxis.h @@ -52,6 +52,8 @@ public: std::vector<double > getBinBoundaries() const; + FixedBinAxis *createClippedAxis(double left, double right) const; + protected: void print(std::ostream& ostr) const; virtual bool equals(const IAxis& other) const; diff --git a/Core/Tools/inc/IAxis.h b/Core/Tools/inc/IAxis.h index d10f81aa5de..2ce545212ec 100644 --- a/Core/Tools/inc/IAxis.h +++ b/Core/Tools/inc/IAxis.h @@ -71,6 +71,9 @@ public: virtual std::vector<double > getBinBoundaries() const; + //! Creates a new clipped axis + virtual IAxis *createClippedAxis(double left, double right) const; + protected: virtual void print(std::ostream& ostr) const=0; virtual bool equals(const IAxis& other) const; @@ -109,6 +112,12 @@ inline std::vector<double> IAxis::getBinBoundaries() const throw Exceptions::NotImplementedException("IAxis::getBinBoundaries() -> Error. Not implemented."); } +inline IAxis *IAxis::createClippedAxis(double /* left */, double /* right */) const +{ + throw Exceptions::NotImplementedException("IAxis::createClippedAxis() -> Error. Not implemented."); +} + + //! global helper function for comparison of axes inline bool HaveSameNameAndShape(const IAxis& left, const IAxis& right) { diff --git a/Core/Tools/inc/IntensityDataFunctions.h b/Core/Tools/inc/IntensityDataFunctions.h index 7f531a95cde..dbcfd5ad191 100644 --- a/Core/Tools/inc/IntensityDataFunctions.h +++ b/Core/Tools/inc/IntensityDataFunctions.h @@ -42,6 +42,9 @@ public: static double GetRelativeDifference(const OutputData<double> &result, const OutputData<double> &reference); + //! Returns new IntensityData objects which axes clipped to represent the specified rectangle + static OutputData<double> *createClippedDataSet(const OutputData<double> &origin, double x1, double y1, double x2, double y2); + }; diff --git a/Core/Tools/inc/VariableBinAxis.h b/Core/Tools/inc/VariableBinAxis.h index 38c94fa227a..d49404e4f94 100644 --- a/Core/Tools/inc/VariableBinAxis.h +++ b/Core/Tools/inc/VariableBinAxis.h @@ -52,6 +52,8 @@ public: std::vector<double > getBinBoundaries() const; + VariableBinAxis *createClippedAxis(double left, double right) const; + protected: VariableBinAxis(const std::string &name, int nbins = 0); void setBinBoundaries(const std::vector<double> &bin_boundaries); diff --git a/Core/Tools/src/ConstKBinAxis.cpp b/Core/Tools/src/ConstKBinAxis.cpp index cfa041691a9..179cb541fdd 100644 --- a/Core/Tools/src/ConstKBinAxis.cpp +++ b/Core/Tools/src/ConstKBinAxis.cpp @@ -3,6 +3,15 @@ #include <iomanip> #include <iostream> +ConstKBinAxis::ConstKBinAxis(const std::string &name, size_t nbins) + : VariableBinAxis(name, nbins) + , m_start(0) + , m_end(0) +{ + +} + + ConstKBinAxis::ConstKBinAxis(const std::string &name, size_t nbins, double start, double end) : VariableBinAxis(name, nbins) , m_start(start) @@ -29,6 +38,34 @@ ConstKBinAxis *ConstKBinAxis::clone() const return new ConstKBinAxis(getName(), m_nbins, m_start, m_end); } +ConstKBinAxis *ConstKBinAxis::createClippedAxis(double left, double right) const +{ + if(left >= right) + throw LogicErrorException("ConstKBinAxis::createClippedAxis() -> Error. 'left'' should be smaller than 'right'"); + + if(left < getMin()) left = getBin(0).getMidPoint(); + if(right >= getMax()) right = getBin(getSize()-1).getMidPoint(); + + size_t nbin1 = findClosestIndex(left); + size_t nbin2 = findClosestIndex(right); + +// return new ConstKBinAxis(getName(), nbin2-nbin1+1, getBin(nbin1).m_lower, getBin(nbin2).m_upper ); + + size_t new_nbins = nbin2-nbin1+1; + std::vector<double> new_boundaries; + std::vector<double> old_boundaries = getBinBoundaries(); + for(size_t i=0; i<new_nbins+1; ++i) { + 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; +} + + bool ConstKBinAxis::equals(const IAxis& other) const { diff --git a/Core/Tools/src/CustomBinAxis.cpp b/Core/Tools/src/CustomBinAxis.cpp index a79c93f4448..c6507648b35 100644 --- a/Core/Tools/src/CustomBinAxis.cpp +++ b/Core/Tools/src/CustomBinAxis.cpp @@ -52,6 +52,11 @@ std::vector<double> CustomBinAxis::getBinCenters() const return m_bin_centers; } +CustomBinAxis *CustomBinAxis::createClippedAxis(double /* left */, double /* right */) const +{ + throw Exceptions::NotImplementedException("VariableBinAxis::CustomBinAxis() -> Error. Not implemented."); +} + void CustomBinAxis::print(std::ostream &ostr) const { diff --git a/Core/Tools/src/FixedBinAxis.cpp b/Core/Tools/src/FixedBinAxis.cpp index a3277be9185..9f54ad241db 100644 --- a/Core/Tools/src/FixedBinAxis.cpp +++ b/Core/Tools/src/FixedBinAxis.cpp @@ -93,6 +93,20 @@ std::vector<double> FixedBinAxis::getBinBoundaries() const return result; } +FixedBinAxis *FixedBinAxis::createClippedAxis(double left, double right) const +{ + if(left >= right) + throw LogicErrorException("FixedBinAxis::createClippedAxis() -> Error. 'left'' should be smaller than 'right'"); + + if(left < getMin()) left = getBin(0).getMidPoint(); + if(right >= getMax()) right = getBin(getSize()-1).getMidPoint(); + + size_t nbin1 = findClosestIndex(left); + size_t nbin2 = findClosestIndex(right); + + return new FixedBinAxis(getName(), nbin2-nbin1+1, getBin(nbin1).m_lower, getBin(nbin2).m_upper ); +} + void FixedBinAxis::print(std::ostream& ostr) const { diff --git a/Core/Tools/src/IntensityDataFunctions.cpp b/Core/Tools/src/IntensityDataFunctions.cpp index 92b88c69c4b..87bed395287 100644 --- a/Core/Tools/src/IntensityDataFunctions.cpp +++ b/Core/Tools/src/IntensityDataFunctions.cpp @@ -40,3 +40,14 @@ double IntensityDataFunctions::GetRelativeDifference(const OutputData<double> &r return diff; } + +OutputData<double> *IntensityDataFunctions::createClippedDataSet(const OutputData<double> &origin, double x1, double y1, double x2, double y2) +{ +// if (origin.getRank() != 2) { +// throw LogicErrorException("IntensityDataFunctions::createClippedData()" +// " -> Error! Works only on two-dimensional data"); +// } + + return 0; +} + diff --git a/Core/Tools/src/VariableBinAxis.cpp b/Core/Tools/src/VariableBinAxis.cpp index ad0c37894c0..402cd7038c7 100644 --- a/Core/Tools/src/VariableBinAxis.cpp +++ b/Core/Tools/src/VariableBinAxis.cpp @@ -97,6 +97,27 @@ std::vector<double> VariableBinAxis::getBinBoundaries() const return m_bin_boundaries; } +VariableBinAxis *VariableBinAxis::createClippedAxis(double left, double right) const +{ + + if(left >= right) + throw LogicErrorException("VariableBinAxis::createClippedAxis() -> Error. 'left'' should be smaller than 'right'"); + + if(left < getMin()) left = getBin(0).getMidPoint(); + if(right >= getMax()) right = getBin(getSize()-1).getMidPoint(); + + size_t nbin1 = findClosestIndex(left); + size_t nbin2 = findClosestIndex(right); + + size_t new_nbins = nbin2-nbin1+1; + std::vector<double> new_boundaries; + 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); +} + void VariableBinAxis::print(std::ostream& ostr) const { diff --git a/Tests/UnitTests/TestCore/ConstKBinAxisTest.h b/Tests/UnitTests/TestCore/ConstKBinAxisTest.h index c51451db0d4..c6c84136df1 100644 --- a/Tests/UnitTests/TestCore/ConstKBinAxisTest.h +++ b/Tests/UnitTests/TestCore/ConstKBinAxisTest.h @@ -46,6 +46,9 @@ TEST_F(ConstKBinAxisTest, TypicalAxis) EXPECT_EQ(m_start, m_axis.getMin()); EXPECT_EQ(m_end, m_axis.getMax()); + EXPECT_DOUBLE_EQ(m_start, m_axis.getBinBoundaries().front()); + EXPECT_DOUBLE_EQ(m_end, m_axis.getBinBoundaries().back()); + for(size_t i=0; i<m_axis.getSize(); ++i) { EXPECT_DOUBLE_EQ( m_centers[i], m_axis[i]); } @@ -76,37 +79,22 @@ TEST_F(ConstKBinAxisTest, IOStream) delete result; } +//[-5.0, -3.99816897832528, -2.9975609824866662, -1.99786732193833, -0.9987818274427882, 0.0, 0.9987818274427874, 1.9978673219383292, 2.997560982486666, 3.998168978325279, 5.0] -//TEST_F(ConstKBinAxisTest, BinCenters) -//{ -// static const double arr[] = {-1.0, -0.5, 0.5, 1.0, 2.0}; -// std::vector<double> values (arr, arr + sizeof(arr) / sizeof(arr[0]) ); -// VariableBinAxis axis("name", 4, values); - -// std::vector<double> centers = axis.getBinCenters(); -// EXPECT_EQ(4, centers.size()); -// EXPECT_DOUBLE_EQ(-0.75, centers[0]); -// EXPECT_DOUBLE_EQ(0.0, centers[1]); -// EXPECT_DOUBLE_EQ(0.75, centers[2]); -// EXPECT_DOUBLE_EQ(1.5, centers[3]); -//} - - -//TEST_F(ConstKBinAxisTest, BinBoundaries) -//{ -// static const double arr[] = {-1.0, -0.5, 0.5, 1.0, 2.0}; -// std::vector<double> values (arr, arr + sizeof(arr) / sizeof(arr[0]) ); -// VariableBinAxis axis("name", 4, values); - -// std::vector<double> boundaries = axis.getBinBoundaries(); -// EXPECT_EQ(5, boundaries.size()); -// EXPECT_DOUBLE_EQ(-1.0, boundaries[0]); -// EXPECT_DOUBLE_EQ(-0.5, boundaries[1]); -// EXPECT_DOUBLE_EQ(0.5, boundaries[2]); -// EXPECT_DOUBLE_EQ(1.0, boundaries[3]); -// EXPECT_DOUBLE_EQ(2.0, boundaries[4]); -//} - - +TEST_F(ConstKBinAxisTest, ClippedAxis) +{ + ConstKBinAxis *clip1 = m_axis.createClippedAxis(Units::deg2rad(-10.0), Units::deg2rad(10.0)); + EXPECT_TRUE(*clip1 == m_axis); + delete clip1; + + ConstKBinAxis *clip2 = m_axis.createClippedAxis(Units::deg2rad(-3.0), Units::deg2rad(3.0)); + EXPECT_EQ(clip2->getSize(), 8); + std::vector<double> boundaries = clip2->getBinBoundaries(); + for(size_t i=0; i<boundaries.size(); ++i) { + EXPECT_EQ(boundaries[i], m_axis.getBin(1+i).m_lower); +// EXPECT_NEAR(boundaries[i], m_axis.getBin(1+i).m_lower, 1e-10); + } + delete clip2; +} #endif diff --git a/Tests/UnitTests/TestCore/FixedBinAxisTest.h b/Tests/UnitTests/TestCore/FixedBinAxisTest.h index 878a54bbdde..a578c369b08 100644 --- a/Tests/UnitTests/TestCore/FixedBinAxisTest.h +++ b/Tests/UnitTests/TestCore/FixedBinAxisTest.h @@ -152,4 +152,24 @@ TEST_F(FixedBinAxisTest, BinBoundaries) } +TEST_F(FixedBinAxisTest, ClippedAxis) +{ + FixedBinAxis axis("name", 4, -1.0, 3.0); + + FixedBinAxis *clip1 = axis.createClippedAxis(-0.5, 2.5); + EXPECT_EQ(clip1->getSize(), axis.getSize()); + EXPECT_EQ(clip1->getMin(), axis.getMin()); + EXPECT_EQ(clip1->getMax(), axis.getMax()); + EXPECT_TRUE(*clip1 == axis); + delete clip1; + + FixedBinAxis *clip2 = axis.createClippedAxis(0.0, 1.99); + EXPECT_EQ(clip2->getSize(), 2); + EXPECT_EQ(clip2->getMin(), 0.0); + EXPECT_EQ(clip2->getMax(), 2.0); + EXPECT_TRUE(*clip2 != axis); + delete clip2; +} + + #endif diff --git a/Tests/UnitTests/TestCore/VariableBinAxisTest.h b/Tests/UnitTests/TestCore/VariableBinAxisTest.h index d39f123826e..405f67689cd 100644 --- a/Tests/UnitTests/TestCore/VariableBinAxisTest.h +++ b/Tests/UnitTests/TestCore/VariableBinAxisTest.h @@ -218,6 +218,40 @@ TEST_F(VariableBinAxisTest, BinBoundaries) EXPECT_DOUBLE_EQ(2.0, boundaries[4]); } +TEST_F(VariableBinAxisTest, ClippedAxis) +{ + static const double arr[] = {-1.0, -0.5, 0.5, 1.0, 2.0}; + std::vector<double> values (arr, arr + sizeof(arr) / sizeof(arr[0]) ); + VariableBinAxis axis("name", 4, values); + + VariableBinAxis *clip1 = axis.createClippedAxis(-1.0, 2.0); + EXPECT_TRUE(axis == *clip1); + delete clip1; + + VariableBinAxis *clip2 = axis.createClippedAxis(-0.5, 1.5); + EXPECT_EQ(clip2->getSize(), 3); + EXPECT_EQ(clip2->getMin(), -0.5); + EXPECT_EQ(clip2->getMax(), 2.0); + std::vector<double> centers = clip2->getBinCenters(); + EXPECT_EQ(centers[0], 0.0); + EXPECT_EQ(centers[1], 0.75); + EXPECT_EQ(centers[2], 1.5); + EXPECT_TRUE(axis != *clip2); + delete clip2; + + VariableBinAxis *clip3 = axis.createClippedAxis(-0.5, 0.99); + EXPECT_EQ(clip3->getSize(), 2); + EXPECT_EQ(clip3->getMin(), -0.5); + EXPECT_EQ(clip3->getMax(), 1.0); + std::vector<double> boundaries = clip3->getBinBoundaries(); + EXPECT_EQ(boundaries[0], -0.5); + EXPECT_EQ(boundaries[1], 0.5); + EXPECT_EQ(boundaries[2], 1.0); + delete clip3; + + +} + #endif -- GitLab