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