CMS 3D CMS Logo

BTLElectronicsSim.cc
Go to the documentation of this file.
2 
4 
5 #include "CLHEP/Random/RandPoissonQ.h"
6 #include "CLHEP/Random/RandGaussQ.h"
7 
8 
9 using namespace mtd;
10 
12  debug_( pset.getUntrackedParameter<bool>("debug",false) ),
13  bxTime_( pset.getParameter<double>("bxTime") ),
14  testBeamMIPTimeRes_( pset.getParameter<double>("TestBeamMIPTimeRes") ),
15  ScintillatorRiseTime_( pset.getParameter<double>("ScintillatorRiseTime") ),
16  ScintillatorDecayTime_( pset.getParameter<double>("ScintillatorDecayTime") ),
17  ChannelTimeOffset_( pset.getParameter<double>("ChannelTimeOffset") ),
18  smearChannelTimeOffset_( pset.getParameter<double>("smearChannelTimeOffset") ),
19  EnergyThreshold_( pset.getParameter<double>("EnergyThreshold") ),
20  TimeThreshold1_( pset.getParameter<double>("TimeThreshold1") ),
21  TimeThreshold2_( pset.getParameter<double>("TimeThreshold2") ),
22  ReferencePulseNpe_( pset.getParameter<double>("ReferencePulseNpe") ),
23  SinglePhotonTimeResolution_( pset.getParameter<double>("SinglePhotonTimeResolution") ),
24  DarkCountRate_( pset.getParameter<double>("DarkCountRate") ),
25  SigmaElectronicNoise_( pset.getParameter<double>("SigmaElectronicNoise") ),
26  SigmaClock_( pset.getParameter<double>("SigmaClock")),
27  Npe_to_pC_( pset.getParameter<double>("Npe_to_pC") ),
28  Npe_to_V_( pset.getParameter<double>("Npe_to_V") ),
29  adcNbits_( pset.getParameter<uint32_t>("adcNbits") ),
30  tdcNbits_( pset.getParameter<uint32_t>("tdcNbits") ),
31  adcSaturation_MIP_( pset.getParameter<double>("adcSaturation_MIP") ),
32  adcBitSaturation_( std::pow(2,adcNbits_)-1 ),
33  adcLSB_MIP_( adcSaturation_MIP_/adcBitSaturation_ ),
34  adcThreshold_MIP_( pset.getParameter<double>("adcThreshold_MIP") ),
35  toaLSB_ns_( pset.getParameter<double>("toaLSB_ns") ),
36  tdcBitSaturation_( std::pow(2,tdcNbits_)-1 ),
37  CorrCoeff_( pset.getParameter<double>("CorrelationCoefficient") ),
38  cosPhi_( 0.5*(sqrt(1.+CorrCoeff_)+sqrt(1.-CorrCoeff_)) ),
39  sinPhi_( 0.5*CorrCoeff_/cosPhi_ ),
40  ScintillatorDecayTime2_(ScintillatorDecayTime_*ScintillatorDecayTime_),
41  SPTR2_(SinglePhotonTimeResolution_*SinglePhotonTimeResolution_),
42  DCRxRiseTime_(DarkCountRate_*ScintillatorRiseTime_),
43  SigmaElectronicNoise2_(SigmaElectronicNoise_*SigmaElectronicNoise_),
44  SigmaClock2_(SigmaClock_*SigmaClock_) {
45 }
46 
47 
50  CLHEP::HepRandomEngine *hre) const {
51 
52  MTDSimHitData chargeColl, toa1, toa2;
53 
54  for(MTDSimHitDataAccumulator::const_iterator it=input.begin();
55  it!=input.end();
56  it++) {
57 
58  chargeColl.fill(0.f);
59  toa1.fill(0.f);
60  toa2.fill(0.f);
61  for(size_t i=0; i<it->second.hit_info[0].size(); i++) {
62 
63  // --- Fluctuate the total number of photo-electrons
64  float Npe = CLHEP::RandPoissonQ::shoot(hre, (it->second).hit_info[0][i]);
65  if ( Npe < EnergyThreshold_ ) continue;
66 
67 
68  // --- Get the time of arrival and add a channel time offset
69  float finalToA1 = (it->second).hit_info[1][i] + ChannelTimeOffset_;
70 
71  if ( smearChannelTimeOffset_ > 0. ){
72  float timeSmearing = CLHEP::RandGaussQ::shoot(hre, 0., smearChannelTimeOffset_);
73  finalToA1 += timeSmearing;
74  }
75 
76 
77  // --- Calculate and add the time walk: the time of arrival is read in correspondence
78  // with two thresholds on the signal pulse
79  std::array<float, 3> times = btlPulseShape_.timeAtThr(Npe/ReferencePulseNpe_,
81  TimeThreshold2_*Npe_to_V_);
82 
83 
84  // --- If the pulse amplitude is smaller than TimeThreshold2, the trigger does not fire
85  if (times[1] == 0.) continue;
86 
87  float finalToA2 = finalToA1 + times[1];
88  finalToA1 += times[0];
89 
90 
91  // --- Uncertainty due to the fluctuations of the n-th photon arrival time:
92  if ( testBeamMIPTimeRes_ > 0. ) {
93  // In this case the time resolution is parametrized from the testbeam.
94  // The same parameterization is used for both thresholds.
95  float sigma = testBeamMIPTimeRes_/sqrt(Npe);
96  float smearing_stat_thr1 = CLHEP::RandGaussQ::shoot(hre, 0., sigma);
97  float smearing_stat_thr2 = CLHEP::RandGaussQ::shoot(hre, 0., sigma);
98 
99  finalToA1 += smearing_stat_thr1;
100  finalToA2 += smearing_stat_thr2;
101 
102  }
103  else {
104  // In this case the time resolution is taken from the literature.
105  // The fluctuations due to the first TimeThreshold1_ p.e. are common to both times
106  float smearing_stat_thr1 = CLHEP::RandGaussQ::shoot(hre, 0.,
108  float smearing_stat_thr2 = CLHEP::RandGaussQ::shoot(hre, 0.,
110  finalToA1 += smearing_stat_thr1;
111  finalToA2 += smearing_stat_thr1 + smearing_stat_thr2;
112  }
113 
114 
115  // --- Add in quadrature the uncertainties due to the SiPM timing resolution, the SiPM DCR,
116  // the electronic noise and the clock distribution:
117  float slew2 = ScintillatorDecayTime2_/Npe/Npe;
118 
119  float sigma2_tot_thr1 = SPTR2_/TimeThreshold1_ + (DCRxRiseTime_ + SigmaElectronicNoise2_)*slew2 + SigmaClock2_;
120  float sigma2_tot_thr2 = SPTR2_/TimeThreshold2_ + (DCRxRiseTime_ + SigmaElectronicNoise2_)*slew2 + SigmaClock2_;
121 
122 
123  // --- Smear the arrival times using the correlated uncertainties:
124  float smearing_thr1_uncorr = CLHEP::RandGaussQ::shoot(hre, 0., sqrt(sigma2_tot_thr1));
125  float smearing_thr2_uncorr = CLHEP::RandGaussQ::shoot(hre, 0., sqrt(sigma2_tot_thr2));
126 
127  finalToA1 += cosPhi_*smearing_thr1_uncorr + sinPhi_*smearing_thr2_uncorr;
128  finalToA2 += sinPhi_*smearing_thr1_uncorr + cosPhi_*smearing_thr2_uncorr;
129 
130  chargeColl[i] = Npe*Npe_to_pC_; // the p.e. number is here converted to pC
131 
132  toa1[i] = finalToA1;
133  toa2[i] = finalToA2;
134 
135  }
136 
137  //run the shaper to create a new data frame
138  BTLDataFrame rawDataFrame( it->first.detid_ );
139  runTrivialShaper(rawDataFrame,chargeColl,toa1,toa2,it->first.row_, it->first.column_);
140  updateOutput(output,rawDataFrame);
141 
142  }
143 
144 }
145 
146 
148  const mtd::MTDSimHitData& chargeColl,
149  const mtd::MTDSimHitData& toa1,
150  const mtd::MTDSimHitData& toa2,
151  const uint8_t row, const uint8_t col) const {
152  bool debug = debug_;
153 #ifdef EDM_ML_DEBUG
154  for(int it=0; it<(int)(chargeColl.size()); it++) debug |= (chargeColl[it]>adcThreshold_fC_);
155 #endif
156 
157  if(debug) edm::LogVerbatim("BTLElectronicsSim") << "[runTrivialShaper]" << std::endl;
158 
159  //set new ADCs
160  for(int it=0; it<(int)(chargeColl.size()); it++) {
161 
162  BTLSample newSample;
163  newSample.set(false,false,0,0,0,row,col);
164 
165  //brute force saturation, maybe could to better with an exponential like saturation
166  const uint32_t adc = std::min( (uint32_t) std::floor(chargeColl[it]/adcLSB_MIP_), adcBitSaturation_ );
167  const uint32_t tdc_time1 = std::min( (uint32_t) std::floor(toa1[it]/toaLSB_ns_), tdcBitSaturation_);
168  const uint32_t tdc_time2 = std::min( (uint32_t) std::floor(toa2[it]/toaLSB_ns_), tdcBitSaturation_);
169 
170  newSample.set(chargeColl[it] > adcThreshold_MIP_,tdc_time1 == tdcBitSaturation_,
171  tdc_time2,tdc_time1,adc,row,col);
172  dataFrame.setSample(it,newSample);
173 
174  if(debug) edm::LogVerbatim("BTLElectronicsSim") << adc << " ("
175  << chargeColl[it] << "/"
176  << adcLSB_MIP_ << ") ";
177  }
178 
179  if(debug) {
180  std::ostringstream msg;
181  dataFrame.print(msg);
182  edm::LogVerbatim("BTLElectronicsSim") << msg.str() << std::endl;
183  }
184 }
185 
187  const BTLDataFrame& rawDataFrame) const {
188 
189  BTLDataFrame dataFrame( rawDataFrame.id() );
190  dataFrame.resize(dfSIZE);
191  bool putInEvent(false);
192  for(int it=0;it<dfSIZE; ++it) {
193  dataFrame.setSample(it, rawDataFrame[it]);
194  if(it==0) putInEvent = rawDataFrame[it].threshold();
195  }
196 
197  if(putInEvent) {
198  coll.push_back(dataFrame);
199  }
200 }
201 
202 float BTLElectronicsSim::sigma2_pe(const float& Q, const float& R) const {
203 
204  float OneOverR = 1./R;
205  float OneOverR2 = OneOverR*OneOverR;
206 
207  // --- This is Eq. (17) from Nucl. Instr. Meth. A 564 (2006) 185
208  float sigma2 = Q * OneOverR2 * ( 1. + 2.*(Q+1.)*OneOverR +
209  (Q+1.)*(6.*Q+11)*OneOverR2 +
210  (Q+1.)*(Q+2.)*(2.*Q+5.)*OneOverR2*OneOverR );
211 
212  return sigma2;
213 
214 }
215 
216 
217 
const float Npe_to_pC_
const float DCRxRiseTime_
const float adcThreshold_MIP_
float sigma2_pe(const float &Q, const float &R) const
void push_back(T const &t)
std::unordered_map< MTDCellId, MTDCellInfo > MTDSimHitDataAccumulator
std::array< MTDSimData_t, nSamples > MTDSimHitData
const float TimeThreshold2_
wrapper for a data word
Definition: BTLSample.h:13
const float adcLSB_MIP_
static std::string const input
Definition: EdmProvDump.cc:48
void updateOutput(BTLDigiCollection &coll, const BTLDataFrame &rawDataFrame) const
const float ScintillatorDecayTime2_
const float toaLSB_ns_
const BTLPulseShape btlPulseShape_
void resize(size_t s)
allow to set size
Definition: FTLDataFrameT.h:52
T sqrt(T t)
Definition: SSEVec.h:18
void run(const mtd::MTDSimHitDataAccumulator &input, BTLDigiCollection &output, CLHEP::HepRandomEngine *hre) const
const uint32_t adcBitSaturation_
double f[11][100]
void setSample(int i, const S &sample)
Definition: FTLDataFrameT.h:59
T min(T a, T b)
Definition: MathUtil.h:58
constexpr int adc(sample_type sample)
get the ADC sample (12 bits)
BTLElectronicsSim(const edm::ParameterSet &pset)
const float SigmaElectronicNoise2_
#define debug
Definition: HDRShower.cc:19
JetCorrectorParametersCollection coll
Definition: classes.h:10
const float EnergyThreshold_
tuple msg
Definition: mps_check.py:279
const uint32_t tdcBitSaturation_
std::array< float, 3 > timeAtThr(const float scale, const float threshold1, const float threshold2) const
Definition: MTDShapeBase.cc:15
const float ScintillatorDecayTime_
const float TimeThreshold1_
void set(bool thr, bool mode, uint16_t toa2, uint16_t toa, uint16_t data, uint8_t row, uint8_t col)
Definition: BTLSample.h:38
const float ChannelTimeOffset_
col
Definition: cuy.py:1010
Readout digi for HGC.
Definition: FTLDataFrameT.h:14
const float testBeamMIPTimeRes_
void runTrivialShaper(BTLDataFrame &dataFrame, const mtd::MTDSimHitData &chargeColl, const mtd::MTDSimHitData &toa1, const mtd::MTDSimHitData &toa2, const uint8_t row, const uint8_t col) const
const float smearChannelTimeOffset_
void print(std::ostream &out=std::cout)
Definition: FTLDataFrameT.h:60
const float SigmaClock2_
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:40
const float ReferencePulseNpe_
const D & id() const
det id
Definition: FTLDataFrameT.h:32