From 59d53ef59e110d5be1a78f8f4e1b0fc6946dbe89 Mon Sep 17 00:00:00 2001 From: Johannes Junggeburth <johannes.josef.junggeburth@cern.ch> Date: Thu, 27 Jun 2024 16:09:45 +0200 Subject: [PATCH] GeoModelHelpers - Add subvolume fetch function with selector --- .../GeoModelHelpers/getChildNodesWithTrf.h | 8 +++++-- .../src/getChildNodesWithTrf.cxx | 21 +++++++++++++------ .../GeoModelKernel/GeoDefinitions.h | 11 +++++++--- .../GeoModelKernel/src/GeoDefinitions.cxx | 21 ++++++++++++++++++- .../GeoModelKernel/tests/testEulerAngles.cxx | 11 ++++++++++ 5 files changed, 60 insertions(+), 12 deletions(-) diff --git a/GeoModelCore/GeoModelHelpers/GeoModelHelpers/getChildNodesWithTrf.h b/GeoModelCore/GeoModelHelpers/GeoModelHelpers/getChildNodesWithTrf.h index 4e2b2e8e6..f8c3599b2 100644 --- a/GeoModelCore/GeoModelHelpers/GeoModelHelpers/getChildNodesWithTrf.h +++ b/GeoModelCore/GeoModelHelpers/GeoModelHelpers/getChildNodesWithTrf.h @@ -39,8 +39,12 @@ std::vector <GeoChildNodeWithTrf> getChildrenWithRef (PVConstLink physVol, bool summarizeEqualVol = true); /**** @brief Traverses through the GeoVPhysVol tree and returns all sub volumes of this tree.*/ std::vector<GeoChildNodeWithTrf> getAllSubVolumes(PVConstLink physVol); - - +/*** @brief Traverses thorugh the GeoVPhysVOl tree and returns all subvolumes satisfying an external + * selection. + */ +std::vector<GeoChildNodeWithTrf> getAllSubVolumes(PVConstLink physVol, + std::function<bool(const GeoChildNodeWithTrf&)> selector, + bool summarizeEqualVol = false); /** * Returns whether a volume has fullPhysical volume nodes in diff --git a/GeoModelCore/GeoModelHelpers/src/getChildNodesWithTrf.cxx b/GeoModelCore/GeoModelHelpers/src/getChildNodesWithTrf.cxx index 3aa9dd8eb..819473880 100644 --- a/GeoModelCore/GeoModelHelpers/src/getChildNodesWithTrf.cxx +++ b/GeoModelCore/GeoModelHelpers/src/getChildNodesWithTrf.cxx @@ -64,14 +64,16 @@ std::vector <GeoChildNodeWithTrf> getChildrenWithRef(PVConstLink physVol, } return children; } - -std::vector<GeoChildNodeWithTrf> getAllSubVolumes(PVConstLink physVol) { - std::vector<GeoChildNodeWithTrf> children{getChildrenWithRef(physVol, false)}, subVolumes{}; +std::vector<GeoChildNodeWithTrf> getAllSubVolumes(PVConstLink physVol, + std::function<bool(const GeoChildNodeWithTrf&)> selector, + bool summarizeEqualVol) { + std::vector<GeoChildNodeWithTrf> children{getChildrenWithRef(physVol, summarizeEqualVol)}, subVolumes{}; subVolumes.reserve(children.size()); for (const GeoChildNodeWithTrf& child : children) { - subVolumes.push_back(child); - std::vector<GeoChildNodeWithTrf> grandChildren = getAllSubVolumes(child.volume); - subVolumes.reserve(grandChildren.size() + subVolumes.size()); + std::vector<GeoChildNodeWithTrf> grandChildren = getAllSubVolumes(child.volume, selector, summarizeEqualVol); + if (selector(child)) subVolumes.push_back(child); + + subVolumes.reserve(grandChildren.size() + subVolumes.capacity()); std::transform(std::make_move_iterator(grandChildren.begin()), std::make_move_iterator(grandChildren.end()), std::back_inserter(subVolumes), [&child](GeoChildNodeWithTrf&& grandChild){ @@ -80,6 +82,13 @@ std::vector<GeoChildNodeWithTrf> getAllSubVolumes(PVConstLink physVol) { }); } return subVolumes; + } + + +std::vector<GeoChildNodeWithTrf> getAllSubVolumes(PVConstLink physVol) { + return getAllSubVolumes(physVol, + [](const GeoChildNodeWithTrf& child){ + return true;}, false); } bool hasFullPhysVolInTree(PVConstLink physVol) { diff --git a/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoDefinitions.h b/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoDefinitions.h index cbc81fd9d..d1861a649 100644 --- a/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoDefinitions.h +++ b/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoDefinitions.h @@ -197,6 +197,8 @@ namespace GeoTrf { /// @brief Simple comparison returning -1, 0, 1 int compare(const EulerAngles& other) const; operator bool() const; + /// @brief Returns the set of Euler angles to invert the rotation + EulerAngles inverse() const; }; @@ -218,6 +220,8 @@ namespace GeoTrf { bool operator<(const CoordEulerAngles& other) const; /// @brief Simple comparison returning -1, 0, 1 int compare(const CoordEulerAngles& other) const; + /// @brief Returns the set of CoordEulerAngles to invert the Rotation + CoordEulerAngles inverse() const; operator bool() const; }; @@ -250,9 +254,10 @@ namespace GeoTrf { class GeoTransformRT : public Transform3D { public: - GeoTransformRT(const GeoRotation& rot, const Vector3D& trans) - : Transform3D(Translation3D(trans)*Transform3D(AngleAxis3D(rot))) - {} + GeoTransformRT(const GeoRotation& rot, const Vector3D& trans); + GeoTransformRT(const EulerAngles& angles, const Vector3D& trans); + GeoTransformRT(const CoordEulerAngles&angles, const Vector3D& trans); + virtual ~GeoTransformRT() = default; }; } diff --git a/GeoModelCore/GeoModelKernel/src/GeoDefinitions.cxx b/GeoModelCore/GeoModelKernel/src/GeoDefinitions.cxx index 79dd1b7a0..01e49145c 100755 --- a/GeoModelCore/GeoModelKernel/src/GeoDefinitions.cxx +++ b/GeoModelCore/GeoModelKernel/src/GeoDefinitions.cxx @@ -7,7 +7,7 @@ #include <cmath> namespace { - constexpr double rotTolerance = 0.01 * GeoModelKernelUnits::deg; + constexpr double rotTolerance = 0.001 * GeoModelKernelUnits::deg; inline double cutOff(const double val, const double cutOff) { return std::abs(val) > cutOff ? val : 0.; @@ -91,6 +91,10 @@ namespace GeoTrf { EulerAngles::operator bool() const { return std::abs(phi) > rotTolerance || std::abs(theta) > rotTolerance || std::abs(psi) > rotTolerance; } + EulerAngles EulerAngles::inverse() const { + return getGeoRotationAngles(GeoRotation(*this).inverse()); + } + int CoordEulerAngles::compare(const CoordEulerAngles& other) const { if (std::abs(alpha - other.alpha) > rotTolerance) return alpha < other.alpha ? -1 : 1; @@ -104,6 +108,21 @@ namespace GeoTrf { CoordEulerAngles::operator bool() const { return std::abs(alpha) > rotTolerance || std::abs(beta) > rotTolerance || std::abs(gamma) > rotTolerance; } + CoordEulerAngles CoordEulerAngles::inverse() const { + return getCoordRotationAngles(GeoRotation(*this).inverse()); + } + + GeoTransformRT::GeoTransformRT(const EulerAngles& angles, const Vector3D& trans): + GeoTransformRT{GeoRotation{angles}, trans}{} + + + GeoTransformRT::GeoTransformRT(const CoordEulerAngles&angles, const Vector3D& trans): + GeoTransformRT{GeoRotation{angles}, trans} { + + } + + GeoTransformRT::GeoTransformRT(const GeoRotation& rot, const Vector3D& trans): + Transform3D(Translation3D(trans)*Transform3D(AngleAxis3D(rot))){} } diff --git a/GeoModelCore/GeoModelKernel/tests/testEulerAngles.cxx b/GeoModelCore/GeoModelKernel/tests/testEulerAngles.cxx index bc3ed0758..541eebc2c 100644 --- a/GeoModelCore/GeoModelKernel/tests/testEulerAngles.cxx +++ b/GeoModelCore/GeoModelKernel/tests/testEulerAngles.cxx @@ -80,6 +80,12 @@ int main() { GeoTrf::get3DRotMatX(coordAngles.alpha *GeoModelKernelUnits::deg)<<std::endl; } + if (!isIdentity(coordRot * GeoTrf::GeoRotation{coordAngles.inverse()})){ + std::cout<<"testEulerAngles() "<<__LINE__<<"The inverse of "<<coordAngles<<" " + <<coordAngles.inverse()<<" does not lead to Identity rotation "<<std::endl; + return EXIT_FAILURE; + } + const GeoTrf::CoordEulerAngles calcCoordAngles = GeoTrf::getCoordRotationAngles(coordRot); const GeoTrf::GeoRotation extCoordRot{calcCoordAngles}; if (!isIdentity(extCoordRot.inverse()* coordRot)) { @@ -90,6 +96,11 @@ int main() { <<calcCoordAngles.beta*toDeg<<"/"<<calcCoordAngles.gamma*toDeg<<std::endl<<extCoordRot<<std::endl; return EXIT_FAILURE; } + if (!isIdentity(extCoordRot * GeoTrf::GeoRotation{calcCoordAngles.inverse()})){ + std::cout<<"testEulerAngles() "<<__LINE__<<"The inverse of "<<calcCoordAngles<<" " + <<calcCoordAngles.inverse()<<" does not lead to Identity rotation "<<std::endl; + return EXIT_FAILURE; + } } } } -- GitLab