CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
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  for(auto const& trackerContainer : trackerContainers) {
79  edm::InputTag tag(hitsProducer, trackerContainer);
80  iC.consumes<std::vector<PSimHit> >(edm::InputTag(hitsProducer, trackerContainer));
81  }
83  if ( ! rng.isAvailable()) {
84  throw cms::Exception("Configuration")
85  << "SiStripDigitizer requires the RandomNumberGeneratorService\n"
86  "which is not present in the configuration file. You must add the service\n"
87  "in the configuration file or remove the modules that require it.";
88  }
89  theDigiAlgo.reset(new SiStripDigitizerAlgorithm(conf));
90 }
91 
92 // Virtual destructor needed.
94 }
95 
96 void SiStripDigitizer::accumulateStripHits(edm::Handle<std::vector<PSimHit> > hSimHits,
97  const TrackerTopology *tTopo, size_t globalSimHitIndex, const unsigned int tofBin, CLHEP::HepRandomEngine* engine ) {
98  // globalSimHitIndex is the index the sim hit will have when it is put in a collection
99  // of sim hits for all crossings. This is only used when creating digi-sim links if
100  // configured to do so.
101 
102  if(hSimHits.isValid()) {
103  std::set<unsigned int> detIds;
104  std::vector<PSimHit> const& simHits = *hSimHits.product();
105  for(std::vector<PSimHit>::const_iterator it = simHits.begin(), itEnd = simHits.end(); it != itEnd; ++it, ++globalSimHitIndex ) {
106  unsigned int detId = (*it).detUnitId();
107  if(detIds.insert(detId).second) {
108  // The insert succeeded, so this detector element has not yet been processed.
109  assert(detectorUnits[detId]);
110  if(detectorUnits[detId]->type().isTrackerStrip()) { // this test can be removed and replaced by stripdet!=0
111  auto stripdet = detectorUnits[detId];
112  //access to magnetic field in global coordinates
113  GlobalVector bfield = pSetup->inTesla(stripdet->surface().position());
114  LogDebug ("Digitizer ") << "B-field(T) at " << stripdet->surface().position() << "(cm): "
115  << pSetup->inTesla(stripdet->surface().position());
116  theDigiAlgo->accumulateSimHits(it, itEnd, globalSimHitIndex, tofBin, stripdet, bfield, tTopo, engine);
117  }
118  }
119  } // end of loop over sim hits
120  }
121 }
122 
123 // Functions that gets called by framework every event
124  void
126  //Retrieve tracker topology from geometry
128  iSetup.get<TrackerTopologyRcd>().get(tTopoHand);
129  const TrackerTopology *tTopo=tTopoHand.product();
130 
131  // Step A: Get Inputs
132  for(auto const& trackerContainer : trackerContainers) {
134  edm::InputTag tag(hitsProducer, trackerContainer);
135  unsigned int tofBin = StripDigiSimLink::LowTof;
136  if (trackerContainer.find(std::string("HighTof")) != std::string::npos) tofBin = StripDigiSimLink::HighTof;
137 
138  iEvent.getByLabel(tag, simHits);
139  accumulateStripHits(simHits,tTopo,crossingSimHitIndexOffset_[tag.encode()], tofBin, randomEngine(iEvent.streamID()));
140  // Now that the hits have been processed, I'll add the amount of hits in this crossing on to
141  // the global counter. Next time accumulateStripHits() is called it will count the sim hits
142  // as though they were on the end of this collection.
143  // Note that this is only used for creating digi-sim links (if configured to do so).
144  if( simHits.isValid() ) crossingSimHitIndexOffset_[tag.encode()]+=simHits->size();
145  }
146  }
147 
148  void
150 
152  iSetup.get<TrackerTopologyRcd>().get(tTopoHand);
153  const TrackerTopology *tTopo=tTopoHand.product();
154 
155  // Step A: Get Inputs
156  for(auto const& trackerContainer : trackerContainers) {
158  edm::InputTag tag(hitsProducer, trackerContainer);
159  unsigned int tofBin = StripDigiSimLink::LowTof;
160  if (trackerContainer.find(std::string("HighTof")) != std::string::npos) tofBin = StripDigiSimLink::HighTof;
161 
162  iEvent.getByLabel(tag, simHits);
163  accumulateStripHits(simHits,tTopo,crossingSimHitIndexOffset_[tag.encode()], tofBin, randomEngine(streamID));
164  // Now that the hits have been processed, I'll add the amount of hits in this crossing on to
165  // the global counter. Next time accumulateStripHits() is called it will count the sim hits
166  // as though they were on the end of this collection.
167  // Note that this is only used for creating digi-sim links (if configured to do so).
168  if( simHits.isValid() ) crossingSimHitIndexOffset_[tag.encode()]+=simHits->size();
169  }
170  }
171 
172 
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  // Step A: Get Inputs
181 
182  if(useConfFromDB){
184  iSetup.get<SiStripDetCablingRcd>().get(detCabling);
185  detCabling->addConnected(theDetIdList);
186  }
187 
188  theDigiAlgo->initializeEvent(iSetup);
189 
191  iSetup.get<IdealMagneticFieldRecord>().get(pSetup);
192 
193  // FIX THIS! We only need to clear and (re)fill detectorUnits when the geometry type IOV changes. Use ESWatcher to determine this.
194  bool changes = true;
195  if(changes) { // Replace with ESWatcher
196  detectorUnits.clear();
197  }
198  for(TrackingGeometry::DetUnitContainer::const_iterator iu = pDD->detUnits().begin(); iu != pDD->detUnits().end(); ++iu) {
199  unsigned int detId = (*iu)->geographicalId().rawId();
200  if((*iu)->type().isTrackerStrip()) {
201  auto stripdet = dynamic_cast<StripGeomDetUnit const*>((*iu));
202  assert(stripdet != 0);
203  if(changes) { // Replace with ESWatcher
204  detectorUnits.insert(std::make_pair(detId, stripdet));
205  }
206  theDigiAlgo->initializeDetUnit(stripdet, iSetup);
207  }
208  }
209 }
210 
212  edm::ESHandle<SiStripGain> gainHandle;
213  edm::ESHandle<SiStripNoises> noiseHandle;
214  edm::ESHandle<SiStripThreshold> thresholdHandle;
215  edm::ESHandle<SiStripPedestals> pedestalHandle;
216  iSetup.get<SiStripGainSimRcd>().get(gainLabel,gainHandle);
217  iSetup.get<SiStripNoisesRcd>().get(noiseHandle);
218  iSetup.get<SiStripThresholdRcd>().get(thresholdHandle);
219  iSetup.get<SiStripPedestalsRcd>().get(pedestalHandle);
220 
221  std::vector<edm::DetSet<SiStripDigi> > theDigiVector;
222  std::vector<edm::DetSet<SiStripRawDigi> > theRawDigiVector;
223  std::auto_ptr< edm::DetSetVector<StripDigiSimLink> > pOutputDigiSimLink( new edm::DetSetVector<StripDigiSimLink> );
224 
225  // Step B: LOOP on StripGeomDetUnit
226  theDigiVector.reserve(10000);
227  theDigiVector.clear();
228 
229  for(TrackingGeometry::DetUnitContainer::const_iterator iu = pDD->detUnits().begin(); iu != pDD->detUnits().end(); iu ++){
230  if(useConfFromDB){
231  //apply the cable map _before_ digitization: consider only the detis that are connected
232  if(theDetIdList.find((*iu)->geographicalId().rawId())==theDetIdList.end())
233  continue;
234  }
235  auto sgd = dynamic_cast<StripGeomDetUnit const*>((*iu));
236  if (sgd != 0){
237  edm::DetSet<SiStripDigi> collectorZS((*iu)->geographicalId().rawId());
238  edm::DetSet<SiStripRawDigi> collectorRaw((*iu)->geographicalId().rawId());
239  edm::DetSet<StripDigiSimLink> collectorLink((*iu)->geographicalId().rawId());
240  theDigiAlgo->digitize(collectorZS,collectorRaw,collectorLink,sgd,
241  gainHandle,thresholdHandle,noiseHandle,pedestalHandle, randomEngine(iEvent.streamID()));
242  if(zeroSuppression){
243  if(collectorZS.data.size()>0){
244  theDigiVector.push_back(collectorZS);
245  if( !collectorLink.data.empty() ) pOutputDigiSimLink->insert(collectorLink);
246  }
247  }else{
248  if(collectorRaw.data.size()>0){
249  theRawDigiVector.push_back(collectorRaw);
250  if( !collectorLink.data.empty() ) pOutputDigiSimLink->insert(collectorLink);
251  }
252  }
253  }
254  }
255 
256  if(zeroSuppression){
257  // Step C: create output collection
258  std::auto_ptr<edm::DetSetVector<SiStripRawDigi> > output_virginraw(new edm::DetSetVector<SiStripRawDigi>());
259  std::auto_ptr<edm::DetSetVector<SiStripRawDigi> > output_scopemode(new edm::DetSetVector<SiStripRawDigi>());
260  std::auto_ptr<edm::DetSetVector<SiStripRawDigi> > output_processedraw(new edm::DetSetVector<SiStripRawDigi>());
261  std::auto_ptr<edm::DetSetVector<SiStripDigi> > output(new edm::DetSetVector<SiStripDigi>(theDigiVector) );
262  // Step D: write output to file
263  iEvent.put(output, ZSDigi);
264  iEvent.put(output_scopemode, SCDigi);
265  iEvent.put(output_virginraw, VRDigi);
266  iEvent.put(output_processedraw, PRDigi);
267  if( makeDigiSimLinks_ ) iEvent.put( pOutputDigiSimLink ); // The previous EDProducer didn't name this collection so I won't either
268  }else{
269  // Step C: create output collection
270  std::auto_ptr<edm::DetSetVector<SiStripRawDigi> > output_virginraw(new edm::DetSetVector<SiStripRawDigi>(theRawDigiVector));
271  std::auto_ptr<edm::DetSetVector<SiStripRawDigi> > output_scopemode(new edm::DetSetVector<SiStripRawDigi>());
272  std::auto_ptr<edm::DetSetVector<SiStripRawDigi> > output_processedraw(new edm::DetSetVector<SiStripRawDigi>());
273  std::auto_ptr<edm::DetSetVector<SiStripDigi> > output(new edm::DetSetVector<SiStripDigi>() );
274  // Step D: write output to file
275  iEvent.put(output, ZSDigi);
276  iEvent.put(output_scopemode, SCDigi);
277  iEvent.put(output_virginraw, VRDigi);
278  iEvent.put(output_processedraw, PRDigi);
279  if( makeDigiSimLinks_ ) iEvent.put( pOutputDigiSimLink ); // The previous EDProducer didn't name this collection so I won't either
280  }
281 }
282 
283 CLHEP::HepRandomEngine* SiStripDigitizer::randomEngine(edm::StreamID const& streamID) {
284  unsigned int index = streamID.value();
285  if(index >= randomEngines_.size()) {
286  randomEngines_.resize(index + 1, nullptr);
287  }
288  CLHEP::HepRandomEngine* ptr = randomEngines_[index];
289  if(!ptr) {
291  ptr = &rng->getEngine(streamID);
292  randomEngines_[index] = ptr;
293  }
294  return ptr;
295 }
#define LogDebug(id)
const vstring trackerContainers
EDGetTokenT< ProductType > consumes(edm::InputTag const &tag)
type
Definition: HCALResponse.h:21
const std::string ZSDigi
void accumulateStripHits(edm::Handle< std::vector< PSimHit > >, const TrackerTopology *tTopo, size_t globalSimHitIndex, const unsigned int tofBin, CLHEP::HepRandomEngine *)
edm::ESHandle< TrackerGeometry > pDD
const bool zeroSuppression
assert(m_qm.get())
virtual void initializeEvent(edm::Event const &e, edm::EventSetup const &c) override
const std::string hitsProducer
virtual void finalizeEvent(edm::Event &e, edm::EventSetup const &c) override
virtual 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:164
std::map< uint32_t, std::vector< int > > theDetIdList
virtual ~SiStripDigitizer()
bool isTrackerStrip(const GeomDetEnumerators::SubDetector m)
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. ...
OrphanHandle< PROD > put(std::auto_ptr< PROD > product)
Put a new product.
Definition: Event.h:121
CLHEP::HepRandomEngine * randomEngine(edm::StreamID const &streamID)
bool isAvailable() const
Definition: Service.h:46
bool isValid() const
Definition: HandleBase.h:75
bool getByLabel(InputTag const &tag, Handle< PROD > &result) const
Definition: Event.h:418
unsigned int value() const
Definition: StreamID.h:46
std::unique_ptr< SiStripDigitizerAlgorithm > theDigiAlgo
edm::ESHandle< MagneticField > pSetup
const std::string VRDigi
const std::string PRDigi
const T & get() const
Definition: EventSetup.h:56
const std::string geometryType
T const * product() const
Definition: ESHandle.h:86
tuple simHits
Definition: trackerHits.py:16
string const
Definition: compareJSON.py:14
SiStripDigitizer(const edm::ParameterSet &conf, edm::stream::EDProducerBase &mixMod, edm::ConsumesCollector &iC)
bool getByLabel(edm::InputTag const &tag, edm::Handle< T > &result) const
StreamID streamID() const
Definition: Event.h:80
const bool makeDigiSimLinks_
Whether or not to create the association to sim truth collection. Set in configuration.
volatile std::atomic< bool > shutdown_flag false
const std::string gainLabel
std::map< unsigned int, StripGeomDetUnit const * > detectorUnits
const std::string SCDigi
std::vector< CLHEP::HepRandomEngine * > randomEngines_