From 0e05eaac3575bc94ab14b530734cf65b5e3bdb8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Ku=C4=8Dera?= <26327373+vkucera@users.noreply.github.com> Date: Mon, 3 Nov 2025 14:30:44 +0100 Subject: [PATCH 1/9] Update skimming --- Tutorials/PWGHF/dpl-config_skim.json | 541 ++++++++++++++++++++++----- Tutorials/PWGHF/run_skim.sh | 27 +- 2 files changed, 471 insertions(+), 97 deletions(-) diff --git a/Tutorials/PWGHF/dpl-config_skim.json b/Tutorials/PWGHF/dpl-config_skim.json index 118a3481248..d2c5278a145 100644 --- a/Tutorials/PWGHF/dpl-config_skim.json +++ b/Tutorials/PWGHF/dpl-config_skim.json @@ -1,7 +1,7 @@ { "internal-dpl-clock": "", "internal-dpl-aod-reader": { - "aod-file-private": "AO2D.root", + "aod-file-private": "@input_skim.txt", "aod-max-io-rate": "0", "time-limit": "0", "orbit-offset-enumeration": "0", @@ -11,96 +11,467 @@ "step-value-enumeration": "1" }, "internal-dpl-aod-spawner": "", - "bc-converter": "", - "timestamp-task": { - "fatalOnInvalidTimestamp": "false", - "verbose": "false", - "rct-path": "RCT/Info/RunInformation", - "orbit-reset-path": "CTP/Calib/OrbitReset", - "ccdb-url": "http://alice-ccdb.cern.ch", - "isRun2MC": "-1" - }, + "internal-dpl-aod-index-builder": "", + "mc-collision-converter": "", "tracks-extra-v002-converter": { - "processV000ToV002": "true", - "processV001ToV002": "false" + "processV000ToV002": "false", + "processV001ToV002": "true" }, "tracks-extra-spawner": "", - "track-propagation": { - "ccdb-url": "http://alice-ccdb.cern.ch", - "lutPath": "GLO/Param/MatLUT", - "geoPath": "GLO/Config/GeometryAligned", - "grpmagPath": "GLO/Config/GRPMagField", - "mVtxPath": "GLO/Calib/MeanVertex", - "minPropagationDistance": "83.0999985", - "useTrackTuner": "false", - "fillTrackTunerTable": "false", - "trackTunerParams": "debugInfo=0|updateTrackDCAs=1|updateTrackCovMat=1|updateCurvature=0|updateCurvatureIU=0|updatePulls=0|isInputFileFromCCDB=1|pathInputFile=Users/m/mfaggin/test/inputsTrackTuner/PbPb2022|nameInputFile=trackTuner_DataLHC22sPass5_McLHC22l1b2_run529397.root|pathFileQoverPt=Users/h/hsharma/qOverPtGraphs|nameFileQoverPt=D0sigma_Data_removal_itstps_MC_LHC22b1b.root|usePvRefitCorrections=0|qOverPtMC=-1.|qOverPtData=-1.", - "axisPtQA": { + "eventselection-run3": { + "timestamp": { + "verbose": "false", + "fatalOnInvalidTimestamp": "false", + "rct-path": "RCT/Info/RunInformation", + "orbit-reset-path": "CTP/Calib/OrbitReset", + "isRun2MC": "-1" + }, + "bcselOpts": { + "amIneeded": "-1", + "triggerBcShift": "0", + "ITSROFrameStartBorderMargin": "-1", + "ITSROFrameEndBorderMargin": "-1", + "TimeFrameStartBorderMargin": "-1", + "TimeFrameEndBorderMargin": "-1", + "checkRunDurationLimits": "false", + "maxInactiveChipsPerLayer": { + "values": [ + "8", + "8", + "8", + "111", + "111", + "195", + "195" + ] + }, + "NumberOfOrbitsPerTF": "-1" + }, + "evselOpts": { + "amIneeded": "-1", + "muonSelection": "0", + "maxDiffZvtxFT0vsPV": "1", + "isMC": "-1", + "confSigmaBCforHighPtTracks": "4", + "TimeIntervalForOccupancyCalculationMin": "-40", + "TimeIntervalForOccupancyCalculationMax": "100", + "TimeRangeVetoOnCollStrict": "10", + "TimeRangeVetoOnCollNarrow": "0.25", + "FT0CamplPerCollCutVetoOnCollInTimeRange": "8000", + "FT0CamplPerCollCutVetoOnCollInROF": "5000", + "EpsilonVzDiffVetoInROF": "0.3", + "UseWeightsForOccupancyEstimator": "true", + "NumberOfOrbitsPerTF": "-1", + "VzDiffNsigma": "3", + "VzDiffMargin": "0.2" + }, + "lumiOpts": { + "amIneeded": "-1" + }, + "ccdburl": "http://alice-ccdb.cern.ch" + }, + "propagation-service": { + "ccdburl": "http://alice-ccdb.cern.ch", + "ccdb": { + "ccdb-url": "http://alice-ccdb.cern.ch", + "lutPath": "GLO/Param/MatLUTInner", + "grpmagPath": "GLO/Config/GRPMagField", + "grpPath": "GLO/GRP/GRP", + "mVtxPath": "GLO/Calib/MeanVertex" + }, + "enabledTables": { + "labels_rows": [ + "V0Indices", + "V0CoresBase", + "V0Covs", + "CascIndices", + "KFCascIndices", + "TraCascIndices", + "StoredCascCores", + "StoredKFCascCores", + "StoredTraCascCores", + "CascCovs", + "KFCascCovs", + "TraCascCovs", + "V0TrackXs", + "CascTrackXs", + "CascBBs", + "V0DauCovs", + "V0DauCovIUs", + "V0TraPosAtDCAs", + "V0TraPosAtIUs", + "V0Ivanovs", + "McV0Labels", + "V0MCCores", + "V0CoreMCLabels", + "V0MCCollRefs", + "McCascLabels", + "McKFCascLabels", + "McTraCascLabels", + "McCascBBTags", + "CascMCCores", + "CascCoreMCLabels", + "CascMCCollRefs", + "CascToTraRefs", + "CascToKFRefs", + "TraToCascRefs", + "KFToCascRefs", + "V0FoundTags", + "CascFoundTags" + ], + "labels_cols": [ + "enable" + ], "values": [ - "0", - "0", - "0.1", - "0.2", - "0.3", - "0.4", - "0.5", - "0.6", - "0.7", - "0.8", - "0.9", - "1", - "1.1", - "1.2", - "1.3", - "1.4", - "1.5", - "1.6", - "1.7", - "1.8", - "1.9", - "2", - "2.2", - "2.4", - "2.6", - "2.8", - "3", - "3.2", - "3.4", - "3.6", - "3.8", - "4", - "4.4", - "4.8", - "5.2", - "5.6", - "6", - "6.5", - "7", - "7.5", - "8", - "9", - "10", - "11", - "12", - "13", - "14", - "15", - "17", - "19", - "21", - "23", - "25", - "30", - "35", - "40", - "50" + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ] ] }, - "processStandard": "false", - "processStandardWithPID": "false", - "processCovarianceMc": "false", - "processCovariance": "true", - "processCovarianceWithPID": "false" + "deduplicationAlgorithm": "1", + "useV0BufferForCascades": "false", + "mc_findableMode": "0", + "refitWithMaterialCorrection": "false", + "v0BuilderOpts": { + "generatePhotonCandidates": "false", + "moveTPCOnlyTracks": "true", + "minCrossedRows": "50", + "dcanegtopv": "0.05", + "dcapostopv": "0.05", + "v0cospa": "0.95", + "dcav0dau": "1", + "v0radius": "0.9", + "maxDaughterEta": "5", + "mc_populateV0MCCoresSymmetric": "true", + "mc_populateV0MCCoresAsymmetric": "false", + "mc_treatPiToMuDecays": "true", + "mc_rapidityWindow": "0.5", + "mc_keepOnlyPhysicalPrimary": "false", + "mc_addGeneratedK0Short": "true", + "mc_addGeneratedLambda": "true", + "mc_addGeneratedAntiLambda": "true", + "mc_addGeneratedGamma": "false", + "mc_addGeneratedGammaMakeCollinear": "true", + "mc_findableDetachedV0": "false" + }, + "cascadeBuilderOpts": { + "useCascadeMomentumAtPrimVtx": "false", + "minCrossedRows": "50", + "dcabachtopv": "0.05", + "cascradius": "0.9", + "casccospa": "0.95", + "dcacascdau": "1", + "lambdaMassWindow": "0.01", + "maxDaughterEta": "5", + "kfTuneForOmega": "false", + "kfConstructMethod": "2", + "kfUseV0MassConstraint": "true", + "kfUseCascadeMassConstraint": "false", + "kfDoDCAFitterPreMinimV0": "true", + "kfDoDCAFitterPreMinimCasc": "true", + "mc_populateCascMCCoresSymmetric": "true", + "mc_populateCascMCCoresAsymmetric": "false", + "mc_addGeneratedXiMinus": "true", + "mc_addGeneratedXiPlus": "true", + "mc_addGeneratedOmegaMinus": "true", + "mc_addGeneratedOmegaPlus": "true", + "mc_treatPiToMuDecays": "true", + "mc_rapidityWindow": "0.5", + "mc_keepOnlyPhysicalPrimary": "false", + "mc_findableDetachedCascade": "false" + }, + "preSelectOpts": { + "preselectOnlyDesiredV0s": "false", + "preselectOnlyDesiredCascades": "false", + "lifetimeCut": { + "labels_rows": "", + "labels_cols": [ + "lifetimeCutK0S", + "lifetimeCutLambda", + "lifetimeCutXi", + "lifetimeCutOmega" + ], + "values": [ + [ + "20", + "60", + "40", + "20" + ] + ] + }, + "massCutPhoton": "0.3", + "massCutK0": { + "labels_rows": "", + "labels_cols": [ + "constant", + "linear", + "expoConstant", + "expoRelax" + ], + "values": [ + [ + "0.00281882007", + "0.00114057004", + "0.00172138005", + "0.500262022" + ] + ] + }, + "massCutLambda": { + "labels_rows": "", + "labels_cols": [ + "constant", + "linear", + "expoConstant", + "expoRelax" + ], + "values": [ + [ + "0.00117517996", + "0.000124098995", + "0.00547936978", + "0.308008999" + ] + ] + }, + "massCutXi": { + "labels_rows": "", + "labels_cols": [ + "constant", + "linear", + "expoConstant", + "expoRelax" + ], + "values": [ + [ + "0.00143209996", + "0.000203560994", + "0.00243186997", + "0.799668014" + ] + ] + }, + "massCutOm": { + "labels_rows": "", + "labels_cols": [ + "constant", + "linear", + "expoConstant", + "expoRelax" + ], + "values": [ + [ + "0.00143209996", + "0.000203560994", + "0.00243186997", + "0.799668014" + ] + ] + }, + "massWindownumberOfSigmas": "20", + "massWindowSafetyMargin": "0.001", + "maxTPCpidNsigma": "5" + }, + "trackTuner": { + "debugInfo": "false", + "updateTrackDCAs": "false", + "updateTrackCovMat": "false", + "updateCurvature": "false", + "updateCurvatureIU": "false", + "updatePulls": "false", + "isInputFileFromCCDB": "false", + "pathInputFile": "", + "nameInputFile": "", + "pathFileQoverPt": "", + "nameFileQoverPt": "", + "usePvRefitCorrections": "false", + "qOverPtMC": "-1", + "qOverPtData": "-1", + "nPhiBins": "0", + "autoDetectDcaCalib": "false" + }, + "trackPropagation": { + "minPropagationDistance": "5", + "useTrackTuner": "false", + "useTrkPid": "false", + "fillTrackTunerTable": "false", + "trackTunerConfigSource": "1", + "trackTunerParams": "debugInfo=0|updateTrackDCAs=1|updateTrackCovMat=1|updateCurvature=0|updateCurvatureIU=0|updatePulls=0|isInputFileFromCCDB=1|pathInputFile=Users/m/mfaggin/test/inputsTrackTuner/PbPb2022|nameInputFile=trackTuner_DataLHC22sPass5_McLHC22l1b2_run529397.root|pathFileQoverPt=Users/h/hsharma/qOverPtGraphs|nameFileQoverPt=D0sigma_Data_removal_itstps_MC_LHC22b1b.root|usePvRefitCorrections=0|qOverPtMC=-1.|qOverPtData=-1.", + "axisPtQA": { + "values": [ + "0", + "0", + "0.1", + "0.2", + "0.3", + "0.4", + "0.5", + "0.6", + "0.7", + "0.8", + "0.9", + "1.0", + "1.1", + "1.2", + "1.3", + "1.4", + "1.5", + "1.6", + "1.7", + "1.8", + "1.9", + "2.0", + "2.2", + "2.4", + "2.6", + "2.8", + "3.0", + "3.2", + "3.4", + "3.6", + "3.8", + "4.0", + "4.4", + "4.8", + "5.2", + "5.6", + "6.0", + "6.5", + "7.0", + "7.5", + "8.0", + "9.0", + "10.0", + "11.0", + "12.0", + "13.0", + "14.0", + "15.0", + "17.0", + "19.0", + "21.0", + "23.0", + "25.0", + "30.0", + "35.0", + "40.0", + "50.0" + ] + } + }, + "processRealData": "false", + "processMonteCarlo": "true", + "processRealDataWithPID": "false", + "processMonteCarloWithPID": "false" }, "track-selection": { "isRun3": "true", diff --git a/Tutorials/PWGHF/run_skim.sh b/Tutorials/PWGHF/run_skim.sh index 3a5b9a6d2e0..1bbbf2f34da 100644 --- a/Tutorials/PWGHF/run_skim.sh +++ b/Tutorials/PWGHF/run_skim.sh @@ -11,7 +11,7 @@ # granted to it by virtue of its status as an Intergovernmental Organization # or submit itself to any jurisdiction. -# @brief Bash script to produce derived data AnalysisResults_trees.root with 2-prong mini skims from Run 3 real-data input for the D0 mini task +# @brief Bash script to produce derived data AnalysisResults_trees.root with 2-prong mini skims from Run 3 input for the D0 mini task # # The input AO2D.root file is expected in the working directory. # @@ -27,24 +27,27 @@ DIR_THIS="$(dirname "$(realpath "$0")")" # O2 configuration file (in the same directory) JSON="$DIR_THIS/dpl-config_skim.json" -# command line options of O2 workflows -OPTIONS=( +# command line options of O2 workflows (required per workflow) +OPTIONS_LOCAL=( -b --configuration json://"$JSON" + --aod-writer-keep "AOD/HFT2PRONG/0" +) + +# command line options of O2 workflows (required only once) +OPTIONS_GLOBAL=( --aod-memory-rate-limit 2000000000 --shm-segment-size 16000000000 --resources-monitoring 2 - --aod-writer-keep "AOD/HFT2PRONG/0" ) -# execute the mini task workflow and its dependencies -# shellcheck disable=SC2086 # Ignore unquoted options. -o2-analysistutorial-hf-skim-creator-mini "${OPTIONS[@]}" | \ -o2-analysis-timestamp "${OPTIONS[@]}" | \ -o2-analysis-trackselection "${OPTIONS[@]}" | \ -o2-analysis-track-propagation "${OPTIONS[@]}" | \ -o2-analysis-bc-converter "${OPTIONS[@]}" | \ -o2-analysis-tracks-extra-v002-converter "${OPTIONS[@]}" \ +# execute the mini skim creator workflow and its dependencies +o2-analysis-trackselection "${OPTIONS_LOCAL[@]}" | \ +o2-analysis-mccollision-converter "${OPTIONS_LOCAL[@]}" | \ +o2-analysis-event-selection-service "${OPTIONS_LOCAL[@]}" | \ +o2-analysis-tracks-extra-v002-converter "${OPTIONS_LOCAL[@]}" | \ +o2-analysis-propagationservice "${OPTIONS_LOCAL[@]}" | \ +o2-analysistutorial-hf-skim-creator-mini "${OPTIONS_LOCAL[@]}" "${OPTIONS_GLOBAL[@]}" \ > "$LOGFILE" 2>&1 # report status From a72316ecd9a641b863783817a8a7e0dab90f756f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Ku=C4=8Dera?= <26327373+vkucera@users.noreply.github.com> Date: Mon, 3 Nov 2025 15:01:33 +0100 Subject: [PATCH 2/9] Update task --- Tutorials/PWGHF/dpl-config_task.json | 718 ++++++++++++++++++--------- Tutorials/PWGHF/run_task.sh | 32 +- 2 files changed, 506 insertions(+), 244 deletions(-) diff --git a/Tutorials/PWGHF/dpl-config_task.json b/Tutorials/PWGHF/dpl-config_task.json index 8da330be6d3..0309c34ee4f 100644 --- a/Tutorials/PWGHF/dpl-config_task.json +++ b/Tutorials/PWGHF/dpl-config_task.json @@ -1,7 +1,7 @@ { "internal-dpl-clock": "", "internal-dpl-aod-reader": { - "aod-file-private": "AnalysisResults_trees.root", + "aod-file-private": "@input_task.txt", "aod-max-io-rate": "0", "time-limit": "0", "orbit-offset-enumeration": "0", @@ -11,234 +11,254 @@ "step-value-enumeration": "1" }, "internal-dpl-aod-spawner": "", - "bc-converter": "", "internal-dpl-aod-index-builder": "", - "timestamp-task": { - "fatalOnInvalidTimestamp": "false", - "verbose": "false", - "rct-path": "RCT/Info/RunInformation", - "orbit-reset-path": "CTP/Calib/OrbitReset", - "ccdb-url": "http://alice-ccdb.cern.ch", - "isRun2MC": "-1" - }, + "mc-collision-converter": "", "tracks-extra-v002-converter": { - "processV000ToV002": "true", - "processV001ToV002": "false" - }, - "bc-selection-task": { - "triggerBcShift": "0", - "ITSROFrameStartBorderMargin": "-1", - "ITSROFrameEndBorderMargin": "-1", - "TimeFrameStartBorderMargin": "-1", - "TimeFrameEndBorderMargin": "-1", - "checkRunDurationLimits": "false", - "processRun2": "false", - "processRun3": "true" + "processV000ToV002": "false", + "processV001ToV002": "true" }, "tracks-extra-spawner": "", - "track-propagation": { - "ccdb-url": "http://alice-ccdb.cern.ch", - "lutPath": "GLO/Param/MatLUT", - "geoPath": "GLO/Config/GeometryAligned", - "grpmagPath": "GLO/Config/GRPMagField", - "mVtxPath": "GLO/Calib/MeanVertex", - "minPropagationDistance": "5", - "useTrackTuner": "true", - "fillTrackTunerTable": "false", - "trackTunerParams": "debugInfo=0|updateTrackDCAs=1|updateTrackCovMat=1|updateCurvature=0|updateCurvatureIU=1|updatePulls=1|isInputFileFromCCDB=1|pathInputFile=Users/m/mfaggin/test/inputsTrackTuner/pp2023/smoothHighPtMC|nameInputFile=trackTuner_DataLHC23fPass1_McLHC23k4b_run535085.root|pathFileQoverPt=Users/h/hsharma/qOverPtGraphs|nameFileQoverPt=D0sigma_Data_removal_itstps_MC_LHC22b1b.root|usePvRefitCorrections=0|qOverPtMC=1|qOverPtData=2|nPhiBins=0", - "axisPtQA": { - "values": [ - "0", - "0", - "0.1", - "0.2", - "0.3", - "0.4", - "0.5", - "0.6", - "0.7", - "0.8", - "0.9", - "1", - "1.1", - "1.2", - "1.3", - "1.4", - "1.5", - "1.6", - "1.7", - "1.8", - "1.9", - "2", - "2.2", - "2.4", - "2.6", - "2.8", - "3", - "3.2", - "3.4", - "3.6", - "3.8", - "4", - "4.4", - "4.8", - "5.2", - "5.6", - "6", - "6.5", - "7", - "7.5", - "8", - "9", - "10", - "11", - "12", - "13", - "14", - "15", - "17", - "19", - "21", - "23", - "25", - "30", - "35", - "40", - "50" - ] + "eventselection-run3": { + "timestamp": { + "verbose": "false", + "fatalOnInvalidTimestamp": "false", + "rct-path": "RCT/Info/RunInformation", + "orbit-reset-path": "CTP/Calib/OrbitReset", + "isRun2MC": "-1" }, - "processStandard": "false", - "processStandardWithPID": "false", - "processCovarianceMc": "false", - "processCovariance": "true", - "processCovarianceWithPID": "false" - }, - "tof-signal": { - "ccdb-url": "http://alice-ccdb.cern.ch", - "ccdb-timestamp": "-1", - "timeShiftCCDBPath": "", - "distanceForGoodMatch": "999", - "distanceForGoodMatchLowMult": "999", - "multThreshold": "0", - "enableQaHistograms": "false", - "processRun3": "true", - "processRun2": "false" - }, - "event-selection-task": { - "muonSelection": "0", - "maxDiffZvtxFT0vsPV": "1", - "isMC": "0", - "TimeIntervalForOccupancyCalculationMin": "-40", - "TimeIntervalForOccupancyCalculationMax": "100", - "TimeBinsForOccupancyCalculation": { - "values": [ - "-40", - "-20", - "0", - "25", - "50", - "75", - "100" - ] + "bcselOpts": { + "amIneeded": "-1", + "triggerBcShift": "0", + "ITSROFrameStartBorderMargin": "-1", + "ITSROFrameEndBorderMargin": "-1", + "TimeFrameStartBorderMargin": "-1", + "TimeFrameEndBorderMargin": "-1", + "checkRunDurationLimits": "false", + "maxInactiveChipsPerLayer": { + "values": [ + "8", + "8", + "8", + "111", + "111", + "195", + "195" + ] + }, + "NumberOfOrbitsPerTF": "-1" }, - "ReferenceOccupanciesInTimeBins": { - "values": [ - "3000", - "1400", - "750", - "1000", - "1750", - "4000" - ] + "evselOpts": { + "amIneeded": "-1", + "muonSelection": "0", + "maxDiffZvtxFT0vsPV": "1", + "isMC": "-1", + "confSigmaBCforHighPtTracks": "4", + "TimeIntervalForOccupancyCalculationMin": "-40", + "TimeIntervalForOccupancyCalculationMax": "100", + "TimeRangeVetoOnCollStrict": "10", + "TimeRangeVetoOnCollNarrow": "0.25", + "FT0CamplPerCollCutVetoOnCollInTimeRange": "8000", + "FT0CamplPerCollCutVetoOnCollInROF": "5000", + "EpsilonVzDiffVetoInROF": "0.3", + "UseWeightsForOccupancyEstimator": "true", + "NumberOfOrbitsPerTF": "-1", + "VzDiffNsigma": "3", + "VzDiffMargin": "0.2" }, - "TimeRangeVetoOnCollStandard": "10", - "TimeRangeVetoOnCollNarrow": "4", - "UseWeightsForOccupancyEstimator": "true", - "processRun2": "false", - "processRun3": "true" - }, - "hf-task-mini-candidate-creator-2prong": { - "magneticField": "5", - "propagateToPCA": "true", - "useAbsDCA": "false", - "maxR": "200", - "maxDZIni": "4", - "minParamChange": "0.001", - "minRelChi2Change": "0.9" + "lumiOpts": { + "amIneeded": "-1" + }, + "ccdburl": "http://alice-ccdb.cern.ch" }, - "pid-multiplicity": { - "processIU": "true", - "processStandard": "false" + "pid-tpc-service": { + "ccdburl": "http://alice-ccdb.cern.ch", + "pidTPC": { + "param-file": "", + "ccdbPath": "Analysis/PID/TPC/Response", + "recoPass": "", + "ccdb-timestamp": "0", + "useNetworkCorrection": "true", + "autofetchNetworks": "true", + "skipTPCOnly": "-1", + "devicesRequiringTPCOnlyPID": { + "values": [ + "photon-conversion-builder" + ] + }, + "networkPathLocally": "network.onnx", + "networkPathCCDB": "Analysis/PID/TPC/ML", + "enableNetworkOptimizations": "false", + "networkSetNumThreads": "0", + "savedEdxsCorrected": "-1", + "useCorrecteddEdx": "false", + "pid-full-el": "-1", + "pid-full-mu": "-1", + "pid-full-pi": "-1", + "pid-full-ka": "-1", + "pid-full-pr": "-1", + "pid-full-de": "-1", + "pid-full-tr": "-1", + "pid-full-he": "-1", + "pid-full-al": "-1", + "pid-tiny-el": "-1", + "pid-tiny-mu": "-1", + "pid-tiny-pi": "-1", + "pid-tiny-ka": "-1", + "pid-tiny-pr": "-1", + "pid-tiny-de": "-1", + "pid-tiny-tr": "-1", + "pid-tiny-he": "-1", + "pid-tiny-al": "-1", + "enableTuneOnDataTable": "-1", + "useNetworkEl": "1", + "useNetworkMu": "0", + "useNetworkPi": "1", + "useNetworkKa": "1", + "useNetworkPr": "1", + "useNetworkDe": "0", + "useNetworkTr": "0", + "useNetworkHe": "0", + "useNetworkAl": "0", + "networkBetaGammaCutoff": "0.45", + "ccdb-path-grplhcif": "GLO/Config/GRPLHCIF" + }, + "processTracksIU": "false", + "processTracksIUWithTracksQA": "false", + "processTracksMCIU": "true" }, - "tpc-pid": { - "param-file": "", + "ft0-corrected-table": { + "resoFT0A": "20", + "resoFT0C": "20", + "addHistograms": "false", + "collisionSystem": "-2", "ccdb-url": "http://alice-ccdb.cern.ch", - "ccdbPath": "Analysis/PID/TPC/Response", - "recoPass": "", - "ccdb-timestamp": "0", - "useNetworkCorrection": "false", - "autofetchNetworks": "true", - "skipTPCOnly": "true", - "networkPathLocally": "network.onnx", - "networkPathCCDB": "Analysis/PID/TPC/ML", - "enableNetworkOptimizations": "true", - "networkSetNumThreads": "0", - "pid-full-el": "-1", - "pid-full-mu": "-1", - "pid-full-pi": "-1", - "pid-full-ka": "-1", - "pid-full-pr": "-1", - "pid-full-de": "-1", - "pid-full-tr": "-1", - "pid-full-he": "-1", - "pid-full-al": "-1", - "pid-tiny-el": "-1", - "pid-tiny-mu": "-1", - "pid-tiny-pi": "-1", - "pid-tiny-ka": "-1", - "pid-tiny-pr": "-1", - "pid-tiny-de": "-1", - "pid-tiny-tr": "-1", - "pid-tiny-he": "-1", - "pid-tiny-al": "-1", - "enableTuneOnDataTable": "-1", - "useNetworkEl": "1", - "useNetworkMu": "1", - "useNetworkPi": "1", - "useNetworkKa": "1", - "useNetworkPr": "1", - "useNetworkDe": "1", - "useNetworkTr": "1", - "useNetworkHe": "1", - "useNetworkAl": "1", - "networkBetaGammaCutoff": "0.45", + "ccdb-path-grplhcif": "GLO/Config/GRPLHCIF", + "ccdb-timestamp": "-1", "processStandard": "true", - "processMcTuneOnData": "false" + "processWithBypassFT0timeInMC": "false" }, - "multiplicity-table": { - "doVertexZeq": "1", - "fractionOfEvents": "2", + "propagation-service": { + "ccdburl": "http://alice-ccdb.cern.ch", + "ccdb": { + "ccdb-url": "http://alice-ccdb.cern.ch", + "lutPath": "GLO/Param/MatLUTInner", + "grpmagPath": "GLO/Config/GRPMagField", + "grpPath": "GLO/GRP/GRP", + "mVtxPath": "GLO/Calib/MeanVertex" + }, "enabledTables": { "labels_rows": [ - "FV0Mults", - "FT0Mults", - "FDDMults", - "ZDCMults", - "TrackletMults", - "TPCMults", - "PVMults", - "MultsExtra", - "MultSelections", - "FV0MultZeqs", - "FT0MultZeqs", - "FDDMultZeqs", - "PVMultZeqs", - "MultMCExtras" + "V0Indices", + "V0CoresBase", + "V0Covs", + "CascIndices", + "KFCascIndices", + "TraCascIndices", + "StoredCascCores", + "StoredKFCascCores", + "StoredTraCascCores", + "CascCovs", + "KFCascCovs", + "TraCascCovs", + "V0TrackXs", + "CascTrackXs", + "CascBBs", + "V0DauCovs", + "V0DauCovIUs", + "V0TraPosAtDCAs", + "V0TraPosAtIUs", + "V0Ivanovs", + "McV0Labels", + "V0MCCores", + "V0CoreMCLabels", + "V0MCCollRefs", + "McCascLabels", + "McKFCascLabels", + "McTraCascLabels", + "McCascBBTags", + "CascMCCores", + "CascCoreMCLabels", + "CascMCCollRefs", + "CascToTraRefs", + "CascToKFRefs", + "TraToCascRefs", + "KFToCascRefs", + "V0FoundTags", + "CascFoundTags" ], "labels_cols": [ - "Enable" + "enable" ], "values": [ + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], [ "-1" ], @@ -283,22 +303,263 @@ ] ] }, - "ccdburl": "http://alice-ccdb.cern.ch", - "ccdbpath": "Centrality/Calibration", - "reconstructionPass": "", - "produceHistograms": "false", - "min_pt_globaltrack": "0.15", - "max_pt_globaltrack": "1e+10", - "min_ncluster_its_globaltrack": "5", - "min_ncluster_itsib_globaltrack": "1", - "processRun2": "false", + "deduplicationAlgorithm": "1", + "useV0BufferForCascades": "false", + "mc_findableMode": "0", + "refitWithMaterialCorrection": "false", + "v0BuilderOpts": { + "generatePhotonCandidates": "false", + "moveTPCOnlyTracks": "true", + "minCrossedRows": "50", + "dcanegtopv": "0.05", + "dcapostopv": "0.05", + "v0cospa": "0.95", + "dcav0dau": "1", + "v0radius": "0.9", + "maxDaughterEta": "5", + "mc_populateV0MCCoresSymmetric": "true", + "mc_populateV0MCCoresAsymmetric": "false", + "mc_treatPiToMuDecays": "true", + "mc_rapidityWindow": "0.5", + "mc_keepOnlyPhysicalPrimary": "false", + "mc_addGeneratedK0Short": "true", + "mc_addGeneratedLambda": "true", + "mc_addGeneratedAntiLambda": "true", + "mc_addGeneratedGamma": "false", + "mc_addGeneratedGammaMakeCollinear": "true", + "mc_findableDetachedV0": "false" + }, + "cascadeBuilderOpts": { + "useCascadeMomentumAtPrimVtx": "false", + "minCrossedRows": "50", + "dcabachtopv": "0.05", + "cascradius": "0.9", + "casccospa": "0.95", + "dcacascdau": "1", + "lambdaMassWindow": "0.01", + "maxDaughterEta": "5", + "kfTuneForOmega": "false", + "kfConstructMethod": "2", + "kfUseV0MassConstraint": "true", + "kfUseCascadeMassConstraint": "false", + "kfDoDCAFitterPreMinimV0": "true", + "kfDoDCAFitterPreMinimCasc": "true", + "mc_populateCascMCCoresSymmetric": "true", + "mc_populateCascMCCoresAsymmetric": "false", + "mc_addGeneratedXiMinus": "true", + "mc_addGeneratedXiPlus": "true", + "mc_addGeneratedOmegaMinus": "true", + "mc_addGeneratedOmegaPlus": "true", + "mc_treatPiToMuDecays": "true", + "mc_rapidityWindow": "0.5", + "mc_keepOnlyPhysicalPrimary": "false", + "mc_findableDetachedCascade": "false" + }, + "preSelectOpts": { + "preselectOnlyDesiredV0s": "false", + "preselectOnlyDesiredCascades": "false", + "lifetimeCut": { + "labels_rows": "", + "labels_cols": [ + "lifetimeCutK0S", + "lifetimeCutLambda", + "lifetimeCutXi", + "lifetimeCutOmega" + ], + "values": [ + [ + "20", + "60", + "40", + "20" + ] + ] + }, + "massCutPhoton": "0.3", + "massCutK0": { + "labels_rows": "", + "labels_cols": [ + "constant", + "linear", + "expoConstant", + "expoRelax" + ], + "values": [ + [ + "0.00281882007", + "0.00114057004", + "0.00172138005", + "0.500262022" + ] + ] + }, + "massCutLambda": { + "labels_rows": "", + "labels_cols": [ + "constant", + "linear", + "expoConstant", + "expoRelax" + ], + "values": [ + [ + "0.00117517996", + "0.000124098995", + "0.00547936978", + "0.308008999" + ] + ] + }, + "massCutXi": { + "labels_rows": "", + "labels_cols": [ + "constant", + "linear", + "expoConstant", + "expoRelax" + ], + "values": [ + [ + "0.00143209996", + "0.000203560994", + "0.00243186997", + "0.799668014" + ] + ] + }, + "massCutOm": { + "labels_rows": "", + "labels_cols": [ + "constant", + "linear", + "expoConstant", + "expoRelax" + ], + "values": [ + [ + "0.00143209996", + "0.000203560994", + "0.00243186997", + "0.799668014" + ] + ] + }, + "massWindownumberOfSigmas": "20", + "massWindowSafetyMargin": "0.001", + "maxTPCpidNsigma": "5" + }, + "trackTuner": { + "debugInfo": "false", + "updateTrackDCAs": "false", + "updateTrackCovMat": "false", + "updateCurvature": "false", + "updateCurvatureIU": "false", + "updatePulls": "false", + "isInputFileFromCCDB": "false", + "pathInputFile": "", + "nameInputFile": "", + "pathFileQoverPt": "", + "nameFileQoverPt": "", + "usePvRefitCorrections": "false", + "qOverPtMC": "-1", + "qOverPtData": "-1", + "nPhiBins": "0", + "autoDetectDcaCalib": "false" + }, + "trackPropagation": { + "minPropagationDistance": "5", + "useTrackTuner": "false", + "useTrkPid": "false", + "fillTrackTunerTable": "false", + "trackTunerConfigSource": "1", + "trackTunerParams": "debugInfo=0|updateTrackDCAs=1|updateTrackCovMat=1|updateCurvature=0|updateCurvatureIU=0|updatePulls=0|isInputFileFromCCDB=1|pathInputFile=Users/m/mfaggin/test/inputsTrackTuner/PbPb2022|nameInputFile=trackTuner_DataLHC22sPass5_McLHC22l1b2_run529397.root|pathFileQoverPt=Users/h/hsharma/qOverPtGraphs|nameFileQoverPt=D0sigma_Data_removal_itstps_MC_LHC22b1b.root|usePvRefitCorrections=0|qOverPtMC=-1.|qOverPtData=-1.", + "axisPtQA": { + "values": [ + "0", + "0", + "0.1", + "0.2", + "0.3", + "0.4", + "0.5", + "0.6", + "0.7", + "0.8", + "0.9", + "1.0", + "1.1", + "1.2", + "1.3", + "1.4", + "1.5", + "1.6", + "1.7", + "1.8", + "1.9", + "2.0", + "2.2", + "2.4", + "2.6", + "2.8", + "3.0", + "3.2", + "3.4", + "3.6", + "3.8", + "4.0", + "4.4", + "4.8", + "5.2", + "5.6", + "6.0", + "6.5", + "7.0", + "7.5", + "8.0", + "9.0", + "10.0", + "11.0", + "12.0", + "13.0", + "14.0", + "15.0", + "17.0", + "19.0", + "21.0", + "23.0", + "25.0", + "30.0", + "35.0", + "40.0", + "50.0" + ] + } + }, + "processRealData": "false", + "processMonteCarlo": "true", + "processRealDataWithPID": "false", + "processMonteCarloWithPID": "false" + }, + "tof-signal": { + "ccdb-url": "http://alice-ccdb.cern.ch", + "ccdb-timestamp": "-1", + "timeShiftCCDBPath": "", + "distanceForGoodMatch": "999", + "distanceForGoodMatchLowMult": "999", + "multThreshold": "0", + "enableQaHistograms": "false", "processRun3": "true", - "processGlobalTrackingCounters": "false", - "processMC": "false", - "processMC2Mults": "false" + "processRun2": "false" + }, + "hf-task-mini-candidate-creator-2prong": { + "magneticField": "5", + "propagateToPCA": "true", + "useAbsDCA": "false", + "maxR": "200", + "maxDZIni": "4", + "minParamChange": "0.001", + "minRelChi2Change": "0.9" }, - "ft0-corrected-table": "", - "hf-task-mini-candidate-creator-2prong-expressions": "", "tof-event-time": { "inheritFromBaseTask": "true", "ccdb-url": "", @@ -315,10 +576,11 @@ "enableTimeDependentResponse": "false", "fatalOnPassNotAvailable": "true", "processRun2": "false", - "processNoFT0": "false", - "processFT0": "true", + "processNoFT0": "true", + "processFT0": "false", "processOnlyFT0": "false" }, + "hf-task-mini-candidate-creator-2prong-expressions": "", "tof-pid-full": { "inheritFromBaseTask": "true", "ccdb-url": "", @@ -383,7 +645,7 @@ "ptCandMax": "50", "ptPidTpcMin": "0.15", "ptPidTpcMax": "10", - "nSigmaTpc": "3", + "nSigmaTpcMax": "3", "cpaMin": "0.98", "massWindow": "0.4" }, diff --git a/Tutorials/PWGHF/run_task.sh b/Tutorials/PWGHF/run_task.sh index 1da3b524766..1e62c0a375c 100644 --- a/Tutorials/PWGHF/run_task.sh +++ b/Tutorials/PWGHF/run_task.sh @@ -11,7 +11,7 @@ # granted to it by virtue of its status as an Intergovernmental Organization # or submit itself to any jurisdiction. -# @brief Bash script to execute the D0 mini task on Run 3 real-data input +# @brief Bash script to execute the D0 mini task on Run 3 input # # The input AO2D.root, AnalysisResults_trees.root files are expected in the working directory. # @@ -27,10 +27,14 @@ DIR_THIS="$(dirname "$(realpath "$0")")" # O2 configuration file (in the same directory) JSON="$DIR_THIS/dpl-config_task.json" -# command line options of O2 workflows -OPTIONS=( +# command line options of O2 workflows (required per workflow) +OPTIONS_LOCAL=( -b --configuration json://"$JSON" + ) + +# command line options of O2 workflows (required only once) +OPTIONS_GLOBAL=( --aod-memory-rate-limit 2000000000 --shm-segment-size 16000000000 --resources-monitoring 2 @@ -39,19 +43,15 @@ OPTIONS=( ) # execute the mini task workflow and its dependencies -# shellcheck disable=SC2086 # Ignore unquoted options. -o2-analysistutorial-hf-task-mini "${OPTIONS[@]}" | \ -o2-analysis-timestamp "${OPTIONS[@]}" | \ -o2-analysis-track-propagation "${OPTIONS[@]}" | \ -o2-analysis-event-selection "${OPTIONS[@]}" | \ -o2-analysis-pid-tpc-base "${OPTIONS[@]}" | \ -o2-analysis-pid-tpc "${OPTIONS[@]}" | \ -o2-analysis-pid-tof-base "${OPTIONS[@]}" | \ -o2-analysis-pid-tof-full "${OPTIONS[@]}" | \ -o2-analysis-ft0-corrected-table "${OPTIONS[@]}" | \ -o2-analysis-bc-converter "${OPTIONS[@]}" | \ -o2-analysis-tracks-extra-v002-converter "${OPTIONS[@]}" | \ -o2-analysis-zdc-converter "${OPTIONS[@]}" \ +o2-analysis-pid-tof-base "${OPTIONS_LOCAL[@]}" | \ +o2-analysis-pid-tof-full "${OPTIONS_LOCAL[@]}" | \ +o2-analysis-pid-tpc-service "${OPTIONS_LOCAL[@]}" | \ +o2-analysis-ft0-corrected-table "${OPTIONS_LOCAL[@]}" | \ +o2-analysis-mccollision-converter "${OPTIONS_LOCAL[@]}" | \ +o2-analysis-event-selection-service "${OPTIONS_LOCAL[@]}" | \ +o2-analysis-tracks-extra-v002-converter "${OPTIONS_LOCAL[@]}" | \ +o2-analysis-propagationservice "${OPTIONS_LOCAL[@]}" | \ +o2-analysistutorial-hf-task-mini "${OPTIONS_LOCAL[@]}" "${OPTIONS_GLOBAL[@]}" \ > "$LOGFILE" 2>&1 # report status From 7899f24cee36f3e0c8b8e6dd5e5014304a838c9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Ku=C4=8Dera?= <26327373+vkucera@users.noreply.github.com> Date: Mon, 3 Nov 2025 15:17:50 +0100 Subject: [PATCH 3/9] Add input list files --- Tutorials/PWGHF/input_skim.txt | 1 + Tutorials/PWGHF/input_task.txt | 1 + 2 files changed, 2 insertions(+) create mode 100644 Tutorials/PWGHF/input_skim.txt create mode 100644 Tutorials/PWGHF/input_task.txt diff --git a/Tutorials/PWGHF/input_skim.txt b/Tutorials/PWGHF/input_skim.txt new file mode 100644 index 00000000000..518fe2342e0 --- /dev/null +++ b/Tutorials/PWGHF/input_skim.txt @@ -0,0 +1 @@ +AO2D.root diff --git a/Tutorials/PWGHF/input_task.txt b/Tutorials/PWGHF/input_task.txt new file mode 100644 index 00000000000..5cf3c50ca80 --- /dev/null +++ b/Tutorials/PWGHF/input_task.txt @@ -0,0 +1 @@ +AnalysisResults_trees.root From e6332989da13c59eb40cb5dfb3ebfaf26e9cbe22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Ku=C4=8Dera?= <26327373+vkucera@users.noreply.github.com> Date: Mon, 3 Nov 2025 17:28:02 +0100 Subject: [PATCH 4/9] Update docs --- Tutorials/PWGHF/README.md | 43 +++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/Tutorials/PWGHF/README.md b/Tutorials/PWGHF/README.md index 47fe9b47805..4231260088f 100644 --- a/Tutorials/PWGHF/README.md +++ b/Tutorials/PWGHF/README.md @@ -4,44 +4,49 @@ Welcome to the heavy-flavour analysis tutorial! -This directory contains the code and configuration for running a minimalistic version of the D0 analysis on Run 3 real data. +This directory contains the code and configuration for running a minimalistic version of the D0 analysis on Run 3 data. See the [official PWG-HF O2 documentation](https://aliceo2group.github.io/analysis-framework/docs/advanced-specifics/pwghf.html) for the overview of the full heavy-flavour analysis framework. ## Setup -1. Create a dedicated working directory on your device. - This is the directory, where you will put your input files, run the code and produce the output files, so it is a good idea to have it outside the O2Physics repository. -2. Put the input file(s) `AO2D.root` (and `AnalysisResults_trees.root`) in the working directory. -3. Load the O2Physics environment. +1. Create and enter a dedicated working directory on your device. + This is the directory, where you will put your input files, run the code, and produce the output files, so it is a good idea to have it outside the O2Physics repository. +1. Put the input file(s) `AO2D.root` (and `AnalysisResults_trees.root`) in the working directory (or in a dedicated directory for input data). +1. Copy the [`input_skim.txt`](input_skim.txt) and [`input_task.txt`](input_task.txt) files into the working directory and adjust the paths inside if needed. +1. Load the O2Physics environment. ## Skim production -The file `AnalysisResults_trees.root` contains a derived table with track index skims of 2-prong decay candidates. -This table contains paired track indices which point to the track table in the parent `AO2D.root` file. -It is produced from the `AO2D.root` file by a dedicated workflow `o2-analysistutorial-hf-skim-creator-mini` (implemented in [`skimCreatorMini.cxx`](skimCreatorMini.cxx)). +The mini skim creator workflow `o2-analysistutorial-hf-skim-creator-mini` (implemented in [`skimCreatorMini.cxx`](skimCreatorMini.cxx)) is a simplified version of the `o2-analysis-hf-track-index-skim-creator` workflow (implemented in [`trackIndexSkimCreator.cxx`](https://github.com/AliceO2Group/O2Physics/blob/master/PWGHF/TableProducer/trackIndexSkimCreator.cxx)) which is used for the central production of linked derived data for all HF analyses and which performs: -If you need to produce these derived skims, you can do that by executing the [`run_skim.sh`](run_skim.sh) bash script in the working directory: +- the HF event selection, +- the HF secondary-track selection, +- the HF secondary-vertex reconstruction and loose selection of found HF decay candidates. + +The mini skim creator processes the `AO2D.root` file(s) and produces a derived table [`HfT2Prongs`](DataModelMini.h) with track index skims of 2-prong decay candidates. +This table contains paired track indices which point to tracks in the track table in the parent `AO2D.root` file. + +These derived skims are produced by executing the [`run_skim.sh`](run_skim.sh) bash script in the working directory: ```bash bash ~/alice/O2Physics/Tutorials/PWGHF/run_skim.sh ``` -It will use the configuration from [`dpl-config_skim.json`](dpl-config_skim.json). +It will use the configuration from [`dpl-config_skim.json`](dpl-config_skim.json) and produce the `AnalysisResults_trees.root` file with the derived table and the `AnalysisResults.root` file with control histograms in the working directory. ## Mini task The mini task workflow `o2-analysistutorial-hf-task-mini` (implemented in [`taskMini.cxx`](taskMini.cxx)) is a simplified version of the D0 analysis chain part which includes: -- the 2-prong candidate creator, -- the D0 candidate selector, -- the D0 analysis task. +- the 2-prong candidate creator (for the full candidate reconstruction), +- the D0 candidate selector (for the candidate selection), +- the D0 analysis task (for the analysis of selected candidates and filling of output histograms). The first step (candidate creator) consumes the track index skim table and therefore needs the derived `AnalysisResults_trees.root` file as input. Processing the derived file requires access to the parent `AO2D.root` file. -The absolute path to the parent file is stored in the derived file but it can be overridden with the parameter `aod-parent-base-path-replacement` in the JSON configuration, -where one has to provide a replacement mask in the format `"old-path-to-parent;new-path-to-parent"`. +The absolute path to the parent file is stored in the derived file but it can be overridden with the command line parameter `--aod-parent-base-path-replacement "old-path-to-parent;new-path-to-parent"`. (If the parent and the derived files are both in the same directory, `new-path-to-parent` can be empty.) Run the mini task by executing the [`run_task.sh`](run_task.sh) bash script in the working directory: @@ -52,7 +57,7 @@ bash ~/alice/O2Physics/Tutorials/PWGHF/run_task.sh It will use the configuration from [`dpl-config_task.json`](dpl-config_task.json) and produce the output file `AnalysisResults.root` with histograms in the working directory. -### Exercise tips +## Exercise tips Organise your working environment so that you can easily switch between running the code in the working directory and modifying the code in the O2Physics repository. @@ -61,6 +66,8 @@ If an error occurs, the script will report the non-zero exit code and ask you to The full O2 configuration is dumped at the end of processing into the `dpl-config.json` file in the working directory. -See the [rebuilding instructions](https://aliceo2group.github.io/analysis-framework/docs/gettingstarted/installing.html#building-partially-for-development-using-ninja) in the official O2 analysis framework documentation for advice on compiling your code changes. +See the [rebuilding instructions](https://aliceo2group.github.io/analysis-framework/docs/gettingstarted/installing.html#building-partially-for-development-using-ninja) in the analysis framework documentation for advice on compiling your code changes. + +See the [Troubleshooting](https://aliceo2group.github.io/analysis-framework/docs/troubleshooting/) section of the analysis framework documentation for debugging advice. -See the [Troubleshooting](https://aliceo2group.github.io/analysis-framework/docs/troubleshooting/) section of the official O2 analysis framework documentation for debugging advice. +Consider using the [Shell rc utilities](https://aliceo2group.github.io/analysis-framework/docs/tools/#shell-rc-utilities) for easier recompilation and debugging. From 194e9c2a5259055396fef618be8c353487be9a71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Ku=C4=8Dera?= <26327373+vkucera@users.noreply.github.com> Date: Tue, 4 Nov 2025 16:31:40 +0100 Subject: [PATCH 5/9] Improve code --- Tutorials/PWGHF/DataModelMini.h | 42 ++++----- Tutorials/PWGHF/skimCreatorMini.cxx | 136 ++++++++++++++-------------- Tutorials/PWGHF/taskMini.cxx | 95 ++++++++++--------- 3 files changed, 135 insertions(+), 138 deletions(-) diff --git a/Tutorials/PWGHF/DataModelMini.h b/Tutorials/PWGHF/DataModelMini.h index 720b7207676..5155b252abf 100644 --- a/Tutorials/PWGHF/DataModelMini.h +++ b/Tutorials/PWGHF/DataModelMini.h @@ -44,7 +44,7 @@ DECLARE_SOA_INDEX_COLUMN_FULL(Prong1, prong1, int, Tracks, "_1"); //! prong 1 } // namespace hf_track_index // Track index skim table -DECLARE_SOA_TABLE(HfT2Prongs, "AOD", "HFT2PRONG", //! table with prongs indices +DECLARE_SOA_TABLE(HfT2Prongs, "AOD", "HFT2PRONG", //! table with prong indices hf_track_index::Prong0Id, hf_track_index::Prong1Id); @@ -53,36 +53,36 @@ namespace hf_cand_prong2 { // Candidate columns // collision properties -DECLARE_SOA_INDEX_COLUMN(Collision, collision); //! collisions +DECLARE_SOA_INDEX_COLUMN(Collision, collision); //! collision // secondary vertex -DECLARE_SOA_COLUMN(XSecondaryVertex, xSecondaryVertex, float); //! x coordinate of the secondary vertex -DECLARE_SOA_COLUMN(YSecondaryVertex, ySecondaryVertex, float); //! y coordinate of the secondary vertex -DECLARE_SOA_COLUMN(ZSecondaryVertex, zSecondaryVertex, float); //! z coordinate of the secondary vertex -DECLARE_SOA_DYNAMIC_COLUMN(RSecondaryVertex, rSecondaryVertex, //! radius of the secondary vertex +DECLARE_SOA_COLUMN(XSecondaryVertex, xSecondaryVertex, float); //! x coordinate of the secondary vertex [cm] +DECLARE_SOA_COLUMN(YSecondaryVertex, ySecondaryVertex, float); //! y coordinate of the secondary vertex [cm] +DECLARE_SOA_COLUMN(ZSecondaryVertex, zSecondaryVertex, float); //! z coordinate of the secondary vertex [cm] +DECLARE_SOA_DYNAMIC_COLUMN(RSecondaryVertex, rSecondaryVertex, //! radius of the secondary vertex [cm] [](float xVtxS, float yVtxS) -> float { return RecoDecay::sqrtSumOfSquares(xVtxS, yVtxS); }); // prong properties -DECLARE_SOA_COLUMN(PxProng0, pxProng0, float); //! px of prong 0 -DECLARE_SOA_COLUMN(PyProng0, pyProng0, float); //! py of prong 0 -DECLARE_SOA_COLUMN(PzProng0, pzProng0, float); //! pz of prong 0 -DECLARE_SOA_DYNAMIC_COLUMN(PtProng0, ptProng0, //! pt of prong 0 +DECLARE_SOA_COLUMN(PxProng0, pxProng0, float); //! px of prong 0 [GeV/c] +DECLARE_SOA_COLUMN(PyProng0, pyProng0, float); //! py of prong 0 [GeV/c] +DECLARE_SOA_COLUMN(PzProng0, pzProng0, float); //! pz of prong 0 [GeV/c] +DECLARE_SOA_DYNAMIC_COLUMN(PtProng0, ptProng0, //! pt of prong 0 [GeV/c] [](float px, float py) -> float { return RecoDecay::pt(px, py); }); -DECLARE_SOA_COLUMN(PxProng1, pxProng1, float); //! px of prong 1 -DECLARE_SOA_COLUMN(PyProng1, pyProng1, float); //! py of prong 1 -DECLARE_SOA_COLUMN(PzProng1, pzProng1, float); //! pz of prong 1 -DECLARE_SOA_DYNAMIC_COLUMN(PtProng1, ptProng1, //! pt of prong 1 +DECLARE_SOA_COLUMN(PxProng1, pxProng1, float); //! px of prong 1 [GeV/c] +DECLARE_SOA_COLUMN(PyProng1, pyProng1, float); //! py of prong 1 [GeV/c] +DECLARE_SOA_COLUMN(PzProng1, pzProng1, float); //! pz of prong 1 [GeV/c] +DECLARE_SOA_DYNAMIC_COLUMN(PtProng1, ptProng1, //! pt of prong 1 [GeV/c] [](float px, float py) -> float { return RecoDecay::pt(px, py); }); // candidate properties -DECLARE_SOA_DYNAMIC_COLUMN(DecayLength, decayLength, //! decay length of candidate +DECLARE_SOA_DYNAMIC_COLUMN(DecayLength, decayLength, //! decay length of candidate [cm] [](float xVtxP, float yVtxP, float zVtxP, float xVtxS, float yVtxS, float zVtxS) -> float { return RecoDecay::distance(std::array{xVtxP, yVtxP, zVtxP}, std::array{xVtxS, yVtxS, zVtxS}); }); -DECLARE_SOA_DYNAMIC_COLUMN(Pt, pt, //! pt of candidate +DECLARE_SOA_DYNAMIC_COLUMN(Pt, pt, //! pt of candidate [GeV/c] [](float px, float py) -> float { return RecoDecay::pt(px, py); }); -DECLARE_SOA_EXPRESSION_COLUMN(Px, px, //! px of candidate +DECLARE_SOA_EXPRESSION_COLUMN(Px, px, //! px of candidate [GeV/c] float, 1.f * pxProng0 + 1.f * pxProng1); -DECLARE_SOA_EXPRESSION_COLUMN(Py, py, //! py of candidate +DECLARE_SOA_EXPRESSION_COLUMN(Py, py, //! py of candidate [GeV/c] float, 1.f * pyProng0 + 1.f * pyProng1); -DECLARE_SOA_EXPRESSION_COLUMN(Pz, pz, //! pz of candidate +DECLARE_SOA_EXPRESSION_COLUMN(Pz, pz, //! pz of candidate [GeV/c] float, 1.f * pzProng0 + 1.f * pzProng1); -DECLARE_SOA_DYNAMIC_COLUMN(M, m, //! invariant mass of candidate +DECLARE_SOA_DYNAMIC_COLUMN(M, m, //! invariant mass of candidate [GeV/c^2] [](float px0, float py0, float pz0, float px1, float py1, float pz1, const std::array& m) -> float { return RecoDecay::m(std::array{std::array{px0, py0, pz0}, std::array{px1, py1, pz1}}, m); }); DECLARE_SOA_DYNAMIC_COLUMN(Cpa, cpa, //! cosine of pointing angle of candidate [](float xVtxP, float yVtxP, float zVtxP, float xVtxS, float yVtxS, float zVtxS, float px, float py, float pz) -> float { return RecoDecay::cpa(std::array{xVtxP, yVtxP, zVtxP}, std::array{xVtxS, yVtxS, zVtxS}, std::array{px, py, pz}); }); @@ -116,7 +116,7 @@ namespace hf_selcandidate_d0 { // Candidate selection columns DECLARE_SOA_COLUMN(IsSelD0, isSelD0, int); //! selection flag for D0 -DECLARE_SOA_COLUMN(IsSelD0bar, isSelD0bar, int); //! selection flag for D0 bar +DECLARE_SOA_COLUMN(IsSelD0bar, isSelD0bar, int); //! selection flag for D0bar } // namespace hf_selcandidate_d0 // Candidate selection table diff --git a/Tutorials/PWGHF/skimCreatorMini.cxx b/Tutorials/PWGHF/skimCreatorMini.cxx index e3aae5bbaf4..333f0e1821e 100644 --- a/Tutorials/PWGHF/skimCreatorMini.cxx +++ b/Tutorials/PWGHF/skimCreatorMini.cxx @@ -41,6 +41,7 @@ using namespace o2; using namespace o2::aod; using namespace o2::framework; using namespace o2::framework::expressions; +using namespace o2::constants::physics; // Track selection ===================================================================== @@ -49,67 +50,62 @@ struct HfSkimCreatorMiniTagSelTracks { Produces rowSelectedTrack; // 2-prong cuts - Configurable ptTrackMin{"ptTrackMin", 0.3, "min. track pT for 2 prong candidate"}; - Configurable etaTrackMax{"etaTrackMax", 0.8, "max. pseudorapidity for 2 prong candidate"}; - Configurable dcaTrackMin{"dcaTrackMin", 0.0025, "min. DCA for 2 prong candidate"}; + Configurable ptTrackMin{"ptTrackMin", 0.3f, "min. track pT for 2 prong candidate [GeV/c]"}; + Configurable etaTrackMax{"etaTrackMax", 0.8f, "max. pseudorapidity for 2 prong candidate"}; + Configurable dcaTrackMin{"dcaTrackMin", 0.0025f, "min. DCA for 2 prong candidate [cm]"}; using TracksWDcaSel = soa::Join; - HistogramRegistry registry{ - "registry", - {}}; + HistogramRegistry registry{"registry"}; void init(InitContext&) { - const TString strTitle = "D^{0} candidates"; const TString strPt = "#it{p}_{T}^{track} (GeV/#it{c})"; const TString strEntries = "entries"; - registry.add("hPtNoCuts", "all tracks;" + strPt + ";" + strEntries, {HistType::kTH1F, {{100, 0., 10.}}}); - registry.add("hPtCuts2Prong", "tracks selected for 2-prong vertexing;" + strPt + ";" + strEntries, {HistType::kTH1F, {{100, 0., 10.}}}); + registry.add("hPtNoCuts", "all tracks;" + strPt + ";" + strEntries, {HistType::kTH1D, {{100, 0., 10.}}}); + registry.add("hPtCuts2Prong", "tracks selected for 2-prong vertexing;" + strPt + ";" + strEntries, {HistType::kTH1D, {{100, 0., 10.}}}); registry.add("hPtVsDcaXYToPvCuts2Prong", "tracks selected for 2-prong vertexing;" + strPt + ";" + "DCAxy to prim. vtx. (cm)" + ";" + strEntries, {HistType::kTH2F, {{100, 0., 10.}, {400, -2., 2.}}}); - registry.add("hEtaCuts2Prong", "tracks selected for 2-prong vertexing;#it{#eta};" + strEntries, {HistType::kTH1F, {{static_cast(1.2 * etaTrackMax * 100), -1.2 * etaTrackMax, 1.2 * etaTrackMax}}}); + registry.add("hEtaCuts2Prong", "tracks selected for 2-prong vertexing;#it{#eta};" + strEntries, {HistType::kTH1D, {{static_cast(1.2 * etaTrackMax * 100), -1.2 * etaTrackMax, 1.2 * etaTrackMax}}}); } - void process(TracksWDcaSel const& tracks) + void process(TracksWDcaSel::iterator const& track) { - for (const auto& track : tracks) { - bool statusProng = true; + const auto ptTrack{track.pt()}; + registry.fill(HIST("hPtNoCuts"), ptTrack); - auto ptTrack = track.pt(); - registry.fill(HIST("hPtNoCuts"), ptTrack); + bool statusProng{true}; - // pT cut - if (ptTrack < ptTrackMin) { - statusProng = false; - } - - // eta cut - auto etaTrack = track.eta(); - if (statusProng && std::abs(etaTrack) > etaTrackMax) { - statusProng = false; - } + // pT cut + if (ptTrack < ptTrackMin) { + statusProng = false; + } - // quality cut - if (!track.isGlobalTrackWoDCA()) { - statusProng = false; - } + // eta cut + const auto etaTrack{track.eta()}; + if (statusProng && std::abs(etaTrack) > etaTrackMax) { + statusProng = false; + } - // DCA cut - auto dcaXY = track.dcaXY(); - if (statusProng && std::abs(dcaXY) < dcaTrackMin) { - statusProng = false; - } + // quality cut + if (!track.isGlobalTrackWoDCA()) { + statusProng = false; + } - // fill histograms - if (statusProng) { - registry.fill(HIST("hPtCuts2Prong"), ptTrack); - registry.fill(HIST("hEtaCuts2Prong"), etaTrack); - registry.fill(HIST("hPtVsDcaXYToPvCuts2Prong"), ptTrack, dcaXY); - } + // DCA cut + const auto dcaXY{track.dcaXY()}; + if (statusProng && std::abs(dcaXY) < dcaTrackMin) { + statusProng = false; + } - // fill table row - rowSelectedTrack(statusProng); + // fill histograms + if (statusProng) { + registry.fill(HIST("hPtCuts2Prong"), ptTrack); + registry.fill(HIST("hEtaCuts2Prong"), etaTrack); + registry.fill(HIST("hPtVsDcaXYToPvCuts2Prong"), ptTrack, dcaXY); } + + // fill table row + rowSelectedTrack(statusProng); } }; @@ -121,30 +117,30 @@ struct HfSkimCreatorMini { Produces rowTrackIndexProng2; // vertexing parameters - Configurable magneticField{"magneticField", 5., "magnetic field [kG]"}; - Configurable propagateToPCA{"propagateToPCA", true, "create tracks version propagated to PCA"}; + Configurable magneticField{"magneticField", 5.f, "magnetic field [kG]"}; + Configurable propagateToPCA{"propagateToPCA", true, "Create tracks version propagated to PCA"}; Configurable useAbsDCA{"useAbsDCA", false, "Minimise abs. distance rather than chi2"}; - Configurable maxR{"maxR", 200., "reject PCA's above this radius"}; - Configurable maxDZIni{"maxDZIni", 4., "reject (if>0) PCA candidate if tracks DZ exceeds threshold"}; - Configurable minParamChange{"minParamChange", 1.e-3, "stop iterations if largest change of any X is smaller than this"}; - Configurable minRelChi2Change{"minRelChi2Change", 0.9, "stop iterations if chi2/chi2old > this"}; + Configurable maxR{"maxR", 200.f, "Reject PCA's above this radius"}; + Configurable maxDZIni{"maxDZIni", 4.f, "Reject (if>0) PCA candidate if tracks DZ exceeds threshold"}; + Configurable minParamChange{"minParamChange", 1.e-3f, "Stop iterations if largest change of any X is smaller than this"}; + Configurable minRelChi2Change{"minRelChi2Change", 0.9f, "Stop iterations if chi2/chi2old > this"}; - o2::vertexing::DCAFitterN<2> fitter; // 2-prong vertex fitter + o2::vertexing::DCAFitterN<2> fitter{}; // 2-prong vertex fitter using SelectedTracks = soa::Filtered>; Filter filterSelectTracks = aod::hf_seltrack::isSelProng == true; - HistogramRegistry registry{ - "registry", - {// 2-prong histograms - {"hVtx2ProngX", "2-prong candidates;#it{x}_{sec. vtx.} (cm);entries", {HistType::kTH1F, {{1000, -2., 2.}}}}, - {"hVtx2ProngY", "2-prong candidates;#it{y}_{sec. vtx.} (cm);entries", {HistType::kTH1F, {{1000, -2., 2.}}}}, - {"hVtx2ProngZ", "2-prong candidates;#it{z}_{sec. vtx.} (cm);entries", {HistType::kTH1F, {{1000, -20., 20.}}}}, - {"hMassD0ToPiK", "D^{0} candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{500, 0., 5.}}}}}}; + HistogramRegistry registry{"registry"}; void init(InitContext&) { + // 2-prong histograms + registry.add("hVtx2ProngX", "2-prong candidates;#it{x}_{sec. vtx.} (cm);entries", {HistType::kTH1D, {{1000, -2., 2.}}}); + registry.add("hVtx2ProngY", "2-prong candidates;#it{y}_{sec. vtx.} (cm);entries", {HistType::kTH1D, {{1000, -2., 2.}}}); + registry.add("hVtx2ProngZ", "2-prong candidates;#it{z}_{sec. vtx.} (cm);entries", {HistType::kTH1D, {{1000, -20., 20.}}}); + registry.add("hMassD0", "D^{0} candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1D, {{500, 0., 5.}}}); + // Configure the vertexer fitter.setBz(magneticField); fitter.setPropagateToPCA(propagateToPCA); @@ -159,23 +155,23 @@ struct HfSkimCreatorMini { SelectedTracks const& tracks) { // loop over positive tracks - for (const auto& trackPos1 : tracks) { - if (trackPos1.signed1Pt() < 0) { + for (const auto& trackPos : tracks) { + if (trackPos.signed1Pt() < 0) { continue; } - auto trackParVarPos1 = getTrackParCov(trackPos1); + const auto trackParVarPos{getTrackParCov(trackPos)}; // loop over negative tracks - for (const auto& trackNeg1 : tracks) { - if (trackNeg1.signed1Pt() > 0) { + for (const auto& trackNeg : tracks) { + if (trackNeg.signed1Pt() > 0) { continue; } - auto trackParVarNeg1 = getTrackParCov(trackNeg1); + const auto trackParVarNeg{getTrackParCov(trackNeg)}; - // secondary vertex reconstruction and further 2-prong selections + // secondary-vertex reconstruction and further 2-prong selections int nVtxFromFitter = 0; try { - nVtxFromFitter = fitter.process(trackParVarPos1, trackParVarNeg1); + nVtxFromFitter = fitter.process(trackParVarPos, trackParVarNeg); } catch (...) { } if (nVtxFromFitter == 0) { @@ -190,16 +186,18 @@ struct HfSkimCreatorMini { fitter.getTrack(1).getPxPyPzGlo(pVec1); // fill table row - rowTrackIndexProng2(trackPos1.globalIndex(), - trackNeg1.globalIndex()); + rowTrackIndexProng2(trackPos.globalIndex(), + trackNeg.globalIndex()); // fill histograms registry.fill(HIST("hVtx2ProngX"), secondaryVertex[0]); registry.fill(HIST("hVtx2ProngY"), secondaryVertex[1]); registry.fill(HIST("hVtx2ProngZ"), secondaryVertex[2]); - std::array, 2> arrMom = {pVec0, pVec1}; - auto mass2Prong = RecoDecay::m(arrMom, std::array{o2::constants::physics::MassPiPlus, o2::constants::physics::MassKPlus}); - registry.fill(HIST("hMassD0ToPiK"), mass2Prong); + const std::array arrayMomenta{pVec0, pVec1}; + const auto massPiK{RecoDecay::m(arrayMomenta, std::array{MassPiPlus, MassKPlus})}; + const auto massKPi{RecoDecay::m(arrayMomenta, std::array{MassKPlus, MassPiPlus})}; + registry.fill(HIST("hMassD0"), massPiK); + registry.fill(HIST("hMassD0"), massKPi); } } } diff --git a/Tutorials/PWGHF/taskMini.cxx b/Tutorials/PWGHF/taskMini.cxx index 65d0f3fc661..7f64b3aacba 100644 --- a/Tutorials/PWGHF/taskMini.cxx +++ b/Tutorials/PWGHF/taskMini.cxx @@ -45,6 +45,7 @@ using namespace o2; using namespace o2::aod; using namespace o2::framework; using namespace o2::framework::expressions; +using namespace o2::constants::physics; // Candidate creation ===================================================================== @@ -54,24 +55,24 @@ struct HfTaskMiniCandidateCreator2Prong { Produces rowCandidateBase; // vertexing parameters - Configurable magneticField{"magneticField", 5., "magnetic field [kG]"}; + Configurable magneticField{"magneticField", 5.f, "magnetic field [kG]"}; Configurable propagateToPCA{"propagateToPCA", true, "create tracks version propagated to PCA"}; Configurable useAbsDCA{"useAbsDCA", false, "Minimise abs. distance rather than chi2"}; - Configurable maxR{"maxR", 200., "reject PCA's above this radius"}; - Configurable maxDZIni{"maxDZIni", 4., "reject (if>0) PCA candidate if tracks DZ exceeds threshold"}; - Configurable minParamChange{"minParamChange", 1.e-3, "stop iterations if largest change of any X is smaller than this"}; - Configurable minRelChi2Change{"minRelChi2Change", 0.9, "stop iterations if chi2/chi2old > this"}; + Configurable maxR{"maxR", 200.f, "reject PCA's above this radius"}; + Configurable maxDZIni{"maxDZIni", 4.f, "reject (if>0) PCA candidate if tracks DZ exceeds threshold"}; + Configurable minParamChange{"minParamChange", 1.e-3f, "stop iterations if largest change of any X is smaller than this"}; + Configurable minRelChi2Change{"minRelChi2Change", 0.9f, "stop iterations if chi2/chi2old > this"}; - o2::vertexing::DCAFitterN<2> fitter; // 2-prong vertex fitter - double massPiK{0.}; - double massKPi{0.}; + o2::vertexing::DCAFitterN<2> fitter{}; // 2-prong vertex fitter using TracksWithCov = soa::Join; - OutputObj hMass{TH1F("hMass", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", 500, 0., 5.)}; + HistogramRegistry registry{"registry"}; void init(InitContext&) { + registry.add("hMass", "D^{0} candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1D, {{500, 0., 5.}}}); + // Configure the vertexer fitter.setBz(magneticField); fitter.setPropagateToPCA(propagateToPCA); @@ -88,23 +89,23 @@ struct HfTaskMiniCandidateCreator2Prong { { // loop over pairs of track indices for (const auto& rowTrackIndexProng2 : rowsTrackIndexProng2) { - auto track0 = rowTrackIndexProng2.prong0_as(); - auto track1 = rowTrackIndexProng2.prong1_as(); - auto trackParVarPos1 = getTrackParCov(track0); - auto trackParVarNeg1 = getTrackParCov(track1); - auto collision = track0.collision(); + const auto& track0{rowTrackIndexProng2.prong0_as()}; + const auto& track1{rowTrackIndexProng2.prong1_as()}; + const auto trackParVarPos1{getTrackParCov(track0)}; + const auto trackParVarNeg1{getTrackParCov(track1)}; + const auto& collision{track0.collision()}; // reconstruct the 2-prong secondary vertex if (fitter.process(trackParVarPos1, trackParVarNeg1) == 0) { continue; } const auto& secondaryVertex = fitter.getPCACandidate(); - auto trackParVar0 = fitter.getTrack(0); - auto trackParVar1 = fitter.getTrack(1); + auto& trackParVar0{fitter.getTrack(0)}; + auto& trackParVar1{fitter.getTrack(1)}; // get track momenta - std::array pVec0; - std::array pVec1; + std::array pVec0{}; + std::array pVec1{}; trackParVar0.getPxPyPzGlo(pVec0); trackParVar1.getPxPyPzGlo(pVec1); @@ -118,11 +119,11 @@ struct HfTaskMiniCandidateCreator2Prong { // fill histograms // calculate invariant masses - auto arrayMomenta = std::array{pVec0, pVec1}; - massPiK = RecoDecay::m(arrayMomenta, std::array{o2::constants::physics::MassPiPlus, o2::constants::physics::MassKPlus}); - massKPi = RecoDecay::m(arrayMomenta, std::array{o2::constants::physics::MassKPlus, o2::constants::physics::MassPiPlus}); - hMass->Fill(massPiK); - // hMass->Fill(massKPi); + const std::array arrayMomenta{pVec0, pVec1}; + const auto massPiK{RecoDecay::m(arrayMomenta, std::array{MassPiPlus, MassKPlus})}; + // const auto massKPi{RecoDecay::m(arrayMomenta, std::array{MassKPlus, MassPiPlus})}; + registry.fill(HIST("hMass"), massPiK); + // registry.fill(HIST("hMass"), massKPi); } } }; @@ -140,18 +141,18 @@ struct HfTaskMiniCandidateCreator2ProngExpressions { struct HfTaskMiniCandidateSelectorD0 { Produces hfSelD0Candidate; - Configurable ptCandMin{"ptCandMin", 0., "Lower bound of candidate pT"}; - Configurable ptCandMax{"ptCandMax", 50., "Upper bound of candidate pT"}; + Configurable ptCandMin{"ptCandMin", 0.f, "Lower bound of candidate pT"}; + Configurable ptCandMax{"ptCandMax", 50.f, "Upper bound of candidate pT"}; // TPC - Configurable ptPidTpcMin{"ptPidTpcMin", 0.15, "Lower bound of track pT for TPC PID"}; - Configurable ptPidTpcMax{"ptPidTpcMax", 5., "Upper bound of track pT for TPC PID"}; - Configurable nSigmaTpc{"nSigmaTpc", 3., "Nsigma cut on TPC only"}; + Configurable ptPidTpcMin{"ptPidTpcMin", 0.15f, "Lower bound of track pT for TPC PID"}; + Configurable ptPidTpcMax{"ptPidTpcMax", 5.f, "Upper bound of track pT for TPC PID"}; + Configurable nSigmaTpcMax{"nSigmaTpcMax", 3.f, "Nsigma cut on TPC only"}; // topological cuts - Configurable cpaMin{"cpaMin", 0.98, "Min. cosine of pointing angle"}; - Configurable massWindow{"massWindow", 0.4, "Half-width of the invariant-mass window"}; + Configurable cpaMin{"cpaMin", 0.98f, "Min. cosine of pointing angle"}; + Configurable massWindow{"massWindow", 0.4f, "Half-width of the invariant-mass window"}; - TrackSelectorPi selectorPion; - TrackSelectorKa selectorKaon; + TrackSelectorPi selectorPion{}; + TrackSelectorKa selectorKaon{}; using TracksWithPid = soa::Join 0) { - if (std::abs(HfHelper::invMassD0ToPiK(candidate) - o2::constants::physics::MassD0) > massWindow) { + if (std::abs(HfHelper::invMassD0ToPiK(candidate) - MassD0) > massWindow) { return false; } } else { - if (std::abs(HfHelper::invMassD0barToKPi(candidate) - o2::constants::physics::MassD0) > massWindow) { + if (std::abs(HfHelper::invMassD0barToKPi(candidate) - MassD0) > massWindow) { return false; } } @@ -213,8 +214,8 @@ struct HfTaskMiniCandidateSelectorD0 { int statusD0 = 0; int statusD0bar = 0; - auto trackPos = candidate.prong0_as(); // positive daughter - auto trackNeg = candidate.prong1_as(); // negative daughter + const auto& trackPos = candidate.prong0_as(); // positive daughter + const auto& trackNeg = candidate.prong1_as(); // negative daughter // conjugate-independent topological selection if (!selectionTopol(candidate)) { @@ -223,9 +224,9 @@ struct HfTaskMiniCandidateSelectorD0 { } // conjugate-dependent topological selection for D0 - bool topolD0 = selectionTopolConjugate(candidate, trackPos, trackNeg); + const auto topolD0 = selectionTopolConjugate(candidate, trackPos, trackNeg); // conjugate-dependent topological selection for D0bar - bool topolD0bar = selectionTopolConjugate(candidate, trackNeg, trackPos); + const auto topolD0bar = selectionTopolConjugate(candidate, trackNeg, trackPos); if (!topolD0 && !topolD0bar) { hfSelD0Candidate(statusD0, statusD0bar); @@ -233,10 +234,10 @@ struct HfTaskMiniCandidateSelectorD0 { } // track-level PID selection - int pidTrackPosKaon = selectorKaon.statusTpcOrTof(trackPos); - int pidTrackPosPion = selectorPion.statusTpcOrTof(trackPos); - int pidTrackNegKaon = selectorKaon.statusTpcOrTof(trackNeg); - int pidTrackNegPion = selectorPion.statusTpcOrTof(trackNeg); + const auto pidTrackPosKaon = selectorKaon.statusTpcOrTof(trackPos); + const auto pidTrackPosPion = selectorPion.statusTpcOrTof(trackPos); + const auto pidTrackNegKaon = selectorKaon.statusTpcOrTof(trackNeg); + const auto pidTrackNegPion = selectorPion.statusTpcOrTof(trackNeg); int pidD0 = -1; int pidD0bar = -1; @@ -287,17 +288,15 @@ struct HfTaskMiniD0 { Partition> selectedD0Candidates = aod::hf_selcandidate_d0::isSelD0 >= selectionFlagD0 || aod::hf_selcandidate_d0::isSelD0bar >= selectionFlagD0bar; - HistogramRegistry registry{ - "registry", - {}}; + HistogramRegistry registry{"registry"}; void init(InitContext&) { const TString strTitle = "D^{0} candidates"; const TString strPt = "#it{p}_{T} (GeV/#it{c})"; const TString strEntries = "entries"; - registry.add("hPtCand", strTitle + ";" + strPt + ";" + strEntries, {HistType::kTH1F, {{100, 0., 10.}}}); - registry.add("hMass", strTitle + ";" + "inv. mass (#pi K) (GeV/#it{c}^{2})" + ";" + strEntries, {HistType::kTH1F, {{500, 0., 5.}}}); + registry.add("hPtCand", strTitle + ";" + strPt + ";" + strEntries, {HistType::kTH1D, {{100, 0., 10.}}}); + registry.add("hMass", strTitle + ";" + "inv. mass (#pi K) (GeV/#it{c}^{2})" + ";" + strEntries, {HistType::kTH1D, {{500, 0., 5.}}}); registry.add("hCpaVsPtCand", strTitle + ";" + "cosine of pointing angle" + ";" + strPt + ";" + strEntries, {HistType::kTH2F, {{110, -1.1, 1.1}, {100, 0., 10.}}}); } From 234311319f8ec0ad562b158c9f054d8d651bfb1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Ku=C4=8Dera?= <26327373+vkucera@users.noreply.github.com> Date: Wed, 5 Nov 2025 23:32:57 +0100 Subject: [PATCH 6/9] Fixes --- Tutorials/PWGHF/DataModelMini.h | 2 + Tutorials/PWGHF/dpl-config_task.json | 72 +++++++++++++++------------- Tutorials/PWGHF/run_skim.sh | 5 +- Tutorials/PWGHF/run_task.sh | 8 ++-- Tutorials/PWGHF/skimCreatorMini.cxx | 14 +++--- 5 files changed, 54 insertions(+), 47 deletions(-) diff --git a/Tutorials/PWGHF/DataModelMini.h b/Tutorials/PWGHF/DataModelMini.h index 5155b252abf..bbd1bdad009 100644 --- a/Tutorials/PWGHF/DataModelMini.h +++ b/Tutorials/PWGHF/DataModelMini.h @@ -45,6 +45,7 @@ DECLARE_SOA_INDEX_COLUMN_FULL(Prong1, prong1, int, Tracks, "_1"); //! prong 1 // Track index skim table DECLARE_SOA_TABLE(HfT2Prongs, "AOD", "HFT2PRONG", //! table with prong indices + o2::soa::Index<>, hf_track_index::Prong0Id, hf_track_index::Prong1Id); @@ -90,6 +91,7 @@ DECLARE_SOA_DYNAMIC_COLUMN(Cpa, cpa, //! cosine of pointing angle of candidate // Candidate table DECLARE_SOA_TABLE(HfTCand2ProngBase, "AOD", "HFTCAND2PBASE", //! 2-prong candidate table + o2::soa::Index<>, hf_cand_prong2::CollisionId, collision::PosX, collision::PosY, collision::PosZ, hf_cand_prong2::XSecondaryVertex, hf_cand_prong2::YSecondaryVertex, hf_cand_prong2::ZSecondaryVertex, diff --git a/Tutorials/PWGHF/dpl-config_task.json b/Tutorials/PWGHF/dpl-config_task.json index 0309c34ee4f..c679951e3db 100644 --- a/Tutorials/PWGHF/dpl-config_task.json +++ b/Tutorials/PWGHF/dpl-config_task.json @@ -77,7 +77,7 @@ "ccdbPath": "Analysis/PID/TPC/Response", "recoPass": "", "ccdb-timestamp": "0", - "useNetworkCorrection": "true", + "useNetworkCorrection": "false", "autofetchNetworks": "true", "skipTPCOnly": "-1", "devicesRequiringTPCOnlyPID": { @@ -122,9 +122,9 @@ "networkBetaGammaCutoff": "0.45", "ccdb-path-grplhcif": "GLO/Config/GRPLHCIF" }, - "processTracksIU": "false", + "processTracksIU": "true", "processTracksIUWithTracksQA": "false", - "processTracksMCIU": "true" + "processTracksMCIU": "false" }, "ft0-corrected-table": { "resoFT0A": "20", @@ -541,13 +541,22 @@ "processMonteCarloWithPID": "false" }, "tof-signal": { + "enableQaHistograms": "false", "ccdb-url": "http://alice-ccdb.cern.ch", + "ccdb-path-grplhcif": "GLO/Config/GRPLHCIF", "ccdb-timestamp": "-1", - "timeShiftCCDBPath": "", - "distanceForGoodMatch": "999", - "distanceForGoodMatchLowMult": "999", - "multThreshold": "0", - "enableQaHistograms": "false", + "timeShiftCCDBPathPos": "Analysis/PID/TOFOffsetPos", + "timeShiftCCDBPathNeg": "Analysis/PID/TOFOffsetPos", + "timeShiftCCDBPathPosMC": "", + "timeShiftCCDBPathNegMC": "", + "paramFileName": "", + "parametrizationPath": "TOF/Calib/Params", + "reconstructionPass": "metadata", + "reconstructionPassDefault": "unanchored", + "fatalOnPassNotAvailable": "false", + "enableTimeDependentResponse": "true", + "collisionSystem": "-1", + "autoSetProcessFunctions": "true", "processRun3": "true", "processRun2": "false" }, @@ -561,37 +570,20 @@ "minRelChi2Change": "0.9" }, "tof-event-time": { - "inheritFromBaseTask": "true", - "ccdb-url": "", - "ccdb-timestamp": "-1", "minMomentum": "0.5", "maxMomentum": "2", "maxEvTimeTOF": "100000", "sel8TOFEvTime": "false", + "computeEvTimeWithTOF": "1", + "computeEvTimeWithFT0": "1", "maxNtracksInSet": "10", - "paramFileName": "", - "parametrizationPath": "TOF/Calib/Params", - "passName": "", - "loadResponseFromCCDB": "false", - "enableTimeDependentResponse": "false", - "fatalOnPassNotAvailable": "true", "processRun2": "false", - "processNoFT0": "true", - "processFT0": "false", - "processOnlyFT0": "false" + "processRun3": "true" }, "hf-task-mini-candidate-creator-2prong-expressions": "", - "tof-pid-full": { - "inheritFromBaseTask": "true", - "ccdb-url": "", - "ccdb-timestamp": "-1", - "paramFileName": "", - "parametrizationPath": "", - "passName": "", - "timeShiftCCDBPath": "", - "loadResponseFromCCDB": "false", - "enableTimeDependentResponse": "false", - "fatalOnPassNotAvailable": "true", + "tof-pid-merge": { + "enableQaHistograms": "false", + "enableTOFParamsForBetaMass": "false", "enableParticle": { "labels_rows": [ "El", @@ -605,40 +597,52 @@ "Al" ], "labels_cols": [ - "Enable" + "Enable", + "EnableFull" ], "values": [ [ + "-1", "-1" ], [ + "-1", "-1" ], [ + "-1", "-1" ], [ + "-1", "-1" ], [ + "-1", "-1" ], [ + "-1", "-1" ], [ + "-1", "-1" ], [ + "-1", "-1" ], [ + "-1", "-1" ] ] }, - "processWSlice": "true", - "processWoSlice": "false" + "processRun3": "true", + "processRun2": "false", + "processRun2BetaM": "false", + "processRun3BetaM": "true" }, "hf-task-mini-candidate-selector-d0": { "ptCandMin": "0", diff --git a/Tutorials/PWGHF/run_skim.sh b/Tutorials/PWGHF/run_skim.sh index 1bbbf2f34da..24a9151d4b7 100644 --- a/Tutorials/PWGHF/run_skim.sh +++ b/Tutorials/PWGHF/run_skim.sh @@ -27,18 +27,19 @@ DIR_THIS="$(dirname "$(realpath "$0")")" # O2 configuration file (in the same directory) JSON="$DIR_THIS/dpl-config_skim.json" -# command line options of O2 workflows (required per workflow) +# local command line options of O2 workflows (required per workflow) OPTIONS_LOCAL=( -b --configuration json://"$JSON" --aod-writer-keep "AOD/HFT2PRONG/0" ) -# command line options of O2 workflows (required only once) +# global command line options of O2 workflows (required only once) OPTIONS_GLOBAL=( --aod-memory-rate-limit 2000000000 --shm-segment-size 16000000000 --resources-monitoring 2 + --aod-file "@input_skim.txt" ) # execute the mini skim creator workflow and its dependencies diff --git a/Tutorials/PWGHF/run_task.sh b/Tutorials/PWGHF/run_task.sh index 1e62c0a375c..cc4cb1a5d41 100644 --- a/Tutorials/PWGHF/run_task.sh +++ b/Tutorials/PWGHF/run_task.sh @@ -27,25 +27,25 @@ DIR_THIS="$(dirname "$(realpath "$0")")" # O2 configuration file (in the same directory) JSON="$DIR_THIS/dpl-config_task.json" -# command line options of O2 workflows (required per workflow) +# local command line options of O2 workflows (required per workflow) OPTIONS_LOCAL=( -b --configuration json://"$JSON" ) -# command line options of O2 workflows (required only once) +# global command line options of O2 workflows (required only once) OPTIONS_GLOBAL=( --aod-memory-rate-limit 2000000000 --shm-segment-size 16000000000 --resources-monitoring 2 --aod-parent-base-path-replacement "old-path-to-parent;new-path-to-parent" --aod-parent-access-level 1 + --aod-file "@input_task.txt" ) # execute the mini task workflow and its dependencies -o2-analysis-pid-tof-base "${OPTIONS_LOCAL[@]}" | \ -o2-analysis-pid-tof-full "${OPTIONS_LOCAL[@]}" | \ o2-analysis-pid-tpc-service "${OPTIONS_LOCAL[@]}" | \ +o2-analysis-pid-tof-merge "${OPTIONS_LOCAL[@]}" | \ o2-analysis-ft0-corrected-table "${OPTIONS_LOCAL[@]}" | \ o2-analysis-mccollision-converter "${OPTIONS_LOCAL[@]}" | \ o2-analysis-event-selection-service "${OPTIONS_LOCAL[@]}" | \ diff --git a/Tutorials/PWGHF/skimCreatorMini.cxx b/Tutorials/PWGHF/skimCreatorMini.cxx index 333f0e1821e..5553a10e1f4 100644 --- a/Tutorials/PWGHF/skimCreatorMini.cxx +++ b/Tutorials/PWGHF/skimCreatorMini.cxx @@ -136,10 +136,10 @@ struct HfSkimCreatorMini { void init(InitContext&) { // 2-prong histograms - registry.add("hVtx2ProngX", "2-prong candidates;#it{x}_{sec. vtx.} (cm);entries", {HistType::kTH1D, {{1000, -2., 2.}}}); - registry.add("hVtx2ProngY", "2-prong candidates;#it{y}_{sec. vtx.} (cm);entries", {HistType::kTH1D, {{1000, -2., 2.}}}); - registry.add("hVtx2ProngZ", "2-prong candidates;#it{z}_{sec. vtx.} (cm);entries", {HistType::kTH1D, {{1000, -20., 20.}}}); - registry.add("hMassD0", "D^{0} candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1D, {{500, 0., 5.}}}); + registry.add("hVtx2ProngX", "2-prong candidates;#it{x}_{sec. vtx.} (cm);entries", {HistType::kTH1F, {{1000, -2., 2.}}}); + registry.add("hVtx2ProngY", "2-prong candidates;#it{y}_{sec. vtx.} (cm);entries", {HistType::kTH1F, {{1000, -2., 2.}}}); + registry.add("hVtx2ProngZ", "2-prong candidates;#it{z}_{sec. vtx.} (cm);entries", {HistType::kTH1F, {{1000, -20., 20.}}}); + registry.add("hMassD0ToPiK", "D^{0} candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{500, 0., 5.}}}); // Configure the vertexer fitter.setBz(magneticField); @@ -195,9 +195,9 @@ struct HfSkimCreatorMini { registry.fill(HIST("hVtx2ProngZ"), secondaryVertex[2]); const std::array arrayMomenta{pVec0, pVec1}; const auto massPiK{RecoDecay::m(arrayMomenta, std::array{MassPiPlus, MassKPlus})}; - const auto massKPi{RecoDecay::m(arrayMomenta, std::array{MassKPlus, MassPiPlus})}; - registry.fill(HIST("hMassD0"), massPiK); - registry.fill(HIST("hMassD0"), massKPi); + // const auto massKPi{RecoDecay::m(arrayMomenta, std::array{MassKPlus, MassPiPlus})}; + registry.fill(HIST("hMassD0ToPiK"), massPiK); + // registry.fill(HIST("hMassD0ToPiK"), massKPi); } } } From 9a9385999ddbb394ece41ccf4584f4154f5ad2d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Ku=C4=8Dera?= <26327373+vkucera@users.noreply.github.com> Date: Thu, 6 Nov 2025 15:09:37 +0100 Subject: [PATCH 7/9] Improve code --- Tutorials/PWGHF/skimCreatorMini.cxx | 16 ++++----- Tutorials/PWGHF/taskMini.cxx | 52 ++++++++++++++--------------- 2 files changed, 33 insertions(+), 35 deletions(-) diff --git a/Tutorials/PWGHF/skimCreatorMini.cxx b/Tutorials/PWGHF/skimCreatorMini.cxx index 5553a10e1f4..45135bfdef8 100644 --- a/Tutorials/PWGHF/skimCreatorMini.cxx +++ b/Tutorials/PWGHF/skimCreatorMini.cxx @@ -50,9 +50,9 @@ struct HfSkimCreatorMiniTagSelTracks { Produces rowSelectedTrack; // 2-prong cuts - Configurable ptTrackMin{"ptTrackMin", 0.3f, "min. track pT for 2 prong candidate [GeV/c]"}; - Configurable etaTrackMax{"etaTrackMax", 0.8f, "max. pseudorapidity for 2 prong candidate"}; - Configurable dcaTrackMin{"dcaTrackMin", 0.0025f, "min. DCA for 2 prong candidate [cm]"}; + Configurable ptTrackMin{"ptTrackMin", 0.3f, "Min. track pT for 2-prong candidate [GeV/c]"}; + Configurable etaTrackMax{"etaTrackMax", 0.8f, "Max. pseudorapidity for 2-prong candidate"}; + Configurable dcaTrackMin{"dcaTrackMin", 0.0025f, "Min. DCA for 2-prong candidate [cm]"}; using TracksWDcaSel = soa::Join; @@ -141,7 +141,7 @@ struct HfSkimCreatorMini { registry.add("hVtx2ProngZ", "2-prong candidates;#it{z}_{sec. vtx.} (cm);entries", {HistType::kTH1F, {{1000, -20., 20.}}}); registry.add("hMassD0ToPiK", "D^{0} candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{500, 0., 5.}}}); - // Configure the vertexer + // Configure the vertexer. fitter.setBz(magneticField); fitter.setPropagateToPCA(propagateToPCA); fitter.setMaxR(maxR); @@ -177,11 +177,11 @@ struct HfSkimCreatorMini { if (nVtxFromFitter == 0) { continue; } - // get secondary vertex + // get secondary vertex const auto& secondaryVertex = fitter.getPCACandidate(); // get track momenta - std::array pVec0; - std::array pVec1; + std::array pVec0{}; + std::array pVec1{}; fitter.getTrack(0).getPxPyPzGlo(pVec0); fitter.getTrack(1).getPxPyPzGlo(pVec1); @@ -195,8 +195,8 @@ struct HfSkimCreatorMini { registry.fill(HIST("hVtx2ProngZ"), secondaryVertex[2]); const std::array arrayMomenta{pVec0, pVec1}; const auto massPiK{RecoDecay::m(arrayMomenta, std::array{MassPiPlus, MassKPlus})}; - // const auto massKPi{RecoDecay::m(arrayMomenta, std::array{MassKPlus, MassPiPlus})}; registry.fill(HIST("hMassD0ToPiK"), massPiK); + // const auto massKPi{RecoDecay::m(arrayMomenta, std::array{MassKPlus, MassPiPlus})}; // registry.fill(HIST("hMassD0ToPiK"), massKPi); } } diff --git a/Tutorials/PWGHF/taskMini.cxx b/Tutorials/PWGHF/taskMini.cxx index 7f64b3aacba..e92553d8e50 100644 --- a/Tutorials/PWGHF/taskMini.cxx +++ b/Tutorials/PWGHF/taskMini.cxx @@ -56,12 +56,12 @@ struct HfTaskMiniCandidateCreator2Prong { // vertexing parameters Configurable magneticField{"magneticField", 5.f, "magnetic field [kG]"}; - Configurable propagateToPCA{"propagateToPCA", true, "create tracks version propagated to PCA"}; + Configurable propagateToPCA{"propagateToPCA", true, "Create tracks version propagated to PCA"}; Configurable useAbsDCA{"useAbsDCA", false, "Minimise abs. distance rather than chi2"}; - Configurable maxR{"maxR", 200.f, "reject PCA's above this radius"}; - Configurable maxDZIni{"maxDZIni", 4.f, "reject (if>0) PCA candidate if tracks DZ exceeds threshold"}; - Configurable minParamChange{"minParamChange", 1.e-3f, "stop iterations if largest change of any X is smaller than this"}; - Configurable minRelChi2Change{"minRelChi2Change", 0.9f, "stop iterations if chi2/chi2old > this"}; + Configurable maxR{"maxR", 200.f, "Reject PCA's above this radius"}; + Configurable maxDZIni{"maxDZIni", 4.f, "Reject (if>0) PCA candidate if tracks DZ exceeds threshold"}; + Configurable minParamChange{"minParamChange", 1.e-3f, "Stop iterations if largest change of any X is smaller than this"}; + Configurable minRelChi2Change{"minRelChi2Change", 0.9f, "Stop iterations if chi2/chi2old > this"}; o2::vertexing::DCAFitterN<2> fitter{}; // 2-prong vertex fitter @@ -71,9 +71,9 @@ struct HfTaskMiniCandidateCreator2Prong { void init(InitContext&) { - registry.add("hMass", "D^{0} candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1D, {{500, 0., 5.}}}); + registry.add("hMass", "D^{0} candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{500, 0., 5.}}}); - // Configure the vertexer + // Configure the vertexer. fitter.setBz(magneticField); fitter.setPropagateToPCA(propagateToPCA); fitter.setMaxR(maxR); @@ -99,17 +99,15 @@ struct HfTaskMiniCandidateCreator2Prong { if (fitter.process(trackParVarPos1, trackParVarNeg1) == 0) { continue; } + // get secondary vertex const auto& secondaryVertex = fitter.getPCACandidate(); - auto& trackParVar0{fitter.getTrack(0)}; - auto& trackParVar1{fitter.getTrack(1)}; - // get track momenta std::array pVec0{}; std::array pVec1{}; - trackParVar0.getPxPyPzGlo(pVec0); - trackParVar1.getPxPyPzGlo(pVec1); + fitter.getTrack(0).getPxPyPzGlo(pVec0); + fitter.getTrack(1).getPxPyPzGlo(pVec1); - // fill candidate table rows + // fill candidate table row rowCandidateBase(collision.globalIndex(), collision.posX(), collision.posY(), collision.posZ(), secondaryVertex[0], secondaryVertex[1], secondaryVertex[2], @@ -121,8 +119,8 @@ struct HfTaskMiniCandidateCreator2Prong { // calculate invariant masses const std::array arrayMomenta{pVec0, pVec1}; const auto massPiK{RecoDecay::m(arrayMomenta, std::array{MassPiPlus, MassKPlus})}; - // const auto massKPi{RecoDecay::m(arrayMomenta, std::array{MassKPlus, MassPiPlus})}; registry.fill(HIST("hMass"), massPiK); + // const auto massKPi{RecoDecay::m(arrayMomenta, std::array{MassKPlus, MassPiPlus})}; // registry.fill(HIST("hMass"), massKPi); } } @@ -141,15 +139,15 @@ struct HfTaskMiniCandidateCreator2ProngExpressions { struct HfTaskMiniCandidateSelectorD0 { Produces hfSelD0Candidate; - Configurable ptCandMin{"ptCandMin", 0.f, "Lower bound of candidate pT"}; - Configurable ptCandMax{"ptCandMax", 50.f, "Upper bound of candidate pT"}; + Configurable ptCandMin{"ptCandMin", 0.f, "Min. candidate pT [GeV/c] "}; + Configurable ptCandMax{"ptCandMax", 50.f, "Max. candidate pT [GeV/c]"}; // TPC - Configurable ptPidTpcMin{"ptPidTpcMin", 0.15f, "Lower bound of track pT for TPC PID"}; - Configurable ptPidTpcMax{"ptPidTpcMax", 5.f, "Upper bound of track pT for TPC PID"}; - Configurable nSigmaTpcMax{"nSigmaTpcMax", 3.f, "Nsigma cut on TPC only"}; + Configurable ptPidTpcMin{"ptPidTpcMin", 0.15f, "Min. track pT for TPC PID [GeV/c]"}; + Configurable ptPidTpcMax{"ptPidTpcMax", 5.f, "Max. track pT for TPC PID [GeV/c]"}; + Configurable nSigmaTpcMax{"nSigmaTpcMax", 3.f, "Max. TPC N_sigma"}; // topological cuts Configurable cpaMin{"cpaMin", 0.98f, "Min. cosine of pointing angle"}; - Configurable massWindow{"massWindow", 0.4f, "Half-width of the invariant-mass window"}; + Configurable massWindow{"massWindow", 0.4f, "Half-width of the invariant-mass window [Gev/c^2]"}; TrackSelectorPi selectorPion{}; TrackSelectorKa selectorKaon{}; @@ -214,18 +212,18 @@ struct HfTaskMiniCandidateSelectorD0 { int statusD0 = 0; int statusD0bar = 0; - const auto& trackPos = candidate.prong0_as(); // positive daughter - const auto& trackNeg = candidate.prong1_as(); // negative daughter - // conjugate-independent topological selection if (!selectionTopol(candidate)) { hfSelD0Candidate(statusD0, statusD0bar); continue; } - // conjugate-dependent topological selection for D0 + // conjugate-dependent topological selection + const auto& trackPos = candidate.prong0_as(); // positive daughter + const auto& trackNeg = candidate.prong1_as(); // negative daughter + // D0 hypothesis const auto topolD0 = selectionTopolConjugate(candidate, trackPos, trackNeg); - // conjugate-dependent topological selection for D0bar + // D0bar hypothesis const auto topolD0bar = selectionTopolConjugate(candidate, trackNeg, trackPos); if (!topolD0 && !topolD0bar) { @@ -295,8 +293,8 @@ struct HfTaskMiniD0 { const TString strTitle = "D^{0} candidates"; const TString strPt = "#it{p}_{T} (GeV/#it{c})"; const TString strEntries = "entries"; - registry.add("hPtCand", strTitle + ";" + strPt + ";" + strEntries, {HistType::kTH1D, {{100, 0., 10.}}}); - registry.add("hMass", strTitle + ";" + "inv. mass (#pi K) (GeV/#it{c}^{2})" + ";" + strEntries, {HistType::kTH1D, {{500, 0., 5.}}}); + registry.add("hPtCand", strTitle + ";" + strPt + ";" + strEntries, {HistType::kTH1F, {{100, 0., 10.}}}); + registry.add("hMass", strTitle + ";" + "inv. mass (#pi K) (GeV/#it{c}^{2})" + ";" + strEntries, {HistType::kTH1F, {{500, 0., 5.}}}); registry.add("hCpaVsPtCand", strTitle + ";" + "cosine of pointing angle" + ";" + strPt + ";" + strEntries, {HistType::kTH2F, {{110, -1.1, 1.1}, {100, 0., 10.}}}); } From 6d66b2fee7e9c9809ab9713980e62746f9c2f36e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Ku=C4=8Dera?= <26327373+vkucera@users.noreply.github.com> Date: Thu, 6 Nov 2025 15:55:28 +0100 Subject: [PATCH 8/9] Update docs --- Tutorials/PWGHF/README.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/Tutorials/PWGHF/README.md b/Tutorials/PWGHF/README.md index 4231260088f..90fd6847896 100644 --- a/Tutorials/PWGHF/README.md +++ b/Tutorials/PWGHF/README.md @@ -6,7 +6,7 @@ Welcome to the heavy-flavour analysis tutorial! This directory contains the code and configuration for running a minimalistic version of the D0 analysis on Run 3 data. -See the [official PWG-HF O2 documentation](https://aliceo2group.github.io/analysis-framework/docs/advanced-specifics/pwghf.html) for the overview of the full heavy-flavour analysis framework. +See the [PWG-HF O2 documentation](https://aliceo2group.github.io/analysis-framework/docs/advanced-specifics/pwghf.html) for the overview of the full heavy-flavour analysis framework. ## Setup @@ -30,10 +30,10 @@ This table contains paired track indices which point to tracks in the track tabl These derived skims are produced by executing the [`run_skim.sh`](run_skim.sh) bash script in the working directory: ```bash -bash ~/alice/O2Physics/Tutorials/PWGHF/run_skim.sh +~/alice/O2Physics/Tutorials/PWGHF/run_skim.sh ``` -It will use the configuration from [`dpl-config_skim.json`](dpl-config_skim.json) and produce the `AnalysisResults_trees.root` file with the derived table and the `AnalysisResults.root` file with control histograms in the working directory. +It processes files specified in `./input_skim.txt`, uses the configuration from [`dpl-config_skim.json`](dpl-config_skim.json), and produces the `./AnalysisResults_trees.root` file with the derived table and the `./AnalysisResults.root` file with control histograms. ## Mini task @@ -52,19 +52,21 @@ The absolute path to the parent file is stored in the derived file but it can be Run the mini task by executing the [`run_task.sh`](run_task.sh) bash script in the working directory: ```bash -bash ~/alice/O2Physics/Tutorials/PWGHF/run_task.sh +~/alice/O2Physics/Tutorials/PWGHF/run_task.sh ``` -It will use the configuration from [`dpl-config_task.json`](dpl-config_task.json) and produce the output file `AnalysisResults.root` with histograms in the working directory. +It processes files specified in `./input_task.txt`, uses the configuration from [`dpl-config_task.json`](dpl-config_task.json), and produces the `./AnalysisResults.root` file with histograms. ## Exercise tips Organise your working environment so that you can easily switch between running the code in the working directory and modifying the code in the O2Physics repository. -When you execute the bash script, the terminal output is saved in the `stdout.log` log file in the working directory. +When you execute the bash script, the terminal output is saved in the `./stdout.log` log file. If an error occurs, the script will report the non-zero exit code and ask you to check the log file to find the problem. +If you get errors that have to be tolerated, you need to remove the `--min-failure-level error` option from the command. -The full O2 configuration is dumped at the end of processing into the `dpl-config.json` file in the working directory. +The full O2 configuration is dumped at the end of processing into the `./dpl-config.json` file. +It is useful to compare it with the input configuration file to spot mismatches. See the [rebuilding instructions](https://aliceo2group.github.io/analysis-framework/docs/gettingstarted/installing.html#building-partially-for-development-using-ninja) in the analysis framework documentation for advice on compiling your code changes. From cc5388ea5c962154843a15f594bbf9f355a72d8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Ku=C4=8Dera?= <26327373+vkucera@users.noreply.github.com> Date: Thu, 6 Nov 2025 15:55:54 +0100 Subject: [PATCH 9/9] Make scripts executable. Fail on error. --- Tutorials/PWGHF/run_skim.sh | 1 + Tutorials/PWGHF/run_task.sh | 1 + 2 files changed, 2 insertions(+) mode change 100644 => 100755 Tutorials/PWGHF/run_skim.sh mode change 100644 => 100755 Tutorials/PWGHF/run_task.sh diff --git a/Tutorials/PWGHF/run_skim.sh b/Tutorials/PWGHF/run_skim.sh old mode 100644 new mode 100755 index 24a9151d4b7..83e85adde22 --- a/Tutorials/PWGHF/run_skim.sh +++ b/Tutorials/PWGHF/run_skim.sh @@ -40,6 +40,7 @@ OPTIONS_GLOBAL=( --shm-segment-size 16000000000 --resources-monitoring 2 --aod-file "@input_skim.txt" + --min-failure-level error ) # execute the mini skim creator workflow and its dependencies diff --git a/Tutorials/PWGHF/run_task.sh b/Tutorials/PWGHF/run_task.sh old mode 100644 new mode 100755 index cc4cb1a5d41..3f363c3279f --- a/Tutorials/PWGHF/run_task.sh +++ b/Tutorials/PWGHF/run_task.sh @@ -41,6 +41,7 @@ OPTIONS_GLOBAL=( --aod-parent-base-path-replacement "old-path-to-parent;new-path-to-parent" --aod-parent-access-level 1 --aod-file "@input_task.txt" + --min-failure-level error ) # execute the mini task workflow and its dependencies