CMS 3D CMS Logo

DataMixingSiPixelMCDigiWorker.cc
Go to the documentation of this file.
1 // File: DataMixingSiPixelWorker.cc
2 // Description: see DataMixingSiPixelMCDigiWorker.h
3 // Author: Mike Hildreth, University of Notre Dame
4 //
5 //--------------------------------------------
6 
7 #include <map>
8 #include <memory>
16 //
17 //
18 
26 
27 #include "CLHEP/Random/RandFlat.h"
28 
30 
31 
32 using namespace std;
33 
34 namespace edm
35 {
36 
37  // Virtual constructor
38 
39  // DataMixingSiPixelMCDigiWorker::DataMixingSiPixelMCDigiWorker() { }
40 
41  // Constructor
42  DataMixingSiPixelMCDigiWorker::DataMixingSiPixelMCDigiWorker(const edm::ParameterSet& ps, edm::ConsumesCollector && iC) :
43  label_(ps.getParameter<std::string>("Label")),
44  geometryType_(ps.getParameter<std::string>("GeometryType")),
45  // get external parameters:
46  // To account for upgrade geometries do not assume the number
47  // of layers or disks.
48  NumberOfBarrelLayers(ps.exists("NumPixelBarrel")?ps.getParameter<int>("NumPixelBarrel"):3),
49  NumberOfEndcapDisks(ps.exists("NumPixelEndcap")?ps.getParameter<int>("NumPixelEndcap"):2),
50  //theInstLumiScaleFactor(ps.getParameter<double>("theInstLumiScaleFactor")), //For dynamic inefficiency PU scaling
51  //bunchScaleAt25(ps.getParameter<double>("bunchScaleAt25")), //For dynamic inefficiency bunchspace scaling
52  // Control the pixel inefficiency
53  AddPixelInefficiency(ps.getParameter<bool>("AddPixelInefficiency")),
54  pixelEff_(ps, AddPixelInefficiency,NumberOfBarrelLayers,NumberOfEndcapDisks)
55  {
56 
57  // get the subdetector names
58  // this->getSubdetectorNames(); //something like this may be useful to check what we are supposed to do...
59 
60  // declare the products to produce
61 
62  pixeldigi_collectionSig_ = ps.getParameter<edm::InputTag>("pixeldigiCollectionSig");
63  pixeldigi_collectionPile_ = ps.getParameter<edm::InputTag>("pixeldigiCollectionPile");
64  PixelDigiCollectionDM_ = ps.getParameter<std::string>("PixelDigiCollectionDM");
65 
68 
69  // clear local storage for this event
70  SiHitStorage_.clear();
71 
72  FirstCall_ = true;
73 
74  }
75 
76 
77  // Virtual destructor needed.
79  }
80 
81  // Need an event initialization
82 
84 
86  //edm::ESHandle<TrackerTopology> tTopoHand;
87  //iSetup.get<IdealGeometryRecord>().get(tTopoHand);
88  //const TrackerTopology *tTopo=tTopoHand.product();
89  }
90 
91 
93  // pixel inefficiency
94  // Don't use Hard coded values, read inefficiencies in from DB/python config or don't use any
95  int NumberOfTotLayers = NumberOfBarrelLayers + NumberOfEndcapDisks;
96  FPixIndex=NumberOfBarrelLayers;
97  if (AddPixelInefficiency){
98  FromConfig =
99  conf.exists("thePixelColEfficiency_BPix1") && conf.exists("thePixelColEfficiency_BPix2") && conf.exists("thePixelColEfficiency_BPix3") &&
100  conf.exists("thePixelColEfficiency_FPix1") && conf.exists("thePixelColEfficiency_FPix2") &&
101  conf.exists("thePixelEfficiency_BPix1") && conf.exists("thePixelEfficiency_BPix2") && conf.exists("thePixelEfficiency_BPix3") &&
102  conf.exists("thePixelEfficiency_FPix1") && conf.exists("thePixelEfficiency_FPix2") &&
103  conf.exists("thePixelChipEfficiency_BPix1") && conf.exists("thePixelChipEfficiency_BPix2") && conf.exists("thePixelChipEfficiency_BPix3") &&
104  conf.exists("thePixelChipEfficiency_FPix1") && conf.exists("thePixelChipEfficiency_FPix2");
105  if (NumberOfBarrelLayers==3) FromConfig = FromConfig && conf.exists("theLadderEfficiency_BPix1") && conf.exists("theLadderEfficiency_BPix2") && conf.exists("theLadderEfficiency_BPix3") &&
106  conf.exists("theModuleEfficiency_BPix1") && conf.exists("theModuleEfficiency_BPix2") && conf.exists("theModuleEfficiency_BPix3") &&
107  conf.exists("thePUEfficiency_BPix1") && conf.exists("thePUEfficiency_BPix2") && conf.exists("thePUEfficiency_BPix3") &&
108  conf.exists("theInnerEfficiency_FPix1") && conf.exists("theInnerEfficiency_FPix2") &&
109  conf.exists("theOuterEfficiency_FPix1") && conf.exists("theOuterEfficiency_FPix2") &&
110  conf.exists("thePUEfficiency_FPix_Inner") && conf.exists("thePUEfficiency_FPix_Outer") &&
111  conf.exists("theInstLumiScaleFactor");
112  if (NumberOfBarrelLayers>=4) FromConfig = FromConfig && conf.exists("thePixelColEfficiency_BPix4") &&
113  conf.exists("thePixelEfficiency_BPix4") && conf.exists("thePixelChipEfficiency_BPix4");
114  if (NumberOfEndcapDisks>=3) FromConfig = FromConfig && conf.exists("thePixelColEfficiency_FPix4") &&
115  conf.exists("thePixelEfficiency_FPix3") && conf.exists("thePixelChipEfficiency_FPix3");
116  if (FromConfig) {
117  LogInfo ("PixelDigitizer ") <<"The PixelDigitizer inefficiency configuration is read from the config file.\n";
118  theInstLumiScaleFactor = conf.getParameter<double>("theInstLumiScaleFactor");
119  int i=0;
120  thePixelColEfficiency[i++] = conf.getParameter<double>("thePixelColEfficiency_BPix1");
121  thePixelColEfficiency[i++] = conf.getParameter<double>("thePixelColEfficiency_BPix2");
122  thePixelColEfficiency[i++] = conf.getParameter<double>("thePixelColEfficiency_BPix3");
123  if (NumberOfBarrelLayers>=4){thePixelColEfficiency[i++] = conf.getParameter<double>("thePixelColEfficiency_BPix4");}
124  //
125  i=0;
126  thePixelEfficiency[i++] = conf.getParameter<double>("thePixelEfficiency_BPix1");
127  thePixelEfficiency[i++] = conf.getParameter<double>("thePixelEfficiency_BPix2");
128  thePixelEfficiency[i++] = conf.getParameter<double>("thePixelEfficiency_BPix3");
129  if (NumberOfBarrelLayers>=4){thePixelEfficiency[i++] = conf.getParameter<double>("thePixelEfficiency_BPix4");}
130  //
131  i=0;
132  thePixelChipEfficiency[i++] = conf.getParameter<double>("thePixelChipEfficiency_BPix1");
133  thePixelChipEfficiency[i++] = conf.getParameter<double>("thePixelChipEfficiency_BPix2");
134  thePixelChipEfficiency[i++] = conf.getParameter<double>("thePixelChipEfficiency_BPix3");
135  if (NumberOfBarrelLayers>=4){thePixelChipEfficiency[i++] = conf.getParameter<double>("thePixelChipEfficiency_BPix4");}
136  //
137  if (NumberOfBarrelLayers==3){
138  i=0;
139  theLadderEfficiency_BPix[i++] = conf.getParameter<std::vector<double> >("theLadderEfficiency_BPix1");
140  theLadderEfficiency_BPix[i++] = conf.getParameter<std::vector<double> >("theLadderEfficiency_BPix2");
141  theLadderEfficiency_BPix[i++] = conf.getParameter<std::vector<double> >("theLadderEfficiency_BPix3");
142  if ( ((theLadderEfficiency_BPix[0].size()!=20) || (theLadderEfficiency_BPix[1].size()!=32) ||
143  (theLadderEfficiency_BPix[2].size()!=44)) && (NumberOfBarrelLayers==3) )
144  throw cms::Exception("Configuration") << "Wrong ladder number in efficiency config!";
145  //
146  i=0;
147  theModuleEfficiency_BPix[i++] = conf.getParameter<std::vector<double> >("theModuleEfficiency_BPix1");
148  theModuleEfficiency_BPix[i++] = conf.getParameter<std::vector<double> >("theModuleEfficiency_BPix2");
149  theModuleEfficiency_BPix[i++] = conf.getParameter<std::vector<double> >("theModuleEfficiency_BPix3");
150  if ( ((theModuleEfficiency_BPix[0].size()!=4) || (theModuleEfficiency_BPix[1].size()!=4) ||
151  (theModuleEfficiency_BPix[2].size()!=4)) && (NumberOfBarrelLayers==3) )
152  throw cms::Exception("Configuration") << "Wrong module number in efficiency config!";
153  //
154  thePUEfficiency.push_back(conf.getParameter<std::vector<double> >("thePUEfficiency_BPix1"));
155  thePUEfficiency.push_back(conf.getParameter<std::vector<double> >("thePUEfficiency_BPix2"));
156  thePUEfficiency.push_back(conf.getParameter<std::vector<double> >("thePUEfficiency_BPix3"));
157  if ( ((thePUEfficiency[0].empty()) || (thePUEfficiency[1].empty()) ||
158  (thePUEfficiency[2].empty())) && (NumberOfBarrelLayers==3) )
159  throw cms::Exception("Configuration") << "At least one PU efficiency (BPix) number is needed in efficiency config!";
160  }
161  // The next is needed for Phase2 Tracker studies
162  if (NumberOfBarrelLayers>=5){
163  if (NumberOfTotLayers>20){throw cms::Exception("Configuration") <<"SiPixelDigitizer was given more layers than it can handle";}
164  // For Phase2 tracker layers just set the outermost BPix inefficiency to 99.9% THESE VALUES ARE HARDCODED ALSO ELSEWHERE IN THIS FILE
165  for (int j=5 ; j<=NumberOfBarrelLayers ; j++){
166  thePixelColEfficiency[j-1]=0.999;
167  thePixelEfficiency[j-1]=0.999;
168  thePixelChipEfficiency[j-1]=0.999;
169  }
170  }
171  //
172  i=FPixIndex;
173  thePixelColEfficiency[i++] = conf.getParameter<double>("thePixelColEfficiency_FPix1");
174  thePixelColEfficiency[i++] = conf.getParameter<double>("thePixelColEfficiency_FPix2");
175  if (NumberOfEndcapDisks>=3){thePixelColEfficiency[i++] = conf.getParameter<double>("thePixelColEfficiency_FPix3");}
176  i=FPixIndex;
177  thePixelEfficiency[i++] = conf.getParameter<double>("thePixelEfficiency_FPix1");
178  thePixelEfficiency[i++] = conf.getParameter<double>("thePixelEfficiency_FPix2");
179  if (NumberOfEndcapDisks>=3){thePixelEfficiency[i++] = conf.getParameter<double>("thePixelEfficiency_FPix3");}
180  i=FPixIndex;
181  thePixelChipEfficiency[i++] = conf.getParameter<double>("thePixelChipEfficiency_FPix1");
182  thePixelChipEfficiency[i++] = conf.getParameter<double>("thePixelChipEfficiency_FPix2");
183  if (NumberOfEndcapDisks>=3){thePixelChipEfficiency[i++] = conf.getParameter<double>("thePixelChipEfficiency_FPix3");}
184  // The next is needed for Phase2 Tracker studies
185  if (NumberOfEndcapDisks>=4){
186  if (NumberOfTotLayers>20){throw cms::Exception("Configuration") <<"SiPixelDigitizer was given more layers than it can handle";}
187  // For Phase2 tracker layers just set the extra FPix disk inefficiency to 99.9% THESE VALUES ARE HARDCODED ALSO ELSEWHERE IN THIS FILE
188  for (int j=4+FPixIndex ; j<=NumberOfEndcapDisks+NumberOfBarrelLayers ; j++){
189  thePixelColEfficiency[j-1]=0.999;
190  thePixelEfficiency[j-1]=0.999;
191  thePixelChipEfficiency[j-1]=0.999;
192  }
193  }
194  //FPix Dynamic Inefficiency
195  if (NumberOfBarrelLayers==3){
196  i=FPixIndex;
197  theInnerEfficiency_FPix[i++] = conf.getParameter<double>("theInnerEfficiency_FPix1");
198  theInnerEfficiency_FPix[i++] = conf.getParameter<double>("theInnerEfficiency_FPix2");
199  i=FPixIndex;
200  theOuterEfficiency_FPix[i++] = conf.getParameter<double>("theOuterEfficiency_FPix1");
201  theOuterEfficiency_FPix[i++] = conf.getParameter<double>("theOuterEfficiency_FPix2");
202  thePUEfficiency.push_back(conf.getParameter<std::vector<double> >("thePUEfficiency_FPix_Inner"));
203  thePUEfficiency.push_back(conf.getParameter<std::vector<double> >("thePUEfficiency_FPix_Outer"));
204  if ( ((thePUEfficiency[3].empty()) || (thePUEfficiency[4].empty())) && (NumberOfEndcapDisks==2) )
205  throw cms::Exception("Configuration") << "At least one (FPix) PU efficiency number is needed in efficiency config!";
206  pu_scale.resize(thePUEfficiency.size());
207  }
208  }
209  else LogInfo ("PixelDigitizer ") <<"The PixelDigitizer inefficiency configuration is read from the database.\n";
210 
211  }
212  // the first "NumberOfBarrelLayers" settings [0],[1], ... , [NumberOfBarrelLayers-1] are for the barrel pixels
213  // the next "NumberOfEndcapDisks" settings [NumberOfBarrelLayers],[NumberOfBarrelLayers+1], ... [NumberOfEndcapDisks+NumberOfBarrelLayers-1]
214 }
215 
216 // Read DynIneff Scale factors from DB
219  if (bunchspace == 50) es.get<SiPixelDynamicInefficiencyRcd>().get("50ns",SiPixelDynamicInefficiency_);
222  }
223 }
224 
226 
227  theInstLumiScaleFactor = SiPixelDynamicInefficiency->gettheInstLumiScaleFactor();
228  const std::map<uint32_t, double>& PixelGeomFactorsDB = SiPixelDynamicInefficiency->getPixelGeomFactors();
229  const std::map<uint32_t, double>& ColGeomFactorsDB = SiPixelDynamicInefficiency->getColGeomFactors();
230  const std::map<uint32_t, double>& ChipGeomFactorsDB = SiPixelDynamicInefficiency->getChipGeomFactors();
231  const std::map<uint32_t, std::vector<double> >& PUFactors = SiPixelDynamicInefficiency->getPUFactors();
232  std::vector<uint32_t > DetIdmasks = SiPixelDynamicInefficiency->getDetIdmasks();
233 
234  // Loop on all modules, calculate geometrical scale factors and store in map for easy access
235  for( const auto& it_module : geom->detUnits()) {
236  if( dynamic_cast<PixelGeomDetUnit const*>(it_module)==nullptr) continue;
237  const DetId detid = it_module->geographicalId();
238  uint32_t rawid = detid.rawId();
239  PixelGeomFactors[rawid] = 1;
240  ColGeomFactors[rawid] = 1;
241  ChipGeomFactors[rawid] = 1;
242  for (auto db_factor : PixelGeomFactorsDB) if (matches(detid, DetId(db_factor.first), DetIdmasks)) PixelGeomFactors[rawid] *= db_factor.second;
243  for (auto db_factor : ColGeomFactorsDB) if (matches(detid, DetId(db_factor.first), DetIdmasks)) ColGeomFactors[rawid] *= db_factor.second;
244  for (auto db_factor : ChipGeomFactorsDB) if (matches(detid, DetId(db_factor.first), DetIdmasks)) ChipGeomFactors[rawid] *= db_factor.second;
245  }
246 
247  // piluep scale factors are calculated once per event
248  // therefore vector index is stored in a map for each module that matches to a db_id
249  size_t i=0;
250  for (auto factor : PUFactors) {
251  const DetId db_id = DetId(factor.first);
252  for( const auto& it_module : geom->detUnits()) {
253  if( dynamic_cast<PixelGeomDetUnit const*>(it_module)==nullptr) continue;
254  const DetId detid = it_module->geographicalId();
255  if (!matches(detid, db_id, DetIdmasks)) continue;
256  if (iPU.count(detid.rawId())) {
257  throw cms::Exception("Database")<<"Multiple db_ids match to same module in SiPixelDynamicInefficiency DB Object";
258  } else {
259  iPU[detid.rawId()] = i;
260  }
261  }
262  thePUEfficiency.push_back(factor.second);
263  ++i;
264  }
265  pu_scale.resize(thePUEfficiency.size());
266 }
267 
268 bool DataMixingSiPixelMCDigiWorker::PixelEfficiencies::matches(const DetId& detid, const DetId& db_id, const std::vector<uint32_t >& DetIdmasks) {
269  if (detid.subdetId() != db_id.subdetId()) return false;
270  for (size_t i=0; i<DetIdmasks.size(); ++i) {
271  DetId maskid = DetId(DetIdmasks.at(i));
272  if (maskid.subdetId() != db_id.subdetId()) continue;
273  if ((detid.rawId()&maskid.rawId()) != (db_id.rawId()&maskid.rawId()) &&
274  (db_id.rawId()&maskid.rawId()) != DetId(db_id.det(), db_id.subdetId()).rawId()) return false;
275  }
276  return true;
277 }
278 
279 
280 
281 
283  // fill in maps of hits
284 
285  LogDebug("DataMixingSiPixelMCDigiWorker")<<"===============> adding MC signals for "<<e.id();
286 
288 
289  if( e.getByToken(PixelDigiToken_,input) ) {
290 
291  //loop on all detsets (detectorIDs) inside the input collection
292  edm::DetSetVector<PixelDigi>::const_iterator DSViter=input->begin();
293  for (; DSViter!=input->end();DSViter++){
294 
295 #ifdef DEBUG
296  LogDebug("DataMixingSiPixelMCDigiWorker") << "Processing DetID " << DSViter->id;
297 #endif
298 
299  uint32_t detID = DSViter->id;
303 
304  OneDetectorMap LocalMap;
305 
306  for (icopy=begin; icopy!=end; icopy++) {
307  LocalMap.insert(OneDetectorMap::value_type( (icopy->channel()), *icopy ));
308  }
309 
310  SiHitStorage_.insert( SiGlobalIndex::value_type( detID, LocalMap ) );
311  }
312 
313  }
314  } // end of addSiPixelSignals
315 
316 
317 
318  void DataMixingSiPixelMCDigiWorker::addSiPixelPileups(const int bcr, const EventPrincipal *ep, unsigned int eventNr,
319  ModuleCallingContext const* mcc) {
320 
321  LogDebug("DataMixingSiPixelMCDigiWorker") <<"\n===============> adding pileups from event "<<ep->id()<<" for bunchcrossing "<<bcr;
322 
323  // fill in maps of hits; same code as addSignals, except now applied to the pileup events
324 
325  std::shared_ptr<Wrapper<edm::DetSetVector<PixelDigi> > const> inputPTR =
326  getProductByTag<edm::DetSetVector<PixelDigi> >(*ep, pixeldigi_collectionPile_, mcc);
327 
328  if(inputPTR ) {
329 
330  const edm::DetSetVector<PixelDigi> *input = const_cast< edm::DetSetVector<PixelDigi> * >(inputPTR->product());
331 
332 
333 
334  // Handle< edm::DetSetVector<PixelDigi> > input;
335 
336  // if( e->getByLabel(pixeldigi_collectionPile_,input) ) {
337 
338  //loop on all detsets (detectorIDs) inside the input collection
340  for (; DSViter!=input->end();DSViter++){
341 
342 #ifdef DEBUG
343  LogDebug("DataMixingSiPixelMCDigiWorker") << "Pileups: Processing DetID " << DSViter->id;
344 #endif
345 
346  uint32_t detID = DSViter->id;
350 
351  // find correct local map (or new one) for this detector ID
352 
353  SiGlobalIndex::const_iterator itest;
354 
355  itest = SiHitStorage_.find(detID);
356 
357  if(itest!=SiHitStorage_.end()) { // this detID already has hits, add to existing map
358 
359  OneDetectorMap LocalMap = itest->second;
360 
361  // fill in local map with extra channels
362  for (icopy=begin; icopy!=end; icopy++) {
363  LocalMap.insert(OneDetectorMap::value_type( (icopy->channel()), *icopy ));
364  }
365 
366  SiHitStorage_[detID]=LocalMap;
367 
368  }
369  else{ // fill local storage with this information, put in global collection
370 
371  OneDetectorMap LocalMap;
372 
373  for (icopy=begin; icopy!=end; icopy++) {
374  LocalMap.insert(OneDetectorMap::value_type( (icopy->channel()), *icopy ));
375  }
376 
377  SiHitStorage_.insert( SiGlobalIndex::value_type( detID, LocalMap ) );
378  }
379 
380  }
381  }
382  }
383 
384 
385 
386  void DataMixingSiPixelMCDigiWorker::putSiPixel(edm::Event &e, edm::EventSetup const& iSetup, std::vector<PileupSummaryInfo> &ps, int &bs) {
387 
388  // collection of Digis to put in the event
389 
390  std::vector< edm::DetSet<PixelDigi> > vPixelDigi;
391 
392  // loop through our collection of detectors, merging hits and putting new ones in the output
393 
394  _signal.clear();
395 
396  // big loop over Detector IDs:
397 
398  for(SiGlobalIndex::const_iterator IDet = SiHitStorage_.begin();
399  IDet != SiHitStorage_.end(); IDet++) {
400 
401  uint32_t detID = IDet->first;
402 
403  OneDetectorMap LocalMap = IDet->second;
404 
405  signal_map_type Signals;
406  Signals.clear();
407 
408  //counter variables
409  int formerPixel = -1;
410  int currentPixel;
411  int ADCSum = 0;
412 
413 
414  OneDetectorMap::const_iterator iLocalchk;
415 
416  for(OneDetectorMap::const_iterator iLocal = LocalMap.begin();
417  iLocal != LocalMap.end(); ++iLocal) {
418 
419  currentPixel = iLocal->first;
420 
421  if (currentPixel == formerPixel) { // we have to add these digis together
422  ADCSum+=(iLocal->second).adc();
423  }
424  else{
425  if(formerPixel!=-1){ // ADC info stolen from SiStrips...
426  if (ADCSum > 511) ADCSum = 255;
427  else if (ADCSum > 253 && ADCSum < 512) ADCSum = 254;
428 
429  Signals.insert( std::make_pair(formerPixel, ADCSum));
430  //PixelDigi aHit(formerPixel, ADCSum);
431  //SPD.push_back( aHit );
432  }
433  // save pointers for next iteration
434  formerPixel = currentPixel;
435  ADCSum = (iLocal->second).adc();
436  }
437 
438  iLocalchk = iLocal;
439  if((++iLocalchk) == LocalMap.end()) { //make sure not to lose the last one
440  if (ADCSum > 511) ADCSum = 255;
441  else if (ADCSum > 253 && ADCSum < 512) ADCSum = 254;
442  Signals.insert( std::make_pair(formerPixel, ADCSum));
443  //SPD.push_back( PixelDigi(formerPixel, ADCSum) );
444  }
445 
446  }// end of loop over one detector
447 
448  // stick this into the global vector of detector info
449  _signal.insert( std::make_pair( detID, Signals));
450 
451  } // end of big loop over all detector IDs
452 
453  // put the collection of digis in the event
454  LogInfo("DataMixingSiPixelMCDigiWorker") << "total # Merged Pixels: " << _signal.size() ;
455 
456  // Now, we have to run Lumi-Dependent efficiency calculation on the merged pixels.
457  // This is the only place where we have the PreMixed pileup information so that we can calculate
458  // the instantaneous luminosity and do the dynamic inefficiency.
459 
461  CLHEP::HepRandomEngine* engine = &rng->getEngine(e.streamID());
462 
464  iSetup.get<TrackerTopologyRcd>().get(tTopoHand);
465  const TrackerTopology *tTopo=tTopoHand.product();
466 
467  // Load inefficiency constants (1st pass), set pileup information.
468 
469  if(FirstCall_) {
470  init_DynIneffDB(iSetup, bs);
471  FirstCall_ = false;
472  }
473 
474  setPileupInfo(ps, bs);
475 
476  for( const auto& iu : pDD->detUnits()) {
477 
478  if(iu->type().isTrackerPixel()) {
479 
480  //
481  const PixelGeomDetUnit* pixdet = dynamic_cast<const PixelGeomDetUnit*>(iu);
482  uint32_t detID = pixdet->geographicalId().rawId();
483 
484  // fetch merged hits for this detID
485 
486  signal_map_type& theSignal = _signal[detID];
487 
488  // if we have some hits...
489  if(!theSignal.empty()) {
490 
491  edm::DetSet<PixelDigi> SPD(detID); // make empty vector with this detID so we can push back digis at the end
492 
493  const PixelTopology* topol=&pixdet->specificTopology();
494  int numColumns = topol->ncolumns(); // det module number of cols&rows
495  int numRows = topol->nrows();
496 
497  // do inefficiency calculation, drop some pixel hits
498 
499  // Predefined efficiencies
500  double pixelEfficiency = 1.0;
501  double columnEfficiency = 1.0;
502  double chipEfficiency = 1.0;
503 
504  if (pixelEff_.FromConfig) {
505  // setup the chip indices conversion
508  pixdet->subDetector()==GeomDetEnumerators::SubDetector::P2PXB){// barrel layers
509  int layerIndex=tTopo->layer(detID);
510  pixelEfficiency = pixelEff_.thePixelEfficiency[layerIndex-1];
511  columnEfficiency = pixelEff_.thePixelColEfficiency[layerIndex-1];
512  chipEfficiency = pixelEff_.thePixelChipEfficiency[layerIndex-1];
513  //std::cout <<"Using BPix columnEfficiency = "<<columnEfficiency<< " for layer = "<<layerIndex <<"\n";
514  // This should never happen, but only check if it is not an upgrade geometry
515  if (NumberOfBarrelLayers==3){
516  if(numColumns>416) LogWarning ("Pixel Geometry") <<" wrong columns in barrel "<<numColumns;
517  if(numRows>160) LogWarning ("Pixel Geometry") <<" wrong rows in barrel "<<numRows;
518 
519  int ladder=tTopo->pxbLadder(detID);
520  int module=tTopo->pxbModule(detID);
521  if (module<=4) module=5-module;
522  else module-=4;
523 
524  columnEfficiency *= pixelEff_.theLadderEfficiency_BPix[layerIndex-1][ladder-1]*pixelEff_.theModuleEfficiency_BPix[layerIndex-1][module-1]*pixelEff_.pu_scale[layerIndex-1];
525  }
528  pixdet->subDetector()==GeomDetEnumerators::SubDetector::P2PXEC){ // forward disks
529 
530  unsigned int diskIndex=tTopo->layer(detID)+pixelEff_.FPixIndex; // Use diskIndex-1 later to stay consistent with BPix
531  unsigned int panelIndex=tTopo->pxfPanel(detID);
532  unsigned int moduleIndex=tTopo->pxfModule(detID);
533  //if (pixelEff_.FPixIndex>diskIndex-1){throw cms::Exception("Configuration") <<"SiPixelDigitizer is using the wrong efficiency value. index = "
534  // <<diskIndex-1<<" , MinIndex = "<<pixelEff_.FPixIndex<<" ... "<<tTopo->pxfDisk(detID);}
535  pixelEfficiency = pixelEff_.thePixelEfficiency[diskIndex-1];
536  columnEfficiency = pixelEff_.thePixelColEfficiency[diskIndex-1];
537  chipEfficiency = pixelEff_.thePixelChipEfficiency[diskIndex-1];
538  //std::cout <<"Using FPix columnEfficiency = "<<columnEfficiency<<" for Disk = "<< tTopo->pxfDisk(detID)<<"\n";
539  // Sometimes the forward pixels have wrong size,
540  // this crashes the index conversion, so exit, but only check if it is not an upgrade geometry
541  if (NumberOfBarrelLayers==3){ // whether it is the present or the phase 1 detector can be checked using GeomDetEnumerators::SubDetector
542  if(numColumns>260 || numRows>160) {
543  if(numColumns>260) LogWarning ("Pixel Geometry") <<" wrong columns in endcaps "<<numColumns;
544  if(numRows>160) LogWarning ("Pixel Geometry") <<" wrong rows in endcaps "<<numRows;
545  return;
546  }
547  if ((panelIndex==1 && (moduleIndex==1 || moduleIndex==2)) || (panelIndex==2 && moduleIndex==1)) { //inner modules
548  columnEfficiency*=pixelEff_.theInnerEfficiency_FPix[diskIndex-1]*pixelEff_.pu_scale[3];
549  } else { //outer modules
550  columnEfficiency*=pixelEff_.theOuterEfficiency_FPix[diskIndex-1]*pixelEff_.pu_scale[4];
551  }
552  } // current detector, forward
554  // If phase 2 outer tracker, hardcoded values as they have been so far
555  pixelEfficiency = 0.999;
556  columnEfficiency = 0.999;
557  chipEfficiency = 0.999;
558  } // if barrel/forward
559  } else { // Load precomputed factors from Database
560  pixelEfficiency = pixelEff_.PixelGeomFactors.at(detID);
561  columnEfficiency = pixelEff_.ColGeomFactors.at(detID)*pixelEff_.pu_scale[pixelEff_.iPU.at(detID)];
562  chipEfficiency = pixelEff_.ChipGeomFactors.at(detID);
563  }
564 
565 #ifdef TP_DEBUG
566  LogDebug ("Pixel Digitizer") << " enter pixel_inefficiency " << pixelEfficiency << " "
567  << columnEfficiency << " " << chipEfficiency;
568 #endif
569 
570  // Initilize the index converter
571  //PixelIndices indexConverter(numColumns,numRows);
572  std::unique_ptr<PixelIndices> pIndexConverter(new PixelIndices(numColumns,numRows));
573 
574 
575  int chipIndex = 0;
576  int rowROC = 0;
577  int colROC = 0;
578  std::map<int, int, std::less<int> >chips, columns;
579  std::map<int, int, std::less<int> >::iterator iter;
580 
581  // Find out the number of columns and rocs hits
582  // Loop over hit pixels, amplitude in electrons, channel = coded row,col
583  for (signal_map_const_iterator i = theSignal.begin(); i != theSignal.end(); ++i) {
584 
585  int chan = i->first;
586  std::pair<int,int> ip = PixelDigi::channelToPixel(chan);
587  int row = ip.first; // X in row
588  int col = ip.second; // Y is in col
589  //transform to ROC index coordinates
590  pIndexConverter->transformToROC(col,row,chipIndex,colROC,rowROC);
591  int dColInChip = pIndexConverter->DColumn(colROC); // get ROC dcol from ROC col
592  //dcol in mod
593  int dColInDet = pIndexConverter->DColumnInModule(dColInChip,chipIndex);
594 
595  chips[chipIndex]++;
596  columns[dColInDet]++;
597  }
598 
599  // Delete some ROC hits.
600  for ( iter = chips.begin(); iter != chips.end() ; iter++ ) {
601  //float rand = RandFlat::shoot();
602  float rand = CLHEP::RandFlat::shoot(engine);
603  if( rand > chipEfficiency ) chips[iter->first]=0;
604  }
605 
606  // Delete some Dcol hits.
607  for ( iter = columns.begin(); iter != columns.end() ; iter++ ) {
608  //float rand = RandFlat::shoot();
609  float rand = CLHEP::RandFlat::shoot(engine);
610  if( rand > columnEfficiency ) columns[iter->first]=0;
611  }
612 
613  // Now loop again over pixels to kill some of them.
614  // Loop over hit pixels, amplitude in electrons, channel = coded row,col
615  for(signal_map_iterator i = theSignal.begin();i != theSignal.end(); ++i) {
616 
617  // int chan = i->first;
618  std::pair<int,int> ip = PixelDigi::channelToPixel(i->first);//get pixel pos
619  int row = ip.first; // X in row
620  int col = ip.second; // Y is in col
621  //transform to ROC index coordinates
622  pIndexConverter->transformToROC(col,row,chipIndex,colROC,rowROC);
623  int dColInChip = pIndexConverter->DColumn(colROC); //get ROC dcol from ROC col
624  //dcol in mod
625  int dColInDet = pIndexConverter->DColumnInModule(dColInChip,chipIndex);
626 
627  //float rand = RandFlat::shoot();
628  float rand = CLHEP::RandFlat::shoot(engine);
629  if( chips[chipIndex]==0 || columns[dColInDet]==0
630  || rand>pixelEfficiency ) {
631  // make pixel amplitude =0, pixel will be lost at clusterization
632  i->second=(0.); // reset amplitude
633  } // end if
634  //Make a new Digi:
635 
636  // Don't put in digis that have been killed:
637  if(i->second > 0.) {
638  SPD.push_back( PixelDigi(i->first, i->second) );
639  }
640  } // end pixel loop
641  // push back vector here of one detID
642 
643  vPixelDigi.push_back(SPD);
644  }
645  }
646  }// end of loop over detectors
647 
648  // make new digi collection
649 
650  std::unique_ptr< edm::DetSetVector<PixelDigi> > MyPixelDigis(new edm::DetSetVector<PixelDigi>(vPixelDigi) );
651 
652  // put collection
653 
654  e.put(std::move(MyPixelDigis), PixelDigiCollectionDM_ );
655 
656  // clear local storage for this event
657  SiHitStorage_.clear();
658  }
659 
660 void DataMixingSiPixelMCDigiWorker::setPileupInfo(const std::vector<PileupSummaryInfo> &ps, const int &bunchSpacing) {
661 
662  //double bunchScale=1.0;
663  //if (bunchSpacing==25) bunchScale=bunchScaleAt25;
664 
665  int p = -1;
666  for ( unsigned int i=0; i<ps.size(); i++)
667  if ( ps[i].getBunchCrossing() == 0 )
668  p=i;
669 
670  if ( p>=0 ) {
671  for (size_t i=0, n = pixelEff_.thePUEfficiency.size(); i<n; i++) {
672  double instlumi = ps[p].getTrueNumInteractions()*pixelEff_.theInstLumiScaleFactor;
673  double instlumi_pow=1.;
674  pixelEff_.pu_scale[i] = 0;
675  for (size_t j=0; j<pixelEff_.thePUEfficiency[i].size(); j++){
676  pixelEff_.pu_scale[i]+=instlumi_pow*pixelEff_.thePUEfficiency[i][j];
677  instlumi_pow*=instlumi;
678  }
679  }
680  }
681 
682 } //this sets pu_scale
683 
684 } //edm
int adc(sample_type sample)
get the ADC sample (12 bits)
#define LogDebug(id)
size
Write out results.
T getParameter(std::string const &) const
virtual int nrows() const =0
void init_DynIneffDB(const edm::EventSetup &, const unsigned int &)
std::multimap< int, PixelDigi > OneDetectorMap
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:136
void push_back(const T &t)
Definition: DetSet.h:68
const DetContainer & detUnits() const override
Returm a vector of all GeomDet.
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:519
edm::EDGetTokenT< edm::DetSetVector< PixelDigi > > PixelDigiToken_
EventID const & id() const
unsigned int pxbLadder(const DetId &id) const
bool exists(std::string const &parameterName) const
checks if a parameter exists
virtual void initializeEvent(edm::Event const &e, edm::EventSetup const &c)
unsigned int pxbModule(const DetId &id) const
virtual CLHEP::HepRandomEngine & getEngine(StreamID const &)=0
Use this engine in event methods.
static std::string const input
Definition: EdmProvDump.cc:44
signal_map_type::const_iterator signal_map_const_iterator
uint32_t rawId() const
get the raw id
Definition: DetId.h:44
bool matches(const DetId &, const DetId &, const std::vector< uint32_t > &)
const std::vector< uint32_t > getDetIdmasks() const
bunchspace
in terms of 25 ns
edm::ESHandle< SiPixelDynamicInefficiency > SiPixelDynamicInefficiency_
DetId geographicalId() const
The label of this GeomDet.
Definition: GeomDet.h:79
#define end
Definition: vmac.h:39
std::map< int, Amplitude, std::less< int > > signal_map_type
int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:38
iterator end()
Return the off-the-end iterator.
Definition: DetSetVector.h:361
unsigned int pxfModule(const DetId &id) const
void init_from_db(const edm::ESHandle< TrackerGeometry > &, const edm::ESHandle< SiPixelDynamicInefficiency > &)
Definition: DetId.h:18
void setPileupInfo(const std::vector< PileupSummaryInfo > &ps, const int &bs)
const T & get() const
Definition: EventSetup.h:59
static std::pair< int, int > channelToPixel(int ch)
Definition: PixelDigi.h:62
virtual const PixelTopology & specificTopology() const
Returns a reference to the pixel proxy topology.
chan
lumi = TPaveText(lowX+0.38, lowY+0.061, lowX+0.45, lowY+0.161, "NDC") lumi.SetBorderSize( 0 ) lumi...
unsigned int layer(const DetId &id) const
edm::EventID id() const
Definition: EventBase.h:60
#define begin
Definition: vmac.h:32
HLT enums.
virtual int ncolumns() const =0
void addSiPixelPileups(const int bcr, const edm::EventPrincipal *, unsigned int EventId, ModuleCallingContext const *)
StreamID streamID() const
Definition: Event.h:95
col
Definition: cuy.py:1008
Signal rand(Signal arg)
Definition: vlib.cc:442
edm::EDGetTokenT< edm::DetSetVector< PixelDigi > > PixelDigiPToken_
const std::map< unsigned int, std::vector< double > > & getPUFactors() const
iterator begin()
Return an iterator to the first DetSet.
Definition: DetSetVector.h:346
PixelEfficiencies(const edm::ParameterSet &conf, bool AddPixelInefficiency, int NumberOfBarrelLayers, int NumberOfEndcapDisks)
collection_type::const_iterator const_iterator
Definition: DetSet.h:33
collection_type::const_iterator const_iterator
Definition: DetSetVector.h:104
Detector det() const
get the detector field from this detid
Definition: DetId.h:36
virtual SubDetector subDetector() const
Which subdetector.
Definition: GeomDet.cc:44
void putSiPixel(edm::Event &e, edm::EventSetup const &iSetup, std::vector< PileupSummaryInfo > &ps, int &bs)
T const * product() const
Definition: ESHandle.h:86
Definition: vlib.h:208
unsigned int pxfPanel(const DetId &id) const
def move(src, dest)
Definition: eostools.py:510
const std::map< unsigned int, double > & getColGeomFactors() const
const std::map< unsigned int, double > & getPixelGeomFactors() const
const std::map< unsigned int, double > & getChipGeomFactors() const