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
53 
54 //Random Number
58 #include "CLHEP/Random/RandFlat.h"
59 
61  : gainLabel(conf.getParameter<std::string>("Gain")),
62  hitsProducer(conf.getParameter<std::string>("hitsProducer")),
63  trackerContainers(conf.getParameter<std::vector<std::string>>("ROUList")),
64  ZSDigi(conf.getParameter<edm::ParameterSet>("DigiModeList").getParameter<std::string>("ZSDigi")),
65  SCDigi(conf.getParameter<edm::ParameterSet>("DigiModeList").getParameter<std::string>("SCDigi")),
66  VRDigi(conf.getParameter<edm::ParameterSet>("DigiModeList").getParameter<std::string>("VRDigi")),
67  PRDigi(conf.getParameter<edm::ParameterSet>("DigiModeList").getParameter<std::string>("PRDigi")),
68  geometryType(conf.getParameter<std::string>("GeometryType")),
69  useConfFromDB(conf.getParameter<bool>("TrackerConfigurationFromDB")),
70  zeroSuppression(conf.getParameter<bool>("ZeroSuppression")),
71  makeDigiSimLinks_(conf.getUntrackedParameter<bool>("makeDigiSimLinks", false)),
72  includeAPVSimulation_(conf.getParameter<bool>("includeAPVSimulation")),
73  fracOfEventsToSimAPV_(conf.getParameter<double>("fracOfEventsToSimAPV")) {
74  const std::string alias("simSiStripDigis");
75 
76  mixMod.produces<edm::DetSetVector<SiStripDigi>>(ZSDigi).setBranchAlias(ZSDigi);
77  mixMod.produces<edm::DetSetVector<SiStripRawDigi>>(SCDigi).setBranchAlias(alias + SCDigi);
78  mixMod.produces<edm::DetSetVector<SiStripRawDigi>>(VRDigi).setBranchAlias(alias + VRDigi);
79  mixMod.produces<edm::DetSetVector<SiStripRawDigi>>("StripAmplitudes").setBranchAlias(alias + "StripAmplitudes");
80  mixMod.produces<edm::DetSetVector<SiStripRawDigi>>("StripAmplitudesPostAPV")
81  .setBranchAlias(alias + "StripAmplitudesPostAPV");
82  mixMod.produces<edm::DetSetVector<SiStripRawDigi>>("StripAPVBaselines").setBranchAlias(alias + "StripAPVBaselines");
83  mixMod.produces<edm::DetSetVector<SiStripRawDigi>>(PRDigi).setBranchAlias(alias + PRDigi);
84  mixMod.produces<edm::DetSetVector<StripDigiSimLink>>().setBranchAlias(alias + "siStripDigiSimLink");
85  mixMod.produces<bool>("SimulatedAPVDynamicGain").setBranchAlias(alias + "SimulatedAPVDynamicGain");
86  mixMod.produces<std::vector<std::pair<int, std::bitset<6>>>>("AffectedAPVList").setBranchAlias(alias + "AffectedAPV");
87  for (auto const& trackerContainer : trackerContainers) {
88  edm::InputTag tag(hitsProducer, trackerContainer);
89  iC.consumes<std::vector<PSimHit>>(edm::InputTag(hitsProducer, trackerContainer));
90  }
92  if (!rng.isAvailable()) {
93  throw cms::Exception("Configuration")
94  << "SiStripDigitizer requires the RandomNumberGeneratorService\n"
95  "which is not present in the configuration file. You must add the service\n"
96  "in the configuration file or remove the modules that require it.";
97  }
98  theDigiAlgo.reset(new SiStripDigitizerAlgorithm(conf));
99 }
100 
101 // Virtual destructor needed.
103 
104 void SiStripDigitizer::accumulateStripHits(edm::Handle<std::vector<PSimHit>> hSimHits,
105  const TrackerTopology* tTopo,
106  size_t globalSimHitIndex,
107  const unsigned int tofBin) {
108  // globalSimHitIndex is the index the sim hit will have when it is put in a collection
109  // of sim hits for all crossings. This is only used when creating digi-sim links if
110  // configured to do so.
111 
112  if (hSimHits.isValid()) {
113  std::set<unsigned int> detIds;
114  std::vector<PSimHit> const& simHits = *hSimHits.product();
115  for (std::vector<PSimHit>::const_iterator it = simHits.begin(), itEnd = simHits.end(); it != itEnd;
116  ++it, ++globalSimHitIndex) {
117  unsigned int detId = (*it).detUnitId();
118  if (detIds.insert(detId).second) {
119  // The insert succeeded, so this detector element has not yet been processed.
120  assert(detectorUnits[detId]);
121  if (detectorUnits[detId]->type().isTrackerStrip()) { // this test can be removed and replaced by stripdet!=0
122  auto stripdet = detectorUnits[detId];
123  //access to magnetic field in global coordinates
124  GlobalVector bfield = pSetup->inTesla(stripdet->surface().position());
125  LogDebug("Digitizer ") << "B-field(T) at " << stripdet->surface().position()
126  << "(cm): " << pSetup->inTesla(stripdet->surface().position());
127  theDigiAlgo->accumulateSimHits(it, itEnd, globalSimHitIndex, tofBin, stripdet, bfield, tTopo, randomEngine_);
128  }
129  }
130  } // end of loop over sim hits
131  }
132 }
133 
134 // Functions that gets called by framework every event
136  //Retrieve tracker topology from geometry
138  iSetup.get<TrackerTopologyRcd>().get(tTopoHand);
139  const TrackerTopology* tTopo = tTopoHand.product();
140 
141  // Step A: Get Inputs
142  for (auto const& trackerContainer : trackerContainers) {
144  edm::InputTag tag(hitsProducer, trackerContainer);
145  unsigned int tofBin = StripDigiSimLink::LowTof;
146  if (trackerContainer.find(std::string("HighTof")) != std::string::npos)
147  tofBin = StripDigiSimLink::HighTof;
148 
149  iEvent.getByLabel(tag, simHits);
150  accumulateStripHits(simHits, tTopo, crossingSimHitIndexOffset_[tag.encode()], tofBin);
151  // Now that the hits have been processed, I'll add the amount of hits in this crossing on to
152  // the global counter. Next time accumulateStripHits() is called it will count the sim hits
153  // as though they were on the end of this collection.
154  // Note that this is only used for creating digi-sim links (if configured to do so).
155  if (simHits.isValid())
156  crossingSimHitIndexOffset_[tag.encode()] += simHits->size();
157  }
158 }
159 
161  edm::EventSetup const& iSetup,
162  edm::StreamID const& streamID) {
164  iSetup.get<TrackerTopologyRcd>().get(tTopoHand);
165  const TrackerTopology* tTopo = tTopoHand.product();
166 
167  //Re-compute luminosity for accumulation for HIP effects
168  theDigiAlgo->calculateInstlumiScale(PileupInfo_.get());
169 
170  // Step A: Get Inputs
171  for (auto const& trackerContainer : trackerContainers) {
173  edm::InputTag tag(hitsProducer, trackerContainer);
174  unsigned int tofBin = StripDigiSimLink::LowTof;
175  if (trackerContainer.find(std::string("HighTof")) != std::string::npos)
176  tofBin = StripDigiSimLink::HighTof;
177 
178  iEvent.getByLabel(tag, simHits);
179  accumulateStripHits(simHits, tTopo, crossingSimHitIndexOffset_[tag.encode()], tofBin);
180  // Now that the hits have been processed, I'll add the amount of hits in this crossing on to
181  // the global counter. Next time accumulateStripHits() is called it will count the sim hits
182  // as though they were on the end of this collection.
183  // Note that this is only used for creating digi-sim links (if configured to do so).
184  if (simHits.isValid())
185  crossingSimHitIndexOffset_[tag.encode()] += simHits->size();
186  }
187 }
188 
190  // Make sure that the first crossing processed starts indexing the sim hits from zero.
191  // This variable is used so that the sim hits from all crossing frames have sequential
192  // indices used to create the digi-sim link (if configured to do so) rather than starting
193  // from zero for each crossing.
195  theAffectedAPVvector.clear();
196  // Step A: Get Inputs
197 
198  if (useConfFromDB) {
200  iSetup.get<SiStripDetCablingRcd>().get(detCabling);
201  detCabling->addConnected(theDetIdList);
202  }
203 
204  // Cache random number engine
206  randomEngine_ = &rng->getEngine(iEvent.streamID());
207 
208  theDigiAlgo->initializeEvent(iSetup);
209 
211  iSetup.get<IdealMagneticFieldRecord>().get(pSetup);
212 
213  // FIX THIS! We only need to clear and (re)fill detectorUnits when the geometry type IOV changes. Use ESWatcher to determine this.
214  bool changes = true;
215  if (changes) { // Replace with ESWatcher
216  detectorUnits.clear();
217  }
218  for (const auto& iu : pDD->detUnits()) {
219  unsigned int detId = iu->geographicalId().rawId();
220  if (iu->type().isTrackerStrip()) {
221  auto stripdet = dynamic_cast<StripGeomDetUnit const*>(iu);
222  assert(stripdet != nullptr);
223  if (changes) { // Replace with ESWatcher
224  detectorUnits.insert(std::make_pair(detId, stripdet));
225  }
226  theDigiAlgo->initializeDetUnit(stripdet, iSetup);
227  }
228  }
229 }
230 
232  edm::ESHandle<SiStripGain> gainHandle;
233  edm::ESHandle<SiStripNoises> noiseHandle;
234  edm::ESHandle<SiStripThreshold> thresholdHandle;
235  edm::ESHandle<SiStripPedestals> pedestalHandle;
236  edm::ESHandle<SiStripApvSimulationParameters> apvSimulationParametersHandle;
237  iSetup.get<SiStripGainSimRcd>().get(gainLabel, gainHandle);
238  iSetup.get<SiStripNoisesRcd>().get(noiseHandle);
239  iSetup.get<SiStripThresholdRcd>().get(thresholdHandle);
240  iSetup.get<SiStripPedestalsRcd>().get(pedestalHandle);
241 
242  std::unique_ptr<bool> simulateAPVInThisEvent = std::make_unique<bool>(false);
243  if (includeAPVSimulation_) {
244  if (CLHEP::RandFlat::shoot(randomEngine_) < fracOfEventsToSimAPV_ ) {
245  *simulateAPVInThisEvent = true;
246  iSetup.get<SiStripApvSimulationParametersRcd>().get(apvSimulationParametersHandle);
247  }
248  }
249  std::vector<edm::DetSet<SiStripDigi>> theDigiVector;
250  std::vector<edm::DetSet<SiStripRawDigi>> theRawDigiVector;
251  std::unique_ptr<edm::DetSetVector<SiStripRawDigi>> theStripAmplitudeVector( new edm::DetSetVector<SiStripRawDigi>());
252  std::unique_ptr<edm::DetSetVector<SiStripRawDigi>> theStripAmplitudeVectorPostAPV( new edm::DetSetVector<SiStripRawDigi>());
253  std::unique_ptr<edm::DetSetVector<SiStripRawDigi>> theStripAPVBaselines( new edm::DetSetVector<SiStripRawDigi>());
254  std::unique_ptr<edm::DetSetVector<StripDigiSimLink>> pOutputDigiSimLink(new edm::DetSetVector<StripDigiSimLink>);
255 
257  iSetup.get<TrackerTopologyRcd>().get(tTopoHand);
258  const TrackerTopology* tTopo = tTopoHand.product();
259 
260  // Step B: LOOP on StripGeomDetUnit
261  theDigiVector.reserve(10000);
262  theDigiVector.clear();
263 
264  for (const auto& iu : pDD->detUnits()) {
265  if (useConfFromDB) {
266  //apply the cable map _before_ digitization: consider only the detis that are connected
267  if (theDetIdList.find(iu->geographicalId().rawId()) == theDetIdList.end())
268  continue;
269  }
270  auto sgd = dynamic_cast<StripGeomDetUnit const*>(iu);
271  if (sgd != nullptr) {
272  edm::DetSet<SiStripDigi> collectorZS(iu->geographicalId().rawId());
273  edm::DetSet<SiStripRawDigi> collectorRaw(iu->geographicalId().rawId());
274  edm::DetSet<SiStripRawDigi> collectorStripAmplitudes(iu->geographicalId().rawId());
275  edm::DetSet<SiStripRawDigi> collectorStripAmplitudesPostAPV(iu->geographicalId().rawId());
276  edm::DetSet<SiStripRawDigi> collectorStripAPVBaselines(iu->geographicalId().rawId());
277  edm::DetSet<StripDigiSimLink> collectorLink(iu->geographicalId().rawId());
278 
279  unsigned int detID = sgd->geographicalId().rawId();
280  DetId detId(detID);
281 
282  theDigiAlgo->digitize(collectorZS,
283  collectorRaw,
284  collectorStripAmplitudes,
285  collectorStripAmplitudesPostAPV,
286  collectorStripAPVBaselines,
287  collectorLink,
288  sgd,
289  gainHandle,
290  thresholdHandle,
291  noiseHandle,
292  pedestalHandle,
293  *simulateAPVInThisEvent,
294  apvSimulationParametersHandle,
297  tTopo);
298 
299  if ( !collectorStripAmplitudes.data.empty() ) theStripAmplitudeVector->insert(collectorStripAmplitudes);
300  if ( !collectorStripAmplitudesPostAPV.data.empty() ) theStripAmplitudeVectorPostAPV->insert(collectorStripAmplitudesPostAPV);
301  if ( !collectorStripAPVBaselines.data.empty() ) theStripAPVBaselines->insert(collectorStripAPVBaselines);
302 
303  if (zeroSuppression) {
304  if (!collectorZS.data.empty()) {
305  theDigiVector.push_back(collectorZS);
306  if (!collectorLink.data.empty())
307  pOutputDigiSimLink->insert(collectorLink);
308  }
309  } else {
310  if (!collectorRaw.data.empty()) {
311  theRawDigiVector.push_back(collectorRaw);
312  if (!collectorLink.data.empty())
313  pOutputDigiSimLink->insert(collectorLink);
314  }
315  }
316  }
317  }
318  if (zeroSuppression) {
319  // Step C: create output collection
320  std::unique_ptr<edm::DetSetVector<SiStripRawDigi>> output_virginraw(new edm::DetSetVector<SiStripRawDigi>());
321  std::unique_ptr<edm::DetSetVector<SiStripRawDigi>> output_scopemode(new edm::DetSetVector<SiStripRawDigi>());
322  std::unique_ptr<edm::DetSetVector<SiStripRawDigi>> output_processedraw(new edm::DetSetVector<SiStripRawDigi>());
323  std::unique_ptr<edm::DetSetVector<SiStripDigi>> output(new edm::DetSetVector<SiStripDigi>(theDigiVector));
324  std::unique_ptr<std::vector<std::pair<int, std::bitset<6>>>> AffectedAPVList(
325  new std::vector<std::pair<int, std::bitset<6>>>(theAffectedAPVvector));
326 
327  // Step D: write output to file
328  iEvent.put(std::move(output), ZSDigi);
329  iEvent.put(std::move(output_scopemode), SCDigi);
330  iEvent.put(std::move(output_virginraw), VRDigi);
331  iEvent.put(std::move(theStripAmplitudeVector), "StripAmplitudes");
332  iEvent.put(std::move(theStripAmplitudeVectorPostAPV), "StripAmplitudesPostAPV");
333  iEvent.put(std::move(theStripAPVBaselines), "StripAPVBaselines");
334  iEvent.put(std::move(output_processedraw), PRDigi);
335  iEvent.put(std::move(AffectedAPVList), "AffectedAPVList");
336  iEvent.put(std::move(simulateAPVInThisEvent), "SimulatedAPVDynamicGain");
337  if (makeDigiSimLinks_)
338  iEvent.put(
339  std::move(pOutputDigiSimLink)); // The previous EDProducer didn't name this collection so I won't either
340  } else {
341  // Step C: create output collection
342  std::unique_ptr<edm::DetSetVector<SiStripRawDigi>> output_virginraw(
343  new edm::DetSetVector<SiStripRawDigi>(theRawDigiVector));
344  std::unique_ptr<edm::DetSetVector<SiStripRawDigi>> output_scopemode(new edm::DetSetVector<SiStripRawDigi>());
345  std::unique_ptr<edm::DetSetVector<SiStripRawDigi>> output_processedraw(new edm::DetSetVector<SiStripRawDigi>());
346  std::unique_ptr<edm::DetSetVector<SiStripDigi>> output(new edm::DetSetVector<SiStripDigi>());
347 
348  // Step D: write output to file
349  iEvent.put(std::move(output), ZSDigi);
350  iEvent.put(std::move(output_scopemode), SCDigi);
351  iEvent.put(std::move(output_virginraw), VRDigi);
352  iEvent.put(std::move(theStripAmplitudeVector), "StripAmplitudes");
353  iEvent.put(std::move(theStripAmplitudeVectorPostAPV), "StripAmplitudesPostAPV");
354  iEvent.put(std::move(theStripAPVBaselines), "StripAPVBaselines");
355  iEvent.put(std::move(output_processedraw), PRDigi);
356  iEvent.put(std::move(simulateAPVInThisEvent), "SimulatedAPVDynamicGain");
357  if (makeDigiSimLinks_)
358  iEvent.put(
359  std::move(pOutputDigiSimLink)); // The previous EDProducer didn't name this collection so I won't either
360  }
361  randomEngine_ = nullptr; // to prevent access outside event
362 }
#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:125
edm::ESHandle< TrackerGeometry > pDD
const DetContainer & detUnits() const override
Returm a vector of all GeomDet.
const bool zeroSuppression
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
std::map< unsigned int, StripGeomDetUnit const * > detectorUnits
virtual CLHEP::HepRandomEngine & getEngine(StreamID const &)=0
Use this engine in event methods.
const bool useConfFromDB
std::string encode() const
Definition: InputTag.cc:159
std::map< uint32_t, std::vector< int > > theDetIdList
CLHEP::HepRandomEngine * randomEngine_
int iEvent
Definition: GenABIO.cc:224
const bool includeAPVSimulation_
void accumulateStripHits(edm::Handle< std::vector< PSimHit >>, const TrackerTopology *tTopo, size_t globalSimHitIndex, const unsigned int tofBin)
bool isValid() const
Definition: HandleBase.h:74
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.
bool isTrackerStrip(GeomDetEnumerators::SubDetector m)
~SiStripDigitizer() override
Definition: DetId.h:18
std::unique_ptr< SiStripDigitizerAlgorithm > theDigiAlgo
edm::ESHandle< MagneticField > pSetup
const std::string VRDigi
const std::string PRDigi
const std::string geometryType
std::vector< std::pair< int, std::bitset< 6 > > > theAffectedAPVvector
HLT enums.
const double fracOfEventsToSimAPV_
Whether or not to create the association to sim truth collection. Set in configuration.
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
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. ...
SiStripDigitizer(const edm::ParameterSet &conf, edm::ProducerBase &mixMod, edm::ConsumesCollector &iC)
void addConnected(std::map< uint32_t, std::vector< int >> &) const
const bool makeDigiSimLinks_
T const * product() const
Definition: ESHandle.h:86
const std::string gainLabel
def move(src, dest)
Definition: eostools.py:511
std::unique_ptr< PileupMixingContent > PileupInfo_
const std::string SCDigi