CMS 3D CMS Logo

Phase2TrackerDigitizer.cc
Go to the documentation of this file.
1 //
2 //
3 // Package: Phase2TrackerDigitizer
4 // Class: Phase2TrackerDigitizer
5 //
6 // *\class SiPhase2TrackerDigitizer Phase2TrackerDigitizer.cc SimTracker/SiPhase2Digitizer/src/Phase2TrackerDigitizer.cc
7 //
8 // Author: Suchandra Dutta, Suvankar Roy Chowdhury, Subir Sarkar
9 // Date: January 29, 2016
10 // Description: <one line class summary>
11 //
12 // Implementation:
13 // <Notes on implementation>
14 //
15 
16 #include <memory>
17 #include <set>
18 #include <iostream>
26 
34 
45 
49 
53 
56 
60 
65 
68 
70 
71 // Random Number
75 #include "CLHEP/Random/RandomEngine.h"
76 
77 namespace cms
78 {
79 
81  first_(true),
82  hitsProducer_(iConfig.getParameter<std::string>("hitsProducer")),
83  trackerContainers_(iConfig.getParameter<std::vector<std::string> >("ROUList")),
84  geometryType_(iConfig.getParameter<std::string>("GeometryType")),
85  isOuterTrackerReadoutAnalog(iConfig.getParameter<bool>("isOTreadoutAnalog")),
86  premixStage1_(iConfig.getParameter<bool>("premixStage1")),
87  makeDigiSimLinks_(iConfig.getParameter<edm::ParameterSet>("AlgorithmCommon").getUntrackedParameter<bool>("makeDigiSimLinks"))
88  {
89  //edm::LogInfo("Phase2TrackerDigitizer") << "Initialize Digitizer Algorithms";
90  const std::string alias1("simSiPixelDigis");
91  mixMod.produces<edm::DetSetVector<PixelDigi> >("Pixel").setBranchAlias(alias1);
92  if(makeDigiSimLinks_) {
93  mixMod.produces<edm::DetSetVector<PixelDigiSimLink> >("Pixel").setBranchAlias(alias1);
94  }
95 
96  if(!iConfig.getParameter<bool>("isOTreadoutAnalog")) {
97  const std::string alias2("simSiTrackerDigis");
98  if(premixStage1_) {
99  // Premixing exploits the ADC field of PixelDigi to store the collected charge
100  // But we still want everything else to be treated like for Phase2TrackerDigi
101  mixMod.produces<edm::DetSetVector<PixelDigi> >("Tracker").setBranchAlias(alias2);
102  }
103  else {
104  mixMod.produces<edm::DetSetVector<Phase2TrackerDigi> >("Tracker").setBranchAlias(alias2);
105  }
106  if(makeDigiSimLinks_) {
107  mixMod.produces<edm::DetSetVector<PixelDigiSimLink> >("Tracker").setBranchAlias(alias2);
108  }
109  }
110  // creating algorithm objects and pushing them into the map
111  algomap_[AlgorithmType::InnerPixel] = std::make_unique<PixelDigitizerAlgorithm>(iConfig);
112  algomap_[AlgorithmType::PixelinPS] = std::make_unique<PSPDigitizerAlgorithm>(iConfig);
113  algomap_[AlgorithmType::StripinPS] = std::make_unique<PSSDigitizerAlgorithm>(iConfig);
114  algomap_[AlgorithmType::TwoStrip] = std::make_unique<SSDigitizerAlgorithm>(iConfig);
115  }
116 
118 
119  iSetup.get<IdealMagneticFieldRecord>().get(pSetup_);
120  iSetup.get<TrackerTopologyRcd>().get(tTopoHand);
121 
122  if (theTkDigiGeomWatcher.check(iSetup)) {
124  //reset cache
126  detectorUnits_.clear();
127  for (auto const & det_u : pDD_->detUnits()) {
128  unsigned int detId_raw = det_u->geographicalId().rawId();
129  DetId detId = DetId(detId_raw);
130  if (DetId(detId).det() == DetId::Detector::Tracker) {
131  const Phase2TrackerGeomDetUnit* pixdet = dynamic_cast<const Phase2TrackerGeomDetUnit*>(det_u);
132  assert(pixdet);
133  detectorUnits_.insert(std::make_pair(detId_raw, pixdet));
134  }
135  }
136  }
137  }
138 
140  }
141  void
143  size_t globalSimHitIndex,const unsigned int tofBin) {
144  if (hSimHits.isValid()) {
145  std::set<unsigned int> detIds;
146  std::vector<PSimHit> const& simHits = *hSimHits.product();
147  int indx = 0;
148  for (auto it = simHits.begin(), itEnd = simHits.end(); it != itEnd; ++it, ++globalSimHitIndex) {
149  unsigned int detId_raw = (*it).detUnitId();
150  if (detectorUnits_.find(detId_raw) == detectorUnits_.end()) continue;
151  if (detIds.insert(detId_raw).second) {
152  // The insert succeeded, so this detector element has not yet been processed.
153  AlgorithmType algotype = getAlgoType(detId_raw);
154  const Phase2TrackerGeomDetUnit* phase2det = detectorUnits_[detId_raw];
155  // access to magnetic field in global coordinates
156  GlobalVector bfield = pSetup_->inTesla(phase2det->surface().position());
157  LogDebug("PixelDigitizer") << "B-field(T) at " << phase2det->surface().position() << "(cm): "
158  << pSetup_->inTesla(phase2det->surface().position());
159  if (algomap_.find(algotype) != algomap_.end()) {
160  algomap_[algotype]->accumulateSimHits(it, itEnd, globalSimHitIndex, tofBin, phase2det, bfield);
161  } else
162  edm::LogInfo("Phase2TrackerDigitizer") << "Unsupported algorithm: ";
163  }
164  indx++;
165  }
166  }
167  }
168 
169  void
171 
173  if (!rng.isAvailable()) {
174  throw cms::Exception("Configuration")
175  << "Phase2TrackerDigitizer requires the RandomNumberGeneratorService\n"
176  "which is not present in the configuration file. You must add the service\n"
177  "in the configuration file or remove the modules that require it.";
178  }
179 
180  // Must initialize all the algorithms
181  for (auto const & el : algomap_) {
182  if (first_) el.second->init(iSetup);
183 
184  el.second->initializeEvent(rng->getEngine(e.streamID()));
185  }
186  first_ = false;
187  // Make sure that the first crossing processed starts indexing the sim hits from zero.
188  // This variable is used so that the sim hits from all crossing frames have sequential
189  // indices used to create the digi-sim link (if configured to do so) rather than starting
190  // from zero for each crossing.
192  }
193  void
195  accumulate_local<edm::Event>(iEvent, iSetup);
196  }
197 
198  void
200  accumulate_local<PileUpEventPrincipal>(iEvent, iSetup);
201  }
202 
203  template <class T>
205  for (auto const & v : trackerContainers_) {
208  iEvent.getByLabel(tag, simHits);
209 
210  //edm::EDGetTokenT< std::vector<PSimHit> > simHitToken_(consumes< std::vector<PSimHit>(tag));
211  //iEvent.getByToken(simHitToken_, simHits);
212 
213  unsigned int tofBin = PixelDigiSimLink::LowTof;
214  if (v.find(std::string("HighTof")) != std::string::npos) tofBin = PixelDigiSimLink::HighTof;
215  accumulatePixelHits(simHits, crossingSimHitIndexOffset_[tag.encode()], tofBin);
216  // Now that the hits have been processed, I'll add the amount of hits in this crossing on to
217  // the global counter. Next time accumulateStripHits() is called it will count the sim hits
218  // as though they were on the end of this collection.
219  // Note that this is only used for creating digi-sim links (if configured to do so).
220  if (simHits.isValid()) crossingSimHitIndexOffset_[tag.encode()] += simHits->size();
221  }
222  }
223 
224  // For premixing
225  void Phase2TrackerDigitizer::loadAccumulator(const std::map<unsigned int, std::map<int, float> >& accumulator) {
226  for(const auto& detMap: accumulator) {
227  AlgorithmType algoType = getAlgoType(detMap.first);
228  auto& algo = *(algomap_.at(algoType));
229  algo.loadAccumulator(detMap.first, detMap.second);
230  }
231  }
232 
234  //Decide if we want analog readout for Outer Tracker.
237  if(premixStage1_) {
238  addOuterTrackerCollection<PixelDigi>(iEvent, iSetup);
239  }
240  else {
241  addOuterTrackerCollection<Phase2TrackerDigi>(iEvent, iSetup);
242  }
243  }
244  }
246  DetId detId(detId_raw);
247 
249 
250  //get mType either from the geometry or from our cache (faster)
252  auto itr = moduleTypeCache_.find(detId_raw);
253  if( itr != moduleTypeCache_.end() ) {
254  mType = itr->second;
255  } else {
256  mType = pDD_->getDetectorType(detId);
257  moduleTypeCache_.emplace(detId_raw,mType);
258  }
259 
260  switch(mType){
261 
263  algotype = AlgorithmType::InnerPixel;
264  break;
266  algotype = AlgorithmType::InnerPixel;
267  break;
269  algotype = AlgorithmType::InnerPixel;
270  break;
272  algotype = AlgorithmType::InnerPixel;
273  break;
275  algotype = AlgorithmType::PixelinPS;
276  break;
278  algotype = AlgorithmType::StripinPS;
279  break;
281  algotype = AlgorithmType::TwoStrip;
282  break;
283  default:
284  edm::LogError("Phase2TrackerDigitizer")<<"ERROR - Wrong Detector Type, No Algorithm available ";
285  }
286 
287  return algotype;
288  }
289  void Phase2TrackerDigitizer::addPixelCollection(edm::Event& iEvent, const edm::EventSetup& iSetup, const bool ot_analog) {
290  const TrackerTopology* tTopo = tTopoHand.product();
291  std::vector<edm::DetSet<PixelDigi> > digiVector;
292  std::vector<edm::DetSet<PixelDigiSimLink> > digiLinkVector;
293  for (auto const & det_u : pDD_->detUnits()) {
294  DetId detId_raw = DetId(det_u->geographicalId().rawId());
295  AlgorithmType algotype = getAlgoType(detId_raw);
296  if (algomap_.find(algotype) == algomap_.end()) continue;
297 
298  //Decide if we want analog readout for Outer Tracker.
299  if( !ot_analog && algotype != AlgorithmType::InnerPixel) continue;
300  std::map<int, DigitizerUtility::DigiSimInfo> digi_map;
301  algomap_[algotype]->digitize(dynamic_cast<const Phase2TrackerGeomDetUnit*>(det_u),
302  digi_map,tTopo);
303  edm::DetSet<PixelDigi> collector(det_u->geographicalId().rawId());
304  edm::DetSet<PixelDigiSimLink> linkcollector(det_u->geographicalId().rawId());
305  for (auto const & digi_p : digi_map) {
306  DigitizerUtility::DigiSimInfo info = digi_p.second;
307  std::pair<int,int> ip = PixelDigi::channelToPixel(digi_p.first);
308  collector.data.emplace_back(ip.first, ip.second, info.sig_tot);
309  for (auto const & sim_p : info.simInfoList) {
310  linkcollector.data.emplace_back(digi_p.first, sim_p.second->trackId(), sim_p.second->hitIndex(), sim_p.second->tofBin(), sim_p.second->eventId(), sim_p.first);
311  }
312  }
313  if (!collector.data.empty()) digiVector.push_back(std::move(collector));
314  if (!linkcollector.data.empty()) digiLinkVector.push_back(std::move(linkcollector));
315  }
316 
317  // Step C: create collection with the cache vector of DetSet
318  std::unique_ptr<edm::DetSetVector<PixelDigi> >
319  output(new edm::DetSetVector<PixelDigi>(digiVector));
320  std::unique_ptr<edm::DetSetVector<PixelDigiSimLink> >
321  outputlink(new edm::DetSetVector<PixelDigiSimLink>(digiLinkVector));
322 
323  // Step D: write output to file
324  iEvent.put(std::move(output), "Pixel");
325  if(makeDigiSimLinks_) {
326  iEvent.put(std::move(outputlink), "Pixel");
327  }
328  }
329 }
330 namespace {
331  void addToCollector(edm::DetSet<PixelDigi>& collector, const int channel, const DigitizerUtility::DigiSimInfo& info) {
332  // For premixing stage1 the channel must be decoded with PixelDigi
333  // so that when the row and column are inserted to PixelDigi the
334  // coded channel stays the same (so that it can then be decoded
335  // with Phase2TrackerDigi in stage2).
336  std::pair<int,int> ip = PixelDigi::channelToPixel(channel);
337  collector.data.emplace_back(ip.first, ip.second, info.sig_tot);
338  }
339  void addToCollector(edm::DetSet<Phase2TrackerDigi>& collector, const int channel, const DigitizerUtility::DigiSimInfo& info) {
340  std::pair<int,int> ip = Phase2TrackerDigi::channelToPixel(channel);
341  collector.data.emplace_back(ip.first, ip.second, info.ot_bit);
342  }
343 }
344 namespace cms {
345  template <typename DigiType>
347  const TrackerTopology* tTopo = tTopoHand.product();
348  std::vector<edm::DetSet<DigiType> > digiVector;
349  std::vector<edm::DetSet<PixelDigiSimLink> > digiLinkVector;
350  for (auto const & det_u : pDD_->detUnits()) {
351  DetId detId_raw = DetId(det_u->geographicalId().rawId());
352  AlgorithmType algotype = getAlgoType(detId_raw);
353 
354  if (algomap_.find(algotype) == algomap_.end() || algotype == AlgorithmType::InnerPixel) continue;
355 
356  std::map<int, DigitizerUtility::DigiSimInfo> digi_map;
357  algomap_[algotype]->digitize(dynamic_cast<const Phase2TrackerGeomDetUnit*>(det_u),
358  digi_map, tTopo);
359  edm::DetSet<DigiType> collector(det_u->geographicalId().rawId());
360  edm::DetSet<PixelDigiSimLink> linkcollector(det_u->geographicalId().rawId());
361 
362  for (auto const & digi_p : digi_map) {
363  DigitizerUtility::DigiSimInfo info = digi_p.second;
364  addToCollector(collector, digi_p.first, info);
365  for (auto const & sim_p : info.simInfoList) {
366 
367  linkcollector.data.emplace_back(digi_p.first, sim_p.second->trackId(), sim_p.second->hitIndex(), sim_p.second->tofBin(), sim_p.second->eventId(), sim_p.first);
368  }
369  }
370 
371  if (!collector.data.empty()) digiVector.push_back(std::move(collector));
372  if (!linkcollector.data.empty()) digiLinkVector.push_back(std::move(linkcollector));
373  }
374 
375  // Step C: create collection with the cache vector of DetSet
376  std::unique_ptr<edm::DetSetVector<DigiType> >
377  output(new edm::DetSetVector<DigiType>(digiVector));
378  std::unique_ptr<edm::DetSetVector<PixelDigiSimLink> >
379  outputlink(new edm::DetSetVector<PixelDigiSimLink>(digiLinkVector));
380 
381  // Step D: write output to file
382  iEvent.put(std::move(output), "Tracker");
383  if(makeDigiSimLinks_) {
384  iEvent.put(std::move(outputlink), "Tracker");
385  }
386  }
387 }
388 
391 
#define LogDebug(id)
BranchAliasSetterT< ProductType > produces()
declare what type of product will make and with which optional label
T getParameter(std::string const &) const
static const TGPicture * info(bool iBackgroundIsBlack)
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:137
void accumulate(edm::Event const &e, edm::EventSetup const &c) override
edm::ESWatcher< TrackerDigiGeometryRecord > theTkDigiGeomWatcher
const DetContainer & detUnits() const override
Returm a vector of all GeomDet.
void finalizeEvent(edm::Event &e, edm::EventSetup const &c) override
void initializeEvent(edm::Event const &e, edm::EventSetup const &c) override
void accumulatePixelHits(edm::Handle< std::vector< PSimHit > >, size_t globalSimHitIndex, const unsigned int tofBin)
void accumulate_local(T const &iEvent, edm::EventSetup const &iSetup)
virtual CLHEP::HepRandomEngine & getEngine(StreamID const &)=0
Use this engine in event methods.
const Plane & surface() const
The nominal surface of the GeomDet.
Definition: GeomDet.h:42
std::unordered_map< unsigned, TrackerGeometry::ModuleType > ModuleTypeCache
std::string encode() const
Definition: InputTag.cc:166
std::map< unsigned int, const Phase2TrackerGeomDetUnit * > detectorUnits_
int iEvent
Definition: GenABIO.cc:230
edm::ESHandle< TrackerTopology > tTopoHand
edm::ESHandle< TrackerGeometry > pDD_
bool isAvailable() const
Definition: Service.h:46
void loadAccumulator(const std::map< unsigned int, std::map< int, float > > &accumulator)
std::map< std::string, size_t > crossingSimHitIndexOffset_
Offset to add to the index of each sim hit to account for which crossing it&#39;s in. ...
ModuleType getDetectorType(DetId) const
bool isValid() const
Definition: HandleBase.h:74
virtual GlobalVector inTesla(const GlobalPoint &gp) const =0
Field value ad specified global point, in Tesla.
Namespace of DDCMS conversion namespace.
void addOuterTrackerCollection(edm::Event &iEvent, const edm::EventSetup &iSetup)
Definition: DetId.h:18
AlgorithmType getAlgoType(unsigned int idet)
void beginLuminosityBlock(edm::LuminosityBlock const &lumi, edm::EventSetup const &iSetup) override
static std::pair< int, int > channelToPixel(int ch)
Definition: PixelDigi.h:62
bool check(const edm::EventSetup &iSetup)
Definition: ESWatcher.h:57
edm::ESHandle< MagneticField > pSetup_
collection_type data
Definition: DetSet.h:78
std::map< AlgorithmType, std::unique_ptr< Phase2TrackerDigitizerAlgorithm > > algomap_
HLT enums.
#define DEFINE_DIGI_ACCUMULATOR(type)
T get() const
Definition: EventSetup.h:62
StreamID streamID() const
Definition: Event.h:96
Phase2TrackerDigitizer(const edm::ParameterSet &iConfig, edm::ProducerBase &mixMod, edm::ConsumesCollector &iC)
std::vector< std::pair< float, SimHitInfoForLinks * > > simInfoList
void addPixelCollection(edm::Event &iEvent, const edm::EventSetup &iSetup, const bool ot_analog)
long double T
const PositionType & position() const
T const * product() const
Definition: ESHandle.h:86
def move(src, dest)
Definition: eostools.py:511
static std::pair< unsigned int, unsigned int > channelToPixel(unsigned int ch)