Skip to content

Commit ff9d75e

Browse files
MatchCosmics: reject legs that are part of primary-vertex contributors
Review suggestion: a TPC track that is part of a global track contributing to a primary vertex comes from a collision, not from a cosmic. The existing veto (--use-pv-info with cosmicsMatch.discardPVContributors, default on) compared the contributor's own track ID with the seeds, so it never fired for TPC-only legs: the contributors are ITS-TPC and higher. New workflow option --pv-contributor-sources (implies --use-pv-info, ignored with a warning if discardPVContributors is off): the contributors of these global track sources reject every leg they contain (RecoContainer::getSingleDetectorRefs), e.g. their TPC track. The sources and the parent matches needed to resolve them are loaded only for this; the legs still come from --track-sources only. Log line: seeds rejected per TF (also those that are themselves contributors). PbPb 567939, 2 TFs with vertices (94 each), sources ITS-TPC,ITS-TPC-TRD, ITS-TPC-TOF,ITS-TPC-TRD-TOF: 54 % of the TPC seeds rejected; without seed DCA cuts the collision-track pairs drop from 183 / 285 to 58 / 88 per TF, with the near-beam option the near-beam seeds by 57 %; matcher CPU for the 4 TFs (2 of them without vertices) 3.1 -> 2.3 s; the physics-v1 cosmic is kept. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 3f1d9f8 commit ff9d75e

5 files changed

Lines changed: 68 additions & 8 deletions

File tree

‎Detectors/GlobalTracking/include/GlobalTracking/MatchCosmics.h‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ class MatchCosmics
118118
void process(const o2::globaltracking::RecoContainer& data);
119119
void setUseMC(bool mc) { mUseMC = mc; }
120120
void setUsePVInfo(bool v) { mUsePVInfo = v; }
121+
void setSeedSources(GTrackID::mask_t src) { mSeedSources = src; } ///< track sources used as legs (other loaded ones resolve PV contributors)
122+
void setPVVetoSources(GTrackID::mask_t src) { mPVVetoSources = src; } ///< sources whose PV contributors veto the legs they contain
121123
void init();
122124
void end();
123125

@@ -180,6 +182,8 @@ class MatchCosmics
180182
bool mFieldON = true;
181183
bool mUsePVInfo = false;
182184
bool mUseMC = true;
185+
GTrackID::mask_t mSeedSources{GTrackID::MASK_ALL}; ///< track sources used as legs
186+
GTrackID::mask_t mPVVetoSources{GTrackID::MASK_NONE}; ///< sources whose PV contributors veto the legs they contain
183187
float mITSROFrameLengthMUS = 0.;
184188
float mQ2PtCutoff = 1e9;
185189
float mQ2PtCutoffOppositeSides = 1e9;
@@ -195,6 +199,7 @@ class MatchCosmics
195199
size_t mNTOFFallbacks = 0; ///< TOF-confirmed winners refitted at their time without TOF in this TF
196200
size_t mNSeedsNearBeam = 0; ///< TPC-only seeds kept for TOF-confirmed pairs only (minSeedDCAxyTOF) in this TF
197201
size_t mNNearBeamConfirmed = 0; ///< accepted pairs with such a seed, confirmed by a TOF flight pair, in this TF
202+
size_t mNSeedsPVContributors = 0; ///< seeds rejected as part of a primary-vertex contributor in this TF
198203

199204
std::vector<o2d::TrackCosmics> mCosmicTracks;
200205
std::vector<o2::MCCompLabel> mCosmicTracksLbl;

‎Detectors/GlobalTracking/src/MatchCosmics.cxx‎

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,9 @@ void MatchCosmics::process(const o2::globaltracking::RecoContainer& data)
161161
if (mMatchParams->tofFlightSelection) {
162162
LOGP(info, "{} accepted pairs confirmed by a TOF flight pair", mNTOFConfirmed);
163163
}
164+
if (mNSeedsPVContributors) {
165+
LOGP(info, "{} seeds rejected as (part of) a primary-vertex contributor", mNSeedsPVContributors);
166+
}
164167
if (mNSeedsNearBeam) {
165168
LOGP(info, "{} seeds near the beam line used in TOF-confirmed pairs only, {} such pairs confirmed", mNSeedsNearBeam, mNNearBeamConfirmed);
166169
}
@@ -940,8 +943,9 @@ void MatchCosmics::createSeeds(const o2::globaltracking::RecoContainer& data)
940943
}
941944
};
942945

943-
data.createTracksVariadic(creator);
946+
data.createTracksVariadic(creator, mSeedSources); // other loaded sources only resolve the primary-vertex contributors below
944947

948+
mNSeedsPVContributors = 0;
945949
if (mUsePVInfo) { // if needed, veto with the primary vertex info
946950
auto trackIndex = data.getPrimaryVertexMatchedTracks(); // Global ID's for associated tracks
947951
auto vtxRefs = data.getPrimaryVertexMatchedTrackRefs(); // references from vertex to these track IDs
@@ -954,11 +958,28 @@ void MatchCosmics::createSeeds(const o2::globaltracking::RecoContainer& data)
954958
auto tvid = trackIndex[it];
955959
auto entry = trackEntry.find(tvid);
956960
if (entry == trackEntry.end()) {
961+
// a contributor of a veto source (not itself a leg): the legs it contains (e.g. its TPC track) come from a collision
962+
if (mMatchParams->discardPVContributors && tvid.isPVContributor() && mPVVetoSources[tvid.getSource()] && data.isTrackSourceLoaded(tvid.getSource())) {
963+
const auto refs = data.getSingleDetectorRefs(tvid);
964+
for (int src = 0; src < GTrackID::NSources; src++) {
965+
if (!mSeedSources[src] || !refs[src].isIndexSet()) {
966+
continue;
967+
}
968+
auto partEntry = trackEntry.find(refs[src]);
969+
if (partEntry != trackEntry.end() && mSeeds[partEntry->second].matchID != Reject) {
970+
mSeeds[partEntry->second].matchID = Reject;
971+
mNSeedsPVContributors++;
972+
}
973+
}
974+
}
957975
continue;
958976
}
959977
auto& seed = mSeeds[entry->second];
960-
if (seed.matchID == Reject || (mMatchParams->discardPVContributors && tvid.isPVContributor())) {
978+
if (seed.matchID != Reject && mMatchParams->discardPVContributors && tvid.isPVContributor()) { // the leg itself is a contributor
961979
seed.matchID = Reject;
980+
mNSeedsPVContributors++;
981+
}
982+
if (seed.matchID == Reject) {
962983
continue;
963984
}
964985
if (seed.vtIDMin < 0) {

‎Detectors/GlobalTrackingWorkflow/include/GlobalTrackingWorkflow/CosmicsMatchingSpec.h‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,11 @@ namespace globaltracking
2424
{
2525

2626
/// create a processor spec
27-
framework::DataProcessorSpec getCosmicsMatchingSpec(o2::dataformats::GlobalTrackID::mask_t src, bool usePV, bool useMC, bool itsStag, bool useTOFClusters = false);
27+
/// srcPVContributors plus the parent matches needed to resolve their single-detector parts (RecoContainer::getSingleDetectorRefs)
28+
o2::dataformats::GlobalTrackID::mask_t addPVContributorParents(o2::dataformats::GlobalTrackID::mask_t srcPVContributors);
29+
30+
framework::DataProcessorSpec getCosmicsMatchingSpec(o2::dataformats::GlobalTrackID::mask_t src, bool usePV, bool useMC, bool itsStag, bool useTOFClusters = false,
31+
o2::dataformats::GlobalTrackID::mask_t srcPVContributors = {});
2832

2933
} // namespace globaltracking
3034
} // namespace o2

‎Detectors/GlobalTrackingWorkflow/src/CosmicsMatchingSpec.cxx‎

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ namespace globaltracking
6666
class CosmicsMatchingSpec : public Task
6767
{
6868
public:
69-
CosmicsMatchingSpec(std::shared_ptr<DataRequest> dr, std::shared_ptr<o2::base::GRPGeomRequest> gr, bool usePV, bool useMC) : mDataRequest(dr), mGGCCDBRequest(gr), mUsePVInfo(usePV), mUseMC(useMC) {}
69+
CosmicsMatchingSpec(std::shared_ptr<DataRequest> dr, std::shared_ptr<o2::base::GRPGeomRequest> gr, GTrackID::mask_t src, GTrackID::mask_t srcPVVeto, bool usePV, bool useMC) : mDataRequest(dr), mGGCCDBRequest(gr), mSeedSources(src), mPVVetoSources(srcPVVeto), mUsePVInfo(usePV), mUseMC(useMC) {}
7070
~CosmicsMatchingSpec() override = default;
7171
void init(InitContext& ic) final;
7272
void run(ProcessingContext& pc) final;
@@ -81,6 +81,8 @@ class CosmicsMatchingSpec : public Task
8181
o2::tpc::VDriftHelper mTPCVDriftHelper{};
8282
const o2::gpu::TPCFastTransformPOD* mCorrMap{nullptr};
8383
o2::globaltracking::MatchCosmics mMatching; // matching engine
84+
GTrackID::mask_t mSeedSources; // track sources used as legs
85+
GTrackID::mask_t mPVVetoSources; // sources whose PV contributors veto the legs they contain
8486
bool mUseMC = true;
8587
bool mUsePVInfo = false;
8688
TStopwatch mTimer;
@@ -94,6 +96,8 @@ void CosmicsMatchingSpec::init(InitContext& ic)
9496
mMatching.setDebugFlag(ic.options().get<int>("debug-tree-flags"));
9597
mMatching.setUseMC(mUseMC);
9698
mMatching.setUsePVInfo(mUsePVInfo);
99+
mMatching.setSeedSources(mSeedSources);
100+
mMatching.setPVVetoSources(mPVVetoSources);
97101
//
98102
}
99103

@@ -183,7 +187,22 @@ void CosmicsMatchingSpec::endOfStream(EndOfStreamContext& ec)
183187
mTimer.CpuTime(), mTimer.RealTime(), mTimer.Counter() - 1);
184188
}
185189

186-
DataProcessorSpec getCosmicsMatchingSpec(GTrackID::mask_t src, bool usePV, bool useMC, bool itsStag, bool useTOFClusters)
190+
GTrackID::mask_t addPVContributorParents(GTrackID::mask_t srcPVContributors)
191+
{
192+
auto src = srcPVContributors;
193+
if (src[GTrackID::ITSTPCTRDTOF]) {
194+
src |= GTrackID::getSourceMask(GTrackID::ITSTPCTRD);
195+
}
196+
if (src[GTrackID::TPCTRDTOF]) {
197+
src |= GTrackID::getSourceMask(GTrackID::TPCTRD);
198+
}
199+
if (src[GTrackID::ITSTPCTRD] || src[GTrackID::ITSTPCTOF]) {
200+
src |= GTrackID::getSourceMask(GTrackID::ITSTPC);
201+
}
202+
return src;
203+
}
204+
205+
DataProcessorSpec getCosmicsMatchingSpec(GTrackID::mask_t src, bool usePV, bool useMC, bool itsStag, bool useTOFClusters, GTrackID::mask_t srcPVContributors)
187206
{
188207
std::vector<OutputSpec> outputs;
189208
Options opts{
@@ -200,6 +219,8 @@ DataProcessorSpec getCosmicsMatchingSpec(GTrackID::mask_t src, bool usePV, bool
200219
}
201220
if (usePV) {
202221
dataRequest->requestPrimaryVertices(useMC);
222+
// global tracks whose primary-vertex contributors veto their TPC track as a leg (MatchCosmicsParams::discardPVContributors), not legs
223+
dataRequest->requestTracks(addPVContributorParents(srcPVContributors) & ~src, useMC); // same MC flag: some requests are shared with the legs
203224
}
204225

205226
outputs.emplace_back("GLO", "COSMICTRC", 0, Lifetime::Timeframe);
@@ -224,7 +245,7 @@ DataProcessorSpec getCosmicsMatchingSpec(GTrackID::mask_t src, bool usePV, bool
224245
"cosmics-matcher",
225246
dataRequest->inputs,
226247
outputs,
227-
AlgorithmSpec{adaptFromTask<CosmicsMatchingSpec>(dataRequest, ggRequest, usePV, useMC)},
248+
AlgorithmSpec{adaptFromTask<CosmicsMatchingSpec>(dataRequest, ggRequest, src, usePV ? srcPVContributors : GTrackID::mask_t{}, usePV, useMC)},
228249
opts};
229250
}
230251

‎Detectors/GlobalTrackingWorkflow/src/cosmics-match-workflow.cxx‎

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ void customize(std::vector<o2::framework::ConfigParamSpec>& workflowOptions)
5454
{"disable-root-input", o2::framework::VariantType::Bool, false, {"disable root-files input reader"}},
5555
{"disable-root-output", o2::framework::VariantType::Bool, false, {"disable root-files output writer"}},
5656
{"use-pv-info", o2::framework::VariantType::Bool, false, {"request primary vertex for relevant cuts in the collision/cosmics interleaved data"}},
57+
{"pv-contributor-sources", VariantType::String, "", {"global track sources (with TPC) loaded only to reject the TPC track of a primary-vertex contributor as a leg (cosmicsMatch.discardPVContributors, implies --use-pv-info), e.g. ITS-TPC,ITS-TPC-TRD,ITS-TPC-TOF,ITS-TPC-TRD-TOF"}},
5758
{"enable-cluster-output", o2::framework::VariantType::Bool, false, {"collect the raw clusters of the cosmics (legs + road around them) and write them with the cosmics"}},
5859
{"road-detectors", VariantType::String, "ITS,TOF,TRD", {"with --enable-cluster-output: detectors whose hits along the cosmic are collected besides the TPC road"}},
5960
{"cosmics-preset", VariantType::String, "", {"named set of cosmicsMatch settings applied before --configKeyValues (which can override single keys): physics-v1 = cosmics in collision data"}},
@@ -127,7 +128,15 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext)
127128
specs.emplace_back(o2::tpc::getTPCScalerSpec(sclOpt));
128129
}
129130
bool usePV = configcontext.options().get<bool>("use-pv-info");
130-
specs.emplace_back(o2::globaltracking::getCosmicsMatchingSpec(src, usePV, useMC, doStag, useTOFClusters));
131+
GID::mask_t srcPV = GID::getSourcesMask("ITS-TPC,TPC-TRD,TPC-TOF,ITS-TPC-TRD,TPC-TRD-TOF,ITS-TPC-TOF,ITS-TPC-TRD-TOF") &
132+
GID::getSourcesMask(configcontext.options().get<std::string>("pv-contributor-sources"));
133+
if (srcPV.any() && !o2::globaltracking::MatchCosmicsParams::Instance().discardPVContributors) {
134+
LOG(warning) << "--pv-contributor-sources ignored: cosmicsMatch.discardPVContributors is off";
135+
srcPV.reset();
136+
}
137+
usePV |= srcPV.any();
138+
specs.emplace_back(o2::globaltracking::getCosmicsMatchingSpec(src, usePV, useMC, doStag, useTOFClusters, srcPV));
139+
const auto srcPVLoaded = o2::globaltracking::addPVContributorParents(srcPV); // with the parents needed to resolve the contributors
131140
bool clusterOutput = configcontext.options().get<bool>("enable-cluster-output");
132141
if (clusterOutput) {
133142
if (!src[GID::TPC]) {
@@ -142,7 +151,7 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext)
142151
specs.emplace_back(o2::globaltracking::getCosmicsClusterCollectorSpec(src, useMC, doStag, roadDets));
143152
}
144153

145-
o2::globaltracking::InputHelper::addInputSpecs(configcontext, specs, srcCl, src, src, useMC, dummy); // clusters MC is not needed
154+
o2::globaltracking::InputHelper::addInputSpecs(configcontext, specs, srcCl, src | srcPVLoaded, src | srcPVLoaded, useMC, dummy); // clusters MC is not needed
146155
if (usePV) {
147156
o2::globaltracking::InputHelper::addInputSpecsPVertex(configcontext, specs, useMC); // P-vertex is always needed
148157
}

0 commit comments

Comments
 (0)