Skip to content

Commit bc257c4

Browse files
authored
Add track efficiency correction and fix table defintions of generated collisions
1 parent 3ba728f commit bc257c4

1 file changed

Lines changed: 73 additions & 161 deletions

File tree

PWGCF/TwoParticleCorrelations/TableProducer/longrangeMaker.cxx

Lines changed: 73 additions & 161 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,6 @@ auto static constexpr TotFt0Channels = 208;
8686
AxisSpec axisEvent{20, 0.5, 20.5, "#Event", "EventAxis"};
8787
AxisSpec axisTrackSel{10, 0.5, 10.5, "#Track", "TrackAxis"};
8888
auto static constexpr KminCharge = 3.0f;
89-
static constexpr std::string_view species[] = {"Pi", "Ka", "Pr"};
90-
static constexpr std::array<int, 3> speciesIds{kPiPlus, kKPlus, kProton};
9189

9290
enum KindOfV0 {
9391
kLambda = 0,
@@ -128,7 +126,6 @@ struct LongrangeMaker {
128126
} cfgevtsel;
129127

130128
struct : ConfigurableGroup {
131-
Configurable<int> cfgItsPattern{"cfgItsPattern", 1, "0 = Run3ITSibAny, 1 = Run3ITSallAny, 2 = Run3ITSall7Layers, 3 = Run3ITSibTwo"};
132129
Configurable<float> cfgEtaCut{"cfgEtaCut", 0.8f, "Eta range to consider"};
133130
Configurable<float> cfgPtCutMin{"cfgPtCutMin", 0.2f, "minimum accepted track pT"};
134131
Configurable<float> cfgPtCutMax{"cfgPtCutMax", 10.0f, "maximum accepted track pT"};
@@ -140,12 +137,13 @@ struct LongrangeMaker {
140137
Configurable<float> maxChi2PerClusterITS{"maxChi2PerClusterITS", 36.f, "cut on maximum value of ITS chi2 per cluster"};
141138
Configurable<float> maxDcaZ{"maxDcaZ", 2.0f, "cut on maximum abs value of DCA z"};
142139
Configurable<float> maxDcaXY{"maxDcaXY", 1.0f, "cut on maximum abs value of DCA xy"};
140+
Configurable<float> cfgLowEffCut{"cfgLowEffCut", 0.001f, "Low efficiency cut"};
141+
Configurable<bool> applyEffCorr{"applyEffCorr", true, "Enable efficiency correction"};
142+
Configurable<std::string> cfgEffccdbPath{"cfgEffccdbPath", "/alice/data/CCDB/Users/a/abmodak/OO/Efficiency", "Browse track eff object from CCDB"};
143143
} cfgtrksel;
144144

145145
struct : ConfigurableGroup {
146146
Configurable<bool> cfgUseChi2Cut{"cfgUseChi2Cut", false, "Use condition on MFT track: chi2/Nclusters"};
147-
Configurable<bool> cfgRequireCA{"cfgRequireCA", false, "Use Cellular Automaton track-finding algorithm"};
148-
Configurable<bool> cfgRequireLTF{"cfgRequireLTF", false, "Use LTF track-finding algorithm"};
149147
Configurable<bool> useMftPtCut{"useMftPtCut", true, "Choose to apply MFT track pT cut"};
150148
Configurable<int> cfgMftCluster{"cfgMftCluster", 5, "cut on MFT Cluster"};
151149
Configurable<float> cfgMftEtaMax{"cfgMftEtaMax", -2.4f, "Maximum MFT eta cut"};
@@ -195,11 +193,6 @@ struct LongrangeMaker {
195193
} cfgv0trksel;
196194

197195
struct : ConfigurableGroup {
198-
ConfigurableAxis axisVtx = {"axisVtx", {20, -10, 10}, "Vertex axis"};
199-
ConfigurableAxis axisMult = {"axisMult", {100, 0, 100}, "Multiplicity axis"};
200-
ConfigurableAxis axisEta = {"axisEta", {20, -1, 1}, "eta axis"};
201-
ConfigurableAxis axisPt = {"axisPt", {10, 0, 10}, "pT axis"};
202-
ConfigurableAxis axisSpecies = {"axisSpecies", {4, 0.5, 4.5}, "Species axis"};
203196
ConfigurableAxis axisAmplitude{"axisAmplitude", {5000, 0, 10000}, "FT0 amplitude"};
204197
ConfigurableAxis axisChannel{"axisChannel", {208, 0, 208}, "FT0 channel"};
205198
ConfigurableAxis axisMFTAmbDegree{"axisMFTAmbDegree", {50, -0.5, 49.5}, "Track Ambiguity axis"};
@@ -232,6 +225,10 @@ struct LongrangeMaker {
232225
Configurable<SGCutParHolder> sgCuts{"sgCuts", {}, "SG event cuts"};
233226
Configurable<int> cfgGapSide{"cfgGapSide", 2, "cut on UPC events"};
234227

228+
// corrections
229+
TH3D* hTrkEff = nullptr;
230+
bool fLoadTrkEffCorr = false;
231+
235232
void init(InitContext&)
236233
{
237234
ccdb->setURL(cfgCcdbParam.cfgURL);
@@ -261,7 +258,8 @@ struct LongrangeMaker {
261258
x->SetBinLabel(12, "ApplyNoCollInTimeRangeStrict");
262259
x->SetBinLabel(13, "ApplyNoHighMultCollInPrevRof");
263260
x->SetBinLabel(14, "ApplyOccupancySelection");
264-
x->SetBinLabel(15, "reject flange event");
261+
x->SetBinLabel(15, "ZvertexSelection");
262+
x->SetBinLabel(16, "reject flange event");
265263
histos.add("hSelectionResult", "hSelectionResult", kTH1I, {{5, -0.5, 4.5}});
266264

267265
histos.add("hMftTrkSel", "hMftTrkSel", kTH1D, {axisTrackSel}, false);
@@ -293,22 +291,8 @@ struct LongrangeMaker {
293291
histos.add("FT0C_Channel_vs_Amp", "FT0C_Channel_vs_Amp", kTH2D, {cfgAxis.axisChannel, cfgAxis.axisAmplitude});
294292
histos.add("FT0C_Channel_vs_Amp_gaincorrected", "FT0C_Channel_vs_Amp_gaincorrected", kTH2D, {cfgAxis.axisChannel, cfgAxis.axisAmplitude});
295293

296-
if (doprocessTPCtrackEff || doprocessMFTtrackEff) {
297-
histos.add("hGenMCdndpt", "hGenMCdndpt", kTHnSparseD, {cfgAxis.axisVtx, cfgAxis.axisMult, cfgAxis.axisEta, cfgAxis.axisPt, cfgAxis.axisSpecies}, false);
298-
histos.add("hRecMCdndpt", "hRecMCdndpt", kTHnSparseD, {cfgAxis.axisVtx, cfgAxis.axisMult, cfgAxis.axisEta, cfgAxis.axisPt, cfgAxis.axisSpecies}, false);
299-
auto hGenSpecies = histos.get<THnSparse>(HIST("hGenMCdndpt"));
300-
auto hRecSpecies = histos.get<THnSparse>(HIST("hRecMCdndpt"));
301-
auto* axisGen = hGenSpecies->GetAxis(4);
302-
auto* axisRec = hRecSpecies->GetAxis(4);
303-
for (auto i = 0U; i < speciesIds.size(); ++i) {
304-
axisGen->SetBinLabel(i + 1, species[i].data());
305-
axisRec->SetBinLabel(i + 1, species[i].data());
306-
}
307-
axisGen->SetBinLabel(4, "Other");
308-
axisRec->SetBinLabel(4, "Other");
309-
}
310-
311-
myTrackFilter = getGlobalTrackSelectionRun3ITSMatch(cfgtrksel.cfgItsPattern, TrackSelection::GlobalTrackRun3DCAxyCut::Default);
294+
myTrackFilter = getGlobalTrackSelectionRun3ITSMatch(TrackSelection::GlobalTrackRun3ITSMatching::Run3ITSibAny,
295+
TrackSelection::GlobalTrackRun3DCAxyCut::Default);
312296
myTrackFilter.SetPtRange(cfgtrksel.cfgPtCutMin, cfgtrksel.cfgPtCutMax);
313297
myTrackFilter.SetEtaRange(-cfgtrksel.cfgEtaCut, cfgtrksel.cfgEtaCut);
314298
myTrackFilter.SetMinNCrossedRowsTPC(cfgtrksel.minNCrossedRowsTPC);
@@ -368,9 +352,8 @@ struct LongrangeMaker {
368352
if (!isEventSelected(col)) {
369353
return;
370354
}
371-
auto multiplicity = countNTracks(tracks);
372-
auto centrality = selColCent(col);
373355
auto bc = col.bc_as<aod::BCsWithTimestamps>();
356+
loadEffCorrection(bc.timestamp());
374357
// retrieve FT0 gain info from CCDB
375358
ft0gainvalues.clear();
376359
ft0gainvalues = {};
@@ -388,6 +371,8 @@ struct LongrangeMaker {
388371
ft0gainvalues.push_back(1.);
389372
}
390373
}
374+
auto multiplicity = countNTracks(tracks, col.posZ());
375+
auto centrality = selColCent(col);
391376
lrcollision(bc.runNumber(), col.posZ(), multiplicity, centrality, bc.timestamp());
392377

393378
// track loop
@@ -430,7 +415,7 @@ struct LongrangeMaker {
430415
return;
431416
}
432417
}
433-
histos.fill(HIST("EventHist"), 15);
418+
histos.fill(HIST("EventHist"), 16);
434419
for (std::size_t iCh = 0; iCh < ft0.channelA().size(); iCh++) {
435420
auto chanelid = ft0.channelA()[iCh];
436421
float ampl = ft0.amplitudeA()[iCh];
@@ -566,6 +551,7 @@ struct LongrangeMaker {
566551
}
567552

568553
auto bc = col.template foundBC_as<BCs>();
554+
loadEffCorrection(bc.timestamp());
569555
auto newbc = bc;
570556
// obtain slice of compatible BCs
571557
auto bcRange = udhelpers::compatibleBCs(col, cfgSgCuts.NDtcoll(), bcs, cfgSgCuts.minNBCs());
@@ -581,7 +567,7 @@ struct LongrangeMaker {
581567

582568
upchelpers::FITInfo fitInfo{};
583569
udhelpers::getFITinfo(fitInfo, newbc, bcs, ft0s, fv0as, fdds);
584-
auto multiplicity = countNTracks(tracks);
570+
auto multiplicity = countNTracks(tracks, col.posZ());
585571
upclrcollision(bc.globalBC(), bc.runNumber(), col.posZ(), multiplicity, fitInfo.ampFT0A, fitInfo.ampFT0C, fitInfo.timeFV0A);
586572
upcsglrcollision(issgevent);
587573
if (newbc.has_zdc()) {
@@ -753,10 +739,8 @@ struct LongrangeMaker {
753739
if (cfgevtsel.isApplyBestCollIndex && RecCol.globalIndex() != mcCollision.bestCollisionIndex()) {
754740
continue;
755741
}
756-
auto recTracksPart = RecTracks.sliceBy(perColMidtrack, RecCol.globalIndex());
757-
auto multiplicity = countNTracks(recTracksPart);
758-
auto centrality = selColCent(RecCol);
759742
auto bc = RecCol.bc_as<aod::BCsWithTimestamps>();
743+
loadEffCorrection(bc.timestamp());
760744
ft0gainvalues.clear();
761745
ft0gainvalues = {};
762746
if (cfgfittrksel.useGainCalib) {
@@ -773,6 +757,9 @@ struct LongrangeMaker {
773757
ft0gainvalues.push_back(1.);
774758
}
775759
}
760+
auto recTracksPart = RecTracks.sliceBy(perColMidtrack, RecCol.globalIndex());
761+
auto multiplicity = countNTracks(recTracksPart, RecCol.posZ());
762+
auto centrality = selColCent(RecCol);
776763
lrcollision(bc.runNumber(), RecCol.posZ(), multiplicity, centrality, bc.timestamp());
777764
lrcollisionMcLabel(RecCol.mcCollisionId());
778765

@@ -895,15 +882,22 @@ struct LongrangeMaker {
895882
}
896883
}
897884

898-
void processMCGen(ColMCTrueTable::iterator const& mcCollision, aod::McParticles const& mcparticles)
885+
void processMCGen(aod::McCollisions::iterator const& mcCollision, aod::McParticles const& mcparticles)
899886
{
900887
auto multiplicity = 0;
888+
auto multMCFT0A = 0;
889+
auto multMCFT0C = 0;
901890
for (const auto& particle : mcparticles) {
902-
if (!isGenPartSelected(particle) || std::abs(particle.eta()) > cfgtrksel.cfgEtaCut || particle.pt() < cfgtrksel.cfgPtCutMin || particle.pt() > cfgtrksel.cfgPtCutMult)
891+
if (!isGenPartSelected(particle))
903892
continue;
904-
multiplicity++;
893+
if (std::abs(particle.eta()) < cfgtrksel.cfgEtaCut && particle.pt() > cfgtrksel.cfgPtCutMin && particle.pt() < cfgtrksel.cfgPtCutMult)
894+
multiplicity++;
895+
if (cfgfittrksel.cfgFt0cEtaMin < particle.eta() && particle.eta() < cfgfittrksel.cfgFt0cEtaMax)
896+
multMCFT0C++;
897+
if (cfgfittrksel.cfgFt0aEtaMin < particle.eta() && particle.eta() < cfgfittrksel.cfgFt0aEtaMax)
898+
multMCFT0A++;
905899
}
906-
lrmccollision(mcCollision.posZ(), multiplicity, mcCollision.multMCFT0A(), mcCollision.multMCFT0C());
900+
lrmccollision(mcCollision.posZ(), multiplicity, multMCFT0A, multMCFT0C);
907901

908902
for (const auto& particle : mcparticles) {
909903
if (!isGenPartSelected(particle)) {
@@ -923,125 +917,6 @@ struct LongrangeMaker {
923917
}
924918
}
925919

926-
void processTPCtrackEff(ColMCTrueTable::iterator const& mcCollision, ColMCRecTable const& RecCols,
927-
TrksMCRecTable const& RecTracks, aod::McParticles const& mcparticles)
928-
{
929-
if (std::abs(mcCollision.posZ()) >= cfgevtsel.cfgVtxCut) {
930-
return;
931-
}
932-
auto multiplicity = 0;
933-
bool atLeastOne = false;
934-
for (const auto& RecCol : RecCols) {
935-
if (!isEventSelected(RecCol))
936-
continue;
937-
if (std::abs(RecCol.posZ()) >= cfgevtsel.cfgVtxCut)
938-
continue;
939-
if (cfgevtsel.isApplyBestCollIndex && RecCol.globalIndex() != mcCollision.bestCollisionIndex())
940-
continue;
941-
if (isUseCentEst) {
942-
multiplicity = selColCent(RecCol);
943-
} else {
944-
auto recTracksPart = RecTracks.sliceBy(perColMidtrack, RecCol.globalIndex());
945-
multiplicity = countNTracks(recTracksPart);
946-
}
947-
atLeastOne = true;
948-
}
949-
for (const auto& particle : mcparticles) {
950-
if (!isGenPartSelected(particle) || std::abs(particle.eta()) > cfgtrksel.cfgEtaCut || particle.pt() < cfgtrksel.cfgPtCutMin || particle.pt() > cfgtrksel.cfgPtCutMax)
951-
continue;
952-
if (atLeastOne) {
953-
auto pos = std::distance(speciesIds.begin(), std::find(speciesIds.begin(), speciesIds.end(), particle.pdgCode())) + 1;
954-
histos.fill(HIST("hGenMCdndpt"), mcCollision.posZ(), multiplicity, particle.eta(), particle.pt(), pos);
955-
}
956-
}
957-
for (const auto& RecCol : RecCols) {
958-
if (!isEventSelected(RecCol))
959-
continue;
960-
if (std::abs(RecCol.posZ()) >= cfgevtsel.cfgVtxCut)
961-
continue;
962-
if (cfgevtsel.isApplyBestCollIndex && RecCol.globalIndex() != mcCollision.bestCollisionIndex())
963-
continue;
964-
auto recTracksPart = RecTracks.sliceBy(perColMidtrack, RecCol.globalIndex());
965-
for (const auto& track : recTracksPart) {
966-
if (!track.isGlobalTrack())
967-
continue;
968-
if (!myTrackFilter.IsSelected(track))
969-
continue;
970-
if (!track.has_mcParticle())
971-
continue;
972-
auto particle = track.mcParticle();
973-
if (RecCol.mcCollisionId() != particle.mcCollisionId())
974-
continue;
975-
if (particle.isPhysicalPrimary()) {
976-
auto pos = std::distance(speciesIds.begin(), std::find(speciesIds.begin(), speciesIds.end(), particle.pdgCode())) + 1;
977-
histos.fill(HIST("hRecMCdndpt"), mcCollision.posZ(), multiplicity, particle.eta(), particle.pt(), pos);
978-
}
979-
}
980-
}
981-
}
982-
void processMFTtrackEff(ColMCTrueTable::iterator const& mcCollision, ColMCRecTable const& RecCols,
983-
TrksMCRecTable const& RecTracks, MftTrkMCRecTable const&,
984-
aod::BestCollisionsFwd3d const& reassoMftTracks, aod::McParticles const& mcparticles)
985-
{
986-
if (std::abs(mcCollision.posZ()) >= cfgevtsel.cfgVtxCut) {
987-
return;
988-
}
989-
auto multiplicity = 0;
990-
bool atLeastOne = false;
991-
for (const auto& RecCol : RecCols) {
992-
if (!isEventSelected(RecCol))
993-
continue;
994-
if (std::abs(RecCol.posZ()) >= cfgevtsel.cfgVtxCut)
995-
continue;
996-
if (cfgevtsel.isApplyBestCollIndex && RecCol.globalIndex() != mcCollision.bestCollisionIndex())
997-
continue;
998-
if (isUseCentEst) {
999-
multiplicity = selColCent(RecCol);
1000-
} else {
1001-
auto recTracksPart = RecTracks.sliceBy(perColMidtrack, RecCol.globalIndex());
1002-
multiplicity = countNTracks(recTracksPart);
1003-
}
1004-
atLeastOne = true;
1005-
}
1006-
for (const auto& particle : mcparticles) {
1007-
if (!isGenPartSelected(particle) || particle.eta() > cfgmfttrksel.cfgMftEtaMax || particle.eta() < cfgmfttrksel.cfgMftEtaMin || particle.pt() < cfgmfttrksel.cfgMftPtCutMin || particle.pt() > cfgmfttrksel.cfgMftPtCutMax)
1008-
continue;
1009-
if (atLeastOne)
1010-
histos.fill(HIST("hGenMCdndpt"), mcCollision.posZ(), multiplicity, particle.eta(), particle.pt(), 1.0);
1011-
}
1012-
for (const auto& RecCol : RecCols) {
1013-
if (!isEventSelected(RecCol))
1014-
continue;
1015-
if (std::abs(RecCol.posZ()) >= cfgevtsel.cfgVtxCut)
1016-
continue;
1017-
if (cfgevtsel.isApplyBestCollIndex && RecCol.globalIndex() != mcCollision.bestCollisionIndex())
1018-
continue;
1019-
1020-
auto recTracksPart = reassoMftTracks.sliceBy(perColMftTrack, RecCol.globalIndex());
1021-
for (const auto& reassoMftTrack : recTracksPart) {
1022-
if (!isMftBestTrackSelected(reassoMftTrack))
1023-
continue;
1024-
auto track = reassoMftTrack.mfttrack_as<MftTrkMCRecTable>();
1025-
if (!isMftTrackSelected(track)) {
1026-
continue;
1027-
}
1028-
if (cfgmfttrksel.cfgRequireCA && !track.isCA()) {
1029-
continue;
1030-
}
1031-
if (cfgmfttrksel.cfgRequireLTF && track.isCA()) {
1032-
continue;
1033-
}
1034-
if (!track.has_mcParticle())
1035-
continue;
1036-
auto particle = track.mcParticle();
1037-
if (RecCol.mcCollisionId() != particle.mcCollisionId())
1038-
continue;
1039-
if (particle.isPhysicalPrimary())
1040-
histos.fill(HIST("hRecMCdndpt"), mcCollision.posZ(), multiplicity, particle.eta(), particle.pt(), 1.0);
1041-
}
1042-
}
1043-
}
1044-
1045920
template <typename CheckGenPart>
1046921
bool isGenPartSelected(CheckGenPart const& particle)
1047922
{
@@ -1117,11 +992,15 @@ struct LongrangeMaker {
1117992
return false;
1118993
}
1119994
histos.fill(HIST("EventHist"), 14);
995+
if (std::abs(col.posZ()) >= cfgevtsel.cfgVtxCut) {
996+
return false;
997+
}
998+
histos.fill(HIST("EventHist"), 15);
1120999
return true;
11211000
}
11221001

11231002
template <typename countTrk>
1124-
int countNTracks(countTrk const& tracks)
1003+
int countNTracks(countTrk const& tracks, float vz)
11251004
{
11261005
auto nTrk = 0;
11271006
for (const auto& track : tracks) {
@@ -1132,7 +1011,10 @@ struct LongrangeMaker {
11321011
if (track.pt() < cfgtrksel.cfgPtCutMin || track.pt() > cfgtrksel.cfgPtCutMult) {
11331012
continue;
11341013
}
1135-
nTrk++;
1014+
float trkeff = 1.0f;
1015+
if (cfgtrksel.applyEffCorr)
1016+
trkeff = getTrkEffCorr(vz, track.eta(), track.pt());
1017+
nTrk += 1.0 / trkeff;
11361018
}
11371019
return nTrk;
11381020
}
@@ -1390,12 +1272,42 @@ struct LongrangeMaker {
13901272
return true;
13911273
}
13921274

1275+
void loadEffCorrection(uint64_t timestamp)
1276+
{
1277+
if (fLoadTrkEffCorr) {
1278+
return;
1279+
}
1280+
if (cfgtrksel.cfgEffccdbPath.value.empty() == false) {
1281+
hTrkEff = ccdb->getForTimeStamp<TH3D>(cfgtrksel.cfgEffccdbPath, timestamp);
1282+
if (hTrkEff == nullptr) {
1283+
LOGF(fatal, "Could not load efficiency histogram for trigger particles from %s", cfgtrksel.cfgEffccdbPath.value.c_str());
1284+
}
1285+
LOGF(info, "Loaded efficiency histogram from %s (%p)", cfgtrksel.cfgEffccdbPath.value.c_str(), (void*)hTrkEff);
1286+
}
1287+
fLoadTrkEffCorr = true;
1288+
}
1289+
1290+
float getTrkEffCorr(float posZ, float eta, float pt)
1291+
{
1292+
float eff = 1.;
1293+
if (hTrkEff) {
1294+
int zBin = hTrkEff->GetXaxis()->FindBin(posZ);
1295+
int etaBin = hTrkEff->GetYaxis()->FindBin(eta);
1296+
int ptBin = hTrkEff->GetZaxis()->FindBin(pt);
1297+
eff = hTrkEff->GetBinContent(zBin, etaBin, ptBin);
1298+
} else {
1299+
eff = 1.0;
1300+
}
1301+
if (eff < cfgtrksel.cfgLowEffCut)
1302+
eff = 1.0;
1303+
1304+
return eff;
1305+
}
1306+
13931307
PROCESS_SWITCH(LongrangeMaker, processData, "process All collisions", false);
13941308
PROCESS_SWITCH(LongrangeMaker, processUpc, "process UPC collisions", false);
13951309
PROCESS_SWITCH(LongrangeMaker, processMCGen, "process MC generated collisions", false);
13961310
PROCESS_SWITCH(LongrangeMaker, processMCRec, "process MC both gen and rec collisions", false);
1397-
PROCESS_SWITCH(LongrangeMaker, processTPCtrackEff, "process TPC track efficiency", false);
1398-
PROCESS_SWITCH(LongrangeMaker, processMFTtrackEff, "process MFT track efficiency", false);
13991311
};
14001312

14011313
WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)

0 commit comments

Comments
 (0)