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