Skip to content

Commit bdfef1f

Browse files
authored
[PWGDQ] Add optional barrel association time margin cut to data and M… (#18052)
1 parent a83063c commit bdfef1f

4 files changed

Lines changed: 152 additions & 0 deletions

File tree

‎PWGDQ/Core/VarManager.cxx‎

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
#include <cmath>
4242
#include <cstddef>
4343
#include <cstdint>
44+
#include <cstdlib>
4445
#include <map>
4546
#include <numeric>
4647
#include <tuple>
@@ -1041,6 +1042,12 @@ void VarManager::SetDefaultVarNames()
10411042
fgVariableUnits[kTrackTimeRes] = "ns";
10421043
fgVariableNames[kTrackTimeResRelative] = "Relative resolution of the track time";
10431044
fgVariableUnits[kTrackTimeResRelative] = "";
1045+
fgVariableNames[kTrackAssocDeltaTime] = "Track-collision association #Deltat";
1046+
fgVariableUnits[kTrackAssocDeltaTime] = "ns";
1047+
fgVariableNames[kTrackAssocTimeThreshold] = "Track-collision association time threshold";
1048+
fgVariableUnits[kTrackAssocTimeThreshold] = "ns";
1049+
fgVariableNames[kTrackAssocDeltaTimeNorm] = "|#Deltat| / threshold";
1050+
fgVariableUnits[kTrackAssocDeltaTimeNorm] = "";
10441051
fgVariableNames[kDetectorMap] = "DetectorMap";
10451052
fgVariableUnits[kDetectorMap] = "";
10461053
fgVariableNames[kHasITS] = "HasITS";
@@ -2369,6 +2376,9 @@ void VarManager::SetDefaultVarNames()
23692376
fgVarNamesMap["kTrackTime"] = kTrackTime;
23702377
fgVarNamesMap["kTrackTimeRes"] = kTrackTimeRes;
23712378
fgVarNamesMap["kTrackTimeResRelative"] = kTrackTimeResRelative;
2379+
fgVarNamesMap["kTrackAssocDeltaTime"] = kTrackAssocDeltaTime;
2380+
fgVarNamesMap["kTrackAssocTimeThreshold"] = kTrackAssocTimeThreshold;
2381+
fgVarNamesMap["kTrackAssocDeltaTimeNorm"] = kTrackAssocDeltaTimeNorm;
23722382
fgVarNamesMap["kDetectorMap"] = kDetectorMap;
23732383
fgVarNamesMap["kHasITS"] = kHasITS;
23742384
fgVarNamesMap["kHasTRD"] = kHasTRD;
@@ -2918,3 +2928,64 @@ void VarManager::SetDefaultVarNames()
29182928
fgVarNamesMap["kInnerTOFnSigmaHe3"] = kInnerTOFnSigmaHe3;
29192929
fgVarNamesMap["kInnerTOFnSigmaAl"] = kInnerTOFnSigmaAl;
29202930
}
2931+
2932+
//__________________________________________________________________
2933+
bool VarManager::computeBarrelAssocTimeCompat(float trackTime, float trackTimeRes, bool timeResIsRange, bool isPVContributor,
2934+
int64_t origBC, float origCollTime, int origNumContrib,
2935+
int64_t collBC, float collTime, float collTimeRes,
2936+
float nSigma, float timeMargin, int bcWindowForOneSigma,
2937+
int usePVAssociation, int maxPvContribLowMult, float* values)
2938+
{
2939+
//
2940+
// Mirrors the time-based association of Common/Core/CollisionAssociation.h::runAssocWithTime for central barrel tracks.
2941+
// Every arithmetic step is kept identical to the associator (including the double->int64 truncations),
2942+
// so that re-applying it on skimmed associations with a smaller timeMargin reproduces a skim produced directly with that margin.
2943+
// Only tracks assigned to a collision in the AO2D are handled (this is always the case for tracks written by the DQ table makers).
2944+
//
2945+
if (!values) {
2946+
values = fgValues;
2947+
}
2948+
values[kTrackAssocDeltaTime] = -9999.f;
2949+
values[kTrackAssocTimeThreshold] = 0.f;
2950+
values[kTrackAssocDeltaTimeNorm] = 9999.f;
2951+
2952+
constexpr double BunchSpacingNS = o2::constants::lhc::LHCBunchSpacingNS;
2953+
2954+
// (1) BC pre-window (CollisionAssociation.h: trackBCCache, bcOffsetMax, bcOffsetWindow)
2955+
// NOTE: the associator uses the raw trackTime here also for PV contributors
2956+
const int64_t bcOffsetMax = static_cast<int64_t>(bcWindowForOneSigma * nSigma + timeMargin / BunchSpacingNS);
2957+
const int64_t trackBCCache = static_cast<int64_t>(static_cast<double>(origBC) + static_cast<double>(trackTime) / BunchSpacingNS);
2958+
if (std::abs(trackBCCache - collBC) > bcOffsetMax) {
2959+
return false;
2960+
}
2961+
2962+
// (2) PV-contributor handling (usePVAssociation: 0 off, 1 OnlySameBc, 2 SameBcAndLowMult)
2963+
constexpr int OnlySameBc = 1;
2964+
constexpr int SameBcAndLowMult = 2;
2965+
const bool pvMode = (usePVAssociation == OnlySameBc && isPVContributor) ||
2966+
(usePVAssociation == SameBcAndLowMult && isPVContributor && origNumContrib > maxPvContribLowMult);
2967+
float tTrack = trackTime;
2968+
float tTrackRes = trackTimeRes;
2969+
if (pvMode) {
2970+
tTrack = origCollTime; // time of the ORIGINAL collision
2971+
tTrackRes = static_cast<float>(BunchSpacingNS); // 1 BC
2972+
}
2973+
2974+
// (3) time difference and threshold
2975+
const int64_t bcOffset = origBC - collBC;
2976+
const float collTimeRes2 = collTimeRes * collTimeRes;
2977+
const float deltaTime = tTrack - collTime + bcOffset * static_cast<float>(BunchSpacingNS);
2978+
float threshold = 0.f;
2979+
if (pvMode) {
2980+
threshold = tTrackRes; // margin NOT applied
2981+
} else if (timeResIsRange) {
2982+
threshold = tTrackRes + nSigma * std::sqrt(collTimeRes2) + timeMargin;
2983+
} else {
2984+
threshold = nSigma * std::sqrt(collTimeRes2 + tTrackRes * tTrackRes) + timeMargin;
2985+
}
2986+
2987+
values[kTrackAssocDeltaTime] = deltaTime;
2988+
values[kTrackAssocTimeThreshold] = threshold;
2989+
values[kTrackAssocDeltaTimeNorm] = (threshold > 0.f) ? std::abs(deltaTime) / threshold : 9999.f;
2990+
return std::abs(deltaTime) < threshold;
2991+
}

‎PWGDQ/Core/VarManager.h‎

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,9 @@ class VarManager : public TObject
578578
kTrackTime,
579579
kTrackTimeRes,
580580
kTrackTimeResRelative,
581+
kTrackAssocDeltaTime, // track time - time of the associated collision (BC offset included), ns
582+
kTrackAssocTimeThreshold, // time-compatibility threshold of the track-to-collision associator (margin included), ns
583+
kTrackAssocDeltaTimeNorm, // |kTrackAssocDeltaTime| / kTrackAssocTimeThreshold; < 1 means the association is time compatible
581584
kDetectorMap,
582585
kHasITS,
583586
kHasTRD,
@@ -1474,6 +1477,22 @@ class VarManager : public TObject
14741477
static void FillTrackEMCal(T const& cluster, float trackP = -1.0f, float deltaEta = -999.0f, float deltaPhi = -999.0f, float* values = nullptr);
14751478
template <uint32_t fillMap, typename T, typename C>
14761479
static void FillTrackCollision(T const& track, C const& collision, float* values = nullptr);
1480+
// Re-evaluation of the time compatibility of a (barrel track, collision) association, mirroring
1481+
// Common/Core/CollisionAssociation.h::runAssocWithTime. Fills kTrackAssocDeltaTime, kTrackAssocTimeThreshold, kTrackAssocDeltaTimeNorm.
1482+
// orig* : collision originally assigned to the track in the AO2D (reference of trackTime)
1483+
// coll* : collision of the association under test
1484+
// The last 5 parameters must match the configuration of track-to-collision-associator used at skimming time
1485+
// (timeMargin and nSigma may be smaller in order to tighten the association at analysis level).
1486+
static bool computeBarrelAssocTimeCompat(float trackTime, float trackTimeRes, bool timeResIsRange, bool isPVContributor,
1487+
int64_t origBC, float origCollTime, int origNumContrib,
1488+
int64_t collBC, float collTime, float collTimeRes,
1489+
float nSigma, float timeMargin, int bcWindowForOneSigma,
1490+
int usePVAssociation, int maxPvContribLowMult, float* values = nullptr);
1491+
// Same as above for DQ skimmed tables: track = ReducedTracks+ReducedTracksBarrel, collision/origCollision = ReducedEvents+ReducedEventsExtended
1492+
template <typename T, typename C>
1493+
static bool isBarrelAssocTimeCompatible(T const& track, C const& collision, C const& origCollision,
1494+
float nSigma, float timeMargin, int bcWindowForOneSigma,
1495+
int usePVAssociation, int maxPvContribLowMult, float* values = nullptr);
14771496
template <int candidateType, uint32_t fillMap, typename T1, typename T2, typename C>
14781497
static void FillTrackCollisionMC(T1 const& track, T2 const& MotherTrack, C const& collision, float* values = nullptr);
14791498
template <int candidateType, typename T1>
@@ -3471,6 +3490,18 @@ void VarManager::FillTrackCollision(T const& track, C const& collision, float* v
34713490
}
34723491
}
34733492

3493+
template <typename T, typename C>
3494+
bool VarManager::isBarrelAssocTimeCompatible(T const& track, C const& collision, C const& origCollision,
3495+
float nSigma, float timeMargin, int bcWindowForOneSigma,
3496+
int usePVAssociation, int maxPvContribLowMult, float* values)
3497+
{
3498+
return computeBarrelAssocTimeCompat(track.trackTime(), track.trackTimeRes(),
3499+
(track.flags() & o2::aod::track::TrackTimeResIsRange) > 0, track.isPVContributor(),
3500+
static_cast<int64_t>(origCollision.globalBC()), origCollision.collisionTime(), origCollision.numContrib(),
3501+
static_cast<int64_t>(collision.globalBC()), collision.collisionTime(), collision.collisionTimeRes(),
3502+
nSigma, timeMargin, bcWindowForOneSigma, usePVAssociation, maxPvContribLowMult, values);
3503+
}
3504+
34743505
template <uint32_t fillMap, typename T, typename C, typename M, typename P>
34753506
void VarManager::FillTrackCollisionMatCorr(T const& track, C const& collision, M const& materialCorr, P const& propagator, float* values)
34763507
{

‎PWGDQ/Tasks/dqEfficiency_withAssoc.cxx‎

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,17 @@ struct AnalysisTrackSelection {
554554
Configurable<std::string> fConfigAddTrackHistogram{"cfgAddTrackHistogram", "", "Comma separated list of histograms"};
555555
Configurable<std::string> fConfigAddJSONHistograms{"cfgAddJSONHistograms", "", "Histograms in JSON format"};
556556
Configurable<bool> fConfigPublishAmbiguity{"cfgPublishAmbiguity", true, "If true, publish ambiguity table and fill QA histograms"};
557+
// Re-application of the track-to-collision time compatibility on the skimmed associations.
558+
// timeMargin and nSigma must be <= the values used by track-to-collision-associator at skimming time;
559+
// bcWindow, usePVAssociation and maxPvContributors must be identical to those values.
560+
struct : ConfigurableGroup {
561+
Configurable<bool> cfgAssocTimeCut{"cfgAssocTimeCut", false, "If true, reject associations failing the time compatibility computed with the parameters below"};
562+
Configurable<float> cfgAssocTimeMargin{"cfgAssocTimeMargin", 0.f, "time margin (ns); must be <= skimming timeMargin"};
563+
Configurable<float> cfgAssocNSigma{"cfgAssocNSigma", 4.f, "nSigmaForTimeCompat; must be <= skimming value"};
564+
Configurable<int> cfgAssocBcWindowForOneSigma{"cfgAssocBcWindowForOneSigma", 60, "bcWindowForOneSigma; must be equal to the skimming value"};
565+
Configurable<int> cfgAssocUsePVAssociation{"cfgAssocUsePVAssociation", 1, "usePVAssociation; must be equal to the skimming value"};
566+
Configurable<int> cfgAssocMaxPvContributorsForLowMultReassoc{"cfgAssocMaxPvContributorsForLowMultReassoc", 10, "maxPvContributorsForLowMultReassoc; must be equal to the skimming value"};
567+
} fConfigAssocTime;
557568
Configurable<std::string> fConfigCcdbUrl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"};
558569
Configurable<std::string> fConfigCcdbPathTPC{"ccdb-path-tpc", "Users/z/zhxiong/TPCPID/PostCalib", "base path to the ccdb object"};
559570
Configurable<int64_t> fConfigNoLaterThan{"ccdb-no-later-than", std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable timestamp of creation for the object"};
@@ -711,6 +722,20 @@ struct AnalysisTrackSelection {
711722
}
712723

713724
auto track = assoc.template reducedtrack_as<TTracks>();
725+
726+
// Reject incompatible associations while preserving the row alignment of trackSel.
727+
// The track time is referenced to its original collision, not the associated one.
728+
if (fConfigAssocTime.cfgAssocTimeCut) {
729+
auto origEvent = track.template reducedevent_as<TEvents>();
730+
if (!VarManager::isBarrelAssocTimeCompatible(track, event, origEvent,
731+
fConfigAssocTime.cfgAssocNSigma, fConfigAssocTime.cfgAssocTimeMargin,
732+
fConfigAssocTime.cfgAssocBcWindowForOneSigma, fConfigAssocTime.cfgAssocUsePVAssociation,
733+
fConfigAssocTime.cfgAssocMaxPvContributorsForLowMultReassoc)) {
734+
trackSel(0);
735+
continue;
736+
}
737+
}
738+
714739
VarManager::FillTrack<TTrackFillMap>(track);
715740
// compute quantities which depend on the associated collision, such as DCA
716741
VarManager::FillTrackCollision<TTrackFillMap>(track, event);

‎PWGDQ/Tasks/tableReader_withAssoc.h‎

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -673,6 +673,17 @@ struct AnalysisTrackSelection {
673673
o2::framework::Configurable<std::string> fConfigAddJSONHistograms{"cfgAddJSONHistograms", "", "Histograms in JSON format"};
674674
o2::framework::Configurable<bool> fConfigQA{"cfgQA", false, "If true, fill QA histograms"};
675675
o2::framework::Configurable<bool> fConfigPublishAmbiguity{"cfgPublishAmbiguity", true, "If true, publish ambiguity table and fill QA histograms"};
676+
// Re-application of the track-to-collision time compatibility on the skimmed associations.
677+
// timeMargin and nSigma must be <= the values used by track-to-collision-associator at skimming time;
678+
// bcWindow, usePVAssociation and maxPvContributors must be identical to those values.
679+
struct : o2::framework::ConfigurableGroup {
680+
o2::framework::Configurable<bool> cfgAssocTimeCut{"cfgAssocTimeCut", false, "If true, reject associations failing the time compatibility computed with the parameters below"};
681+
o2::framework::Configurable<float> cfgAssocTimeMargin{"cfgAssocTimeMargin", 0.f, "time margin (ns); must be <= skimming timeMargin"};
682+
o2::framework::Configurable<float> cfgAssocNSigma{"cfgAssocNSigma", 4.f, "nSigmaForTimeCompat; must be <= skimming value"};
683+
o2::framework::Configurable<int> cfgAssocBcWindowForOneSigma{"cfgAssocBcWindowForOneSigma", 60, "bcWindowForOneSigma; must be equal to the skimming value"};
684+
o2::framework::Configurable<int> cfgAssocUsePVAssociation{"cfgAssocUsePVAssociation", 1, "usePVAssociation; must be equal to the skimming value"};
685+
o2::framework::Configurable<int> cfgAssocMaxPvContributorsForLowMultReassoc{"cfgAssocMaxPvContributorsForLowMultReassoc", 10, "maxPvContributorsForLowMultReassoc; must be equal to the skimming value"};
686+
} fConfigAssocTime;
676687

677688
o2::framework::Configurable<std::string> fConfigCcdbUrl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"};
678689
o2::framework::Configurable<std::string> fConfigCcdbPathTPC{"ccdb-path-tpc", "Users/z/zhxiong/TPCPID/PostCalib", "base path to the ccdb object"};
@@ -806,6 +817,20 @@ struct AnalysisTrackSelection {
806817
VarManager::FillEvent<TEventFillMap>(event);
807818

808819
auto track = assoc.template reducedtrack_as<TTracks>();
820+
821+
// Reject incompatible associations while preserving the row alignment of trackSel.
822+
// The track time is referenced to its original collision, not the associated one.
823+
if (fConfigAssocTime.cfgAssocTimeCut) {
824+
auto origEvent = track.template reducedevent_as<TEvents>();
825+
if (!VarManager::isBarrelAssocTimeCompatible(track, event, origEvent,
826+
fConfigAssocTime.cfgAssocNSigma, fConfigAssocTime.cfgAssocTimeMargin,
827+
fConfigAssocTime.cfgAssocBcWindowForOneSigma, fConfigAssocTime.cfgAssocUsePVAssociation,
828+
fConfigAssocTime.cfgAssocMaxPvContributorsForLowMultReassoc)) {
829+
trackSel(0);
830+
continue;
831+
}
832+
}
833+
809834
filterMap = static_cast<uint32_t>(0);
810835
VarManager::FillTrack<TTrackFillMap>(track);
811836
// compute quantities which depend on the associated collision, such as DCA

0 commit comments

Comments
 (0)