Skip to content

Commit

Permalink
Make it possible to add meta information post-hoc
Browse files Browse the repository at this point in the history
  • Loading branch information
tmadlener committed Apr 12, 2024
1 parent 8101944 commit eb57f57
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 18 deletions.
33 changes: 33 additions & 0 deletions test/utils/test_PIDHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,39 @@ TEST_CASE("PIDHandler from variadic list of collections", "[pid_utils]") {
}
}

TEST_CASE("PIDHandler w/ addMetaInfo", "[pid_utils]") {
using namespace edm4hep;
auto handler = utils::PIDHandler();

const auto recoColl = createRecos();
auto pidColl1 = createParticleIDs(recoColl, 1.0f);
for (auto pid : pidColl1) {
pid.setAlgorithmType(42);
}
const auto pidInfo1 = utils::ParticleIDMeta{"fancyAlgo", 42, {"p1", "p2"}};

handler.addColl(pidColl1, pidInfo1);

REQUIRE(handler.getAlgoType("fancyAlgo").value_or(0) == 42);
REQUIRE(handler.getParamIndex(42, "p2").value_or(-1) == 1);
REQUIRE(handler.getPID(recoColl[0], 42).value() == pidColl1[0]);

// Technically, we can even just add meta data without having a corresponding
// ParticleID collection to match
handler.addMetaInfo(utils::ParticleIDMeta{"anotherAlgo", 123, {}});
REQUIRE(handler.getAlgoType("anotherAlgo").value() == 123);

// Expected exceptions also get thrown
REQUIRE_THROWS_AS(handler.addMetaInfo(utils::ParticleIDMeta{"anotherAlgo", 321, {"param"}}), std::runtime_error);
// No information about this meta data can be obtained
REQUIRE_FALSE(handler.getParamIndex(321, "param").has_value());

REQUIRE_THROWS_AS(handler.addMetaInfo(utils::ParticleIDMeta{"newAlgo", 42, {"PARAM"}}), std::runtime_error);
// Existing meta info is unchanged
REQUIRE_FALSE(handler.getParamIndex(42, "PARAM").has_value());
REQUIRE(handler.getParamIndex(42, "p2").value_or(-1) == 1);
}

TEST_CASE("PIDHandler from Frame w/ metadata", "[pid_utils]") {
using namespace edm4hep;
const auto& [event, metadata] = createEventAndMetadata();
Expand Down
7 changes: 7 additions & 0 deletions utils/include/edm4hep/utils/ParticleIDUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,13 @@ class PIDHandler {
/// Add the information from one ParticleIDCollection to the handler
void addColl(const edm4hep::ParticleIDCollection& coll);

/// Add the information from one ParticleIDCollection to the handler together
/// with its meta data
void addColl(const edm4hep::ParticleIDCollection& coll, const edm4hep::utils::ParticleIDMeta& pidInfo);

/// Add meta information for a collection
void addMetaInfo(const edm4hep::utils::ParticleIDMeta& pidInfo);

/// Retrieve all ParticleIDs that are related to the passed
/// ReconstructedParticle
std::vector<edm4hep::ParticleID> getPIDs(const edm4hep::ReconstructedParticle& reco) const;
Expand Down
42 changes: 24 additions & 18 deletions utils/src/ParticleIDUtils.cc
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#include <edm4hep/utils/ParticleIDUtils.h>

#include "edm4hep/Constants.h"
#include "edm4hep/ReconstructedParticle.h"

#include <podio/FrameCategories.h>

Expand All @@ -18,30 +17,37 @@ void PIDHandler::addColl(const edm4hep::ParticleIDCollection& coll) {
}
}

void PIDHandler::addColl(const edm4hep::ParticleIDCollection& coll, const edm4hep::utils::ParticleIDMeta& pidInfo) {
addColl(coll);
addMetaInfo(pidInfo);
}

void PIDHandler::addMetaInfo(const edm4hep::utils::ParticleIDMeta& pidInfo) {
const auto [algoIt, inserted] = m_algoTypes.emplace(pidInfo.algoName, pidInfo.algoType);
if (!inserted) {
throw std::runtime_error("Cannot have duplicate algorithm names (" + pidInfo.algoName + " already exists)");
}

const auto [__, parInserted] = m_algoParamNames.emplace(pidInfo.algoType, pidInfo.paramNames);
if (!parInserted) {
if (inserted) {
m_algoTypes.erase(algoIt);
}
throw std::runtime_error("Cannot have duplicate algorithm types (" + std::to_string(pidInfo.algoType) +
" already exists)");
}
}

PIDHandler PIDHandler::from(const podio::Frame& event, const podio::Frame& metadata) {
PIDHandler handler{};
for (const auto& name : event.getAvailableCollections()) {
const auto* coll = event.get(name);
if (const auto pidColl = dynamic_cast<const edm4hep::ParticleIDCollection*>(coll)) {
handler.addColl(*pidColl);

const auto& algoName =
metadata.getParameter<std::string>(podio::collMetadataParamName(name, edm4hep::pidAlgoName));
const auto algoType = metadata.getParameter<int>(podio::collMetadataParamName(name, edm4hep::pidAlgoType));

// Here we have to assume that an empty name and an algoType of 0 simply
// mean that this has not been set at all
if (!algoName.empty() && algoType != 0) {
const auto [_, inserted] = handler.m_algoTypes.emplace(algoName, algoType);
if (!inserted) {
throw std::runtime_error("Cannot have duplicate algorithm names");
}

const auto& paramNames = metadata.getParameter<std::vector<std::string>>(
podio::collMetadataParamName(name, edm4hep::pidParameterNames));
if (!paramNames.empty()) {
handler.m_algoParamNames.emplace(algoType, paramNames);
}
auto maybeMetaInfo = PIDHandler::getAlgoInfo(metadata, name);
if (maybeMetaInfo) {
handler.addMetaInfo(std::move(maybeMetaInfo.value()));
}
}
}
Expand Down

0 comments on commit eb57f57

Please sign in to comment.