Commit 4b01577c authored by Paul Schütze's avatar Paul Schütze
Browse files

Merge branch 'gain_function' into 'master'

DefaultDigitizer possibility of change of the gain function.

See merge request allpix-squared/allpix-squared!574
parents c82bf132 49513ffd
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -109,6 +109,7 @@ The following authors, in alphabetical order, have developed or contributed to A
* Daniel Hynds, University of Oxford, @dhynds
* Maoqiang Jing, University of South China, Institute of High Energy Physics Beijing, @mjing
* Moritz Kiehn, Université de Genève, @msmk
* Rafaella Eleni Kotitsa, CERN, @rkotitsa
* Stephan Lachnit, Heidelberg University, @stephanlachnit
* Salman Maqbool, CERN Summer Student, @smaqbool
* Stefano Mersi, CERN, @mersi
+1 −1
Original line number Diff line number Diff line
@@ -34,4 +34,4 @@ propagate_holes = true
[DefaultDigitizer]
log_level = DEBUG

#PASS (Event 20) [R:DefaultDigitizer:mydetector] Passed threshold: 35294.4e > 630.388e
#PASS (Event 20) [R:DefaultDigitizer:mydetector] Passed threshold: 35294.4e > 564.342e
+1 −1
Original line number Diff line number Diff line
@@ -35,4 +35,4 @@ propagate_holes = true
[DefaultDigitizer]
log_level = DEBUG

#PASS (Event 20) [R:DefaultDigitizer:mydetector] Passed threshold: 35294.4e > 630.388e
#PASS (Event 20) [R:DefaultDigitizer:mydetector] Passed threshold: 35294.4e > 564.342e
+42 −12
Original line number Diff line number Diff line
@@ -32,10 +32,18 @@ DefaultDigitizerModule::DefaultDigitizerModule(Configuration& config,
    // Require PixelCharge message for single detector
    messenger_->bindSingle<PixelChargeMessage>(this, MsgFlags::REQUIRED);

    if(config_.has("gain") && config_.has("gain_function")) {
        throw InvalidCombinationError(
            config_, {"gain", "gain_function"}, "Gain and Gain Function cannot be simultaneously configured.");
    }

    // Set defaults for config variables
    config_.setDefault<int>("electronics_noise", Units::get(110, "e"));

    if(!config_.has("gain_function")) {
        config_.setDefault<double>("gain", 1.0);
    config_.setDefault<double>("gain_smearing", 0.0);
    }

    config_.setDefault<int>("threshold", Units::get(600, "e"));
    config_.setDefault<int>("threshold_smearing", Units::get(30, "e"));

@@ -68,8 +76,34 @@ DefaultDigitizerModule::DefaultDigitizerModule(Configuration& config,
    output_plots_ = config_.get<bool>("output_plots");

    electronics_noise_ = config_.get<unsigned int>("electronics_noise");
    gain_ = config_.get<double>("gain");
    gain_smearing_ = config_.get<double>("gain_smearing");

    if(config_.has("gain_function")) {
        gain_function_ = std::make_unique<TFormula>("gain_function", (config_.get<std::string>("gain_function")).c_str());

        if(!gain_function_->IsValid()) {
            throw InvalidValueError(
                config_, "gain_function", "The response function is not a valid ROOT::TFormula expression.");
        }

        auto parameters = config_.getArray<double>("gain_parameters");

        // check if number of parameters match up
        if(static_cast<size_t>(gain_function_->GetNpar()) != parameters.size()) {
            throw InvalidValueError(
                config_,
                "gain_parameters",
                "The number of function parameters does not line up with the number of parameters in the function.");
        }

        for(size_t n = 0; n < parameters.size(); ++n) {
            gain_function_->SetParameter(static_cast<int>(n), parameters[n]);
        }

        LOG(DEBUG) << "Gain response function successfully initialized with " << parameters.size() << " parameters";
    } else {
        gain_function_ = std::make_unique<TFormula>("gain_function", "[0]*x");
        gain_function_->SetParameter(0, config_.get<double>("gain"));
    }

    saturation_ = config_.get<bool>("saturation");
    saturation_mean_ = config_.get<unsigned int>("saturation_mean");
@@ -204,17 +238,13 @@ void DefaultDigitizerModule::run(Event* event) {
            h_pxq_noise->Fill(charge / 1e3);
        }

        // Smear the gain factor, Gaussian distribution around "gain" with width "gain_smearing"
        allpix::normal_distribution<double> gain_smearing(gain_, gain_smearing_);
        double gain = gain_smearing(event->getRandomEngine());
        if(output_plots_) {
            h_gain->Fill(gain);
        }

        // Apply the gain to the charge:
        charge *= gain;
        auto charge_pregain = charge;
        charge = gain_function_->Eval(charge);
        LOG(DEBUG) << "Charge after amplifier (gain): " << Units::display(charge, "e");
        if(output_plots_) {
            // Calculate gain from pre- and post-charge, offset to avoid zero-division:
            h_gain->Fill(charge / (charge_pregain + std::numeric_limits<double>::epsilon()));
            h_pxq_gain->Fill(charge / 1e3);
        }

+2 −1
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@

#include "tools/ROOT.h"

#include <TFormula.h>
#include <TH1D.h>
#include <TH2D.h>

@@ -78,7 +79,7 @@ namespace allpix {
        bool output_plots_{};

        unsigned int electronics_noise_{};
        double gain_{}, gain_smearing_{};
        std::unique_ptr<TFormula> gain_function_{};

        bool saturation_{};
        unsigned int saturation_mean_{}, saturation_width_{};
Loading