ATLAS Offline Software
RpcDigitizationTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 //
7 // RpcDigitizationTool
8 // ------------
9 // Authors:
10 // Andrea Di Simone <Andrea.Di.Simone@cern.ch>
11 // Gabriele Chiodini <gabriele.chiodini@le.infn.it>
12 // Stefania Spagnolo <stefania.spagnolo@le.infn.it>
14 
16 
17 // Inputs
18 #include "GaudiKernel/SystemOfUnits.h"
19 #include "GaudiKernel/PhysicalConstants.h"
21 #include "GeoModelHelpers/TransformToStringConverter.h"
22 #include "MuonSimEvent/RPCSimHit.h"
24 
25 // Geometry
30 
31 // run n. from geometry DB
37 
38 // Truth
39 #include "AtlasHepMC/GenParticle.h"
41 #include "GeoModelHelpers/throwExcept.h"
42 // Random Numbers
44 #include "CLHEP/Random/RandExponential.h"
45 #include "CLHEP/Random/RandFlat.h"
46 #include "CLHEP/Random/RandGaussZiggurat.h"
47 
48 // Core includes
49 #include <TString.h> // for Form
50 
51 #include <atomic>
52 #include <fstream>
53 #include <iostream>
54 #include <sstream>
55 #include <utility>
56 
59 
60 // 12 charge points, 15 BetaGamma points, 180 efficiency points for fcp search
61 namespace {
62  constexpr int N_Charge = 12;
63  constexpr int N_Velocity = 15;
64  constexpr std::array<double, N_Charge> Charge{0.1, 0.2, 0.3, 0.33, 0.4, 0.5, 0.6, 0.66, 0.7, 0.8, 0.9, 1.0};
65  constexpr std::array<double, N_Velocity> Velocity{0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 2.0, 3.0, 10.0, 100.0, 1000.0};
66  constexpr double Eff_garfield[N_Charge][N_Velocity] = {
67  {0.8648, 0.3476, 0.1407, 0.0618, 0.0368, 0.0234, 0.0150, 0.0120, 0.0096, 0.0079, 0.0038, 0.0041, 0.0035, 0.0049, 0.0054},
68  {0.9999, 0.9238, 0.6716, 0.4579, 0.3115, 0.2238, 0.1727, 0.1365, 0.1098, 0.0968, 0.0493, 0.0451, 0.0528, 0.0694, 0.0708},
69  {1.0000, 0.9978, 0.9517, 0.8226, 0.6750, 0.5611, 0.4674, 0.3913, 0.3458, 0.3086, 0.1818, 0.1677, 0.1805, 0.2307, 0.2421},
70  {1.0000, 0.9994, 0.9758, 0.8918, 0.7670, 0.6537, 0.5533, 0.4856, 0.4192, 0.3852, 0.2333, 0.2186, 0.2479, 0.2957, 0.2996},
71  {1.0000, 1.0000, 0.9972, 0.9699, 0.9022, 0.8200, 0.7417, 0.6660, 0.6094, 0.5622, 0.3846, 0.3617, 0.3847, 0.4578, 0.4583},
72  {1.0000, 1.0000, 0.9998, 0.9956, 0.9754, 0.9479, 0.9031, 0.8604, 0.8126, 0.7716, 0.5827, 0.5545, 0.5865, 0.6834, 0.6706},
73  {1.0000, 1.0000, 1.0000, 0.9997, 0.9968, 0.9876, 0.9689, 0.9464, 0.9221, 0.8967, 0.7634, 0.7385, 0.7615, 0.8250, 0.8309},
74  {1.0000, 1.0000, 1.0000, 1.0000, 0.9995, 0.9952, 0.9866, 0.9765, 0.9552, 0.9427, 0.8373, 0.8127, 0.8412, 0.8899, 0.8891},
75  {1.0000, 1.0000, 1.0000, 1.0000, 0.9995, 0.9981, 0.9918, 0.9803, 0.9754, 0.9602, 0.8730, 0.8564, 0.8746, 0.9178, 0.9261},
76  {1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 0.9993, 0.9990, 0.9951, 0.9935, 0.9886, 0.9419, 0.9277, 0.9422, 0.9686, 0.9700},
77  {1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 0.9998, 0.9996, 0.9980, 0.9966, 0.9786, 0.9718, 0.9748, 0.9875, 0.9882},
78  {1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 0.9998, 1.0000, 0.9991, 0.9988, 0.9913, 0.9872, 0.9917, 0.9970, 0.9964}};
79  bool
80  validIndex(int idx, int arraySize){
81  return (idx>=0) and (idx<arraySize);
82  }
83 } // namespace
84 
85 using namespace MuonGM;
86 namespace {
87  constexpr double SIG_VEL = 4.8;
88 }
89 
90 
91 RpcDigitizationTool::RpcDigitizationTool(const std::string& type, const std::string& name, const IInterface* pIID) :
92  PileUpToolBase(type, name, pIID) {}
93 
94 // member function implementation
95 //--------------------------------------------
97  ATH_MSG_DEBUG("RpcDigitizationTool:: in initialize()");
98  ATH_MSG_DEBUG("Configuration RpcDigitizationTool ");
99 
100  ATH_MSG_DEBUG("InputObjectName " << m_inputHitCollectionName);
101  ATH_MSG_DEBUG("OutputObjectName " << m_outputDigitCollectionKey.key());
102  ATH_MSG_DEBUG("OutputSDOName " << m_outputSDO_CollectionKey.key());
103  ATH_MSG_DEBUG("WindowLowerOffset " << m_timeWindowLowerOffset);
104  ATH_MSG_DEBUG("WindowUpperOffset " << m_timeWindowUpperOffset);
105  ATH_MSG_DEBUG("DeadTime " << m_deadTime);
106  ATH_MSG_DEBUG("RndmSvc " << m_rndmSvc);
107  ATH_MSG_DEBUG("PatchForRpcTime " << m_patch_for_rpc_time);
108  ATH_MSG_DEBUG("RpcTimeShift " << m_rpc_time_shift);
109  ATH_MSG_DEBUG("RPC_TimeSchema " << m_RPC_TimeSchema);
110  ATH_MSG_DEBUG("RPCSDOareRPCDigits " << m_sdoAreOnlyDigits);
111 
112  ATH_MSG_DEBUG("IgnoreRunDependentConfig " << m_ignoreRunDepConfig);
113  ATH_MSG_DEBUG("turnON_efficiency " << m_turnON_efficiency);
114  ATH_MSG_DEBUG("Efficiency_fromCOOL " << m_Efficiency_fromCOOL);
115  ATH_MSG_DEBUG("Efficiency_BIS78_fromCOOL" << m_Efficiency_BIS78_fromCOOL);
116  ATH_MSG_DEBUG("turnON_clustersize " << m_turnON_clustersize);
117  ATH_MSG_DEBUG("ClusterSize_fromCOOL " << m_ClusterSize_fromCOOL);
118  ATH_MSG_DEBUG("ClusterSize_BIS78_fromCOOL" << m_ClusterSize_BIS78_fromCOOL);
119  ATH_MSG_DEBUG("FirstClusterSizeInTail " << m_FirstClusterSizeInTail);
120  ATH_MSG_DEBUG("ClusterSize1_2uncorr " << m_ClusterSize1_2uncorr);
121  ATH_MSG_DEBUG("BOG_BOF_DoubletR2_OFF " << m_BOG_BOF_DoubletR2_OFF);
122  ATH_MSG_DEBUG("CutMaxClusterSize " << m_CutMaxClusterSize);
123  ATH_MSG_DEBUG("CutProjectedTracks " << m_CutProjectedTracks);
124  ATH_MSG_DEBUG("ValidationSetup " << m_validationSetup);
125  ATH_MSG_DEBUG("IncludePileUpTruth " << m_includePileUpTruth);
126  ATH_MSG_DEBUG("VetoPileUpTruthLinks " << m_vetoPileUpTruthLinks);
127 
129  if (m_onlyUseContainerName) { ATH_CHECK(m_mergeSvc.retrieve()); }
131  // check the identifiers
132 
133  ATH_MSG_INFO("Max Number of RPC Gas Gaps for these Identifiers = " << m_idHelper->gasGapMax());
134 
135  // check the input object name
136  if (m_hitsContainerKey.key().empty()) {
137  ATH_MSG_FATAL("Property InputObjectName not set !");
138  return StatusCode::FAILURE;
139  }
141  ATH_MSG_DEBUG("Input objects in container : '" << m_inputHitCollectionName << "'");
142 
143  // Initialize ReadHandleKey
144  ATH_CHECK(m_hitsContainerKey.initialize());
145 
146  // initialize the output WriteHandleKeys
150  ATH_MSG_DEBUG("Output digits: '" << m_outputDigitCollectionKey.key() << "'");
151 
152  // set the configuration based on run1/run2
153  // Retrieve geometry config information from the database (RUN1, RUN2, etc...)
154  IRDBAccessSvc* rdbAccess(nullptr);
155  ATH_CHECK(service("RDBAccessSvc", rdbAccess));
156 
157  enum DataPeriod {Unknown, Run1, Run2, Run3, Run4 };
158  DataPeriod run = Unknown;
159 
160  std::string configVal = "";
161  const IGeoModelSvc* geoModel(nullptr);
162  ATH_CHECK(service("GeoModelSvc", geoModel));
163  // check the DetDescr version
164  std::string atlasVersion = geoModel->atlasVersion();
165 
166  IRDBRecordset_ptr atlasCommonRec = rdbAccess->getRecordsetPtr("AtlasCommon", atlasVersion, "ATLAS");
167  if (atlasCommonRec->size() == 0) {
168  run = Run1;
169  } else {
170  configVal = (*atlasCommonRec)[0]->getString("CONFIG");
171  ATH_MSG_INFO("From DD Database, Configuration is " << configVal);
172  if (configVal == "RUN1") {
173  run = Run1;
174  } else if (configVal == "RUN2") {
175  run = Run2;
176  } else if (configVal == "RUN3") {
177  run = Run3;
178  } else if (configVal == "RUN4") {
179  run = Run4;
180  }
181  if (run == DataPeriod::Unknown) {
182  ATH_MSG_FATAL("Unexpected value for geometry config read from the database: " << configVal);
183  return StatusCode::FAILURE;
184  }
185  }
186  if (run == Run3 && m_idHelper->gasGapMax() < 3)
187  ATH_MSG_WARNING("Run3, configVal = " << configVal << " and GasGapMax =" << m_idHelper->gasGapMax());
188 
189  if (run == Run1)
190  ATH_MSG_INFO("From Geometry DB: MuonSpectrometer configuration is: RUN1 or MuonGeometry = R.06");
191  else if (run == Run2)
192  ATH_MSG_INFO("From Geometry DB: MuonSpectrometer configuration is: RUN2 or MuonGeometry = R.07");
193  else if (run == Run3)
194  ATH_MSG_INFO("From Geometry DB: MuonSpectrometer configuration is: RUN3 or MuonGeometry = R.09");
195  else if (run == Run4)
196  ATH_MSG_INFO("From Geometry DB: MuonSpectrometer configuration is: RUN4 or MuonGeometry = R.10");
197 
198  if (m_ignoreRunDepConfig == false) {
199  m_BOG_BOF_DoubletR2_OFF = false;
200  m_Efficiency_fromCOOL = false;
201  m_ClusterSize_fromCOOL = false;
202  m_RPCInfoFromDb = false;
203  m_kill_deadstrips = false;
204  if (run == Run1) {
205  // m_BOG_BOF_DoubletR2_OFF = true
206  // m_Efficiency_fromCOOL = true
207  // m_ClusterSize_fromCOOL = true
209  if (configVal == "RUN1") { // MC12 setup
210  m_Efficiency_fromCOOL = true;
211  m_ClusterSize_fromCOOL = true;
212  m_RPCInfoFromDb = true;
213  m_kill_deadstrips = true;
215  }
216  } else {
217  // m_BOG_BOF_DoubletR2_OFF = false # do not turn off at digitization the hits in the dbR=2 chambers in the feet
218  // m_Efficiency_fromCOOL = false # use common average values in python conf.
219  // m_ClusterSize_fromCOOL = false # use common average values in python conf.
220  m_BOG_BOF_DoubletR2_OFF = false;
221  if (run == Run2) { // MC15c setup
222  m_Efficiency_fromCOOL = true;
223  m_ClusterSize_fromCOOL = true;
224  m_RPCInfoFromDb = true;
225  m_kill_deadstrips = false;
226  m_CutProjectedTracks = 100;
227  } else {
228  ATH_MSG_INFO("Run3/4: configuration parameter not from COOL");
229  m_Efficiency_fromCOOL = false;
230  m_ClusterSize_fromCOOL = false;
231  m_RPCInfoFromDb = false;
232  m_kill_deadstrips = false;
233  }
234  }
235  ATH_MSG_INFO("RPC Run1/2/3-dependent configuration is enforced");
236  } else {
237  ATH_MSG_WARNING("Run1/2/3-dependent configuration is bypassed; be careful with option settings");
238  }
239 
240  ATH_MSG_DEBUG("......RPC Efficiency_fromCOOL " << m_Efficiency_fromCOOL);
241  ATH_MSG_DEBUG("......RPC ClusterSize_fromCOOL " << m_ClusterSize_fromCOOL);
242  ATH_MSG_DEBUG("......RPC BOG_BOF_DoubletR2_OFF " << m_BOG_BOF_DoubletR2_OFF);
243  ATH_MSG_DEBUG("......RPC RPCInfoFromDb " << m_RPCInfoFromDb);
244  ATH_MSG_DEBUG("......RPC KillDeadStrips " << m_kill_deadstrips);
245  ATH_MSG_DEBUG("......RPC CutProjectedTracks " << m_CutProjectedTracks);
246 
247  ATH_MSG_DEBUG("Ready to read parameters for cluster simulation from file");
248 
249  ATH_CHECK(m_rndmSvc.retrieve());
250 
251  // get TagInfoMgr
252  ATH_CHECK(service("TagInfoMgr", m_tagInfoMgr));
253 
254  // fill the taginfo information
256 
258 
260  // m_turnON_clustersize=false;
267 
268  return StatusCode::SUCCESS;
269 }
270 
271 template <class CondType>
274  const CondType* & condPtr) const {
275 
276  if (key.empty()) {
277  ATH_MSG_DEBUG("No key has been configured for object "<<typeid(CondType).name()<<". Clear pointer");
278  condPtr = nullptr;
279  return StatusCode::SUCCESS;
280  }
281  SG::ReadCondHandle<CondType> readHandle{key, ctx};
282  if (!readHandle.isValid()){
283  ATH_MSG_FATAL("Failed to load conditions object "<<key.fullKey()<<".");
284  return StatusCode::FAILURE;
285  }
286  condPtr = readHandle.cptr();
287  return StatusCode::SUCCESS;
288 
289 }
290 //--------------------------------------------
291 StatusCode RpcDigitizationTool::prepareEvent(const EventContext& /*ctx*/, unsigned int) {
292  ATH_MSG_DEBUG("RpcDigitizationTool::in prepareEvent()");
293 
294  // John's Hacks START
295  m_RPCHitCollList.clear();
296  m_thpcRPC = std::make_unique<TimedHitCollection<RPCSimHit>>();
297  // John's Hacks END
298 
299  return StatusCode::SUCCESS;
300 }
301 
302 //--------------------------------------------
304  ATH_MSG_DEBUG("RpcDigitizationTool::in processBunchXing()");
305 
307  TimedHitCollList hitCollList;
308 
309  if (!(m_mergeSvc->retrieveSubSetEvtData(m_inputHitCollectionName, hitCollList, bunchXing, bSubEvents, eSubEvents).isSuccess()) &&
310  hitCollList.empty()) {
311  ATH_MSG_ERROR("Could not fill TimedHitCollList");
312  return StatusCode::FAILURE;
313  } else {
314  ATH_MSG_VERBOSE(hitCollList.size() << " RPCSimHitCollection with key " << m_inputHitCollectionName << " found");
315  }
316 
317  TimedHitCollList::iterator iColl(hitCollList.begin());
318  TimedHitCollList::iterator endColl(hitCollList.end());
319 
320  // Iterating over the list of collections
321  for (; iColl != endColl; ++iColl) {
322  RPCSimHitCollection* hitCollPtr = new RPCSimHitCollection(*iColl->second);
323  PileUpTimeEventIndex timeIndex(iColl->first);
324 
325  ATH_MSG_DEBUG("RPCSimHitCollection found with " << hitCollPtr->size() << " hits");
326  ATH_MSG_VERBOSE("time index info. time: " << timeIndex.time() << " index: " << timeIndex.index() << " type: " << timeIndex.type());
327 
328  m_thpcRPC->insert(timeIndex, hitCollPtr);
329  m_RPCHitCollList.emplace_back(hitCollPtr);
330  }
331 
332  return StatusCode::SUCCESS;
333 }
334 
335 //--------------------------------------------
336 // Get next event and extract collection of hit collections:
338  ATH_MSG_DEBUG("RpcDigitizationTool::getNextEvent()");
339 
340  // initialize pointer
341  m_thpcRPC.reset();
342 
343  // get the container(s)
345 
346  // In case of single hits container just load the collection using read handles
347  if (!m_onlyUseContainerName) {
349  if (!hitCollection.isValid()) {
350  ATH_MSG_ERROR("Could not get RPCSimHitCollection container " << hitCollection.name() << " from store "
351  << hitCollection.store());
352  return StatusCode::FAILURE;
353  }
354 
355  // create a new hits collection
356  m_thpcRPC = std::make_unique<TimedHitCollection<RPCSimHit>>(1);
357  m_thpcRPC->insert(0, hitCollection.cptr());
358  ATH_MSG_DEBUG("RPCSimHitCollection found with " << hitCollection->size() << " hits");
359 
360  return StatusCode::SUCCESS;
361  }
362  // this is a list<pair<time_t, DataLink<RPCSimHitCollection> > >
363  TimedHitCollList hitCollList;
364 
365  if (!(m_mergeSvc->retrieveSubEvtsData(m_inputHitCollectionName, hitCollList).isSuccess())) {
366  ATH_MSG_ERROR("Could not fill TimedHitCollList");
367  return StatusCode::FAILURE;
368  }
369  if (hitCollList.empty()) {
370  ATH_MSG_ERROR("TimedHitCollList has size 0");
371  return StatusCode::FAILURE;
372  } else {
373  ATH_MSG_DEBUG(hitCollList.size() << " RPCSimHitCollections with key " << m_inputHitCollectionName << " found");
374  }
375 
376  // create a new hits collection
377  m_thpcRPC = std::make_unique<TimedHitCollection<RPCSimHit>>();
378  // now merge all collections into one
379  TimedHitCollList::iterator iColl(hitCollList.begin());
380  TimedHitCollList::iterator endColl(hitCollList.end());
381  while (iColl != endColl) {
382  const RPCSimHitCollection* p_collection(iColl->second);
383  m_thpcRPC->insert(iColl->first, p_collection);
384  // if ( m_debug ) ATH_MSG_DEBUG ( "RPCSimHitCollection found with "
385  // << p_collection->size() << " hits" ); // loop on the hit collections
386  ++iColl;
387  }
388  return StatusCode::SUCCESS;
389 }
390 
391 //--------------------------------------------
392 StatusCode RpcDigitizationTool::mergeEvent(const EventContext& ctx) {
393  StatusCode status = StatusCode::SUCCESS;
394 
395  ATH_MSG_DEBUG("RpcDigitizationTool::in mergeEvent()");
396  // create and record the Digit container in StoreGate
398  ATH_CHECK(digitContainer.record(std::make_unique<RpcDigitContainer>(m_idHelper->module_hash_max())));
399  ATH_MSG_DEBUG("RpcDigitContainer recorded in StoreGate.");
400 
401  // Create and record the SDO container in StoreGate
403  ATH_CHECK(sdoContainer.record(std::make_unique<MuonSimDataCollection>()));
404  ATH_MSG_DEBUG("RpcSDOCollection recorded in StoreGate.");
405 
407  m_sdo_tmp_map.clear();
409 
410  Collections_t collections;
411  status = doDigitization(ctx, collections, sdoContainer.ptr());
412  if (status.isFailure()) { ATH_MSG_ERROR("doDigitization Failed"); }
413  for (size_t coll_hash = 0; coll_hash < collections.size(); ++coll_hash) {
414  if (collections[coll_hash]) {
415  ATH_CHECK( digitContainer->addCollection (collections[coll_hash].release(), coll_hash) );
416  }
417  }
418 
419  // Clean-up
420  m_RPCHitCollList.clear();
421 
422  return status;
423 }
424 
425 //--------------------------------------------
427  StatusCode status = StatusCode::SUCCESS;
428 
429  // merging of the hit collection in getNextEvent method
430 
431  ATH_MSG_DEBUG("RpcDigitizationTool::in digitize()");
432 
433  // create and record the Digit container in StoreGate
435  ATH_CHECK(digitContainer.record(std::make_unique<RpcDigitContainer>(m_idHelper->module_hash_max())));
436  ATH_MSG_DEBUG("RpcDigitContainer recorded in StoreGate.");
437 
438  // Create and record the SDO container in StoreGate
440  ATH_CHECK(sdoContainer.record(std::make_unique<MuonSimDataCollection>()));
441  ATH_MSG_DEBUG("RpcSDOCollection recorded in StoreGate.");
442 
444  m_sdo_tmp_map.clear();
446 
447  if (!m_thpcRPC) {
448  status = getNextEvent(ctx);
449  if (StatusCode::FAILURE == status) {
450  ATH_MSG_INFO("There are no RPC hits in this event");
451  return status; // there are no hits in this event
452  }
453  }
454 
455  Collections_t collections;
456  ATH_CHECK(doDigitization(ctx, collections, sdoContainer.ptr()));
457  for (size_t coll_hash = 0; coll_hash < collections.size(); ++coll_hash) {
458  if (collections[coll_hash]) {
459  ATH_CHECK( digitContainer->addCollection (collections[coll_hash].release(), coll_hash) );
460  }
461  }
462 
463  return status;
464 }
465 
466 //--------------------------------------------
468  Collections_t& collections,
469  MuonSimDataCollection* sdoContainer) {
470  ATHRNG::RNGWrapper* rngWrapper = m_rndmSvc->getEngine(this);
471  rngWrapper->setSeed(name(), ctx);
472  CLHEP::HepRandomEngine* rndmEngine = rngWrapper->getEngine(ctx);
473 
474  const MuonGM::MuonDetectorManager* detMgr{nullptr};
475  ATH_CHECK(retrieveCondData(ctx, m_detMgrKey, detMgr));
476 
477 
478  std::unique_ptr<RPCSimHitCollection> inputSimHitColl{std::make_unique<RPCSimHitCollection>("RPC_Hits")};
479 
480 
481  // get the iterator pairs for this DetEl
482  // iterate over hits
484 
485  // Perform null check on m_thpcRPC
486  if (!m_thpcRPC) {
487  ATH_MSG_ERROR("m_thpcRPC is null");
488  return StatusCode::FAILURE;
489  }
490 
491  struct SimDataContent {
492  Identifier channelId{};
493  std::vector<MuonSimData::Deposit> deposits;
495  double simTime{0.};
496  };
497 
498  while (m_thpcRPC->nextDetectorElement(i, e)) {
499  // to store the a single
500 
501  std::map<Identifier, SimDataContent> channelSimDataMap;
502 
503  // Loop over the hits:
504  while (i != e) {
505  ATH_MSG_DEBUG("RpcDigitizationTool::loop over the hits");
506 
507  TimedHitPtr<RPCSimHit> phit(*i++);
508 
509  // the hit
510  const RPCSimHit& hit(*phit);
511  // the hit id
512  const int idHit = hit.RPCid();
513  // the global time (G4 time + bunch time)
514  const double globalHitTime{hitTime(phit)};
515  // the G4 time or TOF from IP
516  const double G4Time{hit.globalTime()};
517  // the bunch time
518  const double bunchTime{globalHitTime - hit.globalTime()};
519 
520  ATH_MSG_DEBUG("Global time " << globalHitTime << " G4 time " << G4Time << " Bunch time " << bunchTime);
521 
522  if (!m_simHitValidKey.empty()) {
523  ATH_MSG_VERBOSE("Validation: globalHitTime, G4Time, BCtime = " << globalHitTime << " " << G4Time << " " << bunchTime);
524  inputSimHitColl->Emplace(idHit, globalHitTime, hit.localPosition(),
525  HepMcParticleLink::getRedirectedLink(phit->particleLink(), phit.eventId(), ctx), // This link should now correctly resolve to the TruthEvent McEventCollection in the main StoreGateSvc.
526  hit.postLocalPosition(),
527  hit.energyDeposit(), hit.stepLength(), hit.particleEncoding(), hit.kineticEnergy());
528  }
529 
530  // convert sim id helper to offline id
531  const std::string stationName = m_muonHelper->GetStationName(idHit);
532  const int stationEta = m_muonHelper->GetZSector(idHit);
533  const int stationPhi = m_muonHelper->GetPhiSector(idHit);
534  const int doubletR = m_muonHelper->GetDoubletR(idHit);
535  const int doubletZ = m_muonHelper->GetDoubletZ(idHit);
536  const int doubletPhi = m_muonHelper->GetDoubletPhi(idHit);
537  int gasGap = m_muonHelper->GetGasGapLayer(idHit);
538 
539  if (m_muonHelper->GetMeasuresPhi(idHit)) continue; // Skip phi strip . To be created after efficiency evaluation
540 
541 
542  bool isValid{false};
543  const Identifier elementID = m_idHelper->elementID(stationName,stationEta,stationPhi,doubletR, isValid);
544  if (!isValid) {
545  ATH_MSG_WARNING("Failed to construct the element ID from "<<stationName
546  <<", stationEta: "<<stationEta<<", stationPhi: "<<stationPhi<<", doubletR: "<<doubletR);
547  continue;
548  }
549  // construct Atlas identifier from components
550  ATH_MSG_DEBUG("creating id for hit in element:"
551  << " stationName " << stationName << " stationEta " << stationEta << " stationPhi " << stationPhi << " doubletR "
552  << doubletR << " doubletZ " << doubletZ << " doubletPhi " << doubletPhi << " gasGap " << gasGap);
553  const Identifier detElId{m_idHelper->channelID(elementID, doubletZ, doubletPhi, 1,0, 1, isValid)};
554  if (!isValid) {
555  continue;
556  }
557  const RpcReadoutElement* reEle = detMgr->getRpcReadoutElement(detElId);
559  if (false && reEle->rotatedRpcModule()) {
560  gasGap = gasGap == 1 ? 2 : 1;
561  }
562 
563 
564  bool isValidEta{false}, isValidPhi{false};
565  const Identifier idpaneleta = m_idHelper->channelID(elementID, doubletZ, doubletPhi, gasGap, 0, 1, isValidEta);
566  const Identifier idpanelphi = m_idHelper->channelID(elementID, doubletZ, doubletPhi, gasGap, 1, 1, isValidPhi);
567  if (!isValidEta || !isValidPhi) {
568  ATH_MSG_WARNING("Found an invalid identifier "
569  << " stationName " << stationName << " stationEta " << stationEta << " stationPhi " << stationPhi
570  << " doubletR " << doubletR << " doubletZ " << doubletZ << " doubletPhi " << doubletPhi << " gasGap "
571  << gasGap);
572  continue;
573  }
574  // loop on eta and phi to apply correlated efficiency between the two views
575 
577  const double tmp_CorrJitter = m_idHelper->stationName(idpaneleta) < 2 ? m_CorrJitter_BIS78 : m_CorrJitter;
579  const double corrtimejitter = tmp_CorrJitter > 0.01 ?
580  CLHEP::RandGaussZiggurat::shoot(rndmEngine, 0., tmp_CorrJitter) : 0.; // correlated jitter
581  // handle here the special case where eta panel is dead => phi strip status (dead or eff.) cannot be resolved;
582  // measured panel eff. will be used in that case and no phi strip killing will happen
583 
584 
585  // Extrapolate the hit to the gas gap centre located at x=0
586  const Amg::Vector3D hitDir{(hit.postLocalPosition() - hit.localPosition()).unit()};
587  const Amg::Vector3D gapCentre = hit.localPosition() +
588  Amg::intersect<3>(hit.localPosition(), hitDir, Amg::Vector3D::UnitX(), 0).value_or(0) * hitDir;
589 
590  std::array<int, 3> pcseta = physicalClusterSize(ctx, reEle, idpaneleta, gapCentre, rndmEngine); // set to one for new algorithms
591  ATH_MSG_VERBOSE("Simulated cluster on eta panel: size/first/last= " << pcseta[0] << "/" << pcseta[1] << "/" << pcseta[2]);
592  std::array<int, 3> pcsphi = physicalClusterSize(ctx, reEle, idpanelphi, gapCentre, rndmEngine); // set to one for new algorithms
593  ATH_MSG_VERBOSE("Simulated cluster on phi panel: size/first/last= " << pcsphi[0] << "/" << pcsphi[1] << "/" << pcsphi[2]);
594 
595 
596 
597  // create Identifiers
598  const Identifier atlasRpcIdeta = m_idHelper->channelID(elementID, doubletZ, doubletPhi, gasGap, 0, pcseta[1], isValidEta);
599  const Identifier atlasRpcIdphi = m_idHelper->channelID(elementID, doubletZ, doubletPhi, gasGap, 1, pcsphi[1], isValidPhi);
600 
601  const HepMcParticleLink particleLink = HepMcParticleLink::getRedirectedLink(phit->particleLink(), phit.eventId(), ctx); // This link should now correctly resolve to the TruthEvent McEventCollection in the main StoreGateSvc.
602  const auto [etaStripOn, phiStripOn] = detectionEfficiency(ctx, idpaneleta, idpanelphi, rndmEngine, particleLink);
603  ATH_MSG_DEBUG("SetPhiOn " << phiStripOn << " SetEtaOn " << etaStripOn);
604 
605  for (bool imeasphi : {false, true}) {
606  if (!imeasphi && (!etaStripOn || !isValidEta)) continue;
607  if (imeasphi && (!phiStripOn || !isValidPhi)) continue;
608 
609 
610  // get Identifier and list of clusters for this projection
611  const Identifier& atlasId = !imeasphi ? atlasRpcIdeta : atlasRpcIdphi;
612  std::array<int, 3> pcs{!imeasphi ? pcseta : pcsphi};
613 
614  ATH_MSG_DEBUG("SetOn: stationName " << stationName << " stationEta " << stationEta << " stationPhi " << stationPhi
615  << " doubletR " << doubletR << " doubletZ " << doubletZ << " doubletPhi " << doubletPhi
616  << " gasGap " << gasGap << " measphi " << imeasphi);
617 
618  // pcs contains the cluster size, the first strip number and the last strip number of the cluster
619  pcs = TurnOnStrips(reEle, std::move(pcs), atlasId);
620  if (pcs[2] < 0){
621  continue;
622  }
623 
624  ATH_MSG_DEBUG("Simulated cluster1: size/first/last= " << pcs[0] << "/" << pcs[1] << "/" << pcs[2]);
625 
626 
627  const Amg::Vector3D pos = fromSimHitToLayer(reEle, atlasId) * hit.localPosition();
628  const Amg::Vector3D gpos = reEle->transform(atlasId) * pos;
629 
630  ATH_MSG_VERBOSE(" evt: "<<ctx.eventID().event_number()
631  <<" hit "<<m_idHelper->print_to_string(atlasId)
632  <<" local simHit "<<Amg::toString(hit.localPosition())
633  <<" corrected: "<<Amg::toString(pos)
634  <<" transform: "<<GeoTrf::toString(fromSimHitToLayer(reEle, atlasId))
635  <<" local strip: "<<Amg::toString(reEle->localToGlobalTransf(atlasId).inverse()*reEle->stripPos(atlasId))
636  <<" local strip (II): "<<Amg::toString(reEle->transform(atlasId).inverse()*reEle->stripPos(atlasId))
637  <<" global: "<<Amg::toString(gpos)
638  <<" strip Pos: "<<Amg::toString(reEle->stripPos(atlasId)));
639 
640  // Calculate propagation time along readout strip in seconds
641  double proptime = PropagationTime(reEle, atlasId, gpos);
642 
643  double tns = G4Time + proptime + corrtimejitter; // the time is in nanoseconds
644  ATH_MSG_VERBOSE("TOF+propagation time " << tns << " /s where proptime " << proptime << "/s");
645 
646  double time = tns + bunchTime;
647  ATH_MSG_VERBOSE("final time in ns: BC+TOF+prop " << time << " /ns");
648 
649  // pack propagation time along strip, bunch time and local hit position
650  long long int packedMCword = PackMCTruth(proptime, bunchTime, pos.y(), pos.z());
651  //cppcheck-suppress invalidPointerCast
652  double* b = reinterpret_cast<double*>(&packedMCword);
653 
655  // create here deposit for MuonSimData
656  // MuonMCData first word is the packing of : proptime, bunchTime, posy, posz
657  // MuonMCData second word is the total hit time: bunchcTime+tof+proptime+correlatedJitter / ns
658  MuonSimData::Deposit deposit(particleLink, MuonMCData((*b), time)); // store tof+strip_propagation+corr.jitter
659  // MuonMCData((*b),G4Time+bunchTime+proptime )); // store tof+strip_propagation
660 
661  // Do not store pile-up truth information
662  if (m_includePileUpTruth || !HepMC::ignoreTruthLink(phit->particleLink(), m_vetoPileUpTruthLinks)) {
663  if (std::abs(hit.particleEncoding()) == 13 || hit.particleEncoding() == 0) {
664  if (channelSimDataMap.find(atlasId) == channelSimDataMap.end()) {
665  SimDataContent& content = channelSimDataMap[atlasId];
666  content.channelId = atlasId;
667  content.deposits.push_back(deposit);
668  content.gpos = reEle->transform(atlasId)*
669  fromSimHitToLayer(reEle,atlasId) * gapCentre;
670  content.simTime = hitTime(phit);
671  ATH_MSG_VERBOSE("adding SDO entry: r " << content.gpos.perp() << " z " << content.gpos.z());
672  }
673  }
674  }
675 
676 
677  //---------------------------------------------------------------------
678  // construct new digit and store it in the respective digit collection
679  // --------------------------------------------------------------------
680 
681  // we create one digit-vector/deposit for each strip in the cluster
682  bool isValid{false};
683  for (int clus = pcs[1]; clus <= pcs[2]; ++clus) {
684  Identifier newId = m_idHelper->channelID(stationName, stationEta, stationPhi, doubletR, doubletZ,
685  doubletPhi, gasGap, imeasphi, clus, isValid);
686  if (!isValid) {
687  ATH_MSG_WARNING(__FILE__<<":"<<__LINE__<< "Channel "<< stationName<<" "<<stationEta<<" "<<stationPhi<<" "<< doubletR<<" "<<doubletZ
688  <<" "<< doubletPhi<<" "<< gasGap <<" "<< imeasphi<<" "<< clus<<" is invalid");
689  continue;
690  }
691 
692  if (!m_idHelper->valid(newId)) {
693  if (stationName.find("BI") != std::string::npos) {
694  ATH_MSG_WARNING("Temporary skipping creation of RPC digit for stationName="
695  << stationName << ", eta=" << stationEta << ", phi=" << stationPhi << ", doubletR=" << doubletR
696  << ", doubletZ=" << doubletZ << ", doubletPhi=" << doubletPhi << ", gasGap=" << gasGap
697  << ", measuresPhi=" << imeasphi << ", strip=" << clus << ", cf. ATLASRECTS-6124");
698  return StatusCode::SUCCESS;
699  } else {
700  ATH_MSG_ERROR("Created an invalid id, aborting!");
701  m_idHelper->print(newId);
702  return StatusCode::FAILURE;
703  }
704  }
705 
709  // One identifier but several deposits // name m_sdo_tmp_map is wrong call it m_sdo_map
710  if (m_sdo_tmp_map.find(newId) == m_sdo_tmp_map.end()) {
711  std::vector<MuonSimData::Deposit> newdeps;
712  newdeps.push_back(deposit);
713  m_sdo_tmp_map.insert(std::map<Identifier, std::vector<MuonSimData::Deposit>>::value_type(newId, newdeps));
714  } else {
715  m_sdo_tmp_map[newId].push_back(deposit);
716  }
717  } // end for cluster
718  } // loop on eta and phi
719  } // end loop hits
720 
721  if (m_muonOnlySDOs) {
722  for (auto it = channelSimDataMap.begin(); it != channelSimDataMap.end(); ++it) {
723  MuonSimData simData(it->second.deposits, 0);
724  simData.setPosition(it->second.gpos);
725  simData.setTime(it->second.simTime);
726  auto insertResult = sdoContainer->insert(std::make_pair(it->first, simData));
727  if (!insertResult.second)
728  ATH_MSG_WARNING("Attention: this sdo is not recorded, since the identifier already exists in the sdoContainer map");
729  }
730  }
731 
732  } // end loop detector elements
733 
735 
736  std::map<Identifier, std::vector<MuonSimData::Deposit>>::iterator map_iter = m_sdo_tmp_map.begin();
737  ATH_MSG_DEBUG("Start the digit map loop");
738 
739  for (; map_iter != m_sdo_tmp_map.end(); ++map_iter) {
740  // Identifier
741  const Identifier theId = (*map_iter).first;
742  ATH_MSG_DEBUG("in the map loop: id " << m_idHelper->show_to_string(theId));
743  // Deposit
744  const std::vector<MuonSimData::Deposit> theDeps = (*map_iter).second;
745 
746  // store the SDO from the muon
747  MuonSimData::Deposit theMuon; // useful beacuse it sorts the digits in ascending time.
748  std::multimap<double, MuonSimData::Deposit> times; // extract here time info from deposits.
749 
750  // loop on the vector deposit
751  for (unsigned int k = 0; k < theDeps.size(); k++) {
752  double time = theDeps[k].second.secondEntry();
753  times.insert(std::multimap<double, MuonSimData::Deposit>::value_type(time, theDeps[k]));
754  }
755 
756  // now iterate again over the multimap entries and store digits after dead time applied
757 
758  IdContext rpcContext = m_idHelper->module_context(); // work on chamber context
759 
761 
762  // loop to suppress digits too close in time (emulate Front-End and CMA dead time)
763  double last_time = -10000; // init to high value
764  for (; map_dep_iter != times.end(); ++map_dep_iter) {
765  double currTime = (*map_dep_iter).first;
766  ATH_MSG_VERBOSE("deposit with time " << currTime);
767 
769  // store (before any cut: all G4 hits) in the SDO container
770  // Identifier sdo and digit are the same
771  if (sdoContainer->find(theId) != sdoContainer->end()) // Identifier exist -> increase deposit
772  {
773  std::map<Identifier, MuonSimData>::const_iterator it = sdoContainer->find(theId);
774  std::vector<MuonSimData::Deposit> deps = ((*it).second).getdeposits();
775  deps.push_back((*map_dep_iter).second);
776  } else // Identifier does not exist -> create (Id,deposit)
777  {
778  std::vector<MuonSimData::Deposit> deposits;
779  deposits.push_back((*map_dep_iter).second);
781  sdoContainer->insert(std::make_pair(theId, MuonSimData(deposits, 0)));
782  if (!insertResult.second)
784  "Attention TEMP: this sdo is not recorded, since the identifier already exists in the sdoContainer map");
785  }
786  }
787  // apply dead time
788  if (std::abs(currTime - last_time) > (m_deadTime)) {
789  ATH_MSG_DEBUG("deposit with time " << currTime << " is distant enough from previous (if any) hit on teh same strip");
790  last_time = (*map_dep_iter).first;
791 
792  // first add time jitter to the time:
793  double uncorrjitter = 0;
794  double tmp_UncorrJitter = m_UncorrJitter;
795  if (m_idHelper->stationName(theId) < 2) tmp_UncorrJitter = m_UncorrJitter_BIS78;
796  if (tmp_UncorrJitter > 0.01) uncorrjitter = CLHEP::RandGaussZiggurat::shoot(rndmEngine, 0., tmp_UncorrJitter);
797  // Historically patch for the cavern background
798  // Now we subtract TOF from IP to assume full time calibrated detector (t=0 for particle from IP at light speed)
799  // We add a time shift to emulate FE global offset
800 
801  const RpcReadoutElement* ele = detMgr->getRpcReadoutElement(theId);
802  Amg::Vector3D posi = ele->stripPos(theId);
803  double tp = m_patch_for_rpc_time ? posi.mag() / Gaudi::Units::c_light : 0.;
804  // Calculate propagation time for a hit at the center of the strip, to be subtructed as well as the nominal TOF
805  double propTimeFromStripCenter = PropagationTime(ele, theId, posi);
806  double newDigit_time = currTime + uncorrjitter + m_rpc_time_shift - tp - propTimeFromStripCenter;
807 
808  double digi_ToT = -1.; // Time over threshold, for Narrow-gap RPCs only
809  if (m_idHelper->stationName(theId) < 2) digi_ToT = timeOverThreshold(rndmEngine); //mn
810 
811  ATH_MSG_VERBOSE("last_time=currTime " << last_time << " jitter " << uncorrjitter << " TOFcorrection " << tp << " shift "
812  << m_rpc_time_shift << " newDigit_time " << newDigit_time);
813 
814  // Apply readout window (sensitive detector time window)
815  bool outsideDigitizationWindow = outsideWindow(newDigit_time);
816  if (outsideDigitizationWindow) {
817  ATH_MSG_VERBOSE("hit outside digitization window - do not produce digits");
818  ATH_MSG_DEBUG("Hit outside time window!!"
819  << " hit time (ns) = " << newDigit_time << " timeWindow = " << m_timeWindowLowerOffset << " / "
821 
822  continue;
823  }
824  // ok, let's store this digit
825  // this is an accepted hit to become digit
826  last_time = (*map_dep_iter).first;
827 
828  std::unique_ptr<RpcDigit> newDigit = std::make_unique<RpcDigit>(theId, newDigit_time, digi_ToT, false);
829 
830  Identifier elemId = m_idHelper->elementID(theId);
831  RpcDigitCollection* digitCollection = nullptr;
832 
833  IdentifierHash coll_hash;
834  if (m_idHelper->get_hash(elemId, coll_hash, &rpcContext)) {
835  ATH_MSG_ERROR("Unable to get RPC hash id from RPC Digit collection "
836  << "context begin_index = " << rpcContext.begin_index()
837  << " context end_index = " << rpcContext.end_index() << " the identifier is ");
838  elemId.show();
839  }
840 
841  // make new digit
842  ATH_MSG_DEBUG("Digit Id = " << m_idHelper->show_to_string(theId) << " digit time " << newDigit_time);
843 
844  // remember new collection.
845  if (coll_hash >= collections.size()) {
846  collections.resize (coll_hash+1);
847  }
848  digitCollection = collections[coll_hash].get();
849  if (!digitCollection) {
850  collections[coll_hash] = std::make_unique<RpcDigitCollection>(elemId, coll_hash);
851  digitCollection = collections[coll_hash].get();
852  }
853  digitCollection->push_back(std::move(newDigit));
854 
856  // put SDO collection in StoreGate
857  if (sdoContainer->find(theId) != sdoContainer->end()) {
858  std::map<Identifier, MuonSimData>::const_iterator it = sdoContainer->find(theId);
859  std::vector<MuonSimData::Deposit> deps = ((*it).second).getdeposits();
860  deps.push_back((*map_dep_iter).second);
861  } else {
862  std::vector<MuonSimData::Deposit> deposits;
863  deposits.push_back((*map_dep_iter).second);
865  sdoContainer->insert(std::make_pair(theId, MuonSimData(deposits, 0)));
866  if (!insertResult.second)
868  "Attention: this sdo is not recorded, since teh identifier already exists in the sdoContainer map");
869  }
870  }
871 
872  } else
873  ATH_MSG_DEBUG("discarding digit due to dead time: " << (*map_dep_iter).first << " " << last_time);
874  }
875 
876  } // loop to suppress digits too close in time ended
877 
878  // reset the pointer if it not null
879  m_thpcRPC.reset();
880  if (!m_simHitValidKey.empty()) {
882  ATH_CHECK(validHandle.record(std::move(inputSimHitColl)));
883  }
884 
885  return StatusCode::SUCCESS;
886 }
888  const Identifier& layerId) const {
889 
890  Amg::Vector3D lGasGapPos = reEle->localGasGapPos(layerId);
891  if (reEle->NphiStripPanels() != reEle->nGasGapPerLay()) {
892  lGasGapPos.y() =0.;
893  }
894 
898  const bool flip = reEle->numberOfLayers() == 2 &&
899  (m_idHelper->gasGap(layerId) == 2) != reEle->rotatedRpcModule();
900  const Amg::Transform3D fromHitToGap{reEle->transform(layerId).inverse() *
901  reEle->absTransform() * Amg::getTranslate3D(lGasGapPos) *
902  (flip ? Amg::getRotateY3D(180.*Gaudi::Units::deg) : Amg::Transform3D::Identity())};
903  ATH_MSG_VERBOSE("Transformation to go from hit to gap restframe "<<m_idHelper->print_to_string(layerId)
904  <<" "<<Amg::toString(fromHitToGap));
905  return fromHitToGap;
906 }
907 
908 //--------------------------------------------
909 std::array<int, 3> RpcDigitizationTool::physicalClusterSize(const EventContext& ctx,
910  const RpcReadoutElement* ele,
911  const Identifier& id,
912  const Amg::Vector3D& gapCentre,
913  CLHEP::HepRandomEngine* rndmEngine) const {
914 
915 
916  std::array<int, 3> result{};
917 
918  const Amg::Vector3D position = fromSimHitToLayer(ele, id) * gapCentre;
919  const int doubletPhi = m_idHelper->doubletPhi(id);
920  const int gasGap = m_idHelper->gasGap(id);
921  const bool measuresPhi = m_idHelper->measuresPhi(id);
922  const double pitch= ele->StripPitch(measuresPhi);
923 
924 
925  const int nstrip = ele->stripNumber(position.block<2,1>(0,0), id);
926  const int numStrips = ele->Nstrips(measuresPhi);
927 
928  result[1] = nstrip;
929  result[2] = nstrip;
930 
931  if (nstrip < 1 || nstrip > numStrips) {
932  return make_array<int, 3>(-1);
933  }
934  const Amg::Vector3D locStripPos = ele->transform(id).inverse()*ele->stripPos(doubletPhi, gasGap, measuresPhi, nstrip);
935  float xstripnorm = (locStripPos -position).x() / pitch ;
936  result[0] = determineClusterSize(ctx, id, xstripnorm, rndmEngine);
937 
938  //
939 
940 
941  if (m_turnON_clustersize == false) result[0] = 1;
942 
943  return result;
944 }
945 
946 //--------------------------------------------
948  std::array<int, 3>&& pcs,
949  const Identifier& id) const {
950 
951 
952  const int nstrips = ele->Nstrips(m_idHelper->measuresPhi(id));
953 
954  if (pcs[0] == -2) {
955  pcs[1] = pcs[2] - 1;
956  } else if (pcs[0] == 2) {
957  pcs[2] = pcs[1] + 1;
958  } else if (pcs[0] > 2) {
959  pcs[1] = pcs[1] - pcs[0] / 2;
960  if (fmod(pcs[0], 2) == 0) pcs[1] = pcs[1] + 1;
961  pcs[2] = pcs[1] + pcs[0] - 1;
962  } else if (pcs[0] < -2) {
963  pcs[1] = pcs[1] + pcs[0] / 2;
964  pcs[2] = pcs[1] - pcs[0] - 1;
965  }
966 
967  // cut the clusters at the beginning and at the end of the chamber
968 
969  pcs[1] = std::clamp(pcs[1], 1, nstrips);
970  pcs[2] = std::clamp(pcs[2], 1, nstrips);
971 
972  pcs[0] = pcs[2] - pcs[1] + 1;
973 
974  return pcs;
975 }
976 
977 //--------------------------------------------
979  const Identifier& id,
980  const Amg::Vector3D& globPos) const {
981 
982  double distance{0.};
983  if (m_idHelper->measuresPhi(id)) {
984  distance = ele->distanceToPhiReadout(globPos);
985  } else {
986  distance = ele->distanceToEtaReadout(globPos);
987  }
988 
989  // distance in mm, SIG_VEL in ns/m
990  return std::abs(distance * SIG_VEL * 1.e-3);
991 }
992 
993 //--------------------------------------------
994 long long int RpcDigitizationTool::PackMCTruth(float proptime, float bctime, float posy, float posz) const {
995  // start with proptime: it is usually ~ns. It comes in ns. We express it in ns/10. use only 8 bits
996  if (proptime < 0) {
997  ATH_MSG_WARNING("A poblem: packing a propagation time <0 " << proptime << " redefine it as 0");
998  proptime = 0.;
999  }
1000  long long int new_proptime = int(proptime * 10) & 0xff;
1001 
1002  // now tof. it is ~100ns. comes in ns. express it in ns/10. 16 bits needed (0-32768)
1003  // now BC time: it is ~100ns. comes in ns. express it in ns/10. 16 bits needed (0-32768)
1004  // can be negative (=> add 300 ns)
1005 
1006  long long int new_bctime = int((bctime + 300.) * 10.) & 0xffff;
1007 
1008  // posy: ~1000mm comes in mm, write it in mm*10. need 16 bits (0-32768)
1009  // can be negative (=>add 1500 mm)
1010 
1011  long long int new_posy = int((posy + 1500.) * 10.) & 0xffff;
1012 
1013  // posz: ~1000mm comes in mm, write it in mm*10. need 16 bits (0-32768)
1014  // can be negative (=>add 1500 mm)
1015 
1016  long long int new_posz = int((posz + 1500.) * 10.) & 0xffff;
1017 
1018  return (new_proptime + (new_bctime << 8) + (new_posy << 24) + (new_posz << 40));
1019 }
1020 
1021 //--------------------------------------------
1022 void RpcDigitizationTool::UnPackMCTruth(double theWord, float& proptime, float& bctime, float& posy, float& posz) {
1023  // int64_t is just a shorter way of writing long long int
1024  using Repacker = union
1025 
1026  {
1027  double dWord;
1028 
1029  int64_t iWord;
1030  };
1031  Repacker MCTruth;
1032  MCTruth.dWord = theWord;
1033  proptime = ((MCTruth.iWord) & 0x00000000000000ffLL) / 10.;
1034  bctime = (((MCTruth.iWord) & 0x0000000000ffff00LL) >> 8) / 10.;
1035  posy = (((MCTruth.iWord) & 0x000000ffff000000LL) >> 24) / 10.;
1036  posz = (((MCTruth.iWord) & 0x00ffff0000000000LL) >> 40) / 10.;
1037 
1038  //
1039  bctime = bctime - 300.;
1040  posy = posy - 1500.;
1041  posz = posz - 1500.;
1042 }
1043 
1044 //--------------------------------------------
1046  if (!m_tagInfoMgr) return StatusCode::FAILURE;
1047 
1048  std::string RpctimeSchema = "";
1049  std::stringstream RpctimeShift;
1050  RpctimeShift << (int)m_rpc_time_shift;
1051 
1052  if (m_patch_for_rpc_time) {
1053  RpctimeSchema = "Datalike_TOFoff_TimeShift" + RpctimeShift.str() + "nsec";
1054  } else {
1055  RpctimeSchema = "G4like_TOFon_TimeShift" + RpctimeShift.str() + "nsec";
1056  }
1057 
1058  StatusCode sc = m_tagInfoMgr->addTag(m_RPC_TimeSchema, RpctimeSchema);
1059 
1060  if (sc.isFailure()) {
1061  ATH_MSG_WARNING(m_RPC_TimeSchema << " " << RpctimeSchema << " not added to TagInfo ");
1062  return sc;
1063  } else {
1064  ATH_MSG_DEBUG(m_RPC_TimeSchema << " " << RpctimeSchema << " added to TagInfo ");
1065  }
1066 
1067  return StatusCode::SUCCESS;
1068 }
1069 
1070 
1071 //--------------------------------------------
1072 std::pair<bool,bool> RpcDigitizationTool::detectionEfficiency(const EventContext& ctx,
1073  const Identifier& IdEta,
1074  const Identifier& IdPhi,
1075  CLHEP::HepRandomEngine* rndmEngine,
1076  const HepMcParticleLink& trkParticle) const {
1077 
1078 
1079 
1080  ATH_MSG_DEBUG("RpcDigitizationTool::in DetectionEfficiency");
1081 
1082  ATH_MSG_DEBUG("EtaPanelId to look for Eff is " << m_idHelper->show_to_string(IdEta));
1083  ATH_MSG_DEBUG("PhiPanelId to look for Eff is " << m_idHelper->show_to_string(IdPhi));
1084 
1085 
1086  // dead spacers are not simulated in GEANT4 => their effect must be emulated in the digitizer as an effective max. efficiency = 99%
1087  // (spacers are 1x1cm^2 over a grid of 10x10cm^2 =? geometrical ineff. introduced is 1% for normal incidence)
1088  float maxGeomEff{0.99}, PhiAndEtaEff{0.99}, OnlyEtaEff{0.f}, OnlyPhiEff{0.f};
1089 
1090  // 2=BML,3=BMS,4=BOL,5=BOS,8=BMF,9=BOF,10=BOG
1091  int stationName = m_idHelper->stationName(IdEta);
1092  int stationEta = m_idHelper->stationEta(IdEta);
1093  int doubletR = m_idHelper->doubletR(IdEta);
1094 
1095  // remove feet extension. driven by joboption
1097  return std::make_pair(false, false);
1098  }
1099 
1100 
1101  if (!m_turnON_efficiency) {
1102  return std::make_pair(true, true);
1103  }
1104  bool etaStripOn{true}, phiStripOn{true};
1105 
1106  // int stripetadead = 0 ; // not used
1107  // int stripphidead = 0 ; // not used
1108 
1109  unsigned int index = stationName - 2;
1110  // BML and BMS, BOL and BOS come first (stationName= 2 and 3, 4 and 5 -> index 0-3)
1111  if (stationName > 5 && stationName < 50) index = index - 2;
1112  // BMF, BOF and BOG are 8,9,10 => must be 4,5 and 6
1113  else if (stationName > 50)
1114  index = index - 44;
1115  // BME and BOE 53 and 54 are at indices 7 and 8
1116 
1117  if (!m_Efficiency_fromCOOL && stationName >= 2) {
1118  if (index > m_PhiAndEtaEff_A.size() || index > m_OnlyEtaEff_A.size() || index > m_OnlyPhiEff_A.size()) {
1119  THROW_EXCEPTION("Index out of array in Detection Efficiency SideA " << index << " stationName = " << stationName);
1120  }
1121 
1122  PhiAndEtaEff = m_PhiAndEtaEff_A[index];
1123  OnlyEtaEff = m_OnlyEtaEff_A[index];
1124  OnlyPhiEff = m_OnlyPhiEff_A[index];
1125 
1126  if (stationEta < 0) {
1127  if (index > m_PhiAndEtaEff_C.size() || index > m_OnlyEtaEff_C.size() || index > m_OnlyPhiEff_C.size()) {
1128  THROW_EXCEPTION("Index out of array in Detection Efficiency SideC " << index << " stationName = " << stationName);
1129  }
1130  PhiAndEtaEff = m_PhiAndEtaEff_C[index];
1131  OnlyEtaEff = m_OnlyEtaEff_C[index];
1132  OnlyPhiEff = m_OnlyPhiEff_C[index];
1133  }
1134  } else if (stationName < 2 && (!m_Efficiency_fromCOOL || !m_Efficiency_BIS78_fromCOOL)) { // BIS
1135  PhiAndEtaEff = m_PhiAndEtaEff_BIS78;
1136  OnlyEtaEff = m_OnlyEtaEff_BIS78;
1137  OnlyPhiEff = m_OnlyPhiEff_BIS78;
1138  } else { // Efficiency from Cool
1139 
1140  const RpcCondDbData* readCdo{nullptr};
1141  if(!retrieveCondData(ctx, m_readKey, readCdo).isSuccess()){
1142  THROW_EXCEPTION("Failed to retrieve conditions object");
1143  }
1144 
1145  ATH_MSG_DEBUG("Efficiencies and cluster size + dead strips will be extracted from COOL");
1146 
1147  double FracDeadStripEta{0.}, FracDeadStripPhi{0.};
1148  double EtaPanelEfficiency{1.}, PhiPanelEfficiency{1.}, GapEfficiency{1.};
1149  int RPC_ProjectedTracksEta = 0;
1150 
1151  std::optional<double> fracDeadStripEtaFromCOOL = readCdo->getFracDeadStrip(IdEta);
1152  std::optional<double> fracDeadStripPhiFromCOOL = readCdo->getFracDeadStrip(IdPhi);
1153 
1154  bool noEntryInDb = !fracDeadStripEtaFromCOOL || !fracDeadStripPhiFromCOOL;
1155 
1156  FracDeadStripEta = fracDeadStripEtaFromCOOL.value_or(0.);
1157  FracDeadStripPhi = fracDeadStripPhiFromCOOL.value_or(0.);
1158  RPC_ProjectedTracksEta = readCdo->getProjectedTrack(IdEta).value_or(0);
1159 
1160  EtaPanelEfficiency = readCdo->getEfficiency(IdEta).value_or(1.);
1161  PhiPanelEfficiency = readCdo->getEfficiency(IdPhi).value_or(1.);
1162  GapEfficiency = readCdo->getGapEfficiency(IdEta).value_or(1.);
1163 
1164  if (std::abs(FracDeadStripEta - 1.) < 0.001) {
1165  ATH_MSG_DEBUG("Watch out: SPECIAL CASE: Read from Cool: FracDeadStripEta/Phi "
1166  << FracDeadStripEta << "/" << FracDeadStripPhi << " RPC_ProjectedTracksEta " << RPC_ProjectedTracksEta
1167  << " Eta/PhiPanelEfficiency " << EtaPanelEfficiency << "/" << PhiPanelEfficiency << " gapEff " << GapEfficiency
1168  << " for gas gap " << m_idHelper->show_to_string(IdEta) << " id " << IdEta.get_identifier32().get_compact());
1169  // dead eta panel => cannot determine the strip status for phi strips
1170  // FracDeadStripPhi must be reset to 0. and undefinedPhiStripStatus = true
1171  FracDeadStripPhi = 0.;
1172  ATH_MSG_VERBOSE("Watch out: SPECIAL CASE: Resetting FracDeadStripPhi " << FracDeadStripPhi << " ignoring phi dead strips ");
1173  }
1174 
1175  // special test
1176  // here redefining the efficiencies:
1177  // EtaPanelEfficiency = 0.92;
1178  // PhiPanelEfficiency = 0.85;
1179  // GapEfficiency = 0.97;
1180  bool changing = false;
1181  ATH_MSG_DEBUG("Read from Cool: FracDeadStripEta/Phi " << FracDeadStripEta << "/" << FracDeadStripPhi << " RPC_ProjectedTracksEta "
1182  << RPC_ProjectedTracksEta << " Eta/PhiPanelEfficiency " << EtaPanelEfficiency
1183  << "/" << PhiPanelEfficiency << " gapEff " << GapEfficiency);
1184  // if ((1.-FracDeadStripEta)<EtaPanelEfficiency)
1185  if ((maxGeomEff - FracDeadStripEta) - EtaPanelEfficiency < -0.011) {
1186  ATH_MSG_DEBUG("Ineff. from dead strips on Eta Panel larger that measured efficiency: deadFrac="
1187  << FracDeadStripEta << " Panel Eff=" << EtaPanelEfficiency << " for Panel " << m_idHelper->show_to_string(IdEta));
1188  ATH_MSG_DEBUG("... see the corresponding report from RpcDetectorStatusDbTool");
1189  // EtaPanelEfficiency = 1.-FracDeadStripEta;
1190  EtaPanelEfficiency = maxGeomEff - FracDeadStripEta;
1191  changing = true;
1192  }
1193  // if ((1.-FracDeadStripPhi)<PhiPanelEfficiency)
1194  if ((maxGeomEff - FracDeadStripPhi) - PhiPanelEfficiency < -0.011) {
1195  ATH_MSG_DEBUG("Ineff. from dead strips on Phi Panel larger that measured efficiency: deadFrac="
1196  << FracDeadStripPhi << " Panel Eff=" << PhiPanelEfficiency << " for Panel " << m_idHelper->show_to_string(IdPhi));
1197  ATH_MSG_DEBUG("... see the corresponding report among the warnings of RpcDetectorStatusDbTool");
1198  // PhiPanelEfficiency = 1.-FracDeadStripPhi;
1199  PhiPanelEfficiency = maxGeomEff - FracDeadStripPhi;
1200  changing = true;
1201  }
1202  // if ((1.-FracDeadStripEta*FracDeadStripPhi)<GapEfficiency)
1203  if ((maxGeomEff - FracDeadStripEta * FracDeadStripPhi) - GapEfficiency < -0.011) {
1204  ATH_MSG_DEBUG("Ineff. from dead strips on Eta/Phi Panels larger that measured EtaORPhi efficiency: deadFrac="
1205  << FracDeadStripEta * FracDeadStripPhi << " EtaORPhi Eff=" << GapEfficiency << " for GasGap "
1206  << m_idHelper->show_to_string(IdEta));
1207  ATH_MSG_DEBUG("... see the corresponding report among the warnings of RpcDetectorStatusDbTool");
1208  // GapEfficiency = 1.-FracDeadStripEta*FracDeadStripPhi;
1209  GapEfficiency = maxGeomEff - FracDeadStripEta * FracDeadStripPhi;
1210  changing = true;
1211  }
1212  if (changing)
1213  ATH_MSG_DEBUG("Rinormalized Values from Cool: FracDeadStripEta/Phi "
1214  << FracDeadStripEta << "/" << FracDeadStripPhi << " RPC_ProjectedTracksEta " << RPC_ProjectedTracksEta
1215  << " Eta/PhiPanelEfficiency " << EtaPanelEfficiency << "/" << PhiPanelEfficiency << " gapEff " << GapEfficiency);
1216 
1217  // gabriele //..stefania - if there are dead strips renormalize the eff. to the active area
1218  if (m_kill_deadstrips) {
1219  if ((FracDeadStripEta > 0.0 && FracDeadStripEta < 1.0) || (FracDeadStripPhi > 0.0 && FracDeadStripPhi < 1.0) || (noEntryInDb)) {
1220  EtaPanelEfficiency = EtaPanelEfficiency / (maxGeomEff - FracDeadStripEta);
1221  PhiPanelEfficiency = PhiPanelEfficiency / (maxGeomEff - FracDeadStripPhi);
1222  GapEfficiency = GapEfficiency / (maxGeomEff - FracDeadStripEta * FracDeadStripPhi);
1223 
1224  if (EtaPanelEfficiency > maxGeomEff) EtaPanelEfficiency = maxGeomEff;
1225  if (PhiPanelEfficiency > maxGeomEff) PhiPanelEfficiency = maxGeomEff;
1226  if (GapEfficiency > maxGeomEff) GapEfficiency = maxGeomEff;
1227 
1228  if (EtaPanelEfficiency > GapEfficiency) GapEfficiency = EtaPanelEfficiency;
1229  if (PhiPanelEfficiency > GapEfficiency) GapEfficiency = PhiPanelEfficiency;
1230  ATH_MSG_DEBUG("Eff Redefined (to correct for deadfrac): FracDeadStripEta/Phi "
1231  << " Eta/PhiPanelEfficiency " << EtaPanelEfficiency << "/" << PhiPanelEfficiency << " gapEff "
1232  << GapEfficiency);
1233  }
1234  }
1235 
1236  // values from COOLDB (eventually overwritten later)
1237  PhiAndEtaEff = float(EtaPanelEfficiency + PhiPanelEfficiency - GapEfficiency);
1238  if (PhiAndEtaEff < 0.) PhiAndEtaEff = 0.;
1239  OnlyEtaEff = float(EtaPanelEfficiency - PhiAndEtaEff);
1240  if (OnlyEtaEff < 0.) OnlyEtaEff = 0.;
1241  OnlyPhiEff = float(PhiPanelEfficiency - PhiAndEtaEff);
1242  if (OnlyPhiEff < 0.) OnlyPhiEff = 0.;
1243 
1244  // special patch to be true only when m_Efficiency_fromCOOL=true and /RPC/DQMF/ELEMENT_STATUS tag is
1245  // RPCDQMFElementStatus_2012_Jaunuary_26
1246  bool applySpecialPatch = false;
1248  if (m_idHelper->stationName(IdEta) == 3)
1249  {
1250  if (std::abs(m_idHelper->stationEta(IdEta)) == 6 && m_idHelper->doubletR(IdEta) == 1 &&
1251  m_idHelper->doubletZ(IdEta) == 2 && m_idHelper->doubletPhi(IdEta) == 1) {
1252  applySpecialPatch = true;
1254  "Applying special patch for BMS at |eta|=6 lowPt plane -dbbZ=2 and dbPhi=1 ... will use default eff. for Id "
1255  << m_idHelper->show_to_string(IdEta));
1257  "Applying special patch: THIS HAS TO BE DONE IF /RPC/DQMF/ELEMENT_STATUS tag is "
1258  "RPCDQMFElementStatus_2012_Jaunuary_2");
1259  }
1260  }
1261  }
1262 
1263  // if projected tracks number too low or inconsistent values get efficiencies from joboption and overwrite previous values
1264  if (applySpecialPatch || RPC_ProjectedTracksEta < m_CutProjectedTracks || RPC_ProjectedTracksEta > 10000000 ||
1265  EtaPanelEfficiency > 1 || EtaPanelEfficiency < 0 || PhiPanelEfficiency > 1 || PhiPanelEfficiency < 0 || GapEfficiency > 1 ||
1266  GapEfficiency < 0) {
1267  if (index > m_PhiAndEtaEff_A.size() || index > m_OnlyEtaEff_A.size() || index > m_OnlyPhiEff_A.size()) {
1268  THROW_EXCEPTION("Index out of array in Detection Efficiency SideA COOLDB" << index << " stationName = " << stationName);
1269  }
1270  if (RPC_ProjectedTracksEta < m_CutProjectedTracks)
1271  ATH_MSG_DEBUG("# of proj tracks = " << RPC_ProjectedTracksEta << " < cut = " << m_CutProjectedTracks
1272  << " resetting eff. from cool with default(python) values ");
1273 
1274  PhiAndEtaEff = m_PhiAndEtaEff_A[index];
1275  OnlyEtaEff = m_OnlyEtaEff_A[index];
1276  OnlyPhiEff = m_OnlyPhiEff_A[index];
1277 
1278  if (stationEta < 0) {
1279  if (index > m_PhiAndEtaEff_C.size() || index > m_OnlyEtaEff_C.size() || index > m_OnlyPhiEff_C.size()) {
1280  THROW_EXCEPTION("Index out of array in Detection Efficiency SideC COOLDB" << index << " stationName = " << stationName);
1281  }
1282  PhiAndEtaEff = m_PhiAndEtaEff_C[index];
1283  OnlyEtaEff = m_OnlyEtaEff_C[index];
1284  OnlyPhiEff = m_OnlyPhiEff_C[index];
1285  }
1286 
1287  // if (m_applyEffThreshold) {
1288  // gabriele Set efficiency from dead strip fraction instead of nominal value
1289  float effgap = PhiAndEtaEff + OnlyEtaEff + OnlyPhiEff;
1290  float s_EtaPanelEfficiency = 1. - FracDeadStripEta;
1291  float s_PhiPanelEfficiency = 1. - FracDeadStripPhi;
1292  float s_PhiAndEtaEff = s_EtaPanelEfficiency * s_PhiPanelEfficiency / effgap;
1293  if (s_PhiAndEtaEff < PhiAndEtaEff) PhiAndEtaEff = s_PhiAndEtaEff;
1294  float s_OnlyEtaEff = s_EtaPanelEfficiency - PhiAndEtaEff;
1295  float s_OnlyPhiEff = s_PhiPanelEfficiency - PhiAndEtaEff;
1296 
1297  if (s_OnlyEtaEff < OnlyEtaEff) OnlyEtaEff = s_OnlyEtaEff;
1298  if (s_OnlyPhiEff < OnlyPhiEff) OnlyPhiEff = s_OnlyPhiEff;
1299  // }
1300  }
1301 
1302  float VolEff = PhiAndEtaEff + OnlyEtaEff + OnlyPhiEff;
1303  if (VolEff > maxGeomEff) {
1304  PhiAndEtaEff = (PhiAndEtaEff / VolEff) * maxGeomEff;
1305  OnlyEtaEff = (OnlyEtaEff / VolEff) * maxGeomEff;
1306  OnlyPhiEff = (OnlyPhiEff / VolEff) * maxGeomEff;
1307  }
1308 
1309  } // End eff from COOL
1310 
1311  // Efficiency correction factor for fractional-charged particles(added by Quanyin Li: quli@cern.ch)
1312  // link to truth particles and calculate the charge and betagamma
1313  HepMC::ConstGenParticlePtr genparticle = trkParticle.cptr();
1314  if (genparticle) {
1315  const int particlePdgId = genparticle->pdg_id();
1316  // only apply efficiency correction to fractional-charged particles based on pdgId betagamma
1317  if ((static_cast<int>(std::abs(particlePdgId) / 10000000) == 2) && (static_cast<int>(std::abs(particlePdgId) / 100000) == 200)) {
1318  const double eff_sf = FCPEfficiency(genparticle);
1319  // Apply scale factor to the 3 Eff.
1320  PhiAndEtaEff = PhiAndEtaEff * eff_sf;
1321  OnlyEtaEff = OnlyEtaEff * eff_sf;
1322  OnlyPhiEff = OnlyPhiEff * eff_sf;
1323  }
1324  }
1325 
1326  float I0 = PhiAndEtaEff;
1327  float I1 = PhiAndEtaEff + OnlyEtaEff;
1328  float ITot = PhiAndEtaEff + OnlyEtaEff + OnlyPhiEff;
1329 
1330  float GapEff = ITot ;
1331  float PhiEff = PhiAndEtaEff + OnlyPhiEff;
1332  float EtaEff = PhiAndEtaEff + OnlyEtaEff;
1333 
1334  ATH_MSG_DEBUG("DetectionEfficiency: Final Efficiency Values applied for "
1335  << m_idHelper->show_to_string(IdEta) << " are " << PhiAndEtaEff << "=PhiAndEtaEff " << OnlyEtaEff
1336  << "=OnlyEtaEff " << OnlyPhiEff << "=OnlyPhiEff " << GapEff << "=GapEff " << EtaEff << "=EtaEff " << PhiEff
1337  << "=PhiEff ");
1338 
1339  float rndmEff = CLHEP::RandFlat::shoot(rndmEngine, 1);
1340 
1341  if (rndmEff < I0) {
1342  phiStripOn = true;
1343  etaStripOn = true;
1344  } else if ((I0 <= rndmEff) && (rndmEff < I1)) {
1345  phiStripOn = false;
1346  etaStripOn = true;
1347  } else if ((I1 <= rndmEff) && (rndmEff <= ITot)) {
1348  phiStripOn = true;
1349  etaStripOn = false;
1350  } else {
1351  phiStripOn = false;
1352  etaStripOn = false;
1353  }
1354 
1355  return std::make_pair(etaStripOn, phiStripOn);
1356 }
1357 
1358 //--------------------------------------------
1359 int RpcDigitizationTool::determineClusterSize(const EventContext& ctx,
1360  const Identifier& idRpcStrip,
1361  double xstripnorm,
1362  CLHEP::HepRandomEngine* rndmEngine) const {
1363  ATH_MSG_DEBUG("RpcDigitizationTool::in determineClusterSize");
1364 
1365  ATH_MSG_DEBUG("Digit Id = " << m_idHelper->show_to_string(idRpcStrip));
1366 
1367  int ClusterSize = 1;
1368 
1369  double FracClusterSize1{1.}, FracClusterSize2{0.}, MeanClusterSize{1.},
1370  FracClusterSizeTail{0.}, MeanClusterSizeTail{1.},
1371  FracClusterSize2norm{0.};
1372 
1373  // 2=BML,3=BMS,4=BOL,5=BOS,8=BMF,9=BOF,10=BOG
1374  int stationName = m_idHelper->stationName(idRpcStrip);
1375  int stationEta = m_idHelper->stationEta(idRpcStrip);
1376  int measuresPhi = m_idHelper->measuresPhi(idRpcStrip);
1377 
1378  unsigned int index = stationName - 2;
1379  // BML and BMS, BOL and BOS come first (stationName= 2 and 3, 4 and 5 -> index 0-3)
1380  if (stationName > 5 && stationName < 50) index = index - 2;
1381  // BMF, BOF and BOG are 8,9,10 => must be 4,5 and 6
1382  else if (stationName > 50)
1383  index = index - 44;
1384  // BME and BOE 53 and 54 are at indices 7 and 8
1385 
1386  if (!m_ClusterSize_fromCOOL && stationName >= 2) {
1387  index += m_FracClusterSize1_A.size() / 2 * measuresPhi;
1388  if (index >= m_FracClusterSize1_A.size() ||
1389  index >= m_FracClusterSize2_A.size() ||
1390  index >= m_FracClusterSizeTail_A.size() ||
1391  index >= m_MeanClusterSizeTail_A.size()) {
1392  ATH_MSG_ERROR("Index out of array in determineClusterSize SideA " << index << " statName " << stationName);
1393  return 1;
1394  }
1395  FracClusterSize1 = m_FracClusterSize1_A[index];
1396  FracClusterSize2 = m_FracClusterSize2_A[index];
1397  FracClusterSizeTail = m_FracClusterSizeTail_A[index];
1398  MeanClusterSizeTail = m_MeanClusterSizeTail_A[index];
1399 
1400  if (stationEta < 0) {
1401  index += m_FracClusterSize1_C.size() / 2 * measuresPhi - m_FracClusterSize1_A.size() / 2 * measuresPhi;
1402  if (index >= m_FracClusterSize1_C.size() ||
1403  index >= m_FracClusterSize2_C.size() ||
1404  index >= m_FracClusterSizeTail_C.size() ||
1405  index >= m_MeanClusterSizeTail_C.size()) {
1406  ATH_MSG_ERROR("Index out of array in determineClusterSize SideC " << index << " statName " << stationName);
1407  return 1;
1408  }
1409  FracClusterSize1 = m_FracClusterSize1_C[index];
1410  FracClusterSize2 = m_FracClusterSize2_C[index];
1411  FracClusterSizeTail = m_FracClusterSizeTail_C[index];
1412  MeanClusterSizeTail = m_MeanClusterSizeTail_C[index];
1413  }
1414  } else if (stationName < 2 && (!m_ClusterSize_fromCOOL || !m_ClusterSize_BIS78_fromCOOL)) { // BIS78
1415  FracClusterSize1 = m_FracClusterSize1_BIS78;
1416  FracClusterSize2 = m_FracClusterSize2_BIS78;
1417  FracClusterSizeTail = m_FracClusterSizeTail_BIS78;
1418  MeanClusterSizeTail = m_MeanClusterSizeTail_BIS78;
1419  } else { // Cluster size from COOL
1420  const RpcCondDbData* readCdo{nullptr};
1421  retrieveCondData(ctx, m_readKey, readCdo).ignore();
1422 
1423  Identifier Id = m_idHelper->panelID(idRpcStrip);
1424 
1425  int RPC_ProjectedTracks = readCdo->getProjectedTrack(Id).value_or(0);
1426  FracClusterSize1 = readCdo->getFracClusterSize1(Id).value_or(1.);
1427  FracClusterSize2 = readCdo->getFracClusterSize2(Id).value_or(0.);
1428  MeanClusterSize = readCdo->getMeanClusterSize(Id).value_or(1.);
1429 
1430 
1431  ATH_MSG_DEBUG("FracClusterSize1 and 2 " << FracClusterSize1 << " " << FracClusterSize2);
1432 
1433  FracClusterSizeTail = 1. - FracClusterSize1 - FracClusterSize2;
1434 
1435  MeanClusterSizeTail = MeanClusterSize - FracClusterSize1 - 2 * FracClusterSize2;
1436 
1437  ATH_MSG_DEBUG("MeanClusterSizeTail and FracClusterSizeTail " << MeanClusterSizeTail << " " << FracClusterSizeTail);
1438 
1439  // if clustersize have anomalous values set to the average cluster size from joboption
1440  if (RPC_ProjectedTracks < m_CutProjectedTracks || RPC_ProjectedTracks > 10000000 || MeanClusterSize > m_CutMaxClusterSize ||
1441  MeanClusterSize <= 1 || FracClusterSizeTail < 0 || FracClusterSize1 < 0 || FracClusterSize2 < 0 || FracClusterSizeTail > 1 ||
1442  FracClusterSize1 > 1 || FracClusterSize2 > 1) {
1443  if (stationName >= 2) {
1444  index += m_FracClusterSize1_A.size() / 2 * measuresPhi;
1445  if (index >= m_FracClusterSize1_A.size() ||
1446  index >= m_FracClusterSize2_A.size() ||
1447  index >= m_FracClusterSizeTail_A.size() ||
1448  index >= m_MeanClusterSizeTail_A.size()) {
1449  ATH_MSG_ERROR("Index out of array in determineClusterSize SideA " << index << " statName " << stationName);
1450  return 1;
1451  }
1452  FracClusterSize1 = m_FracClusterSize1_A[index];
1453  FracClusterSize2 = m_FracClusterSize2_A[index];
1454  FracClusterSizeTail = m_FracClusterSizeTail_A[index];
1455  MeanClusterSizeTail = m_MeanClusterSizeTail_A[index];
1456 
1457  if (stationEta < 0) {
1458  index += m_FracClusterSize1_C.size() / 2 * measuresPhi - m_FracClusterSize1_A.size() / 2 * measuresPhi;
1459  if (index > m_FracClusterSize1_C.size() || index > m_FracClusterSize2_C.size() ||
1461  ATH_MSG_ERROR("Index out of array in determineClusterSize SideC " << index << " statName " << stationName);
1462  return 1;
1463  }
1464 
1465  FracClusterSize1 = m_FracClusterSize1_C[index];
1466  FracClusterSize2 = m_FracClusterSize2_C[index];
1467  FracClusterSizeTail = m_FracClusterSizeTail_C[index];
1468  MeanClusterSizeTail = m_MeanClusterSizeTail_C[index];
1469  }
1470  } else {
1471  FracClusterSize1 = m_FracClusterSize1_BIS78;
1472  FracClusterSize2 = m_FracClusterSize2_BIS78;
1473  FracClusterSizeTail = m_FracClusterSizeTail_BIS78;
1474  MeanClusterSizeTail = m_MeanClusterSizeTail_BIS78;
1475  }
1476  }
1477  }
1478  FracClusterSize1 = std::min(FracClusterSize1, 1.);
1479  FracClusterSize2 = std::min(FracClusterSize2, 1.);
1480  FracClusterSizeTail = std::min(FracClusterSizeTail, 1.);
1481  float FracTot = FracClusterSize1 + FracClusterSize2 + FracClusterSizeTail;
1482  if (FracTot != 1. && FracTot > 0) {
1483  FracClusterSize1 = FracClusterSize1 / FracTot;
1484  FracClusterSize2 = FracClusterSize2 / FracTot;
1485  FracClusterSizeTail = FracClusterSizeTail / FracTot;
1486  }
1487  if (MeanClusterSizeTail < 0 || MeanClusterSizeTail > 10) MeanClusterSizeTail = 1;
1488 
1489  ATH_MSG_VERBOSE("ClusterSize Final " << FracClusterSize1 << " FracClusterSize1 " << FracClusterSize2 << " FracClusterSize2 "
1490  << FracClusterSizeTail << " " << FracClusterSizeTail << " MeanClusterSizeTail "
1491  << MeanClusterSizeTail);
1492 
1493  float FracClusterSize1plus2 = FracClusterSize1 + FracClusterSize2;
1494  float ITot = FracClusterSize1 + FracClusterSize2 + FracClusterSizeTail;
1495 
1496  if (FracClusterSize1plus2 != 0) {
1497  // FracClusterSize1norm = FracClusterSize1 / FracClusterSize1plus2 ; // not used
1498  FracClusterSize2norm = FracClusterSize2 / FracClusterSize1plus2;
1499  }
1500 
1501  float rndmCS = CLHEP::RandFlat::shoot(rndmEngine, ITot);
1502 
1503  if (stationName >= 2) { // Legacy RPCs
1504  // Expanded CS2 of 1.3 to match average CS1 and CS2 (to be investigate)
1505  if (rndmCS < FracClusterSize1plus2) {
1506  // deterministic assignment of CS 1 or 2
1507  if (xstripnorm <= FracClusterSize2norm / 2. * 1.3) {
1508  ClusterSize = -2;
1509  } else if ((1.0 - FracClusterSize2norm / 2. * 1.3) <= xstripnorm) {
1510  ClusterSize = 2;
1511  } else {
1512  ClusterSize = 1;
1513  }
1514  if (m_ClusterSize1_2uncorr) {
1515  float rndmCS1_2 = CLHEP::RandFlat::shoot(rndmEngine, 1);
1516  ClusterSize = 1 + (rndmCS1_2 < FracClusterSize2norm);
1517  }
1518 
1519  } else if ((FracClusterSize1plus2 <= rndmCS) && (rndmCS <= ITot)) {
1520  ClusterSize = m_FirstClusterSizeInTail;
1521  ClusterSize += int(CLHEP::RandExponential::shoot(rndmEngine, MeanClusterSizeTail));
1522  float rndmLR = CLHEP::RandFlat::shoot(rndmEngine, 1.0);
1523  if (rndmLR > 0.5) ClusterSize = -ClusterSize;
1524  } else {
1525  ClusterSize = 1;
1526  }
1527 
1528  } else { // NRPCs
1529  if (rndmCS < FracClusterSize1) {
1530  ClusterSize = 1;
1531  } else if (rndmCS < FracClusterSize1 + FracClusterSize2) {
1532  ClusterSize = 2;
1533  } else {
1534  ClusterSize = int(CLHEP::RandExponential::shoot(rndmEngine, MeanClusterSizeTail));
1535  }
1536  ClusterSize = std::max(ClusterSize, 1);
1537  if (ClusterSize > 1) {
1538  float rndmLR = CLHEP::RandFlat::shoot(rndmEngine, 1.0);
1539  if (rndmLR > 0.5) ClusterSize = -ClusterSize;
1540  }
1541  }
1542 
1543  // negative CS correspond to left asymmetric cluster with respect to nstrip
1544  return ClusterSize;
1545 }
1547  double qcharge = 1.;
1548  const int particlePdgId = genParticle->pdg_id();
1549  // charge calculation
1550  qcharge = (static_cast<double>((std::abs(particlePdgId) / 1000) % 100)) / (static_cast<double>((std::abs(particlePdgId) / 10) % 100));
1551  qcharge = ((static_cast<double>((static_cast<int>(qcharge * 100))))) / 100;
1552  if (particlePdgId < 0.0) qcharge = -qcharge;
1553  // BetaGamma calculation
1554  const double QPx = genParticle->momentum().px();
1555  const double QPy = genParticle->momentum().py();
1556  const double QPz = genParticle->momentum().pz();
1557  const double QE = genParticle->momentum().e();
1558  const double QM2 = std::pow(QE, 2) - std::pow(QPx, 2) - std::pow(QPy, 2) - std::pow(QPz, 2);
1559  const double QP = std::hypot(QPx, QPy, QPz);
1560  const double QM = QM2 >=0 ? std::sqrt(QM2) : -1.;
1561 
1562  const double qbetagamma = QM > 0. ? QP / QM : -1.;
1563 
1564  // find the i in the array
1565  int i_e = -1;
1566  for (int i = 0; i < 12; i++) {
1567  if (Charge[i] == std::abs(qcharge)) {
1568  i_e = i;
1569  break;
1570  }
1571  }
1572  int i_v = -99, j_v = 99;
1573  if (qbetagamma != -1) {
1574  for (int i = 0; i < 15; i++) {
1575  if (Velocity[i] <= qbetagamma) { i_v = i; }
1576  }
1577  for (int i = 14; i >= 0; i--) {
1578  if (Velocity[i] >= qbetagamma) { j_v = i; }
1579  }
1580  }
1581  // calculate the efficiency according to charge and velocity. Using linear function to calculate efficiency of a specific velocity
1582  // between velocity1 and velocity2
1583  double eff_fcp = 1.0, eff_muon = 1.0;
1584  if (i_e >= 0 && i_e <= 11) {
1585  if (validIndex(j_v, N_Velocity) && validIndex(i_v, N_Velocity) && (j_v - i_v) == 1) {
1586  const double delta_v = Velocity[i_v] - Velocity[j_v];
1587  eff_fcp = (Eff_garfield[i_e][i_v] - Eff_garfield[i_e][j_v]) / delta_v * qbetagamma +
1588  (Eff_garfield[i_e][j_v] * Velocity[i_v] - Eff_garfield[i_e][i_v] * Velocity[j_v]) / delta_v;
1589  eff_muon = (Eff_garfield[11][i_v] - Eff_garfield[11][j_v]) / delta_v * qbetagamma +
1590  (Eff_garfield[11][j_v] * Velocity[i_v] - Eff_garfield[11][i_v] * Velocity[j_v]) / delta_v;
1591  } else if (i_v == 14 && j_v == 99) {
1592  eff_fcp = Eff_garfield[i_e][14];
1593  eff_muon = Eff_garfield[11][14];
1594  } else if (i_v == -99 && j_v == 0) {
1595  eff_fcp = Eff_garfield[i_e][0];
1596  eff_muon = Eff_garfield[11][0];
1597  } else {
1598  ATH_MSG_WARNING("Wrong particle with unknown velocity! Scale factor is set to be 1.");
1599  }
1600  } else {
1601  ATH_MSG_WARNING("Wrong particle with unknown charge! Scale factor is set to be 1.");
1602  }
1603  // A scale factor is calculated by efficiency of fcp / efficiency of muon(charge==1.0
1604  const double eff_SF = eff_fcp / eff_muon;
1605  return eff_SF;
1606 }
1607 
1608 double RpcDigitizationTool::timeOverThreshold(CLHEP::HepRandomEngine* rndmEngine) {
1609  //mn Time-over-threshold modeled as a narrow and a wide gaussian
1610  //mn based on the fit documented in https://its.cern.ch/jira/browse/ATLASRECTS-7820
1611  constexpr double tot_mean_narrow = 16.;
1612  constexpr double tot_sigma_narrow = 2.;
1613  constexpr double tot_mean_wide = 15.;
1614  constexpr double tot_sigma_wide = 4.5;
1615 
1616  double thetot = 0.;
1617 
1618  if (CLHEP::RandFlat::shoot(rndmEngine)<0.75) {
1619  thetot = CLHEP::RandGaussZiggurat::shoot(rndmEngine, tot_mean_narrow, tot_sigma_narrow);
1620  } else {
1621  thetot = CLHEP::RandGaussZiggurat::shoot(rndmEngine, tot_mean_wide, tot_sigma_wide);
1622  }
1623 
1624  return (thetot > 0.) ? thetot : 0.;
1625 }
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
RpcDigitizationTool::fillTagInfo
StatusCode fillTagInfo()
Definition: RpcDigitizationTool.cxx:1045
Run1
USAGE: openCoraCool.exe "COOLONL_SCT/COMP200".
Definition: openCoraCool.cxx:57
RpcDigitizationTool::m_sdo_tmp_map
std::map< Identifier, std::vector< MuonSimData::Deposit > > m_sdo_tmp_map
Definition: RpcDigitizationTool.h:165
RpcDigitizationTool::m_outputDigitCollectionKey
SG::WriteHandleKey< RpcDigitContainer > m_outputDigitCollectionKey
Definition: RpcDigitizationTool.h:218
RpcHitIdHelper::GetStationName
std::string GetStationName(const int &hid) const
Definition: RpcHitIdHelper.cxx:58
MuonIdHelper::stationNameIndex
int stationNameIndex(const std::string &name) const
Definition: MuonIdHelper.cxx:846
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
RpcDigitizationTool::m_rpc_time_shift
Gaudi::Property< double > m_rpc_time_shift
Definition: RpcDigitizationTool.h:168
GetLCDefs::Unknown
@ Unknown
Definition: GetLCDefs.h:21
RpcDigitizationTool::m_BIS_id
int m_BIS_id
Definition: RpcDigitizationTool.h:254
RpcDigitizationTool::fromSimHitToLayer
Amg::Transform3D fromSimHitToLayer(const MuonGM::RpcReadoutElement *readOutEle, const Identifier &layerId) const
Returns the position of the hit expressed in the gasGap coordinate system.
Definition: RpcDigitizationTool.cxx:887
Muon::nsw::STGTPSegments::moduleIDBits::stationPhi
constexpr uint8_t stationPhi
station Phi 1 to 8
Definition: NSWSTGTPDecodeBitmaps.h:129
MuonGM::MuonClusterReadoutElement::transform
virtual const Amg::Transform3D & transform() const override
Return local to global transform.
Definition: MuonClusterReadoutElement.h:124
RpcDigitizationTool::m_OnlyEtaEff_BIS78
Gaudi::Property< float > m_OnlyEtaEff_BIS78
Definition: RpcDigitizationTool.h:188
RpcHitIdHelper::GetHelper
static const RpcHitIdHelper * GetHelper(unsigned int nGasGaps=2)
Definition: RpcHitIdHelper.cxx:23
dumpTgcDigiDeadChambers.gasGap
list gasGap
Definition: dumpTgcDigiDeadChambers.py:33
MuonSimData::Deposit
std::pair< HepMcParticleLink, MuonMCData > Deposit
Definition: MuonSimData.h:66
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
MuonGM
Ensure that the Athena extensions are properly loaded.
Definition: GeoMuonHits.h:27
RpcDigitizationTool::m_tagInfoMgr
ITagInfoMgr * m_tagInfoMgr
Definition: RpcDigitizationTool.h:226
MuonGM::RpcReadoutElement::NphiStripPanels
int NphiStripPanels() const
returns the number of phi strip panels (1 or 2)
MuonGM::MuonReadoutElement::absTransform
const Amg::Transform3D & absTransform() const
Definition: MuonDetDescr/MuonReadoutGeometry/MuonReadoutGeometry/MuonReadoutElement.h:210
RpcDigitizationTool::m_muonHelper
const RpcHitIdHelper * m_muonHelper
Definition: RpcDigitizationTool.h:161
get_generator_info.result
result
Definition: get_generator_info.py:21
RPCSimHit::particleEncoding
int particleEncoding() const
Definition: RPCSimHit.h:61
max
#define max(a, b)
Definition: cfImp.cxx:41
RpcHitIdHelper::GetDoubletPhi
int GetDoubletPhi(const int &hid) const
Definition: RpcHitIdHelper.cxx:88
RpcDigitizationTool::m_turnON_efficiency
Gaudi::Property< bool > m_turnON_efficiency
Definition: RpcDigitizationTool.h:175
RpcDigitizationTool::physicalClusterSize
std::array< int, 3 > physicalClusterSize(const EventContext &ctx, const MuonGM::RpcReadoutElement *reEle, const Identifier &id, const Amg::Vector3D &posAtCentre, CLHEP::HepRandomEngine *rndmEngine) const
Cluster simulation: first step.
Definition: RpcDigitizationTool.cxx:909
IGeometryDBSvc.h
RpcDigitizationTool::m_BOG_id
int m_BOG_id
Definition: RpcDigitizationTool.h:250
SG::ReadCondHandle
Definition: ReadCondHandle.h:44
RpcDigitizationTool::m_CorrJitter
Gaudi::Property< double > m_CorrJitter
Definition: RpcDigitizationTool.h:127
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
RpcDigitizationTool::m_FracClusterSize1_A
Gaudi::Property< std::vector< double > > m_FracClusterSize1_A
Definition: RpcDigitizationTool.h:191
IRDBAccessSvc::getRecordsetPtr
virtual IRDBRecordset_ptr getRecordsetPtr(const std::string &node, const std::string &tag, const std::string &tag2node="", const std::string &connName="ATLASDD")=0
Provides access to the Recordset object containing HVS-tagged data.
RpcDigitizationTool::m_readKey
SG::ReadCondHandleKey< RpcCondDbData > m_readKey
Definition: RpcDigitizationTool.h:164
SG::ReadHandle::cptr
const_pointer_type cptr()
Dereference the pointer.
IGeoModelSvc
Definition: IGeoModelSvc.h:17
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
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
RPCSimHit::globalTime
double globalTime() const
Definition: RPCSimHit.h:54
RpcDigitizationTool::m_MeanClusterSizeTail_C
Gaudi::Property< std::vector< double > > m_MeanClusterSizeTail_C
Definition: RpcDigitizationTool.h:199
RPCSimHit::stepLength
double stepLength() const
Definition: RPCSimHit.h:60
RpcIdHelper::elementID
Identifier elementID(int stationName, int stationEta, int stationPhi, int doubletR) const
Definition: RpcIdHelper.cxx:802
dumpTgcDigiDeadChambers.stationName
dictionary stationName
Definition: dumpTgcDigiDeadChambers.py:30
MuonGM::RpcReadoutElement::nGasGapPerLay
int nGasGapPerLay() const
returns the number of gasgaps
RpcDigitizationTool::m_RPC_TimeSchema
Gaudi::Property< std::string > m_RPC_TimeSchema
Definition: RpcDigitizationTool.h:227
RpcHitIdHelper::GetMeasuresPhi
int GetMeasuresPhi(const int &hid) const
Definition: RpcHitIdHelper.cxx:96
RpcIdHelper::doubletZ
int doubletZ(const Identifier &id) const
Definition: RpcIdHelper.cxx:1062
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:70
index
Definition: index.py:1
SG::VarHandleBase::name
const std::string & name() const
Return the StoreGate ID for the referenced object.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleBase.cxx:75
RpcDigitizationTool::m_timeWindowUpperOffset
Gaudi::Property< double > m_timeWindowUpperOffset
Definition: RpcDigitizationTool.h:141
RpcDigitizationTool::m_BOG_BOF_DoubletR2_OFF
Gaudi::Property< bool > m_BOG_BOF_DoubletR2_OFF
Definition: RpcDigitizationTool.h:238
RpcDigitizationTool::m_FracClusterSize2_C
Gaudi::Property< std::vector< double > > m_FracClusterSize2_C
Definition: RpcDigitizationTool.h:197
RpcDigitCollection
Definition: RpcDigitCollection.h:17
ITagInfoMgr.h
RpcDigitizationTool::m_PhiAndEtaEff_BIS78
Gaudi::Property< float > m_PhiAndEtaEff_BIS78
Definition: RpcDigitizationTool.h:187
RpcDigitizationTool::m_CorrJitter_BIS78
Gaudi::Property< double > m_CorrJitter_BIS78
Definition: RpcDigitizationTool.h:130
RpcDigitizationTool::m_idHelper
const RpcIdHelper * m_idHelper
Definition: RpcDigitizationTool.h:160
conifer::pow
constexpr int pow(int x)
Definition: conifer.h:20
RpcDigitizationTool::PropagationTime
double PropagationTime(const MuonGM::RpcReadoutElement *reEle, const Identifier &id, const Amg::Vector3D &globPos) const
Calculates the propagation time along the strip.
Definition: RpcDigitizationTool.cxx:978
VKalVrtAthena::GeoModel::Run2
@ Run2
Definition: VrtSecInclusive.h:72
AtlasHitsVector
Definition: AtlasHitsVector.h:33
RpcDigitizationTool::m_OnlyPhiEff_BIS78
Gaudi::Property< float > m_OnlyPhiEff_BIS78
Definition: RpcDigitizationTool.h:189
skel.it
it
Definition: skel.GENtoEVGEN.py:423
RpcIdHelper::measuresPhi
bool measuresPhi(const Identifier &id) const override
Definition: RpcIdHelper.cxx:1068
createCablingJSON.doubletR
int doubletR
Definition: createCablingJSON.py:10
RpcDigitizationTool::FCPEfficiency
double FCPEfficiency(const HepMC::ConstGenParticlePtr &genParticle) const
Definition: RpcDigitizationTool.cxx:1546
Run2
Definition: openCoraCool.cxx:137
deg
#define deg
Definition: SbPolyhedron.cxx:17
ParticleTest.tp
tp
Definition: ParticleTest.py:25
RpcHitIdHelper::GetDoubletZ
int GetDoubletZ(const int &hid) const
Definition: RpcHitIdHelper.cxx:92
MuonGM::RpcReadoutElement::stripNumber
virtual int stripNumber(const Amg::Vector2D &pos, const Identifier &id) const override final
strip number corresponding to local position.
DataVector::get
const T * get(size_type n) const
Access an element, as an rvalue.
RpcDigitizationTool::m_detMgrKey
SG::ReadCondHandleKey< MuonGM::MuonDetectorManager > m_detMgrKey
Definition: RpcDigitizationTool.h:158
RPCSimHitCollection
AtlasHitsVector< RPCSimHit > RPCSimHitCollection
Definition: RPCSimHitCollection.h:15
RpcDigitizationTool::getNextEvent
StatusCode getNextEvent(const EventContext &ctx)
Get next event and extract collection of hit collections:
Definition: RpcDigitizationTool.cxx:337
RpcDigitizationTool::UnPackMCTruth
static void UnPackMCTruth(double theWord, float &proptime, float &tof, float &posy, float &posz)
Definition: RpcDigitizationTool.cxx:1022
MuonGM::RpcReadoutElement
An RpcReadoutElement corresponds to a single RPC module; therefore typicaly a barrel muon station con...
Definition: MuonDetDescr/MuonReadoutGeometry/MuonReadoutGeometry/RpcReadoutElement.h:54
IdContext::end_index
size_type end_index(void) const
Definition: IdContext.h:106
RPCSimHit::energyDeposit
double energyDeposit() const
Definition: RPCSimHit.h:58
RPCSimHit::localPosition
const Amg::Vector3D & localPosition() const
Definition: RPCSimHit.h:55
PileUpTimeEventIndex::index
index_type index() const
the index of the component event in PileUpEventInfo
Definition: PileUpTimeEventIndex.cxx:76
RpcDigitizationTool::m_UncorrJitter
Gaudi::Property< double > m_UncorrJitter
Calculates the position of the hit wrt to the strip panel this transformation is needed since the imp...
Definition: RpcDigitizationTool.h:126
RpcDigitizationTool::detectionEfficiency
std::pair< bool, bool > detectionEfficiency(const EventContext &ctx, const Identifier &ideta, const Identifier &idphi, CLHEP::HepRandomEngine *rndmEngine, const HepMcParticleLink &trkParticle) const
Evaluate detection efficiency.
Definition: RpcDigitizationTool.cxx:1072
TimedHitPtr< RPCSimHit >
MuonIdHelper::stationName
int stationName(const Identifier &id) const
Definition: MuonIdHelper.cxx:804
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
RpcIdHelper::channelID
Identifier channelID(int stationName, int stationEta, int stationPhi, int doubletR, int doubletZ, int doubletPhi, int gasGap, int measuresPhi, int strip) const
Definition: RpcIdHelper.cxx:940
RpcDigitizationTool::initialize
virtual StatusCode initialize() override final
Initialize.
Definition: RpcDigitizationTool.cxx:96
THROW_EXCEPTION
#define THROW_EXCEPTION(MSG)
Definition: MMReadoutElement.cxx:48
HepMC::ignoreTruthLink
bool ignoreTruthLink(const T &p, bool vetoPileUp)
Helper function for SDO creation in PileUpTools.
Definition: MagicNumbers.h:296
ITagInfoMgr::addTag
virtual StatusCode addTag(const std::string &tagName, const std::string &tagValue)=0
Method to allow clients to add in tags as: tag name, tag value.
x
#define x
RpcHitIdHelper.h
GenParticle.h
RpcDigitizationTool::m_FracClusterSize1_C
Gaudi::Property< std::vector< double > > m_FracClusterSize1_C
Definition: RpcDigitizationTool.h:196
RpcDigitizationTool::mergeEvent
virtual StatusCode mergeEvent(const EventContext &ctx) override final
When being run from PileUpToolsAlgs, this method is called at the end of the subevts loop.
Definition: RpcDigitizationTool.cxx:392
RpcDigitizationTool::m_PhiAndEtaEff_A
Gaudi::Property< std::vector< float > > m_PhiAndEtaEff_A
Definition: RpcDigitizationTool.h:180
RpcIdHelper.h
PileUpToolBase::m_vetoPileUpTruthLinks
Gaudi::Property< int > m_vetoPileUpTruthLinks
Definition: PileUpToolBase.h:58
AthenaPoolTestRead.sc
sc
Definition: AthenaPoolTestRead.py:27
RpcDigitizationTool::m_MeanClusterSizeTail_BIS78
Gaudi::Property< float > m_MeanClusterSizeTail_BIS78
Definition: RpcDigitizationTool.h:204
RpcDigitizationTool::m_rndmSvc
ServiceHandle< IAthRNGSvc > m_rndmSvc
Definition: RpcDigitizationTool.h:224
RpcDigitizationTool::outsideWindow
bool outsideWindow(double time) const
Definition: RpcDigitizationTool.h:258
PileUpMergeSvc::TimedList::type
std::list< value_t > type
type of the collection of timed data object
Definition: PileUpMergeSvc.h:75
RpcIdHelper::gasGap
int gasGap(const Identifier &id) const override
get the hashes
Definition: RpcIdHelper.cxx:1066
RpcDigitizationTool::m_kill_deadstrips
Gaudi::Property< bool > m_kill_deadstrips
Definition: RpcDigitizationTool.h:176
RpcDigitizationTool::m_FirstClusterSizeInTail
Gaudi::Property< int > m_FirstClusterSizeInTail
Definition: RpcDigitizationTool.h:178
RpcDigitizationTool::m_sdoAreOnlyDigits
Gaudi::Property< bool > m_sdoAreOnlyDigits
Definition: RpcDigitizationTool.h:228
RpcDigitizationTool::m_includePileUpTruth
Gaudi::Property< bool > m_includePileUpTruth
Definition: RpcDigitizationTool.h:173
grepfile.content
string content
Definition: grepfile.py:56
MuonGM::RpcReadoutElement::localToGlobalTransf
Amg::Transform3D localToGlobalTransf(const Identifier &id) const
Definition: MuonDetDescr/MuonReadoutGeometry/src/RpcReadoutElement.cxx:211
RpcDigitizationTool::m_ignoreRunDepConfig
Gaudi::Property< bool > m_ignoreRunDepConfig
Definition: RpcDigitizationTool.h:239
RpcDigitizationTool::timeOverThreshold
static double timeOverThreshold(CLHEP::HepRandomEngine *rndmEngine)
Definition: RpcDigitizationTool.cxx:1608
RpcHitIdHelper::GetPhiSector
int GetPhiSector(const int &hid) const
Definition: RpcHitIdHelper.cxx:69
IRDBAccessSvc.h
Definition of the abstract IRDBAccessSvc interface.
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
RpcIdHelper::doubletR
int doubletR(const Identifier &id) const
Definition: RpcIdHelper.cxx:1060
RpcDigitizationTool::m_PhiAndEtaEff_C
Gaudi::Property< std::vector< float > > m_PhiAndEtaEff_C
Definition: RpcDigitizationTool.h:183
MuonGM::RpcReadoutElement::distanceToPhiReadout
double distanceToPhiReadout(const Amg::Vector3D &P) const
Definition: MuonDetDescr/MuonReadoutGeometry/src/RpcReadoutElement.cxx:223
RpcDigitizationTool::TurnOnStrips
std::array< int, 3 > TurnOnStrips(const MuonGM::RpcReadoutElement *reEle, std::array< int, 3 > &&pcs, const Identifier &id) const
Cluster simulation: second step.
Definition: RpcDigitizationTool.cxx:947
lumiFormat.i
int i
Definition: lumiFormat.py:92
RpcDigitizationTool::doDigitization
StatusCode doDigitization(const EventContext &ctx, Collections_t &collections, MuonSimDataCollection *sdoContainer)
Digitization functionality shared with RPC_PileUpTool.
Definition: RpcDigitizationTool.cxx:467
VKalVrtAthena::GeoModel::Run1
@ Run1
Definition: VrtSecInclusive.h:72
RpcCondDbData
Definition: RpcCondDbData.h:24
RpcDigitizationTool::processBunchXing
virtual 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: RpcDigitizationTool.cxx:303
IRDBAccessSvc
IRDBAccessSvc is an abstract interface to the athena service that provides the following functionalit...
Definition: IRDBAccessSvc.h:45
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
SG::WriteHandle::ptr
pointer_type ptr()
Dereference the pointer.
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
MuonSimDataCollection
Definition: MuonSimDataCollection.h:21
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
Amg::Transform3D
Eigen::Affine3d Transform3D
Definition: GeoPrimitives.h:46
RpcIdHelper::panelID
Identifier panelID(const Identifier &padID, int gasGap, int measuresPhi) const
Definition: RpcIdHelper.cxx:879
RpcDigitizationTool::m_FracClusterSizeTail_A
Gaudi::Property< std::vector< double > > m_FracClusterSizeTail_A
Definition: RpcDigitizationTool.h:193
RpcDigitizationTool::m_simHitValidKey
SG::WriteHandleKey< RPCSimHitCollection > m_simHitValidKey
Definition: RpcDigitizationTool.h:223
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
RpcDigitizationTool::prepareEvent
virtual 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: RpcDigitizationTool.cxx:291
RpcDigitizationTool::m_RPCInfoFromDb
Gaudi::Property< bool > m_RPCInfoFromDb
Definition: RpcDigitizationTool.h:245
run
Definition: run.py:1
RPCSimHitCollection.h
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
RpcDigitizationTool::m_deadTime
Gaudi::Property< int > m_deadTime
Definition: RpcDigitizationTool.h:166
RpcDigitizationTool::m_inputHitCollectionName
std::string m_inputHitCollectionName
Definition: RpcDigitizationTool.h:217
CaloCondBlobAlgs_fillNoiseFromASCII.channelId
channelId
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:122
IRDBRecordset_ptr
std::shared_ptr< IRDBRecordset > IRDBRecordset_ptr
Definition: IRDBAccessSvc.h:25
SG::ReadHandle::isValid
virtual bool isValid() override final
Can the handle be successfully dereferenced?
PileUpToolBase
Definition: PileUpToolBase.h:18
RpcDigitizationTool::m_timeWindowLowerOffset
Gaudi::Property< double > m_timeWindowLowerOffset
Definition: RpcDigitizationTool.h:140
RpcDigitizationTool::Collections_t
std::vector< std::unique_ptr< RpcDigitCollection > > Collections_t
Definition: RpcDigitizationTool.h:94
RpcDigitizationTool::m_BOF_id
int m_BOF_id
Definition: RpcDigitizationTool.h:249
RpcDigitizationTool::m_FracClusterSize2_A
Gaudi::Property< std::vector< double > > m_FracClusterSize2_A
Definition: RpcDigitizationTool.h:192
RpcHitIdHelper::GetGasGapLayer
int GetGasGapLayer(const int &hid) const
Definition: RpcHitIdHelper.cxx:84
min
#define min(a, b)
Definition: cfImp.cxx:40
RpcDigitizationTool::m_OnlyEtaEff_C
Gaudi::Property< std::vector< float > > m_OnlyEtaEff_C
Definition: RpcDigitizationTool.h:185
IdContext::begin_index
size_type begin_index(void) const
Definition: IdContext.h:100
python.PyKernel.detStore
detStore
Definition: PyKernel.py:41
AtlasDetectorID::print_to_string
std::string print_to_string(Identifier id, const IdContext *context=0) const
or provide the printout in string form
Definition: AtlasDetectorID.cxx:655
HepMC::ConstGenParticlePtr
const GenParticle * ConstGenParticlePtr
Definition: GenParticle.h:38
PathResolver.h
MuonGM::RpcReadoutElement::rotatedRpcModule
bool rotatedRpcModule() const
Definition: MuonDetDescr/MuonReadoutGeometry/src/RpcReadoutElement.cxx:182
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
RpcDigitizationTool::m_OnlyPhiEff_A
Gaudi::Property< std::vector< float > > m_OnlyPhiEff_A
Definition: RpcDigitizationTool.h:181
PileUpTimeEventIndex::time
time_type time() const
bunch xing time in ns
Definition: PileUpTimeEventIndex.cxx:71
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
RpcIdHelper::gasGapMax
int gasGapMax() const
Definition: RpcIdHelper.cxx:1098
MuonGM::RpcReadoutElement::stripPos
Amg::Vector3D stripPos(const Identifier &id) const
Definition: MuonDetDescr/MuonReadoutGeometry/src/RpcReadoutElement.cxx:177
RpcDigitizationTool::m_OnlyPhiEff_C
Gaudi::Property< std::vector< float > > m_OnlyPhiEff_C
Definition: RpcDigitizationTool.h:184
MuonGM::RpcReadoutElement::localGasGapPos
Amg::Vector3D localGasGapPos(const Identifier &id) const
Returns the position of the gasGap w.r.t. rest frame of the chamber.
Definition: MuonDetDescr/MuonReadoutGeometry/src/RpcReadoutElement.cxx:193
RpcIdHelper::valid
bool valid(const Identifier &id) const
Definition: RpcIdHelper.cxx:604
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)
MuonIdHelper::stationEta
int stationEta(const Identifier &id) const
Definition: MuonIdHelper.cxx:809
MuonGM::RpcReadoutElement::StripPitch
double StripPitch(bool measphi) const
returns the strip pitch for the phi or eta plane
MuonSimData
Definition: MuonSimData.h:62
python.PhysicalConstants.c_light
float c_light
Definition: PhysicalConstants.py:63
Amg::getRotateY3D
Amg::Transform3D getRotateY3D(double angle)
get a rotation transformation around Y-axis
Definition: GeoPrimitivesHelpers.h:261
RpcDigitizationTool::m_FracClusterSize1_BIS78
Gaudi::Property< float > m_FracClusterSize1_BIS78
Definition: RpcDigitizationTool.h:201
RpcDigitizationTool::m_CutProjectedTracks
Gaudi::Property< int > m_CutProjectedTracks
Definition: RpcDigitizationTool.h:247
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
MuonGM::RpcReadoutElement::numberOfLayers
virtual int numberOfLayers(bool measphi=true) const override final
number of layers in phi/eta projection, same for eta/phi planes
MuonDetectorManager.h
MuonIdHelper::module_hash_max
size_type module_hash_max() const
the maximum hash value
Definition: MuonIdHelper.cxx:752
ATHRNG::RNGWrapper::getEngine
CLHEP::HepRandomEngine * getEngine(const EventContext &ctx) const
Retrieve the random engine corresponding to the provided EventContext.
Definition: RNGWrapper.h:134
RNGWrapper.h
python.LumiBlobConversion.pos
pos
Definition: LumiBlobConversion.py:18
AtlasDetectorID::print
void print(Identifier id, const IdContext *context=0) const
Expanded print out of any identifier.
Definition: AtlasDetectorID.cxx:648
SG::ReadCondHandleKey
Definition: ReadCondHandleKey.h:20
SG::WriteHandle
Definition: StoreGate/StoreGate/WriteHandle.h:76
DeMoScan.index
string index
Definition: DeMoScan.py:362
RpcDigitizationTool::m_EfficiencyPatchForBMShighEta
Gaudi::Property< bool > m_EfficiencyPatchForBMShighEta
Definition: RpcDigitizationTool.h:232
RpcDigitizationTool::m_OnlyEtaEff_A
Gaudi::Property< std::vector< float > > m_OnlyEtaEff_A
Definition: RpcDigitizationTool.h:182
RpcDigitizationTool::retrieveCondData
StatusCode retrieveCondData(const EventContext &ctx, const SG::ReadCondHandleKey< CondType > &key, const CondType *&condPtr) const
Definition: RpcDigitizationTool.cxx:272
DiTauMassTools::MaxHistStrategyV2::e
e
Definition: PhysicsAnalysis/TauID/DiTauMassTools/DiTauMassTools/HelperFunctions.h:26
RpcHitIdHelper::GetDoubletR
int GetDoubletR(const int &hid) const
Definition: RpcHitIdHelper.cxx:80
RpcDigitizationTool::m_UncorrJitter_BIS78
Gaudi::Property< double > m_UncorrJitter_BIS78
Definition: RpcDigitizationTool.h:129
IRDBRecord.h
Definition of the abstract IRDBRecord interface.
RpcDigitizationTool::determineClusterSize
int determineClusterSize(const EventContext &ctx, const Identifier &id, double xstripnorm, CLHEP::HepRandomEngine *rndmEngine) const
Definition: RpcDigitizationTool.cxx:1359
RPCSimHit::postLocalPosition
const Amg::Vector3D & postLocalPosition() const
Definition: RPCSimHit.h:57
SG::WriteHandle::record
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
RpcDigitizationTool::processAllSubEvents
virtual StatusCode processAllSubEvents(const EventContext &ctx) override final
alternative interface which uses the PileUpMergeSvc to obtain all the required SubEvents.
Definition: RpcDigitizationTool.cxx:426
AtlasDetectorID::show_to_string
std::string show_to_string(Identifier id, const IdContext *context=0, char sep='.') const
or provide the printout in string form
Definition: AtlasDetectorID.cxx:574
CaloSwCorrections.time
def time(flags, cells_name, *args, **kw)
Definition: CaloSwCorrections.py:242
TimedHitPtr::eventId
unsigned short eventId() const
the index of the component event in PileUpEventInfo.
Definition: TimedHitPtr.h:42
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
MuonIdHelper::get_hash
virtual int get_hash(const Identifier &id, IdentifierHash &hash_id, const IdContext *context=0) const override
Create hash id from compact id (return == 0 for OK)
Definition: MuonIdHelper.cxx:143
RPCSimHit.h
unit
const PlainObject unit() const
This is a plugin that makes Eigen look like CLHEP & defines some convenience methods.
Definition: AmgMatrixBasePlugin.h:20
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
RpcDigitizationTool.h
RpcDigitizationTool::m_Efficiency_fromCOOL
Gaudi::Property< bool > m_Efficiency_fromCOOL
Definition: RpcDigitizationTool.h:231
MuonIdHelper::module_context
IdContext module_context() const
id for module
Definition: MuonIdHelper.cxx:735
RpcDigitizationTool::m_FracClusterSizeTail_C
Gaudi::Property< std::vector< double > > m_FracClusterSizeTail_C
Definition: RpcDigitizationTool.h:198
GeoPrimitivesToStringConverter.h
LArNewCalib_DelayDump_OFC_Cali.idx
idx
Definition: LArNewCalib_DelayDump_OFC_Cali.py:69
RPCSimHit::RPCid
int RPCid() const
Definition: RPCSimHit.h:63
RpcDigitizationTool::m_onlyUseContainerName
Gaudi::Property< bool > m_onlyUseContainerName
Definition: RpcDigitizationTool.h:214
MuonGM::RpcReadoutElement::Nstrips
int Nstrips(bool measphi) const
returns the number of strips for the phi or eta plane
AtlasHitsVector::size
size_type size() const
Definition: AtlasHitsVector.h:143
RpcDigitizationTool::m_turnON_clustersize
Gaudi::Property< bool > m_turnON_clustersize
Definition: RpcDigitizationTool.h:177
RpcDigitizationTool::m_ClusterSize1_2uncorr
Gaudi::Property< bool > m_ClusterSize1_2uncorr
Definition: RpcDigitizationTool.h:236
RpcDigitizationTool::m_BIL_id
int m_BIL_id
Definition: RpcDigitizationTool.h:253
createCablingJSON.doubletPhi
int doubletPhi
Definition: createCablingJSON.py:11
SubEventIterator
std::vector< xAOD::EventInfo::SubEvent >::const_iterator SubEventIterator
Definition: IPileUpTool.h:22
RPCSimHit
Definition: RPCSimHit.h:19
RpcDigitizationTool::m_FracClusterSize2_BIS78
Gaudi::Property< float > m_FracClusterSize2_BIS78
Definition: RpcDigitizationTool.h:202
RpcDigitizationTool::m_BOS_id
int m_BOS_id
Definition: RpcDigitizationTool.h:251
RpcDigitizationTool::m_patch_for_rpc_time
Gaudi::Property< bool > m_patch_for_rpc_time
Definition: RpcDigitizationTool.h:167
merge.status
status
Definition: merge.py:17
MuonGM::RpcReadoutElement::distanceToEtaReadout
double distanceToEtaReadout(const Amg::Vector3D &P) const
Definition: MuonDetDescr/MuonReadoutGeometry/src/RpcReadoutElement.cxx:278
RpcDigitizationTool::m_muonOnlySDOs
Gaudi::Property< bool > m_muonOnlySDOs
Definition: RpcDigitizationTool.h:208
RpcDigitizationTool::m_CutMaxClusterSize
Gaudi::Property< float > m_CutMaxClusterSize
Definition: RpcDigitizationTool.h:246
RpcDigitizationTool::m_RPCHitCollList
std::vector< std::unique_ptr< RPCSimHitCollection > > m_RPCHitCollList
Definition: RpcDigitizationTool.h:162
simData
constexpr bool simData
Definition: constants.h:36
RpcDigitizationTool::m_FracClusterSizeTail_BIS78
Gaudi::Property< float > m_FracClusterSizeTail_BIS78
Definition: RpcDigitizationTool.h:203
RpcDigitizationTool::m_thpcRPC
std::unique_ptr< TimedHitCollection< RPCSimHit > > m_thpcRPC
Definition: RpcDigitizationTool.h:163
hitTime
float hitTime(const AFP_SIDSimHit &hit)
Definition: AFP_SIDSimHit.h:39
IRDBRecordset.h
Definition of the abstract IRDBRecordset interface.
Muon::nsw::STGTPSegments::moduleIDBits::stationEta
constexpr uint8_t stationEta
1 to 3
Definition: NSWSTGTPDecodeBitmaps.h:127
RpcDigitizationTool::m_mergeSvc
ServiceHandle< PileUpMergeSvc > m_mergeSvc
Definition: RpcDigitizationTool.h:213
RpcDigitizationTool::RpcDigitizationTool
RpcDigitizationTool(const std::string &type, const std::string &name, const IInterface *pIID)
Definition: RpcDigitizationTool.cxx:91
python.CreateTierZeroArgdict.pcs
pcs
Definition: CreateTierZeroArgdict.py:200
IGeoModelSvc::atlasVersion
virtual const std::string & atlasVersion() const =0
IGeoModelSvc.h
value_type
Definition: EDM_MasterSearch.h:11
PileUpTimeEventIndex
a struct encapsulating the identifier of a pile-up event
Definition: PileUpTimeEventIndex.h:12
RpcDigitizationTool::m_ClusterSize_BIS78_fromCOOL
Gaudi::Property< bool > m_ClusterSize_BIS78_fromCOOL
Definition: RpcDigitizationTool.h:242
Amg::distance
float distance(const Amg::Vector3D &p1, const Amg::Vector3D &p2)
calculates the distance between two point in 3D space
Definition: GeoPrimitivesHelpers.h:54
PileUpTimeEventIndex::type
PileUpType type() const
the pileup type - minbias, cavern, beam halo, signal?
Definition: PileUpTimeEventIndex.cxx:81
IdContext
class IdContext
Definition: IdContext.h:34
RpcDigitizationTool::m_outputSDO_CollectionKey
SG::WriteHandleKey< MuonSimDataCollection > m_outputSDO_CollectionKey
Definition: RpcDigitizationTool.h:220
RpcDigitizationTool::PackMCTruth
long long int PackMCTruth(float proptime, float tof, float posx, float posz) const
Definition: RpcDigitizationTool.cxx:994
RpcDigitizationTool::m_hitsContainerKey
SG::ReadHandleKey< RPCSimHitCollection > m_hitsContainerKey
Definition: RpcDigitizationTool.h:216
TimedHitCollection
Definition: TimedHitCollection.h:15
readCCLHist.float
float
Definition: readCCLHist.py:83
plot_times.times
def times(fn)
Definition: plot_times.py:11
MuonMCData
Definition: MuonSimData.h:42
RpcHitIdHelper::GetZSector
int GetZSector(const int &hid) const
Definition: RpcHitIdHelper.cxx:74
RpcDigitizationTool::m_MeanClusterSizeTail_A
Gaudi::Property< std::vector< double > > m_MeanClusterSizeTail_A
Definition: RpcDigitizationTool.h:194
fitman.k
k
Definition: fitman.py:528
RpcDigitizationTool::m_ClusterSize_fromCOOL
Gaudi::Property< bool > m_ClusterSize_fromCOOL
Definition: RpcDigitizationTool.h:235
generate::Zero
void Zero(TH1D *hin)
Definition: generate.cxx:32
Amg::getTranslate3D
Amg::Transform3D getTranslate3D(const double X, const double Y, const double Z)
: Returns a shift transformation along an arbitrary axis
Definition: GeoPrimitivesHelpers.h:289
RpcIdHelper::doubletPhi
int doubletPhi(const Identifier &id) const
Definition: RpcIdHelper.cxx:1064
RpcDigitizationTool::m_Efficiency_BIS78_fromCOOL
Gaudi::Property< bool > m_Efficiency_BIS78_fromCOOL
Definition: RpcDigitizationTool.h:241
RpcDigitizationTool::m_validationSetup
Gaudi::Property< bool > m_validationSetup
Definition: RpcDigitizationTool.h:172
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37
RpcReadoutElement.h
RPCSimHit::kineticEnergy
double kineticEnergy() const
Definition: RPCSimHit.h:62