LDMX Software
SimQIE.cxx
1#include "TrigScint/SimQIE.h"
2
3#include <cmath>
4
5#include "Framework/Exception/Exception.h"
6
7namespace trigscint {
8
10
11SimQIE::SimQIE(float PD, float SG, uint64_t seed = 0) {
12 isnoise_ = true;
13 if (seed == 0) {
14 EXCEPTION_RAISE("RandomSeedException",
15 "QIE Noise generator not seeded (seed=0)");
16 } else {
17 rand_ptr_ = std::make_unique<TRandom3>(seed);
18 trg_ = rand_ptr_.get();
19 }
20 mu_ = PD;
21 sg_ = SG;
22}
23
24// Function to convert charge to ADC count
25// Working: The method checks in which QIE subrange does the charge lie,
26// applies a corresponding gain to it and digitizes it.
27int SimQIE::q2Adc(float charge) {
28 float qq = gain_ * charge; // including QIE gain
29 if (isnoise_) qq += trg_->Gaus(mu_, sg_); // Adding gaussian random noise.
30
31 if (qq <= edges_[0]) return 0;
32 if (qq >= edges_[16]) return 255;
33
34 int a = 0;
35 int b = 16;
36
37 // Binary search to find the subrange
38 while (b - a != 1) {
39 if (qq > edges_[(a + b) / 2]) {
40 a = (a + b) / 2;
41 } else
42 b = (a + b) / 2;
43 }
44 return 64 * (a / 4) + nbins_[a % 4] + floor((qq - edges_[a]) / sense_[a]);
45}
46
47// Function to convert ADCs back to charge
48// The method checks to which QIE subrange does the ADC correspnd to
49// and returns the mean charge of the correspnding bin in the subrange
50float SimQIE::adc2Q(int ADC) {
51 if (ADC <= 0) return -16;
52 if (ADC >= 255) return 350000;
53
54 int rr = ADC / 64; // range
55 int v1 = ADC % 64; // temp. var
56 int ss = 0; // sub range
57
58 for (int i = 1; i < 4; i++) { // to get the subrange
59 if (v1 > nbins_[i]) ss++;
60 }
61 // cc is unused, should it be? FIXME
62 // int cc = 64 * rr + nbins_[ss];
63 float temp = edges_[4 * rr + ss] + (v1 - nbins_[ss]) * sense_[4 * rr + ss] +
64 sense_[4 * rr + ss] / 2;
65 return (temp / gain_);
66}
67
68// Function to return the quantization error for given input charge
69float SimQIE::qErr(float Q) {
70 if (Q <= edges_[0]) return 0;
71 if (Q >= edges_[16]) return 0;
72
73 int a = 0;
74 int b = 16;
75 while (b - a != 1) {
76 if (Q > edges_[(a + b) / 2])
77 a = (a + b) / 2;
78 else
79 b = (a + b) / 2;
80 }
81 return (sense_[a] / (sqrt(12) * Q));
82}
83
84// Function that returns an array of ADCs each corresponding to
85// one time sample
86std::vector<int> SimQIE::outAdc(QIEInputPulse* pp) {
87 std::vector<int> op;
88
89 for (int i = 0; i < maxts_; i++) {
90 float qq = pp->integrate(i * tau_, i * tau_ + tau_);
91 op.push_back(q2Adc(qq));
92 }
93 return op;
94}
95
96// Function that returns the digitized time corresponding to
97// current pulse crossing a specified current threshold
98int SimQIE::tdc(QIEInputPulse* pp, float T0 = 0) {
99 float thr2 = tdc_thr_ / gain_;
100 if (pp->eval(T0) > thr2) return 62; // when pulse starts high
101 float tt = T0;
102 while (tt < T0 + tau_) {
103 if (pp->eval(tt) >= thr2) return ((int)(2 * (tt - T0)));
104 tt += 0.1;
105 }
106 return 63; // when pulse remains low all along
107}
108
109// Function that returns an array of TDCs each corresponding to
110// one time sample
111std::vector<int> SimQIE::outTdc(QIEInputPulse* pp) {
112 std::vector<int> op;
113
114 for (int i = 0; i < maxts_; i++) {
115 op.push_back(tdc(pp, tau_ * i));
116 }
117 return op;
118}
119
120// Function that returns an array of Caoacitor IDs
121// each corresponding to one time sample
122std::vector<int> SimQIE::capId(QIEInputPulse* pp) {
123 std::vector<int> op;
124
125 op.push_back(trg_->Integer(4));
126 for (int i = 0; i < maxts_; i++) {
127 op.push_back((op[i] + 1) % 4);
128 }
129 return op;
130}
131
132bool SimQIE::pulseCut(QIEInputPulse* pulse, float cut) {
133 if (pulse->getNPulses() == 0) return false;
134
135 // float thr_in_pes = 1.0; instead make configurable
136
137 // Only keep the pulse if it produces 1 PE (or whatever the cutoff is set to)
138 // integrate over entire pulse so we catch also single-PE pulses
139 float integral = 0;
140 for (int i = 0; i < maxts_; i++) {
141 // if (pulse->integrate(i * tau_, i * tau_ + tau_) >= thr_in_pes) return
142 // true;
143 integral += pulse->integrate(i * tau_, i * tau_ + tau_);
144 }
145 if (integral >= cut) return true;
146
147 return false;
148}
149} // namespace trigscint
The base class to store the most important functions.
virtual float integrate(float T1, float T2)=0
Integrate the pulse from T1 to T2.
float eval(float T)
Evaluate the pulse train at time T.
int getNPulses()
Get the number of pulses in the collection.
float edges_[17]
Charge lower limit of all the 16 subranges.
Definition SimQIE.h:113
int nbins_[5]
Indices of first bin of each subrange.
Definition SimQIE.h:111
bool pulseCut(QIEInputPulse *pulse, float cut)
Method to check if the pulse is good to be stored.
Definition SimQIE.cxx:132
float tau_
time period of one time sample [in ns]
Definition SimQIE.h:123
std::vector< int > outAdc(QIEInputPulse *pp)
Complete set of ADCs for the pulse.
Definition SimQIE.cxx:86
float adc2Q(int ADC)
Converting ADC back to charge.
Definition SimQIE.cxx:50
float tdc_thr_
TDC threshold (default 3.74 microAmpere)
Definition SimQIE.h:128
int q2Adc(float Charge)
Digitizing input charge.
Definition SimQIE.cxx:27
float qErr(float Q)
Quantization error.
Definition SimQIE.cxx:69
float sg_
std. dev. of gaussian noise (Actual noise level)
Definition SimQIE.h:137
float sense_[16]
sensitivity of the subranges (Total charge/no. of bins)
Definition SimQIE.h:117
std::vector< int > outTdc(QIEInputPulse *pp)
Complete set of TDCs for the pulse.
Definition SimQIE.cxx:111
float mu_
mean of gaussian noise (Pedestal)
Definition SimQIE.h:135
bool isnoise_
Whether noise is added to the system.
Definition SimQIE.h:139
int maxts_
No. of time samples to analyze.
Definition SimQIE.h:125
int tdc(QIEInputPulse *pp, float T0)
TDC of the input pulse.
Definition SimQIE.cxx:98
SimQIE()
Defaut constructor.
Definition SimQIE.cxx:9
float gain_
QIE gain -> to convert from no. of e- to charge in fC.
Definition SimQIE.h:121
std::unique_ptr< TRandom3 > rand_ptr_
Random number generator (required for noise simulation)
Definition SimQIE.h:131
std::vector< int > capId(QIEInputPulse *pp)
Complete set of Capacitor IDs for the pulse.
Definition SimQIE.cxx:122