ATLAS Offline Software
DerivationKernel.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2017 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 tool service
85  IToolSvc* toolSvc;
86  StatusCode sc = service("ToolSvc",toolSvc);
87  if (StatusCode::SUCCESS != sc) {
88  ATH_MSG_FATAL("Unable to retrieve ToolSvc");
89  return StatusCode::FAILURE;
90  }
91 
92  // get the skimming tools
93  if( m_skimmingTools.retrieve().isFailure() ) {
94  ATH_MSG_FATAL("Failed to retrieve skimming tools");
95  return StatusCode::FAILURE;
96  } else {
97  ATH_MSG_INFO("The following skimming tools will be applied....");
98  ATH_MSG_INFO(m_skimmingTools);
99  }
100  // get the thinning tools
101  if( m_thinningTools.retrieve().isFailure() ) {
102  ATH_MSG_FATAL("Failed to retrieve thinning tools");
103  return StatusCode::FAILURE;
104  } else {
105  ATH_MSG_INFO("The following thinning tools will be applied");
106  ATH_MSG_INFO(m_thinningTools);
107  }
108  // get the augmentation tools
109  if( m_augmentationTools.retrieve().isFailure() ) {
110  ATH_MSG_FATAL("Failed to retrieve augmentation tools");
111  return StatusCode::FAILURE;
112  } else {
113  ATH_MSG_INFO("The following augmentation tools will be applied....");
114  ATH_MSG_INFO(m_augmentationTools);
115  }
116 
117  if (m_doChronoStat) {
118  //get the chrono auditor
119  ATH_CHECK(m_chronoSvc.retrieve());
120  }
121 
122  if (m_runSkimmingFirst) {
123  ATH_MSG_INFO("Skimming will be run before augmentation. Make sure your skimming does not depend on variables calculated in the augmentation step!");
124  }
125 
126  std::unordered_set<std::string> outputs;
127  std::vector<const DataObjID *> output_ids;
128  auto output_collector = [&outputs, &output_ids](IAlgTool *a_tool_interface) {
129  const AlgTool *alg_tool = dynamic_cast<AlgTool *>(a_tool_interface);
130  if (alg_tool) {
131  collectOutputs(outputs,output_ids, alg_tool);
132  }
133  };
134  auto renounce_and_collect_outputs = [&outputs, &output_ids](IAlgTool *a_tool_interface) {
135  AlgTool *alg_tool = dynamic_cast<AlgTool *>(a_tool_interface);
136  if (alg_tool) {
137  renounceInputs(outputs,output_ids, alg_tool);
138  collectOutputs(outputs,output_ids, alg_tool);
139  }
140  };
141  auto renouncer = [&outputs, &output_ids](IAlgTool *a_tool_interface) {
142  AlgTool *alg_tool = dynamic_cast<AlgTool *>(a_tool_interface);
143  if (alg_tool) {
144  renounceInputs(outputs,output_ids, alg_tool);
145  }
146  };
147 
148  // collection and renouncing has to happen in the order the tools are called
149  // during execute.
150  if (m_runSkimmingFirst) {
151  for (ToolHandle<ISkimmingTool> &a_tool_handle : m_skimmingTools ) {
152  visitTools(*a_tool_handle, output_collector);
153  }
154  for (ToolHandle<IAugmentationTool> &a_tool_handle : m_augmentationTools ) {
155  visitTools(*a_tool_handle, renounce_and_collect_outputs);
156  }
157  }
158  else {
159  for (ToolHandle<IAugmentationTool> &a_tool_handle : m_augmentationTools ) {
160  visitTools(*a_tool_handle, output_collector);
161  }
162  for (ToolHandle<ISkimmingTool> &a_tool_handle : m_skimmingTools ) {
163  visitTools(*a_tool_handle, renounce_and_collect_outputs);
164  }
165  }
166  for (ToolHandle<IThinningTool> &a_tool_handle : m_thinningTools ) {
167  visitTools(*a_tool_handle, renouncer);
168  }
169 
170 
171  return StatusCode::SUCCESS;
172 }
173 
174 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
175 
177 
178  IChronoSvc* cSvc=m_chronoSvc.get(); //Might be null ...
179  // On your marks.... get set.... (but only if not in MT)
180  Chrono chrono( cSvc , name() );
181  // GO!!!
182 
183  ATH_MSG_DEBUG(name() << " is processing next event...");
184 
185  // Increment the event counter
186  m_eventCounter++;
187 
188  //=============================================================================
189  // AUGMENTATION ===============================================================
190  //=============================================================================
191 
192  if (!m_runSkimmingFirst) {
193  ToolHandleArray<IAugmentationTool>::iterator augmentationTool(m_augmentationTools.begin());
194  ToolHandleArray<IAugmentationTool>::iterator endOfAugmentationTools(m_augmentationTools.end());
195  while (augmentationTool != endOfAugmentationTools) {
196  ATH_MSG_DEBUG("Entering " << (**augmentationTool).name());
197  if ( (**augmentationTool).addBranches().isFailure() ) {
198  ATH_MSG_ERROR("Augmentation failed!");
199  return StatusCode::FAILURE;
200  }
201  ++augmentationTool;
202  }
203  }
204 
205  //=============================================================================
206  //SKIMMING ===================================================================
207  //=============================================================================
208 
209  // Set master flag to true
210  bool acceptEvent(true);
211 
212  // Loop over the filters
214  ToolHandleArray<ISkimmingTool>::iterator endOfSkimmingTools(m_skimmingTools.end());
215  while (skimmingTool != endOfSkimmingTools) {
216  ATH_MSG_DEBUG("Entering " << (**skimmingTool).name());
217  if (!((**skimmingTool).eventPassesFilter())) {
218  acceptEvent=false;
219  ATH_MSG_DEBUG("This event failed the " << (**skimmingTool).name() << " filter. Therefore it will not be recorded.");
220  break;
221  }
222  ++skimmingTool;
223  }
224 
225  // Increment local counters if event to be accepted
226  if (acceptEvent) ++m_acceptCntr;
227 
228  // Set the setFilterPassed flag
229  setFilterPassed(acceptEvent);
230 
231  // Return if event didn't pass
232  if (!acceptEvent) return StatusCode::SUCCESS;
233 
234  // If user requested skimming first, run augmentation now...
235  if (m_runSkimmingFirst) {
236  ToolHandleArray<IAugmentationTool>::iterator augmentationTool(m_augmentationTools.begin());
237  ToolHandleArray<IAugmentationTool>::iterator endOfAugmentationTools(m_augmentationTools.end());
238  while (augmentationTool != endOfAugmentationTools) {
239  ATH_MSG_DEBUG("Entering " << (**augmentationTool).name());
240  if ( (**augmentationTool).addBranches().isFailure() ) {
241  ATH_MSG_ERROR("Augmentation failed!");
242  return StatusCode::FAILURE;
243  }
244  ++augmentationTool;
245  }
246  }
247 
248 
249  //=============================================================================
250  // THINNING ===================================================================
251  //=============================================================================
252 
253  ToolHandleArray<IThinningTool>::iterator thinningTool(m_thinningTools.begin());
254  ToolHandleArray<IThinningTool>::iterator endOfThinningTools(m_thinningTools.end());
255  while (thinningTool != endOfThinningTools) {
256  ATH_MSG_DEBUG("Entering " << (**thinningTool).name());
257  if ( (**thinningTool).doThinning().isFailure() ) {
258  ATH_MSG_ERROR("Thinning failed!");
259  return StatusCode::FAILURE;
260  }
261  ++thinningTool;
262  }
263 
264 
265  return StatusCode::SUCCESS;
266 
267 }
268 
269 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
270 
272 
273  ATH_MSG_INFO( "============================================================================");
274  ATH_MSG_INFO( "|| SUMMARY OF THE DERIVATION FRAMEWORK KERNEL WITH NAME " << name() << " || ");
275  ATH_MSG_INFO( "============================================================================");
276  ATH_MSG_INFO( "============================================================================");
277  ATH_MSG_INFO( "Events analyzed: " << m_eventCounter);
278  ATH_MSG_INFO( "Events accepted: " << m_acceptCntr);
279  ATH_MSG_INFO( "============================================================================");
280 
281  return StatusCode::SUCCESS;
282 
283 }
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:176
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
DerivationFramework::DerivationKernel::m_runSkimmingFirst
bool m_runSkimmingFirst
Definition: DerivationKernel.h:40
DataHandle.h
DerivationFramework::DerivationKernel::initialize
StatusCode initialize()
Definition: DerivationKernel.cxx:80
AthenaPoolTestRead.sc
sc
Definition: AthenaPoolTestRead.py:27
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:195
DataVector.h
An STL vector of pointers that by default owns its pointed-to elements.
HION12.skimmingTool
skimmingTool
Definition: HION12.py:65
DerivationFramework::DerivationKernel::m_acceptCntr
int m_acceptCntr
Definition: DerivationKernel.h:39
DerivationFramework::DerivationKernel::finalize
StatusCode finalize()
Definition: DerivationKernel.cxx:271
ATLAS_THREAD_SAFE
#define ATLAS_THREAD_SAFE
Definition: checker_macros.h:211
DefaultKey.h
StoreGateSvc.h