ATLAS Offline Software
L0MuonSmearingAlg.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #include "L0MuonSmearingAlg.h"
6 
8 
9 #include "TruthTrackSmearer.h"
10 
11 #include "TH1.h"
12 
13 namespace L0Muon {
14 
15 L0MuonSmearingAlg::L0MuonSmearingAlg(const std::string& name, ISvcLocator* pSvcLocator)
16 : AthReentrantAlgorithm(name, pSvcLocator) {}
17 
18 
20 
21 
23  ATH_MSG_INFO("Initializing " << name() << "...");
24 
26  ATH_CHECK(m_outputMuonRoIKey.initialize());
27 
28  ATH_CHECK(m_rndmSvc.retrieve());
29 
30  ATH_MSG_INFO("########## L0MuonSmearingAlg Configurations are ########## ");
31  ATH_MSG_INFO("------- InputTruthParticleKey: " << m_inputTruthParticleKey.key());
32  ATH_MSG_INFO("------- OutputMuonRoIKey: "<< m_outputMuonRoIKey.key());
33  ATH_MSG_INFO("########## L0MuonSmearingAlg Configurations: That's it. ########## ");
34 
35  // configure the Smearer
36  ATHRNG::RNGWrapper* rngWrapper = m_rndmSvc->getEngine(this);
37  m_mySmearer = std::make_unique<TruthTrackSmearer>(rngWrapper);
38 
39  if (!m_monTool.empty()) ATH_CHECK(m_monTool.retrieve());
40  return StatusCode::SUCCESS;
41 }
42 
43 
45  ATH_MSG_INFO ("Finalizing " << name() << "...");
46  return StatusCode::SUCCESS;
47 }
48 
49 
50 StatusCode L0MuonSmearingAlg::execute(const EventContext& ctx) const {
51  ATH_MSG_DEBUG ("Executing " << name() << "...");
52 
54  const xAOD::TruthParticleContainer* inputTruth = inputTruth_handle.cptr();
55  if (not inputTruth) {
56  ATH_MSG_FATAL("Unable to retrieve input truth particle of " << m_inputTruthParticleKey.key());
57  return StatusCode::FAILURE;
58  }
59 
61  ATH_CHECK(outputRoI_handle.record(std::make_unique<xAOD::MuonRoIContainer>(), std::make_unique<xAOD::MuonRoIAuxContainer>()));
62  auto outputRoIs = outputRoI_handle.ptr();
63 
64  int n_input_tracks=0;
65  int n_output_tracks=0;
66  ATH_MSG_DEBUG("Found " << inputTruth->size() << " input truth particles of " << m_inputTruthParticleKey.key());
67 
68  for (const auto* part : *inputTruth) {
69  // only muon is used
70  if (part->pdgId() != 13 && part->pdgId() != -13) continue;
71  // Minimum pT cut for 2 GeV
72  if (part->pt() < 2000.) continue; // MeV
73  // only undecayed physical particle
74  if (part->status() != 1) continue;
75  // eta within 3.0
76  if (std::abs(part->eta()) > 3.0) continue;
77 
78  ATH_MSG_DEBUG("New Truth Muon: phi=" << part->phi()
79  << " eta=" << part->eta()
80  << " pT=" << part->pt() / 1000.
81  << "(GeV) q/pT=" << part->charge() * 1000. / part->pt()
82  << "(1/GeV) PDGID=" << part->pdgId()
83  << " status=" << part->status());
84  n_input_tracks++;
85 
86  if (!m_monTool.empty()) {
87  auto track_input_eta = Monitored::Scalar<float>("track_input_eta", part->eta());
88  auto track_input_pt = Monitored::Scalar<float>("track_input_pt", part->pt() / 1000.);
89  auto track_input_phi = Monitored::Scalar<float>("track_input_phi", part->phi());
90  auto track_input_curv = Monitored::Scalar<float>("track_input_curv", part->charge() * 1000. / part->pt());
91  auto monitorIt = Monitored::Group(m_monTool, track_input_eta, track_input_pt, track_input_phi, track_input_curv);
92  }
93 
94  float qoverPt = part->charge() / part->pt(); // in MeV
95  L0MuonTrack otrack;
96  if (m_mySmearer->emulateL0MuonTrack(qoverPt, part->eta(), part->phi(), otrack) == false) { // smearing here
97  ATH_MSG_DEBUG("Killed by the efficiency: q/pt=" << qoverPt * 1000. << " (1/GeV)");
98  continue; // false means the truth muon is killed by the emulated efficiency
99  }
100 
101  n_output_tracks++;
102 
103  ATH_MSG_DEBUG("L0Muon Track: phi=" << otrack.phi()
104  << " eta=" << otrack.eta()
105  << " pT=" << 1. / std::abs(otrack.invpt() * 1000.)
106  << "(GeV) q/pT=" << 1000. * otrack.invpt() << "(1/GeV)");
107 
108  if (!m_monTool.empty()) {
109  auto track_output_eta = Monitored::Scalar<float>("track_output_eta", otrack.eta());
110  auto track_output_pt = Monitored::Scalar<float>("track_output_pt", 1./ std::abs(otrack.invpt() * 1000.));
111  auto track_output_phi = Monitored::Scalar<float>("track_output_phi", otrack.phi());
112  auto track_output_curv = Monitored::Scalar<float>("track_output_curv", otrack.invpt() * 1000.);
113  auto monitorIt = Monitored::Group(m_monTool, track_output_eta, track_output_pt, track_output_phi, track_output_curv);
114  }
115 
116  // RoI creation
117  outputRoIs->push_back(std::make_unique<xAOD::MuonRoI>());
118 
119  // To fill RoI contents, below converts from floating to bit-wise values.
120  static constexpr float PHI_ROISIZE = TMath::TwoPi() / static_cast<float>(xAOD::MuonRoI::PHI_MASK); // phi divided by 9 bits
121  static constexpr float ETA_ROISIZE = 5.4 / static_cast<float>(xAOD::MuonRoI::ETA_MASK); // eta divided by 14 bits
122  static constexpr float PT_ROISIZE = 127.5 / static_cast<float>(xAOD::MuonRoI::PT_MASK); // 0.5 GeV width for 0-128 GeV (8 bits)
123 
124  uint32_t phiword = uint32_t((otrack.phi()+TMath::Pi()) / PHI_ROISIZE); // phi defined from 0 to 2pi in MuonRoI, instead of -pi to pi
125  uint32_t etaword = uint32_t((otrack.eta() + 2.7) / ETA_ROISIZE); // -2.7 to 2.7 in MuonRoI.
126  uint32_t ptword = static_cast<uint32_t>(1. / std::abs(otrack.invpt() * 1000.) / PT_ROISIZE);
127  if (ptword > 0xff) ptword = 0xff;
128 
129  // to still input eta and phi for initialize, not calculated from RoIword
130  float roi_eta = etaword * ETA_ROISIZE - 2.7;
131  float roi_phi = phiword * PHI_ROISIZE - TMath::Pi();
132 
133  // construct roiWord (23th bit is charge information.)
134  uint32_t roiword = (ptword<<24) | ((otrack.invpt() > 0)<<23) | (phiword<<14) | etaword;
135 
136  std::string emu_thr_name = "L0_MUx";
137  float thrvalue = 0.0;
138  outputRoIs->back()->initialize(roiword, roi_eta, roi_phi, emu_thr_name, thrvalue, 0x1); // TODO: roiExtraWord is 1 for the time being
139 
140  ATH_MSG_DEBUG("L0MuonRoI: phi = " << roi_phi << " (0x" << std::hex << phiword << std::dec << "), "
141  << "eta = " << roi_eta << " (0x" << std::hex << etaword << std::dec << "), "
142  << "pT = " << outputRoIs->back()->pt() << " (GeV) (0x" << std::hex << ptword << std::dec << "), "
143  << "q/pT= " << ((otrack.invpt() > 0) ? 1. : -1.) / outputRoIs->back()->pt());
144 
145  if (!m_monTool.empty()) {
146  auto roi_output_eta = Monitored::Scalar<float>("roi_output_eta", outputRoIs->back()->eta());
147  auto roi_output_phi = Monitored::Scalar<float>("roi_output_phi", outputRoIs->back()->phi());
148  auto roi_output_pt = Monitored::Scalar<float>("roi_output_pt", outputRoIs->back()->pt());
149  auto roi_output_curv = Monitored::Scalar<float>("roi_output_curv", (outputRoIs->back()->getCharge() > 0 ? 1. : -1.)/outputRoIs->back()->pt());
150 
151  auto delta_eta = Monitored::Scalar<float>("delta_eta", outputRoIs->back()->eta() - part->eta());
152  auto delta_phi = Monitored::Scalar<float>("delta_phi", TVector2::Phi_mpi_pi(outputRoIs->back()->phi() - (part->phi())));
153  auto delta_pt = Monitored::Scalar<float>("delta_pt", (outputRoIs->back()->pt() - part->pt()/1000.) / (part->pt()/1000.));
154  auto delta_curv = Monitored::Scalar<float>("delta_curv", ((outputRoIs->back()->getCharge() == 1 ? 1. : -1.)/outputRoIs->back()->pt() - (part->charge()*1000./part->pt())) / (part->charge()*1000./part->pt()));
155 
156  auto monitorIt = Monitored::Group(m_monTool, roi_output_eta, roi_output_pt, roi_output_phi, roi_output_curv,
157  delta_eta, delta_phi, delta_pt, delta_curv);
158  }
159  }
160 
161  ATH_MSG_DEBUG ("Result: Number of input truth muons= " << n_input_tracks << " , smeared tracks= "<< n_output_tracks);
162 
163  return StatusCode::SUCCESS;
164 }
165 
166 
167 } // end of namespace
LArG4FSStartPointFilter.part
part
Definition: LArG4FSStartPointFilter.py:21
L0Muon::L0MuonTrack
Definition: L0MuonTrack.h:11
plotBeamSpotCompare.x1
x1
Definition: plotBeamSpotCompare.py:216
xAOD::MuonRoI_v1::ETA_MASK
static constexpr uint32_t ETA_MASK
constants to decode RoI word for Run 4+
Definition: MuonRoI_v1.h:147
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
TrigDefs::Group
Group
Properties of a chain group.
Definition: GroupProperties.h:13
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
SG::ReadHandle::cptr
const_pointer_type cptr()
Dereference the pointer.
xAOD::uint32_t
setEventNumber uint32_t
Definition: EventInfo_v1.cxx:127
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:70
MuonRoIAuxContainer.h
SG::VarHandleKey::key
const std::string & key() const
Return the StoreGate ID for the referenced object.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:141
L0Muon::L0MuonSmearingAlg::m_monTool
ToolHandle< GenericMonitoringTool > m_monTool
Definition: L0MuonSmearingAlg.h:34
Phi_mpi_pi
__HOSTDEV__ double Phi_mpi_pi(double)
Definition: GeoRegion.cxx:7
L0Muon::L0MuonSmearingAlg::L0MuonSmearingAlg
L0MuonSmearingAlg(const std::string &name, ISvcLocator *pSvcLocator)
Definition: L0MuonSmearingAlg.cxx:15
AthReentrantAlgorithm
An algorithm that can be simultaneously executed in multiple threads.
Definition: AthReentrantAlgorithm.h:83
L0Muon::L0MuonSmearingAlg::m_inputTruthParticleKey
SG::ReadHandleKey< xAOD::TruthParticleContainer > m_inputTruthParticleKey
Definition: L0MuonSmearingAlg.h:28
xAOD::MuonRoI_v1::PT_MASK
static constexpr uint32_t PT_MASK
Definition: MuonRoI_v1.h:149
L0Muon
Definition: L0MuonSmearingAlg.cxx:13
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
L0MuonSmearingAlg.h
xAOD::MuonRoI_v1::PHI_MASK
static constexpr uint32_t PHI_MASK
Definition: MuonRoI_v1.h:148
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
L0Muon::L0MuonSmearingAlg::m_rndmSvc
ServiceHandle< IAthRNGSvc > m_rndmSvc
Random number generator engine.
Definition: L0MuonSmearingAlg.h:35
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
L0Muon::L0MuonSmearingAlg::~L0MuonSmearingAlg
virtual ~L0MuonSmearingAlg()
Definition: L0MuonSmearingAlg.cxx:19
L0Muon::L0MuonTrack::eta
float eta() const
Definition: L0MuonTrack.h:19
DataVector
Derived DataVector<T>.
Definition: DataVector.h:794
L0Muon::L0MuonSmearingAlg::execute
virtual StatusCode execute(const EventContext &ctx) const override
Definition: L0MuonSmearingAlg.cxx:50
L0Muon::L0MuonSmearingAlg::m_mySmearer
std::unique_ptr< TruthTrackSmearer > m_mySmearer
Definition: L0MuonSmearingAlg.h:37
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
ATHRNG::RNGWrapper
A wrapper class for event-slot-local random engines.
Definition: RNGWrapper.h:56
L0Muon::L0MuonTrack::invpt
double invpt() const
Definition: L0MuonTrack.h:18
SG::WriteHandle
Definition: StoreGate/StoreGate/WriteHandle.h:76
SG::WriteHandle::record
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
eFEXNTuple.delta_phi
def delta_phi(phi1, phi2)
Definition: eFEXNTuple.py:15
L0Muon::L0MuonSmearingAlg::finalize
virtual StatusCode finalize() override
Definition: L0MuonSmearingAlg.cxx:44
L0Muon::L0MuonTrack::phi
float phi() const
Definition: L0MuonTrack.h:20
TruthTrackSmearer.h
L0Muon::L0MuonSmearingAlg::initialize
virtual StatusCode initialize() override
Definition: L0MuonSmearingAlg.cxx:22
L0Muon::L0MuonSmearingAlg::m_outputMuonRoIKey
SG::WriteHandleKey< xAOD::MuonRoIContainer > m_outputMuonRoIKey
Definition: L0MuonSmearingAlg.h:31
Monitored::Scalar
Declare a monitored scalar variable.
Definition: MonitoredScalar.h:34