Warning, file /EICrecon/src/algorithms/pid/MergeParticleID.cc was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004 #include "MergeParticleID.h"
0005
0006 #include <algorithms/logger.h>
0007 #include <edm4eic/CherenkovParticleIDHypothesis.h>
0008 #include <edm4eic/TrackSegmentCollection.h>
0009 #include <edm4hep/Vector2f.h>
0010 #include <fmt/core.h>
0011 #include <podio/ObjectID.h>
0012 #include <podio/RelationRange.h>
0013 #include <cstddef>
0014 #include <gsl/pointers>
0015 #include <iterator>
0016 #include <stdexcept>
0017 #include <unordered_map>
0018 #include <utility>
0019
0020 #include "algorithms/pid/MergeParticleIDConfig.h"
0021 #include "algorithms/pid/Tools.h"
0022
0023 namespace eicrecon {
0024
0025 void MergeParticleID::init() { debug() << m_cfg << endmsg; }
0026
0027 void MergeParticleID::process(const MergeParticleID::Input& input,
0028 const MergeParticleID::Output& output) const {
0029
0030 const auto [in_pid_collections_list] = input;
0031 auto [out_pids] = output;
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066 std::unordered_map<decltype(podio::ObjectID::index),
0067 std::vector<std::pair<std::size_t, std::size_t>>>
0068 particle_pids;
0069 trace("{:-<70}", "Build `particle_pids` indexing data structure ");
0070
0071
0072 for (std::size_t idx_coll = 0; idx_coll < in_pid_collections_list.size(); idx_coll++) {
0073 const auto& in_pid_collection = in_pid_collections_list.at(idx_coll);
0074 trace("idx_col={}", idx_coll);
0075
0076
0077 for (std::size_t idx_pid = 0; idx_pid < in_pid_collection->size(); idx_pid++) {
0078
0079 const auto& in_pid = in_pid_collection->at(idx_pid);
0080 const auto& charged_particle_track_segment = in_pid.getChargedParticle();
0081 if (!charged_particle_track_segment.isAvailable()) {
0082 error("PID object found with no charged particle");
0083 continue;
0084 }
0085 auto id_particle = charged_particle_track_segment.getObjectID().index;
0086 auto idx_paired = std::make_pair(idx_coll, idx_pid);
0087 trace(" idx_pid={} id_particle={}", idx_pid, id_particle);
0088
0089
0090 auto it = particle_pids.find(id_particle);
0091 if (it == particle_pids.end()) {
0092 particle_pids.insert({id_particle, {idx_paired}});
0093 } else {
0094 it->second.push_back(idx_paired);
0095 }
0096 }
0097 }
0098
0099
0100 if (level() <= algorithms::LogLevel::kTrace) {
0101 trace("{:-<70}", "Resulting `particle_pids` ");
0102 for (auto& [id_particle, idx_paired_list] : particle_pids) {
0103 trace("id_particle={}", id_particle);
0104 for (auto& [idx_coll, idx_pid] : idx_paired_list) {
0105 trace(" (idx_coll, idx_pid) = ({}, {})", idx_coll, idx_pid);
0106 }
0107 }
0108 }
0109
0110
0111
0112
0113
0114 trace("{:-<70}", "Begin Merging PID Objects ");
0115 for (auto& [id_particle, idx_paired_list] : particle_pids) {
0116
0117
0118 trace("Charged Particle:");
0119 trace(" id = {}", id_particle);
0120 trace(" PID Hypotheses:");
0121
0122
0123 auto out_pid = out_pids->create();
0124 decltype(edm4eic::CherenkovParticleIDData::npe) out_npe = 0.0;
0125 decltype(edm4eic::CherenkovParticleIDData::refractiveIndex) out_refractiveIndex = 0.0;
0126 decltype(edm4eic::CherenkovParticleIDData::photonEnergy) out_photonEnergy = 0.0;
0127
0128
0129 std::unordered_map<decltype(edm4eic::CherenkovParticleIDHypothesis::PDG),
0130 edm4eic::CherenkovParticleIDHypothesis>
0131 pdg_2_out_hyp;
0132
0133
0134 for (auto& [idx_coll, idx_pid] : idx_paired_list) {
0135 const auto& in_pid = in_pid_collections_list.at(idx_coll)->at(idx_pid);
0136
0137
0138 trace(" Hypotheses for PID result (idx_coll, idx_pid) = ({}, {}):", idx_coll, idx_pid);
0139 trace(Tools::HypothesisTableHead(6));
0140
0141
0142 out_npe += in_pid.getNpe();
0143 out_refractiveIndex += in_pid.getNpe() * in_pid.getRefractiveIndex();
0144 out_photonEnergy += in_pid.getNpe() * in_pid.getPhotonEnergy();
0145
0146
0147 for (auto in_photon_vec : in_pid.getThetaPhiPhotons()) {
0148 out_pid.addToThetaPhiPhotons(in_photon_vec);
0149 }
0150
0151
0152 if (!out_pid.getChargedParticle().isAvailable()) {
0153 out_pid.setChargedParticle(in_pid.getChargedParticle());
0154 }
0155
0156
0157 for (auto in_hyp : in_pid.getHypotheses()) {
0158 trace(Tools::HypothesisTableLine(in_hyp, 6));
0159 auto out_hyp_it = pdg_2_out_hyp.find(in_hyp.PDG);
0160 if (out_hyp_it == pdg_2_out_hyp.end()) {
0161 edm4eic::CherenkovParticleIDHypothesis out_hyp;
0162 out_hyp.PDG = in_hyp.PDG;
0163 out_hyp.npe = in_hyp.npe;
0164 out_hyp.weight = in_hyp.weight;
0165 pdg_2_out_hyp.insert({out_hyp.PDG, out_hyp});
0166 } else {
0167 auto& out_hyp = out_hyp_it->second;
0168 out_hyp.npe += in_hyp.npe;
0169
0170 switch (m_cfg.mergeMode) {
0171 case MergeParticleIDConfig::kAddWeights:
0172 out_hyp.weight += in_hyp.weight;
0173 break;
0174 case MergeParticleIDConfig::kMultiplyWeights:
0175 out_hyp.weight *= in_hyp.weight;
0176 break;
0177 default:
0178 throw std::runtime_error(
0179 "unknown MergeParticleIDConfig::mergeMode setting; weights not combined");
0180 }
0181 }
0182 }
0183
0184 }
0185
0186
0187 out_pid.setNpe(out_npe);
0188 if (out_npe > 0) {
0189 out_pid.setRefractiveIndex(out_refractiveIndex / out_npe);
0190 out_pid.setPhotonEnergy(out_photonEnergy / out_npe);
0191 }
0192
0193
0194 for (auto [pdg, out_hyp] : pdg_2_out_hyp) {
0195 out_pid.addToHypotheses(out_hyp);
0196 }
0197
0198
0199 trace(" => merged hypothesis weights:");
0200 trace(Tools::HypothesisTableHead(6));
0201 for (auto out_hyp : out_pid.getHypotheses()) {
0202 trace(Tools::HypothesisTableLine(out_hyp, 6));
0203 }
0204
0205 }
0206 }
0207
0208 }