CMS 3D CMS Logo

SiStripDigitizer.cc
Go to the documentation of this file.
1 // File: SiStripDigitizerAlgorithm.cc
2 // Description: Class for digitization.
3 
4 // Modified 15/May/2013 mark.grimes@bristol.ac.uk - Modified so that the digi-sim link has the correct
5 // index for the sim hits stored. It was previously always set to zero (I won't mention that it was
6 // me who originally wrote that).
7 
8 // system include files
9 #include <memory>
10 
12 
13 #include "SiStripDigitizer.h"
16 
21 
22 // user include files
25 
28 
32 
34 //needed for the geometry:
44 //needed for the magnetic field:
47 
48 //Data Base infromations
52 
53 //Random Number
57 
59  gainLabel(conf.getParameter<std::string>("Gain")),
60  hitsProducer(conf.getParameter<std::string>("hitsProducer")),
61  trackerContainers(conf.getParameter<std::vector<std::string> >("ROUList")),
62  ZSDigi(conf.getParameter<edm::ParameterSet>("DigiModeList").getParameter<std::string>("ZSDigi")),
63  SCDigi(conf.getParameter<edm::ParameterSet>("DigiModeList").getParameter<std::string>("SCDigi")),
64  VRDigi(conf.getParameter<edm::ParameterSet>("DigiModeList").getParameter<std::string>("VRDigi")),
65  PRDigi(conf.getParameter<edm::ParameterSet>("DigiModeList").getParameter<std::string>("PRDigi")),
66  geometryType(conf.getParameter<std::string>("GeometryType")),
67  useConfFromDB(conf.getParameter<bool>("TrackerConfigurationFromDB")),
68  zeroSuppression(conf.getParameter<bool>("ZeroSuppression")),
69  makeDigiSimLinks_(conf.getUntrackedParameter<bool>("makeDigiSimLinks", false))
70 {
71  const std::string alias("simSiStripDigis");
72 
73  mixMod.produces<edm::DetSetVector<SiStripDigi> >(ZSDigi).setBranchAlias(ZSDigi);
74  mixMod.produces<edm::DetSetVector<SiStripRawDigi> >(SCDigi).setBranchAlias(alias + SCDigi);
75  mixMod.produces<edm::DetSetVector<SiStripRawDigi> >(VRDigi).setBranchAlias(alias + VRDigi);
76  mixMod.produces<edm::DetSetVector<SiStripRawDigi> >(PRDigi).setBranchAlias(alias + PRDigi);
77  mixMod.produces<edm::DetSetVector<StripDigiSimLink> >().setBranchAlias(alias + "siStripDigiSimLink");
78  mixMod.produces<std::vector<std::pair<int,std::bitset<6>>>>("AffectedAPVList").setBranchAlias(alias + "AffectedAPV");
79  for(auto const& trackerContainer : trackerContainers) {
80  edm::InputTag tag(hitsProducer, trackerContainer);
81  iC.consumes<std::vector<PSimHit> >(edm::InputTag(hitsProducer, trackerContainer));
82  }
84  if ( ! rng.isAvailable()) {
85  throw cms::Exception("Configuration")
86  << "SiStripDigitizer requires the RandomNumberGeneratorService\n"
87  "which is not present in the configuration file. You must add the service\n"
88  "in the configuration file or remove the modules that require it.";
89  }
90  theDigiAlgo.reset(new SiStripDigitizerAlgorithm(conf));
91 }
92 
93 // Virtual destructor needed.
95 }
96 
97 void SiStripDigitizer::accumulateStripHits(edm::Handle<std::vector<PSimHit> > hSimHits,
98  const TrackerTopology *tTopo, size_t globalSimHitIndex, const unsigned int tofBin) {
99  // globalSimHitIndex is the index the sim hit will have when it is put in a collection
100  // of sim hits for all crossings. This is only used when creating digi-sim links if
101  // configured to do so.
102 
103  if(hSimHits.isValid()) {
104  std::set<unsigned int> detIds;
105  std::vector<PSimHit> const& simHits = *hSimHits.product();
106  for(std::vector<PSimHit>::const_iterator it = simHits.begin(), itEnd = simHits.end(); it != itEnd; ++it, ++globalSimHitIndex ) {
107  unsigned int detId = (*it).detUnitId();
108  if(detIds.insert(detId).second) {
109  // The insert succeeded, so this detector element has not yet been processed.
110  assert(detectorUnits[detId]);
111  if(detectorUnits[detId]->type().isTrackerStrip()) { // this test can be removed and replaced by stripdet!=0
112  auto stripdet = detectorUnits[detId];
113  //access to magnetic field in global coordinates
114  GlobalVector bfield = pSetup->inTesla(stripdet->surface().position());
115  LogDebug ("Digitizer ") << "B-field(T) at " << stripdet->surface().position() << "(cm): "
116  << pSetup->inTesla(stripdet->surface().position());
117  theDigiAlgo->accumulateSimHits(it, itEnd, globalSimHitIndex, tofBin, stripdet, bfield, tTopo, randomEngine_);
118  }
119  }
120  } // end of loop over sim hits
121  }
122 }
123 
124 // Functions that gets called by framework every event
125  void
127  //Retrieve tracker topology from geometry
129  iSetup.get<TrackerTopologyRcd>().get(tTopoHand);
130  const TrackerTopology *tTopo=tTopoHand.product();
131 
132  // Step A: Get Inputs
133  for(auto const& trackerContainer : trackerContainers) {
135  edm::InputTag tag(hitsProducer, trackerContainer);
136  unsigned int tofBin = StripDigiSimLink::LowTof;
137  if (trackerContainer.find(std::string("HighTof")) != std::string::npos) tofBin = StripDigiSimLink::HighTof;
138 
139  iEvent.getByLabel(tag, simHits);
140  accumulateStripHits(simHits,tTopo,crossingSimHitIndexOffset_[tag.encode()], tofBin);
141  // Now that the hits have been processed, I'll add the amount of hits in this crossing on to
142  // the global counter. Next time accumulateStripHits() is called it will count the sim hits
143  // as though they were on the end of this collection.
144  // Note that this is only used for creating digi-sim links (if configured to do so).
145  if( simHits.isValid() ) crossingSimHitIndexOffset_[tag.encode()]+=simHits->size();
146  }
147  }
148 
149  void
151 
153  iSetup.get<TrackerTopologyRcd>().get(tTopoHand);
154  const TrackerTopology *tTopo=tTopoHand.product();
155 
156  //Re-compute luminosity for accumulation for HIP effects
158  theDigiAlgo->calculateInstlumiScale(PileupInfo_);
159 
160  // Step A: Get Inputs
161  for(auto const& trackerContainer : trackerContainers) {
163  edm::InputTag tag(hitsProducer, trackerContainer);
164  unsigned int tofBin = StripDigiSimLink::LowTof;
165  if (trackerContainer.find(std::string("HighTof")) != std::string::npos) tofBin = StripDigiSimLink::HighTof;
166 
167  iEvent.getByLabel(tag, simHits);
168  accumulateStripHits(simHits,tTopo,crossingSimHitIndexOffset_[tag.encode()], tofBin);
169  // Now that the hits have been processed, I'll add the amount of hits in this crossing on to
170  // the global counter. Next time accumulateStripHits() is called it will count the sim hits
171  // as though they were on the end of this collection.
172  // Note that this is only used for creating digi-sim links (if configured to do so).
173  if( simHits.isValid() ) crossingSimHitIndexOffset_[tag.encode()]+=simHits->size();
174  }
175  }
176 
177 
179  // Make sure that the first crossing processed starts indexing the sim hits from zero.
180  // This variable is used so that the sim hits from all crossing frames have sequential
181  // indices used to create the digi-sim link (if configured to do so) rather than starting
182  // from zero for each crossing.
184  theAffectedAPVvector.clear();
185  // Step A: Get Inputs
186 
187  if(useConfFromDB){
189  iSetup.get<SiStripDetCablingRcd>().get(detCabling);
190  detCabling->addConnected(theDetIdList);
191  }
192 
193  // Cache random number engine
195  randomEngine_ = &rng->getEngine(iEvent.streamID());
196 
197  theDigiAlgo->initializeEvent(iSetup);
198 
200  iSetup.get<IdealMagneticFieldRecord>().get(pSetup);
201 
202  // FIX THIS! We only need to clear and (re)fill detectorUnits when the geometry type IOV changes. Use ESWatcher to determine this.
203  bool changes = true;
204  if(changes) { // Replace with ESWatcher
205  detectorUnits.clear();
206  }
207  for( const auto& iu : pDD->detUnits()) {
208  unsigned int detId = iu->geographicalId().rawId();
209  if(iu->type().isTrackerStrip()) {
210  auto stripdet = dynamic_cast<StripGeomDetUnit const*>(iu);
211  assert(stripdet != nullptr);
212  if(changes) { // Replace with ESWatcher
213  detectorUnits.insert(std::make_pair(detId, stripdet));
214  }
215  theDigiAlgo->initializeDetUnit(stripdet, iSetup);
216  }
217  }
218 }
219 
221  edm::ESHandle<SiStripGain> gainHandle;
222  edm::ESHandle<SiStripNoises> noiseHandle;
223  edm::ESHandle<SiStripThreshold> thresholdHandle;
224  edm::ESHandle<SiStripPedestals> pedestalHandle;
225  iSetup.get<SiStripGainSimRcd>().get(gainLabel,gainHandle);
226  iSetup.get<SiStripNoisesRcd>().get(noiseHandle);
227  iSetup.get<SiStripThresholdRcd>().get(thresholdHandle);
228  iSetup.get<SiStripPedestalsRcd>().get(pedestalHandle);
229 
230  std::vector<edm::DetSet<SiStripDigi> > theDigiVector;
231  std::vector<edm::DetSet<SiStripRawDigi> > theRawDigiVector;
232  std::unique_ptr< edm::DetSetVector<StripDigiSimLink> > pOutputDigiSimLink( new edm::DetSetVector<StripDigiSimLink> );
233 
234 
235  // Step B: LOOP on StripGeomDetUnit
236  theDigiVector.reserve(10000);
237  theDigiVector.clear();
238 
239  for( const auto& iu : pDD->detUnits()) {
240  if(useConfFromDB){
241  //apply the cable map _before_ digitization: consider only the detis that are connected
242  if(theDetIdList.find(iu->geographicalId().rawId())==theDetIdList.end())
243  continue;
244  }
245  auto sgd = dynamic_cast<StripGeomDetUnit const*>(iu);
246  if (sgd != nullptr){
247  edm::DetSet<SiStripDigi> collectorZS(iu->geographicalId().rawId());
248  edm::DetSet<SiStripRawDigi> collectorRaw(iu->geographicalId().rawId());
249  edm::DetSet<StripDigiSimLink> collectorLink(iu->geographicalId().rawId());
250  theDigiAlgo->digitize(collectorZS,collectorRaw,collectorLink,sgd,
251  gainHandle,thresholdHandle,noiseHandle,pedestalHandle,theAffectedAPVvector,randomEngine_);
252  if(zeroSuppression){
253  if(!collectorZS.data.empty()){
254  theDigiVector.push_back(collectorZS);
255  if( !collectorLink.data.empty() ) pOutputDigiSimLink->insert(collectorLink);
256  }
257  }else{
258  if(!collectorRaw.data.empty()){
259  theRawDigiVector.push_back(collectorRaw);
260  if( !collectorLink.data.empty() ) pOutputDigiSimLink->insert(collectorLink);
261  }
262  }
263  }
264  }
265  if(zeroSuppression){
266  // Step C: create output collection
267  std::unique_ptr<edm::DetSetVector<SiStripRawDigi> > output_virginraw(new edm::DetSetVector<SiStripRawDigi>());
268  std::unique_ptr<edm::DetSetVector<SiStripRawDigi> > output_scopemode(new edm::DetSetVector<SiStripRawDigi>());
269  std::unique_ptr<edm::DetSetVector<SiStripRawDigi> > output_processedraw(new edm::DetSetVector<SiStripRawDigi>());
270  std::unique_ptr<edm::DetSetVector<SiStripDigi> > output(new edm::DetSetVector<SiStripDigi>(theDigiVector) );
271  std::unique_ptr<std::vector<std::pair<int,std::bitset<6>>> > AffectedAPVList(new std::vector<std::pair<int,std::bitset<6>>>(theAffectedAPVvector));
272  // Step D: write output to file
273  iEvent.put(std::move(output), ZSDigi);
274  iEvent.put(std::move(output_scopemode), SCDigi);
275  iEvent.put(std::move(output_virginraw), VRDigi);
276  iEvent.put(std::move(output_processedraw), PRDigi);
277  iEvent.put(std::move(AffectedAPVList),"AffectedAPVList");
278  if( makeDigiSimLinks_ ) iEvent.put(std::move(pOutputDigiSimLink)); // The previous EDProducer didn't name this collection so I won't either
279  }else{
280  // Step C: create output collection
281  std::unique_ptr<edm::DetSetVector<SiStripRawDigi> > output_virginraw(new edm::DetSetVector<SiStripRawDigi>(theRawDigiVector));
282  std::unique_ptr<edm::DetSetVector<SiStripRawDigi> > output_scopemode(new edm::DetSetVector<SiStripRawDigi>());
283  std::unique_ptr<edm::DetSetVector<SiStripRawDigi> > output_processedraw(new edm::DetSetVector<SiStripRawDigi>());
284  std::unique_ptr<edm::DetSetVector<SiStripDigi> > output(new edm::DetSetVector<SiStripDigi>() );
285  // Step D: write output to file
286  iEvent.put(std::move(output), ZSDigi);
287  iEvent.put(std::move(output_scopemode), SCDigi);
288  iEvent.put(std::move(output_virginraw), VRDigi);
289  iEvent.put(std::move(output_processedraw), PRDigi);
290  if( makeDigiSimLinks_ ) iEvent.put(std::move(pOutputDigiSimLink)); // The previous EDProducer didn't name this collection so I won't either
291  }
292  randomEngine_ = nullptr; // to prevent access outside event
293 }
#define LogDebug(id)
BranchAliasSetterT< ProductType > produces()
declare what type of product will make and with which optional label
const vstring trackerContainers
EDGetTokenT< ProductType > consumes(edm::InputTag const &tag)
type
Definition: HCALResponse.h:21
const std::string ZSDigi
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:137
edm::ESHandle< TrackerGeometry > pDD
const DetContainer & detUnits() const override
Returm a vector of all GeomDet.
const bool zeroSuppression
std::vector< std::pair< int, std::bitset< 6 > > > theAffectedAPVvector
void initializeEvent(edm::Event const &e, edm::EventSetup const &c) override
const std::string hitsProducer
void finalizeEvent(edm::Event &e, edm::EventSetup const &c) override
void accumulate(edm::Event const &e, edm::EventSetup const &c) override
virtual CLHEP::HepRandomEngine & getEngine(StreamID const &)=0
Use this engine in event methods.
const bool useConfFromDB
std::string encode() const
Definition: InputTag.cc:166
std::map< uint32_t, std::vector< int > > theDetIdList
CLHEP::HepRandomEngine * randomEngine_
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. ...
bool isValid() const
Definition: HandleBase.h:74
bool getByLabel(InputTag const &tag, Handle< PROD > &result) const
Definition: Event.h:535
virtual GlobalVector inTesla(const GlobalPoint &gp) const =0
Field value ad specified global point, in Tesla.
bool isTrackerStrip(GeomDetEnumerators::SubDetector m)
PileupMixingContent * PileupInfo_
~SiStripDigitizer() override
std::unique_ptr< SiStripDigitizerAlgorithm > theDigiAlgo
edm::ESHandle< MagneticField > pSetup
const std::string VRDigi
const std::string PRDigi
const std::string geometryType
HLT enums.
bool getByLabel(edm::InputTag const &tag, edm::Handle< T > &result) const
T get() const
Definition: EventSetup.h:68
StreamID streamID() const
Definition: Event.h:96
SiStripDigitizer(const edm::ParameterSet &conf, edm::ProducerBase &mixMod, edm::ConsumesCollector &iC)
void accumulateStripHits(edm::Handle< std::vector< PSimHit > >, const TrackerTopology *tTopo, size_t globalSimHitIndex, const unsigned int tofBin)
const bool makeDigiSimLinks_
Whether or not to create the association to sim truth collection. Set in configuration.
T const * product() const
Definition: ESHandle.h:84
const std::string gainLabel
void addConnected(std::map< uint32_t, std::vector< int > > &) const
def move(src, dest)
Definition: eostools.py:511
PileupMixingContent * getEventPileupInfo() override
std::map< unsigned int, StripGeomDetUnit const * > detectorUnits
const std::string SCDigi