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