Skip to content

Commit

Permalink
PWGLF: Add QA and THnSparses for correlation (AliceO2Group#3485)
Browse files Browse the repository at this point in the history
* add QA and THnSparses for correlation
also fix naming of trigger and assoc

* Please consider the following formatting changes (#6)

* add V_z

---------

Co-authored-by: ALICE Builder <[email protected]>
  • Loading branch information
rspijkers and alibuild authored Sep 25, 2023
1 parent ca17548 commit 124dd23
Showing 1 changed file with 109 additions and 46 deletions.
155 changes: 109 additions & 46 deletions PWGLF/Tasks/cascadecorrelations.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ using FullTracksExtWithPID = soa::Join<aod::Tracks, aod::TracksExtra, aod::Track
using FullTracksExtIUWithPID = soa::Join<aod::TracksIU, aod::TracksExtra, aod::TracksCovIU, aod::TracksDCA, aod::pidTPCPi, aod::pidTPCKa, aod::pidTPCPr>;

// Add a column to the cascdataext table: IsSelected.
// 0 = not selected, 1 = Xi, 2 = Omega
// 0 = not selected, 1 = Xi, 2 = Omega, 3 = both
namespace o2::aod
{
namespace cascadeflags
Expand All @@ -68,14 +68,6 @@ using CascDataExtSelected = soa::Join<CascDataExt, CascadeFlags>;
struct cascadeSelector {
Produces<aod::CascadeFlags> cascflags;

// histo's
HistogramRegistry registry{
"registry",
{
{"hMassXiMinus", "hMassXiMinus", {HistType::kTH1F, {{3000, 0.0f, 3.0f, "Inv. Mass (GeV/c^{2})"}}}},
},
};

// Configurables
Configurable<float> tpcNsigmaBachelor{"tpcNsigmaBachelor", 3, "TPC NSigma bachelor (>10 is no cut)"};
Configurable<float> tpcNsigmaProton{"tpcNsigmaProton", 3, "TPC NSigma proton <- lambda (>10 is no cut)"};
Expand All @@ -91,6 +83,8 @@ struct cascadeSelector {
}
auto v0data = v0.v0Data();

// TODO: inv mass selection, other cuts.

// Let's try to do some PID
// these are the tracks:
auto bachTrack = casc.bachelor_as<FullTracksExtIUWithPID>();
Expand Down Expand Up @@ -125,8 +119,8 @@ struct cascadeSelector {
// Bachelor check
if (TMath::Abs(bachTrack.tpcNSigmaPi()) < tpcNsigmaBachelor) {
if (TMath::Abs(bachTrack.tpcNSigmaKa()) < tpcNsigmaBachelor) {
// TODO: ambiguous! ignore for now
cascflags(0);
// consistent with both!
cascflags(3);
continue;
}
cascflags(1);
Expand All @@ -142,20 +136,50 @@ struct cascadeSelector {
}; // struct

struct cascadeCorrelations {
AxisSpec invMassAxis = {3000, 0.0f, 3.0f, "Inv. Mass (GeV/c^{2})"};
AxisSpec deltaPhiAxis = {100, -PI / 2, 1.5 * PI, "#Delta#varphi"};
AxisSpec deltaEtaAxis = {40, -2, 2, "#Delta#eta"};
AxisSpec ptAxis = {200, 0, 15, "#it{p}_{T}"};
AxisSpec selectionFlagAxis = {4, -0.05f, 3.5f, "Selection flag of casc candidate"};
AxisSpec vertexAxis = {1000, -10.0f, 10.0f, "cm"};

HistogramRegistry registry{
"registry",
{
{"hMassXiMinus", "hMassXiMinus", {HistType::kTH1F, {{3000, 0.0f, 3.0f, "Inv. Mass (GeV/c^{2})"}}}},
{"hMassXiPlus", "hMassXiPlus", {HistType::kTH1F, {{3000, 0.0f, 3.0f, "Inv. Mass (GeV/c^{2})"}}}},
{"hMassOmegaMinus", "hMassOmegaMinus", {HistType::kTH1F, {{3000, 0.0f, 3.0f, "Inv. Mass (GeV/c^{2})"}}}},
{"hMassOmegaPlus", "hMassOmegaPlus", {HistType::kTH1F, {{3000, 0.0f, 3.0f, "Inv. Mass (GeV/c^{2})"}}}},
// inv mass
{"hMassXiMinus", "hMassXiMinus", {HistType::kTH2F, {invMassAxis, ptAxis}}},
{"hMassXiPlus", "hMassXiPlus", {HistType::kTH2F, {invMassAxis, ptAxis}}},
{"hMassOmegaMinus", "hMassOmegaMinus", {HistType::kTH2F, {invMassAxis, ptAxis}}},
{"hMassOmegaPlus", "hMassOmegaPlus", {HistType::kTH2F, {invMassAxis, ptAxis}}},

// basic selection variables
{"hV0Radius", "hV0Radius", {HistType::kTH1F, {{1000, 0.0f, 100.0f, "cm"}}}},
{"hCascRadius", "hCascRadius", {HistType::kTH1F, {{1000, 0.0f, 100.0f, "cm"}}}},
{"hV0CosPA", "hV0CosPA", {HistType::kTH1F, {{1000, 0.95f, 1.0f}}}},
{"hCascCosPA", "hCascCosPA", {HistType::kTH1F, {{1000, 0.95f, 1.0f}}}},
{"hDCAPosToPV", "hDCAPosToPV", {HistType::kTH1F, {vertexAxis}}},
{"hDCANegToPV", "hDCANegToPV", {HistType::kTH1F, {vertexAxis}}},
{"hDCABachToPV", "hDCABachToPV", {HistType::kTH1F, {vertexAxis}}},
{"hDCAV0ToPV", "hDCAV0ToPV", {HistType::kTH1F, {vertexAxis}}},
{"hDCAV0Dau", "hDCAV0Dau", {HistType::kTH1F, {{1000, 0.0f, 10.0f, "cm^{2}"}}}},
{"hDCACascDau", "hDCACascDau", {HistType::kTH1F, {{1000, 0.0f, 10.0f, "cm^{2}"}}}},
{"hLambdaMass", "hLambdaMass", {HistType::kTH1F, {{1000, 0.0f, 10.0f, "Inv. Mass (GeV/c^{2})"}}}},

{"hSelectionFlag", "hSelectionFlag", {HistType::kTH1I, {selectionFlagAxis}}},
{"hAutoCorrelation", "hAutoCorrelation", {HistType::kTH1I, {{4, -0.05f, 3.5f, "Types of autocorrelation"}}}},
{"hPhi", "hPhi", {HistType::kTH1F, {{100, 0, 2 * PI, "#varphi"}}}},
{"hDeltaPhiSS", "hDeltaPhiSS", {HistType::kTH1F, {{100, -PI / 2, 1.5 * PI, "#Delta#varphi"}}}},
{"hDeltaPhiOS", "hDeltaPhiOS", {HistType::kTH1F, {{100, -PI / 2, 1.5 * PI, "#Delta#varphi"}}}},
{"hEta", "hEta", {HistType::kTH1F, {{100, -2, 2, "#eta"}}}},

// correlation histos
{"hDeltaPhiSS", "hDeltaPhiSS", {HistType::kTH1F, {deltaPhiAxis}}},
{"hDeltaPhiOS", "hDeltaPhiOS", {HistType::kTH1F, {deltaPhiAxis}}},
// THnSparses containing all relevant dimensions, to be extended with e.g. multiplicity
{"hSparseOS", "hSparseOS", {HistType::kTHnSparseF, {deltaPhiAxis, deltaEtaAxis, ptAxis, ptAxis, selectionFlagAxis, selectionFlagAxis, vertexAxis}}},
{"hSparseSS", "hSparseSS", {HistType::kTHnSparseF, {deltaPhiAxis, deltaEtaAxis, ptAxis, ptAxis, selectionFlagAxis, selectionFlagAxis, vertexAxis}}},
},
};

Filter Selector = aod::cascadeflags::isSelected > 0; // TODO: treat Omega's and Xi's differently
Filter Selector = aod::cascadeflags::isSelected > 0;

void process(soa::Join<aod::Collisions, aod::EvSels>::iterator const& collision, soa::Filtered<aod::CascDataExtSelected> const& Cascades, aod::V0sLinked const&, aod::V0Datas const&, FullTracksExtIU const&)
{
Expand All @@ -167,63 +191,102 @@ struct cascadeCorrelations {
continue; // reject if no v0data
}

if (casc.sign() < 0) { // FIXME: could be done better...
registry.fill(HIST("hMassXiMinus"), casc.mXi());
registry.fill(HIST("hMassOmegaMinus"), casc.mOmega());
} else {
registry.fill(HIST("hMassXiPlus"), casc.mXi());
registry.fill(HIST("hMassOmegaPlus"), casc.mOmega());
if (casc.isSelected() != 2) { // not exclusively an Omega --> consistent with Xi or both
if (casc.sign() < 0) {
registry.fill(HIST("hMassXiMinus"), casc.mXi(), casc.pt());
} else {
registry.fill(HIST("hMassXiPlus"), casc.mXi(), casc.pt());
}
}
if (casc.isSelected() >= 2) { // consistent with Omega or both
if (casc.sign() < 0) {
registry.fill(HIST("hMassOmegaMinus"), casc.mOmega(), casc.pt());
} else {
registry.fill(HIST("hMassOmegaPlus"), casc.mOmega(), casc.pt());
}
}
registry.fill(HIST("hV0Radius"), casc.v0radius());
registry.fill(HIST("hCascRadius"), casc.cascradius());
registry.fill(HIST("hV0CosPA"), casc.v0cosPA(collision.posX(), collision.posY(), collision.posZ()));
registry.fill(HIST("hCascCosPA"), casc.casccosPA(collision.posX(), collision.posY(), collision.posZ()));
registry.fill(HIST("hDCAPosToPV"), casc.dcapostopv());
registry.fill(HIST("hDCANegToPV"), casc.dcanegtopv());
registry.fill(HIST("hDCABachToPV"), casc.dcabachtopv());
registry.fill(HIST("hDCAV0ToPV"), casc.dcav0topv(collision.posX(), collision.posY(), collision.posZ()));
registry.fill(HIST("hDCAV0Dau"), casc.dcaV0daughters());
registry.fill(HIST("hDCACascDau"), casc.dcacascdaughters());
registry.fill(HIST("hLambdaMass"), casc.mLambda());

registry.fill(HIST("hSelectionFlag"), casc.isSelected());
registry.fill(HIST("hPhi"), casc.phi());
registry.fill(HIST("hEta"), casc.eta());
} // casc loop

for (auto& [c0, c1] : combinations(Cascades, Cascades)) { // combinations automatically applies strictly upper in case of 2 identical tables
auto lambda0 = c0.v0_as<o2::aod::V0sLinked>();
auto lambda1 = c1.v0_as<o2::aod::V0sLinked>();
if (!(lambda0.has_v0Data()) || !(lambda1.has_v0Data())) {
// Define the trigger as the particle with the highest pT. As we can't swap the cascade tables themselves, we swap the addresses and later dereference them
auto* triggerAddress = &c0;
auto* assocAddress = &c1;
if (assocAddress->pt() > triggerAddress->pt()) {
std::swap(triggerAddress, assocAddress);
}
auto trigger = *triggerAddress;
auto assoc = *assocAddress;

auto lambdaTrigg = trigger.v0_as<o2::aod::V0sLinked>();
auto lambdaAssoc = assoc.v0_as<o2::aod::V0sLinked>();
if (!(lambdaTrigg.has_v0Data()) || !(lambdaAssoc.has_v0Data())) {
continue; // reject if no v0data in either of the lambda's
}
auto v0data0 = lambda0.v0Data();
auto v0data1 = lambda1.v0Data();
auto v0dataTrigg = lambdaTrigg.v0Data();
auto v0dataAssoc = lambdaAssoc.v0Data();

// calculate angular correlations
double deta = trigger.eta() - assoc.eta();
double dphi = RecoDecay::constrainAngle(trigger.phi() - assoc.phi(), -0.5 * PI);

double dphi = RecoDecay::constrainAngle(c0.phi() - c1.phi(), -0.5 * PI);
if (c0.sign() * c1.sign() < 0) { // opposite-sign
// Fill the correct histograms based on same-sign or opposite-sign
if (trigger.sign() * assoc.sign() < 0) { // opposite-sign
registry.fill(HIST("hDeltaPhiOS"), dphi);
registry.fill(HIST("hSparseOS"), dphi, deta, trigger.pt(), assoc.pt(), trigger.isSelected(), assoc.isSelected(), collision.posZ());
} else { // same-sign
// make sure to check for autocorrelations - only possible in same-sign correlations
// TODO: make QA histo to quantify autocorrelations
if (v0data0.v0Id() == v0data1.v0Id()) {
// LOGF(info, "same v0 in SS correlation! %d %d", v0data0.v0Id(), v0data1.v0Id());
if (v0dataTrigg.v0Id() == v0dataAssoc.v0Id()) {
// LOGF(info, "same v0 in SS correlation! %d %d", v0dataTrigg.v0Id(), v0dataAssoc.v0Id());
registry.fill(HIST("hAutoCorrelation"), 0);
continue;
}
int bachId0 = c0.bachelorId();
int bachId1 = c1.bachelorId();
int posId0 = v0data0.posTrackId();
int negId0 = v0data0.negTrackId();
int posId1 = v0data1.posTrackId();
int negId1 = v0data1.negTrackId();
if (bachId0 == bachId1) {
// LOGF(info, "same bachelor in SS correlation! %d %d", bachId0, bachId1);
int bachIdTrigg = trigger.bachelorId();
int bachIdAssoc = assoc.bachelorId();
int posIdTrigg = v0dataTrigg.posTrackId();
int negIdTrigg = v0dataTrigg.negTrackId();
int posIdAssoc = v0dataAssoc.posTrackId();
int negIdAssoc = v0dataAssoc.negTrackId();
if (bachIdTrigg == bachIdAssoc) {
// LOGF(info, "same bachelor in SS correlation! %d %d", bachIdTrigg, bachIdAssoc);
registry.fill(HIST("hAutoCorrelation"), 1);
continue;
}
// check for same tracks in v0's of cascades
if (negId0 == negId1 || posId0 == posId1) {
if (negIdTrigg == negIdAssoc || posIdTrigg == posIdAssoc) {
// LOGF(info, "cascades have a v0-track in common in SS correlation!");
registry.fill(HIST("hAutoCorrelation"), 2);
continue;
}
if (c0.sign() < 0) { // min cascade
if (negId0 == bachId1 || negId1 == bachId0) {
if (trigger.sign() < 0) { // neg cascade
if (negIdTrigg == bachIdAssoc || negIdAssoc == bachIdTrigg) {
// LOGF(info, "bach of casc == v0-pion of other casc in neg SS correlation!");
registry.fill(HIST("hAutoCorrelation"), 3);
continue;
}
} else { // pos cascade
if (posId0 == bachId1 || posId1 == bachId0) {
if (posIdTrigg == bachIdAssoc || posIdAssoc == bachIdTrigg) {
// LOGF(info, "bach of casc == v0-pion of other casc in pos SS correlation!");
registry.fill(HIST("hAutoCorrelation"), 3);
continue;
}
}
registry.fill(HIST("hDeltaPhiSS"), dphi);
registry.fill(HIST("hSparseSS"), dphi, deta, trigger.pt(), assoc.pt(), trigger.isSelected(), assoc.isSelected(), collision.posZ());
}
} // correlations
} // process
Expand Down

0 comments on commit 124dd23

Please sign in to comment.