21#include <unordered_map>
58 LOG(info) <<
"initializing track MC label finder";
60 throw invalid_argument(
"initialization of MCKinematicsReader failed");
62 double sigmaCut = ic.
options().
get<
double>(
"sigma-cut");
63 mMaxMatchingChi2 = 2. * sigmaCut * sigmaCut;
71 auto digitROFs = pc.
inputs().
get<gsl::span<ROFRecord>>(
"digitrofs");
73 auto trackROFs = pc.
inputs().
get<gsl::span<ROFRecord>>(
"trackrofs");
74 auto tracks = pc.
inputs().
get<gsl::span<TrackMCH>>(
"tracks");
78 int nROFs = digitROFs.size();
79 if (trackROFs.size() != nROFs) {
80 throw length_error(fmt::format(
"inconsistent ROFs: {} tracksROFs vs {} digitROFs", trackROFs.size(), nROFs));
83 std::vector<o2::MCCompLabel> tracklabels;
85 for (
int iROF = 0; iROF < nROFs; ++iROF) {
88 auto trackROF = trackROFs[iROF];
89 if (trackROF.getNEntries() == 0) {
94 auto digitROF = digitROFs[iROF];
95 if (digitROF.getBCData() != trackROF.getBCData()) {
96 throw logic_error(
"inconsistent ROF");
100 std::unordered_map<MCCompLabel, std::vector<Cluster>> mcClusterMap{};
101 for (
int iDigit = digitROF.getFirstIdx(); iDigit <= digitROF.getLastIdx(); ++iDigit) {
102 for (
const auto&
label : digitlabels->getLabels(iDigit)) {
103 if (
label.isCorrect() && mcClusterMap.count(
label) == 0) {
105 mcClusterMap[
label]);
111 for (
int iTrack = trackROF.getFirstIdx(); iTrack <= trackROF.getLastIdx(); ++iTrack) {
112 for (
const auto& [
label, mcClusters] : mcClusterMap) {
113 if (match(
clusters.subspan(tracks[iTrack].getFirstClusterIdx(), tracks[iTrack].getNClusters()), mcClusters)) {
114 tracklabels.push_back(
label);
118 if (tracklabels.size() != iTrack + 1) {
131 void makeMCClusters(gsl::span<const TrackReference> mcTrackRefs, std::vector<Cluster>& mcClusters)
const
135 for (
const auto& trackRef : mcTrackRefs) {
140 if (trackRef.getUserId() == deId) {
141 auto& cluster = mcClusters.back();
142 cluster.x = (cluster.x + trackRef.X()) / 2.;
143 cluster.y = (cluster.y + trackRef.Y()) / 2.;
144 cluster.z = (cluster.z + trackRef.Z()) / 2.;
147 deId = trackRef.getUserId();
148 mcClusters.push_back({trackRef.X(), trackRef.Y(), trackRef.Z(), 0.f, 0.f,
149 Cluster::buildUniqueId(deId / 100 - 1, deId, clusterIdx++), 0u, 0u});
158 bool match(gsl::span<const Cluster>
clusters,
const std::vector<Cluster>& mcClusters)
const
161 bool hasMatched[5] = {
false,
false,
false,
false,
false};
162 for (
const auto& cluster :
clusters) {
163 for (
const auto& mcCluster : mcClusters) {
164 if (cluster.getDEId() == mcCluster.getDEId()) {
165 double dx = cluster.x - mcCluster.x;
166 double dy = cluster.y - mcCluster.y;
167 double chi2 = dx * dx / (cluster.ex * cluster.ex) + dy * dy / (cluster.ey * cluster.ey);
168 if (chi2 <= mMaxMatchingChi2) {
169 hasMatched[cluster.getChamberId() / 2] =
true;
176 return ((hasMatched[0] || hasMatched[1]) && (hasMatched[3] || hasMatched[4]) && 2 * nMatched >
clusters.size());
180 double mMaxMatchingChi2 = 32.;
185 const char* digitRofDataDescription,
186 const char* digitLabelDataDescription)
189 fmt::format(
"digitrofs:MCH/{}/0;digitlabels:MCH/{}/0", digitRofDataDescription,
190 digitLabelDataDescription);
192 ";trackrofs:MCH/TRACKROFS/0;"
193 "tracks:MCH/TRACKS/0;"
194 "clusters:MCH/TRACKCLUSTERS/0";
198 Outputs{
OutputSpec{{
"tracklabels"},
"MCH",
"TRACKLABELS", 0, Lifetime::Timeframe}},
200 Options{{
"incontext", VariantType::String,
"collisioncontext.root", {
"Take collision context from this file"}},
201 {
"sigma-cut", VariantType::Double, 4., {
"Sigma cut to match simulated and reconstructed clusters"}}}};
Definition of the MCH track.
Definition of a data processor to match the reconstructed tracks with the simulated ones.
T get(const char *key) const
void snapshot(const Output &spec, T const &object)
ConfigParamRegistry const & options()
DataAllocator & outputs()
The data allocator is used to allocate memory for the output data.
InputRecord & inputs()
The inputs associated with this processing context.
void init(framework::InitContext &ic)
prepare the task from the context
void run(framework::ProcessingContext &pc)
assign every reconstructed track a MC label, pointing to the corresponding particle or fake
bool initFromDigitContext(std::string_view filename)
gsl::span< o2::TrackReference > getTrackRefs(int source, int event, int track) const
get all primaries for a certain event
GLuint GLsizei const GLchar * label
Defining PrimaryVertex explicitly as messageable.
std::vector< ConfigParamSpec > Options
std::vector< InputSpec > select(char const *matcher="")
std::vector< OutputSpec > Outputs
o2::framework::DataProcessorSpec getTrackMCLabelFinderSpec(const char *specName, const char *digitRofDataDescription, const char *digitLabelDataDescription)
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
Defining DataPointCompositeObject explicitly as copiable.
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
std::vector< Cluster > clusters