16 template <
unsigned int N>
18 using In_t = Writer_t<1>::input_type;
19 using Consumer_t = Writer_t<1>::consumer_type;
22 template <
typename A=detail::defaultAccessor_t<Consumer_t>>
23 void addCustomType(Consumer_t&
c,
25 A a=detail::defaultAccessor<Consumer_t>) {
29 throw std::logic_error(
"called addCustomType on non-custom type");
36 const std::string
s =
p.source;
37 const std::string
t =
p.target;
45 [
a,
f, mult](
I in) ->
float {
46 const auto* associated =
a(in);
47 if (!associated)
return NAN;
48 return f(associated)*mult;
54 auto match = [&
add,
s, &
m, half](
const std::string&
n,
auto func) {
64 auto matchGeV = [&
add,
s, &
m, half](
const std::string&
n,
auto func) {
71 throw std::logic_error(
72 "asked for a full precision version of a variable that can"
73 " not be stored at half precision: " +
s);
77 }
else if (
s ==
n +
"GeV") {
78 add(func, half, 0.001);
84 matchGeV(
"pt", [](
auto in) {
return in->pt(); });
85 match(
"eta", [](
auto in) {
return in->eta(); });
86 match(
"phi", [](
auto in) {
return in->phi(); });
87 matchGeV(
"px", [](
auto in) {
return in->p4().Px(); });
88 matchGeV(
"py", [](
auto in) {
return in->p4().Py(); });
89 matchGeV(
"pz", [](
auto in) {
return in->p4().Pz(); });
90 matchGeV(
"mass", [](
auto in) {
return in->m(); });
95 c.add<
bool>(
s, [](
I) {
return true; },
false);
98 throw std::logic_error(
"unknow known custom primitive: " +
s);
103 template <
typename T,
typename R=SG::AuxElement>
107 LinkGetter(std::string
name);
108 const R* operator()(In_t in)
const;
111 const LinkAccessor m_accessor;
112 const std::string m_linkName;
114 template <
typename T,
typename R>
115 LinkGetter<T,R>::LinkGetter(std::string
name):
119 template <
typename T,
typename R>
120 const R* LinkGetter<T,R>::operator()(In_t in)
const {
121 auto elink = m_accessor(*in);
127 if (elink.isDefault()) {
134 if (!elink.isValid()) {
135 throw std::runtime_error(
"invalid link " + m_linkName);
140 CountWriter_t::consumer_type getOffsetConsumer()
142 using CountIn_t = CountWriter_t::input_type;
143 CountWriter_t::consumer_type
c;
144 c.add<CountIn_t>(
"count", [](CountIn_t
i) {
return i; });
157 virtual void fill(
const std::vector<const xAOD::IParticle*>&
info) = 0;
166 Writer_t<1> m_writer;
169 const std::string&
n,
171 long long unsigned size):
173 ~IParticle2dWriter() =
default;
175 void fill(
const std::vector<In_t>&
v)
override {
178 void flush()
override {
188 Writer_t<0> m_writer;
189 CountWriter_t m_counts;
192 const std::string&
n,
194 m_group(
parent.createGroup(
n)),
195 m_writer(m_group,
"raw",
c),
196 m_counts(m_group,
"counts", getOffsetConsumer())
198 ~IParticleAwkwardWriter() =
default;
200 void fill(
const std::vector<In_t>&
v)
override {
201 using Count_t = CountWriter_t::input_type;
203 auto n_entries =
v.size();
204 if (n_entries >
max) {
205 throw std::overflow_error(
206 "number of entries exceeds maximum for this datatype "
210 for (
const auto&
e:
v) m_writer.fill(
e);
211 m_counts.fill(n_entries);
213 void flush()
override {
225 Writer_t<0> m_writer;
228 const std::string&
n,
232 ~IParticleFlatWriter() =
default;
234 void fill(
const std::vector<In_t>&
v)
override {
235 for (
const auto&
e:
v) m_writer.fill(
e);
237 void flush()
override {
242 std::unique_ptr<details::IParticleWriterBase> getWriter(
247 switch (
cfg.format) {
249 if (
cfg.maximum_size != 0) {
250 throw std::domain_error(
251 "no maximum_size should be specified for awkward arrays");
253 return std::make_unique<IParticleAwkwardWriter>(
g,
cfg.name,
c);
256 if (
cfg.maximum_size != 0) {
257 throw std::domain_error(
258 "no maximum_size should be specified for flat arrays");
260 return std::make_unique<IParticleFlatWriter>(
g,
cfg.name,
c);
263 if (
cfg.maximum_size == 0) {
264 throw std::domain_error(
265 "maximum_size should be specified for padded 2d arrays");
267 return std::make_unique<IParticle2dWriter>(
271 throw std::domain_error(
"unknown array format");
282 using input_type = In_t;
286 for (
const auto&
input:
cfg.inputs) {
287 if (
input.link_name.empty()) {
288 const auto& primitive =
input.input;
290 addCustomType(
c, primitive);
296 std::string
n =
input.link_name;
298 if (
n ==
"btaggingLink") {
299 LinkGetter<xAOD::BTaggingContainer> getter(
n);
303 LinkGetter<IPC,IP> getter(
n);
305 addCustomType(
c,
input.input, getter);