ATLAS Offline Software
Loading...
Searching...
No Matches
DerivationKernel.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
6// DerivationKernel.cxx
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
33
35namespace {
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
59DerivationFramework::DerivationKernel::DerivationKernel(const std::string& name, ISvcLocator* pSvcLocator) :
60 AthFilterAlgorithm(name, pSvcLocator)
61{
62}
63
64// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
65
67
68 ATH_MSG_INFO("Initializing the derivation framework kernel " << name());
69
70 // get the skimming tools
71 ATH_CHECK( m_skimmingTools.retrieve() );
72 ATH_MSG_INFO("The following skimming tools will be applied....");
74
75 // get the thinning tools
76 ATH_CHECK( m_thinningTools.retrieve() );
77 ATH_MSG_INFO("The following thinning tools will be applied");
79
80 // get the augmentation tools
81 ATH_CHECK( m_augmentationTools.retrieve() );
82 ATH_MSG_INFO("The following augmentation tools will be applied....");
84
85 if (m_doChronoStat) {
86 //get the chrono auditor
87 ATH_CHECK(m_chronoSvc.retrieve());
88 }
89
91 ATH_MSG_INFO("Skimming will be run before augmentation. Make sure your skimming does not depend on variables calculated in the augmentation step!");
92 }
93
94 std::unordered_set<std::string> outputs;
95 std::vector<const DataObjID *> output_ids;
96 auto output_collector = [&outputs, &output_ids](IAlgTool *a_tool_interface) {
97 const AlgTool *alg_tool = dynamic_cast<AlgTool *>(a_tool_interface);
98 if (alg_tool) {
99 collectOutputs(outputs,output_ids, alg_tool);
100 }
101 };
102 auto renounce_and_collect_outputs = [&outputs, &output_ids](IAlgTool *a_tool_interface) {
103 AlgTool *alg_tool = dynamic_cast<AlgTool *>(a_tool_interface);
104 if (alg_tool) {
105 renounceInputs(outputs,output_ids, alg_tool);
106 collectOutputs(outputs,output_ids, alg_tool);
107 }
108 };
109 auto renouncer = [&outputs, &output_ids](IAlgTool *a_tool_interface) {
110 AlgTool *alg_tool = dynamic_cast<AlgTool *>(a_tool_interface);
111 if (alg_tool) {
112 renounceInputs(outputs,output_ids, alg_tool);
113 }
114 };
115
116 // collection and renouncing has to happen in the order the tools are called
117 // during execute.
118 if (m_runSkimmingFirst) {
119 for (ToolHandle<ISkimmingTool> &a_tool_handle : m_skimmingTools ) {
120 visitTools(*a_tool_handle, output_collector);
121 }
122 for (ToolHandle<IAugmentationTool> &a_tool_handle : m_augmentationTools ) {
123 visitTools(*a_tool_handle, renounce_and_collect_outputs);
124 }
125 }
126 else {
127 for (ToolHandle<IAugmentationTool> &a_tool_handle : m_augmentationTools ) {
128 visitTools(*a_tool_handle, output_collector);
129 }
130 for (ToolHandle<ISkimmingTool> &a_tool_handle : m_skimmingTools ) {
131 visitTools(*a_tool_handle, renounce_and_collect_outputs);
132 }
133 }
134 for (ToolHandle<IThinningTool> &a_tool_handle : m_thinningTools ) {
135 visitTools(*a_tool_handle, renouncer);
136 }
137
138 return StatusCode::SUCCESS;
139
140}
141
142// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
143
145
146 IChronoSvc* cSvc=m_chronoSvc.get(); //Might be null ...
147 // On your marks.... get set.... (but only if not in MT)
148 Chrono chrono( cSvc , name() );
149 // GO!!!
150
151 ATH_MSG_DEBUG(name() << " is processing next event...");
152
153 // Increment the event counter
155
156 //=============================================================================
157 // AUGMENTATION ===============================================================
158 //=============================================================================
159 const EventContext &ctx = Gaudi::Hive::currentContext();
160 if (!m_runSkimmingFirst) {
161 for (const auto & augmentationTool : m_augmentationTools) {
162 ATH_MSG_DEBUG("Entering " << augmentationTool->name());
163 if ( augmentationTool->addBranches(ctx).isFailure() ) {
164 ATH_MSG_ERROR("Augmentation failed!");
165 return StatusCode::FAILURE;
166 }
167 }
168 }
169
170 //=============================================================================
171 //SKIMMING ===================================================================
172 //=============================================================================
173
174 // Set master flag to true
175 bool acceptEvent(true);
176
177 // Loop over the filters
178 for (const auto & skimmingTool : m_skimmingTools) {
179 ATH_MSG_DEBUG("Entering " << skimmingTool->name());
180 if (!(skimmingTool->eventPassesFilter())) {
181 acceptEvent=false;
182 ATH_MSG_DEBUG("This event failed the " << skimmingTool->name() << " filter. Therefore it will not be recorded.");
183 break;
184 }
185 }
186
187 // Increment local counters if event to be accepted
188 if (acceptEvent) ++m_acceptCntr;
189
190 // Set the setFilterPassed flag
191 setFilterPassed(acceptEvent);
192
193 // Return if event didn't pass
194 if (!acceptEvent) return StatusCode::SUCCESS;
195
196 // If user requested skimming first, run augmentation now...
197 if (m_runSkimmingFirst) {
198 for (const auto & augmentationTool : m_augmentationTools) {
199 ATH_MSG_DEBUG("Entering " << augmentationTool->name());
200 if ( augmentationTool->addBranches(ctx).isFailure() ) {
201 ATH_MSG_ERROR("Augmentation failed!");
202 return StatusCode::FAILURE;
203 }
204 }
205 }
206
207 //=============================================================================
208 // THINNING ===================================================================
209 //=============================================================================
210
211 for (const auto & thinningTool : m_thinningTools) {
212 ATH_MSG_DEBUG("Entering " << thinningTool->name());
213 if ( thinningTool->doThinning().isFailure() ) {
214 ATH_MSG_ERROR("Thinning failed!");
215 return StatusCode::FAILURE;
216 }
217 }
218
219 return StatusCode::SUCCESS;
220
221}
222
223// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
224
226
227 ATH_MSG_INFO( "============================================================================");
228 ATH_MSG_INFO( "|| SUMMARY OF THE DERIVATION FRAMEWORK KERNEL WITH NAME " << name() << " || ");
229 ATH_MSG_INFO( "============================================================================");
230 ATH_MSG_INFO( "============================================================================");
231 ATH_MSG_INFO( "Events analyzed: " << m_eventCounter);
232 ATH_MSG_INFO( "Events accepted: " << m_acceptCntr);
233 ATH_MSG_INFO( "============================================================================");
234
235 return StatusCode::SUCCESS;
236
237}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_DEBUG(x)
defines an "iterator" over instances of a given type in StoreGateSvc
An STL vector of pointers that by default owns its pointed-to elements.
#define ATLAS_THREAD_SAFE
virtual void setFilterPassed(bool state) const
Set the filter passed flag to the specified state.
AthFilterAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
Constructor with parameters:
Gaudi::Property< bool > m_runSkimmingFirst
virtual StatusCode finalize() override
virtual StatusCode initialize() override
PublicToolHandleArray< IThinningTool > m_thinningTools
DerivationKernel(const std::string &name, ISvcLocator *pSvcLocator)
virtual StatusCode execute() override
PublicToolHandleArray< ISkimmingTool > m_skimmingTools
ServiceHandle< IChronoStatSvc > m_chronoSvc
PublicToolHandleArray< IAugmentationTool > m_augmentationTools