ATLAS Offline Software
InvariantMassTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 // Author: James Catmore (james.catmore@cern.ch)
6 
8 #include <utility> //for std::pair
9 #include <cmath> //for std::hypot
10 
11 namespace DerivationFramework {
12 
14  {
16 
17  if (m_expression2.empty()) {
18  ATH_CHECK(initializeParser( {m_expression.value(), m_expression.value()} ));
19  }
20  else {
21  ATH_CHECK(initializeParser( {m_expression.value(),m_expression2.value()} ));
22  }
23 
24  ATH_CHECK(m_containerName.initialize());
27 
28  return StatusCode::SUCCESS;
29  }
30 
32  {
33  ATH_CHECK( finalizeParser());
34  return StatusCode::SUCCESS;
35  }
36 
37  StatusCode InvariantMassTool::addBranches(const EventContext& ctx) const
38  {
39  // Write masses to SG for access by downstream algs
40  if (evtStore()->contains<std::vector<float> >(m_sgName.key())) {
41  ATH_MSG_ERROR("Tool is attempting to write a StoreGate key " << m_sgName << " which already exists. Please use a different key");
42  return StatusCode::FAILURE;
43  }
44  std::unique_ptr<std::vector<float> > masses(new std::vector<float>());
45  ATH_CHECK(getInvariantMasses(masses.get(), ctx));
46  SG::WriteHandle<std::vector<float> > writeHandle(m_sgName, ctx);
47  ATH_CHECK(writeHandle.record(std::move(masses)));
48  return StatusCode::SUCCESS;
49  }
50 
51  StatusCode InvariantMassTool::getInvariantMasses(std::vector<float>* masses, const EventContext& ctx) const
52  {
53 
54  // check the relevant information is available
55  if (m_containerName.key().empty()) {
56  ATH_MSG_WARNING("Input container missing - returning zero");
57  masses->push_back(0.0);
58  return StatusCode::FAILURE;
59  }
60 
62 
63  bool from2Collections(false);
64  const xAOD::IParticleContainer* particles2{nullptr};
65  if (!m_containerName2.key().empty() && m_containerName2.key()!=m_containerName.key()) {
67  particles2=particleHdl2.cptr();
68  from2Collections = true;
69  }
70 
71  // get the positions of the elements which pass the requirement
72  std::vector<int> entries = m_parser[kInvariantMassToolParser1]->evaluateAsVector();
73  std::vector<int> entries2 = m_parser[kInvariantMassToolParser2]->evaluateAsVector();
74  unsigned int nEntries = entries.size();
75  unsigned int nEntries2 = entries2.size();
76 
77  // check the sizes are compatible
78  if (!from2Collections) {
79  if ( (particles->size() != nEntries) || (particles->size() != nEntries2) || (nEntries!=nEntries2) ) {
80  ATH_MSG_ERROR("Branch sizes incompatible - returning zero. Check your selection strings.");
81  masses->push_back(0.0);
82  return StatusCode::FAILURE;
83  }
84  }
85  if (from2Collections) {
86  if ( (particles->size() != nEntries) || (particles2->size() != nEntries2) ) {
87  ATH_MSG_ERROR("Branch sizes incompatible - returning zero. Check your selection strings.");
88  masses->push_back(0.0);
89  return StatusCode::FAILURE;
90  }
91  }
92 
93  // Double loop to get all possible index pairs
94  unsigned int outerIt, innerIt;
95  std::vector<std::pair<int, int> > pairs;
96  // Loop for case where both legs are from the same container
97  if (!from2Collections) {
98  for (outerIt=0; outerIt<nEntries; ++outerIt) {
99  for (innerIt=outerIt+1; innerIt<nEntries; ++innerIt) {
100  pairs.push_back({static_cast<int>(outerIt),static_cast<int>(innerIt)});
101  }
102  }
103  // Select the pairs for which the mass should be calculated, and then calculate it
104  for (const auto & [first, second]: pairs) {
105  if ( (entries[first]==1 && entries2[second]==1) || (entries2[first]==1 && entries[second]==1) ) {
106  const float mass = calculateInvariantMass( ((*particles)[first])->p4().Vect(),
107  ((*particles)[second])->p4().Vect(),
110  masses->push_back(mass);
111  }
112  }
113  }
114 
115  // Loop for case where both legs are from different containers
116  if (from2Collections) {
117  for (outerIt=0; outerIt<nEntries; ++outerIt) {
118  if (entries[outerIt]==0) continue;
119  for (innerIt=0; innerIt<nEntries2; ++innerIt) {
120  if (entries2[innerIt]==0) continue;
121  pairs.push_back({static_cast<int>(outerIt),static_cast<int>(innerIt)});
122  }
123  }
124  // Select the pairs for which the mass should be calculated, and then calculate it
125  for (const auto & [first, second]: pairs) {
126  const float mass = calculateInvariantMass( ((*particles)[first])->p4().Vect(),
127  ((*particles2)[second])->p4().Vect(),
130  masses->push_back(mass);
131  }
132  }
133 
134  return StatusCode::SUCCESS;
135 
136  }
137 
138  float InvariantMassTool::calculateInvariantMass(const TVector3& v1, const TVector3&v2,float M1,float M2) {
139  TLorentzVector p1(v1, M1 > 0 ? std::hypot(M1, v1.Mag()) : v1.Mag());
140  TLorentzVector p2(v2, M2 > 0 ? std::hypot(M2, v2.Mag()) : v2.Mag());
141  return (p1+p2).M();
142 
143  }
144 
145 }
Base_Fragment.mass
mass
Definition: Sherpa_i/share/common/Base_Fragment.py:59
DerivationFramework::InvariantMassTool::m_containerName
SG::ReadHandleKey< xAOD::IParticleContainer > m_containerName
Definition: InvariantMassTool.h:41
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:67
TRTCalib_cfilter.p1
p1
Definition: TRTCalib_cfilter.py:130
python.SystemOfUnits.second
float second
Definition: SystemOfUnits.py:135
DerivationFramework::InvariantMassTool::finalize
virtual StatusCode finalize() override final
Definition: InvariantMassTool.cxx:31
SG::VarHandleKey::key
const std::string & key() const
Return the StoreGate ID for the referenced object.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:141
python.CreateTierZeroArgdict.pairs
pairs
Definition: CreateTierZeroArgdict.py:201
DerivationFramework::InvariantMassTool::calculateInvariantMass
static float calculateInvariantMass(const TVector3 &v1, const TVector3 &v2, float M1, float M2)
Definition: InvariantMassTool.cxx:138
DerivationFramework::InvariantMassTool::m_massHypothesis
Gaudi::Property< float > m_massHypothesis
Definition: InvariantMassTool.h:39
TRTCalib_cfilter.p2
p2
Definition: TRTCalib_cfilter.py:131
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
InvariantMassTool.h
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
contains
bool contains(const std::string &s, const std::string &regx)
does a string contain the substring
Definition: hcg.cxx:114
DerivationFramework::kInvariantMassToolParser2
@ kInvariantMassToolParser2
Definition: InvariantMassTool.h:25
DerivationFramework::InvariantMassTool::m_expression
Gaudi::Property< std::string > m_expression
Definition: InvariantMassTool.h:36
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
DerivationFramework
THE reconstruction tool.
Definition: ParticleSortingAlg.h:24
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
DerivationFramework::InvariantMassTool::m_containerName2
SG::ReadHandleKey< xAOD::IParticleContainer > m_containerName2
Definition: InvariantMassTool.h:42
DataVector
Derived DataVector<T>.
Definition: DataVector.h:795
DerivationFramework::InvariantMassTool::initialize
virtual StatusCode initialize() override final
Definition: InvariantMassTool.cxx:13
DerivationFramework::InvariantMassTool::m_expression2
Gaudi::Property< std::string > m_expression2
Definition: InvariantMassTool.h:37
DerivationFramework::InvariantMassTool::getInvariantMasses
StatusCode getInvariantMasses(std::vector< float > *, const EventContext &ctx) const
Definition: InvariantMassTool.cxx:51
ReadCellNoiseFromCoolCompare.v2
v2
Definition: ReadCellNoiseFromCoolCompare.py:364
SG::WriteHandle
Definition: StoreGate/StoreGate/WriteHandle.h:73
DerivationFramework::InvariantMassTool::addBranches
virtual StatusCode addBranches(const EventContext &ctx) const override final
Definition: InvariantMassTool.cxx:37
SG::WriteHandle::record
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
DerivationFramework::InvariantMassTool::m_inputDecorNames
SG::ReadDecorHandleKeyArray< xAOD::IParticleContainer > m_inputDecorNames
Definition: InvariantMassTool.h:43
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
DeMoScan.first
bool first
Definition: DeMoScan.py:534
LArG4FSStartPointFilter.particles
list particles
Definition: LArG4FSStartPointFilter.py:84
entries
double entries
Definition: listroot.cxx:49
DerivationFramework::InvariantMassTool::m_sgName
SG::WriteHandleKey< std::vector< float > > m_sgName
Definition: InvariantMassTool.h:38
DerivationFramework::kInvariantMassToolParser1
@ kInvariantMassToolParser1
Definition: InvariantMassTool.h:25
dqBeamSpot.nEntries
int nEntries
Definition: dqBeamSpot.py:72
SG::AllowEmpty
@ AllowEmpty
Definition: StoreGate/StoreGate/VarHandleKey.h:27
DerivationFramework::InvariantMassTool::m_massHypothesis2
Gaudi::Property< float > m_massHypothesis2
Definition: InvariantMassTool.h:40
SUSY_SimplifiedModel_PreInclude.masses
dictionary masses
Definition: SUSY_SimplifiedModel_PreInclude.py:7