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