6 #include <GaudiKernel/DataIncident.h>
7 #include <GaudiKernel/IEvtSelector.h>
8 #include <GaudiKernel/IIncidentSvc.h>
10 #include <boost/core/typeinfo.hpp>
11 #include <range/v3/to_container.hpp>
12 #include <range/v3/view.hpp>
19 using namespace std::literals;
20 namespace rv = ranges::views;
23 template <
typename propType,
typename T>
24 const Gaudi::Property<propType>&
25 getProp(SmartIF<T>& iface,
const std::string&
name)
27 auto prop_iface = iface.template as<IProperty>();
28 const auto& prop = prop_iface->getProperty(
name);
30 const auto& conv_prop =
31 dynamic_cast<const Gaudi::Property<propType>&
>(prop);
33 }
catch (
const std::bad_cast&) {
34 std::string if_name =
"UNKNOWN";
36 if_name = iface.template as<INamedInterface>()->name();
40 "The {} object's {} property has type {} not Gaudi::Property<{}>",
41 if_name,
name, boost::core::demangled_name(
typeid(prop)),
42 boost::core::demangled_name(
typeid(propType)));
43 throw std::logic_error(
what);
49 const std::string&
val) {
50 auto prop_iface = iface.template as<IProperty>();
51 return prop_iface->setProperty(
name,
val);
62 SmartIF<IProperty> propMgr(serviceLocator());
63 std::string evt_sel_name{};
64 ATH_CHECK(propMgr->getProperty(
"EvtSel", evt_sel_name));
65 if (evt_sel_name.empty()) {
70 return StatusCode::SUCCESS;
72 auto sg = serviceLocator()->service<
StoreGateSvc>(
"StoreGateSvc/StoreGateSvc",
74 auto evtSel = serviceLocator()->service<IEvtSelector>(std::move(evt_sel_name),
false);
75 if (!sg.isValid() || !evtSel.isValid()) {
77 return StatusCode::FAILURE;
81 "EvtIdModifierSvc/EvtIdModifierSvc",
false);
83 std::vector<EvtId> modifier_evts{};
84 if (modSvc.isValid()) {
87 evts_skipped_before_mod =
88 getProp<std::uint64_t&>(modSvc,
"SkipEvents").value();
90 <<
" events before modifying");
91 std::vector<std::uint64_t>
lst =
92 getProp<std::vector<std::uint64_t>&>(modSvc,
"Modifiers").
value();
94 <<
lst.size() / 6 <<
" entries.");
95 std::string config_str{};
96 auto config_str_iter = std::back_inserter(config_str);
99 rv::for_each([&config_str_iter](
const auto& rec) {
100 const int mod_bitset = rec[5];
101 const bool mod_run_num = mod_bitset & 1;
102 const bool mod_evt_num = mod_bitset & (1 << 1);
103 const bool mod_lb_num = mod_bitset & (1 << 3);
110 std::format_to(config_str_iter,
111 "Run: {} [{:c}] LB: {} [{:c}] EVT: {} [{:c}] "
113 runNum, mod_run_num ?
'Y' :
'N', lbNum,
114 mod_lb_num ?
'Y' :
'N', evtNum,
115 mod_evt_num ?
'Y' :
'N', numEvts);
116 return ranges::yield_from(
118 static_cast<uint32_t>(lbNum), evtNum},
123 }
catch (
const std::bad_cast&) {
124 ATH_MSG_ERROR(
"Wrong type for property of EvtIdModifierSvc.");
131 ATH_CHECK(setProp(evtSel,
"SkipEvents",
"0"));
132 IEvtSelector::Context* ctx =
nullptr;
137 Service* evtSelSvc =
dynamic_cast<Service*
>(evtSel.get());
140 return StatusCode::FAILURE;
143 while (evtSel->next(*ctx).isSuccess()) {
146 IOpaqueAddress* addr =
nullptr;
147 ATH_CHECK(evtSel->createAddress(*ctx, addr));
154 std::vector<std::string> attr_lists;
156 const auto* attr_list_p =
158 if (attr_list_p !=
nullptr && attr_list_p->size() > 6) {
161 const auto runNum = attr_list[
"RunNumber"].data<
unsigned>();
162 const auto evtNum = attr_list[
"EventNumber"].data<
unsigned long long>();
163 const auto lbNum = attr_list[
"LumiBlockN"].data<
unsigned>();
164 evt_id = EvtId{
runNum, lbNum, evtNum};
169 if (
idx >= evts_skipped_before_mod && !modifier_evts.empty()) {
170 const std::size_t mod_idx =
171 (
idx - evts_skipped_before_mod) % modifier_evts.size();
172 evt_id.runNum = modifier_evts[mod_idx].runNum != 0U
173 ? modifier_evts[mod_idx].runNum
175 evt_id.lbNum = modifier_evts[mod_idx].lbNum != 0U
176 ? modifier_evts[mod_idx].lbNum
178 evt_id.evtNum = modifier_evts[mod_idx].evtNum != 0U
179 ? modifier_evts[mod_idx].evtNum
189 <<
" and rewinding");
198 incident_svc->addListener(
this,
"BeginRun");
199 incident_svc->addListener(
this,
"SkipEvents");
200 return StatusCode::SUCCESS;
212 return StatusCode::SUCCESS;
226 return StatusCode::SUCCESS;
230 if (inc.type() !=
"BeginRun"s && inc.type() !=
"SkipEvents"s) {
233 ATH_MSG_DEBUG(
"Received incident of type " << inc.type() <<
" from "
235 if (inc.type() ==
"SkipEvents"s) {
238 dynamic_cast<const ContextIncident<std::tuple<int, int>
>&>(inc);
240 auto end =
m_events.cbegin() + std::get<1>(cInc.tag()) +
243 if (!std::invoke(
fn,
begin,
end).isSuccess()) {
244 throw std::runtime_error(
245 "A skipEvent callback returned a failure error code!");