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 
47 
50 
52 // user include files
55 
58 
61 
65 //Random Number
70 
71 //
72 // constants, enums and typedefs
73 //
74 
75 //
76 // static data member definitions
77 //
78 
79 //
80 // constructors and destructor
81 //
82 //using namespace std;
83 
84 namespace cms {
86  edm::ProducesCollector producesCollector,
88  : firstInitializeEvent_(true),
89  firstFinalizeEvent_(true),
90  _pixeldigialgo(),
91  hitsProducer(iConfig.getParameter<std::string>("hitsProducer")),
92  trackerContainers(iConfig.getParameter<std::vector<std::string> >("RoutList")),
93  geometryType(iConfig.getParameter<std::string>("PixGeometryType")),
94  pilotBlades(iConfig.exists("enablePilotBlades") ? iConfig.getParameter<bool>("enablePilotBlades") : false),
95  NumberOfEndcapDisks(iConfig.exists("NumPixelEndcap") ? iConfig.getParameter<int>("NumPixelEndcap") : 2) {
96  edm::LogInfo("PixelDigitizer ") << "Enter the Pixel Digitizer";
97 
98  const std::string alias("simSiPixelDigis");
99 
100  producesCollector.produces<edm::DetSetVector<PixelDigi> >().setBranchAlias(alias);
101  producesCollector.produces<edm::DetSetVector<PixelDigiSimLink> >().setBranchAlias(alias + "siPixelDigiSimLink");
102 
103  for (auto const& trackerContainer : trackerContainers) {
104  edm::InputTag tag(hitsProducer, trackerContainer);
105  iC.consumes<std::vector<PSimHit> >(edm::InputTag(hitsProducer, trackerContainer));
106  }
108  if (!rng.isAvailable()) {
109  throw cms::Exception("Configuration")
110  << "SiPixelDigitizer requires the RandomNumberGeneratorService\n"
111  "which is not present in the configuration file. You must add the service\n"
112  "in the configuration file or remove the modules that require it.";
113  }
114 
115  _pixeldigialgo.reset(new SiPixelDigitizerAlgorithm(iConfig));
116  if (NumberOfEndcapDisks != 2)
117  producesCollector.produces<PixelFEDChannelCollection>();
118  }
119 
120  SiPixelDigitizer::~SiPixelDigitizer() { edm::LogInfo("PixelDigitizer ") << "Destruct the Pixel Digitizer"; }
121 
122  //
123  // member functions
124  //
125 
126  void SiPixelDigitizer::accumulatePixelHits(edm::Handle<std::vector<PSimHit> > hSimHits,
127  size_t globalSimHitIndex,
128  const unsigned int tofBin,
129  edm::EventSetup const& iSetup) {
130  if (hSimHits.isValid()) {
131  std::set<unsigned int> detIds;
132  std::vector<PSimHit> const& simHits = *hSimHits.product();
134  iSetup.get<TrackerTopologyRcd>().get(tTopoHand);
135  const TrackerTopology* tTopo = tTopoHand.product();
136  for (std::vector<PSimHit>::const_iterator it = simHits.begin(), itEnd = simHits.end(); it != itEnd;
137  ++it, ++globalSimHitIndex) {
138  unsigned int detId = (*it).detUnitId();
139  if (detIds.insert(detId).second) {
140  // The insert succeeded, so this detector element has not yet been processed.
141  assert(detectorUnits[detId]);
142  if (detectorUnits[detId] &&
143  detectorUnits[detId]
144  ->type()
145  .isTrackerPixel()) { // this test could be avoided and changed into a check of pixdet!=0
146  std::map<unsigned int, PixelGeomDetUnit const*>::iterator itDet = detectorUnits.find(detId);
147  if (itDet == detectorUnits.end())
148  continue;
149  auto pixdet = itDet->second;
150  assert(pixdet != nullptr);
151  //access to magnetic field in global coordinates
152  GlobalVector bfield = pSetup->inTesla(pixdet->surface().position());
153  LogDebug("PixelDigitizer ") << "B-field(T) at " << pixdet->surface().position()
154  << "(cm): " << pSetup->inTesla(pixdet->surface().position());
155  _pixeldigialgo->accumulateSimHits(
156  it, itEnd, globalSimHitIndex, tofBin, pixdet, bfield, tTopo, randomEngine_);
157  }
158  }
159  }
160  }
161  }
162 
164  if (firstInitializeEvent_) {
165  _pixeldigialgo->init(iSetup);
166  firstInitializeEvent_ = false;
167  }
168 
169  // Make sure that the first crossing processed starts indexing the sim hits from zero.
170  // This variable is used so that the sim hits from all crossing frames have sequential
171  // indices used to create the digi-sim link (if configured to do so) rather than starting
172  // from zero for each crossing.
174 
175  // Cache random number engine
177  randomEngine_ = &rng->getEngine(e.streamID());
178 
179  _pixeldigialgo->initializeEvent();
181  iSetup.get<IdealMagneticFieldRecord>().get(pSetup);
183  iSetup.get<TrackerTopologyRcd>().get(tTopoHand);
184  const TrackerTopology* tTopo = tTopoHand.product();
185 
186  // FIX THIS! We only need to clear and (re)fill this map when the geometry type IOV changes. Use ESWatcher to determine this.
187  if (true) { // Replace with ESWatcher
188  detectorUnits.clear();
189  for (const auto& iu : pDD->detUnits()) {
190  unsigned int detId = iu->geographicalId().rawId();
191  if (iu->type().isTrackerPixel()) {
192  auto pixdet = dynamic_cast<const PixelGeomDetUnit*>(iu);
193  assert(pixdet != nullptr);
194  if (iu->subDetector() ==
195  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)))
199  continue;
200  }
201  detectorUnits.insert(std::make_pair(detId, pixdet));
202  }
203  }
204  }
205  }
206 
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)
216  tofBin = PixelDigiSimLink::HighTof;
217  accumulatePixelHits(simHits, crossingSimHitIndexOffset_[tag.encode()], tofBin, iSetup);
218  // Now that the hits have been processed, I'll add the amount of hits in this crossing on to
219  // the global counter. Next time accumulateStripHits() is called it will count the sim hits
220  // as though they were on the end of this collection.
221  // Note that this is only used for creating digi-sim links (if configured to do so).
222  // std::cout << "index offset, current hit count = " << crossingSimHitIndexOffset_[tag.encode()] << ", " << simHits->size() << std::endl;
223  if (simHits.isValid())
224  crossingSimHitIndexOffset_[tag.encode()] += simHits->size();
225  }
226  }
227 
229  edm::EventSetup const& iSetup,
230  edm::StreamID const& streamID) {
231  // Step A: Get Inputs
232  for (vstring::const_iterator i = trackerContainers.begin(), iEnd = trackerContainers.end(); i != iEnd; ++i) {
235 
236  iEvent.getByLabel(tag, simHits);
237  unsigned int tofBin = PixelDigiSimLink::LowTof;
238  if ((*i).find(std::string("HighTof")) != std::string::npos)
239  tofBin = PixelDigiSimLink::HighTof;
240  accumulatePixelHits(simHits, crossingSimHitIndexOffset_[tag.encode()], tofBin, iSetup);
241  // Now that the hits have been processed, I'll add the amount of hits in this crossing on to
242  // the global counter. Next time accumulateStripHits() is called it will count the sim hits
243  // as though they were on the end of this collection.
244  // Note that this is only used for creating digi-sim links (if configured to do so).
245  // std::cout << "index offset, current hit count = " << crossingSimHitIndexOffset_[tag.encode()] << ", " << simHits->size() << std::endl;
246  if (simHits.isValid())
247  crossingSimHitIndexOffset_[tag.encode()] += simHits->size();
248  }
249  }
250 
251  // ------------ method called to produce the data ------------
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 
260  if (firstFinalizeEvent_) {
261  const unsigned int bunchspace = PileupInfo_->getMix_bunchSpacing();
262  _pixeldigialgo->init_DynIneffDB(iSetup, bunchspace);
263  firstFinalizeEvent_ = false;
264  }
265  _pixeldigialgo->calculateInstlumiFactor(PileupInfo_.get());
266 
267  if (_pixeldigialgo->killBadFEDChannels()) {
268  std::unique_ptr<PixelFEDChannelCollection> PixelFEDChannelCollection_ =
269  _pixeldigialgo->chooseScenario(PileupInfo_.get(), randomEngine_);
270  if (PixelFEDChannelCollection_ == nullptr) {
271  throw cms::Exception("NullPointerError") << "PixelFEDChannelCollection not set in chooseScenario function.\n";
272  }
273  iEvent.put(std::move(PixelFEDChannelCollection_));
274  }
275 
276  for (const auto& iu : pDD->detUnits()) {
277  if (iu->type().isTrackerPixel()) {
278  //
279 
280  edm::DetSet<PixelDigi> collector(iu->geographicalId().rawId());
281  edm::DetSet<PixelDigiSimLink> linkcollector(iu->geographicalId().rawId());
282 
283  _pixeldigialgo->digitize(
284  dynamic_cast<const PixelGeomDetUnit*>(iu), collector.data, linkcollector.data, tTopo, randomEngine_);
285  if (!collector.data.empty()) {
286  theDigiVector.push_back(std::move(collector));
287  }
288  if (!linkcollector.data.empty()) {
289  theDigiLinkVector.push_back(std::move(linkcollector));
290  }
291  }
292  }
293 
294  // Step C: create collection with the cache vector of DetSet
295  std::unique_ptr<edm::DetSetVector<PixelDigi> > output(new edm::DetSetVector<PixelDigi>(theDigiVector));
296  std::unique_ptr<edm::DetSetVector<PixelDigiSimLink> > outputlink(
297  new edm::DetSetVector<PixelDigiSimLink>(theDigiLinkVector));
298 
299  // Step D: write output to file
300  iEvent.put(std::move(output));
301  iEvent.put(std::move(outputlink));
302 
303  randomEngine_ = nullptr; // to prevent access outside event
304  }
305 } // namespace cms
#define LogDebug(id)
EDGetTokenT< ProductType > consumes(edm::InputTag const &tag)
type
Definition: HCALResponse.h:21
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:131
const DetContainer & detUnits() const override
Returm a vector of all GeomDet.
ProductRegistryHelper::BranchAliasSetterT< ProductType > produces()
edm::ESHandle< MagneticField > pSetup
virtual CLHEP::HepRandomEngine & getEngine(StreamID const &)=0
Use this engine in event methods.
std::unique_ptr< PileupMixingContent > PileupInfo_
std::string encode() const
Definition: InputTag.cc:159
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
void accumulatePixelHits(edm::Handle< std::vector< PSimHit > >, size_t globalSimHitIndex, const unsigned int tofBin, edm::EventSetup const &c)
edm::ESHandle< TrackerGeometry > pDD
bool isValid() const
Definition: HandleBase.h:70
std::unique_ptr< SiPixelDigitizerAlgorithm > _pixeldigialgo
bool getByLabel(InputTag const &tag, Handle< PROD > &result) const
Definition: Event.h:488
virtual GlobalVector inTesla(const GlobalPoint &gp) const =0
Field value ad specified global point, in Tesla.
void accumulate(edm::Event const &e, edm::EventSetup const &c) override
Namespace of DDCMS conversion namespace.
CLHEP::HepRandomEngine * randomEngine_
const std::string geometryType
unsigned int layer(const DetId &id) const
const vstring trackerContainers
bool getByLabel(edm::InputTag const &tag, edm::Handle< T > &result) const
T get() const
Definition: EventSetup.h:73
StreamID streamID() const
Definition: Event.h:96
T const * product() const
Definition: ESHandle.h:86
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. ...