22#include "GaudiKernel/SystemOfUnits.h"
23#include "GaudiKernel/PhysicalConstants.h"
25#include "GeoModelHelpers/TransformToStringConverter.h"
45#include "GeoModelKernel/throwExcept.h"
48#include "CLHEP/Random/RandExponential.h"
49#include "CLHEP/Random/RandFlat.h"
50#include "CLHEP/Random/RandGaussZiggurat.h"
66 constexpr int N_Charge = 12;
67 constexpr int N_Velocity = 15;
68 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};
69 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};
70 constexpr double Eff_garfield[N_Charge][N_Velocity] = {
71 {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},
72 {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},
73 {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},
74 {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},
75 {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},
76 {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},
77 {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},
78 {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},
79 {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},
80 {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},
81 {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},
82 {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}};
84 validIndex(
int idx,
int arraySize){
85 return (idx>=0) and (idx<arraySize);
91 constexpr double SIG_VEL = 4.8;
142 return StatusCode::FAILURE;
159 ATH_MSG_DEBUG(
"Ready to read parameters for cluster simulation from file");
177 return StatusCode::SUCCESS;
183 SmartIF<IGeoModelSvc> geoModel{Gaudi::svcLocator()->service(
"GeoModelSvc")};
186 return StatusCode::FAILURE;
190 std::string atlasVersion = geoModel->atlasVersion();
192 SmartIF<IRDBAccessSvc> rdbAccess{Gaudi::svcLocator()->service(
"RDBAccessSvc")};
195 return StatusCode::FAILURE;
201 std::string configVal =
"";
203 IRDBRecordset_ptr atlasCommonRec = rdbAccess->getRecordsetPtr(
"AtlasCommon", atlasVersion,
"ATLAS");
204 if (atlasCommonRec->
size() == 0) {
207 configVal = (*atlasCommonRec)[0]->getString(
"CONFIG");
208 ATH_MSG_INFO(
"From DD Database, Configuration is " << configVal);
209 if (configVal ==
"RUN1") {
211 }
else if (configVal ==
"RUN2") {
213 }
else if (configVal ==
"RUN3") {
215 }
else if (configVal ==
"RUN4") {
218 if (
run == DataPeriod::Unknown) {
219 ATH_MSG_FATAL(
"Unexpected value for geometry config read from the database: " << configVal);
220 return StatusCode::FAILURE;
227 ATH_MSG_INFO(
"From Geometry DB: MuonSpectrometer configuration is: RUN1 or MuonGeometry = R.06");
229 ATH_MSG_INFO(
"From Geometry DB: MuonSpectrometer configuration is: RUN2 or MuonGeometry = R.07");
230 else if (
run == Run3)
231 ATH_MSG_INFO(
"From Geometry DB: MuonSpectrometer configuration is: RUN3 or MuonGeometry = R.09");
232 else if (
run == Run4)
233 ATH_MSG_INFO(
"From Geometry DB: MuonSpectrometer configuration is: RUN4 or MuonGeometry = R.10");
246 if (configVal ==
"RUN1") {
265 ATH_MSG_INFO(
"Run3/4: configuration parameter not from COOL");
272 ATH_MSG_INFO(
"RPC Run1/2/3-dependent configuration is enforced");
274 ATH_MSG_WARNING(
"Run1/2/3-dependent configuration is bypassed; be careful with option settings");
285 return StatusCode::SUCCESS;
294 m_thpcRPC = std::make_unique<TimedHitCollection<RPCSimHit>>();
297 return StatusCode::SUCCESS;
305 TimedHitCollList hitCollList;
308 hitCollList.empty()) {
310 return StatusCode::FAILURE;
315 TimedHitCollList::iterator iColl(hitCollList.begin());
316 TimedHitCollList::iterator endColl(hitCollList.end());
319 for (; iColl != endColl; ++iColl) {
323 ATH_MSG_DEBUG(
"RPCSimHitCollection found with " << hitCollPtr->
size() <<
" hits");
326 m_thpcRPC->insert(timeIndex, hitCollPtr);
330 return StatusCode::SUCCESS;
347 if (!hitCollection.
isValid()) {
348 ATH_MSG_ERROR(
"Could not get RPCSimHitCollection container " << hitCollection.
name() <<
" from store "
349 << hitCollection.
store());
350 return StatusCode::FAILURE;
354 m_thpcRPC = std::make_unique<TimedHitCollection<RPCSimHit>>(1);
356 ATH_MSG_DEBUG(
"RPCSimHitCollection found with " << hitCollection->size() <<
" hits");
358 return StatusCode::SUCCESS;
361 TimedHitCollList hitCollList;
365 return StatusCode::FAILURE;
367 if (hitCollList.empty()) {
369 return StatusCode::FAILURE;
375 m_thpcRPC = std::make_unique<TimedHitCollection<RPCSimHit>>();
377 TimedHitCollList::iterator iColl(hitCollList.begin());
378 TimedHitCollList::iterator endColl(hitCollList.end());
379 while (iColl != endColl) {
381 m_thpcRPC->insert(iColl->first, p_collection);
386 return StatusCode::SUCCESS;
391 StatusCode status = StatusCode::SUCCESS;
401 ATH_CHECK(sdoContainer.
record(std::make_unique<MuonSimDataCollection>()));
410 if (status.isFailure()) {
ATH_MSG_ERROR(
"doDigitization Failed"); }
411 for (
size_t coll_hash = 0; coll_hash < collections.size(); ++coll_hash) {
412 if (collections[coll_hash]) {
413 ATH_CHECK( digitContainer->addCollection (collections[coll_hash].release(), coll_hash) );
425 StatusCode status = StatusCode::SUCCESS;
438 ATH_CHECK(sdoContainer.
record(std::make_unique<MuonSimDataCollection>()));
447 if (StatusCode::FAILURE == status) {
455 for (
size_t coll_hash = 0; coll_hash < collections.size(); ++coll_hash) {
456 if (collections[coll_hash]) {
457 ATH_CHECK( digitContainer->addCollection (collections[coll_hash].release(), coll_hash) );
469 rngWrapper->
setSeed(name(), ctx);
470 CLHEP::HepRandomEngine* rndmEngine = rngWrapper->
getEngine(ctx);
476 std::unique_ptr<RPCSimHitCollection> inputSimHitColl{std::make_unique<RPCSimHitCollection>(
"RPC_Hits")};
486 return StatusCode::FAILURE;
489 struct SimDataContent {
491 std::vector<MuonSimData::Deposit> deposits;
496 while (
m_thpcRPC->nextDetectorElement(i, e)) {
499 std::map<Identifier, SimDataContent> channelSimDataMap;
510 const int idHit =
hit.RPCid();
512 const double globalHitTime{
hitTime(phit)};
514 const double G4Time{
hit.globalTime()};
516 const double bunchTime{globalHitTime -
hit.globalTime()};
518 ATH_MSG_DEBUG(
"Global time " << globalHitTime <<
" G4 time " << G4Time <<
" Bunch time " << bunchTime);
521 ATH_MSG_VERBOSE(
"Validation: globalHitTime, G4Time, BCtime = " << globalHitTime <<
" " << G4Time <<
" " << bunchTime);
522 inputSimHitColl->Emplace(idHit, globalHitTime,
hit.localPosition(),
524 hit.postLocalPosition(),
525 hit.energyDeposit(),
hit.stepLength(),
hit.particleEncoding(),
hit.kineticEnergy());
529 const std::string stationName =
m_muonHelper->GetStationName(idHit);
531 const int stationPhi =
m_muonHelper->GetPhiSector(idHit);
534 const int doubletPhi =
m_muonHelper->GetDoubletPhi(idHit);
543 ATH_MSG_WARNING(
"Failed to construct the element ID from "<<stationName
544 <<
", stationEta: "<<stationEta<<
", stationPhi: "<<stationPhi<<
", doubletR: "<<doubletR);
549 <<
" stationName " << stationName <<
" stationEta " << stationEta <<
" stationPhi " << stationPhi <<
" doubletR "
550 << doubletR <<
" doubletZ " << doubletZ <<
" doubletPhi " << doubletPhi <<
" gasGap " << gasGap);
558 gasGap = gasGap == 1 ? 2 : 1;
562 bool isValidEta{
false}, isValidPhi{
false};
563 const Identifier idpaneleta =
m_idHelper->channelID(elementID, doubletZ, doubletPhi, gasGap, 0, 1, isValidEta);
564 const Identifier idpanelphi =
m_idHelper->channelID(elementID, doubletZ, doubletPhi, gasGap, 1, 1, isValidPhi);
565 if (!isValidEta || !isValidPhi) {
567 <<
" stationName " << stationName <<
" stationEta " << stationEta <<
" stationPhi " << stationPhi
568 <<
" doubletR " << doubletR <<
" doubletZ " << doubletZ <<
" doubletPhi " << doubletPhi <<
" gasGap "
577 const double corrtimejitter = tmp_CorrJitter > 0.01 ?
578 CLHEP::RandGaussZiggurat::shoot(rndmEngine, 0., tmp_CorrJitter) : 0.;
588 std::array<int, 3> pcseta =
physicalClusterSize(ctx, reEle, idpaneleta, gapCentre, rndmEngine);
589 ATH_MSG_VERBOSE(
"Simulated cluster on eta panel: size/first/last= " << pcseta[0] <<
"/" << pcseta[1] <<
"/" << pcseta[2]);
590 std::array<int, 3> pcsphi =
physicalClusterSize(ctx, reEle, idpanelphi, gapCentre, rndmEngine);
591 ATH_MSG_VERBOSE(
"Simulated cluster on phi panel: size/first/last= " << pcsphi[0] <<
"/" << pcsphi[1] <<
"/" << pcsphi[2]);
596 const Identifier atlasRpcIdeta =
m_idHelper->channelID(elementID, doubletZ, doubletPhi, gasGap, 0, pcseta[1], isValidEta);
597 const Identifier atlasRpcIdphi =
m_idHelper->channelID(elementID, doubletZ, doubletPhi, gasGap, 1, pcsphi[1], isValidPhi);
600 const auto [etaStripOn, phiStripOn] =
detectionEfficiency(ctx, idpaneleta, idpanelphi, rndmEngine, particleLink);
601 ATH_MSG_DEBUG(
"SetPhiOn " << phiStripOn <<
" SetEtaOn " << etaStripOn);
603 for (
bool imeasphi : {
false,
true}) {
604 if (!imeasphi && (!etaStripOn || !isValidEta))
continue;
605 if (imeasphi && (!phiStripOn || !isValidPhi))
continue;
609 const Identifier& atlasId = !imeasphi ? atlasRpcIdeta : atlasRpcIdphi;
610 std::array<int, 3> pcs{!imeasphi ? pcseta : pcsphi};
612 ATH_MSG_DEBUG(
"SetOn: stationName " << stationName <<
" stationEta " << stationEta <<
" stationPhi " << stationPhi
613 <<
" doubletR " << doubletR <<
" doubletZ " << doubletZ <<
" doubletPhi " << doubletPhi
614 <<
" gasGap " << gasGap <<
" measphi " << imeasphi);
622 ATH_MSG_DEBUG(
"Simulated cluster1: size/first/last= " << pcs[0] <<
"/" << pcs[1] <<
"/" << pcs[2]);
629 <<
" hit "<<
m_idHelper->print_to_string(atlasId)
641 double tns = G4Time + proptime + corrtimejitter;
642 ATH_MSG_VERBOSE(
"TOF+propagation time " << tns <<
" /s where proptime " << proptime <<
"/s");
644 double time = tns + bunchTime;
648 long long int packedMCword =
PackMCTruth(proptime, bunchTime, pos.y(), pos.z());
650 double* b =
reinterpret_cast<double*
>(&packedMCword);
661 if (std::abs(
hit.particleEncoding()) == 13 ||
hit.particleEncoding() == 0) {
662 if (channelSimDataMap.find(atlasId) == channelSimDataMap.end()) {
663 SimDataContent& content = channelSimDataMap[atlasId];
664 content.channelId = atlasId;
665 content.deposits.push_back(deposit);
666 content.gpos = reEle->
transform(atlasId)*
668 content.simTime =
hitTime(phit);
669 ATH_MSG_VERBOSE(
"adding SDO entry: r " << content.gpos.perp() <<
" z " << content.gpos.z());
681 for (
int clus = pcs[1]; clus <= pcs[2]; ++clus) {
682 Identifier newId =
m_idHelper->channelID(stationName, stationEta, stationPhi, doubletR, doubletZ,
683 doubletPhi, gasGap, imeasphi, clus,
isValid);
685 ATH_MSG_WARNING(__FILE__<<
":"<<__LINE__<<
"Channel "<< stationName<<
" "<<stationEta<<
" "<<stationPhi<<
" "<< doubletR<<
" "<<doubletZ
686 <<
" "<< doubletPhi<<
" "<< gasGap <<
" "<< imeasphi<<
" "<< clus<<
" is invalid");
691 if (stationName.find(
"BI") != std::string::npos) {
692 ATH_MSG_WARNING(
"Temporary skipping creation of RPC digit for stationName="
693 << stationName <<
", eta=" << stationEta <<
", phi=" << stationPhi <<
", doubletR=" << doubletR
694 <<
", doubletZ=" << doubletZ <<
", doubletPhi=" << doubletPhi <<
", gasGap=" << gasGap
695 <<
", measuresPhi=" << imeasphi <<
", strip=" << clus <<
", cf. ATLASRECTS-6124");
696 return StatusCode::SUCCESS;
700 return StatusCode::FAILURE;
709 std::vector<MuonSimData::Deposit> newdeps;
710 newdeps.push_back(deposit);
720 for (
auto it = channelSimDataMap.begin(); it != channelSimDataMap.end(); ++it) {
722 simData.setPosition(it->second.gpos);
723 simData.setTime(it->second.simTime);
724 auto insertResult = sdoContainer->insert(std::make_pair(it->first,
simData));
725 if (!insertResult.second)
726 ATH_MSG_WARNING(
"Attention: this sdo is not recorded, since the identifier already exists in the sdoContainer map");
742 const std::vector<MuonSimData::Deposit> theDeps = (*map_iter).second;
746 std::multimap<double, MuonSimData::Deposit> times;
749 for (
unsigned int k = 0; k < theDeps.size(); k++) {
750 double time = theDeps[k].second.secondEntry();
751 times.insert(std::multimap<double, MuonSimData::Deposit>::value_type(time, theDeps[k]));
758 std::multimap<double, MuonSimData::Deposit>::iterator map_dep_iter = times.begin();
761 double last_time = -10000;
762 for (; map_dep_iter != times.end(); ++map_dep_iter) {
763 double currTime = (*map_dep_iter).first;
769 if (sdoContainer->find(theId) != sdoContainer->end())
771 std::map<Identifier, MuonSimData>::const_iterator it = sdoContainer->find(theId);
772 std::vector<MuonSimData::Deposit> deps = ((*it).second).getdeposits();
773 deps.push_back((*map_dep_iter).second);
776 std::vector<MuonSimData::Deposit> deposits;
777 deposits.push_back((*map_dep_iter).second);
778 std::pair<std::map<Identifier, MuonSimData>::iterator,
bool> insertResult =
779 sdoContainer->insert(std::make_pair(theId,
MuonSimData(deposits, 0)));
780 if (!insertResult.second)
782 "Attention TEMP: this sdo is not recorded, since the identifier already exists in the sdoContainer map");
786 if (std::abs(currTime - last_time) > (
m_deadTime)) {
787 ATH_MSG_DEBUG(
"deposit with time " << currTime <<
" is distant enough from previous (if any) hit on teh same strip");
788 last_time = (*map_dep_iter).first;
791 double uncorrjitter = 0;
794 if (tmp_UncorrJitter > 0.01) uncorrjitter = CLHEP::RandGaussZiggurat::shoot(rndmEngine, 0., tmp_UncorrJitter);
804 double newDigit_time = currTime + uncorrjitter +
m_rpc_time_shift - tp - propTimeFromStripCenter;
806 double digi_ToT = -1.;
809 ATH_MSG_VERBOSE(
"last_time=currTime " << last_time <<
" jitter " << uncorrjitter <<
" TOFcorrection " << tp <<
" shift "
813 bool outsideDigitizationWindow =
outsideWindow(newDigit_time);
814 if (outsideDigitizationWindow) {
815 ATH_MSG_VERBOSE(
"hit outside digitization window - do not produce digits");
824 last_time = (*map_dep_iter).first;
826 std::unique_ptr<RpcDigit> newDigit = std::make_unique<RpcDigit>(theId, newDigit_time, digi_ToT,
false);
832 if (
m_idHelper->get_hash(elemId, coll_hash, &rpcContext)) {
833 ATH_MSG_ERROR(
"Unable to get RPC hash id from RPC Digit collection "
834 <<
"context begin_index = " << rpcContext.
begin_index()
835 <<
" context end_index = " << rpcContext.
end_index() <<
" the identifier is \n"<<elemId);
842 if (coll_hash >= collections.size()) {
843 collections.resize (coll_hash+1);
845 digitCollection = collections[coll_hash].
get();
846 if (!digitCollection) {
847 collections[coll_hash] = std::make_unique<RpcDigitCollection>(elemId, coll_hash);
848 digitCollection = collections[coll_hash].
get();
850 digitCollection->
push_back(std::move(newDigit));
854 if (sdoContainer->find(theId) != sdoContainer->end()) {
855 std::map<Identifier, MuonSimData>::const_iterator it = sdoContainer->find(theId);
856 std::vector<MuonSimData::Deposit> deps = ((*it).second).getdeposits();
857 deps.push_back((*map_dep_iter).second);
859 std::vector<MuonSimData::Deposit> deposits;
860 deposits.push_back((*map_dep_iter).second);
861 std::pair<std::map<Identifier, MuonSimData>::iterator,
bool> insertResult =
862 sdoContainer->insert(std::make_pair(theId,
MuonSimData(deposits, 0)));
863 if (!insertResult.second)
865 "Attention: this sdo is not recorded, since teh identifier already exists in the sdoContainer map");
870 ATH_MSG_DEBUG(
"discarding digit due to dead time: " << (*map_dep_iter).first <<
" " << last_time);
882 return StatusCode::SUCCESS;
899 (flip ?
Amg::getRotateY3D(180.*Gaudi::Units::deg) : Amg::Isometry3D::Identity())};
910 CLHEP::HepRandomEngine* rndmEngine)
const {
913 std::array<int, 3> result{};
917 const int doubletPhi =
m_idHelper->doubletPhi(
id);
919 const bool measuresPhi =
m_idHelper->measuresPhi(
id);
920 const double pitch= ele->
StripPitch(measuresPhi);
923 const int nstrip = ele->
stripNumber(position.block<2,1>(0,0),
id);
924 const int numStrips = ele->
Nstrips(measuresPhi);
929 if (nstrip < 1 || nstrip > numStrips) {
933 float xstripnorm = (locStripPos -position).
x() / pitch ;
946 std::array<int, 3>&& pcs,
954 }
else if (pcs[0] == 2) {
956 }
else if (pcs[0] > 2) {
957 pcs[1] = pcs[1] - pcs[0] / 2;
958 if (fmod(pcs[0], 2) == 0) pcs[1] = pcs[1] + 1;
959 pcs[2] = pcs[1] + pcs[0] - 1;
960 }
else if (pcs[0] < -2) {
961 pcs[1] = pcs[1] + pcs[0] / 2;
962 pcs[2] = pcs[1] - pcs[0] - 1;
967 pcs[1] = std::clamp(pcs[1], 1, nstrips);
968 pcs[2] = std::clamp(pcs[2], 1, nstrips);
970 pcs[0] = pcs[2] - pcs[1] + 1;
988 return std::abs(distance * SIG_VEL * 1.e-3);
995 ATH_MSG_WARNING(
"A poblem: packing a propagation time <0 " << proptime <<
" redefine it as 0");
998 long long int new_proptime = int(proptime * 10) & 0xff;
1004 long long int new_bctime = int((bctime + 300.) * 10.) & 0xffff;
1009 long long int new_posy = int((posy + 1500.) * 10.) & 0xffff;
1014 long long int new_posz = int((posz + 1500.) * 10.) & 0xffff;
1016 return (new_proptime + (new_bctime << 8) + (new_posy << 24) + (new_posz << 40));
1022 using Repacker =
union
1030 MCTruth.dWord = theWord;
1031 proptime = ((MCTruth.iWord) & 0x00000000000000ffLL) / 10.;
1032 bctime = (((MCTruth.iWord) & 0x0000000000ffff00LL) >> 8) / 10.;
1033 posy = (((MCTruth.iWord) & 0x000000ffff000000LL) >> 24) / 10.;
1034 posz = (((MCTruth.iWord) & 0x00ffff0000000000LL) >> 40) / 10.;
1037 bctime = bctime - 300.;
1038 posy = posy - 1500.;
1039 posz = posz - 1500.;
1045 SmartIF<ITagInfoMgr> tagInfoMgr{Gaudi::svcLocator()->service(
"TagInfoMgr")};
1046 if (!tagInfoMgr) {
return StatusCode::FAILURE; }
1048 std::string RpctimeSchema =
"";
1049 std::stringstream RpctimeShift;
1053 RpctimeSchema =
"Datalike_TOFoff_TimeShift" + RpctimeShift.str() +
"nsec";
1055 RpctimeSchema =
"G4like_TOFon_TimeShift" + RpctimeShift.str() +
"nsec";
1060 if (
sc.isFailure()) {
1067 return StatusCode::SUCCESS;
1075 CLHEP::HepRandomEngine* rndmEngine,
1080 ATH_MSG_DEBUG(
"RpcDigitizationTool::in DetectionEfficiency");
1088 float maxGeomEff{0.99}, PhiAndEtaEff{0.99}, OnlyEtaEff{0.f}, OnlyPhiEff{0.f};
1091 int stationName =
m_idHelper->stationName(IdEta);
1092 int stationEta =
m_idHelper->stationEta(IdEta);
1097 return std::make_pair(
false,
false);
1102 return std::make_pair(
true,
true);
1104 bool etaStripOn{
true}, phiStripOn{
true};
1109 unsigned int index = stationName - 2;
1111 if (stationName > 5 && stationName < 50)
index =
index - 2;
1113 else if (stationName > 50)
1119 THROW_EXCEPTION(
"Index out of array in Detection Efficiency SideA " <<
index <<
" stationName = " << stationName);
1126 if (stationEta < 0) {
1128 THROW_EXCEPTION(
"Index out of array in Detection Efficiency SideC " <<
index <<
" stationName = " << stationName);
1145 ATH_MSG_DEBUG(
"Efficiencies and cluster size + dead strips will be extracted from COOL");
1147 double FracDeadStripEta{0.}, FracDeadStripPhi{0.};
1148 double EtaPanelEfficiency{1.}, PhiPanelEfficiency{1.}, GapEfficiency{1.};
1149 int RPC_ProjectedTracksEta = 0;
1151 std::optional<double> fracDeadStripEtaFromCOOL = readCdo->
getFracDeadStrip(IdEta);
1152 std::optional<double> fracDeadStripPhiFromCOOL = readCdo->
getFracDeadStrip(IdPhi);
1154 bool noEntryInDb = !fracDeadStripEtaFromCOOL || !fracDeadStripPhiFromCOOL;
1156 FracDeadStripEta = fracDeadStripEtaFromCOOL.value_or(0.);
1157 FracDeadStripPhi = fracDeadStripPhiFromCOOL.value_or(0.);
1160 EtaPanelEfficiency = readCdo->
getEfficiency(IdEta).value_or(1.);
1161 PhiPanelEfficiency = readCdo->
getEfficiency(IdPhi).value_or(1.);
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
1171 FracDeadStripPhi = 0.;
1172 ATH_MSG_VERBOSE(
"Watch out: SPECIAL CASE: Resetting FracDeadStripPhi " << FracDeadStripPhi <<
" ignoring phi dead strips ");
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);
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");
1190 EtaPanelEfficiency = maxGeomEff - FracDeadStripEta;
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");
1199 PhiPanelEfficiency = maxGeomEff - FracDeadStripPhi;
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 "
1207 ATH_MSG_DEBUG(
"... see the corresponding report among the warnings of RpcDetectorStatusDbTool");
1209 GapEfficiency = maxGeomEff - FracDeadStripEta * FracDeadStripPhi;
1213 ATH_MSG_DEBUG(
"Rinormalized Values from Cool: FracDeadStripEta/Phi "
1214 << FracDeadStripEta <<
"/" << FracDeadStripPhi <<
" RPC_ProjectedTracksEta " << RPC_ProjectedTracksEta
1215 <<
" Eta/PhiPanelEfficiency " << EtaPanelEfficiency <<
"/" << PhiPanelEfficiency <<
" gapEff " << GapEfficiency);
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);
1224 if (EtaPanelEfficiency > maxGeomEff) EtaPanelEfficiency = maxGeomEff;
1225 if (PhiPanelEfficiency > maxGeomEff) PhiPanelEfficiency = maxGeomEff;
1226 if (GapEfficiency > maxGeomEff) GapEfficiency = maxGeomEff;
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 "
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.;
1246 bool applySpecialPatch =
false;
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 "
1257 "Applying special patch: THIS HAS TO BE DONE IF /RPC/DQMF/ELEMENT_STATUS tag is "
1258 "RPCDQMFElementStatus_2012_Jaunuary_2");
1264 if (applySpecialPatch || RPC_ProjectedTracksEta < m_CutProjectedTracks || RPC_ProjectedTracksEta > 10000000 ||
1265 EtaPanelEfficiency > 1 || EtaPanelEfficiency < 0 || PhiPanelEfficiency > 1 || PhiPanelEfficiency < 0 || GapEfficiency > 1 ||
1266 GapEfficiency < 0) {
1268 THROW_EXCEPTION(
"Index out of array in Detection Efficiency SideA COOLDB" <<
index <<
" stationName = " << stationName);
1272 <<
" resetting eff. from cool with default(python) values ");
1278 if (stationEta < 0) {
1280 THROW_EXCEPTION(
"Index out of array in Detection Efficiency SideC COOLDB" <<
index <<
" stationName = " << stationName);
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;
1297 if (s_OnlyEtaEff < OnlyEtaEff) OnlyEtaEff = s_OnlyEtaEff;
1298 if (s_OnlyPhiEff < OnlyPhiEff) OnlyPhiEff = s_OnlyPhiEff;
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;
1319 PhiAndEtaEff = PhiAndEtaEff * eff_sf;
1320 OnlyEtaEff = OnlyEtaEff * eff_sf;
1321 OnlyPhiEff = OnlyPhiEff * eff_sf;
1325 float I0 = PhiAndEtaEff;
1326 float I1 = PhiAndEtaEff + OnlyEtaEff;
1327 float ITot = PhiAndEtaEff + OnlyEtaEff + OnlyPhiEff;
1329 float GapEff = ITot ;
1330 float PhiEff = PhiAndEtaEff + OnlyPhiEff;
1331 float EtaEff = PhiAndEtaEff + OnlyEtaEff;
1333 ATH_MSG_DEBUG(
"DetectionEfficiency: Final Efficiency Values applied for "
1334 <<
m_idHelper->show_to_string(IdEta) <<
" are " << PhiAndEtaEff <<
"=PhiAndEtaEff " << OnlyEtaEff
1335 <<
"=OnlyEtaEff " << OnlyPhiEff <<
"=OnlyPhiEff " << GapEff <<
"=GapEff " << EtaEff <<
"=EtaEff " << PhiEff
1338 float rndmEff = CLHEP::RandFlat::shoot(rndmEngine, 1);
1343 }
else if ((I0 <= rndmEff) && (rndmEff < I1)) {
1346 }
else if ((I1 <= rndmEff) && (rndmEff <= ITot)) {
1354 return std::make_pair(etaStripOn, phiStripOn);
1361 CLHEP::HepRandomEngine* rndmEngine)
const {
1362 ATH_MSG_DEBUG(
"RpcDigitizationTool::in determineClusterSize");
1366 int ClusterSize = 1;
1368 double FracClusterSize1{1.}, FracClusterSize2{0.}, MeanClusterSize{1.},
1369 FracClusterSizeTail{0.}, MeanClusterSizeTail{1.},
1370 FracClusterSize2norm{0.};
1373 int stationName =
m_idHelper->stationName(idRpcStrip);
1374 int stationEta =
m_idHelper->stationEta(idRpcStrip);
1375 int measuresPhi =
m_idHelper->measuresPhi(idRpcStrip);
1377 unsigned int index = stationName - 2;
1379 if (stationName > 5 && stationName < 50)
index =
index - 2;
1381 else if (stationName > 50)
1391 ATH_MSG_ERROR(
"Index out of array in determineClusterSize SideA " <<
index <<
" statName " << stationName);
1399 if (stationEta < 0) {
1405 ATH_MSG_ERROR(
"Index out of array in determineClusterSize SideC " <<
index <<
" statName " << stationName);
1430 ATH_MSG_DEBUG(
"FracClusterSize1 and 2 " << FracClusterSize1 <<
" " << FracClusterSize2);
1432 FracClusterSizeTail = 1. - FracClusterSize1 - FracClusterSize2;
1434 MeanClusterSizeTail = MeanClusterSize - FracClusterSize1 - 2 * FracClusterSize2;
1436 ATH_MSG_DEBUG(
"MeanClusterSizeTail and FracClusterSizeTail " << MeanClusterSizeTail <<
" " << FracClusterSizeTail);
1439 if (RPC_ProjectedTracks < m_CutProjectedTracks || RPC_ProjectedTracks > 10000000 || MeanClusterSize >
m_CutMaxClusterSize ||
1440 MeanClusterSize <= 1 || FracClusterSizeTail < 0 || FracClusterSize1 < 0 || FracClusterSize2 < 0 || FracClusterSizeTail > 1 ||
1441 FracClusterSize1 > 1 || FracClusterSize2 > 1) {
1442 if (stationName >= 2) {
1448 ATH_MSG_ERROR(
"Index out of array in determineClusterSize SideA " <<
index <<
" statName " << stationName);
1456 if (stationEta < 0) {
1460 ATH_MSG_ERROR(
"Index out of array in determineClusterSize SideC " <<
index <<
" statName " << stationName);
1477 FracClusterSize1 = std::min(FracClusterSize1, 1.);
1478 FracClusterSize2 = std::min(FracClusterSize2, 1.);
1479 FracClusterSizeTail = std::min(FracClusterSizeTail, 1.);
1480 float FracTot = FracClusterSize1 + FracClusterSize2 + FracClusterSizeTail;
1481 if (FracTot != 1. && FracTot > 0) {
1482 FracClusterSize1 = FracClusterSize1 / FracTot;
1483 FracClusterSize2 = FracClusterSize2 / FracTot;
1484 FracClusterSizeTail = FracClusterSizeTail / FracTot;
1486 if (MeanClusterSizeTail < 0 || MeanClusterSizeTail > 10) MeanClusterSizeTail = 1;
1488 ATH_MSG_VERBOSE(
"ClusterSize Final " << FracClusterSize1 <<
" FracClusterSize1 " << FracClusterSize2 <<
" FracClusterSize2 "
1489 << FracClusterSizeTail <<
" " << FracClusterSizeTail <<
" MeanClusterSizeTail "
1490 << MeanClusterSizeTail);
1492 float FracClusterSize1plus2 = FracClusterSize1 + FracClusterSize2;
1493 float ITot = FracClusterSize1 + FracClusterSize2 + FracClusterSizeTail;
1495 if (FracClusterSize1plus2 != 0) {
1497 FracClusterSize2norm = FracClusterSize2 / FracClusterSize1plus2;
1500 float rndmCS = CLHEP::RandFlat::shoot(rndmEngine, ITot);
1502 if (stationName >= 2) {
1504 if (rndmCS < FracClusterSize1plus2) {
1506 if (xstripnorm <= FracClusterSize2norm / 2. * 1.3) {
1508 }
else if ((1.0 - FracClusterSize2norm / 2. * 1.3) <= xstripnorm) {
1514 float rndmCS1_2 = CLHEP::RandFlat::shoot(rndmEngine, 1);
1515 ClusterSize = 1 + (rndmCS1_2 < FracClusterSize2norm);
1518 }
else if ((FracClusterSize1plus2 <= rndmCS) && (rndmCS <= ITot)) {
1520 ClusterSize += int(CLHEP::RandExponential::shoot(rndmEngine, MeanClusterSizeTail));
1521 float rndmLR = CLHEP::RandFlat::shoot(rndmEngine, 1.0);
1522 if (rndmLR > 0.5) ClusterSize = -ClusterSize;
1528 if (rndmCS < FracClusterSize1) {
1530 }
else if (rndmCS < FracClusterSize1 + FracClusterSize2) {
1533 ClusterSize = int(CLHEP::RandExponential::shoot(rndmEngine, MeanClusterSizeTail));
1535 ClusterSize = std::max(ClusterSize, 1);
1536 if (ClusterSize > 1) {
1537 float rndmLR = CLHEP::RandFlat::shoot(rndmEngine, 1.0);
1538 if (rndmLR > 0.5) ClusterSize = -ClusterSize;
1546 double qcharge = 1.;
1547 const int particlePdgId = genParticle->pdg_id();
1549 qcharge = (
static_cast<double>((std::abs(particlePdgId) / 1000) % 100)) / (
static_cast<double>((std::abs(particlePdgId) / 10) % 100));
1550 qcharge = ((
static_cast<double>((
static_cast<int>(qcharge * 100))))) / 100;
1551 if (particlePdgId < 0.0) qcharge = -qcharge;
1553 const double QPx = genParticle->momentum().px();
1554 const double QPy = genParticle->momentum().py();
1555 const double QPz = genParticle->momentum().pz();
1556 const double QE = genParticle->momentum().e();
1557 const double QM2 = std::pow(QE, 2) - std::pow(QPx, 2) - std::pow(QPy, 2) - std::pow(QPz, 2);
1558 const double QP = std::hypot(QPx, QPy, QPz);
1559 const double QM = QM2 >=0 ? std::sqrt(QM2) : -1.;
1561 const double qbetagamma = QM > 0. ? QP / QM : -1.;
1565 for (
int i = 0; i < 12; i++) {
1566 if (Charge[i] == std::abs(qcharge)) {
1571 int i_v = -99, j_v = 99;
1572 if (qbetagamma != -1) {
1573 for (
int i = 0; i < 15; i++) {
1574 if (Velocity[i] <= qbetagamma) { i_v = i; }
1576 for (
int i = 14; i >= 0; i--) {
1577 if (Velocity[i] >= qbetagamma) { j_v = i; }
1582 double eff_fcp = 1.0, eff_muon = 1.0;
1583 if (i_e >= 0 && i_e <= 11) {
1584 if (validIndex(j_v, N_Velocity) && validIndex(i_v, N_Velocity) && (j_v - i_v) == 1) {
1585 const double delta_v = Velocity[i_v] - Velocity[j_v];
1586 eff_fcp = (Eff_garfield[i_e][i_v] - Eff_garfield[i_e][j_v]) / delta_v * qbetagamma +
1587 (Eff_garfield[i_e][j_v] * Velocity[i_v] - Eff_garfield[i_e][i_v] * Velocity[j_v]) / delta_v;
1588 eff_muon = (Eff_garfield[11][i_v] - Eff_garfield[11][j_v]) / delta_v * qbetagamma +
1589 (Eff_garfield[11][j_v] * Velocity[i_v] - Eff_garfield[11][i_v] * Velocity[j_v]) / delta_v;
1590 }
else if (i_v == 14 && j_v == 99) {
1591 eff_fcp = Eff_garfield[i_e][14];
1592 eff_muon = Eff_garfield[11][14];
1593 }
else if (i_v == -99 && j_v == 0) {
1594 eff_fcp = Eff_garfield[i_e][0];
1595 eff_muon = Eff_garfield[11][0];
1597 ATH_MSG_WARNING(
"Wrong particle with unknown velocity! Scale factor is set to be 1.");
1600 ATH_MSG_WARNING(
"Wrong particle with unknown charge! Scale factor is set to be 1.");
1603 const double eff_SF = eff_fcp / eff_muon;
1610 constexpr double tot_mean_narrow = 16.;
1611 constexpr double tot_sigma_narrow = 2.;
1612 constexpr double tot_mean_wide = 15.;
1613 constexpr double tot_sigma_wide = 4.5;
1617 if (CLHEP::RandFlat::shoot(rndmEngine)<0.75) {
1618 thetot = CLHEP::RandGaussZiggurat::shoot(rndmEngine, tot_mean_narrow, tot_sigma_narrow);
1620 thetot = CLHEP::RandGaussZiggurat::shoot(rndmEngine, tot_mean_wide, tot_sigma_wide);
1623 return (thetot > 0.) ? thetot : 0.;
float hitTime(const AFP_SIDSimHit &hit)
constexpr std::array< T, N > make_array(const T &def_val)
Helper function to initialize in-place arrays with non-zero values.
#define ATH_CHECK
Evaluate an expression and check for errors.
bool isValid() const
Test to see if the link can be dereferenced.
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_ERROR(x,...)
#define ATH_MSG_WARNING(x,...)
#define ATH_MSG_VERBOSE(x,...)
#define ATH_MSG_INFO(x,...)
#define ATH_MSG_FATAL(x,...)
ATLAS-specific HepMC functions.
Definition of the abstract IRDBAccessSvc interface.
std::shared_ptr< IRDBRecordset > IRDBRecordset_ptr
Definition of the abstract IRDBRecord interface.
Definition of the abstract IRDBRecordset interface.
AtlasHitsVector< RPCSimHit > RPCSimHitCollection
struct TBPatternUnitContext Unknown
A wrapper class for event-slot-local random engines.
void setSeed(const std::string &algName, const EventContext &ctx)
Set the random seed using a string (e.g.
CLHEP::HepRandomEngine * getEngine(const EventContext &ctx) const
Retrieve the random engine corresponding to the provided EventContext.
const T * get(size_type n) const
Access an element, as an rvalue.
value_type push_back(value_type pElem)
Add an element to the end of the collection.
a link optimized in size for a GenParticle in a McEventCollection
HepMC::ConstGenParticlePtr cptr() const
Dereference.
static HepMcParticleLink getRedirectedLink(const HepMcParticleLink &particleLink, uint32_t eventIndex, const EventContext &ctx)
Return a HepMcParticleLink pointing at the same particle, but in a different GenEvent.
virtual unsigned int size() const =0
This class saves the "context" of an expanded identifier (ExpandedIdentifier) for compact or hash ver...
size_type begin_index() const
size_type end_index() const
value_type get_compact() const
Get the compact id.
This is a "hash" representation of an Identifier.
Identifier32 get_identifier32() const
Get the 32-bit version Identifier, will be invalid if >32 bits needed.
virtual const Amg::Transform3D & transform() const override
Return local to global transform.
The MuonDetectorManager stores the transient representation of the Muon Spectrometer geometry and pro...
const RpcReadoutElement * getRpcReadoutElement(const Identifier &id) const
access via extended identifier (requires unpacking)
const Amg::Transform3D & absTransform() const
An RpcReadoutElement corresponds to a single RPC module; therefore typicaly a barrel muon station con...
bool rotatedRpcModule() const
int nGasGapPerLay() const
returns the number of gasgaps
int NphiStripPanels() const
returns the number of phi strip panels (1 or 2)
double distanceToEtaReadout(const Amg::Vector3D &P) const
virtual int stripNumber(const Amg::Vector2D &pos, const Identifier &id) const override final
strip number corresponding to local position.
Amg::Vector3D localGasGapPos(const Identifier &id) const
Returns the position of the gasGap w.r.t. rest frame of the chamber.
Amg::Vector3D stripPos(const Identifier &id) const
double distanceToPhiReadout(const Amg::Vector3D &P) const
Amg::Transform3D localToGlobalTransf(const Identifier &id) const
int Nstrips(bool measphi) const
returns the number of strips for the phi or eta plane
virtual int numberOfLayers(bool measphi=true) const override final
number of layers in phi/eta projection, same for eta/phi planes
double StripPitch(bool measphi) const
returns the strip pitch for the phi or eta plane
std::pair< HepMcParticleLink, MuonMCData > Deposit
std::optional< double > getFracClusterSize2(const Identifier &) const
std::optional< int > getProjectedTrack(const Identifier &) const
std::optional< double > getFracDeadStrip(const Identifier &) const
std::optional< double > getFracClusterSize1(const Identifier &) const
std::optional< double > getGapEfficiency(const Identifier &) const
std::optional< double > getEfficiency(const Identifier &) const
std::optional< double > getMeanClusterSize(const Identifier &) const
static const RpcHitIdHelper * GetHelper(unsigned int nGasGaps=2)
virtual bool isValid() override final
Can the handle be successfully dereferenced?
const_pointer_type cptr()
Dereference the pointer.
std::string store() const
Return the name of the store holding the object we are proxying.
const std::string & name() const
Return the StoreGate ID for the referenced object.
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
pointer_type ptr()
Dereference the pointer.
TimedVector::const_iterator const_iterator
a smart pointer to a hit that also provides access to the extended timing info of the host event.
unsigned short eventId() const
the index of the component event in PileUpEventInfo.
std::optional< double > intersect(const AmgVector(N)&posA, const AmgVector(N)&dirA, const AmgVector(N)&posB, const AmgVector(N)&dirB)
Calculates the point B' along the line B that's closest to a second line A.
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
Amg::Isometry3D getTranslate3D(const double X, const double Y, const double Z)
: Returns a shift transformation along an arbitrary axis
Eigen::Affine3d Transform3D
Eigen::Matrix< double, 3, 1 > Vector3D
Amg::Isometry3D getRotateY3D(double angle)
Rotate the coordinate system by an angle around the z-axis.
HepMC3::ConstGenParticlePtr ConstGenParticlePtr
bool ignoreTruthLink(const T &p, bool vetoPileUp)
Helper function for SDO creation in PileUpTools.
bool isGenericMultichargedParticle(const T &p)
In addition, there is a need to identify ”Q-ball” and similar very exotic (multi-charged) particles w...
Ensure that the Athena extensions are properly loaded.
USAGE: openCoraCool.exe "COOLONL_SCT/COMP200".
const T * get(const ReadCondHandleKey< T > &key, const EventContext &ctx)
Convenience function to retrieve an object given a ReadCondHandleKey.
std::list< value_t > type
type of the collection of timed data object
a struct encapsulating the identifier of a pile-up event
index_type index() const
the index of the component event in PileUpEventInfo
PileUpType type() const
the pileup type - minbias, cavern, beam halo, signal?
time_type time() const
bunch xing time in ns
#define THROW_EXCEPTION(MESSAGE)
Tell the compiler to optimize assuming that FP may trap.
#define CXXUTILS_TRAPPING_FP
int run(int argc, char *argv[])