CMS 3D CMS Logo

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