ATLAS Offline Software
ParticleSortingTool.cxx
Go to the documentation of this file.
1 
3 /*
4  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
5 */
6 
7 // ParticleSortingTool.cxx
8 // Implementation file for class ParticleSortingTool
9 // Author: Karsten Koeneke <karsten.koeneke@cern.ch>
11 
12 // EventUtils includes
13 #include "ParticleSortingTool.h"
14 
15 // EDM includes
16 #include "xAODBase/IParticle.h"
18 #include "xAODMuon/MuonContainer.h"
19 #include "xAODJet/JetContainer.h"
23 #include "xAODPFlow/PFOContainer.h"
31 
32 // Constructors
35  const std::string& name,
36  const IInterface* parent ) :
37  ::AthAlgTool ( type, name, parent ),
38  m_inCollKey(""),
39  m_outCollKey(""),
40  m_sortVar("pt"),
41  m_sortDescending(true),
42  m_sortID(0),
43  m_nEventsProcessed(0)
44 {
45  declareInterface< DerivationFramework::IAugmentationTool >(this);
46 
47  declareProperty("InputContainer", m_inCollKey="", "Input container name" );
48 
49  declareProperty("OutputContainer", m_outCollKey="",
50  "The name of the output container (with SG::VIEW_ELEMENTS) with the sorted copy of input objects" );
51 
52  declareProperty("SortVariable", m_sortVar="pt",
53  "Define by what parameter to sort (default: 'pt'; allowed: 'pt', 'eta', 'phi', 'm', 'e', 'rapidity')" );
54 
55  declareProperty("SortDescending", m_sortDescending=true,
56  "Define if the container should be sorted in a descending order (default=true)" );
57 }
58 
59 
60 // Destructor
63 {}
64 
65 
66 
67 // Athena algtool's Hooks
70 {
71  ATH_MSG_DEBUG ("Initializing " << name() << "...");
72 
73  // Print out the used configuration
74  ATH_MSG_DEBUG ( " using = " << m_inCollKey );
75  ATH_MSG_DEBUG ( " using = " << m_outCollKey );
76 
77  // initialize the counters
78  m_sortID = 0;
80 
81  // Figure out how to sort
82  if ( m_sortVar.value() == "pt" ) { m_sortID = 1; }
83  else if ( m_sortVar.value() == "eta" ) { m_sortID = 2; }
84  else if ( m_sortVar.value() == "phi" ) { m_sortID = 3; }
85  else if ( m_sortVar.value() == "m" ) { m_sortID = 4; }
86  else if ( m_sortVar.value() == "e" ) { m_sortID = 5; }
87  else if ( m_sortVar.value() == "rapidity" ) { m_sortID = 6; }
88  else {
89  ATH_MSG_INFO("Didn't find a valid value for SortVariable=" << m_sortVar.value() << "."
90  << " Assuming it's an auxdata member");
91  m_sortID = 7;
92  }
93  if ( m_sortDescending.value() ) { m_sortID *= -1; }
94 
95  return StatusCode::SUCCESS;
96 }
97 
98 
99 
100 
102 {
103  ATH_MSG_DEBUG ("Finalizing " << name() << "...");
104 
105  return StatusCode::SUCCESS;
106 }
107 
108 
109 
110 // Declare a short pre-processor macro to deal with the different container types
111 #define COPY_AND_SORT_CONTAINER( CONTAINERTYPE ) \
112 else if ( evtStore()->contains<CONTAINERTYPE>( m_inCollKey.value() ) ) { \
113  ATH_MSG_DEBUG("Trying to copy, sort, and record container of type "#CONTAINERTYPE ); \
114  const CONTAINERTYPE* inCont; \
115  ATH_CHECK( evtStore()->retrieve( inCont, m_inCollKey.value() ) ); \
116  CONTAINERTYPE* outCont = new CONTAINERTYPE( SG::VIEW_ELEMENTS ); \
117  *outCont = *inCont; \
118  ATH_CHECK( evtStore()->record ( outCont, m_outCollKey.value() ) ); \
119  ATH_CHECK( this->doSort(outCont) ); \
120 }
121 
122 
123 // Declare a short pre-processor macro to deal with the different container types
124 #define OVERWRITE_AND_SORT_CONTAINER( CONTAINERTYPE ) \
125 else if ( evtStore()->contains<CONTAINERTYPE>( m_inCollKey.value() ) ) { \
126  ATH_MSG_DEBUG("Trying to copy, sort, and overwrite container of type "#CONTAINERTYPE ); \
127  const CONTAINERTYPE* inCont; \
128  ATH_CHECK( evtStore()->retrieve( inCont, m_inCollKey.value() ) ); \
129  ConstDataVector<CONTAINERTYPE>* outCont = new ConstDataVector<CONTAINERTYPE>( SG::VIEW_ELEMENTS ); \
130  for ( const CONTAINERTYPE::base_value_type* inPart : *inCont ){ \
131  outCont->push_back(inPart); \
132  } \
133  ATH_CHECK( evtStore()->overwrite( outCont, m_inCollKey.value() ) ); \
134  ATH_CHECK( this->doSortConst<CONTAINERTYPE>(outCont) ); \
135 }
136 
137 
138 
140 {
141  // Increase the event counter
143 
144  // Simple status message at the beginning of each event execute,
145  ATH_MSG_DEBUG ( "==> addBranches " << name() << " on " << m_nEventsProcessed << ". event..." );
146 
147  if ( m_outCollKey.value().empty() ) {
148  // Try to get the input container as non-const
149  ATH_MSG_DEBUG("Got an empty 'OutputCollection' property. "
150  << "Trying to retrieve a non-const version of the 'InputContainer'...");
151  xAOD::IParticleContainer* inCont = evtStore()->tryRetrieve<xAOD::IParticleContainer>( m_inCollKey.value() );
152  if (inCont){ ATH_CHECK( this->doSort(inCont) ); }
153  else {
154  ATH_MSG_DEBUG("We couldn't retrieve a non-const version of the input container... try const.");
155  const xAOD::IParticleContainer* inCont2 = nullptr;
156  ATH_CHECK( evtStore()->retrieve( inCont2, m_inCollKey.value()) );
157  // Now, do the copy and sorting and overwriting of all known container types
158  if (false) {
159  }
172  else {
173  ATH_MSG_ERROR("Couln't find the provided intput container in store gate for later overwriting");
174  return StatusCode::FAILURE;
175  }
176  }
177  }
178  else {
179  ATH_MSG_DEBUG("Got a non-empty 'OutputCollection' property. "
180  << "Trying to retrieve a const version of the 'InputContainer'...");
181 
182  // Now, do the copy and sorting of all known container types
183  if (false) {
184  }
197  else {
198  ATH_MSG_ERROR("Couln't find the provided intput container in store gate");
199  return StatusCode::FAILURE;
200  }
201 
202  }
203 
204  return StatusCode::SUCCESS;
205 }
206 
207 
208 
210 {
211  if ( !cont ) {
212  ATH_MSG_ERROR("No container to be sorted");
213  return StatusCode::FAILURE;
214  }
215  // Actually do the sorting, using a C++11 lambda function construct
216  // to be able to use the member function here
217  if ( std::abs(m_sortID) == 1 ) {
218  cont->sort( [this](const xAOD::IParticle* a, const xAOD::IParticle* b) {
219  return this->comparePt(a,b);
220  } );
221  }
222  else if ( std::abs(m_sortID) == 2 ) {
223  cont->sort( [this](const xAOD::IParticle* a, const xAOD::IParticle* b) {
224  return this->compareEta(a,b);
225  } );
226  }
227  else if ( std::abs(m_sortID) == 3 ) {
228  cont->sort( [this](const xAOD::IParticle* a, const xAOD::IParticle* b) {
229  return this->comparePhi(a,b);
230  } );
231  }
232  else if ( std::abs(m_sortID) == 4 ) {
233  cont->sort( [this](const xAOD::IParticle* a, const xAOD::IParticle* b) {
234  return this->compareMass(a,b);
235  } );
236  }
237  else if ( std::abs(m_sortID) == 5 ) {
238  cont->sort( [this](const xAOD::IParticle* a, const xAOD::IParticle* b) {
239  return this->compareEnergy(a,b);
240  } );
241  }
242  else if ( std::abs(m_sortID) == 6 ) {
243  cont->sort( [this](const xAOD::IParticle* a, const xAOD::IParticle* b) {
244  return this->compareRapidity(a,b);
245  } );
246  }
247  else if ( std::abs(m_sortID) == 7 ) {
248  cont->sort( [this](const xAOD::IParticle* a, const xAOD::IParticle* b) {
249  return this->compareAuxData(a,b);
250  } );
251  }
252 
253  return StatusCode::SUCCESS;
254 }
255 
256 
258  const xAOD::IParticle* partB ) const
259 {
260  const double a = partA->pt();
261  const double b = partB->pt();
262  return this->compareDouble(a,b);
263 }
264 
265 
267  const xAOD::IParticle* partB ) const
268 {
269  const double a = partA->eta();
270  const double b = partB->eta();
271  return this->compareDouble(a,b);
272 }
273 
274 
276  const xAOD::IParticle* partB ) const
277 {
278  const double a = partA->phi();
279  const double b = partB->phi();
280  return this->compareDouble(a,b);
281 }
282 
283 
285  const xAOD::IParticle* partB ) const
286 {
287  const double a = partA->m();
288  const double b = partB->m();
289  return this->compareDouble(a,b);
290 }
291 
292 
294  const xAOD::IParticle* partB ) const
295 {
296  const double a = partA->e();
297  const double b = partB->e();
298  return this->compareDouble(a,b);
299 }
300 
301 
303  const xAOD::IParticle* partB ) const
304 {
305  const double a = partA->rapidity();
306  const double b = partB->rapidity();
307  return this->compareDouble(a,b);
308 }
309 
311  const xAOD::IParticle* partB ) const
312 {
313  SG::ConstAccessor<float> acc( this->m_sortVar.value() );
314  return this->compareDouble(acc(*partA),acc(*partB));
315 }
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
ParticleSortingTool::addBranches
virtual StatusCode addBranches() const final override
Implement the method from the ISkimmingTool interface.
Definition: ParticleSortingTool.cxx:139
ParticleSortingTool::~ParticleSortingTool
virtual ~ParticleSortingTool()
Destructor:
Definition: ParticleSortingTool.cxx:62
ParticleSortingTool::compareMass
bool compareMass(const xAOD::IParticle *partA, const xAOD::IParticle *partB) const
The method to compare the particle's mass.
Definition: ParticleSortingTool.cxx:284
ParticleSortingTool::compareAuxData
bool compareAuxData(const xAOD::IParticle *partA, const xAOD::IParticle *partB) const
The method to compare an auxdata member of the particle.
Definition: ParticleSortingTool.cxx:310
IParticle.h
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
ConstDataVector.h
DataVector adapter that acts like it holds const pointers.
ParticleSortingTool::m_outCollKey
StringProperty m_outCollKey
The name of the output container (with SG::VIEW_ELEMENTS) with the sorted copy of input objects.
Definition: ParticleSortingTool.h:105
AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T > &t)
Definition: AthCommonDataStore.h:145
ParticleSortingTool::m_sortID
int m_sortID
Internal identifier for the type of sorting.
Definition: ParticleSortingTool.h:115
TruthParticleContainer.h
ParticleSortingTool::m_sortVar
StringProperty m_sortVar
Define by what parameter to sort (default: 'pt')
Definition: ParticleSortingTool.h:108
xAOD::IParticle::rapidity
virtual double rapidity() const =0
The true rapidity (y) of the particle.
PFOContainer.h
COPY_AND_SORT_CONTAINER
#define COPY_AND_SORT_CONTAINER(CONTAINERTYPE)
Definition: ParticleSortingTool.cxx:111
ParticleSortingTool::comparePt
bool comparePt(const xAOD::IParticle *partA, const xAOD::IParticle *partB) const
The method to compare the particle's pt.
Definition: ParticleSortingTool.cxx:257
SG::ConstAccessor< float >
ParticleSortingTool::m_nEventsProcessed
std::atomic< unsigned long > m_nEventsProcessed
Internal event counter.
Definition: ParticleSortingTool.h:118
CompositeParticleContainer.h
xAOD::IParticle
Class providing the definition of the 4-vector interface.
Definition: Event/xAOD/xAODBase/xAODBase/IParticle.h:41
ParticleSortingTool::compareRapidity
bool compareRapidity(const xAOD::IParticle *partA, const xAOD::IParticle *partB) const
The method to compare the particle's rapidity.
Definition: ParticleSortingTool.cxx:302
ParticleSortingTool::initialize
virtual StatusCode initialize() override
Athena algtool's initialize.
Definition: ParticleSortingTool.cxx:69
ParticleSortingTool::comparePhi
bool comparePhi(const xAOD::IParticle *partA, const xAOD::IParticle *partB) const
The method to compare the particle's phi.
Definition: ParticleSortingTool.cxx:275
AthCommonDataStore< AthCommonMsg< AlgTool > >::evtStore
ServiceHandle< StoreGateSvc > & evtStore()
The standard StoreGateSvc (event store) Returns (kind of) a pointer to the StoreGateSvc.
Definition: AthCommonDataStore.h:85
ParticleSortingTool::compareEta
bool compareEta(const xAOD::IParticle *partA, const xAOD::IParticle *partB) const
The method to compare the particle's eta.
Definition: ParticleSortingTool.cxx:266
ParticleSortingTool::ParticleSortingTool
ParticleSortingTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
Definition: ParticleSortingTool.cxx:34
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
ElectronContainer.h
ParticleContainer.h
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
IParticleContainer.h
test_pyathena.parent
parent
Definition: test_pyathena.py:15
AthenaPoolTestRead.acc
acc
Definition: AthenaPoolTestRead.py:16
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
ParticleSortingTool::compareEnergy
bool compareEnergy(const xAOD::IParticle *partA, const xAOD::IParticle *partB) const
The method to compare the particle's energy.
Definition: ParticleSortingTool.cxx:293
ParticleSortingTool::m_sortDescending
BooleanProperty m_sortDescending
Define if the container should be sorted in a descending order (default=true)
Definition: ParticleSortingTool.h:111
TauJetContainer.h
DataVector
Derived DataVector<T>.
Definition: DataVector.h:794
xAOD::IParticle::pt
virtual double pt() const =0
The transverse momentum ( ) of the particle.
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
ParticleSortingTool.h
ParticleSortingTool::m_inCollKey
StringProperty m_inCollKey
Input container name.
Definition: ParticleSortingTool.h:102
ParticleSortingTool::compareDouble
bool compareDouble(double a, double b) const
Method to compare two doubles.
Definition: ParticleSortingTool.h:123
MuonContainer.h
NeutralParticleContainer.h
DataVector::sort
void sort()
Sort the container.
a
TList * a
Definition: liststreamerinfos.cxx:10
JetContainer.h
xAOD::IParticle::eta
virtual double eta() const =0
The pseudorapidity ( ) of the particle.
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
CaloClusterContainer.h
ParticleSortingTool::doSort
StatusCode doSort(xAOD::IParticleContainer *cont) const
Helper method that implements the call to the right sort function.
Definition: ParticleSortingTool.cxx:209
ParticleSortingTool::finalize
virtual StatusCode finalize() override
Athena algtool's finalize.
Definition: ParticleSortingTool.cxx:101
xAOD::IParticle::phi
virtual double phi() const =0
The azimuthal angle ( ) of the particle.
AthAlgTool
Definition: AthAlgTool.h:26
PhotonContainer.h
TrackParticleContainer.h
xAOD::IParticle::e
virtual double e() const =0
The total energy of the particle.
xAOD::IParticle::m
virtual double m() const =0
The invariant mass of the particle.
OVERWRITE_AND_SORT_CONTAINER
#define OVERWRITE_AND_SORT_CONTAINER(CONTAINERTYPE)
Definition: ParticleSortingTool.cxx:124