CMS 3D CMS Logo

SiPixelDigitizer.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: SiPixelDigitizer
4 // Class: SiPixelDigitizer
5 //
13 //
14 // Original Author: Michele Pioppi-INFN perugia
15 // Modifications: Freya Blekman - Cornell University
16 // Created: Mon Sep 26 11:08:32 CEST 2005
17 //
18 //
19 
20 // system include files
21 #include <memory>
22 #include <set>
23 
24 // user include files
25 #include "SiPixelDigitizer.h"
27 
45 
48 
49 // user include files
51 
54 
56 
60 //Random Number
65 
66 //
67 // constants, enums and typedefs
68 //
69 
70 //
71 // static data member definitions
72 //
73 
74 //
75 // constructors and destructor
76 //
77 //using namespace std;
78 
79 namespace cms {
81  edm::ProducesCollector producesCollector,
83  : firstInitializeEvent_(true),
84  firstFinalizeEvent_(true),
85  _pixeldigialgo(),
86  hitsProducer(iConfig.getParameter<std::string>("hitsProducer")),
87  trackerContainers(iConfig.getParameter<std::vector<std::string> >("RoutList")),
88  pilotBlades(iConfig.exists("enablePilotBlades") ? iConfig.getParameter<bool>("enablePilotBlades") : false),
89  NumberOfEndcapDisks(iConfig.exists("NumPixelEndcap") ? iConfig.getParameter<int>("NumPixelEndcap") : 2),
90  tTopoToken_(iC.esConsumes()),
91  pDDToken_(iC.esConsumes(edm::ESInputTag("", iConfig.getParameter<std::string>("PixGeometryType")))),
92  pSetupToken_(iC.esConsumes()) {
93  edm::LogInfo("PixelDigitizer ") << "Enter the Pixel Digitizer";
94 
95  const std::string alias("simSiPixelDigis");
96 
97  producesCollector.produces<edm::DetSetVector<PixelDigi> >().setBranchAlias(alias);
98  producesCollector.produces<edm::DetSetVector<PixelDigiSimLink> >().setBranchAlias(alias + "siPixelDigiSimLink");
99 
100  for (auto const& trackerContainer : trackerContainers) {
101  edm::InputTag tag(hitsProducer, trackerContainer);
102  iC.consumes<std::vector<PSimHit> >(edm::InputTag(hitsProducer, trackerContainer));
103  }
105  if (!rng.isAvailable()) {
106  throw cms::Exception("Configuration")
107  << "SiPixelDigitizer requires the RandomNumberGeneratorService\n"
108  "which is not present in the configuration file. You must add the service\n"
109  "in the configuration file or remove the modules that require it.";
110  }
111 
112  _pixeldigialgo = std::make_unique<SiPixelDigitizerAlgorithm>(iConfig, iC);
113  if (NumberOfEndcapDisks != 2)
114  producesCollector.produces<PixelFEDChannelCollection>();
115  }
116 
117  SiPixelDigitizer::~SiPixelDigitizer() { edm::LogInfo("PixelDigitizer ") << "Destruct the Pixel Digitizer"; }
118 
119  //
120  // member functions
121  //
122 
123  void SiPixelDigitizer::accumulatePixelHits(edm::Handle<std::vector<PSimHit> > hSimHits,
124  size_t globalSimHitIndex,
125  const unsigned int tofBin,
126  edm::EventSetup const& iSetup) {
127  if (hSimHits.isValid()) {
128  std::set<unsigned int> detIds;
129  std::vector<PSimHit> const& simHits = *hSimHits.product();
130  const TrackerTopology* tTopo = &iSetup.getData(tTopoToken_);
131  for (std::vector<PSimHit>::const_iterator it = simHits.begin(), itEnd = simHits.end(); it != itEnd;
132  ++it, ++globalSimHitIndex) {
133  unsigned int detId = (*it).detUnitId();
134  if (detIds.insert(detId).second) {
135  // The insert succeeded, so this detector element has not yet been processed.
136  assert(detectorUnits[detId]);
137  if (detectorUnits[detId] &&
138  detectorUnits[detId]
139  ->type()
140  .isTrackerPixel()) { // this test could be avoided and changed into a check of pixdet!=0
141  std::map<unsigned int, PixelGeomDetUnit const*>::iterator itDet = detectorUnits.find(detId);
142  if (itDet == detectorUnits.end())
143  continue;
144  auto pixdet = itDet->second;
145  assert(pixdet != nullptr);
146  //access to magnetic field in global coordinates
147  GlobalVector bfield = pSetup->inTesla(pixdet->surface().position());
148  LogDebug("PixelDigitizer ") << "B-field(T) at " << pixdet->surface().position()
149  << "(cm): " << pSetup->inTesla(pixdet->surface().position());
150  _pixeldigialgo->accumulateSimHits(
151  it, itEnd, globalSimHitIndex, tofBin, pixdet, bfield, tTopo, randomEngine_);
152  }
153  }
154  }
155  }
156  }
157 
159  if (firstInitializeEvent_) {
160  _pixeldigialgo->init(iSetup);
161  firstInitializeEvent_ = false;
162  }
163 
164  // Make sure that the first crossing processed starts indexing the sim hits from zero.
165  // This variable is used so that the sim hits from all crossing frames have sequential
166  // indices used to create the digi-sim link (if configured to do so) rather than starting
167  // from zero for each crossing.
169 
170  // Cache random number engine
172  randomEngine_ = &rng->getEngine(e.streamID());
173 
174  _pixeldigialgo->initializeEvent();
175  pDD = &iSetup.getData(pDDToken_);
176  pSetup = &iSetup.getData(pSetupToken_);
177  const TrackerTopology* tTopo = &iSetup.getData(tTopoToken_);
178 
179  // FIX THIS! We only need to clear and (re)fill this map when the geometry type IOV changes. Use ESWatcher to determine this.
180  if (true) { // Replace with ESWatcher
181  detectorUnits.clear();
182  for (const auto& iu : pDD->detUnits()) {
183  unsigned int detId = iu->geographicalId().rawId();
184  if (iu->type().isTrackerPixel()) {
185  auto pixdet = dynamic_cast<const PixelGeomDetUnit*>(iu);
186  assert(pixdet != nullptr);
187  if (iu->subDetector() ==
188  GeomDetEnumerators::SubDetector::PixelEndcap) { // true ONLY for the phase 0 pixel deetctor
189  unsigned int disk = tTopo->layer(detId); // using the generic layer method
190  //if using pilot blades, then allowing it for current detector only
191  if ((disk == 3) && ((!pilotBlades) && (NumberOfEndcapDisks == 2)))
192  continue;
193  }
194  detectorUnits.insert(std::make_pair(detId, pixdet));
195  }
196  }
197  }
198  }
199 
201  // Step A: Get Inputs
202  for (vstring::const_iterator i = trackerContainers.begin(), iEnd = trackerContainers.end(); i != iEnd; ++i) {
205 
206  iEvent.getByLabel(tag, simHits);
207  unsigned int tofBin = PixelDigiSimLink::LowTof;
208  if ((*i).find(std::string("HighTof")) != std::string::npos)
209  tofBin = PixelDigiSimLink::HighTof;
210  accumulatePixelHits(simHits, crossingSimHitIndexOffset_[tag.encode()], tofBin, iSetup);
211  // Now that the hits have been processed, I'll add the amount of hits in this crossing on to
212  // the global counter. Next time accumulateStripHits() is called it will count the sim hits
213  // as though they were on the end of this collection.
214  // Note that this is only used for creating digi-sim links (if configured to do so).
215  // std::cout << "index offset, current hit count = " << crossingSimHitIndexOffset_[tag.encode()] << ", " << simHits->size() << std::endl;
216  if (simHits.isValid())
217  crossingSimHitIndexOffset_[tag.encode()] += simHits->size();
218  }
219  }
220 
222  edm::EventSetup const& iSetup,
223  edm::StreamID const& streamID) {
224  // Step A: Get Inputs
225  for (vstring::const_iterator i = trackerContainers.begin(), iEnd = trackerContainers.end(); i != iEnd; ++i) {
228 
229  iEvent.getByLabel(tag, simHits);
230  unsigned int tofBin = PixelDigiSimLink::LowTof;
231  if ((*i).find(std::string("HighTof")) != std::string::npos)
232  tofBin = PixelDigiSimLink::HighTof;
233  accumulatePixelHits(simHits, crossingSimHitIndexOffset_[tag.encode()], tofBin, iSetup);
234  // Now that the hits have been processed, I'll add the amount of hits in this crossing on to
235  // the global counter. Next time accumulateStripHits() is called it will count the sim hits
236  // as though they were on the end of this collection.
237  // Note that this is only used for creating digi-sim links (if configured to do so).
238  // std::cout << "index offset, current hit count = " << crossingSimHitIndexOffset_[tag.encode()] << ", " << simHits->size() << std::endl;
239  if (simHits.isValid())
240  crossingSimHitIndexOffset_[tag.encode()] += simHits->size();
241  }
242  }
243 
244  // ------------ method called to produce the data ------------
246  const TrackerTopology* tTopo = &iSetup.getData(tTopoToken_);
247 
248  std::vector<edm::DetSet<PixelDigi> > theDigiVector;
249  std::vector<edm::DetSet<PixelDigiSimLink> > theDigiLinkVector;
250 
251  if (firstFinalizeEvent_) {
252  _pixeldigialgo->init_DynIneffDB(iSetup);
253  firstFinalizeEvent_ = false;
254  }
255  _pixeldigialgo->calculateInstlumiFactor(PileupInfo_.get());
256 
257  if (_pixeldigialgo->killBadFEDChannels()) {
258  std::unique_ptr<PixelFEDChannelCollection> PixelFEDChannelCollection_ =
259  _pixeldigialgo->chooseScenario(PileupInfo_.get(), randomEngine_);
260  if (PixelFEDChannelCollection_ == nullptr) {
261  throw cms::Exception("NullPointerError") << "PixelFEDChannelCollection not set in chooseScenario function.\n";
262  }
263  iEvent.put(std::move(PixelFEDChannelCollection_));
264  }
265 
266  for (const auto& iu : pDD->detUnits()) {
267  if (iu->type().isTrackerPixel()) {
268  //
269 
270  edm::DetSet<PixelDigi> collector(iu->geographicalId().rawId());
271  edm::DetSet<PixelDigiSimLink> linkcollector(iu->geographicalId().rawId());
272 
273  _pixeldigialgo->digitize(
274  dynamic_cast<const PixelGeomDetUnit*>(iu), collector.data, linkcollector.data, tTopo, randomEngine_);
275  if (!collector.data.empty()) {
276  theDigiVector.push_back(std::move(collector));
277  }
278  if (!linkcollector.data.empty()) {
279  theDigiLinkVector.push_back(std::move(linkcollector));
280  }
281  }
282  }
283 
284  // Step C: create collection with the cache vector of DetSet
285  std::unique_ptr<edm::DetSetVector<PixelDigi> > output(new edm::DetSetVector<PixelDigi>(theDigiVector));
286  std::unique_ptr<edm::DetSetVector<PixelDigiSimLink> > outputlink(
287  new edm::DetSetVector<PixelDigiSimLink>(theDigiLinkVector));
288 
289  // Step D: write output to file
290  iEvent.put(std::move(output));
291  iEvent.put(std::move(outputlink));
292 
293  randomEngine_ = nullptr; // to prevent access outside event
294  }
295 } // namespace cms
EDGetTokenT< ProductType > consumes(edm::InputTag const &tag)
void finalizeEvent(edm::Event &e, edm::EventSetup const &c) override
ESGetTokenH3DDVariant esConsumes(std::string const &Record, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
const edm::ESGetToken< TrackerTopology, TrackerTopologyRcd > tTopoToken_
const TrackerGeometry * pDD
ProductRegistryHelper::BranchAliasSetterT< ProductType > produces()
virtual GlobalVector inTesla(const GlobalPoint &gp) const =0
Field value ad specified global point, in Tesla.
const MagneticField * pSetup
const DetContainer & detUnits() const override
Returm a vector of all GeomDet.
assert(be >=bs)
virtual CLHEP::HepRandomEngine & getEngine(StreamID const &)=0
Use this engine in event methods.
std::unique_ptr< PileupMixingContent > PileupInfo_
unsigned int layer(const DetId &id) const
const std::string hitsProducer
int iEvent
Definition: GenABIO.cc:224
SiPixelDigitizer(const edm::ParameterSet &conf, edm::ProducesCollector, edm::ConsumesCollector &iC)
std::map< unsigned int, PixelGeomDetUnit const * > detectorUnits
void initializeEvent(edm::Event const &e, edm::EventSetup const &c) override
const edm::ESGetToken< TrackerGeometry, TrackerDigiGeometryRecord > pDDToken_
void accumulatePixelHits(edm::Handle< std::vector< PSimHit > >, size_t globalSimHitIndex, const unsigned int tofBin, edm::EventSetup const &c)
bool getData(T &iHolder) const
Definition: EventSetup.h:122
std::unique_ptr< SiPixelDigitizerAlgorithm > _pixeldigialgo
void accumulate(edm::Event const &e, edm::EventSetup const &c) override
Namespace of DDCMS conversion namespace.
Log< level::Info, false > LogInfo
CLHEP::HepRandomEngine * randomEngine_
const edm::ESGetToken< MagneticField, IdealMagneticFieldRecord > pSetupToken_
HLT enums.
const vstring trackerContainers
bool isAvailable() const
Definition: Service.h:40
def move(src, dest)
Definition: eostools.py:511
bool isTrackerPixel(GeomDetEnumerators::SubDetector m)
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)