Loading src/core/CMakeLists.txt +1 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ ADD_LIBRARY( geometry/Detector.cpp geometry/DetectorField.cpp geometry/DetectorModel.cpp geometry/PixelDetectorModel.cpp geometry/GeometryManager.cpp Allpix.cpp) Loading src/core/geometry/DetectorModel.cpp +0 −84 Original line number Diff line number Diff line Loading @@ -41,18 +41,6 @@ DetectorModel::DetectorModel(std::string type, ConfigReader reader) : type_(std: using namespace ROOT::Math; auto config = reader_.getHeaderConfiguration(); // Number of pixels setNPixels(config.get<DisplacementVector2D<Cartesian2D<unsigned int>>>("number_of_pixels")); // Size of the pixels auto pixel_size = config.get<XYVector>("pixel_size"); setPixelSize(pixel_size); // Size of the collection diode implant on each pixels, defaults to the full pixel size when not specified auto implant_size = config.get<XYVector>("implant_size", pixel_size); if(implant_size.x() > pixel_size.x() || implant_size.y() > pixel_size.y()) { throw InvalidValueError(config, "implant_size", "implant size cannot be larger than pixel pitch"); } setImplantSize(implant_size); // Sensor thickness setSensorThickness(config.get<double>("sensor_thickness")); // Excess around the sensor from the pixel grid Loading Loading @@ -195,75 +183,3 @@ std::vector<DetectorModel::SupportLayer> DetectorModel::getSupportLayers() const return ret_layers; } /** * The definition of inside the sensor is determined by the detector model */ bool DetectorModel::isWithinSensor(const ROOT::Math::XYZPoint& local_pos) const { auto sensor_center = getSensorCenter(); auto sensor_size = getSensorSize(); return (2 * std::fabs(local_pos.z() - sensor_center.z()) <= sensor_size.z()) && (2 * std::fabs(local_pos.y() - sensor_center.y()) <= sensor_size.y()) && (2 * std::fabs(local_pos.x() - sensor_center.x()) <= sensor_size.x()); } /** * The definition of inside the implant region is determined by the detector model * * @note The pixel implant currently is always positioned symmetrically, in the center of the pixel cell. */ bool DetectorModel::isWithinImplant(const ROOT::Math::XYZPoint& local_pos) const { auto [xpixel, ypixel] = getPixelIndex(local_pos); auto inPixelPos = local_pos - getPixelCenter(static_cast<unsigned int>(xpixel), static_cast<unsigned int>(ypixel)); return (std::fabs(inPixelPos.x()) <= std::fabs(getImplantSize().x() / 2) && std::fabs(inPixelPos.y()) <= std::fabs(getImplantSize().y() / 2)); } /** * The definition of the pixel grid size is determined by the detector model */ bool DetectorModel::isWithinMatrix(const Pixel::Index& pixel_index) const { return !(pixel_index.x() >= number_of_pixels_.x() || pixel_index.y() >= number_of_pixels_.y()); } /** * The definition of the pixel grid size is determined by the detector model */ bool DetectorModel::isWithinMatrix(const int x, const int y) const { return !(x < 0 || x >= static_cast<int>(number_of_pixels_.x()) || y < 0 || y >= static_cast<int>(number_of_pixels_.y())); } ROOT::Math::XYZPoint DetectorModel::getPixelCenter(unsigned int x, unsigned int y) const { auto size = getPixelSize(); auto local_x = size.x() * x; auto local_y = size.y() * y; return {local_x, local_y, 0}; } std::pair<int, int> DetectorModel::getPixelIndex(const ROOT::Math::XYZPoint& position) const { auto pixel_x = static_cast<int>(std::round(position.x() / pixel_size_.x())); auto pixel_y = static_cast<int>(std::round(position.y() / pixel_size_.y())); return {pixel_x, pixel_y}; } std::set<Pixel::Index> DetectorModel::getNeighbors(const Pixel::Index& idx, const size_t distance) const { std::set<Pixel::Index> neighbors; for(int x = static_cast<int>(idx.x() - distance); x <= static_cast<int>(idx.x() + distance); x++) { for(int y = static_cast<int>(idx.y() - distance); y <= static_cast<int>(idx.y() + distance); y++) { if(!isWithinMatrix(x, y)) { continue; } neighbors.insert({static_cast<unsigned int>(x), static_cast<unsigned int>(y)}); } } return neighbors; } bool DetectorModel::areNeighbors(const Pixel::Index& seed, const Pixel::Index& entrant, const size_t distance) const { auto pixel_distance = [](unsigned int lhs, unsigned int rhs) { return (lhs > rhs ? lhs - rhs : rhs - lhs); }; return (pixel_distance(seed.x(), entrant.x()) <= distance && pixel_distance(seed.y(), entrant.y()) <= distance); } src/core/geometry/DetectorModel.hpp +29 −13 Original line number Diff line number Diff line Loading @@ -207,10 +207,10 @@ namespace allpix { /* PIXEL GRID */ /** * @brief Get number of pixel (replicated blocks in generic sensors) * @brief Get number of pixels (replicated blocks in generic sensors) * @return Number of two dimensional pixels */ virtual ROOT::Math::DisplacementVector2D<ROOT::Math::Cartesian2D<unsigned int>> getNPixels() const { ROOT::Math::DisplacementVector2D<ROOT::Math::Cartesian2D<unsigned int>> getNPixels() const { return number_of_pixels_; } /** Loading @@ -224,7 +224,7 @@ namespace allpix { * @brief Get size of a single pixel * @return Size of a pixel */ virtual ROOT::Math::XYVector getPixelSize() const { return pixel_size_; } ROOT::Math::XYVector getPixelSize() const { return pixel_size_; } /** * @brief Set the size of a pixel * @param val Size of a pixel Loading @@ -234,7 +234,7 @@ namespace allpix { * @brief Get size of the collection diode * @return Size of the collection diode implant */ virtual ROOT::Math::XYVector getImplantSize() const { return implant_size_; } ROOT::Math::XYVector getImplantSize() const { return implant_size_; } /** * @brief Set the size of the implant (collection diode) within a pixel * @param val Size of the collection diode implant Loading Loading @@ -377,47 +377,59 @@ namespace allpix { * @brief Returns if a local position is within the sensitive device * @param local_pos Position in local coordinates of the detector model * @return True if a local position is within the sensor, false otherwise * * @note This method is purely virtual and must be implemented by the respective concrete detector model classes */ virtual bool isWithinSensor(const ROOT::Math::XYZPoint& local_pos) const; virtual bool isWithinSensor(const ROOT::Math::XYZPoint& local_pos) 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 * @return True if a local position is within the pixel implant, false otherwise * * @note This method is purely virtual and must be implemented by the respective concrete detector model classes */ virtual bool isWithinImplant(const ROOT::Math::XYZPoint& local_pos) const; virtual bool isWithinImplant(const ROOT::Math::XYZPoint& local_pos) const = 0; /** * @brief Returns if a pixel index is within the grid of pixels defined for the device * @param pixel_index Pixel index to be checked * @return True if pixel_index is within the pixel grid, false otherwise * * @note This method is purely virtual and must be implemented by the respective concrete detector model classes */ virtual bool isWithinMatrix(const Pixel::Index& pixel_index) const; virtual bool isWithinMatrix(const Pixel::Index& pixel_index) const = 0; /** * @brief Returns if a set of pixel coordinates is within the grid of pixels defined for the device * @param x X- (or column-) coordinate to be checked * @param y Y- (or row-) coordinate to be checked * @return True if pixel coordinates are within the pixel grid, false otherwise * * @note This method is purely virtual and must be implemented by the respective concrete detector model classes */ virtual bool isWithinMatrix(const int x, const int y) const; virtual bool isWithinMatrix(const int x, const int y) const = 0; /** * @brief Returns a pixel center in local coordinates * @param x X- (or column-) coordinate of the pixel * @param y Y- (or row-) coordinate of the pixel * @return Coordinates of the pixel center * * @note This method is purely virtual and must be implemented by the respective concrete detector model classes */ virtual ROOT::Math::XYZPoint getPixelCenter(unsigned int x, unsigned int y) const; virtual ROOT::Math::XYZPoint getPixelCenter(unsigned int x, unsigned int y) const = 0; /** * @brief Return X,Y indices of a pixel corresponding to a local position in a sensor. * @param position Position in local coordinates of the detector model * @param local_pos Position in local coordinates of the detector model * @return X,Y pixel indices * * @note No checks are performed on whether these indices represent an existing pixel or are within the pixel matrix. * * @note This method is purely virtual and must be implemented by the respective concrete detector model classes */ virtual std::pair<int, int> getPixelIndex(const ROOT::Math::XYZPoint& position) const; virtual std::pair<int, int> getPixelIndex(const ROOT::Math::XYZPoint& local_pos) const = 0; /** * @brief Return a set containing all pixels neighboring the given one with a configurable maximum distance Loading @@ -426,8 +438,10 @@ namespace allpix { * @return Set of neighboring pixel indices, including the initial pixel * * @note The returned set should always also include the initial pixel indices the neighbors are calculated for * * @note This method is purely virtual and must be implemented by the respective concrete detector model classes */ virtual std::set<Pixel::Index> getNeighbors(const Pixel::Index& idx, const size_t distance) const; virtual std::set<Pixel::Index> getNeighbors(const Pixel::Index& idx, const size_t distance) const = 0; /** * @brief Check if two pixel indices are neighbors to each other Loading @@ -435,8 +449,10 @@ namespace allpix { * @param entrant Entrant pixel index to be tested * @param distance Distance for pixels to be considered neighbors * @return Boolean whether pixels are neighbors or not * * @note This method is purely virtual and must be implemented by the respective concrete detector model classes */ virtual bool areNeighbors(const Pixel::Index& seed, const Pixel::Index& entrant, const size_t distance) const; virtual bool areNeighbors(const Pixel::Index& seed, const Pixel::Index& entrant, const size_t distance) const = 0; protected: std::string type_; Loading src/core/geometry/HybridPixelDetectorModel.hpp +3 −3 Original line number Diff line number Diff line Loading @@ -20,7 +20,7 @@ #include <Math/Vector2D.h> #include <Math/Vector3D.h> #include "DetectorModel.hpp" #include "PixelDetectorModel.hpp" namespace allpix { Loading @@ -28,7 +28,7 @@ namespace allpix { * @ingroup DetectorModels * @brief Model of a hybrid pixel detector. This a model where the sensor is bump-bonded to the chip */ class HybridPixelDetectorModel : public DetectorModel { class HybridPixelDetectorModel : public PixelDetectorModel { public: /** * @brief Constructs the hybrid pixel detector model Loading @@ -36,7 +36,7 @@ namespace allpix { * @param reader Configuration reader with description of the model */ explicit HybridPixelDetectorModel(std::string type, const ConfigReader& reader) : DetectorModel(std::move(type), reader) { : PixelDetectorModel(std::move(type), reader) { auto config = reader.getHeaderConfiguration(); // Excess around the chip from the pixel grid Loading src/core/geometry/MonolithicPixelDetectorModel.hpp +4 −4 Original line number Diff line number Diff line Loading @@ -20,7 +20,7 @@ #include <Math/Vector2D.h> #include <Math/Vector3D.h> #include "DetectorModel.hpp" #include "PixelDetectorModel.hpp" namespace allpix { Loading @@ -29,9 +29,9 @@ namespace allpix { * @brief Model of a monolithic pixel detector. This a model where sensor and readout electronics are placed within the * same silicon wafer. * * This model is already fully implemented in the \ref DetectorModel base class. * This model is already fully implemented in the \ref PixelDetectorModel base class. */ class MonolithicPixelDetectorModel : public DetectorModel { class MonolithicPixelDetectorModel : public PixelDetectorModel { public: /** * @brief Constructs the monolithic pixel detector model Loading @@ -39,7 +39,7 @@ namespace allpix { * @param reader Configuration reader with description of the model */ explicit MonolithicPixelDetectorModel(std::string type, const ConfigReader& reader) : DetectorModel(std::move(type), reader) {} : PixelDetectorModel(std::move(type), reader) {} }; } // namespace allpix Loading Loading
src/core/CMakeLists.txt +1 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ ADD_LIBRARY( geometry/Detector.cpp geometry/DetectorField.cpp geometry/DetectorModel.cpp geometry/PixelDetectorModel.cpp geometry/GeometryManager.cpp Allpix.cpp) Loading
src/core/geometry/DetectorModel.cpp +0 −84 Original line number Diff line number Diff line Loading @@ -41,18 +41,6 @@ DetectorModel::DetectorModel(std::string type, ConfigReader reader) : type_(std: using namespace ROOT::Math; auto config = reader_.getHeaderConfiguration(); // Number of pixels setNPixels(config.get<DisplacementVector2D<Cartesian2D<unsigned int>>>("number_of_pixels")); // Size of the pixels auto pixel_size = config.get<XYVector>("pixel_size"); setPixelSize(pixel_size); // Size of the collection diode implant on each pixels, defaults to the full pixel size when not specified auto implant_size = config.get<XYVector>("implant_size", pixel_size); if(implant_size.x() > pixel_size.x() || implant_size.y() > pixel_size.y()) { throw InvalidValueError(config, "implant_size", "implant size cannot be larger than pixel pitch"); } setImplantSize(implant_size); // Sensor thickness setSensorThickness(config.get<double>("sensor_thickness")); // Excess around the sensor from the pixel grid Loading Loading @@ -195,75 +183,3 @@ std::vector<DetectorModel::SupportLayer> DetectorModel::getSupportLayers() const return ret_layers; } /** * The definition of inside the sensor is determined by the detector model */ bool DetectorModel::isWithinSensor(const ROOT::Math::XYZPoint& local_pos) const { auto sensor_center = getSensorCenter(); auto sensor_size = getSensorSize(); return (2 * std::fabs(local_pos.z() - sensor_center.z()) <= sensor_size.z()) && (2 * std::fabs(local_pos.y() - sensor_center.y()) <= sensor_size.y()) && (2 * std::fabs(local_pos.x() - sensor_center.x()) <= sensor_size.x()); } /** * The definition of inside the implant region is determined by the detector model * * @note The pixel implant currently is always positioned symmetrically, in the center of the pixel cell. */ bool DetectorModel::isWithinImplant(const ROOT::Math::XYZPoint& local_pos) const { auto [xpixel, ypixel] = getPixelIndex(local_pos); auto inPixelPos = local_pos - getPixelCenter(static_cast<unsigned int>(xpixel), static_cast<unsigned int>(ypixel)); return (std::fabs(inPixelPos.x()) <= std::fabs(getImplantSize().x() / 2) && std::fabs(inPixelPos.y()) <= std::fabs(getImplantSize().y() / 2)); } /** * The definition of the pixel grid size is determined by the detector model */ bool DetectorModel::isWithinMatrix(const Pixel::Index& pixel_index) const { return !(pixel_index.x() >= number_of_pixels_.x() || pixel_index.y() >= number_of_pixels_.y()); } /** * The definition of the pixel grid size is determined by the detector model */ bool DetectorModel::isWithinMatrix(const int x, const int y) const { return !(x < 0 || x >= static_cast<int>(number_of_pixels_.x()) || y < 0 || y >= static_cast<int>(number_of_pixels_.y())); } ROOT::Math::XYZPoint DetectorModel::getPixelCenter(unsigned int x, unsigned int y) const { auto size = getPixelSize(); auto local_x = size.x() * x; auto local_y = size.y() * y; return {local_x, local_y, 0}; } std::pair<int, int> DetectorModel::getPixelIndex(const ROOT::Math::XYZPoint& position) const { auto pixel_x = static_cast<int>(std::round(position.x() / pixel_size_.x())); auto pixel_y = static_cast<int>(std::round(position.y() / pixel_size_.y())); return {pixel_x, pixel_y}; } std::set<Pixel::Index> DetectorModel::getNeighbors(const Pixel::Index& idx, const size_t distance) const { std::set<Pixel::Index> neighbors; for(int x = static_cast<int>(idx.x() - distance); x <= static_cast<int>(idx.x() + distance); x++) { for(int y = static_cast<int>(idx.y() - distance); y <= static_cast<int>(idx.y() + distance); y++) { if(!isWithinMatrix(x, y)) { continue; } neighbors.insert({static_cast<unsigned int>(x), static_cast<unsigned int>(y)}); } } return neighbors; } bool DetectorModel::areNeighbors(const Pixel::Index& seed, const Pixel::Index& entrant, const size_t distance) const { auto pixel_distance = [](unsigned int lhs, unsigned int rhs) { return (lhs > rhs ? lhs - rhs : rhs - lhs); }; return (pixel_distance(seed.x(), entrant.x()) <= distance && pixel_distance(seed.y(), entrant.y()) <= distance); }
src/core/geometry/DetectorModel.hpp +29 −13 Original line number Diff line number Diff line Loading @@ -207,10 +207,10 @@ namespace allpix { /* PIXEL GRID */ /** * @brief Get number of pixel (replicated blocks in generic sensors) * @brief Get number of pixels (replicated blocks in generic sensors) * @return Number of two dimensional pixels */ virtual ROOT::Math::DisplacementVector2D<ROOT::Math::Cartesian2D<unsigned int>> getNPixels() const { ROOT::Math::DisplacementVector2D<ROOT::Math::Cartesian2D<unsigned int>> getNPixels() const { return number_of_pixels_; } /** Loading @@ -224,7 +224,7 @@ namespace allpix { * @brief Get size of a single pixel * @return Size of a pixel */ virtual ROOT::Math::XYVector getPixelSize() const { return pixel_size_; } ROOT::Math::XYVector getPixelSize() const { return pixel_size_; } /** * @brief Set the size of a pixel * @param val Size of a pixel Loading @@ -234,7 +234,7 @@ namespace allpix { * @brief Get size of the collection diode * @return Size of the collection diode implant */ virtual ROOT::Math::XYVector getImplantSize() const { return implant_size_; } ROOT::Math::XYVector getImplantSize() const { return implant_size_; } /** * @brief Set the size of the implant (collection diode) within a pixel * @param val Size of the collection diode implant Loading Loading @@ -377,47 +377,59 @@ namespace allpix { * @brief Returns if a local position is within the sensitive device * @param local_pos Position in local coordinates of the detector model * @return True if a local position is within the sensor, false otherwise * * @note This method is purely virtual and must be implemented by the respective concrete detector model classes */ virtual bool isWithinSensor(const ROOT::Math::XYZPoint& local_pos) const; virtual bool isWithinSensor(const ROOT::Math::XYZPoint& local_pos) 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 * @return True if a local position is within the pixel implant, false otherwise * * @note This method is purely virtual and must be implemented by the respective concrete detector model classes */ virtual bool isWithinImplant(const ROOT::Math::XYZPoint& local_pos) const; virtual bool isWithinImplant(const ROOT::Math::XYZPoint& local_pos) const = 0; /** * @brief Returns if a pixel index is within the grid of pixels defined for the device * @param pixel_index Pixel index to be checked * @return True if pixel_index is within the pixel grid, false otherwise * * @note This method is purely virtual and must be implemented by the respective concrete detector model classes */ virtual bool isWithinMatrix(const Pixel::Index& pixel_index) const; virtual bool isWithinMatrix(const Pixel::Index& pixel_index) const = 0; /** * @brief Returns if a set of pixel coordinates is within the grid of pixels defined for the device * @param x X- (or column-) coordinate to be checked * @param y Y- (or row-) coordinate to be checked * @return True if pixel coordinates are within the pixel grid, false otherwise * * @note This method is purely virtual and must be implemented by the respective concrete detector model classes */ virtual bool isWithinMatrix(const int x, const int y) const; virtual bool isWithinMatrix(const int x, const int y) const = 0; /** * @brief Returns a pixel center in local coordinates * @param x X- (or column-) coordinate of the pixel * @param y Y- (or row-) coordinate of the pixel * @return Coordinates of the pixel center * * @note This method is purely virtual and must be implemented by the respective concrete detector model classes */ virtual ROOT::Math::XYZPoint getPixelCenter(unsigned int x, unsigned int y) const; virtual ROOT::Math::XYZPoint getPixelCenter(unsigned int x, unsigned int y) const = 0; /** * @brief Return X,Y indices of a pixel corresponding to a local position in a sensor. * @param position Position in local coordinates of the detector model * @param local_pos Position in local coordinates of the detector model * @return X,Y pixel indices * * @note No checks are performed on whether these indices represent an existing pixel or are within the pixel matrix. * * @note This method is purely virtual and must be implemented by the respective concrete detector model classes */ virtual std::pair<int, int> getPixelIndex(const ROOT::Math::XYZPoint& position) const; virtual std::pair<int, int> getPixelIndex(const ROOT::Math::XYZPoint& local_pos) const = 0; /** * @brief Return a set containing all pixels neighboring the given one with a configurable maximum distance Loading @@ -426,8 +438,10 @@ namespace allpix { * @return Set of neighboring pixel indices, including the initial pixel * * @note The returned set should always also include the initial pixel indices the neighbors are calculated for * * @note This method is purely virtual and must be implemented by the respective concrete detector model classes */ virtual std::set<Pixel::Index> getNeighbors(const Pixel::Index& idx, const size_t distance) const; virtual std::set<Pixel::Index> getNeighbors(const Pixel::Index& idx, const size_t distance) const = 0; /** * @brief Check if two pixel indices are neighbors to each other Loading @@ -435,8 +449,10 @@ namespace allpix { * @param entrant Entrant pixel index to be tested * @param distance Distance for pixels to be considered neighbors * @return Boolean whether pixels are neighbors or not * * @note This method is purely virtual and must be implemented by the respective concrete detector model classes */ virtual bool areNeighbors(const Pixel::Index& seed, const Pixel::Index& entrant, const size_t distance) const; virtual bool areNeighbors(const Pixel::Index& seed, const Pixel::Index& entrant, const size_t distance) const = 0; protected: std::string type_; Loading
src/core/geometry/HybridPixelDetectorModel.hpp +3 −3 Original line number Diff line number Diff line Loading @@ -20,7 +20,7 @@ #include <Math/Vector2D.h> #include <Math/Vector3D.h> #include "DetectorModel.hpp" #include "PixelDetectorModel.hpp" namespace allpix { Loading @@ -28,7 +28,7 @@ namespace allpix { * @ingroup DetectorModels * @brief Model of a hybrid pixel detector. This a model where the sensor is bump-bonded to the chip */ class HybridPixelDetectorModel : public DetectorModel { class HybridPixelDetectorModel : public PixelDetectorModel { public: /** * @brief Constructs the hybrid pixel detector model Loading @@ -36,7 +36,7 @@ namespace allpix { * @param reader Configuration reader with description of the model */ explicit HybridPixelDetectorModel(std::string type, const ConfigReader& reader) : DetectorModel(std::move(type), reader) { : PixelDetectorModel(std::move(type), reader) { auto config = reader.getHeaderConfiguration(); // Excess around the chip from the pixel grid Loading
src/core/geometry/MonolithicPixelDetectorModel.hpp +4 −4 Original line number Diff line number Diff line Loading @@ -20,7 +20,7 @@ #include <Math/Vector2D.h> #include <Math/Vector3D.h> #include "DetectorModel.hpp" #include "PixelDetectorModel.hpp" namespace allpix { Loading @@ -29,9 +29,9 @@ namespace allpix { * @brief Model of a monolithic pixel detector. This a model where sensor and readout electronics are placed within the * same silicon wafer. * * This model is already fully implemented in the \ref DetectorModel base class. * This model is already fully implemented in the \ref PixelDetectorModel base class. */ class MonolithicPixelDetectorModel : public DetectorModel { class MonolithicPixelDetectorModel : public PixelDetectorModel { public: /** * @brief Constructs the monolithic pixel detector model Loading @@ -39,7 +39,7 @@ namespace allpix { * @param reader Configuration reader with description of the model */ explicit MonolithicPixelDetectorModel(std::string type, const ConfigReader& reader) : DetectorModel(std::move(type), reader) {} : PixelDetectorModel(std::move(type), reader) {} }; } // namespace allpix Loading