Skip to content

Commit

Permalink
feat: add whiteboard aliases (#1588)
Browse files Browse the repository at this point in the history
I noticed that a lot of information on the whiteboard rolls from one algorithm to the next but requires a different name in the process. that makes it hard to use the correct name downstream.

this PR adds an alias mechanism to the sequencer. the alias can be changes from one entry to the next. when queried the sequencer will return the entry behind the alias.
  • Loading branch information
andiwand authored Nov 3, 2022
1 parent 890eff9 commit 5addf02
Show file tree
Hide file tree
Showing 9 changed files with 103 additions and 64 deletions.
16 changes: 3 additions & 13 deletions CI/physmon/physmon.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,23 +188,15 @@
if label == "seeded":
addAmbiguityResolution(
s,
AmbiguityResolutionConfig(
maximumSharedHits=3,
),
AmbiguityResolutionConfig(maximumSharedHits=3),
CKFPerformanceConfig(ptMin=400.0 * u.MeV, nMeasurementsMin=6),
outputDirRoot=tp,
)

addVertexFitting(
s,
field,
trajectories="trajectories" if label == "seeded" else None,
trackParameters="filteredTrackParameters"
if label == "seeded"
else "fittedTrackParameters",
trackParametersTips="filteredTrackParametersTips"
if label == "seeded"
else "fittedTrackParametersTips",
associatedParticles=None if label == "seeded" else "particles_input",
vertexFinder=VertexFinder.Iterative,
outputDirRoot=tp,
)
Expand Down Expand Up @@ -326,9 +318,7 @@

addAmbiguityResolution(
s,
AmbiguityResolutionConfig(
maximumSharedHits=3,
),
AmbiguityResolutionConfig(maximumSharedHits=3),
CKFPerformanceConfig(ptMin=400.0 * u.MeV, nMeasurementsMin=6),
outputDirRoot=None,
)
Expand Down
13 changes: 10 additions & 3 deletions Examples/Framework/include/ActsExamples/Framework/Sequencer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <memory>
#include <optional>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>

Expand Down Expand Up @@ -52,7 +53,7 @@ class Sequencer {
IterationCallback iterationCallback = []() {};
};

Sequencer(const Config& cfg);
Sequencer(const Config &cfg);

/// Add a service to the set of services.
///
Expand All @@ -75,6 +76,10 @@ class Sequencer {
/// @throws std::invalid_argument if the writer is NULL.
void addWriter(std::shared_ptr<IWriter> writer);

/// Add an alias to the whiteboard.
void addWhiteboardAlias(const std::string &aliasName,
const std::string &objectName);

/// Run the event loop.
///
/// @return status code compatible with the `main()` return code
Expand Down Expand Up @@ -104,7 +109,7 @@ class Sequencer {
int run();

/// Get const access to the config
const Config& config() const { return m_cfg; }
const Config &config() const { return m_cfg; }

private:
/// List of all configured algorithm names.
Expand All @@ -121,7 +126,9 @@ class Sequencer {
std::vector<std::shared_ptr<IWriter>> m_writers;
std::unique_ptr<const Acts::Logger> m_logger;

const Acts::Logger& logger() const { return *m_logger; }
std::unordered_map<std::string, std::string> m_whiteboardObjectAliases;

const Acts::Logger &logger() const { return *m_logger; }
};

} // namespace ActsExamples
18 changes: 13 additions & 5 deletions Examples/Framework/include/ActsExamples/Framework/WhiteBoard.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ namespace ActsExamples {
class WhiteBoard {
public:
WhiteBoard(std::unique_ptr<const Acts::Logger> logger =
Acts::getDefaultLogger("WhiteBoard", Acts::Logging::INFO));
Acts::getDefaultLogger("WhiteBoard", Acts::Logging::INFO),
std::unordered_map<std::string, std::string> objectAliases = {});

// A WhiteBoard holds unique elements and can not be copied
WhiteBoard(const WhiteBoard& other) = delete;
Expand Down Expand Up @@ -75,16 +76,18 @@ class WhiteBoard {
};

std::unique_ptr<const Acts::Logger> m_logger;
std::unordered_map<std::string, std::unique_ptr<IHolder>> m_store;
std::unordered_map<std::string, std::shared_ptr<IHolder>> m_store;
std::unordered_map<std::string, std::string> m_objectAliases;

const Acts::Logger& logger() const { return *m_logger; }
};

} // namespace ActsExamples

inline ActsExamples::WhiteBoard::WhiteBoard(
std::unique_ptr<const Acts::Logger> logger)
: m_logger(std::move(logger)) {}
std::unique_ptr<const Acts::Logger> logger,
std::unordered_map<std::string, std::string> objectAliases)
: m_logger(std::move(logger)), m_objectAliases(std::move(objectAliases)) {}

template <typename T>
inline void ActsExamples::WhiteBoard::add(const std::string& name, T&& object) {
Expand All @@ -94,8 +97,13 @@ inline void ActsExamples::WhiteBoard::add(const std::string& name, T&& object) {
if (0 < m_store.count(name)) {
throw std::invalid_argument("Object '" + name + "' already exists");
}
m_store.emplace(name, std::make_unique<HolderT<T>>(std::forward<T>(object)));
auto holder = std::make_shared<HolderT<T>>(std::forward<T>(object));
m_store.emplace(name, holder);
ACTS_VERBOSE("Added object '" << name << "'");
if (auto it = m_objectAliases.find(name); it != m_objectAliases.end()) {
m_store[it->second] = holder;
ACTS_VERBOSE("Added alias object '" << it->second << "'");
}
}

template <typename T>
Expand Down
16 changes: 14 additions & 2 deletions Examples/Framework/src/Framework/Sequencer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <chrono>
#include <exception>
#include <numeric>
#include <stdexcept>

#ifndef ACTS_EXAMPLES_NO_TBB
#include <TROOT.h>
Expand Down Expand Up @@ -83,6 +84,15 @@ void ActsExamples::Sequencer::addWriter(std::shared_ptr<IWriter> writer) {
ACTS_INFO("Added writer '" << m_writers.back()->name() << "'");
}

void ActsExamples::Sequencer::addWhiteboardAlias(
const std::string& aliasName, const std::string& objectName) {
auto [it, success] =
m_whiteboardObjectAliases.insert({objectName, aliasName});
if (!success) {
throw std::invalid_argument("Alias to '" + objectName + "' already set");
}
}

std::vector<std::string> ActsExamples::Sequencer::listAlgorithmNames() const {
std::vector<std::string> names;

Expand Down Expand Up @@ -291,8 +301,10 @@ int ActsExamples::Sequencer::run() {
for (size_t event = r.begin(); event != r.end(); ++event) {
m_cfg.iterationCallback();
// Use per-event store
WhiteBoard eventStore(Acts::getDefaultLogger(
"EventStore#" + std::to_string(event), m_cfg.logLevel));
WhiteBoard eventStore(
Acts::getDefaultLogger("EventStore#" + std::to_string(event),
m_cfg.logLevel),
m_whiteboardObjectAliases);
// If we ever wanted to run algorithms in parallel, this needs to be
// changed to Algorithm context copies
AlgorithmContext context(0, event, eventStore);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,19 @@ class RootVertexPerformanceWriter final
: public WriterT<std::vector<Acts::Vertex<Acts::BoundTrackParameters>>> {
public:
struct Config {
/// All input truth particle collection
/// All input truth particle collection.
std::string inputAllTruthParticles;
/// Selected input truth particle collection
/// Selected input truth particle collection.
std::string inputSelectedTruthParticles;
/// Truth particles associated to tracks
/// Optional. Truth particles associated to tracks. Using 1:1 matching if
/// given.
std::string inputAssociatedTruthParticles;
/// Input track parameters
/// Input track parameters.
std::string inputTrackParameters;
/// Input track parameters tips (points from `inputTrackParameters` to
/// `inputTrajectories`)
/// `inputTrajectories`).
std::string inputTrackParametersTips;
/// Trajectories object from track finidng
/// Trajectories object from track finidng.
std::string inputTrajectories;
/// Input hit-particles map collection.
std::string inputMeasurementParticlesMap;
Expand All @@ -59,10 +60,10 @@ class RootVertexPerformanceWriter final
/// File access mode.
std::string fileMode = "RECREATE";
/// Minimum fraction of tracks matched between truth
/// and reco vertices to be matched for resolution plots
/// and reco vertices to be matched for resolution plots.
double minTrackVtxMatchFraction = 0.5;
/// Minimum fraction of hits associated to particle to consider
/// as truth matched
/// as truth matched.
double truthMatchProbMin = 0.5;
};

Expand Down
2 changes: 1 addition & 1 deletion Examples/Python/python/acts/examples/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import sys, inspect
from typing import Optional, Protocol, Dict
from typing import Optional, Protocol

from acts.ActsPythonBindings._examples import *
from acts import ActsPythonBindings
Expand Down
81 changes: 50 additions & 31 deletions Examples/Python/python/acts/examples/reconstruction.py
Original file line number Diff line number Diff line change
Expand Up @@ -712,9 +712,6 @@ def addCKFTracks(
customLogLevel = acts.examples.defaultLogging(s, logLevel)
logger = acts.logging.getLogger("addCKFTracks")

outputTrackParameters = "fittedTrackParameters"
outputTrackParametersTips = "fittedTrackParametersTips"

# Setup the track finding algorithm with CKF
# It takes all the source links created from truth hit smearing, seeds from
# truth particle smearing and source link selection config
Expand All @@ -727,27 +724,38 @@ def addCKFTracks(
inputSourceLinks="sourcelinks",
inputInitialTrackParameters="estimatedparameters",
outputTrajectories="trajectories",
outputTrackParameters=outputTrackParameters
+ ("" if trackSelectorRanges is None else "Tmp"),
outputTrackParametersTips=outputTrackParametersTips
+ ("" if trackSelectorRanges is None else "Tmp"),
outputTrackParameters="fittedTrackParameters",
outputTrackParametersTips="fittedTrackParametersTips",
findTracks=acts.examples.TrackFindingAlgorithm.makeTrackFinderFunction(
trackingGeometry, field
),
)
s.addAlgorithm(trackFinder)

s.addWhiteboardAlias("trajectories", trackFinder.config.outputTrajectories)
s.addWhiteboardAlias("trackParameters", trackFinder.config.outputTrackParameters)
s.addWhiteboardAlias(
"trackParametersTips", trackFinder.config.outputTrackParametersTips
)

if trackSelectorRanges is not None:
addTrackSelection(
trackSelector = addTrackSelection(
s,
trackSelectorRanges,
inputTrackParameters=trackFinder.config.outputTrackParameters,
inputTrackParametersTips=trackFinder.config.outputTrackParametersTips,
outputTrackParameters=outputTrackParameters,
outputTrackParametersTips=outputTrackParametersTips,
outputTrackParameters="selectedFittedTrackParameters",
outputTrackParametersTips="selectedFittedTrackParametersTips",
logLevel=customLogLevel(),
)

s.addWhiteboardAlias(
"trackParameters", trackSelector.config.outputTrackParameters
)
s.addWhiteboardAlias(
"trackParametersTips", trackSelector.config.outputTrackParametersTips
)

if outputDirRoot is not None:
outputDirRoot = Path(outputDirRoot)
if not outputDirRoot.exists():
Expand Down Expand Up @@ -830,7 +838,7 @@ def addTrackSelection(
outputTrackParameters: str,
outputTrackParametersTips: str,
logLevel: Optional[acts.logging.Level] = None,
):
) -> acts.examples.TrackSelector:

customLogLevel = acts.examples.defaultLogging(s, logLevel)

Expand Down Expand Up @@ -862,6 +870,8 @@ def addTrackSelection(

s.addAlgorithm(trackSelector)

return trackSelector


ExaTrkXBackend = Enum("ExaTrkXBackend", "Torch Onnx")

Expand Down Expand Up @@ -965,18 +975,17 @@ def addAmbiguityResolution(
outputDirRoot: Optional[Union[Path, str]] = None,
logLevel: Optional[acts.logging.Level] = None,
) -> None:
from acts.examples import (
AmbiguityResolutionAlgorithm,
)

from acts.examples import AmbiguityResolutionAlgorithm

customLogLevel = acts.examples.defaultLogging(s, logLevel)

alg = AmbiguityResolutionAlgorithm(
level=customLogLevel(),
inputSourceLinks="sourcelinks",
inputTrajectories="trajectories",
inputTrackParameters="fittedTrackParameters",
inputTrackParametersTips="fittedTrackParametersTips",
inputTrackParameters="trackParameters",
inputTrackParametersTips="trackParametersTips",
outputTrackParameters="filteredTrackParameters",
outputTrackParametersTips="filteredTrackParametersTips",
**acts.examples.defaultKWArgs(
Expand All @@ -985,6 +994,9 @@ def addAmbiguityResolution(
)
s.addAlgorithm(alg)

s.addWhiteboardAlias("trackParameters", alg.config.outputTrackParameters)
s.addWhiteboardAlias("trackParametersTips", alg.config.outputTrackParametersTips)

if outputDirRoot is not None:
outputDirRoot = Path(outputDirRoot)
if not outputDirRoot.exists():
Expand Down Expand Up @@ -1021,14 +1033,15 @@ def addVertexFitting(
s,
field,
outputDirRoot: Optional[Union[Path, str]] = None,
associatedParticles: str = "particles_input",
associatedParticles: Optional[str] = None,
trajectories: Optional[str] = "trajectories",
trackParameters: str = "filteredTrackParameters",
trackParametersTips: Optional[str] = "filteredTrackParametersTips",
trackParameters: str = "trackParameters",
trackParametersTips: Optional[str] = "trackParametersTips",
vertexFinder: VertexFinder = VertexFinder.Truth,
trackSelectorRanges: Optional[TrackSelectorRanges] = None,
logLevel: Optional[acts.logging.Level] = None,
) -> None:

"""This function steers the vertex fitting
Parameters
Expand Down Expand Up @@ -1056,22 +1069,26 @@ def addVertexFitting(
customLogLevel = acts.examples.defaultLogging(s, logLevel)

if trackSelectorRanges is not None:
addTrackSelection(
trackSelector = addTrackSelection(
s,
trackSelectorRanges,
inputTrackParameters=trackParameters,
inputTrackParametersTips=trackParametersTips,
outputTrackParameters=trackParameters + "Tmp",
outputTrackParametersTips=trackParametersTips + "Tmp",
outputTrackParameters="selectedTrackParametersVertexing",
outputTrackParametersTips="selectedTrackParametersTipsVertexing",
logLevel=customLogLevel(),
)

trackParameters = trackParameters + "Tmp"
trackParametersTips = trackParametersTips + "Tmp"
trackParameters = trackSelector.config.outputTrackParameters
trackParametersTips = (
trackSelector.config.outputTrackParametersTips
if trackParametersTips is not None
else None
)

inputParticles = "particles_input"
outputVertices = "fittedVertices"
selectedParticles = "particles_selected"
outputVertices = "fittedVertices"

outputTime = ""
if vertexFinder == VertexFinder.Truth:
Expand Down Expand Up @@ -1127,15 +1144,17 @@ def addVertexFitting(
level=customLogLevel(),
inputAllTruthParticles=inputParticles,
inputSelectedTruthParticles=selectedParticles,
inputTrackParameters=trackParameters,
inputTrackParametersTips=trackParametersTips,
inputAssociatedTruthParticles=associatedParticles
if associatedParticles is not None
else "",
inputMeasurementParticlesMap="measurement_particles_map",
inputTrajectories=trajectories if trajectories is not None else "",
inputAssociatedTruthParticles=""
if trajectories is not None
else associatedParticles,
inputTrackParameters=trackParameters,
inputTrackParametersTips=trackParametersTips
if trackParametersTips is not None
else "",
inputVertices=outputVertices,
minTrackVtxMatchFraction=0.0 if trajectories is not None else 0.5,
minTrackVtxMatchFraction=0.0 if associatedParticles is None else 0.5,
inputTime=outputTime,
treeName="vertexing",
filePath=str(outputDirRoot / "performance_vertexing.root"),
Expand Down
Loading

0 comments on commit 5addf02

Please sign in to comment.