File indexing completed on 2026-10-30 08:33:36
0001
0002
0003
0004 #include <edm4hep/MCParticle.h>
0005 #include <podio/LinkNavigator.h>
0006 #include <podio/detail/LinkCollectionImpl.h>
0007 #include <cstddef>
0008 #include <format>
0009 #include <gsl/pointers>
0010 #include <stdexcept>
0011 #include <tuple>
0012 #include <vector>
0013
0014 #include "CalorimeterParticleIDPostML.h"
0015 #include "algorithms/interfaces/LinkTruthUtils.h"
0016
0017 namespace eicrecon {
0018
0019 void CalorimeterParticleIDPostML::init() {
0020
0021 }
0022
0023 void CalorimeterParticleIDPostML::process(const CalorimeterParticleIDPostML::Input& input,
0024 const CalorimeterParticleIDPostML::Output& output) const {
0025
0026 const auto [in_clusters, in_links, prediction_tensors] = input;
0027 auto [out_clusters, out_links, out_assocs, out_particle_ids] = output;
0028
0029 const truth::EventLinkNavigator<edm4eic::MCRecoClusterParticleLinkCollection> link_nav(in_links);
0030
0031 if (prediction_tensors->size() != 1) {
0032 error("Expected to find a single tensor, found {}", prediction_tensors->size());
0033 throw std::runtime_error("");
0034 }
0035 edm4eic::Tensor prediction_tensor = (*prediction_tensors)[0];
0036
0037 if (prediction_tensor.shape_size() != 2) {
0038 error("Expected tensor rank to be 2, but it is {}", prediction_tensor.shape_size());
0039 throw std::runtime_error(
0040 std::format("Expected tensor rank to be 2, but it is {}", prediction_tensor.shape_size()));
0041 }
0042
0043 if (prediction_tensor.getShape(0) != static_cast<long>(in_clusters->size())) {
0044 error("Length mismatch between tensor's 0th axis and number of clusters: {} != {}",
0045 prediction_tensor.getShape(0), in_clusters->size());
0046 throw std::runtime_error(
0047 std::format("Length mismatch between tensor's 0th axis and number of clusters: {} != {}",
0048 prediction_tensor.getShape(0), in_clusters->size()));
0049 }
0050
0051 if (prediction_tensor.getShape(1) != 2) {
0052 error("Expected 2 values per cluster in the output tensor, got {}",
0053 prediction_tensor.getShape(0));
0054 throw std::runtime_error(
0055 std::format("Expected 2 values per cluster in the output tensor, got {}",
0056 prediction_tensor.getShape(0)));
0057 }
0058
0059 if (prediction_tensor.getElementType() != 1) {
0060 error("Expected a tensor of floats, but element type is {}",
0061 prediction_tensor.getElementType());
0062 throw std::runtime_error(std::format("Expected a tensor of floats, but element type is {}",
0063 prediction_tensor.getElementType()));
0064 }
0065
0066 for (std::size_t cluster_ix = 0; cluster_ix < in_clusters->size(); cluster_ix++) {
0067 edm4eic::Cluster in_cluster = (*in_clusters)[cluster_ix];
0068 edm4eic::MutableCluster out_cluster = in_cluster.clone();
0069 out_clusters->push_back(out_cluster);
0070
0071 float prob_pion =
0072 prediction_tensor.getFloatData(cluster_ix * prediction_tensor.getShape(1) + 0);
0073 float prob_electron =
0074 prediction_tensor.getFloatData(cluster_ix * prediction_tensor.getShape(1) + 1);
0075
0076 out_cluster.addToParticleIDs(out_particle_ids->create(0,
0077 211,
0078 0,
0079 prob_pion
0080 ));
0081 out_cluster.addToParticleIDs(out_particle_ids->create(0,
0082 11,
0083 0,
0084 prob_electron
0085 ));
0086
0087
0088 if (link_nav.enabled() && out_links != nullptr && out_assocs != nullptr) {
0089 for (const auto& [sim_particle, weight] : link_nav.linked(in_cluster)) {
0090 truth::addWeightedRelation(
0091 out_cluster, sim_particle, weight,
0092 gsl::not_null<edm4eic::MCRecoClusterParticleLinkCollection*>{out_links},
0093 gsl::not_null<edm4eic::MCRecoClusterParticleAssociationCollection*>{out_assocs});
0094 }
0095 }
0096 }
0097 }
0098
0099 }