CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
SiStripDigitizerAlgorithm.cc
Go to the documentation of this file.
1 // File: SiStripDigitizerAlgorithm.cc
2 // Description: Steering class for digitization.
3 
4 #include <vector>
5 #include <algorithm>
6 #include <iostream>
13 #include "CLHEP/Random/RandFlat.h"
14 
15 #define CBOLTZ (1.38E-23)
16 #define e_SI (1.6E-19)
17 
19  conf_(conf),rndEngine(eng){
20  theThreshold = conf_.getParameter<double>("NoiseSigmaThreshold");
21  theFedAlgo = conf_.getParameter<int>("FedAlgorithm");
22  peakMode = conf_.getParameter<bool>("APVpeakmode");
23  theElectronPerADC = conf_.getParameter<double>( peakMode ? "electronPerAdcPeak" : "electronPerAdcDec" );
24  noise = conf_.getParameter<bool>("Noise");
25  zeroSuppression = conf_.getParameter<bool>("ZeroSuppression");
26  theTOFCutForPeak = conf_.getParameter<double>("TOFCutForPeak");
27  theTOFCutForDeconvolution = conf_.getParameter<double>("TOFCutForDeconvolution");
28  cosmicShift = conf_.getUntrackedParameter<double>("CosmicDelayShift");
29  inefficiency = conf_.getParameter<double>("Inefficiency");
30  RealPedestals = conf_.getParameter<bool>("RealPedestals");
31  SingleStripNoise = conf_.getParameter<bool>("SingleStripNoise");
32  CommonModeNoise = conf_.getParameter<bool>("CommonModeNoise");
33  BaselineShift = conf_.getParameter<bool>("BaselineShift");
34  APVSaturationFromHIP = conf_.getParameter<bool>("APVSaturationFromHIP");
35  APVSaturationProb = conf_.getParameter<double>("APVSaturationProb");
36  cmnRMStib = conf_.getParameter<double>("cmnRMStib");
37  cmnRMStob = conf_.getParameter<double>("cmnRMStob");
38  cmnRMStid = conf_.getParameter<double>("cmnRMStid");
39  cmnRMStec = conf_.getParameter<double>("cmnRMStec");
40  pedOffset = (unsigned int)conf_.getParameter<double>("PedestalsOffset");
41  if (peakMode) {
43  LogDebug("StripDigiInfo")<<"APVs running in peak mode (poor time resolution)";
44  } else {
46  LogDebug("StripDigiInfo")<<"APVs running in deconvolution mode (good time resolution)";
47  };
48 
52  theSiDigitalConverter = new SiTrivialDigitalConverter(theElectronPerADC);
54  theFlatDistribution = new CLHEP::RandFlat(rndEngine, 0., 1.);
55 
56 
57 }
58 
60  delete theSiHitDigitizer;
61  delete theSiPileUpSignals;
62  delete theSiNoiseAdder;
63  delete theSiDigitalConverter;
64  delete theSiZeroSuppress;
65  delete theFlatDistribution;
66  //delete particle;
67  //delete pdt;
68 }
69 
70 // Run the algorithm for a given module
71 // ------------------------------------
72 
74  edm::DetSet<SiStripRawDigi>& outrawdigi,
75  const std::vector<std::pair<const PSimHit*, int > > &input,
76  StripGeomDetUnit *det,
77  GlobalVector bfield,float langle,
78  edm::ESHandle<SiStripGain> & gainHandle,
79  edm::ESHandle<SiStripThreshold> & thresholdHandle,
80  edm::ESHandle<SiStripNoises> & noiseHandle,
81  edm::ESHandle<SiStripPedestals> & pedestalHandle,
82  edm::ESHandle<SiStripBadStrip> & deadChannelHandle
83  ) {
85  unsigned int detID = det->geographicalId().rawId();
86  SiStripNoises::Range detNoiseRange = noiseHandle->getRange(detID);
87  SiStripApvGain::Range detGainRange = gainHandle->getRange(detID);
88  SiStripPedestals::Range detPedestalRange = pedestalHandle->getRange(detID);
89  SiStripBadStrip::Range detBadStripRange = deadChannelHandle->getRange(detID);
90  numStrips = (det->specificTopology()).nstrips();
91 
92  //stroing the bad stip of the the module. the module is not removed but just signal put to 0
93  std::vector<bool> badChannels;
94  badChannels.clear();
95  badChannels.insert(badChannels.begin(),numStrips,false);
97  for(SiStripBadStrip::ContainerIterator it=detBadStripRange.first;it!=detBadStripRange.second;++it){
98  fs=deadChannelHandle->decode(*it);
99  for(int strip = fs.firstStrip; strip <fs.firstStrip+fs.range; ++strip )badChannels[strip] = true;
100  }
101 
102 
103  // local amplitude of detector channels (from processed PSimHit)
104  locAmpl.clear();
105  detAmpl.clear();
106  locAmpl.insert(locAmpl.begin(),numStrips,0.);
107  // total amplitude of detector channels
108  detAmpl.insert(detAmpl.begin(),numStrips,0.);
109 
112 
113  // First: loop on the SimHits
114  std::vector<std::pair<const PSimHit*, int > >::const_iterator simHitIter = input.begin();
115  std::vector<std::pair<const PSimHit*, int > >::const_iterator simHitIterEnd = input.end();
116  if(theFlatDistribution->fire()>inefficiency) {
117  for (;simHitIter != simHitIterEnd; ++simHitIter) {
118  // check TOF
119  if ( std::fabs( ((*simHitIter).first)->tof() - cosmicShift - det->surface().toGlobal(((*simHitIter).first)->localPosition()).mag()/30.) < tofCut && ((*simHitIter).first)->energyLoss()>0) {
121  localLastChannel = 0;
122  // process the hit
123  theSiHitDigitizer->processHit(((*simHitIter).first),*det,bfield,langle, locAmpl, localFirstChannel, localLastChannel);
124 
125  //APV Killer to simulate HIP effect
126  //------------------------------------------------------
127 
129  int pdg_id = ((*simHitIter).first)->particleType();
130  particle = pdt->particle(pdg_id);
131  if(particle != NULL){
132  float charge = particle->charge();
133  bool isHadron = particle->isHadron();
134  if(charge!=0 && isHadron){
136  int FirstAPV = localFirstChannel/128;
137  int LastAPV = localLastChannel/128;
138  std::cout << "-------------------HIP--------------" << std::endl;
139  std::cout << "Killing APVs " << FirstAPV << " - " <<LastAPV << " " << detID <<std::endl;
140  for(int strip = FirstAPV*128; strip < LastAPV*128 +128; ++strip) badChannels[strip] = true; //doing like that I remove the signal information only after the
141  //stip that got the HIP but it remains the signal of the previous
142  //one. I'll make a further loop to remove all signal
143 
144  }
145  }
146  }
147  }
148 
149 
150  theSiPileUpSignals->add(locAmpl, localFirstChannel, localLastChannel, ((*simHitIter).first), (*simHitIter).second);
151 
152  // sum signal on strips
153  for (size_t iChannel=localFirstChannel; iChannel<localLastChannel; iChannel++) {
154  if(locAmpl[iChannel]>0.) {
155  //if(!badChannels[iChannel]) detAmpl[iChannel]+=locAmpl[iChannel];
156  //locAmpl[iChannel]=0;
157  detAmpl[iChannel]+=locAmpl[iChannel];
158  }
159  }
162  }
163  }
164  }
165 
166  //removing signal from the dead (and HIP effected) strips
167  for(int strip =0; strip < numStrips; ++strip) if(badChannels[strip]) detAmpl[strip] =0;
168 
171 
172  if(zeroSuppression){
173  if(noise){
174  int RefStrip = 0; //int(numStrips/2.);
175  while(RefStrip<numStrips&&badChannels[RefStrip]){ //if the refstrip is bad, I move up to when I don't find it
176  RefStrip++;
177  }
178  if(RefStrip<numStrips){
179  float noiseRMS = noiseHandle->getNoise(RefStrip,detNoiseRange);
180  float gainValue = gainHandle->getStripGain(RefStrip, detGainRange);
182  }
183  }
184  digis.clear();
185  theSiZeroSuppress->suppress(theSiDigitalConverter->convert(detAmpl, gainHandle, detID), digis, detID,noiseHandle,thresholdHandle);
186  push_link(digis, theLink, theCounterLink, detAmpl,detID);
187  outdigi.data = digis;
188  }
189 
190 
191  if(!zeroSuppression){
192  //if(noise){
193  // the constant pedestal offset is needed because
194  // negative adc counts are not allowed in case
195  // Pedestal and CMN subtraction is performed.
196  // The pedestal value read from the conditions
197  // is pedValue and after the pedestal subtraction
198  // the baseline is zero. The Common Mode Noise
199  // is not subtracted from the negative adc counts
200  // channels. Adding pedOffset the baseline is set
201  // to pedOffset after pedestal subtraction and CMN
202  // is subtracted to all the channels since none of
203  // them has negative adc value. The pedOffset is
204  // treated as a constant component in the CMN
205  // estimation and subtracted as CMN.
206 
207 
208  //calculating the charge deposited on each APV and subtracting the shift
209  //------------------------------------------------------
210  if(BaselineShift){
212  }
213 
214  //Adding the strip noise
215  //------------------------------------------------------
216  if(noise){
217  std::vector<float> noiseRMSv;
218  noiseRMSv.clear();
219  noiseRMSv.insert(noiseRMSv.begin(),numStrips,0.);
220 
221  if(SingleStripNoise){
222  for(int strip=0; strip< numStrips; ++strip){
223  if(!badChannels[strip]) noiseRMSv[strip] = (noiseHandle->getNoise(strip,detNoiseRange))* theElectronPerADC;
224  }
225 
226  } else {
227  int RefStrip = 0; //int(numStrips/2.);
228  while(RefStrip<numStrips&&badChannels[RefStrip]){ //if the refstrip is bad, I move up to when I don't find it
229  RefStrip++;
230  }
231  if(RefStrip<numStrips){
232  float noiseRMS = noiseHandle->getNoise(RefStrip,detNoiseRange) *theElectronPerADC;
233  for(int strip=0; strip< numStrips; ++strip){
234  if(!badChannels[strip]) noiseRMSv[strip] = noiseRMS;
235  }
236  }
237  }
238 
239  theSiNoiseAdder->addNoiseVR(detAmpl, noiseRMSv);
240  }
241 
242  //adding the CMN
243  //------------------------------------------------------
244  if(CommonModeNoise){
245  float cmnRMS = 0.;
246  DetId detId(detID);
247  uint32_t SubDet = detId.subdetId();
248  if(SubDet==3){
249  cmnRMS = cmnRMStib;
250  }else if(SubDet==4){
251  cmnRMS = cmnRMStid;
252  }else if(SubDet==5){
253  cmnRMS = cmnRMStob;
254  }else if(SubDet==6){
255  cmnRMS = cmnRMStec;
256  }
257  cmnRMS *= theElectronPerADC;
258  theSiNoiseAdder->addCMNoise(detAmpl, cmnRMS, badChannels);
259  }
260 
261 
262  //Adding the pedestals
263  //------------------------------------------------------
264 
265  std::vector<float> vPeds;
266  vPeds.clear();
267  vPeds.insert(vPeds.begin(),numStrips,0.);
268 
269  if(RealPedestals){
270  for(int strip=0; strip< numStrips; ++strip){
271  if(!badChannels[strip]) vPeds[strip] = (pedestalHandle->getPed(strip,detPedestalRange)+pedOffset)* theElectronPerADC;
272  }
273  } else {
274  for(int strip=0; strip< numStrips; ++strip){
275  if(!badChannels[strip]) vPeds[strip] = pedOffset* theElectronPerADC;
276  }
277  }
278 
280 
281 
282  //if(!RealPedestals&&!CommonModeNoise&&!noise&&!BaselineShift&&!APVSaturationFromHIP){
283  // edm::LogWarning("SiStripDigitizer")<<"You are running the digitizer without Noise generation and without applying Zero Suppression. ARE YOU SURE???";
284  //}else{
285 
286  rawdigis.clear();
287  rawdigis = theSiDigitalConverter->convertRaw(detAmpl, gainHandle, detID);
288  push_link_raw(rawdigis, theLink, theCounterLink, detAmpl,detID);
289  outrawdigi.data = rawdigis;
290 
291  //}
292  }
293 }
294 
296  const HitToDigisMapType& htd,
297  const HitCounterToDigisMapType& hctd,
298  const std::vector<double>& afterNoise,
299  unsigned int detID) {
300  link_coll.clear();
301  for ( DigitalVecType::const_iterator i=digis.begin(); i!=digis.end(); i++) {
302  // Instead of checking the validity of the links against the digis,
303  // let's loop over digis and push the corresponding link
304  HitToDigisMapType::const_iterator mi(htd.find(i->strip()));
305  if (mi == htd.end()) continue;
306  HitCounterToDigisMapType::const_iterator cmi(hctd.find(i->strip()));
307  std::map<const PSimHit *, Amplitude> totalAmplitudePerSimHit;
308  for (std::vector < std::pair < const PSimHit*, Amplitude > >::const_iterator simul =
309  (*mi).second.begin() ; simul != (*mi).second.end(); simul ++){
310  totalAmplitudePerSimHit[(*simul).first] += (*simul).second;
311  }
312 
313  //--- include the noise as well
314  double totalAmplitude1 = afterNoise[(*mi).first];
315 
316  //--- digisimlink
317  int sim_counter=0;
318  for (std::map<const PSimHit *, Amplitude>::const_iterator iter = totalAmplitudePerSimHit.begin();
319  iter != totalAmplitudePerSimHit.end(); iter++){
320  float threshold = 0.;
321  float fraction = (*iter).second/totalAmplitude1;
322  if ( fraction >= threshold) {
323  // Noise fluctuation could make fraction>1. Unphysical, set it by hand = 1.
324  if(fraction > 1.) fraction = 1.;
325  for (std::vector < std::pair < const PSimHit*, int > >::const_iterator
326  simcount = (*cmi).second.begin() ; simcount != (*cmi).second.end(); simcount ++){
327  if((*iter).first == (*simcount).first) sim_counter = (*simcount).second;
328  }
329  link_coll.push_back(StripDigiSimLink( (*mi).first, //channel
330  ((*iter).first)->trackId(), //simhit trackId
331  sim_counter, //simhit counter
332  ((*iter).first)->eventId(), //simhit eventId
333  fraction)); //fraction
334  }
335  }
336  }
337 }
338 
340  const HitToDigisMapType& htd,
341  const HitCounterToDigisMapType& hctd,
342  const std::vector<double>& afterNoise,
343  unsigned int detID) {
344  link_coll.clear();
345  int nstrip = -1;
346  for ( DigitalRawVecType::const_iterator i=digis.begin(); i!=digis.end(); i++) {
347  nstrip++;
348  // Instead of checking the validity of the links against the digis,
349  // let's loop over digis and push the corresponding link
350  HitToDigisMapType::const_iterator mi(htd.find(nstrip));
351  HitCounterToDigisMapType::const_iterator cmi(hctd.find(nstrip));
352  if (mi == htd.end()) continue;
353  std::map<const PSimHit *, Amplitude> totalAmplitudePerSimHit;
354  for (std::vector < std::pair < const PSimHit*, Amplitude > >::const_iterator simul =
355  (*mi).second.begin() ; simul != (*mi).second.end(); simul ++){
356  totalAmplitudePerSimHit[(*simul).first] += (*simul).second;
357  }
358 
359  //--- include the noise as well
360  double totalAmplitude1 = afterNoise[(*mi).first];
361 
362  //--- digisimlink
363  int sim_counter_raw=0;
364  for (std::map<const PSimHit *, Amplitude>::const_iterator iter = totalAmplitudePerSimHit.begin();
365  iter != totalAmplitudePerSimHit.end(); iter++){
366  float threshold = 0.;
367  float fraction = (*iter).second/totalAmplitude1;
368  if (fraction >= threshold) {
369  //Noise fluctuation could make fraction>1. Unphysical, set it by hand.
370  if(fraction >1.) fraction = 1.;
371  //add counter information
372  for (std::vector < std::pair < const PSimHit*, int > >::const_iterator
373  simcount = (*cmi).second.begin() ; simcount != (*cmi).second.end(); simcount ++){
374  if((*iter).first == (*simcount).first) sim_counter_raw = (*simcount).second;
375  }
376  link_coll.push_back(StripDigiSimLink( (*mi).first, //channel
377  ((*iter).first)->trackId(), //simhit trackId
378  sim_counter_raw, //simhit counter
379  ((*iter).first)->eventId(), //simhit eventId
380  fraction)); //fraction
381  }
382  }
383  }
384 }
#define LogDebug(id)
unsigned short range
GlobalPoint toGlobal(const Point2DBase< Scalar, LocalTag > lp) const
Definition: Surface.h:78
T getParameter(std::string const &) const
T getUntrackedParameter(std::string const &, T const &) const
int i
Definition: DBlmapReader.cc:9
DigitalVecType convert(const std::vector< double > &, edm::ESHandle< SiStripGain > &, unsigned int detid)
void addCMNoise(std::vector< double > &, float, std::vector< bool > &)
const HitCounterToDigisMapType & dumpCounterLink() const
SiDigitalConverter::DigitalRawVecType DigitalRawVecType
SiDigitalConverter::DigitalVecType DigitalVecType
CLHEP::HepRandomEngine & rndEngine
std::vector< unsigned int >::const_iterator ContainerIterator
#define NULL
Definition: scimark2.h:8
std::pair< ContainerIterator, ContainerIterator > Range
void addBaselineShift(std::vector< double > &, std::vector< bool > &)
virtual const StripTopology & specificTopology() const
Returns a reference to the strip proxy topology.
double charge(const std::vector< uint8_t > &Ampls)
void addNoiseVR(std::vector< double > &, std::vector< float > &)
void push_link_raw(const DigitalRawVecType &, const HitToDigisMapType &, const HitCounterToDigisMapType &, const std::vector< double > &, unsigned int)
uint32_t rawId() const
get the raw id
Definition: DetId.h:45
void push_link(const DigitalVecType &, const HitToDigisMapType &, const HitCounterToDigisMapType &, const std::vector< double > &, unsigned int)
SiStripDigitizerAlgorithm(const edm::ParameterSet &conf, CLHEP::HepRandomEngine &)
T mag() const
The vector magnitude. Equivalent to sqrt(vec.mag2())
SiPileUpSignals::HitToDigisMapType HitToDigisMapType
float threshold
Definition: crabWrap.py:319
SiPileUpSignals::HitCounterToDigisMapType HitCounterToDigisMapType
void suppress(const std::vector< SiStripDigi > &, std::vector< SiStripDigi > &, const uint32_t &, edm::ESHandle< SiStripNoises > &, edm::ESHandle< SiStripThreshold > &)
std::pair< ContainerIterator, ContainerIterator > Range
DetId geographicalId() const
The label of this GeomDet.
Definition: GeomDet.h:74
std::map< int, std::vector< std::pair< const PSimHit *, int > >, std::less< int > > HitCounterToDigisMapType
std::map< int, std::vector< std::pair< const PSimHit *, Amplitude > >, std::less< int > > HitToDigisMapType
void processHit(const PSimHit *, const StripGeomDetUnit &, GlobalVector, float, std::vector< double > &, size_t &, size_t &)
int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:39
tuple conf
Definition: dbtoconf.py:185
tuple input
Definition: collect_tpl.py:10
Definition: DetId.h:20
unsigned short firstStrip
SiTrivialDigitalConverter * theSiDigitalConverter
void addNoise(std::vector< double > &, size_t &, size_t &, int, float)
collection_type data
Definition: DetSet.h:65
std::pair< ContainerIterator, ContainerIterator > Range
SiStripFedZeroSuppression * theSiZeroSuppress
SiGaussianTailNoiseAdder * theSiNoiseAdder
tuple cout
Definition: gather_cfg.py:41
void run(edm::DetSet< SiStripDigi > &, edm::DetSet< SiStripRawDigi > &, const std::vector< std::pair< const PSimHit *, int > > &, StripGeomDetUnit *, GlobalVector, float, edm::ESHandle< SiStripGain > &, edm::ESHandle< SiStripThreshold > &, edm::ESHandle< SiStripNoises > &, edm::ESHandle< SiStripPedestals > &, edm::ESHandle< SiStripBadStrip > &)
virtual void add(const std::vector< double > &locAmpl, const size_t &firstChannelWithSignal, const size_t &lastChannelWithSignal, const PSimHit *hit, const int &counter)
std::pair< ContainerIterator, ContainerIterator > Range
Definition: SiStripNoises.h:41
DigitalRawVecType convertRaw(const std::vector< double > &, edm::ESHandle< SiStripGain > &, unsigned int detid)
std::vector< StripDigiSimLink > link_coll
void addPedestals(std::vector< double > &, std::vector< float > &)
const ParticleDataTable * pdt
virtual const BoundPlane & surface() const
The nominal surface of the GeomDet.
Definition: GeomDet.h:37
const HitToDigisMapType & dumpLink() const