ATLAS Offline Software
Loading...
Searching...
No Matches
MetadataAlg.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#include <src/MetadataAlg.h>
6
7#include "HDF5Utils/Writer.h"
8
14
15#include <regex>
16#include <fstream>
17#include <boost/json.hpp>
18
19//
20// method implementations
21//
22
23namespace {
24
25 // name for top level object in json or h5
26 static const std::string top_group = "cutBookkeeper";
27
28 void addCounts(H5::Group& grp, const OriginalAodCounts& counts){
30#define ADD(NAME) \
31 cons.add(#NAME,[](const OriginalAodCounts& c) {return c.NAME;})
32 ADD(nEventsProcessed);
33 ADD(sumOfWeights);
34 ADD(sumOfWeightsSquared);
35#undef ADD
37 writer.fill(counts);
38 }
39 void addCounts(boost::json::object& grp, const OriginalAodCounts& counts) {
40 grp["counts"] = {
41#define ADD(NAME) {#NAME, counts.NAME}
42 ADD(nEventsProcessed),
43 ADD(sumOfWeights),
44 ADD(sumOfWeightsSquared),
45#undef ADD
46 };
47 }
48
49 OriginalAodCounts getCounts(const xAOD::CutBookkeeper& cbk)
50 {
52 counts.nEventsProcessed = cbk.nAcceptedEvents();
53 counts.sumOfWeights = cbk.sumOfEventWeights();
54 counts.sumOfWeightsSquared = cbk.sumOfEventWeightsSquared();
55 return counts;
56 }
57
58 static const std::vector<std::string> allowed_streams{
59 "StreamAOD", "StreamEVGEN", "StreamEVNT"};
60 bool isGoodBook(const xAOD::CutBookkeeper& cbk) {
61 const auto& s = allowed_streams;
62 return cbk.name() == "AllExecutedEvents"
63 && std::find(s.begin(), s.end(), cbk.inputStream()) != s.end();
64 }
65
66}
67
68namespace ftag {
69
71 const std::string& name,
72 ISvcLocator* pSvcLocator):
73 AthAlgorithm(name, pSvcLocator),
74 m_inputMetaStore("StoreGateSvc/InputMetaDataStore", name)
75 {
76 }
77
79 {
80 // register with incident service
81 ServiceHandle<IIncidentSvc> incSvc( "IncidentSvc", name() );
82 CHECK( incSvc.retrieve() );
83 // remove first to make sure it's not called twice
84 incSvc->removeListener( this, IncidentType::BeginInputFile );
85 incSvc->addListener( this, IncidentType::BeginInputFile, 0, true );
86
87 CHECK(m_truthWeightTool.retrieve());
88
89 if (!m_output_svc.empty()) {
90 ATH_CHECK(m_output_svc.retrieve());
91 }
92
93 return StatusCode::SUCCESS;
94 }
95
97 {
98 return StatusCode::SUCCESS;
99 }
100
101 void MetadataAlg::handle(const Incident& inc)
102 {
103
104 // skip all incidents beyond the start of input files
105 if (inc.type() != IncidentType::BeginInputFile) return;
106
107 ATH_MSG_DEBUG("Updating CutBookkeeper information");
108
109 // Retrieve complete CutBookkeeperContainer
110 const xAOD::CutBookkeeperContainer *completeCBC{};
111 auto rc = m_inputMetaStore->retrieve(completeCBC, "CutBookkeepers");
112 if (!rc.isSuccess()) throw std::runtime_error(
113 "could not retrieve CutBookkeepers");
114
115 // Find the max cycle
116 int maxCycle{-1};
117 const xAOD::CutBookkeeper *allEvents{};
118 for (const xAOD::CutBookkeeper *cbk : *completeCBC)
119 {
121 "Complete cbk name: " << cbk->name() <<
122 " - stream: " << cbk->inputStream()
123 );
124
125 if (cbk->cycle() > maxCycle && isGoodBook(*cbk))
126 {
127 allEvents = cbk;
128 maxCycle = cbk->cycle();
129 }
130 }
131
132 if (allEvents == nullptr)
133 {
134 std::string error(
135 "Could not find AllExecutedEvents CutBookkeeper information.");
136 throw std::runtime_error(error);
137 }
138
139 for (const xAOD::CutBookkeeper *cbk : *completeCBC)
140 {
141 if (cbk->cycle() == maxCycle && isGoodBook(*cbk))
142 {
143 static const std::regex re("AllExecutedEvents.*_([0-9]+)");
144 // Get the CBK index
145 size_t index{0};
146 std::smatch match;
147 if (std::regex_match(cbk->name(), match, re))
148 {
149 index = std::stoi(match[1]);
150 }
151 m_weights[index] += getCounts(*cbk);
152 }
153 }
154
155 // now try systematics-aware containers
156 for (size_t index{1}; index < m_truthWeightTool->getWeightNames().size(); ++index)
157 {
158 std::string cbkName = "CutBookkeepers_weight_" + std::to_string(index);
159 if (!m_inputMetaStore->contains<xAOD::CutBookkeeperContainer>(cbkName))
160 {
161 ATH_MSG_VERBOSE("No container named " << cbkName << "available");
162 continue;
163 }
164
165 if (!m_inputMetaStore->retrieve(completeCBC, cbkName).isSuccess()) {
166 throw std::runtime_error("could not retrieve " + cbkName);
167 }
168 for (const xAOD::CutBookkeeper *cbk : *completeCBC)
169 {
170 if (cbk->cycle() == maxCycle && isGoodBook(*cbk))
171 {
172 m_weights[index] += getCounts(*cbk);
173 }
174 }
175 }
176 }
177
178
180 {
181
182 std::vector<CP::SystematicSet> systematics;
183 systematics.emplace_back();
184 for (const CP::SystematicVariation &variation : m_truthWeightTool->affectingSystematics())
185 {
186 auto set = CP::SystematicSet({variation});
187 ATH_MSG_DEBUG("using systematic " << set.name());
188 systematics.emplace_back(set);
189 }
190
191 std::optional<H5::Group> h5_cbk;
192 if (!m_output_svc.empty()) {
193 h5_cbk = H5::Group(m_output_svc->group()->createGroup(top_group));
194 }
195 std::optional<boost::json::object> json_cbk;
196 if (!m_json_output.empty()) {
197 json_cbk = boost::json::object{};
198 }
199
200 for (const CP::SystematicSet &sys : systematics)
201 {
202 const std::string sysname = sys.name().empty() ? "nominal": sys.name();
204 m_truthWeightTool->getSysWeightIndex(sys));
205
206 if (h5_cbk) {
207 H5::Group sysgroup(h5_cbk->createGroup(sysname));
208 addCounts(sysgroup, weights);
209 }
210 if (json_cbk) {
211 boost::json::object& cbk_root = *json_cbk;
212 addCounts(cbk_root[sysname].emplace_object(), weights);
213 }
214 }
215 if (json_cbk) {
216 std::ofstream out(m_json_output.value());
217 boost::json::object jroot {
218 {top_group, *json_cbk}
219 };
220 out << jroot << std::endl;
221 }
222
223 return StatusCode::SUCCESS;
224 }
225
226}
const boost::regex re(r_e)
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_DEBUG(x)
#define CHECK(...)
Evaluate an expression and check for errors.
static Double_t rc
#define ADD(NAME)
static const std::vector< std::string > systematics
AthAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
Constructor with parameters:
Class to wrap a set of SystematicVariations.
Writer.
Definition Writer.h:350
ToolHandle< PMGTools::IPMGTruthWeightTool > m_truthWeightTool
Definition MetadataAlg.h:37
std::unordered_map< size_t, OriginalAodCounts > m_weights
Definition MetadataAlg.h:45
ServiceHandle< IH5GroupSvc > m_output_svc
Definition MetadataAlg.h:40
Gaudi::Property< std::string > m_json_output
Definition MetadataAlg.h:42
void handle(const Incident &) override
StatusCode initialize() override
MetadataAlg(const std::string &name, ISvcLocator *pSvcLocator)
ServiceHandle< StoreGateSvc > m_inputMetaStore
Definition MetadataAlg.h:35
StatusCode execute() override
StatusCode finalize() override
STL class.
double sumOfEventWeightsSquared() const
Get the sum-of-(event-weights-squared) that this CutBookkeeper has seen.
int cycle() const
Get the skimming cycle that this CutBookkeeper was running in.
const std::string & inputStream() const
Get the name of the input-file stream object that was seen by this CutBookkeeper.
double sumOfEventWeights() const
Get the sum-of-event-weights that this CutBookkeeper has seen.
const std::string & name() const
Get the name of this CutBookkeeper.
uint64_t nAcceptedEvents() const
Get the number of accepted events that this CutBookkeeper has seen.
bool match(std::string s1, std::string s2)
match the individual directories of two strings
Definition hcg.cxx:357
writer
show summary of content
Definition example.py:36
Definition index.py:1
CutBookkeeper_v1 CutBookkeeper
Define the latest version of the CutBookkeeper class.
CutBookkeeperContainer_v1 CutBookkeeperContainer
Define the latest version of the CutBookkeeperContainer class.