Commit 5483b0db authored by Simon Spannagel's avatar Simon Spannagel
Browse files

Merge branch 'global-clock-sync' into 'master'

GH#50: Allow Syncing CSA clock

See merge request allpix-squared/allpix-squared!1122
parents c9614be3 ee8fe868
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -99,7 +99,8 @@ The global reference for time measurements is the beginning of the event, i.e. 
setup. The local time reference is the time of entry of the *first* primary particle of the event into the sensor. This means
that secondary particles created within the sensor inherit the local time reference from their parent particles in order to
have a uniform time reference in the sensor. It should be noted that Monte Carlo particles that start the local time frame on
different detectors do not necessarily have to belong to the same particle track.
different detectors do not necessarily have to belong to the same particle track. Few exceptions to these definitions exist and
are commented on in the corresponding module descriptions.

## Changing and accessing the geometry

+18 −6
Original line number Diff line number Diff line
@@ -49,6 +49,8 @@ CSADigitizerModule::CSADigitizerModule(Configuration& config, Messenger* messeng
    config_.setDefault<bool>("output_plots", config_.get<bool>("output_pulsegraphs"));
    config_.setDefault<int>("output_plots_scale", Units::get(30, "ke"));
    config_.setDefault<int>("output_plots_bins", 100);
    config_.setDefault<bool>("sync_event_time", false);
    config_.setDefault<double>("tdc_offset", Units::get(0.0, "ns"));

    if(model_ == DigitizerType::SIMPLE) {
        // defaults for the "simple" parametrisation
@@ -83,6 +85,10 @@ CSADigitizerModule::CSADigitizerModule(Configuration& config, Messenger* messeng
        clockToT_ = config_.get<double>("clock_bin_tot");
    }

    // Synchronize the clock binning to global simulation time
    sync_event_time_ = config_.get<bool>("sync_event_time");
    tdc_offset_ = config_.get<double>("tdc_offset");

    sigmaNoise_ = config_.get<double>("sigma_noise");
    threshold_ = config_.get<double>("threshold");
    ignore_polarity_ = config.get<bool>("ignore_polarity");
@@ -336,8 +342,13 @@ void CSADigitizerModule::run(Event* event) {
        // Store amplified pulse fir dispatch
        pulses.emplace_back(pixel, amplified_pulse, &pixel_charge);

        double time_offset = tdc_offset_;
        if(sync_event_time_) {
            time_offset += pixel_charge.getGlobalTime();
        }

        // Find threshold crossing - if any:
        auto arrival = get_toa(timestep, amplified_pulse);
        auto arrival = get_toa(timestep, amplified_pulse, time_offset);
        if(!std::get<0>(arrival)) {
            LOG(DEBUG) << "Amplified signal never crossed threshold, continuing.";
            continue;
@@ -385,12 +396,13 @@ void CSADigitizerModule::run(Event* event) {
    }
}

std::tuple<bool, unsigned int, double> CSADigitizerModule::get_toa(double timestep, const std::vector<double>& pulse) const {
std::tuple<bool, unsigned int, double>
CSADigitizerModule::get_toa(double timestep, const std::vector<double>& pulse, double time_offset) const {

    LOG(TRACE) << "Calculating time-of-arrival";
    bool threshold_crossed = false;
    unsigned int comparator_cycles = 0;
    double arrival_time = 0;
    auto comparator_cycles = static_cast<unsigned int>(std::floor(time_offset / clockToA_));
    double arrival_time = time_offset;

    // Lambda for threshold calculation:
    auto is_above_threshold = [this](double bin) {
@@ -402,8 +414,8 @@ std::tuple<bool, unsigned int, double> CSADigitizerModule::get_toa(double timest
    };

    // Find the point where the signal crosses the threshold, latch ToA
    while(arrival_time < integration_time_) {
        auto bin = pulse.at(static_cast<size_t>(std::floor(arrival_time / timestep)));
    while(arrival_time < integration_time_ + time_offset) {
        auto bin = pulse.at(static_cast<size_t>(std::floor((arrival_time - time_offset) / timestep)));
        if(is_above_threshold(bin)) {
            threshold_crossed = true;
            break;
+5 −3
Original line number Diff line number Diff line
@@ -75,7 +75,7 @@ namespace allpix {
    private:
        // Control of module output settings
        bool output_plots_{}, output_pulsegraphs_{};
        bool store_tot_{false}, store_toa_{false}, ignore_polarity_{};
        bool store_tot_{false}, store_toa_{false}, sync_event_time_{false}, ignore_polarity_{};
        Messenger* messenger_;
        DigitizerType model_;

@@ -89,7 +89,7 @@ namespace allpix {
        double graph_amplitude_unit_;

        // Parameters of the electronics: Noise, time-over-threshold logic
        double sigmaNoise_{}, clockToT_{}, clockToA_{}, threshold_{};
        double sigmaNoise_{}, clockToT_{}, clockToA_{}, threshold_{}, tdc_offset_{};

        // Helper variables for transfer function
        double integration_time_{};
@@ -104,10 +104,12 @@ namespace allpix {
         * @brief Calculate time of first threshold crossing
         * @param timestep Step size of the input pulse
         * @param pulse    Pulse after amplification and electronics noise
         * @param time_offset Time offset with respect to the beginning of the event
         * @return Tuple containing information about threshold crossing: Boolean (true if crossed), unsigned int (number
         *         of ToA clock cycles before crossing) and double (time of crossing)
         */
        std::tuple<bool, unsigned int, double> get_toa(double timestep, const std::vector<double>& pulse) const;
        std::tuple<bool, unsigned int, double>
        get_toa(double timestep, const std::vector<double>& pulse, double time_offset) const;

        /**
         * @brief Calculate time-over-threshold
+5 −1
Original line number Diff line number Diff line
@@ -43,7 +43,9 @@ Alternatively a custom impulse response function can be provided by using the `c

Noise can be applied to the individual bins of the output pulse, drawn from a normal distribution.

The values stored in `PixelHit` depend on the Time-of-Arrival (ToA) and Time-over-Threshold (ToT) settings. If a ToA clock is defined, then `local_time` will be stored in ToA clock cycles, else in time units. If a ToT clock is defined, then `signal` will be the amount of ToT cycles the pulse is above the threshold, else it will be the integral of the amplified pulse.
The values stored in `PixelHit` depend on the Time-of-Arrival (ToA) and Time-over-Threshold (ToT) settings.
If a ToA clock is defined, then `local_time` will be stored in ToA clock cycles, else in time units. Using the parameter `sync_event_time`, this local time will be, in contrast to the framework's definition of local time stamps, aligned with the global time reference, optionally shifted by the value of the parameter `tdc_offset`.
If a ToT clock is defined, then `signal` will be the amount of ToT cycles the pulse is above the threshold, else it will be the integral of the amplified pulse.

Since the input pulse may have different polarity, it is important to set the threshold accordingly to a positive or negative value, otherwise it may not trigger at all.
If this behavior is not desired, the `ignore_polarity` parameter can be set to compare only the absolute values of the input and the threshold value.
@@ -57,6 +59,8 @@ If this behavior is not desired, the `ignore_polarity` parameter can be set to c
* `ignore_polarity`: Select whether polarity of the threshold is ignored, i.e. the absolute values are compared, or if polarity is taken into account. Defaults to `false`.
* `clock_bin_toa`: Duration of a clock cycle for the time-of-arrival (ToA) clock. If set, the output timestamp is delivered in units of ToA clock cycles, otherwise in nanoseconds.
* `clock_bin_tot`: Duration of a clock cycle for the time-over-threshold (ToT) clock. If set, the output charge is delivered as time over threshold in units of ToT clock cycles, otherwise the pulse integral is stored instead.
* `sync_event_time`: Aligns the clock cycle to start counting with the global event time as opposed to starting at the beginning of the detected pulse time. Defaults to false.
* `tdc_offset`: Adds an offset to the global time for this digitizer. Defaults to 0ns.

### Parameters for the simplified model