ATLAS Offline Software
Loading...
Searching...
No Matches
SkipEventIdxSvc Class Reference

#include <SkipEventIdxSvc.h>

Inheritance diagram for SkipEventIdxSvc:
Collaboration diagram for SkipEventIdxSvc:

Public Member Functions

 SkipEventIdxSvc (const std::string &name, ISvcLocator *svc)
 ~SkipEventIdxSvc () override=default
StatusCode initialize () override
StatusCode start () override
StatusCode registerCallback (std::function< StatusCode(EvtIter, EvtIter)> &&callback) override
void handle (const Incident &inc) override

Private Attributes

int m_initial_skip_events {}
std::vector< EvtId > m_events {}
std::vector< std::function< StatusCode(EvtIter, EvtIter)> > m_callbacks {}
bool m_started = false

Detailed Description

Definition at line 13 of file SkipEventIdxSvc.h.

Constructor & Destructor Documentation

◆ SkipEventIdxSvc()

SkipEventIdxSvc::SkipEventIdxSvc ( const std::string & name,
ISvcLocator * svc )

Definition at line 53 of file SkipEventIdxSvc.cxx.

54 : base_class(name, svc) {}

◆ ~SkipEventIdxSvc()

SkipEventIdxSvc::~SkipEventIdxSvc ( )
overridedefault

Member Function Documentation

◆ handle()

void SkipEventIdxSvc::handle ( const Incident & inc)
override

Definition at line 227 of file SkipEventIdxSvc.cxx.

227 {
228 if (inc.type() != "BeginRun"s && inc.type() != "SkipEvents"s) {
229 return;
230 }
231 ATH_MSG_DEBUG("Received incident of type " << inc.type() << " from "
232 << inc.source());
233 if (inc.type() == "SkipEvents"s) {
234 ATH_MSG_DEBUG("Running callbacks");
235 const auto& cInc =
236 dynamic_cast<const ContextIncident<std::tuple<int, int>>&>(inc);
237 auto begin = m_events.cbegin() + std::get<0>(cInc.tag());
238 auto end = m_events.cbegin() + std::get<1>(cInc.tag()) +
239 1; // plus 1 for 1 after end
240 for (auto&& fn : m_callbacks) {
241 if (!std::invoke(fn, begin, end).isSuccess()) {
242 throw std::runtime_error(
243 "A skipEvent callback returned a failure error code!");
244 }
245 }
246 }
247}
#define ATH_MSG_DEBUG(x)
std::vector< std::function< StatusCode(EvtIter, EvtIter)> > m_callbacks
std::vector< EvtId > m_events

◆ initialize()

StatusCode SkipEventIdxSvc::initialize ( )
override

Definition at line 56 of file SkipEventIdxSvc.cxx.

56 {
57 // This is a special service that runs through all the input events ahead of
58 // time, and records the run and lb numbers
59 ATH_MSG_INFO("Initializing SkipEventIdxSvc");
60 SmartIF<IProperty> propMgr(serviceLocator());
61 std::string evt_sel_name{};
62 ATH_CHECK(propMgr->getProperty("EvtSel", evt_sel_name));
63 if (evt_sel_name.empty()) {
64 // No event selector
65 //
66 ATH_MSG_WARNING("No event selector");
67 m_started = true;
68 return StatusCode::SUCCESS;
69 }
70 auto sg = serviceLocator()->service<StoreGateSvc>("StoreGateSvc/StoreGateSvc",
71 false);
72 auto evtSel = serviceLocator()->service<IEvtSelector>(std::move(evt_sel_name), false);
73 if (!sg.isValid() || !evtSel.isValid()) {
74 ATH_MSG_WARNING("Event selector or storegate is invalid");
75 return StatusCode::FAILURE;
76 }
77
78 auto modSvc = serviceLocator()->service<IEvtIdModifierSvc>(
79 "EvtIdModifierSvc/EvtIdModifierSvc", false);
80 std::uint64_t evts_skipped_before_mod = 0;
81 std::vector<EvtId> modifier_evts{};
82 if (modSvc.isValid()) {
83 // Steal it's configuration
84 try {
85 evts_skipped_before_mod =
86 getProp<std::uint64_t&>(modSvc, "SkipEvents").value();
87 ATH_MSG_INFO("Skipping " << evts_skipped_before_mod
88 << " events before modifying");
89 std::vector<std::uint64_t> lst =
90 getProp<std::vector<std::uint64_t>&>(modSvc, "Modifiers").value();
91 ATH_MSG_DEBUG("Printing EvtId modifier config. There are "
92 << lst.size() / 6 << " entries.");
93 std::string config_str{};
94 auto config_str_iter = std::back_inserter(config_str);
95 modifier_evts.clear();
96 for (const auto rec : lst | std::views::chunk(6)) {
97 const int mod_bitset = rec[5];
98 const bool mod_run_num = mod_bitset & 1;
99 const bool mod_evt_num = mod_bitset & (1 << 1);
100 const bool mod_lb_num = mod_bitset & (1 << 3);
101
102 const std::uint64_t runNum = mod_run_num ? rec[0] : 0;
103 const std::uint64_t evtNum = mod_evt_num ? rec[1] : 0;
104 const std::uint64_t lbNum = mod_lb_num ? rec[3] : 0;
105 const std::uint64_t numEvts = rec[4];
106
107 std::format_to(config_str_iter,
108 "Run: {} [{:c}] LB: {} [{:c}] EVT: {} [{:c}] "
109 "NumEvts: {}\n",
110 runNum, mod_run_num ? 'Y' : 'N', lbNum,
111 mod_lb_num ? 'Y' : 'N', evtNum,
112 mod_evt_num ? 'Y' : 'N', numEvts);
113 const EvtId evt{static_cast<uint32_t>(runNum),
114 static_cast<uint32_t>(lbNum), evtNum};
115 for ([[maybe_unused]] const std::uint64_t _ :
116 std::views::iota(std::uint64_t{0}, numEvts)) {
117 modifier_evts.push_back(evt);
118 }
119 }
120 ATH_MSG_DEBUG(config_str);
121 } catch (const std::bad_cast&) {
122 ATH_MSG_ERROR("Wrong type for property of EvtIdModifierSvc.");
123 }
124 } else {
125 ATH_MSG_INFO("No EvtIdModifierSvc found");
126 }
127
128 m_initial_skip_events = getProp<int>(evtSel, "SkipEvents");
129 ATH_CHECK(setProp(evtSel, "SkipEvents", "0"));
130 IEvtSelector::Context* ctx = nullptr;
131 ATH_CHECK(sg->clearStore());
132 ATH_CHECK(evtSel->createContext(ctx));
133
134 std::uint64_t idx = 0;
135 Service* evtSelSvc = dynamic_cast<Service*>(evtSel.get());
136 if (!evtSelSvc) {
137 ATH_MSG_FATAL("Cannot cast to Service");
138 return StatusCode::FAILURE;
139 }
140 ATH_CHECK(evtSelSvc->start());
141 while (evtSel->next(*ctx).isSuccess()) {
142 EvtId evt_id{};
143 // Load event
144 IOpaqueAddress* addr = nullptr;
145 ATH_CHECK(evtSel->createAddress(*ctx, addr));
146 ATH_CHECK(sg->recordAddress(addr));
147 ATH_CHECK(sg->loadEventProxies());
148
149 // Read EventInfo
150 // We don't look for the legacy EventInfo, only an Input attribute list and
151 // if that doesn't exist, and xAOD::EventInfo
152 std::vector<std::string> attr_lists;
153 sg->keys<AthenaAttributeList> (attr_lists);
154 const auto* attr_list_p =
155 sg->tryConstRetrieve<AthenaAttributeList>("Input");
156 if (attr_list_p != nullptr && attr_list_p->size() > 6) {
157 try {
158 const AthenaAttributeList& attr_list = *attr_list_p;
159 const auto runNum = attr_list["RunNumber"].data<unsigned>();
160 const auto evtNum = attr_list["EventNumber"].data<unsigned long long>();
161 const auto lbNum = attr_list["LumiBlockN"].data<unsigned>();
162 evt_id = EvtId{runNum, lbNum, evtNum};
163 } catch (...) {
164 }
165 }
166 ATH_CHECK(sg->clearStore());
167 if (idx >= evts_skipped_before_mod && !modifier_evts.empty()) {
168 const std::size_t mod_idx =
169 (idx - evts_skipped_before_mod) % modifier_evts.size();
170 evt_id.runNum = modifier_evts[mod_idx].runNum != 0U
171 ? modifier_evts[mod_idx].runNum
172 : evt_id.runNum;
173 evt_id.lbNum = modifier_evts[mod_idx].lbNum != 0U
174 ? modifier_evts[mod_idx].lbNum
175 : evt_id.lbNum;
176 evt_id.evtNum = modifier_evts[mod_idx].evtNum != 0U
177 ? modifier_evts[mod_idx].evtNum
178 : evt_id.evtNum;
179 }
180 evt_id.evtIdx = idx;
181 m_events.push_back(evt_id);
182 ++idx;
183 }
184
185 // reset current storegate
186 ATH_MSG_INFO("Setting SkipEvents back to " << m_initial_skip_events
187 << " and rewinding");
188 ATH_CHECK(
189 setProp(evtSel, "SkipEvents", std::format("{}", m_initial_skip_events)));
190 ATH_CHECK(evtSel->rewind(*ctx));
191 ATH_MSG_INFO("Recorded a total of " << m_events.size() << " events");
192
193 // Register as incident handler
194 ServiceHandle<IIncidentSvc> incident_svc("IncidentSvc", name());
195 ATH_CHECK(incident_svc.retrieve());
196 incident_svc->addListener(this, "BeginRun");
197 incident_svc->addListener(this, "SkipEvents");
198 return StatusCode::SUCCESS;
199}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
setEventNumber uint32_t

◆ registerCallback()

StatusCode SkipEventIdxSvc::registerCallback ( std::function< StatusCode(EvtIter, EvtIter)> && callback)
override

Definition at line 213 of file SkipEventIdxSvc.cxx.

214 {
215 m_callbacks.push_back(callback);
216 // Call callback immediately for events skipped in EventSelector if already
217 // started
218 if (m_started && !m_events.empty()) {
219 auto begin = m_events.cbegin();
220 auto end = m_events.cbegin() +
221 std::min(std::size_t(m_initial_skip_events), m_events.size());
222 ATH_CHECK(std::invoke(callback, begin, end));
223 }
224 return StatusCode::SUCCESS;
225}

◆ start()

StatusCode SkipEventIdxSvc::start ( )
override

Definition at line 201 of file SkipEventIdxSvc.cxx.

201 {
202 ATH_MSG_INFO("Starting SkipEventIdxSvc");
203 // Call callbacks if any have already been added
204 for (auto&& callback : m_callbacks) {
205 auto begin = m_events.cbegin();
206 auto end = m_events.cbegin() + m_initial_skip_events;
207 ATH_CHECK(std::invoke(callback, begin, end));
208 }
209 m_started = true;
210 return StatusCode::SUCCESS;
211}

Member Data Documentation

◆ m_callbacks

std::vector<std::function<StatusCode(EvtIter, EvtIter)> > SkipEventIdxSvc::m_callbacks {}
private

Definition at line 28 of file SkipEventIdxSvc.h.

28{};

◆ m_events

std::vector<EvtId> SkipEventIdxSvc::m_events {}
private

Definition at line 27 of file SkipEventIdxSvc.h.

27{};

◆ m_initial_skip_events

int SkipEventIdxSvc::m_initial_skip_events {}
private

Definition at line 26 of file SkipEventIdxSvc.h.

26{};

◆ m_started

bool SkipEventIdxSvc::m_started = false
private

Definition at line 29 of file SkipEventIdxSvc.h.


The documentation for this class was generated from the following files: