ATLAS Offline Software
ParticleSortingTool.cxx
Go to the documentation of this file.
1 
3 /*
4  Copyright (C) 2002-2025 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 {
39  declareInterface< DerivationFramework::IAugmentationTool >(this);
40 }
41 
42 
43 // Destructor
46 {}
47 
48 
49 
50 // Athena algtool's Hooks
53 {
54  ATH_MSG_DEBUG ("Initializing " << name() << "...");
55 
56  // Print out the used configuration
57  ATH_MSG_DEBUG ( " using = " << m_inCollKey );
58  ATH_MSG_DEBUG ( " using = " << m_outCollKey );
59 
60  // initialize the counters
61  m_sortID = 0;
63 
64  // Figure out how to sort
65  if ( m_sortVar.value() == "pt" ) { m_sortID = 1; }
66  else if ( m_sortVar.value() == "eta" ) { m_sortID = 2; }
67  else if ( m_sortVar.value() == "phi" ) { m_sortID = 3; }
68  else if ( m_sortVar.value() == "m" ) { m_sortID = 4; }
69  else if ( m_sortVar.value() == "e" ) { m_sortID = 5; }
70  else if ( m_sortVar.value() == "rapidity" ) { m_sortID = 6; }
71  else {
72  ATH_MSG_INFO("Didn't find a valid value for SortVariable=" << m_sortVar.value() << "."
73  << " Assuming it's an auxdata member");
74  m_sortID = 7;
75  }
76  if ( m_sortDescending.value() ) { m_sortID *= -1; }
77 
78  return StatusCode::SUCCESS;
79 }
80 
81 
82 
83 
85 {
86  ATH_MSG_DEBUG ("Finalizing " << name() << "...");
87 
88  return StatusCode::SUCCESS;
89 }
90 
91 
92 
93 // Declare a short pre-processor macro to deal with the different container types
94 #define COPY_AND_SORT_CONTAINER( CONTAINERTYPE ) \
95 else if ( evtStore()->contains<CONTAINERTYPE>( m_inCollKey.value() ) ) { \
96  ATH_MSG_DEBUG("Trying to copy, sort, and record container of type "#CONTAINERTYPE ); \
97  const CONTAINERTYPE* inCont; \
98  ATH_CHECK( evtStore()->retrieve( inCont, m_inCollKey.value() ) ); \
99  CONTAINERTYPE* outCont = new CONTAINERTYPE( SG::VIEW_ELEMENTS ); \
100  *outCont = *inCont; \
101  ATH_CHECK( evtStore()->record ( outCont, m_outCollKey.value() ) ); \
102  ATH_CHECK( this->doSort(outCont) ); \
103 }
104 
105 
106 // Declare a short pre-processor macro to deal with the different container types
107 #define OVERWRITE_AND_SORT_CONTAINER( CONTAINERTYPE ) \
108 else if ( evtStore()->contains<CONTAINERTYPE>( m_inCollKey.value() ) ) { \
109  ATH_MSG_DEBUG("Trying to copy, sort, and overwrite container of type "#CONTAINERTYPE ); \
110  const CONTAINERTYPE* inCont; \
111  ATH_CHECK( evtStore()->retrieve( inCont, m_inCollKey.value() ) ); \
112  ConstDataVector<CONTAINERTYPE>* outCont = new ConstDataVector<CONTAINERTYPE>( SG::VIEW_ELEMENTS ); \
113  for ( const CONTAINERTYPE::base_value_type* inPart : *inCont ){ \
114  outCont->push_back(inPart); \
115  } \
116  ATH_CHECK( evtStore()->overwrite( outCont, m_inCollKey.value() ) ); \
117  ATH_CHECK( this->doSortConst<CONTAINERTYPE>(outCont) ); \
118 }
119 
120 
121 
123 {
124  // Increase the event counter
126 
127  // Simple status message at the beginning of each event execute,
128  ATH_MSG_DEBUG ( "==> addBranches " << name() << " on " << m_nEventsProcessed << ". event..." );
129 
130  if ( m_outCollKey.value().empty() ) {
131  // Try to get the input container as non-const
132  ATH_MSG_DEBUG("Got an empty 'OutputCollection' property. "
133  << "Trying to retrieve a non-const version of the 'InputContainer'...");
134  xAOD::IParticleContainer* inCont = evtStore()->tryRetrieve<xAOD::IParticleContainer>( m_inCollKey.value() );
135  if (inCont){ ATH_CHECK( this->doSort(inCont) ); }
136  else {
137  ATH_MSG_DEBUG("We couldn't retrieve a non-const version of the input container... try const.");
138  const xAOD::IParticleContainer* inCont2 = nullptr;
139  ATH_CHECK( evtStore()->retrieve( inCont2, m_inCollKey.value()) );
140  // Now, do the copy and sorting and overwriting of all known container types
141  if (false) {
142  }
155  else {
156  ATH_MSG_ERROR("Couln't find the provided intput container in store gate for later overwriting");
157  return StatusCode::FAILURE;
158  }
159  }
160  }
161  else {
162  ATH_MSG_DEBUG("Got a non-empty 'OutputCollection' property. "
163  << "Trying to retrieve a const version of the 'InputContainer'...");
164 
165  // Now, do the copy and sorting of all known container types
166  if (false) {
167  }
180  else {
181  ATH_MSG_ERROR("Couln't find the provided intput container in store gate");
182  return StatusCode::FAILURE;
183  }
184 
185  }
186 
187  return StatusCode::SUCCESS;
188 }
189 
190 
191 
193 {
194  if ( !cont ) {
195  ATH_MSG_ERROR("No container to be sorted");
196  return StatusCode::FAILURE;
197  }
198  // Actually do the sorting, using a C++11 lambda function construct
199  // to be able to use the member function here
200  if ( std::abs(m_sortID) == 1 ) {
201  cont->sort( [this](const xAOD::IParticle* a, const xAOD::IParticle* b) {
202  return this->comparePt(a,b);
203  } );
204  }
205  else if ( std::abs(m_sortID) == 2 ) {
206  cont->sort( [this](const xAOD::IParticle* a, const xAOD::IParticle* b) {
207  return this->compareEta(a,b);
208  } );
209  }
210  else if ( std::abs(m_sortID) == 3 ) {
211  cont->sort( [this](const xAOD::IParticle* a, const xAOD::IParticle* b) {
212  return this->comparePhi(a,b);
213  } );
214  }
215  else if ( std::abs(m_sortID) == 4 ) {
216  cont->sort( [this](const xAOD::IParticle* a, const xAOD::IParticle* b) {
217  return this->compareMass(a,b);
218  } );
219  }
220  else if ( std::abs(m_sortID) == 5 ) {
221  cont->sort( [this](const xAOD::IParticle* a, const xAOD::IParticle* b) {
222  return this->compareEnergy(a,b);
223  } );
224  }
225  else if ( std::abs(m_sortID) == 6 ) {
226  cont->sort( [this](const xAOD::IParticle* a, const xAOD::IParticle* b) {
227  return this->compareRapidity(a,b);
228  } );
229  }
230  else if ( std::abs(m_sortID) == 7 ) {
231  cont->sort( [this](const xAOD::IParticle* a, const xAOD::IParticle* b) {
232  return this->compareAuxData(a,b);
233  } );
234  }
235 
236  return StatusCode::SUCCESS;
237 }
238 
239 
241  const xAOD::IParticle* partB ) const
242 {
243  const double a = partA->pt();
244  const double b = partB->pt();
245  return this->compareDouble(a,b);
246 }
247 
248 
250  const xAOD::IParticle* partB ) const
251 {
252  const double a = partA->eta();
253  const double b = partB->eta();
254  return this->compareDouble(a,b);
255 }
256 
257 
259  const xAOD::IParticle* partB ) const
260 {
261  const double a = partA->phi();
262  const double b = partB->phi();
263  return this->compareDouble(a,b);
264 }
265 
266 
268  const xAOD::IParticle* partB ) const
269 {
270  const double a = partA->m();
271  const double b = partB->m();
272  return this->compareDouble(a,b);
273 }
274 
275 
277  const xAOD::IParticle* partB ) const
278 {
279  const double a = partA->e();
280  const double b = partB->e();
281  return this->compareDouble(a,b);
282 }
283 
284 
286  const xAOD::IParticle* partB ) const
287 {
288  const double a = partA->rapidity();
289  const double b = partB->rapidity();
290  return this->compareDouble(a,b);
291 }
292 
294  const xAOD::IParticle* partB ) const
295 {
296  SG::ConstAccessor<float> acc( this->m_sortVar.value() );
297  return this->compareDouble(acc(*partA),acc(*partB));
298 }
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:122
ParticleSortingTool::~ParticleSortingTool
virtual ~ParticleSortingTool()
Destructor:
Definition: ParticleSortingTool.cxx:45
ParticleSortingTool::compareMass
bool compareMass(const xAOD::IParticle *partA, const xAOD::IParticle *partB) const
The method to compare the particle's mass.
Definition: ParticleSortingTool.cxx:267
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:293
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
ParticleSortingTool::m_sortID
int m_sortID
Internal identifier for the type of sorting.
Definition: ParticleSortingTool.h:114
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:94
ParticleSortingTool::comparePt
bool comparePt(const xAOD::IParticle *partA, const xAOD::IParticle *partB) const
The method to compare the particle's pt.
Definition: ParticleSortingTool.cxx:240
SG::ConstAccessor< float >
ParticleSortingTool::m_nEventsProcessed
std::atomic< unsigned long > m_nEventsProcessed
Internal event counter.
Definition: ParticleSortingTool.h:117
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:285
ParticleSortingTool::initialize
virtual StatusCode initialize() override
Athena algtool's initialize.
Definition: ParticleSortingTool.cxx:52
python.CaloAddPedShiftConfig.type
type
Definition: CaloAddPedShiftConfig.py:42
ParticleSortingTool::comparePhi
bool comparePhi(const xAOD::IParticle *partA, const xAOD::IParticle *partB) const
The method to compare the particle's phi.
Definition: ParticleSortingTool.cxx:258
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:249
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:276
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:240
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:76
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:122
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.
CaloClusterContainer.h
ParticleSortingTool::doSort
StatusCode doSort(xAOD::IParticleContainer *cont) const
Helper method that implements the call to the right sort function.
Definition: ParticleSortingTool.cxx:192
ParticleSortingTool::finalize
virtual StatusCode finalize() override
Athena algtool's finalize.
Definition: ParticleSortingTool.cxx:84
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:107