Commit 1b28e423 authored by Simon Spannagel's avatar Simon Spannagel
Browse files

Merge branch 'pixel-detector-class' into 'master'

Pixel detector class

See merge request allpix-squared/allpix-squared!586
parents f497a2dd 78109b73
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ ADD_LIBRARY(
    geometry/Detector.cpp
    geometry/DetectorField.cpp
    geometry/DetectorModel.cpp
    geometry/PixelDetectorModel.cpp
    geometry/GeometryManager.cpp
    Allpix.cpp)

+0 −84
Original line number Diff line number Diff line
@@ -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
@@ -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);
}
+29 −13
Original line number Diff line number Diff line
@@ -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_;
        }
        /**
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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_;
+3 −3
Original line number Diff line number Diff line
@@ -20,7 +20,7 @@
#include <Math/Vector2D.h>
#include <Math/Vector3D.h>

#include "DetectorModel.hpp"
#include "PixelDetectorModel.hpp"

namespace allpix {

@@ -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
@@ -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
+4 −4
Original line number Diff line number Diff line
@@ -20,7 +20,7 @@
#include <Math/Vector2D.h>
#include <Math/Vector3D.h>

#include "DetectorModel.hpp"
#include "PixelDetectorModel.hpp"

namespace allpix {

@@ -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
@@ -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