ATLAS Offline Software
Loading...
Searching...
No Matches
ParticleSelectionAlg.icc
Go to the documentation of this file.
1// Dear emacs, this is -*- c++ -*-
2
3/*
4 Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
5*/
6
7
8#include "xAODBase/IParticle.h"
9#include "xAODCore/AuxContainerBase.h"
10#include "AthContainers/ConstDataVector.h"
11#include "xAODEventInfo/EventInfo.h"
12#include "xAODCutFlow/CutBookkeeperContainer.h"
13#include "PATCore/AcceptInfo.h"
14#include "PATCore/AcceptData.h"
15
16
17
18template<class CONT, class AUXCONT>
19StatusCode ParticleSelectionAlg::selectParticles(const xAOD::IParticleContainer* inContainer,
20 const std::vector<int>& resultVec) const
21{
22 ATH_MSG_DEBUG ("selectParticlesStepTwo<CONT,AUXCONT>(...) " << name() << "...");
23
24 // Get the type of particle that the current container CONT has
25 typedef typename CONT::base_value_type PART;
26
27 // Create a new output container and its associated auxiliary container
28 CONT* outCont = nullptr;
29 ConstDataVector<CONT>* outContConst = nullptr;
30
31 if ( m_outOwnPolicy == SG::OWN_ELEMENTS ) {
32 outCont = new CONT( m_outOwnPolicy );
33 ATH_CHECK( evtStore()->record ( outCont, m_outCollKey.value() ) );
34 if ( m_writeSplitAux.value() ) {
35 xAOD::AuxContainerBase* outAuxContainer = new xAOD::AuxContainerBase();
36 ATH_CHECK( evtStore()->record( outAuxContainer, m_outCollKey.value() + "Aux." ) );
37 outCont->setStore( outAuxContainer );
38 ATH_MSG_VERBOSE("Recorded xAOD::AuxContainerBase for container: " << m_outCollKey.value() );
39 }
40 else {
41 AUXCONT* outAuxContainer = new AUXCONT();
42 ATH_CHECK( evtStore()->record( outAuxContainer, m_outCollKey.value() + "Aux." ) );
43 outCont->setStore( outAuxContainer );
44 ATH_MSG_VERBOSE("Recorded AuxContainer for container: " << m_outCollKey.value() );
45 }
46 }
47 else {
48 outContConst = new ConstDataVector<CONT>( m_outOwnPolicy );
49 ATH_CHECK( evtStore()->record ( outContConst, m_outCollKey.value() ) );
50 ATH_MSG_VERBOSE("Recorded ConstDataVector for container: " << m_outCollKey.value() );
51 }
52 // ATH_MSG_VERBOSE("StoreGate dump: " << evtStore()->dump() );
53
54 // Get the CutBookkeeperContainer, if cut-flow bookkeeping was requested
55 double eventWeight = 1.0;
56 xAOD::CutBookkeeperContainer* cutBKCont = nullptr;
57 const xAOD::EventInfo* evtInfo = nullptr;
58 if (m_doCutFlow){
59 ATH_CHECK( outputMetaStore()->retrieve(cutBKCont, m_cutBKCName.value() ) );
60 // Also, get the event info as we need to get the MC-weight for this event
61 ATH_CHECK( evtStore()->retrieve( evtInfo, m_evtInfoName.value() ));
62 const bool isSim = evtInfo->eventType(xAOD::EventInfo::EventType::IS_SIMULATION);
63 if (isSim){
64 eventWeight = static_cast<double>( evtInfo->mcEventWeight() );
65 ATH_MSG_VERBOSE("Got MC event weight of " << eventWeight );
66 }
67 }
68
69
70 // Now, loop over the input container and check which particles to write out
71 ATH_MSG_DEBUG("Input container has size " << inContainer->size() );
72 for ( std::size_t i=0; i<inContainer->size(); ++i ) {
73 const xAOD::IParticle* partBase = inContainer->at(i);
74 const PART* part = static_cast<const PART*>(partBase);
75
76 // ================================
77 // Apply the selection tools
78 // ================================
79 // The default object pass value. As soon as one cut is not passed, then
80 // the remainder of the cuts will not even be tried
81 bool passEverything = true;
82
83 //------------- for the AsgSelectionTools --------------
84 // Loop over all selection tools
85 ATH_MSG_VERBOSE("Loop over all selection tools");
86 for ( std::size_t toolIdx=0; toolIdx < m_selTools.size(); ++toolIdx ){
87 if (passEverything){
88 ATH_MSG_VERBOSE("Now going to try AsgSelectionTools number " << toolIdx );
89 const asg::AcceptData acceptData = m_selTools[toolIdx]->accept(part);
90 if (!m_doCutFlow){ passEverything &= static_cast<bool>(acceptData); }
91 else {
92 const std::size_t cbkStartIdx = m_selToolIdxOffset[toolIdx];
93 const unsigned int nCuts = acceptData.getNCuts();
94 for ( unsigned int iCut=0; iCut<nCuts; ++iCut ){
95 passEverything &= acceptData.getCutResult(iCut);
96 if (passEverything){
97 const std::size_t currentCBKIdx = cbkStartIdx + iCut;
98 xAOD::CutBookkeeper* cutBK = cutBKCont->at(currentCBKIdx);
99 cutBK->addNAcceptedEvents(1);
100 cutBK->addSumOfEventWeights(eventWeight);
101 cutBK->addSumOfEventWeightsSquared(eventWeight*eventWeight);
102 }
103 }
104 } // Done doing detailed particle cut-flow for this tool
105 ATH_MSG_VERBOSE("AsgSelectionTools number " << toolIdx << " passed/failed: " << passEverything );
106 }
107 }
108
109 //------------- for the ExpressionParsing in this algorithm --------------
110 ATH_MSG_VERBOSE("Looking at expression parser result: " << passEverything);
111 if ( passEverything && !(resultVec.empty()) ){
112 // If this particle is not accepted by the expression parser, go to the next one
113 ATH_MSG_VERBOSE("Now going to try expression '" << m_selection.value() << "'" );
114 passEverything &= static_cast<bool>(resultVec.at(i));
115 ATH_MSG_VERBOSE("Expression '" << m_selection.value() << "' passed/failed: " << passEverything
116 << ", particle index=" << part->index() <<", pt=" << 0.001*(part->pt()) << " GeV, eta="
117 << part->eta() << ", phi=" << part->phi() );
118 if (passEverything && m_doCutFlow){
119 xAOD::CutBookkeeper* cutBK = cutBKCont->at(m_idxSelParster);
120 cutBK->addNAcceptedEvents(1);
121 cutBK->addSumOfEventWeights(eventWeight);
122 cutBK->addSumOfEventWeightsSquared(eventWeight*eventWeight);
123 }
124 }
125
126 // Now, if all cuts are passed, write out the current particle to the
127 // output container
128 if (passEverything){
129 ATH_MSG_VERBOSE("Going to fill output container with particle with pt=" << 0.001*(part->pt())
130 << " GeV, eta=" << part->eta() );
131 if ( m_outOwnPolicy == SG::OWN_ELEMENTS ) {
132 PART* newPart = new PART();
133 outCont->push_back(newPart);
134 *newPart = *part;
135 }
136 else {
137 outContConst->push_back(part);
138 }
139 }
140
141 } // End: Loop over input particles
142
143 return StatusCode::SUCCESS;
144}