CMS 3D CMS Logo

PreMixingSiStripWorker.cc
Go to the documentation of this file.
12 
15 
16 //Data Formats
20 
29 
35 
36 #include "CLHEP/Random/RandFlat.h"
37 
40 
41 #include <map>
42 #include <memory>
43 
45 public:
47  ~PreMixingSiStripWorker() override = default;
48 
49  void initializeEvent(edm::Event const& e, edm::EventSetup const& c) override;
50  void addSignals(edm::Event const& e, edm::EventSetup const& es) override;
51  void addPileups(PileUpEventPrincipal const& pep, edm::EventSetup const& es) override;
52  void put(edm::Event& e, edm::EventSetup const& iSetup, std::vector<PileupSummaryInfo> const& ps, int bs) override;
53 
54 private:
55  void DMinitializeDetUnit(StripGeomDetUnit const* det, const edm::EventSetup& iSetup);
56 
57  // data specifiers
58 
59  edm::InputTag SistripLabelSig_; // name given to collection of SiStrip digis
60  edm::InputTag SiStripPileInputTag_; // InputTag for pileup strips
61  std::string SiStripDigiCollectionDM_; // secondary name to be given to new SiStrip digis
62 
63  edm::InputTag SistripAPVLabelSig_; // where to find vector of dead APVs
66 
67  //
68 
69  typedef float Amplitude;
70  typedef std::pair<uint16_t, Amplitude> RawDigi; // Replacement for SiStripDigi with pulse height instead of integer ADC
71  typedef std::vector<SiStripDigi> OneDetectorMap; // maps by strip ID for later combination - can have duplicate strips
72  typedef std::vector<RawDigi> OneDetectorRawMap; // maps by strip ID for later combination - can have duplicate strips
73  typedef std::map<uint32_t, OneDetectorMap> SiGlobalIndex; // map to all data for each detector ID
74  typedef std::map<uint32_t, OneDetectorRawMap> SiGlobalRawIndex; // map to all data for each detector ID
75 
77 
78  SiGlobalIndex SiHitStorage_;
79  SiGlobalRawIndex SiRawDigis_;
80 
81  // variables for temporary storage of mixed hits:
82  typedef std::map<int, Amplitude> SignalMapType;
83  typedef std::map<uint32_t, SignalMapType> signalMaps;
84 
85  const SignalMapType* getSignal(uint32_t detID) const {
86  auto where = signals_.find(detID);
87  if (where == signals_.end()) {
88  return nullptr;
89  }
90  return &where->second;
91  }
92 
93  signalMaps signals_;
94 
95  // to keep track of dead APVs from HIP interactions
96  typedef std::multimap<uint32_t, std::bitset<6>> APVMap;
97 
99 
100  // for noise adding:
101 
104  bool peakMode;
105  double theThreshold;
110 
111  std::unique_ptr<SiGaussianTailNoiseAdder> theSiNoiseAdder;
112  std::unique_ptr<SiStripFedZeroSuppression> theSiZeroSuppress;
113  std::unique_ptr<SiTrivialDigitalConverter> theSiDigitalConverter;
114 
116 
117  // bad channels for each detector ID
118  std::map<unsigned int, std::vector<bool>> allBadChannels;
119  // channels killed by HIP interactions for each detector ID
120  std::map<unsigned int, std::vector<bool>> allHIPChannels;
121  // first and last channel wit signal for each detector ID
122  std::map<unsigned int, size_t> firstChannelsWithSignal;
123  std::map<unsigned int, size_t> lastChannelsWithSignal;
124 
126  const double fracOfEventsToSimAPV_;
127  const double apv_maxResponse_;
128  const double apv_rate_;
129  const double apv_mVPerQ_;
130  const double apv_fCPerElectron_;
131 
132  //----------------------------
133 
135  public:
136  bool operator()(SiStripDigi i, SiStripDigi j) const { return i.strip() < j.strip(); }
137  };
138 
140  public:
141  bool operator()(RawDigi i, RawDigi j) const { return i.first < j.first; }
142  };
143 };
144 
148  : gainLabel(ps.getParameter<std::string>("Gain")),
149  SingleStripNoise(ps.getParameter<bool>("SingleStripNoise")),
150  peakMode(ps.getParameter<bool>("APVpeakmode")),
151  theThreshold(ps.getParameter<double>("NoiseSigmaThreshold")),
152  theElectronPerADC(ps.getParameter<double>(peakMode ? "electronPerAdcPeak" : "electronPerAdcDec")),
153  APVSaturationFromHIP_(ps.getParameter<bool>("APVSaturationFromHIP")),
154  theFedAlgo(ps.getParameter<int>("FedAlgorithm_PM")),
155  geometryType(ps.getParameter<std::string>("GeometryType")),
158  includeAPVSimulation_(ps.getParameter<bool>("includeAPVSimulation")),
159  fracOfEventsToSimAPV_(ps.getParameter<double>("fracOfEventsToSimAPV")),
160  apv_maxResponse_(ps.getParameter<double>("apv_maxResponse")),
161  apv_rate_(ps.getParameter<double>("apv_rate")),
162  apv_mVPerQ_(ps.getParameter<double>("apv_mVPerQ")),
163  apv_fCPerElectron_(ps.getParameter<double>("apvfCPerElectron"))
164 
165 {
166  // declare the products to produce
167 
168  SistripLabelSig_ = ps.getParameter<edm::InputTag>("SistripLabelSig");
169  SiStripPileInputTag_ = ps.getParameter<edm::InputTag>("SiStripPileInputTag");
170 
171  SiStripDigiCollectionDM_ = ps.getParameter<std::string>("SiStripDigiCollectionDM");
172  SistripAPVListDM_ = ps.getParameter<std::string>("SiStripAPVListDM");
173 
175  producer.produces<bool>(SiStripDigiCollectionDM_ + "SimulatedAPVDynamicGain");
176 
177  if (APVSaturationFromHIP_) {
178  SistripAPVLabelSig_ = ps.getParameter<edm::InputTag>("SistripAPVLabelSig");
179  SiStripAPVPileInputTag_ = ps.getParameter<edm::InputTag>("SistripAPVPileInputTag");
180  iC.consumes<std::vector<std::pair<int, std::bitset<6>>>>(SistripAPVLabelSig_);
181  }
183  // clear local storage for this event
184  SiHitStorage_.clear();
185 
187  if (!rng.isAvailable()) {
188  throw cms::Exception("Psiguration") << "SiStripDigitizer requires the RandomNumberGeneratorService\n"
189  "which is not present in the psiguration file. You must add the service\n"
190  "in the configuration file or remove the modules that require it.";
191  }
192 
194 }
195 
197  // initialize individual detectors so we can copy real digitization code:
198 
200 
201  for (auto iu = pDD->detUnits().begin(); iu != pDD->detUnits().end(); ++iu) {
202  unsigned int detId = (*iu)->geographicalId().rawId();
203  DetId idet = DetId(detId);
204  unsigned int isub = idet.subdetId();
205  if ((isub == StripSubdetector::TIB) || (isub == StripSubdetector::TID) || (isub == StripSubdetector::TOB) ||
206  (isub == StripSubdetector::TEC)) {
207  auto stripdet = dynamic_cast<StripGeomDetUnit const*>((*iu));
208  assert(stripdet != nullptr);
209  DMinitializeDetUnit(stripdet, iSetup);
210  }
211  }
212 }
213 
215  edm::ESHandle<SiStripBadStrip> deadChannelHandle;
216  iSetup.get<SiStripBadChannelRcd>().get(deadChannelHandle);
217 
218  unsigned int detId = det->geographicalId().rawId();
219  int numStrips = (det->specificTopology()).nstrips();
220 
221  SiStripBadStrip::Range detBadStripRange = deadChannelHandle->getRange(detId);
222  //storing the bad strip of the the module. the module is not removed but just signal put to 0
223  std::vector<bool>& badChannels = allBadChannels[detId];
224  std::vector<bool>& hipChannels = allHIPChannels[detId];
225  badChannels.clear();
226  badChannels.insert(badChannels.begin(), numStrips, false);
227  hipChannels.clear();
228  hipChannels.insert(hipChannels.begin(), numStrips, false);
229 
230  for (SiStripBadStrip::ContainerIterator it = detBadStripRange.first; it != detBadStripRange.second; ++it) {
231  SiStripBadStrip::data fs = deadChannelHandle->decode(*it);
232  for (int strip = fs.firstStrip; strip < fs.firstStrip + fs.range; ++strip)
233  badChannels[strip] = true;
234  }
235  firstChannelsWithSignal[detId] = numStrips;
236  lastChannelsWithSignal[detId] = 0;
237 }
238 
240  // fill in maps of hits
241 
243 
244  if (e.getByLabel(SistripLabelSig_, input)) {
245  OneDetectorMap LocalMap;
246 
247  //loop on all detsets (detectorIDs) inside the input collection
248  edm::DetSetVector<SiStripDigi>::const_iterator DSViter = input->begin();
249  for (; DSViter != input->end(); DSViter++) {
250 #ifdef DEBUG
251  LogDebug("PreMixingSiStripWorker") << "Processing DetID " << DSViter->id;
252 #endif
253 
254  LocalMap.clear();
255  LocalMap.reserve((DSViter->data).size());
256  LocalMap.insert(LocalMap.end(), (DSViter->data).begin(), (DSViter->data).end());
257 
258  SiHitStorage_.insert(SiGlobalIndex::value_type(DSViter->id, LocalMap));
259  }
260  }
261 
262  // keep here for future reference. In current implementation, HIP killing is done once in PU file
263  /* if(APVSaturationFromHIP_) {
264  edm::Handle<std::vector<std::pair<int,std::bitset<6>> > > APVinput;
265 
266  if( e.getByLabel(SistripAPVLabelSig_,APVinput) ) {
267 
268  std::vector<std::pair<int,std::bitset<6>> >::const_iterator entry = APVinput->begin();
269  for( ; entry != APVinput->end(); entry++) {
270  theAffectedAPVmap_.insert(APVMap::value_type(entry->first, entry->second));
271  }
272  }
273  } */
274 
275 } // end of addSiStripSignals
276 
278  LogDebug("PreMixingSiStripWorker") << "\n===============> adding pileups from event " << pep.principal().id()
279  << " for bunchcrossing " << pep.bunchCrossing();
280 
281  // fill in maps of hits; same code as addSignals, except now applied to the pileup events
282 
284  pep.getByLabel(SiStripPileInputTag_, inputHandle);
285 
286  if (inputHandle.isValid()) {
287  const auto& input = *inputHandle;
288 
289  OneDetectorMap LocalMap;
290 
291  //loop on all detsets (detectorIDs) inside the input collection
293  for (; DSViter != input.end(); DSViter++) {
294 #ifdef DEBUG
295  LogDebug("PreMixingSiStripWorker") << "Pileups: Processing DetID " << DSViter->id;
296 #endif
297 
298  // find correct local map (or new one) for this detector ID
299 
300  SiGlobalIndex::const_iterator itest;
301 
302  itest = SiHitStorage_.find(DSViter->id);
303 
304  if (itest != SiHitStorage_.end()) { // this detID already has hits, add to existing map
305 
306  LocalMap = itest->second;
307 
308  // fill in local map with extra channels
309  LocalMap.insert(LocalMap.end(), (DSViter->data).begin(), (DSViter->data).end());
310  std::stable_sort(LocalMap.begin(), LocalMap.end(), PreMixingSiStripWorker::StrictWeakOrdering());
311  SiHitStorage_[DSViter->id] = LocalMap;
312 
313  } else { // fill local storage with this information, put in global collection
314 
315  LocalMap.clear();
316  LocalMap.reserve((DSViter->data).size());
317  LocalMap.insert(LocalMap.end(), (DSViter->data).begin(), (DSViter->data).end());
318 
319  SiHitStorage_.insert(SiGlobalIndex::value_type(DSViter->id, LocalMap));
320  }
321  }
322 
323  if (APVSaturationFromHIP_) {
325  pep.getByLabel(SiStripAPVPileInputTag_, inputAPVHandle);
326 
327  if (inputAPVHandle.isValid()) {
328  const auto& APVinput = inputAPVHandle;
329 
330  std::vector<std::pair<int, std::bitset<6>>>::const_iterator entry = APVinput->begin();
331  for (; entry != APVinput->end(); entry++) {
332  theAffectedAPVmap_.insert(APVMap::value_type(entry->first, entry->second));
333  }
334  }
335  }
336  }
337 }
338 
340  edm::EventSetup const& iSetup,
341  std::vector<PileupSummaryInfo> const& ps,
342  int bs) {
343  // set up machinery to do proper noise adding:
344  edm::ESHandle<SiStripGain> gainHandle;
345  edm::ESHandle<SiStripNoises> noiseHandle;
346  edm::ESHandle<SiStripThreshold> thresholdHandle;
347  edm::ESHandle<SiStripPedestals> pedestalHandle;
348  edm::ESHandle<SiStripBadStrip> deadChannelHandle;
349  edm::ESHandle<SiStripApvSimulationParameters> apvSimulationParametersHandle;
351  iSetup.get<SiStripGainSimRcd>().get(gainLabel, gainHandle);
352  iSetup.get<SiStripNoisesRcd>().get(noiseHandle);
353  iSetup.get<SiStripThresholdRcd>().get(thresholdHandle);
354  iSetup.get<SiStripPedestalsRcd>().get(pedestalHandle);
355 
357  CLHEP::HepRandomEngine* engine = &rng->getEngine(e.streamID());
358 
359  const bool simulateAPVInThisEvent = includeAPVSimulation_ && (CLHEP::RandFlat::shoot(engine) < fracOfEventsToSimAPV_);
360  float nTruePU = 0.; // = ps.getTrueNumInteractions();
361  if (simulateAPVInThisEvent) {
362  iSetup.get<TrackerTopologyRcd>().get(tTopo);
363  iSetup.get<SiStripApvSimulationParametersRcd>().get(apvSimulationParametersHandle);
364  const auto it = std::find_if(
365  std::begin(ps), std::end(ps), [](const PileupSummaryInfo& bxps) { return bxps.getBunchCrossing() == 0; });
366  if (it != std::begin(ps)) {
367  nTruePU = it->getTrueNumInteractions();
368  } else {
369  edm::LogWarning("PreMixingSiStripWorker") << "Could not find PileupSummaryInfo for current bunch crossing";
370  nTruePU = std::begin(ps)->getTrueNumInteractions();
371  }
372  }
373 
374  std::map<int, std::bitset<6>> DeadAPVList;
375  DeadAPVList.clear();
376 
377  // First, have to convert all ADC counts to raw pulse heights so that values can be added properly
378  // In PreMixing, pulse heights are saved with ADC = sqrt(9.0*PulseHeight) - have to undo.
379 
380  // This is done here because it's the only place we have access to EventSetup
381  // Simultaneously, merge lists of hit channels in each DetId.
382  // Signal Digis are in the list first, have to merge lists of hit strips on the fly,
383  // add signals on duplicates later
384 
385  OneDetectorRawMap LocalRawMap;
386 
387  // Now, loop over hits and add them to the map in the proper sorted order
388  // Note: We are assuming that the hits from the Signal events have been created in
389  // "PreMix" mode, rather than in the standard ADC conversion routines. If not, this
390  // doesn't work at all.
391 
392  // At the moment, both Signal and Reconstituted PU hits have the same compression algorithm.
393  // If this were different, and one needed gains, the conversion back to pulse height can only
394  // be done in this routine. So, yes, there is an extra loop over hits here in the current code,
395  // because, in principle, one could convert to pulse height during the read/store phase.
396 
397  for (SiGlobalIndex::const_iterator IDet = SiHitStorage_.begin(); IDet != SiHitStorage_.end(); IDet++) {
398  uint32_t detID = IDet->first;
399 
400  OneDetectorMap LocalMap = IDet->second;
401 
402  //loop over hit strips for this DetId, do conversion to pulse height, store.
403 
404  LocalRawMap.clear();
405 
406  OneDetectorMap::const_iterator iLocal = LocalMap.begin();
407  for (; iLocal != LocalMap.end(); ++iLocal) {
408  uint16_t currentStrip = iLocal->strip();
409  float signal = float(iLocal->adc());
410  if (iLocal->adc() == 1022)
411  signal = 1500.; // average values for overflows
412  if (iLocal->adc() == 1023)
413  signal = 3000.;
414 
415  //convert signals back to raw counts
416 
417  float ReSignal = signal * signal / 9.0; // The PreMixing conversion is adc = sqrt(9.0*pulseHeight)
418 
419  RawDigi NewRawDigi = std::make_pair(currentStrip, ReSignal);
420 
421  LocalRawMap.push_back(NewRawDigi);
422  }
423 
424  // save information for this detiD into global map
425  SiRawDigis_.insert(SiGlobalRawIndex::value_type(detID, LocalRawMap));
426  }
427 
428  // If we are killing APVs, merge list of dead ones before we digitize
429 
430  int NumberOfBxBetweenHIPandEvent = 1e3;
431 
432  if (APVSaturationFromHIP_) {
433  // calculate affected BX parameter
434 
435  bool HasAtleastOneAffectedAPV = false;
436  while (!HasAtleastOneAffectedAPV) {
437  for (int bx = floor(300.0 / 25.0); bx > 0; bx--) { //Reminder: make these numbers not hard coded!!
438  float temp = CLHEP::RandFlat::shoot(engine) < 0.5 ? 1 : 0;
439  if (temp == 1 && bx < NumberOfBxBetweenHIPandEvent) {
440  NumberOfBxBetweenHIPandEvent = bx;
441  HasAtleastOneAffectedAPV = true;
442  }
443  }
444  }
445 
446  APVMap::const_iterator iAPVchk;
447  uint32_t formerID = 0;
448  uint32_t currentID;
449  std::bitset<6> NewAPVBits;
450 
451  for (APVMap::const_iterator iAPV = theAffectedAPVmap_.begin(); iAPV != theAffectedAPVmap_.end(); ++iAPV) {
452  currentID = iAPV->first;
453 
454  if (currentID == formerID) { // we have to OR these
455  for (int ibit = 0; ibit < 6; ++ibit) {
456  NewAPVBits[ibit] = NewAPVBits[ibit] || (iAPV->second)[ibit];
457  }
458  } else {
459  DeadAPVList[currentID] = NewAPVBits;
460  //save pointers for next iteration
461  formerID = currentID;
462  NewAPVBits = iAPV->second;
463  }
464 
465  iAPVchk = iAPV;
466  if ((++iAPVchk) == theAffectedAPVmap_.end()) { //make sure not to lose the last one
467  DeadAPVList[currentID] = NewAPVBits;
468  }
469  }
470  }
471  //
472 
473  // Ok, done with merging raw signals and APVs - now add signals on duplicate strips
474 
475  // collection of Digis to put in the event
476  std::vector<edm::DetSet<SiStripDigi>> vSiStripDigi;
477 
478  // loop through our collection of detectors, merging hits and making a new list of "signal" digis
479 
480  // clear some temporary storage for later digitization:
481 
482  signals_.clear();
483 
484  // big loop over Detector IDs:
485  for (SiGlobalRawIndex::const_iterator IDet = SiRawDigis_.begin(); IDet != SiRawDigis_.end(); IDet++) {
486  uint32_t detID = IDet->first;
487 
488  SignalMapType Signals;
489  Signals.clear();
490 
491  OneDetectorRawMap LocalMap = IDet->second;
492 
493  //counter variables
494  int formerStrip = -1;
495  int currentStrip;
496  float ADCSum = 0;
497 
498  //loop over hit strips for this DetId, add duplicates
499 
500  OneDetectorRawMap::const_iterator iLocalchk;
501  OneDetectorRawMap::const_iterator iLocal = LocalMap.begin();
502  for (; iLocal != LocalMap.end(); ++iLocal) {
503  currentStrip = iLocal->first; // strip is first element
504 
505  if (currentStrip == formerStrip) { // we have to add these digis together
506 
507  ADCSum += iLocal->second; // raw pulse height is second element.
508  } else {
509  if (formerStrip != -1) {
510  Signals.insert(std::make_pair(formerStrip, ADCSum));
511  }
512  // save pointers for next iteration
513  formerStrip = currentStrip;
514  ADCSum = iLocal->second; // lone ADC
515  }
516 
517  iLocalchk = iLocal;
518  if ((++iLocalchk) == LocalMap.end()) { //make sure not to lose the last one
519  Signals.insert(std::make_pair(formerStrip, ADCSum));
520  }
521  }
522  // save merged map:
523  signals_.insert(std::make_pair(detID, Signals));
524  }
525 
526  //Now, do noise, zero suppression, take into account bad channels, etc.
527  // This section stolen from SiStripDigitizerAlgorithm
528  // must loop over all detIds in the tracker to get all of the noise added properly.
529  for (const auto& iu : pDD->detUnits()) {
530  const StripGeomDetUnit* sgd = dynamic_cast<const StripGeomDetUnit*>(iu);
531  if (sgd != nullptr) {
532  uint32_t detID = sgd->geographicalId().rawId();
533 
534  edm::DetSet<SiStripDigi> SSD(detID); // Make empty collection with this detector ID
535 
536  int numStrips = (sgd->specificTopology()).nstrips();
537 
538  // see if there is some signal on this detector
539 
540  const SignalMapType* theSignal(getSignal(detID));
541 
542  std::vector<float> detAmpl(numStrips, 0.);
543  if (theSignal) {
544  for (const auto& amp : *theSignal) {
545  detAmpl[amp.first] = amp.second;
546  }
547  }
548 
549  //removing signal from the dead (and HIP effected) strips
550  std::vector<bool>& badChannels = allBadChannels[detID];
551 
552  for (int strip = 0; strip < numStrips; ++strip) {
553  if (badChannels[strip])
554  detAmpl[strip] = 0.;
555  }
556 
557  if (simulateAPVInThisEvent) {
558  // Get index in apv baseline distributions corresponding to z of detSet and PU
559  const StripTopology* topol = dynamic_cast<const StripTopology*>(&(sgd->specificTopology()));
560  LocalPoint localPos = topol->localPosition(0);
561  GlobalPoint globalPos = sgd->surface().toGlobal(Local3DPoint(localPos.x(), localPos.y(), localPos.z()));
562  float detSet_z = fabs(globalPos.z());
563  float detSet_r = globalPos.perp();
564 
565  const uint32_t SubDet = DetId(detID).subdetId();
566  // Simulate APV response for each strip
567  for (int strip = 0; strip < numStrips; ++strip) {
568  if (detAmpl[strip] > 0) {
569  // Convert charge from electrons to fC
570  double stripCharge = detAmpl[strip] * apv_fCPerElectron_;
571 
572  // Get APV baseline
573  double baselineV = 0;
574  if (SubDet == StripSubdetector::TIB) {
575  baselineV = apvSimulationParametersHandle->sampleTIB(tTopo->tibLayer(detID), detSet_z, nTruePU, engine);
576  } else if (SubDet == StripSubdetector::TOB) {
577  baselineV = apvSimulationParametersHandle->sampleTOB(tTopo->tobLayer(detID), detSet_z, nTruePU, engine);
578  } else if (SubDet == StripSubdetector::TID) {
579  baselineV = apvSimulationParametersHandle->sampleTID(tTopo->tidWheel(detID), detSet_r, nTruePU, engine);
580  } else if (SubDet == StripSubdetector::TEC) {
581  baselineV = apvSimulationParametersHandle->sampleTEC(tTopo->tecWheel(detID), detSet_r, nTruePU, engine);
582  }
583  // Fitted parameters from G Hall/M Raymond
584  double maxResponse = apv_maxResponse_;
585  double rate = apv_rate_;
586 
587  double outputChargeInADC = 0;
588  if (baselineV < apv_maxResponse_) {
589  // Convert V0 into baseline charge
590  double baselineQ = -1.0 * rate * log(2 * maxResponse / (baselineV + maxResponse) - 1);
591 
592  // Add charge deposited in this BX
593  double newStripCharge = baselineQ + stripCharge;
594 
595  // Apply APV response
596  double signalV = 2 * maxResponse / (1 + exp(-1.0 * newStripCharge / rate)) - maxResponse;
597  double gain = signalV - baselineV;
598 
599  // Convert gain (mV) to charge (assuming linear region of APV) and then to electrons
600  double outputCharge = gain / apv_mVPerQ_;
601  outputChargeInADC = outputCharge / apv_fCPerElectron_;
602  }
603 
604  // Output charge back to original container
605  detAmpl[strip] = outputChargeInADC;
606  }
607  }
608  }
609 
610  if (APVSaturationFromHIP_) {
611  std::bitset<6>& bs = DeadAPVList[detID];
612 
613  if (bs.any()) {
614  // Here below is the scaling function which describes the evolution of the baseline (i.e. how the charge is suppressed).
615  // This must be replaced as soon as we have a proper modeling of the baseline evolution from VR runs
616  float Shift =
617  1 - NumberOfBxBetweenHIPandEvent / floor(300.0 / 25.0); //Reminder: make these numbers not hardcoded!!
618  float randomX = CLHEP::RandFlat::shoot(engine);
619  float scalingValue = (randomX - Shift) * 10.0 / 7.0 - 3.0 / 7.0;
620 
621  for (int strip = 0; strip < numStrips; ++strip) {
622  if (!badChannels[strip] && bs[strip / 128] == 1) {
623  detAmpl[strip] *= scalingValue > 0 ? scalingValue : 0.0;
624  }
625  }
626  }
627  }
628 
629  SiStripNoises::Range detNoiseRange = noiseHandle->getRange(detID);
630  SiStripApvGain::Range detGainRange = gainHandle->getRange(detID);
631 
632  // Gain conversion is already done during signal adding
633  //convert our signals back to raw counts so that we can add noise properly:
634 
635  /*
636  if(theSignal) {
637  for(unsigned int iv = 0; iv!=detAmpl.size(); iv++) {
638  float signal = detAmpl[iv];
639  if(signal > 0) {
640  float gainValue = gainHandle->getStripGain(iv, detGainRange);
641  signal *= theElectronPerADC/gainValue;
642  detAmpl[iv] = signal;
643  }
644  }
645  }
646  */
647 
648  //SiStripPedestals::Range detPedestalRange = pedestalHandle->getRange(detID);
649 
650  // -----------------------------------------------------------
651 
652  size_t firstChannelWithSignal = 0;
653  size_t lastChannelWithSignal = numStrips;
654 
655  if (SingleStripNoise) {
656  std::vector<float> noiseRMSv;
657  noiseRMSv.clear();
658  noiseRMSv.insert(noiseRMSv.begin(), numStrips, 0.);
659  for (int strip = 0; strip < numStrips; ++strip) {
660  if (!badChannels[strip]) {
661  float gainValue = gainHandle->getStripGain(strip, detGainRange);
662  noiseRMSv[strip] = (noiseHandle->getNoise(strip, detNoiseRange)) * theElectronPerADC / gainValue;
663  }
664  }
665  theSiNoiseAdder->addNoiseVR(detAmpl, noiseRMSv, engine);
666  } else {
667  int RefStrip = int(numStrips / 2.);
668  while (RefStrip < numStrips &&
669  badChannels[RefStrip]) { //if the refstrip is bad, I move up to when I don't find it
670  RefStrip++;
671  }
672  if (RefStrip < numStrips) {
673  float RefgainValue = gainHandle->getStripGain(RefStrip, detGainRange);
674  float RefnoiseRMS = noiseHandle->getNoise(RefStrip, detNoiseRange) * theElectronPerADC / RefgainValue;
675 
676  theSiNoiseAdder->addNoise(
677  detAmpl, firstChannelWithSignal, lastChannelWithSignal, numStrips, RefnoiseRMS, engine);
678  }
679  }
680 
681  DigitalVecType digis;
682  theSiZeroSuppress->suppress(
683  theSiDigitalConverter->convert(detAmpl, gainHandle, detID), digis, detID, noiseHandle, thresholdHandle);
684 
685  SSD.data = digis;
686 
687  // stick this into the global vector of detector info
688  vSiStripDigi.push_back(SSD);
689 
690  } // end of loop over one detector
691 
692  } // end of big loop over all detector IDs
693 
694  // put the collection of digis in the event
695  edm::LogInfo("PreMixingSiStripWorker") << "total # Merged strips: " << vSiStripDigi.size();
696 
697  // make new digi collection
698 
699  std::unique_ptr<edm::DetSetVector<SiStripDigi>> MySiStripDigis(new edm::DetSetVector<SiStripDigi>(vSiStripDigi));
700 
701  // put collection
702 
703  e.put(std::move(MySiStripDigis), SiStripDigiCollectionDM_);
704  e.put(std::make_unique<bool>(simulateAPVInThisEvent), SiStripDigiCollectionDM_ + "SimulatedAPVDynamicGain");
705 
706  // clear local storage for this event
707  SiHitStorage_.clear();
708  SiRawDigis_.clear();
709  signals_.clear();
710 }
711 
#define LogDebug(id)
unsigned short range
BranchAliasSetterT< ProductType > produces()
declare what type of product will make and with which optional label
GlobalPoint toGlobal(const Point2DBase< Scalar, LocalTag > lp) const
Definition: Surface.h:106
std::map< unsigned int, std::vector< bool > > allBadChannels
T getParameter(std::string const &) const
void addSignals(edm::Event const &e, edm::EventSetup const &es) override
std::vector< SiStripDigi > DigitalVecType
std::map< unsigned int, std::vector< bool > > allHIPChannels
PreMixingSiStripWorker(const edm::ParameterSet &ps, edm::ProducerBase &producer, edm::ConsumesCollector &&iC)
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:125
float sampleTIB(layerid layer, float z, float pu, CLHEP::HepRandomEngine *engine) const
T perp() const
Definition: PV3DBase.h:72
unsigned int tibLayer(const DetId &id) const
std::unique_ptr< SiTrivialDigitalConverter > theSiDigitalConverter
const DetContainer & detUnits() const override
Returm a vector of all GeomDet.
std::map< unsigned int, size_t > lastChannelsWithSignal
void reserve(size_t s)
Definition: DetSetVector.h:150
std::map< uint32_t, OneDetectorRawMap > SiGlobalRawIndex
std::vector< unsigned int >::const_iterator ContainerIterator
float sampleTID(layerid wheel, float r, float pu, CLHEP::HepRandomEngine *engine) const
edm::ESHandle< TrackerGeometry > pDD
std::map< uint32_t, OneDetectorMap > SiGlobalIndex
EventID const & id() const
constexpr uint32_t rawId() const
get the raw id
Definition: DetId.h:50
T y() const
Definition: PV3DBase.h:63
void DMinitializeDetUnit(StripGeomDetUnit const *det, const edm::EventSetup &iSetup)
unsigned int tidWheel(const DetId &id) const
const int getBunchCrossing() const
virtual const StripTopology & specificTopology() const
Returns a reference to the strip proxy topology.
virtual CLHEP::HepRandomEngine & getEngine(StreamID const &)=0
Use this engine in event methods.
std::multimap< uint32_t, std::bitset< 6 > > APVMap
const Plane & surface() const
The nominal surface of the GeomDet.
Definition: GeomDet.h:42
float sampleTOB(layerid layer, float z, float pu, CLHEP::HepRandomEngine *engine) const
static std::string const input
Definition: EdmProvDump.cc:48
edm::EventPrincipal const & principal()
static float getNoise(uint16_t strip, const Range &range)
Definition: SiStripNoises.h:74
virtual LocalPoint localPosition(float strip) const =0
static float getStripGain(const uint16_t &strip, const SiStripApvGain::Range &range)
Definition: SiStripGain.h:73
std::vector< SiStripDigi > OneDetectorMap
const uint16_t & strip() const
Definition: SiStripDigi.h:33
const SignalMapType * getSignal(uint32_t detID) const
T z() const
Definition: PV3DBase.h:64
std::unique_ptr< SiGaussianTailNoiseAdder > theSiNoiseAdder
bool isAvailable() const
Definition: Service.h:40
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
~PreMixingSiStripWorker() override=default
#define end
Definition: vmac.h:39
A Digi for the silicon strip detector, containing both strip and adc information, and suitable for st...
Definition: SiStripDigi.h:12
bool isValid() const
Definition: HandleBase.h:74
std::unique_ptr< SiStripFedZeroSuppression > theSiZeroSuppress
bool getByLabel(InputTag const &tag, Handle< PROD > &result) const
Definition: Event.h:480
void put(edm::Event &e, edm::EventSetup const &iSetup, std::vector< PileupSummaryInfo > const &ps, int bs) override
Point3DBase< float, LocalTag > Local3DPoint
Definition: LocalPoint.h:9
Definition: DetId.h:18
bool operator()(SiStripDigi i, SiStripDigi j) const
void initializeEvent(edm::Event const &e, edm::EventSetup const &c) override
unsigned short firstStrip
std::pair< uint16_t, Amplitude > RawDigi
double rate(double x)
Definition: Constants.cc:3
collection_type data
Definition: DetSet.h:80
#define begin
Definition: vmac.h:32
const Range getRange(const uint32_t detID) const
const Range getRange(const uint32_t detID) const
std::pair< ContainerIterator, ContainerIterator > Range
bool getByLabel(edm::InputTag const &tag, edm::Handle< T > &result) const
T get() const
Definition: EventSetup.h:71
std::map< unsigned int, size_t > firstChannelsWithSignal
StreamID streamID() const
Definition: Event.h:95
void addPileups(PileUpEventPrincipal const &pep, edm::EventSetup const &es) override
std::vector< RawDigi > OneDetectorRawMap
std::pair< ContainerIterator, ContainerIterator > Range
Definition: SiStripNoises.h:50
collection_type::const_iterator const_iterator
Definition: DetSetVector.h:104
T x() const
Definition: PV3DBase.h:62
unsigned int tecWheel(const DetId &id) const
#define DEFINE_PREMIXING_WORKER(TYPE)
float sampleTEC(layerid wheel, float r, float pu, CLHEP::HepRandomEngine *engine) const
std::map< uint32_t, SignalMapType > signalMaps
def move(src, dest)
Definition: eostools.py:511
std::map< int, Amplitude > SignalMapType
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
SiDigitalConverter::DigitalVecType DigitalVecType