CMS 3D CMS Logo

DigiSimLinkAlgorithm.cc
Go to the documentation of this file.
1 // File: DigiSimLinkAlgorithm.cc
2 // Description: Steering class for digitization.
3 
4 #include <vector>
5 #include <algorithm>
6 #include <iostream>
9 #include "DigiSimLinkAlgorithm.h"
14 
15 #include "CLHEP/Random/RandFlat.h"
16 
17 #define CBOLTZ (1.38E-23)
18 #define e_SI (1.6E-19)
19 
21  theThreshold = conf_.getParameter<double>("NoiseSigmaThreshold");
22  theFedAlgo = conf_.getParameter<int>("FedAlgorithm");
23  peakMode = conf_.getParameter<bool>("APVpeakmode");
24  theElectronPerADC = conf_.getParameter<double>(peakMode ? "electronPerAdcPeak" : "electronPerAdcDec");
25  noise = conf_.getParameter<bool>("Noise");
26  zeroSuppression = conf_.getParameter<bool>("ZeroSuppression");
27  theTOFCutForPeak = conf_.getParameter<double>("TOFCutForPeak");
28  theTOFCutForDeconvolution = conf_.getParameter<double>("TOFCutForDeconvolution");
29  cosmicShift = conf_.getUntrackedParameter<double>("CosmicDelayShift");
30  inefficiency = conf_.getParameter<double>("Inefficiency");
31  RealPedestals = conf_.getParameter<bool>("RealPedestals");
32  SingleStripNoise = conf_.getParameter<bool>("SingleStripNoise");
33  CommonModeNoise = conf_.getParameter<bool>("CommonModeNoise");
34  BaselineShift = conf_.getParameter<bool>("BaselineShift");
35  APVSaturationFromHIP = conf_.getParameter<bool>("APVSaturationFromHIP");
36  APVSaturationProb = conf_.getParameter<double>("APVSaturationProb");
37  cmnRMStib = conf_.getParameter<double>("cmnRMStib");
38  cmnRMStob = conf_.getParameter<double>("cmnRMStob");
39  cmnRMStid = conf_.getParameter<double>("cmnRMStid");
40  cmnRMStec = conf_.getParameter<double>("cmnRMStec");
41  pedOffset = (unsigned int)conf_.getParameter<double>("PedestalsOffset");
42  PreMixing_ = conf_.getParameter<bool>("PreMixingMode");
43  if (peakMode) {
45  LogDebug("StripDigiInfo") << "APVs running in peak mode (poor time resolution)";
46  } else {
48  LogDebug("StripDigiInfo") << "APVs running in deconvolution mode (good time resolution)";
49  };
50 
56 }
57 
59  delete theSiHitDigitizer;
61  delete theSiNoiseAdder;
62  delete theSiDigitalConverter;
63  delete theSiZeroSuppress;
64  //delete particle;
65  //delete pdt;
66 }
67 
68 // Run the algorithm for a given module
69 // ------------------------------------
70 
72  edm::DetSet<SiStripRawDigi>& outrawdigi,
73  const std::vector<std::pair<const PSimHit*, int> >& input,
74  StripGeomDetUnit const* det,
75  GlobalVector bfield,
76  float langle,
77  edm::ESHandle<SiStripGain>& gainHandle,
78  edm::ESHandle<SiStripThreshold>& thresholdHandle,
79  edm::ESHandle<SiStripNoises>& noiseHandle,
80  edm::ESHandle<SiStripPedestals>& pedestalHandle,
81  edm::ESHandle<SiStripBadStrip>& deadChannelHandle,
82  const TrackerTopology* tTopo,
83  CLHEP::HepRandomEngine* engine) {
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)
100  badChannels[strip] = true;
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 (CLHEP::RandFlat::shoot(engine) > inefficiency) {
117  for (; simHitIter != simHitIterEnd; ++simHitIter) {
118  locAmpl.clear();
119  locAmpl.insert(locAmpl.begin(), numStrips, 0.);
120  // check TOF
121  if (std::fabs(((*simHitIter).first)->tof() - cosmicShift -
122  det->surface().toGlobal(((*simHitIter).first)->localPosition()).mag() / 30.) < tofCut &&
123  ((*simHitIter).first)->energyLoss() > 0) {
125  localLastChannel = 0;
126  // process the hit
128  ((*simHitIter).first), *det, bfield, langle, locAmpl, localFirstChannel, localLastChannel, tTopo, engine);
129 
130  //APV Killer to simulate HIP effect
131  //------------------------------------------------------
132 
134  int pdg_id = ((*simHitIter).first)->particleType();
135  particle = pdt->particle(pdg_id);
136  if (particle != nullptr) {
137  float charge = particle->charge();
138  bool isHadron = particle->isHadron();
139  if (charge != 0 && isHadron) {
140  if (CLHEP::RandFlat::shoot(engine) < APVSaturationProb) {
141  int FirstAPV = localFirstChannel / 128;
142  int LastAPV = localLastChannel / 128;
143  std::cout << "-------------------HIP--------------" << std::endl;
144  std::cout << "Killing APVs " << FirstAPV << " - " << LastAPV << " " << detID << std::endl;
145  for (int strip = FirstAPV * 128; strip < LastAPV * 128 + 128; ++strip)
146  badChannels[strip] = true; //doing like that I remove the signal information only after the
147  //stip that got the HIP but it remains the signal of the previous
148  //one. I'll make a further loop to remove all signal
149  }
150  }
151  }
152  }
153 
155  locAmpl, localFirstChannel, localLastChannel, ((*simHitIter).first), (*simHitIter).second);
156 
157  // sum signal on strips
158  for (size_t iChannel = localFirstChannel; iChannel < localLastChannel; iChannel++) {
159  if (locAmpl[iChannel] > 0.) {
160  //if(!badChannels[iChannel]) detAmpl[iChannel]+=locAmpl[iChannel];
161  //locAmpl[iChannel]=0;
162  detAmpl[iChannel] += locAmpl[iChannel];
163  }
164  }
169  }
170  }
171  }
172 
173  //removing signal from the dead (and HIP effected) strips
174  for (int strip = 0; strip < numStrips; ++strip)
175  if (badChannels[strip])
176  detAmpl[strip] = 0;
177 
181 
182  if (zeroSuppression) {
183  if (noise) {
184  int RefStrip = int(numStrips / 2.);
185  while (RefStrip < numStrips &&
186  badChannels[RefStrip]) { //if the refstrip is bad, I move up to when I don't find it
187  RefStrip++;
188  }
189  if (RefStrip < numStrips) {
190  float noiseRMS = noiseHandle->getNoise(RefStrip, detNoiseRange);
191  float gainValue = gainHandle->getStripGain(RefStrip, detGainRange);
195  numStrips,
196  noiseRMS * theElectronPerADC / gainValue,
197  engine);
198  }
199  }
200  digis.clear();
202  digis,
203  detID,
204  *noiseHandle,
205  *thresholdHandle);
206  push_link(digis, theLink, theCounterLink, detAmpl, detID);
207  outdigi.data = digis;
208  }
209 
210  if (!zeroSuppression) {
211  //if(noise){
212  // the constant pedestal offset is needed because
213  // negative adc counts are not allowed in case
214  // Pedestal and CMN subtraction is performed.
215  // The pedestal value read from the conditions
216  // is pedValue and after the pedestal subtraction
217  // the baseline is zero. The Common Mode Noise
218  // is not subtracted from the negative adc counts
219  // channels. Adding pedOffset the baseline is set
220  // to pedOffset after pedestal subtraction and CMN
221  // is subtracted to all the channels since none of
222  // them has negative adc value. The pedOffset is
223  // treated as a constant component in the CMN
224  // estimation and subtracted as CMN.
225 
226  //calculating the charge deposited on each APV and subtracting the shift
227  //------------------------------------------------------
228  if (BaselineShift) {
230  }
231 
232  //Adding the strip noise
233  //------------------------------------------------------
234  if (noise) {
235  std::vector<float> noiseRMSv;
236  noiseRMSv.clear();
237  noiseRMSv.insert(noiseRMSv.begin(), numStrips, 0.);
238 
239  if (SingleStripNoise) {
240  for (int strip = 0; strip < numStrips; ++strip) {
241  if (!badChannels[strip])
242  noiseRMSv[strip] = (noiseHandle->getNoise(strip, detNoiseRange)) * theElectronPerADC;
243  }
244 
245  } else {
246  int RefStrip = 0; //int(numStrips/2.);
247  while (RefStrip < numStrips &&
248  badChannels[RefStrip]) { //if the refstrip is bad, I move up to when I don't find it
249  RefStrip++;
250  }
251  if (RefStrip < numStrips) {
252  float noiseRMS = noiseHandle->getNoise(RefStrip, detNoiseRange) * theElectronPerADC;
253  for (int strip = 0; strip < numStrips; ++strip) {
254  if (!badChannels[strip])
255  noiseRMSv[strip] = noiseRMS;
256  }
257  }
258  }
259 
260  theSiNoiseAdder->addNoiseVR(detAmpl, noiseRMSv, engine);
261  }
262 
263  //adding the CMN
264  //------------------------------------------------------
265  if (CommonModeNoise) {
266  float cmnRMS = 0.;
267  DetId detId(detID);
268  uint32_t SubDet = detId.subdetId();
269  if (SubDet == 3) {
270  cmnRMS = cmnRMStib;
271  } else if (SubDet == 4) {
272  cmnRMS = cmnRMStid;
273  } else if (SubDet == 5) {
274  cmnRMS = cmnRMStob;
275  } else if (SubDet == 6) {
276  cmnRMS = cmnRMStec;
277  }
278  cmnRMS *= theElectronPerADC;
279  theSiNoiseAdder->addCMNoise(detAmpl, cmnRMS, badChannels, engine);
280  }
281 
282  //Adding the pedestals
283  //------------------------------------------------------
284 
285  std::vector<float> vPeds;
286  vPeds.clear();
287  vPeds.insert(vPeds.begin(), numStrips, 0.);
288 
289  if (RealPedestals) {
290  for (int strip = 0; strip < numStrips; ++strip) {
291  if (!badChannels[strip])
292  vPeds[strip] = (pedestalHandle->getPed(strip, detPedestalRange) + pedOffset) * theElectronPerADC;
293  }
294  } else {
295  for (int strip = 0; strip < numStrips; ++strip) {
296  if (!badChannels[strip])
297  vPeds[strip] = pedOffset * theElectronPerADC;
298  }
299  }
300 
302 
303  //if(!RealPedestals&&!CommonModeNoise&&!noise&&!BaselineShift&&!APVSaturationFromHIP){
304  // edm::LogWarning("DigiSimLinkAlgorithm")<<"You are running the digitizer without Noise generation and without applying Zero Suppression. ARE YOU SURE???";
305  //}else{
306 
307  rawdigis.clear();
308  rawdigis = theSiDigitalConverter->convertRaw(detAmpl, gainHandle.product(), detID);
309  push_link_raw(rawdigis, theLink, theCounterLink, detAmpl, detID);
310  outrawdigi.data = rawdigis;
311 
312  //}
313  }
314 }
315 
317  const HitToDigisMapType& htd,
318  const HitCounterToDigisMapType& hctd,
319  const std::vector<float>& afterNoise,
320  unsigned int detID) {
321  link_coll.clear();
322  for (DigitalVecType::const_iterator i = digis.begin(); i != digis.end(); i++) {
323  // Instead of checking the validity of the links against the digis,
324  // let's loop over digis and push the corresponding link
325  HitToDigisMapType::const_iterator mi(htd.find(i->strip()));
326  if (mi == htd.end())
327  continue;
328  HitCounterToDigisMapType::const_iterator cmi(hctd.find(i->strip()));
329  std::map<const PSimHit*, Amplitude> totalAmplitudePerSimHit;
330  for (std::vector<std::pair<const PSimHit*, Amplitude> >::const_iterator simul = (*mi).second.begin();
331  simul != (*mi).second.end();
332  simul++) {
333  totalAmplitudePerSimHit[(*simul).first] += (*simul).second;
334  }
335 
336  //--- include the noise as well
337  double totalAmplitude1 = afterNoise[(*mi).first];
338 
339  //--- digisimlink
340  int sim_counter = 0;
341  for (std::map<const PSimHit*, Amplitude>::const_iterator iter = totalAmplitudePerSimHit.begin();
342  iter != totalAmplitudePerSimHit.end();
343  iter++) {
344  float threshold = 0.;
345  float fraction = (*iter).second / totalAmplitude1;
346  if (fraction >= threshold) {
347  // Noise fluctuation could make fraction>1. Unphysical, set it by hand = 1.
348  if (fraction > 1.)
349  fraction = 1.;
350  for (std::vector<std::pair<const PSimHit*, int> >::const_iterator simcount = (*cmi).second.begin();
351  simcount != (*cmi).second.end();
352  ++simcount) {
353  if ((*iter).first == (*simcount).first)
354  sim_counter = (*simcount).second;
355  }
356  link_coll.push_back(StripDigiSimLink((*mi).first, //channel
357  ((*iter).first)->trackId(), //simhit trackId
358  sim_counter, //simhit counter
359  ((*iter).first)->eventId(), //simhit eventId
360  fraction)); //fraction
361  }
362  }
363  }
364 }
365 
367  const HitToDigisMapType& htd,
368  const HitCounterToDigisMapType& hctd,
369  const std::vector<float>& afterNoise,
370  unsigned int detID) {
371  link_coll.clear();
372  int nstrip = -1;
373  for (DigitalRawVecType::const_iterator i = digis.begin(); i != digis.end(); i++) {
374  nstrip++;
375  // Instead of checking the validity of the links against the digis,
376  // let's loop over digis and push the corresponding link
377  HitToDigisMapType::const_iterator mi(htd.find(nstrip));
378  HitCounterToDigisMapType::const_iterator cmi(hctd.find(nstrip));
379  if (mi == htd.end())
380  continue;
381  std::map<const PSimHit*, Amplitude> totalAmplitudePerSimHit;
382  for (std::vector<std::pair<const PSimHit*, Amplitude> >::const_iterator simul = (*mi).second.begin();
383  simul != (*mi).second.end();
384  simul++) {
385  totalAmplitudePerSimHit[(*simul).first] += (*simul).second;
386  }
387 
388  //--- include the noise as well
389  double totalAmplitude1 = afterNoise[(*mi).first];
390 
391  //--- digisimlink
392  int sim_counter_raw = 0;
393  for (std::map<const PSimHit*, Amplitude>::const_iterator iter = totalAmplitudePerSimHit.begin();
394  iter != totalAmplitudePerSimHit.end();
395  iter++) {
396  float threshold = 0.;
397  float fraction = (*iter).second / totalAmplitude1;
398  if (fraction >= threshold) {
399  //Noise fluctuation could make fraction>1. Unphysical, set it by hand.
400  if (fraction > 1.)
401  fraction = 1.;
402  //add counter information
403  for (std::vector<std::pair<const PSimHit*, int> >::const_iterator simcount = (*cmi).second.begin();
404  simcount != (*cmi).second.end();
405  ++simcount) {
406  if ((*iter).first == (*simcount).first)
407  sim_counter_raw = (*simcount).second;
408  }
409  link_coll.push_back(StripDigiSimLink((*mi).first, //channel
410  ((*iter).first)->trackId(), //simhit trackId
411  sim_counter_raw, //simhit counter
412  ((*iter).first)->eventId(), //simhit eventId
413  fraction)); //fraction
414  }
415  }
416  }
417 }
void push_link(const DigitalVecType &, const HitToDigisMapType &, const HitCounterToDigisMapType &, const std::vector< float > &, unsigned int)
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
const Range getRange(const uint32_t &detID) const
SiHitDigitizer * theSiHitDigitizer
DigitalRawVecType rawdigis
edm::ParameterSet conf_
SiStripFedZeroSuppression * theSiZeroSuppress
std::vector< unsigned int >::const_iterator ContainerIterator
void addBaselineShift(std::vector< float > &, std::vector< bool > &) const override
const SiStripApvGain::Range getRange(uint32_t detID) const
Definition: SiStripGain.h:75
std::pair< ContainerIterator, ContainerIterator > Range
DigitalRawVecType const & convertRaw(const std::vector< float > &, const SiStripGain *, unsigned int detid) override
const ParticleDataTable * pdt
const Range getRange(const uint32_t detID) const
void addNoise(std::vector< float > &, size_t &, size_t &, int, float, CLHEP::HepRandomEngine *) const override
void push_link_raw(const DigitalRawVecType &, const HitToDigisMapType &, const HitCounterToDigisMapType &, const std::vector< float > &, unsigned int)
SiDigitalConverter::DigitalRawVecType DigitalRawVecType
float getPed(const uint16_t &strip, const Range &range) const
SiDigitalConverter::DigitalVecType DigitalVecType
static std::string const input
Definition: EdmProvDump.cc:50
std::vector< StripDigiSimLink > link_coll
T getUntrackedParameter(std::string const &, T const &) const
SiTrivialDigitalConverter * theSiDigitalConverter
static float getNoise(uint16_t strip, const Range &range)
Definition: SiStripNoises.h:73
T const * product() const
Definition: ESHandle.h:86
std::map< int, std::vector< std::pair< const PSimHit *, Amplitude > >, std::less< int > > HitToDigisMapType
virtual void add(const std::vector< float > &locAmpl, const size_t &firstChannelWithSignal, const size_t &lastChannelWithSignal, const PSimHit *hit, const int &counter)
void run(edm::DetSet< SiStripDigi > &, edm::DetSet< SiStripRawDigi > &, const std::vector< std::pair< const PSimHit *, int > > &, StripGeomDetUnit const *, GlobalVector, float, edm::ESHandle< SiStripGain > &, edm::ESHandle< SiStripThreshold > &, edm::ESHandle< SiStripNoises > &, edm::ESHandle< SiStripPedestals > &, edm::ESHandle< SiStripBadStrip > &, const TrackerTopology *tTopo, CLHEP::HepRandomEngine *)
static float getStripGain(const uint16_t &strip, const SiStripApvGain::Range &range)
Definition: SiStripGain.h:77
std::vector< float > detAmpl
SiGaussianTailNoiseAdder * theSiNoiseAdder
virtual const StripTopology & specificTopology() const
Returns a reference to the strip proxy topology.
std::pair< ContainerIterator, ContainerIterator > Range
DetId geographicalId() const
The label of this GeomDet.
Definition: GeomDet.h:64
DigiSimLinkPileUpSignals::HitCounterToDigisMapType HitCounterToDigisMapType
void processHit(const PSimHit *, const StripGeomDetUnit &, GlobalVector, float, std::vector< float > &, size_t &, size_t &, const TrackerTopology *tTopo, CLHEP::HepRandomEngine *)
GlobalPoint toGlobal(const Point2DBase< Scalar, LocalTag > lp) const
Definition: Surface.h:79
DigiSimLinkAlgorithm(const edm::ParameterSet &conf)
Definition: DetId.h:17
const Plane & surface() const
The nominal surface of the GeomDet.
Definition: GeomDet.h:37
T mag() const
The vector magnitude. Equivalent to sqrt(vec.mag2())
const ParticleData * particle
constexpr uint32_t rawId() const
get the raw id
Definition: DetId.h:57
void suppress(const std::vector< SiStripDigi > &in, std::vector< SiStripDigi > &selectedSignal, uint32_t detId, const SiStripNoises &, const SiStripThreshold &)
const HitToDigisMapType & dumpLink() const
void addPedestals(std::vector< float > &, std::vector< float > &) const override
const Range getRange(const uint32_t detID) const
collection_type data
Definition: DetSet.h:80
DigitalVecType const & convert(const std::vector< float > &, const SiStripGain *, unsigned int detid) override
std::pair< ContainerIterator, ContainerIterator > Range
void addCMNoise(std::vector< float > &, float, std::vector< bool > &, CLHEP::HepRandomEngine *) const override
DigiSimLinkPileUpSignals::HitToDigisMapType HitToDigisMapType
data decode(const unsigned int &value) const
DigiSimLinkPileUpSignals * theDigiSimLinkPileUpSignals
std::vector< float > locAmpl
std::pair< ContainerIterator, ContainerIterator > Range
Definition: SiStripNoises.h:47
void addNoiseVR(std::vector< float > &, std::vector< float > &, CLHEP::HepRandomEngine *) const override
const HitCounterToDigisMapType & dumpCounterLink() const
std::map< int, std::vector< std::pair< const PSimHit *, int > >, std::less< int > > HitCounterToDigisMapType
#define LogDebug(id)