Loading src/core/geometry/DetectorModel.hpp +13 −0 Original line number Diff line number Diff line Loading @@ -391,6 +391,19 @@ namespace allpix { */ virtual bool isWithinSensor(const ROOT::Math::XYZPoint& local_pos) const = 0; /** * @brief Calculate exit point of step outside sensor volume from one point inside the sensor (before step) and one * point outside (after step). * @throws std::invalid_argument if no intersection of track segment with sensor volume can be found * @param inside Position before the step, inside the sensor volume * @param outside Position after the step, outside the sensor volume * @return Exit point of the sensor in local coordinates * * @note This method is purely virtual and must be implemented by the respective concrete detector model classes */ virtual ROOT::Math::XYZPoint getSensorIntercept(const ROOT::Math::XYZPoint& inside, const ROOT::Math::XYZPoint& outside) const = 0; /** * @brief Returns if a local position is within the pixel implant region of the sensitive device * @param local_pos Position in local coordinates of the detector model Loading src/core/geometry/PixelDetectorModel.cpp +18 −0 Original line number Diff line number Diff line Loading @@ -11,6 +11,9 @@ #include "PixelDetectorModel.hpp" #include "core/module/exceptions.h" #include "tools/liang_barsky.h" #include <Math/Translation3D.h> using namespace allpix; Loading Loading @@ -103,3 +106,18 @@ bool PixelDetectorModel::areNeighbors(const Pixel::Index& seed, const Pixel::Ind return (static_cast<size_t>(std::abs(seed.x() - entrant.x())) <= distance && static_cast<size_t>(std::abs(seed.y() - entrant.y())) <= distance); } ROOT::Math::XYZPoint PixelDetectorModel::getSensorIntercept(const ROOT::Math::XYZPoint& inside, const ROOT::Math::XYZPoint& outside) const { // Get direction vector of motion *out of* sensor auto direction = (outside - inside).Unit(); // We have to be centered around the sensor box. This means we need to shift by the matrix center auto translation_local = ROOT::Math::Translation3D(static_cast<ROOT::Math::XYZVector>(getMatrixCenter())); try { // Get intersection from Liang-Barsky line clipping and re-transform to local coordinates: return translation_local(LiangBarsky(direction, translation_local.Inverse()(inside), getSensorSize())); } catch(std::invalid_argument&) { return inside; } } src/core/geometry/PixelDetectorModel.hpp +13 −0 Original line number Diff line number Diff line Loading @@ -49,6 +49,19 @@ namespace allpix { */ bool isWithinSensor(const ROOT::Math::XYZPoint& local_pos) const override; /** * @brief Calculate exit point of step outside sensor volume from one point inside the sensor (before step) and one * point outside (after step). * @throws std::invalid_argument if no intersection of track segment with sensor volume can be found * @param inside Position before the step, inside the sensor volume * @param outside Position after the step, outside the sensor volume * @return Exit point of the sensor in local coordinates * * @note This method uses the Liang-Barsky clipping of a line segment with a box */ ROOT::Math::XYZPoint getSensorIntercept(const ROOT::Math::XYZPoint& inside, const ROOT::Math::XYZPoint& outside) const override; /** * @brief Returns if a local position is within the pixel implant region of the sensitive device * @param local_pos Position in local coordinates of the detector model Loading src/core/geometry/RadialStripDetectorModel.cpp +17 −0 Original line number Diff line number Diff line Loading @@ -249,3 +249,20 @@ bool RadialStripDetectorModel::areNeighbors(const Pixel::Index& seed, return (static_cast<size_t>(std::abs(row_seed_x - entrant.x())) <= distance) && (static_cast<size_t>(std::abs(dist_y)) <= distance); } ROOT::Math::XYZPoint RadialStripDetectorModel::getSensorIntercept(const ROOT::Math::XYZPoint& inside, const ROOT::Math::XYZPoint& outside) const { auto check_position = outside; check_position.SetZ(inside.z()); if(std::fabs(outside.z()) > getSensorSize().z() / 2.0 && isWithinSensor(check_position)) { // Carrier left sensor on the top or bottom surface of the sensor, interpolate end point on surface auto z_cur_border = std::fabs(outside.z() - getSensorSize().z() / 2.0); auto z_last_border = std::fabs(getSensorSize().z() / 2.0 - inside.z()); auto z_total = z_cur_border + z_last_border; return (z_last_border / z_total) * static_cast<ROOT::Math::XYZVector>(outside) + (z_cur_border / z_total) * inside; } else { // Carrier left sensor on any other border, use last position inside instead return inside; } } src/core/geometry/RadialStripDetectorModel.hpp +14 −0 Original line number Diff line number Diff line Loading @@ -207,6 +207,20 @@ namespace allpix { */ bool isWithinSensor(const ROOT::Math::XYZPoint& position) const override; /** * @brief Calculate exit point of step outside sensor volume from one point inside the sensor (before step) and one * point outside (after step). * @throws std::invalid_argument if no intersection of track segment with sensor volume can be found * @param inside Position before the step, inside the sensor volume * @param outside Position after the step, outside the sensor volume * @return Exit point of the sensor in local coordinates * * @note This method currently only interpolates the z coordinate between the last two points and returns the last * position inside otherwise */ ROOT::Math::XYZPoint getSensorIntercept(const ROOT::Math::XYZPoint& inside, const ROOT::Math::XYZPoint& outside) const override; /** * @brief Returns if a local position is within the pixel implant region of the sensitive device * @param position Position in local coordinates of the detector model Loading Loading
src/core/geometry/DetectorModel.hpp +13 −0 Original line number Diff line number Diff line Loading @@ -391,6 +391,19 @@ namespace allpix { */ virtual bool isWithinSensor(const ROOT::Math::XYZPoint& local_pos) const = 0; /** * @brief Calculate exit point of step outside sensor volume from one point inside the sensor (before step) and one * point outside (after step). * @throws std::invalid_argument if no intersection of track segment with sensor volume can be found * @param inside Position before the step, inside the sensor volume * @param outside Position after the step, outside the sensor volume * @return Exit point of the sensor in local coordinates * * @note This method is purely virtual and must be implemented by the respective concrete detector model classes */ virtual ROOT::Math::XYZPoint getSensorIntercept(const ROOT::Math::XYZPoint& inside, const ROOT::Math::XYZPoint& outside) const = 0; /** * @brief Returns if a local position is within the pixel implant region of the sensitive device * @param local_pos Position in local coordinates of the detector model Loading
src/core/geometry/PixelDetectorModel.cpp +18 −0 Original line number Diff line number Diff line Loading @@ -11,6 +11,9 @@ #include "PixelDetectorModel.hpp" #include "core/module/exceptions.h" #include "tools/liang_barsky.h" #include <Math/Translation3D.h> using namespace allpix; Loading Loading @@ -103,3 +106,18 @@ bool PixelDetectorModel::areNeighbors(const Pixel::Index& seed, const Pixel::Ind return (static_cast<size_t>(std::abs(seed.x() - entrant.x())) <= distance && static_cast<size_t>(std::abs(seed.y() - entrant.y())) <= distance); } ROOT::Math::XYZPoint PixelDetectorModel::getSensorIntercept(const ROOT::Math::XYZPoint& inside, const ROOT::Math::XYZPoint& outside) const { // Get direction vector of motion *out of* sensor auto direction = (outside - inside).Unit(); // We have to be centered around the sensor box. This means we need to shift by the matrix center auto translation_local = ROOT::Math::Translation3D(static_cast<ROOT::Math::XYZVector>(getMatrixCenter())); try { // Get intersection from Liang-Barsky line clipping and re-transform to local coordinates: return translation_local(LiangBarsky(direction, translation_local.Inverse()(inside), getSensorSize())); } catch(std::invalid_argument&) { return inside; } }
src/core/geometry/PixelDetectorModel.hpp +13 −0 Original line number Diff line number Diff line Loading @@ -49,6 +49,19 @@ namespace allpix { */ bool isWithinSensor(const ROOT::Math::XYZPoint& local_pos) const override; /** * @brief Calculate exit point of step outside sensor volume from one point inside the sensor (before step) and one * point outside (after step). * @throws std::invalid_argument if no intersection of track segment with sensor volume can be found * @param inside Position before the step, inside the sensor volume * @param outside Position after the step, outside the sensor volume * @return Exit point of the sensor in local coordinates * * @note This method uses the Liang-Barsky clipping of a line segment with a box */ ROOT::Math::XYZPoint getSensorIntercept(const ROOT::Math::XYZPoint& inside, const ROOT::Math::XYZPoint& outside) const override; /** * @brief Returns if a local position is within the pixel implant region of the sensitive device * @param local_pos Position in local coordinates of the detector model Loading
src/core/geometry/RadialStripDetectorModel.cpp +17 −0 Original line number Diff line number Diff line Loading @@ -249,3 +249,20 @@ bool RadialStripDetectorModel::areNeighbors(const Pixel::Index& seed, return (static_cast<size_t>(std::abs(row_seed_x - entrant.x())) <= distance) && (static_cast<size_t>(std::abs(dist_y)) <= distance); } ROOT::Math::XYZPoint RadialStripDetectorModel::getSensorIntercept(const ROOT::Math::XYZPoint& inside, const ROOT::Math::XYZPoint& outside) const { auto check_position = outside; check_position.SetZ(inside.z()); if(std::fabs(outside.z()) > getSensorSize().z() / 2.0 && isWithinSensor(check_position)) { // Carrier left sensor on the top or bottom surface of the sensor, interpolate end point on surface auto z_cur_border = std::fabs(outside.z() - getSensorSize().z() / 2.0); auto z_last_border = std::fabs(getSensorSize().z() / 2.0 - inside.z()); auto z_total = z_cur_border + z_last_border; return (z_last_border / z_total) * static_cast<ROOT::Math::XYZVector>(outside) + (z_cur_border / z_total) * inside; } else { // Carrier left sensor on any other border, use last position inside instead return inside; } }
src/core/geometry/RadialStripDetectorModel.hpp +14 −0 Original line number Diff line number Diff line Loading @@ -207,6 +207,20 @@ namespace allpix { */ bool isWithinSensor(const ROOT::Math::XYZPoint& position) const override; /** * @brief Calculate exit point of step outside sensor volume from one point inside the sensor (before step) and one * point outside (after step). * @throws std::invalid_argument if no intersection of track segment with sensor volume can be found * @param inside Position before the step, inside the sensor volume * @param outside Position after the step, outside the sensor volume * @return Exit point of the sensor in local coordinates * * @note This method currently only interpolates the z coordinate between the last two points and returns the last * position inside otherwise */ ROOT::Math::XYZPoint getSensorIntercept(const ROOT::Math::XYZPoint& inside, const ROOT::Math::XYZPoint& outside) const override; /** * @brief Returns if a local position is within the pixel implant region of the sensitive device * @param position Position in local coordinates of the detector model Loading