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