Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions PWGCF/DataModel/CorrelationsDerived.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2019-2020 CERN and copyright holders of ALICE O2.

Check failure on line 1 in PWGCF/DataModel/CorrelationsDerived.h

View workflow job for this annotation

GitHub Actions / O2 linter

[doc/file]

Provide mandatory file documentation.
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
// All rights not expressly granted are reserved.
//
Expand All @@ -8,7 +8,7 @@
// In applying this license CERN does not waive the privileges and immunities
// granted to it by virtue of its status as an Intergovernmental Organization
// or submit itself to any jurisdiction.
#ifndef PWGCF_DATAMODEL_CORRELATIONSDERIVED_H_

Check failure on line 11 in PWGCF/DataModel/CorrelationsDerived.h

View workflow job for this annotation

GitHub Actions / O2 linter

[doc/file]

Documentation for \author is missing, incorrect or misplaced.

Check failure on line 11 in PWGCF/DataModel/CorrelationsDerived.h

View workflow job for this annotation

GitHub Actions / O2 linter

[doc/file]

Documentation for \brief is missing, incorrect or misplaced.

Check failure on line 11 in PWGCF/DataModel/CorrelationsDerived.h

View workflow job for this annotation

GitHub Actions / O2 linter

[doc/file]

Documentation for \file is missing, incorrect or misplaced.
#define PWGCF_DATAMODEL_CORRELATIONSDERIVED_H_

#include "Common/DataModel/Centrality.h"
Expand All @@ -31,7 +31,7 @@

namespace cfmcparticle
{
DECLARE_SOA_INDEX_COLUMN(CFMcCollision, cfMcCollision); //! Index to reduced MC collision

Check failure on line 34 in PWGCF/DataModel/CorrelationsDerived.h

View workflow job for this annotation

GitHub Actions / O2 linter

[name/o2-column]

Use UpperCamelCase for names of O2 columns and matching lowerCamelCase names for their getters.
DECLARE_SOA_COLUMN(Pt, pt, float); //! pT (GeV/c)
DECLARE_SOA_COLUMN(Eta, eta, float); //! Pseudorapidity
DECLARE_SOA_COLUMN(Phi, phi, float); //! Phi angle
Expand All @@ -48,7 +48,7 @@

namespace cfcollision
{
DECLARE_SOA_INDEX_COLUMN(CFMcCollision, cfMcCollision); //! Index to reduced MC collision

Check failure on line 51 in PWGCF/DataModel/CorrelationsDerived.h

View workflow job for this annotation

GitHub Actions / O2 linter

[name/o2-column]

Use UpperCamelCase for names of O2 columns and matching lowerCamelCase names for their getters.
DECLARE_SOA_COLUMN(Multiplicity, multiplicity, float); //! Centrality/multiplicity value
} // namespace cfcollision
DECLARE_SOA_TABLE(CFCollisions, "AOD", "CFCOLLISION", //! Reduced collision table
Expand All @@ -64,8 +64,8 @@

namespace cftrack
{
DECLARE_SOA_INDEX_COLUMN(CFCollision, cfCollision); //! Index to collision

Check failure on line 67 in PWGCF/DataModel/CorrelationsDerived.h

View workflow job for this annotation

GitHub Actions / O2 linter

[name/o2-column]

Use UpperCamelCase for names of O2 columns and matching lowerCamelCase names for their getters.
DECLARE_SOA_INDEX_COLUMN(CFMcParticle, cfMCParticle); //! Index to MC particle

Check failure on line 68 in PWGCF/DataModel/CorrelationsDerived.h

View workflow job for this annotation

GitHub Actions / O2 linter

[name/o2-column]

Use UpperCamelCase for names of O2 columns and matching lowerCamelCase names for their getters.
DECLARE_SOA_COLUMN(Pt, pt, float); //! pT (GeV/c)
DECLARE_SOA_COLUMN(Eta, eta, float); //! Pseudorapidity
DECLARE_SOA_COLUMN(Phi, phi, float); //! Phi angle
Expand Down Expand Up @@ -111,8 +111,8 @@

namespace cf2prongtrack
{
DECLARE_SOA_INDEX_COLUMN_FULL(CFTrackProng0, cfTrackProng0, int, CFTracks, "_0"); //! Index to prong 1 CFTrack

Check failure on line 114 in PWGCF/DataModel/CorrelationsDerived.h

View workflow job for this annotation

GitHub Actions / O2 linter

[name/o2-column]

Use UpperCamelCase for names of O2 columns and matching lowerCamelCase names for their getters.
DECLARE_SOA_INDEX_COLUMN_FULL(CFTrackProng1, cfTrackProng1, int, CFTracks, "_1"); //! Index to prong 2 CFTrack

Check failure on line 115 in PWGCF/DataModel/CorrelationsDerived.h

View workflow job for this annotation

GitHub Actions / O2 linter

[name/o2-column]

Use UpperCamelCase for names of O2 columns and matching lowerCamelCase names for their getters.
DECLARE_SOA_COLUMN(Pt, pt, float); //! pT (GeV/c)
DECLARE_SOA_COLUMN(Eta, eta, float); //! Pseudorapidity
DECLARE_SOA_COLUMN(Phi, phi, float); //! Phi angle
Expand All @@ -124,6 +124,10 @@
JPsiToEE,
JPsiToMuMu,
Generic2Prong,
PhiToKK,
K0stoPiPi,
LambdatoPPi,
AntiLambdatoPiP
};
} // namespace cf2prongtrack
DECLARE_SOA_TABLE(CF2ProngTracks, "AOD", "CF2PRONGTRACK", //! Reduced track table
Expand Down
328 changes: 324 additions & 4 deletions PWGCF/TableProducer/filter2Prong.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
#include "PWGHF/DataModel/CandidateReconstructionTables.h"
#include "PWGHF/DataModel/CandidateSelectionTables.h"

#include "Common/DataModel/PIDResponseITS.h"

#include "Framework/ASoAHelpers.h"
#include "Framework/AnalysisDataModel.h"
#include "Framework/AnalysisTask.h"
Expand Down Expand Up @@ -44,11 +46,61 @@
O2_DEFINE_CONFIGURABLE(cfgImPart2Mass, float, o2::constants::physics::MassKMinus, "Daughter particle 2 mass in GeV")
O2_DEFINE_CONFIGURABLE(cfgImPart1PID, int, o2::track::PID::Kaon, "PID of daughter particle 1 (O2 PID ID)")
O2_DEFINE_CONFIGURABLE(cfgImPart2PID, int, o2::track::PID::Kaon, "PID of daughter particle 2 (O2 PID ID)")
O2_DEFINE_CONFIGURABLE(cfgMomDepPID, bool, 1, "Use mommentum dependent PID for Phi meson")
O2_DEFINE_CONFIGURABLE(cfgImCutPt, float, 0.2f, "Minimal pT for candidates")
O2_DEFINE_CONFIGURABLE(cfgImMinInvMass, float, 0.95f, "Minimum invariant mass (GeV)")
O2_DEFINE_CONFIGURABLE(cfgImMaxInvMass, float, 1.07f, "Maximum invariant mass (GeV)")
O2_DEFINE_CONFIGURABLE(cfgImMinInvMass, float, 0.95f, "Minimum invariant mass for generic 2 prong")
O2_DEFINE_CONFIGURABLE(cfgImMaxInvMass, float, 1.07f, "Maximum invariant mass for generic 2 prong")
O2_DEFINE_CONFIGURABLE(cfgImSigmaFormula, std::string, "(z < 0.5 && x < 3.0) || (z >= 0.5 && x < 2.5 && y < 3.0)", "pT dependent daughter track sigma pass condition (x = TPC sigma, y = TOF sigma, z = pT)")
Comment thread
jaelpark marked this conversation as resolved.
Outdated

struct : ConfigurableGroup{
O2_DEFINE_CONFIGURABLE(DoV0, bool, true, "Store V0s information")
O2_DEFINE_CONFIGURABLE(tpcNClsCrossedRowsTrackMin, float, 70, "Minimum number of crossed rows in TPC")
O2_DEFINE_CONFIGURABLE(etaTrackMax, float, 0.8, "Maximum pseudorapidity")
O2_DEFINE_CONFIGURABLE(ptTrackMin, float, 0.1, "Minimum transverse momentum")
O2_DEFINE_CONFIGURABLE(minV0DCAPr, float, 0.1, "Min V0 proton DCA")
O2_DEFINE_CONFIGURABLE(minV0DCAPiLambda, float, 0.1, "Min V0 pion DCA for lambda")
O2_DEFINE_CONFIGURABLE(minV0DCAPiK0s, float, 0.1, "Min V0 pion DCA for K0s")
O2_DEFINE_CONFIGURABLE(daughPIDCuts, float, 4.0, "PID nsigma for V0s")
O2_DEFINE_CONFIGURABLE(massK0Min, float, 0.4, "Minimum mass for K0")
O2_DEFINE_CONFIGURABLE(massK0Max, float, 0.6, "Maximum mass for K0")
O2_DEFINE_CONFIGURABLE(massLambdaMin, float, 1.0, "Minimum mass for lambda")
O2_DEFINE_CONFIGURABLE(massLambdaMax, float, 1.3, "Maximum mass for lambda")
O2_DEFINE_CONFIGURABLE(radiusMaxLambda, float, 2.3, "Maximum decay radius (cm) for lambda")
O2_DEFINE_CONFIGURABLE(radiusMinLambda, float, 0.0, "Minimum decay radius (cm) for lambda")
O2_DEFINE_CONFIGURABLE(radiusMaxK0s, float, 2.3, "Maximum decay radius (cm) for K0s")
O2_DEFINE_CONFIGURABLE(radiusMinK0s, float, 0.0, "Minimum decay radius (cm) for K0s")
O2_DEFINE_CONFIGURABLE(cosPaMinLambda, float, 0.98, "Minimum cosine of pointing angle for lambda")
O2_DEFINE_CONFIGURABLE(cosPaMinK0s, float, 0.98, "Minimum cosine of pointing angle for K0s")
O2_DEFINE_CONFIGURABLE(dcaV0DaughtersMaxLambda, float, 0.2, "Maximum DCA among the V0 daughters (cm) for lambda")
O2_DEFINE_CONFIGURABLE(dcaV0DaughtersMaxK0s, float, 0.2, "Maximum DCA among the V0 daughters (cm) for K0s")
O2_DEFINE_CONFIGURABLE(qtArmenterosMinForK0s, float, 0.12, "Minimum Armenteros' qt for K0s")
O2_DEFINE_CONFIGURABLE(maxLambdaLifeTime, float, 30, "Maximum lambda lifetime (in cm)")
O2_DEFINE_CONFIGURABLE(maxK0sLifeTime, float, 30, "Maximum K0s lifetime (in cm)")
} grpV0;

Check failure on line 80 in PWGCF/TableProducer/filter2Prong.cxx

View workflow job for this annotation

GitHub Actions / PR formatting / whitespace

Trailing spaces

Remove the trailing spaces at the end of the line.
struct : ConfigurableGroup{
O2_DEFINE_CONFIGURABLE(DoPhi, bool, false, "Store Phi information")
O2_DEFINE_CONFIGURABLE(ImMinInvMassPhiMeson, float, 0.98f, "Minimum invariant mass Phi meson (GeV)")
O2_DEFINE_CONFIGURABLE(ImMaxInvMassPhiMeson, float, 1.07f, "Maximum invariant mass Phi meson (GeV)")
O2_DEFINE_CONFIGURABLE(ITSPIDSelection, bool, true, "PID ITS")
O2_DEFINE_CONFIGURABLE(ITSPIDPthreshold, float, 1.0, "Momentum threshold for ITS PID (GeV/c) (only used if ITSPIDSelection is true)")
O2_DEFINE_CONFIGURABLE(lowITSPIDNsigma, float, 3.0, "lower cut on PID nsigma for ITS")
O2_DEFINE_CONFIGURABLE(highITSPIDNsigma, float, 3.0, "higher cut on PID nsigma for ITS")
O2_DEFINE_CONFIGURABLE(ITSclusterPhiMeson, int, 5, "Minimum number of ITS cluster for phi meson track")
O2_DEFINE_CONFIGURABLE(TPCCrossedRowsPhiMeson, int, 80, "Minimum number of TPC Crossed Rows for phi meson track")
O2_DEFINE_CONFIGURABLE(cutDCAxyPhiMeson, float, 0.1, "Maximum DCAxy for phi meson track")
O2_DEFINE_CONFIGURABLE(cutDCAzPhiMeson, float, 0.1, "Maximum DCAz for phi meson track")
O2_DEFINE_CONFIGURABLE(cutEtaPhiMeson, float, 0.8, "Maximum eta for phi meson track")
O2_DEFINE_CONFIGURABLE(cutPTPhiMeson, float, 0.15, "Maximum pt for phi meson track")
O2_DEFINE_CONFIGURABLE(isDeepAngle, bool, true, "Flag for applying deep angle")
O2_DEFINE_CONFIGURABLE(deepAngle, float, 0.04, "Deep angle cut")
O2_DEFINE_CONFIGURABLE(nsigmaCutTPC, float, 2.5, "nsigma tpc")
O2_DEFINE_CONFIGURABLE(nsigmaCutTOF, float, 2.5, "nsigma tof")
O2_DEFINE_CONFIGURABLE(cutTOFBeta, float, 0.5, "TOF beta")
O2_DEFINE_CONFIGURABLE(confFakeKaonCut, float, 0.15, "Cut based on track from momentum difference")
O2_DEFINE_CONFIGURABLE(removefaketrack, bool, true, "Flag to remove fake kaon")
} grpPhi;

HfHelper hfHelper;
Produces<aod::CF2ProngTracks> output2ProngTracks;
Produces<aod::CF2ProngTrackmls> output2ProngTrackmls;
Expand All @@ -64,6 +116,9 @@
template <class T>
using HasMLProb = decltype(std::declval<T&>().mlProbD0());

using PIDTrack = soa::Join<aod::Tracks, aod::TracksExtra, aod::TrackSelection, aod::pidTPCPi, aod::pidTPCKa, aod::pidTPCPr, aod::pidTOFPi, aod::pidTOFKa, aod::pidTOFPr, aod::pidTOFbeta, aod::TracksDCA>;
using ResoV0s = aod::V0Datas;

std::unique_ptr<TFormula> sigmaFormula;

void init(InitContext&)
Expand Down Expand Up @@ -166,9 +221,166 @@
}
PROCESS_SWITCH(Filter2Prong, processMC, "Process MC 2-prong daughters", false);

template <typename T>
bool selectionTrack(const T& candidate)
{
if (candidate.isGlobalTrack() && candidate.isPVContributor() && candidate.itsNCls() >= grpPhi.ITSclusterPhiMeson && candidate.tpcNClsCrossedRows() > grpPhi.TPCCrossedRowsPhiMeson && std::abs(candidate.dcaXY()) <= grpPhi.cutDCAxyPhiMeson && std::abs(candidate.dcaZ()) <= grpPhi.cutDCAzPhiMeson && std::abs(candidate.eta()) <= grpPhi.cutEtaPhiMeson && candidate.pt() >= grpPhi.cutPTPhiMeson) {
return true;
}
return false;
}

template <typename T1, typename T2>
bool selectionPair(const T1& candidate1, const T2& candidate2)
{
double pt1, pt2, pz1, pz2, p1, p2, angle;
pt1 = candidate1.pt();
pt2 = candidate2.pt();
pz1 = candidate1.pz();
pz2 = candidate2.pz();
p1 = candidate1.p();
p2 = candidate2.p();
angle = TMath::ACos((pt1 * pt2 + pz1 * pz2) / (p1 * p2));
if (grpPhi.isDeepAngle && angle < grpPhi.deepAngle) {
return false;
}
return true;
}

template <typename T>
bool isFakeTrack(T const& track)
{
const auto pglobal = track.p();
const auto ptpc = track.tpcInnerParam();
if (TMath::Abs(pglobal - ptpc) > grpPhi.confFakeKaonCut) {
return true;
}
return false;
}

template <typename Collision, typename V0Cand>
bool isSelectedV0AsK0s(Collision const& collision, const V0Cand& v0)
Comment thread
jgrosseo marked this conversation as resolved.
{
const auto& posTrack = v0.template posTrack_as<PIDTrack>();
const auto& negTrack = v0.template negTrack_as<PIDTrack>();

float CtauK0s = v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassK0;

if (v0.mK0Short() < grpV0.massK0Min || v0.mK0Short() > grpV0.massK0Max) {
return false;
}
if ((v0.qtarm() / std::abs(v0.alpha())) < grpV0.qtArmenterosMinForK0s) {
return false;
}
if (v0.v0radius() > grpV0.radiusMaxK0s || v0.v0radius() < grpV0.radiusMinK0s) {
return false;
}
if (v0.v0cosPA() < grpV0.cosPaMinK0s) {
return false;
}
if (v0.dcaV0daughters() > grpV0.dcaV0DaughtersMaxK0s) {
return false;
}
if (std::abs(CtauK0s) > grpV0.maxK0sLifeTime) {
return false;
}
if (((std::abs(posTrack.tpcNSigmaPi()) > grpV0.daughPIDCuts) || (std::abs(negTrack.tpcNSigmaPi()) > grpV0.daughPIDCuts))) {
return false;
}
if ((TMath::Abs(v0.dcapostopv()) < grpV0.minV0DCAPiK0s || TMath::Abs(v0.dcanegtopv()) < grpV0.minV0DCAPiK0s)) {
return false;
}
return true;
}

template <typename Collision, typename V0Cand>
bool isSelectedV0AsLambda(Collision const& collision, const V0Cand& v0, int pid /*0: lambda, 1: antilambda*/)
Comment thread
jaelpark marked this conversation as resolved.
Outdated
{
const auto& posTrack = v0.template posTrack_as<PIDTrack>();
const auto& negTrack = v0.template negTrack_as<PIDTrack>();

float CtauLambda = v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassLambda;

if ((v0.mLambda() < grpV0.massLambdaMin || v0.mLambda() > grpV0.massLambdaMax) &&
(v0.mAntiLambda() < grpV0.massLambdaMin || v0.mAntiLambda() > grpV0.massLambdaMax)) {
return false;
}
if (v0.v0radius() > grpV0.radiusMaxLambda || v0.v0radius() < grpV0.radiusMinLambda) {
return false;
}
if (v0.v0cosPA() < grpV0.cosPaMinLambda) {
return false;
}
if (v0.dcaV0daughters() > grpV0.dcaV0DaughtersMaxLambda) {
return false;
}
if (pid == 0 && (TMath::Abs(v0.dcapostopv()) < grpV0.minV0DCAPr || TMath::Abs(v0.dcanegtopv()) < grpV0.minV0DCAPiLambda)) {
return false;
}
if (pid == 1 && (TMath::Abs(v0.dcapostopv()) < grpV0.minV0DCAPiLambda || TMath::Abs(v0.dcanegtopv()) < grpV0.minV0DCAPr)) {
return false;
}
if (pid == 0 && ((std::abs(posTrack.tpcNSigmaPr()) > grpV0.daughPIDCuts) || (std::abs(negTrack.tpcNSigmaPi()) > grpV0.daughPIDCuts))) {
return false;
}
if (pid == 1 && ((std::abs(posTrack.tpcNSigmaPi()) > grpV0.daughPIDCuts) || (std::abs(negTrack.tpcNSigmaPr()) > grpV0.daughPIDCuts))) {
return false;
}
if (std::abs(CtauLambda) > grpV0.maxLambdaLifeTime) {
return false;
}
return true;
}

template <typename T1>
bool isV0TrackSelected(const T1& v0)
{
const auto& posTrack = v0.template posTrack_as<PIDTrack>();
const auto& negTrack = v0.template negTrack_as<PIDTrack>();

if (!posTrack.hasTPC() || !negTrack.hasTPC()) {
return false;
}
if (posTrack.tpcNClsCrossedRows() < grpV0.tpcNClsCrossedRowsTrackMin || negTrack.tpcNClsCrossedRows() < grpV0.tpcNClsCrossedRowsTrackMin) {
return false;
}
if (posTrack.tpcCrossedRowsOverFindableCls() < 0.8 || negTrack.tpcCrossedRowsOverFindableCls() < 0.8) {
return false;
}
if (std::abs(v0.positiveeta()) > grpV0.etaTrackMax || std::abs(v0.negativeeta()) > grpV0.etaTrackMax) {
return false;
}
if (v0.positivept() < grpV0.ptTrackMin || v0.negativept() < grpV0.ptTrackMin) {
return false;
}
return true;
}

template <typename T>
bool selectionPID(const T& candidate)
{
if (cfgMomDepPID) {
if (candidate.p() < 0.5) {
if (!candidate.hasTOF() && TMath::Abs(candidate.tpcNSigmaKa()) < grpPhi.nsigmaCutTPC) {
return true;
} else if (candidate.hasTOF() && TMath::Sqrt(candidate.tpcNSigmaKa() * candidate.tpcNSigmaKa() + candidate.tofNSigmaKa() * candidate.tofNSigmaKa()) < grpPhi.nsigmaCutTOF && candidate.beta() > grpPhi.cutTOFBeta) {
return true;
}
} else if (candidate.hasTOF() && TMath::Sqrt(candidate.tpcNSigmaKa() * candidate.tpcNSigmaKa() + candidate.tofNSigmaKa() * candidate.tofNSigmaKa()) < grpPhi.nsigmaCutTOF && candidate.beta() > grpPhi.cutTOFBeta) {
return true;
}
} else if (!cfgMomDepPID) {
Comment thread
jaelpark marked this conversation as resolved.
Outdated
if (!candidate.hasTOF() && TMath::Abs(candidate.tpcNSigmaKa()) < grpPhi.nsigmaCutTPC) {
return true;
} else if (candidate.hasTOF() && TMath::Sqrt(candidate.tpcNSigmaKa() * candidate.tpcNSigmaKa() + candidate.tofNSigmaKa() * candidate.tofNSigmaKa()) < grpPhi.nsigmaCutTOF && candidate.beta() > grpPhi.cutTOFBeta) {
return true;
}
}
return false;
}

// Generic 2-prong invariant mass method candidate finder. Only works for non-identical daughters of opposite charge for now.
using PIDTrack = soa::Join<aod::Tracks, aod::TracksExtra, aod::TrackSelection, aod::pidTPCPi, aod::pidTPCKa, aod::pidTPCPr, aod::pidTOFPi, aod::pidTOFKa, aod::pidTOFPr>;
void processDataInvMass(aod::Collisions::iterator const&, aod::BCsWithTimestamps const&, aod::CFCollRefs const& cfcollisions, aod::CFTrackRefs const& cftracks, PIDTrack const& tracks)
void processDataInvMass(aod::Collisions::iterator const&, aod::BCsWithTimestamps const&, aod::CFCollRefs const& cfcollisions, aod::CFTrackRefs const& cftracks, Filter2Prong::PIDTrack const& tracks)
{
if (cfcollisions.size() <= 0 || cftracks.size() <= 0)
return; // rejected collision
Expand Down Expand Up @@ -199,6 +411,114 @@
}
}
PROCESS_SWITCH(Filter2Prong, processDataInvMass, "Process data generic 2-prong candidates with invariant mass method", false);

// Phi and V0s invariant mass method candidate finder. Only works for non-identical daughters of opposite charge for now.
void processDataPhiV0(aod::Collisions::iterator const& collision, aod::BCsWithTimestamps const&, aod::CFCollRefs const& cfcollisions, aod::CFTrackRefs const& cftracks, Filter2Prong::PIDTrack const& tracks, aod::V0Datas const& V0s)
{
if (cfcollisions.size() <= 0 || cftracks.size() <= 0)
return; // rejected collision

o2::aod::ITSResponse itsResponse;

if (grpPhi.DoPhi) { // Process Phi mesons
for (const auto& cftrack1 : cftracks) { // Loop over first track
const auto& p1 = tracks.iteratorAt(cftrack1.trackId() - tracks.begin().globalIndex());
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why don't we use?

Suggested change
const auto& p1 = tracks.iteratorAt(cftrack1.trackId() - tracks.begin().globalIndex());
const auto& p1 = cftrack1.track();

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure this can be done straightforwardly. As far as I understood, cftrack1 only contains the global track and collision indexes, while the physics information are stored in the CFTracks (which however do not contain global index information, but only cf-index ones) and PIDTrack tables. We might need to modify the tables in order to have both the physics and global index information to do it more efficiently than how it is currently done. What do you think?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I disagree with your statement (Track in CFTrack is an index to the global track to my understanding) but I don't want to delay this PR. We can try it together one of these days.

if (p1.sign() != 1) {
continue;
}
if (!selectionTrack(p1)) {
continue;
}
if (grpPhi.ITSPIDSelection && p1.p() < grpPhi.ITSPIDPthreshold.value && !(itsResponse.nSigmaITS<o2::track::PID::Kaon>(p1) > grpPhi.lowITSPIDNsigma.value && itsResponse.nSigmaITS<o2::track::PID::Kaon>(p1) < grpPhi.highITSPIDNsigma.value)) { // Check ITS PID condition
continue;
}
if (!selectionPID(p1)) {
continue;
}
if (grpPhi.removefaketrack && isFakeTrack(p1)) { // Check if the track is a fake kaon
continue;
}

for (const auto& cftrack2 : cftracks) { // Loop over second track
if (cftrack2.globalIndex() == cftrack1.globalIndex()) // Skip if it's the same track as the first one
continue;

const auto& p2 = tracks.iteratorAt(cftrack2.trackId() - tracks.begin().globalIndex());
if (p2.sign() != -1) {
continue;
}
if (!selectionTrack(p2)) {
continue;
}
if (!selectionPID(p2)) {
continue;
}
if (grpPhi.ITSPIDSelection && p2.p() < grpPhi.ITSPIDPthreshold.value && !(itsResponse.nSigmaITS<o2::track::PID::Kaon>(p2) > grpPhi.lowITSPIDNsigma.value && itsResponse.nSigmaITS<o2::track::PID::Kaon>(p2) < grpPhi.highITSPIDNsigma.value)) { // Check ITS PID condition
continue;
}
if (grpPhi.removefaketrack && isFakeTrack(p2)) { // Check if the track is a fake kaon
continue;
}
if (!selectionPair(p1, p2)) {
continue;
}

ROOT::Math::PtEtaPhiMVector vec1(p1.pt(), p1.eta(), p1.phi(), cfgImPart1Mass);
ROOT::Math::PtEtaPhiMVector vec2(p2.pt(), p2.eta(), p2.phi(), cfgImPart2Mass);
ROOT::Math::PtEtaPhiMVector s = vec1 + vec2;
if (s.M() < grpPhi.ImMinInvMassPhiMeson || s.M() > grpPhi.ImMaxInvMassPhiMeson) {
continue;
}
float phi = RecoDecay::constrainAngle(s.Phi(), 0.0f);
output2ProngTracks(cfcollisions.begin().globalIndex(),
cftrack1.globalIndex(), cftrack2.globalIndex(), s.pt(), s.eta(), phi, s.M(), aod::cf2prongtrack::PhiToKK);
} // end of loop over second track
} // end of loop over first track
} // end of processing Phi mesons

if (grpV0.DoV0) { // Process V0 candidates (K0s, Lambdas, Anti-Lambdas)
Comment thread
jaelpark marked this conversation as resolved.
Outdated
for (const auto& v0 : V0s) { // Loop over V0 candidates
if (!isV0TrackSelected(v0)) { // Quality selection for V0 prongs
continue;
}

const auto& posTrack = v0.template posTrack_as<PIDTrack>();
const auto& negTrack = v0.template negTrack_as<PIDTrack>();

auto v0Type = 0;
double massV0 = 0.0;

// K0s
if (isSelectedV0AsK0s(collision, v0)) { // candidate is K0s
SETBIT(v0Type, aod::cf2prongtrack::K0stoPiPi);

output2ProngTracks(cfcollisions.begin().globalIndex(),
posTrack.globalIndex(), negTrack.globalIndex(),
v0.pt(), v0.eta(), v0.phi(), v0.mK0Short(), v0Type);
}

// Lambda and Anti-Lambda
bool LambdaTag = isSelectedV0AsLambda(collision, v0, 0);
bool aLambdaTag = isSelectedV0AsLambda(collision, v0, 1);

// Note: candidate compatible with Lambda and Anti-Lambda hypothesis are counted twice (once for each hypothesis)
if (LambdaTag) { // candidate is Lambda
SETBIT(v0Type, aod::cf2prongtrack::LambdatoPPi);
massV0 = v0.mLambda();
output2ProngTracks(cfcollisions.begin().globalIndex(), posTrack.globalIndex(), negTrack.globalIndex(),
v0.pt(), v0.eta(), v0.phi(), massV0, v0Type);
Comment thread
jgrosseo marked this conversation as resolved.
Outdated
}
if (aLambdaTag) { // candidate is Anti-lambda
SETBIT(v0Type, aod::cf2prongtrack::AntiLambdatoPiP);
massV0 = v0.mAntiLambda();
output2ProngTracks(cfcollisions.begin().globalIndex(), posTrack.globalIndex(), negTrack.globalIndex(),
v0.pt(), v0.eta(), v0.phi(), massV0, v0Type);
} // end of Lambda and Anti-Lambda processing
} // end of loop over V0 candidates
} // end of processing V0 candidates
}
PROCESS_SWITCH(Filter2Prong, processDataPhiV0, "Process data PhiV0 candidates with invariant mass method", false);

}; // struct

WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)
Expand Down
Loading
Loading