diff --git a/Framework/NexusGeometry/CMakeLists.txt b/Framework/NexusGeometry/CMakeLists.txt index f21c454a121fa9382d47e6e895f54eb2f0444806..9439d186cf8e41608a3322580a15fce838c6dcef 100644 --- a/Framework/NexusGeometry/CMakeLists.txt +++ b/Framework/NexusGeometry/CMakeLists.txt @@ -2,7 +2,7 @@ set ( SRC_FILES src/InstrumentBuilder.cpp src/NexusGeometryParser.cpp src/NexusShapeFactory.cpp - src/Tube.cpp + src/TubeBuilder.cpp src/TubeHelpers.cpp ) @@ -11,7 +11,7 @@ set ( INC_FILES inc/MantidNexusGeometry/InstrumentBuilder.h inc/MantidNexusGeometry/NexusGeometryParser.h inc/MantidNexusGeometry/NexusShapeFactory.h - inc/MantidNexusGeometry/Tube.h + inc/MantidNexusGeometry/TubeBuilder.h inc/MantidNexusGeometry/TubeHelpers.h ) @@ -19,7 +19,7 @@ set ( TEST_FILES InstrumentBuilderTest.h NexusGeometryParserTest.h NexusShapeFactoryTest.h - TubeTest.h + TubeBuilderTest.h TubeHelpersTest.h ) diff --git a/Framework/NexusGeometry/inc/MantidNexusGeometry/InstrumentBuilder.h b/Framework/NexusGeometry/inc/MantidNexusGeometry/InstrumentBuilder.h index f57668ca6516a38ffe68a649f21f25bf02f86b19..cc4d09b9658dadebee87892514ec9d4a261ccf13 100644 --- a/Framework/NexusGeometry/inc/MantidNexusGeometry/InstrumentBuilder.h +++ b/Framework/NexusGeometry/inc/MantidNexusGeometry/InstrumentBuilder.h @@ -1,12 +1,13 @@ #ifndef MANTIDNEXUSGEOMETRY_INSTRUMENTBUILDER_H #define MANTIDNEXUSGEOMETRY_INSTRUMENTBUILDER_H -#include "MantidNexusGeometry/DllConfig.h" #include "MantidGeometry/Objects/IObject.h" +#include "MantidNexusGeometry/DllConfig.h" +#include "MantidNexusGeometry/TubeBuilder.h" #include <Eigen/Core> #include <Eigen/Geometry> -#include <string> #include <memory> +#include <string> namespace Mantid { namespace Geometry { @@ -15,9 +16,6 @@ class IComponent; class ICompAssembly; } namespace NexusGeometry { -namespace detail { -class Tube; -} /** InstrumentBuilder : Builder for wrapping the creating of a Mantid Instrument. Provides some useful abstractions over the full-blown Instrument @@ -51,10 +49,10 @@ public: /// Adds component to instrument Geometry::IComponent *addComponent(const std::string &compName, const Eigen::Vector3d &position); - - void addObjComponentAssembly( - const std::string &compName, const detail::Tube &tube, - boost::shared_ptr<const Mantid::Geometry::IObject> detShape); + /// Adds tubes (ObjComponentAssemblies) to the last registered bank + void addTubes(const std::string &bankName, + const std::vector<detail::TubeBuilder> &tubes, + boost::shared_ptr<const Mantid::Geometry::IObject> pixelShape); /// Adds detector to the root (instrument) void addDetectorToInstrument( const std::string &detName, int detId, const Eigen::Vector3d &position, @@ -82,6 +80,9 @@ public: std::unique_ptr<const Geometry::Instrument> createInstrument() const; private: + /// Add a single tube to the last registed bank + void doAddTube(const std::string &compName, const detail::TubeBuilder &tube, + boost::shared_ptr<const Mantid::Geometry::IObject> pixelShape); /// Sorts detectors void sortDetectors() const; /// Check that this instance is not locked diff --git a/Framework/NexusGeometry/inc/MantidNexusGeometry/Tube.h b/Framework/NexusGeometry/inc/MantidNexusGeometry/Tube.h deleted file mode 100644 index 3f85d5275867a85a1bfde8260b58f2dbfb9ee7a8..0000000000000000000000000000000000000000 --- a/Framework/NexusGeometry/inc/MantidNexusGeometry/Tube.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef MANTIDNEXUSGEOMETRY_TUBE_H -#define MANTIDNEXUSGEOMETRY_TUBE_H -#include "MantidNexusGeometry/DllConfig.h" -#include <Eigen/Core> -#include <Eigen/Geometry> -#include <boost/shared_ptr.hpp> -#include <vector> - -namespace Mantid { -namespace Geometry { -class IObject; -} - -namespace NexusGeometry { -namespace detail { -class MANTID_NEXUSGEOMETRY_DLL Tube { -public: - Tube(const Mantid::Geometry::IObject &firstDetectorShape, - Eigen::Vector3d firstDetectorPosition, int firstDetectorId); - ~Tube(); - - const Eigen::Vector3d &position() const; - const std::vector<Eigen::Vector3d> &detPositions() const; - const std::vector<int> &detIDs() const; - boost::shared_ptr<const Mantid::Geometry::IObject> shape() const; - const double height() const; - const double radius() const; - bool addDetectorIfCoLinear(const Eigen::Vector3d &pos, int detID); - const size_t size() const; - -private: - Eigen::Vector3d m_axis; - double m_baseHeight; - double m_height; - Eigen::Vector3d m_halfHeightVec; // stored for faster calculations - Eigen::Vector3d m_baseVec; // stored for faster calculations - double m_radius; - std::vector<Eigen::Vector3d> m_positions; - std::vector<int> m_detIDs; - Eigen::Vector3d - m_p1; ///< First point which defines the line in space the tube lies along - Eigen::Vector3d m_p2; ///< Second point which defines the line in space the - ///< tube lies along - -private: - bool checkCoLinear(const Eigen::Vector3d &pos) const; -}; -} // namespace detail -} // namespace NexusGeometry -} // namespace Mantid - -#endif // MANTIDNEXUSGEOMETRY_TUBE_H diff --git a/Framework/NexusGeometry/inc/MantidNexusGeometry/TubeBuilder.h b/Framework/NexusGeometry/inc/MantidNexusGeometry/TubeBuilder.h new file mode 100644 index 0000000000000000000000000000000000000000..449527ed759f11e704086dd3448d6ee62aae05b8 --- /dev/null +++ b/Framework/NexusGeometry/inc/MantidNexusGeometry/TubeBuilder.h @@ -0,0 +1,77 @@ +#ifndef MANTIDNEXUSGEOMETRY_TUBEBUILDER_H +#define MANTIDNEXUSGEOMETRY_TUBEBUILDER_H +#include "MantidNexusGeometry/DllConfig.h" +#include <Eigen/Core> +#include <Eigen/Geometry> +#include <boost/shared_ptr.hpp> +#include <vector> + +namespace Mantid { +namespace Geometry { +class IObject; +} + +namespace NexusGeometry { +namespace detail { + +/** TubeBuilder : Builder for wrapping the creation of a tube as a collection of +Colinear detectors with cylindrical shape. + +Copyright © 2018 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge +National Laboratory & European Spallation Source + +This file is part of Mantid. + +Mantid is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. + +Mantid is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>. + +File change history is stored at: <https://github.com/mantidproject/mantid> +Code Documentation is available at: <http://doxygen.mantidproject.org> +*/ +class MANTID_NEXUSGEOMETRY_DLL TubeBuilder { +public: + TubeBuilder(const Mantid::Geometry::IObject &pixelShape, + Eigen::Vector3d firstDetectorPosition, int firstDetectorId); + ~TubeBuilder(); + + const Eigen::Vector3d &tubePosition() const; + const std::vector<Eigen::Vector3d> &detPositions() const; + const std::vector<int> &detIDs() const; + boost::shared_ptr<const Mantid::Geometry::IObject> shape() const; + const double tubeHeight() const; + const double tubeRadius() const; + bool addDetectorIfCoLinear(const Eigen::Vector3d &pos, int detID); + const size_t size() const; + +private: + Eigen::Vector3d m_axis; + double m_pixelHeight; + double m_tubeHeight; + Eigen::Vector3d m_halfHeightVec; // stored for faster calculations + Eigen::Vector3d m_baseVec; // stored for faster calculations + double m_pixelRadius; + std::vector<Eigen::Vector3d> m_positions; + std::vector<int> m_detIDs; + Eigen::Vector3d + m_p1; ///< First point which defines the line in space the tube lies along + Eigen::Vector3d m_p2; ///< Second point which defines the line in space the + ///< tube lies along + +private: + bool checkCoLinear(const Eigen::Vector3d &pos) const; +}; +} // namespace detail +} // namespace NexusGeometry +} // namespace Mantid + +#endif // MANTIDNEXUSGEOMETRY_TUBEBUILDER_H diff --git a/Framework/NexusGeometry/inc/MantidNexusGeometry/TubeHelpers.h b/Framework/NexusGeometry/inc/MantidNexusGeometry/TubeHelpers.h index 0255f95901b284b429a3a6d06510cdef2cdb7802..c68ecc61829e6bf5f77439c4b734784248e751cb 100644 --- a/Framework/NexusGeometry/inc/MantidNexusGeometry/TubeHelpers.h +++ b/Framework/NexusGeometry/inc/MantidNexusGeometry/TubeHelpers.h @@ -1,6 +1,6 @@ #ifndef MANTIDNEXUSGEOMETRY_TUBEHELPERS_H #define MANTIDNEXUSGEOMETRY_TUBEHELPERS_H -#include "MantidNexusGeometry/Tube.h" +#include "MantidNexusGeometry/TubeBuilder.h" #include <Eigen/Core> #include <vector> // Eigen typedefs @@ -15,9 +15,9 @@ namespace detail { class Tube; } namespace TubeHelpers { -MANTID_NEXUSGEOMETRY_DLL std::vector<detail::Tube> -findTubes(const Mantid::Geometry::IObject &shape, const Pixels &positions, - const std::vector<int> &detIDs); +MANTID_NEXUSGEOMETRY_DLL std::vector<detail::TubeBuilder> +findAndSortTubes(const Mantid::Geometry::IObject &shape, + const Pixels &positions, const std::vector<int> &detIDs); } // namespace TubeHelpers } // namespace NexusGeometry } // namespace Mantid diff --git a/Framework/NexusGeometry/src/InstrumentBuilder.cpp b/Framework/NexusGeometry/src/InstrumentBuilder.cpp index 6d5b7abb36d9f08f4a8d24a0c3cf9a96e315f230..1787e4c971b088f67abc18dd43c325410a2788ac 100644 --- a/Framework/NexusGeometry/src/InstrumentBuilder.cpp +++ b/Framework/NexusGeometry/src/InstrumentBuilder.cpp @@ -7,7 +7,6 @@ #include "MantidKernel/EigenConversionHelpers.h" #include "MantidKernel/make_unique.h" #include "MantidNexusGeometry/NexusShapeFactory.h" -#include "MantidNexusGeometry/Tube.h" #include <boost/make_shared.hpp> namespace Mantid { @@ -68,17 +67,29 @@ InstrumentBuilder::addComponent(const std::string &compName, return component; } -/** Add a tube to the last bank +/** Add a set of tubes to the last registered bank +@param bankName Bank name +@param tubes Tubes to be added to bank +@param pixelShape Shape of each detector within the tube +*/ +void InstrumentBuilder::addTubes( + const std::string &bankName, const std::vector<detail::TubeBuilder> &tubes, + boost::shared_ptr<const Mantid::Geometry::IObject> pixelShape) { + for (size_t i = 0; i < tubes.size(); i++) + doAddTube(bankName + "_tube_" + std::to_string(i), tubes[i], pixelShape); +} + +/** Add a tube to the last registered bank @param compName Tube name @param tube Tube to be added to bank -@param detShape Shape of each detector within the tube +@param pixelShape Shape of each detector within the tube */ -void InstrumentBuilder::addObjComponentAssembly( - const std::string &compName, const detail::Tube &tube, - boost::shared_ptr<const Mantid::Geometry::IObject> detShape) { +void InstrumentBuilder::doAddTube( + const std::string &compName, const detail::TubeBuilder &tube, + boost::shared_ptr<const Mantid::Geometry::IObject> pixelShape) { verifyMutable(); auto *objComp(new Geometry::ObjCompAssembly(compName)); - const auto &pos = tube.position(); + const auto &pos = tube.tubePosition(); objComp->setPos(pos(0), pos(1), pos(2)); objComp->setOutline(tube.shape()); auto baseName = compName + "_"; @@ -86,7 +97,7 @@ void InstrumentBuilder::addObjComponentAssembly( auto *detector = new Geometry::Detector(baseName + std::to_string(i), tube.detIDs()[i], objComp); detector->translate(Mantid::Kernel::toV3D(tube.detPositions()[i])); - detector->setShape(detShape); + detector->setShape(pixelShape); objComp->add(detector); m_instrument->markAsDetectorIncomplete(detector); } diff --git a/Framework/NexusGeometry/src/NexusGeometryParser.cpp b/Framework/NexusGeometry/src/NexusGeometryParser.cpp index 72f9f1584c6c01c104a0f3968c8d3bdfc325f752..f4a508cc6abfff998ac761d8765139d7ab48163d 100644 --- a/Framework/NexusGeometry/src/NexusGeometryParser.cpp +++ b/Framework/NexusGeometry/src/NexusGeometryParser.cpp @@ -634,15 +634,11 @@ extractInstrument(const H5File &file, const Group &root) { // Extract shape auto detShape = parseNexusShape(detectorGroup, searchTubes); - std::vector<detail::Tube> tubes; + std::vector<detail::TubeBuilder> tubes; if (searchTubes) { - tubes = TubeHelpers::findTubes(*detShape, pixelOffsets, detectorIds); - auto baseName = bankName + "_tube_"; - for (size_t i = 0; i < tubes.size(); ++i) { - auto &tube = tubes[i]; - builder.addObjComponentAssembly(baseName + std::to_string(i), tube, - detShape); - } + tubes = + TubeHelpers::findAndSortTubes(*detShape, pixelOffsets, detectorIds); + builder.addTubes(bankName, tubes, detShape); } else { for (size_t i = 0; i < detectorIds.size(); ++i) { auto index = static_cast<int>(i); diff --git a/Framework/NexusGeometry/src/Tube.cpp b/Framework/NexusGeometry/src/TubeBuilder.cpp similarity index 53% rename from Framework/NexusGeometry/src/Tube.cpp rename to Framework/NexusGeometry/src/TubeBuilder.cpp index 34219ebc8796c00e081fdd7d29096d402db44555..b0b6112ab255d940df5941ec4191c98cd1769e65 100644 --- a/Framework/NexusGeometry/src/Tube.cpp +++ b/Framework/NexusGeometry/src/TubeBuilder.cpp @@ -1,4 +1,4 @@ -#include "MantidNexusGeometry/Tube.h" +#include "MantidNexusGeometry/TubeBuilder.h" #include "MantidGeometry/Objects/IObject.h" #include "MantidGeometry/Rendering/GeometryHandler.h" #include "MantidGeometry/Rendering/ShapeInfo.h" @@ -10,14 +10,14 @@ namespace NexusGeometry { namespace detail { -Tube::Tube(const Mantid::Geometry::IObject &firstDetectorShape, - Eigen::Vector3d firstDetectorPosition, int firstDetectorId) - : m_radius(firstDetectorShape.getGeometryHandler()->shapeInfo().radius()), - m_baseHeight( - firstDetectorShape.getGeometryHandler()->shapeInfo().height()) { +TubeBuilder::TubeBuilder(const Mantid::Geometry::IObject &pixelShape, + Eigen::Vector3d firstDetectorPosition, + int firstDetectorId) + : m_pixelRadius(pixelShape.getGeometryHandler()->shapeInfo().radius()), + m_pixelHeight(pixelShape.getGeometryHandler()->shapeInfo().height()) { // Get axis along which cylinder lies m_axis = Kernel::toVector3d( - firstDetectorShape.getGeometryHandler()->shapeInfo().points()[1]); + pixelShape.getGeometryHandler()->shapeInfo().points()[1]); // Set position and id of first detector in tube m_positions.push_back(firstDetectorPosition); m_detIDs.push_back(firstDetectorId); @@ -26,27 +26,28 @@ Tube::Tube(const Mantid::Geometry::IObject &firstDetectorShape, m_p1 = m_axis + firstDetectorPosition; m_p2 = firstDetectorPosition; - m_height = m_baseHeight; + // initialise height + m_tubeHeight = m_pixelHeight; auto norm = m_axis.norm(); - auto factor = (m_baseHeight / 2.0) / norm; + auto factor = (m_pixelHeight / 2.0) / norm; m_halfHeightVec = m_axis * factor; m_baseVec = firstDetectorPosition - m_halfHeightVec; } -Tube::~Tube() {} +TubeBuilder::~TubeBuilder() {} -const Eigen::Vector3d &Tube::position() const { return m_baseVec; } +const Eigen::Vector3d &TubeBuilder::tubePosition() const { return m_baseVec; } -const size_t Tube::size() const { return m_positions.size(); } +const size_t TubeBuilder::size() const { return m_positions.size(); } -const std::vector<Eigen::Vector3d> &Tube::detPositions() const { +const std::vector<Eigen::Vector3d> &TubeBuilder::detPositions() const { return m_positions; } -const std::vector<int> &Tube::detIDs() const { return m_detIDs; } +const std::vector<int> &TubeBuilder::detIDs() const { return m_detIDs; } -boost::shared_ptr<const Mantid::Geometry::IObject> Tube::shape() const { +boost::shared_ptr<const Mantid::Geometry::IObject> TubeBuilder::shape() const { Eigen::Matrix<double, 3, 3> points; // calcualte height vector; // Centre shape about (0, 0, 0) @@ -62,33 +63,36 @@ boost::shared_ptr<const Mantid::Geometry::IObject> Tube::shape() const { // Find point on outer circle auto normVec = p1.cross(p2); auto norm = normVec.norm(); - auto factor = m_radius / norm; + auto factor = m_pixelRadius / norm; points.col(1) = (normVec * factor) + (points.col(0)); return NexusShapeFactory::createCylinder(points); } -const double Tube::height() const { return m_height; } +const double TubeBuilder::tubeHeight() const { return m_tubeHeight; } -const double Tube::radius() const { return m_radius; } +const double TubeBuilder::tubeRadius() const { return m_pixelRadius; } -bool Tube::addDetectorIfCoLinear(const Eigen::Vector3d &pos, int detID) { - if (checkCoLinear(pos)) { +bool TubeBuilder::addDetectorIfCoLinear(const Eigen::Vector3d &pos, int detID) { + auto isCoLinear = checkCoLinear(pos); + + if (isCoLinear) { + // Add Detector m_positions.push_back(pos); m_detIDs.push_back(detID); - // calculate half height vector for detector + // Recalculate height as distance between base of tube and tip of new + // detector auto dist = (m_baseVec) - (pos + m_halfHeightVec); - if (dist.norm() > m_height) - m_height = dist.norm(); - return true; + if (dist.norm() > m_tubeHeight) + m_tubeHeight = dist.norm(); } - return false; + return isCoLinear; } -bool Tube::checkCoLinear(const Eigen::Vector3d &pos) const { +bool TubeBuilder::checkCoLinear(const Eigen::Vector3d &pos) const { // Check if pos is on the same line as p1 and p2 auto numVec = ((m_p2 - m_p1).cross(m_p1 - pos)); auto denomVec = (m_p2 - m_p1); diff --git a/Framework/NexusGeometry/src/TubeHelpers.cpp b/Framework/NexusGeometry/src/TubeHelpers.cpp index 41801142e7a39d09792b9b2971f2b0d625261392..aec3859fad9204228f83b9be180fdf141a8f0755 100644 --- a/Framework/NexusGeometry/src/TubeHelpers.cpp +++ b/Framework/NexusGeometry/src/TubeHelpers.cpp @@ -1,38 +1,41 @@ #include "MantidNexusGeometry/TubeHelpers.h" #include "MantidGeometry/Objects/IObject.h" -#include "MantidNexusGeometry/Tube.h" namespace Mantid { namespace NexusGeometry { namespace TubeHelpers { -std::vector<detail::Tube> findTubes(const Mantid::Geometry::IObject &shape, - const Pixels &positions, - const std::vector<int> &detIDs) { - std::vector<detail::Tube> tubes; +std::vector<detail::TubeBuilder> +findAndSortTubes(const Mantid::Geometry::IObject &shape, + const Pixels &positions, const std::vector<int> &detIDs) { + std::vector<detail::TubeBuilder> tubes; tubes.emplace_back(shape, positions.col(0), detIDs[0]); bool newEntry; + // Loop through all detectors and add to tubes for (size_t i = 1; i < detIDs.size(); ++i) { newEntry = true; for (auto t = tubes.rbegin(); t != tubes.rend(); ++t) { auto &tube = (*t); + // Adding detector to existing tube if (tube.addDetectorIfCoLinear(positions.col(i), detIDs[i])) { newEntry = false; break; } } + // Create a new tube if detector does not belong to any tubes if (newEntry) tubes.emplace_back(shape, positions.col(i), detIDs[i]); } // Remove "tubes" with only 1 element - tubes.erase( - std::remove_if(tubes.begin(), tubes.end(), - [](const detail::Tube &tube) { return tube.size() == 1; }), - tubes.end()); + tubes.erase(std::remove_if(tubes.begin(), tubes.end(), + [](const detail::TubeBuilder &tube) { + return tube.size() == 1; + }), + tubes.end()); return tubes; } diff --git a/Framework/NexusGeometry/test/TubeTest.h b/Framework/NexusGeometry/test/TubeBuilderTest.h similarity index 71% rename from Framework/NexusGeometry/test/TubeTest.h rename to Framework/NexusGeometry/test/TubeBuilderTest.h index 31eff0411dc8f453b57cd86dc3eac86e6d9a1bdf..e0b5fec6de7993b9442229f23a27b04a73fa7d86 100644 --- a/Framework/NexusGeometry/test/TubeTest.h +++ b/Framework/NexusGeometry/test/TubeBuilderTest.h @@ -8,7 +8,7 @@ #include "MantidGeometry/Objects/IObject.h" #include "MantidGeometry/Rendering/GeometryHandler.h" #include "MantidGeometry/Rendering/ShapeInfo.h" -#include "MantidNexusGeometry/Tube.h" +#include "MantidNexusGeometry/TubeBuilder.h" #include "MantidTestHelpers/NexusGeometryTestHelpers.h" #include <cxxtest/TestSuite.h> #include <numeric> @@ -17,18 +17,18 @@ using namespace Mantid; using namespace NexusGeometry; using namespace NexusGeometryTestHelpers; -class TubeTest : public CxxTest::TestSuite { +class TubeBuilderTest : public CxxTest::TestSuite { public: void test_constructor() { auto shape = createShape(); const auto &shapeInfo = shape->getGeometryHandler()->shapeInfo(); - detail::Tube tube(*shape, Eigen::Vector3d(2, 2, 3), 10); + detail::TubeBuilder tube(*shape, Eigen::Vector3d(2, 2, 3), 10); TS_ASSERT_EQUALS(tube.size(), 1); - TS_ASSERT_EQUALS(tube.position(), Eigen::Vector3d(2 - 0.00101, 2, 3)); - TS_ASSERT_EQUALS(tube.radius(), shapeInfo.radius()); + TS_ASSERT_EQUALS(tube.tubePosition(), Eigen::Vector3d(2 - 0.00101, 2, 3)); + TS_ASSERT_EQUALS(tube.tubeRadius(), shapeInfo.radius()); // Height should just be shape height - TS_ASSERT_EQUALS(tube.height(), shapeInfo.height()); + TS_ASSERT_EQUALS(tube.tubeHeight(), shapeInfo.height()); TS_ASSERT_EQUALS(tube.detPositions()[0], Eigen::Vector3d(2, 2, 3)); TS_ASSERT_EQUALS(tube.detIDs()[0], 10); @@ -37,25 +37,25 @@ public: TS_ASSERT_EQUALS(tubeShapeInfo, shapeInfo); } - void testAddValid() { + void testAddColinear() { auto shape = createShape(); auto shapeInfo = shape->getGeometryHandler()->shapeInfo(); - detail::Tube tube(*shape, Eigen::Vector3d(0.00202, 1, 0), 10); + detail::TubeBuilder tube(*shape, Eigen::Vector3d(0.00202, 1, 0), 10); TS_ASSERT(tube.addDetectorIfCoLinear(Eigen::Vector3d(0.00404, 1, 0), 11)); TS_ASSERT_EQUALS(tube.size(), 2); // The shape height is 0.00202. See createShape for details. - TS_ASSERT_EQUALS(tube.height(), 0.00404); + TS_ASSERT_EQUALS(tube.tubeHeight(), 0.00404); TS_ASSERT_EQUALS(tube.detIDs(), (std::vector<int>{10, 11})); TS_ASSERT_EQUALS(tube.detPositions()[0], Eigen::Vector3d(0.00202, 1, 0)); TS_ASSERT_EQUALS(tube.detPositions()[1], Eigen::Vector3d(0.00404, 1, 0)); - TS_ASSERT_EQUALS(tube.position(), Eigen::Vector3d(0.00101, 1, 0)); + TS_ASSERT_EQUALS(tube.tubePosition(), Eigen::Vector3d(0.00101, 1, 0)); } - void testAddInvalid() { + void testAddNonColinear() { auto shape = createShape(); auto shapeInfo = shape->getGeometryHandler()->shapeInfo(); - detail::Tube tube(*shape, Eigen::Vector3d(0.00202, 1, 0), 10); + detail::TubeBuilder tube(*shape, Eigen::Vector3d(0.00202, 1, 0), 10); TS_ASSERT(!tube.addDetectorIfCoLinear(Eigen::Vector3d(0, 2, 0), 11)); TS_ASSERT_EQUALS(tube.size(), 1); diff --git a/Framework/NexusGeometry/test/TubeHelpersTest.h b/Framework/NexusGeometry/test/TubeHelpersTest.h index fbe922fe0fcd11cece1f66cc90d9e32169da55b0..1f68f844a654c278e150cb83b97a030f114950bf 100644 --- a/Framework/NexusGeometry/test/TubeHelpersTest.h +++ b/Framework/NexusGeometry/test/TubeHelpersTest.h @@ -17,36 +17,43 @@ using namespace NexusGeometryTestHelpers; class TubeHelpersTest : public CxxTest::TestSuite { public: - void test_findTubesInvalid() { - auto pixels = generateValidPixels(); + void test_CoLinearDetectorsProduceTubes() { + auto pixels = generateCoLinearPixels(); auto shape = createShape(); auto detIds = getFakeDetIDs(); - auto tubes = TubeHelpers::findTubes(*shape, pixels, detIds); + // Inputs represent two parallel tubes comprising two cylindrical detectors + // each. + auto tubes = TubeHelpers::findAndSortTubes(*shape, pixels, detIds); TS_ASSERT_EQUALS(tubes.size(), 2); TS_ASSERT(tubes[0].size() == tubes[1].size()); TS_ASSERT_EQUALS(tubes[0].size(), 2); } - void test_findTubesValid() { - auto pixels = generateInvalidPixels(); + void test_NonColinearDetectorsDoNotProduceTubes() { + auto pixels = generateNonCoLinearPixels(); auto shape = createShape(); auto detIds = getFakeDetIDs(); - auto tubes = TubeHelpers::findTubes(*shape, pixels, detIds); + + // Inputs represent 4 discrete cylinders which are not coLinear. + auto tubes = TubeHelpers::findAndSortTubes(*shape, pixels, detIds); TS_ASSERT_EQUALS(tubes.size(), 0) } - void test_findTubesMixed() { - auto pixels = generateValidPixels(); + void test_MixtureOfCoLinearAndNonCoLinearTubes() { + auto pixels = generateCoLinearPixels(); auto shape = createShape(); auto detIds = getFakeDetIDs(); - // replace with invalid coord + // replace with coord which is not CoLinear and thus will not be part of any + // tube pixels.col(3) = Eigen::Vector3d(-0.7, -0.7, 0); - auto tubes = TubeHelpers::findTubes(*shape, pixels, detIds); + // Inputs represent one tube comprising of two cylinders and two discrete + // non-colinear detectors. + auto tubes = TubeHelpers::findAndSortTubes(*shape, pixels, detIds); TS_ASSERT_EQUALS(tubes.size(), 1); TS_ASSERT_EQUALS(tubes[0].size(), 2); } diff --git a/Framework/TestHelpers/inc/MantidTestHelpers/NexusGeometryTestHelpers.h b/Framework/TestHelpers/inc/MantidTestHelpers/NexusGeometryTestHelpers.h index d5298d3901f0b2a2d0d3924a0e2fbefd707e80a1..36a9d73bf894167ca2df110c53cbee263e822c08 100644 --- a/Framework/TestHelpers/inc/MantidTestHelpers/NexusGeometryTestHelpers.h +++ b/Framework/TestHelpers/inc/MantidTestHelpers/NexusGeometryTestHelpers.h @@ -14,8 +14,8 @@ class IObject; namespace NexusGeometryTestHelpers { boost::shared_ptr<const Mantid::Geometry::IObject> createShape(); -Pixels generateValidPixels(); -Pixels generateInvalidPixels(); +Pixels generateCoLinearPixels(); +Pixels generateNonCoLinearPixels(); std::vector<int> getFakeDetIDs(); } // namespace NexusGeometryTestHelpers diff --git a/Framework/TestHelpers/src/NexusGeometryTestHelpers.cpp b/Framework/TestHelpers/src/NexusGeometryTestHelpers.cpp index ab63fd605ad5c8399194fe44344aee469c4cb720..cbda10300a31038f77c6603df8ca597a2a1ace12 100644 --- a/Framework/TestHelpers/src/NexusGeometryTestHelpers.cpp +++ b/Framework/TestHelpers/src/NexusGeometryTestHelpers.cpp @@ -8,13 +8,16 @@ using namespace Mantid::NexusGeometry; namespace NexusGeometryTestHelpers { boost::shared_ptr<const Mantid::Geometry::IObject> createShape() { Eigen::Matrix<double, 3, 3> pointsDef; + // Vector to base positioned at center of cylinder pointsDef.col(0) = Eigen::Vector3d(-0.00101, 0.0, 0.0); + // vector to base which is radial pointsDef.col(1) = Eigen::Vector3d(-0.00101, 0.00405, 0.0); + // vector to top positioned at center of cylinder pointsDef.col(2) = Eigen::Vector3d(0.00101, 0.0, 0.0); return NexusShapeFactory::createCylinder(pointsDef); } -Pixels generateValidPixels() { +Pixels generateCoLinearPixels() { // Assuming tubes with axis vectors (1, 0, 0) create two tubes lying along x // axis. Eigen::Matrix<double, 3, 4> pix; @@ -32,8 +35,8 @@ Pixels generateValidPixels() { return pix; } -Pixels generateInvalidPixels() { - // Add two 4 cylinders which are randomly distrubuted. +Pixels generateNonCoLinearPixels() { + // Add two 4 cylinders which are not CoLinear Eigen::Matrix<double, 3, 4> pix; pix.col(0) = Eigen::Vector3d(0, 0.1, 0); pix.col(1) = Eigen::Vector3d(0.3, 0.6, 0.3);