ATLAS Offline Software
Loading...
Searching...
No Matches
DerivationKernel.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 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 "AthLinks/ElementLink.h"
18#include "GaudiKernel/AlgTool.h"
19#include "GaudiKernel/Chrono.h"
20#include "GaudiKernel/ToolVisitor.h"
21
22#include <string>
23
25namespace {
26 inline void renounceInputs([[maybe_unused]] const std::unordered_set<std::string> &outputs, std::vector< const DataObjID *> &output_ids, AlgTool *a_tool) {
27 for ( const DataObjID *a_data_id : output_ids ) {
28 a_tool->renounceInput( *a_data_id );
29 }
30 }
31 inline void collectOutputs(std::unordered_set<std::string> &outputs, std::vector< const DataObjID *> &output_ids, const AlgTool *a_tool) {
32 for ( const DataObjID &a_data_id : a_tool->outputDataObjs() ) {
33 if (outputs.insert( a_data_id.key() ).second) {
34 output_ids.push_back( &a_data_id );
35 }
36 }
37 }
38 template <typename Callable, typename = std::enable_if_t<std::is_invocable_r_v<void, Callable, IAlgTool*>>>
39 inline void visitTools(IAlgTool &a_tool_interface, Callable &func) {
40 const AlgTool *alg_tool = dynamic_cast<AlgTool *>(&a_tool_interface);
41 if (alg_tool) {
42 func(&a_tool_interface);
43 std::vector<IAlgTool *> &non_const_tools ATLAS_THREAD_SAFE = const_cast< std::vector<IAlgTool *> &>( alg_tool->tools() );
44 ToolVisitor::visit( non_const_tools, func);
45 }
46 }
47}
48
49// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
50
52
53 ATH_MSG_INFO("Initializing the derivation framework kernel " << name());
54
55 // get the skimming tools
56 ATH_CHECK( m_skimmingTools.retrieve() );
57 ATH_MSG_INFO("The following skimming tools will be applied....");
59
60 // get the thinning tools
61 ATH_CHECK( m_thinningTools.retrieve() );
62 ATH_MSG_INFO("The following thinning tools will be applied");
64
65 // get the augmentation tools
66 ATH_CHECK( m_augmentationTools.retrieve() );
67 ATH_MSG_INFO("The following augmentation tools will be applied....");
69
70 // setup filter reporting
71 m_filterParams.setKey(name());
72 ATH_CHECK( m_filterParams.initialize() );
73
74 if (m_doChronoStat) {
75 //get the chrono auditor
76 ATH_CHECK(m_chronoSvc.retrieve());
77 }
78
80 ATH_MSG_INFO("Skimming will be run before augmentation. Make sure your skimming does not depend on variables calculated in the augmentation step!");
81 }
82
83 std::unordered_set<std::string> outputs;
84 std::vector<const DataObjID *> output_ids;
85 auto output_collector = [&outputs, &output_ids](IAlgTool *a_tool_interface) {
86 const AlgTool *alg_tool = dynamic_cast<AlgTool *>(a_tool_interface);
87 if (alg_tool) {
88 collectOutputs(outputs,output_ids, alg_tool);
89 }
90 };
91 auto renounce_and_collect_outputs = [&outputs, &output_ids](IAlgTool *a_tool_interface) {
92 AlgTool *alg_tool = dynamic_cast<AlgTool *>(a_tool_interface);
93 if (alg_tool) {
94 renounceInputs(outputs,output_ids, alg_tool);
95 collectOutputs(outputs,output_ids, alg_tool);
96 }
97 };
98 auto renouncer = [&outputs, &output_ids](IAlgTool *a_tool_interface) {
99 AlgTool *alg_tool = dynamic_cast<AlgTool *>(a_tool_interface);
100 if (alg_tool) {
101 renounceInputs(outputs,output_ids, alg_tool);
102 }
103 };
104
105 // collection and renouncing has to happen in the order the tools are called
106 // during execute.
107 if (m_runSkimmingFirst) {
108 for (ToolHandle<ISkimmingTool> &a_tool_handle : m_skimmingTools ) {
109 visitTools(*a_tool_handle, output_collector);
110 }
111 for (ToolHandle<IAugmentationTool> &a_tool_handle : m_augmentationTools ) {
112 visitTools(*a_tool_handle, renounce_and_collect_outputs);
113 }
114 }
115 else {
116 for (ToolHandle<IAugmentationTool> &a_tool_handle : m_augmentationTools ) {
117 visitTools(*a_tool_handle, output_collector);
118 }
119 for (ToolHandle<ISkimmingTool> &a_tool_handle : m_skimmingTools ) {
120 visitTools(*a_tool_handle, renounce_and_collect_outputs);
121 }
122 }
123 for (ToolHandle<IThinningTool> &a_tool_handle : m_thinningTools ) {
124 visitTools(*a_tool_handle, renouncer);
125 }
126
127 return StatusCode::SUCCESS;
128
129}
130
131// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
132
133StatusCode DerivationFramework::DerivationKernel::execute(const EventContext& ctx) {
134
135 IChronoSvc* cSvc=m_chronoSvc.get(); //Might be null ...
136 // On your marks.... get set.... (but only if not in MT)
137 Chrono chrono( cSvc , name() );
138 // GO!!!
139
140 ATH_MSG_DEBUG(name() << " is processing next event...");
141
142 // Increment the event counter
144
145 //=============================================================================
146 // AUGMENTATION ===============================================================
147 //=============================================================================
148 if (!m_runSkimmingFirst) {
149 for (const auto & augmentationTool : m_augmentationTools) {
150 ATH_MSG_DEBUG("Entering " << augmentationTool->name());
151 if ( augmentationTool->addBranches(ctx).isFailure() ) {
152 ATH_MSG_ERROR("Augmentation failed!");
153 return StatusCode::FAILURE;
154 }
155 }
156 }
157
158 //=============================================================================
159 //SKIMMING ===================================================================
160 //=============================================================================
161
162 // Set master flag to true
163 bool acceptEvent(true);
164 // Setup the filter reporter
165 FilterReporter filter (m_filterParams, acceptEvent, ctx);
166
167 // Loop over the filters
168 for (const auto & skimmingTool : m_skimmingTools) {
169 ATH_MSG_DEBUG("Entering " << skimmingTool->name());
170 if (!(skimmingTool->eventPassesFilter(ctx))) {
171 acceptEvent=false;
172 ATH_MSG_DEBUG("This event failed the " << skimmingTool->name() << " filter. Therefore it will not be recorded.");
173 break;
174 }
175 }
176
177 // Increment local counters if event to be accepted
178 if (acceptEvent) ++m_acceptCntr;
179
180 // Set the filter passed flag
181 filter.setPassed (acceptEvent);
182
183 // Return if event didn't pass
184 if (!acceptEvent) return StatusCode::SUCCESS;
185
186 // If user requested skimming first, run augmentation now...
187 if (m_runSkimmingFirst) {
188 for (const auto & augmentationTool : m_augmentationTools) {
189 ATH_MSG_DEBUG("Entering " << augmentationTool->name());
190 if ( augmentationTool->addBranches(ctx).isFailure() ) {
191 ATH_MSG_ERROR("Augmentation failed!");
192 return StatusCode::FAILURE;
193 }
194 }
195 }
196
197 //=============================================================================
198 // THINNING ===================================================================
199 //=============================================================================
200
201 for (const auto & thinningTool : m_thinningTools) {
202 ATH_MSG_DEBUG("Entering " << thinningTool->name());
203 if ( thinningTool->doThinning(ctx).isFailure() ) {
204 ATH_MSG_ERROR("Thinning failed!");
205 return StatusCode::FAILURE;
206 }
207 }
208
209 return StatusCode::SUCCESS;
210
211}
212
213// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
214
216
217 ATH_MSG_INFO( "============================================================================");
218 ATH_MSG_INFO( "|| SUMMARY OF THE DERIVATION FRAMEWORK KERNEL WITH NAME " << name() << " || ");
219 ATH_MSG_INFO( "============================================================================");
220 ATH_MSG_INFO( "============================================================================");
221 ATH_MSG_INFO( "Events analyzed: " << m_eventCounter);
222 ATH_MSG_INFO( "Events accepted: " << m_acceptCntr);
223 ATH_MSG_INFO( "============================================================================");
224
225 return StatusCode::SUCCESS;
226
227}
#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)
#define ATLAS_THREAD_SAFE
virtual StatusCode execute(const EventContext &ctx) override
Execute method.
Gaudi::Property< bool > m_runSkimmingFirst
virtual StatusCode finalize() override
virtual StatusCode initialize() override
PublicToolHandleArray< IThinningTool > m_thinningTools
PublicToolHandleArray< ISkimmingTool > m_skimmingTools
ServiceHandle< IChronoStatSvc > m_chronoSvc
PublicToolHandleArray< IAugmentationTool > m_augmentationTools
a guard class for use with ref FilterReporterParams