ATLAS Offline Software
DerivationKernel.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 // DerivationKernel.cxx, (c) ATLAS Detector software
8 // Author: James Catmore (James.Catmore@cern.ch)
9 // Based on the Integrated Simulation Framework
10 // This code loops over tools defining skimming, slimming and thinning
11 // operations, sets the final filter decision, applies the overall slimming
12 // and thinning, and passes on to the persistency
13 
15 
16 #include <sstream> // C++ utilities
17 #include <string>
18 #include <algorithm>
19 #include <fstream>
20 
21 #include "GaudiKernel/ISvcLocator.h"
23 #include "AthLinks/ElementLink.h"
24 #include "GaudiKernel/AlgTool.h"
25 #include "GaudiKernel/Chrono.h"
26 #include "GaudiKernel/ToolVisitor.h"
27 #include "GaudiKernel/ConcurrencyFlags.h"
28 
29 #include "StoreGate/StoreGateSvc.h" // Storegate stuff
30 #include "StoreGate/DataHandle.h"
32 #include "SGTools/StlVectorClids.h"
33 
35 namespace {
36  inline void renounceInputs([[maybe_unused]] const std::unordered_set<std::string> &outputs, std::vector< const DataObjID *> &output_ids, AlgTool *a_tool) {
37  for ( const DataObjID *a_data_id : output_ids ) {
38  a_tool->renounceInput( *a_data_id );
39  }
40  }
41  inline void collectOutputs(std::unordered_set<std::string> &outputs, std::vector< const DataObjID *> &output_ids, const AlgTool *a_tool) {
42  for ( const DataObjID &a_data_id : a_tool->outputDataObjs() ) {
43  if (outputs.insert( a_data_id.key() ).second) {
44  output_ids.push_back( &a_data_id );
45  }
46  }
47  }
48  template <typename Callable, typename = std::enable_if_t<std::is_invocable_r_v<void, Callable, IAlgTool*>>>
49  inline void visitTools(IAlgTool &a_tool_interface, Callable &func) {
50  const AlgTool *alg_tool = dynamic_cast<AlgTool *>(&a_tool_interface);
51  if (alg_tool) {
52  func(&a_tool_interface);
53  std::vector<IAlgTool *> &non_const_tools ATLAS_THREAD_SAFE = const_cast< std::vector<IAlgTool *> &>( alg_tool->tools() );
54  ToolVisitor::visit( non_const_tools, func);
55  }
56  }
57 }
58 
59 DerivationFramework::DerivationKernel::DerivationKernel(const std::string& name, ISvcLocator* pSvcLocator) :
60 AthFilterAlgorithm(name, pSvcLocator),
61 m_chronoSvc("ChronoStatSvc", name),
62 m_runSkimmingFirst(false)
63 {
64  // ------- Python changeable properties -------
65  declareProperty("SkimmingTools", m_skimmingTools);
66  declareProperty("ThinningTools", m_thinningTools);
67  declareProperty("AugmentationTools", m_augmentationTools);
68  declareProperty("RunSkimmingFirst", m_runSkimmingFirst);
69  //declareProperty("PrintCutFlow", m_printCutFlow);
70  //declareProperty("PrintMemoryAndCPU", m_printMemCPU)
71  //---------------------------------------------
72 
73  // Counters
74  m_eventCounter = 0;
75  m_acceptCntr = 0;
76 }
77 
78 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
79 
81 
82  ATH_MSG_INFO("Initializing the derivation framework kernel " << name());
83 
84  // get the skimming tools
85  if( m_skimmingTools.retrieve().isFailure() ) {
86  ATH_MSG_FATAL("Failed to retrieve skimming tools");
87  return StatusCode::FAILURE;
88  } else {
89  ATH_MSG_INFO("The following skimming tools will be applied....");
90  ATH_MSG_INFO(m_skimmingTools);
91  }
92  // get the thinning tools
93  if( m_thinningTools.retrieve().isFailure() ) {
94  ATH_MSG_FATAL("Failed to retrieve thinning tools");
95  return StatusCode::FAILURE;
96  } else {
97  ATH_MSG_INFO("The following thinning tools will be applied");
98  ATH_MSG_INFO(m_thinningTools);
99  }
100  // get the augmentation tools
101  if( m_augmentationTools.retrieve().isFailure() ) {
102  ATH_MSG_FATAL("Failed to retrieve augmentation tools");
103  return StatusCode::FAILURE;
104  } else {
105  ATH_MSG_INFO("The following augmentation tools will be applied....");
106  ATH_MSG_INFO(m_augmentationTools);
107  }
108 
109  if (m_doChronoStat) {
110  //get the chrono auditor
111  ATH_CHECK(m_chronoSvc.retrieve());
112  }
113 
114  if (m_runSkimmingFirst) {
115  ATH_MSG_INFO("Skimming will be run before augmentation. Make sure your skimming does not depend on variables calculated in the augmentation step!");
116  }
117 
118  std::unordered_set<std::string> outputs;
119  std::vector<const DataObjID *> output_ids;
120  auto output_collector = [&outputs, &output_ids](IAlgTool *a_tool_interface) {
121  const AlgTool *alg_tool = dynamic_cast<AlgTool *>(a_tool_interface);
122  if (alg_tool) {
123  collectOutputs(outputs,output_ids, alg_tool);
124  }
125  };
126  auto renounce_and_collect_outputs = [&outputs, &output_ids](IAlgTool *a_tool_interface) {
127  AlgTool *alg_tool = dynamic_cast<AlgTool *>(a_tool_interface);
128  if (alg_tool) {
129  renounceInputs(outputs,output_ids, alg_tool);
130  collectOutputs(outputs,output_ids, alg_tool);
131  }
132  };
133  auto renouncer = [&outputs, &output_ids](IAlgTool *a_tool_interface) {
134  AlgTool *alg_tool = dynamic_cast<AlgTool *>(a_tool_interface);
135  if (alg_tool) {
136  renounceInputs(outputs,output_ids, alg_tool);
137  }
138  };
139 
140  // collection and renouncing has to happen in the order the tools are called
141  // during execute.
142  if (m_runSkimmingFirst) {
143  for (ToolHandle<ISkimmingTool> &a_tool_handle : m_skimmingTools ) {
144  visitTools(*a_tool_handle, output_collector);
145  }
146  for (ToolHandle<IAugmentationTool> &a_tool_handle : m_augmentationTools ) {
147  visitTools(*a_tool_handle, renounce_and_collect_outputs);
148  }
149  }
150  else {
151  for (ToolHandle<IAugmentationTool> &a_tool_handle : m_augmentationTools ) {
152  visitTools(*a_tool_handle, output_collector);
153  }
154  for (ToolHandle<ISkimmingTool> &a_tool_handle : m_skimmingTools ) {
155  visitTools(*a_tool_handle, renounce_and_collect_outputs);
156  }
157  }
158  for (ToolHandle<IThinningTool> &a_tool_handle : m_thinningTools ) {
159  visitTools(*a_tool_handle, renouncer);
160  }
161 
162 
163  return StatusCode::SUCCESS;
164 }
165 
166 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
167 
169 
170  IChronoSvc* cSvc=m_chronoSvc.get(); //Might be null ...
171  // On your marks.... get set.... (but only if not in MT)
172  Chrono chrono( cSvc , name() );
173  // GO!!!
174 
175  ATH_MSG_DEBUG(name() << " is processing next event...");
176 
177  // Increment the event counter
178  m_eventCounter++;
179 
180  //=============================================================================
181  // AUGMENTATION ===============================================================
182  //=============================================================================
183 
184  if (!m_runSkimmingFirst) {
185  ToolHandleArray<IAugmentationTool>::iterator augmentationTool(m_augmentationTools.begin());
186  ToolHandleArray<IAugmentationTool>::iterator endOfAugmentationTools(m_augmentationTools.end());
187  while (augmentationTool != endOfAugmentationTools) {
188  ATH_MSG_DEBUG("Entering " << (**augmentationTool).name());
189  if ( (**augmentationTool).addBranches().isFailure() ) {
190  ATH_MSG_ERROR("Augmentation failed!");
191  return StatusCode::FAILURE;
192  }
193  ++augmentationTool;
194  }
195  }
196 
197  //=============================================================================
198  //SKIMMING ===================================================================
199  //=============================================================================
200 
201  // Set master flag to true
202  bool acceptEvent(true);
203 
204  // Loop over the filters
206  ToolHandleArray<ISkimmingTool>::iterator endOfSkimmingTools(m_skimmingTools.end());
207  while (skimmingTool != endOfSkimmingTools) {
208  ATH_MSG_DEBUG("Entering " << (**skimmingTool).name());
209  if (!((**skimmingTool).eventPassesFilter())) {
210  acceptEvent=false;
211  ATH_MSG_DEBUG("This event failed the " << (**skimmingTool).name() << " filter. Therefore it will not be recorded.");
212  break;
213  }
214  ++skimmingTool;
215  }
216 
217  // Increment local counters if event to be accepted
218  if (acceptEvent) ++m_acceptCntr;
219 
220  // Set the setFilterPassed flag
221  setFilterPassed(acceptEvent);
222 
223  // Return if event didn't pass
224  if (!acceptEvent) return StatusCode::SUCCESS;
225 
226  // If user requested skimming first, run augmentation now...
227  if (m_runSkimmingFirst) {
228  ToolHandleArray<IAugmentationTool>::iterator augmentationTool(m_augmentationTools.begin());
229  ToolHandleArray<IAugmentationTool>::iterator endOfAugmentationTools(m_augmentationTools.end());
230  while (augmentationTool != endOfAugmentationTools) {
231  ATH_MSG_DEBUG("Entering " << (**augmentationTool).name());
232  if ( (**augmentationTool).addBranches().isFailure() ) {
233  ATH_MSG_ERROR("Augmentation failed!");
234  return StatusCode::FAILURE;
235  }
236  ++augmentationTool;
237  }
238  }
239 
240 
241  //=============================================================================
242  // THINNING ===================================================================
243  //=============================================================================
244 
245  ToolHandleArray<IThinningTool>::iterator thinningTool(m_thinningTools.begin());
246  ToolHandleArray<IThinningTool>::iterator endOfThinningTools(m_thinningTools.end());
247  while (thinningTool != endOfThinningTools) {
248  ATH_MSG_DEBUG("Entering " << (**thinningTool).name());
249  if ( (**thinningTool).doThinning().isFailure() ) {
250  ATH_MSG_ERROR("Thinning failed!");
251  return StatusCode::FAILURE;
252  }
253  ++thinningTool;
254  }
255 
256 
257  return StatusCode::SUCCESS;
258 
259 }
260 
261 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
262 
264 
265  ATH_MSG_INFO( "============================================================================");
266  ATH_MSG_INFO( "|| SUMMARY OF THE DERIVATION FRAMEWORK KERNEL WITH NAME " << name() << " || ");
267  ATH_MSG_INFO( "============================================================================");
268  ATH_MSG_INFO( "============================================================================");
269  ATH_MSG_INFO( "Events analyzed: " << m_eventCounter);
270  ATH_MSG_INFO( "Events accepted: " << m_acceptCntr);
271  ATH_MSG_INFO( "============================================================================");
272 
273  return StatusCode::SUCCESS;
274 
275 }
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
DerivationFramework::DerivationKernel::m_skimmingTools
ToolHandleArray< ISkimmingTool > m_skimmingTools
Definition: DerivationKernel.h:32
DerivationFramework::DerivationKernel::execute
StatusCode execute()
Definition: DerivationKernel.cxx:168
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
AthCommonDataStore< AthCommonMsg< Algorithm > >::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T > &t)
Definition: AthCommonDataStore.h:145
python.HION12.skimmingTool
skimmingTool
Definition: HION12.py:64
DerivationFramework::DerivationKernel::m_runSkimmingFirst
bool m_runSkimmingFirst
Definition: DerivationKernel.h:40
DataHandle.h
DerivationFramework::DerivationKernel::initialize
StatusCode initialize()
Definition: DerivationKernel.cxx:80
DerivationFramework::DerivationKernel::DerivationKernel
DerivationKernel(const std::string &name, ISvcLocator *pSvcLocator)
Definition: DerivationKernel.cxx:59
AthFilterAlgorithm
Definition: AthFilterAlgorithm.h:26
StlVectorClids.h
DerivationKernel.h
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
DerivationFramework::DerivationKernel::m_augmentationTools
ToolHandleArray< IAugmentationTool > m_augmentationTools
Definition: DerivationKernel.h:34
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
DerivationFramework::DerivationKernel::m_eventCounter
int m_eventCounter
Definition: DerivationKernel.h:38
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
DerivationFramework::DerivationKernel::m_thinningTools
ToolHandleArray< IThinningTool > m_thinningTools
Definition: DerivationKernel.h:33
python.CreateTierZeroArgdict.outputs
outputs
Definition: CreateTierZeroArgdict.py:189
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
DataVector.h
An STL vector of pointers that by default owns its pointed-to elements.
DerivationFramework::DerivationKernel::m_acceptCntr
int m_acceptCntr
Definition: DerivationKernel.h:39
DerivationFramework::DerivationKernel::finalize
StatusCode finalize()
Definition: DerivationKernel.cxx:263
ATLAS_THREAD_SAFE
#define ATLAS_THREAD_SAFE
Definition: checker_macros.h:211
DefaultKey.h
StoreGateSvc.h