ATLAS Offline Software
EGTransverseMassTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 // EGTransverseMassTool.cxx, (c) ATLAS Detector software
7 // Author: Giovanni Marchiori (giovanni.marchiori@cern.ch)
8 //
9 // The tool computes the transverse mass between the MET and the
10 // particles belonging to some collection.
11 // The MET met and phi values can either be stored in SG under
12 // keys specified with METPtBranchName and METPhiBranchName,
13 // otherwise the met() and phi() of the MET object stored in
14 // SG under the METContainerName (default = MET_LocHadTopo)
15 // will be used.
16 // A MET>METmin cut can be applied.
17 // For the particles, only those passing the ObjectRequirements
18 // selection are retained. Their pt and phi can be stored
19 // in SG under keys specified with ObjectPtBranchName and
20 // ObjectPhiBranchName, otherwise the Pt() and Phi() methods
21 // of the IParticles object of the containred stored in SG
22 // with the key specified by ObjectContainerName will be used
24 
26 
27 #include <cmath>
28 using std::abs;
29 using std::sqrt;
30 
31 #include "TLorentzVector.h"
32 
33 namespace DerivationFramework {
34 
36  const std::string& n,
37  const IInterface* p)
39  , m_expression1("true")
40  , m_METmin(-999.)
41  , m_mass1Hypothesis(0.0)
42 {
43  declareInterface<DerivationFramework::IAugmentationTool>(this);
44  declareProperty("ObjectRequirements", m_expression1);
45  declareProperty("METmin", m_METmin);
46  declareProperty("ObjectMassHypothesis", m_mass1Hypothesis);
47 }
48 
51 {
52  if (m_sgName.key().empty()) {
54  "No SG name provided for the output of the transverse mass tool!");
55  return StatusCode::FAILURE;
56  }
58 
59  if (!m_container1Name.key().empty()) {
60  ATH_CHECK(m_container1Name.initialize());
61  }
62  if (!m_container2Name.key().empty()) {
63  ATH_CHECK(m_container2Name.initialize());
64  }
65  if (!m_pt1BranchName.key().empty()) {
67  }
68  if (!m_phi1BranchName.key().empty()) {
70  }
71  if (!m_pt2BranchName.key().empty()) {
73  }
74  if (!m_phi2BranchName.key().empty()) {
76  }
77 
79 
80  return StatusCode::SUCCESS;
81 }
82 
85 {
86  const EventContext& ctx = Gaudi::Hive::currentContext();
87  SG::WriteHandle<std::vector<float>> writeHandle{ m_sgName, ctx };
88 
89  // create the vector which will hold the values invariant masses
90  auto masses = std::make_unique<std::vector<float>>();
91  // compute the invariant mass values
93 
94  ATH_CHECK(writeHandle.record(std::move(masses)));
95 
96  return StatusCode::SUCCESS;
97 }
98 
101  std::vector<float>& masses) const
102 {
103  // Get optional payload
104  const std::vector<float>* pt1 = nullptr;
105  if (!m_pt1BranchName.key().empty()) {
107  pt1 = readHandle.ptr();
108  }
109  const std::vector<float>* pt2 = nullptr;
110  if (!m_pt2BranchName.key().empty()) {
112  pt2 = readHandle.ptr();
113  }
114 
115  const std::vector<float>* phi1 = nullptr;
116  if (!m_phi1BranchName.key().empty()) {
118  phi1 = readHandle.ptr();
119  }
120  const std::vector<float>* phi2 = nullptr;
121  if (!m_phi2BranchName.key().empty()) {
123  phi2 = readHandle.ptr();
124  }
125 
126  // Get the input particle and MET
128  ctx };
130  ctx };
131  const xAOD::IParticleContainer* particles1 = inputParticles1.ptr();
132  const xAOD::MissingETContainer* particles2 = inputParticles2.ptr();
133 
134  // compute MET
135  if (particles2->empty()) {
136  if (!pt2) {
137  ATH_MSG_WARNING("No MET info found");
138  return StatusCode::SUCCESS;
139  }
140  if (pt2->empty()) {
141  ATH_MSG_WARNING("No MET info found");
142  return StatusCode::SUCCESS;
143  }
144  }
145 
146  float MET = pt2 ? (*pt2)[0] : particles2->at(0)->met();
147  float MET_phi = phi2 ? (*phi2)[0] : particles2->at(0)->phi();
148 
149  // apply MET requirement
150  if (MET < m_METmin)
151  return StatusCode::SUCCESS;
152 
153  // get the positions of the particles which pass the requirement
154  std::vector<int> entries1 = m_parser->evaluateAsVector();
155  unsigned int nEntries1 = entries1.size();
156 
157  // if there are no particles in one of the two lists to combine, just leave
158  // function
159  if (nEntries1 == 0)
160  return StatusCode::SUCCESS;
161 
162  // check that the sizes are compatible
163  if (particles1->size() != nEntries1) {
164  ATH_MSG_ERROR("Branch sizes incompatible - returning zero");
165  return StatusCode::FAILURE;
166  }
167  if ((pt1 && pt1->size() != nEntries1) ||
168  (phi1 && phi1->size() != nEntries1)) {
169  ATH_MSG_ERROR("Branch sizes incompatible - returning zero");
170  return StatusCode::FAILURE;
171  }
172 
173  // Loop over the objects and calculate the transverse mass
174  unsigned int iter;
175  for (iter = 0; iter < nEntries1; ++iter) {
176  if (entries1[iter] != 1)
177  continue;
178  float apt1 = pt1 ? (*pt1)[iter] : ((*particles1)[iter])->p4().Pt();
179  float aphi1 = phi1 ? (*phi1)[iter] : ((*particles1)[iter])->p4().Phi();
180 
181  TLorentzVector v1, v2;
182  v1.SetPtEtaPhiM(apt1, 0., aphi1, m_mass1Hypothesis);
183  v2.SetPtEtaPhiM(MET, 0., MET_phi, 0.);
184  float mass = (v1 + v2).M();
185  masses.push_back(mass);
186  }
187  return StatusCode::SUCCESS;
188 }
189 }
DerivationFramework::EGTransverseMassTool::m_METmin
float m_METmin
Definition: EGTransverseMassTool.h:45
EGTransverseMassTool.h
DerivationFramework::EGTransverseMassTool::m_container1Name
SG::ReadHandleKey< xAOD::IParticleContainer > m_container1Name
Definition: EGTransverseMassTool.h:53
Base_Fragment.mass
mass
Definition: Sherpa_i/share/common/Base_Fragment.py:59
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:70
AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T > &t)
Definition: AthCommonDataStore.h:145
ExpressionParserUserBase< AthAlgTool, 1 >::m_parser
std::conditional< NUM_PARSER==1, std::unique_ptr< ExpressionParsing::ExpressionParser >, std::array< std::unique_ptr< ExpressionParsing::ExpressionParser >, NUM_PARSER > >::type m_parser
Definition: ExpressionParserUser.h:100
DerivationFramework::EGTransverseMassTool::m_pt1BranchName
SG::ReadHandleKey< std::vector< float > > m_pt1BranchName
Definition: EGTransverseMassTool.h:66
DerivationFramework::EGTransverseMassTool::m_mass1Hypothesis
float m_mass1Hypothesis
Definition: EGTransverseMassTool.h:46
DerivationFramework::EGTransverseMassTool::m_phi2BranchName
SG::ReadHandleKey< std::vector< float > > m_phi2BranchName
Definition: EGTransverseMassTool.h:87
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
SG::VarHandleKey::key
const std::string & key() const
Return the StoreGate ID for the referenced object.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:141
DerivationFramework::EGTransverseMassTool::getTransverseMasses
StatusCode getTransverseMasses(const EventContext &ctx, std::vector< float > &) const
Definition: EGTransverseMassTool.cxx:100
DerivationFramework::EGTransverseMassTool::m_container2Name
SG::ReadHandleKey< xAOD::MissingETContainer > m_container2Name
Definition: EGTransverseMassTool.h:59
DerivationFramework::EGTransverseMassTool::m_expression1
std::string m_expression1
Definition: EGTransverseMassTool.h:44
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:210
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
beamspotman.n
n
Definition: beamspotman.py:731
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
DerivationFramework::EGTransverseMassTool::addBranches
virtual StatusCode addBranches() const override final
Pass the thinning service
Definition: EGTransverseMassTool.cxx:84
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::EGTransverseMassTool::EGTransverseMassTool
EGTransverseMassTool(const std::string &t, const std::string &n, const IInterface *p)
Definition: EGTransverseMassTool.cxx:35
DataVector
Derived DataVector<T>.
Definition: DataVector.h:794
DerivationFramework::EGTransverseMassTool::m_sgName
SG::WriteHandleKey< std::vector< float > > m_sgName
Definition: EGTransverseMassTool.h:48
ExpressionParserUser< AthAlgTool >::initializeParser
StatusCode initializeParser(const ExpressionParsing::SelectionArg< 1 > &selection_string)
ExpressionParserUser
Definition: ExpressionParserUser.h:107
xAOD::MissingETContainer_v1
Container for xAOD::MissingET_v1 objects.
Definition: MissingETContainer_v1.h:21
MET
Definition: MET.py:1
DerivationFramework::EGTransverseMassTool::initialize
virtual StatusCode initialize() override final
Definition: EGTransverseMassTool.cxx:50
ReadCellNoiseFromCoolCompare.v2
v2
Definition: ReadCellNoiseFromCoolCompare.py:364
SG::WriteHandle
Definition: StoreGate/StoreGate/WriteHandle.h:76
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
DataVector::at
const T * at(size_type n) const
Access an element, as an rvalue.
AthAlgTool
Definition: AthAlgTool.h:26
DerivationFramework::EGTransverseMassTool::m_phi1BranchName
SG::ReadHandleKey< std::vector< float > > m_phi1BranchName
Definition: EGTransverseMassTool.h:73
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
DataVector::empty
bool empty() const noexcept
Returns true if the collection is empty.
SUSY_SimplifiedModel_PreInclude.masses
dictionary masses
Definition: SUSY_SimplifiedModel_PreInclude.py:7
DerivationFramework::EGTransverseMassTool::m_pt2BranchName
SG::ReadHandleKey< std::vector< float > > m_pt2BranchName
Definition: EGTransverseMassTool.h:80