Commit ff65e4d1 authored by Simon Spannagel's avatar Simon Spannagel
Browse files

DetectorModel: add post-constructor validation logic

parent 5384b87b
Loading
Loading
Loading
Loading
+17 −6
Original line number Diff line number Diff line
@@ -48,19 +48,25 @@ std::shared_ptr<DetectorModel> DetectorModel::factory(const std::string& name, c
    }

    // Instantiate the correct detector model
    std::shared_ptr<DetectorModel> model;
    if(geometry == "pixel") {
        return std::make_shared<PixelDetectorModel>(name, assembly, reader);
        model = std::make_shared<PixelDetectorModel>(name, assembly, reader);
    } else if(geometry == "radial_strip") {
        return std::make_shared<RadialStripDetectorModel>(name, assembly, reader);
        model = std::make_shared<RadialStripDetectorModel>(name, assembly, reader);
    } else if(geometry == "hexagonal") {
        return std::make_shared<HexagonalPixelDetectorModel>(name, assembly, reader);
    }

        model = std::make_shared<HexagonalPixelDetectorModel>(name, assembly, reader);
    } else {
        LOG(FATAL) << "Model file " << config.getFilePath() << " geometry parameter is not valid";
        // FIXME: The model can probably be silently ignored if we have more model readers later
        throw InvalidValueError(config, "geometry", "model geometry is not supported");
    }

    // Validate the detector model - we call this here because validation might depend on derived class properties:
    model->validate();

    return model;
}

DetectorModel::DetectorModel(std::string type, std::shared_ptr<DetectorAssembly> assembly, ConfigReader reader)
    : type_(std::move(type)), assembly_(std::move(assembly)), reader_(std::move(reader)) {
    using namespace ROOT::Math;
@@ -131,6 +137,11 @@ void DetectorModel::addImplant(const Implant::Type& type,
        Implant(type, shape, std::move(size), full_offset, ROOT::Math::RotationZ(orientation), std::move(config)));
}

void DetectorModel::validate() {
    // FIXME at some point we might make this a requirement and throw an exception instead?
    LOG(WARNING) << "No validation implemented for this detector geometry";
}

bool DetectorModel::Implant::contains(const ROOT::Math::XYZVector& position) const {
    // Shift position to implant coordinate system and apply rotation around z axis:
    auto pos = orientation_(position - offset_);
+14 −11
Original line number Diff line number Diff line
@@ -180,17 +180,6 @@ namespace allpix {
         */
        virtual ~DetectorModel() = default;

        ///@{
        /**
         * @brief Use default copy and move behaviour
         */
        DetectorModel(const DetectorModel&) = default;
        DetectorModel& operator=(const DetectorModel&) = default;

        DetectorModel(DetectorModel&&) = default;
        DetectorModel& operator=(DetectorModel&&) = default;
        ///@}

        /**
         * @brief Get the configuration associated with this model
         * @return Configuration used to construct the model
@@ -559,6 +548,20 @@ namespace allpix {
        std::vector<SupportLayer> support_layers_;

    private:
        ///@{
        /**
         * @brief Use default copy and move behaviour
         */
        DetectorModel(const DetectorModel&) = default;
        DetectorModel& operator=(const DetectorModel&) = default;

        DetectorModel(DetectorModel&&) = default;
        DetectorModel& operator=(DetectorModel&&) = default;
        ///@}

        // Validation of the detector model
        virtual void validate();

        ConfigReader reader_;
    };
} // namespace allpix
+21 −0
Original line number Diff line number Diff line
@@ -31,6 +31,27 @@ PixelDetectorModel::PixelDetectorModel(std::string type,
    setPixelSize(pixel_size);
}

void PixelDetectorModel::validate() {

    // Validate implants:
    for(const auto& implant : this->getImplants()) {
        if(implant.getSize().x() > pixel_size_.x() || implant.getSize().y() > pixel_size_.y()) {
            throw InvalidValueError(implant.getConfiguration(), "size", "implant size cannot be larger than pixel pitch");
        }
        if(implant.getSize().z() > getSensorSize().z()) {
            throw InvalidValueError(
                implant.getConfiguration(), "size", "implant depth cannot be larger than sensor thickness");
        }

        // Offset of the collection diode implant from the pixel center, defaults to zero.
        if(std::fabs(implant.getOffset().x()) + implant.getSize().x() / 2 > pixel_size_.x() / 2 ||
           std::fabs(implant.getOffset().y()) + implant.getSize().y() / 2 > pixel_size_.y() / 2) {
            throw InvalidValueError(
                implant.getConfiguration(), "offset", "implant exceeds pixel cell. Reduce implant size or offset");
        }
    }
}

/**
 * The definition of inside the sensor is determined by the detector model
 */
+3 −0
Original line number Diff line number Diff line
@@ -115,6 +115,9 @@ namespace allpix {
         * @return         Boolean whether pixels are neighbors or not
         */
        bool areNeighbors(const Pixel::Index& seed, const Pixel::Index& entrant, const size_t distance) const override;

    protected:
        void validate() override;
    };
} // namespace allpix