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  if (useConfFromDB) {
76  }
79  }
80 
81  const std::string alias("simSiStripDigis");
82 
83  producesCollector.produces<edm::DetSetVector<SiStripDigi>>(ZSDigi).setBranchAlias(ZSDigi);
84  producesCollector.produces<edm::DetSetVector<SiStripRawDigi>>(SCDigi).setBranchAlias(alias + SCDigi);
85  producesCollector.produces<edm::DetSetVector<SiStripRawDigi>>(VRDigi).setBranchAlias(alias + VRDigi);
86  producesCollector.produces<edm::DetSetVector<SiStripRawDigi>>("StripAmplitudes")
87  .setBranchAlias(alias + "StripAmplitudes");
88  producesCollector.produces<edm::DetSetVector<SiStripRawDigi>>("StripAmplitudesPostAPV")
89  .setBranchAlias(alias + "StripAmplitudesPostAPV");
90  producesCollector.produces<edm::DetSetVector<SiStripRawDigi>>("StripAPVBaselines")
91  .setBranchAlias(alias + "StripAPVBaselines");
92  producesCollector.produces<edm::DetSetVector<SiStripRawDigi>>(PRDigi).setBranchAlias(alias + PRDigi);
93  producesCollector.produces<edm::DetSetVector<StripDigiSimLink>>().setBranchAlias(alias + "siStripDigiSimLink");
94  producesCollector.produces<bool>("SimulatedAPVDynamicGain").setBranchAlias(alias + "SimulatedAPVDynamicGain");
95  producesCollector.produces<std::vector<std::pair<int, std::bitset<6>>>>("AffectedAPVList")
96  .setBranchAlias(alias + "AffectedAPV");
97  for (auto const& trackerContainer : trackerContainers) {
98  edm::InputTag tag(hitsProducer, trackerContainer);
99  iC.consumes<std::vector<PSimHit>>(edm::InputTag(hitsProducer, trackerContainer));
100  }
102  if (!rng.isAvailable()) {
103  throw cms::Exception("Configuration")
104  << "SiStripDigitizer requires the RandomNumberGeneratorService\n"
105  "which is not present in the configuration file. You must add the service\n"
106  "in the configuration file or remove the modules that require it.";
107  }
108  theDigiAlgo = std::make_unique<SiStripDigitizerAlgorithm>(conf, iC);
109 }
110 
111 // Virtual destructor needed.
113 
114 void SiStripDigitizer::accumulateStripHits(edm::Handle<std::vector<PSimHit>> hSimHits,
115  const TrackerTopology* tTopo,
116  size_t globalSimHitIndex,
117  const unsigned int tofBin) {
118  // globalSimHitIndex is the index the sim hit will have when it is put in a collection
119  // of sim hits for all crossings. This is only used when creating digi-sim links if
120  // configured to do so.
121 
122  if (hSimHits.isValid()) {
123  std::set<unsigned int> detIds;
124  std::vector<PSimHit> const& simHits = *hSimHits.product();
125  for (std::vector<PSimHit>::const_iterator it = simHits.begin(), itEnd = simHits.end(); it != itEnd;
126  ++it, ++globalSimHitIndex) {
127  unsigned int detId = (*it).detUnitId();
128  if (detIds.insert(detId).second) {
129  // The insert succeeded, so this detector element has not yet been processed.
130  assert(detectorUnits[detId]);
131  if (detectorUnits[detId]->type().isTrackerStrip()) { // this test can be removed and replaced by stripdet!=0
132  auto stripdet = detectorUnits[detId];
133  //access to magnetic field in global coordinates
134  GlobalVector bfield = pSetup->inTesla(stripdet->surface().position());
135  LogDebug("Digitizer ") << "B-field(T) at " << stripdet->surface().position()
136  << "(cm): " << pSetup->inTesla(stripdet->surface().position());
137  theDigiAlgo->accumulateSimHits(it, itEnd, globalSimHitIndex, tofBin, stripdet, bfield, tTopo, randomEngine_);
138  }
139  }
140  } // end of loop over sim hits
141  }
142 }
143 
144 // Functions that gets called by framework every event
146  //Retrieve tracker topology from geometry
147  const TrackerTopology* tTopo = &iSetup.getData(tTopoToken_);
148 
149  // Step A: Get Inputs
150  for (auto const& trackerContainer : trackerContainers) {
152  edm::InputTag tag(hitsProducer, trackerContainer);
153  unsigned int tofBin = StripDigiSimLink::LowTof;
154  if (trackerContainer.find(std::string("HighTof")) != std::string::npos)
155  tofBin = StripDigiSimLink::HighTof;
156 
157  iEvent.getByLabel(tag, simHits);
158  accumulateStripHits(simHits, tTopo, crossingSimHitIndexOffset_[tag.encode()], tofBin);
159  // Now that the hits have been processed, I'll add the amount of hits in this crossing on to
160  // the global counter. Next time accumulateStripHits() is called it will count the sim hits
161  // as though they were on the end of this collection.
162  // Note that this is only used for creating digi-sim links (if configured to do so).
163  if (simHits.isValid())
164  crossingSimHitIndexOffset_[tag.encode()] += simHits->size();
165  }
166 }
167 
169  edm::EventSetup const& iSetup,
170  edm::StreamID const& streamID) {
171  const TrackerTopology* tTopo = &iSetup.getData(tTopoToken_);
172 
173  //Re-compute luminosity for accumulation for HIP effects
174  theDigiAlgo->calculateInstlumiScale(PileupInfo_.get());
175 
176  // Step A: Get Inputs
177  for (auto const& trackerContainer : trackerContainers) {
179  edm::InputTag tag(hitsProducer, trackerContainer);
180  unsigned int tofBin = StripDigiSimLink::LowTof;
181  if (trackerContainer.find(std::string("HighTof")) != std::string::npos)
182  tofBin = StripDigiSimLink::HighTof;
183 
184  iEvent.getByLabel(tag, simHits);
185  accumulateStripHits(simHits, tTopo, crossingSimHitIndexOffset_[tag.encode()], tofBin);
186  // Now that the hits have been processed, I'll add the amount of hits in this crossing on to
187  // the global counter. Next time accumulateStripHits() is called it will count the sim hits
188  // as though they were on the end of this collection.
189  // Note that this is only used for creating digi-sim links (if configured to do so).
190  if (simHits.isValid())
191  crossingSimHitIndexOffset_[tag.encode()] += simHits->size();
192  }
193 }
194 
196  // Make sure that the first crossing processed starts indexing the sim hits from zero.
197  // This variable is used so that the sim hits from all crossing frames have sequential
198  // indices used to create the digi-sim link (if configured to do so) rather than starting
199  // from zero for each crossing.
201  theAffectedAPVvector.clear();
202  // Step A: Get Inputs
203 
204  if (useConfFromDB) {
205  iSetup.getData(detCablingToken_).addConnected(theDetIdList);
206  }
207 
208  // Cache random number engine
210  randomEngine_ = &rng->getEngine(iEvent.streamID());
211 
212  theDigiAlgo->initializeEvent(iSetup);
213 
214  pDD = &iSetup.getData(pDDToken_);
215  pSetup = &iSetup.getData(pSetupToken_);
216 
217  // FIX THIS! We only need to clear and (re)fill detectorUnits when the geometry type IOV changes. Use ESWatcher to determine this.
218  bool changes = true;
219  if (changes) { // Replace with ESWatcher
220  detectorUnits.clear();
221  }
222  for (const auto& iu : pDD->detUnits()) {
223  unsigned int detId = iu->geographicalId().rawId();
224  if (iu->type().isTrackerStrip()) {
225  auto stripdet = dynamic_cast<StripGeomDetUnit const*>(iu);
226  assert(stripdet != nullptr);
227  if (changes) { // Replace with ESWatcher
228  detectorUnits.insert(std::make_pair(detId, stripdet));
229  }
230  theDigiAlgo->initializeDetUnit(stripdet, iSetup);
231  }
232  }
233 }
234 
236  auto const& gain = iSetup.getData(gainToken_);
237  auto const& noise = iSetup.getData(noiseToken_);
238  auto const& threshold = iSetup.getData(thresholdToken_);
239  auto const& pedestal = iSetup.getData(pedestalToken_);
240  SiStripApvSimulationParameters const* apvSimulationParameters = nullptr;
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  apvSimulationParameters = &iSetup.getData(apvSimulationParametersToken_);
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(
254  std::unique_ptr<edm::DetSetVector<SiStripRawDigi>> theStripAPVBaselines(new edm::DetSetVector<SiStripRawDigi>());
255  std::unique_ptr<edm::DetSetVector<StripDigiSimLink>> pOutputDigiSimLink(new edm::DetSetVector<StripDigiSimLink>);
256 
257  const TrackerTopology* tTopo = &iSetup.getData(tTopoToken_);
258 
259  // Step B: LOOP on StripGeomDetUnit
260  theDigiVector.reserve(10000);
261  theDigiVector.clear();
262 
263  for (const auto& iu : pDD->detUnits()) {
264  if (useConfFromDB) {
265  //apply the cable map _before_ digitization: consider only the detis that are connected
266  if (theDetIdList.find(iu->geographicalId().rawId()) == theDetIdList.end())
267  continue;
268  }
269  auto sgd = dynamic_cast<StripGeomDetUnit const*>(iu);
270  if (sgd != nullptr) {
271  edm::DetSet<SiStripDigi> collectorZS(iu->geographicalId().rawId());
272  edm::DetSet<SiStripRawDigi> collectorRaw(iu->geographicalId().rawId());
273  edm::DetSet<SiStripRawDigi> collectorStripAmplitudes(iu->geographicalId().rawId());
274  edm::DetSet<SiStripRawDigi> collectorStripAmplitudesPostAPV(iu->geographicalId().rawId());
275  edm::DetSet<SiStripRawDigi> collectorStripAPVBaselines(iu->geographicalId().rawId());
276  edm::DetSet<StripDigiSimLink> collectorLink(iu->geographicalId().rawId());
277 
278  unsigned int detID = sgd->geographicalId().rawId();
279  DetId detId(detID);
280 
281  theDigiAlgo->digitize(collectorZS,
282  collectorRaw,
283  collectorStripAmplitudes,
284  collectorStripAmplitudesPostAPV,
285  collectorStripAPVBaselines,
286  collectorLink,
287  sgd,
288  gain,
289  threshold,
290  noise,
291  pedestal,
292  *simulateAPVInThisEvent,
293  apvSimulationParameters,
296  tTopo);
297 
298  if (!collectorStripAmplitudes.data.empty())
299  theStripAmplitudeVector->insert(collectorStripAmplitudes);
300  if (!collectorStripAmplitudesPostAPV.data.empty())
301  theStripAmplitudeVectorPostAPV->insert(collectorStripAmplitudesPostAPV);
302  if (!collectorStripAPVBaselines.data.empty())
303  theStripAPVBaselines->insert(collectorStripAPVBaselines);
304 
305  if (zeroSuppression) {
306  if (!collectorZS.data.empty()) {
307  theDigiVector.push_back(collectorZS);
308  if (!collectorLink.data.empty())
309  pOutputDigiSimLink->insert(collectorLink);
310  }
311  } else {
312  if (!collectorRaw.data.empty()) {
313  theRawDigiVector.push_back(collectorRaw);
314  if (!collectorLink.data.empty())
315  pOutputDigiSimLink->insert(collectorLink);
316  }
317  }
318  }
319  }
320  if (zeroSuppression) {
321  // Step C: create output collection
322  std::unique_ptr<edm::DetSetVector<SiStripRawDigi>> output_virginraw(new edm::DetSetVector<SiStripRawDigi>());
323  std::unique_ptr<edm::DetSetVector<SiStripRawDigi>> output_scopemode(new edm::DetSetVector<SiStripRawDigi>());
324  std::unique_ptr<edm::DetSetVector<SiStripRawDigi>> output_processedraw(new edm::DetSetVector<SiStripRawDigi>());
325  std::unique_ptr<edm::DetSetVector<SiStripDigi>> output(new edm::DetSetVector<SiStripDigi>(theDigiVector));
326  std::unique_ptr<std::vector<std::pair<int, std::bitset<6>>>> AffectedAPVList(
327  new std::vector<std::pair<int, std::bitset<6>>>(theAffectedAPVvector));
328 
329  // Step D: write output to file
330  iEvent.put(std::move(output), ZSDigi);
331  iEvent.put(std::move(output_scopemode), SCDigi);
332  iEvent.put(std::move(output_virginraw), VRDigi);
333  iEvent.put(std::move(theStripAmplitudeVector), "StripAmplitudes");
334  iEvent.put(std::move(theStripAmplitudeVectorPostAPV), "StripAmplitudesPostAPV");
335  iEvent.put(std::move(theStripAPVBaselines), "StripAPVBaselines");
336  iEvent.put(std::move(output_processedraw), PRDigi);
337  iEvent.put(std::move(AffectedAPVList), "AffectedAPVList");
338  iEvent.put(std::move(simulateAPVInThisEvent), "SimulatedAPVDynamicGain");
339  if (makeDigiSimLinks_)
340  iEvent.put(
341  std::move(pOutputDigiSimLink)); // The previous EDProducer didn't name this collection so I won't either
342  } else {
343  // Step C: create output collection
344  std::unique_ptr<edm::DetSetVector<SiStripRawDigi>> output_virginraw(
345  new edm::DetSetVector<SiStripRawDigi>(theRawDigiVector));
346  std::unique_ptr<edm::DetSetVector<SiStripRawDigi>> output_scopemode(new edm::DetSetVector<SiStripRawDigi>());
347  std::unique_ptr<edm::DetSetVector<SiStripRawDigi>> output_processedraw(new edm::DetSetVector<SiStripRawDigi>());
348  std::unique_ptr<edm::DetSetVector<SiStripDigi>> output(new edm::DetSetVector<SiStripDigi>());
349 
350  // Step D: write output to file
351  iEvent.put(std::move(output), ZSDigi);
352  iEvent.put(std::move(output_scopemode), SCDigi);
353  iEvent.put(std::move(output_virginraw), VRDigi);
354  iEvent.put(std::move(theStripAmplitudeVector), "StripAmplitudes");
355  iEvent.put(std::move(theStripAmplitudeVectorPostAPV), "StripAmplitudesPostAPV");
356  iEvent.put(std::move(theStripAPVBaselines), "StripAPVBaselines");
357  iEvent.put(std::move(output_processedraw), PRDigi);
358  iEvent.put(std::move(simulateAPVInThisEvent), "SimulatedAPVDynamicGain");
359  if (makeDigiSimLinks_)
360  iEvent.put(
361  std::move(pOutputDigiSimLink)); // The previous EDProducer didn't name this collection so I won't either
362  }
363  randomEngine_ = nullptr; // to prevent access outside event
364 }
const vstring trackerContainers
EDGetTokenT< ProductType > consumes(edm::InputTag const &tag)
const std::string ZSDigi
ESGetTokenH3DDVariant esConsumes(std::string const &Record, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
const edm::ESGetToken< TrackerTopology, TrackerTopologyRcd > tTopoToken_
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
edm::ESGetToken< SiStripApvSimulationParameters, SiStripApvSimulationParametersRcd > apvSimulationParametersToken_
Whether or not to create the association to sim truth collection. Set in configuration.
CLHEP::HepRandomEngine * randomEngine_
int iEvent
Definition: GenABIO.cc:224
const bool includeAPVSimulation_
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_
bool getData(T &iHolder) const
Definition: EventSetup.h:122
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
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
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