ATLAS Offline Software
ParticleRemoverAlg.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 // EventUtils includes
6 #include "ParticleRemoverAlg.h"
7 
10 
12 #include "xAODBase/IParticle.h"
14 #include "xAODCore/ShallowCopy.h"
17 #include "xAODMuon/MuonContainer.h"
19 #include "xAODJet/JetContainer.h"
20 #include "xAODPFlow/PFOContainer.h"
27 
28 ParticleRemoverAlg::ParticleRemoverAlg( const std::string& name, ISvcLocator* pSvcLocator )
29  : AthAlgorithm( name, pSvcLocator ),
30  m_inCont(""),
31  m_separator("___"),
32  m_outCont(""),
33  m_suffixes(),
34  m_viewContNames(),
35  m_resetViewConts(true),
36  m_outPrefix(""),
37  m_inContNameList(),
38  m_outContNameList(),
39  m_inContList(),
40  m_outContList(),
41  m_inViewContNameListList(),
42  m_outViewContNameListList(),
43  m_contType(UNKNOWN)
44 {
45  //
46  // Property declaration
47  //
48  declareProperty("Input", m_inCont, "Input container name" );
49  declareProperty("Output", m_outCont,
50  "The name of the output container with the deep copy of input objects" );
51 
52  declareProperty("Separator", m_separator,
53  "The string seperator between the output container name and the sytematic variation (default='___')" );
54 
55  declareProperty("Suffixes", m_suffixes,
56  "The names of all suffixes for the input and output container names" );
57 
58  declareProperty("SelectedViewContainers", m_viewContNames,
59  "The names of all view containers that contain particles that we want to retain" );
60 
61  declareProperty("RemapViewContainers", m_resetViewConts,
62  "Boolean to decide if the existing view containers should be re-mapped (default: true)" );
63 
64  declareProperty("OutputViewContainerPrefix", m_outPrefix,
65  "Prefix to be used for all created output view containers" );
66 }
67 
68 
70 
71 
73 {
74  ATH_MSG_DEBUG ("Initializing " << name() << "...");
75 
76  // Print the configuration to the log file
77  ATH_MSG_DEBUG( "Using: " << m_inCont );
78  ATH_MSG_DEBUG( "Using: " << m_outCont );
79  ATH_MSG_DEBUG( "Using: " << m_separator );
80  ATH_MSG_DEBUG( "Using: " << m_suffixes );
81  ATH_MSG_DEBUG( "Using: " << m_viewContNames );
82  ATH_MSG_DEBUG( "Using: " << m_resetViewConts );
83  ATH_MSG_DEBUG( "Using: " << m_outPrefix );
84 
85  // Perform some sanity checks on the given container names
86  if ( m_inCont.value().empty() || m_outCont.value().empty() || m_viewContNames.value().empty() ) {
87  ATH_MSG_ERROR("Wrong user setup! You need to give a valid name for both the Input, Output, and SelectedViewContainers!");
88  return StatusCode::FAILURE;
89  }
90 
91  // Abort on an unchecked systematics code
92  // StatusCode::enableFailure();
93 
94  // Build the vector of all input and output container names
95  const std::size_t totSize = 1 + m_suffixes.value().size(); // the '1' comes from the InputContainer
96  m_inContNameList.resize(totSize);
97  m_inContList.resize(totSize);
98  m_outContNameList.resize(totSize);
99  m_inContNameList[0] = m_inCont.value();
100  m_outContNameList[0] = m_outCont.value();
101  for ( std::size_t i=1; i<totSize; ++i ) {
102  const std::string& currentSuffix = m_suffixes.value()[i-1];
103  ATH_MSG_VERBOSE("Using current suffix " << currentSuffix << " to search for matching containers");
104  if ( currentSuffix.rfind( m_separator.value(),0 ) == 0 ) { // If the currentSuffix starts with m_separator.value()
105  m_inContNameList[i] = m_inCont.value() + currentSuffix;
106  m_outContNameList[i] = m_outCont.value() + currentSuffix;
107  }
108  else {
109  m_inContNameList[i] = m_inCont.value() + m_separator.value() + currentSuffix;
110  m_outContNameList[i] = m_outCont.value() + m_separator.value() + currentSuffix;
111  }
112  }
113  // Print out the matches that we found
114  if ( msgLvl(MSG::VERBOSE) ) {
115  for ( std::size_t i=0; i<m_inContNameList.size(); ++i ){
116  ATH_MSG_VERBOSE("Matched input number " << i << " with input name " << m_inContNameList[i] << " to output name " << m_outContNameList[i]);
117  }
118  }
119 
120 
121 
122  // Now, also try to map all the view container names to the input (shallow
123  // copy) containers. Set up with that the correct mapping of the new output
124  // view container names.
125  // Assume that all names where we have a suffix, but where we cannot match it
126  // to a suffix of the input container, it belongs to the origninal one.
127  if ( m_resetViewConts.value() || !(m_outPrefix.value().empty()) ){
128  ATH_MSG_VERBOSE("Going to iterate over " << totSize << " elements");
129  m_inViewContNameListList.reserve(totSize);
130  m_outViewContNameListList.reserve(totSize);
131  for ( std::size_t i=0; i<totSize; ++i ) {
132  ATH_MSG_VERBOSE("At " << i << "-th element");
133  if (i==0){
134  // This is the master container without any "___" in its name
135  std::vector<std::string> inViewNames;
136  std::vector<std::string> outViewNames;
137  for ( const std::string& inViewName : m_viewContNames.value() ){
138  ATH_MSG_VERBOSE("Looking at input view container name: " << inViewName);
139  std::size_t pos = inViewName.find(m_separator.value());
140  if ( pos == std::string::npos ){ // the separator is not found
141  ATH_MSG_VERBOSE("No seperator found");
142  inViewNames.push_back(inViewName);
143  outViewNames.push_back( m_outPrefix.value() + inViewName );
144  ATH_MSG_VERBOSE("Added input name " << inViewNames.back() << " and output name " << outViewNames.back());
145  }
146  else {
147  pos += m_separator.value().length();
148  const std::string foundSuffix = inViewName.substr(pos, std::string::npos);
149  ATH_MSG_VERBOSE("Seperator found and suffix found: " << foundSuffix);
150  // the separator is found, but the found suffix doesn't match any of the provided ones
151  if ( std::find( m_suffixes.value().begin(), m_suffixes.value().end(), foundSuffix) == m_suffixes.value().end() ){
152  inViewNames.push_back(inViewName);
153  outViewNames.push_back( m_outPrefix.value() + inViewName );
154  ATH_MSG_VERBOSE("Added2 input name " << inViewNames.back() << " and output name " << outViewNames.back());
155  }
156  }
157  }
158  m_inViewContNameListList.push_back(inViewNames);
159  m_outViewContNameListList.push_back(outViewNames);
160  }
161  else {
162  const std::string& currentSuffix = m_suffixes.value()[i-1];
163  ATH_MSG_VERBOSE("Looking at current suffix: " << currentSuffix);
164  std::vector<std::string> inViewNames;
165  std::vector<std::string> outViewNames;
166  for ( const std::string& inViewName : m_viewContNames.value() ){
167  ATH_MSG_VERBOSE("Looking at current input view container name: " << inViewName);
168  if ( inViewName.find(m_separator.value()+currentSuffix) != std::string::npos ){ // the suffix is found
169  inViewNames.push_back(inViewName);
170  outViewNames.push_back( m_outPrefix.value() + inViewName );
171  ATH_MSG_VERBOSE("Added3 input name " << inViewNames.back() << " and output name " << outViewNames.back());
172  }
173  }
174  m_inViewContNameListList.push_back(inViewNames);
175  m_outViewContNameListList.push_back(outViewNames);
176  }
177  } // End: loop over all containers
178  }
179  // Some sanity printouts
180  if ( msgLvl(MSG::VERBOSE) ) {
181  ATH_MSG_VERBOSE("Printing final input and output names...");
182  for ( std::size_t i=0; i<m_inViewContNameListList.size(); ++i ){
183  ATH_MSG_VERBOSE(" At i=" << i << "-th element");
184  const std::vector<std::string>& inViewNameList = m_inViewContNameListList[i];
185  const std::vector<std::string>& outViewNameList = m_outViewContNameListList[i];
186  ATH_MSG_VERBOSE(" Have " << inViewNameList.size() << " in view elements and " << outViewNameList.size() << " out view elements");
187  for ( std::size_t j=0; j<inViewNameList.size(); ++j ){
188  ATH_MSG_VERBOSE(" At j=" << j << "-th element");
189  const std::string& inName = inViewNameList[j];
190  const std::string& outName = outViewNameList[j];
191  ATH_MSG_VERBOSE(" Have input name " << inName << " paired with out name " << outName);
192  }
193  }
194  }
195 
196  return StatusCode::SUCCESS;
197 }
198 
199 
200 
202 {
203  ATH_MSG_DEBUG ("Finalizing " << name() << "...");
204 
205  return StatusCode::SUCCESS;
206 }
207 
208 
209 
211 {
212  ATH_MSG_DEBUG ("Executing " << name() << "...");
213  // Let's first clear some stuff
214  m_inContList.clear();
215  m_inContList.resize(m_inContNameList.size());
216  m_outContList.clear();
217 
218  // Figure out what type the input container has, if we didn't do it yet
219  if ( m_contType == UNKNOWN ){
220  if ( evtStore()->contains<xAOD::PhotonContainer>(m_inCont.value()) ){ m_contType = PHOTON; }
221  else if ( evtStore()->contains<xAOD::ElectronContainer>(m_inCont.value()) ){ m_contType = ELECTRON; }
222  else if ( evtStore()->contains<xAOD::MuonContainer>(m_inCont.value()) ){ m_contType = MUON; }
223  else if ( evtStore()->contains<xAOD::TauJetContainer>(m_inCont.value()) ){ m_contType = TAU; }
224  else if ( evtStore()->contains<xAOD::JetContainer>(m_inCont.value()) ){ m_contType = JET; }
225  else if ( evtStore()->contains<xAOD::TruthParticleContainer>(m_inCont.value()) ){ m_contType = TRUTHPARTICLE; }
226  else if ( evtStore()->contains<xAOD::CompositeParticleContainer>(m_inCont.value()) ){ m_contType = COMPOSITEPARTICLE; }
227  else if ( evtStore()->contains<xAOD::PFOContainer>(m_inCont.value()) ){ m_contType = PARITCLEFLOW; }
228  else if ( evtStore()->contains<xAOD::NeutralParticleContainer>(m_inCont.value()) ){ m_contType = NEUTRALPARTICLE; }
229  else if ( evtStore()->contains<xAOD::TrackParticleContainer>(m_inCont.value()) ){ m_contType = TRACKPARTICLE; }
230  else if ( evtStore()->contains<xAOD::ParticleContainer>(m_inCont.value()) ){ m_contType = PARTICLE; }
231  else if ( evtStore()->contains<xAOD::CaloClusterContainer>(m_inCont.value()) ){ m_contType = CALOCLUSTER; }
232  }
233  if ( m_contType == UNKNOWN ){
234  ATH_MSG_FATAL("We couldn't determine the type of the container... abort!");
235  return StatusCode::FAILURE;
236  }
237 
238  // Open the input container
239  for ( std::size_t i=0; i<m_inContNameList.size(); ++i ) {
241  }
242 
243  // Make a quick check that all input containers have the same size
244  const std::size_t inContSize = m_inContList[0]->size();
245  for ( const xAOD::IParticleContainer* inCont : m_inContList ){
246  if ( inContSize != inCont->size() ){
247  ATH_MSG_FATAL("The input container and its shallow copies don't have the same size! Aborting...");
248  return StatusCode::FAILURE;
249  }
250  }
251 
252  // Create a vector of bools with the same size as the input container. This
253  // will be used to say if we want to keep that particular object.
254  // All entries will be initialized to false.
255  std::vector<bool> keepParticleVec (inContSize, false);
256  // Now, loop over all view containers and flag the particles that we want to
257  // keep with true in the above vector of bools.
258  for ( const std::string& viewContName : m_viewContNames.value() ){
259  const xAOD::IParticleContainer* inViewCont = nullptr;
260  ATH_CHECK( evtStore()->retrieve( inViewCont, viewContName ) );
261  // Make a quick check that the provided view containers are not larger
262  if ( inViewCont->size() > inContSize ){
263  ATH_MSG_FATAL("One of the input view containers is larger than the input container... aborting.");
264  return StatusCode::FAILURE;
265  }
266  for ( const xAOD::IParticle* part : *inViewCont ){
267  const std::size_t idx = part->index();
268  keepParticleVec[idx] = true;
269  }
270  }
271 
272  // Do the heavy lifting of actually creating the new and reduced output container(s)
273  if ( m_contType == PHOTON ){
274  ATH_CHECK( this->removeParticles<xAOD::PhotonContainer>(keepParticleVec) );
275  }
276  else if ( m_contType == ELECTRON ){
277  ATH_CHECK( this->removeParticles<xAOD::ElectronContainer>(keepParticleVec) );
278  }
279  else if ( m_contType == MUON ){
280  ATH_CHECK( this->removeParticles<xAOD::MuonContainer>(keepParticleVec) );
281  }
282  else if ( m_contType == TAU ){
283  ATH_CHECK( this->removeParticles<xAOD::TauJetContainer>(keepParticleVec) );
284  }
285  else if ( m_contType == JET ){
286  ATH_CHECK( this->removeParticles<xAOD::JetContainer>(keepParticleVec) );
287  }
288  else if ( m_contType == TRUTHPARTICLE ){
289  ATH_CHECK( this->removeParticles<xAOD::TruthParticleContainer>(keepParticleVec) );
290  }
291  else if ( m_contType == COMPOSITEPARTICLE ){
292  ATH_CHECK( this->removeParticles<xAOD::CompositeParticleContainer>(keepParticleVec) );
293  }
294  else if ( m_contType == PARITCLEFLOW ){
295  ATH_CHECK( this->removeParticles<xAOD::PFOContainer>(keepParticleVec) );
296  }
297  else if ( m_contType == NEUTRALPARTICLE ){
298  ATH_CHECK( this->removeParticles<xAOD::NeutralParticleContainer>(keepParticleVec) );
299  }
300  else if ( m_contType == TRACKPARTICLE ){
301  ATH_CHECK( this->removeParticles<xAOD::TrackParticleContainer>(keepParticleVec) );
302  }
303  else if ( m_contType == PARTICLE ){
304  ATH_CHECK( this->removeParticles<xAOD::ParticleContainer>(keepParticleVec) );
305  }
306  else if ( m_contType == CALOCLUSTER ){
307  ATH_CHECK( this->removeParticles<xAOD::CaloClusterContainer>(keepParticleVec) );
308  }
309 
310  return StatusCode::SUCCESS;
311 }
LArG4FSStartPointFilter.part
part
Definition: LArG4FSStartPointFilter.py:21
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
ShallowCopy.h
python.StoreID.UNKNOWN
int UNKNOWN
Definition: StoreID.py:16
ParticleRemoverAlg::m_outContNameList
std::vector< std::string > m_outContNameList
Vector of all output container names.
Definition: ParticleRemoverAlg.h:72
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
ParticleRemoverAlg::PARITCLEFLOW
@ PARITCLEFLOW
Definition: ParticleRemoverAlg.h:95
IParticle.h
ParticleRemoverAlg::m_outViewContNameListList
std::vector< std::vector< std::string > > m_outViewContNameListList
Vector of all output view container names.
Definition: ParticleRemoverAlg.h:84
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
ParticleRemoverAlg::m_contType
contType_t m_contType
The variable that holds the value that we find for the input container.
Definition: ParticleRemoverAlg.h:105
AthCommonDataStore< AthCommonMsg< Algorithm > >::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T > &t)
Definition: AthCommonDataStore.h:145
TruthParticleContainer.h
ParticleRemoverAlg::m_suffixes
StringArrayProperty m_suffixes
The names of all suffixes for the input and output container names.
Definition: ParticleRemoverAlg.h:51
AuxContainerBase.h
ParticleRemoverAlg.h
PFOContainer.h
AthCommonMsg< Algorithm >::msgLvl
bool msgLvl(const MSG::Level lvl) const
Definition: AthCommonMsg.h:30
ParticleRemoverAlg::UNKNOWN
@ UNKNOWN
Definition: ParticleRemoverAlg.h:89
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
CompositeParticleContainer.h
xAOD::IParticle
Class providing the definition of the 4-vector interface.
Definition: Event/xAOD/xAODBase/xAODBase/IParticle.h:40
xAOD::Muon_v1
Class describing a Muon.
Definition: Muon_v1.h:38
ParticleRemoverAlg::PHOTON
@ PHOTON
Definition: ParticleRemoverAlg.h:90
ParticleRemoverAlg::NEUTRALPARTICLE
@ NEUTRALPARTICLE
Definition: ParticleRemoverAlg.h:96
ParticleRemoverAlg::COMPOSITEPARTICLE
@ COMPOSITEPARTICLE
Definition: ParticleRemoverAlg.h:99
AthCommonDataStore< AthCommonMsg< Algorithm > >::evtStore
ServiceHandle< StoreGateSvc > & evtStore()
The standard StoreGateSvc (event store) Returns (kind of) a pointer to the StoreGateSvc.
Definition: AthCommonDataStore.h:85
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
ElectronContainer.h
lumiFormat.i
int i
Definition: lumiFormat.py:92
ParticleRemoverAlg::TAU
@ TAU
Definition: ParticleRemoverAlg.h:93
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
ParticleRemoverAlg::m_resetViewConts
BooleanProperty m_resetViewConts
Boolean to decide if the existing view containers should be re-mapped (default: true)
Definition: ParticleRemoverAlg.h:57
ParticleRemoverAlg::m_viewContNames
StringArrayProperty m_viewContNames
The names of all view containers that contain particles that we want to retain.
Definition: ParticleRemoverAlg.h:54
ParticleRemoverAlg::m_inContNameList
std::vector< std::string > m_inContNameList
Vector of all input container names.
Definition: ParticleRemoverAlg.h:69
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
ParticleRemoverAlg::JET
@ JET
Definition: ParticleRemoverAlg.h:94
TauJetContainer.h
DataVector
Derived DataVector<T>.
Definition: DataVector.h:581
ParticleRemoverAlg::ELECTRON
@ ELECTRON
Definition: ParticleRemoverAlg.h:91
ParticleRemoverAlg::initialize
virtual StatusCode initialize()
Standard Gaudi initialize method called once before the event loop.
Definition: ParticleRemoverAlg.cxx:72
AthAlgorithm
Definition: AthAlgorithm.h:47
ParticleRemoverAlg::m_outCont
StringProperty m_outCont
The output container name.
Definition: ParticleRemoverAlg.h:48
TestSUSYToolsAlg.outName
string outName
Definition: TestSUSYToolsAlg.py:181
ParticleRemoverAlg::ParticleRemoverAlg
ParticleRemoverAlg(const std::string &name, ISvcLocator *pSvcLocator)
Standard constructor.
Definition: ParticleRemoverAlg.cxx:28
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
ParticleRemoverAlg::m_inViewContNameListList
std::vector< std::vector< std::string > > m_inViewContNameListList
Vector of all input view container names.
Definition: ParticleRemoverAlg.h:81
ParticleRemoverAlg::CALOCLUSTER
@ CALOCLUSTER
Definition: ParticleRemoverAlg.h:101
ParticleRemoverAlg::execute
virtual StatusCode execute()
Standard Gaudi execute method called once for every event.
Definition: ParticleRemoverAlg.cxx:210
python.LumiBlobConversion.pos
pos
Definition: LumiBlobConversion.py:18
MuonContainer.h
ParticleRemoverAlg::m_inContList
std::vector< const xAOD::IParticleContainer * > m_inContList
Vector of all input containers.
Definition: ParticleRemoverAlg.h:75
NeutralParticleContainer.h
JetContainer.h
IAuxTypeVectorFactory.h
Interface for factory objects that create vectors.
AuxTypeRegistry.h
Handle mappings between names and auxid_t.
ParticleRemoverAlg::PARTICLE
@ PARTICLE
Definition: ParticleRemoverAlg.h:100
LArNewCalib_DelayDump_OFC_Cali.idx
idx
Definition: LArNewCalib_DelayDump_OFC_Cali.py:69
CaloClusterContainer.h
ParticleRemoverAlg::m_outContList
std::vector< xAOD::IParticleContainer * > m_outContList
Vector of all output containers.
Definition: ParticleRemoverAlg.h:78
python.Constants.VERBOSE
int VERBOSE
Definition: Control/AthenaCommon/python/Constants.py:14
ParticleRemoverAlg::m_separator
StringProperty m_separator
The string separator between the output container name and the sytematic variation (default="___")
Definition: ParticleRemoverAlg.h:45
ParticleRemoverAlg::m_outPrefix
StringProperty m_outPrefix
Prefix to be used for all created output view containers.
Definition: ParticleRemoverAlg.h:60
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
PhotonContainer.h
ParticleRemoverAlg::TRACKPARTICLE
@ TRACKPARTICLE
Definition: ParticleRemoverAlg.h:97
TrackParticleContainer.h
ParticleRemoverAlg::MUON
@ MUON
Definition: ParticleRemoverAlg.h:92
ParticleRemoverAlg::~ParticleRemoverAlg
virtual ~ParticleRemoverAlg()
Standard destructor.
Definition: ParticleRemoverAlg.cxx:69
ParticleRemoverAlg::TRUTHPARTICLE
@ TRUTHPARTICLE
Definition: ParticleRemoverAlg.h:98
ParticleRemoverAlg::m_inCont
StringProperty m_inCont
The input container name.
Definition: ParticleRemoverAlg.h:42
ParticleRemoverAlg::finalize
virtual StatusCode finalize()
Standard Gaudi finalize method called once after the event loop.
Definition: ParticleRemoverAlg.cxx:201