From b473808ef4191bdd0182a19d8c53007d26409ecf Mon Sep 17 00:00:00 2001 From: Gauthier Legras Date: Thu, 23 Apr 2026 18:32:46 +0200 Subject: [PATCH 1/5] dalitz selection with tag and probe method --- PWGDQ/Core/CutsLibrary.cxx | 73 ++++++++++ PWGDQ/Tasks/DalitzSelection.cxx | 246 ++++++++++++++++++++++++-------- 2 files changed, 262 insertions(+), 57 deletions(-) diff --git a/PWGDQ/Core/CutsLibrary.cxx b/PWGDQ/Core/CutsLibrary.cxx index 09bb472266b..d29bf973e4a 100644 --- a/PWGDQ/Core/CutsLibrary.cxx +++ b/PWGDQ/Core/CutsLibrary.cxx @@ -1488,6 +1488,43 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } } + + if (!nameStr.compare("electronPrimaryTag0")) { + // with tight 3 sigma DCA cut for selecting primary electrons + cut->AddCut(GetAnalysisCut("electronPID_TPCnsigma_loose")); // 3 sigma inclusion, 3sigma rejection + cut->AddCut(GetAnalysisCut("electronPrimary_dca3sigma")); + cut->AddCut(GetAnalysisCut("jpsiStandardKine")); + return cut; + } + + if (!nameStr.compare("electronPrimaryTag1")) { + // with 7 sigma DCA cut for selecting primary electrons + cut->AddCut(GetAnalysisCut("electronPID_TPCnsigma_loose")); // 3 sigma inclusion, 3sigma rejection + cut->AddCut(GetAnalysisCut("electronPrimary_dca7sigma")); + cut->AddCut(GetAnalysisCut("jpsiStandardKine")); + return cut; + } + + if (!nameStr.compare("electronPrimaryProbe_TPC")) { + cut->AddCut(GetAnalysisCut("electronStandardQualityTPCOnly")); + cut->AddCut(GetAnalysisCut("lmeeStandardKine")); + return cut; + } + + if (!nameStr.compare("electronPrimaryProbe_ITS")) { + cut->AddCut(GetAnalysisCut("electronStandardQualitybAnyITSOnly")); + cut->AddCut(GetAnalysisCut("standardPrimaryTrackDCA")); + cut->AddCut(GetAnalysisCut("lmeeStandardKine")); + return cut; + } + + if (!nameStr.compare("electronPrimaryProbe_ITSTPC")) { + cut->AddCut(GetAnalysisCut("electronStandardQualityTPCOnly")); + cut->AddCut(GetAnalysisCut("electronStandardQualitybAnyITSOnly")); + cut->AddCut(GetAnalysisCut("standardPrimaryTrackDCA")); + cut->AddCut(GetAnalysisCut("lmeeStandardKine")); + return cut; + } if (!nameStr.compare("jpsiPIDworseRes")) { cut->AddCut(GetAnalysisCut("jpsiStandardKine")); @@ -5058,6 +5095,42 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) cut->AddCut(VarManager::kTrackDCAz, -1.0, 1.0); return cut; } + + TF1* fDCAxyresLow = new TF1("fDCAxyresLow", "[0] + [1] * pow(x, -[2])", 0.1, 1000.); + TF1* fDCAzresLow = new TF1("fDCAzresLow", "[0] + [1] * pow(x, -[2])", 0.1, 1000.); + TF1* fDCAxyresUp = new TF1("fDCAxyresUp", "[0] + [1] * pow(x, -[2])", 0.1, 1000.); + TF1* fDCAzresUp = new TF1("fDCAzresUp", "[0] + [1] * pow(x, -[2])", 0.1, 1000.); + + if (!nameStr.compare("electronPrimary_dca3sigma")) { + // DCAxy and DCAz 3 sigma cut. DCA resolution vs pt extracted from fits of Users/m/mfaggin/test/inputsTrackTuner/pp2024/pass1_minBias/vsPhi (used for the track tuner) + // we add in addition a term for the misalignment of the mean of the distribution, which seems to be at most 20 mum for DCAxy and 10 mum for DCAz + fDCAxyresLow->SetParameters(-3 * 8.7e-4 - 20e-4, -3 * 25.4e-4, 0.79); // res is 8.7 + 25.4/pt^0.79 mum + fDCAzresLow->SetParameters(-3 * 9.4e-4 - 10e-4, -3 * 26.5e-4, 0.79); // res is 9.4 + 26.5/pt^0.79 mum + fDCAxyresUp->SetParameters(3 * 8.7e-4 + 20e-4, 3 * 25.4e-4, 0.79); // res is 8.7 + 25.4/pt^0.79 mum + fDCAzresUp->SetParameters(3 * 9.4e-4 + 10e-4, 3 * 26.5e-4, 0.79); // res is 9.4 + 26.5/pt^0.79 mum + cut->AddCut(VarManager::kTrackDCAxy, fDCAxyresLow, fDCAxyresUp, false, VarManager::kPt, 0.2, 1000.); + cut->AddCut(VarManager::kTrackDCAz, fDCAzresLow, fDCAzresUp, false, VarManager::kPt, 0.2, 1000.); + cut->AddCut(VarManager::kIsITSibFirst, 0.5, 1.5); + cut->AddCut(VarManager::kITSchi2, 0.0, 5.0); + cut->AddCut(VarManager::kTPCchi2, 0.0, 4.0); + cut->AddCut(VarManager::kTPCncls, 100, 161.); + return cut; + } + + if (!nameStr.compare("electronPrimary_dca7sigma")) { + // DCAxy and DCAz 7 sigma cut + fDCAxyresLow->SetParameters(-7 * 8.7e-4 - 20e-4, -7 * 25.4e-4, 0.79); + fDCAzresLow->SetParameters(-7 * 9.4e-4 - 10e-4, -7 * 26.5e-4, 0.79); + fDCAxyresUp->SetParameters(7 * 8.7e-4 + 20e-4, 7 * 25.4e-4, 0.79); + fDCAzresUp->SetParameters(7 * 9.4e-4 + 10e-4, 7 * 26.5e-4, 0.79); + cut->AddCut(VarManager::kTrackDCAxy, fDCAxyresLow, fDCAxyresUp, false, VarManager::kPt, 0.2, 1000.); + cut->AddCut(VarManager::kTrackDCAz, fDCAzresLow, fDCAzresUp, false, VarManager::kPt, 0.2, 1000.); + cut->AddCut(VarManager::kIsITSibFirst, 0.5, 1.5); + cut->AddCut(VarManager::kITSchi2, 0.0, 5.0); + cut->AddCut(VarManager::kTPCchi2, 0.0, 4.0); + cut->AddCut(VarManager::kTPCncls, 100, 161.); + return cut; + } if (!nameStr.compare("dcaCut1_ionut")) { cut->AddCut(VarManager::kTrackDCAxy, -0.5, 0.5); diff --git a/PWGDQ/Tasks/DalitzSelection.cxx b/PWGDQ/Tasks/DalitzSelection.cxx index c3768b02918..5dada7841ec 100644 --- a/PWGDQ/Tasks/DalitzSelection.cxx +++ b/PWGDQ/Tasks/DalitzSelection.cxx @@ -70,81 +70,142 @@ constexpr static uint32_t gkTrackFillMap = VarManager::ObjTypes::Track | VarMana struct dalitzPairing { Produces dalitzbits; - Preslice perCollision = aod::track::collisionId; + Preslice perCollision = aod::track::collisionId; // Configurables - Configurable fConfigEventCuts{"cfgEventCuts", "eventStandardNoINT7", "Event selection"}; - Configurable fConfigDalitzTrackCuts{"cfgDalitzTrackCuts", "", "Dalitz track selection cuts, separated by a comma"}; - Configurable fConfigDalitzPairCuts{"cfgDalitzPairCuts", "", "Dalitz pair selection cuts"}; - Configurable fConfigAddTrackHistogram{"cfgAddTrackHistogram", "", "Comma separated list of histograms"}; - Configurable fQA{"cfgQA", true, "QA histograms"}; - Configurable fConfigBarrelTrackPINLow{"cfgBarrelLowPIN", 0.1f, "Low pt cut for Dalitz tracks in the barrel"}; - Configurable fConfigEtaCut{"cfgEtaCut", 0.9f, "Eta cut for Dalitz tracks in the barrel"}; - Configurable fConfigTPCNSigLow{"cfgTPCNSigElLow", -3.f, "Low TPCNSigEl cut for Dalitz tracks in the barrel"}; - Configurable fConfigTPCNSigHigh{"cfgTPCNSigElHigh", 3.f, "High TPCNsigEl cut for Dalitz tracks in the barrel"}; - // Configurables for TPC post-calibration maps - Configurable fConfigCcdbUrl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; - Configurable fConfigCcdbPathTPC{"ccdb-path-tpc", "Users/i/iarsene/Calib/TPCpostCalib", "base path to the ccdb object"}; - Configurable fConfigNoLaterThan{"ccdb-no-later-than", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable timestamp of creation for the object"}; - Configurable fConfigComputeTPCpostCalib{"cfgTPCpostCalib", false, "If true, compute TPC post-calibrated n-sigmas"}; - Configurable fUseRemoteField{"cfgUseRemoteField", false, "Chose whether to fetch the magnetic field from ccdb or set it manually"}; - Configurable fConfigMagField{"cfgMagField", 5.0f, "Manually set magnetic field"}; - Configurable grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; + // cuts + struct : ConfigurableGroup { + Configurable fConfigEventCuts{"cfgEventCuts", "eventStandardNoINT7", "Event selection"}; + Configurable fConfigDalitzTrackCuts{"cfgDalitzTrackCuts", "", "Dalitz track selection cuts for tag, separated by a comma"}; + Configurable fConfigDalitzTrackCutsProbe{"cfgDalitzTrackCutsProbe", "", "Dalitz track selection cuts for probe, separated by a comma (if empty, use same selections as the tag)"}; + Configurable fConfigDalitzPairCuts{"cfgDalitzPairCuts", "", "Dalitz pair selection cuts"}; + Configurable fConfigTrackCutsJSON{"cfgTrackCutsJSON", "", "Additional list of barrel track cuts in JSON format"}; + Configurable fConfigTrackCutsProbeJSON{"cfgTrackCutsProbeJSON", "", "Additional list of barrel track cuts for the probe in JSON format"}; + Configurable fConfigPairCutsJSON{"cfgPairCutsJSON", "", "Additional list of barrel track cuts in JSON format"}; + Configurable fConfigBarrelTrackPINLow{"cfgBarrelLowPIN", 0.1f, "Low pt cut for Dalitz tracks in the barrel"}; + Configurable fConfigEtaCut{"cfgEtaCut", 0.9f, "Eta cut for Dalitz tracks in the barrel"}; + Configurable fConfigTPCNSigLow{"cfgTPCNSigElLow", -3.f, "Low TPCNSigEl cut for Dalitz tracks in the barrel"}; + Configurable fConfigTPCNSigHigh{"cfgTPCNSigElHigh", 3.f, "High TPCNsigEl cut for Dalitz tracks in the barrel"}; + } fConfigCuts; + + // histograms + struct : ConfigurableGroup { + Configurable fConfigAddTrackHistogram{"cfgAddTrackHistogram", "", "Comma separated list of histograms"}; + Configurable fConfigAddPairHistogram{"cfgAddPairHistogram", "", "Comma separated list of histograms"}; + Configurable fConfigAddJSONHistograms{"cfgAddJSONHistograms", "", "Histograms in JSON format for tracks"}; + } fConfigHistograms; + + // additional options + struct : ConfigurableGroup { + Configurable fConfigEnableLikeSign{"cfgEnableLikeSign", false, "Whether or not also add like-sign pairs (for studying combinatorial background which might contain misID or non-primary electrons)"}; + Configurable fQA{"cfgQA", true, "QA histograms"}; + // Configurables for TPC post-calibration maps + Configurable fConfigCcdbUrl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable fConfigCcdbPathTPC{"ccdb-path-tpc", "Users/i/iarsene/Calib/TPCpostCalib", "base path to the ccdb object"}; + Configurable fConfigNoLaterThan{"ccdb-no-later-than", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable timestamp of creation for the object"}; + Configurable fConfigComputeTPCpostCalib{"cfgTPCpostCalib", false, "If true, compute TPC post-calibrated n-sigmas"}; + Configurable fUseRemoteField{"cfgUseRemoteField", true, "Chose whether to fetch the magnetic field from ccdb or set it manually"}; + Configurable fConfigMagField{"cfgMagField", 5.0f, "Manually set magnetic field"}; + Configurable grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; + } fConfigOptions; Service fCCDB; o2::parameters::GRPMagField* grpmag = nullptr; int fCurrentRun; // needed to detect if the run changed and trigger update of calibrations etc. - Filter filterBarrelTrack = o2::aod::track::tpcInnerParam >= fConfigBarrelTrackPINLow && nabs(o2::aod::track::eta) <= fConfigEtaCut && o2::aod::pidtpc::tpcNSigmaEl <= fConfigTPCNSigHigh && o2::aod::pidtpc::tpcNSigmaEl >= fConfigTPCNSigLow; + Filter filterBarrelTrack = o2::aod::track::tpcInnerParam >= fConfigCuts.fConfigBarrelTrackPINLow && nabs(o2::aod::track::eta) <= fConfigCuts.fConfigEtaCut && o2::aod::pidtpc::tpcNSigmaEl <= fConfigCuts.fConfigTPCNSigHigh && o2::aod::pidtpc::tpcNSigmaEl >= fConfigCuts.fConfigTPCNSigLow; OutputObj fOutputList{"output"}; //! the histogram manager output list OutputObj fStatsList{"Statistics"}; //! skimming statistics - std::map fTrackmap; - std::map fDalitzmap; + std::map fTrackmap; // whether it is selected with symmetric or tag cut + std::map fTrackmapProbe; // whether it is selected with probe cut + std::map fDalitzmap; // whether it is selected as dalitz decay daughter with symmetric or tag cut + std::map fDalitzmapProbe; // whether it is selected as dalitz decay daughter with probe cut AnalysisCompositeCut* fEventCut; std::vector fTrackCuts; + std::vector fTrackCutsProbe; std::vector fPairCuts; + + bool fIsTagAndProbe; // whether we are doing tag and probe, or just symmetric cuts HistogramManager* fHistMan; void init(o2::framework::InitContext&) { + fIsTagAndProbe = false; + // Event cuts fEventCut = new AnalysisCompositeCut(true); - TString eventCutStr = fConfigEventCuts.value; + TString eventCutStr = fConfigCuts.fConfigEventCuts.value; fEventCut->AddCut(dqcuts::GetAnalysisCut(eventCutStr.Data())); // Barrel track cuts - TString cutNamesStr = fConfigDalitzTrackCuts.value; + // Tag cuts or symmetric cuts + TString cutNamesStr = fConfigCuts.fConfigDalitzTrackCuts.value; if (!cutNamesStr.IsNull()) { std::unique_ptr objArray(cutNamesStr.Tokenize(",")); for (int icut = 0; icut < objArray->GetEntries(); ++icut) { fTrackCuts.push_back(*dqcuts::GetCompositeCut(objArray->At(icut)->GetName())); } } + // extra cuts via JSON + TString addTrackCutsStr = fConfigCuts.fConfigTrackCutsJSON.value; + if (addTrackCutsStr != "") { + std::vector addTrackCuts = dqcuts::GetCutsFromJSON(addTrackCutsStr.Data()); + for (auto& t : addTrackCuts) { + fTrackCuts.push_back(reinterpret_cast(t)); + } + } + + // Probe cuts + TString cutNamesProbeStr = fConfigCuts.fConfigDalitzTrackCutsProbe.value; + TString addTrackCutsProbeStr = fConfigCuts.fConfigTrackCutsProbeJSON.value; + if (!cutNamesProbeStr.IsNull() && (cutNamesProbeStr.CompareTo(cutNamesStr) != 0 || addTrackCutsProbeStr.CompareTo(addTrackCutsStr) != 0)) { + std::unique_ptr objArray(cutNamesProbeStr.Tokenize(",")); + for (int icut = 0; icut < objArray->GetEntries(); ++icut) { + fTrackCutsProbe.push_back(*dqcuts::GetCompositeCut(objArray->At(icut)->GetName())); + } + fIsTagAndProbe = true; + } + // extra cuts via JSON + if (addTrackCutsProbeStr != "" && (cutNamesProbeStr.CompareTo(cutNamesStr) != 0 || addTrackCutsProbeStr.CompareTo(addTrackCutsStr) != 0)) { + std::vector addTrackCuts = dqcuts::GetCutsFromJSON(addTrackCutsProbeStr.Data()); + for (auto& t : addTrackCuts) { + fTrackCutsProbe.push_back(reinterpret_cast(t)); + } + fIsTagAndProbe = true; + } // Pair cuts - TString cutNamesPairStr = fConfigDalitzPairCuts.value; + TString cutNamesPairStr = fConfigCuts.fConfigDalitzPairCuts.value; if (!cutNamesPairStr.IsNull()) { std::unique_ptr objArray(cutNamesPairStr.Tokenize(",")); for (int icut = 0; icut < objArray->GetEntries(); ++icut) { fPairCuts.push_back(*dqcuts::GetCompositeCut(objArray->At(icut)->GetName())); } } + // extra cuts via JSON + TString addPairCutsStr = fConfigCuts.fConfigPairCutsJSON.value; + if (addPairCutsStr != "") { + std::vector addPairCuts = dqcuts::GetCutsFromJSON(addPairCutsStr.Data()); + for (auto& t : addPairCuts) { + fPairCuts.push_back(reinterpret_cast(t)); + } + } - if (fTrackCuts.size() != fPairCuts.size()) { + if (fTrackCuts.size() != fPairCuts.size() || (fTrackCuts.size() != fTrackCutsProbe.size() && fIsTagAndProbe)) { LOGF(fatal, "YOU SHOULD PROVIDE THE SAME NUMBER OF TRACK AND PAIR CUTS"); } // CCDB configuration - if (fConfigComputeTPCpostCalib) { - fCCDB->setURL(fConfigCcdbUrl.value); + if (fConfigOptions.fConfigComputeTPCpostCalib) { + fCCDB->setURL(fConfigOptions.fConfigCcdbUrl.value); fCCDB->setCaching(true); fCCDB->setLocalObjectValidityChecking(); // Not later than now objects - fCCDB->setCreatedNotAfter(fConfigNoLaterThan.value); + fCCDB->setCreatedNotAfter(fConfigOptions.fConfigNoLaterThan.value); } VarManager::SetUseVars(AnalysisCut::fgUsedVars); // provide the list of required variables so that VarManager knows what to fill @@ -156,11 +217,25 @@ struct dalitzPairing { // Create the histogram class names to be added to the histogram manager TString histClasses = ""; - if (fQA) { + if (fConfigOptions.fQA) { auto trackCut = fTrackCuts.begin(); - for (auto pairCut = fPairCuts.begin(); pairCut != fPairCuts.end(); pairCut++, trackCut++) { - histClasses += Form("TrackBarrel_%s_%s;", (*trackCut).GetName(), (*pairCut).GetName()); - histClasses += Form("Pair_%s_%s;", (*trackCut).GetName(), (*pairCut).GetName()); + int iCut = 0; + for (auto pairCut = fPairCuts.begin(); pairCut != fPairCuts.end(); pairCut++, trackCut++, iCut++) { + if (fIsTagAndProbe) { + histClasses += Form("TrackBarrelTag_%s_%s_%s;", (*trackCut).GetName(), fTrackCutsProbe.at(iCut).GetName(), (*pairCut).GetName()); + histClasses += Form("TrackBarrelProbe_%s_%s_%s;", (*trackCut).GetName(), fTrackCutsProbe.at(iCut).GetName(), (*pairCut).GetName()); + histClasses += Form("Pair_%s_%s_%s;", (*trackCut).GetName(), fTrackCutsProbe.at(iCut).GetName(), (*pairCut).GetName()); + if (fConfigOptions.fConfigEnableLikeSign) { + histClasses += Form("Pair_LS_%s_%s_%s;", (*trackCut).GetName(), fTrackCutsProbe.at(iCut).GetName(), (*pairCut).GetName()); + } + } + else { + histClasses += Form("TrackBarrel_%s_%s;", (*trackCut).GetName(), (*pairCut).GetName()); + histClasses += Form("Pair_%s_%s;", (*trackCut).GetName(), (*pairCut).GetName()); + if (fConfigOptions.fConfigEnableLikeSign) { + histClasses += Form("Pair_LS_%s_%s;", (*trackCut).GetName(), (*pairCut).GetName()); + } + } } } @@ -174,28 +249,43 @@ struct dalitzPairing { if (classStr.Contains("Event")) { dqhistograms::DefineHistograms(fHistMan, objArray->At(iclass)->GetName(), "event", ""); } - TString histTrackName = fConfigAddTrackHistogram.value; + + TString histTrackName = fConfigHistograms.fConfigAddTrackHistogram.value; if (classStr.Contains("Track")) { dqhistograms::DefineHistograms(fHistMan, objArray->At(iclass)->GetName(), "track", histTrackName); + dqhistograms::DefineHistograms(fHistMan, objArray->At(iclass)->GetName(), "software-trigger", histTrackName); } + TString histPairName = fConfigHistograms.fConfigAddPairHistogram.value; if (classStr.Contains("Pair")) { - dqhistograms::DefineHistograms(fHistMan, objArray->At(iclass)->GetName(), "pair", "barreldalitz"); + dqhistograms::DefineHistograms(fHistMan, objArray->At(iclass)->GetName(), "pair", histPairName); } } + + // Additional histogram via the JSON configurable + TString addHistsStr = fConfigHistograms.fConfigAddJSONHistograms.value; + if (addHistsStr != "") { + dqhistograms::AddHistogramsFromJSON(fHistMan, addHistsStr.Data()); + } fStatsList.setObject(new TList()); fStatsList->SetOwner(kTRUE); // Dalitz selection statistics: one bin for each (track,pair) selection - TH1I* histTracks = new TH1I("TrackStats", "Dalitz selection statistics", fPairCuts.size() + 1, -0.5, fPairCuts.size() + 0.5); + TH1I* histTracks = new TH1I("TrackStats", "Dalitz selection statistics", fPairCuts.size() * (1 + fIsTagAndProbe) + 1, -0.5, fPairCuts.size() * (1 + fIsTagAndProbe) + 0.5); histTracks->GetXaxis()->SetBinLabel(1, "Events selected"); auto trackCut = fTrackCuts.begin(); int icut = 1; for (auto pairCut = fPairCuts.begin(); pairCut != fPairCuts.end(); pairCut++, trackCut++, icut++) { - histTracks->GetXaxis()->SetBinLabel(icut + 1, Form("%s_%s", (*trackCut).GetName(), (*pairCut).GetName())); + if (fIsTagAndProbe) { + histTracks->GetXaxis()->SetBinLabel(2*icut, Form("%s_%s_%s tag", (*trackCut).GetName(), fTrackCutsProbe.at(icut-1).GetName(), (*pairCut).GetName())); + histTracks->GetXaxis()->SetBinLabel(2*icut + 1, Form("%s_%s_%s probe", (*trackCut).GetName(), fTrackCutsProbe.at(icut-1).GetName(), (*pairCut).GetName())); + } + else { + histTracks->GetXaxis()->SetBinLabel(icut + 1, Form("%s_%s", (*trackCut).GetName(), (*pairCut).GetName())); + } } - if (fQA) { + if (fConfigOptions.fQA) { fStatsList->Add(histTracks); } @@ -208,6 +298,7 @@ struct dalitzPairing { { for (auto& track : tracksBarrel) { uint8_t filterMap = uint8_t(0); + uint8_t filterMapProbe = uint8_t(0); VarManager::FillTrack(track); int i = 0; for (auto cut = fTrackCuts.begin(); cut != fTrackCuts.end(); ++cut, ++i) { @@ -215,23 +306,41 @@ struct dalitzPairing { filterMap |= (uint8_t(1) << i); } } + if (fIsTagAndProbe) { + i = 0; + for (auto cut = fTrackCutsProbe.begin(); cut != fTrackCutsProbe.end(); ++cut, ++i) { + if ((*cut).IsSelected(VarManager::fgValues)) { + filterMapProbe |= (uint8_t(1) << i); + } + } + } if (filterMap) { fTrackmap[track.globalIndex()] = filterMap; } + if (filterMapProbe) { + fTrackmapProbe[track.globalIndex()] = filterMapProbe; + } } // end loop over tracks } template void runDalitzPairing(TTracks const& tracks1, TTracks const& tracks2) { - for (auto& [track1, track2] : o2::soa::combinations(CombinationsStrictlyUpperIndexPolicy(tracks1, tracks2))) { - if (track1.sign() * track2.sign() > 0) { + for (auto& [track1, track2] : o2::soa::combinations(CombinationsFullIndexPolicy(tracks1, tracks2))) { + if (track1.globalIndex() == track2.globalIndex()) { + continue; + } + if (!fIsTagAndProbe && track1.globalIndex() >= track2.globalIndex()) { + continue; + } + if (!fConfigOptions.fConfigEnableLikeSign && track1.sign() * track2.sign() > 0) { continue; } - uint8_t twoTracksFilterMap = fTrackmap[track1.globalIndex()] & fTrackmap[track2.globalIndex()]; - if (!twoTracksFilterMap) + uint8_t twoTracksFilterMap = fTrackmap[track1.globalIndex()] & (fIsTagAndProbe ? fTrackmapProbe[track2.globalIndex()] : fTrackmap[track2.globalIndex()]); + if (!twoTracksFilterMap) { continue; + } // pairing VarManager::FillPair(track1, track2); @@ -244,20 +353,37 @@ struct dalitzPairing { continue; } if ((*pairCut).IsSelected(VarManager::fgValues)) { - fDalitzmap[track1.globalIndex()] |= (uint8_t(1) << icut); - fDalitzmap[track2.globalIndex()] |= (uint8_t(1) << icut); - if (fQA) { - fHistMan->FillHistClass(Form("Pair_%s_%s", (*trackCut).GetName(), (*pairCut).GetName()), VarManager::fgValues); + if (track1.sign() * track2.sign() < 0) { + fDalitzmap[track1.globalIndex()] |= (uint8_t(1) << icut); + if (fIsTagAndProbe) { + fDalitzmapProbe[track2.globalIndex()] |= (uint8_t(1) << icut); + if (fConfigOptions.fQA) { + fHistMan->FillHistClass(Form("Pair_%s_%s_%s", (*trackCut).GetName(), fTrackCutsProbe.at(icut).GetName(), (*pairCut).GetName()), VarManager::fgValues); + } + } + else { + fDalitzmap[track2.globalIndex()] |= (uint8_t(1) << icut); + if (fConfigOptions.fQA) { + fHistMan->FillHistClass(Form("Pair_%s_%s", (*trackCut).GetName(), (*pairCut).GetName()), VarManager::fgValues); + } + } } - } - } + else { + if (fConfigOptions.fQA) { + fHistMan->FillHistClass(fIsTagAndProbe ? Form("PairLS_%s_%s_%s", (*trackCut).GetName(), fTrackCutsProbe.at(icut).GetName(), (*pairCut).GetName()) : Form("PairLS_%s_%s", (*trackCut).GetName(), (*pairCut).GetName()), VarManager::fgValues); + } + } // end if like-sign + } // end if isSelected + } // end cut loop } // end of tracksP,N loop + // Fill Hists - if (fQA) { + if (fConfigOptions.fQA) { for (auto& track : tracks1) { uint8_t filterMap = fDalitzmap[track.globalIndex()]; - if (!filterMap) { + uint8_t filterMapProbe = fDalitzmapProbe[track.globalIndex()]; + if (!filterMap && !filterMapProbe) { continue; } VarManager::FillTrack(track); @@ -266,21 +392,27 @@ struct dalitzPairing { auto trackCut = fTrackCuts.begin(); for (auto pairCut = fPairCuts.begin(); pairCut != fPairCuts.end(); pairCut++, trackCut++, icut++) { if (filterMap & (uint8_t(1) << icut)) { - reinterpret_cast(fStatsList->At(0))->Fill(icut + 1); - fHistMan->FillHistClass(Form("TrackBarrel_%s_%s", (*trackCut).GetName(), (*pairCut).GetName()), VarManager::fgValues); + reinterpret_cast(fStatsList->At(0))->Fill(fIsTagAndProbe ? 2*icut + 1 : icut + 1); + fHistMan->FillHistClass(fIsTagAndProbe ? Form("TrackBarrelTag_%s_%s_%s", (*trackCut).GetName(), fTrackCutsProbe.at(icut).GetName(), (*pairCut).GetName()) : Form("TrackBarrel_%s_%s", (*trackCut).GetName(), (*pairCut).GetName()), VarManager::fgValues); + } + if (filterMapProbe & (uint8_t(1) << icut)) { + reinterpret_cast(fStatsList->At(0))->Fill(2*icut + 2); + fHistMan->FillHistClass(Form("TrackBarrelProbe_%s_%s_%s", (*trackCut).GetName(), fTrackCutsProbe.at(icut).GetName(), (*pairCut).GetName()), VarManager::fgValues); } } } } } - void processFullTracks(MyEvents const& collisions, aod::BCsWithTimestamps const&, soa::Filtered const& filteredTracks, MyBarrelTracks const& tracks) + void processFullTracks(MyEvents const& collisions, aod::BCsWithTimestamps const&, soa::Filtered const& filteredTracks, aod::Tracks const& tracks) { const int pairType = VarManager::kDecayToEE; fDalitzmap.clear(); + fDalitzmapProbe.clear(); for (auto& collision : collisions) { fTrackmap.clear(); + fTrackmapProbe.clear(); VarManager::ResetValues(VarManager::kNRunWiseVariables, VarManager::kNBarrelTrackVariables); VarManager::FillEvent(collision); bool isEventSelected = fEventCut->IsSelected(VarManager::fgValues); @@ -296,15 +428,15 @@ struct dalitzPairing { // We setup the magnetic field, because the conversion rejection cut might depend on it float magField = 0.; - if (fUseRemoteField.value) { - grpmag = fCCDB->getForTimeStamp(grpmagPath, bc.timestamp()); + if (fConfigOptions.fUseRemoteField.value) { + grpmag = fCCDB->getForTimeStamp(fConfigOptions.grpmagPath, bc.timestamp()); if (grpmag != nullptr) { magField = grpmag->getNominalL3Field(); } else { LOGF(fatal, "GRP object is not available in CCDB at timestamp=%llu", bc.timestamp()); } } else { - magField = fConfigMagField.value; + magField = fConfigOptions.fConfigMagField.value; } LOGF(info, "setting mag field to %f", magField); if (magField == 0.) { @@ -312,8 +444,8 @@ struct dalitzPairing { } VarManager::SetMagneticField(magField); - if (fConfigComputeTPCpostCalib) { - auto calibList = fCCDB->getForTimeStamp(fConfigCcdbPathTPC.value, bc.timestamp()); + if (fConfigOptions.fConfigComputeTPCpostCalib) { + auto calibList = fCCDB->getForTimeStamp(fConfigOptions.fConfigCcdbPathTPC.value, bc.timestamp()); VarManager::SetCalibrationObject(VarManager::kTPCElectronMean, calibList->FindObject("mean_map_electron")); VarManager::SetCalibrationObject(VarManager::kTPCElectronSigma, calibList->FindObject("sigma_map_electron")); VarManager::SetCalibrationObject(VarManager::kTPCPionMean, calibList->FindObject("mean_map_pion")); From eff7fba5ea6d8502604dbb625f9903870be875ae Mon Sep 17 00:00:00 2001 From: Gauthier Legras Date: Thu, 23 Apr 2026 18:33:27 +0200 Subject: [PATCH 2/5] clang format --- PWGDQ/Core/CutsLibrary.cxx | 30 +++++++++++------------ PWGDQ/Tasks/DalitzSelection.cxx | 43 +++++++++++++++------------------ 2 files changed, 34 insertions(+), 39 deletions(-) diff --git a/PWGDQ/Core/CutsLibrary.cxx b/PWGDQ/Core/CutsLibrary.cxx index d29bf973e4a..b98d2566a04 100644 --- a/PWGDQ/Core/CutsLibrary.cxx +++ b/PWGDQ/Core/CutsLibrary.cxx @@ -1488,7 +1488,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } } - + if (!nameStr.compare("electronPrimaryTag0")) { // with tight 3 sigma DCA cut for selecting primary electrons cut->AddCut(GetAnalysisCut("electronPID_TPCnsigma_loose")); // 3 sigma inclusion, 3sigma rejection @@ -1496,7 +1496,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) cut->AddCut(GetAnalysisCut("jpsiStandardKine")); return cut; } - + if (!nameStr.compare("electronPrimaryTag1")) { // with 7 sigma DCA cut for selecting primary electrons cut->AddCut(GetAnalysisCut("electronPID_TPCnsigma_loose")); // 3 sigma inclusion, 3sigma rejection @@ -1504,20 +1504,20 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) cut->AddCut(GetAnalysisCut("jpsiStandardKine")); return cut; } - + if (!nameStr.compare("electronPrimaryProbe_TPC")) { cut->AddCut(GetAnalysisCut("electronStandardQualityTPCOnly")); cut->AddCut(GetAnalysisCut("lmeeStandardKine")); return cut; } - + if (!nameStr.compare("electronPrimaryProbe_ITS")) { cut->AddCut(GetAnalysisCut("electronStandardQualitybAnyITSOnly")); cut->AddCut(GetAnalysisCut("standardPrimaryTrackDCA")); cut->AddCut(GetAnalysisCut("lmeeStandardKine")); return cut; } - + if (!nameStr.compare("electronPrimaryProbe_ITSTPC")) { cut->AddCut(GetAnalysisCut("electronStandardQualityTPCOnly")); cut->AddCut(GetAnalysisCut("electronStandardQualitybAnyITSOnly")); @@ -5095,36 +5095,36 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) cut->AddCut(VarManager::kTrackDCAz, -1.0, 1.0); return cut; } - + TF1* fDCAxyresLow = new TF1("fDCAxyresLow", "[0] + [1] * pow(x, -[2])", 0.1, 1000.); TF1* fDCAzresLow = new TF1("fDCAzresLow", "[0] + [1] * pow(x, -[2])", 0.1, 1000.); TF1* fDCAxyresUp = new TF1("fDCAxyresUp", "[0] + [1] * pow(x, -[2])", 0.1, 1000.); TF1* fDCAzresUp = new TF1("fDCAzresUp", "[0] + [1] * pow(x, -[2])", 0.1, 1000.); - + if (!nameStr.compare("electronPrimary_dca3sigma")) { // DCAxy and DCAz 3 sigma cut. DCA resolution vs pt extracted from fits of Users/m/mfaggin/test/inputsTrackTuner/pp2024/pass1_minBias/vsPhi (used for the track tuner) // we add in addition a term for the misalignment of the mean of the distribution, which seems to be at most 20 mum for DCAxy and 10 mum for DCAz fDCAxyresLow->SetParameters(-3 * 8.7e-4 - 20e-4, -3 * 25.4e-4, 0.79); // res is 8.7 + 25.4/pt^0.79 mum - fDCAzresLow->SetParameters(-3 * 9.4e-4 - 10e-4, -3 * 26.5e-4, 0.79); // res is 9.4 + 26.5/pt^0.79 mum - fDCAxyresUp->SetParameters(3 * 8.7e-4 + 20e-4, 3 * 25.4e-4, 0.79); // res is 8.7 + 25.4/pt^0.79 mum - fDCAzresUp->SetParameters(3 * 9.4e-4 + 10e-4, 3 * 26.5e-4, 0.79); // res is 9.4 + 26.5/pt^0.79 mum - cut->AddCut(VarManager::kTrackDCAxy, fDCAxyresLow, fDCAxyresUp, false, VarManager::kPt, 0.2, 1000.); - cut->AddCut(VarManager::kTrackDCAz, fDCAzresLow, fDCAzresUp, false, VarManager::kPt, 0.2, 1000.); + fDCAzresLow->SetParameters(-3 * 9.4e-4 - 10e-4, -3 * 26.5e-4, 0.79); // res is 9.4 + 26.5/pt^0.79 mum + fDCAxyresUp->SetParameters(3 * 8.7e-4 + 20e-4, 3 * 25.4e-4, 0.79); // res is 8.7 + 25.4/pt^0.79 mum + fDCAzresUp->SetParameters(3 * 9.4e-4 + 10e-4, 3 * 26.5e-4, 0.79); // res is 9.4 + 26.5/pt^0.79 mum + cut->AddCut(VarManager::kTrackDCAxy, fDCAxyresLow, fDCAxyresUp, false, VarManager::kPt, 0.2, 1000.); + cut->AddCut(VarManager::kTrackDCAz, fDCAzresLow, fDCAzresUp, false, VarManager::kPt, 0.2, 1000.); cut->AddCut(VarManager::kIsITSibFirst, 0.5, 1.5); cut->AddCut(VarManager::kITSchi2, 0.0, 5.0); cut->AddCut(VarManager::kTPCchi2, 0.0, 4.0); cut->AddCut(VarManager::kTPCncls, 100, 161.); return cut; } - + if (!nameStr.compare("electronPrimary_dca7sigma")) { // DCAxy and DCAz 7 sigma cut fDCAxyresLow->SetParameters(-7 * 8.7e-4 - 20e-4, -7 * 25.4e-4, 0.79); fDCAzresLow->SetParameters(-7 * 9.4e-4 - 10e-4, -7 * 26.5e-4, 0.79); fDCAxyresUp->SetParameters(7 * 8.7e-4 + 20e-4, 7 * 25.4e-4, 0.79); fDCAzresUp->SetParameters(7 * 9.4e-4 + 10e-4, 7 * 26.5e-4, 0.79); - cut->AddCut(VarManager::kTrackDCAxy, fDCAxyresLow, fDCAxyresUp, false, VarManager::kPt, 0.2, 1000.); - cut->AddCut(VarManager::kTrackDCAz, fDCAzresLow, fDCAzresUp, false, VarManager::kPt, 0.2, 1000.); + cut->AddCut(VarManager::kTrackDCAxy, fDCAxyresLow, fDCAxyresUp, false, VarManager::kPt, 0.2, 1000.); + cut->AddCut(VarManager::kTrackDCAz, fDCAzresLow, fDCAzresUp, false, VarManager::kPt, 0.2, 1000.); cut->AddCut(VarManager::kIsITSibFirst, 0.5, 1.5); cut->AddCut(VarManager::kITSchi2, 0.0, 5.0); cut->AddCut(VarManager::kTPCchi2, 0.0, 4.0); diff --git a/PWGDQ/Tasks/DalitzSelection.cxx b/PWGDQ/Tasks/DalitzSelection.cxx index 5dada7841ec..7cf7c22d4a5 100644 --- a/PWGDQ/Tasks/DalitzSelection.cxx +++ b/PWGDQ/Tasks/DalitzSelection.cxx @@ -87,14 +87,14 @@ struct dalitzPairing { Configurable fConfigTPCNSigLow{"cfgTPCNSigElLow", -3.f, "Low TPCNSigEl cut for Dalitz tracks in the barrel"}; Configurable fConfigTPCNSigHigh{"cfgTPCNSigElHigh", 3.f, "High TPCNsigEl cut for Dalitz tracks in the barrel"}; } fConfigCuts; - + // histograms struct : ConfigurableGroup { Configurable fConfigAddTrackHistogram{"cfgAddTrackHistogram", "", "Comma separated list of histograms"}; Configurable fConfigAddPairHistogram{"cfgAddPairHistogram", "", "Comma separated list of histograms"}; Configurable fConfigAddJSONHistograms{"cfgAddJSONHistograms", "", "Histograms in JSON format for tracks"}; } fConfigHistograms; - + // additional options struct : ConfigurableGroup { Configurable fConfigEnableLikeSign{"cfgEnableLikeSign", false, "Whether or not also add like-sign pairs (for studying combinatorial background which might contain misID or non-primary electrons)"}; @@ -118,16 +118,16 @@ struct dalitzPairing { OutputObj fOutputList{"output"}; //! the histogram manager output list OutputObj fStatsList{"Statistics"}; //! skimming statistics - std::map fTrackmap; // whether it is selected with symmetric or tag cut - std::map fTrackmapProbe; // whether it is selected with probe cut - std::map fDalitzmap; // whether it is selected as dalitz decay daughter with symmetric or tag cut - std::map fDalitzmapProbe; // whether it is selected as dalitz decay daughter with probe cut + std::map fTrackmap; // whether it is selected with symmetric or tag cut + std::map fTrackmapProbe; // whether it is selected with probe cut + std::map fDalitzmap; // whether it is selected as dalitz decay daughter with symmetric or tag cut + std::map fDalitzmapProbe; // whether it is selected as dalitz decay daughter with probe cut AnalysisCompositeCut* fEventCut; std::vector fTrackCuts; std::vector fTrackCutsProbe; std::vector fPairCuts; - + bool fIsTagAndProbe; // whether we are doing tag and probe, or just symmetric cuts HistogramManager* fHistMan; @@ -135,7 +135,7 @@ struct dalitzPairing { void init(o2::framework::InitContext&) { fIsTagAndProbe = false; - + // Event cuts fEventCut = new AnalysisCompositeCut(true); TString eventCutStr = fConfigCuts.fConfigEventCuts.value; @@ -158,7 +158,7 @@ struct dalitzPairing { fTrackCuts.push_back(reinterpret_cast(t)); } } - + // Probe cuts TString cutNamesProbeStr = fConfigCuts.fConfigDalitzTrackCutsProbe.value; TString addTrackCutsProbeStr = fConfigCuts.fConfigTrackCutsProbeJSON.value; @@ -228,8 +228,7 @@ struct dalitzPairing { if (fConfigOptions.fConfigEnableLikeSign) { histClasses += Form("Pair_LS_%s_%s_%s;", (*trackCut).GetName(), fTrackCutsProbe.at(iCut).GetName(), (*pairCut).GetName()); } - } - else { + } else { histClasses += Form("TrackBarrel_%s_%s;", (*trackCut).GetName(), (*pairCut).GetName()); histClasses += Form("Pair_%s_%s;", (*trackCut).GetName(), (*pairCut).GetName()); if (fConfigOptions.fConfigEnableLikeSign) { @@ -261,7 +260,7 @@ struct dalitzPairing { dqhistograms::DefineHistograms(fHistMan, objArray->At(iclass)->GetName(), "pair", histPairName); } } - + // Additional histogram via the JSON configurable TString addHistsStr = fConfigHistograms.fConfigAddJSONHistograms.value; if (addHistsStr != "") { @@ -278,10 +277,9 @@ struct dalitzPairing { int icut = 1; for (auto pairCut = fPairCuts.begin(); pairCut != fPairCuts.end(); pairCut++, trackCut++, icut++) { if (fIsTagAndProbe) { - histTracks->GetXaxis()->SetBinLabel(2*icut, Form("%s_%s_%s tag", (*trackCut).GetName(), fTrackCutsProbe.at(icut-1).GetName(), (*pairCut).GetName())); - histTracks->GetXaxis()->SetBinLabel(2*icut + 1, Form("%s_%s_%s probe", (*trackCut).GetName(), fTrackCutsProbe.at(icut-1).GetName(), (*pairCut).GetName())); - } - else { + histTracks->GetXaxis()->SetBinLabel(2 * icut, Form("%s_%s_%s tag", (*trackCut).GetName(), fTrackCutsProbe.at(icut - 1).GetName(), (*pairCut).GetName())); + histTracks->GetXaxis()->SetBinLabel(2 * icut + 1, Form("%s_%s_%s probe", (*trackCut).GetName(), fTrackCutsProbe.at(icut - 1).GetName(), (*pairCut).GetName())); + } else { histTracks->GetXaxis()->SetBinLabel(icut + 1, Form("%s_%s", (*trackCut).GetName(), (*pairCut).GetName())); } } @@ -312,7 +310,7 @@ struct dalitzPairing { if ((*cut).IsSelected(VarManager::fgValues)) { filterMapProbe |= (uint8_t(1) << i); } - } + } } if (filterMap) { fTrackmap[track.globalIndex()] = filterMap; @@ -360,15 +358,13 @@ struct dalitzPairing { if (fConfigOptions.fQA) { fHistMan->FillHistClass(Form("Pair_%s_%s_%s", (*trackCut).GetName(), fTrackCutsProbe.at(icut).GetName(), (*pairCut).GetName()), VarManager::fgValues); } - } - else { + } else { fDalitzmap[track2.globalIndex()] |= (uint8_t(1) << icut); if (fConfigOptions.fQA) { fHistMan->FillHistClass(Form("Pair_%s_%s", (*trackCut).GetName(), (*pairCut).GetName()), VarManager::fgValues); } } - } - else { + } else { if (fConfigOptions.fQA) { fHistMan->FillHistClass(fIsTagAndProbe ? Form("PairLS_%s_%s_%s", (*trackCut).GetName(), fTrackCutsProbe.at(icut).GetName(), (*pairCut).GetName()) : Form("PairLS_%s_%s", (*trackCut).GetName(), (*pairCut).GetName()), VarManager::fgValues); } @@ -377,7 +373,6 @@ struct dalitzPairing { } // end cut loop } // end of tracksP,N loop - // Fill Hists if (fConfigOptions.fQA) { for (auto& track : tracks1) { @@ -392,11 +387,11 @@ struct dalitzPairing { auto trackCut = fTrackCuts.begin(); for (auto pairCut = fPairCuts.begin(); pairCut != fPairCuts.end(); pairCut++, trackCut++, icut++) { if (filterMap & (uint8_t(1) << icut)) { - reinterpret_cast(fStatsList->At(0))->Fill(fIsTagAndProbe ? 2*icut + 1 : icut + 1); + reinterpret_cast(fStatsList->At(0))->Fill(fIsTagAndProbe ? 2 * icut + 1 : icut + 1); fHistMan->FillHistClass(fIsTagAndProbe ? Form("TrackBarrelTag_%s_%s_%s", (*trackCut).GetName(), fTrackCutsProbe.at(icut).GetName(), (*pairCut).GetName()) : Form("TrackBarrel_%s_%s", (*trackCut).GetName(), (*pairCut).GetName()), VarManager::fgValues); } if (filterMapProbe & (uint8_t(1) << icut)) { - reinterpret_cast(fStatsList->At(0))->Fill(2*icut + 2); + reinterpret_cast(fStatsList->At(0))->Fill(2 * icut + 2); fHistMan->FillHistClass(Form("TrackBarrelProbe_%s_%s_%s", (*trackCut).GetName(), fTrackCutsProbe.at(icut).GetName(), (*pairCut).GetName()), VarManager::fgValues); } } From 70bf1d625b14ed0cd3af1ed51684717c4594d751 Mon Sep 17 00:00:00 2001 From: Gauthier Legras Date: Thu, 23 Apr 2026 18:41:33 +0200 Subject: [PATCH 3/5] small fix --- PWGDQ/Tasks/DalitzSelection.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PWGDQ/Tasks/DalitzSelection.cxx b/PWGDQ/Tasks/DalitzSelection.cxx index 7cf7c22d4a5..031adfafe4b 100644 --- a/PWGDQ/Tasks/DalitzSelection.cxx +++ b/PWGDQ/Tasks/DalitzSelection.cxx @@ -70,7 +70,7 @@ constexpr static uint32_t gkTrackFillMap = VarManager::ObjTypes::Track | VarMana struct dalitzPairing { Produces dalitzbits; - Preslice perCollision = aod::track::collisionId; + Preslice perCollision = aod::track::collisionId; // Configurables // cuts @@ -399,7 +399,7 @@ struct dalitzPairing { } } - void processFullTracks(MyEvents const& collisions, aod::BCsWithTimestamps const&, soa::Filtered const& filteredTracks, aod::Tracks const& tracks) + void processFullTracks(MyEvents const& collisions, aod::BCsWithTimestamps const&, soa::Filtered const& filteredTracks, MyBarrelTracks const& tracks) { const int pairType = VarManager::kDecayToEE; fDalitzmap.clear(); From 8926f0255520cb8181c1eb80fd63c55fb728304b Mon Sep 17 00:00:00 2001 From: Gauthier Legras Date: Fri, 24 Apr 2026 11:45:01 +0200 Subject: [PATCH 4/5] fix some linter errors --- PWGDQ/Core/CutsLibrary.cxx | 10 +++++--- PWGDQ/Tasks/DalitzSelection.cxx | 45 ++++++++++++++++++--------------- 2 files changed, 30 insertions(+), 25 deletions(-) diff --git a/PWGDQ/Core/CutsLibrary.cxx b/PWGDQ/Core/CutsLibrary.cxx index b98d2566a04..0c89d356cb3 100644 --- a/PWGDQ/Core/CutsLibrary.cxx +++ b/PWGDQ/Core/CutsLibrary.cxx @@ -29,7 +29,6 @@ #include #include -#include #include #include #include @@ -7765,12 +7764,15 @@ o2::aod::dqmlcuts::BdtScoreConfig o2::aod::dqmlcuts::GetBdtScoreCutsAndConfigFro cutsMl.push_back(binCuts); labelsFlatBin.push_back(Form("%s_cent%.0f_%.0f_pt%.1f_%.1f", cent.c_str(), centMin, centMax, ptMin, ptMax)); LOG(info) << "Added cut for " << Form("%s_cent%.0f_%.0f_pt%.1f_%.1f", cent.c_str(), centMin, centMax, ptMin, ptMax) << " with cuts: ["; + std::string msg = ""; for (size_t i = 0; i < binCuts.size(); ++i) { - std::cout << binCuts[i]; + msg += std::to_string(binCuts[i]); if (i != binCuts.size() - 1) - std::cout << ", "; + msg += ", "; } - std::cout << "] and direction: " << (exclude ? "CutGreater" : "CutSmaller") << std::endl; + msg += "] and direction: "; + msg += (exclude ? "CutGreater" : "CutSmaller"); + LOG(info) << msg; } } diff --git a/PWGDQ/Tasks/DalitzSelection.cxx b/PWGDQ/Tasks/DalitzSelection.cxx index 031adfafe4b..6d55927ebd1 100644 --- a/PWGDQ/Tasks/DalitzSelection.cxx +++ b/PWGDQ/Tasks/DalitzSelection.cxx @@ -9,9 +9,12 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. // -// Task to select electrons from dalitz decay -// It can produce track and pair histograms for selected tracks -// It creates a bitmap with selections to be stored during skimming +// +// \file DalitzSelection.cxx +// \author Gauthier Legras, glegras@uni-muenster.de, gauthier.legras@cern.ch +// \brief Task to select electrons from dalitz decay +// It can produce track and pair histograms for selected tracks +// It creates a bitmap with selections to be stored during skimming // #include "PWGDQ/Core/AnalysisCompositeCut.h" #include "PWGDQ/Core/AnalysisCut.h" @@ -65,10 +68,10 @@ using MyBarrelTracks = soa::Join; -constexpr static uint32_t gkEventFillMap = VarManager::ObjTypes::Collision; -constexpr static uint32_t gkTrackFillMap = VarManager::ObjTypes::Track | VarManager::ObjTypes::TrackExtra | VarManager::ObjTypes::TrackDCA | VarManager::ObjTypes::TrackSelection | VarManager::ObjTypes::TrackPID; +constexpr static uint32_t EventFillMap = VarManager::ObjTypes::Collision; +constexpr static uint32_t TrackFillMap = VarManager::ObjTypes::Track | VarManager::ObjTypes::TrackExtra | VarManager::ObjTypes::TrackDCA | VarManager::ObjTypes::TrackSelection | VarManager::ObjTypes::TrackPID; -struct dalitzPairing { +struct DalitzSelection { Produces dalitzbits; Preslice perCollision = aod::track::collisionId; @@ -154,7 +157,7 @@ struct dalitzPairing { TString addTrackCutsStr = fConfigCuts.fConfigTrackCutsJSON.value; if (addTrackCutsStr != "") { std::vector addTrackCuts = dqcuts::GetCutsFromJSON(addTrackCutsStr.Data()); - for (auto& t : addTrackCuts) { + for (const auto& t : addTrackCuts) { fTrackCuts.push_back(reinterpret_cast(t)); } } @@ -172,7 +175,7 @@ struct dalitzPairing { // extra cuts via JSON if (addTrackCutsProbeStr != "" && (cutNamesProbeStr.CompareTo(cutNamesStr) != 0 || addTrackCutsProbeStr.CompareTo(addTrackCutsStr) != 0)) { std::vector addTrackCuts = dqcuts::GetCutsFromJSON(addTrackCutsProbeStr.Data()); - for (auto& t : addTrackCuts) { + for (const auto& t : addTrackCuts) { fTrackCutsProbe.push_back(reinterpret_cast(t)); } fIsTagAndProbe = true; @@ -190,7 +193,7 @@ struct dalitzPairing { TString addPairCutsStr = fConfigCuts.fConfigPairCutsJSON.value; if (addPairCutsStr != "") { std::vector addPairCuts = dqcuts::GetCutsFromJSON(addPairCutsStr.Data()); - for (auto& t : addPairCuts) { + for (const auto& t : addPairCuts) { fPairCuts.push_back(reinterpret_cast(t)); } } @@ -294,7 +297,7 @@ struct dalitzPairing { template void runTrackSelection(TTracks const& tracksBarrel) { - for (auto& track : tracksBarrel) { + for (const auto& track : tracksBarrel) { uint8_t filterMap = uint8_t(0); uint8_t filterMapProbe = uint8_t(0); VarManager::FillTrack(track); @@ -324,7 +327,7 @@ struct dalitzPairing { template void runDalitzPairing(TTracks const& tracks1, TTracks const& tracks2) { - for (auto& [track1, track2] : o2::soa::combinations(CombinationsFullIndexPolicy(tracks1, tracks2))) { + for (const auto& [track1, track2] : o2::soa::combinations(CombinationsFullIndexPolicy(tracks1, tracks2))) { if (track1.globalIndex() == track2.globalIndex()) { continue; } @@ -375,7 +378,7 @@ struct dalitzPairing { // Fill Hists if (fConfigOptions.fQA) { - for (auto& track : tracks1) { + for (const auto& track : tracks1) { uint8_t filterMap = fDalitzmap[track.globalIndex()]; uint8_t filterMapProbe = fDalitzmapProbe[track.globalIndex()]; if (!filterMap && !filterMapProbe) { @@ -405,11 +408,11 @@ struct dalitzPairing { fDalitzmap.clear(); fDalitzmapProbe.clear(); - for (auto& collision : collisions) { + for (const auto& collision : collisions) { fTrackmap.clear(); fTrackmapProbe.clear(); VarManager::ResetValues(VarManager::kNRunWiseVariables, VarManager::kNBarrelTrackVariables); - VarManager::FillEvent(collision); + VarManager::FillEvent(collision); bool isEventSelected = fEventCut->IsSelected(VarManager::fgValues); if (isEventSelected) { @@ -452,26 +455,26 @@ struct dalitzPairing { } auto groupedFilteredTracks = filteredTracks.sliceBy(perCollision, collision.globalIndex()); - runTrackSelection(groupedFilteredTracks); - runDalitzPairing(groupedFilteredTracks, groupedFilteredTracks); + runTrackSelection(groupedFilteredTracks); + runDalitzPairing(groupedFilteredTracks, groupedFilteredTracks); } } - for (auto& track : tracks) { // Fill dalitz bits + for (const auto& track : tracks) { // Fill dalitz bits dalitzbits(fDalitzmap[track.globalIndex()]); } } - void processDummy(MyEvents&) + void processDummy(MyEvents const&) { } - PROCESS_SWITCH(dalitzPairing, processFullTracks, "Run Dalitz selection on AO2D tables", false); - PROCESS_SWITCH(dalitzPairing, processDummy, "Do nothing", false); + PROCESS_SWITCH(DalitzSelection, processFullTracks, "Run Dalitz selection on AO2D tables", false); + PROCESS_SWITCH(DalitzSelection, processDummy, "Do nothing", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{ - adaptAnalysisTask(cfgc)}; + adaptAnalysisTask(cfgc)}; } From 11646b4d7f1f42c8b63745cc629681dfa9b4eabb Mon Sep 17 00:00:00 2001 From: Gauthier Legras Date: Sun, 26 Apr 2026 12:29:46 +0200 Subject: [PATCH 5/5] define TF1 only when needed --- PWGDQ/Core/CutsLibrary.cxx | 130 +++++++++++++++++++------------------ 1 file changed, 67 insertions(+), 63 deletions(-) diff --git a/PWGDQ/Core/CutsLibrary.cxx b/PWGDQ/Core/CutsLibrary.cxx index 0c89d356cb3..4686339123c 100644 --- a/PWGDQ/Core/CutsLibrary.cxx +++ b/PWGDQ/Core/CutsLibrary.cxx @@ -5095,40 +5095,42 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - TF1* fDCAxyresLow = new TF1("fDCAxyresLow", "[0] + [1] * pow(x, -[2])", 0.1, 1000.); - TF1* fDCAzresLow = new TF1("fDCAzresLow", "[0] + [1] * pow(x, -[2])", 0.1, 1000.); - TF1* fDCAxyresUp = new TF1("fDCAxyresUp", "[0] + [1] * pow(x, -[2])", 0.1, 1000.); - TF1* fDCAzresUp = new TF1("fDCAzresUp", "[0] + [1] * pow(x, -[2])", 0.1, 1000.); - - if (!nameStr.compare("electronPrimary_dca3sigma")) { - // DCAxy and DCAz 3 sigma cut. DCA resolution vs pt extracted from fits of Users/m/mfaggin/test/inputsTrackTuner/pp2024/pass1_minBias/vsPhi (used for the track tuner) - // we add in addition a term for the misalignment of the mean of the distribution, which seems to be at most 20 mum for DCAxy and 10 mum for DCAz - fDCAxyresLow->SetParameters(-3 * 8.7e-4 - 20e-4, -3 * 25.4e-4, 0.79); // res is 8.7 + 25.4/pt^0.79 mum - fDCAzresLow->SetParameters(-3 * 9.4e-4 - 10e-4, -3 * 26.5e-4, 0.79); // res is 9.4 + 26.5/pt^0.79 mum - fDCAxyresUp->SetParameters(3 * 8.7e-4 + 20e-4, 3 * 25.4e-4, 0.79); // res is 8.7 + 25.4/pt^0.79 mum - fDCAzresUp->SetParameters(3 * 9.4e-4 + 10e-4, 3 * 26.5e-4, 0.79); // res is 9.4 + 26.5/pt^0.79 mum - cut->AddCut(VarManager::kTrackDCAxy, fDCAxyresLow, fDCAxyresUp, false, VarManager::kPt, 0.2, 1000.); - cut->AddCut(VarManager::kTrackDCAz, fDCAzresLow, fDCAzresUp, false, VarManager::kPt, 0.2, 1000.); - cut->AddCut(VarManager::kIsITSibFirst, 0.5, 1.5); - cut->AddCut(VarManager::kITSchi2, 0.0, 5.0); - cut->AddCut(VarManager::kTPCchi2, 0.0, 4.0); - cut->AddCut(VarManager::kTPCncls, 100, 161.); - return cut; - } + if (!nameStr.compare("electronPrimary_dca3sigma") || !nameStr.compare("electronPrimary_dca7sigma")) { + TF1* fDCAxyresLow = new TF1("fDCAxyresLow", "[0] + [1] * pow(x, -[2])", 0.1, 1000.); + TF1* fDCAzresLow = new TF1("fDCAzresLow", "[0] + [1] * pow(x, -[2])", 0.1, 1000.); + TF1* fDCAxyresUp = new TF1("fDCAxyresUp", "[0] + [1] * pow(x, -[2])", 0.1, 1000.); + TF1* fDCAzresUp = new TF1("fDCAzresUp", "[0] + [1] * pow(x, -[2])", 0.1, 1000.); + + if (!nameStr.compare("electronPrimary_dca3sigma")) { + // DCAxy and DCAz 3 sigma cut. DCA resolution vs pt extracted from fits of Users/m/mfaggin/test/inputsTrackTuner/pp2024/pass1_minBias/vsPhi (used for the track tuner) + // we add in addition a term for the misalignment of the mean of the distribution, which seems to be at most 20 mum for DCAxy and 10 mum for DCAz + fDCAxyresLow->SetParameters(-3 * 8.7e-4 - 20e-4, -3 * 25.4e-4, 0.79); // res is 8.7 + 25.4/pt^0.79 mum + fDCAzresLow->SetParameters(-3 * 9.4e-4 - 10e-4, -3 * 26.5e-4, 0.79); // res is 9.4 + 26.5/pt^0.79 mum + fDCAxyresUp->SetParameters(3 * 8.7e-4 + 20e-4, 3 * 25.4e-4, 0.79); // res is 8.7 + 25.4/pt^0.79 mum + fDCAzresUp->SetParameters(3 * 9.4e-4 + 10e-4, 3 * 26.5e-4, 0.79); // res is 9.4 + 26.5/pt^0.79 mum + cut->AddCut(VarManager::kTrackDCAxy, fDCAxyresLow, fDCAxyresUp, false, VarManager::kPt, 0.2, 1000.); + cut->AddCut(VarManager::kTrackDCAz, fDCAzresLow, fDCAzresUp, false, VarManager::kPt, 0.2, 1000.); + cut->AddCut(VarManager::kIsITSibFirst, 0.5, 1.5); + cut->AddCut(VarManager::kITSchi2, 0.0, 5.0); + cut->AddCut(VarManager::kTPCchi2, 0.0, 4.0); + cut->AddCut(VarManager::kTPCncls, 100, 161.); + return cut; + } - if (!nameStr.compare("electronPrimary_dca7sigma")) { - // DCAxy and DCAz 7 sigma cut - fDCAxyresLow->SetParameters(-7 * 8.7e-4 - 20e-4, -7 * 25.4e-4, 0.79); - fDCAzresLow->SetParameters(-7 * 9.4e-4 - 10e-4, -7 * 26.5e-4, 0.79); - fDCAxyresUp->SetParameters(7 * 8.7e-4 + 20e-4, 7 * 25.4e-4, 0.79); - fDCAzresUp->SetParameters(7 * 9.4e-4 + 10e-4, 7 * 26.5e-4, 0.79); - cut->AddCut(VarManager::kTrackDCAxy, fDCAxyresLow, fDCAxyresUp, false, VarManager::kPt, 0.2, 1000.); - cut->AddCut(VarManager::kTrackDCAz, fDCAzresLow, fDCAzresUp, false, VarManager::kPt, 0.2, 1000.); - cut->AddCut(VarManager::kIsITSibFirst, 0.5, 1.5); - cut->AddCut(VarManager::kITSchi2, 0.0, 5.0); - cut->AddCut(VarManager::kTPCchi2, 0.0, 4.0); - cut->AddCut(VarManager::kTPCncls, 100, 161.); - return cut; + if (!nameStr.compare("electronPrimary_dca7sigma")) { + // DCAxy and DCAz 7 sigma cut + fDCAxyresLow->SetParameters(-7 * 8.7e-4 - 20e-4, -7 * 25.4e-4, 0.79); + fDCAzresLow->SetParameters(-7 * 9.4e-4 - 10e-4, -7 * 26.5e-4, 0.79); + fDCAxyresUp->SetParameters(7 * 8.7e-4 + 20e-4, 7 * 25.4e-4, 0.79); + fDCAzresUp->SetParameters(7 * 9.4e-4 + 10e-4, 7 * 26.5e-4, 0.79); + cut->AddCut(VarManager::kTrackDCAxy, fDCAxyresLow, fDCAxyresUp, false, VarManager::kPt, 0.2, 1000.); + cut->AddCut(VarManager::kTrackDCAz, fDCAzresLow, fDCAzresUp, false, VarManager::kPt, 0.2, 1000.); + cut->AddCut(VarManager::kIsITSibFirst, 0.5, 1.5); + cut->AddCut(VarManager::kITSchi2, 0.0, 5.0); + cut->AddCut(VarManager::kTPCchi2, 0.0, 4.0); + cut->AddCut(VarManager::kTPCncls, 100, 161.); + return cut; + } } if (!nameStr.compare("dcaCut1_ionut")) { @@ -5487,40 +5489,42 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - TF1* cutLow1 = new TF1("cutLow1", "pol1", 0., 10.); - if (!nameStr.compare("electronPID1")) { - cutLow1->SetParameters(130., -40.0); - cut->AddCut(VarManager::kTPCsignal, 70., 100.); - cut->AddCut(VarManager::kTPCsignal, cutLow1, 100.0, false, VarManager::kPin, 0.5, 3.0); - return cut; - } + if (!nameStr.compare("electronPID1") || !nameStr.compare("electronPID1shiftUp") || !nameStr.compare("electronPID1shiftDown") || !nameStr.compare("electronPID2") || !nameStr.compare("electronPID3")) { + TF1* cutLow1 = new TF1("cutLow1", "pol1", 0., 10.); + if (!nameStr.compare("electronPID1")) { + cutLow1->SetParameters(130., -40.0); + cut->AddCut(VarManager::kTPCsignal, 70., 100.); + cut->AddCut(VarManager::kTPCsignal, cutLow1, 100.0, false, VarManager::kPin, 0.5, 3.0); + return cut; + } - if (!nameStr.compare("electronPID1shiftUp")) { - cut->AddCut(VarManager::kTPCsignal, 70. - 0.85, 100. - 0.85); - cutLow1->SetParameters(130. - 0.85, -40.0); - cut->AddCut(VarManager::kTPCsignal, cutLow1, 100.0 - 0.85, false, VarManager::kPin, 0.5, 3.0); - return cut; - } + if (!nameStr.compare("electronPID1shiftUp")) { + cut->AddCut(VarManager::kTPCsignal, 70. - 0.85, 100. - 0.85); + cutLow1->SetParameters(130. - 0.85, -40.0); + cut->AddCut(VarManager::kTPCsignal, cutLow1, 100.0 - 0.85, false, VarManager::kPin, 0.5, 3.0); + return cut; + } - if (!nameStr.compare("electronPID1shiftDown")) { - cut->AddCut(VarManager::kTPCsignal, 70.0 + 0.85, 100.0 + 0.85); - cutLow1->SetParameters(130. + 0.85, -40.0); - cut->AddCut(VarManager::kTPCsignal, cutLow1, 100.0 + 0.85, false, VarManager::kPin, 0.5, 3.0); - return cut; - } + if (!nameStr.compare("electronPID1shiftDown")) { + cut->AddCut(VarManager::kTPCsignal, 70.0 + 0.85, 100.0 + 0.85); + cutLow1->SetParameters(130. + 0.85, -40.0); + cut->AddCut(VarManager::kTPCsignal, cutLow1, 100.0 + 0.85, false, VarManager::kPin, 0.5, 3.0); + return cut; + } - if (!nameStr.compare("electronPID2")) { - cutLow1->SetParameters(130., -40.0); - cut->AddCut(VarManager::kTPCsignal, 73., 100.); - cut->AddCut(VarManager::kTPCsignal, cutLow1, 100.0, false, VarManager::kPin, 0.5, 3.0); - return cut; - } + if (!nameStr.compare("electronPID2")) { + cutLow1->SetParameters(130., -40.0); + cut->AddCut(VarManager::kTPCsignal, 73., 100.); + cut->AddCut(VarManager::kTPCsignal, cutLow1, 100.0, false, VarManager::kPin, 0.5, 3.0); + return cut; + } - if (!nameStr.compare("electronPID3")) { - cutLow1->SetParameters(130., -40.0); - cut->AddCut(VarManager::kTPCsignal, 60., 110.); - cut->AddCut(VarManager::kTPCsignal, cutLow1, 100.0, false, VarManager::kPin, 0.5, 3.0); - return cut; + if (!nameStr.compare("electronPID3")) { + cutLow1->SetParameters(130., -40.0); + cut->AddCut(VarManager::kTPCsignal, 60., 110.); + cut->AddCut(VarManager::kTPCsignal, cutLow1, 100.0, false, VarManager::kPin, 0.5, 3.0); + return cut; + } } if (!nameStr.compare("electronPIDnsigma")) {