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