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
85 changes: 40 additions & 45 deletions PWGLF/TableProducer/QC/nucleiQC.cxx
Comment thread
GiorgioAlbertoLucia marked this conversation as resolved.
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 PWGLF/TableProducer/QC/nucleiQC.cxx

View workflow job for this annotation

GitHub Actions / O2 linter

[name/workflow-file]

Name of a workflow file must match the name of the main struct in it (without the PWG prefix). (Class implementation files should be in "Core" directories.)
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
// All rights not expressly granted are reserved.
//
Expand Down Expand Up @@ -78,10 +78,11 @@
kNCrossedRowsCut = 5,
kTpcChi2Cut = 6,
kItsChi2Cut = 7,
kNtrackQuality = 8
kDcaCuts = 8,
kNtrackQuality = 9
};

std::array<std::string, trackQuality::kNtrackQuality> trackQualityLabels{"All", "#eta cut", "#it{p}_{TPC}^{min} cut", "#it{N}_{cls}^{ITS} cut", "#it{N}_{cls}^{TPC} cut", "Crossed rows cut", "#chi^{2}_{TPC} cut", "#chi^{2}_{ITS} cut"};
std::array<std::string, trackQuality::kNtrackQuality> trackQualityLabels{"All", "#eta cut", "#it{p}_{TPC}^{min} cut", "#it{N}_{cls}^{ITS} cut", "#it{N}_{cls}^{TPC} cut", "Crossed rows cut", "#chi^{2}_{TPC} cut", "#chi^{2}_{ITS} cut", "DCA cuts"};

} // namespace

Expand Down Expand Up @@ -110,7 +111,7 @@
Configurable<LabeledArray<int>> cfgUseTrackTuner{"cfgUseTrackTuner", {nuclei::useTrackTuner[0], nuclei::Species::kNspecies, 1, nuclei::names, {"UseTrckTuner"}}, "Use Track Tuner"};
Configurable<std::string> cfgTrackTunerParams{"cfgTrackTunerParams", "debugInfo=0|updateTrackDCAs=1|updateTrackCovMat=1|updateCurvature=0|updateCurvatureIU=0|updatePulls=0|isInputFileFromCCDB=1|pathInputFile=Users/m/mfaggin/test/inputsTrackTuner/pp2023/pass4/correct_names|nameInputFile=trackTuner_DataLHC23hPass4_McLHC23k4g.root|pathFileQoverPt=Users/h/hsharma/qOverPtGraphs|nameFileQoverPt=D0sigma_Data_removal_itstps_MC_LHC22b1b.root|usePvRefitCorrections=0|qOverPtMC=-1.|qOverPtData=-1.|nPhiBins=1|autoDetectDcaCalib=false", "TrackTuner parameter initialization (format: <name>=<value>|<name>=<value>)"};
Configurable<int> cfgTrackTunerConfigSource{"cfgTrackTunerConfigSource", aod::track_tuner::InputString, "1: input string; 2: TrackTuner Configurables"};
ConfigurableAxis cfgAxisPtQA{"axisPtQA", {VARIABLE_WIDTH, 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1.0f, 1.1f, 1.2f, 1.3f, 1.4f, 1.5f, 1.6f, 1.7f, 1.8f, 1.9f, 2.0f, 2.2f, 2.4f, 2.6f, 2.8f, 3.0f, 3.2f, 3.4f, 3.6f, 3.8f, 4.0f, 4.4f, 4.8f, 5.2f, 5.6f, 6.0f, 6.5f, 7.0f, 7.5f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 17.0f, 19.0f, 21.0f, 23.0f, 25.0f, 30.0f, 35.0f, 40.0f, 50.0f}, "pt axis for QA histograms"};

Check failure on line 114 in PWGLF/TableProducer/QC/nucleiQC.cxx

View workflow job for this annotation

GitHub Actions / O2 linter

[name/configurable]

Use lowerCamelCase for names of configurables and use the same name for the struct member as for the JSON string. (Declare the type and names on the same line.)

Configurable<bool> cfgRapidityToggle{"cfgRapidityToggle", false, "If true, cut on rapidity for reconstructed particles"};
Configurable<float> cfgRapidityMin{"cfgRapidityMin", -1., "Minimum rapidity value"};
Expand All @@ -125,13 +126,15 @@
Configurable<float> cfgCutNclusCrossedRowsTPC{"cfgCutNclusCrossedRowsTPC", 70, "Minimum number of TPC clusters crossed rows"};
Configurable<float> cfgCutChi2PerClusterTPC{"cfgCutChi2PerClusterTPC", 4.f, "Maximum chi2 per TPC cluster"};
Configurable<float> cfgCutChi2PerClusterITS{"cfgCutChi2PerClusterITS", 36.f, "Maximum chi2 per ITS cluster"};
Configurable<float> cfgCutDCAxy{"cfgCutDCAxy", 10.f, "Maximum DCA in the transverse plane"};
Configurable<float> cfgCutDCAz{"cfgCutDCAz", 10.f, "Maximum DCA in the longitudinal direction"};

Configurable<LabeledArray<double>> cfgNsigmaTPC{"cfgNsigmaTPC", {nuclei::nSigmaTPCdefault[0], nuclei::Species::kNspecies, 2, nuclei::names, nuclei::nSigmaConfigName}, "TPC nsigma selection for light nuclei"};
Configurable<LabeledArray<double>> cfgNsigmaTOF{"cfgNsigmaTOF", {nuclei::nSigmaTOFdefault[0], nuclei::Species::kNspecies, 2, nuclei::names, nuclei::nSigmaConfigName}, "TPC nsigma selection for light nuclei"};

// CCDB options
Configurable<int> cfgMaterialCorrection{"cfgMaterialCorrection", static_cast<int>(o2::base::Propagator::MatCorrType::USEMatCorrLUT), "Type of material correction"};
Configurable<std::string> cfgCCDBurl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"};

Check failure on line 137 in PWGLF/TableProducer/QC/nucleiQC.cxx

View workflow job for this annotation

GitHub Actions / O2 linter

[name/configurable]

Use lowerCamelCase for names of configurables and use the same name for the struct member as for the JSON string. (Declare the type and names on the same line.)
Service<o2::ccdb::BasicCCDBManager> mCcdb;
int mRunNumber = 0;
float mBz = 0.f;
Expand All @@ -142,6 +145,7 @@
{"hEventSelections", "Event selections; Selection step; Counts", {HistType::kTH1D, {{nuclei::evSel::kNevSels + 1, -0.5f, static_cast<float>(nuclei::evSel::kNevSels) + 0.5f}}}},
{"hVtxZBefore", "Vertex distribution in Z before selections;Z (cm)", {HistType::kTH1F, {{400, -20.0, 20.0}}}},
{"hVtxZ", "Vertex distribution in Z;Z (cm)", {HistType::kTH1F, {{400, -20.0, 20.0}}}},
{"hCentrality", "Centrality distribution;Centrality (%)", {HistType::kTH1F, {{100, 0.0, 100.0}}}},
{"hFailCentrality", "0: all the times the centrality filling function is called - 1: each time it fails ; Bool", {HistType::kTH1F, {{2, -0.5, 1.50}}}},
{"hTrackTunedTracks", "", {HistType::kTH1F, {{1, 0.5, 1.5}}}},
},
Expand Down Expand Up @@ -192,7 +196,7 @@
return;

float tpcBetheBlochParams[6];
for (int iParam = 0; iParam < 6; iParam++) {

Check failure on line 199 in PWGLF/TableProducer/QC/nucleiQC.cxx

View workflow job for this annotation

GitHub Actions / O2 linter

[magic-number]

Avoid magic numbers in expressions. Assign the value to a clearly named variable or constant.
tpcBetheBlochParams[iParam] = cfgBetheBlochParams->get(kSpeciesRt, iParam);
}

Expand Down Expand Up @@ -252,8 +256,8 @@
LOGF(info, "Retrieved GRP for timestamp %ull (%i) with magnetic field of %1.2f kZG", timestamp, mRunNumber, mBz);
}

template <int iSpecies, typename Ttrack>
bool trackSelection(const Ttrack& track)
template <int iSpecies, typename Ttrack, typename Tcollision>
bool trackSelection(const Ttrack& track, const Tcollision& collision)
{
mHistograms.fill(HIST(nuclei::cNames[iSpecies]) + HIST("/hTrackQuality"), track.sign() * track.pt(), trackQuality::kNoCuts);

Expand Down Expand Up @@ -285,6 +289,16 @@
return false;
mHistograms.fill(HIST(nuclei::cNames[iSpecies]) + HIST("/hTrackQuality"), track.sign() * track.pt(), trackQuality::kItsChi2Cut);

const o2::math_utils::Point3D<float> collisionVertex{collision.posX(), collision.posY(), collision.posZ()};
mDcaInfoCov.set(999, 999, 999, 999, 999);
setTrackParCov(track, mTrackParCov);
mTrackParCov.setPID(track.pidForTracking());
std::array<float, 2> dcaInfo;
o2::base::Propagator::Instance()->propagateToDCA(collisionVertex, mTrackParCov, mBz, 2.f, static_cast<o2::base::Propagator::MatCorrType>(cfgMaterialCorrection.value), &dcaInfo);
if (std::abs(dcaInfo[0]) > cfgCutDCAxy || std::abs(dcaInfo[1]) > cfgCutDCAz)
return false;
mHistograms.fill(HIST(nuclei::cNames[iSpecies]) + HIST("/hTrackQuality"), track.sign() * track.pt(), trackQuality::kDcaCuts);

return true;
}

Expand All @@ -293,7 +307,7 @@
{
constexpr int kIndex = iSpecies;
if (!nuclei::checkSpeciesValidity(kIndex))
std::runtime_error("species contains invalid nucleus kIndex");
throw std::runtime_error("species contains invalid nucleus kIndex");

float centrality = nuclei::getCentrality(collision, cfgCentralityEstimator);
float nsigmaTPC = mPidManagers[kIndex].getNSigmaTPC(track);
Expand Down Expand Up @@ -329,7 +343,7 @@
}

if (particle.isPhysicalPrimary()) {
candidate.flags |= nuclei::Flags::kIsPhysicalPrimary;
candidate.flags |= nuclei::QcFlags::kQcIsPhysicalPrimary;

///< heavy flavour mother
/*if (particle.has_mothers()) {
Expand All @@ -344,52 +358,33 @@

} else if (particle.getProcess() == TMCProcess::kPDecay) {
///< assuming that strong decays are included in the previous step
candidate.flags |= nuclei::Flags::kIsSecondaryFromWeakDecay;
candidate.flags |= nuclei::QcFlags::kQcIsSecondaryFromWeakDecay;
} else {
candidate.flags |= nuclei::Flags::kIsSecondaryFromMaterial;
candidate.flags |= nuclei::QcFlags::kQcIsSecondaryFromMaterial;
}
}

void fillSpeciesFlags(const int iSpecies, nuclei::SlimCandidate& candidate)
template <typename Tparticle>
void fillCollisionFlag(const Tparticle& particle, nuclei::SlimCandidate& candidate, const std::vector<bool>& reconstructedCollision)
{

switch (iSpecies) {
case nuclei::Species::kPr:
candidate.flags |= nuclei::Flags::kProton;
break;
case nuclei::Species::kDe:
candidate.flags |= nuclei::Flags::kDeuteron;
break;
case nuclei::Species::kTr:
candidate.flags |= nuclei::Flags::kTriton;
break;
case nuclei::Species::kHe:
candidate.flags |= nuclei::Flags::kHe3;
break;
case nuclei::Species::kAl:
candidate.flags |= nuclei::Flags::kHe4;
break;
default:
candidate.flags |= 0;
break;
if (reconstructedCollision[particle.mcCollisionId()]) {
candidate.flags |= nuclei::QcFlags::kQcHasReconstructedCollision;
}
}

template <typename Tcollision, typename Ttrack>
void fillNucleusFlagsPdgs(const int iSpecies, const Tcollision& collision, const Ttrack& track, nuclei::SlimCandidate& candidate)
void fillNucleusFlagsPdgs(const Tcollision& collision, const Ttrack& track, nuclei::SlimCandidate& candidate)
{
candidate.flags = static_cast<uint16_t>((track.pidForTracking() & 0xF) << 12);

fillSpeciesFlags(iSpecies, candidate);

if (track.hasTOF())
candidate.flags |= nuclei::Flags::kHasTOF;
candidate.flags |= nuclei::QcFlags::kQcHasTOF;

if (track.hasTRD())
candidate.flags |= nuclei::Flags::kHasTRD;
candidate.flags |= nuclei::QcFlags::kQcHasTRD;

if (!collision.selection_bit(o2::aod::evsel::kNoITSROFrameBorder))
candidate.flags |= nuclei::Flags::kITSrof;
candidate.flags |= nuclei::QcFlags::kQcITSrof;
}

template <typename Tparticle>
Expand All @@ -405,8 +400,6 @@
void fillDcaInformation(const int iSpecies, const Tcollision& collision, const Ttrack& track, nuclei::SlimCandidate& candidate, const aod::McParticles::iterator& particle)
{

const o2::math_utils::Point3D<float> collisionVertex{collision.posX(), collision.posY(), collision.posZ()};

mDcaInfoCov.set(999, 999, 999, 999, 999);
setTrackParCov(track, mTrackParCov);
mTrackParCov.setPID(track.pidForTracking());
Expand All @@ -432,7 +425,7 @@
nuclei::SlimCandidate fillCandidate(const int iSpecies, Tcollision const& collision, Ttrack const& track)
{
if (!nuclei::checkSpeciesValidity(iSpecies))
std::runtime_error("species contains invalid nucleus index");
throw std::runtime_error("species contains invalid nucleus index");

nuclei::SlimCandidate candidate = {.pt = track.pt() * track.sign(),
.eta = track.eta(),
Expand All @@ -455,7 +448,7 @@
.nsigmaTpc = mPidManagers[iSpecies].getNSigmaTPC(track),
.nsigmaTof = mPidManagers[iSpecies].getNSigmaTOF(track)};

fillNucleusFlagsPdgs(iSpecies, collision, track, candidate);
fillNucleusFlagsPdgs(collision, track, candidate);

aod::McParticles::iterator particle;

Expand Down Expand Up @@ -497,7 +490,7 @@
{
constexpr int kIndex = iSpecies;
if (!nuclei::checkSpeciesValidity(kIndex))
std::runtime_error("species contains invalid nucleus kIndex");
throw std::runtime_error("species contains invalid nucleus kIndex");

if (isGenerated) {
const float ptGenerated = (kIndex == nuclei::Species::kPr || kIndex == nuclei::Species::kDe || kIndex == nuclei::Species::kTr) ? candidate.ptGenerated : candidate.ptGenerated / 2.f;
Expand All @@ -517,11 +510,12 @@
}
}

void processMc(const Collisions& collisions, const TrackCandidatesMC& tracks, const aod::BCsWithTimestamps&, const aod::McParticles& mcParticles)
void processMc(const Collisions& collisions, const TrackCandidatesMC& tracks, const aod::BCsWithTimestamps&, const aod::McParticles& mcParticles, const aod::McCollisions& mcCollisions)
{
gRandom->SetSeed(67);
mNucleiCandidates.clear();
std::vector<bool> reconstructedMcParticles(mcParticles.size(), false);
std::vector<bool> reconstructedCollisions(mcCollisions.size(), false);

for (const auto& collision : collisions) {

Expand All @@ -530,6 +524,8 @@

if (!nuclei::eventSelection(collision, mHistograms, cfgEventSelections, cfgCutVertex))
continue;
mHistograms.fill(HIST("hCentrality"), nuclei::getCentrality(collision, cfgCentralityEstimator, mHistFailCentrality));
reconstructedCollisions[collision.mcCollisionId()] = true;

bool anyTrackTuner = false;
for (int iSpecies = 0; iSpecies < static_cast<int>(nuclei::Species::kNspecies); iSpecies++) {
Expand Down Expand Up @@ -578,10 +574,8 @@
if (cfgFillOnlyPhysicalPrimaries && !particle.isPhysicalPrimary())
return;

LOG(info) << "track passed physical primary cut";

mHistograms.fill(HIST(nuclei::cNames[kSpeciesCt]) + HIST("/hTrackSelections"), nuclei::trackSelection::kNoCuts);
if (!trackSelection<kSpeciesRt>(track))
if (!trackSelection<kSpeciesRt>(track, collision))
return;
mHistograms.fill(HIST(nuclei::cNames[kSpeciesCt]) + HIST("/hTrackSelections"), nuclei::trackSelection::kTrackCuts);

Expand All @@ -591,6 +585,7 @@

nuclei::SlimCandidate candidate;
candidate = fillCandidate</*isMc*/ true>(kSpeciesCt, collision, track);
fillCollisionFlag(particle, candidate, reconstructedCollisions);

mNucleiCandidates.emplace_back(candidate);
reconstructedMcParticles[particle.globalIndex()] = true;
Expand Down Expand Up @@ -627,7 +622,7 @@
nuclei::SlimCandidate candidate;
// candidate.centrality = nuclei::getCentrality(collision, cfgCentralityEstimator, mHistFailCentrality);
candidate.centrality = -1.f; // centrality is not well defined for non-reconstructed particles, set to -1 for now
fillSpeciesFlags(iSpecies, candidate);
fillCollisionFlag(particle, candidate, reconstructedCollisions);
fillNucleusFlagsPdgsMc(particle, candidate);
fillNucleusGeneratedVariables(particle, candidate);

Expand Down
19 changes: 17 additions & 2 deletions PWGLF/Utils/nucleiUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,21 @@
kIsSecondaryFromWeakDecay = BIT(11) /// the last 4 bits are reserved for the PID in tracking
};

enum QcFlags {
kQcHasReconstructedCollision = BIT(0),
kQcPlaceholder0 = BIT(1), /// placeholdedrs
kQcPlaceholder1 = BIT(2), /// placeholdedrs
kQcPlaceholder2 = BIT(3), /// placeholdedrs
kQcPlaceholder3 = BIT(4), /// placeholdedrs
kQcHasTOF = BIT(5),
kQcHasTRD = BIT(6),
kQcIsAmbiguous = BIT(7), /// just a placeholder now
kQcITSrof = BIT(8),
kQcIsPhysicalPrimary = BIT(9), /// MC flags starting from the second half of the short
kQcIsSecondaryFromMaterial = BIT(10),
kQcIsSecondaryFromWeakDecay = BIT(11) /// the last 4 bits are reserved for the PID in tracking
};

constexpr int getSpeciesFromPdg(int pdg)
{
switch (std::abs(pdg)) {
Expand Down Expand Up @@ -419,7 +434,7 @@

constexpr int index = iSpecies;
if (!checkSpeciesValidity(index)) {
std::runtime_error("species contains invalid nucleus index");
throw std::runtime_error("species contains invalid nucleus index");
}

registry.add(fmt::format("{}/hTrackSelections", cNames[index]).c_str(), (fmt::format("{} track selections;", cNames[index]) + std::string("Selection step; Counts")).c_str(), o2::framework::HistType::kTH1D, {{trackSelection::kNtrackSelections, -0.5f, static_cast<float>(trackSelection::kNtrackSelections) - 0.5f}});
Expand Down Expand Up @@ -457,7 +472,7 @@
: mSpecies(species)
{
if (!checkSpeciesValidity(species)) {
std::runtime_error("species contains invalid nucleus index");
throw std::runtime_error("species contains invalid nucleus index");
}

if (!tpcBetheBlochParams) {
Expand All @@ -465,7 +480,7 @@
return;
}

for (int i = 0; i < 6; i++) {

Check failure on line 483 in PWGLF/Utils/nucleiUtils.h

View workflow job for this annotation

GitHub Actions / O2 linter

[magic-number]

Avoid magic numbers in expressions. Assign the value to a clearly named variable or constant.
mTpcBetheBlochParams[i] = tpcBetheBlochParams[i];
}
}
Expand Down
Loading