Skip to content

Commit 91453af

Browse files
matthias-kleinerclaude
authored andcommitted
Cosmics cluster collector: store TPC occupancy per cosmic and per TF (#15987)
For each cosmic, tpcOccBef and tpcOccAft count the TPC clusters in the orbit before and after the cosmic's time (TOF time if available, otherwise the matcher's time), taken from the TPC occupancy map. They are -1 if no map is available or if the window extends beyond the TF. CosmicsTFInfo::tpcOcc stores the TF average of TPC clusters per orbit. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 9b465b8 commit 91453af

2 files changed

Lines changed: 53 additions & 5 deletions

File tree

‎DataFormats/Detectors/GlobalTracking/include/DataFormatsGlobalTracking/TrackCosmicsExtended.h‎

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -110,16 +110,20 @@ struct TrackCosmicsExtended {
110110
///< approach to the beam line; valid if chi2MatchPolished >= 0
111111
float chi2MatchPolished = -1.f; ///< chi2 of the polished bottom and top halves at the closest approach (< 0: not polished)
112112
o2::MCCompLabel label{}; ///< MC label of the cosmic (MC only)
113+
float tpcOccBef = -1.f; ///< TPC clusters in the orbit before the time of the cosmic (TOF time if hasTOFTime(), else the matcher's),
114+
///< from the TPC occupancy map (-1: no map, or the orbit is not fully inside the TF)
115+
float tpcOccAft = -1.f; ///< same for the orbit after the time of the cosmic, i.e. while its clusters drift
113116

114117
bool hasTOFTime() const { return scoreTOFPair >= 0.f; } ///< a HitTOFFlight pair gave the cosmic its time timeTOFMUS
115-
ClassDefNV(TrackCosmicsExtended, 1);
118+
ClassDefNV(TrackCosmicsExtended, 2);
116119
};
117120

118-
/// per-TF quantities of the TPC transformation used in the reconstruction
121+
/// per-TF quantities: the TPC transformation used in the reconstruction and the TPC occupancy
119122
struct CosmicsTFInfo {
120-
float vDrift = 0.f; ///< drift velocity of the transformation [cm/time bin]
121-
float t0 = 0.f; ///< time offset of the transformation [time bins]
122-
ClassDefNV(CosmicsTFInfo, 1);
123+
float vDrift = 0.f; ///< drift velocity of the transformation [cm/time bin]
124+
float t0 = 0.f; ///< time offset of the transformation [time bins]
125+
float tpcOcc = -1.f; ///< TPC clusters per orbit, average of the TF (TPC occupancy map) (< 0: no map)
126+
ClassDefNV(CosmicsTFInfo, 2);
123127
};
124128

125129
} // namespace o2::dataformats

‎Detectors/GlobalTrackingWorkflow/src/CosmicsClusterCollectorSpec.cxx‎

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,8 @@ class CosmicsClusterCollectorSpec : public Task
166166
};
167167

168168
void updateTimeDependentParams(ProcessingContext& pc);
169+
void fillTPCOccupancy(gsl::span<const unsigned int> occupancyMap);
170+
float tpcOccupancy(float timeTB, bool after) const;
169171
void buildUsedMap(const RecoContainer& data, std::vector<std::pair<float, float>>& time0Windows);
170172
void addTPCAttached(const RecoContainer& data, const o2::tpc::TrackTPC& trk, std::vector<o2::dataformats::CosmicTPCCluster>& out, std::unordered_set<uint32_t>& taken) const;
171173
/// time frame of a TPC road: the leg's z is shifted by dz and its clusters are transformed with vertexTime
@@ -221,6 +223,10 @@ class CosmicsClusterCollectorSpec : public Task
221223
float mRoadITS = 1.5f; ///< road half-width in the ITS [cm]
222224
std::vector<o2::math_utils::Point3D<float>> mITSChipCentres; ///< global positions of the ITS chip centres (aligned geometry)
223225
float mTPCTBinMUS = 0.2f; ///< TPC time bin [mus]
226+
std::vector<uint64_t> mTPCOccCumul; ///< TPC occupancy map of the TF summed up: [i] = clusters in the bins before bin i
227+
float mTPCOccBinTB = 16.f; ///< time bins per bin of the TPC occupancy map
228+
int mTPCOccBinsPerOrbit = 1; ///< bins of the TPC occupancy map per orbit
229+
float mTPCOccTF = -1.f; ///< TPC clusters per orbit, average of the TF (< 0: no occupancy map)
224230
float mBz = 0.f;
225231
bool mUseMC = false;
226232
mutable bool mNoDictWarned = false;
@@ -304,6 +310,8 @@ void CosmicsClusterCollectorSpec::run(ProcessingContext& pc)
304310
o2::dataformats::CosmicsTFInfo tfInfo;
305311
tfInfo.vDrift = mCorrMap->getVDrift();
306312
tfInfo.t0 = mCorrMap->getT0();
313+
fillTPCOccupancy(recoData.occupancyMapTPC);
314+
tfInfo.tpcOcc = mTPCOccTF;
307315

308316
std::vector<o2::dataformats::TrackCosmicsExtended> cosmicsOut;
309317
const auto cosmics = recoData.getCosmicTracks();
@@ -390,6 +398,8 @@ void CosmicsClusterCollectorSpec::run(ProcessingContext& pc)
390398
roadTime.known = true;
391399
}
392400
mDbgTauC = roadTime.tb;
401+
out.tpcOccBef = tpcOccupancy(roadTime.tb, false);
402+
out.tpcOccAft = tpcOccupancy(roadTime.tb, true);
393403
std::unordered_set<uint32_t> taken;
394404
for (int leg = 0; leg < 2; leg++) { // attached clusters of both legs first, so that a road never takes the other leg's clusters
395405
if (tpcLegs[leg]) {
@@ -487,6 +497,40 @@ void CosmicsClusterCollectorSpec::buildUsedMap(const RecoContainer& data, std::v
487497
}
488498
}
489499

500+
void CosmicsClusterCollectorSpec::fillTPCOccupancy(gsl::span<const unsigned int> occupancyMap)
501+
{
502+
// TPC occupancy map (GPUChainTrackingSectorTracker): [0] clusters per orbit (average of the TF), [1] time bins per bin << 16 | averaging,
503+
// [2...] clusters per bin (all clusters, by their time)
504+
mTPCOccCumul.clear();
505+
mTPCOccTF = occupancyMap.empty() ? -1.f : occupancyMap[0];
506+
if (occupancyMap.size() < 3 || (occupancyMap[1] >> 16) == 0) { // no time bins in the map
507+
return;
508+
}
509+
mTPCOccBinTB = occupancyMap[1] >> 16;
510+
mTPCOccBinsPerOrbit = std::max(1, static_cast<int>(o2::constants::lhc::LHCMaxBunches / 8 / mTPCOccBinTB));
511+
mTPCOccCumul.resize(occupancyMap.size() - 1, 0);
512+
for (size_t bin = 2; bin < occupancyMap.size(); bin++) {
513+
mTPCOccCumul[bin - 1] = mTPCOccCumul[bin - 2] + occupancyMap[bin];
514+
}
515+
}
516+
517+
float CosmicsClusterCollectorSpec::tpcOccupancy(float timeTB, bool after) const
518+
{
519+
// TPC clusters in the map bins of one orbit before the bin of timeTB (after: from the bin of timeTB on); -1 if the window is not
520+
// fully inside the TF, where the map would understate the occupancy
521+
if (mTPCOccCumul.empty()) {
522+
return -1.f;
523+
}
524+
const int nBins = static_cast<int>(mTPCOccCumul.size()) - 1;
525+
const int bin = static_cast<int>(std::floor(timeTB / mTPCOccBinTB));
526+
const int first = after ? bin : bin - mTPCOccBinsPerOrbit;
527+
const int last = after ? bin + mTPCOccBinsPerOrbit : bin;
528+
if (first < 0 || last > nBins) {
529+
return -1.f;
530+
}
531+
return static_cast<float>(mTPCOccCumul[last] - mTPCOccCumul[first]);
532+
}
533+
490534
void CosmicsClusterCollectorSpec::addTPCAttached(const RecoContainer& data, const o2::tpc::TrackTPC& trk, std::vector<o2::dataformats::CosmicTPCCluster>& out, std::unordered_set<uint32_t>& taken) const
491535
{
492536
const auto& clusters = data.getTPCClusters();

0 commit comments

Comments
 (0)