LDMX Software
TrigScintQIEDigiProducer.cxx
2
3#include <iostream>
4
5#include "Framework/Exception/Exception.h"
6#include "Framework/Logger.h"
8
9namespace trigscint {
10
11TrigScintQIEDigiProducer::TrigScintQIEDigiProducer(const std::string& name,
12 framework::Process& process)
13 : Producer(name, process) {}
14
15void TrigScintQIEDigiProducer::configure(
17 // Configure this instance of the producer
18 strips_per_array_ = parameters.get<int>("number_of_strips");
19 // number_of_arrays_ = parameters.get<int>("number_of_arrays");
20 mean_noise_ = parameters.get<double>("mean_noise");
21 mev_per_mip_ = parameters.get<double>("mev_per_mip");
22 pe_per_mip_ = parameters.get<double>("pe_per_mip");
23 input_collection_ = parameters.get<std::string>("input_collection");
24 input_pass_name_ = parameters.get<std::string>("input_pass_name");
25 output_collection_ = parameters.get<std::string>("output_collection");
26
27 // QIE specific parameters initialization
28 maxts_ = parameters.get<int>("maxts");
29 toff_overall_ = parameters.get<double>("toff_overall");
30 input_pulse_shape_ = parameters.get<std::string>("input_pulse_shape");
31 tdc_thr_ = parameters.get<double>("tdc_thr");
32 pedestal_ = parameters.get<double>("pedestal");
33 elec_noise_ = parameters.get<double>("elec_noise");
34 sipm_gain_ = parameters.get<double>("sipm_gain");
35 s_freq_ = parameters.get<double>("qie_sf");
36 zero_supp_cut_ = parameters.get<double>("zeroSupp_in_pe");
37
38 if (input_pulse_shape_ == "Expo") {
39 pulse_params_.clear();
40 pulse_params_.push_back(parameters.get<double>("expo_k"));
41 pulse_params_.push_back(parameters.get<double>("expo_tmax"));
42
43 ldmx_log(debug) << "expo_k =" << pulse_params_[0];
44 ldmx_log(debug) << "expo_tmax =" << pulse_params_[1];
45 }
46
47 // Debug mode: print parameter values.
48 ldmx_log(debug) << "maxts_ =" << maxts_;
49 ldmx_log(debug) << "toff_overall_ =" << toff_overall_;
50 ldmx_log(debug) << "input_pulse_shape_ =" << input_pulse_shape_;
51 ldmx_log(debug) << "tdc_thr =" << tdc_thr_;
52 ldmx_log(debug) << "pedestal =" << pedestal_;
53 ldmx_log(debug) << "elec_noise =" << elec_noise_;
54 ldmx_log(debug) << "sipm_gain =" << sipm_gain_;
55 ldmx_log(debug) << "qie_sf =" << s_freq_;
56 ldmx_log(debug) << "zeroSupp_in_pe =" << zero_supp_cut_;
57 ldmx_log(debug) << "pe_per_mip =" << pe_per_mip_;
58 ldmx_log(debug) << "mev_per_mip =" << mev_per_mip_;
59}
60
61void TrigScintQIEDigiProducer::produce(framework::Event& event) {
62 // Need to handle seeding on the first event
63 if (random_.get() == nullptr) {
64 const auto& rseed = getCondition<framework::RandomNumberSeedService>(
66 const auto& rseed2 = getCondition<framework::RandomNumberSeedService>(
68
69 random_ = std::make_unique<TRandom3>(rseed.getSeed(output_collection_));
70
71 // Initialize SimQIE instance with
72 // pedestal, electronic noise and the random seed
73 smq_ = new SimQIE(pedestal_, elec_noise_,
74 rseed2.getSeed(output_collection_ + "SimQIE"));
75
76 smq_->setGain(sipm_gain_);
77 smq_->setFreq(s_freq_);
78 smq_->setNTimeSamples(maxts_);
79 smq_->setTDCThreshold(tdc_thr_);
80 }
81
82 // To simulate multiple pulses coming at different times, SiPMS
83 // Initialize with strips_per_array_ zeros
84 std::vector<float> true_edep(strips_per_array_, 0.);
85
86 // Initialize with strips_per_array_ nullptrs
87 std::vector<Expo*> ex(strips_per_array_, nullptr);
88 for (int i = 0; i < strips_per_array_; i++) {
89 // Set the pulse shape with fixed parameters given by config. file
90 ex[i] = new Expo(pulse_params_[0], pulse_params_[1]);
91 true_edep[i] = 0;
92 }
93
94 // loop over sim hits and aggregate energy depositions for each detID
95 const auto sim_hits{event.getCollection<ldmx::SimCalorimeterHit>(
96 input_collection_, input_pass_name_)};
97
98 for (const auto& sim_hit : sim_hits) {
99 ldmx::TrigScintID id(sim_hit.getID());
100
101 ldmx_log(debug) << "Processing sim hit with bar ID: " << id.bar();
102
103 // Simulating the noise corresponding to uncertainity in
104 // detecting scintillating photons.
105 // Poissonian distribution with mean = mean PEs generated
106 double pulse_amp =
107 random_->Poisson(sim_hit.getEdep() / mev_per_mip_ * pe_per_mip_);
108
109 // Adding a pulse for every sim hit recorded.
110 // time offset = global offset+simhit time
111 ex[id.bar()]->addPulse(toff_overall_ + sim_hit.getTime(), pulse_amp);
112
113 // incrementing true energy deposited in appropriate bar.
114 true_edep[id.bar()] += sim_hit.getEdep();
115 }
116
117 // A container to hold the digitized trigger scintillator hits.
118 std::vector<trigscint::TrigScintQIEDigis> q_digis;
119
120 double total_noise = mean_noise_ * maxts_;
121
122 // time period[ns] = 1000/sampling freq.[MHz]
123 double sampling_time = 1000 / s_freq_;
124
125 // Loop over all the bars available.
126 for (int bar_id = 0; bar_id < strips_per_array_; bar_id++) {
127 // Dark current simulation
128 // e-hole pairs may be generated at random times in SiPM
129 // due to thermal fluctuations.
130 // Every e- thus generated, mimicks a Photo Electron.
131 // Hence we will creat 1PE pulses for each electron generated.
132 int n_noise_pulses = random_->Poisson(total_noise);
133 for (int i = 0; i < n_noise_pulses; i++) {
134 ex[bar_id]->addPulse(random_->Uniform(0, maxts_ * sampling_time), 1);
135 }
136
137 // Storing the "good" digis
138 if (smq_->pulseCut(ex[bar_id], zero_supp_cut_)) {
140
141 qie_info.setChanID(bar_id);
142 qie_info.setADC(smq_->outAdc(ex[bar_id]));
143 qie_info.setTDC(smq_->outTdc(ex[bar_id]));
144 qie_info.setCID(smq_->capId(ex[bar_id]));
145
146 q_digis.push_back(qie_info);
147 }
148 }
149 event.add(output_collection_, q_digis);
150}
151
152} // namespace trigscint
153
#define DECLARE_PRODUCER(CLASS)
Macro which allows the framework to construct a producer given its name during configuration.
Conditions object for random number seeds.
Class that simulates QIE chip of the trigger scintillator.
Implements an event buffer system for storing event data.
Definition Event.h:42
Class which represents the process under execution.
Definition Process.h:36
static const std::string CONDITIONS_OBJECT_NAME
Conditions object name.
Class encapsulating parameters for configuring a processor.
Definition Parameters.h:29
const T & get(const std::string &name) const
Retrieve the parameter of the given name.
Definition Parameters.h:78
Stores simulated calorimeter hit information.
Class that defines the detector ID of the trigger scintillator.
Definition TrigScintID.h:14
piece-wise exponential pulse, modelled as an output of a capacitor
class for simulating QIE chip output
Definition SimQIE.h:17
Class that simulates QIE chip of the trigger scintillator.
class for storing QIE output
void setCID(const std::vector< int > cid)
Store cids of all time samples.
void setTDC(const std::vector< int > tdc)
Store tdcs of all time samples.
void setChanID(const int chanid)
Store the channel ID.
void setADC(const std::vector< int > adc)
Store adcs of all time samples.