Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
26 changes: 23 additions & 3 deletions PWGCF/DataModel/FemtoDerived.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2019-2025 CERN and copyright holders of ALICE O2.

Check failure on line 1 in PWGCF/DataModel/FemtoDerived.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.

Check failure on line 11 in PWGCF/DataModel/FemtoDerived.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/FemtoDerived.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/FemtoDerived.h

View workflow job for this annotation

GitHub Actions / O2 linter

[doc/file]

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

Expand Down Expand Up @@ -45,9 +45,9 @@

using BitMaskType = uint32_t; //! Definition of the data type for the collision masks

DECLARE_SOA_COLUMN(BitMaskTrackOne, bitmaskTrackOne, BitMaskType); //! Bit for track one

Check failure on line 48 in PWGCF/DataModel/FemtoDerived.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(BitMaskTrackTwo, bitmaskTrackTwo, BitMaskType); //! Bit for track two

Check failure on line 49 in PWGCF/DataModel/FemtoDerived.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(BitMaskTrackThree, bitmaskTrackThree, BitMaskType); //! Bit for track three

Check failure on line 50 in PWGCF/DataModel/FemtoDerived.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(Downsample, downsample, bool); //! Flag for downsampling
} // namespace femtodreamcollision
Expand Down Expand Up @@ -81,7 +81,7 @@

namespace mcfdcolllabel
{
DECLARE_SOA_INDEX_COLUMN(FDMCCollision, fdMCCollision); //! MC collision for femtodreamcollision

Check failure on line 84 in PWGCF/DataModel/FemtoDerived.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_TABLE_STAGED(FDMCCollLabels, "FDMCCollLabel", mcfdcolllabel::FDMCCollisionId);

Expand Down Expand Up @@ -122,13 +122,13 @@

static constexpr std::string_view TrackTypeName[kNTrackTypes] = {"Trk", "Pos", "Neg", "Bach"}; //! Naming of the different particle types

DECLARE_SOA_INDEX_COLUMN(FDCollision, fdCollision);

Check failure on line 125 in PWGCF/DataModel/FemtoDerived.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); //! p_T (GeV/c)
DECLARE_SOA_COLUMN(Eta, eta, float); //! Eta
DECLARE_SOA_COLUMN(Phi, phi, float); //! Phi
DECLARE_SOA_COLUMN(PartType, partType, uint8_t); //! Type of the particle, according to femtodreamparticle::ParticleType
DECLARE_SOA_COLUMN(Cut, cut, cutContainerType); //! Bit-wise container for the different selection criteria
DECLARE_SOA_COLUMN(PIDCut, pidcut, cutContainerType); //! Bit-wise container for the different PID selection criteria \todo since bit-masking cannot be done yet with filters we use a second field for the PID

Check failure on line 131 in PWGCF/DataModel/FemtoDerived.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(TempFitVar, tempFitVar, float); //! Observable for the template fitting (Track: DCA_xy, V0: CPA)
DECLARE_SOA_SELF_ARRAY_INDEX_COLUMN(Children, children); //! Field for the track indices to remove auto-correlations
DECLARE_SOA_COLUMN(MLambda, mLambda, float); //! The invariant mass of V0 candidate, assuming lambda
Expand Down Expand Up @@ -313,26 +313,46 @@
fdhf::Phi<fdhf::Prong0Pt, fdhf::Prong0Phi, fdhf::Prong0Eta, fdhf::Prong1Pt, fdhf::Prong1Phi, fdhf::Prong1Eta, fdhf::Prong2Pt, fdhf::Prong2Phi, fdhf::Prong2Eta>,
fdhf::Pt<fdhf::Prong0Pt, fdhf::Prong0Phi, fdhf::Prong0Eta, fdhf::Prong1Pt, fdhf::Prong1Phi, fdhf::Prong1Eta, fdhf::Prong2Pt, fdhf::Prong2Phi, fdhf::Prong2Eta>);

DECLARE_SOA_TABLE(FDHfPairs, "AOD", "FDHFPAIRS", //! table to store results for HF femtoscopy
fdhf::CharmM,
fdhf::CharmPt,
fdhf::TrkPt,
fdhf::BDTBkg,
fdhf::BDTPrompt,
fdhf::BDTFD,
fdhf::Kstar,
fdhf::KT,
fdhf::MT,
fdhf::Mult,
fdhf::MultPercentile,
fdhf::Charge,
fdhf::PairSign,
fdhf::ProcessType,
fdhf::FlagMc,
fdhf::OriginMcRec);

Comment on lines +316 to +333
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is this not part of a previous open PR?

Copy link
Collaborator Author

@zhangbiao-phy zhangbiao-phy Aug 6, 2025

Choose a reason for hiding this comment

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

Hi @victor-gonzalez, This was not part of the previous PR. But indeed, we had it in the very beginning (hald year ago), then later removed it because we wanted to separate charm candidates and tracks for the Lc baryon femtoscopy analysis.

Now, I restore it in this PR to make things more convenient for more abundant hf particles like Dplus mesons, where mixed-event processing can be done easily online. Sorry for the confusion, but this is what we want now.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I approve the PR as the explanation sounds reasonable.

DECLARE_SOA_TABLE(FDHfCharm, "AOD", "FDHFCHARM", //! table to store results for HF femtoscopy
fdhf::GIndexCol,
fdhf::TimeStamp,
fdhf::CharmM,
fdhf::CharmPt,
fdhf::CharmEta,
fdhf::CharmPhi,
fdhf::Prong0Id,
fdhf::Prong1Id,
fdhf::Prong2Id,
fdhf::Charge,
fdhf::BDTBkg,
fdhf::BDTPrompt,
fdhf::BDTFD,
fdhf::FlagMc,
fdhf::OriginMcRec);
fdhf::BDTFD);

DECLARE_SOA_TABLE(FDHfTrk, "AOD", "FDHFTRK", //! table to store results for HF femtoscopy
fdhf::GIndexCol,
fdhf::TimeStamp,
fdhf::TrkPt,
fdhf::TrkEta,
fdhf::TrkPhi,
fdhf::TrackId,
femtodreamparticle::Sign,
femtodreamparticle::TPCNClsFound,
track::TPCNClsFindable,
Expand Down
2 changes: 1 addition & 1 deletion PWGHF/HFC/TableProducer/femtoDreamProducer.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ struct HfFemtoDreamProducer {
Configurable<std::vector<float>> trkDCAxyMax{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kDCAxyMax, "trk"), std::vector<float>{0.1f, 3.5f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kDCAxyMax, "Track selection: ")};
Configurable<std::vector<float>> trkDCAzMax{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kDCAzMax, "trk"), std::vector<float>{0.2f, 3.5f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kDCAzMax, "Track selection: ")};
Configurable<std::vector<float>> trkEta{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kEtaMax, "trk"), std::vector<float>{0.8f, 0.7f, 0.9f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kEtaMax, "Track selection: ")};
Configurable<std::vector<int>> trkPIDspecies{"trkPIDspecies", std::vector<int>{o2::track::PID::Pion, o2::track::PID::Kaon, o2::track::PID::Proton}, "Trk sel: Particles species for PID"};
Configurable<std::vector<int>> trkPIDspecies{"trkPIDspecies", std::vector<int>{o2::track::PID::Pion, o2::track::PID::Kaon, o2::track::PID::Proton, o2::track::PID::Deuteron}, "Trk sel: Particles species for PID"};
Configurable<std::vector<float>> trkPIDnSigmaMax{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kPIDnSigmaMax, "trk"), std::vector<float>{3.5f, 3.f, 2.5f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kPIDnSigmaMax, "Track selection: ")};
Configurable<float> trkPIDnSigmaOffsetTPC{"trkPIDnSigmaOffsetTPC", 0., "Offset for TPC nSigma because of bad calibration"};
Configurable<float> trkPIDnSigmaOffsetTOF{"trkPIDnSigmaOffsetTOF", 0., "Offset for TOF nSigma because of bad calibration"};
Expand Down
157 changes: 119 additions & 38 deletions PWGHF/HFC/Tasks/taskCharmHadronsFemtoDream.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,17 @@ struct HfTaskCharmHadronsFemtoDream {
NegativeCharge = -1
};

enum PairSign {
PairNotDefined = 0,
LikeSignPair = 1,
UnLikeSignPair = 2
};

constexpr static int OriginRecPrompt = 1;
constexpr static int OriginRecFD = 2;
constexpr static int CutBitChargePositive = 2;

Produces<o2::aod::FDHfPairs> rowFemtoResultPairs;
Produces<o2::aod::FDHfCharm> rowFemtoResultCharm;
Produces<o2::aod::FDHfTrk> rowFemtoResultTrk;
Produces<o2::aod::FDHfColl> rowFemtoResultColl;
Expand Down Expand Up @@ -131,7 +139,7 @@ struct HfTaskCharmHadronsFemtoDream {
using FilteredCharmMcCands = soa::Filtered<soa::Join<aod::FDHfCand, aod::FDHfCandMC>>;
using FilteredCharmMcCand = FilteredCharmMcCands::iterator;

using FilteredColisions = soa::Filtered<soa::Join<FDCollisions, FDColMasks>>;
using FilteredColisions = soa::Filtered<soa::Join<FDCollisions, FDColMasks, aod::Collisions>>;
using FilteredColision = FilteredColisions::iterator;

using FilteredMcColisions = soa::Filtered<soa::Join<aod::FDCollisions, FDColMasks, aod::FDMCCollLabels>>;
Expand Down Expand Up @@ -294,7 +302,7 @@ struct HfTaskCharmHadronsFemtoDream {
void doSameEvent(PartitionType& sliceTrk1, CandType& sliceCharmHad, TableTracks const& parts, Collision const& col)
{
fillCollision(col);

processType = 1; // for same event
for (auto const& [p1, p2] : combinations(CombinationsFullIndexPolicy(sliceTrk1, sliceCharmHad))) {

if (p1.trackId() == p2.prong0Id() || p1.trackId() == p2.prong1Id() || p1.trackId() == p2.prong2Id())
Expand All @@ -310,15 +318,6 @@ struct HfTaskCharmHadronsFemtoDream {
continue;
}

constexpr int CutBitChargePositive = 2;
// proton track charge
float chargeTrack = 0.;
if ((p1.cut() & CutBitChargePositive) == CutBitChargePositive) {
chargeTrack = PositiveCharge;
} else {
chargeTrack = NegativeCharge;
}

float kstar = FemtoDreamMath::getkstar(p1, massOne, p2, massTwo);
if (kstar > highkstarCut) {
continue;
Expand All @@ -333,6 +332,21 @@ struct HfTaskCharmHadronsFemtoDream {
if (p2.pt() < charmHadMinPt || p2.pt() > charmHadMaxPt) {
continue;
}

// proton track charge
float chargeTrack = 0.;
if ((p1.cut() & CutBitChargePositive) == CutBitChargePositive) {
chargeTrack = PositiveCharge;
} else {
chargeTrack = NegativeCharge;
}
int pairSign = 0;
if (chargeTrack == p2.charge()) {
pairSign = LikeSignPair;
} else {
pairSign = UnLikeSignPair;
}

/// Filling QA histograms of the selected tracks
selectedTrackHisto.fillQA<isMc, true>(p1, static_cast<aod::femtodreamparticle::MomentumType>(confTempFitVarMomentum.value), col.multNtr(), col.multV0M());

Expand All @@ -343,47 +357,32 @@ struct HfTaskCharmHadronsFemtoDream {
originType = p2.originMcRec();
}

rowFemtoResultCharm(
col.globalIndex(),
p2.timeStamp(),
rowFemtoResultPairs(
invMass,
p2.pt(),
p2.eta(),
p2.phi(),
p2.charge(),
p1.pt(),
p2.bdtBkg(),
p2.bdtPrompt(),
p2.bdtFD(),
kstar,
FemtoDreamMath::getkT(p1, massOne, p2, massTwo),
FemtoDreamMath::getmT(p1, massOne, p2, massTwo),
col.multNtr(),
col.multV0M(),
p2.charge(),
pairSign,
processType,
charmHadMc,
originType);

rowFemtoResultTrk(
col.globalIndex(),
p2.timeStamp(),
p1.pt(),
p1.eta(),
p1.phi(),
chargeTrack,
p1.tpcNClsFound(),
p1.tpcNClsFindable(),
p1.tpcNClsCrossedRows(),
p1.tpcNSigmaPr(),
p1.tofNSigmaPr());

rowFemtoResultColl(
col.globalIndex(),
p2.timeStamp(),
col.posZ(),
col.multNtr());

sameEventCont.setPair<isMc, true>(p1, p2, col.multNtr(), col.multV0M(), use4D, extendedPlots, smearingByOrigin);
}
}

template <bool isMc, typename CollisionType, typename PartType, typename PartitionType1, typename PartitionType2, typename BinningType>
void doMixedEvent(CollisionType const& cols, PartType const& parts, PartitionType1& part1, PartitionType2& part2, BinningType policy)
{

processType = 2; // for mixed event
// Mixed events that contain the pair of interest
Partition<CollisionType> partitionMaskedCol1 = (aod::femtodreamcollision::bitmaskTrackOne & bitMask) == bitMask;
partitionMaskedCol1.bindTable(cols);
Expand Down Expand Up @@ -427,8 +426,45 @@ struct HfTaskCharmHadronsFemtoDream {
if (p2.pt() < charmHadMinPt || p2.pt() > charmHadMaxPt) {
continue;
}
// proton track charge
float chargeTrack = 0.;
if ((p1.cut() & CutBitChargePositive) == CutBitChargePositive) {
chargeTrack = PositiveCharge;
} else {
chargeTrack = NegativeCharge;
}
int pairSign = 0;
if (chargeTrack == p2.charge()) {
pairSign = LikeSignPair;
} else {
pairSign = UnLikeSignPair;
}

int charmHadMc = 0;
int originType = 0;
if constexpr (isMc) {
charmHadMc = p2.flagMc();
originType = p2.originMcRec();
}

rowFemtoResultPairs(
invMass,
p2.pt(),
p1.pt(),
p2.bdtBkg(),
p2.bdtPrompt(),
p2.bdtFD(),
kstar,
FemtoDreamMath::getkT(p1, massOne, p2, massTwo),
FemtoDreamMath::getmT(p1, massOne, p2, massTwo),
collision1.multNtr(),
collision1.multV0M(),
p2.charge(),
pairSign,
processType,
charmHadMc,
originType);

// if constexpr (!isMc) mixedEventCont.setPair<isMc, true>(p1, p2, collision1.multNtr(), collision1.multV0M(), use4D, extendedPlots, smearingByOrigin);
mixedEventCont.setPair<isMc, true>(p1, p2, collision1.multNtr(), collision1.multV0M(), use4D, extendedPlots, smearingByOrigin);
}
}
Expand All @@ -441,15 +477,60 @@ struct HfTaskCharmHadronsFemtoDream {
eventHisto.fillQA(col);
auto sliceTrk1 = partitionTrk1->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache);
auto sliceCharmHad = partitionCharmHadron->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache);
auto bc = col.template bc_as<aod::BCsWithTimestamps>();
int64_t timeStamp = bc.timestamp();

/// Filling QA histograms of the all tracks and all charm hadrons before pairing
for (auto const& part : sliceTrk1) {
allTrackHisto.fillQA<false, true>(part, static_cast<aod::femtodreamparticle::MomentumType>(confTempFitVarMomentum.value), col.multNtr(), col.multV0M());

// proton track charge
float chargeTrack = 0.;
if ((part.cut() & CutBitChargePositive) == CutBitChargePositive) {
chargeTrack = PositiveCharge;
} else {
chargeTrack = NegativeCharge;
}

rowFemtoResultTrk(
col.globalIndex(),
timeStamp,
part.pt(),
part.eta(),
part.phi(),
part.trackId(),
chargeTrack,
part.tpcNClsFound(),
part.tpcNClsFindable(),
part.tpcNClsCrossedRows(),
part.tpcNSigmaPr(),
part.tofNSigmaPr());
}
for (auto const& part : sliceCharmHad) {
float invMass = getCharmHadronMass(part);
registryCharmHadronQa.fill(HIST("CharmHadronQA/hPtVsMass"), part.pt(), invMass);
rowFemtoResultCharm(
col.globalIndex(),
timeStamp,
invMass,
part.pt(),
part.eta(),
part.phi(),
part.prong0Id(),
part.prong1Id(),
part.prong2Id(),
part.charge(),
part.bdtBkg(),
part.bdtPrompt(),
part.bdtFD());
}

rowFemtoResultColl(
col.globalIndex(),
timeStamp,
col.posZ(),
col.multNtr());

if ((col.bitmaskTrackOne() & bitMask) != bitMask || (col.bitmaskTrackTwo() & bitMask) != bitMask) {
return;
}
Expand Down
Loading