CMS 3D CMS Logo

SiStripDigitizerAlgorithm.cc
Go to the documentation of this file.
1 // File: SiStripDigitizerAlgorithm.cc
2 // Description: Steering class for digitization.
3 // Modified 15/May/2013 mark.grimes@bristol.ac.uk - Modified so that the digi-sim link has the correct
4 // index for the sim hits stored. It was previously always set to zero (I won't mention that it was
5 // me who originally wrote that).
6 // Modified on Feb 11, 2015: prolay.kumar.mal@cern.ch & Jean-Laurent.Agram@cern.ch
7 // Added/Modified the individual strip noise in zero suppression
8 // mode from the conditions DB; previously, the digitizer used to
9 // consider the noise value for individual strips inside a module from
10 // the central strip noise value.
12 #include <vector>
13 #include <algorithm>
14 #include <iostream>
31 #include "CLHEP/Random/RandFlat.h"
32 
33 #include <cstring>
34 #include <sstream>
35 
36 #include <boost/algorithm/string.hpp>
37 
39  : lorentzAngleName(conf.getParameter<std::string>("LorentzAngle")),
40  theThreshold(conf.getParameter<double>("NoiseSigmaThreshold")),
41  cmnRMStib(conf.getParameter<double>("cmnRMStib")),
42  cmnRMStob(conf.getParameter<double>("cmnRMStob")),
43  cmnRMStid(conf.getParameter<double>("cmnRMStid")),
44  cmnRMStec(conf.getParameter<double>("cmnRMStec")),
45  APVSaturationProbScaling_(conf.getParameter<double>("APVSaturationProbScaling")),
46  makeDigiSimLinks_(conf.getUntrackedParameter<bool>("makeDigiSimLinks", false)),
47  peakMode(conf.getParameter<bool>("APVpeakmode")),
48  noise(conf.getParameter<bool>("Noise")),
49  RealPedestals(conf.getParameter<bool>("RealPedestals")),
50  SingleStripNoise(conf.getParameter<bool>("SingleStripNoise")),
51  CommonModeNoise(conf.getParameter<bool>("CommonModeNoise")),
52  BaselineShift(conf.getParameter<bool>("BaselineShift")),
53  APVSaturationFromHIP(conf.getParameter<bool>("APVSaturationFromHIP")),
54  theFedAlgo(conf.getParameter<int>("FedAlgorithm")),
55  zeroSuppression(conf.getParameter<bool>("ZeroSuppression")),
56  theElectronPerADC(conf.getParameter<double>(peakMode ? "electronPerAdcPeak" : "electronPerAdcDec")),
57  theTOFCutForPeak(conf.getParameter<double>("TOFCutForPeak")),
58  theTOFCutForDeconvolution(conf.getParameter<double>("TOFCutForDeconvolution")),
59  tofCut(peakMode ? theTOFCutForPeak : theTOFCutForDeconvolution),
60  cosmicShift(conf.getUntrackedParameter<double>("CosmicDelayShift")),
61  inefficiency(conf.getParameter<double>("Inefficiency")),
62  pedOffset((unsigned int)conf.getParameter<double>("PedestalsOffset")),
63  PreMixing_(conf.getParameter<bool>("PreMixingMode")),
64  theSiHitDigitizer(new SiHitDigitizer(conf)),
65  theSiPileUpSignals(new SiPileUpSignals()),
66  theSiNoiseAdder(new SiGaussianTailNoiseAdder(theThreshold)),
67  theSiDigitalConverter(new SiTrivialDigitalConverter(theElectronPerADC, PreMixing_)),
68  theSiZeroSuppress(new SiStripFedZeroSuppression(theFedAlgo)),
69  APVProbabilityFile(conf.getParameter<edm::FileInPath>("APVProbabilityFile")),
70  includeAPVSimulation_(conf.getParameter<bool>("includeAPVSimulation")),
71  apv_maxResponse_(conf.getParameter<double>("apv_maxResponse")),
72  apv_rate_(conf.getParameter<double>("apv_rate")),
73  apv_mVPerQ_(conf.getParameter<double>("apv_mVPerQ")),
74  apv_fCPerElectron_(conf.getParameter<double>("apvfCPerElectron")) {
75  if (peakMode) {
76  LogDebug("StripDigiInfo") << "APVs running in peak mode (poor time resolution)";
77  } else {
78  LogDebug("StripDigiInfo") << "APVs running in deconvolution mode (good time resolution)";
79  };
80  if (SingleStripNoise)
81  LogDebug("SiStripDigitizerAlgorithm") << " SingleStripNoise: ON";
82  else
83  LogDebug("SiStripDigitizerAlgorithm") << " SingleStripNoise: OFF";
84  if (CommonModeNoise)
85  LogDebug("SiStripDigitizerAlgorithm") << " CommonModeNoise: ON";
86  else
87  LogDebug("SiStripDigitizerAlgorithm") << " CommonModeNoise: OFF";
89  throw cms::Exception("PreMixing does not work with HIP loss simulation yet");
92  APVProbaFile.open((APVProbabilityFile.fullPath()).c_str());
93  if (APVProbaFile.is_open()) {
94  while (getline(APVProbaFile, line)) {
95  std::vector<std::string> strs;
96  boost::split(strs, line, boost::is_any_of(" "));
97  if (strs.size() == 2) {
98  mapOfAPVprobabilities[std::stoi(strs.at(0))] = std::stof(strs.at(1));
99  }
100  }
101  APVProbaFile.close();
102  } else
103  throw cms::Exception("MissingInput") << "It seems that the APV probability list is missing\n";
104  }
105 }
106 
108 
110  edm::ESHandle<SiStripBadStrip> deadChannelHandle;
111  iSetup.get<SiStripBadChannelRcd>().get(deadChannelHandle);
112 
113  unsigned int detId = det->geographicalId().rawId();
114  int numStrips = (det->specificTopology()).nstrips();
115 
116  SiStripBadStrip::Range detBadStripRange = deadChannelHandle->getRange(detId);
117  //storing the bad strip of the the module. the module is not removed but just signal put to 0
118  std::vector<bool>& badChannels = allBadChannels[detId];
119  badChannels.clear();
120  badChannels.insert(badChannels.begin(), numStrips, false);
121  for (SiStripBadStrip::ContainerIterator it = detBadStripRange.first; it != detBadStripRange.second; ++it) {
122  SiStripBadStrip::data fs = deadChannelHandle->decode(*it);
123  for (int strip = fs.firstStrip; strip < fs.firstStrip + fs.range; ++strip) {
124  badChannels[strip] = true;
125  }
126  }
127  firstChannelsWithSignal[detId] = numStrips;
128  lastChannelsWithSignal[detId] = 0;
129 
130  // if(APVSaturationFromHIP){
131  // std::bitset<6> &bs=SiStripTrackerAffectedAPVMap[detId];
132  // if(bs.any())theAffectedAPVvector.push_back(std::make_pair(detId,bs));
133  //}
134 }
135 
137  theSiPileUpSignals->reset();
138  // This should be clear by after all calls to digitize(), but I might as well make sure
139  associationInfoForDetId_.clear();
140 
141  APVSaturationProb_ = APVSaturationProbScaling_; // reset probability
143  FirstLumiCalc_ = true;
144  FirstDigitize_ = true;
145 
146  nTruePU_ = 0;
147 
148  //get gain noise pedestal lorentzAngle from ES handle
150  iSetup.getData(pdt);
151  setParticleDataTable(&*pdt);
153 }
154 
155 // Run the algorithm for a given module
156 // ------------------------------------
157 
158 void SiStripDigitizerAlgorithm::accumulateSimHits(std::vector<PSimHit>::const_iterator inputBegin,
159  std::vector<PSimHit>::const_iterator inputEnd,
160  size_t inputBeginGlobalIndex,
161  unsigned int tofBin,
162  const StripGeomDetUnit* det,
163  const GlobalVector& bfield,
164  const TrackerTopology* tTopo,
165  CLHEP::HepRandomEngine* engine) {
166  // produce SignalPoints for all SimHits in detector
167  unsigned int detID = det->geographicalId().rawId();
168  int numStrips = (det->specificTopology()).nstrips();
169 
170  size_t thisFirstChannelWithSignal = numStrips;
171  size_t thisLastChannelWithSignal = 0;
172 
173  float langle = (lorentzAngleHandle.isValid()) ? lorentzAngleHandle->getLorentzAngle(detID) : 0.;
174 
175  std::vector<float> locAmpl(numStrips, 0.);
176 
177  // Loop over hits
178 
179  uint32_t detId = det->geographicalId().rawId();
180  // First: loop on the SimHits
181  if (CLHEP::RandFlat::shoot(engine) > inefficiency) {
182  AssociationInfoForChannel* pDetIDAssociationInfo; // I only need this if makeDigiSimLinks_ is true...
183  if (makeDigiSimLinks_)
184  pDetIDAssociationInfo = &(associationInfoForDetId_[detId]); // ...so only search the map if that is the case
185  std::vector<float>
186  previousLocalAmplitude; // Only used if makeDigiSimLinks_ is true. Needed to work out the change in amplitude.
187 
188  size_t simHitGlobalIndex = inputBeginGlobalIndex; // This needs to stored to create the digi-sim link later
189  for (std::vector<PSimHit>::const_iterator simHitIter = inputBegin; simHitIter != inputEnd;
190  ++simHitIter, ++simHitGlobalIndex) {
191  // skip hits not in this detector.
192  if ((*simHitIter).detUnitId() != detId) {
193  continue;
194  }
195  // check TOF
196  if (std::fabs(simHitIter->tof() - cosmicShift -
197  det->surface().toGlobal(simHitIter->localPosition()).mag() / 30.) < tofCut &&
198  simHitIter->energyLoss() > 0) {
199  if (makeDigiSimLinks_)
200  previousLocalAmplitude = locAmpl; // Not needed except to make the sim link association.
201  size_t localFirstChannel = numStrips;
202  size_t localLastChannel = 0;
203  // process the hit
204  theSiHitDigitizer->processHit(
205  &*simHitIter, *det, bfield, langle, locAmpl, localFirstChannel, localLastChannel, tTopo, engine);
206 
207  if (thisFirstChannelWithSignal > localFirstChannel)
208  thisFirstChannelWithSignal = localFirstChannel;
209  if (thisLastChannelWithSignal < localLastChannel)
210  thisLastChannelWithSignal = localLastChannel;
211 
212  if (makeDigiSimLinks_) { // No need to do any of this if truth association was turned off in the configuration
213  for (size_t stripIndex = 0; stripIndex < locAmpl.size(); ++stripIndex) {
214  // Work out the amplitude from this SimHit from the difference of what it was before and what it is now
215  float signalFromThisSimHit = locAmpl[stripIndex] - previousLocalAmplitude[stripIndex];
216  if (signalFromThisSimHit != 0) { // If this SimHit had any contribution I need to record it.
217  auto& associationVector = (*pDetIDAssociationInfo)[stripIndex];
218  bool addNewEntry = true;
219  // Make sure the hit isn't in already. I've seen this a few times, it always seems to happen in pairs so I think
220  // it's something to do with the stereo strips.
221  for (auto& associationInfo : associationVector) {
222  if (associationInfo.trackID == simHitIter->trackId() &&
223  associationInfo.eventID == simHitIter->eventId()) {
224  // The hit is already in, so add this second contribution and move on
225  associationInfo.contributionToADC += signalFromThisSimHit;
226  addNewEntry = false;
227  break;
228  }
229  } // end of loop over associationVector
230  // If the hit wasn't already in create a new association info structure.
231  if (addNewEntry)
232  associationVector.push_back(AssociationInfo{
233  simHitIter->trackId(), simHitIter->eventId(), signalFromThisSimHit, simHitGlobalIndex, tofBin});
234  } // end of "if( signalFromThisSimHit!=0 )"
235  } // end of loop over locAmpl strips
236  } // end of "if( makeDigiSimLinks_ )"
237  } // end of TOF check
238  } // end for
239  }
240  theSiPileUpSignals->add(detID, locAmpl, thisFirstChannelWithSignal, thisLastChannelWithSignal);
241 
242  if (firstChannelsWithSignal[detID] > thisFirstChannelWithSignal)
243  firstChannelsWithSignal[detID] = thisFirstChannelWithSignal;
244  if (lastChannelsWithSignal[detID] < thisLastChannelWithSignal)
245  lastChannelsWithSignal[detID] = thisLastChannelWithSignal;
246 }
247 
248 //============================================================================
250  //Instlumi scalefactor calculating for dynamic inefficiency
251 
252  if (puInfo && FirstLumiCalc_) {
253  const std::vector<int>& bunchCrossing = puInfo->getMix_bunchCrossing();
254  const std::vector<float>& TrueInteractionList = puInfo->getMix_TrueInteractions();
255  const int bunchSpacing = puInfo->getMix_bunchSpacing();
256 
257  double RevFreq = 11245.;
258  double minBXsec = 70.0E-27; // use 70mb as an approximation
259  double Bunch = 2100.; // 2016 value
260  if (bunchSpacing == 50)
261  Bunch = Bunch / 2.;
262 
263  int pui = 0, p = 0;
264  std::vector<int>::const_iterator pu;
265  std::vector<int>::const_iterator pu0 = bunchCrossing.end();
266 
267  for (pu = bunchCrossing.begin(); pu != bunchCrossing.end(); ++pu) {
268  if (*pu == 0) {
269  pu0 = pu;
270  p = pui;
271  }
272  pui++;
273  }
274  if (pu0 != bunchCrossing.end()) { // found the in-time interaction
275  nTruePU_ = TrueInteractionList.at(p);
276  double instLumi = Bunch * nTruePU_ * RevFreq / minBXsec;
277  APVSaturationProb_ = instLumi / 6.0E33;
278  }
279  FirstLumiCalc_ = false;
280  }
281 }
282 
283 //============================================================================
284 
286  edm::DetSet<SiStripRawDigi>& outrawdigi,
287  edm::DetSet<SiStripRawDigi>& outStripAmplitudes,
288  edm::DetSet<SiStripRawDigi>& outStripAmplitudesPostAPV,
289  edm::DetSet<SiStripRawDigi>& outStripAPVBaselines,
291  const StripGeomDetUnit* det,
292  edm::ESHandle<SiStripGain>& gainHandle,
293  edm::ESHandle<SiStripThreshold>& thresholdHandle,
294  edm::ESHandle<SiStripNoises>& noiseHandle,
295  edm::ESHandle<SiStripPedestals>& pedestalHandle,
296  bool simulateAPVInThisEvent,
297  edm::ESHandle<SiStripApvSimulationParameters>& apvSimulationParametersHandle,
298  std::vector<std::pair<int, std::bitset<6>>>& theAffectedAPVvector,
299  CLHEP::HepRandomEngine* engine,
300  const TrackerTopology* tTopo) {
301  unsigned int detID = det->geographicalId().rawId();
302  int numStrips = (det->specificTopology()).nstrips();
303 
304  DetId detId(detID);
305  uint32_t SubDet = detId.subdetId();
306 
307  const SiPileUpSignals::SignalMapType* theSignal(theSiPileUpSignals->getSignal(detID));
308 
309  std::vector<float> detAmpl(numStrips, 0.);
310  if (theSignal) {
311  for (const auto& amp : *theSignal) {
312  detAmpl[amp.first] = amp.second;
313  }
314  }
315 
316  //removing signal from the dead (and HIP effected) strips
317  std::vector<bool>& badChannels = allBadChannels[detID];
318  for (int strip = 0; strip < numStrips; ++strip) {
319  if (badChannels[strip]) {
320  detAmpl[strip] = 0.;
321  }
322  }
323 
324  if (includeAPVSimulation_ && simulateAPVInThisEvent ) {
325 
326  // Get index in apv baseline distributions corresponding to z of detSet and PU
327  const StripTopology* topol = dynamic_cast<const StripTopology*>(&(det->specificTopology()));
328  LocalPoint localPos = topol->localPosition(0);
329  GlobalPoint globalPos = det->surface().toGlobal(Local3DPoint(localPos.x(), localPos.y(), localPos.z()));
330  float detSet_z = fabs(globalPos.z());
331  float detSet_r = globalPos.perp();
332 
333  // Store SCD, before APV sim
334  outStripAmplitudes.reserve(numStrips);
335  for (int strip = 0; strip < numStrips; ++strip) {
336  outStripAmplitudes.emplace_back(SiStripRawDigi(detAmpl[strip] / theElectronPerADC));
337  }
338 
339  // Simulate APV response for each strip
340  for (int strip = 0; strip < numStrips; ++strip) {
341  if (detAmpl[strip] > 0) {
342  // Convert charge from electrons to fC
343  double stripCharge = detAmpl[strip] * apv_fCPerElectron_;
344 
345  // Get APV baseline
346  double baselineV = 0;
347  if (SubDet == StripSubdetector::TIB) {
348  baselineV = apvSimulationParametersHandle->sampleTIB(tTopo->tibLayer(detId), detSet_z, nTruePU_, engine);
349  } else if (SubDet == StripSubdetector::TOB) {
350  baselineV = apvSimulationParametersHandle->sampleTOB(tTopo->tobLayer(detId), detSet_z, nTruePU_, engine);
351  } else if (SubDet == StripSubdetector::TID) {
352  baselineV = apvSimulationParametersHandle->sampleTID(tTopo->tidWheel(detId), detSet_r, nTruePU_, engine);
353  } else if (SubDet == StripSubdetector::TEC) {
354  baselineV = apvSimulationParametersHandle->sampleTEC(tTopo->tecWheel(detId), detSet_r, nTruePU_, engine);
355  }
356  // Store APV baseline for this strip
357  outStripAPVBaselines.emplace_back(SiStripRawDigi(baselineV));
358 
359  // Fitted parameters from G Hall/M Raymond
360  double maxResponse = apv_maxResponse_;
361  double rate = apv_rate_;
362 
363  double outputChargeInADC = 0;
364  if (baselineV < apv_maxResponse_) {
365  // Convert V0 into baseline charge
366  double baselineQ = -1.0 * rate * log(2 * maxResponse / (baselineV + maxResponse) - 1);
367 
368  // Add charge deposited in this BX
369  double newStripCharge = baselineQ + stripCharge;
370 
371  // Apply APV response
372  double signalV = 2 * maxResponse / (1 + exp(-1.0 * newStripCharge / rate)) - maxResponse;
373  double gain = signalV - baselineV;
374 
375  // Convert gain (mV) to charge (assuming linear region of APV) and then to electrons
376  double outputCharge = gain / apv_mVPerQ_;
377  outputChargeInADC = outputCharge / apv_fCPerElectron_;
378  }
379 
380  // Output charge back to original container
381  detAmpl[strip] = outputChargeInADC;
382  }
383  }
384 
385  // Store SCD, after APV sim
386  outStripAmplitudesPostAPV.reserve(numStrips);
387  for (int strip = 0; strip < numStrips; ++strip)
388  outStripAmplitudesPostAPV.emplace_back(SiStripRawDigi(detAmpl[strip] / theElectronPerADC));
389 
390  }
391 
392  if (APVSaturationFromHIP) {
393  //Implementation of the proper charge scaling function. Need consider resaturation effect:
394  //The probability map gives the probability that at least one HIP happened during the last N bunch crossings (cfr APV recovery time).
395  //The impact on the charge depends on the clostest HIP occurance (in terms of bunch crossing).
396  //The function discribing the APV recovery is therefore the weighted average function which takes into account all possibilities of HIP occurances across the last bx's.
397 
398  // do this step here because we now have access to luminosity information
399  if (FirstDigitize_) {
400  for (std::map<int, float>::iterator iter = mapOfAPVprobabilities.begin(); iter != mapOfAPVprobabilities.end();
401  ++iter) {
402  std::bitset<6> bs;
403  for (int Napv = 0; Napv < 6; Napv++) {
404  float cursor = CLHEP::RandFlat::shoot(engine);
405  bs[Napv] = cursor < iter->second * APVSaturationProb_
406  ? true
407  : false; //APVSaturationProb has been scaled by PU luminosity
408  }
409  SiStripTrackerAffectedAPVMap[iter->first] = bs;
410  }
411 
413  bool HasAtleastOneAffectedAPV = false;
414  while (!HasAtleastOneAffectedAPV) {
415  for (int bx = floor(300.0 / 25.0); bx > 0; bx--) { //Reminder: make these numbers not hard coded!!
416  float temp = CLHEP::RandFlat::shoot(engine) < 0.5 ? 1 : 0;
417  if (temp == 1 && bx < NumberOfBxBetweenHIPandEvent) {
419  HasAtleastOneAffectedAPV = true;
420  }
421  }
422  }
423 
424  FirstDigitize_ = false;
425  }
426 
427  std::bitset<6>& bs = SiStripTrackerAffectedAPVMap[detID];
428 
429  if (bs.any()) {
430  // store this information so it can be saved to the event later
431  theAffectedAPVvector.push_back(std::make_pair(detID, bs));
432 
433  if (!PreMixing_) {
434  // Here below is the scaling function which describes the evolution of the baseline (i.e. how the charge is suppressed).
435  // This must be replaced as soon as we have a proper modeling of the baseline evolution from VR runs
436  float Shift =
437  1 - NumberOfBxBetweenHIPandEvent / floor(300.0 / 25.0); //Reminder: make these numbers not hardcoded!!
438  float randomX = CLHEP::RandFlat::shoot(engine);
439  float scalingValue = (randomX - Shift) * 10.0 / 7.0 - 3.0 / 7.0;
440 
441  for (int strip = 0; strip < numStrips; ++strip) {
442  if (!badChannels[strip] && bs[strip / 128] == 1) {
443  detAmpl[strip] *= scalingValue > 0 ? scalingValue : 0.0;
444  }
445  }
446  }
447  }
448  }
449 
450  SiStripNoises::Range detNoiseRange = noiseHandle->getRange(detID);
451  SiStripApvGain::Range detGainRange = gainHandle->getRange(detID);
452  SiStripPedestals::Range detPedestalRange = pedestalHandle->getRange(detID);
453 
454  // -----------------------------------------------------------
455 
456  auto& firstChannelWithSignal = firstChannelsWithSignal[detID];
457  auto& lastChannelWithSignal = lastChannelsWithSignal[detID];
458  auto iAssociationInfoByChannel =
459  associationInfoForDetId_.find(detID); // Use an iterator so that I can easily remove it once finished
460 
461  if (zeroSuppression) {
462  //Adding the strip noise
463  //------------------------------------------------------
464  if (noise) {
465  if (SingleStripNoise) {
466  // std::cout<<"In SSN, detId="<<detID<<std::endl;
467  std::vector<float> noiseRMSv;
468  noiseRMSv.clear();
469  noiseRMSv.insert(noiseRMSv.begin(), numStrips, 0.);
470  for (int strip = 0; strip < numStrips; ++strip) {
471  if (!badChannels[strip]) {
472  float gainValue = gainHandle->getStripGain(strip, detGainRange);
473  noiseRMSv[strip] = (noiseHandle->getNoise(strip, detNoiseRange)) * theElectronPerADC / gainValue;
474  //std::cout<<"<SiStripDigitizerAlgorithm::digitize>: gainValue: "<<gainValue<<"\tnoiseRMSv["<<strip<<"]: "<<noiseRMSv[strip]<<std::endl;
475  }
476  }
477  theSiNoiseAdder->addNoiseVR(detAmpl, noiseRMSv, engine);
478  } else {
479  int RefStrip = int(numStrips / 2.);
480  while (RefStrip < numStrips &&
481  badChannels[RefStrip]) { //if the refstrip is bad, I move up to when I don't find it
482  RefStrip++;
483  }
484  if (RefStrip < numStrips) {
485  float RefgainValue = gainHandle->getStripGain(RefStrip, detGainRange);
486  float RefnoiseRMS = noiseHandle->getNoise(RefStrip, detNoiseRange) * theElectronPerADC / RefgainValue;
487 
488  theSiNoiseAdder->addNoise(
489  detAmpl, firstChannelWithSignal, lastChannelWithSignal, numStrips, RefnoiseRMS, engine);
490  //std::cout<<"<SiStripDigitizerAlgorithm::digitize>: RefgainValue: "<<RefgainValue<<"\tRefnoiseRMS: "<<RefnoiseRMS<<std::endl;
491  }
492  }
493  } //if noise
494 
495  DigitalVecType digis;
496  theSiZeroSuppress->suppress(
497  theSiDigitalConverter->convert(detAmpl, gainHandle, detID), digis, detID, noiseHandle, thresholdHandle);
498  // Now do the association to truth. Note that if truth association was turned off in the configuration this map
499  // will be empty and the iterator will always equal associationInfoForDetId_.end().
500  if (iAssociationInfoByChannel !=
501  associationInfoForDetId_.end()) { // make sure the readings for this DetID aren't completely from noise
502  for (const auto& iDigi : digis) {
503  auto& associationInfoByChannel = iAssociationInfoByChannel->second;
504  const std::vector<AssociationInfo>& associationInfo = associationInfoByChannel[iDigi.channel()];
505 
506  // Need to find the total from all sim hits, because this might not be the same as the total
507  // digitised due to noise or whatever.
508  float totalSimADC = 0;
509  for (const auto& iAssociationInfo : associationInfo)
510  totalSimADC += iAssociationInfo.contributionToADC;
511  // Now I know that I can loop again and create the links
512  for (const auto& iAssociationInfo : associationInfo) {
513  // Note simHitGlobalIndex used to have +1 because TrackerHitAssociator (the only place I can find this value being used)
514  // expected counting to start at 1, not 0. Now changed.
515  outLink.push_back(StripDigiSimLink(iDigi.channel(),
516  iAssociationInfo.trackID,
517  iAssociationInfo.simHitGlobalIndex,
518  iAssociationInfo.tofBin,
519  iAssociationInfo.eventID,
520  iAssociationInfo.contributionToADC / totalSimADC));
521  } // end of loop over associationInfo
522  } // end of loop over the digis
523  } // end of check that iAssociationInfoByChannel is a valid iterator
524  outdigi.data = digis;
525  } //if zeroSuppression
526 
527  if (!zeroSuppression) {
528  //if(noise){
529  // the constant pedestal offset is needed because
530  // negative adc counts are not allowed in case
531  // Pedestal and CMN subtraction is performed.
532  // The pedestal value read from the conditions
533  // is pedValue and after the pedestal subtraction
534  // the baseline is zero. The Common Mode Noise
535  // is not subtracted from the negative adc counts
536  // channels. Adding pedOffset the baseline is set
537  // to pedOffset after pedestal subtraction and CMN
538  // is subtracted to all the channels since none of
539  // them has negative adc value. The pedOffset is
540  // treated as a constant component in the CMN
541  // estimation and subtracted as CMN.
542 
543  //calculating the charge deposited on each APV and subtracting the shift
544  //------------------------------------------------------
545  if (BaselineShift) {
546  theSiNoiseAdder->addBaselineShift(detAmpl, badChannels);
547  }
548 
549  //Adding the strip noise
550  //------------------------------------------------------
551  if (noise) {
552  std::vector<float> noiseRMSv;
553  noiseRMSv.clear();
554  noiseRMSv.insert(noiseRMSv.begin(), numStrips, 0.);
555 
556  if (SingleStripNoise) {
557  for (int strip = 0; strip < numStrips; ++strip) {
558  if (!badChannels[strip])
559  noiseRMSv[strip] = (noiseHandle->getNoise(strip, detNoiseRange)) * theElectronPerADC;
560  }
561 
562  } else {
563  int RefStrip = 0; //int(numStrips/2.);
564  while (RefStrip < numStrips &&
565  badChannels[RefStrip]) { //if the refstrip is bad, I move up to when I don't find it
566  RefStrip++;
567  }
568  if (RefStrip < numStrips) {
569  float noiseRMS = noiseHandle->getNoise(RefStrip, detNoiseRange) * theElectronPerADC;
570  for (int strip = 0; strip < numStrips; ++strip) {
571  if (!badChannels[strip])
572  noiseRMSv[strip] = noiseRMS;
573  }
574  }
575  }
576 
577  theSiNoiseAdder->addNoiseVR(detAmpl, noiseRMSv, engine);
578  }
579 
580  //adding the CMN
581  //------------------------------------------------------
582  if (CommonModeNoise) {
583  float cmnRMS = 0.;
584  DetId detId(detID);
585  switch (detId.subdetId()) {
587  cmnRMS = cmnRMStib;
588  break;
590  cmnRMS = cmnRMStid;
591  break;
593  cmnRMS = cmnRMStob;
594  break;
596  cmnRMS = cmnRMStec;
597  break;
598  }
599  cmnRMS *= theElectronPerADC;
600  theSiNoiseAdder->addCMNoise(detAmpl, cmnRMS, badChannels, engine);
601  }
602 
603  //Adding the pedestals
604  //------------------------------------------------------
605 
606  std::vector<float> vPeds;
607  vPeds.clear();
608  vPeds.insert(vPeds.begin(), numStrips, 0.);
609 
610  if (RealPedestals) {
611  for (int strip = 0; strip < numStrips; ++strip) {
612  if (!badChannels[strip])
613  vPeds[strip] = (pedestalHandle->getPed(strip, detPedestalRange) + pedOffset) * theElectronPerADC;
614  }
615  } else {
616  for (int strip = 0; strip < numStrips; ++strip) {
617  if (!badChannels[strip])
618  vPeds[strip] = pedOffset * theElectronPerADC;
619  }
620  }
621 
622  theSiNoiseAdder->addPedestals(detAmpl, vPeds);
623 
624  //if(!RealPedestals&&!CommonModeNoise&&!noise&&!BaselineShift&&!APVSaturationFromHIP){
625 
626  // edm::LogWarning("SiStripDigitizer")<<"You are running the digitizer without Noise generation and without applying Zero Suppression. ARE YOU SURE???";
627  //}else{
628 
629  DigitalRawVecType rawdigis = theSiDigitalConverter->convertRaw(detAmpl, gainHandle, detID);
630 
631  // Now do the association to truth. Note that if truth association was turned off in the configuration this map
632  // will be empty and the iterator will always equal associationInfoForDetId_.end().
633  if (iAssociationInfoByChannel !=
634  associationInfoForDetId_.end()) { // make sure the readings for this DetID aren't completely from noise
635  // N.B. For the raw digis the channel is inferred from the position in the vector.
636  // I'VE NOT TESTED THIS YET!!!!!
637  // ToDo Test this properly.
638  for (size_t channel = 0; channel < rawdigis.size(); ++channel) {
639  auto& associationInfoByChannel = iAssociationInfoByChannel->second;
640  const auto iAssociationInfo = associationInfoByChannel.find(channel);
641  if (iAssociationInfo == associationInfoByChannel.end())
642  continue; // Skip if there is no sim information for this channel (i.e. it's all noise)
643  const std::vector<AssociationInfo>& associationInfo = iAssociationInfo->second;
644 
645  // Need to find the total from all sim hits, because this might not be the same as the total
646  // digitised due to noise or whatever.
647  float totalSimADC = 0;
648  for (const auto& iAssociationInfo : associationInfo)
649  totalSimADC += iAssociationInfo.contributionToADC;
650  // Now I know that I can loop again and create the links
651  for (const auto& iAssociationInfo : associationInfo) {
652  // Note simHitGlobalIndex used to have +1 because TrackerHitAssociator (the only place I can find this value being used)
653  // expected counting to start at 1, not 0. Now changed.
654  outLink.push_back(StripDigiSimLink(channel,
655  iAssociationInfo.trackID,
656  iAssociationInfo.simHitGlobalIndex,
657  iAssociationInfo.tofBin,
658  iAssociationInfo.eventID,
659  iAssociationInfo.contributionToADC / totalSimADC));
660  } // end of loop over associationInfo
661  } // end of loop over the digis
662  } // end of check that iAssociationInfoByChannel is a valid iterator
663 
664  outrawdigi.data = rawdigis;
665 
666  //}
667  }
668 
669  // Now that I've finished with this entry in the map of associations, I can remove it.
670  // Note that there might not be an association if the ADC reading is from noise in which
671  // case associationIsValid will be false.
672  if (iAssociationInfoByChannel != associationInfoForDetId_.end())
673  associationInfoForDetId_.erase(iAssociationInfoByChannel);
674 }
#define LogDebug(id)
unsigned short range
GlobalPoint toGlobal(const Point2DBase< Scalar, LocalTag > lp) const
Definition: Surface.h:106
const std::unique_ptr< SiPileUpSignals > theSiPileUpSignals
edm::ESHandle< SiStripLorentzAngle > lorentzAngleHandle
float sampleTIB(layerid layer, float z, float pu, CLHEP::HepRandomEngine *engine) const
void push_back(const T &t)
Definition: DetSet.h:68
T perp() const
Definition: PV3DBase.h:72
unsigned int tibLayer(const DetId &id) const
std::map< int, float > mapOfAPVprobabilities
AssociationInfoForDetId associationInfoForDetId_
Structure that holds the information on the SimTrack contributions. Only filled if makeDigiSimLinks_ ...
const std::vector< float > & getMix_TrueInteractions() const
SiDigitalConverter::DigitalRawVecType DigitalRawVecType
SiDigitalConverter::DigitalVecType DigitalVecType
T mag() const
The vector magnitude. Equivalent to sqrt(vec.mag2())
const std::vector< int > & getMix_bunchCrossing() const
std::vector< unsigned int >::const_iterator ContainerIterator
float sampleTID(layerid wheel, float r, float pu, CLHEP::HepRandomEngine *engine) const
void digitize(edm::DetSet< SiStripDigi > &outDigis, edm::DetSet< SiStripRawDigi > &outRawDigis, edm::DetSet< SiStripRawDigi > &outStripAmplitudes, edm::DetSet< SiStripRawDigi > &outStripAmplitudesPostAPV, edm::DetSet< SiStripRawDigi > &outStripAPVBaselines, edm::DetSet< StripDigiSimLink > &outLink, const StripGeomDetUnit *stripdet, edm::ESHandle< SiStripGain > &, edm::ESHandle< SiStripThreshold > &, edm::ESHandle< SiStripNoises > &, edm::ESHandle< SiStripPedestals > &, bool simulateAPVInThisEvent, edm::ESHandle< SiStripApvSimulationParameters > &, std::vector< std::pair< int, std::bitset< 6 >>> &theAffectedAPVvector, CLHEP::HepRandomEngine *, const TrackerTopology *tTopo)
constexpr uint32_t rawId() const
get the raw id
Definition: DetId.h:50
void initializeEvent(const edm::EventSetup &iSetup)
T y() const
Definition: PV3DBase.h:63
unsigned int tidWheel(const DetId &id) const
std::pair< ContainerIterator, ContainerIterator > Range
void initializeDetUnit(StripGeomDetUnit const *det, const edm::EventSetup &iSetup)
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
const std::unique_ptr< const SiGaussianTailNoiseAdder > theSiNoiseAdder
const std::unique_ptr< SiHitDigitizer > theSiHitDigitizer
float sampleTOB(layerid layer, float z, float pu, CLHEP::HepRandomEngine *engine) const
std::map< unsigned int, size_t > firstChannelsWithSignal
float getPed(const uint16_t &strip, const Range &range) const
std::map< int, Amplitude > SignalMapType
bool getData(T &iHolder) const
Definition: EventSetup.h:111
void reserve(size_t s)
Definition: DetSet.h:67
static float getNoise(uint16_t strip, const Range &range)
Definition: SiStripNoises.h:74
float getLorentzAngle(const uint32_t &) const
const std::unique_ptr< SiTrivialDigitalConverter > theSiDigitalConverter
decltype(auto) emplace_back(Args &&...args)
Definition: DetSet.h:70
const std::unique_ptr< SiStripFedZeroSuppression > theSiZeroSuppress
virtual LocalPoint localPosition(float strip) const =0
static float getStripGain(const uint16_t &strip, const SiStripApvGain::Range &range)
Definition: SiStripGain.h:73
T z() const
Definition: PV3DBase.h:64
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
void calculateInstlumiScale(PileupMixingContent *puInfo)
std::map< unsigned int, std::vector< bool > > allBadChannels
Point3DBase< float, LocalTag > Local3DPoint
Definition: LocalPoint.h:9
void setParticleDataTable(const ParticleDataTable *pardt)
Definition: DetId.h:18
unsigned short firstStrip
std::map< int, std::vector< AssociationInfo > > AssociationInfoForChannel
RealPedestals
NOTE : turning Noise ON/OFF will make a big change Parameters valid only if Noise = True and ZeroSupp...
SiStripDigitizerAlgorithm(const edm::ParameterSet &conf)
double rate(double x)
Definition: Constants.cc:3
collection_type data
Definition: DetSet.h:80
const Range getRange(const uint32_t detID) const
HLT enums.
const Range getRange(const uint32_t detID) const
std::pair< ContainerIterator, ContainerIterator > Range
std::map< unsigned int, size_t > lastChannelsWithSignal
T get() const
Definition: EventSetup.h:71
void accumulateSimHits(const std::vector< PSimHit >::const_iterator inputBegin, const std::vector< PSimHit >::const_iterator inputEnd, size_t inputBeginGlobalIndex, unsigned int tofBin, const StripGeomDetUnit *stripdet, const GlobalVector &bfield, const TrackerTopology *tTopo, CLHEP::HepRandomEngine *)
const int & getMix_bunchSpacing() const
std::string fullPath() const
Definition: FileInPath.cc:163
const Range getRange(const uint32_t &detID) const
std::map< int, std::bitset< 6 > > SiStripTrackerAffectedAPVMap
std::pair< ContainerIterator, ContainerIterator > Range
Definition: SiStripNoises.h:50
bool isValid() const
Definition: ESHandle.h:44
A Digi for the silicon strip detector, containing only adc information, and suitable for storing raw ...
T x() const
Definition: PV3DBase.h:62
unsigned int tecWheel(const DetId &id) const
float sampleTEC(layerid wheel, float r, float pu, CLHEP::HepRandomEngine *engine) const
double split
Definition: MVATrainer.cc:139
const ParticleDataTable * pdt
data decode(const unsigned int &value) const
unsigned int tobLayer(const DetId &id) const
const SiStripApvGain::Range getRange(uint32_t detID) const
Definition: SiStripGain.h:71