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 
21 // system include files
22 #include <memory>
23 #include <set>
24 
25 // user include files
26 #include "SiPixelDigitizer.h"
28 
49 
52 
54 // user include files
57 
60 
63 
66 
67 //Random Number
72 
73 namespace CLHEP {
74  class HepRandomEngine;
75 }
76 
77 
78 //
79 // constants, enums and typedefs
80 //
81 
82 //
83 // static data member definitions
84 //
85 
86 //
87 // constructors and destructor
88 //
89 //using namespace std;
90 
91 
92 namespace cms
93 {
94  SiPixelDigitizer::SiPixelDigitizer(const edm::ParameterSet& iConfig, edm::stream::EDProducerBase& mixMod, edm::ConsumesCollector& iC):
95  firstInitializeEvent_(true),
96  firstFinalizeEvent_(true),
97  _pixeldigialgo(),
98  hitsProducer(iConfig.getParameter<std::string>("hitsProducer")),
99  trackerContainers(iConfig.getParameter<std::vector<std::string> >("RoutList")),
100  geometryType(iConfig.getParameter<std::string>("PixGeometryType")),
101  pilotBlades(iConfig.exists("enablePilotBlades")?iConfig.getParameter<bool>("enablePilotBlades"):false),
102  NumberOfEndcapDisks(iConfig.exists("NumPixelEndcap")?iConfig.getParameter<int>("NumPixelEndcap"):2)
103  {
104  edm::LogInfo ("PixelDigitizer ") <<"Enter the Pixel Digitizer";
105 
106  const std::string alias ("simSiPixelDigis");
107 
108  mixMod.produces<edm::DetSetVector<PixelDigi> >().setBranchAlias(alias);
109  mixMod.produces<edm::DetSetVector<PixelDigiSimLink> >().setBranchAlias(alias + "siPixelDigiSimLink");
110  for(auto const& trackerContainer : trackerContainers) {
111  edm::InputTag tag(hitsProducer, trackerContainer);
112  iC.consumes<std::vector<PSimHit> >(edm::InputTag(hitsProducer, trackerContainer));
113  }
115  if ( ! rng.isAvailable()) {
116  throw cms::Exception("Configuration")
117  << "SiPixelDigitizer requires the RandomNumberGeneratorService\n"
118  "which is not present in the configuration file. You must add the service\n"
119  "in the configuration file or remove the modules that require it.";
120  }
121 
122  _pixeldigialgo.reset(new SiPixelDigitizerAlgorithm(iConfig));
123  }
124 
126  edm::LogInfo ("PixelDigitizer ") <<"Destruct the Pixel Digitizer";
127  }
128 
129 
130  //
131  // member functions
132  //
133 
134  void
135  SiPixelDigitizer::accumulatePixelHits(edm::Handle<std::vector<PSimHit> > hSimHits,
136  size_t globalSimHitIndex,
137  const unsigned int tofBin,
138  CLHEP::HepRandomEngine* engine,
139  edm::EventSetup const& iSetup) {
140  if(hSimHits.isValid()) {
141  std::set<unsigned int> detIds;
142  std::vector<PSimHit> const& simHits = *hSimHits.product();
144  iSetup.get<TrackerTopologyRcd>().get(tTopoHand);
145  const TrackerTopology *tTopo=tTopoHand.product();
146  for(std::vector<PSimHit>::const_iterator it = simHits.begin(), itEnd = simHits.end(); it != itEnd; ++it, ++globalSimHitIndex) {
147  unsigned int detId = (*it).detUnitId();
148  if(detIds.insert(detId).second) {
149  // The insert succeeded, so this detector element has not yet been processed.
150  assert(detectorUnits[detId]);
151  if(detectorUnits[detId] && detectorUnits[detId]->type().isTrackerPixel()) { // this test could be avoided and changed into a check of pixdet!=0
152  std::map<unsigned int, PixelGeomDetUnit const *>::iterator itDet = detectorUnits.find(detId);
153  if (itDet == detectorUnits.end()) continue;
154  auto pixdet = itDet->second;
155  assert(pixdet !=0);
156  //access to magnetic field in global coordinates
157  GlobalVector bfield = pSetup->inTesla(pixdet->surface().position());
158  LogDebug ("PixelDigitizer ") << "B-field(T) at " << pixdet->surface().position() << "(cm): "
159  << pSetup->inTesla(pixdet->surface().position());
160  _pixeldigialgo->accumulateSimHits(it, itEnd, globalSimHitIndex, tofBin, pixdet, bfield, tTopo, engine);
161  }
162  }
163  }
164  }
165  }
166 
167  void
170  _pixeldigialgo->init(iSetup);
171  firstInitializeEvent_ = false;
172  }
173 
174  // Make sure that the first crossing processed starts indexing the sim hits from zero.
175  // This variable is used so that the sim hits from all crossing frames have sequential
176  // indices used to create the digi-sim link (if configured to do so) rather than starting
177  // from zero for each crossing.
179 
180  _pixeldigialgo->initializeEvent();
182  iSetup.get<IdealMagneticFieldRecord>().get(pSetup);
184  iSetup.get<TrackerTopologyRcd>().get(tTopoHand);
185  const TrackerTopology *tTopo=tTopoHand.product();
186 
187  // FIX THIS! We only need to clear and (re)fill this map when the geometry type IOV changes. Use ESWatcher to determine this.
188  if(true) { // Replace with ESWatcher
189  detectorUnits.clear();
190  for(TrackingGeometry::DetUnitContainer::const_iterator iu = pDD->detUnits().begin(); iu != pDD->detUnits().end(); ++iu) {
191  unsigned int detId = (*iu)->geographicalId().rawId();
192  if((*iu)->type().isTrackerPixel()) {
193  auto pixdet = dynamic_cast<const PixelGeomDetUnit*>((*iu));
194  assert(pixdet != 0);
195  if ((*iu)->subDetector()==GeomDetEnumerators::SubDetector::PixelEndcap) { // true ONLY for the phase 0 pixel deetctor
196  unsigned int disk = tTopo->layer(detId); // using the generic layer method
197  //if using pilot blades, then allowing it for current detector only
198  if ((disk == 3)&&((!pilotBlades)&&(NumberOfEndcapDisks == 2))) continue;
199  }
200  detectorUnits.insert(std::make_pair(detId, pixdet));
201  }
202  }
203  }
204  }
205 
206  void
208  // Step A: Get Inputs
209  for(vstring::const_iterator i = trackerContainers.begin(), iEnd = trackerContainers.end(); i != iEnd; ++i) {
212 
213  iEvent.getByLabel(tag, simHits);
214  unsigned int tofBin = PixelDigiSimLink::LowTof;
215  if ((*i).find(std::string("HighTof")) != std::string::npos) tofBin = PixelDigiSimLink::HighTof;
216  accumulatePixelHits(simHits, crossingSimHitIndexOffset_[tag.encode()], tofBin, randomEngine(iEvent.streamID()), iSetup);
217  // Now that the hits have been processed, I'll add the amount of hits in this crossing on to
218  // the global counter. Next time accumulateStripHits() is called it will count the sim hits
219  // as though they were on the end of this collection.
220  // Note that this is only used for creating digi-sim links (if configured to do so).
221 // std::cout << "index offset, current hit count = " << crossingSimHitIndexOffset_[tag.encode()] << ", " << simHits->size() << std::endl;
222  if( simHits.isValid() ) crossingSimHitIndexOffset_[tag.encode()]+=simHits->size();
223  }
224  }
225 
226  void
228  // Step A: Get Inputs
229  for(vstring::const_iterator i = trackerContainers.begin(), iEnd = trackerContainers.end(); i != iEnd; ++i) {
232 
233  iEvent.getByLabel(tag, simHits);
234  unsigned int tofBin = PixelDigiSimLink::LowTof;
235  if ((*i).find(std::string("HighTof")) != std::string::npos) tofBin = PixelDigiSimLink::HighTof;
236  accumulatePixelHits(simHits, crossingSimHitIndexOffset_[tag.encode()], tofBin, randomEngine(streamID), iSetup);
237  // Now that the hits have been processed, I'll add the amount of hits in this crossing on to
238  // the global counter. Next time accumulateStripHits() is called it will count the sim hits
239  // as though they were on the end of this collection.
240  // Note that this is only used for creating digi-sim links (if configured to do so).
241 // std::cout << "index offset, current hit count = " << crossingSimHitIndexOffset_[tag.encode()] << ", " << simHits->size() << std::endl;
242  if( simHits.isValid() ) crossingSimHitIndexOffset_[tag.encode()]+=simHits->size();
243  }
244  }
245 
246  // ------------ method called to produce the data ------------
247  void
249 
251  CLHEP::HepRandomEngine* engine = &rng->getEngine(iEvent.streamID());
252 
254  iSetup.get<TrackerTopologyRcd>().get(tTopoHand);
255  const TrackerTopology *tTopo=tTopoHand.product();
256 
257  std::vector<edm::DetSet<PixelDigi> > theDigiVector;
258  std::vector<edm::DetSet<PixelDigiSimLink> > theDigiLinkVector;
259 
261  if (firstFinalizeEvent_) {
262  const unsigned int bunchspace = PileupInfo_->getMix_bunchSpacing();
263  _pixeldigialgo->init_DynIneffDB(iSetup, bunchspace);
264  firstFinalizeEvent_ = false;
265  }
266  _pixeldigialgo->calculateInstlumiFactor(PileupInfo_);
267 
268  for(TrackingGeometry::DetUnitContainer::const_iterator iu = pDD->detUnits().begin(); iu != pDD->detUnits().end(); iu ++){
269 
270  if((*iu)->type().isTrackerPixel()) {
271 
272  //
273 
274  edm::DetSet<PixelDigi> collector((*iu)->geographicalId().rawId());
275  edm::DetSet<PixelDigiSimLink> linkcollector((*iu)->geographicalId().rawId());
276 
277 
278  _pixeldigialgo->digitize(dynamic_cast<const PixelGeomDetUnit*>((*iu)),
279  collector.data,
280  linkcollector.data,
281  tTopo,
282  engine);
283  if(collector.data.size() > 0) {
284  theDigiVector.push_back(std::move(collector));
285  }
286  if(linkcollector.data.size() > 0) {
287  theDigiLinkVector.push_back(std::move(linkcollector));
288  }
289  }
290  }
291 
292  // Step C: create collection with the cache vector of DetSet
293  std::unique_ptr<edm::DetSetVector<PixelDigi> >
294  output(new edm::DetSetVector<PixelDigi>(theDigiVector) );
295  std::unique_ptr<edm::DetSetVector<PixelDigiSimLink> >
296  outputlink(new edm::DetSetVector<PixelDigiSimLink>(theDigiLinkVector) );
297 
298  // Step D: write output to file
299  iEvent.put(std::move(output));
300  iEvent.put(std::move(outputlink));
301  }
302 
303  CLHEP::HepRandomEngine* SiPixelDigitizer::randomEngine(edm::StreamID const& streamID) {
304  unsigned int index = streamID.value();
305  if(index >= randomEngines_.size()) {
306  randomEngines_.resize(index + 1, nullptr);
307  }
308  CLHEP::HepRandomEngine* ptr = randomEngines_[index];
309  if(!ptr) {
311  ptr = &rng->getEngine(streamID);
312  randomEngines_[index] = ptr;
313  }
314  return ptr;
315  }
316 
317 }// end namespace cms::
318 
#define LogDebug(id)
EDGetTokenT< ProductType > consumes(edm::InputTag const &tag)
type
Definition: HCALResponse.h:21
virtual void finalizeEvent(edm::Event &e, edm::EventSetup const &c) override
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:122
CLHEP::HepRandomEngine * randomEngine(edm::StreamID const &streamID)
std::vector< CLHEP::HepRandomEngine * > randomEngines_
std::map< unsigned int, PixelGeomDetUnit const * > detectorUnits
edm::ESHandle< MagneticField > pSetup
virtual CLHEP::HepRandomEngine & getEngine(StreamID const &)=0
Use this engine in event methods.
std::string encode() const
Definition: InputTag.cc:165
virtual PileupMixingContent * getEventPileupInfo() override
const std::string hitsProducer
int iEvent
Definition: GenABIO.cc:230
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. ...
bunchspace
in terms of 25 ns
virtual 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, CLHEP::HepRandomEngine *, edm::EventSetup const &c)
edm::ESHandle< TrackerGeometry > pDD
bool isValid() const
Definition: HandleBase.h:74
std::unique_ptr< SiPixelDigitizerAlgorithm > _pixeldigialgo
bool getByLabel(InputTag const &tag, Handle< PROD > &result) const
Definition: Event.h:416
virtual GlobalVector inTesla(const GlobalPoint &gp) const =0
Field value ad specified global point, in Tesla.
virtual void accumulate(edm::Event const &e, edm::EventSetup const &c) override
unsigned int value() const
Definition: StreamID.h:46
const T & get() const
Definition: EventSetup.h:56
const std::string geometryType
bool isTrackerPixel(const GeomDetEnumerators::SubDetector m)
PileupMixingContent * PileupInfo_
unsigned int layer(const DetId &id) const
const vstring trackerContainers
bool getByLabel(edm::InputTag const &tag, edm::Handle< T > &result) const
StreamID streamID() const
Definition: Event.h:81
const int & getMix_bunchSpacing() const
T const * product() const
Definition: ESHandle.h:86
def move(src, dest)
Definition: eostools.py:510
const DetUnitContainer & detUnits() const
Returm a vector of all GeomDetUnit.