Skip to content

Commit 6826646

Browse files
authored
[Common] adding median time for occupancy estimation (#14202)
1 parent 19e7808 commit 6826646

File tree

3 files changed

+47
-24
lines changed

3 files changed

+47
-24
lines changed

Common/DataModel/EventSelection.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ DECLARE_SOA_INDEX_COLUMN_FULL(FoundFDD, foundFDD, int, FDDs, "_foundFDD"); //!
6565
DECLARE_SOA_INDEX_COLUMN_FULL(FoundZDC, foundZDC, int, Zdcs, "_foundZDC"); //! ZDC entry index in ZDCs table (-1 if doesn't exist)
6666
DECLARE_SOA_COLUMN(NumTracksInTimeRange, trackOccupancyInTimeRange, int); //! Occupancy in specified time interval by a number of tracks from nearby collisions // o2-linter: disable=name/o2-column
6767
DECLARE_SOA_COLUMN(SumAmpFT0CInTimeRange, ft0cOccupancyInTimeRange, float); //! Occupancy in specified time interval by a sum of FT0C amplitudes from nearby collisions // o2-linter: disable=name/o2-column
68+
DECLARE_SOA_COLUMN(OccupancyMedianTime, occupancyMedianTime, float); //! Median time for the occupancy in specified time interval (the delta-time wrt to the collision at which occupancy crosses 1/2 of its full value)
6869
} // namespace evsel
6970

7071
// bc-joinable event selection decisions
@@ -85,7 +86,8 @@ DECLARE_SOA_TABLE(EvSels, "AOD", "EVSEL", //!
8586
evsel::FoundFDDId,
8687
evsel::FoundZDCId,
8788
evsel::NumTracksInTimeRange,
88-
evsel::SumAmpFT0CInTimeRange);
89+
evsel::SumAmpFT0CInTimeRange,
90+
evsel::OccupancyMedianTime);
8991
using EvSel = EvSels::iterator;
9092
} // namespace o2::aod
9193

Common/TableProducer/eventSelection.cxx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -694,7 +694,7 @@ struct EventSelectionTask {
694694
}
695695
}
696696

697-
evsel(alias, selection, rct, sel7, sel8, foundBC, foundFT0, foundFV0, foundFDD, foundZDC, 0, 0);
697+
evsel(alias, selection, rct, sel7, sel8, foundBC, foundFT0, foundFV0, foundFDD, foundZDC, 0, 0, 0);
698698
}
699699
PROCESS_SWITCH(EventSelectionTask, processRun2, "Process Run2 event selection", true);
700700

@@ -750,7 +750,7 @@ struct EventSelectionTask {
750750
int32_t foundFDD = bc.foundFDDId();
751751
int32_t foundZDC = bc.foundZDCId();
752752
uint32_t rct = 0;
753-
evsel(bc.alias_raw(), bc.selection_raw(), rct, kFALSE, kFALSE, foundBC, foundFT0, foundFV0, foundFDD, foundZDC, -1, -1);
753+
evsel(bc.alias_raw(), bc.selection_raw(), rct, kFALSE, kFALSE, foundBC, foundFT0, foundFV0, foundFDD, foundZDC, -1, -1, -1);
754754
}
755755
return;
756756
}
@@ -1166,7 +1166,7 @@ struct EventSelectionTask {
11661166
}
11671167

11681168
evsel(alias, selection, rct, sel7, sel8, foundBC, foundFT0, foundFV0, foundFDD, foundZDC,
1169-
vNumTracksITS567inFullTimeWin[colIndex], vSumAmpFT0CinFullTimeWin[colIndex]);
1169+
vNumTracksITS567inFullTimeWin[colIndex], vSumAmpFT0CinFullTimeWin[colIndex], 0);
11701170
}
11711171
}
11721172

Common/Tools/EventSelectionModule.h

Lines changed: 41 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ struct bcselConfigurables : o2::framework::ConfigurableGroup {
9696
o2::framework::Configurable<int> confTimeFrameStartBorderMargin{"TimeFrameStartBorderMargin", -1, "Number of bcs to cut at the start of the Time Frame. Take from CCDB if -1"}; // o2-linter: disable=name/configurable (temporary fix)
9797
o2::framework::Configurable<int> confTimeFrameEndBorderMargin{"TimeFrameEndBorderMargin", -1, "Number of bcs to cut at the end of the Time Frame. Take from CCDB if -1"}; // o2-linter: disable=name/configurable (temporary fix)
9898
o2::framework::Configurable<bool> confCheckRunDurationLimits{"checkRunDurationLimits", false, "Check if the BCs are within the run duration limits"}; // o2-linter: disable=name/configurable (temporary fix)
99-
o2::framework::Configurable<std::vector<int>> maxInactiveChipsPerLayer{"maxInactiveChipsPerLayer", {8, 8, 8, 111, 111, 195, 195}, "Maximum allowed number of inactive ITS chips per layer"};
99+
o2::framework::Configurable<std::vector<int>> confMaxInactiveChipsPerLayer{"maxInactiveChipsPerLayer", {8, 8, 8, 111, 111, 195, 195}, "Maximum allowed number of inactive ITS chips per layer"};
100100
o2::framework::Configurable<int> confNumberOfOrbitsPerTF{"NumberOfOrbitsPerTF", -1, "Number of orbits per Time Frame. Take from CCDB if -1"}; // o2-linter: disable=name/configurable (temporary fix)
101101
};
102102

@@ -121,6 +121,8 @@ struct evselConfigurables : o2::framework::ConfigurableGroup {
121121
o2::framework::Configurable<bool> confUseWeightsForOccupancyVariable{"UseWeightsForOccupancyEstimator", 1, "Use or not the delta-time weights for the occupancy estimator"}; // o2-linter: disable=name/configurable (temporary fix)
122122
o2::framework::Configurable<int> confNumberOfOrbitsPerTF{"NumberOfOrbitsPerTF", -1, "Number of orbits per Time Frame. Take from CCDB if -1"}; // o2-linter: disable=name/configurable (temporary fix)
123123

124+
// o2::framework::Configurable<std::vector<float>> confTimeIntervalsForGranularOccupancy{"timeIntervalsForGranularOccupancy", {-100, -60, -30, -10, 0, 10, 30, 60, 100}, "Delta-time intervals (wrt given collision) for which we store occupancy"};
125+
124126
// configurables for light-ion event selection
125127
o2::framework::Configurable<float> confLightIonsNsigmaOnVzDiff{"VzDiffNsigma", 3.0, "+/- nSigma on vZ difference by FT0 and by tracks"}; // o2-linter: disable=name/configurable (temporary fix)
126128
o2::framework::Configurable<float> confLightIonsMarginVzDiff{"VzDiffMargin", 0.2, "margin for +/- nSigma cut on vZ difference by FT0 and by tracks, cm"}; // o2-linter: disable=name/configurable (temporary fix)
@@ -561,14 +563,14 @@ class BcSelectionModule
561563
LOGP(debug, "orbit: {}, previous orbit: {}, next orbit: {} ", orbit, prevOrbitForInactiveChips, nextOrbitForInactiveChips);
562564
LOGP(debug, "next inactive chips: {} {} {} {} {} {} {}", vNextInactiveChips[0], vNextInactiveChips[1], vNextInactiveChips[2], vNextInactiveChips[3], vNextInactiveChips[4], vNextInactiveChips[5], vNextInactiveChips[6]);
563565
LOGP(debug, "prev inactive chips: {} {} {} {} {} {} {}", vPrevInactiveChips[0], vPrevInactiveChips[1], vPrevInactiveChips[2], vPrevInactiveChips[3], vPrevInactiveChips[4], vPrevInactiveChips[5], vPrevInactiveChips[6]);
564-
isGoodITSLayer3 = vPrevInactiveChips[3] <= bcselOpts.maxInactiveChipsPerLayer->at(3) && vNextInactiveChips[3] <= bcselOpts.maxInactiveChipsPerLayer->at(3);
566+
isGoodITSLayer3 = vPrevInactiveChips[3] <= bcselOpts.confMaxInactiveChipsPerLayer->at(3) && vNextInactiveChips[3] <= bcselOpts.confMaxInactiveChipsPerLayer->at(3);
565567
isGoodITSLayer0123 = true;
566568
for (int i = 0; i < 4; i++) { // o2-linter: disable=magic-number (counting first 4 ITS layers)
567-
isGoodITSLayer0123 &= vPrevInactiveChips[i] <= bcselOpts.maxInactiveChipsPerLayer->at(i) && vNextInactiveChips[i] <= bcselOpts.maxInactiveChipsPerLayer->at(i);
569+
isGoodITSLayer0123 &= vPrevInactiveChips[i] <= bcselOpts.confMaxInactiveChipsPerLayer->at(i) && vNextInactiveChips[i] <= bcselOpts.confMaxInactiveChipsPerLayer->at(i);
568570
}
569571
isGoodITSLayersAll = true;
570572
for (int i = 0; i < o2::itsmft::ChipMappingITS::NLayers; i++) {
571-
isGoodITSLayersAll &= vPrevInactiveChips[i] <= bcselOpts.maxInactiveChipsPerLayer->at(i) && vNextInactiveChips[i] <= bcselOpts.maxInactiveChipsPerLayer->at(i);
573+
isGoodITSLayersAll &= vPrevInactiveChips[i] <= bcselOpts.confMaxInactiveChipsPerLayer->at(i) && vNextInactiveChips[i] <= bcselOpts.confMaxInactiveChipsPerLayer->at(i);
572574
}
573575
}
574576

@@ -875,7 +877,7 @@ class EventSelectionModule
875877
}
876878
}
877879

878-
evsel(alias, selection, rct, sel7, sel8, foundBC, foundFT0, foundFV0, foundFDD, foundZDC, 0, 0);
880+
evsel(alias, selection, rct, sel7, sel8, foundBC, foundFT0, foundFV0, foundFDD, foundZDC, 0, 0, 0);
879881
}
880882
} // end processRun2
881883

@@ -924,7 +926,7 @@ class EventSelectionModule
924926
int32_t foundFDD = bcselbuffer[bc.globalIndex()].foundFDDId;
925927
int32_t foundZDC = bcselbuffer[bc.globalIndex()].foundZDCId;
926928
uint32_t rct = 0;
927-
evsel(bcselbuffer[bc.globalIndex()].alias, bcselbuffer[bc.globalIndex()].selection, rct, kFALSE, kFALSE, foundBC, foundFT0, foundFV0, foundFDD, foundZDC, -1, -1);
929+
evsel(bcselbuffer[bc.globalIndex()].alias, bcselbuffer[bc.globalIndex()].selection, rct, kFALSE, kFALSE, foundBC, foundFT0, foundFV0, foundFDD, foundZDC, -1, -1, -1);
928930
}
929931
return;
930932
}
@@ -1138,9 +1140,10 @@ class EventSelectionModule
11381140

11391141
// pre-loop for occupancy calculation
11401142
std::vector<bool> vIsFullInfoForOccupancy(cols.size(), 0); // info for occupancy in +/- windows is available (i.e. a given coll is not too close to the TF borders)
1141-
std::vector<bool> vIsCollAtROFborder(cols.size(), 0); // collision is close to ITS ROF border
11421143
std::vector<bool> vIsCollRejectedByTFborderCut(cols.size(), 0); // helper vector with
11431144
std::vector<bool> vCanHaveAssocCollsWithinLastDriftTime(cols.size(), 0); // to see if for some collisions in the occupancy calc (that are close to TF border) we will switch to FT0C based occupancy estimation
1145+
std::vector<int> vProxyForCollNtracks(cols.size(), 0); // n tracks, or - if a collision is close to ITS ROF border - scaled FT0C mult
1146+
std::vector<float> vMedianTimeForOccupancy(cols.size(), 0); // median time for the occupancy in a defined time window
11441147

11451148
const float timeWinOccupancyCalcMinNS = evselOpts.confTimeIntervalForOccupancyCalculationMin * 1e3; // ns
11461149
const float timeWinOccupancyCalcMaxNS = evselOpts.confTimeIntervalForOccupancyCalculationMax * 1e3; // ns
@@ -1153,10 +1156,9 @@ class EventSelectionModule
11531156

11541157
int32_t foundBC = vFoundBCindex[colIndex];
11551158
auto bcselEntry = bcselbuffer[foundBC];
1156-
// check if we are close to ROF or TF borders => N tracks are not reliable, but FT0 can be used for occupancy estimation
1157-
if (!bitcheck64(bcselEntry.selection, aod::evsel::kNoITSROFrameBorder)) {
1158-
vIsCollAtROFborder[colIndex] = true;
1159-
}
1159+
// check if we are close to ITS ROF borders => N ITS tracks is not reliable, and FT0C ampl can be used for occupancy estimation
1160+
// denominator for vAmpFT0CperColl is the approximate conversion factor b/n FT0C ampl and number of PV tracks after cuts
1161+
vProxyForCollNtracks[colIndex] = bitcheck64(bcselEntry.selection, aod::evsel::kNoITSROFrameBorder) ? vTracksITS567perColl[colIndex] : vAmpFT0CperColl[colIndex] / 10.;
11601162

11611163
if (!bitcheck64(bcselEntry.selection, aod::evsel::kNoTimeFrameBorder)) {
11621164
vIsCollRejectedByTFborderCut[colIndex] = true;
@@ -1239,6 +1241,7 @@ class EventSelectionModule
12391241
// ### for occupancy in time windows
12401242
std::vector<int> vAssocToThisCol;
12411243
std::vector<float> vCollsTimeDeltaWrtGivenColl;
1244+
std::vector<float> vProxyNtracksAssocColls; // mult of associated collisions, for the median time calc
12421245
// find all collisions in time window before the current one
12431246
minColIndex = colIndex - 1;
12441247
while (minColIndex >= 0) {
@@ -1253,6 +1256,7 @@ class EventSelectionModule
12531256
break;
12541257
vAssocToThisCol.push_back(minColIndex);
12551258
vCollsTimeDeltaWrtGivenColl.push_back(dt);
1259+
vProxyNtracksAssocColls.push_back(vProxyForCollNtracks[minColIndex]);
12561260
minColIndex--;
12571261
}
12581262
// find all collisions in time window after the current one
@@ -1267,10 +1271,31 @@ class EventSelectionModule
12671271
break;
12681272
vAssocToThisCol.push_back(maxColIndex);
12691273
vCollsTimeDeltaWrtGivenColl.push_back(dt);
1274+
vProxyNtracksAssocColls.push_back(vProxyForCollNtracks[maxColIndex]);
12701275
maxColIndex++;
12711276
}
12721277
vCollsInTimeWin.push_back(vAssocToThisCol);
12731278
vTimeDeltaForColls.push_back(vCollsTimeDeltaWrtGivenColl);
1279+
1280+
// calculation of the median time for the occupancy in a given time window
1281+
std::vector<std::pair<float, float>> pairsDeltaTimeMult;
1282+
for (size_t iCol = 0; iCol < vCollsTimeDeltaWrtGivenColl.size(); iCol++)
1283+
pairsDeltaTimeMult.emplace_back(vCollsTimeDeltaWrtGivenColl[iCol], vProxyNtracksAssocColls[iCol]);
1284+
std::sort(pairsDeltaTimeMult.begin(), pairsDeltaTimeMult.end()); // sorts by first element by default
1285+
int proxyTotalMultInTimeWin = std::accumulate(vProxyNtracksAssocColls.begin(), vProxyNtracksAssocColls.end(), 0);
1286+
1287+
float sumMult = 0.0;
1288+
for (size_t iCol = 0; iCol < vCollsTimeDeltaWrtGivenColl.size(); iCol++) {
1289+
sumMult += pairsDeltaTimeMult[iCol].second;
1290+
if (sumMult > proxyTotalMultInTimeWin / 2.0) {
1291+
vMedianTimeForOccupancy[colIndex] = pairsDeltaTimeMult[iCol].first / 1e3; // ns -> us
1292+
break;
1293+
}
1294+
}
1295+
for (size_t iCol = 0; iCol < vCollsTimeDeltaWrtGivenColl.size(); iCol++) {
1296+
LOGP(debug, "dt={} mult={}", pairsDeltaTimeMult[iCol].first, pairsDeltaTimeMult[iCol].second);
1297+
}
1298+
LOGP(debug, " --> median time = {}", vMedianTimeForOccupancy[colIndex]);
12741299
}
12751300

12761301
// perform the occupancy calculation per ITS ROF and also in the pre-defined time window
@@ -1330,15 +1355,11 @@ class EventSelectionModule
13301355
for (uint32_t iCol = 0; iCol < vAssocToThisCol.size(); iCol++) {
13311356
int thisColIndex = vAssocToThisCol[iCol];
13321357
float dt = vCollsTimeDeltaWrtGivenColl[iCol] / 1e3; // ns -> us
1333-
1334-
// check if we are close to ITS ROF borders => N ITS tracks is not reliable, and FT0C ampl can be used for occupancy estimation
1335-
// denominator for vAmpFT0CperColl is the approximate conversion factor b/n FT0C ampl and number of PV tracks after cuts
1336-
int nItsTracksAssocColl = !vIsCollAtROFborder[thisColIndex] ? vTracksITS567perColl[thisColIndex] : vAmpFT0CperColl[thisColIndex] / 10.;
13371358
// counting tracks from other collisions in fixed time windows
13381359
if (std::fabs(dt) < evselOpts.confTimeRangeVetoOnCollNarrow)
1339-
nITS567tracksForVetoNarrow += nItsTracksAssocColl;
1360+
nITS567tracksForVetoNarrow += vProxyForCollNtracks[thisColIndex];
13401361
if (std::fabs(dt) < evselOpts.confTimeRangeVetoOnCollStrict)
1341-
nITS567tracksForVetoStrict += nItsTracksAssocColl;
1362+
nITS567tracksForVetoStrict += vProxyForCollNtracks[thisColIndex];
13421363

13431364
// veto on high-mult collisions nearby, where artificial structures in the dt-occupancy plots are observed
13441365
if (dt > -4.0 && dt < 2.0 && vAmpFT0CperColl[thisColIndex] > evselOpts.confFT0CamplCutVetoOnCollInTimeRange) { // dt in us // o2-linter: disable=magic-number
@@ -1359,7 +1380,7 @@ class EventSelectionModule
13591380
// weighted occupancy
13601381
wOccup = calcWeightForOccupancy(dt);
13611382
}
1362-
nITS567tracksInFullTimeWindow += wOccup * nItsTracksAssocColl;
1383+
nITS567tracksInFullTimeWindow += wOccup * vProxyForCollNtracks[thisColIndex];
13631384
sumAmpFT0CInFullTimeWindow += wOccup * vAmpFT0CperColl[thisColIndex];
13641385
}
13651386
}
@@ -1410,7 +1431,7 @@ class EventSelectionModule
14101431
vNoCollInTimeRangeNarrow[colIndex] = (nITS567tracksForVetoNarrow == 0);
14111432
vNoCollInTimeRangeStrict[colIndex] = (nITS567tracksForVetoStrict == 0);
14121433
vNoHighMultCollInTimeRange[colIndex] = (nCollsWithFT0CAboveVetoStandard == 0 && nITS567tracksForVetoNarrow == 0);
1413-
}
1434+
} // end of the occupancy calculation
14141435

14151436
for (const auto& col : cols) {
14161437
int32_t colIndex = col.globalIndex();
@@ -1490,7 +1511,7 @@ class EventSelectionModule
14901511
}
14911512

14921513
evsel(alias, selection, rct, sel7, sel8, foundBC, foundFT0, foundFV0, foundFDD, foundZDC,
1493-
vNumTracksITS567inFullTimeWin[colIndex], vSumAmpFT0CinFullTimeWin[colIndex]);
1514+
vNumTracksITS567inFullTimeWin[colIndex], vSumAmpFT0CinFullTimeWin[colIndex], vMedianTimeForOccupancy[colIndex]);
14941515
}
14951516
} // end processRun3
14961517
}; // end EventSelectionModule

0 commit comments

Comments
 (0)