Commit 3db13ef3 authored by Simon Spannagel's avatar Simon Spannagel
Browse files

DepositionPointCharge: add possibility to run multiple events per scan cell

parent 189b6b1b
Loading
Loading
Loading
Loading
+23 −16
Original line number Diff line number Diff line
@@ -146,10 +146,15 @@ void DepositionPointChargeModule::initialize() {
        }

        // Check that the scan setup is correct
        root_ = events;
        events_per_cell_ = config_.get<unsigned int>("events_per_cell", 1);
        if(events % events_per_cell_ != 0) {
            LOG(WARNING) << "Number of events cannot be divided into cells evenly";
        }

        root_ = events / events_per_cell_;
        if(no_of_coordinates_ == 2) {
            root_ = static_cast<unsigned int>(std::lround(std::sqrt(events)));
            if(events != root_ * root_) {
            root_ = static_cast<unsigned int>(std::lround(std::sqrt(events / events_per_cell_)));
            if(events != root_ * root_ * events_per_cell_) {
                LOG(WARNING) << "Number of events is not a square, pixel cell volume cannot fully be covered in scan. "
                             << "Closest square is " << root_ * root_;
            }
@@ -160,8 +165,8 @@ void DepositionPointChargeModule::initialize() {
                                        "The coordinates must be x, y, or z, and a coordinate must not be repeated");
            }
        } else if(no_of_coordinates_ == 3) {
            root_ = static_cast<unsigned int>(std::lround(std::cbrt(events)));
            if(events != root_ * root_ * root_) {
            root_ = static_cast<unsigned int>(std::lround(std::cbrt(events / events_per_cell_)));
            if(events != root_ * root_ * root_ * events_per_cell_) {
                LOG(WARNING) << "Number of events is not a cube, pixel cell volume cannot fully be covered in scan. "
                             << "Closest cube is " << root_ * root_ * root_;
            }
@@ -218,6 +223,9 @@ void DepositionPointChargeModule::run(Event* event) {
        // Fixed position as read from the configuration:
        position = position_;
    } else if(model_ == DepositionModel::SCAN) {
        // Voxel iterator depends in number of events per cell:
        const auto voxel_it = (event->number - 1) / events_per_cell_;

        // Center the volume to be scanned in the center of the sensor,
        // reference point is lower left corner of one pixel volume
        auto ref = position_ + detector_model_->getMatrixSize() / 2.0 + voxel_ / 2.0 -
@@ -226,27 +234,26 @@ void DepositionPointChargeModule::run(Event* event) {
                                         detector_model_->getSensorSize().z() / 2.0);
        LOG(DEBUG) << "Reference: " << Units::display(ref, {"um", "mm"});
        if(no_of_coordinates_ == 3) {
            position =
                ROOT::Math::XYZPoint(voxel_.x() * static_cast<double>((event->number - 1) % root_),
                                     voxel_.y() * static_cast<double>(((event->number - 1) / root_) % root_),
                                     voxel_.z() * static_cast<double>(((event->number - 1) / root_ / root_) % root_)) +
            position = ROOT::Math::XYZPoint(voxel_.x() * static_cast<double>(voxel_it % root_),
                                            voxel_.y() * static_cast<double>((voxel_it / root_) % root_),
                                            voxel_.z() * static_cast<double>((voxel_it / root_ / root_) % root_)) +
                       ref;
        } else {
            position = ref;
            if(scan_x_) {
                position.SetX(voxel_.x() * static_cast<double>((event->number - 1) % root_) + ref.x());
                position.SetX(voxel_.x() * static_cast<double>(voxel_it % root_) + ref.x());
                if(scan_y_) {
                    position.SetY(voxel_.y() * static_cast<double>(((event->number - 1) / root_) % root_) + ref.y());
                    position.SetY(voxel_.y() * static_cast<double>((voxel_it / root_) % root_) + ref.y());
                } else if(scan_z_) {
                    position.SetZ(voxel_.z() * static_cast<double>(((event->number - 1) / root_) % root_) + ref.z());
                    position.SetZ(voxel_.z() * static_cast<double>((voxel_it / root_) % root_) + ref.z());
                }
            } else if(scan_y_) {
                position.SetY(voxel_.y() * static_cast<double>((event->number - 1) % root_) + ref.y());
                position.SetY(voxel_.y() * static_cast<double>(voxel_it % root_) + ref.y());
                if(scan_z_) {
                    position.SetZ(voxel_.z() * static_cast<double>(((event->number - 1) / root_) % root_) + ref.z());
                    position.SetZ(voxel_.z() * static_cast<double>((voxel_it / root_) % root_) + ref.z());
                }
            } else {
                position.SetZ(voxel_.z() * static_cast<double>((event->number - 1) % root_) + ref.z());
                position.SetZ(voxel_.z() * static_cast<double>(voxel_it % root_) + ref.z());
            }
        }
        LOG(DEBUG) << "Deposition position in local coordinates: " << Units::display(position, {"um", "mm"});
+1 −1
Original line number Diff line number Diff line
@@ -99,7 +99,7 @@ namespace allpix {
        double spot_size_{};
        ROOT::Math::XYZVector voxel_;
        double step_size_{};
        unsigned int root_{}, carriers_{};
        unsigned int root_{}, events_per_cell_{1}, carriers_{};
        ROOT::Math::XYZVector position_{};
        ROOT::Math::XYZVector mip_direction_{};
        std::vector<std::string> scan_coordinates_{};
+1 −0
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ All charge carriers are deposited at time zero, i.e. at the beginning of the eve
* `position`: Position in local coordinates of the sensor, where charge carriers should be deposited. Expects three values for local-x, local-y and local-z position in the sensor volume and defaults to `0um 0um 0um`, i.e. the center of first (lower left) pixel. When using source type `mip`, providing a 2D position is sufficient since it only uses the x and y coordinates. If used in scan mode, it allows you to shift the origin of each deposited charge by adding this value. If the scan is only performed in one or two dimensions, the remaining coordinate will constantly have the value given by `position`.
* `spot_size`: Width of the Gaussian distribution used to smear the position in the `spot` model. Only one value is taken and used for all three dimensions.
* `scan_coordinates`: Coordinates to scan over, a combination of x, y, z. Only used for the `scan` model. Defaults to `x y z`, i.e. all three spatial coordinates. The `position` parameter is used to determine the value of the coordinates that are not scanned over if a partial scan is requested, and the start offset of the scan for the other coordinates.
* `events_per_cell`: Number of events simulated in each voxel cell of the scan, Only used with `model = scan`, defaults to `1`. It should be noted that this setting does not change the total `number_of_events` to be simulated, this needs to be increased by the same proportion.
* `mip_direction`: Vector giving the direction of the line along which deposits are made when the `mip` source type is used. Defaults to `0 0 1`, i.e. along the z-axis. The `position` keyword gives a point that the line of depositions will cross through with this direction.

### Plotting parameters