From 26f42d3e6e03f0126a36e1006b6949cd7797a56b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Ku=C4=8Dera?= <26327373+vkucera@users.noreply.github.com> Date: Fri, 13 Mar 2026 17:20:29 +0100 Subject: [PATCH 1/2] Fix includes and using statements --- PWGCF/Core/AnalysisConfigurableCuts.cxx | 4 + PWGCF/Core/AnalysisConfigurableCuts.h | 2 - PWGCF/Core/CorrelationContainer.cxx | 37 +- PWGCF/Core/CorrelationContainer.h | 17 +- PWGCF/Core/PairCuts.h | 63 +- PWGCF/DataModel/CorrelationsDerived.h | 7 +- PWGCF/DataModel/DptDptFiltered.h | 6 +- PWGCF/DataModel/FemtoDerived.h | 19 +- PWGCF/DataModel/SPTableZDC.h | 6 +- .../Tasks/FactorialMomentsTask.cxx | 40 +- .../Tasks/MeanptFluctuations.cxx | 38 +- .../Tasks/NetProtonCumulants.cxx | 38 +- .../Tasks/RobustFluctuationObservables.cxx | 40 +- .../Tasks/antiprotonCumulantsMc.cxx | 43 +- .../EbyEFluctuations/Tasks/eventMeanPtId.cxx | 36 +- .../Tasks/kaonIsospinFluctuations.cxx | 24 +- PWGCF/EbyEFluctuations/Tasks/meanPtFlucId.cxx | 27 +- .../EbyEFluctuations/Tasks/nchCumulantsId.cxx | 22 +- .../Tasks/netchargeFluctuations.cxx | 39 +- .../Tasks/netprotonCumulantsMc.cxx | 43 +- PWGCF/EbyEFluctuations/Tasks/partNumFluc.cxx | 228 +- .../Tasks/radialFlowDecorr.cxx | 64 +- .../Tasks/v0ptHadPiKaProt.cxx | 43 +- PWGCF/Femto/Core/baseSelection.h | 6 +- PWGCF/Femto/Core/cascadeBuilder.h | 10 +- PWGCF/Femto/Core/cascadeHistManager.h | 13 +- PWGCF/Femto/Core/closePairRejection.h | 14 +- PWGCF/Femto/Core/closeTripletRejection.h | 4 +- PWGCF/Femto/Core/collisionBuilder.h | 10 +- PWGCF/Femto/Core/collisionHistManager.h | 8 +- PWGCF/Femto/Core/femtoUtils.h | 11 +- PWGCF/Femto/Core/histManager.h | 2 +- PWGCF/Femto/Core/kinkBuilder.h | 10 +- PWGCF/Femto/Core/kinkHistManager.h | 13 +- PWGCF/Femto/Core/mcBuilder.h | 7 +- PWGCF/Femto/Core/pairBuilder.h | 7 +- PWGCF/Femto/Core/pairCleaner.h | 2 +- PWGCF/Femto/Core/pairHistManager.h | 10 +- PWGCF/Femto/Core/pairProcessHelpers.h | 4 +- PWGCF/Femto/Core/particleCleaner.h | 2 +- PWGCF/Femto/Core/selectionContainer.h | 8 +- PWGCF/Femto/Core/trackBuilder.h | 10 +- PWGCF/Femto/Core/trackHistManager.h | 12 +- PWGCF/Femto/Core/tripletBuilder.h | 9 +- PWGCF/Femto/Core/tripletCleaner.h | 2 +- PWGCF/Femto/Core/tripletHistManager.h | 12 +- PWGCF/Femto/Core/tripletProcessHelpers.h | 4 +- PWGCF/Femto/Core/twoTrackResonanceBuilder.h | 19 +- .../Femto/Core/twoTrackResonanceHistManager.h | 12 +- PWGCF/Femto/Core/v0Builder.h | 10 +- PWGCF/Femto/Core/v0HistManager.h | 13 +- PWGCF/Femto/DataModel/FemtoTables.h | 6 +- .../DataModel/HadronNucleiTables.h | 5 +- .../TableProducer/HadNucleiFemto.cxx | 53 +- PWGCF/Femto/TableProducer/femtoProducer.cxx | 21 +- .../femtoProducerDerivedToDerived.cxx | 14 +- .../femtoProducerKinkPtConverter.cxx | 19 +- PWGCF/Femto/Tasks/femtoCascadeQa.cxx | 19 +- PWGCF/Femto/Tasks/femtoKinkQa.cxx | 19 +- PWGCF/Femto/Tasks/femtoPairTrackCascade.cxx | 21 +- PWGCF/Femto/Tasks/femtoPairTrackKink.cxx | 21 +- PWGCF/Femto/Tasks/femtoPairTrackTrack.cxx | 21 +- .../Tasks/femtoPairTrackTwoTrackResonance.cxx | 20 +- PWGCF/Femto/Tasks/femtoPairTrackV0.cxx | 21 +- PWGCF/Femto/Tasks/femtoPairV0V0.cxx | 21 +- PWGCF/Femto/Tasks/femtoTrackQa.cxx | 18 +- .../Tasks/femtoTripletTrackTrackTrack.cxx | 22 +- .../Femto/Tasks/femtoTripletTrackTrackV0.cxx | 23 +- .../Femto/Tasks/femtoTwotrackresonanceQa.cxx | 21 +- PWGCF/Femto/Tasks/femtoV0Qa.cxx | 19 +- PWGCF/Femto3D/Core/femto3dPairTask.h | 24 +- PWGCF/Femto3D/DataModel/PIDutils.h | 2 + PWGCF/Femto3D/DataModel/singletrackselector.h | 17 +- .../singleTrackSelectorConverter.cxx | 7 +- .../singleTrackSelectorConverterV1.cxx | 7 +- .../TableProducer/singleTrackSelector.cxx | 33 +- .../singleTrackSelectorExtra.cxx | 11 +- .../singleTrackSelectorPIDMaker.cxx | 16 +- PWGCF/Femto3D/Tasks/PIDoptimization.cxx | 41 +- PWGCF/Femto3D/Tasks/femto3dPairTask.cxx | 48 +- PWGCF/Femto3D/Tasks/femto3dPairTaskMC.cxx | 44 +- PWGCF/Femto3D/Tasks/femto3dQA.cxx | 40 +- PWGCF/Femto3D/Tools/checkPacking.cxx | 12 +- .../Core/femtoDreamCascadeSelection.h | 109 +- .../Core/femtoDreamCollisionSelection.h | 89 +- PWGCF/FemtoDream/Core/femtoDreamContainer.h | 83 +- .../Core/femtoDreamContainerThreeBody.h | 43 +- .../FemtoDream/Core/femtoDreamDetaDphiStar.h | 108 +- PWGCF/FemtoDream/Core/femtoDreamEventHisto.h | 23 +- PWGCF/FemtoDream/Core/femtoDreamMath.h | 15 +- .../Core/femtoDreamObjectSelection.h | 16 +- PWGCF/FemtoDream/Core/femtoDreamPairCleaner.h | 10 +- .../FemtoDream/Core/femtoDreamParticleHisto.h | 345 +- .../FemtoDream/Core/femtoDreamResoSelection.h | 108 +- PWGCF/FemtoDream/Core/femtoDreamSelection.h | 9 +- .../Core/femtoDreamTrackSelection.h | 147 +- PWGCF/FemtoDream/Core/femtoDreamUtils.h | 7 +- PWGCF/FemtoDream/Core/femtoDreamV0Selection.h | 103 +- .../Core/femtoDreamV0SelectionK0Short.h | 70 +- .../femtoDreamProducerReducedTask.cxx | 35 +- .../TableProducer/femtoDreamProducerTask.cxx | 43 +- ...toDreamProducerTaskForSpecificAnalysis.cxx | 29 +- .../femtoDreamProducerTaskReso.cxx | 44 +- .../Tasks/femtoDreamCollisionMasker.cxx | 32 +- .../Tasks/femtoDreamDebugCascade.cxx | 29 +- .../FemtoDream/Tasks/femtoDreamDebugReso.cxx | 25 +- .../FemtoDream/Tasks/femtoDreamDebugTrack.cxx | 26 +- PWGCF/FemtoDream/Tasks/femtoDreamDebugV0.cxx | 26 +- PWGCF/FemtoDream/Tasks/femtoDreamHashTask.cxx | 12 +- .../Tasks/femtoDreamPairEfficiency.cxx | 33 +- .../Tasks/femtoDreamPairTaskTrackCascade.cxx | 23 +- .../Tasks/femtoDreamPairTaskTrackTrack.cxx | 31 +- .../Tasks/femtoDreamPairTaskTrackV0.cxx | 39 +- .../Tasks/femtoDreamPairTaskV0Reso.cxx | 28 +- .../Tasks/femtoDreamPairTaskV0V0.cxx | 31 +- .../femtoDreamTripletTaskTrackTrackTrack.cxx | 42 +- ...mtoDreamTripletTaskTrackTrackTrackPbPb.cxx | 32 +- .../femtoDreamTripletTaskTrackTrackV0.cxx | 43 +- .../femtoDreamTripletTaskTrackTrackV0PbPb.cxx | 26 +- .../Tasks/femtodreamPairCascadeCascade.cxx | 23 +- .../FemtoDream/Utils/femtoDreamCutCulator.cxx | 8 +- PWGCF/FemtoDream/Utils/femtoDreamCutCulator.h | 24 +- .../Core/FemtoUniverse3DContainer.h | 59 +- .../Core/FemtoUniverseAngularContainer.h | 22 +- .../Core/FemtoUniverseCascadeSelection.h | 70 +- .../Core/FemtoUniverseCollisionSelection.h | 43 +- .../Core/FemtoUniverseContainer.h | 58 +- .../Core/FemtoUniverseCutculator.h | 9 +- .../Core/FemtoUniverseDetaDphiStar.h | 124 +- .../Core/FemtoUniverseEfficiencyCalculator.h | 30 +- .../Core/FemtoUniverseEfficiencyCorrection.h | 14 +- .../Core/FemtoUniverseEventHisto.h | 20 +- .../Core/FemtoUniverseFemtoContainer.h | 50 +- PWGCF/FemtoUniverse/Core/FemtoUniverseMath.h | 10 +- .../Core/FemtoUniverseObjectSelection.h | 15 +- .../FemtoUniversePairAngularWithCentMultKt.h | 18 +- .../Core/FemtoUniversePairCleaner.h | 9 +- .../Core/FemtoUniversePairSHCentMultKt.h | 38 +- .../Core/FemtoUniversePairWithCentMultKt.h | 30 +- .../Core/FemtoUniverseParticleHisto.h | 190 +- .../Core/FemtoUniversePhiSelection.h | 54 +- .../Core/FemtoUniverseSHContainer.h | 31 +- .../Core/FemtoUniverseSelection.h | 1 + .../Core/FemtoUniverseSoftPionRemoval.h | 15 +- .../Core/FemtoUniverseSpherHarMath.h | 9 +- .../Core/FemtoUniverseTrackSelection.h | 82 +- .../Core/FemtoUniverseV0Selection.h | 74 +- PWGCF/FemtoUniverse/Core/femtoUtils.h | 4 +- PWGCF/FemtoUniverse/DataModel/FemtoDerived.h | 11 +- .../Macros/calculateEfficiencyCorrection.cxx | 15 +- .../femtoUniverseProducerMCTruthTask.cxx | 11 +- .../femtoUniverseProducerReducedTask.cxx | 31 +- .../femtoUniverseProducerTask.cxx | 44 +- .../femtoUniverseProducerTaskV0Only.cxx | 31 +- .../Tasks/femtoUniverseCutCulator.cxx | 5 - .../Tasks/femtoUniverseDebugTrack.cxx | 24 +- .../Tasks/femtoUniverseDebugV0.cxx | 23 +- .../Tasks/femtoUniverseEfficiencyBase.cxx | 27 +- .../Tasks/femtoUniverseEfficiencyTask.cxx | 29 +- .../Tasks/femtoUniverseHashTask.cxx | 8 +- ...toUniversePairTaskTrackCascadeExtended.cxx | 37 +- .../Tasks/femtoUniversePairTaskTrackD0.cxx | 38 +- .../femtoUniversePairTaskTrackNucleus.cxx | 28 +- .../Tasks/femtoUniversePairTaskTrackPhi.cxx | 32 +- .../Tasks/femtoUniversePairTaskTrackTrack.cxx | 26 +- ...ersePairTaskTrackTrack3DMultKtExtended.cxx | 37 +- ...emtoUniversePairTaskTrackTrackExtended.cxx | 29 +- .../femtoUniversePairTaskTrackTrackMC.cxx | 35 +- ...femtoUniversePairTaskTrackTrackMcTruth.cxx | 28 +- ...iversePairTaskTrackTrackMultKtExtended.cxx | 29 +- ...irTaskTrackTrackSpherHarMultKtExtended.cxx | 36 +- .../femtoUniversePairTaskTrackV0Extended.cxx | 53 +- .../femtoUniversePairTaskTrackV0Helicity.cxx | 31 +- ...femtoUniversePairTaskV0CascadeExtended.cxx | 31 +- .../Core/FemtoWorldCollisionSelection.h | 37 +- PWGCF/FemtoWorld/Core/FemtoWorldContainer.h | 46 +- .../FemtoWorld/Core/FemtoWorldDetaDphiStar.h | 37 +- PWGCF/FemtoWorld/Core/FemtoWorldEventHisto.h | 19 +- PWGCF/FemtoWorld/Core/FemtoWorldMath.h | 9 +- .../Core/FemtoWorldObjectSelection.h | 20 +- PWGCF/FemtoWorld/Core/FemtoWorldPairCleaner.h | 12 +- .../Core/FemtoWorldPairWithCentrality.h | 19 +- .../FemtoWorld/Core/FemtoWorldParticleHisto.h | 42 +- .../FemtoWorld/Core/FemtoWorldPhiSelection.h | 135 +- .../FemtoWorld/Core/FemtoWorldPionContainer.h | 46 +- PWGCF/FemtoWorld/Core/FemtoWorldSelection.h | 8 +- .../Core/FemtoWorldTrackSelection.h | 92 +- PWGCF/FemtoWorld/Core/FemtoWorldUtils.h | 13 +- PWGCF/FemtoWorld/Core/FemtoWorldV0Selection.h | 79 +- .../FemtoWorld/DataModel/FemtoWorldDerived.h | 12 +- .../femtoWorldProducerReducedTask.cxx | 20 +- .../TableProducer/femtoWorldProducerTask.cxx | 48 +- .../femtoWorldProducerTaskV0Only.cxx | 20 +- .../Tasks/femtoWorldEfficiencyTask.cxx | 29 +- .../Tasks/femtoWorldEfficiencyTaskDe.cxx | 28 +- .../Tasks/femtoWorldPairTaskPionPion.cxx | 36 +- .../femtoWorldPairTaskProtonAntiproton.cxx | 38 +- .../Tasks/femtoWorldPairTaskTrackD0.cxx | 42 +- .../Tasks/femtoWorldPairTaskTrackPhi.cxx | 40 +- .../Tasks/femtoWorldPairTaskTrackTrack.cxx | 38 +- .../Tasks/femtoWorldPionAllPairTask.cxx | 40 +- .../femtoWorldPionPairTaskTrackTrack.cxx | 38 +- PWGCF/Flow/TableProducer/zdcQVectors.cxx | 68 +- PWGCF/Flow/Tasks/flowAnalysisGF.cxx | 67 +- PWGCF/Flow/Tasks/flowEfficiencyCasc.cxx | 23 +- PWGCF/Flow/Tasks/flowEsePHe3.cxx | 56 +- PWGCF/Flow/Tasks/flowEseTask.cxx | 50 +- PWGCF/Flow/Tasks/flowEventPlane.cxx | 28 +- PWGCF/Flow/Tasks/flowGfwEse.cxx | 41 +- PWGCF/Flow/Tasks/flowGfwOmegaXi.cxx | 44 +- PWGCF/Flow/Tasks/flowGfwTask.cxx | 43 +- PWGCF/Flow/Tasks/flowMc.cxx | 64 +- PWGCF/Flow/Tasks/flowPbpbPikp.cxx | 45 +- PWGCF/Flow/Tasks/flowPidCme.cxx | 57 +- PWGCF/Flow/Tasks/flowPtEfficiency.cxx | 32 +- PWGCF/Flow/Tasks/flowQa.cxx | 63 +- PWGCF/Flow/Tasks/flowRunbyRun.cxx | 68 +- PWGCF/Flow/Tasks/flowSP.cxx | 54 +- PWGCF/Flow/Tasks/flowTask.cxx | 41 +- PWGCF/Flow/Tasks/flowZdcEnergy.cxx | 42 +- PWGCF/Flow/Tasks/flowZdcTask.cxx | 24 +- PWGCF/Flow/Tasks/pidFlowPtCorr.cxx | 47 +- PWGCF/Flow/Tasks/resonancesGfwFlow.cxx | 52 +- .../Core/BootstrapProfile.cxx | 11 + .../GenericFramework/Core/BootstrapProfile.h | 12 +- PWGCF/GenericFramework/Core/FlowContainer.cxx | 19 + PWGCF/GenericFramework/Core/FlowContainer.h | 31 +- .../GenericFramework/Core/FlowPtContainer.cxx | 23 + PWGCF/GenericFramework/Core/FlowPtContainer.h | 25 +- PWGCF/GenericFramework/Core/GFW.cxx | 3 + PWGCF/GenericFramework/Core/GFW.h | 2 - PWGCF/GenericFramework/Core/GFWConfig.h | 8 +- PWGCF/GenericFramework/Core/GFWCumulant.cxx | 2 + PWGCF/GenericFramework/Core/GFWCumulant.h | 2 + PWGCF/GenericFramework/Core/GFWPowerArray.cxx | 6 + PWGCF/GenericFramework/Core/GFWPowerArray.h | 3 +- PWGCF/GenericFramework/Core/GFWWeights.cxx | 16 +- PWGCF/GenericFramework/Core/GFWWeights.h | 17 +- .../GenericFramework/Core/GFWWeightsList.cxx | 18 +- PWGCF/GenericFramework/Core/GFWWeightsList.h | 16 +- .../Core/GenericFrameworkLinkDef.h | 0 PWGCF/GenericFramework/Core/ProfileSubset.cxx | 14 +- PWGCF/GenericFramework/Core/ProfileSubset.h | 7 +- .../Tasks/flowGenericFramework.cxx | 100 +- .../Tasks/flowGfwLightIons.cxx | 43 +- PWGCF/JCorran/Core/FlowJHistManager.cxx | 11 +- PWGCF/JCorran/Core/FlowJHistManager.h | 17 +- PWGCF/JCorran/Core/FlowJSPCAnalysis.cxx | 9 +- PWGCF/JCorran/Core/FlowJSPCAnalysis.h | 23 +- PWGCF/JCorran/Core/FlowJSPCObservables.h | 8 +- PWGCF/JCorran/Core/JCORRANLinkDef.h | 0 PWGCF/JCorran/Core/JEPFlowAnalysis.cxx | 4 + PWGCF/JCorran/Core/JEPFlowAnalysis.h | 39 +- PWGCF/JCorran/Core/JFFlucAnalysis.cxx | 4 +- PWGCF/JCorran/Core/JFFlucAnalysis.h | 3 + PWGCF/JCorran/Core/JFFlucAnalysisO2Hist.cxx | 12 +- PWGCF/JCorran/Core/JFFlucAnalysisO2Hist.h | 7 +- PWGCF/JCorran/Core/JQVectors.h | 6 +- PWGCF/JCorran/DataModel/JCatalyst.h | 6 + PWGCF/JCorran/TableProducer/JCatalyst.cxx | 42 +- PWGCF/JCorran/Tasks/flowJNUACreation.cxx | 37 +- PWGCF/JCorran/Tasks/flowJSPCAnalysis.cxx | 51 +- PWGCF/JCorran/Tasks/jEPDzeroFlowAnalysis.cxx | 55 +- PWGCF/JCorran/Tasks/jEPFlowAnalysis.cxx | 32 +- PWGCF/JCorran/Tasks/jFlucEfficiencyTask.cxx | 26 +- PWGCF/JCorran/Tasks/jflucAnalysisTask.cxx | 40 +- PWGCF/JCorran/Tasks/jflucWeightsLoader.cxx | 30 +- .../Tasks/multiparticle-correlations-ab.cxx | 21027 +++++++++++++++- .../Tasks/multiparticle-correlations-ar.cxx | 41 +- .../Tasks/threeParticleCorrelations.cxx | 50 +- PWGCF/TableProducer/dptDptFilter.cxx | 34 +- PWGCF/TableProducer/dptDptFilter.h | 23 +- PWGCF/TableProducer/filter2Prong.cxx | 32 +- PWGCF/TableProducer/filterCorrelations.cxx | 48 +- PWGCF/Tasks/correlations.cxx | 42 +- PWGCF/Tasks/dptDptCorrelations.cxx | 37 +- PWGCF/Tasks/dptDptFilterQa.cxx | 16 +- PWGCF/Tasks/matchRecoGen.cxx | 32 +- PWGCF/Tutorial/CFTutorialTask0.cxx | 13 +- PWGCF/Tutorial/CFTutorialTask1.cxx | 14 +- PWGCF/Tutorial/CFTutorialTask2.cxx | 16 +- PWGCF/Tutorial/CFTutorialTask3.cxx | 17 +- PWGCF/Tutorial/CFTutorialTask4.cxx | 25 +- PWGCF/Tutorial/CFTutorialTask5.cxx | 27 +- .../Core/EventSelectionFilterAndAnalysis.cxx | 25 +- .../Core/EventSelectionFilterAndAnalysis.h | 26 +- .../Core/FilterAndAnalysisFramework.cxx | 25 +- .../Core/FilterAndAnalysisFramework.h | 21 +- .../Core/PIDSelectionFilterAndAnalysis.cxx | 25 +- .../Core/PIDSelectionFilterAndAnalysis.h | 21 +- .../Core/SelectionFilterAndAnalysis.cxx | 15 +- .../Core/SelectionFilterAndAnalysis.h | 17 +- .../Core/SkimmingConfigurableCuts.cxx | 19 +- .../Core/SkimmingConfigurableCuts.h | 32 +- .../Core/TrackSelectionFilterAndAnalysis.cxx | 22 +- .../Core/TrackSelectionFilterAndAnalysis.h | 24 +- .../DataModel/LongRangeDerived.h | 6 +- .../TwoParticleCorrelationsFiltered.h | 14 +- .../TwoParticleCorrelationsSkimmed.h | 29 +- .../Productions/skimmingconf_20221115.h | 6 +- .../TableProducer/longrangeMaker.cxx | 52 +- .../twoParticleCorrelationsFiltering.cxx | 26 +- .../twoParticleCorrelationsFullSkimming.cxx | 28 +- ...oParticleCorrelationsNotStoredSkimming.cxx | 27 +- ...woParticleCorrelationsRegisterSkimming.cxx | 14 +- .../Tasks/corrSparse.cxx | 64 +- .../Tasks/diHadronCor.cxx | 50 +- .../Tasks/dptDptEfficiencyAndQc.cxx | 34 +- .../Tasks/dptDptPerRunExtraQc.cxx | 19 +- .../Tasks/dptDptPerRunQc.cxx | 35 +- .../Tasks/etaDihadron.cxx | 50 +- .../Tasks/flowDecorrelation.cxx | 57 +- .../Tasks/lambdaR2Correlation.cxx | 33 +- .../Tasks/lambdaSpinPolarization.cxx | 36 +- .../Tasks/longRangeDihadronCor.cxx | 59 +- .../Tasks/longrangeCorrelation.cxx | 62 +- .../Tasks/longrangecorrDerived.cxx | 55 +- .../Tasks/neutronProtonCorrZdc.cxx | 28 +- .../Tasks/nucleibalance.cxx | 26 +- .../Tasks/pidDiHadron.cxx | 52 +- .../Tasks/r2p2-4-id.cxx | 26 +- .../Tasks/twoParticleCorrelationPp.cxx | 22 +- .../Tasks/twoParticleCorrelations.cxx | 33 +- 323 files changed, 26891 insertions(+), 4303 deletions(-) mode change 100755 => 100644 PWGCF/GenericFramework/Core/GenericFrameworkLinkDef.h mode change 100755 => 100644 PWGCF/JCorran/Core/JCORRANLinkDef.h diff --git a/PWGCF/Core/AnalysisConfigurableCuts.cxx b/PWGCF/Core/AnalysisConfigurableCuts.cxx index 19c4d6edec0..ff1c2880dfd 100644 --- a/PWGCF/Core/AnalysisConfigurableCuts.cxx +++ b/PWGCF/Core/AnalysisConfigurableCuts.cxx @@ -11,6 +11,10 @@ #include "PWGCF/Core/AnalysisConfigurableCuts.h" +#include + +#include + using namespace o2::analysis; ClassImp(SimpleInclusiveCut); diff --git a/PWGCF/Core/AnalysisConfigurableCuts.h b/PWGCF/Core/AnalysisConfigurableCuts.h index 820911c5832..76b7b759f07 100644 --- a/PWGCF/Core/AnalysisConfigurableCuts.h +++ b/PWGCF/Core/AnalysisConfigurableCuts.h @@ -16,9 +16,7 @@ #ifndef PWGCF_CORE_ANALYSISCONFIGURABLECUTS_H_ #define PWGCF_CORE_ANALYSISCONFIGURABLECUTS_H_ -#include #include -#include #include diff --git a/PWGCF/Core/CorrelationContainer.cxx b/PWGCF/Core/CorrelationContainer.cxx index 3267cda3988..8cbd834ec8f 100644 --- a/PWGCF/Core/CorrelationContainer.cxx +++ b/PWGCF/Core/CorrelationContainer.cxx @@ -15,20 +15,29 @@ // Author: Jan Fiete Grosse-Oetringhaus #include "PWGCF/Core/CorrelationContainer.h" -#include "Framework/StepTHn.h" -#include "Framework/Logger.h" -#include "THnSparse.h" -#include "TMath.h" -#include "TList.h" -#include "TCollection.h" -#include "TH1D.h" -#include "TH2D.h" -#include "TH3D.h" -#include "TCanvas.h" -#include "TF1.h" -#include "THn.h" -#include "Framework/HistogramSpec.h" -#include "CommonConstants/MathConstants.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include using namespace o2; using namespace o2::framework; diff --git a/PWGCF/Core/CorrelationContainer.h b/PWGCF/Core/CorrelationContainer.h index b037b7d7ad4..287eb9b1c5e 100644 --- a/PWGCF/Core/CorrelationContainer.h +++ b/PWGCF/Core/CorrelationContainer.h @@ -9,14 +9,19 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#ifndef CorrelationContainer_H -#define CorrelationContainer_H +#ifndef PWGCF_CORE_CORRELATIONCONTAINER_H_ +#define PWGCF_CORE_CORRELATIONCONTAINER_H_ // encapsulate histogram and corrections for correlation analysis -#include "TNamed.h" -#include "TString.h" -#include "Framework/HistogramSpec.h" +#include + +#include + +#include +#include + +#include class TH1; class TH1F; @@ -181,4 +186,4 @@ class CorrelationContainer : public TNamed ClassDef(CorrelationContainer, 2) // underlying event histogram container }; -#endif +#endif // PWGCF_CORE_CORRELATIONCONTAINER_H_ diff --git a/PWGCF/Core/PairCuts.h b/PWGCF/Core/PairCuts.h index b90094f30e2..86331562eb2 100644 --- a/PWGCF/Core/PairCuts.h +++ b/PWGCF/Core/PairCuts.h @@ -9,23 +9,22 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#ifndef O2_ANALYSIS_PAIRCUTS_H -#define O2_ANALYSIS_PAIRCUTS_H +#ifndef PWGCF_CORE_PAIRCUTS_H_ +#define PWGCF_CORE_PAIRCUTS_H_ -#include +#include +#include +#include +#include + +#include -#include "Framework/Logger.h" -#include "Framework/HistogramRegistry.h" -#include "CommonConstants/MathConstants.h" +#include // Functions which cut on particle pairs (decays, conversions, two-track cuts) // // Author: Jan Fiete Grosse-Oetringhaus -using namespace o2; -using namespace o2::framework; -using namespace constants::math; - class PairCuts { public: @@ -36,14 +35,14 @@ class PairCuts Rho, ParticlesLastEntry }; - void SetHistogramRegistry(HistogramRegistry* registry) { histogramRegistry = registry; } + void SetHistogramRegistry(o2::framework::HistogramRegistry* registry) { histogramRegistry = registry; } void SetPairCut(Particle particle, float cut) { LOGF(info, "Enabled pair cut for %d with value %f", static_cast(particle), cut); mCuts[particle] = cut; if (histogramRegistry != nullptr && histogramRegistry->contains(HIST("ControlConvResonances")) == false) { - histogramRegistry->add("ControlConvResonances", "", {HistType::kTH2F, {{6, -0.5, 5.5, "id"}, {500, -0.5, 0.5, "delta mass"}}}); + histogramRegistry->add("ControlConvResonances", "", {o2::framework::kTH2F, {{6, -0.5, 5.5, "id"}, {500, -0.5, 0.5, "delta mass"}}}); } } @@ -54,7 +53,7 @@ class PairCuts mTwoTrackRadius = radius; if (histogramRegistry != nullptr && histogramRegistry->contains(HIST("TwoTrackDistancePt_0")) == false) { - histogramRegistry->add("TwoTrackDistancePt_0", "", {HistType::kTH3F, {{100, -0.15, 0.15, "#Delta#eta"}, {100, -0.05, 0.05, "#Delta#varphi^{*}_{min}"}, {20, 0, 10, "#Delta p_{T}"}}}); + histogramRegistry->add("TwoTrackDistancePt_0", "", {o2::framework::HistType::kTH3F, {{100, -0.15, 0.15, "#Delta#eta"}, {100, -0.05, 0.05, "#Delta#varphi^{*}_{min}"}, {20, 0, 10, "#Delta p_{T}"}}}); histogramRegistry->addClone("TwoTrackDistancePt_0", "TwoTrackDistancePt_1"); } } @@ -70,7 +69,7 @@ class PairCuts float mTwoTrackDistance = -1; // distance below which the pair is flagged as to be removed float mTwoTrackRadius = 0.8f; // radius at which the two track cuts are applied - HistogramRegistry* histogramRegistry = nullptr; // if set, control histograms are stored here + o2::framework::HistogramRegistry* histogramRegistry = nullptr; // if set, control histograms are stored here template bool conversionCut(T const& track1, T const& track2, Particle conv, double cut); @@ -147,7 +146,7 @@ bool PairCuts::twoTrackCut(T const& track1, T const& track2, int magField) } if (dphistarminabs < mTwoTrackDistance && std::fabs(deta) < mTwoTrackDistance) { - //LOGF(debug, "Removed track pair %ld %ld with %f %f %f %f %d %f %f %d %d", track1.index(), track2.index(), deta, dphistarminabs, track1.phi2(), track1.pt(), track1.sign(), track2.phi2(), track2.pt(), track2.sign(), magField); + // LOGF(debug, "Removed track pair %ld %ld with %f %f %f %f %d %f %f %d %d", track1.index(), track2.index(), deta, dphistarminabs, track1.phi2(), track1.pt(), track1.sign(), track2.phi2(), track2.pt(), track2.sign(), magField); return true; } @@ -163,7 +162,7 @@ bool PairCuts::twoTrackCut(T const& track1, T const& track2, int magField) template bool PairCuts::conversionCut(T const& track1, T const& track2, Particle conv, double cut) { - //LOGF(info, "pt is %f %f", track1.pt(), track2.pt()); + // LOGF(info, "pt is %f %f", track1.pt(), track2.pt()); if (cut < 0) { return false; @@ -286,25 +285,25 @@ double PairCuts::getInvMassSquaredFast(T const& track1, double m0_1, T const& tr // fold onto 0...pi float deltaPhi = std::fabs(phi1 - phi2); - while (deltaPhi > TwoPI) { - deltaPhi -= TwoPI; + while (deltaPhi > o2::constants::math::TwoPI) { + deltaPhi -= o2::constants::math::TwoPI; } - if (deltaPhi > PI) { - deltaPhi = TwoPI - deltaPhi; + if (deltaPhi > o2::constants::math::PI) { + deltaPhi = o2::constants::math::TwoPI - deltaPhi; } float cosDeltaPhi = 0; - if (deltaPhi < PI / 3.0f) { + if (deltaPhi < o2::constants::math::PI / 3.0f) { cosDeltaPhi = 1.0 - deltaPhi * deltaPhi / 2 + deltaPhi * deltaPhi * deltaPhi * deltaPhi / 24; - } else if (deltaPhi < 2.0f * PI / 3.0f) { - cosDeltaPhi = -(deltaPhi - PI / 2) + 1.0 / 6 * std::pow((deltaPhi - PI / 2), 3); + } else if (deltaPhi < 2.0f * o2::constants::math::PI / 3.0f) { + cosDeltaPhi = -(deltaPhi - o2::constants::math::PI / 2) + 1.0 / 6 * std::pow((deltaPhi - o2::constants::math::PI / 2), 3); } else { - cosDeltaPhi = -1.0f + 1.0f / 2.0f * (deltaPhi - PI) * (deltaPhi - PI) - 1.0f / 24.0f * std::pow(deltaPhi - PI, 4.0f); + cosDeltaPhi = -1.0f + 1.0f / 2.0f * (deltaPhi - o2::constants::math::PI) * (deltaPhi - o2::constants::math::PI) - 1.0f / 24.0f * std::pow(deltaPhi - o2::constants::math::PI, 4.0f); } double mass2 = m0_1 * m0_1 + m0_2 * m0_2 + 2.0f * (std::sqrt(e1squ * e2squ) - (pt1 * pt2 * (cosDeltaPhi + 1.0f / tantheta1 / tantheta2))); - //LOGF(debug, "%f %f %f %f %f %f %f %f %f", pt1, eta1, phi1, pt2, eta2, phi2, m0_1, m0_2, mass2); + // LOGF(debug, "%f %f %f %f %f %f %f %f %f", pt1, eta1, phi1, pt2, eta2, phi2, m0_1, m0_2, mass2); return mass2; } @@ -326,17 +325,17 @@ float PairCuts::getDPhiStar(T const& track1, T const& track2, float radius, int float dphistar = phi1 - phi2 - charge1 * std::asin(0.015 * magField * radius / pt1) + charge2 * std::asin(0.015 * magField * radius / pt2); - if (dphistar > PI) { - dphistar = TwoPI - dphistar; + if (dphistar > o2::constants::math::PI) { + dphistar = o2::constants::math::TwoPI - dphistar; } - if (dphistar < -PI) { - dphistar = -TwoPI - dphistar; + if (dphistar < -o2::constants::math::PI) { + dphistar = -o2::constants::math::TwoPI - dphistar; } - if (dphistar > PI) { // might look funny but is needed - dphistar = TwoPI - dphistar; + if (dphistar > o2::constants::math::PI) { // might look funny but is needed + dphistar = o2::constants::math::TwoPI - dphistar; } return dphistar; } -#endif +#endif // PWGCF_CORE_PAIRCUTS_H_ diff --git a/PWGCF/DataModel/CorrelationsDerived.h b/PWGCF/DataModel/CorrelationsDerived.h index 8af9d7fef71..3f9f8b74e40 100644 --- a/PWGCF/DataModel/CorrelationsDerived.h +++ b/PWGCF/DataModel/CorrelationsDerived.h @@ -11,11 +11,10 @@ #ifndef PWGCF_DATAMODEL_CORRELATIONSDERIVED_H_ #define PWGCF_DATAMODEL_CORRELATIONSDERIVED_H_ -#include "Common/DataModel/Centrality.h" - -#include "Framework/ASoA.h" -#include "Framework/AnalysisDataModel.h" +#include +#include +#include #include namespace o2::aod diff --git a/PWGCF/DataModel/DptDptFiltered.h b/PWGCF/DataModel/DptDptFiltered.h index c9b3b9fba3c..9513a3f1786 100644 --- a/PWGCF/DataModel/DptDptFiltered.h +++ b/PWGCF/DataModel/DptDptFiltered.h @@ -11,8 +11,10 @@ #ifndef PWGCF_DATAMODEL_DPTDPTFILTERED_H_ #define PWGCF_DATAMODEL_DPTDPTFILTERED_H_ -#include "Framework/ASoA.h" -#include "Framework/AnalysisDataModel.h" +#include +#include + +#include namespace o2 { diff --git a/PWGCF/DataModel/FemtoDerived.h b/PWGCF/DataModel/FemtoDerived.h index 16e52a2e262..4f15d00a342 100644 --- a/PWGCF/DataModel/FemtoDerived.h +++ b/PWGCF/DataModel/FemtoDerived.h @@ -11,22 +11,17 @@ #ifndef PWGCF_DATAMODEL_FEMTODERIVED_H_ #define PWGCF_DATAMODEL_FEMTODERIVED_H_ -#include "PWGHF/Core/HfHelper.h" -#include "PWGHF/DataModel/CandidateReconstructionTables.h" -#include "PWGHF/DataModel/CandidateSelectionTables.h" - -#include "Common/DataModel/Multiplicity.h" -#include "Common/DataModel/PIDResponseTOF.h" -#include "Common/DataModel/PIDResponseTPC.h" +#include "Common/Core/RecoDecay.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "Framework/ASoA.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/DataTypes.h" -#include "Framework/Expressions.h" -#include "MathUtils/Utils.h" +#include +#include +#include +#include #include +#include +#include namespace o2::aod { diff --git a/PWGCF/DataModel/SPTableZDC.h b/PWGCF/DataModel/SPTableZDC.h index 1410b038e4f..7196e179787 100644 --- a/PWGCF/DataModel/SPTableZDC.h +++ b/PWGCF/DataModel/SPTableZDC.h @@ -17,12 +17,10 @@ #ifndef PWGCF_DATAMODEL_SPTABLEZDC_H_ #define PWGCF_DATAMODEL_SPTABLEZDC_H_ -#include "Common/Core/RecoDecay.h" -#include "Common/DataModel/TrackSelectionTables.h" - -#include "Framework/AnalysisDataModel.h" +#include #include +#include #include namespace o2::aod diff --git a/PWGCF/EbyEFluctuations/Tasks/FactorialMomentsTask.cxx b/PWGCF/EbyEFluctuations/Tasks/FactorialMomentsTask.cxx index 9ca0bbb7e3f..a4c5f1d9f8d 100644 --- a/PWGCF/EbyEFluctuations/Tasks/FactorialMomentsTask.cxx +++ b/PWGCF/EbyEFluctuations/Tasks/FactorialMomentsTask.cxx @@ -13,26 +13,40 @@ /// \author Salman Malik /// \author Balwan Singh -#include "TRandom.h" -#include - -// O2 includes +#include "Common/CCDB/EventSelectionParams.h" +#include "Common/CCDB/TriggerAliases.h" #include "Common/Core/RecoDecay.h" -#include "Common/Core/TrackSelection.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "Framework/runDataProcessing.h" -#include "ReconstructionDataFormats/GlobalTrackID.h" -#include "ReconstructionDataFormats/Track.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include -#include +#include +#include +#include +#include +#include #include using namespace o2; diff --git a/PWGCF/EbyEFluctuations/Tasks/MeanptFluctuations.cxx b/PWGCF/EbyEFluctuations/Tasks/MeanptFluctuations.cxx index c67c9f767f8..e6a2d4c1225 100644 --- a/PWGCF/EbyEFluctuations/Tasks/MeanptFluctuations.cxx +++ b/PWGCF/EbyEFluctuations/Tasks/MeanptFluctuations.cxx @@ -13,40 +13,42 @@ /// \brief Task for analyzing fluctuation upto fourth order of inclusive hadrons /// \author Swati Saha -#include "Common/Core/TrackSelection.h" +#include "Common/CCDB/EventSelectionParams.h" +#include "Common/CCDB/TriggerAliases.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "CommonConstants/MathConstants.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/runDataProcessing.h" #include - -#include "TDatabasePDG.h" -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include #include -#include -#include -#include #include -#include -#include -#include #include #include #include #include +#include #include -#include +#include #include +#include #include -#include +#include #include #include diff --git a/PWGCF/EbyEFluctuations/Tasks/NetProtonCumulants.cxx b/PWGCF/EbyEFluctuations/Tasks/NetProtonCumulants.cxx index f8db71203fa..a0e91f90faa 100644 --- a/PWGCF/EbyEFluctuations/Tasks/NetProtonCumulants.cxx +++ b/PWGCF/EbyEFluctuations/Tasks/NetProtonCumulants.cxx @@ -9,29 +9,39 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#include "Common/Core/TrackSelection.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/PIDResponseTOF.h" #include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/runDataProcessing.h" #include - -#include "TList.h" -#include "TMath.h" -#include "TProfile.h" -#include "TProfile2D.h" -#include "TRandom3.h" - +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include #include +#include +#include #include +#include + namespace o2::aod { namespace netprotonNum @@ -59,7 +69,7 @@ struct NetProtonCumulants_Table_QA { // Filter command*********** Filter collisionFilter = nabs(aod::collision::posZ) < cfgCutVertex; - Filter trackFilter = (nabs(aod::track::eta) < 0.8f) && (aod::track::pt > cfgCutPtLower) && (aod::track::pt < 5.0f) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true)) && (aod::track::tpcChi2NCl < cfgCutTpcChi2NCl); + Filter trackFilter = (nabs(aod::track::eta) < 0.8f) && (aod::track::pt > cfgCutPtLower) && (aod::track::pt < 5.0f) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t)true)) && (aod::track::tpcChi2NCl < cfgCutTpcChi2NCl); // Connect to ccdb Service ccdb; diff --git a/PWGCF/EbyEFluctuations/Tasks/RobustFluctuationObservables.cxx b/PWGCF/EbyEFluctuations/Tasks/RobustFluctuationObservables.cxx index 82e77dc45f8..ef3bc2bfeec 100644 --- a/PWGCF/EbyEFluctuations/Tasks/RobustFluctuationObservables.cxx +++ b/PWGCF/EbyEFluctuations/Tasks/RobustFluctuationObservables.cxx @@ -15,8 +15,7 @@ #include "PWGLF/DataModel/LFStrangenessTables.h" #include "Common/CCDB/EventSelectionParams.h" -#include "Common/Core/TrackSelection.h" -#include "Common/Core/TrackSelectionDefaults.h" +#include "Common/CCDB/TriggerAliases.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/FT0Corrected.h" @@ -25,18 +24,31 @@ #include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "CCDB/BasicCCDBManager.h" -#include "DataFormatsFT0/Digit.h" -#include "DataFormatsParameters/GRPECSObject.h" -#include "DataFormatsParameters/GRPMagField.h" -#include "DataFormatsParameters/GRPObject.h" -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" - -#include "TF1.h" -#include "TGraphErrors.h" - -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include #include #include #include diff --git a/PWGCF/EbyEFluctuations/Tasks/antiprotonCumulantsMc.cxx b/PWGCF/EbyEFluctuations/Tasks/antiprotonCumulantsMc.cxx index 6bc72a2c9e2..c96e1abbf65 100644 --- a/PWGCF/EbyEFluctuations/Tasks/antiprotonCumulantsMc.cxx +++ b/PWGCF/EbyEFluctuations/Tasks/antiprotonCumulantsMc.cxx @@ -13,47 +13,38 @@ /// \brief Task for analyzing efficiency of proton, and net-proton distributions in MC reconstructed and generated, and calculating net-proton cumulants /// \author Swati Saha -#include "Common/Core/TrackSelection.h" -#include "Common/Core/trackUtilities.h" +#include "Common/CCDB/EventSelectionParams.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponseITS.h" #include "Common/DataModel/PIDResponseTOF.h" #include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "CommonConstants/PhysicsConstants.h" -#include "DataFormatsParameters/GRPMagField.h" -#include "DataFormatsParameters/GRPObject.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/StepTHn.h" -#include "Framework/runDataProcessing.h" -#include "ReconstructionDataFormats/Track.h" #include - -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include #include -#include -#include -#include #include #include #include #include +#include #include +#include #include +#include #include #include #include @@ -119,7 +110,7 @@ struct AntiprotonCumulantsMc { // Filter command for rec (data)*********** Filter collisionFilter = nabs(aod::collision::posZ) < cfgCutVertex; - Filter trackFilter = (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPtLower) && (aod::track::pt < 5.0f) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true)) && (aod::track::tpcChi2NCl < cfgCutTpcChi2NCl) && (aod::track::itsChi2NCl < cfgCutItsChi2NCl) && (nabs(aod::track::dcaZ) < cfgCutDCAz) && (nabs(aod::track::dcaXY) < cfgCutDCAxy); + Filter trackFilter = (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPtLower) && (aod::track::pt < 5.0f) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t)true)) && (aod::track::tpcChi2NCl < cfgCutTpcChi2NCl) && (aod::track::itsChi2NCl < cfgCutItsChi2NCl) && (nabs(aod::track::dcaZ) < cfgCutDCAz) && (nabs(aod::track::dcaXY) < cfgCutDCAxy); // filtering collisions and tracks for real data*********** using AodCollisions = soa::Filtered>; diff --git a/PWGCF/EbyEFluctuations/Tasks/eventMeanPtId.cxx b/PWGCF/EbyEFluctuations/Tasks/eventMeanPtId.cxx index 693c057ad9b..205ec98bf88 100644 --- a/PWGCF/EbyEFluctuations/Tasks/eventMeanPtId.cxx +++ b/PWGCF/EbyEFluctuations/Tasks/eventMeanPtId.cxx @@ -14,36 +14,33 @@ /// \author Sweta Singh (sweta.singh@cern.ch) #include "PWGCF/Core/CorrelationContainer.h" -#include "PWGCF/Core/PairCuts.h" #include "Common/CCDB/EventSelectionParams.h" -#include "Common/CCDB/TriggerAliases.h" -#include "Common/Core/TrackSelection.h" -#include "Common/Core/trackUtilities.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/FT0Corrected.h" #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponseTOF.h" #include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "CCDB/BasicCCDBManager.h" -#include "CommonConstants/MathConstants.h" -#include "CommonConstants/PhysicsConstants.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/runDataProcessing.h" - -#include "TF1.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include #include -#include -#include +#include +#include #include #include @@ -56,7 +53,6 @@ using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; using namespace std; -using o2::constants::physics::Pdg; struct EventMeanPtId { diff --git a/PWGCF/EbyEFluctuations/Tasks/kaonIsospinFluctuations.cxx b/PWGCF/EbyEFluctuations/Tasks/kaonIsospinFluctuations.cxx index 987f540c37a..0f3a0a3c0d7 100644 --- a/PWGCF/EbyEFluctuations/Tasks/kaonIsospinFluctuations.cxx +++ b/PWGCF/EbyEFluctuations/Tasks/kaonIsospinFluctuations.cxx @@ -15,7 +15,6 @@ /// \author Rahul Verma (rahul.verma@iitb.ac.in) :: Sadhana Dash (sadhana@phy.iitb.ac.in) #include "PWGLF/DataModel/LFStrangenessTables.h" -#include "PWGLF/DataModel/mcCentrality.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" @@ -24,11 +23,28 @@ #include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "Framework/AnalysisTask.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "Framework/runDataProcessing.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include #include +#include +#include #include using namespace o2; diff --git a/PWGCF/EbyEFluctuations/Tasks/meanPtFlucId.cxx b/PWGCF/EbyEFluctuations/Tasks/meanPtFlucId.cxx index 9b3e0d943bb..e5d0739e8d3 100644 --- a/PWGCF/EbyEFluctuations/Tasks/meanPtFlucId.cxx +++ b/PWGCF/EbyEFluctuations/Tasks/meanPtFlucId.cxx @@ -16,7 +16,7 @@ /// /// \author Tanu Gahlaut -#include "Common/Core/RecoDecay.h" +#include "Common/CCDB/EventSelectionParams.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" @@ -24,19 +24,24 @@ #include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "CCDB/BasicCCDBManager.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/HistogramSpec.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "Framework/runDataProcessing.h" - +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include #include #include -#include +#include #include using namespace o2; diff --git a/PWGCF/EbyEFluctuations/Tasks/nchCumulantsId.cxx b/PWGCF/EbyEFluctuations/Tasks/nchCumulantsId.cxx index 3f683b99589..1d0ed075e69 100644 --- a/PWGCF/EbyEFluctuations/Tasks/nchCumulantsId.cxx +++ b/PWGCF/EbyEFluctuations/Tasks/nchCumulantsId.cxx @@ -20,15 +20,19 @@ #include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/HistogramSpec.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "Framework/runDataProcessing.h" - -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include #include using namespace o2; diff --git a/PWGCF/EbyEFluctuations/Tasks/netchargeFluctuations.cxx b/PWGCF/EbyEFluctuations/Tasks/netchargeFluctuations.cxx index 77f8c37a625..7b5cf8ad25d 100644 --- a/PWGCF/EbyEFluctuations/Tasks/netchargeFluctuations.cxx +++ b/PWGCF/EbyEFluctuations/Tasks/netchargeFluctuations.cxx @@ -16,34 +16,33 @@ /// /// \author Nida Malik #include "PWGCF/Core/CorrelationContainer.h" -#include "PWGCF/Core/PairCuts.h" #include "Common/CCDB/EventSelectionParams.h" #include "Common/CCDB/TriggerAliases.h" -#include "Common/Core/TrackSelection.h" -#include "Common/Core/trackUtilities.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/FT0Corrected.h" #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "CCDB/BasicCCDBManager.h" -#include "CommonConstants/MathConstants.h" -#include "CommonConstants/PhysicsConstants.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/runDataProcessing.h" - -#include "TF1.h" -#include "TProfile.h" -#include "TProfile2D.h" -#include "TRandom3.h" - +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include #include #include diff --git a/PWGCF/EbyEFluctuations/Tasks/netprotonCumulantsMc.cxx b/PWGCF/EbyEFluctuations/Tasks/netprotonCumulantsMc.cxx index 71659684daa..567c1152fda 100644 --- a/PWGCF/EbyEFluctuations/Tasks/netprotonCumulantsMc.cxx +++ b/PWGCF/EbyEFluctuations/Tasks/netprotonCumulantsMc.cxx @@ -13,47 +13,38 @@ /// \brief Task for analyzing efficiency of proton, and net-proton distributions in MC reconstructed and generated, and calculating net-proton cumulants /// \author Swati Saha -#include "Common/Core/TrackSelection.h" -#include "Common/Core/trackUtilities.h" +#include "Common/CCDB/EventSelectionParams.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponseITS.h" #include "Common/DataModel/PIDResponseTOF.h" #include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "CommonConstants/PhysicsConstants.h" -#include "DataFormatsParameters/GRPMagField.h" -#include "DataFormatsParameters/GRPObject.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/StepTHn.h" -#include "Framework/runDataProcessing.h" -#include "ReconstructionDataFormats/Track.h" #include - -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include #include -#include -#include -#include #include #include #include #include +#include #include +#include #include +#include #include #include #include @@ -119,7 +110,7 @@ struct NetprotonCumulantsMc { // Filter command for rec (data)*********** Filter collisionFilter = nabs(aod::collision::posZ) < cfgCutVertex; - Filter trackFilter = (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPtLower) && (aod::track::pt < 5.0f) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true)) && (aod::track::tpcChi2NCl < cfgCutTpcChi2NCl) && (aod::track::itsChi2NCl < cfgCutItsChi2NCl) && (nabs(aod::track::dcaZ) < cfgCutDCAz) && (nabs(aod::track::dcaXY) < cfgCutDCAxy); + Filter trackFilter = (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPtLower) && (aod::track::pt < 5.0f) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t)true)) && (aod::track::tpcChi2NCl < cfgCutTpcChi2NCl) && (aod::track::itsChi2NCl < cfgCutItsChi2NCl) && (nabs(aod::track::dcaZ) < cfgCutDCAz) && (nabs(aod::track::dcaXY) < cfgCutDCAxy); // filtering collisions and tracks for real data*********** using AodCollisions = soa::Filtered>; diff --git a/PWGCF/EbyEFluctuations/Tasks/partNumFluc.cxx b/PWGCF/EbyEFluctuations/Tasks/partNumFluc.cxx index a92d235b395..1e766ac33c3 100644 --- a/PWGCF/EbyEFluctuations/Tasks/partNumFluc.cxx +++ b/PWGCF/EbyEFluctuations/Tasks/partNumFluc.cxx @@ -13,6 +13,8 @@ /// \brief Task for particle number fluctuation analysis /// \author Fan Si +#include "Common/CCDB/EventSelectionParams.h" +#include "Common/CCDB/RCTSelectionFlags.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/McCollisionExtra.h" @@ -25,10 +27,15 @@ #include #include #include -#include #include +#include #include +#include +#include +#include +#include #include +#include #include #include @@ -1157,17 +1164,18 @@ struct PartNumFluc { if (groupAnalysis.cfgFlagQaEvent.value) { LOG(info) << "Enabling event QA."; - const AxisSpec asNGlobalTracks(200, -0.5, 199.5, "nGlobalTracks"); + const AxisSpec asNTracks(200, -0.5, 199.5); + const HistogramConfigSpec hcsQaEvent(HistType::kTHnSparseD, {asNTracks, asNTracks}); hrQaEvent.add("QaEvent/hVxVy", "", {HistType::kTHnSparseD, {{150, -0.15, 0.15, "#it{V}_{#it{x}} (cm)"}, {150, -0.15, 0.15, "#it{V}_{#it{y}} (cm)"}}}); hrQaEvent.add("QaEvent/hVz", "", {HistType::kTH1D, {{300, -15., 15., "#it{V}_{#it{z}} (cm)"}}}); - hrQaEvent.add("QaEvent/hNPvContributorsNGlobalTracks", "", {HistType::kTHnSparseF, {{200, -0.5, 199.5, "nPvContributors"}, asNGlobalTracks}}); - hrQaEvent.add("QaEvent/hNGlobalTracksMeanDcaXy", "", {HistType::kTHnSparseF, {asNGlobalTracks, {200, -0.5, 0.5, "#LTDCA_{#it{xy}}#GT_{event} (cm)"}}}); - hrQaEvent.add("QaEvent/hNGlobalTracksMeanDcaXy_nPvContributorsCut", "", {HistType::kTHnSparseF, {asNGlobalTracks, {200, -0.5, 0.5, "#LTDCA_{#it{z}}#GT_{event} (cm)"}}}); - hrQaEvent.add("QaEvent/hNGlobalTracksMeanDcaZ", "", {HistType::kTHnSparseF, {asNGlobalTracks, {200, -2., 2., "#LTDCA_{#it{z}}#GT_{event} (cm)"}}}); - hrQaEvent.add("QaEvent/hNGlobalTracksMeanDcaZ_nPvContributorsCut", "", {HistType::kTHnSparseF, {asNGlobalTracks, {200, -2., 2., "#LTDCA_{#it{z}}#GT_{event} (cm)"}}}); - hrQaEvent.add("QaEvent/hNTofBetaNGlobalTracks", "", {HistType::kTHnSparseF, {{200, -0.5, 199.5, "nTofBeta"}, asNGlobalTracks}}); - hrQaEvent.add("QaEvent/hNTofBetaNGlobalTracks_nPvContributorsCut", "", {HistType::kTHnSparseF, {{200, -0.5, 199.5, "nTofBeta"}, asNGlobalTracks}}); + hrQaEvent.add("QaEvent/hNPvContributorsNGlobalTracks", ";nPvContributors;nGlobalTracks;", hcsQaEvent); + hrQaEvent.add("QaEvent/hNGlobalTracksMeanDcaXy", ";nGlobalTracks;", {HistType::kTHnSparseD, {asNTracks, {250, -0.25, 0.25, "#LTDCA_{#it{xy}}#GT_{event} (cm)"}}}); + hrQaEvent.add("QaEvent/hNGlobalTracksMeanDcaXy_nPvContributorsCut", ";nGlobalTracks;", {HistType::kTHnSparseD, {asNTracks, {250, -0.25, 0.25, "#LTDCA_{#it{z}}#GT_{event} (cm)"}}}); + hrQaEvent.add("QaEvent/hNGlobalTracksMeanDcaZ", ";nGlobalTracks;", {HistType::kTHnSparseD, {asNTracks, {200, -2., 2., "#LTDCA_{#it{z}}#GT_{event} (cm)"}}}); + hrQaEvent.add("QaEvent/hNGlobalTracksMeanDcaZ_nPvContributorsCut", ";nGlobalTracks;", {HistType::kTHnSparseD, {asNTracks, {200, -2., 2., "#LTDCA_{#it{z}}#GT_{event} (cm)"}}}); + hrQaEvent.add("QaEvent/hNTofBetaNGlobalTracks", ";nTofBeta;nGlobalTracks;", hcsQaEvent); + hrQaEvent.add("QaEvent/hNTofBetaNGlobalTracks_nPvContributorsCut", ";nTofBeta;nGlobalTracks;", hcsQaEvent); } if (groupAnalysis.cfgFlagQaCentrality.value) { @@ -1199,14 +1207,13 @@ struct PartNumFluc { LOG(info) << "Enabling DCA QA."; const AxisSpec asPt(200, 0., 2., "#it{p}_{T} (GeV/#it{c})"); - const AxisSpec asDca(400, -1., 1.); - hrQaDca.add("QaDca/hPtDcaXy_p", ";;DCA_{#it{xy}} (cm)", {HistType::kTHnSparseD, {asPt, asDca}}); - hrQaDca.add("QaDca/hPtDcaXy_m", ";;DCA_{#it{xy}} (cm)", {HistType::kTHnSparseD, {asPt, asDca}}); + hrQaDca.add("QaDca/hPtDcaXy_p", "", {HistType::kTHnSparseD, {asPt, {500, -0.5, 0.5, "DCA_{#it{xy}} (cm)"}}}); + hrQaDca.add("QaDca/hPtDcaXy_m", "", {HistType::kTHnSparseD, {asPt, {500, -0.5, 0.5, "DCA_{#it{xy}} (cm)"}}}); hrQaDca.add("QaDca/pPtDcaXy_p", ";;#LTDCA_{#it{xy}}#GT (cm)", {HistType::kTProfile, {asPt}}); hrQaDca.add("QaDca/pPtDcaXy_m", ";;#LTDCA_{#it{xy}}#GT (cm)", {HistType::kTProfile, {asPt}}); - hrQaDca.add("QaDca/hPtDcaZ_p", ";;DCA_{#it{z}} (cm)", {HistType::kTHnSparseD, {asPt, asDca}}); - hrQaDca.add("QaDca/hPtDcaZ_m", ";;DCA_{#it{z}} (cm)", {HistType::kTHnSparseD, {asPt, asDca}}); + hrQaDca.add("QaDca/hPtDcaZ_p", "", {HistType::kTHnSparseD, {asPt, {500, -1., 1., "DCA_{#it{z}} (cm)"}}}); + hrQaDca.add("QaDca/hPtDcaZ_m", "", {HistType::kTHnSparseD, {asPt, {500, -1., 1., "DCA_{#it{z}} (cm)"}}}); hrQaDca.add("QaDca/pPtDcaZ_p", ";;#LTDCA_{#it{z}}#GT (cm)", {HistType::kTProfile, {asPt}}); hrQaDca.add("QaDca/pPtDcaZ_m", ";;#LTDCA_{#it{z}}#GT (cm)", {HistType::kTProfile, {asPt}}); } @@ -1363,26 +1370,25 @@ struct PartNumFluc { } if (groupAnalysis.cfgFlagQaPidPi.value || groupAnalysis.cfgFlagQaPidKa.value || groupAnalysis.cfgFlagQaPidPr.value) { - const AxisSpec asPt(40, 0., 2., "#it{p}_{T} (GeV/#it{c})"); - const AxisSpec asEta(32, -0.8, 0.8, "#it{#eta}"); + const HistogramConfigSpec hcsQaPid(HistType::kTHnSparseF, {asCentrality, {40, 0., 2., "#it{p}_{T} (GeV/#it{c})"}, {32, -0.8, 0.8, "#it{#eta}"}, {200, -10., 10.}}); if (groupAnalysis.cfgFlagQaPidPi.value) { LOG(info) << "Enabling pion PID QA."; if (doprocessMc.value) { - hrQaPid.add("QaPid/hCentralityPtEtaTpcNSigmaPi_mcPiP", "", {HistType::kTHnSparseF, {asCentrality, asPt, asEta, {200, -10., 10., "TPC #it{n}#it{#sigma}_{#pi}"}}}); - hrQaPid.add("QaPid/hCentralityPtEtaTpcNSigmaPi_mcPiM", "", {HistType::kTHnSparseF, {asCentrality, asPt, asEta, {200, -10., 10., "TPC #it{n}#it{#sigma}_{#pi}"}}}); - hrQaPid.add("QaPid/hCentralityPtEtaTofNSigmaPi_mcPiP", "", {HistType::kTHnSparseF, {asCentrality, asPt, asEta, {200, -10., 10., "TOF #it{n}#it{#sigma}_{#pi}"}}}); - hrQaPid.add("QaPid/hCentralityPtEtaTofNSigmaPi_mcPiM", "", {HistType::kTHnSparseF, {asCentrality, asPt, asEta, {200, -10., 10., "TOF #it{n}#it{#sigma}_{#pi}"}}}); + hrQaPid.add("QaPid/hCentralityPtEtaTpcNSigmaPi_mcPiP", ";;;;TPC #it{n}#it{#sigma}_{#pi};", hcsQaPid); + hrQaPid.add("QaPid/hCentralityPtEtaTpcNSigmaPi_mcPiM", ";;;;TPC #it{n}#it{#sigma}_{#pi};", hcsQaPid); + hrQaPid.add("QaPid/hCentralityPtEtaTofNSigmaPi_mcPiP", ";;;;TOF #it{n}#it{#sigma}_{#pi};", hcsQaPid); + hrQaPid.add("QaPid/hCentralityPtEtaTofNSigmaPi_mcPiM", ";;;;TOF #it{n}#it{#sigma}_{#pi};", hcsQaPid); } else if (doprocessRaw.value) { - hrQaPid.add("QaPid/hCentralityPtEtaTpcNSigmaPi_p", "", {HistType::kTHnSparseF, {asCentrality, asPt, asEta, {200, -10., 10., "TPC #it{n}#it{#sigma}_{#pi}"}}}); - hrQaPid.add("QaPid/hCentralityPtEtaTpcNSigmaPi_m", "", {HistType::kTHnSparseF, {asCentrality, asPt, asEta, {200, -10., 10., "TPC #it{n}#it{#sigma}_{#pi}"}}}); - hrQaPid.add("QaPid/hCentralityPtEtaTpcNSigmaPi_tofPiP", "", {HistType::kTHnSparseF, {asCentrality, asPt, asEta, {200, -10., 10., "TPC #it{n}#it{#sigma}_{#pi}"}}}); - hrQaPid.add("QaPid/hCentralityPtEtaTpcNSigmaPi_tofPiM", "", {HistType::kTHnSparseF, {asCentrality, asPt, asEta, {200, -10., 10., "TPC #it{n}#it{#sigma}_{#pi}"}}}); - hrQaPid.add("QaPid/hCentralityPtEtaTofNSigmaPi_tpcPiP", "", {HistType::kTHnSparseF, {asCentrality, asPt, asEta, {200, -10., 10., "TOF #it{n}#it{#sigma}_{#pi}"}}}); - hrQaPid.add("QaPid/hCentralityPtEtaTofNSigmaPi_tpcPiM", "", {HistType::kTHnSparseF, {asCentrality, asPt, asEta, {200, -10., 10., "TOF #it{n}#it{#sigma}_{#pi}"}}}); - hrQaPid.add("QaPid/hCentralityPtEtaTpcTofNSigmaPi_p", "", {HistType::kTHnSparseF, {asCentrality, asPt, asEta, {200, -10., 10., "TPC-TOF #it{n}#it{#sigma}_{#pi}"}}}); - hrQaPid.add("QaPid/hCentralityPtEtaTpcTofNSigmaPi_m", "", {HistType::kTHnSparseF, {asCentrality, asPt, asEta, {200, -10., 10., "TPC-TOF #it{n}#it{#sigma}_{#pi}"}}}); + hrQaPid.add("QaPid/hCentralityPtEtaTpcNSigmaPi_p", ";;;;TPC #it{n}#it{#sigma}_{#pi};", hcsQaPid); + hrQaPid.add("QaPid/hCentralityPtEtaTpcNSigmaPi_m", ";;;;TPC #it{n}#it{#sigma}_{#pi};", hcsQaPid); + hrQaPid.add("QaPid/hCentralityPtEtaTpcNSigmaPi_tofPiP", ";;;;TPC #it{n}#it{#sigma}_{#pi};", hcsQaPid); + hrQaPid.add("QaPid/hCentralityPtEtaTpcNSigmaPi_tofPiM", ";;;;TPC #it{n}#it{#sigma}_{#pi};", hcsQaPid); + hrQaPid.add("QaPid/hCentralityPtEtaTofNSigmaPi_tpcPiP", ";;;;TOF #it{n}#it{#sigma}_{#pi};", hcsQaPid); + hrQaPid.add("QaPid/hCentralityPtEtaTofNSigmaPi_tpcPiM", ";;;;TOF #it{n}#it{#sigma}_{#pi};", hcsQaPid); + hrQaPid.add("QaPid/hCentralityPtEtaTpcTofNSigmaPi_p", ";;;;TPC-TOF #it{n}#it{#sigma}_{#pi};", hcsQaPid); + hrQaPid.add("QaPid/hCentralityPtEtaTpcTofNSigmaPi_m", ";;;;TPC-TOF #it{n}#it{#sigma}_{#pi};", hcsQaPid); } } @@ -1390,19 +1396,19 @@ struct PartNumFluc { LOG(info) << "Enabling kaon PID QA."; if (doprocessMc.value) { - hrQaPid.add("QaPid/hCentralityPtEtaTpcNSigmaKa_mcKaP", "", {HistType::kTHnSparseF, {asCentrality, asPt, asEta, {200, -10., 10., "TPC #it{n}#it{#sigma}_{K}"}}}); - hrQaPid.add("QaPid/hCentralityPtEtaTpcNSigmaKa_mcKaM", "", {HistType::kTHnSparseF, {asCentrality, asPt, asEta, {200, -10., 10., "TPC #it{n}#it{#sigma}_{K}"}}}); - hrQaPid.add("QaPid/hCentralityPtEtaTofNSigmaKa_mcKaP", "", {HistType::kTHnSparseF, {asCentrality, asPt, asEta, {200, -10., 10., "TOF #it{n}#it{#sigma}_{K}"}}}); - hrQaPid.add("QaPid/hCentralityPtEtaTofNSigmaKa_mcKaM", "", {HistType::kTHnSparseF, {asCentrality, asPt, asEta, {200, -10., 10., "TOF #it{n}#it{#sigma}_{K}"}}}); + hrQaPid.add("QaPid/hCentralityPtEtaTpcNSigmaKa_mcKaP", ";;;;TPC #it{n}#it{#sigma}_{K};", hcsQaPid); + hrQaPid.add("QaPid/hCentralityPtEtaTpcNSigmaKa_mcKaM", ";;;;TPC #it{n}#it{#sigma}_{K};", hcsQaPid); + hrQaPid.add("QaPid/hCentralityPtEtaTofNSigmaKa_mcKaP", ";;;;TOF #it{n}#it{#sigma}_{K};", hcsQaPid); + hrQaPid.add("QaPid/hCentralityPtEtaTofNSigmaKa_mcKaM", ";;;;TOF #it{n}#it{#sigma}_{K};", hcsQaPid); } else if (doprocessRaw.value) { - hrQaPid.add("QaPid/hCentralityPtEtaTpcNSigmaKa_p", "", {HistType::kTHnSparseF, {asCentrality, asPt, asEta, {200, -10., 10., "TPC #it{n}#it{#sigma}_{K}"}}}); - hrQaPid.add("QaPid/hCentralityPtEtaTpcNSigmaKa_m", "", {HistType::kTHnSparseF, {asCentrality, asPt, asEta, {200, -10., 10., "TPC #it{n}#it{#sigma}_{K}"}}}); - hrQaPid.add("QaPid/hCentralityPtEtaTpcNSigmaKa_tofKaP", "", {HistType::kTHnSparseF, {asCentrality, asPt, asEta, {200, -10., 10., "TPC #it{n}#it{#sigma}_{K}"}}}); - hrQaPid.add("QaPid/hCentralityPtEtaTpcNSigmaKa_tofKaM", "", {HistType::kTHnSparseF, {asCentrality, asPt, asEta, {200, -10., 10., "TPC #it{n}#it{#sigma}_{K}"}}}); - hrQaPid.add("QaPid/hCentralityPtEtaTofNSigmaKa_tpcKaP", "", {HistType::kTHnSparseF, {asCentrality, asPt, asEta, {200, -10., 10., "TOF #it{n}#it{#sigma}_{K}"}}}); - hrQaPid.add("QaPid/hCentralityPtEtaTofNSigmaKa_tpcKaM", "", {HistType::kTHnSparseF, {asCentrality, asPt, asEta, {200, -10., 10., "TOF #it{n}#it{#sigma}_{K}"}}}); - hrQaPid.add("QaPid/hCentralityPtEtaTpcTofNSigmaKa_p", "", {HistType::kTHnSparseF, {asCentrality, asPt, asEta, {200, -10., 10., "TPC-TOF #it{n}#it{#sigma}_{K}"}}}); - hrQaPid.add("QaPid/hCentralityPtEtaTpcTofNSigmaKa_m", "", {HistType::kTHnSparseF, {asCentrality, asPt, asEta, {200, -10., 10., "TPC-TOF #it{n}#it{#sigma}_{K}"}}}); + hrQaPid.add("QaPid/hCentralityPtEtaTpcNSigmaKa_p", ";;;;TPC #it{n}#it{#sigma}_{K};", hcsQaPid); + hrQaPid.add("QaPid/hCentralityPtEtaTpcNSigmaKa_m", ";;;;TPC #it{n}#it{#sigma}_{K};", hcsQaPid); + hrQaPid.add("QaPid/hCentralityPtEtaTpcNSigmaKa_tofKaP", ";;;;TPC #it{n}#it{#sigma}_{K};", hcsQaPid); + hrQaPid.add("QaPid/hCentralityPtEtaTpcNSigmaKa_tofKaM", ";;;;TPC #it{n}#it{#sigma}_{K};", hcsQaPid); + hrQaPid.add("QaPid/hCentralityPtEtaTofNSigmaKa_tpcKaP", ";;;;TOF #it{n}#it{#sigma}_{K};", hcsQaPid); + hrQaPid.add("QaPid/hCentralityPtEtaTofNSigmaKa_tpcKaM", ";;;;TOF #it{n}#it{#sigma}_{K};", hcsQaPid); + hrQaPid.add("QaPid/hCentralityPtEtaTpcTofNSigmaKa_p", ";;;;TPC-TOF #it{n}#it{#sigma}_{K};", hcsQaPid); + hrQaPid.add("QaPid/hCentralityPtEtaTpcTofNSigmaKa_m", ";;;;TPC-TOF #it{n}#it{#sigma}_{K};", hcsQaPid); } } @@ -1410,19 +1416,19 @@ struct PartNumFluc { LOG(info) << "Enabling (anti)proton PID QA."; if (doprocessMc.value) { - hrQaPid.add("QaPid/hCentralityPtEtaTpcNSigmaPr_mcPrP", "", {HistType::kTHnSparseF, {asCentrality, asPt, asEta, {200, -10., 10., "TPC #it{n}#it{#sigma}_{p}"}}}); - hrQaPid.add("QaPid/hCentralityPtEtaTpcNSigmaPr_mcPrM", "", {HistType::kTHnSparseF, {asCentrality, asPt, asEta, {200, -10., 10., "TPC #it{n}#it{#sigma}_{p}"}}}); - hrQaPid.add("QaPid/hCentralityPtEtaTofNSigmaPr_mcPrP", "", {HistType::kTHnSparseF, {asCentrality, asPt, asEta, {200, -10., 10., "TOF #it{n}#it{#sigma}_{p}"}}}); - hrQaPid.add("QaPid/hCentralityPtEtaTofNSigmaPr_mcPrM", "", {HistType::kTHnSparseF, {asCentrality, asPt, asEta, {200, -10., 10., "TOF #it{n}#it{#sigma}_{p}"}}}); + hrQaPid.add("QaPid/hCentralityPtEtaTpcNSigmaPr_mcPrP", ";;;;TPC #it{n}#it{#sigma}_{p};", hcsQaPid); + hrQaPid.add("QaPid/hCentralityPtEtaTpcNSigmaPr_mcPrM", ";;;;TPC #it{n}#it{#sigma}_{p};", hcsQaPid); + hrQaPid.add("QaPid/hCentralityPtEtaTofNSigmaPr_mcPrP", ";;;;TOF #it{n}#it{#sigma}_{p};", hcsQaPid); + hrQaPid.add("QaPid/hCentralityPtEtaTofNSigmaPr_mcPrM", ";;;;TOF #it{n}#it{#sigma}_{p};", hcsQaPid); } else if (doprocessRaw.value) { - hrQaPid.add("QaPid/hCentralityPtEtaTpcNSigmaPr_p", "", {HistType::kTHnSparseF, {asCentrality, asPt, asEta, {200, -10., 10., "TPC #it{n}#it{#sigma}_{p}"}}}); - hrQaPid.add("QaPid/hCentralityPtEtaTpcNSigmaPr_m", "", {HistType::kTHnSparseF, {asCentrality, asPt, asEta, {200, -10., 10., "TPC #it{n}#it{#sigma}_{p}"}}}); - hrQaPid.add("QaPid/hCentralityPtEtaTpcNSigmaPr_tofPrP", "", {HistType::kTHnSparseF, {asCentrality, asPt, asEta, {200, -10., 10., "TPC #it{n}#it{#sigma}_{p}"}}}); - hrQaPid.add("QaPid/hCentralityPtEtaTpcNSigmaPr_tofPrM", "", {HistType::kTHnSparseF, {asCentrality, asPt, asEta, {200, -10., 10., "TPC #it{n}#it{#sigma}_{p}"}}}); - hrQaPid.add("QaPid/hCentralityPtEtaTofNSigmaPr_tpcPrP", "", {HistType::kTHnSparseF, {asCentrality, asPt, asEta, {200, -10., 10., "TOF #it{n}#it{#sigma}_{p}"}}}); - hrQaPid.add("QaPid/hCentralityPtEtaTofNSigmaPr_tpcPrM", "", {HistType::kTHnSparseF, {asCentrality, asPt, asEta, {200, -10., 10., "TOF #it{n}#it{#sigma}_{p}"}}}); - hrQaPid.add("QaPid/hCentralityPtEtaTpcTofNSigmaPr_p", "", {HistType::kTHnSparseF, {asCentrality, asPt, asEta, {200, -10., 10., "TPC-TOF #it{n}#it{#sigma}_{p}"}}}); - hrQaPid.add("QaPid/hCentralityPtEtaTpcTofNSigmaPr_m", "", {HistType::kTHnSparseF, {asCentrality, asPt, asEta, {200, -10., 10., "TPC-TOF #it{n}#it{#sigma}_{p}"}}}); + hrQaPid.add("QaPid/hCentralityPtEtaTpcNSigmaPr_p", ";;;;TPC #it{n}#it{#sigma}_{p};", hcsQaPid); + hrQaPid.add("QaPid/hCentralityPtEtaTpcNSigmaPr_m", ";;;;TPC #it{n}#it{#sigma}_{p};", hcsQaPid); + hrQaPid.add("QaPid/hCentralityPtEtaTpcNSigmaPr_tofPrP", ";;;;TPC #it{n}#it{#sigma}_{p};", hcsQaPid); + hrQaPid.add("QaPid/hCentralityPtEtaTpcNSigmaPr_tofPrM", ";;;;TPC #it{n}#it{#sigma}_{p};", hcsQaPid); + hrQaPid.add("QaPid/hCentralityPtEtaTofNSigmaPr_tpcPrP", ";;;;TOF #it{n}#it{#sigma}_{p};", hcsQaPid); + hrQaPid.add("QaPid/hCentralityPtEtaTofNSigmaPr_tpcPrM", ";;;;TOF #it{n}#it{#sigma}_{p};", hcsQaPid); + hrQaPid.add("QaPid/hCentralityPtEtaTpcTofNSigmaPr_p", ";;;;TPC-TOF #it{n}#it{#sigma}_{p};", hcsQaPid); + hrQaPid.add("QaPid/hCentralityPtEtaTpcTofNSigmaPr_m", ";;;;TPC-TOF #it{n}#it{#sigma}_{p};", hcsQaPid); } } } @@ -1583,6 +1589,60 @@ struct PartNumFluc { const HistogramConfigSpec hcsCalculationFluctuation(HistType::kTHnSparseD, {asCentrality, {50, -0.5, 49.5}, {50, -0.5, 49.5}}); const HistogramConfigSpec hcsFluctuationCalculator(HistType::kTH3D, {asCentrality, {groupEvent.cfgNSubgroups.value, -0.5, groupEvent.cfgNSubgroups.value - 0.5, "Subgroup Index"}, {fluctuation_calculator_base::NOrderVectors, -0.5, fluctuation_calculator_base::NOrderVectors - 0.5, "Order Vector Index"}}); + if (groupAnalysis.cfgFlagCalculationFluctuationCh.value) { + LOG(info) << "Enabling charge number fluctuation calculation."; + + fluctuationCalculatorTrackChP = std::make_unique(); + fluctuationCalculatorTrackChM = std::make_unique(); + fluctuationCalculatorTrackChT = std::make_unique(); + fluctuationCalculatorTrackChN = std::make_unique(); + + if (doprocessMc.value) { + hrCalculationFluctuation.add("CalculationFluctuation/hCentralityNChPNChM_mc", ";;#it{N}(h^{+});#it{N}(h^{#minus});", hcsCalculationFluctuation); + } + hrCalculationFluctuation.add("CalculationFluctuation/hCentralityNChPNChM", ";;#it{N}(h^{+});#it{N}(h^{#minus});", hcsCalculationFluctuation); + hrCalculationFluctuation.add("CalculationFluctuation/hFluctuationCalculatorChP", "", hcsFluctuationCalculator); + hrCalculationFluctuation.add("CalculationFluctuation/hFluctuationCalculatorChM", "", hcsFluctuationCalculator); + hrCalculationFluctuation.add("CalculationFluctuation/hFluctuationCalculatorChT", "", hcsFluctuationCalculator); + hrCalculationFluctuation.add("CalculationFluctuation/hFluctuationCalculatorChN", "", hcsFluctuationCalculator); + } + + if (groupAnalysis.cfgFlagCalculationFluctuationKa.value) { + LOG(info) << "Enabling kaon number fluctuation calculation."; + + fluctuationCalculatorTrackKaP = std::make_unique(); + fluctuationCalculatorTrackKaM = std::make_unique(); + fluctuationCalculatorTrackKaT = std::make_unique(); + fluctuationCalculatorTrackKaN = std::make_unique(); + + if (doprocessMc.value) { + hrCalculationFluctuation.add("CalculationFluctuation/hCentralityNKaPNKaM_mc", ";;#it{N}(K^{+});#it{N}(K^{#minus});", hcsCalculationFluctuation); + } + hrCalculationFluctuation.add("CalculationFluctuation/hCentralityNKaPNKaM", ";;#it{N}(K^{+});#it{N}(K^{#minus});", hcsCalculationFluctuation); + hrCalculationFluctuation.add("CalculationFluctuation/hFluctuationCalculatorKaP", "", hcsFluctuationCalculator); + hrCalculationFluctuation.add("CalculationFluctuation/hFluctuationCalculatorKaM", "", hcsFluctuationCalculator); + hrCalculationFluctuation.add("CalculationFluctuation/hFluctuationCalculatorKaT", "", hcsFluctuationCalculator); + hrCalculationFluctuation.add("CalculationFluctuation/hFluctuationCalculatorKaN", "", hcsFluctuationCalculator); + } + + if (groupAnalysis.cfgFlagCalculationFluctuationPr.value) { + LOG(info) << "Enabling (anti)proton number fluctuation calculation."; + + fluctuationCalculatorTrackPrP = std::make_unique(); + fluctuationCalculatorTrackPrM = std::make_unique(); + fluctuationCalculatorTrackPrT = std::make_unique(); + fluctuationCalculatorTrackPrN = std::make_unique(); + + if (doprocessMc.value) { + hrCalculationFluctuation.add("CalculationFluctuation/hCentralityNPrPNPrM_mc", ";;#it{N}(p);#it{N}(#bar{p});", hcsCalculationFluctuation); + } + hrCalculationFluctuation.add("CalculationFluctuation/hCentralityNPrPNPrM", ";;#it{N}(p);#it{N}(#bar{p});", hcsCalculationFluctuation); + hrCalculationFluctuation.add("CalculationFluctuation/hFluctuationCalculatorPrP", "", hcsFluctuationCalculator); + hrCalculationFluctuation.add("CalculationFluctuation/hFluctuationCalculatorPrM", "", hcsFluctuationCalculator); + hrCalculationFluctuation.add("CalculationFluctuation/hFluctuationCalculatorPrT", "", hcsFluctuationCalculator); + hrCalculationFluctuation.add("CalculationFluctuation/hFluctuationCalculatorPrN", "", hcsFluctuationCalculator); + } + if (groupAnalysis.cfgFlagCalculationFluctuationCh.value) { holderCcdb.hVzCentralityPtEtaEfficiencyTpcPiP.resize(nRunGroups); holderCcdb.hVzCentralityPtEtaEfficiencyTpcPiM.resize(nRunGroups); @@ -1681,60 +1741,6 @@ struct PartNumFluc { LOG(info) << "Reading from CCDB: " << holderCcdb.hVzCentralityPtEtaEfficiencyTpcTofPrM[iRunGroup]->GetName(); } } - - if (groupAnalysis.cfgFlagCalculationFluctuationCh.value) { - LOG(info) << "Enabling charge number fluctuation calculation."; - - fluctuationCalculatorTrackChP = std::make_unique(); - fluctuationCalculatorTrackChM = std::make_unique(); - fluctuationCalculatorTrackChT = std::make_unique(); - fluctuationCalculatorTrackChN = std::make_unique(); - - if (doprocessMc.value) { - hrCalculationFluctuation.add("CalculationFluctuation/hCentralityNChPNChM_mc", ";;#it{N}(h^{+});#it{N}(h^{#minus})", hcsCalculationFluctuation); - } - hrCalculationFluctuation.add("CalculationFluctuation/hCentralityNChPNChM", ";;#it{N}(h^{+});#it{N}(h^{#minus})", hcsCalculationFluctuation); - hrCalculationFluctuation.add("CalculationFluctuation/hFluctuationCalculatorChP", "", hcsFluctuationCalculator); - hrCalculationFluctuation.add("CalculationFluctuation/hFluctuationCalculatorChM", "", hcsFluctuationCalculator); - hrCalculationFluctuation.add("CalculationFluctuation/hFluctuationCalculatorChT", "", hcsFluctuationCalculator); - hrCalculationFluctuation.add("CalculationFluctuation/hFluctuationCalculatorChN", "", hcsFluctuationCalculator); - } - - if (groupAnalysis.cfgFlagCalculationFluctuationKa.value) { - LOG(info) << "Enabling kaon number fluctuation calculation."; - - fluctuationCalculatorTrackKaP = std::make_unique(); - fluctuationCalculatorTrackKaM = std::make_unique(); - fluctuationCalculatorTrackKaT = std::make_unique(); - fluctuationCalculatorTrackKaN = std::make_unique(); - - if (doprocessMc.value) { - hrCalculationFluctuation.add("CalculationFluctuation/hCentralityNKaPNKaM_mc", ";;#it{N}(K^{+});#it{N}(K^{#minus})", hcsCalculationFluctuation); - } - hrCalculationFluctuation.add("CalculationFluctuation/hCentralityNKaPNKaM", ";;#it{N}(K^{+});#it{N}(K^{#minus})", hcsCalculationFluctuation); - hrCalculationFluctuation.add("CalculationFluctuation/hFluctuationCalculatorKaP", "", hcsFluctuationCalculator); - hrCalculationFluctuation.add("CalculationFluctuation/hFluctuationCalculatorKaM", "", hcsFluctuationCalculator); - hrCalculationFluctuation.add("CalculationFluctuation/hFluctuationCalculatorKaT", "", hcsFluctuationCalculator); - hrCalculationFluctuation.add("CalculationFluctuation/hFluctuationCalculatorKaN", "", hcsFluctuationCalculator); - } - - if (groupAnalysis.cfgFlagCalculationFluctuationPr.value) { - LOG(info) << "Enabling (anti)proton number fluctuation calculation."; - - fluctuationCalculatorTrackPrP = std::make_unique(); - fluctuationCalculatorTrackPrM = std::make_unique(); - fluctuationCalculatorTrackPrT = std::make_unique(); - fluctuationCalculatorTrackPrN = std::make_unique(); - - if (doprocessMc.value) { - hrCalculationFluctuation.add("CalculationFluctuation/hCentralityNPrPNPrM_mc", ";;#it{N}(p);#it{N}(#bar{p})", hcsCalculationFluctuation); - } - hrCalculationFluctuation.add("CalculationFluctuation/hCentralityNPrPNPrM", ";;#it{N}(p);#it{N}(#bar{p})", hcsCalculationFluctuation); - hrCalculationFluctuation.add("CalculationFluctuation/hFluctuationCalculatorPrP", "", hcsFluctuationCalculator); - hrCalculationFluctuation.add("CalculationFluctuation/hFluctuationCalculatorPrM", "", hcsFluctuationCalculator); - hrCalculationFluctuation.add("CalculationFluctuation/hFluctuationCalculatorPrT", "", hcsFluctuationCalculator); - hrCalculationFluctuation.add("CalculationFluctuation/hFluctuationCalculatorPrN", "", hcsFluctuationCalculator); - } } } @@ -1784,16 +1790,16 @@ struct PartNumFluc { } static const std::array*, 2>, 2>, static_cast(ParticleSpecies::kNSpecies)> pointersVectorHistogramShiftNSigmaPid = {{{{{&holderCcdb.hCentralityPtEtaShiftTpcNSigmaPiP, &holderCcdb.hCentralityPtEtaShiftTofNSigmaPiP}, {&holderCcdb.hCentralityPtEtaShiftTpcNSigmaPiM, &holderCcdb.hCentralityPtEtaShiftTofNSigmaPiM}}}, {{{&holderCcdb.hCentralityPtEtaShiftTpcNSigmaKaP, &holderCcdb.hCentralityPtEtaShiftTofNSigmaKaP}, {&holderCcdb.hCentralityPtEtaShiftTpcNSigmaKaM, &holderCcdb.hCentralityPtEtaShiftTofNSigmaKaM}}}, {{{&holderCcdb.hCentralityPtEtaShiftTpcNSigmaPrP, &holderCcdb.hCentralityPtEtaShiftTofNSigmaPrP}, {&holderCcdb.hCentralityPtEtaShiftTpcNSigmaPrM, &holderCcdb.hCentralityPtEtaShiftTofNSigmaPrM}}}}}; + static const auto clampInAxis = [](const double value, const TAxis* const axis) { + const std::int32_t first = std::clamp(axis->GetFirst(), 1, axis->GetNbins()); + const std::int32_t last = std::clamp(axis->GetLast(), 1, axis->GetNbins()); + return first == last ? axis->GetBinCenter(first) : std::clamp(value, std::nextafter(axis->GetBinCenter(first), std::numeric_limits::infinity()), std::nextafter(axis->GetBinCenter(last), -std::numeric_limits::infinity())); + }; if (holderTrack.sign == 0) { return 0.; } const TH3* const hCentralityPtEtaShiftNSigmaPid = pointersVectorHistogramShiftNSigmaPid[static_cast(particleSpecies)][holderTrack.sign > 0 ? 0 : 1][pidStrategy == PidStrategy::kTpc ? 0 : 1]->at(std::abs(holderEvent.runGroupIndex) - 1); - auto clampInAxis = [](const double value, const TAxis* const axis) { - const std::int32_t first = std::clamp(axis->GetFirst(), 1, axis->GetNbins()); - const std::int32_t last = std::clamp(axis->GetLast(), 1, axis->GetNbins()); - return first == last ? axis->GetBinCenter(first) : std::clamp(value, std::nextafter(axis->GetBinCenter(first), std::numeric_limits::infinity()), std::nextafter(axis->GetBinCenter(last), -std::numeric_limits::infinity())); - }; return hCentralityPtEtaShiftNSigmaPid ? hCentralityPtEtaShiftNSigmaPid->Interpolate(clampInAxis(holderEvent.centrality, hCentralityPtEtaShiftNSigmaPid->GetXaxis()), clampInAxis(holderTrack.pt, hCentralityPtEtaShiftNSigmaPid->GetYaxis()), clampInAxis(holderTrack.eta, hCentralityPtEtaShiftNSigmaPid->GetZaxis())) : 0.; } diff --git a/PWGCF/EbyEFluctuations/Tasks/radialFlowDecorr.cxx b/PWGCF/EbyEFluctuations/Tasks/radialFlowDecorr.cxx index b052893881e..1ac8206b00b 100644 --- a/PWGCF/EbyEFluctuations/Tasks/radialFlowDecorr.cxx +++ b/PWGCF/EbyEFluctuations/Tasks/radialFlowDecorr.cxx @@ -13,55 +13,49 @@ /// \brief Analysis task for event-by-event radial-flow decorrelation measurement. /// \author Somadutta Bhatta -#include "Common/Core/TrackSelection.h" -#include "Common/Core/trackUtilities.h" +#include "Common/CCDB/EventSelectionParams.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/FT0Corrected.h" #include "Common/DataModel/Multiplicity.h" -#include "Common/DataModel/PIDResponseITS.h" #include "Common/DataModel/PIDResponseTOF.h" #include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "CCDB/BasicCCDBManager.h" -#include "CommonConstants/MathConstants.h" -#include "DataFormatsParameters/GRPObject.h" -#include "DetectorsCommonDataFormats/AlignParam.h" -#include "FT0Base/Geometry.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/Configurable.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/Logger.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "Framework/runDataProcessing.h" -#include "MathUtils/Utils.h" -#include "ReconstructionDataFormats/DCA.h" -#include "ReconstructionDataFormats/PID.h" -#include "ReconstructionDataFormats/Track.h" -#include "ReconstructionDataFormats/TrackTPCITS.h" - -#include "TDirectory.h" -#include "TFile.h" -#include "TH1F.h" -#include "TH2F.h" -#include "TH3F.h" -#include "THnSparse.h" -#include "TMath.h" -#include "TProfile.h" -#include "TProfile2D.h" -#include "TProfile3D.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include +#include #include +#include #include -#include -#include #include -#include #include #include #include diff --git a/PWGCF/EbyEFluctuations/Tasks/v0ptHadPiKaProt.cxx b/PWGCF/EbyEFluctuations/Tasks/v0ptHadPiKaProt.cxx index f79cb80298b..cffbe84540c 100644 --- a/PWGCF/EbyEFluctuations/Tasks/v0ptHadPiKaProt.cxx +++ b/PWGCF/EbyEFluctuations/Tasks/v0ptHadPiKaProt.cxx @@ -13,8 +13,7 @@ /// \brief Task for analyzing v0(pT) of inclusive hadrons, pions, kaons, and, protons /// \author Swati Saha -#include "Common/Core/TrackSelection.h" -#include "Common/Core/trackUtilities.h" +#include "Common/CCDB/EventSelectionParams.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" @@ -23,43 +22,37 @@ #include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "CommonConstants/MathConstants.h" -#include "CommonConstants/PhysicsConstants.h" -#include "DataFormatsParameters/GRPMagField.h" -#include "DataFormatsParameters/GRPObject.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/StepTHn.h" -#include "Framework/runDataProcessing.h" -#include "ReconstructionDataFormats/PID.h" -#include "ReconstructionDataFormats/Track.h" #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include -#include #include -#include -#include -#include -#include -#include -#include +#include #include #include #include -#include -#include #include #include #include +#include #include +#include #include +#include #include +#include #include #include diff --git a/PWGCF/Femto/Core/baseSelection.h b/PWGCF/Femto/Core/baseSelection.h index fcce0c11c13..5bc9a598c1f 100644 --- a/PWGCF/Femto/Core/baseSelection.h +++ b/PWGCF/Femto/Core/baseSelection.h @@ -18,9 +18,11 @@ #include "PWGCF/Femto/Core/selectionContainer.h" -#include "Framework/HistogramRegistry.h" +#include +#include +#include -#include "fairlogger/Logger.h" +#include #include #include diff --git a/PWGCF/Femto/Core/cascadeBuilder.h b/PWGCF/Femto/Core/cascadeBuilder.h index f787543f945..2de7099ee6f 100644 --- a/PWGCF/Femto/Core/cascadeBuilder.h +++ b/PWGCF/Femto/Core/cascadeBuilder.h @@ -23,11 +23,11 @@ #include "PWGCF/Femto/Core/selectionContainer.h" #include "PWGCF/Femto/DataModel/FemtoTables.h" -#include "CommonConstants/MathConstants.h" -#include "Framework/AnalysisHelpers.h" -#include "Framework/Configurable.h" - -#include "fairlogger/Logger.h" +#include +#include +#include +#include +#include #include #include diff --git a/PWGCF/Femto/Core/cascadeHistManager.h b/PWGCF/Femto/Core/cascadeHistManager.h index 3944dcd761a..d1218ec4e8e 100644 --- a/PWGCF/Femto/Core/cascadeHistManager.h +++ b/PWGCF/Femto/Core/cascadeHistManager.h @@ -20,12 +20,17 @@ #include "PWGCF/Femto/Core/modes.h" #include "PWGCF/Femto/Core/trackHistManager.h" -#include "CommonConstants/MathConstants.h" -#include "Framework/Configurable.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/HistogramSpec.h" +#include +#include +#include +#include +#include + +#include +#include #include +#include #include #include #include diff --git a/PWGCF/Femto/Core/closePairRejection.h b/PWGCF/Femto/Core/closePairRejection.h index 63a707f9ad8..41c40e97a54 100644 --- a/PWGCF/Femto/Core/closePairRejection.h +++ b/PWGCF/Femto/Core/closePairRejection.h @@ -16,20 +16,24 @@ #ifndef PWGCF_FEMTO_CORE_CLOSEPAIRREJECTION_H_ #define PWGCF_FEMTO_CORE_CLOSEPAIRREJECTION_H_ -#include "RecoDecay.h" - #include "PWGCF/Femto/Core/histManager.h" -#include "Framework/Configurable.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/HistogramSpec.h" +#include "Common/Core/RecoDecay.h" + +#include +#include +#include +#include +#include #include #include #include #include +#include #include #include +#include #include #include #include diff --git a/PWGCF/Femto/Core/closeTripletRejection.h b/PWGCF/Femto/Core/closeTripletRejection.h index 5bb006e04ab..dd1bd0182c0 100644 --- a/PWGCF/Femto/Core/closeTripletRejection.h +++ b/PWGCF/Femto/Core/closeTripletRejection.h @@ -18,8 +18,8 @@ #include "PWGCF/Femto/Core/closePairRejection.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/HistogramSpec.h" +#include +#include #include #include diff --git a/PWGCF/Femto/Core/collisionBuilder.h b/PWGCF/Femto/Core/collisionBuilder.h index 2d0aa6b532d..5d750cb2a92 100644 --- a/PWGCF/Femto/Core/collisionBuilder.h +++ b/PWGCF/Femto/Core/collisionBuilder.h @@ -27,11 +27,11 @@ #include "Common/CCDB/RCTSelectionFlags.h" #include "Common/Core/Zorro.h" -#include "DataFormatsParameters/GRPMagField.h" -#include "Framework/AnalysisHelpers.h" -#include "Framework/Configurable.h" - -#include "fairlogger/Logger.h" +#include +#include +#include +#include +#include #include #include diff --git a/PWGCF/Femto/Core/collisionHistManager.h b/PWGCF/Femto/Core/collisionHistManager.h index 5233c4799e0..a4bbda81b6f 100644 --- a/PWGCF/Femto/Core/collisionHistManager.h +++ b/PWGCF/Femto/Core/collisionHistManager.h @@ -19,11 +19,13 @@ #include "PWGCF/Femto/Core/histManager.h" #include "PWGCF/Femto/Core/modes.h" -#include "Framework/Configurable.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/HistogramSpec.h" +#include +#include +#include #include +#include +#include #include #include #include diff --git a/PWGCF/Femto/Core/femtoUtils.h b/PWGCF/Femto/Core/femtoUtils.h index 26e7649776d..4baf9ba182f 100644 --- a/PWGCF/Femto/Core/femtoUtils.h +++ b/PWGCF/Femto/Core/femtoUtils.h @@ -18,17 +18,14 @@ #include "Common/Core/TableHelper.h" -#include "CommonConstants/MathConstants.h" -#include "CommonConstants/PhysicsConstants.h" -#include "Framework/InitContext.h" +#include +#include +#include -#include "TPDGCode.h" - -#include "fairlogger/Logger.h" +#include #include #include -#include #include #include #include diff --git a/PWGCF/Femto/Core/histManager.h b/PWGCF/Femto/Core/histManager.h index 19b1b0ce502..ceadf18f38a 100644 --- a/PWGCF/Femto/Core/histManager.h +++ b/PWGCF/Femto/Core/histManager.h @@ -16,7 +16,7 @@ #ifndef PWGCF_FEMTO_CORE_HISTMANAGER_H_ #define PWGCF_FEMTO_CORE_HISTMANAGER_H_ -#include "Framework/HistogramSpec.h" +#include #include #include diff --git a/PWGCF/Femto/Core/kinkBuilder.h b/PWGCF/Femto/Core/kinkBuilder.h index acf74690337..214260ee245 100644 --- a/PWGCF/Femto/Core/kinkBuilder.h +++ b/PWGCF/Femto/Core/kinkBuilder.h @@ -26,11 +26,11 @@ #include "Common/Core/RecoDecay.h" -#include "CommonConstants/MathConstants.h" -#include "Framework/AnalysisHelpers.h" -#include "Framework/Configurable.h" - -#include "fairlogger/Logger.h" +#include +#include +#include +#include +#include #include #include diff --git a/PWGCF/Femto/Core/kinkHistManager.h b/PWGCF/Femto/Core/kinkHistManager.h index f6c672c3200..b3f27e3f4e0 100644 --- a/PWGCF/Femto/Core/kinkHistManager.h +++ b/PWGCF/Femto/Core/kinkHistManager.h @@ -21,12 +21,17 @@ #include "PWGCF/Femto/Core/modes.h" #include "PWGCF/Femto/Core/trackHistManager.h" -#include "CommonConstants/MathConstants.h" -#include "Framework/Configurable.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/HistogramSpec.h" +#include +#include +#include +#include +#include + +#include +#include #include +#include #include #include #include diff --git a/PWGCF/Femto/Core/mcBuilder.h b/PWGCF/Femto/Core/mcBuilder.h index 038ad432df8..30f6210c027 100644 --- a/PWGCF/Femto/Core/mcBuilder.h +++ b/PWGCF/Femto/Core/mcBuilder.h @@ -21,10 +21,11 @@ #include "PWGCF/Femto/Core/modes.h" #include "PWGCF/Femto/DataModel/FemtoTables.h" -#include "Framework/AnalysisHelpers.h" -#include "Framework/Configurable.h" +#include +#include +#include -#include "fairlogger/Logger.h" +#include #include #include diff --git a/PWGCF/Femto/Core/pairBuilder.h b/PWGCF/Femto/Core/pairBuilder.h index 34c360f4943..0a44ba639fc 100644 --- a/PWGCF/Femto/Core/pairBuilder.h +++ b/PWGCF/Femto/Core/pairBuilder.h @@ -30,10 +30,9 @@ #include "PWGCF/Femto/Core/v0HistManager.h" #include "PWGCF/Femto/DataModel/FemtoTables.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/HistogramSpec.h" - -#include "fairlogger/Logger.h" +#include +#include +#include #include #include diff --git a/PWGCF/Femto/Core/pairCleaner.h b/PWGCF/Femto/Core/pairCleaner.h index 506a9dbc9a4..0d66be6721f 100644 --- a/PWGCF/Femto/Core/pairCleaner.h +++ b/PWGCF/Femto/Core/pairCleaner.h @@ -18,7 +18,7 @@ #include "PWGCF/Femto/Core/modes.h" -#include "fairlogger/Logger.h" +#include namespace o2::analysis::femto { diff --git a/PWGCF/Femto/Core/pairHistManager.h b/PWGCF/Femto/Core/pairHistManager.h index 30c0916b67e..fb1d2056b8c 100644 --- a/PWGCF/Femto/Core/pairHistManager.h +++ b/PWGCF/Femto/Core/pairHistManager.h @@ -20,12 +20,14 @@ #include "PWGCF/Femto/Core/histManager.h" #include "PWGCF/Femto/Core/modes.h" -#include "Framework/Configurable.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/HistogramSpec.h" +#include +#include +#include +#include #include -#include +#include // IWYU pragma: keep (do not replace with Math/Vector4Dfwd.h) +#include #include #include diff --git a/PWGCF/Femto/Core/pairProcessHelpers.h b/PWGCF/Femto/Core/pairProcessHelpers.h index 8a70283e9c6..50d00196341 100644 --- a/PWGCF/Femto/Core/pairProcessHelpers.h +++ b/PWGCF/Femto/Core/pairProcessHelpers.h @@ -19,7 +19,9 @@ #include "PWGCF/Femto/Core/modes.h" #include "PWGCF/Femto/DataModel/FemtoTables.h" -#include "Framework/ASoAHelpers.h" +#include + +#include namespace o2::analysis::femto { diff --git a/PWGCF/Femto/Core/particleCleaner.h b/PWGCF/Femto/Core/particleCleaner.h index 8c158198192..045f3dea785 100644 --- a/PWGCF/Femto/Core/particleCleaner.h +++ b/PWGCF/Femto/Core/particleCleaner.h @@ -16,7 +16,7 @@ #ifndef PWGCF_FEMTO_CORE_PARTICLECLEANER_H_ #define PWGCF_FEMTO_CORE_PARTICLECLEANER_H_ -#include "Framework/Configurable.h" +#include #include #include diff --git a/PWGCF/Femto/Core/selectionContainer.h b/PWGCF/Femto/Core/selectionContainer.h index d67819b6f8d..fe5616f8302 100644 --- a/PWGCF/Femto/Core/selectionContainer.h +++ b/PWGCF/Femto/Core/selectionContainer.h @@ -16,11 +16,10 @@ #ifndef PWGCF_FEMTO_CORE_SELECTIONCONTAINER_H_ #define PWGCF_FEMTO_CORE_SELECTIONCONTAINER_H_ -#include "CommonConstants/MathConstants.h" +#include +#include -#include "TF1.h" - -#include "fairlogger/Logger.h" +#include #include #include @@ -28,6 +27,7 @@ #include #include #include +#include #include #include #include diff --git a/PWGCF/Femto/Core/trackBuilder.h b/PWGCF/Femto/Core/trackBuilder.h index ffb5df80c37..5c0fe83bc1c 100644 --- a/PWGCF/Femto/Core/trackBuilder.h +++ b/PWGCF/Femto/Core/trackBuilder.h @@ -23,11 +23,11 @@ #include "PWGCF/Femto/Core/selectionContainer.h" #include "PWGCF/Femto/DataModel/FemtoTables.h" -#include "CommonConstants/MathConstants.h" -#include "Framework/AnalysisHelpers.h" -#include "Framework/Configurable.h" - -#include "fairlogger/Logger.h" +#include +#include +#include +#include +#include #include #include diff --git a/PWGCF/Femto/Core/trackHistManager.h b/PWGCF/Femto/Core/trackHistManager.h index a0eb858e07a..11a307c087f 100644 --- a/PWGCF/Femto/Core/trackHistManager.h +++ b/PWGCF/Femto/Core/trackHistManager.h @@ -20,14 +20,16 @@ #include "PWGCF/Femto/Core/histManager.h" #include "PWGCF/Femto/Core/modes.h" -#include "CommonConstants/MathConstants.h" -#include "Framework/Configurable.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/HistogramSpec.h" +#include +#include +#include +#include +#include -#include "TH1.h" +#include #include +#include #include #include #include diff --git a/PWGCF/Femto/Core/tripletBuilder.h b/PWGCF/Femto/Core/tripletBuilder.h index 26b618441f9..1857f6a3996 100644 --- a/PWGCF/Femto/Core/tripletBuilder.h +++ b/PWGCF/Femto/Core/tripletBuilder.h @@ -19,16 +19,17 @@ #include "PWGCF/Femto/Core/closeTripletRejection.h" #include "PWGCF/Femto/Core/collisionHistManager.h" #include "PWGCF/Femto/Core/modes.h" +#include "PWGCF/Femto/Core/pairHistManager.h" #include "PWGCF/Femto/Core/trackHistManager.h" #include "PWGCF/Femto/Core/tripletCleaner.h" #include "PWGCF/Femto/Core/tripletHistManager.h" #include "PWGCF/Femto/Core/tripletProcessHelpers.h" +#include "PWGCF/Femto/Core/v0HistManager.h" #include "PWGCF/Femto/DataModel/FemtoTables.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/HistogramSpec.h" - -#include "fairlogger/Logger.h" +#include +#include +#include #include #include diff --git a/PWGCF/Femto/Core/tripletCleaner.h b/PWGCF/Femto/Core/tripletCleaner.h index 690c9d526b7..d6f38c78709 100644 --- a/PWGCF/Femto/Core/tripletCleaner.h +++ b/PWGCF/Femto/Core/tripletCleaner.h @@ -16,7 +16,7 @@ #ifndef PWGCF_FEMTO_CORE_TRIPLETCLEANER_H_ #define PWGCF_FEMTO_CORE_TRIPLETCLEANER_H_ -#include "PWGCF/Femto/Core/pairBuilder.h" +#include "PWGCF/Femto/Core/pairCleaner.h" namespace o2::analysis::femto { diff --git a/PWGCF/Femto/Core/tripletHistManager.h b/PWGCF/Femto/Core/tripletHistManager.h index 1af18cd8783..ee72c95e550 100644 --- a/PWGCF/Femto/Core/tripletHistManager.h +++ b/PWGCF/Femto/Core/tripletHistManager.h @@ -20,14 +20,14 @@ #include "PWGCF/Femto/Core/histManager.h" #include "PWGCF/Femto/Core/modes.h" -#include "Framework/Configurable.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/HistogramSpec.h" +#include +#include +#include +#include -#include -#include +#include // IWYU pragma: keep (do not replace with Math/Vector4Dfwd.h) +#include -#include #include #include #include diff --git a/PWGCF/Femto/Core/tripletProcessHelpers.h b/PWGCF/Femto/Core/tripletProcessHelpers.h index fc52c62da0e..75538ae024d 100644 --- a/PWGCF/Femto/Core/tripletProcessHelpers.h +++ b/PWGCF/Femto/Core/tripletProcessHelpers.h @@ -19,7 +19,9 @@ #include "PWGCF/Femto/Core/modes.h" #include "PWGCF/Femto/DataModel/FemtoTables.h" -#include "Framework/ASoAHelpers.h" +#include + +#include namespace o2::analysis::femto { diff --git a/PWGCF/Femto/Core/twoTrackResonanceBuilder.h b/PWGCF/Femto/Core/twoTrackResonanceBuilder.h index 9183527b890..f1dbb8cd5e1 100644 --- a/PWGCF/Femto/Core/twoTrackResonanceBuilder.h +++ b/PWGCF/Femto/Core/twoTrackResonanceBuilder.h @@ -16,8 +16,6 @@ #ifndef PWGCF_FEMTO_CORE_TWOTRACKRESONANCEBUILDER_H_ #define PWGCF_FEMTO_CORE_TWOTRACKRESONANCEBUILDER_H_ -#include "RecoDecay.h" - #include "PWGCF/Femto/Core/baseSelection.h" #include "PWGCF/Femto/Core/dataTypes.h" #include "PWGCF/Femto/Core/femtoUtils.h" @@ -25,15 +23,18 @@ #include "PWGCF/Femto/Core/selectionContainer.h" #include "PWGCF/Femto/DataModel/FemtoTables.h" -#include "CommonConstants/MathConstants.h" -#include "CommonConstants/PhysicsConstants.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisHelpers.h" -#include "Framework/Configurable.h" +#include "Common/Core/RecoDecay.h" -#include +#include +#include +#include +#include +#include +#include +#include -#include "fairlogger/Logger.h" +#include // IWYU pragma: keep (do not replace with Math/Vector4Dfwd.h) +#include #include #include diff --git a/PWGCF/Femto/Core/twoTrackResonanceHistManager.h b/PWGCF/Femto/Core/twoTrackResonanceHistManager.h index 7de7d7c3c04..de5317ff34c 100644 --- a/PWGCF/Femto/Core/twoTrackResonanceHistManager.h +++ b/PWGCF/Femto/Core/twoTrackResonanceHistManager.h @@ -20,10 +20,14 @@ #include "PWGCF/Femto/Core/modes.h" #include "PWGCF/Femto/Core/trackHistManager.h" -#include "CommonConstants/MathConstants.h" -#include "Framework/Configurable.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/HistogramSpec.h" +#include +#include +#include +#include +#include +#include + +#include #include #include diff --git a/PWGCF/Femto/Core/v0Builder.h b/PWGCF/Femto/Core/v0Builder.h index 16de0ea04cc..91465cb99ab 100644 --- a/PWGCF/Femto/Core/v0Builder.h +++ b/PWGCF/Femto/Core/v0Builder.h @@ -23,11 +23,11 @@ #include "PWGCF/Femto/Core/selectionContainer.h" #include "PWGCF/Femto/DataModel/FemtoTables.h" -#include "CommonConstants/MathConstants.h" -#include "Framework/AnalysisHelpers.h" -#include "Framework/Configurable.h" - -#include "fairlogger/Logger.h" +#include +#include +#include +#include +#include #include #include diff --git a/PWGCF/Femto/Core/v0HistManager.h b/PWGCF/Femto/Core/v0HistManager.h index 1fd7eba0b5c..b6cb832579f 100644 --- a/PWGCF/Femto/Core/v0HistManager.h +++ b/PWGCF/Femto/Core/v0HistManager.h @@ -20,12 +20,17 @@ #include "PWGCF/Femto/Core/modes.h" #include "PWGCF/Femto/Core/trackHistManager.h" -#include "CommonConstants/MathConstants.h" -#include "Framework/Configurable.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/HistogramSpec.h" +#include +#include +#include +#include +#include + +#include +#include #include +#include #include #include #include diff --git a/PWGCF/Femto/DataModel/FemtoTables.h b/PWGCF/Femto/DataModel/FemtoTables.h index 4c890bdb4e6..3ea208c3721 100644 --- a/PWGCF/Femto/DataModel/FemtoTables.h +++ b/PWGCF/Femto/DataModel/FemtoTables.h @@ -22,9 +22,9 @@ #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" -#include "Framework/ASoA.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/Expressions.h" +#include +#include +#include #include #include diff --git a/PWGCF/Femto/FemtoNuclei/DataModel/HadronNucleiTables.h b/PWGCF/Femto/FemtoNuclei/DataModel/HadronNucleiTables.h index 0ae1d298e1c..386f279fb0f 100644 --- a/PWGCF/Femto/FemtoNuclei/DataModel/HadronNucleiTables.h +++ b/PWGCF/Femto/FemtoNuclei/DataModel/HadronNucleiTables.h @@ -15,8 +15,9 @@ /// \author CMY /// \date 2025-04-10 -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" +#include + +#include #ifndef PWGCF_FEMTO_FEMTONUCLEI_DATAMODEL_HADRONNUCLEITABLES_H_ #define PWGCF_FEMTO_FEMTONUCLEI_DATAMODEL_HADRONNUCLEITABLES_H_ diff --git a/PWGCF/Femto/FemtoNuclei/TableProducer/HadNucleiFemto.cxx b/PWGCF/Femto/FemtoNuclei/TableProducer/HadNucleiFemto.cxx index 255f7674f1d..2906700eeb1 100644 --- a/PWGCF/Femto/FemtoNuclei/TableProducer/HadNucleiFemto.cxx +++ b/PWGCF/Femto/FemtoNuclei/TableProducer/HadNucleiFemto.cxx @@ -17,14 +17,11 @@ #include "PWGCF/Femto/FemtoNuclei/DataModel/HadronNucleiTables.h" #include "PWGCF/FemtoWorld/Core/FemtoWorldMath.h" -#include "PWGLF/DataModel/EPCalibrationTables.h" #include "PWGLF/DataModel/LFHypernucleiTables.h" #include "PWGLF/Utils/svPoolCreator.h" #include "Common/Core/PID/PIDTOF.h" -#include "Common/Core/PID/TPCPIDResponse.h" #include "Common/Core/RecoDecay.h" -#include "Common/Core/TrackSelection.h" #include "Common/Core/Zorro.h" #include "Common/Core/ZorroSummary.h" #include "Common/Core/trackUtilities.h" @@ -35,38 +32,40 @@ #include "Common/DataModel/PIDResponseTOF.h" #include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "Common/TableProducer/PID/pidTOFBase.h" - -#include "CCDB/BasicCCDBManager.h" -#include "DataFormatsParameters/GRPMagField.h" -#include "DataFormatsParameters/GRPObject.h" -#include "MathUtils/BetheBlochAleph.h" -#include "DetectorsBase/GeometryManager.h" -#include "DetectorsBase/Propagator.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/StepTHn.h" -#include "Framework/runDataProcessing.h" -#include "ReconstructionDataFormats/Track.h" - -#include "Math/Boost.h" -#include "Math/Vector4D.h" -#include -#include -#include -#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + #include #include -#include +#include +#include #include #include #include +#include #include #include -#include // std::prev #include #include diff --git a/PWGCF/Femto/TableProducer/femtoProducer.cxx b/PWGCF/Femto/TableProducer/femtoProducer.cxx index 2bfe13acdbf..4945edc358a 100644 --- a/PWGCF/Femto/TableProducer/femtoProducer.cxx +++ b/PWGCF/Femto/TableProducer/femtoProducer.cxx @@ -32,17 +32,16 @@ #include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "CCDB/BasicCCDBManager.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/Configurable.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/InitContext.h" -#include "Framework/OutputObjHeader.h" -#include "Framework/runDataProcessing.h" - -#include "fairlogger/Logger.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include diff --git a/PWGCF/Femto/TableProducer/femtoProducerDerivedToDerived.cxx b/PWGCF/Femto/TableProducer/femtoProducerDerivedToDerived.cxx index 42fd008417c..64a3ede4696 100644 --- a/PWGCF/Femto/TableProducer/femtoProducerDerivedToDerived.cxx +++ b/PWGCF/Femto/TableProducer/femtoProducerDerivedToDerived.cxx @@ -20,13 +20,13 @@ #include "PWGCF/Femto/Core/v0Builder.h" #include "PWGCF/Femto/DataModel/FemtoTables.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/Configurable.h" -#include "Framework/Expressions.h" -#include "Framework/InitContext.h" -#include "Framework/runDataProcessing.h" +#include +#include +#include +#include +#include +#include +#include using namespace o2::analysis::femto; diff --git a/PWGCF/Femto/TableProducer/femtoProducerKinkPtConverter.cxx b/PWGCF/Femto/TableProducer/femtoProducerKinkPtConverter.cxx index e8642fe53a4..f710e4ac194 100644 --- a/PWGCF/Femto/TableProducer/femtoProducerKinkPtConverter.cxx +++ b/PWGCF/Femto/TableProducer/femtoProducerKinkPtConverter.cxx @@ -16,11 +16,20 @@ #include "PWGCF/Femto/Core/femtoUtils.h" #include "PWGCF/Femto/DataModel/FemtoTables.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" - -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include // IWYU pragma: keep (do not replace with Math/Vector4Dfwd.h) +#include + +#include using namespace o2::analysis::femto; diff --git a/PWGCF/Femto/Tasks/femtoCascadeQa.cxx b/PWGCF/Femto/Tasks/femtoCascadeQa.cxx index 74bedd879d7..dfab27fe67f 100644 --- a/PWGCF/Femto/Tasks/femtoCascadeQa.cxx +++ b/PWGCF/Femto/Tasks/femtoCascadeQa.cxx @@ -23,15 +23,16 @@ #include "PWGCF/Femto/Core/trackHistManager.h" #include "PWGCF/Femto/DataModel/FemtoTables.h" -#include "Framework/ASoA.h" -#include "Framework/AnalysisHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/Configurable.h" -#include "Framework/Expressions.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/InitContext.h" -#include "Framework/OutputObjHeader.h" -#include "Framework/runDataProcessing.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include diff --git a/PWGCF/Femto/Tasks/femtoKinkQa.cxx b/PWGCF/Femto/Tasks/femtoKinkQa.cxx index fa1c977c494..a44d800488c 100644 --- a/PWGCF/Femto/Tasks/femtoKinkQa.cxx +++ b/PWGCF/Femto/Tasks/femtoKinkQa.cxx @@ -25,15 +25,16 @@ #include "PWGCF/Femto/DataModel/FemtoTables.h" #include "PWGLF/DataModel/LFKinkDecayTables.h" -#include "Framework/ASoA.h" -#include "Framework/AnalysisHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/Configurable.h" -#include "Framework/Expressions.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/InitContext.h" -#include "Framework/OutputObjHeader.h" -#include "Framework/runDataProcessing.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include diff --git a/PWGCF/Femto/Tasks/femtoPairTrackCascade.cxx b/PWGCF/Femto/Tasks/femtoPairTrackCascade.cxx index 9181a00d20d..9430fa71eef 100644 --- a/PWGCF/Femto/Tasks/femtoPairTrackCascade.cxx +++ b/PWGCF/Femto/Tasks/femtoPairTrackCascade.cxx @@ -27,16 +27,17 @@ #include "PWGCF/Femto/Core/trackHistManager.h" #include "PWGCF/Femto/DataModel/FemtoTables.h" -#include "Framework/ASoA.h" -#include "Framework/AnalysisHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/BinningPolicy.h" -#include "Framework/Configurable.h" -#include "Framework/Expressions.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/InitContext.h" -#include "Framework/OutputObjHeader.h" -#include "Framework/runDataProcessing.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include diff --git a/PWGCF/Femto/Tasks/femtoPairTrackKink.cxx b/PWGCF/Femto/Tasks/femtoPairTrackKink.cxx index df79897eefc..2132de4073e 100644 --- a/PWGCF/Femto/Tasks/femtoPairTrackKink.cxx +++ b/PWGCF/Femto/Tasks/femtoPairTrackKink.cxx @@ -28,16 +28,17 @@ #include "PWGCF/Femto/Core/trackHistManager.h" #include "PWGCF/Femto/DataModel/FemtoTables.h" -#include "Framework/ASoA.h" -#include "Framework/AnalysisHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/BinningPolicy.h" -#include "Framework/Configurable.h" -#include "Framework/Expressions.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/InitContext.h" -#include "Framework/OutputObjHeader.h" -#include "Framework/runDataProcessing.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include diff --git a/PWGCF/Femto/Tasks/femtoPairTrackTrack.cxx b/PWGCF/Femto/Tasks/femtoPairTrackTrack.cxx index 48c4fed92aa..bad86903f08 100644 --- a/PWGCF/Femto/Tasks/femtoPairTrackTrack.cxx +++ b/PWGCF/Femto/Tasks/femtoPairTrackTrack.cxx @@ -25,16 +25,17 @@ #include "PWGCF/Femto/Core/trackHistManager.h" #include "PWGCF/Femto/DataModel/FemtoTables.h" -#include "Framework/ASoA.h" -#include "Framework/AnalysisHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/BinningPolicy.h" -#include "Framework/Configurable.h" -#include "Framework/Expressions.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/InitContext.h" -#include "Framework/OutputObjHeader.h" -#include "Framework/runDataProcessing.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include diff --git a/PWGCF/Femto/Tasks/femtoPairTrackTwoTrackResonance.cxx b/PWGCF/Femto/Tasks/femtoPairTrackTwoTrackResonance.cxx index 1bf895ffb4f..db7e18ba53b 100644 --- a/PWGCF/Femto/Tasks/femtoPairTrackTwoTrackResonance.cxx +++ b/PWGCF/Femto/Tasks/femtoPairTrackTwoTrackResonance.cxx @@ -26,16 +26,16 @@ #include "PWGCF/Femto/Core/twoTrackResonanceHistManager.h" #include "PWGCF/Femto/DataModel/FemtoTables.h" -#include "Framework/ASoA.h" -#include "Framework/AnalysisHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/BinningPolicy.h" -#include "Framework/Configurable.h" -#include "Framework/Expressions.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/InitContext.h" -#include "Framework/OutputObjHeader.h" -#include "Framework/runDataProcessing.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include diff --git a/PWGCF/Femto/Tasks/femtoPairTrackV0.cxx b/PWGCF/Femto/Tasks/femtoPairTrackV0.cxx index f6891b3b670..f112f60b973 100644 --- a/PWGCF/Femto/Tasks/femtoPairTrackV0.cxx +++ b/PWGCF/Femto/Tasks/femtoPairTrackV0.cxx @@ -27,16 +27,17 @@ #include "PWGCF/Femto/Core/v0HistManager.h" #include "PWGCF/Femto/DataModel/FemtoTables.h" -#include "Framework/ASoA.h" -#include "Framework/AnalysisHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/BinningPolicy.h" -#include "Framework/Configurable.h" -#include "Framework/Expressions.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/InitContext.h" -#include "Framework/OutputObjHeader.h" -#include "Framework/runDataProcessing.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include diff --git a/PWGCF/Femto/Tasks/femtoPairV0V0.cxx b/PWGCF/Femto/Tasks/femtoPairV0V0.cxx index d1783be7075..1cf6ffaf677 100644 --- a/PWGCF/Femto/Tasks/femtoPairV0V0.cxx +++ b/PWGCF/Femto/Tasks/femtoPairV0V0.cxx @@ -26,16 +26,17 @@ #include "PWGCF/Femto/Core/v0HistManager.h" #include "PWGCF/Femto/DataModel/FemtoTables.h" -#include "Framework/ASoA.h" -#include "Framework/AnalysisHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/BinningPolicy.h" -#include "Framework/Configurable.h" -#include "Framework/Expressions.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/InitContext.h" -#include "Framework/OutputObjHeader.h" -#include "Framework/runDataProcessing.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include diff --git a/PWGCF/Femto/Tasks/femtoTrackQa.cxx b/PWGCF/Femto/Tasks/femtoTrackQa.cxx index ca196b85185..1108960405f 100644 --- a/PWGCF/Femto/Tasks/femtoTrackQa.cxx +++ b/PWGCF/Femto/Tasks/femtoTrackQa.cxx @@ -22,14 +22,16 @@ #include "PWGCF/Femto/Core/trackHistManager.h" #include "PWGCF/Femto/DataModel/FemtoTables.h" -#include "Framework/ASoA.h" -#include "Framework/AnalysisHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/Expressions.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/InitContext.h" -#include "Framework/OutputObjHeader.h" -#include "Framework/runDataProcessing.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include diff --git a/PWGCF/Femto/Tasks/femtoTripletTrackTrackTrack.cxx b/PWGCF/Femto/Tasks/femtoTripletTrackTrackTrack.cxx index 8ab8dc46d2d..05dcdd5b153 100644 --- a/PWGCF/Femto/Tasks/femtoTripletTrackTrackTrack.cxx +++ b/PWGCF/Femto/Tasks/femtoTripletTrackTrackTrack.cxx @@ -13,6 +13,7 @@ /// \brief Tasks that computes correlation between three tracks /// \author Anton Riedel, TU München, anton.riedel@cern.ch +#include "PWGCF/Femto/Core/closePairRejection.h" #include "PWGCF/Femto/Core/closeTripletRejection.h" #include "PWGCF/Femto/Core/collisionBuilder.h" #include "PWGCF/Femto/Core/collisionHistManager.h" @@ -24,16 +25,17 @@ #include "PWGCF/Femto/Core/tripletHistManager.h" #include "PWGCF/Femto/DataModel/FemtoTables.h" -#include "Framework/ASoA.h" -#include "Framework/AnalysisHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/BinningPolicy.h" -#include "Framework/Configurable.h" -#include "Framework/Expressions.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/InitContext.h" -#include "Framework/OutputObjHeader.h" -#include "Framework/runDataProcessing.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include diff --git a/PWGCF/Femto/Tasks/femtoTripletTrackTrackV0.cxx b/PWGCF/Femto/Tasks/femtoTripletTrackTrackV0.cxx index ccbe794f3c1..1ac8d76976f 100644 --- a/PWGCF/Femto/Tasks/femtoTripletTrackTrackV0.cxx +++ b/PWGCF/Femto/Tasks/femtoTripletTrackTrackV0.cxx @@ -13,10 +13,12 @@ /// \brief Tasks that computes correlation between two tracks /// \author Anton Riedel, TU München, anton.riedel@cern.ch +#include "PWGCF/Femto/Core/closePairRejection.h" #include "PWGCF/Femto/Core/closeTripletRejection.h" #include "PWGCF/Femto/Core/collisionBuilder.h" #include "PWGCF/Femto/Core/collisionHistManager.h" #include "PWGCF/Femto/Core/modes.h" +#include "PWGCF/Femto/Core/particleCleaner.h" #include "PWGCF/Femto/Core/partitions.h" #include "PWGCF/Femto/Core/trackBuilder.h" #include "PWGCF/Femto/Core/trackHistManager.h" @@ -26,16 +28,17 @@ #include "PWGCF/Femto/Core/v0HistManager.h" #include "PWGCF/Femto/DataModel/FemtoTables.h" -#include "Framework/ASoA.h" -#include "Framework/AnalysisHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/BinningPolicy.h" -#include "Framework/Configurable.h" -#include "Framework/Expressions.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/InitContext.h" -#include "Framework/OutputObjHeader.h" -#include "Framework/runDataProcessing.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include diff --git a/PWGCF/Femto/Tasks/femtoTwotrackresonanceQa.cxx b/PWGCF/Femto/Tasks/femtoTwotrackresonanceQa.cxx index 7faff356fd2..1bd205a9d25 100644 --- a/PWGCF/Femto/Tasks/femtoTwotrackresonanceQa.cxx +++ b/PWGCF/Femto/Tasks/femtoTwotrackresonanceQa.cxx @@ -22,17 +22,16 @@ #include "PWGCF/Femto/Core/twoTrackResonanceHistManager.h" #include "PWGCF/Femto/DataModel/FemtoTables.h" -#include "Framework/ASoA.h" -#include "Framework/AnalysisHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/Configurable.h" -#include "Framework/Expressions.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/InitContext.h" -#include "Framework/OutputObjHeader.h" -#include "Framework/runDataProcessing.h" - -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + #include #include diff --git a/PWGCF/Femto/Tasks/femtoV0Qa.cxx b/PWGCF/Femto/Tasks/femtoV0Qa.cxx index a3587aaca95..d31299cb182 100644 --- a/PWGCF/Femto/Tasks/femtoV0Qa.cxx +++ b/PWGCF/Femto/Tasks/femtoV0Qa.cxx @@ -23,15 +23,16 @@ #include "PWGCF/Femto/Core/v0HistManager.h" #include "PWGCF/Femto/DataModel/FemtoTables.h" -#include "Framework/ASoA.h" -#include "Framework/AnalysisHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/Configurable.h" -#include "Framework/Expressions.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/InitContext.h" -#include "Framework/OutputObjHeader.h" -#include "Framework/runDataProcessing.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include diff --git a/PWGCF/Femto3D/Core/femto3dPairTask.h b/PWGCF/Femto3D/Core/femto3dPairTask.h index 1fd450ac28b..e0ba131e0a3 100644 --- a/PWGCF/Femto3D/Core/femto3dPairTask.h +++ b/PWGCF/Femto3D/Core/femto3dPairTask.h @@ -16,23 +16,23 @@ #ifndef PWGCF_FEMTO3D_CORE_FEMTO3DPAIRTASK_H_ #define PWGCF_FEMTO3D_CORE_FEMTO3DPAIRTASK_H_ -#define THETA(eta) 2.0 * std::atan(std::exp(-eta)) -// #include "Framework/ASoA.h" -// #include "Framework/DataTypes.h" -// #include "Framework/AnalysisDataModel.h" -// #include "Framework/Logger.h" -// #include "Common/DataModel/Multiplicity.h" - -#include "CommonConstants/MathConstants.h" -#include "CommonConstants/PhysicsConstants.h" +#include +#include -#include "TDatabasePDG.h" -#include "TLorentzVector.h" -#include "TVector3.h" +#include +#include +#include +#include +#include +#include +#include #include +#include #include +#define THETA(eta) 2.0 * std::atan(std::exp(-eta)) + double particle_mass(const int PDGcode) { switch (std::abs(PDGcode)) { diff --git a/PWGCF/Femto3D/DataModel/PIDutils.h b/PWGCF/Femto3D/DataModel/PIDutils.h index 74a3b7ef15a..8baed073633 100644 --- a/PWGCF/Femto3D/DataModel/PIDutils.h +++ b/PWGCF/Femto3D/DataModel/PIDutils.h @@ -22,6 +22,8 @@ #include "Common/DataModel/PIDResponseTOF.h" #include "Common/DataModel/PIDResponseTPC.h" +#include + #include #include #include diff --git a/PWGCF/Femto3D/DataModel/singletrackselector.h b/PWGCF/Femto3D/DataModel/singletrackselector.h index cce33ef19aa..9eb7d9458ec 100644 --- a/PWGCF/Femto3D/DataModel/singletrackselector.h +++ b/PWGCF/Femto3D/DataModel/singletrackselector.h @@ -16,18 +16,19 @@ #ifndef PWGCF_FEMTO3D_DATAMODEL_SINGLETRACKSELECTOR_H_ #define PWGCF_FEMTO3D_DATAMODEL_SINGLETRACKSELECTOR_H_ -// #include -#include "PWGCF/Femto3D/DataModel/PIDutils.h" - -#include "Common/DataModel/Multiplicity.h" +#include "Common/CCDB/EventSelectionParams.h" +#include "Common/DataModel/EventSelection.h" #include "Common/DataModel/PIDResponseITS.h" -#include "Framework/ASoA.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/Logger.h" +#include +#include +#include + +#include +#include +#include #include -#include namespace o2::aod { diff --git a/PWGCF/Femto3D/TableProducer/Converters/singleTrackSelectorConverter.cxx b/PWGCF/Femto3D/TableProducer/Converters/singleTrackSelectorConverter.cxx index 4a44e331e9b..7f4071f3b11 100644 --- a/PWGCF/Femto3D/TableProducer/Converters/singleTrackSelectorConverter.cxx +++ b/PWGCF/Femto3D/TableProducer/Converters/singleTrackSelectorConverter.cxx @@ -13,10 +13,11 @@ /// \author Sofia Tomassini, Gleb Romanenko, Nicolò Jacazio /// \since 03 May 2024 -#include #include "PWGCF/Femto3D/DataModel/singletrackselector.h" -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" + +#include +#include +#include using namespace o2; using namespace o2::framework; diff --git a/PWGCF/Femto3D/TableProducer/Converters/singleTrackSelectorConverterV1.cxx b/PWGCF/Femto3D/TableProducer/Converters/singleTrackSelectorConverterV1.cxx index 584760ce74a..fc195ba1b24 100644 --- a/PWGCF/Femto3D/TableProducer/Converters/singleTrackSelectorConverterV1.cxx +++ b/PWGCF/Femto3D/TableProducer/Converters/singleTrackSelectorConverterV1.cxx @@ -13,10 +13,11 @@ /// \author Sofia Tomassini, Gleb Romanenko, Nicolò Jacazio /// \since 03 May 2024 -#include #include "PWGCF/Femto3D/DataModel/singletrackselector.h" -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" + +#include +#include +#include using namespace o2; using namespace o2::framework; diff --git a/PWGCF/Femto3D/TableProducer/singleTrackSelector.cxx b/PWGCF/Femto3D/TableProducer/singleTrackSelector.cxx index 2710513529f..b1704a160b5 100644 --- a/PWGCF/Femto3D/TableProducer/singleTrackSelector.cxx +++ b/PWGCF/Femto3D/TableProducer/singleTrackSelector.cxx @@ -15,27 +15,40 @@ #include "PWGCF/Femto3D/DataModel/singletrackselector.h" +#include "PWGCF/Femto3D/DataModel/PIDutils.h" + +#include "Common/CCDB/RCTSelectionFlags.h" #include "Common/CCDB/ctpRateFetcher.h" #include "Common/Core/Zorro.h" #include "Common/Core/ZorroSummary.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" -#include "Common/DataModel/PIDResponseITS.h" #include "Common/DataModel/PIDResponseTOF.h" #include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "CCDB/BasicCCDBManager.h" -#include "DataFormatsParameters/GRPMagField.h" -#include "DataFormatsParameters/GRPObject.h" -#include "DetectorsBase/Propagator.h" -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" +#include +#include +#include +#include +#include #include - -#include - +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include #include #include #include diff --git a/PWGCF/Femto3D/TableProducer/singleTrackSelectorExtra.cxx b/PWGCF/Femto3D/TableProducer/singleTrackSelectorExtra.cxx index 0f065371ca8..0a6a941958b 100644 --- a/PWGCF/Femto3D/TableProducer/singleTrackSelectorExtra.cxx +++ b/PWGCF/Femto3D/TableProducer/singleTrackSelectorExtra.cxx @@ -15,13 +15,14 @@ // this task produces a dummy "SingleCollExtras" table that is now required in the analysis tasks. Needed to have a compatibility with old der. data -#include -#include - #include "PWGCF/Femto3D/DataModel/singletrackselector.h" -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" +#include +#include +#include +#include + +#include using namespace o2; using namespace o2::framework; diff --git a/PWGCF/Femto3D/TableProducer/singleTrackSelectorPIDMaker.cxx b/PWGCF/Femto3D/TableProducer/singleTrackSelectorPIDMaker.cxx index ebdc786469b..6f70ace41c4 100644 --- a/PWGCF/Femto3D/TableProducer/singleTrackSelectorPIDMaker.cxx +++ b/PWGCF/Femto3D/TableProducer/singleTrackSelectorPIDMaker.cxx @@ -14,17 +14,17 @@ /// \author Sofia Tomassini, Gleb Romanenko, Nicolò Jacazio /// \since 22 January 2025 -#include -#include +#include "PWGCF/Femto3D/DataModel/singletrackselector.h" -#include +#include +#include +#include +#include + +#include #include #include - -#include "PWGCF/Femto3D/DataModel/singletrackselector.h" - -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" +#include using namespace o2; using namespace o2::framework; diff --git a/PWGCF/Femto3D/Tasks/PIDoptimization.cxx b/PWGCF/Femto3D/Tasks/PIDoptimization.cxx index b79d3ca8b55..7ec65abf3ee 100644 --- a/PWGCF/Femto3D/Tasks/PIDoptimization.cxx +++ b/PWGCF/Femto3D/Tasks/PIDoptimization.cxx @@ -13,43 +13,36 @@ /// \author Sofia Tomassini /// \since July 2025 -#include "Common/CCDB/ctpRateFetcher.h" -#include "Common/Core/TrackSelection.h" -#include "Common/Core/Zorro.h" -#include "Common/Core/ZorroSummary.h" -#include "Common/DataModel/Centrality.h" +#include "Common/CCDB/EventSelectionParams.h" #include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponseITS.h" #include "Common/DataModel/PIDResponseTOF.h" #include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "CCDB/BasicCCDBManager.h" -#include "CommonConstants/MathConstants.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/Configurable.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/StaticFor.h" -#include "Framework/runDataProcessing.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include -#include "Math/GenVector/Boost.h" -#include "Math/Vector4D.h" -#include "TMath.h" -#include "TRandom3.h" -#include +#include +#include -#include "fairlogger/Logger.h" - -#include -#include +#include +#include +#include #include #include #include #include +#include + using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; diff --git a/PWGCF/Femto3D/Tasks/femto3dPairTask.cxx b/PWGCF/Femto3D/Tasks/femto3dPairTask.cxx index db6c12dc14c..4be592c5e37 100644 --- a/PWGCF/Femto3D/Tasks/femto3dPairTask.cxx +++ b/PWGCF/Femto3D/Tasks/femto3dPairTask.cxx @@ -13,31 +13,37 @@ /// \author Sofia Tomassini, Gleb Romanenko, Nicolò Jacazio /// \since 31 May 2023 -#include -#include // std::random_shuffle -#include +#include "PWGCF/Femto3D/Core/femto3dPairTask.h" + +#include "PWGCF/Femto3D/DataModel/PIDutils.h" +#include "PWGCF/Femto3D/DataModel/singletrackselector.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + #include -#include +#include +#include +#include #include #include +#include #include -#include -#include - -#include "PWGCF/Femto3D/Core/femto3dPairTask.h" -#include "PWGCF/Femto3D/DataModel/singletrackselector.h" -#include "TLorentzVector.h" - -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/ASoA.h" -#include "Framework/DataTypes.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/Expressions.h" -#include "Framework/StaticFor.h" -#include "MathUtils/Utils.h" -#include "Common/DataModel/Multiplicity.h" +#include using namespace o2; using namespace o2::soa; diff --git a/PWGCF/Femto3D/Tasks/femto3dPairTaskMC.cxx b/PWGCF/Femto3D/Tasks/femto3dPairTaskMC.cxx index 0602efb9913..827494f94f3 100644 --- a/PWGCF/Femto3D/Tasks/femto3dPairTaskMC.cxx +++ b/PWGCF/Femto3D/Tasks/femto3dPairTaskMC.cxx @@ -13,27 +13,35 @@ /// \author Sofia Tomassini, Gleb Romanenko, Nicolò Jacazio /// \since 31 May 2023 -#include +#include "PWGCF/Femto3D/Core/femto3dPairTask.h" +#include "PWGCF/Femto3D/DataModel/PIDutils.h" +#include "PWGCF/Femto3D/DataModel/singletrackselector.h" + +#include "Common/DataModel/PIDResponseITS.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include #include #include #include -#include -#include - -#include "PWGCF/Femto3D/Core/femto3dPairTask.h" -#include "PWGCF/Femto3D/DataModel/singletrackselector.h" -#include "TLorentzVector.h" - -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/ASoA.h" -#include "Framework/DataTypes.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/Expressions.h" -#include "Framework/StaticFor.h" -#include "MathUtils/Utils.h" -#include "Common/DataModel/Multiplicity.h" +#include using namespace o2; using namespace o2::soa; diff --git a/PWGCF/Femto3D/Tasks/femto3dQA.cxx b/PWGCF/Femto3D/Tasks/femto3dQA.cxx index f9f164d9ae3..e55cd3c73ed 100644 --- a/PWGCF/Femto3D/Tasks/femto3dQA.cxx +++ b/PWGCF/Femto3D/Tasks/femto3dQA.cxx @@ -13,26 +13,32 @@ /// \author Sofia Tomassini, Gleb Romanenko, Nicolò Jacazio /// \since 31 May 2023 -#include -#include -#include +#include "PWGCF/Femto3D/Core/femto3dPairTask.h" +#include "PWGCF/Femto3D/DataModel/PIDutils.h" +#include "PWGCF/Femto3D/DataModel/singletrackselector.h" -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include -#include +#include "Common/DataModel/PIDResponseITS.h" -#include "Framework/ASoA.h" -#include "MathUtils/Utils.h" -#include "Framework/DataTypes.h" -#include "Common/DataModel/Multiplicity.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/Expressions.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include -#include "Framework/StaticFor.h" -#include "PWGCF/Femto3D/DataModel/singletrackselector.h" -#include "PWGCF/Femto3D/Core/femto3dPairTask.h" +#include +#include + +#include +#include +#include +#include + +#include using namespace o2; using namespace o2::soa; diff --git a/PWGCF/Femto3D/Tools/checkPacking.cxx b/PWGCF/Femto3D/Tools/checkPacking.cxx index 51d26443200..50a1c4cd60a 100644 --- a/PWGCF/Femto3D/Tools/checkPacking.cxx +++ b/PWGCF/Femto3D/Tools/checkPacking.cxx @@ -17,9 +17,15 @@ /// #include "PWGCF/Femto3D/DataModel/singletrackselector.h" -#include "TH1F.h" -#include "TCanvas.h" -#include "TRandom.h" + +#include + +#include +#include +#include +#include + +#include using namespace o2; diff --git a/PWGCF/FemtoDream/Core/femtoDreamCascadeSelection.h b/PWGCF/FemtoDream/Core/femtoDreamCascadeSelection.h index da74e7bda3a..e3ce9e8f628 100644 --- a/PWGCF/FemtoDream/Core/femtoDreamCascadeSelection.h +++ b/PWGCF/FemtoDream/Core/femtoDreamCascadeSelection.h @@ -22,23 +22,22 @@ #ifndef PWGCF_FEMTODREAM_CORE_FEMTODREAMCASCADESELECTION_H_ #define PWGCF_FEMTODREAM_CORE_FEMTODREAMCASCADESELECTION_H_ +#include "PWGCF/DataModel/FemtoDerived.h" #include "PWGCF/FemtoDream/Core/femtoDreamObjectSelection.h" #include "PWGCF/FemtoDream/Core/femtoDreamSelection.h" #include "PWGCF/FemtoDream/Core/femtoDreamTrackSelection.h" -#include "Common/Core/RecoDecay.h" +#include +#include +#include -#include "Framework/HistogramRegistry.h" -#include "ReconstructionDataFormats/PID.h" - -#include // FIXME - -#include +#include +#include #include +#include #include -using namespace o2::framework; -using namespace o2::analysis::femtoDream::femtoDreamSelection; +#include namespace o2::analysis::femtoDream { @@ -132,7 +131,7 @@ class FemtoDreamCascadeSelection o2::aod::femtodreamparticle::ParticleType v0daugh, o2::aod::femtodreamparticle::ParticleType bach, typename cutContainerType> - void init(HistogramRegistry* QAregistry, HistogramRegistry* Registry, bool isSelectCascOmega = false); + void init(o2::framework::HistogramRegistry* QAregistry, o2::framework::HistogramRegistry* Registry, bool isSelectCascOmega = false); template bool isSelectedMinimal(Col const& col, Casc const& cascade, Track const& posTrack, Track const& negTrack, Track const& bachTrack); @@ -349,11 +348,11 @@ class FemtoDreamCascadeSelection ///< different selections // static constexpr int kNcutStages = 2; - // static constexpr std::string_view mCutStage[kNcutStages] = {"BeforeSel", "AfterSel"}; + // static constexpr std::string_view femtoDreamSelection::mCutStage[kNcutStages] = {"BeforeSel", "AfterSel"}; }; // namespace femtoDream template -void FemtoDreamCascadeSelection::init(HistogramRegistry* QAregistry, HistogramRegistry* Registry, bool isSelectCascOmega) +void FemtoDreamCascadeSelection::init(o2::framework::HistogramRegistry* QAregistry, o2::framework::HistogramRegistry* Registry, bool isSelectCascOmega) { if (QAregistry && Registry) { @@ -363,18 +362,18 @@ void FemtoDreamCascadeSelection::init(HistogramRegistry* QAregistry, HistogramRe // fillSelectionHistogram(); // pos, neg // fillSelectionHistogram(); // bach - AxisSpec ptAxis = {100, 0.0f, 10.0f, "#it{p}_{T} (GeV/#it{c})"}; - AxisSpec etaAxis = {100, -2.0f, 2.0f, "#it{#eta}"}; - AxisSpec phiAxis = {100, 0.0f, 6.0f, "#it{#phi}"}; - AxisSpec DCADaughAxis = {1000, 0.0f, 2.0f, "DCA (cm)"}; - AxisSpec CPAAxis = {1000, 0.95f, 1.0f, "#it{cos #theta_{p}}"}; - AxisSpec tranRadAxis = {1000, 0.0f, 100.0f, "#it{r}_{xy} (cm)"}; - AxisSpec decVtxAxis = {2000, 0, 200, "#it{Vtx}_{z} (cm)"}; - AxisSpec massAxisCascade = {2200, 1.25f, 1.8f, "m_{#Cascade} (GeV/#it{c}^{2})"}; + o2::framework::AxisSpec ptAxis = {100, 0.0f, 10.0f, "#it{p}_{T} (GeV/#it{c})"}; + o2::framework::AxisSpec etaAxis = {100, -2.0f, 2.0f, "#it{#eta}"}; + o2::framework::AxisSpec phiAxis = {100, 0.0f, 6.0f, "#it{#phi}"}; + o2::framework::AxisSpec DCADaughAxis = {1000, 0.0f, 2.0f, "DCA (cm)"}; + o2::framework::AxisSpec CPAAxis = {1000, 0.95f, 1.0f, "#it{cos #theta_{p}}"}; + o2::framework::AxisSpec tranRadAxis = {1000, 0.0f, 100.0f, "#it{r}_{xy} (cm)"}; + o2::framework::AxisSpec decVtxAxis = {2000, 0, 200, "#it{Vtx}_{z} (cm)"}; + o2::framework::AxisSpec massAxisCascade = {2200, 1.25f, 1.8f, "m_{#Cascade} (GeV/#it{c}^{2})"}; - AxisSpec DCAToPVAxis = {1000, -10.0f, 10.0f, "DCA to PV (cm)"}; + o2::framework::AxisSpec DCAToPVAxis = {1000, -10.0f, 10.0f, "DCA to PV (cm)"}; - AxisSpec massAxisV0 = {600, 0.0f, 3.0f, "m_{#V0} (GeV/#it{c}^{2})"}; + o2::framework::AxisSpec massAxisV0 = {600, 0.0f, 3.0f, "m_{#V0} (GeV/#it{c}^{2})"}; /// \todo this should be an automatic check in the parent class, and the /// return type should be templated @@ -386,23 +385,23 @@ void FemtoDreamCascadeSelection::init(HistogramRegistry* QAregistry, HistogramRe } std::string folderName = static_cast(o2::aod::femtodreamparticle::ParticleTypeName[part]); - for (int istage = 0; istage < kNcutStages; istage++) { - mQAHistogramRegistry->add((folderName + "/" + static_cast(mCutStage[istage]) + "/hSign").c_str(), "; Sign of the Cascade ; Entries", kTH1I, {{3, -1, 2}}); - mQAHistogramRegistry->add((folderName + "/" + static_cast(mCutStage[istage]) + "/hPt").c_str(), "; #it{p}_{T} (GeV/#it{c}); Entries", kTH1F, {{1000, 0, 10}}); - mQAHistogramRegistry->add((folderName + "/" + static_cast(mCutStage[istage]) + "/hEta").c_str(), "; #eta; Entries", kTH1F, {{1000, -1, 1}}); - mQAHistogramRegistry->add((folderName + "/" + static_cast(mCutStage[istage]) + "/hPhi").c_str(), "; #phi; Entries", kTH1F, {{1000, 0, 2. * M_PI}}); - mQAHistogramRegistry->add((folderName + "/" + static_cast(mCutStage[istage]) + "/hDCADaugh").c_str(), "; daughters DCA; Entries", kTH1F, {DCADaughAxis}); - mQAHistogramRegistry->add((folderName + "/" + static_cast(mCutStage[istage]) + "/hCPA").c_str(), "; Cos PA; Entries", kTH1F, {CPAAxis}); - mQAHistogramRegistry->add((folderName + "/" + static_cast(mCutStage[istage]) + "/hTranRad").c_str(), "; Transverse Radius; Entries", kTH1F, {tranRadAxis}); - mQAHistogramRegistry->add((folderName + "/" + static_cast(mCutStage[istage]) + "/hDecVtxX").c_str(), "; Decay vertex x position; Entries", kTH1F, {tranRadAxis}); - mQAHistogramRegistry->add((folderName + "/" + static_cast(mCutStage[istage]) + "/hDecVtxY").c_str(), "; Decay vertex y position; Entries", kTH1F, {tranRadAxis}); - mQAHistogramRegistry->add((folderName + "/" + static_cast(mCutStage[istage]) + "/hDecVtxZ").c_str(), "; Decay vertex z position; Entries", kTH1F, {tranRadAxis}); - mQAHistogramRegistry->add((folderName + "/" + static_cast(mCutStage[istage]) + "/hInvMass").c_str(), "; Invariant mass; Entries", kTH1F, {massAxisCascade}); - mQAHistogramRegistry->add((folderName + "/" + static_cast(mCutStage[istage]) + "/hV0DCADaugh").c_str(), "; V0-daughters DCA; Entries", kTH1F, {DCADaughAxis}); - mQAHistogramRegistry->add((folderName + "/" + static_cast(mCutStage[istage]) + "/hV0CPA").c_str(), "; V0 cos PA; Entries", kTH1F, {CPAAxis}); - mQAHistogramRegistry->add((folderName + "/" + static_cast(mCutStage[istage]) + "/hV0TranRad").c_str(), "; V0 transverse radius; Entries", kTH1F, {tranRadAxis}); - mQAHistogramRegistry->add((folderName + "/" + static_cast(mCutStage[istage]) + "/hV0DCAToPV").c_str(), "; DCA of the V0 to the PV; Entries", kTH1F, {DCAToPVAxis}); - mQAHistogramRegistry->add((folderName + "/" + static_cast(mCutStage[istage]) + "/hV0InvMass").c_str(), "; Invariant mass Cascade V0; Entries", kTH1F, {massAxisV0}); + for (int istage = 0; istage < femtoDreamSelection::kNcutStages; istage++) { + mQAHistogramRegistry->add((folderName + "/" + static_cast(femtoDreamSelection::mCutStage[istage]) + "/hSign").c_str(), "; Sign of the Cascade ; Entries", o2::framework::kTH1I, {{3, -1, 2}}); + mQAHistogramRegistry->add((folderName + "/" + static_cast(femtoDreamSelection::mCutStage[istage]) + "/hPt").c_str(), "; #it{p}_{T} (GeV/#it{c}); Entries", o2::framework::kTH1F, {{1000, 0, 10}}); + mQAHistogramRegistry->add((folderName + "/" + static_cast(femtoDreamSelection::mCutStage[istage]) + "/hEta").c_str(), "; #eta; Entries", o2::framework::kTH1F, {{1000, -1, 1}}); + mQAHistogramRegistry->add((folderName + "/" + static_cast(femtoDreamSelection::mCutStage[istage]) + "/hPhi").c_str(), "; #phi; Entries", o2::framework::kTH1F, {{1000, 0, 2. * M_PI}}); + mQAHistogramRegistry->add((folderName + "/" + static_cast(femtoDreamSelection::mCutStage[istage]) + "/hDCADaugh").c_str(), "; daughters DCA; Entries", o2::framework::kTH1F, {DCADaughAxis}); + mQAHistogramRegistry->add((folderName + "/" + static_cast(femtoDreamSelection::mCutStage[istage]) + "/hCPA").c_str(), "; Cos PA; Entries", o2::framework::kTH1F, {CPAAxis}); + mQAHistogramRegistry->add((folderName + "/" + static_cast(femtoDreamSelection::mCutStage[istage]) + "/hTranRad").c_str(), "; Transverse Radius; Entries", o2::framework::kTH1F, {tranRadAxis}); + mQAHistogramRegistry->add((folderName + "/" + static_cast(femtoDreamSelection::mCutStage[istage]) + "/hDecVtxX").c_str(), "; Decay vertex x position; Entries", o2::framework::kTH1F, {tranRadAxis}); + mQAHistogramRegistry->add((folderName + "/" + static_cast(femtoDreamSelection::mCutStage[istage]) + "/hDecVtxY").c_str(), "; Decay vertex y position; Entries", o2::framework::kTH1F, {tranRadAxis}); + mQAHistogramRegistry->add((folderName + "/" + static_cast(femtoDreamSelection::mCutStage[istage]) + "/hDecVtxZ").c_str(), "; Decay vertex z position; Entries", o2::framework::kTH1F, {tranRadAxis}); + mQAHistogramRegistry->add((folderName + "/" + static_cast(femtoDreamSelection::mCutStage[istage]) + "/hInvMass").c_str(), "; Invariant mass; Entries", o2::framework::kTH1F, {massAxisCascade}); + mQAHistogramRegistry->add((folderName + "/" + static_cast(femtoDreamSelection::mCutStage[istage]) + "/hV0DCADaugh").c_str(), "; V0-daughters DCA; Entries", o2::framework::kTH1F, {DCADaughAxis}); + mQAHistogramRegistry->add((folderName + "/" + static_cast(femtoDreamSelection::mCutStage[istage]) + "/hV0CPA").c_str(), "; V0 cos PA; Entries", o2::framework::kTH1F, {CPAAxis}); + mQAHistogramRegistry->add((folderName + "/" + static_cast(femtoDreamSelection::mCutStage[istage]) + "/hV0TranRad").c_str(), "; V0 transverse radius; Entries", o2::framework::kTH1F, {tranRadAxis}); + mQAHistogramRegistry->add((folderName + "/" + static_cast(femtoDreamSelection::mCutStage[istage]) + "/hV0DCAToPV").c_str(), "; DCA of the V0 to the PV; Entries", o2::framework::kTH1F, {DCAToPVAxis}); + mQAHistogramRegistry->add((folderName + "/" + static_cast(femtoDreamSelection::mCutStage[istage]) + "/hV0InvMass").c_str(), "; Invariant mass Cascade V0; Entries", o2::framework::kTH1F, {massAxisV0}); } PosDaughTrack.initfill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(mCutStage[cutstage]) + HIST("/hSign"), casc.sign()); - mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(mCutStage[cutstage]) + HIST("/hPt"), casc.pt()); - mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(mCutStage[cutstage]) + HIST("/hEta"), casc.eta()); - mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(mCutStage[cutstage]) + HIST("/hPhi"), casc.phi()); - mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(mCutStage[cutstage]) + HIST("/hDCADaugh"), casc.dcacascdaughters()); - mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(mCutStage[cutstage]) + HIST("/hCPA"), cpaCasc); - mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(mCutStage[cutstage]) + HIST("/hTranRad"), casc.cascradius()); - mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(mCutStage[cutstage]) + HIST("/hDecVtxX"), decVtx.at(0)); - mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(mCutStage[cutstage]) + HIST("/hDecVtxY"), decVtx.at(1)); - mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(mCutStage[cutstage]) + HIST("/hDecVtxZ"), decVtx.at(2)); - mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(mCutStage[cutstage]) + HIST("/hInvMass"), invMass); - mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(mCutStage[cutstage]) + HIST("/hV0DCADaugh"), casc.dcaV0daughters()); - mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(mCutStage[cutstage]) + HIST("/hV0CPA"), cpav0); - mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(mCutStage[cutstage]) + HIST("/hV0TranRad"), casc.v0radius()); - mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(mCutStage[cutstage]) + HIST("/hV0DCAToPV"), v0dcatopv); - mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(mCutStage[cutstage]) + HIST("/hV0InvMass"), casc.mLambda()); + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(femtoDreamSelection::mCutStage[cutstage]) + HIST("/hSign"), casc.sign()); + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(femtoDreamSelection::mCutStage[cutstage]) + HIST("/hPt"), casc.pt()); + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(femtoDreamSelection::mCutStage[cutstage]) + HIST("/hEta"), casc.eta()); + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(femtoDreamSelection::mCutStage[cutstage]) + HIST("/hPhi"), casc.phi()); + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(femtoDreamSelection::mCutStage[cutstage]) + HIST("/hDCADaugh"), casc.dcacascdaughters()); + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(femtoDreamSelection::mCutStage[cutstage]) + HIST("/hCPA"), cpaCasc); + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(femtoDreamSelection::mCutStage[cutstage]) + HIST("/hTranRad"), casc.cascradius()); + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(femtoDreamSelection::mCutStage[cutstage]) + HIST("/hDecVtxX"), decVtx.at(0)); + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(femtoDreamSelection::mCutStage[cutstage]) + HIST("/hDecVtxY"), decVtx.at(1)); + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(femtoDreamSelection::mCutStage[cutstage]) + HIST("/hDecVtxZ"), decVtx.at(2)); + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(femtoDreamSelection::mCutStage[cutstage]) + HIST("/hInvMass"), invMass); + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(femtoDreamSelection::mCutStage[cutstage]) + HIST("/hV0DCADaugh"), casc.dcaV0daughters()); + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(femtoDreamSelection::mCutStage[cutstage]) + HIST("/hV0CPA"), cpav0); + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(femtoDreamSelection::mCutStage[cutstage]) + HIST("/hV0TranRad"), casc.v0radius()); + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(femtoDreamSelection::mCutStage[cutstage]) + HIST("/hV0DCAToPV"), v0dcatopv); + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(femtoDreamSelection::mCutStage[cutstage]) + HIST("/hV0InvMass"), casc.mLambda()); PosDaughTrack.fillQA(posTrack); diff --git a/PWGCF/FemtoDream/Core/femtoDreamCollisionSelection.h b/PWGCF/FemtoDream/Core/femtoDreamCollisionSelection.h index 8a455f073eb..5204c150e4d 100644 --- a/PWGCF/FemtoDream/Core/femtoDreamCollisionSelection.h +++ b/PWGCF/FemtoDream/Core/femtoDreamCollisionSelection.h @@ -16,22 +16,23 @@ #ifndef PWGCF_FEMTODREAM_CORE_FEMTODREAMCOLLISIONSELECTION_H_ #define PWGCF_FEMTODREAM_CORE_FEMTODREAMCOLLISIONSELECTION_H_ +#include "Common/CCDB/EventSelectionParams.h" #include "Common/CCDB/TriggerAliases.h" -#include "Common/Core/EventPlaneHelper.h" -#include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/Qvectors.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/Logger.h" +#include +#include +#include -#include "TMath.h" +#include +#include +#include -#include +#include +#include +#include #include #include -using namespace o2::framework; - namespace o2::analysis::femtoDream { @@ -63,19 +64,19 @@ class FemtoDreamCollisionSelection /// Initializes histograms for the task /// \param registry Histogram registry to be passed - void init(HistogramRegistry* registry) + void init(o2::framework::HistogramRegistry* registry) { if (!mCutsSet) { LOGF(error, "Event selection not set - quitting!"); } mHistogramRegistry = registry; - mHistogramRegistry->add("Event/Zvtx", "; vtx_{z} (cm); Entries", kTH1F, {{300, -12.5, 12.5}}); - mHistogramRegistry->add("Event/MultPercentile", "; Multiplicity Percentile; Entries", kTH1F, {{100, 0, 100}}); - mHistogramRegistry->add("Event/MultPercentileVSMultNTracksPV", "; Multiplicity Percentile; MultNTracks", kTH2F, {{100, 0, 100}, {200, 0, 200}}); - mHistogramRegistry->add("Event/MultNTracksPV", "; MultNTracksPV; Entries", kTH1F, {{200, 0, 200}}); - mHistogramRegistry->add("Event/MultNTracklets", "; MultNTrackslets; Entries", kTH1F, {{300, 0, 300}}); - mHistogramRegistry->add("Event/MultTPC", "; MultTPC; Entries", kTH1F, {{600, 0, 600}}); - mHistogramRegistry->add("Event/Sphericity", "; Sphericity; Entries", kTH1F, {{100, 0, 1}}); + mHistogramRegistry->add("Event/Zvtx", "; vtx_{z} (cm); Entries", o2::framework::kTH1F, {{300, -12.5, 12.5}}); + mHistogramRegistry->add("Event/MultPercentile", "; Multiplicity Percentile; Entries", o2::framework::kTH1F, {{100, 0, 100}}); + mHistogramRegistry->add("Event/MultPercentileVSMultNTracksPV", "; Multiplicity Percentile; MultNTracks", o2::framework::kTH2F, {{100, 0, 100}, {200, 0, 200}}); + mHistogramRegistry->add("Event/MultNTracksPV", "; MultNTracksPV; Entries", o2::framework::kTH1F, {{200, 0, 200}}); + mHistogramRegistry->add("Event/MultNTracklets", "; MultNTrackslets; Entries", o2::framework::kTH1F, {{300, 0, 300}}); + mHistogramRegistry->add("Event/MultTPC", "; MultTPC; Entries", o2::framework::kTH1F, {{600, 0, 600}}); + mHistogramRegistry->add("Event/Sphericity", "; Sphericity; Entries", o2::framework::kTH1F, {{100, 0, 1}}); } /// Print some debug information @@ -214,41 +215,41 @@ class FemtoDreamCollisionSelection /// Initializes histograms for qn bin /// \param registry Histogram registry to be passed - void initEPQA(HistogramRegistry* registry) + void initEPQA(o2::framework::HistogramRegistry* registry) { mHistogramQn = registry; - mHistogramQn->add("Event/centFT0CBeforeQn", "; cent", kTH1F, {{10, 0, 100}}); - mHistogramQn->add("Event/centFT0CAfterQn", "; cent", kTH1F, {{10, 0, 100}}); - mHistogramQn->add("Event/centVsqn", "; cent; qn", kTH2F, {{10, 0, 100}, {1000, 0, 1000}}); - mHistogramQn->add("Event/centVsqnVsSpher", "; cent; qn; Sphericity", kTH3F, {{10, 0, 100}, {100, 0, 1000}, {100, 0, 1}}); - mHistogramQn->add("Event/qnBin", "; qnBin; entries", kTH1F, {{20, 0, 20}}); - mHistogramQn->add("Event/psiEP", "; #Psi_{EP} (deg); entries", kTH1F, {{100, 0, 180}}); - mHistogramQn->add("Event/epReso_FT0CTPC", "; cent; qnBin; reso_ft0c_tpc", kTH2F, {{10, 0, 100}, {10, 0, 10}}); - mHistogramQn->add("Event/epReso_FT0ATPC", "; cent; qnBin; reso_ft0a_tpc", kTH2F, {{10, 0, 100}, {10, 0, 10}}); - mHistogramQn->add("Event/epReso_FT0CFT0A", "; cent; qnBin; reso_ft0c_ft0a", kTH2F, {{10, 0, 100}, {10, 0, 10}}); - mHistogramQn->add("Event/epReso_count", "; cent; qnBin; count", kTH2F, {{10, 0, 100}, {10, 0, 10}}); + mHistogramQn->add("Event/centFT0CBeforeQn", "; cent", o2::framework::kTH1F, {{10, 0, 100}}); + mHistogramQn->add("Event/centFT0CAfterQn", "; cent", o2::framework::kTH1F, {{10, 0, 100}}); + mHistogramQn->add("Event/centVsqn", "; cent; qn", o2::framework::kTH2F, {{10, 0, 100}, {1000, 0, 1000}}); + mHistogramQn->add("Event/centVsqnVsSpher", "; cent; qn; Sphericity", o2::framework::kTH3F, {{10, 0, 100}, {100, 0, 1000}, {100, 0, 1}}); + mHistogramQn->add("Event/qnBin", "; qnBin; entries", o2::framework::kTH1F, {{20, 0, 20}}); + mHistogramQn->add("Event/psiEP", "; #Psi_{EP} (deg); entries", o2::framework::kTH1F, {{100, 0, 180}}); + mHistogramQn->add("Event/epReso_FT0CTPC", "; cent; qnBin; reso_ft0c_tpc", o2::framework::kTH2F, {{10, 0, 100}, {10, 0, 10}}); + mHistogramQn->add("Event/epReso_FT0ATPC", "; cent; qnBin; reso_ft0a_tpc", o2::framework::kTH2F, {{10, 0, 100}, {10, 0, 10}}); + mHistogramQn->add("Event/epReso_FT0CFT0A", "; cent; qnBin; reso_ft0c_ft0a", o2::framework::kTH2F, {{10, 0, 100}, {10, 0, 10}}); + mHistogramQn->add("Event/epReso_count", "; cent; qnBin; count", o2::framework::kTH2F, {{10, 0, 100}, {10, 0, 10}}); return; } /// Initializes histograms for the flow calculation /// \param registry Histogram registry to be passed - void initFlow(HistogramRegistry* registry, bool doQnSeparation, int mumQnBins = 10, int centBins = 10) + void initFlow(o2::framework::HistogramRegistry* registry, bool doQnSeparation, int mumQnBins = 10, int centBins = 10) { if (!mCutsSet) { LOGF(error, "Event selection not set - quitting!"); } mHistogramQn = registry; - mHistogramQn->add("Event/hN2allQn", ";centrality; #sum Re(Q_{2,A} Q_{2,B}^{*})", kTH1F, {{centBins, 0, 100}}); - mHistogramQn->add("Event/hD2allQn", ";centrality; #sum (W_{A} W_{B})", kTH1F, {{centBins, 0, 100}}); + mHistogramQn->add("Event/hN2allQn", ";centrality; #sum Re(Q_{2,A} Q_{2,B}^{*})", o2::framework::kTH1F, {{centBins, 0, 100}}); + mHistogramQn->add("Event/hD2allQn", ";centrality; #sum (W_{A} W_{B})", o2::framework::kTH1F, {{centBins, 0, 100}}); mHistogramQn->get(HIST("Event/hN2allQn"))->Sumw2(); mHistogramQn->get(HIST("Event/hD2allQn"))->Sumw2(); if (doQnSeparation) { for (int iqn(0); iqn < mumQnBins; ++iqn) { - hN2.push_back(mHistogramQn->add(("Qn/hN2_" + std::to_string(iqn)).c_str(), ";centrality; #sum Re(Q_{2,A} Q_{2,B}^{*})", kTH1F, {{centBins, 0, 100}})); - hD2.push_back(mHistogramQn->add(("Qn/hD2_" + std::to_string(iqn)).c_str(), ";centrality; #sum (W_{A} W_{B})", kTH1F, {{centBins, 0, 100}})); + hN2.push_back(mHistogramQn->add(("Qn/hN2_" + std::to_string(iqn)).c_str(), ";centrality; #sum Re(Q_{2,A} Q_{2,B}^{*})", o2::framework::kTH1F, {{centBins, 0, 100}})); + hD2.push_back(mHistogramQn->add(("Qn/hD2_" + std::to_string(iqn)).c_str(), ";centrality; #sum (W_{A} W_{B})", o2::framework::kTH1F, {{centBins, 0, 100}})); } for (int iqn(0); iqn < mumQnBins; ++iqn) { std::get>(hN2[iqn])->Sumw2(); @@ -532,20 +533,20 @@ class FemtoDreamCollisionSelection } private: - HistogramRegistry* mHistogramRegistry = nullptr; ///< For QA output - bool mCutsSet = false; ///< Protection against running without cuts - bool mCheckTrigger = false; ///< Check for trigger - bool mCheckOffline = false; ///< Check for offline criteria (might change) - bool mAddCheckOffline = false; ///< Additional check for offline criteria (added to sel8 soon) - bool mCheckIsRun3 = false; ///< Check if running on Pilot Beam - triggerAliases mTrigger = kINT7; ///< Trigger to check for - float mZvtxMax = 999.f; ///< Maximal deviation from nominal z-vertex (cm) + o2::framework::HistogramRegistry* mHistogramRegistry = nullptr; ///< For QA output + bool mCutsSet = false; ///< Protection against running without cuts + bool mCheckTrigger = false; ///< Check for trigger + bool mCheckOffline = false; ///< Check for offline criteria (might change) + bool mAddCheckOffline = false; ///< Additional check for offline criteria (added to sel8 soon) + bool mCheckIsRun3 = false; ///< Check if running on Pilot Beam + triggerAliases mTrigger = kINT7; ///< Trigger to check for + float mZvtxMax = 999.f; ///< Maximal deviation from nominal z-vertex (cm) float mMinSphericity = 0.f; float mSphericityPtmin = 0.f; int mQnBin = -999; - HistogramRegistry* mHistogramQn = nullptr; ///< For flow cumulant output - std::vector hN2; ///< Histograms of c22 per Qn bin - std::vector hD2; ///< Histograms of c22 per Qn bin + o2::framework::HistogramRegistry* mHistogramQn = nullptr; ///< For flow cumulant output + std::vector hN2; ///< Histograms of c22 per Qn bin + std::vector hD2; ///< Histograms of c22 per Qn bin }; } // namespace o2::analysis::femtoDream diff --git a/PWGCF/FemtoDream/Core/femtoDreamContainer.h b/PWGCF/FemtoDream/Core/femtoDreamContainer.h index 4c3a5b24be0..3a1b7e631ab 100644 --- a/PWGCF/FemtoDream/Core/femtoDreamContainer.h +++ b/PWGCF/FemtoDream/Core/femtoDreamContainer.h @@ -23,18 +23,17 @@ #include "PWGCF/FemtoDream/Core/femtoDreamMath.h" #include "PWGCF/FemtoDream/Core/femtoDreamUtils.h" -#include "Framework/HistogramRegistry.h" +#include +#include +#include +#include -#include "Math/Vector4D.h" -#include "TMath.h" - -#include +#include #include +#include #include -using namespace o2::framework; - namespace o2::analysis::femtoDream { namespace femtoDreamContainer @@ -78,25 +77,25 @@ class FemtoDreamContainer T& /*kstarAxis4D*/, T& mTAxis4D, T& multAxis4D, T& multPercentileAxis4D, bool use4dplots, bool extendedplots, T& mP2Axis) { - mHistogramRegistry->add((folderName + "/relPairDist").c_str(), ("; " + femtoObs + "; Entries").c_str(), kTH1F, {femtoObsAxis}); - mHistogramRegistry->add((folderName + "/relPairkT").c_str(), "; #it{k}_{T} (GeV/#it{c}); Entries", kTH1F, {kTAxis}); - mHistogramRegistry->add((folderName + "/relPairkstarkT").c_str(), ("; " + femtoObs + "; #it{k}_{T} (GeV/#it{c})").c_str(), kTH2F, {femtoObsAxis, kTAxis}); - mHistogramRegistry->add((folderName + "/relPairkstarmT").c_str(), ("; " + femtoObs + "; #it{m}_{T} (GeV/#it{c}^{2})").c_str(), kTH2F, {femtoObsAxis, mTAxis}); - mHistogramRegistry->add((folderName + "/relPairkstarMult").c_str(), ("; " + femtoObs + "; Multiplicity").c_str(), kTH2F, {femtoObsAxis, multAxis}); - mHistogramRegistry->add((folderName + "/relPairkstarMultPercentile").c_str(), ("; " + femtoObs + "; Multiplicity Percentile").c_str(), kTH2F, {femtoObsAxis, multPercentileAxis4D}); - mHistogramRegistry->add((folderName + "/kstarPtPart1").c_str(), ("; " + femtoObs + "; #it{p} _{T} Particle 1 (GeV/#it{c})").c_str(), kTH2F, {femtoObsAxis, pTAxis}); - mHistogramRegistry->add((folderName + "/kstarPtPart2").c_str(), ("; " + femtoObs + "; #it{p} _{T} Particle 2 (GeV/#it{c})").c_str(), kTH2F, {femtoObsAxis, pTAxis}); - mHistogramRegistry->add((folderName + "/MultPtPart1").c_str(), "; #it{p} _{T} Particle 1 (GeV/#it{c}); Multiplicity", kTH2F, {pTAxis, multAxis}); - mHistogramRegistry->add((folderName + "/MultPtPart2").c_str(), "; #it{p} _{T} Particle 2 (GeV/#it{c}); Multiplicity", kTH2F, {pTAxis, multAxis}); - mHistogramRegistry->add((folderName + "/MultPercentilePtPart1").c_str(), "; #it{p} _{T} Particle 1 (GeV/#it{c}); Multiplicity Percentile", kTH2F, {pTAxis, multPercentileAxis}); - mHistogramRegistry->add((folderName + "/MultPercentilePtPart2").c_str(), "; #it{p} _{T} Particle 2 (GeV/#it{c}); Multiplicity Percentile", kTH2F, {pTAxis, multPercentileAxis}); - mHistogramRegistry->add((folderName + "/PtPart1PtPart2").c_str(), "; #it{p} _{T} Particle 1 (GeV/#it{c}); #it{p} _{T} Particle 2 (GeV/#it{c})", kTH2F, {pTAxis, pTAxis}); + mHistogramRegistry->add((folderName + "/relPairDist").c_str(), ("; " + femtoObs + "; Entries").c_str(), o2::framework::kTH1F, {femtoObsAxis}); + mHistogramRegistry->add((folderName + "/relPairkT").c_str(), "; #it{k}_{T} (GeV/#it{c}); Entries", o2::framework::kTH1F, {kTAxis}); + mHistogramRegistry->add((folderName + "/relPairkstarkT").c_str(), ("; " + femtoObs + "; #it{k}_{T} (GeV/#it{c})").c_str(), o2::framework::kTH2F, {femtoObsAxis, kTAxis}); + mHistogramRegistry->add((folderName + "/relPairkstarmT").c_str(), ("; " + femtoObs + "; #it{m}_{T} (GeV/#it{c}^{2})").c_str(), o2::framework::kTH2F, {femtoObsAxis, mTAxis}); + mHistogramRegistry->add((folderName + "/relPairkstarMult").c_str(), ("; " + femtoObs + "; Multiplicity").c_str(), o2::framework::kTH2F, {femtoObsAxis, multAxis}); + mHistogramRegistry->add((folderName + "/relPairkstarMultPercentile").c_str(), ("; " + femtoObs + "; Multiplicity Percentile").c_str(), o2::framework::kTH2F, {femtoObsAxis, multPercentileAxis4D}); + mHistogramRegistry->add((folderName + "/kstarPtPart1").c_str(), ("; " + femtoObs + "; #it{p} _{T} Particle 1 (GeV/#it{c})").c_str(), o2::framework::kTH2F, {femtoObsAxis, pTAxis}); + mHistogramRegistry->add((folderName + "/kstarPtPart2").c_str(), ("; " + femtoObs + "; #it{p} _{T} Particle 2 (GeV/#it{c})").c_str(), o2::framework::kTH2F, {femtoObsAxis, pTAxis}); + mHistogramRegistry->add((folderName + "/MultPtPart1").c_str(), "; #it{p} _{T} Particle 1 (GeV/#it{c}); Multiplicity", o2::framework::kTH2F, {pTAxis, multAxis}); + mHistogramRegistry->add((folderName + "/MultPtPart2").c_str(), "; #it{p} _{T} Particle 2 (GeV/#it{c}); Multiplicity", o2::framework::kTH2F, {pTAxis, multAxis}); + mHistogramRegistry->add((folderName + "/MultPercentilePtPart1").c_str(), "; #it{p} _{T} Particle 1 (GeV/#it{c}); Multiplicity Percentile", o2::framework::kTH2F, {pTAxis, multPercentileAxis}); + mHistogramRegistry->add((folderName + "/MultPercentilePtPart2").c_str(), "; #it{p} _{T} Particle 2 (GeV/#it{c}); Multiplicity Percentile", o2::framework::kTH2F, {pTAxis, multPercentileAxis}); + mHistogramRegistry->add((folderName + "/PtPart1PtPart2").c_str(), "; #it{p} _{T} Particle 1 (GeV/#it{c}); #it{p} _{T} Particle 2 (GeV/#it{c})", o2::framework::kTH2F, {pTAxis, pTAxis}); if (use4dplots) { - mHistogramRegistry->add((folderName + "/relPairkstarmTMultMultPercentile").c_str(), ("; " + femtoObs + "; #it{m}_{T} (GeV/#it{c}^{2}); Multiplicity").c_str(), kTHnSparseF, {femtoObsAxis, mTAxis4D, multAxis4D, multPercentileAxis4D}); + mHistogramRegistry->add((folderName + "/relPairkstarmTMultMultPercentile").c_str(), ("; " + femtoObs + "; #it{m}_{T} (GeV/#it{c}^{2}); Multiplicity").c_str(), o2::framework::kTHnSparseF, {femtoObsAxis, mTAxis4D, multAxis4D, multPercentileAxis4D}); } if (extendedplots) { - mHistogramRegistry->add((folderName + "/relPairkstarmTPtPart1PtPart2MultPercentile").c_str(), ("; :" + femtoObs + "; #it{m}_{T} (GeV/#it{c}^{2}); #it{p} _{T} Particle 1 (GeV/#it{c}); #it{p} _{T} Particle 2 (GeV/#it{c}); Multiplicity Percentile (%)").c_str(), kTHnSparseF, {femtoObsAxis, mTAxis4D, pTAxis, pTAxis, multPercentileAxis4D}); - mHistogramRegistry->add((folderName + "/invMassPart1invMassPart2kstar").c_str(), (";#it{m} (GeV/#it{c}^{2}); #it{m} (GeV/#it{c}^{2}), " + femtoObs).c_str(), kTHnSparseF, {mP2Axis, mP2Axis, femtoObsAxis}); + mHistogramRegistry->add((folderName + "/relPairkstarmTPtPart1PtPart2MultPercentile").c_str(), ("; :" + femtoObs + "; #it{m}_{T} (GeV/#it{c}^{2}); #it{p} _{T} Particle 1 (GeV/#it{c}); #it{p} _{T} Particle 2 (GeV/#it{c}); Multiplicity Percentile (%)").c_str(), o2::framework::kTHnSparseF, {femtoObsAxis, mTAxis4D, pTAxis, pTAxis, multPercentileAxis4D}); + mHistogramRegistry->add((folderName + "/invMassPart1invMassPart2kstar").c_str(), (";#it{m} (GeV/#it{c}^{2}); #it{m} (GeV/#it{c}^{2}), " + femtoObs).c_str(), o2::framework::kTHnSparseF, {mP2Axis, mP2Axis, femtoObsAxis}); } } @@ -108,18 +107,18 @@ class FemtoDreamContainer template void init_MC(std::string folderName, std::string femtoObs, T femtoObsAxis, T multAxis, T mTAxis, bool smearingByOrigin) { - mHistogramRegistry->add((folderName + "/relPairDist_ReconNoFake").c_str(), ("; " + femtoObs + "; Entries").c_str(), kTH1F, {femtoObsAxis}); - mHistogramRegistry->add((folderName + "/relPairkstarmT_ReconNoFake").c_str(), ("; " + femtoObs + "; #it{m}_{T} (GeV/#it{c}^{2})").c_str(), kTH2F, {femtoObsAxis, mTAxis}); - mHistogramRegistry->add((folderName + "/relPairkstarMult_ReconNoFake").c_str(), ("; " + femtoObs + "; Multiplicity").c_str(), kTH2F, {femtoObsAxis, multAxis}); - mHistogramRegistry->add((folderName + "/hNoMCtruthPairsCounter").c_str(), "; Counter; Entries", kTH1I, {{1, 0, 1}}); - mHistogramRegistry->add((folderName + "/hFakePairsCounter").c_str(), "; Counter; Entries", kTH1I, {{1, 0, 1}}); + mHistogramRegistry->add((folderName + "/relPairDist_ReconNoFake").c_str(), ("; " + femtoObs + "; Entries").c_str(), o2::framework::kTH1F, {femtoObsAxis}); + mHistogramRegistry->add((folderName + "/relPairkstarmT_ReconNoFake").c_str(), ("; " + femtoObs + "; #it{m}_{T} (GeV/#it{c}^{2})").c_str(), o2::framework::kTH2F, {femtoObsAxis, mTAxis}); + mHistogramRegistry->add((folderName + "/relPairkstarMult_ReconNoFake").c_str(), ("; " + femtoObs + "; Multiplicity").c_str(), o2::framework::kTH2F, {femtoObsAxis, multAxis}); + mHistogramRegistry->add((folderName + "/hNoMCtruthPairsCounter").c_str(), "; Counter; Entries", o2::framework::kTH1I, {{1, 0, 1}}); + mHistogramRegistry->add((folderName + "/hFakePairsCounter").c_str(), "; Counter; Entries", o2::framework::kTH1I, {{1, 0, 1}}); if (smearingByOrigin) { const int nOriginBins = o2::aod::femtodreamMCparticle::ParticleOriginMCTruth::kNOriginMCTruthTypes; // framework::AxisSpec mcOriginAxisPart1 = {{nOriginBins, 0, nOriginBins}, "MC origin particle 1"}; // framework::AxisSpec mcOriginAxisPart2 = {{nOriginBins, 0, nOriginBins}, "MC origin particle 2"}; - mHistogramRegistry->add((folderName + "/kstar_resolution").c_str(), "; #it{k}_{*} reconstructed (GeV/#it{c}); #it{k}_{*} truth (GeV/#it{c}); MC origin particle 1; MC origin particle 2; ", kTHnSparseF, {femtoObsAxis, femtoObsAxis, {nOriginBins, 0, nOriginBins}, {nOriginBins, 0, nOriginBins}}); + mHistogramRegistry->add((folderName + "/kstar_resolution").c_str(), "; #it{k}_{*} reconstructed (GeV/#it{c}); #it{k}_{*} truth (GeV/#it{c}); MC origin particle 1; MC origin particle 2; ", o2::framework::kTHnSparseF, {femtoObsAxis, femtoObsAxis, {nOriginBins, 0, nOriginBins}, {nOriginBins, 0, nOriginBins}}); } else { - mHistogramRegistry->add((folderName + "/kstar_resolution").c_str(), "; #it{k}_{*} reconstructed (GeV/#it{c}); #it{k}_{*} truth (GeV/#it{c})", kTH2F, {femtoObsAxis, femtoObsAxis}); + mHistogramRegistry->add((folderName + "/kstar_resolution").c_str(), "; #it{k}_{*} reconstructed (GeV/#it{c}); #it{k}_{*} truth (GeV/#it{c})", o2::framework::kTH2F, {femtoObsAxis, femtoObsAxis}); } } @@ -134,12 +133,12 @@ class FemtoDreamContainer /// \param mTBins mT binning for the histograms /// \param isMC add Monte Carlo truth histograms to the output file template - void init(HistogramRegistry* registry, + void init(o2::framework::HistogramRegistry* registry, T& kstarBins, T& pTBins, T& kTBins, T& mTBins, T& multBins, T& /*multPercentileBins*/, T& kstarBins4D, T& mTBins4D, T& multBins4D, T& multPercentileBins4D, bool isMC, bool use4dplots, bool extendedplots, float highkstarCut, - bool smearingByOrigin = false, ConfigurableAxis invMassBin = {"invMassBin", {250, 2.0, 2.5}, "InvMass binning"}) + bool smearingByOrigin = false, o2::framework::ConfigurableAxis invMassBin = {"invMassBin", {250, 2.0, 2.5}, "InvMass binning"}) { mHistogramRegistry = registry; std::string femtoObs; @@ -183,11 +182,11 @@ class FemtoDreamContainer void init_base_EP(std::string folderName, std::string femtoObs, T& femtoObsAxis, T& mTAxi4D, T& multPercentileAxis4D, T& epObsAxis, std::string epObs) { - mHistogramRegistry->add((folderName + "/relPairkstarmTMultMultPercentileQn").c_str(), ("; " + femtoObs + "; #it{m}_{T} (GeV/#it{c}); Centrality;" + epObs).c_str(), kTHnSparseF, {femtoObsAxis, mTAxi4D, multPercentileAxis4D, epObsAxis}); + mHistogramRegistry->add((folderName + "/relPairkstarmTMultMultPercentileQn").c_str(), ("; " + femtoObs + "; #it{m}_{T} (GeV/#it{c}); Centrality;" + epObs).c_str(), o2::framework::kTHnSparseF, {femtoObsAxis, mTAxi4D, multPercentileAxis4D, epObsAxis}); } template - void init_EP(HistogramRegistry* registry, + void init_EP(o2::framework::HistogramRegistry* registry, T& kstarBins4D, T& mTBins4D, T& multPercentileBins4D, T& epObsBins, std::string epObs, bool isMC, float highkstarCut) { @@ -220,29 +219,29 @@ class FemtoDreamContainer void init_base_3Dqn(std::string folderName, std::string femtoDKout, std::string femtoDKside, std::string femtoDKlong, T& femtoDKoutAxis, T& femtoDKsideAxis, T& femtoDKlongAxis, T& mTAxi4D, T& multPercentileAxis4D, T& qnAxis, T& pairPhiAxis) { - mHistogramRegistry->add((folderName + "/relPair3dRmTMultPercentileQnPairphi").c_str(), ("; " + femtoDKout + femtoDKside + femtoDKlong + "; #it{m}_{T} (GeV/#it{c}); Centrality; qn; #varphi_{pair} - #Psi_{EP}").c_str(), kTHnSparseF, {femtoDKoutAxis, femtoDKsideAxis, femtoDKlongAxis, mTAxi4D, multPercentileAxis4D, qnAxis, pairPhiAxis}); + mHistogramRegistry->add((folderName + "/relPair3dRmTMultPercentileQnPairphi").c_str(), ("; " + femtoDKout + femtoDKside + femtoDKlong + "; #it{m}_{T} (GeV/#it{c}); Centrality; qn; #varphi_{pair} - #Psi_{EP}").c_str(), o2::framework::kTHnSparseF, {femtoDKoutAxis, femtoDKsideAxis, femtoDKlongAxis, mTAxi4D, multPercentileAxis4D, qnAxis, pairPhiAxis}); } template void init_3Dqn_MC(std::string folderName, std::string femtoDKout, std::string femtoDKside, std::string femtoDKlong, T& femtoDKoutAxis, T& femtoDKsideAxis, T& femtoDKlongAxis, bool smearingByOrigin = false) { - mHistogramRegistry->add((folderName + "/hNoMCtruthPairsCounter").c_str(), "; Counter; Entries", kTH1I, {{1, 0, 1}}); - mHistogramRegistry->add((folderName + "/hFakePairsCounter").c_str(), "; Counter; Entries", kTH1I, {{1, 0, 1}}); + mHistogramRegistry->add((folderName + "/hNoMCtruthPairsCounter").c_str(), "; Counter; Entries", o2::framework::kTH1I, {{1, 0, 1}}); + mHistogramRegistry->add((folderName + "/hFakePairsCounter").c_str(), "; Counter; Entries", o2::framework::kTH1I, {{1, 0, 1}}); if (smearingByOrigin) { const int nOriginBins = o2::aod::femtodreamMCparticle::ParticleOriginMCTruth::kNOriginMCTruthTypes; mHistogramRegistry->add((folderName + "/relPair3dresolution").c_str(), (";" + femtoDKout + "mctruth;" + femtoDKout + "_reco;" + femtoDKside + "mctruth;" + femtoDKside + "_reco;" + femtoDKlong + "mctruth;" + femtoDKlong + "_reco;" + "MC origin particle 1; MC origin particle 2;").c_str(), - kTHnSparseF, {femtoDKoutAxis, femtoDKoutAxis, femtoDKsideAxis, femtoDKsideAxis, femtoDKlongAxis, femtoDKlongAxis, {nOriginBins, 0, nOriginBins}, {nOriginBins, 0, nOriginBins}}); + o2::framework::kTHnSparseF, {femtoDKoutAxis, femtoDKoutAxis, femtoDKsideAxis, femtoDKsideAxis, femtoDKlongAxis, femtoDKlongAxis, {nOriginBins, 0, nOriginBins}, {nOriginBins, 0, nOriginBins}}); } else { mHistogramRegistry->add((folderName + "/relPair3dresolution").c_str(), (";" + femtoDKout + "mctruth;" + femtoDKside + "mctruth;" + femtoDKlong + "mctruth;" + femtoDKout + "_reco;" + femtoDKside + "_reco;" + femtoDKlong + "_reco;").c_str(), - kTHnSparseF, {femtoDKoutAxis, femtoDKoutAxis, femtoDKsideAxis, femtoDKsideAxis, femtoDKlongAxis, femtoDKlongAxis}); + o2::framework::kTHnSparseF, {femtoDKoutAxis, femtoDKoutAxis, femtoDKsideAxis, femtoDKsideAxis, femtoDKlongAxis, femtoDKlongAxis}); } } template - void init_3Dqn(HistogramRegistry* registry, + void init_3Dqn(o2::framework::HistogramRegistry* registry, T& DKoutBins, T& DKsideBins, T& DKlongBins, T& mTBins4D, T& multPercentileBins4D, - bool isMC, ConfigurableAxis qnBins = {"qnBins", {10, 0, 10}, "qn binning"}, ConfigurableAxis pairPhiBins = {"phiBins", {10, 0 - 0.05, TMath::Pi() + 0.05}, "pair phi binning"}, bool smearingByOrigin = false) + bool isMC, o2::framework::ConfigurableAxis qnBins = {"qnBins", {10, 0, 10}, "qn binning"}, o2::framework::ConfigurableAxis pairPhiBins = {"phiBins", {10, 0 - 0.05, TMath::Pi() + 0.05}, "pair phi binning"}, bool smearingByOrigin = false) { mHistogramRegistry = registry; @@ -604,7 +603,7 @@ class FemtoDreamContainer } protected: - HistogramRegistry* mHistogramRegistry = nullptr; ///< For QA output + o2::framework::HistogramRegistry* mHistogramRegistry = nullptr; ///< For QA output static constexpr std::string_view mFolderSuffix[2] = {"SameEvent", "MixedEvent"}; ///< Folder naming for the output according to mEventType static constexpr femtoDreamContainer::Observable mFemtoObs = obs; ///< Femtoscopic observable to be computed (according to femtoDreamContainer::Observable) static constexpr int mEventType = eventType; ///< Type of the event (same/mixed, according to femtoDreamContainer::EventType) diff --git a/PWGCF/FemtoDream/Core/femtoDreamContainerThreeBody.h b/PWGCF/FemtoDream/Core/femtoDreamContainerThreeBody.h index a6c60793060..12fe878cc81 100644 --- a/PWGCF/FemtoDream/Core/femtoDreamContainerThreeBody.h +++ b/PWGCF/FemtoDream/Core/femtoDreamContainerThreeBody.h @@ -20,18 +20,17 @@ #ifndef PWGCF_FEMTODREAM_CORE_FEMTODREAMCONTAINERTHREEBODY_H_ #define PWGCF_FEMTODREAM_CORE_FEMTODREAMCONTAINERTHREEBODY_H_ -#include -#include -#include - -#include "Framework/HistogramRegistry.h" +#include "PWGCF/DataModel/FemtoDerived.h" #include "PWGCF/FemtoDream/Core/femtoDreamMath.h" -#include "Math/Vector4D.h" -#include "TMath.h" -#include "TDatabasePDG.h" +#include +#include -using namespace o2::framework; +#include + +#include +#include +#include namespace o2::analysis::femtoDream { @@ -72,12 +71,12 @@ class FemtoDreamContainerThreeBody void init_base(std::string folderName, std::string femtoObs, T femtoObsAxis, T multAxis) { - mHistogramRegistry->add((folderName + "/relTripletDist").c_str(), ("; " + femtoObs + "; Entries").c_str(), kTH1F, {femtoObsAxis}); - mHistogramRegistry->add((folderName + "/relTripletQ3Mult").c_str(), ("; " + femtoObs + "; Multiplicity").c_str(), kTH2F, {femtoObsAxis, multAxis}); - mHistogramRegistry->add((folderName + "/mT1").c_str(), ";mT; Q3", kTH2F, {{1000, 0, 25}, femtoObsAxis}); - mHistogramRegistry->add((folderName + "/mT2").c_str(), ";mT; Q3", kTH2F, {{1000, 0, 25}, femtoObsAxis}); - mHistogramRegistry->add((folderName + "/mT3").c_str(), ";mT; Q3", kTH2F, {{1000, 0, 25}, femtoObsAxis}); - mHistogramRegistry->add((folderName + "/mTAverage").c_str(), ";mT; Q3", kTH2F, {{1000, 0, 25}, femtoObsAxis}); + mHistogramRegistry->add((folderName + "/relTripletDist").c_str(), ("; " + femtoObs + "; Entries").c_str(), o2::framework::kTH1F, {femtoObsAxis}); + mHistogramRegistry->add((folderName + "/relTripletQ3Mult").c_str(), ("; " + femtoObs + "; Multiplicity").c_str(), o2::framework::kTH2F, {femtoObsAxis, multAxis}); + mHistogramRegistry->add((folderName + "/mT1").c_str(), ";mT; Q3", o2::framework::kTH2F, {{1000, 0, 25}, femtoObsAxis}); + mHistogramRegistry->add((folderName + "/mT2").c_str(), ";mT; Q3", o2::framework::kTH2F, {{1000, 0, 25}, femtoObsAxis}); + mHistogramRegistry->add((folderName + "/mT3").c_str(), ";mT; Q3", o2::framework::kTH2F, {{1000, 0, 25}, femtoObsAxis}); + mHistogramRegistry->add((folderName + "/mTAverage").c_str(), ";mT; Q3", o2::framework::kTH2F, {{1000, 0, 25}, femtoObsAxis}); } /// Initializes specialized Monte Carlo truth histograms for the task in case of three-body femtoscopy @@ -88,11 +87,11 @@ class FemtoDreamContainerThreeBody template void init_MC(std::string folderName, std::string femtoObs, T femtoObsAxis, T multAxis) { - mHistogramRegistry->add((folderName + "/relTripletDist_ReconNoFake").c_str(), ("; " + femtoObs + "; Entries").c_str(), kTH1F, {femtoObsAxis}); - mHistogramRegistry->add((folderName + "/relTripletQ3Mult_ReconNoFake").c_str(), ("; " + femtoObs + "; Multiplicity").c_str(), kTH2F, {femtoObsAxis, multAxis}); - mHistogramRegistry->add((folderName + "/hNoMCtruthTripletCounter").c_str(), "; Counter; Entries", kTH1I, {{1, 0, 1}}); - mHistogramRegistry->add((folderName + "/hFakeTripletCounter").c_str(), "; Counter; Entries", kTH1I, {{1, 0, 1}}); - mHistogramRegistry->add((folderName + "/Q3_resolution").c_str(), "; #it{Q}_{3} reconstructed (GeV/#it{c}); #it{Q}_{3} truth (GeV/#it{c})", kTH2F, {femtoObsAxis, femtoObsAxis}); + mHistogramRegistry->add((folderName + "/relTripletDist_ReconNoFake").c_str(), ("; " + femtoObs + "; Entries").c_str(), o2::framework::kTH1F, {femtoObsAxis}); + mHistogramRegistry->add((folderName + "/relTripletQ3Mult_ReconNoFake").c_str(), ("; " + femtoObs + "; Multiplicity").c_str(), o2::framework::kTH2F, {femtoObsAxis, multAxis}); + mHistogramRegistry->add((folderName + "/hNoMCtruthTripletCounter").c_str(), "; Counter; Entries", o2::framework::kTH1I, {{1, 0, 1}}); + mHistogramRegistry->add((folderName + "/hFakeTripletCounter").c_str(), "; Counter; Entries", o2::framework::kTH1I, {{1, 0, 1}}); + mHistogramRegistry->add((folderName + "/Q3_resolution").c_str(), "; #it{Q}_{3} reconstructed (GeV/#it{c}); #it{Q}_{3} truth (GeV/#it{c})", o2::framework::kTH2F, {femtoObsAxis, femtoObsAxis}); } /// Templated function to initialize the histograms for the task in case of three-body femtoscopy @@ -104,7 +103,7 @@ class FemtoDreamContainerThreeBody /// \param multBins multiplicity binning for the histograms /// \param isMC add Monte Carlo truth histograms to the output file template - void init(HistogramRegistry* registry, T& Q3Bins, T& multBins, bool isMC) + void init(o2::framework::HistogramRegistry* registry, T& Q3Bins, T& multBins, bool isMC) { mHistogramRegistry = registry; std::string femtoObs; @@ -220,7 +219,7 @@ class FemtoDreamContainerThreeBody } protected: - HistogramRegistry* mHistogramRegistry = nullptr; ///< For QA output + o2::framework::HistogramRegistry* mHistogramRegistry = nullptr; ///< For QA output static constexpr std::string_view mFolderSuffix[2] = {"SameEvent", "MixedEvent"}; ///< Folder naming for the output according to mEventType static constexpr femtoDreamContainerThreeBody::Observable mFemtoObs = obs; ///< Femtoscopic observable to be computed (according to femtoDreamContainerThreeBody::Observable) static constexpr int mEventType = eventType; ///< Type of the event (same/mixed, according to femtoDreamContainerThreeBody::EventType) diff --git a/PWGCF/FemtoDream/Core/femtoDreamDetaDphiStar.h b/PWGCF/FemtoDream/Core/femtoDreamDetaDphiStar.h index ee49e0155b4..84cd2671bf2 100644 --- a/PWGCF/FemtoDream/Core/femtoDreamDetaDphiStar.h +++ b/PWGCF/FemtoDream/Core/femtoDreamDetaDphiStar.h @@ -18,15 +18,23 @@ #include "PWGCF/DataModel/FemtoDerived.h" -#include "Framework/HistogramRegistry.h" - +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include #include #include +#include #include -using namespace o2; -using namespace o2::framework; - namespace o2::analysis { namespace femtoDream @@ -45,7 +53,7 @@ class FemtoDreamDetaDphiStar virtual ~FemtoDreamDetaDphiStar() = default; /// Initialization of the histograms and setting required values // atWhichRadiiToCut - at which radii apply deta dphi cut; 0 - PV; 1 - average phi at given tpc radii, 2 - at 80 cm - void init(HistogramRegistry* registry, HistogramRegistry* registryQA, float ldeltaPhiMax, float ldeltaEtaMax, bool lplotForEveryRadii, int meORse = 0, bool oldversion = true, float Q3Limit = 8., bool isMELambda = false, int atWhichRadiiToCut = 1, float radiiTPCtoCut = 85., bool fillTHSparse = false) + void init(o2::framework::HistogramRegistry* registry, o2::framework::HistogramRegistry* registryQA, float ldeltaPhiMax, float ldeltaEtaMax, bool lplotForEveryRadii, int meORse = 0, bool oldversion = true, float Q3Limit = 8., bool isMELambda = false, int atWhichRadiiToCut = 1, float radiiTPCtoCut = 85., bool fillTHSparse = false) { deltaPhiMax = ldeltaPhiMax; deltaEtaMax = ldeltaEtaMax; @@ -61,53 +69,53 @@ class FemtoDreamDetaDphiStar if constexpr (mPartOneType == o2::aod::femtodreamparticle::ParticleType::kTrack && (mPartTwoType == o2::aod::femtodreamparticle::ParticleType::kTrack || mPartTwoType == o2::aod::femtodreamparticle::ParticleType::kCascadeV0Child || mPartTwoType == o2::aod::femtodreamparticle::ParticleType::kCascadeBachelor)) { std::string dirName = static_cast(dirNames[0]); - histdetadpi[0][0] = mHistogramRegistry->add((dirName + static_cast(histNames[0][0]) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); - histdetadpi[0][1] = mHistogramRegistry->add((dirName + static_cast(histNames[1][0]) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); - histdetadpi[0][2] = mHistogramRegistry->add((dirName + "at_PV_before" + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); - histdetadpi[0][3] = mHistogramRegistry->add((dirName + "at_PV_after" + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpi[0][0] = mHistogramRegistry->add((dirName + static_cast(histNames[0][0]) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpi[0][1] = mHistogramRegistry->add((dirName + static_cast(histNames[1][0]) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpi[0][2] = mHistogramRegistry->add((dirName + "at_PV_before" + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpi[0][3] = mHistogramRegistry->add((dirName + "at_PV_after" + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); if (plotForEveryRadii) { for (int i = 0; i < 9; i++) { - histdetadpiRadii[0][i] = mHistogramRegistryQA->add((dirName + static_cast(histNamesRadii[0][i]) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpiRadii[0][i] = mHistogramRegistryQA->add((dirName + static_cast(histNamesRadii[0][i]) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); } } if (fillQA) { - histdetadpi_eta[0] = mHistogramRegistry->add((dirName + "dEtadPhi_Eta" + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}; #eta_{1}; #eta_{2}", kTHnSparseF, {{100, -0.15, 0.15}, {100, -0.15, 0.15}, {100, -0.8, 0.8}, {100, -0.8, 0.8}}); - histdetadpi_phi[0] = mHistogramRegistry->add((dirName + "dEtadPhi_Phi" + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}; #phi_{1}; #phi_{2}", kTHnSparseF, {{100, -0.15, 0.15}, {100, -0.15, 0.15}, {100, 0, 6.28}, {100, 0, 6.28}}); + histdetadpi_eta[0] = mHistogramRegistry->add((dirName + "dEtadPhi_Eta" + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}; #eta_{1}; #eta_{2}", o2::framework::kTHnSparseF, {{100, -0.15, 0.15}, {100, -0.15, 0.15}, {100, -0.8, 0.8}, {100, -0.8, 0.8}}); + histdetadpi_phi[0] = mHistogramRegistry->add((dirName + "dEtadPhi_Phi" + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}; #phi_{1}; #phi_{2}", o2::framework::kTHnSparseF, {{100, -0.15, 0.15}, {100, -0.15, 0.15}, {100, 0, 6.28}, {100, 0, 6.28}}); } } if constexpr (mPartOneType == o2::aod::femtodreamparticle::ParticleType::kTrack && mPartTwoType == o2::aod::femtodreamparticle::ParticleType::kV0) { for (int i = 0; i < 2; i++) { std::string dirName = static_cast(dirNames[1]); - histdetadpi[i][0] = mHistogramRegistry->add((dirName + static_cast(histNames[0][i]) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); - histdetadpi[i][1] = mHistogramRegistry->add((dirName + static_cast(histNames[1][i]) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); - histdetadpi[i][2] = mHistogramRegistry->add((dirName + "at_PV_" + std::to_string(i) + "_before" + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); - histdetadpi[i][3] = mHistogramRegistry->add((dirName + "at_PV_" + std::to_string(i) + "_after" + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpi[i][0] = mHistogramRegistry->add((dirName + static_cast(histNames[0][i]) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpi[i][1] = mHistogramRegistry->add((dirName + static_cast(histNames[1][i]) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpi[i][2] = mHistogramRegistry->add((dirName + "at_PV_" + std::to_string(i) + "_before" + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpi[i][3] = mHistogramRegistry->add((dirName + "at_PV_" + std::to_string(i) + "_after" + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); if (plotForEveryRadii) { for (int j = 0; j < 9; j++) { - histdetadpiRadii[i][j] = mHistogramRegistryQA->add((dirName + static_cast(histNamesRadii[i][j]) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpiRadii[i][j] = mHistogramRegistryQA->add((dirName + static_cast(histNamesRadii[i][j]) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); } } if (fillQA) { - histdetadpi_eta[i] = mHistogramRegistry->add((dirName + "dEtadPhi_Eta_" + std::to_string(i) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}; #eta_{1}; #eta_{2}", kTHnSparseF, {{100, -0.15, 0.15}, {100, -0.15, 0.15}, {100, -0.8, 0.8}, {100, -0.8, 0.8}}); - histdetadpi_phi[i] = mHistogramRegistry->add((dirName + "dEtadPhi_Phi_" + std::to_string(i) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}; #phi_{1}; #phi_{2}", kTHnSparseF, {{100, -0.15, 0.15}, {100, -0.15, 0.15}, {100, 0, 6.28}, {100, 0, 6.28}}); + histdetadpi_eta[i] = mHistogramRegistry->add((dirName + "dEtadPhi_Eta_" + std::to_string(i) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}; #eta_{1}; #eta_{2}", o2::framework::kTHnSparseF, {{100, -0.15, 0.15}, {100, -0.15, 0.15}, {100, -0.8, 0.8}, {100, -0.8, 0.8}}); + histdetadpi_phi[i] = mHistogramRegistry->add((dirName + "dEtadPhi_Phi_" + std::to_string(i) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}; #phi_{1}; #phi_{2}", o2::framework::kTHnSparseF, {{100, -0.15, 0.15}, {100, -0.15, 0.15}, {100, 0, 6.28}, {100, 0, 6.28}}); } } } if constexpr (mPartOneType == o2::aod::femtodreamparticle::ParticleType::kV0 && mPartTwoType == o2::aod::femtodreamparticle::ParticleType::kV0) { for (int i = 0; i < 4; i++) { std::string dirName = static_cast(dirNames[1]); - histdetadpi[i][0] = mHistogramRegistry->add((dirName + static_cast(histNames[0][i]) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); - histdetadpi[i][1] = mHistogramRegistry->add((dirName + static_cast(histNames[1][i]) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); - histdetadpi[i][2] = mHistogramRegistry->add((dirName + "at_PV_" + std::to_string(i) + "_before" + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); - histdetadpi[i][3] = mHistogramRegistry->add((dirName + "at_PV_" + std::to_string(i) + "_after" + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpi[i][0] = mHistogramRegistry->add((dirName + static_cast(histNames[0][i]) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpi[i][1] = mHistogramRegistry->add((dirName + static_cast(histNames[1][i]) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpi[i][2] = mHistogramRegistry->add((dirName + "at_PV_" + std::to_string(i) + "_before" + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpi[i][3] = mHistogramRegistry->add((dirName + "at_PV_" + std::to_string(i) + "_after" + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); if (plotForEveryRadii) { for (int j = 0; j < 9; j++) { - histdetadpiRadii[i][j] = mHistogramRegistryQA->add((dirName + static_cast(histNamesRadii[i][j]) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpiRadii[i][j] = mHistogramRegistryQA->add((dirName + static_cast(histNamesRadii[i][j]) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); } } if (fillQA) { - histdetadpi_eta[i] = mHistogramRegistry->add((dirName + "dEtadPhi_Eta_" + std::to_string(i) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}; #eta_{1}; #eta_{2}", kTHnSparseF, {{100, -0.15, 0.15}, {100, -0.15, 0.15}, {100, -0.8, 0.8}, {100, -0.8, 0.8}}); - histdetadpi_phi[i] = mHistogramRegistry->add((dirName + "dEtadPhi_Phi_" + std::to_string(i) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}; #phi_{1}; #phi_{2}", kTHnSparseF, {{100, -0.15, 0.15}, {100, -0.15, 0.15}, {100, 0, 6.28}, {100, 0, 6.28}}); + histdetadpi_eta[i] = mHistogramRegistry->add((dirName + "dEtadPhi_Eta_" + std::to_string(i) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}; #eta_{1}; #eta_{2}", o2::framework::kTHnSparseF, {{100, -0.15, 0.15}, {100, -0.15, 0.15}, {100, -0.8, 0.8}, {100, -0.8, 0.8}}); + histdetadpi_phi[i] = mHistogramRegistry->add((dirName + "dEtadPhi_Phi_" + std::to_string(i) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}; #phi_{1}; #phi_{2}", o2::framework::kTHnSparseF, {{100, -0.15, 0.15}, {100, -0.15, 0.15}, {100, 0, 6.28}, {100, 0, 6.28}}); } } } @@ -120,36 +128,36 @@ class FemtoDreamDetaDphiStar for (int i = 0; i < nProng; i++) { std::string dirName = static_cast(dirNames[2]); - histdetadpi[i][0] = mHistogramRegistry->add((dirName + static_cast(histNames[0][i]) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); - histdetadpi[i][1] = mHistogramRegistry->add((dirName + static_cast(histNames[1][i]) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); - histdetadpi[i][2] = mHistogramRegistry->add((dirName + "at_PV_" + std::to_string(i) + "_before" + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); - histdetadpi[i][3] = mHistogramRegistry->add((dirName + "at_PV_" + std::to_string(i) + "_after" + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpi[i][0] = mHistogramRegistry->add((dirName + static_cast(histNames[0][i]) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpi[i][1] = mHistogramRegistry->add((dirName + static_cast(histNames[1][i]) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpi[i][2] = mHistogramRegistry->add((dirName + "at_PV_" + std::to_string(i) + "_before" + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpi[i][3] = mHistogramRegistry->add((dirName + "at_PV_" + std::to_string(i) + "_after" + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); if (plotForEveryRadii) { for (int j = 0; j < 9; j++) { - histdetadpiRadii[i][j] = mHistogramRegistryQA->add((dirName + static_cast(histNamesRadii[i][j]) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpiRadii[i][j] = mHistogramRegistryQA->add((dirName + static_cast(histNamesRadii[i][j]) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); } } if (fillQA) { - histdetadpi_eta[i] = mHistogramRegistry->add((dirName + "dEtadPhi_Eta_" + std::to_string(i) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}; #eta_{1}; #eta_{2}", kTHnSparseF, {{100, -0.15, 0.15}, {100, -0.15, 0.15}, {100, -0.8, 0.8}, {100, -0.8, 0.8}}); - histdetadpi_phi[i] = mHistogramRegistry->add((dirName + "dEtadPhi_Phi_" + std::to_string(i) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}; #phi_{1}; #phi_{2}", kTHnSparseF, {{100, -0.15, 0.15}, {100, -0.15, 0.15}, {100, 0, 6.28}, {100, 0, 6.28}}); + histdetadpi_eta[i] = mHistogramRegistry->add((dirName + "dEtadPhi_Eta_" + std::to_string(i) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}; #eta_{1}; #eta_{2}", o2::framework::kTHnSparseF, {{100, -0.15, 0.15}, {100, -0.15, 0.15}, {100, -0.8, 0.8}, {100, -0.8, 0.8}}); + histdetadpi_phi[i] = mHistogramRegistry->add((dirName + "dEtadPhi_Phi_" + std::to_string(i) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}; #phi_{1}; #phi_{2}", o2::framework::kTHnSparseF, {{100, -0.15, 0.15}, {100, -0.15, 0.15}, {100, 0, 6.28}, {100, 0, 6.28}}); } } } if constexpr (mPartOneType == o2::aod::femtodreamparticle::ParticleType::kTrack && mPartTwoType == o2::aod::femtodreamparticle::ParticleType::kCascade) { for (int i = 0; i < 3; i++) { std::string dirName = static_cast(dirNames[3]); - histdetadpi[i][0] = mHistogramRegistry->add((dirName + static_cast(histNames[0][i]) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); - histdetadpi[i][1] = mHistogramRegistry->add((dirName + static_cast(histNames[1][i]) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); - histdetadpi[i][2] = mHistogramRegistry->add((dirName + "at_PV_" + std::to_string(i) + "_before" + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); - histdetadpi[i][3] = mHistogramRegistry->add((dirName + "at_PV_" + std::to_string(i) + "_after" + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpi[i][0] = mHistogramRegistry->add((dirName + static_cast(histNames[0][i]) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpi[i][1] = mHistogramRegistry->add((dirName + static_cast(histNames[1][i]) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpi[i][2] = mHistogramRegistry->add((dirName + "at_PV_" + std::to_string(i) + "_before" + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpi[i][3] = mHistogramRegistry->add((dirName + "at_PV_" + std::to_string(i) + "_after" + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); if (plotForEveryRadii) { for (int j = 0; j < 9; j++) { - histdetadpiRadii[i][j] = mHistogramRegistryQA->add((dirName + static_cast(histNamesRadii[i][j]) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpiRadii[i][j] = mHistogramRegistryQA->add((dirName + static_cast(histNamesRadii[i][j]) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); } } if (fillQA) { - histdetadpi_eta[i] = mHistogramRegistry->add((dirName + "dEtadPhi_Eta_" + std::to_string(i) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}; #eta_{1}; #eta_{2}", kTHnSparseF, {{100, -0.15, 0.15}, {100, -0.15, 0.15}, {100, -0.8, 0.8}, {100, -0.8, 0.8}}); - histdetadpi_phi[i] = mHistogramRegistry->add((dirName + "dEtadPhi_Phi_" + std::to_string(i) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}; #phi_{1}; #phi_{2}", kTHnSparseF, {{100, -0.15, 0.15}, {100, -0.15, 0.15}, {100, 0, 6.28}, {100, 0, 6.28}}); + histdetadpi_eta[i] = mHistogramRegistry->add((dirName + "dEtadPhi_Eta_" + std::to_string(i) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}; #eta_{1}; #eta_{2}", o2::framework::kTHnSparseF, {{100, -0.15, 0.15}, {100, -0.15, 0.15}, {100, -0.8, 0.8}, {100, -0.8, 0.8}}); + histdetadpi_phi[i] = mHistogramRegistry->add((dirName + "dEtadPhi_Phi_" + std::to_string(i) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}; #phi_{1}; #phi_{2}", o2::framework::kTHnSparseF, {{100, -0.15, 0.15}, {100, -0.15, 0.15}, {100, 0, 6.28}, {100, 0, 6.28}}); } } } @@ -157,18 +165,18 @@ class FemtoDreamDetaDphiStar for (int i = 0; i < 4; i++) { std::string dirName = static_cast(dirNames[4]); - histdetadpi[i][0] = mHistogramRegistry->add((dirName + static_cast(histNames[0][i]) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); - histdetadpi[i][1] = mHistogramRegistry->add((dirName + static_cast(histNames[1][i]) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); - histdetadpi[i][2] = mHistogramRegistry->add((dirName + "at_PV_" + std::to_string(i) + "_before" + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); - histdetadpi[i][3] = mHistogramRegistry->add((dirName + "at_PV_" + std::to_string(i) + "_after" + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpi[i][0] = mHistogramRegistry->add((dirName + static_cast(histNames[0][i]) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpi[i][1] = mHistogramRegistry->add((dirName + static_cast(histNames[1][i]) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpi[i][2] = mHistogramRegistry->add((dirName + "at_PV_" + std::to_string(i) + "_before" + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpi[i][3] = mHistogramRegistry->add((dirName + "at_PV_" + std::to_string(i) + "_after" + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); if (plotForEveryRadii) { for (int j = 0; j < 9; j++) { - histdetadpiRadii[i][j] = mHistogramRegistryQA->add((dirName + static_cast(histNamesRadii[i][j]) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpiRadii[i][j] = mHistogramRegistryQA->add((dirName + static_cast(histNamesRadii[i][j]) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); } } if (fillQA) { - histdetadpi_eta[i] = mHistogramRegistry->add((dirName + "dEtadPhi_Eta_" + std::to_string(i) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}; #eta_{1}; #eta_{2}", kTHnSparseF, {{100, -0.15, 0.15}, {100, -0.15, 0.15}, {100, -0.8, 0.8}, {100, -0.8, 0.8}}); - histdetadpi_phi[i] = mHistogramRegistry->add((dirName + "dEtadPhi_Phi_" + std::to_string(i) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}; #phi_{1}; #phi_{2}", kTHnSparseF, {{100, -0.15, 0.15}, {100, -0.15, 0.15}, {100, 0, 6.28}, {100, 0, 6.28}}); + histdetadpi_eta[i] = mHistogramRegistry->add((dirName + "dEtadPhi_Eta_" + std::to_string(i) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}; #eta_{1}; #eta_{2}", o2::framework::kTHnSparseF, {{100, -0.15, 0.15}, {100, -0.15, 0.15}, {100, -0.8, 0.8}, {100, -0.8, 0.8}}); + histdetadpi_phi[i] = mHistogramRegistry->add((dirName + "dEtadPhi_Phi_" + std::to_string(i) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}; #phi_{1}; #phi_{2}", o2::framework::kTHnSparseF, {{100, -0.15, 0.15}, {100, -0.15, 0.15}, {100, 0, 6.28}, {100, 0, 6.28}}); } } } @@ -738,8 +746,8 @@ class FemtoDreamDetaDphiStar } private: - HistogramRegistry* mHistogramRegistry = nullptr; ///< For main output - HistogramRegistry* mHistogramRegistryQA = nullptr; ///< For QA output + o2::framework::HistogramRegistry* mHistogramRegistry = nullptr; ///< For main output + o2::framework::HistogramRegistry* mHistogramRegistryQA = nullptr; ///< For QA output static constexpr std::string_view dirNames[5] = {"kTrack_kTrack/", "kTrack_kV0/", "kTrack_kCharmHadron/", "kTrack_kCascade/", "kV0_kReso/"}; static constexpr std::string_view histNameSEorME[3] = {"_SEandME", "_SE", "_ME"}; diff --git a/PWGCF/FemtoDream/Core/femtoDreamEventHisto.h b/PWGCF/FemtoDream/Core/femtoDreamEventHisto.h index 2d668d15c58..2c87f7eefe0 100644 --- a/PWGCF/FemtoDream/Core/femtoDreamEventHisto.h +++ b/PWGCF/FemtoDream/Core/femtoDreamEventHisto.h @@ -16,10 +16,9 @@ #ifndef PWGCF_FEMTODREAM_CORE_FEMTODREAMEVENTHISTO_H_ #define PWGCF_FEMTODREAM_CORE_FEMTODREAMEVENTHISTO_H_ -#include "PWGCF/DataModel/FemtoDerived.h" -#include "Framework/HistogramRegistry.h" +#include +#include -using namespace o2::framework; namespace o2::analysis::femtoDream { /// \class FemtoDreamEventHisto @@ -31,18 +30,18 @@ class FemtoDreamEventHisto virtual ~FemtoDreamEventHisto() = default; /// Initializes histograms for the task /// \param registry Histogram registry to be passed - void init(HistogramRegistry* registry, bool isMC = false) + void init(o2::framework::HistogramRegistry* registry, bool isMC = false) { mHistogramRegistry = registry; - mHistogramRegistry->add("Event/hZvtx", "; vtx_{z} (cm); Entries", kTH1F, {{300, -12.5, 12.5}}); - mHistogramRegistry->add("Event/hMultPercentile", "; Multiplicity Percentile (FT0M); Entries", kTH1F, {{110, 0, 110}}); - mHistogramRegistry->add("Event/hMultNTr", "; Multiplicity (MultNtr); Entries", kTH1F, {{200, 0, 200}}); - mHistogramRegistry->add("Event/hMultNTrVsZvtx", "; Multiplicity (MultNtr); vtx_{z} (cm)", kTH2F, {{200, 0, 200}, {300, -12.5, 12.5}}); - mHistogramRegistry->add("Event/hMultNTrVsMultPercentile", "; Multiplicity (MultNtr); Multiplicity Percentile (FT0M)", kTH2F, {{200, 0, 200}, {110, 0, 110}}); - mHistogramRegistry->add("Event/hMultPercentileVsZvtx", "; Multiplicity Percentile (FT0M); vtx_{z} (cm)", kTH2F, {{110, 0, 110}, {300, -12.5, 12.5}}); + mHistogramRegistry->add("Event/hZvtx", "; vtx_{z} (cm); Entries", o2::framework::kTH1F, {{300, -12.5, 12.5}}); + mHistogramRegistry->add("Event/hMultPercentile", "; Multiplicity Percentile (FT0M); Entries", o2::framework::kTH1F, {{110, 0, 110}}); + mHistogramRegistry->add("Event/hMultNTr", "; Multiplicity (MultNtr); Entries", o2::framework::kTH1F, {{200, 0, 200}}); + mHistogramRegistry->add("Event/hMultNTrVsZvtx", "; Multiplicity (MultNtr); vtx_{z} (cm)", o2::framework::kTH2F, {{200, 0, 200}, {300, -12.5, 12.5}}); + mHistogramRegistry->add("Event/hMultNTrVsMultPercentile", "; Multiplicity (MultNtr); Multiplicity Percentile (FT0M)", o2::framework::kTH2F, {{200, 0, 200}, {110, 0, 110}}); + mHistogramRegistry->add("Event/hMultPercentileVsZvtx", "; Multiplicity Percentile (FT0M); vtx_{z} (cm)", o2::framework::kTH2F, {{110, 0, 110}, {300, -12.5, 12.5}}); if (isMC) { - mHistogramRegistry->add("Event_MC/hGenMult08VsMultPercentile", "; generated MC multiplicity (#eta<0.8); Multiplicity Percentile (FT0M)", kTH2F, {{200, 0, 200}, {110, 0, 110}}); + mHistogramRegistry->add("Event_MC/hGenMult08VsMultPercentile", "; generated MC multiplicity (#eta<0.8); Multiplicity Percentile (FT0M)", o2::framework::kTH2F, {{200, 0, 200}, {110, 0, 110}}); } } @@ -69,7 +68,7 @@ class FemtoDreamEventHisto } private: - HistogramRegistry* mHistogramRegistry; ///< For QA output + o2::framework::HistogramRegistry* mHistogramRegistry; ///< For QA output }; } // namespace o2::analysis::femtoDream diff --git a/PWGCF/FemtoDream/Core/femtoDreamMath.h b/PWGCF/FemtoDream/Core/femtoDreamMath.h index cbb8257f590..2ddc7291818 100644 --- a/PWGCF/FemtoDream/Core/femtoDreamMath.h +++ b/PWGCF/FemtoDream/Core/femtoDreamMath.h @@ -16,14 +16,13 @@ #ifndef PWGCF_FEMTODREAM_CORE_FEMTODREAMMATH_H_ #define PWGCF_FEMTODREAM_CORE_FEMTODREAMMATH_H_ -#include "Math/Boost.h" -#include "Math/Vector4D.h" -#include "TLorentzVector.h" -#include "TMath.h" -#include "TVector2.h" -#include - -#include +#include +#include // IWYU pragma: keep (do not replace with Math/Vector4Dfwd.h) +#include +#include +#include + +#include #include namespace o2::analysis::femtoDream diff --git a/PWGCF/FemtoDream/Core/femtoDreamObjectSelection.h b/PWGCF/FemtoDream/Core/femtoDreamObjectSelection.h index ef77ff8a7df..e2b57d4da1d 100644 --- a/PWGCF/FemtoDream/Core/femtoDreamObjectSelection.h +++ b/PWGCF/FemtoDream/Core/femtoDreamObjectSelection.h @@ -19,16 +19,16 @@ #include "PWGCF/DataModel/FemtoDerived.h" #include "PWGCF/FemtoDream/Core/femtoDreamSelection.h" -#include "Framework/HistogramRegistry.h" -#include "ReconstructionDataFormats/PID.h" +#include +#include + +#include #include +#include #include #include -using namespace o2; -using namespace o2::framework; - namespace o2::analysis { namespace femtoDream @@ -52,7 +52,7 @@ class FemtoDreamObjectSelection void fillSelectionHistogram() { int nBins = mSelections.size(); - mQAHistogramRegistry->add((static_cast(o2::aod::femtodreamparticle::ParticleTypeName[part]) + "/cuthist").c_str(), "; Cut; Value", kTH1F, {{nBins, 0, static_cast(nBins)}}); + mQAHistogramRegistry->add((static_cast(o2::aod::femtodreamparticle::ParticleTypeName[part]) + "/cuthist").c_str(), "; Cut; Value", o2::framework::kTH1F, {{nBins, 0, static_cast(nBins)}}); auto hist = mQAHistogramRegistry->get(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/cuthist")); for (size_t i = 0; i < mSelections.size(); ++i) { hist->GetXaxis()->SetBinLabel(i + 1, Form("%u", mSelections.at(i).getSelectionVariable())); @@ -190,8 +190,8 @@ class FemtoDreamObjectSelection } protected: - HistogramRegistry* mHistogramRegistry; ///< For Analysis QA output - HistogramRegistry* mQAHistogramRegistry; ///< For QA output + o2::framework::HistogramRegistry* mHistogramRegistry; ///< For Analysis QA output + o2::framework::HistogramRegistry* mQAHistogramRegistry; ///< For QA output std::vector> mSelections; ///< Vector containing all selections }; diff --git a/PWGCF/FemtoDream/Core/femtoDreamPairCleaner.h b/PWGCF/FemtoDream/Core/femtoDreamPairCleaner.h index 0a1ae4e02a8..9e77dc5dd1a 100644 --- a/PWGCF/FemtoDream/Core/femtoDreamPairCleaner.h +++ b/PWGCF/FemtoDream/Core/femtoDreamPairCleaner.h @@ -17,9 +17,9 @@ #define PWGCF_FEMTODREAM_CORE_FEMTODREAMPAIRCLEANER_H_ #include "PWGCF/DataModel/FemtoDerived.h" -#include "Framework/HistogramRegistry.h" -using namespace o2::framework; +#include +#include namespace o2::analysis::femtoDream { @@ -36,8 +36,8 @@ class FemtoDreamPairCleaner virtual ~FemtoDreamPairCleaner() = default; /// Initialization of the QA histograms - /// \param registry HistogramRegistry - void init(HistogramRegistry* registry) + /// \param registry o2::framework::HistogramRegistry + void init(o2::framework::HistogramRegistry* registry) { if (registry) { mHistogramRegistry = registry; @@ -116,7 +116,7 @@ class FemtoDreamPairCleaner } private: - HistogramRegistry* mHistogramRegistry; ///< For QA output + o2::framework::HistogramRegistry* mHistogramRegistry; ///< For QA output static constexpr o2::aod::femtodreamparticle::ParticleType mPartOneType = partOne; ///< Type of particle 1 static constexpr o2::aod::femtodreamparticle::ParticleType mPartTwoType = partTwo; ///< Type of particle 2 }; diff --git a/PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h b/PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h index fc5d0301f96..5e05c6533e6 100644 --- a/PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h +++ b/PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h @@ -20,14 +20,17 @@ #include "PWGCF/DataModel/FemtoDerived.h" -#include "CommonConstants/PhysicsConstants.h" -#include "Framework/HistogramRegistry.h" +#include +#include +#include +#include #include +#include +#include #include - -using namespace o2::framework; +#include namespace o2::analysis::femtoDream { @@ -56,39 +59,39 @@ class FemtoDreamParticleHisto { std::string folderSuffix = static_cast(o2::aod::femtodreamMCparticle::MCTypeName[mc]).c_str(); /// Histograms of the kinematic properties - mHistogramRegistry->add((folderName + folderSuffix + "/hPt").c_str(), "; #it{p}_{T} (GeV/#it{c}); Entries", kTH1F, {{240, 0, 6}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hEta").c_str(), "; #eta; Entries", kTH1F, {{200, -1.5, 1.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hPhi").c_str(), "; #phi; Entries", kTH1F, {{200, 0, TMath::TwoPi()}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hPt").c_str(), "; #it{p}_{T} (GeV/#it{c}); Entries", o2::framework::kTH1F, {{240, 0, 6}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hEta").c_str(), "; #eta; Entries", o2::framework::kTH1F, {{200, -1.5, 1.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hPhi").c_str(), "; #phi; Entries", o2::framework::kTH1F, {{200, 0, TMath::TwoPi()}}); /// particle specific histogramms for the TempFitVar column in FemtoDreamParticles if constexpr (o2::aod::femtodreamMCparticle::MCType::kRecon == mc) { - mHistogramRegistry->add((folderName + folderSuffix + static_cast(o2::aod::femtodreamparticle::TempFitVarName[mParticleType])).c_str(), ("; #it{p}_{T} (GeV/#it{c}); " + tempFitVarAxisTitle).c_str(), kTH2F, {{pTAxis}, {tempFitVarAxis}}); + mHistogramRegistry->add((folderName + folderSuffix + static_cast(o2::aod::femtodreamparticle::TempFitVarName[mParticleType])).c_str(), ("; #it{p}_{T} (GeV/#it{c}); " + tempFitVarAxisTitle).c_str(), o2::framework::kTH2F, {{pTAxis}, {tempFitVarAxis}}); } if constexpr ((mParticleType == o2::aod::femtodreamparticle::ParticleType::kV0 || mParticleType == o2::aod::femtodreamparticle::ParticleType::kCascadeV0) && mc == o2::aod::femtodreamMCparticle::MCType::kRecon) { - mHistogramRegistry->add((folderName + folderSuffix + "/hInvMassLambda").c_str(), "; M_{#Lambda}; Entries", kTH1F, {InvMassAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hpTInvMassLambda").c_str(), "; p_{T} (GeV/#it{c{}); M_{#Lambda}", kTH2F, {pTAxis, InvMassAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hInvMassAntiLambda").c_str(), "; M_{#bar{#Lambda}}; Entries", kTH1F, {InvMassAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hpTInvMassAntiLambda").c_str(), "; M_{#bar{#Lambda}}; Entries", kTH2F, {pTAxis, InvMassAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hInvMassLambdaAntiLambda").c_str(), "; M_{#Lambda}; M_{#bar{#Lambda}}", kTH2F, {InvMassAxis, InvMassAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hInvMassLambda").c_str(), "; M_{#Lambda}; Entries", o2::framework::kTH1F, {InvMassAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hpTInvMassLambda").c_str(), "; p_{T} (GeV/#it{c{}); M_{#Lambda}", o2::framework::kTH2F, {pTAxis, InvMassAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hInvMassAntiLambda").c_str(), "; M_{#bar{#Lambda}}; Entries", o2::framework::kTH1F, {InvMassAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hpTInvMassAntiLambda").c_str(), "; M_{#bar{#Lambda}}; Entries", o2::framework::kTH2F, {pTAxis, InvMassAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hInvMassLambdaAntiLambda").c_str(), "; M_{#Lambda}; M_{#bar{#Lambda}}", o2::framework::kTH2F, {InvMassAxis, InvMassAxis}); } if constexpr (mParticleType == o2::aod::femtodreamparticle::ParticleType::kCascade && mc == o2::aod::femtodreamMCparticle::MCType::kRecon) { - mHistogramRegistry->add((folderName + folderSuffix + "/hInvMassCascade").c_str(), "; M_{Cascade}; Entries", kTH1F, {InvMassAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hpTInvMassCascade").c_str(), "; p_{T} (GeV/#it{c{}); M_{Cascade}", kTH2F, {pTAxis, InvMassAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hInvMassCascadeV0Daugh").c_str(), "; M_{Cascade}; Entries", kTH1F, {InvMassAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hpTInvMassCascadeV0Daugh").c_str(), "; p_{T} (GeV/#it{c{}); M_{Cascade}", kTH2F, {pTAxis, InvMassAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hInvMassCascade").c_str(), "; M_{Cascade}; Entries", o2::framework::kTH1F, {InvMassAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hpTInvMassCascade").c_str(), "; p_{T} (GeV/#it{c{}); M_{Cascade}", o2::framework::kTH2F, {pTAxis, InvMassAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hInvMassCascadeV0Daugh").c_str(), "; M_{Cascade}; Entries", o2::framework::kTH1F, {InvMassAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hpTInvMassCascadeV0Daugh").c_str(), "; p_{T} (GeV/#it{c{}); M_{Cascade}", o2::framework::kTH2F, {pTAxis, InvMassAxis}); } if constexpr (mParticleType == o2::aod::femtodreamparticle::ParticleType::kReso) { - mHistogramRegistry->add((folderName + folderSuffix + "/hInvMassReso").c_str(), "; M_{Reso}; Entries", kTH1F, {InvMassAxis}); // added for Phi !! - mHistogramRegistry->add((folderName + folderSuffix + "/hpTInvMassReso").c_str(), "; p_{T} (GeV/#it{c{}); M_{Reso}", kTH2F, {pTAxis, InvMassAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hInvMassAntiReso").c_str(), "; M_{Reso}; Entries", kTH1F, {InvMassAxis}); // added for Phi !! - mHistogramRegistry->add((folderName + folderSuffix + "/hpTInvMassAntiReso").c_str(), "; p_{T} (GeV/#it{c{}); M_{Reso}", kTH2F, {pTAxis, InvMassAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hInvMassReso").c_str(), "; M_{Reso}; Entries", o2::framework::kTH1F, {InvMassAxis}); // added for Phi !! + mHistogramRegistry->add((folderName + folderSuffix + "/hpTInvMassReso").c_str(), "; p_{T} (GeV/#it{c{}); M_{Reso}", o2::framework::kTH2F, {pTAxis, InvMassAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hInvMassAntiReso").c_str(), "; M_{Reso}; Entries", o2::framework::kTH1F, {InvMassAxis}); // added for Phi !! + mHistogramRegistry->add((folderName + folderSuffix + "/hpTInvMassAntiReso").c_str(), "; p_{T} (GeV/#it{c{}); M_{Reso}", o2::framework::kTH2F, {pTAxis, InvMassAxis}); } if constexpr (mParticleType == o2::aod::femtodreamparticle::ParticleType::kResoChild) { - mHistogramRegistry->add((folderName + folderSuffix + "/hInvMassReso").c_str(), "; M_{Reso}; Entries", kTH1F, {InvMassAxis}); // added for Phi !! - mHistogramRegistry->add((folderName + folderSuffix + "/hpTInvMassReso").c_str(), "; p_{T} (GeV/#it{c{}); M_{Reso}", kTH2F, {pTAxis, InvMassAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hInvMassAntiReso").c_str(), "; M_{Reso}; Entries", kTH1F, {InvMassAxis}); // added for Phi !! - mHistogramRegistry->add((folderName + folderSuffix + "/hpTInvMassAntiReso").c_str(), "; p_{T} (GeV/#it{c{}); M_{Reso}", kTH2F, {pTAxis, InvMassAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hInvMassReso").c_str(), "; M_{Reso}; Entries", o2::framework::kTH1F, {InvMassAxis}); // added for Phi !! + mHistogramRegistry->add((folderName + folderSuffix + "/hpTInvMassReso").c_str(), "; p_{T} (GeV/#it{c{}); M_{Reso}", o2::framework::kTH2F, {pTAxis, InvMassAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hInvMassAntiReso").c_str(), "; M_{Reso}; Entries", o2::framework::kTH1F, {InvMassAxis}); // added for Phi !! + mHistogramRegistry->add((folderName + folderSuffix + "/hpTInvMassAntiReso").c_str(), "; p_{T} (GeV/#it{c{}); M_{Reso}", o2::framework::kTH2F, {pTAxis, InvMassAxis}); } } @@ -99,98 +102,98 @@ class FemtoDreamParticleHisto std::string folderSuffix = static_cast(o2::aod::femtodreamMCparticle::MCTypeName[mc]).c_str(); - mHistogramRegistry->add((folderName + folderSuffix + "/hMomentumVsEta").c_str(), "; #it{p} (GeV/#it{c}); #eta", kTH2F, {{500, 0, 10}, {300, -1.5, 1.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hMomentumVsPhi").c_str(), "; #it{p} (GeV/#it{c}); #phi", kTH2F, {{500, 0, 10}, {360, 0., TMath::TwoPi()}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hEtaVsPhi").c_str(), "; #eta; #phi", kTH2F, {{300, -1.5, 1.5}, {360, 0., TMath::TwoPi()}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hMomentumVsEta").c_str(), "; #it{p} (GeV/#it{c}); #eta", o2::framework::kTH2F, {{500, 0, 10}, {300, -1.5, 1.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hMomentumVsPhi").c_str(), "; #it{p} (GeV/#it{c}); #phi", o2::framework::kTH2F, {{500, 0, 10}, {360, 0., TMath::TwoPi()}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hEtaVsPhi").c_str(), "; #eta; #phi", o2::framework::kTH2F, {{300, -1.5, 1.5}, {360, 0., TMath::TwoPi()}}); if constexpr (mParticleType == o2::aod::femtodreamparticle::ParticleType::kTrack || mParticleType == o2::aod::femtodreamparticle::ParticleType::kV0Child || mParticleType == o2::aod::femtodreamparticle::ParticleType::kCascadeV0Child || mParticleType == o2::aod::femtodreamparticle::ParticleType::kCascadeBachelor) { - mHistogramRegistry->add((folderName + folderSuffix + "/hCharge").c_str(), "; Charge; Entries", kTH1F, {{5, -2.5, 2.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hTPCfindable").c_str(), "; TPC findable clusters; Entries", kTH1F, {{163, -0.5, 162.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hTPCfound").c_str(), "; TPC found clusters; Entries", kTH1F, {{163, -0.5, 162.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hTPCcrossedOverFindable").c_str(), "; TPC ratio findable over crossed; Entries", kTH1F, {{100, 0.5, 1.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hTPCcrossedRows").c_str(), "; TPC crossed rows; Entries", kTH1F, {{163, -0.5, 162.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hTPCshared").c_str(), "; TPC shared clusters; Entries", kTH1F, {{163, -0.5, 162.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hTPCsharedOverFound").c_str(), "; TPC ratio shared over found; Entries", kTH1F, {{1000, 0, 1}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hTPCfindableVsCrossed").c_str(), ";TPC findable clusters ; TPC crossed rows;", kTH2F, {{163, -0.5, 162.5}, {163, -0.5, 162.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hTPCfoundVsShared").c_str(), ";TPC found clusters ; TPC shared clusters;", kTH2F, {{163, -0.5, 162.5}, {163, -0.5, 162.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hITSclusters").c_str(), "; ITS clusters; Entries", kTH1F, {{10, -0.5, 9.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hITSclustersIB").c_str(), "; ITS clusters in IB; Entries", kTH1F, {{10, -0.5, 9.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAz").c_str(), "; #it{p} (GeV/#it{c}); DCA_{z} (cm)", kTH2F, {pTAxis, dcazAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCA").c_str(), "; #it{p} (GeV/#it{c}); DCA (cm)", kTH2F, {pTAxis, {300, 0., 1.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hTPCdEdX").c_str(), "; #it{p} (GeV/#it{c}); TPC Signal", kTH2F, {{100, 0, 10}, {1000, 0, 1000}}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTPC_el").c_str(), "n#sigma_{TPC}^{e}", kTH2F, {pTAxis, NsigmaTPCAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTPC_pi").c_str(), "n#sigma_{TPC}^{#pi}", kTH2F, {pTAxis, NsigmaTPCAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTPC_K").c_str(), "n#sigma_{TPC}^{K}", kTH2F, {pTAxis, NsigmaTPCAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTPC_p").c_str(), "n#sigma_{TPC}^{p}", kTH2F, {pTAxis, NsigmaTPCAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTPC_d").c_str(), "n#sigma_{TPC}^{d}", kTH2F, {pTAxis, NsigmaTPCAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTPC_tr").c_str(), "n#sigma_{TPC}^{tr}", kTH2F, {pTAxis, NsigmaTPCAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTPC_he3").c_str(), "n#sigma_{TPC}^{he3}", kTH2F, {pTAxis, NsigmaTPCAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTOF_el").c_str(), "n#sigma_{TOF}^{e}", kTH2F, {pTAxis, NsigmaTOFAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTOF_pi").c_str(), "n#sigma_{TOF}^{#pi}", kTH2F, {pTAxis, NsigmaTOFAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTOF_K").c_str(), "n#sigma_{TOF}^{K}", kTH2F, {pTAxis, NsigmaTOFAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTOF_p").c_str(), "n#sigma_{TOF}^{p}", kTH2F, {pTAxis, NsigmaTOFAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTOF_d").c_str(), "n#sigma_{TOF}^{d}", kTH2F, {pTAxis, NsigmaTOFAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTOF_tr").c_str(), "n#sigma_{TOF}^{tr}", kTH2F, {pTAxis, NsigmaTOFAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTOF_he3").c_str(), "n#sigma_{TOF}^{he3}", kTH2F, {pTAxis, NsigmaTOFAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaComb_el").c_str(), "n#sigma_{comb}^{e}", kTH2F, {pTAxis, NsigmaTPCTOFAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaComb_pi").c_str(), "n#sigma_{comb}^{#pi}", kTH2F, {pTAxis, NsigmaTPCTOFAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaComb_K").c_str(), "n#sigma_{comb}^{K}", kTH2F, {pTAxis, NsigmaTPCTOFAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaComb_p").c_str(), "n#sigma_{comb}^{p}", kTH2F, {pTAxis, NsigmaTPCTOFAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaComb_d").c_str(), "n#sigma_{comb}^{d}", kTH2F, {pTAxis, NsigmaTPCTOFAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaComb_tr").c_str(), "n#sigma_{comb}^{tr}", kTH2F, {pTAxis, NsigmaTPCTOFAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaComb_he3").c_str(), "n#sigma_{comb}^{he3}", kTH2F, {pTAxis, NsigmaTPCTOFAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/ITSSignal").c_str(), "x", kTH2F, {pTAxis, NsigmaITSAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaITS_el").c_str(), "n#sigma_{ITS}^{e}", kTH2F, {pTAxis, NsigmaITSAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaITS_pi").c_str(), "n#sigma_{ITS}^{#pi}", kTH2F, {pTAxis, NsigmaITSAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaITS_K").c_str(), "n#sigma_{ITS}^{K}", kTH2F, {pTAxis, NsigmaITSAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaITS_p").c_str(), "n#sigma_{ITS}^{p}", kTH2F, {pTAxis, NsigmaITSAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaITS_d").c_str(), "n#sigma_{ITS}^{d}", kTH2F, {pTAxis, NsigmaITSAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaITS_tr").c_str(), "n#sigma_{ITS}^{tr}", kTH2F, {pTAxis, NsigmaITSAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaITS_he3").c_str(), "n#sigma_{ITS}^{he3}", kTH2F, {pTAxis, NsigmaITSAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hCharge").c_str(), "; Charge; Entries", o2::framework::kTH1F, {{5, -2.5, 2.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hTPCfindable").c_str(), "; TPC findable clusters; Entries", o2::framework::kTH1F, {{163, -0.5, 162.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hTPCfound").c_str(), "; TPC found clusters; Entries", o2::framework::kTH1F, {{163, -0.5, 162.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hTPCcrossedOverFindable").c_str(), "; TPC ratio findable over crossed; Entries", o2::framework::kTH1F, {{100, 0.5, 1.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hTPCcrossedRows").c_str(), "; TPC crossed rows; Entries", o2::framework::kTH1F, {{163, -0.5, 162.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hTPCshared").c_str(), "; TPC shared clusters; Entries", o2::framework::kTH1F, {{163, -0.5, 162.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hTPCsharedOverFound").c_str(), "; TPC ratio shared over found; Entries", o2::framework::kTH1F, {{1000, 0, 1}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hTPCfindableVsCrossed").c_str(), ";TPC findable clusters ; TPC crossed rows;", o2::framework::kTH2F, {{163, -0.5, 162.5}, {163, -0.5, 162.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hTPCfoundVsShared").c_str(), ";TPC found clusters ; TPC shared clusters;", o2::framework::kTH2F, {{163, -0.5, 162.5}, {163, -0.5, 162.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hITSclusters").c_str(), "; ITS clusters; Entries", o2::framework::kTH1F, {{10, -0.5, 9.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hITSclustersIB").c_str(), "; ITS clusters in IB; Entries", o2::framework::kTH1F, {{10, -0.5, 9.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAz").c_str(), "; #it{p} (GeV/#it{c}); DCA_{z} (cm)", o2::framework::kTH2F, {pTAxis, dcazAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCA").c_str(), "; #it{p} (GeV/#it{c}); DCA (cm)", o2::framework::kTH2F, {pTAxis, {300, 0., 1.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hTPCdEdX").c_str(), "; #it{p} (GeV/#it{c}); TPC Signal", o2::framework::kTH2F, {{100, 0, 10}, {1000, 0, 1000}}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTPC_el").c_str(), "n#sigma_{TPC}^{e}", o2::framework::kTH2F, {pTAxis, NsigmaTPCAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTPC_pi").c_str(), "n#sigma_{TPC}^{#pi}", o2::framework::kTH2F, {pTAxis, NsigmaTPCAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTPC_K").c_str(), "n#sigma_{TPC}^{K}", o2::framework::kTH2F, {pTAxis, NsigmaTPCAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTPC_p").c_str(), "n#sigma_{TPC}^{p}", o2::framework::kTH2F, {pTAxis, NsigmaTPCAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTPC_d").c_str(), "n#sigma_{TPC}^{d}", o2::framework::kTH2F, {pTAxis, NsigmaTPCAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTPC_tr").c_str(), "n#sigma_{TPC}^{tr}", o2::framework::kTH2F, {pTAxis, NsigmaTPCAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTPC_he3").c_str(), "n#sigma_{TPC}^{he3}", o2::framework::kTH2F, {pTAxis, NsigmaTPCAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTOF_el").c_str(), "n#sigma_{TOF}^{e}", o2::framework::kTH2F, {pTAxis, NsigmaTOFAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTOF_pi").c_str(), "n#sigma_{TOF}^{#pi}", o2::framework::kTH2F, {pTAxis, NsigmaTOFAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTOF_K").c_str(), "n#sigma_{TOF}^{K}", o2::framework::kTH2F, {pTAxis, NsigmaTOFAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTOF_p").c_str(), "n#sigma_{TOF}^{p}", o2::framework::kTH2F, {pTAxis, NsigmaTOFAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTOF_d").c_str(), "n#sigma_{TOF}^{d}", o2::framework::kTH2F, {pTAxis, NsigmaTOFAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTOF_tr").c_str(), "n#sigma_{TOF}^{tr}", o2::framework::kTH2F, {pTAxis, NsigmaTOFAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTOF_he3").c_str(), "n#sigma_{TOF}^{he3}", o2::framework::kTH2F, {pTAxis, NsigmaTOFAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaComb_el").c_str(), "n#sigma_{comb}^{e}", o2::framework::kTH2F, {pTAxis, NsigmaTPCTOFAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaComb_pi").c_str(), "n#sigma_{comb}^{#pi}", o2::framework::kTH2F, {pTAxis, NsigmaTPCTOFAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaComb_K").c_str(), "n#sigma_{comb}^{K}", o2::framework::kTH2F, {pTAxis, NsigmaTPCTOFAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaComb_p").c_str(), "n#sigma_{comb}^{p}", o2::framework::kTH2F, {pTAxis, NsigmaTPCTOFAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaComb_d").c_str(), "n#sigma_{comb}^{d}", o2::framework::kTH2F, {pTAxis, NsigmaTPCTOFAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaComb_tr").c_str(), "n#sigma_{comb}^{tr}", o2::framework::kTH2F, {pTAxis, NsigmaTPCTOFAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaComb_he3").c_str(), "n#sigma_{comb}^{he3}", o2::framework::kTH2F, {pTAxis, NsigmaTPCTOFAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/ITSSignal").c_str(), "x", o2::framework::kTH2F, {pTAxis, NsigmaITSAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaITS_el").c_str(), "n#sigma_{ITS}^{e}", o2::framework::kTH2F, {pTAxis, NsigmaITSAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaITS_pi").c_str(), "n#sigma_{ITS}^{#pi}", o2::framework::kTH2F, {pTAxis, NsigmaITSAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaITS_K").c_str(), "n#sigma_{ITS}^{K}", o2::framework::kTH2F, {pTAxis, NsigmaITSAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaITS_p").c_str(), "n#sigma_{ITS}^{p}", o2::framework::kTH2F, {pTAxis, NsigmaITSAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaITS_d").c_str(), "n#sigma_{ITS}^{d}", o2::framework::kTH2F, {pTAxis, NsigmaITSAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaITS_tr").c_str(), "n#sigma_{ITS}^{tr}", o2::framework::kTH2F, {pTAxis, NsigmaITSAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaITS_he3").c_str(), "n#sigma_{ITS}^{he3}", o2::framework::kTH2F, {pTAxis, NsigmaITSAxis}); if (correlatedPlots) { - mHistogramRegistry->add((folderName + folderSuffix + "/HighDcorrelator").c_str(), "", kTHnSparseF, {multAxis, multPercentileAxis, pTAxis, etaAxis, phiAxis, tempFitVarAxis, dcazAxis, NsigmaTPCAxis, NsigmaTOFAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/HighDcorrelator").c_str(), "", o2::framework::kTHnSparseF, {multAxis, multPercentileAxis, pTAxis, etaAxis, phiAxis, tempFitVarAxis, dcazAxis, NsigmaTPCAxis, NsigmaTOFAxis}); } } else if constexpr (mParticleType == o2::aod::femtodreamparticle::ParticleType::kV0) { - mHistogramRegistry->add((folderName + folderSuffix + "/hDaughDCA").c_str(), "; DCA^{daugh} (cm); Entries", kTH1F, {{1000, 0, 10}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hTransRadius").c_str(), "; #it{r}_{xy} (cm); Entries", kTH1F, {{1500, 0, 150}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDecayVtxX").c_str(), "; #it{Vtx}_{x} (cm); Entries", kTH1F, {{2000, 0, 200}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDecayVtxY").c_str(), "; #it{Vtx}_{y} (cm)); Entries", kTH1F, {{2000, 0, 200}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDecayVtxZ").c_str(), "; #it{Vtx}_{z} (cm); Entries", kTH1F, {{2000, 0, 200}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDaughDCA").c_str(), "; DCA^{daugh} (cm); Entries", o2::framework::kTH1F, {{1000, 0, 10}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hTransRadius").c_str(), "; #it{r}_{xy} (cm); Entries", o2::framework::kTH1F, {{1500, 0, 150}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDecayVtxX").c_str(), "; #it{Vtx}_{x} (cm); Entries", o2::framework::kTH1F, {{2000, 0, 200}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDecayVtxY").c_str(), "; #it{Vtx}_{y} (cm)); Entries", o2::framework::kTH1F, {{2000, 0, 200}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDecayVtxZ").c_str(), "; #it{Vtx}_{z} (cm); Entries", o2::framework::kTH1F, {{2000, 0, 200}}); } else if constexpr (mParticleType == o2::aod::femtodreamparticle::ParticleType::kCascade) { - mHistogramRegistry->add((folderName + folderSuffix + "/hCascV0DCADaugh").c_str(), "; #DCA{daugh} (cm); Entries", kTH1F, {{300, 0, 3}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hCascV0TransRadius").c_str(), "; #it{r}_{xy} (cm); Entries", kTH1F, {{1500, 0, 150}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hCascV0DCAtoPV").c_str(), "; DCA^{PV} (cm); Entries", kTH1F, {{1000, 0, 10}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hCascDaughDCA").c_str(), "; DCA^{daugh} (cm); Entries", kTH1F, {{1000, 0, 10}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hCascTransRadius").c_str(), "; #it{r}_{xy} (cm); Entries", kTH1F, {{1500, 0, 150}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hCascDecayVtxX").c_str(), "; #it{Vtx}_{x} (cm); Entries", kTH1F, {{2000, 0, 200}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hCascDecayVtxY").c_str(), "; #it{Vtx}_{y} (cm)); Entries", kTH1F, {{2000, 0, 200}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hCascDecayVtxZ").c_str(), "; #it{Vtx}_{z} (cm); Entries", kTH1F, {{2000, 0, 200}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hInvMassCompetingCascade").c_str(), "; M_{Competing Cascade}; Entries", kTH1F, {InvMassCompetingAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hpTInvMassCompetingCascade").c_str(), "; p_{T} (GeV/#it{c{}); M_{Competing Cascade}", kTH2F, {pTAxis, InvMassCompetingAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hCascV0DCADaugh").c_str(), "; #DCA{daugh} (cm); Entries", o2::framework::kTH1F, {{300, 0, 3}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hCascV0TransRadius").c_str(), "; #it{r}_{xy} (cm); Entries", o2::framework::kTH1F, {{1500, 0, 150}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hCascV0DCAtoPV").c_str(), "; DCA^{PV} (cm); Entries", o2::framework::kTH1F, {{1000, 0, 10}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hCascDaughDCA").c_str(), "; DCA^{daugh} (cm); Entries", o2::framework::kTH1F, {{1000, 0, 10}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hCascTransRadius").c_str(), "; #it{r}_{xy} (cm); Entries", o2::framework::kTH1F, {{1500, 0, 150}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hCascDecayVtxX").c_str(), "; #it{Vtx}_{x} (cm); Entries", o2::framework::kTH1F, {{2000, 0, 200}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hCascDecayVtxY").c_str(), "; #it{Vtx}_{y} (cm)); Entries", o2::framework::kTH1F, {{2000, 0, 200}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hCascDecayVtxZ").c_str(), "; #it{Vtx}_{z} (cm); Entries", o2::framework::kTH1F, {{2000, 0, 200}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hInvMassCompetingCascade").c_str(), "; M_{Competing Cascade}; Entries", o2::framework::kTH1F, {InvMassCompetingAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hpTInvMassCompetingCascade").c_str(), "; p_{T} (GeV/#it{c{}); M_{Competing Cascade}", o2::framework::kTH2F, {pTAxis, InvMassCompetingAxis}); } else if constexpr (mParticleType == o2::aod::femtodreamparticle::ParticleType::kResoChild) { - mHistogramRegistry->add((folderName + folderSuffix + "/hCharge").c_str(), "; Charge; Entries", kTH1F, {{5, -2.5, 2.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hTPCfindable").c_str(), "; TPC findable clusters; Entries", kTH1F, {{163, -0.5, 162.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hTPCfound").c_str(), "; TPC found clusters; Entries", kTH1F, {{163, -0.5, 162.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hTPCcrossedOverFindable").c_str(), "; TPC ratio findable over crossed; Entries", kTH1F, {{100, 0.5, 1.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hTPCcrossedRows").c_str(), "; TPC crossed rows; Entries", kTH1F, {{163, -0.5, 162.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hTPCshared").c_str(), "; TPC shared clusters; Entries", kTH1F, {{163, -0.5, 162.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hTPCsharedOverFound").c_str(), "; TPC ratio shared over found; Entries", kTH1F, {{1000, 0, 1}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hTPCfindableVsCrossed").c_str(), ";TPC findable clusters ; TPC crossed rows;", kTH2F, {{163, -0.5, 162.5}, {163, -0.5, 162.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hTPCfoundVsShared").c_str(), ";TPC found clusters ; TPC shared clusters;", kTH2F, {{163, -0.5, 162.5}, {163, -0.5, 162.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hITSclusters").c_str(), "; ITS clusters; Entries", kTH1F, {{10, -0.5, 9.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hITSclustersIB").c_str(), "; ITS clusters in IB; Entries", kTH1F, {{10, -0.5, 9.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAz").c_str(), "; #it{p} (GeV/#it{c}); DCA_{z} (cm)", kTH2F, {pTAxis, dcazAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCA").c_str(), "; #it{p} (GeV/#it{c}); DCA (cm)", kTH2F, {pTAxis, {300, 0., 1.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hTPCdEdX").c_str(), "; #it{p} (GeV/#it{c}); TPC Signal", kTH2F, {{100, 0, 10}, {1000, 0, 1000}}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTPC_pi").c_str(), "n#sigma_{TPC}^{#pi}", kTH2F, {pTAxis, NsigmaTPCAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTPC_K").c_str(), "n#sigma_{TPC}^{K}", kTH2F, {pTAxis, NsigmaTPCAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTOF_pi").c_str(), "n#sigma_{TOF}^{#pi}", kTH2F, {pTAxis, NsigmaTOFAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTOF_K").c_str(), "n#sigma_{TOF}^{K}", kTH2F, {pTAxis, NsigmaTOFAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaComb_pi").c_str(), "n#sigma_{comb}^{#pi}", kTH2F, {pTAxis, NsigmaTPCTOFAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaComb_K").c_str(), "n#sigma_{comb}^{K}", kTH2F, {pTAxis, NsigmaTPCTOFAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/ITSSignal").c_str(), "x", kTH2F, {pTAxis, NsigmaITSAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaITS_pi").c_str(), "n#sigma_{ITS}^{#pi}", kTH2F, {pTAxis, NsigmaITSAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaITS_K").c_str(), "n#sigma_{ITS}^{K}", kTH2F, {pTAxis, NsigmaITSAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hCharge").c_str(), "; Charge; Entries", o2::framework::kTH1F, {{5, -2.5, 2.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hTPCfindable").c_str(), "; TPC findable clusters; Entries", o2::framework::kTH1F, {{163, -0.5, 162.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hTPCfound").c_str(), "; TPC found clusters; Entries", o2::framework::kTH1F, {{163, -0.5, 162.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hTPCcrossedOverFindable").c_str(), "; TPC ratio findable over crossed; Entries", o2::framework::kTH1F, {{100, 0.5, 1.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hTPCcrossedRows").c_str(), "; TPC crossed rows; Entries", o2::framework::kTH1F, {{163, -0.5, 162.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hTPCshared").c_str(), "; TPC shared clusters; Entries", o2::framework::kTH1F, {{163, -0.5, 162.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hTPCsharedOverFound").c_str(), "; TPC ratio shared over found; Entries", o2::framework::kTH1F, {{1000, 0, 1}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hTPCfindableVsCrossed").c_str(), ";TPC findable clusters ; TPC crossed rows;", o2::framework::kTH2F, {{163, -0.5, 162.5}, {163, -0.5, 162.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hTPCfoundVsShared").c_str(), ";TPC found clusters ; TPC shared clusters;", o2::framework::kTH2F, {{163, -0.5, 162.5}, {163, -0.5, 162.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hITSclusters").c_str(), "; ITS clusters; Entries", o2::framework::kTH1F, {{10, -0.5, 9.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hITSclustersIB").c_str(), "; ITS clusters in IB; Entries", o2::framework::kTH1F, {{10, -0.5, 9.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAz").c_str(), "; #it{p} (GeV/#it{c}); DCA_{z} (cm)", o2::framework::kTH2F, {pTAxis, dcazAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCA").c_str(), "; #it{p} (GeV/#it{c}); DCA (cm)", o2::framework::kTH2F, {pTAxis, {300, 0., 1.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hTPCdEdX").c_str(), "; #it{p} (GeV/#it{c}); TPC Signal", o2::framework::kTH2F, {{100, 0, 10}, {1000, 0, 1000}}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTPC_pi").c_str(), "n#sigma_{TPC}^{#pi}", o2::framework::kTH2F, {pTAxis, NsigmaTPCAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTPC_K").c_str(), "n#sigma_{TPC}^{K}", o2::framework::kTH2F, {pTAxis, NsigmaTPCAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTOF_pi").c_str(), "n#sigma_{TOF}^{#pi}", o2::framework::kTH2F, {pTAxis, NsigmaTOFAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTOF_K").c_str(), "n#sigma_{TOF}^{K}", o2::framework::kTH2F, {pTAxis, NsigmaTOFAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaComb_pi").c_str(), "n#sigma_{comb}^{#pi}", o2::framework::kTH2F, {pTAxis, NsigmaTPCTOFAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaComb_K").c_str(), "n#sigma_{comb}^{K}", o2::framework::kTH2F, {pTAxis, NsigmaTPCTOFAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/ITSSignal").c_str(), "x", o2::framework::kTH2F, {pTAxis, NsigmaITSAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaITS_pi").c_str(), "n#sigma_{ITS}^{#pi}", o2::framework::kTH2F, {pTAxis, NsigmaITSAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaITS_K").c_str(), "n#sigma_{ITS}^{K}", o2::framework::kTH2F, {pTAxis, NsigmaITSAxis}); } } @@ -207,81 +210,81 @@ class FemtoDreamParticleHisto /// Particle-type specific histograms std::string folderSuffix = static_cast(o2::aod::femtodreamMCparticle::MCTypeName[o2::aod::femtodreamMCparticle::MCType::kTruth]).c_str(); - mHistogramRegistry->add((folderName + folderSuffix + "/hPt_ReconNoFake").c_str(), "; #it{p}_{T} (GeV/#it{c}); Entries", kTH1F, {{240, 0, 6}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hPDG").c_str(), "; PDG; Entries", kTH1I, {{6001, -3000.5, 3000.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hOrigin_MC").c_str(), "; Origin; Entries", kTH1I, {{7, -0.5, 6.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hNoMCtruthCounter").c_str(), "; Counter; Entries", kTH1I, {{1, -0.5, 0.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hPt_DiffTruthReco").c_str(), "; p^{truth}_{T}; (p^{reco}_{T} - p^{truth}_{T}) / p^{truth}_{T}", kTH2F, {tempFitVarpTAxis, {200, -1, 1}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hEta_DiffTruthReco").c_str(), "; #eta^{truth}; #eta^{reco} - #eta^{truth}", kTH2F, {{200, -1, 1}, {200, -1, 1}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hPhi_DiffTruthReco").c_str(), "; #varphi^{truth}; #varphi^{reco} - #varphi^{truth}", kTH2F, {{720, 0, TMath::TwoPi()}, {200, -1, 1}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hPt_ReconNoFake").c_str(), "; #it{p}_{T} (GeV/#it{c}); Entries", o2::framework::kTH1F, {{240, 0, 6}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hPDG").c_str(), "; PDG; Entries", o2::framework::kTH1I, {{6001, -3000.5, 3000.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hOrigin_MC").c_str(), "; Origin; Entries", o2::framework::kTH1I, {{7, -0.5, 6.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hNoMCtruthCounter").c_str(), "; Counter; Entries", o2::framework::kTH1I, {{1, -0.5, 0.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hPt_DiffTruthReco").c_str(), "; p^{truth}_{T}; (p^{reco}_{T} - p^{truth}_{T}) / p^{truth}_{T}", o2::framework::kTH2F, {tempFitVarpTAxis, {200, -1, 1}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hEta_DiffTruthReco").c_str(), "; #eta^{truth}; #eta^{reco} - #eta^{truth}", o2::framework::kTH2F, {{200, -1, 1}, {200, -1, 1}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hPhi_DiffTruthReco").c_str(), "; #varphi^{truth}; #varphi^{reco} - #varphi^{truth}", o2::framework::kTH2F, {{720, 0, TMath::TwoPi()}, {200, -1, 1}}); if constexpr (mParticleType == o2::aod::femtodreamparticle::ParticleType::kTrack || mParticleType == o2::aod::femtodreamparticle::ParticleType::kV0Child || mParticleType == o2::aod::femtodreamparticle::ParticleType::kCascadeV0Child || mParticleType == o2::aod::femtodreamparticle::ParticleType::kCascadeBachelor) { /// Track histograms if (isDebug) { - mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_Primary").c_str(), "; PDG mother; Entries", kTH1I, {{6001, -3000.5, 3000.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_Secondary").c_str(), "; PDG mother; Entries", kTH1I, {{6001, -3000.5, 3000.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_Material").c_str(), "; PDG mother; Entries", kTH1I, {{6001, -3000.5, 3000.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_WrongCollision").c_str(), "; PDG mother; Entries", kTH1I, {{6001, -3000.5, 3000.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_Fake").c_str(), "; PDG mother; Entries", kTH1I, {{6001, -3000.5, 3000.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_Else").c_str(), "; PDG mother; Entries", kTH1I, {{6001, -3000.5, 3000.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_SecondaryDaughterLambda").c_str(), "; PDG mother; Entries", kTH1I, {{12001, -6000.5, 6000.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_SecondaryDaughterSigmaplus").c_str(), "; PDG mother; Entries", kTH1I, {{12001, -6000.5, 6000.5}}); - - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Primary").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Secondary").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Material").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_WrongCollision").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Fake").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterLambda").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterSigmaplus").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Else").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_Primary").c_str(), "; PDG mother; Entries", o2::framework::kTH1I, {{6001, -3000.5, 3000.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_Secondary").c_str(), "; PDG mother; Entries", o2::framework::kTH1I, {{6001, -3000.5, 3000.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_Material").c_str(), "; PDG mother; Entries", o2::framework::kTH1I, {{6001, -3000.5, 3000.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_WrongCollision").c_str(), "; PDG mother; Entries", o2::framework::kTH1I, {{6001, -3000.5, 3000.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_Fake").c_str(), "; PDG mother; Entries", o2::framework::kTH1I, {{6001, -3000.5, 3000.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_Else").c_str(), "; PDG mother; Entries", o2::framework::kTH1I, {{6001, -3000.5, 3000.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_SecondaryDaughterLambda").c_str(), "; PDG mother; Entries", o2::framework::kTH1I, {{12001, -6000.5, 6000.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_SecondaryDaughterSigmaplus").c_str(), "; PDG mother; Entries", o2::framework::kTH1I, {{12001, -6000.5, 6000.5}}); + + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Primary").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Secondary").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Material").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_WrongCollision").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Fake").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterLambda").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterSigmaplus").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Else").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); } else { - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Primary").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Secondary").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Material").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_WrongCollision").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Fake").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterLambda").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterSigmaplus").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Else").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Primary").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Secondary").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Material").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_WrongCollision").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Fake").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterLambda").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterSigmaplus").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Else").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); } // DCA plots } else if constexpr (mParticleType == o2::aod::femtodreamparticle::ParticleType::kV0 || mParticleType == o2::aod::femtodreamparticle::ParticleType::kCascadeV0) { if (isDebug) { - mHistogramRegistry->add((folderName + folderSuffix + "/hCPA_Primary").c_str(), "; #it{p}_{T} (GeV/#it{c}); CPA", kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, multAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hCPA_Secondary").c_str(), "; #it{p}_{T} (GeV/#it{c}); CPA", kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, multAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hCPA_Material").c_str(), "; #it{p}_{T} (GeV/#it{c}); CPA", kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, multAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hCPA_WrongCollision").c_str(), "; #it{p}_{T} (GeV/#it{c}); CPA", kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, multAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hCPA_Fake").c_str(), "; #it{p}_{T} (GeV/#it{c}); CPA", kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, multAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hCPA_Else").c_str(), "; #it{p}_{T} (GeV/#it{c}); CPA", kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, multAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hCPA_Secondary_SIGMA0").c_str(), "; #it{p}_{T} (GeV/#it{c}); CPA", kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, multAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hCPA_Secondary_XIMinus").c_str(), "; #it{p}_{T} (GeV/#it{c}); CPA", kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, multAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hCPA_Secondary_XI0").c_str(), "; #it{p}_{T} (GeV/#it{c}); CPA", kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, multAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hCPA_Primary").c_str(), "; #it{p}_{T} (GeV/#it{c}); CPA", o2::framework::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, multAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hCPA_Secondary").c_str(), "; #it{p}_{T} (GeV/#it{c}); CPA", o2::framework::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, multAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hCPA_Material").c_str(), "; #it{p}_{T} (GeV/#it{c}); CPA", o2::framework::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, multAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hCPA_WrongCollision").c_str(), "; #it{p}_{T} (GeV/#it{c}); CPA", o2::framework::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, multAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hCPA_Fake").c_str(), "; #it{p}_{T} (GeV/#it{c}); CPA", o2::framework::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, multAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hCPA_Else").c_str(), "; #it{p}_{T} (GeV/#it{c}); CPA", o2::framework::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, multAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hCPA_Secondary_SIGMA0").c_str(), "; #it{p}_{T} (GeV/#it{c}); CPA", o2::framework::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, multAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hCPA_Secondary_XIMinus").c_str(), "; #it{p}_{T} (GeV/#it{c}); CPA", o2::framework::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, multAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hCPA_Secondary_XI0").c_str(), "; #it{p}_{T} (GeV/#it{c}); CPA", o2::framework::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, multAxis}); } else { - mHistogramRegistry->add((folderName + folderSuffix + "/hCPA_Primary").c_str(), "; #it{p}_{T} (GeV/#it{c}); CPA", kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hCPA_Secondary").c_str(), "; #it{p}_{T} (GeV/#it{c}); CPA", kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hCPA_Material").c_str(), "; #it{p}_{T} (GeV/#it{c}); CPA", kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hCPA_WrongCollision").c_str(), "; #it{p}_{T} (GeV/#it{c}); CPA", kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hCPA_Fake").c_str(), "; #it{p}_{T} (GeV/#it{c}); CPA", kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hCPA_Else").c_str(), "; #it{p}_{T} (GeV/#it{c}); CPA", kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hCPA_Secondary_SIGMA0").c_str(), "; #it{p}_{T} (GeV/#it{c}); CPA", kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hCPA_Secondary_XIMinus").c_str(), "; #it{p}_{T} (GeV/#it{c}); CPA", kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hCPA_Secondary_XI0").c_str(), "; #it{p}_{T} (GeV/#it{c}); CPA", kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hCPA_Primary").c_str(), "; #it{p}_{T} (GeV/#it{c}); CPA", o2::framework::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hCPA_Secondary").c_str(), "; #it{p}_{T} (GeV/#it{c}); CPA", o2::framework::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hCPA_Material").c_str(), "; #it{p}_{T} (GeV/#it{c}); CPA", o2::framework::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hCPA_WrongCollision").c_str(), "; #it{p}_{T} (GeV/#it{c}); CPA", o2::framework::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hCPA_Fake").c_str(), "; #it{p}_{T} (GeV/#it{c}); CPA", o2::framework::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hCPA_Else").c_str(), "; #it{p}_{T} (GeV/#it{c}); CPA", o2::framework::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hCPA_Secondary_SIGMA0").c_str(), "; #it{p}_{T} (GeV/#it{c}); CPA", o2::framework::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hCPA_Secondary_XIMinus").c_str(), "; #it{p}_{T} (GeV/#it{c}); CPA", o2::framework::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hCPA_Secondary_XI0").c_str(), "; #it{p}_{T} (GeV/#it{c}); CPA", o2::framework::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); } /// V0 histograms /// to be implemented } else if constexpr (mParticleType == o2::aod::femtodreamparticle::ParticleType::kCascade) { /// Cascade histograms - mHistogramRegistry->add((folderName + folderSuffix + "/hCPA_Primary").c_str(), "; #it{p}_{T} (GeV/#it{c}); CPA", kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hCPA_Secondary").c_str(), "; #it{p}_{T} (GeV/#it{c}); CPA", kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hCPA_Material").c_str(), "; #it{p}_{T} (GeV/#it{c}); CPA", kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hCPA_WrongCollision").c_str(), "; #it{p}_{T} (GeV/#it{c}); CPA", kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hCPA_Fake").c_str(), "; #it{p}_{T} (GeV/#it{c}); CPA", kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hCPA_Else").c_str(), "; #it{p}_{T} (GeV/#it{c}); CPA", kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hCPA_Secondary_OMEGAMinus").c_str(), "; #it{p}_{T} (GeV/#it{c}); CPA", kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hCPA_Secondary_XIStar0").c_str(), "; #it{p}_{T} (GeV/#it{c}); CPA", kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hCPA_Secondary_XIStarMinus").c_str(), "; #it{p}_{T} (GeV/#it{c}); CPA", kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hCPA_Primary").c_str(), "; #it{p}_{T} (GeV/#it{c}); CPA", o2::framework::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hCPA_Secondary").c_str(), "; #it{p}_{T} (GeV/#it{c}); CPA", o2::framework::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hCPA_Material").c_str(), "; #it{p}_{T} (GeV/#it{c}); CPA", o2::framework::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hCPA_WrongCollision").c_str(), "; #it{p}_{T} (GeV/#it{c}); CPA", o2::framework::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hCPA_Fake").c_str(), "; #it{p}_{T} (GeV/#it{c}); CPA", o2::framework::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hCPA_Else").c_str(), "; #it{p}_{T} (GeV/#it{c}); CPA", o2::framework::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hCPA_Secondary_OMEGAMinus").c_str(), "; #it{p}_{T} (GeV/#it{c}); CPA", o2::framework::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hCPA_Secondary_XIStar0").c_str(), "; #it{p}_{T} (GeV/#it{c}); CPA", o2::framework::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hCPA_Secondary_XIStarMinus").c_str(), "; #it{p}_{T} (GeV/#it{c}); CPA", o2::framework::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); } else { LOG(fatal) << "FemtoDreamParticleHisto: Histogramming for requested object not defined - quitting!"; } @@ -296,7 +299,7 @@ class FemtoDreamParticleHisto /// \param tempFitVarBins binning of the tempFitVar (DCA_xy in case of tracks, CPA in case of V0s, etc.) /// \param isMC add Monte Carlo truth histograms to the output file template - void init(HistogramRegistry* registry, T& MultBins, T& PercentileBins, T& pTBins, T& etaBins, T& phiBins, T& tempFitVarBins, T& NsigmaTPCBins, T& NsigmaTOFBins, T& NsigmaTPCTOFBins, T& NsigmaITSBins, T& InvMassBins, T& InvMassCompetingBins, bool isMC, int pdgCode, bool isDebug = false, bool correlatedPlots = false) + void init(o2::framework::HistogramRegistry* registry, T& MultBins, T& PercentileBins, T& pTBins, T& etaBins, T& phiBins, T& tempFitVarBins, T& NsigmaTPCBins, T& NsigmaTOFBins, T& NsigmaTPCTOFBins, T& NsigmaITSBins, T& InvMassBins, T& InvMassCompetingBins, bool isMC, int pdgCode, bool isDebug = false, bool correlatedPlots = false) { mPDG = pdgCode; if (registry) { @@ -819,7 +822,7 @@ class FemtoDreamParticleHisto } private: - HistogramRegistry* mHistogramRegistry; ///< For QA output + o2::framework::HistogramRegistry* mHistogramRegistry; ///< For QA output static constexpr o2::aod::femtodreamparticle::ParticleType mParticleType = particleType; ///< Type of the particle under analysis static constexpr int mFolderSuffixType = suffixType; ///< Counter for the folder suffix specified below static constexpr std::string_view mFolderSuffix[12] = {"", "_one", "_two", "_pos", "_neg", diff --git a/PWGCF/FemtoDream/Core/femtoDreamResoSelection.h b/PWGCF/FemtoDream/Core/femtoDreamResoSelection.h index f61786deb88..b8b9fc64484 100644 --- a/PWGCF/FemtoDream/Core/femtoDreamResoSelection.h +++ b/PWGCF/FemtoDream/Core/femtoDreamResoSelection.h @@ -22,17 +22,21 @@ #include "PWGCF/FemtoDream/Core/femtoDreamSelection.h" #include "PWGCF/FemtoDream/Core/femtoDreamTrackSelection.h" -#include "Common/Core/RecoDecay.h" +#include +#include +#include +#include +#include -#include "Framework/HistogramRegistry.h" -#include "ReconstructionDataFormats/PID.h" - -#include "Math/Vector4D.h" -#include "TMath.h" +#include // IWYU pragma: keep (do not replace with Math/Vector4Dfwd.h) +#include #include -#include +#include +#include +#include #include +#include #include #include @@ -78,7 +82,7 @@ class FemtoDreamResoSelection size_t numBitsUsed(V const& origvalue); template - void init(HistogramRegistry* QAregistry, HistogramRegistry* Registry); + void init(o2::framework::HistogramRegistry* QAregistry, o2::framework::HistogramRegistry* Registry); template -void FemtoDreamResoSelection::init(HistogramRegistry* QAregistry, HistogramRegistry* Registry) +void FemtoDreamResoSelection::init(o2::framework::HistogramRegistry* QAregistry, o2::framework::HistogramRegistry* Registry) { if (QAregistry && Registry) { mHistogramRegistry = Registry; @@ -283,9 +287,9 @@ void FemtoDreamResoSelection::init(HistogramRegistry* QAregistry, HistogramRegis fillSelectionHistogram(); fillSelectionHistogram(); - AxisSpec massAxisReso = {3000, 0.0f, 3.0f, "m_{#Reso} (GeV/#it{c}^{2})"}; - AxisSpec massAxisAntiReso = {3000, 0.0f, 3.0f, - "m_{#bar{#Reso}} (GeV/#it{c}^{2})"}; + o2::framework::AxisSpec massAxisReso = {3000, 0.0f, 3.0f, "m_{#Reso} (GeV/#it{c}^{2})"}; + o2::framework::AxisSpec massAxisAntiReso = {3000, 0.0f, 3.0f, + "m_{#bar{#Reso}} (GeV/#it{c}^{2})"}; // initialize Histograms std::string folderName = static_cast( @@ -293,61 +297,61 @@ void FemtoDreamResoSelection::init(HistogramRegistry* QAregistry, HistogramRegis /* int cutBits = 8 * sizeof(o2::aod::femtodreamparticle::cutContainerType); - mQAHistogramRegistry->add((folderName + "/CutCounter"), "; Bit; Counter", kTH1F, {{cutBits + 1, -0.5, cutBits + 0.5}}); + mQAHistogramRegistry->add((folderName + "/CutCounter"), "; Bit; Counter", o2::framework::kTH1F, {{cutBits + 1, -0.5, cutBits + 0.5}}); */ // mass histos - mQAHistogramRegistry->add((folderName + "/InvMass"), "Invariant mass V0s;M_{KK};Entries", HistType::kTH1F, {massAxisReso}); - mQAHistogramRegistry->add((folderName + "/InvMassAnti"), "Invariant mass V0s;M_{KK};Entries", HistType::kTH1F, {massAxisReso}); - mQAHistogramRegistry->add((folderName + "/InvMass_phi_selected"), "Invariant mass V0s;M_{KK};Entries", HistType::kTH1F, {massAxisReso}); - mQAHistogramRegistry->add((folderName + "/InvMassAnti_phi_selected"), "Invariant mass V0s;M_{KK};Entries", HistType::kTH1F, {massAxisReso}); + mQAHistogramRegistry->add((folderName + "/InvMass"), "Invariant mass V0s;M_{KK};Entries", o2::framework::HistType::kTH1F, {massAxisReso}); + mQAHistogramRegistry->add((folderName + "/InvMassAnti"), "Invariant mass V0s;M_{KK};Entries", o2::framework::HistType::kTH1F, {massAxisReso}); + mQAHistogramRegistry->add((folderName + "/InvMass_phi_selected"), "Invariant mass V0s;M_{KK};Entries", o2::framework::HistType::kTH1F, {massAxisReso}); + mQAHistogramRegistry->add((folderName + "/InvMassAnti_phi_selected"), "Invariant mass V0s;M_{KK};Entries", o2::framework::HistType::kTH1F, {massAxisReso}); // ResoQA // Histos for PosDaughter - mQAHistogramRegistry->add((folderName + "/ResoQA/PosDaughter/Pt"), "Transverse momentum of all tracks;p_{T} (GeV/c);Entries", HistType::kTH1F, {{1000, 0, 10}}); - mQAHistogramRegistry->add((folderName + "/ResoQA/PosDaughter/Eta"), "Pseudorapidity of all tracks;#eta;Entries", HistType::kTH1F, {{1000, -2, 2}}); - mQAHistogramRegistry->add((folderName + "/ResoQA/PosDaughter/Phi"), "Azimuthal angle of all tracks;#phi;Entries", HistType::kTH1F, {{720, 0, o2::constants::math::TwoPI}}); - mQAHistogramRegistry->add((folderName + "/ResoQA/PosDaughter/DcaXY"), "dcaXY of all tracks;d_{XY} (cm);Entries", HistType::kTH1F, {{1000, 0, 1}}); // check if cm is correct here - mQAHistogramRegistry->add((folderName + "/ResoQA/PosDaughter/DcaZ"), "dcaZ of all tracks;d_{Z} (cm);Entries", HistType::kTH1F, {{1000, 0, 1}}); // check if cm is correct here + mQAHistogramRegistry->add((folderName + "/ResoQA/PosDaughter/Pt"), "Transverse momentum of all tracks;p_{T} (GeV/c);Entries", o2::framework::HistType::kTH1F, {{1000, 0, 10}}); + mQAHistogramRegistry->add((folderName + "/ResoQA/PosDaughter/Eta"), "Pseudorapidity of all tracks;#eta;Entries", o2::framework::HistType::kTH1F, {{1000, -2, 2}}); + mQAHistogramRegistry->add((folderName + "/ResoQA/PosDaughter/Phi"), "Azimuthal angle of all tracks;#phi;Entries", o2::framework::HistType::kTH1F, {{720, 0, o2::constants::math::TwoPI}}); + mQAHistogramRegistry->add((folderName + "/ResoQA/PosDaughter/DcaXY"), "dcaXY of all tracks;d_{XY} (cm);Entries", o2::framework::HistType::kTH1F, {{1000, 0, 1}}); // check if cm is correct here + mQAHistogramRegistry->add((folderName + "/ResoQA/PosDaughter/DcaZ"), "dcaZ of all tracks;d_{Z} (cm);Entries", o2::framework::HistType::kTH1F, {{1000, 0, 1}}); // check if cm is correct here // Histos for NegDaughter - mQAHistogramRegistry->add((folderName + "/ResoQA/NegDaughter/Pt"), "Transverse momentum of all tracks;p_{T} (GeV/c);Entries", HistType::kTH1F, {{1000, 0, 10}}); - mQAHistogramRegistry->add((folderName + "/ResoQA/NegDaughter/Eta"), "Pseudorapidity of all tracks;#eta;Entries", HistType::kTH1F, {{1000, -2, 2}}); - mQAHistogramRegistry->add((folderName + "/ResoQA/NegDaughter/Phi"), "Azimuthal angle of all tracks;#phi;Entries", HistType::kTH1F, {{720, 0, o2::constants::math::TwoPI}}); - mQAHistogramRegistry->add((folderName + "/ResoQA/NegDaughter/DcaXY"), "dcaXY of all tracks;d_{XY} (cm);Entries", HistType::kTH1F, {{1000, 0, 1}}); // check if cm is correct here - mQAHistogramRegistry->add((folderName + "/ResoQA/NegDaughter/DcaZ"), "dcaZ of all tracks;d_{Z} (cm);Entries", HistType::kTH1F, {{1000, 0, 1}}); // check if cm is correct here + mQAHistogramRegistry->add((folderName + "/ResoQA/NegDaughter/Pt"), "Transverse momentum of all tracks;p_{T} (GeV/c);Entries", o2::framework::HistType::kTH1F, {{1000, 0, 10}}); + mQAHistogramRegistry->add((folderName + "/ResoQA/NegDaughter/Eta"), "Pseudorapidity of all tracks;#eta;Entries", o2::framework::HistType::kTH1F, {{1000, -2, 2}}); + mQAHistogramRegistry->add((folderName + "/ResoQA/NegDaughter/Phi"), "Azimuthal angle of all tracks;#phi;Entries", o2::framework::HistType::kTH1F, {{720, 0, o2::constants::math::TwoPI}}); + mQAHistogramRegistry->add((folderName + "/ResoQA/NegDaughter/DcaXY"), "dcaXY of all tracks;d_{XY} (cm);Entries", o2::framework::HistType::kTH1F, {{1000, 0, 1}}); // check if cm is correct here + mQAHistogramRegistry->add((folderName + "/ResoQA/NegDaughter/DcaZ"), "dcaZ of all tracks;d_{Z} (cm);Entries", o2::framework::HistType::kTH1F, {{1000, 0, 1}}); // check if cm is correct here // Histos for massQA - mQAHistogramRegistry->add((folderName + "/ResoQA/InvMassSwitched"), "Invariant mass V0s;M_{KK};Entries", HistType::kTH1F, {massAxisReso}); // for opposite mass hypothesis (Reso is anti) - mQAHistogramRegistry->add((folderName + "/ResoQA/InvMassBothPID1"), "Invariant mass V0s;M_{KK};Entries", HistType::kTH1F, {massAxisReso}); // both particles are of type confDaughterPIDspecies[0] - mQAHistogramRegistry->add((folderName + "/ResoQA/InvMassBothPID2"), "Invariant mass V0s;M_{KK};Entries", HistType::kTH1F, {massAxisReso}); // both particles are of type confDaughterPIDspecies[1] + mQAHistogramRegistry->add((folderName + "/ResoQA/InvMassSwitched"), "Invariant mass V0s;M_{KK};Entries", o2::framework::HistType::kTH1F, {massAxisReso}); // for opposite mass hypothesis (Reso is anti) + mQAHistogramRegistry->add((folderName + "/ResoQA/InvMassBothPID1"), "Invariant mass V0s;M_{KK};Entries", o2::framework::HistType::kTH1F, {massAxisReso}); // both particles are of type confDaughterPIDspecies[0] + mQAHistogramRegistry->add((folderName + "/ResoQA/InvMassBothPID2"), "Invariant mass V0s;M_{KK};Entries", o2::framework::HistType::kTH1F, {massAxisReso}); // both particles are of type confDaughterPIDspecies[1] // AntiResoQA // Histos for PosDaughter - mQAHistogramRegistry->add((folderName + "/AntiResoQA/PosDaughter/Pt"), "Transverse momentum of all tracks;p_{T} (GeV/c);Entries", HistType::kTH1F, {{1000, 0, 10}}); - mQAHistogramRegistry->add((folderName + "/AntiResoQA/PosDaughter/Eta"), "Pseudorapidity of all tracks;#eta;Entries", HistType::kTH1F, {{1000, -2, 2}}); - mQAHistogramRegistry->add((folderName + "/AntiResoQA/PosDaughter/Phi"), "Azimuthal angle of all tracks;#phi;Entries", HistType::kTH1F, {{720, 0, o2::constants::math::TwoPI}}); - mQAHistogramRegistry->add((folderName + "/AntiResoQA/PosDaughter/DcaXY"), "dcaXY of all tracks;d_{XY} (cm);Entries", HistType::kTH1F, {{1000, 0, 1}}); // check if cm is correct here - mQAHistogramRegistry->add((folderName + "/AntiResoQA/PosDaughter/DcaZ"), "dcaZ of all tracks;d_{Z} (cm);Entries", HistType::kTH1F, {{1000, 0, 1}}); // check if cm is correct here + mQAHistogramRegistry->add((folderName + "/AntiResoQA/PosDaughter/Pt"), "Transverse momentum of all tracks;p_{T} (GeV/c);Entries", o2::framework::HistType::kTH1F, {{1000, 0, 10}}); + mQAHistogramRegistry->add((folderName + "/AntiResoQA/PosDaughter/Eta"), "Pseudorapidity of all tracks;#eta;Entries", o2::framework::HistType::kTH1F, {{1000, -2, 2}}); + mQAHistogramRegistry->add((folderName + "/AntiResoQA/PosDaughter/Phi"), "Azimuthal angle of all tracks;#phi;Entries", o2::framework::HistType::kTH1F, {{720, 0, o2::constants::math::TwoPI}}); + mQAHistogramRegistry->add((folderName + "/AntiResoQA/PosDaughter/DcaXY"), "dcaXY of all tracks;d_{XY} (cm);Entries", o2::framework::HistType::kTH1F, {{1000, 0, 1}}); // check if cm is correct here + mQAHistogramRegistry->add((folderName + "/AntiResoQA/PosDaughter/DcaZ"), "dcaZ of all tracks;d_{Z} (cm);Entries", o2::framework::HistType::kTH1F, {{1000, 0, 1}}); // check if cm is correct here // Histos for NegDaughter - mQAHistogramRegistry->add((folderName + "/AntiResoQA/NegDaughter/Pt"), "Transverse momentum of all tracks;p_{T} (GeV/c);Entries", HistType::kTH1F, {{1000, 0, 10}}); - mQAHistogramRegistry->add((folderName + "/AntiResoQA/NegDaughter/Eta"), "Pseudorapidity of all tracks;#eta;Entries", HistType::kTH1F, {{1000, -2, 2}}); - mQAHistogramRegistry->add((folderName + "/AntiResoQA/NegDaughter/Phi"), "Azimuthal angle of all tracks;#phi;Entries", HistType::kTH1F, {{720, 0, o2::constants::math::TwoPI}}); - mQAHistogramRegistry->add((folderName + "/AntiResoQA/NegDaughter/DcaXY"), "dcaXY of all tracks;d_{XY} (cm);Entries", HistType::kTH1F, {{1000, 0, 1}}); // check if cm is correct here - mQAHistogramRegistry->add((folderName + "/AntiResoQA/NegDaughter/DcaZ"), "dcaZ of all tracks;d_{Z} (cm);Entries", HistType::kTH1F, {{1000, 0, 1}}); // check if cm is correct here + mQAHistogramRegistry->add((folderName + "/AntiResoQA/NegDaughter/Pt"), "Transverse momentum of all tracks;p_{T} (GeV/c);Entries", o2::framework::HistType::kTH1F, {{1000, 0, 10}}); + mQAHistogramRegistry->add((folderName + "/AntiResoQA/NegDaughter/Eta"), "Pseudorapidity of all tracks;#eta;Entries", o2::framework::HistType::kTH1F, {{1000, -2, 2}}); + mQAHistogramRegistry->add((folderName + "/AntiResoQA/NegDaughter/Phi"), "Azimuthal angle of all tracks;#phi;Entries", o2::framework::HistType::kTH1F, {{720, 0, o2::constants::math::TwoPI}}); + mQAHistogramRegistry->add((folderName + "/AntiResoQA/NegDaughter/DcaXY"), "dcaXY of all tracks;d_{XY} (cm);Entries", o2::framework::HistType::kTH1F, {{1000, 0, 1}}); // check if cm is correct here + mQAHistogramRegistry->add((folderName + "/AntiResoQA/NegDaughter/DcaZ"), "dcaZ of all tracks;d_{Z} (cm);Entries", o2::framework::HistType::kTH1F, {{1000, 0, 1}}); // check if cm is correct here // Histos for massQA - mQAHistogramRegistry->add((folderName + "/AntiResoQA/InvMassSwitched"), "Invariant mass V0s;M_{KK};Entries", HistType::kTH1F, {massAxisReso}); // for opposite mass hypothesis (Reso is anti) - mQAHistogramRegistry->add((folderName + "/AntiResoQA/InvMassBothPID1"), "Invariant mass V0s;M_{KK};Entries", HistType::kTH1F, {massAxisReso}); // both particles are of type confDaughterPIDspecies[0] - mQAHistogramRegistry->add((folderName + "/AntiResoQA/InvMassBothPID2"), "Invariant mass V0s;M_{KK};Entries", HistType::kTH1F, {massAxisReso}); // both particles are of type confDaughterPIDspecies[1] + mQAHistogramRegistry->add((folderName + "/AntiResoQA/InvMassSwitched"), "Invariant mass V0s;M_{KK};Entries", o2::framework::HistType::kTH1F, {massAxisReso}); // for opposite mass hypothesis (Reso is anti) + mQAHistogramRegistry->add((folderName + "/AntiResoQA/InvMassBothPID1"), "Invariant mass V0s;M_{KK};Entries", o2::framework::HistType::kTH1F, {massAxisReso}); // both particles are of type confDaughterPIDspecies[0] + mQAHistogramRegistry->add((folderName + "/AntiResoQA/InvMassBothPID2"), "Invariant mass V0s;M_{KK};Entries", o2::framework::HistType::kTH1F, {massAxisReso}); // both particles are of type confDaughterPIDspecies[1] // likeSign MassHistos - mQAHistogramRegistry->add((folderName + "/ResoLikeSign/ResoQA/InvMass"), "Invariant mass V0s;M_{KK};Entries", HistType::kTH1F, {massAxisReso}); - mQAHistogramRegistry->add((folderName + "/ResoLikeSign/ResoQA/InvMassSwitched"), "Invariant mass V0s;M_{KK};Entries", HistType::kTH1F, {massAxisReso}); // for opposite mass hypothesis (Reso is anti) - mQAHistogramRegistry->add((folderName + "/ResoLikeSign/ResoQA/InvMassBothPID1"), "Invariant mass V0s;M_{KK};Entries", HistType::kTH1F, {massAxisReso}); // both particles are of type confDaughterPIDspecies[0] - mQAHistogramRegistry->add((folderName + "/ResoLikeSign/ResoQA/InvMassBothPID2"), "Invariant mass V0s;M_{KK};Entries", HistType::kTH1F, {massAxisReso}); // both particles are of type confDaughterPIDspecies[1] - - mQAHistogramRegistry->add((folderName + "/ResoLikeSign/AntiResoQA/InvMass"), "Invariant mass V0s;M_{KK};Entries", HistType::kTH1F, {massAxisReso}); - mQAHistogramRegistry->add((folderName + "/ResoLikeSign/AntiResoQA/InvMassSwitched"), "Invariant mass V0s;M_{KK};Entries", HistType::kTH1F, {massAxisReso}); // for opposite mass hypothesis (Reso is anti) - mQAHistogramRegistry->add((folderName + "/ResoLikeSign/AntiResoQA/InvMassBothPID1"), "Invariant mass V0s;M_{KK};Entries", HistType::kTH1F, {massAxisReso}); // both particles are of type confDaughterPIDspecies[0] - mQAHistogramRegistry->add((folderName + "/ResoLikeSign/AntiResoQA/InvMassBothPID2"), "Invariant mass V0s;M_{KK};Entries", HistType::kTH1F, {massAxisReso}); // both particles are of type confDaughterPIDspecies[1] + mQAHistogramRegistry->add((folderName + "/ResoLikeSign/ResoQA/InvMass"), "Invariant mass V0s;M_{KK};Entries", o2::framework::HistType::kTH1F, {massAxisReso}); + mQAHistogramRegistry->add((folderName + "/ResoLikeSign/ResoQA/InvMassSwitched"), "Invariant mass V0s;M_{KK};Entries", o2::framework::HistType::kTH1F, {massAxisReso}); // for opposite mass hypothesis (Reso is anti) + mQAHistogramRegistry->add((folderName + "/ResoLikeSign/ResoQA/InvMassBothPID1"), "Invariant mass V0s;M_{KK};Entries", o2::framework::HistType::kTH1F, {massAxisReso}); // both particles are of type confDaughterPIDspecies[0] + mQAHistogramRegistry->add((folderName + "/ResoLikeSign/ResoQA/InvMassBothPID2"), "Invariant mass V0s;M_{KK};Entries", o2::framework::HistType::kTH1F, {massAxisReso}); // both particles are of type confDaughterPIDspecies[1] + + mQAHistogramRegistry->add((folderName + "/ResoLikeSign/AntiResoQA/InvMass"), "Invariant mass V0s;M_{KK};Entries", o2::framework::HistType::kTH1F, {massAxisReso}); + mQAHistogramRegistry->add((folderName + "/ResoLikeSign/AntiResoQA/InvMassSwitched"), "Invariant mass V0s;M_{KK};Entries", o2::framework::HistType::kTH1F, {massAxisReso}); // for opposite mass hypothesis (Reso is anti) + mQAHistogramRegistry->add((folderName + "/ResoLikeSign/AntiResoQA/InvMassBothPID1"), "Invariant mass V0s;M_{KK};Entries", o2::framework::HistType::kTH1F, {massAxisReso}); // both particles are of type confDaughterPIDspecies[0] + mQAHistogramRegistry->add((folderName + "/ResoLikeSign/AntiResoQA/InvMassBothPID2"), "Invariant mass V0s;M_{KK};Entries", o2::framework::HistType::kTH1F, {massAxisReso}); // both particles are of type confDaughterPIDspecies[1] posDaughTrack.init #include - -using namespace o2; -using namespace o2::framework; +#include +#include namespace o2::analysis::femtoDream { @@ -110,7 +109,7 @@ class FemtoDreamSelection /// \param cutContainer Bit-wise container for the systematic variations /// \param counter Position in the bit-wise container for the systematic variations to be modified template - void checkSelectionSetBit(selValDataType observable, T& cutContainer, size_t& counter, HistogramRegistry* registry) + void checkSelectionSetBit(selValDataType observable, T& cutContainer, size_t& counter, framework::HistogramRegistry* registry) { /// If the selection is fulfilled the bit at the specified position (counter) within the bit-wise container is set to 1 if (isSelected(observable)) { diff --git a/PWGCF/FemtoDream/Core/femtoDreamTrackSelection.h b/PWGCF/FemtoDream/Core/femtoDreamTrackSelection.h index 5c9780d2e82..a721a31e7ec 100644 --- a/PWGCF/FemtoDream/Core/femtoDreamTrackSelection.h +++ b/PWGCF/FemtoDream/Core/femtoDreamTrackSelection.h @@ -19,21 +19,24 @@ #include "PWGCF/DataModel/FemtoDerived.h" #include "PWGCF/FemtoDream/Core/femtoDreamObjectSelection.h" +#include "PWGCF/FemtoDream/Core/femtoDreamSelection.h" -#include "Common/Core/TrackSelection.h" -#include "Common/Core/TrackSelectionDefaults.h" -#include "Common/DataModel/PIDResponseITS.h" -#include "Common/DataModel/TrackSelectionTables.h" +#include "Common/DataModel/PIDResponseTOF.h" +#include "Common/DataModel/PIDResponseTPC.h" -#include "Framework/HistogramRegistry.h" -#include "ReconstructionDataFormats/PID.h" +#include +#include +#include +#include +#include #include +#include #include +#include #include -using namespace o2::framework; -using namespace o2::analysis::femtoDream::femtoDreamSelection; +#include namespace o2::analysis::femtoDream { @@ -100,9 +103,9 @@ class FemtoDreamTrackSelection : public FemtoDreamObjectSelection - void init(HistogramRegistry* QAregistry, HistogramRegistry* Registry); + void init(o2::framework::HistogramRegistry* QAregistry, o2::framework::HistogramRegistry* Registry); /// Passes the species to the task for which PID needs to be stored /// \tparam T Data type of the configurable passed to the functions @@ -305,7 +308,7 @@ class FemtoDreamTrackSelection : public FemtoDreamObjectSelection -void FemtoDreamTrackSelection::init(HistogramRegistry* QAregistry, HistogramRegistry* Registry) +void FemtoDreamTrackSelection::init(o2::framework::HistogramRegistry* QAregistry, o2::framework::HistogramRegistry* Registry) { if (QAregistry && Registry) { mHistogramRegistry = Registry; @@ -318,37 +321,37 @@ void FemtoDreamTrackSelection::init(HistogramRegistry* QAregistry, HistogramRegi LOG(fatal) << "FemtoDreamTrackCuts: Number of selections too large for your container - quitting!"; } - for (int istage = 0; istage < kNcutStages; istage++) { - mQAHistogramRegistry->add((folderName + "/" + static_cast(mCutStage[istage]) + "/hPt").c_str(), "; #it{p}_{T} (GeV/#it{c}); Entries", kTH1F, {{240, 0, 6}}); - mQAHistogramRegistry->add((folderName + "/" + static_cast(mCutStage[istage]) + "/hEta").c_str(), "; #eta; Entries", kTH1F, {{200, -1.5, 1.5}}); - mQAHistogramRegistry->add((folderName + "/" + static_cast(mCutStage[istage]) + "/hPhi").c_str(), "; #phi; Entries", kTH1F, {{200, 0, 2. * M_PI}}); - mQAHistogramRegistry->add((folderName + "/" + static_cast(mCutStage[istage]) + "/hTPCfindable").c_str(), "; TPC findable clusters; Entries", kTH1F, {{163, -0.5, 162.5}}); - mQAHistogramRegistry->add((folderName + "/" + static_cast(mCutStage[istage]) + "/hTPCfound").c_str(), "; TPC found clusters; Entries", kTH1F, {{163, -0.5, 162.5}}); - mQAHistogramRegistry->add((folderName + "/" + static_cast(mCutStage[istage]) + "/hTPCcrossedOverFindalbe").c_str(), "; TPC ratio findable; Entries", kTH1F, {{100, 0.5, 1.5}}); - mQAHistogramRegistry->add((folderName + "/" + static_cast(mCutStage[istage]) + "/hTPCcrossedRows").c_str(), "; TPC crossed rows; Entries", kTH1F, {{163, 0, 163}}); - mQAHistogramRegistry->add((folderName + "/" + static_cast(mCutStage[istage]) + "/hTPCfindableVsCrossed").c_str(), ";TPC findable clusters ; TPC crossed rows;", kTH2F, {{163, 0, 163}, {163, 0, 163}}); - mQAHistogramRegistry->add((folderName + "/" + static_cast(mCutStage[istage]) + "/hTPCshared").c_str(), "; TPC shared clusters; Entries", kTH1F, {{163, -0.5, 162.5}}); - mQAHistogramRegistry->add((folderName + "/" + static_cast(mCutStage[istage]) + "/hITSclusters").c_str(), "; ITS clusters; Entries", kTH1F, {{10, -0.5, 9.5}}); - mQAHistogramRegistry->add((folderName + "/" + static_cast(mCutStage[istage]) + "/hITSclustersIB").c_str(), "; ITS clusters in IB; Entries", kTH1F, {{10, -0.5, 9.5}}); - mQAHistogramRegistry->add((folderName + "/" + static_cast(mCutStage[istage]) + "/hDCAxy").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", kTH2F, {{100, 0, 10}, {500, -5, 5}}); - mQAHistogramRegistry->add((folderName + "/" + static_cast(mCutStage[istage]) + "/hDCAz").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{z} (cm)", kTH2F, {{100, 0, 10}, {500, -5, 5}}); - mQAHistogramRegistry->add((folderName + "/" + static_cast(mCutStage[istage]) + "/hDCA").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA (cm)", kTH2F, {{100, 0, 10}, {301, 0., 1.5}}); - mQAHistogramRegistry->add((folderName + "/" + static_cast(mCutStage[istage]) + "/hTPCdEdX").c_str(), "; #it{p} (GeV/#it{c}); TPC Signal", kTH2F, {{100, 0, 10}, {1000, 0, 1000}}); - mQAHistogramRegistry->add((folderName + "/" + static_cast(mCutStage[istage]) + "/nSigmaTPC_el").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TPC}^{e}", kTH2F, {{100, 0, 10}, {100, -5, 5}}); - mQAHistogramRegistry->add((folderName + "/" + static_cast(mCutStage[istage]) + "/nSigmaTPC_pi").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TPC}^{#pi}", kTH2F, {{100, 0, 10}, {100, -5, 5}}); - mQAHistogramRegistry->add((folderName + "/" + static_cast(mCutStage[istage]) + "/nSigmaTPC_K").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TPC}^{K}", kTH2F, {{100, 0, 10}, {100, -5, 5}}); - mQAHistogramRegistry->add((folderName + "/" + static_cast(mCutStage[istage]) + "/nSigmaTPC_p").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TPC}^{p}", kTH2F, {{100, 0, 10}, {100, -5, 5}}); - mQAHistogramRegistry->add((folderName + "/" + static_cast(mCutStage[istage]) + "/nSigmaTPC_d").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TPC}^{d}", kTH2F, {{100, 0, 10}, {100, -5, 5}}); - mQAHistogramRegistry->add((folderName + "/" + static_cast(mCutStage[istage]) + "/nSigmaTOF_el").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TOF}^{e}", kTH2F, {{100, 0, 10}, {100, -5, 5}}); - mQAHistogramRegistry->add((folderName + "/" + static_cast(mCutStage[istage]) + "/nSigmaTOF_pi").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TOF}^{#pi}", kTH2F, {{100, 0, 10}, {100, -5, 5}}); - mQAHistogramRegistry->add((folderName + "/" + static_cast(mCutStage[istage]) + "/nSigmaTOF_K").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TOF}^{K}", kTH2F, {{100, 0, 10}, {100, -5, 5}}); - mQAHistogramRegistry->add((folderName + "/" + static_cast(mCutStage[istage]) + "/nSigmaTOF_p").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TOF}^{p}", kTH2F, {{100, 0, 10}, {100, -5, 5}}); - mQAHistogramRegistry->add((folderName + "/" + static_cast(mCutStage[istage]) + "/nSigmaTOF_d").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TOF}^{d}", kTH2F, {{100, 0, 10}, {100, -5, 5}}); - mQAHistogramRegistry->add((folderName + "/" + static_cast(mCutStage[istage]) + "/nSigmaComb_el").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{comb}^{e}", kTH2F, {{100, 0, 10}, {100, -5, 5}}); - mQAHistogramRegistry->add((folderName + "/" + static_cast(mCutStage[istage]) + "/nSigmaComb_pi").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{comb}^{#pi}", kTH2F, {{100, 0, 10}, {100, -5, 5}}); - mQAHistogramRegistry->add((folderName + "/" + static_cast(mCutStage[istage]) + "/nSigmaComb_K").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{comb}^{K}", kTH2F, {{100, 0, 10}, {100, -5, 5}}); - mQAHistogramRegistry->add((folderName + "/" + static_cast(mCutStage[istage]) + "/nSigmaComb_p").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{comb}^{p}", kTH2F, {{100, 0, 10}, {100, -5, 5}}); - mQAHistogramRegistry->add((folderName + "/" + static_cast(mCutStage[istage]) + "/nSigmaComb_d").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{comb}^{d}", kTH2F, {{100, 0, 10}, {100, -5, 5}}); + for (int istage = 0; istage < femtoDreamSelection::kNcutStages; istage++) { + mQAHistogramRegistry->add((folderName + "/" + static_cast(femtoDreamSelection::mCutStage[istage]) + "/hPt").c_str(), "; #it{p}_{T} (GeV/#it{c}); Entries", o2::framework::kTH1F, {{240, 0, 6}}); + mQAHistogramRegistry->add((folderName + "/" + static_cast(femtoDreamSelection::mCutStage[istage]) + "/hEta").c_str(), "; #eta; Entries", o2::framework::kTH1F, {{200, -1.5, 1.5}}); + mQAHistogramRegistry->add((folderName + "/" + static_cast(femtoDreamSelection::mCutStage[istage]) + "/hPhi").c_str(), "; #phi; Entries", o2::framework::kTH1F, {{200, 0, 2. * M_PI}}); + mQAHistogramRegistry->add((folderName + "/" + static_cast(femtoDreamSelection::mCutStage[istage]) + "/hTPCfindable").c_str(), "; TPC findable clusters; Entries", o2::framework::kTH1F, {{163, -0.5, 162.5}}); + mQAHistogramRegistry->add((folderName + "/" + static_cast(femtoDreamSelection::mCutStage[istage]) + "/hTPCfound").c_str(), "; TPC found clusters; Entries", o2::framework::kTH1F, {{163, -0.5, 162.5}}); + mQAHistogramRegistry->add((folderName + "/" + static_cast(femtoDreamSelection::mCutStage[istage]) + "/hTPCcrossedOverFindalbe").c_str(), "; TPC ratio findable; Entries", o2::framework::kTH1F, {{100, 0.5, 1.5}}); + mQAHistogramRegistry->add((folderName + "/" + static_cast(femtoDreamSelection::mCutStage[istage]) + "/hTPCcrossedRows").c_str(), "; TPC crossed rows; Entries", o2::framework::kTH1F, {{163, 0, 163}}); + mQAHistogramRegistry->add((folderName + "/" + static_cast(femtoDreamSelection::mCutStage[istage]) + "/hTPCfindableVsCrossed").c_str(), ";TPC findable clusters ; TPC crossed rows;", o2::framework::kTH2F, {{163, 0, 163}, {163, 0, 163}}); + mQAHistogramRegistry->add((folderName + "/" + static_cast(femtoDreamSelection::mCutStage[istage]) + "/hTPCshared").c_str(), "; TPC shared clusters; Entries", o2::framework::kTH1F, {{163, -0.5, 162.5}}); + mQAHistogramRegistry->add((folderName + "/" + static_cast(femtoDreamSelection::mCutStage[istage]) + "/hITSclusters").c_str(), "; ITS clusters; Entries", o2::framework::kTH1F, {{10, -0.5, 9.5}}); + mQAHistogramRegistry->add((folderName + "/" + static_cast(femtoDreamSelection::mCutStage[istage]) + "/hITSclustersIB").c_str(), "; ITS clusters in IB; Entries", o2::framework::kTH1F, {{10, -0.5, 9.5}}); + mQAHistogramRegistry->add((folderName + "/" + static_cast(femtoDreamSelection::mCutStage[istage]) + "/hDCAxy").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::kTH2F, {{100, 0, 10}, {500, -5, 5}}); + mQAHistogramRegistry->add((folderName + "/" + static_cast(femtoDreamSelection::mCutStage[istage]) + "/hDCAz").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{z} (cm)", o2::framework::kTH2F, {{100, 0, 10}, {500, -5, 5}}); + mQAHistogramRegistry->add((folderName + "/" + static_cast(femtoDreamSelection::mCutStage[istage]) + "/hDCA").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA (cm)", o2::framework::kTH2F, {{100, 0, 10}, {301, 0., 1.5}}); + mQAHistogramRegistry->add((folderName + "/" + static_cast(femtoDreamSelection::mCutStage[istage]) + "/hTPCdEdX").c_str(), "; #it{p} (GeV/#it{c}); TPC Signal", o2::framework::kTH2F, {{100, 0, 10}, {1000, 0, 1000}}); + mQAHistogramRegistry->add((folderName + "/" + static_cast(femtoDreamSelection::mCutStage[istage]) + "/nSigmaTPC_el").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TPC}^{e}", o2::framework::kTH2F, {{100, 0, 10}, {100, -5, 5}}); + mQAHistogramRegistry->add((folderName + "/" + static_cast(femtoDreamSelection::mCutStage[istage]) + "/nSigmaTPC_pi").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TPC}^{#pi}", o2::framework::kTH2F, {{100, 0, 10}, {100, -5, 5}}); + mQAHistogramRegistry->add((folderName + "/" + static_cast(femtoDreamSelection::mCutStage[istage]) + "/nSigmaTPC_K").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TPC}^{K}", o2::framework::kTH2F, {{100, 0, 10}, {100, -5, 5}}); + mQAHistogramRegistry->add((folderName + "/" + static_cast(femtoDreamSelection::mCutStage[istage]) + "/nSigmaTPC_p").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TPC}^{p}", o2::framework::kTH2F, {{100, 0, 10}, {100, -5, 5}}); + mQAHistogramRegistry->add((folderName + "/" + static_cast(femtoDreamSelection::mCutStage[istage]) + "/nSigmaTPC_d").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TPC}^{d}", o2::framework::kTH2F, {{100, 0, 10}, {100, -5, 5}}); + mQAHistogramRegistry->add((folderName + "/" + static_cast(femtoDreamSelection::mCutStage[istage]) + "/nSigmaTOF_el").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TOF}^{e}", o2::framework::kTH2F, {{100, 0, 10}, {100, -5, 5}}); + mQAHistogramRegistry->add((folderName + "/" + static_cast(femtoDreamSelection::mCutStage[istage]) + "/nSigmaTOF_pi").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TOF}^{#pi}", o2::framework::kTH2F, {{100, 0, 10}, {100, -5, 5}}); + mQAHistogramRegistry->add((folderName + "/" + static_cast(femtoDreamSelection::mCutStage[istage]) + "/nSigmaTOF_K").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TOF}^{K}", o2::framework::kTH2F, {{100, 0, 10}, {100, -5, 5}}); + mQAHistogramRegistry->add((folderName + "/" + static_cast(femtoDreamSelection::mCutStage[istage]) + "/nSigmaTOF_p").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TOF}^{p}", o2::framework::kTH2F, {{100, 0, 10}, {100, -5, 5}}); + mQAHistogramRegistry->add((folderName + "/" + static_cast(femtoDreamSelection::mCutStage[istage]) + "/nSigmaTOF_d").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TOF}^{d}", o2::framework::kTH2F, {{100, 0, 10}, {100, -5, 5}}); + mQAHistogramRegistry->add((folderName + "/" + static_cast(femtoDreamSelection::mCutStage[istage]) + "/nSigmaComb_el").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{comb}^{e}", o2::framework::kTH2F, {{100, 0, 10}, {100, -5, 5}}); + mQAHistogramRegistry->add((folderName + "/" + static_cast(femtoDreamSelection::mCutStage[istage]) + "/nSigmaComb_pi").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{comb}^{#pi}", o2::framework::kTH2F, {{100, 0, 10}, {100, -5, 5}}); + mQAHistogramRegistry->add((folderName + "/" + static_cast(femtoDreamSelection::mCutStage[istage]) + "/nSigmaComb_K").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{comb}^{K}", o2::framework::kTH2F, {{100, 0, 10}, {100, -5, 5}}); + mQAHistogramRegistry->add((folderName + "/" + static_cast(femtoDreamSelection::mCutStage[istage]) + "/nSigmaComb_p").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{comb}^{p}", o2::framework::kTH2F, {{100, 0, 10}, {100, -5, 5}}); + mQAHistogramRegistry->add((folderName + "/" + static_cast(femtoDreamSelection::mCutStage[istage]) + "/nSigmaComb_d").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{comb}^{d}", o2::framework::kTH2F, {{100, 0, 10}, {100, -5, 5}}); } } @@ -594,38 +597,38 @@ template fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtodreamparticle::TrackTypeName[tracktype]) + HIST("/") + HIST(mCutStage[cutstage]) + HIST("/hPt"), track.pt()); - mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtodreamparticle::TrackTypeName[tracktype]) + HIST("/") + HIST(mCutStage[cutstage]) + HIST("/hEta"), track.eta()); - mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtodreamparticle::TrackTypeName[tracktype]) + HIST("/") + HIST(mCutStage[cutstage]) + HIST("/hPhi"), track.phi()); - mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtodreamparticle::TrackTypeName[tracktype]) + HIST("/") + HIST(mCutStage[cutstage]) + HIST("/hTPCfindable"), track.tpcNClsFindable()); - mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtodreamparticle::TrackTypeName[tracktype]) + HIST("/") + HIST(mCutStage[cutstage]) + HIST("/hTPCfound"), track.tpcNClsFound()); - mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtodreamparticle::TrackTypeName[tracktype]) + HIST("/") + HIST(mCutStage[cutstage]) + HIST("/hTPCcrossedOverFindalbe"), track.tpcCrossedRowsOverFindableCls()); - mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtodreamparticle::TrackTypeName[tracktype]) + HIST("/") + HIST(mCutStage[cutstage]) + HIST("/hTPCcrossedRows"), track.tpcNClsCrossedRows()); - mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtodreamparticle::TrackTypeName[tracktype]) + HIST("/") + HIST(mCutStage[cutstage]) + HIST("/hTPCfindableVsCrossed"), track.tpcNClsFindable(), track.tpcNClsCrossedRows()); - mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtodreamparticle::TrackTypeName[tracktype]) + HIST("/") + HIST(mCutStage[cutstage]) + HIST("/hTPCshared"), track.tpcNClsShared()); - mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtodreamparticle::TrackTypeName[tracktype]) + HIST("/") + HIST(mCutStage[cutstage]) + HIST("/hITSclusters"), track.itsNCls()); - mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtodreamparticle::TrackTypeName[tracktype]) + HIST("/") + HIST(mCutStage[cutstage]) + HIST("/hITSclustersIB"), track.itsNClsInnerBarrel()); - mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtodreamparticle::TrackTypeName[tracktype]) + HIST("/") + HIST(mCutStage[cutstage]) + HIST("/hDCAxy"), track.pt(), track.dcaXY()); - mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtodreamparticle::TrackTypeName[tracktype]) + HIST("/") + HIST(mCutStage[cutstage]) + HIST("/hDCAz"), track.pt(), track.dcaZ()); - mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtodreamparticle::TrackTypeName[tracktype]) + HIST("/") + HIST(mCutStage[cutstage]) + HIST("/hDCA"), track.pt(), std::sqrt(pow(track.dcaXY(), 2.) + pow(track.dcaZ(), 2.))); - mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtodreamparticle::TrackTypeName[tracktype]) + HIST("/") + HIST(mCutStage[cutstage]) + HIST("/hTPCdEdX"), track.p(), track.tpcSignal()); - mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtodreamparticle::TrackTypeName[tracktype]) + HIST("/") + HIST(mCutStage[cutstage]) + HIST("/nSigmaTPC_pi"), track.p(), track.tpcNSigmaPi()); - mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtodreamparticle::TrackTypeName[tracktype]) + HIST("/") + HIST(mCutStage[cutstage]) + HIST("/nSigmaTPC_K"), track.p(), track.tpcNSigmaKa()); - mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtodreamparticle::TrackTypeName[tracktype]) + HIST("/") + HIST(mCutStage[cutstage]) + HIST("/nSigmaTPC_p"), track.p(), track.tpcNSigmaPr()); - mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtodreamparticle::TrackTypeName[tracktype]) + HIST("/") + HIST(mCutStage[cutstage]) + HIST("/nSigmaTOF_pi"), track.p(), track.tofNSigmaPi()); - mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtodreamparticle::TrackTypeName[tracktype]) + HIST("/") + HIST(mCutStage[cutstage]) + HIST("/nSigmaTOF_K"), track.p(), track.tofNSigmaKa()); - mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtodreamparticle::TrackTypeName[tracktype]) + HIST("/") + HIST(mCutStage[cutstage]) + HIST("/nSigmaTOF_p"), track.p(), track.tofNSigmaPr()); - mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtodreamparticle::TrackTypeName[tracktype]) + HIST("/") + HIST(mCutStage[cutstage]) + HIST("/nSigmaComb_pi"), track.p(), std::sqrt(track.tpcNSigmaPi() * track.tpcNSigmaPi() + track.tofNSigmaPi() * track.tofNSigmaPi())); - mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtodreamparticle::TrackTypeName[tracktype]) + HIST("/") + HIST(mCutStage[cutstage]) + HIST("/nSigmaComb_K"), track.p(), std::sqrt(track.tpcNSigmaKa() * track.tpcNSigmaKa() + track.tofNSigmaKa() * track.tofNSigmaKa())); - mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtodreamparticle::TrackTypeName[tracktype]) + HIST("/") + HIST(mCutStage[cutstage]) + HIST("/nSigmaComb_p"), track.p(), std::sqrt(track.tpcNSigmaPr() * track.tpcNSigmaPr() + track.tofNSigmaPr() * track.tofNSigmaPr())); - mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtodreamparticle::TrackTypeName[tracktype]) + HIST("/") + HIST(mCutStage[cutstage]) + HIST("/nSigmaTPC_d"), track.p(), track.tpcNSigmaDe()); - mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtodreamparticle::TrackTypeName[tracktype]) + HIST("/") + HIST(mCutStage[cutstage]) + HIST("/nSigmaComb_d"), track.p(), std::sqrt(track.tpcNSigmaDe() * track.tpcNSigmaDe() + track.tofNSigmaDe() * track.tofNSigmaDe())); - mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtodreamparticle::TrackTypeName[tracktype]) + HIST("/") + HIST(mCutStage[cutstage]) + HIST("/nSigmaTOF_d"), track.p(), track.tofNSigmaDe()); + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtodreamparticle::TrackTypeName[tracktype]) + HIST("/") + HIST(femtoDreamSelection::mCutStage[cutstage]) + HIST("/hPt"), track.pt()); + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtodreamparticle::TrackTypeName[tracktype]) + HIST("/") + HIST(femtoDreamSelection::mCutStage[cutstage]) + HIST("/hEta"), track.eta()); + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtodreamparticle::TrackTypeName[tracktype]) + HIST("/") + HIST(femtoDreamSelection::mCutStage[cutstage]) + HIST("/hPhi"), track.phi()); + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtodreamparticle::TrackTypeName[tracktype]) + HIST("/") + HIST(femtoDreamSelection::mCutStage[cutstage]) + HIST("/hTPCfindable"), track.tpcNClsFindable()); + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtodreamparticle::TrackTypeName[tracktype]) + HIST("/") + HIST(femtoDreamSelection::mCutStage[cutstage]) + HIST("/hTPCfound"), track.tpcNClsFound()); + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtodreamparticle::TrackTypeName[tracktype]) + HIST("/") + HIST(femtoDreamSelection::mCutStage[cutstage]) + HIST("/hTPCcrossedOverFindalbe"), track.tpcCrossedRowsOverFindableCls()); + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtodreamparticle::TrackTypeName[tracktype]) + HIST("/") + HIST(femtoDreamSelection::mCutStage[cutstage]) + HIST("/hTPCcrossedRows"), track.tpcNClsCrossedRows()); + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtodreamparticle::TrackTypeName[tracktype]) + HIST("/") + HIST(femtoDreamSelection::mCutStage[cutstage]) + HIST("/hTPCfindableVsCrossed"), track.tpcNClsFindable(), track.tpcNClsCrossedRows()); + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtodreamparticle::TrackTypeName[tracktype]) + HIST("/") + HIST(femtoDreamSelection::mCutStage[cutstage]) + HIST("/hTPCshared"), track.tpcNClsShared()); + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtodreamparticle::TrackTypeName[tracktype]) + HIST("/") + HIST(femtoDreamSelection::mCutStage[cutstage]) + HIST("/hITSclusters"), track.itsNCls()); + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtodreamparticle::TrackTypeName[tracktype]) + HIST("/") + HIST(femtoDreamSelection::mCutStage[cutstage]) + HIST("/hITSclustersIB"), track.itsNClsInnerBarrel()); + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtodreamparticle::TrackTypeName[tracktype]) + HIST("/") + HIST(femtoDreamSelection::mCutStage[cutstage]) + HIST("/hDCAxy"), track.pt(), track.dcaXY()); + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtodreamparticle::TrackTypeName[tracktype]) + HIST("/") + HIST(femtoDreamSelection::mCutStage[cutstage]) + HIST("/hDCAz"), track.pt(), track.dcaZ()); + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtodreamparticle::TrackTypeName[tracktype]) + HIST("/") + HIST(femtoDreamSelection::mCutStage[cutstage]) + HIST("/hDCA"), track.pt(), std::sqrt(pow(track.dcaXY(), 2.) + pow(track.dcaZ(), 2.))); + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtodreamparticle::TrackTypeName[tracktype]) + HIST("/") + HIST(femtoDreamSelection::mCutStage[cutstage]) + HIST("/hTPCdEdX"), track.p(), track.tpcSignal()); + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtodreamparticle::TrackTypeName[tracktype]) + HIST("/") + HIST(femtoDreamSelection::mCutStage[cutstage]) + HIST("/nSigmaTPC_pi"), track.p(), track.tpcNSigmaPi()); + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtodreamparticle::TrackTypeName[tracktype]) + HIST("/") + HIST(femtoDreamSelection::mCutStage[cutstage]) + HIST("/nSigmaTPC_K"), track.p(), track.tpcNSigmaKa()); + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtodreamparticle::TrackTypeName[tracktype]) + HIST("/") + HIST(femtoDreamSelection::mCutStage[cutstage]) + HIST("/nSigmaTPC_p"), track.p(), track.tpcNSigmaPr()); + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtodreamparticle::TrackTypeName[tracktype]) + HIST("/") + HIST(femtoDreamSelection::mCutStage[cutstage]) + HIST("/nSigmaTOF_pi"), track.p(), track.tofNSigmaPi()); + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtodreamparticle::TrackTypeName[tracktype]) + HIST("/") + HIST(femtoDreamSelection::mCutStage[cutstage]) + HIST("/nSigmaTOF_K"), track.p(), track.tofNSigmaKa()); + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtodreamparticle::TrackTypeName[tracktype]) + HIST("/") + HIST(femtoDreamSelection::mCutStage[cutstage]) + HIST("/nSigmaTOF_p"), track.p(), track.tofNSigmaPr()); + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtodreamparticle::TrackTypeName[tracktype]) + HIST("/") + HIST(femtoDreamSelection::mCutStage[cutstage]) + HIST("/nSigmaComb_pi"), track.p(), std::sqrt(track.tpcNSigmaPi() * track.tpcNSigmaPi() + track.tofNSigmaPi() * track.tofNSigmaPi())); + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtodreamparticle::TrackTypeName[tracktype]) + HIST("/") + HIST(femtoDreamSelection::mCutStage[cutstage]) + HIST("/nSigmaComb_K"), track.p(), std::sqrt(track.tpcNSigmaKa() * track.tpcNSigmaKa() + track.tofNSigmaKa() * track.tofNSigmaKa())); + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtodreamparticle::TrackTypeName[tracktype]) + HIST("/") + HIST(femtoDreamSelection::mCutStage[cutstage]) + HIST("/nSigmaComb_p"), track.p(), std::sqrt(track.tpcNSigmaPr() * track.tpcNSigmaPr() + track.tofNSigmaPr() * track.tofNSigmaPr())); + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtodreamparticle::TrackTypeName[tracktype]) + HIST("/") + HIST(femtoDreamSelection::mCutStage[cutstage]) + HIST("/nSigmaTPC_d"), track.p(), track.tpcNSigmaDe()); + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtodreamparticle::TrackTypeName[tracktype]) + HIST("/") + HIST(femtoDreamSelection::mCutStage[cutstage]) + HIST("/nSigmaComb_d"), track.p(), std::sqrt(track.tpcNSigmaDe() * track.tpcNSigmaDe() + track.tofNSigmaDe() * track.tofNSigmaDe())); + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtodreamparticle::TrackTypeName[tracktype]) + HIST("/") + HIST(femtoDreamSelection::mCutStage[cutstage]) + HIST("/nSigmaTOF_d"), track.p(), track.tofNSigmaDe()); if constexpr (!isHF) { - mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtodreamparticle::TrackTypeName[tracktype]) + HIST("/") + HIST(mCutStage[cutstage]) + HIST("/nSigmaComb_el"), track.p(), std::sqrt(track.tpcNSigmaEl() * track.tpcNSigmaEl() + track.tofNSigmaEl() * track.tofNSigmaEl())); - mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtodreamparticle::TrackTypeName[tracktype]) + HIST("/") + HIST(mCutStage[cutstage]) + HIST("/nSigmaTOF_el"), track.p(), track.tofNSigmaEl()); - mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtodreamparticle::TrackTypeName[tracktype]) + HIST("/") + HIST(mCutStage[cutstage]) + HIST("/nSigmaTPC_el"), track.p(), track.tpcNSigmaEl()); + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtodreamparticle::TrackTypeName[tracktype]) + HIST("/") + HIST(femtoDreamSelection::mCutStage[cutstage]) + HIST("/nSigmaComb_el"), track.p(), std::sqrt(track.tpcNSigmaEl() * track.tpcNSigmaEl() + track.tofNSigmaEl() * track.tofNSigmaEl())); + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtodreamparticle::TrackTypeName[tracktype]) + HIST("/") + HIST(femtoDreamSelection::mCutStage[cutstage]) + HIST("/nSigmaTOF_el"), track.p(), track.tofNSigmaEl()); + mQAHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + HIST("/") + HIST(o2::aod::femtodreamparticle::TrackTypeName[tracktype]) + HIST("/") + HIST(femtoDreamSelection::mCutStage[cutstage]) + HIST("/nSigmaTPC_el"), track.p(), track.tpcNSigmaEl()); } } } diff --git a/PWGCF/FemtoDream/Core/femtoDreamUtils.h b/PWGCF/FemtoDream/Core/femtoDreamUtils.h index 3911b093a8f..efc075671c1 100644 --- a/PWGCF/FemtoDream/Core/femtoDreamUtils.h +++ b/PWGCF/FemtoDream/Core/femtoDreamUtils.h @@ -18,8 +18,13 @@ #include "PWGCF/DataModel/FemtoDerived.h" -#include "CommonConstants/PhysicsConstants.h" +#include +#include +#include + +#include +#include #include #include diff --git a/PWGCF/FemtoDream/Core/femtoDreamV0Selection.h b/PWGCF/FemtoDream/Core/femtoDreamV0Selection.h index 3cd52ebd219..7f2bf08e2ed 100644 --- a/PWGCF/FemtoDream/Core/femtoDreamV0Selection.h +++ b/PWGCF/FemtoDream/Core/femtoDreamV0Selection.h @@ -18,21 +18,24 @@ #ifndef PWGCF_FEMTODREAM_CORE_FEMTODREAMV0SELECTION_H_ #define PWGCF_FEMTODREAM_CORE_FEMTODREAMV0SELECTION_H_ +#include "PWGCF/DataModel/FemtoDerived.h" #include "PWGCF/FemtoDream/Core/femtoDreamObjectSelection.h" #include "PWGCF/FemtoDream/Core/femtoDreamSelection.h" #include "PWGCF/FemtoDream/Core/femtoDreamTrackSelection.h" -#include "Common/Core/RecoDecay.h" +#include +#include +#include +#include -#include "Framework/HistogramRegistry.h" -#include "ReconstructionDataFormats/PID.h" - -#include +#include +#include +#include #include +#include #include -using namespace o2::framework; -using namespace o2::analysis::femtoDream::femtoDreamSelection; +#include namespace o2::analysis::femtoDream { @@ -76,7 +79,7 @@ class FemtoDreamV0Selection template - void init(HistogramRegistry* QAregistry, HistogramRegistry* Registry); + void init(o2::framework::HistogramRegistry* QAregistry, o2::framework::HistogramRegistry* Registry); template bool isSelectedMinimal(C const& col, V const& v0, T const& posTrack, @@ -280,7 +283,7 @@ class FemtoDreamV0Selection template -void FemtoDreamV0Selection::init(HistogramRegistry* QAregistry, HistogramRegistry* Registry) +void FemtoDreamV0Selection::init(o2::framework::HistogramRegistry* QAregistry, o2::framework::HistogramRegistry* Registry) { if (QAregistry && Registry) { mHistogramRegistry = Registry; @@ -288,9 +291,9 @@ void FemtoDreamV0Selection::init(HistogramRegistry* QAregistry, HistogramRegistr fillSelectionHistogram(); fillSelectionHistogram(); - AxisSpec massAxisLambda = {600, 0.0f, 3.0f, "m_{#Lambda} (GeV/#it{c}^{2})"}; - AxisSpec massAxisAntiLambda = {600, 0.0f, 3.0f, - "m_{#bar{#Lambda}} (GeV/#it{c}^{2})"}; + o2::framework::AxisSpec massAxisLambda = {600, 0.0f, 3.0f, "m_{#Lambda} (GeV/#it{c}^{2})"}; + o2::framework::AxisSpec massAxisAntiLambda = {600, 0.0f, 3.0f, + "m_{#bar{#Lambda}} (GeV/#it{c}^{2})"}; /// \todo this should be an automatic check in the parent class, and the /// return type should be templated @@ -299,45 +302,45 @@ void FemtoDreamV0Selection::init(HistogramRegistry* QAregistry, HistogramRegistr LOG(fatal) << "FemtoDreamV0Cuts: Number of selections to large for your " "container - quitting!"; } - for (int istage = 0; istage < kNcutStages; istage++) { + for (int istage = 0; istage < femtoDreamSelection::kNcutStages; istage++) { std::string folderName = static_cast(o2::aod::femtodreamparticle::ParticleTypeName[part]) + "/" + - static_cast(mCutStage[istage]); + static_cast(femtoDreamSelection::mCutStage[istage]); /// \todo initialize histograms for children tracks of v0s mQAHistogramRegistry->add((folderName + "/hPt").c_str(), - "; #it{p}_{T} (GeV/#it{c}); Entries", kTH1F, + "; #it{p}_{T} (GeV/#it{c}); Entries", o2::framework::kTH1F, {{1000, 0, 10}}); mQAHistogramRegistry->add((folderName + "/hEta").c_str(), "; #eta; Entries", - kTH1F, {{1000, -1, 1}}); + o2::framework::kTH1F, {{1000, -1, 1}}); mQAHistogramRegistry->add((folderName + "/hPhi").c_str(), "; #phi; Entries", - kTH1F, {{1000, 0, 2. * M_PI}}); + o2::framework::kTH1F, {{1000, 0, 2. * M_PI}}); mQAHistogramRegistry->add((folderName + "/hDaughDCA").c_str(), - "; DCA^{daugh} (cm); Entries", kTH1F, + "; DCA^{daugh} (cm); Entries", o2::framework::kTH1F, {{1000, 0, 10}}); mQAHistogramRegistry->add((folderName + "/hTransRadius").c_str(), - "; #it{r}_{xy} (cm); Entries", kTH1F, + "; #it{r}_{xy} (cm); Entries", o2::framework::kTH1F, {{1500, 0, 150}}); mQAHistogramRegistry->add((folderName + "/hDecayVtxX").c_str(), - "; #it{Vtx}_{x} (cm); Entries", kTH1F, + "; #it{Vtx}_{x} (cm); Entries", o2::framework::kTH1F, {{2000, 0, 200}}); mQAHistogramRegistry->add((folderName + "/hDecayVtxY").c_str(), - "; #it{Vtx}_{y} (cm)); Entries", kTH1F, + "; #it{Vtx}_{y} (cm)); Entries", o2::framework::kTH1F, {{2000, 0, 200}}); mQAHistogramRegistry->add((folderName + "/hDecayVtxZ").c_str(), - "; #it{Vtx}_{z} (cm); Entries", kTH1F, + "; #it{Vtx}_{z} (cm); Entries", o2::framework::kTH1F, {{2000, 0, 200}}); mQAHistogramRegistry->add((folderName + "/hCPA").c_str(), - "; #it{cos #theta_{p}}; Entries", kTH1F, + "; #it{cos #theta_{p}}; Entries", o2::framework::kTH1F, {{1000, 0.9, 1.}}); mQAHistogramRegistry->add((folderName + "/hCPAvsPt").c_str(), "; #it{p}_{T} (GeV/#it{c}); #it{cos #theta_{p}}", - kTH2F, {{8, 0.3, 4.3}, {1000, 0.9, 1.}}); - mQAHistogramRegistry->add((folderName + "/hInvMassLambda").c_str(), "", kTH1F, + o2::framework::kTH2F, {{8, 0.3, 4.3}, {1000, 0.9, 1.}}); + mQAHistogramRegistry->add((folderName + "/hInvMassLambda").c_str(), "", o2::framework::kTH1F, {massAxisLambda}); mQAHistogramRegistry->add((folderName + "/hInvMassAntiLambda").c_str(), "", - kTH1F, {massAxisAntiLambda}); + o2::framework::kTH1F, {massAxisAntiLambda}); mQAHistogramRegistry->add((folderName + "/hInvMassLambdaAntiLambda").c_str(), - "", kTH2F, {massAxisLambda, massAxisAntiLambda}); + "", o2::framework::kTH2F, {massAxisLambda, massAxisAntiLambda}); } PosDaughTrack.init( mQAHistogramRegistry, mHistogramRegistry); - mQAHistogramRegistry->add("LambdaQA/hInvMassLambdaNoCuts", "No cuts", kTH1F, + mQAHistogramRegistry->add("LambdaQA/hInvMassLambdaNoCuts", "No cuts", o2::framework::kTH1F, {massAxisLambda}); mQAHistogramRegistry->add("LambdaQA/hInvMassLambdaInvMassCut", - "Invariant mass cut", kTH1F, {massAxisLambda}); + "Invariant mass cut", o2::framework::kTH1F, {massAxisLambda}); mQAHistogramRegistry->add("LambdaQA/hInvMassLambdaPtMin", "Minimum Pt cut", - kTH1F, {massAxisLambda}); + o2::framework::kTH1F, {massAxisLambda}); mQAHistogramRegistry->add("LambdaQA/hInvMassLambdaPtMax", "Maximum Pt cut", - kTH1F, {massAxisLambda}); + o2::framework::kTH1F, {massAxisLambda}); mQAHistogramRegistry->add("LambdaQA/hInvMassLambdaEtaMax", "Maximum Eta cut", - kTH1F, {massAxisLambda}); + o2::framework::kTH1F, {massAxisLambda}); mQAHistogramRegistry->add("LambdaQA/hInvMassLambdaDCAV0Daugh", - "V0-daughters DCA cut", kTH1F, {massAxisLambda}); - mQAHistogramRegistry->add("LambdaQA/hInvMassLambdaCPA", "CPA cut", kTH1F, + "V0-daughters DCA cut", o2::framework::kTH1F, {massAxisLambda}); + mQAHistogramRegistry->add("LambdaQA/hInvMassLambdaCPA", "CPA cut", o2::framework::kTH1F, {massAxisLambda}); mQAHistogramRegistry->add("LambdaQA/hInvMassLambdaTranRadMin", - "Minimum transverse radius cut", kTH1F, + "Minimum transverse radius cut", o2::framework::kTH1F, {massAxisLambda}); mQAHistogramRegistry->add("LambdaQA/hInvMassLambdaTranRadMax", - "Maximum transverse radius cut", kTH1F, + "Maximum transverse radius cut", o2::framework::kTH1F, {massAxisLambda}); mQAHistogramRegistry->add("LambdaQA/hInvMassLambdaDecVtxMax", - "Maximum distance on decay vertex cut", kTH1F, + "Maximum distance on decay vertex cut", o2::framework::kTH1F, {massAxisLambda}); } /// check whether the most open cuts are fulfilled - most of this should have @@ -652,55 +655,55 @@ void FemtoDreamV0Selection::fillQA(C const& /*col*/, V const& v0, T const& posTr if (mQAHistogramRegistry) { mQAHistogramRegistry->fill( HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + - HIST("/") + HIST(mCutStage[cutstage]) + HIST("/hPt"), + HIST("/") + HIST(femtoDreamSelection::mCutStage[cutstage]) + HIST("/hPt"), v0.pt()); mQAHistogramRegistry->fill( HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + - HIST("/") + HIST(mCutStage[cutstage]) + HIST("/hEta"), + HIST("/") + HIST(femtoDreamSelection::mCutStage[cutstage]) + HIST("/hEta"), v0.eta()); mQAHistogramRegistry->fill( HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + - HIST("/") + HIST(mCutStage[cutstage]) + HIST("/hPhi"), + HIST("/") + HIST(femtoDreamSelection::mCutStage[cutstage]) + HIST("/hPhi"), v0.phi()); mQAHistogramRegistry->fill( HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + - HIST("/") + HIST(mCutStage[cutstage]) + HIST("/hDaughDCA"), + HIST("/") + HIST(femtoDreamSelection::mCutStage[cutstage]) + HIST("/hDaughDCA"), v0.dcaV0daughters()); mQAHistogramRegistry->fill( HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + - HIST("/") + HIST(mCutStage[cutstage]) + HIST("/hTransRadius"), + HIST("/") + HIST(femtoDreamSelection::mCutStage[cutstage]) + HIST("/hTransRadius"), v0.v0radius()); mQAHistogramRegistry->fill( HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + - HIST("/") + HIST(mCutStage[cutstage]) + HIST("/hDecayVtxX"), + HIST("/") + HIST(femtoDreamSelection::mCutStage[cutstage]) + HIST("/hDecayVtxX"), v0.x()); mQAHistogramRegistry->fill( HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + - HIST("/") + HIST(mCutStage[cutstage]) + HIST("/hDecayVtxY"), + HIST("/") + HIST(femtoDreamSelection::mCutStage[cutstage]) + HIST("/hDecayVtxY"), v0.y()); mQAHistogramRegistry->fill( HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + - HIST("/") + HIST(mCutStage[cutstage]) + HIST("/hDecayVtxZ"), + HIST("/") + HIST(femtoDreamSelection::mCutStage[cutstage]) + HIST("/hDecayVtxZ"), v0.z()); mQAHistogramRegistry->fill( HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + - HIST("/") + HIST(mCutStage[cutstage]) + HIST("/hCPA"), + HIST("/") + HIST(femtoDreamSelection::mCutStage[cutstage]) + HIST("/hCPA"), v0.v0cosPA()); mQAHistogramRegistry->fill( HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + - HIST("/") + HIST(mCutStage[cutstage]) + HIST("/hCPAvsPt"), + HIST("/") + HIST(femtoDreamSelection::mCutStage[cutstage]) + HIST("/hCPAvsPt"), v0.pt(), v0.v0cosPA()); mQAHistogramRegistry->fill( HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + - HIST("/") + HIST(mCutStage[cutstage]) + HIST("/hInvMassLambda"), + HIST("/") + HIST(femtoDreamSelection::mCutStage[cutstage]) + HIST("/hInvMassLambda"), v0.mLambda()); mQAHistogramRegistry->fill( HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + - HIST("/") + HIST(mCutStage[cutstage]) + HIST("/hInvMassAntiLambda"), + HIST("/") + HIST(femtoDreamSelection::mCutStage[cutstage]) + HIST("/hInvMassAntiLambda"), v0.mAntiLambda()); mQAHistogramRegistry->fill( HIST(o2::aod::femtodreamparticle::ParticleTypeName[part]) + - HIST("/") + HIST(mCutStage[cutstage]) + HIST("/hInvMassLambdaAntiLambda"), + HIST("/") + HIST(femtoDreamSelection::mCutStage[cutstage]) + HIST("/hInvMassLambdaAntiLambda"), v0.mLambda(), v0.mAntiLambda()); } diff --git a/PWGCF/FemtoDream/Core/femtoDreamV0SelectionK0Short.h b/PWGCF/FemtoDream/Core/femtoDreamV0SelectionK0Short.h index b404f9f5b06..2e77fcad4a1 100644 --- a/PWGCF/FemtoDream/Core/femtoDreamV0SelectionK0Short.h +++ b/PWGCF/FemtoDream/Core/femtoDreamV0SelectionK0Short.h @@ -20,16 +20,22 @@ #ifndef PWGCF_FEMTODREAM_CORE_FEMTODREAMV0SELECTIONK0SHORT_H_ #define PWGCF_FEMTODREAM_CORE_FEMTODREAMV0SELECTIONK0SHORT_H_ +#include "PWGCF/DataModel/FemtoDerived.h" #include "PWGCF/FemtoDream/Core/femtoDreamObjectSelection.h" #include "PWGCF/FemtoDream/Core/femtoDreamSelection.h" #include "PWGCF/FemtoDream/Core/femtoDreamTrackSelection.h" -#include "Common/Core/RecoDecay.h" - -#include "Framework/HistogramRegistry.h" -#include "ReconstructionDataFormats/PID.h" +#include +#include +#include +#include +#include +#include +#include +#include #include +#include #include namespace o2::analysis::femtoDream @@ -74,7 +80,7 @@ class FemtoDreamV0Selection /// Initializes histograms for the task template - void init(HistogramRegistry* QAregistry, HistogramRegistry* Registry); + void init(o2::framework::HistogramRegistry* QAregistry, o2::framework::HistogramRegistry* Registry); template bool isSelectedMinimal(C const& col, V const& v0, T const& posTrack, @@ -287,7 +293,7 @@ class FemtoDreamV0Selection template -void FemtoDreamV0Selection::init(HistogramRegistry* QAregistry, HistogramRegistry* Registry) +void FemtoDreamV0Selection::init(o2::framework::HistogramRegistry* QAregistry, o2::framework::HistogramRegistry* Registry) { if (QAregistry && Registry) { mHistogramRegistry = Registry; @@ -295,9 +301,9 @@ void FemtoDreamV0Selection::init(HistogramRegistry* QAregistry, HistogramRegistr fillSelectionHistogram(); fillSelectionHistogram(); - AxisSpec massAxisLambda = {600, 0.0f, 3.0f, "m_{#Lambda} (GeV/#it{c}^{2})"}; /// paramters for K0Short - AxisSpec massAxisAntiLambda = {600, 0.0f, 3.0f, - "m_{#bar{#Lambda}} (GeV/#it{c}^{2})"}; + o2::framework::AxisSpec massAxisLambda = {600, 0.0f, 3.0f, "m_{#Lambda} (GeV/#it{c}^{2})"}; /// paramters for K0Short + o2::framework::AxisSpec massAxisAntiLambda = {600, 0.0f, 3.0f, + "m_{#bar{#Lambda}} (GeV/#it{c}^{2})"}; /// \todo this should be an automatic check in the parent class, and the /// return type should be templated @@ -311,39 +317,39 @@ void FemtoDreamV0Selection::init(HistogramRegistry* QAregistry, HistogramRegistr o2::aod::femtodreamparticle::ParticleTypeName[part]); /// \todo initialize histograms for children tracks of v0s mQAHistogramRegistry->add((folderName + "/hPt").c_str(), - "; #it{p}_{T} (GeV/#it{c}); Entries", kTH1F, + "; #it{p}_{T} (GeV/#it{c}); Entries", o2::framework::kTH1F, {{1000, 0, 10}}); mQAHistogramRegistry->add((folderName + "/hEta").c_str(), "; #eta; Entries", - kTH1F, {{1000, -1, 1}}); + o2::framework::kTH1F, {{1000, -1, 1}}); mQAHistogramRegistry->add((folderName + "/hPhi").c_str(), "; #phi; Entries", - kTH1F, {{1000, 0, o2::constants::math::TwoPI}}); + o2::framework::kTH1F, {{1000, 0, o2::constants::math::TwoPI}}); mQAHistogramRegistry->add((folderName + "/hDaughDCA").c_str(), - "; DCA^{daugh} (cm); Entries", kTH1F, + "; DCA^{daugh} (cm); Entries", o2::framework::kTH1F, {{1000, 0, 10}}); mQAHistogramRegistry->add((folderName + "/hTransRadius").c_str(), - "; #it{r}_{xy} (cm); Entries", kTH1F, + "; #it{r}_{xy} (cm); Entries", o2::framework::kTH1F, {{1500, 0, 150}}); mQAHistogramRegistry->add((folderName + "/hDecayVtxX").c_str(), - "; #it{Vtx}_{x} (cm); Entries", kTH1F, + "; #it{Vtx}_{x} (cm); Entries", o2::framework::kTH1F, {{2000, 0, 200}}); mQAHistogramRegistry->add((folderName + "/hDecayVtxY").c_str(), - "; #it{Vtx}_{y} (cm)); Entries", kTH1F, + "; #it{Vtx}_{y} (cm)); Entries", o2::framework::kTH1F, {{2000, 0, 200}}); mQAHistogramRegistry->add((folderName + "/hDecayVtxZ").c_str(), - "; #it{Vtx}_{z} (cm); Entries", kTH1F, + "; #it{Vtx}_{z} (cm); Entries", o2::framework::kTH1F, {{2000, 0, 200}}); mQAHistogramRegistry->add((folderName + "/hCPA").c_str(), - "; #it{cos #theta_{p}}; Entries", kTH1F, + "; #it{cos #theta_{p}}; Entries", o2::framework::kTH1F, {{1000, 0.9, 1.}}); mQAHistogramRegistry->add((folderName + "/hCPAvsPt").c_str(), "; #it{p}_{T} (GeV/#it{c}); #it{cos #theta_{p}}", - kTH2F, {{8, 0.3, 4.3}, {1000, 0.9, 1.}}); - mQAHistogramRegistry->add((folderName + "/hInvMassLambda").c_str(), "", kTH1F, + o2::framework::kTH2F, {{8, 0.3, 4.3}, {1000, 0.9, 1.}}); + mQAHistogramRegistry->add((folderName + "/hInvMassLambda").c_str(), "", o2::framework::kTH1F, {massAxisLambda}); mQAHistogramRegistry->add((folderName + "/hInvMassAntiLambda").c_str(), "", - kTH1F, {massAxisAntiLambda}); + o2::framework::kTH1F, {massAxisAntiLambda}); mQAHistogramRegistry->add((folderName + "/hInvMassLambdaAntiLambda").c_str(), - "", kTH2F, {massAxisLambda, massAxisAntiLambda}); + "", o2::framework::kTH2F, {massAxisLambda, massAxisAntiLambda}); posDaughTrack.init( mQAHistogramRegistry, mHistogramRegistry); - mQAHistogramRegistry->add(folderName + "QA/hInvMassLambdaNoCuts", "No cuts", kTH1F, + mQAHistogramRegistry->add(folderName + "QA/hInvMassLambdaNoCuts", "No cuts", o2::framework::kTH1F, {massAxisLambda}); mQAHistogramRegistry->add(folderName + "QA/hInvMassLambdaInvMassCut", - "Invariant mass cut", kTH1F, {massAxisLambda}); + "Invariant mass cut", o2::framework::kTH1F, {massAxisLambda}); mQAHistogramRegistry->add(folderName + "QA/hInvMassLambdaPtMin", "Minimum Pt cut", - kTH1F, {massAxisLambda}); + o2::framework::kTH1F, {massAxisLambda}); mQAHistogramRegistry->add(folderName + "QA/hInvMassLambdaPtMax", "Maximum Pt cut", - kTH1F, {massAxisLambda}); + o2::framework::kTH1F, {massAxisLambda}); mQAHistogramRegistry->add(folderName + "QA/hInvMassLambdaEtaMax", "Maximum Eta cut", - kTH1F, {massAxisLambda}); + o2::framework::kTH1F, {massAxisLambda}); mQAHistogramRegistry->add(folderName + "QA/hInvMassLambdaDCAV0Daugh", - "V0-daughters DCA cut", kTH1F, {massAxisLambda}); - mQAHistogramRegistry->add(folderName + "QA/hInvMassLambdaCPA", "CPA cut", kTH1F, + "V0-daughters DCA cut", o2::framework::kTH1F, {massAxisLambda}); + mQAHistogramRegistry->add(folderName + "QA/hInvMassLambdaCPA", "CPA cut", o2::framework::kTH1F, {massAxisLambda}); mQAHistogramRegistry->add(folderName + "QA/hInvMassLambdaTranRadMin", - "Minimum transverse radius cut", kTH1F, + "Minimum transverse radius cut", o2::framework::kTH1F, {massAxisLambda}); mQAHistogramRegistry->add(folderName + "QA/hInvMassLambdaTranRadMax", - "Maximum transverse radius cut", kTH1F, + "Maximum transverse radius cut", o2::framework::kTH1F, {massAxisLambda}); mQAHistogramRegistry->add(folderName + "QA/hInvMassLambdaDecVtxMax", - "Maximum distance on decay vertex cut", kTH1F, + "Maximum distance on decay vertex cut", o2::framework::kTH1F, {massAxisLambda}); } diff --git a/PWGCF/FemtoDream/TableProducer/femtoDreamProducerReducedTask.cxx b/PWGCF/FemtoDream/TableProducer/femtoDreamProducerReducedTask.cxx index dc5fcc8a862..8d2a80b00c4 100644 --- a/PWGCF/FemtoDream/TableProducer/femtoDreamProducerReducedTask.cxx +++ b/PWGCF/FemtoDream/TableProducer/femtoDreamProducerReducedTask.cxx @@ -17,11 +17,12 @@ #include "PWGCF/DataModel/FemtoDerived.h" #include "PWGCF/FemtoDream/Core/femtoDreamCollisionSelection.h" +#include "PWGCF/FemtoDream/Core/femtoDreamSelection.h" #include "PWGCF/FemtoDream/Core/femtoDreamTrackSelection.h" #include "PWGCF/FemtoDream/Core/femtoDreamUtils.h" -#include "PWGLF/DataModel/LFStrangenessTables.h" -#include "Common/Core/trackUtilities.h" +#include "Common/CCDB/TriggerAliases.h" +#include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponseITS.h" @@ -29,19 +30,23 @@ #include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "CCDB/BasicCCDBManager.h" -#include "DataFormatsParameters/GRPMagField.h" -#include "DataFormatsParameters/GRPObject.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/runDataProcessing.h" -#include "ReconstructionDataFormats/Track.h" - -#include "Math/Vector4D.h" -#include "TMath.h" - +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include #include using namespace o2; diff --git a/PWGCF/FemtoDream/TableProducer/femtoDreamProducerTask.cxx b/PWGCF/FemtoDream/TableProducer/femtoDreamProducerTask.cxx index 15686d79e9b..9f47d915620 100644 --- a/PWGCF/FemtoDream/TableProducer/femtoDreamProducerTask.cxx +++ b/PWGCF/FemtoDream/TableProducer/femtoDreamProducerTask.cxx @@ -16,36 +16,49 @@ #include "PWGCF/DataModel/FemtoDerived.h" #include "PWGCF/FemtoDream/Core/femtoDreamCascadeSelection.h" #include "PWGCF/FemtoDream/Core/femtoDreamCollisionSelection.h" +#include "PWGCF/FemtoDream/Core/femtoDreamSelection.h" #include "PWGCF/FemtoDream/Core/femtoDreamTrackSelection.h" #include "PWGCF/FemtoDream/Core/femtoDreamUtils.h" #include "PWGCF/FemtoDream/Core/femtoDreamV0Selection.h" #include "PWGLF/DataModel/LFStrangenessTables.h" +#include "Common/CCDB/RCTSelectionFlags.h" +#include "Common/CCDB/TriggerAliases.h" #include "Common/Core/Zorro.h" -#include "Common/Core/trackUtilities.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponseITS.h" #include "Common/DataModel/PIDResponseTOF.h" #include "Common/DataModel/PIDResponseTPC.h" +#include "Common/DataModel/Qvectors.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "DataFormatsParameters/GRPMagField.h" -#include "DataFormatsParameters/GRPObject.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/runDataProcessing.h" -#include "ReconstructionDataFormats/Track.h" #include - -#include "Math/Vector4D.h" -#include "TMath.h" - -#include - +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include // IWYU pragma: keep (do not replace with Math/Vector4Dfwd.h) +#include +#include + +#include +#include +#include +#include +#include #include #include diff --git a/PWGCF/FemtoDream/TableProducer/femtoDreamProducerTaskForSpecificAnalysis.cxx b/PWGCF/FemtoDream/TableProducer/femtoDreamProducerTaskForSpecificAnalysis.cxx index 5823ce94d9f..d808767c9db 100644 --- a/PWGCF/FemtoDream/TableProducer/femtoDreamProducerTaskForSpecificAnalysis.cxx +++ b/PWGCF/FemtoDream/TableProducer/femtoDreamProducerTaskForSpecificAnalysis.cxx @@ -14,27 +14,26 @@ /// \author Laura Serksnyte, TU München, laura.serksnyte@tum.de #include "PWGCF/DataModel/FemtoDerived.h" -#include "PWGCF/FemtoDream/Core/femtoDreamContainerThreeBody.h" -#include "PWGCF/FemtoDream/Core/femtoDreamDetaDphiStar.h" -#include "PWGCF/FemtoDream/Core/femtoDreamEventHisto.h" -#include "PWGCF/FemtoDream/Core/femtoDreamPairCleaner.h" -#include "PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h" -#include "PWGCF/FemtoDream/Core/femtoDreamUtils.h" - -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/StepTHn.h" -#include "Framework/runDataProcessing.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include #include #include #include using namespace o2; -using namespace o2::analysis::femtoDream; using namespace o2::framework; using namespace o2::framework::expressions; using namespace o2::soa; diff --git a/PWGCF/FemtoDream/TableProducer/femtoDreamProducerTaskReso.cxx b/PWGCF/FemtoDream/TableProducer/femtoDreamProducerTaskReso.cxx index ecb1d3b4eac..9b0f753ef9c 100644 --- a/PWGCF/FemtoDream/TableProducer/femtoDreamProducerTaskReso.cxx +++ b/PWGCF/FemtoDream/TableProducer/femtoDreamProducerTaskReso.cxx @@ -17,13 +17,15 @@ #include "PWGCF/FemtoDream/Core/femtoDreamCascadeSelection.h" #include "PWGCF/FemtoDream/Core/femtoDreamCollisionSelection.h" #include "PWGCF/FemtoDream/Core/femtoDreamResoSelection.h" +#include "PWGCF/FemtoDream/Core/femtoDreamSelection.h" #include "PWGCF/FemtoDream/Core/femtoDreamTrackSelection.h" #include "PWGCF/FemtoDream/Core/femtoDreamUtils.h" #include "PWGCF/FemtoDream/Core/femtoDreamV0SelectionK0Short.h" #include "PWGLF/DataModel/LFStrangenessTables.h" +#include "Common/CCDB/RCTSelectionFlags.h" +#include "Common/CCDB/TriggerAliases.h" #include "Common/Core/Zorro.h" -#include "Common/Core/trackUtilities.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" @@ -32,23 +34,31 @@ #include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "DataFormatsParameters/GRPMagField.h" -#include "DataFormatsParameters/GRPObject.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/Expressions.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/runDataProcessing.h" -#include "ReconstructionDataFormats/Track.h" #include - -#include "Math/Vector4D.h" -#include "TMath.h" - -#include - +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include // IWYU pragma: keep (do not replace with Math/Vector4Dfwd.h) +#include + +#include +#include +#include +#include +#include #include #include diff --git a/PWGCF/FemtoDream/Tasks/femtoDreamCollisionMasker.cxx b/PWGCF/FemtoDream/Tasks/femtoDreamCollisionMasker.cxx index 1cb8c18caef..cdcf9c860a3 100644 --- a/PWGCF/FemtoDream/Tasks/femtoDreamCollisionMasker.cxx +++ b/PWGCF/FemtoDream/Tasks/femtoDreamCollisionMasker.cxx @@ -14,23 +14,25 @@ /// \author Anton Riedel, TU München, anton.riedel@tum.de /// \author Laura Serksnyte, TU München, laura.serksnyte@tum.de -#include -#include -#include -#include -#include -#include -#include +#include "PWGCF/DataModel/FemtoDerived.h" -#include "fairlogger/Logger.h" -#include "Framework/Configurable.h" -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/RunningWorkflowInfo.h" +#include +#include +#include +#include +#include +#include +#include +#include -#include "PWGCF/DataModel/FemtoDerived.h" +#include +#include +#include +#include +#include +#include +#include +#include using namespace o2; using namespace o2::aod; diff --git a/PWGCF/FemtoDream/Tasks/femtoDreamDebugCascade.cxx b/PWGCF/FemtoDream/Tasks/femtoDreamDebugCascade.cxx index 54324361ec0..f22bdcdbd4f 100644 --- a/PWGCF/FemtoDream/Tasks/femtoDreamDebugCascade.cxx +++ b/PWGCF/FemtoDream/Tasks/femtoDreamDebugCascade.cxx @@ -14,24 +14,27 @@ /// \author Luca Barioglio, TU München, luca.barioglio@cern.ch /// \author Georgios Mantzaridis, TU München, luca.barioglio@cern.ch -#include -#include -#include -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/StepTHn.h" -#include "DataFormatsParameters/GRPObject.h" -#include "fairlogger/Logger.h" - #include "PWGCF/DataModel/FemtoDerived.h" -#include "PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h" #include "PWGCF/FemtoDream/Core/femtoDreamEventHisto.h" #include "PWGCF/FemtoDream/Core/femtoDreamMath.h" +#include "PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h" #include "PWGCF/FemtoDream/Core/femtoDreamUtils.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + using namespace o2; using namespace o2::analysis::femtoDream; using namespace o2::framework; diff --git a/PWGCF/FemtoDream/Tasks/femtoDreamDebugReso.cxx b/PWGCF/FemtoDream/Tasks/femtoDreamDebugReso.cxx index 3e000bf69fa..d53ae5c126b 100644 --- a/PWGCF/FemtoDream/Tasks/femtoDreamDebugReso.cxx +++ b/PWGCF/FemtoDream/Tasks/femtoDreamDebugReso.cxx @@ -17,17 +17,20 @@ #include "PWGCF/FemtoDream/Core/femtoDreamEventHisto.h" #include "PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h" -#include "DataFormatsParameters/GRPObject.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/StepTHn.h" -#include "Framework/runDataProcessing.h" - -#include "TVector3.h" - -#include "fairlogger/Logger.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include #include #include diff --git a/PWGCF/FemtoDream/Tasks/femtoDreamDebugTrack.cxx b/PWGCF/FemtoDream/Tasks/femtoDreamDebugTrack.cxx index 77b1c245b67..729fecc4928 100644 --- a/PWGCF/FemtoDream/Tasks/femtoDreamDebugTrack.cxx +++ b/PWGCF/FemtoDream/Tasks/femtoDreamDebugTrack.cxx @@ -13,18 +13,24 @@ /// \brief Tasks that reads the particle tables and fills QA histograms for tracks /// \author Luca Barioglio, TU München, luca.barioglio@cern.ch -#include -#include "DataFormatsParameters/GRPObject.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/StepTHn.h" -#include "Framework/runDataProcessing.h" - +#include "PWGCF/DataModel/FemtoDerived.h" #include "PWGCF/FemtoDream/Core/femtoDreamEventHisto.h" #include "PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h" -#include "PWGCF/DataModel/FemtoDerived.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include using namespace o2; using namespace o2::analysis::femtoDream; diff --git a/PWGCF/FemtoDream/Tasks/femtoDreamDebugV0.cxx b/PWGCF/FemtoDream/Tasks/femtoDreamDebugV0.cxx index 81e7377f0b3..f82fb64330b 100644 --- a/PWGCF/FemtoDream/Tasks/femtoDreamDebugV0.cxx +++ b/PWGCF/FemtoDream/Tasks/femtoDreamDebugV0.cxx @@ -19,20 +19,22 @@ #include "PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h" #include "PWGCF/FemtoDream/Core/femtoDreamUtils.h" -#include "DataFormatsParameters/GRPObject.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/StepTHn.h" -#include "Framework/runDataProcessing.h" - -#include "TVector3.h" - -#include "fairlogger/Logger.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include #include -#include #include using namespace o2; diff --git a/PWGCF/FemtoDream/Tasks/femtoDreamHashTask.cxx b/PWGCF/FemtoDream/Tasks/femtoDreamHashTask.cxx index fe0aa6c0e3d..95116e0140e 100644 --- a/PWGCF/FemtoDream/Tasks/femtoDreamHashTask.cxx +++ b/PWGCF/FemtoDream/Tasks/femtoDreamHashTask.cxx @@ -15,10 +15,16 @@ /// \author Andi Mathis, TU München, andreas.mathis@ph.tum.de #include "PWGCF/DataModel/FemtoDerived.h" + #include "Common/Core/EventMixing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" -#include "Framework/ASoAHelpers.h" + +#include +#include +#include +#include +#include + +#include using namespace o2; using namespace o2::framework; diff --git a/PWGCF/FemtoDream/Tasks/femtoDreamPairEfficiency.cxx b/PWGCF/FemtoDream/Tasks/femtoDreamPairEfficiency.cxx index 620c7b33839..2a0a23900ea 100644 --- a/PWGCF/FemtoDream/Tasks/femtoDreamPairEfficiency.cxx +++ b/PWGCF/FemtoDream/Tasks/femtoDreamPairEfficiency.cxx @@ -19,7 +19,6 @@ #include "PWGLF/DataModel/mcCentrality.h" #include "PWGLF/Utils/inelGt.h" -#include "Common/Core/TrackSelection.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" @@ -28,19 +27,29 @@ #include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "CommonConstants/PhysicsConstants.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/Configurable.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/runDataProcessing.h" - -#include "TPDGCode.h" - -#include "fairlogger/Logger.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include #include +#include +#include +#include +#include #include #include diff --git a/PWGCF/FemtoDream/Tasks/femtoDreamPairTaskTrackCascade.cxx b/PWGCF/FemtoDream/Tasks/femtoDreamPairTaskTrackCascade.cxx index 0fbd3f7e3a3..35c5b4a64a1 100644 --- a/PWGCF/FemtoDream/Tasks/femtoDreamPairTaskTrackCascade.cxx +++ b/PWGCF/FemtoDream/Tasks/femtoDreamPairTaskTrackCascade.cxx @@ -17,16 +17,21 @@ #include "PWGCF/FemtoDream/Core/femtoDreamEventHisto.h" #include "PWGCF/FemtoDream/Core/femtoDreamPairCleaner.h" #include "PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h" -#include "PWGCF/FemtoDream/Core/femtoDreamUtils.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/Expressions.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/runDataProcessing.h" - -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include diff --git a/PWGCF/FemtoDream/Tasks/femtoDreamPairTaskTrackTrack.cxx b/PWGCF/FemtoDream/Tasks/femtoDreamPairTaskTrackTrack.cxx index 0d97ae5b676..5c087e14033 100644 --- a/PWGCF/FemtoDream/Tasks/femtoDreamPairTaskTrackTrack.cxx +++ b/PWGCF/FemtoDream/Tasks/femtoDreamPairTaskTrackTrack.cxx @@ -24,23 +24,32 @@ #include "PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h" #include "PWGCF/FemtoDream/Core/femtoDreamUtils.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/Configurable.h" -#include "Framework/Expressions.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/StepTHn.h" -#include "Framework/runDataProcessing.h" - -#include "TRandom3.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include #include #include #include #include +using namespace o2; using namespace o2::aod; using namespace o2::soa; using namespace o2::framework; diff --git a/PWGCF/FemtoDream/Tasks/femtoDreamPairTaskTrackV0.cxx b/PWGCF/FemtoDream/Tasks/femtoDreamPairTaskTrackV0.cxx index 7798f3d59c8..9fec3723f24 100644 --- a/PWGCF/FemtoDream/Tasks/femtoDreamPairTaskTrackV0.cxx +++ b/PWGCF/FemtoDream/Tasks/femtoDreamPairTaskTrackV0.cxx @@ -13,25 +13,36 @@ /// \brief Tasks that reads the track tables used for the pairing and builds pairs of two tracks /// \author Andi Mathis, TU München, andreas.mathis@ph.tum.de -#include -#include -#include -#include -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/Expressions.h" - #include "PWGCF/DataModel/FemtoDerived.h" -#include "PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h" -#include "PWGCF/FemtoDream/Core/femtoDreamEventHisto.h" -#include "PWGCF/FemtoDream/Core/femtoDreamPairCleaner.h" #include "PWGCF/FemtoDream/Core/femtoDreamContainer.h" #include "PWGCF/FemtoDream/Core/femtoDreamDetaDphiStar.h" +#include "PWGCF/FemtoDream/Core/femtoDreamEventHisto.h" +#include "PWGCF/FemtoDream/Core/femtoDreamPairCleaner.h" +#include "PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h" #include "PWGCF/FemtoDream/Core/femtoDreamUtils.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + using namespace o2; using namespace o2::aod; using namespace o2::soa; diff --git a/PWGCF/FemtoDream/Tasks/femtoDreamPairTaskV0Reso.cxx b/PWGCF/FemtoDream/Tasks/femtoDreamPairTaskV0Reso.cxx index 6702590a2bd..905d692bee0 100644 --- a/PWGCF/FemtoDream/Tasks/femtoDreamPairTaskV0Reso.cxx +++ b/PWGCF/FemtoDream/Tasks/femtoDreamPairTaskV0Reso.cxx @@ -19,23 +19,23 @@ #include "PWGCF/FemtoDream/Core/femtoDreamContainer.h" #include "PWGCF/FemtoDream/Core/femtoDreamDetaDphiStar.h" #include "PWGCF/FemtoDream/Core/femtoDreamEventHisto.h" -#include "PWGCF/FemtoDream/Core/femtoDreamPairCleaner.h" #include "PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h" -#include "PWGCF/FemtoDream/Core/femtoDreamUtils.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/Configurable.h" -#include "Framework/Expressions.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/StepTHn.h" -#include "Framework/runDataProcessing.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include -#include "TRandom3.h" - -#include #include #include #include diff --git a/PWGCF/FemtoDream/Tasks/femtoDreamPairTaskV0V0.cxx b/PWGCF/FemtoDream/Tasks/femtoDreamPairTaskV0V0.cxx index 869a7124191..234b44a8a38 100644 --- a/PWGCF/FemtoDream/Tasks/femtoDreamPairTaskV0V0.cxx +++ b/PWGCF/FemtoDream/Tasks/femtoDreamPairTaskV0V0.cxx @@ -20,27 +20,30 @@ #include "PWGCF/FemtoDream/Core/femtoDreamContainer.h" #include "PWGCF/FemtoDream/Core/femtoDreamDetaDphiStar.h" #include "PWGCF/FemtoDream/Core/femtoDreamEventHisto.h" -#include "PWGCF/FemtoDream/Core/femtoDreamPairCleaner.h" #include "PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h" -#include "PWGCF/FemtoDream/Core/femtoDreamUtils.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/Configurable.h" -#include "Framework/Expressions.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/StepTHn.h" -#include "Framework/runDataProcessing.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include -#include "TRandom3.h" - -#include #include #include #include +using namespace o2; using namespace o2::aod; using namespace o2::soa; using namespace o2::framework; diff --git a/PWGCF/FemtoDream/Tasks/femtoDreamTripletTaskTrackTrackTrack.cxx b/PWGCF/FemtoDream/Tasks/femtoDreamTripletTaskTrackTrackTrack.cxx index 48eb15ec7fe..7af5db93467 100644 --- a/PWGCF/FemtoDream/Tasks/femtoDreamTripletTaskTrackTrackTrack.cxx +++ b/PWGCF/FemtoDream/Tasks/femtoDreamTripletTaskTrackTrackTrack.cxx @@ -13,25 +13,39 @@ /// \brief Tasks that reads the track tables and creates track triplets; only three identical particles can be used /// \author Laura Serksnyte, TU München, laura.serksnyte@tum.de -#include -#include -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/StepTHn.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "TDatabasePDG.h" - #include "PWGCF/DataModel/FemtoDerived.h" -#include "PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h" -#include "PWGCF/FemtoDream/Core/femtoDreamEventHisto.h" -#include "PWGCF/FemtoDream/Core/femtoDreamPairCleaner.h" #include "PWGCF/FemtoDream/Core/femtoDreamContainerThreeBody.h" #include "PWGCF/FemtoDream/Core/femtoDreamDetaDphiStar.h" +#include "PWGCF/FemtoDream/Core/femtoDreamEventHisto.h" +#include "PWGCF/FemtoDream/Core/femtoDreamMath.h" +#include "PWGCF/FemtoDream/Core/femtoDreamPairCleaner.h" +#include "PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h" #include "PWGCF/FemtoDream/Core/femtoDreamUtils.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + using namespace o2; using namespace o2::analysis::femtoDream; using namespace o2::framework; diff --git a/PWGCF/FemtoDream/Tasks/femtoDreamTripletTaskTrackTrackTrackPbPb.cxx b/PWGCF/FemtoDream/Tasks/femtoDreamTripletTaskTrackTrackTrackPbPb.cxx index 698aa5e6c63..a92d54332f8 100644 --- a/PWGCF/FemtoDream/Tasks/femtoDreamTripletTaskTrackTrackTrackPbPb.cxx +++ b/PWGCF/FemtoDream/Tasks/femtoDreamTripletTaskTrackTrackTrackPbPb.cxx @@ -17,20 +17,32 @@ #include "PWGCF/FemtoDream/Core/femtoDreamContainerThreeBody.h" #include "PWGCF/FemtoDream/Core/femtoDreamDetaDphiStar.h" #include "PWGCF/FemtoDream/Core/femtoDreamEventHisto.h" +#include "PWGCF/FemtoDream/Core/femtoDreamMath.h" #include "PWGCF/FemtoDream/Core/femtoDreamPairCleaner.h" #include "PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h" #include "PWGCF/FemtoDream/Core/femtoDreamUtils.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/StepTHn.h" -#include "Framework/runDataProcessing.h" - -#include "TDatabasePDG.h" - +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include #include #include diff --git a/PWGCF/FemtoDream/Tasks/femtoDreamTripletTaskTrackTrackV0.cxx b/PWGCF/FemtoDream/Tasks/femtoDreamTripletTaskTrackTrackV0.cxx index 136b8f9d5ff..ce37fa91140 100644 --- a/PWGCF/FemtoDream/Tasks/femtoDreamTripletTaskTrackTrackV0.cxx +++ b/PWGCF/FemtoDream/Tasks/femtoDreamTripletTaskTrackTrackV0.cxx @@ -13,26 +13,39 @@ /// \brief Tasks that reads the track and V0 tables and creates triplets; only two identical tracks and a V0 can be used /// \author Laura Serksnyte, TU München, laura.serksnyte@tum.de -#include -#include -#include -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/StepTHn.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "TDatabasePDG.h" - #include "PWGCF/DataModel/FemtoDerived.h" -#include "PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h" -#include "PWGCF/FemtoDream/Core/femtoDreamEventHisto.h" -#include "PWGCF/FemtoDream/Core/femtoDreamPairCleaner.h" #include "PWGCF/FemtoDream/Core/femtoDreamContainerThreeBody.h" #include "PWGCF/FemtoDream/Core/femtoDreamDetaDphiStar.h" +#include "PWGCF/FemtoDream/Core/femtoDreamEventHisto.h" +#include "PWGCF/FemtoDream/Core/femtoDreamMath.h" +#include "PWGCF/FemtoDream/Core/femtoDreamPairCleaner.h" +#include "PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h" #include "PWGCF/FemtoDream/Core/femtoDreamUtils.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + using namespace o2; using namespace o2::analysis::femtoDream; using namespace o2::framework; diff --git a/PWGCF/FemtoDream/Tasks/femtoDreamTripletTaskTrackTrackV0PbPb.cxx b/PWGCF/FemtoDream/Tasks/femtoDreamTripletTaskTrackTrackV0PbPb.cxx index 32e5a81a5f8..f58c1deaf6e 100644 --- a/PWGCF/FemtoDream/Tasks/femtoDreamTripletTaskTrackTrackV0PbPb.cxx +++ b/PWGCF/FemtoDream/Tasks/femtoDreamTripletTaskTrackTrackV0PbPb.cxx @@ -18,19 +18,31 @@ #include "PWGCF/FemtoDream/Core/femtoDreamContainerThreeBody.h" #include "PWGCF/FemtoDream/Core/femtoDreamDetaDphiStar.h" #include "PWGCF/FemtoDream/Core/femtoDreamEventHisto.h" +#include "PWGCF/FemtoDream/Core/femtoDreamMath.h" #include "PWGCF/FemtoDream/Core/femtoDreamPairCleaner.h" #include "PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h" #include "PWGCF/FemtoDream/Core/femtoDreamUtils.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/StepTHn.h" -#include "Framework/runDataProcessing.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include #include #include diff --git a/PWGCF/FemtoDream/Tasks/femtodreamPairCascadeCascade.cxx b/PWGCF/FemtoDream/Tasks/femtodreamPairCascadeCascade.cxx index fbf164378a1..ca4e27c7327 100644 --- a/PWGCF/FemtoDream/Tasks/femtodreamPairCascadeCascade.cxx +++ b/PWGCF/FemtoDream/Tasks/femtodreamPairCascadeCascade.cxx @@ -19,16 +19,21 @@ #include "PWGCF/FemtoDream/Core/femtoDreamEventHisto.h" #include "PWGCF/FemtoDream/Core/femtoDreamPairCleaner.h" #include "PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h" -#include "PWGCF/FemtoDream/Core/femtoDreamUtils.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/Expressions.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/runDataProcessing.h" - -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include diff --git a/PWGCF/FemtoDream/Utils/femtoDreamCutCulator.cxx b/PWGCF/FemtoDream/Utils/femtoDreamCutCulator.cxx index d6aa862851f..e5373d8e58f 100644 --- a/PWGCF/FemtoDream/Utils/femtoDreamCutCulator.cxx +++ b/PWGCF/FemtoDream/Utils/femtoDreamCutCulator.cxx @@ -13,13 +13,11 @@ /// \brief Executable that encodes physical selection criteria in a bit-wise /// selection \author Andi Mathis, TU München, andreas.mathis@ph.tum.de +#include "PWGCF/FemtoDream/Utils/femtoDreamCutCulator.h" + +#include #include -#include #include -#include "PWGCF/FemtoDream/Utils/femtoDreamCutCulator.h" -#include "PWGCF/FemtoDream/Core/femtoDreamSelection.h" -#include "PWGCF/FemtoDream/Core/femtoDreamTrackSelection.h" -#include "PWGCF/DataModel/FemtoDerived.h" using namespace o2::analysis::femtoDream; diff --git a/PWGCF/FemtoDream/Utils/femtoDreamCutCulator.h b/PWGCF/FemtoDream/Utils/femtoDreamCutCulator.h index f54a9ff62a4..5e41fb5187f 100644 --- a/PWGCF/FemtoDream/Utils/femtoDreamCutCulator.h +++ b/PWGCF/FemtoDream/Utils/femtoDreamCutCulator.h @@ -18,21 +18,27 @@ #ifndef PWGCF_FEMTODREAM_UTILS_FEMTODREAMCUTCULATOR_H_ #define PWGCF_FEMTODREAM_UTILS_FEMTODREAMCUTCULATOR_H_ +#include "PWGCF/DataModel/FemtoDerived.h" +#include "PWGCF/FemtoDream/Core/femtoDreamCascadeSelection.h" +#include "PWGCF/FemtoDream/Core/femtoDreamSelection.h" +#include "PWGCF/FemtoDream/Core/femtoDreamTrackSelection.h" +#include "PWGCF/FemtoDream/Core/femtoDreamV0Selection.h" + +#include + +#include +#include +#include +#include + +#include #include +#include #include #include #include #include #include -#include -#include -#include -#include - -#include "PWGCF/FemtoDream/Core/femtoDreamSelection.h" -#include "PWGCF/FemtoDream/Core/femtoDreamTrackSelection.h" -#include "PWGCF/FemtoDream/Core/femtoDreamV0Selection.h" -#include "PWGCF/FemtoDream/Core/femtoDreamCascadeSelection.h" namespace o2::analysis::femtoDream { diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverse3DContainer.h b/PWGCF/FemtoUniverse/Core/FemtoUniverse3DContainer.h index d0b33319ffd..bfbf61efe86 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniverse3DContainer.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniverse3DContainer.h @@ -18,20 +18,17 @@ #define PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSE3DCONTAINER_H_ #include "PWGCF/FemtoUniverse/Core/FemtoUniverseMath.h" -#include "PWGCF/FemtoUniverse/Core/FemtoUniverseParticleHisto.h" +#include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" -#include "Framework/HistogramRegistry.h" -#include +#include +#include -#include "Math/Vector4D.h" -#include "TDatabasePDG.h" -#include "TMath.h" +#include #include +#include #include -using namespace o2::framework; - namespace o2::analysis::femto_universe { @@ -80,30 +77,30 @@ class FemtoUniverse3DContainer template void initBase(std::string folderName, std::string femtoObs1D, std::string femtoObsKout, std::string femtoObsKside, std::string femtoObsKlong, T femtoObsAxis1D, T femtoObsAxisOut, T femtoObsAxisSide, T femtoObsAxisLong, T multAxis, T kTAxis, T mTAxis, T multAxis3D, T mTAxis3D, bool use3dplots, bool isiden) { - mHistogramRegistry->add((folderName + "/relPairMom3D").c_str(), ("; " + femtoObsKout + "; " + femtoObsKside + "; " + femtoObsKlong).c_str(), kTH3F, {femtoObsAxisOut, femtoObsAxisSide, femtoObsAxisLong}); - mHistogramRegistry->add((folderName + "/relPairMomOut").c_str(), ("; " + femtoObsKout + "; Entries").c_str(), kTH1F, {femtoObsAxisOut}); - mHistogramRegistry->add((folderName + "/relPairMomSide").c_str(), ("; " + femtoObsKside + "; Entries").c_str(), kTH1F, {femtoObsAxisSide}); - mHistogramRegistry->add((folderName + "/relPairMomLong").c_str(), ("; " + femtoObsKlong + "; Entries").c_str(), kTH1F, {femtoObsAxisLong}); - mHistogramRegistry->add((folderName + "/relPairMom1D").c_str(), ("; " + femtoObs1D + "; Entries").c_str(), kTH1F, {femtoObsAxis1D}); + mHistogramRegistry->add((folderName + "/relPairMom3D").c_str(), ("; " + femtoObsKout + "; " + femtoObsKside + "; " + femtoObsKlong).c_str(), o2::framework::kTH3F, {femtoObsAxisOut, femtoObsAxisSide, femtoObsAxisLong}); + mHistogramRegistry->add((folderName + "/relPairMomOut").c_str(), ("; " + femtoObsKout + "; Entries").c_str(), o2::framework::kTH1F, {femtoObsAxisOut}); + mHistogramRegistry->add((folderName + "/relPairMomSide").c_str(), ("; " + femtoObsKside + "; Entries").c_str(), o2::framework::kTH1F, {femtoObsAxisSide}); + mHistogramRegistry->add((folderName + "/relPairMomLong").c_str(), ("; " + femtoObsKlong + "; Entries").c_str(), o2::framework::kTH1F, {femtoObsAxisLong}); + mHistogramRegistry->add((folderName + "/relPairMom1D").c_str(), ("; " + femtoObs1D + "; Entries").c_str(), o2::framework::kTH1F, {femtoObsAxis1D}); if (!isiden) { - mHistogramRegistry->add((folderName + "/KStarOutP").c_str(), ("; " + femtoObs1D + "; Entries").c_str(), kTH1F, {femtoObsAxis1D}); - mHistogramRegistry->add((folderName + "/KStarSideP").c_str(), ("; " + femtoObs1D + "; Entries").c_str(), kTH1F, {femtoObsAxis1D}); - mHistogramRegistry->add((folderName + "/KStarLongP").c_str(), ("; " + femtoObs1D + "; Entries").c_str(), kTH1F, {femtoObsAxis1D}); - mHistogramRegistry->add((folderName + "/KStarOutN").c_str(), ("; " + femtoObs1D + "; Entries").c_str(), kTH1F, {femtoObsAxis1D}); - mHistogramRegistry->add((folderName + "/KStarSideN").c_str(), ("; " + femtoObs1D + "; Entries").c_str(), kTH1F, {femtoObsAxis1D}); - mHistogramRegistry->add((folderName + "/KStarLongN").c_str(), ("; " + femtoObs1D + "; Entries").c_str(), kTH1F, {femtoObsAxis1D}); + mHistogramRegistry->add((folderName + "/KStarOutP").c_str(), ("; " + femtoObs1D + "; Entries").c_str(), o2::framework::kTH1F, {femtoObsAxis1D}); + mHistogramRegistry->add((folderName + "/KStarSideP").c_str(), ("; " + femtoObs1D + "; Entries").c_str(), o2::framework::kTH1F, {femtoObsAxis1D}); + mHistogramRegistry->add((folderName + "/KStarLongP").c_str(), ("; " + femtoObs1D + "; Entries").c_str(), o2::framework::kTH1F, {femtoObsAxis1D}); + mHistogramRegistry->add((folderName + "/KStarOutN").c_str(), ("; " + femtoObs1D + "; Entries").c_str(), o2::framework::kTH1F, {femtoObsAxis1D}); + mHistogramRegistry->add((folderName + "/KStarSideN").c_str(), ("; " + femtoObs1D + "; Entries").c_str(), o2::framework::kTH1F, {femtoObsAxis1D}); + mHistogramRegistry->add((folderName + "/KStarLongN").c_str(), ("; " + femtoObs1D + "; Entries").c_str(), o2::framework::kTH1F, {femtoObsAxis1D}); } - mHistogramRegistry->add((folderName + "/relPairkT").c_str(), "; #it{k}_{T} (GeV/#it{c}); Entries", kTH1F, {kTAxis}); - mHistogramRegistry->add((folderName + "/relPairkstarkT").c_str(), ("; " + femtoObs1D + "; #it{k}_{T} (GeV/#it{c})").c_str(), kTH2F, {femtoObsAxis1D, kTAxis}); - mHistogramRegistry->add((folderName + "/relPairkstarmT").c_str(), ("; " + femtoObs1D + "; #it{m}_{T} (GeV/#it{c}^{2})").c_str(), kTH2F, {femtoObsAxis1D, mTAxis}); - mHistogramRegistry->add((folderName + "/relPairkstarMult").c_str(), ("; " + femtoObs1D + "; Multiplicity").c_str(), kTH2F, {femtoObsAxis1D, multAxis}); - mHistogramRegistry->add((folderName + "/kstarPtPart1").c_str(), ("; " + femtoObs1D + "; #it{p} _{T} Particle 1 (GeV/#it{c})").c_str(), kTH2F, {femtoObsAxis1D, {375, 0., 7.5}}); - mHistogramRegistry->add((folderName + "/kstarPtPart2").c_str(), ("; " + femtoObs1D + "; #it{p} _{T} Particle 2 (GeV/#it{c})").c_str(), kTH2F, {femtoObsAxis1D, {375, 0., 7.5}}); - mHistogramRegistry->add((folderName + "/MultPtPart1").c_str(), "; #it{p} _{T} Particle 1 (GeV/#it{c}); Multiplicity", kTH2F, {{375, 0., 7.5}, multAxis}); - mHistogramRegistry->add((folderName + "/MultPtPart2").c_str(), "; #it{p} _{T} Particle 2 (GeV/#it{c}); Multiplicity", kTH2F, {{375, 0., 7.5}, multAxis}); - mHistogramRegistry->add((folderName + "/PtPart1PtPart2").c_str(), "; #it{p} _{T} Particle 1 (GeV/#it{c}); #it{p} _{T} Particle 2 (GeV/#it{c})", kTH2F, {{375, 0., 7.5}, {375, 0., 7.5}}); + mHistogramRegistry->add((folderName + "/relPairkT").c_str(), "; #it{k}_{T} (GeV/#it{c}); Entries", o2::framework::kTH1F, {kTAxis}); + mHistogramRegistry->add((folderName + "/relPairkstarkT").c_str(), ("; " + femtoObs1D + "; #it{k}_{T} (GeV/#it{c})").c_str(), o2::framework::kTH2F, {femtoObsAxis1D, kTAxis}); + mHistogramRegistry->add((folderName + "/relPairkstarmT").c_str(), ("; " + femtoObs1D + "; #it{m}_{T} (GeV/#it{c}^{2})").c_str(), o2::framework::kTH2F, {femtoObsAxis1D, mTAxis}); + mHistogramRegistry->add((folderName + "/relPairkstarMult").c_str(), ("; " + femtoObs1D + "; Multiplicity").c_str(), o2::framework::kTH2F, {femtoObsAxis1D, multAxis}); + mHistogramRegistry->add((folderName + "/kstarPtPart1").c_str(), ("; " + femtoObs1D + "; #it{p} _{T} Particle 1 (GeV/#it{c})").c_str(), o2::framework::kTH2F, {femtoObsAxis1D, {375, 0., 7.5}}); + mHistogramRegistry->add((folderName + "/kstarPtPart2").c_str(), ("; " + femtoObs1D + "; #it{p} _{T} Particle 2 (GeV/#it{c})").c_str(), o2::framework::kTH2F, {femtoObsAxis1D, {375, 0., 7.5}}); + mHistogramRegistry->add((folderName + "/MultPtPart1").c_str(), "; #it{p} _{T} Particle 1 (GeV/#it{c}); Multiplicity", o2::framework::kTH2F, {{375, 0., 7.5}, multAxis}); + mHistogramRegistry->add((folderName + "/MultPtPart2").c_str(), "; #it{p} _{T} Particle 2 (GeV/#it{c}); Multiplicity", o2::framework::kTH2F, {{375, 0., 7.5}, multAxis}); + mHistogramRegistry->add((folderName + "/PtPart1PtPart2").c_str(), "; #it{p} _{T} Particle 1 (GeV/#it{c}); #it{p} _{T} Particle 2 (GeV/#it{c})", o2::framework::kTH2F, {{375, 0., 7.5}, {375, 0., 7.5}}); if (use3dplots) { - mHistogramRegistry->add((folderName + "/relPairkstarmTMult").c_str(), ("; " + femtoObs1D + "; #it{m}_{T} (GeV/#it{c}^{2}); Multiplicity").c_str(), kTH3F, {femtoObsAxis1D, mTAxis3D, multAxis3D}); + mHistogramRegistry->add((folderName + "/relPairkstarmTMult").c_str(), ("; " + femtoObs1D + "; #it{m}_{T} (GeV/#it{c}^{2}); Multiplicity").c_str(), o2::framework::kTH3F, {femtoObsAxis1D, mTAxis3D, multAxis3D}); } } @@ -119,7 +116,7 @@ class FemtoUniverse3DContainer /// \param use3dplots Flag to fill 3D plots /// \param isiden Identical or non-identical particle pair template - void init(HistogramRegistry* registry, T& kstarBins, T& multBins, T& kTBins, T& mTBins, T& multBins3D, T& mTBins3D, bool /*isMC*/, bool use3dplots, bool isiden) + void init(o2::framework::HistogramRegistry* registry, T& kstarBins, T& multBins, T& kTBins, T& mTBins, T& multBins3D, T& mTBins3D, bool /*isMC*/, bool use3dplots, bool isiden) { mHistogramRegistry = registry; std::string femtoObs1D, femtoObsKout, femtoObsKside, femtoObsKlong; @@ -266,7 +263,7 @@ class FemtoUniverse3DContainer } protected: - HistogramRegistry* mHistogramRegistry = nullptr; ///< For QA output + o2::framework::HistogramRegistry* mHistogramRegistry = nullptr; ///< For QA output static constexpr std::string_view FolderSuffix[2] = {"SameEvent", "MixedEvent"}; ///< Folder naming for the output according to EventType static constexpr int EventType = eventType; ///< Type of the event (same/mixed, according to femto_universe3d_container::EventType) float mMassOne = 0.f; ///< PDG mass of particle 1 diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverseAngularContainer.h b/PWGCF/FemtoUniverse/Core/FemtoUniverseAngularContainer.h index 4a1fb507b4a..6eba7405571 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniverseAngularContainer.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniverseAngularContainer.h @@ -21,22 +21,18 @@ #define PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSEANGULARCONTAINER_H_ #include "PWGCF/FemtoUniverse/Core/FemtoUniverseMath.h" -#include "PWGCF/FemtoUniverse/Core/FemtoUniverseParticleHisto.h" +#include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" -#include "Common/Core/RecoDecay.h" +#include +#include +#include -#include "Framework/HistogramRegistry.h" -#include - -#include "Math/Vector4D.h" -#include "TDatabasePDG.h" -#include "TMath.h" +#include #include +#include #include -using namespace o2::framework; - namespace o2::analysis::femto_universe { @@ -77,7 +73,7 @@ class FemtoUniverseAngularContainer template void initBase(std::string folderName, std::string /*femtoObs*/, T /*femtoObsAxis*/, T /*multAxis*/, T /*kTAxis*/, T /*mTAxis*/, T /*multAxis3D*/, T /*mTAxis3D*/, T etaAxis, T phiAxis, bool use3dplots) { - mHistogramRegistry->add((folderName + "/DeltaEtaDeltaPhi").c_str(), "; #Delta#varphi (rad); #Delta#eta", kTH2F, {phiAxis, etaAxis}); + mHistogramRegistry->add((folderName + "/DeltaEtaDeltaPhi").c_str(), "; #Delta#varphi (rad); #Delta#eta", o2::framework::kTH2F, {phiAxis, etaAxis}); if (use3dplots) { // use 3d plots } @@ -106,7 +102,7 @@ class FemtoUniverseAngularContainer /// \param phiBins phi binning for the histograms /// \param isMC add Monte Carlo truth histograms to the output file template - void init(HistogramRegistry* registry, T& kstarBins, T& multBins, T& kTBins, T& mTBins, T& multBins3D, T& mTBins3D, P& etaBins, P& phiBins, bool isMC, bool use3dplots) + void init(o2::framework::HistogramRegistry* registry, T& kstarBins, T& multBins, T& kTBins, T& mTBins, T& multBins3D, T& mTBins3D, P& etaBins, P& phiBins, bool isMC, bool use3dplots) { mHistogramRegistry = registry; std::string femtoObs; @@ -232,7 +228,7 @@ class FemtoUniverseAngularContainer } protected: - HistogramRegistry* mHistogramRegistry = nullptr; ///< For QA output + o2::framework::HistogramRegistry* mHistogramRegistry = nullptr; ///< For QA output static constexpr std::string_view FolderSuffix[2] = {"SameEvent", "MixedEvent"}; ///< Folder naming for the output according to EventType static constexpr femto_universe_angular_container::Observable FemtoObs = obs; ///< Femtoscopic observable to be computed (according to femto_universe_angular_container::Observable) static constexpr int EventType = eventType; ///< Type of the event (same/mixed, according to femto_universe_angular_container::EventType) diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverseCascadeSelection.h b/PWGCF/FemtoUniverse/Core/FemtoUniverseCascadeSelection.h index 4bb024288e0..5c989ba580c 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniverseCascadeSelection.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniverseCascadeSelection.h @@ -24,13 +24,15 @@ #include "PWGCF/FemtoUniverse/Core/FemtoUniverseObjectSelection.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseSelection.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseTrackSelection.h" +#include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" -#include "Common/Core/RecoDecay.h" - -#include "Framework/HistogramRegistry.h" -#include "ReconstructionDataFormats/PID.h" +#include +#include +#include +#include #include +#include #include namespace o2::analysis::femto_universe @@ -90,7 +92,7 @@ class FemtoUniverseCascadeSelection /// Initializes histograms for the task template - void init(HistogramRegistry* registry /*, bool isSelectCascOmega = false*/); + void init(o2::framework::HistogramRegistry* registry /*, bool isSelectCascOmega = false*/); template bool isSelectedMinimal(Col const& col, Casc const& cascade, Track const& posTrack, Track const& negTrack, Track const& bachTrack); @@ -290,7 +292,7 @@ class FemtoUniverseCascadeSelection }; // namespace femto_universe template -void FemtoUniverseCascadeSelection::init(HistogramRegistry* registry) +void FemtoUniverseCascadeSelection::init(o2::framework::HistogramRegistry* registry) { if (registry) { @@ -299,15 +301,15 @@ void FemtoUniverseCascadeSelection::init(HistogramRegistry* registry) fillSelectionHistogram(); // pos, neg fillSelectionHistogram(); // bach - AxisSpec massAxisCascade = {2200, 1.25f, 1.8f, "m_{Cascade} (GeV/#it{c}^{2})"}; - AxisSpec massAxisV0 = {600, 0.0f, 3.0f, "m_{V0} (GeV/#it{c}^{2})"}; - AxisSpec aDCADaughAxis = {1000, 0.0f, 2.0f, "DCA (cm)"}; - AxisSpec aDCAToPVAxis = {1000, -10.0f, 10.0f, "DCA to PV (cm)"}; - AxisSpec ptAxis = {100, 0.0f, 10.0f, "#it{p}_{T} (GeV/#it{c})"}; - AxisSpec etaAxis = {100, -2.0f, 2.0f, "#it{#eta}"}; - AxisSpec phiAxis = {100, 0.0f, 6.0f, "#it{#phi}"}; - AxisSpec aCPAAxis = {1000, 0.95f, 1.0f, "#it{cos #theta_{p}}"}; - AxisSpec tranRadAxis = {1000, 0.0f, 100.0f, "#it{r}_{xy} (cm)"}; + o2::framework::AxisSpec massAxisCascade = {2200, 1.25f, 1.8f, "m_{Cascade} (GeV/#it{c}^{2})"}; + o2::framework::AxisSpec massAxisV0 = {600, 0.0f, 3.0f, "m_{V0} (GeV/#it{c}^{2})"}; + o2::framework::AxisSpec aDCADaughAxis = {1000, 0.0f, 2.0f, "DCA (cm)"}; + o2::framework::AxisSpec aDCAToPVAxis = {1000, -10.0f, 10.0f, "DCA to PV (cm)"}; + o2::framework::AxisSpec ptAxis = {100, 0.0f, 10.0f, "#it{p}_{T} (GeV/#it{c})"}; + o2::framework::AxisSpec etaAxis = {100, -2.0f, 2.0f, "#it{#eta}"}; + o2::framework::AxisSpec phiAxis = {100, 0.0f, 6.0f, "#it{#phi}"}; + o2::framework::AxisSpec aCPAAxis = {1000, 0.95f, 1.0f, "#it{cos #theta_{p}}"}; + o2::framework::AxisSpec tranRadAxis = {1000, 0.0f, 100.0f, "#it{r}_{xy} (cm)"}; /// \todo this should be an automatic check in the parent class, and the /// return type should be templated @@ -331,27 +333,27 @@ void FemtoUniverseCascadeSelection::init(HistogramRegistry* registry) mHistogramRegistry); // V0 (Lambda) - // mHistogramRegistry->add("CascadeQA/hInvMassV0NoCuts", "No cuts", kTH1F, {massAxisV0}); - mHistogramRegistry->add("CascadeQA/hInvMassV0Cut", "Invariant mass cut", kTH1F, {massAxisV0}); - mHistogramRegistry->add("CascadeQA/hDCAV0Daugh", "V0-daughters DCA", kTH1F, {aDCADaughAxis}); - mHistogramRegistry->add("CascadeQA/hV0CPA", "V0 cos PA", kTH1F, {aCPAAxis}); - mHistogramRegistry->add("CascadeQA/hV0TranRad", "V0 transverse radius", kTH1F, {tranRadAxis}); - // mHistogramRegistry->add("CascadeQA/hV0DecVtxMax", "V0 maximum distance on decay vertex", kTH1F, {massAxisV0}); + // mHistogramRegistry->add("CascadeQA/hInvMassV0NoCuts", "No cuts", o2::framework::kTH1F, {massAxisV0}); + mHistogramRegistry->add("CascadeQA/hInvMassV0Cut", "Invariant mass cut", o2::framework::kTH1F, {massAxisV0}); + mHistogramRegistry->add("CascadeQA/hDCAV0Daugh", "V0-daughters DCA", o2::framework::kTH1F, {aDCADaughAxis}); + mHistogramRegistry->add("CascadeQA/hV0CPA", "V0 cos PA", o2::framework::kTH1F, {aCPAAxis}); + mHistogramRegistry->add("CascadeQA/hV0TranRad", "V0 transverse radius", o2::framework::kTH1F, {tranRadAxis}); + // mHistogramRegistry->add("CascadeQA/hV0DecVtxMax", "V0 maximum distance on decay vertex", o2::framework::kTH1F, {massAxisV0}); // Cascade (Xi, Omega) - // mHistogramRegistry->add("CascadeQA/hInvMassCascadeNoCuts", "No cuts", kTH1F, {massAxisCascade}); - mHistogramRegistry->add("CascadeQA/hInvMassXiCut", "Invariant mass with cut", kTH1F, {massAxisCascade}); - mHistogramRegistry->add("CascadeQA/hInvMassOmegaCut", "Invariant mass with cut", kTH1F, {massAxisCascade}); - mHistogramRegistry->add("CascadeQA/hCascadePt", "pT distribution", kTH1F, {ptAxis}); - mHistogramRegistry->add("CascadeQA/hCascadeEta", "Eta distribution", kTH1F, {etaAxis}); - mHistogramRegistry->add("CascadeQA/hCascadePhi", "Phi distribution", kTH1F, {phiAxis}); - mHistogramRegistry->add("CascadeQA/hDCACascadeDaugh", "Cascade-daughters DCA", kTH1F, {aDCADaughAxis}); - mHistogramRegistry->add("CascadeQA/hCascadeCPA", "Cos PA", kTH1F, {aCPAAxis}); - mHistogramRegistry->add("CascadeQA/hCascadeTranRad", "Transverse radius", kTH1F, {tranRadAxis}); - mHistogramRegistry->add("CascadeQA/hDCAPosToPV", "Pos V0 daughter DCA to primary vertex", kTH1F, {aDCAToPVAxis}); - mHistogramRegistry->add("CascadeQA/hDCANegToPV", "Neg V0 daughter DCA to primary vertex", kTH1F, {aDCAToPVAxis}); - mHistogramRegistry->add("CascadeQA/hDCABachToPV", "Bachelor DCA to primary vertex", kTH1F, {aDCAToPVAxis}); - mHistogramRegistry->add("CascadeQA/hDCAV0ToPV", "V0 DCA to primary vertex", kTH1F, {aDCAToPVAxis}); + // mHistogramRegistry->add("CascadeQA/hInvMassCascadeNoCuts", "No cuts", o2::framework::kTH1F, {massAxisCascade}); + mHistogramRegistry->add("CascadeQA/hInvMassXiCut", "Invariant mass with cut", o2::framework::kTH1F, {massAxisCascade}); + mHistogramRegistry->add("CascadeQA/hInvMassOmegaCut", "Invariant mass with cut", o2::framework::kTH1F, {massAxisCascade}); + mHistogramRegistry->add("CascadeQA/hCascadePt", "pT distribution", o2::framework::kTH1F, {ptAxis}); + mHistogramRegistry->add("CascadeQA/hCascadeEta", "Eta distribution", o2::framework::kTH1F, {etaAxis}); + mHistogramRegistry->add("CascadeQA/hCascadePhi", "Phi distribution", o2::framework::kTH1F, {phiAxis}); + mHistogramRegistry->add("CascadeQA/hDCACascadeDaugh", "Cascade-daughters DCA", o2::framework::kTH1F, {aDCADaughAxis}); + mHistogramRegistry->add("CascadeQA/hCascadeCPA", "Cos PA", o2::framework::kTH1F, {aCPAAxis}); + mHistogramRegistry->add("CascadeQA/hCascadeTranRad", "Transverse radius", o2::framework::kTH1F, {tranRadAxis}); + mHistogramRegistry->add("CascadeQA/hDCAPosToPV", "Pos V0 daughter DCA to primary vertex", o2::framework::kTH1F, {aDCAToPVAxis}); + mHistogramRegistry->add("CascadeQA/hDCANegToPV", "Neg V0 daughter DCA to primary vertex", o2::framework::kTH1F, {aDCAToPVAxis}); + mHistogramRegistry->add("CascadeQA/hDCABachToPV", "Bachelor DCA to primary vertex", o2::framework::kTH1F, {aDCAToPVAxis}); + mHistogramRegistry->add("CascadeQA/hDCAV0ToPV", "V0 DCA to primary vertex", o2::framework::kTH1F, {aDCAToPVAxis}); } /// check whether the most open cuts are fulfilled - most of this should have diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverseCollisionSelection.h b/PWGCF/FemtoUniverse/Core/FemtoUniverseCollisionSelection.h index ab47405cb9c..39f6454c08f 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniverseCollisionSelection.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniverseCollisionSelection.h @@ -20,12 +20,11 @@ #include "Common/CCDB/TriggerAliases.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/Logger.h" +#include +#include +#include -#include - -using namespace o2::framework; +#include namespace o2::analysis::femto_universe { @@ -61,19 +60,19 @@ class FemtoUniverseCollisionSelection /// Initializes histograms for the task /// \param registry Histogram registry to be passed - void init(HistogramRegistry* registry) + void init(o2::framework::HistogramRegistry* registry) { if (!mCutsSet) { LOGF(error, "Event selection not set - quitting!"); } mHistogramRegistry = registry; - mHistogramRegistry->add("Event/zvtxhist", "; vtx_{z} (cm); Entries", kTH1F, {{300, -12.5, 12.5}}); - mHistogramRegistry->add("Event/MultV0M", "; vMultV0M; Entries", kTH1F, {{16384, 0, 32768}}); - mHistogramRegistry->add("Event/MultT0M", "; vMultT0M; Entries", kTH1F, {{4096, 0, 8192}}); - mHistogramRegistry->add("Event/MultNTracksPV", "; vMultNTracksPV; Entries", kTH1F, {{120, 0, 120}}); - mHistogramRegistry->add("Event/MultNTracklets", "; vMultNTrackslets; Entries", kTH1F, {{300, 0, 300}}); - mHistogramRegistry->add("Event/MultTPC", "; vMultTPC; Entries", kTH1I, {{600, 0, 600}}); - mHistogramRegistry->add("Event/Sphericity", "; Sphericity; Entries", kTH1I, {{200, 0, 3}}); + mHistogramRegistry->add("Event/zvtxhist", "; vtx_{z} (cm); Entries", o2::framework::kTH1F, {{300, -12.5, 12.5}}); + mHistogramRegistry->add("Event/MultV0M", "; vMultV0M; Entries", o2::framework::kTH1F, {{16384, 0, 32768}}); + mHistogramRegistry->add("Event/MultT0M", "; vMultT0M; Entries", o2::framework::kTH1F, {{4096, 0, 8192}}); + mHistogramRegistry->add("Event/MultNTracksPV", "; vMultNTracksPV; Entries", o2::framework::kTH1F, {{120, 0, 120}}); + mHistogramRegistry->add("Event/MultNTracklets", "; vMultNTrackslets; Entries", o2::framework::kTH1F, {{300, 0, 300}}); + mHistogramRegistry->add("Event/MultTPC", "; vMultTPC; Entries", o2::framework::kTH1I, {{600, 0, 600}}); + mHistogramRegistry->add("Event/Sphericity", "; Sphericity; Entries", o2::framework::kTH1I, {{200, 0, 3}}); } /// Print some debug information @@ -206,15 +205,15 @@ class FemtoUniverseCollisionSelection } private: - HistogramRegistry* mHistogramRegistry = nullptr; ///< For QA output - bool mCutsSet = false; ///< Protection against running without cuts - bool mCheckTrigger = false; ///< Check for trigger - bool mCheckOffline = false; ///< Check for offline criteria (might change) - bool mCheckIsRun3 = false; ///< Check if running on Pilot Beam - triggerAliases mTrigger = kINT7; ///< Trigger to check for - float mZvtxMax = 999.f; ///< Maximal deviation from nominal z-vertex (cm) - float mCentMin = 0.0; ///< Minimum centrality value - float mCentMax = 100.0; ///< Maximum centrality value + o2::framework::HistogramRegistry* mHistogramRegistry = nullptr; ///< For QA output + bool mCutsSet = false; ///< Protection against running without cuts + bool mCheckTrigger = false; ///< Check for trigger + bool mCheckOffline = false; ///< Check for offline criteria (might change) + bool mCheckIsRun3 = false; ///< Check if running on Pilot Beam + triggerAliases mTrigger = kINT7; ///< Trigger to check for + float mZvtxMax = 999.f; ///< Maximal deviation from nominal z-vertex (cm) + float mCentMin = 0.0; ///< Minimum centrality value + float mCentMax = 100.0; ///< Maximum centrality value }; } // namespace o2::analysis::femto_universe diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverseContainer.h b/PWGCF/FemtoUniverse/Core/FemtoUniverseContainer.h index c72e756e062..c4597fc5e12 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniverseContainer.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniverseContainer.h @@ -23,20 +23,16 @@ #include "PWGCF/FemtoUniverse/Core/FemtoUniverseMath.h" #include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" -#include "Common/Core/RecoDecay.h" +#include +#include +#include -#include "Framework/HistogramRegistry.h" -#include - -#include "Math/Vector4D.h" -#include "TDatabasePDG.h" -#include "TMath.h" +#include #include +#include #include -using namespace o2::framework; - namespace o2::analysis::femto_universe { @@ -77,21 +73,21 @@ class FemtoUniverseContainer template void initBase(std::string folderName, std::string femtoObs, T femtoObsAxis, T multAxis, T kTAxis, T mTAxis, T multAxis3D, T mTAxis3D, T etaAxis, T phiAxis, bool use3dplots) { - mHistogramRegistry->add((folderName + "/relPairDist").c_str(), ("; " + femtoObs + "; Entries").c_str(), kTH1F, {femtoObsAxis}); - mHistogramRegistry->add((folderName + "/relPairkT").c_str(), "; #it{k}_{T} (GeV/#it{c}); Entries", kTH1F, {kTAxis}); - mHistogramRegistry->add((folderName + "/relPairkstarkT").c_str(), ("; " + femtoObs + "; #it{k}_{T} (GeV/#it{c})").c_str(), kTH2F, {femtoObsAxis, kTAxis}); - mHistogramRegistry->add((folderName + "/relPairkstarmT").c_str(), ("; " + femtoObs + "; #it{m}_{T} (GeV/#it{c}^{2})").c_str(), kTH2F, {femtoObsAxis, mTAxis}); - mHistogramRegistry->add((folderName + "/relPairkstarMult").c_str(), ("; " + femtoObs + "; Multiplicity").c_str(), kTH2F, {femtoObsAxis, multAxis}); - mHistogramRegistry->add((folderName + "/kstarPtPart1").c_str(), ("; " + femtoObs + "; #it{p} _{T} Particle 1 (GeV/#it{c})").c_str(), kTH2F, {femtoObsAxis, {375, 0., 7.5}}); - mHistogramRegistry->add((folderName + "/kstarPtPart2").c_str(), ("; " + femtoObs + "; #it{p} _{T} Particle 2 (GeV/#it{c})").c_str(), kTH2F, {femtoObsAxis, {375, 0., 7.5}}); - mHistogramRegistry->add((folderName + "/MultPtPart1").c_str(), "; #it{p} _{T} Particle 1 (GeV/#it{c}); Multiplicity", kTH2F, {{375, 0., 7.5}, multAxis}); - mHistogramRegistry->add((folderName + "/MultPtPart2").c_str(), "; #it{p} _{T} Particle 2 (GeV/#it{c}); Multiplicity", kTH2F, {{375, 0., 7.5}, multAxis}); - mHistogramRegistry->add((folderName + "/PtPart1PtPart2").c_str(), "; #it{p} _{T} Particle 1 (GeV/#it{c}); #it{p} _{T} Particle 2 (GeV/#it{c})", kTH2F, {{375, 0., 7.5}, {375, 0., 7.5}}); - mHistogramRegistry->add((folderName + "/DeltaEtaDeltaPhi").c_str(), "; #Delta#varphi (rad); #Delta#eta", kTH2F, {phiAxis, etaAxis}); + mHistogramRegistry->add((folderName + "/relPairDist").c_str(), ("; " + femtoObs + "; Entries").c_str(), o2::framework::kTH1F, {femtoObsAxis}); + mHistogramRegistry->add((folderName + "/relPairkT").c_str(), "; #it{k}_{T} (GeV/#it{c}); Entries", o2::framework::kTH1F, {kTAxis}); + mHistogramRegistry->add((folderName + "/relPairkstarkT").c_str(), ("; " + femtoObs + "; #it{k}_{T} (GeV/#it{c})").c_str(), o2::framework::kTH2F, {femtoObsAxis, kTAxis}); + mHistogramRegistry->add((folderName + "/relPairkstarmT").c_str(), ("; " + femtoObs + "; #it{m}_{T} (GeV/#it{c}^{2})").c_str(), o2::framework::kTH2F, {femtoObsAxis, mTAxis}); + mHistogramRegistry->add((folderName + "/relPairkstarMult").c_str(), ("; " + femtoObs + "; Multiplicity").c_str(), o2::framework::kTH2F, {femtoObsAxis, multAxis}); + mHistogramRegistry->add((folderName + "/kstarPtPart1").c_str(), ("; " + femtoObs + "; #it{p} _{T} Particle 1 (GeV/#it{c})").c_str(), o2::framework::kTH2F, {femtoObsAxis, {375, 0., 7.5}}); + mHistogramRegistry->add((folderName + "/kstarPtPart2").c_str(), ("; " + femtoObs + "; #it{p} _{T} Particle 2 (GeV/#it{c})").c_str(), o2::framework::kTH2F, {femtoObsAxis, {375, 0., 7.5}}); + mHistogramRegistry->add((folderName + "/MultPtPart1").c_str(), "; #it{p} _{T} Particle 1 (GeV/#it{c}); Multiplicity", o2::framework::kTH2F, {{375, 0., 7.5}, multAxis}); + mHistogramRegistry->add((folderName + "/MultPtPart2").c_str(), "; #it{p} _{T} Particle 2 (GeV/#it{c}); Multiplicity", o2::framework::kTH2F, {{375, 0., 7.5}, multAxis}); + mHistogramRegistry->add((folderName + "/PtPart1PtPart2").c_str(), "; #it{p} _{T} Particle 1 (GeV/#it{c}); #it{p} _{T} Particle 2 (GeV/#it{c})", o2::framework::kTH2F, {{375, 0., 7.5}, {375, 0., 7.5}}); + mHistogramRegistry->add((folderName + "/DeltaEtaDeltaPhi").c_str(), "; #Delta#varphi (rad); #Delta#eta", o2::framework::kTH2F, {phiAxis, etaAxis}); if (use3dplots) { - mHistogramRegistry->add((folderName + "/relPairkstarmTMult").c_str(), ("; " + femtoObs + "; #it{m}_{T} (GeV/#it{c}^{2}); Multiplicity").c_str(), kTH3F, {femtoObsAxis, mTAxis3D, multAxis3D}); - mHistogramRegistry->add((folderName + "/relPairkstarkTMult").c_str(), ("; " + femtoObs + "; #it{k}_{T} (GeV/#it{c}^{2}); Multiplicity").c_str(), kTH3F, {femtoObsAxis, kTAxis, multAxis3D}); - mHistogramRegistry->add((folderName + "/relPairkTPtPart1PtPart2").c_str(), ("; #it{k}_{T} (GeV/#it{c}^{2}); #it{p}_{T,1} (GeV/#it{c}^{2}); #it{p}_{T,2} (GeV/#it{c}^{2})"), kTH3F, {kTAxis, {375, 0., 7.5}, {375, 0., 7.5}}); + mHistogramRegistry->add((folderName + "/relPairkstarmTMult").c_str(), ("; " + femtoObs + "; #it{m}_{T} (GeV/#it{c}^{2}); Multiplicity").c_str(), o2::framework::kTH3F, {femtoObsAxis, mTAxis3D, multAxis3D}); + mHistogramRegistry->add((folderName + "/relPairkstarkTMult").c_str(), ("; " + femtoObs + "; #it{k}_{T} (GeV/#it{c}^{2}); Multiplicity").c_str(), o2::framework::kTH3F, {femtoObsAxis, kTAxis, multAxis3D}); + mHistogramRegistry->add((folderName + "/relPairkTPtPart1PtPart2").c_str(), ("; #it{k}_{T} (GeV/#it{c}^{2}); #it{p}_{T,1} (GeV/#it{c}^{2}); #it{p}_{T,2} (GeV/#it{c}^{2})"), o2::framework::kTH3F, {kTAxis, {375, 0., 7.5}, {375, 0., 7.5}}); } } @@ -103,12 +99,12 @@ class FemtoUniverseContainer template void initMC(std::string folderName, std::string femtoObs, T femtoObsAxis, T multAxis, T mTAxis) { - mHistogramRegistry->add((folderName + "/relPairDist_ReconNoFake").c_str(), ("; " + femtoObs + "; Entries").c_str(), kTH1F, {femtoObsAxis}); - mHistogramRegistry->add((folderName + "/relPairkstarmT_ReconNoFake").c_str(), ("; " + femtoObs + "; #it{m}_{T} (GeV/#it{c}^{2})").c_str(), kTH2F, {femtoObsAxis, mTAxis}); - mHistogramRegistry->add((folderName + "/relPairkstarMult_ReconNoFake").c_str(), ("; " + femtoObs + "; Multiplicity").c_str(), kTH2F, {femtoObsAxis, multAxis}); - mHistogramRegistry->add((folderName + "/hNoMCtruthPairsCounter").c_str(), "; Counter; Entries", kTH1I, {{1, 0, 1}}); - mHistogramRegistry->add((folderName + "/hFakePairsCounter").c_str(), "; Counter; Entries", kTH1I, {{1, 0, 1}}); - mHistogramRegistry->add((folderName + "/kstar_resolution").c_str(), "; #it{k} _{T} reconstructed (GeV/#it{c}); #it{k} _{T} truth (GeV/#it{c})", kTH2F, {femtoObsAxis, femtoObsAxis}); + mHistogramRegistry->add((folderName + "/relPairDist_ReconNoFake").c_str(), ("; " + femtoObs + "; Entries").c_str(), o2::framework::kTH1F, {femtoObsAxis}); + mHistogramRegistry->add((folderName + "/relPairkstarmT_ReconNoFake").c_str(), ("; " + femtoObs + "; #it{m}_{T} (GeV/#it{c}^{2})").c_str(), o2::framework::kTH2F, {femtoObsAxis, mTAxis}); + mHistogramRegistry->add((folderName + "/relPairkstarMult_ReconNoFake").c_str(), ("; " + femtoObs + "; Multiplicity").c_str(), o2::framework::kTH2F, {femtoObsAxis, multAxis}); + mHistogramRegistry->add((folderName + "/hNoMCtruthPairsCounter").c_str(), "; Counter; Entries", o2::framework::kTH1I, {{1, 0, 1}}); + mHistogramRegistry->add((folderName + "/hFakePairsCounter").c_str(), "; Counter; Entries", o2::framework::kTH1I, {{1, 0, 1}}); + mHistogramRegistry->add((folderName + "/kstar_resolution").c_str(), "; #it{k} _{T} reconstructed (GeV/#it{c}); #it{k} _{T} truth (GeV/#it{c})", o2::framework::kTH2F, {femtoObsAxis, femtoObsAxis}); } /// Templated function to initialize the histograms for the task @@ -124,7 +120,7 @@ class FemtoUniverseContainer /// \param phiBins phi binning for the histograms /// \param isMC add Monte Carlo truth histograms to the output file template - void init(HistogramRegistry* registry, T& kstarBins, T& multBins, T& kTBins, T& mTBins, T& multBins3D, T& mTBins3D, P& etaBins, P& phiBins, bool isMC, bool use3dplots) + void init(o2::framework::HistogramRegistry* registry, T& kstarBins, T& multBins, T& kTBins, T& mTBins, T& multBins3D, T& mTBins3D, P& etaBins, P& phiBins, bool isMC, bool use3dplots) { mHistogramRegistry = registry; std::string femtoObs; @@ -276,7 +272,7 @@ class FemtoUniverseContainer } protected: - HistogramRegistry* mHistogramRegistry = nullptr; ///< For QA output + o2::framework::HistogramRegistry* mHistogramRegistry = nullptr; ///< For QA output static constexpr std::string_view FolderSuffix[2] = {"SameEvent", "MixedEvent"}; ///< Folder naming for the output according to EventType static constexpr femto_universe_container::Observable FemtoObs = obs; ///< Femtoscopic observable to be computed (according to femto_universe_container::Observable) static constexpr int EventType = eventType; ///< Type of the event (same/mixed, according to femto_universe_container::EventType) diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverseCutculator.h b/PWGCF/FemtoUniverse/Core/FemtoUniverseCutculator.h index 58e278cdde7..aa59d49f1fc 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniverseCutculator.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniverseCutculator.h @@ -21,14 +21,19 @@ #include "PWGCF/FemtoUniverse/Core/FemtoUniverseSelection.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseTrackSelection.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseV0Selection.h" +#include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" +#include +#include + +#include #include #include +#include -#include #include +#include #include -#include #include #include #include diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverseDetaDphiStar.h b/PWGCF/FemtoUniverse/Core/FemtoUniverseDetaDphiStar.h index c939a4f269d..2a3c47a1ffe 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniverseDetaDphiStar.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniverseDetaDphiStar.h @@ -19,18 +19,30 @@ #ifndef PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSEDETADPHISTAR_H_ #define PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSEDETADPHISTAR_H_ -#include "PWGCF/FemtoUniverse/Core/FemtoUniverseAngularContainer.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseContainer.h" -#include "PWGCF/FemtoUniverse/Core/FemtoUniverseFemtoContainer.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseTrackSelection.h" #include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" -#include "Framework/HistogramRegistry.h" - -#include "TMath.h" - +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include #include #include +#include #include namespace o2::analysis @@ -50,7 +62,7 @@ class FemtoUniverseDetaDphiStar /// Destructor virtual ~FemtoUniverseDetaDphiStar() = default; /// Initialization of the histograms and setting required values - void init(HistogramRegistry* registry, HistogramRegistry* registryQA, float ldeltaphistarcutmin, float ldeltaphistarcutmax, float ldeltaetacutmin, float ldeltaetacutmax, float lchosenradii, bool lplotForEveryRadii, float lPhiMassMin = 1.014, float lPhiMassMax = 1.026, bool lisSameSignCPR = false) + void init(o2::framework::HistogramRegistry* registry, o2::framework::HistogramRegistry* registryQA, float ldeltaphistarcutmin, float ldeltaphistarcutmax, float ldeltaetacutmin, float ldeltaetacutmax, float lchosenradii, bool lplotForEveryRadii, float lPhiMassMin = 1.014, float lPhiMassMax = 1.026, bool lisSameSignCPR = false) { chosenRadii = lchosenradii; cutDeltaPhiStarMax = ldeltaphistarcutmax; @@ -66,31 +78,31 @@ class FemtoUniverseDetaDphiStar if constexpr (kPartOneType == o2::aod::femtouniverseparticle::ParticleType::kTrack && kPartTwoType == o2::aod::femtouniverseparticle::ParticleType::kTrack) { std::string dirName = static_cast(DirNames[0]); - histdetadpisame[0][0] = mHistogramRegistry->add((dirName + static_cast(HistNamesSame[0][0])).c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); - histdetadpisame[0][1] = mHistogramRegistry->add((dirName + static_cast(HistNamesSame[1][0])).c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); - histdetadpimixed[0][0] = mHistogramRegistry->add((dirName + static_cast(HistNamesMixed[0][0])).c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); - histdetadpimixed[0][1] = mHistogramRegistry->add((dirName + static_cast(HistNamesMixed[1][0])).c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpisame[0][0] = mHistogramRegistry->add((dirName + static_cast(HistNamesSame[0][0])).c_str(), "; #Delta #eta; #Delta #phi", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpisame[0][1] = mHistogramRegistry->add((dirName + static_cast(HistNamesSame[1][0])).c_str(), "; #Delta #eta; #Delta #phi", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpimixed[0][0] = mHistogramRegistry->add((dirName + static_cast(HistNamesMixed[0][0])).c_str(), "; #Delta #eta; #Delta #phi", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpimixed[0][1] = mHistogramRegistry->add((dirName + static_cast(HistNamesMixed[1][0])).c_str(), "; #Delta #eta; #Delta #phi", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); - histdetadpiqlcmssame = mHistogramRegistry->add((dirName + static_cast(HistNamesSame[1][7])).c_str(), "; #it{q}_{LCMS}; #Delta #eta; #Delta #phi", kTH3F, {{100, 0.0, 0.5}, {100, -0.15, 0.15}, {100, -0.15, 0.15}}); - histdetadpiqlcmsmixed = mHistogramRegistry->add((dirName + static_cast(HistNamesMixed[1][7])).c_str(), "; #it{q}_{LCMS}; #Delta #eta; #Delta #phi", kTH3F, {{100, 0.0, 0.5}, {100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpiqlcmssame = mHistogramRegistry->add((dirName + static_cast(HistNamesSame[1][7])).c_str(), "; #it{q}_{LCMS}; #Delta #eta; #Delta #phi", o2::framework::kTH3F, {{100, 0.0, 0.5}, {100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpiqlcmsmixed = mHistogramRegistry->add((dirName + static_cast(HistNamesMixed[1][7])).c_str(), "; #it{q}_{LCMS}; #Delta #eta; #Delta #phi", o2::framework::kTH3F, {{100, 0.0, 0.5}, {100, -0.15, 0.15}, {100, -0.15, 0.15}}); if (plotForEveryRadii) { for (int i = 0; i < 9; i++) { - histdetadpiRadii[0][i] = mHistogramRegistryQA->add((dirName + static_cast(HistNamesRadii[0][i])).c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpiRadii[0][i] = mHistogramRegistryQA->add((dirName + static_cast(HistNamesRadii[0][i])).c_str(), "; #Delta #eta; #Delta #phi", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); } } } if constexpr (kPartOneType == o2::aod::femtouniverseparticle::ParticleType::kTrack && kPartTwoType == o2::aod::femtouniverseparticle::ParticleType::kV0) { for (int i = 0; i < 2; i++) { std::string dirName = static_cast(DirNames[1]); - histdetadpisame[i][0] = mHistogramRegistry->add((dirName + static_cast(HistNamesSame[0][i])).c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); - histdetadpisame[i][1] = mHistogramRegistry->add((dirName + static_cast(HistNamesSame[1][i])).c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); - histdetadpimixed[i][0] = mHistogramRegistry->add((dirName + static_cast(HistNamesMixed[0][i])).c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); - histdetadpimixed[i][1] = mHistogramRegistry->add((dirName + static_cast(HistNamesMixed[1][i])).c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpisame[i][0] = mHistogramRegistry->add((dirName + static_cast(HistNamesSame[0][i])).c_str(), "; #Delta #eta; #Delta #phi", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpisame[i][1] = mHistogramRegistry->add((dirName + static_cast(HistNamesSame[1][i])).c_str(), "; #Delta #eta; #Delta #phi", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpimixed[i][0] = mHistogramRegistry->add((dirName + static_cast(HistNamesMixed[0][i])).c_str(), "; #Delta #eta; #Delta #phi", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpimixed[i][1] = mHistogramRegistry->add((dirName + static_cast(HistNamesMixed[1][i])).c_str(), "; #Delta #eta; #Delta #phi", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); if (plotForEveryRadii) { for (int j = 0; j < 9; j++) { - histdetadpiRadii[i][j] = mHistogramRegistryQA->add((dirName + static_cast(HistNamesRadii[i][j])).c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpiRadii[i][j] = mHistogramRegistryQA->add((dirName + static_cast(HistNamesRadii[i][j])).c_str(), "; #Delta #eta; #Delta #phi", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); } } } @@ -99,13 +111,13 @@ class FemtoUniverseDetaDphiStar /// V0-V0 combination for (int k = 0; k < 2; k++) { std::string dirName = static_cast(DirNames[2]); - histdetadpisame[k][0] = mHistogramRegistry->add((dirName + static_cast(HistNamesSame[0][k])).c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); - histdetadpisame[k][1] = mHistogramRegistry->add((dirName + static_cast(HistNamesSame[1][k])).c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); - histdetadpimixed[k][0] = mHistogramRegistry->add((dirName + static_cast(HistNamesMixed[0][k])).c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); - histdetadpimixed[k][1] = mHistogramRegistry->add((dirName + static_cast(HistNamesMixed[1][k])).c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpisame[k][0] = mHistogramRegistry->add((dirName + static_cast(HistNamesSame[0][k])).c_str(), "; #Delta #eta; #Delta #phi", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpisame[k][1] = mHistogramRegistry->add((dirName + static_cast(HistNamesSame[1][k])).c_str(), "; #Delta #eta; #Delta #phi", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpimixed[k][0] = mHistogramRegistry->add((dirName + static_cast(HistNamesMixed[0][k])).c_str(), "; #Delta #eta; #Delta #phi", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpimixed[k][1] = mHistogramRegistry->add((dirName + static_cast(HistNamesMixed[1][k])).c_str(), "; #Delta #eta; #Delta #phi", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); if (plotForEveryRadii) { for (int l = 0; l < 9; l++) { - histdetadpiRadii[k][l] = mHistogramRegistryQA->add((dirName + static_cast(HistNamesRadii[k][l])).c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpiRadii[k][l] = mHistogramRegistryQA->add((dirName + static_cast(HistNamesRadii[k][l])).c_str(), "; #Delta #eta; #Delta #phi", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); } } } @@ -114,13 +126,13 @@ class FemtoUniverseDetaDphiStar /// Cascade-Cascade combination for (int k = 0; k < 7; k++) { std::string dirName = static_cast(DirNames[5]); - histdetadpisame[k][0] = mHistogramRegistry->add((dirName + static_cast(HistNamesSame[0][k])).c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); - histdetadpisame[k][1] = mHistogramRegistry->add((dirName + static_cast(HistNamesSame[1][k])).c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); - histdetadpimixed[k][0] = mHistogramRegistry->add((dirName + static_cast(HistNamesMixed[0][k])).c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); - histdetadpimixed[k][1] = mHistogramRegistry->add((dirName + static_cast(HistNamesMixed[1][k])).c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpisame[k][0] = mHistogramRegistry->add((dirName + static_cast(HistNamesSame[0][k])).c_str(), "; #Delta #eta; #Delta #phi", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpisame[k][1] = mHistogramRegistry->add((dirName + static_cast(HistNamesSame[1][k])).c_str(), "; #Delta #eta; #Delta #phi", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpimixed[k][0] = mHistogramRegistry->add((dirName + static_cast(HistNamesMixed[0][k])).c_str(), "; #Delta #eta; #Delta #phi", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpimixed[k][1] = mHistogramRegistry->add((dirName + static_cast(HistNamesMixed[1][k])).c_str(), "; #Delta #eta; #Delta #phi", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); if (plotForEveryRadii) { for (int l = 0; l < 9; l++) { - histdetadpiRadii[k][l] = mHistogramRegistryQA->add((dirName + static_cast(HistNamesRadii[k][l])).c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpiRadii[k][l] = mHistogramRegistryQA->add((dirName + static_cast(HistNamesRadii[k][l])).c_str(), "; #Delta #eta; #Delta #phi", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); } } } @@ -129,13 +141,13 @@ class FemtoUniverseDetaDphiStar /// Track-Cascade combination for (int k = 0; k < 3; k++) { std::string dirName = static_cast(DirNames[6]); - histdetadpisame[k][0] = mHistogramRegistry->add((dirName + static_cast(HistNamesSame[0][k])).c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); - histdetadpisame[k][1] = mHistogramRegistry->add((dirName + static_cast(HistNamesSame[1][k])).c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); - histdetadpimixed[k][0] = mHistogramRegistry->add((dirName + static_cast(HistNamesMixed[0][k])).c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); - histdetadpimixed[k][1] = mHistogramRegistry->add((dirName + static_cast(HistNamesMixed[1][k])).c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpisame[k][0] = mHistogramRegistry->add((dirName + static_cast(HistNamesSame[0][k])).c_str(), "; #Delta #eta; #Delta #phi", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpisame[k][1] = mHistogramRegistry->add((dirName + static_cast(HistNamesSame[1][k])).c_str(), "; #Delta #eta; #Delta #phi", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpimixed[k][0] = mHistogramRegistry->add((dirName + static_cast(HistNamesMixed[0][k])).c_str(), "; #Delta #eta; #Delta #phi", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpimixed[k][1] = mHistogramRegistry->add((dirName + static_cast(HistNamesMixed[1][k])).c_str(), "; #Delta #eta; #Delta #phi", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); if (plotForEveryRadii) { for (int l = 0; l < 9; l++) { - histdetadpiRadii[k][l] = mHistogramRegistryQA->add((dirName + static_cast(HistNamesRadii[k][l])).c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpiRadii[k][l] = mHistogramRegistryQA->add((dirName + static_cast(HistNamesRadii[k][l])).c_str(), "; #Delta #eta; #Delta #phi", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); } } } @@ -144,13 +156,13 @@ class FemtoUniverseDetaDphiStar /// V0-Cascade combination for (int k = 0; k < 3; k++) { std::string dirName = static_cast(DirNames[7]); - histdetadpisame[k][0] = mHistogramRegistry->add((dirName + static_cast(HistNamesSame[0][k])).c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); - histdetadpisame[k][1] = mHistogramRegistry->add((dirName + static_cast(HistNamesSame[1][k])).c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); - histdetadpimixed[k][0] = mHistogramRegistry->add((dirName + static_cast(HistNamesMixed[0][k])).c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); - histdetadpimixed[k][1] = mHistogramRegistry->add((dirName + static_cast(HistNamesMixed[1][k])).c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpisame[k][0] = mHistogramRegistry->add((dirName + static_cast(HistNamesSame[0][k])).c_str(), "; #Delta #eta; #Delta #phi", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpisame[k][1] = mHistogramRegistry->add((dirName + static_cast(HistNamesSame[1][k])).c_str(), "; #Delta #eta; #Delta #phi", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpimixed[k][0] = mHistogramRegistry->add((dirName + static_cast(HistNamesMixed[0][k])).c_str(), "; #Delta #eta; #Delta #phi", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpimixed[k][1] = mHistogramRegistry->add((dirName + static_cast(HistNamesMixed[1][k])).c_str(), "; #Delta #eta; #Delta #phi", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); if (plotForEveryRadii) { for (int l = 0; l < 9; l++) { - histdetadpiRadii[k][l] = mHistogramRegistryQA->add((dirName + static_cast(HistNamesRadii[k][l])).c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpiRadii[k][l] = mHistogramRegistryQA->add((dirName + static_cast(HistNamesRadii[k][l])).c_str(), "; #Delta #eta; #Delta #phi", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); } } } @@ -158,14 +170,14 @@ class FemtoUniverseDetaDphiStar if constexpr (kPartOneType == o2::aod::femtouniverseparticle::ParticleType::kTrack && kPartTwoType == o2::aod::femtouniverseparticle::ParticleType::kPhi) { for (int i = 0; i < 2; i++) { std::string dirName = static_cast(DirNames[3]); - histdetadpisame[i][0] = mHistogramRegistry->add((dirName + static_cast(HistNamesSame[0][i])).c_str(), "; #Delta #eta; #Delta #varphi*", kTH2F, {{400, -0.30, 0.30}, {400, -0.30, 0.30}}); - histdetadpisame[i][1] = mHistogramRegistry->add((dirName + static_cast(HistNamesSame[1][i])).c_str(), "; #Delta #eta; #Delta #varphi*", kTH2F, {{400, -0.30, 0.30}, {400, -0.30, 0.30}}); - histdetadpimixed[i][0] = mHistogramRegistry->add((dirName + static_cast(HistNamesMixed[0][i])).c_str(), "; #Delta #eta; #Delta #varphi*", kTH2F, {{400, -0.30, 0.30}, {400, -0.30, 0.30}}); - histdetadpimixed[i][1] = mHistogramRegistry->add((dirName + static_cast(HistNamesMixed[1][i])).c_str(), "; #Delta #eta; #Delta #varphi*", kTH2F, {{400, -0.30, 0.30}, {400, -0.30, 0.30}}); + histdetadpisame[i][0] = mHistogramRegistry->add((dirName + static_cast(HistNamesSame[0][i])).c_str(), "; #Delta #eta; #Delta #varphi*", o2::framework::kTH2F, {{400, -0.30, 0.30}, {400, -0.30, 0.30}}); + histdetadpisame[i][1] = mHistogramRegistry->add((dirName + static_cast(HistNamesSame[1][i])).c_str(), "; #Delta #eta; #Delta #varphi*", o2::framework::kTH2F, {{400, -0.30, 0.30}, {400, -0.30, 0.30}}); + histdetadpimixed[i][0] = mHistogramRegistry->add((dirName + static_cast(HistNamesMixed[0][i])).c_str(), "; #Delta #eta; #Delta #varphi*", o2::framework::kTH2F, {{400, -0.30, 0.30}, {400, -0.30, 0.30}}); + histdetadpimixed[i][1] = mHistogramRegistry->add((dirName + static_cast(HistNamesMixed[1][i])).c_str(), "; #Delta #eta; #Delta #varphi*", o2::framework::kTH2F, {{400, -0.30, 0.30}, {400, -0.30, 0.30}}); if (plotForEveryRadii) { for (int j = 0; j < 9; j++) { - histdetadpiRadii[i][j] = mHistogramRegistryQA->add((dirName + static_cast(HistNamesRadii[i][j])).c_str(), "; #Delta #eta; #Delta #varphi*", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpiRadii[i][j] = mHistogramRegistryQA->add((dirName + static_cast(HistNamesRadii[i][j])).c_str(), "; #Delta #eta; #Delta #varphi*", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); } } } @@ -173,14 +185,14 @@ class FemtoUniverseDetaDphiStar if constexpr (kPartOneType == o2::aod::femtouniverseparticle::ParticleType::kTrack && kPartTwoType == o2::aod::femtouniverseparticle::ParticleType::kD0) { for (int i = 0; i < 2; i++) { std::string dirName = static_cast(DirNames[4]); - histdetadpisame[i][0] = mHistogramRegistry->add((dirName + static_cast(HistNamesSame[0][i])).c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); - histdetadpisame[i][1] = mHistogramRegistry->add((dirName + static_cast(HistNamesSame[1][i])).c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); - histdetadpimixed[i][0] = mHistogramRegistry->add((dirName + static_cast(HistNamesMixed[0][i])).c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); - histdetadpimixed[i][1] = mHistogramRegistry->add((dirName + static_cast(HistNamesMixed[1][i])).c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpisame[i][0] = mHistogramRegistry->add((dirName + static_cast(HistNamesSame[0][i])).c_str(), "; #Delta #eta; #Delta #phi", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpisame[i][1] = mHistogramRegistry->add((dirName + static_cast(HistNamesSame[1][i])).c_str(), "; #Delta #eta; #Delta #phi", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpimixed[i][0] = mHistogramRegistry->add((dirName + static_cast(HistNamesMixed[0][i])).c_str(), "; #Delta #eta; #Delta #phi", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpimixed[i][1] = mHistogramRegistry->add((dirName + static_cast(HistNamesMixed[1][i])).c_str(), "; #Delta #eta; #Delta #phi", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); if (plotForEveryRadii) { for (int j = 0; j < 9; j++) { - histdetadpiRadii[i][j] = mHistogramRegistryQA->add((dirName + static_cast(HistNamesRadii[i][j])).c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpiRadii[i][j] = mHistogramRegistryQA->add((dirName + static_cast(HistNamesRadii[i][j])).c_str(), "; #Delta #eta; #Delta #phi", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); } } } @@ -188,7 +200,7 @@ class FemtoUniverseDetaDphiStar } template - void init_kT(HistogramRegistry* registry, t1& ktbins, std::vector ldeltaphistarcutmin, std::vector ldeltaphistarcutmax, std::vector ldeltaetacutmin, std::vector ldeltaetacutmax) + void init_kT(o2::framework::HistogramRegistry* registry, t1& ktbins, std::vector ldeltaphistarcutmin, std::vector ldeltaphistarcutmax, std::vector ldeltaetacutmin, std::vector ldeltaetacutmax) { mHistogramRegistry = registry; ktBins = ktbins; @@ -204,10 +216,10 @@ class FemtoUniverseDetaDphiStar std::string histSuffixkT1 = std::to_string(static_cast(ktBins[j] * 100.0)); std::string histSuffixkT2 = std::to_string(static_cast(ktBins[j + 1] * 100.0)); std::string histFolderkT = "kT_" + histSuffixkT1 + "_" + histSuffixkT2 + "/"; - histdetadphisamebeforekT[j] = mHistogramRegistry->add((dirName + histFolderkT + "detadphidetadphiBeforeSame").c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); - histdetadphimixedbeforekT[j] = mHistogramRegistry->add((dirName + histFolderkT + "detadphidetadphiBeforeMixed").c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); - histdetadphisameafterkT[j] = mHistogramRegistry->add((dirName + histFolderkT + "detadphidetadphiAfterSame").c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); - histdetadphimixedafterkT[j] = mHistogramRegistry->add((dirName + histFolderkT + "detadphidetadphiAfterMixed").c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadphisamebeforekT[j] = mHistogramRegistry->add((dirName + histFolderkT + "detadphidetadphiBeforeSame").c_str(), "; #Delta #eta; #Delta #phi", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadphimixedbeforekT[j] = mHistogramRegistry->add((dirName + histFolderkT + "detadphidetadphiBeforeMixed").c_str(), "; #Delta #eta; #Delta #phi", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadphisameafterkT[j] = mHistogramRegistry->add((dirName + histFolderkT + "detadphidetadphiAfterSame").c_str(), "; #Delta #eta; #Delta #phi", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadphimixedafterkT[j] = mHistogramRegistry->add((dirName + histFolderkT + "detadphidetadphiAfterMixed").c_str(), "; #Delta #eta; #Delta #phi", o2::framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); } } } @@ -714,8 +726,8 @@ class FemtoUniverseDetaDphiStar } private: - HistogramRegistry* mHistogramRegistry = nullptr; ///< For main output - HistogramRegistry* mHistogramRegistryQA = nullptr; ///< For QA output + o2::framework::HistogramRegistry* mHistogramRegistry = nullptr; ///< For main output + o2::framework::HistogramRegistry* mHistogramRegistryQA = nullptr; ///< For QA output static constexpr std::string_view DirNames[8] = {"kTrack_kTrack/", "kTrack_kV0/", "kV0_kV0/", "kTrack_kPhi/", "kTrack_kD0/", "kCascade_kCascade/", "kTrack_kCascade/", "kV0_kCascade/"}; static constexpr std::string_view HistNamesSame[2][8] = {{"detadphidetadphi0BeforeSame_0", "detadphidetadphi0BeforeSame_1", "detadphidetadphi0BeforeSame_2", diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverseEfficiencyCalculator.h b/PWGCF/FemtoUniverse/Core/FemtoUniverseEfficiencyCalculator.h index 7b66ac2fc45..5cacf981a4c 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniverseEfficiencyCalculator.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniverseEfficiencyCalculator.h @@ -16,16 +16,22 @@ #ifndef PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSEEFFICIENCYCALCULATOR_H_ #define PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSEEFFICIENCYCALCULATOR_H_ -#include "FemtoUniverseParticleHisto.h" - -#include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" - -#include "CCDB/BasicCCDBManager.h" -#include "Framework/Configurable.h" +#include +#include +#include #include +#include +#include + +#include #include +#include +#include +#include +#include +#include #include #include #include @@ -53,14 +59,14 @@ consteval auto getHistDim() -> int return -1; } -struct EfficiencyConfigurableGroup : ConfigurableGroup { - Configurable confEfficiencyApplyCorrections{"confEfficiencyApplyCorrections", false, "Should apply corrections from efficiency"}; - Configurable confEfficiencyCCDBTrainNumber{"confEfficiencyCCDBTrainNumber", 0, "Train number for which to query CCDB objects (set 0 to ignore)"}; - Configurable> confEfficiencyCCDBTimestamps{"confEfficiencyCCDBTimestamps", {}, "Timestamps of efficiency histograms in CCDB, to query for specific objects (default: [], set 0 to ignore, useful when running subwagons)"}; +struct EfficiencyConfigurableGroup : framework::ConfigurableGroup { + framework::Configurable confEfficiencyApplyCorrections{"confEfficiencyApplyCorrections", false, "Should apply corrections from efficiency"}; + framework::Configurable confEfficiencyCCDBTrainNumber{"confEfficiencyCCDBTrainNumber", 0, "Train number for which to query CCDB objects (set 0 to ignore)"}; + framework::Configurable> confEfficiencyCCDBTimestamps{"confEfficiencyCCDBTimestamps", {}, "Timestamps of efficiency histograms in CCDB, to query for specific objects (default: [], set 0 to ignore, useful when running subwagons)"}; // NOTE: in the future we might move the below configurables to a separate struct, eg. CCDBConfigurableGroup - Configurable confCCDBUrl{"confCCDBUrl", "http://alice-ccdb.cern.ch", "CCDB URL to be used"}; - Configurable confCCDBPath{"confCCDBPath", "", "CCDB base path to where to upload objects"}; + framework::Configurable confCCDBUrl{"confCCDBUrl", "http://alice-ccdb.cern.ch", "CCDB URL to be used"}; + framework::Configurable confCCDBPath{"confCCDBPath", "", "CCDB base path to where to upload objects"}; }; template diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverseEfficiencyCorrection.h b/PWGCF/FemtoUniverse/Core/FemtoUniverseEfficiencyCorrection.h index 74e37d27a66..23506574426 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniverseEfficiencyCorrection.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniverseEfficiencyCorrection.h @@ -20,17 +20,27 @@ #include #include -#include #include #include -#include +#include #include #include +#include + +#include #include +#include +#include +#include +#include +#include +#include +#include #include #include +#include #include namespace o2::analysis::femto_universe::efficiency_correction diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverseEventHisto.h b/PWGCF/FemtoUniverse/Core/FemtoUniverseEventHisto.h index dfe2bd35d62..5019d21597d 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniverseEventHisto.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniverseEventHisto.h @@ -17,11 +17,9 @@ #ifndef PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSEEVENTHISTO_H_ #define PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSEEVENTHISTO_H_ -#include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" +#include +#include -#include "Framework/HistogramRegistry.h" - -using namespace o2::framework; namespace o2::analysis::femto_universe { /// \class FemtoUniverseEventHisto @@ -33,14 +31,14 @@ class FemtoUniverseEventHisto virtual ~FemtoUniverseEventHisto() = default; /// Initializes histograms for the task /// \param registry Histogram registry to be passed - void init(HistogramRegistry* registry) + void init(o2::framework::HistogramRegistry* registry) { mHistogramRegistry = registry; - mHistogramRegistry->add("Event/zvtxhist", "; vtx_{z} (cm); Entries", kTH1F, {{250, -12.5, 12.5}}); - mHistogramRegistry->add("Event/MultV0M", "; vMultV0M; Entries", kTH1F, {{2000, 0, 20000}}); - mHistogramRegistry->add("Event/MultNTr", "; vMultNTr; Entries", kTH1F, {{20, 0, 200}}); - mHistogramRegistry->add("Event/MultNTrVSMultV0M", "; vMultNTr; MultV0M", kTH2F, {{200, 0, 4000}, {2000, 0, 20000}}); - mHistogramRegistry->add("Event/zvtxhist_MultNTr", "; zvtxhist; MultNTr", kTH2F, {{250, -12.5, 12.5}, {20, 0, 200}}); + mHistogramRegistry->add("Event/zvtxhist", "; vtx_{z} (cm); Entries", o2::framework::kTH1F, {{250, -12.5, 12.5}}); + mHistogramRegistry->add("Event/MultV0M", "; vMultV0M; Entries", o2::framework::kTH1F, {{2000, 0, 20000}}); + mHistogramRegistry->add("Event/MultNTr", "; vMultNTr; Entries", o2::framework::kTH1F, {{20, 0, 200}}); + mHistogramRegistry->add("Event/MultNTrVSMultV0M", "; vMultNTr; MultV0M", o2::framework::kTH2F, {{200, 0, 4000}, {2000, 0, 20000}}); + mHistogramRegistry->add("Event/zvtxhist_MultNTr", "; zvtxhist; MultNTr", o2::framework::kTH2F, {{250, -12.5, 12.5}, {20, 0, 200}}); } /// Some basic QA of the event @@ -59,7 +57,7 @@ class FemtoUniverseEventHisto } private: - HistogramRegistry* mHistogramRegistry; ///< For QA output + o2::framework::HistogramRegistry* mHistogramRegistry; ///< For QA output }; } // namespace o2::analysis::femto_universe diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverseFemtoContainer.h b/PWGCF/FemtoUniverse/Core/FemtoUniverseFemtoContainer.h index eb9f25dff14..4baf0145e3a 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniverseFemtoContainer.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniverseFemtoContainer.h @@ -21,19 +21,17 @@ #define PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSEFEMTOCONTAINER_H_ #include "PWGCF/FemtoUniverse/Core/FemtoUniverseMath.h" +#include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" -#include "Framework/HistogramRegistry.h" -#include +#include +#include -#include "Math/Vector4D.h" -#include "TDatabasePDG.h" -#include "TMath.h" +#include #include +#include #include -using namespace o2::framework; - namespace o2::analysis::femto_universe { @@ -74,18 +72,18 @@ class FemtoUniverseFemtoContainer template void initBase(std::string folderName, std::string femtoObs, T femtoObsAxis, T multAxis, T kTAxis, T mTAxis, T multAxis3D, T mTAxis3D, bool use3dplots) { - kHistogramRegistry->add((folderName + "/relPairDist").c_str(), ("; " + femtoObs + "; Entries").c_str(), kTH1F, {femtoObsAxis}); - kHistogramRegistry->add((folderName + "/relPairkT").c_str(), "; #it{k}_{T} (GeV/#it{c}); Entries", kTH1F, {kTAxis}); - kHistogramRegistry->add((folderName + "/relPairkstarkT").c_str(), ("; " + femtoObs + "; #it{k}_{T} (GeV/#it{c})").c_str(), kTH2F, {femtoObsAxis, kTAxis}); - kHistogramRegistry->add((folderName + "/relPairkstarmT").c_str(), ("; " + femtoObs + "; #it{m}_{T} (GeV/#it{c}^{2})").c_str(), kTH2F, {femtoObsAxis, mTAxis}); - kHistogramRegistry->add((folderName + "/relPairkstarMult").c_str(), ("; " + femtoObs + "; Multiplicity").c_str(), kTH2F, {femtoObsAxis, multAxis}); - kHistogramRegistry->add((folderName + "/kstarPtPart1").c_str(), ("; " + femtoObs + "; #it{p} _{T} Particle 1 (GeV/#it{c})").c_str(), kTH2F, {femtoObsAxis, {375, 0., 7.5}}); - kHistogramRegistry->add((folderName + "/kstarPtPart2").c_str(), ("; " + femtoObs + "; #it{p} _{T} Particle 2 (GeV/#it{c})").c_str(), kTH2F, {femtoObsAxis, {375, 0., 7.5}}); - kHistogramRegistry->add((folderName + "/MultPtPart1").c_str(), "; #it{p} _{T} Particle 1 (GeV/#it{c}); Multiplicity", kTH2F, {{375, 0., 7.5}, multAxis}); - kHistogramRegistry->add((folderName + "/MultPtPart2").c_str(), "; #it{p} _{T} Particle 2 (GeV/#it{c}); Multiplicity", kTH2F, {{375, 0., 7.5}, multAxis}); - kHistogramRegistry->add((folderName + "/PtPart1PtPart2").c_str(), "; #it{p} _{T} Particle 1 (GeV/#it{c}); #it{p} _{T} Particle 2 (GeV/#it{c})", kTH2F, {{375, 0., 7.5}, {375, 0., 7.5}}); + kHistogramRegistry->add((folderName + "/relPairDist").c_str(), ("; " + femtoObs + "; Entries").c_str(), o2::framework::kTH1F, {femtoObsAxis}); + kHistogramRegistry->add((folderName + "/relPairkT").c_str(), "; #it{k}_{T} (GeV/#it{c}); Entries", o2::framework::kTH1F, {kTAxis}); + kHistogramRegistry->add((folderName + "/relPairkstarkT").c_str(), ("; " + femtoObs + "; #it{k}_{T} (GeV/#it{c})").c_str(), o2::framework::kTH2F, {femtoObsAxis, kTAxis}); + kHistogramRegistry->add((folderName + "/relPairkstarmT").c_str(), ("; " + femtoObs + "; #it{m}_{T} (GeV/#it{c}^{2})").c_str(), o2::framework::kTH2F, {femtoObsAxis, mTAxis}); + kHistogramRegistry->add((folderName + "/relPairkstarMult").c_str(), ("; " + femtoObs + "; Multiplicity").c_str(), o2::framework::kTH2F, {femtoObsAxis, multAxis}); + kHistogramRegistry->add((folderName + "/kstarPtPart1").c_str(), ("; " + femtoObs + "; #it{p} _{T} Particle 1 (GeV/#it{c})").c_str(), o2::framework::kTH2F, {femtoObsAxis, {375, 0., 7.5}}); + kHistogramRegistry->add((folderName + "/kstarPtPart2").c_str(), ("; " + femtoObs + "; #it{p} _{T} Particle 2 (GeV/#it{c})").c_str(), o2::framework::kTH2F, {femtoObsAxis, {375, 0., 7.5}}); + kHistogramRegistry->add((folderName + "/MultPtPart1").c_str(), "; #it{p} _{T} Particle 1 (GeV/#it{c}); Multiplicity", o2::framework::kTH2F, {{375, 0., 7.5}, multAxis}); + kHistogramRegistry->add((folderName + "/MultPtPart2").c_str(), "; #it{p} _{T} Particle 2 (GeV/#it{c}); Multiplicity", o2::framework::kTH2F, {{375, 0., 7.5}, multAxis}); + kHistogramRegistry->add((folderName + "/PtPart1PtPart2").c_str(), "; #it{p} _{T} Particle 1 (GeV/#it{c}); #it{p} _{T} Particle 2 (GeV/#it{c})", o2::framework::kTH2F, {{375, 0., 7.5}, {375, 0., 7.5}}); if (use3dplots) { - kHistogramRegistry->add((folderName + "/relPairkstarmTMult").c_str(), ("; " + femtoObs + "; #it{m}_{T} (GeV/#it{c}^{2}); Multiplicity").c_str(), kTH3F, {femtoObsAxis, mTAxis3D, multAxis3D}); + kHistogramRegistry->add((folderName + "/relPairkstarmTMult").c_str(), ("; " + femtoObs + "; #it{m}_{T} (GeV/#it{c}^{2}); Multiplicity").c_str(), o2::framework::kTH3F, {femtoObsAxis, mTAxis3D, multAxis3D}); } } @@ -97,12 +95,12 @@ class FemtoUniverseFemtoContainer template void initMC(std::string folderName, std::string femtoObs, T femtoObsAxis, T multAxis, T mTAxis) { - kHistogramRegistry->add((folderName + "/relPairDist_ReconNoFake").c_str(), ("; " + femtoObs + "; Entries").c_str(), kTH1F, {femtoObsAxis}); - kHistogramRegistry->add((folderName + "/relPairkstarmT_ReconNoFake").c_str(), ("; " + femtoObs + "; #it{m}_{T} (GeV/#it{c}^{2})").c_str(), kTH2F, {femtoObsAxis, mTAxis}); - kHistogramRegistry->add((folderName + "/relPairkstarMult_ReconNoFake").c_str(), ("; " + femtoObs + "; Multiplicity").c_str(), kTH2F, {femtoObsAxis, multAxis}); - kHistogramRegistry->add((folderName + "/hNoMCtruthPairsCounter").c_str(), "; Counter; Entries", kTH1I, {{1, 0, 1}}); - kHistogramRegistry->add((folderName + "/hFakePairsCounter").c_str(), "; Counter; Entries", kTH1I, {{1, 0, 1}}); - kHistogramRegistry->add((folderName + "/kstar_resolution").c_str(), "; #it{k} _{T} reconstructed (GeV/#it{c}); #it{k} _{T} truth (GeV/#it{c})", kTH2F, {femtoObsAxis, femtoObsAxis}); + kHistogramRegistry->add((folderName + "/relPairDist_ReconNoFake").c_str(), ("; " + femtoObs + "; Entries").c_str(), o2::framework::kTH1F, {femtoObsAxis}); + kHistogramRegistry->add((folderName + "/relPairkstarmT_ReconNoFake").c_str(), ("; " + femtoObs + "; #it{m}_{T} (GeV/#it{c}^{2})").c_str(), o2::framework::kTH2F, {femtoObsAxis, mTAxis}); + kHistogramRegistry->add((folderName + "/relPairkstarMult_ReconNoFake").c_str(), ("; " + femtoObs + "; Multiplicity").c_str(), o2::framework::kTH2F, {femtoObsAxis, multAxis}); + kHistogramRegistry->add((folderName + "/hNoMCtruthPairsCounter").c_str(), "; Counter; Entries", o2::framework::kTH1I, {{1, 0, 1}}); + kHistogramRegistry->add((folderName + "/hFakePairsCounter").c_str(), "; Counter; Entries", o2::framework::kTH1I, {{1, 0, 1}}); + kHistogramRegistry->add((folderName + "/kstar_resolution").c_str(), "; #it{k} _{T} reconstructed (GeV/#it{c}); #it{k} _{T} truth (GeV/#it{c})", o2::framework::kTH2F, {femtoObsAxis, femtoObsAxis}); } /// Templated function to initialize the histograms for the task @@ -116,7 +114,7 @@ class FemtoUniverseFemtoContainer /// \param mTBins mT binning for the histograms /// \param isMC add Monte Carlo truth histograms to the output file template - void init(HistogramRegistry* registry, T& kstarBins, T& multBins, T& kTBins, T& mTBins, T& multBins3D, T& mTBins3D, bool isMC, bool use3dplots) + void init(o2::framework::HistogramRegistry* registry, T& kstarBins, T& multBins, T& kTBins, T& mTBins, T& multBins3D, T& mTBins3D, bool isMC, bool use3dplots) { kHistogramRegistry = registry; std::string femtoObs; @@ -242,7 +240,7 @@ class FemtoUniverseFemtoContainer } protected: - HistogramRegistry* kHistogramRegistry = nullptr; ///< For QA output + o2::framework::HistogramRegistry* kHistogramRegistry = nullptr; ///< For QA output static constexpr std::string_view kFolderSuffix[2] = {"SameEvent", "MixedEvent"}; ///< Folder naming for the output according to kEventType static constexpr femto_universe_femto_container::Observable kFemtoObs = obs; ///< Femtoscopic observable to be computed (according to femto_universe_femto_container::Observable) static constexpr int kEventType = eventType; ///< Type of the event (same/mixed, according to femto_universe_femto_container::EventType) diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverseMath.h b/PWGCF/FemtoUniverse/Core/FemtoUniverseMath.h index 680fc61eaf7..96682ffd04d 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniverseMath.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniverseMath.h @@ -19,12 +19,12 @@ #ifndef PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSEMATH_H_ #define PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSEMATH_H_ -#include "Math/Boost.h" -#include "Math/Vector4D.h" -#include "TLorentzVector.h" -#include "TMath.h" +#include +#include // IWYU pragma: keep (do not replace with Math/Vector4Dfwd.h) +#include +#include -#include +#include #include namespace o2::analysis::femto_universe diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverseObjectSelection.h b/PWGCF/FemtoUniverse/Core/FemtoUniverseObjectSelection.h index 8487ef11bc0..6364246c4fb 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniverseObjectSelection.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniverseObjectSelection.h @@ -20,16 +20,17 @@ #include "PWGCF/FemtoUniverse/Core/FemtoUniverseSelection.h" #include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" -#include "Framework/HistogramRegistry.h" -#include "ReconstructionDataFormats/PID.h" +#include +#include +#include + +#include #include +#include #include #include -using namespace o2; -using namespace o2::framework; - namespace o2::analysis { namespace femto_universe @@ -54,7 +55,7 @@ class FemtoUniverseObjectSelection { int nBins = mSelections.size(); LOGF(info, "%s", (static_cast(o2::aod::femtouniverseparticle::ParticleTypeName[part]) + "/cuthist").c_str()); - mHistogramRegistry->add((static_cast(o2::aod::femtouniverseparticle::ParticleTypeName[part]) + "/cuthist").c_str(), "; Cut; Value", kTH1F, {{nBins, 0, static_cast(nBins)}}); + mHistogramRegistry->add((static_cast(o2::aod::femtouniverseparticle::ParticleTypeName[part]) + "/cuthist").c_str(), "; Cut; Value", o2::framework::kTH1F, {{nBins, 0, static_cast(nBins)}}); auto hist = mHistogramRegistry->get(HIST(o2::aod::femtouniverseparticle::ParticleTypeName[part]) + HIST("/cuthist")); for (size_t i = 0; i < mSelections.size(); ++i) { hist->GetXaxis()->SetBinLabel(i + 1, Form("%u", mSelections.at(i).getSelectionVariable())); @@ -191,7 +192,7 @@ class FemtoUniverseObjectSelection } protected: - HistogramRegistry* mHistogramRegistry; ///< For QA output + o2::framework::HistogramRegistry* mHistogramRegistry; ///< For QA output std::vector> mSelections; ///< Vector containing all selections }; diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniversePairAngularWithCentMultKt.h b/PWGCF/FemtoUniverse/Core/FemtoUniversePairAngularWithCentMultKt.h index b63455ee3cf..744bff7f274 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniversePairAngularWithCentMultKt.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniversePairAngularWithCentMultKt.h @@ -17,9 +17,13 @@ #ifndef PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSEPAIRANGULARWITHCENTMULTKT_H_ #define PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSEPAIRANGULARWITHCENTMULTKT_H_ -#include "Framework/HistogramRegistry.h" +#include +#include +#include +#include #include +#include #include namespace o2::analysis::femto_universe @@ -34,10 +38,10 @@ class FemtoUniversePairAngularWithCentMultKt /// @param kstarbins /// @param centmultbins template - void init(HistogramRegistry* registry, t1& /*kstarbins*/, t1& centmultbins, t2& phiBins, t2& etaBins, bool processKT) + void init(framework::HistogramRegistry* registry, t1& /*kstarbins*/, t1& centmultbins, t2& phiBins, t2& etaBins, bool processKT) { pairWithCentMultKtRegistry = registry; - // AxisSpec kstarAxis = {kstarbins, "#it{k*} (GeV/#it{c})"}; + // o2::framework::AxisSpec kstarAxis = {kstarbins, "#it{k*} (GeV/#it{c})"}; kPhiLow = (-static_cast(phiBins / 4) + 0.5) * o2::constants::math::TwoPI / phiBins; kPhiHigh = o2::constants::math::TwoPI + (-static_cast(phiBins / 4) + 0.5) * o2::constants::math::TwoPI / phiBins; @@ -58,7 +62,7 @@ class FemtoUniversePairAngularWithCentMultKt std::string kHistSuffix2 = static_cast(HistSuffix[i + 1]); std::string kHistFolderMult = "mult_" + kHistSuffix1 + "_" + kHistSuffix2; std::string kHistName = kHistFolderMult + "/DeltaEtaDeltaPhi"; - pairWithCentMultKtRegistry->add(kHistName.c_str(), kHistTitle.c_str(), HistType::kTH2F, {phiAxis, etaAxis}); + pairWithCentMultKtRegistry->add(kHistName.c_str(), kHistTitle.c_str(), framework::HistType::kTH2F, {phiAxis, etaAxis}); if (useKt) { for (int i = 0; i < static_cast(ktBins.size() - 1); i++) { std::string ktBin1String = std::to_string(ktBins[i]); @@ -71,11 +75,11 @@ class FemtoUniversePairAngularWithCentMultKt std::string kHistSuffix1Kt = static_cast(HistSuffix[i]); std::string kHistSuffix2Kt = static_cast(HistSuffix[i + 1]); std::string kHistNameKt = kHistFolderMult + "/DeltaEtaDeltaPhi" + kHistSuffix1Kt + "_" + kHistSuffix2Kt; - pairWithCentMultKtRegistry->add(kHistNameKt.c_str(), kHistTitleKt.c_str(), HistType::kTH2F, {phiAxis, etaAxis}); + pairWithCentMultKtRegistry->add(kHistNameKt.c_str(), kHistTitleKt.c_str(), framework::HistType::kTH2F, {phiAxis, etaAxis}); } } } - pairWithCentMultKtRegistry->add("Beyond_Max", "Beyond_Max", HistType::kTH2F, {phiAxis, etaAxis}); + pairWithCentMultKtRegistry->add("Beyond_Max", "Beyond_Max", framework::HistType::kTH2F, {phiAxis, etaAxis}); } /// @brief @@ -176,7 +180,7 @@ class FemtoUniversePairAngularWithCentMultKt // } protected: - HistogramRegistry* pairWithCentMultKtRegistry = nullptr; + framework::HistogramRegistry* pairWithCentMultKtRegistry = nullptr; std::vector kCentMultBins; std::vector ktBins; bool useKt = false; diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniversePairCleaner.h b/PWGCF/FemtoUniverse/Core/FemtoUniversePairCleaner.h index 32da4810b85..b6db8a0b1cc 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniversePairCleaner.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniversePairCleaner.h @@ -21,7 +21,8 @@ #include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" -#include "Framework/HistogramRegistry.h" +#include +#include namespace o2::analysis::femto_universe { @@ -38,8 +39,8 @@ class FemtoUniversePairCleaner virtual ~FemtoUniversePairCleaner() = default; /// Initialization of the QA histograms - /// \param registry HistogramRegistry - void init(HistogramRegistry* registry) + /// \param registry o2::framework::HistogramRegistry + void init(framework::HistogramRegistry* registry) { if (registry) { mHistogramRegistry = registry; @@ -185,7 +186,7 @@ class FemtoUniversePairCleaner } private: - HistogramRegistry* mHistogramRegistry; ///< For QA output + framework::HistogramRegistry* mHistogramRegistry; ///< For QA output static constexpr o2::aod::femtouniverseparticle::ParticleType kPartOneType = partOne; ///< Type of particle 1 static constexpr o2::aod::femtouniverseparticle::ParticleType kPartTwoType = partTwo; ///< Type of particle 2 }; diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniversePairSHCentMultKt.h b/PWGCF/FemtoUniverse/Core/FemtoUniversePairSHCentMultKt.h index 9f5afb0ab1a..a1d65c44fc6 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniversePairSHCentMultKt.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniversePairSHCentMultKt.h @@ -16,17 +16,27 @@ #ifndef PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSEPAIRSHCENTMULTKT_H_ #define PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSEPAIRSHCENTMULTKT_H_ +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseMath.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseSHContainer.h" +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseSpherHarMath.h" -#include "Framework/HistogramRegistry.h" +#include +#include +#include +#include +#include +#include + +#include +#include #include +#include #include #include +#include #include -// using namespace o2::constants::physics; - namespace o2::analysis::femto_universe { @@ -50,11 +60,11 @@ class PairSHCentMultKt /// \param ktbins Number of kT bins /// \param maxl Maximum valie of L component of the spherical harmonics template - void init(HistogramRegistry* registry, t1& kstarbins, t1& centmultbins, + void init(framework::HistogramRegistry* registry, t1& kstarbins, t1& centmultbins, t1& ktbins, bool isqinvfill, int /*maxl*/) { pairSHCentMultKtRegistry = registry; - AxisSpec kstarAxis = {kstarbins, "#it{k*} (GeV/#it{c})"}; + framework::AxisSpec kstarAxis = {kstarbins, "#it{k*} (GeV/#it{c})"}; kStarBins = kstarbins; centMultBins = centmultbins; @@ -124,23 +134,23 @@ class PairSHCentMultKt if (FolderSuffix[EventType] == FolderSuffix[0]) { fnumsreal[i][j][ihist] = pairSHCentMultKtRegistry->add( (histFolderMult + "/" + histFolderkT + "/" + "NumRe" + suffix).c_str(), - ("; " + femtoObs1D + "; Entries").c_str(), kTH1D, {femtoObsAxis1D}); + ("; " + femtoObs1D + "; Entries").c_str(), framework::kTH1D, {femtoObsAxis1D}); fnumsimag[i][j][ihist] = pairSHCentMultKtRegistry->add( (histFolderMult + "/" + histFolderkT + "/" + "NumIm" + suffix).c_str(), - ("; " + femtoObs1D + "; Entries").c_str(), kTH1D, {femtoObsAxis1D}); + ("; " + femtoObs1D + "; Entries").c_str(), framework::kTH1D, {femtoObsAxis1D}); } else { fdensreal[i][j][ihist] = pairSHCentMultKtRegistry->add( (histFolderMult + "/" + histFolderkT + "/" + "DenRe" + suffix).c_str(), - ("; " + femtoObs1D + "; Entries").c_str(), kTH1D, {femtoObsAxis1D}); + ("; " + femtoObs1D + "; Entries").c_str(), framework::kTH1D, {femtoObsAxis1D}); fdensimag[i][j][ihist] = pairSHCentMultKtRegistry->add( (histFolderMult + "/" + histFolderkT + "/" + "DenIm" + suffix).c_str(), - ("; " + femtoObs1D + "; Entries").c_str(), kTH1D, {femtoObsAxis1D}); + ("; " + femtoObs1D + "; Entries").c_str(), framework::kTH1D, {femtoObsAxis1D}); } } if (FolderSuffix[EventType] == FolderSuffix[0]) { std::string bufnameNum = "CovNum"; - fcovnum[i][j] = pairSHCentMultKtRegistry->add((histFolderMult + "/" + histFolderkT + "/" + bufnameNum).c_str(), "; x; y; z", kTH3D, + fcovnum[i][j] = pairSHCentMultKtRegistry->add((histFolderMult + "/" + histFolderkT + "/" + bufnameNum).c_str(), "; x; y; z", framework::kTH3D, {{kstarbins}, {(kMaxJM * 2), -0.5, ((static_cast(kMaxJM) * 2.0 - 0.5))}, {(kMaxJM * 2), -0.5, @@ -148,7 +158,7 @@ class PairSHCentMultKt fcovnum[i][j]->Sumw2(); } else if (FolderSuffix[EventType] == FolderSuffix[1]) { std::string bufnameDen = "CovDen"; - fcovden[i][j] = pairSHCentMultKtRegistry->add((histFolderMult + "/" + histFolderkT + "/" + bufnameDen).c_str(), "; x; y; z", kTH3D, + fcovden[i][j] = pairSHCentMultKtRegistry->add((histFolderMult + "/" + histFolderkT + "/" + bufnameDen).c_str(), "; x; y; z", framework::kTH3D, {{kstarbins}, {(kMaxJM * 2), -0.5, ((static_cast(kMaxJM) * 2.0 - 0.5))}, {(kMaxJM * 2), -0.5, @@ -159,13 +169,13 @@ class PairSHCentMultKt std::string bufnameNum = "h1DNum"; fnums1D[i][j] = pairSHCentMultKtRegistry->add( (histFolderMult + "/" + histFolderkT + "/" + bufnameNum).c_str(), - ("; " + femtoObs1D + "; Entries").c_str(), kTH1D, {femtoObsAxis1D}); + ("; " + femtoObs1D + "; Entries").c_str(), framework::kTH1D, {femtoObsAxis1D}); fnums1D[i][j]->Sumw2(); } else if (FolderSuffix[EventType] == FolderSuffix[1]) { std::string bufnameNum = "h1DDen"; fdens1D[i][j] = pairSHCentMultKtRegistry->add( (histFolderMult + "/" + histFolderkT + "/" + bufnameNum).c_str(), - ("; " + femtoObs1D + "; Entries").c_str(), kTH1D, {femtoObsAxis1D}); + ("; " + femtoObs1D + "; Entries").c_str(), framework::kTH1D, {femtoObsAxis1D}); fdens1D[i][j]->Sumw2(); } } @@ -412,7 +422,7 @@ class PairSHCentMultKt std::array, 7>, 4> fcovden{}; protected: - HistogramRegistry* pairSHCentMultKtRegistry = nullptr; + framework::HistogramRegistry* pairSHCentMultKtRegistry = nullptr; static constexpr std::string_view FolderSuffix[2] = {"SameEvent", "MixedEvent"}; ///< Folder naming for the output according to EventType static constexpr int EventType = eventType; ///< Type of the event (same/mixed, according to FEMTOUNIVERSESHCONTAINER::EventType) float mMassOne = 0.f; ///< PDG mass of particle 1 diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniversePairWithCentMultKt.h b/PWGCF/FemtoUniverse/Core/FemtoUniversePairWithCentMultKt.h index f83f480347b..5944fc2f81d 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniversePairWithCentMultKt.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniversePairWithCentMultKt.h @@ -17,9 +17,13 @@ #ifndef PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSEPAIRWITHCENTMULTKT_H_ #define PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSEPAIRWITHCENTMULTKT_H_ -#include "Framework/HistogramRegistry.h" +#include +#include +#include +#include #include +#include #include namespace o2::analysis::femto_universe @@ -34,13 +38,13 @@ class FemtoUniversePairWithCentMultKt /// @param kstarbins /// @param centmultbins template - void init(HistogramRegistry* registry, t1& kstarbins, t1& centmultbins, t1& ktbins, bool processKT, bool process3D) + void init(framework::HistogramRegistry* registry, t1& kstarbins, t1& centmultbins, t1& ktbins, bool processKT, bool process3D) { pairWithCentMultKtRegistry = registry; - AxisSpec kstarAxis = {kstarbins, "#it{k*} (GeV/#it{c})"}; - AxisSpec kOutAxis = {kstarbins, "#it{q}_{out} (GeV/#it{c})"}; - AxisSpec kSideAxis = {kstarbins, "#it{q}_{side} (GeV/#it{c})"}; - AxisSpec kLongAxis = {kstarbins, "#it{q}_{long} (GeV/#it{c})"}; + framework::AxisSpec kstarAxis = {kstarbins, "#it{k*} (GeV/#it{c})"}; + framework::AxisSpec kOutAxis = {kstarbins, "#it{q}_{out} (GeV/#it{c})"}; + framework::AxisSpec kSideAxis = {kstarbins, "#it{q}_{side} (GeV/#it{c})"}; + framework::AxisSpec kLongAxis = {kstarbins, "#it{q}_{long} (GeV/#it{c})"}; centMultBins = centmultbins; ktBins = ktbins; ktBins.erase(ktBins.begin()); @@ -56,7 +60,7 @@ class FemtoUniversePairWithCentMultKt std::string histSuffix2 = static_cast(HistSuffix[i + 1]); std::string histFolderMult = "mult_" + histSuffix1 + "_" + histSuffix2; std::string histName = histFolderMult + "/kstar"; - pairWithCentMultKtRegistry->add(histName.c_str(), histTitle.c_str(), HistType::kTH1F, {kstarAxis}); + pairWithCentMultKtRegistry->add(histName.c_str(), histTitle.c_str(), framework::HistType::kTH1F, {kstarAxis}); if (useKt) { for (int i = 0; i < static_cast(ktBins.size() - 1); i++) { std::string ktBin1String = std::to_string(ktBins[i]); @@ -70,12 +74,12 @@ class FemtoUniversePairWithCentMultKt std::string histSuffix2Kt = static_cast(HistSuffix[i + 1]); std::string histNameKt = histFolderMult + "/kstar_kt_" + histSuffix1Kt + "_" + histSuffix2Kt; LOGF(info, "histNameKt %s", histNameKt); - pairWithCentMultKtRegistry->add(histNameKt.c_str(), histTitleKt.c_str(), HistType::kTH1F, {kstarAxis}); + pairWithCentMultKtRegistry->add(histNameKt.c_str(), histTitleKt.c_str(), framework::HistType::kTH1F, {kstarAxis}); } } if (use3D) { std::string histName3D = histFolderMult + "/q3D"; - pairWithCentMultKtRegistry->add(histName3D.c_str(), histTitle.c_str(), HistType::kTH3F, {kOutAxis, kSideAxis, kLongAxis}); + pairWithCentMultKtRegistry->add(histName3D.c_str(), histTitle.c_str(), framework::HistType::kTH3F, {kOutAxis, kSideAxis, kLongAxis}); for (int i = 0; i < static_cast(ktBins.size() - 1); i++) { std::string ktBin1String = std::to_string(ktBins[i]); std::replace(ktBin1String.begin(), ktBin1String.end(), '.', '_'); @@ -88,12 +92,12 @@ class FemtoUniversePairWithCentMultKt std::string histSuffix2Kt = static_cast(HistSuffix[i + 1]); std::string histNameKt = histFolderMult + "/q3D_kt_" + histSuffix1Kt + "_" + histSuffix2Kt; LOGF(info, "histNameKt %s", histNameKt); - pairWithCentMultKtRegistry->add(histNameKt.c_str(), histTitleKt.c_str(), HistType::kTH3F, {kOutAxis, kSideAxis, kLongAxis}); + pairWithCentMultKtRegistry->add(histNameKt.c_str(), histTitleKt.c_str(), framework::HistType::kTH3F, {kOutAxis, kSideAxis, kLongAxis}); } } } - pairWithCentMultKtRegistry->add("Beyond_Max", "Beyond_Max", HistType::kTH1F, {kstarAxis}); - pairWithCentMultKtRegistry->add("Beyond_Max_3D", "Beyond_Max_3D", HistType::kTH3F, {kOutAxis, kSideAxis, kLongAxis}); + pairWithCentMultKtRegistry->add("Beyond_Max", "Beyond_Max", framework::HistType::kTH1F, {kstarAxis}); + pairWithCentMultKtRegistry->add("Beyond_Max_3D", "Beyond_Max_3D", framework::HistType::kTH3F, {kOutAxis, kSideAxis, kLongAxis}); } /// @brief @@ -288,7 +292,7 @@ class FemtoUniversePairWithCentMultKt } protected: - HistogramRegistry* pairWithCentMultKtRegistry = nullptr; + framework::HistogramRegistry* pairWithCentMultKtRegistry = nullptr; std::vector centMultBins; std::vector ktBins; bool useKt = false; diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverseParticleHisto.h b/PWGCF/FemtoUniverse/Core/FemtoUniverseParticleHisto.h index 8a48e540c74..4816ab0c2fc 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniverseParticleHisto.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniverseParticleHisto.h @@ -22,15 +22,17 @@ #include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" -#include "CommonConstants/MathConstants.h" -#include "Framework/HistogramRegistry.h" +#include +#include +#include +#include +#include #include #include +#include -using namespace o2::framework; // o2-linter: disable=using-directive - -namespace o2::analysis::femto_universe // o2-linter: disable=name/namespace +namespace o2::analysis::femto_universe { /// \class FemtoUniverseParticleHisto @@ -57,14 +59,14 @@ class FemtoUniverseParticleHisto { std::string folderSuffix = static_cast(o2::aod::femtouniverse_mc_particle::MCTypeName[mc]).c_str(); /// Histograms of the kinematic properties - mHistogramRegistry->add((folderName + folderSuffix + "/hPt").c_str(), "; #it{p}_{T} (GeV/#it{c}); Entries", kTH1F, {tempFitVarpTAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hEta").c_str(), "; #eta; Entries", kTH1F, {{200, -1.5, 1.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hPhi").c_str(), "; #phi; Entries", kTH1F, {{200, 0, o2::constants::math::TwoPI}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hPhiEta").c_str(), "; #phi; #eta", kTH2F, {{200, 0, o2::constants::math::TwoPI}, {200, -1.5, 1.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hPt").c_str(), "; #it{p}_{T} (GeV/#it{c}); Entries", o2::framework::kTH1F, {tempFitVarpTAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hEta").c_str(), "; #eta; Entries", o2::framework::kTH1F, {{200, -1.5, 1.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hPhi").c_str(), "; #phi; Entries", o2::framework::kTH1F, {{200, 0, o2::constants::math::TwoPI}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hPhiEta").c_str(), "; #phi; #eta", o2::framework::kTH2F, {{200, 0, o2::constants::math::TwoPI}, {200, -1.5, 1.5}}); /// particle specific histogramms for the TempFitVar column in FemtoUniverseParticles if constexpr (o2::aod::femtouniverse_mc_particle::MCType::kRecon == mc) { - mHistogramRegistry->add((folderName + folderSuffix + static_cast(o2::aod::femtouniverseparticle::TempFitVarName[mParticleType])).c_str(), ("; #it{p}_{T} (GeV/#it{c}); " + tempFitVarAxisTitle).c_str(), kTH2F, {{tempFitVarpTAxis}, {tempFitVarAxis}}); + mHistogramRegistry->add((folderName + folderSuffix + static_cast(o2::aod::femtouniverseparticle::TempFitVarName[mParticleType])).c_str(), ("; #it{p}_{T} (GeV/#it{c}); " + tempFitVarAxisTitle).c_str(), o2::framework::kTH2F, {{tempFitVarpTAxis}, {tempFitVarAxis}}); } } @@ -74,53 +76,53 @@ class FemtoUniverseParticleHisto { std::string folderSuffix = static_cast(o2::aod::femtouniverse_mc_particle::MCTypeName[mc]).c_str(); if constexpr (mParticleType == o2::aod::femtouniverseparticle::ParticleType::kTrack || mParticleType == o2::aod::femtouniverseparticle::ParticleType::kV0Child || mParticleType == o2::aod::femtouniverseparticle::ParticleType::kCascadeBachelor || mParticleType == o2::aod::femtouniverseparticle::ParticleType::kMCTruthTrack) { - mHistogramRegistry->add((folderName + folderSuffix + "/hCharge").c_str(), "; Charge; Entries", kTH1F, {{5, -2.5, 2.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hTPCfindable").c_str(), "; TPC findable clusters; Entries", kTH1F, {{163, -0.5, 162.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hTPCfound").c_str(), "; TPC found clusters; Entries", kTH1F, {{163, -0.5, 162.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hTPCcrossedOverFindable").c_str(), "; TPC ratio findable; Entries", kTH1F, {{100, 0.5, 1.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hTPCcrossedRows").c_str(), "; TPC crossed rows; Entries", kTH1F, {{163, -0.5, 162.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hTPCfindableVsCrossed").c_str(), ";TPC findable clusters ; TPC crossed rows;", kTH2F, {{163, -0.5, 162.5}, {163, -0.5, 162.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hTPCshared").c_str(), "; TPC shared clusters; Entries", kTH1F, {{163, -0.5, 162.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hTPCfractionSharedCls").c_str(), "; TPC fraction of shared clusters; Entries", kTH1F, {{100, 0.0, 1.0}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hITSclusters").c_str(), "; ITS clusters; Entries", kTH1F, {{10, -0.5, 9.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hITSclustersIB").c_str(), "; ITS clusters in IB; Entries", kTH1F, {{10, -0.5, 9.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAz").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{z} (cm)", kTH2F, {{100, 0, 10}, {500, -5, 5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCA").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA (cm)", kTH2F, {{100, 0, 10}, {301, 0., 1.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hTPCdEdX").c_str(), "; #it{p} (GeV/#it{c}); TPC Signal", kTH2F, {{tempFitVarpTAxis}, {1000, 0, 1000}}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTPC_el").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TPC}^{e}", kTH2F, {{tempFitVarpTAxis}, {200, -4.975, 5.025}}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTPC_pi").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TPC}^{#pi}", kTH2F, {{tempFitVarpTAxis}, {200, -4.975, 5.025}}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTPC_K").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TPC}^{K}", kTH2F, {{tempFitVarpTAxis}, {200, -4.975, 5.025}}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTPC_p").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TPC}^{p}", kTH2F, {{tempFitVarpTAxis}, {200, -4.975, 5.025}}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTPC_d").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TPC}^{d}", kTH2F, {{tempFitVarpTAxis}, {200, -4.975, 5.025}}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTOF_el").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TOF}^{e}", kTH2F, {{tempFitVarpTAxis}, {200, -4.975, 5.025}}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTOF_pi").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TOF}^{#pi}", kTH2F, {{tempFitVarpTAxis}, {200, -4.975, 5.025}}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTOF_K").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TOF}^{K}", kTH2F, {{tempFitVarpTAxis}, {200, -4.975, 5.025}}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTOF_p").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TOF}^{p}", kTH2F, {{tempFitVarpTAxis}, {200, -4.975, 5.025}}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTOF_d").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TOF}^{d}", kTH2F, {{tempFitVarpTAxis}, {200, -4.975, 5.025}}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaComb_el").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{comb}^{e}", kTH2F, {{tempFitVarpTAxis}, {100, 0, 5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaComb_pi").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{comb}^{#pi}", kTH2F, {{tempFitVarpTAxis}, {100, 0, 5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaComb_K").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{comb}^{K}", kTH2F, {{tempFitVarpTAxis}, {100, 0, 5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaComb_p").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{comb}^{p}", kTH2F, {{tempFitVarpTAxis}, {100, 0, 5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaComb_d").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{comb}^{d}", kTH2F, {{tempFitVarpTAxis}, {100, 0, 5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hCharge").c_str(), "; Charge; Entries", o2::framework::kTH1F, {{5, -2.5, 2.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hTPCfindable").c_str(), "; TPC findable clusters; Entries", o2::framework::kTH1F, {{163, -0.5, 162.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hTPCfound").c_str(), "; TPC found clusters; Entries", o2::framework::kTH1F, {{163, -0.5, 162.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hTPCcrossedOverFindable").c_str(), "; TPC ratio findable; Entries", o2::framework::kTH1F, {{100, 0.5, 1.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hTPCcrossedRows").c_str(), "; TPC crossed rows; Entries", o2::framework::kTH1F, {{163, -0.5, 162.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hTPCfindableVsCrossed").c_str(), ";TPC findable clusters ; TPC crossed rows;", o2::framework::kTH2F, {{163, -0.5, 162.5}, {163, -0.5, 162.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hTPCshared").c_str(), "; TPC shared clusters; Entries", o2::framework::kTH1F, {{163, -0.5, 162.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hTPCfractionSharedCls").c_str(), "; TPC fraction of shared clusters; Entries", o2::framework::kTH1F, {{100, 0.0, 1.0}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hITSclusters").c_str(), "; ITS clusters; Entries", o2::framework::kTH1F, {{10, -0.5, 9.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hITSclustersIB").c_str(), "; ITS clusters in IB; Entries", o2::framework::kTH1F, {{10, -0.5, 9.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAz").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{z} (cm)", o2::framework::kTH2F, {{100, 0, 10}, {500, -5, 5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCA").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA (cm)", o2::framework::kTH2F, {{100, 0, 10}, {301, 0., 1.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hTPCdEdX").c_str(), "; #it{p} (GeV/#it{c}); TPC Signal", o2::framework::kTH2F, {{tempFitVarpTAxis}, {1000, 0, 1000}}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTPC_el").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TPC}^{e}", o2::framework::kTH2F, {{tempFitVarpTAxis}, {200, -4.975, 5.025}}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTPC_pi").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TPC}^{#pi}", o2::framework::kTH2F, {{tempFitVarpTAxis}, {200, -4.975, 5.025}}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTPC_K").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TPC}^{K}", o2::framework::kTH2F, {{tempFitVarpTAxis}, {200, -4.975, 5.025}}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTPC_p").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TPC}^{p}", o2::framework::kTH2F, {{tempFitVarpTAxis}, {200, -4.975, 5.025}}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTPC_d").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TPC}^{d}", o2::framework::kTH2F, {{tempFitVarpTAxis}, {200, -4.975, 5.025}}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTOF_el").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TOF}^{e}", o2::framework::kTH2F, {{tempFitVarpTAxis}, {200, -4.975, 5.025}}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTOF_pi").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TOF}^{#pi}", o2::framework::kTH2F, {{tempFitVarpTAxis}, {200, -4.975, 5.025}}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTOF_K").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TOF}^{K}", o2::framework::kTH2F, {{tempFitVarpTAxis}, {200, -4.975, 5.025}}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTOF_p").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TOF}^{p}", o2::framework::kTH2F, {{tempFitVarpTAxis}, {200, -4.975, 5.025}}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTOF_d").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TOF}^{d}", o2::framework::kTH2F, {{tempFitVarpTAxis}, {200, -4.975, 5.025}}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaComb_el").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{comb}^{e}", o2::framework::kTH2F, {{tempFitVarpTAxis}, {100, 0, 5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaComb_pi").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{comb}^{#pi}", o2::framework::kTH2F, {{tempFitVarpTAxis}, {100, 0, 5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaComb_K").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{comb}^{K}", o2::framework::kTH2F, {{tempFitVarpTAxis}, {100, 0, 5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaComb_p").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{comb}^{p}", o2::framework::kTH2F, {{tempFitVarpTAxis}, {100, 0, 5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaComb_d").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{comb}^{d}", o2::framework::kTH2F, {{tempFitVarpTAxis}, {100, 0, 5}}); } else if constexpr (mParticleType == o2::aod::femtouniverseparticle::ParticleType::kV0) { - mHistogramRegistry->add((folderName + folderSuffix + "/hDaughDCA").c_str(), "; DCA^{daugh} (cm); Entries", kTH1F, {{1000, 0, 10}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hTransRadius").c_str(), "; #it{r}_{xy} (cm); Entries", kTH1F, {{1500, 0, 150}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDecayVtxX").c_str(), "; #it{Vtx}_{x} (cm); Entries", kTH1F, {{2000, 0, 200}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDecayVtxY").c_str(), "; #it{Vtx}_{y} (cm)); Entries", kTH1F, {{2000, 0, 200}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDecayVtxZ").c_str(), "; #it{Vtx}_{z} (cm); Entries", kTH1F, {{2000, 0, 200}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hInvMassLambda").c_str(), "; M_{#Lambda}; Entries", kTH1F, {{2000, 1.f, 3.f}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hInvMassLambdaVsPt").c_str(), "; #it{p}_{T} (GeV/#it{c}); M_{#Lambda}; Entries", kTH2F, {{240, 0, 6}, {2000, 1.f, 3.f}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hInvMassAntiLambda").c_str(), "; M_{#bar{#Lambda}}; Entries", kTH1F, {{2000, 1.f, 3.f}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hInvMassAntiLambdaVsPt").c_str(), "; #it{p}_{T} (GeV/#it{c}); M_{#Lambda}; Entries", kTH2F, {{240, 0, 6}, {2000, 1.f, 3.f}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hInvMassLambdaAntiLambda").c_str(), "; M_{#Lambda}; M_{#bar{#Lambda}}", kTH2F, {{2000, 1.f, 3.f}, {2000, 1.f, 3.f}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDaughDCA").c_str(), "; DCA^{daugh} (cm); Entries", o2::framework::kTH1F, {{1000, 0, 10}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hTransRadius").c_str(), "; #it{r}_{xy} (cm); Entries", o2::framework::kTH1F, {{1500, 0, 150}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDecayVtxX").c_str(), "; #it{Vtx}_{x} (cm); Entries", o2::framework::kTH1F, {{2000, 0, 200}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDecayVtxY").c_str(), "; #it{Vtx}_{y} (cm)); Entries", o2::framework::kTH1F, {{2000, 0, 200}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDecayVtxZ").c_str(), "; #it{Vtx}_{z} (cm); Entries", o2::framework::kTH1F, {{2000, 0, 200}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hInvMassLambda").c_str(), "; M_{#Lambda}; Entries", o2::framework::kTH1F, {{2000, 1.f, 3.f}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hInvMassLambdaVsPt").c_str(), "; #it{p}_{T} (GeV/#it{c}); M_{#Lambda}; Entries", o2::framework::kTH2F, {{240, 0, 6}, {2000, 1.f, 3.f}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hInvMassAntiLambda").c_str(), "; M_{#bar{#Lambda}}; Entries", o2::framework::kTH1F, {{2000, 1.f, 3.f}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hInvMassAntiLambdaVsPt").c_str(), "; #it{p}_{T} (GeV/#it{c}); M_{#Lambda}; Entries", o2::framework::kTH2F, {{240, 0, 6}, {2000, 1.f, 3.f}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hInvMassLambdaAntiLambda").c_str(), "; M_{#Lambda}; M_{#bar{#Lambda}}", o2::framework::kTH2F, {{2000, 1.f, 3.f}, {2000, 1.f, 3.f}}); } else if constexpr (mParticleType == o2::aod::femtouniverseparticle::ParticleType::kCascade) { - mHistogramRegistry->add((folderName + folderSuffix + "/hDaughDCA").c_str(), "; DCA^{daugh} (cm); Entries", kTH1F, {{1000, 0, 10}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hTransRadius").c_str(), "; #it{r}_{xy} (cm); Entries", kTH1F, {{1500, 0, 150}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDecayVtxX").c_str(), "; #it{Vtx}_{x} (cm); Entries", kTH1F, {{2000, 0, 200}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDecayVtxY").c_str(), "; #it{Vtx}_{y} (cm)); Entries", kTH1F, {{2000, 0, 200}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDecayVtxZ").c_str(), "; #it{Vtx}_{z} (cm); Entries", kTH1F, {{2000, 0, 200}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hInvMassXi").c_str(), "; M_{Xi}; Entries", kTH1F, {{2000, 1.f, 1.8f}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hInvMassOmega").c_str(), "; M_{Omega}; Entries", kTH1F, {{2000, 1.f, 1.8f}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDaughDCA").c_str(), "; DCA^{daugh} (cm); Entries", o2::framework::kTH1F, {{1000, 0, 10}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hTransRadius").c_str(), "; #it{r}_{xy} (cm); Entries", o2::framework::kTH1F, {{1500, 0, 150}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDecayVtxX").c_str(), "; #it{Vtx}_{x} (cm); Entries", o2::framework::kTH1F, {{2000, 0, 200}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDecayVtxY").c_str(), "; #it{Vtx}_{y} (cm)); Entries", o2::framework::kTH1F, {{2000, 0, 200}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDecayVtxZ").c_str(), "; #it{Vtx}_{z} (cm); Entries", o2::framework::kTH1F, {{2000, 0, 200}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hInvMassXi").c_str(), "; M_{Xi}; Entries", o2::framework::kTH1F, {{2000, 1.f, 1.8f}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hInvMassOmega").c_str(), "; M_{Omega}; Entries", o2::framework::kTH1F, {{2000, 1.f, 1.8f}}); } } @@ -137,50 +139,50 @@ class FemtoUniverseParticleHisto /// Particle-type specific histograms std::string folderSuffix = static_cast(o2::aod::femtouniverse_mc_particle::MCTypeName[o2::aod::femtouniverse_mc_particle::MCType::kTruth]).c_str(); - mHistogramRegistry->add((folderName + folderSuffix + "/hPt_ReconNoFake").c_str(), "; #it{p}_{T} (GeV/#it{c}); Entries", kTH1F, {tempFitVarpTAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hPDG").c_str(), "; PDG; Entries", kTH1I, {{6001, -3000, 3000}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hOrigin_MC").c_str(), "; Origin; Entries", kTH1I, {{100, 0, 100}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hNoMCtruthCounter").c_str(), "; Counter; Entries", kTH1I, {{1, 0, 1}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hPt_ReconNoFake").c_str(), "; #it{p}_{T} (GeV/#it{c}); Entries", o2::framework::kTH1F, {tempFitVarpTAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hPDG").c_str(), "; PDG; Entries", o2::framework::kTH1I, {{6001, -3000, 3000}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hOrigin_MC").c_str(), "; Origin; Entries", o2::framework::kTH1I, {{100, 0, 100}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hNoMCtruthCounter").c_str(), "; Counter; Entries", o2::framework::kTH1I, {{1, 0, 1}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hTrueRecoMomPart1").c_str(), "; #it{p}_{reco} (GeV/#it{c}); #it{p}_{truth} - #it{p}_{reco} (GeV/#it{c})", kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hTrueRecoThetaPart1").c_str(), "; #it{p}_{reco} (GeV/#it{c}); #it{#theta}_{truth} - #it{#theta}_{reco} (GeV/#it{c})", kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hTrueRecoPhiPart1").c_str(), "; #it{p}_{reco} (GeV/#it{c}); #it{#phi}_{truth} - #it{#phi}_{reco} (GeV/#it{c})", kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hTrueRecoMomPart1").c_str(), "; #it{p}_{reco} (GeV/#it{c}); #it{p}_{truth} - #it{p}_{reco} (GeV/#it{c})", o2::framework::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hTrueRecoThetaPart1").c_str(), "; #it{p}_{reco} (GeV/#it{c}); #it{#theta}_{truth} - #it{#theta}_{reco} (GeV/#it{c})", o2::framework::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hTrueRecoPhiPart1").c_str(), "; #it{p}_{reco} (GeV/#it{c}); #it{#phi}_{truth} - #it{#phi}_{reco} (GeV/#it{c})", o2::framework::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); if constexpr (mParticleType == o2::aod::femtouniverseparticle::ParticleType::kTrack || mParticleType == o2::aod::femtouniverseparticle::ParticleType::kV0Child || mParticleType == o2::aod::femtouniverseparticle::ParticleType::kCascadeBachelor || mParticleType == o2::aod::femtouniverseparticle::ParticleType::kMCTruthTrack) { /// Track histograms if (isDebug) { - mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_Primary").c_str(), "; PDG mother; Entries", kTH1I, {{6001, -3000.5, 3000.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_Daughter").c_str(), "; PDG mother; Entries", kTH1I, {{6001, -3000.5, 3000.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_Material").c_str(), "; PDG mother; Entries", kTH1I, {{6001, -3000.5, 3000.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_WrongCollision").c_str(), "; PDG mother; Entries", kTH1I, {{6001, -3000.5, 3000.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_Fake").c_str(), "; PDG mother; Entries", kTH1I, {{6001, -3000.5, 3000.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_Else").c_str(), "; PDG mother; Entries", kTH1I, {{6001, -3000.5, 3000.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_DaughterLambda").c_str(), "; PDG mother; Entries", kTH1I, {{12001, -6000.5, 6000.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_DaughterSigmaplus").c_str(), "; PDG mother; Entries", kTH1I, {{12001, -6000.5, 6000.5}}); - - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Primary").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Daughter").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Material").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_WrongCollision").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Fake").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Else").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_DaughterLambda").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_DaughterSigmaplus").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_NoMCTruthOrigin").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hMisidentification").c_str(), "; #it{p}_{T} (GeV/#it{c}); Particle; Particle", kTH3F, {{4, 0, 4}, {4, 0, 4}, tempFitVarpTAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_Primary").c_str(), "; PDG mother; Entries", o2::framework::kTH1I, {{6001, -3000.5, 3000.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_Daughter").c_str(), "; PDG mother; Entries", o2::framework::kTH1I, {{6001, -3000.5, 3000.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_Material").c_str(), "; PDG mother; Entries", o2::framework::kTH1I, {{6001, -3000.5, 3000.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_WrongCollision").c_str(), "; PDG mother; Entries", o2::framework::kTH1I, {{6001, -3000.5, 3000.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_Fake").c_str(), "; PDG mother; Entries", o2::framework::kTH1I, {{6001, -3000.5, 3000.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_Else").c_str(), "; PDG mother; Entries", o2::framework::kTH1I, {{6001, -3000.5, 3000.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_DaughterLambda").c_str(), "; PDG mother; Entries", o2::framework::kTH1I, {{12001, -6000.5, 6000.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_DaughterSigmaplus").c_str(), "; PDG mother; Entries", o2::framework::kTH1I, {{12001, -6000.5, 6000.5}}); + + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Primary").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Daughter").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Material").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_WrongCollision").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Fake").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Else").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_DaughterLambda").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_DaughterSigmaplus").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_NoMCTruthOrigin").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hMisidentification").c_str(), "; #it{p}_{T} (GeV/#it{c}); Particle; Particle", o2::framework::kTH3F, {{4, 0, 4}, {4, 0, 4}, tempFitVarpTAxis}); } else { - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Primary").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Daughter").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Material").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_WrongCollision").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Fake").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Else").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_NoMCTruthOrigin").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hMisidentification").c_str(), "; #it{p}_{T} (GeV/#it{c}); Particle; Particle", kTH3F, {{4, 0, 4}, {4, 0, 4}, tempFitVarpTAxis}); - - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_DaughterLambda").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); - mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_DaughterSigmaplus").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Primary").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Daughter").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Material").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_WrongCollision").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Fake").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Else").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_NoMCTruthOrigin").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hMisidentification").c_str(), "; #it{p}_{T} (GeV/#it{c}); Particle; Particle", o2::framework::kTH3F, {{4, 0, 4}, {4, 0, 4}, tempFitVarpTAxis}); + + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_DaughterLambda").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_DaughterSigmaplus").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); } } else if constexpr (mParticleType == o2::aod::femtouniverseparticle::ParticleType::kV0) { @@ -208,7 +210,7 @@ class FemtoUniverseParticleHisto /// \param tempFitVarBins binning of the tempFitVar (DCA_xy in case of tracks, CPA in case of V0s, etc.) /// \param isMC add Monte Carlo truth histograms to the output file template - void init(HistogramRegistry* registry, T& tempFitVarpTBins, T& tempFitVarBins, bool isMC, int pdgCode, bool isDebug = false, std::optional flexibleFolder = std::nullopt) + void init(o2::framework::HistogramRegistry* registry, T& tempFitVarpTBins, T& tempFitVarBins, bool isMC, int pdgCode, bool isDebug = false, std::optional flexibleFolder = std::nullopt) { mPDG = pdgCode; if (registry) { @@ -537,7 +539,7 @@ class FemtoUniverseParticleHisto } private: - HistogramRegistry* mHistogramRegistry; ///< For QA output + o2::framework::HistogramRegistry* mHistogramRegistry; ///< For QA output static constexpr o2::aod::femtouniverseparticle::ParticleType mParticleType = particleType; ///< Type of the particle under analysis // o2-linter: disable=name/constexpr-constant static constexpr int mFolderSuffixType = suffixType; ///< Counter for the folder suffix specified below // o2-linter: disable=name/constexpr-constant static constexpr std::string_view mFolderSuffix[5] = {"", "_one", "_two", "_pos", "_neg"}; ///< Suffix for the folder name in case of analyses of pairs of the same kind (T-T, V-V, C-C) // o2-linter: disable=name/constexpr-constant diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniversePhiSelection.h b/PWGCF/FemtoUniverse/Core/FemtoUniversePhiSelection.h index c43217ceb72..18e2f3ada22 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniversePhiSelection.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniversePhiSelection.h @@ -22,15 +22,23 @@ #include "PWGCF/FemtoUniverse/Core/FemtoUniverseObjectSelection.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseSelection.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseTrackSelection.h" +#include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" #include "Common/Core/RecoDecay.h" -#include "Framework/HistogramRegistry.h" -#include "ReconstructionDataFormats/PID.h" +#include +#include +#include +#include +#include -#include "TLorentzVector.h" +#include +#include +#include +#include #include +#include #include namespace o2::analysis::femto_universe @@ -75,7 +83,7 @@ class FemtoUniversePhiSelection template - void init(HistogramRegistry* registry); + void init(o2::framework::HistogramRegistry* registry); template bool isSelectedMinimal(C const& col, V const& phi, T const& posTrack, @@ -276,7 +284,7 @@ class FemtoUniversePhiSelection template -void FemtoUniversePhiSelection::init(HistogramRegistry* registry) +void FemtoUniversePhiSelection::init(o2::framework::HistogramRegistry* registry) { if (registry) { @@ -284,10 +292,10 @@ void FemtoUniversePhiSelection::init(HistogramRegistry* registry) fillSelectionHistogram(); fillSelectionHistogram(); - AxisSpec massAxisPhi = {6000, 0.9f, 3.0f, "m_{#Phi} (GeV/#it{c}^{2})"}; - AxisSpec massAxisLambda = {600, 0.0f, 3.0f, "m_{#Lambda} (GeV/#it{c}^{2})"}; - AxisSpec massAxisAntiLambda = {600, 0.0f, 3.0f, - "m_{#bar{#Lambda}} (GeV/#it{c}^{2})"}; + o2::framework::AxisSpec massAxisPhi = {6000, 0.9f, 3.0f, "m_{#Phi} (GeV/#it{c}^{2})"}; + o2::framework::AxisSpec massAxisLambda = {600, 0.0f, 3.0f, "m_{#Lambda} (GeV/#it{c}^{2})"}; + o2::framework::AxisSpec massAxisAntiLambda = {600, 0.0f, 3.0f, + "m_{#bar{#Lambda}} (GeV/#it{c}^{2})"}; /// \todo this should be an automatic check in the parent class, and the /// return type should be templated @@ -300,13 +308,13 @@ void FemtoUniversePhiSelection::init(HistogramRegistry* registry) o2::aod::femtouniverseparticle::ParticleTypeName[part]); /// \todo initialize histograms for children tracks of phis mHistogramRegistry->add((folderName + "/hPt").c_str(), - "; #it{p}_{T} (GeV/#it{c}); Entries", kTH1F, + "; #it{p}_{T} (GeV/#it{c}); Entries", o2::framework::kTH1F, {{1000, 0, 10}}); mHistogramRegistry->add((folderName + "/hEta").c_str(), "; #eta; Entries", - kTH1F, {{1000, -1, 1}}); + o2::framework::kTH1F, {{1000, -1, 1}}); mHistogramRegistry->add((folderName + "/hPhi").c_str(), "; #phi; Entries", - kTH1F, {{1000, 0, o2::constants::math::TwoPI}}); - mHistogramRegistry->add((folderName + "/hInvMassPhi").c_str(), "", kTH1F, + o2::framework::kTH1F, {{1000, 0, o2::constants::math::TwoPI}}); + mHistogramRegistry->add((folderName + "/hInvMassPhi").c_str(), "", o2::framework::kTH1F, {massAxisPhi}); posDaughTrack.init( mHistogramRegistry); - // mHistogramRegistry->add("LambdaQA/hInvMassLambdaNoCuts", "No cuts", kTH1F, + // mHistogramRegistry->add("LambdaQA/hInvMassLambdaNoCuts", "No cuts", o2::framework::kTH1F, // {massAxisLambda}); // mHistogramRegistry->add("LambdaQA/hInvMassLambdaInvMassCut", - // "Invariant mass cut", kTH1F, {massAxisLambda}); + // "Invariant mass cut", o2::framework::kTH1F, {massAxisLambda}); // mHistogramRegistry->add("LambdaQA/hInvMassLambdaPtMin", "Minimum Pt cut", - // kTH1F, {massAxisLambda}); + // o2::framework::kTH1F, {massAxisLambda}); // mHistogramRegistry->add("LambdaQA/hInvMassLambdaPtMax", "Maximum Pt cut", - // kTH1F, {massAxisLambda}); + // o2::framework::kTH1F, {massAxisLambda}); // mHistogramRegistry->add("LambdaQA/hInvMassLambdaEtaMax", "Maximum Eta cut", - // kTH1F, {massAxisLambda}); + // o2::framework::kTH1F, {massAxisLambda}); // mHistogramRegistry->add("LambdaQA/hInvMassLambdaDCAPhiDaugh", - // "Phi-daughters DCA cut", kTH1F, {massAxisLambda}); - // mHistogramRegistry->add("LambdaQA/hInvMassLambdaCPA", "CPA cut", kTH1F, + // "Phi-daughters DCA cut", o2::framework::kTH1F, {massAxisLambda}); + // mHistogramRegistry->add("LambdaQA/hInvMassLambdaCPA", "CPA cut", o2::framework::kTH1F, // {massAxisLambda}); // mHistogramRegistry->add("LambdaQA/hInvMassLambdaTranRadMin", - // "Minimum transverse radius cut", kTH1F, + // "Minimum transverse radius cut", o2::framework::kTH1F, // {massAxisLambda}); // mHistogramRegistry->add("LambdaQA/hInvMassLambdaTranRadMax", - // "Maximum transverse radius cut", kTH1F, + // "Maximum transverse radius cut", o2::framework::kTH1F, // {massAxisLambda}); // mHistogramRegistry->add("LambdaQA/hInvMassLambdaDecVtxMax", - // "Maximum distance on decay vertex cut", kTH1F, + // "Maximum distance on decay vertex cut", o2::framework::kTH1F, // {massAxisLambda}); } /// check whether the most open cuts are fulfilled - most of this should have diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverseSHContainer.h b/PWGCF/FemtoUniverse/Core/FemtoUniverseSHContainer.h index b99cccb338a..a529a9f0c94 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniverseSHContainer.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniverseSHContainer.h @@ -19,17 +19,22 @@ #include "PWGCF/FemtoUniverse/Core/FemtoUniverseMath.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseSpherHarMath.h" +#include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" -#include "Framework/HistogramRegistry.h" -#include +#include +#include -#include "Math/Vector4D.h" -#include "TDatabasePDG.h" -#include "TMath.h" +#include +#include +#include +#include +#include #include +#include #include #include +#include #include namespace o2::analysis::femto_universe @@ -67,7 +72,7 @@ class FemtoUniverseSHContainer /// \param registry Histogram registry to be passed /// \param kstarbins k* binning for the histograms template - void init(HistogramRegistry* registry, T& kstarbins, int /*maxl*/) + void init(framework::HistogramRegistry* registry, T& kstarbins, int /*maxl*/) { kStarBins = kstarbins; std::string femtoObs1D; @@ -110,20 +115,20 @@ class FemtoUniverseSHContainer } if (kFolderSuffix[kEventType] == kFolderSuffix[0]) { - fnumsreal[ihist] = kHistogramRegistry->add(("NumRe" + suffix).c_str(), ("; " + femtoObs1D + "; Entries").c_str(), kTH1D, {femtoObsAxis1D}); - fnumsimag[ihist] = kHistogramRegistry->add(("NumIm" + suffix).c_str(), ("; " + femtoObs1D + "; Entries").c_str(), kTH1D, {femtoObsAxis1D}); + fnumsreal[ihist] = kHistogramRegistry->add(("NumRe" + suffix).c_str(), ("; " + femtoObs1D + "; Entries").c_str(), framework::kTH1D, {femtoObsAxis1D}); + fnumsimag[ihist] = kHistogramRegistry->add(("NumIm" + suffix).c_str(), ("; " + femtoObs1D + "; Entries").c_str(), framework::kTH1D, {femtoObsAxis1D}); } else { - fdensreal[ihist] = kHistogramRegistry->add(("DenRe" + suffix).c_str(), ("; " + femtoObs1D + "; Entries").c_str(), kTH1D, {femtoObsAxis1D}); - fdensimag[ihist] = kHistogramRegistry->add(("DenIm" + suffix).c_str(), ("; " + femtoObs1D + "; Entries").c_str(), kTH1D, {femtoObsAxis1D}); + fdensreal[ihist] = kHistogramRegistry->add(("DenRe" + suffix).c_str(), ("; " + femtoObs1D + "; Entries").c_str(), framework::kTH1D, {femtoObsAxis1D}); + fdensimag[ihist] = kHistogramRegistry->add(("DenIm" + suffix).c_str(), ("; " + femtoObs1D + "; Entries").c_str(), framework::kTH1D, {femtoObsAxis1D}); } } if (kFolderSuffix[kEventType] == kFolderSuffix[0]) { std::string bufnameNum = "CovNum"; - fcovnum = kHistogramRegistry->add((bufnameNum).c_str(), "; x; y; z", kTH3D, {{kstarbins}, {(kMaxJM * 2), -0.5, ((static_cast(kMaxJM) * 2.0 - 0.5))}, {(kMaxJM * 2), -0.5, ((static_cast(kMaxJM) * 2.0 - 0.5))}}); + fcovnum = kHistogramRegistry->add((bufnameNum).c_str(), "; x; y; z", framework::kTH3D, {{kstarbins}, {(kMaxJM * 2), -0.5, ((static_cast(kMaxJM) * 2.0 - 0.5))}, {(kMaxJM * 2), -0.5, ((static_cast(kMaxJM) * 2.0 - 0.5))}}); } else if (kFolderSuffix[kEventType] == kFolderSuffix[1]) { std::string bufnameDen = "CovDen"; - fcovden = kHistogramRegistry->add((bufnameDen).c_str(), "; x; y; z", kTH3D, {{kstarbins}, {(kMaxJM * 2), -0.5, ((static_cast(kMaxJM) * 2.0 - 0.5))}, {(kMaxJM * 2), -0.5, ((static_cast(kMaxJM) * 2.0 - 0.5))}}); + fcovden = kHistogramRegistry->add((bufnameDen).c_str(), "; x; y; z", framework::kTH3D, {{kstarbins}, {(kMaxJM * 2), -0.5, ((static_cast(kMaxJM) * 2.0 - 0.5))}, {(kMaxJM * 2), -0.5, ((static_cast(kMaxJM) * 2.0 - 0.5))}}); } fbinctn = new TH1D(TString("BinCountNum"), "Bin Occupation (Numerator)", static_cast(kStarBins[0]), kStarBins[1], kStarBins[2]); @@ -257,7 +262,7 @@ class FemtoUniverseSHContainer std::array fcovmden{}; ///< Covariance matrix for the numerator protected: - HistogramRegistry* kHistogramRegistry = nullptr; ///< For QA output + framework::HistogramRegistry* kHistogramRegistry = nullptr; ///< For QA output static constexpr std::string_view kFolderSuffix[2] = {"SameEvent", "MixedEvent"}; ///< Folder naming for the output according to kEventType static constexpr int kEventType = eventType; ///< Type of the event (same/mixed, according to FEMTOUNIVERSESHCONTAINER::EventType) float kMassOne = 0.f; ///< PDG mass of particle 1 diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverseSelection.h b/PWGCF/FemtoUniverse/Core/FemtoUniverseSelection.h index 63d9646cdde..641647a3c65 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniverseSelection.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniverseSelection.h @@ -18,6 +18,7 @@ #define PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSESELECTION_H_ #include +#include namespace o2::analysis::femto_universe { diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverseSoftPionRemoval.h b/PWGCF/FemtoUniverse/Core/FemtoUniverseSoftPionRemoval.h index 4a97c83865d..66793386ff0 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniverseSoftPionRemoval.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniverseSoftPionRemoval.h @@ -18,7 +18,12 @@ #include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" -#include "Framework/HistogramRegistry.h" +#include "Common/Core/RecoDecay.h" + +#include +#include +#include +#include #include @@ -37,12 +42,12 @@ class FemtoUniverseSoftPionRemoval virtual ~FemtoUniverseSoftPionRemoval() = default; /// Initialization of the QA histograms - /// \param registry HistogramRegistry - void init(HistogramRegistry* registry) + /// \param registry o2::framework::HistogramRegistry + void init(framework::HistogramRegistry* registry) { if (registry) { mHistogramRegistry = registry; - mHistogramRegistry->add("SoftPion/softPionMassVsPt", "; M(K#pi#pi-K#pi); p_{T}", kTH2F, {{200, 0.0, 0.2}, {36, 0., 36.}}); + mHistogramRegistry->add("SoftPion/softPionMassVsPt", "; M(K#pi#pi-K#pi); p_{T}", framework::kTH2F, {{200, 0.0, 0.2}, {36, 0., 36.}}); } } @@ -112,7 +117,7 @@ class FemtoUniverseSoftPionRemoval } private: - HistogramRegistry* mHistogramRegistry; ///< For QA output + framework::HistogramRegistry* mHistogramRegistry; ///< For QA output static constexpr o2::aod::femtouniverseparticle::ParticleType kPartOneType = partOne; ///< Type of particle 1 static constexpr o2::aod::femtouniverseparticle::ParticleType kPartTwoType = partTwo; ///< Type of particle 2 }; diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverseSpherHarMath.h b/PWGCF/FemtoUniverse/Core/FemtoUniverseSpherHarMath.h index 082ddd25663..134ff2fe0a9 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniverseSpherHarMath.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniverseSpherHarMath.h @@ -16,14 +16,11 @@ #ifndef PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSESPHERHARMATH_H_ #define PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSESPHERHARMATH_H_ -#include "Math/Boost.h" -#include "Math/Vector4D.h" -#include "TLorentzVector.h" -#include "TMath.h" +#include -#include +#include +#include #include -#include namespace o2::analysis::femto_universe { diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverseTrackSelection.h b/PWGCF/FemtoUniverse/Core/FemtoUniverseTrackSelection.h index 3aee759b29b..ac8088aa084 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniverseTrackSelection.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniverseTrackSelection.h @@ -19,19 +19,23 @@ #define PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSETRACKSELECTION_H_ #include "PWGCF/FemtoUniverse/Core/FemtoUniverseObjectSelection.h" +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseSelection.h" #include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" -#include "Common/Core/TrackSelection.h" -#include "Common/Core/TrackSelectionDefaults.h" #include "Common/DataModel/PIDResponseTOF.h" #include "Common/DataModel/PIDResponseTPC.h" -#include "Common/DataModel/TrackSelectionTables.h" -#include "Framework/HistogramRegistry.h" -#include "ReconstructionDataFormats/PID.h" +#include +#include +#include +#include +#include +#include #include +#include #include +#include #include // using namespace o2::framework; @@ -103,9 +107,9 @@ class FemtoUniverseTrackSelection : public FemtoUniverseObjectSelection - void init(HistogramRegistry* registry); + void init(o2::framework::HistogramRegistry* registry); /// Passes the species to the task for which PID needs to be stored /// \tparam T Data type of the configurable passed to the functions @@ -301,7 +305,7 @@ class FemtoUniverseTrackSelection : public FemtoUniverseObjectSelection -void FemtoUniverseTrackSelection::init(HistogramRegistry* registry) +void FemtoUniverseTrackSelection::init(o2::framework::HistogramRegistry* registry) { if (registry) { mHistogramRegistry = registry; @@ -313,37 +317,37 @@ void FemtoUniverseTrackSelection::init(HistogramRegistry* registry) LOG(fatal) << "FemtoUniverseTrackCuts: Number of selections too large for your container - quitting!"; } - mHistogramRegistry->add((folderName + "/hPt").c_str(), "; #it{p}_{T} (GeV/#it{c}); Entries", kTH1F, {{240, 0, 6}}); - mHistogramRegistry->add((folderName + "/hEta").c_str(), "; #eta; Entries", kTH1F, {{200, -1.5, 1.5}}); - mHistogramRegistry->add((folderName + "/hPhi").c_str(), "; #phi; Entries", kTH1F, {{200, 0, o2::constants::math::TwoPI}}); - mHistogramRegistry->add((folderName + "/hTPCfindable").c_str(), "; TPC findable clusters; Entries", kTH1F, {{163, -0.5, 162.5}}); - mHistogramRegistry->add((folderName + "/hTPCfound").c_str(), "; TPC found clusters; Entries", kTH1F, {{163, -0.5, 162.5}}); - mHistogramRegistry->add((folderName + "/hTPCcrossedOverFindalbe").c_str(), "; TPC ratio findable; Entries", kTH1F, {{100, 0.5, 1.5}}); - mHistogramRegistry->add((folderName + "/hTPCcrossedRows").c_str(), "; TPC crossed rows; Entries", kTH1F, {{163, 0, 163}}); - mHistogramRegistry->add((folderName + "/hTPCfindableVsCrossed").c_str(), ";TPC findable clusters ; TPC crossed rows;", kTH2F, {{163, 0, 163}, {163, 0, 163}}); - mHistogramRegistry->add((folderName + "/hTPCshared").c_str(), "; TPC shared clusters; Entries", kTH1F, {{163, -0.5, 162.5}}); - mHistogramRegistry->add((folderName + "/hTPCfractionSharedCls").c_str(), "; TPC fraction of shared clusters; Entries", kTH1F, {{100, 0.0, 100.0}}); - mHistogramRegistry->add((folderName + "/hITSclusters").c_str(), "; ITS clusters; Entries", kTH1F, {{10, -0.5, 9.5}}); - mHistogramRegistry->add((folderName + "/hITSclustersIB").c_str(), "; ITS clusters in IB; Entries", kTH1F, {{10, -0.5, 9.5}}); - mHistogramRegistry->add((folderName + "/hDCAxy").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", kTH2F, {{100, 0, 10}, {500, -5, 5}}); - mHistogramRegistry->add((folderName + "/hDCAz").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{z} (cm)", kTH2F, {{100, 0, 10}, {500, -5, 5}}); - mHistogramRegistry->add((folderName + "/hDCA").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA (cm)", kTH2F, {{100, 0, 10}, {301, 0., 1.5}}); - mHistogramRegistry->add((folderName + "/hTPCdEdX").c_str(), "; #it{p} (GeV/#it{c}); TPC Signal", kTH2F, {{100, 0, 10}, {1000, 0, 1000}}); - mHistogramRegistry->add((folderName + "/nSigmaTPC_el").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TPC}^{e}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); - mHistogramRegistry->add((folderName + "/nSigmaTPC_pi").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TPC}^{#pi}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); - mHistogramRegistry->add((folderName + "/nSigmaTPC_K").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TPC}^{K}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); - mHistogramRegistry->add((folderName + "/nSigmaTPC_p").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TPC}^{p}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); - mHistogramRegistry->add((folderName + "/nSigmaTPC_d").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TPC}^{d}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); - mHistogramRegistry->add((folderName + "/nSigmaTOF_el").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TOF}^{e}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); - mHistogramRegistry->add((folderName + "/nSigmaTOF_pi").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TOF}^{#pi}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); - mHistogramRegistry->add((folderName + "/nSigmaTOF_K").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TOF}^{K}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); - mHistogramRegistry->add((folderName + "/nSigmaTOF_p").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TOF}^{p}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); - mHistogramRegistry->add((folderName + "/nSigmaTOF_d").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TOF}^{d}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); - mHistogramRegistry->add((folderName + "/nSigmaComb_el").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{comb}^{e}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); - mHistogramRegistry->add((folderName + "/nSigmaComb_pi").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{comb}^{#pi}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); - mHistogramRegistry->add((folderName + "/nSigmaComb_K").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{comb}^{K}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.0255}}); - mHistogramRegistry->add((folderName + "/nSigmaComb_p").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{comb}^{p}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); - mHistogramRegistry->add((folderName + "/nSigmaComb_d").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{comb}^{d}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); + mHistogramRegistry->add((folderName + "/hPt").c_str(), "; #it{p}_{T} (GeV/#it{c}); Entries", o2::framework::kTH1F, {{240, 0, 6}}); + mHistogramRegistry->add((folderName + "/hEta").c_str(), "; #eta; Entries", o2::framework::kTH1F, {{200, -1.5, 1.5}}); + mHistogramRegistry->add((folderName + "/hPhi").c_str(), "; #phi; Entries", o2::framework::kTH1F, {{200, 0, o2::constants::math::TwoPI}}); + mHistogramRegistry->add((folderName + "/hTPCfindable").c_str(), "; TPC findable clusters; Entries", o2::framework::kTH1F, {{163, -0.5, 162.5}}); + mHistogramRegistry->add((folderName + "/hTPCfound").c_str(), "; TPC found clusters; Entries", o2::framework::kTH1F, {{163, -0.5, 162.5}}); + mHistogramRegistry->add((folderName + "/hTPCcrossedOverFindalbe").c_str(), "; TPC ratio findable; Entries", o2::framework::kTH1F, {{100, 0.5, 1.5}}); + mHistogramRegistry->add((folderName + "/hTPCcrossedRows").c_str(), "; TPC crossed rows; Entries", o2::framework::kTH1F, {{163, 0, 163}}); + mHistogramRegistry->add((folderName + "/hTPCfindableVsCrossed").c_str(), ";TPC findable clusters ; TPC crossed rows;", o2::framework::kTH2F, {{163, 0, 163}, {163, 0, 163}}); + mHistogramRegistry->add((folderName + "/hTPCshared").c_str(), "; TPC shared clusters; Entries", o2::framework::kTH1F, {{163, -0.5, 162.5}}); + mHistogramRegistry->add((folderName + "/hTPCfractionSharedCls").c_str(), "; TPC fraction of shared clusters; Entries", o2::framework::kTH1F, {{100, 0.0, 100.0}}); + mHistogramRegistry->add((folderName + "/hITSclusters").c_str(), "; ITS clusters; Entries", o2::framework::kTH1F, {{10, -0.5, 9.5}}); + mHistogramRegistry->add((folderName + "/hITSclustersIB").c_str(), "; ITS clusters in IB; Entries", o2::framework::kTH1F, {{10, -0.5, 9.5}}); + mHistogramRegistry->add((folderName + "/hDCAxy").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::kTH2F, {{100, 0, 10}, {500, -5, 5}}); + mHistogramRegistry->add((folderName + "/hDCAz").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{z} (cm)", o2::framework::kTH2F, {{100, 0, 10}, {500, -5, 5}}); + mHistogramRegistry->add((folderName + "/hDCA").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA (cm)", o2::framework::kTH2F, {{100, 0, 10}, {301, 0., 1.5}}); + mHistogramRegistry->add((folderName + "/hTPCdEdX").c_str(), "; #it{p} (GeV/#it{c}); TPC Signal", o2::framework::kTH2F, {{100, 0, 10}, {1000, 0, 1000}}); + mHistogramRegistry->add((folderName + "/nSigmaTPC_el").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TPC}^{e}", o2::framework::kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); + mHistogramRegistry->add((folderName + "/nSigmaTPC_pi").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TPC}^{#pi}", o2::framework::kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); + mHistogramRegistry->add((folderName + "/nSigmaTPC_K").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TPC}^{K}", o2::framework::kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); + mHistogramRegistry->add((folderName + "/nSigmaTPC_p").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TPC}^{p}", o2::framework::kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); + mHistogramRegistry->add((folderName + "/nSigmaTPC_d").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TPC}^{d}", o2::framework::kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); + mHistogramRegistry->add((folderName + "/nSigmaTOF_el").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TOF}^{e}", o2::framework::kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); + mHistogramRegistry->add((folderName + "/nSigmaTOF_pi").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TOF}^{#pi}", o2::framework::kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); + mHistogramRegistry->add((folderName + "/nSigmaTOF_K").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TOF}^{K}", o2::framework::kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); + mHistogramRegistry->add((folderName + "/nSigmaTOF_p").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TOF}^{p}", o2::framework::kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); + mHistogramRegistry->add((folderName + "/nSigmaTOF_d").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TOF}^{d}", o2::framework::kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); + mHistogramRegistry->add((folderName + "/nSigmaComb_el").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{comb}^{e}", o2::framework::kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); + mHistogramRegistry->add((folderName + "/nSigmaComb_pi").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{comb}^{#pi}", o2::framework::kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); + mHistogramRegistry->add((folderName + "/nSigmaComb_K").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{comb}^{K}", o2::framework::kTH2F, {{100, 0, 10}, {200, -4.975, 5.0255}}); + mHistogramRegistry->add((folderName + "/nSigmaComb_p").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{comb}^{p}", o2::framework::kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); + mHistogramRegistry->add((folderName + "/nSigmaComb_d").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{comb}^{d}", o2::framework::kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); } /// set cuts nPtMinSel = getNSelections(femto_universe_track_selection::kpTMin); diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverseV0Selection.h b/PWGCF/FemtoUniverse/Core/FemtoUniverseV0Selection.h index 8b45f664f15..d3330ff6fc0 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniverseV0Selection.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniverseV0Selection.h @@ -22,13 +22,19 @@ #include "PWGCF/FemtoUniverse/Core/FemtoUniverseObjectSelection.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseSelection.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseTrackSelection.h" +#include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" -#include "Common/Core/RecoDecay.h" - -#include "Framework/HistogramRegistry.h" -#include "ReconstructionDataFormats/PID.h" +#include +#include +#include +#include +#include +#include +#include +#include #include +#include #include namespace o2::analysis::femto_universe @@ -73,7 +79,7 @@ class FemtoUniverseV0Selection template - void init(HistogramRegistry* registry); + void init(o2::framework::HistogramRegistry* registry); template bool isSelectedMinimal(C const& col, V const& v0, T const& posTrack, @@ -275,16 +281,16 @@ class FemtoUniverseV0Selection template -void FemtoUniverseV0Selection::init(HistogramRegistry* registry) +void FemtoUniverseV0Selection::init(o2::framework::HistogramRegistry* registry) { if (registry) { mHistogramRegistry = registry; fillSelectionHistogram(); fillSelectionHistogram(); - AxisSpec massAxisLambda = {600, 0.0f, 3.0f, "m_{#Lambda} (GeV/#it{c}^{2})"}; - AxisSpec massAxisAntiLambda = {600, 0.0f, 3.0f, - "m_{#bar{#Lambda}} (GeV/#it{c}^{2})"}; + o2::framework::AxisSpec massAxisLambda = {600, 0.0f, 3.0f, "m_{#Lambda} (GeV/#it{c}^{2})"}; + o2::framework::AxisSpec massAxisAntiLambda = {600, 0.0f, 3.0f, + "m_{#bar{#Lambda}} (GeV/#it{c}^{2})"}; /// \todo this should be an automatic check in the parent class, and the /// return type should be templated @@ -297,43 +303,43 @@ void FemtoUniverseV0Selection::init(HistogramRegistry* registry) o2::aod::femtouniverseparticle::ParticleTypeName[part]); /// \todo initialize histograms for children tracks of v0s mHistogramRegistry->add((folderName + "/hPt").c_str(), - "; #it{p}_{T} (GeV/#it{c}); Entries", kTH1F, + "; #it{p}_{T} (GeV/#it{c}); Entries", o2::framework::kTH1F, {{1000, 0, 10}}); mHistogramRegistry->add((folderName + "/hEta").c_str(), "; #eta; Entries", - kTH1F, {{1000, -1, 1}}); + o2::framework::kTH1F, {{1000, -1, 1}}); mHistogramRegistry->add((folderName + "/hPhi").c_str(), "; #phi; Entries", - kTH1F, {{1000, 0, o2::constants::math::TwoPI}}); + o2::framework::kTH1F, {{1000, 0, o2::constants::math::TwoPI}}); mHistogramRegistry->add((folderName + "/hDaughDCA").c_str(), - "; DCA^{daugh} (cm); Entries", kTH1F, + "; DCA^{daugh} (cm); Entries", o2::framework::kTH1F, {{1000, 0, 10}}); mHistogramRegistry->add((folderName + "/hTransRadius").c_str(), - "; #it{r}_{xy} (cm); Entries", kTH1F, + "; #it{r}_{xy} (cm); Entries", o2::framework::kTH1F, {{1500, 0, 150}}); mHistogramRegistry->add((folderName + "/hDecayVtxX").c_str(), - "; #it{Vtx}_{x} (cm); Entries", kTH1F, + "; #it{Vtx}_{x} (cm); Entries", o2::framework::kTH1F, {{2000, 0, 200}}); mHistogramRegistry->add((folderName + "/hDecayVtxY").c_str(), - "; #it{Vtx}_{y} (cm)); Entries", kTH1F, + "; #it{Vtx}_{y} (cm)); Entries", o2::framework::kTH1F, {{2000, 0, 200}}); mHistogramRegistry->add((folderName + "/hDecayVtxZ").c_str(), - "; #it{Vtx}_{z} (cm); Entries", kTH1F, + "; #it{Vtx}_{z} (cm); Entries", o2::framework::kTH1F, {{2000, 0, 200}}); mHistogramRegistry->add((folderName + "/hCPA").c_str(), - "; #it{cos #theta_{p}}; Entries", kTH1F, + "; #it{cos #theta_{p}}; Entries", o2::framework::kTH1F, {{1000, 0.9, 1.}}); mHistogramRegistry->add((folderName + "/hCPAvsPt").c_str(), "; #it{p}_{T} (GeV/#it{c}); #it{cos #theta_{p}}", - kTH2F, {{8, 0.3, 4.3}, {1000, 0.9, 1.}}); - mHistogramRegistry->add((folderName + "/hInvMassLambda").c_str(), "", kTH1F, + o2::framework::kTH2F, {{8, 0.3, 4.3}, {1000, 0.9, 1.}}); + mHistogramRegistry->add((folderName + "/hInvMassLambda").c_str(), "", o2::framework::kTH1F, {massAxisLambda}); mHistogramRegistry->add((folderName + "/hInvMassAntiLambda").c_str(), "", - kTH1F, {massAxisAntiLambda}); + o2::framework::kTH1F, {massAxisAntiLambda}); mHistogramRegistry->add((folderName + "/hInvMassLambdaAntiLambda").c_str(), - "", kTH2F, {massAxisLambda, massAxisAntiLambda}); + "", o2::framework::kTH2F, {massAxisLambda, massAxisAntiLambda}); mHistogramRegistry->add((folderName + "/hInvMassAntiLambdavsPt").c_str(), - "; ; #it{p}_{T} (GeV/#it{c})", kTH2F, {massAxisAntiLambda, {8, 0.0, 5.0}}); + "; ; #it{p}_{T} (GeV/#it{c})", o2::framework::kTH2F, {massAxisAntiLambda, {8, 0.0, 5.0}}); mHistogramRegistry->add((folderName + "/hInvMassLambdavsPt").c_str(), - "; ; #it{p}_{T} (GeV/#it{c})", kTH2F, {massAxisLambda, {8, 0.0, 5.0}}); + "; ; #it{p}_{T} (GeV/#it{c})", o2::framework::kTH2F, {massAxisLambda, {8, 0.0, 5.0}}); posDaughTrack.init( mHistogramRegistry); - mHistogramRegistry->add("LambdaQA/hInvMassLambdaNoCuts", "No cuts", kTH1F, + mHistogramRegistry->add("LambdaQA/hInvMassLambdaNoCuts", "No cuts", o2::framework::kTH1F, {massAxisLambda}); mHistogramRegistry->add("LambdaQA/hInvMassLambdaInvMassCut", - "Invariant mass cut", kTH1F, {massAxisLambda}); + "Invariant mass cut", o2::framework::kTH1F, {massAxisLambda}); mHistogramRegistry->add("LambdaQA/hInvMassLambdaPtMin", "Minimum Pt cut", - kTH1F, {massAxisLambda}); + o2::framework::kTH1F, {massAxisLambda}); mHistogramRegistry->add("LambdaQA/hInvMassLambdaPtMax", "Maximum Pt cut", - kTH1F, {massAxisLambda}); + o2::framework::kTH1F, {massAxisLambda}); mHistogramRegistry->add("LambdaQA/hInvMassLambdaEtaMax", "Maximum Eta cut", - kTH1F, {massAxisLambda}); + o2::framework::kTH1F, {massAxisLambda}); mHistogramRegistry->add("LambdaQA/hInvMassLambdaDCAV0Daugh", - "V0-daughters DCA cut", kTH1F, {massAxisLambda}); - mHistogramRegistry->add("LambdaQA/hInvMassLambdaCPA", "CPA cut", kTH1F, + "V0-daughters DCA cut", o2::framework::kTH1F, {massAxisLambda}); + mHistogramRegistry->add("LambdaQA/hInvMassLambdaCPA", "CPA cut", o2::framework::kTH1F, {massAxisLambda}); mHistogramRegistry->add("LambdaQA/hInvMassLambdaTranRadMin", - "Minimum transverse radius cut", kTH1F, + "Minimum transverse radius cut", o2::framework::kTH1F, {massAxisLambda}); mHistogramRegistry->add("LambdaQA/hInvMassLambdaTranRadMax", - "Maximum transverse radius cut", kTH1F, + "Maximum transverse radius cut", o2::framework::kTH1F, {massAxisLambda}); mHistogramRegistry->add("LambdaQA/hInvMassLambdaDecVtxMax", - "Maximum distance on decay vertex cut", kTH1F, + "Maximum distance on decay vertex cut", o2::framework::kTH1F, {massAxisLambda}); } /// check whether the most open cuts are fulfilled - most of this should have diff --git a/PWGCF/FemtoUniverse/Core/femtoUtils.h b/PWGCF/FemtoUniverse/Core/femtoUtils.h index ddc1833c335..daeef089442 100644 --- a/PWGCF/FemtoUniverse/Core/femtoUtils.h +++ b/PWGCF/FemtoUniverse/Core/femtoUtils.h @@ -19,10 +19,12 @@ #include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" -#include "Framework/ASoAHelpers.h" +#include #include +#include #include +#include #include namespace o2::analysis::femto_universe diff --git a/PWGCF/FemtoUniverse/DataModel/FemtoDerived.h b/PWGCF/FemtoUniverse/DataModel/FemtoDerived.h index c9b158ce1b5..e6a54a6263b 100644 --- a/PWGCF/FemtoUniverse/DataModel/FemtoDerived.h +++ b/PWGCF/FemtoUniverse/DataModel/FemtoDerived.h @@ -16,18 +16,17 @@ #ifndef PWGCF_FEMTOUNIVERSE_DATAMODEL_FEMTODERIVED_H_ #define PWGCF_FEMTOUNIVERSE_DATAMODEL_FEMTODERIVED_H_ -#include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponseTOF.h" #include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "Framework/ASoA.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/DataTypes.h" -#include "Framework/Expressions.h" -#include "MathUtils/Utils.h" +#include +#include +#include #include +#include +#include namespace o2::aod { diff --git a/PWGCF/FemtoUniverse/Macros/calculateEfficiencyCorrection.cxx b/PWGCF/FemtoUniverse/Macros/calculateEfficiencyCorrection.cxx index 3880661d9f7..b0b2cf29275 100644 --- a/PWGCF/FemtoUniverse/Macros/calculateEfficiencyCorrection.cxx +++ b/PWGCF/FemtoUniverse/Macros/calculateEfficiencyCorrection.cxx @@ -14,20 +14,19 @@ /// \author Dawid Karpiński, WUT Warsaw, dawid.karpinski@cern.ch #include -#include #include -#include -#include -#include -#include -#include -#include +#include +#include + +#include #include +#include #include +#include #include // NOLINT -#include #include +#include #include namespace fs = std::filesystem; diff --git a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerMCTruthTask.cxx b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerMCTruthTask.cxx index b2d03f48998..3f94d573ee9 100644 --- a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerMCTruthTask.cxx +++ b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerMCTruthTask.cxx @@ -23,17 +23,20 @@ #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/runDataProcessing.h" #include #include +#include #include +#include #include +#include #include #include +#include +#include + +#include #include #include #include diff --git a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerReducedTask.cxx b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerReducedTask.cxx index 71101d143d4..a0eb1fe69d1 100644 --- a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerReducedTask.cxx +++ b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerReducedTask.cxx @@ -17,31 +17,34 @@ /// \author Zuzanna Chochulska, WUT Warsaw & CTU Prague, zchochul@cern.ch #include "PWGCF/FemtoUniverse/Core/FemtoUniverseCollisionSelection.h" +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseSelection.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseTrackSelection.h" #include "PWGCF/FemtoUniverse/Core/femtoUtils.h" #include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" -#include "PWGLF/DataModel/LFStrangenessTables.h" -#include "Common/Core/trackUtilities.h" +#include "Common/CCDB/TriggerAliases.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponseTOF.h" #include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "DataFormatsParameters/GRPMagField.h" -#include "DataFormatsParameters/GRPObject.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/runDataProcessing.h" -#include "ReconstructionDataFormats/Track.h" #include - -#include "Math/Vector4D.h" -#include "TMath.h" - +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include #include using namespace o2; diff --git a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx index a9b94fe4b0a..1c607fbff0d 100644 --- a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx +++ b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx @@ -20,6 +20,7 @@ #include "PWGCF/FemtoUniverse/Core/FemtoUniverseCascadeSelection.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseCollisionSelection.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniversePhiSelection.h" +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseSelection.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseTrackSelection.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseV0Selection.h" #include "PWGCF/FemtoUniverse/Core/femtoUtils.h" @@ -28,14 +29,16 @@ #include "PWGHF/Core/HfHelper.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" +#include "PWGHF/DataModel/TrackIndexSkimmingTables.h" #include "PWGLF/DataModel/LFStrangenessPIDTables.h" #include "PWGLF/DataModel/LFStrangenessTables.h" +#include "Common/CCDB/EventSelectionParams.h" +#include "Common/CCDB/TriggerAliases.h" #include "Common/CCDB/ctpRateFetcher.h" #include "Common/Core/RecoDecay.h" #include "Common/Core/Zorro.h" #include "Common/Core/ZorroSummary.h" -#include "Common/Core/trackUtilities.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" @@ -43,25 +46,36 @@ #include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "CommonConstants/PhysicsConstants.h" -#include "DataFormatsParameters/GRPMagField.h" -#include "DataFormatsParameters/GRPObject.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "Framework/runDataProcessing.h" -#include "ReconstructionDataFormats/Track.h" #include - -#include "Math/Vector4D.h" -#include "TLorentzVector.h" -#include "TMath.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include #include +#include + #include +#include +#include +#include +#include +#include +#include #include +#include +#include #include #include #include diff --git a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTaskV0Only.cxx b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTaskV0Only.cxx index a7b66212480..c69f0f2eea5 100644 --- a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTaskV0Only.cxx +++ b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTaskV0Only.cxx @@ -14,31 +14,36 @@ /// \author Zuzanna Chochulska, WUT Warsaw & CTU Prague, zchochul@cern.ch #include "PWGCF/FemtoUniverse/Core/FemtoUniverseCollisionSelection.h" +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseSelection.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseTrackSelection.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseV0Selection.h" #include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" #include "PWGLF/DataModel/LFStrangenessTables.h" -#include "Common/Core/trackUtilities.h" +#include "Common/CCDB/TriggerAliases.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponseTOF.h" #include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "DataFormatsParameters/GRPMagField.h" -#include "DataFormatsParameters/GRPObject.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/runDataProcessing.h" -#include "ReconstructionDataFormats/Track.h" #include - -#include "Math/Vector4D.h" -#include "TMath.h" - +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include #include using namespace o2; diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniverseCutCulator.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniverseCutCulator.cxx index c503b0e46c8..c7f222897a1 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniverseCutCulator.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniverseCutCulator.cxx @@ -16,13 +16,8 @@ #include "PWGCF/FemtoUniverse/Core/FemtoUniverseCutculator.h" -#include "PWGCF/FemtoUniverse/Core/FemtoUniverseSelection.h" -#include "PWGCF/FemtoUniverse/Core/FemtoUniverseTrackSelection.h" -#include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" - #include #include -#include #include using namespace o2::analysis::femto_universe; diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniverseDebugTrack.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniverseDebugTrack.cxx index 4984b3283f4..79933fdae0f 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniverseDebugTrack.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniverseDebugTrack.cxx @@ -17,17 +17,23 @@ #include "PWGCF/FemtoUniverse/Core/FemtoUniverseEventHisto.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseParticleHisto.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseTrackSelection.h" -#include "PWGCF/FemtoUniverse/Core/femtoUtils.h" #include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" -#include "DataFormatsParameters/GRPObject.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/StepTHn.h" -#include "Framework/runDataProcessing.h" - +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include #include #include diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniverseDebugV0.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniverseDebugV0.cxx index 8f8f8664f52..21967c475e7 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniverseDebugV0.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniverseDebugV0.cxx @@ -21,17 +21,18 @@ #include "PWGCF/FemtoUniverse/Core/femtoUtils.h" #include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" -#include "DataFormatsParameters/GRPObject.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/StepTHn.h" -#include "Framework/runDataProcessing.h" -#include "ReconstructionDataFormats/PID.h" - -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniverseEfficiencyBase.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniverseEfficiencyBase.cxx index 638e410df62..70a5164bf83 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniverseEfficiencyBase.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniverseEfficiencyBase.cxx @@ -18,12 +18,27 @@ #include "PWGCF/FemtoUniverse/Core/FemtoUniverseEventHisto.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseParticleHisto.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseTrackSelection.h" - -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/runDataProcessing.h" - +#include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include #include using namespace o2; diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniverseEfficiencyTask.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniverseEfficiencyTask.cxx index e9367ba944a..efe5aabeeb6 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniverseEfficiencyTask.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniverseEfficiencyTask.cxx @@ -16,26 +16,31 @@ /// \author Barbara Chytla, WUT Warsaw, barbara.chytla@cern.ch /// \author Zuzanna Chochulska, WUT Warsaw & CTU Prague, zchochul@cern.ch -// O2 includes #include "PWGCF/FemtoUniverse/Core/FemtoUniverseCollisionSelection.h" -#include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" -#include "PWGLF/DataModel/LFResonanceTables.h" -#include "Common/Core/trackUtilities.h" +#include "Common/CCDB/TriggerAliases.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponseTOF.h" #include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "Framework/runDataProcessing.h" -#include "ReconstructionDataFormats/Track.h" - -#include "TPDGCode.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include using namespace o2; using namespace o2::analysis::femto_universe; diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniverseHashTask.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniverseHashTask.cxx index 04c9865a73c..08c0a74f675 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniverseHashTask.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniverseHashTask.cxx @@ -18,9 +18,11 @@ #include "Common/Core/EventMixing.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" +#include +#include +#include +#include +#include #include diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackCascadeExtended.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackCascadeExtended.cxx index 4002a0a1cac..c22ab23a542 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackCascadeExtended.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackCascadeExtended.cxx @@ -19,20 +19,37 @@ #include "PWGCF/FemtoUniverse/Core/FemtoUniverseEventHisto.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniversePairCleaner.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseParticleHisto.h" -#include "PWGCF/FemtoUniverse/Core/femtoUtils.h" #include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" -#include "CCDB/BasicCCDBManager.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/StepTHn.h" -#include "Framework/runDataProcessing.h" - +#include "Common/DataModel/PIDResponseTOF.h" +#include "Common/DataModel/PIDResponseTPC.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include #include +#include +#include +#include +#include #include #include #include diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackD0.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackD0.cxx index 65538ecd6f0..1ca010fb5d4 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackD0.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackD0.cxx @@ -21,25 +21,37 @@ #include "PWGCF/FemtoUniverse/Core/FemtoUniverseParticleHisto.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseSoftPionRemoval.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseTrackSelection.h" -#include "PWGCF/FemtoUniverse/Core/femtoUtils.h" #include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" #include "PWGHF/Core/DecayChannels.h" -#include "PWGHF/Core/HfHelper.h" #include "PWGHF/Core/SelectorCuts.h" -#include "PWGHF/DataModel/CandidateReconstructionTables.h" -#include "PWGHF/DataModel/CandidateSelectionTables.h" #include "Common/Core/RecoDecay.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/StepTHn.h" -#include "Framework/runDataProcessing.h" -#include "ReconstructionDataFormats/PID.h" - +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include #include #include diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackNucleus.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackNucleus.cxx index e133de72efe..709159fef57 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackNucleus.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackNucleus.cxx @@ -18,6 +18,7 @@ /// \author Alicja Płachta, WUT Warsaw, alicja.plachta.stud@pw.edu.pl /// \author Anna-Mariia Andrushko, WUT Warsaw, anna-mariia.andrushko@cern.ch +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseContainer.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseDetaDphiStar.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseEventHisto.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseFemtoContainer.h" @@ -26,19 +27,28 @@ #include "PWGCF/FemtoUniverse/Core/FemtoUniversePairWithCentMultKt.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseParticleHisto.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseTrackSelection.h" -#include "PWGCF/FemtoUniverse/Core/femtoUtils.h" #include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/StepTHn.h" -#include "Framework/runDataProcessing.h" -#include "ReconstructionDataFormats/PID.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include #include #include diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackPhi.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackPhi.cxx index 98a697434ac..e38ce70b48e 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackPhi.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackPhi.cxx @@ -25,16 +25,28 @@ #include "PWGCF/FemtoUniverse/Core/FemtoUniverseTrackSelection.h" #include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "Framework/runDataProcessing.h" -#include "ReconstructionDataFormats/PID.h" - -#include -#include - +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include #include #include diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrack.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrack.cxx index e672064bd59..fc1d31341c0 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrack.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrack.cxx @@ -17,23 +17,31 @@ /// \author Zuzanna Chochulska, WUT Warsaw & CTU Prague, zchochul@cern.ch #include "PWGCF/FemtoUniverse/Core/FemtoUniverseAngularContainer.h" +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseContainer.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseDetaDphiStar.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseEventHisto.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseFemtoContainer.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniversePairCleaner.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseParticleHisto.h" -#include "PWGCF/FemtoUniverse/Core/FemtoUniverseTrackSelection.h" #include "PWGCF/FemtoUniverse/Core/femtoUtils.h" #include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/StepTHn.h" -#include "Framework/runDataProcessing.h" - +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include #include #include diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrack3DMultKtExtended.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrack3DMultKtExtended.cxx index 5de02b3c346..99ce0e828ae 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrack3DMultKtExtended.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrack3DMultKtExtended.cxx @@ -23,21 +23,34 @@ #include "PWGCF/FemtoUniverse/Core/FemtoUniversePairWithCentMultKt.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseParticleHisto.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseTrackSelection.h" -#include "PWGCF/FemtoUniverse/Core/femtoUtils.h" #include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/StepTHn.h" -#include "Framework/runDataProcessing.h" -#include "ReconstructionDataFormats/PID.h" - -#include "TRandom2.h" - +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include #include +#include #include using namespace o2; diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackExtended.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackExtended.cxx index 7760a8f2451..d4c89ed8f07 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackExtended.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackExtended.cxx @@ -25,13 +25,30 @@ #include "PWGCF/FemtoUniverse/Core/FemtoUniverseTrackSelection.h" #include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/runDataProcessing.h" -#include "ReconstructionDataFormats/PID.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include - +#include +#include +#include +#include + +#include +#include +#include +#include #include #include diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackMC.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackMC.cxx index 5cff8c72cf9..24038e1b89b 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackMC.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackMC.cxx @@ -25,20 +25,31 @@ #include "PWGCF/FemtoUniverse/Core/FemtoUniversePairCleaner.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseParticleHisto.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseTrackSelection.h" -#include "PWGCF/FemtoUniverse/Core/femtoUtils.h" #include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/StepTHn.h" -#include "Framework/runDataProcessing.h" -#include "ReconstructionDataFormats/PID.h" - -#include "TDatabasePDG.h" - +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include #include using namespace o2; diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackMcTruth.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackMcTruth.cxx index 39e0e83e075..30666e44c8b 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackMcTruth.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackMcTruth.cxx @@ -18,19 +18,25 @@ #include "PWGCF/FemtoUniverse/Core/FemtoUniverseEventHisto.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniversePairCleaner.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseParticleHisto.h" -#include "PWGCF/FemtoUniverse/Core/FemtoUniverseTrackSelection.h" -#include "PWGCF/FemtoUniverse/Core/femtoUtils.h" #include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/StepTHn.h" -#include "Framework/runDataProcessing.h" - -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include #include using namespace o2; diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackMultKtExtended.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackMultKtExtended.cxx index 76a3c989494..6f7f82b963c 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackMultKtExtended.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackMultKtExtended.cxx @@ -17,6 +17,7 @@ /// \author Zuzanna Chochulska, WUT Warsaw & CTU Prague, zchochul@cern.ch /// \author Alicja Płachta, WUT Warsaw, alicja.plachta.stud@pw.edu.pl +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseContainer.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseDetaDphiStar.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseEventHisto.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseFemtoContainer.h" @@ -27,13 +28,27 @@ #include "PWGCF/FemtoUniverse/Core/FemtoUniverseTrackSelection.h" #include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "Framework/runDataProcessing.h" -#include "ReconstructionDataFormats/PID.h" - +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include #include #include diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackSpherHarMultKtExtended.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackSpherHarMultKtExtended.cxx index f5a4409a2e7..93bfafe5ff2 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackSpherHarMultKtExtended.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackSpherHarMultKtExtended.cxx @@ -14,6 +14,7 @@ /// \remark This file is inherited from ~/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrack3DMultKtExtended.cxx on 17/06/2024 /// \author Pritam Chakraborty, WUT Warsaw, pritam.chakraborty@pw.edu.pl +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseContainer.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseDetaDphiStar.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseEventHisto.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseMath.h" @@ -22,20 +23,31 @@ #include "PWGCF/FemtoUniverse/Core/FemtoUniverseParticleHisto.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseSHContainer.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseTrackSelection.h" -#include "PWGCF/FemtoUniverse/Core/femtoUtils.h" #include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/StepTHn.h" -#include "Framework/runDataProcessing.h" -#include "ReconstructionDataFormats/PID.h" - -#include "TRandom2.h" - +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include #include #include diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackV0Extended.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackV0Extended.cxx index f10e793f263..10bab49150b 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackV0Extended.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackV0Extended.cxx @@ -21,21 +21,42 @@ #include "PWGCF/FemtoUniverse/Core/FemtoUniverseEventHisto.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniversePairCleaner.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseParticleHisto.h" - -#include "CCDB/BasicCCDBManager.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "Framework/runDataProcessing.h" +#include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" + +#include "Common/DataModel/PIDResponseTOF.h" +#include "Common/DataModel/PIDResponseTPC.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include +#include +#include +#include +#include +#include +#include #include #include #include +#include #include using namespace o2; @@ -482,8 +503,12 @@ struct FemtoUniversePairTaskTrackV0Extended { trackHistoPartOneNeg.fillQA(part); } } else { - if ((part.pidCut() & (64u << ConfTrkSelection.confTrackChoicePartOne)) == 0) + if ((part.pidCut() & 512u) != 0) { + if ((part.pidCut() & (64u << ConfTrkSelection.confTrackChoicePartOne)) == 0) + continue; + } else if ((part.pidCut() & (1u << ConfTrkSelection.confTrackChoicePartOne)) == 0) { continue; + } if (ConfTrkSelection.confChargePart1 > 0) trackHistoPartOnePos.fillQA(part); if (ConfTrkSelection.confChargePart1 < 0) @@ -501,8 +526,12 @@ struct FemtoUniversePairTaskTrackV0Extended { if (!isParticleCombined(p1, ConfTrkSelection.confTrackChoicePartOne)) continue; } else { - if ((p1.pidCut() & (64u << ConfTrkSelection.confTrackChoicePartOne)) == 0) + if ((p1.pidCut() & 512u) != 0) { + if ((p1.pidCut() & (64u << ConfTrkSelection.confTrackChoicePartOne)) == 0) + continue; + } else if ((p1.pidCut() & (1u << ConfTrkSelection.confTrackChoicePartOne)) == 0) { continue; + } } // track cleaning if (!pairCleaner.isCleanPair(p1, p2, parts)) { @@ -958,8 +987,12 @@ struct FemtoUniversePairTaskTrackV0Extended { if (!isParticleCombined(p1, ConfTrkSelection.confTrackChoicePartOne)) continue; } else { - if ((p1.pidCut() & (64u << ConfTrkSelection.confTrackChoicePartOne)) == 0) + if ((p1.pidCut() & 512u) != 0) { + if ((p1.pidCut() & (64u << ConfTrkSelection.confTrackChoicePartOne)) == 0) + continue; + } else if ((p1.pidCut() & (1u << ConfTrkSelection.confTrackChoicePartOne)) == 0) { continue; + } } const auto& posChild = parts.iteratorAt(p2.globalIndex() - 2 - parts.begin().globalIndex()); diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackV0Helicity.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackV0Helicity.cxx index afee000d7d6..d59a0b0cc3f 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackV0Helicity.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackV0Helicity.cxx @@ -22,22 +22,37 @@ #include "PWGCF/FemtoUniverse/Core/FemtoUniverseMath.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniversePairCleaner.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseParticleHisto.h" -#include "PWGCF/FemtoUniverse/Core/femtoUtils.h" #include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/StepTHn.h" -#include "Framework/runDataProcessing.h" +#include "Common/DataModel/PIDResponseTOF.h" +#include "Common/DataModel/PIDResponseTPC.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include +#include +#include +#include +#include #include #include +#include #include using namespace o2; diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskV0CascadeExtended.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskV0CascadeExtended.cxx index 739128780ea..f88e9eae0b6 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskV0CascadeExtended.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskV0CascadeExtended.cxx @@ -18,18 +18,29 @@ #include "PWGCF/FemtoUniverse/Core/FemtoUniverseEventHisto.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniversePairCleaner.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseParticleHisto.h" -#include "PWGCF/FemtoUniverse/Core/femtoUtils.h" #include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/StepTHn.h" -#include "Framework/runDataProcessing.h" - -#include +#include "Common/DataModel/PIDResponseTOF.h" +#include "Common/DataModel/PIDResponseTPC.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include #include using namespace o2; diff --git a/PWGCF/FemtoWorld/Core/FemtoWorldCollisionSelection.h b/PWGCF/FemtoWorld/Core/FemtoWorldCollisionSelection.h index d2404f3e214..df6da437ef3 100644 --- a/PWGCF/FemtoWorld/Core/FemtoWorldCollisionSelection.h +++ b/PWGCF/FemtoWorld/Core/FemtoWorldCollisionSelection.h @@ -17,14 +17,11 @@ #ifndef PWGCF_FEMTOWORLD_CORE_FEMTOWORLDCOLLISIONSELECTION_H_ #define PWGCF_FEMTOWORLD_CORE_FEMTOWORLDCOLLISIONSELECTION_H_ -#include -#include - #include "Common/CCDB/TriggerAliases.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/Logger.h" -using namespace o2::framework; +#include +#include +#include namespace o2::analysis::femtoWorld { @@ -54,18 +51,18 @@ class FemtoWorldCollisionSelection /// Initializes histograms for the task /// \param registry Histogram registry to be passed - void init(HistogramRegistry* registry) + void init(o2::framework::HistogramRegistry* registry) { if (!mCutsSet) { LOGF(error, "Event selection not set - quitting!"); } mHistogramRegistry = registry; - mHistogramRegistry->add("Event/zvtxhist", "; vtx_{z} (cm); Entries", kTH1F, {{300, -12.5, 12.5}}); - mHistogramRegistry->add("Event/MultV0M", "; vMultV0M; Entries", kTH1F, {{16384, 0, 32768}}); - mHistogramRegistry->add("Event/MultT0M", "; vMultT0M; Entries", kTH1F, {{4096, 0, 8192}}); - mHistogramRegistry->add("Event/MultNTracksPV", "; vMultNTracksPV; Entries", kTH1F, {{120, 0, 120}}); - mHistogramRegistry->add("Event/MultNTracklets", "; vMultNTrackslets; Entries", kTH1F, {{300, 0, 300}}); - mHistogramRegistry->add("Event/MultTPC", "; vMultTPC; Entries", kTH1I, {{600, 0, 600}}); + mHistogramRegistry->add("Event/zvtxhist", "; vtx_{z} (cm); Entries", o2::framework::kTH1F, {{300, -12.5, 12.5}}); + mHistogramRegistry->add("Event/MultV0M", "; vMultV0M; Entries", o2::framework::kTH1F, {{16384, 0, 32768}}); + mHistogramRegistry->add("Event/MultT0M", "; vMultT0M; Entries", o2::framework::kTH1F, {{4096, 0, 8192}}); + mHistogramRegistry->add("Event/MultNTracksPV", "; vMultNTracksPV; Entries", o2::framework::kTH1F, {{120, 0, 120}}); + mHistogramRegistry->add("Event/MultNTracklets", "; vMultNTrackslets; Entries", o2::framework::kTH1F, {{300, 0, 300}}); + mHistogramRegistry->add("Event/MultTPC", "; vMultTPC; Entries", o2::framework::kTH1I, {{600, 0, 600}}); } /// Print some debug information @@ -140,13 +137,13 @@ class FemtoWorldCollisionSelection } private: - HistogramRegistry* mHistogramRegistry = nullptr; ///< For QA output - bool mCutsSet = false; ///< Protection against running without cuts - bool mCheckTrigger = false; ///< Check for trigger - bool mCheckOffline = false; ///< Check for offline criteria (might change) - bool mCheckIsRun3 = false; ///< Check if running on Pilot Beam - triggerAliases mTrigger = kINT7; ///< Trigger to check for - float mZvtxMax = 999.f; ///< Maximal deviation from nominal z-vertex (cm) + o2::framework::HistogramRegistry* mHistogramRegistry = nullptr; ///< For QA output + bool mCutsSet = false; ///< Protection against running without cuts + bool mCheckTrigger = false; ///< Check for trigger + bool mCheckOffline = false; ///< Check for offline criteria (might change) + bool mCheckIsRun3 = false; ///< Check if running on Pilot Beam + triggerAliases mTrigger = kINT7; ///< Trigger to check for + float mZvtxMax = 999.f; ///< Maximal deviation from nominal z-vertex (cm) }; } // namespace o2::analysis::femtoWorld diff --git a/PWGCF/FemtoWorld/Core/FemtoWorldContainer.h b/PWGCF/FemtoWorld/Core/FemtoWorldContainer.h index a80af060d56..9f96deab5d0 100644 --- a/PWGCF/FemtoWorld/Core/FemtoWorldContainer.h +++ b/PWGCF/FemtoWorld/Core/FemtoWorldContainer.h @@ -18,20 +18,18 @@ #ifndef PWGCF_FEMTOWORLD_CORE_FEMTOWORLDCONTAINER_H_ #define PWGCF_FEMTOWORLD_CORE_FEMTOWORLDCONTAINER_H_ -#include -#include -#include "Framework/HistogramRegistry.h" #include "PWGCF/FemtoWorld/Core/FemtoWorldMath.h" -#include "Math/Vector4D.h" -#include "TMath.h" -#include "TDatabasePDG.h" +#include +#include +#include -#include "TLorentzVector.h" -#include "CommonConstants/MathConstants.h" -#include "TRandom.h" +#include +#include -using namespace o2::framework; +#include +#include +#include namespace o2::analysis::femtoWorld { @@ -73,7 +71,7 @@ class FemtoWorldContainer /// \param mInvBins invariant mass binning for the histograms template - void init(HistogramRegistry* registry, T1& kstarBins, T1& multBins, T1& kTBins, T1& mTBins, T2& phiBins, T2& etaBins, T2& mInvBins) + void init(o2::framework::HistogramRegistry* registry, T1& kstarBins, T1& multBins, T1& kTBins, T1& mTBins, T2& phiBins, T2& etaBins, T2& mInvBins) { mHistogramRegistry = registry; std::string femtoObs; @@ -94,18 +92,18 @@ class FemtoWorldContainer framework::AxisSpec mInvAxis = {mInvBins, 0.0, 10.0}; std::string folderName = static_cast(mFolderSuffix[mEventType]); - mHistogramRegistry->add((folderName + "relPairDist").c_str(), ("; " + femtoObs + "; Entries").c_str(), kTH1F, {femtoObsAxis}); - mHistogramRegistry->add((folderName + "relPairkT").c_str(), "; #it{k}_{T} (GeV/#it{c}); Entries", kTH1F, {kTAxis}); - mHistogramRegistry->add((folderName + "relPairkstarkT").c_str(), ("; " + femtoObs + "; #it{k}_{T} (GeV/#it{c})").c_str(), kTH2F, {femtoObsAxis, kTAxis}); - mHistogramRegistry->add((folderName + "relPairkstarmT").c_str(), ("; " + femtoObs + "; #it{m}_{T} (GeV/#it{c}^{2})").c_str(), kTH2F, {femtoObsAxis, mTAxis}); - mHistogramRegistry->add((folderName + "relPairkstarMult").c_str(), ("; " + femtoObs + "; Multiplicity").c_str(), kTH2F, {femtoObsAxis, multAxis}); - mHistogramRegistry->add((folderName + "kstarPtPart1").c_str(), ("; " + femtoObs + "; #it{p} _{T} Particle 1 (GeV/#it{c})").c_str(), kTH2F, {femtoObsAxis, {375, 0., 7.5}}); - mHistogramRegistry->add((folderName + "kstarPtPart2").c_str(), ("; " + femtoObs + "; #it{p} _{T} Particle 2 (GeV/#it{c})").c_str(), kTH2F, {femtoObsAxis, {375, 0., 7.5}}); - mHistogramRegistry->add((folderName + "MultPtPart1").c_str(), "; #it{p} _{T} Particle 1 (GeV/#it{c}); Multiplicity", kTH2F, {{375, 0., 7.5}, multAxis}); - mHistogramRegistry->add((folderName + "MultPtPart2").c_str(), "; #it{p} _{T} Particle 2 (GeV/#it{c}); Multiplicity", kTH2F, {{375, 0., 7.5}, multAxis}); - mHistogramRegistry->add((folderName + "PtPart1PtPart2").c_str(), "; #it{p} _{T} Particle 1 (GeV/#it{c}); #it{p} _{T} Particle 2 (GeV/#it{c})", kTH2F, {{375, 0., 7.5}, {375, 0., 7.5}}); - mHistogramRegistry->add((folderName + "relPairDetaDphi").c_str(), "; #Delta#varphi (rad); #Delta#eta", kTH2D, {phiAxis, etaAxis}); - mHistogramRegistry->add((folderName + "relPairInvariantMass").c_str(), ";M_{K^{+}K^{-}} (GeV/#it{c}^{2});", kTH1D, {mInvAxis}); + mHistogramRegistry->add((folderName + "relPairDist").c_str(), ("; " + femtoObs + "; Entries").c_str(), o2::framework::kTH1F, {femtoObsAxis}); + mHistogramRegistry->add((folderName + "relPairkT").c_str(), "; #it{k}_{T} (GeV/#it{c}); Entries", o2::framework::kTH1F, {kTAxis}); + mHistogramRegistry->add((folderName + "relPairkstarkT").c_str(), ("; " + femtoObs + "; #it{k}_{T} (GeV/#it{c})").c_str(), o2::framework::kTH2F, {femtoObsAxis, kTAxis}); + mHistogramRegistry->add((folderName + "relPairkstarmT").c_str(), ("; " + femtoObs + "; #it{m}_{T} (GeV/#it{c}^{2})").c_str(), o2::framework::kTH2F, {femtoObsAxis, mTAxis}); + mHistogramRegistry->add((folderName + "relPairkstarMult").c_str(), ("; " + femtoObs + "; Multiplicity").c_str(), o2::framework::kTH2F, {femtoObsAxis, multAxis}); + mHistogramRegistry->add((folderName + "kstarPtPart1").c_str(), ("; " + femtoObs + "; #it{p} _{T} Particle 1 (GeV/#it{c})").c_str(), o2::framework::kTH2F, {femtoObsAxis, {375, 0., 7.5}}); + mHistogramRegistry->add((folderName + "kstarPtPart2").c_str(), ("; " + femtoObs + "; #it{p} _{T} Particle 2 (GeV/#it{c})").c_str(), o2::framework::kTH2F, {femtoObsAxis, {375, 0., 7.5}}); + mHistogramRegistry->add((folderName + "MultPtPart1").c_str(), "; #it{p} _{T} Particle 1 (GeV/#it{c}); Multiplicity", o2::framework::kTH2F, {{375, 0., 7.5}, multAxis}); + mHistogramRegistry->add((folderName + "MultPtPart2").c_str(), "; #it{p} _{T} Particle 2 (GeV/#it{c}); Multiplicity", o2::framework::kTH2F, {{375, 0., 7.5}, multAxis}); + mHistogramRegistry->add((folderName + "PtPart1PtPart2").c_str(), "; #it{p} _{T} Particle 1 (GeV/#it{c}); #it{p} _{T} Particle 2 (GeV/#it{c})", o2::framework::kTH2F, {{375, 0., 7.5}, {375, 0., 7.5}}); + mHistogramRegistry->add((folderName + "relPairDetaDphi").c_str(), "; #Delta#varphi (rad); #Delta#eta", o2::framework::kTH2D, {phiAxis, etaAxis}); + mHistogramRegistry->add((folderName + "relPairInvariantMass").c_str(), ";M_{K^{+}K^{-}} (GeV/#it{c}^{2});", o2::framework::kTH1D, {mInvAxis}); } /// Set the PDG codes of the two particles involved @@ -183,7 +181,7 @@ class FemtoWorldContainer } protected: - HistogramRegistry* mHistogramRegistry = nullptr; ///< For QA output + o2::framework::HistogramRegistry* mHistogramRegistry = nullptr; ///< For QA output static constexpr std::string_view mFolderSuffix[2] = {"SameEvent/", "MixedEvent/"}; ///< Folder naming for the output according to mEventType static constexpr femtoWorldContainer::Observable mFemtoObs = obs; ///< Femtoscopic observable to be computed (according to femtoWorldContainer::Observable) static constexpr int mEventType = eventType; ///< Type of the event (same/mixed, according to femtoWorldContainer::EventType) diff --git a/PWGCF/FemtoWorld/Core/FemtoWorldDetaDphiStar.h b/PWGCF/FemtoWorld/Core/FemtoWorldDetaDphiStar.h index f7262481a77..18e3e531b3a 100644 --- a/PWGCF/FemtoWorld/Core/FemtoWorldDetaDphiStar.h +++ b/PWGCF/FemtoWorld/Core/FemtoWorldDetaDphiStar.h @@ -17,13 +17,24 @@ #ifndef PWGCF_FEMTOWORLD_CORE_FEMTOWORLDDETADPHISTAR_H_ #define PWGCF_FEMTOWORLD_CORE_FEMTOWORLDDETADPHISTAR_H_ -#include +#include "PWGCF/FemtoWorld/DataModel/FemtoWorldDerived.h" + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include #include +#include +#include #include -#include "PWGCF/FemtoWorld/DataModel/FemtoWorldDerived.h" -#include "Framework/HistogramRegistry.h" - namespace o2::analysis { namespace femtoWorld @@ -40,7 +51,7 @@ class FemtoWorldDetaDphiStar /// Destructor virtual ~FemtoWorldDetaDphiStar() = default; /// Initialization of the histograms and setting required values - void init(HistogramRegistry* registry, HistogramRegistry* registryQA, float ldeltaPhiMax, float ldeltaEtaMax, bool lplotForEveryRadii) + void init(framework::HistogramRegistry* registry, framework::HistogramRegistry* registryQA, float ldeltaPhiMax, float ldeltaEtaMax, bool lplotForEveryRadii) { deltaPhiMax = ldeltaPhiMax; deltaEtaMax = ldeltaEtaMax; @@ -50,22 +61,22 @@ class FemtoWorldDetaDphiStar if constexpr (mPartOneType == o2::aod::femtoworldparticle::ParticleType::kTrack && mPartTwoType == o2::aod::femtoworldparticle::ParticleType::kTrack) { std::string dirName = static_cast(dirNames[0]); - histdetadpi[0][0] = mHistogramRegistry->add((dirName + static_cast(histNames[0][0])).c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); - histdetadpi[0][1] = mHistogramRegistry->add((dirName + static_cast(histNames[1][0])).c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpi[0][0] = mHistogramRegistry->add((dirName + static_cast(histNames[0][0])).c_str(), "; #Delta #eta; #Delta #phi", framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpi[0][1] = mHistogramRegistry->add((dirName + static_cast(histNames[1][0])).c_str(), "; #Delta #eta; #Delta #phi", framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); if (plotForEveryRadii) { for (int i = 0; i < 9; i++) { - histdetadpiRadii[0][i] = mHistogramRegistryQA->add((dirName + static_cast(histNamesRadii[0][i])).c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpiRadii[0][i] = mHistogramRegistryQA->add((dirName + static_cast(histNamesRadii[0][i])).c_str(), "; #Delta #eta; #Delta #phi", framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); } } } if constexpr (mPartOneType == o2::aod::femtoworldparticle::ParticleType::kTrack && mPartTwoType == o2::aod::femtoworldparticle::ParticleType::kV0) { for (int i = 0; i < 2; i++) { std::string dirName = static_cast(dirNames[1]); - histdetadpi[i][0] = mHistogramRegistry->add((dirName + static_cast(histNames[0][i])).c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); - histdetadpi[i][1] = mHistogramRegistry->add((dirName + static_cast(histNames[1][i])).c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpi[i][0] = mHistogramRegistry->add((dirName + static_cast(histNames[0][i])).c_str(), "; #Delta #eta; #Delta #phi", framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpi[i][1] = mHistogramRegistry->add((dirName + static_cast(histNames[1][i])).c_str(), "; #Delta #eta; #Delta #phi", framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); if (plotForEveryRadii) { for (int j = 0; j < 9; j++) { - histdetadpiRadii[i][j] = mHistogramRegistryQA->add((dirName + static_cast(histNamesRadii[i][j])).c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpiRadii[i][j] = mHistogramRegistryQA->add((dirName + static_cast(histNamesRadii[i][j])).c_str(), "; #Delta #eta; #Delta #phi", framework::kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); } } } @@ -133,8 +144,8 @@ class FemtoWorldDetaDphiStar } private: - HistogramRegistry* mHistogramRegistry = nullptr; ///< For main output - HistogramRegistry* mHistogramRegistryQA = nullptr; ///< For QA output + framework::HistogramRegistry* mHistogramRegistry = nullptr; ///< For main output + framework::HistogramRegistry* mHistogramRegistryQA = nullptr; ///< For QA output static constexpr std::string_view dirNames[2] = {"kTrack_kTrack/", "kTrack_kV0/"}; static constexpr std::string_view histNames[2][2] = {{"detadphidetadphi0Before_0", "detadphidetadphi0Before_1"}, diff --git a/PWGCF/FemtoWorld/Core/FemtoWorldEventHisto.h b/PWGCF/FemtoWorld/Core/FemtoWorldEventHisto.h index fade16ebb00..3a0d454f03d 100644 --- a/PWGCF/FemtoWorld/Core/FemtoWorldEventHisto.h +++ b/PWGCF/FemtoWorld/Core/FemtoWorldEventHisto.h @@ -14,13 +14,12 @@ /// \author Andi Mathis, TU München, andreas.mathis@ph.tum.de /// \author Zuzanna Chochulska, WUT Warsaw, zchochul@cern.ch -#ifndef FEMTOWORLDEVENTHISTO_H_ -#define FEMTOWORLDEVENTHISTO_H_ +#ifndef PWGCF_FEMTOWORLD_CORE_FEMTOWORLDEVENTHISTO_H_ +#define PWGCF_FEMTOWORLD_CORE_FEMTOWORLDEVENTHISTO_H_ -#include "PWGCF/FemtoWorld/DataModel/FemtoWorldDerived.h" -#include "Framework/HistogramRegistry.h" +#include +#include -using namespace o2::framework; namespace o2::analysis::femtoWorld { /// \class FemtoWorldEventHisto @@ -32,11 +31,11 @@ class FemtoWorldEventHisto virtual ~FemtoWorldEventHisto() = default; /// Initializes histograms for the task /// \param registry Histogram registry to be passed - void init(HistogramRegistry* registry) + void init(o2::framework::HistogramRegistry* registry) { mHistogramRegistry = registry; - mHistogramRegistry->add("Event/zvtxhist", "; vtx_{z} (cm); Entries", kTH1F, {{300, -12.5, 12.5}}); - mHistogramRegistry->add("Event/MultV0M", "; vMultV0M; Entries", kTH1F, {{600, 0, 600}}); + mHistogramRegistry->add("Event/zvtxhist", "; vtx_{z} (cm); Entries", o2::framework::kTH1F, {{300, -12.5, 12.5}}); + mHistogramRegistry->add("Event/MultV0M", "; vMultV0M; Entries", o2::framework::kTH1F, {{600, 0, 600}}); } /// Some basic QA of the event @@ -52,8 +51,8 @@ class FemtoWorldEventHisto } private: - HistogramRegistry* mHistogramRegistry; ///< For QA output + o2::framework::HistogramRegistry* mHistogramRegistry; ///< For QA output }; } // namespace o2::analysis::femtoWorld -#endif /* FEMTOWORLDEVENTHISTO_H_ */ +#endif // PWGCF_FEMTOWORLD_CORE_FEMTOWORLDEVENTHISTO_H_ diff --git a/PWGCF/FemtoWorld/Core/FemtoWorldMath.h b/PWGCF/FemtoWorld/Core/FemtoWorldMath.h index 16df6773cd8..0996ac807f0 100644 --- a/PWGCF/FemtoWorld/Core/FemtoWorldMath.h +++ b/PWGCF/FemtoWorld/Core/FemtoWorldMath.h @@ -17,12 +17,11 @@ #ifndef PWGCF_FEMTOWORLD_CORE_FEMTOWORLDMATH_H_ #define PWGCF_FEMTOWORLD_CORE_FEMTOWORLDMATH_H_ -#include "Math/Vector4D.h" -#include "Math/Boost.h" -#include "TLorentzVector.h" -#include "TMath.h" +#include +#include // IWYU pragma: keep (do not replace with Math/Vector4Dfwd.h) +#include -#include +#include namespace o2::analysis::femtoWorld { diff --git a/PWGCF/FemtoWorld/Core/FemtoWorldObjectSelection.h b/PWGCF/FemtoWorld/Core/FemtoWorldObjectSelection.h index d940f9d13ef..c50e434526b 100644 --- a/PWGCF/FemtoWorld/Core/FemtoWorldObjectSelection.h +++ b/PWGCF/FemtoWorld/Core/FemtoWorldObjectSelection.h @@ -13,15 +13,19 @@ /// \brief FemtoWorldObjectSelection - Parent class of all selections /// \author Andi Mathis, TU München, andreas.mathis@ph.tum.de -#ifndef FEMTOWORLDOBJECTSELECTION_H_ -#define FEMTOWORLDOBJECTSELECTION_H_ +#ifndef PWGCF_FEMTOWORLD_CORE_FEMTOWORLDOBJECTSELECTION_H_ +#define PWGCF_FEMTOWORLD_CORE_FEMTOWORLDOBJECTSELECTION_H_ #include "PWGCF/FemtoWorld/Core/FemtoWorldSelection.h" +#include "PWGCF/FemtoWorld/DataModel/FemtoWorldDerived.h" -#include "ReconstructionDataFormats/PID.h" -#include "Framework/HistogramRegistry.h" +#include +#include -using namespace o2::framework; +#include + +#include +#include namespace o2::analysis { @@ -46,7 +50,7 @@ class FemtoWorldObjectSelection void fillSelectionHistogram() { int nBins = mSelections.size(); - mHistogramRegistry->add((static_cast(o2::aod::femtoworldparticle::ParticleTypeName[part]) + "/cuthist").c_str(), "; Cut; Value", kTH1F, {{nBins, 0, static_cast(nBins)}}); + mHistogramRegistry->add((static_cast(o2::aod::femtoworldparticle::ParticleTypeName[part]) + "/cuthist").c_str(), "; Cut; Value", o2::framework::kTH1F, {{nBins, 0, static_cast(nBins)}}); auto hist = mHistogramRegistry->get(HIST(o2::aod::femtoworldparticle::ParticleTypeName[part]) + HIST("/cuthist")); for (size_t i = 0; i < mSelections.size(); ++i) { hist->GetXaxis()->SetBinLabel(i + 1, Form("%u", mSelections.at(i).getSelectionVariable())); @@ -182,11 +186,11 @@ class FemtoWorldObjectSelection } protected: - HistogramRegistry* mHistogramRegistry; ///< For QA output + o2::framework::HistogramRegistry* mHistogramRegistry; ///< For QA output std::vector> mSelections; ///< Vector containing all selections }; } // namespace femtoWorld } // namespace o2::analysis -#endif /* FEMTOWORLDOBJECTSELECTION_H_ */ +#endif // PWGCF_FEMTOWORLD_CORE_FEMTOWORLDOBJECTSELECTION_H_ diff --git a/PWGCF/FemtoWorld/Core/FemtoWorldPairCleaner.h b/PWGCF/FemtoWorld/Core/FemtoWorldPairCleaner.h index 5c20af3813e..526f313cf92 100644 --- a/PWGCF/FemtoWorld/Core/FemtoWorldPairCleaner.h +++ b/PWGCF/FemtoWorld/Core/FemtoWorldPairCleaner.h @@ -18,9 +18,11 @@ #define PWGCF_FEMTOWORLD_CORE_FEMTOWORLDPAIRCLEANER_H_ #include "PWGCF/FemtoWorld/DataModel/FemtoWorldDerived.h" -#include "Framework/HistogramRegistry.h" -using namespace o2::framework; +#include +#include + +#include namespace o2::analysis::femtoWorld { @@ -37,8 +39,8 @@ class FemtoWorldPairCleaner virtual ~FemtoWorldPairCleaner() = default; /// Initialization of the QA histograms - /// \param registry HistogramRegistry - void init(HistogramRegistry* registry) + /// \param registry o2::framework::HistogramRegistry + void init(o2::framework::HistogramRegistry* registry) { if (registry) { mHistogramRegistry = registry; @@ -88,7 +90,7 @@ class FemtoWorldPairCleaner } private: - HistogramRegistry* mHistogramRegistry; ///< For QA output + o2::framework::HistogramRegistry* mHistogramRegistry; ///< For QA output static constexpr o2::aod::femtoworldparticle::ParticleType mPartOneType = partOne; ///< Type of particle 1 static constexpr o2::aod::femtoworldparticle::ParticleType mPartTwoType = partTwo; ///< Type of particle 2 }; diff --git a/PWGCF/FemtoWorld/Core/FemtoWorldPairWithCentrality.h b/PWGCF/FemtoWorld/Core/FemtoWorldPairWithCentrality.h index 2a2548b5d5b..d30f5ab56b8 100644 --- a/PWGCF/FemtoWorld/Core/FemtoWorldPairWithCentrality.h +++ b/PWGCF/FemtoWorld/Core/FemtoWorldPairWithCentrality.h @@ -13,13 +13,12 @@ #ifndef PWGCF_FEMTOWORLD_CORE_FEMTOWORLDPAIRWITHCENTRALITY_H_ #define PWGCF_FEMTOWORLD_CORE_FEMTOWORLDPAIRWITHCENTRALITY_H_ +#include +#include + #include -#include +#include #include -#include "Framework/HistogramRegistry.h" - -using namespace o2; -using namespace o2::framework; namespace o2::analysis::femtoWorld { @@ -33,10 +32,10 @@ class PairWithCentrality /// @param kstarbins /// @param centbins template - void init(HistogramRegistry* registry, t1& kstarbins, t1& centbins) + void init(o2::framework::HistogramRegistry* registry, t1& kstarbins, t1& centbins) { PairWithCentralityRegistry = registry; - AxisSpec kstarAxis = {kstarbins, "#it{k*} (GeV/#it{c})"}; + o2::framework::AxisSpec kstarAxis = {kstarbins, "#it{k*} (GeV/#it{c})"}; CentBins = centbins; CentBins.erase(CentBins.begin()); @@ -45,9 +44,9 @@ class PairWithCentrality std::string HistSuffix1 = static_cast(HistSuffix[i]); std::string HistSuffix2 = static_cast(HistSuffix[i + 1]); std::string HistName = "kstar_cent_" + HistSuffix1 + "_" + HistSuffix2; - PairWithCentralityRegistry->add(HistName.c_str(), HistTitle.c_str(), HistType::kTH1F, {kstarAxis}); + PairWithCentralityRegistry->add(HistName.c_str(), HistTitle.c_str(), o2::framework::HistType::kTH1F, {kstarAxis}); } - PairWithCentralityRegistry->add("Beyond_Max_Cent", "Beyond_Max_Cent", HistType::kTH1F, {kstarAxis}); + PairWithCentralityRegistry->add("Beyond_Max_Cent", "Beyond_Max_Cent", o2::framework::HistType::kTH1F, {kstarAxis}); } /// @brief @@ -81,7 +80,7 @@ class PairWithCentrality } protected: - HistogramRegistry* PairWithCentralityRegistry = nullptr; + o2::framework::HistogramRegistry* PairWithCentralityRegistry = nullptr; std::vector CentBins; static constexpr std::string_view HistSuffix[10] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"}; }; diff --git a/PWGCF/FemtoWorld/Core/FemtoWorldParticleHisto.h b/PWGCF/FemtoWorld/Core/FemtoWorldParticleHisto.h index 0671c267200..1df20179841 100644 --- a/PWGCF/FemtoWorld/Core/FemtoWorldParticleHisto.h +++ b/PWGCF/FemtoWorld/Core/FemtoWorldParticleHisto.h @@ -17,12 +17,16 @@ #ifndef PWGCF_FEMTOWORLD_CORE_FEMTOWORLDPARTICLEHISTO_H_ #define PWGCF_FEMTOWORLD_CORE_FEMTOWORLDPARTICLEHISTO_H_ -#include #include "PWGCF/FemtoWorld/DataModel/FemtoWorldDerived.h" -#include "Framework/HistogramRegistry.h" -using namespace o2::framework; -// using namespace o2::aod::o2::aod; +#include +#include +#include + +#include +#include + +#include namespace o2::analysis::femtoWorld { @@ -39,8 +43,8 @@ class FemtoWorldParticleHisto virtual ~FemtoWorldParticleHisto() = default; /// Initialization of the QA histograms - /// \param registry HistogramRegistry - void init(HistogramRegistry* registry) + /// \param registry o2::framework::HistogramRegistry + void init(o2::framework::HistogramRegistry* registry) { if (registry) { mHistogramRegistry = registry; @@ -49,32 +53,32 @@ class FemtoWorldParticleHisto folderName += static_cast(mFolderSuffix[mFolderSuffixType]); /// Histograms of the kinematic properties - mHistogramRegistry->add((folderName + "/hPt").c_str(), "; #it{p}_{T} (GeV/#it{c}); Entries", kTH1F, {{240, 0, 6}}); - mHistogramRegistry->add((folderName + "/hEta").c_str(), "; #eta; Entries", kTH1F, {{200, -1.5, 1.5}}); - mHistogramRegistry->add((folderName + "/hPhi").c_str(), "; #phi; Entries", kTH1F, {{200, 0, 2. * M_PI}}); - mHistogramRegistry->add((folderName + "/dEdxTPCVsMomentum").c_str(), "; #it{p} (GeV/#it{c}); dE/dx (keV/cm)", kTH2F, {{200, 0., 5.}, {250, 0., 500.}}); - mHistogramRegistry->add((folderName + "/TOFBetaVsMomentum").c_str(), "; #it{p} (GeV/#it{c}); TOF #beta", kTH2F, {{200, 0., 5.}, {250, 0.4, 1.1}}); + mHistogramRegistry->add((folderName + "/hPt").c_str(), "; #it{p}_{T} (GeV/#it{c}); Entries", o2::framework::kTH1F, {{240, 0, 6}}); + mHistogramRegistry->add((folderName + "/hEta").c_str(), "; #eta; Entries", o2::framework::kTH1F, {{200, -1.5, 1.5}}); + mHistogramRegistry->add((folderName + "/hPhi").c_str(), "; #phi; Entries", o2::framework::kTH1F, {{200, 0, 2. * M_PI}}); + mHistogramRegistry->add((folderName + "/dEdxTPCVsMomentum").c_str(), "; #it{p} (GeV/#it{c}); dE/dx (keV/cm)", o2::framework::kTH2F, {{200, 0., 5.}, {250, 0., 500.}}); + mHistogramRegistry->add((folderName + "/TOFBetaVsMomentum").c_str(), "; #it{p} (GeV/#it{c}); TOF #beta", o2::framework::kTH2F, {{200, 0., 5.}, {250, 0.4, 1.1}}); /// Particle-type specific histograms if constexpr (mParticleType == o2::aod::femtoworldparticle::ParticleType::kTrack) { /// Track histograms - mHistogramRegistry->add((folderName + "/hDCAxy").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", kTH2F, {{20, 0.5, 4.05}, {500, -5, 5}}); - mHistogramRegistry->add((folderName + "/hDCAz").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{z} (cm)", kTH2F, {{20, 0.5, 4.05}, {500, -5, 5}}); + mHistogramRegistry->add((folderName + "/hDCAxy").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::kTH2F, {{20, 0.5, 4.05}, {500, -5, 5}}); + mHistogramRegistry->add((folderName + "/hDCAz").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{z} (cm)", o2::framework::kTH2F, {{20, 0.5, 4.05}, {500, -5, 5}}); } else if constexpr (mParticleType == o2::aod::femtoworldparticle::ParticleType::kV0) { /// V0 histograms - mHistogramRegistry->add((folderName + "/hCPA").c_str(), "; #it{p}_{T} (GeV/#it{c}); cos#alpha", kTH2F, {{8, 0.3, 4.3}, {1000, 0.9, 1}}); + mHistogramRegistry->add((folderName + "/hCPA").c_str(), "; #it{p}_{T} (GeV/#it{c}); cos#alpha", o2::framework::kTH2F, {{8, 0.3, 4.3}, {1000, 0.9, 1}}); } else if constexpr (mParticleType == o2::aod::femtoworldparticle::ParticleType::kCascade) { /// Cascade histograms } else if constexpr (mParticleType == o2::aod::femtoworldparticle::ParticleType::kPhi) { /// Phi histograms int mInvBins = 1000; framework::AxisSpec mInvAxis = {mInvBins, 0.5, 1.5}; - mHistogramRegistry->add((folderName + "/InvariantMass").c_str(), ";M_{K^{+}K^{-}} (GeV/#it{c}^{2});", kTH1D, {mInvAxis}); - mHistogramRegistry->add((folderName + "/EtaVsMultiplicity").c_str(), "; multiplicity; #eta", kTH2F, {{12, 0., 200.}, {29, -2., 2.}}); + mHistogramRegistry->add((folderName + "/InvariantMass").c_str(), ";M_{K^{+}K^{-}} (GeV/#it{c}^{2});", o2::framework::kTH1D, {mInvAxis}); + mHistogramRegistry->add((folderName + "/EtaVsMultiplicity").c_str(), "; multiplicity; #eta", o2::framework::kTH2F, {{12, 0., 200.}, {29, -2., 2.}}); } else if constexpr (mParticleType == o2::aod::femtoworldparticle::ParticleType::kPhiChild) { /// Phi daughters histograms - mHistogramRegistry->add((folderName + "/TOFNSigmaKvsP").c_str(), "; #it{p} (GeV/#it{c}); n#sigma TOF vs p ", kTH2F, {{200, 0., 5.}, {80, -10, 10}}); - mHistogramRegistry->add((folderName + "/TPCNSigmaKvsP").c_str(), "; #it{p} (GeV/#it{c}); n#sigma TPC vs p ", kTH2F, {{200, 0., 5.}, {80, -10, 10}}); + mHistogramRegistry->add((folderName + "/TOFNSigmaKvsP").c_str(), "; #it{p} (GeV/#it{c}); n#sigma TOF vs p ", o2::framework::kTH2F, {{200, 0., 5.}, {80, -10, 10}}); + mHistogramRegistry->add((folderName + "/TPCNSigmaKvsP").c_str(), "; #it{p} (GeV/#it{c}); n#sigma TPC vs p ", o2::framework::kTH2F, {{200, 0., 5.}, {80, -10, 10}}); } else { LOG(fatal) << "FemtoWorldParticleHisto: Histogramming for requested object not defined - quitting!"; } @@ -158,7 +162,7 @@ class FemtoWorldParticleHisto } private: - HistogramRegistry* mHistogramRegistry; ///< For QA output + o2::framework::HistogramRegistry* mHistogramRegistry; ///< For QA output static constexpr o2::aod::femtoworldparticle::ParticleType mParticleType = particleType; ///< Type of the particle under analysis static constexpr int mFolderSuffixType = suffixType; ///< Counter for the folder suffix specified below static constexpr std::string_view mFolderSuffix[5] = {"", "_one", "_one_rejected", "_two", "two_rejected"}; ///< Suffix for the folder name in case of analyses of pairs of the same kind (T-T, V-V, C-C) diff --git a/PWGCF/FemtoWorld/Core/FemtoWorldPhiSelection.h b/PWGCF/FemtoWorld/Core/FemtoWorldPhiSelection.h index 39040d70ec0..20503e6dcf9 100644 --- a/PWGCF/FemtoWorld/Core/FemtoWorldPhiSelection.h +++ b/PWGCF/FemtoWorld/Core/FemtoWorldPhiSelection.h @@ -19,21 +19,26 @@ #ifndef PWGCF_FEMTOWORLD_CORE_FEMTOWORLDPHISELECTION_H_ #define PWGCF_FEMTOWORLD_CORE_FEMTOWORLDPHISELECTION_H_ -#include -#include - -#include // FIXME - #include "PWGCF/FemtoWorld/Core/FemtoWorldObjectSelection.h" -#include "PWGCF/FemtoWorld/Core/FemtoWorldTrackSelection.h" #include "PWGCF/FemtoWorld/Core/FemtoWorldSelection.h" +#include "PWGCF/FemtoWorld/Core/FemtoWorldTrackSelection.h" +#include "PWGCF/FemtoWorld/DataModel/FemtoWorldDerived.h" + +#include +#include +#include +#include + +#include // FIXME +#include -#include "ReconstructionDataFormats/PID.h" -#include "Common/Core/RecoDecay.h" -#include "Framework/HistogramRegistry.h" -#include "TLorentzVector.h" +#include +#include +#include +#include +#include -using namespace o2::framework; +#include namespace o2::analysis::femtoWorld { @@ -88,10 +93,10 @@ class FemtoWorldPhiSelection : public FemtoWorldObjectSelection - void init(HistogramRegistry* registry); + void init(o2::framework::HistogramRegistry* registry); template - void initPhi(HistogramRegistry* registry); + void initPhi(o2::framework::HistogramRegistry* registry); template bool isSelectedMinimal(C const& col, V const& v0, T const& posTrack, T const& negTrack); @@ -264,15 +269,15 @@ class FemtoWorldPhiSelection : public FemtoWorldObjectSelection -void FemtoWorldPhiSelection::init(HistogramRegistry* registry) +void FemtoWorldPhiSelection::init(o2::framework::HistogramRegistry* registry) { if (registry) { mHistogramRegistry = registry; fillSelectionHistogram(); fillSelectionHistogram(); - AxisSpec massAxisPhi = {60000, 0.0f, 3.0f, "m_{#Phi} (GeV/#it{c}^{2})"}; - AxisSpec massAxisAntiPhi = {60000, 0.0f, 3.0f, "m_{#bar{#Phi}} (GeV/#it{c}^{2})"}; + o2::framework::AxisSpec massAxisPhi = {60000, 0.0f, 3.0f, "m_{#Phi} (GeV/#it{c}^{2})"}; + o2::framework::AxisSpec massAxisAntiPhi = {60000, 0.0f, 3.0f, "m_{#bar{#Phi}} (GeV/#it{c}^{2})"}; /// \todo this should be an automatic check in the parent class, and the return type should be templated size_t nSelections = getNSelections(); @@ -281,32 +286,32 @@ void FemtoWorldPhiSelection::init(HistogramRegistry* registry) } std::string folderName = static_cast(o2::aod::femtoworldparticle::ParticleTypeName[part]); /// \todo initialize histograms for children tracks of v0s - mHistogramRegistry->add((folderName + "/hPt").c_str(), "; #it{p}_{T} (GeV/#it{c}); Entries", kTH1F, {{1000, 0, 10}}); - mHistogramRegistry->add((folderName + "/hEta").c_str(), "; #eta; Entries", kTH1F, {{1000, -1, 1}}); - mHistogramRegistry->add((folderName + "/hPhi").c_str(), "; #phi; Entries", kTH1F, {{1000, 0, 2. * M_PI}}); - // mHistogramRegistry->add((folderName + "/hDaughDCA").c_str(), "; DCA^{daugh} (cm); Entries", kTH1F, {{1000, 0, 10}}); - // mHistogramRegistry->add((folderName + "/hTransRadius").c_str(), "; #it{r}_{xy} (cm); Entries", kTH1F, {{1500, 0, 150}}); - // mHistogramRegistry->add((folderName + "/hDecayVtxX").c_str(), "; #it{Vtx}_{x} (cm); Entries", kTH1F, {{2000, 0, 200}}); - // mHistogramRegistry->add((folderName + "/hDecayVtxY").c_str(), "; #it{Vtx}_{y} (cm)); Entries", kTH1F, {{2000, 0, 200}}); - // mHistogramRegistry->add((folderName + "/hDecayVtxZ").c_str(), "; #it{Vtx}_{z} (cm); Entries", kTH1F, {{2000, 0, 200}}); - // mHistogramRegistry->add((folderName + "/hCPA").c_str(), "; #it{cos #theta_{p}}; Entries", kTH1F, {{1000, 0.9, 1.}}); - // mHistogramRegistry->add((folderName + "/hCPAvsPt").c_str(), "; #it{p}_{T} (GeV/#it{c}); #it{cos #theta_{p}}", kTH2F, {{8, 0.3, 4.3}, {1000, 0.9, 1.}}); - mHistogramRegistry->add((folderName + "/hInvMassPhi").c_str(), "", kTH1F, {massAxisPhi}); - // mHistogramRegistry->add((folderName + "/hInvMassAntiPhi").c_str(), "", kTH1F, {massAxisAntiPhi}); - // mHistogramRegistry->add((folderName + "/hInvMassPhiPhi").c_str(), "", kTH2F, {massAxisPhi, massAxisPhi}); + mHistogramRegistry->add((folderName + "/hPt").c_str(), "; #it{p}_{T} (GeV/#it{c}); Entries", o2::framework::kTH1F, {{1000, 0, 10}}); + mHistogramRegistry->add((folderName + "/hEta").c_str(), "; #eta; Entries", o2::framework::kTH1F, {{1000, -1, 1}}); + mHistogramRegistry->add((folderName + "/hPhi").c_str(), "; #phi; Entries", o2::framework::kTH1F, {{1000, 0, 2. * M_PI}}); + // mHistogramRegistry->add((folderName + "/hDaughDCA").c_str(), "; DCA^{daugh} (cm); Entries", o2::framework::kTH1F, {{1000, 0, 10}}); + // mHistogramRegistry->add((folderName + "/hTransRadius").c_str(), "; #it{r}_{xy} (cm); Entries", o2::framework::kTH1F, {{1500, 0, 150}}); + // mHistogramRegistry->add((folderName + "/hDecayVtxX").c_str(), "; #it{Vtx}_{x} (cm); Entries", o2::framework::kTH1F, {{2000, 0, 200}}); + // mHistogramRegistry->add((folderName + "/hDecayVtxY").c_str(), "; #it{Vtx}_{y} (cm)); Entries", o2::framework::kTH1F, {{2000, 0, 200}}); + // mHistogramRegistry->add((folderName + "/hDecayVtxZ").c_str(), "; #it{Vtx}_{z} (cm); Entries", o2::framework::kTH1F, {{2000, 0, 200}}); + // mHistogramRegistry->add((folderName + "/hCPA").c_str(), "; #it{cos #theta_{p}}; Entries", o2::framework::kTH1F, {{1000, 0.9, 1.}}); + // mHistogramRegistry->add((folderName + "/hCPAvsPt").c_str(), "; #it{p}_{T} (GeV/#it{c}); #it{cos #theta_{p}}", o2::framework::kTH2F, {{8, 0.3, 4.3}, {1000, 0.9, 1.}}); + mHistogramRegistry->add((folderName + "/hInvMassPhi").c_str(), "", o2::framework::kTH1F, {massAxisPhi}); + // mHistogramRegistry->add((folderName + "/hInvMassAntiPhi").c_str(), "", o2::framework::kTH1F, {massAxisAntiPhi}); + // mHistogramRegistry->add((folderName + "/hInvMassPhiPhi").c_str(), "", o2::framework::kTH2F, {massAxisPhi, massAxisPhi}); PosDaughTrack.init(mHistogramRegistry); NegDaughTrack.init(mHistogramRegistry); - mHistogramRegistry->add("PhiQA/hInvMassPhiNoCuts", "No cuts Phi", kTH1F, {massAxisPhi}); - mHistogramRegistry->add("PhiQA/hInvMassPhiInvMassCut", "Invariant mass cut Phi", kTH1F, {massAxisPhi}); - mHistogramRegistry->add("PhiQA/hInvMassPhiPtMin", "Minimum Pt cut", kTH1F, {massAxisPhi}); - mHistogramRegistry->add("PhiQA/hInvMassPhiPtMax", "Maximum Pt cut", kTH1F, {massAxisPhi}); - mHistogramRegistry->add("PhiQA/hInvMassPhiDCAPhiDaugh", "Phi-daughters DCA cut", kTH1F, {massAxisPhi}); - mHistogramRegistry->add("PhiQA/hInvMassPhiCPA", "CPA cut", kTH1F, {massAxisPhi}); - mHistogramRegistry->add("PhiQA/hInvMassPhiTranRadMin", "Minimum transverse radius cut", kTH1F, {massAxisPhi}); - mHistogramRegistry->add("PhiQA/hInvMassPhiTranRadMax", "Maximum transverse radius cut", kTH1F, {massAxisPhi}); - mHistogramRegistry->add("PhiQA/hInvMassPhiDecVtxMax", "Maximum distance on decay vertex cut", kTH1F, {massAxisPhi}); + mHistogramRegistry->add("PhiQA/hInvMassPhiNoCuts", "No cuts Phi", o2::framework::kTH1F, {massAxisPhi}); + mHistogramRegistry->add("PhiQA/hInvMassPhiInvMassCut", "Invariant mass cut Phi", o2::framework::kTH1F, {massAxisPhi}); + mHistogramRegistry->add("PhiQA/hInvMassPhiPtMin", "Minimum Pt cut", o2::framework::kTH1F, {massAxisPhi}); + mHistogramRegistry->add("PhiQA/hInvMassPhiPtMax", "Maximum Pt cut", o2::framework::kTH1F, {massAxisPhi}); + mHistogramRegistry->add("PhiQA/hInvMassPhiDCAPhiDaugh", "Phi-daughters DCA cut", o2::framework::kTH1F, {massAxisPhi}); + mHistogramRegistry->add("PhiQA/hInvMassPhiCPA", "CPA cut", o2::framework::kTH1F, {massAxisPhi}); + mHistogramRegistry->add("PhiQA/hInvMassPhiTranRadMin", "Minimum transverse radius cut", o2::framework::kTH1F, {massAxisPhi}); + mHistogramRegistry->add("PhiQA/hInvMassPhiTranRadMax", "Maximum transverse radius cut", o2::framework::kTH1F, {massAxisPhi}); + mHistogramRegistry->add("PhiQA/hInvMassPhiDecVtxMax", "Maximum distance on decay vertex cut", o2::framework::kTH1F, {massAxisPhi}); } /// check whether the most open cuts are fulfilled - most of this should have already be done by the filters nPtPhiMinSel = getNSelections(femtoWorldPhiSelection::kpTPhiMin); @@ -328,15 +333,15 @@ void FemtoWorldPhiSelection::init(HistogramRegistry* registry) // Phi initialization template -void FemtoWorldPhiSelection::initPhi(HistogramRegistry* registry) +void FemtoWorldPhiSelection::initPhi(o2::framework::HistogramRegistry* registry) { if (registry) { mHistogramRegistry = registry; fillSelectionHistogram(); fillSelectionHistogram(); - AxisSpec massAxisPhi = {60000, 0.0f, 3.0f, "m_{#Phi} (GeV/#it{c}^{2})"}; - // AxisSpec massAxisAntiPhi = {600, 0.0f, 3.0f, "m_{#bar{#Phi}} (GeV/#it{c}^{2})"}; + o2::framework::AxisSpec massAxisPhi = {60000, 0.0f, 3.0f, "m_{#Phi} (GeV/#it{c}^{2})"}; + // o2::framework::AxisSpec massAxisAntiPhi = {600, 0.0f, 3.0f, "m_{#bar{#Phi}} (GeV/#it{c}^{2})"}; /// \todo this should be an automatic check in the parent class, and the return type should be templated size_t nSelections = getNSelections(); @@ -345,29 +350,29 @@ void FemtoWorldPhiSelection::initPhi(HistogramRegistry* registry) } std::string folderName = static_cast(o2::aod::femtoworldparticle::ParticleTypeName[part]); /// \todo initialize histograms for children tracks of v0s - mHistogramRegistry->add((folderName + "/hPtPhi").c_str(), "; #it{p}_{T} (GeV/#it{c}); Entries", kTH1F, {{1000, 0, 10}}); - mHistogramRegistry->add((folderName + "/hEtaPhi").c_str(), "; #eta; Entries", kTH1F, {{1000, -1, 1}}); - mHistogramRegistry->add((folderName + "/hPhiPhi").c_str(), "; #phi; Entries", kTH1F, {{1000, 0, 2. * M_PI}}); - // mHistogramRegistry->add((folderName + "/hDaughDCA").c_str(), "; DCA^{daugh} (cm); Entries", kTH1F, {{1000, 0, 10}}); - // mHistogramRegistry->add((folderName + "/hTransRadius").c_str(), "; #it{r}_{xy} (cm); Entries", kTH1F, {{1500, 0, 150}}); - // mHistogramRegistry->add((folderName + "/hDecayVtxX").c_str(), "; #it{Vtx}_{x} (cm); Entries", kTH1F, {{2000, 0, 200}}); - // mHistogramRegistry->add((folderName + "/hDecayVtxY").c_str(), "; #it{Vtx}_{y} (cm)); Entries", kTH1F, {{2000, 0, 200}}); - // mHistogramRegistry->add((folderName + "/hDecayVtxZ").c_str(), "; #it{Vtx}_{z} (cm); Entries", kTH1F, {{2000, 0, 200}}); - // mHistogramRegistry->add((folderName + "/hCPA").c_str(), "; #it{cos #theta_{p}}; Entries", kTH1F, {{1000, 0.9, 1.}}); - // mHistogramRegistry->add((folderName + "/hCPAvsPt").c_str(), "; #it{p}_{T} (GeV/#it{c}); #it{cos #theta_{p}}", kTH2F, {{8, 0.3, 4.3}, {1000, 0.9, 1.}}); - mHistogramRegistry->add((folderName + "/hInvMassPhi").c_str(), "", kTH1F, {massAxisPhi}); + mHistogramRegistry->add((folderName + "/hPtPhi").c_str(), "; #it{p}_{T} (GeV/#it{c}); Entries", o2::framework::kTH1F, {{1000, 0, 10}}); + mHistogramRegistry->add((folderName + "/hEtaPhi").c_str(), "; #eta; Entries", o2::framework::kTH1F, {{1000, -1, 1}}); + mHistogramRegistry->add((folderName + "/hPhiPhi").c_str(), "; #phi; Entries", o2::framework::kTH1F, {{1000, 0, 2. * M_PI}}); + // mHistogramRegistry->add((folderName + "/hDaughDCA").c_str(), "; DCA^{daugh} (cm); Entries", o2::framework::kTH1F, {{1000, 0, 10}}); + // mHistogramRegistry->add((folderName + "/hTransRadius").c_str(), "; #it{r}_{xy} (cm); Entries", o2::framework::kTH1F, {{1500, 0, 150}}); + // mHistogramRegistry->add((folderName + "/hDecayVtxX").c_str(), "; #it{Vtx}_{x} (cm); Entries", o2::framework::kTH1F, {{2000, 0, 200}}); + // mHistogramRegistry->add((folderName + "/hDecayVtxY").c_str(), "; #it{Vtx}_{y} (cm)); Entries", o2::framework::kTH1F, {{2000, 0, 200}}); + // mHistogramRegistry->add((folderName + "/hDecayVtxZ").c_str(), "; #it{Vtx}_{z} (cm); Entries", o2::framework::kTH1F, {{2000, 0, 200}}); + // mHistogramRegistry->add((folderName + "/hCPA").c_str(), "; #it{cos #theta_{p}}; Entries", o2::framework::kTH1F, {{1000, 0.9, 1.}}); + // mHistogramRegistry->add((folderName + "/hCPAvsPt").c_str(), "; #it{p}_{T} (GeV/#it{c}); #it{cos #theta_{p}}", o2::framework::kTH2F, {{8, 0.3, 4.3}, {1000, 0.9, 1.}}); + mHistogramRegistry->add((folderName + "/hInvMassPhi").c_str(), "", o2::framework::kTH1F, {massAxisPhi}); PosDaughTrack.init(mHistogramRegistry); NegDaughTrack.init(mHistogramRegistry); - mHistogramRegistry->add("PhiQA/hInvMasPhiNoCuts", "No cuts", kTH1F, {massAxisPhi}); - mHistogramRegistry->add("PhiQA/hInvMassPhiInvMassCut", "Invariant mass cut", kTH1F, {massAxisPhi}); - mHistogramRegistry->add("PhiQA/hInvMassPhiPtMin", "Minimum Pt cut", kTH1F, {massAxisPhi}); - mHistogramRegistry->add("PhiQA/hInvMassPhiPtMax", "Maximum Pt cut", kTH1F, {massAxisPhi}); - // mHistogramRegistry->add("PhiQA/hInvMassPhiDCAPhiDaugh", "Phi-daughters DCA cut", kTH1F, {massAxisPhi}); - // mHistogramRegistry->add("PhiQA/hInvMassPhiCPA", "CPA cut", kTH1F, {massAxisPhi}); - // mHistogramRegistry->add("PhiQA/hInvMassPhiTranRadMin", "Minimum transverse radius cut", kTH1F, {massAxisPhi}); - // mHistogramRegistry->add("PhiQA/hInvMassPhiTranRadMax", "Maximum transverse radius cut", kTH1F, {massAxisPhi}); - // mHistogramRegistry->add("PhiQA/hInvMassPhiDecVtxMax", "Maximum distance on decay vertex cut", kTH1F, {massAxisPhi}); + mHistogramRegistry->add("PhiQA/hInvMasPhiNoCuts", "No cuts", o2::framework::kTH1F, {massAxisPhi}); + mHistogramRegistry->add("PhiQA/hInvMassPhiInvMassCut", "Invariant mass cut", o2::framework::kTH1F, {massAxisPhi}); + mHistogramRegistry->add("PhiQA/hInvMassPhiPtMin", "Minimum Pt cut", o2::framework::kTH1F, {massAxisPhi}); + mHistogramRegistry->add("PhiQA/hInvMassPhiPtMax", "Maximum Pt cut", o2::framework::kTH1F, {massAxisPhi}); + // mHistogramRegistry->add("PhiQA/hInvMassPhiDCAPhiDaugh", "Phi-daughters DCA cut", o2::framework::kTH1F, {massAxisPhi}); + // mHistogramRegistry->add("PhiQA/hInvMassPhiCPA", "CPA cut", o2::framework::kTH1F, {massAxisPhi}); + // mHistogramRegistry->add("PhiQA/hInvMassPhiTranRadMin", "Minimum transverse radius cut", o2::framework::kTH1F, {massAxisPhi}); + // mHistogramRegistry->add("PhiQA/hInvMassPhiTranRadMax", "Maximum transverse radius cut", o2::framework::kTH1F, {massAxisPhi}); + // mHistogramRegistry->add("PhiQA/hInvMassPhiDecVtxMax", "Maximum distance on decay vertex cut", o2::framework::kTH1F, {massAxisPhi}); } /// check whether the most open cuts are fulfilled - most of this should have already be done by the filters nPtPhiMinSel = getNSelections(femtoWorldPhiSelection::kpTPhiMin); @@ -557,8 +562,8 @@ std::array FemtoWorldPhiSelection::getCutContainer(C const& TLorentzVector part1Vec; TLorentzVector part2Vec; - Configurable ConfPDGCodePartOne{"ConfPDGCodePartOne", 321, "Particle 1 - PDG code"}; - Configurable ConfPDGCodePartTwo{"ConfPDGCodePartTwo", 321, "Particle 2 - PDG code"}; + o2::framework::Configurable ConfPDGCodePartOne{"ConfPDGCodePartOne", 321, "Particle 1 - PDG code"}; + o2::framework::Configurable ConfPDGCodePartTwo{"ConfPDGCodePartTwo", 321, "Particle 2 - PDG code"}; float mMassOne = TDatabasePDG::Instance()->GetParticle(ConfPDGCodePartOne)->Mass(); // FIXME: Get from the PDG service of the common header float mMassTwo = TDatabasePDG::Instance()->GetParticle(ConfPDGCodePartTwo)->Mass(); // FIXME: Get from the PDG service of the common header part1Vec.SetPtEtaPhiM(posTrack.pt(), posTrack.eta(), posTrack.phi(), mMassOne); @@ -619,8 +624,8 @@ void FemtoWorldPhiSelection::fillQA(C const& /*col*/, V const& /*v0*/, T const& if (mHistogramRegistry) { TLorentzVector part1Vec; TLorentzVector part2Vec; - Configurable ConfPDGCodePartOne{"ConfPDGCodePartOne", 321, "Particle 1 - PDG code"}; - Configurable ConfPDGCodePartTwo{"ConfPDGCodePartTwo", 321, "Particle 2 - PDG code"}; + o2::framework::Configurable ConfPDGCodePartOne{"ConfPDGCodePartOne", 321, "Particle 1 - PDG code"}; + o2::framework::Configurable ConfPDGCodePartTwo{"ConfPDGCodePartTwo", 321, "Particle 2 - PDG code"}; float mMassOne = TDatabasePDG::Instance()->GetParticle(ConfPDGCodePartOne)->Mass(); // FIXME: Get from the PDG service of the common header float mMassTwo = TDatabasePDG::Instance()->GetParticle(ConfPDGCodePartTwo)->Mass(); // FIXME: Get from the PDG service of the common header part1Vec.SetPtEtaPhiM(posTrack.pt(), posTrack.eta(), posTrack.phi(), mMassOne); diff --git a/PWGCF/FemtoWorld/Core/FemtoWorldPionContainer.h b/PWGCF/FemtoWorld/Core/FemtoWorldPionContainer.h index 9c68ac7c76e..c6b959a83c6 100644 --- a/PWGCF/FemtoWorld/Core/FemtoWorldPionContainer.h +++ b/PWGCF/FemtoWorld/Core/FemtoWorldPionContainer.h @@ -18,20 +18,18 @@ #ifndef PWGCF_FEMTOWORLD_CORE_FEMTOWORLDPIONCONTAINER_H_ #define PWGCF_FEMTOWORLD_CORE_FEMTOWORLDPIONCONTAINER_H_ -#include -#include -#include "Framework/HistogramRegistry.h" #include "PWGCF/FemtoWorld/Core/FemtoWorldMath.h" -#include "Math/Vector4D.h" -#include "TMath.h" -#include "TDatabasePDG.h" +#include +#include +#include -#include "TLorentzVector.h" -#include "CommonConstants/MathConstants.h" -#include "TRandom.h" +#include +#include -using namespace o2::framework; +#include +#include +#include namespace o2::analysis::femtoWorld { @@ -77,7 +75,7 @@ class FemtoWorldPionContainer /// \param mInvBins invariant mass binning for the histograms template - void init(HistogramRegistry* registry, T1& kstarBins, T1& multBins, T1& kTBins, T1& mTBins, T2& phiBins, T2& etaBins, T2& mInvBins) + void init(o2::framework::HistogramRegistry* registry, T1& kstarBins, T1& multBins, T1& kTBins, T1& mTBins, T2& phiBins, T2& etaBins, T2& mInvBins) { mHistogramRegistry = registry; std::string femtoObs; @@ -98,18 +96,18 @@ class FemtoWorldPionContainer framework::AxisSpec mInvAxis = {mInvBins, 0.0, 10.0}; std::string folderName = static_cast(mFolderSuffix[mEventType]); - mHistogramRegistry->add((folderName + "relPairDist").c_str(), ("; " + femtoObs + "; Entries").c_str(), kTH1F, {femtoObsAxis}); - mHistogramRegistry->add((folderName + "relPairkT").c_str(), "; #it{k}_{T} (GeV/#it{c}); Entries", kTH1F, {kTAxis}); - mHistogramRegistry->add((folderName + "relPairkstarkT").c_str(), ("; " + femtoObs + "; #it{k}_{T} (GeV/#it{c})").c_str(), kTH2F, {femtoObsAxis, kTAxis}); - mHistogramRegistry->add((folderName + "relPairkstarmT").c_str(), ("; " + femtoObs + "; #it{m}_{T} (GeV/#it{c}^{2})").c_str(), kTH2F, {femtoObsAxis, mTAxis}); - mHistogramRegistry->add((folderName + "relPairkstarMult").c_str(), ("; " + femtoObs + "; Multiplicity").c_str(), kTH2F, {femtoObsAxis, multAxis}); - mHistogramRegistry->add((folderName + "kstarPtPart1").c_str(), ("; " + femtoObs + "; #it{p} _{T} Particle 1 (GeV/#it{c})").c_str(), kTH2F, {femtoObsAxis, {375, 0., 7.5}}); - mHistogramRegistry->add((folderName + "kstarPtPart2").c_str(), ("; " + femtoObs + "; #it{p} _{T} Particle 2 (GeV/#it{c})").c_str(), kTH2F, {femtoObsAxis, {375, 0., 7.5}}); - mHistogramRegistry->add((folderName + "MultPtPart1").c_str(), "; #it{p} _{T} Particle 1 (GeV/#it{c}); Multiplicity", kTH2F, {{375, 0., 7.5}, multAxis}); - mHistogramRegistry->add((folderName + "MultPtPart2").c_str(), "; #it{p} _{T} Particle 2 (GeV/#it{c}); Multiplicity", kTH2F, {{375, 0., 7.5}, multAxis}); - mHistogramRegistry->add((folderName + "PtPart1PtPart2").c_str(), "; #it{p} _{T} Particle 1 (GeV/#it{c}); #it{p} _{T} Particle 2 (GeV/#it{c})", kTH2F, {{375, 0., 7.5}, {375, 0., 7.5}}); - mHistogramRegistry->add((folderName + "relPairDetaDphi").c_str(), "; #Delta#varphi (rad); #Delta#eta", kTH2D, {phiAxis, etaAxis}); - mHistogramRegistry->add((folderName + "relPairInvariantMass").c_str(), ";M_{K^{+}K^{-}} (GeV/#it{c}^{2});", kTH1D, {mInvAxis}); + mHistogramRegistry->add((folderName + "relPairDist").c_str(), ("; " + femtoObs + "; Entries").c_str(), o2::framework::kTH1F, {femtoObsAxis}); + mHistogramRegistry->add((folderName + "relPairkT").c_str(), "; #it{k}_{T} (GeV/#it{c}); Entries", o2::framework::kTH1F, {kTAxis}); + mHistogramRegistry->add((folderName + "relPairkstarkT").c_str(), ("; " + femtoObs + "; #it{k}_{T} (GeV/#it{c})").c_str(), o2::framework::kTH2F, {femtoObsAxis, kTAxis}); + mHistogramRegistry->add((folderName + "relPairkstarmT").c_str(), ("; " + femtoObs + "; #it{m}_{T} (GeV/#it{c}^{2})").c_str(), o2::framework::kTH2F, {femtoObsAxis, mTAxis}); + mHistogramRegistry->add((folderName + "relPairkstarMult").c_str(), ("; " + femtoObs + "; Multiplicity").c_str(), o2::framework::kTH2F, {femtoObsAxis, multAxis}); + mHistogramRegistry->add((folderName + "kstarPtPart1").c_str(), ("; " + femtoObs + "; #it{p} _{T} Particle 1 (GeV/#it{c})").c_str(), o2::framework::kTH2F, {femtoObsAxis, {375, 0., 7.5}}); + mHistogramRegistry->add((folderName + "kstarPtPart2").c_str(), ("; " + femtoObs + "; #it{p} _{T} Particle 2 (GeV/#it{c})").c_str(), o2::framework::kTH2F, {femtoObsAxis, {375, 0., 7.5}}); + mHistogramRegistry->add((folderName + "MultPtPart1").c_str(), "; #it{p} _{T} Particle 1 (GeV/#it{c}); Multiplicity", o2::framework::kTH2F, {{375, 0., 7.5}, multAxis}); + mHistogramRegistry->add((folderName + "MultPtPart2").c_str(), "; #it{p} _{T} Particle 2 (GeV/#it{c}); Multiplicity", o2::framework::kTH2F, {{375, 0., 7.5}, multAxis}); + mHistogramRegistry->add((folderName + "PtPart1PtPart2").c_str(), "; #it{p} _{T} Particle 1 (GeV/#it{c}); #it{p} _{T} Particle 2 (GeV/#it{c})", o2::framework::kTH2F, {{375, 0., 7.5}, {375, 0., 7.5}}); + mHistogramRegistry->add((folderName + "relPairDetaDphi").c_str(), "; #Delta#varphi (rad); #Delta#eta", o2::framework::kTH2D, {phiAxis, etaAxis}); + mHistogramRegistry->add((folderName + "relPairInvariantMass").c_str(), ";M_{K^{+}K^{-}} (GeV/#it{c}^{2});", o2::framework::kTH1D, {mInvAxis}); } /// Set the PDG codes of the two particles involved @@ -170,7 +168,7 @@ class FemtoWorldPionContainer } protected: - HistogramRegistry* mHistogramRegistry = nullptr; ///< For QA output + o2::framework::HistogramRegistry* mHistogramRegistry = nullptr; ///< For QA output static constexpr std::string_view mFolderSuffix[6] = {"SameEventPlusMinus/", "MixedEventPlusMinus/", "SameEventPlusPlus/", "MixedEventPlusPlus/", "SameEventMinusMinus/", "MixedEventMinusMinus/"}; ///< Folder naming for the output according to mEventType static constexpr femtoWorldPionContainer::Observable mFemtoObs = obs; ///< Femtoscopic observable to be computed (according to femtoWorldPionContainer::Observable) static constexpr int mEventType = eventType; ///< Type of the event (same/mixed, according to femtoWorldPionContainer::EventType) diff --git a/PWGCF/FemtoWorld/Core/FemtoWorldSelection.h b/PWGCF/FemtoWorld/Core/FemtoWorldSelection.h index d94fa0add6b..637eeb85dc9 100644 --- a/PWGCF/FemtoWorld/Core/FemtoWorldSelection.h +++ b/PWGCF/FemtoWorld/Core/FemtoWorldSelection.h @@ -13,8 +13,10 @@ /// \brief FemtoWorldSelection - small generic class to do selections /// \author Andi Mathis, TU München, andreas.mathis@ph.tum.de -#ifndef FEMTOWORLDSELECTION_H_ -#define FEMTOWORLDSELECTION_H_ +#ifndef PWGCF_FEMTOWORLD_CORE_FEMTOWORLDSELECTION_H_ +#define PWGCF_FEMTOWORLD_CORE_FEMTOWORLDSELECTION_H_ + +#include namespace o2::analysis::femtoWorld { @@ -115,4 +117,4 @@ class FemtoWorldSelection } // namespace o2::analysis::femtoWorld -#endif /* FEMTOWORLDSELECTION_H_ */ +#endif // PWGCF_FEMTOWORLD_CORE_FEMTOWORLDSELECTION_H_ diff --git a/PWGCF/FemtoWorld/Core/FemtoWorldTrackSelection.h b/PWGCF/FemtoWorld/Core/FemtoWorldTrackSelection.h index 22869bde36f..2223aefa07b 100644 --- a/PWGCF/FemtoWorld/Core/FemtoWorldTrackSelection.h +++ b/PWGCF/FemtoWorld/Core/FemtoWorldTrackSelection.h @@ -15,25 +15,29 @@ /// \author Luca Barioglio, TU München, luca.barioglio@cern.ch /// \author Zuzanna Chochulska, WUT Warsaw, zchochul@cern.ch -#ifndef FEMTOWORLDTRACKSELECTION_H_ -#define FEMTOWORLDTRACKSELECTION_H_ +#ifndef PWGCF_FEMTOWORLD_CORE_FEMTOWORLDTRACKSELECTION_H_ +#define PWGCF_FEMTOWORLD_CORE_FEMTOWORLDTRACKSELECTION_H_ #include "PWGCF/FemtoWorld/Core/FemtoWorldObjectSelection.h" +#include "PWGCF/FemtoWorld/Core/FemtoWorldSelection.h" #include "PWGCF/FemtoWorld/DataModel/FemtoWorldDerived.h" -#include "Common/Core/TrackSelection.h" -#include "Common/Core/TrackSelectionDefaults.h" #include "Common/DataModel/PIDResponseTOF.h" #include "Common/DataModel/PIDResponseTPC.h" -#include "Common/DataModel/TrackSelectionTables.h" -#include "Framework/HistogramRegistry.h" -#include "ReconstructionDataFormats/PID.h" +#include +#include +#include +#include +#include #include -#include +#include +#include +#include +#include -using namespace o2::framework; +#include namespace o2::analysis::femtoWorld { @@ -92,15 +96,15 @@ class FemtoWorldTrackSelection : public FemtoWorldObjectSelection - void init(HistogramRegistry* registry); + void init(o2::framework::HistogramRegistry* registry); /// Passes the species to the task for which PID needs to be stored /// \tparam T Data type of the configurable passed to the functions @@ -285,7 +289,7 @@ class FemtoWorldTrackSelection : public FemtoWorldObjectSelection -void FemtoWorldTrackSelection::init(HistogramRegistry* registry) +void FemtoWorldTrackSelection::init(o2::framework::HistogramRegistry* registry) { if (registry) { mHistogramRegistry = registry; @@ -297,36 +301,36 @@ void FemtoWorldTrackSelection::init(HistogramRegistry* registry) LOG(fatal) << "FemtoWorldTrackCuts: Number of selections too large for your container - quitting!"; } - mHistogramRegistry->add((folderName + "/hPt").c_str(), "; #it{p}_{T} (GeV/#it{c}); Entries", kTH1F, {{240, 0, 6}}); - mHistogramRegistry->add((folderName + "/hEta").c_str(), "; #eta; Entries", kTH1F, {{200, -1.5, 1.5}}); - mHistogramRegistry->add((folderName + "/hPhi").c_str(), "; #phi; Entries", kTH1F, {{200, 0, 2. * M_PI}}); - mHistogramRegistry->add((folderName + "/hTPCfindable").c_str(), "; TPC findable clusters; Entries", kTH1F, {{163, -0.5, 162.5}}); - mHistogramRegistry->add((folderName + "/hTPCfound").c_str(), "; TPC found clusters; Entries", kTH1F, {{163, -0.5, 162.5}}); - mHistogramRegistry->add((folderName + "/hTPCcrossedOverFindalbe").c_str(), "; TPC ratio findable; Entries", kTH1F, {{100, 0.5, 1.5}}); - mHistogramRegistry->add((folderName + "/hTPCcrossedRows").c_str(), "; TPC crossed rows; Entries", kTH1F, {{163, 0, 163}}); - mHistogramRegistry->add((folderName + "/hTPCfindableVsCrossed").c_str(), ";TPC findable clusters ; TPC crossed rows;", kTH2F, {{163, 0, 163}, {163, 0, 163}}); - mHistogramRegistry->add((folderName + "/hTPCshared").c_str(), "; TPC shared clusters; Entries", kTH1F, {{163, -0.5, 162.5}}); - mHistogramRegistry->add((folderName + "/hITSclusters").c_str(), "; ITS clusters; Entries", kTH1F, {{10, -0.5, 9.5}}); - mHistogramRegistry->add((folderName + "/hITSclustersIB").c_str(), "; ITS clusters in IB; Entries", kTH1F, {{10, -0.5, 9.5}}); - mHistogramRegistry->add((folderName + "/hDCAxy").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", kTH2F, {{100, 0, 10}, {500, -5, 5}}); - mHistogramRegistry->add((folderName + "/hDCAz").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{z} (cm)", kTH2F, {{100, 0, 10}, {500, -5, 5}}); - mHistogramRegistry->add((folderName + "/hDCA").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA (cm)", kTH2F, {{100, 0, 10}, {301, 0., 1.5}}); - mHistogramRegistry->add((folderName + "/hTPCdEdX").c_str(), "; #it{p} (GeV/#it{c}); TPC Signal", kTH2F, {{100, 0, 10}, {1000, 0, 1000}}); - mHistogramRegistry->add((folderName + "/nSigmaTPC_el").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TPC}^{e}", kTH2F, {{100, 0, 10}, {100, -5, 5}}); - mHistogramRegistry->add((folderName + "/nSigmaTPC_pi").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TPC}^{#pi}", kTH2F, {{100, 0, 10}, {100, -5, 5}}); - mHistogramRegistry->add((folderName + "/nSigmaTPC_K").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TPC}^{K}", kTH2F, {{100, 0, 10}, {100, -5, 5}}); - mHistogramRegistry->add((folderName + "/nSigmaTPC_p").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TPC}^{p}", kTH2F, {{100, 0, 10}, {100, -5, 5}}); - mHistogramRegistry->add((folderName + "/nSigmaTPC_d").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TPC}^{d}", kTH2F, {{100, 0, 10}, {100, -5, 5}}); - mHistogramRegistry->add((folderName + "/nSigmaTOF_el").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TOF}^{e}", kTH2F, {{100, 0, 10}, {100, -5, 5}}); - mHistogramRegistry->add((folderName + "/nSigmaTOF_pi").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TOF}^{#pi}", kTH2F, {{100, 0, 10}, {100, -5, 5}}); - mHistogramRegistry->add((folderName + "/nSigmaTOF_K").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TOF}^{K}", kTH2F, {{100, 0, 10}, {100, -5, 5}}); - mHistogramRegistry->add((folderName + "/nSigmaTOF_p").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TOF}^{p}", kTH2F, {{100, 0, 10}, {100, -5, 5}}); - mHistogramRegistry->add((folderName + "/nSigmaTOF_d").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TOF}^{d}", kTH2F, {{100, 0, 10}, {100, -5, 5}}); - mHistogramRegistry->add((folderName + "/nSigmaComb_el").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{comb}^{e}", kTH2F, {{100, 0, 10}, {100, -5, 5}}); - mHistogramRegistry->add((folderName + "/nSigmaComb_pi").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{comb}^{#pi}", kTH2F, {{100, 0, 10}, {100, -5, 5}}); - mHistogramRegistry->add((folderName + "/nSigmaComb_K").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{comb}^{K}", kTH2F, {{100, 0, 10}, {100, -5, 5}}); - mHistogramRegistry->add((folderName + "/nSigmaComb_p").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{comb}^{p}", kTH2F, {{100, 0, 10}, {100, -5, 5}}); - mHistogramRegistry->add((folderName + "/nSigmaComb_d").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{comb}^{d}", kTH2F, {{100, 0, 10}, {100, -5, 5}}); + mHistogramRegistry->add((folderName + "/hPt").c_str(), "; #it{p}_{T} (GeV/#it{c}); Entries", o2::framework::kTH1F, {{240, 0, 6}}); + mHistogramRegistry->add((folderName + "/hEta").c_str(), "; #eta; Entries", o2::framework::kTH1F, {{200, -1.5, 1.5}}); + mHistogramRegistry->add((folderName + "/hPhi").c_str(), "; #phi; Entries", o2::framework::kTH1F, {{200, 0, 2. * M_PI}}); + mHistogramRegistry->add((folderName + "/hTPCfindable").c_str(), "; TPC findable clusters; Entries", o2::framework::kTH1F, {{163, -0.5, 162.5}}); + mHistogramRegistry->add((folderName + "/hTPCfound").c_str(), "; TPC found clusters; Entries", o2::framework::kTH1F, {{163, -0.5, 162.5}}); + mHistogramRegistry->add((folderName + "/hTPCcrossedOverFindalbe").c_str(), "; TPC ratio findable; Entries", o2::framework::kTH1F, {{100, 0.5, 1.5}}); + mHistogramRegistry->add((folderName + "/hTPCcrossedRows").c_str(), "; TPC crossed rows; Entries", o2::framework::kTH1F, {{163, 0, 163}}); + mHistogramRegistry->add((folderName + "/hTPCfindableVsCrossed").c_str(), ";TPC findable clusters ; TPC crossed rows;", o2::framework::kTH2F, {{163, 0, 163}, {163, 0, 163}}); + mHistogramRegistry->add((folderName + "/hTPCshared").c_str(), "; TPC shared clusters; Entries", o2::framework::kTH1F, {{163, -0.5, 162.5}}); + mHistogramRegistry->add((folderName + "/hITSclusters").c_str(), "; ITS clusters; Entries", o2::framework::kTH1F, {{10, -0.5, 9.5}}); + mHistogramRegistry->add((folderName + "/hITSclustersIB").c_str(), "; ITS clusters in IB; Entries", o2::framework::kTH1F, {{10, -0.5, 9.5}}); + mHistogramRegistry->add((folderName + "/hDCAxy").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::kTH2F, {{100, 0, 10}, {500, -5, 5}}); + mHistogramRegistry->add((folderName + "/hDCAz").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{z} (cm)", o2::framework::kTH2F, {{100, 0, 10}, {500, -5, 5}}); + mHistogramRegistry->add((folderName + "/hDCA").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA (cm)", o2::framework::kTH2F, {{100, 0, 10}, {301, 0., 1.5}}); + mHistogramRegistry->add((folderName + "/hTPCdEdX").c_str(), "; #it{p} (GeV/#it{c}); TPC Signal", o2::framework::kTH2F, {{100, 0, 10}, {1000, 0, 1000}}); + mHistogramRegistry->add((folderName + "/nSigmaTPC_el").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TPC}^{e}", o2::framework::kTH2F, {{100, 0, 10}, {100, -5, 5}}); + mHistogramRegistry->add((folderName + "/nSigmaTPC_pi").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TPC}^{#pi}", o2::framework::kTH2F, {{100, 0, 10}, {100, -5, 5}}); + mHistogramRegistry->add((folderName + "/nSigmaTPC_K").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TPC}^{K}", o2::framework::kTH2F, {{100, 0, 10}, {100, -5, 5}}); + mHistogramRegistry->add((folderName + "/nSigmaTPC_p").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TPC}^{p}", o2::framework::kTH2F, {{100, 0, 10}, {100, -5, 5}}); + mHistogramRegistry->add((folderName + "/nSigmaTPC_d").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TPC}^{d}", o2::framework::kTH2F, {{100, 0, 10}, {100, -5, 5}}); + mHistogramRegistry->add((folderName + "/nSigmaTOF_el").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TOF}^{e}", o2::framework::kTH2F, {{100, 0, 10}, {100, -5, 5}}); + mHistogramRegistry->add((folderName + "/nSigmaTOF_pi").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TOF}^{#pi}", o2::framework::kTH2F, {{100, 0, 10}, {100, -5, 5}}); + mHistogramRegistry->add((folderName + "/nSigmaTOF_K").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TOF}^{K}", o2::framework::kTH2F, {{100, 0, 10}, {100, -5, 5}}); + mHistogramRegistry->add((folderName + "/nSigmaTOF_p").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TOF}^{p}", o2::framework::kTH2F, {{100, 0, 10}, {100, -5, 5}}); + mHistogramRegistry->add((folderName + "/nSigmaTOF_d").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TOF}^{d}", o2::framework::kTH2F, {{100, 0, 10}, {100, -5, 5}}); + mHistogramRegistry->add((folderName + "/nSigmaComb_el").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{comb}^{e}", o2::framework::kTH2F, {{100, 0, 10}, {100, -5, 5}}); + mHistogramRegistry->add((folderName + "/nSigmaComb_pi").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{comb}^{#pi}", o2::framework::kTH2F, {{100, 0, 10}, {100, -5, 5}}); + mHistogramRegistry->add((folderName + "/nSigmaComb_K").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{comb}^{K}", o2::framework::kTH2F, {{100, 0, 10}, {100, -5, 5}}); + mHistogramRegistry->add((folderName + "/nSigmaComb_p").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{comb}^{p}", o2::framework::kTH2F, {{100, 0, 10}, {100, -5, 5}}); + mHistogramRegistry->add((folderName + "/nSigmaComb_d").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{comb}^{d}", o2::framework::kTH2F, {{100, 0, 10}, {100, -5, 5}}); } /// set cuts nPtMinSel = getNSelections(femtoWorldTrackSelection::kpTMin); @@ -578,4 +582,4 @@ void FemtoWorldTrackSelection::fillQA(T const& track) } // namespace o2::analysis::femtoWorld -#endif /* FEMTOWORLDTRACKSELECTION_H_ */ +#endif // PWGCF_FEMTOWORLD_CORE_FEMTOWORLDTRACKSELECTION_H_ diff --git a/PWGCF/FemtoWorld/Core/FemtoWorldUtils.h b/PWGCF/FemtoWorld/Core/FemtoWorldUtils.h index 6f7ae6e31e3..b3f7a654ccd 100644 --- a/PWGCF/FemtoWorld/Core/FemtoWorldUtils.h +++ b/PWGCF/FemtoWorld/Core/FemtoWorldUtils.h @@ -15,13 +15,15 @@ /// \author Luca Barioglio, TU München, luca.barioglio@cern.ch /// \author Zuzanna Chochulska, WUT Warsaw, zchochul@cern.ch -#ifndef FEMTOWORLD_UTILS_H_ -#define FEMTOWORLD_UTILS_H_ +#ifndef PWGCF_FEMTOWORLD_CORE_FEMTOWORLDUTILS_H_ +#define PWGCF_FEMTOWORLD_CORE_FEMTOWORLDUTILS_H_ -#include "Framework/ASoAHelpers.h" #include "PWGCF/FemtoWorld/DataModel/FemtoWorldDerived.h" -#include +#include + +#include +#include #include namespace o2::analysis::femtoWorld @@ -100,4 +102,5 @@ bool isFullPIDSelected(aod::femtoworldparticle::cutContainerType const& pidCut, }; } // namespace o2::analysis::femtoWorld -#endif + +#endif // PWGCF_FEMTOWORLD_CORE_FEMTOWORLDUTILS_H_ diff --git a/PWGCF/FemtoWorld/Core/FemtoWorldV0Selection.h b/PWGCF/FemtoWorld/Core/FemtoWorldV0Selection.h index b86171502e8..0d1468df3d1 100644 --- a/PWGCF/FemtoWorld/Core/FemtoWorldV0Selection.h +++ b/PWGCF/FemtoWorld/Core/FemtoWorldV0Selection.h @@ -16,18 +16,27 @@ /// \author Luca Barioglio, TU München, luca.barioglio@cern.ch /// \author Zuzanna Chochulska, WUT Warsaw, zchochul@cern.ch -#ifndef FEMTOWORLDV0SELECTION_H_ -#define FEMTOWORLDV0SELECTION_H_ +#ifndef PWGCF_FEMTOWORLD_CORE_FEMTOWORLDV0SELECTION_H_ +#define PWGCF_FEMTOWORLD_CORE_FEMTOWORLDV0SELECTION_H_ #include "PWGCF/FemtoWorld/Core/FemtoWorldObjectSelection.h" -#include "PWGCF/FemtoWorld/Core/FemtoWorldTrackSelection.h" #include "PWGCF/FemtoWorld/Core/FemtoWorldSelection.h" +#include "PWGCF/FemtoWorld/Core/FemtoWorldTrackSelection.h" +#include "PWGCF/FemtoWorld/DataModel/FemtoWorldDerived.h" + +#include +#include +#include + +#include -#include "ReconstructionDataFormats/PID.h" -#include "Common/Core/RecoDecay.h" -#include "Framework/HistogramRegistry.h" +#include +#include +#include +#include +#include -using namespace o2::framework; +#include namespace o2::analysis::femtoWorld { @@ -79,10 +88,10 @@ class FemtoWorldV0Selection : public FemtoWorldObjectSelection - void init(HistogramRegistry* registry); + void init(o2::framework::HistogramRegistry* registry); template bool isSelectedMinimal(C const& col, V const& v0, T const& posTrack, T const& negTrack); @@ -253,15 +262,15 @@ class FemtoWorldV0Selection : public FemtoWorldObjectSelection -void FemtoWorldV0Selection::init(HistogramRegistry* registry) +void FemtoWorldV0Selection::init(o2::framework::HistogramRegistry* registry) { if (registry) { mHistogramRegistry = registry; fillSelectionHistogram(); fillSelectionHistogram(); - AxisSpec massAxisLambda = {600, 0.0f, 3.0f, "m_{#Lambda} (GeV/#it{c}^{2})"}; - AxisSpec massAxisAntiLambda = {600, 0.0f, 3.0f, "m_{#bar{#Lambda}} (GeV/#it{c}^{2})"}; + o2::framework::AxisSpec massAxisLambda = {600, 0.0f, 3.0f, "m_{#Lambda} (GeV/#it{c}^{2})"}; + o2::framework::AxisSpec massAxisAntiLambda = {600, 0.0f, 3.0f, "m_{#bar{#Lambda}} (GeV/#it{c}^{2})"}; /// \todo this should be an automatic check in the parent class, and the return type should be templated size_t nSelections = getNSelections(); @@ -270,32 +279,32 @@ void FemtoWorldV0Selection::init(HistogramRegistry* registry) } std::string folderName = static_cast(o2::aod::femtoworldparticle::ParticleTypeName[part]); /// \todo initialize histograms for children tracks of v0s - mHistogramRegistry->add((folderName + "/hPt").c_str(), "; #it{p}_{T} (GeV/#it{c}); Entries", kTH1F, {{1000, 0, 10}}); - mHistogramRegistry->add((folderName + "/hEta").c_str(), "; #eta; Entries", kTH1F, {{1000, -1, 1}}); - mHistogramRegistry->add((folderName + "/hPhi").c_str(), "; #phi; Entries", kTH1F, {{1000, 0, 2. * M_PI}}); - mHistogramRegistry->add((folderName + "/hDaughDCA").c_str(), "; DCA^{daugh} (cm); Entries", kTH1F, {{1000, 0, 10}}); - mHistogramRegistry->add((folderName + "/hTransRadius").c_str(), "; #it{r}_{xy} (cm); Entries", kTH1F, {{1500, 0, 150}}); - mHistogramRegistry->add((folderName + "/hDecayVtxX").c_str(), "; #it{Vtx}_{x} (cm); Entries", kTH1F, {{2000, 0, 200}}); - mHistogramRegistry->add((folderName + "/hDecayVtxY").c_str(), "; #it{Vtx}_{y} (cm)); Entries", kTH1F, {{2000, 0, 200}}); - mHistogramRegistry->add((folderName + "/hDecayVtxZ").c_str(), "; #it{Vtx}_{z} (cm); Entries", kTH1F, {{2000, 0, 200}}); - mHistogramRegistry->add((folderName + "/hCPA").c_str(), "; #it{cos #theta_{p}}; Entries", kTH1F, {{1000, 0.9, 1.}}); - mHistogramRegistry->add((folderName + "/hCPAvsPt").c_str(), "; #it{p}_{T} (GeV/#it{c}); #it{cos #theta_{p}}", kTH2F, {{8, 0.3, 4.3}, {1000, 0.9, 1.}}); - mHistogramRegistry->add((folderName + "/hInvMassLambda").c_str(), "", kTH1F, {massAxisLambda}); - mHistogramRegistry->add((folderName + "/hInvMassAntiLambda").c_str(), "", kTH1F, {massAxisAntiLambda}); - mHistogramRegistry->add((folderName + "/hInvMassLambdaAntiLambda").c_str(), "", kTH2F, {massAxisLambda, massAxisAntiLambda}); + mHistogramRegistry->add((folderName + "/hPt").c_str(), "; #it{p}_{T} (GeV/#it{c}); Entries", o2::framework::kTH1F, {{1000, 0, 10}}); + mHistogramRegistry->add((folderName + "/hEta").c_str(), "; #eta; Entries", o2::framework::kTH1F, {{1000, -1, 1}}); + mHistogramRegistry->add((folderName + "/hPhi").c_str(), "; #phi; Entries", o2::framework::kTH1F, {{1000, 0, 2. * M_PI}}); + mHistogramRegistry->add((folderName + "/hDaughDCA").c_str(), "; DCA^{daugh} (cm); Entries", o2::framework::kTH1F, {{1000, 0, 10}}); + mHistogramRegistry->add((folderName + "/hTransRadius").c_str(), "; #it{r}_{xy} (cm); Entries", o2::framework::kTH1F, {{1500, 0, 150}}); + mHistogramRegistry->add((folderName + "/hDecayVtxX").c_str(), "; #it{Vtx}_{x} (cm); Entries", o2::framework::kTH1F, {{2000, 0, 200}}); + mHistogramRegistry->add((folderName + "/hDecayVtxY").c_str(), "; #it{Vtx}_{y} (cm)); Entries", o2::framework::kTH1F, {{2000, 0, 200}}); + mHistogramRegistry->add((folderName + "/hDecayVtxZ").c_str(), "; #it{Vtx}_{z} (cm); Entries", o2::framework::kTH1F, {{2000, 0, 200}}); + mHistogramRegistry->add((folderName + "/hCPA").c_str(), "; #it{cos #theta_{p}}; Entries", o2::framework::kTH1F, {{1000, 0.9, 1.}}); + mHistogramRegistry->add((folderName + "/hCPAvsPt").c_str(), "; #it{p}_{T} (GeV/#it{c}); #it{cos #theta_{p}}", o2::framework::kTH2F, {{8, 0.3, 4.3}, {1000, 0.9, 1.}}); + mHistogramRegistry->add((folderName + "/hInvMassLambda").c_str(), "", o2::framework::kTH1F, {massAxisLambda}); + mHistogramRegistry->add((folderName + "/hInvMassAntiLambda").c_str(), "", o2::framework::kTH1F, {massAxisAntiLambda}); + mHistogramRegistry->add((folderName + "/hInvMassLambdaAntiLambda").c_str(), "", o2::framework::kTH2F, {massAxisLambda, massAxisAntiLambda}); PosDaughTrack.init(mHistogramRegistry); NegDaughTrack.init(mHistogramRegistry); - mHistogramRegistry->add("LambdaQA/hInvMassLambdaNoCuts", "No cuts", kTH1F, {massAxisLambda}); - mHistogramRegistry->add("LambdaQA/hInvMassLambdaInvMassCut", "Invariant mass cut", kTH1F, {massAxisLambda}); - mHistogramRegistry->add("LambdaQA/hInvMassLambdaPtMin", "Minimum Pt cut", kTH1F, {massAxisLambda}); - mHistogramRegistry->add("LambdaQA/hInvMassLambdaPtMax", "Maximum Pt cut", kTH1F, {massAxisLambda}); - mHistogramRegistry->add("LambdaQA/hInvMassLambdaDCAV0Daugh", "V0-daughters DCA cut", kTH1F, {massAxisLambda}); - mHistogramRegistry->add("LambdaQA/hInvMassLambdaCPA", "CPA cut", kTH1F, {massAxisLambda}); - mHistogramRegistry->add("LambdaQA/hInvMassLambdaTranRadMin", "Minimum transverse radius cut", kTH1F, {massAxisLambda}); - mHistogramRegistry->add("LambdaQA/hInvMassLambdaTranRadMax", "Maximum transverse radius cut", kTH1F, {massAxisLambda}); - mHistogramRegistry->add("LambdaQA/hInvMassLambdaDecVtxMax", "Maximum distance on decay vertex cut", kTH1F, {massAxisLambda}); + mHistogramRegistry->add("LambdaQA/hInvMassLambdaNoCuts", "No cuts", o2::framework::kTH1F, {massAxisLambda}); + mHistogramRegistry->add("LambdaQA/hInvMassLambdaInvMassCut", "Invariant mass cut", o2::framework::kTH1F, {massAxisLambda}); + mHistogramRegistry->add("LambdaQA/hInvMassLambdaPtMin", "Minimum Pt cut", o2::framework::kTH1F, {massAxisLambda}); + mHistogramRegistry->add("LambdaQA/hInvMassLambdaPtMax", "Maximum Pt cut", o2::framework::kTH1F, {massAxisLambda}); + mHistogramRegistry->add("LambdaQA/hInvMassLambdaDCAV0Daugh", "V0-daughters DCA cut", o2::framework::kTH1F, {massAxisLambda}); + mHistogramRegistry->add("LambdaQA/hInvMassLambdaCPA", "CPA cut", o2::framework::kTH1F, {massAxisLambda}); + mHistogramRegistry->add("LambdaQA/hInvMassLambdaTranRadMin", "Minimum transverse radius cut", o2::framework::kTH1F, {massAxisLambda}); + mHistogramRegistry->add("LambdaQA/hInvMassLambdaTranRadMax", "Maximum transverse radius cut", o2::framework::kTH1F, {massAxisLambda}); + mHistogramRegistry->add("LambdaQA/hInvMassLambdaDecVtxMax", "Maximum distance on decay vertex cut", o2::framework::kTH1F, {massAxisLambda}); } /// check whether the most open cuts are fulfilled - most of this should have already be done by the filters nPtV0MinSel = getNSelections(femtoWorldV0Selection::kpTV0Min); @@ -544,4 +553,4 @@ void FemtoWorldV0Selection::fillQA(C const& /*col*/, V const& v0, T const& posTr } // namespace o2::analysis::femtoWorld -#endif /* FEMTOWORLDV0SELECTION_H_ */ +#endif // PWGCF_FEMTOWORLD_CORE_FEMTOWORLDV0SELECTION_H_ diff --git a/PWGCF/FemtoWorld/DataModel/FemtoWorldDerived.h b/PWGCF/FemtoWorld/DataModel/FemtoWorldDerived.h index 923729d7e84..317dbc75c61 100644 --- a/PWGCF/FemtoWorld/DataModel/FemtoWorldDerived.h +++ b/PWGCF/FemtoWorld/DataModel/FemtoWorldDerived.h @@ -12,19 +12,17 @@ #ifndef PWGCF_FEMTOWORLD_DATAMODEL_FEMTOWORLDDERIVED_H_ #define PWGCF_FEMTOWORLD_DATAMODEL_FEMTOWORLDDERIVED_H_ -#include "Common/DataModel/Centrality.h" -#include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponseTOF.h" #include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "Framework/ASoA.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/DataTypes.h" -#include "Framework/Expressions.h" -#include "MathUtils/Utils.h" +#include +#include +#include #include +#include +#include namespace o2::aod { diff --git a/PWGCF/FemtoWorld/TableProducer/femtoWorldProducerReducedTask.cxx b/PWGCF/FemtoWorld/TableProducer/femtoWorldProducerReducedTask.cxx index ffdeb15c7b2..28ef5d0ea9e 100644 --- a/PWGCF/FemtoWorld/TableProducer/femtoWorldProducerReducedTask.cxx +++ b/PWGCF/FemtoWorld/TableProducer/femtoWorldProducerReducedTask.cxx @@ -25,17 +25,17 @@ #include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "DataFormatsParameters/GRPObject.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/runDataProcessing.h" -#include "ReconstructionDataFormats/Track.h" #include - -#include "Math/Vector4D.h" -#include "TMath.h" +#include +#include +#include +#include +#include +#include +#include + +#include +#include using namespace o2; using namespace o2::analysis::femtoWorld; diff --git a/PWGCF/FemtoWorld/TableProducer/femtoWorldProducerTask.cxx b/PWGCF/FemtoWorld/TableProducer/femtoWorldProducerTask.cxx index ab3f7e66d96..6547189a8eb 100644 --- a/PWGCF/FemtoWorld/TableProducer/femtoWorldProducerTask.cxx +++ b/PWGCF/FemtoWorld/TableProducer/femtoWorldProducerTask.cxx @@ -14,18 +14,23 @@ /// \author Andi Mathis, TU München, andreas.mathis@ph.tum.de /// \author Zuzanna Chochulska, WUT Warsaw, zchochul@cern.ch +#include "TrackSelection.h" +#include "TrackSelectionDefaults.h" + #include "PWGCF/FemtoWorld/Core/FemtoWorldCollisionSelection.h" -#include "PWGCF/FemtoWorld/Core/FemtoWorldPairCleaner.h" #include "PWGCF/FemtoWorld/Core/FemtoWorldPhiSelection.h" +#include "PWGCF/FemtoWorld/Core/FemtoWorldSelection.h" #include "PWGCF/FemtoWorld/Core/FemtoWorldTrackSelection.h" #include "PWGCF/FemtoWorld/Core/FemtoWorldV0Selection.h" #include "PWGCF/FemtoWorld/DataModel/FemtoWorldDerived.h" #include "PWGHF/Core/HfHelper.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" +#include "PWGHF/DataModel/TrackIndexSkimmingTables.h" #include "PWGLF/DataModel/LFStrangenessTables.h" -#include "Common/Core/trackUtilities.h" +#include "Common/CCDB/TriggerAliases.h" +#include "Common/Core/RecoDecay.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" @@ -33,20 +38,33 @@ #include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "CCDB/BasicCCDBManager.h" -#include "DataFormatsParameters/GRPMagField.h" -#include "DataFormatsParameters/GRPObject.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/runDataProcessing.h" -#include "ReconstructionDataFormats/Track.h" - -#include "Math/Vector4D.h" -#include "TLorentzVector.h" -#include "TMath.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + #include // FIXME +#include +#include +#include + +#include +#include +#include +#include +#include +#include using namespace o2; using namespace o2::analysis::femtoWorld; diff --git a/PWGCF/FemtoWorld/TableProducer/femtoWorldProducerTaskV0Only.cxx b/PWGCF/FemtoWorld/TableProducer/femtoWorldProducerTaskV0Only.cxx index b46aa32a312..091afad61ba 100644 --- a/PWGCF/FemtoWorld/TableProducer/femtoWorldProducerTaskV0Only.cxx +++ b/PWGCF/FemtoWorld/TableProducer/femtoWorldProducerTaskV0Only.cxx @@ -26,17 +26,17 @@ #include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "DataFormatsParameters/GRPObject.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/runDataProcessing.h" -#include "ReconstructionDataFormats/Track.h" #include - -#include "Math/Vector4D.h" -#include "TMath.h" +#include +#include +#include +#include +#include +#include +#include + +#include +#include using namespace o2; using namespace o2::analysis::femtoWorld; diff --git a/PWGCF/FemtoWorld/Tasks/femtoWorldEfficiencyTask.cxx b/PWGCF/FemtoWorld/Tasks/femtoWorldEfficiencyTask.cxx index 12bc5b3ad32..47a20b5be86 100644 --- a/PWGCF/FemtoWorld/Tasks/femtoWorldEfficiencyTask.cxx +++ b/PWGCF/FemtoWorld/Tasks/femtoWorldEfficiencyTask.cxx @@ -15,26 +15,31 @@ /// \author Alicja Plachta, WUT Warsaw, alicja.plachta@cern.ch /// \author Barbara Chytla, WUT Warsaw, barbara.chytla@cern.ch -// O2 includes #include "PWGCF/FemtoWorld/Core/FemtoWorldCollisionSelection.h" -#include "PWGCF/FemtoWorld/DataModel/FemtoWorldDerived.h" -#include "PWGLF/DataModel/LFResonanceTables.h" -#include "Common/Core/trackUtilities.h" +#include "Common/CCDB/TriggerAliases.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponseTOF.h" #include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "Framework/runDataProcessing.h" -#include "ReconstructionDataFormats/Track.h" - -#include "TPDGCode.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include using namespace o2; using namespace o2::analysis::femtoWorld; diff --git a/PWGCF/FemtoWorld/Tasks/femtoWorldEfficiencyTaskDe.cxx b/PWGCF/FemtoWorld/Tasks/femtoWorldEfficiencyTaskDe.cxx index 6c7a97c1f5b..ff4f49f0c33 100644 --- a/PWGCF/FemtoWorld/Tasks/femtoWorldEfficiencyTaskDe.cxx +++ b/PWGCF/FemtoWorld/Tasks/femtoWorldEfficiencyTaskDe.cxx @@ -15,25 +15,31 @@ /// \author Alicja Plachta, WUT Warsaw, alicja.plachta@cern.ch /// \author Barbara Chytla, WUT Warsaw, barbara.chytla@cern.ch -// O2 includes #include "PWGCF/FemtoWorld/Core/FemtoWorldCollisionSelection.h" -#include "PWGLF/DataModel/LFResonanceTables.h" -#include "Common/Core/trackUtilities.h" +#include "Common/CCDB/TriggerAliases.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponseTOF.h" #include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "Framework/runDataProcessing.h" -#include "ReconstructionDataFormats/Track.h" - -#include "TPDGCode.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include using namespace o2; using namespace o2::analysis::femtoWorld; diff --git a/PWGCF/FemtoWorld/Tasks/femtoWorldPairTaskPionPion.cxx b/PWGCF/FemtoWorld/Tasks/femtoWorldPairTaskPionPion.cxx index a2d061ed1f4..c3c0d0a9dcb 100644 --- a/PWGCF/FemtoWorld/Tasks/femtoWorldPairTaskPionPion.cxx +++ b/PWGCF/FemtoWorld/Tasks/femtoWorldPairTaskPionPion.cxx @@ -15,20 +15,34 @@ /// \author Zuzanna Chochulska, WUT Warsaw, zchochul@cern.ch /// \author Alicja Plachta, WUT Warsaw -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/StepTHn.h" - -#include "PWGCF/FemtoWorld/DataModel/FemtoWorldDerived.h" -#include "PWGCF/FemtoWorld/Core/FemtoWorldParticleHisto.h" +#include "PWGCF/FemtoWorld/Core/FemtoWorldDetaDphiStar.h" #include "PWGCF/FemtoWorld/Core/FemtoWorldEventHisto.h" #include "PWGCF/FemtoWorld/Core/FemtoWorldPairCleaner.h" +#include "PWGCF/FemtoWorld/Core/FemtoWorldParticleHisto.h" #include "PWGCF/FemtoWorld/Core/FemtoWorldPionContainer.h" -#include "PWGCF/FemtoWorld/Core/FemtoWorldDetaDphiStar.h" -#include "PWGCF/FemtoWorld/Core/FemtoWorldUtils.h" +#include "PWGCF/FemtoWorld/DataModel/FemtoWorldDerived.h" + +#include "Common/DataModel/TrackSelectionTables.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include using namespace o2; using namespace o2::analysis::femtoWorld; diff --git a/PWGCF/FemtoWorld/Tasks/femtoWorldPairTaskProtonAntiproton.cxx b/PWGCF/FemtoWorld/Tasks/femtoWorldPairTaskProtonAntiproton.cxx index 066307a91d4..6ded175155f 100644 --- a/PWGCF/FemtoWorld/Tasks/femtoWorldPairTaskProtonAntiproton.cxx +++ b/PWGCF/FemtoWorld/Tasks/femtoWorldPairTaskProtonAntiproton.cxx @@ -15,20 +15,34 @@ /// \author Zuzanna Chochulska, WUT Warsaw, zchochul@cern.ch /// \author Barbara Chytła, WUT Warsaw, barbara.chytla.stud@pw.edu.pl -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/StepTHn.h" - -#include "PWGCF/FemtoWorld/DataModel/FemtoWorldDerived.h" -#include "PWGCF/FemtoWorld/Core/FemtoWorldParticleHisto.h" -#include "PWGCF/FemtoWorld/Core/FemtoWorldEventHisto.h" -#include "PWGCF/FemtoWorld/Core/FemtoWorldPairCleaner.h" #include "PWGCF/FemtoWorld/Core/FemtoWorldContainer.h" #include "PWGCF/FemtoWorld/Core/FemtoWorldDetaDphiStar.h" -#include "PWGCF/FemtoWorld/Core/FemtoWorldUtils.h" +#include "PWGCF/FemtoWorld/Core/FemtoWorldEventHisto.h" +#include "PWGCF/FemtoWorld/Core/FemtoWorldPairCleaner.h" +#include "PWGCF/FemtoWorld/Core/FemtoWorldParticleHisto.h" +#include "PWGCF/FemtoWorld/DataModel/FemtoWorldDerived.h" + +#include "Common/DataModel/TrackSelectionTables.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include using namespace o2; using namespace o2::analysis::femtoWorld; diff --git a/PWGCF/FemtoWorld/Tasks/femtoWorldPairTaskTrackD0.cxx b/PWGCF/FemtoWorld/Tasks/femtoWorldPairTaskTrackD0.cxx index 8f1452c1c49..5ca9109e6e7 100644 --- a/PWGCF/FemtoWorld/Tasks/femtoWorldPairTaskTrackD0.cxx +++ b/PWGCF/FemtoWorld/Tasks/femtoWorldPairTaskTrackD0.cxx @@ -14,23 +14,37 @@ /// \author Andi Mathis, TU München, andreas.mathis@ph.tum.de /// \author Zuzanna Chochulska, WUT Warsaw, zchochul@cern.ch -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/StepTHn.h" - -#include "PWGCF/FemtoWorld/DataModel/FemtoWorldDerived.h" -#include "PWGCF/FemtoWorld/Core/FemtoWorldParticleHisto.h" -#include "PWGCF/FemtoWorld/Core/FemtoWorldEventHisto.h" -#include "PWGCF/FemtoWorld/Core/FemtoWorldPairCleaner.h" #include "PWGCF/FemtoWorld/Core/FemtoWorldContainer.h" #include "PWGCF/FemtoWorld/Core/FemtoWorldDetaDphiStar.h" -#include "PWGCF/FemtoWorld/Core/FemtoWorldUtils.h" +#include "PWGCF/FemtoWorld/Core/FemtoWorldEventHisto.h" +#include "PWGCF/FemtoWorld/Core/FemtoWorldPairCleaner.h" +#include "PWGCF/FemtoWorld/Core/FemtoWorldParticleHisto.h" +#include "PWGCF/FemtoWorld/DataModel/FemtoWorldDerived.h" -#include "PWGHF/DataModel/CandidateReconstructionTables.h" -#include "PWGHF/DataModel/CandidateSelectionTables.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include using namespace o2; using namespace o2::analysis::femtoWorld; diff --git a/PWGCF/FemtoWorld/Tasks/femtoWorldPairTaskTrackPhi.cxx b/PWGCF/FemtoWorld/Tasks/femtoWorldPairTaskTrackPhi.cxx index e5201b379d5..426ca4af935 100644 --- a/PWGCF/FemtoWorld/Tasks/femtoWorldPairTaskTrackPhi.cxx +++ b/PWGCF/FemtoWorld/Tasks/femtoWorldPairTaskTrackPhi.cxx @@ -14,20 +14,36 @@ /// \author Andi Mathis, TU München, andreas.mathis@ph.tum.de /// \author Zuzanna Chochulska, WUT Warsaw, zchochul@cern.ch -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/StepTHn.h" - -#include "PWGCF/FemtoWorld/DataModel/FemtoWorldDerived.h" -#include "PWGCF/FemtoWorld/Core/FemtoWorldParticleHisto.h" -#include "PWGCF/FemtoWorld/Core/FemtoWorldEventHisto.h" -#include "PWGCF/FemtoWorld/Core/FemtoWorldPairCleaner.h" #include "PWGCF/FemtoWorld/Core/FemtoWorldContainer.h" #include "PWGCF/FemtoWorld/Core/FemtoWorldDetaDphiStar.h" -#include "PWGCF/FemtoWorld/Core/FemtoWorldUtils.h" +#include "PWGCF/FemtoWorld/Core/FemtoWorldEventHisto.h" +#include "PWGCF/FemtoWorld/Core/FemtoWorldPairCleaner.h" +#include "PWGCF/FemtoWorld/Core/FemtoWorldParticleHisto.h" +#include "PWGCF/FemtoWorld/DataModel/FemtoWorldDerived.h" + +#include "Common/DataModel/TrackSelectionTables.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include using namespace o2; using namespace o2::analysis::femtoWorld; diff --git a/PWGCF/FemtoWorld/Tasks/femtoWorldPairTaskTrackTrack.cxx b/PWGCF/FemtoWorld/Tasks/femtoWorldPairTaskTrackTrack.cxx index 4037bd991e0..1711a4fdc48 100644 --- a/PWGCF/FemtoWorld/Tasks/femtoWorldPairTaskTrackTrack.cxx +++ b/PWGCF/FemtoWorld/Tasks/femtoWorldPairTaskTrackTrack.cxx @@ -14,20 +14,34 @@ /// \author Andi Mathis, TU München, andreas.mathis@ph.tum.de /// \author Zuzanna Chochulska, WUT Warsaw, zchochul@cern.ch -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/StepTHn.h" - -#include "PWGCF/FemtoWorld/DataModel/FemtoWorldDerived.h" -#include "PWGCF/FemtoWorld/Core/FemtoWorldParticleHisto.h" -#include "PWGCF/FemtoWorld/Core/FemtoWorldEventHisto.h" -#include "PWGCF/FemtoWorld/Core/FemtoWorldPairCleaner.h" #include "PWGCF/FemtoWorld/Core/FemtoWorldContainer.h" #include "PWGCF/FemtoWorld/Core/FemtoWorldDetaDphiStar.h" -#include "PWGCF/FemtoWorld/Core/FemtoWorldUtils.h" +#include "PWGCF/FemtoWorld/Core/FemtoWorldEventHisto.h" +#include "PWGCF/FemtoWorld/Core/FemtoWorldPairCleaner.h" +#include "PWGCF/FemtoWorld/Core/FemtoWorldParticleHisto.h" +#include "PWGCF/FemtoWorld/DataModel/FemtoWorldDerived.h" + +#include "Common/DataModel/TrackSelectionTables.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include using namespace o2; using namespace o2::analysis::femtoWorld; diff --git a/PWGCF/FemtoWorld/Tasks/femtoWorldPionAllPairTask.cxx b/PWGCF/FemtoWorld/Tasks/femtoWorldPionAllPairTask.cxx index 44278d89471..248225ecd46 100644 --- a/PWGCF/FemtoWorld/Tasks/femtoWorldPionAllPairTask.cxx +++ b/PWGCF/FemtoWorld/Tasks/femtoWorldPionAllPairTask.cxx @@ -15,23 +15,37 @@ /// \author Zuzanna Chochulska, WUT Warsaw, zchochul@cern.ch /// \author Deependra Sharma, IITB, deependra.sharma@cern.ch -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/StepTHn.h" -#include "TDatabasePDG.h" - -#include "PWGCF/FemtoWorld/DataModel/FemtoWorldDerived.h" -#include "PWGCF/FemtoWorld/Core/FemtoWorldParticleHisto.h" -#include "PWGCF/FemtoWorld/Core/FemtoWorldEventHisto.h" -#include "PWGCF/FemtoWorld/Core/FemtoWorldPairCleaner.h" #include "PWGCF/FemtoWorld/Core/FemtoWorldContainer.h" #include "PWGCF/FemtoWorld/Core/FemtoWorldDetaDphiStar.h" -#include "PWGCF/FemtoWorld/Core/FemtoWorldUtils.h" +#include "PWGCF/FemtoWorld/Core/FemtoWorldEventHisto.h" #include "PWGCF/FemtoWorld/Core/FemtoWorldMath.h" +#include "PWGCF/FemtoWorld/Core/FemtoWorldPairCleaner.h" #include "PWGCF/FemtoWorld/Core/FemtoWorldPairWithCentrality.h" +#include "PWGCF/FemtoWorld/Core/FemtoWorldParticleHisto.h" +#include "PWGCF/FemtoWorld/DataModel/FemtoWorldDerived.h" + +#include "Common/DataModel/TrackSelectionTables.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include using namespace o2; using namespace o2::analysis::femtoWorld; diff --git a/PWGCF/FemtoWorld/Tasks/femtoWorldPionPairTaskTrackTrack.cxx b/PWGCF/FemtoWorld/Tasks/femtoWorldPionPairTaskTrackTrack.cxx index 9d83c1ca3ec..fdedf6e0870 100644 --- a/PWGCF/FemtoWorld/Tasks/femtoWorldPionPairTaskTrackTrack.cxx +++ b/PWGCF/FemtoWorld/Tasks/femtoWorldPionPairTaskTrackTrack.cxx @@ -15,20 +15,34 @@ /// \author Zuzanna Chochulska, WUT Warsaw, zchochul@cern.ch /// \author Deependra Sharma, IITB, deependra.sharma@cern.ch -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/StepTHn.h" - -#include "PWGCF/FemtoWorld/DataModel/FemtoWorldDerived.h" -#include "PWGCF/FemtoWorld/Core/FemtoWorldParticleHisto.h" -#include "PWGCF/FemtoWorld/Core/FemtoWorldEventHisto.h" -#include "PWGCF/FemtoWorld/Core/FemtoWorldPairCleaner.h" #include "PWGCF/FemtoWorld/Core/FemtoWorldContainer.h" #include "PWGCF/FemtoWorld/Core/FemtoWorldDetaDphiStar.h" -#include "PWGCF/FemtoWorld/Core/FemtoWorldUtils.h" +#include "PWGCF/FemtoWorld/Core/FemtoWorldEventHisto.h" +#include "PWGCF/FemtoWorld/Core/FemtoWorldPairCleaner.h" +#include "PWGCF/FemtoWorld/Core/FemtoWorldParticleHisto.h" +#include "PWGCF/FemtoWorld/DataModel/FemtoWorldDerived.h" + +#include "Common/DataModel/TrackSelectionTables.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include using namespace o2; using namespace o2::analysis::femtoWorld; diff --git a/PWGCF/Flow/TableProducer/zdcQVectors.cxx b/PWGCF/Flow/TableProducer/zdcQVectors.cxx index 9adde113460..6601815d240 100644 --- a/PWGCF/Flow/TableProducer/zdcQVectors.cxx +++ b/PWGCF/Flow/TableProducer/zdcQVectors.cxx @@ -14,47 +14,43 @@ /// \since 11/2024 /// \brief In this task the energy calibration and recentring of Q-vectors constructed in the ZDCs will be done -#include -#include -#include -#include -#include -#include -#include -#include +#include "PWGCF/DataModel/SPTableZDC.h" -#include "CCDB/BasicCCDBManager.h" #include "Common/CCDB/EventSelectionParams.h" -#include "Common/CCDB/TriggerAliases.h" -#include "Common/Core/TrackSelection.h" -#include "Common/DataModel/TrackSelectionTables.h" +#include "Common/CCDB/RCTSelectionFlags.h" #include "Common/DataModel/Centrality.h" -#include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/EventSelection.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/runDataProcessing.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/StaticFor.h" - -#include "DataFormatsParameters/GRPObject.h" -#include "DataFormatsParameters/GRPMagField.h" -#include "ReconstructionDataFormats/GlobalTrackID.h" -#include "ReconstructionDataFormats/Track.h" -#include "PWGCF/DataModel/SPTableZDC.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include -#include "TH1F.h" -#include "TH2F.h" -#include "TProfile.h" -#include "TObjArray.h" -#include "TF1.h" -#include "TFitResult.h" -#include "TCanvas.h" -#include "TSystem.h" -#include "TROOT.h" +#include #define O2_DEFINE_CONFIGURABLE(NAME, TYPE, DEFAULT, HELP) Configurable NAME{#NAME, DEFAULT, HELP}; @@ -83,7 +79,7 @@ std::vector pyZDC = {-1.75, -1.75, 1.75, 1.75}; double alphaZDC = 0.395; // q-vectors before (q) and after (qRec) recentering. -std::vector q(4); // start values of [QxA, QyA, QxC, QyC] +std::vector q(4); // start values of [QxA, QyA, QxC, QyC] std::vector qNoEq(4); // start values of [QxA, QyA, QxC, QyC] // for energy calibration diff --git a/PWGCF/Flow/Tasks/flowAnalysisGF.cxx b/PWGCF/Flow/Tasks/flowAnalysisGF.cxx index 08e223befb6..3eb239c4f5a 100644 --- a/PWGCF/Flow/Tasks/flowAnalysisGF.cxx +++ b/PWGCF/Flow/Tasks/flowAnalysisGF.cxx @@ -9,42 +9,61 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#include -#include -#include -#include -#include -#include - -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/HistogramRegistry.h" - -#include "Common/DataModel/EventSelection.h" -#include "Common/Core/TrackSelection.h" -#include "Common/DataModel/TrackSelectionTables.h" -#include "Common/DataModel/Multiplicity.h" -#include "Common/DataModel/Centrality.h" - -#include "GFWPowerArray.h" -#include "GFW.h" -#include "GFWCumulant.h" #include "FlowContainer.h" #include "FlowPtContainer.h" +#include "GFW.h" #include "GFWConfig.h" #include "GFWWeights.h" + +#include "Common/CCDB/EventSelectionParams.h" +#include "Common/CCDB/TriggerAliases.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include #include #include -#include +#include + +#include + +#include + +#include +#include +#include +#include +#include using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; using namespace o2::analysis; +using namespace o2::analysis::genericframework; #define O2_DEFINE_CONFIGURABLE(NAME, TYPE, DEFAULT, HELP) Configurable NAME{#NAME, DEFAULT, HELP}; + namespace o2::analysis::flowanalysis { std::vector ptbinning = { @@ -719,7 +738,7 @@ struct flowAnalysisGF { } Filter collisionFilter = nabs(aod::collision::posZ) < cfgVtxZ; - Filter trackFilter = nabs(aod::track::eta) < cfgEta && aod::track::pt > cfgPtmin&& aod::track::pt < cfgPtmax && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true)) && nabs(aod::track::dcaXY) < cfgDCAxy&& nabs(aod::track::dcaZ) < cfgDCAz; + Filter trackFilter = nabs(aod::track::eta) < cfgEta && aod::track::pt > cfgPtmin&& aod::track::pt < cfgPtmax && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t)true)) && nabs(aod::track::dcaXY) < cfgDCAxy&& nabs(aod::track::dcaZ) < cfgDCAz; using myTracks = soa::Filtered>; diff --git a/PWGCF/Flow/Tasks/flowEfficiencyCasc.cxx b/PWGCF/Flow/Tasks/flowEfficiencyCasc.cxx index 7a6c8a285a7..246e811614f 100644 --- a/PWGCF/Flow/Tasks/flowEfficiencyCasc.cxx +++ b/PWGCF/Flow/Tasks/flowEfficiencyCasc.cxx @@ -16,22 +16,23 @@ #include "PWGLF/DataModel/LFStrangenessPIDTables.h" #include "PWGLF/DataModel/LFStrangenessTables.h" -#include "PWGLF/DataModel/cascqaanalysis.h" -#include "Common/Core/TrackSelection.h" -#include "Common/Core/TrackSelectionDefaults.h" -#include "Common/DataModel/Centrality.h" -#include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/Multiplicity.h" -#include "Common/DataModel/TrackSelectionTables.h" +#include "Common/CCDB/EventSelectionParams.h" +#include "Common/CCDB/TriggerAliases.h" -#include "CommonConstants/PhysicsConstants.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" +#include +#include +#include +#include +#include +#include +#include +#include #include +#include +#include #include using namespace o2; diff --git a/PWGCF/Flow/Tasks/flowEsePHe3.cxx b/PWGCF/Flow/Tasks/flowEsePHe3.cxx index ea203a1b4a2..6e90802ef9d 100644 --- a/PWGCF/Flow/Tasks/flowEsePHe3.cxx +++ b/PWGCF/Flow/Tasks/flowEsePHe3.cxx @@ -12,25 +12,9 @@ /// \author ZhengqingWang(zhengqing.wang@cern.ch) /// \file flowEsePHe3.cxx /// \brief task to calculate the P He3 flow correlation. -// C++/ROOT includes. -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -// o2Physics includes. +#include "Common/CCDB/EventSelectionParams.h" #include "Common/Core/EventPlaneHelper.h" -#include "Common/Core/TrackSelection.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" @@ -40,16 +24,34 @@ #include "Common/DataModel/Qvectors.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "CommonConstants/PhysicsConstants.h" -#include "MathUtils/BetheBlochAleph.h" -#include "Framework/ASoA.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/StaticFor.h" -#include "Framework/runDataProcessing.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include using namespace o2; using namespace o2::framework; diff --git a/PWGCF/Flow/Tasks/flowEseTask.cxx b/PWGCF/Flow/Tasks/flowEseTask.cxx index cdb4ee3147d..d14ad602849 100644 --- a/PWGCF/Flow/Tasks/flowEseTask.cxx +++ b/PWGCF/Flow/Tasks/flowEseTask.cxx @@ -18,44 +18,44 @@ #include "PWGLF/DataModel/LFStrangenessTables.h" #include "PWGMM/Mult/DataModel/Index.h" // for Particles2Tracks table +#include "Common/CCDB/EventSelectionParams.h" #include "Common/Core/EventPlaneHelper.h" #include "Common/Core/RecoDecay.h" -#include "Common/Core/TrackSelection.h" -#include "Common/Core/trackUtilities.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" -#include "Common/DataModel/PIDResponseITS.h" #include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/Qvectors.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "CCDB/BasicCCDBManager.h" -#include "CCDB/CcdbApi.h" -#include "CommonConstants/PhysicsConstants.h" -#include "DataFormatsParameters/GRPMagField.h" -#include "DataFormatsParameters/GRPObject.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "Framework/StaticFor.h" -#include "Framework/StepTHn.h" -#include "Framework/runDataProcessing.h" -#include "ReconstructionDataFormats/Track.h" - -#include "Math/GenVector/Boost.h" -#include "Math/Vector3D.h" -#include "Math/Vector4D.h" -#include "TF1.h" -#include "TRandom3.h" -#include "TVector2.h" -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include // IWYU pragma: keep (do not replace with Math/Vector4Dfwd.h) +#include +#include +#include +#include +#include +#include +#include #include #include #include +#include #include #include #include diff --git a/PWGCF/Flow/Tasks/flowEventPlane.cxx b/PWGCF/Flow/Tasks/flowEventPlane.cxx index ea895bc8232..d710a4350a8 100644 --- a/PWGCF/Flow/Tasks/flowEventPlane.cxx +++ b/PWGCF/Flow/Tasks/flowEventPlane.cxx @@ -15,6 +15,7 @@ #include "PWGLF/DataModel/LFStrangenessTables.h" +#include "Common/CCDB/EventSelectionParams.h" #include "Common/Core/RecoDecay.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/CollisionAssociationTables.h" @@ -24,15 +25,32 @@ #include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "CCDB/BasicCCDBManager.h" -#include "CommonConstants/PhysicsConstants.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include #include +#include #include #include +#include #include using namespace o2; diff --git a/PWGCF/Flow/Tasks/flowGfwEse.cxx b/PWGCF/Flow/Tasks/flowGfwEse.cxx index 15a2cf24473..133a9ac0573 100644 --- a/PWGCF/Flow/Tasks/flowGfwEse.cxx +++ b/PWGCF/Flow/Tasks/flowGfwEse.cxx @@ -17,12 +17,10 @@ #include "FlowPtContainer.h" #include "GFW.h" #include "GFWConfig.h" -#include "GFWCumulant.h" -#include "GFWPowerArray.h" #include "GFWWeights.h" -#include "GFWWeightsList.h" -#include "Common/Core/TrackSelection.h" +#include "Common/CCDB/EventSelectionParams.h" +#include "Common/CCDB/TriggerAliases.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EseTable.h" #include "Common/DataModel/EventSelection.h" @@ -30,31 +28,52 @@ #include "Common/DataModel/Qvectors.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/runDataProcessing.h" #include +#include #include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include +#include +#include +#include #include #include #include +#include + +#include + +#include #include +#include +#include #include +#include +#include #include +#include #include -#include +#include #include +#include #include #include using namespace o2; using namespace o2::framework; +using namespace o2::analysis::genericframework; #define O2_DEFINE_CONFIGURABLE(NAME, TYPE, DEFAULT, HELP) Configurable NAME{#NAME, DEFAULT, HELP}; diff --git a/PWGCF/Flow/Tasks/flowGfwOmegaXi.cxx b/PWGCF/Flow/Tasks/flowGfwOmegaXi.cxx index 4b41fbbb893..20f58de9380 100644 --- a/PWGCF/Flow/Tasks/flowGfwOmegaXi.cxx +++ b/PWGCF/Flow/Tasks/flowGfwOmegaXi.cxx @@ -15,48 +15,58 @@ /// \brief This task is to caculate V0s and cascades flow by GenericFramework #include "GFW.h" -#include "GFWCumulant.h" -#include "GFWPowerArray.h" #include "GFWWeights.h" #include "PWGLF/DataModel/LFStrangenessPIDTables.h" #include "PWGLF/DataModel/LFStrangenessTables.h" #include "PWGMM/Mult/DataModel/Index.h" +#include "Common/CCDB/EventSelectionParams.h" +#include "Common/CCDB/TriggerAliases.h" #include "Common/CCDB/ctpRateFetcher.h" -#include "Common/Core/EventPlaneHelper.h" -#include "Common/Core/TrackSelection.h" -#include "Common/Core/trackUtilities.h" +#include "Common/Core/RecoDecay.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponseITS.h" #include "Common/DataModel/PIDResponseTOF.h" #include "Common/DataModel/PIDResponseTPC.h" -#include "Common/DataModel/Qvectors.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "CommonConstants/PhysicsConstants.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/runDataProcessing.h" -#include "ReconstructionDataFormats/Track.h" #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include -#include "TList.h" #include -#include +#include +#include +#include #include #include +#include #include +#include +#include + +#include #include +#include #include #include #include -#include #include #include @@ -214,7 +224,7 @@ struct FlowGfwOmegaXi { AxisSpec axisMultiplicity{{0, 5, 10, 20, 30, 40, 50, 60, 70, 80, 90}, "Centrality (%)"}; Filter collisionFilter = nabs(aod::collision::posZ) < cfgCutVertex; - Filter trackFilter = (nabs(aod::track::eta) < trkQualityOpts.cfgCutEta.value) && (aod::track::pt > trkQualityOpts.cfgCutPtPOIMin.value) && (aod::track::pt < trkQualityOpts.cfgCutPtPOIMax.value) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true)) && (aod::track::tpcChi2NCl < cfgCutChi2prTPCcls) && (nabs(aod::track::dcaZ) < trkQualityOpts.cfgCutDCAz.value); + Filter trackFilter = (nabs(aod::track::eta) < trkQualityOpts.cfgCutEta.value) && (aod::track::pt > trkQualityOpts.cfgCutPtPOIMin.value) && (aod::track::pt < trkQualityOpts.cfgCutPtPOIMax.value) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t)true)) && (aod::track::tpcChi2NCl < cfgCutChi2prTPCcls) && (nabs(aod::track::dcaZ) < trkQualityOpts.cfgCutDCAz.value); using TracksPID = soa::Join; using AodTracks = soa::Filtered>; // tracks filter diff --git a/PWGCF/Flow/Tasks/flowGfwTask.cxx b/PWGCF/Flow/Tasks/flowGfwTask.cxx index e0c6616828d..4ed891c722b 100644 --- a/PWGCF/Flow/Tasks/flowGfwTask.cxx +++ b/PWGCF/Flow/Tasks/flowGfwTask.cxx @@ -16,10 +16,9 @@ #include "FlowContainer.h" #include "GFW.h" -#include "GFWCumulant.h" -#include "GFWPowerArray.h" #include "GFWWeights.h" +#include "Common/CCDB/EventSelectionParams.h" #include "Common/Core/TrackSelection.h" #include "Common/Core/TrackSelectionDefaults.h" #include "Common/DataModel/Centrality.h" @@ -27,25 +26,35 @@ #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/runDataProcessing.h" -#include "ReconstructionDataFormats/GlobalTrackID.h" -#include "ReconstructionDataFormats/Track.h" #include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include -#include "TList.h" -#include "TPDGCode.h" #include +#include +#include +#include #include #include +#include +#include + +#include + +#include #include +#include #include #include #include @@ -976,11 +985,11 @@ struct FlowGfwTask { ft0aAmp = ft0cAmp = -999; } - registry.fill(HIST("FT0AAmp"), ft0aAmp); - registry.fill(HIST("FT0CAmp"), ft0cAmp); + registry.fill(HIST("FT0AAmp"), ft0aAmp); + registry.fill(HIST("FT0CAmp"), ft0cAmp); - ft0mAmp = ft0aAmp + ft0cAmp; - registry.fill(HIST("FT0MAmp"), ft0mAmp); + ft0mAmp = ft0aAmp + ft0cAmp; + registry.fill(HIST("FT0MAmp"), ft0mAmp); float vtxz = collision.posZ(); float lRandom = fRndm->Rndm(); diff --git a/PWGCF/Flow/Tasks/flowMc.cxx b/PWGCF/Flow/Tasks/flowMc.cxx index 28e1e2e49bc..56a44f135ac 100644 --- a/PWGCF/Flow/Tasks/flowMc.cxx +++ b/PWGCF/Flow/Tasks/flowMc.cxx @@ -14,34 +14,52 @@ /// \since Feb/5/2025 /// \brief QC of synthetic flow exercise -#include -#include -#include -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/runDataProcessing.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Common/DataModel/TrackSelectionTables.h" +#include "FlowContainer.h" +#include "GFW.h" +#include "GFWWeights.h" + +#include "PWGMM/Mult/DataModel/Index.h" // for Particles2Tracks table + +#include "Common/CCDB/EventSelectionParams.h" #include "Common/Core/RecoDecay.h" #include "Common/Core/TrackSelection.h" #include "Common/Core/TrackSelectionDefaults.h" -#include "Common/Core/trackUtilities.h" -#include "ReconstructionDataFormats/Track.h" -#include "DataFormatsParameters/GRPObject.h" -#include "DataFormatsParameters/GRPMagField.h" -#include "PWGLF/DataModel/LFStrangenessTables.h" -#include "PWGMM/Mult/DataModel/Index.h" // for Particles2Tracks table -#include "GFWPowerArray.h" -#include "GFW.h" -#include "GFWCumulant.h" -#include "GFWWeights.h" -#include "FlowContainer.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include #include #include -#include -#include +#include + +#include + +#include + +#include +#include +#include +#include +#include +#include using namespace o2; using namespace o2::framework; diff --git a/PWGCF/Flow/Tasks/flowPbpbPikp.cxx b/PWGCF/Flow/Tasks/flowPbpbPikp.cxx index 12809169eb8..caecf49b188 100644 --- a/PWGCF/Flow/Tasks/flowPbpbPikp.cxx +++ b/PWGCF/Flow/Tasks/flowPbpbPikp.cxx @@ -16,13 +16,10 @@ #include "PWGCF/GenericFramework/Core/FlowContainer.h" #include "PWGCF/GenericFramework/Core/GFW.h" #include "PWGCF/GenericFramework/Core/GFWConfig.h" -#include "PWGCF/GenericFramework/Core/GFWCumulant.h" -#include "PWGCF/GenericFramework/Core/GFWPowerArray.h" #include "PWGCF/GenericFramework/Core/GFWWeights.h" -#include "PWGCF/GenericFramework/Core/GFWWeightsList.h" -#include "Common/Core/TrackSelection.h" -#include "Common/Core/trackUtilities.h" +#include "Common/CCDB/EventSelectionParams.h" +#include "Common/CCDB/TriggerAliases.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" @@ -31,26 +28,40 @@ #include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "CommonConstants/PhysicsConstants.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/StepTHn.h" -#include "Framework/runDataProcessing.h" -#include "ReconstructionDataFormats/PID.h" -#include "ReconstructionDataFormats/Track.h" #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include -#include "Math/Vector4D.h" #include +#include +#include +#include +#include #include #include +#include +#include + +#include + +#include #include +#include #include +#include #include +#include #include #include #include @@ -139,7 +150,7 @@ struct FlowPbpbPikp { std::vector eventCuts; Filter collisionFilter = nabs(aod::collision::posZ) < cfgCutVertex; - Filter trackFilter = (nabs(aod::track::dcaXY) < cfgCutDCAxy) && (nabs(aod::track::dcaZ) < cfgCutDCAz) && (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPtPOIMin) && (aod::track::pt < cfgCutPtPOIMax) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true)) && (aod::track::tpcChi2NCl < cfgCutChi2prTPCcls); + Filter trackFilter = (nabs(aod::track::dcaXY) < cfgCutDCAxy) && (nabs(aod::track::dcaZ) < cfgCutDCAz) && (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPtPOIMin) && (aod::track::pt < cfgCutPtPOIMax) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t)true)) && (aod::track::tpcChi2NCl < cfgCutChi2prTPCcls); using AodCollisions = soa::Filtered>; using AodTracksWithoutBayes = soa::Filtered>; diff --git a/PWGCF/Flow/Tasks/flowPidCme.cxx b/PWGCF/Flow/Tasks/flowPidCme.cxx index 6b457daa168..4f804c97fb3 100644 --- a/PWGCF/Flow/Tasks/flowPidCme.cxx +++ b/PWGCF/Flow/Tasks/flowPidCme.cxx @@ -11,26 +11,10 @@ /// \author ZhengqingWang(zhengqing.wang@cern.ch), KegangXiong(kxiong@cern.ch) /// \file flowPidCme.cxx -/// \brief task to calculate the pikp cme signal and bacground. -// C++/ROOT includes. -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include +/// \brief task to calculate the pikp cme signal and background. -// o2Physics includes. +#include "Common/CCDB/EventSelectionParams.h" #include "Common/Core/EventPlaneHelper.h" -#include "Common/Core/TrackSelection.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" @@ -40,17 +24,32 @@ #include "Common/DataModel/Qvectors.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "CommonConstants/PhysicsConstants.h" -#include "Framework/ASoA.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/StaticFor.h" -#include "Framework/runDataProcessing.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include -// o2 includes. +#include +#include +#include +#include +#include +#include +#include using namespace o2; using namespace o2::framework; @@ -238,7 +237,7 @@ struct FillPIDcolums { if (std::abs(track.eta()) > cfgMaxEtaPID) return false; if (cfgRequireGlobalTrack) { - if (!(track.isGlobalTrackSDD() == (uint8_t) true)) + if (!(track.isGlobalTrackSDD() == (uint8_t)true)) return false; } if (cfgUseCostomTrackCuts) { diff --git a/PWGCF/Flow/Tasks/flowPtEfficiency.cxx b/PWGCF/Flow/Tasks/flowPtEfficiency.cxx index 27657e0f435..5de1cadb5f6 100644 --- a/PWGCF/Flow/Tasks/flowPtEfficiency.cxx +++ b/PWGCF/Flow/Tasks/flowPtEfficiency.cxx @@ -16,8 +16,6 @@ #include "FlowContainer.h" #include "GFW.h" -#include "GFWCumulant.h" -#include "GFWPowerArray.h" #include "GFWWeights.h" #include "Common/Core/RecoDecay.h" @@ -26,18 +24,38 @@ #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/runDataProcessing.h" #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include +#include +#include #include #include #include +#include +#include + +#include + +#include +#include +#include +#include +#include #include #include diff --git a/PWGCF/Flow/Tasks/flowQa.cxx b/PWGCF/Flow/Tasks/flowQa.cxx index 1eaa6d8437d..675aced2c01 100644 --- a/PWGCF/Flow/Tasks/flowQa.cxx +++ b/PWGCF/Flow/Tasks/flowQa.cxx @@ -14,36 +14,51 @@ /// \since Feb/23/2025 /// \brief jira: PWGCF-254, QA for flow analysis -#include -#include -#include -#include -#include -#include -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/HistogramRegistry.h" +#include "FlowContainer.h" +#include "GFW.h" +#include "GFWWeights.h" -#include "Common/DataModel/EventSelection.h" -#include "Common/Core/TrackSelection.h" -#include "Common/Core/TrackSelectionDefaults.h" -#include "Common/DataModel/TrackSelectionTables.h" +#include "Common/CCDB/EventSelectionParams.h" +#include "Common/CCDB/ctpRateFetcher.h" #include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" -#include "Common/CCDB/ctpRateFetcher.h" +#include "Common/DataModel/TrackSelectionTables.h" -#include "GFWPowerArray.h" -#include "GFW.h" -#include "GFWCumulant.h" -#include "GFWWeights.h" -#include "FlowContainer.h" -#include "TList.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include #include #include -#include -#include +#include + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include using namespace o2; using namespace o2::framework; diff --git a/PWGCF/Flow/Tasks/flowRunbyRun.cxx b/PWGCF/Flow/Tasks/flowRunbyRun.cxx index 9259eb8be9e..3d0937e319e 100644 --- a/PWGCF/Flow/Tasks/flowRunbyRun.cxx +++ b/PWGCF/Flow/Tasks/flowRunbyRun.cxx @@ -15,36 +15,54 @@ /// \since Oct/30/2024 /// \brief jira: PWGCF-254, produce Run-by-Run QA plots and flow analysis for Run3 -#include -#include -#include -#include -#include -#include -#include -#include -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/HistogramRegistry.h" +#include "FlowContainer.h" +#include "GFW.h" +#include "GFWWeights.h" -#include "Common/DataModel/EventSelection.h" -#include "Common/Core/TrackSelection.h" -#include "Common/DataModel/TrackSelectionTables.h" +#include "Common/CCDB/EventSelectionParams.h" +#include "Common/CCDB/ctpRateFetcher.h" #include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" -#include "Common/CCDB/ctpRateFetcher.h" +#include "Common/DataModel/TrackSelectionTables.h" -#include "GFWPowerArray.h" -#include "GFW.h" -#include "GFWCumulant.h" -#include "GFWWeights.h" -#include "FlowContainer.h" -#include "TList.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include #include #include -#include +#include + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include using namespace o2; using namespace o2::framework; @@ -108,7 +126,7 @@ struct FlowRunbyRun { ConfigurableAxis axisT0A{"axisT0A", {200, 0, 200000}, "N_{ch} (T0A)"}; Filter collisionFilter = nabs(aod::collision::posZ) < cfgCutVertex; - Filter trackFilter = ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true)) && (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPtMin) && (aod::track::pt < cfgCutPtMax) && (aod::track::tpcChi2NCl < cfgCutChi2prTPCcls) && (nabs(aod::track::dcaZ) < cfgCutDCAz); + Filter trackFilter = ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t)true)) && (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPtMin) && (aod::track::pt < cfgCutPtMax) && (aod::track::tpcChi2NCl < cfgCutChi2prTPCcls) && (nabs(aod::track::dcaZ) < cfgCutDCAz); // Corrections TH1D* mEfficiency = nullptr; diff --git a/PWGCF/Flow/Tasks/flowSP.cxx b/PWGCF/Flow/Tasks/flowSP.cxx index a323867eb6b..3ad6c9aa6d9 100644 --- a/PWGCF/Flow/Tasks/flowSP.cxx +++ b/PWGCF/Flow/Tasks/flowSP.cxx @@ -18,35 +18,49 @@ #include "PWGCF/DataModel/SPTableZDC.h" -#include "Common/Core/EventPlaneHelper.h" +#include "Common/CCDB/EventSelectionParams.h" +#include "Common/CCDB/RCTSelectionFlags.h" #include "Common/Core/RecoDecay.h" -#include "Common/Core/TrackSelection.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponseTOF.h" #include "Common/DataModel/PIDResponseTPC.h" -#include "Common/DataModel/Qvectors.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "CCDB/BasicCCDBManager.h" -#include "DataFormatsParameters/GRPLHCIFData.h" -#include "DataFormatsParameters/GRPMagField.h" -#include "DataFormatsParameters/GRPObject.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/runDataProcessing.h" - -#include "TF1.h" -#include "TPDGCode.h" - -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include #include -#include #include +#include #include #include #include @@ -151,7 +165,7 @@ struct FlowSP { Configurable> cfgEvSelsMult{"cfgEvSelsMult", std::vector{1301.56, -41.4615, 0.478224, -0.00239449, 4.46966e-06, 2967.6, -102.927, 1.47488, -0.0106534, 3.28622e-05}, "Multiplicity cuts (Global) first 5 parameters cutLOW last 5 cutHIGH (Default is +-2sigma pass5) "}; Filter collisionFilter = nabs(aod::collision::posZ) < cfgEvSelsVtxZ; - Filter trackFilter = nabs(aod::track::eta) < cfgTrackSelsEta && aod::track::pt > cfgTrackSelsPtmin&& aod::track::pt < cfgTrackSelsPtmax && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true)) && nabs(aod::track::dcaXY) < cfgTrackSelsDCAxy&& nabs(aod::track::dcaZ) < cfgTrackSelsDCAz; + Filter trackFilter = nabs(aod::track::eta) < cfgTrackSelsEta && aod::track::pt > cfgTrackSelsPtmin&& aod::track::pt < cfgTrackSelsPtmax && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t)true)) && nabs(aod::track::dcaXY) < cfgTrackSelsDCAxy&& nabs(aod::track::dcaZ) < cfgTrackSelsDCAz; Filter trackFilterMC = nabs(aod::mcparticle::eta) < cfgTrackSelsEta && aod::mcparticle::pt > cfgTrackSelsPtmin&& aod::mcparticle::pt < cfgTrackSelsPtmax; using GeneralCollisions = soa::Join; using UnfilteredTracks = soa::Join; diff --git a/PWGCF/Flow/Tasks/flowTask.cxx b/PWGCF/Flow/Tasks/flowTask.cxx index 53b84b5f849..a3665d6264c 100644 --- a/PWGCF/Flow/Tasks/flowTask.cxx +++ b/PWGCF/Flow/Tasks/flowTask.cxx @@ -18,34 +18,52 @@ #include "FlowPtContainer.h" #include "GFW.h" #include "GFWConfig.h" -#include "GFWCumulant.h" -#include "GFWPowerArray.h" #include "GFWWeights.h" +#include "Common/CCDB/EventSelectionParams.h" #include "Common/CCDB/ctpRateFetcher.h" -#include "Common/Core/TrackSelection.h" -#include "Common/Core/TrackSelectionDefaults.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/runDataProcessing.h" #include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include -#include "TList.h" #include +#include +#include +#include +#include #include #include #include +#include #include +#include +#include + +#include + +#include +#include #include +#include +#include #include #include #include @@ -56,6 +74,7 @@ using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; +using namespace o2::analysis::genericframework; #define O2_DEFINE_CONFIGURABLE(NAME, TYPE, DEFAULT, HELP) Configurable NAME{#NAME, DEFAULT, HELP}; static constexpr double LongArrayDouble[4][2] = {{-2.0, -2.0}, {-2.0, -2.0}, {-2.0, -2.0}, {-2.0, -2.0}}; @@ -217,7 +236,7 @@ struct FlowTask { ConfigurableAxis axisDCAxy{"axisDCAxy", {200, -1, 1}, "DCA_{xy} (cm)"}; Filter collisionFilter = (nabs(aod::collision::posZ) < cfgCutVertex) && (aod::cent::centFT0C > cfgCentFT0CMin) && (aod::cent::centFT0C < cfgCentFT0CMax); - Filter trackFilter = ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true)) && (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPtMin) && (aod::track::pt < cfgCutPtMax); + Filter trackFilter = ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t)true)) && (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPtMin) && (aod::track::pt < cfgCutPtMax); using FilteredCollisions = soa::Filtered>; using FilteredTracks = soa::Filtered>; // Filter for MCcollisions diff --git a/PWGCF/Flow/Tasks/flowZdcEnergy.cxx b/PWGCF/Flow/Tasks/flowZdcEnergy.cxx index 11f9c2fe4c3..dcdde4e63f5 100644 --- a/PWGCF/Flow/Tasks/flowZdcEnergy.cxx +++ b/PWGCF/Flow/Tasks/flowZdcEnergy.cxx @@ -14,40 +14,32 @@ /// \since 03/2026 /// \brief A try to use the znc energy. -#include "Common/Core/EventPlaneHelper.h" -#include "Common/Core/RecoDecay.h" -#include "Common/Core/TrackSelection.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" -#include "Common/DataModel/Qvectors.h" -#include "Common/DataModel/TrackSelectionTables.h" - -#include "CCDB/BasicCCDBManager.h" -#include "DataFormatsParameters/GRPLHCIFData.h" -#include "DataFormatsParameters/GRPMagField.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/runDataProcessing.h" - -#include "TF1.h" -#include "TPDGCode.h" - -#include -#include -#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include #include -#include -#include #include using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; -using namespace o2::aod::rctsel; -// using namespace o2::analysis; #define O2_DEFINE_CONFIGURABLE(NAME, TYPE, DEFAULT, HELP) Configurable NAME{#NAME, DEFAULT, HELP}; diff --git a/PWGCF/Flow/Tasks/flowZdcTask.cxx b/PWGCF/Flow/Tasks/flowZdcTask.cxx index a0a424172dd..878f10a6078 100644 --- a/PWGCF/Flow/Tasks/flowZdcTask.cxx +++ b/PWGCF/Flow/Tasks/flowZdcTask.cxx @@ -20,18 +20,28 @@ #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "CommonConstants/MathConstants.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/runDataProcessing.h" #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include -#include -#include +#include +#include #include +#include #include #include diff --git a/PWGCF/Flow/Tasks/pidFlowPtCorr.cxx b/PWGCF/Flow/Tasks/pidFlowPtCorr.cxx index cb0fe7b46d0..c45cc9bae6e 100644 --- a/PWGCF/Flow/Tasks/pidFlowPtCorr.cxx +++ b/PWGCF/Flow/Tasks/pidFlowPtCorr.cxx @@ -16,47 +16,56 @@ #include "FlowContainer.h" #include "GFW.h" -#include "GFWCumulant.h" -#include "GFWPowerArray.h" #include "GFWWeights.h" -#include "PWGMM/Mult/DataModel/Index.h" - +#include "Common/CCDB/EventSelectionParams.h" +#include "Common/CCDB/TriggerAliases.h" #include "Common/CCDB/ctpRateFetcher.h" -#include "Common/Core/EventPlaneHelper.h" -#include "Common/Core/TrackSelection.h" -#include "Common/Core/trackUtilities.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponseITS.h" #include "Common/DataModel/PIDResponseTOF.h" #include "Common/DataModel/PIDResponseTPC.h" -#include "Common/DataModel/Qvectors.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "CommonConstants/PhysicsConstants.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/runDataProcessing.h" -#include "ReconstructionDataFormats/Track.h" #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include -#include "TList.h" #include -#include +#include +#include +#include +#include +#include +#include #include #include #include +#include + +#include + +#include +#include #include +#include #include #include #include -#include -#include #include using namespace o2; diff --git a/PWGCF/Flow/Tasks/resonancesGfwFlow.cxx b/PWGCF/Flow/Tasks/resonancesGfwFlow.cxx index 45f4284391c..0ba13019c63 100644 --- a/PWGCF/Flow/Tasks/resonancesGfwFlow.cxx +++ b/PWGCF/Flow/Tasks/resonancesGfwFlow.cxx @@ -13,19 +13,14 @@ /// \brief PID flow for resonances using the generic framework /// \author Preet Bhanjan Pati -#include "PWGCF/GenericFramework/Core/FlowContainer.h" #include "PWGCF/GenericFramework/Core/GFW.h" #include "PWGCF/GenericFramework/Core/GFWConfig.h" -#include "PWGCF/GenericFramework/Core/GFWCumulant.h" -#include "PWGCF/GenericFramework/Core/GFWPowerArray.h" #include "PWGCF/GenericFramework/Core/GFWWeights.h" -#include "PWGCF/GenericFramework/Core/GFWWeightsList.h" -#include "PWGLF/DataModel/EPCalibrationTables.h" #include "PWGLF/DataModel/LFStrangenessTables.h" +#include "Common/CCDB/EventSelectionParams.h" +#include "Common/CCDB/TriggerAliases.h" #include "Common/Core/RecoDecay.h" -#include "Common/Core/TrackSelection.h" -#include "Common/Core/trackUtilities.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" @@ -34,28 +29,43 @@ #include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "CommonConstants/PhysicsConstants.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/StepTHn.h" -#include "Framework/runDataProcessing.h" -#include "ReconstructionDataFormats/PID.h" -#include "ReconstructionDataFormats/Track.h" #include - -#include "Math/Vector4D.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include // IWYU pragma: keep (do not replace with Math/Vector4Dfwd.h) +#include #include +#include +#include #include +#include #include +#include + +#include + +#include #include +#include #include +#include #include #include -#include #include using namespace o2; @@ -231,7 +241,7 @@ struct ResonancesGfwFlow { ConfigurableAxis axisParticles{"axisParticles", {3, 0, 3}, "axis for different hadrons"}; Filter collisionFilter = nabs(aod::collision::posZ) < cfgCutVertex; - Filter trackFilter = (nabs(aod::track::dcaXY) < cfgCutDCAxy) && (nabs(aod::track::dcaZ) < cfgCutDCAz) && (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPtPOIMin) && (aod::track::pt < cfgCutPtPOIMax) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true)) && (aod::track::tpcChi2NCl < cfgCutChi2prTPCcls); + Filter trackFilter = (nabs(aod::track::dcaXY) < cfgCutDCAxy) && (nabs(aod::track::dcaZ) < cfgCutDCAz) && (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPtPOIMin) && (aod::track::pt < cfgCutPtPOIMax) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t)true)) && (aod::track::tpcChi2NCl < cfgCutChi2prTPCcls); using AodCollisions = soa::Filtered>; using AodTracksWithoutBayes = soa::Filtered>; diff --git a/PWGCF/GenericFramework/Core/BootstrapProfile.cxx b/PWGCF/GenericFramework/Core/BootstrapProfile.cxx index 1813016eb38..94bd49a01ac 100644 --- a/PWGCF/GenericFramework/Core/BootstrapProfile.cxx +++ b/PWGCF/GenericFramework/Core/BootstrapProfile.cxx @@ -10,6 +10,17 @@ // or submit itself to any jurisdiction. #include "BootstrapProfile.h" + +#include +#include +#include +#include +#include +#include + +#include + +#include BootstrapProfile::BootstrapProfile() : TProfile(), fListOfEntries(0), fProfInitialized(kFALSE), diff --git a/PWGCF/GenericFramework/Core/BootstrapProfile.h b/PWGCF/GenericFramework/Core/BootstrapProfile.h index 829c58cc11a..dd7e4d76336 100644 --- a/PWGCF/GenericFramework/Core/BootstrapProfile.h +++ b/PWGCF/GenericFramework/Core/BootstrapProfile.h @@ -16,11 +16,13 @@ #ifndef PWGCF_GENERICFRAMEWORK_CORE_BOOTSTRAPPROFILE_H_ #define PWGCF_GENERICFRAMEWORK_CORE_BOOTSTRAPPROFILE_H_ -#include "TProfile.h" -#include "TList.h" -#include "TString.h" -#include "TCollection.h" -#include "TMath.h" +#include +#include +#include +#include + +#include +#include class BootstrapProfile : public TProfile { diff --git a/PWGCF/GenericFramework/Core/FlowContainer.cxx b/PWGCF/GenericFramework/Core/FlowContainer.cxx index 532eb35c80c..29c4ba721a4 100644 --- a/PWGCF/GenericFramework/Core/FlowContainer.cxx +++ b/PWGCF/GenericFramework/Core/FlowContainer.cxx @@ -11,6 +11,25 @@ #include "FlowContainer.h" +#include "ProfileSubset.h" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + #include #include diff --git a/PWGCF/GenericFramework/Core/FlowContainer.h b/PWGCF/GenericFramework/Core/FlowContainer.h index 8547436cf2b..c78acf240a3 100644 --- a/PWGCF/GenericFramework/Core/FlowContainer.h +++ b/PWGCF/GenericFramework/Core/FlowContainer.h @@ -15,23 +15,20 @@ #ifndef PWGCF_GENERICFRAMEWORK_CORE_FLOWCONTAINER_H_ #define PWGCF_GENERICFRAMEWORK_CORE_FLOWCONTAINER_H_ -#include -#include "TH3F.h" -#include "TProfile2D.h" -#include "TProfile.h" -#include "TNamed.h" -#include "TH1.h" -#include "TMath.h" -#include "TFile.h" -#include "TAxis.h" -#include "TString.h" -#include "TObjArray.h" -#include "TRandom.h" -#include "TString.h" -#include "TCollection.h" -#include "TAxis.h" -#include "ProfileSubset.h" -#include "Framework/HistogramSpec.h" +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include class FlowContainer : public TNamed { diff --git a/PWGCF/GenericFramework/Core/FlowPtContainer.cxx b/PWGCF/GenericFramework/Core/FlowPtContainer.cxx index f527b05d6af..9ec9506c20d 100644 --- a/PWGCF/GenericFramework/Core/FlowPtContainer.cxx +++ b/PWGCF/GenericFramework/Core/FlowPtContainer.cxx @@ -15,10 +15,33 @@ #include "FlowPtContainer.h" +#include "BootstrapProfile.h" +#include "GFWConfig.h" + +#include +#include + +#include +#include +#include +#include +#include + +#include + #include +#include +#include +#include +#include +#include #include +#include #include +using namespace o2::analysis::genericframework; +using namespace o2::analysis::genericframework::eventweight; + FlowPtContainer::FlowPtContainer() : fCMTermList(0), fCorrList(0), fCovList(0), diff --git a/PWGCF/GenericFramework/Core/FlowPtContainer.h b/PWGCF/GenericFramework/Core/FlowPtContainer.h index d4fef16b7cf..748d4e57cb5 100644 --- a/PWGCF/GenericFramework/Core/FlowPtContainer.h +++ b/PWGCF/GenericFramework/Core/FlowPtContainer.h @@ -16,18 +16,20 @@ #ifndef PWGCF_GENERICFRAMEWORK_CORE_FLOWPTCONTAINER_H_ #define PWGCF_GENERICFRAMEWORK_CORE_FLOWPTCONTAINER_H_ -#include "BootstrapProfile.h" -#include "GFW.h" #include "GFWConfig.h" -#include "Framework/HistogramSpec.h" +#include -#include "TCollection.h" -#include "TList.h" -#include "TNamed.h" +#include +#include +#include +#include + +#include +#include -#include #include +#include #include #include @@ -39,9 +41,6 @@ enum EventWeight { }; }; -using namespace o2::analysis::genericframework; -using namespace o2::analysis::genericframework::eventweight; - class FlowPtContainer : public TNamed { public: @@ -50,9 +49,9 @@ class FlowPtContainer : public TNamed explicit FlowPtContainer(const char* name); ~FlowPtContainer(); FlowPtContainer(const char* name, const char* title); - void initialise(const o2::framework::AxisSpec axis, const int& m, const GFWCorrConfigs& configs, const int& nsub = 10); - void initialise(int nbinsx, double* xbins, const int& m, const GFWCorrConfigs& configs, const int& nsub = 10); - void initialise(int nbinsx, double xlow, double xhigh, const int& m, const GFWCorrConfigs& configs, const int& nsub = 10); + void initialise(const o2::framework::AxisSpec axis, const int& m, const o2::analysis::genericframework::GFWCorrConfigs& configs, const int& nsub = 10); + void initialise(int nbinsx, double* xbins, const int& m, const o2::analysis::genericframework::GFWCorrConfigs& configs, const int& nsub = 10); + void initialise(int nbinsx, double xlow, double xhigh, const int& m, const o2::analysis::genericframework::GFWCorrConfigs& configs, const int& nsub = 10); // initial pt-pt correlations with two subevents void initialiseSubevent(const o2::framework::AxisSpec axis, const int& m, const int& nsubev = 2, const int& nsub = 10); void initialiseSubevent(int nbinsx, double* xbins, const int& m, const int& nsubev = 2, const int& nsub = 10); diff --git a/PWGCF/GenericFramework/Core/GFW.cxx b/PWGCF/GenericFramework/Core/GFW.cxx index 350fe752156..c8fcb8e3ec6 100644 --- a/PWGCF/GenericFramework/Core/GFW.cxx +++ b/PWGCF/GenericFramework/Core/GFW.cxx @@ -11,6 +11,9 @@ #include "GFW.h" +#include "GFWPowerArray.h" + +#include #include #include #include diff --git a/PWGCF/GenericFramework/Core/GFW.h b/PWGCF/GenericFramework/Core/GFW.h index 8ec2b78d095..3263e5c4836 100644 --- a/PWGCF/GenericFramework/Core/GFW.h +++ b/PWGCF/GenericFramework/Core/GFW.h @@ -17,9 +17,7 @@ #define PWGCF_GENERICFRAMEWORK_CORE_GFW_H_ #include "GFWCumulant.h" -#include "GFWPowerArray.h" -#include #include #include #include diff --git a/PWGCF/GenericFramework/Core/GFWConfig.h b/PWGCF/GenericFramework/Core/GFWConfig.h index 7a7a9dd82ed..1bc1811c30a 100644 --- a/PWGCF/GenericFramework/Core/GFWConfig.h +++ b/PWGCF/GenericFramework/Core/GFWConfig.h @@ -16,14 +16,12 @@ #ifndef PWGCF_GENERICFRAMEWORK_CORE_GFWCONFIG_H_ #define PWGCF_GENERICFRAMEWORK_CORE_GFWCONFIG_H_ -#include "GFW.h" +#include -#include "Framework/Logger.h" - -#include -#include +#include #include +#include #include #include #include diff --git a/PWGCF/GenericFramework/Core/GFWCumulant.cxx b/PWGCF/GenericFramework/Core/GFWCumulant.cxx index f27da24bd27..3a8b1c4d172 100644 --- a/PWGCF/GenericFramework/Core/GFWCumulant.cxx +++ b/PWGCF/GenericFramework/Core/GFWCumulant.cxx @@ -11,6 +11,8 @@ #include "GFWCumulant.h" +#include +#include #include using std::complex; diff --git a/PWGCF/GenericFramework/Core/GFWCumulant.h b/PWGCF/GenericFramework/Core/GFWCumulant.h index 2567a2e9c4a..e8521c60af9 100644 --- a/PWGCF/GenericFramework/Core/GFWCumulant.h +++ b/PWGCF/GenericFramework/Core/GFWCumulant.h @@ -16,6 +16,8 @@ #ifndef PWGCF_GENERICFRAMEWORK_CORE_GFWCUMULANT_H_ #define PWGCF_GENERICFRAMEWORK_CORE_GFWCUMULANT_H_ +#include + #include #include #include diff --git a/PWGCF/GenericFramework/Core/GFWPowerArray.cxx b/PWGCF/GenericFramework/Core/GFWPowerArray.cxx index 609b235ec6f..c3aeaf43edb 100644 --- a/PWGCF/GenericFramework/Core/GFWPowerArray.cxx +++ b/PWGCF/GenericFramework/Core/GFWPowerArray.cxx @@ -11,6 +11,12 @@ #include "GFWPowerArray.h" +#include +#include +#include +#include +#include + using std::string; using std::vector; diff --git a/PWGCF/GenericFramework/Core/GFWPowerArray.h b/PWGCF/GenericFramework/Core/GFWPowerArray.h index ba38f2fcc54..30d5444e727 100644 --- a/PWGCF/GenericFramework/Core/GFWPowerArray.h +++ b/PWGCF/GenericFramework/Core/GFWPowerArray.h @@ -16,9 +16,8 @@ #ifndef PWGCF_GENERICFRAMEWORK_CORE_GFWPOWERARRAY_H_ #define PWGCF_GENERICFRAMEWORK_CORE_GFWPOWERARRAY_H_ -#include #include -#include +#include typedef std::vector HarSet; class GFWPowerArray diff --git a/PWGCF/GenericFramework/Core/GFWWeights.cxx b/PWGCF/GenericFramework/Core/GFWWeights.cxx index 4d2d41cd85d..a0074866f5a 100644 --- a/PWGCF/GenericFramework/Core/GFWWeights.cxx +++ b/PWGCF/GenericFramework/Core/GFWWeights.cxx @@ -10,7 +10,21 @@ // or submit itself to any jurisdiction. #include "GFWWeights.h" -#include "TMath.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + #include GFWWeights::GFWWeights() : TNamed("", ""), diff --git a/PWGCF/GenericFramework/Core/GFWWeights.h b/PWGCF/GenericFramework/Core/GFWWeights.h index f60783ccec8..9cecbd337e6 100644 --- a/PWGCF/GenericFramework/Core/GFWWeights.h +++ b/PWGCF/GenericFramework/Core/GFWWeights.h @@ -16,16 +16,15 @@ #ifndef PWGCF_GENERICFRAMEWORK_CORE_GFWWEIGHTS_H_ #define PWGCF_GENERICFRAMEWORK_CORE_GFWWEIGHTS_H_ -#include "Framework/Logger.h" +#include +#include +#include +#include +#include +#include -#include "TObjArray.h" -#include "TNamed.h" -#include "TH3D.h" -#include "TH2D.h" -#include "TH1D.h" -#include "TFile.h" -#include "TCollection.h" -#include "TString.h" +#include +#include class GFWWeights : public TNamed { diff --git a/PWGCF/GenericFramework/Core/GFWWeightsList.cxx b/PWGCF/GenericFramework/Core/GFWWeightsList.cxx index 11a6ffe3159..36cf2029589 100644 --- a/PWGCF/GenericFramework/Core/GFWWeightsList.cxx +++ b/PWGCF/GenericFramework/Core/GFWWeightsList.cxx @@ -14,9 +14,25 @@ /// \since Dec/25/2024 /// \brief one object to hold a list of GFWWeights objects, -#include #include "GFWWeightsList.h" +#include "GFWWeights.h" + +#include + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + GFWWeightsList::GFWWeightsList() : TNamed("", ""), list(0) { runNumberMap.clear(); diff --git a/PWGCF/GenericFramework/Core/GFWWeightsList.h b/PWGCF/GenericFramework/Core/GFWWeightsList.h index c0f208a7088..b48e4661b89 100644 --- a/PWGCF/GenericFramework/Core/GFWWeightsList.h +++ b/PWGCF/GenericFramework/Core/GFWWeightsList.h @@ -16,16 +16,20 @@ #ifndef PWGCF_GENERICFRAMEWORK_CORE_GFWWEIGHTSLIST_H_ #define PWGCF_GENERICFRAMEWORK_CORE_GFWWEIGHTSLIST_H_ -#include +#include "GFWWeights.h" + +#include +#include +#include + +#include +#include + #include +#include #include #include -#include "Framework/Logger.h" - -#include "TObjArray.h" -#include "GFWWeights.h" - class GFWWeightsList : public TNamed { public: diff --git a/PWGCF/GenericFramework/Core/GenericFrameworkLinkDef.h b/PWGCF/GenericFramework/Core/GenericFrameworkLinkDef.h old mode 100755 new mode 100644 diff --git a/PWGCF/GenericFramework/Core/ProfileSubset.cxx b/PWGCF/GenericFramework/Core/ProfileSubset.cxx index 66969f699af..c36a52e5346 100644 --- a/PWGCF/GenericFramework/Core/ProfileSubset.cxx +++ b/PWGCF/GenericFramework/Core/ProfileSubset.cxx @@ -10,7 +10,19 @@ // or submit itself to any jurisdiction. #include "ProfileSubset.h" -#include "TProfile2D.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include TProfile* ProfileSubset::GetSubset(bool onX, const char* name, int firstbin, int lastbin, int l_nbins, double* l_binarray) { diff --git a/PWGCF/GenericFramework/Core/ProfileSubset.h b/PWGCF/GenericFramework/Core/ProfileSubset.h index fc920b898c4..f0bfa5d5c6b 100644 --- a/PWGCF/GenericFramework/Core/ProfileSubset.h +++ b/PWGCF/GenericFramework/Core/ProfileSubset.h @@ -16,9 +16,10 @@ #ifndef PWGCF_GENERICFRAMEWORK_CORE_PROFILESUBSET_H_ #define PWGCF_GENERICFRAMEWORK_CORE_PROFILESUBSET_H_ -#include "TProfile.h" -#include "TProfile2D.h" -#include "TError.h" +#include +#include + +#include class ProfileSubset : public TProfile2D { diff --git a/PWGCF/GenericFramework/Tasks/flowGenericFramework.cxx b/PWGCF/GenericFramework/Tasks/flowGenericFramework.cxx index 44e1669f2cb..6507f1b9687 100644 --- a/PWGCF/GenericFramework/Tasks/flowGenericFramework.cxx +++ b/PWGCF/GenericFramework/Tasks/flowGenericFramework.cxx @@ -17,12 +17,9 @@ #include "FlowPtContainer.h" #include "GFW.h" #include "GFWConfig.h" -#include "GFWCumulant.h" -#include "GFWPowerArray.h" #include "GFWWeights.h" -#include "GFWWeightsList.h" -#include "Common/Core/TrackSelection.h" +#include "Common/CCDB/EventSelectionParams.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" @@ -30,30 +27,53 @@ #include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/runDataProcessing.h" #include +#include #include -#include - +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include #include +#include +#include +#include +#include #include #include +#include #include +#include + +#include + +#include #include +#include +#include #include +#include +#include +#include #include -#include +#include #include +#include #include #include using namespace o2; using namespace o2::framework; +using namespace o2::analysis::genericframework; #define O2_DEFINE_CONFIGURABLE(NAME, TYPE, DEFAULT, HELP) Configurable NAME{#NAME, DEFAULT, HELP}; @@ -280,8 +300,8 @@ struct FlowGenericFramework { TF1* fMultGlobalT0ACutHigh = nullptr; // Track selection - pt-phi cuts - TF1* fPhiCutLow; - TF1* fPhiCutHigh; + TF1* fPhiCutLow = nullptr; + TF1* fPhiCutHigh = nullptr; void init(InitContext const&) { @@ -334,11 +354,11 @@ struct FlowGenericFramework { } AxisSpec nchAxis = {nchbinning, "N_{ch}"}; AxisSpec bAxis = {200, 0, 20, "#it{b}"}; - AxisSpec t0cAxis = {1000, 0, 10000, "N_{ch} (T0C)"}; - AxisSpec t0aAxis = {300, 0, 30000, "N_{ch} (T0A)"}; - AxisSpec v0aAxis = {800, 0, 80000, "N_{ch} (V0A)"}; - AxisSpec multpvAxis = {600, 0, 600, "N_{ch} (PV)"}; - AxisSpec occAxis = {600, 0, 3000, "occupancy"}; + AxisSpec t0cAxis = {1000, 0, 50000, "N_{ch} (T0C)"}; + AxisSpec t0aAxis = {1800, 0, 180000, "N_{ch} (T0A)"}; + AxisSpec v0aAxis = {1800, 0, 180000, "N_{ch} (V0A)"}; + AxisSpec multpvAxis = {3500, 0, 3500, "N_{ch} (PV)"}; + AxisSpec occAxis = {500, 0, 5000, "occupancy"}; AxisSpec multAxis = (doprocessOnTheFly && !cfgUseNch) ? bAxis : (cfgUseNch) ? nchAxis : centAxis; AxisSpec dcaZAXis = {200, -2, 2, "DCA_{z} (cm)"}; @@ -380,8 +400,8 @@ struct FlowGenericFramework { registry.add("eventQA/before/PVTracks_centT0C", "; FT0C centrality (%); N_{PV}", {HistType::kTH2D, {centAxis, multpvAxis}}); registry.add("eventQA/before/globalTracks_PVTracks", "; N_{PV}; N_{global}", {HistType::kTH2D, {multpvAxis, nchAxis}}); registry.add("eventQA/before/globalTracks_multT0A", "; multT0A; N_{global}", {HistType::kTH2D, {t0aAxis, nchAxis}}); - registry.add("eventQA/before/globalTracks_multV0A", "; multV0A; N_{global}", {HistType::kTH2D, {t0aAxis, nchAxis}}); - registry.add("eventQA/before/multV0A_multT0A", "; multV0A; multT0A", {HistType::kTH2D, {t0aAxis, t0aAxis}}); + registry.add("eventQA/before/globalTracks_multV0A", "; multV0A; N_{global}", {HistType::kTH2D, {v0aAxis, nchAxis}}); + registry.add("eventQA/before/multV0A_multT0A", "; multV0A; multT0A", {HistType::kTH2D, {t0aAxis, v0aAxis}}); registry.add("eventQA/before/multT0C_centT0C", "; multT0C; FT0C centrality (%)", {HistType::kTH2D, {centAxis, t0cAxis}}); registry.add("eventQA/before/occ_mult_cent", "; occupancy; N_{ch}; centrality (%)", {HistType::kTH3D, {occAxis, nchAxis, centAxis}}); registry.addClone("eventQA/before/", "eventQA/after/"); @@ -633,7 +653,7 @@ struct FlowGenericFramework { } template - bool eventSelected(TCollision collision, const int& multTrk, const float& centrality, const int& run) + bool eventSelected(TCollision collision, const int multTrk, const float& centrality, const int run) { // Cut on trigger alias if (cfgEventCutFlags.cfgTVXinTRD) { @@ -686,7 +706,7 @@ struct FlowGenericFramework { } template - bool selectMultiplicityCorrelation(TCollision collision, const int& multTrk, const float& centrality, const int& run) + bool selectMultiplicityCorrelation(TCollision collision, const int multTrk, const float& centrality, const int run) { auto multNTracksPV = collision.multNTracksPV(); if (multNTracksPV < fMultPVCutLow->Eval(centrality)) @@ -715,7 +735,7 @@ struct FlowGenericFramework { } template - bool trackSelected(TTrack track, const int& field) + bool trackSelected(TTrack track, const int field) { if (cfgTrackCuts.cfgTPCSectorCut) { double phimodn = track.phi(); @@ -754,7 +774,7 @@ struct FlowGenericFramework { }; template - void fillWeights(const TTrack track, const double vtxz, const int& pid_index, const int& run) + void fillWeights(const TTrack track, const double vtxz, const int pid_index, const int run) { if (cfgUsePID) { double ptpidmins[] = {o2::analysis::gfw::ptpoilow, o2::analysis::gfw::ptpoilow, 0.3, 0.5}; // min pt for ch, pi, ka, pr @@ -795,7 +815,7 @@ struct FlowGenericFramework { return; } - void createRunByRunHistograms(const int& run) + void createRunByRunHistograms(const int run) { AxisSpec phiAxis = {o2::analysis::gfw::phibins, o2::analysis::gfw::philow, o2::analysis::gfw::phiup, "#phi"}; AxisSpec phiModAxis = {100, 0, constants::math::PI / 9, "fmod(#varphi,#pi/9)"}; @@ -883,7 +903,7 @@ struct FlowGenericFramework { } template - void processCollision(TCollision collision, TTracks tracks, const float& centrality, const int& field, const int& run) + void processCollision(TCollision collision, TTracks tracks, const float& centrality, const int field, const int run) { if (tracks.size() < 1) return; @@ -974,7 +994,7 @@ struct FlowGenericFramework { }; template - inline void processTrack(TTrack const& track, const float& vtxz, const int& field, const int& run, DensityCorr densitycorrections, AcceptedTracks& acceptedTracks) + inline void processTrack(TTrack const& track, const float& vtxz, const int field, const int run, DensityCorr densitycorrections, AcceptedTracks& acceptedTracks) { if constexpr (framework::has_type_v) { if (track.mcParticleId() < 0 || !(track.has_mcParticle())) @@ -1220,7 +1240,7 @@ struct FlowGenericFramework { } o2::framework::expressions::Filter collisionFilter = nabs(aod::collision::posZ) < cfgVtxZ; - o2::framework::expressions::Filter trackFilter = nabs(aod::track::eta) < cfgEta && aod::track::pt > cfgPtmin&& aod::track::pt < cfgPtmax && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true)) && (aod::track::itsChi2NCl < cfgTrackCuts.cfgChi2PrITSCls) && (aod::track::tpcChi2NCl < cfgTrackCuts.cfgChi2PrTPCCls) && nabs(aod::track::dcaZ) < cfgTrackCuts.cfgDCAz; + o2::framework::expressions::Filter trackFilter = nabs(aod::track::eta) < cfgEta && aod::track::pt > cfgPtmin&& aod::track::pt < cfgPtmax && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t)true)) && (aod::track::itsChi2NCl < cfgTrackCuts.cfgChi2PrITSCls) && (aod::track::tpcChi2NCl < cfgTrackCuts.cfgChi2PrTPCCls) && nabs(aod::track::dcaZ) < cfgTrackCuts.cfgDCAz; using GFWTracks = soa::Filtered>; // using GFWTracks = soa::Filtered>; @@ -1297,9 +1317,31 @@ struct FlowGenericFramework { if (cfgRunByRun) createRunByRunHistograms(run); } + + registry.fill(HIST("eventQA/eventSel"), 0.5); + if (cfgRunByRun) + th1sList[run][hEventSel]->Fill(0.5); + if (!collision.sel8()) return; + + registry.fill(HIST("eventQA/eventSel"), 1.5); + if (cfgRunByRun) + th1sList[run][hEventSel]->Fill(1.5); + const auto centrality = getCentrality(collision); + + if (cfgDoOccupancySel) { + int occupancy = collision.trackOccupancyInTimeRange(); + registry.fill(HIST("eventQA/before/occ_mult_cent"), occupancy, tracks.size(), centrality); + if (occupancy < 0 || occupancy > cfgOccupancySelection) + return; + registry.fill(HIST("eventQA/after/occ_mult_cent"), occupancy, tracks.size(), centrality); + } + registry.fill(HIST("eventQA/eventSel"), 2.5); + if (cfgRunByRun) + th1sList[run][hEventSel]->Fill(2.5); + if (cfgFillQA) fillEventQA(collision, tracks); if (!eventSelected(collision, tracks.size(), centrality, run)) diff --git a/PWGCF/GenericFramework/Tasks/flowGfwLightIons.cxx b/PWGCF/GenericFramework/Tasks/flowGfwLightIons.cxx index 6a82cf9c5b0..269fe53f84d 100644 --- a/PWGCF/GenericFramework/Tasks/flowGfwLightIons.cxx +++ b/PWGCF/GenericFramework/Tasks/flowGfwLightIons.cxx @@ -17,42 +17,61 @@ #include "FlowPtContainer.h" #include "GFW.h" #include "GFWConfig.h" -#include "GFWCumulant.h" -#include "GFWPowerArray.h" #include "GFWWeights.h" -#include "GFWWeightsList.h" -#include "Common/Core/TrackSelection.h" +#include "Common/CCDB/EventSelectionParams.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/runDataProcessing.h" #include +#include #include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include +#include +#include +#include #include #include #include +#include + +#include + +#include #include +#include +#include #include +#include +#include #include +#include #include -#include +#include #include +#include #include #include using namespace o2; using namespace o2::framework; +using namespace o2::analysis::genericframework; #define O2_DEFINE_CONFIGURABLE(NAME, TYPE, DEFAULT, HELP) Configurable NAME{#NAME, DEFAULT, HELP}; @@ -283,7 +302,7 @@ struct FlowGfwLightIons { TF1* fPtDepDCAxy = nullptr; o2::framework::expressions::Filter collisionFilter = nabs(aod::collision::posZ) < cfgVtxZ; - o2::framework::expressions::Filter trackFilter = nabs(aod::track::eta) < cfgEta && aod::track::pt > cfgPtmin&& aod::track::pt < cfgPtmax && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true)) && (aod::track::itsChi2NCl < cfgChi2PrITSCls) && (aod::track::tpcChi2NCl < cfgChi2PrTPCCls) && nabs(aod::track::dcaZ) < cfgDCAz; + o2::framework::expressions::Filter trackFilter = nabs(aod::track::eta) < cfgEta && aod::track::pt > cfgPtmin&& aod::track::pt < cfgPtmax && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t)true)) && (aod::track::itsChi2NCl < cfgChi2PrITSCls) && (aod::track::tpcChi2NCl < cfgChi2PrTPCCls) && nabs(aod::track::dcaZ) < cfgDCAz; Preslice perCollision = aod::track::collisionId; o2::framework::expressions::Filter mcCollFilter = nabs(aod::mccollision::posZ) < cfgVtxZ; diff --git a/PWGCF/JCorran/Core/FlowJHistManager.cxx b/PWGCF/JCorran/Core/FlowJHistManager.cxx index 880ec409dbd..a106d6cbf78 100644 --- a/PWGCF/JCorran/Core/FlowJHistManager.cxx +++ b/PWGCF/JCorran/Core/FlowJHistManager.cxx @@ -9,14 +9,13 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -// Header files. -#include +#include "PWGCF/JCorran/Core/FlowJHistManager.h" -// O2 headers. +#include +#include +#include -// O2 Physics headers. -#include "PWGCF/JCorran/Core/FlowJHistManager.h" -#include "CommonConstants/MathConstants.h" +#include // Namespaces. using namespace o2; diff --git a/PWGCF/JCorran/Core/FlowJHistManager.h b/PWGCF/JCorran/Core/FlowJHistManager.h index 3d70dd15ebc..48dda0937f4 100644 --- a/PWGCF/JCorran/Core/FlowJHistManager.h +++ b/PWGCF/JCorran/Core/FlowJHistManager.h @@ -15,21 +15,12 @@ #ifndef PWGCF_JCORRAN_CORE_FLOWJHISTMANAGER_H_ #define PWGCF_JCORRAN_CORE_FLOWJHISTMANAGER_H_ -/* Header files. */ -#include -#include -#include -#include -#include "TH1.h" -#include "TH2.h" -#include "TH3.h" -#include "TProfile.h" -#include "TProfile2D.h" +#include +#include -// O2 headers. // -#include "Framework/HistogramRegistry.h" +#include -// O2 Physics headers. +#include /* Namespaces. */ diff --git a/PWGCF/JCorran/Core/FlowJSPCAnalysis.cxx b/PWGCF/JCorran/Core/FlowJSPCAnalysis.cxx index 40585b3abec..0c1927d9579 100644 --- a/PWGCF/JCorran/Core/FlowJSPCAnalysis.cxx +++ b/PWGCF/JCorran/Core/FlowJSPCAnalysis.cxx @@ -9,13 +9,14 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -// Header files. +#include "PWGCF/JCorran/Core/FlowJSPCAnalysis.h" -// O2 headers. +#include +#include -// O2 Physics headers. +#include -#include "PWGCF/JCorran/Core/FlowJSPCAnalysis.h" +#include using namespace o2; using namespace o2::framework; diff --git a/PWGCF/JCorran/Core/FlowJSPCAnalysis.h b/PWGCF/JCorran/Core/FlowJSPCAnalysis.h index ba584d1e1eb..59a677dccd7 100644 --- a/PWGCF/JCorran/Core/FlowJSPCAnalysis.h +++ b/PWGCF/JCorran/Core/FlowJSPCAnalysis.h @@ -15,16 +15,23 @@ #ifndef PWGCF_JCORRAN_CORE_FLOWJSPCANALYSIS_H_ #define PWGCF_JCORRAN_CORE_FLOWJSPCANALYSIS_H_ -/* Header files. */ -#include -#include +#include "PWGCF/JCorran/Core/JQVectors.h" + +#include +#include +#include +#include + #include -#include +#include -// O2 headers. // -#include "Framework/HistogramRegistry.h" -#include "PWGCF/JCorran/Core/JQVectors.h" -#include "CommonConstants/MathConstants.h" +#include + +#include + +#include +#include +#include class FlowJSPCAnalysis { diff --git a/PWGCF/JCorran/Core/FlowJSPCObservables.h b/PWGCF/JCorran/Core/FlowJSPCObservables.h index 9fb479772d5..440d70c8bf2 100644 --- a/PWGCF/JCorran/Core/FlowJSPCObservables.h +++ b/PWGCF/JCorran/Core/FlowJSPCObservables.h @@ -15,10 +15,14 @@ #ifndef PWGCF_JCORRAN_CORE_FLOWJSPCOBSERVABLES_H_ #define PWGCF_JCORRAN_CORE_FLOWJSPCOBSERVABLES_H_ -// O2 headers. // -#include "Framework/HistogramRegistry.h" +#include + +#include + +#include const int maxNrComb = 12; + class FlowJSPCObservables { public: diff --git a/PWGCF/JCorran/Core/JCORRANLinkDef.h b/PWGCF/JCorran/Core/JCORRANLinkDef.h old mode 100755 new mode 100644 diff --git a/PWGCF/JCorran/Core/JEPFlowAnalysis.cxx b/PWGCF/JCorran/Core/JEPFlowAnalysis.cxx index 6d027002e8c..b4f01ff260c 100644 --- a/PWGCF/JCorran/Core/JEPFlowAnalysis.cxx +++ b/PWGCF/JCorran/Core/JEPFlowAnalysis.cxx @@ -11,6 +11,10 @@ #include "JEPFlowAnalysis.h" +#include + +#include + using namespace o2; using namespace o2::framework; using namespace std; diff --git a/PWGCF/JCorran/Core/JEPFlowAnalysis.h b/PWGCF/JCorran/Core/JEPFlowAnalysis.h index f1bc994099c..a4951a2e047 100644 --- a/PWGCF/JCorran/Core/JEPFlowAnalysis.h +++ b/PWGCF/JCorran/Core/JEPFlowAnalysis.h @@ -14,20 +14,21 @@ #ifndef PWGCF_JCORRAN_CORE_JEPFLOWANALYSIS_H_ #define PWGCF_JCORRAN_CORE_JEPFLOWANALYSIS_H_ -#include +#include +#include +#include -// O2 headers. // -#include "Framework/HistogramRegistry.h" +#include +#include -using namespace o2; -using namespace o2::framework; -using namespace std; +#include +#include class JEPFlowAnalysis { public: JEPFlowAnalysis() = default; - void SetHistRegistry(HistogramRegistry* histReg) { mHistRegistry = histReg; } + void SetHistRegistry(o2::framework::HistogramRegistry* histReg) { mHistRegistry = histReg; } void FillHistograms(const Int_t fCentBin, Float_t det, Float_t v2, Float_t v3, Float_t v4); void FillVnHistograms(const Int_t harmN, Float_t fCent, Float_t det, Float_t pT, Float_t vn, Float_t vn_sin); @@ -41,21 +42,21 @@ class JEPFlowAnalysis return; } - mHistRegistry->add("FullCentrality", "FullCentrality", HistType::kTH1D, {{100, 0., 100.}}, true); - mHistRegistry->add("fV2EP", "", {HistType::kTHnD, {{200, -1.05, 1.05}, {3, 0.5, 3.5}, {100, 0.2, 12.}, {20, 0., 100.}}}, true); // x: v2_cos, y: detector, z: pT, t: centrality - mHistRegistry->add("fV3EP", "", {HistType::kTHnD, {{200, -1.05, 1.05}, {3, 0.5, 3.5}, {100, 0.2, 12.}, {20, 0., 100.}}}, true); // x: v2_cos, y: detector, z: pT, t: centrality - mHistRegistry->add("fV4EP", "", {HistType::kTHnD, {{200, -1.05, 1.05}, {3, 0.5, 3.5}, {100, 0.2, 12.}, {20, 0., 100.}}}, true); // x: v2_cos, y: detector, z: pT, t: centrality - mHistRegistry->add("fV2EP_sin", "", {HistType::kTHnD, {{200, -1.05, 1.05}, {3, 0.5, 3.5}, {100, 0.2, 12.}, {20, 0., 100.}}}, true); // x: v2_sin, y: detector, z: pT, t: centrality - mHistRegistry->add("fV3EP_sin", "", {HistType::kTHnD, {{200, -1.05, 1.05}, {3, 0.5, 3.5}, {100, 0.2, 12.}, {20, 0., 100.}}}, true); // x: v2_sin, y: detector, z: pT, t: centrality - mHistRegistry->add("fV4EP_sin", "", {HistType::kTHnD, {{200, -1.05, 1.05}, {3, 0.5, 3.5}, {100, 0.2, 12.}, {20, 0., 100.}}}, true); // x: v2_sin, y: detector, z: pT, t: centrality - mHistRegistry->add("fResNumA", "", {HistType::kTH3D, {{100, -1.05, 1.05}, {3, 1.5, 4.5}, {20, 0., 100.}}}, true); // x: resolution, y: harmonic, t: centrality - mHistRegistry->add("fResNumB", "", {HistType::kTH3D, {{100, -1.05, 1.05}, {3, 1.5, 4.5}, {20, 0., 100.}}}, true); // x: resolution, y: harmonic, t: centrality - mHistRegistry->add("fResDenom", "", {HistType::kTH3D, {{100, -1.05, 1.05}, {3, 1.5, 4.5}, {20, 0., 100.}}}, true); // x: resolution, y: harmonic, t: centrality - mHistRegistry->add("phi", "Phi", {HistType::kTH1D, {{100, 0., TMath::TwoPi()}}}, true); + mHistRegistry->add("FullCentrality", "FullCentrality", o2::framework::HistType::kTH1D, {{100, 0., 100.}}, true); + mHistRegistry->add("fV2EP", "", {o2::framework::HistType::kTHnD, {{200, -1.05, 1.05}, {3, 0.5, 3.5}, {100, 0.2, 12.}, {20, 0., 100.}}}, true); // x: v2_cos, y: detector, z: pT, t: centrality + mHistRegistry->add("fV3EP", "", {o2::framework::HistType::kTHnD, {{200, -1.05, 1.05}, {3, 0.5, 3.5}, {100, 0.2, 12.}, {20, 0., 100.}}}, true); // x: v2_cos, y: detector, z: pT, t: centrality + mHistRegistry->add("fV4EP", "", {o2::framework::HistType::kTHnD, {{200, -1.05, 1.05}, {3, 0.5, 3.5}, {100, 0.2, 12.}, {20, 0., 100.}}}, true); // x: v2_cos, y: detector, z: pT, t: centrality + mHistRegistry->add("fV2EP_sin", "", {o2::framework::HistType::kTHnD, {{200, -1.05, 1.05}, {3, 0.5, 3.5}, {100, 0.2, 12.}, {20, 0., 100.}}}, true); // x: v2_sin, y: detector, z: pT, t: centrality + mHistRegistry->add("fV3EP_sin", "", {o2::framework::HistType::kTHnD, {{200, -1.05, 1.05}, {3, 0.5, 3.5}, {100, 0.2, 12.}, {20, 0., 100.}}}, true); // x: v2_sin, y: detector, z: pT, t: centrality + mHistRegistry->add("fV4EP_sin", "", {o2::framework::HistType::kTHnD, {{200, -1.05, 1.05}, {3, 0.5, 3.5}, {100, 0.2, 12.}, {20, 0., 100.}}}, true); // x: v2_sin, y: detector, z: pT, t: centrality + mHistRegistry->add("fResNumA", "", {o2::framework::HistType::kTH3D, {{100, -1.05, 1.05}, {3, 1.5, 4.5}, {20, 0., 100.}}}, true); // x: resolution, y: harmonic, t: centrality + mHistRegistry->add("fResNumB", "", {o2::framework::HistType::kTH3D, {{100, -1.05, 1.05}, {3, 1.5, 4.5}, {20, 0., 100.}}}, true); // x: resolution, y: harmonic, t: centrality + mHistRegistry->add("fResDenom", "", {o2::framework::HistType::kTH3D, {{100, -1.05, 1.05}, {3, 1.5, 4.5}, {20, 0., 100.}}}, true); // x: resolution, y: harmonic, t: centrality + mHistRegistry->add("phi", "Phi", {o2::framework::HistType::kTH1D, {{100, 0., TMath::TwoPi()}}}, true); } private: - HistogramRegistry* mHistRegistry; + o2::framework::HistogramRegistry* mHistRegistry; ClassDefNV(JEPFlowAnalysis, 1); }; diff --git a/PWGCF/JCorran/Core/JFFlucAnalysis.cxx b/PWGCF/JCorran/Core/JFFlucAnalysis.cxx index 4c3b01adeca..2ed70c0eb15 100644 --- a/PWGCF/JCorran/Core/JFFlucAnalysis.cxx +++ b/PWGCF/JCorran/Core/JFFlucAnalysis.cxx @@ -15,7 +15,9 @@ #include "JFFlucAnalysis.h" #include -#include +#include + +#include #include diff --git a/PWGCF/JCorran/Core/JFFlucAnalysis.h b/PWGCF/JCorran/Core/JFFlucAnalysis.h index b728c809173..5417ef8f9d7 100644 --- a/PWGCF/JCorran/Core/JFFlucAnalysis.h +++ b/PWGCF/JCorran/Core/JFFlucAnalysis.h @@ -23,6 +23,9 @@ #include #include +#include +#include + #include #include diff --git a/PWGCF/JCorran/Core/JFFlucAnalysisO2Hist.cxx b/PWGCF/JCorran/Core/JFFlucAnalysisO2Hist.cxx index 0439b5e2931..4833838b078 100644 --- a/PWGCF/JCorran/Core/JFFlucAnalysisO2Hist.cxx +++ b/PWGCF/JCorran/Core/JFFlucAnalysisO2Hist.cxx @@ -13,10 +13,20 @@ #include "JFFlucAnalysisO2Hist.h" +#include "JFFlucAnalysis.h" + #include "PWGCF/DataModel/CorrelationsDerived.h" -#include "CommonConstants/MathConstants.h" +#include +#include + +#include +#include +#include + +#include +#include #include #include diff --git a/PWGCF/JCorran/Core/JFFlucAnalysisO2Hist.h b/PWGCF/JCorran/Core/JFFlucAnalysisO2Hist.h index 3bc0a1a225e..60d4471b846 100644 --- a/PWGCF/JCorran/Core/JFFlucAnalysisO2Hist.h +++ b/PWGCF/JCorran/Core/JFFlucAnalysisO2Hist.h @@ -16,7 +16,12 @@ #include "JFFlucAnalysis.h" -#include "Framework/HistogramRegistry.h" +#include +#include + +#include + +#include class JFFlucAnalysisO2Hist : public JFFlucAnalysis { diff --git a/PWGCF/JCorran/Core/JQVectors.h b/PWGCF/JCorran/Core/JQVectors.h index 01693ae6073..d0ba705c32f 100644 --- a/PWGCF/JCorran/Core/JQVectors.h +++ b/PWGCF/JCorran/Core/JQVectors.h @@ -15,9 +15,13 @@ #ifndef PWGCF_JCORRAN_CORE_JQVECTORS_H_ #define PWGCF_JCORRAN_CORE_JQVECTORS_H_ -#include #include +#include + +#include +#include + template class JQVectorsGapBase { diff --git a/PWGCF/JCorran/DataModel/JCatalyst.h b/PWGCF/JCorran/DataModel/JCatalyst.h index 71797429589..bc21b43411a 100644 --- a/PWGCF/JCorran/DataModel/JCatalyst.h +++ b/PWGCF/JCorran/DataModel/JCatalyst.h @@ -11,9 +11,15 @@ /// \author Jasper Parkkila (jparkkil@cern.ch) /// \author Dong Jo Kim (djkim@jyu.fi) /// \since Sep 2022 + #ifndef PWGCF_JCORRAN_DATAMODEL_JCATALYST_H_ #define PWGCF_JCORRAN_DATAMODEL_JCATALYST_H_ +#include +#include + +#include + namespace o2::aod { namespace jcollision diff --git a/PWGCF/JCorran/TableProducer/JCatalyst.cxx b/PWGCF/JCorran/TableProducer/JCatalyst.cxx index e0cb26994e3..be6e9b41874 100644 --- a/PWGCF/JCorran/TableProducer/JCatalyst.cxx +++ b/PWGCF/JCorran/TableProducer/JCatalyst.cxx @@ -12,40 +12,30 @@ /// \author Dong Jo Kim (djkim@jyu.fi) /// \since Sep 2022 -#include -#include -#include -#include - -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/ASoAHelpers.h" - -// centrality -#include "Common/DataModel/Multiplicity.h" +#include "PWGCF/JCorran/DataModel/JCatalyst.h" + +#include "Common/CCDB/TriggerAliases.h" +#include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "Common/DataModel/Centrality.h" - -////TODO: remove redundant: -#include "Framework/HistogramRegistry.h" -#include "DCAFitter/DCAFitterN.h" -#include "PWGHF/DataModel/CandidateReconstructionTables.h" -#include "Common/Core/trackUtilities.h" -#include "ReconstructionDataFormats/DCA.h" -#include "ReconstructionDataFormats/V0.h" -//// +#include +#include +#include +#include +#include +#include +#include +#include +#include -#include "PWGCF/JCorran/DataModel/JCatalyst.h" +#include using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; using namespace ROOT; -using namespace ROOT::Math; #define O2_DEFINE_CONFIGURABLE(NAME, TYPE, DEFAULT, HELP) Configurable NAME{#NAME, DEFAULT, HELP}; @@ -75,7 +65,7 @@ struct JCatalyst { Filter collisionVertexTypeFilter = (collisionFlags == 0) || ((aod::collision::flags & collisionFlags) == collisionFlags); Filter trackFilter = (nabs(aod::track::eta) < etamax) && (aod::track::pt > ptmin) && (aod::track::pt < ptmax); - Filter trackSelection = (requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true); + Filter trackSelection = (requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t)true); Produces particleTrack; Produces collisionData; @@ -116,7 +106,7 @@ struct JMultiplicitySelector { O2_DEFINE_CONFIGURABLE(etamax, float, 0.9f, "Eta range for tracks") Filter trackFilter = (nabs(aod::track::eta) < etamax) && (aod::track::pt > ptmin); - Filter trackSelection = (requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true); + Filter trackSelection = (requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t)true); void processTracks(aod::Collision const&, soa::Filtered> const& tracks) { diff --git a/PWGCF/JCorran/Tasks/flowJNUACreation.cxx b/PWGCF/JCorran/Tasks/flowJNUACreation.cxx index 31edc2a7c3d..0ac9d45b2e8 100644 --- a/PWGCF/JCorran/Tasks/flowJNUACreation.cxx +++ b/PWGCF/JCorran/Tasks/flowJNUACreation.cxx @@ -12,31 +12,30 @@ // \brief Task for the NUA correction with filtered data. // \author Maxim Virta (maxim.virta@cern.ch) -// Standard headers. -#include -#include -#include -#include - -// O2 headers. // -// The first two are mandatory. -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" - -#include "Framework/AnalysisDataModel.h" -#include "Framework/ASoAHelpers.h" -#include "CCDB/BasicCCDBManager.h" -#include "Framework/HistogramRegistry.h" +#include "PWGCF/JCorran/Core/FlowJHistManager.h" -// O2 Physics headers. // +#include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/FT0Corrected.h" #include "Common/DataModel/Multiplicity.h" -#include "Common/DataModel/Centrality.h" -#include "Common/Core/TrackSelection.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "PWGCF/JCorran/Core/FlowJHistManager.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include // Namespaces and definitions. using namespace o2; diff --git a/PWGCF/JCorran/Tasks/flowJSPCAnalysis.cxx b/PWGCF/JCorran/Tasks/flowJSPCAnalysis.cxx index 380de913181..6892ab58658 100644 --- a/PWGCF/JCorran/Tasks/flowJSPCAnalysis.cxx +++ b/PWGCF/JCorran/Tasks/flowJSPCAnalysis.cxx @@ -13,37 +13,40 @@ /// \brief Task for the calculation of SPC with filtered data. /// \author Maxim Virta (maxim.virta@cern.ch), Cindy Mordasini (cindy.mordasini@cern.ch), Neelkamal Mallick (neelkamal.mallick@cern.ch) -// Standard headers. -#include -#include - -#include -#include -#include -#include - -// O2 headers. // -// The first two are mandatory. -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" +#include "PWGCF/JCorran/Core/FlowJSPCAnalysis.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/HistogramRegistry.h" +#include "PWGCF/DataModel/CorrelationsDerived.h" +#include "PWGCF/JCorran/Core/FlowJHistManager.h" +#include "PWGCF/JCorran/Core/FlowJSPCObservables.h" +#include "PWGCF/JCorran/DataModel/JCatalyst.h" -// O2 Physics headers. // +#include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/FT0Corrected.h" #include "Common/DataModel/Multiplicity.h" -#include "Common/DataModel/Centrality.h" -#include "Common/Core/TrackSelection.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "PWGCF/DataModel/CorrelationsDerived.h" -#include "PWGCF/JCorran/DataModel/JCatalyst.h" -#include "PWGCF/JCorran/Core/FlowJSPCAnalysis.h" -#include "PWGCF/JCorran/Core/FlowJSPCObservables.h" -#include "PWGCF/JCorran/Core/FlowJHistManager.h" +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include // Namespaces and definitions. using namespace o2; diff --git a/PWGCF/JCorran/Tasks/jEPDzeroFlowAnalysis.cxx b/PWGCF/JCorran/Tasks/jEPDzeroFlowAnalysis.cxx index be132b44684..0240170f245 100644 --- a/PWGCF/JCorran/Tasks/jEPDzeroFlowAnalysis.cxx +++ b/PWGCF/JCorran/Tasks/jEPDzeroFlowAnalysis.cxx @@ -11,52 +11,29 @@ /// \author junlee.kim@cern.ch /// \since Jul 2024 -#include -#include -#include -#include -#include -#include -#include - -#include "TLorentzVector.h" -#include "TRandom3.h" -#include "TF1.h" -#include "TVector2.h" -#include "Math/Vector3D.h" -#include "Math/Vector4D.h" -#include "Math/GenVector/Boost.h" -#include - -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/StepTHn.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/StaticFor.h" +#include "PWGCF/DataModel/CorrelationsDerived.h" +#include "Common/CCDB/EventSelectionParams.h" +#include "Common/Core/EventPlaneHelper.h" #include "Common/DataModel/Centrality.h" -#include "Common/DataModel/TrackSelectionTables.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Qvectors.h" -#include "Common/Core/trackUtilities.h" -#include "Common/Core/TrackSelection.h" -#include "Common/Core/EventPlaneHelper.h" - -#include "CommonConstants/PhysicsConstants.h" - -#include "ReconstructionDataFormats/Track.h" +#include +#include +#include +#include +#include +#include +#include +#include -#include "DataFormatsParameters/GRPObject.h" -#include "DataFormatsParameters/GRPMagField.h" +#include -#include "CCDB/CcdbApi.h" -#include "CCDB/BasicCCDBManager.h" - -#include "PWGCF/DataModel/CorrelationsDerived.h" +#include +#include +#include +#include using namespace std; using namespace o2; diff --git a/PWGCF/JCorran/Tasks/jEPFlowAnalysis.cxx b/PWGCF/JCorran/Tasks/jEPFlowAnalysis.cxx index 2853dd5d089..6411c6866ff 100644 --- a/PWGCF/JCorran/Tasks/jEPFlowAnalysis.cxx +++ b/PWGCF/JCorran/Tasks/jEPFlowAnalysis.cxx @@ -16,22 +16,37 @@ #include "FlowJHistManager.h" +#include "Common/CCDB/EventSelectionParams.h" #include "Common/Core/EventPlaneHelper.h" -#include "Common/Core/TrackSelection.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Qvectors.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "CCDB/BasicCCDBManager.h" -#include "CCDB/CcdbApi.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/runDataProcessing.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include +#include +#include + +#include +#include +#include #include #include @@ -76,6 +91,7 @@ struct jEPFlowAnalysis { Configurable cfgEffCor{"cfgEffCor", false, "flag for efficiency correction"}; Configurable cfgEffCorDir{"cfgEffCorDir", "Users/n/nmallick/Run3OO/Eff/LHC25h3b_FT0C", "path for efficiency correction"}; + Configurable cfgTrkSelFlag{"cfgTrkSelFlag", true, "flag for track selection"}; Configurable cfgSystStudy{"cfgSystStudy", false, "flag for syst study"}; Configurable cfgITSNCls{"cfgITSNCls", 5, "minimum number of its clusters"}; Configurable cfgTPCNclsCR{"cfgTPCNclsCR", 70, "minimum number of tpc cluster crossed rows"}; @@ -278,7 +294,7 @@ struct jEPFlowAnalysis { epFlowHistograms.fill(HIST("EpResQvecRefARefBxy"), i + 2, cent, qx_shifted[2] * qy_shifted[1] - qx_shifted[1] * qy_shifted[2]); for (const auto& track : tracks) { - if (trackSel(track)) + if (cfgTrkSelFlag && trackSel(track)) continue; if (cfgEffCor) { diff --git a/PWGCF/JCorran/Tasks/jFlucEfficiencyTask.cxx b/PWGCF/JCorran/Tasks/jFlucEfficiencyTask.cxx index 70f9b1a8390..cce681dd45c 100644 --- a/PWGCF/JCorran/Tasks/jFlucEfficiencyTask.cxx +++ b/PWGCF/JCorran/Tasks/jFlucEfficiencyTask.cxx @@ -17,21 +17,31 @@ #include "PWGCF/DataModel/CorrelationsDerived.h" #include "PWGLF/Utils/collisionCuts.h" -#include "Common/Core/TrackSelection.h" +#include "Common/CCDB/RCTSelectionFlags.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "CommonConstants/PhysicsConstants.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "Framework/runDataProcessing.h" - +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include #include +#include +#include +#include +#include #include #include diff --git a/PWGCF/JCorran/Tasks/jflucAnalysisTask.cxx b/PWGCF/JCorran/Tasks/jflucAnalysisTask.cxx index c6a213163d5..d9d8d8bf9a7 100644 --- a/PWGCF/JCorran/Tasks/jflucAnalysisTask.cxx +++ b/PWGCF/JCorran/Tasks/jflucAnalysisTask.cxx @@ -12,34 +12,36 @@ /// \author Dong Jo Kim (djkim@jyu.fi) /// \since Sep 2022 -#include "Common/Core/TrackSelection.h" -#include "Common/DataModel/Centrality.h" -#include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/TrackSelectionTables.h" +#include "JFFlucAnalysis.h" +#include "JFFlucAnalysisO2Hist.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/RunningWorkflowInfo.h" -#include "ReconstructionDataFormats/V0.h" +#include "PWGCF/DataModel/CorrelationsDerived.h" +#include "PWGCF/JCorran/DataModel/JCatalyst.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include + +#include #include +#include +#include #include +#include +#include #include #include -// #include "CCDB/BasicCCDBManager.h" - -#include "JFFlucAnalysis.h" -#include "JFFlucAnalysisO2Hist.h" - -#include "PWGCF/DataModel/CorrelationsDerived.h" -#include "PWGCF/JCorran/DataModel/JCatalyst.h" - -#include "Framework/runDataProcessing.h" - using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; diff --git a/PWGCF/JCorran/Tasks/jflucWeightsLoader.cxx b/PWGCF/JCorran/Tasks/jflucWeightsLoader.cxx index 9fbea5ed78a..02088eab148 100644 --- a/PWGCF/JCorran/Tasks/jflucWeightsLoader.cxx +++ b/PWGCF/JCorran/Tasks/jflucWeightsLoader.cxx @@ -18,24 +18,26 @@ #include "PWGCF/DataModel/CorrelationsDerived.h" #include "PWGCF/JCorran/DataModel/JCatalyst.h" -#include "Common/Core/TrackSelection.h" -#include "Common/DataModel/Centrality.h" -#include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/TrackSelectionTables.h" - -#include "CCDB/BasicCCDBManager.h" -#include "CommonConstants/MathConstants.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/runDataProcessing.h" -#include "ReconstructionDataFormats/V0.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include -#include +#include + +#include #include #include diff --git a/PWGCF/MultiparticleCorrelations/Tasks/multiparticle-correlations-ab.cxx b/PWGCF/MultiparticleCorrelations/Tasks/multiparticle-correlations-ab.cxx index 2149497f2fc..0d65294f05f 100644 --- a/PWGCF/MultiparticleCorrelations/Tasks/multiparticle-correlations-ab.cxx +++ b/PWGCF/MultiparticleCorrelations/Tasks/multiparticle-correlations-ab.cxx @@ -13,20 +13,66 @@ /// \brief ... TBI 20250425 /// \author Ante.Bilandzic@cern.ch -// O2: +#include "Common/CCDB/EventSelectionParams.h" +#include "Common/CCDB/RCTSelectionFlags.h" +#include "Common/CCDB/TriggerAliases.h" #include "Common/CCDB/ctpRateFetcher.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/TrackSelectionTables.h" // needed for aod::TracksDCA table -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/DataTypes.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "Framework/runDataProcessing.h" #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; using namespace o2; using namespace o2::framework; @@ -74,35 +120,618 @@ using BCs_QA = soa::Join; using Collision_QA = CollisionRec; // if I would need additional tables for QA, just join 'em here with CollisionRec using TracksRec_QA = TracksRec; // if I would need additional tables for QA, just join 'em here with TracksRec -// *) ROOT: -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +// *) Enums: -#include +enum eConfiguration { + eTaskIsConfiguredFromJson = 1, // here I start from 1 exceptionally, because these enums are used as bin contents, and ROOT starts counting bins from 1 + eTaskName, + eRunNumber, + eDryRun, + eVerbose, + eVerboseUtility, + eVerboseForEachParticle, + eVerboseEventCounter, + ePlainPrintout, + eDoAdditionalInsanityChecks, + eInsanityCheckForEachParticle, + eWhichProcess, + eRandomSeed, + eUseFisherYates, + eFixedNumberOfRandomlySelectedTracks, + eUseStopwatch, + eFloatingPointPrecision, + eSequentialBailout, + eUseSpecificCuts, + eWhichSpecificCuts, + eSkipTheseRuns, + eUseSetBinLabel, // Use or not ->SetBinLabel(...) + eUseClone, // Use or not ->Clone() + eUseFormula, // Use or not class TFormula + eUseDatabasePDG, // Use or not class TDatabasePDG + eConfiguration_N +}; -#include -using namespace std; +enum eProcess { + eProcessRec = 0, // Run 3, only reconstructed + eProcessRecSim, // Run 3, both reconstructed and simulated + eProcessSim, // Run 3, only simulated + eProcessRec_Run2, // Run 2, only reconstructed + eProcessRecSim_Run2, // Run 2, both reconstructed and simulated + eProcessSim_Run2, // Run 2, only simulated + eProcessRec_Run1, // Run 1, only reconstructed + eProcessRecSim_Run1, // Run 1, both reconstructed and simulated + eProcessSim_Run1, // Run 1, only simulated + eProcessTest, // minimum subscription to the tables, for testing purposes + eProcessQA, // maximum subscription to the tables, for QA purposes. Basically: eProcessRec + otherwise unnecessary tables + eProcessHepMChi, // special subscription when I extract info from the table HepMCHeavyIons TBI 20250429 merge this case eventually with RecSim cases + // Generic flags, calculated and set from individual flags above in DefaultConfiguration(), AFTER process switch was taken into account: + eGenericRec, // generic "Rec" case, eTest is treated for the time being as "Rec". eQA is also in this category + eGenericRecSim, // generic "RecSim" case + eGenericSim, // generic "Sim" case + eProcess_N +}; -// *) Enums: -#include "PWGCF/MultiparticleCorrelations/Core/MuPa-Enums.h" +enum eRecSim { eRec = 0, + eSim, + eRecAndSim, + eRec_Run2, // converted Run 2 data + eSim_Run2, + eRecAndSim_Run2, + eRec_Run1, // converted Run 1 data + eSim_Run1, + eRecAndSim_Run1, + eTest, // remember that as of 20250315 I can use "cfWhichSpecificCuts": "Test" in JSON, to configure quickly all cuts for this case + eQA }; + +enum eBeforeAfter { eBefore = 0, // use this one for cuts + eAfter = 1 }; + +enum eMinMax { eMin = 0, + eMax = 1 }; + +enum eXYZ { eX = 0, + eY = 1, + eZ = 2 }; + +enum eDefaultColors { eColor = kBlack, + eFillColor = kGray }; + +enum eWeights { wPHI = 0, + wPT = 1, + wETA = 2, + wCHARGE = 3, + eWeights_N }; + +enum eDiffWeights { // TBI 20250215 this is now obsolete, superseeded with more general implementation, see enums eDiffWeightCategory, eDiffPhiWeights, etc. + wPHIPT = 0, + wPHIETA, + wPHICHARGE, + eDiffWeights_N +}; + +enum eDiffWeightCategory { + eDWPhi = 0, // corresponds to eDiffPhiWeights structure, here the fundamental 0-th axis never to be projected out is "phi" + eDWPt, // corresponds to eDiffPtWeights structure, here the fundamental 0-th axis never to be projected out is "pt" + eDWEta, // corresponds to eDiffEtaWeights structure, here the fundamental 0-th axis never to be projected out is "eta" + // ... + eDiffWeightCategory_N +}; + +enum eDiffPhiWeights { + wPhiPhiAxis = 0, // this is the main axis in this category, the only axis which shall never be projected out. If I project out all remaining axes, I shall recover the standard integrated phi weights + wPhiPtAxis, + wPhiEtaAxis, + wPhiChargeAxis, + wPhiCentralityAxis, + wPhiVertexZAxis, + eDiffPhiWeights_N +}; + +enum eDiffPtWeights { // if i add new entry here, or in eDiffPhiWeights and eDiffEtaWeights, I need to update also GetParticleWeights() + wPtPtAxis = 0, + wPtEtaAxis, + wPtChargeAxis, + wPtCentralityAxis, + eDiffPtWeights_N +}; + +enum eDiffEtaWeights { + wEtaEtaAxis = 0, + wEtaPtAxis, + wEtaChargeAxis, + wEtaCentralityAxis, + eDiffEtaWeights_N +}; + +enum eVnPsin { eVn = 0, + ePsin = 1 }; + +enum eEventHistograms { + eNumberOfEvents = 0, // Total events = eNumberOfEvents + eBefore, Selected events = eNumberOfEvents + eAfter + eTotalMultiplicity, // TBI 20241123 I define it as tracks.size(), but most likely I do not need this + eMultiplicity, // see documentation for ebye.fMultiplicity + eReferenceMultiplicity, // see documentation for ebye.fReferenceMultiplicity + eCentrality, // default centrality estimator + eVertexX, + eVertexY, + eVertexZ, + eNContributors, // number of tracks used for the vertex + eImpactParameter, + eEventPlaneAngle, + eOccupancy, // from helper task o2-analysis-event-selection, see also IA's presentation in https://indico.cern.ch/event/1464946, slide 38. Use specific occupancy estimator via eOccupancyEstimator + eInteractionRate, // from utility ctpRateFetcher . + eCurrentRunDuration, // calculated with utility ctpRateFetcher + eMultMCNParticlesEta08, // from helper task table o2::aod::MultMCExtras + eEventHistograms_N +}; + +enum eEventCuts { + // a) For available event selection bits, check https://github.com/AliceO2Group/O2Physics/blob/master/Common/CCDB/EventSelectionParams.cxx (and .h for better documentation) + // b) Some settings are configurable, check: https://github.com/AliceO2Group/O2Physics/blob/master/Common/TableProducer/eventSelection.cxx + eTrigger = eEventHistograms_N, // Implemented and validated so far: + // a) Run 3: "kTVXinTRD" (use optionally for systematics, and only in real data) + // b) Run 2: "kINT7" (at the moment there is a warning if not used in real data.). Not validated in Monte Carlo. + // c) Run 1: TBI 20241209 check if I can use kINT7 also for Run 1 + eSel7, // See def. of sel7 in Ref. b) above. Event selection decision based on V0A & V0C => use only in Run 2 and Run 1. + // TBI 20250115 it removes 99% of events in MC LHC21i6a, check this further + eSel8, // See def. of sel8 in Ref. b) above. Event selection decision based on TVX => use only in Run 3, both for data and MC + // *) As of 20240410, kNoITSROFrameBorder (only in MC) and kNoTimeFrameBorder event selection cuts are part of Sel8 + // See also email from EK from 2024041 + eMultiplicityEstimator, // see documentation for ebye.fMultiplicity + eReferenceMultiplicityEstimator, // see documentation for ebye.fReferenceMultiplicity + eCentralityEstimator, // the default centrality estimator, set via configurable. All supported centrality estimators, for QA, etc, are in enum eCentralityEstimators + eSelectedEvents, // selected events = eNumberOfEvents + eAfter => therefore I do not need a special histogram for it + eNoSameBunchPileup, // reject collisions in case of pileup with another collision in the same foundBC (emails from IA on 20240404 and EK on 20240410) + eIsGoodZvtxFT0vsPV, // small difference between z-vertex from PV and from FT0 (emails from IA on 20240404 and EK on 20240410) + // Avoid using kIsGoodZvtxFT0vsPV selection bit for Pb-Pb 2024 apass1, see IA email from 20250115. + // Therefore, until further notice, use this one in LHC23zzh, but not in LHC24ar and LHC24as + eIsVertexITSTPC, // at least one ITS-TPC track (reject vertices built from ITS-only tracks) (emails from IA on 20240404 and EK on 20240410 + eIsVertexTOFmatched, // at least one of vertex contributors is matched to TOF + eIsVertexTRDmatched, // at least one of vertex contributors is matched to TRD + eNoCollInTimeRangeStrict, // rejects a collision if there are other events in dtime +/- 10 μs, see IA Slide 39 in https://indico.cern.ch/event/1462154/ + // 20250122 Per feedback from IA, use this one only as a part of systematic check, and use eNoCollInTimeRangeStandard by default + eNoCollInTimeRangeStandard, // rejects a collision if there are other events in dtime +/- 2 μs + additional cuts on multiplicity, see IA Slide 39 in https://indico.cern.ch/event/1462154/ + eNoCollInRofStrict, // rejects a collision if there are other events within the same ROF (in-ROF pileup), ROF = "ITS Readout Frames", + // see IA Slide 39 in https://indico.cern.ch/event/1462154/ + // 20250122 Per feedback from IA, use this one only as a part of systematic check, and use eNoCollInRofStandard by default + eNoCollInRofStandard, // same as previous + additional cuts on multiplicity, see IA Slide 39 in https://indico.cern.ch/event/1462154/ + eNoHighMultCollInPrevRof, // veto an event if FT0C amplitude in previous ITS ROF is above threshold (default is >5000 a.e. by FT0C), see IA Slide 39 in https://indico.cern.ch/event/1462154/ + // 20250122 Per feedback from IA, use it only in 2023 PbPb data (e.g. eLHC23zzh), in 2024 PbPb data this one has no effect (do not use in eLHC24ar and eLHC24as) + eIsGoodITSLayer3, // number of inactive chips on ITS layer 3 is below maximum allowed value + eIsGoodITSLayer0123, // numbers of inactive chips on ITS layers 0-3 are below maximum allowed values + eIsGoodITSLayersAll, // numbers of inactive chips on all ITS layers are below maximum allowed values + eOccupancyEstimator, // the default Occupancy estimator, set via configurable. All supported centrality estimators, for QA, etc, are in enum eOccupancyEstimators + eMinVertexDistanceFromIP, // if sqrt(vx^2+vy^2+vz^2) < MinVertexDistanceFromIP, the event is rejected. This way, I remove suspicious events with |vertex| = 0. + eNoPileupTPC, // no pileup in TPC + eNoPileupFromSPD, // no pileup according to SPD vertexer + eNoSPDOnVsOfPileup, // no out-of-bunch pileup according to online-vs-offline SPD correlation + eRefMultVsNContrUp, // formula for upper boundary cut in eReferenceMultiplicity_vs_NContributors (remember that I use naming convention "x_vs_y") + eRefMultVsNContrLow, // formula for lower boundary cut in eReferenceMultiplicity_vs_NContributors (remember that I use naming convention "x_vs_y") + eCentralityCorrelationsCut, // port of void SetCentralityCorrelationsCuts(...) from MuPa class. Example format: "CentFT0C_CentFT0M", so IFS is "_", until proven otherwise + + // RCT flags, see https://indico.cern.ch/event/1545907/ + up-to-date code in Common/CCDB/RCTSelectionFlags.h + // Remark 1: For the time being, I support here differentially 6 flags used to define the combined "CBT" flag, see if (label == "CBT") in Common/CCDB/RCTSelectionFlags.h + // Remark 2: If I want to use directly the combined "CBT" flag, see how it can be done using RCTFlagsChecker in + // https://github.com/AliceO2Group/O2Physics/blob/master/DPG/Tasks/AOTEvent/timeDependentQa.cxx#L115 + // But check before the memory status after RCTFlagsChecker is used. + eFT0Bad, + eITSBad, + eITSLimAccMCRepr, + eTPCBadTracking, + eTPCLimAccMCRepr, + eTPCBadPID, + // ... + eCentralityWeights, // used for centrality flattening. Remember that this event cut must be implemented very last, + // therefore I have it separately implemented for Run 3,2,1 in EventCuts() at the very end in each case. + // Use only for small non-uniformity in centrality distribution (e.g. of the biggest dip in distribution is up to 20% compared to uniform part of cent. distribution), + // otherwise this flattening is too costly in terms of statistics. + eEventCuts_N +}; + +enum eEventCutsFormulas { // special treatment for all event cuts defined via mathematical formula, because for them I have to do one additional layer of booking using TFormula + eRefMultVsNContrUp_Formula = 0, + eRefMultVsNContrLow_Formula, + eEventCutsFormulas_N +}; + +enum eParticleHistograms { + + // from o2::aod::Tracks (Track parameters at their point closest to the collision vertex) + ePhi = 0, + ePt, + eEta, + eCharge, // Charge: positive: 1, negative: -1 + + // from o2::aod::TracksExtra_001 - I keep the ordering here the same as in the TracksExtra_001 table + etpcNClsFindable, + etpcNClsShared, + eitsChi2NCl, // TBI 20250110 I see for this one [478682:track-selection]: [15:35:00][INFO] Track selection, set max chi2 per cluster ITS: 36 + // But even with open particle cuts, this distribution doesn't cross 30... There is a sudden drop round 22, but when I apply other cuts + // that tail is gone already. + etpcNClsFound, + etpcNClsCrossedRows, + eitsNCls, + eitsNClsInnerBarrel, + etpcCrossedRowsOverFindableCls, + etpcFoundOverFindableCls, // TBI 20250110 I keep this one in sync with values for etpcCrossedRowsOverFindableCls + etpcFractionSharedCls, + etpcChi2NCl, // TBI 20250110 this one shall resemble aodTrack->GetTPCchi2()/aodTrack->GetTPCNcls(), but cross-check with the experts. Particles with tpcChi2NCl > 4. I reject now by default. + // See what I documented in AliPhysics below // task->SetParticleCuts("TPCChi2perNDF",4.,-44); // VAL + // 20250123 in some Run 2 analysis, 2.5 was used as a default. Check that value as a part of systematics + // from o2::aod::TracksDCA + edcaXY, + edcaZ, + + // the rest: + ePDG, + + // counter: + eParticleHistograms_N +}; + +enum eParticleHistograms2D { // All 2D histograms are first implemented in eQAParticleHistograms2D, the ones which I need regularly, are then promoted to this category. + ePhiPt = 0, + ePhiEta, + eParticleHistograms2D_N +}; + +enum eParticleCuts { + + // from o2::aod::TrackSelection (https://aliceo2group.github.io/analysis-framework/docs/datamodel/helperTaskTables.html#o2-analysis-trackselection) + // See also O2Physics/Common/DataModel/TrackSelectionTables.h + etrackCutFlag = eParticleHistograms_N, // General selection, with centrally tuned particle cuts for tpcNClsFound, itsNCls, etc. + // As of 20250113, this cut still has not effect, neither in Run 3 nor in converted Run 2. Use instead trackCutFlagFb1 and/or trackCutFlagFb2 below. + etrackCutFlagFb1, // Global tracks in Run 3. Closest possible match to global track definition in Run 2, which are selected with eisGlobalTrack. + // For the definition, see: + // a) "filtbit1" in https://github.com/AliceO2Group/O2Physics/blob/master/Common/TableProducer/trackselection.cxx#L128 + // b) "getGlobalTrackSelectionRun3ITSMatch" in https://github.com/AliceO2Group/O2Physics/blob/master/Common/Core/TrackSelectionDefaults.cxx#L43 + // When I use this flag, make sure I do NOT cut on something on which this cut is already cutting by default (e.g. pt-dependent DCA xy cut) + etrackCutFlagFb2, // Global tracks in Run 3, similar as etrackCutFlagFb1, but more stringent (since 2 points in ITS are required in inner barrel (IB)). + // Unlike etrackCutFlagFb1 (1 ITS point is required), it produces a 20% dip in azimuthal acceptance for 1.2 < phi < 1.6, in LHC24ar/559545 + // DCAxy and z are significantly further depleted, when compared to etrackCutFlagFb1 + eisQualityTrack, // Do not use in Run 3, but it can be used in Run 2 and Run 1 + // In Run 2, it is already requested in isGlobalTrack, through definition kGlobalTrack = kQualityTracks | kPrimaryTracks | kInAcceptanceTracks + // See O2Physics/Common/DataModel/TrackSelectionTables.h for further details. + // Therefore, vary in Run 2 only is isGlobalTrack is NOT requested by default. + eisPrimaryTrack, // Validated in Run 3. See also isPVContributor + // In Run 2, it is already requested in isGlobalTrack, through definition kGlobalTrack = kQualityTracks | kPrimaryTracks | kInAcceptanceTracks + // See O2Physics/Common/DataModel/TrackSelectionTables.h for further details. + // Therefore, vary in Run 2 only is isGlobalTrack is NOT requested by default. + eisInAcceptanceTrack, // kInAcceptanceTracks = kPtRange | kEtaRange . Pt is open, and |eta| < 0.8. + // But after I already cut directly on 0.2 < pt < 5.0 and |eta| < 0.8, it has no effect. + // Can be used both in Run 3 and Run 2. + // TBI 20250113 remove this cut eventually from the code, because I cut direcly on 0.2 < pt < 5.0 and |eta| < 0.8 in any case. + eisGlobalTrack, // Do not use in Run 3, it can be used directly only in Run 2 and Run 1, see definition in: + // https://github.com/AliceO2Group/O2Physics/blob/master/Common/Core/TrackSelectionDefaults.cxx#L23 + // For Run 3 global tracks, I need to use TrackSelection getGlobalTrackSelectionRun3ITSMatch(int matching, int passFlag) from + // https://github.com/AliceO2Group/O2Physics/blob/master/Common/Core/TrackSelectionDefaults.cxx#L43 + // That is precisely definition of filtBit1 in https://github.com/AliceO2Group/O2Physics/blob/master/Common/TableProducer/trackselection.cxx + // So: etrackCutFlagFb1 in Run 3 is a closest match to eisGlobalTrack in Run 2 + eisPVContributor, // Run 3: Has this track contributed to the collision vertex fit + // Tracks used in vertex fit are flagged as "contributors" (-> track.isPVContributor() for AO2D tracks). Such a track is + // allowed to contribute to only one PV. => See further details in RS presentation https://indico.cern.ch/event/1453901/timetable/#12-track-reconstruction + // This cut affects significantly distributions of other tracking parameters. Most notably, after using this cut, DCAz distribution is reduced to ~ 1mm range. + // But for global tracks in any case we request very stringent DCA cut. + // pt and eta distributions are only mildly affected. + // Do not use in Run 2 and Run 1. + // It's not the same as isPrimaryTrack cut, albeit there is an overlap. + // special treatment: + ePtDependentDCAxyParameterization, + + eParticleCuts_N +}; + +enum eAsFunctionOf { // this is a specific enum only for 1D dependence + // 1D: + AFO_INTEGRATED = 0, + AFO_MULTIPLICITY, // vs. default multiplicity, which is (at the moment) fSelectedTracks, i.e. number of tracks in Q-vector + AFO_CENTRALITY, // vs. default centrality estimator, see how it's calculated in DetermineCentrality(...) + AFO_PT, + AFO_ETA, + AFO_OCCUPANCY, // vs. default "occupancy" variable which is (at the moment) "FT0COccupancyInTimeRange" (alternative is "TrackOccupancyInTimeRange") + AFO_INTERACTIONRATE, // vs. "interation rate" + AFO_CURRENTRUNDURATION, // vs. "current run duration", i.e. vs "seconds since start of run" + AFO_VZ, // vs. "vertex z position" + AFO_CHARGE, // vs. "particle charge" + // ... + eAsFunctionOf_N +}; // prefix is needed, to avoid conflict with enum eKinematics + +enum eAsFunctionOf2D { // this is a specific enum only for 2D dependence + // 2D: + AFO_CENTRALITY_PT = 0, + AFO_CENTRALITY_ETA, + AFO_CENTRALITY_CHARGE, + AFO_CENTRALITY_VZ, + AFO_PT_ETA, + AFO_PT_CHARGE, + AFO_ETA_CHARGE, + // ... + eAsFunctionOf2D_N +}; + +enum eAsFunctionOf3D { // this is a specific enum only for 3D dependence + // 3D: + AFO_CENTRALITY_PT_ETA = 0, + AFO_CENTRALITY_PT_CHARGE, + AFO_CENTRALITY_PT_VZ, + AFO_CENTRALITY_ETA_VZ, + AFO_CENTRALITY_ETA_CHARGE, + AFO_CENTRALITY_VZ_CHARGE, + AFO_PT_ETA_CHARGE, + // ... + eAsFunctionOf3D_N +}; + +enum eNUAPDF { + ePhiNUAPDF = 0, + ePtNUAPDF, + eEtaNUAPDF, + eNUAPDF_N +}; + +enum eqvectorKine { // Here "kine" originally meant "kinematic", i.e. vs. pt or vs. eta, now it's general. + // 1D: + PTq = 0, + ETAq, + CHARGEq, + // ... + + // 2D: // Yes, I linearize 2D case, in an analogy with "global bin" structure for multidimensional histograms. + PT_ETAq, + PT_CHARGEq, + ETA_CHARGEq, + // ... + + // 3D: // Yes, I linearize 3D case, in an analogy with "global bin" structure for multidimensional histograms. + PT_ETA_CHARGEq, + // ... + eqvectorKine_N +}; + +enum eTimer { + eGlobal = 0, + eLocal, + eTimer_N +}; + +enum eEventCounterForDryRun { + eFill = 0, + ePrint +}; + +enum eCutModus { + eCut = 0, // standard, i.e. no cut counters are used + eCutCounterBinning, // dry call to EventCuts and ParticleCuts, just to establish order of binning in CutCountets, which resembles order of cut implementation + eCutCounterAbsolute, + eCutCounterSequential +}; + +enum eCutCounter { + eAbsolute = 0, + eSequential, + eCutCounter_N +}; + +enum eQAEventHistograms2D { + // General (estimators can be chosen via configurables): + eMultiplicity_vs_ReferenceMultiplicity = 0, // multiplicity is x, reference multiplicity is y. I can swap offline if needed: histOriginal->GetBinContent(x,y); histSwapped->Fill(y,x); + eMultiplicity_vs_NContributors, + eMultiplicity_vs_Centrality, + eMultiplicity_vs_VertexZ, + eMultiplicity_vs_Occupancy, + eMultiplicity_vs_InteractionRate, // TBI 20250331 I ctd. below with more histos in category eMultiplicity_vs_... - re-organize at some point bookkeping here + eReferenceMultiplicity_vs_NContributors, + eReferenceMultiplicity_vs_Centrality, + eReferenceMultiplicity_vs_VertexZ, + eReferenceMultiplicity_vs_Occupancy, + eReferenceMultiplicity_vs_InteractionRate, + eNContributors_vs_Centrality, + eNContributors_vs_VertexZ, + eNContributors_vs_Occupancy, + eNContributors_vs_InteractionRate, + eCentrality_vs_VertexZ, + eCentrality_vs_Occupancy, + eCentrality_vs_ImpactParameter, // [sim] = reconstructed centrality vs. simulated impact parameter. [rec] = ... TBI 20241210 + eCentrality_vs_InteractionRate, + eVertexZ_vs_Occupancy, + eVertexZ_vs_InteractionRate, + // ... + // Specific (everything is hardwired): + eMultNTracksPV_vs_MultNTracksGlobal, // Run 3 multiplicity + eCentFT0C_vs_CentFT0CVariant1, // Run 3 centrality + eCentFT0C_vs_CentFT0M, // Run 3 centrality + eCentFT0C_vs_CentFV0A, // Run 3 centrality + eCentFT0C_vs_CentNTPV, // Run 3 centrality + eCentFT0C_vs_CentNGlobal, // Run 3 centrality + eCentFT0M_vs_CentNTPV, // Run 3 centrality + eCentRun2V0M_vs_CentRun2SPDTracklets, // Run 2 centrality (do not use in Run 1 converted, because there is no centrality information) + eTrackOccupancyInTimeRange_vs_FT0COccupancyInTimeRange, + eCurrentRunDuration_vs_InteractionRate, // ... + // ... + // Unsorted category: TBI 20250331 not sure if I will keep these ones permanently: + eMultiplicity_vs_FT0CAmplitudeOnFoundBC, + eCentFT0C_vs_FT0CAmplitudeOnFoundBC, + eCentrality_vs_CentralitySim, // correlation between centrality determined from reconstructed data, and centrality determined at generated level (from IP). I save it as [eSim], not as [eRec] + // ... + eQAEventHistograms2D_N +}; + +enum eQAParticleHistograms2D { + ePt_vs_dcaXY, + eQAParticleHistograms2D_N +}; + +enum eQAParticleEventHistograms2D { + // In this category I do correlation vs. some-event-property. + // The < ... > goes over all particles in that event. + // All < ... > over particles are calculated with helper TProfile fQAParticleEventProEbyE + // For instance: vs. current run duration + eCurrentRunDuration_vs_itsNClsEbyE, + eCurrentRunDuration_vs_itsNClsNegEtaEbyE, + eCurrentRunDuration_vs_itsNClsPosEtaEbyE, + eCurrentRunDuration_vs_Eta0804EbyE, + eCurrentRunDuration_vs_Eta0400EbyE, + eCurrentRunDuration_vs_Eta0004EbyE, + eCurrentRunDuration_vs_Eta0408EbyE, + eCurrentRunDuration_vs_Pt0005EbyE, + eCurrentRunDuration_vs_Pt0510EbyE, + eCurrentRunDuration_vs_Pt1050EbyE, + eQAParticleEventHistograms2D_N +}; + +enum eQAParticleEventProEbyE { + eitsNClsEbyE = 1, // Labels average in a given event (therefore "EbyE" is appended). Yes, from one, because it runs over bin content and entries in TProfile for most of the time. + eitsNClsNegEtaEbyE, // in a given event for eta < 0 + eitsNClsPosEtaEbyE, // in a given event for eta > 0 + eEta0804EbyE, // in a given event for -0.8 < eta < -0.4 + eEta0400EbyE, // in a given event for -0.4 < eta < 0.0 + eEta0004EbyE, // in a given event for 0.0 < eta < 0.4 + eEta0408EbyE, // in a given event for 0.4 < eta < 0.8 + ePt0005EbyE, // in a given event for 0.0 < pt < 0.5 + ePt0510EbyE, // in a given event for 0.5 < pt < 1.0 + ePt1050EbyE, // in a given event for 1.0 < pt < 5.0 + eMeanPhi, // in an event TBI 20250214 I need to unify naming convention for <> with previous enums in above in the series, but okay... + eMeanPt, // in an event + eMeanEta, // in an event + eMeanCharge, // in an event + eMeantpcNClsFindable, // in an event + eMeantpcNClsShared, // in an event + eMeanitsChi2NCl, // in an event + eMeantpcNClsFound, // in an event + eMeantpcNClsCrossedRows, // in an event + eMeanitsNCls, // in an event + eMeanitsNClsInnerBarrel, // in an event + eMeantpcCrossedRowsOverFindableCls, // in an event + eMeantpcFoundOverFindableCls, // in an event + eMeantpcFractionSharedCls, // in an event + eMeantpcChi2NCl, // in an event + eMeandcaXY, // in an event + eMeandcaZ, // in an event + eQAParticleEventProEbyE_N +}; + +enum eQACorrelationsVsHistograms2D { + // In this category I correlate <2> vs. some-event-property. + // For instance: <2> vs. ref. mult + // <2> vs. , where is calculated from all particles in that event (so in this sense, it's an event property as well) + // Remark 1: If I would ever need the same thingie for <4>, <6>, etc., just introduce new dimension in 2D histogram + // Remark 2: All < ... > over particles are calculated with helper TProfile fQAParticleEventProEbyE + eCorrelations_vs_Multiplicity = 0, + eCorrelations_vs_ReferenceMultiplicity, + eCorrelations_vs_Centrality, + // ... + eCorrelations_vs_MeanPhi, + eCorrelations_vs_MeanPt, + eCorrelations_vs_MeanEta, + eCorrelations_vs_MeanCharge, + eCorrelations_vs_MeantpcNClsFindable, + eCorrelations_vs_MeantpcNClsShared, + eCorrelations_vs_MeanitsChi2NCl, + eCorrelations_vs_MeantpcNClsFound, + eCorrelations_vs_MeantpcNClsCrossedRows, + eCorrelations_vs_MeanitsNCls, + eCorrelations_vs_MeanitsNClsInnerBarrel, + eCorrelations_vs_MeantpcCrossedRowsOverFindableCls, + eCorrelations_vs_MeantpcFoundOverFindableCls, + eCorrelations_vs_MeantpcFractionSharedCls, + eCorrelations_vs_MeantpcChi2NCl, + eCorrelations_vs_MeandcaXY, + eCorrelations_vs_MeandcaZ, + // ... + eQACorrelationsVsHistograms2D_N +}; + +enum eQACorrelationsVsInteractionRateVsProfiles2D_N { + // In this category I fill <2> in 2D profile spanned by IR vs. some-other-observable (IR is always x axis) + // For instance: <2> is filled in TProfile2D spanned by IR vs. CurrentRunDuration (crd) + // <2> is filled in TProfile2D spanned by IR vs. , where is calculated from all particles in that event + // Remark 1: If I would ever need the same thingie for <4>, <6>, etc., just introduce new dimension in 2D profile + // Remark 2: All < ... > over particles are calculated with helper TProfile fQAParticleEventProEbyE + eCorrelationsVsInteractionRate_vs_CurrentRunDuration = 0, + eCorrelationsVsInteractionRate_vs_Multiplicity, + eCorrelationsVsInteractionRate_vs_ReferenceMultiplicity, + eCorrelationsVsInteractionRate_vs_Centrality, + // ... + eCorrelationsVsInteractionRate_vs_MeanPhi, + eCorrelationsVsInteractionRate_vs_SigmaMeanPhi, + eCorrelationsVsInteractionRate_vs_MeanPt, + eCorrelationsVsInteractionRate_vs_SigmaMeanPt, + eCorrelationsVsInteractionRate_vs_MeanEta, + eCorrelationsVsInteractionRate_vs_SigmaMeanEta, + // ... + eQACorrelationsVsInteractionRateVsProfiles2D_N +}; + +enum eReferenceMultiplicityEstimators { + // Run 3: + eMultTPC = 0, + eMultFV0M, // ref. mult from helper task o2-analysis-multiplicity-table + eMultFT0C, // ref. mult from helper task o2-analysis-multiplicity-table + eMultFT0M, // ref. mult from helper task o2-analysis-multiplicity-table + eMultNTracksPV, // ref. mult from helper task o2-analysis-multiplicity-table + eMultNTracksGlobal, // ref. mult from helper task o2-analysis-multiplicity-table + // Run 2: + eMultTracklets, // ref. mult from helper task o2-analysis-multiplicity-table, use only for Run 2 + eReferenceMultiplicityEstimators_N +}; + +enum eCentralityEstimators { + // Run 3: + eCentFT0C = 0, + eCentFT0CVariant1, + eCentFT0M, + eCentFV0A, + eCentNTPV, + eCentNGlobal, + // Run 2: + eCentRun2V0M, + eCentRun2SPDTracklets, + eCentralityEstimators_N +}; + +enum eOccupancyEstimators { + eTrackOccupancyInTimeRange, // from helper task o2-analysis-event-selection, see also IA's presentation in https://indico.cern.ch/event/1464946, slide 38 + eFT0COccupancyInTimeRange, // from helper task o2-analysis-event-selection + eOccupancyEstimators_N +}; + +enum eEventCounter { + eTotal, // total number of events, before any cuts are applied + eProcessed, // number of processed events, i.e. number of events which survived cuts and on which analysis have been performed + eEventCounter_N +}; + +enum eSpecificCuts { + // Run 3: + eLHC23zzh, + eLHC24ar, + eLHC24as, + // Run 2: + eLHC15o, + // Run 1: + // ... + // Cuts for minimal subscription, "processTest": "true in JSON + eTestCuts, + eSpecificCuts_N +}; + +enum eRunTime { + eStartOfRun = 0, // in abs. seconds since Unix epoch + eEndOfRun, // in abs. seconds since Unix epoch + eDurationInSec, // in seconds + eRunTime_N +}; // *) Global constants: -#include "PWGCF/MultiparticleCorrelations/Core/MuPa-GlobalConstants.h" + +const int gMaxCorrelator = 12; +const int gMaxHarmonic = 9; +const int gMaxIndex = 300; // per order, used only in Test0 +const int gMaxNoBinsKine = 1000; // max number of bins for differential q-vector +const int gMaxBinsDiffWeights = 100; // max number of bins for differential weights, see MakeWeights.C +const int gMaxNumberEtaSeparations = 9; // max number of different eta separations used to calculated 2p corr. with eta separations +const int gMaxNumberSparseDimensions = 10; // max number of dimensions in sparse histograms // *) Main task: struct MultiparticleCorrelationsAB // this name is used in lower-case format to name the TDirectoryFile in AnalysisResults.root @@ -118,14 +747,20340 @@ struct MultiparticleCorrelationsAB // this name is used in lower-case format to // tc.fDatabasePDG->GetParticle(track.pdgCode()) with pdg->GetParticle(track.pdgCode()) + same for mcParticle + remove TDatabasePDG.h // Service pdg; -// *) Configurables (cuts): -#include "PWGCF/MultiparticleCorrelations/Core/MuPa-Configurables.h" + // *) Configurables (cuts): + + // *) Task configuration: + struct : ConfigurableGroup { + // std::string prefix = "Task configuration"; // AA: now these configurables also appear grouped on hyperloop => TBI 20240522 check if this work, and if further modifications in init are needed + Configurable cfTaskIsConfiguredFromJson{"cfTaskIsConfiguredFromJson", "no", "always set manaully to \"yes\" via JSON, merely to ensure that settings are not ignored silently"}; + Configurable cfTaskName{"cfTaskName", "Default task name", "set task name - use eventually to determine weights for this task"}; + Configurable cfDryRun{"cfDryRun", false, "book all histos and run without storing and calculating anything"}; + Configurable cfVerbose{"cfVerbose", false, "run or not in verbose mode (but not for simple utility functions or function calls per particle)"}; + Configurable cfVerboseUtility{"cfVerboseUtility", false, "run or not in verbose mode, also for simple utility functions (but not for function calls per particle)"}; + Configurable cfVerboseForEachParticle{"cfVerboseForEachParticle", false, "run or not in verbose mode (also for function calls per particle)"}; + Configurable cfVerboseEventCounter{"cfVerboseEventCounter", false, "print or not only event counter"}; + Configurable cfVerboseEventCut{"cfVerboseEventCut", false, "print or not which event cut didn't survive"}; + Configurable cfPlainPrintout{"cfPlainPrintout", false, "print in color or in plain (use the latter in HL)"}; + Configurable cfDoAdditionalInsanityChecks{"cfDoAdditionalInsanityChecks", false, "do additional insanity checks at run time (this leads to small loss of performance)"}; + Configurable cfInsanityCheckForEachParticle{"cfInsanityCheckForEachParticle", false, "do insanity checks at run time for each particle, at the expense of losing a lot of performance. Use only during debugging."}; + Configurable cfRandomSeed{"cfRandomSeed", 0, "0 = random seed is guaranteed to be unique in space and time"}; + Configurable cfUseFisherYates{"cfUseFisherYates", false, "use or not Fisher-Yates algorithm to randomize particle indices"}; + Configurable cfFixedNumberOfRandomlySelectedTracks{"cfFixedNumberOfRandomlySelectedTracks", -1, "set to some integer > 0, to apply and use. Set to <=0, to ignore."}; + Configurable cfUseStopwatch{"cfUseStopwatch", false, "if true, some basic info on time execution is printed, here and there. Very loosely, this can be used for execution time profiling."}; + Configurable cfFloatingPointPrecision{"cfFloatingPointPrecision", 0.000001, "two floats are the same if abs(f1 - f2) < fFloatingPointPrecision"}; + Configurable cfSequentialBailout{"cfSequentialBailout", 0, "if fSequentialBailout > 0, then each fSequentialBailout events the function BailOut() is called. Can be used for real analysis and for IV"}; + Configurable cfUseSpecificCuts{"cfUseSpecificCuts", false, "if true, analysis-specific cuts set via configurable cfWhichSpecificCuts are applied after DefaultCuts(). "}; + Configurable cfWhichSpecificCuts{"cfWhichSpecificCuts", "some supported set of analysis-specific cuts (e.g. LHC23zzh, ...)", "determine which set of analysis-specific cuts will be applied after DefaultCuts(). Use in combination with tc.fUseSpecificCuts"}; + Configurable cfSkipTheseRuns{"cfSkipTheseRuns", "", "Set here via comma-separated list which runs will be skipped during hl analysis (a.k.a. \"bad runs\"). Leave empty to ignore. Example format and list for LHC23zzh: \"544116,544091\""}; + Configurable cfUseSetBinLabel{"cfUseSetBinLabel", false, "until hist->SetBinLabel(...) large memory consumption is resolved, for each histogram dump all that info in the y-axis title. See also local executable PostprocessLabels.C, where I do the final bin labeling offline"}; + Configurable cfUseClone{"cfUseClone", false, "until hist->Clone(...) large memory consumption is resolved, do not use cloning. See ROOT Forum thread."}; + Configurable cfUseFormula{"cfUseFormula", false, "until TFormula large memory consumption is resolved, do not use this class. See ROOT Forum thread."}; + Configurable cfUseDatabasePDG{"cfUseDatabasePDG", false, "When enabled, there is a standard memory blow-up."}; + } cf_tc; + + // *) QA: + struct : ConfigurableGroup { + Configurable cfCheckUnderflowAndOverflow{"cfCheckUnderflowAndOverflow", false, "check and bail out if in event and particle histograms there are entries which went to underflow or overflow bins (use only locally)"}; + Configurable cfRebin{"cfRebin", 10, "number of bins of selected heavy 2D histograms are devided with this number"}; + Configurable cfFillQAEventHistograms2D{"cfFillQAEventHistograms2D", false, "if false, all QA 2D event histograms are not filled. if true, only the ones for which fBookQAEventHistograms2D[...] is true, are filled"}; + Configurable> cfBookQAEventHistograms2D{"cfBookQAEventHistograms2D", {"1-Multiplicity_vs_ReferenceMultiplicity", "1-Multiplicity_vs_NContributors", "1-Multiplicity_vs_Centrality", "1-Multiplicity_vs_VertexZ", "1-Multiplicity_vs_Occupancy", "1-Multiplicity_vs_InteractionRate", "1-ReferenceMultiplicity_vs_NContributors", "1-ReferenceMultiplicity_vs_Centrality", "1-ReferenceMultiplicity_vs_VertexZ", "1-ReferenceMultiplicity_vs_Occupancy", "1-ReferenceMultiplicity_vs_InteractionRate", "1-NContributors_vs_Centrality", "1-NContributors_vs_VertexZ", "1-NContributors_vs_Occupancy", "1-NContributors_vs_InteractionRate", "1-Centrality_vs_VertexZ", "1-Centrality_vs_Occupancy", "0-Centrality_vs_ImpactParameter", "1-Centrality_vs_InteractionRate", "1-VertexZ_vs_Occupancy", "1-VertexZ_vs_InteractionRate", "0-MultNTracksPV_vs_MultNTracksGlobal", "1-CentFT0C_vs_CentFT0CVariant1", "1-CentFT0C_vs_CentFT0M", "1-CentFT0C_vs_CentFV0A", "0-CentFT0C_vs_CentNTPV", "0-CentFT0C_vs_CentNGlobal", "0-CentFT0M_vs_CentNTPV", "0-CentRun2V0M_vs_CentRun2SPDTracklets", "1-TrackOccupancyInTimeRange_vs_FT0COccupancyInTimeRange", "1-CurrentRunDuration_vs_InteractionRate", "1-Multiplicity_vs_FT0CAmplitudeOnFoundBC", "1-CentFT0C_vs_FT0CAmplitudeOnFoundBC", "1-Centrality_vs_CentralitySim"}, "book (1) or do not book (0) this QA 2D event histogram"}; + Configurable cfFillQAParticleHistograms2D{"cfFillQAParticleHistograms2D", false, "if false, all QA 2D particle histograms are not filled. if true, only the ones for which fBookQAParticleHistograms2D[...] is true, are filled"}; + Configurable> cfBookQAParticleHistograms2D{"cfBookQAParticleHistograms2D", {"1-Pt_vs_dcaXY"}, "book (1) or do not book (0) this QA 2D particle histogram"}; + Configurable cfFillQAParticleEventHistograms2D{"cfFillQAParticleEventHistograms2D", false, "if false, all QA 2D particle event histograms are not filled. if true, only the ones for which fBookQAParticleEventHistograms2D[...] is true, are filled"}; + Configurable> cfBookQAParticleEventHistograms2D{"cfBookQAParticleEventHistograms2D", {"1-CurrentRunDuration_vs_itsNCls", "1-CurrentRunDuration_vs_itsNClsNegEtaEbyE", "1-CurrentRunDuration_vs_itsNClsPosEtaEbyE", "1-CurrentRunDuration_vs_Eta0804EbyE", "1-CurrentRunDuration_vs_Eta0400EbyE", "1-CurrentRunDuration_vs_Eta0004EbyE", "1-CurrentRunDuration_vs_Eta0408EbyE", "1-CurrentRunDuration_vs_Pt0005EbyE", "1-CurrentRunDuration_vs_Pt0510EbyE", "1-CurrentRunDuration_vs_Pt1050EbyE"}, "book (1) or do not book (0) this QA 2D particle event histogram"}; + + Configurable cfFillQACorrelationsVsHistograms2D{"cfFillQACorrelationsVsHistograms2D", false, "if false, all QA 2D histograms of this category are not filled. if true, only the ones for which fBookQACorrelationsVsHistograms2D[...] is true, are filled"}; + Configurable> cfBookQACorrelationsVsHistograms2D{"cfBookQACorrelationsVsHistograms2D", {"1-Correlations_vs_Multiplicity", "1-Correlations_vs_ReferenceMultiplicity", "1-Correlations_vs_Centrality", "1-Correlations_vs_Phi", "1-Correlations_vs_Pt", "1-Correlations_vs_Eta", "1-Correlations_vs_Charge", "1-Correlations_vs_tpcNClsFindable", "1-Correlations_vs_tpcNClsShared", "1-Correlations_vs_itsChi2NCl", "1-Correlations_vs_tpcNClsFound", "1-Correlations_vs_tpcNClsCrossedRows", "1-Correlations_vs_itsNCls", "1-Correlations_vs_itsNClsInnerBarrel", "1-Correlations_vs_tpcCrossedRowsOverFindableCls", "1-Correlations_vs_tpcFoundOverFindableCls", "1-Correlations_vs_tpcFractionSharedCls", "1-Correlations_vs_tpcChi2NCl", "1-Correlations_vs_dcaXY", "1-Correlations_vs_dcaZ"}, "book (1) or do not book (0) this QA 2D histogram"}; + Configurable> cfQACorrelationsVsHistogramsMinMaxHarmonic{"cfQACorrelationsVsHistogramsMinMaxHarmonic", {1, 5}, "harmonics are filled for min <= harmonic < max"}; + + Configurable cfFillQACorrelationsVsInteractionRateVsProfiles2D{"cfFillQACorrelationsVsInteractionRateVsProfiles2D", false, "if false, all QA 2D profiles of this category are not filled. if true, only the ones for which fBookQACorrelationsVsInteractionRateVsProfiles2D[...] is true, are filled"}; + Configurable> cfBookQACorrelationsVsInteractionRateVsProfiles2D{"cfBookQACorrelationsVsInteractionRateVsProfiles2D", {"1-CorrVsIR_vs_CurrentRunDuration", "1-CorrVsIR_vs_Multiplicity", "1-CorrVsIR_vs_ReferenceMultiplicity", "1-CorrVsIR_vs_Centrality", "1-CorrVsIR_vs_MeanPhi", "1-CorrVsIR_vs_SigmaMeanPhi", "1-CorrVsIR_vs_MeanPt", "1-CorrVsIR_vs_SigmaMeanPt", "1-CorrVsIR_vs_MeanEta", "1-CorrVsIR_vs_SigmaMeanEta"}, "book (1) or do not book (0) this QA 2D profile"}; + Configurable> cfQACorrelationsVsInteractionRateVsProfilesMinMaxHarmonic{"cfQACorrelationsVsInteractionRateVsProfilesMinMaxHarmonic", {1, 5}, "harmonics are filled for min <= harmonic < max"}; + + } cf_qa; + + // *) Event histograms: + struct : ConfigurableGroup { + Configurable cfFillEventHistograms{"cfFillEventHistograms", true, "if false, all event histograms are not filled. if true, only the ones for which fBookEventHistograms[...] is true, are filled"}; + Configurable> cfBookEventHistograms{"cfBookEventHistograms", {"1-NumberOfEvents", "1-TotalMultiplicity", "1-Multiplicity", "1-ReferenceMultiplicity", "1-Centrality", "1-VertexX", "1-VertexY", "1-VertexZ", "1-NContributors", "0-ImpactParameter", "0-EventPlaneAngle", "1-Occupancy", "1-InteractionRate", "1-CurrentRunDuration", "0-MultMCNParticlesEta08"}, "Book (1) or do not book (0) event histogram"}; + } cf_eh; + + // *) Event cuts: + struct : ConfigurableGroup { + Configurable> cfUseEventCuts{"cfUseEventCuts", {"1-NumberOfEvents", "1-TotalMultiplicity", "1-Multiplicity", "1-ReferenceMultiplicity", "1-Centrality", "1-VertexX", "1-VertexY", "1-VertexZ", "1-NContributors", "1-ImpactParameter", "0-EventPlaneAngle", "1-Occupancy", "1-InteractionRate", "1-CurrentRunDuration", "0-MultMCNParticlesEta08", "0-Trigger", "0-Sel7", "1-Sel8", "1-MultiplicityEstimator", "1-ReferenceMultiplicityEstimator", "1-CentralityEstimator", "1-SelectedEvents", "1-NoSameBunchPileup", "1-IsGoodZvtxFT0vsPV", "1-IsVertexITSTPC", "1-IsVertexTOFmatched", "1-IsVertexTRDmatched", "0-NoCollInTimeRangeStrict", "0-NoCollInTimeRangeStandard", "0-NoCollInRofStrict", "0-NoCollInRofStandard", "0-NoHighMultCollInPrevRof", "0-IsGoodITSLayer3", "0-IsGoodITSLayer0123", "0-IsGoodITSLayersAll", "1-OccupancyEstimator", "1-MinVertexDistanceFromIP", "0-NoPileupTPC", "0-NoPileupFromSPD", "0-NoSPDOnVsOfPileup", "1-RefMultVsNContrUp", "1-RefMultVsNContrLow", "1-CentralityCorrelationsCut", "0-FT0Bad", "0-ITSBad", "0-ITSLimAccMCRepr", "0-TPCBadTracking", "0-TPCLimAccMCRepr", "0-TPCBadPID", "1-CentralityWeights"}, "use (1) or do not use (0) event cuts"}; + Configurable cfUseEventCutCounterAbsolute{"cfUseEventCutCounterAbsolute", false, "profile and save how many times each event cut counter triggered (absolute). Use with care, as this is computationally heavy"}; + Configurable cfUseEventCutCounterSequential{"cfUseEventCutCounterSequential", false, "profile and save how many times each event cut counter triggered (sequential). Use with care, as this is computationally heavy"}; + Configurable cfPrintCutCounterContent{"cfPrintCutCounterContent", false, "if true, prints on the screen after each event the content of fEventCutCounterHist[*][*] (all which were booked)"}; + // Remark: Preserve below the same ordering as in enum's eEventHistograms + eEventCuts. In hyperloop, in any case this ordering is lost, because there it's alphabetical TBI 20240521 check this, after I added now std::string prefix thingie + Configurable> cfNumberOfEvents{"cfNumberOfEvents", {-1, 1000000000}, "total number of events to process (whether or not they survive event cuts): {min, max}, with convention: min <= N < max"}; + Configurable> cfTotalMultiplicity{"cfTotalMultiplicity", {-1, 1000000000}, "total multiplicity range: {min, max}, with convention: min <= M < max"}; + Configurable> cfMultiplicity{"cfMultiplicity", {-1., 1000000000.}, "multiplicity (defined via cfMultiplicityEstimator) range {min, max}, with convention: min <= M < max"}; + Configurable> cfReferenceMultiplicity{"cfReferenceMultiplicity", {-1., 1000000000.}, "reference multiplicity (defined via cfReferenceMultiplicityEstimator) range {min, max}, with convention: min <= M < max"}; + Configurable> cfCentrality{"cfCentrality", {-10., 110.}, "centrality range: {min, max}, with convention: min <= cent < max"}; + Configurable> cfVertexX{"cfVertexX", {-10., 10.}, "vertex x position range: {min, max}[cm], with convention: min <= Vx < max"}; + Configurable> cfVertexY{"cfVertexY", {-10., 10.}, "vertex y position range: {min, max}[cm], with convention: min <= Vy < max"}; + Configurable> cfVertexZ{"cfVertexZ", {-10, 10.}, "vertex z position range: {min, max}[cm], with convention: min <= Vz < max"}; + Configurable cfMinVertexDistanceFromIP{"cfMinVertexDistanceFromIP", {0.000001}, "if sqrt(vx^2+vy^2+vz^2) < cfMinVertexDistanceFromIP [cm], the event is reject. IP = nominal Interaction Point."}; + Configurable> cfNContributors{"cfNContributors", {2, 1000000000}, "Number of vertex contributors: {min, max}, with convention: min <= N < max"}; + Configurable> cfImpactParameter{"cfImpactParameter", {-1, 1000000000}, "Impact parameter range (can be used only for sim): {min, max}, with convention: min <= IP < max"}; + Configurable> cfEventPlaneAngle{"cfEventPlaneAngle", {-o2::constants::math::PI, o2::constants::math::TwoPI}, "Event Plane Angle range (can be used only for sim): {min, max}, with convention: min <= EP < max"}; + Configurable> cfOccupancy{"cfOccupancy", {-0.0001, 1000000000}, "Range for occupancy (use cfOccupancyEstimator to set specific estimator): {min, max}, with convention: min <= X < max. Important: remember that 0. has to be included, therefore I set -0.0001 by default for low edge"}; + Configurable> cfInteractionRate{"cfInteractionRate", {0.1, 1000000000.}, "Range for interaction rate (in kHz): {min, max}, with convention: min <= X < max"}; + Configurable> cfCurrentRunDuration{"cfCurrentRunDuration", {-2, 1000000000}, "Range for current run duration (i.e. seconds since start of run) in seconds: {min, max}, with convention: min <= X < max. Only collisions taken in this range (measured from SOR) are taken for analysis"}; + Configurable> cfMultMCNParticlesEta08{"cfMultMCNParticlesEta08", {-1, 1000000000}, "Range for MultMCNParticlesEta08 : {min, max}, with convention: min <= X < max"}; + Configurable cfTrigger{"cfTrigger", "some supported trigger (e.g. \"kINT7\" for Run 2, \"kTVXinTRD\" for Run 3, etc...)", "set here some supported trigger"}; + Configurable cfUseSel7{"cfUseSel7", false, "use for Run 1 and 2 data and MC (see official doc)"}; + Configurable cfUseSel8{"cfUseSel8", false, "use for Run 3 data and MC (see official doc)"}; + Configurable cfMultiplicityEstimator{"cfMultiplicityEstimator", "SelectedTracks", "all results vs. mult are calculated against this multiplicity. Can be set to SelectedTracks (calculated internally), ReferenceMultiplicity (calculated outside of my code), etc."}; + Configurable cfReferenceMultiplicityEstimator{"cfReferenceMultiplicityEstimator", "MultFT0C", "Reference multiplicity, calculated outside of my code. Can be MultFT0C, MultFV0M, MultTPC, etc."}; + // Configurable cfCentralityEstimator{"cfCentralityEstimator", "some supported centrality estimator (e.g. CentFT0C, ...)", "set here some supported centrality estimator (CentFT0C, CentFT0M, CentFV0A, CentNTPV, ... for Run 3, and CentRun2V0M, CentRun2SPDTracklets, ..., for Run 2 and 1) "}; + Configurable cfCentralityEstimator{"cfCentralityEstimator", "CentFT0C", "set here some supported centrality estimator (CentFT0C, CentFT0M, CentFV0A, CentNTPV, ... for Run 3, and CentRun2V0M, CentRun2SPDTracklets, ..., for Run 2 and 1) "}; + Configurable> cfSelectedEvents{"cfSelectedEvents", {-1, 1000000000}, "Selected number of events to process (i.e. only events which survive event cuts): {min, max}, with convention: min <= N < max"}; + Configurable cfUseNoSameBunchPileup{"cfUseNoSameBunchPileup", false, "TBI 20240521 explanation"}; + Configurable cfUseIsGoodZvtxFT0vsPV{"cfUseIsGoodZvtxFT0vsPV", false, "TBI 20240521 explanation"}; + Configurable cfUseIsVertexITSTPC{"cfUseIsVertexITSTPC", false, "TBI 20240521 explanation"}; + Configurable cfUseIsVertexTOFmatched{"cfUseIsVertexTOFmatched", false, "TBI 20240521 explanation"}; + Configurable cfUseIsVertexTRDmatched{"cfUseIsVertexTRDmatched", false, "TBI 20240521 explanation"}; + Configurable cfUseNoCollInTimeRangeStrict{"cfUseNoCollInTimeRangeStrict", false, "TBI 20240521 explanation"}; + Configurable cfUseNoCollInTimeRangeStandard{"cfUseNoCollInTimeRangeStandard", false, "TBI 20240521 explanation"}; + Configurable cfUseNoCollInRofStrict{"cfUseNoCollInRofStrict", false, "TBI 20240521 explanation"}; + Configurable cfUseNoCollInRofStandard{"cfUseNoCollInRofStandard", false, "TBI 20240521 explanation"}; + Configurable cfUseNoHighMultCollInPrevRof{"cfUseNoHighMultCollInPrevRof", false, "TBI 20240521 explanation"}; + Configurable cfUseIsGoodITSLayer3{"cfUseIsGoodITSLayer3", false, "TBI 20241220 explanation (or see enum)"}; + Configurable cfUseIsGoodITSLayer0123{"cfUseIsGoodITSLayer0123", false, "TBI 20241220 explanation (or see enum)"}; + Configurable cfUseIsGoodITSLayersAll{"cfUseIsGoodITSLayersAll", false, "TBI 20241220 explanation (or see enum)"}; + Configurable cfUseNoPileupTPC{"cfUseNoPileupTPC", false, "TBI 20250318 explanation"}; + Configurable cfUseNoPileupFromSPD{"cfUseNoPileupFromSPD", false, "TBI 20250318 explanation"}; + Configurable cfUseNoSPDOnVsOfPileup{"cfUseNoSPDOnVsOfPileup", false, "TBI 20250318 explanation"}; + Configurable cfOccupancyEstimator{"cfOccupancyEstimator", "FT0COccupancyInTimeRange", "set here some supported occupancy estimator (TrackOccupancyInTimeRange, FT0COccupancyInTimeRange, ..."}; + Configurable cfRefMultVsNContrUp{"cfRefMultVsNContrUp", "1200. + 0.20*x", "set here some formula in the mandatory format \"p0 + p1*x\" for the upper boundary cut in RefMult_vs_NContr correlation"}; + Configurable cfRefMultVsNContrLow{"cfRefMultVsNContrLow", "-650. + 0.08*x", "set here some in the mandatory format \"p0 + p1*x\" for the lower boundary cut in RefMult_vs_NContr correlation"}; + Configurable cfCentralityCorrelationsCut{"cfCentralityCorrelationsCut", "CentFT0C_CentFT0M", "Indicate two centrality estimators for the calculation of centrality correlation cut"}; + Configurable cfCentralityCorrelationsCutTreshold{"cfCentralityCorrelationsCutTreshold", 10.0, "set the treshold for centrality correlation cut"}; + Configurable cfCentralityCorrelationsCutVersion{"cfCentralityCorrelationsCutVersion", "Absolute", "set the version of centrality correlation cut. Supported: \"Relative\" and \"Absolute\""}; + Configurable cfUseFT0Bad{"cfUseFT0Bad", false, "TBI 20250516 explanation (or see enum)"}; + Configurable cfUseITSBad{"cfUseITSBad", false, "TBI 20250516 explanation (or see enum)"}; + Configurable cfUseITSLimAccMCRepr{"cfUseITSLimAccMCRepr", false, "TBI 20250516 explanation (or see enum)"}; + Configurable cfUseTPCBadTracking{"cfUseTPCBadTracking", false, "TBI 20250516 explanation (or see enum)"}; + Configurable cfUseTPCLimAccMCRepr{"cfUseTPCLimAccMCRepr", false, "TBI 20250516 explanation (or see enum)"}; + Configurable cfUseTPCBadPID{"cfUseTPCBadPID", false, "TBI 20250516 explanation (or see enum)"}; + } cf_ec; + + // *) Particle histograms: + struct : ConfigurableGroup { + Configurable cfFillParticleHistograms{"cfFillParticleHistograms", true, "if false, all 1D particle histograms are not filled. if kTRUE, the ones for which fBookParticleHistograms[...] is kTRUE, are filled"}; + Configurable> cfBookParticleHistograms{"cfBookParticleHistograms", {"1-Phi", "1-Pt", "1-Eta", "1-Charge", "1-tpcNClsFindable", "1-tpcNClsShared", "1-itsChi2NCl", "1-tpcNClsFound", "1-tpcNClsCrossedRows", "1-itsNCls", "1-itsNClsInnerBarrel", "1-tpcCrossedRowsOverFindableCls", "1-tpcFoundOverFindableCls", "1-tpcFractionSharedCls", "1-tpcChi2NCl", "1-dcaXY", "1-dcaZ", "0-PDG"}, "Book (1) or do not book (0) particle histogram"}; + Configurable cfFillParticleHistograms2D{"cfFillParticleHistograms2D", false, "if false, all 2D particle histograms are not filled. if kTRUE, the ones for which fBookParticleHistograms2D[...] is kTRUE, are filled"}; + Configurable> cfBookParticleHistograms2D{"cfBookParticleHistograms2D", {"1-Phi_vs_Pt", "1-Phi_vs_Eta"}, "Book (1) or do not book (0) 2D particle histograms"}; + Configurable> cfRebinSparse{"cfRebinSparse", {1., 1., 1., 1., 1., 1.}, "Ordering is the same as in eDiffPhiWeights. To make bins factor 2 finer use 0.5, to make bins factor 5 coarser use 5."}; + Configurable> cfBookParticleSparseHistograms{"cfBookParticleSparseHistograms", {"0-DWPhi", "0-DWPt", "0-DWEta"}, "Book (1) or do not book (0) particular category of sparse histograms"}; + Configurable cfFillParticleSparseHistogramsBeforeCuts{"cfFillParticleSparseHistogramsBeforeCuts", false, "I need sparse histograms before cuts only when testing pt and eta weights, in internal validation"}; + // TBI 20250223 add eventually configurable for FillParticleSparseHistogramsDimension + } cf_ph; + + // *) Particle cuts: + struct : ConfigurableGroup { + Configurable> cfUseParticleCuts{"cfUseParticleCuts", {"1-Phi", "1-Pt", "1-Eta", "1-Charge", "1-tpcNClsFindable", "1-tpcNClsShared", "1-itsChi2NCl", "1-tpcNClsFound", "1-tpcNClsCrossedRows", "1-itsNCls", "1-itsNClsInnerBarrel", "1-tpcCrossedRowsOverFindableCls", "1-tpcFoundOverFindableCls", "1-tpcFractionSharedCls", "1-tpcChi2NCl", "1-dcaXY", "1-dcaZ", "1-PDG", "0-trackCutFlag", "0-trackCutFlagFb1", "0-trackCutFlagFb2", "0-isQualityTrack", "1-isPrimaryTrack", "0-isInAcceptanceTrack", "0-isGlobalTrack", "1-isPVContributor", "0-PtDependentDCAxyParameterization"}, "Use (1) or do not use (0) particle cuts"}; + Configurable cfUseParticleCutCounterAbsolute{"cfUseParticleCutCounterAbsolute", false, "profile and save how many times each particle cut counter triggered (absolute). Use with care, as this is computationally heavy"}; + Configurable cfUseParticleCutCounterSequential{"cfUseParticleCutCounterSequential", false, "profile and save how many times each particle cut counter triggered (sequential). Use with care, as this is computationally heavy"}; + Configurable> cfPhi{"cfPhi", {0.0, o2::constants::math::TwoPI}, "phi range: {min, max}[rad], with convention: min <= phi < max"}; + Configurable> cfPt{"cfPt", {0.2, 5.0}, "pt range: {min, max}[GeV], with convention: min <= pt < max"}; + Configurable> cfEta{"cfEta", {-0.8, 0.8}, "eta range: {min, max}, with convention: min <= eta < max"}; + Configurable> cfCharge{"cfCharge", {-2.0, 2.0}, "particle charge. {-2.0,0} = only negative, {0,2.0} = only positive (keep in sync with res.fResultsProBinEdges[AFO_CHARGE])"}; + Configurable> cftpcNClsFindable{"cftpcNClsFindable", {-1000., 1000.}, "tpcNClsFindable range: {min, max}, with convention: min <= cftpcNClsFindable < max"}; + Configurable> cftpcNClsShared{"cftpcNClsShared", {-1000., 1000.}, "tpcNClsShared range: {min, max}, with convention: min <= cftpcNClsShared < max"}; + Configurable> cfitsChi2NCl{"cfitsChi2NCl", {-1000., 36.}, "itsChi2NCl range: {min, max}, with convention: min <= cfitsChi2NCl < max"}; + Configurable> cftpcNClsFound{"cftpcNClsFound", {70., 1000.}, "tpcNClsFound range: {min, max}, with convention: min <= cftpcNClsFound < max"}; + Configurable> cftpcNClsCrossedRows{"cftpcNClsCrossedRows", {70., 1000.}, "tpcNClsCrossedRows range: {min, max}, with convention: min <= tpcNClsCrossedRows < max"}; + Configurable> cfitsNCls{"cfitsNCls", {5., 1000.}, "itsNCls range: {min, max}, with convention: min <= itsNCls < max"}; + Configurable> cfitsNClsInnerBarrel{"cfitsNClsInnerBarrel", {-1000., 1000.}, "itsNClsInnerBarrel range: {min, max}, with convention: min <= cfitsNClsInnerBarrel < max"}; + Configurable> cftpcCrossedRowsOverFindableCls{"cftpcCrossedRowsOverFindableCls", {0.8, 1000.}, "tpcCrossedRowsOverFindableCls range: {min, max}, with convention: min <= cftpcCrossedRowsOverFindableCls < max"}; + Configurable> cftpcFoundOverFindableCls{"cftpcFoundOverFindableCls", {0.8, 1000.}, "tpcFoundOverFindableCls range: {min, max}, with convention: min <= cftpcFoundOverFindableCls < max"}; + Configurable> cftpcFractionSharedCls{"cftpcFractionSharedCls", {-1000., 0.4}, "tpcFractionSharedCls range: {min, max}, with convention: min <= cftpcFractionSharedCls < max"}; + Configurable> cftpcChi2NCl{"cftpcChi2NCl", {-1000., 4.}, "tpcChi2NCl range: {min, max}, with convention: min <= cftpcChi2NCl < max"}; + Configurable> cfdcaXY{"cfdcaXY", {-2.4, 2.4}, "dcaXY range: {min, max}, with convention: min <= dcaXY < max (yes, DCA can be negative!)"}; + Configurable> cfdcaZ{"cfdcaZ", {-3.2, 3.2}, "dcaZ range: {min, max}, with convention: min <= dcaZ < max (yes, DCA can be negative!)"}; + Configurable> cfPDG{"cfPDG", {-5000., 5000.}, "PDG code"}; + Configurable cftrackCutFlag{"cftrackCutFlag", false, "general selection, particle cuts are tuned centrally. Use only in Run 3."}; + Configurable cftrackCutFlagFb1{"cftrackCutFlagFb1", false, "general selection + 1 point in ITS IB. Use only in Run 3."}; + Configurable cftrackCutFlagFb2{"cftrackCutFlagFb2", false, "general selection + 2 point in ITS IB. Use only in Run 3."}; + Configurable cfisQualityTrack{"cfisQualityTrack", false, "TBI 20240510 add description"}; + Configurable cfisPrimaryTrack{"cfisPrimaryTrack", true, "Set to true by default both in Run 3 and Run 2 TBI 20250319 validate still for Run 1"}; + Configurable cfisInAcceptanceTrack{"cfisInAcceptanceTrack", false, "TBI 20250113 obsolete - see enum, to be removed"}; + Configurable cfisGlobalTrack{"cfisGlobalTrack", false, "TBI 20240510 add description"}; + Configurable cfisPVContributor{"cfisPVContributor", false, "Has this track contributed to the collision vertex fit"}; + Configurable cfPtDependentDCAxyParameterization{"cfPtDependentDCAxyParameterization", "some formula TBI add some default formula, e.g. 0.0105+0.0350/x^1.1", "set here formula for pt-dependence DCAxy cut, in the following example format 0.0105+0.0350/x^1.1"}; + // TBI 20240426 do I need to add separate support for booleans to use each specific cut? + } cf_pc; + + // *) Q-vector: + struct : ConfigurableGroup { + Configurable cfCalculateQvectors{"cfCalculateQvectors", true, "calculate or not Q-vectors (all, also diff. ones). If I want only to fill control histograms, then set here false"}; + } cf_qv; + + // *) Multiparticle correlations: + struct : ConfigurableGroup { + Configurable cfCalculateCorrelations{"cfCalculateCorrelations", false, "calculate or not multiparticle correlations"}; + Configurable> cfCalculateCorrelationsAsFunctionOf{"cfCalculateCorrelationsAsFunctionOf", {"1-Integrated", "1-Multiplicity", "1-Centrality", "0-Pt", "0-Eta", "1-Occupancy", "1-InteractionRate", "1-CurrentRunDuration", "1-Vz", "0-Charge"}, "calculate or not correlations as a function of specified variable"}; + } cf_mupa; + + // *) Test0: + struct : ConfigurableGroup { + + // 1D: + Configurable cfCalculateTest0{"cfCalculateTest0", false, "calculate or not Test0"}; + Configurable> cfCalculateTest0AsFunctionOf{"cfCalculateTest0AsFunctionOf", {"1-Integrated", "1-Multiplicity", "1-Centrality", "1-Pt", "1-Eta", "1-Occupancy", "1-InteractionRate", "1-CurrentRunDuration", "1-Vz", "1-Charge"}, "calculate or not correlations as a function of specified variable"}; + + // 2D: + Configurable cfCalculate2DTest0{"cfCalculate2DTest0", false, "calculate or not 2D Test0 using TProfile2D"}; + Configurable> cfCalculate2DTest0AsFunctionOf{"cfCalculate2DTest0AsFunctionOf", {"1-Centrality_Pt", "1-Centrality_Eta", "1-Centrality_Charge", "1-Centrality_Vz", "1-Pt_Eta", "1-Pt_Charge", "1-Eta_Charge"}, "calculate or not correlations in 2D as a function of two specified variables."}; + + // 3D: + Configurable cfCalculate3DTest0{"cfCalculate3DTest0", false, "calculate or not 3D Test0 using TProfile3D"}; + Configurable> cfCalculate3DTest0AsFunctionOf{"cfCalculate3DTest0AsFunctionOf", {"1-Centrality_Pt_Eta", "1-Centrality_Pt_Charge", "1-Centrality_Pt_Vz", "1-Centrality_Eta_Vz", "1-Centrality_Eta_Charge", "1-Centrality_Vz_Charge", "1-Pt_Eta_Charge"}, "calculate or not correlations in 3D as a function of three specified variables."}; + + Configurable cfFileWithLabels{"cfFileWithLabels", "/home/abilandz/DatasetsO2/labels.root", "path to external ROOT file which specifies all labels"}; // for AliEn file prepend "/alice/cern.ch/", for CCDB prepend "/alice-ccdb.cern.ch" + Configurable cfUseDefaultLabels{"cfUseDefaultLabels", false, "use default internally hardwired labels, only for testing purposes"}; + Configurable cfWhichDefaultLabels{"cfWhichDefaultLabels", "standard", "only for testing purposes, select one set of default labels, see GetDefaultObjArrayWithLabels for supported options"}; + } cf_t0; + + // *) Eta separation: + struct : ConfigurableGroup { + Configurable cfCalculateEtaSeparations{"cfCalculateEtaSeparations", false, "calculate or not 2p corr. vs. eta separations"}; + Configurable> cfCalculateEtaSeparationsAsFunctionOf{"cfCalculateEtaSeparationsAsFunctionOf", {"1-Integrated", "1-Multiplicity", "1-Centrality", "1-Pt", "0-Eta", "1-Occupancy", "1-InteractionRate", "1-CurrentRunDuration", "1-Vz", "1-Charge"}, "calculate or not correlations as a function of specified variable"}; + Configurable> cfEtaSeparationsValues{"cfEtaSeparationsValues", {0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8}, "Eta separation between interval A (-eta) and B (+eta)"}; + Configurable> cfEtaSeparationsSkipHarmonics{"cfEtaSeparationsSkipHarmonics", {"0-v1", "0-v2", "0-v3", "0-v4", "1-v5", "1-v6", "1-v7", "1-v8", "1-v9"}, "For calculation of 2p correlation with eta separation these harmonics will be skipped (if first flag = \"0-v1\", v1 will be NOT be skipped in the calculus of 2p correlations with eta separations, etc.)"}; + } cf_es; + + // *) Particle weights: + struct : ConfigurableGroup { + Configurable cfUsePhiWeights{"cfUsePhiWeights", false, "use or not phi weights"}; + Configurable cfUsePtWeights{"cfUsePtWeights", false, "use or not pt weights"}; + Configurable cfUseEtaWeights{"cfUseEtaWeights", false, "use or not eta weights"}; + Configurable cfUseDiffPhiPtWeights{"cfUseDiffPhiPtWeights", false, "use or not differential phi(pt) weights"}; + Configurable cfUseDiffPhiEtaWeights{"cfUseDiffPhiEtaWeights", false, "use or not differential phi(eta) weights"}; + Configurable> cfWhichDiffPhiWeights{"cfWhichDiffPhiWeights", {"1-wPhi", "1-wPt", "1-wEta", "1-wCharge", "1-wCentrality", "1-wVertexZ"}, "use (1) or do not use (0) differential phi weight for particular dimension. If only phi is set to 1, integrated phi weights are used. If phi is set to 0, ALL dimensions are switched off (yes!)"}; + Configurable> cfWhichDiffPtWeights{"cfWhichDiffPtWeights", {"0-wPt", "0-wEta", "0-wCharge", "0-wCentrality"}, "use (1) or do not use (0) differential pt weight for particular dimension. If only pt is set to 1, integrated pt weights are used. If pt is set to 0, ALL dimensions are switched off (yes!)"}; + Configurable> cfWhichDiffEtaWeights{"cfWhichDiffEtaWeights", {"0-wEta", "0-wPt", "0-wCharge", "0-wCentrality"}, "use (1) or do not use (0) differential eta weight for particular dimension. If only eta is set to 1, integrated eta weights are used. If eta is set to 0, ALL dimensions are switched off (yes!)"}; + Configurable cfFileWithWeights{"cfFileWithWeights", "/home/abilandz/DatasetsO2/weights.root", "path to external ROOT file which holds all particle weights in O2 format"}; // for AliEn file prepend "/alice/cern.ch/", for CCDB prepend "/alice-ccdb.cern.ch" + } cf_pw; + + // *) Centrality weights: + struct : ConfigurableGroup { + Configurable cfUseCentralityWeights{"cfUseCentralityWeights", false, "use or not centrality weights"}; + Configurable cfFileWithCentralityWeights{"cfFileWithCentralityWeights", "/home/abilandz/DatasetsO2/centralityWeights.root", "path to external ROOT file which holds centrality weights in O2 format"}; // for AliEn file prepend "/alice/cern.ch/", for CCDB prepend "/alice-ccdb.cern.ch" + } cf_cw; + + // *) Nested loops: + struct : ConfigurableGroup { + Configurable cfCalculateNestedLoops{"cfCalculateNestedLoops", false, "cross-check for all events all correlations with nested loops"}; + Configurable cfCalculateCustomNestedLoops{"cfCalculateCustomNestedLoops", false, "cross-check e-b-e all correlations with custom nested loops"}; + Configurable cfCalculateKineCustomNestedLoops{"cfCalculateKineCustomNestedLoops", false, "cross-check e-b-e all differential (vs. pt, eta, etc.) correlations with custom nested loops"}; + Configurable cfMaxNestedLoop{"cfMaxNestedLoop", -1, "if set to e.g. 4, all nested loops beyond that, e.g. 6-p and 8-p, are NOT calculated"}; + } cf_nl; + + // *) Toy NUA: + struct : ConfigurableGroup { + Configurable> cfApplyNUAPDF{"cfApplyNUAPDF", {0, 0, 0}, "Apply (1) or do not apply (0) NUA on variable, ordering is the same as in enum eNUAPDF (phi, pt, eta)"}; + Configurable> cfUseDefaultNUAPDF{"cfUseDefaultNUAPDF", {1, 1, 1}, "Use (1) or do not use (0) default NUA profile, ordering is the same as in enum eNUAPDF (phi, pt, eta)"}; + Configurable> cfCustomNUAPDFHistNames{"cfCustomNUAPDFHistNames", {"a", "bb", "ccc"}, "the names of histograms holding custom NUA in an external file."}; + Configurable cfFileWithCustomNUA{"cfFileWithCustomNUA", "/home/abilandz/DatasetsO2/customNUA.root", "path to external ROOT file which holds all histograms with custom NUA"}; // for AliEn file prepend "/alice/cern.ch/", for CCDB prepend "/alice-ccdb.cern.ch" + } cf_nua; + + // *) Internal validation: + struct : ConfigurableGroup { + Configurable cfUseInternalValidation{"cfUseInternalValidation", false, "perform internal validation using flow analysis on-the-fly"}; + Configurable cfInternalValidationForceBailout{"cfInternalValidationForceBailout", false, "force bailout (use only locally, since there is no graceful exit (yet))"}; + Configurable cfnEventsInternalValidation{"cfnEventsInternalValidation", 0, "number of events simulated on-the-fly for internal validation"}; + Configurable cfHarmonicsOptionInternalValidation{"cfHarmonicsOptionInternalValidation", "constant", "for internal validation, supported options are \"constant\", \"correlated\", \"persistent\", \"ptDependent\", and \"ptEtaDependent\""}; + Configurable cfRescaleWithTheoreticalInput{"cfRescaleWithTheoreticalInput", false, "if kTRUE, all correlators are rescaled with theoretical input, so that all results in profiles are 1"}; + Configurable cfRandomizeReactionPlane{"cfRandomizeReactionPlane", true, "set to false only when validating against theoretical value the non-isotropic correlators"}; + Configurable> cfInternalValidationAmplitudes{"cfInternalValidationAmplitudes", {0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09}, "{v1, v2, v3, v4, ...} + has an effect only in combination with cfHarmonicsOptionInternalValidation = \"constant\". Max number of vn's is gMaxHarmonic."}; + Configurable> cfInternalValidationPlanes{"cfInternalValidationPlanes", {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, "{Psi1, Psi2, Psi3, Psi4, ...} + has an effect only in combination with cfHarmonicsOptionInternalValidation = \"constant\". Max number of Psin's is gMaxHarmonic."}; + Configurable> cfMultRangeInternalValidation{"cfMultRangeInternalValidation", {1000, 1001}, "{min, max}, with convention: min <= M < max"}; + } cf_iv; + + // *) Results histograms: + struct : ConfigurableGroup { + Configurable cfSaveResultsHistograms{"cfSaveResultsHistograms", false, "save or not results histograms"}; + + // Fixed-length binning (default): + Configurable> cfFixedLengthMultBins{"cfFixedLengthMultBins", {2000, 0., 20000.}, "nMultBins, multMin, multMax (only for results histograms)"}; + Configurable> cfFixedLengthCentBins{"cfFixedLengthCentBins", {110, 0., 110.}, "nCentBins, centMin, centMax (only for results histograms)"}; + Configurable> cfFixedLengthPtBins{"cfFixedLengthPtBins", {1000, 0., 10.}, "nPtBins, ptMin, ptMax (only for results histograms)"}; + Configurable> cfFixedLengthEtaBins{"cfFixedLengthEtaBins", {80, -2., 2.}, "nEtaBins, etaMin, etaMax (only for results histograms)"}; + Configurable> cfFixedLengthOccuBins{"cfFixedLengthOccuBins", {200, 0., 60000.}, "nOccuBins, occuMin, occuMax (only for results histograms)"}; + Configurable> cfFixedLengthIRBins{"cfFixedLengthIRBins", {1000, 0., 100.}, "nirBins, irMin, irMax (only for results histograms)"}; + Configurable> cfFixedLengthCRDBins{"cfFixedLengthCRDBins", {100000, 0., 100000.}, "ncrdBins, crdMin, crdMax (only for results histograms)"}; + Configurable> cfFixedLengthVzBins{"cfFixedLengthVzBins", {400, -20., 20.}, "nvzBins, vzMin, vzMax (only for results histograms)"}; + + // Variable-length binning (per request): + Configurable cfUseVariableLengthMultBins{"cfUseVariableLengthMultBins", false, "use or not variable-length multiplicity bins"}; + Configurable> cfVariableLengthMultBins{"cfVariableLengthMultBins", {0., 5., 6., 7., 8., 9., 100., 200., 500., 1000., 10000.}, "variable-length multiplicity bins"}; + Configurable cfUseVariableLengthCentBins{"cfUseVariableLengthCentBins", false, "use or not variable-length centrality bins"}; + Configurable> cfVariableLengthCentBins{"cfVariableLengthCentBins", {0., 10., 50., 100.}, "variable-length centrality bins"}; + Configurable cfUseVariableLengthPtBins{"cfUseVariableLengthPtBins", true, "use or not variable-length pt bins"}; + Configurable> cfVariableLengthPtBins{"cfVariableLengthPtBins", {0.20, 0.25, 0.30, 0.35, 0.40, 0.50, 0.60, 0.80, 1.00, 1.25, 1.50, 1.75, 2.00, 2.50, 3.00, 4.00, 5.00}, "variable-length pt bins"}; + Configurable cfUseVariableLengthEtaBins{"cfUseVariableLengthEtaBins", true, "use or not variable-length eta bins"}; + Configurable> cfVariableLengthEtaBins{"cfVariableLengthEtaBins", {-0.8, -0.6, -0.4, -0.3, -0.2, -0.1, 0.0, 0.1, 0.2, 0.3, 0.4, 0.6, 0.8}, "variable-length eta bins"}; + Configurable cfUseVariableLengthOccuBins{"cfUseVariableLengthOccuBins", false, "use or not variable-length occupancy bins"}; + Configurable> cfVariableLengthOccuBins{"cfVariableLengthOccuBins", {0., 5., 6., 7., 8., 9., 100., 200., 500., 1000., 10000.}, "variable-length occupancy bins"}; + Configurable cfUseVariableLengthIRBins{"cfUseVariableLengthIRBins", false, "use or not variable-length interaction rate bins"}; + Configurable> cfVariableLengthIRBins{"cfVariableLengthIRBins", {0., 5., 10., 50., 100., 200.}, "variable-length ineraction rate bins"}; + Configurable cfUseVariableLengthCRDBins{"cfUseVariableLengthCRDBins", false, "use or not variable-length current run duration bins"}; + Configurable> cfVariableLengthCRDBins{"cfVariableLengthCRDBins", {0., 5., 10., 50., 100., 500.}, "variable-length current run duration bins"}; + Configurable cfUseVariableLengthVzBins{"cfUseVariableLengthVzBins", false, "use or not variable-length vertex z bins"}; + Configurable> cfVariableLengthVzBins{"cfVariableLengthVzBins", {-10., -8., -6., -4, -2., -1., 0., 1., 2., 4., 6., 8., 10.}, "variable-length vertex z bins"}; + + } cf_res; + + // *) Data members: + + // General remarks: + // 0. Starting with C++11, it's possible to initialize data members at declaration, so I do it here + // 1. Use //! fBaseList{sBaseListName.Data(), + o2::framework::OutputObjHandlingPolicy::AnalysisObject, + o2::framework::OutputObjSourceType::OutputObjSource}; + TProfile* fBasePro = NULL; //! 0. Set to <=0 to ignore. + + bool fUseStopwatch = false; // do some basing profiling with TStopwatch for where the execution time is going + TStopwatch* fTimer[eTimer_N] = {NULL}; // stopwatch, global (overal execution time) and local + float fFloatingPointPrecision = 1.e-6; // two floats are the same if abs(f1 - f2) < fFloatingPointPrecision (there is configurable for it) + int fSequentialBailout = 0; // if fSequentialBailout > 0, then each fSequentialBailout events the function BailOut() is called. Can be used for real analysis and for IV. + bool fUseSpecificCuts = false; // apply after DefaultCuts() also hardwired analysis-specific cuts, determined via tc.fWhichSpecificCuts + TString fWhichSpecificCuts = ""; // determine which set of analysis-specific cuts will be applied after DefaultCuts(). Use in combination with tc.fUseSpecificCuts + TString fSkipTheseRuns = ""; // comma-separated list of runs which will be skipped during analysis in hl (a.k.a. "bad runs") + bool fSkipRun = false; // based on the content of fWhichSpecificCuts, skip or not the current run + bool fCalculateAsFunctionOf[eAsFunctionOf_N] = {false}; //! [0=integrated,1=vs. multiplicity,2=vs. centrality,3=pT,4=eta,5=vs. occupancy, ...] + // Example: tc.fCalculateAsFunctionOf[AFO_PT] = mupa.fCalculateCorrelationsAsFunctionOf[AFO_PT] || t0.fCalculateTest0AsFunctionOf[AFO_PT] + // || es.fCalculateEtaSeparationsAsFunctionOf[AFO_PT] + bool fCalculate2DAsFunctionOf[eAsFunctionOf2D_N] = {false}; //! See example above for 1D case + enum for 2D details + bool fCalculate3DAsFunctionOf[eAsFunctionOf3D_N] = {false}; //! See example above for 1D case + enum for 3D details + TDatabasePDG* fDatabasePDG = NULL; // booked only when MC info is available. There is a standard memory blow-up when booked, therefore I need to request also fUseDatabasePDG = true + // TBI 20250625 replace eventually with the service O2DatabasePDG, when memory consumption problem is resolved + bool fUseSetBinLabel = false; // until SetBinLabel(...) large memory consumption is resolved, do not use hist->SetBinLabel(...), see ROOT Forum + // See also local executable PostprocessLabels.C + bool fUseClone = false; // until Clone(...) large memory consumption is resolved, do not use hist->Clone(...), see ROOT Forum + bool fUseFormula = false; // until TFormula large memory consumption is resolved, do not use, see ROOT Forum + bool fUseDatabasePDG = false; // I use it at the moment only to retreive charge for MC particle from its PDG code, because there is no direct getter mcParticle.sign() + // But most likely I will use it to retrieve other particle proprties from PDG table. There is a standard memory blow-up when used. + } tc; // "tc" labels an instance of this group of variables. + + // *) Event-by-event quantities: + struct EventByEventQuantities { + int fSelectedTracks = 0; // integer counter of tracks used to calculate Q-vectors, after all particle cuts have been applied + float fMultiplicity = 0.; // my internal multiplicity, can be set to fSelectedTracks (calculated internally), fReferenceMultiplicity (calculated outside of my code), etc. + // Results "vs. mult" are plotted against fMultiplicity, whatever it is set to. + // Use configurable cfMultiplicityEstimator[eMultiplicityEstimator] to define what is this multiplicity, by default it is "SelectedTracks" + float fReferenceMultiplicity = 0.; // reference multiplicity, calculated outside of my code. Can be "MultTPC", "MultFV0M", etc. + // Use configurable cfReferenceMultiplicityEstimator[eReferenceMultiplicityEstimator]" to define what is this multiplicity, + // by default it is "TBI 20241123 I do not know yet which estimator is best for ref. mult." + float fCentrality = 0.; // event-by-event centrality, in reconstructed data. Value of the default centrality estimator, set via configurable cfCentralityEstimator + float fCentralitySim = 0.; // event-by-event centrality, in simulated data. Calculated directly from IP at the moment, eventually I will access it from o2::aod::hepmcheavyion::Centrality + float fOccupancy = 0.; // event-by-event occupancy. Value of the default occupancy estimator, set via configurable cfOccupancyEstimator. + // Remebmer that collision with occupanct 0. shall NOT be rejected, therefore in configurable I set -0.0001 for low edge by default. + float fInteractionRate = 0.; // event-by-event interaction rate + float fCurrentRunDuration = 0.; // how many seconds after start of run this collision was taken, i.e. seconds after start of run (SOR) + float fVz = 0.; // vertex z position + float fVzSim = 0.; // vertex z position, in simulated data + float fFT0CAmplitudeOnFoundBC = 0.; // TBI20250331 finalize the comment here + float fImpactParameter = 0.; // calculated only for simulated/generated data + } ebye; // "ebye" is a common label for objects in this struct + + // *) Particle-by-particle quantities: + // Remark: Here I define all particle quantities, that I need across several member functions. + struct ParticleByParticleQuantities { + double fPhi = 0.; // azimuthal angle + double fPt = 0.; // transverse momentum + double fEta = 0.; // pseudorapidity + double fCharge = -44.; // particle charge. Yes, never initialize charge to 0. + } pbyp; + + // *) QA: + // Remark 1: I keep new histograms in this group, until I need them permanently in the analysis. Then, they are moved to EventHistograms or ParticleHistograms (yes, even if they are 2D). + // Remark 2: All 2D histograms book as TH2F, due to "stmem error" in terminate (see .cxx for further details) + struct QualityAssurance { + TList* fQAList = NULL; //! event-by-event + // [reco, sim][before, after]. Type dimension is bin. + + TList* fQACorrelationsVsList = NULL; //!>> fQ; // generic Q-vector + TComplex fQvector[gMaxHarmonic * gMaxCorrelator + 1][gMaxCorrelator + 1] = {{TComplex(0., 0.)}}; //! integrated Q-vector, legacy code (TBI 20250718 remove, and switch to line below eventually) + // std::vector>> fQvector; // dynamically allocated integrated Q-vector => it has to be done this way, to optimize memory usage + + bool fCalculateqvectorsKineAny = false; // by default, it's off. It's set to true automatically if any of kine correlators is requested, + // either for Correlations, Test0, EtaSeparations, etc. + bool fCalculateqvectorsKine[eqvectorKine_N] = {false}; // same as above, just specifically for each enum eqvectorKine + applies only to Correlations and Test0 + bool fCalculateqvectorsKineEtaSeparations[eqvectorKine_N] = {false}; // same as above, just specifically for each enum eqvectorKine + applies only to EtaSeparations + + std::vector>>>> fqvector; // dynamically allocated differential q-vector => it has to be done this way, to optimize memory usage + // dimensions: [eqvectorKine_N][gMaxNoBinsKine][gMaxHarmonic * gMaxCorrelator + 1][gMaxCorrelator + 1] + std::vector fNumberOfKineBins = {0}; // for each kine vector which was requested in this analysis, here I calculate and store the corresponding number of kine bins + std::vector> fqvectorEntries; // dynamically allocated number of entries for differential q-vector => it has to be done this way, to optimize memory usage. Dimensions: [eqvectorKine_N][gMaxNoBinsKine] + + // q-vectors for eta separations: + TComplex fQabVector[2][gMaxHarmonic][gMaxNumberEtaSeparations] = {{{TComplex(0., 0.)}}}; //! integrated [-eta or +eta][harmonic][eta separation] + float fMab[2][gMaxNumberEtaSeparations] = {{0.}}; //! multiplicities in 2 eta separated intervals + TH1F* fMabDist[2][2][2][gMaxNumberEtaSeparations] = {{{{NULL}}}}; // multiplicity distributions in A and B, for each eta separation [ A or B ] [rec or sim] [ before or after cuts ] [ eta separation value ] + std::vector>>>>> fqabVector; // dynamically allocated differential q-vector. + // dimensions: [-eta or +eta][eqvectorKine_N][global binNo][harmonic][eta separation] + // Remark: Unlike fqvector above, here I support only 2-p correlations, + // therefore no need for "[gMaxHarmonic * gMaxCorrelator + 1][gMaxCorrelator + 1]", etc. + std::vector>>> fmab; //! multiplicities vs kine in 2 eta separated intervals + // [-eta or +eta][eqvectorKine_N][global binNo][eta separation] + } qv; // "qv" is a common label for objects in this struct + + // *) Multiparticle correlations (standard, isotropic, same harmonic): + struct MultiparticleCorrelations { + TList* fCorrelationsList = NULL; // list to hold all correlations objects + TProfile* fCorrelationsFlagsPro = NULL; // profile to hold all flags for correlations + bool fCalculateCorrelations = false; // calculate and store integrated correlations + TProfile* fCorrelationsPro[4][gMaxHarmonic][eAsFunctionOf_N] = {{{NULL}}}; //! multiparticle correlations + // [2p=0,4p=1,6p=2,8p=3][n=1,n=2,...,n=gMaxHarmonic] + // [0=integrated,1=vs. multiplicity,2=vs. centrality,3=pT,4=eta,5=vs. occupancy, ...] + bool fCalculateCorrelationsAsFunctionOf[eAsFunctionOf_N] = {false}; //! [0=integrated,1=vs. multiplicity,2=vs. centrality,3=pT,4=eta,5=vs. occupancy, ...] + // As of 20241111, 3=pT and 4=eta are not implemented, see void CalculateKineCorrelations(...) + } mupa; // "mupa" is a common label for objects in this struct + + // *) Particle weights: + struct ParticleWeights { + TList* fWeightsList = NULL; //! TBI 20250215 this is obsolete and superseeded with fUseDiffPhiWeights, etc. + TH1D* fDiffWeightsHist[eDiffWeights_N][gMaxBinsDiffWeights] = {{NULL}}; // histograms holding differential weights [phipt,phieta][bin number] => TBI 20250222 obsolete + + // ** sparse histograms: + THnSparse* fDiffWeightsSparse[eDiffWeightCategory_N] = {NULL}; // multidimensional sparse histogram to hold all differential phi-weights (as a function of pt, eta, etc.). + // each dimension has its own enum category, e.g. 0 = eDWPhi => eDiffPhiWeights, 1 = eDWPt => eDiffPtWeights, etc. + bool fUseDiffPhiWeights[eDiffPhiWeights_N] = {false}; // use differential phi weights, see enum eDiffPhiWeights for supported dimensions + bool fUseDiffPtWeights[eDiffPtWeights_N] = {false}; // use differential pt weights, see enum eDiffPtWeights for supported dimensions + bool fUseDiffEtaWeights[eDiffEtaWeights_N] = {false}; // use differential eta weights, see enum eDiffEtaWeights for supported dimensions + // ... + int fDWdimension[eDiffWeightCategory_N] = {0}; // dimension of differential weight for each category in current analysis + TArrayD* fFindBinVector[eDiffWeightCategory_N] = {NULL}; // this is the vector I use to find bin when I obtain weights with sparse histograms + + TString fFileWithWeights = ""; // path to external ROOT file which holds all particle weights + bool fParticleWeightsAreFetched = false; // ensures that particle weights are fetched only once + } pw; // "pw" labels an instance of this group of histograms + + // *) Centrality weights: + struct CentralityWeights { + TList* fCentralityWeightsList = NULL; // list to hold all Q-vector objects + TProfile* fCentralityWeightsFlagsPro = NULL; // profile to hold all flags for CentralityWeights + bool fUseCentralityWeights = false; // use centrality weights + TH1D* fCentralityWeightsHist = NULL; // histograms holding centrality weights + TString fFileWithCentralityWeights = ""; // path to external ROOT file which holds all centrality weights + bool fCentralityWeightsAreFetched = false; // ensures that centrality weights are fetched only once + } cw; + + // *) Nested loops: + struct NestedLoops { + TList* fNestedLoopsList = NULL; // list to hold all nested loops objects + TProfile* fNestedLoopsFlagsPro = NULL; // profile to hold all flags for nested loops + bool fCalculateNestedLoops = false; // calculate and store correlations with nested loops, as a cross-check + bool fCalculateCustomNestedLoops = false; // validate e-b-e all correlations with custom nested loop + bool fCalculateKineCustomNestedLoops = false; // validate e-b-e all differential (vs pt, eta, etc.) correlations with custom nested loop + int fMaxNestedLoop = -1; // if set to e.g. 4, all nested loops beyond that, e.g. 6-p and 8-p, are NOT calculated + TProfile* fNestedLoopsPro[4][gMaxHarmonic][eAsFunctionOf_N] = {{{NULL}}}; //! multiparticle correlations from nested loops + //! [2p=0,4p=1,6p=2,8p=3][n=1,n=2,...,n=gMaxHarmonic][0=integrated,1=vs. + //! multiplicity,2=vs. centrality,3=pT,4=eta] + TArrayD* ftaNestedLoops[2] = {NULL}; //! e-b-e container for nested loops [0=angles;1=product of all weights] + TArrayD* ftaNestedLoopsKine[eqvectorKine_N][gMaxNoBinsKine][2] = {{{NULL}}}; //! e-b-e container for nested loops // [0=pT,1=eta,2=...][kine bin][0=angles;1=product of all weights] + } nl; // "nl" labels an instance of this group of histograms + + // *) Toy NUA (can be applied both in real data analysis and in analysis 'on-the-fly', e.g. when running internal validation): + struct NUA { + TList* fNUAList = NULL; // list to hold all NUA objects + TProfile* fNUAFlagsPro = NULL; // profile to hold all flags for NUA objects + bool fApplyNUAPDF[eNUAPDF_N] = {false}; // apply NUA to particular kine variable (see the corresponding enum eNUAPDF) + bool fUseDefaultNUAPDF[eNUAPDF_N] = {true, true, true}; // by default, use simple hardcoded expressions for NUA acceptance profile + TF1* fDefaultNUAPDF[eNUAPDF_N] = {NULL}; // default distributions used as pdfs to simulate NUA on-the-fly + TH1D* fCustomNUAPDF[eNUAPDF_N] = {NULL}; // custom, user-supplied distributions used to simulate NUA + TString* fCustomNUAPDFHistNames[eNUAPDF_N] = {NULL}; // these are the names of histograms holding custom NUA in an external file. There is a configurable for this one. + TString fFileWithCustomNUA = ""; // path to external ROOT file which holds all histograms with custom NUA + float fMaxValuePDF[eNUAPDF_N] = {0.}; // see algorithm used in Accept(...). I implemented it as a data member, so that it is not calculated again and again at each particle call + } nua; + + // *) Internal validation: + struct InternalValidation { + TList* fInternalValidationList = NULL; // list to hold all objects for internal validation + TProfile* fInternalValidationFlagsPro = NULL; // profile to hold all flags for internal validation + bool fUseInternalValidation = false; // use internal validation + bool fInternalValidationForceBailout = false; // force bailout in internal validation after either eNumberOfEvents or eSelectedEvents is reached. + // This is OK as long as I do not apply any event cuts in InternalValidation(). + // Remember that for each real event, I do fnEventsInternalValidation events on-the-fly. + // Can be used in combination with setting fSequentialBailout > 0. + unsigned int fnEventsInternalValidation = 0; // how many on-the-fly events will be sampled for each real event, for internal validation + TString* fHarmonicsOptionInternalValidation = NULL; // "constant", "correlated", "persistent", "ptDependent", "ptEtaDependent", see .cxx for full documentation + bool fRescaleWithTheoreticalInput = false; // if true, all measured correlators are rescaled with theoretical input, so that in profiles everything is at 1 + bool fRandomizeReactionPlane = true; // if true, RP is randomized e-by-e. I need false basically only when validating against theoretical input non-isotropic correlators + TArrayD* fInternalValidationVnPsin[2] = {NULL}; // 0 = { v1, v2, ... }, 1 = { Psi1, Psi2, ... } + int fMultRangeInternalValidation[2] = {0, 0}; // min and max values for uniform multiplicity distribution in on-the-fly analysis (convention: min <= M < max) + } iv; + + // *) Test0: + struct Test0 { + TList* fTest0List = NULL; // list to hold all objects for Test0 + TProfile* fTest0FlagsPro = NULL; // store all flags for Test0 + bool fCalculateTest0 = false; // calculate or not Test0 + TProfile* fTest0Pro[gMaxCorrelator][gMaxIndex][eAsFunctionOf_N] = {{{NULL}}}; //! [order][index][0=integrated,1=vs. multiplicity,2=vs. centrality,3=pT,4=eta] + bool fCalculate2DTest0 = false; // calculate or not 2D Test0 + TProfile2D* fTest0Pro2D[gMaxCorrelator][gMaxIndex][eAsFunctionOf2D_N] = {{{NULL}}}; //! [order][index][0=cent vs pt, ..., see enum eAsFunctionOf2D] + bool fCalculate3DTest0 = false; // calculate or not 2D Test0 + TProfile3D* fTest0Pro3D[gMaxCorrelator][gMaxIndex][eAsFunctionOf3D_N] = {{{NULL}}}; //! [order][index][0=cent vs pt vs eta, ..., see enum eAsFunctionOf3D] + TString* fTest0Labels[gMaxCorrelator][gMaxIndex] = {{NULL}}; // all labels: k-p'th order is stored in k-1'th index. So yes, I also store 1-p + bool fCalculateTest0AsFunctionOf[eAsFunctionOf_N] = {false}; //! [0=integrated,1=vs. multiplicity,2=vs. centrality,3=pT,4=eta,5=vs. occupancy, ...] + bool fCalculate2DTest0AsFunctionOf[eAsFunctionOf2D_N] = {false}; //! [0=integrated,1=vs. multiplicity,2=vs. centrality,3=pT,4=eta,5=vs. occupancy, ...] + bool fCalculate3DTest0AsFunctionOf[eAsFunctionOf3D_N] = {false}; //! [0=integrated,1=vs. multiplicity,2=vs. centrality,3=pT,4=eta,5=vs. occupancy, ...] + TString fFileWithLabels = ""; // path to external ROOT file which specifies all labels of interest + bool fUseDefaultLabels = false; // use default labels hardwired in GetDefaultObjArrayWithLabels(), the choice is made with cfWhichDefaultLabels + TString fWhichDefaultLabels = ""; // only for testing purposes, select one set of default labels, see GetDefaultObjArrayWithLabels for supported options + } t0; // "t0" labels an instance of this group of histograms + + // *) Eta separations: + struct EtaSeparations { + TList* fEtaSeparationsList; // list to hold all correlations with eta separations + TProfile* fEtaSeparationsFlagsPro; // profile to hold all flags for correlations with eta separations + bool fCalculateEtaSeparations; // calculate correlations with eta separations + bool fCalculateEtaSeparationsAsFunctionOf[eAsFunctionOf_N] = {false}; //! [0=integrated,1=vs. multiplicity,2=vs. centrality,3=pT,4=eta,5=vs. occupancy, ...] + float fEtaSeparationsValues[gMaxNumberEtaSeparations] = {-1.}; // this array holds eta separation interals for which 2p correlations with eta separation will be calculated + // See the corresponding cofigurable cfEtaSeparationsValues. If entry is -1, it's ignored + bool fEtaSeparationsSkipHarmonics[gMaxHarmonic] = {false}; // For calculation of 2p correlation with eta separation these harmonics will be skipped + TProfile* fEtaSeparationsPro[gMaxHarmonic][gMaxNumberEtaSeparations][eAsFunctionOf_N]; // [harmonic, 0 = v1, 8 = v9][ different eta Separations - see that enum ] [ AFO ] + } es; + + // *) Global cosmetics: + struct GlobalCosmetics { + TString srs[2] = {"rec", "sim"}; // used in the histogram name as index when saved to the file + TString srsLong[2] = {"reconstructed", "simulated"}; // used in the histogram title + TString sba[2] = {"before", "after"}; // used in the histogram name as index when saved to the file + TString sbaLong[2] = {"before cuts", "after cuts"}; // used in the histogram title + TString scc[eCutCounter_N] = {"abs", "seq"}; // used in the histogram name as index when saved to the file + TString sccLong[eCutCounter_N] = {"absolute", "sequential"}; // used in the histogram title + } gc; + + // *) Results: + struct Results { // This is in addition also sort of "abstract" interface, which defines common binning, etc., for other groups of histograms. + TList* fResultsList = NULL; //!SetOwner(true); + fBaseList.setObject(temp); + + // b) Book base profile to hold task configuration: + fBasePro = new TProfile("fBasePro", "flags for the whole analysis", eConfiguration_N - 1, 0.5, static_cast(eConfiguration_N) - 0.5); + // yes, eConfiguration_N - 1 and -0.5, because eConfiguration kicks off from 1 + fBasePro->SetStats(false); + fBasePro->SetLineColor(eColor); + fBasePro->SetFillColor(eFillColor); + + // Remark: If I want to change the ordering of bin labels, simply change the + // ordering in enum eConfiguration { ... }, nothing needs to be changed here. + + if (tc.fUseSetBinLabel) { + + // c) Define bin labels directly via SetBinLabel(...): + fBasePro->GetXaxis()->SetBinLabel(eTaskIsConfiguredFromJson, TString::Format("fTaskIsConfiguredFromJson = %s", tc.fTaskIsConfiguredFromJson.Data())); + + fBasePro->GetXaxis()->SetBinLabel(eTaskName, Form("fTaskName = %s", tc.fTaskName.Data())); + + fBasePro->GetXaxis()->SetBinLabel(eRunNumber, Form("fRunNumber = %s", "__RUN_NUMBER__")); + // I have to do it this way via placeholder, because run number is available only when i start to process data. + // Then, I replace placeholder with run number in PropagateRunNumber(...) + + fBasePro->GetXaxis()->SetBinLabel(eDryRun, "fDryRun"); + fBasePro->Fill(eDryRun, static_cast(tc.fDryRun)); + + fBasePro->GetXaxis()->SetBinLabel(eVerbose, "fVerbose"); + fBasePro->Fill(eVerbose, static_cast(tc.fVerbose)); + + fBasePro->GetXaxis()->SetBinLabel(eVerboseUtility, "fVerboseUtility"); + fBasePro->Fill(eVerboseUtility, static_cast(tc.fVerboseUtility)); + + fBasePro->GetXaxis()->SetBinLabel(eVerboseForEachParticle, "fVerboseForEachParticle"); + fBasePro->Fill(eVerboseForEachParticle, static_cast(tc.fVerboseForEachParticle)); + + fBasePro->GetXaxis()->SetBinLabel(eVerboseEventCounter, "fVerboseEventCounter"); + fBasePro->Fill(eVerboseEventCounter, static_cast(tc.fVerboseEventCounter)); + + fBasePro->GetXaxis()->SetBinLabel(ePlainPrintout, "fPlainPrintout"); + fBasePro->Fill(ePlainPrintout, static_cast(tc.fPlainPrintout)); + + fBasePro->GetXaxis()->SetBinLabel(eDoAdditionalInsanityChecks, "fDoAdditionalInsanityChecks"); + fBasePro->Fill(eDoAdditionalInsanityChecks, static_cast(tc.fDoAdditionalInsanityChecks)); + + fBasePro->GetXaxis()->SetBinLabel(eInsanityCheckForEachParticle, "fInsanityCheckForEachParticle"); + fBasePro->Fill(eInsanityCheckForEachParticle, static_cast(tc.fInsanityCheckForEachParticle)); + + fBasePro->GetXaxis()->SetBinLabel(eWhichProcess, Form("WhichProcess = %s", tc.fWhichProcess.Data())); + + fBasePro->GetXaxis()->SetBinLabel(eRandomSeed, "fRandomSeed"); + fBasePro->Fill(eRandomSeed, static_cast(tc.fRandomSeed)); + + fBasePro->GetXaxis()->SetBinLabel(eUseFisherYates, "fUseFisherYates"); + fBasePro->Fill(eUseFisherYates, static_cast(tc.fUseFisherYates)); + + fBasePro->GetXaxis()->SetBinLabel(eFixedNumberOfRandomlySelectedTracks, "fFixedNumberOfRandomlySelectedTracks"); + fBasePro->Fill(eFixedNumberOfRandomlySelectedTracks, static_cast(tc.fFixedNumberOfRandomlySelectedTracks)); + + fBasePro->GetXaxis()->SetBinLabel(eUseStopwatch, "fUseStopwatch"); + fBasePro->Fill(eUseStopwatch, static_cast(tc.fUseStopwatch)); + + fBasePro->GetXaxis()->SetBinLabel(eFloatingPointPrecision, "fFloatingPointPrecision"); + fBasePro->Fill(eFloatingPointPrecision, tc.fFloatingPointPrecision); + + fBasePro->GetXaxis()->SetBinLabel(eSequentialBailout, "fSequentialBailout"); + fBasePro->Fill(eSequentialBailout, static_cast(tc.fSequentialBailout)); + + fBasePro->GetXaxis()->SetBinLabel(eUseSpecificCuts, "fUseSpecificCuts"); + fBasePro->Fill(eUseSpecificCuts, static_cast(tc.fUseSpecificCuts)); + + fBasePro->GetXaxis()->SetBinLabel(eWhichSpecificCuts, Form("WhichSpecificCuts = %s", tc.fWhichSpecificCuts.Data())); + + fBasePro->GetXaxis()->SetBinLabel(eSkipTheseRuns, Form("SkipTheseRuns = %s", tc.fSkipTheseRuns.Data())); + + fBasePro->GetXaxis()->SetBinLabel(eUseSetBinLabel, "fUseSetBinLabel"); + fBasePro->Fill(eUseSetBinLabel, static_cast(tc.fUseSetBinLabel)); + + fBasePro->GetXaxis()->SetBinLabel(eUseClone, "fUseClone"); + fBasePro->Fill(eUseClone, static_cast(tc.fUseClone)); + + fBasePro->GetXaxis()->SetBinLabel(eUseFormula, "fUseFormula"); + fBasePro->Fill(eUseFormula, static_cast(tc.fUseFormula)); + + fBasePro->GetXaxis()->SetBinLabel(eUseDatabasePDG, "fUseDatabasePDG"); + fBasePro->Fill(eUseDatabasePDG, static_cast(tc.fUseDatabasePDG)); + + } else { + + // d) Define bin labels indirectly by storing them in y-axis title + local executable PostprocessLabels.C. + // Algorithm is documented in the function preamble above. + + TString yAxisTitle = ""; + yAxisTitle += TString::Format("%d:fTaskIsConfiguredFromJson = %s; ", static_cast(eTaskIsConfiguredFromJson), tc.fTaskIsConfiguredFromJson.Data()); + + yAxisTitle += TString::Format("%d:fTaskName = %s; ", static_cast(eTaskName), tc.fTaskName.Data()); + + yAxisTitle += TString::Format("%d:fRunNumber = %s; ", static_cast(eRunNumber), "__RUN_NUMBER__"); + // I have to do it this way via placeholder, because run number is available only when i start to process data. + // Then, I replace placeholder with run number in PropagateRunNumber(...) + + yAxisTitle += TString::Format("%d:fDryRun; ", static_cast(eDryRun)); + fBasePro->Fill(eDryRun, static_cast(tc.fDryRun)); + + yAxisTitle += TString::Format("%d:fVerbose; ", static_cast(eVerbose)); + fBasePro->Fill(eVerbose, static_cast(tc.fVerbose)); + + yAxisTitle += TString::Format("%d:fVerboseUtility; ", static_cast(eVerboseUtility)); + fBasePro->Fill(eVerboseUtility, static_cast(tc.fVerboseUtility)); + + yAxisTitle += TString::Format("%d:fVerboseForEachParticle; ", static_cast(eVerboseForEachParticle)); + fBasePro->Fill(eVerboseForEachParticle, static_cast(tc.fVerboseForEachParticle)); + + yAxisTitle += TString::Format("%d:fVerboseEventCounter; ", static_cast(eVerboseEventCounter)); + fBasePro->Fill(eVerboseEventCounter, static_cast(tc.fVerboseEventCounter)); + + yAxisTitle += TString::Format("%d:fPlainPrintout; ", static_cast(ePlainPrintout)); + fBasePro->Fill(ePlainPrintout, static_cast(tc.fPlainPrintout)); + + yAxisTitle += TString::Format("%d:fDoAdditionalInsanityChecks; ", static_cast(eDoAdditionalInsanityChecks)); + fBasePro->Fill(eDoAdditionalInsanityChecks, static_cast(tc.fDoAdditionalInsanityChecks)); + + yAxisTitle += TString::Format("%d:fInsanityCheckForEachParticle; ", static_cast(eInsanityCheckForEachParticle)); + fBasePro->Fill(eInsanityCheckForEachParticle, static_cast(tc.fInsanityCheckForEachParticle)); + + yAxisTitle += TString::Format("%d:fWhichProcess = %s; ", static_cast(eWhichProcess), tc.fWhichProcess.Data()); + + yAxisTitle += TString::Format("%d:fRandomSeed; ", static_cast(eRandomSeed)); + fBasePro->Fill(eRandomSeed, static_cast(tc.fRandomSeed)); + + yAxisTitle += TString::Format("%d:fUseFisherYates; ", static_cast(eUseFisherYates)); + fBasePro->Fill(eUseFisherYates, static_cast(tc.fUseFisherYates)); + + yAxisTitle += TString::Format("%d:fFixedNumberOfRandomlySelectedTracks; ", static_cast(eFixedNumberOfRandomlySelectedTracks)); + fBasePro->Fill(eFixedNumberOfRandomlySelectedTracks, static_cast(tc.fFixedNumberOfRandomlySelectedTracks)); + + yAxisTitle += TString::Format("%d:fUseStopwatch; ", static_cast(eUseStopwatch)); + fBasePro->Fill(eUseStopwatch, static_cast(tc.fUseStopwatch)); + + yAxisTitle += TString::Format("%d:fFloatingPointPrecision; ", static_cast(eFloatingPointPrecision)); + fBasePro->Fill(eFloatingPointPrecision, static_cast(tc.fFloatingPointPrecision)); + + yAxisTitle += TString::Format("%d:fSequentialBailout; ", static_cast(eSequentialBailout)); + fBasePro->Fill(eSequentialBailout, static_cast(tc.fSequentialBailout)); + + yAxisTitle += TString::Format("%d:fUseSpecificCuts; ", static_cast(eUseSpecificCuts)); + fBasePro->Fill(eUseSpecificCuts, static_cast(tc.fUseSpecificCuts)); + + yAxisTitle += TString::Format("%d:fWhichSpecificCuts = %s; ", static_cast(eWhichSpecificCuts), tc.fWhichSpecificCuts.Data()); + + yAxisTitle += TString::Format("%d:fSkipTheseRuns = %s; ", static_cast(eSkipTheseRuns), tc.fSkipTheseRuns.Data()); + + yAxisTitle += TString::Format("%d:fUseSetBinLabel; ", static_cast(eUseSetBinLabel)); + fBasePro->Fill(eUseSetBinLabel, static_cast(tc.fUseSetBinLabel)); + + yAxisTitle += TString::Format("%d:fUseClone; ", static_cast(eUseClone)); + fBasePro->Fill(eUseClone, static_cast(tc.fUseClone)); + + yAxisTitle += TString::Format("%d:fUseFormula; ", static_cast(eUseFormula)); + fBasePro->Fill(eUseFormula, static_cast(tc.fUseFormula)); + + yAxisTitle += TString::Format("%d:fUseDatabasePDG; ", static_cast(eUseDatabasePDG)); + fBasePro->Fill(eUseDatabasePDG, static_cast(tc.fUseDatabasePDG)); + + // ... + + // *) Insanity check on the number of fields in this specially crafted y-axis title: + TObjArray* oa = yAxisTitle.Tokenize(";"); + if (!oa) { + LOGF(fatal, "\033[1;31m%s at line %d : oa is NULL\033[0m", __FUNCTION__, __LINE__); + } + if (oa->GetEntries() != static_cast(eConfiguration_N)) { + LOGF(fatal, "\033[1;31m%s at line %d : oa->GetEntries() = %d != eConfiguration_N = %d\033[0m", __FUNCTION__, __LINE__, oa->GetEntries(), static_cast(eConfiguration_N)); + } + delete oa; + + // *) Okay, set the title: + fBasePro->GetYaxis()->SetTitle(yAxisTitle.Data()); + + } // else + + // e) Add configured base TProfile to the list: + fBaseList->Add(fBasePro); + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // void bookBaseList() + + //============================================================ + + void defaultConfiguration() + { + // Default task configuration. + // a) Default values are hardcoded as Configurables in the file MuPa-Configurables.h + + // b) If corresponding fields are available in an external json file at run time, the default values hardcoded here are + // overwritten with values set in json file. + // Remember #1: To take into account configuration from external json file, + // use additional flag for executable, e.g.: --configuration + // json://my-config.json + // And yes, --configuration json://my-config.json has to be + // supplied to all executables in the pipe chain (workflow), + // not only to mine! + // Remember #2: If names of Configurables in the json file are not + // identical to the internal definitions in MuPa-Configurables.h, the + // settings in json file are silently ignored. + + // c) Scientific notation is NOT supported in json file. E.g. if you have + // "cSelectedTracks_max": "1e3", + // that setting and ALL other ones in json are silently ignored. + + // d) There are also implicit variables like "doprocessSomeProcessName" within a PROCESS_SWITCH clause. For them, I do not need an entry in Configurables + + // e) Use whenever you can ConfigurableGroup, keep grouping in sync with all struct's in MuPa-DataMembers.h. + // This is needed, to avoid this compilation error: + // Framework/StructToTuple.h:286:6: error: only 99 names provided for structured binding + // *) As far as I can tell, that means that sum of individual data members + struct fields + individual configurables > 99 + // *) Therefore, wrap up all data members in some struct fields + use in instead of individual configurables ConfigurableGroup whenever possible. + // *) Within a given struct field, number of data members do not add to that number. Also, number of enum fields do not add. + + tc.fTaskIsConfiguredFromJson = TString(cf_tc.cfTaskIsConfiguredFromJson); + tc.fTaskName = TString(cf_tc.cfTaskName); + tc.fDryRun = cf_tc.cfDryRun; + tc.fVerbose = cf_tc.cfVerbose; + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); // yes, here + } + tc.fVerboseUtility = cf_tc.cfVerboseUtility; + tc.fVerboseForEachParticle = cf_tc.cfVerboseForEachParticle; + tc.fVerboseEventCounter = cf_tc.cfVerboseEventCounter; + tc.fVerboseEventCut = cf_tc.cfVerboseEventCut; + tc.fPlainPrintout = cf_tc.cfPlainPrintout; + tc.fDoAdditionalInsanityChecks = cf_tc.cfDoAdditionalInsanityChecks; + // Set automatically what to process, from an implicit variable "doprocessSomeProcessName" within a PROCESS_SWITCH clause: + tc.fProcess[eProcessRec] = doprocessRec; + tc.fProcess[eProcessRecSim] = doprocessRecSim; + tc.fProcess[eProcessSim] = doprocessSim; + tc.fProcess[eProcessRec_Run2] = doprocessRec_Run2; + tc.fProcess[eProcessRecSim_Run2] = doprocessRecSim_Run2; + tc.fProcess[eProcessSim_Run2] = doprocessSim_Run2; + tc.fProcess[eProcessRec_Run1] = doprocessRec_Run1; + tc.fProcess[eProcessRecSim_Run1] = doprocessRecSim_Run1; + tc.fProcess[eProcessSim_Run1] = doprocessSim_Run1; + tc.fProcess[eProcessTest] = doprocessTest; + tc.fProcess[eProcessQA] = doprocessQA; + tc.fProcess[eProcessHepMChi] = doprocessHepMChi; + + // Temporarary bailout protection against cases which are not implemented/validated yet: + if (tc.fProcess[eProcessSim]) { + LOGF(fatal, "\033[1;31m%s at line %d - processSim(...) is not implemented/validated yet \033[0m", __FUNCTION__, __LINE__); + // TBI 20240512 Most likely, for this case i will have to establish a separate workflow. But since I can with the current + // workflow run both over Rec and RecSim, this case is not of a high priority + // TBI 20240512 See also if I need to extand subscription, both in the definition of CollisionSim and TrackSim + } + + if (tc.fProcess[eProcessSim_Run2]) { + LOGF(fatal, "\033[1;31m%s at line %d - processSim_Run2(...) is not implemented/validated yet \033[0m", __FUNCTION__, __LINE__); + // TBI 20240517 see above comments for eProcessSim , most likely they also apply for this case + } + + if (tc.fProcess[eProcessRecSim_Run1]) { + LOGF(fatal, "\033[1;31m%s at line %d - processRecSim_Run1(...) is not implemented/validated yet \033[0m", __FUNCTION__, __LINE__); + } + + if (tc.fProcess[eProcessSim_Run1]) { + LOGF(fatal, "\033[1;31m%s at line %d - processSim_Run1(...) is not implemented/validated yet \033[0m", __FUNCTION__, __LINE__); + } + + // Set automatically generic flags, from above individual flags: + tc.fProcess[eGenericRec] = tc.fProcess[eProcessRec] || tc.fProcess[eProcessRec_Run2] || tc.fProcess[eProcessRec_Run1] || tc.fProcess[eProcessTest] || tc.fProcess[eProcessQA]; + tc.fProcess[eGenericRecSim] = tc.fProcess[eProcessRecSim] || tc.fProcess[eProcessRecSim_Run2] || tc.fProcess[eProcessRecSim_Run1]; + tc.fProcess[eGenericSim] = tc.fProcess[eProcessSim] || tc.fProcess[eProcessSim_Run2] || tc.fProcess[eProcessSim_Run1]; + + // Set automatically tc.fWhichProcess from above individual flags: + if (tc.fProcess[eProcessRec]) { + tc.fWhichProcess = "ProcessRec"; + } else if (tc.fProcess[eProcessRecSim]) { + tc.fWhichProcess = "ProcessRecSim"; + } else if (tc.fProcess[eProcessSim]) { + tc.fWhichProcess = "ProcessSim"; + } else if (tc.fProcess[eProcessRec_Run2]) { + tc.fWhichProcess = "ProcessRec_Run2"; + } else if (tc.fProcess[eProcessRecSim_Run2]) { + tc.fWhichProcess = "ProcessRecSim_Run2"; + } else if (tc.fProcess[eProcessSim_Run2]) { + tc.fWhichProcess = "ProcessSim_Run2"; + } else if (tc.fProcess[eProcessRec_Run1]) { + tc.fWhichProcess = "ProcessRec_Run1"; + } else if (tc.fProcess[eProcessRecSim_Run1]) { + tc.fWhichProcess = "ProcessRecSim_Run1"; + } else if (tc.fProcess[eProcessSim_Run1]) { + tc.fWhichProcess = "ProcessSim_Run1"; + } else if (tc.fProcess[eProcessTest]) { + tc.fWhichProcess = "ProcessTest"; + } else if (tc.fProcess[eProcessQA]) { + tc.fWhichProcess = "ProcessQA"; + } else if (tc.fProcess[eProcessHepMChi]) { + tc.fWhichProcess = "ProcessHepMChi"; + } + + tc.fRandomSeed = cf_tc.cfRandomSeed; + tc.fUseFisherYates = cf_tc.cfUseFisherYates; + tc.fFixedNumberOfRandomlySelectedTracks = cf_tc.cfFixedNumberOfRandomlySelectedTracks; + tc.fUseStopwatch = cf_tc.cfUseStopwatch; + tc.fFloatingPointPrecision = cf_tc.cfFloatingPointPrecision; + tc.fSequentialBailout = cf_tc.cfSequentialBailout; + tc.fUseSpecificCuts = cf_tc.cfUseSpecificCuts; + tc.fWhichSpecificCuts = cf_tc.cfWhichSpecificCuts; + tc.fSkipTheseRuns = cf_tc.cfSkipTheseRuns; + tc.fUseSetBinLabel = cf_tc.cfUseSetBinLabel; + tc.fUseClone = cf_tc.cfUseClone; + tc.fUseFormula = cf_tc.cfUseFormula; + tc.fUseDatabasePDG = cf_tc.cfUseDatabasePDG; + + // *) Event histograms (for QA see below): + eh.fEventHistogramsName[eNumberOfEvents] = "NumberOfEvents"; + eh.fEventHistogramsName[eTotalMultiplicity] = "TotalMultiplicity"; + eh.fEventHistogramsName[eMultiplicity] = "Multiplicity"; + eh.fEventHistogramsName[eReferenceMultiplicity] = "ReferenceMultiplicity"; + eh.fEventHistogramsName[eCentrality] = "Centrality"; + eh.fEventHistogramsName[eVertexX] = "VertexX"; + eh.fEventHistogramsName[eVertexY] = "VertexY"; + eh.fEventHistogramsName[eVertexZ] = "VertexZ"; + eh.fEventHistogramsName[eNContributors] = "NContributors"; + eh.fEventHistogramsName[eImpactParameter] = "ImpactParameter"; + eh.fEventHistogramsName[eEventPlaneAngle] = "EventPlaneAngle"; + eh.fEventHistogramsName[eOccupancy] = "Occupancy"; + eh.fEventHistogramsName[eInteractionRate] = "InteractionRate"; + eh.fEventHistogramsName[eCurrentRunDuration] = "CurrentRunDuration"; + eh.fEventHistogramsName[eMultMCNParticlesEta08] = "MultMCNParticlesEta08"; + + for (int t = 0; t < eEventHistograms_N; t++) { + if (eh.fEventHistogramsName[t].EqualTo("")) { + LOGF(fatal, "\033[1;31m%s at line %d : name of fEventHistogramsName[%d] is not set \033[0m", __FUNCTION__, __LINE__, static_cast(t)); + } + } + + // *) Event cuts: + ec.fUseEventCutCounterAbsolute = cf_ec.cfUseEventCutCounterAbsolute; + ec.fUseEventCutCounterSequential = cf_ec.cfUseEventCutCounterSequential; + ec.fPrintCutCounterContent = cf_ec.cfPrintCutCounterContent; + + // Set names of all event cuts: + ec.fEventCutName[eNumberOfEvents] = "NumberOfEvents"; + ec.fEventCutName[eTotalMultiplicity] = "TotalMultiplicity"; + ec.fEventCutName[eMultiplicity] = "Multiplicity"; + ec.fEventCutName[eReferenceMultiplicity] = "ReferenceMultiplicity"; + ec.fEventCutName[eCentrality] = "Centrality"; + ec.fEventCutName[eVertexX] = "VertexX"; + ec.fEventCutName[eVertexY] = "VertexY"; + ec.fEventCutName[eVertexZ] = "VertexZ"; + ec.fEventCutName[eNContributors] = "NContributors"; + ec.fEventCutName[eImpactParameter] = "ImpactParameter"; + ec.fEventCutName[eEventPlaneAngle] = "EventPlaneAngle"; + ec.fEventCutName[eOccupancy] = "Occupancy"; + ec.fEventCutName[eInteractionRate] = "InteractionRate"; + ec.fEventCutName[eCurrentRunDuration] = "CurrentRunDuration"; + ec.fEventCutName[eMultMCNParticlesEta08] = "MultMCNParticlesEta08"; + ec.fEventCutName[eTrigger] = "Trigger"; + ec.fEventCutName[eSel7] = "Sel7"; + ec.fEventCutName[eSel8] = "Sel8"; + ec.fEventCutName[eCentralityEstimator] = "CentralityEstimator"; + ec.fEventCutName[eMultiplicityEstimator] = "MultiplicityEstimator"; + ec.fEventCutName[eReferenceMultiplicityEstimator] = "ReferenceMultiplicityEstimator"; + ec.fEventCutName[eSelectedEvents] = "SelectedEvents"; + ec.fEventCutName[eNoSameBunchPileup] = "NoSameBunchPileup"; + ec.fEventCutName[eIsGoodZvtxFT0vsPV] = "IsGoodZvtxFT0vsPV"; + ec.fEventCutName[eIsVertexITSTPC] = "IsVertexITSTPC"; + ec.fEventCutName[eIsVertexTOFmatched] = "IsVertexTOFmatched"; + ec.fEventCutName[eIsVertexTRDmatched] = "IsVertexTRDmatched"; + ec.fEventCutName[eNoCollInTimeRangeStrict] = "NoCollInTimeRangeStrict"; + ec.fEventCutName[eNoCollInTimeRangeStandard] = "NoCollInTimeRangeStandard"; + ec.fEventCutName[eNoCollInRofStrict] = "NoCollInRofStrict"; + ec.fEventCutName[eNoCollInRofStandard] = "NoCollInRofStandard"; + ec.fEventCutName[eNoHighMultCollInPrevRof] = "NoHighMultCollInPrevRof"; + ec.fEventCutName[eIsGoodITSLayer3] = "IsGoodITSLayer3"; + ec.fEventCutName[eIsGoodITSLayer0123] = "IsGoodITSLayer0123"; + ec.fEventCutName[eIsGoodITSLayersAll] = "IsGoodITSLayersAll"; + ec.fEventCutName[eOccupancyEstimator] = "OccupancyEstimator"; + ec.fEventCutName[eMinVertexDistanceFromIP] = "MinVertexDistanceFromIP"; + ec.fEventCutName[eNoPileupTPC] = "NoPileupTPC"; + ec.fEventCutName[eNoPileupFromSPD] = "NoPileupFromSPD"; + ec.fEventCutName[eNoSPDOnVsOfPileup] = "NoSPDOnVsOfPileup"; + ec.fEventCutName[eRefMultVsNContrUp] = "RefMultVsNContrUp"; + ec.fEventCutName[eRefMultVsNContrLow] = "RefMultVsNContrLow"; + ec.fEventCutName[eCentralityCorrelationsCut] = "CentralityCorrelationsCut"; + ec.fEventCutName[eFT0Bad] = "FT0Bad"; + ec.fEventCutName[eITSBad] = "ITSBad"; + ec.fEventCutName[eITSLimAccMCRepr] = "ITSLimAccMCRepr"; + ec.fEventCutName[eTPCBadTracking] = "TPCBadTracking"; + ec.fEventCutName[eTPCLimAccMCRepr] = "TPCLimAccMCRepr"; + ec.fEventCutName[eTPCBadPID] = "TPCBadPID"; + ec.fEventCutName[eCentralityWeights] = "CentralityWeights"; + for (int t = 0; t < eEventCuts_N; t++) { + if (ec.fEventCutName[t].EqualTo("")) { + LOGF(fatal, "\033[1;31m%s at line %d : event cut name is not set for ec.fEventCutName[%d]. The last cut name which was set is \"%s\" \033[0m", __FUNCTION__, __LINE__, t, ec.fEventCutName[t - 1].Data()); + } + } + + // *) Particle histograms 1D (for QA see below): + ph.fParticleHistogramsName[ePhi] = "Phi"; + ph.fParticleHistogramsName[ePt] = "Pt"; + ph.fParticleHistogramsName[eEta] = "Eta"; + ph.fParticleHistogramsName[eCharge] = "Charge"; + ph.fParticleHistogramsName[etpcNClsFindable] = "tpcNClsFindable"; + ph.fParticleHistogramsName[etpcNClsShared] = "tpcNClsShared"; + ph.fParticleHistogramsName[eitsChi2NCl] = "itsChi2NCl"; + ph.fParticleHistogramsName[etpcNClsFound] = "tpcNClsFound"; + ph.fParticleHistogramsName[etpcNClsCrossedRows] = "tpcNClsCrossedRows"; + ph.fParticleHistogramsName[eitsNCls] = "itsNCls"; + ph.fParticleHistogramsName[eitsNClsInnerBarrel] = "itsNClsInnerBarrel"; + ph.fParticleHistogramsName[etpcCrossedRowsOverFindableCls] = "tpcCrossedRowsOverFindableCls"; + ph.fParticleHistogramsName[etpcFoundOverFindableCls] = "tpcFoundOverFindableCls"; + ph.fParticleHistogramsName[etpcFractionSharedCls] = "tpcFractionSharedCls"; + ph.fParticleHistogramsName[etpcChi2NCl] = "tpcChi2NCl"; + ph.fParticleHistogramsName[edcaXY] = "dcaXY"; + ph.fParticleHistogramsName[edcaZ] = "dcaZ"; + ph.fParticleHistogramsName[ePDG] = "PDG"; + for (int t = 0; t < eParticleHistograms_N; t++) { + if (ph.fParticleHistogramsName[t].EqualTo("")) { + LOGF(fatal, "\033[1;31m%s at line %d : name of fParticleHistogramsName[%d] is not set \033[0m", __FUNCTION__, __LINE__, t); + } + } + + // *) Particle histograms 2D (for QA see below): + ph.fParticleHistogramsName2D[ePhiPt] = Form("%s_vs_%s", ph.fParticleHistogramsName[ePhi].Data(), ph.fParticleHistogramsName[ePt].Data()), + ph.fParticleHistogramsName2D[ePhiEta] = Form("%s_vs_%s", ph.fParticleHistogramsName[ePhi].Data(), ph.fParticleHistogramsName[eEta].Data()); + for (int t = 0; t < eParticleHistograms2D_N; t++) { + if (ph.fParticleHistogramsName2D[t].EqualTo("")) { + LOGF(fatal, "\033[1;31m%s at line %d : name of fParticleHistogramsName2D[%d] is not set \033[0m", __FUNCTION__, __LINE__, t); + } + } + + // *) Particle cuts: + pc.fUseParticleCutCounterAbsolute = cf_pc.cfUseParticleCutCounterAbsolute; + pc.fUseParticleCutCounterSequential = cf_pc.cfUseParticleCutCounterSequential; + + // Set names of all particle cuts: + pc.fParticleCutName[ePhi] = "Phi"; + pc.fParticleCutName[ePt] = "Pt"; + pc.fParticleCutName[eEta] = "Eta"; + pc.fParticleCutName[eCharge] = "Charge"; + pc.fParticleCutName[etpcNClsFindable] = "tpcNClsFindable"; + pc.fParticleCutName[etpcNClsShared] = "tpcNClsShared"; + pc.fParticleCutName[eitsChi2NCl] = "itsChi2NCl"; + pc.fParticleCutName[etpcNClsFound] = "tpcNClsFound"; + pc.fParticleCutName[etpcNClsCrossedRows] = "tpcNClsCrossedRows"; + pc.fParticleCutName[eitsNCls] = "itsNCls"; + pc.fParticleCutName[eitsNClsInnerBarrel] = "itsNClsInnerBarrel"; + pc.fParticleCutName[etpcCrossedRowsOverFindableCls] = "tpcCrossedRowsOverFindableCls"; + pc.fParticleCutName[etpcFoundOverFindableCls] = "tpcFoundOverFindableCls"; + pc.fParticleCutName[etpcFractionSharedCls] = "tpcFractionSharedCls"; + pc.fParticleCutName[etpcChi2NCl] = "tpcChi2NCl"; + pc.fParticleCutName[edcaXY] = "dcaXY"; + pc.fParticleCutName[edcaZ] = "dcaZ"; + pc.fParticleCutName[ePDG] = "PDG"; + pc.fParticleCutName[etrackCutFlag] = "trackCutFlag"; + pc.fParticleCutName[etrackCutFlagFb1] = "trackCutFlagFb1"; + pc.fParticleCutName[etrackCutFlagFb2] = "trackCutFlagFb2"; + pc.fParticleCutName[eisQualityTrack] = "isQualityTrack"; + pc.fParticleCutName[eisPrimaryTrack] = "isPrimaryTrack"; + pc.fParticleCutName[eisInAcceptanceTrack] = "isInAcceptanceTrack"; + pc.fParticleCutName[eisGlobalTrack] = "isGlobalTrack"; + pc.fParticleCutName[eisPVContributor] = "isPVContributor"; + pc.fParticleCutName[ePtDependentDCAxyParameterization] = "PtDependentDCAxyParameterization"; + for (int t = 0; t < eParticleCuts_N; t++) { + if (pc.fParticleCutName[t].EqualTo("")) { + LOGF(fatal, "\033[1;31m%s at line %d : particle cut name is not set for pc.fParticleCutName[%d] \033[0m", __FUNCTION__, __LINE__, t); + } + } + + // *) Q-vectors: + qv.fCalculateQvectors = cf_qv.cfCalculateQvectors; + + // *) Multiparticle correlations: + mupa.fCalculateCorrelations = cf_mupa.cfCalculateCorrelations; + + // *) Use configurable array cfCalculateCorrelationsAsFunctionOf, to specify vs which observable correlations will be calculated (flags 1 or 0). + // Supported format: "0-someName" and "1-someName", where "-" is a field separator. + // Ordering of the flags in that array is interpreted through ordering of enums in enum eAsFunctionOf. + auto lCalculateCorrelationsAsFunctionOf = cf_mupa.cfCalculateCorrelationsAsFunctionOf.value; // this is now the local version of that string array from configurable. + if (lCalculateCorrelationsAsFunctionOf.size() != eAsFunctionOf_N) { + LOGF(info, "\033[1;31m lCalculateCorrelationsAsFunctionOf.size() = %d\033[0m", lCalculateCorrelationsAsFunctionOf.size()); + LOGF(info, "\033[1;31m eAsFunctionOf_N) = %d\033[0m", static_cast(eAsFunctionOf_N)); + LOGF(fatal, "\033[1;31m%s at line %d : Mismatch in the number of flags in configurable cfCalculateCorrelationsAsFunctionOf, and number of entries in enum eAsFunctionOf_N \n \033[0m", __FUNCTION__, __LINE__); + } + + // I append "&& mupa.fCalculateCorrelations" below, to switch off calculation of all correlations with one common flag: + mupa.fCalculateCorrelationsAsFunctionOf[AFO_INTEGRATED] = Alright(lCalculateCorrelationsAsFunctionOf[AFO_INTEGRATED]) && mupa.fCalculateCorrelations; + mupa.fCalculateCorrelationsAsFunctionOf[AFO_MULTIPLICITY] = Alright(lCalculateCorrelationsAsFunctionOf[AFO_MULTIPLICITY]) && mupa.fCalculateCorrelations; + mupa.fCalculateCorrelationsAsFunctionOf[AFO_CENTRALITY] = Alright(lCalculateCorrelationsAsFunctionOf[AFO_CENTRALITY]) && mupa.fCalculateCorrelations; + mupa.fCalculateCorrelationsAsFunctionOf[AFO_PT] = Alright(lCalculateCorrelationsAsFunctionOf[AFO_PT]) && mupa.fCalculateCorrelations; + mupa.fCalculateCorrelationsAsFunctionOf[AFO_ETA] = Alright(lCalculateCorrelationsAsFunctionOf[AFO_ETA]) && mupa.fCalculateCorrelations; + mupa.fCalculateCorrelationsAsFunctionOf[AFO_OCCUPANCY] = Alright(lCalculateCorrelationsAsFunctionOf[AFO_OCCUPANCY]) && mupa.fCalculateCorrelations; + mupa.fCalculateCorrelationsAsFunctionOf[AFO_INTERACTIONRATE] = Alright(lCalculateCorrelationsAsFunctionOf[AFO_INTERACTIONRATE]) && mupa.fCalculateCorrelations; + mupa.fCalculateCorrelationsAsFunctionOf[AFO_CURRENTRUNDURATION] = Alright(lCalculateCorrelationsAsFunctionOf[AFO_CURRENTRUNDURATION]) && mupa.fCalculateCorrelations; + mupa.fCalculateCorrelationsAsFunctionOf[AFO_VZ] = Alright(lCalculateCorrelationsAsFunctionOf[AFO_VZ]) && mupa.fCalculateCorrelations; + mupa.fCalculateCorrelationsAsFunctionOf[AFO_CHARGE] = Alright(lCalculateCorrelationsAsFunctionOf[AFO_CHARGE]) && mupa.fCalculateCorrelations; + // ... + + // *) Test0: + // 1D: + t0.fCalculateTest0 = cf_t0.cfCalculateTest0; + + // *) Use configurable array cfCalculateTest0AsFunctionOf, to specify vs which observable Test0 will be calculated (flags 1 or 0). + // Supported format: "0-someName" and "1-someName", where "-" is a field separator. + // Ordering of the flags in that array is interpreted through ordering of enums in enum eAsFunctionOf. + auto lCalculateTest0AsFunctionOf = cf_t0.cfCalculateTest0AsFunctionOf.value; // this is now the local version of that string array from configurable. + if (lCalculateTest0AsFunctionOf.size() != eAsFunctionOf_N) { + LOGF(info, "\033[1;31m lCalculateTest0AsFunctionOf.size() = %d\033[0m", lCalculateTest0AsFunctionOf.size()); + LOGF(info, "\033[1;31m eAsFunctionOf_N) = %d\033[0m", static_cast(eAsFunctionOf_N)); + LOGF(fatal, "\033[1;31m%s at line %d : Mismatch in the number of flags in configurable cfCalculateTest0AsFunctionOf, and number of entries in enum eAsFunctionOf_N \n \033[0m", __FUNCTION__, __LINE__); + } + + // I append "&& t0.fCalculateTest0" below, to switch off calculation of all Test0 with one common flag: + t0.fCalculateTest0AsFunctionOf[AFO_INTEGRATED] = Alright(lCalculateTest0AsFunctionOf[AFO_INTEGRATED]) && t0.fCalculateTest0; + t0.fCalculateTest0AsFunctionOf[AFO_MULTIPLICITY] = Alright(lCalculateTest0AsFunctionOf[AFO_MULTIPLICITY]) && t0.fCalculateTest0; + t0.fCalculateTest0AsFunctionOf[AFO_CENTRALITY] = Alright(lCalculateTest0AsFunctionOf[AFO_CENTRALITY]) && t0.fCalculateTest0; + t0.fCalculateTest0AsFunctionOf[AFO_PT] = Alright(lCalculateTest0AsFunctionOf[AFO_PT]) && t0.fCalculateTest0; + t0.fCalculateTest0AsFunctionOf[AFO_ETA] = Alright(lCalculateTest0AsFunctionOf[AFO_ETA]) && t0.fCalculateTest0; + t0.fCalculateTest0AsFunctionOf[AFO_OCCUPANCY] = Alright(lCalculateTest0AsFunctionOf[AFO_OCCUPANCY]) && t0.fCalculateTest0; + t0.fCalculateTest0AsFunctionOf[AFO_INTERACTIONRATE] = Alright(lCalculateTest0AsFunctionOf[AFO_INTERACTIONRATE]) && t0.fCalculateTest0; + t0.fCalculateTest0AsFunctionOf[AFO_CURRENTRUNDURATION] = Alright(lCalculateTest0AsFunctionOf[AFO_CURRENTRUNDURATION]) && t0.fCalculateTest0; + t0.fCalculateTest0AsFunctionOf[AFO_VZ] = Alright(lCalculateTest0AsFunctionOf[AFO_VZ]) && t0.fCalculateTest0; + t0.fCalculateTest0AsFunctionOf[AFO_CHARGE] = Alright(lCalculateTest0AsFunctionOf[AFO_CHARGE]) && t0.fCalculateTest0; + // ... + + // 2D: + t0.fCalculate2DTest0 = cf_t0.cfCalculate2DTest0; + + // *) Use configurable array cfCalculate2DTest0AsFunctionOf, to specify vs which two observables Test0 will be calculated (flags 1 or 0). + // Supported format: "0-someName1_someName_2" and "1-someName1_someName_2", where both "-" and "_" are IFS, but with different meaning. + // Ordering of the flags in that array is interpreted through ordering of enums in enum eAsFunctionOf2D_N. + auto lCalculate2DTest0AsFunctionOf = cf_t0.cfCalculate2DTest0AsFunctionOf.value; // this is now the local version of that string array from configurable. + if (lCalculate2DTest0AsFunctionOf.size() != eAsFunctionOf2D_N) { + LOGF(info, "\033[1;31m lCalculate2DTest0AsFunctionOf.size() = %d\033[0m", lCalculate2DTest0AsFunctionOf.size()); + LOGF(info, "\033[1;31m eAsFunctionOf2D_N) = %d\033[0m", static_cast(eAsFunctionOf2D_N)); + LOGF(fatal, "\033[1;31m%s at line %d : Mismatch in the number of flags in configurable cfCalculate2DTest0AsFunctionOf, and number of entries in enum eAsFunctionOf2D_N \n \033[0m", __FUNCTION__, __LINE__); + } + + // I append "&& t0.fCalculate2DTest0" below, to switch off calculation of all Test0 with one common flag: + t0.fCalculate2DTest0AsFunctionOf[AFO_CENTRALITY_PT] = Alright(lCalculate2DTest0AsFunctionOf[AFO_CENTRALITY_PT]) && t0.fCalculate2DTest0; + t0.fCalculate2DTest0AsFunctionOf[AFO_CENTRALITY_ETA] = Alright(lCalculate2DTest0AsFunctionOf[AFO_CENTRALITY_ETA]) && t0.fCalculate2DTest0; + t0.fCalculate2DTest0AsFunctionOf[AFO_CENTRALITY_CHARGE] = Alright(lCalculate2DTest0AsFunctionOf[AFO_CENTRALITY_CHARGE]) && t0.fCalculate2DTest0; + t0.fCalculate2DTest0AsFunctionOf[AFO_CENTRALITY_VZ] = Alright(lCalculate2DTest0AsFunctionOf[AFO_CENTRALITY_VZ]) && t0.fCalculate2DTest0; + t0.fCalculate2DTest0AsFunctionOf[AFO_PT_ETA] = Alright(lCalculate2DTest0AsFunctionOf[AFO_PT_ETA]) && t0.fCalculate2DTest0; + t0.fCalculate2DTest0AsFunctionOf[AFO_PT_CHARGE] = Alright(lCalculate2DTest0AsFunctionOf[AFO_PT_CHARGE]) && t0.fCalculate2DTest0; + t0.fCalculate2DTest0AsFunctionOf[AFO_ETA_CHARGE] = Alright(lCalculate2DTest0AsFunctionOf[AFO_ETA_CHARGE]) && t0.fCalculate2DTest0; + + // ... + + // 3D: + t0.fCalculate3DTest0 = cf_t0.cfCalculate3DTest0; + + // *) Use configurable array cfCalculate3DTest0AsFunctionOf, to specify vs which two observables Test0 will be calculated (flags 1 or 0). + // Supported format: "0-someName1_someName_2" and "1-someName1_someName_2", where both "-" and "_" are IFS, but with different meaning. + // Ordering of the flags in that array is interpreted through ordering of enums in enum eAsFunctionOf3D_N. + auto lCalculate3DTest0AsFunctionOf = cf_t0.cfCalculate3DTest0AsFunctionOf.value; // this is now the local version of that string array from configurable. + if (lCalculate3DTest0AsFunctionOf.size() != eAsFunctionOf3D_N) { + LOGF(info, "\033[1;31m lCalculate3DTest0AsFunctionOf.size() = %d\033[0m", lCalculate3DTest0AsFunctionOf.size()); + LOGF(info, "\033[1;31m eAsFunctionOf3D_N) = %d\033[0m", static_cast(eAsFunctionOf3D_N)); + LOGF(fatal, "\033[1;31m%s at line %d : Mismatch in the number of flags in configurable cfCalculate3DTest0AsFunctionOf, and number of entries in enum eAsFunctionOf3D_N \n \033[0m", __FUNCTION__, __LINE__); + } + + // I append "&& t0.fCalculate3DTest0" below, to switch off calculation of all Test0 with one common flag: + t0.fCalculate3DTest0AsFunctionOf[AFO_CENTRALITY_PT_ETA] = Alright(lCalculate3DTest0AsFunctionOf[AFO_CENTRALITY_PT_ETA]) && t0.fCalculate3DTest0; + t0.fCalculate3DTest0AsFunctionOf[AFO_CENTRALITY_PT_CHARGE] = Alright(lCalculate3DTest0AsFunctionOf[AFO_CENTRALITY_PT_CHARGE]) && t0.fCalculate3DTest0; + t0.fCalculate3DTest0AsFunctionOf[AFO_CENTRALITY_PT_VZ] = Alright(lCalculate3DTest0AsFunctionOf[AFO_CENTRALITY_PT_VZ]) && t0.fCalculate3DTest0; + t0.fCalculate3DTest0AsFunctionOf[AFO_CENTRALITY_ETA_VZ] = Alright(lCalculate3DTest0AsFunctionOf[AFO_CENTRALITY_ETA_VZ]) && t0.fCalculate3DTest0; + t0.fCalculate3DTest0AsFunctionOf[AFO_CENTRALITY_ETA_CHARGE] = Alright(lCalculate3DTest0AsFunctionOf[AFO_CENTRALITY_ETA_CHARGE]) && t0.fCalculate3DTest0; + t0.fCalculate3DTest0AsFunctionOf[AFO_CENTRALITY_VZ_CHARGE] = Alright(lCalculate3DTest0AsFunctionOf[AFO_CENTRALITY_VZ_CHARGE]) && t0.fCalculate3DTest0; + t0.fCalculate3DTest0AsFunctionOf[AFO_PT_ETA_CHARGE] = Alright(lCalculate3DTest0AsFunctionOf[AFO_PT_ETA_CHARGE]) && t0.fCalculate3DTest0; + + // ... + + if (t0.fCalculateTest0 || t0.fCalculate2DTest0 || t0.fCalculate3DTest0) { + t0.fFileWithLabels = TString(cf_t0.cfFileWithLabels); + t0.fUseDefaultLabels = cf_t0.cfUseDefaultLabels; + t0.fWhichDefaultLabels = TString(cf_t0.cfWhichDefaultLabels); + } + + // *) Particle weights: + pw.fUseWeights[wPHI] = cf_pw.cfUsePhiWeights; + pw.fUseWeights[wPT] = cf_pw.cfUsePtWeights; + pw.fUseWeights[wETA] = cf_pw.cfUseEtaWeights; + pw.fUseDiffWeights[wPHIPT] = cf_pw.cfUseDiffPhiPtWeights; // TBI 20250222 obsolete + pw.fUseDiffWeights[wPHIETA] = cf_pw.cfUseDiffPhiEtaWeights; // TBI 20250222 obsolete + + // **) Differential multidimensional phi weights: + auto lWhichDiffPhiWeights = cf_pw.cfWhichDiffPhiWeights.value; + if (lWhichDiffPhiWeights.size() != eDiffPhiWeights_N) { + LOGF(info, "\033[1;31m lWhichDiffPhiWeights.size() = %d\033[0m", lWhichDiffPhiWeights.size()); + LOGF(info, "\033[1;31m eDiffPhiWeights_N = %d\033[0m", static_cast(eDiffPhiWeights_N)); + LOGF(fatal, "\033[1;31m%s at line %d : Mismatch in the number of flags in configurable cfWhichDiffPhiWeights, and number of entries in enum eDiffPhiWeights_N \n \033[0m", __FUNCTION__, __LINE__); + } + for (int dpw = 0; dpw < eDiffPhiWeights_N; dpw++) { // "differential phi weight" + if (TString(lWhichDiffPhiWeights[dpw]).Contains("wPhi")) { + pw.fUseDiffPhiWeights[wPhiPhiAxis] = Alright(lWhichDiffPhiWeights[dpw]); // if I pass "1-Phi" => true, "0-Phi" => false + } else if (TString(lWhichDiffPhiWeights[dpw]).Contains("wPt")) { + pw.fUseDiffPhiWeights[wPhiPtAxis] = Alright(lWhichDiffPhiWeights[dpw]) && pw.fUseDiffPhiWeights[wPhiPhiAxis]; // I chain here with wPhiPhiAxis , so that I can switch off all differential phi weights, if phi itself is not set to true + } else if (TString(lWhichDiffPhiWeights[dpw]).Contains("wEta")) { + pw.fUseDiffPhiWeights[wPhiEtaAxis] = Alright(lWhichDiffPhiWeights[dpw]) && pw.fUseDiffPhiWeights[wPhiPhiAxis]; + } else if (TString(lWhichDiffPhiWeights[dpw]).Contains("wCharge")) { + pw.fUseDiffPhiWeights[wPhiChargeAxis] = Alright(lWhichDiffPhiWeights[dpw]) && pw.fUseDiffPhiWeights[wPhiPhiAxis]; + } else if (TString(lWhichDiffPhiWeights[dpw]).Contains("wCentrality")) { + pw.fUseDiffPhiWeights[wPhiCentralityAxis] = Alright(lWhichDiffPhiWeights[dpw]) && pw.fUseDiffPhiWeights[wPhiPhiAxis]; + } else if (TString(lWhichDiffPhiWeights[dpw]).Contains("wVertexZ") || TString(lWhichDiffPhiWeights[dpw]).Contains("wVertex_z")) { // TBI 20250402 I keep "wVertex_z" here just in case I still have somewhere dependency on it, remove eventually + pw.fUseDiffPhiWeights[wPhiVertexZAxis] = Alright(lWhichDiffPhiWeights[dpw]) && pw.fUseDiffPhiWeights[wPhiPhiAxis]; + } else { + LOGF(fatal, "\033[1;31m%s at line %d : The setting %s in configurable cfWhichDiffPhiWeights is not supported yet. See enum eDiffPhiWeights . \n \033[0m", __FUNCTION__, __LINE__, TString(lWhichDiffPhiWeights[dpw]).Data()); + } + } + + // **) Differential multidimensional pt weights: + auto lWhichDiffPtWeights = cf_pw.cfWhichDiffPtWeights.value; + if (lWhichDiffPtWeights.size() != eDiffPtWeights_N) { + LOGF(info, "\033[1;31m lWhichDiffPtWeights.size() = %d\033[0m", lWhichDiffPtWeights.size()); + LOGF(info, "\033[1;31m eDiffPtWeights_N = %d\033[0m", static_cast(eDiffPtWeights_N)); + LOGF(fatal, "\033[1;31m%s at line %d : Mismatch in the number of flags in configurable cfWhichDiffPtWeights, and number of entries in enum eDiffPtWeights_N \n \033[0m", __FUNCTION__, __LINE__); + } + for (int dpw = 0; dpw < eDiffPtWeights_N; dpw++) { // "differential pt weight" + if (TString(lWhichDiffPtWeights[dpw]).Contains("wPt")) { + pw.fUseDiffPtWeights[wPtPtAxis] = Alright(lWhichDiffPtWeights[dpw]); // if I pass "1-Pt" => true, "0-Pt" => false + } else if (TString(lWhichDiffPtWeights[dpw]).Contains("wEta")) { + pw.fUseDiffPtWeights[wPtEtaAxis] = Alright(lWhichDiffPtWeights[dpw]) && pw.fUseDiffPtWeights[wPtPtAxis]; + } else if (TString(lWhichDiffPtWeights[dpw]).Contains("wCharge")) { + pw.fUseDiffPtWeights[wPtChargeAxis] = Alright(lWhichDiffPtWeights[dpw]) && pw.fUseDiffPtWeights[wPtPtAxis]; + } else if (TString(lWhichDiffPtWeights[dpw]).Contains("wCentrality")) { + pw.fUseDiffPtWeights[wPtCentralityAxis] = Alright(lWhichDiffPtWeights[dpw]) && pw.fUseDiffPtWeights[wPtPtAxis]; + } else { + LOGF(fatal, "\033[1;31m%s at line %d : The setting %s in configurable cfWhichDiffPtWeights is not supported yet. See enum eDiffPtWeights . \n \033[0m", __FUNCTION__, __LINE__, TString(lWhichDiffPtWeights[dpw]).Data()); + } + } + + // **) Differential multidimensional eta weights: + auto lWhichDiffEtaWeights = cf_pw.cfWhichDiffEtaWeights.value; + if (lWhichDiffEtaWeights.size() != eDiffEtaWeights_N) { + LOGF(info, "\033[1;31m lWhichDiffEtaWeights.size() = %d\033[0m", lWhichDiffEtaWeights.size()); + LOGF(info, "\033[1;31m eDiffEtaWeights_N = %d\033[0m", static_cast(eDiffEtaWeights_N)); + LOGF(fatal, "\033[1;31m%s at line %d : Mismatch in the number of flags in configurable cfWhichDiffEtaWeights, and number of entries in enum eDiffEtaWeights_N \n \033[0m", __FUNCTION__, __LINE__); + } + for (int dpw = 0; dpw < eDiffEtaWeights_N; dpw++) { // "differential eta weight" + if (TString(lWhichDiffEtaWeights[dpw]).Contains("wEta")) { + pw.fUseDiffEtaWeights[wEtaEtaAxis] = Alright(lWhichDiffEtaWeights[dpw]); // if I pass "1-Eta" => true, "0-Eta" => false + } else if (TString(lWhichDiffEtaWeights[dpw]).Contains("wPt")) { + pw.fUseDiffEtaWeights[wEtaPtAxis] = Alright(lWhichDiffEtaWeights[dpw]) && pw.fUseDiffEtaWeights[wEtaEtaAxis]; + } else if (TString(lWhichDiffEtaWeights[dpw]).Contains("wCharge")) { + pw.fUseDiffEtaWeights[wEtaChargeAxis] = Alright(lWhichDiffEtaWeights[dpw]) && pw.fUseDiffEtaWeights[wEtaEtaAxis]; + } else if (TString(lWhichDiffEtaWeights[dpw]).Contains("wCentrality")) { + pw.fUseDiffEtaWeights[wEtaCentralityAxis] = Alright(lWhichDiffEtaWeights[dpw]) && pw.fUseDiffEtaWeights[wEtaEtaAxis]; + } else { + LOGF(fatal, "\033[1;31m%s at line %d : The setting %s in configurable cfWhichDiffEtaWeights is not supported yet. See enum eDiffEtaWeights . \n \033[0m", __FUNCTION__, __LINE__, TString(lWhichDiffEtaWeights[dpw]).Data()); + } + } + + // **) File holding all particle weights: + pw.fFileWithWeights = cf_pw.cfFileWithWeights; + + // *) Centrality weights: + cw.fUseCentralityWeights = cf_cw.cfUseCentralityWeights; + cw.fFileWithCentralityWeights = cf_cw.cfFileWithCentralityWeights; + + // ... + + // *) Nested loops: + nl.fCalculateNestedLoops = cf_nl.cfCalculateNestedLoops; + nl.fCalculateCustomNestedLoops = cf_nl.cfCalculateCustomNestedLoops; + nl.fCalculateKineCustomNestedLoops = cf_nl.cfCalculateKineCustomNestedLoops; + nl.fMaxNestedLoop = cf_nl.cfMaxNestedLoop; + + // ... + + // *) Toy NUA: + auto lApplyNUAPDF = (std::vector)cf_nua.cfApplyNUAPDF; + if (lApplyNUAPDF.size() != eNUAPDF_N) { + LOGF(info, "\033[1;31m lApplyNUAPDF.size() = %d\033[0m", lApplyNUAPDF.size()); + LOGF(info, "\033[1;31m eNUAPDF_N = %d\033[0m", static_cast(eNUAPDF_N)); + LOGF(fatal, "\033[1;31m%s at line %d : Mismatch in the number of flags in configurable cfApplyNUAPDF, and number of entries in enum eNUAPDF \n \033[0m", __FUNCTION__, __LINE__); + } + nua.fApplyNUAPDF[ePhiNUAPDF] = static_cast(lApplyNUAPDF[ePhiNUAPDF]); + nua.fApplyNUAPDF[ePtNUAPDF] = static_cast(lApplyNUAPDF[ePtNUAPDF]); + nua.fApplyNUAPDF[eEtaNUAPDF] = static_cast(lApplyNUAPDF[eEtaNUAPDF]); + + // **) Execute the lines below, only if toy NUA (either default or custom) is requested for at least one kine variable: + if (nua.fApplyNUAPDF[ePhiNUAPDF] || nua.fApplyNUAPDF[ePtNUAPDF] || nua.fApplyNUAPDF[eEtaNUAPDF]) { + + auto lUseDefaultNUAPDF = (std::vector)cf_nua.cfUseDefaultNUAPDF; + if (lUseDefaultNUAPDF.size() != eNUAPDF_N) { + LOGF(info, "\033[1;31m lUseDefaultNUAPDF.size() = %d\033[0m", lUseDefaultNUAPDF.size()); + LOGF(info, "\033[1;31m eNUAPDF_N = %d\033[0m", static_cast(eNUAPDF_N)); + LOGF(fatal, "\033[1;31m%s at line %d : Mismatch in the number of flags in configurable cfUseDefaultNUAPDF, and number of entries in enum eNUAPDF \n \033[0m", __FUNCTION__, __LINE__); + } + nua.fUseDefaultNUAPDF[ePhiNUAPDF] = static_cast(lUseDefaultNUAPDF[ePhiNUAPDF]); + nua.fUseDefaultNUAPDF[ePtNUAPDF] = static_cast(lUseDefaultNUAPDF[ePtNUAPDF]); + nua.fUseDefaultNUAPDF[eEtaNUAPDF] = static_cast(lUseDefaultNUAPDF[eEtaNUAPDF]); + + // **) Execute the lines below, only if custom toy NUA is requested in at least one kine variable: + if (!((nua.fApplyNUAPDF[ePhiNUAPDF] && nua.fUseDefaultNUAPDF[ePhiNUAPDF]) || + (nua.fApplyNUAPDF[ePtNUAPDF] && nua.fUseDefaultNUAPDF[ePtNUAPDF]) || + (nua.fApplyNUAPDF[eEtaNUAPDF] && nua.fUseDefaultNUAPDF[eEtaNUAPDF]))) { + // If the above conditon is true, as least one NUA is requested and is not default, i.e. it's custom NUA obtained from external file, which was requested to be used. + // TBI 20240501 Can I simplify the logic above, it's a bit cryptic... + + // *) external file path with custom NUA histos: + nua.fFileWithCustomNUA = TString(cf_nua.cfFileWithCustomNUA); + + // *) histogram names with custom NUA distributions in that file + get those histograms immediately here: + auto lCustomNUAPDFHistNames = (std::vector)cf_nua.cfCustomNUAPDFHistNames; + // TBI 20241115 For some reason, the default values of configurable "cfCustomNUAPDFHistNames" are not correctly propagated in the local variables, but I can circumvent that with JSON settings for the time being + if (lCustomNUAPDFHistNames.size() != eNUAPDF_N) { + LOGF(info, "\033[1;31m lCustomNUAPDFHistNames.size() = %d\033[0m", lCustomNUAPDFHistNames.size()); + LOGF(info, "\033[1;31m eNUAPDF_N = %d\033[0m", static_cast(eNUAPDF_N)); + LOGF(fatal, "\033[1;31m%s at line %d : Mismatch in the number of flags in configurable cfCustomNUAPDFHistNames, and number of entries in enum eNUAPDF \n \033[0m", __FUNCTION__, __LINE__); + } + + if (!nua.fUseDefaultNUAPDF[ePhiNUAPDF]) { + nua.fCustomNUAPDFHistNames[ePhiNUAPDF] = new TString(lCustomNUAPDFHistNames[ePhiNUAPDF]); + this->GetHistogramWithCustomNUA(nua.fFileWithCustomNUA.Data(), ePhiNUAPDF); + if (!nua.fCustomNUAPDF[ePhiNUAPDF]) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + } + + if (!nua.fUseDefaultNUAPDF[ePtNUAPDF]) { + nua.fCustomNUAPDFHistNames[ePtNUAPDF] = new TString(lCustomNUAPDFHistNames[ePtNUAPDF]); + this->GetHistogramWithCustomNUA(nua.fFileWithCustomNUA.Data(), ePtNUAPDF); + if (!nua.fCustomNUAPDF[ePtNUAPDF]) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + } + if (!nua.fUseDefaultNUAPDF[eEtaNUAPDF]) { + nua.fCustomNUAPDFHistNames[eEtaNUAPDF] = new TString(lCustomNUAPDFHistNames[eEtaNUAPDF]); + this->GetHistogramWithCustomNUA(nua.fFileWithCustomNUA.Data(), eEtaNUAPDF); + if (!nua.fCustomNUAPDF[eEtaNUAPDF]) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + } + } // if (!(nua.fUseDefaultNUAPDF[ePhiNUAPDF] || nua.fUseDefaultNUAPDF[ePtNUAPDF] || nua.fUseDefaultNUAPDF[eEtaNUAPDF])) { + + } // if ( nua.fApplyNUAPDF[ePhiNUAPDF] || nua.fApplyNUAPDF[ePtNUAPDF] || nua.fApplyNUAPDF[eEtaNUAPDF] ) { + + // *) Internal validation: + iv.fUseInternalValidation = cf_iv.cfUseInternalValidation; + iv.fInternalValidationForceBailout = cf_iv.cfInternalValidationForceBailout; + iv.fnEventsInternalValidation = cf_iv.cfnEventsInternalValidation; + iv.fRescaleWithTheoreticalInput = cf_iv.cfRescaleWithTheoreticalInput; + iv.fRandomizeReactionPlane = cf_iv.cfRandomizeReactionPlane; + iv.fHarmonicsOptionInternalValidation = new TString(cf_iv.cfHarmonicsOptionInternalValidation); + // **) Cut counters are not supported in IV (as of 20250728): + if (iv.fUseInternalValidation) { + pc.fUseParticleCutCounterAbsolute = false; + pc.fUseParticleCutCounterSequential = false; + ec.fUseEventCutCounterAbsolute = false; + ec.fUseEventCutCounterSequential = false; + } + + // *) Results histograms: + // **) Fixed-length or variable-length binning: + // Remark: keep ordering in sync with enum eAsFunctionOf: + cf_res.cfUseVariableLengthMultBins ? res.fUseResultsProVariableLengthBins[AFO_MULTIPLICITY] = true : res.fUseResultsProVariableLengthBins[AFO_MULTIPLICITY] = false; + cf_res.cfUseVariableLengthCentBins ? res.fUseResultsProVariableLengthBins[AFO_CENTRALITY] = true : res.fUseResultsProVariableLengthBins[AFO_CENTRALITY] = false; + cf_res.cfUseVariableLengthPtBins ? res.fUseResultsProVariableLengthBins[AFO_PT] = true : res.fUseResultsProVariableLengthBins[AFO_PT] = false; + cf_res.cfUseVariableLengthEtaBins ? res.fUseResultsProVariableLengthBins[AFO_ETA] = true : res.fUseResultsProVariableLengthBins[AFO_ETA] = false; + cf_res.cfUseVariableLengthOccuBins ? res.fUseResultsProVariableLengthBins[AFO_OCCUPANCY] = true : res.fUseResultsProVariableLengthBins[AFO_OCCUPANCY] = false; + cf_res.cfUseVariableLengthCRDBins ? res.fUseResultsProVariableLengthBins[AFO_CURRENTRUNDURATION] = true : res.fUseResultsProVariableLengthBins[AFO_CURRENTRUNDURATION] = false; + cf_res.cfUseVariableLengthVzBins ? res.fUseResultsProVariableLengthBins[AFO_VZ] = true : res.fUseResultsProVariableLengthBins[AFO_VZ] = false; + + // **) Define axis titles: + // Remark: keep ordering in sync with enum eAsFunctionOf + // 1D: + res.fResultsProXaxisTitle[AFO_INTEGRATED] = "integrated"; + res.fResultsProRawName[AFO_INTEGRATED] = "int"; // this is how it appears simplified in the hist name when saved to the file + res.fResultsProXaxisTitle[AFO_MULTIPLICITY] = "multiplicity"; + res.fResultsProRawName[AFO_MULTIPLICITY] = "mult"; + res.fResultsProXaxisTitle[AFO_CENTRALITY] = "centrality"; + res.fResultsProRawName[AFO_CENTRALITY] = "cent"; + res.fResultsProXaxisTitle[AFO_PT] = "pt"; + res.fResultsProRawName[AFO_PT] = "pt"; + res.fResultsProXaxisTitle[AFO_ETA] = "eta"; + res.fResultsProRawName[AFO_ETA] = "eta"; + res.fResultsProXaxisTitle[AFO_OCCUPANCY] = "occupancy"; + res.fResultsProRawName[AFO_OCCUPANCY] = "occu"; + res.fResultsProXaxisTitle[AFO_INTERACTIONRATE] = "interaction rate"; + res.fResultsProRawName[AFO_INTERACTIONRATE] = "ir"; + res.fResultsProXaxisTitle[AFO_CURRENTRUNDURATION] = "current run duration"; + res.fResultsProRawName[AFO_CURRENTRUNDURATION] = "crd"; + res.fResultsProXaxisTitle[AFO_VZ] = "vertex z position"; + res.fResultsProRawName[AFO_VZ] = "vz"; + res.fResultsProXaxisTitle[AFO_CHARGE] = "particle charge"; + res.fResultsProRawName[AFO_CHARGE] = "charge"; + // ... + + // 2D: + // Remark: I re-use the above definitions for 1D. + + // 3D: + // Remark: I re-use the above definitions for 1D. + + res.fSaveResultsHistograms = cf_res.cfSaveResultsHistograms; + + // *) QA: + // Remark: I keep it on the bottom, because here I define some names in temrs of names defined above. + qa.fCheckUnderflowAndOverflow = cf_qa.cfCheckUnderflowAndOverflow; + qa.fRebin = cf_qa.cfRebin; + + // **) Reference multiplicity estimators: + qa.fReferenceMultiplicityEstimatorName[eMultTPC] = "MultTPC"; + qa.fReferenceMultiplicityEstimatorName[eMultFV0M] = "MultFV0M"; + qa.fReferenceMultiplicityEstimatorName[eMultFT0C] = "MultFT0C"; + qa.fReferenceMultiplicityEstimatorName[eMultFT0M] = "MultFT0M"; + qa.fReferenceMultiplicityEstimatorName[eMultNTracksPV] = "MultNTracksPV"; + qa.fReferenceMultiplicityEstimatorName[eMultNTracksGlobal] = "MultNTracksGlobal"; + qa.fReferenceMultiplicityEstimatorName[eMultTracklets] = "MultTracklets"; + + // **) Centrality estimators: + qa.fCentralityEstimatorName[eCentFT0C] = "CentFT0C"; + qa.fCentralityEstimatorName[eCentFT0CVariant1] = "CentFT0CVariant1"; + qa.fCentralityEstimatorName[eCentFT0M] = "CentFT0M"; + qa.fCentralityEstimatorName[eCentFV0A] = "CentFV0A"; + qa.fCentralityEstimatorName[eCentNTPV] = "CentNTPV"; + qa.fCentralityEstimatorName[eCentNGlobal] = "CentNGlobal"; + qa.fCentralityEstimatorName[eCentRun2V0M] = "CentRun2V0M"; + qa.fCentralityEstimatorName[eCentRun2SPDTracklets] = "CentRun2SPDTracklets"; + + // **) Occupancy estimators: + qa.fOccupancyEstimatorName[eTrackOccupancyInTimeRange] = "TrackOccupancyInTimeRange"; + qa.fOccupancyEstimatorName[eFT0COccupancyInTimeRange] = "FT0COccupancyInTimeRange"; + + // **) Names of QA 2D event histograms: + // Remark: Do NOT use FancyFormatting here, only later in bookQAHistograms() for axis titles! + qa.fEventHistogramsName2D[eMultiplicity_vs_ReferenceMultiplicity] = Form("%s_vs_%s", eh.fEventHistogramsName[eMultiplicity].Data(), eh.fEventHistogramsName[eReferenceMultiplicity].Data()); + qa.fEventHistogramsName2D[eMultiplicity_vs_NContributors] = Form("%s_vs_%s", eh.fEventHistogramsName[eMultiplicity].Data(), eh.fEventHistogramsName[eNContributors].Data()); + qa.fEventHistogramsName2D[eMultiplicity_vs_Centrality] = Form("%s_vs_%s", eh.fEventHistogramsName[eMultiplicity].Data(), eh.fEventHistogramsName[eCentrality].Data()); + qa.fEventHistogramsName2D[eMultiplicity_vs_VertexZ] = Form("%s_vs_%s", eh.fEventHistogramsName[eMultiplicity].Data(), eh.fEventHistogramsName[eVertexZ].Data()); + qa.fEventHistogramsName2D[eMultiplicity_vs_Occupancy] = Form("%s_vs_%s", eh.fEventHistogramsName[eMultiplicity].Data(), eh.fEventHistogramsName[eOccupancy].Data()); + qa.fEventHistogramsName2D[eMultiplicity_vs_InteractionRate] = Form("%s_vs_%s", eh.fEventHistogramsName[eMultiplicity].Data(), eh.fEventHistogramsName[eInteractionRate].Data()); + qa.fEventHistogramsName2D[eReferenceMultiplicity_vs_NContributors] = Form("%s_vs_%s", eh.fEventHistogramsName[eReferenceMultiplicity].Data(), eh.fEventHistogramsName[eNContributors].Data()); + qa.fEventHistogramsName2D[eReferenceMultiplicity_vs_Centrality] = Form("%s_vs_%s", eh.fEventHistogramsName[eReferenceMultiplicity].Data(), eh.fEventHistogramsName[eCentrality].Data()); + qa.fEventHistogramsName2D[eReferenceMultiplicity_vs_VertexZ] = Form("%s_vs_%s", eh.fEventHistogramsName[eReferenceMultiplicity].Data(), eh.fEventHistogramsName[eVertexZ].Data()); + qa.fEventHistogramsName2D[eReferenceMultiplicity_vs_Occupancy] = Form("%s_vs_%s", eh.fEventHistogramsName[eReferenceMultiplicity].Data(), eh.fEventHistogramsName[eOccupancy].Data()); + qa.fEventHistogramsName2D[eReferenceMultiplicity_vs_InteractionRate] = Form("%s_vs_%s", eh.fEventHistogramsName[eReferenceMultiplicity].Data(), eh.fEventHistogramsName[eInteractionRate].Data()); + qa.fEventHistogramsName2D[eNContributors_vs_Centrality] = Form("%s_vs_%s", eh.fEventHistogramsName[eNContributors].Data(), eh.fEventHistogramsName[eCentrality].Data()); + qa.fEventHistogramsName2D[eNContributors_vs_VertexZ] = Form("%s_vs_%s", eh.fEventHistogramsName[eNContributors].Data(), eh.fEventHistogramsName[eVertexZ].Data()); + qa.fEventHistogramsName2D[eNContributors_vs_Occupancy] = Form("%s_vs_%s", eh.fEventHistogramsName[eNContributors].Data(), eh.fEventHistogramsName[eOccupancy].Data()); + qa.fEventHistogramsName2D[eNContributors_vs_InteractionRate] = Form("%s_vs_%s", eh.fEventHistogramsName[eNContributors].Data(), eh.fEventHistogramsName[eInteractionRate].Data()); + qa.fEventHistogramsName2D[eCentrality_vs_VertexZ] = Form("%s_vs_%s", eh.fEventHistogramsName[eCentrality].Data(), eh.fEventHistogramsName[eVertexZ].Data()); + qa.fEventHistogramsName2D[eCentrality_vs_Occupancy] = Form("%s_vs_%s", eh.fEventHistogramsName[eCentrality].Data(), eh.fEventHistogramsName[eOccupancy].Data()); + qa.fEventHistogramsName2D[eCentrality_vs_ImpactParameter] = Form("%s_vs_%s", eh.fEventHistogramsName[eCentrality].Data(), eh.fEventHistogramsName[eImpactParameter].Data()); + qa.fEventHistogramsName2D[eCentrality_vs_InteractionRate] = Form("%s_vs_%s", eh.fEventHistogramsName[eCentrality].Data(), eh.fEventHistogramsName[eInteractionRate].Data()); + qa.fEventHistogramsName2D[eVertexZ_vs_Occupancy] = Form("%s_vs_%s", eh.fEventHistogramsName[eVertexZ].Data(), eh.fEventHistogramsName[eOccupancy].Data()); + qa.fEventHistogramsName2D[eVertexZ_vs_InteractionRate] = Form("%s_vs_%s", eh.fEventHistogramsName[eVertexZ].Data(), eh.fEventHistogramsName[eInteractionRate].Data()); + qa.fEventHistogramsName2D[eMultiplicity_vs_FT0CAmplitudeOnFoundBC] = Form("%s_vs_%s", eh.fEventHistogramsName[eMultiplicity].Data(), "FT0CAmplitudeOnFoundBC"); // TBI 20250331 hardwired string + qa.fEventHistogramsName2D[eCentFT0C_vs_FT0CAmplitudeOnFoundBC] = Form("%s_vs_%s", qa.fCentralityEstimatorName[eCentFT0C].Data(), "FT0CAmplitudeOnFoundBC"); // TBI 20250331 hardwired string + qa.fEventHistogramsName2D[eCentrality_vs_CentralitySim] = Form("%s_vs_%s", eh.fEventHistogramsName[eCentrality].Data(), "CentralitySim"); // TBI 20250331 hardwired string + qa.fEventHistogramsName2D[eMultNTracksPV_vs_MultNTracksGlobal] = Form("%s_vs_%s", qa.fReferenceMultiplicityEstimatorName[eMultNTracksPV].Data(), qa.fReferenceMultiplicityEstimatorName[eMultNTracksGlobal].Data()); + qa.fEventHistogramsName2D[eCentFT0C_vs_CentFT0CVariant1] = Form("%s_vs_%s", qa.fCentralityEstimatorName[eCentFT0C].Data(), qa.fCentralityEstimatorName[eCentFT0CVariant1].Data()); + qa.fEventHistogramsName2D[eCentFT0C_vs_CentFT0M] = Form("%s_vs_%s", qa.fCentralityEstimatorName[eCentFT0C].Data(), qa.fCentralityEstimatorName[eCentFT0M].Data()); + qa.fEventHistogramsName2D[eCentFT0C_vs_CentFV0A] = Form("%s_vs_%s", qa.fCentralityEstimatorName[eCentFT0C].Data(), qa.fCentralityEstimatorName[eCentFV0A].Data()); + qa.fEventHistogramsName2D[eCentFT0C_vs_CentNTPV] = Form("%s_vs_%s", qa.fCentralityEstimatorName[eCentFT0C].Data(), qa.fCentralityEstimatorName[eCentNTPV].Data()); + qa.fEventHistogramsName2D[eCentFT0C_vs_CentNGlobal] = Form("%s_vs_%s", qa.fCentralityEstimatorName[eCentFT0C].Data(), qa.fCentralityEstimatorName[eCentNGlobal].Data()); + qa.fEventHistogramsName2D[eCentFT0M_vs_CentNTPV] = Form("%s_vs_%s", qa.fCentralityEstimatorName[eCentFT0M].Data(), qa.fCentralityEstimatorName[eCentNTPV].Data()); + qa.fEventHistogramsName2D[eCentRun2V0M_vs_CentRun2SPDTracklets] = Form("%s_vs_%s", qa.fCentralityEstimatorName[eCentRun2V0M].Data(), qa.fCentralityEstimatorName[eCentRun2SPDTracklets].Data()); + qa.fEventHistogramsName2D[eTrackOccupancyInTimeRange_vs_FT0COccupancyInTimeRange] = Form("%s_vs_%s", qa.fOccupancyEstimatorName[eTrackOccupancyInTimeRange].Data(), qa.fOccupancyEstimatorName[eFT0COccupancyInTimeRange].Data()); + qa.fEventHistogramsName2D[eCurrentRunDuration_vs_InteractionRate] = Form("%s_vs_%s", ec.fEventCutName[eCurrentRunDuration].Data(), ec.fEventCutName[eInteractionRate].Data()); + + // ***) Quick insanity check that all names are set: + for (int t = 0; t < eQAEventHistograms2D_N; t++) { + if (qa.fEventHistogramsName2D[t].EqualTo("")) { + LOGF(fatal, "\033[1;31m%s at line %d : qa.fEventHistogramsName2D[%d] is not set, check corresponding enum eQAEventHistograms2D \033[0m", __FUNCTION__, __LINE__, t); + } + } + + // **) Names of QA 2D particle histograms: + qa.fParticleHistogramsName2D[ePt_vs_dcaXY] = Form("%s_vs_%s", ph.fParticleHistogramsName[ePt].Data(), ph.fParticleHistogramsName[edcaXY].Data()); + + // ***) Quick insanity check that all names are set: + for (int t = 0; t < eQAParticleHistograms2D_N; t++) { + if (qa.fParticleHistogramsName2D[t].EqualTo("")) { + LOGF(fatal, "\033[1;31m%s at line %d : qa.fParticleHistogramsName2D[%d] is not set, check corresponding enum eQAParticleHistograms2D \033[0m", __FUNCTION__, __LINE__, t); + } + } + + // **) Names of QA 2D particle event histograms: + qa.fQAParticleEventHistogramsName2D[eCurrentRunDuration_vs_itsNClsEbyE] = TString::Format("%s_vs_%s", eh.fEventHistogramsName[eCurrentRunDuration].Data(), ph.fParticleHistogramsName[eitsNCls].Data()).Data(); + qa.fQAParticleEventHistogramsName2D[eCurrentRunDuration_vs_itsNClsNegEtaEbyE] = TString::Format("%s_vs_%s", eh.fEventHistogramsName[eCurrentRunDuration].Data(), TString(ph.fParticleHistogramsName[eitsNCls].Data()).Append("NegEtaEbyE").Data()).Data(); // TBI 20241214 time will tell if this Append() is safe enough... Remember that Append works in-place + qa.fQAParticleEventHistogramsName2D[eCurrentRunDuration_vs_itsNClsPosEtaEbyE] = TString::Format("%s_vs_%s", eh.fEventHistogramsName[eCurrentRunDuration].Data(), TString(ph.fParticleHistogramsName[eitsNCls].Data()).Append("PosEtaEbyE").Data()).Data(); // TBI 20241214 time will tell if this Append() is safe enough... Remember that Append works in-place + qa.fQAParticleEventHistogramsName2D[eCurrentRunDuration_vs_Eta0804EbyE] = TString::Format("%s_vs_%s", eh.fEventHistogramsName[eCurrentRunDuration].Data(), TString(ph.fParticleHistogramsName[eEta].Data()).Append("0804EbyE").Data()).Data(); // TBI 20241214 time will tell if this Append() is safe enough... Remember that Append works in-place + qa.fQAParticleEventHistogramsName2D[eCurrentRunDuration_vs_Eta0400EbyE] = TString::Format("%s_vs_%s", eh.fEventHistogramsName[eCurrentRunDuration].Data(), TString(ph.fParticleHistogramsName[eEta].Data()).Append("0400EbyE").Data()).Data(); // TBI 20241214 time will tell if this Append() is safe enough... Remember that Append works in-place + qa.fQAParticleEventHistogramsName2D[eCurrentRunDuration_vs_Eta0004EbyE] = TString::Format("%s_vs_%s", eh.fEventHistogramsName[eCurrentRunDuration].Data(), TString(ph.fParticleHistogramsName[eEta].Data()).Append("0004EbyE").Data()).Data(); // TBI 20241214 time will tell if this Append() is safe enough... Remember that Append works in-place + qa.fQAParticleEventHistogramsName2D[eCurrentRunDuration_vs_Eta0408EbyE] = TString::Format("%s_vs_%s", eh.fEventHistogramsName[eCurrentRunDuration].Data(), TString(ph.fParticleHistogramsName[eEta].Data()).Append("0408EbyE").Data()).Data(); // TBI 20241214 time will tell if this Append() is safe enough... Remember that Append works in-place + qa.fQAParticleEventHistogramsName2D[eCurrentRunDuration_vs_Pt0005EbyE] = TString::Format("%s_vs_%s", eh.fEventHistogramsName[eCurrentRunDuration].Data(), TString(ph.fParticleHistogramsName[ePt].Data()).Append("0005EbyE").Data()).Data(); // TBI 20241214 time will tell if this Append() is safe enough... Remember that Append works in-place + qa.fQAParticleEventHistogramsName2D[eCurrentRunDuration_vs_Pt0510EbyE] = TString::Format("%s_vs_%s", eh.fEventHistogramsName[eCurrentRunDuration].Data(), TString(ph.fParticleHistogramsName[ePt].Data()).Append("0510EbyE").Data()).Data(); // TBI 20241214 time will tell if this Append() is safe enough... Remember that Append works in-place + qa.fQAParticleEventHistogramsName2D[eCurrentRunDuration_vs_Pt1050EbyE] = TString::Format("%s_vs_%s", eh.fEventHistogramsName[eCurrentRunDuration].Data(), TString(ph.fParticleHistogramsName[ePt].Data()).Append("1050EbyE").Data()).Data(); // TBI 20241214 time will tell if this Append() is safe enough... Remember that Append works in-place + + // ***) Quick insanity check that all names are set: + for (int t = 0; t < eQAParticleEventHistograms2D_N; t++) { + if (qa.fQAParticleEventHistogramsName2D[t].EqualTo("")) { + LOGF(fatal, "\033[1;31m%s at line %d : qa.fQAParticleEventHistogramsName2D[%d] is not set, check corresponding enum eQAParticleEventHistograms2D \033[0m", __FUNCTION__, __LINE__, t); + } + } + + // **) Names of QA 2D "correlations vs." histograms: + qa.fQACorrelationsVsHistogramsName2D[eCorrelations_vs_Multiplicity] = TString::Format("%s_vs_%s", "Correlations", eh.fEventHistogramsName[eMultiplicity].Data()).Data(); + qa.fQACorrelationsVsHistogramsName2D[eCorrelations_vs_ReferenceMultiplicity] = TString::Format("%s_vs_%s", "Correlations", eh.fEventHistogramsName[eReferenceMultiplicity].Data()).Data(); + qa.fQACorrelationsVsHistogramsName2D[eCorrelations_vs_Centrality] = TString::Format("%s_vs_%s", "Correlations", eh.fEventHistogramsName[eCentrality].Data()).Data(); + // ... + qa.fQACorrelationsVsHistogramsName2D[eCorrelations_vs_MeanPhi] = TString::Format("%s_vs_%s", "Correlations", ph.fParticleHistogramsName[ePhi].Data()).Data(); + qa.fQACorrelationsVsHistogramsName2D[eCorrelations_vs_MeanPt] = TString::Format("%s_vs_%s", "Correlations", ph.fParticleHistogramsName[ePt].Data()).Data(); + qa.fQACorrelationsVsHistogramsName2D[eCorrelations_vs_MeanEta] = TString::Format("%s_vs_%s", "Correlations", ph.fParticleHistogramsName[eEta].Data()).Data(); + qa.fQACorrelationsVsHistogramsName2D[eCorrelations_vs_MeanCharge] = TString::Format("%s_vs_%s", "Correlations", ph.fParticleHistogramsName[eCharge].Data()).Data(); + qa.fQACorrelationsVsHistogramsName2D[eCorrelations_vs_MeantpcNClsFindable] = TString::Format("%s_vs_%s", "Correlations", ph.fParticleHistogramsName[etpcNClsFindable].Data()).Data(); + qa.fQACorrelationsVsHistogramsName2D[eCorrelations_vs_MeantpcNClsShared] = TString::Format("%s_vs_%s", "Correlations", ph.fParticleHistogramsName[etpcNClsShared].Data()).Data(); + qa.fQACorrelationsVsHistogramsName2D[eCorrelations_vs_MeanitsChi2NCl] = TString::Format("%s_vs_%s", "Correlations", ph.fParticleHistogramsName[eitsChi2NCl].Data()).Data(); + qa.fQACorrelationsVsHistogramsName2D[eCorrelations_vs_MeantpcNClsFound] = TString::Format("%s_vs_%s", "Correlations", ph.fParticleHistogramsName[etpcNClsFound].Data()).Data(); + qa.fQACorrelationsVsHistogramsName2D[eCorrelations_vs_MeantpcNClsCrossedRows] = TString::Format("%s_vs_%s", "Correlations", ph.fParticleHistogramsName[etpcNClsCrossedRows].Data()).Data(); + qa.fQACorrelationsVsHistogramsName2D[eCorrelations_vs_MeanitsNCls] = TString::Format("%s_vs_%s", "Correlations", ph.fParticleHistogramsName[eitsNCls].Data()).Data(); + qa.fQACorrelationsVsHistogramsName2D[eCorrelations_vs_MeanitsNClsInnerBarrel] = TString::Format("%s_vs_%s", "Correlations", ph.fParticleHistogramsName[eitsNClsInnerBarrel].Data()).Data(); + qa.fQACorrelationsVsHistogramsName2D[eCorrelations_vs_MeantpcCrossedRowsOverFindableCls] = TString::Format("%s_vs_%s", "Correlations", ph.fParticleHistogramsName[etpcCrossedRowsOverFindableCls].Data()).Data(); + qa.fQACorrelationsVsHistogramsName2D[eCorrelations_vs_MeantpcFoundOverFindableCls] = TString::Format("%s_vs_%s", "Correlations", ph.fParticleHistogramsName[etpcFoundOverFindableCls].Data()).Data(); + qa.fQACorrelationsVsHistogramsName2D[eCorrelations_vs_MeantpcFractionSharedCls] = TString::Format("%s_vs_%s", "Correlations", ph.fParticleHistogramsName[etpcFractionSharedCls].Data()).Data(); + qa.fQACorrelationsVsHistogramsName2D[eCorrelations_vs_MeantpcChi2NCl] = TString::Format("%s_vs_%s", "Correlations", ph.fParticleHistogramsName[etpcChi2NCl].Data()).Data(); + qa.fQACorrelationsVsHistogramsName2D[eCorrelations_vs_MeandcaXY] = TString::Format("%s_vs_%s", "Correlations", ph.fParticleHistogramsName[edcaXY].Data()).Data(); + qa.fQACorrelationsVsHistogramsName2D[eCorrelations_vs_MeandcaZ] = TString::Format("%s_vs_%s", "Correlations", ph.fParticleHistogramsName[edcaZ].Data()).Data(); + + // ... + + // ***) Quick insanity check that all names are set: + for (int t = 0; t < eQACorrelationsVsHistograms2D_N; t++) { + if (qa.fQACorrelationsVsHistogramsName2D[t].EqualTo("")) { + LOGF(fatal, "\033[1;31m%s at line %d : qa.fQACorrelationsVsHistogramsName2D[%d] is not set, check corresponding enum eQACorrelationsVsHistograms2D \033[0m", __FUNCTION__, __LINE__, t); + } + } + + // **) Names of QA 2D "correlations vs. IR vs. " profiles: + qa.fQACorrelationsVsInteractionRateVsProfilesName2D[eCorrelationsVsInteractionRate_vs_CurrentRunDuration] = TString::Format("%s_vs_%s", "CorrVsIR", eh.fEventHistogramsName[eCurrentRunDuration].Data()).Data(); + qa.fQACorrelationsVsInteractionRateVsProfilesName2D[eCorrelationsVsInteractionRate_vs_Multiplicity] = TString::Format("%s_vs_%s", "CorrVsIR", eh.fEventHistogramsName[eMultiplicity].Data()).Data(); + qa.fQACorrelationsVsInteractionRateVsProfilesName2D[eCorrelationsVsInteractionRate_vs_ReferenceMultiplicity] = TString::Format("%s_vs_%s", "CorrVsIR", eh.fEventHistogramsName[eReferenceMultiplicity].Data()).Data(); + qa.fQACorrelationsVsInteractionRateVsProfilesName2D[eCorrelationsVsInteractionRate_vs_Centrality] = TString::Format("%s_vs_%s", "CorrVsIR", eh.fEventHistogramsName[eCentrality].Data()).Data(); + // ... + qa.fQACorrelationsVsInteractionRateVsProfilesName2D[eCorrelationsVsInteractionRate_vs_MeanPhi] = TString::Format("%s_vs_Mean%s", "CorrVsIR", ph.fParticleHistogramsName[ePhi].Data()).Data(); + qa.fQACorrelationsVsInteractionRateVsProfilesName2D[eCorrelationsVsInteractionRate_vs_SigmaMeanPhi] = TString::Format("%s_vs_SigmaMean%s", "CorrVsIR", ph.fParticleHistogramsName[ePhi].Data()).Data(); + qa.fQACorrelationsVsInteractionRateVsProfilesName2D[eCorrelationsVsInteractionRate_vs_MeanPt] = TString::Format("%s_vs_Mean%s", "CorrVsIR", ph.fParticleHistogramsName[ePt].Data()).Data(); + qa.fQACorrelationsVsInteractionRateVsProfilesName2D[eCorrelationsVsInteractionRate_vs_SigmaMeanPt] = TString::Format("%s_vs_SigmaMean%s", "CorrVsIR", ph.fParticleHistogramsName[ePt].Data()).Data(); + qa.fQACorrelationsVsInteractionRateVsProfilesName2D[eCorrelationsVsInteractionRate_vs_MeanEta] = TString::Format("%s_vs_Mean%s", "CorrVsIR", ph.fParticleHistogramsName[eEta].Data()).Data(); + qa.fQACorrelationsVsInteractionRateVsProfilesName2D[eCorrelationsVsInteractionRate_vs_SigmaMeanEta] = TString::Format("%s_vs_SigmaMean%s", "CorrVsIR", ph.fParticleHistogramsName[eEta].Data()).Data(); + + // ... + + // ***) Quick insanity check that all names are set: + for (int t = 0; t < eQACorrelationsVsInteractionRateVsProfiles2D_N; t++) { + if (qa.fQACorrelationsVsInteractionRateVsProfilesName2D[t].EqualTo("")) { + LOGF(fatal, "\033[1;31m%s at line %d : qa.fQACorrelationsVsInteractionRateVsProfilesName2D[%d] is not set, check corresponding enum eQACorrelationsVsInteractionRateVsProfiles2D \033[0m", __FUNCTION__, __LINE__, t); + } + } + + // **) Names and titles of all categories of sparse histograms: + ph.fParticleSparseHistogramsName[eDWPhi] = "fParticleSparseHistograms_DWPhi"; + ph.fParticleSparseHistogramsTitle[eDWPhi] = "sparse histogram for differential #phi weights,"; + + ph.fParticleSparseHistogramsName[eDWPt] = "fParticleSparseHistograms_DWPt"; + ph.fParticleSparseHistogramsTitle[eDWPt] = "sparse histogram for differential p_{T} weights,"; + + ph.fParticleSparseHistogramsName[eDWEta] = "fParticleSparseHistograms_DWEta"; + ph.fParticleSparseHistogramsTitle[eDWEta] = "sparse histogram for differential #eta weights,"; + + // ... + + // ** Eta separations: + es.fCalculateEtaSeparations = cf_es.cfCalculateEtaSeparations; + + // *) Use configurable array cfCalculateEtaSeparationsAsFunctionOf, to specify vs which observable EtaSeparations will be calculated (flags 1 or 0). + // Supported format: "0-someName" and "1-someName", where "-" is a field separator. + // Ordering of the flags in that array is interpreted through ordering of enums in enum eAsFunctionOf. + auto lCalculateEtaSeparationsAsFunctionOf = cf_es.cfCalculateEtaSeparationsAsFunctionOf.value; // this is now the local version of that string array from configurable. + if (lCalculateEtaSeparationsAsFunctionOf.size() != eAsFunctionOf_N) { + LOGF(info, "\033[1;31m lCalculateEtaSeparationsAsFunctionOf.size() = %d\033[0m", lCalculateEtaSeparationsAsFunctionOf.size()); + LOGF(info, "\033[1;31m eAsFunctionOf_N) = %d\033[0m", static_cast(eAsFunctionOf_N)); + LOGF(fatal, "\033[1;31m%s at line %d : Mismatch in the number of flags in configurable cfCalculateEtaSeparationsAsFunctionOf, and number of entries in enum eAsFunctionOf_N \n \033[0m", __FUNCTION__, __LINE__); + } + + // I append "&& es.fCalculateEtaSeparations" below, to switch off calculation of all correlations with one common flag: + es.fCalculateEtaSeparationsAsFunctionOf[AFO_INTEGRATED] = Alright(lCalculateEtaSeparationsAsFunctionOf[AFO_INTEGRATED]) && es.fCalculateEtaSeparations; + es.fCalculateEtaSeparationsAsFunctionOf[AFO_MULTIPLICITY] = Alright(lCalculateEtaSeparationsAsFunctionOf[AFO_MULTIPLICITY]) && es.fCalculateEtaSeparations; + es.fCalculateEtaSeparationsAsFunctionOf[AFO_CENTRALITY] = Alright(lCalculateEtaSeparationsAsFunctionOf[AFO_CENTRALITY]) && es.fCalculateEtaSeparations; + es.fCalculateEtaSeparationsAsFunctionOf[AFO_PT] = Alright(lCalculateEtaSeparationsAsFunctionOf[AFO_PT]) && es.fCalculateEtaSeparations; + es.fCalculateEtaSeparationsAsFunctionOf[AFO_ETA] = false; // yes, in this context this one doesn't make sense + es.fCalculateEtaSeparationsAsFunctionOf[AFO_OCCUPANCY] = Alright(lCalculateEtaSeparationsAsFunctionOf[AFO_OCCUPANCY]) && es.fCalculateEtaSeparations; + es.fCalculateEtaSeparationsAsFunctionOf[AFO_INTERACTIONRATE] = Alright(lCalculateEtaSeparationsAsFunctionOf[AFO_INTERACTIONRATE]) && es.fCalculateEtaSeparations; + es.fCalculateEtaSeparationsAsFunctionOf[AFO_CURRENTRUNDURATION] = Alright(lCalculateEtaSeparationsAsFunctionOf[AFO_CURRENTRUNDURATION]) && es.fCalculateEtaSeparations; + es.fCalculateEtaSeparationsAsFunctionOf[AFO_VZ] = Alright(lCalculateEtaSeparationsAsFunctionOf[AFO_VZ]) && es.fCalculateEtaSeparations; + es.fCalculateEtaSeparationsAsFunctionOf[AFO_CHARGE] = Alright(lCalculateEtaSeparationsAsFunctionOf[AFO_CHARGE]) && es.fCalculateEtaSeparations; + // ... + + if (es.fCalculateEtaSeparations) { + auto lEtaSeparationsValues = cf_es.cfEtaSeparationsValues.value; + if (lEtaSeparationsValues.size() != gMaxNumberEtaSeparations) { + LOGF(info, "\033[1;31m%s at line %d : lEtaSeparationsValues.size() = %d\n \033[0m", __FUNCTION__, __LINE__, lEtaSeparationsValues.size()); + LOGF(fatal, "\033[1;31m%s at line %d : Provide in configurable cfEtaSeparationsValues precisely %d entries\n \033[0m", __FUNCTION__, __LINE__, static_cast(gMaxNumberEtaSeparations)); + } + for (int e = 0; e < gMaxNumberEtaSeparations; e++) { + if (lEtaSeparationsValues[e] < 0.) { + LOGF(fatal, "\033[1;31m%s at line %d : lEtaSeparationsValues[%d] = %f is not >= 0. \n \033[0m", __FUNCTION__, __LINE__, e, static_cast(lEtaSeparationsValues[e])); + } + es.fEtaSeparationsValues[e] = lEtaSeparationsValues[e]; + } + + auto lEtaSeparationsSkipHarmonics = cf_es.cfEtaSeparationsSkipHarmonics.value; + if (lEtaSeparationsSkipHarmonics.size() != gMaxHarmonic) { + LOGF(info, "\033[1;31m lEtaSeparationsSkipHarmonics.size() = %d\033[0m", lEtaSeparationsSkipHarmonics.size()); + LOGF(info, "\033[1;31m gMaxHarmonic) = %d\033[0m", static_cast(gMaxHarmonic)); + LOGF(fatal, "\033[1;31m%s at line %d : Mismatch in the number of flags in configurable cfEtaSeparationsSkipHarmonics, and max number of supported harmonics \n \033[0m", __FUNCTION__, __LINE__); + } + + for (int h = 0; h < static_cast(lEtaSeparationsSkipHarmonics.size()); h++) { + es.fEtaSeparationsSkipHarmonics[h] = Alright(lEtaSeparationsSkipHarmonics[h]); + } + + } // if(es.fCalculateEtaSeparations) { + + // Set the flags qv.fCalculateqvectorsKineAny, fCalculateqvectorsKine[eqvectorKine_N] and fCalculateqvectorsKineEtaSeparations[eqvectorKine_N]: + // TBI 20250601 I have to do it without loop, until I provide support for 2D and 3D to Correlations and EtaSeparations + + // Test0 and Correlations: + if (mupa.fCalculateCorrelationsAsFunctionOf[AfoKineMap1D(PTq)] || t0.fCalculateTest0AsFunctionOf[AfoKineMap1D(PTq)]) { + qv.fCalculateqvectorsKine[PTq] = true; + } + if (mupa.fCalculateCorrelationsAsFunctionOf[AfoKineMap1D(ETAq)] || t0.fCalculateTest0AsFunctionOf[AfoKineMap1D(ETAq)]) { + qv.fCalculateqvectorsKine[ETAq] = true; + } + if (mupa.fCalculateCorrelationsAsFunctionOf[AfoKineMap1D(CHARGEq)] || t0.fCalculateTest0AsFunctionOf[AfoKineMap1D(CHARGEq)]) { + qv.fCalculateqvectorsKine[CHARGEq] = true; + } + if (t0.fCalculate2DTest0AsFunctionOf[AfoKineMap2D(PT_ETAq)]) { + qv.fCalculateqvectorsKine[PT_ETAq] = true; + } + if (t0.fCalculate2DTest0AsFunctionOf[AfoKineMap2D(PT_CHARGEq)]) { + qv.fCalculateqvectorsKine[PT_CHARGEq] = true; + } + if (t0.fCalculate2DTest0AsFunctionOf[AfoKineMap2D(ETA_CHARGEq)]) { + qv.fCalculateqvectorsKine[ETA_CHARGEq] = true; + } + if (t0.fCalculate3DTest0AsFunctionOf[AfoKineMap3D(PT_ETA_CHARGEq)]) { + qv.fCalculateqvectorsKine[PT_ETA_CHARGEq] = true; + } + + // Eta separations: + if (es.fCalculateEtaSeparationsAsFunctionOf[AfoKineMap1D(PTq)]) { + qv.fCalculateqvectorsKineEtaSeparations[PTq] = true; + } + qv.fCalculateqvectorsKineEtaSeparations[ETAq] = false; // yes, this one is alwas set explicitly to false + if (es.fCalculateEtaSeparationsAsFunctionOf[AfoKineMap1D(CHARGEq)]) { + qv.fCalculateqvectorsKineEtaSeparations[CHARGEq] = true; + } + qv.fCalculateqvectorsKineEtaSeparations[PT_ETAq] = false; // yes, this one is alwas set explicitly to false + + // TBI 20250617 comment in this branch, when i implement support for 2D eta separations. + // if (es.fCalculate2DEtaSeparationsAsFunctionOf[AfoKineMap2D(PT_CHARGEq)]) { + // qv.fCalculateqvectorsKineEtaSeparations[PT_CHARGEq] = true; + // } + + qv.fCalculateqvectorsKineEtaSeparations[ETA_CHARGEq] = false; // yes, this one is alwas set explicitly to false + qv.fCalculateqvectorsKineEtaSeparations[PT_ETA_CHARGEq] = false; // yes, this one is alwas set explicitly to false + + for (int qKine = 0; qKine < eqvectorKine_N; qKine++) { + if (qv.fCalculateqvectorsKine[qKine] || qv.fCalculateqvectorsKineEtaSeparations[qKine]) { + qv.fCalculateqvectorsKineAny = true; + break; // yes, I need at least one kine calculus, to set this flag to true + } + } + + // In terms of above settings, define automatically general fCalculateAsFunctionOf flags: + // 1D: + for (int AFO_1D = 0; AFO_1D < eAsFunctionOf_N; AFO_1D++) { + tc.fCalculateAsFunctionOf[AFO_1D] = mupa.fCalculateCorrelationsAsFunctionOf[AFO_1D] || t0.fCalculateTest0AsFunctionOf[AFO_1D] || es.fCalculateEtaSeparationsAsFunctionOf[AFO_1D]; + } + // 2D: + for (int AFO_2D = 0; AFO_2D < eAsFunctionOf2D_N; AFO_2D++) { + tc.fCalculate2DAsFunctionOf[AFO_2D] = t0.fCalculate2DTest0AsFunctionOf[AFO_2D]; // TBI 20260212 for the time being, I support 2D only for Test0 + } + // 3D: + for (int AFO_3D = 0; AFO_3D < eAsFunctionOf3D_N; AFO_3D++) { + tc.fCalculate3DAsFunctionOf[AFO_3D] = t0.fCalculate3DTest0AsFunctionOf[AFO_3D]; // TBI 20260212 for the time being, I support 3D only for Test0 + } + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // void defaultConfiguration() + + //============================================================ + + bool Alright(TString s) + { + // Simple utility function, which for a string formatted "0-someName" returns false, and for "1-someName" returns true. + + // a) Insanity check on the format; + // b) Do the thing. + + if (tc.fVerboseUtility) { + StartFunction(__FUNCTION__); + LOGF(info, "\033[1;32m TString s = %s\033[0m", s.Data()); + } + + bool returnValue = false; + + // a) Insanity check on the format: + TObjArray* oa = s.Tokenize("-"); + if (!oa) { + LOGF(fatal, "\033[1;31m%s at line %d : oa is NULL , s = %s\033[0m", __FUNCTION__, __LINE__, s.Data()); + } + int nEntries = oa->GetEntries(); + if (2 != nEntries) { + LOGF(fatal, "\033[1;31m%s at line %d : string expected in this function must be formatted as \"0-someName\" or \"1-someName\" => s = %s\033[0m", __FUNCTION__, __LINE__, s.Data()); + } + + // b) Do the thing: + // Algorithm: I split "0-someName" or "1-someName" with respect to "-" as a field separator, and check what is in the 1st field. + if (TString(oa->At(0)->GetName()).EqualTo("0")) { + delete oa; + returnValue = false; + } else if (TString(oa->At(0)->GetName()).EqualTo("1")) { + delete oa; + returnValue = true; + } else { + LOGF(fatal, "\033[1;31m%s at line %d : string expected in this function must be formatted as \"0-someName\" or \"1-someName\" => s = %s\033[0m", __FUNCTION__, __LINE__, s.Data()); + } + + if (tc.fVerboseUtility) { + ExitFunction(__FUNCTION__); + } + + return returnValue; + + } // bool Alright(const char* name) + + //============================================================ + + void defaultBooking() + { + // Set here which histograms are booked by default. + + // a) Event histograms 1D; + // b) Event histograms 2D; + // c) Particle histograms 1D; + // d) Particle histograms 2D; + // e) Particle sparse histograms; + // f) QA. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // a) Event histograms 1D: + // By default all event histograms are booked. Set this flag to false to switch off booking of all event histograms: + eh.fFillEventHistograms = cf_eh.cfFillEventHistograms; + + // *) By default all event histograms are booked. If you do not want particular event histogram to be booked, + // use configurable array cfBookEventHistograms, where you can specify name of the histogram accompanied with flags 1 (book) or 0 (do not book). + // Supported format: "0-someName" and "1-someName", where "-" is a field separator. + // Ordering of the flags in that array is interpreted through ordering of enums in enum eEventHistograms. + auto lBookEventHistograms = cf_eh.cfBookEventHistograms.value; // this is now the local version of that string array from configurable. + if (lBookEventHistograms.size() != eEventHistograms_N) { + LOGF(info, "\033[1;31m lBookEventHistograms.size() = %d\033[0m", lBookEventHistograms.size()); + LOGF(info, "\033[1;31m eEventHistograms_N) = %d\033[0m", static_cast(eEventHistograms_N)); + LOGF(fatal, "\033[1;31m%s at line %d : Mismatch in the number of flags in configurable cfBookEventHistograms, and number of entries in enum eEventHistograms \n \033[0m", __FUNCTION__, __LINE__); + } + + // *) Insanity check on the content and ordering of histogram names in the initialization in configurable cfBookEventHistograms: + // TBI 20240518 I do not need this in fact, I can automate initialization even without ordering in configurable, but it feels with the ordering enforced, it's much safer. + for (int name = 0; name < eEventHistograms_N; name++) { + // TBI 20240518 I could implement even a strickter EqualTo instead of EndsWith, but then I need to tokenize, etc., etc. This shall be safe enough. + if (!TString(lBookEventHistograms[name]).EndsWith(eh.fEventHistogramsName[name].Data())) { + LOGF(fatal, "\033[1;31m%s at line %d : Wrong content or ordering of contents in configurable cfBookEventHistograms => name = %d, lBookEventHistograms[%d] = \"%s\", eh.fEventHistogramsName[%d] = \"%s\" \n Check if you are using an up to date tag. \033[0m", __FUNCTION__, __LINE__, name, name, TString(lBookEventHistograms[name]).Data(), name, eh.fEventHistogramsName[name].Data()); + } + } + + // I append "&& eh.fFillEventHistograms" below, to switch off booking of all event histograms with one common flag: + eh.fBookEventHistograms[eNumberOfEvents] = Alright(lBookEventHistograms[eNumberOfEvents]) && eh.fFillEventHistograms; + eh.fBookEventHistograms[eTotalMultiplicity] = Alright(lBookEventHistograms[eTotalMultiplicity]) && eh.fFillEventHistograms; + eh.fBookEventHistograms[eMultiplicity] = Alright(lBookEventHistograms[eMultiplicity]) && eh.fFillEventHistograms; + eh.fBookEventHistograms[eReferenceMultiplicity] = Alright(lBookEventHistograms[eReferenceMultiplicity]) && eh.fFillEventHistograms; + eh.fBookEventHistograms[eCentrality] = Alright(lBookEventHistograms[eCentrality]) && eh.fFillEventHistograms; + eh.fBookEventHistograms[eVertexX] = Alright(lBookEventHistograms[eVertexX]) && eh.fFillEventHistograms; + eh.fBookEventHistograms[eVertexY] = Alright(lBookEventHistograms[eVertexY]) && eh.fFillEventHistograms; + eh.fBookEventHistograms[eVertexZ] = Alright(lBookEventHistograms[eVertexZ]) && eh.fFillEventHistograms; + eh.fBookEventHistograms[eNContributors] = Alright(lBookEventHistograms[eNContributors]) && eh.fFillEventHistograms; + eh.fBookEventHistograms[eImpactParameter] = Alright(lBookEventHistograms[eImpactParameter]) && eh.fFillEventHistograms; + eh.fBookEventHistograms[eEventPlaneAngle] = Alright(lBookEventHistograms[eEventPlaneAngle]) && eh.fFillEventHistograms; + eh.fBookEventHistograms[eOccupancy] = Alright(lBookEventHistograms[eOccupancy]) && eh.fFillEventHistograms; + eh.fBookEventHistograms[eInteractionRate] = Alright(lBookEventHistograms[eInteractionRate]) && eh.fFillEventHistograms; + eh.fBookEventHistograms[eCurrentRunDuration] = Alright(lBookEventHistograms[eCurrentRunDuration]) && eh.fFillEventHistograms; + eh.fBookEventHistograms[eMultMCNParticlesEta08] = Alright(lBookEventHistograms[eMultMCNParticlesEta08]) && eh.fFillEventHistograms; + + // b) Event histograms 2D: + // TBI 20240515 Ideally, all 2D shall go to QA group, see below + // ... + + // c) Particle histograms 1D: + // By default all 1D particle histograms are booked. Set this flag to false to switch off booking of all 1D particle histograms: + ph.fFillParticleHistograms = cf_ph.cfFillParticleHistograms; + + // *) If you do not want particular particle histogram to be booked, use configurable array cfBookParticleHistograms, where you can specify flags 1 (book) or 0 (do not book). + // Ordering of the flags in that array is interpreted through ordering of enums in enum eParticleHistograms. // TBI 20240124 is this safe enough? + auto lBookParticleHistograms = cf_ph.cfBookParticleHistograms.value; // this is now the local version of that string array from configurable. + if (lBookParticleHistograms.size() != eParticleHistograms_N) { + LOGF(info, "\033[1;31m lBookParticleHistograms.size() = %d\033[0m", lBookParticleHistograms.size()); + LOGF(info, "\033[1;31m eParticleHistograms_N) = %d\033[0m", static_cast(eParticleHistograms_N)); + LOGF(fatal, "in function \033[1;31m%s at line %d Mismatch in the number of flags in configurable cfBookParticleHistograms, and number of entries in enum eParticleHistograms \n \033[0m", __FUNCTION__, __LINE__); + } + + // *) Insanity check on the content and ordering of particle histograms in the initialization in configurable cfBookParticleHistograms: + // TBI 20240518 I do not need this in fact, I can automate initialization even without ordering in configurable, but it feels with the ordering enforced, it's much safer. + for (int name = 0; name < eParticleHistograms_N; name++) { + // TBI 20240518 I could implement even a strickter EqualTo instead of EndsWith, but then I need to tokenize, etc., etc. This shall be safe enough. + if (!TString(lBookParticleHistograms[name]).EndsWith(ph.fParticleHistogramsName[name].Data())) { + LOGF(fatal, "\033[1;31m%s at line %d : Wrong content or ordering of contents in configurable cfBookParticleHistograms => name = %d, lBookParticleHistograms[name] = \"%s\", ph.fParticleHistogramsName[name] = \"%s\" \n Check if you are using an up to date tag. \033[0m", __FUNCTION__, __LINE__, name, TString(lBookParticleHistograms[name]).Data(), ph.fParticleHistogramsName[name].Data()); + } + } + + // I append "&& ph.fFillParticleHistograms" below, to switch off booking of all 1D particle histograms with one common flag: + ph.fBookParticleHistograms[ePhi] = Alright(lBookParticleHistograms[ePhi]) && ph.fFillParticleHistograms; + ph.fBookParticleHistograms[ePt] = Alright(lBookParticleHistograms[ePt]) && ph.fFillParticleHistograms; + ph.fBookParticleHistograms[eEta] = Alright(lBookParticleHistograms[eEta]) && ph.fFillParticleHistograms; + ph.fBookParticleHistograms[eCharge] = Alright(lBookParticleHistograms[eCharge]) && ph.fFillParticleHistograms; + ph.fBookParticleHistograms[etpcNClsFindable] = Alright(lBookParticleHistograms[etpcNClsFindable]) && ph.fFillParticleHistograms; + ph.fBookParticleHistograms[etpcNClsShared] = Alright(lBookParticleHistograms[etpcNClsShared]) && ph.fFillParticleHistograms; + ph.fBookParticleHistograms[eitsChi2NCl] = Alright(lBookParticleHistograms[eitsChi2NCl]) && ph.fFillParticleHistograms; + ph.fBookParticleHistograms[etpcNClsFound] = Alright(lBookParticleHistograms[etpcNClsFound]) && ph.fFillParticleHistograms; + ph.fBookParticleHistograms[etpcNClsCrossedRows] = Alright(lBookParticleHistograms[etpcNClsCrossedRows]) && ph.fFillParticleHistograms; + ph.fBookParticleHistograms[eitsNCls] = Alright(lBookParticleHistograms[eitsNCls]) && ph.fFillParticleHistograms; + ph.fBookParticleHistograms[eitsNClsInnerBarrel] = Alright(lBookParticleHistograms[eitsNClsInnerBarrel]) && ph.fFillParticleHistograms; + ph.fBookParticleHistograms[etpcCrossedRowsOverFindableCls] = Alright(lBookParticleHistograms[etpcCrossedRowsOverFindableCls]) && ph.fFillParticleHistograms; + ph.fBookParticleHistograms[etpcFoundOverFindableCls] = Alright(lBookParticleHistograms[etpcFoundOverFindableCls]) && ph.fFillParticleHistograms; + ph.fBookParticleHistograms[etpcFractionSharedCls] = Alright(lBookParticleHistograms[etpcFractionSharedCls]) && ph.fFillParticleHistograms; + ph.fBookParticleHistograms[etpcChi2NCl] = Alright(lBookParticleHistograms[etpcChi2NCl]) && ph.fFillParticleHistograms; + ph.fBookParticleHistograms[edcaXY] = Alright(lBookParticleHistograms[edcaXY]) && ph.fFillParticleHistograms; + ph.fBookParticleHistograms[edcaZ] = Alright(lBookParticleHistograms[edcaZ]) && ph.fFillParticleHistograms; + ph.fBookParticleHistograms[ePDG] = Alright(lBookParticleHistograms[ePDG]) && ph.fFillParticleHistograms; + // Remark #1: I do not need here anythig for etrackCutFlagFb1, etrackCutFlagFb2, ... eisGlobalTrack, because they are booleans + // Remark #2: Nothing special here for ePtDependentDCAxyParameterization, because that is a string. + + // d) Particle histograms 2D: + // By default all 2D particle histograms are booked. Set this flag to false to switch off booking of all 2D particle histograms: + ph.fFillParticleHistograms2D = cf_ph.cfFillParticleHistograms2D; + + // If you do not want particular 2D particle histogram to be booked, use configurable array cfBookParticleHistograms2D, where you can specify flags 1 (book) or 0 (do not book). + // *) Ordering of the flags in that array is interpreted through ordering of enums in enum eParticleHistograms2D. + auto lBookParticleHistograms2D = cf_ph.cfBookParticleHistograms2D.value; // this is now the local version of that string array from configurable + // TBI 20241113 For some reason, the default values of configurable "cfBookParticleHistograms2D" are not correctly propagated in the local variables, but I can circumvent that with JSON settings for the time being + if (lBookParticleHistograms2D.size() != eParticleHistograms2D_N) { + LOGF(info, "\033[1;31m lBookParticleHistograms2D.size() = %d\033[0m", lBookParticleHistograms2D.size()); + LOGF(info, "\033[1;31m eParticleHistograms2D_N) = %d\033[0m", static_cast(eParticleHistograms2D_N)); + LOGF(fatal, "in function \033[1;31m%s at line %d Mismatch in the number of flags in configurable cfBookParticleHistograms2D, and number of entries in enum eParticleHistograms2D \n \033[0m", __FUNCTION__, __LINE__); + } + + // *) Insanity check on the content and ordering of 2D particle histograms in the initialization in configurable cfBookParticleHistograms2D: + // TBI 20241109 I do not need this in fact, I can automate initialization even without ordering in configurable, but it feels with the ordering enforced, it's much safer. + for (int name = 0; name < eParticleHistograms2D_N; name++) { + // TBI 20241109 I could implement even a strickter EqualTo instead of EndsWith, but then I need to tokenize, etc., etc. This shall be safe enough. + if (!TString(lBookParticleHistograms2D[name]).EndsWith(ph.fParticleHistogramsName2D[name].Data())) { + LOGF(fatal, "\033[1;31m%s at line %d : Wrong content or ordering of contents in configurable cfBookParticleHistograms2D => name = %d, lBookParticleHistograms2D[name] = \"%s\", ph.fParticleHistogramsName2D[name] = \"%s\" \n Check if you are using an up to date tag. \033[0m", __FUNCTION__, __LINE__, name, TString(lBookParticleHistograms2D[name]).Data(), ph.fParticleHistogramsName2D[name].Data()); + } + } + + // I append "&& ph.fFillParticleHistograms2D" below, to switch off booking of all 2D particle histograms with one common flag: + ph.fBookParticleHistograms2D[ePhiPt] = Alright(lBookParticleHistograms2D[ePhiPt]) && ph.fFillParticleHistograms2D; + ph.fBookParticleHistograms2D[ePhiEta] = Alright(lBookParticleHistograms2D[ePhiEta]) && ph.fFillParticleHistograms2D; + + // e) Particle sparse histograms: + auto lRebinSparse = (std::vector)cf_ph.cfRebinSparse; + + ph.fRebinSparse[eDWPhi][wPhiPhiAxis] = lRebinSparse[wPhiPhiAxis]; + ph.fRebinSparse[eDWPhi][wPhiPtAxis] = lRebinSparse[wPhiPtAxis]; + ph.fRebinSparse[eDWPhi][wPhiEtaAxis] = lRebinSparse[wPhiEtaAxis]; + ph.fRebinSparse[eDWPhi][wPhiChargeAxis] = lRebinSparse[wPhiChargeAxis]; + ph.fRebinSparse[eDWPhi][wPhiCentralityAxis] = lRebinSparse[wPhiCentralityAxis]; + ph.fRebinSparse[eDWPhi][wPhiVertexZAxis] = lRebinSparse[wPhiVertexZAxis]; + // ... + + ph.fRebinSparse[eDWPt][wPtPtAxis] = lRebinSparse[wPhiPtAxis]; // yes, wPhiPtAxis is on the RHS, becase I defined ordering of cfRebinSparse by using oredring in eDiffPhiWeights + ph.fRebinSparse[eDWPt][wPtEtaAxis] = lRebinSparse[wPhiEtaAxis]; + ph.fRebinSparse[eDWPt][wPtChargeAxis] = lRebinSparse[wPhiChargeAxis]; + ph.fRebinSparse[eDWPt][wPtCentralityAxis] = lRebinSparse[wPhiCentralityAxis]; + // ... + + ph.fRebinSparse[eDWEta][wEtaEtaAxis] = lRebinSparse[wPhiEtaAxis]; // yes, wPhiEtaAxis is on the RHS, becase I defined ordering of cfRebinSparse by using oredring in eDiffPhiWeights + ph.fRebinSparse[eDWEta][wEtaPtAxis] = lRebinSparse[wPhiPtAxis]; + ph.fRebinSparse[eDWEta][wEtaChargeAxis] = lRebinSparse[wPhiChargeAxis]; + ph.fRebinSparse[eDWEta][wEtaCentralityAxis] = lRebinSparse[wPhiCentralityAxis]; + // ... + + // *) Categories of sparse histograms: + auto lBookParticleSparseHistograms = cf_ph.cfBookParticleSparseHistograms.value; // fill or not particulat category of sparse histograms + if (lBookParticleSparseHistograms.size() != eDiffWeightCategory_N) { + LOGF(info, "\033[1;31m lBookParticleSparseHistograms.size() = %d\033[0m", lBookParticleSparseHistograms.size()); + LOGF(info, "\033[1;31m eDiffWeightCategory_N) = %d\033[0m", static_cast(eDiffWeightCategory_N)); + LOGF(fatal, "in function \033[1;31m%s at line %d Mismatch in the number of flags in configurable cfBookParticleSparseHistograms, and number of entries in enum eDiffWeightCategory_N \n \033[0m", __FUNCTION__, __LINE__); + } + + ph.fFillParticleSparseHistogramsBeforeCuts = cf_ph.cfFillParticleSparseHistogramsBeforeCuts; + + // *) Insanity check on the content and ordering in the initialization in configurable cfBookParticleSparseHistograms: + // TBI 20241109 I do not need this in fact, I can automate initialization even without ordering in configurable, but it feels with the ordering enforced, it's much safer. + // Algorithm: From [01]-DWPhi I tokenize with respect to "-" the 2nd field, and check if e.g. fParticleSparseHistogramsName_DWPhi ends with it. + for (int name = 0; name < eDiffWeightCategory_N; name++) { + TObjArray* oa = TString(lBookParticleSparseHistograms[name]).Tokenize("-"); + if (!oa) { + LOGF(fatal, "\033[1;31m%s at line %d : name = %s\033[0m", __FUNCTION__, __LINE__, TString(lBookParticleSparseHistograms[name]).Data()); + } + if (!ph.fParticleSparseHistogramsName[name].EndsWith(oa->At(1)->GetName())) { + LOGF(fatal, "\033[1;31m%s at line %d : Wrong content or ordering of contents in configurable cfBookParticleSparseHistograms => name = %d, lBookParticleSparseHistograms[name] = \"%s\", ph.fParticleSparseHistogramsName[name] = \"%s\" \n Check if you are using an up to date tag. \033[0m", __FUNCTION__, __LINE__, name, TString(lBookParticleSparseHistograms[name]).Data(), ph.fParticleSparseHistogramsName[name].Data()); + } + delete oa; + } + // Remark: below exceptionally I do not append the common flag with &&, since each of these flags already stands for one category + ph.fBookParticleSparseHistograms[eDWPhi] = Alright(lBookParticleSparseHistograms[eDWPhi]); + ph.fBookParticleSparseHistograms[eDWPt] = Alright(lBookParticleSparseHistograms[eDWPt]); + ph.fBookParticleSparseHistograms[eDWEta] = Alright(lBookParticleSparseHistograms[eDWEta]); + + // f) QA: + + // **) QA 2D event histograms: + qa.fFillQAEventHistograms2D = cf_qa.cfFillQAEventHistograms2D; + + // *) If you do not want particular 2D event histogram to be booked, use configurable array cfBookQAEventHistograms2D, where you can specify flags 1 (book) or 0 (do not book). + // Ordering of the flags in that array is interpreted through ordering of enums in enum eQAEventHistograms2D + auto lBookQAEventHistograms2D = cf_qa.cfBookQAEventHistograms2D.value; // this is now the local version of that string array from configurable + // TBI 20241115 For some reason, the default values of configurable "cfBookQAEventHistograms2D" are not correctly propagated in the local variables, but I can circumvent that with JSON settings for the time being + if (lBookQAEventHistograms2D.size() != eQAEventHistograms2D_N) { + LOGF(info, "\033[1;31m lBookQAEventHistograms2D.size() = %d\033[0m", lBookQAEventHistograms2D.size()); + LOGF(info, "\033[1;31m eQAEventHistograms2D_N = %d\033[0m", static_cast(eQAEventHistograms2D_N)); + LOGF(fatal, "in function \033[1;31m%s at line %d Mismatch in the number of flags in configurable cfBookQAEventHistograms2D, and number of entries in enum eQAEventHistograms2D \n \033[0m", __FUNCTION__, __LINE__); + } + + // *) Insanity check on the content and ordering of QA 2D event histograms in the initialization in configurable cfBookQAEventHistograms2D: + // TBI 20240518 I do not need this in fact, I can automate initialization even without ordering in configurable, but it feels with the ordering enforced, it's much safer. + for (int name = 0; name < eQAEventHistograms2D_N; name++) { + // TBI 20240518 I could implement even a strickter EqualTo instead of EndsWith, but then I need to tokenize, etc., etc. This shall be safe enough. + if (!TString(lBookQAEventHistograms2D[name]).EndsWith(qa.fEventHistogramsName2D[name].Data())) { + LOGF(fatal, "\033[1;31m%s at line %d : Wrong content or ordering of contents in configurable cfBookQAEventHistograms2D => name = %d, lBookQAEventHistograms2D[name] = \"%s\", qa.fEventHistogramsName2D[name] = \"%s\" \n Check if you are using an up to date tag. \033[0m", __FUNCTION__, __LINE__, name, TString(lBookQAEventHistograms2D[name]).Data(), qa.fEventHistogramsName2D[name].Data()); + } + } + + // I append "&& qa.fFillQAEventHistograms2D" below, to switch off booking of all 2D event histograms with one common flag: + qa.fBookQAEventHistograms2D[eMultiplicity_vs_ReferenceMultiplicity] = Alright(lBookQAEventHistograms2D[eMultiplicity_vs_ReferenceMultiplicity]) && qa.fFillQAEventHistograms2D; + qa.fBookQAEventHistograms2D[eMultiplicity_vs_NContributors] = Alright(lBookQAEventHistograms2D[eMultiplicity_vs_NContributors]) && qa.fFillQAEventHistograms2D; + qa.fBookQAEventHistograms2D[eMultiplicity_vs_Centrality] = Alright(lBookQAEventHistograms2D[eMultiplicity_vs_Centrality]) && qa.fFillQAEventHistograms2D; + qa.fBookQAEventHistograms2D[eMultiplicity_vs_VertexZ] = Alright(lBookQAEventHistograms2D[eMultiplicity_vs_VertexZ]) && qa.fFillQAEventHistograms2D; + qa.fBookQAEventHistograms2D[eMultiplicity_vs_Occupancy] = Alright(lBookQAEventHistograms2D[eMultiplicity_vs_Occupancy]) && qa.fFillQAEventHistograms2D; + qa.fBookQAEventHistograms2D[eMultiplicity_vs_InteractionRate] = Alright(lBookQAEventHistograms2D[eMultiplicity_vs_InteractionRate]) && qa.fFillQAEventHistograms2D; + qa.fBookQAEventHistograms2D[eReferenceMultiplicity_vs_NContributors] = Alright(lBookQAEventHistograms2D[eReferenceMultiplicity_vs_NContributors]) && qa.fFillQAEventHistograms2D; + qa.fBookQAEventHistograms2D[eReferenceMultiplicity_vs_Centrality] = Alright(lBookQAEventHistograms2D[eReferenceMultiplicity_vs_Centrality]) && qa.fFillQAEventHistograms2D; + qa.fBookQAEventHistograms2D[eReferenceMultiplicity_vs_VertexZ] = Alright(lBookQAEventHistograms2D[eReferenceMultiplicity_vs_VertexZ]) && qa.fFillQAEventHistograms2D; + qa.fBookQAEventHistograms2D[eReferenceMultiplicity_vs_Occupancy] = Alright(lBookQAEventHistograms2D[eReferenceMultiplicity_vs_Occupancy]) && qa.fFillQAEventHistograms2D; + qa.fBookQAEventHistograms2D[eReferenceMultiplicity_vs_InteractionRate] = Alright(lBookQAEventHistograms2D[eReferenceMultiplicity_vs_InteractionRate]) && qa.fFillQAEventHistograms2D; + qa.fBookQAEventHistograms2D[eNContributors_vs_Centrality] = Alright(lBookQAEventHistograms2D[eNContributors_vs_Centrality]) && qa.fFillQAEventHistograms2D; + qa.fBookQAEventHistograms2D[eNContributors_vs_VertexZ] = Alright(lBookQAEventHistograms2D[eNContributors_vs_VertexZ]) && qa.fFillQAEventHistograms2D; + qa.fBookQAEventHistograms2D[eNContributors_vs_Occupancy] = Alright(lBookQAEventHistograms2D[eNContributors_vs_Occupancy]) && qa.fFillQAEventHistograms2D; + qa.fBookQAEventHistograms2D[eNContributors_vs_InteractionRate] = Alright(lBookQAEventHistograms2D[eNContributors_vs_InteractionRate]) && qa.fFillQAEventHistograms2D; + qa.fBookQAEventHistograms2D[eCentrality_vs_VertexZ] = Alright(lBookQAEventHistograms2D[eCentrality_vs_VertexZ]) && qa.fFillQAEventHistograms2D; + qa.fBookQAEventHistograms2D[eCentrality_vs_Occupancy] = Alright(lBookQAEventHistograms2D[eCentrality_vs_Occupancy]) && qa.fFillQAEventHistograms2D; + qa.fBookQAEventHistograms2D[eCentrality_vs_ImpactParameter] = Alright(lBookQAEventHistograms2D[eCentrality_vs_ImpactParameter]) && qa.fFillQAEventHistograms2D; + qa.fBookQAEventHistograms2D[eCentrality_vs_InteractionRate] = Alright(lBookQAEventHistograms2D[eCentrality_vs_InteractionRate]) && qa.fFillQAEventHistograms2D; + qa.fBookQAEventHistograms2D[eVertexZ_vs_Occupancy] = Alright(lBookQAEventHistograms2D[eVertexZ_vs_Occupancy]) && qa.fFillQAEventHistograms2D; + qa.fBookQAEventHistograms2D[eVertexZ_vs_InteractionRate] = Alright(lBookQAEventHistograms2D[eVertexZ_vs_InteractionRate]) && qa.fFillQAEventHistograms2D; + qa.fBookQAEventHistograms2D[eMultiplicity_vs_FT0CAmplitudeOnFoundBC] = Alright(lBookQAEventHistograms2D[eMultiplicity_vs_FT0CAmplitudeOnFoundBC]) && qa.fFillQAEventHistograms2D; + qa.fBookQAEventHistograms2D[eCentFT0C_vs_FT0CAmplitudeOnFoundBC] = Alright(lBookQAEventHistograms2D[eCentFT0C_vs_FT0CAmplitudeOnFoundBC]) && qa.fFillQAEventHistograms2D; + qa.fBookQAEventHistograms2D[eCentrality_vs_CentralitySim] = Alright(lBookQAEventHistograms2D[eCentrality_vs_CentralitySim]) && qa.fFillQAEventHistograms2D; + qa.fBookQAEventHistograms2D[eMultNTracksPV_vs_MultNTracksGlobal] = Alright(lBookQAEventHistograms2D[eMultNTracksPV_vs_MultNTracksGlobal]) && qa.fFillQAEventHistograms2D; + qa.fBookQAEventHistograms2D[eCentFT0C_vs_CentFT0CVariant1] = Alright(lBookQAEventHistograms2D[eCentFT0C_vs_CentFT0CVariant1]) && qa.fFillQAEventHistograms2D; + qa.fBookQAEventHistograms2D[eCentFT0C_vs_CentFT0M] = Alright(lBookQAEventHistograms2D[eCentFT0C_vs_CentFT0M]) && qa.fFillQAEventHistograms2D; + qa.fBookQAEventHistograms2D[eCentFT0C_vs_CentFV0A] = Alright(lBookQAEventHistograms2D[eCentFT0C_vs_CentFV0A]) && qa.fFillQAEventHistograms2D; + qa.fBookQAEventHistograms2D[eCentFT0C_vs_CentNTPV] = Alright(lBookQAEventHistograms2D[eCentFT0C_vs_CentNTPV]) && qa.fFillQAEventHistograms2D; + qa.fBookQAEventHistograms2D[eCentFT0C_vs_CentNGlobal] = Alright(lBookQAEventHistograms2D[eCentFT0C_vs_CentNGlobal]) && qa.fFillQAEventHistograms2D; + qa.fBookQAEventHistograms2D[eCentFT0M_vs_CentNTPV] = Alright(lBookQAEventHistograms2D[eCentFT0M_vs_CentNTPV]) && qa.fFillQAEventHistograms2D; + qa.fBookQAEventHistograms2D[eCentRun2V0M_vs_CentRun2SPDTracklets] = Alright(lBookQAEventHistograms2D[eCentRun2V0M_vs_CentRun2SPDTracklets]) && qa.fFillQAEventHistograms2D; + qa.fBookQAEventHistograms2D[eTrackOccupancyInTimeRange_vs_FT0COccupancyInTimeRange] = Alright(lBookQAEventHistograms2D[eTrackOccupancyInTimeRange_vs_FT0COccupancyInTimeRange]) && qa.fFillQAEventHistograms2D; + qa.fBookQAEventHistograms2D[eCurrentRunDuration_vs_InteractionRate] = Alright(lBookQAEventHistograms2D[eCurrentRunDuration_vs_InteractionRate]) && qa.fFillQAEventHistograms2D; + + // **) QA 2D particle histograms: + qa.fFillQAParticleHistograms2D = cf_qa.cfFillQAParticleHistograms2D; + + // *) If you do not want particular 2D particle histogram to be booked, use configurable array cfBookQAParticleHistograms2D, where you can specify flags 1 (book) or 0 (do not book). + // Ordering of the flags in that array is interpreted through ordering of enums in enum eQAParticleHistograms2D. + auto lBookQAParticleHistograms2D = cf_qa.cfBookQAParticleHistograms2D.value; // this is now the local version of that string array from configurable + if (lBookQAParticleHistograms2D.size() != eQAParticleHistograms2D_N) { + LOGF(info, "\033[1;31m lBookQAParticleHistograms2D.size() = %d\033[0m", lBookQAParticleHistograms2D.size()); + LOGF(info, "\033[1;31m eQAParticleHistograms2D_N = %d\033[0m", static_cast(eQAParticleHistograms2D_N)); + LOGF(fatal, "in function \033[1;31m%s at line %d Mismatch in the number of flags in configurable cfBookQAParticleHistograms2D, and number of entries in enum eParticleHistograms2D \n \033[0m", __FUNCTION__, __LINE__); + } + + // *) Insanity check on the content and ordering of QA 2D particle histograms in the initialization in configurable cfBookQAParticleHistograms2D: + // TBI 20240518 I do not need this in fact, I can automate initialization even without ordering in configurable, but it feels with the ordering enforced, it's much safer. + for (int name = 0; name < eQAParticleHistograms2D_N; name++) { + // TBI 20240518 I could implement even a strickter EqualTo instead of EndsWith, but then I need to tokenize, etc., etc. This shall be safe enough. + if (!TString(lBookQAParticleHistograms2D[name]).EndsWith(qa.fParticleHistogramsName2D[name].Data())) { + LOGF(fatal, "\033[1;31m%s at line %d : Wrong content or ordering of contents in configurable cfBookQAParticleHistograms2D => name = %d, lBookQAParticleHistograms2D[name] = \"%s\", qa.fParticleHistogramsName2D[name] = \"%s\" \n Check if you are using an up to date tag. \033[0m", __FUNCTION__, __LINE__, name, TString(lBookQAParticleHistograms2D[name]).Data(), qa.fParticleHistogramsName2D[name].Data()); + } + } + + // I append "&& qa.fFillQAParticleHistograms2D" below, to switch off booking of all 2D particle histograms with one common flag: + qa.fBookQAParticleHistograms2D[ePt_vs_dcaXY] = Alright(lBookQAParticleHistograms2D[ePt_vs_dcaXY]) && qa.fFillQAParticleHistograms2D; + + // **) QA 2D particle event histograms: + qa.fFillQAParticleEventHistograms2D = cf_qa.cfFillQAParticleEventHistograms2D; + + // *) If you do not want particular 2D particle event histogram to be booked, use configurable array cfBookQAParticleEventHistograms2D, where you can specify flags 1 (book) or 0 (do not book). + // Ordering of the flags in that array is interpreted through ordering of enums in enum eQAParticleEventHistograms2D. + auto lBookQAParticleEventHistograms2D = cf_qa.cfBookQAParticleEventHistograms2D.value; // this is now the local version of that string array from configurable + if (lBookQAParticleEventHistograms2D.size() != eQAParticleEventHistograms2D_N) { + LOGF(info, "\033[1;31m lBookQAParticleEventHistograms2D.size() = %d\033[0m", lBookQAParticleEventHistograms2D.size()); + LOGF(info, "\033[1;31m eQAParticleEventHistograms2D_N = %d\033[0m", static_cast(eQAParticleEventHistograms2D_N)); + LOGF(fatal, "in function \033[1;31m%s at line %d Mismatch in the number of flags in configurable cfBookQAParticleEventHistograms2D, and number of entries in enum eParticleEventHistograms2D \n \033[0m", __FUNCTION__, __LINE__); + } + + // *) Insanity check on the content and ordering of QA 2D particle event histograms in the initialization in configurable cfBookQAParticleEventHistograms2D: + // TBI 20240518 I do not need this in fact, I can automate initialization even without ordering in configurable, but it feels with the ordering enforced, it's much safer. + for (int name = 0; name < eQAParticleEventHistograms2D_N; name++) { + // TBI 20240518 I could implement even a strickter EqualTo instead of EndsWith, but then I need to tokenize, etc., etc. This shall be safe enough. + if (!TString(lBookQAParticleEventHistograms2D[name]).EndsWith(qa.fQAParticleEventHistogramsName2D[name].Data())) { + LOGF(fatal, "\033[1;31m%s at line %d : Wrong content or ordering of contents in configurable cfBookQAParticleEventHistograms2D => name = %d, lBookQAParticleEventHistograms2D[name] = \"%s\", qa.fParticleEventHistogramsName2D[name] = \"%s\" \n Check if you are using an up to date tag. \033[0m", __FUNCTION__, __LINE__, name, TString(lBookQAParticleEventHistograms2D[name]).Data(), qa.fQAParticleEventHistogramsName2D[name].Data()); + } + } + + // I append "&& qa.fFillQAParticleEventHistograms2D" below, to switch off booking of all 2D particle event histograms with one common flag: + qa.fBookQAParticleEventHistograms2D[eCurrentRunDuration_vs_itsNClsEbyE] = Alright(lBookQAParticleEventHistograms2D[eCurrentRunDuration_vs_itsNClsEbyE]) && qa.fFillQAParticleEventHistograms2D; + qa.fBookQAParticleEventHistograms2D[eCurrentRunDuration_vs_itsNClsNegEtaEbyE] = Alright(lBookQAParticleEventHistograms2D[eCurrentRunDuration_vs_itsNClsNegEtaEbyE]) && qa.fFillQAParticleEventHistograms2D; + qa.fBookQAParticleEventHistograms2D[eCurrentRunDuration_vs_itsNClsPosEtaEbyE] = Alright(lBookQAParticleEventHistograms2D[eCurrentRunDuration_vs_itsNClsPosEtaEbyE]) && qa.fFillQAParticleEventHistograms2D; + qa.fBookQAParticleEventHistograms2D[eCurrentRunDuration_vs_Eta0804EbyE] = Alright(lBookQAParticleEventHistograms2D[eCurrentRunDuration_vs_Eta0804EbyE]) && qa.fFillQAParticleEventHistograms2D; + qa.fBookQAParticleEventHistograms2D[eCurrentRunDuration_vs_Eta0400EbyE] = Alright(lBookQAParticleEventHistograms2D[eCurrentRunDuration_vs_Eta0400EbyE]) && qa.fFillQAParticleEventHistograms2D; + qa.fBookQAParticleEventHistograms2D[eCurrentRunDuration_vs_Eta0004EbyE] = Alright(lBookQAParticleEventHistograms2D[eCurrentRunDuration_vs_Eta0004EbyE]) && qa.fFillQAParticleEventHistograms2D; + qa.fBookQAParticleEventHistograms2D[eCurrentRunDuration_vs_Eta0408EbyE] = Alright(lBookQAParticleEventHistograms2D[eCurrentRunDuration_vs_Eta0408EbyE]) && qa.fFillQAParticleEventHistograms2D; + qa.fBookQAParticleEventHistograms2D[eCurrentRunDuration_vs_Pt0005EbyE] = Alright(lBookQAParticleEventHistograms2D[eCurrentRunDuration_vs_Pt0005EbyE]) && qa.fFillQAParticleEventHistograms2D; + qa.fBookQAParticleEventHistograms2D[eCurrentRunDuration_vs_Pt0510EbyE] = Alright(lBookQAParticleEventHistograms2D[eCurrentRunDuration_vs_Pt0510EbyE]) && qa.fFillQAParticleEventHistograms2D; + qa.fBookQAParticleEventHistograms2D[eCurrentRunDuration_vs_Pt1050EbyE] = Alright(lBookQAParticleEventHistograms2D[eCurrentRunDuration_vs_Pt1050EbyE]) && qa.fFillQAParticleEventHistograms2D; + + // **) QA 2D "correlations vs." histograms: + qa.fFillQACorrelationsVsHistograms2D = cf_qa.cfFillQACorrelationsVsHistograms2D; + + // *) If you do not want particular 2D "correlations vs." histogram to be booked, use configurable array cfBookQACorrelationsVsHistograms2D, where you can specify flags 1 (book) or 0 (do not book). + // Ordering of the flags in that array is interpreted through ordering of enums in enum eQACorrelationsVsHistograms2D. + auto lBookQACorrelationsVsHistograms2D = cf_qa.cfBookQACorrelationsVsHistograms2D.value; // this is now the local version of that string array from configurable + if (lBookQACorrelationsVsHistograms2D.size() != eQACorrelationsVsHistograms2D_N) { + LOGF(info, "\033[1;31m lBookQACorrelationsVsHistograms2D.size() = %d\033[0m", lBookQACorrelationsVsHistograms2D.size()); + LOGF(info, "\033[1;31m eQACorrelationsVsHistograms2D_N = %d\033[0m", static_cast(eQACorrelationsVsHistograms2D_N)); + LOGF(fatal, "in function \033[1;31m%s at line %d Mismatch in the number of flags in configurable cfBookQACorrelationsVsHistograms2D, and number of entries in enum eCorrelationsVsHistograms2D \n \033[0m", __FUNCTION__, __LINE__); + } + + // *) Insanity check on the content and ordering of QA 2D "correlations vs." histograms in the initialization in configurable cfBookQACorrelationsVsHistograms2D: + // TBI 20240518 I do not need this in fact, I can automate initialization even without ordering in configurable, but it feels with the ordering enforced, it's much safer. + for (int name = 0; name < eQACorrelationsVsHistograms2D_N; name++) { + // TBI 20240518 I could implement even a strickter EqualTo instead of EndsWith, but then I need to tokenize, etc., etc. This shall be safe enough. + if (!TString(lBookQACorrelationsVsHistograms2D[name]).EndsWith(qa.fQACorrelationsVsHistogramsName2D[name].Data())) { + LOGF(fatal, "\033[1;31m%s at line %d : Wrong content or ordering of contents in configurable cfBookQACorrelationsVsHistograms2D => name = %d, lBookQACorrelationsVsHistograms2D[name] = \"%s\", qa.fCorrelationsVsHistogramsName2D[name] = \"%s\" \n Check if you are using an up to date tag. \033[0m", __FUNCTION__, __LINE__, name, TString(lBookQACorrelationsVsHistograms2D[name]).Data(), qa.fQACorrelationsVsHistogramsName2D[name].Data()); + } + } + + // I append "&& qa.fFillQACorrelationsVsHistograms2D" below, to switch off booking of all 2D "correlations vs." histograms with one common flag: + qa.fBookQACorrelationsVsHistograms2D[eCorrelations_vs_Multiplicity] = Alright(lBookQACorrelationsVsHistograms2D[eCorrelations_vs_Multiplicity]) && qa.fFillQACorrelationsVsHistograms2D; + qa.fBookQACorrelationsVsHistograms2D[eCorrelations_vs_ReferenceMultiplicity] = Alright(lBookQACorrelationsVsHistograms2D[eCorrelations_vs_ReferenceMultiplicity]) && qa.fFillQACorrelationsVsHistograms2D; + qa.fBookQACorrelationsVsHistograms2D[eCorrelations_vs_Centrality] = Alright(lBookQACorrelationsVsHistograms2D[eCorrelations_vs_Centrality]) && qa.fFillQACorrelationsVsHistograms2D; + // ..... + qa.fBookQACorrelationsVsHistograms2D[eCorrelations_vs_MeanPhi] = Alright(lBookQACorrelationsVsHistograms2D[eCorrelations_vs_MeanPhi]) && qa.fFillQACorrelationsVsHistograms2D; + qa.fBookQACorrelationsVsHistograms2D[eCorrelations_vs_MeanPt] = Alright(lBookQACorrelationsVsHistograms2D[eCorrelations_vs_MeanPt]) && qa.fFillQACorrelationsVsHistograms2D; + qa.fBookQACorrelationsVsHistograms2D[eCorrelations_vs_MeanEta] = Alright(lBookQACorrelationsVsHistograms2D[eCorrelations_vs_MeanEta]) && qa.fFillQACorrelationsVsHistograms2D; + qa.fBookQACorrelationsVsHistograms2D[eCorrelations_vs_MeanCharge] = Alright(lBookQACorrelationsVsHistograms2D[eCorrelations_vs_MeanCharge]) && qa.fFillQACorrelationsVsHistograms2D; + qa.fBookQACorrelationsVsHistograms2D[eCorrelations_vs_MeantpcNClsFindable] = Alright(lBookQACorrelationsVsHistograms2D[eCorrelations_vs_MeantpcNClsFindable]) && qa.fFillQACorrelationsVsHistograms2D; + qa.fBookQACorrelationsVsHistograms2D[eCorrelations_vs_MeantpcNClsShared] = Alright(lBookQACorrelationsVsHistograms2D[eCorrelations_vs_MeantpcNClsShared]) && qa.fFillQACorrelationsVsHistograms2D; + qa.fBookQACorrelationsVsHistograms2D[eCorrelations_vs_MeanitsChi2NCl] = Alright(lBookQACorrelationsVsHistograms2D[eCorrelations_vs_MeanitsChi2NCl]) && qa.fFillQACorrelationsVsHistograms2D; + qa.fBookQACorrelationsVsHistograms2D[eCorrelations_vs_MeantpcNClsFound] = Alright(lBookQACorrelationsVsHistograms2D[eCorrelations_vs_MeantpcNClsFound]) && qa.fFillQACorrelationsVsHistograms2D; + qa.fBookQACorrelationsVsHistograms2D[eCorrelations_vs_MeantpcNClsCrossedRows] = Alright(lBookQACorrelationsVsHistograms2D[eCorrelations_vs_MeantpcNClsCrossedRows]) && qa.fFillQACorrelationsVsHistograms2D; + qa.fBookQACorrelationsVsHistograms2D[eCorrelations_vs_MeanitsNCls] = Alright(lBookQACorrelationsVsHistograms2D[eCorrelations_vs_MeanitsNCls]) && qa.fFillQACorrelationsVsHistograms2D; + qa.fBookQACorrelationsVsHistograms2D[eCorrelations_vs_MeanitsNClsInnerBarrel] = Alright(lBookQACorrelationsVsHistograms2D[eCorrelations_vs_MeanitsNClsInnerBarrel]) && qa.fFillQACorrelationsVsHistograms2D; + qa.fBookQACorrelationsVsHistograms2D[eCorrelations_vs_MeantpcCrossedRowsOverFindableCls] = Alright(lBookQACorrelationsVsHistograms2D[eCorrelations_vs_MeantpcCrossedRowsOverFindableCls]) && qa.fFillQACorrelationsVsHistograms2D; + qa.fBookQACorrelationsVsHistograms2D[eCorrelations_vs_MeantpcFoundOverFindableCls] = Alright(lBookQACorrelationsVsHistograms2D[eCorrelations_vs_MeantpcFoundOverFindableCls]) && qa.fFillQACorrelationsVsHistograms2D; + qa.fBookQACorrelationsVsHistograms2D[eCorrelations_vs_MeantpcFractionSharedCls] = Alright(lBookQACorrelationsVsHistograms2D[eCorrelations_vs_MeantpcFractionSharedCls]) && qa.fFillQACorrelationsVsHistograms2D; + qa.fBookQACorrelationsVsHistograms2D[eCorrelations_vs_MeantpcChi2NCl] = Alright(lBookQACorrelationsVsHistograms2D[eCorrelations_vs_MeantpcChi2NCl]) && qa.fFillQACorrelationsVsHistograms2D; + qa.fBookQACorrelationsVsHistograms2D[eCorrelations_vs_MeandcaXY] = Alright(lBookQACorrelationsVsHistograms2D[eCorrelations_vs_MeandcaXY]) && qa.fFillQACorrelationsVsHistograms2D; + qa.fBookQACorrelationsVsHistograms2D[eCorrelations_vs_MeandcaZ] = Alright(lBookQACorrelationsVsHistograms2D[eCorrelations_vs_MeandcaZ]) && qa.fFillQACorrelationsVsHistograms2D; + // ..... + + // *) min and max harmonics for which this series of histograms will be booked: + auto lQACorrelationsVsHistogramsMinMaxHarmonic = cf_qa.cfQACorrelationsVsHistogramsMinMaxHarmonic.value; + qa.fQACorrelationsVsHistogramsMinMaxHarmonic[eMin] = lQACorrelationsVsHistogramsMinMaxHarmonic[eMin]; + qa.fQACorrelationsVsHistogramsMinMaxHarmonic[eMax] = lQACorrelationsVsHistogramsMinMaxHarmonic[eMax]; + // **) insanity check: + if (!(qa.fQACorrelationsVsHistogramsMinMaxHarmonic[eMin] <= qa.fQACorrelationsVsHistogramsMinMaxHarmonic[eMax])) { + LOGF(fatal, "\033[1;31m%s at line %d : wrong setting for min and max harmonics: min = %d, max = %d \033[0m", __FUNCTION__, __LINE__, qa.fQACorrelationsVsHistogramsMinMaxHarmonic[eMin], qa.fQACorrelationsVsHistogramsMinMaxHarmonic[eMax]); + } + + // **) QA 2D "correlations vs. IR vs. " profiles: + qa.fFillQACorrelationsVsInteractionRateVsProfiles2D = cf_qa.cfFillQACorrelationsVsInteractionRateVsProfiles2D; + + // *) If you do not want particular 2D correlations vs. IR vs. " profile to be booked, use configurable array cfBookQACorrelationsVsInteractionRateVsProfiles2D, where you can specify flags 1 (book) or 0 (do not book). + // Ordering of the flags in that array is interpreted through ordering of enums in enum eQACorrelationsVsInteractionRateVsProfiles2D. + auto lBookQACorrelationsVsInteractionRateVsProfiles2D = cf_qa.cfBookQACorrelationsVsInteractionRateVsProfiles2D.value; // this is now the local version of that string array from configurable + if (lBookQACorrelationsVsInteractionRateVsProfiles2D.size() != eQACorrelationsVsInteractionRateVsProfiles2D_N) { + LOGF(info, "\033[1;31m lBookQACorrelationsVsInteractionRateVsProfiles2D.size() = %d\033[0m", lBookQACorrelationsVsInteractionRateVsProfiles2D.size()); + LOGF(info, "\033[1;31m eQACorrelationsVsInteractionRateVsProfiles2D_N = %d\033[0m", static_cast(eQACorrelationsVsInteractionRateVsProfiles2D_N)); + LOGF(fatal, "in function \033[1;31m%s at line %d Mismatch in the number of flags in configurable cfBookQACorrelationsVsInteractionRateVsProfiles2D, and number of entries in enum eCorrelationsVsInteractionRateVsProfiles2D \n \033[0m", __FUNCTION__, __LINE__); + } + + // *) Insanity check on the content and ordering of QA 2D "correlations vs. IR vs. " profiles in the initialization in configurable cfBookQACorrelationsVsInteractionRateVsProfiles2D: + // TBI 20240518 I do not need this in fact, I can automate initialization even without ordering in configurable, but it feels with the ordering enforced, it's much safer. + for (int name = 0; name < eQACorrelationsVsInteractionRateVsProfiles2D_N; name++) { + // TBI 20240518 I could implement even a strickter EqualTo instead of EndsWith, but then I need to tokenize, etc., etc. This shall be safe enough. + if (!TString(lBookQACorrelationsVsInteractionRateVsProfiles2D[name]).EndsWith(qa.fQACorrelationsVsInteractionRateVsProfilesName2D[name].Data())) { + LOGF(fatal, "\033[1;31m%s at line %d : Wrong content or ordering of contents in configurable cfBookQACorrelationsVsInteractionRateVsProfiles2D => name = %d, lBookQACorrelationsVsInteractionRateVsProfiles2D[name] = \"%s\", qa.fCorrelationsVsInteractionRateVsProfilesName2D[name] = \"%s\" \n Check if you are using an up to date tag. \033[0m", __FUNCTION__, __LINE__, name, TString(lBookQACorrelationsVsInteractionRateVsProfiles2D[name]).Data(), qa.fQACorrelationsVsInteractionRateVsProfilesName2D[name].Data()); + } + } + + // I append "&& qa.fFillQACorrelationsVsInteractionRateVsProfiles2D" below, to switch off booking of all 2D "correlations vs. IR vs. " profiles with one common flag: + qa.fBookQACorrelationsVsInteractionRateVsProfiles2D[eCorrelationsVsInteractionRate_vs_CurrentRunDuration] = Alright(lBookQACorrelationsVsInteractionRateVsProfiles2D[eCorrelationsVsInteractionRate_vs_CurrentRunDuration]) && qa.fFillQACorrelationsVsInteractionRateVsProfiles2D; + qa.fBookQACorrelationsVsInteractionRateVsProfiles2D[eCorrelationsVsInteractionRate_vs_Multiplicity] = Alright(lBookQACorrelationsVsInteractionRateVsProfiles2D[eCorrelationsVsInteractionRate_vs_Multiplicity]) && qa.fFillQACorrelationsVsInteractionRateVsProfiles2D; + qa.fBookQACorrelationsVsInteractionRateVsProfiles2D[eCorrelationsVsInteractionRate_vs_ReferenceMultiplicity] = Alright(lBookQACorrelationsVsInteractionRateVsProfiles2D[eCorrelationsVsInteractionRate_vs_ReferenceMultiplicity]) && qa.fFillQACorrelationsVsInteractionRateVsProfiles2D; + qa.fBookQACorrelationsVsInteractionRateVsProfiles2D[eCorrelationsVsInteractionRate_vs_Centrality] = Alright(lBookQACorrelationsVsInteractionRateVsProfiles2D[eCorrelationsVsInteractionRate_vs_Centrality]) && qa.fFillQACorrelationsVsInteractionRateVsProfiles2D; + // ..... + qa.fBookQACorrelationsVsInteractionRateVsProfiles2D[eCorrelationsVsInteractionRate_vs_MeanPhi] = Alright(lBookQACorrelationsVsInteractionRateVsProfiles2D[eCorrelationsVsInteractionRate_vs_MeanPhi]) && qa.fFillQACorrelationsVsInteractionRateVsProfiles2D; + qa.fBookQACorrelationsVsInteractionRateVsProfiles2D[eCorrelationsVsInteractionRate_vs_SigmaMeanPhi] = Alright(lBookQACorrelationsVsInteractionRateVsProfiles2D[eCorrelationsVsInteractionRate_vs_SigmaMeanPhi]) && qa.fFillQACorrelationsVsInteractionRateVsProfiles2D; + qa.fBookQACorrelationsVsInteractionRateVsProfiles2D[eCorrelationsVsInteractionRate_vs_MeanPt] = Alright(lBookQACorrelationsVsInteractionRateVsProfiles2D[eCorrelationsVsInteractionRate_vs_MeanPt]) && qa.fFillQACorrelationsVsInteractionRateVsProfiles2D; + qa.fBookQACorrelationsVsInteractionRateVsProfiles2D[eCorrelationsVsInteractionRate_vs_SigmaMeanPt] = Alright(lBookQACorrelationsVsInteractionRateVsProfiles2D[eCorrelationsVsInteractionRate_vs_SigmaMeanPt]) && qa.fFillQACorrelationsVsInteractionRateVsProfiles2D; + qa.fBookQACorrelationsVsInteractionRateVsProfiles2D[eCorrelationsVsInteractionRate_vs_MeanEta] = Alright(lBookQACorrelationsVsInteractionRateVsProfiles2D[eCorrelationsVsInteractionRate_vs_MeanEta]) && qa.fFillQACorrelationsVsInteractionRateVsProfiles2D; + qa.fBookQACorrelationsVsInteractionRateVsProfiles2D[eCorrelationsVsInteractionRate_vs_SigmaMeanEta] = Alright(lBookQACorrelationsVsInteractionRateVsProfiles2D[eCorrelationsVsInteractionRate_vs_SigmaMeanEta]) && qa.fFillQACorrelationsVsInteractionRateVsProfiles2D; + + // ..... + + // *) min and max harmonics for which this series of histograms will be booked: + auto lQACorrelationsVsInteractionRateVsProfilesMinMaxHarmonic = cf_qa.cfQACorrelationsVsInteractionRateVsProfilesMinMaxHarmonic.value; + qa.fQACorrelationsVsInteractionRateVsProfilesMinMaxHarmonic[eMin] = lQACorrelationsVsInteractionRateVsProfilesMinMaxHarmonic[eMin]; + qa.fQACorrelationsVsInteractionRateVsProfilesMinMaxHarmonic[eMax] = lQACorrelationsVsInteractionRateVsProfilesMinMaxHarmonic[eMax]; + // **) insanity check: + if (!(qa.fQACorrelationsVsInteractionRateVsProfilesMinMaxHarmonic[eMin] < qa.fQACorrelationsVsInteractionRateVsProfilesMinMaxHarmonic[eMax])) { + LOGF(fatal, "\033[1;31m%s at line %d : wrong setting for min and max harmonics: min = %d, max = %d \033[0m", __FUNCTION__, __LINE__, qa.fQACorrelationsVsInteractionRateVsProfilesMinMaxHarmonic[eMin], qa.fQACorrelationsVsInteractionRateVsProfilesMinMaxHarmonic[eMax]); + } + + // ... + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // void defaultBooking() + + //============================================================ + + void defaultBinning() + { + // Default binning for all histograms. + + // TBI 20240114 If some of these values are going to change frequently, add support for them in MuPa-Configurables.h, + // in the same way I did it for defaultCuts(). + // TBI 20260223 If ever I will add also support for variable-length binning for control histograms, re-think first what I did in the + // booking of sparse histograms, because the code there hinges on the usage of fixed-length binning and the usage of + // configurable cfRebinSparse. But I doubt I will even need here variable-length binning, I have always rebin in such a way + // all control histograms in offline postprocessing. + + // a) Default binning for event histograms; + // b) Default binning for particle histograms 1D; + // c) Default binning for particle histograms 2D; + // d) Default binning for results histograms; + // e) Variable-length binning for results histograms set via MuPa-Configurables.h. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // a) Default binning for event histograms: + eh.fEventHistogramsBins[eNumberOfEvents][0] = 1; + eh.fEventHistogramsBins[eNumberOfEvents][1] = 0.; + eh.fEventHistogramsBins[eNumberOfEvents][2] = 1.; + + eh.fEventHistogramsBins[eTotalMultiplicity][0] = 10000.; + eh.fEventHistogramsBins[eTotalMultiplicity][1] = 0.; + eh.fEventHistogramsBins[eTotalMultiplicity][2] = 100000.; + + eh.fEventHistogramsBins[eMultiplicity][0] = 500.; + eh.fEventHistogramsBins[eMultiplicity][1] = 0.; + eh.fEventHistogramsBins[eMultiplicity][2] = 5000.; + + eh.fEventHistogramsBins[eReferenceMultiplicity][0] = 700.; // bin width is 100 + eh.fEventHistogramsBins[eReferenceMultiplicity][1] = 0.; + eh.fEventHistogramsBins[eReferenceMultiplicity][2] = 70000.; + + eh.fEventHistogramsBins[eCentrality][0] = 110; // intentionally, because if centrality is not determined, it's set to 105.0 at the moment + eh.fEventHistogramsBins[eCentrality][1] = 0.; + eh.fEventHistogramsBins[eCentrality][2] = 110.; + + eh.fEventHistogramsBins[eVertexX][0] = 1600; + eh.fEventHistogramsBins[eVertexX][1] = -0.8; + eh.fEventHistogramsBins[eVertexX][2] = 0.8; + + eh.fEventHistogramsBins[eVertexY][0] = 1600; + eh.fEventHistogramsBins[eVertexY][1] = -0.8; + eh.fEventHistogramsBins[eVertexY][2] = 0.8; + + eh.fEventHistogramsBins[eVertexZ][0] = 800; + eh.fEventHistogramsBins[eVertexZ][1] = -40.; + eh.fEventHistogramsBins[eVertexZ][2] = 40.; + + eh.fEventHistogramsBins[eNContributors][0] = 600.; // bin width is 20 + eh.fEventHistogramsBins[eNContributors][1] = 0.; + eh.fEventHistogramsBins[eNContributors][2] = 12000.; + + eh.fEventHistogramsBins[eImpactParameter][0] = 1000; + eh.fEventHistogramsBins[eImpactParameter][1] = 0.; + eh.fEventHistogramsBins[eImpactParameter][2] = 100.; + + eh.fEventHistogramsBins[eEventPlaneAngle][0] = 720; + eh.fEventHistogramsBins[eEventPlaneAngle][1] = -o2::constants::math::PI; // just in case somebody uses the convention -Pi < EP < Pi, instead of 0 < EP < 2Pi + eh.fEventHistogramsBins[eEventPlaneAngle][2] = o2::constants::math::TwoPI; + + eh.fEventHistogramsBins[eOccupancy][0] = 1000; + eh.fEventHistogramsBins[eOccupancy][1] = 0.; + eh.fEventHistogramsBins[eOccupancy][2] = 100000.; + + eh.fEventHistogramsBins[eInteractionRate][0] = 1000; + eh.fEventHistogramsBins[eInteractionRate][1] = 0.; + eh.fEventHistogramsBins[eInteractionRate][2] = 100.; + + eh.fEventHistogramsBins[eCurrentRunDuration][0] = 10000; + eh.fEventHistogramsBins[eCurrentRunDuration][1] = 0.; + eh.fEventHistogramsBins[eCurrentRunDuration][2] = 10000.; + + // b) Default binning for particle histograms 1D: + ph.fParticleHistogramsBins[ePhi][0] = 360; + ph.fParticleHistogramsBins[ePhi][1] = 0.; + ph.fParticleHistogramsBins[ePhi][2] = o2::constants::math::TwoPI; + + ph.fParticleHistogramsBins[ePt][0] = 2000; + ph.fParticleHistogramsBins[ePt][1] = 0.; + ph.fParticleHistogramsBins[ePt][2] = 20.; + + ph.fParticleHistogramsBins[eEta][0] = 400; + ph.fParticleHistogramsBins[eEta][1] = -2.; + ph.fParticleHistogramsBins[eEta][2] = 2.; + + ph.fParticleHistogramsBins[eCharge][0] = 7; + ph.fParticleHistogramsBins[eCharge][1] = -3.5; // anticipating I might be storing charge of Delta++, etc. + ph.fParticleHistogramsBins[eCharge][2] = 3.5; + + ph.fParticleHistogramsBins[etpcNClsFindable][0] = 300; + ph.fParticleHistogramsBins[etpcNClsFindable][1] = 0.; + ph.fParticleHistogramsBins[etpcNClsFindable][2] = 300.; + + ph.fParticleHistogramsBins[etpcNClsShared][0] = 200; + ph.fParticleHistogramsBins[etpcNClsShared][1] = 0.; + ph.fParticleHistogramsBins[etpcNClsShared][2] = 200.; + + ph.fParticleHistogramsBins[eitsChi2NCl][0] = 200; + ph.fParticleHistogramsBins[eitsChi2NCl][1] = 0.; + ph.fParticleHistogramsBins[eitsChi2NCl][2] = 200.; + + ph.fParticleHistogramsBins[etpcNClsFound][0] = 200; + ph.fParticleHistogramsBins[etpcNClsFound][1] = 0.; + ph.fParticleHistogramsBins[etpcNClsFound][2] = 200.; + + ph.fParticleHistogramsBins[etpcNClsCrossedRows][0] = 200; + ph.fParticleHistogramsBins[etpcNClsCrossedRows][1] = 0.; + ph.fParticleHistogramsBins[etpcNClsCrossedRows][2] = 200.; + + ph.fParticleHistogramsBins[eitsNCls][0] = 10; + ph.fParticleHistogramsBins[eitsNCls][1] = 0.; + ph.fParticleHistogramsBins[eitsNCls][2] = 10.; + + ph.fParticleHistogramsBins[eitsNClsInnerBarrel][0] = 10; + ph.fParticleHistogramsBins[eitsNClsInnerBarrel][1] = 0.; + ph.fParticleHistogramsBins[eitsNClsInnerBarrel][2] = 10.; + + ph.fParticleHistogramsBins[etpcCrossedRowsOverFindableCls][0] = 1000; + ph.fParticleHistogramsBins[etpcCrossedRowsOverFindableCls][1] = 0.; + ph.fParticleHistogramsBins[etpcCrossedRowsOverFindableCls][2] = 10; + + ph.fParticleHistogramsBins[etpcFoundOverFindableCls][0] = 1000; + ph.fParticleHistogramsBins[etpcFoundOverFindableCls][1] = 0.; + ph.fParticleHistogramsBins[etpcFoundOverFindableCls][2] = 10.; + + ph.fParticleHistogramsBins[etpcFractionSharedCls][0] = 110; + ph.fParticleHistogramsBins[etpcFractionSharedCls][1] = -1.; // yes, I saw here entries with negative values TBI 20240507 check what are these values + ph.fParticleHistogramsBins[etpcFractionSharedCls][2] = 10.; + + ph.fParticleHistogramsBins[etpcChi2NCl][0] = 2500; + ph.fParticleHistogramsBins[etpcChi2NCl][1] = 0.; + ph.fParticleHistogramsBins[etpcChi2NCl][2] = 250.; + + ph.fParticleHistogramsBins[edcaXY][0] = 2000; + ph.fParticleHistogramsBins[edcaXY][1] = -10.; + ph.fParticleHistogramsBins[edcaXY][2] = 10.; + + ph.fParticleHistogramsBins[edcaZ][0] = 2000; + ph.fParticleHistogramsBins[edcaZ][1] = -10.; + ph.fParticleHistogramsBins[edcaZ][2] = 10.; + + ph.fParticleHistogramsBins[ePDG][0] = 2000; + ph.fParticleHistogramsBins[ePDG][1] = -1000.; + ph.fParticleHistogramsBins[ePDG][2] = 1000.; + + // c) Default binning for particle histograms 2D: + // At the moment, for fixed binning, I just re-use the binning of corresponding 1D histograms. + // For variable-length binning, I use binning from fResultsPro[], as for other histograms. + ph.fParticleHistogramsBins2D[ePhiPt][eX][0] = ph.fParticleHistogramsBins[ePhi][0]; + ph.fParticleHistogramsBins2D[ePhiPt][eX][1] = ph.fParticleHistogramsBins[ePhi][1]; + ph.fParticleHistogramsBins2D[ePhiPt][eX][2] = ph.fParticleHistogramsBins[ePhi][2]; + ph.fParticleHistogramsBins2D[ePhiPt][eY][0] = ph.fParticleHistogramsBins[ePt][0]; + ph.fParticleHistogramsBins2D[ePhiPt][eY][1] = ph.fParticleHistogramsBins[ePt][1]; + ph.fParticleHistogramsBins2D[ePhiPt][eY][2] = ph.fParticleHistogramsBins[ePt][2]; + + ph.fParticleHistogramsBins2D[ePhiEta][eX][0] = ph.fParticleHistogramsBins[ePhi][0]; + ph.fParticleHistogramsBins2D[ePhiEta][eX][1] = ph.fParticleHistogramsBins[ePhi][1]; + ph.fParticleHistogramsBins2D[ePhiEta][eX][2] = ph.fParticleHistogramsBins[ePhi][2]; + ph.fParticleHistogramsBins2D[ePhiEta][eY][0] = ph.fParticleHistogramsBins[eEta][0]; + ph.fParticleHistogramsBins2D[ePhiEta][eY][1] = ph.fParticleHistogramsBins[eEta][1]; + ph.fParticleHistogramsBins2D[ePhiEta][eY][2] = ph.fParticleHistogramsBins[eEta][2]; + + // d) Default binning for results histograms: + // Remark: These bins apply to following categories fCorrelationsPro, fNestedLoopsPro, fTest0Pro, fResultsPro, and all 2D and 3D variants. + // 1D: + // *) For integrated results, binning is always the same nBins = 1 in (0.,1.): + res.fResultsProBinEdges[AFO_INTEGRATED] = new TArrayD(2); + res.fResultsProBinEdges[AFO_INTEGRATED]->AddAt(0., 0); + res.fResultsProBinEdges[AFO_INTEGRATED]->AddAt(1., 1); + + // *) Binning vs. multiplicity: + if (res.fUseResultsProVariableLengthBins[AFO_MULTIPLICITY]) { + this->InitializeVariableLengthBins(AFO_MULTIPLICITY); + } else { + this->InitializeFixedLengthBins(AFO_MULTIPLICITY); + } + + // *) Binning vs. centrality: + if (res.fUseResultsProVariableLengthBins[AFO_CENTRALITY]) { + this->InitializeVariableLengthBins(AFO_CENTRALITY); + } else { + this->InitializeFixedLengthBins(AFO_CENTRALITY); + } + + // *) Binning vs. pt: + if (res.fUseResultsProVariableLengthBins[AFO_PT]) { + this->InitializeVariableLengthBins(AFO_PT); + } else { + this->InitializeFixedLengthBins(AFO_PT); + } + + // *) Binning vs. eta: + if (res.fUseResultsProVariableLengthBins[AFO_ETA]) { + this->InitializeVariableLengthBins(AFO_ETA); + } else { + this->InitializeFixedLengthBins(AFO_ETA); + } + + // *) Binning vs. occupancy: + if (res.fUseResultsProVariableLengthBins[AFO_OCCUPANCY]) { + this->InitializeVariableLengthBins(AFO_OCCUPANCY); + } else { + this->InitializeFixedLengthBins(AFO_OCCUPANCY); + } + + // *) Binning vs. interaction rate: + if (res.fUseResultsProVariableLengthBins[AFO_INTERACTIONRATE]) { + this->InitializeVariableLengthBins(AFO_INTERACTIONRATE); + } else { + this->InitializeFixedLengthBins(AFO_INTERACTIONRATE); + } + + // *) Binning vs. current run duration: + if (res.fUseResultsProVariableLengthBins[AFO_CURRENTRUNDURATION]) { + this->InitializeVariableLengthBins(AFO_CURRENTRUNDURATION); + } else { + this->InitializeFixedLengthBins(AFO_CURRENTRUNDURATION); + } + + // *) Binning vs. vertex z position: + if (res.fUseResultsProVariableLengthBins[AFO_VZ]) { + this->InitializeVariableLengthBins(AFO_VZ); + } else { + this->InitializeFixedLengthBins(AFO_VZ); + } + + // *) Binning vs. particle charge => binning is always the same nBins = 2 in (-2.,2), so that the center of bins is at +/- 1: + // Therefore, I shall never initialize or set for ill-defined cases the charge to 0., because when filling, that one will go to bin for +1 charge ("lower boundary included"). + // Keep in sync with Configurable> cfCharge{ ... + res.fResultsProBinEdges[AFO_CHARGE] = new TArrayD(3); + res.fResultsProBinEdges[AFO_CHARGE]->AddAt(-2., 0); + res.fResultsProBinEdges[AFO_CHARGE]->AddAt(0., 1); + res.fResultsProBinEdges[AFO_CHARGE]->AddAt(2., 2); + + // ... + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // void defaultBinning() + + //============================================================ + + void InitializeFixedLengthBins(eAsFunctionOf AFO) + { + // This is a helper function to suppress code bloat in defaultBinning(). + // It merely initalizes res.fResultsProFixedLengthBins[...] from corresponding configurables + a few other minor thingies. + // I do not have here AFO_INTEGRATED and AFO_CHARGE, because for them binning is always the same, i.e. no need for configurable. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // Common local vector for all fixed-length bins: + std::vector lFixedLength_bins; + + switch (AFO) { + case AFO_MULTIPLICITY: { + lFixedLength_bins = cf_res.cfFixedLengthMultBins.value; + break; + } + case AFO_CENTRALITY: { + lFixedLength_bins = cf_res.cfFixedLengthCentBins.value; + break; + } + case AFO_PT: { + lFixedLength_bins = cf_res.cfFixedLengthPtBins.value; + break; + } + case AFO_ETA: { + lFixedLength_bins = cf_res.cfFixedLengthEtaBins.value; + break; + } + case AFO_OCCUPANCY: { + lFixedLength_bins = cf_res.cfFixedLengthOccuBins.value; + break; + } + case AFO_INTERACTIONRATE: { + lFixedLength_bins = cf_res.cfFixedLengthIRBins.value; + break; + } + case AFO_CURRENTRUNDURATION: { + lFixedLength_bins = cf_res.cfFixedLengthCRDBins.value; + break; + } + case AFO_VZ: { + lFixedLength_bins = cf_res.cfFixedLengthVzBins.value; + break; + } + // ... + default: { + LOGF(fatal, "\033[1;31m%s at line %d : This enum AFO = %d is not supported yet. \033[0m", __FUNCTION__, __LINE__, static_cast(AFO)); + break; + } + } // switch(AFO) + + // From this point onward, the code is the same for any AFO variable: + if (lFixedLength_bins.size() != 3) { + LOGF(fatal, "in function \033[1;31m%s at line %d => The array cfFixedLength_bins must have have 3 entries: {nBins, min, max} \n \033[0m", __FUNCTION__, __LINE__); + } + + res.fResultsProBinEdges[AFO] = ArrayWithBinEdges(lFixedLength_bins[0], lFixedLength_bins[1], lFixedLength_bins[2]); + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // void InitializeFixedLengthBins(eAsFunctionOf AFO) + + //============================================================ + + void InitializeVariableLengthBins(eAsFunctionOf AFO) + { + // This is a helper function to suppress code bloat in defaultBinning(). + // It merely initalizes res.fResultsProVariableLengthBins[...] from corresponding configurables + a few other minor thingies. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // Common local vector for all variable-length bins: + std::vector lVariableLength_bins; + + switch (AFO) { + case AFO_MULTIPLICITY: { + lVariableLength_bins = cf_res.cfVariableLengthMultBins.value; + break; + } + case AFO_CENTRALITY: { + lVariableLength_bins = cf_res.cfVariableLengthCentBins.value; + break; + } + case AFO_PT: { + lVariableLength_bins = cf_res.cfVariableLengthPtBins.value; + break; + } + case AFO_ETA: { + lVariableLength_bins = cf_res.cfVariableLengthEtaBins.value; + break; + } + case AFO_OCCUPANCY: { + lVariableLength_bins = cf_res.cfVariableLengthOccuBins.value; + break; + } + case AFO_INTERACTIONRATE: { + lVariableLength_bins = cf_res.cfVariableLengthIRBins.value; + break; + } + case AFO_CURRENTRUNDURATION: { + lVariableLength_bins = cf_res.cfVariableLengthCRDBins.value; + break; + } + case AFO_VZ: { + lVariableLength_bins = cf_res.cfVariableLengthVzBins.value; + break; + } + // ... + default: { + LOGF(fatal, "\033[1;31m%s at line %d : This enum AFO = %d is not supported yet. \033[0m", __FUNCTION__, __LINE__, static_cast(AFO)); + break; + } + } // switch(AFO) + + // From this point onward, the code is the same for any AFO variable: + if (lVariableLength_bins.size() < 2) { + LOGF(fatal, "in function \033[1;31m%s at line %d => The array cfVariableLength_bins must have at least 2 entries \n \033[0m", __FUNCTION__, __LINE__); + } + res.fResultsProBinEdges[AFO] = new TArrayD(lVariableLength_bins.size(), lVariableLength_bins.data()); + if (tc.fVerbose) { + LOGF(info, "\033[1;32m %s : variable-length %s bins \033[0m", __FUNCTION__, res.fResultsProXaxisTitle[AFO].Data()); + for (int i = 0; i < res.fResultsProBinEdges[AFO]->GetSize(); i++) { + LOGF(info, "\033[1;32m [%d] : %f \033[0m", i, res.fResultsProBinEdges[AFO]->GetAt(i)); + } + } + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // void InitializeVariableLengthBins(eAsFunctionOf AFO) + + //============================================================ + + void CastStringIntoArray(int AFO) + { + // Temporary function, to be removed eventually. Here temporarily I am casting e.g. a string "1.0,2.0,5.0" into corresponding TArrayD. + + // TBI 20241019 This function is not needed any longer, remove eventually. + + if (tc.fVerbose) { + LOGF(info, "\033[1;32m%s\033[0m", __FUNCTION__); + } + + if (tc.fVerbose) { + LOGF(info, "\033[1;32m Casting a string %s into TArrayD .... \033[0m", res.fResultsProVariableLengthBinsString[AFO].Data()); + } + + TObjArray* oa = res.fResultsProVariableLengthBinsString[AFO].Tokenize(","); + if (!oa) { + LOGF(fatal, "in function \033[1;31m%s at line %d \n fResultsProVariableLengthBinsString[AFO] = %s\033[0m", __FUNCTION__, __LINE__, res.fResultsProVariableLengthBinsString[AFO].Data()); + } + int nEntries = oa->GetEntries(); + res.fResultsProVariableLengthBins[AFO] = new TArrayF(nEntries); + for (int i = 0; i < nEntries; i++) { + res.fResultsProVariableLengthBins[AFO]->AddAt(TString(oa->At(i)->GetName()).Atof(), i); + } + delete oa; // yes, otherwise it's a memory leak + + if (tc.fVerbose) { + for (int i = 0; i < res.fResultsProVariableLengthBins[AFO]->GetSize(); i++) { + LOGF(info, "\033[1;32m [%d] : %f \033[0m", i, res.fResultsProVariableLengthBins[AFO]->At(i)); + } + } + + if (tc.fVerbose) { + LOGF(info, "\033[1;32m Done! \033[0m"); + } + + } // void CastStringIntoArray(int AFO) + + //============================================================ + + void defaultCuts() + { + // Define default cuts. Default cuts are hardwired in MuPa-Configurables.h. + + // a) Default event cuts; + // b) Default particle cuts. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // a) Default event cuts: + + // *) Use or do not use a cut enumerated in eEventHistograms + eEventCuts. + // Default cuts are set in configurable cfUseEventCuts + auto lUseEventCuts = (std::vector)cf_ec.cfUseEventCuts; + if (lUseEventCuts.size() != eEventCuts_N) { + LOGF(info, "\033[1;31m lUseEventCuts.size() = %d\033[0m", lUseEventCuts.size()); + LOGF(info, "\033[1;31m eEventCuts_N = %d\033[0m", static_cast(eEventCuts_N)); + LOGF(fatal, "\033[1;31m%s at line %d : Mismatch in the number of flags in configurable cfUseEventCuts, and number of entries in enum eEventHistograms + eEventCuts \n \033[0m", __FUNCTION__, __LINE__); + } + + // *) Insanity check on the content and ordering of event cuts in the initialization in configurable cfUseEventCuts: + // TBI 20240518 I do not need this in fact, I can automate initialization even without ordering in configurable, but it feels with the ordering enforced, it's much safer. + for (int name = 0; name < eEventCuts_N; name++) { + // TBI 20240518 I could implement even a strickter EqualTo instead of EndsWith, but then I need to tokenize, etc., etc. This shall be safe enough. + if (!TString(lUseEventCuts[name]).EndsWith(ec.fEventCutName[name].Data())) { + LOGF(fatal, "\033[1;31m%s at line %d : Wrong content or ordering of contents in configurable cfUseEventCuts => name = %d, lUseEventCuts[name] = \"%s\", ec.fEventCutName[name] = \"%s\" \033[0m", __FUNCTION__, __LINE__, name, TString(lUseEventCuts[name]).Data(), ec.fEventCutName[name].Data()); + } + } + + // *) from enum eEventHistograms: + ec.fUseEventCuts[eNumberOfEvents] = Alright(lUseEventCuts[eNumberOfEvents]); // total number of events (before event cuts) + ec.fUseEventCuts[eTotalMultiplicity] = Alright(lUseEventCuts[eTotalMultiplicity]); + ec.fUseEventCuts[eMultiplicity] = Alright(lUseEventCuts[eMultiplicity]); + ec.fUseEventCuts[eReferenceMultiplicity] = Alright(lUseEventCuts[eReferenceMultiplicity]); + ec.fUseEventCuts[eCentrality] = Alright(lUseEventCuts[eCentrality]); + ec.fUseEventCuts[eVertexX] = Alright(lUseEventCuts[eVertexX]); + ec.fUseEventCuts[eVertexY] = Alright(lUseEventCuts[eVertexY]); + ec.fUseEventCuts[eVertexZ] = Alright(lUseEventCuts[eVertexZ]); + ec.fUseEventCuts[eNContributors] = Alright(lUseEventCuts[eNContributors]); + ec.fUseEventCuts[eImpactParameter] = Alright(lUseEventCuts[eImpactParameter]); + ec.fUseEventCuts[eEventPlaneAngle] = Alright(lUseEventCuts[eEventPlaneAngle]); + ec.fUseEventCuts[eOccupancy] = Alright(lUseEventCuts[eOccupancy]); + ec.fUseEventCuts[eInteractionRate] = Alright(lUseEventCuts[eInteractionRate]); + ec.fUseEventCuts[eCurrentRunDuration] = Alright(lUseEventCuts[eCurrentRunDuration]); + ec.fUseEventCuts[eMultMCNParticlesEta08] = Alright(lUseEventCuts[eMultMCNParticlesEta08]); + + // *) from enum eEventCuts: + ec.fUseEventCuts[eTrigger] = Alright(lUseEventCuts[eTrigger]); + ec.fUseEventCuts[eSel7] = Alright(lUseEventCuts[eSel7]); + ec.fUseEventCuts[eSel8] = Alright(lUseEventCuts[eSel8]); + ec.fUseEventCuts[eMultiplicityEstimator] = Alright(lUseEventCuts[eMultiplicityEstimator]); + ec.fUseEventCuts[eCentralityEstimator] = Alright(lUseEventCuts[eCentralityEstimator]); + ec.fUseEventCuts[eReferenceMultiplicityEstimator] = Alright(lUseEventCuts[eReferenceMultiplicityEstimator]); + ec.fUseEventCuts[eSelectedEvents] = Alright(lUseEventCuts[eSelectedEvents]); // selected number of events (after all event cuts) + ec.fUseEventCuts[eNoSameBunchPileup] = Alright(lUseEventCuts[eNoSameBunchPileup]); + ec.fUseEventCuts[eIsGoodZvtxFT0vsPV] = Alright(lUseEventCuts[eIsGoodZvtxFT0vsPV]); + ec.fUseEventCuts[eIsVertexITSTPC] = Alright(lUseEventCuts[eIsVertexITSTPC]); + ec.fUseEventCuts[eIsVertexTOFmatched] = Alright(lUseEventCuts[eIsVertexTOFmatched]); + ec.fUseEventCuts[eIsVertexTRDmatched] = Alright(lUseEventCuts[eIsVertexTRDmatched]); + ec.fUseEventCuts[eNoCollInTimeRangeStrict] = Alright(lUseEventCuts[eNoCollInTimeRangeStrict]); + ec.fUseEventCuts[eNoCollInTimeRangeStandard] = Alright(lUseEventCuts[eNoCollInTimeRangeStandard]); + ec.fUseEventCuts[eNoCollInRofStrict] = Alright(lUseEventCuts[eNoCollInRofStrict]); + ec.fUseEventCuts[eNoCollInRofStandard] = Alright(lUseEventCuts[eNoCollInRofStandard]); + ec.fUseEventCuts[eNoHighMultCollInPrevRof] = Alright(lUseEventCuts[eNoHighMultCollInPrevRof]); + ec.fUseEventCuts[eIsGoodITSLayer3] = Alright(lUseEventCuts[eIsGoodITSLayer3]); + ec.fUseEventCuts[eIsGoodITSLayer0123] = Alright(lUseEventCuts[eIsGoodITSLayer0123]); + ec.fUseEventCuts[eIsGoodITSLayersAll] = Alright(lUseEventCuts[eIsGoodITSLayersAll]); + ec.fUseEventCuts[eOccupancyEstimator] = Alright(lUseEventCuts[eOccupancyEstimator]); + ec.fUseEventCuts[eMinVertexDistanceFromIP] = Alright(lUseEventCuts[eMinVertexDistanceFromIP]); + ec.fUseEventCuts[eNoPileupTPC] = Alright(lUseEventCuts[eNoPileupTPC]); + ec.fUseEventCuts[eNoPileupFromSPD] = Alright(lUseEventCuts[eNoPileupFromSPD]); + ec.fUseEventCuts[eNoSPDOnVsOfPileup] = Alright(lUseEventCuts[eNoSPDOnVsOfPileup]); + ec.fUseEventCuts[eRefMultVsNContrUp] = Alright(lUseEventCuts[eRefMultVsNContrUp]); + ec.fUseEventCuts[eRefMultVsNContrLow] = Alright(lUseEventCuts[eRefMultVsNContrLow]); + ec.fUseEventCuts[eCentralityCorrelationsCut] = Alright(lUseEventCuts[eCentralityCorrelationsCut]); + ec.fUseEventCuts[eFT0Bad] = Alright(lUseEventCuts[eFT0Bad]); + ec.fUseEventCuts[eITSBad] = Alright(lUseEventCuts[eITSBad]); + ec.fUseEventCuts[eITSLimAccMCRepr] = Alright(lUseEventCuts[eITSLimAccMCRepr]); + ec.fUseEventCuts[eTPCBadTracking] = Alright(lUseEventCuts[eTPCBadTracking]); + ec.fUseEventCuts[eTPCLimAccMCRepr] = Alright(lUseEventCuts[eTPCLimAccMCRepr]); + ec.fUseEventCuts[eTPCBadPID] = Alright(lUseEventCuts[eTPCBadPID]); + ec.fUseEventCuts[eCentralityWeights] = Alright(lUseEventCuts[eCentralityWeights]); + + // **) event cuts defined via booleans: + ec.fUseEventCuts[eSel7] = ec.fUseEventCuts[eSel7] && cf_ec.cfUseSel7; + ec.fUseEventCuts[eSel8] = ec.fUseEventCuts[eSel8] && cf_ec.cfUseSel8; + ec.fUseEventCuts[eNoSameBunchPileup] = ec.fUseEventCuts[eNoSameBunchPileup] && cf_ec.cfUseNoSameBunchPileup; + ec.fUseEventCuts[eIsGoodZvtxFT0vsPV] = ec.fUseEventCuts[eIsGoodZvtxFT0vsPV] && cf_ec.cfUseIsGoodZvtxFT0vsPV; + ec.fUseEventCuts[eIsVertexITSTPC] = ec.fUseEventCuts[eIsVertexITSTPC] && cf_ec.cfUseIsVertexITSTPC; + ec.fUseEventCuts[eIsVertexTOFmatched] = ec.fUseEventCuts[eIsVertexTOFmatched] && cf_ec.cfUseIsVertexTOFmatched; + ec.fUseEventCuts[eIsVertexTRDmatched] = ec.fUseEventCuts[eIsVertexTRDmatched] && cf_ec.cfUseIsVertexTRDmatched; + ec.fUseEventCuts[eNoCollInTimeRangeStrict] = ec.fUseEventCuts[eNoCollInTimeRangeStrict] && cf_ec.cfUseNoCollInTimeRangeStrict; + ec.fUseEventCuts[eNoCollInTimeRangeStandard] = ec.fUseEventCuts[eNoCollInTimeRangeStandard] && cf_ec.cfUseNoCollInTimeRangeStandard; + ec.fUseEventCuts[eNoCollInRofStrict] = ec.fUseEventCuts[eNoCollInRofStrict] && cf_ec.cfUseNoCollInRofStrict; + ec.fUseEventCuts[eNoCollInRofStandard] = ec.fUseEventCuts[eNoCollInRofStandard] && cf_ec.cfUseNoCollInRofStandard; + ec.fUseEventCuts[eNoHighMultCollInPrevRof] = ec.fUseEventCuts[eNoHighMultCollInPrevRof] && cf_ec.cfUseNoHighMultCollInPrevRof; + ec.fUseEventCuts[eIsGoodITSLayer3] = ec.fUseEventCuts[eIsGoodITSLayer3] && cf_ec.cfUseIsGoodITSLayer3; + ec.fUseEventCuts[eIsGoodITSLayer0123] = ec.fUseEventCuts[eIsGoodITSLayer0123] && cf_ec.cfUseIsGoodITSLayer0123; + ec.fUseEventCuts[eIsGoodITSLayersAll] = ec.fUseEventCuts[eIsGoodITSLayersAll] && cf_ec.cfUseIsGoodITSLayersAll; + ec.fUseEventCuts[eNoPileupTPC] = ec.fUseEventCuts[eNoPileupTPC] && cf_ec.cfUseNoPileupTPC; + ec.fUseEventCuts[eNoPileupFromSPD] = ec.fUseEventCuts[eNoPileupFromSPD] && cf_ec.cfUseNoPileupFromSPD; + ec.fUseEventCuts[eNoSPDOnVsOfPileup] = ec.fUseEventCuts[eNoSPDOnVsOfPileup] && cf_ec.cfUseNoSPDOnVsOfPileup; + ec.fUseEventCuts[eFT0Bad] = ec.fUseEventCuts[eFT0Bad] && cf_ec.cfUseFT0Bad; + ec.fUseEventCuts[eITSBad] = ec.fUseEventCuts[eITSBad] && cf_ec.cfUseITSBad; + ec.fUseEventCuts[eITSLimAccMCRepr] = ec.fUseEventCuts[eITSLimAccMCRepr] && cf_ec.cfUseITSLimAccMCRepr; + ec.fUseEventCuts[eTPCBadTracking] = ec.fUseEventCuts[eTPCBadTracking] && cf_ec.cfUseTPCBadTracking; + ec.fUseEventCuts[eTPCLimAccMCRepr] = ec.fUseEventCuts[eTPCLimAccMCRepr] && cf_ec.cfUseTPCLimAccMCRepr; + ec.fUseEventCuts[eTPCBadPID] = ec.fUseEventCuts[eTPCBadPID] && cf_ec.cfUseTPCBadPID; + ec.fUseEventCuts[eCentralityWeights] = ec.fUseEventCuts[eCentralityWeights] && cf_cw.cfUseCentralityWeights; + + // **) event cuts defined via [min, max): + // Remark: I use this one also for events cuts set only via min or via max. + // In this case, I set either min or max intentionally to some value which never can be met (see below example for "MinVertexDistanceFromIP") + auto lNumberOfEvents = (std::vector)cf_ec.cfNumberOfEvents; + ec.fdEventCuts[eNumberOfEvents][eMin] = lNumberOfEvents[eMin]; + ec.fdEventCuts[eNumberOfEvents][eMax] = lNumberOfEvents[eMax]; + + auto lTotalMultiplicity = (std::vector)cf_ec.cfTotalMultiplicity; + ec.fdEventCuts[eTotalMultiplicity][eMin] = lTotalMultiplicity[eMin]; + ec.fdEventCuts[eTotalMultiplicity][eMax] = lTotalMultiplicity[eMax]; + + auto lMultiplicity = (std::vector)cf_ec.cfMultiplicity; + ec.fdEventCuts[eMultiplicity][eMin] = lMultiplicity[eMin]; + ec.fdEventCuts[eMultiplicity][eMax] = lMultiplicity[eMax]; + // If I have requested fFixedNumberOfRandomlySelectedTracks, then I do not care about events with smaller number of particles: + if (tc.fFixedNumberOfRandomlySelectedTracks > 0) { + ec.fdEventCuts[eMultiplicity][eMin] = tc.fFixedNumberOfRandomlySelectedTracks; + } + + auto lReferenceMultiplicity = (std::vector)cf_ec.cfReferenceMultiplicity; + ec.fdEventCuts[eReferenceMultiplicity][eMin] = lReferenceMultiplicity[eMin]; + ec.fdEventCuts[eReferenceMultiplicity][eMax] = lReferenceMultiplicity[eMax]; + + auto lCentrality = (std::vector)cf_ec.cfCentrality; + ec.fdEventCuts[eCentrality][eMin] = lCentrality[eMin]; + ec.fdEventCuts[eCentrality][eMax] = lCentrality[eMax]; + + auto lVertexX = (std::vector)cf_ec.cfVertexX; + ec.fdEventCuts[eVertexX][eMin] = lVertexX[eMin]; + ec.fdEventCuts[eVertexX][eMax] = lVertexX[eMax]; + + auto lVertexY = (std::vector)cf_ec.cfVertexY; + ec.fdEventCuts[eVertexY][eMin] = lVertexY[eMin]; + ec.fdEventCuts[eVertexY][eMax] = lVertexY[eMax]; + + auto lVertexZ = (std::vector)cf_ec.cfVertexZ; + ec.fdEventCuts[eVertexZ][eMin] = lVertexZ[eMin]; + ec.fdEventCuts[eVertexZ][eMax] = lVertexZ[eMax]; + + auto lNContributors = (std::vector)cf_ec.cfNContributors; + ec.fdEventCuts[eNContributors][eMin] = lNContributors[eMin]; + ec.fdEventCuts[eNContributors][eMax] = lNContributors[eMax]; + + auto lImpactParameter = (std::vector)cf_ec.cfImpactParameter; + ec.fdEventCuts[eImpactParameter][eMin] = lImpactParameter[eMin]; + ec.fdEventCuts[eImpactParameter][eMax] = lImpactParameter[eMax]; + + auto lEventPlaneAngle = (std::vector)cf_ec.cfEventPlaneAngle; + ec.fdEventCuts[eEventPlaneAngle][eMin] = lEventPlaneAngle[eMin]; + ec.fdEventCuts[eEventPlaneAngle][eMax] = lEventPlaneAngle[eMax]; + + auto lOccupancy = (std::vector)cf_ec.cfOccupancy; + ec.fdEventCuts[eOccupancy][eMin] = lOccupancy[eMin]; + ec.fdEventCuts[eOccupancy][eMax] = lOccupancy[eMax]; + + auto lInteractionRate = (std::vector)cf_ec.cfInteractionRate; + ec.fdEventCuts[eInteractionRate][eMin] = lInteractionRate[eMin]; + ec.fdEventCuts[eInteractionRate][eMax] = lInteractionRate[eMax]; + + auto lCurrentRunDuration = (std::vector)cf_ec.cfCurrentRunDuration; + ec.fdEventCuts[eCurrentRunDuration][eMin] = lCurrentRunDuration[eMin]; + ec.fdEventCuts[eCurrentRunDuration][eMax] = lCurrentRunDuration[eMax]; + + auto lMultMCNParticlesEta08 = (std::vector)cf_ec.cfMultMCNParticlesEta08; + ec.fdEventCuts[eMultMCNParticlesEta08][eMin] = lMultMCNParticlesEta08[eMin]; + ec.fdEventCuts[eMultMCNParticlesEta08][eMax] = lMultMCNParticlesEta08[eMax]; + + auto lSelectedEvents = (std::vector)cf_ec.cfSelectedEvents; + ec.fdEventCuts[eSelectedEvents][eMin] = lSelectedEvents[eMin]; + ec.fdEventCuts[eSelectedEvents][eMax] = lSelectedEvents[eMax]; + + ec.fdEventCuts[eMinVertexDistanceFromIP][eMin] = cf_ec.cfMinVertexDistanceFromIP; // if vertex is closer to IP than this value, the event is rejected + ec.fdEventCuts[eMinVertexDistanceFromIP][eMax] = -1; // this value is never checked in any case + + // **) event cuts defined via string: + ec.fsEventCuts[eMultiplicityEstimator] = cf_ec.cfMultiplicityEstimator; + ec.fsEventCuts[eReferenceMultiplicityEstimator] = cf_ec.cfReferenceMultiplicityEstimator; + ec.fsEventCuts[eCentralityEstimator] = cf_ec.cfCentralityEstimator; + ec.fsEventCuts[eTrigger] = cf_ec.cfTrigger; + ec.fsEventCuts[eOccupancyEstimator] = cf_ec.cfOccupancyEstimator; + ec.fsEventCuts[eRefMultVsNContrUp] = cf_ec.cfRefMultVsNContrUp; + ec.fsEventCuts[eRefMultVsNContrLow] = cf_ec.cfRefMultVsNContrLow; + ec.fsEventCuts[eCentralityCorrelationsCut] = cf_ec.cfCentralityCorrelationsCut; + + // **) additional info for some specific event cuts, which I didn't enumerate in enum eEventCuts, to trim down bookeeping: + ec.fCentralityCorrelationsCutTreshold = cf_ec.cfCentralityCorrelationsCutTreshold; + ec.fCentralityCorrelationsCutVersion = cf_ec.cfCentralityCorrelationsCutVersion; + + // ---------------------------------------------------------------------- + + // b) Default particle cuts: + + // *) Use or do not use a cut enumerated in eParticleHistograms + eParticleCuts. + // Default cuts are set in configurable cfUseParticleCuts + auto lUseParticleCuts = (std::vector)cf_pc.cfUseParticleCuts; + if (lUseParticleCuts.size() != eParticleCuts_N) { + LOGF(info, "\033[1;31m lUseParticleCuts.size() = %d\033[0m", lUseParticleCuts.size()); + LOGF(info, "\033[1;31m eParticleCuts_N = %d\033[0m", static_cast(eParticleCuts_N)); + LOGF(fatal, "\033[1;31m%s at line %d : Mismatch in the number of flags in configurable cfUseParticleCuts, and number of entries in enum eParticleHistograms + eParticleCuts \n \033[0m", __FUNCTION__, __LINE__); + } + + // *) Insanity check on the content and ordering of particle cuts in the initialization in configurable cfUseParticleCuts: + // TBI 20240518 I do not need this in fact, I can automate initialization even without ordering in configurable, but it feels with the ordering enforced, it's much safer. + for (int name = 0; name < eParticleCuts_N; name++) { + // TBI 20240518 I could implement even a strickter EqualTo instead of EndsWith, but then I need to tokenize, etc., etc. This shall be safe enough. + if (!TString(lUseParticleCuts[name]).EndsWith(pc.fParticleCutName[name].Data())) { + LOGF(fatal, "\033[1;31m%s at line %d : Wrong content or ordering of contents in configurable cfUseParticleCuts => name = %d, lUseParticleCuts[name] = \"%s\", pc.fParticleCutName[name] = \"%s\" \033[0m", __FUNCTION__, __LINE__, name, TString(lUseParticleCuts[name]).Data(), pc.fParticleCutName[name].Data()); + } + } + + // *) from enum eParticleHistograms: + pc.fUseParticleCuts[ePhi] = Alright(lUseParticleCuts[ePhi]); + pc.fUseParticleCuts[ePt] = Alright(lUseParticleCuts[ePt]); + pc.fUseParticleCuts[eEta] = Alright(lUseParticleCuts[eEta]); + pc.fUseParticleCuts[eCharge] = Alright(lUseParticleCuts[eCharge]); + pc.fUseParticleCuts[etpcNClsFindable] = Alright(lUseParticleCuts[etpcNClsFindable]); + pc.fUseParticleCuts[etpcNClsShared] = Alright(lUseParticleCuts[etpcNClsShared]); + pc.fUseParticleCuts[eitsChi2NCl] = Alright(lUseParticleCuts[eitsChi2NCl]); + pc.fUseParticleCuts[etpcNClsFound] = Alright(lUseParticleCuts[etpcNClsFound]); + pc.fUseParticleCuts[etpcNClsCrossedRows] = Alright(lUseParticleCuts[etpcNClsCrossedRows]); + pc.fUseParticleCuts[eitsNCls] = Alright(lUseParticleCuts[eitsNCls]); + pc.fUseParticleCuts[eitsNClsInnerBarrel] = Alright(lUseParticleCuts[eitsNClsInnerBarrel]); + pc.fUseParticleCuts[etpcCrossedRowsOverFindableCls] = Alright(lUseParticleCuts[etpcCrossedRowsOverFindableCls]); + pc.fUseParticleCuts[etpcFoundOverFindableCls] = Alright(lUseParticleCuts[etpcFoundOverFindableCls]); + pc.fUseParticleCuts[etpcFractionSharedCls] = Alright(lUseParticleCuts[etpcFractionSharedCls]); + pc.fUseParticleCuts[etpcChi2NCl] = Alright(lUseParticleCuts[etpcChi2NCl]); + pc.fUseParticleCuts[edcaXY] = Alright(lUseParticleCuts[edcaXY]); + pc.fUseParticleCuts[edcaZ] = Alright(lUseParticleCuts[edcaZ]); + pc.fUseParticleCuts[ePDG] = Alright(lUseParticleCuts[ePDG]); + pc.fUseParticleCuts[etrackCutFlag] = Alright(lUseParticleCuts[etrackCutFlag]); + pc.fUseParticleCuts[etrackCutFlagFb1] = Alright(lUseParticleCuts[etrackCutFlagFb1]); + pc.fUseParticleCuts[etrackCutFlagFb2] = Alright(lUseParticleCuts[etrackCutFlagFb2]); + pc.fUseParticleCuts[eisQualityTrack] = Alright(lUseParticleCuts[eisQualityTrack]); + pc.fUseParticleCuts[eisPrimaryTrack] = Alright(lUseParticleCuts[eisPrimaryTrack]); + pc.fUseParticleCuts[eisInAcceptanceTrack] = Alright(lUseParticleCuts[eisInAcceptanceTrack]); + pc.fUseParticleCuts[eisGlobalTrack] = Alright(lUseParticleCuts[eisGlobalTrack]); + pc.fUseParticleCuts[eisPVContributor] = Alright(lUseParticleCuts[eisPVContributor]); + pc.fUseParticleCuts[ePtDependentDCAxyParameterization] = Alright(lUseParticleCuts[ePtDependentDCAxyParameterization]); + + // **) particles cuts defined via booleans: + pc.fUseParticleCuts[etrackCutFlag] = pc.fUseParticleCuts[etrackCutFlag] && cf_pc.cftrackCutFlag; + pc.fUseParticleCuts[etrackCutFlagFb1] = pc.fUseParticleCuts[etrackCutFlagFb1] && cf_pc.cftrackCutFlagFb1; + pc.fUseParticleCuts[etrackCutFlagFb2] = pc.fUseParticleCuts[etrackCutFlagFb2] && cf_pc.cftrackCutFlagFb2; + pc.fUseParticleCuts[eisQualityTrack] = pc.fUseParticleCuts[eisQualityTrack] && cf_pc.cfisQualityTrack; + pc.fUseParticleCuts[eisPrimaryTrack] = pc.fUseParticleCuts[eisPrimaryTrack] && cf_pc.cfisPrimaryTrack; + pc.fUseParticleCuts[eisInAcceptanceTrack] = pc.fUseParticleCuts[eisInAcceptanceTrack] && cf_pc.cfisInAcceptanceTrack; + pc.fUseParticleCuts[eisGlobalTrack] = pc.fUseParticleCuts[eisGlobalTrack] && cf_pc.cfisGlobalTrack; + pc.fUseParticleCuts[eisPVContributor] = pc.fUseParticleCuts[eisPVContributor] && cf_pc.cfisPVContributor; + + // **) particles cuts defined via [min, max): + auto lPhi = (std::vector)cf_pc.cfPhi; + pc.fdParticleCuts[ePhi][eMin] = lPhi[eMin]; + pc.fdParticleCuts[ePhi][eMax] = lPhi[eMax]; + + auto lPt = (std::vector)cf_pc.cfPt; + pc.fdParticleCuts[ePt][eMin] = lPt[eMin]; + pc.fdParticleCuts[ePt][eMax] = lPt[eMax]; + + auto lEta = (std::vector)cf_pc.cfEta; + pc.fdParticleCuts[eEta][eMin] = lEta[eMin]; + pc.fdParticleCuts[eEta][eMax] = lEta[eMax]; + + auto lCharge = (std::vector)cf_pc.cfCharge; + pc.fdParticleCuts[eCharge][eMin] = lCharge[eMin]; + pc.fdParticleCuts[eCharge][eMax] = lCharge[eMax]; + + auto ltpcNClsFindable = (std::vector)cf_pc.cftpcNClsFindable; + pc.fdParticleCuts[etpcNClsFindable][eMin] = ltpcNClsFindable[eMin]; + pc.fdParticleCuts[etpcNClsFindable][eMax] = ltpcNClsFindable[eMax]; + + auto ltpcNClsShared = (std::vector)cf_pc.cftpcNClsShared; + pc.fdParticleCuts[etpcNClsShared][eMin] = ltpcNClsShared[eMin]; + pc.fdParticleCuts[etpcNClsShared][eMax] = ltpcNClsShared[eMax]; + + auto litsChi2NCl = (std::vector)cf_pc.cfitsChi2NCl; + pc.fdParticleCuts[eitsChi2NCl][eMin] = litsChi2NCl[eMin]; + pc.fdParticleCuts[eitsChi2NCl][eMax] = litsChi2NCl[eMax]; + + auto ltpcNClsFound = (std::vector)cf_pc.cftpcNClsFound; + pc.fdParticleCuts[etpcNClsFound][eMin] = ltpcNClsFound[eMin]; + pc.fdParticleCuts[etpcNClsFound][eMax] = ltpcNClsFound[eMax]; + + auto ltpcNClsCrossedRows = (std::vector)cf_pc.cftpcNClsCrossedRows; + pc.fdParticleCuts[etpcNClsCrossedRows][eMin] = ltpcNClsCrossedRows[eMin]; + pc.fdParticleCuts[etpcNClsCrossedRows][eMax] = ltpcNClsCrossedRows[eMax]; + + auto litsNCls = (std::vector)cf_pc.cfitsNCls; + pc.fdParticleCuts[eitsNCls][eMin] = litsNCls[eMin]; + pc.fdParticleCuts[eitsNCls][eMax] = litsNCls[eMax]; + + auto litsNClsInnerBarrel = (std::vector)cf_pc.cfitsNClsInnerBarrel; + pc.fdParticleCuts[eitsNClsInnerBarrel][eMin] = litsNClsInnerBarrel[eMin]; + pc.fdParticleCuts[eitsNClsInnerBarrel][eMax] = litsNClsInnerBarrel[eMax]; + + auto ltpcCrossedRowsOverFindableCls = (std::vector)cf_pc.cftpcCrossedRowsOverFindableCls; + pc.fdParticleCuts[etpcCrossedRowsOverFindableCls][eMin] = ltpcCrossedRowsOverFindableCls[eMin]; + pc.fdParticleCuts[etpcCrossedRowsOverFindableCls][eMax] = ltpcCrossedRowsOverFindableCls[eMax]; + + auto ltpcFoundOverFindableCls = (std::vector)cf_pc.cftpcFoundOverFindableCls; + pc.fdParticleCuts[etpcFoundOverFindableCls][eMin] = ltpcFoundOverFindableCls[eMin]; + pc.fdParticleCuts[etpcFoundOverFindableCls][eMax] = ltpcFoundOverFindableCls[eMax]; + + auto ltpcFractionSharedCls = (std::vector)cf_pc.cftpcFractionSharedCls; + pc.fdParticleCuts[etpcFractionSharedCls][eMin] = ltpcFractionSharedCls[eMin]; + pc.fdParticleCuts[etpcFractionSharedCls][eMax] = ltpcFractionSharedCls[eMax]; + + auto ltpcChi2NCl = (std::vector)cf_pc.cftpcChi2NCl; + pc.fdParticleCuts[etpcChi2NCl][eMin] = ltpcChi2NCl[eMin]; + pc.fdParticleCuts[etpcChi2NCl][eMax] = ltpcChi2NCl[eMax]; + + auto ldcaXY = (std::vector)cf_pc.cfdcaXY; + pc.fdParticleCuts[edcaXY][eMin] = ldcaXY[eMin]; + pc.fdParticleCuts[edcaXY][eMax] = ldcaXY[eMax]; + + auto ldcaZ = (std::vector)cf_pc.cfdcaZ; + pc.fdParticleCuts[edcaZ][eMin] = ldcaZ[eMin]; + pc.fdParticleCuts[edcaZ][eMax] = ldcaZ[eMax]; + + auto lPDG = (std::vector)cf_pc.cfPDG; + pc.fdParticleCuts[ePDG][eMin] = lPDG[eMin]; + pc.fdParticleCuts[ePDG][eMax] = lPDG[eMax]; + + // **) particles cuts defined via string: + pc.fsParticleCuts[ePtDependentDCAxyParameterization] = cf_pc.cfPtDependentDCAxyParameterization; + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // void defaultCuts() + + //============================================================ + + void specificCuts(TString whichSpecificCuts) + { + // After default cuts are applied, on top of them apply analysis-specific cuts. Has to be called after defaultBinning() and defaultCuts(). + // Here I hardwire defalt cuts and settings for a given period which will overwrite whatever is set in configurables. + // When I do systematic checks, this option shall NOT be used, because values for some cuts which I plan to vary, are also hardwired here. + // Both event and particle cuts are hardwired here. As well as some other settings. + // For the time being, all specific cuts are defaulted and tuned for the latest reconstruction pass. + + // a) Mapping; + // b) Implementation of analysis-specific cuts. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // a) Mapping: + // I need this mapping, for the switch statement below. TBI 20241120 I could introduce a utility function for this as well... + eSpecificCuts specificCuts = eSpecificCuts_N; + if (whichSpecificCuts.EqualTo("LHC23zzh")) { + specificCuts = eLHC23zzh; + } else if (whichSpecificCuts.EqualTo("LHC24ar")) { + specificCuts = eLHC24ar; + } else if (whichSpecificCuts.EqualTo("LHC24as")) { + specificCuts = eLHC24as; + } else if (whichSpecificCuts.EqualTo("LHC15o")) { + specificCuts = eLHC15o; + } else if (whichSpecificCuts.EqualTo("Test")) { + specificCuts = eTestCuts; + } else { + LOGF(fatal, "\033[1;31m%s at line %d : whichSpecificCuts = %s is not supported \033[0m", __FUNCTION__, __LINE__, whichSpecificCuts.Data()); + } + + // b) Implementation of analysis-specific cuts: + // Remark #1: Whichever cuts start to repeat below across different case statements, promote them into defaultCuts(), i.e. hardwire those values in configurables. + // The idea is to keep here cuts only which are specific for particular analysis, and which are unlikely ever to change as a default cut for that particular analysis. + // Remark #2: Remember that the values for the cuts hardwired here overwrite the ones set as default values in configurables. + // If you want to reconfigure all cuts below manually via configurables, simply do not call specificCuts, i.e. set in JSON "cfUseSpecificCuts": "false" + // Therefore, if I want to vary some of these cuts via configurables as a part of systematics, I must set in JSON "cfUseSpecificCuts": "false" + // Remark #3: Most up-to-date documentation of each cut is in enum file. + switch (specificCuts) { + + case eLHC23zzh: { + + // In this branch I implement default cuts and settings for PbPb Run 3 datasets collected in 2023. + // If I change some cut here, keep in sync. with other branches (e.g. for 2024 data). + + // Event cuts: + ec.fUseEventCuts[eSel7] = false; + ec.fUseEventCuts[eSel8] = true; + ec.fUseEventCuts[eNoSameBunchPileup] = true; + ec.fUseEventCuts[eIsVertexITSTPC] = true; + ec.fUseEventCuts[eNoCollInTimeRangeStandard] = true; + ec.fUseEventCuts[eNoCollInTimeRangeStrict] = false; + ec.fUseEventCuts[eNoCollInRofStandard] = true; + ec.fUseEventCuts[eNoCollInRofStrict] = false; + ec.fUseEventCuts[eNoPileupTPC] = false; // Run 2 + ec.fUseEventCuts[eNoPileupFromSPD] = false; // Run 2 + ec.fUseEventCuts[eNoSPDOnVsOfPileup] = false; // Run 2 + + ec.fUseEventCuts[eInteractionRate] = false; // I set it to false by default, to prevent having the standard memory blow-up by default + ec.fdEventCuts[eInteractionRate][eMin] = 0.1; // there are some pathological non-physical events with IR = 0. See eCorrelationsVsInteractionRate_vs_ReferenceMultiplicity + ec.fdEventCuts[eInteractionRate][eMax] = 1000000000.; + + ec.fUseEventCuts[eRefMultVsNContrUp] = true; + ec.fUseEventCuts[eRefMultVsNContrLow] = true; + if (ec.fsEventCuts[eReferenceMultiplicityEstimator].EqualTo("MultFT0C")) { + ec.fsEventCuts[eRefMultVsNContrUp] = "1200. + 0.20*x"; // TBI 20250401 not fine-tune, just an example + ec.fsEventCuts[eRefMultVsNContrLow] = "-650. + 0.08*x"; // TBI 20250401 not fine-tune, just an example + // TBI 20250331 fine-tune this cut in the same spirit for other ref. mult. estimators + } + + ec.fUseEventCuts[eCentralityCorrelationsCut] = true; + ec.fsEventCuts[eCentralityCorrelationsCut] = "CentFT0C_CentFT0M"; + ec.fCentralityCorrelationsCutTreshold = 10.0; + ec.fCentralityCorrelationsCutVersion = "Absolute"; + + // Particle cuts: + pc.fUseParticleCuts[eitsNCls] = true; + pc.fdParticleCuts[eitsNCls][eMin] = 5.; + pc.fdParticleCuts[eitsNCls][eMax] = 1000.; + + pc.fUseParticleCuts[etpcNClsFound] = true; + pc.fdParticleCuts[etpcNClsFound][eMin] = 70.; + pc.fdParticleCuts[etpcNClsFound][eMax] = 1000.; + + pc.fUseParticleCuts[etpcNClsCrossedRows] = true; + pc.fdParticleCuts[etpcNClsCrossedRows][eMin] = 70.; + pc.fdParticleCuts[etpcNClsCrossedRows][eMax] = 1000.; + + pc.fUseParticleCuts[etpcCrossedRowsOverFindableCls] = true; + pc.fdParticleCuts[etpcCrossedRowsOverFindableCls][eMin] = 0.8; + pc.fdParticleCuts[etpcCrossedRowsOverFindableCls][eMax] = 1000.; + + pc.fUseParticleCuts[etpcFoundOverFindableCls] = true; + pc.fdParticleCuts[etpcFoundOverFindableCls][eMin] = 0.8; + pc.fdParticleCuts[etpcFoundOverFindableCls][eMax] = 1000.; + + pc.fUseParticleCuts[etpcFractionSharedCls] = true; + pc.fdParticleCuts[etpcFractionSharedCls][eMin] = -1000.; + pc.fdParticleCuts[etpcFractionSharedCls][eMax] = 0.4; + + pc.fUseParticleCuts[etpcChi2NCl] = true; + pc.fdParticleCuts[etpcChi2NCl][eMin] = -1000.; + pc.fdParticleCuts[etpcChi2NCl][eMax] = 4.0; + + pc.fUseParticleCuts[edcaXY] = true; + pc.fdParticleCuts[edcaXY][eMin] = -2.4; // TBI 20250401 check further + pc.fdParticleCuts[edcaXY][eMax] = 2.4; // TBI 20250401 check further + + pc.fUseParticleCuts[edcaZ] = true; + pc.fdParticleCuts[edcaZ][eMin] = -3.2; // TBI 20250401 check further + pc.fdParticleCuts[edcaZ][eMax] = 3.2; // TBI 20250401 check further + + pc.fUseParticleCuts[eisInAcceptanceTrack] = false; // see enum + pc.fUseParticleCuts[eisGlobalTrack] = false; // only for Run 2 + pc.fUseParticleCuts[eisPVContributor] = true; + + break; + } + + case eLHC24ar: + case eLHC24as: { + + // In this branch I implement default cuts and settings for PbPb Run 3 datasets collected in 2024: + // If I change some cut here, keep in sync. with other branches (e.g. for 2023 data). + // As of 20250207, all cuts are the same as for 2023, expect that here I do NOT use eIsGoodZvtxFT0vsPV and eNoHighMultCollInPrevRof + + // Event cuts: + ec.fUseEventCuts[eSel7] = false; + ec.fUseEventCuts[eSel8] = true; + ec.fUseEventCuts[eNoSameBunchPileup] = true; + ec.fUseEventCuts[eIsVertexITSTPC] = true; + ec.fUseEventCuts[eNoCollInTimeRangeStandard] = true; + ec.fUseEventCuts[eNoCollInTimeRangeStrict] = false; + ec.fUseEventCuts[eNoCollInRofStandard] = true; + ec.fUseEventCuts[eNoCollInRofStrict] = false; + ec.fUseEventCuts[eIsGoodZvtxFT0vsPV] = false; // diff commpared to 2023 + ec.fUseEventCuts[eNoHighMultCollInPrevRof] = false; // diff commpared to 2023 + ec.fUseEventCuts[eNoPileupTPC] = false; // Run 2 + ec.fUseEventCuts[eNoPileupFromSPD] = false; // Run 2 + ec.fUseEventCuts[eNoSPDOnVsOfPileup] = false; // Run 2 + + ec.fUseEventCuts[eInteractionRate] = false; // I set it to false by default, to prevent having the standard memory blow-up by default + ec.fdEventCuts[eInteractionRate][eMin] = 0.1; // there are some pathological non-physical events with IR = 0. See eCorrelationsVsInteractionRate_vs_ReferenceMultiplicity + ec.fdEventCuts[eInteractionRate][eMax] = 1000000000.; + + ec.fUseEventCuts[eRefMultVsNContrUp] = false; // TBI 20250331 set to true only when I fine-tune + ec.fUseEventCuts[eRefMultVsNContrLow] = false; // TBI 20250331 set to true only when I fine-tune + if (ec.fsEventCuts[eReferenceMultiplicityEstimator].EqualTo("MultFT0C")) { + ec.fsEventCuts[eRefMultVsNContrUp] = "..."; // TBI 20250329 I need to tune and validate for this dataset, and estimator + ec.fsEventCuts[eRefMultVsNContrLow] = "..."; // TBI 20250329 I need to tune and validate for this dataset, and estimator + // TBI 20250331 fine-tune this cut in the same spirit for other ref. mult. estimators + } + + ec.fUseEventCuts[eCentralityCorrelationsCut] = false; // TBI 20250104 yes, because in 2024 I can use only FT0C at the moment + ec.fsEventCuts[eCentralityCorrelationsCut] = "CentFT0C_CentFT0M"; + ec.fCentralityCorrelationsCutTreshold = 10.0; + ec.fCentralityCorrelationsCutVersion = "Absolute"; + + // Particle cuts: + pc.fUseParticleCuts[eitsNCls] = true; + pc.fdParticleCuts[eitsNCls][eMin] = 5.; + pc.fdParticleCuts[eitsNCls][eMax] = 1000.; + + pc.fUseParticleCuts[etpcNClsFound] = true; + pc.fdParticleCuts[etpcNClsFound][eMin] = 70.; + pc.fdParticleCuts[etpcNClsFound][eMax] = 1000.; + + pc.fUseParticleCuts[etpcNClsCrossedRows] = true; + pc.fdParticleCuts[etpcNClsCrossedRows][eMin] = 70.; + pc.fdParticleCuts[etpcNClsCrossedRows][eMax] = 1000.; + + pc.fUseParticleCuts[etpcCrossedRowsOverFindableCls] = true; + pc.fdParticleCuts[etpcCrossedRowsOverFindableCls][eMin] = 0.8; + pc.fdParticleCuts[etpcCrossedRowsOverFindableCls][eMax] = 1000.; + + pc.fUseParticleCuts[etpcFoundOverFindableCls] = true; + pc.fdParticleCuts[etpcFoundOverFindableCls][eMin] = 0.8; + pc.fdParticleCuts[etpcFoundOverFindableCls][eMax] = 1000.; + + pc.fUseParticleCuts[etpcFractionSharedCls] = true; + pc.fdParticleCuts[etpcFractionSharedCls][eMin] = -1000.; + pc.fdParticleCuts[etpcFractionSharedCls][eMax] = 0.4; + + pc.fUseParticleCuts[etpcChi2NCl] = true; + pc.fdParticleCuts[etpcChi2NCl][eMin] = -1000.; + pc.fdParticleCuts[etpcChi2NCl][eMax] = 4.0; + + pc.fUseParticleCuts[edcaXY] = true; + pc.fdParticleCuts[edcaXY][eMin] = -2.4; // TBI 20250401 check further + pc.fdParticleCuts[edcaXY][eMax] = 2.4; // TBI 20250401 check further + + pc.fUseParticleCuts[edcaZ] = true; + pc.fdParticleCuts[edcaZ][eMin] = -3.2; // TBI 20250401 check further + pc.fdParticleCuts[edcaZ][eMax] = 3.2; // TBI 20250401 check further + + pc.fUseParticleCuts[eisInAcceptanceTrack] = false; // see enum + pc.fUseParticleCuts[eisGlobalTrack] = false; // only for Run 2 + pc.fUseParticleCuts[eisPVContributor] = true; + + break; + } + + case eLHC15o: { + + // In this branch I implement default cuts and settings for Run 2 datasets: + + // Event cuts: + ec.fUseEventCuts[eOccupancy] = false; + ec.fUseEventCuts[eInteractionRate] = false; + ec.fUseEventCuts[eCurrentRunDuration] = false; + // ec.fUseEventCuts[eSel7] = true; // TBI 20250115 ehen i procees in "Rec" some converted Run 2 MC, it removes 99% of events, see enum + ec.fUseEventCuts[eSel8] = false; + ec.fUseEventCuts[eNoSameBunchPileup] = false; + ec.fUseEventCuts[eIsGoodZvtxFT0vsPV] = false; + ec.fUseEventCuts[eIsVertexITSTPC] = false; + ec.fUseEventCuts[eNoCollInTimeRangeStrict] = false; + ec.fUseEventCuts[eNoCollInRofStrict] = false; + ec.fUseEventCuts[eNoHighMultCollInPrevRof] = false; + ec.fUseEventCuts[eNoCollInTimeRangeStandard] = false; + ec.fUseEventCuts[eNoCollInRofStrict] = false; + ec.fUseEventCuts[eNoCollInRofStandard] = false; + ec.fUseEventCuts[eNoCollInRofStandard] = false; + ec.fUseEventCuts[eIsGoodITSLayer3] = false; + ec.fUseEventCuts[eIsGoodITSLayer0123] = false; + ec.fUseEventCuts[eIsGoodITSLayersAll] = false; + ec.fUseEventCuts[eFT0Bad] = false; + ec.fUseEventCuts[eITSBad] = false; + ec.fUseEventCuts[eITSLimAccMCRepr] = false; + ec.fUseEventCuts[eTPCBadTracking] = false; + ec.fUseEventCuts[eTPCLimAccMCRepr] = false; + ec.fUseEventCuts[eTPCBadPID] = false; + ec.fUseEventCuts[eTrigger] = true; + ec.fsEventCuts[eTrigger] = "kINT7"; // TBI 20250115 remember that it cannot be used when i procees in "Rec" some converted Run 2 MC, see enum + + ec.fsEventCuts[eReferenceMultiplicityEstimator] = "MultTracklets"; // default ref. mult. estimator in Run 2 + ec.fsEventCuts[eCentralityEstimator] = "CentRun2V0M"; // default centrality estimator in Run 2 + + ec.fUseEventCuts[eRefMultVsNContrUp] = true; + ec.fUseEventCuts[eRefMultVsNContrLow] = true; + if (ec.fsEventCuts[eReferenceMultiplicityEstimator].EqualTo("MultTracklets")) { + ec.fsEventCuts[eRefMultVsNContrUp] = "700. + 0.95*x"; // TBI 20250401 not fine-tune, just an example + ec.fsEventCuts[eRefMultVsNContrLow] = "-400. + 0.5*x"; // TBI 20250401 not fine-tune, just an example + // TBI 20250331 fine-tune this cut in the same spirit for other ref. mult. estimators + } + + ec.fUseEventCuts[eCentralityCorrelationsCut] = false; + ec.fsEventCuts[eCentralityCorrelationsCut] = "CentRun2V0M_CentRun2SPDTracklets"; + ec.fCentralityCorrelationsCutTreshold = 10.0; + ec.fCentralityCorrelationsCutVersion = "Absolute"; + + // ... + + // Particle cuts: + pc.fUseParticleCuts[eisInAcceptanceTrack] = false; // see enum + pc.fUseParticleCuts[etrackCutFlagFb1] = false; // only for Run 3 + pc.fUseParticleCuts[etrackCutFlagFb2] = false; // only for Run 3 + pc.fUseParticleCuts[eisPVContributor] = false; // only for Run 3 + + // The rest: + mupa.fCalculateCorrelationsAsFunctionOf[AFO_OCCUPANCY] = false; + mupa.fCalculateCorrelationsAsFunctionOf[AFO_INTERACTIONRATE] = false; + mupa.fCalculateCorrelationsAsFunctionOf[AFO_CURRENTRUNDURATION] = false; + + t0.fCalculateTest0AsFunctionOf[AFO_OCCUPANCY] = false; + t0.fCalculateTest0AsFunctionOf[AFO_INTERACTIONRATE] = false; + t0.fCalculateTest0AsFunctionOf[AFO_CURRENTRUNDURATION] = false; + + es.fCalculateEtaSeparationsAsFunctionOf[AFO_OCCUPANCY] = false; + es.fCalculateEtaSeparationsAsFunctionOf[AFO_INTERACTIONRATE] = false; + es.fCalculateEtaSeparationsAsFunctionOf[AFO_CURRENTRUNDURATION] = false; + + eh.fBookEventHistograms[eOccupancy] = false; + eh.fBookEventHistograms[eInteractionRate] = false; + eh.fBookEventHistograms[eCurrentRunDuration] = false; + + qa.fBookQAEventHistograms2D[eMultiplicity_vs_Occupancy] = false; + qa.fBookQAEventHistograms2D[eMultiplicity_vs_InteractionRate] = false; + qa.fBookQAEventHistograms2D[eReferenceMultiplicity_vs_Occupancy] = false; + qa.fBookQAEventHistograms2D[eReferenceMultiplicity_vs_InteractionRate] = false; + qa.fBookQAEventHistograms2D[eNContributors_vs_Occupancy] = false; + qa.fBookQAEventHistograms2D[eNContributors_vs_InteractionRate] = false; + qa.fBookQAEventHistograms2D[eCentrality_vs_Occupancy] = false; + qa.fBookQAEventHistograms2D[eCentrality_vs_InteractionRate] = false; + qa.fBookQAEventHistograms2D[eVertexZ_vs_Occupancy] = false; + qa.fBookQAEventHistograms2D[eVertexZ_vs_InteractionRate] = false; + qa.fBookQAEventHistograms2D[eMultiplicity_vs_FT0CAmplitudeOnFoundBC] = false; + qa.fBookQAEventHistograms2D[eCentFT0C_vs_FT0CAmplitudeOnFoundBC] = false; + qa.fBookQAEventHistograms2D[eCentFT0C_vs_CentFT0CVariant1] = false; + qa.fBookQAEventHistograms2D[eCentFT0C_vs_CentFT0M] = false; + qa.fBookQAEventHistograms2D[eCentFT0C_vs_CentFV0A] = false; + qa.fBookQAEventHistograms2D[eCentFT0C_vs_CentNTPV] = false; + qa.fBookQAEventHistograms2D[eCentFT0C_vs_CentNGlobal] = false; + qa.fBookQAEventHistograms2D[eCentFT0M_vs_CentNTPV] = false; + qa.fBookQAEventHistograms2D[eTrackOccupancyInTimeRange_vs_FT0COccupancyInTimeRange] = false; + + // ... + + break; + } + + // ... + + case eTestCuts: { + + // In this branch I implement default cuts and settings for minimal subscription, "processTest": "true in JSON + + // Event cuts: + // ec.fUseEventCuts[eSel7] = true; // TBI 20250115 ehen i procees in "Rec" some converted Run 2 MC, it removes 99% of events, see enum + ec.fUseEventCuts[eSel8] = false; + ec.fUseEventCuts[eNoSameBunchPileup] = false; + ec.fUseEventCuts[eIsGoodZvtxFT0vsPV] = false; + ec.fUseEventCuts[eIsVertexITSTPC] = false; + ec.fUseEventCuts[eNoCollInTimeRangeStrict] = false; + ec.fUseEventCuts[eNoCollInRofStrict] = false; + ec.fUseEventCuts[eNoHighMultCollInPrevRof] = false; + ec.fUseEventCuts[eNoCollInTimeRangeStandard] = false; + ec.fUseEventCuts[eNoCollInRofStrict] = false; + ec.fUseEventCuts[eNoCollInRofStandard] = false; + ec.fUseEventCuts[eNoCollInRofStandard] = false; + ec.fUseEventCuts[eIsGoodITSLayer3] = false; + ec.fUseEventCuts[eIsGoodITSLayer0123] = false; + ec.fUseEventCuts[eIsGoodITSLayersAll] = false; + ec.fUseEventCuts[eFT0Bad] = false; + ec.fUseEventCuts[eITSBad] = false; + ec.fUseEventCuts[eITSLimAccMCRepr] = false; + ec.fUseEventCuts[eTPCBadTracking] = false; + ec.fUseEventCuts[eTPCLimAccMCRepr] = false; + ec.fUseEventCuts[eTPCBadPID] = false; + + // ec.fUseEventCuts[eTrigger] = true; + // ec.fsEventCuts[eTrigger] = "kINT7"; // TBI 20250115 cannot be used when i procees in "Rec" some converted Run 2 MC, see enum + + // ... + + // Particle cuts: + pc.fUseParticleCuts[eisInAcceptanceTrack] = false; // see enum + pc.fUseParticleCuts[etrackCutFlagFb1] = false; // only for Run 3 + pc.fUseParticleCuts[etrackCutFlagFb2] = false; // only for Run 3 + pc.fUseParticleCuts[eisPVContributor] = false; // only for Run 3 + + // ... + + // The rest: + mupa.fCalculateCorrelationsAsFunctionOf[AFO_OCCUPANCY] = false; + mupa.fCalculateCorrelationsAsFunctionOf[AFO_INTERACTIONRATE] = false; + mupa.fCalculateCorrelationsAsFunctionOf[AFO_CURRENTRUNDURATION] = false; + + t0.fCalculateTest0AsFunctionOf[AFO_OCCUPANCY] = false; + t0.fCalculateTest0AsFunctionOf[AFO_INTERACTIONRATE] = false; + t0.fCalculateTest0AsFunctionOf[AFO_CURRENTRUNDURATION] = false; + + es.fCalculateEtaSeparationsAsFunctionOf[AFO_OCCUPANCY] = false; + es.fCalculateEtaSeparationsAsFunctionOf[AFO_INTERACTIONRATE] = false; + es.fCalculateEtaSeparationsAsFunctionOf[AFO_CURRENTRUNDURATION] = false; + + // ... + + break; + } + + default: { + LOGF(fatal, "\033[1;31m%s at line %d : specificCuts = %d is not supported yet \033[0m", __FUNCTION__, __LINE__, static_cast(specificCuts)); + break; + } + } // switch (specificCuts) + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // void specificCuts(const char* specificCutsName) + + //============================================================ + + void insanityChecksOnDefinitionsOfConfigurables() + { + // Do insanity checks on values obtained from configurables before using them in the remaining function. + // This is really important, because one misconfigured configurable (e.g. boolean set to string), causes the whole json config to die silently, and + // only default values from MuPa-Configurables.h are used. + // Here I only check if configurables are correctly defined, I do NOT here initialize local variables with configurables, that is done later. + // Example misconfiguration in JSON: + // "var": "true", => var = 1 + other configurables are processed correctly + // "var": "truee", => var = 0 + all settings in JSON for configurables are ingored silently + + // TBI 20241127 finalize this function eventually. This is not urgent, though, as only a check below on cfTaskIsConfiguredFromJson covers most cases already. + + // Remark: Ordering below reflects the ordering in Configurables.h, not in DataMembers.h + // a) Task configuration; + // b) QA; + // c) Event histograms; + // d) Event cuts; + // e) Particle histograms; + // f) Particle cuts; + // g) Q-vectors; + // h) Multiparticle correlations; + // i) Test0; + // j) Particle weights; + // k) Centrality weights; + // l) Nested loops; + // m) Toy NUA; + // n) Internal validation; + // o) Results histograms. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // a) Task configuration: + if (!TString(cf_tc.cfTaskIsConfiguredFromJson).EqualTo("yes")) { + LOGF(fatal, "\033[1;31m%s at line %d : configurable cfTaskIsConfiguredFromJson = \"%s\", but it has to be set to \"yes\" in JSON => most likely some other configurable is misconfigured and all remaining settings in JSON are ignored silently\033[0m", __FUNCTION__, __LINE__, TString(cf_tc.cfTaskIsConfiguredFromJson).Data()); + } + + if (cf_tc.cfUseSpecificCuts) { + LOGF(info, "\033[1;33m%s at line %d: !!!! WARNING !!!! cfUseSpecificCuts = true, all settings in the current config are ignored !!!! WARNING !!!! \033[0m", __FUNCTION__, __LINE__); + } + + // b) QA: + // ... + + // c) Event histograms: + // ... + + // d) Event cuts: + // ... + + // e) Particle histograms: + // ... + + // f) Particle cuts: + // ... + + // g) Q-vectors: + // ... + + // h) Multiparticle correlations: + // ... + + // i) Test0: + // ... + + // j) Particle weights: + // ... + + // k) Centrality weights: + // ... + + // l) Nested loops: + // ... + + // m) Toy NUA: + // ... + + // n) Internal validation: + // ... + + // o) Results histograms: + // ... + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // insanityChecksOnDefinitionsOfConfigurables() + + //============================================================ + + void insanityChecksBeforeBooking() + { + // Do insanity checks on configuration, binning and cuts. Values obtained from configurables are checked before being used in insanityChecksOnDefinitionsOfConfigurables(). + // Remember that here I cannot do insanity checks on local histograms, etc., because they are not booked yet. + // For those additional checks, use insanityChecksAfterBooking(). + + // a) Insanity checks on configuration; + // b) Ensure that Run 1/2 specific cuts and flags are used only in Run 1/2 (both data and sim); + // c) Ensure that Run 3 specific cuts and flags are used only in Run 3 (both data and sim); + // d) Insanity checks on binning; + // e) Insanity checks on events cuts; + // f) Insanity checks on Toy NUA; + // g) Insanity checks on internal validation; + // h) Insanity checks on results histograms. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // a) Insanity checks on configuration: + + // **) Dry run and internal validation are not meant to be run together: + if (tc.fDryRun && iv.fUseInternalValidation) { + LOGF(fatal, "\033[1;31m%s at line %d : Dry run and internal validation are not meant to be run together\033[0m", __FUNCTION__, __LINE__); + } + + // **) Cannot calculate multiparticle correlations, in case Q-vectors are not filled: + if (mupa.fCalculateCorrelations && !qv.fCalculateQvectors) { + LOGF(fatal, "\033[1;31m%s at line %d : Cannot calculate multiparticle correlations, in case Q-vectors are not calculated \033[0m", __FUNCTION__, __LINE__); + } + + // **) If some differential "correlations" flag is set to true, but the main fCalculateCorrelations is false, only print the warning that that differential correlations won't be calculated. + // This is not fatal, because this way I can turn off all differential "correlations" flags, just by setting fCalculateCorrelations to false, e.g. when I want to fill only control histograms. + for (int v = 0; v < eAsFunctionOf_N; v++) { + if (mupa.fCalculateCorrelationsAsFunctionOf[v] && !mupa.fCalculateCorrelations) { + LOGF(warning, "\033[1;33m%s at line %d : mupa.fCalculateCorrelationsAsFunctionOf[%d] is true, but mupa.fCalculateCorrelations is false. This differential correlations won't be calculated.\033[0m", __FUNCTION__, __LINE__, v); + } + } + + // **) Cannot calculate Test0, in case Q-vectors are not filled: + if (t0.fCalculateTest0 && !qv.fCalculateQvectors) { + LOGF(fatal, "\033[1;31m%s at line %d : Cannot calculate Test0, in case Q-vectors are not filled \033[0m", __FUNCTION__, __LINE__); + } + + // **) If some differential Test0 flag is set to true, but the main fCalculateTest0 is false, only print the warning that that differential Test0 won't be calculated. + // This is not fatal, because this way I can turn off all differential Test0 flags, just by setting fCalculateTest0 to false, e.g. when I want to fill only control histograms. + for (int v = 0; v < eAsFunctionOf_N; v++) { + if (t0.fCalculateTest0AsFunctionOf[v] && !t0.fCalculateTest0) { + LOGF(warning, "\033[1;33m%s at line %d : t0.fCalculateTest0AsFunctionOf[%d] is true, but t0.fCalculateTest0 is false. This differential Test0 won't be calculated.\033[0m", __FUNCTION__, __LINE__, v); + } + } + + // **) Enforce that if the fixed number of randomly selected tracks is used in the analysis, that Fisher-Yates algorithm is enabled: + if (tc.fFixedNumberOfRandomlySelectedTracks > 0 && !tc.fUseFisherYates) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m : Did you forget to enable Fisher-Yates algorithm?", __FUNCTION__, __LINE__); + } + + // **) Enforce that if the fixed number of randomly selected tracks is used that Toy NUA is disabled: + if (tc.fFixedNumberOfRandomlySelectedTracks > 0 && (nua.fApplyNUAPDF[ePhiNUAPDF] || nua.fApplyNUAPDF[ePtNUAPDF] || nua.fApplyNUAPDF[eEtaNUAPDF])) { + LOGF(fatal, "\033[1;31m%s at line %d : Not supported at the moment: use FixedNumberOfRandomlySelectedTracks + Toy NUA enabled.\nI cannot in an easy way ensure that ParticleCuts behave exactly the same in the Main and Banishment loops, because e.g. I call consequtively for same partcile gRandom->Uniform(...) in ParticleCuts, and that can't work.\033[0m", __FUNCTION__, __LINE__); + } + + // **) When it comes to DCAxy cut, ensure that either flat or pt-dependent cut is used, but not both: + if (pc.fUseParticleCuts[edcaXY] && pc.fUseParticleCuts[ePtDependentDCAxyParameterization]) { + LOGF(fatal, "\033[1;31m%s at line %d : use either flat or pt-dependent DCAxy cut, but not both \033[0m", __FUNCTION__, __LINE__); + } + + // **) Insanity check on individual flags: Make sure that only one process is set to true. + // If 2 or more are true, then corresponding process function is executed over ALL data, then another process(...) function, etc. + // Re-think this if it's possible to run different process(...)'s concurently over the same data. + if (static_cast(tc.fProcess[eProcessRec]) + static_cast(tc.fProcess[eProcessRecSim]) + static_cast(tc.fProcess[eProcessSim]) + static_cast(tc.fProcess[eProcessRec_Run2]) + static_cast(tc.fProcess[eProcessRecSim_Run2]) + static_cast(tc.fProcess[eProcessSim_Run2]) + static_cast(tc.fProcess[eProcessRec_Run1]) + static_cast(tc.fProcess[eProcessRecSim_Run1]) + static_cast(tc.fProcess[eProcessSim_Run1]) > 1) { + LOGF(info, "\033[1;31m Only one flag can be true: tc.fProcess[eProcessRec] = %d, tc.fProcess[eProcessRecSim] = %d, tc.fProcess[eProcessSim] = %d, tc.fProcess[eProcessRec_Run2] = %d, tc.fProcess[eProcessRecSim_Run2] = %d, tc.fProcess[eProcessSim_Run2] = %d, tc.fProcess[eProcessRec_Run1] = %d, tc.fProcess[eProcessRecSim_Run1] = %d, tc.fProcess[eProcessSim_Run1] = %d \033[0m", static_cast(tc.fProcess[eProcessRec]), static_cast(tc.fProcess[eProcessRecSim]), static_cast(tc.fProcess[eProcessSim]), static_cast(tc.fProcess[eProcessRec_Run2]), static_cast(tc.fProcess[eProcessRecSim_Run2]), static_cast(tc.fProcess[eProcessSim_Run2]), static_cast(tc.fProcess[eProcessRec_Run1]), static_cast(tc.fProcess[eProcessRecSim_Run1]), static_cast(tc.fProcess[eProcessSim_Run1])); + LOGF(fatal, "in function \033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + + // **) Insanity checks on event cuts: + + // **) This check is meant to prevent the case when I want to bailout for max number of events, but I do not fill event histograms: + if (ec.fdEventCuts[eNumberOfEvents][eMax] < 1e6) { // TBI 20241011 Do I need to tune 1000000000 + // If I do not want to bail out when max number of events is reached, then in the configurable I have e.g. cfNumberOfEvents{"cfNumberOfEvents", {-1, 1000000000} + // So if the upper limit is set to some number < 1e6, I want to bail out for that number of events. + // TBI 20241011 this is a bit shaky, but nevermind now... + if (!eh.fBookEventHistograms[eNumberOfEvents]) { + LOGF(fatal, "\033[1;31m%s at line %d : Bailout for max number of events cannot be done, unless eh.fBookEventHistograms[eNumberOfEvents] is true.\033[0m", __FUNCTION__, __LINE__); + } + } + + // **) Check if the trigger makes sense or was validated for this dataset: + if (ec.fUseEventCuts[eTrigger]) { + + // Validated and supported Run 3 triggers: + if (tc.fProcess[eProcessRec]) { + if (!ec.fsEventCuts[eTrigger].EqualTo("kTVXinTRD")) { + LOGF(fatal, "\033[1;31m%s at line %d : trigger \"%s\" is not internally validated or supported for Run 3. Add it to the list of supported triggers, if you really want to use that one.\033[0m", __FUNCTION__, __LINE__, ec.fsEventCuts[eTrigger].Data()); + } + } + + // Validated and supported Run 2 triggers: + if (tc.fProcess[eProcessRec_Run2]) { + if (!ec.fsEventCuts[eTrigger].EqualTo("kINT7")) { + // LOGF(fatal, "\033[1;31m%s at line %d : trigger \"%s\" is not internally validated/supported yet for Run 2. Add it to the list of supported triggers, if you really want to use that one.\033[0m", __FUNCTION__, __LINE__, ec.fsEventCuts[eTrigger].Data()); + } + } + + // Validated and supported Run 1 triggers: + // ... + + } // if (ec.fUseEventCuts[eTrigger]) { + + // **) Check if the cut on MinVertexDistanceFromIP makes sense: + if (ec.fUseEventCuts[eMinVertexDistanceFromIP]) { + if (!(ec.fdEventCuts[eMinVertexDistanceFromIP][eMin] > 0.)) { + LOGF(fatal, "\033[1;31m%s at line %d : trigger ec.fdEventCuts[eMinVertexDistanceFromIP][eMin] = %f must be positive. Check the setting of configurable cfMinVertexDistanceFromIP\033[0m", __FUNCTION__, __LINE__, ec.fdEventCuts[eMinVertexDistanceFromIP][eMin]); + } + } + + // **) Enforce the usage of particular trigger for this dataset: + // if (tc.fProcess[eProcessRec_Run2]) { + // TBI 20250115 Not really sure I need this - if I want to run only "Rec" over Monte Carlo, then obviously the condition below is pointless. + // Also here I need to be able automaticaly to determine whether I am processing real data or Monte Carlo, from the dataset itself. + // TBI 20240517 for the time being, here I am enforcing that "kINT7" is mandatory for Run 2 + // TBI 20241209 I still have to validate it for Run 1 converted real data => then expand if(...) statement above + + // commented out temporariy, see TBI 20250115 above + // if (!(ec.fUseEventCuts[eTrigger] && ec.fsEventCuts[eTrigger].EqualTo("kINT7"))) { + // LOGF(fatal, "\033[1;31m%s at line %d : trigger \"%s\" is not internally validated/supported yet. Add it to the list of supported triggers, if you really want to use that one.\033[0m", __FUNCTION__, __LINE__, ec.fsEventCuts[eTrigger].Data()); + // } else { + // LOGF(info, "\033[1;32m%s at line %d : WARNING => trigger \"%s\" can be used only on real converted Run 2 and Run 1 data. For MC converted Run 2 and Run 1 data, this trigger shouldn't be used.\033[0m", __FUNCTION__, __LINE__, ec.fsEventCuts[eTrigger].Data()); + // // TBI 20240517 I need here programmatic access to "event-selection-task" flags "isMC and "isRunMC" . Then I can directly bail out. + // } + // } + + // **) Ensure that fFloatingPointPrecision makes sense: + if (!(tc.fFloatingPointPrecision > 0.)) { + LOGF(fatal, "\033[1;31m%s at line %d : set fFloatingPointPrecision = %f to some small positive value, which will determine if two floats are the same \033[0m", __FUNCTION__, __LINE__, tc.fFloatingPointPrecision); + } + + // **) Ensure that fSequentialBailout makes sense: + if (!(tc.fSequentialBailout >= 0)) { + LOGF(fatal, "\033[1;31m%s at line %d : set fSequentialBailout = %d either to 0 (not used), or to positive integer.\033[0m", __FUNCTION__, __LINE__, tc.fSequentialBailout); + } + + // **) Ensure that I do not spill over with number of dimensions in sparse histograms: + if (eDiffPhiWeights_N > gMaxNumberSparseDimensions) { + LOGF(fatal, "\033[1;31m%s at line %d : set eDiffPhiWeights_N = %d is bigger than gMaxNumberSparseDimensions = %d\033[0m", __FUNCTION__, __LINE__, static_cast(eDiffPhiWeights_N), gMaxNumberSparseDimensions); + } + if (eDiffPtWeights_N > gMaxNumberSparseDimensions) { + LOGF(fatal, "\033[1;31m%s at line %d : set eDiffPtWeights_N = %d is bigger than gMaxNumberSparseDimensions = %d\033[0m", __FUNCTION__, __LINE__, static_cast(eDiffPtWeights_N), gMaxNumberSparseDimensions); + } + if (eDiffEtaWeights_N > gMaxNumberSparseDimensions) { + LOGF(fatal, "\033[1;31m%s at line %d : set eDiffEtaWeights_N = %d is bigger than gMaxNumberSparseDimensions = %d\033[0m", __FUNCTION__, __LINE__, static_cast(eDiffEtaWeights_N), gMaxNumberSparseDimensions); + } + + // ** For simulated data when fDatabasePDG is NOT used, I have to disable cut on charge, since that info is not available: + if ((tc.fProcess[eGenericRecSim] || tc.fProcess[eGenericSim]) && pc.fUseParticleCuts[eCharge] && !tc.fUseDatabasePDG) { + LOGF(fatal, "\033[1;31m%s at line %d : For simulated data when fDatabasePDG is NOT used, I have to disable cut on charge, since that info is not available.\033[0m", __FUNCTION__, __LINE__); + } + // ** Make sure I am using fDatabasePDG only over Monte Carlo data: + if (tc.fUseDatabasePDG && !(tc.fProcess[eGenericRecSim] || tc.fProcess[eGenericSim])) { + LOGF(fatal, "\033[1;31m%s at line %d : Use fDatabasePDG only over Monte Carlo datasets.\033[0m", __FUNCTION__, __LINE__); + } + + // b) Ensure that Run 1/2 specific cuts and flags are used only in Run 1/2 (both data and sim): + // **) Ensure that eSel7 is used only for converted Run 2 and Run 1 (both data and sim): + if (ec.fUseEventCuts[eSel7]) { + if (!(tc.fProcess[eProcessRec_Run2] || tc.fProcess[eProcessRecSim_Run2] || tc.fProcess[eProcessSim_Run2] || tc.fProcess[eProcessRec_Run1] || tc.fProcess[eProcessRecSim_Run1] || tc.fProcess[eProcessSim_Run1])) { + LOGF(fatal, "\033[1;31m%s at line %d : use fSel7 for Run 2 data and MC\033[0m", __FUNCTION__, __LINE__); + } + } + + // **) Supported reference multiplicity estimators for Run 1 and 2 are enlisted here: + if (tc.fProcess[eProcessRec_Run2] || tc.fProcess[eProcessRecSim_Run2] || tc.fProcess[eProcessRec_Run1] || tc.fProcess[eProcessRecSim_Run1]) { + if (!(ec.fsEventCuts[eReferenceMultiplicityEstimator].EqualTo("MultTracklets", TString::kIgnoreCase))) { + LOGF(fatal, "\033[1;31m%s at line %d : reference multiplicity estimator = %s is not supported for Run 1 and 2 analysis.\nUse \"MultTracklets\"\033[0m", __FUNCTION__, __LINE__, ec.fsEventCuts[eReferenceMultiplicityEstimator].Data()); + } + } else if (tc.fProcess[eProcessSim_Run2] || tc.fProcess[eProcessSim_Run1]) { + LOGF(fatal, "\033[1;31m%s at line %d : eProcessSim is not validated yet \033[0m", __FUNCTION__, __LINE__); + } + + // **) Supported centrality estimators for Run 1 and 2 are enlisted here: + if (tc.fProcess[eProcessRec_Run2] || tc.fProcess[eProcessRecSim_Run2] || tc.fProcess[eProcessSim_Run2] || tc.fProcess[eProcessRec_Run1] || tc.fProcess[eProcessRecSim_Run1] || tc.fProcess[eProcessSim_Run1]) { + if (!(ec.fsEventCuts[eCentralityEstimator].EqualTo("centRun2V0M", TString::kIgnoreCase) || + ec.fsEventCuts[eCentralityEstimator].EqualTo("centRun2SPDTracklets", TString::kIgnoreCase))) { + LOGF(fatal, "\033[1;31m%s at line %d : centrality estimator = %s is not supported for converted Run 2 and Run 1 analysis.\nUse either \"centRun2V0M\" or \"centRun2SPDTracklets\" (case sensitive!) \033[0m", __FUNCTION__, __LINE__, ec.fsEventCuts[eCentralityEstimator].Data()); + } + } + + // **) Protection against particle cuts which are available, but not yet validated, or are meaningless, in Run 2 and 1: + if (tc.fProcess[eProcessRec_Run2] || tc.fProcess[eProcessRecSim_Run2] || tc.fProcess[eProcessSim_Run2] || tc.fProcess[eProcessRec_Run1] || tc.fProcess[eProcessRecSim_Run1] || tc.fProcess[eProcessSim_Run1]) { + if (pc.fUseParticleCuts[etrackCutFlag]) { + LOGF(fatal, "\033[1;31m%s at line %d : particle cut etrackCutFlag is not validated, as of 20250113 it has no effect in Run 2 and Run 1 \033[0m", __FUNCTION__, __LINE__); + } + if (pc.fUseParticleCuts[etrackCutFlagFb1]) { + LOGF(fatal, "\033[1;31m%s at line %d : particle cut etrackCutFlagFb1 is not validated, as of 20250113 it kills all reconstructed tracks in Run 2 and Run 1 \033[0m", __FUNCTION__, __LINE__); + } + if (pc.fUseParticleCuts[etrackCutFlagFb2]) { + LOGF(fatal, "\033[1;31m%s at line %d : particle cut etrackCutFlagFb2 is not validated, as of 20250113 it kills all reconstructed tracks in Run 2 and Run 1 \033[0m", __FUNCTION__, __LINE__); + } + } + + // **) Print a warning if kINT7 trigger is not used in reconstructed Run 2: + // TBI 20250318 shall I expand the check also to Run 1? In 2011 there were dedicated kCentral and kSemiCentral triggers only... + // TBI 20250318 shall I make it fatal instead? Without this trigger, a lot of histos are just meaningles (e.g. nContributores vs centrality, etc.) + if (tc.fProcess[eProcessRec_Run2]) { + if (!(ec.fUseEventCuts[eTrigger] && ec.fsEventCuts[eTrigger].EqualTo("kINT7"))) { + LOGF(warning, "\033[1;31m%s at line %d : kINT7 trigger in Run 2 is not selected - by default it should be used.\033[0m", __FUNCTION__, __LINE__); + } + } + + // **) Bail out if kINT7 trigger is used in Run 2 Monte Carlo: + // TBI 20250318 shall I expand the check also to Run 1? In 2011 there were dedicated kCentral and kSemiCentral triggers only... + if (tc.fProcess[eProcessRecSim_Run2] || tc.fProcess[eProcessSim_Run2]) { + if (ec.fUseEventCuts[eTrigger] && ec.fsEventCuts[eTrigger].EqualTo("kINT7")) { + LOGF(fatal, "\033[1;31m%s at line %d : kINT7 trigger in Run 2 Monte Carlo is not validated - use it at your own peril.\033[0m", __FUNCTION__, __LINE__); + } + } + + if (ec.fUseEventCuts[eNoPileupTPC]) { + if (tc.fProcess[eProcessRec] || tc.fProcess[eProcessRecSim] || tc.fProcess[eProcessSim]) { + LOGF(fatal, "\033[1;31m%s at line %d : cannot use NoPileupTPC in Run 3\033[0m", __FUNCTION__, __LINE__); + } + } + + if (ec.fUseEventCuts[eNoPileupFromSPD]) { + if (tc.fProcess[eProcessRec] || tc.fProcess[eProcessRecSim] || tc.fProcess[eProcessSim]) { + LOGF(fatal, "\033[1;31m%s at line %d : cannot use NoPileupFromSPD in Run 3\033[0m", __FUNCTION__, __LINE__); + } + } + + if (ec.fUseEventCuts[eNoSPDOnVsOfPileup]) { + if (tc.fProcess[eProcessRec] || tc.fProcess[eProcessRecSim] || tc.fProcess[eProcessSim]) { + LOGF(fatal, "\033[1;31m%s at line %d : cannot use NoSPDOnVsOfPileup in Run 3\033[0m", __FUNCTION__, __LINE__); + } + } + + // ... + + // c) Ensure that Run 3 specific cuts and flags are used only in Run 3 (both data and sim): + // **) Ensure that eSel8 is used only in Run 3 (both data and sim): + if (ec.fUseEventCuts[eSel8]) { + if (!(tc.fProcess[eProcessRec] || tc.fProcess[eProcessRecSim] || tc.fProcess[eProcessSim] || tc.fProcess[eProcessQA])) { + LOGF(fatal, "\033[1;31m%s at line %d : use eSel8 only for Run 3 data and MC\033[0m", __FUNCTION__, __LINE__); + } + } + + if (ec.fUseEventCuts[eNoSameBunchPileup]) { + if (!(tc.fProcess[eProcessRec] || tc.fProcess[eProcessRecSim] || tc.fProcess[eProcessSim] || tc.fProcess[eProcessQA])) { + LOGF(fatal, "\033[1;31m%s at line %d : use eNoSameBunchPileup only for Run 3 data and MC\033[0m", __FUNCTION__, __LINE__); + } + } + + if (ec.fUseEventCuts[eIsGoodZvtxFT0vsPV]) { + if (!(tc.fProcess[eProcessRec] || tc.fProcess[eProcessRecSim] || tc.fProcess[eProcessSim] || tc.fProcess[eProcessQA])) { + LOGF(fatal, "\033[1;31m%s at line %d : use eIsGoodZvtxFT0vsPV only for Run 3 data and MC\033[0m", __FUNCTION__, __LINE__); + } + } + + if (ec.fUseEventCuts[eIsVertexITSTPC]) { + if (!(tc.fProcess[eProcessRec] || tc.fProcess[eProcessRecSim] || tc.fProcess[eProcessSim] || tc.fProcess[eProcessQA])) { + LOGF(fatal, "\033[1;31m%s at line %d : use eIsVertexITSTPC only for Run 3 data and MC\033[0m", __FUNCTION__, __LINE__); + } + } + + if (ec.fUseEventCuts[eIsVertexTOFmatched]) { + if (!(tc.fProcess[eProcessRec] || tc.fProcess[eProcessRecSim] || tc.fProcess[eProcessSim] || tc.fProcess[eProcessQA])) { + LOGF(fatal, "\033[1;31m%s at line %d : use eIsVertexTOFmatched only for Run 3 data and MC\033[0m", __FUNCTION__, __LINE__); + } + } + + if (ec.fUseEventCuts[eIsVertexTRDmatched]) { + if (!(tc.fProcess[eProcessRec] || tc.fProcess[eProcessRecSim] || tc.fProcess[eProcessSim] || tc.fProcess[eProcessQA])) { + LOGF(fatal, "\033[1;31m%s at line %d : use eIsVertexTRDmatched only for Run 3 data and MC\033[0m", __FUNCTION__, __LINE__); + } + } + + if (ec.fUseEventCuts[eNoCollInTimeRangeStrict]) { + if (!(tc.fProcess[eProcessRec] || tc.fProcess[eProcessRecSim] || tc.fProcess[eProcessSim] || tc.fProcess[eProcessQA])) { + LOGF(fatal, "\033[1;31m%s at line %d : use eNoCollInTimeRangeStrict only for Run 3 data and MC\033[0m", __FUNCTION__, __LINE__); + } + } + + if (ec.fUseEventCuts[eNoCollInTimeRangeStandard]) { + if (!(tc.fProcess[eProcessRec] || tc.fProcess[eProcessRecSim] || tc.fProcess[eProcessSim] || tc.fProcess[eProcessQA])) { + LOGF(fatal, "\033[1;31m%s at line %d : use eNoCollInTimeRangeStandard only for Run 3 data and MC\033[0m", __FUNCTION__, __LINE__); + } + } + + if (ec.fUseEventCuts[eNoCollInRofStrict]) { + if (!(tc.fProcess[eProcessRec] || tc.fProcess[eProcessRecSim] || tc.fProcess[eProcessSim] || tc.fProcess[eProcessQA])) { + LOGF(fatal, "\033[1;31m%s at line %d : use eNoCollInRofStrict only for Run 3 data and MC\033[0m", __FUNCTION__, __LINE__); + } + } + + if (ec.fUseEventCuts[eNoCollInRofStandard]) { + if (!(tc.fProcess[eProcessRec] || tc.fProcess[eProcessRecSim] || tc.fProcess[eProcessSim] || tc.fProcess[eProcessQA])) { + LOGF(fatal, "\033[1;31m%s at line %d : use eNoCollInRofStandard only for Run 3 data and MC\033[0m", __FUNCTION__, __LINE__); + } + } + + if (ec.fUseEventCuts[eNoHighMultCollInPrevRof]) { + if (!(tc.fProcess[eProcessRec] || tc.fProcess[eProcessRecSim] || tc.fProcess[eProcessSim] || tc.fProcess[eProcessQA])) { + LOGF(fatal, "\033[1;31m%s at line %d : use eNoHighMultCollInPrevRof only for Run 3 data and MC\033[0m", __FUNCTION__, __LINE__); + } + } + + if (ec.fUseEventCuts[eIsGoodITSLayer3]) { + if (!(tc.fProcess[eProcessRec] || tc.fProcess[eProcessRecSim] || tc.fProcess[eProcessSim] || tc.fProcess[eProcessQA])) { + LOGF(fatal, "\033[1;31m%s at line %d : use eIsGoodITSLayer3 only for Run 3 data and MC\033[0m", __FUNCTION__, __LINE__); + } + } + + if (ec.fUseEventCuts[eIsGoodITSLayer0123]) { + if (!(tc.fProcess[eProcessRec] || tc.fProcess[eProcessRecSim] || tc.fProcess[eProcessSim] || tc.fProcess[eProcessQA])) { + LOGF(fatal, "\033[1;31m%s at line %d : use eIsGoodITSLayer0123 only for Run 3 data and MC\033[0m", __FUNCTION__, __LINE__); + } + } + + if (ec.fUseEventCuts[eIsGoodITSLayersAll]) { + if (!(tc.fProcess[eProcessRec] || tc.fProcess[eProcessRecSim] || tc.fProcess[eProcessSim] || tc.fProcess[eProcessQA])) { + LOGF(fatal, "\033[1;31m%s at line %d : use eIsGoodITSLayersAll only for Run 3 data and MC\033[0m", __FUNCTION__, __LINE__); + } + } + + if (ec.fUseEventCuts[eFT0Bad] || ec.fUseEventCuts[eITSBad] || ec.fUseEventCuts[eITSLimAccMCRepr] || ec.fUseEventCuts[eTPCBadTracking] || ec.fUseEventCuts[eTPCLimAccMCRepr] || ec.fUseEventCuts[eTPCBadPID]) { + if (!(tc.fProcess[eProcessRec] || tc.fProcess[eProcessRecSim] || tc.fProcess[eProcessSim] || tc.fProcess[eProcessQA])) { + LOGF(fatal, "\033[1;31m%s at line %d : use eFT0Bad, eITSBad, eITSLimAccMCRepr, eTPCBadTracking, eTPCLimAccMCRepr, eTPCBadPID only for Run 3 data and MC\033[0m", __FUNCTION__, __LINE__); + } + } + + // **) Supported reference multiplicity estimators for Run 3 are enlisted here: + if (tc.fProcess[eProcessRec] || tc.fProcess[eProcessRecSim] || tc.fProcess[eProcessQA]) { + if (!(ec.fsEventCuts[eReferenceMultiplicityEstimator].EqualTo("MultTPC", TString::kIgnoreCase) || + ec.fsEventCuts[eReferenceMultiplicityEstimator].EqualTo("MultFV0M", TString::kIgnoreCase) || + ec.fsEventCuts[eReferenceMultiplicityEstimator].EqualTo("MultFT0C", TString::kIgnoreCase) || + ec.fsEventCuts[eReferenceMultiplicityEstimator].EqualTo("MultFT0M", TString::kIgnoreCase) || + ec.fsEventCuts[eReferenceMultiplicityEstimator].EqualTo("MultNTracksPV", TString::kIgnoreCase))) { + LOGF(fatal, "\033[1;31m%s at line %d : reference multiplicity estimator = %s is not supported yet for Run 3 analysis.\nUse \"MultTPC\", \"MultFV0M\", \"MultFT0C\", \"MultFT0M\" or \"MultNTracksPV\"\033[0m", __FUNCTION__, __LINE__, ec.fsEventCuts[eReferenceMultiplicityEstimator].Data()); + } + } else if (tc.fProcess[eProcessSim]) { + LOGF(fatal, "\033[1;31m%s at line %d : eProcessSim is not validated yet \033[0m", __FUNCTION__, __LINE__); + } + + // **) Supported centrality estimators for Run 3 are enlisted here: + if (tc.fProcess[eProcessRec] || tc.fProcess[eProcessRecSim] || tc.fProcess[eProcessQA]) { + if (!(ec.fsEventCuts[eCentralityEstimator].EqualTo("centFT0C", TString::kIgnoreCase) || + ec.fsEventCuts[eCentralityEstimator].EqualTo("centFT0CVariant1", TString::kIgnoreCase) || + ec.fsEventCuts[eCentralityEstimator].EqualTo("centFT0M", TString::kIgnoreCase) || + ec.fsEventCuts[eCentralityEstimator].EqualTo("centFV0A", TString::kIgnoreCase) || + ec.fsEventCuts[eCentralityEstimator].EqualTo("centNTPV", TString::kIgnoreCase) || + ec.fsEventCuts[eCentralityEstimator].EqualTo("centNGlobal", TString::kIgnoreCase))) { + LOGF(fatal, "\033[1;31m%s at line %d : centrality estimator = %s is not supported yet for Run 3 analysis.\nUse \"centFT0C\", \"centFT0CVariant1\", \"centFT0M\", \"centFV0A\", \"centNTPV\", pr , \"centNGlobal\"\033[0m", __FUNCTION__, __LINE__, ec.fsEventCuts[eCentralityEstimator].Data()); + } + } else if (tc.fProcess[eProcessSim]) { + LOGF(fatal, "\033[1;31m%s at line %d : eProcessSim is not validated yet \033[0m", __FUNCTION__, __LINE__); + } + + // **) Supported occupancy estimators for Run 3 are enlisted here: + if (tc.fProcess[eProcessRec] || tc.fProcess[eProcessRecSim] || tc.fProcess[eProcessQA]) { + if (!(ec.fsEventCuts[eOccupancyEstimator].EqualTo("TrackOccupancyInTimeRange", TString::kIgnoreCase) || + ec.fsEventCuts[eOccupancyEstimator].EqualTo("FT0COccupancyInTimeRange", TString::kIgnoreCase))) { + LOGF(fatal, "\033[1;31m%s at line %d : occupancy estimator = %s is not supported yet for Run 3 analysis. \033[0m", __FUNCTION__, __LINE__, ec.fsEventCuts[eOccupancyEstimator].Data()); + } + } + + // **) Protection against particle cuts which are available, but not yet validated, or are meaningless, in Run 3: + if (tc.fProcess[eProcessRec] || tc.fProcess[eProcessRecSim] || tc.fProcess[eProcessSim] || tc.fProcess[eProcessQA]) { + if (pc.fUseParticleCuts[etrackCutFlag]) { + LOGF(fatal, "\033[1;31m%s at line %d : particle cut trackCutFlag is not validated in Run 3 as of 20250113 => it has no effect\033[0m", __FUNCTION__, __LINE__); + } + if (pc.fUseParticleCuts[eisQualityTrack]) { + LOGF(fatal, "\033[1;31m%s at line %d : particle cut isQualityTrack is not validated in Run 3 as of 20250113 => it kills all reconstructed tracks \033[0m", __FUNCTION__, __LINE__); + } + if (pc.fUseParticleCuts[eisGlobalTrack]) { + LOGF(fatal, "\033[1;31m%s at line %d : particle cut isGlobalTrack cannot be used in Run 3 => it kills all reconstructed tracks.\n To select global track in Run 3, use etrackCutFlagFb1 or etrackCutFlagFb2, see documentation in enum\033[0m", __FUNCTION__, __LINE__); + } + } + + // **) Protection on particle cuts which can be used only in Run 3: + // trackCutFlag, trackCutFlagFb1, trackCutFlagFb2 => use only one at the time + if (static_cast(pc.fUseParticleCuts[etrackCutFlag]) + static_cast(pc.fUseParticleCuts[etrackCutFlagFb1]) + static_cast(pc.fUseParticleCuts[etrackCutFlagFb2]) >= 2) { + LOGF(fatal, "\033[1;31m%s at line %d : use only one of trackCutFlag, trackCutFlagFb1, trackCutFlagFb2 at time. \033[0m", __FUNCTION__, __LINE__); + } + + // isPVContributor: + if (pc.fUseParticleCuts[eisPVContributor]) { + if (!(tc.fProcess[eProcessRec] || tc.fProcess[eProcessRecSim] || tc.fProcess[eProcessSim] || tc.fProcess[eProcessQA])) { + LOGF(fatal, "\033[1;31m%s at line %d : particle cut isPVContributor can be used only in Run 3\033[0m", __FUNCTION__, __LINE__); + } + } + + // **) Protection for histograms which are meaningfull only in Run 3: + // ***) interaction rate is available only in Run 3: + if (!(tc.fProcess[eProcessRec] || tc.fProcess[eProcessRecSim] || tc.fProcess[eProcessSim] || tc.fProcess[eProcessQA])) { + if (qa.fFillQACorrelationsVsInteractionRateVsProfiles2D) { + LOGF(fatal, "\033[1;31m%s at line %d : fFillQACorrelationsVsInteractionRateVsProfiles2D can be used only in Run 3, because only there ir is available.\033[0m", __FUNCTION__, __LINE__); + } + if (qa.fFillQAParticleEventHistograms2D) { + LOGF(fatal, "\033[1;31m%s at line %d : qa.fFillQAParticleEventHistograms2D can be used only in Run 3, because only there crd is available.\033[0m", __FUNCTION__, __LINE__); + } + // ... + } // if (! (tc.fProcess[eProcessRec] || tc.fProcess[eProcessRecSim] || tc.fProcess[eProcessSim])) { + + // ... + + // d) Insanity checks on binning: + // ... + + // e) Insanity checks on events cuts: + if (ec.fsEventCuts[eMultiplicityEstimator].EqualTo("ReferenceMultiplicity", TString::kIgnoreCase) && ec.fUseEventCuts[eMultiplicity]) { + LOGF(fatal, "\033[1;31m%s at line %d : use ec.fUseEventCuts[eMultiplicity] only when eMultiplicityEstimator = SelectedTracks. Otherwise, things can happen... \033[0m", __FUNCTION__, __LINE__); + } + // ... + + // f) Insanity checks on Toy NUA: + // ... + + // g) Insanity checks on internal validation: + // Remark: I check here only in the settings I could define in defaultConfiguration(). + // The other insanity checks are in bookInternalValidationHistograms() or in insanityChecksAfterBooking() + if (iv.fUseInternalValidation) { + if (iv.fnEventsInternalValidation <= 0) { + LOGF(fatal, "\033[1;31m%s at line %d : iv.fnEventsInternalValidation <= 0 => Set number of events to positive integer\033[0m", __FUNCTION__, __LINE__); + } + + if (!(iv.fHarmonicsOptionInternalValidation->EqualTo("constant", TString::kIgnoreCase) || + iv.fHarmonicsOptionInternalValidation->EqualTo("correlated", TString::kIgnoreCase) || + iv.fHarmonicsOptionInternalValidation->EqualTo("persistent", TString::kIgnoreCase) || + iv.fHarmonicsOptionInternalValidation->EqualTo("ptDependent", TString::kIgnoreCase) || + iv.fHarmonicsOptionInternalValidation->EqualTo("ptEtaDependent", TString::kIgnoreCase))) { + LOGF(fatal, "\033[1;31m%s at line %d : fHarmonicsOptionInternalValidation = %s is not supported. \033[0m", __FUNCTION__, __LINE__, iv.fHarmonicsOptionInternalValidation->Data()); + } + + if (iv.fRescaleWithTheoreticalInput && (nl.fCalculateNestedLoops || nl.fCalculateCustomNestedLoops || nl.fCalculateKineCustomNestedLoops)) { + LOGF(fatal, "\033[1;31m%s at line %d : rescaling with theoretical input is not supported when cross-check is done with nested loops. \033[0m", __FUNCTION__, __LINE__); + } + + if (ec.fsEventCuts[eMultiplicityEstimator].EqualTo("ReferenceMultiplicity", TString::kIgnoreCase)) { + LOGF(fatal, "\033[1;31m%s at line %d : in IV eMultiplicityEstimator cannot be set to \"ReferenceMultiplicity\" (yet) \033[0m", __FUNCTION__, __LINE__); + } + + if (!tc.fCalculateAsFunctionOf[AFO_PT] && pc.fUseParticleCuts[ePt]) { + LOGF(fatal, "\033[1;31m%s at line %d : in IV you do not calculate vs pt, but the cut on pt is on in IV\033[0m", __FUNCTION__, __LINE__); + } + + if (!tc.fCalculateAsFunctionOf[AFO_ETA] && pc.fUseParticleCuts[eEta]) { + LOGF(fatal, "\033[1;31m%s at line %d : in IV you do not calculate vs eta, but the cut on eta is on in IV\033[0m", __FUNCTION__, __LINE__); + } + + if (!tc.fCalculateAsFunctionOf[AFO_CHARGE] && pc.fUseParticleCuts[eCharge]) { + LOGF(fatal, "\033[1;31m%s at line %d : in IV you do not calculate vs charge, but the cut on charge is on in IV\033[0m", __FUNCTION__, __LINE__); + } + + } // if (iv.fUseInternalValidation) { + + // h) Insanity checks on results histograms: + // **) Check if all arrays are initialized until the end: + for (int afo = 0; afo < eAsFunctionOf_N; afo++) { + if (res.fResultsProXaxisTitle[afo].EqualTo("")) { + LOGF(fatal, "\033[1;31m%s at line %d : res.fResultsProXaxisTitle[%d] is empty.\033[0m", __FUNCTION__, __LINE__, afo); + } + + if (res.fResultsProRawName[afo].EqualTo("")) { + LOGF(fatal, "\033[1;31m%s at line %d : res.fResultsProRawName[%d] is empty.\033[0m", __FUNCTION__, __LINE__, afo); + } + } // for(int afo = 0; afo < eAsFunctionOf_N; afo++) { + + // ... + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // void insanityChecksBeforeBooking() + + //============================================================ + + void insanityChecksAfterBooking() + { + // Do insanity checks on all booked histograms, etc., + // Configuration, binning and cuts are checked already before booking in insanityChecksBeforeBooking(). + + // a) Insanity checks on booking; + // b) Insanity checks on internal validation; + // c) Insanity checks on results histograms; + // ... + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // a) Insanity checks on booking: + + // **) Check that the last bin is not empty in fBasePro, and that there is no underflow or overflow bins: + if (std::abs(fBasePro->GetBinContent(0)) > 0.) { + LOGF(fatal, "\033[1;31m%s at line %d : In \"fBasePro\" something was filled in the underflow, check the booking of this hostogram. \033[0m", __FUNCTION__, __LINE__); + } + if (std::abs(fBasePro->GetBinContent(eConfiguration_N)) > 0.) { + LOGF(fatal, "\033[1;31m%s at line %d : In \"fBasePro\" something was filled in the overflow, check the booking of this hostogram. \033[0m", __FUNCTION__, __LINE__); + } + + // ... + + // b) Insanity checks on internal validation: + if (iv.fUseInternalValidation) { + + // **) Check that rescaling is used only when it makes sense: + if (iv.fRescaleWithTheoreticalInput && iv.fHarmonicsOptionInternalValidation->EqualTo("correlated")) { + LOGF(fatal, "\033[1;31m%s at line %d : rescaling with theoretical input doesn't make sanse for fHarmonicsOptionInternalValidation = \"correlated\". \033[0m", __FUNCTION__, __LINE__); + } + if (iv.fRescaleWithTheoreticalInput && iv.fHarmonicsOptionInternalValidation->EqualTo("persistent")) { + LOGF(fatal, "\033[1;31m%s at line %d : rescaling with theoretical input doesn't make sanse for fHarmonicsOptionInternalValidation = \"persistent\". \033[0m", __FUNCTION__, __LINE__); + } + if (iv.fRescaleWithTheoreticalInput && iv.fHarmonicsOptionInternalValidation->EqualTo("ptDependent")) { + LOGF(fatal, "\033[1;31m%s at line %d : rescaling with theoretical input doesn't make sanse for fHarmonicsOptionInternalValidation = \"ptDependent\". \033[0m", __FUNCTION__, __LINE__); + } + if (iv.fRescaleWithTheoreticalInput && iv.fHarmonicsOptionInternalValidation->EqualTo("ptEtaDependent")) { + LOGF(fatal, "\033[1;31m%s at line %d : rescaling with theoretical input doesn't make sanse for fHarmonicsOptionInternalValidation = \"ptEtaDependent\". \033[0m", __FUNCTION__, __LINE__); + } + + // **) Print a warning if this histogram is not booked: + if (!eh.fEventHistograms[eNumberOfEvents][eSim][eAfter]) { + LOGF(warning, "\033[1;31m%s at line %d : eh.fEventHistograms[eNumberOfEvents][eSim][eAfter] is not booked => no info on the total number of events in internal validation can be provided \033[0m", __FUNCTION__, __LINE__); + } + + } // end of if (iv.fUseInternalValidation) { + + // c) Insanity checks on results histograms: + for (int AFO_1D = 0; AFO_1D < eAsFunctionOf_N; AFO_1D++) { + if (tc.fCalculateAsFunctionOf[AFO_1D] && !res.fResultsPro[AFO_1D]) { + LOGF(fatal, "\033[1;31m%s at line %d : AFO_1D = %d , fResultsPro profiles are not booked for this case \033[0m", __FUNCTION__, __LINE__, AFO_1D); + } + } + + for (int AFO_2D = 0; AFO_2D < eAsFunctionOf2D_N; AFO_2D++) { + if (tc.fCalculate2DAsFunctionOf[AFO_2D] && !res.fResultsPro2D[AFO_2D]) { + LOGF(fatal, "\033[1;31m%s at line %d : AFO_2D = %d , fResultsPro2D profiles are not booked for this case \033[0m", __FUNCTION__, __LINE__, AFO_2D); + } + } + + for (int AFO_3D = 0; AFO_3D < eAsFunctionOf3D_N; AFO_3D++) { + if (tc.fCalculate3DAsFunctionOf[AFO_3D] && !res.fResultsPro3D[AFO_3D]) { + LOGF(fatal, "\033[1;31m%s at line %d : AFO_3D = %d , fResultsPro3D profiles are not booked for this case \033[0m", __FUNCTION__, __LINE__, AFO_3D); + } + } + + // ... + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // void insanityChecksAfterBooking() + + //============================================================ + + void purgeAfterBooking() + { + // I can purge a few objects used for common consistent booking across different group of histograms. + + // TBI 20250518 I now automatically purge only 2D and 3D objects, I can refine further an purge also the lighte objects, if necessary + + // a) Purge results histograms and related objects; + // ... + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + return; // TBI 20250625 the code below is not ready yet, because I still use these 2D and 3D histos in FillqvectorNdim(...) + + // a) Purge results histograms and related objects: + if (!res.fSaveResultsHistograms) { + for (int v = 0; v < eAsFunctionOf2D_N; v++) { + if (res.fResultsPro2D[v]) { + delete res.fResultsPro2D[v]; + res.fResultsPro2D[v] = NULL; + } + } + + for (int v = 0; v < eAsFunctionOf3D_N; v++) { + if (res.fResultsPro3D[v]) { + delete res.fResultsPro3D[v]; + res.fResultsPro3D[v] = NULL; + } + } + } // if(!res.fSaveResultsHistograms) + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // void purgeAfterBooking() + + //============================================================ + + bool Skip(int recOrSim) + { + // Decide here whether a certain histogram, etc., will be booked and used both for eRec and eSim. + // Same for cuts. + + if (tc.fVerboseUtility) { + StartFunction(__FUNCTION__); + } + + // *) Insanity check: + if (!(recOrSim == eRec || recOrSim == eSim)) { + LOGF(fatal, "\033[1;31m%s at line %d : recOrSim = %d \033[0m", __FUNCTION__, __LINE__, recOrSim); + } + + // *) If I am doing internal validation, I book and fill only eSim: + if (iv.fUseInternalValidation) { + if (recOrSim == eRec) { + return true; // yes, skip + } else { + return false; // this is eSim, do not skip + } + } + + // *) If I am analyzing only reconstructed data, do not book histos for simulated, and vice versa. + // TBI 20240223 tc.fProcess[eProcessTest] is treated as tc.fProcess[eProcessRec], for the time being + if ((tc.fProcess[eGenericRec] && recOrSim == eSim) || (tc.fProcess[eGenericSim] && recOrSim == eRec)) { + return true; // yes, skip + } + + return false; // by default, I do not skip anything + + } // bool Skip(int recOrSim) + + //============================================================ + + void bookAndNestAllLists() + { + // *) QA; + // **) QA event histograms; + // **) QA particle histograms; + // **) QA particle event histograms; + // **) QA "correlations vs." histograms: + // **) QA "correlations vs. IR vs. " profiles; + // *) Control event histograms; + // *) Control particle histograms; + // *) Correlations; + // *) Q-vectors; + // *) Particle weights; + // *) Centrality weights; + // *) Nested loops; + // *) Toy NUA; + // *) Internal validation; + // *) Test0; + // *) Eta separations; + // *) Results. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // *) QA: + qa.fQAList = new TList(); + qa.fQAList->SetName("QA"); + qa.fQAList->SetOwner(true); + fBaseList->Add(qa.fQAList); + + // **) QA event histograms: + if (qa.fFillQAEventHistograms2D) { + qa.fQAEventList = new TList(); + qa.fQAEventList->SetName("QAEvent"); + qa.fQAEventList->SetOwner(true); + qa.fQAList->Add(qa.fQAEventList); // yes, this one is nested within base QA TList + } + + // **) QA particle histograms: + if (qa.fFillQAParticleHistograms2D) { + qa.fQAParticleList = new TList(); + qa.fQAParticleList->SetName("QAParticle"); + qa.fQAParticleList->SetOwner(true); + qa.fQAList->Add(qa.fQAParticleList); // yes, this one is nested within base QA TList + } + + // **) QA particle event histograms: + if (qa.fFillQAParticleEventHistograms2D) { + qa.fQAParticleEventList = new TList(); + qa.fQAParticleEventList->SetName("QAParticleEvent"); + qa.fQAParticleEventList->SetOwner(true); + qa.fQAList->Add(qa.fQAParticleEventList); // yes, this one is nested within base QA TList + } + + // **) QA "correlations vs." histograms: + if (qa.fFillQACorrelationsVsHistograms2D) { + qa.fQACorrelationsVsList = new TList(); + qa.fQACorrelationsVsList->SetName("QACorrelationsVs"); + qa.fQACorrelationsVsList->SetOwner(true); + qa.fQAList->Add(qa.fQACorrelationsVsList); // yes, this one is nested within base QA TList + } + + // **) QA "correlations vs. IR vs. " profiles: + if (qa.fFillQACorrelationsVsInteractionRateVsProfiles2D) { + qa.fQACorrelationsVsInteractionRateVsList = new TList(); + qa.fQACorrelationsVsInteractionRateVsList->SetName("QACorrelationsVsInteractionRateVsList"); + qa.fQACorrelationsVsInteractionRateVsList->SetOwner(true); + qa.fQAList->Add(qa.fQACorrelationsVsInteractionRateVsList); // yes, this one is nested within base QA TList + } + + // *) Event cuts: + ec.fEventCutsList = new TList(); + ec.fEventCutsList->SetName("EventCuts"); + ec.fEventCutsList->SetOwner(true); + fBaseList->Add(ec.fEventCutsList); + + // *) Control event histograms: + eh.fEventHistogramsList = new TList(); + eh.fEventHistogramsList->SetName("EventHistograms"); + eh.fEventHistogramsList->SetOwner(true); + fBaseList->Add(eh.fEventHistogramsList); + + // *) Particle cuts: + pc.fParticleCutsList = new TList(); + pc.fParticleCutsList->SetName("ParticleCuts"); + pc.fParticleCutsList->SetOwner(true); + fBaseList->Add(pc.fParticleCutsList); + + // *) Control particle histograms: + ph.fParticleHistogramsList = new TList(); + ph.fParticleHistogramsList->SetName("ParticleHistograms"); + ph.fParticleHistogramsList->SetOwner(true); + fBaseList->Add(ph.fParticleHistogramsList); + + // *) Q-vectors: + qv.fQvectorList = new TList(); + qv.fQvectorList->SetName("Q-vectors"); + qv.fQvectorList->SetOwner(true); + fBaseList->Add(qv.fQvectorList); + + // *) Correlations: + mupa.fCorrelationsList = new TList(); + mupa.fCorrelationsList->SetName("Correlations"); + mupa.fCorrelationsList->SetOwner(true); + fBaseList->Add(mupa.fCorrelationsList); + + // *) Particle weights: + pw.fWeightsList = new TList(); + pw.fWeightsList->SetName("Weights"); + pw.fWeightsList->SetOwner(true); + fBaseList->Add(pw.fWeightsList); + + // *) Centrality weights: + cw.fCentralityWeightsList = new TList(); + cw.fCentralityWeightsList->SetName("CentralityWeights"); + cw.fCentralityWeightsList->SetOwner(true); + fBaseList->Add(cw.fCentralityWeightsList); + + // *) Nested loops: + nl.fNestedLoopsList = new TList(); + nl.fNestedLoopsList->SetName("NestedLoops"); + nl.fNestedLoopsList->SetOwner(true); + fBaseList->Add(nl.fNestedLoopsList); + + // *) Toy NUA: + nua.fNUAList = new TList(); + nua.fNUAList->SetName("ToyNUA"); + nua.fNUAList->SetOwner(true); + fBaseList->Add(nua.fNUAList); + + // *) Internal validation: + iv.fInternalValidationList = new TList(); + iv.fInternalValidationList->SetName("InternalValidation"); + iv.fInternalValidationList->SetOwner(true); + fBaseList->Add(iv.fInternalValidationList); + + // *) Test0: + t0.fTest0List = new TList(); + t0.fTest0List->SetName("Test0"); + t0.fTest0List->SetOwner(true); + fBaseList->Add(t0.fTest0List); + + // *) Eta separations: + es.fEtaSeparationsList = new TList(); + es.fEtaSeparationsList->SetName("EtaSeparations"); + es.fEtaSeparationsList->SetOwner(true); + fBaseList->Add(es.fEtaSeparationsList); + + // *) Results: + res.fResultsList = new TList(); + res.fResultsList->SetName("Results"); + res.fResultsList->SetOwner(true); + fBaseList->Add(res.fResultsList); + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // void bookAndNestAllLists() + + //========================================================== + + void bookQAHistograms() + { + // Book all QA histograms and other related objects. + + // TBI 20240520 There is a bit of code bloat here - I could introduce a new enum eEventParticle, and then use eEvent = 0 and eParticle = 1 + + // a) Book the profile holding flags; + // b) Common local variables; + // c) Book specific QA 2D event histograms; + // d) Book specific QA 2D particle histograms; + // e) Book specific QA 2D particle event histograms; + // f) Book specific QA 2D "correlations vs." histograms; + // g) Book specific QA 2D "correlations vs. IR vs. " profiles. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // *) Print the warning message, because with too many 2D histograms with double precision, the code crashes in terminate, due to: + // + // [1450742:multiparticle-correlations-a-b]: [13:30:27][STATE] Exiting FairMQ state machine + // [1450742:multiparticle-correlations-a-b]: [13:30:27][FATAL] error while setting up workflow in o2-analysis-cf-multiparticle-correlations-ab: shmem: could not create a message of size 1282720912, alignment: 64, free memory: 1358639296 + // [1450742:multiparticle-correlations-a-b]: terminate called after throwing an instance of 'o2::framework::RuntimeErrorRef' + // [1450742:multiparticle-correlations-a-b]: *** Program crashed (Aborted) + // [1450742:multiparticle-correlations-a-b]: Backtrace by DPL: + // + + if (tc.fVerbose) { + LOGF(info, "\033[1;33m%s: !!!! WARNING !!!! With too many 2D histograms with double precision, the code will crash in terminate (\"... shmem: could not create a message of size ...\") . Locally, you can circumvent this while testing by calling Bailout() explicitly. !!!! WARNING !!!! \033[0m", __FUNCTION__); + } + + // a) Book the profile holding flags: + qa.fQAHistogramsPro = new TProfile("fQAHistogramsPro", "flags for QA histograms", 7, 0., 7.); + qa.fQAHistogramsPro->SetStats(false); + qa.fQAHistogramsPro->SetLineColor(eColor); + qa.fQAHistogramsPro->SetFillColor(eFillColor); + + if (tc.fUseSetBinLabel) { + qa.fQAHistogramsPro->GetXaxis()->SetBinLabel(1, "fCheckUnderflowAndOverflow"); + qa.fQAHistogramsPro->Fill(0.5, static_cast(qa.fCheckUnderflowAndOverflow)); + qa.fQAHistogramsPro->GetXaxis()->SetBinLabel(2, "fFillQAEventHistograms2D"); + qa.fQAHistogramsPro->Fill(1.5, static_cast(qa.fFillQAEventHistograms2D)); + qa.fQAHistogramsPro->GetXaxis()->SetBinLabel(3, "fFillQAParticleHistograms2D"); + qa.fQAHistogramsPro->Fill(2.5, static_cast(qa.fFillQAParticleHistograms2D)); + qa.fQAHistogramsPro->GetXaxis()->SetBinLabel(4, "fFillQAParticleEventHistograms2D"); + qa.fQAHistogramsPro->Fill(3.5, static_cast(qa.fFillQAParticleEventHistograms2D)); + qa.fQAHistogramsPro->GetXaxis()->SetBinLabel(5, "fFillQACorrelationsVsHistograms2D"); + qa.fQAHistogramsPro->Fill(4.5, static_cast(qa.fFillQACorrelationsVsHistograms2D)); + qa.fQAHistogramsPro->GetXaxis()->SetBinLabel(6, "fFillQACorrelationsVsInteractionRateVsProfiles2D"); + qa.fQAHistogramsPro->Fill(5.5, static_cast(qa.fFillQACorrelationsVsInteractionRateVsProfiles2D)); + qa.fQAHistogramsPro->GetXaxis()->SetBinLabel(7, "fRebin"); + qa.fQAHistogramsPro->Fill(6.5, static_cast(qa.fRebin)); + + // ... + + } else { + // Workaround for SetBinLabel() large memory consumption: + TString yAxisTitle = ""; + + yAxisTitle += TString::Format("%d:fCheckUnderflowAndOverflow; ", 1); + qa.fQAHistogramsPro->Fill(0.5, static_cast(qa.fCheckUnderflowAndOverflow)); + + yAxisTitle += TString::Format("%d:fFillQAEventHistograms2D; ", 2); + qa.fQAHistogramsPro->Fill(1.5, static_cast(qa.fFillQAEventHistograms2D)); + + yAxisTitle += TString::Format("%d:fFillQAParticleHistograms2D; ", 3); + qa.fQAHistogramsPro->Fill(2.5, static_cast(qa.fFillQAParticleHistograms2D)); + + yAxisTitle += TString::Format("%d:fFillQAParticleEventHistograms2D; ", 4); + qa.fQAHistogramsPro->Fill(3.5, static_cast(qa.fFillQAParticleEventHistograms2D)); + + yAxisTitle += TString::Format("%d:fFillQACorrelationsVsHistograms2D; ", 5); + qa.fQAHistogramsPro->Fill(4.5, static_cast(qa.fFillQACorrelationsVsHistograms2D)); + + yAxisTitle += TString::Format("%d:fFillQACorrelationsVsInteractionRateVsProfiles2D; ", 6); + qa.fQAHistogramsPro->Fill(5.5, static_cast(qa.fFillQACorrelationsVsInteractionRateVsProfiles2D)); + + yAxisTitle += TString::Format("%d:fRebin; ", 7); + qa.fQAHistogramsPro->Fill(6.5, static_cast(qa.fRebin)); + + // ... + + // *) Insanity check on the number of fields in this specially crafted y-axis title: + TObjArray* oa = yAxisTitle.Tokenize(";"); + if (!oa) { + LOGF(fatal, "\033[1;31m%s at line %d : oa is NULL\033[0m", __FUNCTION__, __LINE__); + } + if (oa->GetEntries() - 1 != qa.fQAHistogramsPro->GetNbinsX()) { + LOGF(fatal, "\033[1;31m%s at line %d : oa->GetEntries() - 1 = %d != qa.fQAHistogramsPro->GetNbinsX() = %d\033[0m", __FUNCTION__, __LINE__, oa->GetEntries(), qa.fQAHistogramsPro->GetNbinsX()); + } + delete oa; + + // *) Okay, set the title: + qa.fQAHistogramsPro->GetYaxis()->SetTitle(yAxisTitle.Data()); + + } // else + + qa.fQAList->Add(qa.fQAHistogramsPro); + + // b) Common local variables: + // ... + + // c) Book specific QA 2D event histograms: + // Binning of 2D event histos: TBI 20240503 see if you can automate all this + int nBins_x_Event[eQAEventHistograms2D_N] = {0}; + double min_x_Event[eQAEventHistograms2D_N] = {0.}; + double max_x_Event[eQAEventHistograms2D_N] = {0.}; + TString title_x_Event[eQAEventHistograms2D_N] = {""}; + int nBins_y_Event[eQAEventHistograms2D_N] = {0}; + double min_y_Event[eQAEventHistograms2D_N] = {0.}; + double max_y_Event[eQAEventHistograms2D_N] = {0.}; + TString title_y_Event[eQAEventHistograms2D_N] = {""}; + + // *) "Multiplicity_vs_ReferenceMultiplicity": + nBins_x_Event[eMultiplicity_vs_ReferenceMultiplicity] = static_cast(eh.fEventHistogramsBins[eMultiplicity][0] / qa.fRebin); + min_x_Event[eMultiplicity_vs_ReferenceMultiplicity] = eh.fEventHistogramsBins[eMultiplicity][1]; + max_x_Event[eMultiplicity_vs_ReferenceMultiplicity] = eh.fEventHistogramsBins[eMultiplicity][2]; + title_x_Event[eMultiplicity_vs_ReferenceMultiplicity] = FancyFormatting(eh.fEventHistogramsName[eMultiplicity].Data()); + nBins_y_Event[eMultiplicity_vs_ReferenceMultiplicity] = static_cast(eh.fEventHistogramsBins[eReferenceMultiplicity][0] / qa.fRebin); + min_y_Event[eMultiplicity_vs_ReferenceMultiplicity] = eh.fEventHistogramsBins[eReferenceMultiplicity][1]; + max_y_Event[eMultiplicity_vs_ReferenceMultiplicity] = eh.fEventHistogramsBins[eReferenceMultiplicity][2]; + title_y_Event[eMultiplicity_vs_ReferenceMultiplicity] = FancyFormatting(eh.fEventHistogramsName[eReferenceMultiplicity].Data()); + + // *) "Multiplicity_vs_NContributors": + nBins_x_Event[eMultiplicity_vs_NContributors] = static_cast(eh.fEventHistogramsBins[eMultiplicity][0] / qa.fRebin); + min_x_Event[eMultiplicity_vs_NContributors] = eh.fEventHistogramsBins[eMultiplicity][1]; + max_x_Event[eMultiplicity_vs_NContributors] = eh.fEventHistogramsBins[eMultiplicity][2]; + title_x_Event[eMultiplicity_vs_NContributors] = FancyFormatting(eh.fEventHistogramsName[eMultiplicity].Data()); + nBins_y_Event[eMultiplicity_vs_NContributors] = static_cast(eh.fEventHistogramsBins[eNContributors][0] / qa.fRebin); + min_y_Event[eMultiplicity_vs_NContributors] = eh.fEventHistogramsBins[eNContributors][1]; + max_y_Event[eMultiplicity_vs_NContributors] = eh.fEventHistogramsBins[eNContributors][2]; + title_y_Event[eMultiplicity_vs_NContributors] = FancyFormatting(eh.fEventHistogramsName[eNContributors].Data()); + + // *) "Multiplicity_vs_Centrality": + nBins_x_Event[eMultiplicity_vs_Centrality] = static_cast(eh.fEventHistogramsBins[eMultiplicity][0] / qa.fRebin); + min_x_Event[eMultiplicity_vs_Centrality] = eh.fEventHistogramsBins[eMultiplicity][1]; + max_x_Event[eMultiplicity_vs_Centrality] = eh.fEventHistogramsBins[eMultiplicity][2]; + title_x_Event[eMultiplicity_vs_Centrality] = FancyFormatting(eh.fEventHistogramsName[eMultiplicity].Data()); + nBins_y_Event[eMultiplicity_vs_Centrality] = static_cast(eh.fEventHistogramsBins[eCentrality][0]); + min_y_Event[eMultiplicity_vs_Centrality] = eh.fEventHistogramsBins[eCentrality][1]; + max_y_Event[eMultiplicity_vs_Centrality] = eh.fEventHistogramsBins[eCentrality][2]; + title_y_Event[eMultiplicity_vs_Centrality] = FancyFormatting(eh.fEventHistogramsName[eCentrality].Data()); + + // *) "Multiplicity_vs_VertexZ": + nBins_x_Event[eMultiplicity_vs_VertexZ] = static_cast(eh.fEventHistogramsBins[eMultiplicity][0] / qa.fRebin); + min_x_Event[eMultiplicity_vs_VertexZ] = eh.fEventHistogramsBins[eMultiplicity][1]; + max_x_Event[eMultiplicity_vs_VertexZ] = eh.fEventHistogramsBins[eMultiplicity][2]; + title_x_Event[eMultiplicity_vs_VertexZ] = FancyFormatting(eh.fEventHistogramsName[eMultiplicity].Data()); + nBins_y_Event[eMultiplicity_vs_VertexZ] = static_cast(eh.fEventHistogramsBins[eVertexZ][0]); + min_y_Event[eMultiplicity_vs_VertexZ] = eh.fEventHistogramsBins[eVertexZ][1]; + max_y_Event[eMultiplicity_vs_VertexZ] = eh.fEventHistogramsBins[eVertexZ][2]; + title_y_Event[eMultiplicity_vs_VertexZ] = FancyFormatting(eh.fEventHistogramsName[eVertexZ].Data()); + + // *) "Multiplicity_vs_Occupancy": + nBins_x_Event[eMultiplicity_vs_Occupancy] = static_cast(eh.fEventHistogramsBins[eMultiplicity][0] / qa.fRebin); + min_x_Event[eMultiplicity_vs_Occupancy] = eh.fEventHistogramsBins[eMultiplicity][1]; + max_x_Event[eMultiplicity_vs_Occupancy] = eh.fEventHistogramsBins[eMultiplicity][2]; + title_x_Event[eMultiplicity_vs_Occupancy] = FancyFormatting(eh.fEventHistogramsName[eMultiplicity].Data()); + nBins_y_Event[eMultiplicity_vs_Occupancy] = static_cast(eh.fEventHistogramsBins[eOccupancy][0] / qa.fRebin); + min_y_Event[eMultiplicity_vs_Occupancy] = eh.fEventHistogramsBins[eOccupancy][1]; + max_y_Event[eMultiplicity_vs_Occupancy] = eh.fEventHistogramsBins[eOccupancy][2]; + title_y_Event[eMultiplicity_vs_Occupancy] = FancyFormatting(eh.fEventHistogramsName[eOccupancy].Data()); + + // *) "Multiplicity_vs_InteractionRate": + nBins_x_Event[eMultiplicity_vs_InteractionRate] = static_cast(eh.fEventHistogramsBins[eMultiplicity][0] / qa.fRebin); + min_x_Event[eMultiplicity_vs_InteractionRate] = eh.fEventHistogramsBins[eMultiplicity][1]; + max_x_Event[eMultiplicity_vs_InteractionRate] = eh.fEventHistogramsBins[eMultiplicity][2]; + title_x_Event[eMultiplicity_vs_InteractionRate] = FancyFormatting(eh.fEventHistogramsName[eMultiplicity].Data()); + nBins_y_Event[eMultiplicity_vs_InteractionRate] = static_cast(eh.fEventHistogramsBins[eInteractionRate][0] / qa.fRebin); + min_y_Event[eMultiplicity_vs_InteractionRate] = eh.fEventHistogramsBins[eInteractionRate][1]; + max_y_Event[eMultiplicity_vs_InteractionRate] = eh.fEventHistogramsBins[eInteractionRate][2]; + title_y_Event[eMultiplicity_vs_InteractionRate] = FancyFormatting(eh.fEventHistogramsName[eInteractionRate].Data()); + + // *) "ReferenceMultiplicity_vs_NContributors": // TBI 20250401 I use this one to calculate quantiles for HMO cut, therefore I keep it refined for the time being + nBins_x_Event[eReferenceMultiplicity_vs_NContributors] = static_cast(eh.fEventHistogramsBins[eReferenceMultiplicity][0]); + min_x_Event[eReferenceMultiplicity_vs_NContributors] = eh.fEventHistogramsBins[eReferenceMultiplicity][1]; + max_x_Event[eReferenceMultiplicity_vs_NContributors] = eh.fEventHistogramsBins[eReferenceMultiplicity][2]; + title_x_Event[eReferenceMultiplicity_vs_NContributors] = FancyFormatting(eh.fEventHistogramsName[eReferenceMultiplicity].Data()); + nBins_y_Event[eReferenceMultiplicity_vs_NContributors] = static_cast(eh.fEventHistogramsBins[eNContributors][0]); + min_y_Event[eReferenceMultiplicity_vs_NContributors] = eh.fEventHistogramsBins[eNContributors][1]; + max_y_Event[eReferenceMultiplicity_vs_NContributors] = eh.fEventHistogramsBins[eNContributors][2]; + title_y_Event[eReferenceMultiplicity_vs_NContributors] = FancyFormatting(eh.fEventHistogramsName[eNContributors].Data()); + + // *) "ReferenceMultiplicity_vs_Centrality": + nBins_x_Event[eReferenceMultiplicity_vs_Centrality] = static_cast(eh.fEventHistogramsBins[eReferenceMultiplicity][0] / qa.fRebin); + min_x_Event[eReferenceMultiplicity_vs_Centrality] = eh.fEventHistogramsBins[eReferenceMultiplicity][1]; + max_x_Event[eReferenceMultiplicity_vs_Centrality] = eh.fEventHistogramsBins[eReferenceMultiplicity][2]; + title_x_Event[eReferenceMultiplicity_vs_Centrality] = FancyFormatting(eh.fEventHistogramsName[eReferenceMultiplicity].Data()); + nBins_y_Event[eReferenceMultiplicity_vs_Centrality] = static_cast(eh.fEventHistogramsBins[eCentrality][0]); + min_y_Event[eReferenceMultiplicity_vs_Centrality] = eh.fEventHistogramsBins[eCentrality][1]; + max_y_Event[eReferenceMultiplicity_vs_Centrality] = eh.fEventHistogramsBins[eCentrality][2]; + title_y_Event[eReferenceMultiplicity_vs_Centrality] = FancyFormatting(eh.fEventHistogramsName[eCentrality].Data()); + + // *) "ReferenceMultiplicity_vs_VertexZ": + nBins_x_Event[eReferenceMultiplicity_vs_VertexZ] = static_cast(eh.fEventHistogramsBins[eReferenceMultiplicity][0] / qa.fRebin); + min_x_Event[eReferenceMultiplicity_vs_VertexZ] = eh.fEventHistogramsBins[eReferenceMultiplicity][1]; + max_x_Event[eReferenceMultiplicity_vs_VertexZ] = eh.fEventHistogramsBins[eReferenceMultiplicity][2]; + title_x_Event[eReferenceMultiplicity_vs_VertexZ] = FancyFormatting(eh.fEventHistogramsName[eReferenceMultiplicity].Data()); + nBins_y_Event[eReferenceMultiplicity_vs_VertexZ] = static_cast(eh.fEventHistogramsBins[eVertexZ][0]); + min_y_Event[eReferenceMultiplicity_vs_VertexZ] = eh.fEventHistogramsBins[eVertexZ][1]; + max_y_Event[eReferenceMultiplicity_vs_VertexZ] = eh.fEventHistogramsBins[eVertexZ][2]; + title_y_Event[eReferenceMultiplicity_vs_VertexZ] = FancyFormatting(eh.fEventHistogramsName[eVertexZ].Data()); + + // *) "ReferenceMultiplicity_vs_Occupancy": + nBins_x_Event[eReferenceMultiplicity_vs_Occupancy] = static_cast(eh.fEventHistogramsBins[eReferenceMultiplicity][0] / qa.fRebin); + min_x_Event[eReferenceMultiplicity_vs_Occupancy] = eh.fEventHistogramsBins[eReferenceMultiplicity][1]; + max_x_Event[eReferenceMultiplicity_vs_Occupancy] = eh.fEventHistogramsBins[eReferenceMultiplicity][2]; + title_x_Event[eReferenceMultiplicity_vs_Occupancy] = FancyFormatting(eh.fEventHistogramsName[eReferenceMultiplicity].Data()); + nBins_y_Event[eReferenceMultiplicity_vs_Occupancy] = static_cast(eh.fEventHistogramsBins[eOccupancy][0] / qa.fRebin); + min_y_Event[eReferenceMultiplicity_vs_Occupancy] = eh.fEventHistogramsBins[eOccupancy][1]; + max_y_Event[eReferenceMultiplicity_vs_Occupancy] = eh.fEventHistogramsBins[eOccupancy][2]; + title_y_Event[eReferenceMultiplicity_vs_Occupancy] = FancyFormatting(eh.fEventHistogramsName[eOccupancy].Data()); + + // *) "ReferenceMultiplicity_vs_InteractionRate": + nBins_x_Event[eReferenceMultiplicity_vs_InteractionRate] = static_cast(eh.fEventHistogramsBins[eReferenceMultiplicity][0] / qa.fRebin); + min_x_Event[eReferenceMultiplicity_vs_InteractionRate] = eh.fEventHistogramsBins[eReferenceMultiplicity][1]; + max_x_Event[eReferenceMultiplicity_vs_InteractionRate] = eh.fEventHistogramsBins[eReferenceMultiplicity][2]; + title_x_Event[eReferenceMultiplicity_vs_InteractionRate] = FancyFormatting(eh.fEventHistogramsName[eReferenceMultiplicity].Data()); + nBins_y_Event[eReferenceMultiplicity_vs_InteractionRate] = static_cast(eh.fEventHistogramsBins[eInteractionRate][0] / qa.fRebin); + min_y_Event[eReferenceMultiplicity_vs_InteractionRate] = eh.fEventHistogramsBins[eInteractionRate][1]; + max_y_Event[eReferenceMultiplicity_vs_InteractionRate] = eh.fEventHistogramsBins[eInteractionRate][2]; + title_y_Event[eReferenceMultiplicity_vs_InteractionRate] = FancyFormatting(eh.fEventHistogramsName[eInteractionRate].Data()); + + // *) "NContributors_vs_Centrality": + nBins_x_Event[eNContributors_vs_Centrality] = static_cast(eh.fEventHistogramsBins[eNContributors][0] / qa.fRebin); + min_x_Event[eNContributors_vs_Centrality] = eh.fEventHistogramsBins[eNContributors][1]; + max_x_Event[eNContributors_vs_Centrality] = eh.fEventHistogramsBins[eNContributors][2]; + title_x_Event[eNContributors_vs_Centrality] = FancyFormatting(eh.fEventHistogramsName[eNContributors].Data()); + nBins_y_Event[eNContributors_vs_Centrality] = static_cast(eh.fEventHistogramsBins[eCentrality][0]); + min_y_Event[eNContributors_vs_Centrality] = eh.fEventHistogramsBins[eCentrality][1]; + max_y_Event[eNContributors_vs_Centrality] = eh.fEventHistogramsBins[eCentrality][2]; + title_y_Event[eNContributors_vs_Centrality] = FancyFormatting(eh.fEventHistogramsName[eCentrality].Data()); + + // *) "NContributors_vs_VertexZ": + nBins_x_Event[eNContributors_vs_VertexZ] = static_cast(eh.fEventHistogramsBins[eNContributors][0] / qa.fRebin); + min_x_Event[eNContributors_vs_VertexZ] = eh.fEventHistogramsBins[eNContributors][1]; + max_x_Event[eNContributors_vs_VertexZ] = eh.fEventHistogramsBins[eNContributors][2]; + title_x_Event[eNContributors_vs_VertexZ] = FancyFormatting(eh.fEventHistogramsName[eNContributors].Data()); + nBins_y_Event[eNContributors_vs_VertexZ] = static_cast(eh.fEventHistogramsBins[eVertexZ][0]); + min_y_Event[eNContributors_vs_VertexZ] = eh.fEventHistogramsBins[eVertexZ][1]; + max_y_Event[eNContributors_vs_VertexZ] = eh.fEventHistogramsBins[eVertexZ][2]; + title_y_Event[eNContributors_vs_VertexZ] = FancyFormatting(eh.fEventHistogramsName[eVertexZ].Data()); + + // *) "NContributors_vs_Occupancy": + nBins_x_Event[eNContributors_vs_Occupancy] = static_cast(eh.fEventHistogramsBins[eNContributors][0] / qa.fRebin); + min_x_Event[eNContributors_vs_Occupancy] = eh.fEventHistogramsBins[eNContributors][1]; + max_x_Event[eNContributors_vs_Occupancy] = eh.fEventHistogramsBins[eNContributors][2]; + title_x_Event[eNContributors_vs_Occupancy] = FancyFormatting(eh.fEventHistogramsName[eNContributors].Data()); + nBins_y_Event[eNContributors_vs_Occupancy] = static_cast(eh.fEventHistogramsBins[eOccupancy][0] / qa.fRebin); + min_y_Event[eNContributors_vs_Occupancy] = eh.fEventHistogramsBins[eOccupancy][1]; + max_y_Event[eNContributors_vs_Occupancy] = eh.fEventHistogramsBins[eOccupancy][2]; + title_y_Event[eNContributors_vs_Occupancy] = FancyFormatting(eh.fEventHistogramsName[eOccupancy].Data()); + + // *) "NContributors_vs_InteractionRate": + nBins_x_Event[eNContributors_vs_InteractionRate] = static_cast(eh.fEventHistogramsBins[eNContributors][0] / qa.fRebin); + min_x_Event[eNContributors_vs_InteractionRate] = eh.fEventHistogramsBins[eNContributors][1]; + max_x_Event[eNContributors_vs_InteractionRate] = eh.fEventHistogramsBins[eNContributors][2]; + title_x_Event[eNContributors_vs_InteractionRate] = FancyFormatting(eh.fEventHistogramsName[eNContributors].Data()); + nBins_y_Event[eNContributors_vs_InteractionRate] = static_cast(eh.fEventHistogramsBins[eInteractionRate][0] / qa.fRebin); + min_y_Event[eNContributors_vs_InteractionRate] = eh.fEventHistogramsBins[eInteractionRate][1]; + max_y_Event[eNContributors_vs_InteractionRate] = eh.fEventHistogramsBins[eInteractionRate][2]; + title_y_Event[eNContributors_vs_InteractionRate] = FancyFormatting(eh.fEventHistogramsName[eInteractionRate].Data()); + + // *) "Centrality_vs_VertexZ": + nBins_x_Event[eCentrality_vs_VertexZ] = static_cast(eh.fEventHistogramsBins[eCentrality][0]); + min_x_Event[eCentrality_vs_VertexZ] = eh.fEventHistogramsBins[eCentrality][1]; + max_x_Event[eCentrality_vs_VertexZ] = eh.fEventHistogramsBins[eCentrality][2]; + title_x_Event[eCentrality_vs_VertexZ] = FancyFormatting(eh.fEventHistogramsName[eCentrality].Data()); + nBins_y_Event[eCentrality_vs_VertexZ] = static_cast(eh.fEventHistogramsBins[eVertexZ][0]); + min_y_Event[eCentrality_vs_VertexZ] = eh.fEventHistogramsBins[eVertexZ][1]; + max_y_Event[eCentrality_vs_VertexZ] = eh.fEventHistogramsBins[eVertexZ][2]; + title_y_Event[eCentrality_vs_VertexZ] = FancyFormatting(eh.fEventHistogramsName[eVertexZ].Data()); + + // *) "Centrality_vs_Occupancy": + nBins_x_Event[eCentrality_vs_Occupancy] = static_cast(eh.fEventHistogramsBins[eCentrality][0]); + min_x_Event[eCentrality_vs_Occupancy] = eh.fEventHistogramsBins[eCentrality][1]; + max_x_Event[eCentrality_vs_Occupancy] = eh.fEventHistogramsBins[eCentrality][2]; + title_x_Event[eCentrality_vs_Occupancy] = FancyFormatting(eh.fEventHistogramsName[eCentrality].Data()); + nBins_y_Event[eCentrality_vs_Occupancy] = static_cast(eh.fEventHistogramsBins[eOccupancy][0] / qa.fRebin); + min_y_Event[eCentrality_vs_Occupancy] = eh.fEventHistogramsBins[eOccupancy][1]; + max_y_Event[eCentrality_vs_Occupancy] = eh.fEventHistogramsBins[eOccupancy][2]; + title_y_Event[eCentrality_vs_Occupancy] = FancyFormatting(eh.fEventHistogramsName[eOccupancy].Data()); + + // *) "Centrality_vs_ImpactParameter": + nBins_x_Event[eCentrality_vs_ImpactParameter] = static_cast(eh.fEventHistogramsBins[eCentrality][0]); + min_x_Event[eCentrality_vs_ImpactParameter] = eh.fEventHistogramsBins[eCentrality][1]; + max_x_Event[eCentrality_vs_ImpactParameter] = eh.fEventHistogramsBins[eCentrality][2]; + title_x_Event[eCentrality_vs_ImpactParameter] = FancyFormatting(eh.fEventHistogramsName[eCentrality].Data()); + nBins_y_Event[eCentrality_vs_ImpactParameter] = static_cast(eh.fEventHistogramsBins[eImpactParameter][0] / qa.fRebin); + min_y_Event[eCentrality_vs_ImpactParameter] = eh.fEventHistogramsBins[eImpactParameter][1]; + max_y_Event[eCentrality_vs_ImpactParameter] = eh.fEventHistogramsBins[eImpactParameter][2]; + title_y_Event[eCentrality_vs_ImpactParameter] = FancyFormatting(eh.fEventHistogramsName[eImpactParameter].Data()); + + // *) "Centrality_vs_InteractionRate": + nBins_x_Event[eCentrality_vs_InteractionRate] = static_cast(eh.fEventHistogramsBins[eCentrality][0]); + min_x_Event[eCentrality_vs_InteractionRate] = eh.fEventHistogramsBins[eCentrality][1]; + max_x_Event[eCentrality_vs_InteractionRate] = eh.fEventHistogramsBins[eCentrality][2]; + title_x_Event[eCentrality_vs_InteractionRate] = FancyFormatting(eh.fEventHistogramsName[eCentrality].Data()); + nBins_y_Event[eCentrality_vs_InteractionRate] = static_cast(eh.fEventHistogramsBins[eInteractionRate][0] / qa.fRebin); + min_y_Event[eCentrality_vs_InteractionRate] = eh.fEventHistogramsBins[eInteractionRate][1]; + max_y_Event[eCentrality_vs_InteractionRate] = eh.fEventHistogramsBins[eInteractionRate][2]; + title_y_Event[eCentrality_vs_InteractionRate] = FancyFormatting(eh.fEventHistogramsName[eInteractionRate].Data()); + + // *) "VertexZ_vs_Occupancy": + nBins_x_Event[eVertexZ_vs_Occupancy] = static_cast(eh.fEventHistogramsBins[eVertexZ][0]); + min_x_Event[eVertexZ_vs_Occupancy] = eh.fEventHistogramsBins[eVertexZ][1]; + max_x_Event[eVertexZ_vs_Occupancy] = eh.fEventHistogramsBins[eVertexZ][2]; + title_x_Event[eVertexZ_vs_Occupancy] = FancyFormatting(eh.fEventHistogramsName[eVertexZ].Data()); + nBins_y_Event[eVertexZ_vs_Occupancy] = static_cast(eh.fEventHistogramsBins[eOccupancy][0] / qa.fRebin); + min_y_Event[eVertexZ_vs_Occupancy] = eh.fEventHistogramsBins[eOccupancy][1]; + max_y_Event[eVertexZ_vs_Occupancy] = eh.fEventHistogramsBins[eOccupancy][2]; + title_y_Event[eVertexZ_vs_Occupancy] = FancyFormatting(eh.fEventHistogramsName[eOccupancy].Data()); + + // *) "VertexZ_vs_InteractionRate": + nBins_x_Event[eVertexZ_vs_InteractionRate] = static_cast(eh.fEventHistogramsBins[eVertexZ][0]); + min_x_Event[eVertexZ_vs_InteractionRate] = eh.fEventHistogramsBins[eVertexZ][1]; + max_x_Event[eVertexZ_vs_InteractionRate] = eh.fEventHistogramsBins[eVertexZ][2]; + title_x_Event[eVertexZ_vs_InteractionRate] = FancyFormatting(eh.fEventHistogramsName[eVertexZ].Data()); + nBins_y_Event[eVertexZ_vs_InteractionRate] = static_cast(eh.fEventHistogramsBins[eInteractionRate][0] / qa.fRebin); + min_y_Event[eVertexZ_vs_InteractionRate] = eh.fEventHistogramsBins[eInteractionRate][1]; + max_y_Event[eVertexZ_vs_InteractionRate] = eh.fEventHistogramsBins[eInteractionRate][2]; + title_y_Event[eVertexZ_vs_InteractionRate] = FancyFormatting(eh.fEventHistogramsName[eInteractionRate].Data()); + + // *) "Multiplicity_vs_FT0CAmplitudeOnFoundBC": + // nBins_x_Event[eMultiplicity_vs_FT0CAmplitudeOnFoundBC] = static_cast(eh.fEventHistogramsBins[eMultiplicity][0]); + nBins_x_Event[eMultiplicity_vs_FT0CAmplitudeOnFoundBC] = 2000.; // TBI 20250331 hardwired value + min_x_Event[eMultiplicity_vs_FT0CAmplitudeOnFoundBC] = eh.fEventHistogramsBins[eMultiplicity][1]; + max_x_Event[eMultiplicity_vs_FT0CAmplitudeOnFoundBC] = eh.fEventHistogramsBins[eMultiplicity][2]; + title_x_Event[eMultiplicity_vs_FT0CAmplitudeOnFoundBC] = FancyFormatting(eh.fEventHistogramsName[eMultiplicity].Data()); + nBins_y_Event[eMultiplicity_vs_FT0CAmplitudeOnFoundBC] = 1000; // TBI 20250331 hardwired value + min_y_Event[eMultiplicity_vs_FT0CAmplitudeOnFoundBC] = 0.; // TBI 20250331 hardwired value + max_y_Event[eMultiplicity_vs_FT0CAmplitudeOnFoundBC] = 100000.; // TBI 20250331 hardwired value + title_y_Event[eMultiplicity_vs_FT0CAmplitudeOnFoundBC] = "FT0CAmplitudeOnFoundBC"; // TBI 20250331 hardwired string + + // *) "CentFT0C_vs_FT0CAmplitudeOnFoundBC": + nBins_x_Event[eCentFT0C_vs_FT0CAmplitudeOnFoundBC] = eh.fEventHistogramsBins[eCentrality][0]; // yes, eCentrality, not eCentFT0C, just think of it ! + min_x_Event[eCentFT0C_vs_FT0CAmplitudeOnFoundBC] = eh.fEventHistogramsBins[eCentrality][1]; + max_x_Event[eCentFT0C_vs_FT0CAmplitudeOnFoundBC] = eh.fEventHistogramsBins[eCentrality][2]; + title_x_Event[eCentFT0C_vs_FT0CAmplitudeOnFoundBC] = FancyFormatting(qa.fCentralityEstimatorName[eCentFT0C].Data()); + nBins_y_Event[eCentFT0C_vs_FT0CAmplitudeOnFoundBC] = 1000; // TBI 20250331 hardwired value + min_y_Event[eCentFT0C_vs_FT0CAmplitudeOnFoundBC] = 0.; // TBI 20250331 hardwired value + max_y_Event[eCentFT0C_vs_FT0CAmplitudeOnFoundBC] = 100000.; // TBI 20250331 hardwired value + title_y_Event[eCentFT0C_vs_FT0CAmplitudeOnFoundBC] = "FT0CAmplitudeOnFoundBC"; // TBI 20250331 hardwired string + + // *) "Centrality_vs_CentralitySim": + nBins_x_Event[eCentrality_vs_CentralitySim] = eh.fEventHistogramsBins[eCentrality][0]; + min_x_Event[eCentrality_vs_CentralitySim] = eh.fEventHistogramsBins[eCentrality][1]; + max_x_Event[eCentrality_vs_CentralitySim] = eh.fEventHistogramsBins[eCentrality][2]; + title_x_Event[eCentrality_vs_CentralitySim] = FancyFormatting(eh.fEventHistogramsName[eCentrality].Data()); + nBins_y_Event[eCentrality_vs_CentralitySim] = eh.fEventHistogramsBins[eCentrality][0]; + min_y_Event[eCentrality_vs_CentralitySim] = eh.fEventHistogramsBins[eCentrality][1]; + max_y_Event[eCentrality_vs_CentralitySim] = eh.fEventHistogramsBins[eCentrality][2]; + title_y_Event[eCentrality_vs_CentralitySim] = "simulated centrality (calculated from IP)"; // TBI 20250331 hardwired string + + // *) "MultNTracksPV_vs_MultNTracksGlobal": + nBins_x_Event[eMultNTracksPV_vs_MultNTracksGlobal] = static_cast(eh.fEventHistogramsBins[eMultiplicity][0] / qa.fRebin); + min_x_Event[eMultNTracksPV_vs_MultNTracksGlobal] = eh.fEventHistogramsBins[eMultiplicity][1]; + max_x_Event[eMultNTracksPV_vs_MultNTracksGlobal] = eh.fEventHistogramsBins[eMultiplicity][2]; + title_x_Event[eMultNTracksPV_vs_MultNTracksGlobal] = FancyFormatting(qa.fReferenceMultiplicityEstimatorName[eMultNTracksPV].Data()); + nBins_y_Event[eMultNTracksPV_vs_MultNTracksGlobal] = static_cast(eh.fEventHistogramsBins[eMultiplicity][0] / qa.fRebin); + min_y_Event[eMultNTracksPV_vs_MultNTracksGlobal] = eh.fEventHistogramsBins[eMultiplicity][1]; + max_y_Event[eMultNTracksPV_vs_MultNTracksGlobal] = eh.fEventHistogramsBins[eMultiplicity][2]; + title_y_Event[eMultNTracksPV_vs_MultNTracksGlobal] = FancyFormatting(qa.fReferenceMultiplicityEstimatorName[eMultNTracksGlobal].Data()); + + // *) "CentFT0C_vs_CentFT0CVariant1": + nBins_x_Event[eCentFT0C_vs_CentFT0CVariant1] = static_cast(eh.fEventHistogramsBins[eCentrality][0]); + min_x_Event[eCentFT0C_vs_CentFT0CVariant1] = eh.fEventHistogramsBins[eCentrality][1]; + max_x_Event[eCentFT0C_vs_CentFT0CVariant1] = eh.fEventHistogramsBins[eCentrality][2]; + title_x_Event[eCentFT0C_vs_CentFT0CVariant1] = FancyFormatting(qa.fCentralityEstimatorName[eCentFT0C].Data()); + nBins_y_Event[eCentFT0C_vs_CentFT0CVariant1] = static_cast(eh.fEventHistogramsBins[eCentrality][0]); + min_y_Event[eCentFT0C_vs_CentFT0CVariant1] = eh.fEventHistogramsBins[eCentrality][1]; + max_y_Event[eCentFT0C_vs_CentFT0CVariant1] = eh.fEventHistogramsBins[eCentrality][2]; + title_y_Event[eCentFT0C_vs_CentFT0CVariant1] = FancyFormatting(qa.fCentralityEstimatorName[eCentFT0CVariant1].Data()); + + // *) "CentFT0C_vs_CentFT0M": + nBins_x_Event[eCentFT0C_vs_CentFT0M] = static_cast(eh.fEventHistogramsBins[eCentrality][0]); + min_x_Event[eCentFT0C_vs_CentFT0M] = eh.fEventHistogramsBins[eCentrality][1]; + max_x_Event[eCentFT0C_vs_CentFT0M] = eh.fEventHistogramsBins[eCentrality][2]; + title_x_Event[eCentFT0C_vs_CentFT0M] = FancyFormatting(qa.fCentralityEstimatorName[eCentFT0C].Data()); + nBins_y_Event[eCentFT0C_vs_CentFT0M] = static_cast(eh.fEventHistogramsBins[eCentrality][0]); + min_y_Event[eCentFT0C_vs_CentFT0M] = eh.fEventHistogramsBins[eCentrality][1]; + max_y_Event[eCentFT0C_vs_CentFT0M] = eh.fEventHistogramsBins[eCentrality][2]; + title_y_Event[eCentFT0C_vs_CentFT0M] = FancyFormatting(qa.fCentralityEstimatorName[eCentFT0M].Data()); + + // *) "CentFT0C_vs_CentFV0A": + nBins_x_Event[eCentFT0C_vs_CentFV0A] = static_cast(eh.fEventHistogramsBins[eCentrality][0]); + min_x_Event[eCentFT0C_vs_CentFV0A] = eh.fEventHistogramsBins[eCentrality][1]; + max_x_Event[eCentFT0C_vs_CentFV0A] = eh.fEventHistogramsBins[eCentrality][2]; + title_x_Event[eCentFT0C_vs_CentFV0A] = FancyFormatting(qa.fCentralityEstimatorName[eCentFT0C].Data()); + nBins_y_Event[eCentFT0C_vs_CentFV0A] = static_cast(eh.fEventHistogramsBins[eCentrality][0]); + min_y_Event[eCentFT0C_vs_CentFV0A] = eh.fEventHistogramsBins[eCentrality][1]; + max_y_Event[eCentFT0C_vs_CentFV0A] = eh.fEventHistogramsBins[eCentrality][2]; + title_y_Event[eCentFT0C_vs_CentFV0A] = FancyFormatting(qa.fCentralityEstimatorName[eCentFV0A].Data()); + + // *) "CentFT0C_vs_CentNTPV": + nBins_x_Event[eCentFT0C_vs_CentNTPV] = static_cast(eh.fEventHistogramsBins[eCentrality][0]); + min_x_Event[eCentFT0C_vs_CentNTPV] = eh.fEventHistogramsBins[eCentrality][1]; + max_x_Event[eCentFT0C_vs_CentNTPV] = eh.fEventHistogramsBins[eCentrality][2]; + title_x_Event[eCentFT0C_vs_CentNTPV] = FancyFormatting(qa.fCentralityEstimatorName[eCentFT0C].Data()); + nBins_y_Event[eCentFT0C_vs_CentNTPV] = static_cast(eh.fEventHistogramsBins[eCentrality][0]); + min_y_Event[eCentFT0C_vs_CentNTPV] = eh.fEventHistogramsBins[eCentrality][1]; + max_y_Event[eCentFT0C_vs_CentNTPV] = eh.fEventHistogramsBins[eCentrality][2]; + title_y_Event[eCentFT0C_vs_CentNTPV] = FancyFormatting(qa.fCentralityEstimatorName[eCentNTPV].Data()); + + // *) "CentFT0C_vs_CentNGlobal": + nBins_x_Event[eCentFT0C_vs_CentNGlobal] = static_cast(eh.fEventHistogramsBins[eCentrality][0]); + min_x_Event[eCentFT0C_vs_CentNGlobal] = eh.fEventHistogramsBins[eCentrality][1]; + max_x_Event[eCentFT0C_vs_CentNGlobal] = eh.fEventHistogramsBins[eCentrality][2]; + title_x_Event[eCentFT0C_vs_CentNGlobal] = FancyFormatting(qa.fCentralityEstimatorName[eCentFT0C].Data()); + nBins_y_Event[eCentFT0C_vs_CentNGlobal] = static_cast(eh.fEventHistogramsBins[eCentrality][0]); + min_y_Event[eCentFT0C_vs_CentNGlobal] = eh.fEventHistogramsBins[eCentrality][1]; + max_y_Event[eCentFT0C_vs_CentNGlobal] = eh.fEventHistogramsBins[eCentrality][2]; + title_y_Event[eCentFT0C_vs_CentNGlobal] = FancyFormatting(qa.fCentralityEstimatorName[eCentNGlobal].Data()); + + // *) "CentFT0M_vs_CentNTPV": + nBins_x_Event[eCentFT0M_vs_CentNTPV] = static_cast(eh.fEventHistogramsBins[eCentrality][0]); + min_x_Event[eCentFT0M_vs_CentNTPV] = eh.fEventHistogramsBins[eCentrality][1]; + max_x_Event[eCentFT0M_vs_CentNTPV] = eh.fEventHistogramsBins[eCentrality][2]; + title_x_Event[eCentFT0M_vs_CentNTPV] = FancyFormatting(qa.fCentralityEstimatorName[eCentFT0M].Data()); + nBins_y_Event[eCentFT0M_vs_CentNTPV] = static_cast(eh.fEventHistogramsBins[eCentrality][0]); + min_y_Event[eCentFT0M_vs_CentNTPV] = eh.fEventHistogramsBins[eCentrality][1]; + max_y_Event[eCentFT0M_vs_CentNTPV] = eh.fEventHistogramsBins[eCentrality][2]; + title_y_Event[eCentFT0M_vs_CentNTPV] = FancyFormatting(qa.fCentralityEstimatorName[eCentNTPV].Data()); + + // *) "CentRun2V0M_vs_CentRun2SPDTracklets": + nBins_x_Event[eCentRun2V0M_vs_CentRun2SPDTracklets] = static_cast(eh.fEventHistogramsBins[eCentrality][0]); + min_x_Event[eCentRun2V0M_vs_CentRun2SPDTracklets] = eh.fEventHistogramsBins[eCentrality][1]; + max_x_Event[eCentRun2V0M_vs_CentRun2SPDTracklets] = eh.fEventHistogramsBins[eCentrality][2]; + title_x_Event[eCentRun2V0M_vs_CentRun2SPDTracklets] = FancyFormatting(qa.fCentralityEstimatorName[eCentRun2V0M].Data()); + nBins_y_Event[eCentRun2V0M_vs_CentRun2SPDTracklets] = static_cast(eh.fEventHistogramsBins[eCentrality][0]); + min_y_Event[eCentRun2V0M_vs_CentRun2SPDTracklets] = eh.fEventHistogramsBins[eCentrality][1]; + max_y_Event[eCentRun2V0M_vs_CentRun2SPDTracklets] = eh.fEventHistogramsBins[eCentrality][2]; + title_y_Event[eCentRun2V0M_vs_CentRun2SPDTracklets] = FancyFormatting(qa.fCentralityEstimatorName[eCentRun2SPDTracklets].Data()); + + // *) "TrackOccupancyInTimeRange_vs_FT0COccupancyInTimeRange": + nBins_x_Event[eTrackOccupancyInTimeRange_vs_FT0COccupancyInTimeRange] = static_cast(eh.fEventHistogramsBins[eOccupancy][0] / qa.fRebin); + min_x_Event[eTrackOccupancyInTimeRange_vs_FT0COccupancyInTimeRange] = eh.fEventHistogramsBins[eOccupancy][1]; + max_x_Event[eTrackOccupancyInTimeRange_vs_FT0COccupancyInTimeRange] = eh.fEventHistogramsBins[eOccupancy][2]; + title_x_Event[eTrackOccupancyInTimeRange_vs_FT0COccupancyInTimeRange] = FancyFormatting(qa.fOccupancyEstimatorName[eTrackOccupancyInTimeRange].Data()); + nBins_y_Event[eTrackOccupancyInTimeRange_vs_FT0COccupancyInTimeRange] = static_cast(eh.fEventHistogramsBins[eOccupancy][0] / qa.fRebin); + min_y_Event[eTrackOccupancyInTimeRange_vs_FT0COccupancyInTimeRange] = eh.fEventHistogramsBins[eOccupancy][1]; + max_y_Event[eTrackOccupancyInTimeRange_vs_FT0COccupancyInTimeRange] = eh.fEventHistogramsBins[eOccupancy][2]; + title_y_Event[eTrackOccupancyInTimeRange_vs_FT0COccupancyInTimeRange] = FancyFormatting(qa.fOccupancyEstimatorName[eFT0COccupancyInTimeRange].Data()); + + // *) "CurrentRunDuration_vs_InteractionRate": + nBins_x_Event[eCurrentRunDuration_vs_InteractionRate] = static_cast(eh.fEventHistogramsBins[eCurrentRunDuration][0] / qa.fRebin); + min_x_Event[eCurrentRunDuration_vs_InteractionRate] = eh.fEventHistogramsBins[eCurrentRunDuration][1]; + max_x_Event[eCurrentRunDuration_vs_InteractionRate] = eh.fEventHistogramsBins[eCurrentRunDuration][2]; + title_x_Event[eCurrentRunDuration_vs_InteractionRate] = FancyFormatting(eh.fEventHistogramsName[eCurrentRunDuration].Data()); + nBins_y_Event[eCurrentRunDuration_vs_InteractionRate] = static_cast(eh.fEventHistogramsBins[eInteractionRate][0] / qa.fRebin); + min_y_Event[eCurrentRunDuration_vs_InteractionRate] = eh.fEventHistogramsBins[eInteractionRate][1]; + max_y_Event[eCurrentRunDuration_vs_InteractionRate] = eh.fEventHistogramsBins[eInteractionRate][2]; + title_y_Event[eCurrentRunDuration_vs_InteractionRate] = FancyFormatting(eh.fEventHistogramsName[eInteractionRate].Data()); + + // ... + + // *) Quick insanity check on title_x_Event and title_y_Event: + for (int t = 0; t < eQAEventHistograms2D_N; t++) { + + // **) title_x_Event: + if (tc.fVerbose) { + LOGF(info, "\033[1;32m title_x_Event[%d] = %s \033[0m", t, title_x_Event[t].Data()); + } + if (title_x_Event[t].EqualTo("")) { + LOGF(fatal, "\033[1;31m%s at line %d : title_x_Event[%d] is not set, check corresponding enum \033[0m", __FUNCTION__, __LINE__, t); + } + + // **) title_y_Event: + if (tc.fVerbose) { + LOGF(info, "\033[1;32m title_y_Event[%d] = %s \033[0m", t, title_y_Event[t].Data()); + } + if (title_y_Event[t].EqualTo("")) { + LOGF(fatal, "\033[1;31m%s at line %d : title_y_Event[%d] is not set, check corresponding enum \033[0m", __FUNCTION__, __LINE__, t); + } + + } // for (int t = 0; t < eQAEventHistograms2D_N; t++) { + + // Okay, let's book 'em all: + for (int t = 0; t < eQAEventHistograms2D_N; t++) // type, see enum eQAEventHistograms2D + { + if (!qa.fBookQAEventHistograms2D[t]) { + continue; + } + for (int rs = 0; rs < 2; rs++) // reco/sim + { + + if (Skip(rs)) { + continue; + } + + for (int ba = 0; ba < 2; ba++) // before/after cuts + { + + // Special treatment for eMultiplicity => I will never fill this one before the cuts, if Multiplicity = SelectedTracks, obviously: + if (ba == eBefore && (title_x_Event[t].BeginsWith("Multiplicity") || title_y_Event[t].BeginsWith("Multiplicity")) && ec.fsEventCuts[eMultiplicityEstimator].EqualTo("SelectedTracks", TString::kIgnoreCase)) { + // TBI 20241123 what remains ill-defined is the case when Multiplicity != SelectedTracks , check that further + // TBI 20241123 not sure if checking with BeginsWith(...) x2 is robust enough + // TBI 20241123 just like I have Skip(rs), introduce the same thingie for "ba" counter + propagate to other member functions + // TBI 20241124 there is a corner case when eMultiplicityEstimator itself is "ReferenceMultiplicity" => all 2D QA booked both before and after cuts, + // but it's filled trivially before the cuts, because Multiplicity is always 0. Re-think this at some point. + continue; + } + + // valgrind --tool=massif => ~9.8 MiB (Last check: 20250315) + qa.fQAEventHistograms2D[t][rs][ba] = new TH2F( + TString::Format("fQAEventHistograms2D[%s][%s][%s]", qa.fEventHistogramsName2D[t].Data(), gc.srs[rs].Data(), gc.sba[ba].Data()), + TString::Format("%s, %s, %s", "__RUN_NUMBER__", gc.srsLong[rs].Data(), gc.sbaLong[ba].Data()), // __RUN_NUMBER__ is handled in PropagateRunNumber(...) + nBins_x_Event[t], min_x_Event[t], max_x_Event[t], nBins_y_Event[t], min_y_Event[t], max_y_Event[t]); + qa.fQAEventHistograms2D[t][rs][ba]->GetXaxis()->SetTitle(title_x_Event[t].Data()); + qa.fQAEventHistograms2D[t][rs][ba]->GetYaxis()->SetTitle(title_y_Event[t].Data()); + qa.fQAEventHistograms2D[t][rs][ba]->SetLineColor(ec.fBeforeAfterColor[ba]); + qa.fQAEventHistograms2D[t][rs][ba]->SetFillColor(ec.fBeforeAfterColor[ba] - 10); + qa.fQAEventHistograms2D[t][rs][ba]->SetOption("col"); + qa.fQAEventList->Add(qa.fQAEventHistograms2D[t][rs][ba]); + } // for(int ba=0;ba<2;ba++) + } // for(int rs=0;rs<2;rs++) // reco/sim + } // for(int t=0;t(ph.fParticleHistogramsBins[ePt][0]); // TBI 20240702 add support for rebinning + min_x_Particle[ePt_vs_dcaXY] = ph.fParticleHistogramsBins[ePt][1]; + max_x_Particle[ePt_vs_dcaXY] = ph.fParticleHistogramsBins[ePt][2]; + title_x_Particle[ePt_vs_dcaXY] = FancyFormatting(ph.fParticleHistogramsName[ePt].Data()); + nBins_y_Particle[ePt_vs_dcaXY] = static_cast(ph.fParticleHistogramsBins[edcaXY][0]); // TBI 20240702 add support for rebinning + min_y_Particle[ePt_vs_dcaXY] = ph.fParticleHistogramsBins[edcaXY][1]; + max_y_Particle[ePt_vs_dcaXY] = ph.fParticleHistogramsBins[edcaXY][2]; + title_y_Particle[ePt_vs_dcaXY] = FancyFormatting(ph.fParticleHistogramsName[edcaXY].Data()); + + // ... + + // *) Quick insanity check on title_x_Particle and title_y_Particle: + for (int t = 0; t < eQAParticleHistograms2D_N; t++) { + if (title_x_Particle[t].EqualTo("")) { + LOGF(fatal, "\033[1;31m%s at line %d : title_x_Particle[%d] is not set, check corresponding enum \033[0m", __FUNCTION__, __LINE__, t); + } + if (title_y_Particle[t].EqualTo("")) { + LOGF(fatal, "\033[1;31m%s at line %d : title_y_Particle[%d] is not set, check corresponding enum \033[0m", __FUNCTION__, __LINE__, t); + } + } + + // Okay, let's book 'em all: + for (int t = 0; t < eQAParticleHistograms2D_N; t++) // type, see enum eQAParticleHistograms2D + { + if (!qa.fBookQAParticleHistograms2D[t]) { + continue; + } + for (int rs = 0; rs < 2; rs++) // reco/sim + { + + if (Skip(rs)) { + continue; + } + + for (int ba = 0; ba < 2; ba++) // before/after cuts + { + // valgrind --tool=massif => ~30.6 MiB (Last check: 20250315) + qa.fQAParticleHistograms2D[t][rs][ba] = new TH2F( + TString::Format("fQAParticleHistograms2D[%s][%s][%s]", qa.fParticleHistogramsName2D[t].Data(), gc.srs[rs].Data(), gc.sba[ba].Data()), + TString::Format("%s, %s, %s", "__RUN_NUMBER__", gc.srsLong[rs].Data(), gc.sbaLong[ba].Data()), // __RUN_NUMBER__ is handled in PropagateRunNumber(...) + nBins_x_Particle[t], min_x_Particle[t], max_x_Particle[t], nBins_y_Particle[t], min_y_Particle[t], max_y_Particle[t]); + + qa.fQAParticleHistograms2D[t][rs][ba]->GetXaxis()->SetTitle(title_x_Particle[t].Data()); + qa.fQAParticleHistograms2D[t][rs][ba]->GetYaxis()->SetTitle(title_y_Particle[t].Data()); + qa.fQAParticleHistograms2D[t][rs][ba]->SetLineColor(ec.fBeforeAfterColor[ba]); + qa.fQAParticleHistograms2D[t][rs][ba]->SetFillColor(ec.fBeforeAfterColor[ba] - 10); + qa.fQAParticleHistograms2D[t][rs][ba]->SetOption("col"); + qa.fQAParticleList->Add(qa.fQAParticleHistograms2D[t][rs][ba]); + } // for(int ba=0;ba<2;ba++) + } // for(int rs=0;rs<2;rs++) // reco/sim + } // for(int t=0;t(eh.fEventHistogramsBins[eCurrentRunDuration][0]); + min_x_ParticleEvent[eCurrentRunDuration_vs_itsNClsEbyE] = eh.fEventHistogramsBins[eCurrentRunDuration][1]; + max_x_ParticleEvent[eCurrentRunDuration_vs_itsNClsEbyE] = eh.fEventHistogramsBins[eCurrentRunDuration][2]; + title_x_ParticleEvent[eCurrentRunDuration_vs_itsNClsEbyE] = FancyFormatting(eh.fEventHistogramsName[eCurrentRunDuration].Data()); + // nBins_y_ParticleEvent[eCurrentRunDuration_vs_itsNClsEbyE] = static_cast(ph.fParticleHistogramsBins[eitsNCls][0]); + nBins_y_ParticleEvent[eCurrentRunDuration_vs_itsNClsEbyE] = 100; + min_y_ParticleEvent[eCurrentRunDuration_vs_itsNClsEbyE] = ph.fParticleHistogramsBins[eitsNCls][1]; + max_y_ParticleEvent[eCurrentRunDuration_vs_itsNClsEbyE] = ph.fParticleHistogramsBins[eitsNCls][2]; + title_y_ParticleEvent[eCurrentRunDuration_vs_itsNClsEbyE] = TString::Format("#LT%s#GT", FancyFormatting(ph.fParticleHistogramsName[eitsNCls].Data())); + + // *) "eCurrentRunDuration_vs_itsNClsNegEtaEbyE": + nBins_x_ParticleEvent[eCurrentRunDuration_vs_itsNClsNegEtaEbyE] = static_cast(eh.fEventHistogramsBins[eCurrentRunDuration][0]); + min_x_ParticleEvent[eCurrentRunDuration_vs_itsNClsNegEtaEbyE] = eh.fEventHistogramsBins[eCurrentRunDuration][1]; + max_x_ParticleEvent[eCurrentRunDuration_vs_itsNClsNegEtaEbyE] = eh.fEventHistogramsBins[eCurrentRunDuration][2]; + title_x_ParticleEvent[eCurrentRunDuration_vs_itsNClsNegEtaEbyE] = FancyFormatting(eh.fEventHistogramsName[eCurrentRunDuration].Data()); + nBins_y_ParticleEvent[eCurrentRunDuration_vs_itsNClsNegEtaEbyE] = 100; + min_y_ParticleEvent[eCurrentRunDuration_vs_itsNClsNegEtaEbyE] = ph.fParticleHistogramsBins[eitsNCls][1]; + max_y_ParticleEvent[eCurrentRunDuration_vs_itsNClsNegEtaEbyE] = ph.fParticleHistogramsBins[eitsNCls][2]; + title_y_ParticleEvent[eCurrentRunDuration_vs_itsNClsNegEtaEbyE] = TString::Format("#LT%s#GT, #eta < 0", FancyFormatting(ph.fParticleHistogramsName[eitsNCls].Data())); + + // *) "eCurrentRunDuration_vs_itsNClsPosEtaEbyE": + nBins_x_ParticleEvent[eCurrentRunDuration_vs_itsNClsPosEtaEbyE] = static_cast(eh.fEventHistogramsBins[eCurrentRunDuration][0]); + min_x_ParticleEvent[eCurrentRunDuration_vs_itsNClsPosEtaEbyE] = eh.fEventHistogramsBins[eCurrentRunDuration][1]; + max_x_ParticleEvent[eCurrentRunDuration_vs_itsNClsPosEtaEbyE] = eh.fEventHistogramsBins[eCurrentRunDuration][2]; + title_x_ParticleEvent[eCurrentRunDuration_vs_itsNClsPosEtaEbyE] = FancyFormatting(eh.fEventHistogramsName[eCurrentRunDuration].Data()); + nBins_y_ParticleEvent[eCurrentRunDuration_vs_itsNClsPosEtaEbyE] = 100; + min_y_ParticleEvent[eCurrentRunDuration_vs_itsNClsPosEtaEbyE] = ph.fParticleHistogramsBins[eitsNCls][1]; + max_y_ParticleEvent[eCurrentRunDuration_vs_itsNClsPosEtaEbyE] = ph.fParticleHistogramsBins[eitsNCls][2]; + title_y_ParticleEvent[eCurrentRunDuration_vs_itsNClsPosEtaEbyE] = TString::Format("#LT%s#GT, #eta > 0", FancyFormatting(ph.fParticleHistogramsName[eitsNCls].Data())); + + // *) "eCurrentRunDuration_vs_Eta0804EbyE": + nBins_x_ParticleEvent[eCurrentRunDuration_vs_Eta0804EbyE] = static_cast(eh.fEventHistogramsBins[eCurrentRunDuration][0]); + min_x_ParticleEvent[eCurrentRunDuration_vs_Eta0804EbyE] = eh.fEventHistogramsBins[eCurrentRunDuration][1]; + max_x_ParticleEvent[eCurrentRunDuration_vs_Eta0804EbyE] = eh.fEventHistogramsBins[eCurrentRunDuration][2]; + title_x_ParticleEvent[eCurrentRunDuration_vs_Eta0804EbyE] = FancyFormatting(eh.fEventHistogramsName[eCurrentRunDuration].Data()); + nBins_y_ParticleEvent[eCurrentRunDuration_vs_Eta0804EbyE] = 80; + min_y_ParticleEvent[eCurrentRunDuration_vs_Eta0804EbyE] = -1.0; // TBI 20241214 intentionally temporarily overshooting, to trace down overflow and underflow, if any + max_y_ParticleEvent[eCurrentRunDuration_vs_Eta0804EbyE] = 1.0; // TBI 20241214 intentionally temporarily overshooting, to trace down overflow and underflow, if any + title_y_ParticleEvent[eCurrentRunDuration_vs_Eta0804EbyE] = TString::Format("#LT%s#GT, -0.8 < #eta < -0.4", FancyFormatting(ph.fParticleHistogramsName[eEta].Data())); + + // *) "eCurrentRunDuration_vs_Eta0400EbyE": + nBins_x_ParticleEvent[eCurrentRunDuration_vs_Eta0400EbyE] = static_cast(eh.fEventHistogramsBins[eCurrentRunDuration][0]); + min_x_ParticleEvent[eCurrentRunDuration_vs_Eta0400EbyE] = eh.fEventHistogramsBins[eCurrentRunDuration][1]; + max_x_ParticleEvent[eCurrentRunDuration_vs_Eta0400EbyE] = eh.fEventHistogramsBins[eCurrentRunDuration][2]; + title_x_ParticleEvent[eCurrentRunDuration_vs_Eta0400EbyE] = FancyFormatting(eh.fEventHistogramsName[eCurrentRunDuration].Data()); + nBins_y_ParticleEvent[eCurrentRunDuration_vs_Eta0400EbyE] = 80; + min_y_ParticleEvent[eCurrentRunDuration_vs_Eta0400EbyE] = -1.0; + max_y_ParticleEvent[eCurrentRunDuration_vs_Eta0400EbyE] = 1.0; + title_y_ParticleEvent[eCurrentRunDuration_vs_Eta0400EbyE] = TString::Format("#LT%s#GT, -0.4 < #eta < 0.0", FancyFormatting(ph.fParticleHistogramsName[eEta].Data())); + + // *) "eCurrentRunDuration_vs_Eta0004EbyE": + nBins_x_ParticleEvent[eCurrentRunDuration_vs_Eta0004EbyE] = static_cast(eh.fEventHistogramsBins[eCurrentRunDuration][0]); + min_x_ParticleEvent[eCurrentRunDuration_vs_Eta0004EbyE] = eh.fEventHistogramsBins[eCurrentRunDuration][1]; + max_x_ParticleEvent[eCurrentRunDuration_vs_Eta0004EbyE] = eh.fEventHistogramsBins[eCurrentRunDuration][2]; + title_x_ParticleEvent[eCurrentRunDuration_vs_Eta0004EbyE] = FancyFormatting(eh.fEventHistogramsName[eCurrentRunDuration].Data()); + nBins_y_ParticleEvent[eCurrentRunDuration_vs_Eta0004EbyE] = 80; + min_y_ParticleEvent[eCurrentRunDuration_vs_Eta0004EbyE] = -1.0; + max_y_ParticleEvent[eCurrentRunDuration_vs_Eta0004EbyE] = 1.0; + title_y_ParticleEvent[eCurrentRunDuration_vs_Eta0004EbyE] = TString::Format("#LT%s#GT, 0.0 < #eta < 0.4", FancyFormatting(ph.fParticleHistogramsName[eEta].Data())); + + // *) "eCurrentRunDuration_vs_Eta0408EbyE": + nBins_x_ParticleEvent[eCurrentRunDuration_vs_Eta0408EbyE] = static_cast(eh.fEventHistogramsBins[eCurrentRunDuration][0]); + min_x_ParticleEvent[eCurrentRunDuration_vs_Eta0408EbyE] = eh.fEventHistogramsBins[eCurrentRunDuration][1]; + max_x_ParticleEvent[eCurrentRunDuration_vs_Eta0408EbyE] = eh.fEventHistogramsBins[eCurrentRunDuration][2]; + title_x_ParticleEvent[eCurrentRunDuration_vs_Eta0408EbyE] = FancyFormatting(eh.fEventHistogramsName[eCurrentRunDuration].Data()); + nBins_y_ParticleEvent[eCurrentRunDuration_vs_Eta0408EbyE] = 80; + min_y_ParticleEvent[eCurrentRunDuration_vs_Eta0408EbyE] = -1.0; + max_y_ParticleEvent[eCurrentRunDuration_vs_Eta0408EbyE] = 1.0; + title_y_ParticleEvent[eCurrentRunDuration_vs_Eta0408EbyE] = TString::Format("#LT%s#GT, 0.4 < #eta < 0.8", FancyFormatting(ph.fParticleHistogramsName[eEta].Data())); + + // *) "eCurrentRunDuration_vs_Pt0005EbyE": + nBins_x_ParticleEvent[eCurrentRunDuration_vs_Pt0005EbyE] = static_cast(eh.fEventHistogramsBins[eCurrentRunDuration][0]); + min_x_ParticleEvent[eCurrentRunDuration_vs_Pt0005EbyE] = eh.fEventHistogramsBins[eCurrentRunDuration][1]; + max_x_ParticleEvent[eCurrentRunDuration_vs_Pt0005EbyE] = eh.fEventHistogramsBins[eCurrentRunDuration][2]; + title_x_ParticleEvent[eCurrentRunDuration_vs_Pt0005EbyE] = FancyFormatting(eh.fEventHistogramsName[eCurrentRunDuration].Data()); + nBins_y_ParticleEvent[eCurrentRunDuration_vs_Pt0005EbyE] = 400; + min_y_ParticleEvent[eCurrentRunDuration_vs_Pt0005EbyE] = 0.0; // TBI 20241214 intentionally temporarilyovershooting, to trace down overflow and underflow, if any + max_y_ParticleEvent[eCurrentRunDuration_vs_Pt0005EbyE] = 10.0; // TBI 20241214 intentionally temporarily overshooting, to trace down overflow and underflow, if any + title_y_ParticleEvent[eCurrentRunDuration_vs_Pt0005EbyE] = TString::Format("#LT%s#GT, 0.0 < p_{T} < 0.5 GeV/c", FancyFormatting(ph.fParticleHistogramsName[ePt].Data())); + + // *) "eCurrentRunDuration_vs_Pt0510EbyE": + nBins_x_ParticleEvent[eCurrentRunDuration_vs_Pt0510EbyE] = static_cast(eh.fEventHistogramsBins[eCurrentRunDuration][0]); + min_x_ParticleEvent[eCurrentRunDuration_vs_Pt0510EbyE] = eh.fEventHistogramsBins[eCurrentRunDuration][1]; + max_x_ParticleEvent[eCurrentRunDuration_vs_Pt0510EbyE] = eh.fEventHistogramsBins[eCurrentRunDuration][2]; + title_x_ParticleEvent[eCurrentRunDuration_vs_Pt0510EbyE] = FancyFormatting(eh.fEventHistogramsName[eCurrentRunDuration].Data()); + nBins_y_ParticleEvent[eCurrentRunDuration_vs_Pt0510EbyE] = 400; + min_y_ParticleEvent[eCurrentRunDuration_vs_Pt0510EbyE] = 0.0; + max_y_ParticleEvent[eCurrentRunDuration_vs_Pt0510EbyE] = 10.0; + title_y_ParticleEvent[eCurrentRunDuration_vs_Pt0510EbyE] = TString::Format("#LT%s#GT, 0.5 < p_{T} < 1.0 GeV/c", FancyFormatting(ph.fParticleHistogramsName[ePt].Data())); + + // *) "eCurrentRunDuration_vs_Pt1050EbyE": + nBins_x_ParticleEvent[eCurrentRunDuration_vs_Pt1050EbyE] = static_cast(eh.fEventHistogramsBins[eCurrentRunDuration][0]); + min_x_ParticleEvent[eCurrentRunDuration_vs_Pt1050EbyE] = eh.fEventHistogramsBins[eCurrentRunDuration][1]; + max_x_ParticleEvent[eCurrentRunDuration_vs_Pt1050EbyE] = eh.fEventHistogramsBins[eCurrentRunDuration][2]; + title_x_ParticleEvent[eCurrentRunDuration_vs_Pt1050EbyE] = FancyFormatting(eh.fEventHistogramsName[eCurrentRunDuration].Data()); + nBins_y_ParticleEvent[eCurrentRunDuration_vs_Pt1050EbyE] = 400; + min_y_ParticleEvent[eCurrentRunDuration_vs_Pt1050EbyE] = 0.0; + max_y_ParticleEvent[eCurrentRunDuration_vs_Pt1050EbyE] = 10.0; + title_y_ParticleEvent[eCurrentRunDuration_vs_Pt1050EbyE] = TString::Format("#LT%s#GT, 1.0 < p_{T} < 5.0 GeV/c", FancyFormatting(ph.fParticleHistogramsName[ePt].Data())); + + // ... + + // *) Quick insanity check on title_x_ParticleEvent and title_y_ParticleEvent: + for (int t = 0; t < eQAParticleEventHistograms2D_N; t++) { + if (title_x_ParticleEvent[t].EqualTo("")) { + LOGF(fatal, "\033[1;31m%s at line %d : title_x_ParticleEvent[%d] is not set, check corresponding enum \033[0m", __FUNCTION__, __LINE__, t); + } + if (title_y_ParticleEvent[t].EqualTo("")) { + LOGF(fatal, "\033[1;31m%s at line %d : title_y_ParticleEvent[%d] is not set, check corresponding enum \033[0m", __FUNCTION__, __LINE__, t); + } + } + + // Okay, let's book 'em all: + for (int t = 0; t < eQAParticleEventHistograms2D_N; t++) // type, see enum eQAParticleEventHistograms2D + { + if (!qa.fBookQAParticleEventHistograms2D[t]) { + continue; + } + for (int rs = 0; rs < 2; rs++) // reco/sim + { + + if (Skip(rs)) { + continue; + } + + for (int ba = 0; ba < 2; ba++) // before/after cuts + { + + if (ba == eBefore) { // TBI 20241214 re-think if I need these additional QA particle event histos before cuts + continue; + } + + // valgrind --tool=massif => ~70.2 MiB (Last check: 20250315) + qa.fQAParticleEventHistograms2D[t][rs][ba] = new TH2F( + TString::Format("fQAParticleEventHistograms2D[%s][%s][%s]", qa.fQAParticleEventHistogramsName2D[t].Data(), gc.srs[rs].Data(), gc.sba[ba].Data()), + TString::Format("%s, %s, %s", "__RUN_NUMBER__", gc.srsLong[rs].Data(), gc.sbaLong[ba].Data()), // __RUN_NUMBER__ is handled in PropagateRunNumber(...) + nBins_x_ParticleEvent[t], min_x_ParticleEvent[t], max_x_ParticleEvent[t], nBins_y_ParticleEvent[t], min_y_ParticleEvent[t], max_y_ParticleEvent[t]); + + qa.fQAParticleEventHistograms2D[t][rs][ba]->GetXaxis()->SetTitle(title_x_ParticleEvent[t].Data()); + qa.fQAParticleEventHistograms2D[t][rs][ba]->GetYaxis()->SetTitle(title_y_ParticleEvent[t].Data()); + qa.fQAParticleEventHistograms2D[t][rs][ba]->SetLineColor(ec.fBeforeAfterColor[ba]); + qa.fQAParticleEventHistograms2D[t][rs][ba]->SetFillColor(ec.fBeforeAfterColor[ba] - 10); + qa.fQAParticleEventHistograms2D[t][rs][ba]->SetOption("col"); + qa.fQAParticleEventList->Add(qa.fQAParticleEventHistograms2D[t][rs][ba]); + } // for(int ba=0;ba<2;ba++) + } // for(int rs=0;rs<2;rs++) // reco/sim + } // for(int t=0;t(eh.fEventHistogramsBins[eMultiplicity][0] / 10); // TBI 20250331 here I have temporarily hardwired rebin value + min_y_CorrelationsVs[eCorrelations_vs_Multiplicity] = eh.fEventHistogramsBins[eMultiplicity][1]; + max_y_CorrelationsVs[eCorrelations_vs_Multiplicity] = eh.fEventHistogramsBins[eMultiplicity][2]; + title_y_CorrelationsVs[eCorrelations_vs_Multiplicity] = FancyFormatting(eh.fEventHistogramsName[eMultiplicity].Data()); + + // *) "eCorrelations_vs_ReferenceMultiplicity": + nBins_y_CorrelationsVs[eCorrelations_vs_ReferenceMultiplicity] = static_cast(eh.fEventHistogramsBins[eReferenceMultiplicity][0] / 10); // TBI 20250331 here I have temporarily hardwired rebin value + min_y_CorrelationsVs[eCorrelations_vs_ReferenceMultiplicity] = eh.fEventHistogramsBins[eReferenceMultiplicity][1]; + max_y_CorrelationsVs[eCorrelations_vs_ReferenceMultiplicity] = eh.fEventHistogramsBins[eReferenceMultiplicity][2]; + title_y_CorrelationsVs[eCorrelations_vs_ReferenceMultiplicity] = FancyFormatting(eh.fEventHistogramsName[eReferenceMultiplicity].Data()); + + // *) "eCorrelations_vs_Centrality": + nBins_y_CorrelationsVs[eCorrelations_vs_Centrality] = static_cast(eh.fEventHistogramsBins[eCentrality][0]); + min_y_CorrelationsVs[eCorrelations_vs_Centrality] = eh.fEventHistogramsBins[eCentrality][1]; + max_y_CorrelationsVs[eCorrelations_vs_Centrality] = eh.fEventHistogramsBins[eCentrality][2]; + title_y_CorrelationsVs[eCorrelations_vs_Centrality] = FancyFormatting(eh.fEventHistogramsName[eCentrality].Data()); + + // ..... + + // *) "eCorrelations_vs_MeanPhi": + nBins_y_CorrelationsVs[eCorrelations_vs_MeanPhi] = 200; + min_y_CorrelationsVs[eCorrelations_vs_MeanPhi] = 2.; + max_y_CorrelationsVs[eCorrelations_vs_MeanPhi] = 4.; + title_y_CorrelationsVs[eCorrelations_vs_MeanPhi] = FancyFormatting(ph.fParticleHistogramsName[ePhi].Data()); + + // *) "eCorrelations_vs_MeanPt": + nBins_y_CorrelationsVs[eCorrelations_vs_MeanPt] = 100; + min_y_CorrelationsVs[eCorrelations_vs_MeanPt] = 0.0; + max_y_CorrelationsVs[eCorrelations_vs_MeanPt] = 2.0; + title_y_CorrelationsVs[eCorrelations_vs_MeanPt] = FancyFormatting(ph.fParticleHistogramsName[ePt].Data()); + + // *) "eCorrelations_vs_MeanEta": + nBins_y_CorrelationsVs[eCorrelations_vs_MeanEta] = 200; + min_y_CorrelationsVs[eCorrelations_vs_MeanEta] = -0.3; + max_y_CorrelationsVs[eCorrelations_vs_MeanEta] = 0.3; + title_y_CorrelationsVs[eCorrelations_vs_MeanEta] = FancyFormatting(ph.fParticleHistogramsName[eEta].Data()); + + // *) "eCorrelations_vs_MeanCharge": + nBins_y_CorrelationsVs[eCorrelations_vs_MeanCharge] = 200; + min_y_CorrelationsVs[eCorrelations_vs_MeanCharge] = -1.; + max_y_CorrelationsVs[eCorrelations_vs_MeanCharge] = 1.; + title_y_CorrelationsVs[eCorrelations_vs_MeanCharge] = FancyFormatting(ph.fParticleHistogramsName[eCharge].Data()); + + // *) "eCorrelations_vs_MeantpcNClsFindable": + nBins_y_CorrelationsVs[eCorrelations_vs_MeantpcNClsFindable] = 400; + min_y_CorrelationsVs[eCorrelations_vs_MeantpcNClsFindable] = 50.; + max_y_CorrelationsVs[eCorrelations_vs_MeantpcNClsFindable] = 250.; + title_y_CorrelationsVs[eCorrelations_vs_MeantpcNClsFindable] = FancyFormatting(ph.fParticleHistogramsName[etpcNClsFindable].Data()); + + // *) "eCorrelations_vs_MeantpcNClsShared": + nBins_y_CorrelationsVs[eCorrelations_vs_MeantpcNClsShared] = 500; + min_y_CorrelationsVs[eCorrelations_vs_MeantpcNClsShared] = 0.; + max_y_CorrelationsVs[eCorrelations_vs_MeantpcNClsShared] = 100.; + title_y_CorrelationsVs[eCorrelations_vs_MeantpcNClsShared] = FancyFormatting(ph.fParticleHistogramsName[etpcNClsShared].Data()); + + // *) "eCorrelations_vs_MeanitsChi2NCl": + nBins_y_CorrelationsVs[eCorrelations_vs_MeanitsChi2NCl] = 200; + min_y_CorrelationsVs[eCorrelations_vs_MeanitsChi2NCl] = 0.; + max_y_CorrelationsVs[eCorrelations_vs_MeanitsChi2NCl] = 4.; + title_y_CorrelationsVs[eCorrelations_vs_MeanitsChi2NCl] = FancyFormatting(ph.fParticleHistogramsName[eitsChi2NCl].Data()); + + // *) "eCorrelations_vs_MeantpcNClsFound": + nBins_y_CorrelationsVs[eCorrelations_vs_MeantpcNClsFound] = 400; + min_y_CorrelationsVs[eCorrelations_vs_MeantpcNClsFound] = 50.; + max_y_CorrelationsVs[eCorrelations_vs_MeantpcNClsFound] = 250.; + title_y_CorrelationsVs[eCorrelations_vs_MeantpcNClsFound] = FancyFormatting(ph.fParticleHistogramsName[etpcNClsFound].Data()); + + // *) "eCorrelations_vs_MeantpcNClsCrossedRows": + nBins_y_CorrelationsVs[eCorrelations_vs_MeantpcNClsCrossedRows] = 400; + min_y_CorrelationsVs[eCorrelations_vs_MeantpcNClsCrossedRows] = 50.; + max_y_CorrelationsVs[eCorrelations_vs_MeantpcNClsCrossedRows] = 250.; + title_y_CorrelationsVs[eCorrelations_vs_MeantpcNClsCrossedRows] = FancyFormatting(ph.fParticleHistogramsName[etpcNClsCrossedRows].Data()); + + // *) "eCorrelations_vs_MeanitsNCls": + nBins_y_CorrelationsVs[eCorrelations_vs_MeanitsNCls] = 500; + min_y_CorrelationsVs[eCorrelations_vs_MeanitsNCls] = 0.; + max_y_CorrelationsVs[eCorrelations_vs_MeanitsNCls] = 10.; + title_y_CorrelationsVs[eCorrelations_vs_MeanitsNCls] = FancyFormatting(ph.fParticleHistogramsName[eitsNCls].Data()); + + // *) "eCorrelations_vs_MeanitsNClsInnerBarrel": + nBins_y_CorrelationsVs[eCorrelations_vs_MeanitsNClsInnerBarrel] = 400; + min_y_CorrelationsVs[eCorrelations_vs_MeanitsNClsInnerBarrel] = 0.; + max_y_CorrelationsVs[eCorrelations_vs_MeanitsNClsInnerBarrel] = 4.; + title_y_CorrelationsVs[eCorrelations_vs_MeanitsNClsInnerBarrel] = FancyFormatting(ph.fParticleHistogramsName[eitsNClsInnerBarrel].Data()); + + // *) "eCorrelations_vs_MeantpcCrossedRowsOverFindableCls": + nBins_y_CorrelationsVs[eCorrelations_vs_MeantpcCrossedRowsOverFindableCls] = 200; + min_y_CorrelationsVs[eCorrelations_vs_MeantpcCrossedRowsOverFindableCls] = 0.; + max_y_CorrelationsVs[eCorrelations_vs_MeantpcCrossedRowsOverFindableCls] = 2.; + title_y_CorrelationsVs[eCorrelations_vs_MeantpcCrossedRowsOverFindableCls] = FancyFormatting(ph.fParticleHistogramsName[etpcCrossedRowsOverFindableCls].Data()); + + // *) "eCorrelations_vs_MeantpcFoundOverFindableCls": + nBins_y_CorrelationsVs[eCorrelations_vs_MeantpcFoundOverFindableCls] = 200; + min_y_CorrelationsVs[eCorrelations_vs_MeantpcFoundOverFindableCls] = 0.8; + max_y_CorrelationsVs[eCorrelations_vs_MeantpcFoundOverFindableCls] = 1.2; + title_y_CorrelationsVs[eCorrelations_vs_MeantpcFoundOverFindableCls] = FancyFormatting(ph.fParticleHistogramsName[etpcFoundOverFindableCls].Data()); + + // *) "eCorrelations_vs_MeantpcFractionSharedCls": + nBins_y_CorrelationsVs[eCorrelations_vs_MeantpcFractionSharedCls] = 500; + min_y_CorrelationsVs[eCorrelations_vs_MeantpcFractionSharedCls] = 0.; + max_y_CorrelationsVs[eCorrelations_vs_MeantpcFractionSharedCls] = 1.; + title_y_CorrelationsVs[eCorrelations_vs_MeantpcFractionSharedCls] = FancyFormatting(ph.fParticleHistogramsName[etpcFractionSharedCls].Data()); + + // *) "eCorrelations_vs_MeantpcChi2NCl": + nBins_y_CorrelationsVs[eCorrelations_vs_MeantpcChi2NCl] = 200; + min_y_CorrelationsVs[eCorrelations_vs_MeantpcChi2NCl] = 0.; + max_y_CorrelationsVs[eCorrelations_vs_MeantpcChi2NCl] = 2.; + title_y_CorrelationsVs[eCorrelations_vs_MeantpcChi2NCl] = FancyFormatting(ph.fParticleHistogramsName[etpcChi2NCl].Data()); + + // *) "eCorrelations_vs_MeandcaXY": + nBins_y_CorrelationsVs[eCorrelations_vs_MeandcaXY] = 200; + min_y_CorrelationsVs[eCorrelations_vs_MeandcaXY] = -0.2; + max_y_CorrelationsVs[eCorrelations_vs_MeandcaXY] = 0.2; + title_y_CorrelationsVs[eCorrelations_vs_MeandcaXY] = FancyFormatting(ph.fParticleHistogramsName[edcaXY].Data()); + + // *) "eCorrelations_vs_MeandcaZ": + nBins_y_CorrelationsVs[eCorrelations_vs_MeandcaZ] = 200; + min_y_CorrelationsVs[eCorrelations_vs_MeandcaZ] = -0.2; + max_y_CorrelationsVs[eCorrelations_vs_MeandcaZ] = 0.2; + title_y_CorrelationsVs[eCorrelations_vs_MeandcaZ] = FancyFormatting(ph.fParticleHistogramsName[edcaZ].Data()); + + // ..... + + // *) Quick insanity check on title_x_CorrelationsVs and title_y_CorrelationsVs: + if (title_x_CorrelationsVs.EqualTo("")) { + LOGF(fatal, "\033[1;31m%s at line %d : title_x_CorrelationsVs is not set, check corresponding enum \033[0m", __FUNCTION__, __LINE__); + } + for (int t = 0; t < eQACorrelationsVsHistograms2D_N; t++) { + if (title_y_CorrelationsVs[t].EqualTo("")) { + LOGF(fatal, "\033[1;31m%s at line %d : title_y_CorrelationsVs[%d] is not set, check corresponding enum \033[0m", __FUNCTION__, __LINE__, t); + } + } + + // Okay, let's book 'em all: + for (int t = 0; t < eQACorrelationsVsHistograms2D_N; t++) // type, see enum eQACorrelationsVsHistograms2D + { + if (!qa.fBookQACorrelationsVsHistograms2D[t]) { + continue; + } + + for (int h = 0; h < gMaxHarmonic; h++) { + + if (h + 1 < qa.fQACorrelationsVsHistogramsMinMaxHarmonic[eMin] || h + 1 >= qa.fQACorrelationsVsHistogramsMinMaxHarmonic[eMax]) { + continue; + } + + for (int rs = 0; rs < 2; rs++) // reco/sim + { + + if (Skip(rs)) { + continue; + } + + // valgrind --tool=massif => ~58.7 MiB (Last check: 20250315) + qa.fQACorrelationsVsHistograms2D[t][h][rs] = new TH2F( + TString::Format("fQACorrelationsVsHistograms2D[%s][%d][%s]", qa.fQACorrelationsVsHistogramsName2D[t].Data(), h, gc.srs[rs].Data()), + TString::Format("%s, %s", "__RUN_NUMBER__", gc.srsLong[rs].Data()), // __RUN_NUMBER__ is handled in PropagateRunNumber(...) + nBins_x_CorrelationsVs, min_x_CorrelationsVs, max_x_CorrelationsVs, nBins_y_CorrelationsVs[t], min_y_CorrelationsVs[t], max_y_CorrelationsVs[t]); + + qa.fQACorrelationsVsHistograms2D[t][h][rs]->GetXaxis()->SetTitle(TString::Format("%s (harmonic = %d)", title_x_CorrelationsVs.Data(), h + 1)); + qa.fQACorrelationsVsHistograms2D[t][h][rs]->GetYaxis()->SetTitle(title_y_CorrelationsVs[t].Data()); + qa.fQACorrelationsVsHistograms2D[t][h][rs]->SetLineColor(ec.fBeforeAfterColor[eAfter]); + qa.fQACorrelationsVsHistograms2D[t][h][rs]->SetFillColor(ec.fBeforeAfterColor[eAfter] - 10); + qa.fQACorrelationsVsHistograms2D[t][h][rs]->SetOption("col"); + qa.fQACorrelationsVsList->Add(qa.fQACorrelationsVsHistograms2D[t][h][rs]); + } // for(int rs=0;rs<2;rs++) // reco/sim + + } // for (int h = 0; h < gMaxHarmonic; h++) { + + } // for(int t=0;t(eh.fEventHistogramsBins[eInteractionRate][0] / qa.fRebin); + double min_x_CorrelationsVsInteractionRateVs = eh.fEventHistogramsBins[eInteractionRate][1]; + double max_x_CorrelationsVsInteractionRateVs = eh.fEventHistogramsBins[eInteractionRate][2]; + TString title_x_CorrelationsVsInteractionRateVs = "interaction rate"; + int nBins_y_CorrelationsVsInteractionRateVs[eQACorrelationsVsInteractionRateVsProfiles2D_N] = {0}; + double min_y_CorrelationsVsInteractionRateVs[eQACorrelationsVsInteractionRateVsProfiles2D_N] = {0.}; + double max_y_CorrelationsVsInteractionRateVs[eQACorrelationsVsInteractionRateVsProfiles2D_N] = {0.}; + TString title_y_CorrelationsVsInteractionRateVs[eQACorrelationsVsInteractionRateVsProfiles2D_N] = {""}; + + // *) "eCorrelationsVsInteractionRate_vs_CurrentRunDuration": + nBins_y_CorrelationsVsInteractionRateVs[eCorrelationsVsInteractionRate_vs_CurrentRunDuration] = static_cast(eh.fEventHistogramsBins[eCurrentRunDuration][0] / qa.fRebin); + min_y_CorrelationsVsInteractionRateVs[eCorrelationsVsInteractionRate_vs_CurrentRunDuration] = eh.fEventHistogramsBins[eCurrentRunDuration][1]; + max_y_CorrelationsVsInteractionRateVs[eCorrelationsVsInteractionRate_vs_CurrentRunDuration] = eh.fEventHistogramsBins[eCurrentRunDuration][2]; + title_y_CorrelationsVsInteractionRateVs[eCorrelationsVsInteractionRate_vs_CurrentRunDuration] = FancyFormatting(eh.fEventHistogramsName[eCurrentRunDuration].Data()); + + // *) "eCorrelationsVsInteractionRate_vs_Multiplicity": + nBins_y_CorrelationsVsInteractionRateVs[eCorrelationsVsInteractionRate_vs_Multiplicity] = static_cast(eh.fEventHistogramsBins[eMultiplicity][0] / qa.fRebin); + min_y_CorrelationsVsInteractionRateVs[eCorrelationsVsInteractionRate_vs_Multiplicity] = eh.fEventHistogramsBins[eMultiplicity][1]; + max_y_CorrelationsVsInteractionRateVs[eCorrelationsVsInteractionRate_vs_Multiplicity] = eh.fEventHistogramsBins[eMultiplicity][2]; + title_y_CorrelationsVsInteractionRateVs[eCorrelationsVsInteractionRate_vs_Multiplicity] = FancyFormatting(eh.fEventHistogramsName[eMultiplicity].Data()); + + // *) "eCorrelationsVsInteractionRate_vs_ReferenceMultiplicity": + nBins_y_CorrelationsVsInteractionRateVs[eCorrelationsVsInteractionRate_vs_ReferenceMultiplicity] = static_cast(eh.fEventHistogramsBins[eReferenceMultiplicity][0] / qa.fRebin); + min_y_CorrelationsVsInteractionRateVs[eCorrelationsVsInteractionRate_vs_ReferenceMultiplicity] = eh.fEventHistogramsBins[eReferenceMultiplicity][1]; + max_y_CorrelationsVsInteractionRateVs[eCorrelationsVsInteractionRate_vs_ReferenceMultiplicity] = eh.fEventHistogramsBins[eReferenceMultiplicity][2]; + title_y_CorrelationsVsInteractionRateVs[eCorrelationsVsInteractionRate_vs_ReferenceMultiplicity] = FancyFormatting(eh.fEventHistogramsName[eReferenceMultiplicity].Data()); + + // *) "eCorrelationsVsInteractionRate_vs_Centrality": + nBins_y_CorrelationsVsInteractionRateVs[eCorrelationsVsInteractionRate_vs_Centrality] = static_cast(eh.fEventHistogramsBins[eCentrality][0]); + min_y_CorrelationsVsInteractionRateVs[eCorrelationsVsInteractionRate_vs_Centrality] = eh.fEventHistogramsBins[eCentrality][1]; + max_y_CorrelationsVsInteractionRateVs[eCorrelationsVsInteractionRate_vs_Centrality] = eh.fEventHistogramsBins[eCentrality][2]; + title_y_CorrelationsVsInteractionRateVs[eCorrelationsVsInteractionRate_vs_Centrality] = FancyFormatting(eh.fEventHistogramsName[eCentrality].Data()); + + // ..... + + // *) "eCorrelationsVsInteractionRate_vs_MeanPhi": + nBins_y_CorrelationsVsInteractionRateVs[eCorrelationsVsInteractionRate_vs_MeanPhi] = 200; + min_y_CorrelationsVsInteractionRateVs[eCorrelationsVsInteractionRate_vs_MeanPhi] = 0.; + max_y_CorrelationsVsInteractionRateVs[eCorrelationsVsInteractionRate_vs_MeanPhi] = o2::constants::math::TwoPI; + title_y_CorrelationsVsInteractionRateVs[eCorrelationsVsInteractionRate_vs_MeanPhi] = FancyFormatting(ph.fParticleHistogramsName[ePhi].Data()); + + // *) "eCorrelationsVsInteractionRate_vs_SigmaMeanPhi": + nBins_y_CorrelationsVsInteractionRateVs[eCorrelationsVsInteractionRate_vs_SigmaMeanPhi] = 200; + min_y_CorrelationsVsInteractionRateVs[eCorrelationsVsInteractionRate_vs_SigmaMeanPhi] = 0.; + max_y_CorrelationsVsInteractionRateVs[eCorrelationsVsInteractionRate_vs_SigmaMeanPhi] = 1.0; + title_y_CorrelationsVsInteractionRateVs[eCorrelationsVsInteractionRate_vs_SigmaMeanPhi] = TString::Format("#sigma_{%s}", FancyFormatting(ph.fParticleHistogramsName[ePhi].Data())); + + // *) "eCorrelationsVsInteractionRate_vs_MeanPt": + nBins_y_CorrelationsVsInteractionRateVs[eCorrelationsVsInteractionRate_vs_MeanPt] = 200; + min_y_CorrelationsVsInteractionRateVs[eCorrelationsVsInteractionRate_vs_MeanPt] = 0.0; + max_y_CorrelationsVsInteractionRateVs[eCorrelationsVsInteractionRate_vs_MeanPt] = 2.0; + title_y_CorrelationsVsInteractionRateVs[eCorrelationsVsInteractionRate_vs_MeanPt] = FancyFormatting(ph.fParticleHistogramsName[ePt].Data()); + + // *) "eCorrelationsVsInteractionRate_vs_SigmaMeanPt": + nBins_y_CorrelationsVsInteractionRateVs[eCorrelationsVsInteractionRate_vs_SigmaMeanPt] = 200; + min_y_CorrelationsVsInteractionRateVs[eCorrelationsVsInteractionRate_vs_SigmaMeanPt] = 0.; + max_y_CorrelationsVsInteractionRateVs[eCorrelationsVsInteractionRate_vs_SigmaMeanPt] = 1.0; + title_y_CorrelationsVsInteractionRateVs[eCorrelationsVsInteractionRate_vs_SigmaMeanPt] = TString::Format("#sigma_{%s}", FancyFormatting(ph.fParticleHistogramsName[ePt].Data())); + + // *) "eCorrelationsVsInteractionRate_vs_MeanEta": + nBins_y_CorrelationsVsInteractionRateVs[eCorrelationsVsInteractionRate_vs_MeanEta] = 600; + min_y_CorrelationsVsInteractionRateVs[eCorrelationsVsInteractionRate_vs_MeanEta] = -0.5; + max_y_CorrelationsVsInteractionRateVs[eCorrelationsVsInteractionRate_vs_MeanEta] = 0.5; + title_y_CorrelationsVsInteractionRateVs[eCorrelationsVsInteractionRate_vs_MeanEta] = FancyFormatting(ph.fParticleHistogramsName[eEta].Data()); + + // *) "eCorrelationsVsInteractionRate_vs_SigmaMeanEta": + nBins_y_CorrelationsVsInteractionRateVs[eCorrelationsVsInteractionRate_vs_SigmaMeanEta] = 200; + min_y_CorrelationsVsInteractionRateVs[eCorrelationsVsInteractionRate_vs_SigmaMeanEta] = 0.; + max_y_CorrelationsVsInteractionRateVs[eCorrelationsVsInteractionRate_vs_SigmaMeanEta] = 1.0; + title_y_CorrelationsVsInteractionRateVs[eCorrelationsVsInteractionRate_vs_SigmaMeanEta] = TString::Format("#sigma_{%s}", FancyFormatting(ph.fParticleHistogramsName[eEta].Data())); + + // ..... + + // *) Quick insanity check on title_x_CorrelationsVsInteractionRateVs and title_y_CorrelationsVsInteractionRateVs: + if (title_x_CorrelationsVsInteractionRateVs.EqualTo("")) { + LOGF(fatal, "\033[1;31m%s at line %d : title_x_CorrelationsVsInteractionRateVs is not set, check corresponding enum \033[0m", __FUNCTION__, __LINE__); + } + for (int t = 0; t < eQACorrelationsVsInteractionRateVsProfiles2D_N; t++) { + if (title_y_CorrelationsVsInteractionRateVs[t].EqualTo("")) { + LOGF(fatal, "\033[1;31m%s at line %d : title_y_CorrelationsVsInteractionRateVs[%d] is not set, check corresponding enum \033[0m", __FUNCTION__, __LINE__, t); + } + } + + // Okay, let's book 'em all: + for (int t = 0; t < eQACorrelationsVsInteractionRateVsProfiles2D_N; t++) // type, see enum eQACorrelationsVsInteractionRateVsProfiles2D + { + if (!qa.fBookQACorrelationsVsInteractionRateVsProfiles2D[t]) { + continue; + } + + for (int h = 0; h < gMaxHarmonic; h++) { + + if (h + 1 < qa.fQACorrelationsVsInteractionRateVsProfilesMinMaxHarmonic[eMin] || h + 1 >= qa.fQACorrelationsVsInteractionRateVsProfilesMinMaxHarmonic[eMax]) { + continue; + } + + for (int rs = 0; rs < 2; rs++) // reco/sim + { + + if (Skip(rs)) { + continue; + } + + // TBI 20250317 documet here the output of profiling using valgrind --tool=massif + qa.fQACorrVsIRVsProfiles2D[t][h][rs] = new TProfile2D( + TString::Format("fQACorrVsIRVsProfiles2D[%s][%d][%s]", qa.fQACorrelationsVsInteractionRateVsProfilesName2D[t].Data(), h, gc.srs[rs].Data()), + TString::Format("%s, %s", "__RUN_NUMBER__", gc.srsLong[rs].Data()), // __RUN_NUMBER__ is handled in PropagateRunNumber(...) + nBins_x_CorrelationsVsInteractionRateVs, min_x_CorrelationsVsInteractionRateVs, max_x_CorrelationsVsInteractionRateVs, nBins_y_CorrelationsVsInteractionRateVs[t], min_y_CorrelationsVsInteractionRateVs[t], max_y_CorrelationsVsInteractionRateVs[t]); + + TString tmp = qa.fQACorrVsIRVsProfiles2D[t][h][rs]->GetTitle(); // translating e.g. "544114, reconstructed" into "<<2>> (harmonic = 2), 544114, reconstructed" + qa.fQACorrVsIRVsProfiles2D[t][h][rs]->SetTitle(TString::Format("#LT#LT2#GT#GT (harmonic = %d), %s", h + 1, tmp.Data())); + qa.fQACorrVsIRVsProfiles2D[t][h][rs]->GetXaxis()->SetTitle(title_x_CorrelationsVsInteractionRateVs.Data()); + qa.fQACorrVsIRVsProfiles2D[t][h][rs]->GetYaxis()->SetTitle(title_y_CorrelationsVsInteractionRateVs[t].Data()); + qa.fQACorrVsIRVsProfiles2D[t][h][rs]->SetLineColor(ec.fBeforeAfterColor[eAfter]); + qa.fQACorrVsIRVsProfiles2D[t][h][rs]->SetFillColor(ec.fBeforeAfterColor[eAfter] - 10); + qa.fQACorrVsIRVsProfiles2D[t][h][rs]->SetOption("col"); + qa.fQACorrelationsVsInteractionRateVsList->Add(qa.fQACorrVsIRVsProfiles2D[t][h][rs]); + } // for(int rs=0;rs<2;rs++) // reco/sim + + } // for (int h = 0; h < gMaxHarmonic; h++) { + + } // for(int t=0;tSetStats(false); + eh.fEventHistogramsPro->SetLineColor(eColor); + eh.fEventHistogramsPro->SetFillColor(eFillColor); + + if (tc.fUseSetBinLabel) { + eh.fEventHistogramsPro->GetXaxis()->SetBinLabel(1, "fFillEventHistograms"); + eh.fEventHistogramsPro->Fill(0.5, static_cast(eh.fFillEventHistograms)); + + // ... + + } else { + // Workaround for SetBinLabel() large memory consumption: + TString yAxisTitle = ""; + + yAxisTitle += TString::Format("%d:fFillEventHistograms; ", 1); // TBI 20250411 hardwired 1 + eh.fEventHistogramsPro->Fill(0.5, static_cast(eh.fFillEventHistograms)); // TBI 20250411 hardwired 0.5 + + // ... + + // *) Insanity check on the number of fields in this specially crafted y-axis title: + TObjArray* oa = yAxisTitle.Tokenize(";"); + if (!oa) { + LOGF(fatal, "\033[1;31m%s at line %d : oa is NULL\033[0m", __FUNCTION__, __LINE__); + } + if (oa->GetEntries() - 1 != eh.fEventHistogramsPro->GetNbinsX()) { + LOGF(fatal, "\033[1;31m%s at line %d : oa->GetEntries() - 1 = %d != eh.fEventHistogramsPro->GetNbinsX() = %d\033[0m", __FUNCTION__, __LINE__, oa->GetEntries(), eh.fEventHistogramsPro->GetNbinsX()); + } + delete oa; + + // *) Okay, set the title: + eh.fEventHistogramsPro->GetYaxis()->SetTitle(yAxisTitle.Data()); + + } // else + + eh.fEventHistogramsList->Add(eh.fEventHistogramsPro); + + // b) Book specific control event histograms 1D: + // ... + + for (int t = 0; t < eEventHistograms_N; t++) // type, see enum eEventHistograms + { + if (!eh.fBookEventHistograms[t]) { + continue; + } + + for (int rs = 0; rs < 2; rs++) // reco/sim + { + if (Skip(rs)) { + continue; + } + + for (int ba = 0; ba < 2; ba++) // before/after cuts + { + + // Special treatment for eMultiplicity => I will never fill this one before the cuts, if Multiplicity = SelectedTracks, obviously: + if (ba == eBefore && eh.fEventHistogramsName[t].EqualTo("Multiplicity") && ec.fsEventCuts[eMultiplicityEstimator].EqualTo("SelectedTracks", TString::kIgnoreCase)) { + // TBI 20241123 what remains ill-defined is the case when Multiplicity != SelectedTracks , check that further + continue; + } + eh.fEventHistograms[t][rs][ba] = new TH1F( + TString::Format("fEventHistograms[%s][%s][%s]", eh.fEventHistogramsName[t].Data(), gc.srs[rs].Data(), gc.sba[ba].Data()), + TString::Format("%s, %s, %s", "__RUN_NUMBER__", gc.srsLong[rs].Data(), gc.sbaLong[ba].Data()), // __RUN_NUMBER__ is handled in PropagateRunNumber(...) + static_cast(eh.fEventHistogramsBins[t][0]), + eh.fEventHistogramsBins[t][1], eh.fEventHistogramsBins[t][2]); + eh.fEventHistograms[t][rs][ba]->GetXaxis()->SetTitle(FancyFormatting(eh.fEventHistogramsName[t].Data())); + eh.fEventHistograms[t][rs][ba]->SetLineColor(ec.fBeforeAfterColor[ba]); + eh.fEventHistograms[t][rs][ba]->SetFillColor(ec.fBeforeAfterColor[ba] - 10); + eh.fEventHistogramsList->Add(eh.fEventHistograms[t][rs][ba]); + } // for(int ba=0;ba<2;ba++) + } // for(int rs=0;rs<2;rs++) // reco/sim + } // for(int t=0;t(eEventCuts_N) - 0.5); + if (tc.fUseSpecificCuts) { + ec.fEventCutsPro->SetTitle(TString::Format("%s (hardwired analysis-specific cuts = %s)", ec.fEventCutsPro->GetTitle(), tc.fWhichSpecificCuts.Data()).Data()); + } else { + ec.fEventCutsPro->SetTitle(TString::Format("%s (hardwired analysis-specific cuts not used)", ec.fEventCutsPro->GetTitle()).Data()); + } + ec.fEventCutsPro->SetStats(false); + ec.fEventCutsPro->SetLineColor(eColor); + ec.fEventCutsPro->SetFillColor(eFillColor); + ec.fEventCutsPro->GetXaxis()->SetLabelSize(0.020); + + TString yAxisTitle = ""; // TBI 20250413 when I fall back on using SetBinLabel(...), this variable is declared but will be unused + for (int cut = 0; cut < eEventCuts_N; cut++) { + + if (tc.fUseSetBinLabel) { + ec.fEventCutsPro->GetXaxis()->SetBinLabel(1 + cut, ec.fEventCutName[cut].Data()); // Remark: check always if bin labels here correspond to ordering in enum eEventCuts + } else { + // Workaround for SetBinLabel() large memory consumption: + yAxisTitle += TString::Format("%d:%s; ", 1 + cut, ec.fEventCutName[cut].Data()); + } + + ec.fEventCutsPro->Fill(cut, static_cast(ec.fUseEventCuts[cut])); + + } // for (int cut = 0; cut < eEventCuts_N; cut++) { + + // *) Insanity check on the number of fields in this specially crafted y-axis title: + if (!tc.fUseSetBinLabel) { + + TObjArray* oa = yAxisTitle.Tokenize(";"); + if (!oa) { + LOGF(fatal, "\033[1;31m%s at line %d : oa is NULL\033[0m", __FUNCTION__, __LINE__); + } + if (oa->GetEntries() - 1 != ec.fEventCutsPro->GetNbinsX()) { + LOGF(fatal, "\033[1;31m%s at line %d : oa->GetEntries() = %d != ec.fEventCutsPro->GetNbinsX() = %d\033[0m", __FUNCTION__, __LINE__, oa->GetEntries(), ec.fEventCutsPro->GetNbinsX()); + } + delete oa; + + // *) Okay, set the title: + ec.fEventCutsPro->GetYaxis()->SetTitle(yAxisTitle.Data()); + } // if(!tc.fUseSetBinLabel) + + ec.fEventCutsList->Add(ec.fEventCutsPro); + + // b) Book event cut counter maps: + for (int rs = 0; rs < 2; rs++) // reco/sim + { + // If I am analyzing only reconstructed data, do not book maps for simulated, and vice versa. + if ((tc.fProcess[eGenericRec] && rs == eSim) || (tc.fProcess[eGenericSim] && rs == eRec)) { + continue; + } + ec.fEventCutCounterMap[rs] = new TExMap(); + ec.fEventCutCounterMapInverse[rs] = new TExMap(); + } + + // c) Book event cut counter histograms: + // ... + for (int rs = 0; rs < 2; rs++) // reco/sim + { + + if (Skip(rs)) { + continue; + } + + for (int cc = 0; cc < eCutCounter_N; cc++) // cut counter + { + + if ((!ec.fUseEventCutCounterAbsolute && cc == eAbsolute) || (!ec.fUseEventCutCounterSequential && cc == eSequential)) { + continue; + } + + ec.fEventCutCounterHist[rs][cc] = new TH1F(TString::Format("fEventCutCounterHist[%s][%s]", gc.srs[rs].Data(), gc.scc[cc].Data()), TString::Format("%s, %s, event cut counter (%s)", "__RUN_NUMBER__", gc.srsLong[rs].Data(), gc.sccLong[cc].Data()), eEventCuts_N, 0.5, static_cast(eEventCuts_N) + 0.5); // I cast in double the last argument, because that's what this particular TH1I constructor expects. And yes, +0.5, because eEventCuts kicks off from 0 + ec.fEventCutCounterHist[rs][cc]->SetStats(false); + ec.fEventCutCounterHist[rs][cc]->SetLineColor(eColor); + ec.fEventCutCounterHist[rs][cc]->SetFillColor(eFillColor); + ec.fEventCutCounterHist[rs][cc]->GetXaxis()->SetLabelSize(0.025); + + // Remark: Bin labels are set later in a dry call to EventCuts, to accomodate sequential event cut counting + ec.fEventCutsList->Add(ec.fEventCutCounterHist[rs][cc]); + + } // for (int cc = 0; cc < eCutCounter_N; cc++) // enum eCutCounter + + } // for (int rs = 0; rs < 2; rs++) // reco/sim + + // d) Book the formulas for all event cuts defined via mathematical expressions: + + // **) eRefMultVsNContrUp: + if (ec.fUseEventCuts[eRefMultVsNContrUp]) { + if (tc.fUseFormula) { + ec.fEventCutsFormulas[eRefMultVsNContrUp_Formula] = new TFormula("RefMultVsNContrUp_Formula", ec.fsEventCuts[eRefMultVsNContrUp].Data()); + + LOGF(info, "\033[1;33m%s at line %d: !!!! WARNING !!!! There is a large memory blow-up when using TFormula() !!!! WARNING !!!! \033[0m", __FUNCTION__, __LINE__); + + // As a quick insanity check, try immediately to evaluate something from this formula: + if (std::isnan(ec.fEventCutsFormulas[eRefMultVsNContrUp_Formula]->Eval(1.44))) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + } else { + // This is a workaround to evaluate upper boundary of HMO cut, until large-memory consumption with TFormula is resolved. + + // Algorithm: 1. ec.fsEventCuts[eRefMultVsNContrUp].Data() is linear expression in the mandatory format "p0 + p1*x". + // 2. Then I extract p0 and p1, and store them in float fdEventCutsFormulas[eEventCutsFormulas_N][2] = {{0.}} + // 3. Those values are then used in temporary function float RefMultVsNContr(const float &refMult, ...) + + this->GetP0P1(ec.fsEventCuts[eRefMultVsNContrUp].ReplaceAll(" ", ""), eRefMultVsNContrUp_Formula); + + } // else + + } // if (ec.fUseEventCuts[eRefMultVsNContrUp]) + + // **) eRefMultVsNContrLow: + if (ec.fUseEventCuts[eRefMultVsNContrLow]) { + if (tc.fUseFormula) { + ec.fEventCutsFormulas[eRefMultVsNContrLow_Formula] = new TFormula("RefMultVsNContrLow_Formula", ec.fsEventCuts[eRefMultVsNContrLow].Data()); + + LOGF(info, "\033[1;33m%s at line %d: !!!! WARNING !!!! There is a large memory blow-up when using TFormula() !!!! WARNING !!!! \033[0m", __FUNCTION__, __LINE__); + + // As a quick insanity check, try immediately to evaluate something from this formula: + if (std::isnan(ec.fEventCutsFormulas[eRefMultVsNContrLow_Formula]->Eval(1.44))) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + } else { + // This is a workaround to evaluate upper boundary of HMO cut, until large-memory consumption with TFormula is resolved. + + // Algorithm: See above for eRefMultVsNContrUp + this->GetP0P1(ec.fsEventCuts[eRefMultVsNContrLow].ReplaceAll(" ", ""), eRefMultVsNContrLow_Formula); + } + + } // if (ec.fUseEventCuts[eRefMultVsNContrLow]) + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // void bookEventCutsHistograms() + + //============================================================ + + void GetP0P1(const char* formula, eEventCutsFormulas whichCutFormula) + { + // This is a sort of temporary parser, which extracts from linear expression p0 + p1*x coefficients p0 and p1, and stores them into float fdEventCutsFormulas[eEventCutsFormulas_N][2] = {{0.}} + // Remark #0: I need all this gym until large memory consumption with TFormula is resolved; + // Remark #1: Remove all blanks in 'formula' before calling this function; + // Remark #2: If I need to go beyond p1, use recursion instead. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + TString signP0 = ""; + TString signP1 = ""; + TString P0 = ""; + TString P1 = ""; + + // P0 signature parser: + int offset = 0; + if (TString(formula[0]).EqualTo("-")) { + signP0 = "-"; + offset = 1; + } + + // P0 parser + P1 signature parser: + int c1 = 0; + for (int c = 0 + offset; c < static_cast(strlen(formula)); c++) { + if (!(TString(formula[c]).EqualTo("-") || TString(formula[c]).EqualTo("+") || TString(formula[c]).EqualTo("*"))) { + P0 += formula[c]; + continue; + } else { + signP1 = formula[c]; + c1 = c; + break; + } + } + // P1 parser: + for (int c = c1 + 1; c < static_cast(strlen(formula)); c++) { + if (TString(formula[c]).EqualTo("-") || TString(formula[c]).EqualTo("+") || TString(formula[c]).EqualTo("*")) { + break; + } + P1 += formula[c]; + } + + // Okay, finally merge signature and value, cast into floats and store: + signP0 += P0; + ec.fdEventCutsFormulas[whichCutFormula][0] = signP0.Atof(); + + signP1 += P1; + ec.fdEventCutsFormulas[whichCutFormula][1] = signP1.Atof(); + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // void GetP0P1(const char *formula, eEventCutsFormulas whichCutFormula) + + //============================================================ + + float RefMultVsNContr(const float& refMult, eEventCutsFormulas whichCutFormula) + { + // Temporary workaround for p0 + p1 * x formula until large memory consumption with TFormula is resolved. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // Evaluate p0 + p1 * x: + return ec.fdEventCutsFormulas[whichCutFormula][0] + (ec.fdEventCutsFormulas[whichCutFormula][1]) * refMult; + + } // float RefMultVsNContr(const float &refMult, eEventCutsFormulas whichCutFormula) + + //============================================================ + + void bookParticleHistograms() + { + // Book all particle histograms. + + // a) Book the profile holding flags; + // b) Book specific particle histograms 1D; + // c) Book specific particle histograms 2D; + // d) Default binning for particle sparse histograms (yes, here, see comments below); + // e) Book specific particle sparse histograms (n-dimensions). + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // a) Book the profile holding flags: + ph.fParticleHistogramsPro = new TProfile( + "fParticleHistogramsPro", "flags for particle histograms", 1, 0., 1.); + ph.fParticleHistogramsPro->SetStats(false); + ph.fParticleHistogramsPro->SetLineColor(eColor); + ph.fParticleHistogramsPro->SetFillColor(eFillColor); + ph.fParticleHistogramsPro->GetXaxis()->SetLabelSize(0.025); + + if (tc.fUseSetBinLabel) { + ph.fParticleHistogramsPro->GetXaxis()->SetBinLabel(1, "fFillParticleHistograms"); + ph.fParticleHistogramsPro->Fill(0.5, static_cast(ph.fFillParticleHistograms)); + + // ... + + } else { + // Workaround for SetBinLabel() large memory consumption: + TString yAxisTitle = ""; + + yAxisTitle += TString::Format("%d:fFillParticleHistograms; ", 1); // TBI 20250411 hardwired 1 + ph.fParticleHistogramsPro->Fill(0.5, static_cast(ph.fFillParticleHistograms)); // TBI 20250411 hardwired 0.5 + + // ... + + // *) Insanity check on the number of fields in this specially crafted y-axis title: + TObjArray* oa = yAxisTitle.Tokenize(";"); + if (!oa) { + LOGF(fatal, "\033[1;31m%s at line %d : oa is NULL\033[0m", __FUNCTION__, __LINE__); + } + if (oa->GetEntries() - 1 != ph.fParticleHistogramsPro->GetNbinsX()) { + LOGF(fatal, "\033[1;31m%s at line %d : oa->GetEntries() - 1 = %d != ph.fParticleHistogramsPro->GetNbinsX() = %d\033[0m", __FUNCTION__, __LINE__, oa->GetEntries(), ph.fParticleHistogramsPro->GetNbinsX()); + } + + // *) Okay, set the title: + ph.fParticleHistogramsPro->GetYaxis()->SetTitle(yAxisTitle.Data()); + + } // else + + ph.fParticleHistogramsList->Add(ph.fParticleHistogramsPro); + + // b) Book specific particle histograms 1D: + // ... + for (int t = 0; t < eParticleHistograms_N; t++) // type, see enum eParticleHistograms + { + if (!ph.fBookParticleHistograms[t]) { + continue; + } + for (int rs = 0; rs < 2; rs++) // reco/sim + { + + if (Skip(rs)) { + continue; + } + + // **) PDG makes sense only for Sim: + if ((tc.fProcess[eGenericRec] || tc.fProcess[eGenericRecSim]) && rs == eRec) { + if (t == ePDG) { + continue; + } + } + + for (int ba = 0; ba < 2; ba++) // before/after cuts + { + ph.fParticleHistograms[t][rs][ba] = new TH1F(TString::Format("fParticleHistograms[%s][%s][%s]", ph.fParticleHistogramsName[t].Data(), gc.srs[rs].Data(), gc.sba[ba].Data()), + TString::Format("%s, %s, %s", "__RUN_NUMBER__", gc.srsLong[rs].Data(), gc.sbaLong[ba].Data()), + static_cast(ph.fParticleHistogramsBins[t][0]), ph.fParticleHistogramsBins[t][1], ph.fParticleHistogramsBins[t][2]); + ph.fParticleHistograms[t][rs][ba]->SetLineColor(ec.fBeforeAfterColor[ba]); + ph.fParticleHistograms[t][rs][ba]->SetFillColor(ec.fBeforeAfterColor[ba] - 10); + ph.fParticleHistograms[t][rs][ba]->GetXaxis()->SetTitle(FancyFormatting(ph.fParticleHistogramsName[t].Data())); + ph.fParticleHistograms[t][rs][ba]->SetMinimum(1.e-4); // so that I can switch to log scale, even if some bins are empty + // Remark: For empty histograms, when plotting interactively, because of this line, I will get + // E-TCanvas::Range: illegal world coordinates range .... + // But it's harmless, because in any case I do not care about the content of empty histogram... + ph.fParticleHistograms[t][rs][ba]->SetOption("hist"); // do not plot marker and error (see BanishmentLoopOverParticles why errors are not reliable) for each bin, only content + filled area. + ph.fParticleHistogramsList->Add(ph.fParticleHistograms[t][rs][ba]); + } // for(int ba=0;ba<2;ba++) + } // for(int rs=0;rs<2;rs++) // reco/sim + } // for(int t=0;t(eParticleHistograms2D_N)); + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + if (sizeof(stitleY2D) / sizeof(stitleY2D[0]) != eParticleHistograms2D_N) { + LOGF(info, "\033[1;31m mismatch - add same number of names for 2D particle histograms as you have data members \033[0m"); + LOGF(info, "\033[1;31m sizeof(stitleY2D)/sizeof(stitleY2D[0]) = %d \033[0m", sizeof(stitleY2D) / sizeof(stitleY2D[0])); + LOGF(info, "\033[1;31m eParticleHistograms2D_N = %d \033[0m", static_cast(eParticleHistograms2D_N)); + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + + for (int t = 0; t < eParticleHistograms2D_N; t++) // type, see enum eParticleHistograms2D + { + if (!ph.fBookParticleHistograms2D[t]) { + continue; + } + for (int rs = 0; rs < 2; rs++) // reco/sim + { + + if (Skip(rs)) { + continue; + } + + for (int ba = 0; ba < 2; ba++) // before/after cuts + { + + // optional variable-length binning for y-axis (for supported observables): + if (ph.fParticleHistogramsName2D[t].EqualTo("Phi_vs_Pt") && res.fUseResultsProVariableLengthBins[AFO_PT]) { + + // Remark: placeholder __RUN_NUMBER__ is handled in PropagateRunNumber(...) + + // *) variable-length binning for phi vs pt, but only in pt axis: + ph.fParticleHistograms2D[t][rs][ba] = new TH2D(TString::Format("fParticleHistograms2D[%s][%s][%s]", ph.fParticleHistogramsName2D[t].Data(), gc.srs[rs].Data(), gc.sba[ba].Data()), + TString::Format("%s, %s, %s", "__RUN_NUMBER__", gc.srsLong[rs].Data(), gc.sbaLong[ba].Data()), + static_cast(ph.fParticleHistogramsBins2D[t][eX][0]), ph.fParticleHistogramsBins2D[t][eX][1], ph.fParticleHistogramsBins2D[t][eX][2], + res.fResultsPro[AFO_PT]->GetXaxis()->GetXbins()->GetSize() - 1, res.fResultsPro[AFO_PT]->GetXaxis()->GetXbins()->GetArray()); // yes, x-axis of "results vs pt" hist is y-axis here for 2D. + } else if (ph.fParticleHistogramsName2D[t].EqualTo("Phi_vs_Eta") && res.fUseResultsProVariableLengthBins[AFO_ETA]) { + + // *) variable-length binning for phi vs eta, but only in eta axis: + ph.fParticleHistograms2D[t][rs][ba] = new TH2D(TString::Format("fParticleHistograms2D[%s][%s][%s]", ph.fParticleHistogramsName2D[t].Data(), gc.srs[rs].Data(), gc.sba[ba].Data()), + TString::Format("%s, %s, %s", "__RUN_NUMBER__", gc.srsLong[rs].Data(), gc.sbaLong[ba].Data()), + static_cast(ph.fParticleHistogramsBins2D[t][eX][0]), ph.fParticleHistogramsBins2D[t][eX][1], ph.fParticleHistogramsBins2D[t][eX][2], + res.fResultsPro[AFO_ETA]->GetXaxis()->GetXbins()->GetSize() - 1, res.fResultsPro[AFO_ETA]->GetXaxis()->GetXbins()->GetArray()); // yes, x-axis of "results vs pt" hist is y-axis here for 2D + } else { + // default fixed-length binning: + // Remark: Remember that I cannot use here GetXaxis()->GetXbins()->GetArray() as for variable-width case, because for fixed-width case, this is always 0 + // See https://root-forum.cern.ch/t/get-bin-array/7276/9 + ph.fParticleHistograms2D[t][rs][ba] = new TH2D(TString::Format("fParticleHistograms2D[%s][%s][%s]", ph.fParticleHistogramsName2D[t].Data(), gc.srs[rs].Data(), gc.sba[ba].Data()), + TString::Format("%s, %s, %s", "__RUN_NUMBER__", gc.srsLong[rs].Data(), gc.sbaLong[ba].Data()), + static_cast(ph.fParticleHistogramsBins2D[t][eX][0]), ph.fParticleHistogramsBins2D[t][eX][1], ph.fParticleHistogramsBins2D[t][eX][2], + static_cast(ph.fParticleHistogramsBins2D[t][eY][0]), ph.fParticleHistogramsBins2D[t][eY][1], ph.fParticleHistogramsBins2D[t][eY][2]); + } + ph.fParticleHistograms2D[t][rs][ba]->SetLineColor(ec.fBeforeAfterColor[ba]); + ph.fParticleHistograms2D[t][rs][ba]->SetFillColor(ec.fBeforeAfterColor[ba] - 10); + ph.fParticleHistograms2D[t][rs][ba]->GetXaxis()->SetTitle(stitleX2D[t].Data()); + ph.fParticleHistograms2D[t][rs][ba]->GetYaxis()->SetTitle(stitleY2D[t].Data()); + ph.fParticleHistogramsList->Add(ph.fParticleHistograms2D[t][rs][ba]); + } // for(int ba=0;ba<2;ba++) + } // for(int rs=0;rs<2;rs++) // reco/sim + } // for(int t=0;t(ph.fParticleHistogramsBins[ePhi][0] / ph.fRebinSparse[eDWPhi][wPhiPhiAxis]); + lAxis = new TAxis(ph.fParticleSparseHistogramsNBins[eDWPhi][wPhiPhiAxis], ph.fParticleHistogramsBins[ePhi][1], ph.fParticleHistogramsBins[ePhi][2]); + ph.fParticleSparseHistogramsBinEdges[eDWPhi][wPhiPhiAxis] = new TArrayD(1 + ph.fParticleSparseHistogramsNBins[eDWPhi][wPhiPhiAxis]); + for (int bin = 1; bin <= lAxis->GetNbins(); bin++) { + ph.fParticleSparseHistogramsBinEdges[eDWPhi][wPhiPhiAxis]->AddAt(lAxis->GetBinLowEdge(bin), bin - 1); + } + ph.fParticleSparseHistogramsBinEdges[eDWPhi][wPhiPhiAxis]->AddAt(lAxis->GetBinLowEdge(1 + lAxis->GetNbins()), lAxis->GetNbins()); // special treatment for last bin + delete lAxis; + ph.fParticleSparseHistogramsAxisTitle[eDWPhi][wPhiPhiAxis] = FancyFormatting("Phi"); + + // ***) pt-axis for diff phi weights - at the moment I support only fixed-length binning from control histograms, which optionally can be made finer or coarser with cfRebinSparse configurable: + ph.fParticleSparseHistogramsNBins[eDWPhi][wPhiPtAxis] = static_cast(ph.fParticleHistogramsBins[ePt][0] / ph.fRebinSparse[eDWPhi][wPhiPtAxis]); + lAxis = new TAxis(ph.fParticleSparseHistogramsNBins[eDWPhi][wPhiPtAxis], ph.fParticleHistogramsBins[ePt][1], ph.fParticleHistogramsBins[ePt][2]); + ph.fParticleSparseHistogramsBinEdges[eDWPhi][wPhiPtAxis] = new TArrayD(1 + ph.fParticleSparseHistogramsNBins[eDWPhi][wPhiPtAxis]); + for (int bin = 1; bin <= lAxis->GetNbins(); bin++) { + ph.fParticleSparseHistogramsBinEdges[eDWPhi][wPhiPtAxis]->AddAt(lAxis->GetBinLowEdge(bin), bin - 1); + } + ph.fParticleSparseHistogramsBinEdges[eDWPhi][wPhiPtAxis]->AddAt(lAxis->GetBinLowEdge(1 + lAxis->GetNbins()), lAxis->GetNbins()); // special treatment for last bin + delete lAxis; + ph.fParticleSparseHistogramsAxisTitle[eDWPhi][wPhiPtAxis] = FancyFormatting("Pt"); + + // ***) eta-axis for diff phi weights - at the moment I support only fixed-length binning from control histograms, which optionally can be made finer or coarser with cfRebinSparse configurable: + ph.fParticleSparseHistogramsNBins[eDWPhi][wPhiEtaAxis] = static_cast(ph.fParticleHistogramsBins[eEta][0] / ph.fRebinSparse[eDWPhi][wPhiEtaAxis]); + lAxis = new TAxis(ph.fParticleSparseHistogramsNBins[eDWPhi][wPhiEtaAxis], ph.fParticleHistogramsBins[eEta][1], ph.fParticleHistogramsBins[eEta][2]); + ph.fParticleSparseHistogramsBinEdges[eDWPhi][wPhiEtaAxis] = new TArrayD(1 + ph.fParticleSparseHistogramsNBins[eDWPhi][wPhiEtaAxis]); + for (int bin = 1; bin <= lAxis->GetNbins(); bin++) { + ph.fParticleSparseHistogramsBinEdges[eDWPhi][wPhiEtaAxis]->AddAt(lAxis->GetBinLowEdge(bin), bin - 1); + } + ph.fParticleSparseHistogramsBinEdges[eDWPhi][wPhiEtaAxis]->AddAt(lAxis->GetBinLowEdge(1 + lAxis->GetNbins()), lAxis->GetNbins()); // special treatment for last bin + delete lAxis; + ph.fParticleSparseHistogramsAxisTitle[eDWPhi][wPhiEtaAxis] = FancyFormatting("Eta"); + + // ***) charge-axis for diff phi weights - at the moment I support only fixed-length binning from control histograms, which optionally can be made finer or coarser with cfRebinSparse configurable: + ph.fParticleSparseHistogramsNBins[eDWPhi][wPhiChargeAxis] = static_cast(ph.fParticleHistogramsBins[eCharge][0] / ph.fRebinSparse[eDWPhi][wPhiChargeAxis]); + lAxis = new TAxis(ph.fParticleSparseHistogramsNBins[eDWPhi][wPhiChargeAxis], ph.fParticleHistogramsBins[eCharge][1], ph.fParticleHistogramsBins[eCharge][2]); + ph.fParticleSparseHistogramsBinEdges[eDWPhi][wPhiChargeAxis] = new TArrayD(1 + ph.fParticleSparseHistogramsNBins[eDWPhi][wPhiChargeAxis]); + for (int bin = 1; bin <= lAxis->GetNbins(); bin++) { + ph.fParticleSparseHistogramsBinEdges[eDWPhi][wPhiChargeAxis]->AddAt(lAxis->GetBinLowEdge(bin), bin - 1); + } + ph.fParticleSparseHistogramsBinEdges[eDWPhi][wPhiChargeAxis]->AddAt(lAxis->GetBinLowEdge(1 + lAxis->GetNbins()), lAxis->GetNbins()); // special treatment for last bin + delete lAxis; + ph.fParticleSparseHistogramsAxisTitle[eDWPhi][wPhiChargeAxis] = FancyFormatting("Charge"); + + // ***) centrality-axis for diff phi weights - at the moment I support only fixed-length binning from control histograms, which optionally can be made finer or coarser with cfRebinSparse configurable: + ph.fParticleSparseHistogramsNBins[eDWPhi][wPhiCentralityAxis] = static_cast(eh.fEventHistogramsBins[eCentrality][0] / ph.fRebinSparse[eDWPhi][wPhiCentralityAxis]); + lAxis = new TAxis(ph.fParticleSparseHistogramsNBins[eDWPhi][wPhiCentralityAxis], eh.fEventHistogramsBins[eCentrality][1], eh.fEventHistogramsBins[eCentrality][2]); + ph.fParticleSparseHistogramsBinEdges[eDWPhi][wPhiCentralityAxis] = new TArrayD(1 + ph.fParticleSparseHistogramsNBins[eDWPhi][wPhiCentralityAxis]); + for (int bin = 1; bin <= lAxis->GetNbins(); bin++) { + ph.fParticleSparseHistogramsBinEdges[eDWPhi][wPhiCentralityAxis]->AddAt(lAxis->GetBinLowEdge(bin), bin - 1); + } + ph.fParticleSparseHistogramsBinEdges[eDWPhi][wPhiCentralityAxis]->AddAt(lAxis->GetBinLowEdge(1 + lAxis->GetNbins()), lAxis->GetNbins()); // special treatment for last bin + delete lAxis; + ph.fParticleSparseHistogramsAxisTitle[eDWPhi][wPhiCentralityAxis] = "Centrality"; // TBI 20250222 I cannot call here FancyFormatting for "Centrality", because ec.fsEventCuts[eCentralityEstimator] is still not fetched and set from configurable. Re-think how to proceed for this specific case. + + // ***) VertexZ-axis for diff phi weights - at the moment I support only fixed-length binning from control histograms, which optionally can be made finer or coarser with cfRebinSparse configurable: + ph.fParticleSparseHistogramsNBins[eDWPhi][wPhiVertexZAxis] = static_cast(eh.fEventHistogramsBins[eVertexZ][0] / ph.fRebinSparse[eDWPhi][wPhiVertexZAxis]); + lAxis = new TAxis(ph.fParticleSparseHistogramsNBins[eDWPhi][wPhiVertexZAxis], eh.fEventHistogramsBins[eVertexZ][1], eh.fEventHistogramsBins[eVertexZ][2]); + ph.fParticleSparseHistogramsBinEdges[eDWPhi][wPhiVertexZAxis] = new TArrayD(1 + ph.fParticleSparseHistogramsNBins[eDWPhi][wPhiVertexZAxis]); + for (int bin = 1; bin <= lAxis->GetNbins(); bin++) { + ph.fParticleSparseHistogramsBinEdges[eDWPhi][wPhiVertexZAxis]->AddAt(lAxis->GetBinLowEdge(bin), bin - 1); + } + ph.fParticleSparseHistogramsBinEdges[eDWPhi][wPhiVertexZAxis]->AddAt(lAxis->GetBinLowEdge(1 + lAxis->GetNbins()), lAxis->GetNbins()); // special treatment for last bin + delete lAxis; + ph.fParticleSparseHistogramsAxisTitle[eDWPhi][wPhiVertexZAxis] = "VertexZ"; + + // ... + + // **) eDiffWeightCategory = eDWPt: + + // ***) pt-axis for diff pt weights - at the moment I support only fixed-length binning from control histograms, which optionally can be made finer or coarser with cfRebinSparse configurable: + ph.fParticleSparseHistogramsNBins[eDWPt][wPtPtAxis] = static_cast(ph.fParticleHistogramsBins[ePt][0] / ph.fRebinSparse[eDWPt][wPtPtAxis]); + lAxis = new TAxis(ph.fParticleSparseHistogramsNBins[eDWPt][wPtPtAxis], ph.fParticleHistogramsBins[ePt][1], ph.fParticleHistogramsBins[ePt][2]); + ph.fParticleSparseHistogramsBinEdges[eDWPt][wPtPtAxis] = new TArrayD(1 + ph.fParticleSparseHistogramsNBins[eDWPt][wPtPtAxis]); + for (int bin = 1; bin <= lAxis->GetNbins(); bin++) { + ph.fParticleSparseHistogramsBinEdges[eDWPt][wPtPtAxis]->AddAt(lAxis->GetBinLowEdge(bin), bin - 1); + } + ph.fParticleSparseHistogramsBinEdges[eDWPt][wPtPtAxis]->AddAt(lAxis->GetBinLowEdge(1 + lAxis->GetNbins()), lAxis->GetNbins()); // special treatment for last bin + delete lAxis; + ph.fParticleSparseHistogramsAxisTitle[eDWPt][wPtPtAxis] = FancyFormatting("Pt"); + + // ***) eta-axis for diff pt weights - at the moment I support only fixed-length binning from control histograms, which optionally can be made finer or coarser with cfRebinSparse configurable: + ph.fParticleSparseHistogramsNBins[eDWPt][wPtEtaAxis] = static_cast(ph.fParticleHistogramsBins[eEta][0] / ph.fRebinSparse[eDWPt][wPtEtaAxis]); + lAxis = new TAxis(ph.fParticleSparseHistogramsNBins[eDWPt][wPtEtaAxis], ph.fParticleHistogramsBins[eEta][1], ph.fParticleHistogramsBins[eEta][2]); + ph.fParticleSparseHistogramsBinEdges[eDWPt][wPtEtaAxis] = new TArrayD(1 + ph.fParticleSparseHistogramsNBins[eDWPt][wPtEtaAxis]); + for (int bin = 1; bin <= lAxis->GetNbins(); bin++) { + ph.fParticleSparseHistogramsBinEdges[eDWPt][wPtEtaAxis]->AddAt(lAxis->GetBinLowEdge(bin), bin - 1); + } + ph.fParticleSparseHistogramsBinEdges[eDWPt][wPtEtaAxis]->AddAt(lAxis->GetBinLowEdge(1 + lAxis->GetNbins()), lAxis->GetNbins()); // special treatment for last bin + delete lAxis; + ph.fParticleSparseHistogramsAxisTitle[eDWPt][wPtEtaAxis] = FancyFormatting("Eta"); + + // ***) charge-axis for diff pt weights - at the moment I support only fixed-length binning from control histograms, which optionally can be made finer or coarser with cfRebinSparse configurable: + ph.fParticleSparseHistogramsNBins[eDWPt][wPtChargeAxis] = static_cast(ph.fParticleHistogramsBins[eCharge][0] / ph.fRebinSparse[eDWPt][wPtChargeAxis]); + lAxis = new TAxis(ph.fParticleSparseHistogramsNBins[eDWPt][wPtChargeAxis], ph.fParticleHistogramsBins[eCharge][1], ph.fParticleHistogramsBins[eCharge][2]); + ph.fParticleSparseHistogramsBinEdges[eDWPt][wPtChargeAxis] = new TArrayD(1 + ph.fParticleSparseHistogramsNBins[eDWPt][wPtChargeAxis]); + for (int bin = 1; bin <= lAxis->GetNbins(); bin++) { + ph.fParticleSparseHistogramsBinEdges[eDWPt][wPtChargeAxis]->AddAt(lAxis->GetBinLowEdge(bin), bin - 1); + } + ph.fParticleSparseHistogramsBinEdges[eDWPt][wPtChargeAxis]->AddAt(lAxis->GetBinLowEdge(1 + lAxis->GetNbins()), lAxis->GetNbins()); // special treatment for last bin + delete lAxis; + ph.fParticleSparseHistogramsAxisTitle[eDWPt][wPtChargeAxis] = FancyFormatting("Charge"); + + // ***) centrality-axis for diff pt weights - at the moment I support only fixed-length binning from control histograms, which optionally can be made finer or coarser with cfRebinSparse configurable: + ph.fParticleSparseHistogramsNBins[eDWPt][wPtCentralityAxis] = static_cast(eh.fEventHistogramsBins[eCentrality][0] / ph.fRebinSparse[eDWPt][wPtCentralityAxis]); + lAxis = new TAxis(ph.fParticleSparseHistogramsNBins[eDWPt][wPtCentralityAxis], eh.fEventHistogramsBins[eCentrality][1], eh.fEventHistogramsBins[eCentrality][2]); + ph.fParticleSparseHistogramsBinEdges[eDWPt][wPtCentralityAxis] = new TArrayD(1 + ph.fParticleSparseHistogramsNBins[eDWPt][wPtCentralityAxis]); + for (int bin = 1; bin <= lAxis->GetNbins(); bin++) { + ph.fParticleSparseHistogramsBinEdges[eDWPt][wPtCentralityAxis]->AddAt(lAxis->GetBinLowEdge(bin), bin - 1); + } + ph.fParticleSparseHistogramsBinEdges[eDWPt][wPtCentralityAxis]->AddAt(lAxis->GetBinLowEdge(1 + lAxis->GetNbins()), lAxis->GetNbins()); // special treatment for last bin + delete lAxis; + ph.fParticleSparseHistogramsAxisTitle[eDWPt][wPtCentralityAxis] = "Centrality"; // TBI 20250222 I cannot call here FancyFormatting for "Centrality", because ec.fsEventCuts[eCentralityEstimator] is still not fetched and set from configurable. Re-think how to proceed for this specific case. + + // ... + + // **) eDiffWeightCategory = eDWEta: + + // ***) eta-axis for diff eta weights - at the moment I support only fixed-length binning from control histograms, which optionally can be made finer or coarser with cfRebinSparse configurable: + ph.fParticleSparseHistogramsNBins[eDWEta][wEtaEtaAxis] = static_cast(ph.fParticleHistogramsBins[eEta][0] / ph.fRebinSparse[eDWEta][wEtaEtaAxis]); + lAxis = new TAxis(ph.fParticleSparseHistogramsNBins[eDWEta][wEtaEtaAxis], ph.fParticleHistogramsBins[eEta][1], ph.fParticleHistogramsBins[eEta][2]); + ph.fParticleSparseHistogramsBinEdges[eDWEta][wEtaEtaAxis] = new TArrayD(1 + ph.fParticleSparseHistogramsNBins[eDWEta][wEtaEtaAxis]); + for (int bin = 1; bin <= lAxis->GetNbins(); bin++) { + ph.fParticleSparseHistogramsBinEdges[eDWEta][wEtaEtaAxis]->AddAt(lAxis->GetBinLowEdge(bin), bin - 1); + } + ph.fParticleSparseHistogramsBinEdges[eDWEta][wEtaEtaAxis]->AddAt(lAxis->GetBinLowEdge(1 + lAxis->GetNbins()), lAxis->GetNbins()); // special treatment for last bin + delete lAxis; + ph.fParticleSparseHistogramsAxisTitle[eDWEta][wEtaEtaAxis] = FancyFormatting("Eta"); + + // ***) pt-axis for diff eta weights - at the moment I support only fixed-length binning from control histograms, which optionally can be made finer or coarser with cfRebinSparse configurable: + ph.fParticleSparseHistogramsNBins[eDWEta][wEtaPtAxis] = static_cast(ph.fParticleHistogramsBins[ePt][0] / ph.fRebinSparse[eDWEta][wEtaPtAxis]); + lAxis = new TAxis(ph.fParticleSparseHistogramsNBins[eDWEta][wEtaPtAxis], ph.fParticleHistogramsBins[ePt][1], ph.fParticleHistogramsBins[ePt][2]); + ph.fParticleSparseHistogramsBinEdges[eDWEta][wEtaPtAxis] = new TArrayD(1 + ph.fParticleSparseHistogramsNBins[eDWEta][wEtaPtAxis]); + for (int bin = 1; bin <= lAxis->GetNbins(); bin++) { + ph.fParticleSparseHistogramsBinEdges[eDWEta][wEtaPtAxis]->AddAt(lAxis->GetBinLowEdge(bin), bin - 1); + } + ph.fParticleSparseHistogramsBinEdges[eDWEta][wEtaPtAxis]->AddAt(lAxis->GetBinLowEdge(1 + lAxis->GetNbins()), lAxis->GetNbins()); // special treatment for last bin + delete lAxis; + ph.fParticleSparseHistogramsAxisTitle[eDWEta][wEtaPtAxis] = FancyFormatting("Pt"); + + // ***) charge-axis for diff eta weights - at the moment I support only fixed-length binning from control histograms, which optionally can be made finer or coarser with cfRebinSparse configurable: + ph.fParticleSparseHistogramsNBins[eDWEta][wEtaChargeAxis] = static_cast(ph.fParticleHistogramsBins[eCharge][0] / ph.fRebinSparse[eDWEta][wEtaChargeAxis]); + lAxis = new TAxis(ph.fParticleSparseHistogramsNBins[eDWEta][wEtaChargeAxis], ph.fParticleHistogramsBins[eCharge][1], ph.fParticleHistogramsBins[eCharge][2]); + ph.fParticleSparseHistogramsBinEdges[eDWEta][wEtaChargeAxis] = new TArrayD(1 + ph.fParticleSparseHistogramsNBins[eDWEta][wEtaChargeAxis]); + for (int bin = 1; bin <= lAxis->GetNbins(); bin++) { + ph.fParticleSparseHistogramsBinEdges[eDWEta][wEtaChargeAxis]->AddAt(lAxis->GetBinLowEdge(bin), bin - 1); + } + ph.fParticleSparseHistogramsBinEdges[eDWEta][wEtaChargeAxis]->AddAt(lAxis->GetBinLowEdge(1 + lAxis->GetNbins()), lAxis->GetNbins()); // special treatment for last bin + delete lAxis; + ph.fParticleSparseHistogramsAxisTitle[eDWEta][wEtaChargeAxis] = FancyFormatting("Charge"); + + // ***) centrality-axis for diff eta weights - at the moment I support only fixed-length binning from control histograms, which optionally can be made finer or coarser with cfRebinSparse configurable: + ph.fParticleSparseHistogramsNBins[eDWEta][wEtaCentralityAxis] = static_cast(eh.fEventHistogramsBins[eCentrality][0] / ph.fRebinSparse[eDWEta][wEtaCentralityAxis]); + lAxis = new TAxis(ph.fParticleSparseHistogramsNBins[eDWEta][wEtaCentralityAxis], eh.fEventHistogramsBins[eCentrality][1], eh.fEventHistogramsBins[eCentrality][2]); + ph.fParticleSparseHistogramsBinEdges[eDWEta][wEtaCentralityAxis] = new TArrayD(1 + ph.fParticleSparseHistogramsNBins[eDWEta][wEtaCentralityAxis]); + for (int bin = 1; bin <= lAxis->GetNbins(); bin++) { + ph.fParticleSparseHistogramsBinEdges[eDWEta][wEtaCentralityAxis]->AddAt(lAxis->GetBinLowEdge(bin), bin - 1); + } + ph.fParticleSparseHistogramsBinEdges[eDWEta][wEtaCentralityAxis]->AddAt(lAxis->GetBinLowEdge(1 + lAxis->GetNbins()), lAxis->GetNbins()); // special treatment for last bin + delete lAxis; + ph.fParticleSparseHistogramsAxisTitle[eDWEta][wEtaCentralityAxis] = "Centrality"; // TBI 20250222 I cannot call here FancyFormatting for "Centrality", because ec.fsEventCuts[eCentralityEstimator] is still not fetched and set from configurable. Re-think how to proceed for this specific case. + + // ... + + // e) Book specific particle sparse histograms (n-dimensions): + if (ph.fBookParticleSparseHistograms[eDWPhi]) { + BookParticleSparseHistograms(eDWPhi); + } + + if (ph.fBookParticleSparseHistograms[eDWPt]) { + BookParticleSparseHistograms(eDWPt); + } + + if (ph.fBookParticleSparseHistograms[eDWEta]) { + BookParticleSparseHistograms(eDWEta); + } + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // void bookParticleHistograms() + + //============================================================ + + void BookParticleSparseHistograms(eDiffWeightCategory dwc) + { + // This is a helper function for bookParticleHistograms(), merely to reduce code bloat. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // *) Determine number of dimensions for sparse histogram for this differential weight category: + int nDimensions = -1; + switch (dwc) { + case eDWPhi: { + nDimensions = static_cast(eDiffPhiWeights_N); + break; + } + case eDWPt: { + nDimensions = static_cast(eDiffPtWeights_N); + break; + } + case eDWEta: { + nDimensions = static_cast(eDiffEtaWeights_N); + break; + } + default: { + LOGF(fatal, "\033[1;31m%s at line %d : This differential weight category, dwc = %d, is not supported yet. \033[0m", __FUNCTION__, __LINE__, static_cast(dwc)); + break; + } + } // switch(dwc) + + // *) Determine binning for all dimensions: + TArrayI* nBins = new TArrayI(nDimensions); + for (int d = 0; d < nDimensions; d++) { + nBins->AddAt(static_cast(ph.fParticleSparseHistogramsNBins[dwc][d]), d); + } + + // *) Book THnSparse with correct number of bins for each dimension, but void bin edges: + for (int rs = 0; rs < 2; rs++) // reco/sim + { + if (Skip(rs)) { + continue; + } + + for (int ba = 0; ba < 2; ba++) // before/after cuts + { + + if (eBefore == ba && !ph.fFillParticleSparseHistogramsBeforeCuts) { + continue; + } + + // Remark: Here I have a bit unusual convention for the name and title, but okay... + ph.fParticleSparseHistograms[dwc][rs][ba] = new THnSparseF(TString::Format("%s[%s][%s]", ph.fParticleSparseHistogramsName[dwc].Data(), gc.srs[rs].Data(), gc.sba[ba].Data()), TString::Format("__RUN_NUMBER__, %s, %s, %s", gc.srsLong[rs].Data(), gc.sbaLong[ba].Data(), ph.fParticleSparseHistogramsTitle[dwc].Data()), nDimensions, nBins->GetArray(), NULL, NULL); + + // *) For each dimension set bin edges, axis title, etc.: + for (int d = 0; d < nDimensions; d++) { + ph.fParticleSparseHistograms[dwc][rs][ba]->SetBinEdges(d, ph.fParticleSparseHistogramsBinEdges[dwc][d]->GetArray()); + ph.fParticleSparseHistograms[dwc][rs][ba]->GetAxis(d)->SetTitle(ph.fParticleSparseHistogramsAxisTitle[dwc][d].Data()); + } + + // *) Finally, add the fully configured THnSparse to its TList: + ph.fParticleHistogramsList->Add(ph.fParticleSparseHistograms[dwc][rs][ba]); + + } // for (int ba = 0; ba < 2; ba++) // before/after cuts + + } // for (int rs = 0; rs < 2; rs++) // reco/sim + + // *) Clean up: + delete nBins; + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // void BookParticleSparseHistograms() + + //============================================================ + + void bookParticleCutsHistograms() + { + // Book all particle cuts objects. + + // a) Book the profile holding flags; + // b) Book particle cut counter maps; + // c) Book the particle cut counter (absolute); + // d) Book the formula for pt-dependent DCAxy cut. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // a) Book the profile holding flags: + pc.fParticleCutsPro = new TProfile("fParticleCutsPro", "flags for particle cuts", eParticleCuts_N, -0.5, static_cast(eParticleCuts_N) - 0.5); + if (tc.fUseSpecificCuts) { + pc.fParticleCutsPro->SetTitle(TString::Format("%s (hardwired analysis-specific cuts = %s)", pc.fParticleCutsPro->GetTitle(), tc.fWhichSpecificCuts.Data()).Data()); + } else { + pc.fParticleCutsPro->SetTitle(TString::Format("%s (hardwired analysis-specific cuts not used)", pc.fParticleCutsPro->GetTitle()).Data()); + } + pc.fParticleCutsPro->SetStats(false); + pc.fParticleCutsPro->SetLineColor(eColor); + pc.fParticleCutsPro->SetFillColor(eFillColor); + + TString yAxisTitle = ""; // TBI 20250413 when I fall back on using SetBinLabel(...), this variable is declared but will be unused + for (int cut = 0; cut < eParticleCuts_N; cut++) { + if (tc.fUseSetBinLabel) { + pc.fParticleCutsPro->GetXaxis()->SetBinLabel(1 + cut, pc.fParticleCutName[cut].Data()); // Remark: check always if bin labels here correspond to ordering in enum eParticleCuts + } else { + // Workaround for SetBinLabel() large memory consumption: + yAxisTitle += TString::Format("%d:%s; ", 1 + cut, pc.fParticleCutName[cut].Data()); + } + + pc.fParticleCutsPro->Fill(cut, static_cast(pc.fUseParticleCuts[cut])); + + } // for (int cut = 0; cut < eParticleCuts_N; cut++)s + + // *) Insanity check on the number of fields in this specially crafted y-axis title: + if (!tc.fUseSetBinLabel) { + + TObjArray* oa = yAxisTitle.Tokenize(";"); + if (!oa) { + LOGF(fatal, "\033[1;31m%s at line %d : oa is NULL\033[0m", __FUNCTION__, __LINE__); + } + if (oa->GetEntries() - 1 != pc.fParticleCutsPro->GetNbinsX()) { + LOGF(fatal, "\033[1;31m%s at line %d : oa->GetEntries() = %d != pc.fParticleCutsPro->GetNbinsX() = %d\033[0m", __FUNCTION__, __LINE__, oa->GetEntries(), pc.fParticleCutsPro->GetNbinsX()); + } + delete oa; + + // *) Okay, set the title: + pc.fParticleCutsPro->GetYaxis()->SetTitle(yAxisTitle.Data()); + } // if(!tc.fUseSetBinLabel) + + pc.fParticleCutsList->Add(pc.fParticleCutsPro); + + // b) Book particle cut counter maps: + for (int rs = 0; rs < 2; rs++) // reco/sim + { + // If I am analyzing only reconstructed data, do not book maps for simulated, and vice versa. + if ((tc.fProcess[eGenericRec] && rs == eSim) || (tc.fProcess[eGenericSim] && rs == eRec)) { + continue; + } + pc.fParticleCutCounterMap[rs] = new TExMap(); + pc.fParticleCutCounterMapInverse[rs] = new TExMap(); + } + + // c) Book the particle cut counter (absolute): + // ... + for (int rs = 0; rs < 2; rs++) // reco/sim + { + + if (Skip(rs)) { + continue; + } + + for (int cc = 0; cc < eCutCounter_N; cc++) // cut counter + { + + if ((!pc.fUseParticleCutCounterAbsolute && cc == eAbsolute) || (!pc.fUseParticleCutCounterSequential && cc == eSequential)) { + continue; + } + + pc.fParticleCutCounterHist[rs][cc] = new TH1F(TString::Format("fParticleCutCounterHist[%s][%s]", gc.srs[rs].Data(), gc.scc[cc].Data()), TString::Format("%s, %s, particle cut counter (%s)", "__RUN_NUMBER__", gc.srsLong[rs].Data(), gc.sccLong[cc].Data()), eParticleCuts_N, 0.5, static_cast(eParticleCuts_N) + 0.5); + // I cast in double the last argument, because that's what this particular TH1I constructor expects + // Yes, +0.5, because eParticleCuts kicks off from 0 + pc.fParticleCutCounterHist[rs][cc]->SetStats(false); + pc.fParticleCutCounterHist[rs][cc]->SetLineColor(eColor); + pc.fParticleCutCounterHist[rs][cc]->SetFillColor(eFillColor); + pc.fParticleCutCounterHist[rs][cc]->GetXaxis()->SetLabelSize(0.025); + // Remark: Bin labels are set later in a dry call to ParticleCuts, to accomodate sequential particle cut counting + pc.fParticleCutsList->Add(pc.fParticleCutCounterHist[rs][cc]); + + } // for (int cc = 0; cc < eCutCounter_N; cc++) // enum eCutCounter + + } // for (int rs = 0; rs < 2; rs++) // reco/sim + + // d) Book the formula for pt-dependent DCAxy cut: + if (pc.fUseParticleCuts[ePtDependentDCAxyParameterization]) { + pc.fPtDependentDCAxyFormula = new TFormula("fPtDependentDCAxyFormula", pc.fsParticleCuts[ePtDependentDCAxyParameterization].Data()); + + LOGF(info, "\033[1;33m%s at line %d: !!!! WARNING !!!! There is a large memory blow-up when using TFormula() !!!! WARNING !!!! \033[0m", __FUNCTION__, __LINE__); + + // As a quick insanity check, try immediately to evaluate something from this formula: + if (std::isnan(pc.fPtDependentDCAxyFormula->Eval(1.44))) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + } // if(pc.fUseParticleCuts[ePtDependentDCAxyParameterization]) { + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // void bookParticleCutsHistograms() + + //============================================================ + + void bookQvectorHistograms() + { + // Book all Q-vector histograms. + + // a) Book the profile holding flags; + // b) Differential q-vectors booked dynamically: + // c) Book multiplicity distributions in A and B, for each eta separation; + // d) ... + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // a) Book the profile holding flags: + qv.fQvectorFlagsPro = + new TProfile("fQvectorFlagsPro", "flags for Q-vector objects", 3, 0., 3.); + qv.fQvectorFlagsPro->SetStats(false); + qv.fQvectorFlagsPro->SetLineColor(eColor); + qv.fQvectorFlagsPro->SetFillColor(eFillColor); + qv.fQvectorFlagsPro->GetXaxis()->SetLabelSize(0.05); + + if (tc.fUseSetBinLabel) { + + qv.fQvectorFlagsPro->GetXaxis()->SetBinLabel(1, "fCalculateQvectors"); + qv.fQvectorFlagsPro->Fill(0.5, qv.fCalculateQvectors); + qv.fQvectorFlagsPro->GetXaxis()->SetBinLabel(2, "gMaxHarmonic"); + qv.fQvectorFlagsPro->Fill(1.5, gMaxHarmonic); + qv.fQvectorFlagsPro->GetXaxis()->SetBinLabel(3, "gMaxCorrelator"); + qv.fQvectorFlagsPro->Fill(2.5, gMaxCorrelator); + + // ... + + } else { + // Workaround for SetBinLabel() large memory consumption: + TString yAxisTitle = ""; + + yAxisTitle += TString::Format("%d:fCalculateQvectors; ", 1); + qv.fQvectorFlagsPro->Fill(0.5, static_cast(qv.fCalculateQvectors)); + + yAxisTitle += TString::Format("%d:gMaxHarmonic; ", 2); + qv.fQvectorFlagsPro->Fill(1.5, static_cast(gMaxHarmonic)); + + yAxisTitle += TString::Format("%d:gMaxCorrelator; ", 3); + qv.fQvectorFlagsPro->Fill(2.5, static_cast(gMaxCorrelator)); + + // ... + + // *) Insanity check on the number of fields in this specially crafted y-axis title: + TObjArray* oa = yAxisTitle.Tokenize(";"); + if (!oa) { + LOGF(fatal, "\033[1;31m%s at line %d : oa is NULL\033[0m", __FUNCTION__, __LINE__); + } + if (oa->GetEntries() - 1 != qv.fQvectorFlagsPro->GetNbinsX()) { + LOGF(fatal, "\033[1;31m%s at line %d : oa->GetEntries() - 1 = %d != qv.fQvectorFlagsPro->GetNbinsX() = %d\033[0m", __FUNCTION__, __LINE__, oa->GetEntries(), qv.fQvectorFlagsPro->GetNbinsX()); + } + + // *) Okay, set the title: + qv.fQvectorFlagsPro->GetYaxis()->SetTitle(yAxisTitle.Data()); + + } // else + + qv.fQvectorList->Add(qv.fQvectorFlagsPro); + + // b) Differential q-vectors booked dynamically: + // Remark: Here I am slighthly generalizing the great example provided at https://cplusplus.com/forum/articles/7459/ + + // b1) book qv.fqvector and qv.fqvectorEntries : + // dimensions: [eqvectorKine_N][gMaxNoBinsKine][gMaxHarmonic * gMaxCorrelator + 1][gMaxCorrelator + 1] => keep in sync with the documentation in the header + // here I am calculating for each dimensions how many entries I need in a given analysis + if (qv.fCalculateqvectorsKineAny) { + qv.fNumberOfKineBins.resize(eqvectorKine_N); // this is the light object, so I can hardwire here eqvectorKine_N + // then, in NumberOfKineVectors() i will store bins ONLY for qvectorKine which were requested. + // Therefore, final ordering in will correspond to the ordering in enum eqvectorKine ONLY if all kine vectors were requested. + // Otherwise, I fill here bins only for kine vectors which were requested, in consequtive order, starting from 0. + + int dim1 = eqvectorKine_N; + // int dim2 = number of kine bins => I calculate this one dynamically for each qVectorKine, see the loop below + NumberOfKineBins(); // here I calculate and fill qv.fNumberOfKineBins[ ... ] + int dim3 = gMaxHarmonic * gMaxCorrelator + 1; // TBI 20250601 I could dinamically allocate this one as well, but this will trigger another major re-design, and it's not rally a big deal + int dim4 = gMaxCorrelator + 1; // TBI 20250601 I could dinamically allocate this one as well, but this will trigger another major re-design, and it's not really a big deal + + qv.fqvector.resize(dim1); + qv.fqvectorEntries.resize(dim1); + + for (int i = 0; i < dim1; ++i) { // here I am looping over entries in enum eqvectorKine + if (qv.fCalculateqvectorsKine[i]) { + qv.fqvector[i].resize(qv.fNumberOfKineBins[i]); // yes, qv.fNumberOfKineBins[i] => for each qvectorkine I calculate and dynamically allocate only necessary bins + qv.fqvectorEntries[i].resize(qv.fNumberOfKineBins[i]); + } else { + // calculus for this kine variable is not needed, I am ironing out this dimension + qv.fqvector[i].resize(0); + qv.fqvectorEntries[i].resize(0); + } + + for (int j = 0; j < qv.fNumberOfKineBins[i]; ++j) { + if (qv.fCalculateqvectorsKine[i]) { + qv.fqvector[i][j].resize(dim3); + } else { + // calculus for this kine variable is not needed, I am ironing out this dimension + qv.fqvector[i][j].resize(0); + } + + for (int k = 0; k < dim3; ++k) { + if (qv.fCalculateqvectorsKine[i]) { + qv.fqvector[i][j][k].resize(dim4); + } else { + // calculus for this kine variable is not needed, I am ironing out this dimension + qv.fqvector[i][j][k].resize(0); + } + } + } + } // for (int i = 0; i < dim1; ++i) + + // b2) book qv.fqabVector and qv.fmab (differential q-vectors with eta separations): + // dimensions: [-eta or +eta][eqvectorKine_N][global binNo][harmonic][eta separation] => keep in sync with the documentation in the header + // here I am calculating for each dimensions how many entries I need in a given analysis + + if (es.fCalculateEtaSeparations) { + int dim1 = 2; // -eta or eta + int dim2 = eqvectorKine_N; + // int dim3 = number of kine bins => I calculated this one dynamically for each qVectorKine, see the loop below + // NumberOfKineBins(); // here I calculate and fill qv.fNumberOfKineBins[ ... ] => I did it already above for qv.fqvector + int dim4 = gMaxHarmonic; + int dim5 = gMaxNumberEtaSeparations; + qv.fqabVector.resize(dim1); + qv.fmab.resize(dim1); + + for (int i = 0; i < dim1; ++i) { // here I am looping over -eta or eta + qv.fqabVector[i].resize(dim2); + qv.fmab[i].resize(dim2); + + for (int j = 0; j < dim2; ++j) { // here I am looping over entries in enum eqvectorKine + + if (qv.fCalculateqvectorsKineEtaSeparations[j]) { + qv.fqabVector[i][j].resize(qv.fNumberOfKineBins[j]); // yes, qv.fNumberOfKineBins[j] => for each qvectorkine I calculate and dynamically allocate only necessary bins + qv.fmab[i][j].resize(qv.fNumberOfKineBins[j]); + } else { + // calculus for this kine variable is not needed, I am ironing out this dimension + qv.fqabVector[i][j].resize(0); + qv.fmab[i][j].resize(0); + } + + for (int k = 0; k < qv.fNumberOfKineBins[j]; ++k) { + if (qv.fCalculateqvectorsKineEtaSeparations[j]) { + qv.fqabVector[i][j][k].resize(dim4); + qv.fmab[i][j][k].resize(dim5); // yes, directly dim5, because this one doesn't depend on harmonics + } else { + // calculus for this kine variable is not needed, I am ironing out this dimension + // I have already in the previous loop ironed out for qv.fCalculateqvectorsKineEtaSeparations[j] = false, so no need to do it here again + // TBI 20250620 validate what happens here + } + + for (int l = 0; l < dim4; ++l) { // loop over harmonics + if (qv.fCalculateqvectorsKineEtaSeparations[j] && !es.fEtaSeparationsSkipHarmonics[l]) { + qv.fqabVector[i][j][k][l].resize(dim5); + // no need to resize qv.fmab here, because this one doesn't depend on harmonics + } else { + // calculus for this kine variable is not needed, I am ironing out this dimension + // I have already in the previous loop ironed out for qv.fCalculateqvectorsKineEtaSeparations[j] = false, so no need to do it here again + // TBI 20250620 validate what happens here + } + } // for (int l = 0; l < dim4; ++l) + } // for (int k = 0; k < qv.fNumberOfKineBins[j]; ++k) + } // for (int j = 0; j < dim2; ++j) + } // for (int i = 0; i < dim1; ++i) + } // if(es.fCalculateEtaSeparations) + } // if(qv.fCalculateqvectorsKineAny) + + // c) Book multiplicity distributions in A and B, for each eta separation: + if (es.fCalculateEtaSeparations) { + TString sEtaSep[2] = {"A", "B"}; // A <=> -eta , B <=> + eta + TString sEtaSepLong[2] = {TString::Format("%.2f < #eta <", pc.fdParticleCuts[eEta][eMin]), TString::Format("< #eta < %.2f", pc.fdParticleCuts[eEta][eMax])}; + // yes, here I define first the part of intervals as etaCutMin < eta < "subevent boundary", and "subevent" boundary < eta < etaCutMax + // Then below in the loop, I inject for "subevent boundary" the corresponding fEtaSeparationsValues (divided by 2, becaus it's symmetric round 0) + for (int ab = 0; ab < 2; ab++) { // ab = 0 <=> -eta , ab = 1 <=> + eta + for (int rs = 0; rs < 2; rs++) { // reco/sim + if (Skip(rs)) { + continue; + } + for (int ba = 0; ba < 2; ba++) { // before/after cuts + if (eBefore == ba) { + continue; // it make sense to fill these histos only for "eAfter", because Q-vectors are not filled for "eBefore" + } + for (int e = 0; e < gMaxNumberEtaSeparations; e++) { // eta separation + qv.fMabDist[ab][rs][ba][e] = new TH1F(Form("fMabDist[%s][%s][%s][%d]", sEtaSep[ab].Data(), gc.srs[rs].Data(), gc.sba[ba].Data(), e), + Form("%s, %s, %s, %s", "__RUN_NUMBER__", + 0 == ab ? Form("%s -%.2f", sEtaSepLong[ab].Data(), es.fEtaSeparationsValues[e] / 2.) : Form("%.2f %s", es.fEtaSeparationsValues[e] / 2., sEtaSepLong[ab].Data()), gc.srsLong[rs].Data(), gc.sbaLong[ba].Data()), + static_cast(eh.fEventHistogramsBins[eMultiplicity][0]), eh.fEventHistogramsBins[eMultiplicity][1], eh.fEventHistogramsBins[eMultiplicity][2]); // TBI 20241207 I have hardwired in this constructor "0 == ab", this can backfire... + qv.fMabDist[ab][rs][ba][e]->SetLineColor(ec.fBeforeAfterColor[ba]); + qv.fMabDist[ab][rs][ba][e]->SetFillColor(ec.fBeforeAfterColor[ba] - 10); + qv.fMabDist[ab][rs][ba][e]->GetXaxis()->SetTitle("subevent multiplicity (sum of particle weights)"); + qv.fMabDist[ab][rs][ba][e]->SetMinimum(1.e-4); // so that I can switch to log scale, even if some bins are empty + // Remark: For empty histograms, when plotting interactively, because of this line, I will get + // E-TCanvas::Range: illegal world coordinates range .... + // But it's harmless, because in any case I do not care about the content of empty histogram... + qv.fMabDist[ab][rs][ba][e]->SetOption("hist"); // do not plot marker and error (see BanishmentLoopOverParticles why errors are not reliable) for each bin, only content + filled area. + qv.fQvectorList->Add(qv.fMabDist[ab][rs][ba][e]); + } + } + } + } + } // if (es.fCalculateEtaSeparations) { + + // c) ... + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // void bookQvectorHistograms() + + //============================================================ + + void NumberOfKineBins() + { + // Helper function called only in void bookQvectorHistograms(), if kine analysis was requested. + // I calculate for each requested kine vector the number of kine bins => this is stored in dynamically allocated array qv.fNumberOfKineBins. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // 1D kine: + if (qv.fCalculateqvectorsKine[PTq]) { + qv.fNumberOfKineBins[PTq] = res.fResultsPro[AFO_PT]->GetNbinsX() + 2; // + 2 means that I take into account overflow and underflow, then skip it in the loop below + } + if (qv.fCalculateqvectorsKine[ETAq]) { + qv.fNumberOfKineBins[ETAq] = res.fResultsPro[AFO_ETA]->GetNbinsX() + 2; // + 2 means that I take into account overflow and underflow, then skip it in the loop below + } + if (qv.fCalculateqvectorsKine[CHARGEq]) { + qv.fNumberOfKineBins[CHARGEq] = res.fResultsPro[AFO_CHARGE]->GetNbinsX() + 2; // + 2 means that I take into account overflow and underflow, then skip it in the loop below + } + // ... + + // 2D kine: + if (qv.fCalculateqvectorsKine[PT_ETAq]) { + qv.fNumberOfKineBins[PT_ETAq] = (res.fResultsPro2D[AfoKineMap2D(PT_ETAq)]->GetNbinsX() + 2) * (res.fResultsPro2D[AfoKineMap2D(PT_ETAq)]->GetNbinsY() + 2); // + 2 means that I take into account overflow and underflow, then skip it in the loop below + } + if (qv.fCalculateqvectorsKine[PT_CHARGEq]) { + qv.fNumberOfKineBins[PT_CHARGEq] = (res.fResultsPro2D[AfoKineMap2D(PT_CHARGEq)]->GetNbinsX() + 2) * (res.fResultsPro2D[AfoKineMap2D(PT_CHARGEq)]->GetNbinsY() + 2); // + 2 means that I take into account overflow and underflow, then skip it in the loop below + } + if (qv.fCalculateqvectorsKine[ETA_CHARGEq]) { + qv.fNumberOfKineBins[ETA_CHARGEq] = (res.fResultsPro2D[AfoKineMap2D(ETA_CHARGEq)]->GetNbinsX() + 2) * (res.fResultsPro2D[AfoKineMap2D(ETA_CHARGEq)]->GetNbinsY() + 2); // + 2 means that I take into account overflow and underflow, then skip it in the loop below + } + // ... + + // 3D kine: + if (qv.fCalculateqvectorsKine[PT_ETA_CHARGEq]) { + qv.fNumberOfKineBins[PT_ETA_CHARGEq] = (res.fResultsPro3D[AfoKineMap3D(PT_ETA_CHARGEq)]->GetNbinsX() + 2) * (res.fResultsPro3D[AfoKineMap3D(PT_ETA_CHARGEq)]->GetNbinsY() + 2) * (res.fResultsPro3D[AfoKineMap3D(PT_ETA_CHARGEq)]->GetNbinsZ() + 2); // + 2 means that I take into account overflow and underflow, then skip it in the loop below + } + // ... + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // void NumberOfKineBins() + + //============================================================ + + void bookCorrelationsHistograms() + { + // Book all correlations histograms. + + // a) Book the profile holding flags; + // b) Common local labels; + // c) Histograms; + // d) Few quick insanity checks on booking. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // a) Book the profile holding flags: + mupa.fCorrelationsFlagsPro = new TProfile("fCorrelationsFlagsPro", + "flags for correlations", 1, 0., 1.); + mupa.fCorrelationsFlagsPro->SetStats(false); + mupa.fCorrelationsFlagsPro->SetLineColor(eColor); + mupa.fCorrelationsFlagsPro->SetFillColor(eFillColor); + mupa.fCorrelationsFlagsPro->GetXaxis()->SetLabelSize(0.05); + + if (tc.fUseSetBinLabel) { + mupa.fCorrelationsFlagsPro->GetXaxis()->SetBinLabel(1, "fCalculateCorrelations"); + mupa.fCorrelationsFlagsPro->Fill(0.5, mupa.fCalculateCorrelations); + + // ... + + } else { + // Workaround for SetBinLabel() large memory consumption: + TString yAxisTitle = ""; + + yAxisTitle += TString::Format("%d:fCalculateCorrelations; ", 1); + mupa.fCorrelationsFlagsPro->Fill(0.5, static_cast(mupa.fCalculateCorrelations)); + + // ... + + // *) Insanity check on the number of fields in this specially crafted y-axis title: + TObjArray* oa = yAxisTitle.Tokenize(";"); + if (!oa) { + LOGF(fatal, "\033[1;31m%s at line %d : oa is NULL\033[0m", __FUNCTION__, __LINE__); + } + if (oa->GetEntries() - 1 != mupa.fCorrelationsFlagsPro->GetNbinsX()) { + LOGF(fatal, "\033[1;31m%s at line %d : oa->GetEntries() - 1 = %d != mupa.fCorrelationsFlagsPro->GetNbinsX() = %d\033[0m", __FUNCTION__, __LINE__, oa->GetEntries(), mupa.fCorrelationsFlagsPro->GetNbinsX()); + } + + // *) Okay, set the title: + mupa.fCorrelationsFlagsPro->GetYaxis()->SetTitle(yAxisTitle.Data()); + + } // else + + mupa.fCorrelationsList->Add(mupa.fCorrelationsFlagsPro); + + if (!mupa.fCalculateCorrelations) { + return; + } + + // b) Common local labels: + TString oVariable[4] = { + "#varphi_{1}-#varphi_{2}", + "#varphi_{1}+#varphi_{2}-#varphi_{3}-#varphi_{4}", + "#varphi_{1}+#varphi_{2}+#varphi_{3}-#varphi_{4}-#varphi_{5}-#varphi_{6}", + "#varphi_{1}+#varphi_{2}+#varphi_{3}+#varphi_{4}-#varphi_{5}-#varphi_{6}-" + "#varphi_{7}-#varphi_{8}"}; + + // c) Histograms: + for (int k = 0; k < 4; k++) // order [2p=0,4p=1,6p=2,8p=3] + { + for (int n = 0; n < gMaxHarmonic; n++) // harmonic + { + for (int v = 0; v < eAsFunctionOf_N; v++) { + + // decide what is booked, then later valid pointer to fCorrelationsPro[k][n][v] is used as a boolean, in the standard way: + if (!mupa.fCalculateCorrelationsAsFunctionOf[v]) { + continue; + } + + if (!res.fResultsPro[v]) { + LOGF(fatal, "\033[1;31m%s at line %d : fResultsPro[%d] is NULL, this shall never happen, but apparently it happened... \033[0m", __FUNCTION__, __LINE__, v); + } + + if (tc.fUseClone) { + mupa.fCorrelationsPro[k][n][v] = reinterpret_cast(res.fResultsPro[v]->Clone(Form("fCorrelationsPro[%d][%d][%s]", k, n, res.fResultsProRawName[v].Data()))); // yes + } else { + mupa.fCorrelationsPro[k][n][v] = new TProfile(Form("fCorrelationsPro[%d][%d][%s]", k, n, res.fResultsProRawName[v].Data()), "", res.fResultsPro[v]->GetXaxis()->GetXbins()->GetSize() - 1, res.fResultsPro[v]->GetXaxis()->GetXbins()->GetArray()); + } + + mupa.fCorrelationsPro[k][n][v]->SetStats(false); + mupa.fCorrelationsPro[k][n][v]->Sumw2(); + mupa.fCorrelationsPro[k][n][v]->GetXaxis()->SetTitle(FancyFormatting(res.fResultsProXaxisTitle[v].Data())); + mupa.fCorrelationsPro[k][n][v]->GetYaxis()->SetTitle(Form("#LT#LTcos[%s(%s)]#GT#GT", 1 == n + 1 ? "" : Form("%d", n + 1), oVariable[k].Data())); + mupa.fCorrelationsList->Add(mupa.fCorrelationsPro[k][n][v]); + } + } // for (int n = 0; n < gMaxHarmonic; n++) // harmonic + } // for (int k = 0; k < 4; k++) // order [2p=0,4p=1,6p=2,8p=3] + + // d) Few quick insanity checks on booking: + if (mupa.fCorrelationsPro[0][0][AFO_INTEGRATED] && !TString(mupa.fCorrelationsPro[0][0][AFO_INTEGRATED]->GetXaxis()->GetTitle()).EqualTo("integrated")) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); // ordering in enum eAsFunctionOf is not the same as in TString fResultsProXaxisTitle[eAsFunctionOf_N] + } + if (mupa.fCorrelationsPro[0][0][AFO_PT] && !TString(mupa.fCorrelationsPro[0][0][AFO_PT]->GetXaxis()->GetTitle()).EqualTo("p_{T}")) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); // ordering in enum eAsFunctionOf is not the same as in TString fResultsProXaxisTitle[eAsFunctionOf_N] + } + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // bookCorrelationsHistograms() + + //============================================================ + + void bookWeightsHistograms() + { + // Book all objects for particle weights. + + // a) Book the profile holding flags; + // b) Histograms for integrated weights; + // c) Histograms for differential weights; + // d) Sparse histograms for differential phi weights. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // a) Book the profile holding flags: + pw.fWeightsFlagsPro = new TProfile("fWeightsFlagsPro", "flags for particle weights", 17, 0., 17.); + pw.fWeightsFlagsPro->SetStats(false); + pw.fWeightsFlagsPro->SetLineColor(eColor); + pw.fWeightsFlagsPro->SetFillColor(eFillColor); + pw.fWeightsFlagsPro->GetXaxis()->SetLabelSize(0.035); + + if (tc.fUseSetBinLabel) { + + pw.fWeightsFlagsPro->GetXaxis()->SetBinLabel(1, "w_{#varphi}"); + pw.fWeightsFlagsPro->GetXaxis()->SetBinLabel(2, "w_{p_{t}}"); + pw.fWeightsFlagsPro->GetXaxis()->SetBinLabel(3, "w_{#eta}"); + pw.fWeightsFlagsPro->GetXaxis()->SetBinLabel(4, "(w_{#varphi})_{| p_{T}}"); // TBI 20241019 not sure if this is the final notation, keep in sync with void SetDiffWeightsHist(...) + pw.fWeightsFlagsPro->GetXaxis()->SetBinLabel(5, "(w_{#varphi})_{| #eta}"); // TBI 20241019 not sure if this is the final notation, keep in sync with void SetDiffWeightsHist(...) + + // **) differential phi weights using sparse: + pw.fWeightsFlagsPro->GetXaxis()->SetBinLabel(6, "(w_{#varphi})_{phi axis (sparse)}"); + pw.fWeightsFlagsPro->GetXaxis()->SetBinLabel(7, "(w_{#varphi})_{p_{T} axis (sparse)}"); + pw.fWeightsFlagsPro->GetXaxis()->SetBinLabel(8, "(w_{#varphi})_{#eta axis (sparse)}"); + pw.fWeightsFlagsPro->GetXaxis()->SetBinLabel(9, "(w_{#varphi})_{charge axis (sparse)}"); + pw.fWeightsFlagsPro->GetXaxis()->SetBinLabel(10, "(w_{#varphi})_{centrality axis (sparse)}"); + pw.fWeightsFlagsPro->GetXaxis()->SetBinLabel(11, "(w_{#varphi})_{VertexZ axis (sparse)}"); + + // **) differential pt weights using sparse: + pw.fWeightsFlagsPro->GetXaxis()->SetBinLabel(12, "(w_{p_{T}})_{pt axis (sparse)}"); + + // **) differential eta weights using sparse: + pw.fWeightsFlagsPro->GetXaxis()->SetBinLabel(13, "(w_{#eta})_{eta axis (sparse)}"); + + } else { + + // Workaround for SetBinLabel() large memory consumption: + TString yAxisTitle = ""; + + yAxisTitle += TString::Format("%d:w_{#varphi}; ", 1); + yAxisTitle += TString::Format("%d:w_{p_{t}}; ", 2); + yAxisTitle += TString::Format("%d:w_{#eta}; ", 3); + yAxisTitle += TString::Format("%d:(w_{#varphi})_{| p_{T}}; ", 4); + yAxisTitle += TString::Format("%d:(w_{#varphi})_{| #eta}; ", 5); + + // **) differential phi weights using sparse: + yAxisTitle += TString::Format("%d:(w_{#varphi})_{phi axis (sparse)}; ", 6); + yAxisTitle += TString::Format("%d:(w_{#varphi})_{p_{T} axis (sparse)}; ", 7); + yAxisTitle += TString::Format("%d:(w_{#varphi})_{#eta axis (sparse)}; ", 8); + yAxisTitle += TString::Format("%d:(w_{#varphi})_{charge axis (sparse)}; ", 9); + yAxisTitle += TString::Format("%d:(w_{#varphi})_{centrality axis (sparse)}; ", 10); + yAxisTitle += TString::Format("%d:(w_{#varphi})_{VertexZ axis (sparse)}; ", 11); + + // **) differential pt weights using sparse: + yAxisTitle += TString::Format("%d:(w_{p_{T}})_{pt axis (sparse)}; ", 12); + yAxisTitle += TString::Format("%d:(w_{p_{T}})_{charge axis (sparse)}; ", 13); + yAxisTitle += TString::Format("%d:(w_{p_{T}})_{centrality axis (sparse)}; ", 14); + + // **) differential eta weights using sparse: + yAxisTitle += TString::Format("%d:(w_{#eta})_{eta axis (sparse)}; ", 15); + yAxisTitle += TString::Format("%d:(w_{#eta})_{charge axis (sparse)}; ", 16); + yAxisTitle += TString::Format("%d:(w_{#eta})_{centrality axis (sparse)}; ", 17); + + // ... + + // *) Insanity check on the number of fields in this specially crafted y-axis title: + TObjArray* oa = yAxisTitle.Tokenize(";"); + if (!oa) { + LOGF(fatal, "\033[1;31m%s at line %d : oa is NULL\033[0m", __FUNCTION__, __LINE__); + } + if (oa->GetEntries() - 1 != pw.fWeightsFlagsPro->GetNbinsX()) { + LOGF(fatal, "\033[1;31m%s at line %d : oa->GetEntries() - 1 = %d != pw.fWeightsFlagsPro->GetNbinsX() = %d\033[0m", __FUNCTION__, __LINE__, oa->GetEntries(), pw.fWeightsFlagsPro->GetNbinsX()); + } + + // *) Okay, set the title: + pw.fWeightsFlagsPro->GetYaxis()->SetTitle(yAxisTitle.Data()); + + } // else + + for (int w = 0; w < eWeights_N; w++) // use weights [phi,pt,eta] + { + if (pw.fUseWeights[w]) { + pw.fWeightsFlagsPro->Fill(w + 0.5, 1.); + } + } + + // **) use differential weights [phipt,phieta,...] TBI 20250514 obsolete + if (pw.fUseDiffWeights[wPHIPT]) { + pw.fWeightsFlagsPro->Fill(3.5, 1.); + } + if (pw.fUseDiffWeights[wPHIETA]) { + pw.fWeightsFlagsPro->Fill(4.5, 1.); + } + + // **) differential phi weights using sparse: + if (pw.fUseDiffPhiWeights[wPhiPhiAxis]) { + pw.fWeightsFlagsPro->Fill(5.5, 1.); + } + if (pw.fUseDiffPhiWeights[wPhiPtAxis]) { + pw.fWeightsFlagsPro->Fill(6.5, 1.); + } + if (pw.fUseDiffPhiWeights[wPhiEtaAxis]) { + pw.fWeightsFlagsPro->Fill(7.5, 1.); + } + if (pw.fUseDiffPhiWeights[wPhiChargeAxis]) { + pw.fWeightsFlagsPro->Fill(8.5, 1.); + } + if (pw.fUseDiffPhiWeights[wPhiCentralityAxis]) { + pw.fWeightsFlagsPro->Fill(9.5, 1.); + } + if (pw.fUseDiffPhiWeights[wPhiVertexZAxis]) { + pw.fWeightsFlagsPro->Fill(10.5, 1.); + } + + // **) differential pt weights using sparse: + if (pw.fUseDiffPtWeights[wPtPtAxis]) { + pw.fWeightsFlagsPro->Fill(11.5, 1.); + } + if (pw.fUseDiffPhiWeights[wPtChargeAxis]) { + pw.fWeightsFlagsPro->Fill(12.5, 1.); + } + if (pw.fUseDiffPhiWeights[wPtCentralityAxis]) { + pw.fWeightsFlagsPro->Fill(13.5, 1.); + } + + // **) differential eta weights using sparse: + if (pw.fUseDiffEtaWeights[wEtaEtaAxis]) { + pw.fWeightsFlagsPro->Fill(14.5, 1.); + } + if (pw.fUseDiffPhiWeights[wEtaChargeAxis]) { + pw.fWeightsFlagsPro->Fill(15.5, 1.); + } + if (pw.fUseDiffPhiWeights[wEtaCentralityAxis]) { + pw.fWeightsFlagsPro->Fill(16.5, 1.); + } + + pw.fWeightsList->Add(pw.fWeightsFlagsPro); + + // b) Histograms for integrated weights: + // As of 20240216, I have abandoned the idea to generate integrated weights internally, weights + // are always fetched and cloned from external files, in any case (local, AliEn, CCDB). + // Therefore, add histos with weights to this list only after they are cloned from external files. + + // c) Histograms for differential weights: + // Same comment applies as for b) => add histograms to the list, only after they are cloned from external files. + + // d) Sparse histograms for differential phi weights: + // Same comment applies as for b) => add sparse histograms to the list, only after they are cloned from external files. + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // void bookWeightsHistograms() + + //============================================================ + + void bookCentralityWeightsHistograms() + { + // Book all objects for centrality weights. + + // a) Book the profile holding flags; + // b) Histograms for centrality weights. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // a) Book the profile holding flags: + cw.fCentralityWeightsFlagsPro = + new TProfile("fCentralityWeightsFlagsPro", "flags for centrality weights", 1, 0., 1.); + cw.fCentralityWeightsFlagsPro->SetStats(false); + cw.fCentralityWeightsFlagsPro->SetLineColor(eColor); + cw.fCentralityWeightsFlagsPro->SetFillColor(eFillColor); + cw.fCentralityWeightsFlagsPro->GetXaxis()->SetLabelSize(0.05); + + if (tc.fUseSetBinLabel) { + cw.fCentralityWeightsFlagsPro->GetXaxis()->SetBinLabel(1, TString::Format("Use centrality weights for estimator %s", ec.fsEventCuts[eCentralityEstimator].Data())); + + // ... + + } else { + // Workaround for SetBinLabel() large memory consumption: + TString yAxisTitle = ""; + + yAxisTitle += TString::Format("%d:Use centrality weights for estimator %s; ", 1, ec.fsEventCuts[eCentralityEstimator].Data()); + + // ... + + // *) Insanity check on the number of fields in this specially crafted y-axis title: + TObjArray* oa = yAxisTitle.Tokenize(";"); + if (!oa) { + LOGF(fatal, "\033[1;31m%s at line %d : oa is NULL\033[0m", __FUNCTION__, __LINE__); + } + if (oa->GetEntries() - 1 != cw.fCentralityWeightsFlagsPro->GetNbinsX()) { + LOGF(fatal, "\033[1;31m%s at line %d : oa->GetEntries() - 1 = %d != cw.fCentralityWeightsFlagsPro->GetNbinsX() = %d\033[0m", __FUNCTION__, __LINE__, oa->GetEntries(), cw.fCentralityWeightsFlagsPro->GetNbinsX()); + } + + // *) Okay, set the title: + cw.fCentralityWeightsFlagsPro->GetYaxis()->SetTitle(yAxisTitle.Data()); + } + + if (cw.fUseCentralityWeights) { + cw.fCentralityWeightsFlagsPro->Fill(0.5, 1.); // TBI 20241118 shall I automate this? + } + cw.fCentralityWeightsList->Add(cw.fCentralityWeightsFlagsPro); + + // b) Histograms for centrality weights: + // As of 20240216, I have abandoned the idea to generate centrality weights internally, centrality weights + // are always fetched and cloned from external files, in any case (local, AliEn, CCDB). + // Therefore, add histos with centrality weights to this list only after they are cloned from external files. + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // void bookCentralityWeightsHistograms() + + //============================================================ + + void bookNestedLoopsHistograms() + { + // Book all nested loops histograms. + + // a) Book the profile holding flags; + // b) Common local labels (keep 'em in sync with bookCorrelationsHistograms()); + // c) Book what needs to be booked; + // d) Few quick insanity checks on booking. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // a) Book the profile holding flags: + nl.fNestedLoopsFlagsPro = + new TProfile("fNestedLoopsFlagsPro", "flags for nested loops", 4, 0., 4.); + nl.fNestedLoopsFlagsPro->SetStats(false); + nl.fNestedLoopsFlagsPro->SetLineColor(eColor); + nl.fNestedLoopsFlagsPro->SetFillColor(eFillColor); + nl.fNestedLoopsFlagsPro->GetXaxis()->SetLabelSize(0.03); + + if (tc.fUseSetBinLabel) { + nl.fNestedLoopsFlagsPro->GetXaxis()->SetBinLabel(1, "fCalculateNestedLoops"); + nl.fNestedLoopsFlagsPro->Fill(0.5, nl.fCalculateNestedLoops); + nl.fNestedLoopsFlagsPro->GetXaxis()->SetBinLabel(2, "fCalculateCustomNestedLoops"); + nl.fNestedLoopsFlagsPro->Fill(1.5, nl.fCalculateCustomNestedLoops); + nl.fNestedLoopsFlagsPro->GetXaxis()->SetBinLabel(3, "fCalculateKineCustomNestedLoops"); + nl.fNestedLoopsFlagsPro->Fill(2.5, nl.fCalculateKineCustomNestedLoops); + nl.fNestedLoopsFlagsPro->GetXaxis()->SetBinLabel(4, "fMaxNestedLoop"); + nl.fNestedLoopsFlagsPro->Fill(3.5, nl.fMaxNestedLoop); + + // ... + } else { + // Workaround for SetBinLabel() large memory consumption: + TString yAxisTitle = ""; + + yAxisTitle += TString::Format("%d:fCalculateNestedLoops; ", 1); + nl.fNestedLoopsFlagsPro->Fill(0.5, nl.fCalculateNestedLoops); + + yAxisTitle += TString::Format("%d:fCalculateCustomNestedLoops; ", 2); + nl.fNestedLoopsFlagsPro->Fill(1.5, nl.fCalculateCustomNestedLoops); + + yAxisTitle += TString::Format("%d:fCalculateKineCustomNestedLoops; ", 3); + nl.fNestedLoopsFlagsPro->Fill(2.5, nl.fCalculateKineCustomNestedLoops); + + yAxisTitle += TString::Format("%d:fMaxNestedLoop; ", 4); + nl.fNestedLoopsFlagsPro->Fill(3.5, nl.fMaxNestedLoop); + + // ... + + // *) Insanity check on the number of fields in this specially crafted y-axis title: + TObjArray* oa = yAxisTitle.Tokenize(";"); + if (!oa) { + LOGF(fatal, "\033[1;31m%s at line %d : oa is NULL\033[0m", __FUNCTION__, __LINE__); + } + if (oa->GetEntries() - 1 != nl.fNestedLoopsFlagsPro->GetNbinsX()) { + LOGF(fatal, "\033[1;31m%s at line %d : oa->GetEntries() - 1 = %d != nl.fNestedLoopsFlagsPro->GetNbinsX() = %d\033[0m", __FUNCTION__, __LINE__, oa->GetEntries(), nl.fNestedLoopsFlagsPro->GetNbinsX()); + } + + // *) Okay, set the title: + nl.fNestedLoopsFlagsPro->GetYaxis()->SetTitle(yAxisTitle.Data()); + + } // else + + nl.fNestedLoopsList->Add(nl.fNestedLoopsFlagsPro); + + if (!(nl.fCalculateNestedLoops || nl.fCalculateCustomNestedLoops || nl.fCalculateKineCustomNestedLoops)) { + // TBI 20240326 I have to keep all 3 flags above, because for instance TArrayD* ftaNestedLoops[2] is used as a storage both for nl.fCalculateNestedLoops and nl.fCalculateCustomNestedLoops + return; + } + + // *) Book containers for integrated nested loops: + if (nl.fCalculateNestedLoops || nl.fCalculateCustomNestedLoops) { + const int iMaxSize = 2e4; + nl.ftaNestedLoops[0] = new TArrayD(iMaxSize); // ebe container for azimuthal angles + nl.ftaNestedLoops[1] = new TArrayD(iMaxSize); // ebe container for particle weights (product of all) + } + + // *) Book containers for differential nested loops: + if (nl.fCalculateKineCustomNestedLoops) { + + const int iMaxSize = 2e4; // this is roughly number of particles per bin, it shouldn't exceed this threshold + int nBins = -1; + + // 1D kine: + // **) vs. pt: + nBins = res.fResultsPro[AFO_PT]->GetNbinsX() + 2; // + 2 means that I take into account overflow and underflow, then skip later + for (int b = 0; b < nBins; b++) { + nl.ftaNestedLoopsKine[PTq][b][0] = new TArrayD(iMaxSize); + nl.ftaNestedLoopsKine[PTq][b][1] = new TArrayD(iMaxSize); + } + + // **) vs. eta: + nBins = res.fResultsPro[AFO_ETA]->GetNbinsX() + 2; // + 2 means that I take into account overflow and underflow, then skip it later + for (int b = 0; b < nBins; b++) { + nl.ftaNestedLoopsKine[ETAq][b][0] = new TArrayD(iMaxSize); + nl.ftaNestedLoopsKine[ETAq][b][1] = new TArrayD(iMaxSize); + } + + // **) vs. charge: + nBins = res.fResultsPro[AFO_CHARGE]->GetNbinsX() + 2; // + 2 means that I take into account overflow and underflow, then skip it later + for (int b = 0; b < nBins; b++) { + nl.ftaNestedLoopsKine[CHARGEq][b][0] = new TArrayD(iMaxSize); + nl.ftaNestedLoopsKine[CHARGEq][b][1] = new TArrayD(iMaxSize); + } + + // ... + + // 2D kine: + // **) vs. (pt,eta): + if (res.fResultsPro2D[AfoKineMap2D(PT_ETAq)]) { + // this is safe, because this one shall be booked if any of Correlations, Test0, EtaSeparations, etc., was requested + nBins = (res.fResultsPro2D[AfoKineMap2D(PT_ETAq)]->GetNbinsX() + 2) * (res.fResultsPro2D[AfoKineMap2D(PT_ETAq)]->GetNbinsY() + 2); + // + 2 means that I take into account overflow and underflow, then skip it in the loop below + for (int b = 0; b < nBins; b++) { // loop over lineralized global bins + nl.ftaNestedLoopsKine[PT_ETAq][b][0] = new TArrayD(iMaxSize); + nl.ftaNestedLoopsKine[PT_ETAq][b][1] = new TArrayD(iMaxSize); + } + } + + // **) vs. (pt,charge): + if (res.fResultsPro2D[AfoKineMap2D(PT_CHARGEq)]) { + // this is safe, because this one shall be booked if any of Correlations, Test0, EtaSeparations, etc., was requested + nBins = (res.fResultsPro2D[AfoKineMap2D(PT_CHARGEq)]->GetNbinsX() + 2) * (res.fResultsPro2D[AfoKineMap2D(PT_CHARGEq)]->GetNbinsY() + 2); + // + 2 means that I take into account overflow and underflow, then skip it in the loop below + for (int b = 0; b < nBins; b++) { // loop over lineralized global bins + nl.ftaNestedLoopsKine[PT_CHARGEq][b][0] = new TArrayD(iMaxSize); + nl.ftaNestedLoopsKine[PT_CHARGEq][b][1] = new TArrayD(iMaxSize); + } + } + + // **) vs. (eta,charge): + if (res.fResultsPro2D[AfoKineMap2D(ETA_CHARGEq)]) { + // this is safe, because this one shall be booked if any of Correlations, Test0, EtaSeparations, etc., was requested + nBins = (res.fResultsPro2D[AfoKineMap2D(ETA_CHARGEq)]->GetNbinsX() + 2) * (res.fResultsPro2D[AfoKineMap2D(ETA_CHARGEq)]->GetNbinsY() + 2); + // + 2 means that I take into account overflow and underflow, then skip it in the loop below + for (int b = 0; b < nBins; b++) { // loop over lineralized global bins + nl.ftaNestedLoopsKine[ETA_CHARGEq][b][0] = new TArrayD(iMaxSize); + nl.ftaNestedLoopsKine[ETA_CHARGEq][b][1] = new TArrayD(iMaxSize); + } + } + + // ... + + // 3D kine: + // **) vs. (pt,eta,charge): + if (res.fResultsPro3D[AfoKineMap3D(PT_ETA_CHARGEq)]) { + // this is safe, because this one shall be booked if any of Correlations, Test0, EtaSeparations, etc., was requested + nBins = (res.fResultsPro3D[AfoKineMap3D(PT_ETA_CHARGEq)]->GetNbinsX() + 2) * (res.fResultsPro3D[AfoKineMap3D(PT_ETA_CHARGEq)]->GetNbinsY() + 2) * (res.fResultsPro3D[AfoKineMap3D(PT_ETA_CHARGEq)]->GetNbinsZ() + 2); + // + 2 means that I take into account overflow and underflow, then skip it in the loop below + for (int b = 0; b < nBins; b++) { // loop over lineralized global bins + nl.ftaNestedLoopsKine[PT_ETA_CHARGEq][b][0] = new TArrayD(iMaxSize); + nl.ftaNestedLoopsKine[PT_ETA_CHARGEq][b][1] = new TArrayD(iMaxSize); + } + } + + // ... + + } // if (nl.fCalculateKineCustomNestedLoops) + + // b) Common local labels (keep 'em in sync with bookCorrelationsHistograms()) + TString oVariable[4] = { + "#varphi_{1}-#varphi_{2}", + "#varphi_{1}+#varphi_{2}-#varphi_{3}-#varphi_{4}", + "#varphi_{1}+#varphi_{2}+#varphi_{3}-#varphi_{4}-#varphi_{5}-#varphi_{6}", + "#varphi_{1}+#varphi_{2}+#varphi_{3}+#varphi_{4}-#varphi_{5}-#varphi_{6}-" + "#varphi_{7}-#varphi_{8}"}; + + // c) Book what needs to be booked: + if (!(nl.fCalculateNestedLoops)) { // TBI 20240404 for the time being, I can keep it here, but eventualy it will have to go elsewhere + return; + } + for (int k = 0; k < 4; k++) // order [2p=0,4p=1,6p=2,8p=3] + { + // TBI 20240405 I could break here, with respect to what nl.fMaxNestedLoop was set to + + for (int n = 0; n < gMaxHarmonic; n++) // harmonic + { + for (int v = 0; v < eAsFunctionOf_N; v++) { + + if (!res.fResultsPro[v]) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + + if (tc.fUseClone) { + nl.fNestedLoopsPro[k][n][v] = reinterpret_cast(res.fResultsPro[v]->Clone(Form("fNestedLoopsPro[%d][%d][%d]", k, n, v))); // yes + } else { + nl.fNestedLoopsPro[k][n][v] = new TProfile(Form("fNestedLoopsPro[%d][%d][%s]", k, n, res.fResultsProRawName[v].Data()), "", res.fResultsPro[v]->GetXaxis()->GetXbins()->GetSize() - 1, res.fResultsPro[v]->GetXaxis()->GetXbins()->GetArray()); + } + + nl.fNestedLoopsPro[k][n][v]->SetTitle(Form("#LT#LTcos[%s(%s)]#GT#GT", 1 == n + 1 ? "" : Form("%d", n + 1), oVariable[k].Data())); + nl.fNestedLoopsPro[k][n][v]->SetStats(false); + nl.fNestedLoopsPro[k][n][v]->Sumw2(); + nl.fNestedLoopsPro[k][n][v]->GetXaxis()->SetTitle(res.fResultsProXaxisTitle[v].Data()); + + if (tc.fFixedNumberOfRandomlySelectedTracks > 0 && AFO_MULTIPLICITY == v) { // just a warning for the meaning of multiplicity in this special case + nl.fNestedLoopsPro[k][n][v]->GetXaxis()->SetTitle("WARNING: for each multiplicity, fFixedNumberOfRandomlySelectedTracks is selected randomly in Q-vector"); + } + + nl.fNestedLoopsList->Add(nl.fNestedLoopsPro[k][n][v]); + } // for(int v=0;v<5;v++) // variable [0=integrated,1=vs. + // multiplicity,2=vs. centrality] + } // for (int n = 0; n < gMaxHarmonic; n++) // harmonic + } // for (int k = 0; k < 4; k++) // order [2p=0,4p=1,6p=2,8p=3] + + // d) Few quick insanity checks on booking: + if (nl.fNestedLoopsPro[0][0][AFO_INTEGRATED] && !TString(nl.fNestedLoopsPro[0][0][AFO_INTEGRATED]->GetXaxis()->GetTitle()).EqualTo("integrated")) { + LOGF(info, "\033[1;33mnl.fNestedLoopsPro[0][0][AFO_INTEGRATED]->GetXaxis()->GetTitle() = %s \033[0m", nl.fNestedLoopsPro[0][0][AFO_INTEGRATED]->GetXaxis()->GetTitle()); + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); // ordering in enum eAsFunctionOf is not the same as in TString fResultsProXaxisTitle[eAsFunctionOf_N] + } + if (nl.fNestedLoopsPro[0][0][AFO_PT] && !TString(nl.fNestedLoopsPro[0][0][AFO_PT]->GetXaxis()->GetTitle()).EqualTo("pt")) { // I do not need here fancy formatting + LOGF(info, "\033[1;33mnl.fNestedLoopsPro[0][0][AFO_PT]->GetXaxis()->GetTitle() = %s \033[0m", nl.fNestedLoopsPro[0][0][AFO_PT]->GetXaxis()->GetTitle()); + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); // ordering in enum eAsFunctionOf is not the same as in TString fResultsProXaxisTitle[eAsFunctionOf_N] + } + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // void bookNestedLoopsHistograms() + + //============================================================ + + void bookNUAHistograms() + { + // Book all objects for Toy NUA. + + // a) Book the profile holding flags; + // b) Common local labels; + // c) Histograms. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // a) Book the profile holding flags: + nua.fNUAFlagsPro = new TProfile("fNUAFlagsPro", "flags for Toy NUA", 6, 0.5, 6.5); + nua.fNUAFlagsPro->SetStats(false); + nua.fNUAFlagsPro->SetLineColor(eColor); + nua.fNUAFlagsPro->SetFillColor(eFillColor); + nua.fNUAFlagsPro->GetXaxis()->SetLabelSize(0.03); + + // TBI 20240429 the binning below is a bit fragile, but ok... + if (tc.fUseSetBinLabel) { + nua.fNUAFlagsPro->GetXaxis()->SetBinLabel(static_cast(1 + ePhiNUAPDF), "fApplyNUAPDF[phi]"); + nua.fNUAFlagsPro->GetXaxis()->SetBinLabel(static_cast(1 + ePtNUAPDF), "fApplyNUAPDF[pt]"); + nua.fNUAFlagsPro->GetXaxis()->SetBinLabel(static_cast(1 + eEtaNUAPDF), "fApplyNUAPDF[eta]"); + nua.fNUAFlagsPro->GetXaxis()->SetBinLabel(static_cast(4 + ePhiNUAPDF), "fUseDefaultNUAPDF[phi]"); + nua.fNUAFlagsPro->GetXaxis()->SetBinLabel(static_cast(4 + ePtNUAPDF), "fUseDefaultNUAPDF[pt]"); + nua.fNUAFlagsPro->GetXaxis()->SetBinLabel(static_cast(4 + eEtaNUAPDF), "fUseDefaultNUAPDF[eta]"); + + // ... + + } else { + + // Workaround for SetBinLabel() large memory consumption: + TString yAxisTitle = ""; + + yAxisTitle += TString::Format("%d:fApplyNUAPDF[phi]; ", static_cast(1 + ePhiNUAPDF)); + yAxisTitle += TString::Format("%d:fApplyNUAPDF[pt]; ", static_cast(1 + ePtNUAPDF)); + yAxisTitle += TString::Format("%d:fApplyNUAPDF[eta]; ", static_cast(1 + eEtaNUAPDF)); + yAxisTitle += TString::Format("%d:fUseDefaultNUAPDF[phi]; ", static_cast(4 + ePhiNUAPDF)); + yAxisTitle += TString::Format("%d:fUseDefaultNUAPDF[pt]; ", static_cast(4 + ePtNUAPDF)); + yAxisTitle += TString::Format("%d:fUseDefaultNUAPDF[eta]; ", static_cast(4 + eEtaNUAPDF)); + + // ... + + // *) Insanity check on the number of fields in this specially crafted y-axis title: + TObjArray* oa = yAxisTitle.Tokenize(";"); + if (!oa) { + LOGF(fatal, "\033[1;31m%s at line %d : oa is NULL\033[0m", __FUNCTION__, __LINE__); + } + if (oa->GetEntries() - 1 != nua.fNUAFlagsPro->GetNbinsX()) { + LOGF(fatal, "\033[1;31m%s at line %d : oa->GetEntries() - 1 = %d != nua.fNUAFlagsPro->GetNbinsX() = %d\033[0m", __FUNCTION__, __LINE__, oa->GetEntries(), nua.fNUAFlagsPro->GetNbinsX()); + } + + // *) Okay, set the title: + nua.fNUAFlagsPro->GetYaxis()->SetTitle(yAxisTitle.Data()); + + } // else + + if (nua.fApplyNUAPDF[ePhiNUAPDF]) { + nua.fNUAFlagsPro->Fill(static_cast(1 + ePhiNUAPDF), 1.); + } + if (nua.fApplyNUAPDF[ePtNUAPDF]) { + nua.fNUAFlagsPro->Fill(static_cast(1 + ePtNUAPDF), 1.); + } + if (nua.fApplyNUAPDF[eEtaNUAPDF]) { + nua.fNUAFlagsPro->Fill(static_cast(1 + eEtaNUAPDF), 1.); + } + if (nua.fUseDefaultNUAPDF[ePhiNUAPDF]) { + nua.fNUAFlagsPro->Fill(static_cast(4 + ePhiNUAPDF), 1.); + } + if (nua.fUseDefaultNUAPDF[ePtNUAPDF]) { + nua.fNUAFlagsPro->Fill(static_cast(4 + ePtNUAPDF), 1.); + } + if (nua.fUseDefaultNUAPDF[eEtaNUAPDF]) { + nua.fNUAFlagsPro->Fill(static_cast(4 + eEtaNUAPDF), 1.); + } + nua.fNUAList->Add(nua.fNUAFlagsPro); + + if (!(nua.fApplyNUAPDF[ePhiNUAPDF] || nua.fApplyNUAPDF[ePtNUAPDF] || nua.fApplyNUAPDF[eEtaNUAPDF])) { + return; + } + + // b) Common local labels: + TString sVariable[eNUAPDF_N] = {"#varphi", "p_{t}", "#eta"}; // has to be in sync with the ordering of enum eNUAPDF + + // c) Histograms: + for (int pdf = 0; pdf < eNUAPDF_N; pdf++) // use pdfs for NUA in (phi, pt, eta, ...) + { + if (!nua.fCustomNUAPDF[pdf]) // yes, because these histos are cloned from the external ones, see void SetNUAPDF(TH1D* const hist, const char* variable); + { + // otherwise, book here TF1 objects with default pdfs for NUA: + + // *) default NUA for azimuthal angle pdf: + if (sVariable[pdf].EqualTo("#varphi")) { + if (!nua.fApplyNUAPDF[ePhiNUAPDF]) { + continue; + } + // Define default detector acceptance in azimuthal angle: Two sectors, with different probabilities. + double dFirstSector[2] = {-(3. / 4.) * o2::constants::math::PI, -(1. / 4.) * o2::constants::math::PI}; // first sector is defined as [-3Pi/4,Pi/4] + double dSecondSector[2] = {(1. / 3.) * o2::constants::math::PI, (2. / 3.) * o2::constants::math::PI}; // second sector is defined as [Pi/3,2Pi/3] + double dProbability[2] = {0.3, 0.5}; // probabilities + nua.fDefaultNUAPDF[ePhiNUAPDF] = new TF1(TString::Format("fDefaultNUAPDF[%d]", ePhiNUAPDF), "1.-(x>=[0])*(1.-[4]) + (x>=[1])*(1.-[4]) - (x>=[2])*(1.-[5]) + (x>=[3])*(1.-[5]) ", + ph.fParticleHistogramsBins[ePhi][1], ph.fParticleHistogramsBins[ePhi][2]); + nua.fDefaultNUAPDF[ePhiNUAPDF]->SetParameter(0, dFirstSector[0]); + nua.fDefaultNUAPDF[ePhiNUAPDF]->SetParameter(1, dFirstSector[1]); + nua.fDefaultNUAPDF[ePhiNUAPDF]->SetParameter(2, dSecondSector[0]); + nua.fDefaultNUAPDF[ePhiNUAPDF]->SetParameter(3, dSecondSector[1]); + nua.fDefaultNUAPDF[ePhiNUAPDF]->SetParameter(4, dProbability[0]); + nua.fDefaultNUAPDF[ePhiNUAPDF]->SetParameter(5, dProbability[1]); + nua.fNUAList->Add(nua.fDefaultNUAPDF[ePhiNUAPDF]); + + } else if (sVariable[pdf].EqualTo("p_{t}")) { + + // *) default NUA for transverse momentum pdf: + if (!nua.fApplyNUAPDF[ePtNUAPDF]) { + continue; + } + // Define default detector acceptance in transverse momentum: One sectors, with probability < 1. + double dSector[2] = {0.4, 0.8}; // sector is defined as 0.8 < pT < 1.2 + double dProbability = 0.3; // probability, so after being set this way, only 30% of particles in that sector are reconstructed + nua.fDefaultNUAPDF[ePtNUAPDF] = new TF1(TString::Format("fDefaultNUAPDF[%d]", ePtNUAPDF), "1.-(x>=[0])*(1.-[2]) + (x>=[1])*(1.-[2])", + ph.fParticleHistogramsBins[ePt][1], ph.fParticleHistogramsBins[ePt][2]); + nua.fDefaultNUAPDF[ePtNUAPDF]->SetParameter(0, dSector[0]); + nua.fDefaultNUAPDF[ePtNUAPDF]->SetParameter(1, dSector[1]); + nua.fDefaultNUAPDF[ePtNUAPDF]->SetParameter(2, dProbability); + nua.fNUAList->Add(nua.fDefaultNUAPDF[ePtNUAPDF]); + + } else if (sVariable[pdf].EqualTo("#eta")) { + + // *) default NUA for pseudorapidity pdf: + if (!nua.fApplyNUAPDF[eEtaNUAPDF]) { + continue; + } + // Define default detector acceptance in pseudorapidity: One sectors, with probability < 1. + double dSector[2] = {0.2, 0.6}; // sector is defined as 0.2 < eta < 0.6 + double dProbability = 0.2; // probability, so after being set this way, only 20% of particles in that sector are reconstructed + nua.fDefaultNUAPDF[eEtaNUAPDF] = new TF1(TString::Format("fDefaultNUAPDF[%d]", eEtaNUAPDF), "1.-(x>=[0])*(1.-[2]) + (x>=[1])*(1.-[2])", + ph.fParticleHistogramsBins[eEta][1], ph.fParticleHistogramsBins[eEta][2]); + nua.fDefaultNUAPDF[eEtaNUAPDF]->SetParameter(0, dSector[0]); + nua.fDefaultNUAPDF[eEtaNUAPDF]->SetParameter(1, dSector[1]); + nua.fDefaultNUAPDF[eEtaNUAPDF]->SetParameter(2, dProbability); + nua.fNUAList->Add(nua.fDefaultNUAPDF[eEtaNUAPDF]); + } else { + LOGF(fatal, "\033[1;31m%s at line %d : pdf = %s is not supported (yet)\n \033[0m", __FUNCTION__, __LINE__, sVariable[pdf].Data()); + } + + } else { // if(!nua.fCustomNUAPDF[pdf]) + // generic cosmetics for custom user-supplied pdfs via histograms: + nua.fCustomNUAPDF[pdf]->SetTitle(TString::Format("Custom user-provided NUA for %s", sVariable[pdf].Data())); + nua.fCustomNUAPDF[pdf]->SetStats(false); + nua.fCustomNUAPDF[pdf]->GetXaxis()->SetTitle(sVariable[pdf].Data()); + nua.fCustomNUAPDF[pdf]->SetFillColor(eFillColor); + nua.fCustomNUAPDF[pdf]->SetLineColor(eColor); + nua.fNUAList->Add(nua.fCustomNUAPDF[pdf]); + } // if(!nua.fCustomNUAPDF[pdf]) + + // Get the max values of pdfs, so that later in Accept(...) there is no loss of efficiency, when I would need to calculate the same thing for each particle: + if (!nua.fUseDefaultNUAPDF[pdf] && nua.fCustomNUAPDF[pdf]) { // pdf is a loop variable + // custom, user-provided pdf via TH1D object: + nua.fMaxValuePDF[pdf] = nua.fCustomNUAPDF[pdf]->GetMaximum(); + } else if (nua.fUseDefaultNUAPDF[pdf] && nua.fDefaultNUAPDF[pdf]) { + // default pdf implemented as TF1 object: + nua.fMaxValuePDF[pdf] = nua.fDefaultNUAPDF[pdf]->GetMaximum(ph.fParticleHistogramsBins[pdf][1], ph.fParticleHistogramsBins[pdf][2]); + } + + } // for(int pdf=0;pdfSetStats(false); + iv.fInternalValidationFlagsPro->SetLineColor(eColor); + iv.fInternalValidationFlagsPro->SetFillColor(eFillColor); + iv.fInternalValidationFlagsPro->GetXaxis()->SetLabelSize(0.04); + iv.fInternalValidationList->Add(iv.fInternalValidationFlagsPro); + + if (tc.fUseSetBinLabel) { + iv.fInternalValidationFlagsPro->GetXaxis()->SetBinLabel(1, "fUseInternalValidation"); + iv.fInternalValidationFlagsPro->Fill(0.5, iv.fUseInternalValidation); + iv.fInternalValidationFlagsPro->GetXaxis()->SetBinLabel(2, "fnEventsInternalValidation"); + iv.fInternalValidationFlagsPro->Fill(1.5, iv.fnEventsInternalValidation); + iv.fInternalValidationFlagsPro->GetXaxis()->SetBinLabel(3, "fRescaleWithTheoreticalInput"); + iv.fInternalValidationFlagsPro->Fill(2.5, iv.fRescaleWithTheoreticalInput); + iv.fInternalValidationFlagsPro->GetXaxis()->SetBinLabel(4, "fRandomizeReactionPlane"); + iv.fInternalValidationFlagsPro->Fill(3.5, iv.fRandomizeReactionPlane); + iv.fInternalValidationFlagsPro->GetXaxis()->SetBinLabel(5, TString::Format("option = %s", iv.fHarmonicsOptionInternalValidation->Data())); + + } else { + // Workaround for SetBinLabel() large memory consumption: + TString yAxisTitle = ""; + + yAxisTitle += TString::Format("%d:fUseInternalValidation; ", 1); + iv.fInternalValidationFlagsPro->Fill(0.5, static_cast(iv.fUseInternalValidation)); + + yAxisTitle += TString::Format("%d:fnEventsInternalValidation; ", 2); + iv.fInternalValidationFlagsPro->Fill(1.5, static_cast(iv.fnEventsInternalValidation)); + + yAxisTitle += TString::Format("%d:fRescaleWithTheoreticalInput; ", 3); + iv.fInternalValidationFlagsPro->Fill(2.5, static_cast(iv.fRescaleWithTheoreticalInput)); + + yAxisTitle += TString::Format("%d:fRandomizeReactionPlane; ", 4); + iv.fInternalValidationFlagsPro->Fill(3.5, static_cast(iv.fRandomizeReactionPlane)); + + yAxisTitle += TString::Format("%d:option = %s; ", 5, iv.fHarmonicsOptionInternalValidation->Data()); + + // ... + + // *) Insanity check on the number of fields in this specially crafted y-axis title: + TObjArray* oa = yAxisTitle.Tokenize(";"); + if (!oa) { + LOGF(fatal, "\033[1;31m%s at line %d : oa is NULL\033[0m", __FUNCTION__, __LINE__); + } + if (oa->GetEntries() - 1 != iv.fInternalValidationFlagsPro->GetNbinsX()) { + LOGF(fatal, "\033[1;31m%s at line %d : oa->GetEntries() - 1 = %d != iv.fInternalValidationFlagsPro->GetNbinsX() = %d\033[0m", __FUNCTION__, __LINE__, oa->GetEntries(), iv.fInternalValidationFlagsPro->GetNbinsX()); + } + + // *) Okay, set the title: + iv.fInternalValidationFlagsPro->GetYaxis()->SetTitle(yAxisTitle.Data()); + + } // else + + // *) Book object beyond this line only if internal validation was requested: + if (!iv.fUseInternalValidation) { + return; + } + + // b) Book and fill container vn amplitudes: + iv.fInternalValidationVnPsin[eVn] = new TArrayD(gMaxHarmonic); + auto lInternalValidationAmplitudes = (std::vector)cf_iv.cfInternalValidationAmplitudes; // this is now the local version of that array from configurable + if (lInternalValidationAmplitudes.size() < 1) { + LOGF(fatal, "\033[1;31m%s at line %d : set at least one vn amplitude in array cfInternalValidationAmplitudes\n \033[0m", __FUNCTION__, __LINE__); + } + if (lInternalValidationAmplitudes.size() > gMaxHarmonic) { + LOGF(fatal, "\033[1;31m%s at line %d : lInternalValidationAmplitudes.size() > gMaxHarmonic \n \033[0m", __FUNCTION__, __LINE__); + } + for (int i = 0; i < static_cast(lInternalValidationAmplitudes.size()); i++) { + iv.fInternalValidationVnPsin[eVn]->SetAt(lInternalValidationAmplitudes[i], i); + } + + // c) Book and fill container for Psin planes: + iv.fInternalValidationVnPsin[ePsin] = new TArrayD(gMaxHarmonic); + auto lInternalValidationPlanes = (std::vector)cf_iv.cfInternalValidationPlanes; + if (lInternalValidationPlanes.size() < 1) { + LOGF(fatal, "\033[1;31m%s at line : %d set at least one Psi plane in array cfInternalValidationPlanes\n \033[0m", __FUNCTION__, __LINE__); + } + if (lInternalValidationPlanes.size() > gMaxHarmonic) { + LOGF(fatal, "\033[1;31m%s at line %d : lInternalValidationPlanes.size() > gMaxHarmonic \n \033[0m", __FUNCTION__, __LINE__); + } + if (lInternalValidationAmplitudes.size() != lInternalValidationPlanes.size()) { + LOGF(fatal, "\033[1;31m%s at line %d : lInternalValidationAmplitudes.size() != lInternalValidationPlanes.size() \n \033[0m", __FUNCTION__, __LINE__); + } + for (int i = 0; i < static_cast(lInternalValidationPlanes.size()); i++) { + iv.fInternalValidationVnPsin[ePsin]->SetAt(lInternalValidationPlanes[i], i); + } + + // d) Handle multiplicity for internal validation: + auto lMultRangeInternalValidation = (std::vector)cf_iv.cfMultRangeInternalValidation; + iv.fMultRangeInternalValidation[eMin] = lMultRangeInternalValidation[eMin]; + iv.fMultRangeInternalValidation[eMax] = lMultRangeInternalValidation[eMax]; + if (iv.fMultRangeInternalValidation[eMin] >= iv.fMultRangeInternalValidation[eMax]) { + LOGF(fatal, "\033[1;31m%s at line %d : iv.fMultRangeInternalValidation[eMin] >= iv.fMultRangeInternalValidation[eMax] \n \033[0m", __FUNCTION__, __LINE__); + } + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // bookInternalValidationHistograms() + + //============================================================ + + TComplex TheoreticalValue(TArrayI* harmonics, TArrayD* amplitudes, TArrayD* planes) + { + // For the specified harmonics, from available amplitudes and symmetry planes, return the theoretical value of correlator. + // See Eq. (2) in MVC, originally derived in R. S. Bhalerao, M. Luzum, and J.-Y. Ollitrault, Phys. Rev. C 84, 034910 (2011), arXiv:1104.4740 [nucl-th]. + + // a) Insanity checks; + // b) Main calculus; + // c) Return value. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // a) Insanity checks: + if (!harmonics) { + LOGF(fatal, "\033[1;31m%s at line %d : !harmonics \n \033[0m", __FUNCTION__, __LINE__); + } + if (!amplitudes) { + LOGF(fatal, "\033[1;31m%s at line %d : !amplitudes \n \033[0m", __FUNCTION__, __LINE__); + } + if (!planes) { + LOGF(fatal, "\033[1;31m%s at line %d : !planes \n \033[0m", __FUNCTION__, __LINE__); + } + if (amplitudes->GetSize() != planes->GetSize()) { + LOGF(fatal, "\033[1;31m%s at line %d : amplitudes->GetSize() != planes->GetSize() \n \033[0m", __FUNCTION__, __LINE__); + } + + // b) Main calculus: + TComplex value = TComplex(1., 0., true); // yes, polar representation + for (int h = 0; h < harmonics->GetSize(); h++) { + // Using polar form of TComplex (double re, double im=0, bool polar=false): + value *= TComplex(amplitudes->GetAt(std::abs(harmonics->GetAt(h)) - 1), 1. * harmonics->GetAt(h) * planes->GetAt(std::abs(harmonics->GetAt(h)) - 1), true); + } // for(int h=0;hGetSize();h++) + + // c) Return value: + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + return value; + + } // TComplex TheoreticalValue(TArrayI *harmonics, TArrayD *amplitudes, TArrayD *planes) + + //============================================================ + + void InternalValidation() + { + // Internal validation against theoretical values in on-the-fly study for all implemented correlators. + + // :iv + + // Last update: 20260220 + + // To do: + // 20250121 At the moment, I do not support here differential phi weights. If I decide to add that feature, basically I need to generalize Accept() for 2D case, + // where e.g. phi(pt) weights will be given with some toy 2D pdf. + // 20251124 Not sure any longer if the previous comment applies => check further + + // *) Set and propagate some fake run number; + // *) Fetch the weights for this particular run number. Do it only once; + // a) Fourier like p.d.f. for azimuthal angles and flow amplitudes; + // b) Loop over on-the-fly events. + // b0) Reset ebye quantities; + // b1) Determine multiplicity, centrality, reaction plane and configure p.d.f. for azimuthal angles if harmonics are not constant e-by-e; + // b2) Fill event histograms before cuts; + // b3) Loop over particles; + // b4) Fill event histograms after cuts; + // b5) Calculate everything for selected events and particles; + // c) Delete persistent objects. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // *) Set and propagate some fake run number: + tc.fRunNumber = "123456"; + PropagateRunNumber(); + + // *) Fetch the weights for this particular run number. Do it only once. + // TBI 20231012 If eventualy I can access programatically run number in init(...) at run time, this shall go there. + if (!pw.fParticleWeightsAreFetched) { + if (pw.fUseWeights[wPHI] || pw.fUseWeights[wPT] || pw.fUseWeights[wETA] || pw.fUseDiffWeights[wPHIPT] || pw.fUseDiffWeights[wPHIETA]) { + GetParticleWeights(); + pw.fParticleWeightsAreFetched = true; + } + + // differential phi weights: + if (pw.fUseDiffPhiWeights[wPhiPhiAxis]) { // Yes, I check only the first flag. This way, I can switch off all differential phi weights by setting 0-wPhi in config. + // On the other hand, it doesn't make sense to calculate differential phi weights without having phi axis. + // At any point I shall be able to fall back to integrated phi weights, that corresponds to the case wheh "1-wPhi" and all others are "0-w..." + GetParticleWeights(); + pw.fParticleWeightsAreFetched = true; + } + + // differential pt weights: + if (pw.fUseDiffPtWeights[wPtPtAxis]) { // Yes, I check only the first flag. This way, I can switch off all differential pt weights by setting 0-wPt in config. + // On the other hand, it doesn't make sense to calculate differential pt weights without having pt axis. + // At any point I shall be able to fall back to integrated pt weights, that corresponds to the case wheh "1-wPt" and all others are "0-w..." + GetParticleWeights(); + pw.fParticleWeightsAreFetched = true; + } + + // differential eta weights: + if (pw.fUseDiffEtaWeights[wEtaEtaAxis]) { // Yes, I check only the first flag. This way, I can switch off all differential eta weights by setting 0-wEta in config. + // On the other hand, it doesn't make sense to calculate differential eta weights without having eta axis. + // At any point I shall be able to fall back to integrated eta weights, that corresponds to the case wheh "1-wEta" and all others are "0-w..." + GetParticleWeights(); + pw.fParticleWeightsAreFetched = true; + } + + } // if (!pw.fParticleWeightsAreFetched) { + + // a) Fourier like p.d.f. for azimuthal angles and flow amplitudes: + TF1* fPhiPDF = NULL; + TF3* fvnPDF = NULL; + + if (iv.fHarmonicsOptionInternalValidation->EqualTo("constant")) { + // For this option, vn's and psin's are constant for all simulated events, therefore I can configure fPhiPDF outside of loop over events. + // Remark: The last parameter [18] is a random reaction plane, keep in sync with fPhiPDF->SetParameter(18,fReactionPlane); below. + // Keep also in sync with const int gMaxHarmonic = 9; in *GlobalConstants.h + fPhiPDF = new TF1("fPhiPDF", "1 + 2.*[0]*std::cos(x-[1]-[18]) + 2.*[2]*std::cos(2.*(x-[3]-[18])) + 2.*[4]*std::cos(3.*(x-[5]-[18])) + 2.*[6]*std::cos(4.*(x-[7]-[18])) + 2.*[8]*std::cos(5.*(x-[9]-[18])) + 2.*[10]*std::cos(6.*(x-[11]-[18])) + 2.*[12]*std::cos(7.*(x-[13]-[18])) + 2.*[14]*std::cos(8.*(x-[15]-[18])) + 2.*[16]*std::cos(9.*(x-[17]-[18]))", 0., o2::constants::math::TwoPI); + for (int h = 0; h < gMaxHarmonic; h++) { + fPhiPDF->SetParName(2 * h, TString::Format("v_{%d}", h + 1)); // set name v_n + fPhiPDF->SetParName(2 * h + 1, TString::Format("Psi_{%d}", h + 1)); // set name psi_n + // initialize v_n: + if (iv.fInternalValidationVnPsin[eVn] && h + 1 <= iv.fInternalValidationVnPsin[eVn]->GetSize()) { + fPhiPDF->SetParameter(2 * h, iv.fInternalValidationVnPsin[eVn]->GetAt(h)); + } else { + fPhiPDF->SetParameter(2 * h, 0.); + } + // initialize psi_n: + if (iv.fInternalValidationVnPsin[ePsin] && h + 1 <= iv.fInternalValidationVnPsin[ePsin]->GetSize()) { + fPhiPDF->SetParameter(2 * h + 1, iv.fInternalValidationVnPsin[ePsin]->GetAt(h)); + } else { + fPhiPDF->SetParameter(2 * h + 1, 0.); + } + } // for(int h=0;h This is initial configuration for p.d.f. used in internal validation:"); + for (int h = 0; h < 2 * gMaxHarmonic; h++) { + LOGF(info, Form("%d %s = %f", h, fPhiPDF->GetParName(h), fPhiPDF->GetParameter(h))); + } + LOGF(info, "Remark: Parameter [18] at the moment is reaction plane.\n"); + } // if (tc.fVerbose) { + + } else if (iv.fHarmonicsOptionInternalValidation->EqualTo("correlated")) { + // For this option, three selected vn's (v1,v2,v3) are correlated, and all psin's are set to zero, for simplicity. + // Remark: The last parameter [3] is a random reaction plane, keep in sync with fPhiPDF->SetParameter(3,fReactionPlane); below + // Keep also in sync with const int gMaxHarmonic = 9; in *GlobalConstants.h + + // Azimuthal angles are sampled from this pdf: + fPhiPDF = new TF1("fPhiPDF", "1 + 2.*[0]*std::cos(x-[3]) + 2.*[1]*std::cos(2.*(x-[3])) + 2.*[2]*std::cos(3.*(x-[3]))", 0., o2::constants::math::TwoPI); + // With this parameterization, I have: + // [0] => v1 + // [1] => v2 + // [2] => v3 + // [3] => RP + fPhiPDF->SetParName(0, "v_{1}"); + fPhiPDF->SetParName(1, "v_{2}"); + fPhiPDF->SetParName(2, "v_{3}"); + fPhiPDF->SetParName(3, "RP"); + + // vn amplitudes are sampled e-b-e from this pdf: + fvnPDF = new TF3("fvnPDF", "x + 2.*y - 3.*z", 0.07, 0.08, 0.06, 0.07, 0.05, 0.06); // v1 \in [0.07,0.08], v2 \in [0.06,0.07], v3 \in [0.05,0.06] + // check for example message 'W-TF3::GetRandom3: function:fvnPDF has 27000 negative values: abs assumed' in the log file + // All the amplitudes v1, v2 and v3, and RP are determined e-b-e, and then set in fPhiPDF below + + } else if (iv.fHarmonicsOptionInternalValidation->EqualTo("persistent")) { + // For this option, three selected vn's (v1,v2,v3) are correlated in the same way as in "correlated" case, but in addition, the persistent + // non-vanishing correlation among SPCs Psi1, Psi2 and Psi3 is introduced, in the same way as in arXiv:1901.06968, Sec. II D. + + // Remark: In this example, there is no Reaction Plane, instead Psi1 and Psi2 are sampled uniformly, and the equation for Psi3 is hardwired, + // to introduce strong and persistent SPC correlation, see arXiv:1901.06968, Sec. II D. + // Keep also in sync with const int gMaxHarmonic = 9; in *GlobalConstants.h + + // Azimuthal angles are sampled from this pdf: + fPhiPDF = new TF1("fPhiPDF", "1 + 2.*[0]*std::cos(x-[3]) + 2.*[1]*std::cos(2.*(x-[4])) + 2.*[2]*std::cos(3.*(x-[5]))", 0., o2::constants::math::TwoPI); + // With this parameterization, I have: + // [0] => v1 + // [1] => v2 + // [2] => v3 + // [3] => Psi1 + // [4] => Psi2 + // [5] => Psi3 + fPhiPDF->SetParName(0, "v_{1}"); + fPhiPDF->SetParName(1, "v_{2}"); + fPhiPDF->SetParName(2, "v_{3}"); + fPhiPDF->SetParName(3, "Psi_{1}"); + fPhiPDF->SetParName(4, "Psi_{2}"); + fPhiPDF->SetParName(5, "Psi_{3}"); + + // vn amplitudes are sampled e-b-e from this pdf (yes, for simplicity, I keep it the same as in "correlated" case): + fvnPDF = new TF3("fvnPDF", "x + 2.*y - 3.*z", 0.07, 0.08, 0.06, 0.07, 0.05, 0.06); // v1 \in [0.07,0.08], v2 \in [0.06,0.07], v3 \in [0.05,0.06] + // check for example message 'W-TF3::GetRandom3: function:fvnPDF has 27000 negative values: abs assumed' in the log file + // All the amplitudes v1, v2 and v3, and symmetry planes Psi_{1}, Psi_{2} and Psi_{3} are determined e-b-e, and then set in fPhiPDF below + } else if (iv.fHarmonicsOptionInternalValidation->EqualTo("ptDependent")) { + // For this option, one selected vn harmonic (v2) depends on pT, in the same way as defined in Eq. (32) in arXiv:1312.3572 + // I still use constant v1 = 0.04 and v3 = 0.06 in this example + one common reaction plane. + // For v2(pT), I am simply porting the legacy code from the class AliFlowEventSimpleMakerOnTheFly.cxx class from AliPhysics + + // Azimuthal angles are sampled from this pdf: + fPhiPDF = new TF1("fPhiPDF", "1 + 2.*[1]*std::cos(x-[0]) + 2.*[2]*std::cos(2.*(x-[0])) + 2.*[3]*std::cos(3.*(x-[0]))", 0., o2::constants::math::TwoPI); + // With this parameterization, I have: + // [0] => RP + // [1] => v1 + // [2] => v2(pt) + // [3] => v3 + fPhiPDF->SetParName(0, "RP"); + fPhiPDF->SetParName(1, "v_{1}"); + fPhiPDF->SetParName(2, "v_{2}(pt)"); + fPhiPDF->SetParName(3, "v_{3}"); + + // Set constant parameters here: + fPhiPDF->SetParameter(1, 0.04); // v1 = 0.04 = const in this parameterization + fPhiPDF->SetParameter(3, 0.06); // v3 = 0.06 = const in this parameterization + // Amplitude v2(pt) and reaction plane are pbyp set ebye in the loop below + } else if (iv.fHarmonicsOptionInternalValidation->EqualTo("ptEtaDependent")) { + // For this option, one selected vn harmonic (v2) depends both on pT and eta. + // pt dependence is the same as defined in Eq. (32) in arXiv:1312.3572 + // eta dependence is defined as 0.4 - (1/4) eta^2, so that v2(eta) = 0.24 at eta = +-0.8, and v2(eta) = 0.4 at eta = 0 (keep in sync with details below, when I am sampling pt and eta) + // to increase significance, I multiply by factor of 2 the sampled v2(pt,eta) (see the formula below when sampling) + // I still use constant v1 = 0.04 and v3 = 0.06 in this example + one common reaction plane. + + // Azimuthal angles are sampled from this pdf: + fPhiPDF = new TF1("fPhiPDF", "1 + 2.*[1]*std::cos(x-[0]) + 2.*[2]*std::cos(2.*(x-[0])) + 2.*[3]*std::cos(3.*(x-[0]))", 0., o2::constants::math::TwoPI); + // With this parameterization, I have: + // [0] => RP + // [1] => v1 + // [2] => v2(pt) + // [3] => v3 + fPhiPDF->SetParName(0, "RP"); + fPhiPDF->SetParName(1, "v_{1}"); + fPhiPDF->SetParName(2, "v_{2}(pt,eta)"); + fPhiPDF->SetParName(3, "v_{3}"); + + // Set constant parameters here: + fPhiPDF->SetParameter(1, 0.04); // v1 = 0.04 = const in this parameterization + fPhiPDF->SetParameter(3, 0.06); // v3 = 0.06 = const in this parameterization + // Amplitude v2(pt,eta) and reaction plane are pbyp set ebye in the loop below + } + + // b) Loop over on-the-fly events: + double v1 = 0., v2 = 0., v3 = 0.; + for (int e = 0; e < static_cast(iv.fnEventsInternalValidation); e++) { + + // b0) Reset ebye quantities: + ResetEventByEventQuantities(); + + // b1) Determine multiplicity, centrality, reaction plane and configure p.d.f. for azimuthal angles if harmonics are not constant e-by-e: + int nMult = static_cast(gRandom->Uniform(iv.fMultRangeInternalValidation[eMin], iv.fMultRangeInternalValidation[eMax])); + + double fReactionPlane = 0.; + if (iv.fRandomizeReactionPlane) { + fReactionPlane = gRandom->Uniform(0., o2::constants::math::TwoPI); // no cast is needed, since Uniform(...) returns double + } else { + LOGF(info, "\033[1;33m%s at line %d : Reaction plane was not randomized for this collision.\033[0m", __FUNCTION__, __LINE__); + } + if (iv.fHarmonicsOptionInternalValidation->EqualTo("constant")) { + fPhiPDF->SetParameter(18, fReactionPlane); + } else if (iv.fHarmonicsOptionInternalValidation->EqualTo("correlated")) { + fPhiPDF->SetParameter(3, fReactionPlane); + } else if (iv.fHarmonicsOptionInternalValidation->EqualTo("ptDependent")) { + fPhiPDF->SetParameter(0, fReactionPlane); + } else if (iv.fHarmonicsOptionInternalValidation->EqualTo("ptEtaDependent")) { + fPhiPDF->SetParameter(0, fReactionPlane); + } + // Remark: I do not need here anything for option "persistent", because RP is not used for that case. See below how 3 symmetry planes are introduced with persistent correlation + + ebye.fCentrality = static_cast(gRandom->Uniform(0., 100.)); // this is perfectly fine for this exercise + ebye.fOccupancy = static_cast(gRandom->Uniform(0., 10000.)); // this is perfectly fine for this exercise + ebye.fInteractionRate = static_cast(gRandom->Uniform(0., 1000.)); // this is perfectly fine for this exercise + ebye.fCurrentRunDuration = static_cast(gRandom->Uniform(0., 86400.)); // this is perfectly fine for this exercise + ebye.fVz = static_cast(gRandom->Uniform(-20., 20.)); // this is perfectly fine for this exercise + ebye.fFT0CAmplitudeOnFoundBC = static_cast(gRandom->Uniform(0., 100000.)); // this is perfectly fine for this exercise + ebye.fImpactParameter = static_cast(gRandom->Uniform(0., 20.)); // this is perfectly fine for this exercise + + // b2) Fill event histograms before cuts: + if (eh.fFillEventHistograms) { + !eh.fEventHistograms[eNumberOfEvents][eSim][eBefore] ? true : eh.fEventHistograms[eNumberOfEvents][eSim][eBefore]->Fill(0.5); + !eh.fEventHistograms[eTotalMultiplicity][eSim][eBefore] ? true : eh.fEventHistograms[eTotalMultiplicity][eSim][eBefore]->Fill(nMult); + !eh.fEventHistograms[eCentrality][eSim][eBefore] ? true : eh.fEventHistograms[eCentrality][eSim][eBefore]->Fill(ebye.fCentrality); + !eh.fEventHistograms[eOccupancy][eSim][eBefore] ? true : eh.fEventHistograms[eOccupancy][eSim][eBefore]->Fill(ebye.fOccupancy); + !eh.fEventHistograms[eInteractionRate][eSim][eBefore] ? true : eh.fEventHistograms[eInteractionRate][eSim][eBefore]->Fill(ebye.fInteractionRate); + !eh.fEventHistograms[eCurrentRunDuration][eSim][eBefore] ? true : eh.fEventHistograms[eCurrentRunDuration][eSim][eBefore]->Fill(ebye.fCurrentRunDuration); + !eh.fEventHistograms[eVertexZ][eSim][eBefore] ? true : eh.fEventHistograms[eVertexZ][eSim][eBefore]->Fill(ebye.fVz); + !eh.fEventHistograms[eEventPlaneAngle][eSim][eBefore] ? true : eh.fEventHistograms[eEventPlaneAngle][eSim][eBefore]->Fill(fReactionPlane); + } + + // ... here I could implement some event cuts, if necessary ... + + // configure p.d.f. for azimuthal angles if harmonics are not constant e-by-e, for option "correlated": + if (iv.fHarmonicsOptionInternalValidation->EqualTo("correlated")) { + // Sample 3 correlated vn's from TF3 fvnPDF, and with them initialize fPhiPDF: + fvnPDF->GetRandom3(v1, v2, v3); + fPhiPDF->SetParameter(0, v1); + fPhiPDF->SetParameter(1, v2); + fPhiPDF->SetParameter(2, v3); + // reaction plane is set above already + } // if(fHarmonicsOptionInternalValidation->EqualTo("correlated")) + + // configure p.d.f. for azimuthal angles if harmonics are not constant e-by-e, for option "persistent": + if (iv.fHarmonicsOptionInternalValidation->EqualTo("persistent")) { + + // Sample 3 correlated vn's from TF3 fvnPDF, and with them initialize fPhiPDF: + fvnPDF->GetRandom3(v1, v2, v3); + fPhiPDF->SetParameter(0, v1); + fPhiPDF->SetParameter(1, v2); + fPhiPDF->SetParameter(2, v3); + + // Persistent symmetry plane correlation: + double Psi1 = gRandom->Uniform(0., o2::constants::math::TwoPI); + double Psi2 = gRandom->Uniform(0., o2::constants::math::TwoPI); + double Psi3 = (1. / 3.) * (o2::constants::math::PIQuarter + 2. * Psi2 + Psi1); // see arXiv:1901.06968, Sec. II D. + // o2::constants::math::PIQuarter = 0.25f * PI + fPhiPDF->SetParameter(3, Psi1); + fPhiPDF->SetParameter(4, Psi2); + fPhiPDF->SetParameter(5, Psi3); + + // Remark: reaction plane is not needed for case "persistent" + + } // if(fHarmonicsOptionInternalValidation->EqualTo("persistent")) + + // b3) Loop over particles: + // *) Define min and max ranges for sampling: + double dPt_min = res.fResultsPro[AFO_PT]->GetXaxis()->GetBinLowEdge(1); // yes, low edge of first bin is pt min + double dPt_max = res.fResultsPro[AFO_PT]->GetXaxis()->GetBinLowEdge(1 + res.fResultsPro[AFO_PT]->GetNbinsX()); // yes, low edge of overflow bin is max pt + double dEta_min = res.fResultsPro[AFO_ETA]->GetXaxis()->GetBinLowEdge(1); // yes, low edge of first bin is eta min + double dEta_max = res.fResultsPro[AFO_ETA]->GetXaxis()->GetBinLowEdge(1 + res.fResultsPro[AFO_ETA]->GetNbinsX()); // yes, low edge of overflow bin is max eta + + for (int p = 0; p < nMult; p++) { + // Remark 0: I have to sample first pt, eta, charge, only then phi, because I allow the possibility that some harmonics depend on kinematics, e.g. v2(pt) or v2(pt,eta), etc. + // Remark 1: To increase performance, sample pt, eta or charge only if requested. + + if (mupa.fCalculateCorrelationsAsFunctionOf[AFO_PT] || t0.fCalculateTest0AsFunctionOf[AFO_PT] || es.fCalculateEtaSeparationsAsFunctionOf[AFO_PT] || + t0.fCalculate2DTest0AsFunctionOf[AFO_CENTRALITY_PT] || t0.fCalculate2DTest0AsFunctionOf[AFO_PT_ETA] || t0.fCalculate2DTest0AsFunctionOf[AFO_PT_CHARGE] || + t0.fCalculate3DTest0AsFunctionOf[AFO_CENTRALITY_PT_ETA] || t0.fCalculate3DTest0AsFunctionOf[AFO_CENTRALITY_PT_CHARGE] || t0.fCalculate3DTest0AsFunctionOf[AFO_CENTRALITY_PT_VZ] || + t0.fCalculate3DTest0AsFunctionOf[AFO_PT_ETA_CHARGE]) { + pbyp.fPt = gRandom->Uniform(dPt_min, dPt_max); + } + + if (mupa.fCalculateCorrelationsAsFunctionOf[AFO_ETA] || t0.fCalculateTest0AsFunctionOf[AFO_ETA] || es.fCalculateEtaSeparations || + t0.fCalculate2DTest0AsFunctionOf[AFO_CENTRALITY_ETA] || t0.fCalculate2DTest0AsFunctionOf[AFO_PT_ETA] || t0.fCalculate2DTest0AsFunctionOf[AFO_ETA_CHARGE] || + t0.fCalculate3DTest0AsFunctionOf[AFO_CENTRALITY_PT_ETA] || t0.fCalculate3DTest0AsFunctionOf[AFO_CENTRALITY_ETA_CHARGE] || t0.fCalculate3DTest0AsFunctionOf[AFO_CENTRALITY_ETA_VZ] || + t0.fCalculate3DTest0AsFunctionOf[AFO_PT_ETA_CHARGE]) { + // Yes, I have to use here es.fCalculateEtaSeparations , and not some differential flag, like for pt case above + pbyp.fEta = gRandom->Uniform(dEta_min, dEta_max); + } + + if (mupa.fCalculateCorrelationsAsFunctionOf[AFO_CHARGE] || t0.fCalculateTest0AsFunctionOf[AFO_CHARGE] || es.fCalculateEtaSeparationsAsFunctionOf[AFO_CHARGE] || + t0.fCalculate2DTest0AsFunctionOf[AFO_CENTRALITY_CHARGE] || t0.fCalculate2DTest0AsFunctionOf[AFO_PT_CHARGE] || t0.fCalculate2DTest0AsFunctionOf[AFO_ETA_CHARGE] || + t0.fCalculate3DTest0AsFunctionOf[AFO_CENTRALITY_PT_CHARGE] || t0.fCalculate3DTest0AsFunctionOf[AFO_CENTRALITY_ETA_CHARGE] || t0.fCalculate3DTest0AsFunctionOf[AFO_CENTRALITY_VZ_CHARGE] || + t0.fCalculate3DTest0AsFunctionOf[AFO_PT_ETA_CHARGE]) { + pbyp.fCharge = (1 == gRandom->Integer(2) ? 1 : -1); // gRandom->Integer(2) samples either 0 or 1, then I cast 0 into -1 + if (tc.fInsanityCheckForEachParticle && std::abs(pbyp.fCharge) != 1) { + LOGF(fatal, "\033[1;31m%s at line %d : pbyp.fCharge = %d\033[0m", __FUNCTION__, __LINE__, pbyp.fCharge); + } + } + + // Finalize configuration of p.d.f. for azimuthal angles if harmonics are depending on particle kine variables: + if (iv.fHarmonicsOptionInternalValidation->EqualTo("ptDependent")) { + float fV2vsPtCutOff = 2.0; // TBI 20250729 I could add configurables for these 2 variables at some point, otherwise, simply hardwire the constants in the expression below + float fV2vsPtMax = 0.3; + // v2(pt): for pt < fV2vsPtCutOff v2 increases linearly, for pt >= fV2vsPtCutOff v2 = fV2vsPtMax, see Eq. (32) in arXiv:1312.3572 + pbyp.fPt < fV2vsPtCutOff ? fPhiPDF->SetParameter(2, pbyp.fPt * fV2vsPtMax / fV2vsPtCutOff) : fPhiPDF->SetParameter(2, fV2vsPtMax); + } else if (iv.fHarmonicsOptionInternalValidation->EqualTo("ptEtaDependent")) { + float fV2vsPtCutOff = 2.0; // TBI 20250729 I could add configurables for these 2 variables at some point, otherwise, simply hardwire the constants in the expression below + float fV2vsPtMax = 0.3; // TBI 20250729 I shall NOT use f to name these two variables, rename eventually + // pt dependence: for pt < fV2vsPtCutOff v2 increases linearly, for pt >= fV2vsPtCutOff v2 = fV2vsPtMax, see Eq. (32) in arXiv:1312.3572 + // eta dependence is defined as 0.4 - (1/4) eta^2, so that v2(eta) = 0.24 at eta = +-0.8, and v2(eta) = 0.40 at eta = 0 (keep in sync with details above) + // to increase significance, I multiply by factor of 2 the sampled v2(pt,eta) + float v2 = 0.; // this is the actual v2(pt,eta) for the current particle + pbyp.fPt < fV2vsPtCutOff ? v2 = 2. * (pbyp.fPt * fV2vsPtMax / fV2vsPtCutOff) * (0.4 - (1. / 4.) * pbyp.fEta * pbyp.fEta) : v2 = 2. * fV2vsPtMax * (0.4 - (1. / 4.) * pbyp.fEta * pbyp.fEta); + if (v2 < 0. || v2 > 0.5) { + LOGF(fatal, "\033[1;31m%s at line %d : v2 = %f\033[0m", __FUNCTION__, __LINE__, v2); + } + fPhiPDF->SetParameter(2, v2); // set v2(pt,eta) for this particle + } + + // Finally, sample particle angle: + pbyp.fPhi = fPhiPDF->GetRandom(); + + // *) Fill few selected particle histograms before cuts here directly: + // Remark: I do not call FillParticleHistograms(track, eBefore), as I do not want to bother to make here full 'track' object, etc., just to fill simple kine info: + if (ph.fFillParticleHistograms || ph.fFillParticleHistograms2D) { + // 1D: + !ph.fParticleHistograms[ePhi][eSim][eBefore] ? true : ph.fParticleHistograms[ePhi][eSim][eBefore]->Fill(pbyp.fPhi); + !ph.fParticleHistograms[ePt][eSim][eBefore] ? true : ph.fParticleHistograms[ePt][eSim][eBefore]->Fill(pbyp.fPt); + !ph.fParticleHistograms[eEta][eSim][eBefore] ? true : ph.fParticleHistograms[eEta][eSim][eBefore]->Fill(pbyp.fEta); + !ph.fParticleHistograms[eCharge][eSim][eBefore] ? true : ph.fParticleHistograms[eCharge][eSim][eBefore]->Fill(pbyp.fCharge); + // 2D: + !ph.fParticleHistograms2D[ePhiPt][eSim][eBefore] ? true : ph.fParticleHistograms2D[ePhiPt][eSim][eBefore]->Fill(pbyp.fPhi, pbyp.fPt); + !ph.fParticleHistograms2D[ePhiEta][eSim][eBefore] ? true : ph.fParticleHistograms2D[ePhiEta][eSim][eBefore]->Fill(pbyp.fPhi, pbyp.fEta); + + // nD (THnSparse): + if (ph.fFillParticleSparseHistogramsBeforeCuts) { + // **) eDWPhi : here the fundamental 0-th axis never to be projected out is "phi" + if (ph.fBookParticleSparseHistograms[eDWPhi]) { + // Remark: It is mandatory that ordering in initialization here resembles the ordering in enum eDiffPhiWeights + double vector[eDiffPhiWeights_N] = {pbyp.fPhi, pbyp.fPt, pbyp.fEta, pbyp.fCharge, ebye.fCentrality, ebye.fVz}; + ph.fParticleSparseHistograms[eDWPhi][eSim][eBefore]->Fill(vector); + } + // **) eDWPt : here the fundamental 0-th axis never to be projected out is "pt" + if (ph.fBookParticleSparseHistograms[eDWPt]) { + // Remark: It is mandatory that ordering in initialization here resembles the ordering in enum eDiffPtWeights + double vector[eDiffPtWeights_N] = {pbyp.fPt, pbyp.fEta, pbyp.fCharge, ebye.fCentrality}; + ph.fParticleSparseHistograms[eDWPt][eSim][eBefore]->Fill(vector); + } + // **) eDWEta : here the fundamental 0-th axis never to be projected out is "eta" + if (ph.fBookParticleSparseHistograms[eDWEta]) { + // Remark: It is mandatory that ordering in initialization here resembles the ordering in enum eDiffEtaWeights + double vector[eDiffEtaWeights_N] = {pbyp.fEta, pbyp.fPt, pbyp.fCharge, ebye.fCentrality}; + ph.fParticleSparseHistograms[eDWEta][eSim][eBefore]->Fill(vector); + } + } // ph.fFillParticleSparseHistogramsBeforeCuts + } // if (ph.fFillParticleHistograms || ph.fFillParticleHistograms2D) + + // *) Particle cuts (only support for elementary kinematics (pt, eta, charge) and Toy NUA is provided, for the time being): + // *) Pt: + if (pc.fUseParticleCuts[ePt]) { + if (pbyp.fPt < pc.fdParticleCuts[ePt][eMin] || pbyp.fPt > pc.fdParticleCuts[ePt][eMax] || std::abs(pbyp.fPt - pc.fdParticleCuts[ePt][eMax]) < tc.fFloatingPointPrecision) { + continue; + } + } + + // *) Eta: + if (pc.fUseParticleCuts[eEta]) { + if (pbyp.fEta < pc.fdParticleCuts[eEta][eMin] || pbyp.fEta > pc.fdParticleCuts[eEta][eMax] || std::abs(pbyp.fEta - pc.fdParticleCuts[eEta][eMax]) < tc.fFloatingPointPrecision) { + continue; + } + } + + // *) Charge: + if (pc.fUseParticleCuts[eCharge]) { + if (pbyp.fCharge < pc.fdParticleCuts[eCharge][eMin] || pbyp.fCharge > pc.fdParticleCuts[eCharge][eMax]) { + // With first condition, I always throw away neutral particles => not needed here, see how I sample above. + // I can use safely == here, because track.sign() returns short int. + continue; + } + } + + // *) NUA: + if (nua.fApplyNUAPDF[ePhiNUAPDF] && !Accept(pbyp.fPhi, ePhiNUAPDF)) { + continue; + } + if (nua.fApplyNUAPDF[ePtNUAPDF] && !Accept(pbyp.fPt, ePtNUAPDF)) { + continue; + } + if (nua.fApplyNUAPDF[eEtaNUAPDF] && !Accept(pbyp.fEta, eEtaNUAPDF)) { + continue; + } + + // *) Fill few selected particle histograms after cuts here directly here: + // Remark: I do not call FillParticleHistograms(track, eAfter), as I do not want to bother to make here full 'track' object, etc., just to fill simple kine info: + if (ph.fFillParticleHistograms || ph.fFillParticleHistograms2D) { + // 1D: + !ph.fParticleHistograms[ePhi][eSim][eAfter] ? true : ph.fParticleHistograms[ePhi][eSim][eAfter]->Fill(pbyp.fPhi); + !ph.fParticleHistograms[ePt][eSim][eAfter] ? true : ph.fParticleHistograms[ePt][eSim][eAfter]->Fill(pbyp.fPt); + !ph.fParticleHistograms[eEta][eSim][eAfter] ? true : ph.fParticleHistograms[eEta][eSim][eAfter]->Fill(pbyp.fEta); + !ph.fParticleHistograms[eCharge][eSim][eAfter] ? true : ph.fParticleHistograms[eCharge][eSim][eAfter]->Fill(pbyp.fCharge); + // 2D: + !ph.fParticleHistograms2D[ePhiPt][eSim][eAfter] ? true : ph.fParticleHistograms2D[ePhiPt][eSim][eAfter]->Fill(pbyp.fPhi, pbyp.fPt); + !ph.fParticleHistograms2D[ePhiEta][eSim][eAfter] ? true : ph.fParticleHistograms2D[ePhiEta][eSim][eAfter]->Fill(pbyp.fPhi, pbyp.fEta); + // nD (THnSparse): + // **) eDWPhi : here the fundamental 0-th axis never to be projected out is "phi" + if (ph.fBookParticleSparseHistograms[eDWPhi]) { + // Remark: It is mandatory that ordering in initialization here resembles the ordering in enum eDiffPhiWeights + double vector[eDiffPhiWeights_N] = {pbyp.fPhi, pbyp.fPt, pbyp.fEta, pbyp.fCharge, ebye.fCentrality, ebye.fVz}; + ph.fParticleSparseHistograms[eDWPhi][eSim][eAfter]->Fill(vector); + } + // **) eDWPt : here the fundamental 0-th axis never to be projected out is "pt" + if (ph.fBookParticleSparseHistograms[eDWPt]) { + // Remark: It is mandatory that ordering in initialization here resembles the ordering in enum eDiffPtWeights + double vector[eDiffPtWeights_N] = {pbyp.fPt, pbyp.fEta, pbyp.fCharge, ebye.fCentrality}; + ph.fParticleSparseHistograms[eDWPt][eSim][eAfter]->Fill(vector); + } + // **) eDWEta : here the fundamental 0-th axis never to be projected out is "eta" + if (ph.fBookParticleSparseHistograms[eDWEta]) { + // Remark: It is mandatory that ordering in initialization here resembles the ordering in enum eDiffEtaWeights + double vector[eDiffEtaWeights_N] = {pbyp.fEta, pbyp.fPt, pbyp.fCharge, ebye.fCentrality}; + ph.fParticleSparseHistograms[eDWEta][eSim][eAfter]->Fill(vector); + } + } // if (ph.fFillParticleHistograms || ph.fFillParticleHistograms2D) + + // Remark: Keep in sync all calls and flags below with the ones in MainLoopOverParticles(). + // *) Integrated Q-vectors: + if (qv.fCalculateQvectors || es.fCalculateEtaSeparations) { + // This is now the new approach, with sparse histograms: + // **) particle arguments are passed by reference + // **) event observables (centrality, vertex z, ...), I do not need to pass as arguments, as I have data members for them (ebye.fCentrality, ebye.Vz, ...) + // **) I decide within FillQvectorFromSparse(...) whether and which weights are used. So yes, I use this one, despite its name, even when weights are NOT used + // (there is no real performance penalty) + // **) Legacy function FillQvector(...) is obsolete as of 20250714, since I can get both integrated and differential wights from sparse histograms. + this->FillQvectorFromSparse(); + } + + // *) Differential q-vectors (keep in sync with the code in MainLoopOverParticles(...)): + + // TBI 20260210 I need here a flag if this calculus is needed at all + + this->Fillqvectors(); // within this function, i call FillqvectorFromSparse(...), for each differential q-vector separately + + // *) Fill nested loops containers: + if (nl.fCalculateNestedLoops || nl.fCalculateCustomNestedLoops) { + this->FillNestedLoopsContainers(ebye.fSelectedTracks); + } + + // *) Counter of selected tracks in the current event: + // Remark: This has to go after FillNestedLoopsContainers(...), because ebye.fSelectedTracks is used as a particle index there. + ebye.fSelectedTracks++; + if (ebye.fSelectedTracks >= ec.fdEventCuts[eMultiplicity][eMax]) { + break; + } + + } // for(int p=0;pFill(0.5); + !eh.fEventHistograms[eTotalMultiplicity][eSim][eAfter] ? true : eh.fEventHistograms[eTotalMultiplicity][eSim][eAfter]->Fill(nMult); + !eh.fEventHistograms[eMultiplicity][eSim][eAfter] ? true : eh.fEventHistograms[eMultiplicity][eSim][eAfter]->Fill(ebye.fMultiplicity); + !eh.fEventHistograms[eCentrality][eSim][eAfter] ? true : eh.fEventHistograms[eCentrality][eSim][eAfter]->Fill(ebye.fCentrality); + !eh.fEventHistograms[eOccupancy][eSim][eAfter] ? true : eh.fEventHistograms[eOccupancy][eSim][eAfter]->Fill(ebye.fOccupancy); + !eh.fEventHistograms[eInteractionRate][eSim][eAfter] ? true : eh.fEventHistograms[eCentrality][eSim][eAfter]->Fill(ebye.fInteractionRate); + !eh.fEventHistograms[eCurrentRunDuration][eSim][eAfter] ? true : eh.fEventHistograms[eCurrentRunDuration][eSim][eAfter]->Fill(ebye.fCurrentRunDuration); + !eh.fEventHistograms[eVertexZ][eSim][eAfter] ? true : eh.fEventHistograms[eVertexZ][eSim][eAfter]->Fill(ebye.fVz); + !eh.fEventHistograms[eEventPlaneAngle][eSim][eAfter] ? true : eh.fEventHistograms[eEventPlaneAngle][eSim][eAfter]->Fill(fReactionPlane); + } + + // *) Fill subevent multiplicities: + // Remark: I can call this one only after Qa and Qb vectors are filled: + if (es.fCalculateEtaSeparations) { + FillSubeventMultiplicities(); + } + + // b5) Calculate everything for selected events and particles: + CalculateEverything(); + + // *) Reset event-by-event quantities: + ResetEventByEventQuantities(); + + // *) Print info on the current event number (within current real event): + LOGF(info, " Event # %d/%d (within current real event, running internal validation) ....", e + 1, static_cast(iv.fnEventsInternalValidation)); + + // *) Determine all event counters: + DetermineEventCounters(); + + // *) Sequential bailout: After each tc.fSequentialBailout events, I bail out: + if (iv.fInternalValidationForceBailout && tc.fSequentialBailout > 0 && eh.fEventCounter[eProcessed] > 0 && 0 == eh.fEventCounter[eProcessed] % tc.fSequentialBailout) { + BailOut(); + } + + // *) If I reached max number of events, ignore the remaining collisions: + if (MaxNumberOfEvents(eAfter)) { + if (iv.fInternalValidationForceBailout) { + BailOut(true); + } + } + + } // for(int e=0;e(iv.fnEventsInternalValidation);e++) + + // *) Print info on the current event number (total): + if (tc.fVerboseEventCounter) { + PrintEventCounter(eAfter); + } + + // c) Delete persistent objects: + if (fPhiPDF) { + delete fPhiPDF; + } + if (fvnPDF) { + delete fvnPDF; + } + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // void InternalValidation() + + //============================================================ + + bool Accept(const double& value, int var) + { + // Given the acceptance profile for this observable, accept or not that observable for the analysis. + // Use in Toy NUA studies. + + // Remark: var corresponds to the field in enum eNUAPDF { ePhiNUAPDF, ePtNUAPDF, eEtaNUAPDF }; + // Therefore, always call this function as e.g. Accept(someAngle, ePhiNUAPDF) or Accept(somePt, ePtNUAPDF) + + if (tc.fVerboseForEachParticle) { + LOGF(info, "\033[1;32m%s\033[0m", __FUNCTION__); + } + + // Basic protection: + if (nua.fUseDefaultNUAPDF[var] && !nua.fDefaultNUAPDF[var]) { + LOGF(info, "\033[1;33m%s var = %d\033[0m", static_cast(var)); + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } else if (!nua.fUseDefaultNUAPDF[var] && !nua.fCustomNUAPDF[var]) { + LOGF(info, "\033[1;33m%s var = %d\033[0m", static_cast(var)); + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + + bool bAccept = true; // return value + + double acceptanceProbability = 1.; + double correspondingAcceptance = -44.; + if (!nua.fUseDefaultNUAPDF[var]) { + correspondingAcceptance = nua.fCustomNUAPDF[var]->GetBinContent(nua.fCustomNUAPDF[var]->FindBin(value)); + } else { + correspondingAcceptance = nua.fDefaultNUAPDF[var]->Eval(value); + } + + // Probability to accept: + acceptanceProbability = 1. - (nua.fMaxValuePDF[var] - correspondingAcceptance) / nua.fMaxValuePDF[var]; + + // Accept or not: + (gRandom->Uniform(0, 1) < acceptanceProbability) ? bAccept = true : bAccept = false; + + return bAccept; + + } // bool Accept(const double &value, int var) + + //============================================================ + + void bookTest0Histograms() + { + // Book all Test0 histograms. + + // a) Book the profile holding flags; + // b) Book placeholder and make sure all labels are stored in the placeholder; + // c) Book what needs to be booked for 1D; + // d) Book what needs to be booked for 2D; + // e) Book what needs to be booked for 3D; + // f) Few quick insanity checks on booking (cherry-picking). + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // a) Book the profile holding flags: + t0.fTest0FlagsPro = new TProfile("fTest0FlagsPro", "flags for Test0", 3, 0., 3.); + t0.fTest0FlagsPro->SetStats(false); + t0.fTest0FlagsPro->GetXaxis()->SetLabelSize(0.04); + + if (tc.fUseSetBinLabel) { + t0.fTest0FlagsPro->GetXaxis()->SetBinLabel(1, "fCalculateTest0"); + t0.fTest0FlagsPro->GetXaxis()->SetBinLabel(2, "fCalculate2DTest0"); + t0.fTest0FlagsPro->GetXaxis()->SetBinLabel(3, "fCalculate3DTest0"); + + // ... + + } else { + // Workaround for SetBinLabel() large memory consumption: + TString yAxisTitle = ""; + + yAxisTitle += TString::Format("%d:fCalculateTest0; ", 1); + yAxisTitle += TString::Format("%d:fCalculate2DTest0; ", 2); + yAxisTitle += TString::Format("%d:fCalculate3DTest0; ", 3); + + // ... + + // *) Insanity check on the number of fields in this specially crafted y-axis title: + TObjArray* oa = yAxisTitle.Tokenize(";"); + if (!oa) { + LOGF(fatal, "\033[1;31m%s at line %d : oa is NULL\033[0m", __FUNCTION__, __LINE__); + } + if (oa->GetEntries() - 1 != t0.fTest0FlagsPro->GetNbinsX()) { + LOGF(fatal, "\033[1;31m%s at line %d : oa->GetEntries() - 1 = %d != t0.fTest0FlagsPro->GetNbinsX() = %d\033[0m", __FUNCTION__, __LINE__, oa->GetEntries(), t0.fTest0FlagsPro->GetNbinsX()); + } + + // *) Okay, set the title: + t0.fTest0FlagsPro->GetYaxis()->SetTitle(yAxisTitle.Data()); + + // ... + + } // else + + t0.fTest0FlagsPro->Fill(0.5, static_cast(t0.fCalculateTest0)); + t0.fTest0FlagsPro->Fill(1.5, static_cast(t0.fCalculate2DTest0)); + t0.fTest0FlagsPro->Fill(2.5, static_cast(t0.fCalculate3DTest0)); + // ... + t0.fTest0List->Add(t0.fTest0FlagsPro); + + if (!(t0.fCalculateTest0 || t0.fCalculate2DTest0 || t0.fCalculate3DTest0)) { + return; + } + + // b) Book placeholder and make sure all labels are stored in the placeholder: + this->StoreLabelsInPlaceholder(); + + // c) Book what needs to be booked for 1D: + if (t0.fCalculateTest0) { + for (int mo = 0; mo < gMaxCorrelator; mo++) { + for (int mi = 0; mi < gMaxIndex; mi++) { + if (!t0.fTest0Labels[mo][mi]) { + continue; + } + for (int v = 0; v < eAsFunctionOf_N; v++) { + + // decide what is booked, then later valid pointer to fTest0Pro[k][n][v] is used as a boolean, in the standard way: + if (!t0.fCalculateTest0AsFunctionOf[v]) { + continue; + } + + if (!res.fResultsPro[v]) { + LOGF(fatal, "\033[1;31m%s at line %d : fResultsPro[%d] is NULL, this shall never happen, but apparently it happened... \033[0m", __FUNCTION__, __LINE__, v); + } + + if (tc.fUseClone) { + t0.fTest0Pro[mo][mi][v] = reinterpret_cast(res.fResultsPro[v]->Clone(Form("fTest0Pro[%d][%d][%s]", mo, mi, res.fResultsProRawName[v].Data()))); // yes + } else { + t0.fTest0Pro[mo][mi][v] = new TProfile(Form("fTest0Pro[%d][%d][%s]", mo, mi, res.fResultsProRawName[v].Data()), "", res.fResultsPro[v]->GetXaxis()->GetXbins()->GetSize() - 1, res.fResultsPro[v]->GetXaxis()->GetXbins()->GetArray()); + } + + t0.fTest0Pro[mo][mi][v]->SetStats(false); + t0.fTest0Pro[mo][mi][v]->Sumw2(); + t0.fTest0Pro[mo][mi][v]->SetTitle(t0.fTest0Labels[mo][mi]->Data()); + t0.fTest0Pro[mo][mi][v]->GetXaxis()->SetTitle(FancyFormatting(res.fResultsProXaxisTitle[v].Data())); + t0.fTest0List->Add(t0.fTest0Pro[mo][mi][v]); // yes, this has to be here + + } // for(int v=0;vGetName(); + TObjArray* oa = rawName.Tokenize("[]"); + if (oa->GetEntries() != 2) { + LOGF(fatal, "\033[1;31m%s at line %d : oa->GetEntries() = %d \033[0m", __FUNCTION__, __LINE__, oa->GetEntries()); + } + rawName = oa->At(1)->GetName(); // basically: fResultsPro2D[cent_pt] => cent_pt + delete oa; + if (rawName.EqualTo("")) { + LOGF(fatal, "\033[1;31m%s at line %d : rawName is empty string \033[0m", __FUNCTION__, __LINE__); + } + + if (tc.fUseClone) { + t0.fTest0Pro2D[mo][mi][v] = reinterpret_cast(res.fResultsPro2D[v]->Clone(Form("fTest0Pro2D[%d][%d][%s]", mo, mi, rawName.Data()))); + } else { + // TBI 20250412 this branch is temporary workaround until hist->Clone(...) large memory consumption is resolved + t0.fTest0Pro2D[mo][mi][v] = new TProfile2D(Form("fTest0Pro2D[%d][%d][%s]", mo, mi, rawName.Data()), "", + res.fResultsPro2D[v]->GetXaxis()->GetXbins()->GetSize() - 1, res.fResultsPro2D[v]->GetXaxis()->GetXbins()->GetArray(), + res.fResultsPro2D[v]->GetYaxis()->GetXbins()->GetSize() - 1, res.fResultsPro2D[v]->GetYaxis()->GetXbins()->GetArray()); // yes, GetYaxis()->GetXbins() + } // else + + t0.fTest0Pro2D[mo][mi][v]->SetStats(false); + t0.fTest0Pro2D[mo][mi][v]->Sumw2(); + t0.fTest0Pro2D[mo][mi][v]->SetTitle(t0.fTest0Labels[mo][mi]->Data()); + t0.fTest0Pro2D[mo][mi][v]->GetXaxis()->SetTitle(FancyFormatting(res.fResultsPro2D[v]->GetXaxis()->GetTitle())); + t0.fTest0Pro2D[mo][mi][v]->GetYaxis()->SetTitle(FancyFormatting(res.fResultsPro2D[v]->GetYaxis()->GetTitle())); + t0.fTest0List->Add(t0.fTest0Pro2D[mo][mi][v]); // yes, this has to be here + + } // for(int v=0;vGetName(); + TObjArray* oa = rawName.Tokenize("[]"); + if (oa->GetEntries() != 2) { + LOGF(fatal, "\033[1;31m%s at line %d : oa->GetEntries() = %d \033[0m", __FUNCTION__, __LINE__, oa->GetEntries()); + } + rawName = oa->At(1)->GetName(); // basically: fResultsPro2D[cent_pt_eta] => cent_pt_eta + delete oa; + if (rawName.EqualTo("")) { + LOGF(fatal, "\033[1;31m%s at line %d : rawName is empty string \033[0m", __FUNCTION__, __LINE__); + } + + if (tc.fUseClone) { + t0.fTest0Pro3D[mo][mi][v] = reinterpret_cast(res.fResultsPro3D[v]->Clone(Form("fTest0Pro3D[%d][%d][%s]", mo, mi, rawName.Data()))); + } else { + // TBI 20250412 this branch is temporary workaround until hist->Clone(...) large memory consumption is resolved + t0.fTest0Pro3D[mo][mi][v] = new TProfile3D(Form("fTest0Pro3D[%d][%d][%s]", mo, mi, rawName.Data()), "", + res.fResultsPro3D[v]->GetXaxis()->GetXbins()->GetSize() - 1, res.fResultsPro3D[v]->GetXaxis()->GetXbins()->GetArray(), + res.fResultsPro3D[v]->GetYaxis()->GetXbins()->GetSize() - 1, res.fResultsPro3D[v]->GetYaxis()->GetXbins()->GetArray(), // yes, GetYaxis()->GetXbins() + res.fResultsPro3D[v]->GetZaxis()->GetXbins()->GetSize() - 1, res.fResultsPro3D[v]->GetZaxis()->GetXbins()->GetArray()); // yes, GetZaxis()->GetXbins() + } // else + + t0.fTest0Pro3D[mo][mi][v]->SetStats(false); + t0.fTest0Pro3D[mo][mi][v]->Sumw2(); + t0.fTest0Pro3D[mo][mi][v]->SetTitle(t0.fTest0Labels[mo][mi]->Data()); + t0.fTest0Pro3D[mo][mi][v]->GetXaxis()->SetTitle(FancyFormatting(res.fResultsPro3D[v]->GetXaxis()->GetTitle())); + t0.fTest0Pro3D[mo][mi][v]->GetYaxis()->SetTitle(FancyFormatting(res.fResultsPro3D[v]->GetYaxis()->GetTitle())); + t0.fTest0Pro3D[mo][mi][v]->GetZaxis()->SetTitle(FancyFormatting(res.fResultsPro3D[v]->GetZaxis()->GetTitle())); + t0.fTest0List->Add(t0.fTest0Pro3D[mo][mi][v]); // yes, this has to be here + + } // for(int v=0;vGetXaxis()->GetTitle()).EqualTo("integrated")) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); // ordering in enum eAsFunctionOf is not the same as in TString fResultsProXaxisTitle[eAsFunctionOf_N] + } + if (t0.fTest0Pro[0][0][AFO_PT] && !TString(t0.fTest0Pro[0][0][AFO_PT]->GetXaxis()->GetTitle()).EqualTo("p_{T}")) { + LOGF(fatal, "\033[1;31m%s at line %d : x-axis title = %s\033[0m", __FUNCTION__, __LINE__, t0.fTest0Pro[0][0][AFO_PT]->GetXaxis()->GetTitle()); // ordering in enum eAsFunctionOf is not the same as in TString fResultsProXaxisTitle[eAsFunctionOf_N] + } + + // 2D: + if (t0.fTest0Pro2D[0][0][AFO_CENTRALITY_PT] && !(TString(t0.fTest0Pro2D[0][0][AFO_CENTRALITY_PT]->GetXaxis()->GetTitle()).Contains("centrality", TString::kIgnoreCase) && TString(t0.fTest0Pro2D[0][0][AFO_CENTRALITY_PT]->GetYaxis()->GetTitle()).EqualTo("p_{T}"))) { + LOGF(fatal, "\033[1;31m%s at line %d : x-axis title = %s, y-axis title = %s\033[0m", __FUNCTION__, __LINE__, t0.fTest0Pro2D[0][0][AFO_CENTRALITY_PT]->GetXaxis()->GetTitle(), t0.fTest0Pro2D[0][0][AFO_CENTRALITY_PT]->GetYaxis()->GetTitle()); // ordering in enum eAsFunctionOf is not the same as in TString fResultsProXaxisTitle[eAsFunctionOf_N] + } + + // 3D: + if (t0.fTest0Pro3D[0][0][AFO_CENTRALITY_PT_ETA] && !(TString(t0.fTest0Pro3D[0][0][AFO_CENTRALITY_PT_ETA]->GetXaxis()->GetTitle()).Contains("centrality", TString::kIgnoreCase) && TString(t0.fTest0Pro3D[0][0][AFO_CENTRALITY_PT_ETA]->GetYaxis()->GetTitle()).EqualTo("p_{T}") && TString(t0.fTest0Pro3D[0][0][AFO_CENTRALITY_PT_ETA]->GetZaxis()->GetTitle()).EqualTo("#eta"))) { + LOGF(fatal, "\033[1;31m%s at line %d : x-axis title = %s, y-axis title = %s, z-axis title = %s\033[0m", __FUNCTION__, __LINE__, t0.fTest0Pro3D[0][0][AFO_CENTRALITY_PT_ETA]->GetXaxis()->GetTitle(), t0.fTest0Pro3D[0][0][AFO_CENTRALITY_PT_ETA]->GetYaxis()->GetTitle(), t0.fTest0Pro3D[0][0][AFO_CENTRALITY_PT_ETA]->GetZaxis()->GetTitle()); // ordering in enum eAsFunctionOf is not the same as in TString fResultsProXaxisTitle[eAsFunctionOf_N] + } + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // void bookTest0Histograms() + + //============================================================ + + void bookEtaSeparationsHistograms() + { + // Book all eta separations histograms. + + // a) Book the profile holding flags; + // b) Book what needs to be booked; + // c) Few quick insanity checks on booking. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // a) Book the profile holding flags: + es.fEtaSeparationsFlagsPro = new TProfile("fEtaSeparationsFlagsPro", "flags for eta separations", 1, 0., 1.); + es.fEtaSeparationsFlagsPro->SetStats(false); + es.fEtaSeparationsFlagsPro->SetLineColor(eColor); + es.fEtaSeparationsFlagsPro->SetFillColor(eFillColor); + es.fEtaSeparationsFlagsPro->GetXaxis()->SetLabelSize(0.04); + + if (tc.fUseSetBinLabel) { + es.fEtaSeparationsFlagsPro->GetXaxis()->SetBinLabel(1, "fCalculateEtaSeparations"); + + // ... + } else { + // Workaround for SetBinLabel() large memory consumption: + TString yAxisTitle = ""; + + yAxisTitle += TString::Format("%d:fCalculateEtaSeparations; ", 1); + es.fEtaSeparationsFlagsPro->Fill(0.5, static_cast(es.fCalculateEtaSeparations)); + + // ... + + // *) Insanity check on the number of fields in this specially crafted y-axis title: + TObjArray* oa = yAxisTitle.Tokenize(";"); + if (!oa) { + LOGF(fatal, "\033[1;31m%s at line %d : oa is NULL\033[0m", __FUNCTION__, __LINE__); + } + if (oa->GetEntries() - 1 != es.fEtaSeparationsFlagsPro->GetNbinsX()) { + LOGF(fatal, "\033[1;31m%s at line %d : oa->GetEntries() - 1 = %d != es.fEtaSeparationsFlagsPro->GetNbinsX() = %d\033[0m", __FUNCTION__, __LINE__, oa->GetEntries(), es.fEtaSeparationsFlagsPro->GetNbinsX()); + } + + // *) Okay, set the title: + es.fEtaSeparationsFlagsPro->GetYaxis()->SetTitle(yAxisTitle.Data()); + + // ... + + } // else + + es.fEtaSeparationsFlagsPro->Fill(0.5, es.fCalculateEtaSeparations); + es.fEtaSeparationsList->Add(es.fEtaSeparationsFlagsPro); + + if (!es.fCalculateEtaSeparations) { + return; + } + + // b) Book what needs to be booked: + for (int h = 0; h < gMaxHarmonic; h++) { + if (es.fEtaSeparationsSkipHarmonics[h]) { + continue; + } + for (int e = 0; e < gMaxNumberEtaSeparations; e++) { + for (int v = 0; v < eAsFunctionOf_N; v++) { + + // decide what is booked, then later valid pointer to es.fEtaSeparationsPro[h][e][v] is used as a boolean, in the standard way: + if (!es.fCalculateEtaSeparationsAsFunctionOf[v]) { + continue; + } + + if (!res.fResultsPro[v]) { + LOGF(fatal, "\033[1;31m%s at line %d : fResultsPro[%d] is NULL, this shall never happen, but apparently it happened... \033[0m", __FUNCTION__, __LINE__, v); + } + + if (tc.fUseClone) { + es.fEtaSeparationsPro[h][e][v] = reinterpret_cast(res.fResultsPro[v]->Clone(Form("fEtaSeparationsPro[%d][%d][%s]", h, e, res.fResultsProRawName[v].Data()))); // yes + } else { + es.fEtaSeparationsPro[h][e][v] = new TProfile(Form("fEtaSeparationsPro[%d][%d][%s]", h, e, res.fResultsProRawName[v].Data()), "", res.fResultsPro[v]->GetXaxis()->GetXbins()->GetSize() - 1, res.fResultsPro[v]->GetXaxis()->GetXbins()->GetArray()); + } + + es.fEtaSeparationsPro[h][e][v]->SetStats(false); + es.fEtaSeparationsPro[h][e][v]->Sumw2(); + es.fEtaSeparationsPro[h][e][v]->SetTitle(Form("%d -%d, |#Delta#eta| > %.2f", h + 1, h + 1, es.fEtaSeparationsValues[e])); + es.fEtaSeparationsPro[h][e][v]->GetXaxis()->SetTitle(FancyFormatting(res.fResultsProXaxisTitle[v].Data())); + es.fEtaSeparationsList->Add(es.fEtaSeparationsPro[h][e][v]); // yes, this has to be here + } // for(int v=0;vGetXaxis()->GetTitle()).EqualTo("integrated")) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); // ordering in enum eAsFunctionOf is not the same as in TString fResultsProXaxisTitle[eAsFunctionOf_N] + } + if (es.fEtaSeparationsPro[0][0][AFO_PT] && !TString(es.fEtaSeparationsPro[0][0][AFO_PT]->GetXaxis()->GetTitle()).EqualTo("p_{T}")) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); // ordering in enum eAsFunctionOf is not the same as in TString fResultsProXaxisTitle[eAsFunctionOf_N] + } + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // void bookEtaSeparationsHistograms() + + //============================================================ + + void bookResultsHistograms() + { + // Book all results histograms. + // These results histograms in addition act as a sort of "abstract" interface, which defines common binning, etc., for other groups of histograms. + + // a) Book the profile holding flags; + // b) Book (and optionaly save) results histograms 1D; + // c) Book (and optionaly save) results histograms 2D; + // d) Book (and optionaly save) results histograms 3D. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // a) Book the profile holding flags: + res.fResultsFlagsPro = new TProfile("fResultsFlagsPro", "flags for results histograms", 1, 0., 1.); + res.fResultsFlagsPro->SetStats(false); + res.fResultsFlagsPro->SetLineColor(eColor); + res.fResultsFlagsPro->SetFillColor(eFillColor); + + if (tc.fUseSetBinLabel) { + res.fResultsFlagsPro->GetXaxis()->SetBinLabel(1, "fSaveResultsHistograms"); + res.fResultsFlagsPro->Fill(0.5, res.fSaveResultsHistograms); + + // ... + + } else { + // Workaround for SetBinLabel() large memory consumption: + TString yAxisTitle = ""; + + yAxisTitle += TString::Format("%d:fSaveResultsHistograms; ", 1); + res.fResultsFlagsPro->Fill(0.5, static_cast(res.fSaveResultsHistograms)); + + // ... + + // *) Insanity check on the number of fields in this specially crafted y-axis title: + TObjArray* oa = yAxisTitle.Tokenize(";"); + if (!oa) { + LOGF(fatal, "\033[1;31m%s at line %d : oa is NULL\033[0m", __FUNCTION__, __LINE__); + } + if (oa->GetEntries() - 1 != res.fResultsFlagsPro->GetNbinsX()) { + LOGF(fatal, "\033[1;31m%s at line %d : oa->GetEntries() = %d != res.fResultsFlagsPro->GetNbinsX() = %d\033[0m", __FUNCTION__, __LINE__, oa->GetEntries(), res.fResultsFlagsPro->GetNbinsX()); + } + delete oa; + + // *) Okay, set the title: + res.fResultsFlagsPro->GetYaxis()->SetTitle(yAxisTitle.Data()); + } + res.fResultsList->Add(res.fResultsFlagsPro); + + // b) Book (and optionaly save) results histograms 1D: + for (int v = 0; v < eAsFunctionOf_N; v++) { + + // TBI 20250518 I book 1D case always for the time being, because I also use their binning to book particle sparse histograms. + // There should not be any big memory penalty for 1D case + // if (!(tc.fCalculateAsFunctionOf[v])) { + // // TBI 20250518 do I need here also some check for the nested loops? + // continue; + // } + + res.fResultsPro[v] = new TProfile(Form("fResultsPro[%s]", res.fResultsProRawName[v].Data()), "...", res.fResultsProBinEdges[v]->GetSize() - 1, res.fResultsProBinEdges[v]->GetArray()); + res.fResultsPro[v]->GetXaxis()->SetTitle(res.fResultsProXaxisTitle[v].Data()); + res.fResultsPro[v]->SetStats(false); + + delete res.fResultsProBinEdges[v]; // yes, it served the purpose. Now this info is carried permanently with res.fResultsPro[v], and I can always retrieve it later with e.g. + // res.fResultsPro[AFO_PT]->GetXaxis()->GetXbins() (which gives pointer to TArrayD, yes I need double, because TProfile ctor takes double) + + // Optionally, save these histograms - I need this mostly to check/validate the binning. + if (res.fSaveResultsHistograms) { + res.fResultsList->Add(res.fResultsPro[v]); + } + } // for (int v = 0; v < eAsFunctionOf_N; v++) + + // c) Book (and optionaly save) results histograms 2D: + // Remark 1: Here I cannot loop, because for each axis I re-use binning from 1D cases. + // Remark 2: I have deleted above res.fResultsProBinEdges[...], that info is now only in the axis of res.fResultsPro[...] + if (t0.fCalculate2DTest0AsFunctionOf[AFO_CENTRALITY_PT]) { + TString rawName = TString::Format("%s_%s", res.fResultsProRawName[AFO_CENTRALITY].Data(), res.fResultsProRawName[AFO_PT].Data()); // raw name is e.g. "[cent_pt]" in the file + res.fResultsPro2D[AFO_CENTRALITY_PT] = new TProfile2D(Form("fResultsPro2D[%s]", rawName.Data()), "...", + res.fResultsPro[AFO_CENTRALITY]->GetXaxis()->GetXbins()->GetSize() - 1, res.fResultsPro[AFO_CENTRALITY]->GetXaxis()->GetXbins()->GetArray(), + res.fResultsPro[AFO_PT]->GetXaxis()->GetXbins()->GetSize() - 1, res.fResultsPro[AFO_PT]->GetXaxis()->GetXbins()->GetArray()); + res.fResultsPro2D[AFO_CENTRALITY_PT]->GetXaxis()->SetTitle(res.fResultsPro[AFO_CENTRALITY]->GetXaxis()->GetTitle()); + res.fResultsPro2D[AFO_CENTRALITY_PT]->GetYaxis()->SetTitle(res.fResultsPro[AFO_PT]->GetXaxis()->GetTitle()); + res.fResultsPro2D[AFO_CENTRALITY_PT]->SetStats(false); + } + + if (t0.fCalculate2DTest0AsFunctionOf[AFO_CENTRALITY_ETA]) { + TString rawName = TString::Format("%s_%s", res.fResultsProRawName[AFO_CENTRALITY].Data(), res.fResultsProRawName[AFO_ETA].Data()); + res.fResultsPro2D[AFO_CENTRALITY_ETA] = new TProfile2D(Form("fResultsPro2D[%s]", rawName.Data()), "...", + res.fResultsPro[AFO_CENTRALITY]->GetXaxis()->GetXbins()->GetSize() - 1, res.fResultsPro[AFO_CENTRALITY]->GetXaxis()->GetXbins()->GetArray(), + res.fResultsPro[AFO_ETA]->GetXaxis()->GetXbins()->GetSize() - 1, res.fResultsPro[AFO_ETA]->GetXaxis()->GetXbins()->GetArray()); + res.fResultsPro2D[AFO_CENTRALITY_ETA]->GetXaxis()->SetTitle(res.fResultsPro[AFO_CENTRALITY]->GetXaxis()->GetTitle()); + res.fResultsPro2D[AFO_CENTRALITY_ETA]->GetYaxis()->SetTitle(res.fResultsPro[AFO_ETA]->GetXaxis()->GetTitle()); + res.fResultsPro2D[AFO_CENTRALITY_ETA]->SetStats(false); + } + + if (t0.fCalculate2DTest0AsFunctionOf[AFO_CENTRALITY_CHARGE]) { + TString rawName = TString::Format("%s_%s", res.fResultsProRawName[AFO_CENTRALITY].Data(), res.fResultsProRawName[AFO_CHARGE].Data()); + res.fResultsPro2D[AFO_CENTRALITY_CHARGE] = new TProfile2D(Form("fResultsPro2D[%s]", rawName.Data()), "...", + res.fResultsPro[AFO_CENTRALITY]->GetXaxis()->GetXbins()->GetSize() - 1, res.fResultsPro[AFO_CENTRALITY]->GetXaxis()->GetXbins()->GetArray(), + res.fResultsPro[AFO_CHARGE]->GetXaxis()->GetXbins()->GetSize() - 1, res.fResultsPro[AFO_CHARGE]->GetXaxis()->GetXbins()->GetArray()); + + res.fResultsPro2D[AFO_CENTRALITY_CHARGE]->GetXaxis()->SetTitle(res.fResultsPro[AFO_CENTRALITY]->GetXaxis()->GetTitle()); + res.fResultsPro2D[AFO_CENTRALITY_CHARGE]->GetYaxis()->SetTitle(res.fResultsPro[AFO_CHARGE]->GetXaxis()->GetTitle()); + res.fResultsPro2D[AFO_CENTRALITY_CHARGE]->SetStats(false); + } + + if (t0.fCalculate2DTest0AsFunctionOf[AFO_CENTRALITY_VZ]) { + TString rawName = TString::Format("%s_%s", res.fResultsProRawName[AFO_CENTRALITY].Data(), res.fResultsProRawName[AFO_VZ].Data()); + res.fResultsPro2D[AFO_CENTRALITY_VZ] = new TProfile2D(Form("fResultsPro2D[%s]", rawName.Data()), "...", + res.fResultsPro[AFO_CENTRALITY]->GetXaxis()->GetXbins()->GetSize() - 1, res.fResultsPro[AFO_CENTRALITY]->GetXaxis()->GetXbins()->GetArray(), + res.fResultsPro[AFO_VZ]->GetXaxis()->GetXbins()->GetSize() - 1, res.fResultsPro[AFO_VZ]->GetXaxis()->GetXbins()->GetArray()); + res.fResultsPro2D[AFO_CENTRALITY_VZ]->GetXaxis()->SetTitle(res.fResultsPro[AFO_CENTRALITY]->GetXaxis()->GetTitle()); + res.fResultsPro2D[AFO_CENTRALITY_VZ]->GetYaxis()->SetTitle(res.fResultsPro[AFO_VZ]->GetXaxis()->GetTitle()); + res.fResultsPro2D[AFO_CENTRALITY_VZ]->SetStats(false); + } + + if (t0.fCalculate2DTest0AsFunctionOf[AFO_PT_ETA]) { + TString rawName = TString::Format("%s_%s", res.fResultsProRawName[AFO_PT].Data(), res.fResultsProRawName[AFO_ETA].Data()); + res.fResultsPro2D[AFO_PT_ETA] = new TProfile2D(Form("fResultsPro2D[%s]", rawName.Data()), "...", + res.fResultsPro[AFO_PT]->GetXaxis()->GetXbins()->GetSize() - 1, res.fResultsPro[AFO_PT]->GetXaxis()->GetXbins()->GetArray(), + res.fResultsPro[AFO_ETA]->GetXaxis()->GetXbins()->GetSize() - 1, res.fResultsPro[AFO_ETA]->GetXaxis()->GetXbins()->GetArray()); + res.fResultsPro2D[AFO_PT_ETA]->GetXaxis()->SetTitle(res.fResultsPro[AFO_PT]->GetXaxis()->GetTitle()); + res.fResultsPro2D[AFO_PT_ETA]->GetYaxis()->SetTitle(res.fResultsPro[AFO_ETA]->GetXaxis()->GetTitle()); + res.fResultsPro2D[AFO_PT_ETA]->SetStats(false); + } + + if (t0.fCalculate2DTest0AsFunctionOf[AFO_PT_CHARGE]) { + TString rawName = TString::Format("%s_%s", res.fResultsProRawName[AFO_PT].Data(), res.fResultsProRawName[AFO_CHARGE].Data()); + res.fResultsPro2D[AFO_PT_CHARGE] = new TProfile2D(Form("fResultsPro2D[%s]", rawName.Data()), "...", + res.fResultsPro[AFO_PT]->GetXaxis()->GetXbins()->GetSize() - 1, res.fResultsPro[AFO_PT]->GetXaxis()->GetXbins()->GetArray(), + res.fResultsPro[AFO_CHARGE]->GetXaxis()->GetXbins()->GetSize() - 1, res.fResultsPro[AFO_CHARGE]->GetXaxis()->GetXbins()->GetArray()); + res.fResultsPro2D[AFO_PT_CHARGE]->GetXaxis()->SetTitle(res.fResultsPro[AFO_PT]->GetXaxis()->GetTitle()); + res.fResultsPro2D[AFO_PT_CHARGE]->GetYaxis()->SetTitle(res.fResultsPro[AFO_CHARGE]->GetXaxis()->GetTitle()); + res.fResultsPro2D[AFO_PT_CHARGE]->SetStats(false); + } + + if (t0.fCalculate2DTest0AsFunctionOf[AFO_ETA_CHARGE]) { + TString rawName = TString::Format("%s_%s", res.fResultsProRawName[AFO_ETA].Data(), res.fResultsProRawName[AFO_CHARGE].Data()); + res.fResultsPro2D[AFO_ETA_CHARGE] = new TProfile2D(Form("fResultsPro2D[%s]", rawName.Data()), "...", + res.fResultsPro[AFO_ETA]->GetXaxis()->GetXbins()->GetSize() - 1, res.fResultsPro[AFO_ETA]->GetXaxis()->GetXbins()->GetArray(), + res.fResultsPro[AFO_CHARGE]->GetXaxis()->GetXbins()->GetSize() - 1, res.fResultsPro[AFO_CHARGE]->GetXaxis()->GetXbins()->GetArray()); + res.fResultsPro2D[AFO_ETA_CHARGE]->GetXaxis()->SetTitle(res.fResultsPro[AFO_ETA]->GetXaxis()->GetTitle()); + res.fResultsPro2D[AFO_ETA_CHARGE]->GetYaxis()->SetTitle(res.fResultsPro[AFO_CHARGE]->GetXaxis()->GetTitle()); + res.fResultsPro2D[AFO_ETA_CHARGE]->SetStats(false); + } + + // ... + + // Optionally, save 2D results histograms - I need this mostly to check/validate the binning: + for (int v = 0; v < eAsFunctionOf2D_N; v++) { + if (res.fSaveResultsHistograms && res.fResultsPro2D[v]) { + res.fResultsList->Add(res.fResultsPro2D[v]); + } + } + + // d) Book (and optionaly save) results histograms 3D: + // Remark 1: Here I cannot loop, because for each axis I re-use binning from 1D cases. + // Remark 2: I have deleted above res.fResultsProBinEdges[...], that info is now only in the axis of res.fResultsPro[...] + if (t0.fCalculate3DTest0AsFunctionOf[AFO_CENTRALITY_PT_ETA]) { + TString rawName = TString::Format("%s_%s_%s", res.fResultsProRawName[AFO_CENTRALITY].Data(), res.fResultsProRawName[AFO_PT].Data(), res.fResultsProRawName[AFO_ETA].Data()); + res.fResultsPro3D[AFO_CENTRALITY_PT_ETA] = new TProfile3D(Form("fResultsPro3D[%s]", rawName.Data()), "...", + res.fResultsPro[AFO_CENTRALITY]->GetXaxis()->GetXbins()->GetSize() - 1, res.fResultsPro[AFO_CENTRALITY]->GetXaxis()->GetXbins()->GetArray(), + res.fResultsPro[AFO_PT]->GetXaxis()->GetXbins()->GetSize() - 1, res.fResultsPro[AFO_PT]->GetXaxis()->GetXbins()->GetArray(), + res.fResultsPro[AFO_ETA]->GetXaxis()->GetXbins()->GetSize() - 1, res.fResultsPro[AFO_ETA]->GetXaxis()->GetXbins()->GetArray()); + res.fResultsPro3D[AFO_CENTRALITY_PT_ETA]->GetXaxis()->SetTitle(res.fResultsPro[AFO_CENTRALITY]->GetXaxis()->GetTitle()); + res.fResultsPro3D[AFO_CENTRALITY_PT_ETA]->GetYaxis()->SetTitle(res.fResultsPro[AFO_PT]->GetXaxis()->GetTitle()); + res.fResultsPro3D[AFO_CENTRALITY_PT_ETA]->GetZaxis()->SetTitle(res.fResultsPro[AFO_ETA]->GetXaxis()->GetTitle()); + res.fResultsPro3D[AFO_CENTRALITY_PT_ETA]->SetStats(false); + } + + if (t0.fCalculate3DTest0AsFunctionOf[AFO_CENTRALITY_PT_CHARGE]) { + TString rawName = TString::Format("%s_%s_%s", res.fResultsProRawName[AFO_CENTRALITY].Data(), res.fResultsProRawName[AFO_PT].Data(), res.fResultsProRawName[AFO_CHARGE].Data()); + res.fResultsPro3D[AFO_CENTRALITY_PT_CHARGE] = new TProfile3D(Form("fResultsPro3D[%s]", rawName.Data()), "...", + res.fResultsPro[AFO_CENTRALITY]->GetXaxis()->GetXbins()->GetSize() - 1, res.fResultsPro[AFO_CENTRALITY]->GetXaxis()->GetXbins()->GetArray(), + res.fResultsPro[AFO_PT]->GetXaxis()->GetXbins()->GetSize() - 1, res.fResultsPro[AFO_PT]->GetXaxis()->GetXbins()->GetArray(), + res.fResultsPro[AFO_CHARGE]->GetXaxis()->GetXbins()->GetSize() - 1, res.fResultsPro[AFO_CHARGE]->GetXaxis()->GetXbins()->GetArray()); + res.fResultsPro3D[AFO_CENTRALITY_PT_CHARGE]->GetXaxis()->SetTitle(res.fResultsPro[AFO_CENTRALITY]->GetXaxis()->GetTitle()); + res.fResultsPro3D[AFO_CENTRALITY_PT_CHARGE]->GetYaxis()->SetTitle(res.fResultsPro[AFO_PT]->GetXaxis()->GetTitle()); + res.fResultsPro3D[AFO_CENTRALITY_PT_CHARGE]->GetZaxis()->SetTitle(res.fResultsPro[AFO_CHARGE]->GetXaxis()->GetTitle()); + res.fResultsPro3D[AFO_CENTRALITY_PT_CHARGE]->SetStats(false); + } + + if (t0.fCalculate3DTest0AsFunctionOf[AFO_CENTRALITY_PT_VZ]) { + TString rawName = TString::Format("%s_%s_%s", res.fResultsProRawName[AFO_CENTRALITY].Data(), res.fResultsProRawName[AFO_PT].Data(), res.fResultsProRawName[AFO_VZ].Data()); + res.fResultsPro3D[AFO_CENTRALITY_PT_VZ] = new TProfile3D(Form("fResultsPro3D[%s]", rawName.Data()), "...", + res.fResultsPro[AFO_CENTRALITY]->GetXaxis()->GetXbins()->GetSize() - 1, res.fResultsPro[AFO_CENTRALITY]->GetXaxis()->GetXbins()->GetArray(), + res.fResultsPro[AFO_PT]->GetXaxis()->GetXbins()->GetSize() - 1, res.fResultsPro[AFO_PT]->GetXaxis()->GetXbins()->GetArray(), + res.fResultsPro[AFO_VZ]->GetXaxis()->GetXbins()->GetSize() - 1, res.fResultsPro[AFO_VZ]->GetXaxis()->GetXbins()->GetArray()); + res.fResultsPro3D[AFO_CENTRALITY_PT_VZ]->GetXaxis()->SetTitle(res.fResultsPro[AFO_CENTRALITY]->GetXaxis()->GetTitle()); + res.fResultsPro3D[AFO_CENTRALITY_PT_VZ]->GetYaxis()->SetTitle(res.fResultsPro[AFO_PT]->GetXaxis()->GetTitle()); + res.fResultsPro3D[AFO_CENTRALITY_PT_VZ]->GetZaxis()->SetTitle(res.fResultsPro[AFO_VZ]->GetXaxis()->GetTitle()); + res.fResultsPro3D[AFO_CENTRALITY_PT_VZ]->SetStats(false); + } + + if (t0.fCalculate3DTest0AsFunctionOf[AFO_CENTRALITY_ETA_VZ]) { + TString rawName = TString::Format("%s_%s_%s", res.fResultsProRawName[AFO_CENTRALITY].Data(), res.fResultsProRawName[AFO_ETA].Data(), res.fResultsProRawName[AFO_VZ].Data()); + res.fResultsPro3D[AFO_CENTRALITY_ETA_VZ] = new TProfile3D(Form("fResultsPro3D[%s]", rawName.Data()), "...", + res.fResultsPro[AFO_CENTRALITY]->GetXaxis()->GetXbins()->GetSize() - 1, res.fResultsPro[AFO_CENTRALITY]->GetXaxis()->GetXbins()->GetArray(), + res.fResultsPro[AFO_ETA]->GetXaxis()->GetXbins()->GetSize() - 1, res.fResultsPro[AFO_ETA]->GetXaxis()->GetXbins()->GetArray(), + res.fResultsPro[AFO_VZ]->GetXaxis()->GetXbins()->GetSize() - 1, res.fResultsPro[AFO_VZ]->GetXaxis()->GetXbins()->GetArray()); + res.fResultsPro3D[AFO_CENTRALITY_ETA_VZ]->GetXaxis()->SetTitle(res.fResultsPro[AFO_CENTRALITY]->GetXaxis()->GetTitle()); + res.fResultsPro3D[AFO_CENTRALITY_ETA_VZ]->GetYaxis()->SetTitle(res.fResultsPro[AFO_ETA]->GetXaxis()->GetTitle()); + res.fResultsPro3D[AFO_CENTRALITY_ETA_VZ]->GetZaxis()->SetTitle(res.fResultsPro[AFO_VZ]->GetXaxis()->GetTitle()); + res.fResultsPro3D[AFO_CENTRALITY_ETA_VZ]->SetStats(false); + } + + if (t0.fCalculate3DTest0AsFunctionOf[AFO_CENTRALITY_ETA_CHARGE]) { + TString rawName = TString::Format("%s_%s_%s", res.fResultsProRawName[AFO_CENTRALITY].Data(), res.fResultsProRawName[AFO_ETA].Data(), res.fResultsProRawName[AFO_CHARGE].Data()); + res.fResultsPro3D[AFO_CENTRALITY_ETA_CHARGE] = new TProfile3D(Form("fResultsPro3D[%s]", rawName.Data()), "...", + res.fResultsPro[AFO_CENTRALITY]->GetXaxis()->GetXbins()->GetSize() - 1, res.fResultsPro[AFO_CENTRALITY]->GetXaxis()->GetXbins()->GetArray(), + res.fResultsPro[AFO_ETA]->GetXaxis()->GetXbins()->GetSize() - 1, res.fResultsPro[AFO_ETA]->GetXaxis()->GetXbins()->GetArray(), + res.fResultsPro[AFO_CHARGE]->GetXaxis()->GetXbins()->GetSize() - 1, res.fResultsPro[AFO_CHARGE]->GetXaxis()->GetXbins()->GetArray()); + res.fResultsPro3D[AFO_CENTRALITY_ETA_CHARGE]->GetXaxis()->SetTitle(res.fResultsPro[AFO_CENTRALITY]->GetXaxis()->GetTitle()); + res.fResultsPro3D[AFO_CENTRALITY_ETA_CHARGE]->GetYaxis()->SetTitle(res.fResultsPro[AFO_ETA]->GetXaxis()->GetTitle()); + res.fResultsPro3D[AFO_CENTRALITY_ETA_CHARGE]->GetZaxis()->SetTitle(res.fResultsPro[AFO_CHARGE]->GetXaxis()->GetTitle()); + res.fResultsPro3D[AFO_CENTRALITY_ETA_CHARGE]->SetStats(false); + } + + if (t0.fCalculate3DTest0AsFunctionOf[AFO_CENTRALITY_VZ_CHARGE]) { + TString rawName = TString::Format("%s_%s_%s", res.fResultsProRawName[AFO_CENTRALITY].Data(), res.fResultsProRawName[AFO_VZ].Data(), res.fResultsProRawName[AFO_CHARGE].Data()); + res.fResultsPro3D[AFO_CENTRALITY_VZ_CHARGE] = new TProfile3D(Form("fResultsPro3D[%s]", rawName.Data()), "...", + res.fResultsPro[AFO_CENTRALITY]->GetXaxis()->GetXbins()->GetSize() - 1, res.fResultsPro[AFO_CENTRALITY]->GetXaxis()->GetXbins()->GetArray(), + res.fResultsPro[AFO_VZ]->GetXaxis()->GetXbins()->GetSize() - 1, res.fResultsPro[AFO_VZ]->GetXaxis()->GetXbins()->GetArray(), + res.fResultsPro[AFO_CHARGE]->GetXaxis()->GetXbins()->GetSize() - 1, res.fResultsPro[AFO_CHARGE]->GetXaxis()->GetXbins()->GetArray()); + res.fResultsPro3D[AFO_CENTRALITY_VZ_CHARGE]->GetXaxis()->SetTitle(res.fResultsPro[AFO_CENTRALITY]->GetXaxis()->GetTitle()); + res.fResultsPro3D[AFO_CENTRALITY_VZ_CHARGE]->GetYaxis()->SetTitle(res.fResultsPro[AFO_VZ]->GetXaxis()->GetTitle()); + res.fResultsPro3D[AFO_CENTRALITY_VZ_CHARGE]->GetZaxis()->SetTitle(res.fResultsPro[AFO_CHARGE]->GetXaxis()->GetTitle()); + res.fResultsPro3D[AFO_CENTRALITY_VZ_CHARGE]->SetStats(false); + } + + if (t0.fCalculate3DTest0AsFunctionOf[AFO_PT_ETA_CHARGE]) { + TString rawName = TString::Format("%s_%s_%s", res.fResultsProRawName[AFO_PT].Data(), res.fResultsProRawName[AFO_ETA].Data(), res.fResultsProRawName[AFO_CHARGE].Data()); + res.fResultsPro3D[AFO_PT_ETA_CHARGE] = new TProfile3D(Form("fResultsPro3D[%s]", rawName.Data()), "...", + res.fResultsPro[AFO_PT]->GetXaxis()->GetXbins()->GetSize() - 1, res.fResultsPro[AFO_PT]->GetXaxis()->GetXbins()->GetArray(), + res.fResultsPro[AFO_ETA]->GetXaxis()->GetXbins()->GetSize() - 1, res.fResultsPro[AFO_ETA]->GetXaxis()->GetXbins()->GetArray(), + res.fResultsPro[AFO_CHARGE]->GetXaxis()->GetXbins()->GetSize() - 1, res.fResultsPro[AFO_CHARGE]->GetXaxis()->GetXbins()->GetArray()); + res.fResultsPro3D[AFO_PT_ETA_CHARGE]->GetXaxis()->SetTitle(res.fResultsPro[AFO_PT]->GetXaxis()->GetTitle()); + res.fResultsPro3D[AFO_PT_ETA_CHARGE]->GetYaxis()->SetTitle(res.fResultsPro[AFO_ETA]->GetXaxis()->GetTitle()); + res.fResultsPro3D[AFO_PT_ETA_CHARGE]->GetZaxis()->SetTitle(res.fResultsPro[AFO_CHARGE]->GetXaxis()->GetTitle()); + res.fResultsPro3D[AFO_PT_ETA_CHARGE]->SetStats(false); + } + + // Optionally, save 3D results histograms - I need this mostly to check/validate the binning: + for (int v = 0; v < eAsFunctionOf3D_N; v++) { + + if (res.fSaveResultsHistograms && res.fResultsPro3D[v]) { + res.fResultsList->Add(res.fResultsPro3D[v]); + } + } + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // void bookResultsHistograms() + + //============================================================ + + TArrayD* ArrayWithBinEdges(int nBins, float min, float max) + { + // Helper function to determine concrete bin edges, when the fixed-size binning was specified with nBins in (min, max). + + // a) Insanity checks on arguments; + // b) Okay, do the thing. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // a) Insanity check on arguments: + if (nBins <= 0 || max < min || std::abs(max - min) < tc.fFloatingPointPrecision) { + LOGF(fatal, "\033[1;31m%s at line %d : Insane arguments for fixed-length binning: nBins = %d , min = %f, max = %f \033[0m", __FUNCTION__, __LINE__, nBins, min, max); + } + + // b) Okay, do the thing: + float binWidth = (max - min) / (1. * nBins); + + TArrayD* binEdges = new TArrayD(nBins + 1); + for (int b = 1; b <= nBins + 1; b++) { + binEdges->AddAt(min + (b - 1) * binWidth, b - 1); + } + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + return binEdges; + + } // TArrayD *ArrayWithBinEdges(int nBins, float min, float max) + + //============================================================ + + void bookTheRest() + { + // Here I book everything not sorted (yes) in specific functions above. + + // a) Book the timer; + // b) Book TDatabasePDG; + // *) ... + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // a) Book the timer: + if (tc.fUseStopwatch) { + tc.fTimer[eGlobal] = new TStopwatch(); + tc.fTimer[eGlobal]->Start(); + tc.fTimer[eLocal] = new TStopwatch(); + } + + // b) Book TDatabasePDG: + if (tc.fUseDatabasePDG) { + tc.fDatabasePDG = new TDatabasePDG(); // there is a standard memory blow-up here + } + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // void bookTheRest() + + //============================================================ + + template + void Preprocess(T1 const& collision, T2 const& bcs) + { + // Do all thingies before starting to process data (e.g. count number of events, fetch the run number, get the weights for this run number, etc.). + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // *) Determine all event counters: + DetermineEventCounters(); + + // *) Sequential bailout: After each tc.fSequentialBailout events, I bail out: + if (tc.fSequentialBailout > 0 && eh.fEventCounter[eProcessed] > 0 && 0 == eh.fEventCounter[eProcessed] % tc.fSequentialBailout) { + BailOut(); + } + + // *) If I reached max number of events, ignore the remaining collisions: + if (MaxNumberOfEvents(eAfter) || MaxNumberOfEvents(eBefore)) { // TBI 20240510 this is a bit confusing, implemented this way. Shall I split off? + BailOut(true); + } + + // *) Determine and propagate run number info to already booked objects: + if (!tc.fRunNumberIsDetermined) { + DetermineRunNumber(collision, bcs); + PropagateRunNumber(); + } + + if (tc.fDoAdditionalInsanityChecks && tc.fRunNumberIsDetermined) { + CheckCurrentRunNumber(collision, bcs); + } + + // *) Check whether this run shall be skipped later from further processing in Steer(): + if (!tc.fSkipTheseRuns.EqualTo("")) { + // If tc.fSkipTheseRuns is not empty, that means it holds comma-separated list of runs to be skipped. Let's check it out... + SkipThisRun(); // I set inside the data member tc.fSkipRun , which serves then as a switch later all over the place + if (tc.fSkipRun) { + return; // yes, I bail out immediately from Preprocess, so that I do not waste time on fetching weights for this run + } + // TBI 20250316 Same comment here: At the moment I can access run number info only in process(...), but not in init(...) + // Once I can access run number info in init(...), this function shall be called in init(...), not in process(...) + } // if (!tc.fSkipTheseRuns.EqualTo("")) + + // *) Fetch the weights for this particular run number. Do it only once. + // TBI 20231012 If eventualy I can access programatically run number in init(...) at run time, this shall go there. + if (!pw.fParticleWeightsAreFetched) { + + // integrated weights and differentials weights without sparse histograms (the latter is becoming obsolete): + if (pw.fUseWeights[wPHI] || pw.fUseWeights[wPT] || pw.fUseWeights[wETA] || pw.fUseDiffWeights[wPHIPT] || pw.fUseDiffWeights[wPHIETA]) { + GetParticleWeights(); + pw.fParticleWeightsAreFetched = true; + } + + // differential particle weights using sparse histograms: + if (pw.fUseDiffPhiWeights[wPhiPhiAxis] || pw.fUseDiffPtWeights[wPtPtAxis] || pw.fUseDiffPtWeights[wEtaEtaAxis]) { + // Yes, I check only the first flag. This way, I can e.g. switch off all differential phi weights by setting 0-wPhi in config. + // On the other hand, it doesn't make sense to calculate differential phi weights without having phi axis. + // At any point I shall be able to fall back e.g. to integrated phi weights, that corresponds to the case wheh "1-wPhi" and all others are "0-w..." + // Same for differential pt or eta weights. + GetParticleWeights(); + pw.fParticleWeightsAreFetched = true; + } + + } // if (!pw.fParticleWeightsAreFetched) { + + // *) Fetch the centrality weights for this particular run number. Do it only once. + // TBI 20231012 If eventualy I can access programatically run number in init(...) at run time, this shall go there. + if (!cw.fCentralityWeightsAreFetched) { + if (cw.fUseCentralityWeights) { + GetCentralityWeights(); + cw.fCentralityWeightsAreFetched = true; + } + } + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // template void Preprocess(T1 const& collision, T2 const& bcs) + + //============================================================ + + template + void DetermineRunNumber(T1 const& collision, T2 const&) + { + // Determine run number and all related thingies. + // Make sure in process(...) that this function is called only once. + + // TBI 20231018 At the moment I can access run number info only in process(...), but not in init(...) + // Once I can access run number info in init(...), this function shall be called in init(...), not in process(...) + + // a) Determine run number for Run 3 and Run 2 real data; + // b) Determine run number for the rest. TBI 20241126 differentiate this support as well, e.g. for eRecSim and eSim. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // a) Determine run number for Run 3 and Run 2 real data; + if constexpr (rs == eRec || rs == eRecAndSim || rs == eRec_Run2 || rs == eRecAndSim_Run2 || rs == eQA) { + + // **) Determine run number: + // Get start timestamp and end timemstamp for this run in miliseconds, and convert both of them in seconds: + // o see O2/CCDB/src/BasicCCDBManager.cxx, O2/CCDB/include/CCDB/BasicCCDBManager.h + // o example usage in O2Physics/PWGLF/TableProducer/Common/zdcSP.cxx + auto bc = collision.template foundBC_as(); // I have the same code snippet at other places, keep in sync. + tc.fRunNumber = Form("%d", bc.runNumber()); + if (tc.fRunNumber.EqualTo("")) { + LOGF(error, "\033[1;33m%fRunNumber is empty, bc.runNumber() failed...\033[0m"); + LOGF(fatal, "\033[1;31m%s at line %d : bc.runNumber() = %d \033[0m", __FUNCTION__, __LINE__, bc.runNumber()); + } + + // **) Determine SoR, EoR, and run duration: + auto runDuration = ccdb->getRunDuration(bc.runNumber()); // this is total run duration, not the current one (see below) + tc.fRunTime[eStartOfRun] = std::floor(runDuration.first * 0.001); // in seconds since Unix epoch + tc.fRunTime[eEndOfRun] = std::ceil(runDuration.second * 0.001); // in seconds since Unix epoch + tc.fRunTime[eDurationInSec] = tc.fRunTime[eEndOfRun] - tc.fRunTime[eStartOfRun]; // yes, this is now run duration in seconds + + if (!(tc.fRunTime[eStartOfRun] > 0)) { + LOGF(fatal, "\033[1;31m%s at line %d : tc.fRunTime[eStartOfRun] = %d is not positive\033[0m", __FUNCTION__, __LINE__, tc.fRunTime[eStartOfRun]); + } + if (!(tc.fRunTime[eEndOfRun] > 0)) { + LOGF(fatal, "\033[1;31m%s at line %d : tc.fRunTime[eEndOfRun] = %d is not positive\033[0m", __FUNCTION__, __LINE__, tc.fRunTime[eEndOfRun]); + } + if (!(tc.fRunTime[eDurationInSec] > 0)) { + LOGF(fatal, "\033[1;31m%s at line %d : tc.fRunTime[eDurationInSec] = %d is not positive\033[0m", __FUNCTION__, __LINE__, tc.fRunTime[eDurationInSec]); + } + + } else if constexpr (rs == eTest) { + LOGF(warning, "\033[1;33m%s at line %d : RunNumber cannot be determined for eTest mode, due to minimal subscription. Setting run number manually to some dummy value. If you do not like this, extend subscription to more tables.\033[0m", __FUNCTION__, __LINE__); + tc.fRunNumber = "123456"; + } else { + // b) Determine run number for the rest. + // TBI 20241126 differentiate this support as well, e.g. for eRecSim and eSim. + LOGF(fatal, "\033[1;31m%s at line %d : bc.runNumber() is not validated yet for this case\033[0m", __FUNCTION__, __LINE__); + } + tc.fRunNumberIsDetermined = true; + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // template void DetermineRunNumber(T1 const& collision, T2 const&) + + //============================================================ + + void PropagateRunNumber() + { + // Propagate run number info to already booked objects, wherever it's relevant. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // Do some local insanity checks: + if (tc.fRunNumber.EqualTo("")) { + LOGF(fatal, "\033[1;31m%s at line %d : tc.fRunNumber is empty \033[0m", __FUNCTION__, __LINE__); + } + + // *) base: + if (tc.fUseSetBinLabel) { + fBasePro->GetXaxis()->SetBinLabel(eRunNumber, Form("fRunNumber = %s", tc.fRunNumber.Data())); + } else { + // Workaround for SetBinLabel() large memory consumption: + TString tmp = fBasePro->GetYaxis()->GetTitle(); + fBasePro->GetYaxis()->SetTitle(tmp.ReplaceAll("__RUN_NUMBER__", tc.fRunNumber.Data())); + } // else + + // *) common title var: + TString histTitle = ""; + + // *) event cuts: + for (int rs = 0; rs < 2; rs++) // reco/sim + { + for (int cc = 0; cc < eCutCounter_N; cc++) // enum eCutCounter + { + if (!ec.fEventCutCounterHist[rs][cc]) { + continue; + } + histTitle = ec.fEventCutCounterHist[rs][cc]->GetTitle(); + if (histTitle.Contains("__RUN_NUMBER__")) { + histTitle.ReplaceAll("__RUN_NUMBER__", tc.fRunNumber.Data()); // it replaces in-place + ec.fEventCutCounterHist[rs][cc]->SetTitle(histTitle.Data()); + } + } + } + + // *) event histograms 1D: + for (int t = 0; t < eEventHistograms_N; t++) // type, see enum eEventHistograms + { + for (int rs = 0; rs < 2; rs++) // reco/sim + { + for (int ba = 0; ba < 2; ba++) // before/after cuts + { + if (!eh.fEventHistograms[t][rs][ba]) { + continue; + } + histTitle = eh.fEventHistograms[t][rs][ba]->GetTitle(); + if (histTitle.Contains("__RUN_NUMBER__")) { + histTitle.ReplaceAll("__RUN_NUMBER__", tc.fRunNumber.Data()); // it replaces in-place + eh.fEventHistograms[t][rs][ba]->SetTitle(histTitle.Data()); + } + } // for(int ba=0;ba<2;ba++) + } // for(int rs=0;rs<2;rs++) // reco/sim + } // for(int t=0;tGetTitle(); + if (histTitle.Contains("__RUN_NUMBER__")) { + histTitle.ReplaceAll("__RUN_NUMBER__", tc.fRunNumber.Data()); // it replaces in-place + qa.fQAEventHistograms2D[t][rs][ba]->SetTitle(histTitle.Data()); + } + } // for(int ba=0;ba<2;ba++) + } // for(int rs=0;rs<2;rs++) // reco/sim + } // for (int t = 0; t < eQAEventHistograms2D_N; t++) // type, see enum eEventHistograms2D + + // *) particle histograms 2D: + for (int t = 0; t < eQAParticleHistograms2D_N; t++) // type, see enum eParticleHistograms2D + { + for (int rs = 0; rs < 2; rs++) // reco/sim + { + for (int ba = 0; ba < 2; ba++) // before/after cuts + { + if (!qa.fQAParticleHistograms2D[t][rs][ba]) { + continue; + } + histTitle = qa.fQAParticleHistograms2D[t][rs][ba]->GetTitle(); + if (histTitle.Contains("__RUN_NUMBER__")) { + histTitle.ReplaceAll("__RUN_NUMBER__", tc.fRunNumber.Data()); // it replaces in-place + qa.fQAParticleHistograms2D[t][rs][ba]->SetTitle(histTitle.Data()); + } + } // for(int ba=0;ba<2;ba++) + } // for(int rs=0;rs<2;rs++) // reco/sim + } // for (int t = 0; t < eQAParticleHistograms2D_N; t++) // type, see enum eParticleHistograms2D + + // *) particle event histograms 2D: + for (int t = 0; t < eQAParticleEventHistograms2D_N; t++) // type, see enum eParticleEventHistograms2D + { + for (int rs = 0; rs < 2; rs++) // reco/sim + { + for (int ba = 0; ba < 2; ba++) // before/after cuts + { + if (!qa.fQAParticleEventHistograms2D[t][rs][ba]) { + continue; + } + histTitle = qa.fQAParticleEventHistograms2D[t][rs][ba]->GetTitle(); + if (histTitle.Contains("__RUN_NUMBER__")) { + histTitle.ReplaceAll("__RUN_NUMBER__", tc.fRunNumber.Data()); // it replaces in-place + qa.fQAParticleEventHistograms2D[t][rs][ba]->SetTitle(histTitle.Data()); + } + } // for(int ba=0;ba<2;ba++) + } // for(int rs=0;rs<2;rs++) // reco/sim + } // for (int t = 0; t < eQAParticleEventHistograms2D_N; t++) // type, see enum eParticleEventHistograms2D + + // *) particle sparse histograms: + for (int t = 0; t < eDiffWeightCategory_N; t++) // category, see enum eDiffWeightCategory + { + for (int rs = 0; rs < 2; rs++) // reco/sim + { + for (int ba = 0; ba < 2; ba++) // before/after cuts + { + if (!ph.fParticleSparseHistograms[t][rs][ba]) { + continue; + } + histTitle = ph.fParticleSparseHistograms[t][rs][ba]->GetTitle(); + if (histTitle.Contains("__RUN_NUMBER__")) { + histTitle.ReplaceAll("__RUN_NUMBER__", tc.fRunNumber.Data()); // it replaces in-place + ph.fParticleSparseHistograms[t][rs][ba]->SetTitle(histTitle.Data()); + } + } // for (int ba = 0; ba < 2; ba++) // before/after cuts + } // for(int rs=0;rs<2;rs++) // reco/sim + } // for (int t = 0; t < eDiffWeightCategory; t++) // category, see enum eDiffWeightCategory + + // *) "correlations vs." histograms 2D: + for (int t = 0; t < eQACorrelationsVsHistograms2D_N; t++) // type, see enum eCorrelationsVsHistograms2D + { + for (int h = 0; h < gMaxHarmonic; h++) { + for (int rs = 0; rs < 2; rs++) // reco/sim + { + if (!qa.fQACorrelationsVsHistograms2D[t][h][rs]) { + continue; + } + histTitle = qa.fQACorrelationsVsHistograms2D[t][h][rs]->GetTitle(); + if (histTitle.Contains("__RUN_NUMBER__")) { + histTitle.ReplaceAll("__RUN_NUMBER__", tc.fRunNumber.Data()); // it replaces in-place + qa.fQACorrelationsVsHistograms2D[t][h][rs]->SetTitle(histTitle.Data()); + } + } // for(int rs=0;rs<2;rs++) // reco/sim + } // for (int h = 0; h < gMaxHarmonic; h++) + } // for (int t = 0; t < eQACorrelationsVsHistograms2D_N; t++) // type, see enum eCorrelationsVsHistograms2D + + // *) "correlations vs. IR vs. " profiles 2D: + for (int t = 0; t < eQACorrelationsVsInteractionRateVsProfiles2D_N; t++) // type, see enum eCorrelationsVsInteractionRateVsProfiles2D + { + for (int h = 0; h < gMaxHarmonic; h++) { + for (int rs = 0; rs < 2; rs++) // reco/sim + { + if (!qa.fQACorrVsIRVsProfiles2D[t][h][rs]) { + continue; + } + histTitle = qa.fQACorrVsIRVsProfiles2D[t][h][rs]->GetTitle(); + if (histTitle.Contains("__RUN_NUMBER__")) { + histTitle.ReplaceAll("__RUN_NUMBER__", tc.fRunNumber.Data()); // it replaces in-place + qa.fQACorrVsIRVsProfiles2D[t][h][rs]->SetTitle(histTitle.Data()); + } + } // for(int rs=0;rs<2;rs++) // reco/sim + } // for (int h = 0; h < gMaxHarmonic; h++) + } // for (int t = 0; t < eQACorrelationsVsInteractionRateVsProfiles2D_N; t++) // type, see enum eCorrelationsVsInteractionRateVsProfiles2D + + // *) particle cuts: + for (int rs = 0; rs < 2; rs++) // reco/sim + { + for (int cc = 0; cc < eCutCounter_N; cc++) // enum eCutCounter + { + if (!pc.fParticleCutCounterHist[rs][cc]) { + continue; + } + histTitle = pc.fParticleCutCounterHist[rs][cc]->GetTitle(); + if (histTitle.Contains("__RUN_NUMBER__")) { + histTitle.ReplaceAll("__RUN_NUMBER__", tc.fRunNumber.Data()); // it replaces in-place + pc.fParticleCutCounterHist[rs][cc]->SetTitle(histTitle.Data()); + } + } + } + + // *) particle histograms 1D: + for (int t = 0; t < eParticleHistograms_N; t++) // type, see enum eParticleHistograms + { + for (int rs = 0; rs < 2; rs++) // reco/sim + { + for (int ba = 0; ba < 2; ba++) // before/after cuts + { + if (!ph.fParticleHistograms[t][rs][ba]) { + continue; + } + histTitle = ph.fParticleHistograms[t][rs][ba]->GetTitle(); + if (histTitle.Contains("__RUN_NUMBER__")) { + histTitle.ReplaceAll("__RUN_NUMBER__", tc.fRunNumber.Data()); // it replaces in-place + ph.fParticleHistograms[t][rs][ba]->SetTitle(histTitle.Data()); + } + } // for(int ba=0;ba<2;ba++) + } // for(int rs=0;rs<2;rs++) // reco/sim + } // for(int t=0;tGetTitle(); + if (histTitle.Contains("__RUN_NUMBER__")) { + histTitle.ReplaceAll("__RUN_NUMBER__", tc.fRunNumber.Data()); // it replaces in-place + ph.fParticleHistograms2D[t][rs][ba]->SetTitle(histTitle.Data()); + } + } // for(int ba=0;ba<2;ba++) + } // for(int rs=0;rs<2;rs++) // reco/sim + } // for(int t=0;t -eta , ab = 1 <=> + eta + for (int rs = 0; rs < 2; rs++) { // reco/sim + for (int ba = 0; ba < 2; ba++) { // before/after cuts + for (int e = 0; e < gMaxNumberEtaSeparations; e++) { // eta separation + if (!qv.fMabDist[ab][rs][ba][e]) { + continue; + } + histTitle = qv.fMabDist[ab][rs][ba][e]->GetTitle(); + if (histTitle.Contains("__RUN_NUMBER__")) { + histTitle.ReplaceAll("__RUN_NUMBER__", tc.fRunNumber.Data()); // it replaces in-place + qv.fMabDist[ab][rs][ba][e]->SetTitle(histTitle.Data()); + } + } + } + } + } + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // PropagateRunNumber() + + //============================================================ + + template + void CheckCurrentRunNumber(T1 const& collision, T2 const&) + { + // Insanity check for the current run number and related thingies. + // Used only during validation. + + // a) Support for Run 3 and Run 2 real data; + // b) The rest. TBI 20241126 differentiate this support as well, e.g. for eRecSim and eSim. But Run 2 and Run 1 most likely will stay as before + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // a) Support for Run 3 and Run 2 real data: + // TBI 20250112 enable other cases, after validating them + // TBI 20250112 Remember that I can get total run duration in converted data, but not current run duration. + if constexpr (rs == eRec || rs == eRec_Run2 || rs == eQA) { + + // **) Check run number: + + auto bc = collision.template foundBC_as(); // I have the same code snippet at other places, keep in sync. + if (!tc.fRunNumber.EqualTo(Form("%d", bc.runNumber()))) { + LOGF(error, "\033[1;33m%s Run number changed within process(). This most likely indicates that a given masterjob is processing 2 or more different runs in one go.\033[0m", __FUNCTION__); + LOGF(fatal, "tc.fRunNumber = %s, bc.runNumber() = %d", tc.fRunNumber.Data(), bc.runNumber()); + } + + // **) Check SoR, EoR, and run duration: + auto runDuration = ccdb->getRunDuration(bc.runNumber()); // this is total run duration, not the current one (see below) + int64_t startOfRun = std::floor(runDuration.first * 0.001); // in seconds since Unix epoch + int64_t endOfRun = std::ceil(runDuration.second * 0.001); // in seconds since Unix epoch + int64_t durationInSec = endOfRun - startOfRun; // yes, this is now run duration in seconds + + // **) Insanity check on SoR: + if (!(tc.fRunTime[eStartOfRun] == startOfRun)) { + LOGF(error, "\033[1;33m%s tc.fRunTime[eStartOfRun] changed within process(). This most likely indicates that a given masterjob is processing 2 or more different runs in one go.\033[0m", __FUNCTION__); + LOGF(fatal, "tc.fRunTime[eStartOfRun] = %d, startOfRun = %d", tc.fRunTime[eStartOfRun], startOfRun); + } + + // **) Insanity check on EoR: + if (!(tc.fRunTime[eEndOfRun] == endOfRun)) { + LOGF(error, "\033[1;33m%s tc.fRunTime[eEndOfRun] changed within process(). This most likely indicates that a given masterjob is processing 2 or more different runs in one go.\033[0m", __FUNCTION__); + LOGF(fatal, "tc.fRunTime[eEndOfRun] = %d, endOfRun = %d", tc.fRunTime[eEndOfRun], endOfRun); + } + + // **) Insanity check on run duration: + if (!(tc.fRunTime[eDurationInSec] == durationInSec)) { + LOGF(error, "\033[1;33m%s tc.fRunTime[eDurationInSec] changed within process(). This most likely indicates that a given masterjob is processing 2 or more different runs in one go.\033[0m", __FUNCTION__); + LOGF(fatal, "tc.fRunTime[eDurationInSec] = %d, durationInSec = %d", tc.fRunTime[eDurationInSec], durationInSec); + } + + } else if constexpr (rs == eTest) { + LOGF(warning, "\033[1;33m%s at line %d : RunNumber cannot be checked in eTest mode, due to minimal subscription. Simply skipping this check. If you do not like this, extend subscription to more tables.\033[0m", __FUNCTION__, __LINE__); + } else { + // b) The rest: + + if (!tc.fRunNumber.EqualTo(Form("%d", collision.bc().runNumber()))) { + LOGF(error, "\033[1;33m%s Run number changed within process(). This most likely indicates that a given masterjob is processing 2 or more different runs in one go.\033[0m", __FUNCTION__); + LOGF(fatal, "tc.fRunNumber = %s, collision.bc().runNumber() = %d", tc.fRunNumber.Data(), collision.bc().runNumber()); + } + + } // to else + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // template void CheckCurrentRunNumber(T1 const& collision, T2 const&) + + //============================================================ + + void ResetEventByEventQuantities() + { + // Reset all global event-by-event quantities here: + + // a) Event-by-event quantities; + // b) Q-vectors; + // c) Reset ebe containers for nested loops; + // d) Fisher-Yates algorithm; + // e) QA. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // a) Event-by-event quantities: + ebye.fSelectedTracks = 0; + ebye.fMultiplicity = 0.; + ebye.fReferenceMultiplicity = 0.; + ebye.fCentrality = 0.; + // ebye.fCentralitySim = 0.; // TBI 20250429 special treatment, because I access this one before Steer(...) is called in .cxx . Re-think how to handle this one + // But if I do not access it in .cxx, in any case I skip that collision, so I think it is just fine not to reset it here + ebye.fOccupancy = 0.; + ebye.fInteractionRate = 0.; + ebye.fCurrentRunDuration = 0.; + ebye.fVz = 0.; + ebye.fVzSim = 0.; + ebye.fFT0CAmplitudeOnFoundBC = 0.; + ebye.fImpactParameter = 0.; // I can reset it here to 0., as long as I am calculating it from collision.mcCollision().impactParameter() . If I calculate it from hep.impactParameter(), i need to re-think + + // b) Q-vectors: + if (qv.fCalculateQvectors) { + + // b0) generic Q-vector: + ResetQ(); + // b1) integrated Q-vector: + for (int h = 0; h < gMaxHarmonic * gMaxCorrelator + 1; h++) { + for (int wp = 0; wp < gMaxCorrelator + 1; wp++) // weight power + { + qv.fQvector[h][wp] = TComplex(0., 0.); // legacy code (TBI 20250718 remove, and switch to line below eventually) + // qv.fQvector[h][wp] = {0., 0.}; // yes, this is the right notation for complex numbers + } + } + } // if (qv.fCalculateQvectors) + + if (qv.fCalculateqvectorsKineAny) { + ResetQ(); // TBI 20250601 do I really need this one here. It doesn't hurt, though... + // Remark: It's important to validate this reset with nested loops e-by-e and for all events. + for (int i = 0; i < static_cast(qv.fqvector.size()); ++i) { + for (int j = 0; j < static_cast(qv.fqvector[i].size()); ++j) { + qv.fqvectorEntries[i][j] = 0; + for (int k = 0; k < static_cast(qv.fqvector[i][j].size()); ++k) { + for (int l = 0; l < static_cast(qv.fqvector[i][j][k].size()); ++l) { + qv.fqvector[i][j][k][l] = {0., 0.}; // yes, this is the right notation for complex numbers + } + } + } + } + + } // if (qv.fCalculateqvectorsKineAny) + + // b3) integrated Q-vector needed for calculations with eta separations: + if (es.fCalculateEtaSeparations) { + for (int ab = 0; ab < 2; ab++) { // ab = 0 <=> -eta , ab = 1 <=> + eta + for (int h = 0; h < gMaxHarmonic; h++) { + if (es.fEtaSeparationsSkipHarmonics[h]) { + continue; + } + for (int e = 0; e < gMaxNumberEtaSeparations; e++) { // eta separation + qv.fQabVector[ab][h][e] = TComplex(0., 0.); + } + } + } + for (int ab = 0; ab < 2; ab++) { // ab = 0 <=> -eta , ab = 1 <=> + eta + for (int e = 0; e < gMaxNumberEtaSeparations; e++) { // eta separation + qv.fMab[ab][e] = 0.; + } + } + } + + // b4) diff. q-vector needed for calculations with eta separations: + if (es.fCalculateEtaSeparationsAsFunctionOf[AFO_PT]) { // _444 check this conditions + // [-eta or +eta][eqvectorKine_N][global binNo][harmonic][eta separation] + for (int i = 0; i < static_cast(qv.fqabVector.size()); ++i) { + for (int j = 0; j < static_cast(qv.fqabVector[i].size()); ++j) { + for (int k = 0; k < static_cast(qv.fqabVector[i][j].size()); ++k) { + for (int l = 0; l < static_cast(qv.fqabVector[i][j][k].size()); ++l) { // yes, this dimension is for harmonics at the moment + if (es.fEtaSeparationsSkipHarmonics[l]) { + continue; + } + for (int m = 0; m < static_cast(qv.fqabVector[i][j][k][l].size()); ++m) { + qv.fqabVector[i][j][k][l][m] = {0., 0.}; // yes, this is the right notation for complex numbers + } + } + } + } + } + + // [-eta or +eta][eqvectorKine_N][global binNo][eta separation] + for (int i = 0; i < static_cast(qv.fmab.size()); ++i) { + for (int j = 0; j < static_cast(qv.fmab[i].size()); ++j) { + for (int k = 0; k < static_cast(qv.fmab[i][j].size()); ++k) { + for (int l = 0; l < static_cast(qv.fmab[i][j][k].size()); ++l) { + qv.fmab[i][j][k][l] = 0.; + } + } + } + } + + } // if (es.fCalculateEtaSeparationsAsFunctionOf[AFO_PT]) + + // c) Reset ebe containers for nested loops: + if (nl.fCalculateNestedLoops || nl.fCalculateCustomNestedLoops) { + if (nl.ftaNestedLoops[0]) { + nl.ftaNestedLoops[0]->Reset(); + } + if (nl.ftaNestedLoops[1]) { + nl.ftaNestedLoops[1]->Reset(); + } + + } // if(nl.fCalculateNestedLoops || nl.fCalculateCustomNestedLoops) + + if (nl.fCalculateKineCustomNestedLoops) { + int nBins = -1; + + // 1D kine: + // **) vs. pt: + nBins = res.fResultsPro[AFO_PT]->GetNbinsX() + 2; // + 2 means that I take into account overflow and underflow, then skip it in the loop below + for (int b = 0; b < nBins; b++) { + nl.ftaNestedLoopsKine[PTq][b][0]->Reset(); + nl.ftaNestedLoopsKine[PTq][b][1]->Reset(); + } + + // **) vs. eta: + nBins = res.fResultsPro[AFO_ETA]->GetNbinsX() + 2; // + 2 means that I take into account overflow and underflow, then skip it in the loop below + for (int b = 0; b < nBins; b++) { + nl.ftaNestedLoopsKine[ETAq][b][0]->Reset(); + nl.ftaNestedLoopsKine[ETAq][b][1]->Reset(); + } + + // **) vs. charge: + nBins = res.fResultsPro[AFO_CHARGE]->GetNbinsX() + 2; // + 2 means that I take into account overflow and underflow, then skip it in the loop below + for (int b = 0; b < nBins; b++) { + nl.ftaNestedLoopsKine[CHARGEq][b][0]->Reset(); + nl.ftaNestedLoopsKine[CHARGEq][b][1]->Reset(); + } + + // ... + + // 2D kine: + // **) vs. (pt,eta): + if (res.fResultsPro2D[AfoKineMap2D(PT_ETAq)]) { // this is safe, because this one shall be booked if any of Correlations, Test0, EtaSeparations, etc., was requested + nBins = (res.fResultsPro2D[AfoKineMap2D(PT_ETAq)]->GetNbinsX() + 2) * (res.fResultsPro2D[AfoKineMap2D(PT_ETAq)]->GetNbinsY() + 2); // + 2 means that I take into account overflow and underflow, then skip it in the loop below + for (int b = 0; b < nBins; b++) { // loop over lineralized global bins + nl.ftaNestedLoopsKine[PT_ETAq][b][0]->Reset(); + nl.ftaNestedLoopsKine[PT_ETAq][b][1]->Reset(); + } + } + + // **) vs. (pt,charge): + if (res.fResultsPro2D[AfoKineMap2D(PT_CHARGEq)]) { // this is safe, because this one shall be booked if any of Correlations, Test0, EtaSeparations, etc., was requested + nBins = (res.fResultsPro2D[AfoKineMap2D(PT_CHARGEq)]->GetNbinsX() + 2) * (res.fResultsPro2D[AfoKineMap2D(PT_CHARGEq)]->GetNbinsY() + 2); // + 2 means that I take into account overflow and underflow, then skip it in the loop below + for (int b = 0; b < nBins; b++) { // loop over lineralized global bins + nl.ftaNestedLoopsKine[PT_CHARGEq][b][0]->Reset(); + nl.ftaNestedLoopsKine[PT_CHARGEq][b][1]->Reset(); + } + } + + // **) vs. (eta,charge): + if (res.fResultsPro2D[AfoKineMap2D(ETA_CHARGEq)]) { // this is safe, because this one shall be booked if any of Correlations, Test0, EtaSeparations, etc., was requested + nBins = (res.fResultsPro2D[AfoKineMap2D(ETA_CHARGEq)]->GetNbinsX() + 2) * (res.fResultsPro2D[AfoKineMap2D(ETA_CHARGEq)]->GetNbinsY() + 2); // + 2 means that I take into account overflow and underflow, then skip it in the loop below + for (int b = 0; b < nBins; b++) { // loop over lineralized global bins + nl.ftaNestedLoopsKine[ETA_CHARGEq][b][0]->Reset(); + nl.ftaNestedLoopsKine[ETA_CHARGEq][b][1]->Reset(); + } + } + + // ... + + // 3D kine: + // **) vs. (pt,eta,charge): + if (res.fResultsPro3D[AfoKineMap3D(PT_ETA_CHARGEq)]) { // this is safe, because this one shall be booked if any of Correlations, Test0, EtaSeparations, etc., was requested + nBins = (res.fResultsPro3D[AfoKineMap3D(PT_ETA_CHARGEq)]->GetNbinsX() + 2) * (res.fResultsPro3D[AfoKineMap3D(PT_ETA_CHARGEq)]->GetNbinsY() + 2) * (res.fResultsPro3D[AfoKineMap3D(PT_ETA_CHARGEq)]->GetNbinsZ() + 2); // + 2 means that I take into account overflow and underflow, then skip it in the loop below + for (int b = 0; b < nBins; b++) { // loop over lineralized global bins + nl.ftaNestedLoopsKine[PT_ETA_CHARGEq][b][0]->Reset(); + nl.ftaNestedLoopsKine[PT_ETA_CHARGEq][b][1]->Reset(); + } + } + + // ... + + } // if(nl.fCalculateKineCustomNestedLoops) { + + // d) Fisher-Yates algorithm: + if (tc.fUseFisherYates) { + delete tc.fRandomIndices; + tc.fRandomIndices = NULL; + } + + // e) QA: + for (int rs = 0; rs < 2; rs++) // reco/sim + { + for (int ba = 0; ba < 2; ba++) // before/after cuts + { + if (qa.fQAParticleEventProEbyE[rs][ba]) { + qa.fQAParticleEventProEbyE[rs][ba]->Reset(); + } + } + } + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // void ResetEventByEventQuantities() + + //============================================================ + + template + void EventCutsCounters(T1 const& collision, T2 const& tracks) + { + // Use this function to fill absolute and sequential event cut counters. Use only during QA, as this is computationally heavy. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // *) Establish ordering of binning in event cut counters histograms, which resembles ordering of event cuts implementation: + if (!ec.fEventCutCounterBinLabelingIsDone) { + ec.fEventCutCounterBinNumber[eRec] = 1; // remember that I cannot use 'rs' here as an index, because the enum eRecSim covers separately Run 1 and Run 2, etc. + ec.fEventCutCounterBinNumber[eSim] = 1; + EventCuts(collision, tracks, eCutCounterBinning); // dry call, to establish the map fEventCutCounterMap and its inverse + + // **) Special treatment for event cuts implemented outside of EventCuts(), like eMultiplicity: + // Algorithm: I simply add eMultiplicity at the end of what was esatablished by now in the above call EventCuts(collision, tracks, eCutCounterBinning) + // unless proven it shall be done some other way. + if (ec.fEventCutCounterMap[eRec]) { // TBI 20240414 also here have to hardcode 'eRec', because 'rs' spans over all enums in eRecSim => I definitely need 'generic Rec' case, perhaps via TExMap ? + // But I have already tc.fProcess[eGenericRec] and tc.fProcess[eGenericRecSim], available, shall I simply re-use them? + ec.fEventCutCounterMap[eRec]->Add(ec.fEventCutCounterBinNumber[eRec], eMultiplicity); + ec.fEventCutCounterMapInverse[eRec]->Add(eMultiplicity, ec.fEventCutCounterBinNumber[eRec]); + ec.fEventCutCounterBinNumber[eRec]++; // yes + } + if (ec.fEventCutCounterMap[eSim]) { // TBI 20240414 also here have to hardcode 'eSim', because 'rs' spans over all enums in eRecSim => I definitely need 'generic Rec' case, perhaps via TExMap ? + // But I have already tc.fProcess[eGenericRec] and tc.fProcess[eGenericRecSim], available, shall I simply re-use them? + ec.fEventCutCounterMap[eSim]->Add(ec.fEventCutCounterBinNumber[eSim], eMultiplicity); + ec.fEventCutCounterMapInverse[eSim]->Add(eMultiplicity, ec.fEventCutCounterBinNumber[eSim]); + ec.fEventCutCounterBinNumber[eSim]++; // yes + } + + // **) Map this ordering into bin labels of actual histograms for event cut counters: + for (int rec_sim = 0; rec_sim < 2; rec_sim++) // reco/sim => I use here exceptionally different var 'rec_sim', not the shadow 'rs' in the template parameter + { + for (int cc = 0; cc < eCutCounter_N; cc++) // enum eCutCounter + { + if (!ec.fEventCutCounterHist[rec_sim][cc]) { + continue; + } + + if (tc.fUseSetBinLabel) { + for (int bin = 1; bin < ec.fEventCutCounterBinNumber[rec_sim]; bin++) // implemented and used cuts in this analysis + { + ec.fEventCutCounterHist[rec_sim][cc]->GetXaxis()->SetBinLabel(bin, FancyFormatting(ec.fEventCutName[ec.fEventCutCounterMap[rec_sim]->GetValue(bin)].Data())); + } + for (int bin = ec.fEventCutCounterBinNumber[rec_sim]; bin <= eEventCuts_N; bin++) // implemented, but unused cuts in this analysis + { + ec.fEventCutCounterHist[rec_sim][cc]->GetXaxis()->SetBinLabel(bin, TString::Format("binNo = %d (unused cut)", bin)); + // Remark: I have to write here something concrete as a bin label, if I leave "TBI" for all bin labels here for cuts which were not used, + // I get this harmless but annoying warning during merging: + // Warning in : Histogram fEventCutCounterHist[rec][seq] has duplicate labels in the x axis. Bin contents will be merged in a single bin + // TBI 20241130 as a better solution, I shall re-define this histogram with the narower range on x-axis... + } + } else { + + // Workaround for SetBinLabel() large memory consumption: + TString yAxisTitle = ""; + for (int bin = 1; bin < ec.fEventCutCounterBinNumber[rec_sim]; bin++) // implemented and used cuts in this analysis + { + yAxisTitle += TString::Format("%d:%s; ", bin, FancyFormatting(ec.fEventCutName[ec.fEventCutCounterMap[rec_sim]->GetValue(bin)].Data())); + } + for (int bin = ec.fEventCutCounterBinNumber[rec_sim]; bin <= eEventCuts_N; bin++) // implemented, but unused cuts in this analysis + { + yAxisTitle += TString::Format("%d:%s; ", bin, TString::Format("binNo = %d (unused cut)", bin).Data()); + } + + // *) Insanity check on the number of fields in this specially crafted y-axis title: + TObjArray* oa = yAxisTitle.Tokenize(";"); + if (!oa) { + LOGF(fatal, "\033[1;31m%s at line %d : oa is NULL\033[0m", __FUNCTION__, __LINE__); + } + if (oa->GetEntries() - 1 != ec.fEventCutCounterHist[rec_sim][cc]->GetNbinsX()) { + LOGF(fatal, "\033[1;31m%s at line %d : oa->GetEntries() = %d != ec.fEventCutCounterHist[rec_sim][cc]->GetNbinsX() = %d\033[0m", __FUNCTION__, __LINE__, oa->GetEntries(), ec.fEventCutCounterHist[rec_sim][cc]->GetNbinsX()); + } + delete oa; + + // *) Okay, set the title: + ec.fEventCutCounterHist[rec_sim][cc]->GetYaxis()->SetTitle(yAxisTitle.Data()); + + } // else + + // All cuts which were implemeted, but not used I simply do not show (i can always UnZoom x-axis in TBrowser, if I want to see 'em): + ec.fEventCutCounterHist[rec_sim][cc]->GetXaxis()->SetRangeUser(ec.fEventCutCounterHist[rec_sim][cc]->GetBinLowEdge(1), ec.fEventCutCounterHist[rec_sim][cc]->GetBinLowEdge(ec.fEventCutCounterBinNumber[rec_sim])); + } + } + + ec.fEventCutCounterBinLabelingIsDone = true; // this flag ensures that this specific binning is performed only once, for the first processed event + // delete ec.fEventCutCounterMap[eRec]; // TBI 20240508 if i do not need them later, I could delete here + // delete ec.fEventCutCounterMap[eSim]; + // delete ec.fEventCutCounterMapInverse[eRec]; + // delete ec.fEventCutCounterMapInverse[eSim]; + } // if (!ec.fEventCutCounterBinLabelingIsDone) { + + // *) Event cut counter (absolute): + if (ec.fUseEventCutCounterAbsolute) { + ec.fEventCutCounterBinNumber[eRec] = 1; + ec.fEventCutCounterBinNumber[eSim] = 1; + EventCuts(collision, tracks, eCutCounterAbsolute); + + // **) Special treatments: + // a) eMultiplicity: It doesn't make sense to treat this one in eCutCounterAbsolute + } + + // *) Event cut counter (sequential): + if (ec.fUseEventCutCounterSequential) { + ec.fEventCutCounterBinNumber[eRec] = 1; + ec.fEventCutCounterBinNumber[eSim] = 1; + EventCuts(collision, tracks, eCutCounterSequential); + + // **) Special treatments: + // a) eMultiplicity: Since cut on eMultiplicity is implenented outside of EventCuts + // I call EventCut(rs, eMultiplicity, eCutCounterSequential) directly where its implemented. + // Add same treatment for other special cases, but do not forget above to expand **) Special treatment for event cuts ... + } + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // template void EventCutsCounters(T1 const& collision, T2 const& tracks, eCutModus cutModus) + + //============================================================ + + template + bool EventCuts(T1 const& collision, T2 const& tracks, eCutModus cutModus) + { + // Event cuts on reconstructed and simulated data. Supports event cut counters, both absolute and sequential. + // There is also a related enum eEventCuts. + // Remark: I have added to all if statemets below which deals with floats, e.g. std::abs(ebye.fCentrality - ec.fdEventCuts[eCentrality][eMax]) < tc.fFloatingPointPrecision , + // to enforce the ROOT convention: "lower boundary included, upper boundary excluded" + + // a) Event cuts on reconstructed, and corresponding MC truth simulated (common to Run 3, Run 2 and Run 1); + // b) Event cuts only on simulated (common to Run 3, Run 2 and Run 1); + // c) Event cuts on reconstructed, and corresponding MC truth simulated (Run 3 specific); + // d) Event cuts on simulated (Run 3 specific); + // e) Event cuts on reconstructed, and corresponding MC truth simulated (Run 1 and 2 specific); // In case there is some corner case between Run 1 and Run 2, simply branch further this one + // f) Event cuts on simulated (Run 1 and 2 specific); // In case there is some corner case between Run 1 and Run 2, simply branch further this one + // *) Event cuts for Test case. + + // 44:EventCuts + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // a) Event cuts on reconstructed, and corresponding MC truth simulated (common to Run 3, Run 2 and Run 1) ... + if constexpr (rs == eRec || rs == eRecAndSim || rs == eRec_Run2 || rs == eRecAndSim_Run2 || rs == eRec_Run1 || rs == eRecAndSim_Run1 || rs == eQA) { + + // *) NumberOfEvents: => this event cut is implemented directly in Steer(...) + + // *) SelectedEvents: => this event cut is implemented directly in Steer(...) + + // *) Offline trigger: + // Remark from documentation: Bypass this check if you analyse MC or continuous Run3 data. + // Documentation: + // a) O2Physics/Common/CCDB/TriggerAliases.h => available trigger aliases + // b) O2Physics/Common/CCDB/macros/upload_trigger_aliases.C => definitions of each trigger alias + // In addition: remember that I can use it only for process cases where I have joined aod::Collisions with aod::EvSels + // TBI 20240517 I didn't validate this trigger on Run 1, in fact, I have added protection against its usage in InsanityChecks. + if (ec.fUseEventCuts[eTrigger]) { + if (cutModus == eCutCounterBinning) { + EventCut(eRec, eTrigger, eCutCounterBinning); + } else if (ec.fsEventCuts[eTrigger].EqualTo("kINT7") && !collision.alias_bit(kINT7)) { // Validated only for Run 2 + if (!EventCut(eRec, eTrigger, cutModus)) { + return false; + } + } else if (ec.fsEventCuts[eTrigger].EqualTo("kTVXinTRD") && !collision.alias_bit(kTVXinTRD)) { // Validated only for Run 3 + if (!EventCut(eRec, eTrigger, cutModus)) { + return false; + } + } + // ... + } + + // collision.alias_bit(kTVXinTRD); + + // *) Sel8: // see definition in Common/TableProducer/eventSelection.cxx + if (ec.fUseEventCuts[eSel8]) { + if (cutModus == eCutCounterBinning) { + EventCut(eRec, eSel8, eCutCounterBinning); + } else if (!collision.sel8()) { + if (!EventCut(eRec, eSel8, cutModus)) { + return false; + } + } + } + + // *) TotalMultiplicity: + if (ec.fUseEventCuts[eTotalMultiplicity]) { + if (cutModus == eCutCounterBinning) { + EventCut(eRec, eTotalMultiplicity, eCutCounterBinning); + } else if (tracks.size() < ec.fdEventCuts[eTotalMultiplicity][eMin] || tracks.size() > ec.fdEventCuts[eTotalMultiplicity][eMax] || std::abs(tracks.size() - ec.fdEventCuts[eTotalMultiplicity][eMax]) < tc.fFloatingPointPrecision) { + if (!EventCut(eRec, eTotalMultiplicity, cutModus)) { + return false; + } + } + } + + // *) Multiplicity: + // Remark: This cut is implemented directly in Steer(...), because I allow the possibility that ebye.fMultiplicity = ebye.fSelectedTracks . + // In fact, that will be true in most cases of practical interest. + + // *) Reference multiplicity: + // Remark: In this member function, reference multiplicity is just a number, and any specific setting for Run 3, 2, or 1 is already done in DetermineReferenceMultiplicity(...) + if (ec.fUseEventCuts[eReferenceMultiplicity]) { + if (cutModus == eCutCounterBinning) { + EventCut(eRec, eReferenceMultiplicity, eCutCounterBinning); + } else if (ebye.fReferenceMultiplicity < ec.fdEventCuts[eReferenceMultiplicity][eMin] || ebye.fReferenceMultiplicity > ec.fdEventCuts[eReferenceMultiplicity][eMax] || std::abs(ebye.fReferenceMultiplicity - ec.fdEventCuts[eReferenceMultiplicity][eMax]) < tc.fFloatingPointPrecision) { + if (!EventCut(eRec, eReferenceMultiplicity, cutModus)) { + return false; + } + } + } + + // *) Centrality: + // Remark: In this member function, centrality is just a number, and any specific setting for Run 3, 2, or 1 is already done in DetermineCentrality(...) + if (ec.fUseEventCuts[eCentrality]) { + if (cutModus == eCutCounterBinning) { + EventCut(eRec, eCentrality, eCutCounterBinning); + } else if (ebye.fCentrality < ec.fdEventCuts[eCentrality][eMin] || ebye.fCentrality > ec.fdEventCuts[eCentrality][eMax] || std::abs(ebye.fCentrality - ec.fdEventCuts[eCentrality][eMax]) < tc.fFloatingPointPrecision) { + if (!EventCut(eRec, eCentrality, cutModus)) { + return false; + } + } + } + + // *) VertexX: + if (ec.fUseEventCuts[eVertexX]) { + if (cutModus == eCutCounterBinning) { + EventCut(eRec, eVertexX, eCutCounterBinning); + } else if (collision.posX() < ec.fdEventCuts[eVertexX][eMin] || collision.posX() > ec.fdEventCuts[eVertexX][eMax] || std::abs(collision.posX() - ec.fdEventCuts[eVertexX][eMax]) < tc.fFloatingPointPrecision) { + if (!EventCut(eRec, eVertexX, cutModus)) { + return false; + } + } + } + + // *) VertexY: + if (ec.fUseEventCuts[eVertexY]) { + if (cutModus == eCutCounterBinning) { + EventCut(eRec, eVertexY, eCutCounterBinning); + } else if (collision.posY() < ec.fdEventCuts[eVertexY][eMin] || collision.posY() > ec.fdEventCuts[eVertexY][eMax] || std::abs(collision.posY() - ec.fdEventCuts[eVertexY][eMax]) < tc.fFloatingPointPrecision) { + if (!EventCut(eRec, eVertexY, cutModus)) { + return false; + } + } + } + + // *) VertexZ: + if (ec.fUseEventCuts[eVertexZ]) { + if (cutModus == eCutCounterBinning) { + EventCut(eRec, eVertexZ, eCutCounterBinning); + } else if (collision.posZ() < ec.fdEventCuts[eVertexZ][eMin] || collision.posZ() > ec.fdEventCuts[eVertexZ][eMax] || std::abs(collision.posZ() - ec.fdEventCuts[eVertexZ][eMax]) < tc.fFloatingPointPrecision) { + if (!EventCut(eRec, eVertexZ, cutModus)) { + return false; + } + } + } + + // *) MinVertexDistanceFromIP (minimal vertex distance from nominal Interaction Point). If vertex is closer that this value, this event is rejected: + if (ec.fUseEventCuts[eMinVertexDistanceFromIP]) { + if (cutModus == eCutCounterBinning) { + EventCut(eRec, eMinVertexDistanceFromIP, eCutCounterBinning); + } else if (std::sqrt(std::pow(collision.posX(), 2.) + std::pow(collision.posY(), 2.) + std::pow(collision.posZ(), 2.)) < ec.fdEventCuts[eMinVertexDistanceFromIP][eMin]) { + if (!EventCut(eRec, eMinVertexDistanceFromIP, cutModus)) { + return false; + } + } + } + + // *) NContributors: + if (ec.fUseEventCuts[eNContributors]) { + if (cutModus == eCutCounterBinning) { + EventCut(eRec, eNContributors, eCutCounterBinning); + } else if (collision.numContrib() < ec.fdEventCuts[eNContributors][eMin] || collision.numContrib() > ec.fdEventCuts[eNContributors][eMax] || std::abs(collision.numContrib() - ec.fdEventCuts[eNContributors][eMax]) < tc.fFloatingPointPrecision) { + if (!EventCut(eRec, eNContributors, cutModus)) { + return false; + } + } + } + + // *) RefMultVsNContrUp: + if (ec.fUseEventCuts[eRefMultVsNContrUp]) { + if (cutModus == eCutCounterBinning) { + EventCut(eRec, eRefMultVsNContrUp, eCutCounterBinning); + } else if (collision.numContrib() > (tc.fUseFormula ? ec.fEventCutsFormulas[eRefMultVsNContrUp_Formula]->Eval(ebye.fReferenceMultiplicity) : RefMultVsNContr(ebye.fReferenceMultiplicity, eRefMultVsNContrUp_Formula))) { + if (!EventCut(eRec, eRefMultVsNContrUp, cutModus)) { + return false; + } + } + } + + // *) RefMultVsNContrLow: + if (ec.fUseEventCuts[eRefMultVsNContrLow]) { + if (cutModus == eCutCounterBinning) { + EventCut(eRec, eRefMultVsNContrLow, eCutCounterBinning); + } else if (collision.numContrib() < (tc.fUseFormula ? ec.fEventCutsFormulas[eRefMultVsNContrLow_Formula]->Eval(ebye.fReferenceMultiplicity) : RefMultVsNContr(ebye.fReferenceMultiplicity, eRefMultVsNContrLow_Formula))) { + if (!EventCut(eRec, eRefMultVsNContrLow, cutModus)) { + return false; + } + } + } + + // *) CentralityCorrelationsCut: + if (ec.fUseEventCuts[eCentralityCorrelationsCut]) { + if (cutModus == eCutCounterBinning) { + EventCut(eRec, eCentralityCorrelationsCut, eCutCounterBinning); + } else if (!CentralityCorrelationCut()) { + if (!EventCut(eRec, eCentralityCorrelationsCut, cutModus)) { + return false; + } + } + } + + // ... + + // ... and corresponding MC truth simulated: + // See https://github.com/AliceO2Group/O2Physics/blob/master/Tutorials/src/mcHistograms.cxx + // See https://aliceo2group.github.io/analysis-framework/docs/datamodel/ao2dTables.html#montecarlo + if constexpr (rs == eRecAndSim || rs == eRecAndSim_Run2 || rs == eRecAndSim_Run1) { + if (!collision.has_mcCollision()) { + LOGF(warning, "\033[1;31m%s at line %d : No MC collision for this collision, skip... \033[0m", __FUNCTION__, __LINE__); // TBI 20231106 re-think. I shouldn't probably get to this point, if MC truth info doesn't exist for this collision + return false; + } + + // In this branch I can cut additionally and directly on corresponding MC truth simulated, e.g. on collision.mcCollision().posZ(). + // In case I implement something here, remember to switch from eRec to eSim when calling e.g. EventCut(...) + + // ... + + } // if constexpr (rs == eRecAndSim || rs == eRecAndSim_Run2 || rs == eRecAndSim_Run1) { + + } // if constexpr (rs == eRec || rs == eRecAndSim || rs == eRec_Run2 || rs == eRecAndSim_Run2 || rs == eRec_Run1 || rs == eRecAndSim_Run1) { + + // ------------------------------------------------------------------------- + + // b) Event cuts only on simulated (common to Run 3, Run 2 and Run 1): + // Remark #1: This branch is relevant when processing ONLY simulated data at generator level. + // Remark #2: In this branch 'collision' is always o2::aod::McCollision, see https://aliceo2group.github.io/analysis-framework/docs/datamodel/ao2dTables.html#montecarlo + if constexpr (rs == eSim || rs == eSim_Run2 || rs == eSim_Run1) { + + // *) NumberOfEvents: => this event cut is implemented directly in Steer(...) + + // *) Impact parameter: + if (ec.fUseEventCuts[eImpactParameter]) { + if (cutModus == eCutCounterBinning) { + EventCut(eSim, eImpactParameter, eCutCounterBinning); + } else if (collision.impactParameter() < ec.fdEventCuts[eImpactParameter][eMin] || collision.impactParameter() > ec.fdEventCuts[eImpactParameter][eMax] || std::abs(collision.impactParameter() - ec.fdEventCuts[eImpactParameter][eMax]) < tc.fFloatingPointPrecision) { + if (!EventCut(eSim, eImpactParameter, cutModus)) { + return false; + } + } + } + + // *) Event plane angle: + if (ec.fUseEventCuts[eEventPlaneAngle]) { + if (cutModus == eCutCounterBinning) { + EventCut(eSim, eEventPlaneAngle, eCutCounterBinning); + } else if (collision.eventPlaneAngle() < ec.fdEventCuts[eEventPlaneAngle][eMin] || collision.eventPlaneAngle() > ec.fdEventCuts[eEventPlaneAngle][eMax] || std::abs(collision.eventPlaneAngle() - ec.fdEventCuts[eEventPlaneAngle][eMax]) < tc.fFloatingPointPrecision) { + if (!EventCut(eSim, eEventPlaneAngle, cutModus)) { + return false; + } + } + } + + // *) TotalMultiplicity: + // TBI 20240509 check what is the Monte Carlo analogy for tracks.size() + + // *) Multiplicity: + // Remark: This cut is implemented directly in Steer(...) TBI 20240508 check how to implement this one with the current re-write + + // *) Centrality: this centrality is calculated directly from impact parameter, i.e. this is centrality at simulated level, see DetermineCentrality(...) what I do for thre "eSim*" cases. + if (ec.fUseEventCuts[eCentrality]) { + if (cutModus == eCutCounterBinning) { + EventCut(eSim, eCentrality, eCutCounterBinning); + } else if (ebye.fCentrality < ec.fdEventCuts[eCentrality][eMin] || ebye.fCentrality > ec.fdEventCuts[eCentrality][eMax] || std::abs(ebye.fCentrality - ec.fdEventCuts[eCentrality][eMax]) < tc.fFloatingPointPrecision) { + if (!EventCut(eSim, eCentrality, cutModus)) { + return false; + } + } + } + + // *) VertexX: + if (ec.fUseEventCuts[eVertexX]) { + if (cutModus == eCutCounterBinning) { + EventCut(eSim, eVertexX, eCutCounterBinning); + } else if (collision.posX() < ec.fdEventCuts[eVertexX][eMin] || collision.posX() > ec.fdEventCuts[eVertexX][eMax] || std::abs(collision.posX() - ec.fdEventCuts[eVertexX][eMax]) < tc.fFloatingPointPrecision) { + if (!EventCut(eSim, eVertexX, cutModus)) { + return false; + } + } + } + + // *) VertexY: + if (ec.fUseEventCuts[eVertexY]) { + if (cutModus == eCutCounterBinning) { + EventCut(eSim, eVertexY, eCutCounterBinning); + } else if (collision.posY() < ec.fdEventCuts[eVertexY][eMin] || collision.posY() > ec.fdEventCuts[eVertexY][eMax] || std::abs(collision.posY() - ec.fdEventCuts[eVertexY][eMax]) < tc.fFloatingPointPrecision) { + if (!EventCut(eSim, eVertexY, cutModus)) { + return false; + } + } + } + + // *) VertexZ: + if (ec.fUseEventCuts[eVertexZ]) { + if (cutModus == eCutCounterBinning) { + EventCut(eSim, eVertexZ, eCutCounterBinning); + } else if (collision.posZ() < ec.fdEventCuts[eVertexZ][eMin] || collision.posZ() > ec.fdEventCuts[eVertexZ][eMax] || std::abs(collision.posZ() - ec.fdEventCuts[eVertexZ][eMax]) < tc.fFloatingPointPrecision) { + if (!EventCut(eSim, eVertexZ, cutModus)) { + return false; + } + } + } + + // *) MinVertexDistanceFromIP (minimal vertex distance from nominal Interaction Point). If vertex is closer that this value, this event is rejected: + if (ec.fUseEventCuts[eMinVertexDistanceFromIP]) { + if (cutModus == eCutCounterBinning) { + EventCut(eRec, eMinVertexDistanceFromIP, eCutCounterBinning); + } else if (std::sqrt(std::pow(collision.posX(), 2.) + std::pow(collision.posY(), 2.) + std::pow(collision.posZ(), 2.)) < ec.fdEventCuts[eMinVertexDistanceFromIP][eMin]) { + if (!EventCut(eRec, eMinVertexDistanceFromIP, cutModus)) { + return false; + } + } + } + + // *) Sel8: TBI 20240509 + + // *) SelectedEvents: => this event cut is implemented directly in Steer(...) + + // ... + + } // if constexpr (rs == eSim || rs == eSim_Run2 || rs == eSim_Run1) { + + // ------------------------------------------------------------------------- + + // c) Event cuts on reconstructed, and corresponding MC truth simulated (Run 3 specific): + // Remark: I implement here only the event cuts which are not already in group a) above, and which make sense only for Run 3 data. + if constexpr (rs == eRec || rs == eRecAndSim || rs == eQA) { + + // For Run 3 multiplicities, I subscribe to o2::aod::Mults + // See how it is defined as Joined table at https://aliceo2group.github.io/analysis-framework/docs/datamodel/helperTaskTables.html#o2-analysis-multiplicity-table + // Therefore, I need always a header Common/DataModel/Multiplicity.h and o2-analysis-multiplicity-table in the workflow + // TBI 20240509 check also o2::aod::MultExtra + + // *) Occupancy: + if (ec.fUseEventCuts[eOccupancy]) { + if (cutModus == eCutCounterBinning) { + EventCut(eRec, eOccupancy, eCutCounterBinning); + } else if (ebye.fOccupancy < ec.fdEventCuts[eOccupancy][eMin] || ebye.fOccupancy > ec.fdEventCuts[eOccupancy][eMax] || std::abs(ebye.fOccupancy - ec.fdEventCuts[eOccupancy][eMax]) < tc.fFloatingPointPrecision) { + if (!EventCut(eRec, eOccupancy, cutModus)) { + return false; + } + } + } + + // *) InteractionRate: + if (ec.fUseEventCuts[eInteractionRate]) { + if (cutModus == eCutCounterBinning) { + EventCut(eRec, eInteractionRate, eCutCounterBinning); + } else if (ebye.fInteractionRate < ec.fdEventCuts[eInteractionRate][eMin] || ebye.fInteractionRate > ec.fdEventCuts[eInteractionRate][eMax] || std::abs(ebye.fInteractionRate - ec.fdEventCuts[eInteractionRate][eMax]) < tc.fFloatingPointPrecision) { + if (!EventCut(eRec, eInteractionRate, cutModus)) { + return false; + } + } + } + + // *) CurrentRunDuration: // TBI 20241128 check if I can use this one also on Run 2 and Run 1, most likely not + if (ec.fUseEventCuts[eCurrentRunDuration]) { + if (cutModus == eCutCounterBinning) { + EventCut(eRec, eCurrentRunDuration, eCutCounterBinning); + } else if (ebye.fCurrentRunDuration < ec.fdEventCuts[eCurrentRunDuration][eMin] || ebye.fCurrentRunDuration > ec.fdEventCuts[eCurrentRunDuration][eMax] || std::abs(ebye.fCurrentRunDuration - ec.fdEventCuts[eCurrentRunDuration][eMax]) < tc.fFloatingPointPrecision) { + if (!EventCut(eRec, eCurrentRunDuration, cutModus)) { + return false; + } + } + } + + // *) NoSameBunchPileup: // see O2Physics/Common/CCDB/EventSelectionParams.cxx (and .h for better documentation) + if (ec.fUseEventCuts[eNoSameBunchPileup]) { + if (cutModus == eCutCounterBinning) { + EventCut(eRec, eNoSameBunchPileup, eCutCounterBinning); + } else if (!collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) { + if (!EventCut(eRec, eNoSameBunchPileup, cutModus)) { + return false; + } + } + } + + // *) IsGoodZvtxFT0vsPV: // see O2Physics/Common/CCDB/EventSelectionParams.cxx (and .h for better documentation) + if (ec.fUseEventCuts[eIsGoodZvtxFT0vsPV]) { + if (cutModus == eCutCounterBinning) { + EventCut(eRec, eIsGoodZvtxFT0vsPV, eCutCounterBinning); + } else if (!collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) { + if (!EventCut(eRec, eIsGoodZvtxFT0vsPV, cutModus)) { + return false; + } + } + } + + // *) IsVertexITSTPC: // see O2Physics/Common/CCDB/EventSelectionParams.cxx (and .h for better documentation) + if (ec.fUseEventCuts[eIsVertexITSTPC]) { + if (cutModus == eCutCounterBinning) { + EventCut(eRec, eIsVertexITSTPC, eCutCounterBinning); + } else if (!collision.selection_bit(o2::aod::evsel::kIsVertexITSTPC)) { + if (!EventCut(eRec, eIsVertexITSTPC, cutModus)) { + return false; + } + } + } + + // *) IsVertexTOFmatched: // see O2Physics/Common/CCDB/EventSelectionParams.cxx (and .h for better documentation) + if (ec.fUseEventCuts[eIsVertexTOFmatched]) { + if (cutModus == eCutCounterBinning) { + EventCut(eRec, eIsVertexTOFmatched, eCutCounterBinning); + } else if (!collision.selection_bit(o2::aod::evsel::kIsVertexTOFmatched)) { + if (!EventCut(eRec, eIsVertexTOFmatched, cutModus)) { + return false; + } + } + } + + // *) IsVertexTRDmatched: // see O2Physics/Common/CCDB/EventSelectionParams.cxx (and .h for better documentation) + if (ec.fUseEventCuts[eIsVertexTRDmatched]) { + if (cutModus == eCutCounterBinning) { + EventCut(eRec, eIsVertexTRDmatched, eCutCounterBinning); + } else if (!collision.selection_bit(o2::aod::evsel::kIsVertexTRDmatched)) { + if (!EventCut(eRec, eIsVertexTRDmatched, cutModus)) { + return false; + } + } + } + + // *) NoCollInTimeRangeStrict: // see O2Physics/Common/CCDB/EventSelectionParams.cxx (and .h for better documentation) + if (ec.fUseEventCuts[eNoCollInTimeRangeStrict]) { + if (cutModus == eCutCounterBinning) { + EventCut(eRec, eNoCollInTimeRangeStrict, eCutCounterBinning); + } else if (!collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStrict)) { + if (!EventCut(eRec, eNoCollInTimeRangeStrict, cutModus)) { + return false; + } + } + } + + // *) NoCollInTimeRangeStandard: // see O2Physics/Common/CCDB/EventSelectionParams.cxx (and .h for better documentation) + if (ec.fUseEventCuts[eNoCollInTimeRangeStandard]) { + if (cutModus == eCutCounterBinning) { + EventCut(eRec, eNoCollInTimeRangeStandard, eCutCounterBinning); + } else if (!collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { + if (!EventCut(eRec, eNoCollInTimeRangeStandard, cutModus)) { + return false; + } + } + } + + // *) NoCollInRofStrict: // see O2Physics/Common/CCDB/EventSelectionParams.cxx (and .h for better documentation) + if (ec.fUseEventCuts[eNoCollInRofStrict]) { + if (cutModus == eCutCounterBinning) { + EventCut(eRec, eNoCollInRofStrict, eCutCounterBinning); + } else if (!collision.selection_bit(o2::aod::evsel::kNoCollInRofStrict)) { + if (!EventCut(eRec, eNoCollInRofStrict, cutModus)) { + return false; + } + } + } + + // *) NoCollInRofStandard: // see O2Physics/Common/CCDB/EventSelectionParams.cxx (and .h for better documentation) + if (ec.fUseEventCuts[eNoCollInRofStandard]) { + if (cutModus == eCutCounterBinning) { + EventCut(eRec, eNoCollInRofStandard, eCutCounterBinning); + } else if (!collision.selection_bit(o2::aod::evsel::kNoCollInRofStandard)) { + if (!EventCut(eRec, eNoCollInRofStandard, cutModus)) { + return false; + } + } + } + + // *) NoHighMultCollInPrevRof: // see O2Physics/Common/CCDB/EventSelectionParams.cxx (and .h for better documentation) + if (ec.fUseEventCuts[eNoHighMultCollInPrevRof]) { + if (cutModus == eCutCounterBinning) { + EventCut(eRec, eNoHighMultCollInPrevRof, eCutCounterBinning); + } else if (!collision.selection_bit(o2::aod::evsel::kNoHighMultCollInPrevRof)) { + if (!EventCut(eRec, eNoHighMultCollInPrevRof, cutModus)) { + return false; + } + } + } + + // *) IsGoodITSLayer3: // see O2Physics/Common/CCDB/EventSelectionParams.cxx (and .h for better documentation) + if (ec.fUseEventCuts[eIsGoodITSLayer3]) { + if (cutModus == eCutCounterBinning) { + EventCut(eRec, eIsGoodITSLayer3, eCutCounterBinning); + } else if (!collision.selection_bit(o2::aod::evsel::kIsGoodITSLayer3)) { + if (!EventCut(eRec, eIsGoodITSLayer3, cutModus)) { + return false; + } + } + } + + // *) IsGoodITSLayer0123: // see O2Physics/Common/CCDB/EventSelectionParams.cxx (and .h for better documentation) + if (ec.fUseEventCuts[eIsGoodITSLayer0123]) { + if (cutModus == eCutCounterBinning) { + EventCut(eRec, eIsGoodITSLayer0123, eCutCounterBinning); + } else if (!collision.selection_bit(o2::aod::evsel::kIsGoodITSLayer0123)) { + if (!EventCut(eRec, eIsGoodITSLayer0123, cutModus)) { + return false; + } + } + } + + // *) IsGoodITSLayersAll: // see O2Physics/Common/CCDB/EventSelectionParams.cxx (and .h for better documentation) + if (ec.fUseEventCuts[eIsGoodITSLayersAll]) { + if (cutModus == eCutCounterBinning) { + EventCut(eRec, eIsGoodITSLayersAll, eCutCounterBinning); + } else if (!collision.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { + if (!EventCut(eRec, eIsGoodITSLayersAll, cutModus)) { + return false; + } + } + } + + // *) FT0Bad: // see O2Physics/Common/CCDB/RCTSelectionFlags.h + if (ec.fUseEventCuts[eFT0Bad]) { + if (cutModus == eCutCounterBinning) { + EventCut(eRec, eFT0Bad, eCutCounterBinning); + } else if (collision.rct_bit(o2::aod::rctsel::kFT0Bad)) { + if (!EventCut(eRec, eFT0Bad, cutModus)) { + return false; + } + } + } + + // *) ITSBad: // see O2Physics/Common/CCDB/RCTSelectionFlags.h + if (ec.fUseEventCuts[eITSBad]) { + if (cutModus == eCutCounterBinning) { + EventCut(eRec, eITSBad, eCutCounterBinning); + } else if (collision.rct_bit(o2::aod::rctsel::kITSBad)) { + if (!EventCut(eRec, eITSBad, cutModus)) { + return false; + } + } + } + + // *) ITSLimAccMCRepr: // see O2Physics/Common/CCDB/RCTSelectionFlags.h + if (ec.fUseEventCuts[eITSLimAccMCRepr]) { + if (cutModus == eCutCounterBinning) { + EventCut(eRec, eITSLimAccMCRepr, eCutCounterBinning); + } else if (collision.rct_bit(o2::aod::rctsel::kITSLimAccMCRepr)) { + if (!EventCut(eRec, eITSLimAccMCRepr, cutModus)) { + return false; + } + } + } + + // *) TPCBadTracking: // see O2Physics/Common/CCDB/RCTSelectionFlags.h + if (ec.fUseEventCuts[eTPCBadTracking]) { + if (cutModus == eCutCounterBinning) { + EventCut(eRec, eTPCBadTracking, eCutCounterBinning); + } else if (collision.rct_bit(o2::aod::rctsel::kTPCBadTracking)) { + if (!EventCut(eRec, eTPCBadTracking, cutModus)) { + return false; + } + } + } + + // *) TPCLimAccMCRepr: // see O2Physics/Common/CCDB/RCTSelectionFlags.h + if (ec.fUseEventCuts[eTPCLimAccMCRepr]) { + if (cutModus == eCutCounterBinning) { + EventCut(eRec, eTPCLimAccMCRepr, eCutCounterBinning); + } else if (collision.rct_bit(o2::aod::rctsel::kTPCLimAccMCRepr)) { + if (!EventCut(eRec, eTPCLimAccMCRepr, cutModus)) { + return false; + } + } + } + + // *) TPCBadPID: // see O2Physics/Common/CCDB/RCTSelectionFlags.h + if (ec.fUseEventCuts[eTPCBadPID]) { + if (cutModus == eCutCounterBinning) { + EventCut(eRec, eTPCBadPID, eCutCounterBinning); + } else if (collision.rct_bit(o2::aod::rctsel::kTPCBadPID)) { + if (!EventCut(eRec, eTPCBadPID, cutModus)) { + return false; + } + } + } + + // ... + + // *) Centrality weights (flattening): + // Remark 1: Since I am getting centrality weights from centrality distribution AFTER all the events cuts, flattening must be applied here after all other event cuts: + // Remark 2: Whatever I change here, change also in the corresponding branch for Run 2 and Run 1. + // Yes, I have to replicate for this special event cut the same code, since in each case it has to be applied at the very end. + if (ec.fUseEventCuts[eCentralityWeights]) { + if (cutModus == eCutCounterBinning) { + EventCut(eRec, eCentralityWeights, eCutCounterBinning); + } else if (gRandom->Uniform(0, 1) > CentralityWeight(ebye.fCentrality)) { // yes, since centralityWeight is normalized probability (see CentralityWeight(...)) + if (!EventCut(eRec, eCentralityWeights, cutModus)) { + return false; + } + } + } + + // Remark: If I need any further event cut, implement it BEFORE event cut "Centrality weights (flattening)", which must be implemented last. + + // ... and corresponding MC truth simulated (Run 3 specific): + // See https://github.com/AliceO2Group/O2Physics/blob/master/Tutorials/src/mcHistograms.cxx + // See https://aliceo2group.github.io/analysis-framework/docs/datamodel/ao2dTables.html#montecarlo + if constexpr (rs == eRecAndSim) { + if (!collision.has_mcCollision()) { + LOGF(warning, "\033[1;31m%s at line %d : No MC collision for this collision, skip... \033[0m", __FUNCTION__, __LINE__); // TBI 20231106 re-think. I shouldn't probably get to this point, if MC truth info doesn't exist for this collision + return false; + } + + // In this branch I can cut additionally and directly on corresponding MC truth simulated. + // Remark: I implement here only the event cuts which are not already in group a) above, and which make sense only for Run 3 data. + // In case I implement something here, remember to switch from eRec to eSim when calling e.g. EventCut(...) + + // ... + + } // if constexpr (rs == eRecAndSim) { + + } // if constexpr (rs == eRec || rs == eRecAndSim) { + + // ------------------------------------------------------------------------- + + // d) Event cuts on simulated (Run 3 specific): + // Remark #1: I implement here only the event cuts which are not already in group b) above, and which make sense only for Run 3 data. + // Remark #2: In this branch 'collision' is always o2::aod::McCollision, see https://aliceo2group.github.io/analysis-framework/docs/datamodel/ao2dTables.html#montecarlo + // See how I handled the case b) above. + if constexpr (rs == eSim) { + + // ... + + } // if constexpr (rs == eSim) { + + // ------------------------------------------------------------------------- + + // e) Event cuts on reconstructed, and corresponding MC truth simulated (Run 1 and 2 specific): + // Remark: I implement here only the event cuts which are not already in group a) above, and which make sense only for Run 1 and 2 data. + if constexpr (rs == eRec_Run2 || rs == eRecAndSim_Run2 || rs == eRec_Run1 || rs == eRecAndSim_Run1) { + + // *) Sel7: + if (ec.fUseEventCuts[eSel7]) { + if (cutModus == eCutCounterBinning) { + EventCut(eRec, eSel7, eCutCounterBinning); + } else if (!collision.sel7()) { + if (!EventCut(eRec, eSel7, cutModus)) { + return false; + } + } + } + + // *) NoPileupTPC: // see O2Physics/Common/CCDB/EventSelectionParams.cxx (and .h for better documentation) + if (ec.fUseEventCuts[eNoPileupTPC]) { + if (cutModus == eCutCounterBinning) { + EventCut(eRec, eNoPileupTPC, eCutCounterBinning); + } else if (!collision.selection_bit(o2::aod::evsel::kNoPileupTPC)) { + if (!EventCut(eRec, eNoPileupTPC, cutModus)) { + return false; + } + } + } + + // *) NoPileupFromSPD: // see O2Physics/Common/CCDB/EventSelectionParams.cxx (and .h for better documentation) + if (ec.fUseEventCuts[eNoPileupFromSPD]) { + if (cutModus == eCutCounterBinning) { + EventCut(eRec, eNoPileupFromSPD, eCutCounterBinning); + } else if (!collision.selection_bit(o2::aod::evsel::kNoPileupFromSPD)) { + if (!EventCut(eRec, eNoPileupFromSPD, cutModus)) { + return false; + } + } + } + + // *) NoSPDOnVsOfPileup: // see O2Physics/Common/CCDB/EventSelectionParams.cxx (and .h for better documentation) + if (ec.fUseEventCuts[eNoSPDOnVsOfPileup]) { + if (cutModus == eCutCounterBinning) { + EventCut(eRec, eNoSPDOnVsOfPileup, eCutCounterBinning); + } else if (!collision.selection_bit(o2::aod::evsel::kNoSPDOnVsOfPileup)) { + if (!EventCut(eRec, eNoSPDOnVsOfPileup, cutModus)) { + return false; + } + } + } + + // ... + + // *) Centrality weights (flattening): + // Remark 1: Since I am getting centrality weights from centrality distribution AFTER all the events cuts, flattening must be applied here after all other event cuts: + // Remark 2: Whatever I change here, change also in the corresponding branch for Run 3. + // Yes, I have to replicate for this special event cut the same code, since in each case it has to be applied at the very end. + if (ec.fUseEventCuts[eCentralityWeights]) { + if (cutModus == eCutCounterBinning) { + EventCut(eRec, eCentralityWeights, eCutCounterBinning); + } else if (gRandom->Uniform(0, 1) > CentralityWeight(ebye.fCentrality)) { // yes, since centralityWeight is normalized probability (see CentralityWeight(...)) + if (!EventCut(eRec, eCentralityWeights, cutModus)) { + return false; + } + } + } + + // Remark: If I need any further event cut, implement it BEFORE event cut "Centrality weights (flattening)", which must be implemented last. + + // ... and corresponding MC truth simulated: + // See https://github.com/AliceO2Group/O2Physics/blob/master/Tutorials/src/mcHistograms.cxx + // See https://aliceo2group.github.io/analysis-framework/docs/datamodel/ao2dTables.html#montecarlo + if constexpr (rs == eRecAndSim_Run2 || rs == eRecAndSim_Run1) { + if (!collision.has_mcCollision()) { + LOGF(warning, "\033[1;31m%s at line %d : No MC collision for this collision, skip... \033[0m", __FUNCTION__, __LINE__); // TBI 20231106 re-think. I shouldn't probably get to this point, if MC truth info doesn't exist for this collision + return false; + } + + // In this branch I can cut additionally and directly on corresponding MC truth simulated. + // Remark: I implement here only the event cuts which are not already in group a) above, and which make sense only for Run 1 and 2 data. + // In case I implement something here, remember to switch from eRec to eSim when calling e.g. EventCut(...) + + // ... + + } // if constexpr (rs == eRecAndSim_Run2 || rs == eRecAndSim_Run1) { + + } // if constexpr (rs == eRec_Run2 || rs == eRecAndSim_Run2 || rs == eRec_Run1 || rs == eRecAndSim_Run1) { + + // ------------------------------------------------------------------------- + + // f) Event cuts on simulated (Run 1 and 2 specific) + // Remark #1: I implement here only the event cuts which are not already in group b) above, and which make sense only for Run 1 and 2 data. + // Remark #2: In this branch 'collision' is always o2::aod::McCollision, see https://aliceo2group.github.io/analysis-framework/docs/datamodel/ao2dTables.html#montecarlo + // See how I handled the case b) above. + if constexpr (rs == eSim_Run2 || rs == eSim_Run1) { + + // ... + + } // if constexpr (rs == eSim_Run2 || rs == eSim_Run1) { + + // ------------------------------------------------------------------------- + + // *) Test case: + if constexpr (rs == eTest) { + // This branch corresponds to process with minimal subscription - I implement just a few example cuts, just for testing purposes. + // Only eRec is support in Test for the time being. + + // *) TotalMultiplicity: + if (ec.fUseEventCuts[eTotalMultiplicity]) { + if (cutModus == eCutCounterBinning) { + EventCut(eRec, eTotalMultiplicity, eCutCounterBinning); + } else if (tracks.size() < ec.fdEventCuts[eTotalMultiplicity][eMin] || tracks.size() > ec.fdEventCuts[eTotalMultiplicity][eMax] || std::abs(tracks.size() - ec.fdEventCuts[eTotalMultiplicity][eMax]) < tc.fFloatingPointPrecision) { + if (!EventCut(eRec, eTotalMultiplicity, cutModus)) { + return false; + } + } + } + + // *) VertexZ: + if (ec.fUseEventCuts[eVertexZ]) { + if (cutModus == eCutCounterBinning) { + EventCut(eRec, eVertexZ, eCutCounterBinning); + } else if (collision.posZ() < ec.fdEventCuts[eVertexZ][eMin] || collision.posZ() > ec.fdEventCuts[eVertexZ][eMax] || std::abs(collision.posZ() - ec.fdEventCuts[eVertexZ][eMax]) < tc.fFloatingPointPrecision) { + if (!EventCut(eRec, eVertexZ, cutModus)) { + return false; + } + } + } + + // *) Centrality: + if (ec.fUseEventCuts[eCentrality]) { + if (cutModus == eCutCounterBinning) { + EventCut(eRec, eCentrality, eCutCounterBinning); + } else if (ebye.fCentrality < ec.fdEventCuts[eCentrality][eMin] || ebye.fCentrality > ec.fdEventCuts[eCentrality][eMax] || std::abs(ebye.fCentrality - ec.fdEventCuts[eCentrality][eMax]) < tc.fFloatingPointPrecision) { + if (!EventCut(eRec, eCentrality, cutModus)) { + return false; + } + } + } + + // ... + + } // if constexpr (rs == eTest) { + + return true; + + } // template bool EventCuts(T1 const& collision, T2 const& tracks) + + //============================================================ + + bool EventCut(int rs, int eventCut, eCutModus cutModus) + { + // Helper function to reduce code bloat in EventCuts(). It's meant to be used only in EventCuts(). + // It can be used also in exceptional cases outside of EventCuts(), like for eMultiplicity, but use with care. + // For instance, I can call EventCut(eRec, eCentrality, eCutCounterSequential) directly, only if I have checked that + // fUseEventCutCounterSequential is true, etc. + + // Remark: Remember that as a second argument I cannot use enum eEventCuts, because here in one go I take both enum eEventCuts and enum eEventHistograms . + + // *) Insanity checks on arguments: + if (!(0 == rs || 1 == rs)) { + LOGF(fatal, "\033[1;31m%s at line %d : 'rs' must be generic Rec or Sim index, rs = %d \033[0m", __FUNCTION__, __LINE__, rs); + } + if (eventCut >= eEventCuts_N) { + LOGF(fatal, "\033[1;31m%s at line %d : eventCut >= eEventCuts_N, eventCut = %d , eEventCuts_N = %d \033[0m", __FUNCTION__, __LINE__, eventCut, static_cast(eEventCuts_N)); + } + + // *) Do the thing: + switch (cutModus) { + case eCut: { + if (tc.fVerboseEventCut) { + LOGF(info, "\033[1;31mEvent didn't survive the cut: %s\033[0m", ec.fEventCutName[eventCut].Data()); + } + return false; + break; + } + case eCutCounterBinning: { + ec.fEventCutCounterMap[rs]->Add(ec.fEventCutCounterBinNumber[rs], eventCut); + ec.fEventCutCounterMapInverse[rs]->Add(eventCut, ec.fEventCutCounterBinNumber[rs]); + ec.fEventCutCounterBinNumber[rs]++; // yes + return true; + break; + } + case eCutCounterAbsolute: { + ec.fEventCutCounterHist[rs][eAbsolute]->Fill(ec.fEventCutCounterMapInverse[rs]->GetValue(eventCut)); + return true; // yes, so that I can proceed with another cut in EventCuts + break; + } + case eCutCounterSequential: { + ec.fEventCutCounterHist[rs][eSequential]->Fill(ec.fEventCutCounterMapInverse[rs]->GetValue(eventCut)); + return false; // yes, so that I bail out from EventCuts + break; + } + default: { + LOGF(fatal, "\033[1;31m%s at line %d : This cutModus = %d is not supported yet. \033[0m", __FUNCTION__, __LINE__, static_cast(cutModus)); + break; + } + } // switch(cutModus) + + return false; // obsolete, but it suppresses the warning... + + } // bool EventCut(int rs, int eventCut, eCutModus cutModus) + + //============================================================ + + bool RemainingEventCuts() + { + // Remaining event cuts which can be applied ONLY after the main loop over particles. + // For instance, cut on total number of selected particles (eMultiplicity). + // Remark #1: Whichever cut I implement here, update EventCutsCounters(...) for that cut (like I did for eMultiplicity, as a sort of template). + // Remark #2: I do not have here templated arguments like in EventCuts(), because I do not anticipate using any getter from the framework directly here. + // Remark #3: With the current implementation, I support here only eCutCounterSequential, i.e. eCutCounterAbsolute is not supported for cuts applied here. + + // a) Determine if this function was called for generic rec or generic sim: + // *) eMultiplicity; + // ... + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // a) Determine if this function was called for generic rec or generic sim: + // Remark: I can do it in this simplified way, because I do not anticipate I will call here any getters from the framework. + int rs = -1; + if (tc.fProcess[eGenericRec] || tc.fProcess[eGenericRecSim]) { + rs = eRec; // yes, I do not count in RecSim mode separately particles and rec and sim level which survived particle cuts + } else if (tc.fProcess[eGenericSim]) { + rs = eSim; + } + + // *) Multiplicity: (see documentation for ebye.fMultiplicity for its definition) + if (ec.fUseEventCuts[eMultiplicity]) { + if (ebye.fMultiplicity < ec.fdEventCuts[eMultiplicity][eMin] || ebye.fMultiplicity > ec.fdEventCuts[eMultiplicity][eMax] || std::abs(ebye.fMultiplicity - ec.fdEventCuts[eMultiplicity][eMax]) < tc.fFloatingPointPrecision) { + // Remark: I have to implement RemainingEventCuts() in a slightly different way as EventCuts() + EventCut(rs, eMultiplicity, eCut); // just a printout that this event didn't survive this cut + if (ec.fUseEventCutCounterSequential) { // yes, this is important. Otherwise fEventCutCounterHist can be used in EventCut(...), even though it's NULL + EventCut(rs, eMultiplicity, eCutCounterSequential); + } + return false; + } + } + + return true; + + } // bool RemainingEventCuts() + + //============================================================ + + template + void FillSubeventMultiplicities() + { + // Fill subevent (defined via eta separation) multiplicities. + + // a) Fill reconstructed (common to Run 3, Run 2 and Run 1 + Test mode); + // b) Fill only simulated (common to Run 3, Run 2 and Run 1). + + // Remark: This function has to be called after Q-vectors are filled. It makes sense to fill these histograms only for "eAfter", + // becase Q-vectors are not filled before the event cuts. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // a) Fill reconstructed (common to Run 3, Run 2 and Run 1 + Test mode): + if constexpr (rs == eRec || rs == eRecAndSim || rs == eRec_Run2 || rs == eRecAndSim_Run2 || rs == eRec_Run1 || rs == eRecAndSim_Run1 || rs == eTest || rs == eQA) { + for (int ab = 0; ab < 2; ab++) { // ab = 0 <=> -eta , ab = 1 <=> + eta + for (int e = 0; e < gMaxNumberEtaSeparations; e++) { // eta separation + !qv.fMabDist[ab][eRec][eAfter][e] ? true : qv.fMabDist[ab][eRec][eAfter][e]->Fill(qv.fMab[ab][e]); + } + } + } + + // b) Fill only simulated (common to Run 3, Run 2 and Run 1): + if constexpr (rs == eSim || rs == eSim_Run2 || rs == eSim_Run1) { + for (int ab = 0; ab < 2; ab++) { // ab = 0 <=> -eta , ab = 1 <=> + eta + for (int e = 0; e < gMaxNumberEtaSeparations; e++) { // eta separation + !qv.fMabDist[ab][eSim][eAfter][e] ? true : qv.fMabDist[ab][eSim][eAfter][e]->Fill(qv.fMab[ab][e]); + } + } + } + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // void FillSubeventMultiplicities() + + //============================================================ + + template + void FillEventHistograms(T1 const& collision, T2 const& tracks, eBeforeAfter ba) + { + // Fill all event histograms for reconstructed or simulated data. QA event histograms are also filled here. + + // a) Fill reconstructed, and corresponding MC truth simulated (common to Run 3, Run 2 and Run 1); + // b) Fill only simulated (common to Run 3, Run 2 and Run 1); + // c) Fill reconstructed (Run 3 specific); + // d) Fill only simulated (Run 3 specific); + // e) Fill reconstructed (Run 1 and 2 specific); // In case there is some corner case between Run 1 and Run 2, simply branch further this one + // f) Fill only simulated (Run 1 and 2 specific); // In case there is some corner case between Run 1 and Run 2, simply branch further this one + // g) Test case. + + // Remark: in most cases, all histogram which depend on eMultiplicity are booked only for "after", because by default, Multiplicity = SelectedTracks. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // a) Fill reconstructed ... (common to Run 3, Run 2 and Run 1): + if constexpr (rs == eRec || rs == eRecAndSim || rs == eRec_Run2 || rs == eRecAndSim_Run2 || rs == eRec_Run1 || rs == eRecAndSim_Run1 || rs == eQA) { + if (eh.fFillEventHistograms) { + !eh.fEventHistograms[eNumberOfEvents][eRec][ba] ? true : eh.fEventHistograms[eNumberOfEvents][eRec][ba]->Fill(0.5); // basically, if histogram is not booked, do nothing. 'true' is a placeholder, for the time being + !eh.fEventHistograms[eVertexX][eRec][ba] ? true : eh.fEventHistograms[eVertexX][eRec][ba]->Fill(collision.posX()); + !eh.fEventHistograms[eVertexY][eRec][ba] ? true : eh.fEventHistograms[eVertexY][eRec][ba]->Fill(collision.posY()); + !eh.fEventHistograms[eVertexZ][eRec][ba] ? true : eh.fEventHistograms[eVertexZ][eRec][ba]->Fill(collision.posZ()); + !eh.fEventHistograms[eNContributors][eRec][ba] ? true : eh.fEventHistograms[eNContributors][eRec][ba]->Fill(collision.numContrib()); + !eh.fEventHistograms[eTotalMultiplicity][eRec][ba] ? true : eh.fEventHistograms[eTotalMultiplicity][eRec][ba]->Fill(tracks.size()); // TBI 20231106 check and validate further + !eh.fEventHistograms[eMultiplicity][eRec][ba] ? true : eh.fEventHistograms[eMultiplicity][eRec][ba]->Fill(ebye.fMultiplicity); + !eh.fEventHistograms[eReferenceMultiplicity][eRec][ba] ? true : eh.fEventHistograms[eReferenceMultiplicity][eRec][ba]->Fill(ebye.fReferenceMultiplicity); + !eh.fEventHistograms[eCentrality][eRec][ba] ? true : eh.fEventHistograms[eCentrality][eRec][ba]->Fill(ebye.fCentrality); + } + + // QA: + if (qa.fFillQAEventHistograms2D) { + !qa.fQAEventHistograms2D[eMultiplicity_vs_ReferenceMultiplicity][eRec][ba] ? true : qa.fQAEventHistograms2D[eMultiplicity_vs_ReferenceMultiplicity][eRec][ba]->Fill(ebye.fMultiplicity, ebye.fReferenceMultiplicity); + !qa.fQAEventHistograms2D[eMultiplicity_vs_NContributors][eRec][ba] ? true : qa.fQAEventHistograms2D[eMultiplicity_vs_NContributors][eRec][ba]->Fill(ebye.fMultiplicity, collision.numContrib()); + !qa.fQAEventHistograms2D[eMultiplicity_vs_Centrality][eRec][ba] ? true : qa.fQAEventHistograms2D[eMultiplicity_vs_Centrality][eRec][ba]->Fill(ebye.fMultiplicity, ebye.fCentrality); + !qa.fQAEventHistograms2D[eMultiplicity_vs_VertexZ][eRec][ba] ? true : qa.fQAEventHistograms2D[eMultiplicity_vs_VertexZ][eRec][ba]->Fill(ebye.fMultiplicity, collision.posZ()); + !qa.fQAEventHistograms2D[eReferenceMultiplicity_vs_NContributors][eRec][ba] ? true : qa.fQAEventHistograms2D[eReferenceMultiplicity_vs_NContributors][eRec][ba]->Fill(ebye.fReferenceMultiplicity, collision.numContrib()); + !qa.fQAEventHistograms2D[eReferenceMultiplicity_vs_Centrality][eRec][ba] ? true : qa.fQAEventHistograms2D[eReferenceMultiplicity_vs_Centrality][eRec][ba]->Fill(ebye.fReferenceMultiplicity, ebye.fCentrality); + !qa.fQAEventHistograms2D[eReferenceMultiplicity_vs_VertexZ][eRec][ba] ? true : qa.fQAEventHistograms2D[eReferenceMultiplicity_vs_VertexZ][eRec][ba]->Fill(ebye.fReferenceMultiplicity, collision.posZ()); + !qa.fQAEventHistograms2D[eNContributors_vs_Centrality][eRec][ba] ? true : qa.fQAEventHistograms2D[eNContributors_vs_Centrality][eRec][ba]->Fill(collision.numContrib(), ebye.fCentrality); + !qa.fQAEventHistograms2D[eNContributors_vs_VertexZ][eRec][ba] ? true : qa.fQAEventHistograms2D[eNContributors_vs_VertexZ][eRec][ba]->Fill(collision.numContrib(), collision.posZ()); + !qa.fQAEventHistograms2D[eCentrality_vs_VertexZ][eRec][ba] ? true : qa.fQAEventHistograms2D[eCentrality_vs_VertexZ][eRec][ba]->Fill(ebye.fCentrality, collision.posZ()); + } + + if (qa.fFillQACorrelationsVsHistograms2D && qa.fQAParticleEventProEbyE[eRec][ba] && ba == eAfter) { // fill only for eAfter, because I do not calculate Q-vectors before cuts + + // Calculate quickly 2-p correlation in harmonic h for this event: TBI 20250114 shall I add this also to some EbyE variable? There is no really much of a code bloat for the time being... + + // Flush 'n' fill the generic Q-vectors: + ResetQ(); + int lMaxCorrelator = 2; // used only here locally + for (int h = 0; h < gMaxHarmonic * lMaxCorrelator + 1; h++) { + for (int wp = 0; wp < lMaxCorrelator + 1; wp++) // weight power + { + qv.fQ[h][wp] = qv.fQvector[h][wp]; + } + } + + for (int h = 1; h <= gMaxHarmonic; h++) { + TComplex two = Two(h, -h); + double twoC = two.Re(); // cos + // double twoS = two.Im(); // sin + double wTwo = Two(0, 0).Re(); // Weight is 'number of combinations' by default TBI + // 20220809 add support for other weights + if (!(wTwo > 0.0)) { + LOGF(fatal, "In function \033[1;31m%s at line %d : wTwo = %f <=0. ebye.fSelectedTracks = %d.\nDid you forget to enable fCalculateQvectors = true?\033[0m", __FUNCTION__, __LINE__, wTwo, ebye.fSelectedTracks); + } + !qa.fQACorrelationsVsHistograms2D[eCorrelations_vs_Multiplicity][h - 1][eRec] ? true : qa.fQACorrelationsVsHistograms2D[eCorrelations_vs_Multiplicity][h - 1][eRec]->Fill(twoC / wTwo, ebye.fMultiplicity, wTwo); + !qa.fQACorrelationsVsHistograms2D[eCorrelations_vs_ReferenceMultiplicity][h - 1][eRec] ? true : qa.fQACorrelationsVsHistograms2D[eCorrelations_vs_ReferenceMultiplicity][h - 1][eRec]->Fill(twoC / wTwo, ebye.fReferenceMultiplicity, wTwo); + !qa.fQACorrelationsVsHistograms2D[eCorrelations_vs_Centrality][h - 1][eRec] ? true : qa.fQACorrelationsVsHistograms2D[eCorrelations_vs_Centrality][h - 1][eRec]->Fill(twoC / wTwo, ebye.fCentrality, wTwo); + // ..... + !qa.fQACorrelationsVsHistograms2D[eCorrelations_vs_MeanPhi][h - 1][eRec] ? true : qa.fQACorrelationsVsHistograms2D[eCorrelations_vs_MeanPhi][h - 1][eRec]->Fill(twoC / wTwo, qa.fQAParticleEventProEbyE[eRec][ba]->GetBinContent(eMeanPhi), wTwo); + !qa.fQACorrelationsVsHistograms2D[eCorrelations_vs_MeanPt][h - 1][eRec] ? true : qa.fQACorrelationsVsHistograms2D[eCorrelations_vs_MeanPt][h - 1][eRec]->Fill(twoC / wTwo, qa.fQAParticleEventProEbyE[eRec][ba]->GetBinContent(eMeanPt), wTwo); + !qa.fQACorrelationsVsHistograms2D[eCorrelations_vs_MeanEta][h - 1][eRec] ? true : qa.fQACorrelationsVsHistograms2D[eCorrelations_vs_MeanEta][h - 1][eRec]->Fill(twoC / wTwo, qa.fQAParticleEventProEbyE[eRec][ba]->GetBinContent(eMeanEta), wTwo); + !qa.fQACorrelationsVsHistograms2D[eCorrelations_vs_MeanCharge][h - 1][eRec] ? true : qa.fQACorrelationsVsHistograms2D[eCorrelations_vs_MeanCharge][h - 1][eRec]->Fill(twoC / wTwo, qa.fQAParticleEventProEbyE[eRec][ba]->GetBinContent(eMeanCharge), wTwo); + !qa.fQACorrelationsVsHistograms2D[eCorrelations_vs_MeantpcNClsFindable][h - 1][eRec] ? true : qa.fQACorrelationsVsHistograms2D[eCorrelations_vs_MeantpcNClsFindable][h - 1][eRec]->Fill(twoC / wTwo, qa.fQAParticleEventProEbyE[eRec][ba]->GetBinContent(eMeantpcNClsFindable), wTwo); + !qa.fQACorrelationsVsHistograms2D[eCorrelations_vs_MeantpcNClsShared][h - 1][eRec] ? true : qa.fQACorrelationsVsHistograms2D[eCorrelations_vs_MeantpcNClsShared][h - 1][eRec]->Fill(twoC / wTwo, qa.fQAParticleEventProEbyE[eRec][ba]->GetBinContent(eMeantpcNClsShared), wTwo); + !qa.fQACorrelationsVsHistograms2D[eCorrelations_vs_MeanitsChi2NCl][h - 1][eRec] ? true : qa.fQACorrelationsVsHistograms2D[eCorrelations_vs_MeanitsChi2NCl][h - 1][eRec]->Fill(twoC / wTwo, qa.fQAParticleEventProEbyE[eRec][ba]->GetBinContent(eMeanitsChi2NCl), wTwo); + !qa.fQACorrelationsVsHistograms2D[eCorrelations_vs_MeantpcNClsFound][h - 1][eRec] ? true : qa.fQACorrelationsVsHistograms2D[eCorrelations_vs_MeantpcNClsFound][h - 1][eRec]->Fill(twoC / wTwo, qa.fQAParticleEventProEbyE[eRec][ba]->GetBinContent(eMeantpcNClsFound), wTwo); + !qa.fQACorrelationsVsHistograms2D[eCorrelations_vs_MeantpcNClsCrossedRows][h - 1][eRec] ? true : qa.fQACorrelationsVsHistograms2D[eCorrelations_vs_MeantpcNClsCrossedRows][h - 1][eRec]->Fill(twoC / wTwo, qa.fQAParticleEventProEbyE[eRec][ba]->GetBinContent(eMeantpcNClsCrossedRows), wTwo); + !qa.fQACorrelationsVsHistograms2D[eCorrelations_vs_MeanitsNCls][h - 1][eRec] ? true : qa.fQACorrelationsVsHistograms2D[eCorrelations_vs_MeanitsNCls][h - 1][eRec]->Fill(twoC / wTwo, qa.fQAParticleEventProEbyE[eRec][ba]->GetBinContent(eMeanitsNCls), wTwo); + !qa.fQACorrelationsVsHistograms2D[eCorrelations_vs_MeanitsNClsInnerBarrel][h - 1][eRec] ? true : qa.fQACorrelationsVsHistograms2D[eCorrelations_vs_MeanitsNClsInnerBarrel][h - 1][eRec]->Fill(twoC / wTwo, qa.fQAParticleEventProEbyE[eRec][ba]->GetBinContent(eMeanitsNClsInnerBarrel), wTwo); + !qa.fQACorrelationsVsHistograms2D[eCorrelations_vs_MeantpcCrossedRowsOverFindableCls][h - 1][eRec] ? true : qa.fQACorrelationsVsHistograms2D[eCorrelations_vs_MeantpcCrossedRowsOverFindableCls][h - 1][eRec]->Fill(twoC / wTwo, qa.fQAParticleEventProEbyE[eRec][ba]->GetBinContent(eMeantpcCrossedRowsOverFindableCls), wTwo); + !qa.fQACorrelationsVsHistograms2D[eCorrelations_vs_MeantpcFoundOverFindableCls][h - 1][eRec] ? true : qa.fQACorrelationsVsHistograms2D[eCorrelations_vs_MeantpcFoundOverFindableCls][h - 1][eRec]->Fill(twoC / wTwo, qa.fQAParticleEventProEbyE[eRec][ba]->GetBinContent(eMeantpcFoundOverFindableCls), wTwo); + !qa.fQACorrelationsVsHistograms2D[eCorrelations_vs_MeantpcFractionSharedCls][h - 1][eRec] ? true : qa.fQACorrelationsVsHistograms2D[eCorrelations_vs_MeantpcFractionSharedCls][h - 1][eRec]->Fill(twoC / wTwo, qa.fQAParticleEventProEbyE[eRec][ba]->GetBinContent(eMeantpcFractionSharedCls), wTwo); + !qa.fQACorrelationsVsHistograms2D[eCorrelations_vs_MeantpcChi2NCl][h - 1][eRec] ? true : qa.fQACorrelationsVsHistograms2D[eCorrelations_vs_MeantpcChi2NCl][h - 1][eRec]->Fill(twoC / wTwo, qa.fQAParticleEventProEbyE[eRec][ba]->GetBinContent(eMeantpcChi2NCl), wTwo); + !qa.fQACorrelationsVsHistograms2D[eCorrelations_vs_MeandcaXY][h - 1][eRec] ? true : qa.fQACorrelationsVsHistograms2D[eCorrelations_vs_MeandcaXY][h - 1][eRec]->Fill(twoC / wTwo, qa.fQAParticleEventProEbyE[eRec][ba]->GetBinContent(eMeandcaXY), wTwo); + !qa.fQACorrelationsVsHistograms2D[eCorrelations_vs_MeandcaZ][h - 1][eRec] ? true : qa.fQACorrelationsVsHistograms2D[eCorrelations_vs_MeandcaZ][h - 1][eRec]->Fill(twoC / wTwo, qa.fQAParticleEventProEbyE[eRec][ba]->GetBinContent(eMeandcaZ), wTwo); + // ..... + } + + // Flush the generic Q-vectors: + ResetQ(); + + } // if (qa.fFillQACorrelationsVsHistograms2D && qa.fQAParticleEventProEbyE[eRec][ba] && ba == eAfter) + + // ... + + // ... and corresponding MC truth simulated (common to Run 3, Run 2 and Run 1) ( see https://github.com/AliceO2Group/O2Physics/blob/master/Tutorials/src/mcHistograms.cxx ): + if constexpr (rs == eRecAndSim || rs == eRecAndSim_Run2 || rs == eRecAndSim_Run1) { + if (!collision.has_mcCollision()) { + LOGF(warning, "\033[1;31m%s at line %d : No MC collision for this collision, skip... \033[0m", __FUNCTION__, __LINE__); + return; + } + if (eh.fFillEventHistograms) { + !eh.fEventHistograms[eNumberOfEvents][eSim][ba] ? true : eh.fEventHistograms[eNumberOfEvents][eSim][ba]->Fill(0.5); + !eh.fEventHistograms[eVertexX][eSim][ba] ? true : eh.fEventHistograms[eVertexX][eSim][ba]->Fill(collision.mcCollision().posX()); + !eh.fEventHistograms[eVertexY][eSim][ba] ? true : eh.fEventHistograms[eVertexY][eSim][ba]->Fill(collision.mcCollision().posY()); + !eh.fEventHistograms[eVertexZ][eSim][ba] ? true : eh.fEventHistograms[eVertexZ][eSim][ba]->Fill(collision.mcCollision().posZ()); + !eh.fEventHistograms[eImpactParameter][eSim][ba] ? true : eh.fEventHistograms[eImpactParameter][eSim][ba]->Fill(collision.mcCollision().impactParameter()); + !eh.fEventHistograms[eEventPlaneAngle][eSim][ba] ? true : eh.fEventHistograms[eEventPlaneAngle][eSim][ba]->Fill(collision.mcCollision().eventPlaneAngle()); + // eh.fEventHistograms[eTotalMultiplicity][eSim][ba]->Fill(tracks.size()); // TBI 20231106 check how to get corresponding MC truth info, and validate further + // eh.fEventHistograms[eMultiplicity][eSim][ba]->Fill(ebye.fMultiplicity); // TBI 20241123 re-think if I really need it here. If yes, most likely I will have to + // generalize fSelectedTracks to an array, to counter separately selected sim particles + !eh.fEventHistograms[eCentrality][eSim][ba] ? true : eh.fEventHistograms[eCentrality][eSim][ba]->Fill(ebye.fCentralitySim); + } + + // QA: + if (qa.fFillQAEventHistograms2D) { + !qa.fQAEventHistograms2D[eCentrality_vs_ImpactParameter][eSim][ba] ? true : qa.fQAEventHistograms2D[eCentrality_vs_ImpactParameter][eSim][ba]->Fill(ebye.fCentrality, collision.mcCollision().impactParameter()); + !qa.fQAEventHistograms2D[eCentrality_vs_CentralitySim][eSim][ba] ? true : qa.fQAEventHistograms2D[eCentrality_vs_CentralitySim][eSim][ba]->Fill(ebye.fCentrality, ebye.fCentralitySim); + // ... + } + } // if constexpr (rs == eRecAndSim) { + } // if constexpr (rs == eRec || rs == eRecAndSim) { + + // ----------------------------------------------------------------------------- + + // b) Fill only simulated (common to Run 3, Run 2 and Run 1): + if constexpr (rs == eSim || rs == eSim_Run2 || rs == eSim_Run1) { + if (eh.fFillEventHistograms) { + !eh.fEventHistograms[eImpactParameter][eSim][ba] ? true : eh.fEventHistograms[eImpactParameter][eSim][ba]->Fill(collision.impactParameter()); // yes, because in this branch 'collision' is always aod::McCollision + !eh.fEventHistograms[eEventPlaneAngle][eSim][ba] ? true : eh.fEventHistograms[eEventPlaneAngle][eSim][ba]->Fill(collision.eventPlaneAngle()); // yes, because in this branch 'collision' is always aod::McCollision + !eh.fEventHistograms[eMultiplicity][eSim][ba] ? true : eh.fEventHistograms[eMultiplicity][eSim][ba]->Fill(ebye.fMultiplicity); + !eh.fEventHistograms[eCentrality][eSim][ba] ? true : eh.fEventHistograms[eCentrality][eSim][ba]->Fill(ebye.fCentrality); // ebye.fCentrality = ebye.fCentralitySim in any case in this branch + // eh.fEventHistograms[eReferenceMultiplicity][eSim][ba]->Fill(ebye.fReferenceMultiplicity); // TBI 20241123 this case is still not supported in DetermineReferenceMultiplicity() + // eh.fEventHistograms[eTotalMultiplicity][eSim][ba]->Fill(tracks.size()); // TBI 20231030 check further how to use the same thing for 'sim' + } + + // Eta separations: + if (es.fCalculateEtaSeparations) { + for (int ab = 0; ab < 2; ab++) { // ab = 0 <=> -eta , ab = 1 <=> + eta + for (int e = 0; e < gMaxNumberEtaSeparations; e++) { // eta separation + !qv.fMabDist[ab][eSim][ba][e] ? true : qv.fMabDist[ab][eSim][ba][e]->Fill(qv.fMab[ab][e]); + } + } + } + } + + // ----------------------------------------------------------------------------- + + // c) Fill reconstructed (Run 3 specific): + if constexpr (rs == eRec || rs == eRecAndSim || rs == eQA) { + if (eh.fFillEventHistograms) { + !eh.fEventHistograms[eOccupancy][eRec][ba] ? true : eh.fEventHistograms[eOccupancy][eRec][ba]->Fill(ebye.fOccupancy); + !eh.fEventHistograms[eInteractionRate][eRec][ba] ? true : eh.fEventHistograms[eInteractionRate][eRec][ba]->Fill(ebye.fInteractionRate); + !eh.fEventHistograms[eCurrentRunDuration][eRec][ba] ? true : eh.fEventHistograms[eCurrentRunDuration][eRec][ba]->Fill(ebye.fCurrentRunDuration); + } + // QA: + if (qa.fFillQAEventHistograms2D) { + // General (estimators can be chosen via configurables): + + // **) vs occupancy: + !qa.fQAEventHistograms2D[eMultiplicity_vs_Occupancy][eRec][ba] ? true : qa.fQAEventHistograms2D[eMultiplicity_vs_Occupancy][eRec][ba]->Fill(ebye.fMultiplicity, ebye.fOccupancy); + !qa.fQAEventHistograms2D[eReferenceMultiplicity_vs_Occupancy][eRec][ba] ? true : qa.fQAEventHistograms2D[eReferenceMultiplicity_vs_Occupancy][eRec][ba]->Fill(ebye.fReferenceMultiplicity, ebye.fOccupancy); + !qa.fQAEventHistograms2D[eNContributors_vs_Occupancy][eRec][ba] ? true : qa.fQAEventHistograms2D[eNContributors_vs_Occupancy][eRec][ba]->Fill(collision.numContrib(), ebye.fOccupancy); + !qa.fQAEventHistograms2D[eCentrality_vs_Occupancy][eRec][ba] ? true : qa.fQAEventHistograms2D[eCentrality_vs_Occupancy][eRec][ba]->Fill(ebye.fCentrality, ebye.fOccupancy); + !qa.fQAEventHistograms2D[eVertexZ_vs_Occupancy][eRec][ba] ? true : qa.fQAEventHistograms2D[eVertexZ_vs_Occupancy][eRec][ba]->Fill(collision.posZ(), ebye.fOccupancy); + + // **) vs interaction rate: + !qa.fQAEventHistograms2D[eMultiplicity_vs_InteractionRate][eRec][ba] ? true : qa.fQAEventHistograms2D[eMultiplicity_vs_InteractionRate][eRec][ba]->Fill(ebye.fMultiplicity, ebye.fInteractionRate); + !qa.fQAEventHistograms2D[eReferenceMultiplicity_vs_InteractionRate][eRec][ba] ? true : qa.fQAEventHistograms2D[eReferenceMultiplicity_vs_InteractionRate][eRec][ba]->Fill(ebye.fReferenceMultiplicity, ebye.fInteractionRate); + !qa.fQAEventHistograms2D[eNContributors_vs_InteractionRate][eRec][ba] ? true : qa.fQAEventHistograms2D[eNContributors_vs_InteractionRate][eRec][ba]->Fill(collision.numContrib(), ebye.fInteractionRate); + !qa.fQAEventHistograms2D[eCentrality_vs_InteractionRate][eRec][ba] ? true : qa.fQAEventHistograms2D[eCentrality_vs_InteractionRate][eRec][ba]->Fill(ebye.fCentrality, ebye.fInteractionRate); + !qa.fQAEventHistograms2D[eVertexZ_vs_InteractionRate][eRec][ba] ? true : qa.fQAEventHistograms2D[eVertexZ_vs_InteractionRate][eRec][ba]->Fill(collision.posZ(), ebye.fInteractionRate); + + // **) unsorted TBI 20250331 sort at some point + !qa.fQAEventHistograms2D[eMultiplicity_vs_FT0CAmplitudeOnFoundBC][eRec][ba] ? true : qa.fQAEventHistograms2D[eMultiplicity_vs_FT0CAmplitudeOnFoundBC][eRec][ba]->Fill(ebye.fMultiplicity, ebye.fFT0CAmplitudeOnFoundBC); + !qa.fQAEventHistograms2D[eCentFT0C_vs_FT0CAmplitudeOnFoundBC][eRec][ba] ? true : qa.fQAEventHistograms2D[eCentFT0C_vs_FT0CAmplitudeOnFoundBC][eRec][ba]->Fill(qa.fCentrality[eCentFT0C], ebye.fFT0CAmplitudeOnFoundBC); + + // ... + + // Specific (estimators are hardwired): + !qa.fQAEventHistograms2D[eMultNTracksPV_vs_MultNTracksGlobal][eRec][ba] ? true : qa.fQAEventHistograms2D[eMultNTracksPV_vs_MultNTracksGlobal][eRec][ba]->Fill(qa.fReferenceMultiplicity[eMultNTracksPV], qa.fReferenceMultiplicity[eMultNTracksGlobal]); // TBI 20241209 check if I can use this one for Run 2 and 1 + !qa.fQAEventHistograms2D[eCentFT0C_vs_CentFT0CVariant1][eRec][ba] ? true : qa.fQAEventHistograms2D[eCentFT0C_vs_CentFT0CVariant1][eRec][ba]->Fill(qa.fCentrality[eCentFT0C], qa.fCentrality[eCentFT0CVariant1]); + !qa.fQAEventHistograms2D[eCentFT0C_vs_CentFT0M][eRec][ba] ? true : qa.fQAEventHistograms2D[eCentFT0C_vs_CentFT0M][eRec][ba]->Fill(qa.fCentrality[eCentFT0C], qa.fCentrality[eCentFT0M]); + !qa.fQAEventHistograms2D[eCentFT0C_vs_CentFV0A][eRec][ba] ? true : qa.fQAEventHistograms2D[eCentFT0C_vs_CentFV0A][eRec][ba]->Fill(qa.fCentrality[eCentFT0C], qa.fCentrality[eCentFV0A]); + !qa.fQAEventHistograms2D[eCentFT0C_vs_CentNTPV][eRec][ba] ? true : qa.fQAEventHistograms2D[eCentFT0C_vs_CentNTPV][eRec][ba]->Fill(qa.fCentrality[eCentFT0C], qa.fCentrality[eCentNTPV]); + !qa.fQAEventHistograms2D[eCentFT0C_vs_CentNGlobal][eRec][ba] ? true : qa.fQAEventHistograms2D[eCentFT0C_vs_CentNGlobal][eRec][ba]->Fill(qa.fCentrality[eCentFT0C], qa.fCentrality[eCentNGlobal]); + !qa.fQAEventHistograms2D[eCentFT0M_vs_CentNTPV][eRec][ba] ? true : qa.fQAEventHistograms2D[eCentFT0M_vs_CentNTPV][eRec][ba]->Fill(qa.fCentrality[eCentFT0M], qa.fCentrality[eCentNTPV]); + !qa.fQAEventHistograms2D[eTrackOccupancyInTimeRange_vs_FT0COccupancyInTimeRange][eRec][ba] ? true : qa.fQAEventHistograms2D[eTrackOccupancyInTimeRange_vs_FT0COccupancyInTimeRange][eRec][ba]->Fill(collision.trackOccupancyInTimeRange(), collision.ft0cOccupancyInTimeRange()); + !qa.fQAEventHistograms2D[eCurrentRunDuration_vs_InteractionRate][eRec][ba] ? true : qa.fQAEventHistograms2D[eCurrentRunDuration_vs_InteractionRate][eRec][ba]->Fill(ebye.fCurrentRunDuration, ebye.fInteractionRate); + } + + if (qa.fFillQAParticleEventHistograms2D && qa.fQAParticleEventProEbyE[eRec][ba]) { + // This is a special category, where I do correlation vs. some-event-property. + // I use 'number of combinations' as a weight, which here reduces simply to the 'number of entries' weight. + !qa.fQAParticleEventHistograms2D[eCurrentRunDuration_vs_itsNClsEbyE][eRec][ba] ? true : qa.fQAParticleEventHistograms2D[eCurrentRunDuration_vs_itsNClsEbyE][eRec][ba]->Fill(ebye.fCurrentRunDuration, qa.fQAParticleEventProEbyE[eRec][ba]->GetBinContent(eitsNClsEbyE), qa.fQAParticleEventProEbyE[eRec][ba]->GetBinEntries(eitsNClsEbyE)); + !qa.fQAParticleEventHistograms2D[eCurrentRunDuration_vs_itsNClsNegEtaEbyE][eRec][ba] ? true : qa.fQAParticleEventHistograms2D[eCurrentRunDuration_vs_itsNClsNegEtaEbyE][eRec][ba]->Fill(ebye.fCurrentRunDuration, qa.fQAParticleEventProEbyE[eRec][ba]->GetBinContent(eitsNClsNegEtaEbyE), qa.fQAParticleEventProEbyE[eRec][ba]->GetBinEntries(eitsNClsNegEtaEbyE)); + !qa.fQAParticleEventHistograms2D[eCurrentRunDuration_vs_itsNClsPosEtaEbyE][eRec][ba] ? true : qa.fQAParticleEventHistograms2D[eCurrentRunDuration_vs_itsNClsPosEtaEbyE][eRec][ba]->Fill(ebye.fCurrentRunDuration, qa.fQAParticleEventProEbyE[eRec][ba]->GetBinContent(eitsNClsPosEtaEbyE), qa.fQAParticleEventProEbyE[eRec][ba]->GetBinEntries(eitsNClsPosEtaEbyE)); + !qa.fQAParticleEventHistograms2D[eCurrentRunDuration_vs_Eta0804EbyE][eRec][ba] ? true : qa.fQAParticleEventHistograms2D[eCurrentRunDuration_vs_Eta0804EbyE][eRec][ba]->Fill(ebye.fCurrentRunDuration, qa.fQAParticleEventProEbyE[eRec][ba]->GetBinContent(eEta0804EbyE), qa.fQAParticleEventProEbyE[eRec][ba]->GetBinEntries(eEta0804EbyE)); + !qa.fQAParticleEventHistograms2D[eCurrentRunDuration_vs_Eta0400EbyE][eRec][ba] ? true : qa.fQAParticleEventHistograms2D[eCurrentRunDuration_vs_Eta0400EbyE][eRec][ba]->Fill(ebye.fCurrentRunDuration, qa.fQAParticleEventProEbyE[eRec][ba]->GetBinContent(eEta0400EbyE), qa.fQAParticleEventProEbyE[eRec][ba]->GetBinEntries(eEta0400EbyE)); + !qa.fQAParticleEventHistograms2D[eCurrentRunDuration_vs_Eta0004EbyE][eRec][ba] ? true : qa.fQAParticleEventHistograms2D[eCurrentRunDuration_vs_Eta0004EbyE][eRec][ba]->Fill(ebye.fCurrentRunDuration, qa.fQAParticleEventProEbyE[eRec][ba]->GetBinContent(eEta0004EbyE), qa.fQAParticleEventProEbyE[eRec][ba]->GetBinEntries(eEta0004EbyE)); + !qa.fQAParticleEventHistograms2D[eCurrentRunDuration_vs_Eta0408EbyE][eRec][ba] ? true : qa.fQAParticleEventHistograms2D[eCurrentRunDuration_vs_Eta0408EbyE][eRec][ba]->Fill(ebye.fCurrentRunDuration, qa.fQAParticleEventProEbyE[eRec][ba]->GetBinContent(eEta0408EbyE), qa.fQAParticleEventProEbyE[eRec][ba]->GetBinEntries(eEta0408EbyE)); + !qa.fQAParticleEventHistograms2D[eCurrentRunDuration_vs_Pt0005EbyE][eRec][ba] ? true : qa.fQAParticleEventHistograms2D[eCurrentRunDuration_vs_Pt0005EbyE][eRec][ba]->Fill(ebye.fCurrentRunDuration, qa.fQAParticleEventProEbyE[eRec][ba]->GetBinContent(ePt0005EbyE), qa.fQAParticleEventProEbyE[eRec][ba]->GetBinEntries(ePt0005EbyE)); + !qa.fQAParticleEventHistograms2D[eCurrentRunDuration_vs_Pt0510EbyE][eRec][ba] ? true : qa.fQAParticleEventHistograms2D[eCurrentRunDuration_vs_Pt0510EbyE][eRec][ba]->Fill(ebye.fCurrentRunDuration, qa.fQAParticleEventProEbyE[eRec][ba]->GetBinContent(ePt0510EbyE), qa.fQAParticleEventProEbyE[eRec][ba]->GetBinEntries(ePt0510EbyE)); + !qa.fQAParticleEventHistograms2D[eCurrentRunDuration_vs_Pt1050EbyE][eRec][ba] ? true : qa.fQAParticleEventHistograms2D[eCurrentRunDuration_vs_Pt1050EbyE][eRec][ba]->Fill(ebye.fCurrentRunDuration, qa.fQAParticleEventProEbyE[eRec][ba]->GetBinContent(ePt1050EbyE), qa.fQAParticleEventProEbyE[eRec][ba]->GetBinEntries(ePt1050EbyE)); + } // if (qa.fFillQAParticleEventHistograms2D && qa.fQAParticleEventProEbyE[eRec][ba]) { + + if (qa.fFillQACorrelationsVsInteractionRateVsProfiles2D && qa.fQAParticleEventProEbyE[eRec][ba] && ba == eAfter) { // fill only for eAfter, because I do not calculate Q-vectors before cuts + + // Calculate quickly 2-p correlation in harmonic h for this event: TBI 20250114 shall I add this also to some EbyE variable? There is no really much of a code bloat for the time being... + + // Flush 'n' fill the generic Q-vectors: + ResetQ(); + int lMaxCorrelator = 2; // used only here locally + for (int h = 0; h < gMaxHarmonic * lMaxCorrelator + 1; h++) { + for (int wp = 0; wp < lMaxCorrelator + 1; wp++) // weight power + { + qv.fQ[h][wp] = qv.fQvector[h][wp]; + } + } + + for (int h = 1; h <= gMaxHarmonic; h++) { + TComplex two = Two(h, -h); + double twoC = two.Re(); // cos + // double twoS = two.Im(); // sin + double wTwo = Two(0, 0).Re(); // Weight is 'number of combinations' by default TBI + // 20220809 add support for other weights + if (!(wTwo > 0.0)) { + LOGF(fatal, "In function \033[1;31m%s at line %d : wTwo = %f <=0. ebye.fSelectedTracks = %d.\nDid you forget to enable fCalculateQvectors = true?\033[0m", __FUNCTION__, __LINE__, wTwo, ebye.fSelectedTracks); + } + + !qa.fQACorrVsIRVsProfiles2D[eCorrelationsVsInteractionRate_vs_CurrentRunDuration][h - 1][eRec] ? true : qa.fQACorrVsIRVsProfiles2D[eCorrelationsVsInteractionRate_vs_CurrentRunDuration][h - 1][eRec]->Fill(ebye.fInteractionRate, ebye.fCurrentRunDuration, twoC / wTwo, wTwo); + !qa.fQACorrVsIRVsProfiles2D[eCorrelationsVsInteractionRate_vs_Multiplicity][h - 1][eRec] ? true : qa.fQACorrVsIRVsProfiles2D[eCorrelationsVsInteractionRate_vs_Multiplicity][h - 1][eRec]->Fill(ebye.fInteractionRate, ebye.fMultiplicity, twoC / wTwo, wTwo); + !qa.fQACorrVsIRVsProfiles2D[eCorrelationsVsInteractionRate_vs_ReferenceMultiplicity][h - 1][eRec] ? true : qa.fQACorrVsIRVsProfiles2D[eCorrelationsVsInteractionRate_vs_ReferenceMultiplicity][h - 1][eRec]->Fill(ebye.fInteractionRate, ebye.fReferenceMultiplicity, twoC / wTwo, wTwo); + !qa.fQACorrVsIRVsProfiles2D[eCorrelationsVsInteractionRate_vs_Centrality][h - 1][eRec] ? true : qa.fQACorrVsIRVsProfiles2D[eCorrelationsVsInteractionRate_vs_Centrality][h - 1][eRec]->Fill(ebye.fInteractionRate, ebye.fCentrality, twoC / wTwo, wTwo); + // ..... + !qa.fQACorrVsIRVsProfiles2D[eCorrelationsVsInteractionRate_vs_MeanPhi][h - 1][eRec] ? true : qa.fQACorrVsIRVsProfiles2D[eCorrelationsVsInteractionRate_vs_MeanPhi][h - 1][eRec]->Fill(ebye.fInteractionRate, qa.fQAParticleEventProEbyE[eRec][ba]->GetBinContent(eMeanPhi), twoC / wTwo, wTwo); + !qa.fQACorrVsIRVsProfiles2D[eCorrelationsVsInteractionRate_vs_SigmaMeanPhi][h - 1][eRec] ? true : qa.fQACorrVsIRVsProfiles2D[eCorrelationsVsInteractionRate_vs_SigmaMeanPhi][h - 1][eRec]->Fill(ebye.fInteractionRate, qa.fQAParticleEventProEbyE[eRec][ba]->GetBinError(eMeanPhi), twoC / wTwo, wTwo); + !qa.fQACorrVsIRVsProfiles2D[eCorrelationsVsInteractionRate_vs_MeanPt][h - 1][eRec] ? true : qa.fQACorrVsIRVsProfiles2D[eCorrelationsVsInteractionRate_vs_MeanPt][h - 1][eRec]->Fill(ebye.fInteractionRate, qa.fQAParticleEventProEbyE[eRec][ba]->GetBinContent(eMeanPt), twoC / wTwo, wTwo); + !qa.fQACorrVsIRVsProfiles2D[eCorrelationsVsInteractionRate_vs_SigmaMeanPt][h - 1][eRec] ? true : qa.fQACorrVsIRVsProfiles2D[eCorrelationsVsInteractionRate_vs_SigmaMeanPt][h - 1][eRec]->Fill(ebye.fInteractionRate, qa.fQAParticleEventProEbyE[eRec][ba]->GetBinError(eMeanPt), twoC / wTwo, wTwo); + !qa.fQACorrVsIRVsProfiles2D[eCorrelationsVsInteractionRate_vs_MeanEta][h - 1][eRec] ? true : qa.fQACorrVsIRVsProfiles2D[eCorrelationsVsInteractionRate_vs_MeanEta][h - 1][eRec]->Fill(ebye.fInteractionRate, qa.fQAParticleEventProEbyE[eRec][ba]->GetBinContent(eMeanEta), twoC / wTwo, wTwo); + !qa.fQACorrVsIRVsProfiles2D[eCorrelationsVsInteractionRate_vs_SigmaMeanEta][h - 1][eRec] ? true : qa.fQACorrVsIRVsProfiles2D[eCorrelationsVsInteractionRate_vs_SigmaMeanEta][h - 1][eRec]->Fill(ebye.fInteractionRate, qa.fQAParticleEventProEbyE[eRec][ba]->GetBinError(eMeanEta), twoC / wTwo, wTwo); + // ..... + } + + // Flush the generic Q-vectors: + ResetQ(); + + } // if (qa.fFillQACorrelationsVsInteractionRateVsProfiles2D && qa.fQAParticleEventProEbyE[eRec][ba] && ba == eAfter) { + + // ... + + // ... and corresponding MC truth simulated (Run 3 specific) + // See https://github.com/AliceO2Group/O2Physics/blob/master/Tutorials/src/mcHistograms.cxx + if constexpr (rs == eRecAndSim) { + if (!collision.has_mcCollision()) { + LOGF(warning, "\033[1;31m%s at line %d : No MC collision for this collision, skip... \033[0m", __FUNCTION__, __LINE__); + return; + } + + // !eh.fEventHistograms[eMultMCNParticlesEta08][eSim][ba] ? true : eh.fEventHistograms[eMultMCNParticlesEta08][eSim][ba]->Fill(collision.multMCNParticlesEta08()); + + // !eh.fEventHistograms[eNumberOfEvents][eSim][ba] ? true : eh.fEventHistograms[eNumberOfEvents][eSim][ba]->Fill(0.5); + } // if constexpr (rs == eRecAndSim) { + } // if constexpr (rs == eRec || rs == eRecAndSim) { + + // ----------------------------------------------------------------------------- + + // d) Fill only simulated (Run 3 specific): + if constexpr (rs == eSim) { + // !eh.fEventHistograms[eImpactParameter][eSim][ba] ? true : eh.fEventHistograms[eImpactParameter][eSim][ba]->Fill(collision.impactParameter()); // yes, because in this branch 'collision' is always aod::McCollision + // !eh.fEventHistograms[eEventPlaneAngle][eSim][ba] ? true : eh.fEventHistograms[eEventPlaneAngle][eSim][ba]->Fill(collision.eventPlaneAngle()); // yes, because in this branch 'collision' is always aod::McCollision + } // if constexpr (rs == eSim) { + + // ----------------------------------------------------------------------------- + + // e) Fill reconstructed (Run 1 and 2 specific): // In case there is some corner case between Run 1 and Run 2, simply branch further this one + if constexpr (rs == eRec_Run2 || rs == eRecAndSim_Run2 || rs == eRec_Run1 || rs == eRecAndSim_Run1) { + if (eh.fFillEventHistograms) { + // ... + } + // QA: + if (qa.fFillQAEventHistograms2D) { + !qa.fQAEventHistograms2D[eCentRun2V0M_vs_CentRun2SPDTracklets][eRec][ba] ? true : qa.fQAEventHistograms2D[eCentRun2V0M_vs_CentRun2SPDTracklets][eRec][ba]->Fill(qa.fCentrality[eCentRun2V0M], qa.fCentrality[eCentRun2SPDTracklets]); + } + + // ... and corresponding MC truth simulated (Run 1 and Run 2 specific): + // See https://github.com/AliceO2Group/O2Physics/blob/master/Tutorials/src/mcHistograms.cxx + if constexpr (rs == eRecAndSim_Run2 || rs == eRecAndSim_Run1) { + if (!collision.has_mcCollision()) { + LOGF(warning, "\033[1;31m%s at line %d : No MC collision for this collision, skip... \033[0m", __FUNCTION__, __LINE__); + return; + } + // !eh.fEventHistograms[eNumberOfEvents][eSim][ba] ? true : eh.fEventHistograms[eNumberOfEvents][eSim][ba]->Fill(0.5); + + } // if constexpr (rs == eRecAndSim_Run2 || rs == eRecAndSim_Run1) { + } // if constexpr (rs == eRec_Run2 || rs == eRecAndSim_Run2 || rs == eRec_Run1 || rs == eRecAndSim_Run1) { + + // ----------------------------------------------------------------------------- + + // f) Fill only simulated (Run 1 and 2 specific): // In case there is some corner case between Run 1 and Run 2, simply branch further this one + if constexpr (rs == eSim_Run2 || rs == eSim_Run1) { + // !eh.fEventHistograms[eImpactParameter][eSim][ba] ? true : eh.fEventHistograms[eImpactParameter][eSim][ba]->Fill(collision.impactParameter()); // yes, because in this branch 'collision' is always aod::McCollision + // !eh.fEventHistograms[eEventPlaneAngle][eSim][ba] ? true : eh.fEventHistograms[eEventPlaneAngle][eSim][ba]->Fill(collision.eventPlaneAngle()); // yes, because in this branch 'collision' is always aod::McCollision + } // if constexpr (rs == eSim_Run2 || rs == eSim_Run1) { + + // ----------------------------------------------------------------------------- + + // g) Test case: + if constexpr (rs == eTest) { + // TBI 20240223 for the time being, eTest fills only eRec histos: + // A few example histograms, just to check if I access corresponding tables: + if (eh.fFillEventHistograms) { + !eh.fEventHistograms[eNumberOfEvents][eRec][ba] ? true : eh.fEventHistograms[eNumberOfEvents][eRec][ba]->Fill(0.5); + !eh.fEventHistograms[eVertexZ][eRec][ba] ? true : eh.fEventHistograms[eVertexZ][eRec][ba]->Fill(collision.posZ()); + !eh.fEventHistograms[eTotalMultiplicity][eRec][ba] ? true : eh.fEventHistograms[eTotalMultiplicity][eRec][ba]->Fill(tracks.size()); + !eh.fEventHistograms[eCentrality][eRec][ba] ? true : eh.fEventHistograms[eCentrality][eRec][ba]->Fill(ebye.fCentrality); + } + } // if constexpr (rs == eTest) { + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // template void FillEventHistograms(...) + + //============================================================ + + void CheckUnderflowAndOverflow() + { + // Check and bail out if in event and particle histograms there are entries which went to underflow or overflow bins. + + // TBI 20250527 I have reinvented the wheel here, there are already member functions TH1::IsBinUnderflow() and TH1::IsBinOverflow(), + // which I have use also for 2D and 3D cases with "global bin". + // Reimplemented this function using those member functions eventually. + + // a) Event histograms 1D; + // b) Event histograms 2D; + // c) Particle histograms 1D; + // d) Particle histograms 2D; + // e) QA Event histograms 2D; + // f) QA Particle histograms 2D; + // g) QA Particle event histograms 2D. + + if (tc.fVerboseForEachParticle) { + StartFunction(__FUNCTION__); + } + + // a) Event histograms 1D: + for (int t = 0; t < eEventHistograms_N; t++) // type, see enum eEventHistograms + { + for (int rs = 0; rs < 2; rs++) // reco/sim + { + for (int ba = 0; ba < 2; ba++) // before/after cuts + { + if (!eh.fEventHistograms[t][rs][ba]) { + continue; + } else if (eh.fEventHistograms[t][rs][ba]->GetBinContent(0) > 0) { + LOGF(fatal, "\033[1;31m%s at line %d : underflow in fEventHistograms[%d][%d][%d] => optimize default binning for this histogram\033[0m", __FUNCTION__, __LINE__, t, rs, ba); + } else if (eh.fEventHistograms[t][rs][ba]->GetBinContent(eh.fEventHistograms[t][rs][ba]->GetNbinsX() + 1) > 0) { + LOGF(fatal, "\033[1;31m%s at line %d : overflow in fEventHistograms[%d][%d][%d] => optimize default binning for this histogram\033[0m", __FUNCTION__, __LINE__, t, rs, ba); + } + } + } + } + + // b) Event histograms 2D: + // ... + + // c) Particle histograms 1D: + for (int t = 0; t < eParticleHistograms_N; t++) // type, see enum eParticleHistograms + { + for (int rs = 0; rs < 2; rs++) // reco/sim + { + for (int ba = 0; ba < 2; ba++) // before/after cuts + { + if (!ph.fParticleHistograms[t][rs][ba]) { + continue; + } else if (ph.fParticleHistograms[t][rs][ba]->GetBinContent(0) > 0) { + LOGF(fatal, "\033[1;31m%s at line %d : underflow in fParticleHistograms[%d][%d][%d] => optimize default binning for this histogram\033[0m", __FUNCTION__, __LINE__, t, rs, ba); + } else if (ph.fParticleHistograms[t][rs][ba]->GetBinContent(ph.fParticleHistograms[t][rs][ba]->GetNbinsX() + 1) > 0) { + LOGF(fatal, "\033[1;31m%s at line %d : overflow in fParticleHistograms[%d][%d][%d] => optimize default binning for this histogram\033[0m", __FUNCTION__, __LINE__, t, rs, ba); + } + } + } + } + + // d) Particle histograms 2D: + for (int t = 0; t < eParticleHistograms2D_N; t++) // type, see enum eParticleHistograms2D + { + for (int rs = 0; rs < 2; rs++) // reco/sim + { + for (int ba = 0; ba < 2; ba++) // before/after cuts + { + if (!ph.fParticleHistograms2D[t][rs][ba]) { + continue; + } + + // Underflow and overflow in x: + for (int binY = 0; binY <= ph.fParticleHistograms2D[t][rs][ba]->GetNbinsY(); binY++) { + if (ph.fParticleHistograms2D[t][rs][ba]->GetBinContent(ph.fParticleHistograms2D[t][rs][ba]->GetBin(0, binY)) > 0) { + LOGF(fatal, "\033[1;31m%s at line %d : underflow in x variable in fParticleHistograms2D[%d][%d][%d], for binY = %d => optimize default binning for this histogram\033[0m", __FUNCTION__, __LINE__, t, rs, ba, binY); + } + if (ph.fParticleHistograms2D[t][rs][ba]->GetBinContent(ph.fParticleHistograms2D[t][rs][ba]->GetBin(ph.fParticleHistograms2D[t][rs][ba]->GetNbinsX() + 1, binY)) > 0) { + LOGF(fatal, "\033[1;31m%s at line %d : overflow in x variable in fParticleHistograms2D[%d][%d][%d], for binY = %d => optimize default binning for this histogram\033[0m", __FUNCTION__, __LINE__, t, rs, ba, binY); + } + } // for (int binY = 0; binY <= ph.fParticleHistograms2D[t][rs][ba]->GetNbinsY(); binY++) { + + // Underflow and overflow in y: + for (int binX = 0; binX <= ph.fParticleHistograms2D[t][rs][ba]->GetNbinsX(); binX++) { + if (ph.fParticleHistograms2D[t][rs][ba]->GetBinContent(ph.fParticleHistograms2D[t][rs][ba]->GetBin(binX, 0)) > 0) { + LOGF(fatal, "\033[1;31m%s at line %d : underflow in y variable in fParticleHistograms2D[%d][%d][%d], for binX = %d => optimize default binning for this histogram\033[0m", __FUNCTION__, __LINE__, t, rs, ba, binX); + } + + if (ph.fParticleHistograms2D[t][rs][ba]->GetBinContent(ph.fParticleHistograms2D[t][rs][ba]->GetBin(binX, ph.fParticleHistograms2D[t][rs][ba]->GetNbinsY() + 1)) > 0) { + LOGF(fatal, "\033[1;31m%s at line %d : overflow in y variable in fParticleHistograms2D[%d][%d][%d], for binX = %d => optimize default binning for this histogram\033[0m", __FUNCTION__, __LINE__, t, rs, ba, binX); + } + } // for (int binX = 0; binX <= ph.fParticleHistograms2D[t][rs][ba]->GetNbinsX(); binX++) { + } // for (int ba = 0; ba < 2; ba++) // before/after cuts + } // for (int rs = 0; rs < 2; rs++) // reco/sim + } // for (int t = 0; t < eParticleHistograms2D_N; t++) // type, see enum eParticleHistograms2D + + // e) QA Event histograms 2D: + for (int t = 0; t < eQAEventHistograms2D_N; t++) // type, see enum eQAEventHistograms2D + { + for (int rs = 0; rs < 2; rs++) // reco/sim + { + for (int ba = 0; ba < 2; ba++) // before/after cuts + { + if (!qa.fQAEventHistograms2D[t][rs][ba]) { + continue; + } + + // Underflow and overflow in x: + for (int binY = 0; binY <= qa.fQAEventHistograms2D[t][rs][ba]->GetNbinsY(); binY++) { + if (qa.fQAEventHistograms2D[t][rs][ba]->GetBinContent(qa.fQAEventHistograms2D[t][rs][ba]->GetBin(0, binY)) > 0) { + LOGF(fatal, "\033[1;31m%s at line %d : underflow in x variable in fEventHistograms2D[%d][%d][%d], for binY = %d => optimize default binning for this histogram\033[0m", __FUNCTION__, __LINE__, t, rs, ba, binY); + } + if (qa.fQAEventHistograms2D[t][rs][ba]->GetBinContent(qa.fQAEventHistograms2D[t][rs][ba]->GetBin(qa.fQAEventHistograms2D[t][rs][ba]->GetNbinsX() + 1, binY)) > 0) { + LOGF(fatal, "\033[1;31m%s at line %d : overflow in x variable in fEventHistograms2D[%d][%d][%d], for binY = %d => optimize default binning for this histogram\033[0m", __FUNCTION__, __LINE__, t, rs, ba, binY); + } + } // for (int binY = 0; binY <= qa.fQAEventHistograms2D[t][rs][ba]->GetNbinsY(); binY++) { + + // Underflow and overflow in y: + for (int binX = 0; binX <= qa.fQAEventHistograms2D[t][rs][ba]->GetNbinsX(); binX++) { + if (qa.fQAEventHistograms2D[t][rs][ba]->GetBinContent(qa.fQAEventHistograms2D[t][rs][ba]->GetBin(binX, 0)) > 0) { + LOGF(fatal, "\033[1;31m%s at line %d : underflow in y variable in fEventHistograms2D[%d][%d][%d], for binX = %d => optimize default binning for this histogram\033[0m", __FUNCTION__, __LINE__, t, rs, ba, binX); + } + + if (qa.fQAEventHistograms2D[t][rs][ba]->GetBinContent(qa.fQAEventHistograms2D[t][rs][ba]->GetBin(binX, qa.fQAEventHistograms2D[t][rs][ba]->GetNbinsY() + 1)) > 0) { + LOGF(fatal, "\033[1;31m%s at line %d : overflow in y variable in fEventHistograms2D[%d][%d][%d], for binX = %d => optimize default binning for this histogram\033[0m", __FUNCTION__, __LINE__, t, rs, ba, binX); + } + } // for (int binX = 0; binX <= qa.fQAEventHistograms2D[t][rs][ba]->GetNbinsX(); binX++) { + } // for (int ba = 0; ba < 2; ba++) // before/after cuts + } // for (int rs = 0; rs < 2; rs++) // reco/sim + } // for (int t = 0; t < eQAEventHistograms2D_N; t++) // type, see enum eQAEventHistograms2D + + // f) QA Particle histograms 2D: + for (int t = 0; t < eQAParticleHistograms2D_N; t++) // type, see enum eQAParticleHistograms2D + { + for (int rs = 0; rs < 2; rs++) // reco/sim + { + for (int ba = 0; ba < 2; ba++) // before/after cuts + { + if (!qa.fQAParticleHistograms2D[t][rs][ba]) { + continue; + } + + // Underflow and overflow in x: + for (int binY = 0; binY <= qa.fQAParticleHistograms2D[t][rs][ba]->GetNbinsY(); binY++) { + if (qa.fQAParticleHistograms2D[t][rs][ba]->GetBinContent(qa.fQAParticleHistograms2D[t][rs][ba]->GetBin(0, binY)) > 0) { + LOGF(fatal, "\033[1;31m%s at line %d : underflow in x variable in fParticleHistograms2D[%d][%d][%d], for binY = %d => optimize default binning for this histogram\033[0m", __FUNCTION__, __LINE__, t, rs, ba, binY); + } + if (qa.fQAParticleHistograms2D[t][rs][ba]->GetBinContent(qa.fQAParticleHistograms2D[t][rs][ba]->GetBin(qa.fQAParticleHistograms2D[t][rs][ba]->GetNbinsX() + 1, binY)) > 0) { + LOGF(fatal, "\033[1;31m%s at line %d : overflow in x variable in fParticleHistograms2D[%d][%d][%d], for binY = %d => optimize default binning for this histogram\033[0m", __FUNCTION__, __LINE__, t, rs, ba, binY); + } + } // for (int binY = 0; binY <= qa.fQAParticleHistograms2D[t][rs][ba]->GetNbinsY(); binY++) { + + // Underflow and overflow in y: + for (int binX = 0; binX <= qa.fQAParticleHistograms2D[t][rs][ba]->GetNbinsX(); binX++) { + if (qa.fQAParticleHistograms2D[t][rs][ba]->GetBinContent(qa.fQAParticleHistograms2D[t][rs][ba]->GetBin(binX, 0)) > 0) { + LOGF(fatal, "\033[1;31m%s at line %d : underflow in y variable in fParticleHistograms2D[%d][%d][%d], for binX = %d => optimize default binning for this histogram\033[0m", __FUNCTION__, __LINE__, t, rs, ba, binX); + } + + if (qa.fQAParticleHistograms2D[t][rs][ba]->GetBinContent(qa.fQAParticleHistograms2D[t][rs][ba]->GetBin(binX, qa.fQAParticleHistograms2D[t][rs][ba]->GetNbinsY() + 1)) > 0) { + LOGF(fatal, "\033[1;31m%s at line %d : overflow in y variable in fParticleHistograms2D[%d][%d][%d], for binX = %d => optimize default binning for this histogram\033[0m", __FUNCTION__, __LINE__, t, rs, ba, binX); + } + } // for (int binX = 0; binX <= qa.fQAParticleHistograms2D[t][rs][ba]->GetNbinsX(); binX++) { + } // for (int ba = 0; ba < 2; ba++) // before/after cuts + } // for (int rs = 0; rs < 2; rs++) // reco/sim + } // for (int t = 0; t < eQAParticleHistograms2D_N; t++) // type, see enum eParticleHistograms2D + + // g) QA Particle event histograms 2D: + // TBI 20241212 I never validated this code block + for (int t = 0; t < eQAParticleEventHistograms2D_N; t++) // type, see enum eQAParticleEventHistograms2D + { + for (int rs = 0; rs < 2; rs++) // reco/sim + { + for (int ba = 0; ba < 2; ba++) // before/after cuts + { + if (!qa.fQAParticleEventHistograms2D[t][rs][ba]) { + continue; + } + + // Underflow and overflow in x: + for (int binY = 0; binY <= qa.fQAParticleEventHistograms2D[t][rs][ba]->GetNbinsY(); binY++) { + if (qa.fQAParticleEventHistograms2D[t][rs][ba]->GetBinContent(qa.fQAParticleEventHistograms2D[t][rs][ba]->GetBin(0, binY)) > 0) { + LOGF(fatal, "\033[1;31m%s at line %d : underflow in x variable in fParticleEventHistograms2D[%d][%d][%d], for binY = %d => optimize default binning for this histogram\033[0m", __FUNCTION__, __LINE__, t, rs, ba, binY); + } + if (qa.fQAParticleEventHistograms2D[t][rs][ba]->GetBinContent(qa.fQAParticleEventHistograms2D[t][rs][ba]->GetBin(qa.fQAParticleEventHistograms2D[t][rs][ba]->GetNbinsX() + 1, binY)) > 0) { + LOGF(fatal, "\033[1;31m%s at line %d : overflow in x variable in fParticleEventHistograms2D[%d][%d][%d], for binY = %d => optimize default binning for this histogram\033[0m", __FUNCTION__, __LINE__, t, rs, ba, binY); + } + } // for (int binY = 0; binY <= qa.fQAParticleEventHistograms2D[t][rs][ba]->GetNbinsY(); binY++) { + + // Underflow and overflow in y: + for (int binX = 0; binX <= qa.fQAParticleEventHistograms2D[t][rs][ba]->GetNbinsX(); binX++) { + if (qa.fQAParticleEventHistograms2D[t][rs][ba]->GetBinContent(qa.fQAParticleEventHistograms2D[t][rs][ba]->GetBin(binX, 0)) > 0) { + LOGF(fatal, "\033[1;31m%s at line %d : underflow in y variable in fParticleEventHistograms2D[%d][%d][%d], for binX = %d => optimize default binning for this histogram\033[0m", __FUNCTION__, __LINE__, t, rs, ba, binX); + } + + if (qa.fQAParticleEventHistograms2D[t][rs][ba]->GetBinContent(qa.fQAParticleEventHistograms2D[t][rs][ba]->GetBin(binX, qa.fQAParticleEventHistograms2D[t][rs][ba]->GetNbinsY() + 1)) > 0) { + LOGF(fatal, "\033[1;31m%s at line %d : overflow in y variable in fParticleEventHistograms2D[%d][%d][%d], for binX = %d => optimize default binning for this histogram\033[0m", __FUNCTION__, __LINE__, t, rs, ba, binX); + } + } // for (int binX = 0; binX <= qa.fQAParticleEventHistograms2D[t][rs][ba]->GetNbinsX(); binX++) { + } // for (int ba = 0; ba < 2; ba++) // before/after cuts + } // for (int rs = 0; rs < 2; rs++) // reco/sim + } // for (int t = 0; t < eQAParticleEventHistograms2D_N; t++) // type, see enum eParticleEventHistograms2D + + if (tc.fVerboseForEachParticle) { + ExitFunction(__FUNCTION__); + } + + } // void CheckUnderflowAndOverflow() + + //============================================================ + + template + bool ValidTrack(T const& track) + { + // Before I start applying any track cuts, check if this is a valid track. + // For instance, Run 2 or Run 1 tracklets are NOT valid tracks, as they carry no pt information, and in this function they are filtered out. + + // See enum TrackTypeEnum in O2/Framework/Core/include/Framework/DataTypes.h for further info. + + // a) Validity checks for tracks in Run 3; + // b) Validity checks for tracks in Run 2 and 1; + // c) Additional validity checks for all tracks (in Run 3, 2 and 1), use only during debugging. + + if (tc.fVerboseForEachParticle) { + StartFunction(__FUNCTION__); + LOGF(info, " track.phi() = %f", track.phi()); + LOGF(info, " track.pt() = %f", track.pt()); + LOGF(info, " track.eta() = %f", track.eta()); + // LOGF(info, "track.trackType() = %d", static_cast(track.trackType())); TBI 20240404 this is not supported for MC particles + } + + // a) Validity checks for tracks in Run 3: + // *) Ensure that I am taking into account propagated tracks (and not e.g. track evaluated at innermost update): + if constexpr (rs == eRec || rs == eRecAndSim || rs == eQA) { + if (!(track.trackType() == o2::aod::track::TrackTypeEnum::Track)) { + if (tc.fVerboseForEachParticle) { + LOGF(info, "\033[1;31m%s track.trackType() == o2::aod::track::TrackTypeEnum::Trac\033[0m", __FUNCTION__); + } + return false; + } + } + + // b) Validity checks for tracks in Run 2 and 1: + // *) Ensure that tracklets (no pt information) are skipped: + if constexpr (rs == eRec_Run2 || rs == eRecAndSim_Run2 || rs == eRec_Run1 || rs == eRecAndSim_Run1) { + if (!(track.trackType() == o2::aod::track::TrackTypeEnum::Run2Track)) { + if (tc.fVerboseForEachParticle) { + LOGF(info, "\033[1;31m%s track.trackType() == o2::aod::track::TrackTypeEnum::Run2Track\033[0m", __FUNCTION__); + } + return false; + } + } + + // *) Temporary here, until I cover also these cases: + if constexpr (rs == eSim || rs == eSim_Run2 || rs == eSim_Run1) { + LOGF(fatal, "\033[1;31m%s at line %d : add support for TrackTypeEnum here also for cases eSim, eSim_Run2 and eSim_Run1\033[0m", __FUNCTION__, __LINE__); + } + + // c) Additional validity checks for all tracks (in Run 3, 2 and 1), use only during debugging: + if (tc.fInsanityCheckForEachParticle) { + + // *) std::isnan() check (remember that 'nan' is 0./0., inf-inf, etc. However 'inf' itself is NOT a 'nan', therefore std::isnan(1./0.) is false, std::isnan(0./0.) is true, etc.): + if (std::isnan(track.phi()) || std::isnan(track.pt()) || std::isnan(track.eta())) { + if (tc.fVerboseForEachParticle) { + LOGF(info, "\033[1;31m%s std::isnan(track.phi()) || std::isnan(track.pt()) || std::isnan(track.eta())\033[0m", __FUNCTION__); + LOGF(error, "track.phi() = %f\ntrack.pt() = %f\ntrack.eta() = %f", track.phi(), track.pt(), track.eta()); + } + return false; + } + + // *) ... + // ... + + } // if(tc.fInsanityCheckForEachParticle) { + + // *) All checks above survived, then it's a valid track: + return true; + + } // template bool ValidTrack(T const& track) + + //============================================================ + + float GetCentralityPercentile(TString ce) + { + // Helper function for CentralityCorrelationCut(), to reduce the code bloat there. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // TBI 20250331 shall I add some insanity check on centrality estimator "ce" + + float centralityPercentile = -1.; + + // Run 3: + if (ce.EqualTo("centFT0C", TString::kIgnoreCase)) { + centralityPercentile = qa.fCentrality[eCentFT0C]; + } else if (ce.EqualTo("centFT0CVariant1", TString::kIgnoreCase)) { + centralityPercentile = qa.fCentrality[eCentFT0CVariant1]; + } else if (ce.EqualTo("centFT0M", TString::kIgnoreCase)) { + centralityPercentile = qa.fCentrality[eCentFT0M]; + } else if (ce.EqualTo("centFV0A", TString::kIgnoreCase)) { + centralityPercentile = qa.fCentrality[eCentFV0A]; + } else if (ce.EqualTo("centNTPV", TString::kIgnoreCase)) { + centralityPercentile = qa.fCentrality[eCentNTPV]; + } else if (ce.EqualTo("centNGlobal", TString::kIgnoreCase)) { + // centralityPercentile = qa.fCentrality[eCentNGlobal]; // TBI 20250331 enable eventually + + // ... ctd. here with Run 3 estimators ... + + // Run 1 and Run 2: + } else if (ce.EqualTo("centRun2V0M", TString::kIgnoreCase)) { + centralityPercentile = qa.fCentrality[eCentRun2V0M]; + } else if (ce.EqualTo("centRun2SPDTracklets", TString::kIgnoreCase)) { + centralityPercentile = qa.fCentrality[eCentRun2SPDTracklets]; + + // ... ctd. here with Run 1 and Run 2 estimators ... + + } else { + LOGF(fatal, "\033[1;31m%s at line %d : centrality estimator = %s is not supported yet. \033[0m", __FUNCTION__, __LINE__, ce.Data()); + } + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + return centralityPercentile; + + } // float GetCentralityPercentile(TString ce) + + //============================================================ + + bool CentralityCorrelationCut() + { + // If centrality correlation cut was requested, in this function i decide whether the current event survives it or not. + // This function is called only in EventCuts(...). I implemented it here separately merely to keep code in EventCuts(...) as clean as possible. + // If makes sense to call this function, only if in DetermineCentrality(...) I have filled in qa.Centrality . + + // TBI 20250331 There is a bit of performance loss, because I need 2 centrality estimators to calculate correlation cut, and I fill in qa.Centrality values + // for all centrality estimators. But this way I can chain several centrality correlation cuts in the future with AND condition, if necessary. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + LOGF(info, "\033[1;33m%s at line %d : ec.fsEventCuts[eCentralityCorrelationsCut] = %s \033[0m", __FUNCTION__, __LINE__, ec.fsEventCuts[eCentralityCorrelationsCut].Data()); + } + + bool alright = true; // this local variable holds the return value for this function + + // Algorithm: I extract e.g. from "CentFT0C_CentFT0M" that the first estimator is "CentFT0C" and second "CentFT0M", and for each estimator I fetch the corresponding centrality percentile: + if (!ec.fsEventCuts[eCentralityCorrelationsCut].Contains("_")) { + LOGF(fatal, "\033[1;31m%s at line %d : ec.fsEventCuts[eCentralityCorrelationsCut] = %s \033[0m", __FUNCTION__, __LINE__, ec.fsEventCuts[eCentralityCorrelationsCut].Data()); + } + + TObjArray* oa = ec.fsEventCuts[eCentralityCorrelationsCut].Tokenize("_"); // TBI 20250331 let's see for how long I can use "_" safely as IFS ... + if (!oa || 2 != oa->GetEntries()) { + LOGF(fatal, "\033[1;31m%s at line %d : oa is NULL , s = %s. Example format is e.g. \"CentFT0C_CentFT0M\"\033[0m", __FUNCTION__, __LINE__, ec.fsEventCuts[eCentralityCorrelationsCut].Data()); + } + + if (tc.fVerbose) { + LOGF(info, "\033[1;33m%s at line %d : oa->At(0)->GetName() = %s \033[0m", __FUNCTION__, __LINE__, oa->At(0)->GetName()); + LOGF(info, "\033[1;33m%s at line %d : oa->At(1)->GetName() = %s \033[0m", __FUNCTION__, __LINE__, oa->At(1)->GetName()); + } + + ec.fCentralityValues[0] = GetCentralityPercentile(oa->At(0)->GetName()); + ec.fCentralityValues[1] = GetCentralityPercentile(oa->At(1)->GetName()); + delete oa; // yes + + // Okay, do the thing: + // *) "Relative" <=> |(firstEstimator-secondEstimator)/(firstEstimator+secondEstimator)| > treshold => reject the event => alright = false + // *) "Absolute" <=> |firstEstimator-secondEstimator| > treshold => reject the event => alright = false + // *) ... + if (ec.fCentralityValues[0] > 0. && ec.fCentralityValues[1] > 0.) { + if (ec.fCentralityCorrelationsCutVersion.EqualTo("Relative")) { + if (std::abs((ec.fCentralityValues[0] - ec.fCentralityValues[1]) / (ec.fCentralityValues[0] + ec.fCentralityValues[1])) > ec.fCentralityCorrelationsCutTreshold) { + alright = false; + } + } else if (ec.fCentralityCorrelationsCutVersion.EqualTo("Absolute")) { + if (std::abs((ec.fCentralityValues[0] - ec.fCentralityValues[1])) > ec.fCentralityCorrelationsCutTreshold) { + alright = false; + } + } else { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + } // if(ec.fCentralityValues[0] > 0. && ec.fCentralityValues[1] > 0.) + + if (tc.fVerbose) { + LOGF(info, "\033[1;33m%s at line %d : %f, %f, %f, %d \033[0m", __FUNCTION__, __LINE__, ec.fCentralityValues[0], ec.fCentralityValues[1], ec.fCentralityCorrelationsCutTreshold, static_cast(alright)); + ExitFunction(__FUNCTION__); + } + + return alright; + + } // bool CentralityCorrelationCut() + + //============================================================ + + template + void ParticleCutsCounters(T const& track) + { + // Use this function to fill absolute and sequential particle cut counters. Use only during QA, as this is computationally heavy (I mean really). + + if (tc.fVerboseForEachParticle) { + StartFunction(__FUNCTION__); + } + + // *) Establish ordering of binning in particle cut counters histograms, which resembles ordering of particle cuts implementation: + if (!pc.fParticleCutCounterBinLabelingIsDone) { + pc.fParticleCutCounterBinNumber[eRec] = 1; // remember that I cannot use 'rs' here as an index, because the enum eRecSim covers separately Run 1 and Run 2, etc. + pc.fParticleCutCounterBinNumber[eSim] = 1; + ParticleCuts(track, eCutCounterBinning); // dry call, to establish the map fParticleCutCounterMap and its inverse + + // **) Map this ordering into bin labels of actual histograms for particle cut counters: + for (int rec_sim = 0; rec_sim < 2; rec_sim++) // reco/sim => I use here exceptionally different var 'rec_sim', not the shadow 'rs' in the template parameter + { + for (int cc = 0; cc < eCutCounter_N; cc++) // enum eCutCounter + { + if (!pc.fParticleCutCounterHist[rec_sim][cc]) { + continue; + } + + if (tc.fUseSetBinLabel) { + + for (int bin = 1; bin < pc.fParticleCutCounterBinNumber[rec_sim]; bin++) // implemented and used particle cuts in this analysis + { + pc.fParticleCutCounterHist[rec_sim][cc]->GetXaxis()->SetBinLabel(bin, FancyFormatting(pc.fParticleCutName[pc.fParticleCutCounterMap[rec_sim]->GetValue(bin)].Data())); + } + for (int bin = pc.fParticleCutCounterBinNumber[rec_sim]; bin <= eParticleCuts_N; bin++) // implemented, but unused particle cuts in this analysis + { + pc.fParticleCutCounterHist[rec_sim][cc]->GetXaxis()->SetBinLabel(bin, Form("binNo = %d (unused cut)", bin)); + // Remark: I have to write here something concrete as a bin label, if I leave "TBI" for all bin labels here for cuts which were not used, + // I get this harmless but annoying warning during merging: + // Warning in : Histogram fParticleCutCounterHist[rec][seq] has duplicate labels in the x axis. Bin contents will be merged in a single bin + // TBI 20241130 as a better solution, I shall re-define this histogram with the narower range on x-axis... + } + + } else { + + // Workaround for SetBinLabel() large memory consumption: + TString yAxisTitle = ""; + for (int bin = 1; bin < pc.fParticleCutCounterBinNumber[rec_sim]; bin++) // implemented and used cuts in this analysis + { + yAxisTitle += TString::Format("%d:%s; ", bin, FancyFormatting(pc.fParticleCutName[pc.fParticleCutCounterMap[rec_sim]->GetValue(bin)].Data())); + } + for (int bin = pc.fParticleCutCounterBinNumber[rec_sim]; bin <= eParticleCuts_N; bin++) // implemented, but unused cuts in this analysis + { + yAxisTitle += TString::Format("%d:%s; ", bin, TString::Format("binNo = %d (unused cut)", bin).Data()); + } + + // *) Insanity check on the number of fields in this specially crafted y-axis title: + TObjArray* oa = yAxisTitle.Tokenize(";"); + if (!oa) { + LOGF(fatal, "\033[1;31m%s at line %d : oa is NULL\033[0m", __FUNCTION__, __LINE__); + } + if (oa->GetEntries() - 1 != pc.fParticleCutCounterHist[rec_sim][cc]->GetNbinsX()) { + LOGF(fatal, "\033[1;31m%s at line %d : oa->GetEntries() = %d != pc.fParticleCutCounterHist[rec_sim][cc]->GetNbinsX() = %d\033[0m", __FUNCTION__, __LINE__, oa->GetEntries(), pc.fParticleCutCounterHist[rec_sim][cc]->GetNbinsX()); + } + delete oa; + + // *) Okay, set the title: + pc.fParticleCutCounterHist[rec_sim][cc]->GetYaxis()->SetTitle(yAxisTitle.Data()); + } + // All cuts which were implemeted, but not used I simply do not show (i can always UnZoom x-axis in TBrowser, if I want to see 'em). + pc.fParticleCutCounterHist[rec_sim][cc]->GetXaxis()->SetRangeUser(pc.fParticleCutCounterHist[rec_sim][cc]->GetBinLowEdge(1), pc.fParticleCutCounterHist[rec_sim][cc]->GetBinLowEdge(pc.fParticleCutCounterBinNumber[rec_sim])); + } + } + pc.fParticleCutCounterBinLabelingIsDone = true; // this flag ensures that this specific binning is performed only once, for the first processed particle + // delete pc.fParticleCutCounterMap[eRec]; // TBI 20240508 if i do not need them later, I could delete here + // delete pc.fParticleCutCounterMap[eSim]; + // delete pc.fParticleCutCounterMapInverse[eRec]; + // delete pc.fParticleCutCounterMapInverse[eSim]; + } // if (!pc.fParticleCutCounterBinLabelingIsDone) { + + // *) Particle cut counter (absolute): + if (pc.fUseParticleCutCounterAbsolute) { + pc.fParticleCutCounterBinNumber[eRec] = 1; + pc.fParticleCutCounterBinNumber[eSim] = 1; + ParticleCuts(track, eCutCounterAbsolute); + } + + // *) Particle cut counter (sequential): + if (pc.fUseParticleCutCounterSequential) { + pc.fParticleCutCounterBinNumber[eRec] = 1; + pc.fParticleCutCounterBinNumber[eSim] = 1; + ParticleCuts(track, eCutCounterSequential); + } + + } // template void ParticleCutsCounters(T const& track) + + //============================================================ + + template + bool ParticleCuts(T const& track, eCutModus cutModus) + { + // Particle cuts on reconstructed and simulated data. Supports particle cut counters, both absolute and sequential. + // There is also a related enum eParticleCuts. + // Remark: I have added to all if statemets below which deals with floats, e.g. std::abs(track.eta() - pc.fdParticleCuts[eEta][eMax]) < tc.fFloatingPointPrecision , + // to enforce the ROOT convention: "lower boundary included, upper boundary excluded" + + // a) Particle cuts on reconstructed, and corresponding MC truth simulated (common to Run 3, Run 2 and Run 1); + // b) Particle cuts only on simulated (common to Run 3, Run 2 and Run 1); + // c) Particle cuts on reconstructed, and corresponding MC truth simulated (Run 3 specific); + // d) Particle cuts on simulated (Run 3 specific); + // e) Particle cuts on reconstructed, and corresponding MC truth simulated (Run 1 and 2 specific); // In case there is some corner case between Run 1 and Run 2, simply branch further this one + // f) Particle cuts on simulated (Run 1 and 2 specific); // In case there is some corner case between Run 1 and Run 2, simply branch further this one + // *) Particle cuts on Test case; + // *) Toy NUA. + + // :pc + + if (tc.fVerboseForEachParticle) { + StartFunction(__FUNCTION__); + } + + // a) Particle cuts on reconstructed, and corresponding MC truth simulated (common to Run 3, Run 2 and Run 1) ... + if constexpr (rs == eRec || rs == eRecAndSim || rs == eRec_Run2 || rs == eRecAndSim_Run2 || rs == eRec_Run1 || rs == eRecAndSim_Run1 || rs == eQA) { + + // *) Phi: + if (pc.fUseParticleCuts[ePhi]) { + if (cutModus == eCutCounterBinning) { + ParticleCut(eRec, ePhi, eCutCounterBinning); + } else if (track.phi() < pc.fdParticleCuts[ePhi][eMin] || track.phi() > pc.fdParticleCuts[ePhi][eMax] || std::abs(track.phi() - pc.fdParticleCuts[ePhi][eMax]) < tc.fFloatingPointPrecision) { + if (!ParticleCut(eRec, ePhi, cutModus)) { + return false; + } + } + } + + // *) Pt: + if (pc.fUseParticleCuts[ePt]) { + if (cutModus == eCutCounterBinning) { + ParticleCut(eRec, ePt, eCutCounterBinning); + } else if (track.pt() < pc.fdParticleCuts[ePt][eMin] || track.pt() > pc.fdParticleCuts[ePt][eMax] || std::abs(track.pt() - pc.fdParticleCuts[ePt][eMax]) < tc.fFloatingPointPrecision) { + if (!ParticleCut(eRec, ePt, cutModus)) { + return false; + } + } + } + + // *) Eta: + if (pc.fUseParticleCuts[eEta]) { + if (cutModus == eCutCounterBinning) { + ParticleCut(eRec, eEta, eCutCounterBinning); + } else if (track.eta() < pc.fdParticleCuts[eEta][eMin] || track.eta() > pc.fdParticleCuts[eEta][eMax] || std::abs(track.eta() - pc.fdParticleCuts[eEta][eMax]) < tc.fFloatingPointPrecision) { + if (!ParticleCut(eRec, eEta, cutModus)) { + return false; + } + } + } + + // *) Charge: + if (pc.fUseParticleCuts[eCharge]) { + if (cutModus == eCutCounterBinning) { + ParticleCut(eRec, eCharge, eCutCounterBinning); + } else if (0 == track.sign() || track.sign() < pc.fdParticleCuts[eCharge][eMin] || track.sign() > pc.fdParticleCuts[eCharge][eMax]) { + // With first condition, I always throw away neutral particles. + // I can use safely == here, because track.sign() returns short int. + if (!ParticleCut(eRec, eCharge, cutModus)) { + return false; + } + } + } + + // *) tpcNClsFindable: + if (pc.fUseParticleCuts[etpcNClsFindable]) { + if (cutModus == eCutCounterBinning) { + ParticleCut(eRec, etpcNClsFindable, eCutCounterBinning); + } else if (track.tpcNClsFindable() < pc.fdParticleCuts[etpcNClsFindable][eMin] || track.tpcNClsFindable() > pc.fdParticleCuts[etpcNClsFindable][eMax]) { + if (!ParticleCut(eRec, etpcNClsFindable, cutModus)) { + return false; + } + } + } + + // *) tpcNClsShared: + if (pc.fUseParticleCuts[etpcNClsShared]) { + if (cutModus == eCutCounterBinning) { + ParticleCut(eRec, etpcNClsShared, eCutCounterBinning); + } else if (track.tpcNClsShared() < pc.fdParticleCuts[etpcNClsShared][eMin] || track.tpcNClsShared() > pc.fdParticleCuts[etpcNClsShared][eMax]) { + if (!ParticleCut(eRec, etpcNClsShared, cutModus)) { + return false; + } + } + } + + // *) itsChi2NCl + if (pc.fUseParticleCuts[eitsChi2NCl]) { + if (cutModus == eCutCounterBinning) { + ParticleCut(eRec, eitsChi2NCl, eCutCounterBinning); + } else if (track.itsChi2NCl() < pc.fdParticleCuts[eitsChi2NCl][eMin] || track.itsChi2NCl() > pc.fdParticleCuts[eitsChi2NCl][eMax]) { + if (!ParticleCut(eRec, eitsChi2NCl, cutModus)) { + return false; + } + } + } + + // *) tpcNClsFound: + if (pc.fUseParticleCuts[etpcNClsFound]) { + if (cutModus == eCutCounterBinning) { + ParticleCut(eRec, etpcNClsFound, eCutCounterBinning); + } else if (track.tpcNClsFound() < pc.fdParticleCuts[etpcNClsFound][eMin] || track.tpcNClsFound() > pc.fdParticleCuts[etpcNClsFound][eMax]) { + if (!ParticleCut(eRec, etpcNClsFound, cutModus)) { + return false; + } + } + } + + // *) tpcNClsCrossedRows: + if (pc.fUseParticleCuts[etpcNClsCrossedRows]) { + if (cutModus == eCutCounterBinning) { + ParticleCut(eRec, etpcNClsCrossedRows, eCutCounterBinning); + } else if (track.tpcNClsCrossedRows() < pc.fdParticleCuts[etpcNClsCrossedRows][eMin] || track.tpcNClsCrossedRows() > pc.fdParticleCuts[etpcNClsCrossedRows][eMax]) { + if (!ParticleCut(eRec, etpcNClsCrossedRows, cutModus)) { + return false; + } + } + } + + // *) itsNCls: + if (pc.fUseParticleCuts[eitsNCls]) { + if (cutModus == eCutCounterBinning) { + ParticleCut(eRec, eitsNCls, eCutCounterBinning); + } else if (track.itsNCls() < pc.fdParticleCuts[eitsNCls][eMin] || track.itsNCls() > pc.fdParticleCuts[eitsNCls][eMax]) { + if (!ParticleCut(eRec, eitsNCls, cutModus)) { + return false; + } + } + } + + // *) itsNClsInnerBarrel: + if (pc.fUseParticleCuts[eitsNClsInnerBarrel]) { + if (cutModus == eCutCounterBinning) { + ParticleCut(eRec, eitsNClsInnerBarrel, eCutCounterBinning); + } else if (track.itsNClsInnerBarrel() < pc.fdParticleCuts[eitsNClsInnerBarrel][eMin] || track.itsNClsInnerBarrel() > pc.fdParticleCuts[eitsNClsInnerBarrel][eMax]) { + if (!ParticleCut(eRec, eitsNClsInnerBarrel, cutModus)) { + return false; + } + } + } + + // *) tpcCrossedRowsOverFindableCls: + if (pc.fUseParticleCuts[etpcCrossedRowsOverFindableCls]) { + if (cutModus == eCutCounterBinning) { + ParticleCut(eRec, etpcCrossedRowsOverFindableCls, eCutCounterBinning); + } else if (track.tpcCrossedRowsOverFindableCls() < pc.fdParticleCuts[etpcCrossedRowsOverFindableCls][eMin] || track.tpcCrossedRowsOverFindableCls() > pc.fdParticleCuts[etpcCrossedRowsOverFindableCls][eMax] || std::abs(track.tpcCrossedRowsOverFindableCls() - pc.fdParticleCuts[etpcCrossedRowsOverFindableCls][eMax]) < tc.fFloatingPointPrecision) { + if (!ParticleCut(eRec, etpcCrossedRowsOverFindableCls, cutModus)) { + return false; + } + } + } + + // *) tpcFoundOverFindableCls: + if (pc.fUseParticleCuts[etpcFoundOverFindableCls]) { + if (cutModus == eCutCounterBinning) { + ParticleCut(eRec, etpcFoundOverFindableCls, eCutCounterBinning); + } else if (track.tpcFoundOverFindableCls() < pc.fdParticleCuts[etpcFoundOverFindableCls][eMin] || track.tpcFoundOverFindableCls() > pc.fdParticleCuts[etpcFoundOverFindableCls][eMax] || std::abs(track.tpcFoundOverFindableCls() - pc.fdParticleCuts[etpcFoundOverFindableCls][eMax]) < tc.fFloatingPointPrecision) { + if (!ParticleCut(eRec, etpcFoundOverFindableCls, cutModus)) { + return false; + } + } + } + + // *) tpcFractionSharedCls: + if (pc.fUseParticleCuts[etpcFractionSharedCls]) { + if (cutModus == eCutCounterBinning) { + ParticleCut(eRec, etpcFractionSharedCls, eCutCounterBinning); + } else if (track.tpcFractionSharedCls() < pc.fdParticleCuts[etpcFractionSharedCls][eMin] || track.tpcFractionSharedCls() > pc.fdParticleCuts[etpcFractionSharedCls][eMax] || std::abs(track.tpcFractionSharedCls() - pc.fdParticleCuts[etpcFractionSharedCls][eMax]) < tc.fFloatingPointPrecision) { + if (!ParticleCut(eRec, etpcFractionSharedCls, cutModus)) { + return false; + } + } + } + + // *) tpcChi2NCl: + if (pc.fUseParticleCuts[etpcChi2NCl]) { + if (cutModus == eCutCounterBinning) { + ParticleCut(eRec, etpcChi2NCl, eCutCounterBinning); + } else if (track.tpcChi2NCl() < pc.fdParticleCuts[etpcChi2NCl][eMin] || track.tpcChi2NCl() > pc.fdParticleCuts[etpcChi2NCl][eMax] || std::abs(track.tpcChi2NCl() - pc.fdParticleCuts[etpcChi2NCl][eMax]) < tc.fFloatingPointPrecision) { + if (!ParticleCut(eRec, etpcChi2NCl, cutModus)) { + return false; + } + } + } + + // *) dcaXY: + if (pc.fUseParticleCuts[edcaXY]) { + if (cutModus == eCutCounterBinning) { + ParticleCut(eRec, edcaXY, eCutCounterBinning); + } else if (track.dcaXY() < pc.fdParticleCuts[edcaXY][eMin] || track.dcaXY() > pc.fdParticleCuts[edcaXY][eMax] || std::abs(track.dcaXY() - pc.fdParticleCuts[edcaXY][eMax]) < tc.fFloatingPointPrecision) { + if (!ParticleCut(eRec, edcaXY, cutModus)) { + return false; + } + } + } + + // *) dcaZ: + if (pc.fUseParticleCuts[edcaZ]) { + if (cutModus == eCutCounterBinning) { + ParticleCut(eRec, edcaZ, eCutCounterBinning); + } else if (track.dcaZ() < pc.fdParticleCuts[edcaZ][eMin] || track.dcaZ() > pc.fdParticleCuts[edcaZ][eMax] || std::abs(track.dcaZ() - pc.fdParticleCuts[edcaZ][eMax]) < tc.fFloatingPointPrecision) { + if (!ParticleCut(eRec, edcaZ, cutModus)) { + return false; + } + } + } + + // *) trackCutFlag: + if (pc.fUseParticleCuts[etrackCutFlag]) { + if (cutModus == eCutCounterBinning) { + ParticleCut(eRec, etrackCutFlag, eCutCounterBinning); + } else if (!track.trackCutFlag()) { + if (!ParticleCut(eRec, etrackCutFlag, cutModus)) { + return false; + } + } + } + + // *) trackCutFlagFb1: + if (pc.fUseParticleCuts[etrackCutFlagFb1]) { + if (cutModus == eCutCounterBinning) { + ParticleCut(eRec, etrackCutFlagFb1, eCutCounterBinning); + } else if (!track.trackCutFlagFb1()) { + if (!ParticleCut(eRec, etrackCutFlagFb1, cutModus)) { + return false; + } + } + } + + // *) trackCutFlagFb2: + if (pc.fUseParticleCuts[etrackCutFlagFb2]) { + if (cutModus == eCutCounterBinning) { + ParticleCut(eRec, etrackCutFlagFb2, eCutCounterBinning); + } else if (!track.trackCutFlagFb2()) { + if (!ParticleCut(eRec, etrackCutFlagFb2, cutModus)) { + return false; + } + } + } + + // *) isQualityTrack: + if (pc.fUseParticleCuts[eisQualityTrack]) { + if (cutModus == eCutCounterBinning) { + ParticleCut(eRec, eisQualityTrack, eCutCounterBinning); + } else if (!track.isQualityTrack()) { + if (!ParticleCut(eRec, eisQualityTrack, cutModus)) { + return false; + } + } + } + + // *) isPrimaryTrack: + if (pc.fUseParticleCuts[eisPrimaryTrack]) { + if (cutModus == eCutCounterBinning) { + ParticleCut(eRec, eisPrimaryTrack, eCutCounterBinning); + } else if (!track.isPrimaryTrack()) { + if (!ParticleCut(eRec, eisPrimaryTrack, cutModus)) { + return false; + } + } + } + + // *) isInAcceptanceTrack: + if (pc.fUseParticleCuts[eisInAcceptanceTrack]) { + if (cutModus == eCutCounterBinning) { + ParticleCut(eRec, eisInAcceptanceTrack, eCutCounterBinning); + } else if (!track.isInAcceptanceTrack()) { + if (!ParticleCut(eRec, eisInAcceptanceTrack, cutModus)) { + return false; + } + } + } + + // *) isGlobalTrack: + if (pc.fUseParticleCuts[eisGlobalTrack]) { + if (cutModus == eCutCounterBinning) { + ParticleCut(eRec, eisGlobalTrack, eCutCounterBinning); + } else if (!track.isGlobalTrack()) { + if (!ParticleCut(eRec, eisGlobalTrack, cutModus)) { + return false; + } + } + } + + // *) isPVContributor: + if (pc.fUseParticleCuts[eisPVContributor]) { + if (cutModus == eCutCounterBinning) { + ParticleCut(eRec, eisPVContributor, eCutCounterBinning); + } else if (!track.isPVContributor()) { + if (!ParticleCut(eRec, eisPVContributor, cutModus)) { + return false; + } + } + } + + // *) PtDependentDCAxyParameterization: + if (pc.fUseParticleCuts[ePtDependentDCAxyParameterization]) { + if (cutModus == eCutCounterBinning) { + ParticleCut(eRec, ePtDependentDCAxyParameterization, eCutCounterBinning); + } else if (std::abs(track.dcaXY()) > pc.fPtDependentDCAxyFormula->Eval(track.pt())) { + if (!ParticleCut(eRec, ePtDependentDCAxyParameterization, cutModus)) { + return false; + } + } + } + + // ... + + // ... and corresponding MC truth simulated: + // See https://github.com/AliceO2Group/O2Physics/blob/master/Tutorials/src/mcHistograms.cxx + // See https://aliceo2group.github.io/analysis-framework/docs/datamodel/ao2dTables.html#montecarlo + if constexpr (rs == eRecAndSim || rs == eRecAndSim_Run2 || rs == eRecAndSim_Run1) { + + if (!track.has_mcParticle()) { + LOGF(warning, "No MC particle for this track, skip..."); + return false; // TBI 20231107 re-think. I shouldn't probably get to this point, if MC truth info doesn't exist for this track + } + // auto mcParticle = track.mcParticle(); // corresponding MC truth simulated particle + + // In this branch I can cut additionally and directly on corresponding MC truth simulated, e.g. on mcParticle.pt() + // In case I implement something here, remember to switch from eRec to eSim when calling e.g. ParticleCut(...) + + // // *) Phi: TBI 2024-511 re-think if i really cut directly on MC truth kine and other info and keep it in sync with what I did in AliPhysics + // if (pc.fUseParticleCuts[ePhi]) { + // if (cutModus == eCutCounterBinning) { + // ParticleCut(eSim, ePhi, eCutCounterBinning); + // } else if (mcParticle.phi() < pc.fdParticleCuts[ePhi][eMin] || mcParticle.phi() > pc.fdParticleCuts[ePhi][eMax]) { + // if (!ParticleCut(eSim, ePhi, cutModus)) { + // return false; + // } + // } + // } + + // *) Charge: TBI 20240511 mcParticle.sign() doesn't exist, get charge from tc.fDatabasePDG instead using PDG code , as I did it below + + // if (pc.fUseParticleCuts[eCharge]) { + // if (cutModus == eCutCounterBinning) { + // ParticleCut(eSim, eCharge, eCutCounterBinning); + // } else if (0 == mcParticle.sign() || mcParticle.sign() < pc.fdParticleCuts[eCharge][eMin] || mcParticle.sign() > pc.fdParticleCuts[eCharge][eMax]) { + // // TBI 20240511 with first condition, I always throw away neutral particles, so for the time being that is hardcoded + // if (!ParticleCut(eSim, eCharge, cutModus)) { + // return false; + // } + // } + // } + + // TBI 20240511 add cut on PDG + + // ... + + } // if constexpr (rs == eRecAndSim || rs == eRecAndSim_Run2 || rs == eRecAndSim_Run1) { + + } // if constexpr (rs == eRec || rs == eRecAndSim || rs == eRec_Run2 || rs == eRecAndSim_Run2 || rs == eRec_Run1 || rs == eRecAndSim_Run1) { + + // ------------------------------------------------------------------------- + + // b) Particle cuts only on simulated (common to Run 3, Run 2 and Run 1): + // Remark #1: This branch is relevant when processing ONLY simulated data at generator level. + // Remark #2: In this branch, 'track' is always TracksSim = aod::McParticles, see https://aliceo2group.github.io/analysis-framework/docs/datamodel/ao2dTables.html#montecarlo + if constexpr (rs == eSim || rs == eSim_Run2 || rs == eSim_Run1) { + + // *) Phi: + if (pc.fUseParticleCuts[ePhi]) { + if (cutModus == eCutCounterBinning) { + ParticleCut(eSim, ePhi, eCutCounterBinning); + } else if (track.phi() < pc.fdParticleCuts[ePhi][eMin] || track.phi() > pc.fdParticleCuts[ePhi][eMax] || std::abs(track.phi() - pc.fdParticleCuts[ePhi][eMax]) < tc.fFloatingPointPrecision) { + if (!ParticleCut(eSim, ePhi, cutModus)) { + return false; + } + } + } + + // *) Pt: + if (pc.fUseParticleCuts[ePt]) { + if (cutModus == eCutCounterBinning) { + ParticleCut(eSim, ePt, eCutCounterBinning); + } else if (track.pt() < pc.fdParticleCuts[ePt][eMin] || track.pt() > pc.fdParticleCuts[ePt][eMax] || std::abs(track.pt() - pc.fdParticleCuts[ePt][eMax]) < tc.fFloatingPointPrecision) { + if (!ParticleCut(eSim, ePt, cutModus)) { + return false; + } + } + } + + // *) Eta: + if (pc.fUseParticleCuts[eEta]) { + if (cutModus == eCutCounterBinning) { + ParticleCut(eSim, eEta, eCutCounterBinning); + } else if (track.eta() < pc.fdParticleCuts[eEta][eMin] || track.eta() > pc.fdParticleCuts[eEta][eMax] || std::abs(track.eta() - pc.fdParticleCuts[eEta][eMax]) < tc.fFloatingPointPrecision) { + if (!ParticleCut(eSim, eEta, cutModus)) { + return false; + } + } + } + + /* + // *) Charge: + if (pc.fUseParticleCuts[eCharge]) { + double charge = -44.; // yes, never initialize charge to 0. + if (tc.fDatabasePDG && tc.fDatabasePDG->GetParticle(track.pdgCode())) { + // Yes, I have to check the 2nd condition, because e.g. for PDG code 1000010020 (deuteron), GetParticle(...) returns NULL + charge = tc.fDatabasePDG->GetParticle(track.pdgCode())->Charge() / 3.; // yes, divided by 3. Fundamental unit of charge is associated with quarks + if (tc.fVerboseForEachParticle) { + LOGF(info, "\033[1;33m%s at line %d: !!!! WARNING !!!! There is a large memory blow-up when using TDatabasePDG !!!! WARNING !!!! \033[0m", __FUNCTION__, __LINE__); + } + } + if (cutModus == eCutCounterBinning) { + ParticleCut(eSim, eCharge, eCutCounterBinning); + } else if (0 == static_cast(charge) || charge < pc.fdParticleCuts[eCharge][eMin] || charge > pc.fdParticleCuts[eCharge][eMax]) { + // TBI 20250611 with first condition, I always throw away neutral particles when O2DatabasePDG is used. + // However due to initialization charge = 0. that way I throw all particles when O2DatabasePDG is NOT used. + // Therefore, when O2DatabasePDG is NOT used, I have to disable cut on charge, since that info is not available. + if (!ParticleCut(eSim, eCharge, cutModus)) { + return false; + } + } + } + + */ + + // *) PDG code: + if (pc.fUseParticleCuts[ePDG]) { + if (cutModus == eCutCounterBinning) { + ParticleCut(eSim, ePDG, eCutCounterBinning); + } else if (track.pdgCode() < pc.fdParticleCuts[ePDG][eMin] || track.pdgCode() > pc.fdParticleCuts[ePDG][eMax]) { + // TBI 20250611 I need to generalize this, e.g. add support to process more that one PDG code (e.g. 2212 and -2212, etc.) + if (!ParticleCut(eSim, ePDG, cutModus)) { + return false; + } + } + } + + // ... + + } // if constexpr (rs == eSim || rs == eSim_Run2 || rs == eSim_Run1) { + + // ------------------------------------------------------------------------- + + // c) Particle cuts on reconstructed, and corresponding MC truth simulated (Run 3 specific): + // Remark: I implement here only the particle cuts which are not already in group a) above, and which make sense only for Run 3 data. + if constexpr (rs == eRec || rs == eRecAndSim || rs == eQA) { + + // ... + + // ... and corresponding MC truth simulated (Run 3 specific): + if constexpr (rs == eRecAndSim) { + + if (!track.has_mcParticle()) { + LOGF(warning, "No MC particle for this track, skip..."); + return false; // TBI 20231107 re-think. I shouldn't probably get to this point, if MC truth info doesn't exist for this track + } + // auto mcParticle = track.mcParticle(); // corresponding MC truth simulated particle + + // ... + + } // if constexpr (rs == eRecAndSim) { + + } // if constexpr (rs == eRec || rs == eRecAndSim) { + + // ------------------------------------------------------------------------- + + // d) Particle cuts on simulated (Run 3 specific): + // Remark #1: I implement here only the particle cuts which are not already in group b) above, and which make sense only for Run 3 data. + // Remark #2: In this branch, 'track' is always TracksSim = aod::McParticles, see https://aliceo2group.github.io/analysis-framework/docs/datamodel/ao2dTables.html#montecarlo + // See how I handled the case b) above. + if constexpr (rs == eSim) { + + // ... + + } // if constexpr (rs == eSim) { + + // ------------------------------------------------------------------------- + + // e) Particle cuts on reconstructed, and corresponding MC truth simulated (Run 1 and 2 specific): + // Remark: I implement here only the particle cuts which are not already in group a) above, and which make sense only for Run 1 and 2 data. + if constexpr (rs == eRec_Run2 || rs == eRecAndSim_Run2 || rs == eRec_Run1 || rs == eRecAndSim_Run1) { + + // ... + + // ... and corresponding MC truth simulated: + // See https://github.com/AliceO2Group/O2Physics/blob/master/Tutorials/src/mcHistograms.cxx + // See https://aliceo2group.github.io/analysis-framework/docs/datamodel/ao2dTables.html#montecarlo + if constexpr (rs == eRecAndSim_Run2 || rs == eRecAndSim_Run1) { + + if (!track.has_mcParticle()) { + LOGF(warning, "No MC particle for this track, skip..."); + return false; // TBI 20231107 re-think. I shouldn't probably get to this point, if MC truth info doesn't exist for this track + } + // auto mcParticle = track.mcParticle(); // corresponding MC truth simulated particle + + // ... + + } // if constexpr (rs == eRecAndSim_Run2 || rs == eRecAndSim_Run1) { + + } // if constexpr (rs == eRec_Run2 || rs == eRecAndSim_Run2 || rs == eRec_Run1 || rs == eRecAndSim_Run1) { + + // ------------------------------------------------------------------------- + + // f) Event cuts on simulated (Run 1 and 2 specific) + // Remark #1: I implement here only the event cuts which are not already in group b) above, and which make sense only for Run 1 and 2 data. + // Remark #2: In this branch, 'track' is always TracksSim = aod::McParticles, see https://aliceo2group.github.io/analysis-framework/docs/datamodel/ao2dTables.html#montecarlo + // See how I handled the case b) above. + if constexpr (rs == eSim_Run2 || rs == eSim_Run1) { + + // ... + + } // if constexpr (rs == eSim_Run2 || rs == eSim_Run1) { + + // ------------------------------------------------------------------------- + + // *) Test case: + if constexpr (rs == eTest) { + // This branch corresponds to process with minimal subscription - I implement just a few example cuts, just for testing purposes. + // Only eRec is support in Test for the time being. + + // *) Phi: + if (pc.fUseParticleCuts[ePhi]) { + if (cutModus == eCutCounterBinning) { + ParticleCut(eRec, ePhi, eCutCounterBinning); + } else if (track.phi() < pc.fdParticleCuts[ePhi][eMin] || track.phi() > pc.fdParticleCuts[ePhi][eMax] || std::abs(track.phi() - pc.fdParticleCuts[ePhi][eMax]) < tc.fFloatingPointPrecision) { + if (!ParticleCut(eRec, ePhi, cutModus)) { + return false; + } + } + } + + // *) Pt: + if (pc.fUseParticleCuts[ePt]) { + if (cutModus == eCutCounterBinning) { + ParticleCut(eRec, ePt, eCutCounterBinning); + } else if (track.pt() < pc.fdParticleCuts[ePt][eMin] || track.pt() > pc.fdParticleCuts[ePt][eMax] || std::abs(track.pt() - pc.fdParticleCuts[ePt][eMax]) < tc.fFloatingPointPrecision) { + if (!ParticleCut(eRec, ePt, cutModus)) { + return false; + } + } + } + + // *) Eta: + if (pc.fUseParticleCuts[eEta]) { + if (cutModus == eCutCounterBinning) { + ParticleCut(eRec, eEta, eCutCounterBinning); + } else if (track.eta() < pc.fdParticleCuts[eEta][eMin] || track.eta() > pc.fdParticleCuts[eEta][eMax] || std::abs(track.eta() - pc.fdParticleCuts[eEta][eMax]) < tc.fFloatingPointPrecision) { + if (!ParticleCut(eRec, eEta, cutModus)) { + return false; + } + } + } + + // ... + + } // if constexpr (rs == eTest) { + + // ------------------------------------------------------------------------- + + // *) Toy NUA: + // TBI 20250718 Check if can optimize here something by using new global pbyp.fPhi, pbyp.fPt, etc, variables. Most likely yes, since I would avoid calling again track.phi(), etc. + // But I do not use Toy NUA in any case for real large-scale data analysis. + if (nua.fApplyNUAPDF[ePhiNUAPDF] || nua.fApplyNUAPDF[ePtNUAPDF] || nua.fApplyNUAPDF[eEtaNUAPDF]) { + + // Remark: I do not for the time being add Toy NUA cuts to particle cut counters, since in this case I can inspect direcly from phi, pt and eta distributions. + + // Local kine variables on which support for Toy NUA is implemented and applied: + double dPhi = 0.; + double dPt = 0.; + double dEta = 0.; + + // *) Apply Toy NUA on info available in reconstructed (and the corresponding MC truth simulated track); + if constexpr (rs == eRec || rs == eRecAndSim || rs == eRec_Run2 || rs == eRecAndSim_Run2 || rs == eRec_Run1 || rs == eRecAndSim_Run1) { + dPhi = track.phi(); + dPt = track.pt(); + dEta = track.eta(); + + // Apply NUA on these kine variables: + if (nua.fApplyNUAPDF[ePhiNUAPDF] && !Accept(dPhi, ePhiNUAPDF)) { + return false; + } + if (nua.fApplyNUAPDF[ePtNUAPDF] && !Accept(dPt, ePtNUAPDF)) { + return false; + } + if (nua.fApplyNUAPDF[eEtaNUAPDF] && !Accept(dEta, eEtaNUAPDF)) { + return false; + } + + // ... and corresponding MC truth simulated ( see https://github.com/AliceO2Group/O2Physics/blob/master/Tutorials/src/mcHistograms.cxx ): + if constexpr (rs == eRecAndSim || rs == eRecAndSim_Run2 || rs == eRecAndSim_Run1) { + if (!track.has_mcParticle()) { + LOGF(warning, "No MC particle for this track, skip..."); + return false; // TBI 20231107 re-think. I shouldn't probably get to this point, if MC truth info doesn't exist for this particle + } + auto mcParticle = track.mcParticle(); // corresponding MC truth simulated particle + dPhi = mcParticle.phi(); + dPt = mcParticle.pt(); + dEta = mcParticle.eta(); + + // Apply NUA on these kine variables: + if (nua.fApplyNUAPDF[ePhiNUAPDF] && !Accept(dPhi, ePhiNUAPDF)) { + return false; + } + if (nua.fApplyNUAPDF[ePtNUAPDF] && !Accept(dPt, ePtNUAPDF)) { + return false; + } + if (nua.fApplyNUAPDF[eEtaNUAPDF] && !Accept(dEta, eEtaNUAPDF)) { + return false; + } + + } // if constexpr (rs == eRecAndSim || rs == eRecAndSim_Run2 || rs == eRecAndSim_Run1) { + } // if constexpr (rs == eRec || rs == eRecAndSim || rs == eRec_Run2 || rs == eRecAndSim_Run2 || rs == eRec_Run1 || rs == eRecAndSim_Run1) { + + // *) Apply Toy NUA on info available only in simulated data: + if constexpr (rs == eSim || rs == eSim_Run2 || rs == eSim_Run1) { + // Remark: in this branch, 'track' is always TracksSim = aod::McParticles + dPhi = track.phi(); + dPt = track.pt(); + dEta = track.eta(); + + // Apply NUA on these kine variables: + if (nua.fApplyNUAPDF[ePhiNUAPDF] && !Accept(dPhi, ePhiNUAPDF)) { + return false; + } + if (nua.fApplyNUAPDF[ePtNUAPDF] && !Accept(dPt, ePtNUAPDF)) { + return false; + } + if (nua.fApplyNUAPDF[eEtaNUAPDF] && !Accept(dEta, eEtaNUAPDF)) { + return false; + } + } // if constexpr (rs == eSim || rs == eSim_Run2 || rs == eSim_Run1) { + + } // if(nua.fApplyNUAPDF[ePhiNUAPDF] || nua.fApplyNUAPDF[ePtNUAPDF] || nua.fApplyNUAPDF[eEtaNUAPDF]) { + + return true; + + } // template bool ParticleCuts(T const& track, eCutModus cutModus) + + //============================================================ + + bool ParticleCut(int rs, int particleCut, eCutModus cutModus) + { + // Helper function to reduce code bloat in ParticleCuts(). It's meant to be used only in ParticleCuts(). + + // Remark: Remember that as a second argument I cannot use enum eParticleCuts, because here in one go I take both enum eParticleCuts and enum eParticleHistograms . + + switch (cutModus) { + case eCut: { + if (tc.fVerboseForEachParticle) { + LOGF(info, "\033[1;31mParticle didn't pass the cut: %s\033[0m", pc.fParticleCutName[particleCut].Data()); + } + return false; + break; + } + case eCutCounterBinning: { + pc.fParticleCutCounterMap[rs]->Add(pc.fParticleCutCounterBinNumber[rs], particleCut); + pc.fParticleCutCounterMapInverse[rs]->Add(particleCut, pc.fParticleCutCounterBinNumber[rs]); + pc.fParticleCutCounterBinNumber[rs]++; // yes + return true; + break; + } + case eCutCounterAbsolute: { + pc.fParticleCutCounterHist[rs][eAbsolute]->Fill(pc.fParticleCutCounterMapInverse[rs]->GetValue(particleCut)); + return true; // yes, so that I can proceed with another cut in ParticleCuts + break; + } + case eCutCounterSequential: { + pc.fParticleCutCounterHist[rs][eSequential]->Fill(pc.fParticleCutCounterMapInverse[rs]->GetValue(particleCut)); + return false; // yes, so that I bail out from ParticleCuts + break; + } + default: { + LOGF(fatal, "\033[1;31m%s at line %d : This cutModus = %d is not supported yet. \033[0m", __FUNCTION__, __LINE__, static_cast(cutModus)); + break; + } + } // switch(cutModus) + + return false; // obsolete, but it suppresses the warning... + + } // bool ParticleCut(int rs, int particleCut, eCutModus cutModus) + + //============================================================ + + template + void FillParticleHistograms(T const& track, eBeforeAfter ba, int weight = 1) + { + // Fill all particle histograms for reconstructed and simulated data. + + // a) Fill reconstructed, and corresponding MC truth simulated (common to Run 3, Run 2 and Run 1); + // b) Fill only simulated (common to Run 3, Run 2 and Run 1); + // c) Fill reconstructed, and corresponding MC truth simulated (Run 3 specific); + // d) Fill only simulated (Run 3 specific); + // e) Fill reconstructed, and corresponding MC truth simulated (Run 1 and 2 specific); // In case there is some corner case between Run 1 and Run 2, simply branch further this one + // f) Fill only simulated (Run 1 and 2 specific); // In case there is some corner case between Run 1 and Run 2, simply branch further this one + // i) Test case. + + // Remark #1: Why weight is introduced as 3rd argument, see explanation in BanishmentLoopOverParticles. + // The efficiency loss for default fill between weight = 1 and previous implementation with no weight, is negligible. + // Remark #2: After calling BanishmentLoopOverParticles, the GetMean(), GetRMS(), GetStdDev(), skewness, kurtosis, etc., of histogram are unaffected. + // But GetMeanErorr(), GetRMSError(), etc. are affected. + // For instance, GetMean() remains the same, because (x+y)/(1+1) = (x+y+z-z)(1+1+1-1). But whenever weight in the formula is taken directly to some higher power, + // like in the calculation of GetMeanError(), this idea with BanishmentLoopOverParticles is not applicable (also when I enable Setw2() in histograms). + // Since from particle histograms I only care about the number of entries, I rarely need even GetMean(), and basically never GetMeanError(), + // I use BanishmentLoopOverParticles . Alternatively, I would need new set of histograms, fill them separately, etc. + + if (tc.fVerboseForEachParticle) { + StartFunction(__FUNCTION__); + } + + if (tc.fInsanityCheckForEachParticle) { + if (1 != std::abs(weight)) { + LOGF(fatal, "\033[1;31m%s at line %d : in the current implementation, weight for particle histograms can be only +1 or -1, weight = %d\033[0m", __FUNCTION__, __LINE__, weight); + } + } + + // a) Fill reconstructed ... (common to Run 3, Run 2 and Run 1): + if constexpr (rs == eRec || rs == eRecAndSim || rs == eRec_Run2 || rs == eRecAndSim_Run2 || rs == eRec_Run1 || rs == eRecAndSim_Run1 || rs == eQA) { + // Remark: Remember to use only eRec and eSim as array indices in histos, also for rs == eRecAndSim, etc. TBI 20240504 shall I introduce generic enum egRec and egSim for this sake? + // TBI 20240414 also here have to hardcode 'eRec', because 'rs' spans over all enums in eRecSim => I definitely need 'generic Rec' case, perhaps via TExMap ? + // But I have already tc.fProcess[eGenericRec] and tc.fProcess[eGenericRecSim], available, shall I simply re-use them? + + // 1D: + if (ph.fFillParticleHistograms) { + + // From o2::aod::Tracks + !ph.fParticleHistograms[ePhi][eRec][ba] ? true : ph.fParticleHistograms[ePhi][eRec][ba]->Fill(track.phi(), weight); + !ph.fParticleHistograms[ePt][eRec][ba] ? true : ph.fParticleHistograms[ePt][eRec][ba]->Fill(track.pt(), weight); + !ph.fParticleHistograms[eEta][eRec][ba] ? true : ph.fParticleHistograms[eEta][eRec][ba]->Fill(track.eta(), weight); + !ph.fParticleHistograms[eCharge][eRec][ba] ? true : ph.fParticleHistograms[eCharge][eRec][ba]->Fill(track.sign(), weight); + + // From o2::aod::TracksExtra_001 + !ph.fParticleHistograms[etpcNClsFindable][eRec][ba] ? true : ph.fParticleHistograms[etpcNClsFindable][eRec][ba]->Fill(track.tpcNClsFindable(), weight); + !ph.fParticleHistograms[etpcNClsShared][eRec][ba] ? true : ph.fParticleHistograms[etpcNClsShared][eRec][ba]->Fill(track.tpcNClsShared(), weight); + !ph.fParticleHistograms[eitsChi2NCl][eRec][ba] ? true : ph.fParticleHistograms[eitsChi2NCl][eRec][ba]->Fill(track.itsChi2NCl(), weight); + !ph.fParticleHistograms[etpcNClsFound][eRec][ba] ? true : ph.fParticleHistograms[etpcNClsFound][eRec][ba]->Fill(track.tpcNClsFound(), weight); + !ph.fParticleHistograms[etpcNClsCrossedRows][eRec][ba] ? true : ph.fParticleHistograms[etpcNClsCrossedRows][eRec][ba]->Fill(track.tpcNClsCrossedRows(), weight); + !ph.fParticleHistograms[eitsNCls][eRec][ba] ? true : ph.fParticleHistograms[eitsNCls][eRec][ba]->Fill(track.itsNCls(), weight); + !ph.fParticleHistograms[eitsNClsInnerBarrel][eRec][ba] ? true : ph.fParticleHistograms[eitsNClsInnerBarrel][eRec][ba]->Fill(track.itsNClsInnerBarrel(), weight); + !ph.fParticleHistograms[etpcCrossedRowsOverFindableCls][eRec][ba] ? true : ph.fParticleHistograms[etpcCrossedRowsOverFindableCls][eRec][ba]->Fill(track.tpcCrossedRowsOverFindableCls(), weight); + !ph.fParticleHistograms[etpcFoundOverFindableCls][eRec][ba] ? true : ph.fParticleHistograms[etpcFoundOverFindableCls][eRec][ba]->Fill(track.tpcFoundOverFindableCls(), weight); + !ph.fParticleHistograms[etpcFractionSharedCls][eRec][ba] ? true : ph.fParticleHistograms[etpcFractionSharedCls][eRec][ba]->Fill(track.tpcFractionSharedCls(), weight); + !ph.fParticleHistograms[etpcChi2NCl][eRec][ba] ? true : ph.fParticleHistograms[etpcChi2NCl][eRec][ba]->Fill(track.tpcChi2NCl(), weight); + + // From o2::aod::TracksDCA + // Remark: For this one, in Run 3 workflow I need helper task o2-analysis-track-propagation, while in Run 2 and 1 I need o2-analysis-trackextension . + !ph.fParticleHistograms[edcaXY][eRec][ba] ? true : ph.fParticleHistograms[edcaXY][eRec][ba]->Fill(track.dcaXY(), weight); + !ph.fParticleHistograms[edcaZ][eRec][ba] ? true : ph.fParticleHistograms[edcaZ][eRec][ba]->Fill(track.dcaZ(), weight); + } + + // 2D: + if (ph.fFillParticleHistograms2D) { + !ph.fParticleHistograms2D[ePhiPt][eRec][ba] ? true : ph.fParticleHistograms2D[ePhiPt][eRec][ba]->Fill(track.phi(), track.pt(), weight); + !ph.fParticleHistograms2D[ePhiEta][eRec][ba] ? true : ph.fParticleHistograms2D[ePhiEta][eRec][ba]->Fill(track.phi(), track.eta(), weight); + } // if (ph.fFillParticleHistograms2D) { + + // nD (THnSparse): + if (ba == eAfter || (eBefore == ba && ph.fFillParticleSparseHistogramsBeforeCuts)) { + // **) eDWPhi : here the fundamental 0-th axis never to be projected out is "phi" + if (ph.fBookParticleSparseHistograms[eDWPhi]) { + // Remark: It is mandatory that ordering in initialization here resembles the ordering in enum eDiffPhiWeights + double vector[eDiffPhiWeights_N] = {track.phi(), track.pt(), track.eta(), static_cast(track.sign()), ebye.fCentrality, ebye.fVz}; + ph.fParticleSparseHistograms[eDWPhi][eRec][ba]->Fill(vector, weight); + } + // **) eDWPt : here the fundamental 0-th axis never to be projected out is "pt" + if (ph.fBookParticleSparseHistograms[eDWPt]) { + // Remark: It is mandatory that ordering in initialization here resembles the ordering in enum eDiffPtWeights + double vector[eDiffPtWeights_N] = {track.pt(), track.eta(), static_cast(track.sign()), ebye.fCentrality}; + ph.fParticleSparseHistograms[eDWPt][eRec][ba]->Fill(vector, weight); + } + // **) eDWEta : here the fundamental 0-th axis never to be projected out is "eta" + if (ph.fBookParticleSparseHistograms[eDWEta]) { + // Remark: It is mandatory that ordering in initialization here resembles the ordering in enum eDiffEtaWeights + double vector[eDiffEtaWeights_N] = {track.eta(), track.pt(), static_cast(track.sign()), ebye.fCentrality}; + ph.fParticleSparseHistograms[eDWEta][eRec][ba]->Fill(vector, weight); + } + } // if (ba == eAfter ... ) { + + // QA: + if (qa.fFillQAParticleHistograms2D) { + !qa.fQAParticleHistograms2D[ePt_vs_dcaXY][eRec][ba] ? true : qa.fQAParticleHistograms2D[ePt_vs_dcaXY][eRec][ba]->Fill(track.pt(), track.dcaXY(), weight); + } + if ((qa.fFillQAParticleEventHistograms2D || qa.fFillQACorrelationsVsHistograms2D || qa.fFillQACorrelationsVsInteractionRateVsProfiles2D) && qa.fQAParticleEventProEbyE[eRec][ba]) { + // Here I only fill the helper profile to get average of requested particle variable for current event: + qa.fQAParticleEventProEbyE[eRec][ba]->Fill(static_cast(eitsNClsEbyE) - 0.5, track.itsNCls(), weight); + + if (track.eta() < 0.) { + qa.fQAParticleEventProEbyE[eRec][ba]->Fill(static_cast(eitsNClsNegEtaEbyE) - 0.5, track.itsNCls(), weight); + } else if (track.eta() > 0.) { // TBI 20241214 for the time being, I do not care about the corner case eta = 0. + qa.fQAParticleEventProEbyE[eRec][ba]->Fill(static_cast(eitsNClsPosEtaEbyE) - 0.5, track.itsNCls(), weight); + } + + if (-0.8 < track.eta() && track.eta() < -0.4) { + qa.fQAParticleEventProEbyE[eRec][ba]->Fill(static_cast(eEta0804EbyE) - 0.5, track.eta(), weight); + } else if (-0.4 < track.eta() && track.eta() < 0.0) { + qa.fQAParticleEventProEbyE[eRec][ba]->Fill(static_cast(eEta0400EbyE) - 0.5, track.eta(), weight); + } else if (0.0 < track.eta() && track.eta() < 0.4) { + qa.fQAParticleEventProEbyE[eRec][ba]->Fill(static_cast(eEta0004EbyE) - 0.5, track.eta(), weight); + } else if (0.4 < track.eta() && track.eta() < 0.8) { + qa.fQAParticleEventProEbyE[eRec][ba]->Fill(static_cast(eEta0408EbyE) - 0.5, track.eta(), weight); + } + + if (0.0 < track.pt() && track.pt() < 0.5) { + qa.fQAParticleEventProEbyE[eRec][ba]->Fill(static_cast(ePt0005EbyE) - 0.5, track.pt(), weight); + } else if (0.5 < track.pt() && track.pt() < 1.0) { + qa.fQAParticleEventProEbyE[eRec][ba]->Fill(static_cast(ePt0510EbyE) - 0.5, track.pt(), weight); + } else if (1.0 < track.pt() && track.pt() < 5.0) { + qa.fQAParticleEventProEbyE[eRec][ba]->Fill(static_cast(ePt1050EbyE) - 0.5, track.pt(), weight); + } + + // eMeanPhi: + qa.fQAParticleEventProEbyE[eRec][ba]->Fill(static_cast(eMeanPhi) - 0.5, track.phi(), weight); + + // eMeanPt: + qa.fQAParticleEventProEbyE[eRec][ba]->Fill(static_cast(eMeanPt) - 0.5, track.pt(), weight); + + // eMeanEta: + qa.fQAParticleEventProEbyE[eRec][ba]->Fill(static_cast(eMeanEta) - 0.5, track.eta(), weight); + + // eMeanCharge: + qa.fQAParticleEventProEbyE[eRec][ba]->Fill(static_cast(eMeanCharge) - 0.5, track.sign(), weight); + + // eMeantpcNClsFindable: + qa.fQAParticleEventProEbyE[eRec][ba]->Fill(static_cast(eMeantpcNClsFindable) - 0.5, track.tpcNClsFindable(), weight); + + // eMeantpcNClsShared: + qa.fQAParticleEventProEbyE[eRec][ba]->Fill(static_cast(eMeantpcNClsShared) - 0.5, track.tpcNClsShared(), weight); + + // eMeanitsChi2NCl: + qa.fQAParticleEventProEbyE[eRec][ba]->Fill(static_cast(eMeanitsChi2NCl) - 0.5, track.itsChi2NCl(), weight); + + // eMeantpcNClsFound: + qa.fQAParticleEventProEbyE[eRec][ba]->Fill(static_cast(eMeantpcNClsFound) - 0.5, track.tpcNClsFound(), weight); + + // eMeantpcNClsCrossedRow: + qa.fQAParticleEventProEbyE[eRec][ba]->Fill(static_cast(eMeantpcNClsCrossedRows) - 0.5, track.tpcNClsCrossedRows(), weight); + + // eMeanitsNCls: + qa.fQAParticleEventProEbyE[eRec][ba]->Fill(static_cast(eMeanitsNCls) - 0.5, track.itsNCls(), weight); + + // eMeanitsNClsInnerBarrel: + qa.fQAParticleEventProEbyE[eRec][ba]->Fill(static_cast(eMeanitsNClsInnerBarrel) - 0.5, track.itsNClsInnerBarrel(), weight); + + // eMeantpcCrossedRowsOverFindableCl: + qa.fQAParticleEventProEbyE[eRec][ba]->Fill(static_cast(eMeantpcCrossedRowsOverFindableCls) - 0.5, track.tpcCrossedRowsOverFindableCls(), weight); + + // eMeantpcFoundOverFindableCl: + qa.fQAParticleEventProEbyE[eRec][ba]->Fill(static_cast(eMeantpcFoundOverFindableCls) - 0.5, track.tpcFoundOverFindableCls(), weight); + + // eMeantpcFractionSharedCls: + qa.fQAParticleEventProEbyE[eRec][ba]->Fill(static_cast(eMeantpcFractionSharedCls) - 0.5, track.tpcFractionSharedCls(), weight); + + // eMeantpcChi2NCl: + qa.fQAParticleEventProEbyE[eRec][ba]->Fill(static_cast(eMeantpcChi2NCl) - 0.5, track.tpcChi2NCl(), weight); + + // eMeandcaXY: + qa.fQAParticleEventProEbyE[eRec][ba]->Fill(static_cast(eMeandcaXY) - 0.5, track.dcaXY(), weight); + + // eMeandcaZ: + qa.fQAParticleEventProEbyE[eRec][ba]->Fill(static_cast(eMeandcaZ) - 0.5, track.dcaZ(), weight); + + // ... + + } // if ... + + // ... and corresponding MC truth simulated (common to Run 3, Run 2 and Run 1) + // See https://github.com/AliceO2Group/O2Physics/blob/master/Tutorials/src/mcHistograms.cxx + // See https://aliceo2group.github.io/analysis-framework/docs/datamodel/ao2dTables.html#montecarlo + + if constexpr (rs == eRecAndSim || rs == eRecAndSim_Run2 || rs == eRecAndSim_Run1) { + if (!track.has_mcParticle()) { + LOGF(warning, " No MC particle for this track, skip..."); + return; + } + auto mcParticle = track.mcParticle(); // corresponding MC truth simulated particle + + // 1D: + if (ph.fFillParticleHistograms) { + !ph.fParticleHistograms[ePhi][eSim][ba] ? true : ph.fParticleHistograms[ePhi][eSim][ba]->Fill(mcParticle.phi(), weight); + !ph.fParticleHistograms[ePt][eSim][ba] ? true : ph.fParticleHistograms[ePt][eSim][ba]->Fill(mcParticle.pt(), weight); + !ph.fParticleHistograms[eEta][eSim][ba] ? true : ph.fParticleHistograms[eEta][eSim][ba]->Fill(mcParticle.eta(), weight); + + // special treatment for charge, because there is no getter mcParticle.sign() + double charge = -44.; // yes, never initialize charge to 0. + if (tc.fDatabasePDG && tc.fDatabasePDG->GetParticle(mcParticle.pdgCode())) { + // Yes, I have to check the 2nd condition, because e.g. for PDG code 1000010020 (deuteron), GetParticle(...) returns NULL + charge = tc.fDatabasePDG->GetParticle(mcParticle.pdgCode())->Charge() / 3.; // yes, divided by 3. Fundamental unit of charge is associated with quarks + } + !ph.fParticleHistograms[eCharge][eSim][ba] ? true : ph.fParticleHistograms[eCharge][eSim][ba]->Fill(charge); + !ph.fParticleHistograms[ePDG][eSim][ba] ? true : ph.fParticleHistograms[ePDG][eSim][ba]->Fill(mcParticle.pdgCode(), weight); + } + + // 2D: + if (ph.fFillParticleHistograms2D) { + !ph.fParticleHistograms2D[ePhiPt][eSim][ba] ? true : ph.fParticleHistograms2D[ePhiPt][eSim][ba]->Fill(mcParticle.phi(), mcParticle.pt(), weight); + !ph.fParticleHistograms2D[ePhiEta][eSim][ba] ? true : ph.fParticleHistograms2D[ePhiEta][eSim][ba]->Fill(mcParticle.phi(), mcParticle.eta(), weight); + } // if(ph.fFillParticleHistograms2D) { + + // nD (THnSparse): + if (ba == eAfter || (eBefore == ba && ph.fFillParticleSparseHistogramsBeforeCuts)) { + // **) eDWPhi : here the fundamental 0-th axis never to be projected out is "phi" + if (ph.fBookParticleSparseHistograms[eDWPhi]) { + // Remark: It is mandatory that ordering in initialization here resembles the ordering in enum eDiffPhiWeights + + // special treatment for charge, because there is no getter mcParticle.sign() + double charge = -44.; // yes, never initialize charge to 0. + if (tc.fDatabasePDG && tc.fDatabasePDG->GetParticle(mcParticle.pdgCode())) { + // Yes, I have to check the 2nd condition, because e.g. for PDG code 1000010020 (deuteron), GetParticle(...) returns NULL + charge = tc.fDatabasePDG->GetParticle(mcParticle.pdgCode())->Charge() / 3.; // yes, divided by 3. Fundamental unit of charge is associated with quarks + } + double vector[eDiffPhiWeights_N] = {mcParticle.phi(), mcParticle.pt(), mcParticle.eta(), charge, ebye.fCentralitySim, 0.}; + // TBI 20250611 I do nothing for vertex z, I could trivially extend ebye.fVz also for "sim" dimension => I set it to 0 temporarily here, until that's done. + ph.fParticleSparseHistograms[eDWPhi][eSim][ba]->Fill(vector, weight); + } + // **) eDWPt : here the fundamental 0-th axis never to be projected out is "pt" + if (ph.fBookParticleSparseHistograms[eDWPt]) { + // Remark: It is mandatory that ordering in initialization here resembles the ordering in enum eDiffPtWeights + + // special treatment for charge, because there is no getter mcParticle.sign() + double charge = -44.; // yes, never initialize charge to 0. + if (tc.fDatabasePDG && tc.fDatabasePDG->GetParticle(mcParticle.pdgCode())) { + // Yes, I have to check the 2nd condition, because e.g. for PDG code 1000010020 (deuteron), GetParticle(...) returns NULL + charge = tc.fDatabasePDG->GetParticle(mcParticle.pdgCode())->Charge() / 3.; // yes, divided by 3. Fundamental unit of charge is associated with quarks + } + double vector[eDiffPtWeights_N] = {mcParticle.pt(), mcParticle.eta(), charge, ebye.fCentralitySim}; + ph.fParticleSparseHistograms[eDWPt][eSim][ba]->Fill(vector, weight); + } + // **) eDWEta : here the fundamental 0-th axis never to be projected out is "eta" + if (ph.fBookParticleSparseHistograms[eDWEta]) { + // Remark: It is mandatory that ordering in initialization here resembles the ordering in enum eDiffEtaWeights + + // special treatment for charge, because there is no getter mcParticle.sign() + double charge = -44.; // yes, never initialize charge to 0. + if (tc.fDatabasePDG && tc.fDatabasePDG->GetParticle(mcParticle.pdgCode())) { + // Yes, I have to check the 2nd condition, because e.g. for PDG code 1000010020 (deuteron), GetParticle(...) returns NULL + charge = tc.fDatabasePDG->GetParticle(mcParticle.pdgCode())->Charge() / 3.; // yes, divided by 3. Fundamental unit of charge is associated with quarks + } + double vector[eDiffEtaWeights_N] = {mcParticle.eta(), mcParticle.pt(), charge, ebye.fCentralitySim}; + ph.fParticleSparseHistograms[eDWEta][eSim][ba]->Fill(vector, weight); + } + } // if (ba == eAfter ... ) { + + } // if constexpr (rs == eRecAndSim || rs == eRecAndSim_Run2 || rs == eRecAndSim_Run1) { + } // if constexpr (rs == eRec || rs == eRecAndSim || rs == eRec_Run2 || rs == eRecAndSim_Run2 || rs == eRec_Run1 || rs == eRecAndSim_Run1) { + + // ----------------------------------------------------------------------------- + + // b) Fill only simulated (common to Run 3, Run 2 and Run 1): + // Remark #1: This branch is relevant when processing ONLY simulated data at generator level. + // Remark #2: In this branch, 'track' is always TracksSim = aod::McParticles, see https://aliceo2group.github.io/analysis-framework/docs/datamodel/ao2dTables.html#montecarlo . + // Remark #3: This code is completely irrelevant for InternalValidation(), because few selected histos I fill directly there. + if constexpr (rs == eSim || rs == eSim_Run2 || rs == eSim_Run1) { + // 1D: + if (ph.fFillParticleHistograms) { + !ph.fParticleHistograms[ePhi][eSim][ba] ? true : ph.fParticleHistograms[ePhi][eSim][ba]->Fill(track.phi(), weight); + !ph.fParticleHistograms[ePt][eSim][ba] ? true : ph.fParticleHistograms[ePt][eSim][ba]->Fill(track.pt(), weight); + !ph.fParticleHistograms[eEta][eSim][ba] ? true : ph.fParticleHistograms[eEta][eSim][ba]->Fill(track.eta(), weight); + + // special treatment for charge, because there is no getter mcParticle.sign() + double charge = -44.; // yes, never initialize charge to 0. + if (tc.fDatabasePDG && tc.fDatabasePDG->GetParticle(track.pdgCode())) { + // Yes, I have to check the 2nd condition, because e.g. for PDG code 1000010020 (deuteron), GetParticle(...) returns NULL + charge = tc.fDatabasePDG->GetParticle(track.pdgCode())->Charge() / 3.; // yes, divided by 3. Fundamental unit of charge is associated with quarks + } + !ph.fParticleHistograms[eCharge][eSim][ba] ? true : ph.fParticleHistograms[eCharge][eSim][ba]->Fill(charge); + !ph.fParticleHistograms[ePDG][eSim][ba] ? true : ph.fParticleHistograms[ePDG][eSim][ba]->Fill(track.pdgCode(), weight); + } // if(ph.fFillParticleHistograms) { + + // 2D: + if (ph.fFillParticleHistograms2D) { + !ph.fParticleHistograms2D[ePhiPt][eSim][ba] ? true : ph.fParticleHistograms2D[ePhiPt][eSim][ba]->Fill(track.phi(), track.pt(), weight); + !ph.fParticleHistograms2D[ePhiEta][eSim][ba] ? true : ph.fParticleHistograms2D[ePhiEta][eSim][ba]->Fill(track.phi(), track.eta(), weight); + } // if(ph.fFillParticleHistograms2D) { + } // if constexpr (rs == eSim || rs == eSim_Run2 || rs == eSim_Run1) { + + // ----------------------------------------------------------------------------- + + // c) Fill reconstructed ... (Run 3 specific): + if constexpr (rs == eRec || rs == eRecAndSim || rs == eQA) { + // TBI 20240511 check If I can use them for Run 2 and Run 1, but extending TracksRecSim_Run2 to Tracks_extra, etc. + // Remark: Remember to use only eRec and eSim as array indices in histos, also for rs == eRecAndSim, etc. TBI 20240504 shall I introduce generic enum egRec and egSim for this sake? + + // ... + + // ... and corresponding MC truth simulated (Run 3 specific): + // See https://github.com/AliceO2Group/O2Physics/blob/master/Tutorials/src/mcHistograms.cxx ): + if constexpr (rs == eRecAndSim) { + if (!track.has_mcParticle()) { + LOGF(warning, " No MC particle for this track, skip..."); + return; + } + + // auto mcParticle = track.mcParticle(); // corresponding MC truth simulated particle + + // ... + + } // if constexpr (rs == eRecAndSim) { + } // if constexpr (rs == eRec || rs == eRecAndSim) { + + // ----------------------------------------------------------------------------- + + // d) Fill only simulated (Run 3 specific): + // Remark #1: I fill here only the histograms which are not already filled in group b) above, and which make sense only for Run 3 data. + // Remark #2: In this branch 'track' is always TracksSim = aod::McParticles, see https://aliceo2group.github.io/analysis-framework/docs/datamodel/ao2dTables.html#montecarlo + // See how I handled the case b) above. + if constexpr (rs == eSim) { + + // ... + + } // if constexpr (rs == eSim) { + + // ----------------------------------------------------------------------------- + + // e) Fill reconstructed ... (Run 1 and 2 specific): + // Remark: I fill here only the histograms which are not already filled in group a) above, and which make sense only for Run 1 and 2 data. + if constexpr (rs == eRec_Run2 || rs == eRecAndSim_Run2 || rs == eRec_Run1 || rs == eRecAndSim_Run1) { + + // ... + + // ... and corresponding MC truth simulated (Run 1 and 2 specific): + // See https://github.com/AliceO2Group/O2Physics/blob/master/Tutorials/src/mcHistograms.cxx ): + if constexpr (rs == eRecAndSim_Run2 || rs == eRecAndSim_Run1) { + if (!track.has_mcParticle()) { + LOGF(warning, " No MC particle for this track, skip..."); + return; + } + + // auto mcParticle = track.mcParticle(); // corresponding MC truth simulated particle + + // ... + + } // if constexpr (rs == eRecAndSim_Run2 || rs == eRecAndSim_Run1) { + } // if constexpr (rs == eRec_Run2 || rs == eRecAndSim_Run2 || rs == eRec_Run1 || rs == eRecAndSim_Run1) { + + // ----------------------------------------------------------------------------- + + // f) Fill only simulated (Run 1 and 2 specific): + // Remark #1: I fill here only histograms which are not already filled in group b) above, and which make sense only for Run 1 and 2 data. + // Remark #2: In this branch In this branch 'track' is always TracksSim = aod::McParticles, see https://aliceo2group.github.io/analysis-framework/docs/datamodel/ao2dTables.html#montecarlo + // See how I handled the case b) above. + if constexpr (rs == eSim_Run2 || rs == eSim_Run1) { + + // ... + + } // if constexpr (rs == eSim_Run2 || rs == eSim_Run1) { + + // ----------------------------------------------------------------------------- + + // *) Test case: + if constexpr (rs == eTest) { + // This branch corresponds to process with minimal subscription - I implement just a few example cuts, just for testing purposes. + // Only eRec is support in Test for the time being. + // 1D: + if (ph.fFillParticleHistograms) { + !ph.fParticleHistograms[ePhi][eRec][ba] ? true : ph.fParticleHistograms[ePhi][eRec][ba]->Fill(track.phi(), weight); + !ph.fParticleHistograms[ePt][eRec][ba] ? true : ph.fParticleHistograms[ePt][eRec][ba]->Fill(track.pt(), weight); + !ph.fParticleHistograms[eEta][eRec][ba] ? true : ph.fParticleHistograms[eEta][eRec][ba]->Fill(track.eta(), weight); + } + // 2D: + if (ph.fFillParticleHistograms2D) { + !ph.fParticleHistograms2D[ePhiPt][eRec][ba] ? true : ph.fParticleHistograms2D[ePhiPt][eRec][ba]->Fill(track.phi(), track.pt(), weight); + !ph.fParticleHistograms2D[ePhiEta][eRec][ba] ? true : ph.fParticleHistograms2D[ePhiEta][eRec][ba]->Fill(track.phi(), track.eta(), weight); + } + } // if constexpr (rs == eTest) { + + } // template void FillParticleHistograms(...) + + //============================================================ + + void CalculateCorrelations() + { + // Calculate analytically multiparticle correlations from Q-vectors. + // In this method, only isotropic correlations for which all harmonics are the same are evaluated. + + // a) Flush 'n' fill the generic Q-vectors; + // b) Calculate correlations; + // c) Flush the generic Q-vectors. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // a) Flush 'n' fill the generic Q-vectors: + ResetQ(); + for (int h = 0; h < gMaxHarmonic * gMaxCorrelator + 1; h++) { + for (int wp = 0; wp < gMaxCorrelator + 1; wp++) // weight power + { + qv.fQ[h][wp] = qv.fQvector[h][wp]; + } + } + + // b) Calculate correlations: + for (int h = 1; h <= gMaxHarmonic; h++) // harmonic + { + // 2p: + if (ebye.fSelectedTracks < 2) { + return; + } + if (tc.fVerbose) { + LOGF(info, " calculating 2-particle correlations ...."); + } + TComplex two = Two(h, -h); + double twoC = two.Re(); // cos + // double twoS = two.Im(); // sin + double wTwo = Two(0, 0).Re(); // Weight is 'number of combinations' by default TBI + // 20220809 add support for other weights + if (wTwo > 0.0) { + twoC /= wTwo; + } else { + LOGF(fatal, "In function \033[1;31m%s at line %d, wTwo = %f <=0. ebye.fSelectedTracks = %d\033[0m", __FUNCTION__, __LINE__, wTwo, ebye.fSelectedTracks); + } + + if (nl.fCalculateCustomNestedLoops) { + // e-b-e sanity check: + TArrayI* harmonics = new TArrayI(2); + harmonics->SetAt(h, 0); + harmonics->SetAt(-h, 1); + double nestedLoopValue = this->CalculateCustomNestedLoops(harmonics); + if (std::abs(nestedLoopValue) > 0. && std::abs(twoC - nestedLoopValue) > tc.fFloatingPointPrecision) { + LOGF(fatal, "\033[1;31m%s at line %d : nestedLoopValue = %f is not the same as twoC = %f\033[0m", __FUNCTION__, __LINE__, nestedLoopValue, twoC); + } else { + LOGF(info, "\033[1;32m ebye check (integrated) with CustomNestedLoops is OK for isotropic 2-p, harmonic %d\033[0m", h); + } + delete harmonics; + harmonics = NULL; + } // if(nl.fCalculateCustomNestedLoops) + + // for on-the-fly and internal validation, rescale results with theoretical value: + if (iv.fUseInternalValidation && iv.fRescaleWithTheoreticalInput && iv.fInternalValidationVnPsin[eVn] && std::abs(iv.fInternalValidationVnPsin[eVn]->GetAt(h - 1)) > 0.) { + twoC /= std::pow(iv.fInternalValidationVnPsin[eVn]->GetAt(h - 1), 2.); + } + + // integrated: + if (mupa.fCorrelationsPro[0][h - 1][AFO_INTEGRATED]) { + mupa.fCorrelationsPro[0][h - 1][AFO_INTEGRATED]->Fill(0.5, twoC, wTwo); + } + // vs. multiplicity: + if (mupa.fCorrelationsPro[0][h - 1][AFO_MULTIPLICITY]) { + mupa.fCorrelationsPro[0][h - 1][AFO_MULTIPLICITY]->Fill(ebye.fSelectedTracks + 0.5, twoC, wTwo); + } + // vs. centrality: + if (mupa.fCorrelationsPro[0][h - 1][AFO_CENTRALITY]) { + mupa.fCorrelationsPro[0][h - 1][AFO_CENTRALITY]->Fill(ebye.fCentrality, twoC, wTwo); + } + // vs. occupancy: + if (mupa.fCorrelationsPro[0][h - 1][AFO_OCCUPANCY]) { + mupa.fCorrelationsPro[0][h - 1][AFO_OCCUPANCY]->Fill(ebye.fOccupancy, twoC, wTwo); + } + // vs. interaction rate: + if (mupa.fCorrelationsPro[0][h - 1][AFO_INTERACTIONRATE]) { + mupa.fCorrelationsPro[0][h - 1][AFO_INTERACTIONRATE]->Fill(ebye.fInteractionRate, twoC, wTwo); + } + // vs. current run duration: + if (mupa.fCorrelationsPro[0][h - 1][AFO_CURRENTRUNDURATION]) { + mupa.fCorrelationsPro[0][h - 1][AFO_CURRENTRUNDURATION]->Fill(ebye.fCurrentRunDuration, twoC, wTwo); + } + // vs. vertex z position: + if (mupa.fCorrelationsPro[0][h - 1][AFO_VZ]) { + mupa.fCorrelationsPro[0][h - 1][AFO_VZ]->Fill(ebye.fVz, twoC, wTwo); + } + + // 4p: + if (ebye.fSelectedTracks < 4) { + continue; + } // yes, continue, because I can still calculate 2-p in other harmonics! + if (tc.fVerbose) { + LOGF(info, " calculating 4-particle correlations ...."); + } + TComplex four = Four(h, h, -h, -h); + double fourC = four.Re(); // cos + // double fourS = four.Im(); // sin + double wFour = Four(0, 0, 0, 0).Re(); // Weight is 'number of combinations' by default TBI_20210515 add support for other weights + if (wFour > 0.0) { + fourC /= wFour; + } else { + LOGF(fatal, "In function \033[1;31m%s at line %d, wFour = %f <=0. ebye.fSelectedTracks = %d\033[0m", __FUNCTION__, __LINE__, wFour, ebye.fSelectedTracks); + // TBI 20240110 shall I 'continue' here, instead of bailing out? + } + + if (nl.fCalculateCustomNestedLoops) { + // e-b-e sanity check: + TArrayI* harmonics = new TArrayI(4); + harmonics->SetAt(h, 0); + harmonics->SetAt(h, 1); + harmonics->SetAt(-h, 2); + harmonics->SetAt(-h, 3); + double nestedLoopValue = this->CalculateCustomNestedLoops(harmonics); + if (std::abs(nestedLoopValue) > 0. && std::abs(fourC - nestedLoopValue) > tc.fFloatingPointPrecision) { + LOGF(fatal, "\033[1;31m%s at line %d : nestedLoopValue = %f is not the same as fourC = %f\033[0m", __FUNCTION__, __LINE__, nestedLoopValue, fourC); + } else { + LOGF(info, "\033[1;32m ebye check (integrated) with CustomNestedLoops is OK for isotropic 4-p, harmonic %d\033[0m", h); + } + delete harmonics; + harmonics = NULL; + } // if(nl.fCalculateCustomNestedLoops) + + // for on-the-fly and internal validation, rescale results with theoretical value: + if (iv.fUseInternalValidation && iv.fRescaleWithTheoreticalInput && iv.fInternalValidationVnPsin[eVn] && std::abs(iv.fInternalValidationVnPsin[eVn]->GetAt(h - 1)) > 0.) { + fourC /= std::pow(iv.fInternalValidationVnPsin[eVn]->GetAt(h - 1), 4.); + } + + // integrated: + if (mupa.fCorrelationsPro[1][h - 1][AFO_INTEGRATED]) { + mupa.fCorrelationsPro[1][h - 1][AFO_INTEGRATED]->Fill(0.5, fourC, wFour); + } + // vs. multiplicity: + if (mupa.fCorrelationsPro[1][h - 1][AFO_MULTIPLICITY]) { + mupa.fCorrelationsPro[1][h - 1][AFO_MULTIPLICITY]->Fill(ebye.fSelectedTracks + 0.5, fourC, wFour); + } + // vs. centrality: + if (mupa.fCorrelationsPro[1][h - 1][AFO_CENTRALITY]) { + mupa.fCorrelationsPro[1][h - 1][AFO_CENTRALITY]->Fill(ebye.fCentrality, fourC, wFour); + } + // vs. occupancy: + if (mupa.fCorrelationsPro[1][h - 1][AFO_OCCUPANCY]) { + mupa.fCorrelationsPro[1][h - 1][AFO_OCCUPANCY]->Fill(ebye.fOccupancy, fourC, wFour); + } + // vs. interaction rate: + if (mupa.fCorrelationsPro[1][h - 1][AFO_INTERACTIONRATE]) { + mupa.fCorrelationsPro[1][h - 1][AFO_INTERACTIONRATE]->Fill(ebye.fInteractionRate, fourC, wFour); + } + // vs. current run duration: + if (mupa.fCorrelationsPro[1][h - 1][AFO_CURRENTRUNDURATION]) { + mupa.fCorrelationsPro[1][h - 1][AFO_CURRENTRUNDURATION]->Fill(ebye.fCurrentRunDuration, fourC, wFour); + } + // vs. vertex z position: + if (mupa.fCorrelationsPro[1][h - 1][AFO_VZ]) { + mupa.fCorrelationsPro[1][h - 1][AFO_VZ]->Fill(ebye.fVz, fourC, wFour); + } + + // 6p: + if (ebye.fSelectedTracks < 6) { + continue; + } // yes, continue, because I can still calculate 2-p and 4-p in other harmonics! + if (tc.fVerbose) { + LOGF(info, " calculating 6-particle correlations ...."); + } + TComplex six = Six(h, h, h, -h, -h, -h); + double sixC = six.Re(); // cos + // double sixS = six.Im(); // sin + double wSix = Six(0, 0, 0, 0, 0, 0).Re(); // Weight is 'number of combinations' by default TBI_20210515 add support for other weights + if (wSix > 0.0) { + sixC /= wSix; + } else { + LOGF(fatal, "In function \033[1;31m%s at line %d, wSix = %f <=0. ebye.fSelectedTracks = %d\033[0m", __FUNCTION__, __LINE__, wSix, ebye.fSelectedTracks); + // TBI 20240110 shall I 'continue' here, instead of bailing out? + } + + if (nl.fCalculateCustomNestedLoops) { + // e-b-e sanity check: + TArrayI* harmonics = new TArrayI(6); + harmonics->SetAt(h, 0); + harmonics->SetAt(h, 1); + harmonics->SetAt(h, 2); + harmonics->SetAt(-h, 3); + harmonics->SetAt(-h, 4); + harmonics->SetAt(-h, 5); + double nestedLoopValue = this->CalculateCustomNestedLoops(harmonics); + if (std::abs(nestedLoopValue) > 0. && std::abs(sixC - nestedLoopValue) > tc.fFloatingPointPrecision) { + LOGF(fatal, "\033[1;31m%s at line %d : nestedLoopValue = %f is not the same as sixC = %f\033[0m", __FUNCTION__, __LINE__, nestedLoopValue, sixC); + } else { + LOGF(info, "\033[1;32m ebye check (integrated) with CustomNestedLoops is OK for isotropic 6-p, harmonic %d\033[0m", h); + } + delete harmonics; + harmonics = NULL; + } // if(nl.fCalculateCustomNestedLoops) + + // for on-the-fly and internal validation, rescale results with theoretical value: + if (iv.fUseInternalValidation && iv.fRescaleWithTheoreticalInput && iv.fInternalValidationVnPsin[eVn] && std::abs(iv.fInternalValidationVnPsin[eVn]->GetAt(h - 1)) > 0.) { + sixC /= std::pow(iv.fInternalValidationVnPsin[eVn]->GetAt(h - 1), 6.); + } + + // integrated: + if (mupa.fCorrelationsPro[2][h - 1][AFO_INTEGRATED]) { + mupa.fCorrelationsPro[2][h - 1][AFO_INTEGRATED]->Fill(0.5, sixC, wSix); + } + // vs. multiplicity: + if (mupa.fCorrelationsPro[2][h - 1][AFO_MULTIPLICITY]) { + mupa.fCorrelationsPro[2][h - 1][AFO_MULTIPLICITY]->Fill(ebye.fSelectedTracks + 0.5, sixC, wSix); + } + // vs. centrality: + if (mupa.fCorrelationsPro[2][h - 1][AFO_CENTRALITY]) { + mupa.fCorrelationsPro[2][h - 1][AFO_CENTRALITY]->Fill(ebye.fCentrality, sixC, wSix); + } + // vs. occupancy: + if (mupa.fCorrelationsPro[2][h - 1][AFO_OCCUPANCY]) { + mupa.fCorrelationsPro[2][h - 1][AFO_OCCUPANCY]->Fill(ebye.fOccupancy, sixC, wSix); + } + // vs. interaction rate: + if (mupa.fCorrelationsPro[2][h - 1][AFO_INTERACTIONRATE]) { + mupa.fCorrelationsPro[2][h - 1][AFO_INTERACTIONRATE]->Fill(ebye.fInteractionRate, sixC, wSix); + } + // vs. current run duration: + if (mupa.fCorrelationsPro[2][h - 1][AFO_CURRENTRUNDURATION]) { + mupa.fCorrelationsPro[2][h - 1][AFO_CURRENTRUNDURATION]->Fill(ebye.fCurrentRunDuration, sixC, wSix); + } + // vs. vertex z position: + if (mupa.fCorrelationsPro[2][h - 1][AFO_VZ]) { + mupa.fCorrelationsPro[2][h - 1][AFO_VZ]->Fill(ebye.fVz, sixC, wSix); + } + + // 8p: + if (ebye.fSelectedTracks < 8) { + continue; + } // yes, continue, because I can still calculate 2-p, 4-p and 6-p in other harmonics! + if (tc.fVerbose) { + LOGF(info, " calculating 8-particle correlations ...."); + } + TComplex eight = Eight(h, h, h, h, -h, -h, -h, -h); + double eightC = eight.Re(); // cos + // double eightS = eight.Im(); // sin + double wEight = Eight(0, 0, 0, 0, 0, 0, 0, 0).Re(); // Weight is 'number of combinations' by default TBI_20210515 add support for other weights + if (wEight > 0.0) { + eightC /= wEight; + } else { + LOGF(fatal, "In function \033[1;31m%s at line %d, wEight = %f <=0. ebye.fSelectedTracks = %d\033[0m", __FUNCTION__, __LINE__, wEight, ebye.fSelectedTracks); + // TBI 20240110 shall I 'continue' here, instead of bailing out? + } + + if (nl.fCalculateCustomNestedLoops) { + // e-b-e sanity check: + TArrayI* harmonics = new TArrayI(8); + harmonics->SetAt(h, 0); + harmonics->SetAt(h, 1); + harmonics->SetAt(h, 2); + harmonics->SetAt(h, 3); + harmonics->SetAt(-h, 4); + harmonics->SetAt(-h, 5); + harmonics->SetAt(-h, 6); + harmonics->SetAt(-h, 7); + double nestedLoopValue = this->CalculateCustomNestedLoops(harmonics); + if (std::abs(nestedLoopValue) > 0. && std::abs(eightC - nestedLoopValue) > tc.fFloatingPointPrecision) { + LOGF(fatal, "\033[1;31m%s at line %d : nestedLoopValue = %f is not the same as eightC = %f\033[0m", __FUNCTION__, __LINE__, nestedLoopValue, eightC); + } else { + LOGF(info, "\033[1;32m ebye check (integrated) with CustomNestedLoops is OK for isotropic 8-p, harmonic %d\033[0m", h); + } + delete harmonics; + harmonics = NULL; + } // if(nl.fCalculateCustomNestedLoops) + + // for on-the-fly and internal validation, rescale results with theoretical value: + if (iv.fUseInternalValidation && iv.fRescaleWithTheoreticalInput && iv.fInternalValidationVnPsin[eVn] && std::abs(iv.fInternalValidationVnPsin[eVn]->GetAt(h - 1)) > 0.) { + eightC /= std::pow(iv.fInternalValidationVnPsin[eVn]->GetAt(h - 1), 8.); + } + + // integrated: + if (mupa.fCorrelationsPro[3][h - 1][AFO_INTEGRATED]) { + mupa.fCorrelationsPro[3][h - 1][AFO_INTEGRATED]->Fill(0.5, eightC, wEight); + } + // vs. multiplicity: + if (mupa.fCorrelationsPro[3][h - 1][AFO_MULTIPLICITY]) { + mupa.fCorrelationsPro[3][h - 1][AFO_MULTIPLICITY]->Fill(ebye.fSelectedTracks + 0.5, eightC, wEight); + } + // vs. centrality: + if (mupa.fCorrelationsPro[3][h - 1][AFO_CENTRALITY]) { + mupa.fCorrelationsPro[3][h - 1][AFO_CENTRALITY]->Fill(ebye.fCentrality, eightC, wEight); + } + // vs. occupancy: + if (mupa.fCorrelationsPro[3][h - 1][AFO_OCCUPANCY]) { + mupa.fCorrelationsPro[3][h - 1][AFO_OCCUPANCY]->Fill(ebye.fOccupancy, eightC, wEight); + } + // vs. interaction rate: + if (mupa.fCorrelationsPro[3][h - 1][AFO_INTERACTIONRATE]) { + mupa.fCorrelationsPro[3][h - 1][AFO_INTERACTIONRATE]->Fill(ebye.fInteractionRate, eightC, wEight); + } + // vs. current run duration: + if (mupa.fCorrelationsPro[3][h - 1][AFO_CURRENTRUNDURATION]) { + mupa.fCorrelationsPro[3][h - 1][AFO_CURRENTRUNDURATION]->Fill(ebye.fCurrentRunDuration, eightC, wEight); + } + // vs. vertex z position: + if (mupa.fCorrelationsPro[3][h - 1][AFO_VZ]) { + mupa.fCorrelationsPro[3][h - 1][AFO_VZ]->Fill(ebye.fVz, eightC, wEight); + } + } // for(int h=1;h<=gMaxHarmonic;h++) // harmonic + + // c) Flush the generic Q-vectors: + ResetQ(); + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // void CalculateCorrelations() + + //============================================================ + + void CalculateKineCorrelations(eAsFunctionOf AFO_variable) + { + // Calculate analytically differential multiparticle correlations from Q-vectors. + + // TBI 20250702 I need declare this function obsolete, and move to CalculateKineCorrelationsNdim, see what I did in CalculateKineTest0Ndim + // After that, finalize this function and add the standard support for kine calculus. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // *) ... + eqvectorKine qvKine = eqvectorKine_N; // which eqvectorKine enum + // int nBins = -1; // TBI 20241111 temporarily commented out just to suppress warnings + + switch (AFO_variable) { + case AFO_PT: { + qvKine = PTq; + // nBins = res.fResultsPro[AFO_PT]->GetNbinsX(); // TBI 20241111 temporarily commented out just to suppress warnings + break; + } + case AFO_ETA: { + qvKine = ETAq; + // nBins = res.fResultsPro[AFO_ETA]->GetNbinsX(); // TBI 20241111 temporarily commented out just to suppress warnings + break; + } + case AFO_CHARGE: { + qvKine = CHARGEq; + // nBins = res.fResultsPro[AFO_ETA]->GetNbinsX(); // TBI 20241111 temporarily commented out just to suppress warnings + break; + } + default: { + LOGF(fatal, "\033[1;31m%s at line %d : This AFO_variable = %d is not supported yet. \033[0m", __FUNCTION__, __LINE__, static_cast(AFO_variable)); + break; + } + } // switch(AFO_variable) + + // *) Insanity checks on above settings: + if (qvKine == eqvectorKine_N) { + LOGF(fatal, "\033[1;31m%s at line %d : qvKine == eqvectorKine_N => add some more entries to the case statement \033[0m", __FUNCTION__, __LINE__); + } + + // ... + + LOGF(warning, "\033[1;33m%s at line %d : Not implemented yet, this is just a placeholder for future implementation.\033[0m", __FUNCTION__, __LINE__); + + // ... + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // void CalculateKineCorrelations(eAsFunctionOf AFO_variable) + + //============================================================ + + void CalculateTest0() + { + // Calculate Test0. + + // a) Flush 'n' fill the generic Q-vectors; + // b) Calculate correlations; + // c) Flush the generic Q-vectors. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // a) Flush 'n' fill the generic Q-vectors: + ResetQ(); + for (int h = 0; h < gMaxHarmonic * gMaxCorrelator + 1; h++) { + for (int wp = 0; wp < gMaxCorrelator + 1; wp++) // weight power + { + qv.fQ[h][wp] = qv.fQvector[h][wp]; + } + } + + // b) Calculate correlations: + double correlation = 0.; // still has to be divided with 'weight' later, to get average correlation + double weight = 0.; + int n[gMaxCorrelator] = {0}; // array holding harmonics + + for (int mo = 0; mo < gMaxCorrelator; mo++) { + for (int mi = 0; mi < gMaxIndex; mi++) { + // TBI 20210913 I do not have to loop each time all the way up to gMaxCorrelator and gMaxIndex, but nevermind now, it's not a big efficiency loss. + + // Sanitize the labels (If necessary. Locally this is irrelevant): + if (!t0.fTest0Labels[mo][mi]) // I do not stream them. + { + for (int v = 0; v < eAsFunctionOf_N; v++) { + if (t0.fTest0Pro[mo][mi][v]) { + t0.fTest0Labels[mo][mi] = new TString(t0.fTest0Pro[mo][mi][v]->GetTitle()); // there is no memory leak here, since this is executed only once due to if(!fTest0Labels[mo][mi]) + break; // yes, since for all v they are the same, so I just need to fetch it from one + } + } + } // if(!t0_afTest0Labels[mo][mi]) + + if (t0.fTest0Labels[mo][mi]) { + // Extract harmonics from TString, FS is " ": + for (int h = 0; h <= mo; h++) { + TObjArray* oa = t0.fTest0Labels[mo][mi]->Tokenize(" "); + if (!oa) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + n[h] = TString(oa->At(h)->GetName()).Atoi(); + delete oa; // yes, otherwise it's a memory leak + } + + switch (mo + 1) // which order? yes, mo+1 + { + case 1: + if (ebye.fSelectedTracks < 1) { + return; + } + correlation = One(n[0]).Re(); + weight = One(0).Re(); + break; + + case 2: + if (ebye.fSelectedTracks < 2) { + return; + } + correlation = Two(n[0], n[1]).Re(); + weight = Two(0, 0).Re(); + break; + + case 3: + if (ebye.fSelectedTracks < 3) { + return; + } + correlation = Three(n[0], n[1], n[2]).Re(); + weight = Three(0, 0, 0).Re(); + break; + + case 4: + if (ebye.fSelectedTracks < 4) { + return; + } + correlation = Four(n[0], n[1], n[2], n[3]).Re(); + weight = Four(0, 0, 0, 0).Re(); + break; + + case 5: + if (ebye.fSelectedTracks < 5) { + return; + } + correlation = Five(n[0], n[1], n[2], n[3], n[4]).Re(); + weight = Five(0, 0, 0, 0, 0).Re(); + break; + + case 6: + if (ebye.fSelectedTracks < 6) { + return; + } + correlation = Six(n[0], n[1], n[2], n[3], n[4], n[5]).Re(); + weight = Six(0, 0, 0, 0, 0, 0).Re(); + break; + + case 7: + if (ebye.fSelectedTracks < 7) { + return; + } + correlation = Seven(n[0], n[1], n[2], n[3], n[4], n[5], n[6]).Re(); + weight = Seven(0, 0, 0, 0, 0, 0, 0).Re(); + break; + + case 8: + if (ebye.fSelectedTracks < 8) { + return; + } + correlation = Eight(n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7]).Re(); + weight = Eight(0, 0, 0, 0, 0, 0, 0, 0).Re(); + break; + + case 9: + if (ebye.fSelectedTracks < 9) { + return; + } + correlation = Nine(n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7], n[8]).Re(); + weight = Nine(0, 0, 0, 0, 0, 0, 0, 0, 0).Re(); + break; + + case 10: + if (ebye.fSelectedTracks < 10) { + return; + } + correlation = Ten(n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7], n[8], n[9]).Re(); + weight = Ten(0, 0, 0, 0, 0, 0, 0, 0, 0, 0).Re(); + break; + + case 11: + if (ebye.fSelectedTracks < 11) { + return; + } + correlation = Eleven(n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7], n[8], n[9], n[10]).Re(); + weight = Eleven(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0).Re(); + break; + + case 12: + if (ebye.fSelectedTracks < 12) { + return; + } + correlation = Twelve(n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7], n[8], n[9], n[10], n[11]).Re(); + weight = Twelve(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0).Re(); + break; + + default: + LOGF(fatal, "\033[1;31m%s at line %d : Not supported yet: t0.fTest0Labels[mo][mi]->Data() = %s\033[0m", __FUNCTION__, __LINE__, t0.fTest0Labels[mo][mi]->Data()); + } // switch(mo+1) + + // Insanity check on weight: + if (!(weight > 0.)) { + LOGF(fatal, "\033[1;31m%s at line %d : weight = %f, correlation = %f, ebye.fSelectedTracks = %d => Is perhaps order of correlator bigger than the number of particles? t0.fTest0Labels[mo][mi]->Data() = %s \033[0m", __FUNCTION__, __LINE__, weight, correlation, ebye.fSelectedTracks, t0.fTest0Labels[mo][mi]->Data()); + } + + // e-b-e sanity check: + if (nl.fCalculateCustomNestedLoops) { + TArrayI* harmonics = new TArrayI(mo + 1); + for (int i = 0; i < mo + 1; i++) { + harmonics->SetAt(n[i], i); + } + double nestedLoopValue = this->CalculateCustomNestedLoops(harmonics); + if (!(std::abs(nestedLoopValue) > 0.)) { + LOGF(info, " ebye check (integrated) with CustomNestedLoops was NOT calculated for %d-p Test0 corr. %s", mo + 1, t0.fTest0Labels[mo][mi]->Data()); + } else if (std::abs(nestedLoopValue) > 0. && std::abs(correlation / weight - nestedLoopValue) > tc.fFloatingPointPrecision) { + LOGF(fatal, "\033[1;31m%s at line %d : nestedLoopValue = %f is not the same as correlation/weight = %f, for correlator %s\033[0m", __FUNCTION__, __LINE__, nestedLoopValue, correlation / weight, t0.fTest0Labels[mo][mi]->Data()); + } else { + LOGF(info, "\033[1;32m ebye check (integrated) with CustomNestedLoops is OK for %d-p Test0 corr. %s\033[0m", mo + 1, t0.fTest0Labels[mo][mi]->Data()); + } + delete harmonics; + harmonics = NULL; + } // if(nl.fCalculateCustomNestedLoops) + + // To ease comparison, rescale with theoretical value. Now all Test0 results shall be at 1. Remember that contribution from symmetry planes is here also relevant (in general): + if (iv.fUseInternalValidation && iv.fRescaleWithTheoreticalInput && iv.fInternalValidationVnPsin[eVn] && iv.fInternalValidationVnPsin[ePsin]) { + TArrayI* harmonics = new TArrayI(mo + 1); + for (int i = 0; i < mo + 1; i++) { + harmonics->SetAt(n[i], i); + } + TComplex theoreticalValue = this->TheoreticalValue(harmonics, iv.fInternalValidationVnPsin[eVn], iv.fInternalValidationVnPsin[ePsin]); + if (std::abs(theoreticalValue.Re()) > 0.) { + correlation /= theoreticalValue.Re(); + } + // TBI 20240424 for the time being, I do not do anything with imaginary part, but I could eventually... + delete harmonics; + harmonics = NULL; + } // if(fUseInternalValidation && fRescaleWithTheoreticalInput) + + // Finally, fill: + + // 1D: + // integrated: + if (t0.fTest0Pro[mo][mi][AFO_INTEGRATED]) { + t0.fTest0Pro[mo][mi][AFO_INTEGRATED]->Fill(0.5, correlation / weight, weight); + } + // vs. multiplicity: + if (t0.fTest0Pro[mo][mi][AFO_MULTIPLICITY]) { + t0.fTest0Pro[mo][mi][AFO_MULTIPLICITY]->Fill(ebye.fMultiplicity + 0.5, correlation / weight, weight); + } + // vs. centrality: + if (t0.fTest0Pro[mo][mi][AFO_CENTRALITY]) { + t0.fTest0Pro[mo][mi][AFO_CENTRALITY]->Fill(ebye.fCentrality, correlation / weight, weight); + } + // vs. occupancy: + if (t0.fTest0Pro[mo][mi][AFO_OCCUPANCY]) { + t0.fTest0Pro[mo][mi][AFO_OCCUPANCY]->Fill(ebye.fOccupancy, correlation / weight, weight); + } + // vs. interaction rate: + if (t0.fTest0Pro[mo][mi][AFO_INTERACTIONRATE]) { + t0.fTest0Pro[mo][mi][AFO_INTERACTIONRATE]->Fill(ebye.fInteractionRate, correlation / weight, weight); + } + // vs. current run duration: + if (t0.fTest0Pro[mo][mi][AFO_CURRENTRUNDURATION]) { + t0.fTest0Pro[mo][mi][AFO_CURRENTRUNDURATION]->Fill(ebye.fCurrentRunDuration, correlation / weight, weight); + } + // vs. vertex z position: + if (t0.fTest0Pro[mo][mi][AFO_VZ]) { + t0.fTest0Pro[mo][mi][AFO_VZ]->Fill(ebye.fVz, correlation / weight, weight); + } + + // ... + + // 2D: + // vs. centrality vs. vertex z position: + if (t0.fTest0Pro2D[mo][mi][AFO_CENTRALITY_VZ]) { + t0.fTest0Pro2D[mo][mi][AFO_CENTRALITY_VZ]->Fill(ebye.fCentrality, ebye.fVz, correlation / weight, weight); + } + + // ... + + // 3D: + + // ... + + } // if(t0.fTest0Labels[mo][mi]) + } // for(int mi=0;miGetNbinsX(); + break; + } + case AFO_ETA: { + qvKine = ETAq; + nBins = res.fResultsPro[AFO_ETA]->GetNbinsX(); + break; + } + case AFO_CHARGE: { + qvKine = CHARGEq; + nBins = res.fResultsPro[AFO_CHARGE]->GetNbinsX(); + break; + } + default: { + LOGF(fatal, "\033[1;31m%s at line %d : This AFO_variable = %d is not supported yet. \033[0m", __FUNCTION__, __LINE__, static_cast(AFO_variable)); + break; + } + } // switch(AFO_variable) + + // *) Insanity checks on above settings: + if (qvKine == eqvectorKine_N) { + LOGF(fatal, "\033[1;31m%s at line %d : qvKine == eqvectorKine_N => add some more entries to the case statement \033[0m", __FUNCTION__, __LINE__); + } + + // *) Uniform loop over bins for all kine variables: + for (int b = 0; b < nBins; b++) { + + // *) Ensures that in each bin of interest, I have the same cut on number of particles, like in integrated analysis: + if ((qv.fqvectorEntries[qvKine][b] < ec.fdEventCuts[eMultiplicity][eMin]) || (qv.fqvectorEntries[qvKine][b] > ec.fdEventCuts[eMultiplicity][eMax] || std::abs(qv.fqvectorEntries[qvKine][b] - ec.fdEventCuts[eMultiplicity][eMax]) < tc.fFloatingPointPrecision)) { + if (tc.fVerbose) { + LOGF(info, "\033[1;31m%s eMultiplicity cut in bin = %d, for qvKine = %d\033[0m", __FUNCTION__, b, static_cast(qvKine)); + } + } + + // *) Re-initialize Q-vector to be q-vector in this bin: + // After that, I can call all standard Q-vector functions again: + for (int h = 0; h < gMaxHarmonic * gMaxCorrelator + 1; h++) { + for (int wp = 0; wp < gMaxCorrelator + 1; wp++) { // weight power + // qv.fQ[h][wp] = qv.fqvector[qvKine][b][h][wp]; TBI 20250616 I cannot use this any longer, after I added one more dimension to qv.fqvector + } + } + + // *) Okay, let's do the differential calculus: + double correlation = 0.; + double weight = 0.; + int n[gMaxCorrelator] = {0}; // array holding harmonics + + for (int mo = 0; mo < gMaxCorrelator; mo++) { + for (int mi = 0; mi < gMaxIndex; mi++) { + // TBI 20240221 I do not have to loop each time all the way up to gMaxCorrelator and gMaxIndex, but nevermind now, it's not a big efficiency loss. + if (t0.fTest0Labels[mo][mi]) { + // Extract harmonics from TString, FS is " ": + for (int h = 0; h <= mo; h++) { + // cout<At(h)->GetName()).Atoi(); + delete oa; // yes, otherwise it's a memory leak + } + + if (qv.fqvectorEntries[qvKine][b] < mo + 1) { + continue; + } + + switch (mo + 1) // which order? yes, mo+1 + { + case 1: + correlation = One(n[0]).Re(); + weight = One(0).Re(); + break; + + case 2: + correlation = Two(n[0], n[1]).Re(); + weight = Two(0, 0).Re(); + break; + + case 3: + correlation = Three(n[0], n[1], n[2]).Re(); + weight = Three(0, 0, 0).Re(); + break; + + case 4: + correlation = Four(n[0], n[1], n[2], n[3]).Re(); + weight = Four(0, 0, 0, 0).Re(); + break; + + case 5: + correlation = Five(n[0], n[1], n[2], n[3], n[4]).Re(); + weight = Five(0, 0, 0, 0, 0).Re(); + break; + + case 6: + correlation = Six(n[0], n[1], n[2], n[3], n[4], n[5]).Re(); + weight = Six(0, 0, 0, 0, 0, 0).Re(); + break; + + case 7: + correlation = Seven(n[0], n[1], n[2], n[3], n[4], n[5], n[6]).Re(); + weight = Seven(0, 0, 0, 0, 0, 0, 0).Re(); + break; + + case 8: + correlation = Eight(n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7]).Re(); + weight = Eight(0, 0, 0, 0, 0, 0, 0, 0).Re(); + break; + + case 9: + correlation = Nine(n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7], n[8]).Re(); + weight = Nine(0, 0, 0, 0, 0, 0, 0, 0, 0).Re(); + break; + + case 10: + correlation = Ten(n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7], n[8], n[9]).Re(); + weight = Ten(0, 0, 0, 0, 0, 0, 0, 0, 0, 0).Re(); + break; + + case 11: + correlation = Eleven(n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7], n[8], n[9], n[10]).Re(); + weight = Eleven(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0).Re(); + break; + + case 12: + correlation = Twelve(n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7], n[8], n[9], n[10], n[11]).Re(); + weight = Twelve(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0).Re(); + break; + + default: + LOGF(fatal, "\033[1;31m%s at line %d : not supported yet: %s \n\n\033[0m", __FUNCTION__, __LINE__, t0.fTest0Labels[mo][mi]->Data()); + } // switch(mo+1) + + // *) e-b-e sanity check: + if (nl.fCalculateKineCustomNestedLoops) { + TArrayI* harmonics = new TArrayI(mo + 1); + for (int i = 0; i < mo + 1; i++) { + harmonics->SetAt(n[i], i); + } + if (!(weight > 0.)) { + LOGF(fatal, "\033[1;31m%s at line %d : is perhaps order of some requested correlator bigger than the number of particles? Correlator = %s \033[0m", __FUNCTION__, __LINE__, t0.fTest0Labels[mo][mi]->Data()); + } + double nestedLoopValue = this->CalculateKineCustomNestedLoops(harmonics, AFO_variable, b); + if (!(std::abs(nestedLoopValue) > 0.)) { + LOGF(info, " e-b-e check with CalculateKineCustomNestedLoops was NOT calculated for %d-p Test0 corr. %s, bin = %d", mo + 1, t0.fTest0Labels[mo][mi]->Data(), b + 1); + } else if (std::abs(nestedLoopValue) > 0. && std::abs(correlation / weight - nestedLoopValue) > tc.fFloatingPointPrecision) { + LOGF(fatal, "\033[1;31m%s at line %d : correlator: %s \n correlation: %f \n custom loop: %f \033[0m", __FUNCTION__, __LINE__, t0.fTest0Labels[mo][mi]->Data(), correlation / weight, nestedLoopValue); + } else { + LOGF(info, "\033[1;32m ebye check (differential) with CalculateKineCustomNestedLoops is OK for %d-p Test0 corr. %s, bin = %d\033[0m", mo + 1, t0.fTest0Labels[mo][mi]->Data(), b + 1); + } + delete harmonics; + harmonics = NULL; + } // if(nl.fCalculateKineCustomNestedLoops) + + // To ease comparison, rescale with theoretical value. Now all Test0 results shall be at 1: + if (iv.fUseInternalValidation && iv.fRescaleWithTheoreticalInput && iv.fInternalValidationVnPsin[eVn] && iv.fInternalValidationVnPsin[ePsin]) { + TArrayI* harmonics = new TArrayI(mo + 1); + for (int i = 0; i < mo + 1; i++) { + harmonics->SetAt(n[i], i); + } + TComplex theoreticalValue = TheoreticalValue(harmonics, iv.fInternalValidationVnPsin[eVn], iv.fInternalValidationVnPsin[ePsin]); + if (std::abs(theoreticalValue.Re()) > 0.) { + correlation /= theoreticalValue.Re(); + } + // TBI 20240424 for the time being, I do not do anything with imaginary part, but I could eventually... + delete harmonics; + harmonics = NULL; + } // if(fUseInternalValidation && fRescaleWithTheoreticalInput) + + // Insanity check for the event weight: + if (!(weight > 0.)) { + // If it's negative, that means that sum of particle weights is smaller than "number of particles - 1" + // In that case, you can simply rescale all particle weights, so that each of them is > 1, basically recalculate weights.root files with such a rescaling. + LOGF(info, "\n\033[1;33m b = %d \033[0m\n", b); + LOGF(info, "\n\033[1;33m qvKine = %d \033[0m\n", static_cast(qvKine)); + LOGF(info, "\n\033[1;33m event weight = %e \033[0m\n", weight); + LOGF(info, "\n\033[1;33m sum of particle weights = %e \033[0m\n", One(0).Re()); + LOGF(info, "\n\033[1;33m correlation = %f \033[0m\n", correlation); + LOGF(info, "\n\033[1;33m t0.fTest0Pro[mo][mi][AFO_variable]->GetTitle() = %s \033[0m\n", t0.fTest0Pro[mo][mi][AFO_variable]->GetTitle()); + LOGF(info, "\n\033[1;33m [mo][mi][AFO_variable] = [%d][%d][%d] \033[0m\n", mo, mi, static_cast(AFO_variable)); + LOGF(info, "\n\033[1;33m ebye.fSelectedTracks = %d \033[0m\n", ebye.fSelectedTracks); + LOGF(info, "\n\033[1;33m qv.fqvectorEntries[qvKine][b] = %d \033[0m\n", qv.fqvectorEntries[qvKine][b]); + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + + // Finally, fill: + + // 1D: + if (t0.fTest0Pro[mo][mi][AFO_variable]) { + t0.fTest0Pro[mo][mi][AFO_variable]->Fill(t0.fTest0Pro[mo][mi][AFO_variable]->GetXaxis()->GetBinCenter(b + 1), correlation / weight, weight); + } // fill in the bin center + + // 2D: + if (t0.fCalculate2DTest0) { + + // vs. centrality vs. pt: + if (t0.fTest0Pro2D[mo][mi][AFO_CENTRALITY_PT] && AFO_variable == AFO_PT) { + t0.fTest0Pro2D[mo][mi][AFO_CENTRALITY_PT]->Fill(ebye.fCentrality, t0.fTest0Pro2D[mo][mi][AFO_CENTRALITY_PT]->GetYaxis()->GetBinCenter(b + 1), correlation / weight, weight); + } + + // vs. centrality vs. eta: + if (t0.fTest0Pro2D[mo][mi][AFO_CENTRALITY_ETA] && AFO_variable == AFO_ETA) { + t0.fTest0Pro2D[mo][mi][AFO_CENTRALITY_ETA]->Fill(ebye.fCentrality, t0.fTest0Pro2D[mo][mi][AFO_CENTRALITY_ETA]->GetYaxis()->GetBinCenter(b + 1), correlation / weight, weight); + } + + // vs. centrality vs. charge: + if (t0.fTest0Pro2D[mo][mi][AFO_CENTRALITY_CHARGE] && AFO_variable == AFO_CHARGE) { + t0.fTest0Pro2D[mo][mi][AFO_CENTRALITY_CHARGE]->Fill(ebye.fCentrality, t0.fTest0Pro2D[mo][mi][AFO_CENTRALITY_CHARGE]->GetYaxis()->GetBinCenter(b + 1), correlation / weight, weight); + } + + // ... + + } // if(t0.fCalculate2DTest0) + + } // if(fTest0Labels[mo][mi]) + } // for(int mi=0;mi(kineVarChoice), StringKineMap(kineVarChoice).Data(), Ndim); + } + + int nBins = -1; + + switch (Ndim) { + + case 1: { + eAsFunctionOf AFO_var = AfoKineMap1D(kineVarChoice); + if (res.fResultsPro[AFO_var]) { + nBins = res.fResultsPro[AFO_var]->GetNbinsX() + 2; // + 2 means that I take into account overflow and underflow, then skip it in the loop below. + if (tc.fVerbose) { + LOGF(info, "\033[1;31m%s nBins = %d, kineVarChoice = %d (%s), Ndim = %d \033[0m", __FUNCTION__, nBins, static_cast(kineVarChoice), StringKineMap(kineVarChoice).Data(), Ndim); + } + } + + break; + } + + case 2: { + eAsFunctionOf2D AFO_var = AfoKineMap2D(kineVarChoice); + if (res.fResultsPro2D[AFO_var]) { + nBins = (res.fResultsPro2D[AFO_var]->GetNbinsX() + 2) * (res.fResultsPro2D[AFO_var]->GetNbinsY() + 2); // + 2 means that I take into account overflow and underflow, then skip it in the loop below + if (tc.fVerbose) { + LOGF(info, "\033[1;31m%s nBins = %d, kineVarChoice = %d (%s), Ndim = %d \033[0m", __FUNCTION__, nBins, static_cast(kineVarChoice), StringKineMap(kineVarChoice).Data(), Ndim); + } + } + + break; + } + + case 3: { + eAsFunctionOf3D AFO_var = AfoKineMap3D(kineVarChoice); + if (res.fResultsPro3D[AFO_var]) { + nBins = (res.fResultsPro3D[AFO_var]->GetNbinsX() + 2) * (res.fResultsPro3D[AFO_var]->GetNbinsY() + 2) * (res.fResultsPro3D[AFO_var]->GetNbinsZ() + 2); // + 2 means that I take into account overflow and underflow, then skip it in the loop below + if (tc.fVerbose) { + LOGF(info, "\033[1;31m%s nBins = %d, kineVarChoice = %d (%s), Ndim = %d \033[0m", __FUNCTION__, nBins, static_cast(kineVarChoice), StringKineMap(kineVarChoice).Data(), Ndim); + } + } + break; + } + + // ... + + default: { + LOGF(fatal, "\033[1;31m%s at line %d : Ndim = %d is not supported yet. \033[0m", __FUNCTION__, __LINE__, Ndim); + break; + } + + } // switch (Ndim) + + // *) Uniform loop over linearized global bins for all kine variables: + for (int b = 0; b < nBins; b++) { // yes, "< nBins", not "<= nBins", because b runs over all regular bins + 2 (therefore, including underflow and overflow already) + + if (tc.fVerbose) { // TBI 20250701 temporary check, remove eventually + LOGF(info, "\033[1;31m%s b = %d \033[0m", __FUNCTION__, b); + Trace(__FUNCTION__, __LINE__); + } + + // *) Check if this bin is overflow or underflow, or otherwise if it's empty: + // Well, I already checked that when filling fqvector, if this global bin is overflow or underflow, qvector and number of entries shall be empty for that bin, so I am checking for that: + if (0 == qv.fqvectorEntries[kineVarChoice][b]) { + if (tc.fVerbose) { + LOGF(info, "\033[1;31m%s no entries in bin = %d, for kineVarChoice = %d (%s). Just skipping this bin (this is most likely underflow or overflow global bin)\033[0m", __FUNCTION__, b, static_cast(kineVarChoice), StringKineMap(kineVarChoice).Data()); + } + continue; + } + + // *) Ensures that in each kine bin, I have the same cut on number of particles, like in integrated analysis: + // Remarks: + // 1. if I do not use this cut here, I allow possibility that correlations are calculated in a given kine bin even when that makes no sense + // (two few particles for that particular correlators); + // 2. if I use it, I will not be able to get exactly the same result after rebinning (or ironing out some dimensions) as in integrated analysis. But this is + // how it is in any case, because paticles from different kine bins are never directly correlated in kine analysis. Therefore, even in principle, I cannot + // cross-check integrated results for correlations, by rebinning the final kine results. + if (qv.fqvectorEntries[kineVarChoice][b] < ec.fdEventCuts[eMultiplicity][eMin] || qv.fqvectorEntries[kineVarChoice][b] > ec.fdEventCuts[eMultiplicity][eMax] || std::abs(qv.fqvectorEntries[kineVarChoice][b] - ec.fdEventCuts[eMultiplicity][eMax]) < tc.fFloatingPointPrecision) { + if (tc.fVerbose) { + LOGF(info, "\033[1;31m%s eMultiplicity cut in kine bin = %b, for kineVarChoice = %d (%s), there are only %d selected particles in this kine bin\033[0m", __FUNCTION__, b, static_cast(kineVarChoice), StringKineMap(kineVarChoice).Data(), qv.fqvectorEntries[kineVarChoice][b]); + } + continue; + } + + // *) Re-initialize Q-vector to be q-vector in this bin: + // After that, I can call all standard Q-vector functions again: + for (int h = 0; h < gMaxHarmonic * gMaxCorrelator + 1; h++) { + for (int wp = 0; wp < gMaxCorrelator + 1; wp++) { + qv.fQ[h][wp] = TComplex(qv.fqvector[kineVarChoice][b][h][wp].real(), qv.fqvector[kineVarChoice][b][h][wp].imag()); // TBI 20250601 check if there is a simpler way to initialize ROOT TComplex with C++ type 'complex' + } + } + + // TBI 20250702 Do I need to do some separate insanity check for the case when Q is identically 0? + // Most likely not, as all such cases shall already be covered with previous two checks above. + // I leave it like this, unless proven otherwise. + + if (tc.fVerbose) { // TBI 20250701 temporary check, remove eventually + Trace(__FUNCTION__, __LINE__); + } + + // *) Okay, let's do transparently the differential calculus, whether it's 1D, 2D, 3D, ...: + double correlation = 0.; + double weight = 0.; + int n[gMaxCorrelator] = {0}; // array holding harmonics + + for (int mo = 0; mo < gMaxCorrelator; mo++) { + for (int mi = 0; mi < gMaxIndex; mi++) { + // TBI 20240221 I do not have to loop each time all the way up to gMaxCorrelator and gMaxIndex, but nevermind now, it's not a big efficiency loss. + if (t0.fTest0Labels[mo][mi]) { + // Extract harmonics from TString, FS is " ": + for (int h = 0; h <= mo; h++) { + // cout<At(h)->GetName()).Atoi(); + delete oa; // yes, otherwise it's a memory leak + } + + if (qv.fqvectorEntries[kineVarChoice][b] < mo + 1) { + continue; + } + + switch (mo + 1) // which order? yes, mo+1 + { + case 1: + correlation = One(n[0]).Re(); + weight = One(0).Re(); + break; + + case 2: + correlation = Two(n[0], n[1]).Re(); + weight = Two(0, 0).Re(); + break; + + case 3: + correlation = Three(n[0], n[1], n[2]).Re(); + weight = Three(0, 0, 0).Re(); + break; + + case 4: + correlation = Four(n[0], n[1], n[2], n[3]).Re(); + weight = Four(0, 0, 0, 0).Re(); + break; + + case 5: + correlation = Five(n[0], n[1], n[2], n[3], n[4]).Re(); + weight = Five(0, 0, 0, 0, 0).Re(); + break; + + case 6: + correlation = Six(n[0], n[1], n[2], n[3], n[4], n[5]).Re(); + weight = Six(0, 0, 0, 0, 0, 0).Re(); + break; + + case 7: + correlation = Seven(n[0], n[1], n[2], n[3], n[4], n[5], n[6]).Re(); + weight = Seven(0, 0, 0, 0, 0, 0, 0).Re(); + break; + + case 8: + correlation = Eight(n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7]).Re(); + weight = Eight(0, 0, 0, 0, 0, 0, 0, 0).Re(); + break; + + case 9: + correlation = Nine(n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7], n[8]).Re(); + weight = Nine(0, 0, 0, 0, 0, 0, 0, 0, 0).Re(); + break; + + case 10: + correlation = Ten(n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7], n[8], n[9]).Re(); + weight = Ten(0, 0, 0, 0, 0, 0, 0, 0, 0, 0).Re(); + break; + + case 11: + correlation = Eleven(n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7], n[8], n[9], n[10]).Re(); + weight = Eleven(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0).Re(); + break; + + case 12: + correlation = Twelve(n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7], n[8], n[9], n[10], n[11]).Re(); + weight = Twelve(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0).Re(); + break; + + default: + LOGF(fatal, "\033[1;31m%s at line %d : not supported yet: %s \n\n\033[0m", __FUNCTION__, __LINE__, t0.fTest0Labels[mo][mi]->Data()); + } // switch(mo+1) + + // *) e-b-e sanity check: + if (nl.fCalculateKineCustomNestedLoops) { + TArrayI* harmonics = new TArrayI(mo + 1); + for (int i = 0; i < mo + 1; i++) { + harmonics->SetAt(n[i], i); + } + if (!(weight > 0.)) { + LOGF(fatal, "\033[1;31m%s at line %d : is perhaps order of some requested correlator bigger than the number of particles? Correlator = %s \033[0m", __FUNCTION__, __LINE__, t0.fTest0Labels[mo][mi]->Data()); + } + double nestedLoopValue = this->CalculateKineCustomNestedLoops(harmonics, kineVarChoice, b); + PrintBinEdgesKine(kineVarChoice, b); + if (!(std::abs(nestedLoopValue) > 0.)) { + LOGF(info, " e-b-e check with CalculateKineCustomNestedLoops was NOT calculated for %d-p Test0 corr. %s, kineVarChoice (eqvectorKine) = %d (%s), bin = %d", mo + 1, t0.fTest0Labels[mo][mi]->Data(), static_cast(kineVarChoice), StringKineMap(kineVarChoice).Data(), b); + } else if (std::abs(nestedLoopValue) > 0. && std::abs(correlation / weight - nestedLoopValue) > tc.fFloatingPointPrecision) { + LOGF(fatal, "\033[1;31m%s at line %d : correlator: %s \n correlation: %f \n custom loop: %f \033[0m", __FUNCTION__, __LINE__, t0.fTest0Labels[mo][mi]->Data(), correlation / weight, nestedLoopValue); + } else { + LOGF(info, "\033[1;32m ebye check (differential) with CalculateKineCustomNestedLoops is OK for %d-p Test0 corr. %s, kineVarChoice (eqvectorKine) = %d (%s), bin = %d, nParticles in this bin = %d\033[0m", mo + 1, t0.fTest0Labels[mo][mi]->Data(), static_cast(kineVarChoice), StringKineMap(kineVarChoice).Data(), b, qv.fqvectorEntries[kineVarChoice][b]); + } + delete harmonics; + harmonics = NULL; + } // if(nl.fCalculateKineCustomNestedLoops) + + if (tc.fVerbose) { // TBI 20250701 temporary check, remove eventually + Trace(__FUNCTION__, __LINE__); + } + + // To ease comparison, rescale with theoretical value. Now all Test0 results shall be at 1: + if (iv.fUseInternalValidation && iv.fRescaleWithTheoreticalInput && iv.fInternalValidationVnPsin[eVn] && iv.fInternalValidationVnPsin[ePsin]) { + TArrayI* harmonics = new TArrayI(mo + 1); + for (int i = 0; i < mo + 1; i++) { + harmonics->SetAt(n[i], i); + } + TComplex theoreticalValue = TheoreticalValue(harmonics, iv.fInternalValidationVnPsin[eVn], iv.fInternalValidationVnPsin[ePsin]); + if (std::abs(theoreticalValue.Re()) > 0.) { + correlation /= theoreticalValue.Re(); + } + // TBI 20240424 for the time being, I do not do anything with imaginary part, but I could eventually... + delete harmonics; + harmonics = NULL; + } // if(fUseInternalValidation && fRescaleWithTheoreticalInput) + + if (tc.fVerbose) { // TBI 20250701 temporary check, remove eventually + Trace(__FUNCTION__, __LINE__); + } + + // Insanity check for the event weight: + if (!(weight > 0.)) { + // If it's negative, that means that sum of particle weights is smaller than "number of particles - 1" + // In that case, you can simply rescale all particle weights, so that each of them is > 1, basically recalculate weights.root files with such a rescaling. + LOGF(info, "\n\033[1;33m b = %d \033[0m\n", b); + LOGF(info, "\n\033[1;33m kineVarChoice = %d \033[0m\n", static_cast(kineVarChoice)); + LOGF(info, "\n\033[1;33m event weight = %e \033[0m\n", weight); + LOGF(info, "\n\033[1;33m sum of particle weights = %e \033[0m\n", One(0).Re()); + LOGF(info, "\n\033[1;33m correlation = %f \033[0m\n", correlation); + + switch (Ndim) { + + case 1: { + eAsFunctionOf AFO_var = AfoKineMap1D(kineVarChoice); + LOGF(info, "\n\033[1;33m t0.fTest0Pro[mo][mi][AFO_variable]->GetTitle() = %s \033[0m\n", t0.fTest0Pro[mo][mi][AFO_var]->GetTitle()); + LOGF(info, "\n\033[1;33m [mo][mi][AFO_variable] = [%d][%d][%d] \033[0m\n", mo, mi, static_cast(AFO_var)); + break; + } + + case 2: { + eAsFunctionOf2D AFO_var = AfoKineMap2D(kineVarChoice); + LOGF(info, "\n\033[1;33m t0.fTest0Pro2D[mo][mi][AFO_variable]->GetTitle() = %s \033[0m\n", t0.fTest0Pro2D[mo][mi][AFO_var]->GetTitle()); + LOGF(info, "\n\033[1;33m [mo][mi][AFO_variable] = [%d][%d][%d] \033[0m\n", mo, mi, static_cast(AFO_var)); + break; + } + + case 3: { + eAsFunctionOf3D AFO_var = AfoKineMap3D(kineVarChoice); + LOGF(info, "\n\033[1;33m t0.fTest0Pro3D[mo][mi][AFO_variable]->GetTitle() = %s \033[0m\n", t0.fTest0Pro3D[mo][mi][AFO_var]->GetTitle()); + LOGF(info, "\n\033[1;33m [mo][mi][AFO_variable] = [%d][%d][%d] \033[0m\n", mo, mi, static_cast(AFO_var)); + break; + } + + // ... + + default: { + LOGF(fatal, "\033[1;31m%s at line %d : Ndim = %d is not supported yet. \033[0m", __FUNCTION__, __LINE__, Ndim); + break; + } + + } // switch (Ndim) + + LOGF(info, "\n\033[1;33m ebye.fSelectedTracks = %d \033[0m\n", ebye.fSelectedTracks); + LOGF(info, "\n\033[1;33m qv.fqvectorEntries[kineVarChoice][b] = %d \033[0m\n", qv.fqvectorEntries[kineVarChoice][b]); + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + + // Finally, fill: + switch (Ndim) { + + case 1: { + + // *) cases for which 1D vs. pt calculus is needed: + if (kineVarChoice == PTq) { + // **) vs. pt: + if (t0.fTest0Pro[mo][mi][AFO_PT]) { + t0.fTest0Pro[mo][mi][AFO_PT]->Fill(t0.fTest0Pro[mo][mi][AFO_PT]->GetXaxis()->GetBinCenter(b), correlation / weight, weight); // only for 1D kine case, I can use direcly b, because "linearized global bin" is the same as ordinary bin + } + // **) vs. centrality vs. pt: + if (t0.fTest0Pro2D[mo][mi][AFO_CENTRALITY_PT]) { + t0.fTest0Pro2D[mo][mi][AFO_CENTRALITY_PT]->Fill(ebye.fCentrality, t0.fTest0Pro2D[mo][mi][AFO_CENTRALITY_PT]->GetYaxis()->GetBinCenter(b), correlation / weight, weight); // only for 1D kine case, I can use direcly b, because "linearized global bin" is the same as ordinary bin + } + // **) vs. centrality vs. pt vs. vz: + if (t0.fTest0Pro3D[mo][mi][AFO_CENTRALITY_PT_VZ]) { + t0.fTest0Pro3D[mo][mi][AFO_CENTRALITY_PT_VZ]->Fill(ebye.fCentrality, t0.fTest0Pro3D[mo][mi][AFO_CENTRALITY_PT_VZ]->GetYaxis()->GetBinCenter(b), ebye.fVz, correlation / weight, weight); // only for 1D kine case, I can use direcly b, because "linearized global bin" is the same as ordinary bin + } + + // ... + + } // if (kineVarChoice == PTq) { + + // *) cases for which 1D vs. eta calculus is needed: + if (kineVarChoice == ETAq) { + // **) vs. eta: + if (t0.fTest0Pro[mo][mi][AFO_ETA]) { + t0.fTest0Pro[mo][mi][AFO_ETA]->Fill(t0.fTest0Pro[mo][mi][AFO_ETA]->GetXaxis()->GetBinCenter(b), correlation / weight, weight); // only for 1D kine case, I can use direcly b, because "linearized global bin" is the same as ordinary bin + } + // **) vs. centrality vs. eta: + if (t0.fTest0Pro2D[mo][mi][AFO_CENTRALITY_ETA]) { + t0.fTest0Pro2D[mo][mi][AFO_CENTRALITY_ETA]->Fill(ebye.fCentrality, t0.fTest0Pro2D[mo][mi][AFO_CENTRALITY_ETA]->GetYaxis()->GetBinCenter(b), correlation / weight, weight); // only for 1D kine case, I can use direcly b, because "linearized global bin" is the same as ordinary bin + } + // **) vs. centrality vs. eta vs. vz: + if (t0.fTest0Pro3D[mo][mi][AFO_CENTRALITY_ETA_VZ]) { + t0.fTest0Pro3D[mo][mi][AFO_CENTRALITY_ETA_VZ]->Fill(ebye.fCentrality, t0.fTest0Pro3D[mo][mi][AFO_CENTRALITY_ETA_VZ]->GetYaxis()->GetBinCenter(b), ebye.fVz, correlation / weight, weight); // only for 1D kine case, I can use direcly b, because "linearized global bin" is the same as ordinary bin + } + + // ... + + } // if (kineVarChoice == ETAq) { + + // *) cases for which 1D vs. charge calculus is needed: + if (kineVarChoice == CHARGEq) { + // **) vs. charge: + if (t0.fTest0Pro[mo][mi][AFO_CHARGE]) { + t0.fTest0Pro[mo][mi][AFO_CHARGE]->Fill(t0.fTest0Pro[mo][mi][AFO_CHARGE]->GetXaxis()->GetBinCenter(b), correlation / weight, weight); // only for 1D kine case, I can use direcly b, because "linearized global bin" is the same as ordinary bin + } + // **) vs. centrality vs. charge: + if (t0.fTest0Pro2D[mo][mi][AFO_CENTRALITY_CHARGE]) { + t0.fTest0Pro2D[mo][mi][AFO_CENTRALITY_CHARGE]->Fill(ebye.fCentrality, t0.fTest0Pro2D[mo][mi][AFO_CENTRALITY_CHARGE]->GetYaxis()->GetBinCenter(b), correlation / weight, weight); // only for 1D kine case, I can use direcly b, because "linearized global bin" is the same as ordinary bin + } + + // **) vs. centrality vs. vz vs. charge: + if (t0.fTest0Pro3D[mo][mi][AFO_CENTRALITY_VZ_CHARGE]) { + t0.fTest0Pro3D[mo][mi][AFO_CENTRALITY_VZ_CHARGE]->Fill(ebye.fCentrality, ebye.fVz, t0.fTest0Pro3D[mo][mi][AFO_CENTRALITY_VZ_CHARGE]->GetZaxis()->GetBinCenter(b), correlation / weight, weight); // only for 1D kine case, I can use direcly b, because "linearized global bin" is the same as ordinary bin + } + + // ... + + } // if (kineVarChoice == CHARGEq) { + + // ... + + break; + } + + case 2: { + + // *) cases for which 2D vs. (pt,eta) calculus is needed: + if (kineVarChoice == PT_ETAq) { + + // transfer global bin b into (binX, binY, binZ): + int binX = -1; + int binY = -1; + int binZ = -1; // dummy for 2D case + t0.fTest0Pro2D[mo][mi][AFO_PT_ETA]->GetBinXYZ(b, binX, binY, binZ); + + // **) vs. pt vs. eta: + if (t0.fTest0Pro2D[mo][mi][AFO_PT_ETA]) { + t0.fTest0Pro2D[mo][mi][AFO_PT_ETA]->Fill(t0.fTest0Pro2D[mo][mi][AFO_PT_ETA]->GetXaxis()->GetBinCenter(binX), t0.fTest0Pro2D[mo][mi][AFO_PT_ETA]->GetYaxis()->GetBinCenter(binY), correlation / weight, weight); + } + + // **) vs. centrality vs. pt vs. eta: + if (t0.fTest0Pro3D[mo][mi][AFO_CENTRALITY_PT_ETA]) { + // Remark: I have to re-use binX, binY, binZ obtained from t0.fTest0Pro2D[mo][mi][AFO_PT_ETA] above, because I am looping for "case 2:" here over global bin number of + // t0.fTest0Pro2D[mo][mi][AFO_PT_ETA], not of t0.fTest0Pro3D[mo][mi][AFO_CENTRALITY_PT_ETA] + t0.fTest0Pro3D[mo][mi][AFO_CENTRALITY_PT_ETA]->Fill(ebye.fCentrality, t0.fTest0Pro3D[mo][mi][AFO_CENTRALITY_PT_ETA]->GetYaxis()->GetBinCenter(binX), t0.fTest0Pro3D[mo][mi][AFO_CENTRALITY_PT_ETA]->GetZaxis()->GetBinCenter(binY), correlation / weight, weight); // yes, y-axis of this histogram is x-axis of t0.fTest0Pro2D[mo][mi][AFO_PT_ETA], and similarly z-axis here is y-axis of t0.fTest0Pro2D[mo][mi][AFO_PT_ETA] + } + + // ... + + } // if (kineVarChoice == PT_ETAq) + + // *) cases for which 2D vs. (pt,charge) calculus is needed: + if (kineVarChoice == PT_CHARGEq) { + + // transfer global bin b into (binX, binY, binZ): + int binX = -1; + int binY = -1; + int binZ = -1; // dummy for 2D case + t0.fTest0Pro2D[mo][mi][AFO_PT_CHARGE]->GetBinXYZ(b, binX, binY, binZ); + + // **) vs. pt vs. charge: + if (t0.fTest0Pro2D[mo][mi][AFO_PT_CHARGE]) { + t0.fTest0Pro2D[mo][mi][AFO_PT_CHARGE]->Fill(t0.fTest0Pro2D[mo][mi][AFO_PT_CHARGE]->GetXaxis()->GetBinCenter(binX), t0.fTest0Pro2D[mo][mi][AFO_PT_CHARGE]->GetYaxis()->GetBinCenter(binY), correlation / weight, weight); + } + // **) vs. centrality vs. pt vs. charge: + if (t0.fTest0Pro3D[mo][mi][AFO_CENTRALITY_PT_CHARGE]) { + // Remark: I have to re-use binX, binY, binZ obtained from t0.fTest0Pro2D[mo][mi][AFO_PT_CHARGE] above, because I am looping for "case 2:" here over global bin number of + // t0.fTest0Pro2D[mo][mi][AFO_PT_CHARGE], not of t0.fTest0Pro3D[mo][mi][AFO_CENTRALITY_PT_CHARGE] + t0.fTest0Pro3D[mo][mi][AFO_CENTRALITY_PT_CHARGE]->Fill(ebye.fCentrality, t0.fTest0Pro3D[mo][mi][AFO_CENTRALITY_PT_CHARGE]->GetYaxis()->GetBinCenter(binX), t0.fTest0Pro3D[mo][mi][AFO_CENTRALITY_PT_CHARGE]->GetZaxis()->GetBinCenter(binY), correlation / weight, weight); // yes, y-axis of this histogram is x-axis of t0.fTest0Pro2D[mo][mi][AFO_PT_CHARGE], and similarly z-axis here is y-axis of t0.fTest0Pro2D[mo][mi][AFO_PT_CHARGE] + } + + // ... + + } // if (kineVarChoice == PT_CHARGEq) + + // *) cases for which 2D vs. (eta,charge) calculus is needed: + if (kineVarChoice == ETA_CHARGEq) { + + // transfer global bin b into (binX, binY, binZ): + int binX = -1; + int binY = -1; + int binZ = -1; // dummy for 2D case + t0.fTest0Pro2D[mo][mi][AFO_ETA_CHARGE]->GetBinXYZ(b, binX, binY, binZ); + + // **) vs. eta vs. charge: + if (t0.fTest0Pro2D[mo][mi][AFO_ETA_CHARGE]) { + t0.fTest0Pro2D[mo][mi][AFO_ETA_CHARGE]->Fill(t0.fTest0Pro2D[mo][mi][AFO_ETA_CHARGE]->GetXaxis()->GetBinCenter(binX), t0.fTest0Pro2D[mo][mi][AFO_ETA_CHARGE]->GetYaxis()->GetBinCenter(binY), correlation / weight, weight); + } + // **) vs. centrality vs. eta vs. charge: + if (t0.fTest0Pro3D[mo][mi][AFO_CENTRALITY_ETA_CHARGE]) { + // Remark: I have to re-use binX, binY, binZ obtained from t0.fTest0Pro2D[mo][mi][AFO_ETA_CHARGE] above, because I am looping for "case 2:" here over global bin number of + // t0.fTest0Pro2D[mo][mi][AFO_ETA_CHARGE], not of t0.fTest0Pro3D[mo][mi][AFO_CENTRALITY_ETA_CHARGE] + t0.fTest0Pro3D[mo][mi][AFO_CENTRALITY_ETA_CHARGE]->Fill(ebye.fCentrality, t0.fTest0Pro3D[mo][mi][AFO_CENTRALITY_ETA_CHARGE]->GetYaxis()->GetBinCenter(binX), t0.fTest0Pro3D[mo][mi][AFO_CENTRALITY_ETA_CHARGE]->GetZaxis()->GetBinCenter(binY), correlation / weight, weight); // yes, y-axis of this histogram is x-axis of t0.fTest0Pro2D[mo][mi][AFO_ETA_CHARGE], and similarly z-axis here is y-axis of t0.fTest0Pro2D[mo][mi][AFO_ETA_CHARGE] + } + + // ... + + } // if (kineVarChoice == ETA_CHARGEq) + + // ... + + break; + } + + case 3: { + + // *) cases for which 3D vs. (pt,eta,charge) calculus is needed: + if (kineVarChoice == PT_ETA_CHARGEq) { + + // transfer global bin b into (binX, binY, binZ): + int binX = -1; + int binY = -1; + int binZ = -1; + t0.fTest0Pro3D[mo][mi][AFO_PT_ETA_CHARGE]->GetBinXYZ(b, binX, binY, binZ); + + // **) vs. pt vs. eta vs. charge: + if (t0.fTest0Pro3D[mo][mi][AFO_PT_ETA_CHARGE]) { + t0.fTest0Pro3D[mo][mi][AFO_PT_ETA_CHARGE]->Fill(t0.fTest0Pro3D[mo][mi][AFO_PT_ETA_CHARGE]->GetXaxis()->GetBinCenter(binX), + t0.fTest0Pro3D[mo][mi][AFO_PT_ETA_CHARGE]->GetYaxis()->GetBinCenter(binY), + t0.fTest0Pro3D[mo][mi][AFO_PT_ETA_CHARGE]->GetZaxis()->GetBinCenter(binZ), + correlation / weight, weight); + } + } + + // ... + + break; + } + + // ... + + default: { + LOGF(fatal, "\033[1;31m%s at line %d : Ndim = %d is not supported yet. \033[0m", __FUNCTION__, __LINE__, Ndim); + break; + } + + } // switch (Ndim) + + } // if(fTest0Labels[mo][mi]) + } // for(int mi=0;mi kineVarChoice (eqvectorKine) = %d, global (ordinary) bin %d <=> (%f, %f)", static_cast(kineVarChoice), bin, res.fResultsPro[AfoKineMap1D(kineVarChoice)]->GetBinLowEdge(bin), res.fResultsPro[AfoKineMap1D(kineVarChoice)]->GetBinLowEdge(bin + 1)); + + break; + } + + // 2D: + case PT_ETAq: + case PT_CHARGEq: + case ETA_CHARGEq: { + + // transfer global bin b into (binX, binY, binZ): + int binX = -1; + int binY = -1; + int binZ = -1; // dummy for 2D case + res.fResultsPro2D[AfoKineMap2D(kineVarChoice)]->GetBinXYZ(bin, binX, binY, binZ); + + LOGF(info, " => kineVarChoice (eqvectorKine) = %d, global bin %d = (%d, %d) <=> (%f, %f) x (%f, %f)", static_cast(kineVarChoice), bin, binX, binY, res.fResultsPro2D[AfoKineMap2D(kineVarChoice)]->GetXaxis()->GetBinLowEdge(binX), res.fResultsPro2D[AfoKineMap2D(kineVarChoice)]->GetXaxis()->GetBinLowEdge(binX + 1), res.fResultsPro2D[AfoKineMap2D(kineVarChoice)]->GetYaxis()->GetBinLowEdge(binY), res.fResultsPro2D[AfoKineMap2D(kineVarChoice)]->GetYaxis()->GetBinLowEdge(binY + 1)); + + break; + } + + // 3D: + case PT_ETA_CHARGEq: { + + // transfer global bin b into (binX, binY, binZ): + int binX = -1; + int binY = -1; + int binZ = -1; + res.fResultsPro3D[AfoKineMap3D(kineVarChoice)]->GetBinXYZ(bin, binX, binY, binZ); + + LOGF(info, " => kineVarChoice (eqvectorKine) = %d, global bin %d = (%d, %d, %d) <=> (%f, %f) x (%f, %f) x (%f, %f)", static_cast(kineVarChoice), bin, binX, binY, binZ, res.fResultsPro3D[AfoKineMap3D(kineVarChoice)]->GetXaxis()->GetBinLowEdge(binX), res.fResultsPro3D[AfoKineMap3D(kineVarChoice)]->GetXaxis()->GetBinLowEdge(binX + 1), res.fResultsPro3D[AfoKineMap3D(kineVarChoice)]->GetYaxis()->GetBinLowEdge(binY), res.fResultsPro3D[AfoKineMap3D(kineVarChoice)]->GetYaxis()->GetBinLowEdge(binY + 1), res.fResultsPro3D[AfoKineMap3D(kineVarChoice)]->GetZaxis()->GetBinLowEdge(binZ), res.fResultsPro3D[AfoKineMap3D(kineVarChoice)]->GetZaxis()->GetBinLowEdge(binZ + 1)); + + break; + } + + default: { + LOGF(fatal, "\033[1;31m%s at line %d : This kineVarChoice = %d is not supported yet. \033[0m", __FUNCTION__, __LINE__, static_cast(kineVarChoice)); + break; + } + + } // switch(AFO_variable) + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // void PrintBinEdgesKine() + + //============================================================ + + void CalculateEtaSeparations() + { + // Calculate correlations with pseudorapidity separations. + + // Remark: this is a port and generalization of void AliFlowAnalysisWithMultiparticleCorrelations::CalculateEtaGaps(AliFlowEventSimple *anEvent) + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // Calculate 2-p correlations with eta separations from Qa (-eta, index [0]) and Qb (+eta, index [1]) vectors: + double correlation = 0.; + double weight = 0.; + for (int h = 0; h < gMaxHarmonic; h++) { + if (es.fEtaSeparationsSkipHarmonics[h]) { + continue; + } + for (int e = 0; e < gMaxNumberEtaSeparations; e++) { + if (!(qv.fQabVector[0][h][e].Rho() > 0. && qv.fQabVector[1][h][e].Rho() > 0.)) { + continue; + } + if (!(qv.fMab[0][e] > 0. && qv.fMab[1][e] > 0.)) { + continue; + } + + // calculate correlation and weights with particular eta separation: + correlation = TComplex(qv.fQabVector[0][h][e] * TComplex::Conjugate(qv.fQabVector[1][h][e])).Re(); + weight = qv.fMab[0][e] * qv.fMab[1][e]; + + // for on-the-fly and internal validation, rescale results with theoretical value: + if (iv.fUseInternalValidation && iv.fRescaleWithTheoreticalInput && iv.fInternalValidationVnPsin[eVn] && std::abs(iv.fInternalValidationVnPsin[eVn]->GetAt(h)) > 0.) { + correlation /= std::pow(iv.fInternalValidationVnPsin[eVn]->GetAt(h), 2.); + } + + // integrated: + if (es.fEtaSeparationsPro[h][e][AFO_INTEGRATED]) { + es.fEtaSeparationsPro[h][e][AFO_INTEGRATED]->Fill(0.5, correlation / weight, weight); + } + + // vs. multiplicity: + if (es.fEtaSeparationsPro[h][e][AFO_MULTIPLICITY]) { + es.fEtaSeparationsPro[h][e][AFO_MULTIPLICITY]->Fill(ebye.fMultiplicity + 0.5, correlation / weight, weight); + } + + // vs. centrality: + if (es.fEtaSeparationsPro[h][e][AFO_CENTRALITY]) { + es.fEtaSeparationsPro[h][e][AFO_CENTRALITY]->Fill(ebye.fCentrality, correlation / weight, weight); + } + + // vs. occupancy: + if (es.fEtaSeparationsPro[h][e][AFO_OCCUPANCY]) { + es.fEtaSeparationsPro[h][e][AFO_OCCUPANCY]->Fill(ebye.fOccupancy, correlation / weight, weight); + } + + // vs. interaction rate: + if (es.fEtaSeparationsPro[h][e][AFO_INTERACTIONRATE]) { + es.fEtaSeparationsPro[h][e][AFO_INTERACTIONRATE]->Fill(ebye.fInteractionRate, correlation / weight, weight); + } + + // vs. current run duration: + if (es.fEtaSeparationsPro[h][e][AFO_CURRENTRUNDURATION]) { + es.fEtaSeparationsPro[h][e][AFO_CURRENTRUNDURATION]->Fill(ebye.fCurrentRunDuration, correlation / weight, weight); + } + + // vs. vertex z position: + if (es.fEtaSeparationsPro[h][e][AFO_VZ]) { + es.fEtaSeparationsPro[h][e][AFO_VZ]->Fill(ebye.fVz, correlation / weight, weight); + } + + } // for (int e = 0; e < gMaxNumberEtaSeparations; e++) { + } // for (int h = 0; h < gMaxHarmonic; h++) { + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // void CalculateEtaSeparations() + + //============================================================ + + void CalculateKineEtaSeparationsNdim(eqvectorKine kineVarChoice, int Ndim) + { + // Calculate analytically N-dimensional kine eta separations from differential q-vectors. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // This is a replacement for the legacy function CalculateKineEtaSeparations(...), which is as of 20250620 deemed obsolete. + // Remember that here I changed design, and pass enum eqvectorKine as an argument, not any longer enum eAsFunctionOf. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + int nBins = -1; + + switch (Ndim) { + + case 1: { + eAsFunctionOf AFO_var = AfoKineMap1D(kineVarChoice); + if (res.fResultsPro[AFO_var]) { + nBins = res.fResultsPro[AFO_var]->GetNbinsX() + 2; // + 2 means that I take into account overflow and underflow, then skip it in the loop below. + } + + break; + } + + case 2: { + eAsFunctionOf2D AFO_var = AfoKineMap2D(kineVarChoice); + if (res.fResultsPro2D[AFO_var]) { + nBins = (res.fResultsPro2D[AFO_var]->GetNbinsX() + 2) * (res.fResultsPro2D[AFO_var]->GetNbinsY() + 2); // + 2 means that I take into account overflow and underflow, then skip it in the loop below + } + + break; + } + + case 3: { + eAsFunctionOf3D AFO_var = AfoKineMap3D(kineVarChoice); + if (res.fResultsPro3D[AFO_var]) { + nBins = (res.fResultsPro3D[AFO_var]->GetNbinsX() + 2) * (res.fResultsPro3D[AFO_var]->GetNbinsY() + 2) * (res.fResultsPro3D[AFO_var]->GetNbinsZ() + 2); // + 2 means that I take into account overflow and underflow, then skip it in the loop below + } + break; + } + + // ... + + default: { + LOGF(fatal, "\033[1;31m%s at line %d : Ndim = %d is not supported yet. \033[0m", __FUNCTION__, __LINE__, Ndim); + break; + } + + } // switch (Ndim) + + // *) Uniform loop over linearized global bins for all kine variables: + for (int b = 0; b < nBins; b++) { // yes, "< nBins", not "<= nBins", because b runs over all regular bins + 2 (therefore, including underflow and overflow already) + + // Calculate differential 2-p correlations for all requested harmonics, and all eta separations from Qa (-eta, index [0]) and Qb (+eta, index [1]) vectors: + double correlation = 0.; + double weight = 0.; + for (int h = 0; h < gMaxHarmonic; h++) { + if (es.fEtaSeparationsSkipHarmonics[h]) { + continue; + } + + for (int e = 0; e < gMaxNumberEtaSeparations; e++) { + + // *) Check if this bin is overflow or underflow, or otherwise if it's empty: + if (!(qv.fmab[0][kineVarChoice][b][e] > 0. && qv.fmab[1][kineVarChoice][b][e] > 0.)) { + if (tc.fVerbose) { + LOGF(info, "\033[1;31m%s no entries in kine bin = %b, for kineVarChoice = %d (%s), and for eta separation index = %d. Just skipping this kine bin (this is most likely underflow or overflow global kine bin)\033[0m", __FUNCTION__, b, static_cast(kineVarChoice), StringKineMap(kineVarChoice).Data(), e); + } + continue; + } + + // *) Ensures that in each kine bin, with eta separations, I have the same cut on number of particles, like in integrated analysis: + // 1. see corrresponding remarks in CalculateKineTest0Ndim( ... ); + // 2. note that here I apply the cut on the sum A + B (it's safe, because corner cases when mult. is 0 in A or in B, is already removed with previous cut here) + + if ((qv.fmab[0][kineVarChoice][b][e] + qv.fmab[1][kineVarChoice][b][e]) < ec.fdEventCuts[eMultiplicity][eMin] || + (qv.fmab[0][kineVarChoice][b][e] + qv.fmab[1][kineVarChoice][b][e]) > ec.fdEventCuts[eMultiplicity][eMax] || + std::abs(qv.fmab[0][kineVarChoice][b][e] + qv.fmab[1][kineVarChoice][b][e] - ec.fdEventCuts[eMultiplicity][eMax]) < tc.fFloatingPointPrecision) { + + if (tc.fVerbose) { + LOGF(info, "\033[1;31m%s eMultiplicity cut in kine bin = %b, for kineVarChoice = %d (%s), and for eta separation index = %d. There are only %d selected particles in both eta separated intervals in this kine bin\033[0m", __FUNCTION__, b, static_cast(kineVarChoice), StringKineMap(kineVarChoice).Data(), e, qv.fqvectorEntries[kineVarChoice][b]); + } + continue; + } + + // *) Finally, skip kine bins, with eta separations, for which either qa or qb is zero: + if (!(std::abs(qv.fqabVector[0][kineVarChoice][b][h][e]) > 0. && std::abs(qv.fqabVector[1][kineVarChoice][b][h][e]) > 0.)) { + continue; + } + + // calculate correlation and weights with particular eta separation: + correlation = (qv.fqabVector[0][kineVarChoice][b][h][e] * std::conj(qv.fqabVector[1][kineVarChoice][b][h][e])).real(); + // Remark: this was the legacy code, just in case I would still need it: + // correlation = TComplex(qv.fqabVector[0][kineVarChoice][b][h][e] * TComplex::Conjugate(qv.fqabVector[1][kineVarChoice][b][h][e])).Re(); + weight = qv.fmab[0][kineVarChoice][b][e] * qv.fmab[1][kineVarChoice][b][e]; + + // for on-the-fly and internal validation, rescale results with theoretical value: + if (iv.fUseInternalValidation && iv.fRescaleWithTheoreticalInput && iv.fInternalValidationVnPsin[eVn] && std::abs(iv.fInternalValidationVnPsin[eVn]->GetAt(h)) > 0.) { + correlation /= std::pow(iv.fInternalValidationVnPsin[eVn]->GetAt(h), 2.); + } + + // finally, fill 1D case: + if (es.fEtaSeparationsPro[h][e][AfoKineMap1D(kineVarChoice)]) { + es.fEtaSeparationsPro[h][e][AfoKineMap1D(kineVarChoice)]->Fill(es.fEtaSeparationsPro[h][e][AfoKineMap1D(kineVarChoice)]->GetXaxis()->GetBinCenter(b), correlation / weight, weight); + } + + // TBI 20250620 I need to add support eventually also for 2D and 3D cases. + } + } + } // for (int b = 0; b < nBins; b++) + + // *) Quick insanity check: I shall never have any entry in underflow (bin = 0) or overflow (bin = nBins -1) in es.fEtaSeparationsPro, otherwise some cuts were bypassed: + if (tc.fDoAdditionalInsanityChecks) { + for (int h = 0; h < gMaxHarmonic; h++) { + for (int e = 0; e < gMaxNumberEtaSeparations; e++) { + if (es.fEtaSeparationsPro[h][e][AfoKineMap1D(kineVarChoice)] && std::abs(es.fEtaSeparationsPro[h][e][AfoKineMap1D(kineVarChoice)]->GetBinContent(0)) > 0.) { + LOGF(fatal, "\033[1;31m%s at line %d : underflow is not empty \033[0m", __FUNCTION__, __LINE__); + } + if (es.fEtaSeparationsPro[h][e][AfoKineMap1D(kineVarChoice)] && std::abs(es.fEtaSeparationsPro[h][e][AfoKineMap1D(kineVarChoice)]->GetBinContent(nBins - 1)) > 0.) { + LOGF(fatal, "\033[1;31m%s at line %d : overflow is not empty \033[0m", __FUNCTION__, __LINE__); + } + } + } + } // if (tc.fDoAdditionalInsanityChecks) + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // void CalculateKineEtaSeparationsNdim(eqvectorKine kineVarChoice, int Ndim) + + //============================================================ + + void FillNestedLoopsContainers(const int& particleIndex) + { + // Fill into the nested loop containers the current particle. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + if (tc.fInsanityCheckForEachParticle) { + if (particleIndex < 0) { + LOGF(fatal, "\033[1;31m%s at line %d : particleIndex = %d\033[0m", __FUNCTION__, __LINE__, particleIndex); + } + if (!(std::abs(nl.ftaNestedLoops[0]->GetAt(particleIndex - 1)) > 0.)) { + LOGF(fatal, "\033[1;31m%s at line %d : there are empty elements in nl.ftaNestedLoops[0] \033[0m", __FUNCTION__, __LINE__); + // I need this protection, to ensure that all array entries are filled. If not, most likely a particle passed all + // selection criteria, and it wasn't added to the nested loops containers + } + } + + // *) Fill container for angles: + if (nl.ftaNestedLoops[0]) { + nl.ftaNestedLoops[0]->AddAt(pbyp.fPhi, particleIndex); // remember that the 2nd argument here must start from 0 + } + + // *) Fill container for weights: + if (nl.ftaNestedLoops[1]) { + // TBI 20240501 there is a bit of efficiency loss here, because I access Weight() again here. + // But it doesn't matter really, in any case I evaluate nested loops only for small M during debugging. + // Otherwise, just promote weights to data members, and initialize them only once for a given particle. + double wPhi = 1.; + double wPt = 1.; + double wEta = 1.; + + if (pw.fUseDiffPhiWeights[wPhiPhiAxis]) { // yes, 0th axis serves as a common boolean for this category + wPhi = WeightFromSparse(eDWPhi); + } + + if (pw.fUseDiffPtWeights[wPtPtAxis]) { // yes, 0th axis serves as a common boolean for this category + wPt = WeightFromSparse(eDWPt); + } + + if (pw.fUseDiffEtaWeights[wEtaEtaAxis]) { // yes, 0th axis serves as a common boolean for this category + wEta = WeightFromSparse(eDWEta); + } + + if (pw.fUseWeights[wPHI]) { // TBI 20260216 obsolete, remove eventually + wPhi = Weight(pbyp.fPhi, wPHI); + } + + if (pw.fUseWeights[wPT]) { // TBI 20260216 obsolete, remove eventually + wPt = Weight(pbyp.fPt, wPT); + } + + if (pw.fUseWeights[wETA]) { // TBI 20260216 obsolete, remove eventually + wEta = Weight(pbyp.fEta, wETA); + } + + nl.ftaNestedLoops[1]->AddAt(wPhi * wPt * wEta, particleIndex); // remember that the 2nd argument here must start from 0 + } + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // void FillNestedLoopsContainers(const int& particleIndex) + + //============================================================ + + void CalculateNestedLoops() + { + // Calculate correlations with nested loops. + + // a) 2-particle nested loops; + // b) 4-particle nested loops; + // c) 6-particle nested loops; + // d) 8-particle nested loops. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + LOGF(info, " ebye.fSelectedTracks = %d", ebye.fSelectedTracks); + int nParticles = ebye.fSelectedTracks; + + // a) 2-particle nested loops: + if (nParticles < 2) { + return; + } + if (nl.fMaxNestedLoop > 0 && nl.fMaxNestedLoop < 2) { + return; + } + LOGF(info, " Calculating 2-p correlations with nested loops .... "); + for (int i1 = 0; i1 < nParticles; i1++) { + double dPhi1 = nl.ftaNestedLoops[0]->GetAt(i1); + double dW1 = nl.ftaNestedLoops[1]->GetAt(i1); + for (int i2 = 0; i2 < nParticles; i2++) { + if (i2 == i1) { + continue; + } + double dPhi2 = nl.ftaNestedLoops[0]->GetAt(i2); + double dW2 = nl.ftaNestedLoops[1]->GetAt(i2); + for (int h = 0; h < gMaxHarmonic; h++) { + // fill cos, 2p, integreated: + if (nl.fNestedLoopsPro[0][h][AFO_INTEGRATED]) { + nl.fNestedLoopsPro[0][h][AFO_INTEGRATED]->Fill( + 0.5, std::cos((h + 1.) * (dPhi1 - dPhi2)), dW1 * dW2); + } + // fill cos, 2p, vs. multiplicity: + if (nl.fNestedLoopsPro[0][h][AFO_MULTIPLICITY]) { + nl.fNestedLoopsPro[0][h][AFO_MULTIPLICITY]->Fill( + ebye.fMultiplicity + 0.5, std::cos((h + 1.) * (dPhi1 - dPhi2)), + dW1 * dW2); + } + // fill cos, 2p, vs. centrality: + if (nl.fNestedLoopsPro[0][h][AFO_CENTRALITY]) { + nl.fNestedLoopsPro[0][h][AFO_CENTRALITY]->Fill( + ebye.fCentrality, std::cos((h + 1.) * (dPhi1 - dPhi2)), dW1 * dW2); + } + // fill cos, 2p, vs. occupancy: + if (nl.fNestedLoopsPro[0][h][AFO_OCCUPANCY]) { + nl.fNestedLoopsPro[0][h][AFO_OCCUPANCY]->Fill( + ebye.fOccupancy, std::cos((h + 1.) * (dPhi1 - dPhi2)), dW1 * dW2); + } + // fill cos, 2p, vs. interaction rate: + if (nl.fNestedLoopsPro[0][h][AFO_INTERACTIONRATE]) { + nl.fNestedLoopsPro[0][h][AFO_INTERACTIONRATE]->Fill( + ebye.fInteractionRate, std::cos((h + 1.) * (dPhi1 - dPhi2)), dW1 * dW2); + } + // fill cos, 2p, vs. current run duration: + if (nl.fNestedLoopsPro[0][h][AFO_CURRENTRUNDURATION]) { + nl.fNestedLoopsPro[0][h][AFO_CURRENTRUNDURATION]->Fill( + ebye.fCurrentRunDuration, std::cos((h + 1.) * (dPhi1 - dPhi2)), dW1 * dW2); + } + // fill cos, 2p, vs. vertex z position: + if (nl.fNestedLoopsPro[0][h][AFO_VZ]) { + nl.fNestedLoopsPro[0][h][AFO_VZ]->Fill( + ebye.fVz, std::cos((h + 1.) * (dPhi1 - dPhi2)), dW1 * dW2); + } + + } // for(int h=1; h<=6; h++) + } // for(int i2=0; i2 0 && nl.fMaxNestedLoop < 4) { + return; + } + LOGF(info, " Calculating 4-p correlations with nested loops .... "); + for (int i1 = 0; i1 < nParticles; i1++) { + double dPhi1 = nl.ftaNestedLoops[0]->GetAt(i1); + double dW1 = nl.ftaNestedLoops[1]->GetAt(i1); + for (int i2 = 0; i2 < nParticles; i2++) { + if (i2 == i1) { + continue; + } + double dPhi2 = nl.ftaNestedLoops[0]->GetAt(i2); + double dW2 = nl.ftaNestedLoops[1]->GetAt(i2); + for (int i3 = 0; i3 < nParticles; i3++) { + if (i3 == i1 || i3 == i2) { + continue; + } + double dPhi3 = nl.ftaNestedLoops[0]->GetAt(i3); + double dW3 = nl.ftaNestedLoops[1]->GetAt(i3); + for (int i4 = 0; i4 < nParticles; i4++) { + if (i4 == i1 || i4 == i2 || i4 == i3) { + continue; + } + double dPhi4 = nl.ftaNestedLoops[0]->GetAt(i4); + double dW4 = nl.ftaNestedLoops[1]->GetAt(i4); + for (int h = 0; h < gMaxHarmonic; h++) { + // fill cos, 4p, integreated: + if (nl.fNestedLoopsPro[1][h][AFO_INTEGRATED]) { + nl.fNestedLoopsPro[1][h][AFO_INTEGRATED]->Fill(0.5, std::cos((h + 1.) * (dPhi1 + dPhi2 - dPhi3 - dPhi4)), dW1 * dW2 * dW3 * dW4); + } + // fill cos, 4p, all harmonics, vs. M: + if (nl.fNestedLoopsPro[1][h][AFO_MULTIPLICITY]) { + nl.fNestedLoopsPro[1][h][AFO_MULTIPLICITY]->Fill(ebye.fMultiplicity + 0.5, std::cos((h + 1.) * (dPhi1 + dPhi2 - dPhi3 - dPhi4)), dW1 * dW2 * dW3 * dW4); + } + // fill cos, 4p, all harmonics, vs. centrality: + if (nl.fNestedLoopsPro[1][h][AFO_CENTRALITY]) { + nl.fNestedLoopsPro[1][h][AFO_CENTRALITY]->Fill(ebye.fCentrality, std::cos((h + 1.) * (dPhi1 + dPhi2 - dPhi3 - dPhi4)), dW1 * dW2 * dW3 * dW4); + } + // fill cos, 4p, all harmonics, vs. occupancy: + if (nl.fNestedLoopsPro[1][h][AFO_OCCUPANCY]) { + nl.fNestedLoopsPro[1][h][AFO_OCCUPANCY]->Fill(ebye.fOccupancy, std::cos((h + 1.) * (dPhi1 + dPhi2 - dPhi3 - dPhi4)), dW1 * dW2 * dW3 * dW4); + } + // fill cos, 4p, all harmonics, vs. interaction rate: + if (nl.fNestedLoopsPro[1][h][AFO_INTERACTIONRATE]) { + nl.fNestedLoopsPro[1][h][AFO_INTERACTIONRATE]->Fill(ebye.fInteractionRate, std::cos((h + 1.) * (dPhi1 + dPhi2 - dPhi3 - dPhi4)), dW1 * dW2 * dW3 * dW4); + } + // fill cos, 4p, all harmonics, vs. current run duratione: + if (nl.fNestedLoopsPro[1][h][AFO_CURRENTRUNDURATION]) { + nl.fNestedLoopsPro[1][h][AFO_CURRENTRUNDURATION]->Fill(ebye.fCurrentRunDuration, std::cos((h + 1.) * (dPhi1 + dPhi2 - dPhi3 - dPhi4)), dW1 * dW2 * dW3 * dW4); + } + // fill cos, 4p, all harmonics, vs. vertex z position: + if (nl.fNestedLoopsPro[1][h][AFO_VZ]) { + nl.fNestedLoopsPro[1][h][AFO_VZ]->Fill(ebye.fVz, std::cos((h + 1.) * (dPhi1 + dPhi2 - dPhi3 - dPhi4)), dW1 * dW2 * dW3 * dW4); + } + } // for(int h=0; h 0 && nl.fMaxNestedLoop < 6) { + return; + } + LOGF(info, " Calculating 6-p correlations with nested loops .... "); + for (int i1 = 0; i1 < nParticles; i1++) { + double dPhi1 = nl.ftaNestedLoops[0]->GetAt(i1); + double dW1 = nl.ftaNestedLoops[1]->GetAt(i1); + for (int i2 = 0; i2 < nParticles; i2++) { + if (i2 == i1) { + continue; + } + double dPhi2 = nl.ftaNestedLoops[0]->GetAt(i2); + double dW2 = nl.ftaNestedLoops[1]->GetAt(i2); + for (int i3 = 0; i3 < nParticles; i3++) { + if (i3 == i1 || i3 == i2) { + continue; + } + double dPhi3 = nl.ftaNestedLoops[0]->GetAt(i3); + double dW3 = nl.ftaNestedLoops[1]->GetAt(i3); + for (int i4 = 0; i4 < nParticles; i4++) { + if (i4 == i1 || i4 == i2 || i4 == i3) { + continue; + } + double dPhi4 = nl.ftaNestedLoops[0]->GetAt(i4); + double dW4 = nl.ftaNestedLoops[1]->GetAt(i4); + for (int i5 = 0; i5 < nParticles; i5++) { + if (i5 == i1 || i5 == i2 || i5 == i3 || i5 == i4) { + continue; + } + double dPhi5 = nl.ftaNestedLoops[0]->GetAt(i5); + double dW5 = nl.ftaNestedLoops[1]->GetAt(i5); + for (int i6 = 0; i6 < nParticles; i6++) { + if (i6 == i1 || i6 == i2 || i6 == i3 || i6 == i4 || i6 == i5) { + continue; + } + double dPhi6 = nl.ftaNestedLoops[0]->GetAt(i6); + double dW6 = nl.ftaNestedLoops[1]->GetAt(i6); + for (int h = 0; h < gMaxHarmonic; h++) { + // fill cos, 6p, integreated: + if (nl.fNestedLoopsPro[2][h][AFO_INTEGRATED]) { + nl.fNestedLoopsPro[2][h][AFO_INTEGRATED]->Fill(0.5, std::cos((h + 1.) * (dPhi1 + dPhi2 + dPhi3 - dPhi4 - dPhi5 - dPhi6)), dW1 * dW2 * dW3 * dW4 * dW5 * dW6); + } + // fill cos, 6p, all harmonics, vs. M: + if (nl.fNestedLoopsPro[2][h][AFO_MULTIPLICITY]) { + nl.fNestedLoopsPro[2][h][AFO_MULTIPLICITY]->Fill(ebye.fMultiplicity + 0.5, std::cos((h + 1.) * (dPhi1 + dPhi2 + dPhi3 - dPhi4 - dPhi5 - dPhi6)), dW1 * dW2 * dW3 * dW4 * dW5 * dW6); + } + // fill cos, 6p, all harmonics, vs. centrality: + if (nl.fNestedLoopsPro[2][h][AFO_CENTRALITY]) { + nl.fNestedLoopsPro[2][h][AFO_CENTRALITY]->Fill(ebye.fCentrality, std::cos((h + 1.) * (dPhi1 + dPhi2 + dPhi3 - dPhi4 - dPhi5 - dPhi6)), dW1 * dW2 * dW3 * dW4 * dW5 * dW6); + } + // fill cos, 6p, all harmonics, vs. occupancy: + if (nl.fNestedLoopsPro[2][h][AFO_OCCUPANCY]) { + nl.fNestedLoopsPro[2][h][AFO_OCCUPANCY]->Fill(ebye.fOccupancy, std::cos((h + 1.) * (dPhi1 + dPhi2 + dPhi3 - dPhi4 - dPhi5 - dPhi6)), dW1 * dW2 * dW3 * dW4 * dW5 * dW6); + } + // fill cos, 6p, all harmonics, vs. interaction rate: + if (nl.fNestedLoopsPro[2][h][AFO_INTERACTIONRATE]) { + nl.fNestedLoopsPro[2][h][AFO_INTERACTIONRATE]->Fill(ebye.fInteractionRate, std::cos((h + 1.) * (dPhi1 + dPhi2 + dPhi3 - dPhi4 - dPhi5 - dPhi6)), dW1 * dW2 * dW3 * dW4 * dW5 * dW6); + } + // fill cos, 6p, all harmonics, vs. current run duration: + if (nl.fNestedLoopsPro[2][h][AFO_CURRENTRUNDURATION]) { + nl.fNestedLoopsPro[2][h][AFO_CURRENTRUNDURATION]->Fill(ebye.fCurrentRunDuration, std::cos((h + 1.) * (dPhi1 + dPhi2 + dPhi3 - dPhi4 - dPhi5 - dPhi6)), dW1 * dW2 * dW3 * dW4 * dW5 * dW6); + } + // fill cos, 6p, all harmonics, vs. vertex z position: + if (nl.fNestedLoopsPro[2][h][AFO_VZ]) { + nl.fNestedLoopsPro[2][h][AFO_VZ]->Fill(ebye.fVz, std::cos((h + 1.) * (dPhi1 + dPhi2 + dPhi3 - dPhi4 - dPhi5 - dPhi6)), dW1 * dW2 * dW3 * dW4 * dW5 * dW6); + } + } // for(int h=0; h 0 && nl.fMaxNestedLoop < 8) { + return; + } + LOGF(info, " Calculating 8-p correlations with nested loops .... "); + for (int i1 = 0; i1 < nParticles; i1++) { + double dPhi1 = nl.ftaNestedLoops[0]->GetAt(i1); + double dW1 = nl.ftaNestedLoops[1]->GetAt(i1); + for (int i2 = 0; i2 < nParticles; i2++) { + if (i2 == i1) { + continue; + } + double dPhi2 = nl.ftaNestedLoops[0]->GetAt(i2); + double dW2 = nl.ftaNestedLoops[1]->GetAt(i2); + for (int i3 = 0; i3 < nParticles; i3++) { + if (i3 == i1 || i3 == i2) { + continue; + } + double dPhi3 = nl.ftaNestedLoops[0]->GetAt(i3); + double dW3 = nl.ftaNestedLoops[1]->GetAt(i3); + for (int i4 = 0; i4 < nParticles; i4++) { + if (i4 == i1 || i4 == i2 || i4 == i3) { + continue; + } + double dPhi4 = nl.ftaNestedLoops[0]->GetAt(i4); + double dW4 = nl.ftaNestedLoops[1]->GetAt(i4); + for (int i5 = 0; i5 < nParticles; i5++) { + if (i5 == i1 || i5 == i2 || i5 == i3 || i5 == i4) { + continue; + } + double dPhi5 = nl.ftaNestedLoops[0]->GetAt(i5); + double dW5 = nl.ftaNestedLoops[1]->GetAt(i5); + for (int i6 = 0; i6 < nParticles; i6++) { + if (i6 == i1 || i6 == i2 || i6 == i3 || i6 == i4 || i6 == i5) { + continue; + } + double dPhi6 = nl.ftaNestedLoops[0]->GetAt(i6); + double dW6 = nl.ftaNestedLoops[1]->GetAt(i6); + for (int i7 = 0; i7 < nParticles; i7++) { + if (i7 == i1 || i7 == i2 || i7 == i3 || i7 == i4 || i7 == i5 || i7 == i6) { + continue; + } + double dPhi7 = nl.ftaNestedLoops[0]->GetAt(i7); + double dW7 = nl.ftaNestedLoops[1]->GetAt(i7); + for (int i8 = 0; i8 < nParticles; i8++) { + if (i8 == i1 || i8 == i2 || i8 == i3 || i8 == i4 || i8 == i5 || i8 == i6 || i8 == i7) { + continue; + } + double dPhi8 = nl.ftaNestedLoops[0]->GetAt(i8); + double dW8 = nl.ftaNestedLoops[1]->GetAt(i8); + for (int h = 0; h < gMaxHarmonic; h++) { + // fill cos, 8p, integreated: + if (nl.fNestedLoopsPro[3][h][AFO_INTEGRATED]) { + nl.fNestedLoopsPro[3][h][AFO_INTEGRATED]->Fill(0.5, std::cos((h + 1.) * (dPhi1 + dPhi2 + dPhi3 + dPhi4 - dPhi5 - dPhi6 - dPhi7 - dPhi8)), dW1 * dW2 * dW3 * dW4 * dW5 * dW6 * dW7 * dW8); + } + // fill cos, 8p, all harmonics, vs. M: + if (nl.fNestedLoopsPro[3][h][AFO_MULTIPLICITY]) { + nl.fNestedLoopsPro[3][h][AFO_MULTIPLICITY]->Fill(ebye.fMultiplicity + 0.5, std::cos((h + 1.) * (dPhi1 + dPhi2 + dPhi3 + dPhi4 - dPhi5 - dPhi6 - dPhi7 - dPhi8)), dW1 * dW2 * dW3 * dW4 * dW5 * dW6 * dW7 * dW8); + } + // fill cos, 8p, all harmonics, vs. centrality: + if (nl.fNestedLoopsPro[3][h][AFO_CENTRALITY]) { + nl.fNestedLoopsPro[3][h][AFO_CENTRALITY]->Fill(ebye.fCentrality, std::cos((h + 1.) * (dPhi1 + dPhi2 + dPhi3 + dPhi4 - dPhi5 - dPhi6 - dPhi7 - dPhi8)), dW1 * dW2 * dW3 * dW4 * dW5 * dW6 * dW7 * dW8); + } + // fill cos, 8p, all harmonics, vs. occupancy: + if (nl.fNestedLoopsPro[3][h][AFO_OCCUPANCY]) { + nl.fNestedLoopsPro[3][h][AFO_OCCUPANCY]->Fill(ebye.fOccupancy, std::cos((h + 1.) * (dPhi1 + dPhi2 + dPhi3 + dPhi4 - dPhi5 - dPhi6 - dPhi7 - dPhi8)), dW1 * dW2 * dW3 * dW4 * dW5 * dW6 * dW7 * dW8); + } + // fill cos, 8p, all harmonics, vs. interaction rate: + if (nl.fNestedLoopsPro[3][h][AFO_INTERACTIONRATE]) { + nl.fNestedLoopsPro[3][h][AFO_INTERACTIONRATE]->Fill(ebye.fInteractionRate, std::cos((h + 1.) * (dPhi1 + dPhi2 + dPhi3 + dPhi4 - dPhi5 - dPhi6 - dPhi7 - dPhi8)), dW1 * dW2 * dW3 * dW4 * dW5 * dW6 * dW7 * dW8); + } + // fill cos, 8p, all harmonics, vs. current run duration: + if (nl.fNestedLoopsPro[3][h][AFO_CURRENTRUNDURATION]) { + nl.fNestedLoopsPro[3][h][AFO_CURRENTRUNDURATION]->Fill(ebye.fCurrentRunDuration, std::cos((h + 1.) * (dPhi1 + dPhi2 + dPhi3 + dPhi4 - dPhi5 - dPhi6 - dPhi7 - dPhi8)), dW1 * dW2 * dW3 * dW4 * dW5 * dW6 * dW7 * dW8); + } + // fill cos, 8p, all harmonics, vs. vertex z position: + if (nl.fNestedLoopsPro[3][h][AFO_VZ]) { + nl.fNestedLoopsPro[3][h][AFO_VZ]->Fill(ebye.fVz, std::cos((h + 1.) * (dPhi1 + dPhi2 + dPhi3 + dPhi4 - dPhi5 - dPhi6 - dPhi7 - dPhi8)), dW1 * dW2 * dW3 * dW4 * dW5 * dW6 * dW7 * dW8); + } + } // for(int h=0; hGetNbinsX(); + nBinsNL = nl.fNestedLoopsPro[0][0][v]->GetNbinsX(); + if (nBinsQV != nBinsNL) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + LOGF(info, "\033[1;32m [%d] : %s\033[0m", v, res.fResultsProXaxisTitle[v].Data()); + for (int o = 0; o < 4; o++) { + LOGF(info, "\033[1;32m ==== <<%d>>-particle correlations ====\033[0m", 2 * (o + 1)); + for (int h = 0; h < gMaxHarmonic; h++) { + for (int b = 1; b <= nBinsQV; b++) { + if (mupa.fCorrelationsPro[o][h][v]) { + valueQV = mupa.fCorrelationsPro[o][h][v]->GetBinContent(b); + } + if (nl.fNestedLoopsPro[o][h][v]) { + valueNL = nl.fNestedLoopsPro[o][h][v]->GetBinContent(b); + } + if (std::abs(valueQV) > 0. && std::abs(valueNL) > 0.) { + LOGF(info, " bin=%d, h=%d, Q-vectors: %f", b, h + 1, valueQV); + LOGF(info, " bin=%d, h=%d, Nested loops: %f", b, h + 1, valueNL); + if (std::abs(valueQV - valueNL) > tc.fFloatingPointPrecision) { + LOGF(info, "\n\033[1;33m[%d][%d][%d] \033[0m\n", o, h, v); + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + } // if(std::abs(valueQV)>0. && std::abs(valueNL)>0.) + } // for(int b=1;b<=nBinsQV;b++) + } // for (int h = 0; h < gMaxHarmonic; h++) { + LOGF(info, ""); // new line + } // for(int o=0;o<4;o++) + } // for (int v = 0; v < 3; v++) + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // void ComparisonNestedLoopsVsCorrelations() + + //============================================================ + + TComplex Q(int n, int wp) + { + // Using the fact that Q{-n,p} = Q{n,p}^*. + + if (n >= 0) { + return qv.fQ[n][wp]; + } + return TComplex::Conjugate(qv.fQ[-n][wp]); + + } // TComplex FlowWithMultiparticleCorrelationsTask::Q(int n, int wp) + + //============================================================ + + TComplex One(int n1) + { + // Generic expression . + + TComplex one = Q(n1, 1); + + return one; + + } // TComplex FlowWithMultiparticleCorrelationsTask::One(int n1) + + //============================================================ + + TComplex Two(int n1, int n2) + { + // Generic two-particle correlation . + + TComplex two = Q(n1, 1) * Q(n2, 1) - Q(n1 + n2, 2); + + return two; + + } // TComplex FlowWithMultiparticleCorrelationsTask::Two(int n1, int n2) + + //============================================================ + + TComplex Three(int n1, int n2, int n3) + { + // Generic three-particle correlation . + + TComplex three = Q(n1, 1) * Q(n2, 1) * Q(n3, 1) - Q(n1 + n2, 2) * Q(n3, 1) - + Q(n2, 1) * Q(n1 + n3, 2) - Q(n1, 1) * Q(n2 + n3, 2) + + 2. * Q(n1 + n2 + n3, 3); + + return three; + + } // TComplex Three(int n1, int n2, int n3) + + //============================================================ + + TComplex Four(int n1, int n2, int n3, int n4) + { + // Generic four-particle correlation . + + TComplex four = + Q(n1, 1) * Q(n2, 1) * Q(n3, 1) * Q(n4, 1) - + Q(n1 + n2, 2) * Q(n3, 1) * Q(n4, 1) - + Q(n2, 1) * Q(n1 + n3, 2) * Q(n4, 1) - + Q(n1, 1) * Q(n2 + n3, 2) * Q(n4, 1) + 2. * Q(n1 + n2 + n3, 3) * Q(n4, 1) - + Q(n2, 1) * Q(n3, 1) * Q(n1 + n4, 2) + Q(n2 + n3, 2) * Q(n1 + n4, 2) - + Q(n1, 1) * Q(n3, 1) * Q(n2 + n4, 2) + Q(n1 + n3, 2) * Q(n2 + n4, 2) + + 2. * Q(n3, 1) * Q(n1 + n2 + n4, 3) - Q(n1, 1) * Q(n2, 1) * Q(n3 + n4, 2) + + Q(n1 + n2, 2) * Q(n3 + n4, 2) + 2. * Q(n2, 1) * Q(n1 + n3 + n4, 3) + + 2. * Q(n1, 1) * Q(n2 + n3 + n4, 3) - 6. * Q(n1 + n2 + n3 + n4, 4); + + return four; + + } // TComplex Four(int n1, int n2, int n3, int n4) + + //============================================================ + + TComplex Five(int n1, int n2, int n3, int n4, int n5) + { + // Generic five-particle correlation . + + TComplex five = Q(n1, 1) * Q(n2, 1) * Q(n3, 1) * Q(n4, 1) * Q(n5, 1) - Q(n1 + n2, 2) * Q(n3, 1) * Q(n4, 1) * Q(n5, 1) - Q(n2, 1) * Q(n1 + n3, 2) * Q(n4, 1) * Q(n5, 1) - Q(n1, 1) * Q(n2 + n3, 2) * Q(n4, 1) * Q(n5, 1) + 2. * Q(n1 + n2 + n3, 3) * Q(n4, 1) * Q(n5, 1) - Q(n2, 1) * Q(n3, 1) * Q(n1 + n4, 2) * Q(n5, 1) + Q(n2 + n3, 2) * Q(n1 + n4, 2) * Q(n5, 1) - Q(n1, 1) * Q(n3, 1) * Q(n2 + n4, 2) * Q(n5, 1) + Q(n1 + n3, 2) * Q(n2 + n4, 2) * Q(n5, 1) + 2. * Q(n3, 1) * Q(n1 + n2 + n4, 3) * Q(n5, 1) - Q(n1, 1) * Q(n2, 1) * Q(n3 + n4, 2) * Q(n5, 1) + Q(n1 + n2, 2) * Q(n3 + n4, 2) * Q(n5, 1) + 2. * Q(n2, 1) * Q(n1 + n3 + n4, 3) * Q(n5, 1) + 2. * Q(n1, 1) * Q(n2 + n3 + n4, 3) * Q(n5, 1) - 6. * Q(n1 + n2 + n3 + n4, 4) * Q(n5, 1) - Q(n2, 1) * Q(n3, 1) * Q(n4, 1) * Q(n1 + n5, 2) + Q(n2 + n3, 2) * Q(n4, 1) * Q(n1 + n5, 2) + Q(n3, 1) * Q(n2 + n4, 2) * Q(n1 + n5, 2) + Q(n2, 1) * Q(n3 + n4, 2) * Q(n1 + n5, 2) - 2. * Q(n2 + n3 + n4, 3) * Q(n1 + n5, 2) - Q(n1, 1) * Q(n3, 1) * Q(n4, 1) * Q(n2 + n5, 2) + Q(n1 + n3, 2) * Q(n4, 1) * Q(n2 + n5, 2) + Q(n3, 1) * Q(n1 + n4, 2) * Q(n2 + n5, 2) + Q(n1, 1) * Q(n3 + n4, 2) * Q(n2 + n5, 2) - 2. * Q(n1 + n3 + n4, 3) * Q(n2 + n5, 2) + 2. * Q(n3, 1) * Q(n4, 1) * Q(n1 + n2 + n5, 3) - 2. * Q(n3 + n4, 2) * Q(n1 + n2 + n5, 3) - Q(n1, 1) * Q(n2, 1) * Q(n4, 1) * Q(n3 + n5, 2) + Q(n1 + n2, 2) * Q(n4, 1) * Q(n3 + n5, 2) + Q(n2, 1) * Q(n1 + n4, 2) * Q(n3 + n5, 2) + Q(n1, 1) * Q(n2 + n4, 2) * Q(n3 + n5, 2) - 2. * Q(n1 + n2 + n4, 3) * Q(n3 + n5, 2) + 2. * Q(n2, 1) * Q(n4, 1) * Q(n1 + n3 + n5, 3) - 2. * Q(n2 + n4, 2) * Q(n1 + n3 + n5, 3) + 2. * Q(n1, 1) * Q(n4, 1) * Q(n2 + n3 + n5, 3) - 2. * Q(n1 + n4, 2) * Q(n2 + n3 + n5, 3) - 6. * Q(n4, 1) * Q(n1 + n2 + n3 + n5, 4) - Q(n1, 1) * Q(n2, 1) * Q(n3, 1) * Q(n4 + n5, 2) + Q(n1 + n2, 2) * Q(n3, 1) * Q(n4 + n5, 2) + Q(n2, 1) * Q(n1 + n3, 2) * Q(n4 + n5, 2) + Q(n1, 1) * Q(n2 + n3, 2) * Q(n4 + n5, 2) - 2. * Q(n1 + n2 + n3, 3) * Q(n4 + n5, 2) + 2. * Q(n2, 1) * Q(n3, 1) * Q(n1 + n4 + n5, 3) - 2. * Q(n2 + n3, 2) * Q(n1 + n4 + n5, 3) + 2. * Q(n1, 1) * Q(n3, 1) * Q(n2 + n4 + n5, 3) - 2. * Q(n1 + n3, 2) * Q(n2 + n4 + n5, 3) - 6. * Q(n3, 1) * Q(n1 + n2 + n4 + n5, 4) + 2. * Q(n1, 1) * Q(n2, 1) * Q(n3 + n4 + n5, 3) - 2. * Q(n1 + n2, 2) * Q(n3 + n4 + n5, 3) - 6. * Q(n2, 1) * Q(n1 + n3 + n4 + n5, 4) - 6. * Q(n1, 1) * Q(n2 + n3 + n4 + n5, 4) + 24. * Q(n1 + n2 + n3 + n4 + n5, 5); + + return five; + + } // TComplex Five(int n1, int n2, int n3, int n4, int n5) + + //============================================================ + + TComplex Six(int n1, int n2, int n3, int n4, int n5, int n6) + { + // Generic six-particle correlation . + + TComplex six = Q(n1, 1) * Q(n2, 1) * Q(n3, 1) * Q(n4, 1) * Q(n5, 1) * Q(n6, 1) - Q(n1 + n2, 2) * Q(n3, 1) * Q(n4, 1) * Q(n5, 1) * Q(n6, 1) - Q(n2, 1) * Q(n1 + n3, 2) * Q(n4, 1) * Q(n5, 1) * Q(n6, 1) - Q(n1, 1) * Q(n2 + n3, 2) * Q(n4, 1) * Q(n5, 1) * Q(n6, 1) + 2. * Q(n1 + n2 + n3, 3) * Q(n4, 1) * Q(n5, 1) * Q(n6, 1) - Q(n2, 1) * Q(n3, 1) * Q(n1 + n4, 2) * Q(n5, 1) * Q(n6, 1) + Q(n2 + n3, 2) * Q(n1 + n4, 2) * Q(n5, 1) * Q(n6, 1) - Q(n1, 1) * Q(n3, 1) * Q(n2 + n4, 2) * Q(n5, 1) * Q(n6, 1) + Q(n1 + n3, 2) * Q(n2 + n4, 2) * Q(n5, 1) * Q(n6, 1) + 2. * Q(n3, 1) * Q(n1 + n2 + n4, 3) * Q(n5, 1) * Q(n6, 1) - Q(n1, 1) * Q(n2, 1) * Q(n3 + n4, 2) * Q(n5, 1) * Q(n6, 1) + Q(n1 + n2, 2) * Q(n3 + n4, 2) * Q(n5, 1) * Q(n6, 1) + 2. * Q(n2, 1) * Q(n1 + n3 + n4, 3) * Q(n5, 1) * Q(n6, 1) + 2. * Q(n1, 1) * Q(n2 + n3 + n4, 3) * Q(n5, 1) * Q(n6, 1) - 6. * Q(n1 + n2 + n3 + n4, 4) * Q(n5, 1) * Q(n6, 1) - Q(n2, 1) * Q(n3, 1) * Q(n4, 1) * Q(n1 + n5, 2) * Q(n6, 1) + Q(n2 + n3, 2) * Q(n4, 1) * Q(n1 + n5, 2) * Q(n6, 1) + Q(n3, 1) * Q(n2 + n4, 2) * Q(n1 + n5, 2) * Q(n6, 1) + Q(n2, 1) * Q(n3 + n4, 2) * Q(n1 + n5, 2) * Q(n6, 1) - 2. * Q(n2 + n3 + n4, 3) * Q(n1 + n5, 2) * Q(n6, 1) - Q(n1, 1) * Q(n3, 1) * Q(n4, 1) * Q(n2 + n5, 2) * Q(n6, 1) + Q(n1 + n3, 2) * Q(n4, 1) * Q(n2 + n5, 2) * Q(n6, 1) + Q(n3, 1) * Q(n1 + n4, 2) * Q(n2 + n5, 2) * Q(n6, 1) + Q(n1, 1) * Q(n3 + n4, 2) * Q(n2 + n5, 2) * Q(n6, 1) - 2. * Q(n1 + n3 + n4, 3) * Q(n2 + n5, 2) * Q(n6, 1) + 2. * Q(n3, 1) * Q(n4, 1) * Q(n1 + n2 + n5, 3) * Q(n6, 1) - 2. * Q(n3 + n4, 2) * Q(n1 + n2 + n5, 3) * Q(n6, 1) - Q(n1, 1) * Q(n2, 1) * Q(n4, 1) * Q(n3 + n5, 2) * Q(n6, 1) + Q(n1 + n2, 2) * Q(n4, 1) * Q(n3 + n5, 2) * Q(n6, 1) + Q(n2, 1) * Q(n1 + n4, 2) * Q(n3 + n5, 2) * Q(n6, 1) + Q(n1, 1) * Q(n2 + n4, 2) * Q(n3 + n5, 2) * Q(n6, 1) - 2. * Q(n1 + n2 + n4, 3) * Q(n3 + n5, 2) * Q(n6, 1) + 2. * Q(n2, 1) * Q(n4, 1) * Q(n1 + n3 + n5, 3) * Q(n6, 1) - 2. * Q(n2 + n4, 2) * Q(n1 + n3 + n5, 3) * Q(n6, 1) + 2. * Q(n1, 1) * Q(n4, 1) * Q(n2 + n3 + n5, 3) * Q(n6, 1) - 2. * Q(n1 + n4, 2) * Q(n2 + n3 + n5, 3) * Q(n6, 1) - 6. * Q(n4, 1) * Q(n1 + n2 + n3 + n5, 4) * Q(n6, 1) - Q(n1, 1) * Q(n2, 1) * Q(n3, 1) * Q(n4 + n5, 2) * Q(n6, 1) + Q(n1 + n2, 2) * Q(n3, 1) * Q(n4 + n5, 2) * Q(n6, 1) + Q(n2, 1) * Q(n1 + n3, 2) * Q(n4 + n5, 2) * Q(n6, 1) + Q(n1, 1) * Q(n2 + n3, 2) * Q(n4 + n5, 2) * Q(n6, 1) - 2. * Q(n1 + n2 + n3, 3) * Q(n4 + n5, 2) * Q(n6, 1) + 2. * Q(n2, 1) * Q(n3, 1) * Q(n1 + n4 + n5, 3) * Q(n6, 1) - 2. * Q(n2 + n3, 2) * Q(n1 + n4 + n5, 3) * Q(n6, 1) + 2. * Q(n1, 1) * Q(n3, 1) * Q(n2 + n4 + n5, 3) * Q(n6, 1) - 2. * Q(n1 + n3, 2) * Q(n2 + n4 + n5, 3) * Q(n6, 1) - 6. * Q(n3, 1) * Q(n1 + n2 + n4 + n5, 4) * Q(n6, 1) + 2. * Q(n1, 1) * Q(n2, 1) * Q(n3 + n4 + n5, 3) * Q(n6, 1) - 2. * Q(n1 + n2, 2) * Q(n3 + n4 + n5, 3) * Q(n6, 1) - 6. * Q(n2, 1) * Q(n1 + n3 + n4 + n5, 4) * Q(n6, 1) - 6. * Q(n1, 1) * Q(n2 + n3 + n4 + n5, 4) * Q(n6, 1) + 24. * Q(n1 + n2 + n3 + n4 + n5, 5) * Q(n6, 1) - Q(n2, 1) * Q(n3, 1) * Q(n4, 1) * Q(n5, 1) * Q(n1 + n6, 2) + Q(n2 + n3, 2) * Q(n4, 1) * Q(n5, 1) * Q(n1 + n6, 2) + Q(n3, 1) * Q(n2 + n4, 2) * Q(n5, 1) * Q(n1 + n6, 2) + Q(n2, 1) * Q(n3 + n4, 2) * Q(n5, 1) * Q(n1 + n6, 2) - 2. * Q(n2 + n3 + n4, 3) * Q(n5, 1) * Q(n1 + n6, 2) + Q(n3, 1) * Q(n4, 1) * Q(n2 + n5, 2) * Q(n1 + n6, 2) - Q(n3 + n4, 2) * Q(n2 + n5, 2) * Q(n1 + n6, 2) + Q(n2, 1) * Q(n4, 1) * Q(n3 + n5, 2) * Q(n1 + n6, 2) - Q(n2 + n4, 2) * Q(n3 + n5, 2) * Q(n1 + n6, 2) - 2. * Q(n4, 1) * Q(n2 + n3 + n5, 3) * Q(n1 + n6, 2) + Q(n2, 1) * Q(n3, 1) * Q(n4 + n5, 2) * Q(n1 + n6, 2) - Q(n2 + n3, 2) * Q(n4 + n5, 2) * Q(n1 + n6, 2) - 2. * Q(n3, 1) * Q(n2 + n4 + n5, 3) * Q(n1 + n6, 2) - 2. * Q(n2, 1) * Q(n3 + n4 + n5, 3) * Q(n1 + n6, 2) + 6. * Q(n2 + n3 + n4 + n5, 4) * Q(n1 + n6, 2) - Q(n1, 1) * Q(n3, 1) * Q(n4, 1) * Q(n5, 1) * Q(n2 + n6, 2) + Q(n1 + n3, 2) * Q(n4, 1) * Q(n5, 1) * Q(n2 + n6, 2) + Q(n3, 1) * Q(n1 + n4, 2) * Q(n5, 1) * Q(n2 + n6, 2) + Q(n1, 1) * Q(n3 + n4, 2) * Q(n5, 1) * Q(n2 + n6, 2) - 2. * Q(n1 + n3 + n4, 3) * Q(n5, 1) * Q(n2 + n6, 2) + Q(n3, 1) * Q(n4, 1) * Q(n1 + n5, 2) * Q(n2 + n6, 2) - Q(n3 + n4, 2) * Q(n1 + n5, 2) * Q(n2 + n6, 2) + Q(n1, 1) * Q(n4, 1) * Q(n3 + n5, 2) * Q(n2 + n6, 2) - Q(n1 + n4, 2) * Q(n3 + n5, 2) * Q(n2 + n6, 2) - 2. * Q(n4, 1) * Q(n1 + n3 + n5, 3) * Q(n2 + n6, 2) + Q(n1, 1) * Q(n3, 1) * Q(n4 + n5, 2) * Q(n2 + n6, 2) - Q(n1 + n3, 2) * Q(n4 + n5, 2) * Q(n2 + n6, 2) - 2. * Q(n3, 1) * Q(n1 + n4 + n5, 3) * Q(n2 + n6, 2) - 2. * Q(n1, 1) * Q(n3 + n4 + n5, 3) * Q(n2 + n6, 2) + 6. * Q(n1 + n3 + n4 + n5, 4) * Q(n2 + n6, 2) + 2. * Q(n3, 1) * Q(n4, 1) * Q(n5, 1) * Q(n1 + n2 + n6, 3) - 2. * Q(n3 + n4, 2) * Q(n5, 1) * Q(n1 + n2 + n6, 3) - 2. * Q(n4, 1) * Q(n3 + n5, 2) * Q(n1 + n2 + n6, 3) - 2. * Q(n3, 1) * Q(n4 + n5, 2) * Q(n1 + n2 + n6, 3) + 4. * Q(n3 + n4 + n5, 3) * Q(n1 + n2 + n6, 3) - Q(n1, 1) * Q(n2, 1) * Q(n4, 1) * Q(n5, 1) * Q(n3 + n6, 2) + Q(n1 + n2, 2) * Q(n4, 1) * Q(n5, 1) * Q(n3 + n6, 2) + Q(n2, 1) * Q(n1 + n4, 2) * Q(n5, 1) * Q(n3 + n6, 2) + Q(n1, 1) * Q(n2 + n4, 2) * Q(n5, 1) * Q(n3 + n6, 2) - 2. * Q(n1 + n2 + n4, 3) * Q(n5, 1) * Q(n3 + n6, 2) + Q(n2, 1) * Q(n4, 1) * Q(n1 + n5, 2) * Q(n3 + n6, 2) - Q(n2 + n4, 2) * Q(n1 + n5, 2) * Q(n3 + n6, 2) + Q(n1, 1) * Q(n4, 1) * Q(n2 + n5, 2) * Q(n3 + n6, 2) - Q(n1 + n4, 2) * Q(n2 + n5, 2) * Q(n3 + n6, 2) - 2. * Q(n4, 1) * Q(n1 + n2 + n5, 3) * Q(n3 + n6, 2) + Q(n1, 1) * Q(n2, 1) * Q(n4 + n5, 2) * Q(n3 + n6, 2) - Q(n1 + n2, 2) * Q(n4 + n5, 2) * Q(n3 + n6, 2) - 2. * Q(n2, 1) * Q(n1 + n4 + n5, 3) * Q(n3 + n6, 2) - 2. * Q(n1, 1) * Q(n2 + n4 + n5, 3) * Q(n3 + n6, 2) + 6. * Q(n1 + n2 + n4 + n5, 4) * Q(n3 + n6, 2) + 2. * Q(n2, 1) * Q(n4, 1) * Q(n5, 1) * Q(n1 + n3 + n6, 3) - 2. * Q(n2 + n4, 2) * Q(n5, 1) * Q(n1 + n3 + n6, 3) - 2. * Q(n4, 1) * Q(n2 + n5, 2) * Q(n1 + n3 + n6, 3) - 2. * Q(n2, 1) * Q(n4 + n5, 2) * Q(n1 + n3 + n6, 3) + 4. * Q(n2 + n4 + n5, 3) * Q(n1 + n3 + n6, 3) + 2. * Q(n1, 1) * Q(n4, 1) * Q(n5, 1) * Q(n2 + n3 + n6, 3) - 2. * Q(n1 + n4, 2) * Q(n5, 1) * Q(n2 + n3 + n6, 3) - 2. * Q(n4, 1) * Q(n1 + n5, 2) * Q(n2 + n3 + n6, 3) - 2. * Q(n1, 1) * Q(n4 + n5, 2) * Q(n2 + n3 + n6, 3) + 4. * Q(n1 + n4 + n5, 3) * Q(n2 + n3 + n6, 3) - 6. * Q(n4, 1) * Q(n5, 1) * Q(n1 + n2 + n3 + n6, 4) + 6. * Q(n4 + n5, 2) * Q(n1 + n2 + n3 + n6, 4) - Q(n1, 1) * Q(n2, 1) * Q(n3, 1) * Q(n5, 1) * Q(n4 + n6, 2) + Q(n1 + n2, 2) * Q(n3, 1) * Q(n5, 1) * Q(n4 + n6, 2) + Q(n2, 1) * Q(n1 + n3, 2) * Q(n5, 1) * Q(n4 + n6, 2) + Q(n1, 1) * Q(n2 + n3, 2) * Q(n5, 1) * Q(n4 + n6, 2) - 2. * Q(n1 + n2 + n3, 3) * Q(n5, 1) * Q(n4 + n6, 2) + Q(n2, 1) * Q(n3, 1) * Q(n1 + n5, 2) * Q(n4 + n6, 2) - Q(n2 + n3, 2) * Q(n1 + n5, 2) * Q(n4 + n6, 2) + Q(n1, 1) * Q(n3, 1) * Q(n2 + n5, 2) * Q(n4 + n6, 2) - Q(n1 + n3, 2) * Q(n2 + n5, 2) * Q(n4 + n6, 2) - 2. * Q(n3, 1) * Q(n1 + n2 + n5, 3) * Q(n4 + n6, 2) + Q(n1, 1) * Q(n2, 1) * Q(n3 + n5, 2) * Q(n4 + n6, 2) - Q(n1 + n2, 2) * Q(n3 + n5, 2) * Q(n4 + n6, 2) - 2. * Q(n2, 1) * Q(n1 + n3 + n5, 3) * Q(n4 + n6, 2) - 2. * Q(n1, 1) * Q(n2 + n3 + n5, 3) * Q(n4 + n6, 2) + 6. * Q(n1 + n2 + n3 + n5, 4) * Q(n4 + n6, 2) + 2. * Q(n2, 1) * Q(n3, 1) * Q(n5, 1) * Q(n1 + n4 + n6, 3) - 2. * Q(n2 + n3, 2) * Q(n5, 1) * Q(n1 + n4 + n6, 3) - 2. * Q(n3, 1) * Q(n2 + n5, 2) * Q(n1 + n4 + n6, 3) - 2. * Q(n2, 1) * Q(n3 + n5, 2) * Q(n1 + n4 + n6, 3) + 4. * Q(n2 + n3 + n5, 3) * Q(n1 + n4 + n6, 3) + 2. * Q(n1, 1) * Q(n3, 1) * Q(n5, 1) * Q(n2 + n4 + n6, 3) - 2. * Q(n1 + n3, 2) * Q(n5, 1) * Q(n2 + n4 + n6, 3) - 2. * Q(n3, 1) * Q(n1 + n5, 2) * Q(n2 + n4 + n6, 3) - 2. * Q(n1, 1) * Q(n3 + n5, 2) * Q(n2 + n4 + n6, 3) + 4. * Q(n1 + n3 + n5, 3) * Q(n2 + n4 + n6, 3) - 6. * Q(n3, 1) * Q(n5, 1) * Q(n1 + n2 + n4 + n6, 4) + 6. * Q(n3 + n5, 2) * Q(n1 + n2 + n4 + n6, 4) + 2. * Q(n1, 1) * Q(n2, 1) * Q(n5, 1) * Q(n3 + n4 + n6, 3) - 2. * Q(n1 + n2, 2) * Q(n5, 1) * Q(n3 + n4 + n6, 3) - 2. * Q(n2, 1) * Q(n1 + n5, 2) * Q(n3 + n4 + n6, 3) - 2. * Q(n1, 1) * Q(n2 + n5, 2) * Q(n3 + n4 + n6, 3) + 4. * Q(n1 + n2 + n5, 3) * Q(n3 + n4 + n6, 3) - 6. * Q(n2, 1) * Q(n5, 1) * Q(n1 + n3 + n4 + n6, 4) + 6. * Q(n2 + n5, 2) * Q(n1 + n3 + n4 + n6, 4) - 6. * Q(n1, 1) * Q(n5, 1) * Q(n2 + n3 + n4 + n6, 4) + 6. * Q(n1 + n5, 2) * Q(n2 + n3 + n4 + n6, 4) + 24. * Q(n5, 1) * Q(n1 + n2 + n3 + n4 + n6, 5) - Q(n1, 1) * Q(n2, 1) * Q(n3, 1) * Q(n4, 1) * Q(n5 + n6, 2) + Q(n1 + n2, 2) * Q(n3, 1) * Q(n4, 1) * Q(n5 + n6, 2) + Q(n2, 1) * Q(n1 + n3, 2) * Q(n4, 1) * Q(n5 + n6, 2) + Q(n1, 1) * Q(n2 + n3, 2) * Q(n4, 1) * Q(n5 + n6, 2) - 2. * Q(n1 + n2 + n3, 3) * Q(n4, 1) * Q(n5 + n6, 2) + Q(n2, 1) * Q(n3, 1) * Q(n1 + n4, 2) * Q(n5 + n6, 2) - Q(n2 + n3, 2) * Q(n1 + n4, 2) * Q(n5 + n6, 2) + Q(n1, 1) * Q(n3, 1) * Q(n2 + n4, 2) * Q(n5 + n6, 2) - Q(n1 + n3, 2) * Q(n2 + n4, 2) * Q(n5 + n6, 2) - 2. * Q(n3, 1) * Q(n1 + n2 + n4, 3) * Q(n5 + n6, 2) + Q(n1, 1) * Q(n2, 1) * Q(n3 + n4, 2) * Q(n5 + n6, 2) - Q(n1 + n2, 2) * Q(n3 + n4, 2) * Q(n5 + n6, 2) - 2. * Q(n2, 1) * Q(n1 + n3 + n4, 3) * Q(n5 + n6, 2) - 2. * Q(n1, 1) * Q(n2 + n3 + n4, 3) * Q(n5 + n6, 2) + 6. * Q(n1 + n2 + n3 + n4, 4) * Q(n5 + n6, 2) + 2. * Q(n2, 1) * Q(n3, 1) * Q(n4, 1) * Q(n1 + n5 + n6, 3) - 2. * Q(n2 + n3, 2) * Q(n4, 1) * Q(n1 + n5 + n6, 3) - 2. * Q(n3, 1) * Q(n2 + n4, 2) * Q(n1 + n5 + n6, 3) - 2. * Q(n2, 1) * Q(n3 + n4, 2) * Q(n1 + n5 + n6, 3) + 4. * Q(n2 + n3 + n4, 3) * Q(n1 + n5 + n6, 3) + 2. * Q(n1, 1) * Q(n3, 1) * Q(n4, 1) * Q(n2 + n5 + n6, 3) - 2. * Q(n1 + n3, 2) * Q(n4, 1) * Q(n2 + n5 + n6, 3) - 2. * Q(n3, 1) * Q(n1 + n4, 2) * Q(n2 + n5 + n6, 3) - 2. * Q(n1, 1) * Q(n3 + n4, 2) * Q(n2 + n5 + n6, 3) + 4. * Q(n1 + n3 + n4, 3) * Q(n2 + n5 + n6, 3) - 6. * Q(n3, 1) * Q(n4, 1) * Q(n1 + n2 + n5 + n6, 4) + 6. * Q(n3 + n4, 2) * Q(n1 + n2 + n5 + n6, 4) + 2. * Q(n1, 1) * Q(n2, 1) * Q(n4, 1) * Q(n3 + n5 + n6, 3) - 2. * Q(n1 + n2, 2) * Q(n4, 1) * Q(n3 + n5 + n6, 3) - 2. * Q(n2, 1) * Q(n1 + n4, 2) * Q(n3 + n5 + n6, 3) - 2. * Q(n1, 1) * Q(n2 + n4, 2) * Q(n3 + n5 + n6, 3) + 4. * Q(n1 + n2 + n4, 3) * Q(n3 + n5 + n6, 3) - 6. * Q(n2, 1) * Q(n4, 1) * Q(n1 + n3 + n5 + n6, 4) + 6. * Q(n2 + n4, 2) * Q(n1 + n3 + n5 + n6, 4) - 6. * Q(n1, 1) * Q(n4, 1) * Q(n2 + n3 + n5 + n6, 4) + 6. * Q(n1 + n4, 2) * Q(n2 + n3 + n5 + n6, 4) + 24. * Q(n4, 1) * Q(n1 + n2 + n3 + n5 + n6, 5) + 2. * Q(n1, 1) * Q(n2, 1) * Q(n3, 1) * Q(n4 + n5 + n6, 3) - 2. * Q(n1 + n2, 2) * Q(n3, 1) * Q(n4 + n5 + n6, 3) - 2. * Q(n2, 1) * Q(n1 + n3, 2) * Q(n4 + n5 + n6, 3) - 2. * Q(n1, 1) * Q(n2 + n3, 2) * Q(n4 + n5 + n6, 3) + 4. * Q(n1 + n2 + n3, 3) * Q(n4 + n5 + n6, 3) - 6. * Q(n2, 1) * Q(n3, 1) * Q(n1 + n4 + n5 + n6, 4) + 6. * Q(n2 + n3, 2) * Q(n1 + n4 + n5 + n6, 4) - 6. * Q(n1, 1) * Q(n3, 1) * Q(n2 + n4 + n5 + n6, 4) + 6. * Q(n1 + n3, 2) * Q(n2 + n4 + n5 + n6, 4) + 24. * Q(n3, 1) * Q(n1 + n2 + n4 + n5 + n6, 5) - 6. * Q(n1, 1) * Q(n2, 1) * Q(n3 + n4 + n5 + n6, 4) + 6. * Q(n1 + n2, 2) * Q(n3 + n4 + n5 + n6, 4) + 24. * Q(n2, 1) * Q(n1 + n3 + n4 + n5 + n6, 5) + 24. * Q(n1, 1) * Q(n2 + n3 + n4 + n5 + n6, 5) - 120. * Q(n1 + n2 + n3 + n4 + n5 + n6, 6); + + return six; + + } // TComplex Six(int n1, int n2, int n3, int n4, int n5, int n6) + + //============================================================ + + TComplex Seven(int n1, int n2, int n3, int n4, int n5, int n6, int n7) + { + // Generic seven-particle correlation . + + int harmonic[7] = {n1, n2, n3, n4, n5, n6, n7}; + + TComplex seven = Recursion(7, harmonic); + + return seven; + + } // end of TComplex Seven(int n1, int n2, int n3, int n4, int n5, int n6, int n7) + + //============================================================ + + TComplex Eight(int n1, int n2, int n3, int n4, int n5, int n6, int n7, int n8) + { + // Generic eight-particle correlation . + + int harmonic[8] = {n1, n2, n3, n4, n5, n6, n7, n8}; + + TComplex eight = Recursion(8, harmonic); + + return eight; + + } // end of Eight(int n1, int n2, int n3, int n4, int n5, int n6, int n7, int n8) + + //============================================================ + + TComplex Nine(int n1, int n2, int n3, int n4, int n5, int n6, int n7, int n8, int n9) + { + // Generic nine-particle correlation . + + int harmonic[9] = {n1, n2, n3, n4, n5, n6, n7, n8, n9}; + + TComplex nine = Recursion(9, harmonic); + + return nine; + + } // end of TComplex Nine(int n1, int n2, int n3, int n4, int n5, int n6, int n7, int n8, int n9) + + //============================================================ + + TComplex Ten(int n1, int n2, int n3, int n4, int n5, int n6, int n7, int n8, int n9, int n10) + { + // Generic ten-particle correlation . + + int harmonic[10] = {n1, n2, n3, n4, n5, n6, n7, n8, n9, n10}; + + TComplex ten = Recursion(10, harmonic); + + return ten; + + } // end of TComplex Ten(int n1, int n2, int n3, int n4, int n5, int n6, int n7, int n8, int n9, int n10) + + //============================================================ + + TComplex Eleven(int n1, int n2, int n3, int n4, int n5, int n6, int n7, int n8, int n9, int n10, int n11) + { + // Generic eleven-particle correlation . + + int harmonic[11] = {n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11}; + + TComplex eleven = Recursion(11, harmonic); + + return eleven; + + } // end of TComplex Eleven(int n1, int n2, int n3, int n4, int n5, int n6, int n7, int n8, int n9, int n10, int n11) + + //============================================================ + + TComplex Twelve(int n1, int n2, int n3, int n4, int n5, int n6, int n7, int n8, int n9, int n10, int n11, int n12) + { + // Generic twelve-particle correlation . + + int harmonic[12] = {n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12}; + + TComplex twelve = Recursion(12, harmonic); + + return twelve; + + } // end of TComplex Twelve(int n1, int n2, int n3, int n4, int n5, int n6, int n7, int n8, int n9, int n10, int n11, int n12) + + //============================================================ + + TComplex Recursion(int n, int* harmonic, int mult = 1, int skip = 0) + { + // Calculate multi-particle correlators by using recursion (an improved faster version) originally developed by + // Kristjan Gulbrandsen (gulbrand@nbi.dk). + + int nm1 = n - 1; + TComplex c(Q(harmonic[nm1], mult)); + if (nm1 == 0) + return c; + c *= Recursion(nm1, harmonic); + if (nm1 == skip) + return c; + + int multp1 = mult + 1; + int nm2 = n - 2; + int counter1 = 0; + int hhold = harmonic[counter1]; + harmonic[counter1] = harmonic[nm2]; + harmonic[nm2] = hhold + harmonic[nm1]; + TComplex c2(Recursion(nm1, harmonic, multp1, nm2)); + int counter2 = n - 3; + while (counter2 >= skip) { + harmonic[nm2] = harmonic[counter1]; + harmonic[counter1] = hhold; + ++counter1; + hhold = harmonic[counter1]; + harmonic[counter1] = harmonic[nm2]; + harmonic[nm2] = hhold + harmonic[nm1]; + c2 += Recursion(nm1, harmonic, multp1, counter2); + --counter2; + } + harmonic[nm2] = harmonic[counter1]; + harmonic[counter1] = hhold; + + if (mult == 1) + return c - c2; + return c - static_cast(mult) * c2; + + } // TComplex Recursion(int n, int* harmonic, int mult = 1, int skip = 0) + + //============================================================ + + void ResetQ() + { + // Reset the components of generic Q-vectors. Use it whenever you call the + // standard functions for correlations, for some custom Q-vectors. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + for (int h = 0; h < gMaxHarmonic * gMaxCorrelator + 1; h++) { + for (int wp = 0; wp < gMaxCorrelator + 1; wp++) // weight power + { + qv.fQ[h][wp] = TComplex(0., 0.); + } + } + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // void ResetQ() + + //============================================================ + + void SetWeightsHist(TH1D* const hist, eWeights whichWeight) + { + // Copy histogram holding weights from an external file to the corresponding data member. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // Finally: + hist->SetDirectory(0); + pw.fWeightsHist[whichWeight] = reinterpret_cast(hist); + + if (!pw.fWeightsHist[whichWeight]) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + + // Cosmetics: TBI 20240216 do I really want to overwrite initial cosmetics, perhaps this shall go better into MakeWeights.C ? + // Or I could move all this to GetHistogramWithWeights, where in any case I am setting e.g. histogram title, etc. + TString sVariable[eWeights_N] = {"#varphi", "p_{t}", "#eta"}; // [phi,pt,eta] + TString sWeights[eWeights_N] = {"w_{#varphi}", "w_{p_{t}}", "w_{#eta}"}; + pw.fWeightsHist[whichWeight]->SetStats(false); + pw.fWeightsHist[whichWeight]->GetXaxis()->SetTitle(sVariable[whichWeight].Data()); + pw.fWeightsHist[whichWeight]->GetYaxis()->SetTitle(sWeights[whichWeight].Data()); + pw.fWeightsHist[whichWeight]->SetFillColor(eFillColor); + pw.fWeightsHist[whichWeight]->SetLineColor(eColor); + if (!pw.fWeightsList) { + LOGF(fatal, "\033[1;31m%s at line %d: fWeightsList is NULL. That means that you have called SetWeightsHist(...) in init(), before this TList was booked.\033[0m", __FUNCTION__, __LINE__); + } + pw.fWeightsList->Add(pw.fWeightsHist[whichWeight]); // This is working at the moment, because I am fetching all weights in Preprocess(), which is called after init() + // But if eventually it will be possible to fetch run number programatically in init(), I will have to re-think this line. + + // Flag: + pw.fUseWeights[whichWeight] = true; + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // void SetWeightsHist(TH1D* const hist, eWeights whichWeight) + + //============================================================ + + void SetDiffWeightsHist(TH1D* const hist, eDiffWeights whichDiffWeight, int bin) + { + // Copy histogram holding differential weights from an external file to the corresponding data member. + + // Remark: Do not edit histogram title here, because that's done in GetHistogramWithWeights(), because I have "filePath" info there locally. + // Only if I promote "filePath" to data members, re-think the design of this function, and what goes where. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // Finally: + hist->SetDirectory(0); + pw.fDiffWeightsHist[whichDiffWeight][bin] = reinterpret_cast(hist); + + if (!pw.fDiffWeightsHist[whichDiffWeight][bin]) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + + // Cosmetics: TBI 20240216 do I really want to overwrite initial cosmetics, perhaps this shall go better into MakeWeights.C ? + // Or I could move all this to GetHistogramWithWeights, where in any case I am setting e.g. histogram title, etc. + TString sVariable[eDiffWeights_N] = {"#varphi", "#varphi"}; // yes, for the time being, x-axis is always phi + TString sWeights[eDiffWeights_N] = {"(w_{#varphi})_{| p_{T}}", "(w_{#varphi})_{| #eta}"}; + pw.fDiffWeightsHist[whichDiffWeight][bin]->SetStats(false); + pw.fDiffWeightsHist[whichDiffWeight][bin]->GetXaxis()->SetTitle(sVariable[whichDiffWeight].Data()); + pw.fDiffWeightsHist[whichDiffWeight][bin]->GetYaxis()->SetTitle(sWeights[whichDiffWeight].Data()); + pw.fDiffWeightsHist[whichDiffWeight][bin]->SetFillColor(eFillColor); + pw.fDiffWeightsHist[whichDiffWeight][bin]->SetLineColor(eColor); + pw.fWeightsList->Add(pw.fDiffWeightsHist[whichDiffWeight][bin]); // This is working at the moment, because I am fetching all weights in Preprocess(), which is called after init() + // But if eventually it will be possible to fetch run number programatically in init(), I will have to re-think this line. + + // Flag: + if (!pw.fUseDiffWeights[whichDiffWeight]) // yes, set it only once to true, for all bins + { + pw.fUseDiffWeights[whichDiffWeight] = true; + } + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // SetDiffWeightsHist(TH1D* const hist, const char *variable, int bin) + + //============================================================ + + void SetDiffWeightsSparse(THnSparseF* const sparse, eDiffWeightCategory dwc) + { + // Copy sparse histogram holding differential phi, pt, eta, etc., weights from an external file to the corresponding data member. + + // Remark: Do not edit sparse histogram title here, because that's done in GetHistogramWithWeights(), because I have "filePath" info there locally. + // Only if I promote "filePath" to data members, re-think the design of this function, and what goes where. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // Finally: + // sparse->SetDirectory(0); I cannot use this for sparse + pw.fDiffWeightsSparse[dwc] = reinterpret_cast(sparse); // TBI 20250702 why I am casting here in fact, 'sparse' is already THnSparseF... + + if (!pw.fDiffWeightsSparse[dwc]) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + + // Within current analysis the dimension of weight for each category won't change, therefore I store it permanently: + pw.fDWdimension[dwc] = pw.fDiffWeightsSparse[dwc]->GetNdimensions(); + + // I book here immediately vectors needed to fetch the weight from the right bin of THnSparse: + pw.fFindBinVector[dwc] = new TArrayD(pw.fDWdimension[dwc]); + + // Finally, add to corresponding TList: + pw.fWeightsList->Add(pw.fDiffWeightsSparse[dwc]); + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // void SetDiffWeightsSparse(THnSparseF* const sparse, eDiffWeightCategory dwc) + + //============================================================ + + void insanitizeDiffWeightsSparse(THnSparseF* const sparse) + { + // Check if particle weights are avaiable for the phase window I have selected for each dimension with cuts. + // Basically, I check whether range of each axis in sparse histograms is compatible with the cuts i used for variable on that axis. + + // TBI 20260223 : I am doing one unnecessary extra check in each if statement below to prevent rounding problem - check this further + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + if (!sparse) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + + int nDim = sparse->GetNdimensions(); + for (int d = 0; d < nDim; d++) { + + // get title for this axis: + std::string axisTitle = sparse->GetAxis(d)->GetTitle(); + + // insanity check on the title: + if (axisTitle.empty()) { + LOGF(fatal, "\033[1;31m%s at line %d : axis %d of sparse %s has an empty title \033[0m", __FUNCTION__, __LINE__, d, sparse->GetName()); + } + + // check all supported observables: + if (!axisTitle.compare("#varphi")) { // I have to negate, becase compare() returns 0 if strings are equal + keep in sync hardwired string here with what i have in FancyFormatting(...) + + // check lower boundary: + if ((pc.fdParticleCuts[ePhi][eMin] < sparse->GetAxis(d)->GetBinLowEdge(1)) && (std::abs(sparse->GetAxis(d)->GetBinLowEdge(1) - pc.fdParticleCuts[ePhi][eMin]) > tc.fFloatingPointPrecision)) { + LOGF(fatal, "\033[1;31m%s at line %d : axis %d (#varphi) of sparse %s has lower boundary %f, while lower cut on that variable is %f. This means that for some particles I won't be able to fetch weights from this sparse. \033[0m", __FUNCTION__, __LINE__, d, sparse->GetName(), sparse->GetAxis(d)->GetBinLowEdge(1), pc.fdParticleCuts[ePhi][eMin]); + } + + // check upper boundary: + if ((pc.fdParticleCuts[ePhi][eMax] > sparse->GetAxis(d)->GetBinUpEdge(sparse->GetAxis(d)->GetNbins())) && (std::abs(sparse->GetAxis(d)->GetBinUpEdge(sparse->GetAxis(d)->GetNbins()) - pc.fdParticleCuts[ePhi][eMax]) > tc.fFloatingPointPrecision)) { + LOGF(fatal, "\033[1;31m%s at line %d : axis %d (#varphi) of sparse %s has upper boundary %f, while upper cut on that variable is %f. This means that for some particles I won't be able to fetch weights from this sparse. \033[0m", __FUNCTION__, __LINE__, d, sparse->GetName(), sparse->GetAxis(d)->GetBinUpEdge(sparse->GetAxis(d)->GetNbins()), pc.fdParticleCuts[ePhi][eMax]); + } + + } else if (!axisTitle.compare("p_{T}")) { + + // check lower boundary: + if ((pc.fdParticleCuts[ePt][eMin] < sparse->GetAxis(d)->GetBinLowEdge(1)) && (std::abs(sparse->GetAxis(d)->GetBinLowEdge(1) - pc.fdParticleCuts[ePt][eMin]) > tc.fFloatingPointPrecision)) { + LOGF(fatal, "\033[1;31m%s at line %d : axis %d (p_{T}) of sparse %s has lower boundary %f, while lower cut on that variable is %f. This means that for some particles I won't be able to fetch weights from this sparse. \033[0m", __FUNCTION__, __LINE__, d, sparse->GetName(), sparse->GetAxis(d)->GetBinLowEdge(1), pc.fdParticleCuts[ePt][eMin]); + } + + // check upper boundary: + if ((pc.fdParticleCuts[ePt][eMax] > sparse->GetAxis(d)->GetBinUpEdge(sparse->GetAxis(d)->GetNbins())) && (std::abs(sparse->GetAxis(d)->GetBinUpEdge(sparse->GetAxis(d)->GetNbins()) - pc.fdParticleCuts[ePt][eMax]) > tc.fFloatingPointPrecision)) { + LOGF(fatal, "\033[1;31m%s at line %d : axis %d (p_{T}) of sparse %s has upper boundary %f, while upper cut on that variable is %f. This means that for some particles I won't be able to fetch weights from this sparse. \033[0m", __FUNCTION__, __LINE__, d, sparse->GetName(), sparse->GetAxis(d)->GetBinUpEdge(sparse->GetAxis(d)->GetNbins()), pc.fdParticleCuts[ePt][eMax]); + } + + } else if (!axisTitle.compare("#eta")) { + + // check lower boundary: + if ((pc.fdParticleCuts[eEta][eMin] < sparse->GetAxis(d)->GetBinLowEdge(1)) && (std::abs(sparse->GetAxis(d)->GetBinLowEdge(1) - pc.fdParticleCuts[eEta][eMin]) > tc.fFloatingPointPrecision)) { + LOGF(fatal, "\033[1;31m%s at line %d : axis %d (#eta) of sparse %s has lower boundary %f, while lower cut on that variable is %f. This means that for some particles I won't be able to fetch weights from this sparse. \033[0m", __FUNCTION__, __LINE__, d, sparse->GetName(), sparse->GetAxis(d)->GetBinLowEdge(1), pc.fdParticleCuts[eEta][eMin]); + } + + // check upper boundary: + if ((pc.fdParticleCuts[eEta][eMax] > sparse->GetAxis(d)->GetBinUpEdge(sparse->GetAxis(d)->GetNbins())) && (std::abs(sparse->GetAxis(d)->GetBinUpEdge(sparse->GetAxis(d)->GetNbins()) - pc.fdParticleCuts[eEta][eMax]) > tc.fFloatingPointPrecision)) { + LOGF(fatal, "\033[1;31m%s at line %d : axis %d (#eta) of sparse %s has upper boundary %f, while upper cut on that variable is %f. This means that for some particles I won't be able to fetch weights from this sparse. \033[0m", __FUNCTION__, __LINE__, d, sparse->GetName(), sparse->GetAxis(d)->GetBinUpEdge(sparse->GetAxis(d)->GetNbins()), pc.fdParticleCuts[eEta][eMax]); + } + + } else if (!axisTitle.compare("Charge")) { + + // check lower boundary: + if ((pc.fdParticleCuts[eCharge][eMin] < sparse->GetAxis(d)->GetBinLowEdge(1)) && (std::abs(sparse->GetAxis(d)->GetBinLowEdge(1) - pc.fdParticleCuts[eCharge][eMin]) > tc.fFloatingPointPrecision)) { + LOGF(fatal, "\033[1;31m%s at line %d : axis %d (Charge) of sparse %s has lower boundary %f, while lower cut on that variable is %f. This means that for some particles I won't be able to fetch weights from this sparse. \033[0m", __FUNCTION__, __LINE__, d, sparse->GetName(), sparse->GetAxis(d)->GetBinLowEdge(1), pc.fdParticleCuts[eCharge][eMin]); + } + + // check upper boundary: + if ((pc.fdParticleCuts[eCharge][eMax] > sparse->GetAxis(d)->GetBinUpEdge(sparse->GetAxis(d)->GetNbins())) && (std::abs(sparse->GetAxis(d)->GetBinUpEdge(sparse->GetAxis(d)->GetNbins()) - pc.fdParticleCuts[eCharge][eMax]) > tc.fFloatingPointPrecision)) { + LOGF(fatal, "\033[1;31m%s at line %d : axis %d (Charge) of sparse %s has upper boundary %f, while upper cut on that variable is %f. This means that for some particles I won't be able to fetch weights from this sparse. \033[0m", __FUNCTION__, __LINE__, d, sparse->GetName(), sparse->GetAxis(d)->GetBinUpEdge(sparse->GetAxis(d)->GetNbins()), pc.fdParticleCuts[eCharge][eMax]); + } + + } else if (!axisTitle.find("Centrality")) { // I have to use here find() instead, because title also contains centrality estimator name, e.g. "Centality (FT0C)" + + // check lower boundary: + if ((ec.fdEventCuts[eCentrality][eMin] < sparse->GetAxis(d)->GetBinLowEdge(1)) && (std::abs(sparse->GetAxis(d)->GetBinLowEdge(1) - ec.fdEventCuts[eCentrality][eMin]) > tc.fFloatingPointPrecision)) { + LOGF(fatal, "\033[1;31m%s at line %d : axis %d (Centrality) of sparse %s has lower boundary %f, while lower cut on that variable is %f. This means that for some events I won't be able to fetch particle weights from this sparse. \033[0m", __FUNCTION__, __LINE__, d, sparse->GetName(), sparse->GetAxis(d)->GetBinLowEdge(1), ec.fdEventCuts[eCentrality][eMin]); + } + + // check upper boundary: + if ((ec.fdEventCuts[eCentrality][eMax] > sparse->GetAxis(d)->GetBinUpEdge(sparse->GetAxis(d)->GetNbins())) && (std::abs(sparse->GetAxis(d)->GetBinUpEdge(sparse->GetAxis(d)->GetNbins()) - ec.fdEventCuts[eCentrality][eMax]) > tc.fFloatingPointPrecision)) { + LOGF(fatal, "\033[1;31m%s at line %d : axis %d (Centrality) of sparse %s has upper boundary %f, while upper cut on that variable is %f. This means that for some events I won't be able to fetch particles weights from this sparse. \033[0m", __FUNCTION__, __LINE__, d, sparse->GetName(), sparse->GetAxis(d)->GetBinUpEdge(sparse->GetAxis(d)->GetNbins()), ec.fdEventCuts[eCentrality][eMax]); + } + + } else if (!(axisTitle.compare("V_{z}")) || !(axisTitle.compare("VertexZ"))) { // TBI 20260217 I use indeed "VertexZ" for the time being, not sure why I didn't use here also FancyFormatting. But it doesn't hurt to add check for both + + // check lower boundary: + if ((ec.fdEventCuts[eVertexZ][eMin] < sparse->GetAxis(d)->GetBinLowEdge(1)) && (std::abs(sparse->GetAxis(d)->GetBinLowEdge(1) - ec.fdEventCuts[eVertexZ][eMin]) > tc.fFloatingPointPrecision)) { + LOGF(fatal, "\033[1;31m%s at line %d : axis %d (V_{z} or VertexZ) of sparse %s has lower boundary %f, while lower cut on that variable is %f. This means that for some events I won't be able to fetch particle weights from this sparse. \033[0m", __FUNCTION__, __LINE__, d, sparse->GetName(), sparse->GetAxis(d)->GetBinLowEdge(1), ec.fdEventCuts[eVertexZ][eMin]); + } + + // check upper boundary: + if ((ec.fdEventCuts[eVertexZ][eMax] > sparse->GetAxis(d)->GetBinUpEdge(sparse->GetAxis(d)->GetNbins())) && (std::abs(sparse->GetAxis(d)->GetBinUpEdge(sparse->GetAxis(d)->GetNbins()) - ec.fdEventCuts[eVertexZ][eMax]) > tc.fFloatingPointPrecision)) { + LOGF(fatal, "\033[1;31m%s at line %d : axis %d (V_{z} or VertexZ) of sparse %s has upper boundary %f, while upper cut on that variable is %f. This means that for some events I won't be able to fetch particles weights from this sparse. \033[0m", __FUNCTION__, __LINE__, d, sparse->GetName(), sparse->GetAxis(d)->GetBinUpEdge(sparse->GetAxis(d)->GetNbins()), ec.fdEventCuts[eVertexZ][eMax]); + } + + // ... add in the same way check for any other variable + + } else { + LOGF(fatal, "\033[1;31m%s at line %d : axisTitle = %s of sparse = %s is not supported yet in this function \033[0m", __FUNCTION__, __LINE__, axisTitle.data(), sparse->GetName()); + } + + } // for(int d = 0; d < nDim; d++) { + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // void insanitizeDiffWeightsSparse(THnSparseF* const sparse) + + //============================================================ + + void SetCentralityWeightsHist(TH1D* const hist) + { + // Copy histogram holding weights from an external file to the corresponding data member. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // Finally: + hist->SetDirectory(0); + cw.fCentralityWeightsHist = reinterpret_cast(hist); + + if (!cw.fCentralityWeightsHist) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + + // Cosmetics: TBI 20240216 do I really want to overwrite initial cosmetics, perhaps this shall go better into MakeCentralityWeights.C ? + // Or I could move all this to GetHistogramWithCentralityWeights, where in any case I am setting e.g. histogram title, etc. + cw.fCentralityWeightsHist->SetStats(false); + cw.fCentralityWeightsHist->GetXaxis()->SetTitle("Centrality percentile"); + cw.fCentralityWeightsHist->GetYaxis()->SetTitle(Form("Centrality weight (%s)", ec.fsEventCuts[eCentralityEstimator].Data())); + cw.fCentralityWeightsHist->SetFillColor(eFillColor); + cw.fCentralityWeightsHist->SetLineColor(eColor); + if (!cw.fCentralityWeightsList) { + LOGF(fatal, "\033[1;31m%s at line %d: fCentralityWeightsList is NULL. That means that you have called SetCentralityWeightsHist(...) in init(), before this TList was booked.\033[0m", __FUNCTION__, __LINE__); + } + cw.fCentralityWeightsList->Add(cw.fCentralityWeightsHist); // This is working at the moment, because I am fetching all centrality weights in Preprocess(), which is called after init() + // But if eventually it will be possible to fetch run number programatically in init(), I will have to re-think this line. + + // Flag: + cw.fUseCentralityWeights = true; + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // void SetCentralityWeightsHist(TH1D* const hist) + + //============================================================ + + TH1D* GetWeightsHist(eWeights whichWeight) + { + // The standard getter. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // ... + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + // Finally: + return pw.fWeightsHist[whichWeight]; + + } // TH1D* GetWeightsHist(eWeights whichWeigh) + + //============================================================ + + TH1D* GetHistogramWithWeights(const char* filePath, const char* runNumber, const char* variable, int bin = -1) + { + // Get and return histogram with weights from an external file. + // If bin > 0, differential weights for that bin are searched for. + // If bin = -1, integrated weights are searched for, i.e. in this case "bin" variable has no effect. + // I do it this way, so as to condense GetHistogramWithWeights(...) and GetHistogramWithDiffWeights(...) from MuPa class in + // one routine here, so that I do not duplicate code related to CCDB access, etc. + + // TBI 20240504: Here I can keep const char* variable , i.e. no need to switch to enums, because this function is called only once, at init. + // Nevertheless, I could switch to enums and make it more general, i.e. I could introduce additional data members and configurables, + // for the names of histograms with weights. Like I did it in void GetHistogramWithCustomNUA(const char* filePath, eNUAPDF variable) + + // TBI 20241021 Strictly speaking, I do not need to pass here first 2 arguments, "filePath" and "runNumber", because they are initialized at call from data members. + // But since this function is called only once, it's not an important performance loss. But re-think the design here eventually. + // If I decide to promote filePath to data member, implement it as an array, to allow possibility that different catagories of weights are fetched from different external files. + + // a) Return value; + // b) Basic protection for arguments; + // c) Determine from filePath if the file in on a local machine, or in AliEn, or in CCDB; + // d) Handle the AliEn case; + // e) Handle the CCDB case; + // f) Handle the local case; + // g) The final touch on histogram with weights; + // h) Clone histogram and delete baseList (realising back the memory). + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + LOGF(info, "\033[1;33m filePath = %s\033[0m", filePath); + LOGF(info, "\033[1;33m runNumber = %s\033[0m", runNumber); + LOGF(info, "\033[1;33m variable = %s\033[0m", variable); + LOGF(info, "\033[1;33m bin = %d (if bin = -1, integrated weights are searched for)\033[0m", bin); + LOGF(info, "\033[1;33m fTaskName = %s\033[0m", tc.fTaskName.Data()); + } + + // a) Return value: + TH1D* hist = NULL; + TList* baseList = NULL; // base top-level list in the TFile, e.g. named "ccdb_object" + TList* listWithRuns = NULL; // nested list with run-wise TList's holding run-specific weights + + // b) Basic protection for arguments: + // Remark: below I do one more specific check. + if (!(TString(variable).EqualTo("phi") || TString(variable).EqualTo("pt") || TString(variable).EqualTo("eta") || + TString(variable).EqualTo("phipt") || TString(variable).EqualTo("phieta"))) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + + // c) Determine from filePath if the file in on a local machine, or in home + // dir AliEn, or in CCDB: + // Algorithm: If filePath begins with "/alice/cern.ch/" then it's in home + // dir AliEn. If filePath begins with "/alice-ccdb.cern.ch/" then it's in + // CCDB. Therefore, files in AliEn and CCDB must be specified with abs path, + // for local files both abs and relative paths are just fine. + bool bFileIsInAliEn = false; + bool bFileIsInCCDB = false; + if (TString(filePath).BeginsWith("/alice/cern.ch/")) { + bFileIsInAliEn = true; + } else { + if (TString(filePath).BeginsWith("/alice-ccdb.cern.ch/")) { + bFileIsInCCDB = true; + } // else { + } // if (TString(filePath).BeginsWith("/alice/cern.ch/")) { + + if (bFileIsInAliEn) { + // d) Handle the AliEn case: + TGrid* alien = TGrid::Connect("alien", gSystem->Getenv("USER"), "", ""); + if (!alien) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + TFile* weightsFile = TFile::Open(Form("alien://%s", filePath), "READ"); + if (!weightsFile) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + + weightsFile->GetObject( + "ccdb_object", baseList); // TBI 20231008 for simplicity, hardwired name + // of base TList is "ccdb_object" also for + // AliEn case, see if I need to change this + if (!baseList) { + // weightsFile->ls(); + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + + listWithRuns = reinterpret_cast(GetObjectFromList(baseList, runNumber)); + if (!listWithRuns) { + TString runNumberWithLeadingZeroes = "000"; + runNumberWithLeadingZeroes += runNumber; // another try, with "000" prepended to run number + listWithRuns = reinterpret_cast(GetObjectFromList(baseList, runNumberWithLeadingZeroes.Data())); + if (!listWithRuns) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + } + + } else if (bFileIsInCCDB) { + + // e) Handle the CCDB case: Remember that here I do not access the file, + // instead directly object in that file. + // My home dir in CCDB: https://alice-ccdb.cern.ch/browse/Users/a/abilandz/ + // Inspired by: + // 1. Discussion at: + // https://alice-talk.web.cern.ch/t/access-to-lhc-filling-scheme/1073/17 + // 2. See also: + // https://github.com/AliceO2Group/O2Physics/blob/master/Tutorials/src/efficiencyGlobal.cxx + // https://github.com/AliceO2Group/O2Physics/blob/master/Tutorials/src/efficiencyPerRun.cxx + // 3. O2 Analysis Tutorial 2.0: + // https://indico.cern.ch/event/1267433/timetable/#20230417.detailed + + ccdb->setURL("http://alice-ccdb.cern.ch"); + if (tc.fVerbose) { + LOGF(info, "\033[1;32mAccessing in CCDB %s\033[0m", TString(filePath).ReplaceAll("/alice-ccdb.cern.ch/", "").Data()); + } + + baseList = reinterpret_cast(ccdb->get(TString(filePath).ReplaceAll("/alice-ccdb.cern.ch/", "").Data())); + + if (!baseList) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + + listWithRuns = reinterpret_cast(GetObjectFromList(baseList, runNumber)); + if (!listWithRuns) { + TString runNumberWithLeadingZeroes = "000"; + runNumberWithLeadingZeroes += runNumber; // another try, with "000" prepended to run number + listWithRuns = reinterpret_cast(GetObjectFromList(baseList, runNumberWithLeadingZeroes.Data())); + if (!listWithRuns) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + } + + } else { + + // f) Handle the local case: + // TBI 20231008 In principle, also for the local case in O2, I could + // maintain the same local structure of weights as it was in AliPhysics. + // But for simplicity, in O2 I organize local weights in the + // same way as in AliEn or CCDB. + + // Check if the external ROOT file exists at specified path: + if (gSystem->AccessPathName(filePath, kFileExists)) { + LOGF(info, "\033[1;33m if(gSystem->AccessPathName(filePath,kFileExists)), filePath = %s \033[0m", filePath); + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + + TFile* weightsFile = TFile::Open(filePath, "READ"); + if (!weightsFile) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + + weightsFile->GetObject("ccdb_object", baseList); // TBI 20231008 for simplicity, hardwired name + // of base TList is "ccdb_object" also for + // local case, see if I need to change this + if (!baseList) { + // weightsFile->ls(); + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + + listWithRuns = reinterpret_cast(GetObjectFromList(baseList, runNumber)); + if (!listWithRuns) { + TString runNumberWithLeadingZeroes = "000"; + runNumberWithLeadingZeroes += runNumber; // another try, with "000" prepended to run number + listWithRuns = reinterpret_cast(GetObjectFromList(baseList, runNumberWithLeadingZeroes.Data())); + if (!listWithRuns) { + // baseList->ls(); + LOGF(fatal, "\033[1;31m%s at line %d : this crash can happen if in the output file there is no list with weights for the current run number = %s\033[0m", __FUNCTION__, __LINE__, tc.fRunNumber.Data()); + } + } + + } // else { + + // g) The final touch on histogram with weights: + TString histName = ""; + if (-1 == bin) { + // Integrated weights: + if (!(TString(variable).EqualTo("phi") || TString(variable).EqualTo("pt") || TString(variable).EqualTo("eta"))) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + + // fetch histogram directly from this list: + histName = TString::Format("%s_%s", variable, tc.fTaskName.Data()); + LOGF(info, "\033[1;33m%s at line %d : fetching directly hist with name = %s\033[0m", __FUNCTION__, __LINE__, histName.Data()); + hist = reinterpret_cast(listWithRuns->FindObject(histName.Data())); + // if the previous search failed, descend recursively also into the nested lists: + if (!hist) { + LOGF(info, "\033[1;33m%s at line %d : previous attempt failed, fetching instead recursively hist with name = %s\033[0m", __FUNCTION__, __LINE__, histName.Data()); + hist = reinterpret_cast(GetObjectFromList(listWithRuns, histName.Data())); + } + if (!hist) { + histName = TString::Format("%s", variable); // yes, for some simple tests I can have only histogram named e.g. 'phi' + LOGF(info, "\033[1;33m%s at line %d : last attempt, fetching instead hist with trivial name = %s\033[0m", __FUNCTION__, __LINE__, histName.Data()); + hist = reinterpret_cast(GetObjectFromList(listWithRuns, histName.Data())); + } + if (!hist) { + listWithRuns->ls(); + LOGF(fatal, "\033[1;31m%s at line %d : couldn't fetch hist with name = %s\033[0m", __FUNCTION__, __LINE__, histName.Data()); + } + hist->SetDirectory(0); + hist->SetTitle(Form("%s, %s", filePath, runNumber)); // I have to do it here, because only here I have "filePath" av + + } else { + // Differential weights: + if (!(TString(variable).EqualTo("phipt") || TString(variable).EqualTo("phieta"))) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + // fetch histogram directly from this list: + histName = TString::Format("%s[%d]_%s", variable, bin, tc.fTaskName.Data()); + LOGF(info, "\033[1;33m%s at line %d : fetching directly hist with name = %s\033[0m", __FUNCTION__, __LINE__, histName.Data()); + hist = reinterpret_cast(listWithRuns->FindObject(histName.Data())); + // if the previous search failed, descend recursively also into the nested lists: + if (!hist) { + LOGF(info, "\033[1;33m%s at line %d : previous attempt failed, fetching instead recursively hist with name = %s\033[0m", __FUNCTION__, __LINE__, histName.Data()); + hist = reinterpret_cast(GetObjectFromList(listWithRuns, Form("%s[%d]_%s", variable, bin, tc.fTaskName.Data()))); + } + if (!hist) { + histName = TString::Format("%s[%d]", variable, bin); // yes, for some simple tests I can have only histogram named e.g. 'phipt[0]' + LOGF(info, "\033[1;33m%s at line %d : last attempt, fetching instead hist with trivial name = %s\033[0m", __FUNCTION__, __LINE__, histName.Data()); + hist = reinterpret_cast(GetObjectFromList(listWithRuns, histName.Data())); + } + if (!hist) { + listWithRuns->ls(); + LOGF(fatal, "\033[1;31m%s at line %d : couldn't fetch hist with name = %s\033[0m", __FUNCTION__, __LINE__, histName.Data()); + } + + // *) insanity check for differential weights => check if boundaries of current bin are the same as bin boundaries for which these weights were calculated. + // This way I ensure that weights correspond to same kinematic cuts and binning as in current analysis. + // Current example format which was set in MakeWeights.C: someString(s), min < kinematic-variable-name < max + // Algorithm: IFS is " " and I take (N-1)th and (N-5)th entry: + TObjArray* oa = TString(hist->GetTitle()).Tokenize(" "); + if (!oa) { + LOGF(fatal, "in function \033[1;31m%s at line %d \n hist->GetTitle() = %s\033[0m", __FUNCTION__, __LINE__, hist->GetTitle()); + } + int nEntries = oa->GetEntries(); + + // I need to figure out corresponding variable from results histograms and its formatting: + eAsFunctionOf AFO = eAsFunctionOf_N; + const char* lVariableName = ""; + if (TString(variable).EqualTo("phipt")) { + AFO = AFO_PT; + lVariableName = FancyFormatting("Pt"); + } else if (TString(variable).EqualTo("phieta")) { + AFO = AFO_ETA; + lVariableName = FancyFormatting("Eta"); + } else { + LOGF(fatal, "\033[1;31m%s at line %d : name = %s is not supported yet. \033[0m", __FUNCTION__, __LINE__, static_cast(variable)); + } + + // Get min and max value for bin, stored locally: + float min = res.fResultsPro[AFO]->GetBinLowEdge(bin + 1); + float max = res.fResultsPro[AFO]->GetBinLowEdge(bin + 2); + if (min > max) { + LOGF(fatal, "\033[1;33m min = %f, max = %f, res.fResultsPro[AFO]->GetName() = %s\033[0m", min, max, res.fResultsPro[AFO]->GetName()); + } + + // Compare with min and max value stored in external weights.root file using MakeWeights.C: + if (!(std::abs(TString(oa->At(nEntries - 1)->GetName()).Atof() - max) < tc.fFloatingPointPrecision)) { + LOGF(info, "\033[1;33m hist->GetTitle() = %s, res.fResultsPro[AFO]->GetName() = %s\033[0m", hist->GetTitle(), res.fResultsPro[AFO]->GetName()); + LOGF(fatal, "in function \033[1;31m%s at line %d : mismatch in upper bin boundaries \n from title = %f , local = %f\033[0m", __FUNCTION__, __LINE__, TString(oa->At(nEntries - 1)->GetName()).Atof(), max); + } + if (!(std::abs(TString(oa->At(nEntries - 5)->GetName()).Atof() - min) < tc.fFloatingPointPrecision)) { + LOGF(info, "\033[1;33m hist->GetTitle() = %s, res.fResultsPro[AFO]->GetName() = %s\033[0m", hist->GetTitle(), res.fResultsPro[AFO]->GetName()); + LOGF(fatal, "in function \033[1;31m%s at line %d : mismatch in lower bin boundaries \n from title = %f , local = %f\033[0m", __FUNCTION__, __LINE__, TString(oa->At(nEntries - 5)->GetName()).Atof(), min); + } + delete oa; // yes, otherwise it's a memory leak + + // *) final settings and cosmetics: + hist->SetDirectory(0); + hist->SetTitle(Form("%s, %.2f < %s < %.2f", filePath, min, lVariableName, max)); + + } // else + + // TBI 20241021 if I need to split hist title across two lines, use this technique: + // hist->SetTitle(Form("#splitline{#scale[0.6]{%s}}{#scale[0.4]{%s}}",hist->GetTitle(),filePath)); + + // h) Clone histogram and delete baseList (realising back the memory): + // Remark: Yes, I have to clone here. + TH1D* histClone = reinterpret_cast(hist->Clone()); + delete baseList; // release back the memory + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + return histClone; + + } // TH1D* GetHistogramWithWeights(const char* filePath, const char* runNumber, const char* variable, int bin = -1) + + //============================================================ + + THnSparseF* GetSparseHistogramWithWeights(const char* filePath, const char* runNumber, const char* whichCategory, const char* whichDimensions) + { + // Get and return sparse histogram with weights from an external file. + + // Remark 1: "whichCategory" always indicates the default x-axis (0th dimension), for instance for "differential phi weights" it's "phi" + + // Remark 2: "whichDimensions" is formatted as follows: __..., for instance "pt_cent", if weights are calculated differentially as a function of pt and centrality. + // If empty, that is also fine, I am fetching integrated weights, for instance integrated phi weights. + + // Remark 3: The naming convention for sparse histogram in the output file is: __multiparticle-correlations-a-b_ + // a) I allow possibility that "multiparticle-correlations-a-b_" is not present in the name + // b) In HL, fTaskName is typically subwagon name. Therefore, it's mandatory that for a given subwagon in HL, BOTH subwagon name and fTaskName are set to the same name + // TBI 20250215 If I can get within my task at run time subwagon name, I can automate this step. Check if that is possible + + // TBI 20240504: Here I can keep const char* variable , i.e. no need to switch to enums, because this function is called only once, at init. + // Nevertheless, I could switch to enums and make it more general, i.e. I could introduce additional data members and configurables, + // for the names of histograms with weights. Like I did it in void GetHistogramWithCustomNUA(const char* filePath, eNUAPDF variable) + + // TBI 20241021 Strictly speaking, I do not need to pass here first 2 arguments, "filePath" and "runNumber", because they are initialized at call from data members. + // But since this function is called only once, it's not an important performance loss. But re-think the design here eventually. + // If I decide to promote filePath to data member, implement it as an array, to allow possibility that different catagories of weights are fetched from different external files. + + // a) Return value; + // b) Basic protection for arguments; + // c) Determine from filePath if the file in on a local machine, or in AliEn, or in CCDB; + // d) Handle the AliEn case; + // e) Handle the CCDB case; + // f) Handle the local case; + // g) The final touch on sparse histogram with weights; + // h) Clone histogram and delete baseList (realising back the memory). + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + LOGF(info, "\033[1;33m filePath = %s\033[0m", filePath); + LOGF(info, "\033[1;33m runNumber = %s\033[0m", runNumber); + LOGF(info, "\033[1;33m whichDimensions = %s\033[0m", whichDimensions); + } + + // a) Return value: + THnSparseF* sparseHist = NULL; + TList* baseList = NULL; // base top-level list in the TFile, e.g. named "ccdb_object" + TList* listWithRuns = NULL; // nested list with run-wise TList's holding run-specific weights + + // b) Basic protection for arguments: + // Remark: below I do one more specific check. + if (!(TString(whichCategory).EqualTo("phi") || TString(whichCategory).EqualTo("pt") || TString(whichCategory).EqualTo("eta"))) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + if (TString(whichDimensions).EqualTo("")) { + LOGF(warning, "\033[1;33m%s at line %d : whichDimensions is empty, accessing only integrated %s weights\033[0m", __FUNCTION__, __LINE__, whichCategory); + } + + // c) Determine from filePath if the file in on a local machine, or in home dir AliEn, or in CCDB: + // Algorithm: If filePath begins with "/alice/cern.ch/" then it's in home + // dir AliEn. If filePath begins with "/alice-ccdb.cern.ch/" then it's in + // CCDB. Therefore, files in AliEn and CCDB must be specified with abs path, + // for local files both abs and relative paths are just fine. + bool bFileIsInAliEn = false; + bool bFileIsInCCDB = false; + if (TString(filePath).BeginsWith("/alice/cern.ch/")) { + bFileIsInAliEn = true; + } else { + if (TString(filePath).BeginsWith("/alice-ccdb.cern.ch/")) { + bFileIsInCCDB = true; + } // else { + } // if (TString(filePath).BeginsWith("/alice/cern.ch/")) { + + if (bFileIsInAliEn) { + // d) Handle the AliEn case: + TGrid* alien = TGrid::Connect("alien", gSystem->Getenv("USER"), "", ""); + if (!alien) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + TFile* weightsFile = TFile::Open(Form("alien://%s", filePath), "READ"); + if (!weightsFile) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + + weightsFile->GetObject("ccdb_object", baseList); // TBI 20231008 for simplicity, hardwired name + // of base TList is "ccdb_object" also for + // AliEn case, see if I need to change this + if (!baseList) { + // weightsFile->ls(); + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + + listWithRuns = reinterpret_cast(GetObjectFromList(baseList, runNumber)); + if (!listWithRuns) { + TString runNumberWithLeadingZeroes = "000"; + runNumberWithLeadingZeroes += runNumber; // another try, with "000" prepended to run number + listWithRuns = reinterpret_cast(GetObjectFromList(baseList, runNumberWithLeadingZeroes.Data())); + if (!listWithRuns) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + } + + } else if (bFileIsInCCDB) { + + // e) Handle the CCDB case: Remember that here I do not access the file, + // instead directly object in that file. + // My home dir in CCDB: https://alice-ccdb.cern.ch/browse/Users/a/abilandz/ + // Inspired by: + // 1. Discussion at: + // https://alice-talk.web.cern.ch/t/access-to-lhc-filling-scheme/1073/17 + // 2. See also: + // https://github.com/AliceO2Group/O2Physics/blob/master/Tutorials/src/efficiencyGlobal.cxx + // https://github.com/AliceO2Group/O2Physics/blob/master/Tutorials/src/efficiencyPerRun.cxx + // 3. O2 Analysis Tutorial 2.0: + // https://indico.cern.ch/event/1267433/timetable/#20230417.detailed + + ccdb->setURL("http://alice-ccdb.cern.ch"); + if (tc.fVerbose) { + LOGF(info, "\033[1;32mAccessing in CCDB %s\033[0m", TString(filePath).ReplaceAll("/alice-ccdb.cern.ch/", "").Data()); + } + + baseList = reinterpret_cast(ccdb->get(TString(filePath).ReplaceAll("/alice-ccdb.cern.ch/", "").Data())); + + if (!baseList) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + + listWithRuns = reinterpret_cast(GetObjectFromList(baseList, runNumber)); + if (!listWithRuns) { + TString runNumberWithLeadingZeroes = "000"; + runNumberWithLeadingZeroes += runNumber; // another try, with "000" prepended to run number + listWithRuns = reinterpret_cast(GetObjectFromList(baseList, runNumberWithLeadingZeroes.Data())); + if (!listWithRuns) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + } + + } else { + + // f) Handle the local case: + // TBI 20231008 In principle, also for the local case in O2, I could + // maintain the same local structure of weights as it was in AliPhysics. + // But for simplicity, in O2 I organize local weights in the + // same way as in AliEn or CCDB. + + // Check if the external ROOT file exists at specified path: + if (gSystem->AccessPathName(filePath, kFileExists)) { + LOGF(info, "\033[1;33m if(gSystem->AccessPathName(filePath,kFileExists)), filePath = %s \033[0m", filePath); + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + + TFile* weightsFile = TFile::Open(filePath, "READ"); + if (!weightsFile) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + + weightsFile->GetObject("ccdb_object", baseList); // TBI 20231008 for simplicity, hardwired name + // of base TList is "ccdb_object" also for + // local case, see if I need to change this + if (!baseList) { + // weightsFile->ls(); + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + + listWithRuns = reinterpret_cast(GetObjectFromList(baseList, runNumber)); + if (!listWithRuns) { + TString runNumberWithLeadingZeroes = "000"; + runNumberWithLeadingZeroes += runNumber; // another try, with "000" prepended to run number + listWithRuns = reinterpret_cast(GetObjectFromList(baseList, runNumberWithLeadingZeroes.Data())); + if (!listWithRuns) { + // baseList->ls(); + LOGF(fatal, "\033[1;31m%s at line %d : this crash can happen if in the output file there is no list with weights for the current run number = %s\033[0m", __FUNCTION__, __LINE__, tc.fRunNumber.Data()); + } + } + + } // else { + + // g) The final touch on sparse histogram with weights: + TString sparseHistName = ""; + if (TString(whichDimensions).EqualTo("")) { + sparseHistName = TString::Format("%s_multiparticle-correlations-a-b", whichCategory); + } else if (TString(whichDimensions).BeginsWith("_")) { // TBI 20250215 alternativelly, I can remove leading "_" before calling this function + sparseHistName = TString::Format("%s%s_multiparticle-correlations-a-b", whichCategory, whichDimensions); + } else { + sparseHistName = TString::Format("%s_%s_multiparticle-correlations-a-b", whichCategory, whichDimensions); + } + // *) If not empty, I still need to append TaskName (i.e. the cut name): + if (!TString(tc.fTaskName).EqualTo("")) { + sparseHistName += tc.fTaskName.Data(); + } + + // 1. fetch histogram directly from this list: const char* whichCategory, const char* whichDimensions + LOGF(info, "\033[1;33m%s at line %d : fetching directly from the list sparse histogram with the name \"%s\"\033[0m", __FUNCTION__, __LINE__, sparseHistName.Data()); + sparseHist = reinterpret_cast(listWithRuns->FindObject(sparseHistName.Data())); + if (!sparseHist) { + // try once again by chopping off "multiparticle-correlations-a-b_" from the name: + TString tmp = sparseHistName; // yes, because "ReplaceAll" below replaces in-place, and I will need sparseHistName unmodified still later + sparseHist = reinterpret_cast(listWithRuns->FindObject(tmp.ReplaceAll("multiparticle-correlations-a-b_", ""))); + } + + // 2. if the previous search failed, descend recursively into the nested lists: + if (!sparseHist) { + LOGF(info, "\033[1;33m%s at line %d : previous attempt failed, fetching instead recursively sparse histogram with the name \"%s\"\033[0m", __FUNCTION__, __LINE__, sparseHistName.Data()); + sparseHist = reinterpret_cast(GetObjectFromList(listWithRuns, sparseHistName.Data())); + if (!sparseHist) { + // try once again by chopping off "multiparticle-correlations-a-b_" from name: + TString tmp = sparseHistName; // yes, because "ReplaceAll" below replaces in-place, and I will need sparseHistName unmodified still later + sparseHist = reinterpret_cast(GetObjectFromList(listWithRuns, tmp.ReplaceAll("multiparticle-correlations-a-b_", ""))); + } + } + + if (!sparseHist) { + listWithRuns->ls(); + LOGF(fatal, "\033[1;31m%s at line %d : couldn't fetch sparse histogram with name = %s from this list\033[0m", __FUNCTION__, __LINE__, sparseHistName.Data()); + } + + sparseHist->SetTitle(Form("%s, %s", filePath, runNumber)); // I have to do it here, because only here I have "filePath" available + + // hist->SetTitle(Form("%s, %.2f < %s < %.2f", filePath, min, lVariableName, max)); + + // TBI 20250530 check this code snippet - do I need it? + // // *) insanity check for differential weights => check if boundaries of current bin are the same as bin boundaries for which these weights were calculated. + // // This way I ensure that weights correspond to same kinematic cuts and binning as in current analysis. + // // Current example format which was set in MakeWeights.C: someString(s), min < kinematic-variable-name < max + // // Algorithm: IFS is " " and I take (N-1)th and (N-5)th entry: + // TObjArray* oa = TString(hist->GetTitle()).Tokenize(" "); + // if (!oa) { + // LOGF(fatal, "in function \033[1;31m%s at line %d \n hist->GetTitle() = %s\033[0m", __FUNCTION__, __LINE__, hist->GetTitle()); + // } + // int nEntries = oa->GetEntries(); + // + // // I need to figure out corresponding variable from results histograms and its formatting: + // eAsFunctionOf AFO = eAsFunctionOf_N; + // const char* lVariableName = ""; + // if (TString(variable).EqualTo("phipt")) { + // AFO = AFO_PT; + // lVariableName = FancyFormatting("Pt"); + // } else if (TString(variable).EqualTo("phieta")) { + // AFO = AFO_ETA; + // lVariableName = FancyFormatting("Eta"); + // } else { + // LOGF(fatal, "\033[1;31m%s at line %d : name = %s is not supported yet. \033[0m", __FUNCTION__, __LINE__, static_cast(variable)); + // } + // + // // Get min and max value for bin, stored locally: + // float min = res.fResultsPro[AFO]->GetBinLowEdge(bin + 1); + // float max = res.fResultsPro[AFO]->GetBinLowEdge(bin + 2); + // if (min > max) { + // LOGF(fatal, "\033[1;33m min = %f, max = %f, res.fResultsPro[AFO]->GetName() = %s\033[0m", min, max, res.fResultsPro[AFO]->GetName()); + // } + // + // // Compare with min and max value stored in external weights.root file using MakeWeights.C: + // if (!(std::abs(TString(oa->At(nEntries - 1)->GetName()).Atof() - max) < tc.fFloatingPointPrecision)) { + // LOGF(info, "\033[1;33m hist->GetTitle() = %s, res.fResultsPro[AFO]->GetName() = %s\033[0m", hist->GetTitle(), res.fResultsPro[AFO]->GetName()); + // LOGF(fatal, "in function \033[1;31m%s at line %d : mismatch in upper bin boundaries \n from title = %f , local = %f\033[0m", __FUNCTION__, __LINE__, TString(oa->At(nEntries - 1)->GetName()).Atof(), max); + // } + // if (!(std::abs(TString(oa->At(nEntries - 5)->GetName()).Atof() - min) < tc.fFloatingPointPrecision)) { + // LOGF(info, "\033[1;33m hist->GetTitle() = %s, res.fResultsPro[AFO]->GetName() = %s\033[0m", hist->GetTitle(), res.fResultsPro[AFO]->GetName()); + // LOGF(fatal, "in function \033[1;31m%s at line %d : mismatch in lower bin boundaries \n from title = %f , local = %f\033[0m", __FUNCTION__, __LINE__, TString(oa->At(nEntries - 5)->GetName()).Atof(), min); + // } + // delete oa; // yes, otherwise it's a memory leak + // + // // *) final settings and cosmetics: + // hist->SetDirectory(0); + + // TBI 20241021 if I need to split hist title across two lines, use this technique: + // hist->SetTitle(Form("#splitline{#scale[0.6]{%s}}{#scale[0.4]{%s}}",hist->GetTitle(),filePath)); + + // h) Clone histogram and delete baseList (releasing back the memory): + // Remark: Yes, I have to clone here. + THnSparseF* sparseHistClone = reinterpret_cast(sparseHist->Clone()); + delete baseList; // release back the memory + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + return sparseHistClone; + + } // THnSparseF* GetSparseHistogramWithWeights(const char* filePath, const char* runNumber, const char* whichCategory, const char* whichDimensions) + + //============================================================ + + TH1D* GetHistogramWithCentralityWeights(const char* filePath, const char* runNumber) + { + // Get and return histogram with centrality weights from an external file. + + // TBI 20241118 Shall I merge this function with GetHistogramWithWeights(...) as there is a bit of code bloat? + + // TBI 20241021 Strictly speaking, I do not need to pass here 2 arguments, "filePath" and "runNumber", because they are initialized at call from data members. + // But since this function is called only once, it's not an important performance loss. But re-think the design here eventually. + + // a) Return value; + // b) Basic protection for arguments; + // c) Determine from filePath if the file in on a local machine, or in AliEn, or in CCDB; + // d) Handle the AliEn case; + // e) Handle the CCDB case; + // f) Handle the local case; + // g) The final touch on histogram with centrality weights; + // h) Clone histogram and delete baseList (realising back the memory). + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + LOGF(info, "\033[1;33m filePath = %s\033[0m", filePath); + LOGF(info, "\033[1;33m runNumber = %s\033[0m", runNumber); + LOGF(info, "\033[1;33m fTaskName = %s\033[0m", tc.fTaskName.Data()); + } + + // a) Return value: + TH1D* hist = NULL; + TList* baseList = NULL; // base top-level list in the TFile, e.g. named "ccdb_object" + TList* listWithRuns = NULL; // nested list with run-wise TList's holding run-specific weights + + // b) Basic protection for arguments: + // ... + + // c) Determine from filePath if the file in on a local machine, or in home dir AliEn, or in CCDB: + // Algorithm: If filePath begins with "/alice/cern.ch/" then it's in home + // dir AliEn. If filePath begins with "/alice-ccdb.cern.ch/" then it's in + // CCDB. Therefore, files in AliEn and CCDB must be specified with abs path, + // for local files both abs and relative paths are just fine. + bool bFileIsInAliEn = false; + bool bFileIsInCCDB = false; + if (TString(filePath).BeginsWith("/alice/cern.ch/")) { + bFileIsInAliEn = true; + } else { + if (TString(filePath).BeginsWith("/alice-ccdb.cern.ch/")) { + bFileIsInCCDB = true; + } // else { + } // if (TString(filePath).BeginsWith("/alice/cern.ch/")) { + + if (bFileIsInAliEn) { + // d) Handle the AliEn case: + TGrid* alien = TGrid::Connect("alien", gSystem->Getenv("USER"), "", ""); + if (!alien) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + TFile* centralityWeightsFile = TFile::Open(Form("alien://%s", filePath), "READ"); + if (!centralityWeightsFile) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + + centralityWeightsFile->GetObject("ccdb_object", baseList); // TBI 20231008 for simplicity, hardwired name + // of base TList is "ccdb_object" also for + // AliEn case, see if I need to change this + if (!baseList) { + // centralityWeightsFile->ls(); + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + + listWithRuns = reinterpret_cast(GetObjectFromList(baseList, runNumber)); + if (!listWithRuns) { + TString runNumberWithLeadingZeroes = "000"; + runNumberWithLeadingZeroes += runNumber; // another try, with "000" prepended to run number + listWithRuns = reinterpret_cast(GetObjectFromList(baseList, runNumberWithLeadingZeroes.Data())); + if (!listWithRuns) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + } + + } else if (bFileIsInCCDB) { + + // e) Handle the CCDB case: Remember that here I do not access the file, + // instead directly object in that file. + // My home dir in CCDB: https://alice-ccdb.cern.ch/browse/Users/a/abilandz/ + // Inspired by: + // 1. Discussion at: + // https://alice-talk.web.cern.ch/t/access-to-lhc-filling-scheme/1073/17 + // 2. See also: + // https://github.com/AliceO2Group/O2Physics/blob/master/Tutorials/src/efficiencyGlobal.cxx + // https://github.com/AliceO2Group/O2Physics/blob/master/Tutorials/src/efficiencyPerRun.cxx + // 3. O2 Analysis Tutorial 2.0: + // https://indico.cern.ch/event/1267433/timetable/#20230417.detailed + + ccdb->setURL("http://alice-ccdb.cern.ch"); + if (tc.fVerbose) { + LOGF(info, "\033[1;32mAccessing in CCDB %s\033[0m", TString(filePath).ReplaceAll("/alice-ccdb.cern.ch/", "").Data()); + } + + baseList = reinterpret_cast(ccdb->get(TString(filePath).ReplaceAll("/alice-ccdb.cern.ch/", "").Data())); + + if (!baseList) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + + listWithRuns = reinterpret_cast(GetObjectFromList(baseList, runNumber)); + if (!listWithRuns) { + TString runNumberWithLeadingZeroes = "000"; + runNumberWithLeadingZeroes += runNumber; // another try, with "000" prepended to run number + listWithRuns = reinterpret_cast(GetObjectFromList(baseList, runNumberWithLeadingZeroes.Data())); + if (!listWithRuns) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + } + + } else { + + // f) Handle the local case: + // TBI 20231008 In principle, also for the local case in O2, I could + // maintain the same local structure of weights as it was in AliPhysics. + // But for simplicity, in O2 I organize local weights in the same way as in AliEn or CCDB. + + // Check if the external ROOT file exists at specified path: + if (gSystem->AccessPathName(filePath, kFileExists)) { + LOGF(info, "\033[1;33m if(gSystem->AccessPathName(filePath,kFileExists)), filePath = %s \033[0m", filePath); + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + + TFile* centralityWeightsFile = TFile::Open(filePath, "READ"); + if (!centralityWeightsFile) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + + centralityWeightsFile->GetObject("ccdb_object", baseList); // TBI 20231008 for simplicity, hardwired name + // of base TList is "ccdb_object" also for + // local case, see if I need to change this + + if (!baseList) { + // centralityWeightsFile->ls(); + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + + listWithRuns = reinterpret_cast(GetObjectFromList(baseList, runNumber)); + if (!listWithRuns) { + TString runNumberWithLeadingZeroes = "000"; + runNumberWithLeadingZeroes += runNumber; // another try, with "000" prepended to run number + listWithRuns = reinterpret_cast(GetObjectFromList(baseList, runNumberWithLeadingZeroes.Data())); + if (!listWithRuns) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + } + + } // else { + + // g) The final touch on histogram with centrality weights: + TString histName = ""; + + // fetch histogram directly from this list: + // Remark: histName must be formated as e.g. "FT0C_multiparticle-correlations-a-b" for default analysis, or "FT0C_multiparticle-correlations-a-b_someCut" + + // Isolate short centrality estimator name, e.g. "FT0C" or "V0M" TBI 20250122 move this to utility function, because I have the same code in FancyFormatting() + TString tmp = ec.fsEventCuts[eCentralityEstimator]; // I have to introduce local TString tmp, because ReplaceAll replaces in-place + if (tmp.BeginsWith("CentRun2")) { + tmp.ReplaceAll("CentRun2", ""); // "CentRun2V0M" => "V0M" + } else if (tmp.BeginsWith("Cent")) { + tmp.ReplaceAll("Cent", ""); // "CentFT0C" => FT0C" + } else { + LOGF(fatal, "\033[1;31m%s at line %d : the case tmp = %s is not supported yet\033[0m", __FUNCTION__, __LINE__, tmp.Data()); + } + + histName = TString::Format("%s_multiparticle-correlations-a-b", tmp.Data()); // I can hardwire here the name, as long as my main task name is struct MultiparticleCorrelationsAB + if (!tc.fTaskName.EqualTo("")) { + // for non-default analysis (e.g. in subwagon), append still "_someName", where "someName" is subwagon = taskname + histName += "_"; + histName += tc.fTaskName; + } + + LOGF(info, "\033[1;33m%s at line %d : fetching directly hist with name = %s\033[0m", __FUNCTION__, __LINE__, histName.Data()); + hist = reinterpret_cast(listWithRuns->FindObject(histName.Data())); + // if the previous search failed, descend recursively also into the nested lists: + if (!hist) { + LOGF(info, "\033[1;33m%s at line %d : previous attempt failed, fetching instead recursively hist with name = %s\033[0m", __FUNCTION__, __LINE__, histName.Data()); + hist = reinterpret_cast(GetObjectFromList(listWithRuns, histName.Data())); + } + if (!hist) { + histName = tmp; // yes, for some simple tests I can have only histogram named e.g. 'FT0C' + LOGF(info, "\033[1;33m%s at line %d : last attempt, fetching instead hist with trivial name = %s\033[0m", __FUNCTION__, __LINE__, histName.Data()); + hist = reinterpret_cast(GetObjectFromList(listWithRuns, histName.Data())); + } + if (!hist) { + listWithRuns->ls(); + LOGF(fatal, "\033[1;31m%s at line %d : couldn't fetch hist with name = %s\033[0m", __FUNCTION__, __LINE__, histName.Data()); + } + hist->SetDirectory(0); + hist->SetTitle(Form("%s, %s", filePath, runNumber)); // I have to do it here, because only here I have "filePath" av + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + // h) Clone histogram and delete baseList (realising back the memory): + // Remark: Yes, I have to clone here. + TH1D* histClone = reinterpret_cast(hist->Clone()); + delete baseList; // release back the memory + + return histClone; + + } // TH1D* GetHistogramWithCentralityWeights(const char* filePath, const char* runNumber) + + //============================================================ + + TObjArray* GetDefaultObjArrayWithLabels(const char* whichDefaultLabels) + { + // To speed up testing, I hardwire here some labels and use them directly as they are. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // Define TObjArray: + TObjArray* arr = new TObjArray(); + arr->SetOwner(); + + // Define some labels, depending on the chosen option for whichDefaultLabels: + if (TString(whichDefaultLabels).EqualTo("trivial")) { + const int nLabels = 1; + TString labels[nLabels] = {"2 -2"}; + for (int l = 0; l < nLabels; l++) { + TObjString* objstr = new TObjString(labels[l].Data()); + arr->Add(objstr); + } + } else if (TString(whichDefaultLabels).EqualTo("mixedEventsStudy")) { + const int nLabels = 3; + TString labels[nLabels] = {"2", "-2", "2 -2"}; + for (int l = 0; l < nLabels; l++) { + TObjString* objstr = new TObjString(labels[l].Data()); + arr->Add(objstr); + } + } else if (TString(whichDefaultLabels).EqualTo("scan2p")) { + const int nLabels = 6; + TString labels[nLabels] = {"1 -1", "2 -2", "3 -3", "4 -4", "5 -5", "6 -6"}; + for (int l = 0; l < nLabels; l++) { + TObjString* objstr = new TObjString(labels[l].Data()); + arr->Add(objstr); + } + } else if (TString(whichDefaultLabels).EqualTo("projections")) { // use this set to test projections when calculating multi-dimensional weights + const int nLabels = 10; + TString labels[nLabels] = {"1", "2", "3", "1 -1", "2 -2", "3 -3", "3 -1 -2", "1 1 -1 -1", "2 2 -2 -2", "3 3 -3 -3"}; + for (int l = 0; l < nLabels; l++) { + TObjString* objstr = new TObjString(labels[l].Data()); + arr->Add(objstr); + } + } else if (TString(whichDefaultLabels).EqualTo("standard")) { + const int nLabels = 7; + TString labels[nLabels] = {"1 -1", "2 -2", "3 -3", "2 1 -1 -2", "3 1 -1 -3", "3 2 -2 -3", "3 2 1 -1 -2 -3"}; + for (int l = 0; l < nLabels; l++) { + TObjString* objstr = new TObjString(labels[l].Data()); + arr->Add(objstr); + } + } else if (TString(whichDefaultLabels).EqualTo("isotropic")) { + const int nLabels = 8; + TString labels[nLabels] = {"1 -1", "2 -2", "3 -3", "4 -4", "1 1 -1 -1", "2 2 -2 -2", "3 3 -3 -3", "4 4 -4 -4"}; + for (int l = 0; l < nLabels; l++) { + TObjString* objstr = new TObjString(labels[l].Data()); + arr->Add(objstr); + } + } else if (TString(whichDefaultLabels).EqualTo("upto8th")) { + const int nLabels = 7; // yes, because I do not care about 1-p + TString labels[nLabels] = {"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"}; + for (int l = 0; l < nLabels; l++) { + TObjString* objstr = new TObjString(labels[l].Data()); + arr->Add(objstr); + } + } else if (TString(whichDefaultLabels).EqualTo("upto10th")) { + const int nLabels = 9; // yes, because I do not care about 1-p + TString labels[nLabels] = {"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 1 1 -1 -1 -1 -1 -1", "1 1 1 1 1 -1 -1 -1 -1 -1"}; + for (int l = 0; l < nLabels; l++) { + TObjString* objstr = new TObjString(labels[l].Data()); + arr->Add(objstr); + } + } else if (TString(whichDefaultLabels).EqualTo("upto12th")) { + const int nLabels = 11; // yes, because I do not care about 1-p + TString labels[nLabels] = {"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 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 -1 -1 -1"}; + for (int l = 0; l < nLabels; l++) { + TObjString* objstr = new TObjString(labels[l].Data()); + arr->Add(objstr); + } + } else if (TString(whichDefaultLabels).EqualTo("Set_0")) { + // From ~/scratch/O2/master/Labels/Set_0/labels_Set_0.root + const int nLabels = 57; // yes, because I do not care about 1-p + TString labels[nLabels] = { + "1 -1 ", + "2 -2 ", + "3 -3 ", + "4 -4 ", + "5 -5 ", + "6 -6 ", + "2 1 -1 -2 ", + "3 1 -1 -3 ", + "3 2 -2 -3 ", + "4 1 -1 -4 ", + "4 2 -2 -4 ", + "4 3 -3 -4 ", + "5 1 -1 -5 ", + "5 2 -2 -5 ", + "5 3 -3 -5 ", + "5 4 -4 -5 ", + "6 1 -1 -6 ", + "6 2 -2 -6 ", + "6 3 -3 -6 ", + "6 4 -4 -6 ", + "6 5 -5 -6 ", + "3 2 1 -1 -2 -3 ", + "4 2 1 -1 -2 -4 ", + "4 3 1 -1 -3 -4 ", + "4 3 2 -2 -3 -4 ", + "5 2 1 -1 -2 -5 ", + "5 3 1 -1 -3 -5 ", + "5 3 2 -2 -3 -5 ", + "5 4 1 -1 -4 -5 ", + "5 4 2 -2 -4 -5 ", + "5 4 3 -3 -4 -5 ", + "6 2 1 -1 -2 -6 ", + "6 3 1 -1 -3 -6 ", + "6 3 2 -2 -3 -6 ", + "6 4 1 -1 -4 -6 ", + "6 4 2 -2 -4 -6 ", + "6 4 3 -3 -4 -6 ", + "6 5 1 -1 -5 -6 ", + "6 5 2 -2 -5 -6 ", + "6 5 3 -3 -5 -6 ", + "6 5 4 -4 -5 -6 ", + "2 2 -2 -2", + "3 3 -3 -3", + "4 4 -4 -4", + "2 2 2 -2 -2 -2", + "3 3 2 -2 -3 -3", + "3 2 2 -2 -2 -3 ", + "3 3 3 -3 -3 -3", + "4 4 2 -2 -4 -4", + "4 2 2 -2 -2 -4", + "4 4 3 -3 -4 -4", + "4 3 3 -3 -3 -4", + "4 4 3 2 -2 -3 -4 -4", + "4 3 3 2 -2 -3 -3 -4", + "4 3 2 2 -2 -2 -3 -4", + "3 3 3 2 -2 -3 -3 -3", + "3 2 2 2 -2 -2 -2 -3"}; + for (int l = 0; l < nLabels; l++) { + TObjString* objstr = new TObjString(labels[l].Data()); + arr->Add(objstr); + } + } else if (TString(whichDefaultLabels).EqualTo("Set_1")) { + // From ~/scratch/O2/master/Labels/Set_1/labels_Set_1.root + const int nLabels = 56; // yes, because I do not care about 1-p + TString labels[nLabels] = { + "1 -1 ", + "2 -2 ", + "3 -3 ", + "4 -4 ", + "5 -5 ", + "6 -6 ", + "2 1 -1 -2 ", + "3 1 -1 -3 ", + "3 2 -2 -3 ", + "4 1 -1 -4 ", + "4 2 -2 -4 ", + "4 3 -3 -4 ", + "5 1 -1 -5 ", + "5 2 -2 -5 ", + "5 3 -3 -5 ", + "5 4 -4 -5 ", + "6 1 -1 -6 ", + "6 2 -2 -6 ", + "6 3 -3 -6 ", + "6 4 -4 -6 ", + "6 5 -5 -6 ", + "3 2 1 -1 -2 -3 ", + "4 2 1 -1 -2 -4 ", + "4 3 1 -1 -3 -4 ", + "4 3 2 -2 -3 -4 ", + "5 2 1 -1 -2 -5 ", + "5 3 1 -1 -3 -5 ", + "5 3 2 -2 -3 -5 ", + "5 4 1 -1 -4 -5 ", + "5 4 2 -2 -4 -5 ", + "5 4 3 -3 -4 -5 ", + "6 2 1 -1 -2 -6 ", + "6 3 1 -1 -3 -6 ", + "6 3 2 -2 -3 -6 ", + "6 4 1 -1 -4 -6 ", + "6 4 2 -2 -4 -6 ", + "6 4 3 -3 -4 -6 ", + "6 5 1 -1 -5 -6 ", + "6 5 2 -2 -5 -6 ", + "6 5 3 -3 -5 -6 ", + "6 5 4 -4 -5 -6 ", + "4 3 2 1 -1 -2 -3 -4 ", + "5 3 2 1 -1 -2 -3 -5 ", + "5 4 2 1 -1 -2 -4 -5 ", + "5 4 3 1 -1 -3 -4 -5 ", + "5 4 3 2 -2 -3 -4 -5 ", + "6 3 2 1 -1 -2 -3 -6 ", + "6 4 2 1 -1 -2 -4 -6 ", + "6 4 3 1 -1 -3 -4 -6 ", + "6 4 3 2 -2 -3 -4 -6 ", + "6 5 2 1 -1 -2 -5 -6 ", + "6 5 3 1 -1 -3 -5 -6 ", + "6 5 3 2 -2 -3 -5 -6 ", + "6 5 4 1 -1 -4 -5 -6 ", + "6 5 4 2 -2 -4 -5 -6 ", + "6 5 4 3 -3 -4 -5 -6 "}; + for (int l = 0; l < nLabels; l++) { + TObjString* objstr = new TObjString(labels[l].Data()); + arr->Add(objstr); + } + } else if (TString(whichDefaultLabels).EqualTo("Set_2")) { + // From ~/scratch/O2/master/Labels/Set_2/labels_Set_2.root + const int nLabels = 62; // yes, because I do not care about 1-p + TString labels[nLabels] = { + "1 -1 ", + "2 -2 ", + "3 -3 ", + "4 -4 ", + "5 -5 ", + "6 -6 ", + "2 1 -1 -2 ", + "3 1 -1 -3 ", + "3 2 -2 -3 ", + "4 1 -1 -4 ", + "4 2 -2 -4 ", + "4 3 -3 -4 ", + "5 1 -1 -5 ", + "5 2 -2 -5 ", + "5 3 -3 -5 ", + "5 4 -4 -5 ", + "6 1 -1 -6 ", + "6 2 -2 -6 ", + "6 3 -3 -6 ", + "6 4 -4 -6 ", + "6 5 -5 -6 ", + "3 2 1 -1 -2 -3 ", + "4 2 1 -1 -2 -4 ", + "4 3 1 -1 -3 -4 ", + "4 3 2 -2 -3 -4 ", + "5 2 1 -1 -2 -5 ", + "5 3 1 -1 -3 -5 ", + "5 3 2 -2 -3 -5 ", + "5 4 1 -1 -4 -5 ", + "5 4 2 -2 -4 -5 ", + "5 4 3 -3 -4 -5 ", + "6 2 1 -1 -2 -6 ", + "6 3 1 -1 -3 -6 ", + "6 3 2 -2 -3 -6 ", + "6 4 1 -1 -4 -6 ", + "6 4 2 -2 -4 -6 ", + "6 4 3 -3 -4 -6 ", + "6 5 1 -1 -5 -6 ", + "6 5 2 -2 -5 -6 ", + "6 5 3 -3 -5 -6 ", + "6 5 4 -4 -5 -6 ", + "4 3 2 1 -1 -2 -3 -4 ", + "5 3 2 1 -1 -2 -3 -5 ", + "5 4 2 1 -1 -2 -4 -5 ", + "5 4 3 1 -1 -3 -4 -5 ", + "5 4 3 2 -2 -3 -4 -5 ", + "6 3 2 1 -1 -2 -3 -6 ", + "6 4 2 1 -1 -2 -4 -6 ", + "6 4 3 1 -1 -3 -4 -6 ", + "6 4 3 2 -2 -3 -4 -6 ", + "6 5 2 1 -1 -2 -5 -6 ", + "6 5 3 1 -1 -3 -5 -6 ", + "6 5 3 2 -2 -3 -5 -6 ", + "6 5 4 1 -1 -4 -5 -6 ", + "6 5 4 2 -2 -4 -5 -6 ", + "6 5 4 3 -3 -4 -5 -6 ", + "5 4 3 2 1 -1 -2 -3 -4 -5 ", + "6 4 3 2 1 -1 -2 -3 -4 -6 ", + "6 5 3 2 1 -1 -2 -3 -5 -6 ", + "6 5 4 2 1 -1 -2 -4 -5 -6 ", + "6 5 4 3 1 -1 -3 -4 -5 -6 ", + "6 5 4 3 2 -2 -3 -4 -5 -6 "}; + for (int l = 0; l < nLabels; l++) { + TObjString* objstr = new TObjString(labels[l].Data()); + arr->Add(objstr); + } + } else { + LOGF(fatal, "\033[1;31m%s at line %d : whichDefaultLabels = %s is not supported yet \033[0m", __FUNCTION__, __LINE__, whichDefaultLabels); + } + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + return arr; + + } // TObjArray* GetDefaultObjArrayWithLabels(const char* whichDefaultLabels) + + //============================================================ + + TObjArray* GetObjArrayWithLabels(const char* filePath) + { + // This function extracts from an external file TObjArray named "labels", and + // returns it. External file can be: + // 1) on a local computer; + // 2) in home directory AliEn => configurable "cfFileWithLabels" must begin with "/alice/cern.ch/" + // 3) in CCDB => configurable "cfFileWithLabels" must begin with "/alice-ccdb.cern.ch/" + // For all CCDB wisdom, see toggle "CCDB" in page "O2" + + // a) Return value; + // b) Determine from filePath if the file in on a local machine, or in AliEn; + // c) Handle the AliEn case; + // d) Handle the CCDB case; + // e) Handle the local case; + // f) Clean up. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // a) Return value: + TObjArray* oa = NULL; + + // b) Determine from filePath if the file in on a local machine, or in home + // dir AliEn, or in CCDB: + // Algorithm: If filePath begins with "/alice/cern.ch/" then it's in home + // dir AliEn. + // If filePath begins with "/alice-ccdb.cern.ch/" then it's in + // CCDB. Therefore, files in AliEn and CCDB must be specified + // with abs path, for local files both abs and relative paths + // are just fine. + bool bFileIsInAliEn = false; + bool bFileIsInCCDB = false; + if (TString(filePath).BeginsWith("/alice/cern.ch/")) { + bFileIsInAliEn = true; + } else { + if (TString(filePath).BeginsWith("/alice-ccdb.cern.ch/")) { + bFileIsInCCDB = true; + } // else { + } // if (TString(filePath).BeginsWith("/alice/cern.ch/")) { + + TFile* oaFile = NULL; // file holding TObjArray with all labels + if (bFileIsInAliEn) { + // c) Handle the AliEn case: + TGrid* alien = TGrid::Connect("alien", gSystem->Getenv("USER"), "", ""); + if (!alien) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + oaFile = TFile::Open(Form("alien://%s", filePath), "READ"); + if (!oaFile) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + + // Fetch TObjArray from external file (keep in sync with local file case below): + TList* lok = oaFile->GetListOfKeys(); + if (!lok) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + for (int l = 0; l < lok->GetEntries(); l++) { + oaFile->GetObject(lok->At(l)->GetName(), oa); + if (oa && TString(oa->ClassName()).EqualTo("TObjArray")) { + break; // TBI 20231107 the working assumption is that in an external file there is only one TObjArray object, + // and here I fetch it, whatever its name is. The advantage is that I do not have to do + // any additional work for TObjArray's name. Since I do not anticipate ever having more than 1 + // TObjArray in an external file, this shall be alright. With the current implementation, + // if there are multiple TObjArray objects in the same ROOT file, the first one will be fetched. + } + } // for(int l=0;lGetEntries();l++) + + if (!oa) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + } else if (bFileIsInCCDB) { + + // d) Handle the CCDB case: Remember that here I do not access the file, + // instead directly object in that file. + // My home dir in CCDB: https://alice-ccdb.cern.ch/browse/Users/a/abilandz/ + // Inspired by: + // 1. Discussion at: + // https://alice-talk.web.cern.ch/t/access-to-lhc-filling-scheme/1073/17 + // 2. See also: + // https://github.com/AliceO2Group/O2Physics/blob/master/Tutorials/src/efficiencyGlobal.cxx + // https://github.com/AliceO2Group/O2Physics/blob/master/Tutorials/src/efficiencyPerRun.cxx + // 3. O2 Analysis Tutorial 2.0: + // https://indico.cern.ch/event/1267433/timetable/#20230417.detailed + + ccdb->setURL("http://alice-ccdb.cern.ch"); + oa = reinterpret_cast(ccdb->get(TString(filePath).ReplaceAll("/alice-ccdb.cern.ch/", "").Data())); // TBI 20250414 memory blow-up + if (!oa) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + } else { + + // e) Handle the local case: + // Check if the external ROOT file exists at specified path: + if (gSystem->AccessPathName(filePath, kFileExists)) { + LOGF(info, "\033[1;33m if(gSystem->AccessPathName(filePath,kFileExists)), filePath = %s \033[0m", filePath); + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + oaFile = TFile::Open(filePath, "READ"); + if (!oaFile) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + + // Fetch TObjArray from external file (keep in sync with AliEn file case above): + TList* lok = oaFile->GetListOfKeys(); + if (!lok) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + for (int l = 0; l < lok->GetEntries(); l++) { + oaFile->GetObject(lok->At(l)->GetName(), oa); + if (oa && TString(oa->ClassName()).EqualTo("TObjArray")) { + break; // TBI 20231107 the working assumption is that in an external file there is only one TObjArray object, + // and here I fetch it, whatever its name is. The advantage is that I do not have to do + // any additional work for TObjArray's name. Since I do not anticipate ever having more than 1 + // TObjArray in an external file, this shall be alright. With the current implementation, + // if there are multiple TObjArray objects in the same ROOT file, the first one will be fetched. + } + } // for(int l=0;lGetEntries();l++) + if (!oa) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + + } // else { + + if (tc.fVerbose) { + LOGF(info, "\033[1;32m%s => Fetched TObjArray named \"%s\" from file %s\033[0m", __FUNCTION__, oa->GetName(), filePath); + ExitFunction(__FUNCTION__); + } + + // f) Clean up: + if (oaFile) { + oaFile->Close(); + delete oaFile; + oaFile = nullptr; + } + + return oa; // "292535" (local) + 294291 (ccdb) + + } // TObjArray* GetObjArrayWithLabels(const char *filePath) + + //============================================================ + + void GetHistogramWithCustomNUA(const char* filePath, eNUAPDF variable) + { + // Get and set immediately histogram with custom NUA for specified variable, from an external file. + // This structure of an external file is mandatory at the moment: + // *) There is a TList named "ccdb_object", which holds all histograms for custom NUA; + // *) These histograms are TH1D objects. + // This is a port of void FlowWithMultiparticleCorrelationsTask::SetNUAPDF(TH1D* const hist, const char* variable) + + // Remark: Unlike for weights and labels, here I am trying to do everythign in the same function, that's why here return type is void, instead of TH1D*. + + // TBI 20240501 there is a bit of code repetition below, add with analogous functions GetHistogramWithWeights(...) and GetObjArrayWithLabels(...) + + // a) Local objects; + // b) Basic protection for arguments; + // c) Determine from filePath if the file in on a local machine, or in AliEn, or in CCDB; + // d) Handle the AliEn case; + // e) Handle the CCDB case; + // f) Handle the local case; + // g) The final touch; + // h) Clone histogram and delete baseList (realising back the memory). + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + LOGF(info, "\033[1;32m filePath = %s\033[0m", filePath); + LOGF(info, "\033[1;32m variable = %d\033[0m", static_cast(variable)); + LOGF(info, "\033[1;32m nua.fCustomNUAPDFHistNames[variable]->Data() = %s\033[0m", nua.fCustomNUAPDFHistNames[variable]->Data()); + LOGF(info, "\033[1;32m fTaskName = %s\033[0m", tc.fTaskName.Data()); + } + + // *) Basic protection: + if (nua.fCustomNUAPDFHistNames[variable] && nua.fCustomNUAPDFHistNames[variable]->EqualTo("")) { + LOGF(info, "\033[1;32m empty TString, variable = %d\033[0m", static_cast(variable)); + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + + // a) Local objects: + TH1D* hist = NULL; + TList* baseList = NULL; // base top-level list in the TFile, always named "ccdb_object" + + // b) Basic protection for arguments: + // ... + + // c) Determine from filePath if the file in on a local machine, or in home dir AliEn, or in CCDB: + // Algorithm: + // *) If filePath begins with "/alice/cern.ch/" then it's in home dir AliEn. + // *) If filePath begins with "/alice-ccdb.cern.ch/" then it's in CCDB. + // *) It's a local file otherwise. + // Therefore, files in AliEn and CCDB must be specified with abs path, for local files both abs and relative paths are just fine. + bool bFileIsInAliEn = false; + bool bFileIsInCCDB = false; + if (TString(filePath).BeginsWith("/alice/cern.ch/")) { + bFileIsInAliEn = true; + } else { + if (TString(filePath).BeginsWith("/alice-ccdb.cern.ch/")) { + bFileIsInCCDB = true; + } // else { + } // if (TString(filePath).BeginsWith("/alice/cern.ch/")) { + + if (bFileIsInAliEn) { + // d) Handle the AliEn case: + TGrid* alien = TGrid::Connect("alien", gSystem->Getenv("USER"), "", ""); + if (!alien) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + TFile* customNUAFile = TFile::Open(Form("alien://%s", filePath), "READ"); + if (!customNUAFile) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + customNUAFile->GetObject("ccdb_object", baseList); + if (!baseList) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + + } else if (bFileIsInCCDB) { + + // e) Handle the CCDB case: Remember that here I do not access the file, instead directly object in that file. + // My home dir in CCDB: https://alice-ccdb.cern.ch/browse/Users/a/abilandz/ + // Inspired by: + // 1. Discussion at: + // https://alice-talk.web.cern.ch/t/access-to-lhc-filling-scheme/1073/17 + // 2. See also: + // https://github.com/AliceO2Group/O2Physics/blob/master/Tutorials/src/efficiencyGlobal.cxx + // https://github.com/AliceO2Group/O2Physics/blob/master/Tutorials/src/efficiencyPerRun.cxx + // 3. O2 Analysis Tutorial 2.0: + // https://indico.cern.ch/event/1267433/timetable/#20230417.detailed + + ccdb->setURL("http://alice-ccdb.cern.ch"); + if (tc.fVerbose) { + LOGF(info, "\033[1;32mAccessing in CCDB %s\033[0m", TString(filePath).ReplaceAll("/alice-ccdb.cern.ch/", "").Data()); + } + + baseList = reinterpret_cast(ccdb->get(TString(filePath).ReplaceAll("/alice-ccdb.cern.ch/", "").Data())); + + if (!baseList) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + + } else { + + // f) Handle the local case: + + // Check if the external ROOT file exists at specified path: + if (gSystem->AccessPathName(filePath, kFileExists)) { + LOGF(info, "\033[1;33m if(gSystem->AccessPathName(filePath,kFileExists)), filePath = %s \033[0m", filePath); + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + + TFile* customNUAFile = TFile::Open(filePath, "READ"); + if (!customNUAFile) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + customNUAFile->GetObject("ccdb_object", baseList); + if (!baseList) { + // customNUAFile->ls(); + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + + // hist = reinterpret_cast(GetObjectFromList(baseList, nua.fCustomNUAPDFHistNames[variable]->Data())); + + } // else { + + // g) The final touch: + hist = reinterpret_cast(GetObjectFromList(baseList, nua.fCustomNUAPDFHistNames[variable]->Data())); + if (!hist) { + LOGF(info, "\033[1;31m hist is NULL \033[0m"); + LOGF(info, "\033[1;31m variable = %d\033[0m", static_cast(variable)); + LOGF(info, "\033[1;31m nua.fCustomNUAPDFHistNames[variable]->Data() = %s\033[0m", nua.fCustomNUAPDFHistNames[variable]->Data()); + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + + // h) Clone histogram and delete baseList (realising back the memory). + // TBI 20250315 here I did it a bit differently than e.g. in GetHistogramWithWeights or in GetSparseHistogramWithWeights . + // If it's failing here, redo it in exactly the same way as I did it there. + hist->SetDirectory(0); + nua.fCustomNUAPDF[variable] = reinterpret_cast(hist->Clone()); + nua.fCustomNUAPDF[variable]->SetTitle(Form("%s", filePath)); + delete baseList; + + // TBI 20240501 if additional cosmetics is needed, it can be implemented here + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // void GetHistogramWithCustomNUA(const char* filePath, eNUAPDF variable) + + //============================================================ + + void StoreLabelsInPlaceholder() + { + // Storal all Test0 labels in the placeholder. + + // a) Initialize all counters; + // b) Fetch TObjArray with labels from an external file or from local hardwired values; + // c) Insanity check on labels; + // d) Finally, store the labels from external source into the placeholder. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // a) Initialize all counters; + int counter[gMaxCorrelator] = {0}; // is this safe? + for (int o = 0; o < gMaxCorrelator; o++) { + counter[o] = 0; + } // now it's safe :-) + + // b) Fetch TObjArray with labels from an external file or from local hardwired values: + TObjArray* oa = NULL; + if (t0.fUseDefaultLabels) { + oa = GetDefaultObjArrayWithLabels(t0.fWhichDefaultLabels.Data()); + } else { + + LOGF(info, "\033[1;33m%s at line %d: !!!! WARNING !!!! There is a large memory blow-up when calling function GetObjArrayWithLabels(...) !!!! WARNING !!!! \033[0m", __FUNCTION__, __LINE__); + + oa = GetObjArrayWithLabels(t0.fFileWithLabels.Data()); + // TBI 20250412 There is a large memory penalty in this call, confirmed for "local" and "ccdb" cases (most likely also for "alien", but I didn't test it yet) + // a) For the "local" case, it's related to the following minimal reproducer: + // TFile *f = new TFile("tmp.root", "read"); // memory blows up by > 50 MB + // f->Close(); delete f; f = nullptr; // memory stays > 50 MB + // b) Not clear why there is a blow-up for "ccdb" case, but it can be reproduced with this line: + // Service ccdb; + // ccdb->get("somePath"); + // c) TBI 20250412 document eventually also the "alien" case here + // ... + } + if (!oa) { + LOGF(info, "\033[1;33m fFileWithLabels = %s \033[0m", + t0.fFileWithLabels.Data()); + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + + // c) Insanity check on labels: + int nLabels = oa->GetEntries(); + // c1) Insanity check on number of labels: + if (nLabels <= 0) { + LOGF(fatal, "\033[1;31m%s at line %d : nLabels = %d \033[0m", __FUNCTION__, __LINE__, nLabels); + } + // c2) Here I am merely checking that harmonic larger than gMaxHarmonic was not requested: + for (int e = 0; e < nLabels; e++) { + TObjArray* temp = TString(oa->At(e)->GetName()).Tokenize(" "); + for (int h = 0; h < temp->GetEntries(); h++) { + if (std::abs(TString(temp->At(h)->GetName()).Atoi()) > gMaxHarmonic) { + LOGF(info, "\033[1;31m e = %d, label = %s, gMaxHarmonic = %d\033[0m", e, temp->At(h)->GetName(), static_cast(gMaxHarmonic)); + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } // if(TString(temp->At(h)->GetName()).Atoi() > gMaxHarmonic) { + } // for(int h = 0; h < temp->GetEntries(); h++) { + delete temp; // yes, otherwise it's a memory leak + } // for (int e = 0; e < nLabels; e++) { + // ... + + // d) Finally, store the labels from external source into the placeholder: + int order = -44; + for (int e = 0; e < nLabels; e++) { + TObjArray* temp = TString(oa->At(e)->GetName()).Tokenize(" "); + if (!temp) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + order = temp->GetEntries(); + delete temp; // yes, otherwise it's a memory leak + if (0 == order) { + continue; + } // empty lines, or the label format which is not supported + // 1-p => 0, 2-p => 1, etc.: + t0.fTest0Labels[order - 1][counter[order - 1]] = new TString(oa->At(e)->GetName()); // okay... + counter[order - 1]++; + } // for(int e=0; eGet("hist-name"). + + // Usage: TH1D *hist = (TH1D*) + // GetObjectFromList("some-valid-TList-pointer","some-object-name"); + + // Example 1: + // GetObjectFromList("some-valid-TList-pointer","some-object-name")->Draw(); + // // yes, for histograms and profiles this is just fine, at least in + // interpreted code + + // To do: + // a) Check if I can make it working in compiled mode. + // b) If I have objects with same name, nested in different TLists, what then? + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // Insanity checks: + if (!list) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + if (!objectName) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + if (0 == list->GetEntries()) { + return NULL; + } + + // The object is in the current base list: + TObject* objectFinal = + list->FindObject(objectName); // final object I am after + if (objectFinal) + return objectFinal; + + // Search for object recursively in the nested lists: + TObject* objectIter; // iterator object in the loop below + TIter next(list); + while ( + (objectIter = next())) // double round braces are to silent the warnings + { + if (TString(objectIter->ClassName()).EqualTo("TList")) { + objectFinal = GetObjectFromList(reinterpret_cast(objectIter), objectName); + if (objectFinal) + return objectFinal; + } + } // while(objectIter = next()) + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + return NULL; + + } // TObject* GetObjectFromList(TList *list, char *objectName) + + //============================================================ + + double Weight(const double& value, eWeights whichWeight) // value, integrated [phi,pt,eta] weight + { + // Determine particle weight. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + LOGF(info, "\033[1;32m value = %f\033[0m", value); + LOGF(info, "\033[1;32m variable = %d\033[0m", static_cast(whichWeight)); + } + + if (!pw.fWeightsHist[whichWeight]) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + + int bin = pw.fWeightsHist[whichWeight]->FindBin(value); + double weight = 0.; + if (bin > pw.fWeightsHist[whichWeight]->GetNbinsX()) { + weight = 0.; // we are in the overflow, ignore this particle TBI_20210524 is + // this really the correct procedure? + } else { + weight = pw.fWeightsHist[whichWeight]->GetBinContent(bin); + } + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + return weight; + + } // Weight(const double &value, eWeights whichWeight) // value, integrated [phi,pt,eta] weight + + //============================================================ + + double WeightFromSparse(eDiffWeightCategory dwc) + { + // Determine differential multidimensional particle weight using sparse histograms. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // *) Reduce dimensionality if possible, i.e. look up only the dimensions in sparse histogram which were requested in this analysis: + int dim = 1; // yes, because dimension 0 is always reserved for each category + switch (dwc) { + case eDWPhi: { + // Remember that ordering here has to resemble ordering in eDiffPhiWeights + pw.fFindBinVector[dwc]->AddAt(pbyp.fPhi, 0); // special treatment for phi in eDWPhi category + if (pw.fUseDiffPhiWeights[wPhiPtAxis]) { + pw.fFindBinVector[dwc]->AddAt(pbyp.fPt, dim++); + } + if (pw.fUseDiffPhiWeights[wPhiEtaAxis]) { + pw.fFindBinVector[dwc]->AddAt(pbyp.fEta, dim++); + } + if (pw.fUseDiffPhiWeights[wPhiChargeAxis]) { + pw.fFindBinVector[dwc]->AddAt(pbyp.fCharge, dim++); + } + if (pw.fUseDiffPhiWeights[wPhiCentralityAxis]) { + pw.fFindBinVector[dwc]->AddAt(ebye.fCentrality, dim++); + } + if (pw.fUseDiffPhiWeights[wPhiVertexZAxis]) { + pw.fFindBinVector[dwc]->AddAt(ebye.fVz, dim++); + } + // ... + break; + } + case eDWPt: { + pw.fFindBinVector[dwc]->AddAt(pbyp.fPt, 0); // special treatment for pt in eDWPt category + // Remember that ordering here has to resemble ordering in eDiffPtWeights + if (pw.fUseDiffPtWeights[wPtChargeAxis]) { + pw.fFindBinVector[dwc]->AddAt(pbyp.fCharge, dim++); + } + if (pw.fUseDiffPtWeights[wPtCentralityAxis]) { + pw.fFindBinVector[dwc]->AddAt(ebye.fCentrality, dim++); + } + // ... + break; + } + case eDWEta: { + pw.fFindBinVector[dwc]->AddAt(pbyp.fEta, 0); // special treatment for eta in eDWEta category + // Remember that ordering here has to resemble ordering in eDiffEtaWeights + if (pw.fUseDiffEtaWeights[wEtaChargeAxis]) { + pw.fFindBinVector[dwc]->AddAt(pbyp.fCharge, dim++); + } + if (pw.fUseDiffEtaWeights[wEtaCentralityAxis]) { + pw.fFindBinVector[dwc]->AddAt(ebye.fCentrality, dim++); + } + // ... + break; + } + default: { + LOGF(fatal, "\033[1;31m%s at line %d : This differential weight category, dwc = %d, is not supported yet. \033[0m", __FUNCTION__, __LINE__, static_cast(dwc)); + break; + } + } // switch(dwc) + + // *) Insanity check: + // **) ... + if (!pw.fDiffWeightsSparse[dwc]) { + LOGF(fatal, "\033[1;31m dwc = %d\033[0m", static_cast(dwc)); + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + + // **) Check that dimensions of vector I will use to fetch the right bin content and sparse histogram with weights do match: + if (tc.fInsanityCheckForEachParticle) { + if (pw.fFindBinVector[dwc]->GetSize() != pw.fDiffWeightsSparse[dwc]->GetNdimensions()) { + LOGF(fatal, "\033[1;31m dwc = %d\033[0m", static_cast(dwc)); + LOGF(fatal, "\033[1;31m pw.fFindBinVector[dwc]->GetSize() = %d\033[0m", pw.fFindBinVector[dwc]->GetSize()); + LOGF(fatal, "\033[1;31m pw.fDiffWeightsSparse[dwc]->GetNdimensions() = %d\033[0m", pw.fDiffWeightsSparse[dwc]->GetNdimensions()); + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + } // if(tc.fInsanityCheckForEachParticle) + + // *) okay, let's fetch the weight: + int bin = pw.fDiffWeightsSparse[dwc]->GetBin(pw.fFindBinVector[dwc]->GetArray()); // this is the general bin, corresponding to the actual multidimensional bin + // TBI 20250224 do I need some insanity check here, e.g. that bin is neither in overflow nor in underflow? + // If I decide to implement this, remember e.g. for 2D case that all bins of type (0,1), (0,2) ... are underflow of first variable, + // and all bins of type (1,0), (2,0), ... are underflow of second variable. Analogously for overflow. + // Each of these cases, however, have different global bin! + // Total number of linearized global bins for N-dimensional sparse = (N_1 + 2) * (N_2 + 2) * ... * (N_N + 2), + // where N_1 is number of bins in first dimension, etc. The offset + 2 in each case counts underflow and overflow. + // Mapping between 2D bins and linearized global bins goes as follows (for an example 2 x 3 histogram): + // 0,0 => 0 + // 1,0 => 1 + // 2,0 => 2 + // 3,0 => 3 + // 0,1 => 4 + // 1,1 => 5 + // ... + // 2,4 => 18 + // 3,4 => 19 + // So, for 2 x 3 histogram, there are (2+2) * (3+2) = 20 linearized global bins, indexed from 0 to 19. + // Remember that I need to loop first over y dimension, then nest inside the loop over x dimension, to achieve loop over global bins in consequtive order. Yes! + + double weight = pw.fDiffWeightsSparse[dwc]->GetBinContent(bin); + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + return weight; + + } // double WeightFromSparse(eDiffWeightCategory dwc) + + //============================================================ + + double DiffWeight(const double& valueY, const double& valueX, eqvectorKine variableX) + { + // !!! OBSOLETE FUNCTION !!! + + LOGF(info, "\033[1;33m%s at line %d: !!!! WARNING !!!! As of 20250520, this is an obsolete function, use double WeightFromSparse(...) instead !!!! WARNING !!!! \033[0m", __FUNCTION__, __LINE__); + + // Determine differential particle weight y(x). For the time being, "y = phi" always, but this can be generalized. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // *) Determine first to which bin the 'valueX' corresponds to. + // Based on that, I decide from which histogram I fetch weight for y. See MakeWeights.C + + // *) Mapping between enums "eqvectorKine" on one side, and enums "eAsFunctionOf" and "eDiffWeights" on the other: + eAsFunctionOf AFO_var = eAsFunctionOf_N; // this local variable determines the enum "eAsFunctionOf" which corresponds to enum "eqvectorKine" + eDiffWeights AFO_diffWeight = eDiffWeights_N; // this local variable determines the enum "eDiffWeights" which corresponds to enum "eqvectorKine" + if (variableX == PTq) { + AFO_var = AFO_PT; + AFO_diffWeight = wPHIPT; + } else if (variableX == ETAq) { + AFO_var = AFO_ETA; + AFO_diffWeight = wPHIETA; + } + + // *) Insanity checks on above settings: + if (AFO_var == eAsFunctionOf_N) { + LOGF(fatal, "\033[1;31m%s at line %d : AFO_var == eAsFunctionOf_N => add some more entries to the case statement \033[0m", __FUNCTION__, __LINE__); + } + if (AFO_diffWeight == eDiffWeights_N) { + LOGF(fatal, "\033[1;31m%s at line %d : AFO_diffWeight == eDiffWeights_N => add some more entries to the case statement \033[0m", __FUNCTION__, __LINE__); + } + + // *) Determine first to which bin the 'valueX' corresponds to. + // Based on that, I decide from which histogram I fetch weight for y. See MakeWeights.C + int binX = res.fResultsPro[AFO_var]->FindBin(valueX); + if (tc.fInsanityCheckForEachParticle) // enable only during debugging, as this check is computationally heavy. + { + if (binX < 1) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + // underflow. this means that I didn't use the same cuts now, and I was using when making the particle weights. Adjust the cuts. + } + if (binX > res.fResultsPro[AFO_var]->GetNbinsX()) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + // overflow. this means that I didn't use the same cuts now, and I was using when making the particle weights. Adjust the cuts. + } + } // if(tc.fInsanityCheckForEachParticle) + + // *) Finally, determine weight for y(x): + if (!pw.fDiffWeightsHist[AFO_diffWeight][binX - 1]) { + LOGF(info, "\033[1;32mvalueY = %f\033[0m", valueY); + LOGF(info, "\033[1;32mvalueX = %f\033[0m", valueX); + LOGF(info, "\033[1;32mvariableX = %d\033[0m", static_cast(variableX)); + LOGF(info, "\033[1;32mAFO_diffWeight = %d\033[0m", static_cast(AFO_diffWeight)); + LOGF(info, "\033[1;32mbinX = %d\033[0m", binX); + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + + int bin = pw.fDiffWeightsHist[AFO_diffWeight][binX - 1]->FindBin(valueY); // binX - 1, because I histogram for first bin in X is labeled with "[0]", etc. + if (tc.fInsanityCheckForEachParticle) // enable only during debugging, as this check is computationally heavy. + { + if (bin < 1) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + // underflow. this means that I didn't use the same cuts now, and I was using when making the particle weights. Adjust the cuts. + } + if (bin > pw.fDiffWeightsHist[AFO_diffWeight][binX - 1]->GetNbinsX()) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + // overflow. this means that I didn't use the same cuts now, and I was using when making the particle weights. Adjust the cuts. + } + } // if(tc.fInsanityCheckForEachParticle) + + double diffWeight = pw.fDiffWeightsHist[AFO_diffWeight][binX - 1]->GetBinContent(bin); + if (tc.fInsanityCheckForEachParticle) // enable only during debugging, as this check is computationally heavy. + { + if (diffWeight < 0.) { // or <= 0 ? TBI 20240324 rethink + LOGF(fatal, "\033[1;31m%s at line %d : diffWeight < 0\033[0m", __FUNCTION__, __LINE__); + } + } + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + return diffWeight; + + } // DiffWeight(const double &valueY, const double &valueX, eqvectorKine variableX) + + //============================================================ + + void GetParticleWeights() + { + // Get the particle weights. Call this function only once. + + // TBI 20231012 Here the current working assumption is that: + // 1) Corrections do not change within a given run; + // 2) Hyperloop proceeses the dataset one masterjob per run number. + // If any of these 2 assumptions are violated, this code will have to be modified. + + // a) Integrated weights; + // b) Differential weights; => TBI 20250225 this is now obsolete and superseeded with c), where I use more general approach with sparse histograms + // c) Differential phi weights using sparse histograms; + // d) Differential pt weights using sparse histograms; + // e) Differential eta weights using sparse histograms. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // a) Integrated weights: + // integrated phi weights: + if (pw.fUseWeights[wPHI]) { + TH1D* phiWeights = GetHistogramWithWeights(pw.fFileWithWeights.Data(), tc.fRunNumber.Data(), "phi"); + if (!phiWeights) { + LOGF(fatal, "in function \033[1;31m%s at line %d, phiWeights is NULL. Check the external file %s with particle weights\033[0m", __FUNCTION__, __LINE__, pw.fFileWithWeights.Data()); + } + SetWeightsHist(phiWeights, wPHI); + } + + // integrated pt weights: + if (pw.fUseWeights[wPT]) { + TH1D* ptWeights = GetHistogramWithWeights(pw.fFileWithWeights.Data(), tc.fRunNumber.Data(), "pt"); + if (!ptWeights) { + LOGF(fatal, "\033[1;31m%s at line %d : ptWeights is NULL. Check the external file %s with particle weights\033[0m", __FUNCTION__, __LINE__, pw.fFileWithWeights.Data()); + } + SetWeightsHist(ptWeights, wPT); + } + + // integrated eta weights: + if (pw.fUseWeights[wETA]) { + TH1D* etaWeights = GetHistogramWithWeights(pw.fFileWithWeights.Data(), tc.fRunNumber.Data(), "eta"); + if (!etaWeights) { + LOGF(fatal, "\033[1;31m%s at line %d : etaWeights is NULL. Check the external file %s with particle weights\033[0m", __FUNCTION__, __LINE__, pw.fFileWithWeights.Data()); + } + SetWeightsHist(etaWeights, wETA); + } + + // b) Differential weights: + // differential phi(pt) weights: + if (pw.fUseDiffWeights[wPHIPT]) { // TBI 20260217 obsolete branch, remove eventually + TH1D* phiptWeights = NULL; + int nPtBins = res.fResultsPro[AFO_PT]->GetXaxis()->GetNbins(); + for (int b = 0; b < nPtBins; b++) { + + // *) check if particles in this pt bin survive particle cuts in pt. If not, skip this bin, because for that pt bin weights are simply not available: + if (!(res.fResultsPro[AFO_PT]->GetBinLowEdge(b + 2) > pc.fdParticleCuts[ePt][eMin])) { + // this branch protects against the case when I am e.g. in pt bin [0.0,0.2], and pt cut is 0.2 < pt < 5.0 + LOGF(info, "\033[1;33m%s at line %d : you are requesting phi(pt) weight for pt bin = %d from (%f,%f), which is outside (below) pt phase space = (%f,%f). Skipping this bin. \033[0m", __FUNCTION__, __LINE__, b, res.fResultsPro[AFO_PT]->GetBinLowEdge(b + 1), res.fResultsPro[AFO_PT]->GetBinLowEdge(b + 2), pc.fdParticleCuts[ePt][eMin], pc.fdParticleCuts[ePt][eMax]); + continue; + } + if (!(res.fResultsPro[AFO_PT]->GetBinLowEdge(b + 1) < pc.fdParticleCuts[ePt][eMax])) { + // this branch protects against the case when I am e.g. in pt bin [5.0,10.0], and pt cut is 0.2 < pt < 5.0 + LOGF(info, "\033[1;33m%s at line %d : you are requesting phi(pt) weight for pt bin = %d from (%f,%f), which is outside (above) pt phase space = (%f,%f). Skipping this bin. \033[0m", __FUNCTION__, __LINE__, b, res.fResultsPro[AFO_PT]->GetBinLowEdge(b + 1), res.fResultsPro[AFO_PT]->GetBinLowEdge(b + 2), pc.fdParticleCuts[ePt][eMin], pc.fdParticleCuts[ePt][eMax]); + continue; + } + + // *) okay, this pt bin is within pt phase-space window, defined by pt cut: + phiptWeights = GetHistogramWithWeights(pw.fFileWithWeights.Data(), tc.fRunNumber.Data(), "phipt", b); + if (!phiptWeights) { + LOGF(fatal, "\033[1;31m%s at line %d : phiptWeights is NULL. Check the external file %s with particle weights\033[0m", __FUNCTION__, __LINE__, pw.fFileWithWeights.Data()); + } + + // *) okay, just use this histogram with weights: + SetDiffWeightsHist(phiptWeights, wPHIPT, b); + } + } // if (pw.fUseDiffWeights[wPHIPT]) { + + // differential phi(eta) weights: + if (pw.fUseDiffWeights[wPHIETA]) { // TBI 20260217 obsolete branch, remove eventually + TH1D* phietaWeights = NULL; + int nEtaBins = res.fResultsPro[AFO_ETA]->GetXaxis()->GetNbins(); + for (int b = 0; b < nEtaBins; b++) { + + // *) check if particles in this eta bin survive particle cuts in eta. If not, skip this bin, because for that eta bin weights are simply not available: + if (!(res.fResultsPro[AFO_ETA]->GetBinLowEdge(b + 2) > pc.fdParticleCuts[eEta][eMin])) { + // this branch protects against the case when I am e.g. in eta bin [-1.0,-0.8], and eta cut is -0.8 < eta < 0.8 + LOGF(info, "\033[1;33m%s at line %d : you are requesting phi(eta) weight for eta bin = %d from (%f,%f), which is outside (below) eta phase space = (%f,%f). Skipping this bin. \033[0m", __FUNCTION__, __LINE__, b, res.fResultsPro[AFO_ETA]->GetBinLowEdge(b + 1), res.fResultsPro[AFO_ETA]->GetBinLowEdge(b + 2), pc.fdParticleCuts[eEta][eMin], pc.fdParticleCuts[eEta][eMax]); + continue; + } + if (!(res.fResultsPro[AFO_ETA]->GetBinLowEdge(b + 1) < pc.fdParticleCuts[eEta][eMax])) { + // this branch protects against the case when I am e.g. in eta bin [0.8,1.0], and eta cut is 0.8 < eta < 1.0 + LOGF(info, "\033[1;33m%s at line %d : you are requesting phi(eta) weight for eta bin = %d from (%f,%f), which is outside (above) eta phase space = (%f,%f). Skipping this bin. \033[0m", __FUNCTION__, __LINE__, b, res.fResultsPro[AFO_ETA]->GetBinLowEdge(b + 1), res.fResultsPro[AFO_ETA]->GetBinLowEdge(b + 2), pc.fdParticleCuts[eEta][eMin], pc.fdParticleCuts[eEta][eMax]); + continue; + } + + // *) okay, this eta bin is within eta phase-space window, defined by eta cut: + phietaWeights = GetHistogramWithWeights(pw.fFileWithWeights.Data(), tc.fRunNumber.Data(), "phieta", b); + if (!phietaWeights) { + LOGF(fatal, "\033[1;31m%s at line %d : phietaWeights is NULL. Check the external file %s with particle weights\033[0m", __FUNCTION__, __LINE__, pw.fFileWithWeights.Data()); + } + + // *) okay, just use this histogram with weights: + SetDiffWeightsHist(phietaWeights, wPHIETA, b); + } // for(int b=0; bFindBin(value); + double weight = 0.; + if (bin > cw.fCentralityWeightsHist->GetNbinsX()) { + weight = 0.; // we are in the overflow, ignore this case + } else { + weight = cw.fCentralityWeightsHist->GetBinContent(bin) * cw.fCentralityWeightsHist->GetBinWidth(bin); // yes, since fCentralityWeightsHist is normalized p.d.f. + // (I ensure that with the macro which makes centrality weights) + } + + // In this context, it is assumed that centrality weight is a normalized probability (I ensure that with the macro which makes centrality weights): + if (weight < 0. || weight > 1.) { + LOGF(fatal, "\033[1;31m%s at line %d : weight = %f \033[0m", __FUNCTION__, __LINE__, weight); + } + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + return weight; + + } // double CentralityWeight(const double& value) + + //============================================================ + + bool MaxNumberOfEvents(eBeforeAfter ba) + { + // Check if max number of events was reached. Can be used for cut eNumberOfEvents (= total events, with ba = eBefore), and eSelectedEvents (ba = eAfter). + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // *) Return value: + bool reachedMaxNumberOfEvents = false; + + // *) Internal validation case (special treatment): + if (iv.fUseInternalValidation) { + if (eh.fEventHistograms[eNumberOfEvents][eSim][eAfter] && (eh.fEventHistograms[eNumberOfEvents][eSim][eAfter]->GetBinContent(1) == ec.fdEventCuts[eNumberOfEvents][eMax] || eh.fEventHistograms[eNumberOfEvents][eSim][eAfter]->GetBinContent(1) == ec.fdEventCuts[eSelectedEvents][eMax])) { + return true; + } else { + return false; + } + } + + // *) Determine from which histogram the relevant info will be taken: + int rs = -44; // reconstructed or simulated + if (tc.fProcess[eGenericRec] || tc.fProcess[eGenericRecSim]) { // yes, for tc.fProcess[eGenericRecSim] I take info from Rec part + rs = eRec; + } else if (tc.fProcess[eGenericSim]) { + rs = eSim; + } else { + LOGF(fatal, "\033[1;31m%s at line %d : not a single flag gProcess* is true \033[0m", __FUNCTION__, __LINE__); + } + + // *) Okay, do the thing: + switch (ba) { + case eBefore: { + if (eh.fEventHistograms[eNumberOfEvents][rs][eBefore] && eh.fEventHistograms[eNumberOfEvents][rs][eBefore]->GetBinContent(1) == ec.fdEventCuts[eNumberOfEvents][eMax]) { + reachedMaxNumberOfEvents = true; + } + break; + } + case eAfter: { + if (eh.fEventHistograms[eNumberOfEvents][rs][eAfter] && eh.fEventHistograms[eNumberOfEvents][rs][eAfter]->GetBinContent(1) == ec.fdEventCuts[eSelectedEvents][eMax]) { + reachedMaxNumberOfEvents = true; + } + break; + } + default: { + LOGF(fatal, "\033[1;31m%s at line %d : enum ba = %d is not supported yet. \033[0m", __FUNCTION__, __LINE__, static_cast(ba)); + break; + } + } // switch (ba) + + // *) Hasta la vista: + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + return reachedMaxNumberOfEvents; + + } // void MaxNumberOfEvents(eBeforeAfter ba) + + //============================================================ + + void PrintEventCounter(eBeforeAfter ba) + { + // Print how many events were processed by now. + // Remark: If I am processing RecSim, the counter is corresponding to Rec. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // *) Print or die: + switch (ba) { + case eBefore: { + if (!tc.fPlainPrintout) { + LOGF(info, "\033[1;32m%s : processing event %d ....\033[0m", __FUNCTION__, eh.fEventCounter[eTotal]); + } else { + LOGF(info, "%s : processing event %d ....", __FUNCTION__, eh.fEventCounter[eTotal]); + } + break; + } + case eAfter: { + if (!tc.fPlainPrintout) { + LOGF(info, "\033[1;32m%s : event passed all cuts %d/%d\033[0m", __FUNCTION__, eh.fEventCounter[eProcessed], eh.fEventCounter[eTotal]); + } else { + LOGF(info, "%s : event passed all cuts %d/%d", __FUNCTION__, eh.fEventCounter[eProcessed], eh.fEventCounter[eTotal]); + } + break; + } + default: { + LOGF(fatal, "\033[1;31m%s at line %d : enum ba = %d is not supported yet. \033[0m", __FUNCTION__, __LINE__, static_cast(ba)); + break; + } + } // switch (ba) + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // void PrintEventCounter(eBeforeAfter ba) + + //============================================================ + + void EventCounterForDryRun(eEventCounterForDryRun eVar) + { + // Simple utility function which either fills histogram with event count, or prints its current content. + // Remark: Use only in combination with tc.fDryRun = true, otherwise I might be filling the same histogram in different member functions, there is a protection below. + // It fills or prints per call, therefore I do not have to pass 'collision' objects, etc. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + if (!tc.fDryRun) { + LOGF(fatal, "\033[1;31m%s at line %d : for the time being, function EventCounterForDryRun(...) can be safely used only for tc.fDryRun = true \033[0m", __FUNCTION__, __LINE__); + } + + switch (eVar) { + case eFill: { + // Fill event counter: + !eh.fEventHistograms[eNumberOfEvents][eRec][eAfter] ? true : eh.fEventHistograms[eNumberOfEvents][eRec][eAfter]->Fill(0.5); + !eh.fEventHistograms[eNumberOfEvents][eSim][eAfter] ? true : eh.fEventHistograms[eNumberOfEvents][eSim][eAfter]->Fill(0.5); + break; + } + case ePrint: { + // Print current status of event counter: + // Remark: if I am processing RecSim, the counter is corresponding to Rec. + if (eh.fEventHistograms[eNumberOfEvents][eRec][eAfter]) { + LOGF(info, "Processing event %d (dry run) ....", static_cast(eh.fEventHistograms[eNumberOfEvents][eRec][eAfter]->GetBinContent(1))); + } else if (eh.fEventHistograms[eNumberOfEvents][eSim][eAfter]) { + LOGF(info, "Processing event %d (dry run) ....", static_cast(eh.fEventHistograms[eNumberOfEvents][eSim][eAfter]->GetBinContent(1))); + } + break; + } + default: { + LOGF(fatal, "\033[1;31m%s at line %d : enum eVar = %d is not supported yet in eEventCounter. \033[0m", __FUNCTION__, __LINE__, static_cast(eVar)); + break; + } + } // switch(eVar) + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // void EventCounterForDryRun(eEventCounterForDryRun eVar) + + //============================================================ + + const char* FancyFormatting(const char* name) + { + // Simple utility function to convert ordinary name into fancier formatting. + // If I change something in the formatting here, check if that fancy formatting was hardwired elsewhere, e.g. in void insanitizeDiffWeightsSparse(...) + + // :ff + + // Examples: + // 1. use LaTeX syntax (as supported by ROOT!), for the case when it's possible (e.g. "Phi" => "#{varphi}"); + // 2. add additional information to defalt name (e.g. "Centrality" => "Centrality (V0M)" + // 3. ... + + if (tc.fVerboseUtility) { + StartFunction(__FUNCTION__); + LOGF(info, "\033[1;32m const char* name = %s\033[0m", name); + } + + // By default, do nothing and return the same thing: + const char* fancyFormatting = name; + + // Special cases supported by now: + if (TString(name).EqualTo("Phi", TString::kIgnoreCase)) { + fancyFormatting = "#varphi"; + } else if (TString(name).EqualTo("Pt", TString::kIgnoreCase)) { + fancyFormatting = "p_{T}"; + } else if (TString(name).EqualTo("Eta", TString::kIgnoreCase)) { + fancyFormatting = "#eta"; + } else if (TString(name).EqualTo("VertexX")) { + fancyFormatting = "V_{x}"; + } else if (TString(name).EqualTo("VertexY")) { + fancyFormatting = "V_{y}"; + } else if (TString(name).EqualTo("VertexZ")) { + fancyFormatting = "V_{z}"; + } else if (TString(name).EqualTo("TotalMultiplicity")) { + fancyFormatting = "TotalMultiplicity (tracks.size())"; + } else if (TString(name).EqualTo("Multiplicity", TString::kIgnoreCase)) { + fancyFormatting = Form("Multiplicity (%s)", ec.fsEventCuts[eMultiplicityEstimator].Data()); + } else if (TString(name).EqualTo("ReferenceMultiplicity")) { + fancyFormatting = Form("ReferenceMultiplicity (%s)", ec.fsEventCuts[eReferenceMultiplicityEstimator].Data()); + } else if (TString(name).EqualTo("Centrality", TString::kIgnoreCase)) { + TString tmp = ec.fsEventCuts[eCentralityEstimator]; // I have to introduce local TString tmp, because ReplaceAll replaces in-place + if (tmp.BeginsWith("CentRun2")) { + fancyFormatting = Form("Centrality (%s)", tmp.ReplaceAll("CentRun2", "").Data()); // "CentRun2V0M" => "Centrality (V0M)" + } else if (tmp.BeginsWith("Cent")) { + fancyFormatting = Form("Centrality (%s)", tmp.ReplaceAll("Cent", "").Data()); // "CentFT0C" => "Centrality (FT0C)" + } else { + LOGF(fatal, "\033[1;31m%s at line %d : the case tmp = \"%s\" is not supported yet\033[0m", __FUNCTION__, __LINE__, tmp.Data()); + } + } else if (TString(name).EqualTo("Trigger")) { + fancyFormatting = Form("Trigger (%s)", ec.fsEventCuts[eTrigger].Data()); + } else if (TString(name).EqualTo("TrackOccupancyInTimeRange")) { + fancyFormatting = "trackOccupancyInTimeRange()"; + } else if (TString(name).EqualTo("FT0COccupancyInTimeRange")) { + fancyFormatting = "ft0cOccupancyInTimeRange()"; + } else if (TString(name).EqualTo("Occupancy", TString::kIgnoreCase)) { + fancyFormatting = Form("Occupancy (%s)", ec.fsEventCuts[eOccupancyEstimator].Data()); + } else if (TString(name).EqualTo("InteractionRate", TString::kIgnoreCase) || TString(name).EqualTo("Interaction Rate", TString::kIgnoreCase)) { + fancyFormatting = "Interaction Rate [kHz]"; // TBI 20241127 do I leave kHz hardwired here? + } else if (TString(name).EqualTo("CurrentRunDuration", TString::kIgnoreCase) || TString(name).EqualTo("Current Run Duration", TString::kIgnoreCase)) { + fancyFormatting = "Current run duration [s] (i.e. time in seconds since start of run)"; + } + + if (tc.fVerboseUtility) { + ExitFunction(__FUNCTION__); + } + + return fancyFormatting; + + } // const char* FancyFormatting(const char *name) + + //============================================================ + + double CalculateCustomNestedLoops(TArrayI* harmonics) + { + // For the specified harmonics, get the correlation from nested loops. + // Order of correlator is the number of harmonics, i.e. the number of elements in an array. + + // a) Determine the order of correlator; + // b) Custom nested loop; + // c) Return value. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + if (!harmonics) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + + int nParticles = ebye.fSelectedTracks; + + // a) Determine the order of correlator; + int order = harmonics->GetSize(); + if (0 == order || order > gMaxCorrelator) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + if (nl.fMaxNestedLoop > 0 && nl.fMaxNestedLoop < order) { + LOGF(info, " nl.fMaxNestedLoop > 0 && nl.fMaxNestedLoop < order, where nl.fMaxNestedLoop = %d, order = %d", nl.fMaxNestedLoop, order); + return 0.; // TBI 20240405 Is this really safe here? Re-think... + } + + // b) Custom nested loop: + TProfile* profile = new TProfile("profile", "", 1, 0., 1.); // helper profile to get all averages automatically + // profile->Sumw2(); + double value = 0.; // cos of current multiplet + double weight = 1.; // weight of current multiplet + for (int i1 = 0; i1 < nParticles; i1++) { + double dPhi1 = nl.ftaNestedLoops[0]->GetAt(i1); + double dW1 = nl.ftaNestedLoops[1]->GetAt(i1); + if (1 == order) { + value = std::cos(harmonics->GetAt(0) * dPhi1); + weight = dW1; + profile->Fill(0.5, value, weight); + continue; + } + for (int i2 = 0; i2 < nParticles; i2++) { + if (i2 == i1) { + continue; + } + double dPhi2 = nl.ftaNestedLoops[0]->GetAt(i2); + double dW2 = nl.ftaNestedLoops[1]->GetAt(i2); + if (2 == order) { + value = std::cos(harmonics->GetAt(0) * dPhi1 + harmonics->GetAt(1) * dPhi2); + weight = dW1 * dW2; + profile->Fill(0.5, value, weight); + continue; + } + for (int i3 = 0; i3 < nParticles; i3++) { + if (i3 == i1 || i3 == i2) { + continue; + } + double dPhi3 = nl.ftaNestedLoops[0]->GetAt(i3); + double dW3 = nl.ftaNestedLoops[1]->GetAt(i3); + if (3 == order) { + value = std::cos(harmonics->GetAt(0) * dPhi1 + harmonics->GetAt(1) * dPhi2 + harmonics->GetAt(2) * dPhi3); + weight = dW1 * dW2 * dW3; + profile->Fill(0.5, value, weight); + continue; + } + for (int i4 = 0; i4 < nParticles; i4++) { + if (i4 == i1 || i4 == i2 || i4 == i3) { + continue; + } + double dPhi4 = nl.ftaNestedLoops[0]->GetAt(i4); + double dW4 = nl.ftaNestedLoops[1]->GetAt(i4); + if (4 == order) { + value = std::cos(harmonics->GetAt(0) * dPhi1 + harmonics->GetAt(1) * dPhi2 + harmonics->GetAt(2) * dPhi3 + harmonics->GetAt(3) * dPhi4); + weight = dW1 * dW2 * dW3 * dW4; + profile->Fill(0.5, value, weight); + continue; + } + for (int i5 = 0; i5 < nParticles; i5++) { + if (i5 == i1 || i5 == i2 || i5 == i3 || i5 == i4) { + continue; + } + double dPhi5 = nl.ftaNestedLoops[0]->GetAt(i5); + double dW5 = nl.ftaNestedLoops[1]->GetAt(i5); + if (5 == order) { + value = std::cos(harmonics->GetAt(0) * dPhi1 + harmonics->GetAt(1) * dPhi2 + harmonics->GetAt(2) * dPhi3 + harmonics->GetAt(3) * dPhi4 + harmonics->GetAt(4) * dPhi5); + weight = dW1 * dW2 * dW3 * dW4 * dW5; + profile->Fill(0.5, value, weight); + continue; + } + for (int i6 = 0; i6 < nParticles; i6++) { + if (i6 == i1 || i6 == i2 || i6 == i3 || i6 == i4 || i6 == i5) { + continue; + } + double dPhi6 = nl.ftaNestedLoops[0]->GetAt(i6); + double dW6 = nl.ftaNestedLoops[1]->GetAt(i6); + if (6 == order) { + value = std::cos(harmonics->GetAt(0) * dPhi1 + harmonics->GetAt(1) * dPhi2 + harmonics->GetAt(2) * dPhi3 + harmonics->GetAt(3) * dPhi4 + harmonics->GetAt(4) * dPhi5 + harmonics->GetAt(5) * dPhi6); + weight = dW1 * dW2 * dW3 * dW4 * dW5 * dW6; + profile->Fill(0.5, value, weight); + continue; + } + for (int i7 = 0; i7 < nParticles; i7++) { + if (i7 == i1 || i7 == i2 || i7 == i3 || i7 == i4 || i7 == i5 || i7 == i6) { + continue; + } + double dPhi7 = nl.ftaNestedLoops[0]->GetAt(i7); + double dW7 = nl.ftaNestedLoops[1]->GetAt(i7); + if (7 == order) { + value = std::cos(harmonics->GetAt(0) * dPhi1 + harmonics->GetAt(1) * dPhi2 + harmonics->GetAt(2) * dPhi3 + harmonics->GetAt(3) * dPhi4 + harmonics->GetAt(4) * dPhi5 + harmonics->GetAt(5) * dPhi6 + harmonics->GetAt(6) * dPhi7); + weight = dW1 * dW2 * dW3 * dW4 * dW5 * dW6 * dW7; + profile->Fill(0.5, value, weight); + continue; + } + for (int i8 = 0; i8 < nParticles; i8++) { + if (i8 == i1 || i8 == i2 || i8 == i3 || i8 == i4 || i8 == i5 || i8 == i6 || i8 == i7) { + continue; + } + double dPhi8 = nl.ftaNestedLoops[0]->GetAt(i8); + double dW8 = nl.ftaNestedLoops[1]->GetAt(i8); + if (8 == order) { + value = std::cos(harmonics->GetAt(0) * dPhi1 + harmonics->GetAt(1) * dPhi2 + harmonics->GetAt(2) * dPhi3 + harmonics->GetAt(3) * dPhi4 + harmonics->GetAt(4) * dPhi5 + harmonics->GetAt(5) * dPhi6 + harmonics->GetAt(6) * dPhi7 + harmonics->GetAt(7) * dPhi8); + weight = dW1 * dW2 * dW3 * dW4 * dW5 * dW6 * dW7 * dW8; + profile->Fill(0.5, value, weight); + continue; + } + for (int i9 = 0; i9 < nParticles; i9++) { + if (i9 == i1 || i9 == i2 || i9 == i3 || i9 == i4 || i9 == i5 || i9 == i6 || i9 == i7 || i9 == i8) { + continue; + } + double dPhi9 = nl.ftaNestedLoops[0]->GetAt(i9); + double dW9 = nl.ftaNestedLoops[1]->GetAt(i9); + if (9 == order) { + value = std::cos(harmonics->GetAt(0) * dPhi1 + harmonics->GetAt(1) * dPhi2 + harmonics->GetAt(2) * dPhi3 + harmonics->GetAt(3) * dPhi4 + harmonics->GetAt(4) * dPhi5 + harmonics->GetAt(5) * dPhi6 + harmonics->GetAt(6) * dPhi7 + harmonics->GetAt(7) * dPhi8 + harmonics->GetAt(8) * dPhi9); + weight = dW1 * dW2 * dW3 * dW4 * dW5 * dW6 * dW7 * dW8 * dW9; + profile->Fill(0.5, value, weight); + continue; + } + for (int i10 = 0; i10 < nParticles; i10++) { + if (i10 == i1 || i10 == i2 || i10 == i3 || i10 == i4 || i10 == i5 || i10 == i6 || i10 == i7 || i10 == i8 || i10 == i9) { + continue; + } + double dPhi10 = nl.ftaNestedLoops[0]->GetAt(i10); + double dW10 = nl.ftaNestedLoops[1]->GetAt(i10); + if (10 == order) { + value = std::cos(harmonics->GetAt(0) * dPhi1 + harmonics->GetAt(1) * dPhi2 + harmonics->GetAt(2) * dPhi3 + harmonics->GetAt(3) * dPhi4 + harmonics->GetAt(4) * dPhi5 + harmonics->GetAt(5) * dPhi6 + harmonics->GetAt(6) * dPhi7 + harmonics->GetAt(7) * dPhi8 + harmonics->GetAt(8) * dPhi9 + harmonics->GetAt(9) * dPhi10); + weight = dW1 * dW2 * dW3 * dW4 * dW5 * dW6 * dW7 * dW8 * dW9 * dW10; + profile->Fill(0.5, value, weight); + continue; + } + for (int i11 = 0; i11 < nParticles; i11++) { + if (i11 == i1 || i11 == i2 || i11 == i3 || i11 == i4 || i11 == i5 || i11 == i6 || i11 == i7 || i11 == i8 || i11 == i9 || i11 == i10) { + continue; + } + double dPhi11 = nl.ftaNestedLoops[0]->GetAt(i11); + double dW11 = nl.ftaNestedLoops[1]->GetAt(i11); + if (11 == order) { + value = std::cos(harmonics->GetAt(0) * dPhi1 + harmonics->GetAt(1) * dPhi2 + harmonics->GetAt(2) * dPhi3 + harmonics->GetAt(3) * dPhi4 + harmonics->GetAt(4) * dPhi5 + harmonics->GetAt(5) * dPhi6 + harmonics->GetAt(6) * dPhi7 + harmonics->GetAt(7) * dPhi8 + harmonics->GetAt(8) * dPhi9 + harmonics->GetAt(9) * dPhi10 + harmonics->GetAt(10) * dPhi11); + weight = dW1 * dW2 * dW3 * dW4 * dW5 * dW6 * dW7 * dW8 * dW9 * dW10 * dW11; + profile->Fill(0.5, value, weight); + continue; + } + for (int i12 = 0; i12 < nParticles; i12++) { + if (i12 == i1 || i12 == i2 || i12 == i3 || i12 == i4 || i12 == i5 || i12 == i6 || i12 == i7 || i12 == i8 || i12 == i9 || i12 == i10 || i12 == i11) { + continue; + } + double dPhi12 = nl.ftaNestedLoops[0]->GetAt(i12); + double dW12 = nl.ftaNestedLoops[1]->GetAt(i12); + if (12 == order) { + value = std::cos(harmonics->GetAt(0) * dPhi1 + harmonics->GetAt(1) * dPhi2 + harmonics->GetAt(2) * dPhi3 + harmonics->GetAt(3) * dPhi4 + harmonics->GetAt(4) * dPhi5 + harmonics->GetAt(5) * dPhi6 + harmonics->GetAt(6) * dPhi7 + harmonics->GetAt(7) * dPhi8 + harmonics->GetAt(8) * dPhi9 + harmonics->GetAt(9) * dPhi10 + harmonics->GetAt(10) * dPhi11 + harmonics->GetAt(11) * dPhi12); + weight = dW1 * dW2 * dW3 * dW4 * dW5 * dW6 * dW7 * dW8 * dW9 * dW10 * dW11 * dW12; + profile->Fill(0.5, value, weight); + continue; + } + + // ... it's easy to continue the above pattern here + + } // for(int i12=0; i12GetBinContent(1); + delete profile; + profile = NULL; + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + return finalValue; + + } // double CalculateCustomNestedLoops(TArrayI *harmonics) + + //============================================================ + + double CalculateKineCustomNestedLoops(TArrayI* harmonics, eAsFunctionOf AFO_variable, int bin) + { + // !!! OBSOLETE FUNCTION !!! + + LOGF(info, "\033[1;33m%s at line %d: !!!! WARNING !!!! As of 20250529, this is an obsolete function, use double CalculateKineCustomNestedLoops(TArrayI* harmonics, eqvectorKine kineVarChoice, int bin) instead !!!! WARNING !!!! \033[0m", __FUNCTION__, __LINE__); + + // For the specified harmonics, kine variable, and bin, get the correlation from nested loops. + // Order of correlator is the number of harmonics, i.e. the number of elements in an array. + + // a) Determine the order of correlator; + // b) Custom nested loop; + // c) Return value. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + if (!harmonics) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + + // *) ... + eqvectorKine qvKine = eqvectorKine_N; // which component of q-vector + TString kineVarName = ""; + switch (AFO_variable) { + case AFO_PT: { + qvKine = PTq; + kineVarName = "pt"; + break; + } + case AFO_ETA: { + qvKine = ETAq; + kineVarName = "eta"; + break; + } + case AFO_CHARGE: { + qvKine = CHARGEq; + kineVarName = "charge"; + break; + } + default: { + LOGF(fatal, "\033[1;31m%s at line %d : This AFO_variable = %d is not supported yet. \033[0m", __FUNCTION__, __LINE__, static_cast(AFO_variable)); + break; + } + } // switch(AFO_variable) + + // *) Insanity checks on above settings: + if (qvKine == eqvectorKine_N) { + LOGF(fatal, "\033[1;31m%s at line %d : qvKine == eqvectorKine_N => add some more entries to the case statement \033[0m", __FUNCTION__, __LINE__); + } + + if (0 > bin || res.fResultsPro[AFO_variable]->GetNbinsX() < bin) { // this 'bin' starts from 0, i.e. this is an array bin + // either underflow or overflow is hit, meaning that histogram is booked in narrower range than cuts + LOGF(fatal, "\033[1;31m%s at line %d => AFO_variable = %d, bin = %d\033[0m", __FUNCTION__, __LINE__, static_cast(AFO_variable), bin); + } + + // Get the number of particles in this kine bin: + int nParticles = 0; + for (int i = 0; i < nl.ftaNestedLoopsKine[qvKine][bin][0]->GetSize(); i++) { + if (std::abs(nl.ftaNestedLoopsKine[qvKine][bin][0]->GetAt(i)) > 0.) { + nParticles++; + } + } + + // 'qvKine' is enum eqvectorKine: + if (!res.fResultsPro[AFO_variable]) { + LOGF(fatal, "\033[1;31m%s at line %d : AFO_variable = %d, bin = %d \033[0m", __FUNCTION__, __LINE__, static_cast(AFO_variable), bin); + } + + LOGF(info, " Processing qvKine = %d (vs. %s), nParticles in this kine bin = %d, bin range = [%f,%f) ....", static_cast(qvKine), kineVarName.Data(), nParticles, res.fResultsPro[AFO_variable]->GetBinLowEdge(bin + 1), res.fResultsPro[AFO_variable]->GetBinLowEdge(bin + 2)); + + // a) Determine the order of correlator; + int order = harmonics->GetSize(); + if (0 == order || order > gMaxCorrelator) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + if (order > nParticles) { + LOGF(info, " There is no enough particles in this bin to calculate the requested correlator"); + return 0.; // TBI 20240405 Is this really safe here? Re-think... + } + if (nl.fMaxNestedLoop > 0 && nl.fMaxNestedLoop < order) { + LOGF(info, " nl.fMaxNestedLoop > 0 && nl.fMaxNestedLoop < order, where nl.fMaxNestedLoop = %d, order = %d", nl.fMaxNestedLoop, order); + return 0.; // TBI 20240405 Is this really safe here? Re-think... + } + + // b) Custom nested loop: + TProfile* profile = new TProfile("profile", "", 1, 0., 1.); // helper profile to get all averages automatically + // profile->Sumw2(); + double value = 0.; // cos of current multiplet + double weight = 1.; // weight of current multiplet + for (int i1 = 0; i1 < nParticles; i1++) { + double dPhi1 = nl.ftaNestedLoopsKine[qvKine][bin][0]->GetAt(i1); + double dW1 = nl.ftaNestedLoopsKine[qvKine][bin][1]->GetAt(i1); + if (1 == order) { + value = std::cos(harmonics->GetAt(0) * dPhi1); + weight = dW1; + profile->Fill(0.5, value, weight); + continue; + } + for (int i2 = 0; i2 < nParticles; i2++) { + if (i2 == i1) { + continue; + } + double dPhi2 = nl.ftaNestedLoopsKine[qvKine][bin][0]->GetAt(i2); + double dW2 = nl.ftaNestedLoopsKine[qvKine][bin][1]->GetAt(i2); + if (2 == order) { + value = std::cos(harmonics->GetAt(0) * dPhi1 + harmonics->GetAt(1) * dPhi2); + weight = dW1 * dW2; + profile->Fill(0.5, value, weight); + continue; + } + for (int i3 = 0; i3 < nParticles; i3++) { + if (i3 == i1 || i3 == i2) { + continue; + } + double dPhi3 = nl.ftaNestedLoopsKine[qvKine][bin][0]->GetAt(i3); + double dW3 = nl.ftaNestedLoopsKine[qvKine][bin][1]->GetAt(i3); + if (3 == order) { + value = std::cos(harmonics->GetAt(0) * dPhi1 + harmonics->GetAt(1) * dPhi2 + harmonics->GetAt(2) * dPhi3); + weight = dW1 * dW2 * dW3; + profile->Fill(0.5, value, weight); + continue; + } + for (int i4 = 0; i4 < nParticles; i4++) { + if (i4 == i1 || i4 == i2 || i4 == i3) { + continue; + } + double dPhi4 = nl.ftaNestedLoopsKine[qvKine][bin][0]->GetAt(i4); + double dW4 = nl.ftaNestedLoopsKine[qvKine][bin][1]->GetAt(i4); + if (4 == order) { + value = std::cos(harmonics->GetAt(0) * dPhi1 + harmonics->GetAt(1) * dPhi2 + harmonics->GetAt(2) * dPhi3 + harmonics->GetAt(3) * dPhi4); + weight = dW1 * dW2 * dW3 * dW4; + profile->Fill(0.5, value, weight); + continue; + } + for (int i5 = 0; i5 < nParticles; i5++) { + if (i5 == i1 || i5 == i2 || i5 == i3 || i5 == i4) { + continue; + } + double dPhi5 = nl.ftaNestedLoopsKine[qvKine][bin][0]->GetAt(i5); + double dW5 = nl.ftaNestedLoopsKine[qvKine][bin][1]->GetAt(i5); + if (5 == order) { + value = std::cos(harmonics->GetAt(0) * dPhi1 + harmonics->GetAt(1) * dPhi2 + harmonics->GetAt(2) * dPhi3 + harmonics->GetAt(3) * dPhi4 + harmonics->GetAt(4) * dPhi5); + weight = dW1 * dW2 * dW3 * dW4 * dW5; + profile->Fill(0.5, value, weight); + continue; + } + for (int i6 = 0; i6 < nParticles; i6++) { + if (i6 == i1 || i6 == i2 || i6 == i3 || i6 == i4 || i6 == i5) { + continue; + } + double dPhi6 = nl.ftaNestedLoopsKine[qvKine][bin][0]->GetAt(i6); + double dW6 = nl.ftaNestedLoopsKine[qvKine][bin][1]->GetAt(i6); + if (6 == order) { + value = std::cos(harmonics->GetAt(0) * dPhi1 + harmonics->GetAt(1) * dPhi2 + harmonics->GetAt(2) * dPhi3 + harmonics->GetAt(3) * dPhi4 + harmonics->GetAt(4) * dPhi5 + harmonics->GetAt(5) * dPhi6); + weight = dW1 * dW2 * dW3 * dW4 * dW5 * dW6; + profile->Fill(0.5, value, weight); + continue; + } + for (int i7 = 0; i7 < nParticles; i7++) { + if (i7 == i1 || i7 == i2 || i7 == i3 || i7 == i4 || i7 == i5 || i7 == i6) { + continue; + } + double dPhi7 = nl.ftaNestedLoopsKine[qvKine][bin][0]->GetAt(i7); + double dW7 = nl.ftaNestedLoopsKine[qvKine][bin][1]->GetAt(i7); + if (7 == order) { + value = std::cos(harmonics->GetAt(0) * dPhi1 + harmonics->GetAt(1) * dPhi2 + harmonics->GetAt(2) * dPhi3 + harmonics->GetAt(3) * dPhi4 + harmonics->GetAt(4) * dPhi5 + harmonics->GetAt(5) * dPhi6 + harmonics->GetAt(6) * dPhi7); + weight = dW1 * dW2 * dW3 * dW4 * dW5 * dW6 * dW7; + profile->Fill(0.5, value, weight); + continue; + } + for (int i8 = 0; i8 < nParticles; i8++) { + if (i8 == i1 || i8 == i2 || i8 == i3 || i8 == i4 || i8 == i5 || i8 == i6 || i8 == i7) { + continue; + } + double dPhi8 = nl.ftaNestedLoopsKine[qvKine][bin][0]->GetAt(i8); + double dW8 = nl.ftaNestedLoopsKine[qvKine][bin][1]->GetAt(i8); + if (8 == order) { + value = std::cos(harmonics->GetAt(0) * dPhi1 + harmonics->GetAt(1) * dPhi2 + harmonics->GetAt(2) * dPhi3 + harmonics->GetAt(3) * dPhi4 + harmonics->GetAt(4) * dPhi5 + harmonics->GetAt(5) * dPhi6 + harmonics->GetAt(6) * dPhi7 + harmonics->GetAt(7) * dPhi8); + weight = dW1 * dW2 * dW3 * dW4 * dW5 * dW6 * dW7 * dW8; + profile->Fill(0.5, value, weight); + continue; + } + for (int i9 = 0; i9 < nParticles; i9++) { + if (i9 == i1 || i9 == i2 || i9 == i3 || i9 == i4 || i9 == i5 || i9 == i6 || i9 == i7 || i9 == i8) { + continue; + } + double dPhi9 = nl.ftaNestedLoopsKine[qvKine][bin][0]->GetAt(i9); + double dW9 = nl.ftaNestedLoopsKine[qvKine][bin][1]->GetAt(i9); + if (9 == order) { + value = std::cos(harmonics->GetAt(0) * dPhi1 + harmonics->GetAt(1) * dPhi2 + harmonics->GetAt(2) * dPhi3 + harmonics->GetAt(3) * dPhi4 + harmonics->GetAt(4) * dPhi5 + harmonics->GetAt(5) * dPhi6 + harmonics->GetAt(6) * dPhi7 + harmonics->GetAt(7) * dPhi8 + harmonics->GetAt(8) * dPhi9); + weight = dW1 * dW2 * dW3 * dW4 * dW5 * dW6 * dW7 * dW8 * dW9; + profile->Fill(0.5, value, weight); + continue; + } + for (int i10 = 0; i10 < nParticles; i10++) { + if (i10 == i1 || i10 == i2 || i10 == i3 || i10 == i4 || i10 == i5 || i10 == i6 || i10 == i7 || i10 == i8 || i10 == i9) { + continue; + } + double dPhi10 = nl.ftaNestedLoopsKine[qvKine][bin][0]->GetAt(i10); + double dW10 = nl.ftaNestedLoopsKine[qvKine][bin][1]->GetAt(i10); + if (10 == order) { + value = std::cos(harmonics->GetAt(0) * dPhi1 + harmonics->GetAt(1) * dPhi2 + harmonics->GetAt(2) * dPhi3 + harmonics->GetAt(3) * dPhi4 + harmonics->GetAt(4) * dPhi5 + harmonics->GetAt(5) * dPhi6 + harmonics->GetAt(6) * dPhi7 + harmonics->GetAt(7) * dPhi8 + harmonics->GetAt(8) * dPhi9 + harmonics->GetAt(9) * dPhi10); + weight = dW1 * dW2 * dW3 * dW4 * dW5 * dW6 * dW7 * dW8 * dW9 * dW10; + profile->Fill(0.5, value, weight); + continue; + } + for (int i11 = 0; i11 < nParticles; i11++) { + if (i11 == i1 || i11 == i2 || i11 == i3 || i11 == i4 || i11 == i5 || i11 == i6 || i11 == i7 || i11 == i8 || i11 == i9 || i11 == i10) { + continue; + } + double dPhi11 = nl.ftaNestedLoopsKine[qvKine][bin][0]->GetAt(i11); + double dW11 = nl.ftaNestedLoopsKine[qvKine][bin][1]->GetAt(i11); + if (11 == order) { + value = std::cos(harmonics->GetAt(0) * dPhi1 + harmonics->GetAt(1) * dPhi2 + harmonics->GetAt(2) * dPhi3 + harmonics->GetAt(3) * dPhi4 + harmonics->GetAt(4) * dPhi5 + harmonics->GetAt(5) * dPhi6 + harmonics->GetAt(6) * dPhi7 + harmonics->GetAt(7) * dPhi8 + harmonics->GetAt(8) * dPhi9 + harmonics->GetAt(9) * dPhi10 + harmonics->GetAt(10) * dPhi11); + weight = dW1 * dW2 * dW3 * dW4 * dW5 * dW6 * dW7 * dW8 * dW9 * dW10 * dW11; + profile->Fill(0.5, value, weight); + continue; + } + for (int i12 = 0; i12 < nParticles; i12++) { + if (i12 == i1 || i12 == i2 || i12 == i3 || i12 == i4 || i12 == i5 || i12 == i6 || i12 == i7 || i12 == i8 || i12 == i9 || i12 == i10 || i12 == i11) { + continue; + } + double dPhi12 = nl.ftaNestedLoopsKine[qvKine][bin][0]->GetAt(i12); + double dW12 = nl.ftaNestedLoopsKine[qvKine][bin][1]->GetAt(i12); + if (12 == order) { + value = std::cos(harmonics->GetAt(0) * dPhi1 + harmonics->GetAt(1) * dPhi2 + harmonics->GetAt(2) * dPhi3 + harmonics->GetAt(3) * dPhi4 + harmonics->GetAt(4) * dPhi5 + harmonics->GetAt(5) * dPhi6 + harmonics->GetAt(6) * dPhi7 + harmonics->GetAt(7) * dPhi8 + harmonics->GetAt(8) * dPhi9 + harmonics->GetAt(9) * dPhi10 + harmonics->GetAt(10) * dPhi11 + harmonics->GetAt(11) * dPhi12); + weight = dW1 * dW2 * dW3 * dW4 * dW5 * dW6 * dW7 * dW8 * dW9 * dW10 * dW11 * dW12; + profile->Fill(0.5, value, weight); + continue; + } + + // ... it's easy to continue the above pattern here + + } // for(int i12=0; i12GetBinContent(1); + delete profile; + profile = NULL; + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + return finalValue; + + } // double CalculateKineCustomNestedLoops(TArrayI *harmonics, eAsFunctionOf AFO_variable, int bin) + + //============================================================ + + double CalculateKineCustomNestedLoops(TArrayI* harmonics, eqvectorKine kineVarChoice, int bin) + { + // For the specified harmonics, kine variable, and bin, get the correlation from nested loops. + // Order of correlator is the number of harmonics, i.e. the number of elements in an array. + + // a) Determine the order of correlator; + // b) Custom nested loop; + // c) Return value. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + if (!harmonics) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + + // TBI 20250529 add protection for b in underflow or overflow + + // Get the number of particles in this kine bin: + int nParticles = 0; + for (int i = 0; i < nl.ftaNestedLoopsKine[kineVarChoice][bin][0]->GetSize(); i++) { + if (std::abs(nl.ftaNestedLoopsKine[kineVarChoice][bin][0]->GetAt(i)) > 0.) { + nParticles++; + } + } + + // It doesn't hurt to do here insanity check on the number of particles, in case I have already calculated it independently when calculating diff. q-vectors: + if (qv.fCalculateqvectorsKineAny && qv.fqvectorEntries[kineVarChoice][bin] > 0) { // TBI 20250602 I think this chained condition is ok, but re-think nevertheless + if (!(nParticles == qv.fqvectorEntries[kineVarChoice][bin])) { + LOGF(fatal, "\033[1;31m%s at line %d : nParticles = %d, qv.fqvectorEntries[kineVarChoice][bin] = %d, kineVarChoices = %d (%s), bin = %d\033[0m", __FUNCTION__, __LINE__, nParticles, qv.fqvectorEntries[kineVarChoice][bin], static_cast(kineVarChoice), StringKineMap(kineVarChoice).Data(), bin); + } + } + + // a) Determine the order of correlator; + int order = harmonics->GetSize(); + if (0 == order || order > gMaxCorrelator) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + if (order > nParticles) { + LOGF(info, " There is no enough particles in this bin to calculate the requested correlator"); + return 0.; // TBI 20240405 Is this really safe here? Re-think... + } + if (nl.fMaxNestedLoop > 0 && nl.fMaxNestedLoop < order) { + LOGF(info, " nl.fMaxNestedLoop > 0 && nl.fMaxNestedLoop < order, where nl.fMaxNestedLoop = %d, order = %d", nl.fMaxNestedLoop, order); + return 0.; // TBI 20240405 Is this really safe here? Re-think... + } + + // b) Custom nested loop: + TProfile* profile = new TProfile("profile", "", 1, 0., 1.); // helper profile to get all averages automatically + // profile->Sumw2(); + double value = 0.; // cos of current multiplet + double weight = 1.; // weight of current multiplet + for (int i1 = 0; i1 < nParticles; i1++) { + double dPhi1 = nl.ftaNestedLoopsKine[kineVarChoice][bin][0]->GetAt(i1); + double dW1 = nl.ftaNestedLoopsKine[kineVarChoice][bin][1]->GetAt(i1); + if (1 == order) { + value = std::cos(harmonics->GetAt(0) * dPhi1); + weight = dW1; + profile->Fill(0.5, value, weight); + continue; + } + for (int i2 = 0; i2 < nParticles; i2++) { + if (i2 == i1) { + continue; + } + double dPhi2 = nl.ftaNestedLoopsKine[kineVarChoice][bin][0]->GetAt(i2); + double dW2 = nl.ftaNestedLoopsKine[kineVarChoice][bin][1]->GetAt(i2); + if (2 == order) { + value = std::cos(harmonics->GetAt(0) * dPhi1 + harmonics->GetAt(1) * dPhi2); + weight = dW1 * dW2; + profile->Fill(0.5, value, weight); + continue; + } + for (int i3 = 0; i3 < nParticles; i3++) { + if (i3 == i1 || i3 == i2) { + continue; + } + double dPhi3 = nl.ftaNestedLoopsKine[kineVarChoice][bin][0]->GetAt(i3); + double dW3 = nl.ftaNestedLoopsKine[kineVarChoice][bin][1]->GetAt(i3); + if (3 == order) { + value = std::cos(harmonics->GetAt(0) * dPhi1 + harmonics->GetAt(1) * dPhi2 + harmonics->GetAt(2) * dPhi3); + weight = dW1 * dW2 * dW3; + profile->Fill(0.5, value, weight); + continue; + } + for (int i4 = 0; i4 < nParticles; i4++) { + if (i4 == i1 || i4 == i2 || i4 == i3) { + continue; + } + double dPhi4 = nl.ftaNestedLoopsKine[kineVarChoice][bin][0]->GetAt(i4); + double dW4 = nl.ftaNestedLoopsKine[kineVarChoice][bin][1]->GetAt(i4); + if (4 == order) { + value = std::cos(harmonics->GetAt(0) * dPhi1 + harmonics->GetAt(1) * dPhi2 + harmonics->GetAt(2) * dPhi3 + harmonics->GetAt(3) * dPhi4); + weight = dW1 * dW2 * dW3 * dW4; + profile->Fill(0.5, value, weight); + continue; + } + for (int i5 = 0; i5 < nParticles; i5++) { + if (i5 == i1 || i5 == i2 || i5 == i3 || i5 == i4) { + continue; + } + double dPhi5 = nl.ftaNestedLoopsKine[kineVarChoice][bin][0]->GetAt(i5); + double dW5 = nl.ftaNestedLoopsKine[kineVarChoice][bin][1]->GetAt(i5); + if (5 == order) { + value = std::cos(harmonics->GetAt(0) * dPhi1 + harmonics->GetAt(1) * dPhi2 + harmonics->GetAt(2) * dPhi3 + harmonics->GetAt(3) * dPhi4 + harmonics->GetAt(4) * dPhi5); + weight = dW1 * dW2 * dW3 * dW4 * dW5; + profile->Fill(0.5, value, weight); + continue; + } + for (int i6 = 0; i6 < nParticles; i6++) { + if (i6 == i1 || i6 == i2 || i6 == i3 || i6 == i4 || i6 == i5) { + continue; + } + double dPhi6 = nl.ftaNestedLoopsKine[kineVarChoice][bin][0]->GetAt(i6); + double dW6 = nl.ftaNestedLoopsKine[kineVarChoice][bin][1]->GetAt(i6); + if (6 == order) { + value = std::cos(harmonics->GetAt(0) * dPhi1 + harmonics->GetAt(1) * dPhi2 + harmonics->GetAt(2) * dPhi3 + harmonics->GetAt(3) * dPhi4 + harmonics->GetAt(4) * dPhi5 + harmonics->GetAt(5) * dPhi6); + weight = dW1 * dW2 * dW3 * dW4 * dW5 * dW6; + profile->Fill(0.5, value, weight); + continue; + } + for (int i7 = 0; i7 < nParticles; i7++) { + if (i7 == i1 || i7 == i2 || i7 == i3 || i7 == i4 || i7 == i5 || i7 == i6) { + continue; + } + double dPhi7 = nl.ftaNestedLoopsKine[kineVarChoice][bin][0]->GetAt(i7); + double dW7 = nl.ftaNestedLoopsKine[kineVarChoice][bin][1]->GetAt(i7); + if (7 == order) { + value = std::cos(harmonics->GetAt(0) * dPhi1 + harmonics->GetAt(1) * dPhi2 + harmonics->GetAt(2) * dPhi3 + harmonics->GetAt(3) * dPhi4 + harmonics->GetAt(4) * dPhi5 + harmonics->GetAt(5) * dPhi6 + harmonics->GetAt(6) * dPhi7); + weight = dW1 * dW2 * dW3 * dW4 * dW5 * dW6 * dW7; + profile->Fill(0.5, value, weight); + continue; + } + for (int i8 = 0; i8 < nParticles; i8++) { + if (i8 == i1 || i8 == i2 || i8 == i3 || i8 == i4 || i8 == i5 || i8 == i6 || i8 == i7) { + continue; + } + double dPhi8 = nl.ftaNestedLoopsKine[kineVarChoice][bin][0]->GetAt(i8); + double dW8 = nl.ftaNestedLoopsKine[kineVarChoice][bin][1]->GetAt(i8); + if (8 == order) { + value = std::cos(harmonics->GetAt(0) * dPhi1 + harmonics->GetAt(1) * dPhi2 + harmonics->GetAt(2) * dPhi3 + harmonics->GetAt(3) * dPhi4 + harmonics->GetAt(4) * dPhi5 + harmonics->GetAt(5) * dPhi6 + harmonics->GetAt(6) * dPhi7 + harmonics->GetAt(7) * dPhi8); + weight = dW1 * dW2 * dW3 * dW4 * dW5 * dW6 * dW7 * dW8; + profile->Fill(0.5, value, weight); + continue; + } + for (int i9 = 0; i9 < nParticles; i9++) { + if (i9 == i1 || i9 == i2 || i9 == i3 || i9 == i4 || i9 == i5 || i9 == i6 || i9 == i7 || i9 == i8) { + continue; + } + double dPhi9 = nl.ftaNestedLoopsKine[kineVarChoice][bin][0]->GetAt(i9); + double dW9 = nl.ftaNestedLoopsKine[kineVarChoice][bin][1]->GetAt(i9); + if (9 == order) { + value = std::cos(harmonics->GetAt(0) * dPhi1 + harmonics->GetAt(1) * dPhi2 + harmonics->GetAt(2) * dPhi3 + harmonics->GetAt(3) * dPhi4 + harmonics->GetAt(4) * dPhi5 + harmonics->GetAt(5) * dPhi6 + harmonics->GetAt(6) * dPhi7 + harmonics->GetAt(7) * dPhi8 + harmonics->GetAt(8) * dPhi9); + weight = dW1 * dW2 * dW3 * dW4 * dW5 * dW6 * dW7 * dW8 * dW9; + profile->Fill(0.5, value, weight); + continue; + } + for (int i10 = 0; i10 < nParticles; i10++) { + if (i10 == i1 || i10 == i2 || i10 == i3 || i10 == i4 || i10 == i5 || i10 == i6 || i10 == i7 || i10 == i8 || i10 == i9) { + continue; + } + double dPhi10 = nl.ftaNestedLoopsKine[kineVarChoice][bin][0]->GetAt(i10); + double dW10 = nl.ftaNestedLoopsKine[kineVarChoice][bin][1]->GetAt(i10); + if (10 == order) { + value = std::cos(harmonics->GetAt(0) * dPhi1 + harmonics->GetAt(1) * dPhi2 + harmonics->GetAt(2) * dPhi3 + harmonics->GetAt(3) * dPhi4 + harmonics->GetAt(4) * dPhi5 + harmonics->GetAt(5) * dPhi6 + harmonics->GetAt(6) * dPhi7 + harmonics->GetAt(7) * dPhi8 + harmonics->GetAt(8) * dPhi9 + harmonics->GetAt(9) * dPhi10); + weight = dW1 * dW2 * dW3 * dW4 * dW5 * dW6 * dW7 * dW8 * dW9 * dW10; + profile->Fill(0.5, value, weight); + continue; + } + for (int i11 = 0; i11 < nParticles; i11++) { + if (i11 == i1 || i11 == i2 || i11 == i3 || i11 == i4 || i11 == i5 || i11 == i6 || i11 == i7 || i11 == i8 || i11 == i9 || i11 == i10) { + continue; + } + double dPhi11 = nl.ftaNestedLoopsKine[kineVarChoice][bin][0]->GetAt(i11); + double dW11 = nl.ftaNestedLoopsKine[kineVarChoice][bin][1]->GetAt(i11); + if (11 == order) { + value = std::cos(harmonics->GetAt(0) * dPhi1 + harmonics->GetAt(1) * dPhi2 + harmonics->GetAt(2) * dPhi3 + harmonics->GetAt(3) * dPhi4 + harmonics->GetAt(4) * dPhi5 + harmonics->GetAt(5) * dPhi6 + harmonics->GetAt(6) * dPhi7 + harmonics->GetAt(7) * dPhi8 + harmonics->GetAt(8) * dPhi9 + harmonics->GetAt(9) * dPhi10 + harmonics->GetAt(10) * dPhi11); + weight = dW1 * dW2 * dW3 * dW4 * dW5 * dW6 * dW7 * dW8 * dW9 * dW10 * dW11; + profile->Fill(0.5, value, weight); + continue; + } + for (int i12 = 0; i12 < nParticles; i12++) { + if (i12 == i1 || i12 == i2 || i12 == i3 || i12 == i4 || i12 == i5 || i12 == i6 || i12 == i7 || i12 == i8 || i12 == i9 || i12 == i10 || i12 == i11) { + continue; + } + double dPhi12 = nl.ftaNestedLoopsKine[kineVarChoice][bin][0]->GetAt(i12); + double dW12 = nl.ftaNestedLoopsKine[kineVarChoice][bin][1]->GetAt(i12); + if (12 == order) { + value = std::cos(harmonics->GetAt(0) * dPhi1 + harmonics->GetAt(1) * dPhi2 + harmonics->GetAt(2) * dPhi3 + harmonics->GetAt(3) * dPhi4 + harmonics->GetAt(4) * dPhi5 + harmonics->GetAt(5) * dPhi6 + harmonics->GetAt(6) * dPhi7 + harmonics->GetAt(7) * dPhi8 + harmonics->GetAt(8) * dPhi9 + harmonics->GetAt(9) * dPhi10 + harmonics->GetAt(10) * dPhi11 + harmonics->GetAt(11) * dPhi12); + weight = dW1 * dW2 * dW3 * dW4 * dW5 * dW6 * dW7 * dW8 * dW9 * dW10 * dW11 * dW12; + profile->Fill(0.5, value, weight); + continue; + } + + // ... it's easy to continue the above pattern here + + } // for(int i12=0; i12GetBinContent(1); + delete profile; + profile = NULL; + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + return finalValue; + + } // double CalculateKineCustomNestedLoops(TArrayI *harmonics, eAsFunctionOf AFO_variable, int bin) + + //============================================================ + + void DetermineMultiplicity() + { + // Determine multiplicity for "vs. mult" results. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + if (ec.fsEventCuts[eMultiplicityEstimator].EqualTo("SelectedTracks", TString::kIgnoreCase)) { + ebye.fMultiplicity = static_cast(ebye.fSelectedTracks); + } else if (ec.fsEventCuts[eMultiplicityEstimator].EqualTo("ReferenceMultiplicity", TString::kIgnoreCase)) { + ebye.fMultiplicity = ebye.fReferenceMultiplicity; + } else { + LOGF(fatal, "\033[1;31m%s at line %d : multiplicity estimator = %s is not supported yet. \033[0m", __FUNCTION__, __LINE__, ec.fsEventCuts[eMultiplicityEstimator].Data()); + } + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // void DetermineMultiplicity() + + //============================================================ + + template + void DetermineReferenceMultiplicity(T const& collision) + { + // Determine collision reference multiplicity. + + // a) Determine reference multiplicity for real Run 3 data; + // b) Determine reference multiplicity for simulated Run 3 data; + // c) Same as a), just for converted Run 2 and Run 1 data; + // d) Same as b), just for converted Run 2 and Run 1 data; + // e) Test case; + // f) Print reference multiplicity for the audience... + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // a) Determine reference multiplicity for real Run 3 data: + if constexpr (rs == eRec || rs == eRecAndSim || rs == eQA) { + // Local convention for name of reference multiplicity estimator: use the same name as the getter, case insensitive. + if (ec.fsEventCuts[eReferenceMultiplicityEstimator].EqualTo("multTPC", TString::kIgnoreCase)) { + ebye.fReferenceMultiplicity = collision.multTPC(); + } else if (ec.fsEventCuts[eReferenceMultiplicityEstimator].EqualTo("multFV0M", TString::kIgnoreCase)) { + ebye.fReferenceMultiplicity = collision.multFV0M(); + } else if (ec.fsEventCuts[eReferenceMultiplicityEstimator].EqualTo("multFT0C", TString::kIgnoreCase)) { + ebye.fReferenceMultiplicity = collision.multFT0C(); + } else if (ec.fsEventCuts[eReferenceMultiplicityEstimator].EqualTo("multFT0M", TString::kIgnoreCase)) { + ebye.fReferenceMultiplicity = collision.multFT0M(); + } else if (ec.fsEventCuts[eReferenceMultiplicityEstimator].EqualTo("multNTracksPV", TString::kIgnoreCase)) { + ebye.fReferenceMultiplicity = collision.multNTracksPV(); + } else if (ec.fsEventCuts[eReferenceMultiplicityEstimator].EqualTo("multNTracksGlobal", TString::kIgnoreCase)) { + // ebye.fReferenceMultiplicity = collision.multNTracksGlobal(); // TBI 20241209 not validated yet + } else { + LOGF(fatal, "\033[1;31m%s at line %d : reference multiplicity estimator = %d is not supported yet for Run 3. \033[0m", __FUNCTION__, __LINE__, ec.fsEventCuts[eReferenceMultiplicityEstimator].Data()); + } + // QA: + if (qa.fFillQAEventHistograms2D) { // TBI 20240515 this flag is too general here, I need to make it more specific + qa.fReferenceMultiplicity[eMultTPC] = collision.multTPC(); + qa.fReferenceMultiplicity[eMultFV0M] = collision.multFV0M(); + qa.fReferenceMultiplicity[eMultFT0C] = collision.multFT0C(); + qa.fReferenceMultiplicity[eMultFT0M] = collision.multFT0M(); + qa.fReferenceMultiplicity[eMultNTracksPV] = collision.multNTracksPV(); + // qa.fReferenceMultiplicity[eMultNTracksGlobal] = collision.multNTracksGlobal(); // TBI 20241209 not validated yet + } + + // TBI 20241123 check if corresponding simulated ref. mult. is available through collision.has_mcCollision() + // ... + } + + // b) Determine reference multiplicity for simulated Run 3 data: + if constexpr (rs == eSim) { + ebye.fReferenceMultiplicity = -44.; // TBI 20241123 check what to use here and add support eventualy + } + + // c) Same as a), just for converted Run 2 and Run 1 data: + if constexpr (rs == eRec_Run2 || rs == eRecAndSim_Run2 || rs == eRec_Run1 || rs == eRecAndSim_Run1) { + if (ec.fsEventCuts[eReferenceMultiplicityEstimator].EqualTo("multTracklets", TString::kIgnoreCase)) { + ebye.fReferenceMultiplicity = collision.multTracklets(); + } else { + LOGF(fatal, "\033[1;31m%s at line %d : reference multiplicity estimator = %d is not supported yet for Run 2. \033[0m", __FUNCTION__, __LINE__, ec.fsEventCuts[eReferenceMultiplicityEstimator].Data()); + } + // QA: + if (qa.fFillQAEventHistograms2D) { // TBI 20240515 this flag is too general here, I need to make it more specific + // ... + } + + // TBI 20241123 check if corresponding simulated ref. mult. is available through collision.has_mcCollision() + // ... + } + + // d) Same as b), just for converted Run 2 and Run 1 data: + if constexpr (rs == eSim_Run2 || rs == eSim_Run1) { + ebye.fReferenceMultiplicity = -44.; // TBI 20241123 check what to use here and add support eventualy + } + + // e) Test case: + if constexpr (rs == eTest) { + ebye.fReferenceMultiplicity = static_cast(gRandom->Uniform(0., 5000.)); // TBI 20241123 I could implement here a getter, if there is one available both for Run 3 and Run 2/1 + } + + // f) Print centrality for the audience...: + if (tc.fVerbose) { + LOGF(info, "\033[1;32m ebye.fReferenceMultiplicity = %f\033[0m", ebye.fReferenceMultiplicity); + ExitFunction(__FUNCTION__); + } + + } // template void DetermineReferenceMultiplicity(T const& collision) + + //============================================================ + + template + void DetermineCentrality(T const& collision) + { + // Determine collision centrality. + // For simulated data, I determine ebye.ImpactParameter here as well. + + // TBI 20250429 there it a bit of code bloat here in this function + + // a) For real data, determine centrality from default centrality estimator; + // b) For simulated data, determine centrality directly from impact parameter + store impact parameter; + // c) Same as a), just for converted Run 2 data; + // d) Same as b), just for converted Run 2 data; + // e) Same as a), just for converted Run 1 data; + // f) Same as b), just for converted Run 1 data; + // g) Test case; + // h) Print centrality for the audience... + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // a) For real data, determine centrality from default centrality estimator: + if constexpr (rs == eRec || rs == eRecAndSim || rs == eQA) { + // Local convention for name of centrality estimator: use the same name as the getter, case insensitive. + if (ec.fsEventCuts[eCentralityEstimator].EqualTo("centFT0C", TString::kIgnoreCase)) { + ebye.fCentrality = collision.centFT0C(); + } else if (ec.fsEventCuts[eCentralityEstimator].EqualTo("centFT0CVariant1", TString::kIgnoreCase)) { + ebye.fCentrality = collision.centFT0CVariant1(); + } else if (ec.fsEventCuts[eCentralityEstimator].EqualTo("centFT0M", TString::kIgnoreCase)) { + ebye.fCentrality = collision.centFT0M(); + } else if (ec.fsEventCuts[eCentralityEstimator].EqualTo("centFV0A", TString::kIgnoreCase)) { + ebye.fCentrality = collision.centFV0A(); + } else if (ec.fsEventCuts[eCentralityEstimator].EqualTo("centNTPV", TString::kIgnoreCase)) { + ebye.fCentrality = collision.centNTPV(); + } else if (ec.fsEventCuts[eCentralityEstimator].EqualTo("centNGlobal", TString::kIgnoreCase)) { + // ebye.fCentrality = collision.centNGlobal(); // TBI 20250128 enable eventually + } else { + LOGF(fatal, "\033[1;31m%s at line %d : centrality estimator = %d is not supported yet. \033[0m", __FUNCTION__, __LINE__, ec.fsEventCuts[eCentralityEstimator].Data()); + } + // QA: + if (qa.fFillQAEventHistograms2D || ec.fUseEventCuts[eCentralityCorrelationsCut]) { // TBI 20250331 I re-use here qa.fCentrality for CentralityCorrelationsCut, why not... + qa.fCentrality[eCentFT0C] = collision.centFT0C(); + qa.fCentrality[eCentFT0CVariant1] = collision.centFT0CVariant1(); + qa.fCentrality[eCentFT0M] = collision.centFT0M(); + qa.fCentrality[eCentFV0A] = collision.centFV0A(); + qa.fCentrality[eCentNTPV] = collision.centNTPV(); + // qa.fCentrality[eCentNGlobal] = collision.centNGlobal(); // TBI 20250128 enable eventually + } + + // ... + + // ... and corresponding MC truth simulated: + if constexpr (rs == eRecAndSim) { + + // *) Impact parameter: + ebye.fImpactParameter = collision.mcCollision().impactParameter(); // has to be called before DetermineSimulatedCentrality(); + + // *) Centrality for simulated data in Run 3: + ebye.fCentralitySim = DetermineSimulatedCentrality(); + + // ... + + } // if constexpr (rs == eRecAndSim) + + } // if constexpr (rs == eRec || rs == eRecAndSim || rs == eQA) + + // b) For simulated data, determine centrality directly from impact parameter + store impact parameter: + if constexpr (rs == eSim) { + ebye.fImpactParameter = collision.mcCollision().impactParameter(); // has to be called before DetermineSimulatedCentrality(); + ebye.fCentrality = DetermineSimulatedCentrality(); // yes, I use here ebye.fCentrality, not ebye.fCentralitySim + } + + // c) Same as a), just for converted Run 2 data: + if constexpr (rs == eRec_Run2 || rs == eRecAndSim_Run2) { + if (ec.fsEventCuts[eCentralityEstimator].EqualTo("centRun2V0M", TString::kIgnoreCase)) { + ebye.fCentrality = collision.centRun2V0M(); + } else if (ec.fsEventCuts[eCentralityEstimator].EqualTo("centRun2SPDTracklets", TString::kIgnoreCase)) { + ebye.fCentrality = collision.centRun2SPDTracklets(); + } else { + LOGF(fatal, "\033[1;31m%s at line %d : centrality estimator = %d is not supported yet. \033[0m", __FUNCTION__, __LINE__, ec.fsEventCuts[eCentralityEstimator].Data()); + } + // QA: + if (qa.fFillQAEventHistograms2D || ec.fUseEventCuts[eCentralityCorrelationsCut]) { // TBI 20250331 I re-use here qa.fCentrality for CentralityCorrelationsCut, why not... + qa.fCentrality[eCentRun2V0M] = collision.centRun2V0M(); + qa.fCentrality[eCentRun2SPDTracklets] = collision.centRun2SPDTracklets(); + } + + // ... + + // ... and corresponding MC truth simulated: + + if constexpr (rs == eRecAndSim_Run2) { + + // *) Impact parameter: + ebye.fImpactParameter = collision.mcCollision().impactParameter(); // has to be called before DetermineSimulatedCentrality(); + + // *) Centrality for simulated data in Run 3: + ebye.fCentralitySim = DetermineSimulatedCentrality(); + + // ... + + } // if constexpr (rs == eRecAndSim_Run2) + } + + // d) Same as b), just for converted Run 2 data: + if constexpr (rs == eSim_Run2) { + ebye.fImpactParameter = collision.mcCollision().impactParameter(); // has to be called before DetermineSimulatedCentrality(); + ebye.fCentrality = DetermineSimulatedCentrality(); // yes, I use here ebye.fCentrality, not ebye.fCentralitySim + } + + // e) Same as a), just for converted Run 1 data: + if constexpr (rs == eRec_Run1 || rs == eRecAndSim_Run1) { + if (ec.fsEventCuts[eCentralityEstimator].EqualTo("centRun2V0M", TString::kIgnoreCase)) { + // ebye.fCentrality = collision.centRun2V0M(); // TBI 20240224 enable when I add support for RecAndSim_Run1 + } else if (ec.fsEventCuts[eCentralityEstimator].EqualTo("CentRun2SPDTracklets", TString::kIgnoreCase)) { + // ebye.fCentrality = collision.centRun2SPDTracklets(); // TBI 20240224 enable when I add support for RecAndSim_Run1 + } else { + LOGF(fatal, "\033[1;31m%s at line %d : centrality estimator = %d is not supported yet. \033[0m", __FUNCTION__, __LINE__, ec.fsEventCuts[eCentralityEstimator].Data()); + } + + // ... and corresponding MC truth simulated: + + if constexpr (rs == eRecAndSim_Run1) { + + // *) Impact parameter: + ebye.fImpactParameter = collision.mcCollision().impactParameter(); // has to be called before DetermineSimulatedCentrality(); + + // *) Centrality for simulated data in Run 3: + ebye.fCentralitySim = DetermineSimulatedCentrality(); + + // ... + + } // if constexpr (rs == eRecAndSim_Run1) + } + + // f) Same as b), just for converted Run 1 data: + if constexpr (rs == eSim_Run1) { + ebye.fImpactParameter = collision.mcCollision().impactParameter(); // has to be called before DetermineSimulatedCentrality(); + ebye.fCentrality = DetermineSimulatedCentrality(); // yes, I use here ebye.fCentrality, not ebye.fCentralitySim + } + + // g) Test case: + if constexpr (rs == eTest) { + ebye.fCentrality = static_cast(gRandom->Uniform(0., 100.)); + } + + // h) Print centrality for the audience...: + if (tc.fVerbose) { + LOGF(info, "\033[1;32m ebye.fCentrality = %f\033[0m", ebye.fCentrality); + LOGF(info, "\033[1;32m ebye.fCentralitySim = %f\033[0m", ebye.fCentralitySim); + ExitFunction(__FUNCTION__); + } + + } // template void DetermineCentrality(T const& collision) + + //============================================================ + + float DetermineSimulatedCentrality() + { + // Determine centrality at generated/simulated level, just using impact parameter. + // This is a helper function for DetermineCentrality(), to reduce the code bloat there. I do not anticipate calling this function anywhere alse at the moment. + + // Algorithm: + // 1. Ideally, I simply fetch this centrality from the table HepMCHeavyIons via getter .centrality(); + // 2. If that info is not available, I calculate the simulated centrality here temporarily manually from impact parameter + sigma_inel; + // 3. From process switches I can see whether I am processing Run 3, Run 2 or Run 1 data, for collision system I support at the moment only Pb+Pb. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + float lSimulatedCentrality = -1.; + float lSigmaInel = -1.; + + if (tc.fProcess[eProcessHepMChi]) { + // I have extracted already by this point simulated centrality from HepMCHeavyIons and stored it in ebye.fCentralitySim: + + // TBI 20250429 when I merge eProcessHepMChi with other RecSim process switches, I will have to refurbish the code here + + lSimulatedCentrality = ebye.fCentralitySim; + + } else if (tc.fProcess[eGenericRecSim] || tc.fProcess[eGenericSim]) { + + LOGF(warning, "\033[1;33m%s at line %d : Simulated centrality is calculated manually for the time being from impact parameter. Results make sense only for Pb+Pb at Run 3, Run 2 and Run 1 energies, other cases are not supported here (yet)\033[0m\n", __FUNCTION__, __LINE__); + + // Algorithm: Temporarily, I calculate centrality manually for simulated data directly from impact parameter as follows: + + // centrality(b) = Pi * b^2 / sigma_inel , where e.g. I take sigma_inel = 7.67 for Pb+Pb at 5.02 TeV, and analogously for other collision systems and energies + + if (tc.fProcess[eProcessRecSim] || tc.fProcess[eSim]) { + // Pb+Pb in Run 3: + lSigmaInel = 7.71; // interpolation, see Slide 3 in DDC presentation https://indico.cern.ch/event/1326916/ + } else if (tc.fProcess[eProcessRecSim_Run2] || tc.fProcess[eSim_Run2]) { + // Pb+Pb in Run 2: + lSigmaInel = 7.67; // for 5.02 TeV, see Slide 3 in DDC presentation https://indico.cern.ch/event/1326916/ + Run 2 paper https://arxiv.org/abs/2204.10148 + } else if (tc.fProcess[eProcessRecSim_Run1] || tc.fProcess[eSim_Run1]) { + // Pb+Pb in Run 1: + lSigmaInel = 7.55; // see Slide 3 in DDC presentation https://indico.cern.ch/event/1326916/ + Run 1 multiplicity paper https://arxiv.org/abs/1301.4361 + } else { + LOGF(fatal, "\033[1;31m%s at line %d : this branch is not supported/validated yet\033[0m", __FUNCTION__, __LINE__); + } + + // okay, I have SigmaInel for this collision system and energy, calculate centrality: + float b = ebye.fImpactParameter; + if (b < 0.) { + LOGF(warning, "\033[1;31m%s at line %d : b < 0. => did you forget to calculate ebye.fImpactParameter before calling DetermineSimulatedCentrality() ? Or you are processing Monte Carlo dataset where IP was not stored, i.e. it's set to -999 (e.g. in LHC21i6a) ? Setting lSimulatedCentrality = -1. and simply continuing... \033[0m", __FUNCTION__, __LINE__); + lSimulatedCentrality = -1.; + } else { + lSimulatedCentrality = o2::constants::math::PI * std::pow(b, 2.) / lSigmaInel; // finally, calculate true simulated centrality directly from impact parameter + } + } else { + LOGF(fatal, "\033[1;31m%s at line %d : this branch is not supported/validated yet\033[0m", __FUNCTION__, __LINE__); + } + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + return lSimulatedCentrality; + + } // float DetermineSimulatedCentrality() + + //============================================================ + + template + void DetermineOccupancy(T const& collision) + { + // Determine collision occupancy. + + // a) Determine occupancy from default occupancy estimator, only for eRec and eRecAndSim; + // b) For all other cases, set occupancy to -1 (not defined). + // c) Print occupancy for the audience... + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // a) Determine occupancy from default occupancy estimator, only for eRec and eRecAndSim: + if constexpr (rs == eRec || rs == eRecAndSim || rs == eQA) { + if (ec.fsEventCuts[eOccupancyEstimator].EqualTo("TrackOccupancyInTimeRange", TString::kIgnoreCase)) { + ebye.fOccupancy = collision.trackOccupancyInTimeRange(); + } else if (ec.fsEventCuts[eOccupancyEstimator].EqualTo("FT0COccupancyInTimeRange", TString::kIgnoreCase)) { + ebye.fOccupancy = collision.ft0cOccupancyInTimeRange(); + } else { + LOGF(fatal, "\033[1;31m%s at line %d : occupancy estimator = %d is not supported yet. \033[0m", __FUNCTION__, __LINE__, ec.fsEventCuts[eOccupancyEstimator].Data()); + } + // QA: + if (qa.fFillQAEventHistograms2D) { // TBI 20240515 this flag is too general here, I need to make it more specific + qa.fOccupancy[eTrackOccupancyInTimeRange] = collision.trackOccupancyInTimeRange(); + qa.fOccupancy[eFT0COccupancyInTimeRange] = collision.ft0cOccupancyInTimeRange(); + } + } else { + // b) For all other cases, set occupancy to -1 (not defined): + ebye.fOccupancy = -1.; + // QA: + if (qa.fFillQAEventHistograms2D) { // TBI 20240515 this flag is too general here, I need to make it more specific + for (int oe = 0; oe < eOccupancyEstimators_N; oe++) { + qa.fOccupancy[oe] = -1.; + } + } + } + + // c) Print occupancy for the audience...: + if (tc.fVerbose) { + LOGF(info, "\033[1;32m ebye.fOccupancy = %f\033[0m", ebye.fOccupancy); + ExitFunction(__FUNCTION__); + } + + } // template void DetermineOccupancy(T const& collision) + + //============================================================ + + template + void DetermineInteractionRateAndCurrentRunDuration(T1 const& collision, T2 const&) + { + // Determine interaction rate and current run duration in Run 3. + + // Cannot be used in converted Run 2 and Run 1, because mRateFetcher.fetch... line below crashes with example line: + // [228607:multiparticle-correlations-a-b]: [10:02:38][ERROR] Requested resource does not exist: http://alice-ccdb.cern.ch//GLO/Config/GRPLHCIF/1449947476529/ + // [228607:multiparticle-correlations-a-b]: [10:02:38][FATAL] Got nullptr from CCDB for path GLO/Config/GRPLHCIF and timestamp 1449947476529 + + // a) Determine interaction rate and current run duration only for eRec; + // b) For all other cases, set interaction rate to -1 for the time being; + // c) Print interaction rate and current run duration for the audience... + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + if constexpr (rs == eRec || rs == eQA) { // TBI 20250112 check still eRecSim mode here + auto bc = collision.template foundBC_as(); // I have the same code snippet at other places, keep in sync. + + // a1) Determine interaction rate only for eRec: + if (ec.fUseEventCuts[eInteractionRate] || qa.fFillQAEventHistograms2D || qa.fFillQACorrelationsVsInteractionRateVsProfiles2D || (mupa.fCalculateCorrelations && mupa.fCalculateCorrelationsAsFunctionOf[AFO_INTERACTIONRATE]) || (t0.fCalculateTest0 && t0.fCalculateTest0AsFunctionOf[AFO_INTERACTIONRATE]) || (es.fCalculateEtaSeparations && es.fCalculateEtaSeparationsAsFunctionOf[AFO_INTERACTIONRATE])) { + + LOGF(info, "\033[1;33m%s at line %d: !!!! WARNING !!!! There is a large memory blow-up of ~130 MB when calling mRateFetcher.fetch(...) !!!! WARNING !!!! \033[0m", __FUNCTION__, __LINE__); + + double hadronicRate = mRateFetcher.fetch(ccdb.service, static_cast(bc.timestamp()), static_cast(bc.runNumber()), "ZNC hadronic") * 1.e-3; // TBI 20250414 memory blow-up + if (hadronicRate > 0.) { + ebye.fInteractionRate = static_cast(hadronicRate); + } else { + LOGF(warning, "\033[1;31m%s at line %d : hadronicRate = %f is meaningless \033[0m", __FUNCTION__, __LINE__, hadronicRate); + // I hit indeed at negative hadronic rate in LHC24ar/559545/apass1 dataset. But I do not really need to bail out here, because that collision in + // any case will not pass a cut in configurable cfInteractionRate . Therefore, I print a warning, and then can grep it from the log, if necessary. + } + } // if(...) + + // a2) Determine the current run duration: + // TBI 20250107 I could move this to a separate function? + // TBI 20250415 I do not see any memory penalty here, so I keep it + ebye.fCurrentRunDuration = std::floor(bc.timestamp() * 0.001) - tc.fRunTime[eStartOfRun]; + if (ebye.fCurrentRunDuration > tc.fRunTime[eDurationInSec]) { + LOGF(fatal, "\033[1;31m%s at line %d : ebye.fCurrentRunDuration = %d is bigger than tc.fRunTime[eDurationInSec] = %d, which is meaningless \033[0m", __FUNCTION__, __LINE__, static_cast(ebye.fCurrentRunDuration), static_cast(tc.fRunTime[eDurationInSec])); + } + + } else { + // b) For all other cases, set interaction rate to -1: + ebye.fInteractionRate = -1.; + ebye.fCurrentRunDuration = -1.; + ebye.fFT0CAmplitudeOnFoundBC = -1.; + } + + // c) Print interaction rate and run duration for the audience...: + if (tc.fVerbose) { + LOGF(info, "\033[1;32m ebye.fInteractionRate = %f kHz\033[0m", ebye.fInteractionRate); + if (qa.fBookQAEventHistograms2D[eCurrentRunDuration_vs_InteractionRate]) { // TBI 20241127 do I check this flag, or pointer, like in FillEventHistograms(...) ? + LOGF(info, "\033[1;32m ebye.fCurrentRunDuration = %f s (in seconds after SOR)\033[0m", ebye.fCurrentRunDuration); + } + ExitFunction(__FUNCTION__); + } + + } // template void DetermineInteractionRateAndCurrentRunDuration(T1 const& collision, T2 const&) + + //============================================================ + + template + void DetermineVertexZ(T const& collision) + { + // Determine vetex z position. + + // TBI 20250108 I could use ebye.fVz determined here to fill event histograms, but it's not a big deal to fetch it there also via collision.posZ() + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + ebye.fVz = collision.posZ(); + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // void DetermineVertexZ(T const& collision) + + //============================================================ + + template + void DetermineQAThingies(T1 const& collision, T2 const&) + { + // Remark: I implement ideally here only the getters for which the subscription to additional non-standard tables was needed for QA purposes. + // Support only for Run 3 data is provided, because in the "processQA" switch the starting point are tables used in "processRec", and I join to them + // some non-standard tables only for QA purposes. + + // a) Determine FT0CAmplitudeOnFoundBC; + // ... + // *) Print something for the audience... . + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + if constexpr (rs == eQA) { + auto bc = collision.template foundBC_as(); // I have the same code snippet at other places, keep in sync. + + // a) Determine FT0CAmplitudeOnFoundBC; + if (bc.has_foundFT0()) { + ebye.fFT0CAmplitudeOnFoundBC = bc.foundFT0().sumAmpC(); // see more details in rofOccupancyQa.cxx + } + + // ... + + // *) Print something for the audience...: + if (tc.fVerbose) { + LOGF(info, "\033[1;32m ebye.fFT0CAmplitudeOnFoundBC = %f\033[0m", ebye.fFT0CAmplitudeOnFoundBC); + } // if (tc.fVerbose) { + + } else { + // For all other cases, set all QA-specific variables calculated here to -1. TBI 20250401 shall I really do it this way, in a sense that for all other cases, this function should never be called? + ebye.fFT0CAmplitudeOnFoundBC = -1.; + } + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } // if (tc.fVerbose) { + + } // template void DetermineQAThingies(T1 const& collision, T2 const&) + + //============================================================ + + void ProcessHepMCHeavyIons(aod::HepMCHeavyIon const& hep) + { + // Process extra MC info from HepMCHeavyIons only in this function. + // See documentation at https://aliceo2group.github.io/analysis-framework/docs/datamodel/ao2dTables.html#montecarlo + + LOGF(info, "\033[1;32m hep.mcCollisionId() = %d\033[0m", hep.mcCollisionId()); + LOGF(info, "\033[1;32m hep.centrality() = %f\033[0m", hep.centrality()); // TBI 20250428 set to -1 in LHC24g3 + LOGF(info, "\033[1;32m hep.eccentricity() = %f\033[0m", hep.eccentricity()); // TBI 20250428 set to 0 in LHC24g3 + LOGF(info, "\033[1;32m hep.sigmaInelNN() = %f\033[0m", hep.sigmaInelNN()); // TBI 20250428 set to 0 in LHC24g3 + LOGF(info, "\033[1;32m hep.eventPlaneAngle() = %f\033[0m", hep.eventPlaneAngle()); // TBI 20250428 set to 0 in LHC24g3, but stored correctly in McCollisions + LOGF(info, "\033[1;32m hep.impactParameter() = %f\033[0m\n", hep.impactParameter()); // stored correctly both in HepMCHeavyIons and McCollisions + + // *) Centrality at generated level: + ebye.fCentralitySim = hep.centrality(); + if (ebye.fCentralitySim < 0. || ebye.fCentralitySim > 100.) { + LOGF(info, "\033[1;33m%s at line %d: !!!! WARNING !!!! ebye.fCentralitySim = %f, this info is still not stored in the table HepMCHeavyIons !!!! WARNING !!!! \033[0m\n", __FUNCTION__, __LINE__, ebye.fCentralitySim); + } + + // ... TBI 20240429 as soon as HepMCHeavyIons data is stored filled in Monte Carlo datasets, ctd. here + + } // void ProcessHepMCHeavyIons(aod::HepMCHeavyIon const& hep) + + //============================================================ + + void DetermineEventCounters() + { + // Determine all event counters. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // Remark: For "RecSim", the total number of events is taken from eRec. + if (eh.fEventHistograms[eNumberOfEvents][eRec][eBefore] && eh.fEventHistograms[eNumberOfEvents][eRec][eAfter]) { + eh.fEventCounter[eTotal] = static_cast(eh.fEventHistograms[eNumberOfEvents][eRec][eBefore]->GetBinContent(1)); + eh.fEventCounter[eProcessed] = static_cast(eh.fEventHistograms[eNumberOfEvents][eRec][eAfter]->GetBinContent(1)); + } else if (eh.fEventHistograms[eNumberOfEvents][eSim][eBefore] && eh.fEventHistograms[eNumberOfEvents][eSim][eAfter]) { + // Remark: This branch covers automatically also internal validation, because I book and fill there only eSim. + eh.fEventCounter[eTotal] = static_cast(eh.fEventHistograms[eNumberOfEvents][eSim][eBefore]->GetBinContent(1)); + eh.fEventCounter[eProcessed] = static_cast(eh.fEventHistograms[eNumberOfEvents][eSim][eAfter]->GetBinContent(1)); + } + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // void DetermineEventCounters() + + //============================================================ + + void RandomIndices(int nTracks) + { + // Randomize indices using Fisher-Yates algorithm. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + if (nTracks < 1) { + return; + } + + // Fisher-Yates algorithm: + tc.fRandomIndices = new TArrayI(nTracks); + tc.fRandomIndices->Reset(); // just in case there is some random garbage in memory at init + for (int i = 0; i < nTracks; i++) { + tc.fRandomIndices->AddAt(i, i); + } + for (int i = nTracks - 1; i >= 1; i--) { + int j = gRandom->Integer(i + 1); + int temp = tc.fRandomIndices->GetAt(j); + tc.fRandomIndices->AddAt(tc.fRandomIndices->GetAt(i), j); + tc.fRandomIndices->AddAt(temp, i); + } // end of for(int i=nTracks-1;i>=1;i--) + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // void RandomIndices(int nTracks) + + //============================================================ + + template + void BanishmentLoopOverParticles(T const& tracks) + { + // This is the quick banishment loop over particles, as a support for eSelectedTracks cut (used through eMultiplicity, see comments for ebye.fMultiplicity). + // This is particularly relevant to get all efficiency corrections right. + // The underlying problem is that particle histograms got filled before eSelectedTracks could be applied in Steer. + // Therefore, particle histograms got filled even for events which were rejected by eSelectedTracks cut. + // In this loop, for those few specific events (typically low-multiplicity outliers), particle histograms are re-filled again with weight -1, + // which in effect cancels the previos fill in the MainLoopOverParticles. + + // Remark: I have to use here all additional checks, like ValidTrack, as in the MainLoopOverParticles. + // Therefore, it's important to have local variable lSelectedTracks, so that I can cross-compare + // at the end with central data member ebye.fSelectedTracks + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // *) If random access of tracks from collection is requested, use Fisher-Yates algorithm to generate random indices: + // Remark: It is very important that I use exactly the same random sequence from FY already generated in the MainLoop + if (tc.fUseFisherYates) { + if (!tc.fRandomIndices) { + LOGF(fatal, "\033[1;31m%s at line %d : I have to use here exactly the same random sequence from FY already generated in the MainLoopOverParticles, but it's not available \033[0m", __FUNCTION__, __LINE__); + } + } + + // *) Counter of selected tracks in the current event: + int lSelectedTracks = 0; // I could reset and reuse here ebye.fSelectedTracks, but it's safer to use separate local variable, as I can do additional insanity checks here + + // *) Banishment loop over particles: + // for (auto& track : tracks) { // default standard way of looping of tracks + auto track = tracks.iteratorAt(0); // set the type and scope from one instance + for (int64_t i = 0; i < tracks.size(); i++) { + + // *) Access track sequentially from collection of tracks (default), or randomly using Fisher-Yates algorithm: + if (!tc.fUseFisherYates) { + track = tracks.iteratorAt(i); + } else { + track = tracks.iteratorAt(static_cast(tc.fRandomIndices->GetAt(i))); + } + + // *) Skip track objects which are not valid tracks (e.g. Run 2 and 1 tracklets, etc.): + if (!ValidTrack(track)) { + continue; + } + + // *) Banish particle histograms before particle cuts: + // TBI 20240515 I banish for the time being only particle histograms AFTER particle cuts. + // If I start to banish here also particle histograms BEFORE particle cuts, then see if I have to do it also for event histograms BEFORE cuts. + // Event histograms AFTER cuts are not affected. + // if (ph.fFillParticleHistograms || ph.fFillParticleHistograms2D) { + // FillParticleHistograms(track, eBefore, -1); + // } + + // *) Particle cuts: + if (!ParticleCuts(track, eCut)) { // Main call for particle cuts. + continue; // not return!! + } + + // *) Banish particle histograms after particle cuts: + if (ph.fFillParticleHistograms || ph.fFillParticleHistograms2D || qa.fFillQAParticleHistograms2D) { + FillParticleHistograms(track, eAfter, -1); // with negative weight -1, I effectively remove the previous fill for this track + } + + // *) Increase the local selected particle counter: + lSelectedTracks++; + if (lSelectedTracks >= ec.fdEventCuts[eMultiplicity][eMax]) { + break; + } + + // *) Break the loop if fixed number of particles is taken randomly from each event (use always in combination with tc.fUseFisherYates = true): + if (tc.fFixedNumberOfRandomlySelectedTracks > 0 && tc.fFixedNumberOfRandomlySelectedTracks == lSelectedTracks) { + LOGF(info, "%s : Breaking the loop over particles, since requested fixed number of %d particles was reached", __FUNCTION__, tc.fFixedNumberOfRandomlySelectedTracks); + break; + } + + } // for (auto& track : tracks) + + // *) Quick insanity checks (mandatory!): + if (lSelectedTracks != ebye.fSelectedTracks) { + LOGF(fatal, "\033[1;31m%s at line %d : lSelectedTracks != ebye.fSelectedTracks , lSelectedTracks = %d, ebye.fSelectedTracks = %d\nDid you accidentally enable Toy NUA? \033[0m", __FUNCTION__, __LINE__, lSelectedTracks, ebye.fSelectedTracks); + } + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // template void BanishmentLoopOverParticles(T const& tracks) { + + //============================================================ + + void PrintCutCounterContent() + { + // Prints on the screen content of fEventCutCounterHist[][] (all which were booked). + + // a) Insanity checks; + // b) Print or die. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // a) Insanity checks: + if (!(ec.fUseEventCutCounterAbsolute || ec.fUseEventCutCounterSequential)) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + + // b) Print or die: + for (int rs = 0; rs < 2; rs++) // reco/sim + { + for (int cc = 0; cc < eCutCounter_N; cc++) // enum eCutCounter + { + if (!(ec.fEventCutCounterHist[rs][cc])) { + continue; + } + LOGF(info, "\033[1;32m\nPrinting the content of event cut counter histogram %s\033[0m", ec.fEventCutCounterHist[rs][cc]->GetName()); + for (int bin = 1; bin <= ec.fEventCutCounterHist[rs][cc]->GetNbinsX(); bin++) { + if (TString(ec.fEventCutCounterHist[rs][cc]->GetXaxis()->GetBinLabel(bin)).EqualTo("TBI")) { // TBI 20240514 temporary workaround, "TBI" can't persist here + continue; + } + LOGF(info, "bin = %d => %s : %d", bin, ec.fEventCutCounterHist[rs][cc]->GetXaxis()->GetBinLabel(bin), static_cast(ec.fEventCutCounterHist[rs][cc]->GetBinContent(bin))); + } + } // for (int cc = 0; cc < eCutCounter_N; cc++) // enum eCutCounter + } // for (int rs = 0; rs < 2; rs++) // reco/sim + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // void PrintCutCounterContent() + + //============================================================ + + void Trace(const char* functionName, int lineNumber) + { + // A simple utility wrapper. Use only during debugging, sprinkle calls to this function here and there, as follows + // Trace(__FUNCTION__, __LINE__); + + LOGF(info, "\033[1;32m%s .... line %d\033[0m", functionName, lineNumber); + + } // void Trace(const char* functionName, int lineNumber) + + //============================================================ + + void Exit() + { + // A simple utility wrapper. Used only during debugging. + // Use directly as: Exit(); + // Line number, function name, formatting, etc, are determinad automatically. + + LOGF(info, "\n\n\n\n\n\n\n\n\n\n"); + exit(1); + + } // void Exit() + + //============================================================ + + void StartFunction(const char* functionName) + { + // A simple utility wrapper, used when tc.fVerbose = true. It merely ensures uniform formatting of notification when the function starts. + + LOGF(info, "\033[1;32mStart %s\033[0m", functionName); // prints in green + + } // void StartFunction(const char* functionName) + + //============================================================ + + void ExitFunction(const char* functionName) + { + // A simple utility wrapper, used when tc.fVerbose = true. It merely ensures uniform formatting of notification when the function exits. + + LOGF(info, "\033[1;32mExit %s\033[0m", functionName); // prints in green + + } // void ExitFunction(const char* functionName) + + //============================================================ + + void printEnvironment() + { + // Print the content of selected environment variables. + + LOGF(info, ""); + LOGF(info, "Environment variables:"); + LOGF(info, " O2_ROOT = %s", std::getenv("O2_ROOT")); + LOGF(info, " O2PHYSICS_ROOT = %s", std::getenv("O2PHYSICS_ROOT")); + LOGF(info, " ROOT_RELEASE = %s", std::getenv("ROOT_RELEASE")); + LOGF(info, " ROOTSYS = %s", std::getenv("ROOTSYS")); + LOGF(info, ""); + + } // void printEnvironment() + + //============================================================ + + void BailOut(bool finalBailout = false) + { + // Use only locally - bail out if maximum number of events was reached, and dump all results by that point in a local ROOT file. + // If fSequentialBailout > 0, bail out is performed each fSequentialBailout events, each time in a new local ROOT file. + // For sequential bailout, the naming scheme of ROOT files is AnalysisResultsBailOut_eh.fEventCounter[eProcessed].root . + // If ROOT file with the same name already exists, BailOut is not performed, since the argument is that + // it's pointless to perform Bailout for same eh.fEventCounter[eProcessed], even if eh.fEventCounter[eTotal] changed. + // Only if finalBailout = true, I will overwrite the existing file with the same name. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // *) Local variables: TBI 20240130 shall I promote 'em to data members + add support for configurables? + TString sBailOutFile = "AnalysisResultsBailOut.root"; + TString sDirectoryFile = "multiparticle-correlations-a-b"; + + // *) For sequential bailout, I need to adapt the ROOT file name each time this function is called: + if (tc.fSequentialBailout > 0) { + sBailOutFile.ReplaceAll(".root", Form("_%d.root", eh.fEventCounter[eProcessed])); // replaces in-place + // basically, at 1st call "AnalysisResultsBailOut.root" => "AnalysisResultsBailOut_1*eh.fEventCounter[eProcessed].root", + // at 2nd call "AnalysisResultsBailOut.root" => "AnalysisResultsBailOut_2*eh.fEventCounter[eProcessed].root", etc. + if (!finalBailout && !gSystem->AccessPathName(sBailOutFile.Data(), kFileExists)) { // only for finalBailout = true, I will overwrite the existing file with the same name. + LOGF(info, "\033[1;33m\nsBailOutFile = %s already exits, that means that eh.fEventCounter[eProcessed] is the same as in the previous call of BailOut.\nJust skipping and waiting more events to pass selection criteria... \033[0m", sBailOutFile.Data()); + return; + } + } + + // *) Info message: + if (eh.fEventHistograms[eNumberOfEvents][eRec][eAfter]) { + LOGF(info, "\033[1;32m=> Per request, bailing out after %d selected events in the local file %s .\n\033[0m", static_cast(eh.fEventHistograms[eNumberOfEvents][eRec][eAfter]->GetBinContent(1)), sBailOutFile.Data()); + } + + // *) Okay, let's bail out intentionally: + TFile* f = new TFile(sBailOutFile.Data(), "recreate"); + TDirectoryFile* dirFile = new TDirectoryFile(sDirectoryFile.Data(), sDirectoryFile.Data()); + // TBI 20240130 I cannot add here fBaseList directly, since that one is declared as OutputObj + // Therefore, adding one-by-one nested TList's I want to bail out. + // Keep in sync with bookAndNestAllLists(). + TList* bailOutList = new TList(); // this is sort of 'fake' fBaseList + bailOutList->SetOwner(false); // yes, beacause for sequential bailout, with SetOwner(true) the code is crashing after 1st sequential bailout is done + bailOutList->SetName(sBaseListName.Data()); + bailOutList->Add(fBasePro); // yes, this one needs a special treatment + bailOutList->Add(qa.fQAList); + bailOutList->Add(ec.fEventCutsList); + bailOutList->Add(eh.fEventHistogramsList); + bailOutList->Add(pc.fParticleCutsList); + bailOutList->Add(ph.fParticleHistogramsList); + bailOutList->Add(qv.fQvectorList); + bailOutList->Add(mupa.fCorrelationsList); + bailOutList->Add(pw.fWeightsList); + bailOutList->Add(cw.fCentralityWeightsList); + bailOutList->Add(nl.fNestedLoopsList); + bailOutList->Add(nua.fNUAList); + bailOutList->Add(iv.fInternalValidationList); + bailOutList->Add(t0.fTest0List); + bailOutList->Add(es.fEtaSeparationsList); + bailOutList->Add(res.fResultsList); + + // *) Add list with nested list to TDirectoryFile: + dirFile->Add(bailOutList, true); + dirFile->Write(dirFile->GetName(), TObject::kSingleKey + TObject::kOverwrite); + + delete dirFile; + dirFile = NULL; + f->Close(); + + if (tc.fVerbose && !(tc.fSequentialBailout > 0)) { // then it will be called only once, for the only and permanent bailout + ExitFunction(__FUNCTION__); + } + + // *) Hasta la vista: + if (finalBailout) { + LOGF(fatal, "\033[1;31mHasta la vista - bailed out permanently in function %s at line %d\n The output file is: %s\n\n\033[0m", __FUNCTION__, __LINE__, sBailOutFile.Data()); + } else { + LOGF(info, "\033[1;32mBailed out sequentially in function %s at line %d\n The output file is: %s\n\n\033[0m", __FUNCTION__, __LINE__, sBailOutFile.Data()); + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + } + + } // void BailOut(bool finalBailout = false) + + //============================================================ + + void FillQvector(const double& dPhi, const double& dPt, const double& dEta) + { + // !!! OBSOLETE FUNCTION (as of 20250714) !!! + + LOGF(info, "\033[1;33m%s at line %d: !!!! WARNING !!!! As of 20250714, this is an obsolete function, use FillQvectorFromSparse(...) instead (yes, use it also when particles weights are NOT needed) !!!! WARNING !!!! \033[0m", __FUNCTION__, __LINE__); + + return; + + // Fill integrated Q-vector. + // Example usage: this->FillQvector(dPhi, dPt, dEta); + + if (tc.fVerboseForEachParticle) { + StartFunction(__FUNCTION__); + LOGF(info, "\033[1;32m dPhi = %f\033[0m", dPhi); + LOGF(info, "\033[1;32m dPt = %f\033[0m", dPt); + LOGF(info, "\033[1;32m dEta = %f\033[0m", dEta); + } + + // Particle weights: + double wPhi = 1.; // integrated phi weight + double wPt = 1.; // integrated pt weight + double wEta = 1.; // integrated eta weight + double wToPowerP = 1.; // weight raised to power p + + if (pw.fUseWeights[wPHI]) { + wPhi = Weight(dPhi, wPHI); + if (!(wPhi > 0.)) { + LOGF(error, "\033[1;33m%s wPhi is not positive\033[0m", __FUNCTION__); + LOGF(fatal, "dPhi = %f\nwPhi = %f", dPhi, wPhi); + } + } // if(pw.fUseWeights[wPHI]) + + if (pw.fUseWeights[wPT]) { + wPt = Weight(dPt, wPT); // corresponding pt weight + if (!(wPt > 0.)) { + LOGF(error, "\033[1;33m%s wPt is not positive\033[0m", __FUNCTION__); + LOGF(fatal, "dPt = %f\nwPt = %f", dPt, wPt); + } + } // if(pw.fUseWeights[wPT]) + + if (pw.fUseWeights[wETA]) { + wEta = Weight(dEta, wETA); // corresponding eta weight + if (!(wEta > 0.)) { + LOGF(error, "\033[1;33m%s wEta is not positive\033[0m", __FUNCTION__); + LOGF(fatal, "dEta = %f\nwEta = %f", dEta, wEta); + } + } // if(pw.fUseWeights[wETA]) + + if (qv.fCalculateQvectors) { + for (int h = 0; h < gMaxHarmonic * gMaxCorrelator + 1; h++) { + for (int wp = 0; wp < gMaxCorrelator + 1; wp++) { // weight power + if (pw.fUseWeights[wPHI] || pw.fUseWeights[wPT] || pw.fUseWeights[wETA]) { + wToPowerP = std::pow(wPhi * wPt * wEta, wp); + qv.fQvector[h][wp] += TComplex(wToPowerP * std::cos(h * dPhi), wToPowerP * std::sin(h * dPhi)); // Q-vector with weights + // Remark: If ever I will re-use this code, see how I implemented it in void FillQvectorFromSparse() + } else { + qv.fQvector[h][wp] += TComplex(std::cos(h * dPhi), std::sin(h * dPhi)); // bare Q-vector without weights + // Remark: If ever I will re-use this code, see how I implemented it in void FillQvectorFromSparse() + } + } // for(int wp=0;wp 0.) { + for (int e = 0; e < gMaxNumberEtaSeparations; e++) { + if (dEta > es.fEtaSeparationsValues[e] / 2.) { // yes, if eta separation is 0.2, then separation interval runs from -0.1 to 0.1 + qv.fMab[1][e] += wPhi * wPt * wEta; + for (int h = 0; h < gMaxHarmonic; h++) { + { + if (es.fEtaSeparationsSkipHarmonics[h]) { + continue; + } + qv.fQabVector[1][h][e] += TComplex(wPhi * wPt * wEta * std::cos((h + 1) * dPhi), wPhi * wPt * wEta * std::sin((h + 1) * dPhi)); + } + } // for (int h = 0; h < gMaxHarmonic; h++) { + } // for (int e = 0; e < gMaxNumberEtaSeparations; e++) { // eta separation + } + } + } // if(es.fCalculateEtaSeparations) { + + if (tc.fVerboseForEachParticle) { + ExitFunction(__FUNCTION__); + } + + } // void FillQvector(const double& dPhi, const double& dPt, const double& dEta) + + //============================================================ + + void FillQvectorFromSparse() + { + // Fill integrated Q-vector using sparse histograms. + + if (tc.fVerboseForEachParticle) { + StartFunction(__FUNCTION__); + LOGF(info, "\033[1;32m pbyp.fPhi = %f\033[0m", pbyp.fPhi); + LOGF(info, "\033[1;32m pbyp.fPt = %f\033[0m", pbyp.fPt); + LOGF(info, "\033[1;32m pbyp.fEta = %f\033[0m", pbyp.fEta); + LOGF(info, "\033[1;32m pbyp.fCharge = %f\033[0m", pbyp.fCharge); + } + + // Particle weights from sparse histograms: + // Remark: Keep in sync with corresponding implementation in Fillqvectors() + double wPhi = 1.; // differential multidimensional phi weight, its dimensions are defined via enum eDiffPhiWeights + double wPt = 1.; // differential multidimensional pt weight, its dimensions are defined via enum eDiffPtWeights + double wEta = 1.; // differential multidimensional eta weight, its dimensions are defined via enum eDiffEtaWeights + double wToPowerP = 1.; // weight raised to power p + + // *) Multidimensional phi weights: + if (pw.fUseDiffPhiWeights[wPhiPhiAxis]) { // yes, 0th axis serves as a common boolean for this category + wPhi = WeightFromSparse(eDWPhi); + if (!(wPhi > 0.)) { + LOGF(error, "\033[1;33m%s wPhi is not positive\033[0m", __FUNCTION__); + LOGF(error, "pbyp.fPhi = %f", pbyp.fPhi); + if (pw.fUseDiffPhiWeights[wPhiPtAxis]) { + LOGF(fatal, "pbyp.fPt = %f", pbyp.fPt); + } + if (pw.fUseDiffPhiWeights[wPhiEtaAxis]) { + LOGF(fatal, "pbyp.fEta = %f", pbyp.fEta); + } + if (pw.fUseDiffPhiWeights[wPhiChargeAxis]) { + LOGF(fatal, "pbyp.fCharge = %f", pbyp.fCharge); + } + if (pw.fUseDiffPhiWeights[wPhiCentralityAxis]) { + LOGF(fatal, "ebye.fCentrality = %f", ebye.fCentrality); + } + if (pw.fUseDiffPhiWeights[wPhiVertexZAxis]) { + LOGF(fatal, "ebye.fVz = %f", ebye.fVz); + } + LOGF(fatal, "Multidimensional weight for enabled dimensions is wPhi = %f", wPhi); + } + } // if(pw.fUseDiffPhiWeights[wPhiPhiAxis]) + + // *) Multidimensional pt weights: + if (pw.fUseDiffPtWeights[wPtPtAxis]) { // yes, 0th axis serves as a common boolean for this category + wPt = WeightFromSparse(eDWPt); + if (!(wPt > 0.)) { + LOGF(error, "\033[1;33m%s wPt is not positive\033[0m", __FUNCTION__); + LOGF(error, "pbyp.fPt = %f", pbyp.fPt); + if (pw.fUseDiffPtWeights[wPtChargeAxis]) { + LOGF(fatal, "pbyp.fCharge = %f", pbyp.fCharge); + } + if (pw.fUseDiffPtWeights[wPtCentralityAxis]) { + LOGF(fatal, "ebye.fCentrality = %f", ebye.fCentrality); + } + LOGF(fatal, "Multidimensional weight for enabled dimensions is wPt = %f", wPt); + } + } // if(pw.fUseDiffPtWeights[wPtPtAxis]) + + // *) Multidimensional eta weights: + if (pw.fUseDiffEtaWeights[wEtaEtaAxis]) { // yes, 0th axis serves as a common boolean for this category + wEta = WeightFromSparse(eDWEta); + if (!(wEta > 0.)) { + LOGF(error, "\033[1;33m%s wEta is not positive\033[0m", __FUNCTION__); + LOGF(error, "pbyp.fEta = %f", pbyp.fEta); + if (pw.fUseDiffEtaWeights[wEtaChargeAxis]) { + LOGF(fatal, "pbyp.fCharge = %f", pbyp.fCharge); + } + if (pw.fUseDiffEtaWeights[wEtaCentralityAxis]) { + LOGF(fatal, "ebye.fCentrality = %f", ebye.fCentrality); + } + LOGF(fatal, "Multidimensional weight for enabled dimensions is wEta = %f", wEta); + } + } // if(pw.fUseDiffEtaWeights[wEtaEtaAxis]) + + if (qv.fCalculateQvectors) { + for (int h = 0; h < gMaxHarmonic * gMaxCorrelator + 1; h++) { + for (int wp = 0; wp < gMaxCorrelator + 1; wp++) { // weight power + if (pw.fUseDiffPhiWeights[wPhiPhiAxis] || pw.fUseDiffPtWeights[wPtPtAxis] || pw.fUseDiffEtaWeights[wEtaEtaAxis]) { + wToPowerP = std::pow(wPhi * wPt * wEta, wp); + qv.fQvector[h][wp] += TComplex(wToPowerP * std::cos(h * pbyp.fPhi), wToPowerP * std::sin(h * pbyp.fPhi)); // Q-vector with weights, legacy code (TBI 20251027 remove this line) + // qv.fQvector[h][wp] += std::complex(wToPowerP * std::cos(h * pbyp.fPhi), wToPowerP * std::sin(h * pbyp.fPhi)); // Q-vector with weights, new code + // TBI 20251028 I have to keep it this way for the time being, otherwise I have to change all over the place, e.g. in TComplex Q(int n, int wp), etc. + } else { + qv.fQvector[h][wp] += TComplex(std::cos(h * pbyp.fPhi), std::sin(h * pbyp.fPhi)); // bare Q-vector without weights, legacy code (TBI 20251027 remove this line) + // qv.fQvector[h][wp] += std::complex(std::cos(h * pbyp.fPhi), std::sin(h * pbyp.fPhi)); // bare Q-vector without weights, new code + // TBI 20251028 I have to keep it this way for the time being, otherwise I have to change all over the place, e.g. in TComplex Q(int n, int wp), etc. + } + } // for(int wp=0;wp (but it's a major modification, see the comment above within if (qv.fCalculateQvectors) ) + } + } // for (int h = 0; h < gMaxHarmonic; h++) { + } // for (int e = 0; e < gMaxNumberEtaSeparations; e++) { // eta separation + } else if (pbyp.fEta > 0.) { + for (int e = 0; e < gMaxNumberEtaSeparations; e++) { + if (pbyp.fEta > es.fEtaSeparationsValues[e] / 2.) { // yes, if eta separation is 0.2, then separation interval runs from -0.1 to 0.1 + qv.fMab[1][e] += wPhi * wPt * wEta; + for (int h = 0; h < gMaxHarmonic; h++) { + { + if (es.fEtaSeparationsSkipHarmonics[h]) { + continue; + } + qv.fQabVector[1][h][e] += TComplex(wPhi * wPt * wEta * std::cos((h + 1) * pbyp.fPhi), wPhi * wPt * wEta * std::sin((h + 1) * pbyp.fPhi)); + // TBI 20251028 Replace TComplex with std::complex (but it's a major modification, see the comment above within if (qv.fCalculateQvectors) ) + // Remark: I can hardwire linear weights like this only for 2-p correlations + } + } // for (int h = 0; h < gMaxHarmonic; h++) { + } // for (int e = 0; e < gMaxNumberEtaSeparations; e++) { // eta separation + } + } + } // if(es.fCalculateEtaSeparations) { + + if (tc.fVerboseForEachParticle) { + ExitFunction(__FUNCTION__); + } + + } // void FillQvectorFromSparse() + + //============================================================ + + void Fillqvector(const double& dPhi, const double& kineVarValue, eqvectorKine kineVarChoice, const double& dEta = 0.) + { + // !!! OBSOLETE FUNCTION (as of 20250527) !!! + + LOGF(info, "\033[1;33m%s at line %d: !!!! WARNING !!!! As of 20250527, this is an obsolete function, use Fillqvectors() instead (yes, plural!) + its helper function(s) !!!! WARNING !!!! \033[0m", __FUNCTION__, __LINE__); + + return; + + // Fill differential q-vector, in generic kinematic variable. Here "kine" originally meant vs. pt or vs. eta, now it's general. + // Example usage #1: this->Fillqvector(dPhi, dPt, PTq); // differential q-vectors without using eta separations + // Example usage #2: this->Fillqvector(dPhi, dPt, PTq, dEta); // differential q-vectors with using eta separations (I need dEta of particle to decide whether particle is added to qa or qb) + + // Remark: As of 20250527, this function is obsolete, and it's superseeded by more general functions: + // a) void FillqvectorNdim(...) (without particle weights) + // b) void FillqvectorNdimFromSparse(...) (with particle weights) + // Remark: As of 20251027, FillqvectorNdim(...) and FillqvectorNdimFromSparse(...) are also obsolete, use instead Fillqvectors() (yes, plural!) + its helper function(s) + + if (tc.fVerboseForEachParticle) { + StartFunction(__FUNCTION__); + } + + // *) Mapping between enum's "eqvectorKine" on one side, and "eAsFunctionOf", "eWeights" and "eDiffWeights" on the other: + // TBI 20240212 I could promote this also to a member function, if I need it elsewhere. Or I could use TExMap? + eAsFunctionOf AFO_var = eAsFunctionOf_N; // this local variable determines the enum "eAsFunctionOf" which corresponds to enum "eqvectorKine" + eWeights AFO_weight = eWeights_N; // this local variable determines the enum "eWeights" which corresponds to enum "eqvectorKine" + eDiffWeights AFO_diffWeight = eDiffWeights_N; // this local variable determines the enum "eDiffWeights" which corresponds to enum "eqvectorKine" + switch (kineVarChoice) { + case PTq: { + AFO_var = AFO_PT; + AFO_weight = wPT; + AFO_diffWeight = wPHIPT; // TBI 20250215 this is now obsolete, see the comment in enum + break; + } + case ETAq: { + AFO_var = AFO_ETA; + AFO_weight = wETA; + AFO_diffWeight = wPHIETA; // TBI 20250215 this is now obsolete, see the comment in enum + break; + } + case CHARGEq: { + AFO_var = AFO_CHARGE; + AFO_weight = wCHARGE; + AFO_diffWeight = wPHICHARGE; // TBI 20250215 this is now obsolete, see the comment in enum + break; + } + default: { + LOGF(fatal, "\033[1;31m%s at line %d : this kineVarChoice = %d is not supported yet. \033[0m", __FUNCTION__, __LINE__, static_cast(kineVarChoice)); + break; + } + } // switch(kineVarChoice) + + // *) Insanity checks on above settings: + if (AFO_var == eAsFunctionOf_N) { + LOGF(fatal, "\033[1;31m%s at line %d : AFO_var == eAsFunctionOf_N => add some more entries to the case statement \033[0m", __FUNCTION__, __LINE__); + } + if (AFO_weight == eWeights_N) { + LOGF(fatal, "\033[1;31m%s at line %d : AFO_weight == eWeights_N => add some more entries to the case statement \033[0m", __FUNCTION__, __LINE__); + } + if (AFO_diffWeight == eDiffWeights_N) { + LOGF(fatal, "\033[1;31m%s at line %d : AFO_diffWeight == eDiffWeights_N => add some more entries to the case statement \033[0m", __FUNCTION__, __LINE__); + } + + // *) Get the desired bin number: + int bin = -1; + if (res.fResultsPro[AFO_var]) { + bin = res.fResultsPro[AFO_var]->FindBin(kineVarValue); // this 'bin' starts from 1, i.e. this is genuine histogram bin + if (0 >= bin || res.fResultsPro[AFO_var]->GetNbinsX() < bin) { // either underflow or overflow is hit, meaning that histogram is booked in narrower range than cuts + LOGF(fatal, "\033[1;31m%s at line %d : kineVarChoice = %d, bin = %d, kineVarValue = %f \033[0m", __FUNCTION__, __LINE__, static_cast(kineVarChoice), bin, kineVarValue); + } + } + + // *) Get all integrated kinematic weights: + double wToPowerP = 1.; // weight raised to power p + double kineVarWeight = 1.; // e.g. this can be integrated pT or eta weight + if (pw.fUseWeights[AFO_weight]) { + kineVarWeight = Weight(kineVarValue, AFO_weight); // corresponding e.g. pt or eta weight + if (!(kineVarWeight > 0.)) { + LOGF(fatal, "\033[1;31m%s at line %d : kineVarWeight is not positive \033[0m", __FUNCTION__, __LINE__); + // TBI 20240212 or could I just skip this particle? + } + } // if(fUseWeights[AFO_weight]) { + + // *) Get all differential phi-weights for this kinematic variable: + // Remark: special treatment is justified for phi-weights, because q-vector is defined in terms of phi-weights. + double diffPhiWeightsForThisKineVar = 1.; + if (pw.fUseDiffWeights[AFO_diffWeight]) { + diffPhiWeightsForThisKineVar = DiffWeight(dPhi, kineVarValue, kineVarChoice); // corresponding differential phi weight as a function of e.g. pt or eta + if (!(diffPhiWeightsForThisKineVar > 0.)) { + LOGF(fatal, "\033[1;31m%s at line %d : diffPhiWeightsForThisKineVar is not positive \033[0m", __FUNCTION__, __LINE__); + // TBI 20240212 or could I just skip this particle? + } + } // if(pw.fUseDiffWeights[AFO_diffWeight]) { + + // *) Finally, fill differential q-vector in that bin: + for (int h = 0; h < gMaxHarmonic * gMaxCorrelator + 1; h++) { + for (int wp = 0; wp < gMaxCorrelator + 1; wp++) { // weight power + if (pw.fUseWeights[AFO_weight] || pw.fUseDiffWeights[AFO_diffWeight]) { + // TBI 20240212 supported at the moment: e.g. q-vector vs pt can be weighted only with diff. phi(pt) and integrated pt weights. + // It cannot be weighted in addition with eta weights, since in any case I anticipate I will do always 1-D analysis, by integrating out all other dependencies + wToPowerP = std::pow(diffPhiWeightsForThisKineVar * kineVarWeight, wp); + qv.fqvector[kineVarChoice][bin - 1][h][wp] += TComplex(wToPowerP * std::cos(h * dPhi), wToPowerP * std::sin(h * dPhi)); // q-vector with weights + } else { + qv.fqvector[kineVarChoice][bin - 1][h][wp] += TComplex(std::cos(h * dPhi), std::sin(h * dPhi)); // bare q-vector without weights + } + } // for(int wp=0;wpAddAt(dPhi, qv.fqvectorEntries[kineVarChoice][bin - 1]); + nl.ftaNestedLoopsKine[kineVarChoice][bin - 1][1]->AddAt(diffPhiWeightsForThisKineVar * kineVarWeight, qv.fqvectorEntries[kineVarChoice][bin - 1]); + } + + // *) Multiplicity counter in this bin: + qv.fqvectorEntries[kineVarChoice][bin - 1]++; // count number of particles in this pt bin in this event + + // *) Usage of eta separations in differential correlations: + if (es.fCalculateEtaSeparations && es.fCalculateEtaSeparationsAsFunctionOf[AFO_var]) { // yes, I can decouple this one from if (qv.fCalculateQvectors) + + if (AFO_var == AFO_ETA) { + LOGF(fatal, "\033[1;31m%s at line %d : AFO_var == AFO_ETA . This doesn't make any sense in this context. \033[0m", __FUNCTION__, __LINE__); + } + + if (dEta < 0.) { + for (int e = 0; e < gMaxNumberEtaSeparations; e++) { + if (dEta < -1. * es.fEtaSeparationsValues[e] / 2.) { // yes, if eta separation is 0.2, then separation interval runs from -0.1 to 0.1 + // qv.fmab[0][bin - 1][e] += diffPhiWeightsForThisKineVar * kineVarWeight; // Remark: I can hardwire linear weight like this only for 2-p correlation + // TBI 20250616 I cannot use this any longer, after i added one more dimension + for (int h = 0; h < gMaxHarmonic; h++) { + if (es.fEtaSeparationsSkipHarmonics[h]) { + continue; + } + // qv.fqabVector[0][bin - 1][h][e] += TComplex(diffPhiWeightsForThisKineVar * kineVarWeight * std::cos((h + 1) * dPhi), diffPhiWeightsForThisKineVar * kineVarWeight * std::sin((h + 1) * dPhi)); // TBI 20250616 I cannot use this any longer, after I added one more dimension to qv.fqabVector + } + } // for (int h = 0; h < gMaxHarmonic; h++) { + } // for (int e = 0; e < gMaxNumberEtaSeparations; e++) { // eta separation + } else if (dEta > 0.) { + for (int e = 0; e < gMaxNumberEtaSeparations; e++) { + if (dEta > es.fEtaSeparationsValues[e] / 2.) { // yes, if eta separation is 0.2, then separation interval runs from -0.1 to 0.1 + // qv.fmab[1][bin - 1][e] += diffPhiWeightsForThisKineVar * kineVarWeight; // Remark: I can hardwire linear weight like this only for 2-p correlation + // TBI 20250616 I cannot use this any longer, after i added one more dimension + for (int h = 0; h < gMaxHarmonic; h++) { + { + if (es.fEtaSeparationsSkipHarmonics[h]) { + continue; + } + // qv.fqabVector[1][bin - 1][h][e] += TComplex(diffPhiWeightsForThisKineVar * kineVarWeight * std::cos((h + 1) * dPhi), diffPhiWeightsForThisKineVar * kineVarWeight * std::sin((h + 1) * dPhi)); // Remark: I can hardwire linear weight like this only for 2-p correlation // TBI 20250616 I cannot use this any longer, after I added one more dimension to qv.fqabVector + } + } // for (int h = 0; h < gMaxHarmonic; h++) { + } // for (int e = 0; e < gMaxNumberEtaSeparations; e++) { // eta separation + } + } + } // if(es.fCalculateEtaSeparations) { + + if (tc.fVerboseForEachParticle) { + ExitFunction(__FUNCTION__); + } + + } // void Fillqvector(const double& dPhi, const double& kineVarValue, eqvectorKine kineVarChoice) + + //============================================================ + + eAsFunctionOf AfoKineMap1D(eqvectorKine kineVarChoice) + { + // Simple utility function to map for the 1-dimensional case eqvectorKine into eAsFunctionOf. + + if (tc.fVerboseForEachParticle) { + StartFunction(__FUNCTION__); + } + + eAsFunctionOf AFO_var = eAsFunctionOf_N; + + switch (kineVarChoice) { + + case PTq: { + AFO_var = AFO_PT; + break; + } + + case ETAq: { + AFO_var = AFO_ETA; + break; + } + + case CHARGEq: { + AFO_var = AFO_CHARGE; + break; + } + + // ... + + default: { + LOGF(fatal, "\033[1;31m%s at line %d : this kineVarChoice = %d is not supported yet for 1D case. \033[0m", __FUNCTION__, __LINE__, static_cast(kineVarChoice)); + break; + } + + } // switch(kineVarChoice) + + if (tc.fVerboseForEachParticle) { + ExitFunction(__FUNCTION__); + } + + return AFO_var; + + } // eAsFunctionOf AfoKineMap1D(eqvectorKine kineVarChoice) + + //============================================================ + + eAsFunctionOf2D AfoKineMap2D(eqvectorKine kineVarChoice) + { + // Simple utility function to map for the 2-dimensional case eqvectorKine into eAsFunctionOf2D. + + if (tc.fVerboseForEachParticle) { + StartFunction(__FUNCTION__); + } + + eAsFunctionOf2D AFO_var = eAsFunctionOf2D_N; + + switch (kineVarChoice) { + + case PT_ETAq: { + AFO_var = AFO_PT_ETA; + break; + } + + case PT_CHARGEq: { + AFO_var = AFO_PT_CHARGE; + break; + } + + case ETA_CHARGEq: { + AFO_var = AFO_ETA_CHARGE; + break; + } + + // ... + + default: { + LOGF(fatal, "\033[1;31m%s at line %d : this kineVarChoice = %d is not supported yet for 2D case. \033[0m", __FUNCTION__, __LINE__, static_cast(kineVarChoice)); + break; + } + + } // switch(kineVarChoice) + + if (tc.fVerboseForEachParticle) { + ExitFunction(__FUNCTION__); + } + + return AFO_var; + + } // eAsFunctionOf2D AfoKineMap2D(eqvectorKine kineVarChoice) + + //============================================================ + + eAsFunctionOf3D AfoKineMap3D(eqvectorKine kineVarChoice) + { + // Simple utility function to map for the 3-dimensional case eqvectorKine into eAsFunctionOf3D. + + if (tc.fVerboseForEachParticle) { + StartFunction(__FUNCTION__); + } + + eAsFunctionOf3D AFO_var = eAsFunctionOf3D_N; + + switch (kineVarChoice) { + + case PT_ETA_CHARGEq: { + AFO_var = AFO_PT_ETA_CHARGE; + break; + } + + // ... + + default: { + LOGF(fatal, "\033[1;31m%s at line %d : this kineVarChoice = %d is not supported yet for 3D case. \033[0m", __FUNCTION__, __LINE__, static_cast(kineVarChoice)); + break; + } + + } // switch(kineVarChoice) + + if (tc.fVerboseForEachParticle) { + ExitFunction(__FUNCTION__); + } + + return AFO_var; + + } // eAsFunctionOf3D AfoKineMap3D(eqvectorKine kineVarChoice) + + //============================================================ + + TString StringKineMap(eqvectorKine kineVarChoice) + { + // Simple utility function to map eqvectorKine into string. + + // Example: StringKineMap(PTq).Data() => prints "vs. pt" + + if (tc.fVerboseForEachParticle) { + StartFunction(__FUNCTION__); + } + + TString s = ""; + + switch (kineVarChoice) { + + case PTq: { + s = "vs. pt"; + break; + } + + case ETAq: { + s = "vs. eta"; + break; + } + + case CHARGEq: { + s = "vs. charge"; + break; + } + + case PT_ETAq: { + s = "vs. pt vs. eta"; + break; + } + + case PT_CHARGEq: { + s = "vs. pt vs. charge"; + break; + } + + case ETA_CHARGEq: { + s = "vs. eta vs. charge"; + break; + } + + case PT_ETA_CHARGEq: { + s = "vs. pt vs. eta vs. charge"; + break; + } + + // ... + + default: { + LOGF(fatal, "\033[1;31m%s at line %d : this kineVarChoice = %d is not supported yet. \033[0m", __FUNCTION__, __LINE__, static_cast(kineVarChoice)); + break; + } + + } // switch(kineVarChoice) + + if (tc.fVerboseForEachParticle) { + ExitFunction(__FUNCTION__); + } + + return s; + + } // TString StringKineMap(eqvectorKine kineVarChoice) + + //============================================================ + + void FillqvectorNdim(const double& dPhi, double* kineVarValues, int Ndim, eqvectorKine kineVarChoice, const double& dEta = 0.) + { + // !!! OBSOLETE FUNCTION (as of 20250717) !!! + + LOGF(info, "\033[1;33m%s at line %d: !!!! WARNING !!!! As of 20250717, this is an obsolete function, use Fillqvectors(...) and its helper function FillqvectorFromSparse(...) instead !!!! WARNING !!!! \033[0m", __FUNCTION__, __LINE__); + + return; + + // Fill differential q-vector in N dimensions, calculated vs. N generic kinematic variables. + // I use this function both when unit and non-unit particle weights are used (there is no really a big performance penalty, i.e. I do not need bare version only for unit weights). + // Here "kine" originally meant vs. pt or vs. eta, now it's general, also multi-dimensional (i.e. "kine" is a "global bin"). + // For more than 1 dimension, e.g. vs. (pt, eta), "kineVarChoice" corresponds to linearized 2D case, in an analogy with "global bin" structure for multidimensional histograms. + + // Remark 0: "kineVarValues" is now an array, e.g. for qvector vs. (pt, eta), it holds pt and eta of a particle. Ndim is dimensionality of that array. + // Remark 1: The last argument "dEta" is meant to be used only for fqabVector (I need dEta of particle to decide whether particle is added to qa or qb). + // Remark 2: "bin" is always meant to be "linearized global bin", therefore I changed indexing here from "bin-1" to "bin". + // Remark 3: Whether or not non-unit weights are used, is determined automatically below with flags pw.fUseDiffPhiWeights, pw.fUseDiffPtWeights, etc., which in turn + // are configured in the JSON + + // Example - the standard 1D case: + // double kineArr[1] = {dPt}; + // this->FillqvectorNdim(dPhi, kineArr, 1, PTq); // differential q-vector vs. pt + + // Example - the 2D case: + // double kineArr[2] = {dPt, dEta}; + // this->FillqvectorNdim(dPhi, kineArr, 2, PT_ETAq); // differential q-vector vs. (pt, eta) + + // Example - the 3D case: + // double kineArr[3] = {dPt, dEta, dCharge}; + // this->FillqvectorNdim(dPhi, kineArr, 3, PT_ETA_CHARGEq); // differential q-vector vs. (pt, eta, charge) + + // Example - the 1D case, pt dependence with eta separations: + // double kineArr[1] = {dPt}; + // this->FillqvectorNdim(dPhi, kineArr, 1, PTq, dEta); // differential q-vectors with using eta separations (I need dEta of particle to decide whether particle is added to qa or qb) + + if (tc.fVerboseForEachParticle) { + StartFunction(__FUNCTION__); + } + + // This is the linearized global bin, the 2nd index of fqvector[...][gMaxNoBinsKine][...][...], it shall work transparently for 1D, 2D, 3D, etc... + // Yes, it is also the 3rd index of fqabVector[...][...][gMaxNoBinsKine][...][...] + int bin = -1; + + switch (Ndim) { + + case 1: { + eAsFunctionOf AFO_var = AfoKineMap1D(kineVarChoice); + if (res.fResultsPro[AFO_var]) { + bin = res.fResultsPro[AFO_var]->FindBin(kineVarValues[0]); // this is linearized 'global bin', for 1D it's the same as ordinary bin + + // TBI 20250528 check if the test below is computationally heavy. If so, add the flag tc.fInsanityCheckForEachParticle here. + if (res.fResultsPro[AFO_var]->IsBinUnderflow(bin) || res.fResultsPro[AFO_var]->IsBinOverflow(bin)) { + LOGF(fatal, "\033[1;31m%s at line %d : kineVarChoice = %d (%s), kineVarValues[0] = %f is in bin = %d, which is either underflow or overflow.\033[0m", __FUNCTION__, __LINE__, static_cast(kineVarChoice), StringKineMap(kineVarChoice).Data(), kineVarValues[0], bin); + } + } + break; + } + + case 2: { + eAsFunctionOf2D AFO_var = AfoKineMap2D(kineVarChoice); + if (res.fResultsPro2D[AFO_var]) { + bin = res.fResultsPro2D[AFO_var]->FindBin(kineVarValues[0], kineVarValues[1]); // this is linearized 'global bin' + + // TBI 20250528 check if the test below is computationally heavy. If so, add the flag tc.fInsanityCheckForEachParticle here. + if (res.fResultsPro2D[AFO_var]->IsBinUnderflow(bin) || res.fResultsPro2D[AFO_var]->IsBinOverflow(bin)) { + LOGF(fatal, "\033[1;31m%s at line %d : kineVarChoice = %d (%s), kineVarValues[0] = %f, kineVarValues[1] = %f is in global bin = %d, which is either underflow or overflow.\033[0m", __FUNCTION__, __LINE__, static_cast(kineVarChoice), StringKineMap(kineVarChoice).Data(), kineVarValues[0], kineVarValues[1], bin); + } + } + break; + } + + case 3: { + eAsFunctionOf3D AFO_var = AfoKineMap3D(kineVarChoice); + if (res.fResultsPro3D[AFO_var]) { + bin = res.fResultsPro3D[AFO_var]->FindBin(kineVarValues[0], kineVarValues[1], kineVarValues[2]); // this is linearized 'global bin' + + // TBI 20250528 check if the test below is computationally heavy. If so, add the flag tc.fInsanityCheckForEachParticle here. + if (res.fResultsPro3D[AFO_var]->IsBinUnderflow(bin) || res.fResultsPro3D[AFO_var]->IsBinOverflow(bin)) { + LOGF(fatal, "\033[1;31m%s at line %d : kineVarChoice = %d (%s), kineVarValues[0] = %f, kineVarValues[1] = %f, kineVarValues[2] = %f is in global bin = %d, which is either underflow or overflow.\033[0m", __FUNCTION__, __LINE__, static_cast(kineVarChoice), StringKineMap(kineVarChoice).Data(), kineVarValues[0], kineVarValues[1], kineVarValues[2], bin); + } + } + break; + } + + // ... + + default: { + LOGF(fatal, "\033[1;31m%s at line %d : Ndim = %d is not supported yet. \033[0m", __FUNCTION__, __LINE__, Ndim); + break; + } + + } // switch (Ndim) + + // TBI 20250715 I need to review and most likely redesign the code below - but since this function is now obsolete, it's irrelevant + return; // TBI 20250716 remove eventually, here is just a protection against using the code below + + // Particle weights from sparse histograms: + // Remark: Keep in sync with corresponding implementation in FillQvectorFromSparse + double wPhi = 1.; // differential multidimensional phi weight, its dimensions are defined via enum eDiffPhiWeights + double wPt = 1.; // differential multidimensional pt weight, its dimensions are defined via enum eDiffPtWeights + double wEta = 1.; // differential multidimensional eta weight, its dimensions are defined via enum eDiffEtaWeights + double wToPowerP = 1.; // weight raised to power p + + // *) Multidimensional phi weights: + if (pw.fUseDiffPhiWeights[wPhiPhiAxis]) { // yes, 0th axis serves as a common boolean for this category + switch (kineVarChoice) { + case PTq: { + // wPhi = WeightFromSparse(dPhi, kineVarValues[0], 0., 0., eDWPhi); + break; + } + case ETAq: { + // wPhi = WeightFromSparse(dPhi, 0., kineVarValues[0], 0., eDWPhi); + break; + } + case CHARGEq: { + // wPhi = WeightFromSparse(dPhi, 0., 0., kineVarValues[0], eDWPhi); + break; + } + case PT_ETAq: { + // wPhi = WeightFromSparse(dPhi, kineVarValues[0], kineVarValues[1], 0., eDWPhi); + break; + } + case PT_CHARGEq: { + // wPhi = WeightFromSparse(dPhi, kineVarValues[0], 0., kineVarValues[1], eDWPhi); + break; + } + case ETA_CHARGEq: { + // wPhi = WeightFromSparse(dPhi, 0., kineVarValues[0], kineVarValues[1], eDWPhi); + break; + } + case PT_ETA_CHARGEq: { + // wPhi = WeightFromSparse(dPhi, kineVarValues[0], kineVarValues[1], kineVarValues[2], eDWPhi); + break; + } + + // ... + + default: { + LOGF(fatal, "\033[1;31m%s at line %d : kineVarChoice = %d is not supported yet. \033[0m", __FUNCTION__, __LINE__, static_cast(kineVarChoice)); + break; + } + } + + // last argument is enum eDiffWeightCategory. Event quantities, e.g. centrality and vz, I do not need to pass, because + // for them I have ebye data members + if (!(wPhi > 0.)) { + LOGF(error, "\033[1;33m%s wPhi is not positive\033[0m", __FUNCTION__); + LOGF(error, "dPhi = %f", dPhi); + LOGF(fatal, "Multidimensional weight for enabled dimensions is wPhi = %f", wPhi); + } + } // if(pw.fUseDiffPhiWeights[wPhiPhiAxis]) + + // *) Multidimensional pt weights: + if (pw.fUseDiffPtWeights[wPtPtAxis]) { // yes, 0th axis serves as a common boolean for this category + switch (kineVarChoice) { + case PTq: { + // wPt = WeightFromSparse(dPhi, kineVarValues[0], 0., 0., eDWPt); + break; + } + case CHARGEq: { + // wPt = WeightFromSparse(dPhi, 0., 0., kineVarValues[0], eDWPt); + break; + } + + // ... + + default: { + LOGF(fatal, "\033[1;31m%s at line %d : kineVarChoice = %d is not supported yet. \033[0m", __FUNCTION__, __LINE__, static_cast(kineVarChoice)); + break; + } + } + + if (!(wPt > 0.)) { + LOGF(error, "\033[1;33m%s wPt is not positive\033[0m", __FUNCTION__); + // LOGF(error, "dPt = %f", dPt); + LOGF(fatal, "Multidimensional weight for enabled dimensions is wPt = %f", wPt); + } + } // if(pw.fUseDiffPtWeights[wPtPtAxis]) + + // *) Multidimensional eta weights: + if (pw.fUseDiffEtaWeights[wEtaEtaAxis]) { // yes, 0th axis serves as a common boolean for this category + switch (kineVarChoice) { + case ETAq: { + // wEta = WeightFromSparse(dPhi, 0., kineVarValues[0], 0., eDWEta); + break; + } + case CHARGEq: { + // wEta = WeightFromSparse(dPhi, 0., 0., kineVarValues[0], eDWEta); + break; + } + + // ... + + default: { + LOGF(fatal, "\033[1;31m%s at line %d : kineVarChoice = %d is not supported yet. \033[0m", __FUNCTION__, __LINE__, static_cast(kineVarChoice)); + break; + } + } + + if (!(wEta > 0.)) { + LOGF(error, "\033[1;33m%s wEta is not positive\033[0m", __FUNCTION__); + // LOGF(error, "dEta = %f", dEta); + LOGF(fatal, "Multidimensional weight for enabled dimensions is wEta = %f", wEta); + } + } // if(pw.fUseDiffEtaWeights[wEtaEtaAxis]) + + // *) Finally, fill differential q-vector in that linearized "global bin": + for (int h = 0; h < gMaxHarmonic * gMaxCorrelator + 1; h++) { + for (int wp = 0; wp < gMaxCorrelator + 1; wp++) { // weight power + if (pw.fUseDiffPhiWeights[wPhiPhiAxis] || pw.fUseDiffPtWeights[wPtPtAxis] || pw.fUseDiffEtaWeights[wEtaEtaAxis]) { + wToPowerP = std::pow(wPhi * wPt * wEta, wp); + qv.fqvector[kineVarChoice][bin][h][wp] += std::complex(wToPowerP * std::cos(h * dPhi), wToPowerP * std::sin(h * dPhi)); // q-vector with weights + } else { + qv.fqvector[kineVarChoice][bin][h][wp] += std::complex(std::cos(h * dPhi), std::sin(h * dPhi)); // bare q-vector without weights + } + } // for(int wp=0;wpAddAt(dPhi, qv.fqvectorEntries[kineVarChoice][bin]); + nl.ftaNestedLoopsKine[kineVarChoice][bin][1]->AddAt(wPhi * wPt * wEta, qv.fqvectorEntries[kineVarChoice][bin]); + } + + // *) Multiplicity counter in this bin: + qv.fqvectorEntries[kineVarChoice][bin]++; // count number of particles in this differential bin in this event + + // *) Usage of eta separations in differential correlations: + if (es.fCalculateEtaSeparations && qv.fCalculateqvectorsKineEtaSeparations[kineVarChoice]) { // yes, I have decoupled this one from if (qv.fCalculateQvectors) + + if (kineVarChoice == ETAq || kineVarChoice == PT_ETAq || kineVarChoice == ETA_CHARGEq || kineVarChoice == PT_ETA_CHARGEq) { + LOGF(fatal, "\033[1;31m%s at line %d : kineVarChoice == %s . This doesn't make any sense in this context => eta separations cannot be used for differential vectors vs. eta (either 1D or 2D or 3D case). \033[0m", __FUNCTION__, __LINE__, StringKineMap(kineVarChoice).Data()); + } + + if (dEta < 0.) { + for (int e = 0; e < gMaxNumberEtaSeparations; e++) { + if (dEta < -1. * es.fEtaSeparationsValues[e] / 2.) { // yes, if eta separation is 0.2, then separation interval runs from -0.1 to 0.1 + qv.fmab[0][kineVarChoice][bin][e] += wPhi * wPt * wEta; // Remark: I can hardwire linear weight like this only for 2-p correlation + for (int h = 0; h < gMaxHarmonic; h++) { + if (es.fEtaSeparationsSkipHarmonics[h]) { + continue; + } + qv.fqabVector[0][kineVarChoice][bin][h][e] += std::complex(wPhi * wPt * wEta * std::cos((h + 1) * dPhi), wPhi * wPt * wEta * std::sin((h + 1) * dPhi)); // Remark: I can hardwire linear weight like this only for 2-p correlation + } + } // for (int h = 0; h < gMaxHarmonic; h++) { + } // for (int e = 0; e < gMaxNumberEtaSeparations; e++) { // eta separation + } else if (dEta > 0.) { + for (int e = 0; e < gMaxNumberEtaSeparations; e++) { + if (dEta > es.fEtaSeparationsValues[e] / 2.) { // yes, if eta separation is 0.2, then separation interval runs from -0.1 to 0.1 + qv.fmab[1][kineVarChoice][bin][e] += wPhi * wPt * wEta; // Remark: I can hardwire linear weight like this only for 2-p correlation + for (int h = 0; h < gMaxHarmonic; h++) { + { + if (es.fEtaSeparationsSkipHarmonics[h]) { + continue; + } + qv.fqabVector[1][kineVarChoice][bin][h][e] += std::complex(wPhi * wPt * wEta * std::cos((h + 1) * dPhi), wPhi * wPt * wEta * std::sin((h + 1) * dPhi)); // Remark: I can hardwire linear weight like this only for 2-p correlation + } + } // for (int h = 0; h < gMaxHarmonic; h++) { + } // for (int e = 0; e < gMaxNumberEtaSeparations; e++) { // eta separation + } + } + } // if(es.fCalculateEtaSeparations) + + if (tc.fVerboseForEachParticle) { + ExitFunction(__FUNCTION__); + } + + } // void FillqvectorNdim(const double& dPhi, double* kineVarValues, int Ndim, eqvectorKine kineVarChoice, const double& dEta = 0.) + + //============================================================ + + void Fillqvectors() + { + // In this function, I fill all requested differential q-vectors, by calling for each requested case a helper function FillqvectorFromSparse(...). + + // :44 + + if (tc.fVerboseForEachParticle) { + StartFunction(__FUNCTION__); + LOGF(info, "\033[1;32m pbyp.fPhi = %f\033[0m", pbyp.fPhi); + LOGF(info, "\033[1;32m pbyp.fPt = %f\033[0m", pbyp.fPt); + LOGF(info, "\033[1;32m pbyp.fEta = %f\033[0m", pbyp.fEta); + LOGF(info, "\033[1;32m pbyp.fCharge = %f\033[0m", pbyp.fCharge); + } + + // *) Local variables: + int bin = -1; // global kine bin + double wPhi = 1.; // differential multidimensional phi weight, its dimensions are defined via enum eDiffPhiWeights + double wPt = 1.; // differential multidimensional pt weight, its dimensions are defined via enum eDiffPtWeights + double wEta = 1.; // differential multidimensional eta weight, its dimensions are defined via enum eDiffEtaWeights + + /* // TBT + // TBI 20250528 check if the test below is computationally heavy. If so, add the flag tc.fInsanityCheckForEachParticle here. + if (res.fResultsPro[AFO_ETA]->IsBinUnderflow(bin) || res.fResultsPro[AFO_ETA]->IsBinOverflow(bin)) { + LOGF(fatal, "\033[1;31m%s at line %d : kineVarChoice = eta, kineVarValue = %f is in bin = %d, which is either underflow or overflow.\033[0m", __FUNCTION__, __LINE__, pbyp.fEta, bin); + } + */ + + // ** 1D: + + // ***) pt dependence: + if (tc.fCalculateAsFunctionOf[AFO_PT]) { + + // ****) determine global kine bin: + bin = res.fResultsPro[AFO_PT]->FindBin(pbyp.fPt); // I already checked before that res.fResultsPro[AFO_PT] is not NULL in insanityChecksAfterBooking() + + // ****) determine all supported particle weights: + // w_phi(pt): + if (pw.fUseDiffPhiWeights[wPhiPtAxis]) { + wPhi = WeightFromSparse(eDWPhi); + } + // w_pt(pt): + if (pw.fUseDiffPtWeights[wPtPtAxis]) { + wPt = WeightFromSparse(eDWPt); + } + + // ****) finally, fill: + FillqvectorFromSparse(PTq, bin, wPhi * wPt * wEta); // weighted q(pT) filled for global bin to which this pT corresponds + + } // if(tc.fCalculateAsFunctionOf[AFO_PT]) + + // ***) eta dependence: + if (tc.fCalculateAsFunctionOf[AFO_ETA]) { + + // ****) determine global kine bin: + bin = res.fResultsPro[AFO_ETA]->FindBin(pbyp.fEta); + + // ****) determine all supported particle weights: + // w_phi(eta): + if (pw.fUseDiffPhiWeights[wPhiEtaAxis]) { + wPhi = WeightFromSparse(eDWPhi); + } + // w_eta(eta): + if (pw.fUseDiffEtaWeights[wEtaEtaAxis]) { + wEta = WeightFromSparse(eDWEta); + } + + // ****) finally, fill: + FillqvectorFromSparse(ETAq, bin, wPhi * wPt * wEta); // weighted q(eta) filled for global bin to which this eta corresponds + + } // if (mupa.fCalculateCorrelationsAsFunctionOf[AFO_ETA] || t0.fCalculateTest0AsFunctionOf[AFO_ETA]) + + // ***) charge dependence: + if (tc.fCalculateAsFunctionOf[AFO_CHARGE]) { + + // ****) determine global kine bin: + bin = res.fResultsPro[AFO_CHARGE]->FindBin(pbyp.fCharge); + + // ****) determine all supported particle weights: + // w_phi(charge): + if (pw.fUseDiffPhiWeights[wPhiChargeAxis]) { + wPhi = WeightFromSparse(eDWPhi); + } + // w_pt(charge): + if (pw.fUseDiffPtWeights[wPtChargeAxis]) { + wPt = WeightFromSparse(eDWPhi); + } + // w_eta(charge): + if (pw.fUseDiffEtaWeights[wEtaChargeAxis]) { + wEta = WeightFromSparse(eDWPhi); + } + + // ****) finally, fill: + FillqvectorFromSparse(CHARGEq, bin, wPhi * wPt * wEta); // weighted q(charge) filled for global bin to which this charge corresponds + + } // if (mupa.fCalculateCorrelationsAsFunctionOf[AFO_CHARGE] || t0.fCalculateTest0AsFunctionOf[AFO_CHARGE]) + + // ... + + // ** 2D: + + // ***) pt-eta dependence: + if (tc.fCalculate2DAsFunctionOf[AFO_PT_ETA]) { + + bin = res.fResultsPro2D[AFO_PT_ETA]->FindBin(pbyp.fPt, pbyp.fEta); + + // ****) determine all supported particle weights: + // w_phi(pt,eta): + if (pw.fUseDiffPhiWeights[wPhiPtAxis] && pw.fUseDiffPhiWeights[wPhiEtaAxis]) { + wPhi = WeightFromSparse(eDWPhi); + } + + // ****) finally, fill: + FillqvectorFromSparse(PT_ETAq, bin, wPhi * wPt * wEta); // weighted q(pt,eta) filled for global bin to which this (pt,eta) corresponds + + } // if (t0.fCalculate2DTest0AsFunctionOf[AFO_PT_ETA] || t0.fCalculate3DTest0AsFunctionOf[AFO_CENTRALITY_PT_ETA]) + + // ***) pt-charge dependence: + if (tc.fCalculate2DAsFunctionOf[AFO_PT_CHARGE]) { + + // ****) determine global kine bin: + bin = res.fResultsPro2D[AFO_PT_CHARGE]->FindBin(pbyp.fPt, pbyp.fCharge); + + // ****) determine all supported particle weights: + // w_phi(pt,charge): + if (pw.fUseDiffPhiWeights[wPhiPtAxis] && pw.fUseDiffPhiWeights[wPhiChargeAxis]) { + wPhi = WeightFromSparse(eDWPhi); + } + + // ****) finally, fill: + FillqvectorFromSparse(PT_CHARGEq, bin, wPhi * wPt * wEta); // weighted q(pt,charge) filled for global bin to which this (pt,charge) corresponds + + } // if (t0.fCalculate2DTest0AsFunctionOf[AFO_PT_CHARGE] || t0.fCalculate3DTest0AsFunctionOf[AFO_CENTRALITY_PT_CHARGE]) + + // ***) eta-charge dependence: + if (tc.fCalculate2DAsFunctionOf[AFO_ETA_CHARGE]) { + + // ****) determine global kine bin: + bin = res.fResultsPro2D[AFO_ETA_CHARGE]->FindBin(pbyp.fEta, pbyp.fCharge); + + // ****) determine all supported particle weights: + // w_phi(eta,charge): + if (pw.fUseDiffPhiWeights[wEtaChargeAxis] && pw.fUseDiffPhiWeights[wPhiChargeAxis]) { + wPhi = WeightFromSparse(eDWPhi); + } + + // ****) finally, fill: + FillqvectorFromSparse(ETA_CHARGEq, bin, wPhi * wPt * wEta); // weighted q(eta,charge) filled in global bin to which this (eta,charge) corresponds + + } // if (t0.fCalculate2DTest0AsFunctionOf[AFO_ETA_CHARGE] || t0.fCalculate3DTest0AsFunctionOf[AFO_CENTRALITY_ETA_CHARGE]) + + // ... + + // ** 3D: + + // ***) pt-eta-charge dependence: + if (tc.fCalculate3DAsFunctionOf[AFO_PT_ETA_CHARGE]) { + + // ****) determine global kine bin: + bin = res.fResultsPro3D[AFO_PT_ETA_CHARGE]->FindBin(pbyp.fPt, pbyp.fEta, pbyp.fCharge); + + // ****) determine all supported particle weights: + // w_phi(pt,eta,charge): + if (pw.fUseDiffPhiWeights[wPhiPtAxis] && pw.fUseDiffPhiWeights[wPhiEtaAxis] && pw.fUseDiffPhiWeights[wPhiChargeAxis]) { + wPhi = WeightFromSparse(eDWPhi); + } + + // ****) finally, fill: + FillqvectorFromSparse(PT_ETA_CHARGEq, bin, wPhi * wPt * wEta); // weighted q(pt,eta,charge) filled in global bin to which this (pt,eta,charge) corresponds + } + + if (tc.fVerboseForEachParticle) { + ExitFunction(__FUNCTION__); + } + + } // void Fillqvectors() + + //============================================================ + + void FillqvectorFromSparse(const eqvectorKine& kineVarChoice, const int& bin, const double& dWeight) + { + // TBI 20260211 add a comment + document few example use cases + + if (tc.fVerboseForEachParticle) { + StartFunction(__FUNCTION__); + LOGF(info, "\033[1;32m kineVarChoice = %d (%s)\033[0m", static_cast(kineVarChoice), StringKineMap(kineVarChoice).Data()); + LOGF(info, "\033[1;32m bin = %d\033[0m", bin); + LOGF(info, "\033[1;32m dWeight = %f\033[0m", dWeight); + } + + // *) Finally, fill differential q-vector in that linearized "global bin": + double wToPowerP = 1.; // weight raised to power p + + for (int h = 0; h < gMaxHarmonic * gMaxCorrelator + 1; h++) { + for (int wp = 0; wp < gMaxCorrelator + 1; wp++) { // weight power + if (pw.fUseDiffPhiWeights[wPhiPhiAxis] || pw.fUseDiffPtWeights[wPtPtAxis] || pw.fUseDiffEtaWeights[wEtaEtaAxis]) { // yes, because the first enum serves as a boolean for that category + wToPowerP = std::pow(dWeight, wp); // dWeight = wPhi * wPt * wEta + qv.fqvector[kineVarChoice][bin][h][wp] += std::complex(wToPowerP * std::cos(h * pbyp.fPhi), wToPowerP * std::sin(h * pbyp.fPhi)); // q-vector with weights + } else { + qv.fqvector[kineVarChoice][bin][h][wp] += std::complex(std::cos(h * pbyp.fPhi), std::sin(h * pbyp.fPhi)); // bare q-vector without weights + } + } // for(int wp=0;wpAddAt(pbyp.fPhi, qv.fqvectorEntries[kineVarChoice][bin]); + nl.ftaNestedLoopsKine[kineVarChoice][bin][1]->AddAt(dWeight, qv.fqvectorEntries[kineVarChoice][bin]); // dWeight = wPhi * wPt * wEta + } + + // *) Multiplicity counter in this bin: + qv.fqvectorEntries[kineVarChoice][bin]++; // count number of particles in this differential bin in this event + + // *) Usage of eta separations in differential correlations: + if (es.fCalculateEtaSeparations && qv.fCalculateqvectorsKineEtaSeparations[kineVarChoice]) { // yes, I have decoupled this one from if (qv.fCalculateQvectors) + + if (kineVarChoice == ETAq || kineVarChoice == PT_ETAq || kineVarChoice == ETA_CHARGEq || kineVarChoice == PT_ETA_CHARGEq) { + LOGF(fatal, "\033[1;31m%s at line %d : kineVarChoice == %s . This doesn't make any sense in this context => eta separations cannot be used for differential vectors vs. eta (either 1D or 2D or 3D case). \033[0m", __FUNCTION__, __LINE__, StringKineMap(kineVarChoice).Data()); + } + + if (pbyp.fEta < 0.) { + for (int e = 0; e < gMaxNumberEtaSeparations; e++) { + if (pbyp.fEta < -1. * es.fEtaSeparationsValues[e] / 2.) { // yes, if eta separation is 0.2, then separation interval runs from -0.1 to 0.1 + qv.fmab[0][kineVarChoice][bin][e] += dWeight; // dWeight = wPhi * wPt * wEta => Remark: I can hardwire linear weight like this only for 2-p correlation + for (int h = 0; h < gMaxHarmonic; h++) { + if (es.fEtaSeparationsSkipHarmonics[h]) { + continue; + } + qv.fqabVector[0][kineVarChoice][bin][h][e] += std::complex(dWeight * std::cos((h + 1) * pbyp.fPhi), dWeight * std::sin((h + 1) * pbyp.fPhi)); // dWeight = wPhi * wPt * wEta => Remark: I can hardwire linear weight like this only for 2-p correlation + } + } // for (int h = 0; h < gMaxHarmonic; h++) { + } // for (int e = 0; e < gMaxNumberEtaSeparations; e++) { // eta separation + } else if (pbyp.fEta > 0.) { + for (int e = 0; e < gMaxNumberEtaSeparations; e++) { + if (pbyp.fEta > es.fEtaSeparationsValues[e] / 2.) { // yes, if eta separation is 0.2, then separation interval runs from -0.1 to 0.1 + qv.fmab[1][kineVarChoice][bin][e] += dWeight; // dWeight = wPhi * wPt * wEta => Remark: I can hardwire linear weight like this only for 2-p correlation + for (int h = 0; h < gMaxHarmonic; h++) { + { + if (es.fEtaSeparationsSkipHarmonics[h]) { + continue; + } + qv.fqabVector[1][kineVarChoice][bin][h][e] += std::complex(dWeight * std::cos((h + 1) * pbyp.fPhi), dWeight * std::sin((h + 1) * pbyp.fPhi)); // dWeight = wPhi * wPt * wEta => Remark: I can hardwire linear weight like this only for 2-p correlation + } + } // for (int h = 0; h < gMaxHarmonic; h++) { + } // for (int e = 0; e < gMaxNumberEtaSeparations; e++) { // eta separation + } + } + } // if(es.fCalculateEtaSeparations) + + if (tc.fVerboseForEachParticle) { + ExitFunction(__FUNCTION__); + } + + } // void FillqvectorFromSparse(eqvectorKine kineVarChoice, const int& bin, const double& dWeight) + + //============================================================ + + void CalculateEverything() + { + // Calculate everything for selected events and particles. + // Remark: Data members for Q-vectors (both integrated and differential), containers for nested loops, etc., must all be filled when this function is called. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // *) Calculate multiparticle correlations (standard, isotropic, same harmonic): + if (qv.fCalculateQvectors && mupa.fCalculateCorrelations) { + this->CalculateCorrelations(); + } + + // *) Calculate differential ("kine") multiparticle correlations: + // Remark: vs. pt, vs. eta, etc., are all calculated here + if (qv.fCalculateQvectors && mupa.fCalculateCorrelationsAsFunctionOf[AFO_PT]) { + this->CalculateKineCorrelations(AFO_PT); + } + if (qv.fCalculateQvectors && mupa.fCalculateCorrelationsAsFunctionOf[AFO_ETA]) { + this->CalculateKineCorrelations(AFO_ETA); + } + + // *) Calculate Test0: TBI 20240110 name convention + // Remark: integrated, vs. M and vs. centrality are all calculated here + if (qv.fCalculateQvectors && t0.fCalculateTest0) { + this->CalculateTest0(); + } + + // *) Calculate kine Test0: + + // **) 1D kine: + // ***) cases for which 1D vs. pt calculus is needed: + if (qv.fCalculateQvectors && qv.fCalculateqvectorsKine[PTq]) { // TBI 20250601 do I really need here qv.fCalculateQvectors + this->CalculateKineTest0Ndim(PTq, 1); + } + + // ***) cases for which 1D vs. eta calculus is needed: + if (qv.fCalculateQvectors && qv.fCalculateqvectorsKine[ETAq]) { // TBI 20250601 do I really need here qv.fCalculateQvectors + this->CalculateKineTest0Ndim(ETAq, 1); + } + // ***) cases for which 1D vs. charge calculus is needed: + if (qv.fCalculateQvectors && qv.fCalculateqvectorsKine[CHARGEq]) { // TBI 20250601 do I really need here qv.fCalculateQvectors + this->CalculateKineTest0Ndim(CHARGEq, 1); + } + // ... + + // **) 2D kine: + // ***) cases for which 2D vs. (pt,eta) calculus is needed: + if (qv.fCalculateQvectors && qv.fCalculateqvectorsKine[PT_ETAq]) { // TBI 20250601 do I really need here qv.fCalculateQvectors + this->CalculateKineTest0Ndim(PT_ETAq, 2); + } + // ***) cases for which 2D vs. (pt,charge) calculus is needed: + if (qv.fCalculateQvectors && qv.fCalculateqvectorsKine[PT_CHARGEq]) { // TBI 20250601 do I really need here qv.fCalculateQvectors + this->CalculateKineTest0Ndim(PT_CHARGEq, 2); + } + // ***) cases for which 2D vs. (eta,charge) calculus is needed: + if (qv.fCalculateQvectors && qv.fCalculateqvectorsKine[ETA_CHARGEq]) { // TBI 20250601 do I really need here qv.fCalculateQvectors + this->CalculateKineTest0Ndim(ETA_CHARGEq, 2); + } + // ... + + // **) 3D kine: + // ***) cases for which 3D vs. (pt,eta,charge) calculus is needed: + if (qv.fCalculateQvectors && qv.fCalculateqvectorsKine[PT_ETA_CHARGEq]) { // TBI 20250601 do I really need here qv.fCalculateQvectors + this->CalculateKineTest0Ndim(PT_ETA_CHARGEq, 3); + } + // ... + + // *) Calculate nested loops: + if (nl.fCalculateNestedLoops) { + this->CalculateNestedLoops(); + if (mupa.fCalculateCorrelations) { + // I do not have option here for Test0, because in Test0 I cross-check either e-by-e with CustomNestedLoops or + // for all events with IV + fRescaleWithTheoreticalInput = true + this->ComparisonNestedLoopsVsCorrelations(); // I call it here, so comparison is performed cumulatively after each event. The final printout corresponds to all events. + } + } + + // *) Calculate correlations with eta separations: + if (es.fCalculateEtaSeparations) { + this->CalculateEtaSeparations(); + if (es.fCalculateEtaSeparationsAsFunctionOf[AFO_PT]) { + this->CalculateKineEtaSeparationsNdim(PTq, 1); + } + if (es.fCalculateEtaSeparationsAsFunctionOf[AFO_CHARGE]) { + this->CalculateKineEtaSeparationsNdim(CHARGEq, 1); + } + } + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // void CalculateEverything() + + //============================================================ + + void SkipThisRun() + { + // Skip or not the current run from furher processing. + + // a) Insanity checks; + // b) Do the check. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + // a) Insanity checks: + if (tc.fRunNumber.EqualTo("")) { + LOGF(fatal, "\033[1;31m%s at line %d : tc.fRunNumber is empty. In case you are running something on-the-fly, empty the string fSkipTheseRuns .\033[0m", __FUNCTION__, __LINE__); + } + + // TBI 20250516 Shall I implement some insanity check on fSkipTheseRuns? I commented in configurable that the format is comma-separated list of runs, + // but I am nowhere really enforcing that... + + // b) Do the check: + if (tc.fSkipTheseRuns.Contains(tc.fRunNumber.Data())) { + // TBI 20250316 I think this check is safe enough. If not, tokenize fSkipTheseRuns with respect to "," etc. + tc.fSkipRun = true; + } else { + tc.fSkipRun = false; + } + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + } // void SkipThisRun() + + //============================================================ + + template + void MainLoopOverParticles(T const& tracks) + { + // This is the main loop over particles, in which Q-vectors (both integrated and differential) and particle histograms are filled, particle cuts applied, etc. + + // :mm + + // Remark #1: + // *) To process only reconstructed Run 3, use processRec(...), i.e. set field "processRec": "true" in json config + // *) To process both reconstructed and simulated Run 3, use processRecSim(...), i.e. set field "processRecSim": "true" in json config + // *) To process only simulated Run 3, use processSim(...), i.e. set field "processSim": "true" in json config + + // Remark #2: + // *) To process Run 1 and Run 2 converted data, use in the same spirit e.g. processRec_Run2(...), i.e. set field "processRec_Run2": "true" in json config + + // Remark #3: + // *) There is also processTest(...), to process data with minimum subscription to the tables. To use it, set field "processTest": "true" in json config + + // Remark #4: + // *) There is also processQA(...), to process data with maximum subscription to the tables (use for Run 3 only). To use it, set field "processQA: "true" in json config + + // Remark #5: + // *) Switch ProcessHepMChi(...) amounts at the moment to calling one dedicated function + calling Steer for "RecSim", so no special care is needed here for that switch. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // *) If random access of tracks from collection is requested, use Fisher-Yates algorithm to generate random indices: + if (tc.fUseFisherYates) { + if (tc.fRandomIndices) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + this->RandomIndices(tracks.size()); + if (!tc.fRandomIndices) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + } + + // *) Local timestamp: + if (tc.fUseStopwatch && tc.fVerboseUtility) { + LOGF(info, " Local timer starts at line %d", __LINE__); + tc.fTimer[eLocal]->Reset(); + tc.fTimer[eLocal]->Start(); + } + + // *) Main loop over particles: + // for (auto& track : tracks) { // default standard way of looping of tracks + auto track = tracks.iteratorAt(0); // set the type and scope from one instance + for (int64_t i = 0; i < tracks.size(); i++) { + + // *) Access track sequentially from collection of tracks (default), or randomly using Fisher-Yates algorithm: + if (!tc.fUseFisherYates) { + track = tracks.iteratorAt(i); + } else { + track = tracks.iteratorAt(static_cast(tc.fRandomIndices->GetAt(i))); + } + + // *) Skip track objects which are not valid tracks (e.g. Run 2 and 1 tracklets, etc.): + if (!ValidTrack(track)) { + continue; + } + + // *) Fill particle histograms before particle cuts: + if (ph.fFillParticleHistograms || ph.fFillParticleHistograms2D || qa.fFillQAParticleHistograms2D) { + FillParticleHistograms(track, eBefore); + } + // *) Particle cuts counters (use only during QA, as this is computationally heavy): + if (pc.fUseParticleCutCounterAbsolute || pc.fUseParticleCutCounterSequential) { + ParticleCutsCounters(track); + } + + // *) Particle cuts: + if (!ParticleCuts(track, eCut)) { // Main call for event cuts. + continue; // not return!! + } + + // *) Fill particle histograms after particle cuts: + if (ph.fFillParticleHistograms || ph.fFillParticleHistograms2D || qa.fFillQAParticleHistograms2D) { + FillParticleHistograms(track, eAfter); + } + + // *) Intitialize global (yes, as of 20250718, I promoted 'em to data members, to gain efficiency) kinematic variables: + // Remark: for "eRecSim" processing, kinematics is taken from "reconstructed". + pbyp.fPhi = track.phi(); + pbyp.fPt = track.pt(); + pbyp.fEta = track.eta(); + pbyp.fCharge = track.sign(); + + // Remark: Keep in sync all calls and flags below with the ones in InternalValidation(). + // *) Integrated Q-vectors: + if (qv.fCalculateQvectors || es.fCalculateEtaSeparations) { + // This is now the new approach, with sparse histograms: + // **) particle arguments are passed by reference + // **) event observables (centrality, vertex z, ...), I do not need to pass as arguments, as I have data members for them (ebye.fCentrality, ebye.Vz, ...) + // **) I decide within FillQvectorFromSparse(...) whether and which weights are used. So yes, I use this one, despite its name, even when weights are NOT used + // (there is no real performance penalty) + // **) Legacy function FillQvector(...) is obsolete as of 20250714, since I can get both integrated and differential weights from sparse histograms + this->FillQvectorFromSparse(); + } + + // *) Differential q-vectors (keep in sync with the code in InternalValidation()): + + // TBI 20260210 I need here a flag if this calculus is needed at all + + this->Fillqvectors(); // within this function, i call FillqvectorFromSparse(...), for each differential q-vector separately + + // *) Fill nested loops containers (integrated => I fill kine containers for nested loops in FillqvectorNdim(...)): + if (nl.fCalculateNestedLoops || nl.fCalculateCustomNestedLoops) { + this->FillNestedLoopsContainers(ebye.fSelectedTracks); // all 4 arguments are passed by reference => not true any longer, I have now 4 pbyp data members + } + + // *) Counter of selected tracks in the current event: + ebye.fSelectedTracks++; + if (ebye.fSelectedTracks >= ec.fdEventCuts[eMultiplicity][eMax]) { + break; + } + + // *) Break the loop if fixed number of particles is taken randomly from each event (use always in combination with tc.fUseFisherYates = true): + if (tc.fFixedNumberOfRandomlySelectedTracks > 0 && tc.fFixedNumberOfRandomlySelectedTracks == ebye.fSelectedTracks) { + LOGF(info, "%s : Breaking the loop over particles, since requested fixed number of %d particles was reached", __FUNCTION__, tc.fFixedNumberOfRandomlySelectedTracks); + break; + } + + } // for (auto& track : tracks) + + // *) Local timestamp: + if (tc.fUseStopwatch && tc.fVerboseUtility) { + LOGF(info, " Local timer ends at line %d, time elapsed ... %.6f", __LINE__, tc.fTimer[eLocal]->RealTime()); + tc.fTimer[eLocal]->Continue(); + } + + // *) Insanity check on fixed number of randomly selected tracks: + if (tc.fFixedNumberOfRandomlySelectedTracks > 0 && tc.fFixedNumberOfRandomlySelectedTracks < ebye.fSelectedTracks) { + LOGF(fatal, "\033[1;31mIn this event there are too few particles (ebye.fSelectedTracks = %d), and requested number of fixed number randomly selected tracks %d couldn't be reached\033[0m", ebye.fSelectedTracks, tc.fFixedNumberOfRandomlySelectedTracks); + } + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + } // template void MainLoopOverParticles(T const& tracks) { + + //============================================================ + + template + void Steer(T1 const& collision, T2 const& bcs, T3 const& tracks) + { + // This is the only function to be called in processRec(...), processRecSim(...), and processSim(...). + // All analysis workflow is defined step-by-step here, via dedicated function calls. + // The order of function calls obviously matters. + + // :ss + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // memStatus: ~50K (without differential q-vectors and eta separations) + + // *) Print environment: + if (tc.fVerbose) { + printEnvironment(); + } + + // *) Dry run: + if (tc.fDryRun) { + EventCounterForDryRun(eFill); + EventCounterForDryRun(ePrint); + Preprocess(collision, bcs); // yes, so that e.g. I can only test if the particle and centrality weights were correctly fetched from external file and initialized locally into data members + return; + } + + // memStatus: ~50K (without differential q-vectors and eta separations) + + // *) Reset event-by-event quantities: TBI 20240430 I do not need this call also here really, but it doesn't hurt either... + ResetEventByEventQuantities(); + + // *) Only do internal validation for all implemented correlators against the theoretical values: + if (iv.fUseInternalValidation) { + InternalValidation(); + return; + } + + // *) Global timestamp: + if (tc.fUseStopwatch) { + LOGF(info, "\033[1;32m=> Global timer: Steer begins ... %.6f\033[0m", tc.fTimer[eGlobal]->RealTime()); + tc.fTimer[eGlobal]->Continue(); // yes + } + + // *) Do all thingies before starting to process data from this collision (e.g. cut on number of events (both total and selected), fetch the run number, etc.): + Preprocess(collision, bcs); + + // *) It was explicitly requested, skip this particular run: + if (tc.fSkipRun) { + LOGF(info, "\033[1;33mPer exlicit request via configurable cfSkipTheseRuns, skipping run %s from further processing.\033[0m", tc.fRunNumber.Data()); + return; + } + + // *) Determine collision reference multiplicity: + DetermineReferenceMultiplicity(collision); + + // *) Determine collision centrality: + // Remark: I determine also IP here. + DetermineCentrality(collision); + + // *) Determine collision occupancy: + DetermineOccupancy(collision); + + // *) Determine collision interaction rate and current run duration: + DetermineInteractionRateAndCurrentRunDuration(collision, bcs); // TBI 20250414 temporary commented out, because of memory blow-up + + // *) Determine vertex z position: + DetermineVertexZ(collision); + + // memStatus: ~50K (without differential q-vectors and eta separations) + + // *) Determine additional QA thingies: + if (qa.fFillQAEventHistograms2D || qa.fFillQAParticleHistograms2D || qa.fFillQAParticleEventHistograms2D || qa.fFillQACorrelationsVsHistograms2D || qa.fFillQACorrelationsVsInteractionRateVsProfiles2D) { + // Remark: I implement ideally here only the getters for which the subscription to additional non-standard tables was needed for QA purposes. + DetermineQAThingies(collision, bcs); + } + + // *) Fill event histograms before event cuts: + if (eh.fFillEventHistograms || qa.fFillQAEventHistograms2D || qa.fFillQAParticleEventHistograms2D) { + // Remark: I do not check above the flag fFillQACorrelationsVsHistograms2D, because as a part of QA I calculate <2> only after cuts in any case + FillEventHistograms(collision, tracks, eBefore); + } + + // *) Print info on the current event number (total, before cuts): + if (tc.fVerboseEventCounter) { + PrintEventCounter(eBefore); + } + + // *) Event cuts counters (use only during QA, as this is computationally heavy): + if (ec.fUseEventCutCounterAbsolute || ec.fUseEventCutCounterSequential) { + EventCutsCounters(collision, tracks); + } + + // *) Event cuts: + if (!EventCuts(collision, tracks, eCut)) { // Main call for event cuts + return; + } + + // memStatus: ~50K (without differential q-vectors and eta separations) + + // *) Main loop over particles: + MainLoopOverParticles(tracks); // memStatus: so here I invest ~20K, as of 20250530 + + // memStatus: ~70K (without differential q-vectors and eta separations) + + // *) Determine multiplicity of this event, for all "vs. mult" results: + DetermineMultiplicity(); + + // *) Remaining event cuts which can be applied only after the loop over particles is performed: + if (!RemainingEventCuts()) { + // yes, I need to remove particles from ParticleHistograms, which were filled in the MainLoopOverParticles also for events which didn't survive RemainingEventCuts + BanishmentLoopOverParticles(tracks); + ResetEventByEventQuantities(); + return; + } + + // *) Fill event histograms after event AND particle cuts: + if (eh.fFillEventHistograms || qa.fFillQAEventHistograms2D || qa.fFillQAParticleEventHistograms2D || qa.fFillQACorrelationsVsHistograms2D) { + FillEventHistograms(collision, tracks, eAfter); + } + + // *) Fill subevent multiplicities: + // Remark: I can call this one only after Qa and Qb vectors are filled, and after all particle and event cuts: + if (es.fCalculateEtaSeparations) { + FillSubeventMultiplicities(); + } + + // *) Calculate everything for selected events and particles: + CalculateEverything(); + + // memStatus: ~72K (without differential q-vectors and eta separations) + + // *) Reset event-by-event quantities: + ResetEventByEventQuantities(); + + // *) QA: + if (qa.fCheckUnderflowAndOverflow) { // TBI 20240507 introduce eventualy common function QA(), within which I will call all specific QA functions + CheckUnderflowAndOverflow(); + } + + // *) Print info on the current event number after cuts: + if (tc.fVerboseEventCounter) { + PrintEventCounter(eAfter); + } + + // *) Per request, print content of event cut counters: + if (ec.fPrintCutCounterContent) { + PrintCutCounterContent(); + } + + // *) Global timestamp: + if (tc.fUseStopwatch) { + LOGF(info, "\033[1;32m=> Global timer: Steer ends ... %.6f\033[0m\n", tc.fTimer[eGlobal]->RealTime()); + tc.fTimer[eGlobal]->Continue(); // yes + } + + // *) Print environment: + if (tc.fVerbose) { + printEnvironment(); + } + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + // memStatus (summary): Status at 20260218 (wf-13.sh + file 2023/LHC23zzh/544116/apass5/0140/o2_ctf_run00544116_orbit0034437888_tf0000000601_epn103/008/AO2D.root) + // Remark: disable sequential bailout before doing this test (yes!) + all of UseSetBinLabel, ... UseDatabasetPDG + // ~47K (dry run with 1D objects booked) + // ~61K (all object declaration besides kine objects (diff. q-vectors and eta separations) + all calculus and 1D histograms filled, trivial labels) + // ~61K (all object declaration + 1D kine objects (diff. q-vectors in coarse kine bins: 2 bins in pt and 2 in eta) + all calculus and 1D histograms filled, standard labels) + // ~61K (all object declaration + 1D kine objects (diff. q-vectors in fine kine bins: 16 bins in pt and 10 in eta) + all calculus and 1D histograms filled, standard labels) + // ~62K (all object declaration + 1D kine objects (diff. q-vectors in fine kine bins: 16 bins in pt and 10 in eta) + all calculus and 1D histograms filled, Set_0 labels + // + all 3 sparse histograms only after the cuts) + // ~80K (all object declaration + 1D kine objects (diff. q-vectors in fine kine bins: 16 bins in pt and 10 in eta) + all calculus and 1D histograms filled, Set_0 labels + // + all 3 sparse histograms before and after the cuts) + // ~102K (all object declaration + 1D + 2D + 3D kine objects (diff. q-vectors in fine kine bins: same as above) + all calculus and 1D histograms filled, Set_0 labels) -// *) Data members: -#include "PWGCF/MultiparticleCorrelations/Core/MuPa-DataMembers.h" + // memStatus (summary): Status at 20250602 + // Remark: disable sequential bailout before doing this test (yes!) + all of UseSetBinLabel, ... UseDatabasetPDG + // ~46K (skeleton - literally) + // ~50K (dry run with 1D objects booked) + // ~70K (all object declaration besides kine objects (diff. q-vectors and eta separations) + all calculus and 1D histograms filled, trivial labels) + // ~70K (all object declaration + 1D kine objects (diff. q-vectors in coarse kine bins) + all calculus and 1D histograms filled, standard labels) + // ~80K (all object declaration + 1D + 2D kine objects (diff. q-vectors in fine kine bins) + all calculus and 1D histograms filled, standard labels) + // ~110K (all object declaration + 1D + 2D + 3D kine objects (diff. q-vectors in fine kine bins) + all calculus and 1D histograms filled, standard labels) + // ~125K (all object declaration + 1D + 2D + 3D kine objects (diff. q-vectors in fine kine bins) + all calculus and 1D histograms filled, Set_0 labels) -// *) Member functions: -#include "PWGCF/MultiparticleCorrelations/Core/MuPa-MemberFunctions.h" + } // template void Steer(T1 const* collision, T2 const* tracks) // ------------------------------------------- diff --git a/PWGCF/MultiparticleCorrelations/Tasks/multiparticle-correlations-ar.cxx b/PWGCF/MultiparticleCorrelations/Tasks/multiparticle-correlations-ar.cxx index 5b1539deb9e..284259d9988 100644 --- a/PWGCF/MultiparticleCorrelations/Tasks/multiparticle-correlations-ar.cxx +++ b/PWGCF/MultiparticleCorrelations/Tasks/multiparticle-correlations-ar.cxx @@ -13,23 +13,40 @@ /// \brief multiparticle-correlations-ar - Task belonging to Anton Riedel for computing multiparticle correlations /// \author Anton Riedel, TU München, anton.riedel@tum.de +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include #include -#include "fairlogger/Logger.h" +#include + #include +#include +#include +#include #include -#include -#include +#include +#include #include +#include +#include #include -#include -#include -#include "TComplex.h" -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/Expressions.h" -#include "Common/DataModel/Centrality.h" -#include "Common/DataModel/Multiplicity.h" -#include "Common/DataModel/TrackSelectionTables.h" using namespace o2; using namespace o2::framework; diff --git a/PWGCF/MultiparticleCorrelations/Tasks/threeParticleCorrelations.cxx b/PWGCF/MultiparticleCorrelations/Tasks/threeParticleCorrelations.cxx index f74b90da6c3..b6aab98d17e 100644 --- a/PWGCF/MultiparticleCorrelations/Tasks/threeParticleCorrelations.cxx +++ b/PWGCF/MultiparticleCorrelations/Tasks/threeParticleCorrelations.cxx @@ -13,23 +13,49 @@ /// \brief Task for producing particle correlations /// \author Joey Staa -#include "RecoDecay.h" - #include "PWGLF/DataModel/LFStrangenessTables.h" +#include "Common/CCDB/EventSelectionParams.h" +#include "Common/Core/RecoDecay.h" #include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" #include "Common/DataModel/McCollisionExtra.h" #include "Common/DataModel/PIDResponseTOF.h" #include "Common/DataModel/PIDResponseTPC.h" - -#include "CCDB/BasicCCDBManager.h" -#include "DataFormatsParameters/GRPMagField.h" -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" - -#include "TPDGCode.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include #include +#include +#include +#include +#include #include #include @@ -1122,7 +1148,7 @@ struct ThreeParticleCorrelations { return false; } - if (trackPID(track)[0] == pionID) { // Pions + if (trackPID(track)[0] == pionID) { // Pions if (std::abs(track.tpcNSigmaPi()) >= nSigma4 + trackSelGroup.nSigmaTPCvar) { // TPC return false; } @@ -1144,7 +1170,7 @@ struct ThreeParticleCorrelations { return false; } - } else if (trackPID(track)[0] == kaonID) { // Kaons + } else if (trackPID(track)[0] == kaonID) { // Kaons if (std::abs(track.tpcNSigmaKa()) >= nSigma4 + trackSelGroup.nSigmaTPCvar) { // TPC return false; } @@ -1166,7 +1192,7 @@ struct ThreeParticleCorrelations { return false; } - } else if (trackPID(track)[0] == protonID) { // Protons + } else if (trackPID(track)[0] == protonID) { // Protons if (std::abs(track.tpcNSigmaPr()) >= nSigma4 + trackSelGroup.nSigmaTPCvar) { // TPC return false; } diff --git a/PWGCF/TableProducer/dptDptFilter.cxx b/PWGCF/TableProducer/dptDptFilter.cxx index dd703f3b3c3..baff1b96e2d 100644 --- a/PWGCF/TableProducer/dptDptFilter.cxx +++ b/PWGCF/TableProducer/dptDptFilter.cxx @@ -19,36 +19,41 @@ #include "PWGCF/DataModel/DptDptFiltered.h" #include "Common/Core/TableHelper.h" -#include "Common/Core/TrackSelection.h" -#include "Common/Core/TrackSelectionDefaults.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/CollisionAssociationTables.h" -#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponseTOF.h" #include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "CommonConstants/PhysicsConstants.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/runDataProcessing.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include -#include -#include #include #include #include #include #include #include -#include -#include +#include + +#include #include #include +#include +#include #include #include #include @@ -58,6 +63,7 @@ using namespace o2::framework; using namespace o2::soa; using namespace o2::framework::expressions; using namespace o2::analysis; +using namespace o2::common::core; #define DPTDPTFILTERLOGCOLLISIONS debug #define DPTDPTFILTERLOGTRACKS debug diff --git a/PWGCF/TableProducer/dptDptFilter.h b/PWGCF/TableProducer/dptDptFilter.h index 9c51fbbf60a..3d85ab3a79d 100644 --- a/PWGCF/TableProducer/dptDptFilter.h +++ b/PWGCF/TableProducer/dptDptFilter.h @@ -18,7 +18,9 @@ #include "PWGCF/Core/AnalysisConfigurableCuts.h" +#include "Common/CCDB/EventSelectionParams.h" #include "Common/CCDB/RCTSelectionFlags.h" +#include "Common/CCDB/TriggerAliases.h" #include "Common/Core/MetadataHelper.h" #include "Common/Core/RecoDecay.h" #include "Common/Core/TrackSelection.h" @@ -28,26 +30,33 @@ #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "ReconstructionDataFormats/PID.h" -#include +#include +#include +#include +#include +#include +#include #include #include +#include #include #include #include +#include + #include +#include #include +#include +#include +#include #include #include #include -#include #include -#include #include #include #include @@ -1594,8 +1603,6 @@ struct TpcExcludeTrack { template inline bool matchTrackType(TrackObject const& track) { - using namespace o2::aod::track; - if (tracktype == TrackTypePWGMM) { // under tests MM track selection // see: https://indico.cern.ch/event/1383788/contributions/5816953/attachments/2805905/4896281/TrackSel_GlobalTracks_vs_MMTrackSel.pdf diff --git a/PWGCF/TableProducer/filter2Prong.cxx b/PWGCF/TableProducer/filter2Prong.cxx index c57427a92c5..f25c8cf0e2c 100644 --- a/PWGCF/TableProducer/filter2Prong.cxx +++ b/PWGCF/TableProducer/filter2Prong.cxx @@ -16,18 +16,36 @@ #include "PWGHF/Core/HfHelper.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" +#include "PWGHF/DataModel/TrackIndexSkimmingTables.h" +#include "PWGLF/DataModel/LFStrangenessTables.h" +#include "Common/Core/RecoDecay.h" #include "Common/DataModel/PIDResponseITS.h" - -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" -#include "MathUtils/detail/TypeTruncation.h" - +#include "Common/DataModel/PIDResponseTOF.h" +#include "Common/DataModel/PIDResponseTPC.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include // IWYU pragma: keep (do not replace with Math/Vector4Dfwd.h) +#include #include +#include + +#include +#include +#include +#include #include +#include #include #include #include diff --git a/PWGCF/TableProducer/filterCorrelations.cxx b/PWGCF/TableProducer/filterCorrelations.cxx index 3977682397c..48cf2ea1279 100644 --- a/PWGCF/TableProducer/filterCorrelations.cxx +++ b/PWGCF/TableProducer/filterCorrelations.cxx @@ -8,32 +8,46 @@ // In applying this license CERN does not waive the privileges and immunities // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. + #include "PWGCF/DataModel/CorrelationsDerived.h" -#include "PWGHF/DataModel/CandidateReconstructionTables.h" -#include "PWGHF/DataModel/CandidateSelectionTables.h" +#include "Common/CCDB/EventSelectionParams.h" +#include "Common/CCDB/TriggerAliases.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponseITS.h" +#include "Common/DataModel/PIDResponseTOF.h" +#include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "Framework/runDataProcessing.h" -#include "MathUtils/detail/TypeTruncation.h" -#include - -#include -#include -#include - +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include #include #include // required for is_detected +#include #include +#include + using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; @@ -106,7 +120,7 @@ struct FilterCF { // TODO how to have this in the second task? For now they are copied Filter trackFilter = (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPt); - Filter trackSelection = (requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true); + Filter trackSelection = (requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t)true); Filter mcCollisionFilter = nabs(aod::mccollision::posZ) < cfgCutVertex; @@ -570,7 +584,7 @@ struct MultiplicitySelector { O2_DEFINE_CONFIGURABLE(cfgCutEta, float, 0.8f, "Eta range for tracks") Filter trackFilter = (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPt); - Filter trackSelection = (requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true); + Filter trackSelection = (requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t)true); void init(InitContext&) { diff --git a/PWGCF/Tasks/correlations.cxx b/PWGCF/Tasks/correlations.cxx index 6044510a562..177f1c04f6b 100644 --- a/PWGCF/Tasks/correlations.cxx +++ b/PWGCF/Tasks/correlations.cxx @@ -17,35 +17,51 @@ #include "PWGCF/Core/PairCuts.h" #include "PWGCF/DataModel/CorrelationsDerived.h" +#include "Common/CCDB/TriggerAliases.h" #include "Common/Core/RecoDecay.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "CCDB/BasicCCDBManager.h" -#include "CommonConstants/MathConstants.h" -#include "DataFormatsParameters/GRPMagField.h" -#include "DataFormatsParameters/GRPObject.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/StepTHn.h" -#include "Framework/runDataProcessing.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include -#include #include +#include #include +#include + +#include +#include +#include +#include #include +#include #include +#include #include #include #include +#include #include #include @@ -133,7 +149,7 @@ struct CorrelationTask { Filter collisionVertexTypeFilter = (aod::collision::flags & static_cast(aod::collision::CollisionFlagsRun2::Run2VertexerTracks)) == static_cast(aod::collision::CollisionFlagsRun2::Run2VertexerTracks); // Track filters - Filter trackFilter = (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPt) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true)); + Filter trackFilter = (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPt) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t)true)); Filter cfTrackFilter = (nabs(aod::cftrack::eta) < cfgCutEta) && (aod::cftrack::pt > cfgCutPt) && ncheckbit(aod::track::trackType, as(cfgTrackBitMask)); // MC filters diff --git a/PWGCF/Tasks/dptDptCorrelations.cxx b/PWGCF/Tasks/dptDptCorrelations.cxx index e6ee088eca0..0868ab02905 100644 --- a/PWGCF/Tasks/dptDptCorrelations.cxx +++ b/PWGCF/Tasks/dptDptCorrelations.cxx @@ -20,40 +20,45 @@ #include "Common/Core/RecoDecay.h" #include "Common/Core/TableHelper.h" -#include "Common/Core/TrackSelection.h" -#include "Common/DataModel/Centrality.h" -#include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/TrackSelectionTables.h" - -#include "DataFormatsParameters/GRPObject.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/runDataProcessing.h" + #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include -#include -#include #include #include #include #include #include -#include -#include -#include + +#include + +#include #include +#include #include #include #include +#include #include using namespace o2; using namespace o2::framework; using namespace o2::soa; using namespace o2::framework::expressions; +using namespace o2::common::core; #define DPTDPTLOGCOLLISIONS debug #define DPTDPTLOGTRACKS debug diff --git a/PWGCF/Tasks/dptDptFilterQa.cxx b/PWGCF/Tasks/dptDptFilterQa.cxx index 876fd8ccb5e..c5771213e62 100644 --- a/PWGCF/Tasks/dptDptFilterQa.cxx +++ b/PWGCF/Tasks/dptDptFilterQa.cxx @@ -16,13 +16,21 @@ #include "PWGCF/DataModel/DptDptFiltered.h" #include "PWGCF/TableProducer/dptDptFilter.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" +#include +#include +#include +#include +#include +#include +#include +#include + +#include #include +#include #include +#include using namespace o2; using namespace o2::framework; diff --git a/PWGCF/Tasks/matchRecoGen.cxx b/PWGCF/Tasks/matchRecoGen.cxx index 8f1b57ce348..b9a995b427d 100644 --- a/PWGCF/Tasks/matchRecoGen.cxx +++ b/PWGCF/Tasks/matchRecoGen.cxx @@ -18,30 +18,28 @@ #include "PWGCF/TableProducer/dptDptFilter.h" #include "Common/Core/RecoDecay.h" -#include "Common/Core/TrackSelection.h" -#include "Common/Core/TrackSelectionDefaults.h" -#include "Common/DataModel/Centrality.h" -#include "Common/DataModel/EventSelection.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "Framework/runDataProcessing.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include -#include -#include #include -#include -#include -#include -#include -#include -#include +#include #include +#include +#include #include +#include #include using namespace o2; diff --git a/PWGCF/Tutorial/CFTutorialTask0.cxx b/PWGCF/Tutorial/CFTutorialTask0.cxx index 3de52379610..35d4763dca4 100644 --- a/PWGCF/Tutorial/CFTutorialTask0.cxx +++ b/PWGCF/Tutorial/CFTutorialTask0.cxx @@ -11,9 +11,16 @@ /// \author Luca Barioglio -// O2 includes -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" +#include +#include +#include +#include +#include +#include +#include + +#include +#include using namespace o2; using namespace o2::framework; diff --git a/PWGCF/Tutorial/CFTutorialTask1.cxx b/PWGCF/Tutorial/CFTutorialTask1.cxx index d4f0360bdf0..e4d30fe5f12 100644 --- a/PWGCF/Tutorial/CFTutorialTask1.cxx +++ b/PWGCF/Tutorial/CFTutorialTask1.cxx @@ -11,13 +11,21 @@ /// \author Luca Barioglio -// O2 includes #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponseTPC.h" -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include using namespace o2; using namespace o2::framework; diff --git a/PWGCF/Tutorial/CFTutorialTask2.cxx b/PWGCF/Tutorial/CFTutorialTask2.cxx index 6402ed2d504..c8ba5cca9ff 100644 --- a/PWGCF/Tutorial/CFTutorialTask2.cxx +++ b/PWGCF/Tutorial/CFTutorialTask2.cxx @@ -11,13 +11,23 @@ /// \author Luca Barioglio -// O2 includes #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponseTPC.h" -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include using namespace o2; using namespace o2::framework; diff --git a/PWGCF/Tutorial/CFTutorialTask3.cxx b/PWGCF/Tutorial/CFTutorialTask3.cxx index 7ddbe231b30..4ece0be89e1 100644 --- a/PWGCF/Tutorial/CFTutorialTask3.cxx +++ b/PWGCF/Tutorial/CFTutorialTask3.cxx @@ -11,13 +11,24 @@ /// \author Luca Barioglio -// O2 includes #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponseTPC.h" -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include using namespace o2; using namespace o2::framework; diff --git a/PWGCF/Tutorial/CFTutorialTask4.cxx b/PWGCF/Tutorial/CFTutorialTask4.cxx index fdd79d9e9f4..22056bb0957 100644 --- a/PWGCF/Tutorial/CFTutorialTask4.cxx +++ b/PWGCF/Tutorial/CFTutorialTask4.cxx @@ -11,16 +11,29 @@ /// \author Luca Barioglio -// O2 includes #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponseTPC.h" -#include "CommonConstants/PhysicsConstants.h" -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" - -#include "TLorentzVector.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include using namespace o2; using namespace o2::framework; diff --git a/PWGCF/Tutorial/CFTutorialTask5.cxx b/PWGCF/Tutorial/CFTutorialTask5.cxx index bb99f0a36cc..a3d087ef42f 100644 --- a/PWGCF/Tutorial/CFTutorialTask5.cxx +++ b/PWGCF/Tutorial/CFTutorialTask5.cxx @@ -11,16 +11,31 @@ /// \author Luca Barioglio -// O2 includes #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponseTPC.h" -#include "CommonConstants/PhysicsConstants.h" -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" - -#include "TLorentzVector.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include using namespace o2; using namespace o2::framework; diff --git a/PWGCF/TwoParticleCorrelations/Core/EventSelectionFilterAndAnalysis.cxx b/PWGCF/TwoParticleCorrelations/Core/EventSelectionFilterAndAnalysis.cxx index 57a65059663..2188c234cc7 100644 --- a/PWGCF/TwoParticleCorrelations/Core/EventSelectionFilterAndAnalysis.cxx +++ b/PWGCF/TwoParticleCorrelations/Core/EventSelectionFilterAndAnalysis.cxx @@ -9,11 +9,30 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#include +#include "EventSelectionFilterAndAnalysis.h" + +#include "SelectionFilterAndAnalysis.h" +#include "SkimmingConfigurableCuts.h" + +#include + +#include #include +#include -#include "Framework/AnalysisTask.h" -#include "EventSelectionFilterAndAnalysis.h" +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include using namespace o2; using namespace o2::analysis::PWGCF; diff --git a/PWGCF/TwoParticleCorrelations/Core/EventSelectionFilterAndAnalysis.h b/PWGCF/TwoParticleCorrelations/Core/EventSelectionFilterAndAnalysis.h index 72e8d6672c0..00a098177a6 100644 --- a/PWGCF/TwoParticleCorrelations/Core/EventSelectionFilterAndAnalysis.h +++ b/PWGCF/TwoParticleCorrelations/Core/EventSelectionFilterAndAnalysis.h @@ -8,18 +8,24 @@ // In applying this license CERN does not waive the privileges and immunities // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#ifndef EVENTSELECTIONFILTERANDANALYSIS_H -#define EVENTSELECTIONFILTERANDANALYSIS_H -#include -#include -#include -#include -#include +#ifndef PWGCF_TWOPARTICLECORRELATIONS_CORE_EVENTSELECTIONFILTERANDANALYSIS_H_ +#define PWGCF_TWOPARTICLECORRELATIONS_CORE_EVENTSELECTIONFILTERANDANALYSIS_H_ -#include -#include "SkimmingConfigurableCuts.h" #include "SelectionFilterAndAnalysis.h" +#include "SkimmingConfigurableCuts.h" + +#include + +#include +#include +#include + +#include + +#include +#include +#include namespace o2 { @@ -265,4 +271,4 @@ inline std::vector EventSelectionFilterAndAnalysis::MultiplicityBrick::Ge } // namespace analysis } // namespace o2 -#endif // EVENTSELECTIONFILTERANDANALYSIS_H +#endif // PWGCF_TWOPARTICLECORRELATIONS_CORE_EVENTSELECTIONFILTERANDANALYSIS_H_ diff --git a/PWGCF/TwoParticleCorrelations/Core/FilterAndAnalysisFramework.cxx b/PWGCF/TwoParticleCorrelations/Core/FilterAndAnalysisFramework.cxx index ba83f4aa2ed..cc3cb3bb73d 100644 --- a/PWGCF/TwoParticleCorrelations/Core/FilterAndAnalysisFramework.cxx +++ b/PWGCF/TwoParticleCorrelations/Core/FilterAndAnalysisFramework.cxx @@ -9,14 +9,29 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#include -#include -#include -#include +#include "FilterAndAnalysisFramework.h" + +#include "EventSelectionFilterAndAnalysis.h" +#include "PIDSelectionFilterAndAnalysis.h" +#include "SelectionFilterAndAnalysis.h" +#include "TrackSelectionFilterAndAnalysis.h" + +#include +#include +#include + #include +#include #include -#include "FilterAndAnalysisFramework.h" +#include + +#include +#include +#include +#include +#include +#include using namespace o2; using namespace o2::analysis::PWGCF; diff --git a/PWGCF/TwoParticleCorrelations/Core/FilterAndAnalysisFramework.h b/PWGCF/TwoParticleCorrelations/Core/FilterAndAnalysisFramework.h index fa3b7aaeb6e..f077af40d6c 100644 --- a/PWGCF/TwoParticleCorrelations/Core/FilterAndAnalysisFramework.h +++ b/PWGCF/TwoParticleCorrelations/Core/FilterAndAnalysisFramework.h @@ -8,21 +8,24 @@ // In applying this license CERN does not waive the privileges and immunities // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. + #ifndef PWGCF_TWOPARTICLECORRELATIONS_CORE_FILTERANDANALYSISFRAMEWORK_H_ #define PWGCF_TWOPARTICLECORRELATIONS_CORE_FILTERANDANALYSISFRAMEWORK_H_ -#include -#include -#include -#include -#include -#include -#include -#include +#include "SelectionFilterAndAnalysis.h" #include "PWGCF/TwoParticleCorrelations/Core/EventSelectionFilterAndAnalysis.h" -#include "PWGCF/TwoParticleCorrelations/Core/TrackSelectionFilterAndAnalysis.h" #include "PWGCF/TwoParticleCorrelations/Core/PIDSelectionFilterAndAnalysis.h" +#include "PWGCF/TwoParticleCorrelations/Core/TrackSelectionFilterAndAnalysis.h" + +#include +#include + +#include + +#include +#include +#include namespace o2 { diff --git a/PWGCF/TwoParticleCorrelations/Core/PIDSelectionFilterAndAnalysis.cxx b/PWGCF/TwoParticleCorrelations/Core/PIDSelectionFilterAndAnalysis.cxx index d5b15a8db3f..b36c625f3ae 100644 --- a/PWGCF/TwoParticleCorrelations/Core/PIDSelectionFilterAndAnalysis.cxx +++ b/PWGCF/TwoParticleCorrelations/Core/PIDSelectionFilterAndAnalysis.cxx @@ -11,18 +11,27 @@ #include "PIDSelectionFilterAndAnalysis.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" +#include "SelectionFilterAndAnalysis.h" +#include "SkimmingConfigurableCuts.h" -#include +#include -#include +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include using namespace o2; -using namespace o2::framework; -using namespace o2::soa; -using namespace o2::framework::expressions; using namespace o2::analysis::PWGCF; using namespace boost; diff --git a/PWGCF/TwoParticleCorrelations/Core/PIDSelectionFilterAndAnalysis.h b/PWGCF/TwoParticleCorrelations/Core/PIDSelectionFilterAndAnalysis.h index 1d8645b351c..4106be0de48 100644 --- a/PWGCF/TwoParticleCorrelations/Core/PIDSelectionFilterAndAnalysis.h +++ b/PWGCF/TwoParticleCorrelations/Core/PIDSelectionFilterAndAnalysis.h @@ -8,17 +8,20 @@ // In applying this license CERN does not waive the privileges and immunities // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#ifndef PIDSELECTIONFILTERANDANALYSIS_H -#define PIDSELECTIONFILTERANDANALYSIS_H -#include -#include -#include -#include -#include +#ifndef PWGCF_TWOPARTICLECORRELATIONS_CORE_PIDSELECTIONFILTERANDANALYSIS_H_ +#define PWGCF_TWOPARTICLECORRELATIONS_CORE_PIDSELECTIONFILTERANDANALYSIS_H_ -#include "SkimmingConfigurableCuts.h" #include "SelectionFilterAndAnalysis.h" +#include "SkimmingConfigurableCuts.h" + +#include + +#include + +#include +#include +#include #undef INCORPORATEBAYESIANPID @@ -189,4 +192,4 @@ inline uint64_t PIDSelectionFilterAndAnalysis::Filter(TrackToFilter const& track } // namespace analysis } // namespace o2 -#endif // PIDSELECTIONFILTERANDANALYSIS_H +#endif // PWGCF_TWOPARTICLECORRELATIONS_CORE_PIDSELECTIONFILTERANDANALYSIS_H_ diff --git a/PWGCF/TwoParticleCorrelations/Core/SelectionFilterAndAnalysis.cxx b/PWGCF/TwoParticleCorrelations/Core/SelectionFilterAndAnalysis.cxx index 1c816268063..2af7b649e7b 100644 --- a/PWGCF/TwoParticleCorrelations/Core/SelectionFilterAndAnalysis.cxx +++ b/PWGCF/TwoParticleCorrelations/Core/SelectionFilterAndAnalysis.cxx @@ -9,18 +9,15 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#include -#include - -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/ASoAHelpers.h" #include "SelectionFilterAndAnalysis.h" +#include + +#include + +#include + using namespace o2; -using namespace o2::framework; -using namespace o2::soa; -using namespace o2::framework::expressions; using namespace o2::analysis::PWGCF; ClassImp(SelectionFilterAndAnalysis); diff --git a/PWGCF/TwoParticleCorrelations/Core/SelectionFilterAndAnalysis.h b/PWGCF/TwoParticleCorrelations/Core/SelectionFilterAndAnalysis.h index f3680d188f4..fad166337af 100644 --- a/PWGCF/TwoParticleCorrelations/Core/SelectionFilterAndAnalysis.h +++ b/PWGCF/TwoParticleCorrelations/Core/SelectionFilterAndAnalysis.h @@ -8,14 +8,17 @@ // In applying this license CERN does not waive the privileges and immunities // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#ifndef SELECTIONFILTERANDANALYSIS_H -#define SELECTIONFILTERANDANALYSIS_H -#include -#include -#include +#ifndef PWGCF_TWOPARTICLECORRELATIONS_CORE_SELECTIONFILTERANDANALYSIS_H_ +#define PWGCF_TWOPARTICLECORRELATIONS_CORE_SELECTIONFILTERANDANALYSIS_H_ + #include -#include +#include + +#include + +#include +#include namespace o2 { @@ -76,4 +79,4 @@ class SelectionFilterAndAnalysis : public TNamed } // namespace analysis } // namespace o2 -#endif // SELECTIONFILTERANDANALYSIS_H +#endif // PWGCF_TWOPARTICLECORRELATIONS_CORE_SELECTIONFILTERANDANALYSIS_H_ diff --git a/PWGCF/TwoParticleCorrelations/Core/SkimmingConfigurableCuts.cxx b/PWGCF/TwoParticleCorrelations/Core/SkimmingConfigurableCuts.cxx index 81436952bd0..ffd29c96571 100644 --- a/PWGCF/TwoParticleCorrelations/Core/SkimmingConfigurableCuts.cxx +++ b/PWGCF/TwoParticleCorrelations/Core/SkimmingConfigurableCuts.cxx @@ -9,11 +9,24 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#include +#include "PWGCF/TwoParticleCorrelations/Core/SkimmingConfigurableCuts.h" + +#include +#include + +#include #include -#include -#include "PWGCF/TwoParticleCorrelations/Core/SkimmingConfigurableCuts.h" +#include + +#include +#include +#include +#include +#include +#include +#include +#include using namespace o2; using namespace o2::analysis::PWGCF; diff --git a/PWGCF/TwoParticleCorrelations/Core/SkimmingConfigurableCuts.h b/PWGCF/TwoParticleCorrelations/Core/SkimmingConfigurableCuts.h index 53e1c56dcaa..68d7f9671a4 100644 --- a/PWGCF/TwoParticleCorrelations/Core/SkimmingConfigurableCuts.h +++ b/PWGCF/TwoParticleCorrelations/Core/SkimmingConfigurableCuts.h @@ -8,23 +8,27 @@ // In applying this license CERN does not waive the privileges and immunities // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#ifndef SKIMMING_CONFIGURABLE_CUTS_CLASSES_H -#define SKIMMING_CONFIGURABLE_CUTS_CLASSES_H -#include -#include -#include -#include -#include -#include +#ifndef PWGCF_TWOPARTICLECORRELATIONS_CORE_SKIMMINGCONFIGURABLECUTS_H_ +#define PWGCF_TWOPARTICLECORRELATIONS_CORE_SKIMMINGCONFIGURABLECUTS_H_ + +#include +#include + #include +#include +#include +#include +#include + +#include + +#include +#include #include +#include +#include #include -#include -#include - -#include -#include "Framework/DataTypes.h" namespace o2 { @@ -629,4 +633,4 @@ class TrackSelectionBrick : public SpecialCutBrick } // namespace analysis } // namespace o2 -#endif // SKIMMING_CONFIGURABLE_CUTS_CLASSES_H +#endif // PWGCF_TWOPARTICLECORRELATIONS_CORE_SKIMMINGCONFIGURABLECUTS_H_ diff --git a/PWGCF/TwoParticleCorrelations/Core/TrackSelectionFilterAndAnalysis.cxx b/PWGCF/TwoParticleCorrelations/Core/TrackSelectionFilterAndAnalysis.cxx index 4b5708fdc90..ccbdb25494e 100644 --- a/PWGCF/TwoParticleCorrelations/Core/TrackSelectionFilterAndAnalysis.cxx +++ b/PWGCF/TwoParticleCorrelations/Core/TrackSelectionFilterAndAnalysis.cxx @@ -9,11 +9,27 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#include +#include "TrackSelectionFilterAndAnalysis.h" + +#include "SelectionFilterAndAnalysis.h" +#include "SkimmingConfigurableCuts.h" + +#include + #include +#include -#include -#include "TrackSelectionFilterAndAnalysis.h" +#include +#include +#include +#include + +#include + +#include +#include +#include +#include using namespace o2; using namespace o2::analysis::PWGCF; diff --git a/PWGCF/TwoParticleCorrelations/Core/TrackSelectionFilterAndAnalysis.h b/PWGCF/TwoParticleCorrelations/Core/TrackSelectionFilterAndAnalysis.h index 8c186a97109..ab3b33a45f2 100644 --- a/PWGCF/TwoParticleCorrelations/Core/TrackSelectionFilterAndAnalysis.h +++ b/PWGCF/TwoParticleCorrelations/Core/TrackSelectionFilterAndAnalysis.h @@ -8,18 +8,22 @@ // In applying this license CERN does not waive the privileges and immunities // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#ifndef TRACKSELECTIONFILTERANDANALYSIS_H -#define TRACKSELECTIONFILTERANDANALYSIS_H -#include -#include -#include -#include -#include +#ifndef PWGCF_TWOPARTICLECORRELATIONS_CORE_TRACKSELECTIONFILTERANDANALYSIS_H_ +#define PWGCF_TWOPARTICLECORRELATIONS_CORE_TRACKSELECTIONFILTERANDANALYSIS_H_ -#include -#include "SkimmingConfigurableCuts.h" #include "SelectionFilterAndAnalysis.h" +#include "SkimmingConfigurableCuts.h" + +#include +#include +#include + +#include + +#include +#include +#include namespace o2 { @@ -205,4 +209,4 @@ uint64_t TrackSelectionFilterAndAnalysis::Filter(TrackToFilter const& track) } // namespace analysis } // namespace o2 -#endif // TRACKSELECTIONFILTERANDANALYSIS_H +#endif // PWGCF_TWOPARTICLECORRELATIONS_CORE_TRACKSELECTIONFILTERANDANALYSIS_H_ diff --git a/PWGCF/TwoParticleCorrelations/DataModel/LongRangeDerived.h b/PWGCF/TwoParticleCorrelations/DataModel/LongRangeDerived.h index f9b79242ac0..100feb1639e 100644 --- a/PWGCF/TwoParticleCorrelations/DataModel/LongRangeDerived.h +++ b/PWGCF/TwoParticleCorrelations/DataModel/LongRangeDerived.h @@ -18,8 +18,10 @@ #ifndef PWGCF_TWOPARTICLECORRELATIONS_DATAMODEL_LONGRANGEDERIVED_H_ #define PWGCF_TWOPARTICLECORRELATIONS_DATAMODEL_LONGRANGEDERIVED_H_ -#include "Framework/ASoA.h" -#include "Framework/AnalysisDataModel.h" +#include +#include + +#include namespace o2::aod { diff --git a/PWGCF/TwoParticleCorrelations/DataModel/TwoParticleCorrelationsFiltered.h b/PWGCF/TwoParticleCorrelations/DataModel/TwoParticleCorrelationsFiltered.h index ac35f064808..c2376828a55 100644 --- a/PWGCF/TwoParticleCorrelations/DataModel/TwoParticleCorrelationsFiltered.h +++ b/PWGCF/TwoParticleCorrelations/DataModel/TwoParticleCorrelationsFiltered.h @@ -8,12 +8,14 @@ // In applying this license CERN does not waive the privileges and immunities // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#ifndef O2_ANALYSIS_TWOPARTFILTERED_H -#define O2_ANALYSIS_TWOPARTFILTERED_H -#include "Framework/ASoA.h" -#include "Framework/AnalysisDataModel.h" -#include "TwoParticleCorrelationsSkimmed.h" +#ifndef PWGCF_TWOPARTICLECORRELATIONS_DATAMODEL_TWOPARTICLECORRELATIONSFILTERED_H_ +#define PWGCF_TWOPARTICLECORRELATIONS_DATAMODEL_TWOPARTICLECORRELATIONSFILTERED_H_ + +#include +#include + +#include namespace o2 { @@ -46,4 +48,4 @@ DECLARE_SOA_TABLE(TwoPFilteredParticles, "AOD", "FILTEREDGENTRKS", //! The gener } // namespace aod } // namespace o2 -#endif // O2_ANALYSIS_TWOPARTFILTERED_H +#endif // PWGCF_TWOPARTICLECORRELATIONS_DATAMODEL_TWOPARTICLECORRELATIONSFILTERED_H_ diff --git a/PWGCF/TwoParticleCorrelations/DataModel/TwoParticleCorrelationsSkimmed.h b/PWGCF/TwoParticleCorrelations/DataModel/TwoParticleCorrelationsSkimmed.h index b032d89647f..3dc26215d89 100644 --- a/PWGCF/TwoParticleCorrelations/DataModel/TwoParticleCorrelationsSkimmed.h +++ b/PWGCF/TwoParticleCorrelations/DataModel/TwoParticleCorrelationsSkimmed.h @@ -12,18 +12,11 @@ #ifndef PWGCF_TWOPARTICLECORRELATIONS_DATAMODEL_TWOPARTICLECORRELATIONSSKIMMED_H_ #define PWGCF_TWOPARTICLECORRELATIONS_DATAMODEL_TWOPARTICLECORRELATIONSSKIMMED_H_ +#include +#include + +#include #include -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/ASoA.h" -#include "Framework/ASoAHelpers.h" -#include "Common/DataModel/TrackSelectionTables.h" -#include "Common/DataModel/Centrality.h" -#include "PWGCF/TwoParticleCorrelations/Core/SkimmingConfigurableCuts.h" -#include "PWGCF/TwoParticleCorrelations/Core/EventSelectionFilterAndAnalysis.h" -#include "PWGCF/TwoParticleCorrelations/Core/TrackSelectionFilterAndAnalysis.h" -#include "PWGCF/TwoParticleCorrelations/Core/PIDSelectionFilterAndAnalysis.h" -#include "Framework/runDataProcessing.h" namespace o2 { @@ -60,15 +53,15 @@ DECLARE_SOA_TABLE(CFMCCollMasks, "AOD", "CFMCCOLLMASK", //! Generated collision/ using CFMCCollMask = CFMCCollMasks::iterator; namespace cfskim { -DECLARE_SOA_INDEX_COLUMN(CFCollision, cfcollision); //! Reconstructed collision/event -DECLARE_SOA_INDEX_COLUMN(CFMCCollision, cfmccollision); //! Generated collision/event -DECLARE_SOA_COLUMN(CFTrackFlags, trackflags, uint64_t); //! The skimming flags for track selection, B0 track/particle positive charge, B1 track/particle negative charge +DECLARE_SOA_INDEX_COLUMN(CFCollision, cfcollision); //! Reconstructed collision/event +DECLARE_SOA_INDEX_COLUMN(CFMCCollision, cfmccollision); //! Generated collision/event +DECLARE_SOA_COLUMN(CFTrackFlags, trackflags, uint64_t); //! The skimming flags for track selection, B0 track/particle positive charge, B1 track/particle negative charge DECLARE_SOA_COLUMN(CFMCTrackFlags, mctrackflags, uint64_t); //! The skimming flags for particle selection, B0 track/particle positive charge, B1 track/particle negative charge DECLARE_SOA_COLUMN(CFPidFlags, pidflags, uint64_t); //! The PID skimming flags for track selection -DECLARE_SOA_COLUMN(Pt, pt, float); //! The track transverse momentum -DECLARE_SOA_COLUMN(Eta, eta, float); //! The track pseudorapidity -DECLARE_SOA_COLUMN(Phi, phi, float); //! The track azimuthal angle -DECLARE_SOA_DYNAMIC_COLUMN(Sign, sign, //! Charge: positive: 1, negative: -1 +DECLARE_SOA_COLUMN(Pt, pt, float); //! The track transverse momentum +DECLARE_SOA_COLUMN(Eta, eta, float); //! The track pseudorapidity +DECLARE_SOA_COLUMN(Phi, phi, float); //! The track azimuthal angle +DECLARE_SOA_DYNAMIC_COLUMN(Sign, sign, //! Charge: positive: 1, negative: -1 [](uint64_t mask) -> int8_t { return ((mask & 0x1L) == 0x1L) ? 1 : ((mask & 0x2L) == 0x2L) ? -1 : 0; }); diff --git a/PWGCF/TwoParticleCorrelations/TableProducer/Productions/skimmingconf_20221115.h b/PWGCF/TwoParticleCorrelations/TableProducer/Productions/skimmingconf_20221115.h index 0299ca49dcf..124dc3116fe 100644 --- a/PWGCF/TwoParticleCorrelations/TableProducer/Productions/skimmingconf_20221115.h +++ b/PWGCF/TwoParticleCorrelations/TableProducer/Productions/skimmingconf_20221115.h @@ -9,8 +9,10 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisTask.h" +/// IMPORTANT: Cannot have header guard because it's included multiple times inside the code. +// NOLINT(build/header_guard) + +#include #include #include diff --git a/PWGCF/TwoParticleCorrelations/TableProducer/longrangeMaker.cxx b/PWGCF/TwoParticleCorrelations/TableProducer/longrangeMaker.cxx index a7d90746265..927f98edc35 100644 --- a/PWGCF/TwoParticleCorrelations/TableProducer/longrangeMaker.cxx +++ b/PWGCF/TwoParticleCorrelations/TableProducer/longrangeMaker.cxx @@ -15,50 +15,54 @@ /// \author Abhi Modak (abhi.modak@cern.ch) /// \since October 28, 2025 +#include "SGCutParHolder.h" +#include "UDHelpers.h" + #include "PWGCF/Core/CorrelationContainer.h" -#include "PWGCF/Core/PairCuts.h" #include "PWGCF/TwoParticleCorrelations/DataModel/LongRangeDerived.h" #include "PWGLF/DataModel/LFStrangenessTables.h" #include "PWGMM/Mult/DataModel/bestCollisionTable.h" #include "PWGUD/Core/SGSelector.h" #include "PWGUD/Core/UPCHelpers.h" +#include "Common/CCDB/EventSelectionParams.h" #include "Common/Core/RecoDecay.h" #include "Common/Core/TrackSelection.h" #include "Common/Core/TrackSelectionDefaults.h" -#include "Common/Core/trackUtilities.h" #include "Common/DataModel/Centrality.h" -#include "Common/DataModel/CollisionAssociationTables.h" #include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/FT0Corrected.h" #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponseITS.h" #include "Common/DataModel/PIDResponseTOF.h" #include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "CCDB/BasicCCDBManager.h" -#include "CCDB/CcdbApi.h" -#include "CommonConstants/MathConstants.h" -#include "CommonConstants/PhysicsConstants.h" -#include "DetectorsCommonDataFormats/AlignParam.h" -#include "FT0Base/Geometry.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "Framework/runDataProcessing.h" -#include "ReconstructionDataFormats/PID.h" -#include "ReconstructionDataFormats/Track.h" - -#include -#include -#include -#include - +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include #include +#include +#include #include +#include #include #include diff --git a/PWGCF/TwoParticleCorrelations/TableProducer/twoParticleCorrelationsFiltering.cxx b/PWGCF/TwoParticleCorrelations/TableProducer/twoParticleCorrelationsFiltering.cxx index a13bc933961..914551008cb 100644 --- a/PWGCF/TwoParticleCorrelations/TableProducer/twoParticleCorrelationsFiltering.cxx +++ b/PWGCF/TwoParticleCorrelations/TableProducer/twoParticleCorrelationsFiltering.cxx @@ -9,25 +9,25 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. +#include "EventSelectionFilterAndAnalysis.h" +#include "PIDSelectionFilterAndAnalysis.h" +#include "SelectionFilterAndAnalysis.h" +#include "TrackSelectionFilterAndAnalysis.h" + #include "PWGCF/TwoParticleCorrelations/Core/FilterAndAnalysisFramework.h" #include "PWGCF/TwoParticleCorrelations/DataModel/TwoParticleCorrelationsFiltered.h" #include "PWGCF/TwoParticleCorrelations/DataModel/TwoParticleCorrelationsSkimmed.h" -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include #include +#include #include using namespace o2; diff --git a/PWGCF/TwoParticleCorrelations/TableProducer/twoParticleCorrelationsFullSkimming.cxx b/PWGCF/TwoParticleCorrelations/TableProducer/twoParticleCorrelationsFullSkimming.cxx index 9c1f5ffe71c..35dbea96dd0 100644 --- a/PWGCF/TwoParticleCorrelations/TableProducer/twoParticleCorrelationsFullSkimming.cxx +++ b/PWGCF/TwoParticleCorrelations/TableProducer/twoParticleCorrelationsFullSkimming.cxx @@ -9,6 +9,11 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. +#include "EventSelectionFilterAndAnalysis.h" +#include "PIDSelectionFilterAndAnalysis.h" +#include "SelectionFilterAndAnalysis.h" +#include "TrackSelectionFilterAndAnalysis.h" + #include "PWGCF/TwoParticleCorrelations/Core/FilterAndAnalysisFramework.h" #include "PWGCF/TwoParticleCorrelations/DataModel/TwoParticleCorrelationsSkimmed.h" @@ -18,13 +23,24 @@ #include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "DataFormatsParameters/GRPObject.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" #include - +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include #include using namespace o2; diff --git a/PWGCF/TwoParticleCorrelations/TableProducer/twoParticleCorrelationsNotStoredSkimming.cxx b/PWGCF/TwoParticleCorrelations/TableProducer/twoParticleCorrelationsNotStoredSkimming.cxx index 544e48e2076..f9a4ea5cf82 100644 --- a/PWGCF/TwoParticleCorrelations/TableProducer/twoParticleCorrelationsNotStoredSkimming.cxx +++ b/PWGCF/TwoParticleCorrelations/TableProducer/twoParticleCorrelationsNotStoredSkimming.cxx @@ -9,6 +9,11 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. +#include "EventSelectionFilterAndAnalysis.h" +#include "PIDSelectionFilterAndAnalysis.h" +#include "SelectionFilterAndAnalysis.h" +#include "TrackSelectionFilterAndAnalysis.h" + #include "PWGCF/TwoParticleCorrelations/Core/FilterAndAnalysisFramework.h" #include "PWGCF/TwoParticleCorrelations/DataModel/TwoParticleCorrelationsSkimmed.h" @@ -18,12 +23,24 @@ #include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "DataFormatsParameters/GRPObject.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include using namespace o2; using namespace o2::framework; diff --git a/PWGCF/TwoParticleCorrelations/TableProducer/twoParticleCorrelationsRegisterSkimming.cxx b/PWGCF/TwoParticleCorrelations/TableProducer/twoParticleCorrelationsRegisterSkimming.cxx index 0791f456a4c..ff70c146212 100644 --- a/PWGCF/TwoParticleCorrelations/TableProducer/twoParticleCorrelationsRegisterSkimming.cxx +++ b/PWGCF/TwoParticleCorrelations/TableProducer/twoParticleCorrelationsRegisterSkimming.cxx @@ -9,13 +9,17 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. +#include "EventSelectionFilterAndAnalysis.h" +#include "PIDSelectionFilterAndAnalysis.h" +#include "SelectionFilterAndAnalysis.h" +#include "TrackSelectionFilterAndAnalysis.h" + #include "PWGCF/TwoParticleCorrelations/Core/FilterAndAnalysisFramework.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" -#include +#include +#include +#include +#include using namespace o2; using namespace o2::framework; diff --git a/PWGCF/TwoParticleCorrelations/Tasks/corrSparse.cxx b/PWGCF/TwoParticleCorrelations/Tasks/corrSparse.cxx index e0c75ff22a6..a1f5bbd4e74 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/corrSparse.cxx +++ b/PWGCF/TwoParticleCorrelations/Tasks/corrSparse.cxx @@ -14,50 +14,52 @@ /// \author Thor Jensen (thor.kjaersgaard.jensen@cern.ch) #include "PWGCF/Core/CorrelationContainer.h" -#include "PWGCF/Core/PairCuts.h" -#include "PWGCF/DataModel/CorrelationsDerived.h" -#include "PWGCF/GenericFramework/Core/GFW.h" -#include "PWGCF/GenericFramework/Core/GFWCumulant.h" -#include "PWGCF/GenericFramework/Core/GFWPowerArray.h" -#include "PWGCF/GenericFramework/Core/GFWWeights.h" #include "PWGMM/Mult/DataModel/bestCollisionTable.h" +#include "Common/CCDB/EventSelectionParams.h" #include "Common/Core/RecoDecay.h" -#include "Common/DataModel/Centrality.h" -#include "Common/DataModel/CollisionAssociationTables.h" #include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/FT0Corrected.h" #include "Common/DataModel/Multiplicity.h" -#include "Common/DataModel/PIDResponseITS.h" -#include "Common/DataModel/PIDResponseTOF.h" -#include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "CommonConstants/MathConstants.h" -#include "DataFormatsParameters/GRPMagField.h" -#include "DataFormatsParameters/GRPObject.h" -#include "DetectorsCommonDataFormats/AlignParam.h" -#include "FT0Base/Geometry.h" -#include "FV0Base/Geometry.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/StepTHn.h" -#include "Framework/runDataProcessing.h" -#include "ReconstructionDataFormats/PID.h" -#include "ReconstructionDataFormats/Track.h" #include - -#include "TRandom3.h" - +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include #include #include using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; +using namespace constants::math; + namespace o2::aod { namespace corrsparse @@ -236,7 +238,7 @@ struct CorrSparse { // make the filters and cuts. Filter collisionFilter = (nabs(aod::collision::posZ) < cfgZVtxCut); - Filter trackFilter = (nabs(aod::track::eta) < cfgTrackCuts.cfgEtaCut) && (cfgTrackCuts.cfgPtCutMin < aod::track::pt) && (cfgTrackCuts.cfgPtCutMax > aod::track::pt) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true)) && (aod::track::tpcChi2NCl < cfgTrackCuts.cfgCutChi2prTPCcls) && (aod::track::dcaZ < cfgTrackCuts.cfgCutDCAz); + Filter trackFilter = (nabs(aod::track::eta) < cfgTrackCuts.cfgEtaCut) && (cfgTrackCuts.cfgPtCutMin < aod::track::pt) && (cfgTrackCuts.cfgPtCutMax > aod::track::pt) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t)true)) && (aod::track::tpcChi2NCl < cfgTrackCuts.cfgCutChi2prTPCcls) && (aod::track::dcaZ < cfgTrackCuts.cfgCutDCAz); Filter mftTrackEtaFilter = ((aod::fwdtrack::eta < cfgMftConfig.etaMftTrackMaxFilter) && (aod::fwdtrack::eta > cfgMftConfig.etaMftTrackMinFilter)); diff --git a/PWGCF/TwoParticleCorrelations/Tasks/diHadronCor.cxx b/PWGCF/TwoParticleCorrelations/Tasks/diHadronCor.cxx index 1398bfa374c..0bf84ab594a 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/diHadronCor.cxx +++ b/PWGCF/TwoParticleCorrelations/Tasks/diHadronCor.cxx @@ -15,42 +15,48 @@ /// \since May/03/2025 #include "PWGCF/Core/CorrelationContainer.h" -#include "PWGCF/Core/PairCuts.h" -#include "PWGCF/DataModel/CorrelationsDerived.h" -#include "PWGCF/GenericFramework/Core/GFW.h" -#include "PWGCF/GenericFramework/Core/GFWCumulant.h" -#include "PWGCF/GenericFramework/Core/GFWPowerArray.h" -#include "PWGCF/GenericFramework/Core/GFWWeights.h" +#include "Common/CCDB/EventSelectionParams.h" #include "Common/Core/RecoDecay.h" #include "Common/DataModel/Centrality.h" -#include "Common/DataModel/CollisionAssociationTables.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "CommonConstants/MathConstants.h" -#include "DataFormatsParameters/GRPMagField.h" -#include "DataFormatsParameters/GRPObject.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/StepTHn.h" -#include "Framework/runDataProcessing.h" #include - -#include "TF1.h" -#include "TRandom3.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include #include - +#include + +#include +#include +#include +#include +#include +#include #include #include using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; +using namespace constants::math; // define the filtered collisions and tracks #define O2_DEFINE_CONFIGURABLE(NAME, TYPE, DEFAULT, HELP) Configurable NAME{#NAME, DEFAULT, HELP}; @@ -154,7 +160,7 @@ struct DiHadronCor { // make the filters and cuts. Filter collisionFilter = (nabs(aod::collision::posZ) < cfgCutVtxZ); - Filter trackFilter = (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPtMin) && (aod::track::pt < cfgCutPtMax) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true)) && (aod::track::tpcChi2NCl < cfgCutChi2prTPCcls) && (nabs(aod::track::dcaZ) < cfgCutDCAz); + Filter trackFilter = (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPtMin) && (aod::track::pt < cfgCutPtMax) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t)true)) && (aod::track::tpcChi2NCl < cfgCutChi2prTPCcls) && (nabs(aod::track::dcaZ) < cfgCutDCAz); using FilteredCollisions = soa::Filtered>; using FilteredTracks = soa::Filtered>; using FilteredTracksWithMCLabels = soa::Filtered>; diff --git a/PWGCF/TwoParticleCorrelations/Tasks/dptDptEfficiencyAndQc.cxx b/PWGCF/TwoParticleCorrelations/Tasks/dptDptEfficiencyAndQc.cxx index 37aabda0f26..e8899bbd173 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/dptDptEfficiencyAndQc.cxx +++ b/PWGCF/TwoParticleCorrelations/Tasks/dptDptEfficiencyAndQc.cxx @@ -19,29 +19,36 @@ #include "Common/Core/RecoDecay.h" #include "Common/Core/TableHelper.h" -#include "Common/Core/TrackSelection.h" #include "Common/DataModel/PIDResponseTOF.h" #include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/Expressions.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/runDataProcessing.h" -#include "ReconstructionDataFormats/PID.h" #include - -#include "Math/MatrixFunctions.h" -#include "Math/SMatrix.h" -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include #include #include #include #include +#include + +#include -#include +#include #include #include #include @@ -51,6 +58,7 @@ using namespace o2; using namespace o2::framework; using namespace o2::soa; using namespace o2::framework::expressions; +using namespace o2::common::core; #define ADDHISTOGRAM(thetype, thedirectory, thename, thetitle, thekind, thebinning...) \ registry.add(TString::Format("%s/%s", thedirectory, thename).Data(), thetitle, thekind, thebinning) diff --git a/PWGCF/TwoParticleCorrelations/Tasks/dptDptPerRunExtraQc.cxx b/PWGCF/TwoParticleCorrelations/Tasks/dptDptPerRunExtraQc.cxx index c9304ec1ef9..9cc322d26de 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/dptDptPerRunExtraQc.cxx +++ b/PWGCF/TwoParticleCorrelations/Tasks/dptDptPerRunExtraQc.cxx @@ -14,16 +14,19 @@ /// \author victor.gonzalez.sebastian@gmail.com #include "PWGCF/DataModel/DptDptFiltered.h" -#include "PWGCF/TableProducer/dptDptFilter.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/runDataProcessing.h" +#include +#include +#include +#include +#include +#include +#include + +#include -#include #include +#include #include using namespace o2; @@ -82,8 +85,6 @@ struct DptDptPerRunExtraQc { void process(soa::Filtered>::iterator const& collision, soa::Filtered> const& tracks, aod::BCsWithTimestamps const&) { - using namespace analysis::dptdptfilter; - if (!collision.collisionaccepted()) { return; } diff --git a/PWGCF/TwoParticleCorrelations/Tasks/dptDptPerRunQc.cxx b/PWGCF/TwoParticleCorrelations/Tasks/dptDptPerRunQc.cxx index 286641391ea..178a23d115e 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/dptDptPerRunQc.cxx +++ b/PWGCF/TwoParticleCorrelations/Tasks/dptDptPerRunQc.cxx @@ -14,23 +14,30 @@ /// \author victor.gonzalez.sebastian@gmail.com #include "PWGCF/DataModel/DptDptFiltered.h" -#include "PWGCF/TableProducer/dptDptFilter.h" #include "Common/CCDB/ctpRateFetcher.h" +#include "Common/DataModel/EventSelection.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include -#include "CCDB/BasicCCDBManager.h" -#include "DataFormatsITSMFT/NoiseMap.h" // missing include in TimeDeadMap.h -#include "DataFormatsITSMFT/TimeDeadMap.h" -#include "DataFormatsParameters/AggregatedRunInfo.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/runDataProcessing.h" -#include "ITSMFTReconstruction/ChipMappingITS.h" - -#include #include +#include #include #include #include @@ -69,7 +76,6 @@ struct DptDptPerRunQc { void initCCDB(aod::BCsWithTimestamps::iterator const& bc) { using namespace perrunqctask; - using namespace analysis::dptdptfilter; if (mRunNumber == bc.runNumber()) { return; @@ -116,7 +122,6 @@ struct DptDptPerRunQc { void process(soa::Join::iterator const& collision, aod::BCsWithTimestamps const&) { using namespace perrunqctask; - using namespace analysis::dptdptfilter; auto bc = collision.bc_as(); initCCDB(bc); diff --git a/PWGCF/TwoParticleCorrelations/Tasks/etaDihadron.cxx b/PWGCF/TwoParticleCorrelations/Tasks/etaDihadron.cxx index bc34cfb35c4..7aaa275a16e 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/etaDihadron.cxx +++ b/PWGCF/TwoParticleCorrelations/Tasks/etaDihadron.cxx @@ -15,42 +15,48 @@ /// \since May/03/2025 #include "PWGCF/Core/CorrelationContainer.h" -#include "PWGCF/Core/PairCuts.h" -#include "PWGCF/DataModel/CorrelationsDerived.h" -#include "PWGCF/GenericFramework/Core/GFW.h" -#include "PWGCF/GenericFramework/Core/GFWCumulant.h" -#include "PWGCF/GenericFramework/Core/GFWPowerArray.h" -#include "PWGCF/GenericFramework/Core/GFWWeights.h" +#include "Common/CCDB/EventSelectionParams.h" #include "Common/Core/RecoDecay.h" #include "Common/DataModel/Centrality.h" -#include "Common/DataModel/CollisionAssociationTables.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "CommonConstants/MathConstants.h" -#include "DataFormatsParameters/GRPMagField.h" -#include "DataFormatsParameters/GRPObject.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/StepTHn.h" -#include "Framework/runDataProcessing.h" #include - -#include "TF1.h" -#include "TRandom3.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include #include - +#include + +#include +#include +#include +#include +#include +#include #include #include using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; +using namespace constants::math; // define the filtered collisions and tracks #define O2_DEFINE_CONFIGURABLE(NAME, TYPE, DEFAULT, HELP) Configurable NAME{#NAME, DEFAULT, HELP}; @@ -153,7 +159,7 @@ struct EtaDihadron { // make the filters and cuts. Filter collisionFilter = (nabs(aod::collision::posZ) < cfgCutVtxZ); - Filter trackFilter = (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPtMin) && (aod::track::pt < cfgCutPtMax) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true)) && (aod::track::tpcChi2NCl < cfgCutChi2prTPCcls) && (nabs(aod::track::dcaZ) < cfgCutDCAz); + Filter trackFilter = (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPtMin) && (aod::track::pt < cfgCutPtMax) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t)true)) && (aod::track::tpcChi2NCl < cfgCutChi2prTPCcls) && (nabs(aod::track::dcaZ) < cfgCutDCAz); using FilteredCollisions = soa::Filtered>; using FilteredTracks = soa::Filtered>; using FilteredTracksWithMCLabels = soa::Filtered>; diff --git a/PWGCF/TwoParticleCorrelations/Tasks/flowDecorrelation.cxx b/PWGCF/TwoParticleCorrelations/Tasks/flowDecorrelation.cxx index 61eb715a0a1..93f8163d625 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/flowDecorrelation.cxx +++ b/PWGCF/TwoParticleCorrelations/Tasks/flowDecorrelation.cxx @@ -15,48 +15,49 @@ /// \since Sep/10/2025 #include "PWGCF/Core/CorrelationContainer.h" -#include "PWGCF/Core/PairCuts.h" -#include "PWGCF/DataModel/CorrelationsDerived.h" -#include "PWGCF/GenericFramework/Core/GFW.h" -#include "PWGCF/GenericFramework/Core/GFWCumulant.h" -#include "PWGCF/GenericFramework/Core/GFWPowerArray.h" -#include "PWGCF/GenericFramework/Core/GFWWeights.h" +#include "Common/CCDB/EventSelectionParams.h" #include "Common/Core/RecoDecay.h" #include "Common/DataModel/Centrality.h" -#include "Common/DataModel/CollisionAssociationTables.h" #include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/FT0Corrected.h" #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "CommonConstants/MathConstants.h" -#include "DataFormatsParameters/GRPMagField.h" -#include "DataFormatsParameters/GRPObject.h" -#include "DetectorsCommonDataFormats/AlignParam.h" -#include "FT0Base/Geometry.h" -#include "FV0Base/Geometry.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/StepTHn.h" -#include "Framework/runDataProcessing.h" -#include "ReconstructionDataFormats/Track.h" #include - -#include "TF1.h" -#include "TRandom3.h" -#include - +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include #include -#include #include using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; +using namespace constants::math; // define the filtered collisions and tracks #define O2_DEFINE_CONFIGURABLE(NAME, TYPE, DEFAULT, HELP) Configurable NAME{#NAME, DEFAULT, HELP}; diff --git a/PWGCF/TwoParticleCorrelations/Tasks/lambdaR2Correlation.cxx b/PWGCF/TwoParticleCorrelations/Tasks/lambdaR2Correlation.cxx index 0d0d75c58bb..56201ca6bd3 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/lambdaR2Correlation.cxx +++ b/PWGCF/TwoParticleCorrelations/Tasks/lambdaR2Correlation.cxx @@ -15,21 +15,42 @@ #include "PWGLF/DataModel/LFStrangenessTables.h" +#include "Common/CCDB/EventSelectionParams.h" +#include "Common/CCDB/TriggerAliases.h" #include "Common/Core/RecoDecay.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/CollisionAssociationTables.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponseTPC.h" - -#include "CCDB/BasicCCDBManager.h" -#include "CommonConstants/PhysicsConstants.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include #include +#include +#include #include +#include #include using namespace o2; diff --git a/PWGCF/TwoParticleCorrelations/Tasks/lambdaSpinPolarization.cxx b/PWGCF/TwoParticleCorrelations/Tasks/lambdaSpinPolarization.cxx index e0eefb67fad..231868f9e3c 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/lambdaSpinPolarization.cxx +++ b/PWGCF/TwoParticleCorrelations/Tasks/lambdaSpinPolarization.cxx @@ -15,22 +15,44 @@ #include "PWGLF/DataModel/LFStrangenessTables.h" +#include "Common/CCDB/EventSelectionParams.h" +#include "Common/CCDB/TriggerAliases.h" #include "Common/Core/RecoDecay.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/CollisionAssociationTables.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponseTPC.h" - -#include "CCDB/BasicCCDBManager.h" -#include "CommonConstants/PhysicsConstants.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/GroupedCombinations.h" -#include "Framework/runDataProcessing.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include #include +#include +#include #include +#include #include using namespace o2; diff --git a/PWGCF/TwoParticleCorrelations/Tasks/longRangeDihadronCor.cxx b/PWGCF/TwoParticleCorrelations/Tasks/longRangeDihadronCor.cxx index f50d8f15e6c..87491892ee4 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/longRangeDihadronCor.cxx +++ b/PWGCF/TwoParticleCorrelations/Tasks/longRangeDihadronCor.cxx @@ -15,45 +15,47 @@ /// \since Sep/10/2025 #include "PWGCF/Core/CorrelationContainer.h" -#include "PWGCF/Core/PairCuts.h" -#include "PWGCF/DataModel/CorrelationsDerived.h" -#include "PWGCF/GenericFramework/Core/GFW.h" -#include "PWGCF/GenericFramework/Core/GFWCumulant.h" -#include "PWGCF/GenericFramework/Core/GFWPowerArray.h" -#include "PWGCF/GenericFramework/Core/GFWWeights.h" +#include "Common/CCDB/EventSelectionParams.h" #include "Common/Core/RecoDecay.h" #include "Common/DataModel/Centrality.h" -#include "Common/DataModel/CollisionAssociationTables.h" #include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/FT0Corrected.h" #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponseITS.h" #include "Common/DataModel/PIDResponseTOF.h" #include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "CommonConstants/MathConstants.h" -#include "DataFormatsParameters/GRPMagField.h" -#include "DataFormatsParameters/GRPObject.h" -#include "DetectorsCommonDataFormats/AlignParam.h" -#include "FT0Base/Geometry.h" -#include "FV0Base/Geometry.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/StepTHn.h" -#include "Framework/runDataProcessing.h" -#include "ReconstructionDataFormats/PID.h" -#include "ReconstructionDataFormats/Track.h" #include - -#include "TF1.h" -#include "TRandom3.h" -#include - +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include #include #include #include @@ -63,6 +65,7 @@ using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; +using namespace constants::math; // define the filtered collisions and tracks #define O2_DEFINE_CONFIGURABLE(NAME, TYPE, DEFAULT, HELP) Configurable NAME{#NAME, DEFAULT, HELP}; diff --git a/PWGCF/TwoParticleCorrelations/Tasks/longrangeCorrelation.cxx b/PWGCF/TwoParticleCorrelations/Tasks/longrangeCorrelation.cxx index 2986c545c90..c646439fd28 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/longrangeCorrelation.cxx +++ b/PWGCF/TwoParticleCorrelations/Tasks/longrangeCorrelation.cxx @@ -16,48 +16,52 @@ /// \since April 22, 2025 #include "PWGCF/Core/CorrelationContainer.h" -#include "PWGCF/Core/PairCuts.h" -#include "PWGCF/DataModel/CorrelationsDerived.h" #include "PWGMM/Mult/DataModel/bestCollisionTable.h" +#include "Common/CCDB/EventSelectionParams.h" #include "Common/Core/RecoDecay.h" -#include "Common/Core/TrackSelection.h" -#include "Common/Core/trackUtilities.h" #include "Common/DataModel/Centrality.h" -#include "Common/DataModel/CollisionAssociationTables.h" #include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/FT0Corrected.h" -#include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponseITS.h" #include "Common/DataModel/PIDResponseTOF.h" #include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "CCDB/BasicCCDBManager.h" -#include "CCDB/CcdbApi.h" -#include "CommonConstants/MathConstants.h" -#include "CommonConstants/PhysicsConstants.h" -#include "DetectorsCommonDataFormats/AlignParam.h" -#include "FT0Base/Geometry.h" -#include "FV0Base/Geometry.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "Framework/StepTHn.h" -#include "Framework/runDataProcessing.h" -#include "ReconstructionDataFormats/PID.h" -#include "ReconstructionDataFormats/Track.h" - -#include -#include -#include -#include - +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include #include +#include +#include #include #include +#include #include using namespace o2; diff --git a/PWGCF/TwoParticleCorrelations/Tasks/longrangecorrDerived.cxx b/PWGCF/TwoParticleCorrelations/Tasks/longrangecorrDerived.cxx index 977f534729a..f6b38189164 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/longrangecorrDerived.cxx +++ b/PWGCF/TwoParticleCorrelations/Tasks/longrangecorrDerived.cxx @@ -16,52 +16,27 @@ /// \since November 05, 2025 #include "PWGCF/Core/CorrelationContainer.h" -#include "PWGCF/Core/PairCuts.h" -#include "PWGCF/DataModel/CorrelationsDerived.h" #include "PWGCF/TwoParticleCorrelations/DataModel/LongRangeDerived.h" -#include "PWGMM/Mult/DataModel/bestCollisionTable.h" #include "PWGUD/Core/SGSelector.h" #include "Common/Core/RecoDecay.h" -#include "Common/Core/TrackSelection.h" -#include "Common/Core/trackUtilities.h" -#include "Common/DataModel/Centrality.h" -#include "Common/DataModel/CollisionAssociationTables.h" -#include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/FT0Corrected.h" -#include "Common/DataModel/Multiplicity.h" -#include "Common/DataModel/PIDResponseITS.h" -#include "Common/DataModel/PIDResponseTOF.h" -#include "Common/DataModel/PIDResponseTPC.h" -#include "Common/DataModel/TrackSelectionTables.h" - -#include "CCDB/BasicCCDBManager.h" -#include "CCDB/CcdbApi.h" -#include "CommonConstants/MathConstants.h" -#include "CommonConstants/PhysicsConstants.h" -#include "DetectorsCommonDataFormats/AlignParam.h" -#include "FT0Base/Geometry.h" -#include "FV0Base/Geometry.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/StepTHn.h" -#include "Framework/runDataProcessing.h" -#include "ReconstructionDataFormats/PID.h" -#include "ReconstructionDataFormats/Track.h" - -#include -#include -#include -#include - -#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include #include #include -#include #include #include #include diff --git a/PWGCF/TwoParticleCorrelations/Tasks/neutronProtonCorrZdc.cxx b/PWGCF/TwoParticleCorrelations/Tasks/neutronProtonCorrZdc.cxx index 772d7c9d288..30ea2b53197 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/neutronProtonCorrZdc.cxx +++ b/PWGCF/TwoParticleCorrelations/Tasks/neutronProtonCorrZdc.cxx @@ -13,15 +13,29 @@ /// \brief Correlations between protons and neutrons in the ZDC /// \author Olaf Massen -#include -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/ASoAHelpers.h" -#include "Common/DataModel/TrackSelectionTables.h" -#include "Common/DataModel/EventSelection.h" +#include "Common/CCDB/EventSelectionParams.h" +#include "Common/CCDB/TriggerAliases.h" #include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" -#include "Framework/StaticFor.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include using namespace o2; using namespace o2::framework; diff --git a/PWGCF/TwoParticleCorrelations/Tasks/nucleibalance.cxx b/PWGCF/TwoParticleCorrelations/Tasks/nucleibalance.cxx index c905bda396d..611b8a8ca03 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/nucleibalance.cxx +++ b/PWGCF/TwoParticleCorrelations/Tasks/nucleibalance.cxx @@ -17,6 +17,7 @@ #include "PWGCF/Core/PairCuts.h" #include "PWGCF/DataModel/CorrelationsDerived.h" +#include "Common/CCDB/EventSelectionParams.h" #include "Common/Core/RecoDecay.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" @@ -27,32 +28,41 @@ #include #include #include -#include #include -#include #include +#include #include +#include +#include +#include +#include +#include #include -#include +#include +#include #include #include #include #include #include -#include #include -#include #include -#include +#include + +#include +#include +#include #include +#include #include #include -#include +#include #include #include #include +#include #include #include @@ -244,7 +254,7 @@ struct Nucleibalance { Filter collisionVertexTypeFilter = (aod::collision::flags & static_cast(aod::collision::CollisionFlagsRun2::Run2VertexerTracks)) == static_cast(aod::collision::CollisionFlagsRun2::Run2VertexerTracks); // Track filters - Filter trackFilter = (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPt) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true)); + Filter trackFilter = (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPt) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t)true)); Filter cfTrackFilter = (nabs(aod::cftrack::eta) < cfgCutEta) && (aod::cftrack::pt > cfgCutPt) && ((aod::track::trackType & (uint8_t)cfgTrackBitMask) == (uint8_t)cfgTrackBitMask); // MC filters diff --git a/PWGCF/TwoParticleCorrelations/Tasks/pidDiHadron.cxx b/PWGCF/TwoParticleCorrelations/Tasks/pidDiHadron.cxx index 2ae92312225..641bb2f8ffb 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/pidDiHadron.cxx +++ b/PWGCF/TwoParticleCorrelations/Tasks/pidDiHadron.cxx @@ -15,14 +15,12 @@ /// \since July/29/2025 #include "PWGCF/Core/CorrelationContainer.h" -#include "PWGCF/Core/PairCuts.h" -#include "PWGCF/DataModel/CorrelationsDerived.h" -#include "PWGLF/DataModel/EPCalibrationTables.h" #include "PWGLF/DataModel/LFStrangenessTables.h" +#include "Common/CCDB/EventSelectionParams.h" +#include "Common/CCDB/TriggerAliases.h" #include "Common/Core/RecoDecay.h" #include "Common/DataModel/Centrality.h" -#include "Common/DataModel/CollisionAssociationTables.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponseITS.h" @@ -30,30 +28,44 @@ #include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "CommonConstants/MathConstants.h" -#include "DataFormatsParameters/GRPMagField.h" -#include "DataFormatsParameters/GRPObject.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/StepTHn.h" -#include "Framework/runDataProcessing.h" -#include "ReconstructionDataFormats/PID.h" -#include "ReconstructionDataFormats/Track.h" #include - -#include "TF1.h" -#include "TRandom3.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include #include +#include +#include + +#include +#include +#include +#include +#include #include #include using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; +using namespace constants::math; // define the filtered collisions and tracks #define O2_DEFINE_CONFIGURABLE(NAME, TYPE, DEFAULT, HELP) Configurable NAME{#NAME, DEFAULT, HELP}; @@ -186,7 +198,7 @@ struct PidDiHadron { // make the filters and cuts. Filter collisionFilter = (nabs(aod::collision::posZ) < cfgCutVertex); - Filter trackFilter = (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPtPOIMin) && (aod::track::pt < cfgCutPtPOIMax) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true)) && (aod::track::tpcChi2NCl < cfgCutChi2prTPCcls) && (nabs(aod::track::dcaZ) < cfgCutDCAz); + Filter trackFilter = (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPtPOIMin) && (aod::track::pt < cfgCutPtPOIMax) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t)true)) && (aod::track::tpcChi2NCl < cfgCutChi2prTPCcls) && (nabs(aod::track::dcaZ) < cfgCutDCAz); using FilteredCollisions = soa::Filtered>; using FilteredTracks = soa::Filtered>; diff --git a/PWGCF/TwoParticleCorrelations/Tasks/r2p2-4-id.cxx b/PWGCF/TwoParticleCorrelations/Tasks/r2p2-4-id.cxx index b12ee5481a1..3601f1f7fe4 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/r2p2-4-id.cxx +++ b/PWGCF/TwoParticleCorrelations/Tasks/r2p2-4-id.cxx @@ -14,11 +14,29 @@ #include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" - +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include #include +#include using namespace o2; using namespace o2::framework; diff --git a/PWGCF/TwoParticleCorrelations/Tasks/twoParticleCorrelationPp.cxx b/PWGCF/TwoParticleCorrelations/Tasks/twoParticleCorrelationPp.cxx index 24cfc066838..125fe4db09f 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/twoParticleCorrelationPp.cxx +++ b/PWGCF/TwoParticleCorrelations/Tasks/twoParticleCorrelationPp.cxx @@ -16,23 +16,31 @@ #include "PWGCF/Core/CorrelationContainer.h" #include "PWGCF/Core/PairCuts.h" +#include "Common/CCDB/EventSelectionParams.h" #include "Common/Core/RecoDecay.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "CommonConstants/MathConstants.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/runDataProcessing.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; +using namespace o2::constants::math; static constexpr float cfgPairCutDefaults[1][5] = {{-1, -1, -1, -1, -1}}; constexpr float kThreeHalfPi = 1.5f * PI; diff --git a/PWGCF/TwoParticleCorrelations/Tasks/twoParticleCorrelations.cxx b/PWGCF/TwoParticleCorrelations/Tasks/twoParticleCorrelations.cxx index 9ba279ad79d..bf7bfc0e996 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/twoParticleCorrelations.cxx +++ b/PWGCF/TwoParticleCorrelations/Tasks/twoParticleCorrelations.cxx @@ -9,28 +9,47 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. +#include "EventSelectionFilterAndAnalysis.h" +#include "PIDSelectionFilterAndAnalysis.h" +#include "SelectionFilterAndAnalysis.h" +#include "TrackSelectionFilterAndAnalysis.h" + #include "PWGCF/Core/AnalysisConfigurableCuts.h" #include "PWGCF/Core/PairCuts.h" #include "PWGCF/TwoParticleCorrelations/Core/FilterAndAnalysisFramework.h" #include "PWGCF/TwoParticleCorrelations/DataModel/TwoParticleCorrelationsSkimmed.h" -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" +#include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include -#include -#include -#include #include #include #include #include +#include #include -#include -#include + +#include + +#include #include +#include #include +#include +#include +#include #include #include From d16159f1009bbc2ad4adb76e73fdddab92f80d6e Mon Sep 17 00:00:00 2001 From: ALICE Action Bot Date: Fri, 13 Mar 2026 16:25:43 +0000 Subject: [PATCH 2/2] Please consider the following formatting changes --- PWGCF/EbyEFluctuations/Tasks/NetProtonCumulants.cxx | 2 +- PWGCF/EbyEFluctuations/Tasks/antiprotonCumulantsMc.cxx | 2 +- PWGCF/EbyEFluctuations/Tasks/netprotonCumulantsMc.cxx | 2 +- PWGCF/FemtoWorld/Core/FemtoWorldTrackSelection.h | 2 +- PWGCF/FemtoWorld/Core/FemtoWorldV0Selection.h | 2 +- PWGCF/Flow/Tasks/flowAnalysisGF.cxx | 2 +- PWGCF/Flow/Tasks/flowGfwOmegaXi.cxx | 2 +- PWGCF/Flow/Tasks/flowPbpbPikp.cxx | 2 +- PWGCF/Flow/Tasks/flowPidCme.cxx | 2 +- PWGCF/Flow/Tasks/flowRunbyRun.cxx | 2 +- PWGCF/Flow/Tasks/flowSP.cxx | 2 +- PWGCF/Flow/Tasks/flowTask.cxx | 2 +- PWGCF/Flow/Tasks/resonancesGfwFlow.cxx | 2 +- PWGCF/GenericFramework/Tasks/flowGenericFramework.cxx | 2 +- PWGCF/GenericFramework/Tasks/flowGfwLightIons.cxx | 2 +- PWGCF/JCorran/TableProducer/JCatalyst.cxx | 4 ++-- PWGCF/TableProducer/filterCorrelations.cxx | 4 ++-- PWGCF/Tasks/correlations.cxx | 2 +- PWGCF/TwoParticleCorrelations/Tasks/corrSparse.cxx | 2 +- PWGCF/TwoParticleCorrelations/Tasks/diHadronCor.cxx | 2 +- PWGCF/TwoParticleCorrelations/Tasks/etaDihadron.cxx | 2 +- PWGCF/TwoParticleCorrelations/Tasks/nucleibalance.cxx | 2 +- PWGCF/TwoParticleCorrelations/Tasks/pidDiHadron.cxx | 2 +- 23 files changed, 25 insertions(+), 25 deletions(-) diff --git a/PWGCF/EbyEFluctuations/Tasks/NetProtonCumulants.cxx b/PWGCF/EbyEFluctuations/Tasks/NetProtonCumulants.cxx index a0e91f90faa..d9e1f132bfa 100644 --- a/PWGCF/EbyEFluctuations/Tasks/NetProtonCumulants.cxx +++ b/PWGCF/EbyEFluctuations/Tasks/NetProtonCumulants.cxx @@ -69,7 +69,7 @@ struct NetProtonCumulants_Table_QA { // Filter command*********** Filter collisionFilter = nabs(aod::collision::posZ) < cfgCutVertex; - Filter trackFilter = (nabs(aod::track::eta) < 0.8f) && (aod::track::pt > cfgCutPtLower) && (aod::track::pt < 5.0f) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t)true)) && (aod::track::tpcChi2NCl < cfgCutTpcChi2NCl); + Filter trackFilter = (nabs(aod::track::eta) < 0.8f) && (aod::track::pt > cfgCutPtLower) && (aod::track::pt < 5.0f) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true)) && (aod::track::tpcChi2NCl < cfgCutTpcChi2NCl); // Connect to ccdb Service ccdb; diff --git a/PWGCF/EbyEFluctuations/Tasks/antiprotonCumulantsMc.cxx b/PWGCF/EbyEFluctuations/Tasks/antiprotonCumulantsMc.cxx index c96e1abbf65..00871c475c5 100644 --- a/PWGCF/EbyEFluctuations/Tasks/antiprotonCumulantsMc.cxx +++ b/PWGCF/EbyEFluctuations/Tasks/antiprotonCumulantsMc.cxx @@ -110,7 +110,7 @@ struct AntiprotonCumulantsMc { // Filter command for rec (data)*********** Filter collisionFilter = nabs(aod::collision::posZ) < cfgCutVertex; - Filter trackFilter = (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPtLower) && (aod::track::pt < 5.0f) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t)true)) && (aod::track::tpcChi2NCl < cfgCutTpcChi2NCl) && (aod::track::itsChi2NCl < cfgCutItsChi2NCl) && (nabs(aod::track::dcaZ) < cfgCutDCAz) && (nabs(aod::track::dcaXY) < cfgCutDCAxy); + Filter trackFilter = (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPtLower) && (aod::track::pt < 5.0f) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true)) && (aod::track::tpcChi2NCl < cfgCutTpcChi2NCl) && (aod::track::itsChi2NCl < cfgCutItsChi2NCl) && (nabs(aod::track::dcaZ) < cfgCutDCAz) && (nabs(aod::track::dcaXY) < cfgCutDCAxy); // filtering collisions and tracks for real data*********** using AodCollisions = soa::Filtered>; diff --git a/PWGCF/EbyEFluctuations/Tasks/netprotonCumulantsMc.cxx b/PWGCF/EbyEFluctuations/Tasks/netprotonCumulantsMc.cxx index 567c1152fda..2f31669b547 100644 --- a/PWGCF/EbyEFluctuations/Tasks/netprotonCumulantsMc.cxx +++ b/PWGCF/EbyEFluctuations/Tasks/netprotonCumulantsMc.cxx @@ -110,7 +110,7 @@ struct NetprotonCumulantsMc { // Filter command for rec (data)*********** Filter collisionFilter = nabs(aod::collision::posZ) < cfgCutVertex; - Filter trackFilter = (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPtLower) && (aod::track::pt < 5.0f) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t)true)) && (aod::track::tpcChi2NCl < cfgCutTpcChi2NCl) && (aod::track::itsChi2NCl < cfgCutItsChi2NCl) && (nabs(aod::track::dcaZ) < cfgCutDCAz) && (nabs(aod::track::dcaXY) < cfgCutDCAxy); + Filter trackFilter = (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPtLower) && (aod::track::pt < 5.0f) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true)) && (aod::track::tpcChi2NCl < cfgCutTpcChi2NCl) && (aod::track::itsChi2NCl < cfgCutItsChi2NCl) && (nabs(aod::track::dcaZ) < cfgCutDCAz) && (nabs(aod::track::dcaXY) < cfgCutDCAxy); // filtering collisions and tracks for real data*********** using AodCollisions = soa::Filtered>; diff --git a/PWGCF/FemtoWorld/Core/FemtoWorldTrackSelection.h b/PWGCF/FemtoWorld/Core/FemtoWorldTrackSelection.h index 2223aefa07b..1ba3a824eac 100644 --- a/PWGCF/FemtoWorld/Core/FemtoWorldTrackSelection.h +++ b/PWGCF/FemtoWorld/Core/FemtoWorldTrackSelection.h @@ -96,7 +96,7 @@ class FemtoWorldTrackSelection : public FemtoWorldObjectSelection void init(o2::framework::HistogramRegistry* registry); diff --git a/PWGCF/Flow/Tasks/flowAnalysisGF.cxx b/PWGCF/Flow/Tasks/flowAnalysisGF.cxx index 3eb239c4f5a..2c0187e75a0 100644 --- a/PWGCF/Flow/Tasks/flowAnalysisGF.cxx +++ b/PWGCF/Flow/Tasks/flowAnalysisGF.cxx @@ -738,7 +738,7 @@ struct flowAnalysisGF { } Filter collisionFilter = nabs(aod::collision::posZ) < cfgVtxZ; - Filter trackFilter = nabs(aod::track::eta) < cfgEta && aod::track::pt > cfgPtmin&& aod::track::pt < cfgPtmax && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t)true)) && nabs(aod::track::dcaXY) < cfgDCAxy&& nabs(aod::track::dcaZ) < cfgDCAz; + Filter trackFilter = nabs(aod::track::eta) < cfgEta && aod::track::pt > cfgPtmin&& aod::track::pt < cfgPtmax && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true)) && nabs(aod::track::dcaXY) < cfgDCAxy&& nabs(aod::track::dcaZ) < cfgDCAz; using myTracks = soa::Filtered>; diff --git a/PWGCF/Flow/Tasks/flowGfwOmegaXi.cxx b/PWGCF/Flow/Tasks/flowGfwOmegaXi.cxx index 20f58de9380..c73d989abb9 100644 --- a/PWGCF/Flow/Tasks/flowGfwOmegaXi.cxx +++ b/PWGCF/Flow/Tasks/flowGfwOmegaXi.cxx @@ -224,7 +224,7 @@ struct FlowGfwOmegaXi { AxisSpec axisMultiplicity{{0, 5, 10, 20, 30, 40, 50, 60, 70, 80, 90}, "Centrality (%)"}; Filter collisionFilter = nabs(aod::collision::posZ) < cfgCutVertex; - Filter trackFilter = (nabs(aod::track::eta) < trkQualityOpts.cfgCutEta.value) && (aod::track::pt > trkQualityOpts.cfgCutPtPOIMin.value) && (aod::track::pt < trkQualityOpts.cfgCutPtPOIMax.value) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t)true)) && (aod::track::tpcChi2NCl < cfgCutChi2prTPCcls) && (nabs(aod::track::dcaZ) < trkQualityOpts.cfgCutDCAz.value); + Filter trackFilter = (nabs(aod::track::eta) < trkQualityOpts.cfgCutEta.value) && (aod::track::pt > trkQualityOpts.cfgCutPtPOIMin.value) && (aod::track::pt < trkQualityOpts.cfgCutPtPOIMax.value) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true)) && (aod::track::tpcChi2NCl < cfgCutChi2prTPCcls) && (nabs(aod::track::dcaZ) < trkQualityOpts.cfgCutDCAz.value); using TracksPID = soa::Join; using AodTracks = soa::Filtered>; // tracks filter diff --git a/PWGCF/Flow/Tasks/flowPbpbPikp.cxx b/PWGCF/Flow/Tasks/flowPbpbPikp.cxx index caecf49b188..de29ae33e9f 100644 --- a/PWGCF/Flow/Tasks/flowPbpbPikp.cxx +++ b/PWGCF/Flow/Tasks/flowPbpbPikp.cxx @@ -150,7 +150,7 @@ struct FlowPbpbPikp { std::vector eventCuts; Filter collisionFilter = nabs(aod::collision::posZ) < cfgCutVertex; - Filter trackFilter = (nabs(aod::track::dcaXY) < cfgCutDCAxy) && (nabs(aod::track::dcaZ) < cfgCutDCAz) && (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPtPOIMin) && (aod::track::pt < cfgCutPtPOIMax) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t)true)) && (aod::track::tpcChi2NCl < cfgCutChi2prTPCcls); + Filter trackFilter = (nabs(aod::track::dcaXY) < cfgCutDCAxy) && (nabs(aod::track::dcaZ) < cfgCutDCAz) && (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPtPOIMin) && (aod::track::pt < cfgCutPtPOIMax) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true)) && (aod::track::tpcChi2NCl < cfgCutChi2prTPCcls); using AodCollisions = soa::Filtered>; using AodTracksWithoutBayes = soa::Filtered>; diff --git a/PWGCF/Flow/Tasks/flowPidCme.cxx b/PWGCF/Flow/Tasks/flowPidCme.cxx index 4f804c97fb3..46cbb863bde 100644 --- a/PWGCF/Flow/Tasks/flowPidCme.cxx +++ b/PWGCF/Flow/Tasks/flowPidCme.cxx @@ -237,7 +237,7 @@ struct FillPIDcolums { if (std::abs(track.eta()) > cfgMaxEtaPID) return false; if (cfgRequireGlobalTrack) { - if (!(track.isGlobalTrackSDD() == (uint8_t)true)) + if (!(track.isGlobalTrackSDD() == (uint8_t) true)) return false; } if (cfgUseCostomTrackCuts) { diff --git a/PWGCF/Flow/Tasks/flowRunbyRun.cxx b/PWGCF/Flow/Tasks/flowRunbyRun.cxx index 3d0937e319e..23b747eaf89 100644 --- a/PWGCF/Flow/Tasks/flowRunbyRun.cxx +++ b/PWGCF/Flow/Tasks/flowRunbyRun.cxx @@ -126,7 +126,7 @@ struct FlowRunbyRun { ConfigurableAxis axisT0A{"axisT0A", {200, 0, 200000}, "N_{ch} (T0A)"}; Filter collisionFilter = nabs(aod::collision::posZ) < cfgCutVertex; - Filter trackFilter = ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t)true)) && (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPtMin) && (aod::track::pt < cfgCutPtMax) && (aod::track::tpcChi2NCl < cfgCutChi2prTPCcls) && (nabs(aod::track::dcaZ) < cfgCutDCAz); + Filter trackFilter = ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true)) && (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPtMin) && (aod::track::pt < cfgCutPtMax) && (aod::track::tpcChi2NCl < cfgCutChi2prTPCcls) && (nabs(aod::track::dcaZ) < cfgCutDCAz); // Corrections TH1D* mEfficiency = nullptr; diff --git a/PWGCF/Flow/Tasks/flowSP.cxx b/PWGCF/Flow/Tasks/flowSP.cxx index 3ad6c9aa6d9..424da9eafc9 100644 --- a/PWGCF/Flow/Tasks/flowSP.cxx +++ b/PWGCF/Flow/Tasks/flowSP.cxx @@ -165,7 +165,7 @@ struct FlowSP { Configurable> cfgEvSelsMult{"cfgEvSelsMult", std::vector{1301.56, -41.4615, 0.478224, -0.00239449, 4.46966e-06, 2967.6, -102.927, 1.47488, -0.0106534, 3.28622e-05}, "Multiplicity cuts (Global) first 5 parameters cutLOW last 5 cutHIGH (Default is +-2sigma pass5) "}; Filter collisionFilter = nabs(aod::collision::posZ) < cfgEvSelsVtxZ; - Filter trackFilter = nabs(aod::track::eta) < cfgTrackSelsEta && aod::track::pt > cfgTrackSelsPtmin&& aod::track::pt < cfgTrackSelsPtmax && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t)true)) && nabs(aod::track::dcaXY) < cfgTrackSelsDCAxy&& nabs(aod::track::dcaZ) < cfgTrackSelsDCAz; + Filter trackFilter = nabs(aod::track::eta) < cfgTrackSelsEta && aod::track::pt > cfgTrackSelsPtmin&& aod::track::pt < cfgTrackSelsPtmax && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true)) && nabs(aod::track::dcaXY) < cfgTrackSelsDCAxy&& nabs(aod::track::dcaZ) < cfgTrackSelsDCAz; Filter trackFilterMC = nabs(aod::mcparticle::eta) < cfgTrackSelsEta && aod::mcparticle::pt > cfgTrackSelsPtmin&& aod::mcparticle::pt < cfgTrackSelsPtmax; using GeneralCollisions = soa::Join; using UnfilteredTracks = soa::Join; diff --git a/PWGCF/Flow/Tasks/flowTask.cxx b/PWGCF/Flow/Tasks/flowTask.cxx index a3665d6264c..3fa0b8541c1 100644 --- a/PWGCF/Flow/Tasks/flowTask.cxx +++ b/PWGCF/Flow/Tasks/flowTask.cxx @@ -236,7 +236,7 @@ struct FlowTask { ConfigurableAxis axisDCAxy{"axisDCAxy", {200, -1, 1}, "DCA_{xy} (cm)"}; Filter collisionFilter = (nabs(aod::collision::posZ) < cfgCutVertex) && (aod::cent::centFT0C > cfgCentFT0CMin) && (aod::cent::centFT0C < cfgCentFT0CMax); - Filter trackFilter = ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t)true)) && (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPtMin) && (aod::track::pt < cfgCutPtMax); + Filter trackFilter = ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true)) && (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPtMin) && (aod::track::pt < cfgCutPtMax); using FilteredCollisions = soa::Filtered>; using FilteredTracks = soa::Filtered>; // Filter for MCcollisions diff --git a/PWGCF/Flow/Tasks/resonancesGfwFlow.cxx b/PWGCF/Flow/Tasks/resonancesGfwFlow.cxx index 0ba13019c63..5749da5843c 100644 --- a/PWGCF/Flow/Tasks/resonancesGfwFlow.cxx +++ b/PWGCF/Flow/Tasks/resonancesGfwFlow.cxx @@ -241,7 +241,7 @@ struct ResonancesGfwFlow { ConfigurableAxis axisParticles{"axisParticles", {3, 0, 3}, "axis for different hadrons"}; Filter collisionFilter = nabs(aod::collision::posZ) < cfgCutVertex; - Filter trackFilter = (nabs(aod::track::dcaXY) < cfgCutDCAxy) && (nabs(aod::track::dcaZ) < cfgCutDCAz) && (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPtPOIMin) && (aod::track::pt < cfgCutPtPOIMax) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t)true)) && (aod::track::tpcChi2NCl < cfgCutChi2prTPCcls); + Filter trackFilter = (nabs(aod::track::dcaXY) < cfgCutDCAxy) && (nabs(aod::track::dcaZ) < cfgCutDCAz) && (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPtPOIMin) && (aod::track::pt < cfgCutPtPOIMax) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true)) && (aod::track::tpcChi2NCl < cfgCutChi2prTPCcls); using AodCollisions = soa::Filtered>; using AodTracksWithoutBayes = soa::Filtered>; diff --git a/PWGCF/GenericFramework/Tasks/flowGenericFramework.cxx b/PWGCF/GenericFramework/Tasks/flowGenericFramework.cxx index 6507f1b9687..d3c307cdb3b 100644 --- a/PWGCF/GenericFramework/Tasks/flowGenericFramework.cxx +++ b/PWGCF/GenericFramework/Tasks/flowGenericFramework.cxx @@ -1240,7 +1240,7 @@ struct FlowGenericFramework { } o2::framework::expressions::Filter collisionFilter = nabs(aod::collision::posZ) < cfgVtxZ; - o2::framework::expressions::Filter trackFilter = nabs(aod::track::eta) < cfgEta && aod::track::pt > cfgPtmin&& aod::track::pt < cfgPtmax && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t)true)) && (aod::track::itsChi2NCl < cfgTrackCuts.cfgChi2PrITSCls) && (aod::track::tpcChi2NCl < cfgTrackCuts.cfgChi2PrTPCCls) && nabs(aod::track::dcaZ) < cfgTrackCuts.cfgDCAz; + o2::framework::expressions::Filter trackFilter = nabs(aod::track::eta) < cfgEta && aod::track::pt > cfgPtmin&& aod::track::pt < cfgPtmax && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true)) && (aod::track::itsChi2NCl < cfgTrackCuts.cfgChi2PrITSCls) && (aod::track::tpcChi2NCl < cfgTrackCuts.cfgChi2PrTPCCls) && nabs(aod::track::dcaZ) < cfgTrackCuts.cfgDCAz; using GFWTracks = soa::Filtered>; // using GFWTracks = soa::Filtered>; diff --git a/PWGCF/GenericFramework/Tasks/flowGfwLightIons.cxx b/PWGCF/GenericFramework/Tasks/flowGfwLightIons.cxx index 269fe53f84d..585fc84a2fa 100644 --- a/PWGCF/GenericFramework/Tasks/flowGfwLightIons.cxx +++ b/PWGCF/GenericFramework/Tasks/flowGfwLightIons.cxx @@ -302,7 +302,7 @@ struct FlowGfwLightIons { TF1* fPtDepDCAxy = nullptr; o2::framework::expressions::Filter collisionFilter = nabs(aod::collision::posZ) < cfgVtxZ; - o2::framework::expressions::Filter trackFilter = nabs(aod::track::eta) < cfgEta && aod::track::pt > cfgPtmin&& aod::track::pt < cfgPtmax && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t)true)) && (aod::track::itsChi2NCl < cfgChi2PrITSCls) && (aod::track::tpcChi2NCl < cfgChi2PrTPCCls) && nabs(aod::track::dcaZ) < cfgDCAz; + o2::framework::expressions::Filter trackFilter = nabs(aod::track::eta) < cfgEta && aod::track::pt > cfgPtmin&& aod::track::pt < cfgPtmax && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true)) && (aod::track::itsChi2NCl < cfgChi2PrITSCls) && (aod::track::tpcChi2NCl < cfgChi2PrTPCCls) && nabs(aod::track::dcaZ) < cfgDCAz; Preslice perCollision = aod::track::collisionId; o2::framework::expressions::Filter mcCollFilter = nabs(aod::mccollision::posZ) < cfgVtxZ; diff --git a/PWGCF/JCorran/TableProducer/JCatalyst.cxx b/PWGCF/JCorran/TableProducer/JCatalyst.cxx index be6e9b41874..41b74c4b2be 100644 --- a/PWGCF/JCorran/TableProducer/JCatalyst.cxx +++ b/PWGCF/JCorran/TableProducer/JCatalyst.cxx @@ -65,7 +65,7 @@ struct JCatalyst { Filter collisionVertexTypeFilter = (collisionFlags == 0) || ((aod::collision::flags & collisionFlags) == collisionFlags); Filter trackFilter = (nabs(aod::track::eta) < etamax) && (aod::track::pt > ptmin) && (aod::track::pt < ptmax); - Filter trackSelection = (requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t)true); + Filter trackSelection = (requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true); Produces particleTrack; Produces collisionData; @@ -106,7 +106,7 @@ struct JMultiplicitySelector { O2_DEFINE_CONFIGURABLE(etamax, float, 0.9f, "Eta range for tracks") Filter trackFilter = (nabs(aod::track::eta) < etamax) && (aod::track::pt > ptmin); - Filter trackSelection = (requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t)true); + Filter trackSelection = (requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true); void processTracks(aod::Collision const&, soa::Filtered> const& tracks) { diff --git a/PWGCF/TableProducer/filterCorrelations.cxx b/PWGCF/TableProducer/filterCorrelations.cxx index 48cf2ea1279..f99ba22616a 100644 --- a/PWGCF/TableProducer/filterCorrelations.cxx +++ b/PWGCF/TableProducer/filterCorrelations.cxx @@ -120,7 +120,7 @@ struct FilterCF { // TODO how to have this in the second task? For now they are copied Filter trackFilter = (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPt); - Filter trackSelection = (requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t)true); + Filter trackSelection = (requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true); Filter mcCollisionFilter = nabs(aod::mccollision::posZ) < cfgCutVertex; @@ -584,7 +584,7 @@ struct MultiplicitySelector { O2_DEFINE_CONFIGURABLE(cfgCutEta, float, 0.8f, "Eta range for tracks") Filter trackFilter = (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPt); - Filter trackSelection = (requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t)true); + Filter trackSelection = (requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true); void init(InitContext&) { diff --git a/PWGCF/Tasks/correlations.cxx b/PWGCF/Tasks/correlations.cxx index 177f1c04f6b..03e58cc9171 100644 --- a/PWGCF/Tasks/correlations.cxx +++ b/PWGCF/Tasks/correlations.cxx @@ -149,7 +149,7 @@ struct CorrelationTask { Filter collisionVertexTypeFilter = (aod::collision::flags & static_cast(aod::collision::CollisionFlagsRun2::Run2VertexerTracks)) == static_cast(aod::collision::CollisionFlagsRun2::Run2VertexerTracks); // Track filters - Filter trackFilter = (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPt) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t)true)); + Filter trackFilter = (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPt) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true)); Filter cfTrackFilter = (nabs(aod::cftrack::eta) < cfgCutEta) && (aod::cftrack::pt > cfgCutPt) && ncheckbit(aod::track::trackType, as(cfgTrackBitMask)); // MC filters diff --git a/PWGCF/TwoParticleCorrelations/Tasks/corrSparse.cxx b/PWGCF/TwoParticleCorrelations/Tasks/corrSparse.cxx index a1f5bbd4e74..3f66c69da7b 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/corrSparse.cxx +++ b/PWGCF/TwoParticleCorrelations/Tasks/corrSparse.cxx @@ -238,7 +238,7 @@ struct CorrSparse { // make the filters and cuts. Filter collisionFilter = (nabs(aod::collision::posZ) < cfgZVtxCut); - Filter trackFilter = (nabs(aod::track::eta) < cfgTrackCuts.cfgEtaCut) && (cfgTrackCuts.cfgPtCutMin < aod::track::pt) && (cfgTrackCuts.cfgPtCutMax > aod::track::pt) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t)true)) && (aod::track::tpcChi2NCl < cfgTrackCuts.cfgCutChi2prTPCcls) && (aod::track::dcaZ < cfgTrackCuts.cfgCutDCAz); + Filter trackFilter = (nabs(aod::track::eta) < cfgTrackCuts.cfgEtaCut) && (cfgTrackCuts.cfgPtCutMin < aod::track::pt) && (cfgTrackCuts.cfgPtCutMax > aod::track::pt) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true)) && (aod::track::tpcChi2NCl < cfgTrackCuts.cfgCutChi2prTPCcls) && (aod::track::dcaZ < cfgTrackCuts.cfgCutDCAz); Filter mftTrackEtaFilter = ((aod::fwdtrack::eta < cfgMftConfig.etaMftTrackMaxFilter) && (aod::fwdtrack::eta > cfgMftConfig.etaMftTrackMinFilter)); diff --git a/PWGCF/TwoParticleCorrelations/Tasks/diHadronCor.cxx b/PWGCF/TwoParticleCorrelations/Tasks/diHadronCor.cxx index 0bf84ab594a..99de5feb14e 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/diHadronCor.cxx +++ b/PWGCF/TwoParticleCorrelations/Tasks/diHadronCor.cxx @@ -160,7 +160,7 @@ struct DiHadronCor { // make the filters and cuts. Filter collisionFilter = (nabs(aod::collision::posZ) < cfgCutVtxZ); - Filter trackFilter = (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPtMin) && (aod::track::pt < cfgCutPtMax) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t)true)) && (aod::track::tpcChi2NCl < cfgCutChi2prTPCcls) && (nabs(aod::track::dcaZ) < cfgCutDCAz); + Filter trackFilter = (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPtMin) && (aod::track::pt < cfgCutPtMax) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true)) && (aod::track::tpcChi2NCl < cfgCutChi2prTPCcls) && (nabs(aod::track::dcaZ) < cfgCutDCAz); using FilteredCollisions = soa::Filtered>; using FilteredTracks = soa::Filtered>; using FilteredTracksWithMCLabels = soa::Filtered>; diff --git a/PWGCF/TwoParticleCorrelations/Tasks/etaDihadron.cxx b/PWGCF/TwoParticleCorrelations/Tasks/etaDihadron.cxx index 7aaa275a16e..fc26117acc0 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/etaDihadron.cxx +++ b/PWGCF/TwoParticleCorrelations/Tasks/etaDihadron.cxx @@ -159,7 +159,7 @@ struct EtaDihadron { // make the filters and cuts. Filter collisionFilter = (nabs(aod::collision::posZ) < cfgCutVtxZ); - Filter trackFilter = (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPtMin) && (aod::track::pt < cfgCutPtMax) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t)true)) && (aod::track::tpcChi2NCl < cfgCutChi2prTPCcls) && (nabs(aod::track::dcaZ) < cfgCutDCAz); + Filter trackFilter = (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPtMin) && (aod::track::pt < cfgCutPtMax) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true)) && (aod::track::tpcChi2NCl < cfgCutChi2prTPCcls) && (nabs(aod::track::dcaZ) < cfgCutDCAz); using FilteredCollisions = soa::Filtered>; using FilteredTracks = soa::Filtered>; using FilteredTracksWithMCLabels = soa::Filtered>; diff --git a/PWGCF/TwoParticleCorrelations/Tasks/nucleibalance.cxx b/PWGCF/TwoParticleCorrelations/Tasks/nucleibalance.cxx index 611b8a8ca03..dca0592bd91 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/nucleibalance.cxx +++ b/PWGCF/TwoParticleCorrelations/Tasks/nucleibalance.cxx @@ -254,7 +254,7 @@ struct Nucleibalance { Filter collisionVertexTypeFilter = (aod::collision::flags & static_cast(aod::collision::CollisionFlagsRun2::Run2VertexerTracks)) == static_cast(aod::collision::CollisionFlagsRun2::Run2VertexerTracks); // Track filters - Filter trackFilter = (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPt) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t)true)); + Filter trackFilter = (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPt) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true)); Filter cfTrackFilter = (nabs(aod::cftrack::eta) < cfgCutEta) && (aod::cftrack::pt > cfgCutPt) && ((aod::track::trackType & (uint8_t)cfgTrackBitMask) == (uint8_t)cfgTrackBitMask); // MC filters diff --git a/PWGCF/TwoParticleCorrelations/Tasks/pidDiHadron.cxx b/PWGCF/TwoParticleCorrelations/Tasks/pidDiHadron.cxx index 641bb2f8ffb..b3efdcc4480 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/pidDiHadron.cxx +++ b/PWGCF/TwoParticleCorrelations/Tasks/pidDiHadron.cxx @@ -198,7 +198,7 @@ struct PidDiHadron { // make the filters and cuts. Filter collisionFilter = (nabs(aod::collision::posZ) < cfgCutVertex); - Filter trackFilter = (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPtPOIMin) && (aod::track::pt < cfgCutPtPOIMax) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t)true)) && (aod::track::tpcChi2NCl < cfgCutChi2prTPCcls) && (nabs(aod::track::dcaZ) < cfgCutDCAz); + Filter trackFilter = (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPtPOIMin) && (aod::track::pt < cfgCutPtPOIMax) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true)) && (aod::track::tpcChi2NCl < cfgCutChi2prTPCcls) && (nabs(aod::track::dcaZ) < cfgCutDCAz); using FilteredCollisions = soa::Filtered>; using FilteredTracks = soa::Filtered>;