From e8c8e31f763aa90c787a89e484aa1a0200d9a5a7 Mon Sep 17 00:00:00 2001 From: Lucia Anna Tarasovicova Date: Fri, 28 Nov 2025 09:03:56 +0100 Subject: [PATCH 1/6] fix the code for V0s --- ALICE3/TableProducer/OTF/onTheFlyTracker.cxx | 330 +++++++++++-------- 1 file changed, 189 insertions(+), 141 deletions(-) diff --git a/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx b/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx index c3c64b39665..1c5b846a0b1 100644 --- a/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx +++ b/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx @@ -196,6 +196,7 @@ struct OnTheFlyTracker { // V0 names for filling histograms static constexpr std::string_view kV0names[] = {"K0", "Lambda", "AntiLambda"}; + static constexpr std::string_view index[] = {"0", "1", "2", "3"}; // Class to hold the track information for the O2 vertexing class TrackAlice3 : public o2::track::TrackParCov @@ -299,41 +300,40 @@ struct OnTheFlyTracker { TRandom3 rand; Service ccdb; - static constexpr int kMaxLUTConfigs = 20; void init(o2::framework::InitContext&) { ccdb->setURL("http://alice-ccdb.cern.ch"); ccdb->setTimestamp(-1); - if (enablePrimarySmearing) { - auto loadLUT = [&](int icfg, int pdg, const std::vector& tables) { - LOG(info) << "Loading LUT for pdg " << pdg << " for config " << icfg << " from provided tables with size " << tables.size(); - if (tables.empty()) { - LOG(debug) << "No LUT file passed for pdg " << pdg << ", skipping."; - return false; - } - const bool foundNewCfg = static_cast(icfg) < tables.size(); - std::string lutFile = foundNewCfg ? tables[icfg] : tables.front(); - LOG(info) << "Loading LUT for pdg " << pdg << " from file " << lutFile << " for config " << icfg; - // strip from leading/trailing spaces - lutFile.erase(0, lutFile.find_first_not_of(" ")); - lutFile.erase(lutFile.find_last_not_of(" ") + 1); - if (lutFile.empty()) { - LOG(debug) << "Empty LUT file name for pdg " << pdg << ", skipping."; - return false; - } - bool success = mSmearer[icfg]->loadTable(pdg, lutFile.c_str()); - if (!success) { - LOG(fatal) << "Having issue with loading the LUT " << pdg << " " << lutFile; - } - - return foundNewCfg; - }; + auto loadLUT = [&](int icfg, int pdg, const std::vector& tables) { + LOG(info) << "Loading LUT for pdg " << pdg << " for config " << icfg << " from provided tables with size " << tables.size(); + if (tables.empty()) { + LOG(debug) << "No LUT file passed for pdg " << pdg << ", skipping."; + return false; + } + const bool foundNewCfg = static_cast(icfg) < tables.size(); + std::string lutFile = foundNewCfg ? tables[icfg] : tables.front(); + LOG(info) << "Loading LUT for pdg " << pdg << " from file " << lutFile << " for config " << icfg; + // strip from leading/trailing spaces + lutFile.erase(0, lutFile.find_first_not_of(" ")); + lutFile.erase(lutFile.find_last_not_of(" ") + 1); + if (lutFile.empty()) { + LOG(info) << "Empty LUT file name for pdg " << pdg << ", skipping."; + return false; + } + bool success = mSmearer[icfg]->loadTable(pdg, lutFile.c_str()); + if (!success) { + LOG(fatal) << "Having issue with loading the LUT " << pdg << " " << lutFile; + } - for (int icfg = 0; icfg < kMaxLUTConfigs; ++icfg) { - mSmearer.emplace_back(std::make_unique()); - mSmearer[icfg]->setCcdbManager(ccdb.operator->()); + return foundNewCfg; + }; + for (int icfg = 0; icfg < static_cast(fastTrackerSettings.alice3geo->size()); ++icfg) { + std::string histPath = "Configuration_" + std::to_string(icfg) + "/"; + mSmearer.emplace_back(std::make_unique()); + mSmearer[icfg]->setCcdbManager(ccdb.operator->()); + if (enablePrimarySmearing) { // check if more configs were provided, fall back to first entry bool newLUTLoaded = false; newLUTLoaded |= loadLUT(icfg, kElectron, lookUpTables.lutEl.value); @@ -345,19 +345,21 @@ struct OnTheFlyTracker { newLUTLoaded |= loadLUT(icfg, o2::constants::physics::kTriton, lookUpTables.lutTr.value); newLUTLoaded |= loadLUT(icfg, o2::constants::physics::kHelium3, lookUpTables.lutHe3.value); newLUTLoaded |= loadLUT(icfg, o2::constants::physics::kAlpha, lookUpTables.lutAl.value); - + bool smearerOK = true; if (!newLUTLoaded) { mSmearer.pop_back(); - break; + // break; + smearerOK = false; } // interpolate efficiencies if requested to do so - mSmearer[icfg]->interpolateEfficiency(static_cast(interpolateLutEfficiencyVsNch)); + if (smearerOK) { + mSmearer[icfg]->interpolateEfficiency(static_cast(interpolateLutEfficiencyVsNch)); - // smear un-reco'ed tracks if asked to do so - mSmearer[icfg]->skipUnreconstructed(static_cast(!processUnreconstructedTracks)); + // smear un-reco'ed tracks if asked to do so + mSmearer[icfg]->skipUnreconstructed(static_cast(!processUnreconstructedTracks)); + } - std::string histPath = "Configuration_" + std::to_string(icfg) + "/"; histPointers.insert({histPath + "hPtGenerated", histos.add((histPath + "hPtGenerated").c_str(), "hPtGenerated", {kTH1D, {{axes.axisMomentum}}})}); histPointers.insert({histPath + "hPhiGenerated", histos.add((histPath + "hPhiGenerated").c_str(), "hPhiGenerated", {kTH1D, {{100, 0.0f, 2 * M_PI, "#phi (rad)"}}})}); @@ -370,44 +372,42 @@ struct OnTheFlyTracker { histPointers.insert({histPath + "hPtReconstructedPi", histos.add((histPath + "hPtReconstructedPi").c_str(), "hPtReconstructedPi", {kTH1D, {{axes.axisMomentum}}})}); histPointers.insert({histPath + "hPtReconstructedKa", histos.add((histPath + "hPtReconstructedKa").c_str(), "hPtReconstructedKa", {kTH1D, {{axes.axisMomentum}}})}); histPointers.insert({histPath + "hPtReconstructedPr", histos.add((histPath + "hPtReconstructedPr").c_str(), "hPtReconstructedPr", {kTH1D, {{axes.axisMomentum}}})}); - - // Collision QA - histPointers.insert({histPath + "hPVz", histos.add((histPath + "hPVz").c_str(), "hPVz", {kTH1D, {{axes.axisVertexZ}}})}); - histPointers.insert({histPath + "hLUTMultiplicity", histos.add((histPath + "hLUTMultiplicity").c_str(), "hLUTMultiplicity", {kTH1D, {{axes.axisMultiplicity}}})}); - histPointers.insert({histPath + "hSimMultiplicity", histos.add((histPath + "hSimMultiplicity").c_str(), "hSimMultiplicity", {kTH1D, {{axes.axisMultiplicity}}})}); - histPointers.insert({histPath + "hRecoMultiplicity", histos.add((histPath + "hRecoMultiplicity").c_str(), "hRecoMultiplicity", {kTH1D, {{axes.axisMultiplicity}}})}); - - if (enableSecondarySmearing) { - fastTracker.emplace_back(std::make_unique()); - fastTracker[icfg]->SetMagneticField(magneticField); - fastTracker[icfg]->SetApplyZacceptance(fastTrackerSettings.applyZacceptance); - fastTracker[icfg]->SetApplyMSCorrection(fastTrackerSettings.applyMSCorrection); - fastTracker[icfg]->SetApplyElossCorrection(fastTrackerSettings.applyElossCorrection); - - if (fastTrackerSettings.alice3geo.value[icfg] == "0") { - fastTracker[icfg]->AddSiliconALICE3v2(fastTrackerSettings.pixelRes); - } else if (fastTrackerSettings.alice3geo.value[icfg] == "1") { - fastTracker[icfg]->AddSiliconALICE3v4(fastTrackerSettings.pixelRes); - fastTracker[icfg]->AddTPC(0.1, 0.1); - } else if (fastTrackerSettings.alice3geo.value[icfg] == "2") { - fastTracker[icfg]->AddSiliconALICE3(fastTrackerSettings.scaleVD, fastTrackerSettings.pixelRes); - } else { - fastTracker[icfg]->AddGenericDetector(fastTrackerSettings.alice3geo.value[icfg], ccdb.operator->()); - } - - // print fastTracker settings - fastTracker[icfg]->Print(); - histPointers.insert({histPath + "hMassXi", histos.add((histPath + "hMassXi").c_str(), "hMassXi", {kTH1D, {{axes.axisXiMass}}})}); + } + // Collision QA + histPointers.insert({histPath + "hPVz", histos.add((histPath + "hPVz").c_str(), "hPVz", {kTH1D, {{axes.axisVertexZ}}})}); + histPointers.insert({histPath + "hLUTMultiplicity", histos.add((histPath + "hLUTMultiplicity").c_str(), "hLUTMultiplicity", {kTH1D, {{axes.axisMultiplicity}}})}); + histPointers.insert({histPath + "hSimMultiplicity", histos.add((histPath + "hSimMultiplicity").c_str(), "hSimMultiplicity", {kTH1D, {{axes.axisMultiplicity}}})}); + histPointers.insert({histPath + "hRecoMultiplicity", histos.add((histPath + "hRecoMultiplicity").c_str(), "hRecoMultiplicity", {kTH1D, {{axes.axisMultiplicity}}})}); + + if (enableSecondarySmearing) { + fastTracker.emplace_back(std::make_unique()); + fastTracker[icfg]->SetMagneticField(magneticField); + fastTracker[icfg]->SetApplyZacceptance(fastTrackerSettings.applyZacceptance); + fastTracker[icfg]->SetApplyMSCorrection(fastTrackerSettings.applyMSCorrection); + fastTracker[icfg]->SetApplyElossCorrection(fastTrackerSettings.applyElossCorrection); + if (fastTrackerSettings.alice3geo.value[icfg] == "0") { + fastTracker[icfg]->AddSiliconALICE3v2(fastTrackerSettings.pixelRes); + } else if (fastTrackerSettings.alice3geo.value[icfg] == "1") { + fastTracker[icfg]->AddSiliconALICE3v4(fastTrackerSettings.pixelRes); + fastTracker[icfg]->AddTPC(0.1, 0.1); + } else if (fastTrackerSettings.alice3geo.value[icfg] == "2") { + fastTracker[icfg]->AddSiliconALICE3(fastTrackerSettings.scaleVD, fastTrackerSettings.pixelRes); + } else { + fastTracker[icfg]->AddGenericDetector(fastTrackerSettings.alice3geo.value[icfg], ccdb.operator->()); } + // print fastTracker settings + fastTracker[icfg]->Print(); + if (cascadeDecaySettings.doXiQA) + histPointers.insert({histPath + "hMassXi", histos.add((histPath + "hMassXi").c_str(), "hMassXi", {kTH1D, {{axes.axisXiMass}}})}); + } - if (doExtraQA) { - histPointers.insert({histPath + "h2dPtRes", histos.add((histPath + "h2dPtRes").c_str(), "h2dPtRes", {kTH2D, {{axes.axisMomentum, axes.axisPtRes}}})}); - histPointers.insert({histPath + "h2dDCAxy", histos.add((histPath + "h2dDCAxy").c_str(), "h2dDCAxy", {kTH2D, {{axes.axisMomentum, axes.axisDCA}}})}); - histPointers.insert({histPath + "h2dDCAz", histos.add((histPath + "h2dDCAz").c_str(), "h2dDCAz", {kTH2D, {{axes.axisMomentum, axes.axisDCA}}})}); - } + if (doExtraQA) { + histPointers.insert({histPath + "h2dPtRes", histos.add((histPath + "h2dPtRes").c_str(), "h2dPtRes", {kTH2D, {{axes.axisMomentum, axes.axisPtRes}}})}); + histPointers.insert({histPath + "h2dDCAxy", histos.add((histPath + "h2dDCAxy").c_str(), "h2dDCAxy", {kTH2D, {{axes.axisMomentum, axes.axisDCA}}})}); + histPointers.insert({histPath + "h2dDCAz", histos.add((histPath + "h2dDCAz").c_str(), "h2dDCAz", {kTH2D, {{axes.axisMomentum, axes.axisDCA}}})}); + } - } // end config loop - } + } // end config loop // Basic QA auto hNaN = histos.add("hNaNBookkeeping", "hNaNBookkeeping", kTH2F, {{10, -0.5f, 9.5f}, {10, -0.5f, 9.5f}}); @@ -478,31 +478,9 @@ struct OnTheFlyTracker { hFastTrackerQA->GetXaxis()->SetBinLabel(8, "efficiency"); } if (v0DecaySettings.doV0QA) { - histos.add("V0Building/hV0Building", "hV0Building", kTH1F, {{10, -0.5f, 9.5f}}); - - histos.add("V0Building/K0/hGen", "hGen", kTH2F, {axes.axisDecayRadius, axes.axisMomentum}); - histos.add("V0Building/K0/hReco", "hReco", kTH2F, {axes.axisDecayRadius, axes.axisMomentum}); - histos.add("V0Building/K0/hGenNegDaughterFromV0", "hGenNegDaughterFromV0", kTH2F, {axes.axisDecayRadius, axes.axisMomentum}); - histos.add("V0Building/K0/hGenPosDaughterFromV0", "hGenPosDaughterFromV0", kTH2F, {axes.axisDecayRadius, axes.axisMomentum}); - histos.add("V0Building/K0/hRecoNegDaughterFromV0", "hRecoNegDaughterFromV0", kTH2F, {axes.axisDecayRadius, axes.axisMomentum}); - histos.add("V0Building/K0/hRecoPosDaughterFromV0", "hRecoPosDaughterFromV0", kTH2F, {axes.axisDecayRadius, axes.axisMomentum}); - - // histos.add("V0Building/K0/h2dDCAxyV0Negative", "h2dDCAxyV0Negative", kTH2F, {axes.axisMomentum, axes.axisDCA}); - // histos.add("V0Building/K0/h2dDCAxyV0Positive", "h2dDCAxyV0Positive", kTH2F, {axes.axisMomentum, axes.axisDCA}); - - // histos.add("V0Building/K0/h2dDCAzV0Negative", "h2dDCAzV0Negative", kTH2F, {axes.axisMomentum, axes.axisDCA}); - // histos.add("V0Building/K0/h2dDCAzV0Positive", "h2dDCAzV0Positive", kTH2F, {axes.axisMomentum, axes.axisDCA}); - - histos.addClone("V0Building/K0/", "V0Building/Lambda/"); - histos.addClone("V0Building/K0/", "V0Building/AntiLambda/"); - - histos.add("V0Building/K0/hMass", "hMass", kTH2F, {axes.axisK0Mass, axes.axisMomentum}); - histos.add("V0Building/K0/hFinalMass", "hMass", kTH1F, {axes.axisK0Mass}); - histos.add("V0Building/Lambda/hMass", "hMass", kTH2F, {axes.axisLambdaMass, axes.axisMomentum}); - histos.add("V0Building/AntiLambda/hMass", "hMass", kTH2F, {axes.axisLambdaMass, axes.axisMomentum}); - - histos.add("V0Building/hFastTrackerHits", "hFastTrackerHits", kTH2F, {axes.axisZ, axes.axisRadius}); - auto hFastTrackerQA = histos.add("V0Building/hFastTrackerQA", "hFastTrackerQA", kTH1D, {{8, -0.5f, 7.5f}}); + histos.add("V0Building_Configuration_0/hV0Building", "hV0Building", kTH1F, {{10, -0.5f, 9.5f}}); + histos.add("V0Building_Configuration_0/hFastTrackerHits", "hFastTrackerHits", kTH2F, {axes.axisZ, axes.axisRadius}); + auto hFastTrackerQA = histos.add("V0Building_Configuration_0/hFastTrackerQA", "hFastTrackerQA", kTH1D, {{8, -0.5f, 7.5f}}); hFastTrackerQA->GetXaxis()->SetBinLabel(1, "Negative eigenvalue"); hFastTrackerQA->GetXaxis()->SetBinLabel(2, "Failed sanity check"); hFastTrackerQA->GetXaxis()->SetBinLabel(3, "intercept original radius"); @@ -511,6 +489,27 @@ struct OnTheFlyTracker { hFastTrackerQA->GetXaxis()->SetBinLabel(6, "multiple scattering"); hFastTrackerQA->GetXaxis()->SetBinLabel(7, "energy loss"); hFastTrackerQA->GetXaxis()->SetBinLabel(8, "efficiency"); + + histos.add("V0Building_Configuration_0/K0/hGen", "hGen", kTH2F, {axes.axisDecayRadius, axes.axisMomentum}); + histos.add("V0Building_Configuration_0/K0/hReco", "hReco", kTH2F, {axes.axisDecayRadius, axes.axisMomentum}); + histos.add("V0Building_Configuration_0/K0/hGenNegDaughterFromV0", "hGenNegDaughterFromV0", kTH2F, {axes.axisDecayRadius, axes.axisMomentum}); + histos.add("V0Building_Configuration_0/K0/hGenPosDaughterFromV0", "hGenPosDaughterFromV0", kTH2F, {axes.axisDecayRadius, axes.axisMomentum}); + histos.add("V0Building_Configuration_0/K0/hRecoNegDaughterFromV0", "hRecoNegDaughterFromV0", kTH2F, {axes.axisDecayRadius, axes.axisMomentum}); + histos.add("V0Building_Configuration_0/K0/hRecoPosDaughterFromV0", "hRecoPosDaughterFromV0", kTH2F, {axes.axisDecayRadius, axes.axisMomentum}); + + histos.addClone("V0Building_Configuration_0/K0/", "V0Building_Configuration_0/Lambda/"); + histos.addClone("V0Building_Configuration_0/K0/", "V0Building_Configuration_0/AntiLambda/"); + + histos.add("V0Building_Configuration_0/K0/hMass", "hMass", kTH2F, {axes.axisK0Mass, axes.axisMomentum}); + histos.add("V0Building_Configuration_0/K0/hFinalMass", "hMass", kTH1F, {axes.axisK0Mass}); + histos.add("V0Building_Configuration_0/Lambda/hMass", "hMass", kTH2F, {axes.axisLambdaMass, axes.axisMomentum}); + histos.add("V0Building_Configuration_0/AntiLambda/hMass", "hMass", kTH2F, {axes.axisLambdaMass, axes.axisMomentum}); + if (static_cast(fastTrackerSettings.alice3geo->size()) > 1) { + for (int icfg = 1; icfg < static_cast(fastTrackerSettings.alice3geo->size()); icfg++) { + std::string histPath = "Configuration_" + std::to_string(icfg) + "/"; + histos.addClone("V0Building_Configuration_0/", fmt::format("V0Building_{}", histPath).c_str()); + } + } } LOGF(info, "Initializing magnetic field to value: %.3f kG", static_cast(magneticField)); @@ -787,18 +786,18 @@ struct OnTheFlyTracker { if (std::fabs(mcParticle.eta()) > maxEta) { continue; } - - getHist(TH1, histPath + "hPtGenerated")->Fill(mcParticle.pt()); - getHist(TH1, histPath + "hPhiGenerated")->Fill(mcParticle.phi()); - if (std::abs(mcParticle.pdgCode()) == kElectron) - getHist(TH1, histPath + "hPtGeneratedEl")->Fill(mcParticle.pt()); - if (std::abs(mcParticle.pdgCode()) == kPiPlus) - getHist(TH1, histPath + "hPtGeneratedPi")->Fill(mcParticle.pt()); - if (std::abs(mcParticle.pdgCode()) == kKPlus) - getHist(TH1, histPath + "hPtGeneratedKa")->Fill(mcParticle.pt()); - if (std::abs(mcParticle.pdgCode()) == kProton) - getHist(TH1, histPath + "hPtGeneratedPr")->Fill(mcParticle.pt()); - + if (enablePrimarySmearing) { + getHist(TH1, histPath + "hPtGenerated")->Fill(mcParticle.pt()); + getHist(TH1, histPath + "hPhiGenerated")->Fill(mcParticle.phi()); + if (std::abs(mcParticle.pdgCode()) == kElectron) + getHist(TH1, histPath + "hPtGeneratedEl")->Fill(mcParticle.pt()); + if (std::abs(mcParticle.pdgCode()) == kPiPlus) + getHist(TH1, histPath + "hPtGeneratedPi")->Fill(mcParticle.pt()); + if (std::abs(mcParticle.pdgCode()) == kKPlus) + getHist(TH1, histPath + "hPtGeneratedKa")->Fill(mcParticle.pt()); + if (std::abs(mcParticle.pdgCode()) == kProton) + getHist(TH1, histPath + "hPtGeneratedPr")->Fill(mcParticle.pt()); + } if (cascadeDecaySettings.doXiQA && mcParticle.pdgCode() == kXiMinus) { histos.fill(HIST("hGenXi"), xiDecayRadius2D, mcParticle.pt()); histos.fill(HIST("hGenPiFromXi"), xiDecayRadius2D, decayProducts[0].Pt()); @@ -808,9 +807,16 @@ struct OnTheFlyTracker { if (v0DecaySettings.doV0QA && isV0) { static_for<0, 2>([&](auto i) { constexpr int Index = i.value; - histos.fill(HIST("V0Building/") + HIST(kV0names[Index]) + HIST("/hGen"), v0DecayRadius2D, mcParticle.pt()); - histos.fill(HIST("V0Building/") + HIST(kV0names[Index]) + HIST("/hGenNegDaughterFromV0"), v0DecayRadius2D, v0DecayProducts[0].Pt()); - histos.fill(HIST("V0Building/") + HIST(kV0names[Index]) + HIST("/hGenPosDaughterFromV0"), v0DecayRadius2D, v0DecayProducts[1].Pt()); + if (pdg == v0PDGs[Index]) { + static_for<0, 3>([&](auto j) { + constexpr int IndexCnfg = j.value; + if (icfg == IndexCnfg) { + histos.fill(HIST("V0Building_Configuration_") + HIST(index[IndexCnfg]) + HIST("/") + HIST(kV0names[Index]) + HIST("/hGen"), v0DecayRadius2D, mcParticle.pt()); + histos.fill(HIST("V0Building_Configuration_") + HIST(index[IndexCnfg]) + HIST("/") + HIST(kV0names[Index]) + HIST("/hGenNegDaughterFromV0"), v0DecayRadius2D, v0DecayProducts[0].Pt()); + histos.fill(HIST("V0Building_Configuration_") + HIST(index[IndexCnfg]) + HIST("/") + HIST(kV0names[Index]) + HIST("/hGenPosDaughterFromV0"), v0DecayRadius2D, v0DecayProducts[1].Pt()); + } + }); + } }); } if (mcParticle.pt() < minPt) { @@ -1102,7 +1108,12 @@ struct OnTheFlyTracker { std::vector nV0TPCHits(kv0Prongs); // TPC type if (v0DecaySettings.decayV0 && isV0) { if (v0DecaySettings.doV0QA) { - histos.fill(HIST("V0Building/hV0Building"), 0.0f); + static_for<0, 3>([&](auto j) { + constexpr int IndexCnfg = j.value; + if (icfg == IndexCnfg) { + histos.fill(HIST("V0Building_Configuration_") + HIST(index[IndexCnfg]) + HIST("/hV0Building"), 0.0f); + } + }); } if (isK0) { o2::upgrade::convertTLorentzVectorToO2Track(kPiMinus, v0DecayProducts[0], v0DecayVertex, v0DaughterTrackParCovsPerfect[0], pdgDB); @@ -1125,7 +1136,12 @@ struct OnTheFlyTracker { nV0TPCHits[i] = fastTracker[icfg]->GetNGasPoints(); if (nV0Hits[i] < 0) { // QA - histos.fill(HIST("V0Building/hFastTrackerQA"), o2::math_utils::abs(nV0Hits[i])); + static_for<0, 3>([&](auto j) { + constexpr int IndexCnfg = j.value; + if (icfg == IndexCnfg) { + histos.fill(HIST("V0Building_Configuration_") + HIST(index[IndexCnfg]) + HIST("/hFastTrackerQA"), o2::math_utils::abs(nV0Hits[i])); + } + }); } if (nV0SiliconHits[i] >= fastTrackerSettings.minSiliconHits || (nV0SiliconHits[i] >= fastTrackerSettings.minSiliconHitsIfTPCUsed && nV0TPCHits[i] >= fastTrackerSettings.minTPCClusters)) { @@ -1134,7 +1150,12 @@ struct OnTheFlyTracker { continue; // extra sure } for (uint32_t ih = 0; ih < fastTracker[icfg]->GetNHits(); ih++) { - histos.fill(HIST("V0Building/hFastTrackerHits"), fastTracker[icfg]->GetHitZ(ih), std::hypot(fastTracker[icfg]->GetHitX(ih), fastTracker[icfg]->GetHitY(ih))); + static_for<0, 3>([&](auto j) { + constexpr int IndexCnfg = j.value; + if (icfg == IndexCnfg) { + histos.fill(HIST("V0Building_Configuration_") + HIST(index[IndexCnfg]) + HIST("/hFastTrackerHits"), fastTracker[icfg]->GetHitZ(ih), std::hypot(fastTracker[icfg]->GetHitX(ih), fastTracker[icfg]->GetHitY(ih))); + } + }); } } else { isReco[i] = true; @@ -1156,25 +1177,42 @@ struct OnTheFlyTracker { static_for<0, 2>([&](auto i) { constexpr int Index = i.value; if (pdg == v0PDGs[Index]) { - if (isReco[0] && isReco[1]) { - histos.fill(HIST("V0Building/") + HIST(kV0names[Index]) + HIST("/hReco"), v0DecayRadius2D, mcParticle.pt()); - } - if (isReco[0]) - histos.fill(HIST("V0Building/") + HIST(kV0names[Index]) + HIST("/hRecoNegDaughterFromV0"), v0DecayRadius2D, v0DecayProducts[0].Pt()); - if (isReco[1]) - histos.fill(HIST("V0Building/") + HIST(kV0names[Index]) + HIST("/hRecoPosDaughterFromV0"), v0DecayRadius2D, v0DecayProducts[1].Pt()); + static_for<0, 3>([&](auto j) { + constexpr int IndexCnfg = j.value; + if (icfg == IndexCnfg) { + if (isReco[0] && isReco[1]) + histos.fill(HIST("V0Building_Configuration_") + HIST(index[IndexCnfg]) + HIST("/") + HIST(kV0names[Index]) + HIST("/hReco"), v0DecayRadius2D, mcParticle.pt()); + if (isReco[0]) + histos.fill(HIST("V0Building_Configuration_") + HIST(index[IndexCnfg]) + HIST("/") + HIST(kV0names[Index]) + HIST("/hRecoNegDaughterFromV0"), v0DecayRadius2D, v0DecayProducts[0].Pt()); + if (isReco[1]) + histos.fill(HIST("V0Building_Configuration_") + HIST(index[IndexCnfg]) + HIST("/") + HIST(kV0names[Index]) + HIST("/hRecoPosDaughterFromV0"), v0DecayRadius2D, v0DecayProducts[1].Pt()); + } + }); } }); if (isReco[0] && isReco[1]) { - histos.fill(HIST("V0Building/hV0Building"), 1.0f); + static_for<0, 3>([&](auto j) { + constexpr int IndexCnfg = j.value; + if (icfg == IndexCnfg) { + histos.fill(HIST("V0Building_Configuration_") + HIST(index[IndexCnfg]) + HIST("/hV0Building"), 1.0f); + } + }); } } + // +-~-+-~-+-~-+-~-+-~-+-~-+-~-+-~-+-~-+-~-+-~-+-~-+-~-+ // combine particles into actual V0 candidate // V0 building starts here if (v0DecaySettings.findV0 && isReco[0] && isReco[1]) { - if (v0DecaySettings.doV0QA) - histos.fill(HIST("V0Building/hV0Building"), 2.0f); + if (v0DecaySettings.doV0QA) { + static_for<0, 3>([&](auto j) { + constexpr int IndexCnfg = j.value; + if (icfg == IndexCnfg) { + histos.fill(HIST("V0Building_Configuration_") + HIST(index[IndexCnfg]) + HIST("/hV0Building"), 2.0f); + } + }); + } + // assign indices of the particles we've used // they should be the last ones to be filled, in order: // n-1: positive Track from V0 @@ -1195,8 +1233,15 @@ struct OnTheFlyTracker { } // V0 found successfully if (dcaFitterOK_V0) { - if (v0DecaySettings.doV0QA) - histos.fill(HIST("V0Building/hV0Building"), 3.0f); + if (v0DecaySettings.doV0QA) { + static_for<0, 3>([&](auto j) { + constexpr int IndexCnfg = j.value; + if (icfg == IndexCnfg) { + histos.fill(HIST("V0Building_Configuration_") + HIST(index[IndexCnfg]) + HIST("/hV0Building"), 3.0f); + } + }); + } + std::array pos; std::array posP; std::array negP; @@ -1250,11 +1295,15 @@ struct OnTheFlyTracker { } if (v0DecaySettings.doV0QA) { - histos.fill(HIST("V0Building/hV0Building"), 4.0f); - - histos.fill(HIST("V0Building/K0/hMass"), thisV0.mK0, thisV0.pt); - histos.fill(HIST("V0Building/Lambda/hMass"), thisV0.mLambda, thisV0.pt); - histos.fill(HIST("V0Building/AntiLambda/hMass"), thisV0.mAntiLambda, thisV0.pt); + static_for<0, 3>([&](auto j) { + constexpr int IndexCnfg = j.value; + if (icfg == IndexCnfg) { + histos.fill(HIST("V0Building_Configuration_") + HIST(index[IndexCnfg]) + HIST("/hV0Building"), 4.0f); + histos.fill(HIST("V0Building_Configuration_") + HIST(index[IndexCnfg]) + HIST("/K0/hMass"), thisV0.mK0, thisV0.pt); + histos.fill(HIST("V0Building_Configuration_") + HIST(index[IndexCnfg]) + HIST("/Lambda/hMass"), thisV0.mLambda, thisV0.pt); + histos.fill(HIST("V0Building_Configuration_") + HIST(index[IndexCnfg]) + HIST("/AntiLambda/hMass"), thisV0.mAntiLambda, thisV0.pt); + } + }); } // add this V0 to vector (will fill cursor later with collision ID) @@ -1291,16 +1340,17 @@ struct OnTheFlyTracker { } // Base QA (note: reco pT here) - getHist(TH1, histPath + "hPtReconstructed")->Fill(trackParCov.getPt()); - if (std::abs(mcParticle.pdgCode()) == kElectron) - getHist(TH1, histPath + "hPtReconstructedEl")->Fill(trackParCov.getPt()); - if (std::abs(mcParticle.pdgCode()) == kPiPlus) - getHist(TH1, histPath + "hPtReconstructedPi")->Fill(trackParCov.getPt()); - if (std::abs(mcParticle.pdgCode()) == kKPlus) - getHist(TH1, histPath + "hPtReconstructedKa")->Fill(trackParCov.getPt()); - if (std::abs(mcParticle.pdgCode()) == kProton) - getHist(TH1, histPath + "hPtReconstructedPr")->Fill(trackParCov.getPt()); - + if (enablePrimarySmearing) { + getHist(TH1, histPath + "hPtReconstructed")->Fill(trackParCov.getPt()); + if (std::abs(mcParticle.pdgCode()) == kElectron) + getHist(TH1, histPath + "hPtReconstructedEl")->Fill(trackParCov.getPt()); + if (std::abs(mcParticle.pdgCode()) == kPiPlus) + getHist(TH1, histPath + "hPtReconstructedPi")->Fill(trackParCov.getPt()); + if (std::abs(mcParticle.pdgCode()) == kKPlus) + getHist(TH1, histPath + "hPtReconstructedKa")->Fill(trackParCov.getPt()); + if (std::abs(mcParticle.pdgCode()) == kProton) + getHist(TH1, histPath + "hPtReconstructedPr")->Fill(trackParCov.getPt()); + } if (doExtraQA) { getHist(TH2, histPath + "h2dPtRes")->Fill(trackParCov.getPt(), (trackParCov.getPt() - mcParticle.pt()) / trackParCov.getPt()); histos.fill(HIST("hRecoTrackX"), trackParCov.getX()); @@ -1519,8 +1569,6 @@ struct OnTheFlyTracker { cascade.foundClusters); } for (const auto& v0 : v0sAlice3) { - if (v0.mK0 > 0) - histos.fill(HIST("V0Building/K0/hFinalMass"), v0.mK0); tableUpgradeV0s(tableCollisions.lastIndex(), // now we know the collision index -> populate table v0.positiveId, v0.negativeId, From 0a7064b8c142053bc75f544b79d5d77b52565019 Mon Sep 17 00:00:00 2001 From: Lucia Anna Tarasovicova Date: Mon, 1 Dec 2025 09:21:38 +0100 Subject: [PATCH 2/6] fix of the build --- ALICE3/TableProducer/OTF/onTheFlyTracker.cxx | 56 ++++++++------------ 1 file changed, 23 insertions(+), 33 deletions(-) diff --git a/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx b/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx index 1c5b846a0b1..09e579064bc 100644 --- a/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx +++ b/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx @@ -505,6 +505,9 @@ struct OnTheFlyTracker { histos.add("V0Building_Configuration_0/Lambda/hMass", "hMass", kTH2F, {axes.axisLambdaMass, axes.axisMomentum}); histos.add("V0Building_Configuration_0/AntiLambda/hMass", "hMass", kTH2F, {axes.axisLambdaMass, axes.axisMomentum}); if (static_cast(fastTrackerSettings.alice3geo->size()) > 1) { + if(fastTrackerSettings.alice3geo->size()>4){ + LOG(warn) << "More than 4 FastTracker configurations found. Only first 4 will have V0 QA histograms filled."; + } for (int icfg = 1; icfg < static_cast(fastTrackerSettings.alice3geo->size()); icfg++) { std::string histPath = "Configuration_" + std::to_string(icfg) + "/"; histos.addClone("V0Building_Configuration_0/", fmt::format("V0Building_{}", histPath).c_str()); @@ -805,17 +808,14 @@ struct OnTheFlyTracker { histos.fill(HIST("hGenPrFromLa"), laDecayRadius2D, decayProducts[2].Pt()); } if (v0DecaySettings.doV0QA && isV0) { - static_for<0, 2>([&](auto i) { - constexpr int Index = i.value; - if (pdg == v0PDGs[Index]) { - static_for<0, 3>([&](auto j) { - constexpr int IndexCnfg = j.value; - if (icfg == IndexCnfg) { - histos.fill(HIST("V0Building_Configuration_") + HIST(index[IndexCnfg]) + HIST("/") + HIST(kV0names[Index]) + HIST("/hGen"), v0DecayRadius2D, mcParticle.pt()); - histos.fill(HIST("V0Building_Configuration_") + HIST(index[IndexCnfg]) + HIST("/") + HIST(kV0names[Index]) + HIST("/hGenNegDaughterFromV0"), v0DecayRadius2D, v0DecayProducts[0].Pt()); - histos.fill(HIST("V0Building_Configuration_") + HIST(index[IndexCnfg]) + HIST("/") + HIST(kV0names[Index]) + HIST("/hGenPosDaughterFromV0"), v0DecayRadius2D, v0DecayProducts[1].Pt()); - } - }); + static_for<0, 11>([&](auto i) { + constexpr int Index = i.value % 3; + constexpr int IndexCnfg = i.value % 4; + if (pdg == v0PDGs[Index] && icfg == IndexCnfg) { + + histos.fill(HIST("V0Building_Configuration_") + HIST(index[IndexCnfg]) + HIST("/") + HIST(kV0names[Index]) + HIST("/hGen"), v0DecayRadius2D, mcParticle.pt()); + histos.fill(HIST("V0Building_Configuration_") + HIST(index[IndexCnfg]) + HIST("/") + HIST(kV0names[Index]) + HIST("/hGenNegDaughterFromV0"), v0DecayRadius2D, v0DecayProducts[0].Pt()); + histos.fill(HIST("V0Building_Configuration_") + HIST(index[IndexCnfg]) + HIST("/") + HIST(kV0names[Index]) + HIST("/hGenPosDaughterFromV0"), v0DecayRadius2D, v0DecayProducts[1].Pt()); } }); } @@ -1174,30 +1174,20 @@ struct OnTheFlyTracker { } } if (v0DecaySettings.doV0QA) { - static_for<0, 2>([&](auto i) { - constexpr int Index = i.value; - if (pdg == v0PDGs[Index]) { - static_for<0, 3>([&](auto j) { - constexpr int IndexCnfg = j.value; - if (icfg == IndexCnfg) { - if (isReco[0] && isReco[1]) - histos.fill(HIST("V0Building_Configuration_") + HIST(index[IndexCnfg]) + HIST("/") + HIST(kV0names[Index]) + HIST("/hReco"), v0DecayRadius2D, mcParticle.pt()); - if (isReco[0]) - histos.fill(HIST("V0Building_Configuration_") + HIST(index[IndexCnfg]) + HIST("/") + HIST(kV0names[Index]) + HIST("/hRecoNegDaughterFromV0"), v0DecayRadius2D, v0DecayProducts[0].Pt()); - if (isReco[1]) - histos.fill(HIST("V0Building_Configuration_") + HIST(index[IndexCnfg]) + HIST("/") + HIST(kV0names[Index]) + HIST("/hRecoPosDaughterFromV0"), v0DecayRadius2D, v0DecayProducts[1].Pt()); - } - }); - } - }); - if (isReco[0] && isReco[1]) { - static_for<0, 3>([&](auto j) { - constexpr int IndexCnfg = j.value; - if (icfg == IndexCnfg) { + static_for<0, 11>([&](auto i) { + constexpr int Index = i.value % 3; + constexpr int IndexCnfg = i.value % 4; + if (pdg == v0PDGs[Index] && icfg == IndexCnfg) { + if (isReco[0] && isReco[1]) { histos.fill(HIST("V0Building_Configuration_") + HIST(index[IndexCnfg]) + HIST("/hV0Building"), 1.0f); + histos.fill(HIST("V0Building_Configuration_") + HIST(index[IndexCnfg]) + HIST("/") + HIST(kV0names[Index]) + HIST("/hReco"), v0DecayRadius2D, mcParticle.pt()); } - }); - } + if (isReco[0]) + histos.fill(HIST("V0Building_Configuration_") + HIST(index[IndexCnfg]) + HIST("/") + HIST(kV0names[Index]) + HIST("/hRecoNegDaughterFromV0"), v0DecayRadius2D, v0DecayProducts[0].Pt()); + if (isReco[1]) + histos.fill(HIST("V0Building_Configuration_") + HIST(index[IndexCnfg]) + HIST("/") + HIST(kV0names[Index]) + HIST("/hRecoPosDaughterFromV0"), v0DecayRadius2D, v0DecayProducts[1].Pt()); + } + }); } // +-~-+-~-+-~-+-~-+-~-+-~-+-~-+-~-+-~-+-~-+-~-+-~-+-~-+ From c67251f5e41d79b600e400dcbdcffd68aea43f49 Mon Sep 17 00:00:00 2001 From: Lucia Anna Tarasovicova Date: Mon, 1 Dec 2025 09:28:53 +0100 Subject: [PATCH 3/6] fix clang --- ALICE3/TableProducer/OTF/onTheFlyTracker.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx b/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx index 09e579064bc..defed2fb35b 100644 --- a/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx +++ b/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx @@ -505,7 +505,7 @@ struct OnTheFlyTracker { histos.add("V0Building_Configuration_0/Lambda/hMass", "hMass", kTH2F, {axes.axisLambdaMass, axes.axisMomentum}); histos.add("V0Building_Configuration_0/AntiLambda/hMass", "hMass", kTH2F, {axes.axisLambdaMass, axes.axisMomentum}); if (static_cast(fastTrackerSettings.alice3geo->size()) > 1) { - if(fastTrackerSettings.alice3geo->size()>4){ + if (fastTrackerSettings.alice3geo->size() > 4) { LOG(warn) << "More than 4 FastTracker configurations found. Only first 4 will have V0 QA histograms filled."; } for (int icfg = 1; icfg < static_cast(fastTrackerSettings.alice3geo->size()); icfg++) { From 30da79ca43eeae4a4c61bb72fd30ed9394d96bff Mon Sep 17 00:00:00 2001 From: Lucia Anna Tarasovicova Date: Wed, 3 Dec 2025 08:11:14 +0100 Subject: [PATCH 4/6] proper way for the nested static for loop --- ALICE3/TableProducer/OTF/onTheFlyTracker.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx b/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx index defed2fb35b..80ae578d3e2 100644 --- a/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx +++ b/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx @@ -809,7 +809,7 @@ struct OnTheFlyTracker { } if (v0DecaySettings.doV0QA && isV0) { static_for<0, 11>([&](auto i) { - constexpr int Index = i.value % 3; + constexpr int Index = i.value / 4; constexpr int IndexCnfg = i.value % 4; if (pdg == v0PDGs[Index] && icfg == IndexCnfg) { @@ -1175,7 +1175,7 @@ struct OnTheFlyTracker { } if (v0DecaySettings.doV0QA) { static_for<0, 11>([&](auto i) { - constexpr int Index = i.value % 3; + constexpr int Index = i.value / 4; constexpr int IndexCnfg = i.value % 4; if (pdg == v0PDGs[Index] && icfg == IndexCnfg) { if (isReco[0] && isReco[1]) { From 5f88348a52fc1775a89ce1fe5336893dfcd83a8e Mon Sep 17 00:00:00 2001 From: Lucia Anna Tarasovicova Date: Wed, 3 Dec 2025 08:27:05 +0100 Subject: [PATCH 5/6] different source of number of geometries for primary and secondary smearing --- ALICE3/TableProducer/OTF/onTheFlyTracker.cxx | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx b/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx index 80ae578d3e2..5593bb83319 100644 --- a/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx +++ b/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx @@ -328,8 +328,16 @@ struct OnTheFlyTracker { return foundNewCfg; }; + int nGeometries = static_cast(fastTrackerSettings.alice3geo->size()); + if (enablePrimarySmearing) + nGeometries = static_cast(lookUpTables.lutPi->size()); + if (enablePrimarySmearing && enableSecondarySmearing) { + if (static_cast(lookUpTables.lutPi->size()) != static_cast(fastTrackerSettings.alice3geo->size())) { + LOG(fatal) << "When enabling both primary and secondary smearing, the number of LUTs provided must match the number of geometries provided!"; + } + } - for (int icfg = 0; icfg < static_cast(fastTrackerSettings.alice3geo->size()); ++icfg) { + for (int icfg = 0; icfg < nGeometries; ++icfg) { std::string histPath = "Configuration_" + std::to_string(icfg) + "/"; mSmearer.emplace_back(std::make_unique()); mSmearer[icfg]->setCcdbManager(ccdb.operator->()); From e98a378a9aa81c9e79e7efecee8cfc0115a57c14 Mon Sep 17 00:00:00 2001 From: Lucia Anna Tarasovicova Date: Wed, 3 Dec 2025 15:20:18 +0100 Subject: [PATCH 6/6] using variables instead of hardcoded numbers --- ALICE3/TableProducer/OTF/onTheFlyTracker.cxx | 91 ++++++++++---------- 1 file changed, 46 insertions(+), 45 deletions(-) diff --git a/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx b/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx index 5593bb83319..29204e87dce 100644 --- a/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx +++ b/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx @@ -195,8 +195,10 @@ struct OnTheFlyTracker { o2::fastsim::FastTracker fastPrimaryTracker; // V0 names for filling histograms - static constexpr std::string_view kV0names[] = {"K0", "Lambda", "AntiLambda"}; - static constexpr std::string_view index[] = {"0", "1", "2", "3"}; + static constexpr int NtypesV0 = 3; + static constexpr std::string_view NameV0s[NtypesV0] = {"K0", "Lambda", "AntiLambda"}; + static constexpr int NtypesDetectors = 4; + static constexpr std::string_view NameDetectors[NtypesDetectors] = {"0", "1", "2", "3"}; // Class to hold the track information for the O2 vertexing class TrackAlice3 : public o2::track::TrackParCov @@ -816,14 +818,13 @@ struct OnTheFlyTracker { histos.fill(HIST("hGenPrFromLa"), laDecayRadius2D, decayProducts[2].Pt()); } if (v0DecaySettings.doV0QA && isV0) { - static_for<0, 11>([&](auto i) { - constexpr int Index = i.value / 4; - constexpr int IndexCnfg = i.value % 4; - if (pdg == v0PDGs[Index] && icfg == IndexCnfg) { - - histos.fill(HIST("V0Building_Configuration_") + HIST(index[IndexCnfg]) + HIST("/") + HIST(kV0names[Index]) + HIST("/hGen"), v0DecayRadius2D, mcParticle.pt()); - histos.fill(HIST("V0Building_Configuration_") + HIST(index[IndexCnfg]) + HIST("/") + HIST(kV0names[Index]) + HIST("/hGenNegDaughterFromV0"), v0DecayRadius2D, v0DecayProducts[0].Pt()); - histos.fill(HIST("V0Building_Configuration_") + HIST(index[IndexCnfg]) + HIST("/") + HIST(kV0names[Index]) + HIST("/hGenPosDaughterFromV0"), v0DecayRadius2D, v0DecayProducts[1].Pt()); + static_for<0, NtypesV0 * NtypesDetectors - 1>([&](auto i) { + constexpr int IndexV0 = i.value / NtypesDetectors; + constexpr int IndexDetector = i.value % NtypesDetectors; + if (pdg == v0PDGs[IndexV0] && icfg == IndexDetector) { + histos.fill(HIST("V0Building_Configuration_") + HIST(NameDetectors[IndexDetector]) + HIST("/") + HIST(NameV0s[IndexV0]) + HIST("/hGen"), v0DecayRadius2D, mcParticle.pt()); + histos.fill(HIST("V0Building_Configuration_") + HIST(NameDetectors[IndexDetector]) + HIST("/") + HIST(NameV0s[IndexV0]) + HIST("/hGenNegDaughterFromV0"), v0DecayRadius2D, v0DecayProducts[0].Pt()); + histos.fill(HIST("V0Building_Configuration_") + HIST(NameDetectors[IndexDetector]) + HIST("/") + HIST(NameV0s[IndexV0]) + HIST("/hGenPosDaughterFromV0"), v0DecayRadius2D, v0DecayProducts[1].Pt()); } }); } @@ -1116,10 +1117,10 @@ struct OnTheFlyTracker { std::vector nV0TPCHits(kv0Prongs); // TPC type if (v0DecaySettings.decayV0 && isV0) { if (v0DecaySettings.doV0QA) { - static_for<0, 3>([&](auto j) { - constexpr int IndexCnfg = j.value; - if (icfg == IndexCnfg) { - histos.fill(HIST("V0Building_Configuration_") + HIST(index[IndexCnfg]) + HIST("/hV0Building"), 0.0f); + static_for<0, NtypesDetectors - 1>([&](auto j) { + constexpr int IndexDetector = j.value; + if (icfg == IndexDetector) { + histos.fill(HIST("V0Building_Configuration_") + HIST(NameDetectors[IndexDetector]) + HIST("/hV0Building"), 0.0f); } }); } @@ -1144,10 +1145,10 @@ struct OnTheFlyTracker { nV0TPCHits[i] = fastTracker[icfg]->GetNGasPoints(); if (nV0Hits[i] < 0) { // QA - static_for<0, 3>([&](auto j) { - constexpr int IndexCnfg = j.value; - if (icfg == IndexCnfg) { - histos.fill(HIST("V0Building_Configuration_") + HIST(index[IndexCnfg]) + HIST("/hFastTrackerQA"), o2::math_utils::abs(nV0Hits[i])); + static_for<0, NtypesDetectors - 1>([&](auto j) { + constexpr int IndexDetector = j.value; + if (icfg == IndexDetector) { + histos.fill(HIST("V0Building_Configuration_") + HIST(NameDetectors[IndexDetector]) + HIST("/hFastTrackerQA"), o2::math_utils::abs(nV0Hits[i])); } }); } @@ -1158,10 +1159,10 @@ struct OnTheFlyTracker { continue; // extra sure } for (uint32_t ih = 0; ih < fastTracker[icfg]->GetNHits(); ih++) { - static_for<0, 3>([&](auto j) { - constexpr int IndexCnfg = j.value; - if (icfg == IndexCnfg) { - histos.fill(HIST("V0Building_Configuration_") + HIST(index[IndexCnfg]) + HIST("/hFastTrackerHits"), fastTracker[icfg]->GetHitZ(ih), std::hypot(fastTracker[icfg]->GetHitX(ih), fastTracker[icfg]->GetHitY(ih))); + static_for<0, NtypesDetectors - 1>([&](auto j) { + constexpr int IndexDetector = j.value; + if (icfg == IndexDetector) { + histos.fill(HIST("V0Building_Configuration_") + HIST(NameDetectors[IndexDetector]) + HIST("/hFastTrackerHits"), fastTracker[icfg]->GetHitZ(ih), std::hypot(fastTracker[icfg]->GetHitX(ih), fastTracker[icfg]->GetHitY(ih))); } }); } @@ -1182,18 +1183,18 @@ struct OnTheFlyTracker { } } if (v0DecaySettings.doV0QA) { - static_for<0, 11>([&](auto i) { - constexpr int Index = i.value / 4; - constexpr int IndexCnfg = i.value % 4; - if (pdg == v0PDGs[Index] && icfg == IndexCnfg) { + static_for<0, NtypesV0 * NtypesDetectors - 1>([&](auto i) { + constexpr int IndexV0 = i.value / NtypesDetectors; + constexpr int IndexDetector = i.value % NtypesDetectors; + if (pdg == v0PDGs[IndexV0] && icfg == IndexDetector) { if (isReco[0] && isReco[1]) { - histos.fill(HIST("V0Building_Configuration_") + HIST(index[IndexCnfg]) + HIST("/hV0Building"), 1.0f); - histos.fill(HIST("V0Building_Configuration_") + HIST(index[IndexCnfg]) + HIST("/") + HIST(kV0names[Index]) + HIST("/hReco"), v0DecayRadius2D, mcParticle.pt()); + histos.fill(HIST("V0Building_Configuration_") + HIST(NameDetectors[IndexDetector]) + HIST("/hV0Building"), 1.0f); + histos.fill(HIST("V0Building_Configuration_") + HIST(NameDetectors[IndexDetector]) + HIST("/") + HIST(NameV0s[IndexV0]) + HIST("/hReco"), v0DecayRadius2D, mcParticle.pt()); } if (isReco[0]) - histos.fill(HIST("V0Building_Configuration_") + HIST(index[IndexCnfg]) + HIST("/") + HIST(kV0names[Index]) + HIST("/hRecoNegDaughterFromV0"), v0DecayRadius2D, v0DecayProducts[0].Pt()); + histos.fill(HIST("V0Building_Configuration_") + HIST(NameDetectors[IndexDetector]) + HIST("/") + HIST(NameV0s[IndexV0]) + HIST("/hRecoNegDaughterFromV0"), v0DecayRadius2D, v0DecayProducts[0].Pt()); if (isReco[1]) - histos.fill(HIST("V0Building_Configuration_") + HIST(index[IndexCnfg]) + HIST("/") + HIST(kV0names[Index]) + HIST("/hRecoPosDaughterFromV0"), v0DecayRadius2D, v0DecayProducts[1].Pt()); + histos.fill(HIST("V0Building_Configuration_") + HIST(NameDetectors[IndexDetector]) + HIST("/") + HIST(NameV0s[IndexV0]) + HIST("/hRecoPosDaughterFromV0"), v0DecayRadius2D, v0DecayProducts[1].Pt()); } }); } @@ -1203,10 +1204,10 @@ struct OnTheFlyTracker { // V0 building starts here if (v0DecaySettings.findV0 && isReco[0] && isReco[1]) { if (v0DecaySettings.doV0QA) { - static_for<0, 3>([&](auto j) { - constexpr int IndexCnfg = j.value; - if (icfg == IndexCnfg) { - histos.fill(HIST("V0Building_Configuration_") + HIST(index[IndexCnfg]) + HIST("/hV0Building"), 2.0f); + static_for<0, NtypesDetectors - 1>([&](auto j) { + constexpr int IndexDetector = j.value; + if (icfg == IndexDetector) { + histos.fill(HIST("V0Building_Configuration_") + HIST(NameDetectors[IndexDetector]) + HIST("/hV0Building"), 2.0f); } }); } @@ -1232,10 +1233,10 @@ struct OnTheFlyTracker { // V0 found successfully if (dcaFitterOK_V0) { if (v0DecaySettings.doV0QA) { - static_for<0, 3>([&](auto j) { - constexpr int IndexCnfg = j.value; - if (icfg == IndexCnfg) { - histos.fill(HIST("V0Building_Configuration_") + HIST(index[IndexCnfg]) + HIST("/hV0Building"), 3.0f); + static_for<0, NtypesDetectors - 1>([&](auto j) { + constexpr int IndexDetector = j.value; + if (icfg == IndexDetector) { + histos.fill(HIST("V0Building_Configuration_") + HIST(NameDetectors[IndexDetector]) + HIST("/hV0Building"), 3.0f); } }); } @@ -1293,13 +1294,13 @@ struct OnTheFlyTracker { } if (v0DecaySettings.doV0QA) { - static_for<0, 3>([&](auto j) { - constexpr int IndexCnfg = j.value; - if (icfg == IndexCnfg) { - histos.fill(HIST("V0Building_Configuration_") + HIST(index[IndexCnfg]) + HIST("/hV0Building"), 4.0f); - histos.fill(HIST("V0Building_Configuration_") + HIST(index[IndexCnfg]) + HIST("/K0/hMass"), thisV0.mK0, thisV0.pt); - histos.fill(HIST("V0Building_Configuration_") + HIST(index[IndexCnfg]) + HIST("/Lambda/hMass"), thisV0.mLambda, thisV0.pt); - histos.fill(HIST("V0Building_Configuration_") + HIST(index[IndexCnfg]) + HIST("/AntiLambda/hMass"), thisV0.mAntiLambda, thisV0.pt); + static_for<0, NtypesDetectors - 1>([&](auto j) { + constexpr int IndexDetector = j.value; + if (icfg == IndexDetector) { + histos.fill(HIST("V0Building_Configuration_") + HIST(NameDetectors[IndexDetector]) + HIST("/hV0Building"), 4.0f); + histos.fill(HIST("V0Building_Configuration_") + HIST(NameDetectors[IndexDetector]) + HIST("/K0/hMass"), thisV0.mK0, thisV0.pt); + histos.fill(HIST("V0Building_Configuration_") + HIST(NameDetectors[IndexDetector]) + HIST("/Lambda/hMass"), thisV0.mLambda, thisV0.pt); + histos.fill(HIST("V0Building_Configuration_") + HIST(NameDetectors[IndexDetector]) + HIST("/AntiLambda/hMass"), thisV0.mAntiLambda, thisV0.pt); } }); }