ATLAS Offline Software
Loading...
Searching...
No Matches
CutFlowSvc.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5// Implementation file for class CutFlowSvc
6// Authors:
7// Tadej Novak <tadej@cern.ch>
8// Joao Firmino da Costa <joao.costa@cern.ch> and David Cote <david.cote@cern.ch>
9
10// Not dual use at the moment
11#ifndef XAOD_STANDALONE
12
14
15#include <GaudiKernel/Incident.h>
16#include <GaudiKernel/FileIncident.h>
17#include <GaudiKernel/IIncidentSvc.h>
18
19// EDM includes
22
23CutFlowSvc::CutFlowSvc(const std::string& name,
24 ISvcLocator* pSvcLocator ) :
25 base_class(name, pSvcLocator)
26{
27 assert( pSvcLocator );
28}
29
30
31StatusCode
33{
34 ATH_MSG_DEBUG( "Initializing " << name() );
35
36 // Only run if explicitly configured
37 if (m_configured.value() == false) {
38 ATH_MSG_ERROR("CutFlowSvc should be explicitly configured!");
39 return StatusCode::FAILURE;
40 }
41
42 //Get input MetaData StoreGate
43 ATH_CHECK( m_inMetaDataStore.retrieve() );
44
45 //Get IncidentSvc
46 ServiceHandle<IIncidentSvc> incSvc("IncidentSvc", this->name());
47 ATH_CHECK( incSvc.retrieve() );
48 incSvc->addListener(this, IncidentType::BeginInputFile, 60); // pri has to be < 100 to be after MetaDataSvc.
49 incSvc->addListener(this, "MetaDataStop", 30);
50
51 // Create initial bookkeeper container for bookkeepers in _this_ processing
53
54 // Determine the skimming cycle number that we should use now from the input file
55 ATH_MSG_VERBOSE("Have currently the cycle number = " << m_skimmingCycle );
57 ATH_MSG_VERBOSE("Will use cycle number = " << m_skimmingCycle );
58
59 return StatusCode::SUCCESS;
60}
61
62
63
65 const std::string& description,
66 bool nominalOnly )
67{
68 ATH_MSG_DEBUG("Registering filter with name '" << name << "' and description '" << description << "'");
69
70 auto newCbk = std::make_unique<xAOD::CutBookkeeper>();
71 newCbk->setName(name);
72 newCbk->setDescription(description);
73 newCbk->setInputStream(m_inputStream);
74 newCbk->setCycle(m_skimmingCycle);
75 CutIdentifier cutID = newCbk->uniqueIdentifier();
76
77 // Let's see if an CutBookkeeper of this name already exists
79 ATH_MSG_VERBOSE("Searching if this CutBookkeeper already exists");
80 for (xAOD::CutBookkeeper* cbk : *container) {
81 if (newCbk->isEqualTo(cbk)) {
82 ATH_MSG_DEBUG("The CutBookkeeper with name '" << name << "' already exists"
83 << " and has CutID " << cbk->uniqueIdentifier() << "... Not adding!" );
84 // Return the existing cut ID
85 return cbk->uniqueIdentifier();
86 }
87 }
88
89 // If it is a new CutBookkeeper, add it to the container
90 ATH_MSG_DEBUG("Declaring a new filter with name '" << name << "' and CutID " << cutID );
91 container->push_back(std::move(newCbk));
92
93 if (nominalOnly) {
94 m_nominalOnlyCuts.emplace(cutID);
95 }
96
97 return cutID;
98}
99
100
101
102// This method is probably only called by the DecisionSvc
103CutIdentifier CutFlowSvc::registerTopFilter ATLAS_NOT_THREAD_SAFE ( const std::string& name,
104 const std::string& description,
105 unsigned int logic,
106 const std::string& outputStream,
107 bool nominalOnly )
108{
109 ATH_MSG_DEBUG("Registering top filter with name '" << name << "' and description '" << description << "'"
110 << ", logic=" << logic << ", outputStream=" << outputStream << ")");
111
112 // Call the registerFilter method and get the correct CutBookkeeper
113 // from the returned cutID
114 CutIdentifier cutID = registerFilter(name, description, nominalOnly);
115 xAOD::CutBookkeeper* cbk = getCutBookkeeper(cutID, 0);
116 if (cbk == nullptr) {
117 ATH_MSG_ERROR("Could not find CutBookkeeper with CutID " << cutID);
118 throw std::runtime_error("Could not find CutBookkeeper");
119 }
120
121 // Then set the logic and outputStream of the relevant CutBookkeeper
123 cbk->setTopFilter(true);
124 cbk->addOutputStreamForAllUsed(outputStream);
125
126 return cutID;
127}
128
129
130CutIdentifier CutFlowSvc::registerCut( const std::string& name,
131 const std::string& description,
132 CutIdentifier parentCutID,
133 bool nominalOnly )
134{
135 ATH_MSG_DEBUG("Registering cut with name '" << name << "', description '" << description
136 << "' and original CutID " << parentCutID);
137
138 // Get the CutBookkeeper of the origin Filter Algorithm/Tool
139 xAOD::CutBookkeeper* parentCbk = getCutBookkeeper(parentCutID, 0);
140 if (parentCbk == nullptr) {
141 ATH_MSG_ERROR("Could not find parent CutBookkeeper with CutID " << parentCutID);
142 throw std::runtime_error("Could not find CutBookkeeper");
143 }
144
145 // Call the registerFilter method and get the correct CutBookkeeper
146 // from the returned cutID
147 CutIdentifier cutID = registerFilter(name, description, nominalOnly);
148 xAOD::CutBookkeeper* cbk = getCutBookkeeper(cutID, 0);
149 if (cbk == nullptr) {
150 ATH_MSG_ERROR("Could not find CutBookkeeper with CutID " << cutID);
151 throw std::runtime_error("Could not find CutBookkeeper");
152 }
153
154 // Add child to parent
155 parentCbk->addChild(cbk);
156
157 return cutID;
158}
159
160
161void
163 const std::string& descr )
164{
165 ATH_MSG_DEBUG("calling setFilterDescription(" << cutID << ", " << descr << ")" );
166
167 for (size_t i = 0; i < m_containers.size(); ++i) {
168 xAOD::CutBookkeeper* cbk = getCutBookkeeper(cutID, i);
169 if (cbk != nullptr) {
170 cbk->setDescription(descr);
171 }
172 }
173 return;
174}
175
176
177void
179 const std::vector<float>& weights )
180{
181 if (weights.size() != m_containers.size()) {
182 ATH_MSG_ERROR("Inconsistent weights and variation sizes " << weights.size() << " and " << m_containers.size());
183 throw std::runtime_error("Inconsistent weights and variation sizes");
184 }
185
186 for (size_t i = 0; i < m_containers.size(); ++i) {
187 addEvent(cutID, i, weights[i]);
188 }
189}
190
191
192void
194 double weight )
195{
196 if (m_nominalOnlyCuts.count(cutID) == 1) {
197 addEvent(cutID, 0, weight);
198 return;
199 }
200
201 for (size_t i = 0; i < m_containers.size(); ++i) {
202 addEvent(cutID, i, weight);
203 }
204}
205
206
207
208void
210 size_t index,
211 double weight )
212{
213 std::lock_guard<std::recursive_mutex> lock(m_addEventMutex);
214
215 ATH_MSG_VERBOSE("Adding event with weight " << weight << " to cut " << cutID << " for variation " << index);
216
218 if (cbk == nullptr) {
219 ATH_MSG_ERROR("Could not find CutBookkeeper for CutID " << cutID << " and variation " << index);
220 throw std::runtime_error("Could not find CutBookkeeper");
221 }
222
223 cbk->addNAcceptedEvents(1);
224 cbk->addSumOfEventWeights(weight);
225 cbk->addSumOfEventWeightsSquared(weight*weight);
226}
227
228
229
230//__________________________________________________________________________
231void CutFlowSvc::handle( const Incident& inc )
232{
233 ATH_MSG_VERBOSE( "Start incident " << inc.type() );
234
235 if (inc.type() == IncidentType::BeginInputFile) {
236 // Look up input stream name from FileMetaData
237 std::string inputstream = "";
238 if (m_inMetaDataStore->contains<xAOD::FileMetaData>("FileMetaData")) {
239 const xAOD::FileMetaData* fmd = nullptr;
240 if (m_inMetaDataStore->retrieve(fmd).isFailure()) {
241 ATH_MSG_ERROR("Failed to retrieve input FileMetaData");
242 } else if (fmd &&
243 !fmd->value(xAOD::FileMetaData::dataType, inputstream)) {
244 ATH_MSG_WARNING("Failed to get input stream name from FileMetaData");
245 }
246 } else {
247 ATH_MSG_DEBUG("No FileMetaData in input, trying EventStreamInfo");
248 // determine key for EventStreamInfo
249 std::vector<std::string> vKeys;
251 // eliminate duplicate keys
252 std::set<std::string> keys(vKeys.begin(), vKeys.end());
253 if (keys.size() == 1) {
254 std::string key = *keys.begin(); // get the one key
255 auto esi = m_inMetaDataStore->tryConstRetrieve<EventStreamInfo>(key);
256 if (esi && !esi->getProcessingTags().empty()) {
257 // use the first tag
258 inputstream = *esi->getProcessingTags().begin();
259 }
260 }
261 }
262
263 if (inputstream.empty()) {
264 if (m_inputStream.empty()) {
265 ATH_MSG_FATAL("Cannot determine input stream name");
266 return;
267 }
269 "Failed to parse stream name from metadata, using "
270 "property \"InputStream\"");
271 inputstream = m_inputStream;
272 }
273
274 // Check that input stream is consistent with previous file
275 ATH_MSG_DEBUG("Input stream name: \"" << inputstream << '"');
276 if (m_inputStream.empty()) {
277 m_inputStream = inputstream;
278 } else if (m_inputStream != inputstream) {
279 const FileIncident* finc = dynamic_cast<const FileIncident*>(&inc);
280 if (m_inputStream != "N/A" && m_inputStream != "unknownStream") {
281 ATH_MSG_FATAL("File " << (finc?finc->fileName():"???") << " stream " << inputstream
282 << " does not match previous file "
283 << m_inputStream);
284 return;
285 }
286 }
287 }
288
289 // Clear the local bookkeepers
290 if (inc.type() == "MetaDataStop") {
291 if (!m_containers.empty()) {
292 // Reset existing container
293 for (size_t i = 0; i < m_containers.size(); ++i) {
294 for (xAOD::CutBookkeeper* cbk : *m_containers.at(i)) {
295 cbk->setNAcceptedEvents(0);
296 cbk->setSumOfEventWeights(0);
297 cbk->setSumOfEventWeightsSquared(0);
298 }
299 }
300 }
301 }
302
303 ATH_MSG_VERBOSE( "End incident " << inc.type() );
304 return;
305}
306
307
308
309StatusCode CutFlowSvc::determineCycleNumberFromInput( const std::string& collName )
310{
311 ATH_MSG_DEBUG("calling determineCycleNumberFromInput('" << collName
312 << "')... have currently cycle number = " << m_skimmingCycle );
313
314 // Try to get CutBookkeepers from the input file
315 if ( m_inMetaDataStore->contains<xAOD::CutBookkeeperContainer>(collName) ) {
316 ATH_MSG_VERBOSE("Found xAOD::CutBookkeeperContainer in input MetaStore with name: " << collName);
317
318 const xAOD::CutBookkeeperContainer* inputContainer{};
319 ATH_CHECK( m_inMetaDataStore->retrieve( inputContainer, collName ) );
320 // Now, iterate over all CutBookkeepers and search for the highest cycle number
321 int maxCycle{};
322 for (const xAOD::CutBookkeeper* cbk : *inputContainer) {
323 int inCycle = cbk->cycle();
324 if (inCycle > maxCycle) maxCycle = inCycle;
325 }
326 m_skimmingCycle = std::max(m_skimmingCycle.value(), maxCycle + 1);
327 }
328
329 ATH_MSG_DEBUG("done calling determineCycleNumberFromInput('" << collName
330 << "')... have now cycle number = " << m_skimmingCycle );
331 return StatusCode::SUCCESS;
332}
333
334
335
337{
338 // Expect that this should only be called once for now
339 if (!m_containers.empty() && m_containers.size() == count) {
340 return StatusCode::SUCCESS;
341 }
342
343 if (m_containers.size() > count) {
344 ATH_MSG_ERROR("Inconsistent variation count");
345 return StatusCode::FAILURE;
346 }
347
348 ATH_MSG_VERBOSE("Create containers with count " << count);
349
350 ATH_MSG_VERBOSE("Existing size " << m_containers.size());
351
352 // Create the containers
354 if (count == 1) {
355 return StatusCode::SUCCESS;
356 }
357
358 // Copy existing CutBookkeepers for consistency
360 if (first->empty()) {
361 return StatusCode::SUCCESS;
362 }
363 for (size_t i = 1; i < count; ++i) {
365 for (const xAOD::CutBookkeeper *cbk : *first) {
367 cont->push_back(newCbk);
368 *newCbk = *cbk;
369 }
370 }
371
372 return StatusCode::SUCCESS;
373}
374
375
376
378{
380 return StatusCode::SUCCESS;
381}
382
383
384
389
390
391
393 size_t index) const
394{
395 if (index >= m_containers.size()) {
396 return nullptr;
397 }
398
399 for (xAOD::CutBookkeeper* cbk : *m_containers.at(index)) {
400 if (cbk->uniqueIdentifier() == cutID) {
401 return cbk;
402 }
403 }
404 return nullptr;
405}
406
407
408
410{
411 const xAOD::CutBookkeeper* cbk = getCutBookkeeper(cutID, 0);
412 if (cbk == nullptr) {
413 return std::numeric_limits<uint64_t>::max();
414 }
415 return cbk->nAcceptedEvents();
416}
417
418
419#endif // dual use
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
This file contains the class definition for the EventStreamInfo class.
uint32_t CutIdentifier
InstanceIdentifier is a unique identifer used for every AthFilterAlgorithm instance.
Definition ICutFlowSvc.h:26
#define ATLAS_NOT_THREAD_SAFE
getNoisyStrip() Find noisy strips from hitmaps and write out into xml/db formats
const CutBookkeepersLocalCache & getCutBookkeepers() const
Get CutBookkeepers cache.
virtual void setFilterDescription(CutIdentifier cutID, const std::string &descr) override final
Set the description of an existing CutBookkeeper.
CutBookkeepersLocalCache m_containers
Local CutBookkeeperContainers.
Definition CutFlowSvc.h:140
Gaudi::Property< std::string > m_completeCollName
The name of the completed, i.e., fully processed, CutBookkeeperContainer.
Definition CutFlowSvc.h:137
ServiceHandle< StoreGateSvc > m_inMetaDataStore
The input meta-data store.
Definition CutFlowSvc.h:134
std::recursive_mutex m_addEventMutex
Mutex to protect adding an event.
Definition CutFlowSvc.h:149
virtual uint64_t getNAcceptedEvents(const CutIdentifier cutID) const override final
Get number of accepted events for a cut.
StatusCode setNumberOfWeightVariations(size_t count)
Set number of weight variations.
StatusCode determineCycleNumberFromInput(const std::string &collName)
Helper function to determine the processing cycle number from the input meta-data store.
StatusCode createContainers(size_t count)
Helper function to create an empty containers (and its aux store)
Gaudi::Property< bool > m_configured
CutFlow service should be explicitly configured.
Definition CutFlowSvc.h:131
virtual void handle(const Incident &incident) override final
Incident service handle listening for BeginInputFile, EndInputFile and MetaDataStop.
virtual void addEvent(CutIdentifier cutID, const std::vector< float > &weights) override final
Tells CutFlowSvc to update the weighted event counter of a CutIdentifier cutID, using CutIdentifier r...
virtual CutIdentifier registerCut(const std::string &name, const std::string &description, CutIdentifier parentCutID, bool nominalOnly) override final
Register cut as child of a filter in the CutFlowSvc and returns the CutID of the corresponding EventB...
virtual CutIdentifier registerFilter(const std::string &name, const std::string &description, bool nominalOnly) override final
Register filter in the CutFlowSvc and returns the CutID of the corresponding CutBookkeeper.
virtual StatusCode initialize() override final
Gaudi Service Implementation.
Gaudi::Property< int > m_skimmingCycle
The current skimming cycle, i.e., how many processing stages we already had.
Definition CutFlowSvc.h:143
xAOD::CutBookkeeper * getCutBookkeeper(const CutIdentifier cutID, size_t index) const
Get a CutBookkeeper given a CutID.
std::unordered_set< CutIdentifier > m_nominalOnlyCuts
List of nominal-only filters.
Definition CutFlowSvc.h:152
Gaudi::Property< std::string > m_inputStream
The name of the currently used input file stream.
Definition CutFlowSvc.h:146
CutFlowSvc(const std::string &name, ISvcLocator *pSvcLocator)
Constructor.
value_type push_back(value_type pElem)
Add an element to the end of the collection.
This class provides the summary information stored for data written as a Event Stream.
void addSumOfEventWeights(double nWeightedEvents)
Add more sum-of-event-weights that this CutBookkeeper has seen.
void addChild(CutBookkeeper_v1 *childEB)
Add one child to this CutBookkeeper.
void addSumOfEventWeightsSquared(double nWeightedEventsSquared)
Add more sum-of-(event-weights-squared) that this CutBookkeeper has seen.
void addNAcceptedEvents(uint64_t nEvents)
Add seen events to the number of accepted events that this CutBookkeeper has seen.
CutLogic
Enumeration of the logic of a cut.
void setDescription(const std::string &description)
Set the description of this CutBookkeeper.
uint64_t nAcceptedEvents() const
Get the number of accepted events that this CutBookkeeper has seen.
void setCutLogic(CutLogic logic)
Set the cut logic of this CutBookkeeper, e.g., ACCEPT, REQUIRE, VETO.
void setTopFilter(bool isTopFilter)
Set the top-filter property of this CutBookkeeper.
@ dataType
Data type that's in the file [string].
bool value(MetaDataType type, std::string &val) const
Get a pre-defined string value out of the object.
std::string description
glabal timer - how long have I taken so far?
Definition hcg.cxx:91
int count(std::string s, const std::string &regx)
count how many occurances of a regx are in a string
Definition hcg.cxx:146
Definition index.py:1
CutBookkeeper_v1 CutBookkeeper
Define the latest version of the CutBookkeeper class.
FileMetaData_v1 FileMetaData
Declare the latest version of the class.
CutBookkeeperContainer_v1 CutBookkeeperContainer
Define the latest version of the CutBookkeeperContainer class.
Helper in-memory structure.
static void prepareContainers(CutBookkeepersLocalCache &target, size_t size, bool extend=false)