CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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 #include <memory>
16 #include <set>
17 #include <iostream>
18 
28 
35 
39 
46 
49 
52 
54 
56 
57 // Random Number
60 
61 namespace cms {
62 
64  edm::ProducesCollector producesCollector,
66  : first_(true),
67  hitsProducer_(iConfig.getParameter<std::string>("hitsProducer")),
68  trackerContainers_(iConfig.getParameter<std::vector<std::string> >("ROUList")),
69  pDDToken_(iC.esConsumes(edm::ESInputTag("", iConfig.getParameter<std::string>("GeometryType")))),
70  pSetupToken_(iC.esConsumes()),
71  tTopoToken_(iC.esConsumes()),
72  isOuterTrackerReadoutAnalog_(iConfig.getParameter<bool>("isOTreadoutAnalog")),
73  premixStage1_(iConfig.getParameter<bool>("premixStage1")),
74  makeDigiSimLinks_(
75  iConfig.getParameter<edm::ParameterSet>("AlgorithmCommon").getUntrackedParameter<bool>("makeDigiSimLinks")) {
76  const std::string alias1("simSiPixelDigis");
77  producesCollector.produces<edm::DetSetVector<PixelDigi> >("Pixel").setBranchAlias(alias1);
79  producesCollector.produces<edm::DetSetVector<PixelDigiSimLink> >("Pixel").setBranchAlias(alias1);
80 
81  if (!iConfig.getParameter<bool>("isOTreadoutAnalog")) {
82  const std::string alias2("simSiTrackerDigis");
83  if (premixStage1_) {
84  // Premixing exploits the ADC field of PixelDigi to store the collected charge
85  // But we still want everything else to be treated like for Phase2TrackerDigi
86  producesCollector.produces<edm::DetSetVector<PixelDigi> >("Tracker").setBranchAlias(alias2);
87  } else {
88  producesCollector.produces<edm::DetSetVector<Phase2TrackerDigi> >("Tracker").setBranchAlias(alias2);
89  }
91  producesCollector.produces<edm::DetSetVector<PixelDigiSimLink> >("Tracker").setBranchAlias(alias2);
92  }
93  // creating algorithm objects and pushing them into the map
94  algomap_[AlgorithmType::InnerPixel] = std::make_unique<PixelDigitizerAlgorithm>(iConfig, iC);
95  algomap_[AlgorithmType::InnerPixelBricked] = std::make_unique<PixelBrickedDigitizerAlgorithm>(iConfig, iC);
96  algomap_[AlgorithmType::InnerPixel3D] = std::make_unique<Pixel3DDigitizerAlgorithm>(iConfig, iC);
97  algomap_[AlgorithmType::PixelinPS] = std::make_unique<PSPDigitizerAlgorithm>(iConfig, iC);
98  algomap_[AlgorithmType::StripinPS] = std::make_unique<PSSDigitizerAlgorithm>(iConfig, iC);
99  algomap_[AlgorithmType::TwoStrip] = std::make_unique<SSDigitizerAlgorithm>(iConfig, iC);
100  }
101 
103  void Phase2TrackerDigitizer::accumulatePixelHits(edm::Handle<std::vector<PSimHit> > hSimHits,
104  size_t globalSimHitIndex,
105  const uint32_t tofBin) {
106  if (hSimHits.isValid()) {
107  std::set<uint32_t> detIds;
108  auto const& simHits = *(hSimHits.product());
109  for (auto it = std::begin(simHits), itEnd = std::end(simHits); it != itEnd; ++it, ++globalSimHitIndex) {
110  uint32_t detId_raw = (*it).detUnitId();
111  auto fiter = detectorUnits_.find(detId_raw);
112  if (fiter == detectorUnits_.end())
113  continue;
114 
115  if (detIds.insert(detId_raw).second) {
116  // The insert succeeded, so this detector element has not yet been processed.
117  const Phase2TrackerGeomDetUnit* phase2det = fiter->second;
118 
119  // access to magnetic field in global coordinates
120  GlobalVector bfield = pSetup_->inTesla(phase2det->surface().position());
121  LogDebug("PixelDigitizer") << "B-field(T) at " << phase2det->surface().position()
122  << " (cm): " << pSetup_->inTesla(phase2det->surface().position());
123 
124  auto kiter = algomap_.find(getAlgoType(detId_raw));
125  if (kiter != algomap_.end())
126  kiter->second->accumulateSimHits(it, itEnd, globalSimHitIndex, tofBin, phase2det, bfield);
127  else
128  edm::LogInfo("Phase2TrackerDigitizer") << "Unsupported algorithm: ";
129  }
130  }
131  }
132  }
133 
136  if (!rng.isAvailable()) {
137  throw cms::Exception("Configuration")
138  << "Phase2TrackerDigitizer requires the RandomNumberGeneratorService\n"
139  "which is not present in the configuration file. You must add the service\n"
140  "in the configuration file or remove the modules that require it.";
141  }
142 
143  pSetup_ = &iSetup.getData(pSetupToken_);
144  tTopo_ = &iSetup.getData(tTopoToken_);
145 
146  if (theTkDigiGeomWatcher_.check(iSetup)) {
147  pDD_ = &iSetup.getData(pDDToken_);
148 
149  // reset cache
151  detectorUnits_.clear();
152  for (auto const& det_u : pDD_->detUnits()) {
153  uint32_t rawId = det_u->geographicalId().rawId();
154  if (DetId(rawId).det() == DetId::Detector::Tracker) {
155  const Phase2TrackerGeomDetUnit* pixdet = dynamic_cast<const Phase2TrackerGeomDetUnit*>(det_u);
156  assert(pixdet);
157  detectorUnits_.emplace(rawId, pixdet);
158  }
159  }
160  }
161 
162  // Must initialize all the algorithms
163  for (auto const& el : algomap_) {
164  if (first_)
165  el.second->init(iSetup);
166 
167  el.second->initializeEvent(rng->getEngine(e.streamID()));
168  }
169  first_ = false;
170  // Make sure that the first crossing processed starts indexing the sim hits from zero.
171  // This variable is used so that the sim hits from all crossing frames have sequential
172  // indices used to create the digi-sim link (if configured to do so) rather than starting
173  // from zero for each crossing.
175  }
177  accumulate_local<edm::Event>(iEvent, iSetup);
178  }
179 
181  edm::EventSetup const& iSetup,
182  edm::StreamID const&) {
183  accumulate_local<PileUpEventPrincipal>(iEvent, iSetup);
184  }
185 
186  template <class T>
188  for (auto const& v : trackerContainers_) {
191  iEvent.getByLabel(tag, simHits);
192 
193  //edm::EDGetTokenT< std::vector<PSimHit> > simHitToken_(consumes< std::vector<PSimHit>(tag));
194  //iEvent.getByToken(simHitToken_, simHits);
195 
196  uint32_t tofBin = PixelDigiSimLink::LowTof;
197  if (v.find(std::string("HighTof")) != std::string::npos)
198  tofBin = PixelDigiSimLink::HighTof;
199  accumulatePixelHits(simHits, crossingSimHitIndexOffset_[tag.encode()], tofBin);
200  // Now that the hits have been processed, I'll add the amount of hits in this crossing on to
201  // the global counter. Next time accumulateStripHits() is called it will count the sim hits
202  // as though they were on the end of this collection.
203  // Note that this is only used for creating digi-sim links (if configured to do so).
204  if (simHits.isValid())
205  crossingSimHitIndexOffset_[tag.encode()] += simHits->size();
206  }
207  }
208 
209  // For premixing
210  void Phase2TrackerDigitizer::loadAccumulator(const std::map<uint32_t, std::map<int, float> >& accumulator) {
211  for (const auto& detMap : accumulator) {
212  AlgorithmType algoType = getAlgoType(detMap.first);
213  auto& algo = *(algomap_.at(algoType));
214  algo.loadAccumulator(detMap.first, detMap.second);
215  }
216  }
217 
219  //Decide if we want analog readout for Outer Tracker.
222  if (premixStage1_)
223  addOuterTrackerCollection<PixelDigi>(iEvent, iSetup);
224  else
225  addOuterTrackerCollection<Phase2TrackerDigi>(iEvent, iSetup);
226  }
227  }
229  // get mType either from the geometry or from our cache (faster)
231  auto itr = moduleTypeCache_.find(detId_raw);
232  if (itr != moduleTypeCache_.end()) {
233  mType = itr->second;
234  } else {
235  mType = pDD_->getDetectorType(DetId(detId_raw));
236  moduleTypeCache_.emplace(detId_raw, mType);
237  }
238 
239  auto detUnit = detectorUnits_.find(detId_raw);
240  const Phase2TrackerGeomDetUnit* pixdet = dynamic_cast<const Phase2TrackerGeomDetUnit*>(detUnit->second);
241  const Phase2TrackerTopology* topol = &pixdet->specificTopology();
243  switch (mType) {
245  algotype = AlgorithmType::InnerPixel;
246  break;
248  algotype = AlgorithmType::InnerPixel;
249  break;
251  if (topol->isBricked())
253  else
254  algotype = AlgorithmType::InnerPixel;
255  break;
257  if (topol->isBricked())
259  else
260  algotype = AlgorithmType::InnerPixel;
261  break;
263  algotype = AlgorithmType::InnerPixel3D;
264  break;
266  algotype = AlgorithmType::InnerPixel3D;
267  break;
269  algotype = AlgorithmType::PixelinPS;
270  break;
272  algotype = AlgorithmType::StripinPS;
273  break;
275  algotype = AlgorithmType::TwoStrip;
276  break;
277  default:
278  edm::LogError("Phase2TrackerDigitizer") << "ERROR - Wrong Detector Type, No Algorithm available ";
279  }
280 
281  return algotype;
282  }
284  const edm::EventSetup& iSetup,
285  const bool ot_analog) {
286  std::vector<edm::DetSet<PixelDigi> > digiVector;
287  std::vector<edm::DetSet<PixelDigiSimLink> > digiLinkVector;
288  for (auto const& det_u : pDD_->detUnits()) {
289  uint32_t rawId = det_u->geographicalId().rawId();
290  auto algotype = getAlgoType(rawId);
291  auto fiter = algomap_.find(algotype);
292  if (fiter == algomap_.end())
293  continue;
294 
295  // Decide if we want analog readout for Outer Tracker.
296  if (!ot_analog && algotype != AlgorithmType::InnerPixel && algotype != AlgorithmType::InnerPixel3D &&
298  continue;
299 
300  std::map<int, DigitizerUtility::DigiSimInfo> digi_map;
301  fiter->second->digitize(dynamic_cast<const Phase2TrackerGeomDetUnit*>(det_u), digi_map, tTopo_);
302 
303  edm::DetSet<PixelDigi> collector(rawId);
304  edm::DetSet<PixelDigiSimLink> linkcollector(rawId);
305  for (auto const& digi_p : digi_map) {
306  DigitizerUtility::DigiSimInfo info = digi_p.second;
307  const auto& 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,
311  sim_p.second->trackId(),
312  sim_p.second->hitIndex(),
313  sim_p.second->tofBin(),
314  sim_p.second->eventId(),
315  sim_p.first);
316  }
317  }
318  if (!collector.data.empty())
319  digiVector.push_back(std::move(collector));
320  if (!linkcollector.data.empty())
321  digiLinkVector.push_back(std::move(linkcollector));
322  }
323 
324  // Step C: create collection with the cache vector of DetSet
325  auto output = std::make_unique<edm::DetSetVector<PixelDigi> >(digiVector);
326  auto outputlink = std::make_unique<edm::DetSetVector<PixelDigiSimLink> >(digiLinkVector);
327 
328  // Step D: write output to file
329  iEvent.put(std::move(output), "Pixel");
330  if (makeDigiSimLinks_)
331  iEvent.put(std::move(outputlink), "Pixel");
332  }
333 } // namespace cms
334 namespace {
335  void addToCollector(edm::DetSet<PixelDigi>& collector, const int channel, const DigitizerUtility::DigiSimInfo& info) {
336  // For premixing stage1 the channel must be decoded with PixelDigi
337  // so that when the row and column are inserted to PixelDigi the
338  // coded channel stays the same (so that it can then be decoded
339  // with Phase2TrackerDigi in stage2).
340  const auto& ip = PixelDigi::channelToPixel(channel);
341  collector.data.emplace_back(ip.first, ip.second, info.sig_tot);
342  }
343  void addToCollector(edm::DetSet<Phase2TrackerDigi>& collector,
344  const int channel,
345  const DigitizerUtility::DigiSimInfo& info) {
346  const auto& ip = Phase2TrackerDigi::channelToPixel(channel);
347  collector.data.emplace_back(ip.first, ip.second, info.ot_bit);
348  }
349 } // namespace
350 namespace cms {
351  template <typename DigiType>
353  std::vector<edm::DetSet<DigiType> > digiVector;
354  std::vector<edm::DetSet<PixelDigiSimLink> > digiLinkVector;
355  for (auto const& det_u : pDD_->detUnits()) {
356  uint32_t rawId = det_u->geographicalId().rawId();
357  auto algotype = getAlgoType(rawId);
358 
359  auto fiter = algomap_.find(algotype);
360  if (fiter == algomap_.end() || algotype == AlgorithmType::InnerPixel || algotype == AlgorithmType::InnerPixel3D ||
362  continue;
363 
364  std::map<int, DigitizerUtility::DigiSimInfo> digi_map;
365  fiter->second->digitize(dynamic_cast<const Phase2TrackerGeomDetUnit*>(det_u), digi_map, tTopo_);
366 
367  edm::DetSet<DigiType> collector(rawId);
368  edm::DetSet<PixelDigiSimLink> linkcollector(rawId);
369  for (auto const& digi_p : digi_map) {
370  DigitizerUtility::DigiSimInfo info = digi_p.second;
371  addToCollector(collector, digi_p.first, info);
372  for (auto const& sim_p : info.simInfoList) {
373  linkcollector.data.emplace_back(digi_p.first,
374  sim_p.second->trackId(),
375  sim_p.second->hitIndex(),
376  sim_p.second->tofBin(),
377  sim_p.second->eventId(),
378  sim_p.first);
379  }
380  }
381 
382  if (!collector.data.empty())
383  digiVector.push_back(std::move(collector));
384  if (!linkcollector.data.empty())
385  digiLinkVector.push_back(std::move(linkcollector));
386  }
387 
388  // Step C: create collection with the cache vector of DetSet
389  auto output = std::make_unique<edm::DetSetVector<DigiType> >(digiVector);
390  auto outputlink = std::make_unique<edm::DetSetVector<PixelDigiSimLink> >(digiLinkVector);
391 
392  // Step D: write output to file
393  iEvent.put(std::move(output), "Tracker");
394  if (makeDigiSimLinks_)
395  iEvent.put(std::move(outputlink), "Tracker");
396  }
397 } // namespace cms
398 
401 
edm::ESWatcher< TrackerDigiGeometryRecord > theTkDigiGeomWatcher_
Phase2TrackerDigitizer(const edm::ParameterSet &iConfig, edm::ProducesCollector, edm::ConsumesCollector &iC)
static const TGPicture * info(bool iBackgroundIsBlack)
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:133
const TrackerTopology * tTopo_
void accumulate(edm::Event const &e, edm::EventSetup const &c) override
static std::pair< int, int > channelToPixel(int ch)
Definition: PixelDigi.h:69
void accumulatePixelHits(edm::Handle< std::vector< PSimHit > >, size_t globalSimHitIndex, const uint32_t tofBin)
void finalizeEvent(edm::Event &e, edm::EventSetup const &c) override
ProductRegistryHelper::BranchAliasSetterT< ProductType > produces()
AlgorithmType getAlgoType(uint32_t idet)
virtual GlobalVector inTesla(const GlobalPoint &gp) const =0
Field value ad specified global point, in Tesla.
void initializeEvent(edm::Event const &e, edm::EventSetup const &c) override
const edm::ESGetToken< TrackerTopology, TrackerTopologyRcd > tTopoToken_
const DetContainer & detUnits() const override
Returm a vector of all GeomDet.
void accumulate_local(T const &iEvent, edm::EventSetup const &iSetup)
Log< level::Error, false > LogError
assert(be >=bs)
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:37
std::string encode() const
Definition: InputTag.cc:159
bool getData(T &iHolder) const
Definition: EventSetup.h:128
int iEvent
Definition: GenABIO.cc:224
virtual bool isBricked() const =0
def move
Definition: eostools.py:511
bool isAvailable() const
Definition: Service.h:40
std::unordered_map< uint32_t, TrackerGeometry::ModuleType > ModuleTypeCache
ModuleType getDetectorType(DetId) const
void loadAccumulator(const std::map< uint32_t, std::map< int, float > > &accumulator)
bool isValid() const
Definition: HandleBase.h:70
std::vector< std::pair< float, SimHitInfo * > > simInfoList
Log< level::Info, false > LogInfo
std::map< uint32_t, const Phase2TrackerGeomDetUnit * > detectorUnits_
void addOuterTrackerCollection(edm::Event &iEvent, const edm::EventSetup &iSetup)
Definition: DetId.h:17
const edm::ESGetToken< MagneticField, IdealMagneticFieldRecord > pSetupToken_
virtual const PixelTopology & specificTopology() const
Returns a reference to the pixel proxy topology.
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
tuple simHits
Definition: trackerHits.py:16
bool check(const edm::EventSetup &iSetup)
Definition: ESWatcher.h:57
collection_type data
Definition: DetSet.h:80
std::map< AlgorithmType, std::unique_ptr< Phase2TrackerDigitizerAlgorithm > > algomap_
static std::pair< unsigned int, unsigned int > channelToPixel(unsigned int ch)
#define DEFINE_DIGI_ACCUMULATOR(type)
string end
Definition: dataset.py:937
StreamID streamID() const
Definition: Event.h:98
const edm::ESGetToken< TrackerGeometry, TrackerDigiGeometryRecord > pDDToken_
void addPixelCollection(edm::Event &iEvent, const edm::EventSetup &iSetup, const bool ot_analog)
long double T
const PositionType & position() const
ESGetTokenH3DDVariant esConsumes(std::string const &Reccord, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
tTopoToken_
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. ...
#define LogDebug(id)