diff --git a/Core/Instrument/IDetector2D.cpp b/Core/Instrument/IDetector2D.cpp index 02545ff6633f183ad25d09fb461daab24b5dcc72..716efb17c1b2d37a21cf897b41d82641c1ba5105 100644 --- a/Core/Instrument/IDetector2D.cpp +++ b/Core/Instrument/IDetector2D.cpp @@ -19,6 +19,7 @@ #include "InfinitePlane.h" #include "Logger.h" #include "SimulationElement.h" +#include "SimulationArea.h" IDetector2D::IDetector2D() : m_axes() @@ -197,24 +198,22 @@ std::vector<SimulationElement> IDetector2D::createSimulationElements(const Beam Eigen::Matrix2cd beam_polarization = beam.getPolarization(); Eigen::Matrix2cd analyzer_operator = getAnalyzerOperator(); - if (getDimension()!=2) - throw Exceptions::RuntimeErrorException( - "IDetector2D::createSimulationElements: detector is not two-dimensional"); if (!hasMasks()) m_detector_mask.initMaskData(*this); size_t spec_index = getIndexOfSpecular(beam); - const OutputData<bool>* mask_data = m_detector_mask.getMaskData(); - for (size_t index=0; index<mask_data->getAllocatedSize(); ++index) { - if ((*mask_data)[index]) continue; + + SimulationArea area(this); + for(SimulationArea::iterator it = area.begin(); it!=area.end(); ++it) { SimulationElement sim_element(wavelength, alpha_i, phi_i, - std::unique_ptr<IPixelMap>(createPixelMap(index))); + std::unique_ptr<IPixelMap>(createPixelMap(it.index()))); sim_element.setPolarization(beam_polarization); sim_element.setAnalyzerOperator(analyzer_operator); - if (index==spec_index) { + if (it.index()==spec_index) { sim_element.setSpecular(true); } result.push_back(sim_element); } + return result; } @@ -230,15 +229,9 @@ SimulationElement IDetector2D::getSimulationElement(size_t index, const Beam &be void IDetector2D::transferResultsToIntensityMap(OutputData<double> &data, const std::vector<SimulationElement> &elements) const { - size_t element_index(0); - for(size_t index=0; index<data.getAllocatedSize(); ++index) { - if(this->isMasked(index)) continue; - data[index] = elements[element_index++].getIntensity(); - if(element_index > elements.size()) { - throw Exceptions::RuntimeErrorException("IDetector2D::transferResultsToIntensityMap -> " - "Error. Number of elements doesn't match data"); - } - } + SimulationArea area(this); + for(SimulationArea::iterator it = area.begin(); it!=area.end(); ++it) + data[it.index()] = elements[it.elementIndex()].getIntensity(); } bool IDetector2D::dataShapeMatches(const OutputData<double> *p_data) const diff --git a/Core/Instrument/SimulationArea.cpp b/Core/Instrument/SimulationArea.cpp index 6af53ddd2ac94e8fa2acb7133a46d1238ec971b8..9a359c3fb671c2738b73b5005ef8e6ef0bec9624 100644 --- a/Core/Instrument/SimulationArea.cpp +++ b/Core/Instrument/SimulationArea.cpp @@ -16,6 +16,7 @@ #include "SimulationArea.h" #include "IDetector2D.h" #include "Exceptions.h" +#include <sstream> SimulationArea::SimulationArea(const IDetector2D *detector) : m_detector(detector) @@ -23,6 +24,10 @@ SimulationArea::SimulationArea(const IDetector2D *detector) if(detector == nullptr) throw Exceptions::RuntimeErrorException("SimulationArea::SimulationArea -> Error. " "Detector nullptr."); + + if (m_detector->getDimension()!=2) + throw Exceptions::RuntimeErrorException( + "SimulationArea::SimulationArea: detector is not two-dimensional"); } SimulationAreaIterator SimulationArea::begin() @@ -35,3 +40,19 @@ SimulationAreaIterator SimulationArea::end() return SimulationAreaIterator(this, m_detector->getTotalSize()); } +bool SimulationArea::isMasked(size_t index) const +{ + if(index >= m_detector->getTotalSize()) { + std::ostringstream message; + message << "SimulationArea::isActive() -> Error. Index " << index << " is out of range, " + << "totalSize=" << m_detector->getTotalSize(); + throw Exceptions::RuntimeErrorException(message.str()); + } + + return m_detector->isMasked(index); +} + +size_t SimulationArea::totalSize() const +{ + return m_detector->getTotalSize(); +} diff --git a/Core/Instrument/SimulationArea.h b/Core/Instrument/SimulationArea.h index a6fc2fe1b435490147cbbefd534732f1a0be11c6..60496d8b2c21ca5682400d03ed28a715eb1ab0b9 100644 --- a/Core/Instrument/SimulationArea.h +++ b/Core/Instrument/SimulationArea.h @@ -34,7 +34,9 @@ public: SimulationAreaIterator begin(); SimulationAreaIterator end(); - const IDetector2D* detector() const { return m_detector; } + bool isMasked(size_t index) const; + + size_t totalSize() const; private: const IDetector2D *m_detector; diff --git a/Core/Instrument/SimulationAreaIterator.cpp b/Core/Instrument/SimulationAreaIterator.cpp index eba4afc9d3fa638242dcce4c5a71b79da7adfeda..dbbded7dc08f1c343228cf52481e2470e8896175 100644 --- a/Core/Instrument/SimulationAreaIterator.cpp +++ b/Core/Instrument/SimulationAreaIterator.cpp @@ -22,20 +22,43 @@ SimulationAreaIterator::SimulationAreaIterator(const SimulationArea *area, size_ , m_index(start_at_index) , m_element_index(0) { + if(m_index > m_area->totalSize()) + throw Exceptions::RuntimeErrorException("SimulationAreaIterator::SimulationAreaIterator() " + "-> Error. Invalid initial index"); + if(m_index != m_area->totalSize() && m_area->isMasked(m_index)) + m_index = nextIndex(m_index); } SimulationAreaIterator &SimulationAreaIterator::operator++() { - while(m_area->detector()->isMasked(++m_index)); - ++m_element_index; + size_t index = nextIndex(m_index); + if(index != m_index) { + ++m_element_index; + m_index = index; + } return *this; } -SimulationAreaIterator &SimulationAreaIterator::operator++(int) +SimulationAreaIterator SimulationAreaIterator::operator++(int) { - m_index++; - m_element_index++; - return *this; + SimulationAreaIterator result(*this); + this->operator++(); + return result; +} + +size_t SimulationAreaIterator::nextIndex(size_t currentIndex) +{ + size_t result = ++currentIndex; + if(result < m_area->totalSize()) { + while(m_area->isMasked(result)) { + ++result; + if(result == m_area->totalSize()) + break; + } + } else { + return m_area->totalSize(); + } + return result; } diff --git a/Core/Instrument/SimulationAreaIterator.h b/Core/Instrument/SimulationAreaIterator.h index 30ef3b836f9b26ede331d565af88ef5161fb9c3f..b123975f24e3a6cf6b062f06b84880663178e022 100644 --- a/Core/Instrument/SimulationAreaIterator.h +++ b/Core/Instrument/SimulationAreaIterator.h @@ -29,8 +29,8 @@ class BA_CORE_API_ SimulationAreaIterator public: explicit SimulationAreaIterator(const SimulationArea *area, size_t start_at_index); - int index() const { return m_index; } - int elementIndex() const { return m_element_index;} + size_t index() const { return m_index; } + size_t elementIndex() const { return m_element_index;} bool operator==(const SimulationAreaIterator &other) const; bool operator!=(const SimulationAreaIterator &other) const; @@ -39,9 +39,10 @@ public: SimulationAreaIterator& operator++(); //! postfix increment - SimulationAreaIterator& operator++(int); + SimulationAreaIterator operator++(int); private: + size_t nextIndex(size_t currentIndex); const SimulationArea *m_area; size_t m_index; //!< global index in detector plane defined by its axes size_t m_element_index; //!< sequential number for SimulationElementVector @@ -50,7 +51,6 @@ private: inline bool SimulationAreaIterator::operator==(const SimulationAreaIterator &other) const { return m_area == other.m_area && m_index == other.m_index; -// && m_element_index == other.m_element_index; } inline bool SimulationAreaIterator::operator!=(const SimulationAreaIterator &right) const diff --git a/Tests/UnitTests/Core/3/SimulationAreaTest.h b/Tests/UnitTests/Core/3/SimulationAreaTest.h index 6e2ea26205931820339926c2cc5689252cc4016b..6fc647dffa6c831a0104daf0a6c0391feae04333 100644 --- a/Tests/UnitTests/Core/3/SimulationAreaTest.h +++ b/Tests/UnitTests/Core/3/SimulationAreaTest.h @@ -51,6 +51,11 @@ TEST_F(SimulationAreaTest, iteratorOperations) ++it; EXPECT_EQ(it.index(), 2); EXPECT_EQ(it.elementIndex(), 2); + + // incrementing well behind the end + for(size_t i=0; i<100; ++i) ++it; + EXPECT_EQ(it.index(), detector.getTotalSize()); + EXPECT_EQ(it.elementIndex(), detector.getTotalSize()); } //! Iteration over non-masked detector @@ -71,16 +76,11 @@ TEST_F(SimulationAreaTest, detectorIteration) } EXPECT_EQ(indexes, expectedIndexes); EXPECT_EQ(elementIndexes, expectedElementIndexes); - - // testing C++-11 -// for(SimulationArea::iterator it : area) { -// std::cout << "KKK" << std::endl; -// } } //! Iteration over masked detector -TEST_F(SimulationAreaTest, maskedDetectorIteration) +TEST_F(SimulationAreaTest, maskedIteration) { SphericalDetector detector(5, -1.0, 4.0, 4, 0.0, 4.0); detector.addMask(Geometry::Rectangle(0.1, 1.1, 2.9, 2.9), true); @@ -97,8 +97,45 @@ TEST_F(SimulationAreaTest, maskedDetectorIteration) } EXPECT_EQ(indexes, expectedIndexes); EXPECT_EQ(elementIndexes, expectedElementIndexes); +} + +//! Iteration over the detector with first and alst bin masked + +TEST_F(SimulationAreaTest, maskedCornerIteration) +{ + SphericalDetector detector(5, -1.0, 4.0, 4, 0.0, 4.0); + detector.addMask(Geometry::Rectangle(-0.9, 0.1, -0.1, 0.9), true); + detector.addMask(Geometry::Rectangle(3.1, 3.1, 3.9, 3.9), true); + SimulationArea area(&detector); + + std::vector<int> expectedIndexes + = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18}; + std::vector<int> expectedElementIndexes + = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17}; + std::vector<int> indexes; + std::vector<int> elementIndexes; + for(SimulationArea::iterator it = area.begin(); it!=area.end(); ++it) { + indexes.push_back(it.index()); + elementIndexes.push_back(it.elementIndex()); + } + EXPECT_EQ(indexes, expectedIndexes); + EXPECT_EQ(elementIndexes, expectedElementIndexes); +} +TEST_F(SimulationAreaTest, allMaskedIteration) +{ + SphericalDetector detector(5, -1.0, 4.0, 4, 0.0, 4.0); + detector.addMask(Geometry::Rectangle(-0.9, 0.1, 3.9, 3.9), true); + SimulationArea area(&detector); + std::vector<int> indexes; + std::vector<int> elementIndexes; + for(SimulationArea::iterator it = area.begin(); it!=area.end(); ++it) { + indexes.push_back(it.index()); + elementIndexes.push_back(it.elementIndex()); + } + EXPECT_EQ(indexes.size(), size_t(0)); + EXPECT_EQ(elementIndexes.size(), size_t(0)); } #endif diff --git a/dev-tools/log/perf_history.txt b/dev-tools/log/perf_history.txt index 84f18759e99e1676b233bb0c31c9af8437963d81..7b0db4a6e1be6e078eda625159eaf1e65f2859d6 100644 --- a/dev-tools/log/perf_history.txt +++ b/dev-tools/log/perf_history.txt @@ -514,5 +514,8 @@ # after the switch to std::move in SimulationElement -| date | hostname | sysinfo | python | total cpu | total wall | MultiLayer | CylindersInDWBA | RotatedPyramids | CoreShell | SquareLattice | RadialParaCrystal | HexParaCrystal | SSCA | Mesocrystal | | 2016-10-14 08:51:54 | scgsun | Linux x86_64 | 2.7 | 122.8880 | 19.3683 | 2.8577 | 0.7296 | 3.3728 | 0.5629 | 2.3569 | 0.7555 | 3.3065 | 1.0475 | 1.7642 | 1.7467 | 0.8680 | +| 2016-10-14 08:51:54 | scgsun | Linux x86_64 | 2.7 | 122.8880 | 19.3683 | 2.8577 | 0.7296 | 3.3728 | 0.5629 | 2.3569 | 0.7555 | 3.3065 | 1.0475 | 1.7642 | 1.7467 | 0.8680 | + +# after switch to SimulationAreaIterator +| 2016-10-17 11:28:02 | scgsun | Linux x86_64 | 2.7 | 122.3960 | 19.9584 | 3.0328 | 0.7849 | 3.4156 | 0.5976 | 2.3843 | 0.7670 | 3.4331 | 1.0687 | 1.7839 | 1.8056 | 0.8850 |