diff --git a/Detectors/MUON/MCH/Base/include/MCHBase/Trackable.h b/Detectors/MUON/MCH/Base/include/MCHBase/Trackable.h index a862be411cb35..ef556d49a9201 100644 --- a/Detectors/MUON/MCH/Base/include/MCHBase/Trackable.h +++ b/Detectors/MUON/MCH/Base/include/MCHBase/Trackable.h @@ -38,11 +38,21 @@ bool isTrackable(std::array itemsPerChamber, /** Return the number of items per chamber. * * @tparam T the type of items : implementation exists so far - * only for mch::Digit (clusters and pre-clusters to come next) + * for deIds (int) and mch::Digit */ template std::array perChamber(gsl::span items); +/** Return the number of items per chamber. + * + * @tparam T1 the type of items : implementation exists so far + * for mch::PreCluster + * @tparam T2 the type of subitems pointed to by items, + * e.g. mch::Digit attached to mch::PreCluster + */ +template +std::array perChamber(gsl::span items, gsl::span subitems); + /** Return the number of items per station (1 station==2 chambers). */ template std::array perStation(gsl::span items) diff --git a/Detectors/MUON/MCH/Base/src/Trackable.cxx b/Detectors/MUON/MCH/Base/src/Trackable.cxx index c25b12945cb90..0545f7cb1eac5 100644 --- a/Detectors/MUON/MCH/Base/src/Trackable.cxx +++ b/Detectors/MUON/MCH/Base/src/Trackable.cxx @@ -10,7 +10,9 @@ // or submit itself to any jurisdiction. #include "MCHBase/Trackable.h" + #include "DataFormatsMCH/Digit.h" +#include "MCHBase/PreCluster.h" namespace o2::mch { @@ -59,7 +61,27 @@ std::array perChamber(gsl::span digits) for (const auto& digit : digits) { nofDigits[digit.getDetID() / 100 - 1]++; } + // do not count isolated digits (at least 2 are required for a cluster) + for (auto i = 0; i < 10; ++i) { + if (nofDigits[i] == 1) { + nofDigits[i] = 0; + } + } return nofDigits; } +/** Specialization of perChamber for PreClusters */ +template <> +std::array perChamber(gsl::span preclusters, gsl::span digits) +{ + std::array nofPreclusters{}; + for (const auto& precluster : preclusters) { + // only consider preclusters made of at least 2 digits + if (precluster.nDigits > 1) { + nofPreclusters[digits[precluster.firstDigit].getDetID() / 100 - 1]++; + } + } + return nofPreclusters; +} + } // namespace o2::mch diff --git a/Detectors/MUON/MCH/Clustering/include/MCHClustering/ClusterizerParam.h b/Detectors/MUON/MCH/Clustering/include/MCHClustering/ClusterizerParam.h index a24a8543af2cb..8f6f28a1f45d7 100644 --- a/Detectors/MUON/MCH/Clustering/include/MCHClustering/ClusterizerParam.h +++ b/Detectors/MUON/MCH/Clustering/include/MCHClustering/ClusterizerParam.h @@ -37,6 +37,8 @@ struct ClusterizerParam : public o2::conf::ConfigurableParamHelper ROFFilter createTrackableFilter(gsl::span items, @@ -46,6 +45,33 @@ ROFFilter }; } +/** Returns a ROFRecord filter that selects ROFs that are trackable. + * + * The returned filter is a function that takes a ROFRecord and returns + * a boolean. + * + * @param items : the items "pointed to" by the ROFRecords (preclusters, ...) + * @param subitems : the subitems "pointed to" by the items (digits, ...) + * + * @param requestStation : @ref isTrackable + * @param moreCandidates : @ref isTrackable + * + * @tparam T1 : the type of the items pointed to by the ROFRecords + * @tparam T2 : the type of the subitems pointed to by the items + */ +template +ROFFilter + createTrackableFilter(gsl::span items, + gsl::span subitems, + std::array requestStation = {true, true, true, true, true}, + bool moreCandidates = false) +{ + return [items, subitems, requestStation, moreCandidates](const ROFRecord& rof) { + std::array nofItemsPerChamber = perChamber(items.subspan(rof.getFirstIdx(), rof.getNEntries()), subitems); + return isTrackable(nofItemsPerChamber, requestStation, moreCandidates); + }; +} + } // namespace o2::mch #endif diff --git a/Detectors/MUON/MCH/Workflow/CMakeLists.txt b/Detectors/MUON/MCH/Workflow/CMakeLists.txt index e0fce7d103df7..f97c78526f21e 100644 --- a/Detectors/MUON/MCH/Workflow/CMakeLists.txt +++ b/Detectors/MUON/MCH/Workflow/CMakeLists.txt @@ -30,6 +30,7 @@ o2_add_library(MCHWorkflow O2::MCHPreClustering O2::MCHRawCommon O2::MCHRawDecoder + O2::MCHROFFiltering ROOT::TreePlayer ) diff --git a/Detectors/MUON/MCH/Workflow/src/ClusterFinderOriginalSpec.cxx b/Detectors/MUON/MCH/Workflow/src/ClusterFinderOriginalSpec.cxx index 8344d2837b814..e369e514b0f2e 100644 --- a/Detectors/MUON/MCH/Workflow/src/ClusterFinderOriginalSpec.cxx +++ b/Detectors/MUON/MCH/Workflow/src/ClusterFinderOriginalSpec.cxx @@ -35,13 +35,16 @@ #include "Framework/Logger.h" #include "CommonUtils/ConfigurableParam.h" -#include "DataFormatsMCH/ROFRecord.h" +#include "DataFormatsMCH/Cluster.h" #include "DataFormatsMCH/Digit.h" +#include "DataFormatsMCH/ROFRecord.h" #include "MCHBase/Error.h" #include "MCHBase/ErrorMap.h" #include "MCHBase/PreCluster.h" -#include "DataFormatsMCH/Cluster.h" +#include "MCHBase/TrackerParam.h" #include "MCHClustering/ClusterFinderOriginal.h" +#include "MCHClustering/ClusterizerParam.h" +#include "MCHROFFiltering/TrackableFilter.h" namespace o2 { @@ -94,11 +97,35 @@ class ClusterFinderOriginalTask auto& clusters = pc.outputs().make>(OutputRef{"clusters"}); auto& usedDigits = pc.outputs().make>(OutputRef{"clusterdigits"}); + // create the trackable ROF filtering if needed + ROFFilter trackable{}; + if (ClusterizerParam::Instance().onlyTrackable) { + const auto& trackerParam = TrackerParam::Instance(); + std::array requestStation{ + trackerParam.requestStation[0], + trackerParam.requestStation[1], + trackerParam.requestStation[2], + trackerParam.requestStation[3], + trackerParam.requestStation[4]}; + trackable = createTrackableFilter(preClusters, digits, requestStation, trackerParam.moreCandidates); + } + clusterROFs.reserve(preClusterROFs.size()); auto& errorMap = mClusterFinder.getErrorMap(); errorMap.clear(); + int nFilteredRofs = 0; + int nFilteredPreClusters = 0; for (const auto& preClusterROF : preClusterROFs) { + // filter out non-trackable ROFs if requested + if (ClusterizerParam::Instance().onlyTrackable && !trackable(preClusterROF)) { + // create an empty cluster ROF + clusterROFs.emplace_back(preClusterROF.getBCData(), clusters.size(), 0, preClusterROF.getBCWidth()); + continue; + } + ++nFilteredRofs; + nFilteredPreClusters += preClusterROF.getNEntries(); + // prepare to clusterize the current ROF auto clusterOffset = clusters.size(); mClusterFinder.reset(); @@ -137,8 +164,8 @@ class ClusterFinderOriginalTask }); mErrorMap.add(errorMap); - LOGP(info, "Found {:4d} clusters from {:4d} preclusters in {:2d} ROFs", - clusters.size(), preClusters.size(), preClusterROFs.size()); + LOGP(info, "Found {:4d} clusters from {:4d} preclusters (out of {:4d}) in {:2d} filtered ROFs (out of {:2d})", + clusters.size(), nFilteredPreClusters, preClusters.size(), nFilteredRofs, preClusterROFs.size()); } private: