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::IParticleContainerm_container1Name
SG::ReadHandleKey< xAOD::IParticleContainerm_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 61 of file EGInvariantMassTool.cxx.

62{
63
64 SG::WriteHandle<std::vector<float>> writeHandle{ m_sgName, ctx };
65
66 // create the vector which will hold the values invariant masses
67 auto masses = std::make_unique<std::vector<float>>();
68 // compute the invariant mass values
69 ATH_CHECK(getInvariantMasses(ctx, *masses));
70
71 ATH_CHECK(writeHandle.record(std::move(masses)));
72
73 return StatusCode::SUCCESS;
74}
#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 77 of file EGInvariantMassTool.cxx.

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

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