ATLAS Offline Software
MM_DigitizationTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 
6 // Inputs
9 
10 // Outputs
12 
13 // MM digitization includes
17 
18 // Geometry
25 #include "TrkSurfaces/Surface.h"
26 
27 // Truth
29 #include "AtlasHepMC/GenParticle.h"
30 #include "CLHEP/Units/PhysicalConstants.h"
33 
34 // ROOT
35 #include <fstream>
36 #include <iostream>
37 #include <memory>
38 #include <sstream>
39 #include <string>
40 
41 #include "TFile.h"
42 #include "TString.h"
43 #include "TTree.h"
44 
45 
46 namespace {
47  // thresholds for the shortest and longest strips
48  //values from https://indico.cern.ch/event/1131762/contributions/4749097/attachments/2431773/4164431/MMGcoord2022.04.26.pdf
49 
50  constexpr float maxNoiseSmall_eta1 = 2100;
51  constexpr float minNoiseSmall_eta1 = 1000;
52  constexpr float maxNoiseSmall_eta2 = 2600;
53  constexpr float minNoiseSmall_eta2 = 2100;
54 
55  constexpr float maxNoiseLarge_eta1 = 2500;
56  constexpr float minNoiseLarge_eta1 = 1200;
57  constexpr float maxNoiseLarge_eta2 = 3000;
58  constexpr float minNoiseLarge_eta2 = 2500;
59 
60 } // namespace
61 
62 using namespace MuonGM;
63 
64 /*******************************************************************************/
65 MM_DigitizationTool::MM_DigitizationTool(const std::string& type, const std::string& name, const IInterface* parent) :
67 
68 /*******************************************************************************/
69 // member function implementation
70 //--------------------------------------------
72  ATH_MSG_DEBUG("MM_DigitizationTool:: in initialize()");
73 
74  ATH_CHECK(m_rndmSvc.retrieve());
75 
76  // Initialize transient detector store and MuonGeoModel OR MuonDetDescrManager
78  ATH_CHECK(m_idHelperSvc.retrieve());
79 
80  if (m_hitsContainerKey.key().empty()) {
81  ATH_MSG_FATAL("Property InputObjectName not set !");
82  return StatusCode::FAILURE;
83  }
84 
86  ATH_MSG_DEBUG("Input objects in container: '" << m_inputObjectName << "'");
87 
88  // Pile-up merge service
89  if (m_onlyUseContainerName) { ATH_CHECK(m_mergeSvc.retrieve()); }
90 
91  // Initialize ReadHandleKey
92  ATH_CHECK(m_hitsContainerKey.initialize());
93 
94  // Initialize the output WriteHandleKeys
97  ATH_MSG_DEBUG("Output Digits: '" << m_outputDigitCollectionKey.key() << "'");
98 
101  ATH_CHECK(m_calibrationTool.retrieve());
102 
103  // simulation identifier helper
105 
106  // get gas properties from calibration tool
107  const NSWCalib::MicroMegaGas prop = m_calibrationTool->mmGasProperties();
108  const float peakTime = m_calibrationTool->mmPeakTime();
109 
111  strip_cfg.NSWCalib::MicroMegaGas::operator=(prop);
113  strip_cfg.qThreshold = m_qThreshold;
114  strip_cfg.driftGapWidth = m_driftGapWidth;
115  strip_cfg.crossTalk1 = m_crossTalk1;
116  strip_cfg.crossTalk2 = m_crossTalk2;
117  strip_cfg.avalancheGain = m_avalancheGain;
118  m_StripsResponseSimulation = std::make_unique<MM_StripsResponseSimulation>(std::move(strip_cfg));
119 
120 
121  m_timeWindowLowerOffset += peakTime; // account for peak time in time window
122  m_timeWindowUpperOffset += peakTime; // account for peak time in time window
123 
125  elec_sim_cfg.peakTime = peakTime;
126  elec_sim_cfg.timeWindowLowerOffset = m_timeWindowLowerOffset;
127  elec_sim_cfg.timeWindowUpperOffset = m_timeWindowUpperOffset;
128  elec_sim_cfg.vmmDeadtime = m_vmmDeadtime;
129  elec_sim_cfg.vmmUpperGrazeWindow = m_vmmUpperGrazeWindow;
130  elec_sim_cfg.stripDeadTime = m_stripdeadtime;
131  elec_sim_cfg.artDeadTime = m_ARTdeadtime;
132  elec_sim_cfg.useNeighborLogic = m_vmmNeighborLogic;
133  // ElectronicsResponseSimulation Creation
134  m_ElectronicsResponseSimulation = std::make_unique<MM_ElectronicsResponseSimulation>(std::move(elec_sim_cfg));
135 
136  // Configuring various VMM modes of signal readout
137  //
138  std::string vmmReadoutMode = m_vmmReadoutMode;
139  // convert vmmReadoutMode to lower case
140  std::for_each(vmmReadoutMode.begin(), vmmReadoutMode.end(), [](char& c) { c = ::tolower(c); });
141  if (vmmReadoutMode.find("peak") != std::string::npos)
142  m_vmmReadoutMode = "peak";
143  else if (vmmReadoutMode.find("threshold") != std::string::npos)
144  m_vmmReadoutMode = "threshold";
145  else {
146  ATH_MSG_ERROR("MM_DigitizationTool can't interperet vmmReadoutMode option! (Should be 'peak' or 'threshold'.) Contains: "
147  << m_vmmReadoutMode);
148  return StatusCode::FAILURE;
149  }
150  std::string vmmARTMode = m_vmmARTMode;
151  // convert vmmARTMode to lower case
152  std::for_each(vmmARTMode.begin(), vmmARTMode.end(), [](char& c) { c = ::tolower(c); });
153  if (vmmARTMode.find("peak") != std::string::npos)
154  m_vmmARTMode = "peak";
155  else if (vmmARTMode.find("threshold") != std::string::npos)
156  m_vmmARTMode = "threshold";
157  else
159  "MM_DigitizationTool can't interperet vmmARTMode option! (Should be 'peak' or 'threshold'.) Contains: " << m_vmmARTMode);
160 
161  if (m_doSmearing) ATH_MSG_INFO("Running in smeared mode!");
162 
163  // get shortest and longest strip length for threshold scaling
164  Identifier tmpId{0}; // temporary identifier to work with ReadoutElement
165  const MuonGM::MuonDetectorManager* muonGeoMgr{nullptr};
166  ATH_CHECK(detStore()->retrieve(muonGeoMgr));
167  int stripNumberShortestStrip{-1}, stripNumberLongestStrip{-1};
168  Identifier tmpIdShortestStrip{0},tmpIdLongestStrip{0};
169  float shortestStripLength{FLT_MAX}, longestStripLength{0};
170 
171  //============================
172  //SMALL SECTORS - ETA 1 CHAMBERS
173  // identifier for first gas gap in a small MM sector, layer is eta layer
174  tmpId = m_idHelperSvc->mmIdHelper().channelID("MMS", 1, 1, 1, 1, 1);
175  const MuonGM::MMReadoutElement* detectorReadoutElement = muonGeoMgr->getMMReadoutElement(tmpId);
176  stripNumberShortestStrip = (detectorReadoutElement->getDesign(tmpId))->nMissedBottomEta + 1;
177  tmpIdShortestStrip = m_idHelperSvc->mmIdHelper().channelID("MMS", 1, 1, 1, 1, stripNumberShortestStrip); // identifier for the shortest strip
178  shortestStripLength = detectorReadoutElement->stripLength(tmpIdShortestStrip);
179 
180  stripNumberLongestStrip = (detectorReadoutElement->getDesign(tmpId))->totalStrips - (detectorReadoutElement->getDesign(tmpId))->nMissedTopEta;
181  tmpIdLongestStrip = m_idHelperSvc->mmIdHelper().channelID("MMS", 1, 1, 1, 1, stripNumberLongestStrip); // identifier for the longest strip
182  longestStripLength = detectorReadoutElement->stripLength(tmpIdLongestStrip);
183 
184  // now get the slope and intercept for the threshold scaling
185  // function is m_noiseSlope * stripLength + m_noiseIntercept
187  NoiseCalibConstants& noise_smallEta1 = m_noiseParams[m_idHelperSvc->stationName(tmpId)];
188  noise_smallEta1.slope = (maxNoiseSmall_eta1 - minNoiseSmall_eta1) / (longestStripLength - shortestStripLength);
189  noise_smallEta1.intercept = minNoiseSmall_eta1 - noise_smallEta1.slope* shortestStripLength;
190  //============================
191 
192  //============================
193  //SMALL SECTORS - ETA 2 CHAMBERS
194  // identifier for first gas gap in a small MM sector, layer is eta layer
195  tmpId = m_idHelperSvc->mmIdHelper().channelID("MMS", 2, 1, 1, 1, 1);
196  detectorReadoutElement = muonGeoMgr->getMMReadoutElement(tmpId);
197  stripNumberShortestStrip = (detectorReadoutElement->getDesign(tmpId))->nMissedBottomEta + 1;
198  tmpIdShortestStrip = m_idHelperSvc->mmIdHelper().channelID("MMS", 2, 1, 1, 1, stripNumberShortestStrip); // identifier for the shortest strip
199  shortestStripLength = detectorReadoutElement->stripLength(tmpIdShortestStrip);
200 
201  stripNumberLongestStrip = (detectorReadoutElement->getDesign(tmpId))->totalStrips - (detectorReadoutElement->getDesign(tmpId))->nMissedTopEta;
202  tmpIdLongestStrip = m_idHelperSvc->mmIdHelper().channelID("MMS", 2, 1, 1, 1, stripNumberLongestStrip); // identifier for the longest strip
203  longestStripLength = detectorReadoutElement->stripLength(tmpIdLongestStrip);
204 
205  // now get the slope and intercept for the threshold scaling
206  // function is m_noiseSlope * stripLength + m_noiseIntercept
208  NoiseCalibConstants& noise_smallEta2 = m_noiseParams[m_idHelperSvc->stationName(tmpId)*2];
209  noise_smallEta2.slope = (maxNoiseSmall_eta2 - minNoiseSmall_eta2) / (longestStripLength - shortestStripLength);
210  noise_smallEta2.intercept = minNoiseSmall_eta2 - noise_smallEta2.slope * shortestStripLength;
211  //============================
212 
213  //============================
214  //LARGE SECTORS - ETA 1 CHAMBERS
215  // identifier for first gas gap in a small MM sector, layer is eta layer
216  tmpId = m_idHelperSvc->mmIdHelper().channelID("MML", 1, 1, 1, 1, 1);
217  detectorReadoutElement = muonGeoMgr->getMMReadoutElement(tmpId);
218  stripNumberShortestStrip = (detectorReadoutElement->getDesign(tmpId))->nMissedBottomEta + 1;
219  tmpIdShortestStrip = m_idHelperSvc->mmIdHelper().channelID("MML", 1, 1, 1, 1, stripNumberShortestStrip); // identifier for the shortest strip
220  shortestStripLength = detectorReadoutElement->stripLength(tmpIdShortestStrip);
221 
222  stripNumberLongestStrip = (detectorReadoutElement->getDesign(tmpId))->totalStrips - (detectorReadoutElement->getDesign(tmpId))->nMissedTopEta;
223  tmpIdLongestStrip = m_idHelperSvc->mmIdHelper().channelID("MML", 1, 1, 1, 1, stripNumberLongestStrip); // identifier for the longest strip
224  longestStripLength = detectorReadoutElement->stripLength(tmpIdLongestStrip);
225 
226  // now get the slope and intercept for the threshold scaling
227  // function is m_noiseSlope * stripLength + m_noiseIntercept
229  NoiseCalibConstants& noise_largeEta1 = m_noiseParams[m_idHelperSvc->stationName(tmpId)];
230  noise_largeEta1.slope = (maxNoiseLarge_eta1 - minNoiseLarge_eta1) / (longestStripLength - shortestStripLength);
231  noise_largeEta1.intercept = minNoiseLarge_eta1 - noise_largeEta1.slope * shortestStripLength;
232  //============================
233 
234  //============================
235  //LARGE SECTORS - ETA 2 CHAMBERS
236  // identifier for first gas gap in a small MM sector, layer is eta layer
237  tmpId = m_idHelperSvc->mmIdHelper().channelID("MML", 2, 1, 1, 1, 1);
238  detectorReadoutElement = muonGeoMgr->getMMReadoutElement(tmpId);
239  stripNumberShortestStrip = (detectorReadoutElement->getDesign(tmpId))->nMissedBottomEta + 1;
240  tmpIdShortestStrip = m_idHelperSvc->mmIdHelper().channelID("MML", 2, 1, 1, 1, stripNumberShortestStrip); // identifier for the shortest strip
241  shortestStripLength = detectorReadoutElement->stripLength(tmpIdShortestStrip);
242 
243  stripNumberLongestStrip = (detectorReadoutElement->getDesign(tmpId))->totalStrips - (detectorReadoutElement->getDesign(tmpId))->nMissedTopEta;
244  tmpIdLongestStrip = m_idHelperSvc->mmIdHelper().channelID("MML", 2, 1, 1, 1, stripNumberLongestStrip); // identifier for the longest strip
245  longestStripLength = detectorReadoutElement->stripLength(tmpIdLongestStrip);
246 
247  // now get the slope and intercept for the threshold scaling
248  // function is m_noiseSlope * stripLength + m_noiseIntercept
250  NoiseCalibConstants& noise_largeEta2 = m_noiseParams[m_idHelperSvc->stationName(tmpId)*2];
251  noise_largeEta2.slope = (maxNoiseLarge_eta2 - minNoiseLarge_eta2) / (longestStripLength - shortestStripLength);
252  noise_largeEta2.intercept = minNoiseLarge_eta2 - noise_largeEta2.slope * shortestStripLength;
253  //============================
254 
255  ATH_MSG_DEBUG("Configuration MM_DigitizationTool ");
256  ATH_MSG_INFO("RndmSvc " << m_rndmSvc);
257  ATH_MSG_INFO("RndmEngine " << m_rndmEngineName);
258  ATH_MSG_DEBUG("InputObjectName " << m_inputObjectName);
259  ATH_MSG_DEBUG("OutputObjectName " << m_outputDigitCollectionKey.key());
260  ATH_MSG_DEBUG("OutputSDOName " << m_outputSDO_CollectionKey.key());
261  ATH_MSG_DEBUG("UseTimeWindow " << m_useTimeWindow);
262  ATH_MSG_DEBUG("CheckSimHits " << m_checkMMSimHits);
263  ATH_MSG_DEBUG("Threshold " << m_qThreshold);
264  ATH_MSG_DEBUG("TransverseDiffusSigma " << m_StripsResponseSimulation->getTransversDiffusionSigma());
265  ATH_MSG_DEBUG("LogitundinalDiffusSigma" << m_StripsResponseSimulation->getLongitudinalDiffusionSigma());
266  ATH_MSG_DEBUG("Interaction density mean: " << m_StripsResponseSimulation->getInteractionDensityMean());
267  ATH_MSG_DEBUG("Interaction density sigma: " << m_StripsResponseSimulation->getInteractionDensitySigma());
268  ATH_MSG_DEBUG("DriftVelocity stripResponse: " << m_StripsResponseSimulation->getDriftVelocity());
269  ATH_MSG_DEBUG("crossTalk1 " << m_crossTalk1);
270  ATH_MSG_DEBUG("crossTalk2 " << m_crossTalk2);
271  ATH_MSG_DEBUG("EnergyThreshold " << m_energyThreshold);
272 
273  return StatusCode::SUCCESS;
274 }
275 /*******************************************************************************/
276 //----------------------------------------------------------------------
277 // PrepareEvent method:
278 //----------------------------------------------------------------------
279 StatusCode MM_DigitizationTool::prepareEvent(const EventContext& /*ctx*/, unsigned int nInputEvents) {
280  ATH_MSG_DEBUG("MM_DigitizationTool::prepareEvent() called for " << nInputEvents << " input events");
281 
282  m_MMHitCollList.clear();
283 
285  m_timedHitCollection_MM = std::make_unique<TimedHitCollection<MMSimHit>>();
286  } else {
287  ATH_MSG_ERROR("m_timedHitCollection_MM is not null");
288  return StatusCode::FAILURE;
289  }
290 
291  return StatusCode::SUCCESS;
292 }
293 /*******************************************************************************/
295  ATH_MSG_DEBUG("MM_DigitizationTool::in processBunchXing()" << bunchXing);
296 
298  TimedHitCollList hitCollList;
299 
300  if (!(m_mergeSvc->retrieveSubSetEvtData(m_inputObjectName, hitCollList, bunchXing, bSubEvents, eSubEvents).isSuccess()) &&
301  hitCollList.empty()) {
302  ATH_MSG_ERROR("Could not fill TimedHitCollList");
303  return StatusCode::FAILURE;
304  } else {
305  ATH_MSG_VERBOSE(hitCollList.size() << " MMSimHitCollection with key " << m_inputObjectName << " found");
306  }
307 
308  TimedHitCollList::iterator iColl(hitCollList.begin());
309  TimedHitCollList::iterator endColl(hitCollList.end());
310 
311  // Iterating over the list of collections
312  for (; iColl != endColl; ++iColl) {
313  auto hitCollPtr = std::make_unique<MMSimHitCollection>(*iColl->second);
314  PileUpTimeEventIndex timeIndex(iColl->first);
315 
316  ATH_MSG_DEBUG("MMSimHitCollection found with " << hitCollPtr->size() << " hits");
317  ATH_MSG_VERBOSE("time index info. time: " << timeIndex.time() << " index: " << timeIndex.index() << " type: " << timeIndex.type());
318 
319  m_timedHitCollection_MM->insert(timeIndex, hitCollPtr.get());
320  m_MMHitCollList.push_back(std::move(hitCollPtr));
321  }
322  return StatusCode::SUCCESS;
323 }
324 
325 /*******************************************************************************/
327  // Get next event and extract collection of hit collections:
328  // This is applicable to non-PileUp Event...
329 
330  ATH_MSG_DEBUG("MM_DigitizationTool::getNextEvent()");
331 
332  // get the container(s)
334 
335  // In case of single hits container just load the collection using read handles
336  if (!m_onlyUseContainerName) {
338  if (!hitCollection.isValid()) {
339  ATH_MSG_ERROR("Could not get MMSimHitCollection container " << hitCollection.name() << " from store " << hitCollection.store());
340  return StatusCode::FAILURE;
341  }
342 
343  // create a new hits collection
344  m_timedHitCollection_MM = std::make_unique<TimedHitCollection<MMSimHit>>(1);
345  m_timedHitCollection_MM->insert(0, hitCollection.cptr());
346  ATH_MSG_DEBUG("MMSimHitCollection found with " << hitCollection->size() << " hits");
347  return StatusCode::SUCCESS;
348  }
349 
350  // this is a list<info<time_t, DataLink<MMSimHitCollection> > >
351  TimedHitCollList hitCollList;
352 
353  ATH_CHECK(m_mergeSvc->retrieveSubEvtsData(m_inputObjectName, hitCollList));
354  if (hitCollList.empty()) {
355  ATH_MSG_ERROR("TimedHitCollList has size 0");
356  return StatusCode::FAILURE;
357  } else {
358  ATH_MSG_DEBUG(hitCollList.size() << " MicroMegas SimHitCollections with key " << m_inputObjectName << " found");
359  }
360 
361  // create a new hits collection - Define Hit Collection
362  if (m_timedHitCollection_MM == nullptr) {
363  m_timedHitCollection_MM = std::make_unique<TimedHitCollection<MMSimHit>>();
364  } else {
365  ATH_MSG_ERROR("m_timedHitCollection_MM is not null");
366  return StatusCode::FAILURE;
367  }
368 
369  // now merge all collections into one
370  TimedHitCollList::iterator iColl(hitCollList.begin());
371  TimedHitCollList::iterator endColl(hitCollList.end());
372 
373  // loop on the hit collections
374  while (iColl != endColl) {
375  const MMSimHitCollection* tmpColl(iColl->second);
376  m_timedHitCollection_MM->insert(iColl->first, tmpColl);
377  ATH_MSG_DEBUG("MMSimHitCollection found with " << tmpColl->size() << " hits");
378  ++iColl;
379  }
380  return StatusCode::SUCCESS;
381 }
382 /*******************************************************************************/
383 StatusCode MM_DigitizationTool::mergeEvent(const EventContext& ctx) {
384  ATH_MSG_VERBOSE("MM_DigitizationTool::in mergeEvent()");
385 
387 
388  // reset the pointer
389  m_timedHitCollection_MM.reset();
390 
391  // clear cloned list
392  m_MMHitCollList.clear();
393  return StatusCode::SUCCESS;
394 }
395 /*******************************************************************************/
396 StatusCode MM_DigitizationTool::digitize(const EventContext& ctx) { return this->processAllSubEvents(ctx); }
397 /*******************************************************************************/
399  ATH_MSG_DEBUG("MM_DigitizationTool::processAllSubEvents()");
400 
401  // merging of the hit collection in getNextEvent method
402 
404 
406 
407  // reset the pointer
408  m_timedHitCollection_MM.reset();
409  return StatusCode::SUCCESS;
410 }
411 
412 /*******************************************************************************/
414  CLHEP::HepRandomEngine* rndmEngine = getRandomEngine(m_rndmEngineName, ctx);
415 
417  if (!muonGeoMgrHandle.isValid()) {
418  ATH_MSG_FATAL("Failed to retrieve the detector manager from the conditiosn store");
419  return StatusCode::FAILURE;
420  }
421  const MuonGM::MuonDetectorManager* muonGeoMgr = *muonGeoMgrHandle;
422 
423  // create and record the Digit container in StoreGate
425  ATH_CHECK(digitContainer.record(std::make_unique<MmDigitContainer>(m_idHelperSvc->mmIdHelper().detectorElement_hash_max())));
426  ATH_MSG_DEBUG("MmDigitContainer recorded in StoreGate.");
427 
428  // Create and record the SDO container in StoreGate
430  ATH_CHECK(sdoContainer.record(std::make_unique<MuonSimDataCollection>()));
431  ATH_MSG_DEBUG("MmSDOCollection recorded in StoreGate.");
432 
433 
434  if (m_maskMultiplet == 3) { return StatusCode::SUCCESS; }
435 
436  // Perform null check on m_thpcCSC
438  ATH_MSG_ERROR("m_timedHitCollection_MM is null");
439  return StatusCode::FAILURE;
440  }
441 
442 
443  // iterate over hits and fill id-keyed drift time map
445 
446  std::vector<std::unique_ptr<MmDigitCollection> > collections;
447 
448  // nextDetectorElement-->sets an iterator range with the hits of current detector element , returns a bool when done
449  const MmIdHelper& idHelper{m_idHelperSvc->mmIdHelper()};
450  while (m_timedHitCollection_MM->nextDetectorElement(i, e)) {
451  Identifier layerID;
452  std::vector<MM_ElectronicsToolInput> v_stripDigitOutput;
453 
454  // Loop over the hits:
455  while (i != e) {
457  //
458  // Hit Information And Preparation
459  //
460  TimedHitPtr<MMSimHit> phit = *i++;
461  const double eventTime = phit.eventTime();
462  const MMSimHit& hit(*phit);
463 
464  const double hitKineticEnergy = hit.kineticEnergy();
465  if (hitKineticEnergy <= 0) continue;
466 
467  const Amg::Vector3D& globalHitPosition = hit.globalPosition();
468 
469  const double globalHitTime = hit.globalTime();
470  const double tofCorrection = globalHitPosition.mag() / CLHEP::c_light;
471  const double bunchTime = globalHitTime - tofCorrection + eventTime;
472 
473  const int hitID = hit.MMId();
474  // the G4 time or TOF from IP
475  // double G4Time(hit.globalTime());
476  // see what are the members of MMSimHit
477 
478  // convert sim id helper to offline id
479  MM_SimIdToOfflineId simToOffline(&idHelper);
480 
481  // get the hit Identifier and info
482  int simId = hit.MMId();
483  layerID = simToOffline.convert(simId);
484 
486  if (m_doSmearing) {
487  bool acceptHit = true;
488  ATH_CHECK(m_smearingTool->isAccepted(layerID, acceptHit,rndmEngine));
489  if (!acceptHit) {
490  ATH_MSG_DEBUG("Dropping the hit - smearing tool");
491  continue;
492  }
493  }
494  const HepMcParticleLink particleLink = HepMcParticleLink::getRedirectedLink(phit->particleLink(), phit.eventId(), ctx); // This link should now correctly resolve to the TruthEvent McEventCollection in the main StoreGateSvc.
495  // Read the information about the Micro Megas hit
496  ATH_MSG_DEBUG("> hitID " << hitID << " Hit bunch time " << bunchTime << " tot " << globalHitTime << " tof/G4 time "
497  << hit.globalTime() << " globalHitPosition " << globalHitPosition << "hit: r "
498  << globalHitPosition.perp() << " z " << globalHitPosition.z() << " mclink " << particleLink
499  << m_idHelperSvc->toStringGasGap(layerID));
500 
501  // For collection of inputs to throw back in SG
502 
503  // remove hits in masked multiplet
504  if (m_maskMultiplet == idHelper.multilayer(layerID)) continue;
505 
506  //
507  // Hit Information And Preparation
508  //
510 
512  //
513  // Sanity Checks
514  //
515  if (!m_idHelperSvc->isMM(layerID)) {
516  ATH_MSG_WARNING("layerID does not represent a valid MM layer: "<< m_idHelperSvc->toString(layerID));
517  continue;
518  }
519 
520  // get readout element
521  const MuonGM::MMReadoutElement* detectorReadoutElement = muonGeoMgr->getMMReadoutElement(layerID);
522  if (!detectorReadoutElement) {
523  ATH_MSG_WARNING("Failed to retrieve detector element for: " << m_idHelperSvc->toString(layerID));
524  continue;
525  }
526  const std::array<int, 4>& readoutSide=detectorReadoutElement->getReadoutSide();
527 
528  //
529  // Sanity Checks
530  //
532 
533  const std::string stName = m_idHelperSvc->stationNameString(layerID);
534 
535 
537  //
538  // Angles, Geometry, and Coordinates. Oh my!
539  //
540 
541  // Surface
542  const Trk::PlaneSurface& surf = detectorReadoutElement->surface(layerID);
543 
544  // Calculate The Inclination Angle
545  // Angle
546  const Amg::Vector3D globalHitDirection = hit.globalDirection();
547  Trk::LocalDirection localHitDirection;
548  surf.globalToLocalDirection(globalHitDirection, localHitDirection);
549 
550  // This is not an incident angle yet. It's atan(z/x),
551  // ... so it's the complement of the angle w.r.t. a vector normal to the detector surface
552  float inAngleCompliment_XZ = localHitDirection.angleXZ() / CLHEP::degree;
553  float inAngleCompliment_YZ = localHitDirection.angleYZ() / CLHEP::degree;
554 
555  // This is basically to handle the atan ambiguity
556  if (inAngleCompliment_XZ < 0.0) inAngleCompliment_XZ += 180;
557  if (inAngleCompliment_YZ < 0.0) inAngleCompliment_YZ += 180;
558 
559  // This gets the actual incidence angle from its complement.
560  float inAngle_XZ = 90. - inAngleCompliment_XZ;
561  float inAngle_YZ = 90. - inAngleCompliment_YZ;
562 
563  ATH_MSG_DEBUG("At eta: " << m_idHelperSvc->toString(layerID)
564  << " Readout Side: " << (readoutSide).at(m_muonHelper->GetLayer(simId) - 1)
565  << " Layer: " << m_muonHelper->GetLayer(simId) << "\n\t\t\t inAngle_XZ (degrees): " << inAngle_XZ
566  << " inAngle_YZ (degrees): " << inAngle_YZ);
567 
568  // compute the hit position on the readout plane (same as in MuonFastDigitization)
569  Amg::Vector3D stripLayerPosition = surf.transform().inverse() * globalHitPosition;
570  Amg::Vector2D positionOnSurfaceUnprojected{stripLayerPosition.x(), stripLayerPosition.y()};
571 
572  Amg::Vector3D localDirection = surf.transform().inverse().linear() * globalHitDirection;
573  Amg::Vector3D localDirectionTime{Amg::Vector3D::Zero()};
574 
575  // drift direction in backwards-chamber should be opposite to the incident direction.
576  if ((readoutSide).at(idHelper.gasGap(layerID) - 1) == 1) {
577  localDirectionTime = localDirection;
578  inAngle_XZ = (-inAngle_XZ);
579  } else
580  localDirectionTime = surf.transform().inverse().linear() * globalHitDirection;
581 
583  int gasGap = idHelper.gasGap(layerID);
584  double shift = 0.5 * detectorReadoutElement->getDesign(layerID)->thickness;
585  double scale = 0.0;
586  if (gasGap == 1 || gasGap == 3) {
587  scale = -(stripLayerPosition.z() + shift) / localDirection.z();
588  } else if (gasGap == 2 || gasGap == 4) {
589  scale = -(stripLayerPosition.z() - shift) / localDirection.z();
590  }
591 
592  const Amg::Vector3D hitOnSurface = stripLayerPosition + scale * localDirection;
593  Amg::Vector2D positionOnSurface{hitOnSurface.x(), hitOnSurface.y()};
594 
595  // Account For Time Offset
596  double shiftTimeOffset = (globalHitTime - tofCorrection) * m_StripsResponseSimulation->getDriftVelocity();
597  Amg::Vector3D hitAfterTimeShift(hitOnSurface.x(), hitOnSurface.y(), shiftTimeOffset);
598  Amg::Vector3D hitAfterTimeShiftOnSurface = hitAfterTimeShift - (shiftTimeOffset / localDirectionTime.z()) * localDirectionTime;
599 
600  if (std::abs(hitAfterTimeShiftOnSurface.z()) > 0.1)
601  ATH_MSG_WARNING("Bad propagation to surface after time shift " << hitAfterTimeShiftOnSurface);
602 
603  // moving the hit position to the center of the gap for the SDO position
604  double scaleSDO = -stripLayerPosition.z() / localDirection.z();
605  Amg::Vector3D hitAtCenterOfGasGap = stripLayerPosition + scaleSDO * localDirection;
606  Amg::Vector3D hitAtCenterOfGasGapGlobal = surf.transform() * hitAtCenterOfGasGap;
607  ATH_MSG_DEBUG("strip layer position z" << stripLayerPosition.z() << "hitAtCenterOfGasGap "
608  << Amg::toString(hitAtCenterOfGasGap)<< " gas gap " << gasGap);
609 
610  // Don't consider electron hits below m_energyThreshold
611  if (hit.kineticEnergy() < m_energyThreshold && std::abs(hit.particleEncoding()) == 11) {
612  continue;
613  }
614 
615  // Perform Bound Check (making the call from the detector element to consider edge passivation)
616  if (!detectorReadoutElement->insideActiveBounds(layerID, positionOnSurface)) {
617  ATH_MSG_DEBUG("m_exitcode = 1 : shiftTimeOffset = " << shiftTimeOffset << " "<<Amg::toString(hitOnSurface));
618  continue;
619  }
620 
621  int stripNumber = detectorReadoutElement->stripNumber(positionOnSurface, layerID);
622  Amg::Vector2D tmp(stripLayerPosition.x(), stripLayerPosition.y());
623 
624  if (stripNumber == -1) {
625  ATH_MSG_WARNING("!!! Failed to obtain strip number "
626  << m_idHelperSvc->mmIdHelper().print_to_string(layerID) << "\n\t\t with pos " << positionOnSurface << " z "
627  << stripLayerPosition.z() << " eKin: " << hit.kineticEnergy() << " eDep: " << hit.depositEnergy()
628  << " unprojectedStrip: " << detectorReadoutElement->stripNumber(positionOnSurfaceUnprojected, layerID));
629  continue;
630  }
631 
632  // Re-definition Of ID
633  Identifier parentID = idHelper.parentID(layerID);
634  Identifier digitID = idHelper.channelID(parentID,
635  idHelper.multilayer(layerID),
636  idHelper.gasGap(layerID), stripNumber);
637 
638  // contain (name, eta, phi, multiPlet)
639  const IdentifierHash moduleHash = m_idHelperSvc->moduleHash(layerID);
640 
641  ATH_MSG_DEBUG(" looking up collection using moduleHash "
642  << static_cast<int>(moduleHash) << " " << m_idHelperSvc->toString(layerID)
643  << " digitID: " << m_idHelperSvc->toString(digitID));
644 
645  const MuonGM::MuonChannelDesign* mmChannelDesign = detectorReadoutElement->getDesign(digitID);
646  double distToChannel = mmChannelDesign->distanceToChannel(positionOnSurface, stripNumber);
647 
648  // check whether retrieved distance is greater than strip width
649  // first retrieve the strip number from position by geometrical check
650  int geoStripNumber = mmChannelDesign->channelNumber(positionOnSurface);
651  if (geoStripNumber == -1) ATH_MSG_WARNING("Failed to retrieve strip number");
652  // retrieve channel position of closest active strip
654  if (!mmChannelDesign->center(geoStripNumber, chPos)) {
655  ATH_MSG_DEBUG("Failed to retrieve channel position for closest strip number "
656  << geoStripNumber
657  << ". Can happen if hit was found in non-active strip. Will not digitize it, since in data, "
658  << "we would probably not find a cluster formed well enough to survive reconstruction.");
659  continue;
660  }
661 
662  MagField::AtlasFieldCache fieldCache;
664  const AtlasFieldCacheCondObj* fieldCondObj{*readHandle};
665  if (!fieldCondObj) {
666  ATH_MSG_ERROR("doDigitization: Failed to retrieve AtlasFieldCacheCondObj with key " << m_fieldCondObjInputKey.key());
667  return StatusCode::FAILURE;
668  }
669  fieldCondObj->getInitializedCache(fieldCache);
670 
671  // Obtain Magnetic Field At Detector Surface
672  Amg::Vector3D hitOnSurfaceGlobal = surf.transform() * hitOnSurface;
673  Amg::Vector3D magneticField{Amg::Vector3D::Zero()};
674  fieldCache.getField(hitOnSurfaceGlobal.data(), magneticField.data());
675 
676  // B-field in local cordinate, X ~ #strip, increasing to outer R, Z ~ global Z but positive to IP
677  Amg::Vector3D localMagneticField = surf.transform().linear().inverse() * magneticField;
678  if ((readoutSide).at(m_muonHelper->GetLayer(simId) - 1) == -1)
679  localMagneticField[Amg::y] = -localMagneticField[Amg::y];
680 
681  //
682  // Angles, Geometry, and Coordinates. Oh my!
683  //
685 
687  //
688  // Strip Response Simulation For This Hit
689  //
690  const MM_DigitToolInput stripDigitInput(
691  stripNumber, distToChannel, inAngle_XZ, inAngle_YZ, localMagneticField,
692  detectorReadoutElement->numberOfMissingBottomStrips(layerID) + 1,
693  detectorReadoutElement->numberOfStrips(layerID) - detectorReadoutElement->numberOfMissingTopStrips(layerID),
694  idHelper.gasGap(layerID), eventTime + globalHitTime);
695 
696  // fill the SDO collection in StoreGate
697  // create here deposit for MuonSimData, link and tof
698  //
699  // Since we have output based on channel, instead of hit, the SDO and digit ID are No longer meaningless. 2016/06/27 T.Saito
700  //
701  // digitize input for strip response
702 
703  MuonSimData::Deposit deposit(particleLink, MuonMCData(hitOnSurface.x(), hitOnSurface.y()));
704 
705  // Record the SDO collection in StoreGate
706  std::vector<MuonSimData::Deposit> deposits{deposit};
707  MuonSimData simData(std::move(deposits), 0);
708  simData.setPosition(hitAtCenterOfGasGapGlobal);
709  simData.setTime(globalHitTime);
710  sdoContainer->insert(std::make_pair(digitID, simData));
711  ATH_MSG_DEBUG(" added MM SDO " << sdoContainer->size());
712 
713  float gainFraction = 1.0;
714  if (m_doSmearing) {
715  // build identifier including the strip since layerId does not contain teh strip number
716  Identifier id = idHelper.channelID(layerID,
717  idHelper.multilayer(layerID),
718  idHelper.gasGap(layerID), stripNumber);
719  ATH_CHECK(m_smearingTool->getGainFraction(id, gainFraction));
720  }
721  double stripPitch = detectorReadoutElement->getDesign(layerID)->channelWidth();
722 
723  MM_StripToolOutput tmpStripOutput = m_StripsResponseSimulation->GetResponseFrom(stripDigitInput, gainFraction, stripPitch, rndmEngine);
724  MM_ElectronicsToolInput stripDigitOutput(tmpStripOutput.NumberOfStripsPos(), tmpStripOutput.chipCharge(),
725  tmpStripOutput.chipTime(), digitID, hit.kineticEnergy());
726 
727  v_stripDigitOutput.push_back(stripDigitOutput);
728 
729  } // Hit Loop
730 
731  // Now at Detector Element Level (VMM)
732 
733  if (v_stripDigitOutput.empty()) {
734  ATH_MSG_DEBUG("MM_DigitizationTool::doDigitization() -- there is no strip response on this VMM.");
735  continue;
736  }
737 
739  //
740  // VMM Simulation
741  //
742 
743  // Combine all strips (for this VMM) into a single VMM-level object
744  //
745  MM_ElectronicsToolInput stripDigitOutputAllHits = combinedStripResponseAllHits(v_stripDigitOutput);
746  if (!m_idHelperSvc->isMM(stripDigitOutputAllHits.digitID())) {
747  ATH_MSG_WARNING("Identifier from stripdigitOutputAllHits "
748  << m_idHelperSvc->toString(stripDigitOutputAllHits.digitID())
749  << " is not a MM Identifier, skipping");
750  continue;
751  }
752 
753  // Create Electronics Output with peak finding setting
754  //
755 
756  MM_DigitToolOutput electronicsOutputForReadout {m_vmmReadoutMode == "peak"
757  ? m_ElectronicsResponseSimulation->getPeakResponseFrom(stripDigitOutputAllHits)
758  : m_ElectronicsResponseSimulation->getThresholdResponseFrom(stripDigitOutputAllHits)};
759  if (!electronicsOutputForReadout.isValid()) {
760  ATH_MSG_DEBUG("MM_DigitizationTool::doDigitization() -- "<<
761  " there is no electronics response (peak finding mode) even though there is a strip response.");
762  }
763 
764 
765  for (unsigned int firedCh = 0; firedCh < electronicsOutputForReadout.stripPos().size(); ++firedCh) {
766 
767  const int channel = electronicsOutputForReadout.stripPos()[firedCh];
768  float time = electronicsOutputForReadout.stripTime()[firedCh];
769  float charge = electronicsOutputForReadout.stripCharge()[firedCh];
770  bool isValid{false};
771  const Identifier digitID = idHelper.channelID(stripDigitOutputAllHits.digitID(),
772  idHelper.multilayer(stripDigitOutputAllHits.digitID()),
773  idHelper.gasGap(stripDigitOutputAllHits.digitID()),
774  channel, isValid);
775  if (!isValid) {
776  ATH_MSG_DEBUG("Ghost strip fired... Ghost busters... ");
777  continue;
778  }
779  bool acceptStrip = true;
780  if (m_doSmearing) {
782  ATH_CHECK(m_smearingTool->smearTimeAndCharge(digitID, time, charge, acceptStrip, rndmEngine));
783 
784  }
785  if (!acceptStrip) {
786  ATH_MSG_DEBUG("Exaggeated with smearing "<<m_idHelperSvc->toString(digitID));
787  continue;
788  }
789  std::unique_ptr<MmDigit> newDigit = std::make_unique<MmDigit>(digitID, time, charge);
790 
791  const IdentifierHash moduleHash = m_idHelperSvc->moduleHash(digitID);
792  if (moduleHash >= collections.size()) {
793  collections.resize(moduleHash+1);
794  }
795  MmDigitCollection* coll = collections[moduleHash].get();
796  if (!coll) {
797  collections[moduleHash] = std::make_unique<MmDigitCollection>(m_idHelperSvc->chamberId(digitID), moduleHash);
798  coll = collections[moduleHash].get();
799  }
800  coll->push_back(std::move(newDigit));
801  }
802  v_stripDigitOutput.clear();
803  }
804 
805  for (size_t coll_hash = 0; coll_hash < collections.size(); ++coll_hash) {
806  if (collections[coll_hash]) {
807  ATH_CHECK( digitContainer->addCollection (collections[coll_hash].release(), coll_hash) );
808  }
809  }
810 
811  ATH_MSG_DEBUG("MM_Digitization Done!");
812 
813  m_timedHitCollection_MM.reset();
814 
815  return StatusCode::SUCCESS;
816 }
817 
818 MM_ElectronicsToolInput MM_DigitizationTool::combinedStripResponseAllHits(const std::vector<MM_ElectronicsToolInput>& v_stripDigitOutput) {
819  // set up pointer to conditions object
820  const EventContext& ctx = Gaudi::Hive::currentContext();
821 
822  const NswCalibDbThresholdData* thresholdData {nullptr};
825  if (!readThresholds.isValid()) { ATH_MSG_ERROR("Cannot find conditions data container for VMM thresholds!"); }
826  thresholdData = readThresholds.cptr();
827  }
828 
830  if (!muonGeoMgrHandle.isValid()) { ATH_MSG_FATAL("Failed to retrieve the detector manager from the conditiosn store"); }
831  const MuonGM::MuonDetectorManager* muonGeoMgr = *muonGeoMgrHandle;
832 
833  std::vector<int> v_stripStripResponseAllHits;
834  std::vector<std::vector<float>> v_timeStripResponseAllHits;
835  std::vector<std::vector<float>> v_qStripResponseAllHits;
836  std::vector<float> v_stripThresholdResponseAllHits;
837 
838  Identifier digitID = v_stripDigitOutput.at(0).digitID();
839  float max_kineticEnergy = 0.0;
840 
841  // Loop over strip digit output elements
842  for (auto& i_stripDigitOutput : v_stripDigitOutput) {
843  //--- Just to get Digit id with the largest kinetic energy, but the Digit id is no longer meaningful
844  if (i_stripDigitOutput.kineticEnergy() > max_kineticEnergy) {
845  digitID = i_stripDigitOutput.digitID();
846  max_kineticEnergy = i_stripDigitOutput.kineticEnergy();
847  }
848  //---
849  for (size_t i = 0; i < i_stripDigitOutput.NumberOfStripsPos().size(); ++i) {
850  int strip_id = i_stripDigitOutput.NumberOfStripsPos().at(i);
851  bool found = false;
852 
853  for (size_t ii = 0; ii < v_stripStripResponseAllHits.size(); ++ii) {
854  if (v_stripStripResponseAllHits.at(ii) == strip_id) {
855  for (size_t iii = 0; iii < i_stripDigitOutput.chipTime().at(i).size(); ++iii) {
856  v_timeStripResponseAllHits.at(ii).push_back(i_stripDigitOutput.chipTime().at(i).at(iii));
857  v_qStripResponseAllHits.at(ii).push_back(i_stripDigitOutput.chipCharge().at(i).at(iii));
858  }
859  found = true;
860  }
861  }
862  if (!found) { // strip id not in vector, add new entry
863  v_stripStripResponseAllHits.push_back(strip_id);
864  v_timeStripResponseAllHits.push_back(i_stripDigitOutput.chipTime().at(i));
865  v_qStripResponseAllHits.push_back(i_stripDigitOutput.chipCharge().at(i));
866  if (m_useCondThresholds) {
867  const Identifier id = m_idHelperSvc->mmIdHelper().channelID(digitID, m_idHelperSvc->mmIdHelper().multilayer(digitID),
868  m_idHelperSvc->mmIdHelper().gasGap(digitID), strip_id);
869  float threshold = 0;
870  if (!thresholdData->getThreshold(id, threshold))
871  ATH_MSG_ERROR("Cannot find retrieve VMM threshold from conditions data base!");
872  v_stripThresholdResponseAllHits.push_back(threshold);
873  } else if (m_useThresholdScaling) {
874  Identifier id = m_idHelperSvc->mmIdHelper().channelID(digitID, m_idHelperSvc->mmIdHelper().multilayer(digitID),
875  m_idHelperSvc->mmIdHelper().gasGap(digitID), strip_id);
876  const MuonGM::MMReadoutElement* detectorReadoutElement = muonGeoMgr->getMMReadoutElement(id);
877  float stripLength = detectorReadoutElement->stripLength(id);
878  const int noise_id = m_idHelperSvc->stationName(digitID) * std::abs(m_idHelperSvc->stationEta(digitID));
879  const NoiseCalibConstants& noise = m_noiseParams.at(noise_id);
880  float threshold = (noise.slope * stripLength + noise.intercept) * m_thresholdScaleFactor;
881  v_stripThresholdResponseAllHits.push_back(threshold);
882  } else {
883  v_stripThresholdResponseAllHits.push_back(m_electronicsThreshold);
884  }
885  }
886  }
887  }
888 
889  MM_ElectronicsToolInput stripDigitOutputAllHits(v_stripStripResponseAllHits, v_qStripResponseAllHits, v_timeStripResponseAllHits,
890  v_stripThresholdResponseAllHits, digitID, max_kineticEnergy);
891 
892  return stripDigitOutputAllHits;
893 }
894 /*******************************************************************************/
895 bool MM_DigitizationTool::checkMMSimHit(const MMSimHit& /*hit*/) const { return true; }
896 
897 CLHEP::HepRandomEngine* MM_DigitizationTool::getRandomEngine(const std::string& streamName, const EventContext& ctx) const {
898  ATHRNG::RNGWrapper* rngWrapper = m_rndmSvc->getEngine(this, streamName);
899  rngWrapper->setSeed(streamName, ctx);
900  return rngWrapper->getEngine(ctx);
901 }
MmDigitCollection
Definition: MmDigitCollection.h:18
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
MM_DigitizationTool::m_DetectorManagerKey
SG::ReadCondHandleKey< MuonGM::MuonDetectorManager > m_DetectorManagerKey
Definition: MM_DigitizationTool.h:190
ATHRNG::RNGWrapper::setSeed
void setSeed(const std::string &algName, const EventContext &ctx)
Set the random seed using a string (e.g.
Definition: RNGWrapper.h:169
MM_DigitizationTool::m_thresholdScaleFactor
Gaudi::Property< float > m_thresholdScaleFactor
Definition: MM_DigitizationTool.h:179
MM_DigitizationTool::m_vmmUpperGrazeWindow
Gaudi::Property< float > m_vmmUpperGrazeWindow
Definition: MM_DigitizationTool.h:185
MMSimHit
Definition: MMSimHit.h:15
dumpTgcDigiDeadChambers.gasGap
list gasGap
Definition: dumpTgcDigiDeadChambers.py:33
MuonSimData::Deposit
std::pair< HepMcParticleLink, MuonMCData > Deposit
Definition: MuonSimData.h:66
MM_DigitizationTool::m_ARTdeadtime
Gaudi::Property< float > m_ARTdeadtime
Definition: MM_DigitizationTool.h:166
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
MM_SimIdToOfflineId.h
MuonGM
Ensure that the Athena extensions are properly loaded.
Definition: GeoMuonHits.h:27
MM_DigitizationTool::m_timeWindowLowerOffset
Gaudi::Property< double > m_timeWindowLowerOffset
Definition: MM_DigitizationTool.h:134
NswCalibDbThresholdData
Definition: NswCalibDbThresholdData.h:21
MM_DigitizationTool::m_maskMultiplet
Gaudi::Property< int > m_maskMultiplet
Definition: MM_DigitizationTool.h:140
NswCalibDbTimeChargeData::CalibConstants
Helper struct to cache all calibration constants in a common place of the memory.
Definition: NswCalibDbTimeChargeData.h:28
MuonGM::MMReadoutElement::insideActiveBounds
bool insideActiveBounds(const Identifier &id, const Amg::Vector2D &locpos, double tol1=0., double tol2=0.) const
boundary check Wrapper Trk::PlaneSurface::insideBounds() taking into account the passivated width
Definition: MMReadoutElement.h:257
plotting.yearwise_efficiency.channel
channel
Definition: yearwise_efficiency.py:28
SG::ReadCondHandle
Definition: ReadCondHandle.h:44
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
SG::ReadHandle::cptr
const_pointer_type cptr()
Dereference the pointer.
Surface.h
AtlasFieldCacheCondObj
Definition: AtlasFieldCacheCondObj.h:19
MM_SimIdToOfflineId
Definition: MM_SimIdToOfflineId.h:12
IdentifiableContainerMT::addCollection
virtual StatusCode addCollection(const T *coll, IdentifierHash hashId) override final
insert collection into container with id hash if IDC should not take ownership of collection,...
Definition: IdentifiableContainerMT.h:300
MM_DigitizationTool::doDigitization
StatusCode doDigitization(const EventContext &ctx)
Definition: MM_DigitizationTool.cxx:413
MicromegasHitIdHelper.h
MuonGM::MuonChannelDesign::channelNumber
int channelNumber(const Amg::Vector2D &pos) const
calculate local channel number, range 1=nstrips like identifiers. Returns -1 if out of range
Definition: MuonChannelDesign.h:198
Amg::Vector2D
Eigen::Matrix< double, 2, 1 > Vector2D
Definition: GeoPrimitives.h:48
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:70
MM_DigitizationTool::getRandomEngine
CLHEP::HepRandomEngine * getRandomEngine(const std::string &streamName, const EventContext &ctx) const
Definition: MM_DigitizationTool.cxx:897
MM_StripToolOutput::NumberOfStripsPos
const std::vector< int > & NumberOfStripsPos() const
Definition: MM_StripToolOutput.h:17
SG::VarHandleBase::name
const std::string & name() const
Return the StoreGate ID for the referenced object.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleBase.cxx:75
MM_DigitizationTool::m_mergeSvc
ServiceHandle< PileUpMergeSvc > m_mergeSvc
Definition: MM_DigitizationTool.h:173
MM_DigitizationTool::MM_DigitizationTool
MM_DigitizationTool(const std::string &type, const std::string &name, const IInterface *parent)
Definition: MM_DigitizationTool.cxx:65
MuonGM::MMReadoutElement::getDesign
const MuonChannelDesign * getDesign(const Identifier &id) const
returns the MuonChannelDesign class for the given identifier
Definition: MMReadoutElement.h:193
AtlasHitsVector
Definition: AtlasHitsVector.h:33
Amg::y
@ y
Definition: GeoPrimitives.h:35
MM_DigitizationTool::initialize
virtual StatusCode initialize() override final
Initialize.
Definition: MM_DigitizationTool.cxx:71
MM_StripToolOutput::chipCharge
const std::vector< std::vector< float > > & chipCharge() const
Definition: MM_StripToolOutput.h:18
MM_DigitizationTool::digitize
StatusCode digitize(const EventContext &ctx)
Just calls processAllSubEvents - leaving for back-compatibility (IMuonDigitizationTool)
Definition: MM_DigitizationTool.cxx:396
MM_DigitizationTool::processAllSubEvents
virtual StatusCode processAllSubEvents(const EventContext &ctx) override
When being run from MM_Digitizer, this method is called during the event loop.
Definition: MM_DigitizationTool.cxx:398
MM_DigitizationTool::m_useTimeWindow
Gaudi::Property< bool > m_useTimeWindow
Definition: MM_DigitizationTool.h:145
MM_DigitizationTool::m_StripsResponseSimulation
std::unique_ptr< MM_StripsResponseSimulation > m_StripsResponseSimulation
Definition: MM_DigitizationTool.h:195
MM_StripsResponseSimulation::ConfigModule
Definition: MM_StripsResponseSimulation.h:64
PileUpTimeEventIndex::index
index_type index() const
the index of the component event in PileUpEventInfo
Definition: PileUpTimeEventIndex.cxx:76
MM_DigitizationTool::checkMMSimHit
bool checkMMSimHit(const MMSimHit &) const
Definition: MM_DigitizationTool.cxx:895
MM_DigitToolInput.h
TimedHitPtr< MMSimHit >
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
isValid
bool isValid(const T &p)
Definition: AtlasPID.h:214
SG::VarHandleKey::key
const std::string & key() const
Return the StoreGate ID for the referenced object.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:141
MicromegasHitIdHelper::GetLayer
int GetLayer(const int &hid) const
Definition: MicromegasHitIdHelper.cxx:89
MM_DigitToolInput
Definition: MM_DigitToolInput.h:25
MM_DigitizationTool::processBunchXing
StatusCode processBunchXing(int bunchXing, SubEventIterator bSubEvents, SubEventIterator eSubEvents) override final
When being run from PileUpToolsAlgs, this method is called for each active bunch-crossing to process ...
Definition: MM_DigitizationTool.cxx:294
MM_ElectronicsResponseSimulation::ConfigModule
Definition: MM_ElectronicsResponseSimulation.h:34
yodamerge_tmp.scale
scale
Definition: yodamerge_tmp.py:138
MuonGM::MuonClusterReadoutElement::surface
virtual const Trk::PlaneSurface & surface() const override
access to chamber surface (phi orientation), uses the first gas gap
Definition: MuonClusterReadoutElement.h:123
MM_DigitizationTool::m_idHelperSvc
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
Definition: MM_DigitizationTool.h:116
GenParticle.h
MM_DigitizationTool::m_rndmSvc
ServiceHandle< IAthRNGSvc > m_rndmSvc
Definition: MM_DigitizationTool.h:113
MM_DigitizationTool::m_MMHitCollList
std::list< std::unique_ptr< MMSimHitCollection > > m_MMHitCollList
Definition: MM_DigitizationTool.h:193
MM_DigitizationTool::m_noiseParams
std::map< int, NoiseCalibConstants > m_noiseParams
Define a map to cache the noise parameters individually Key: stationName * std::abs(stationEta)
Definition: MM_DigitizationTool.h:201
MM_DigitizationTool::m_fieldCondObjInputKey
SG::ReadCondHandleKey< AtlasFieldCacheCondObj > m_fieldCondObjInputKey
Definition: MM_DigitizationTool.h:120
Trk::LocalDirection::angleYZ
double angleYZ() const
access method for angle of local YZ projection
Definition: LocalDirection.h:106
PileUpMergeSvc::TimedList::type
std::list< value_t > type
type of the collection of timed data object
Definition: PileUpMergeSvc.h:75
MM_DigitToolOutput
Definition: MM_DigitToolOutput.h:25
MMSimHit::globalDirection
const Amg::Vector3D & globalDirection() const
Definition: MMSimHit.h:41
TimedHitPtr::eventTime
float eventTime() const
t0 offset of the bunch xing containing the hit in ns.
Definition: TimedHitPtr.h:50
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
GeometryStatics.h
MM_DigitizationTool::m_muonHelper
const MicromegasHitIdHelper * m_muonHelper
Definition: MM_DigitizationTool.h:189
MM_ElectronicsToolInput
Definition: MM_ElectronicsToolInput.h:9
MMReadoutElement.h
MM_SimIdToOfflineId::convert
Identifier convert(int simId) const
Definition: MM_SimIdToOfflineId.h:24
MM_DigitizationTool.h
Amg::toString
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
Definition: GeoPrimitivesToStringConverter.h:40
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
lumiFormat.i
int i
Definition: lumiFormat.py:92
MM_DigitizationTool::m_vmmNeighborLogic
Gaudi::Property< bool > m_vmmNeighborLogic
Definition: MM_DigitizationTool.h:146
MmDigitContainer.h
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
MM_DigitizationTool::m_calibrationTool
ToolHandle< Muon::INSWCalibTool > m_calibrationTool
Definition: MM_DigitizationTool.h:118
MM_DigitizationTool::m_timeWindowUpperOffset
Gaudi::Property< double > m_timeWindowUpperOffset
Definition: MM_DigitizationTool.h:136
SG::VarHandleBase::store
std::string store() const
Return the name of the store holding the object we are proxying.
Definition: StoreGate/src/VarHandleBase.cxx:379
MM_DigitizationTool::m_rndmEngineName
Gaudi::Property< std::string > m_rndmEngineName
Definition: MM_DigitizationTool.h:114
test_pyathena.parent
parent
Definition: test_pyathena.py:15
MM_DigitizationTool::m_ElectronicsResponseSimulation
std::unique_ptr< MM_ElectronicsResponseSimulation > m_ElectronicsResponseSimulation
Definition: MM_DigitizationTool.h:196
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
MMSimHit::globalTime
double globalTime() const
Definition: MMSimHit.h:35
Trk::PlaneSurface::globalToLocalDirection
void globalToLocalDirection(const Amg::Vector3D &glodir, Trk::LocalDirection &locdir) const
This method transforms the global direction to a local direction wrt the plane.
Definition: PlaneSurface.cxx:260
MM_DigitizationTool::m_writeOutputFile
Gaudi::Property< bool > m_writeOutputFile
Definition: MM_DigitizationTool.h:142
SG::VarHandleKey::initialize
StatusCode initialize(bool used=true)
If this object is used as a property, then this should be called during the initialize phase.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:103
DeMoUpdate.tmp
string tmp
Definition: DeMoUpdate.py:1167
Trk::LocalDirection
represents the three-dimensional global direction with respect to a planar surface frame.
Definition: LocalDirection.h:81
MM_DigitizationTool::m_useCondThresholds
Gaudi::Property< bool > m_useCondThresholds
Definition: MM_DigitizationTool.h:175
SG::ReadHandle::isValid
virtual bool isValid() override final
Can the handle be successfully dereferenced?
NswCalibDbTimeChargeData::CalibConstants::slope
float slope
Definition: NswCalibDbTimeChargeData.h:29
PileUpToolBase
Definition: PileUpToolBase.h:18
MMSimHit::particleEncoding
int particleEncoding() const
Definition: MMSimHit.h:39
MM_DigitizationTool::m_vmmReadoutMode
Gaudi::Property< std::string > m_vmmReadoutMode
Definition: MM_DigitizationTool.h:130
MuonGM::MuonChannelDesign::center
bool center(int channel, Amg::Vector2D &pos) const
STRIPS ONLY: Returns the center on the strip.
Definition: MuonChannelDesign.h:484
python.PyKernel.detStore
detStore
Definition: PyKernel.py:41
MM_DigitizationTool::m_outputSDO_CollectionKey
SG::WriteHandleKey< MuonSimDataCollection > m_outputSDO_CollectionKey
Definition: MM_DigitizationTool.h:170
PathResolver.h
MuonGM::MMReadoutElement::numberOfStrips
virtual int numberOfStrips(const Identifier &layerId) const override final
number of strips per layer
Definition: MMReadoutElement.h:291
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
ATHRNG::RNGWrapper
A wrapper class for event-slot-local random engines.
Definition: RNGWrapper.h:56
PileUpTimeEventIndex::time
time_type time() const
bunch xing time in ns
Definition: PileUpTimeEventIndex.cxx:71
MM_DigitizationTool::getNextEvent
StatusCode getNextEvent(const EventContext &ctx)
Record MmDigitContainer and MuonSimDataCollection.
Definition: MM_DigitizationTool.cxx:326
threshold
Definition: chainparser.cxx:74
MM_StripToolOutput::chipTime
const std::vector< std::vector< float > > & chipTime() const
Definition: MM_StripToolOutput.h:19
charge
double charge(const T &p)
Definition: AtlasPID.h:494
DataVector::push_back
value_type push_back(value_type pElem)
Add an element to the end of the collection.
SG::CondHandleKey::initialize
StatusCode initialize(bool used=true)
MM_DigitizationTool::m_avalancheGain
Gaudi::Property< float > m_avalancheGain
Definition: MM_DigitizationTool.h:160
MuonSimData
Definition: MuonSimData.h:62
python.PhysicalConstants.c_light
float c_light
Definition: PhysicalConstants.py:63
MuonGM::MMReadoutElement::getReadoutSide
const std::array< int, 4 > & getReadoutSide() const
Definition: MMReadoutElement.h:137
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
MM_DigitizationTool::m_energyThreshold
Gaudi::Property< double > m_energyThreshold
Definition: MM_DigitizationTool.h:133
ATHRNG::RNGWrapper::getEngine
CLHEP::HepRandomEngine * getEngine(const EventContext &ctx) const
Retrieve the random engine corresponding to the provided EventContext.
Definition: RNGWrapper.h:134
MM_StripToolOutput
Definition: MM_StripToolOutput.h:9
RNGWrapper.h
MM_DigitizationTool::m_stripdeadtime
Gaudi::Property< float > m_stripdeadtime
Definition: MM_DigitizationTool.h:165
MicromegasHitIdHelper::GetHelper
static const MicromegasHitIdHelper * GetHelper()
Definition: MicromegasHitIdHelper.cxx:25
MM_DigitizationTool::m_timedHitCollection_MM
std::unique_ptr< TimedHitCollection< MMSimHit > > m_timedHitCollection_MM
Definition: MM_DigitizationTool.h:194
MM_StripsResponseSimulation::ConfigModule::writeOutputFile
bool writeOutputFile
Definition: MM_StripsResponseSimulation.h:80
MuonChannelDesign.h
MM_DigitizationTool::m_electronicsThreshold
Gaudi::Property< float > m_electronicsThreshold
Definition: MM_DigitizationTool.h:163
MMSimHit::MMId
HitID MMId() const
Definition: MMSimHit.h:44
MM_DigitizationTool::m_qThreshold
Gaudi::Property< float > m_qThreshold
Definition: MM_DigitizationTool.h:155
SG::WriteHandle
Definition: StoreGate/StoreGate/WriteHandle.h:76
MuonGM::MuonChannelDesign
Definition: MuonChannelDesign.h:24
AthenaPoolExample_Copy.streamName
string streamName
Definition: AthenaPoolExample_Copy.py:39
DiTauMassTools::MaxHistStrategyV2::e
e
Definition: PhysicsAnalysis/TauID/DiTauMassTools/DiTauMassTools/HelperFunctions.h:26
MM_DigitizationTool::m_smearingTool
ToolHandle< Muon::INSWCalibSmearingTool > m_smearingTool
Definition: MM_DigitizationTool.h:117
MM_ElectronicsToolInput::digitID
const Identifier & digitID() const
Definition: MM_ElectronicsToolInput.h:35
MmIdHelper
Definition: MmIdHelper.h:54
SG::WriteHandle::record
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
CondAlgsOpts.found
int found
Definition: CondAlgsOpts.py:101
CaloSwCorrections.time
def time(flags, cells_name, *args, **kw)
Definition: CaloSwCorrections.py:242
MuonGM::MMReadoutElement::numberOfMissingBottomStrips
int numberOfMissingBottomStrips(const Identifier &layerId) const
Definition: MMReadoutElement.h:306
TimedHitPtr::eventId
unsigned short eventId() const
the index of the component event in PileUpEventInfo.
Definition: TimedHitPtr.h:42
MM_DigitizationTool::m_crossTalk2
Gaudi::Property< float > m_crossTalk2
Definition: MM_DigitizationTool.h:158
MuonGM::MuonDetectorManager
The MuonDetectorManager stores the transient representation of the Muon Spectrometer geometry and pro...
Definition: MuonDetDescr/MuonReadoutGeometry/MuonReadoutGeometry/MuonDetectorManager.h:49
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
Trk::PlaneSurface
Definition: PlaneSurface.h:64
MuonGM::MMReadoutElement::stripLength
double stripLength(const Identifier &id) const
strip length Wrappers to MuonChannelDesign::channelLength() taking into account the passivated width
Definition: MMReadoutElement.h:221
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
MM_DigitizationTool::m_condThrshldsKey
SG::ReadCondHandleKey< NswCalibDbThresholdData > m_condThrshldsKey
Definition: MM_DigitizationTool.h:121
MM_DigitizationTool::m_outputDigitCollectionKey
SG::WriteHandleKey< MmDigitContainer > m_outputDigitCollectionKey
Definition: MM_DigitizationTool.h:168
MuonGM::MMReadoutElement::stripNumber
virtual int stripNumber(const Amg::Vector2D &pos, const Identifier &id) const override final
strip number corresponding to local position.
Definition: MMReadoutElement.h:202
MuonGM::MuonDetectorManager::getMMReadoutElement
const MMReadoutElement * getMMReadoutElement(const Identifier &id) const
access via extended identifier (requires unpacking)
Definition: MuonDetDescr/MuonReadoutGeometry/src/MuonDetectorManager.cxx:255
MM_DigitizationTool::m_checkMMSimHits
Gaudi::Property< bool > m_checkMMSimHits
Definition: MM_DigitizationTool.h:144
MagField::AtlasFieldCache
Local cache for magnetic field (based on MagFieldServices/AtlasFieldSvcTLS.h)
Definition: AtlasFieldCache.h:43
GeoPrimitivesToStringConverter.h
MuonGM::MMReadoutElement
An MMReadoutElement corresponds to a single STGC module; therefore typicaly a barrel muon station con...
Definition: MMReadoutElement.h:23
MM_DigitizationTool::m_crossTalk1
Gaudi::Property< float > m_crossTalk1
Definition: MM_DigitizationTool.h:157
MMSimHit::depositEnergy
double depositEnergy() const
Definition: MMSimHit.h:42
MagField::AtlasFieldCache::getField
void getField(const double *ATH_RESTRICT xyz, double *ATH_RESTRICT bxyz, double *ATH_RESTRICT deriv=nullptr)
get B field value at given position xyz[3] is in mm, bxyz[3] is in kT if deriv[9] is given,...
Definition: AtlasFieldCache.cxx:42
AtlasHitsVector::size
size_type size() const
Definition: AtlasHitsVector.h:143
MuonGM::MMReadoutElement::numberOfMissingTopStrips
int numberOfMissingTopStrips(const Identifier &layerId) const
Number of missing bottom and top strips (not read out)
Definition: MMReadoutElement.h:300
MMSimHit::globalPosition
const Amg::Vector3D & globalPosition() const
Definition: MMSimHit.h:38
MM_DigitizationTool::prepareEvent
StatusCode prepareEvent(const EventContext &ctx, const unsigned int) override final
When being run from PileUpToolsAlgs, this method is called at the start of the subevts loop.
Definition: MM_DigitizationTool.cxx:279
SubEventIterator
std::vector< xAOD::EventInfo::SubEvent >::const_iterator SubEventIterator
Definition: IPileUpTool.h:22
MM_DigitizationTool::m_driftGapWidth
Gaudi::Property< float > m_driftGapWidth
Definition: MM_DigitizationTool.h:156
LocalDirection.h
MM_DigitizationTool::m_doSmearing
Gaudi::Property< bool > m_doSmearing
Definition: MM_DigitizationTool.h:147
MM_ElectronicsResponseSimulation::ConfigModule::peakTime
float peakTime
power of responce function
Definition: MM_ElectronicsResponseSimulation.h:36
simData
constexpr bool simData
Definition: constants.h:36
Trk::LocalDirection::angleXZ
double angleXZ() const
access method for angle of local XZ projection
Definition: LocalDirection.h:103
MM_DigitizationTool::combinedStripResponseAllHits
MM_ElectronicsToolInput combinedStripResponseAllHits(const std::vector< MM_ElectronicsToolInput > &v_stripDigitOutput)
Definition: MM_DigitizationTool.cxx:818
MuonSimDataCollection.h
MuonGM::MuonChannelDesign::channelWidth
double channelWidth() const
calculate local channel width
Definition: MuonChannelDesign.h:399
PileUpTimeEventIndex
a struct encapsulating the identifier of a pile-up event
Definition: PileUpTimeEventIndex.h:12
MM_DigitizationTool::m_vmmDeadtime
Gaudi::Property< float > m_vmmDeadtime
Definition: MM_DigitizationTool.h:181
Trk::Surface::transform
const Amg::Transform3D & transform() const
Returns HepGeom::Transform3D by reference.
PileUpTimeEventIndex::type
PileUpType type() const
the pileup type - minbias, cavern, beam halo, signal?
Definition: PileUpTimeEventIndex.cxx:81
MM_DigitizationTool::mergeEvent
StatusCode mergeEvent(const EventContext &ctx) override final
When being run from PileUpToolsAlgs, this method is called at the end of the subevts loop.
Definition: MM_DigitizationTool.cxx:383
python.compressB64.c
def c
Definition: compressB64.py:93
MMSimHit::kineticEnergy
double kineticEnergy() const
Definition: MMSimHit.h:40
MM_DigitizationTool::m_vmmARTMode
Gaudi::Property< std::string > m_vmmARTMode
Definition: MM_DigitizationTool.h:131
MM_DigitizationTool::m_useThresholdScaling
Gaudi::Property< bool > m_useThresholdScaling
Definition: MM_DigitizationTool.h:177
TimedHitCollection
Definition: TimedHitCollection.h:15
NSWCalib::MicroMegaGas
Definition: INSWCalibTool.h:32
python.SystemOfUnits.degree
tuple degree
Definition: SystemOfUnits.py:106
MuonGM::MuonChannelDesign::thickness
double thickness
Definition: MuonChannelDesign.h:42
NswCalibDbTimeChargeData::CalibConstants::intercept
float intercept
Definition: NswCalibDbTimeChargeData.h:30
WriteCellNoiseToCool.noise
noise
Definition: WriteCellNoiseToCool.py:380
MM_DigitizationTool::m_hitsContainerKey
SG::ReadHandleKey< MMSimHitCollection > m_hitsContainerKey
Definition: MM_DigitizationTool.h:127
MM_DigitizationTool::m_inputObjectName
std::string m_inputObjectName
Definition: MM_DigitizationTool.h:128
MuonMCData
Definition: MuonSimData.h:42
generate::Zero
void Zero(TH1D *hin)
Definition: generate.cxx:32
MuonSimData.h
MuonGM::MuonChannelDesign::distanceToChannel
double distanceToChannel(const Amg::Vector2D &pos, int nChannel) const
distance to channel - residual
Definition: MuonChannelDesign.h:181
MM_DigitizationTool::m_onlyUseContainerName
Gaudi::Property< bool > m_onlyUseContainerName
Definition: MM_DigitizationTool.h:125