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