ATLAS Offline Software
Loading...
Searching...
No Matches
DerivationFramework::EGInvariantMassTool Class Reference

#include <EGInvariantMassTool.h>

Inheritance diagram for DerivationFramework::EGInvariantMassTool:
Collaboration diagram for DerivationFramework::EGInvariantMassTool:

Public Member Functions

virtual StatusCode initialize () override final
virtual StatusCode addBranches (const EventContext &ctx) const override final

Private Member Functions

StatusCode getInvariantMasses (const EventContext &ctx, std::vector< float > &) const

Private Attributes

Gaudi::Property< std::string > m_expression1 {this, "Object1Requirements", "true"}
Gaudi::Property< std::string > m_expression2 {this, "Object2Requirements", "true"}
SG::WriteHandleKey< std::vector< float > > m_sgName
SG::ReadHandleKey< xAOD::IParticleContainer > m_container1Name
SG::ReadHandleKey< xAOD::IParticleContainer > m_container2Name
SG::ReadHandleKey< std::vector< float > > m_pt1BranchName
SG::ReadHandleKey< std::vector< float > > m_eta1BranchName
SG::ReadHandleKey< std::vector< float > > m_phi1BranchName
SG::ReadHandleKey< std::vector< float > > m_pt2BranchName
SG::ReadHandleKey< std::vector< float > > m_eta2BranchName
SG::ReadHandleKey< std::vector< float > > m_phi2BranchName
Gaudi::Property< float > m_mass1Hypothesis {this, "Mass1Hypothesis", 0.f}
Gaudi::Property< float > m_mass2Hypothesis {this, "Mass2Hypothesis", 0.f}
Gaudi::Property< float > m_mindR {this, "MinDeltaR", 0.f}
Gaudi::Property< bool > m_checkCharge {this, "CheckCharge", true}
Gaudi::Property< bool > m_doTransverseMass {this,"DoTransverseMass", true}

Detailed Description

Definition at line 31 of file EGInvariantMassTool.h.

Member Function Documentation

◆ addBranches()

StatusCode DerivationFramework::EGInvariantMassTool::addBranches ( const EventContext & ctx) const
finaloverridevirtual

Definition at line 62 of file EGInvariantMassTool.cxx.

63{
64
65 SG::WriteHandle<std::vector<float>> writeHandle{ m_sgName, ctx };
66
67 // create the vector which will hold the values invariant masses
68 auto masses = std::make_unique<std::vector<float>>();
69 // compute the invariant mass values
70 ATH_CHECK(getInvariantMasses(ctx, *masses));
71
72 ATH_CHECK(writeHandle.record(std::move(masses)));
73
74 return StatusCode::SUCCESS;
75}
#define ATH_CHECK
Evaluate an expression and check for errors.
SG::WriteHandleKey< std::vector< float > > m_sgName
StatusCode getInvariantMasses(const EventContext &ctx, std::vector< float > &) const
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.

◆ getInvariantMasses()

StatusCode DerivationFramework::EGInvariantMassTool::getInvariantMasses ( const EventContext & ctx,
std::vector< float > & masses ) const
private

Definition at line 78 of file EGInvariantMassTool.cxx.

80{
81 // Get optional payload
82 const std::vector<float>* pt1 = nullptr;
83 if (!m_pt1BranchName.key().empty()) {
84 SG::ReadHandle<std::vector<float>> readHandle{ m_pt1BranchName, ctx };
85 pt1 = readHandle.ptr();
86 }
87 const std::vector<float>* pt2 = nullptr;
88 if (!m_pt2BranchName.key().empty()) {
89 SG::ReadHandle<std::vector<float>> readHandle{ m_pt2BranchName, ctx };
90 pt2 = readHandle.ptr();
91 }
92
93 const std::vector<float>* eta1 = nullptr;
94 if (!m_eta1BranchName.key().empty()) {
95 SG::ReadHandle<std::vector<float>> readHandle{ m_eta1BranchName, ctx };
96 eta1 = readHandle.ptr();
97 }
98 const std::vector<float>* eta2 = nullptr;
99 if (!m_eta2BranchName.key().empty()) {
100 SG::ReadHandle<std::vector<float>> readHandle{ m_eta2BranchName, ctx };
101 eta2 = readHandle.ptr();
102 }
103
104 const std::vector<float>* phi1 = nullptr;
105 if (!m_phi1BranchName.key().empty()) {
106 SG::ReadHandle<std::vector<float>> readHandle{ m_phi1BranchName, ctx };
107 phi1 = readHandle.ptr();
108 }
109 const std::vector<float>* phi2 = nullptr;
110 if (!m_phi2BranchName.key().empty()) {
111 SG::ReadHandle<std::vector<float>> readHandle{ m_phi2BranchName, ctx };
112 phi2 = readHandle.ptr();
113 }
114 // Get the input particles
115 SG::ReadHandle<xAOD::IParticleContainer> inputParticles1{ m_container1Name,
116 ctx };
117 SG::ReadHandle<xAOD::IParticleContainer> inputParticles2{ m_container2Name,
118 ctx };
119 const xAOD::IParticleContainer* particles1 = inputParticles1.ptr();
120 const xAOD::IParticleContainer* particles2 = inputParticles2.ptr();
121
122 // get the positions of the elements which pass the requirement
123 std::vector<int> entries1 = m_parser[kParser1]->evaluateAsVector();
124 unsigned int nEntries1 = entries1.size();
125 std::vector<int> entries2 = m_parser[kParser2]->evaluateAsVector();
126 unsigned int nEntries2 = entries2.size();
127
128 // if there are no particles in one of the two lists to combine,
129 // just leave the function
130 if (nEntries1 == 0 || nEntries2 == 0) {
131 return StatusCode::SUCCESS;
132 }
133
134 // check the sizes are compatible
135 if (particles1->size() != nEntries1) {
136 ATH_MSG_ERROR("Branch sizes incompatible - returning zero");
137 return StatusCode::FAILURE;
138 }
139 if (particles2->size() != nEntries2) {
140 ATH_MSG_ERROR("Branch sizes incompatible - returning zero");
141 return StatusCode::FAILURE;
142 }
143 if ((pt1 && pt1->size() != nEntries1) ||
144 ((!m_doTransverseMass || (m_mindR > 0.0)) && eta1 &&
145 eta1->size() != nEntries1) ||
146 (phi1 && phi1->size() != nEntries1)) {
147 ATH_MSG_ERROR("Branch sizes incompatible - returning zero");
148 return StatusCode::FAILURE;
149 }
150 if ((pt2 && pt2->size() != nEntries2) ||
151 ((!m_doTransverseMass || (m_mindR > 0.0)) && eta2 &&
152 eta2->size() != nEntries2) ||
153 (phi2 && phi2->size() != nEntries2)) {
154 ATH_MSG_ERROR("Branch sizes incompatible - returning zero");
155 return StatusCode::FAILURE;
156 }
157
158 // Double loop to get the pairs for which the mass should be calculated
159 unsigned int outerIt, innerIt;
160 std::vector<std::vector<int>> pairs;
161 for (outerIt = 0; outerIt < nEntries1; ++outerIt) {
162 for (innerIt = 0; innerIt < nEntries2; ++innerIt) {
163 std::vector<int> tmpPair;
164 if (entries1[outerIt] == 1 && entries2[innerIt] == 1) {
165 tmpPair.push_back(outerIt);
166 tmpPair.push_back(innerIt);
167 pairs.push_back(std::move(tmpPair));
168 }
169 }
170 }
171
172 // since IParticle interface does not provide charge() method
173 // we need to identify the particle type in case we want to check
174 // its charge (through a type cast)
177 if (m_checkCharge) {
178 type1 = ((*particles1)[0])->type();
179 type2 = ((*particles2)[0])->type();
180 if ((type1 != xAOD::Type::Electron && type1 != xAOD::Type::Muon) ||
181 (type2 != xAOD::Type::Electron && type2 != xAOD::Type::Muon)) {
183 "Cannot check charge for particles not of type electron or muon");
184 return StatusCode::FAILURE;
185 }
186 }
187
188 for (const auto& pair : pairs) {
189 unsigned int first = pair[0];
190 unsigned int second = pair[1];
191 float apt1 = pt1 ? (*pt1)[first] : ((*particles1)[first])->p4().Pt();
192 float apt2 = pt2 ? (*pt2)[second] : ((*particles2)[second])->p4().Pt();
193 float aeta1(-999.), aeta2(-999.);
194 if (!m_doTransverseMass || (m_mindR > 0.0)) {
195 aeta1 = eta1 ? (*eta1)[first] : ((*particles1)[first])->p4().Eta();
196 aeta2 = eta2 ? (*eta2)[second] : ((*particles2)[second])->p4().Eta();
197 }
198 float aphi1 = phi1 ? (*phi1)[first] : ((*particles1)[first])->p4().Phi();
199 float aphi2 = phi2 ? (*phi2)[second] : ((*particles2)[second])->p4().Phi();
200
201 if (m_mindR > 0.0) {
202 float deta = aeta1 - aeta2;
203 float dphi = std::abs(aphi1 - aphi2);
204 if (dphi > std::numbers::pi) {
205 dphi = (2*std::numbers::pi) - dphi;
206 }
207 if (std::sqrt(deta * deta + dphi * dphi) < m_mindR) {
208 continue;
209 }
210 }
211
212 if (m_checkCharge) {
213 float q1(0.), q2(0.);
214 if (type1 == xAOD::Type::Electron) {
215 q1 = ((xAOD::Electron*)((*particles1)[first]))->charge();
216 } else if (type1 == xAOD::Type::Muon) {
217 q1 = ((xAOD::Muon*)((*particles1)[first]))
218 ->trackParticle(xAOD::Muon::TrackParticleType::Primary)
219 ->charge();
220 }
221 if (type2 == xAOD::Type::Electron) {
222 q2 = ((xAOD::Electron*)((*particles2)[second]))->charge();
223 } else if (type2 == xAOD::Type::Muon) {
224 q2 = ((xAOD::Muon*)((*particles2)[second]))
225 ->trackParticle(xAOD::Muon::TrackParticleType::Primary)
226 ->charge();
227 }
228 if (q1 * q2 > 0.) {
229 continue;
230 }
231 }
232 TLorentzVector v1, v2, v;
233 if (m_doTransverseMass) {
234 v1.SetPtEtaPhiM(apt1, 0., aphi1, m_mass1Hypothesis);
235 v2.SetPtEtaPhiM(apt2, 0., aphi2, m_mass2Hypothesis);
236 } else {
237 v1.SetPtEtaPhiM(apt1, aeta1, aphi1, m_mass1Hypothesis);
238 v2.SetPtEtaPhiM(apt2, aeta2, aphi2, m_mass2Hypothesis);
239 }
240 float mass = (v1 + v2).M();
241 masses.push_back(mass);
242 }
243 return StatusCode::SUCCESS;
244}
#define ATH_MSG_ERROR(x,...)
#define ATH_MSG_WARNING(x,...)
size_type size() const noexcept
Returns the number of elements in the collection.
SG::ReadHandleKey< std::vector< float > > m_eta1BranchName
SG::ReadHandleKey< std::vector< float > > m_pt1BranchName
SG::ReadHandleKey< xAOD::IParticleContainer > m_container1Name
SG::ReadHandleKey< xAOD::IParticleContainer > m_container2Name
SG::ReadHandleKey< std::vector< float > > m_phi1BranchName
SG::ReadHandleKey< std::vector< float > > m_eta2BranchName
SG::ReadHandleKey< std::vector< float > > m_pt2BranchName
SG::ReadHandleKey< std::vector< float > > m_phi2BranchName
const_pointer_type ptr()
Dereference the pointer.
bool first
Definition DeMoScan.py:534
ObjectType
Type of objects that have a representation in the xAOD EDM.
Definition ObjectType.h:32
@ Other
An object not falling into any of the other categories.
Definition ObjectType.h:34
@ Muon
The object is a muon.
Definition ObjectType.h:48
@ Electron
The object is an electron.
Definition ObjectType.h:46
setEt setPhi setE277 setWeta2 eta1
Muon_v1 Muon
Reference the current persistent version:
Electron_v1 Electron
Definition of the current "egamma version".
DataVector< IParticle > IParticleContainer
Simple convenience declaration of IParticleContainer.

◆ initialize()

StatusCode DerivationFramework::EGInvariantMassTool::initialize ( )
finaloverridevirtual

Definition at line 23 of file EGInvariantMassTool.cxx.

24{
25 if (m_sgName.key().empty()) {
26 ATH_MSG_ERROR("No SG name provided for the output of EGInvariantMassTool!");
27 return StatusCode::FAILURE;
28 }
29 ATH_CHECK(m_sgName.initialize());
30
31 if (!m_container1Name.key().empty()) {
32 ATH_CHECK(m_container1Name.initialize());
33 }
34 if (!m_container2Name.key().empty()) {
35 ATH_CHECK(m_container2Name.initialize());
36 }
37 if (!m_pt1BranchName.key().empty()) {
38 ATH_CHECK(m_pt1BranchName.initialize());
39 }
40 if (!m_eta1BranchName.key().empty()) {
41 ATH_CHECK(m_eta1BranchName.initialize());
42 }
43 if (!m_phi1BranchName.key().empty()) {
44 ATH_CHECK(m_phi1BranchName.initialize());
45 }
46 if (!m_pt2BranchName.key().empty()) {
47 ATH_CHECK(m_pt2BranchName.initialize());
48 }
49 if (!m_eta2BranchName.key().empty()) {
50 ATH_CHECK(m_eta2BranchName.initialize());
51 }
52 if (!m_phi2BranchName.key().empty()) {
53 ATH_CHECK(m_phi2BranchName.initialize());
54 }
55
56 ATH_CHECK(initializeParser({ m_expression1, m_expression2 }));
57
58 return StatusCode::SUCCESS;
59}
Gaudi::Property< std::string > m_expression2
Gaudi::Property< std::string > m_expression1

Member Data Documentation

◆ m_checkCharge

Gaudi::Property<bool> DerivationFramework::EGInvariantMassTool::m_checkCharge {this, "CheckCharge", true}
private

Definition at line 109 of file EGInvariantMassTool.h.

109{this, "CheckCharge", true};

◆ m_container1Name

SG::ReadHandleKey<xAOD::IParticleContainer> DerivationFramework::EGInvariantMassTool::m_container1Name
private
Initial value:
{
this,
"Container1Name",
"",
"SG key of first container"
}

Definition at line 51 of file EGInvariantMassTool.h.

51 {
52 this,
53 "Container1Name",
54 "",
55 "SG key of first container"
56 };

◆ m_container2Name

SG::ReadHandleKey<xAOD::IParticleContainer> DerivationFramework::EGInvariantMassTool::m_container2Name
private
Initial value:
{
this,
"Container2Name",
"",
"SG key of second container"
}

Definition at line 57 of file EGInvariantMassTool.h.

57 {
58 this,
59 "Container2Name",
60 "",
61 "SG key of second container"
62 };

◆ m_doTransverseMass

Gaudi::Property<bool> DerivationFramework::EGInvariantMassTool::m_doTransverseMass {this,"DoTransverseMass", true}
private

Definition at line 110 of file EGInvariantMassTool.h.

110{this,"DoTransverseMass", true};

◆ m_eta1BranchName

SG::ReadHandleKey<std::vector<float> > DerivationFramework::EGInvariantMassTool::m_eta1BranchName
private
Initial value:
{
this,
"Eta1BranchName",
"",
"Eta1 if different than default"
}

Definition at line 71 of file EGInvariantMassTool.h.

71 {
72 this,
73 "Eta1BranchName",
74 "",
75 "Eta1 if different than default"
76 };

◆ m_eta2BranchName

SG::ReadHandleKey<std::vector<float> > DerivationFramework::EGInvariantMassTool::m_eta2BranchName
private
Initial value:
{
this,
"Eta2BranchName",
"",
"Eta2 if different than default"
}

Definition at line 92 of file EGInvariantMassTool.h.

92 {
93 this,
94 "Eta2BranchName",
95 "",
96 "Eta2 if different than default"
97 };

◆ m_expression1

Gaudi::Property<std::string> DerivationFramework::EGInvariantMassTool::m_expression1 {this, "Object1Requirements", "true"}
private

Definition at line 44 of file EGInvariantMassTool.h.

44{this, "Object1Requirements", "true"};

◆ m_expression2

Gaudi::Property<std::string> DerivationFramework::EGInvariantMassTool::m_expression2 {this, "Object2Requirements", "true"}
private

Definition at line 45 of file EGInvariantMassTool.h.

45{this, "Object2Requirements", "true"};

◆ m_mass1Hypothesis

Gaudi::Property<float> DerivationFramework::EGInvariantMassTool::m_mass1Hypothesis {this, "Mass1Hypothesis", 0.f}
private

Definition at line 106 of file EGInvariantMassTool.h.

106{this, "Mass1Hypothesis", 0.f};

◆ m_mass2Hypothesis

Gaudi::Property<float> DerivationFramework::EGInvariantMassTool::m_mass2Hypothesis {this, "Mass2Hypothesis", 0.f}
private

Definition at line 107 of file EGInvariantMassTool.h.

107{this, "Mass2Hypothesis", 0.f};

◆ m_mindR

Gaudi::Property<float> DerivationFramework::EGInvariantMassTool::m_mindR {this, "MinDeltaR", 0.f}
private

Definition at line 108 of file EGInvariantMassTool.h.

108{this, "MinDeltaR", 0.f};

◆ m_phi1BranchName

SG::ReadHandleKey<std::vector<float> > DerivationFramework::EGInvariantMassTool::m_phi1BranchName
private
Initial value:
{
this,
"Phi1BranchName",
"",
"Phi1 if different than default"
}

Definition at line 78 of file EGInvariantMassTool.h.

78 {
79 this,
80 "Phi1BranchName",
81 "",
82 "Phi1 if different than default"
83 };

◆ m_phi2BranchName

SG::ReadHandleKey<std::vector<float> > DerivationFramework::EGInvariantMassTool::m_phi2BranchName
private
Initial value:
{
this,
"Phi2BranchName",
"",
"Phi2 if different than default"
}

Definition at line 99 of file EGInvariantMassTool.h.

99 {
100 this,
101 "Phi2BranchName",
102 "",
103 "Phi2 if different than default"
104 };

◆ m_pt1BranchName

SG::ReadHandleKey<std::vector<float> > DerivationFramework::EGInvariantMassTool::m_pt1BranchName
private
Initial value:
{
this,
"Pt1BranchName",
"",
"Pt1 if different than default"
}

Definition at line 64 of file EGInvariantMassTool.h.

64 {
65 this,
66 "Pt1BranchName",
67 "",
68 "Pt1 if different than default"
69 };

◆ m_pt2BranchName

SG::ReadHandleKey<std::vector<float> > DerivationFramework::EGInvariantMassTool::m_pt2BranchName
private
Initial value:
{
this,
"Pt2BranchName",
"",
"Pt2 if different than default"
}

Definition at line 85 of file EGInvariantMassTool.h.

85 {
86 this,
87 "Pt2BranchName",
88 "",
89 "Pt2 if different than default"
90 };

◆ m_sgName

SG::WriteHandleKey<std::vector<float> > DerivationFramework::EGInvariantMassTool::m_sgName
private
Initial value:
{ this,
"StoreGateEntryName",
"",
"SG key of output object" }

Definition at line 46 of file EGInvariantMassTool.h.

46 { this,
47 "StoreGateEntryName",
48 "",
49 "SG key of output object" };

The documentation for this class was generated from the following files: