Skip to content

Commit 34aa3c0

Browse files
committed
adding track-to-collision reassociation to dalitz selection
1 parent 2bb996d commit 34aa3c0

1 file changed

Lines changed: 194 additions & 35 deletions

File tree

PWGDQ/Tasks/DalitzSelection.cxx

Lines changed: 194 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@
2424
#include "PWGDQ/Core/VarManager.h"
2525
#include "PWGDQ/DataModel/ReducedInfoTables.h"
2626

27+
#include "Common/DataModel/CollisionAssociationTables.h"
2728
#include "Common/DataModel/EventSelection.h"
2829
#include "Common/DataModel/PIDResponseTOF.h"
2930
#include "Common/DataModel/PIDResponseTPC.h"
30-
#include "Common/DataModel/TrackSelectionTables.h"
3131

3232
#include <CCDB/BasicCCDBManager.h>
3333
#include <DataFormatsParameters/GRPMagField.h>
@@ -60,20 +60,23 @@ using namespace o2::framework::expressions;
6060
using namespace o2::aod;
6161
using namespace o2::soa;
6262

63-
using MyEvents = soa::Join<aod::Collisions, aod::EvSels>;
63+
//using MyEvents = soa::Join<aod::Collisions, aod::EvSels>
64+
using MyEventsWithCent = soa::Join<aod::Collisions, aod::EvSels, aod::CentFT0Cs, aod::CentFT0As, aod::CentFT0Ms>;
6465

65-
using MyBarrelTracks = soa::Join<aod::Tracks, aod::TracksExtra, aod::TrackSelection, aod::TracksDCA,
66+
using MyBarrelTracks = soa::Join<aod::Tracks, aod::TracksExtra, aod::TracksDCA,
6667
aod::pidTPCFullEl, aod::pidTPCFullPi, aod::pidTPCFullMu,
6768
aod::pidTPCFullKa, aod::pidTPCFullPr,
6869
aod::pidTOFFullEl, aod::pidTOFFullPi, aod::pidTOFFullMu,
6970
aod::pidTOFFullKa, aod::pidTOFFullPr, aod::pidTOFbeta>;
7071

71-
constexpr static uint32_t EventFillMap = VarManager::ObjTypes::Collision;
72-
constexpr static uint32_t TrackFillMap = VarManager::ObjTypes::Track | VarManager::ObjTypes::TrackExtra | VarManager::ObjTypes::TrackDCA | VarManager::ObjTypes::TrackSelection | VarManager::ObjTypes::TrackPID;
72+
//constexpr static uint32_t EventFillMap = VarManager::ObjTypes::Collision;
73+
constexpr static uint32_t EventFillMapWithCent = VarManager::ObjTypes::Collision| VarManager::ObjTypes::CollisionCent;
74+
constexpr static uint32_t TrackFillMap = VarManager::ObjTypes::Track | VarManager::ObjTypes::TrackExtra | VarManager::ObjTypes::TrackDCA | VarManager::ObjTypes::TrackPID;
7375

7476
struct DalitzSelection {
7577
Produces<o2::aod::DalitzBits> dalitzbits;
7678
Preslice<MyBarrelTracks> perCollision = aod::track::collisionId;
79+
Preslice<aod::TrackAssoc> trackIndicesPerCollision = aod::track_association::collisionId;
7780

7881
// Configurables
7982
// cuts
@@ -102,6 +105,7 @@ struct DalitzSelection {
102105
struct : ConfigurableGroup {
103106
Configurable<bool> fConfigEnableLikeSign{"cfgEnableLikeSign", false, "Whether or not also add like-sign pairs (for studying combinatorial background which might contain misID or non-primary electrons)"};
104107
Configurable<bool> fQA{"cfgQA", true, "QA histograms"};
108+
Configurable<bool> fRemoveDoubleCounting{"cfgRemoveDoubleCounting", true, "If a track/pair is selected for several collisions, we still count it only once"};
105109
// Configurables for TPC post-calibration maps
106110
Configurable<std::string> fConfigCcdbUrl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"};
107111
Configurable<std::string> fConfigCcdbPathTPC{"ccdb-path-tpc", "Users/i/iarsene/Calib/TPCpostCalib", "base path to the ccdb object"};
@@ -125,6 +129,11 @@ struct DalitzSelection {
125129
std::map<int, uint8_t> fTrackmapProbe; // whether it is selected with probe cut
126130
std::map<int, uint8_t> fDalitzmap; // whether it is selected as dalitz decay daughter with symmetric or tag cut
127131
std::map<int, uint8_t> fDalitzmapProbe; // whether it is selected as dalitz decay daughter with probe cut
132+
133+
// maps to remove ambiguities
134+
std::map<int, uint8_t> fDalitzmapAmbiguity;
135+
std::map<int, uint8_t> fDalitzmapProbeAmbiguity;
136+
std::map<std::pair<int, int>, uint8_t> fAmbiguousPairs;
128137

129138
AnalysisCompositeCut* fEventCut;
130139
std::vector<AnalysisCompositeCut> fTrackCuts;
@@ -295,13 +304,23 @@ struct DalitzSelection {
295304
fOutputList.setObject(fHistMan->GetMainHistogramList());
296305
}
297306

298-
template <uint32_t TTrackFillMap, typename TTracks>
299-
void runTrackSelection(TTracks const& tracksBarrel)
307+
template <bool isReassoc, uint32_t TTrackFillMap, typename TTracks, typename TEvent>
308+
void runTrackSelection(TTracks const& tracksBarrel, TEvent const& collision)
300309
{
301-
for (const auto& track : tracksBarrel) {
310+
for (const auto& track1 : tracksBarrel) {
302311
uint8_t filterMap = uint8_t(0);
303312
uint8_t filterMapProbe = uint8_t(0);
304-
VarManager::FillTrack<TTrackFillMap>(track);
313+
int fullTrackIdx = 0;
314+
if constexpr (isReassoc) {
315+
auto const& fullTrack = track1.template track_as<MyBarrelTracks>();
316+
VarManager::FillTrack<TTrackFillMap>(fullTrack);
317+
VarManager::FillTrackCollision<TTrackFillMap>(fullTrack, collision);
318+
fullTrackIdx = fullTrack.globalIndex();
319+
}
320+
else {
321+
VarManager::FillTrack<TTrackFillMap>(track1);
322+
fullTrackIdx = track1.globalIndex();
323+
}
305324
int i = 0;
306325
for (auto cut = fTrackCuts.begin(); cut != fTrackCuts.end(); ++cut, ++i) {
307326
if ((*cut).IsSelected(VarManager::fgValues)) {
@@ -317,35 +336,66 @@ struct DalitzSelection {
317336
}
318337
}
319338
if (filterMap) {
320-
fTrackmap[track.globalIndex()] = filterMap;
339+
fTrackmap[fullTrackIdx] = filterMap;
321340
}
322341
if (filterMapProbe) {
323-
fTrackmapProbe[track.globalIndex()] = filterMapProbe;
342+
fTrackmapProbe[fullTrackIdx] = filterMapProbe;
324343
}
325344
} // end loop over tracks
326345
}
327346

328-
template <int TPairType, uint32_t TTrackFillMap, typename TTracks>
329-
void runDalitzPairing(TTracks const& tracks1, TTracks const& tracks2)
347+
template <bool isReassoc, int TPairType, uint32_t TTrackFillMap, typename TTracks, typename TEvent>
348+
void runDalitzPairing(TTracks const& tracks1, TTracks const& tracks2, TEvent collision)
330349
{
350+
if (isReassoc & fConfigOptions.fRemoveDoubleCounting) {
351+
// keep track of selections from previous events to check if the track was already selected or not
352+
fDalitzmapAmbiguity = fDalitzmap;
353+
fDalitzmapProbeAmbiguity = fDalitzmapProbe;
354+
}
355+
331356
for (const auto& [track1, track2] : o2::soa::combinations(CombinationsFullIndexPolicy(tracks1, tracks2))) {
332-
if (track1.globalIndex() == track2.globalIndex()) {
357+
358+
int trackIdx1;
359+
int trackIdx2;
360+
bool isLikeSign;
361+
if constexpr (isReassoc) {
362+
auto const& fullTrack1 = track1.template track_as<MyBarrelTracks>();
363+
auto const& fullTrack2 = track2.template track_as<MyBarrelTracks>();
364+
trackIdx1 = fullTrack1.globalIndex();
365+
trackIdx2 = fullTrack2.globalIndex();
366+
isLikeSign = (fullTrack1.sign() * fullTrack2.sign() > 0);
367+
}
368+
else {
369+
trackIdx1 = track1.globalIndex();
370+
trackIdx2 = track2.globalIndex();
371+
isLikeSign = (track1.sign() * track2.sign() > 0);
372+
}
373+
374+
if (trackIdx1 == trackIdx2) {
333375
continue;
334376
}
335-
if (!fIsTagAndProbe && track1.globalIndex() >= track2.globalIndex()) {
377+
if (!fIsTagAndProbe && trackIdx1 >= trackIdx2) {
336378
continue;
337379
}
338-
if (!fConfigOptions.fConfigEnableLikeSign && (track1.sign() * track2.sign() > 0)) {
380+
if (!fConfigOptions.fConfigEnableLikeSign && isLikeSign) {
339381
continue;
340382
}
341383

342-
uint8_t twoTracksFilterMap = fTrackmap[track1.globalIndex()] & (fIsTagAndProbe ? fTrackmapProbe[track2.globalIndex()] : fTrackmap[track2.globalIndex()]);
384+
uint8_t twoTracksFilterMap = fTrackmap[trackIdx1] & (fIsTagAndProbe ? fTrackmapProbe[trackIdx2] : fTrackmap[trackIdx2]);
343385
if (!twoTracksFilterMap) {
344386
continue;
345387
}
346388

347389
// pairing
348-
VarManager::FillPair<TPairType, TTrackFillMap>(track1, track2);
390+
if constexpr (isReassoc) {
391+
auto const& fullTrack1 = track1.template track_as<MyBarrelTracks>();
392+
auto const& fullTrack2 = track2.template track_as<MyBarrelTracks>();
393+
VarManager::FillPair<TPairType, TTrackFillMap>(fullTrack1, fullTrack2);
394+
}
395+
else {
396+
VarManager::FillPair<TPairType, TTrackFillMap>(track1, track2);
397+
}
398+
349399

350400
// Fill pair selection map and fill pair histogram
351401
int icut = 0;
@@ -355,21 +405,35 @@ struct DalitzSelection {
355405
continue;
356406
}
357407
if ((*pairCut).IsSelected(VarManager::fgValues)) {
358-
if (track1.sign() * track2.sign() < 0) {
359-
fDalitzmap[track1.globalIndex()] |= (uint8_t(1) << icut);
408+
bool isPairAlreadySelected = false;
409+
if (isReassoc & fConfigOptions.fRemoveDoubleCounting) {
410+
// if we remove double counting and the pair is already selected, we don't fill the histograms
411+
std::pair<int, int> iPair(trackIdx1, trackIdx2);
412+
if (fAmbiguousPairs.find(iPair) != fAmbiguousPairs.end()) {
413+
if (fAmbiguousPairs[iPair] & (static_cast<uint8_t>(1) << icut)) { // if this pair is already stored with this cut
414+
isPairAlreadySelected = true;
415+
} else {
416+
fAmbiguousPairs[iPair] |= static_cast<uint8_t>(1) << icut;
417+
}
418+
} else {
419+
fAmbiguousPairs[iPair] = static_cast<uint8_t>(1) << icut;
420+
}
421+
}
422+
if (!isLikeSign) {
423+
fDalitzmap[trackIdx1] |= (uint8_t(1) << icut);
360424
if (fIsTagAndProbe) {
361-
fDalitzmapProbe[track2.globalIndex()] |= (uint8_t(1) << icut);
362-
if (fConfigOptions.fQA) {
425+
fDalitzmapProbe[trackIdx2] |= (uint8_t(1) << icut);
426+
if (fConfigOptions.fQA && !isPairAlreadySelected) {
363427
fHistMan->FillHistClass(Form("Pair_%s_%s_%s", (*trackCut).GetName(), fTrackCutsProbe.at(icut).GetName(), (*pairCut).GetName()), VarManager::fgValues);
364428
}
365429
} else {
366-
fDalitzmap[track2.globalIndex()] |= (uint8_t(1) << icut);
367-
if (fConfigOptions.fQA) {
430+
fDalitzmap[trackIdx2] |= (uint8_t(1) << icut);
431+
if (fConfigOptions.fQA && !isPairAlreadySelected) {
368432
fHistMan->FillHistClass(Form("Pair_%s_%s", (*trackCut).GetName(), (*pairCut).GetName()), VarManager::fgValues);
369433
}
370434
}
371435
} else {
372-
if (fConfigOptions.fQA) {
436+
if (fConfigOptions.fQA && !isPairAlreadySelected) {
373437
fHistMan->FillHistClass(fIsTagAndProbe ? Form("PairLS_%s_%s_%s", (*trackCut).GetName(), fTrackCutsProbe.at(icut).GetName(), (*pairCut).GetName()) : Form("PairLS_%s_%s", (*trackCut).GetName(), (*pairCut).GetName()), VarManager::fgValues);
374438
}
375439
} // end if like-sign
@@ -380,12 +444,38 @@ struct DalitzSelection {
380444
// Fill Hists
381445
if (fConfigOptions.fQA) {
382446
for (const auto& track : tracks1) {
383-
uint8_t filterMap = fDalitzmap[track.globalIndex()];
384-
uint8_t filterMapProbe = fDalitzmapProbe[track.globalIndex()];
385-
if (!filterMap && !filterMapProbe) {
386-
continue;
447+
uint8_t filterMap;
448+
uint8_t filterMapProbe;
449+
if constexpr (isReassoc) {
450+
auto const& fullTrack = track.template track_as<MyBarrelTracks>();
451+
filterMap = fDalitzmap[fullTrack.globalIndex()];
452+
filterMapProbe = fDalitzmapProbe[fullTrack.globalIndex()];
453+
if (fConfigOptions.fRemoveDoubleCounting) {
454+
// we remove track selections which were already selected before
455+
uint8_t previousFilterMap = fDalitzmapAmbiguity[fullTrack.globalIndex()];
456+
uint8_t previousFilterMapProbe = fDalitzmapProbeAmbiguity[fullTrack.globalIndex()];
457+
filterMap &= ~previousFilterMap;
458+
filterMapProbe &= ~previousFilterMapProbe;
459+
}
460+
461+
if (!filterMap && !filterMapProbe) {
462+
continue;
463+
}
464+
465+
VarManager::FillTrack<TTrackFillMap>(fullTrack);
466+
// The caveat here is that we only fill the DCA to the first selected collision
467+
VarManager::FillTrackCollision<TTrackFillMap>(fullTrack, collision);
468+
}
469+
else {
470+
filterMap = fDalitzmap[track.globalIndex()];
471+
filterMapProbe = fDalitzmapProbe[track.globalIndex()];
472+
473+
if (!filterMap && !filterMapProbe) {
474+
continue;
475+
}
476+
477+
VarManager::FillTrack<TTrackFillMap>(track);
387478
}
388-
VarManager::FillTrack<TTrackFillMap>(track);
389479

390480
int icut = 0;
391481
auto trackCut = fTrackCuts.begin();
@@ -403,7 +493,7 @@ struct DalitzSelection {
403493
}
404494
}
405495

406-
void processFullTracks(MyEvents const& collisions, aod::BCsWithTimestamps const&, soa::Filtered<MyBarrelTracks> const& filteredTracks, MyBarrelTracks const& tracks)
496+
void processFullTracks(MyEventsWithCent const& collisions, aod::BCsWithTimestamps const&, soa::Filtered<MyBarrelTracks> const& filteredTracks, MyBarrelTracks const& tracks)
407497
{
408498
const int pairType = VarManager::kDecayToEE;
409499
fDalitzmap.clear();
@@ -413,7 +503,7 @@ struct DalitzSelection {
413503
fTrackmap.clear();
414504
fTrackmapProbe.clear();
415505
VarManager::ResetValues(VarManager::kNRunWiseVariables, VarManager::kNBarrelTrackVariables);
416-
VarManager::FillEvent<EventFillMap>(collision);
506+
VarManager::FillEvent<EventFillMapWithCent>(collision);
417507
bool isEventSelected = fEventCut->IsSelected(VarManager::fgValues);
418508

419509
if (isEventSelected) {
@@ -456,20 +546,89 @@ struct DalitzSelection {
456546
}
457547

458548
auto groupedFilteredTracks = filteredTracks.sliceBy(perCollision, collision.globalIndex());
459-
runTrackSelection<TrackFillMap>(groupedFilteredTracks);
460-
runDalitzPairing<pairType, TrackFillMap>(groupedFilteredTracks, groupedFilteredTracks);
549+
runTrackSelection<false, TrackFillMap>(groupedFilteredTracks, nullptr);
550+
runDalitzPairing<false, pairType, TrackFillMap>(groupedFilteredTracks, groupedFilteredTracks, nullptr);
551+
}
552+
}
553+
554+
for (const auto& track : tracks) { // Fill dalitz bits
555+
dalitzbits(fIsTagAndProbe ? fDalitzmapProbe[track.globalIndex()] : fDalitzmap[track.globalIndex()]);
556+
}
557+
}
558+
559+
void processFullTracksWithAssoc(MyEventsWithCent const& collisions, aod::BCsWithTimestamps const&, MyBarrelTracks const& tracks, TrackAssoc const& trackAssocs)
560+
{
561+
562+
const int pairType = VarManager::kDecayToEE;
563+
fDalitzmap.clear();
564+
fDalitzmapProbe.clear();
565+
fDalitzmapAmbiguity.clear();
566+
fDalitzmapProbeAmbiguity.clear();
567+
fAmbiguousPairs.clear();
568+
569+
for (const auto& collision : collisions) {
570+
fTrackmap.clear();
571+
fTrackmapProbe.clear();
572+
VarManager::ResetValues(VarManager::kNRunWiseVariables, VarManager::kNBarrelTrackVariables);
573+
VarManager::FillEvent<EventFillMapWithCent>(collision);
574+
bool isEventSelected = fEventCut->IsSelected(VarManager::fgValues);
575+
576+
if (isEventSelected) {
577+
578+
reinterpret_cast<TH1I*>(fStatsList->At(0))->Fill(0);
579+
580+
auto bc = collision.template bc_as<aod::BCsWithTimestamps>();
581+
582+
if (fCurrentRun != bc.runNumber()) {
583+
VarManager::ResetValues(0, VarManager::kNRunWiseVariables);
584+
585+
// We setup the magnetic field, because the conversion rejection cut might depend on it
586+
float magField = 0.;
587+
if (fConfigOptions.fUseRemoteField.value) {
588+
grpmag = fCCDB->getForTimeStamp<o2::parameters::GRPMagField>(fConfigOptions.grpmagPath, bc.timestamp());
589+
if (grpmag != nullptr) {
590+
magField = grpmag->getNominalL3Field();
591+
} else {
592+
LOGF(fatal, "GRP object is not available in CCDB at timestamp=%llu", bc.timestamp());
593+
}
594+
} else {
595+
magField = fConfigOptions.fConfigMagField.value;
596+
}
597+
LOGF(info, "setting mag field to %f", magField);
598+
if (magField == 0.) {
599+
LOGF(fatal, "magnetic field not set correctly, please check");
600+
}
601+
VarManager::SetMagneticField(magField);
602+
603+
if (fConfigOptions.fConfigComputeTPCpostCalib) {
604+
auto calibList = fCCDB->getForTimeStamp<TList>(fConfigOptions.fConfigCcdbPathTPC.value, bc.timestamp());
605+
VarManager::SetCalibrationObject(VarManager::kTPCElectronMean, calibList->FindObject("mean_map_electron"));
606+
VarManager::SetCalibrationObject(VarManager::kTPCElectronSigma, calibList->FindObject("sigma_map_electron"));
607+
VarManager::SetCalibrationObject(VarManager::kTPCPionMean, calibList->FindObject("mean_map_pion"));
608+
VarManager::SetCalibrationObject(VarManager::kTPCPionSigma, calibList->FindObject("sigma_map_pion"));
609+
VarManager::SetCalibrationObject(VarManager::kTPCProtonMean, calibList->FindObject("mean_map_proton"));
610+
VarManager::SetCalibrationObject(VarManager::kTPCProtonSigma, calibList->FindObject("sigma_map_proton"));
611+
}
612+
fCurrentRun = bc.runNumber();
613+
}
614+
615+
auto groupedTracksAssoc = trackAssocs.sliceBy(trackIndicesPerCollision, collision.globalIndex());
616+
runTrackSelection<true, TrackFillMap>(groupedTracksAssoc, collision);
617+
runDalitzPairing<true, pairType, TrackFillMap>(groupedTracksAssoc, groupedTracksAssoc, collision);
461618
}
462619
}
463620

464621
for (const auto& track : tracks) { // Fill dalitz bits
465622
dalitzbits(fIsTagAndProbe ? fDalitzmapProbe[track.globalIndex()] : fDalitzmap[track.globalIndex()]);
466623
}
624+
467625
}
468626

469-
void processDummy(MyEvents const&)
627+
void processDummy(MyEventsWithCent const&)
470628
{
471629
}
472630

631+
PROCESS_SWITCH(DalitzSelection, processFullTracksWithAssoc, "Run Dalitz selection on AO2D tables with reassociation", false);
473632
PROCESS_SWITCH(DalitzSelection, processFullTracks, "Run Dalitz selection on AO2D tables", false);
474633
PROCESS_SWITCH(DalitzSelection, processDummy, "Do nothing", false);
475634
};

0 commit comments

Comments
 (0)