15 const std::string&
name)
18 return [](
const xAOD::Jet& j) ->
float {
return j.pt();};
20 if (
name ==
"log_pt") {
24 return [](
const xAOD::Jet& j) ->
float {
return j.eta();};
26 if (
name ==
"abs_eta") {
27 return [](
const xAOD::Jet& j) ->
float {
return std::abs(j.eta());};
29 if (
name ==
"energy") {
30 return [](
const xAOD::Jet& j) ->
float {
return j.e();};
33 return [](
const xAOD::Jet& j) ->
float {
return j.m();};
36 throw std::logic_error(
"no match for custom getter " +
name);
43 template <
typename T,
typename U>
49 NamedSeqGetter(
const std::string&
name):
54 std::pair<std::string, std::vector<double>>
55 operator()(
const xAOD::Jet&,
const std::vector<const U*>& constituents)
const {
56 std::vector<double> sequence;
57 for (
const U*
el: constituents) {
58 sequence.push_back(m_getter(*
el));
60 return {m_name, sequence};
65 template <
typename Const>
72 CustomSeqGetter(
F getter): m_getter(getter) {}
75 operator()(
const xAOD::Jet&
jet,
const std::vector<const Const*>& constituents)
const {
76 std::vector<double> sequence;
77 sequence.reserve(constituents.size());
78 for (
const auto* constituent: constituents) {
79 sequence.push_back(m_getter(*constituent,
jet));
86 std::optional<SequenceGetterFunc<xAOD::TrackParticle>>
87 getterFromTracksWithIpDep(
88 const std::string&
name,
95 if (
name ==
"IP3D_signed_d0_significance") {
96 return CustomSeqGetter<Tp>([
a](
const Tp&
tp,
const Jet& j){
97 return a.getSignedIp(
tp, j).ip3d_signed_d0_significance;
100 if (
name ==
"IP3D_signed_z0_significance") {
101 return CustomSeqGetter<Tp>([
a](
const Tp&
tp,
const Jet& j){
102 return a.getSignedIp(
tp, j).ip3d_signed_z0_significance;
105 if (
name ==
"IP2D_signed_d0") {
106 return CustomSeqGetter<Tp>([
a](
const Tp&
tp,
const Jet& j){
107 return a.getSignedIp(
tp, j).ip2d_signed_d0;
110 if (
name ==
"IP3D_signed_d0") {
111 return CustomSeqGetter<Tp>([
a](
const Tp&
tp,
const Jet& j){
112 return a.getSignedIp(
tp, j).ip3d_signed_d0;
115 if (
name ==
"IP3D_signed_z0") {
116 return CustomSeqGetter<Tp>([
a](
const Tp&
tp,
const Jet& j){
117 return a.getSignedIp(
tp, j).ip3d_signed_z0;
120 if (
name ==
"d0" ||
name ==
"btagIp_d0") {
121 return CustomSeqGetter<Tp>([
a](
const Tp&
tp,
const Jet&){
125 if (
name ==
"z0SinTheta" ||
name ==
"btagIp_z0SinTheta") {
126 return CustomSeqGetter<Tp>([
a](
const Tp&
tp,
const Jet&){
127 return a.z0SinTheta(
tp);
130 if (
name ==
"d0Uncertainty") {
131 return CustomSeqGetter<Tp>([
a](
const Tp&
tp,
const Jet&){
132 return a.d0Uncertainty(
tp);
135 if (
name ==
"z0SinThetaUncertainty") {
136 return CustomSeqGetter<Tp>([
a](
const Tp&
tp,
const Jet&){
137 return a.z0SinThetaUncertainty(
tp);
145 std::optional<SequenceGetterFunc<xAOD::TrackParticle>>
146 getterFromTracksNoIpDep(
const std::string&
name)
151 if (
name ==
"phiUncertainty") {
152 return CustomSeqGetter<Tp>([](
const Tp&
tp,
const Jet&) {
153 return std::sqrt(
tp.definingParametersCovMatrixDiagVec().at(2));
156 if (
name ==
"thetaUncertainty") {
157 return CustomSeqGetter<Tp>([](
const Tp&
tp,
const Jet&) {
158 return std::sqrt(
tp.definingParametersCovMatrixDiagVec().at(3));
161 if (
name ==
"qOverPUncertainty") {
162 return CustomSeqGetter<Tp>([](
const Tp&
tp,
const Jet&) {
163 return std::sqrt(
tp.definingParametersCovMatrixDiagVec().at(4));
166 if (
name ==
"z0RelativeToBeamspot") {
167 return CustomSeqGetter<Tp>([](
const Tp&
tp,
const Jet&) {
171 if (
name ==
"log_z0RelativeToBeamspotUncertainty") {
172 return CustomSeqGetter<Tp>([](
const Tp&
tp,
const Jet&) {
173 return std::log(std::sqrt(
tp.definingParametersCovMatrixDiagVec().at(1)));
176 if (
name ==
"z0RelativeToBeamspotUncertainty") {
177 return CustomSeqGetter<Tp>([](
const Tp&
tp,
const Jet&) {
178 return std::sqrt(
tp.definingParametersCovMatrixDiagVec().at(1));
181 if (
name ==
"numberOfPixelHitsInclDead") {
184 return CustomSeqGetter<Tp>([pix_hits, pix_dead](
const Tp&
tp,
const Jet&) {
185 return pix_hits(
tp) + pix_dead(
tp);
188 if (
name ==
"numberOfSCTHitsInclDead") {
191 return CustomSeqGetter<Tp>([sct_hits, sct_dead](
const Tp&
tp,
const Jet&) {
192 return sct_hits(
tp) + sct_dead(
tp);
195 if (
name ==
"numberOfInnermostPixelLayerHits21p9") {
198 return CustomSeqGetter<Tp>([barrel_hits, endcap_hits](
const Tp&
tp,
const Jet&) {
199 return barrel_hits(
tp) + endcap_hits(
tp);
202 if (
name ==
"numberOfNextToInnermostPixelLayerHits21p9") {
205 return CustomSeqGetter<Tp>([barrel_hits, endcap_hits](
const Tp&
tp,
const Jet&) {
206 return barrel_hits(
tp) + endcap_hits(
tp);
209 if (
name ==
"numberOfInnermostPixelLayerSharedHits21p9") {
212 return CustomSeqGetter<Tp>([barrel_hits, endcap_hits](
const Tp&
tp,
const Jet&) {
213 return barrel_hits(
tp) + endcap_hits(
tp);
216 if (
name ==
"numberOfInnermostPixelLayerSplitHits21p9") {
219 return CustomSeqGetter<Tp>([barrel_hits, endcap_hits](
const Tp&
tp,
const Jet&) {
220 return barrel_hits(
tp) + endcap_hits(
tp);
228 template <
typename T> std::optional<SequenceGetterFunc<T>>
229 getterFromIParticles(
const std::string&
name)
233 return CustomSeqGetter<T>([](
const T&
p,
const Jet&) {
237 if (
name ==
"log_pt") {
238 return CustomSeqGetter<T>([](
const T&
p,
const Jet&) {
242 if (
name ==
"ptfrac") {
243 return CustomSeqGetter<T>([](
const T&
p,
const Jet& j) {
244 return p.pt() / j.
pt();
247 if (
name ==
"log_ptfrac") {
248 return CustomSeqGetter<T>([](
const T&
p,
const Jet& j) {
253 return CustomSeqGetter<T>([](
const T&
p,
const Jet&) {
257 if (
name ==
"deta") {
258 return CustomSeqGetter<T>([](
const T&
p,
const Jet& j) {
259 return p.eta() - j.
eta();
262 if (
name ==
"abs_deta") {
263 return CustomSeqGetter<T>([](
const T&
p,
const Jet& j) {
264 return copysign(1.0, j.
eta()) * (
p.eta() - j.
eta());
268 return CustomSeqGetter<T>([](
const T&
p,
const Jet&) {
272 if (
name ==
"dphi") {
273 return CustomSeqGetter<T>([](
const T&
p,
const Jet& j) {
274 return p.p4().DeltaPhi(j.p4());
278 return CustomSeqGetter<T>([](
const T&
p,
const Jet& j) {
282 if (
name ==
"log_dr") {
283 return CustomSeqGetter<T>([](
const T&
p,
const Jet& j) {
287 if (
name ==
"log_dr_nansafe") {
288 return CustomSeqGetter<T>([](
const T&
p,
const Jet& j) {
289 return std::log(
p.p4().DeltaR(j.p4()) + 1
e-7);
292 if (
name ==
"mass") {
293 return CustomSeqGetter<T>([](
const T&
p,
const Jet&) {
297 if (
name ==
"energy") {
298 return CustomSeqGetter<T>([](
const T&
p,
const Jet&) {
307 namespace getter_utils {
317 std::function<std::pair<std::string, double>(
const xAOD::Jet&)>
319 auto getter = customJetGetter(
name);
321 return std::make_pair(
name, getter(j));
327 template <
typename T>
328 std::pair<SequenceGetterFunc<T>, std::set<std::string>>
331 if constexpr (std::is_same_v<T, xAOD::TrackParticle>) {
332 if (
auto getter = getterFromTracksWithIpDep(
name,
prefix)) {
334 return {*getter, deps};
336 if (
auto getter = getterFromTracksNoIpDep(
name)) {
337 return {*getter, {}};
340 if (
auto getter = getterFromIParticles<T>(
name)){
341 return {*getter, {}};
343 throw std::logic_error(
"no match for custom getter " +
name);
349 template <
typename T>
350 std::pair<typename SeqGetter<T>::InputSequence, std::set<std::string>>
352 auto [getter, deps] = buildCustomSeqGetter<T>(
name,
prefix);
355 return std::make_pair(
n,
g(j,
t));
361 template <
typename T>
362 std::pair<typename SeqGetter<T>::InputSequence, std::set<std::string>>
367 NamedSeqGetter<int, T>(
cfg.name), {
cfg.name}
370 NamedSeqGetter<float, T>(
cfg.name), {
cfg.name}
373 NamedSeqGetter<char, T>(
cfg.name), {
cfg.name}
376 NamedSeqGetter<unsigned char, T>(
cfg.name), {
cfg.name}
379 return getNamedCustomSeqGetter(
383 throw std::logic_error(
"Unknown EDM type for constituent.");
388 template <
typename T>
391 std::map<std::string, std::string>
remap =
options.remap_scalar;
393 auto [seqGetter, seq_deps] = seqFromConsituents(input_cfg,
options);
395 if(input_cfg.flip_sign){
397 auto [
n,
v] =
g(
jet,constituents);
398 std::for_each(
v.begin(),
v.end(), [](
double &
n){ n=-1.0*n; });
399 return std::make_pair(
n,
v);
401 m_sequence_getters.push_back(seqGetter_flip);
404 m_sequence_getters.push_back(seqGetter);
406 m_deps.merge(seq_deps);
407 if (
auto h =
remap.extract(input_cfg.name)){
408 m_used_remap.insert(
h.key());
413 template <
typename T>
417 std::vector<float> cnsts_feats;
418 int num_vars = m_sequence_getters.size();
421 int cnst_var_idx = 0;
422 for (
const auto& seq_getter: m_sequence_getters){
423 auto input_sequence = seq_getter(
jet, constituents).second;
425 if (cnst_var_idx==0){
426 num_cnsts =
static_cast<int>(input_sequence.size());
427 cnsts_feats.resize(num_cnsts * num_vars);
431 for (
unsigned int cnst_idx=0; cnst_idx<input_sequence.size(); cnst_idx++){
432 cnsts_feats.at(cnst_idx*num_vars + cnst_var_idx) = input_sequence.at(cnst_idx);
436 std::vector<int64_t> cnsts_feat_dim = {num_cnsts, num_vars};
437 return {cnsts_feats, cnsts_feat_dim};
440 template <
typename T>
444 std::map<std::string, std::vector<double>> feats;
445 for (
const auto& seq_getter: m_sequence_getters){
446 feats.insert(seq_getter(
jet, constituents));
451 template <
typename T>
455 template <
typename T>