diff --git a/.github/workflows/o2-linter.yml b/.github/workflows/o2-linter.yml index 8e150e970fd..099209da6e6 100644 --- a/.github/workflows/o2-linter.yml +++ b/.github/workflows/o2-linter.yml @@ -2,10 +2,10 @@ # Find issues in O2 code name: O2 linter -'on': [pull_request, push] +"on": [pull_request_target, push] permissions: {} env: - MAIN_BRANCH: master + BRANCH_MAIN: master concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }} @@ -15,20 +15,47 @@ jobs: o2-linter: name: O2 linter runs-on: ubuntu-24.04 + permissions: + pull-requests: write steps: + - name: Set branches + run: | + if [[ "${{ github.event_name }}" == "push" ]]; then + branch_head="${{ github.ref }}" + branch_base="${{ env.BRANCH_MAIN }}" + else + branch_head="refs/pull/${{ github.event.pull_request.number }}/merge" + branch_base="${{ github.event.pull_request.base.ref }}" + fi + echo BRANCH_HEAD="$branch_head" >> "$GITHUB_ENV" + echo BRANCH_BASE="$branch_base" >> "$GITHUB_ENV" - name: Checkout Code uses: actions/checkout@v4 with: + ref: ${{ env.BRANCH_HEAD }} fetch-depth: 0 # needed to get the full history - name: Run tests + id: linter run: | - # Diff against the common ancestor of the source branch and the main branch. - readarray -t files < <(git diff --diff-filter d --name-only origin/${{ env.MAIN_BRANCH }}...) + # Diff against the common ancestor of the source (head) branch and the target (base) branch. + echo "Diffing ${{ env.BRANCH_HEAD }} against ${{ env.BRANCH_BASE }}." + readarray -t files < <(git diff --diff-filter d --name-only origin/${{ env.BRANCH_BASE }}...) if [ ${#files[@]} -eq 0 ]; then echo "::notice::No files to lint." + echo "linter_ran=0" >> "$GITHUB_OUTPUT" exit 0 fi - [ ${{ github.event_name }} == 'pull_request' ] && options="-g" + echo "linter_ran=1" >> "$GITHUB_OUTPUT" + [[ "${{ github.event_name }}" == "pull_request_target" ]] && options="-g" # shellcheck disable=SC2086 # Ignore unquoted options. python3 Scripts/o2_linter.py $options "${files[@]}" echo "Tip: If you allow actions in your fork repository, O2 linter will run when you push commits." + - name: Comment PR + if: (success() || failure()) && (github.event_name == 'pull_request_target' && steps.linter.outputs.linter_ran == 1) + uses: thollander/actions-comment-pull-request@v3 + with: + comment-tag: o2-linter + message: "**O2 linter results:** + ❌ ${{ steps.linter.outputs.n_issues }} errors, + ⚠️ ${{ steps.linter.outputs.n_tolerated }} warnings, + 🔕 ${{ steps.linter.outputs.n_disabled }} disabled" diff --git a/ALICE3/DataModel/OTFTOF.h b/ALICE3/DataModel/OTFTOF.h index 57fd5bb8e8c..10f3de38b19 100644 --- a/ALICE3/DataModel/OTFTOF.h +++ b/ALICE3/DataModel/OTFTOF.h @@ -27,42 +27,81 @@ namespace o2::aod { namespace upgrade_tof { -DECLARE_SOA_COLUMN(NSigmaElectronInnerTOF, nSigmaElectronInnerTOF, float); //! NSigma electron InnerTOF -DECLARE_SOA_COLUMN(NSigmaMuonInnerTOF, nSigmaMuonInnerTOF, float); //! NSigma muon InnerTOF -DECLARE_SOA_COLUMN(NSigmaPionInnerTOF, nSigmaPionInnerTOF, float); //! NSigma pion InnerTOF -DECLARE_SOA_COLUMN(NSigmaKaonInnerTOF, nSigmaKaonInnerTOF, float); //! NSigma kaon InnerTOF -DECLARE_SOA_COLUMN(NSigmaProtonInnerTOF, nSigmaProtonInnerTOF, float); //! NSigma proton InnerTOF -DECLARE_SOA_COLUMN(InnerTOFTrackLength, innerTOFTrackLength, float); //! track length for calculation of InnerTOF -DECLARE_SOA_COLUMN(InnerTOFTrackLengthReco, innerTOFTrackLengthReco, float); //! track length for calculation of InnerTOF -DECLARE_SOA_COLUMN(DeltaTrackLengthInnerTOF, deltaTrackLengthInnerTOF, float); //! track length for calculation of InnerTOF -DECLARE_SOA_COLUMN(NSigmaElectronOuterTOF, nSigmaElectronOuterTOF, float); //! NSigma electron OuterTOF -DECLARE_SOA_COLUMN(NSigmaMuonOuterTOF, nSigmaMuonOuterTOF, float); //! NSigma muon OuterTOF -DECLARE_SOA_COLUMN(NSigmaPionOuterTOF, nSigmaPionOuterTOF, float); //! NSigma pion OuterTOF -DECLARE_SOA_COLUMN(NSigmaKaonOuterTOF, nSigmaKaonOuterTOF, float); //! NSigma kaon OuterTOF -DECLARE_SOA_COLUMN(NSigmaProtonOuterTOF, nSigmaProtonOuterTOF, float); //! NSigma proton OuterTOF -DECLARE_SOA_COLUMN(OuterTOFTrackLength, outerTOFTrackLength, float); //! track length for calculation of OuterTOF -DECLARE_SOA_COLUMN(OuterTOFTrackLengthReco, outerTOFTrackLengthReco, float); //! track length for calculation of OuterTOF -DECLARE_SOA_COLUMN(DeltaTrackLengthOuterTOF, deltaTrackLengthOuterTOF, float); //! track length for calculation of InnerTOF +DECLARE_SOA_COLUMN(InnerTOFTrackTime, innerTOFTrackTime, float); //! Track time generated at the InnerTOF +DECLARE_SOA_COLUMN(InnerTOFTrackLength, innerTOFTrackLength, float); //! track length for calculation of InnerTOF (generated) +DECLARE_SOA_COLUMN(OuterTOFTrackTime, outerTOFTrackTime, float); //! Track time generated at the OuterTOF +DECLARE_SOA_COLUMN(OuterTOFTrackLength, outerTOFTrackLength, float); //! track length for calculation of OuterTOF (generated) + +DECLARE_SOA_COLUMN(TOFEventTime, tofEventTime, float); //! Event time reconstructed with the TOF +DECLARE_SOA_COLUMN(TOFEventTimeErr, tofEventTimeErr, float); //! Uncertainty on the event time reconstructed with the TOF +DECLARE_SOA_COLUMN(NSigmaElectronInnerTOF, nSigmaElectronInnerTOF, float); //! NSigma electron InnerTOF +DECLARE_SOA_COLUMN(NSigmaMuonInnerTOF, nSigmaMuonInnerTOF, float); //! NSigma muon InnerTOF +DECLARE_SOA_COLUMN(NSigmaPionInnerTOF, nSigmaPionInnerTOF, float); //! NSigma pion InnerTOF +DECLARE_SOA_COLUMN(NSigmaKaonInnerTOF, nSigmaKaonInnerTOF, float); //! NSigma kaon InnerTOF +DECLARE_SOA_COLUMN(NSigmaProtonInnerTOF, nSigmaProtonInnerTOF, float); //! NSigma proton InnerTOF +DECLARE_SOA_COLUMN(InnerTOFTrackTimeReco, innerTOFTrackTimeReco, float); //! Track time measured at the InnerTOF +DECLARE_SOA_COLUMN(InnerTOFTrackLengthReco, innerTOFTrackLengthReco, float); //! track length for calculation of InnerTOF (reconstructed) + +DECLARE_SOA_COLUMN(InnerTOFExpectedTimeEl, innerTOFExpectedTimeEl, float); //! Reconstructed expected time at the InnerTOF for the Electron mass hypotheses +DECLARE_SOA_COLUMN(InnerTOFExpectedTimeMu, innerTOFExpectedTimeMu, float); //! Reconstructed expected time at the InnerTOF for the Muon mass hypotheses +DECLARE_SOA_COLUMN(InnerTOFExpectedTimePi, innerTOFExpectedTimePi, float); //! Reconstructed expected time at the InnerTOF for the Pion mass hypotheses +DECLARE_SOA_COLUMN(InnerTOFExpectedTimeKa, innerTOFExpectedTimeKa, float); //! Reconstructed expected time at the InnerTOF for the Kaon mass hypotheses +DECLARE_SOA_COLUMN(InnerTOFExpectedTimePr, innerTOFExpectedTimePr, float); //! Reconstructed expected time at the InnerTOF for the Proton mass hypotheses + +DECLARE_SOA_COLUMN(NSigmaElectronOuterTOF, nSigmaElectronOuterTOF, float); //! NSigma electron OuterTOF +DECLARE_SOA_COLUMN(NSigmaMuonOuterTOF, nSigmaMuonOuterTOF, float); //! NSigma muon OuterTOF +DECLARE_SOA_COLUMN(NSigmaPionOuterTOF, nSigmaPionOuterTOF, float); //! NSigma pion OuterTOF +DECLARE_SOA_COLUMN(NSigmaKaonOuterTOF, nSigmaKaonOuterTOF, float); //! NSigma kaon OuterTOF +DECLARE_SOA_COLUMN(NSigmaProtonOuterTOF, nSigmaProtonOuterTOF, float); //! NSigma proton OuterTOF +DECLARE_SOA_COLUMN(OuterTOFTrackTimeReco, outerTOFTrackTimeReco, float); //! Track time measured at the OuterTOF +DECLARE_SOA_COLUMN(OuterTOFTrackLengthReco, outerTOFTrackLengthReco, float); //! track length for calculation of OuterTOF (reconstructed) + +DECLARE_SOA_COLUMN(OuterTOFExpectedTimeEl, outerTOFExpectedTimeEl, float); //! Reconstructed expected time at the OuterTOF for the Electron mass hypotheses +DECLARE_SOA_COLUMN(OuterTOFExpectedTimeMu, outerTOFExpectedTimeMu, float); //! Reconstructed expected time at the OuterTOF for the Muon mass hypotheses +DECLARE_SOA_COLUMN(OuterTOFExpectedTimePi, outerTOFExpectedTimePi, float); //! Reconstructed expected time at the OuterTOF for the Pion mass hypotheses +DECLARE_SOA_COLUMN(OuterTOFExpectedTimeKa, outerTOFExpectedTimeKa, float); //! Reconstructed expected time at the OuterTOF for the Kaon mass hypotheses +DECLARE_SOA_COLUMN(OuterTOFExpectedTimePr, outerTOFExpectedTimePr, float); //! Reconstructed expected time at the OuterTOF for the Proton mass hypotheses } // namespace upgrade_tof + +DECLARE_SOA_TABLE(UpgradeTofMCs, "AOD", "UPGRADETOFMC", + upgrade_tof::InnerTOFTrackTime, + upgrade_tof::InnerTOFTrackLength, + upgrade_tof::OuterTOFTrackTime, + upgrade_tof::OuterTOFTrackLength); + DECLARE_SOA_TABLE(UpgradeTofs, "AOD", "UPGRADETOF", + upgrade_tof::TOFEventTime, + upgrade_tof::TOFEventTimeErr, upgrade_tof::NSigmaElectronInnerTOF, upgrade_tof::NSigmaMuonInnerTOF, upgrade_tof::NSigmaPionInnerTOF, upgrade_tof::NSigmaKaonInnerTOF, upgrade_tof::NSigmaProtonInnerTOF, - upgrade_tof::InnerTOFTrackLength, + upgrade_tof::InnerTOFTrackTimeReco, upgrade_tof::InnerTOFTrackLengthReco, - upgrade_tof::DeltaTrackLengthInnerTOF, upgrade_tof::NSigmaElectronOuterTOF, upgrade_tof::NSigmaMuonOuterTOF, upgrade_tof::NSigmaPionOuterTOF, upgrade_tof::NSigmaKaonOuterTOF, upgrade_tof::NSigmaProtonOuterTOF, - upgrade_tof::OuterTOFTrackLength, - upgrade_tof::OuterTOFTrackLengthReco, - upgrade_tof::DeltaTrackLengthOuterTOF); + upgrade_tof::OuterTOFTrackTimeReco, + upgrade_tof::OuterTOFTrackLengthReco); + +DECLARE_SOA_TABLE(UpgradeTofExpectedTimes, "AOD", "UPGRADETOFEXPT", + upgrade_tof::InnerTOFExpectedTimeEl, + upgrade_tof::InnerTOFExpectedTimeMu, + upgrade_tof::InnerTOFExpectedTimePi, + upgrade_tof::InnerTOFExpectedTimeKa, + upgrade_tof::InnerTOFExpectedTimePr, + upgrade_tof::OuterTOFExpectedTimeEl, + upgrade_tof::OuterTOFExpectedTimeMu, + upgrade_tof::OuterTOFExpectedTimePi, + upgrade_tof::OuterTOFExpectedTimeKa, + upgrade_tof::OuterTOFExpectedTimePr); +using UpgradeTofMC = UpgradeTofMCs::iterator; using UpgradeTof = UpgradeTofs::iterator; +using UpgradeTofExpectedTime = UpgradeTofExpectedTimes::iterator; } // namespace o2::aod diff --git a/ALICE3/TableProducer/OTF/CMakeLists.txt b/ALICE3/TableProducer/OTF/CMakeLists.txt index d20b6c6ba5c..b7d40692770 100644 --- a/ALICE3/TableProducer/OTF/CMakeLists.txt +++ b/ALICE3/TableProducer/OTF/CMakeLists.txt @@ -15,7 +15,7 @@ o2physics_add_dpl_workflow(onthefly-tracker COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(onthefly-tofpid - SOURCES onTheFlyTOFPID.cxx + SOURCES onTheFlyTofPid.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2::DetectorsBase O2Physics::AnalysisCore O2::ReconstructionDataFormats O2::DetectorsCommonDataFormats O2Physics::ALICE3Core COMPONENT_NAME Analysis) diff --git a/ALICE3/TableProducer/OTF/onTheFlyRICHPID.cxx b/ALICE3/TableProducer/OTF/onTheFlyRICHPID.cxx index af6024f3afd..42a0fbbc277 100644 --- a/ALICE3/TableProducer/OTF/onTheFlyRICHPID.cxx +++ b/ALICE3/TableProducer/OTF/onTheFlyRICHPID.cxx @@ -60,11 +60,13 @@ /// Since angular resolution depends on the specific geometric details, it is better to /// calculate it from full simulation and add new input. Alternatively, an analytical /// expression can be provided as a function of the main parameters. +/// Latest version: analytical parametrization of angular resolution !!! /// /// \author David Dobrigkeit Chinellato, UNICAMP, Nicola Nicassio, University and INFN Bari using namespace o2; using namespace o2::framework; +using namespace o2::constants::math; struct OnTheFlyRichPid { Produces upgradeRich; @@ -96,6 +98,50 @@ struct OnTheFlyRichPid { Configurable flagIncludeTrackAngularRes{"flagIncludeTrackAngularRes", true, "flag to include or exclude track time resolution"}; Configurable multiplicityEtaRange{"multiplicityEtaRange", 0.800000012, "eta range to compute the multiplicity"}; Configurable flagRICHLoadDelphesLUTs{"flagRICHLoadDelphesLUTs", false, "flag to load Delphes LUTs for tracking correction (use recoTrack parameters if false)"}; + /*Configurable bRichRefractiveIndexSector0AndNMinus1{"bRichRefractiveIndexSector0AndMinus1", 1.03, "barrel RICH refractive index sector 0 and N-1"}; + Configurable bRichRefractiveIndexSector1AndNMinus2{"bRichRefractiveIndexSector1AndMinus2", 1.03, "barrel RICH refractive index sector 1 and N-2"}; + Configurable bRichRefractiveIndexSector2AndNMinus3{"bRichRefractiveIndexSector2AndMinus3", 1.03, "barrel RICH refractive index sector 2 and N-3"}; + Configurable bRichRefractiveIndexSector3AndNMinus4{"bRichRefractiveIndexSector3AndMinus4", 1.03, "barrel RICH refractive index sector 3 and N-4"}; + Configurable bRichRefractiveIndexSector4AndNMinus5{"bRichRefractiveIndexSector4AndMinus5", 1.03, "barrel RICH refractive index sector 4 and N-5"}; + Configurable bRichRefractiveIndexSector5AndNMinus6{"bRichRefractiveIndexSector5AndMinus6", 1.03, "barrel RICH refractive index sector 5 and N-6"}; + Configurable bRichRefractiveIndexSector6AndNMinus7{"bRichRefractiveIndexSector6AndMinus7", 1.03, "barrel RICH refractive index sector 6 and N-7"}; + Configurable bRichRefractiveIndexSector7AndNMinus8{"bRichRefractiveIndexSector7AndMinus8", 1.03, "barrel RICH refractive index sector 7 and N-8"}; + Configurable bRichRefractiveIndexSector8AndNMinus9{"bRichRefractiveIndexSector8AndMinus9", 1.03, "barrel RICH refractive index sector 8 and N-9"}; + Configurable bRichRefractiveIndexSector9AndNMinus10{"bRichRefractiveIndexSector9AndMinus10", 1.03, "barrel RICH refractive index sector 9 and N-10"}; + Configurable bRichRefractiveIndexSector10AndNMinus11{"bRichRefractiveIndexSector10AndMinus11", 1.03, "barrel RICH refractive index sector 10 and N-11"}; + Configurable bRichRefractiveIndexSector11AndNMinus12{"bRichRefractiveIndexSector11AndMinus12", 1.03, "barrel RICH refractive index sector 11 and N-12"}; + Configurable bRichRefractiveIndexSector12AndNMinus13{"bRichRefractiveIndexSector12AndMinus13", 1.03, "barrel RICH refractive index sector 12 and N-13"}; + Configurable bRichRefractiveIndexSector13AndNMinus14{"bRichRefractiveIndexSector13AndMinus14", 1.03, "barrel RICH refractive index sector 13 and N-14"}; + Configurable bRichRefractiveIndexSector14AndNMinus15{"bRichRefractiveIndexSector14AndMinus15", 1.03, "barrel RICH refractive index sector 14 and N-15"}; + Configurable bRichRefractiveIndexSector15AndNMinus16{"bRichRefractiveIndexSector15AndMinus16", 1.03, "barrel RICH refractive index sector 15 and N-16"}; + Configurable bRichRefractiveIndexSector16AndNMinus17{"bRichRefractiveIndexSector16AndMinus17", 1.03, "barrel RICH refractive index sector 16 and N-17"}; + Configurable bRichRefractiveIndexSector17AndNMinus18{"bRichRefractiveIndexSector17AndMinus18", 1.03, "barrel RICH refractive index sector 17 and N-18"}; + Configurable bRichRefractiveIndexSector18AndNMinus19{"bRichRefractiveIndexSector18AndMinus19", 1.03, "barrel RICH refractive index sector 18 and N-19"}; + Configurable bRichRefractiveIndexSector19AndNMinus20{"bRichRefractiveIndexSector19AndMinus20", 1.03, "barrel RICH refractive index sector 19 and N-20"}; + Configurable bRichRefractiveIndexSector20AndNMinus21{"bRichRefractiveIndexSector20AndMinus21", 1.03, "barrel RICH refractive index sector 20 and N-21"};*/ + Configurable bRichRefractiveIndexSector0{"bRichRefractiveIndexSector0", 1.03, "barrel RICH refractive index central(s)"}; // central(s) + Configurable bRichRefractiveIndexSector1{"bRichRefractiveIndexSector1", 1.03, "barrel RICH refractive index central(s)-1 and central(s)+1"}; // central(s)-1 and central(s)+1 + Configurable bRichRefractiveIndexSector2{"bRichRefractiveIndexSector2", 1.03, "barrel RICH refractive index central(s)-2 and central(s)+2"}; // central(s)-2 and central(s)+2 + Configurable bRichRefractiveIndexSector3{"bRichRefractiveIndexSector3", 1.03, "barrel RICH refractive index central(s)-3 and central(s)+3"}; // central(s)-3 and central(s)+3 + Configurable bRichRefractiveIndexSector4{"bRichRefractiveIndexSector4", 1.03, "barrel RICH refractive index central(s)-4 and central(s)+4"}; // central(s)-4 and central(s)+4 + Configurable bRichRefractiveIndexSector5{"bRichRefractiveIndexSector5", 1.03, "barrel RICH refractive index central(s)-5 and central(s)+5"}; // central(s)-5 and central(s)+5 + Configurable bRichRefractiveIndexSector6{"bRichRefractiveIndexSector6", 1.03, "barrel RICH refractive index central(s)-6 and central(s)+6"}; // central(s)-6 and central(s)+6 + Configurable bRichRefractiveIndexSector7{"bRichRefractiveIndexSector7", 1.03, "barrel RICH refractive index central(s)-7 and central(s)+7"}; // central(s)-7 and central(s)+7 + Configurable bRichRefractiveIndexSector8{"bRichRefractiveIndexSector8", 1.03, "barrel RICH refractive index central(s)-8 and central(s)+8"}; // central(s)-8 and central(s)+8 + Configurable bRichRefractiveIndexSector9{"bRichRefractiveIndexSector9", 1.03, "barrel RICH refractive index central(s)-9 and central(s)+9"}; // central(s)-9 and central(s)+9 + Configurable bRichRefractiveIndexSector10{"bRichRefractiveIndexSector10", 1.03, "barrel RICH refractive index central(s)-10 and central(s)+10"}; // central(s)-10 and central(s)+10 + Configurable bRichRefractiveIndexSector11{"bRichRefractiveIndexSector11", 1.03, "barrel RICH refractive index central(s)-11 and central(s)+11"}; // central(s)-11 and central(s)+11 + Configurable bRichRefractiveIndexSector12{"bRichRefractiveIndexSector12", 1.03, "barrel RICH refractive index central(s)-12 and central(s)+12"}; // central(s)-12 and central(s)+12 + Configurable bRichRefractiveIndexSector13{"bRichRefractiveIndexSector13", 1.03, "barrel RICH refractive index central(s)-13 and central(s)+13"}; // central(s)-13 and central(s)+13 + Configurable bRichRefractiveIndexSector14{"bRichRefractiveIndexSector14", 1.03, "barrel RICH refractive index central(s)-14 and central(s)+14"}; // central(s)-14 and central(s)+14 + Configurable bRichRefractiveIndexSector15{"bRichRefractiveIndexSector15", 1.03, "barrel RICH refractive index central(s)-15 and central(s)+15"}; // central(s)-15 and central(s)+15 + Configurable bRichRefractiveIndexSector16{"bRichRefractiveIndexSector16", 1.03, "barrel RICH refractive index central(s)-16 and central(s)+16"}; // central(s)-16 and central(s)+16 + Configurable bRichRefractiveIndexSector17{"bRichRefractiveIndexSector17", 1.03, "barrel RICH refractive index central(s)-17 and central(s)+17"}; // central(s)-17 and central(s)+17 + Configurable bRichRefractiveIndexSector18{"bRichRefractiveIndexSector18", 1.03, "barrel RICH refractive index central(s)-18 and central(s)+18"}; // central(s)-18 and central(s)+18 + Configurable bRichRefractiveIndexSector19{"bRichRefractiveIndexSector19", 1.03, "barrel RICH refractive index central(s)-19 and central(s)+19"}; // central(s)-19 and central(s)+19 + Configurable bRichRefractiveIndexSector20{"bRichRefractiveIndexSector20", 1.03, "barrel RICH refractive index central(s)-20 and central(s)+20"}; // central(s)-20 and central(s)+20 + Configurable bRICHPixelSize{"bRICHPixelSize", 0.1, "barrel RICH pixel size (cm)"}; + Configurable bRichGapRefractiveIndex{"bRichGapRefractiveIndex", 1.000283, "barrel RICH gap refractive index"}; Configurable lutEl{"lutEl", "lutCovm.el.dat", "LUT for electrons"}; Configurable lutMu{"lutMu", "lutCovm.mu.dat", "LUT for muons"}; @@ -114,7 +160,7 @@ struct OnTheFlyRichPid { // for handling basic QA histograms if requested HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; - /// Flag unphysical and unavailable values + /// Flag unphysical and unavailable values (must be negative) float error_value = -1000; // Variables projective/hybrid layout @@ -129,16 +175,29 @@ struct OnTheFlyRichPid { std::vector angle_centers; std::vector theta_min; std::vector theta_max; + std::vector bRichRefractiveIndexSector; + std::vector aerogel_rindex; + std::vector photodetrctor_length; + std::vector gap_thickness; // Update projective geometry void updateProjectiveParameters() { + mNumberSectors = bRichNumberOfSectors; + mTileLength = bRichPhotodetectorOtherModuleLength; + mTileLengthCentral = bRichPhotodetectorCentralModuleHalfLength; + mProjectiveLengthInner = mTileLengthCentral; + mRadiusProjIn = bRichRadiatorInnerRadius; + mRadiusProjOut = bRichPhotodetectorOuterRadius; const int number_of_sectors_in_z = mNumberSectors; det_centers.resize(number_of_sectors_in_z); rad_centers.resize(number_of_sectors_in_z); angle_centers.resize(number_of_sectors_in_z); theta_min.resize(number_of_sectors_in_z); theta_max.resize(number_of_sectors_in_z); + aerogel_rindex.resize(number_of_sectors_in_z); + photodetrctor_length.resize(number_of_sectors_in_z); + gap_thickness.resize(number_of_sectors_in_z); float square_size_barrel_cylinder = 2.0 * mTileLengthCentral; float square_size_z = mTileLength; float R_min = mRadiusProjIn; @@ -156,43 +215,83 @@ struct OnTheFlyRichPid { l_aerogel_z.resize(number_of_sectors_in_z); l_detector_z.resize(number_of_sectors_in_z); - // Central sector - int i_central_mirror = static_cast((number_of_sectors_in_z) / 2.0); - float m_val = std::tan(0.0); - theta_bi[i_central_mirror] = std::atan(m_val); - R0_tilt[i_central_mirror] = R_max; - z0_tilt[i_central_mirror] = R0_tilt[i_central_mirror] * std::tan(theta_bi[i_central_mirror]); - l_detector_z[i_central_mirror] = square_size_barrel_cylinder; - l_aerogel_z[i_central_mirror] = std::sqrt(1.0 + m_val * m_val) * R_min * square_size_barrel_cylinder / (std::sqrt(1.0 + m_val * m_val) * R_max - m_val * square_size_barrel_cylinder); - T_r_plus_g[i_central_mirror] = R_max - R_min; - float t = std::tan(atan(m_val) + std::atan(square_size_barrel_cylinder / (2.0 * R_max * std::sqrt(1.0 + m_val * m_val) - square_size_barrel_cylinder * m_val))); - theta_max[i_central_mirror] = M_PI / 2.0 - std::atan(t); - theta_min[i_central_mirror] = M_PI / 2.0 + std::atan(t); - mProjectiveLengthInner = R_min * t; - for (int i = static_cast((number_of_sectors_in_z) / 2.0) + 1; i < number_of_sectors_in_z; i++) { - float par_a = t; - float par_b = 2.0 * R_max / square_size_z; - m_val = (std::sqrt(par_a * par_a * par_b * par_b + par_b * par_b - 1.0) + par_a * par_b * par_b) / (par_b * par_b - 1.0); - theta_min[i] = M_PI / 2.0 - std::atan(t); - theta_max[2 * i_central_mirror - i] = M_PI / 2.0 + std::atan(t); - t = std::tan(std::atan(m_val) + std::atan(square_size_z / (2.0 * R_max * std::sqrt(1.0 + m_val * m_val) - square_size_z * m_val))); - theta_max[i] = M_PI / 2.0 - std::atan(t); - theta_min[2 * i_central_mirror - i] = M_PI / 2.0 + std::atan(t); - // Forward sectors - theta_bi[i] = std::atan(m_val); - R0_tilt[i] = R_max - square_size_z / 2.0 * std::sin(std::atan(m_val)); - z0_tilt[i] = R0_tilt[i] * std::tan(theta_bi[i]); - l_detector_z[i] = square_size_z; - l_aerogel_z[i] = std::sqrt(1.0 + m_val * m_val) * R_min * square_size_z / (std::sqrt(1.0 + m_val * m_val) * R_max - m_val * square_size_z); - T_r_plus_g[i] = std::sqrt(1.0 + m_val * m_val) * (R_max - R_min) - m_val / 2.0 * (square_size_z + l_aerogel_z[i]); - // Backword sectors - theta_bi[2 * i_central_mirror - i] = -std::atan(m_val); - R0_tilt[2 * i_central_mirror - i] = R_max - square_size_z / 2.0 * std::sin(std::atan(m_val)); - z0_tilt[2 * i_central_mirror - i] = -R0_tilt[i] * std::tan(theta_bi[i]); - l_detector_z[2 * i_central_mirror - i] = square_size_z; - l_aerogel_z[2 * i_central_mirror - i] = std::sqrt(1.0 + m_val * m_val) * R_min * square_size_z / (std::sqrt(1.0 + m_val * m_val) * R_max - m_val * square_size_z); - T_r_plus_g[2 * i_central_mirror - i] = std::sqrt(1.0 + m_val * m_val) * (R_max - R_min) - m_val / 2.0 * (square_size_z + l_aerogel_z[i]); - mProjectiveLengthInner = R_min * t; // <-- At the end of the loop this will be the maximum Z + // Odd number of sectors + if (number_of_sectors_in_z % 2 != 0) { + int i_central_mirror = static_cast((number_of_sectors_in_z) / 2.0); + float m_val = std::tan(0.0); + theta_bi[i_central_mirror] = std::atan(m_val); + R0_tilt[i_central_mirror] = R_max; + z0_tilt[i_central_mirror] = R0_tilt[i_central_mirror] * std::tan(theta_bi[i_central_mirror]); + l_detector_z[i_central_mirror] = square_size_barrel_cylinder; + l_aerogel_z[i_central_mirror] = std::sqrt(1.0 + m_val * m_val) * R_min * square_size_barrel_cylinder / (std::sqrt(1.0 + m_val * m_val) * R_max - m_val * square_size_barrel_cylinder); + T_r_plus_g[i_central_mirror] = R_max - R_min; + float t = std::tan(std::atan(m_val) + std::atan(square_size_barrel_cylinder / (2.0 * R_max * std::sqrt(1.0 + m_val * m_val) - square_size_barrel_cylinder * m_val))); + theta_max[i_central_mirror] = M_PI / 2.0 - std::atan(t); + theta_min[i_central_mirror] = M_PI / 2.0 + std::atan(t); + mProjectiveLengthInner = R_min * t; + aerogel_rindex[i_central_mirror] = bRichRefractiveIndexSector[0]; + for (int i = i_central_mirror + 1; i < number_of_sectors_in_z; i++) { + float par_a = t; + float par_b = 2.0 * R_max / square_size_z; + m_val = (std::sqrt(par_a * par_a * par_b * par_b + par_b * par_b - 1.0) + par_a * par_b * par_b) / (par_b * par_b - 1.0); + theta_min[i] = M_PI / 2.0 - std::atan(t); + theta_max[2 * i_central_mirror - i] = M_PI / 2.0 + std::atan(t); + t = std::tan(std::atan(m_val) + std::atan(square_size_z / (2.0 * R_max * std::sqrt(1.0 + m_val * m_val) - square_size_z * m_val))); + theta_max[i] = M_PI / 2.0 - std::atan(t); + theta_min[2 * i_central_mirror - i] = M_PI / 2.0 + std::atan(t); + // Forward sectors + theta_bi[i] = std::atan(m_val); + R0_tilt[i] = R_max - square_size_z / 2.0 * std::sin(std::atan(m_val)); + z0_tilt[i] = R0_tilt[i] * std::tan(theta_bi[i]); + l_detector_z[i] = square_size_z; + l_aerogel_z[i] = std::sqrt(1.0 + m_val * m_val) * R_min * square_size_z / (std::sqrt(1.0 + m_val * m_val) * R_max - m_val * square_size_z); + T_r_plus_g[i] = std::sqrt(1.0 + m_val * m_val) * (R_max - R_min) - m_val / 2.0 * (square_size_z + l_aerogel_z[i]); + aerogel_rindex[i] = bRichRefractiveIndexSector[i - i_central_mirror]; + // Backword sectors + theta_bi[2 * i_central_mirror - i] = -std::atan(m_val); + R0_tilt[2 * i_central_mirror - i] = R_max - square_size_z / 2.0 * std::sin(std::atan(m_val)); + z0_tilt[2 * i_central_mirror - i] = -R0_tilt[i] * std::tan(theta_bi[i]); + l_detector_z[2 * i_central_mirror - i] = square_size_z; + l_aerogel_z[2 * i_central_mirror - i] = std::sqrt(1.0 + m_val * m_val) * R_min * square_size_z / (std::sqrt(1.0 + m_val * m_val) * R_max - m_val * square_size_z); + T_r_plus_g[2 * i_central_mirror - i] = std::sqrt(1.0 + m_val * m_val) * (R_max - R_min) - m_val / 2.0 * (square_size_z + l_aerogel_z[i]); + aerogel_rindex[2 * i_central_mirror - i] = bRichRefractiveIndexSector[i - i_central_mirror]; + mProjectiveLengthInner = R_min * t; // <-- At the end of the loop this will be the maximum Z + } + } + // Even number of sectors + else { + float two_half_gap = 1.0; + int i_central_mirror = static_cast((number_of_sectors_in_z) / 2.0); + float m_val = std::tan(0.0); + float t = std::tan(std::atan(m_val) + std::atan(two_half_gap / (2.0 * R_max * std::sqrt(1.0 + m_val * m_val) - two_half_gap * m_val))); + mProjectiveLengthInner = R_min * t; + for (int i = i_central_mirror; i < number_of_sectors_in_z; i++) { + float par_a = t; + float par_b = 2.0 * R_max / square_size_z; + m_val = (std::sqrt(par_a * par_a * par_b * par_b + par_b * par_b - 1.0) + par_a * par_b * par_b) / (par_b * par_b - 1.0); + theta_min[i] = M_PI / 2.0 - std::atan(t); + theta_max[2 * i_central_mirror - i - 1] = M_PI / 2.0 + std::atan(t); + t = std::tan(std::atan(m_val) + std::atan(square_size_z / (2.0 * R_max * std::sqrt(1.0 + m_val * m_val) - square_size_z * m_val))); + theta_max[i] = M_PI / 2.0 - std::atan(t); + theta_min[2 * i_central_mirror - i - 1] = M_PI / 2.0 + std::atan(t); + // Forward sectors + theta_bi[i] = std::atan(m_val); + R0_tilt[i] = R_max - square_size_z / 2.0 * std::sin(std::atan(m_val)); + z0_tilt[i] = R0_tilt[i] * std::tan(theta_bi[i]); + l_detector_z[i] = square_size_z; + l_aerogel_z[i] = std::sqrt(1.0 + m_val * m_val) * R_min * square_size_z / (std::sqrt(1.0 + m_val * m_val) * R_max - m_val * square_size_z); + T_r_plus_g[i] = std::sqrt(1.0 + m_val * m_val) * (R_max - R_min) - m_val / 2.0 * (square_size_z + l_aerogel_z[i]); + aerogel_rindex[i] = bRichRefractiveIndexSector[i - i_central_mirror]; + // Backword sectors + theta_bi[2 * i_central_mirror - i - 1] = -std::atan(m_val); + R0_tilt[2 * i_central_mirror - i - 1] = R_max - square_size_z / 2.0 * std::sin(std::atan(m_val)); + z0_tilt[2 * i_central_mirror - i - 1] = -R0_tilt[i] * std::tan(theta_bi[i]); + l_detector_z[2 * i_central_mirror - i - 1] = square_size_z; + l_aerogel_z[2 * i_central_mirror - i - 1] = std::sqrt(1.0 + m_val * m_val) * R_min * square_size_z / (std::sqrt(1.0 + m_val * m_val) * R_max - m_val * square_size_z); + T_r_plus_g[2 * i_central_mirror - i - 1] = std::sqrt(1.0 + m_val * m_val) * (R_max - R_min) - m_val / 2.0 * (square_size_z + l_aerogel_z[i]); + aerogel_rindex[2 * i_central_mirror - i - 1] = bRichRefractiveIndexSector[i - i_central_mirror]; + mProjectiveLengthInner = R_min * t; // <-- At the end of the loop this will be the maximum Z + } } // Coordinate radiali layer considerati std::vector R0_detector; @@ -200,15 +299,23 @@ struct OnTheFlyRichPid { R0_detector.resize(number_of_sectors_in_z); R0_aerogel.resize(number_of_sectors_in_z); for (int i = 0; i < number_of_sectors_in_z; i++) { - R0_detector[i] = R0_tilt[i]; + R0_detector[i] = R0_tilt[i]; // + (detector_thickness / 2.0) * std::cos(theta_bi[i]) NEGLIGIBLE det_centers[i].SetXYZ(R0_detector[i], 0, R0_detector[i] * std::tan(theta_bi[i])); - R0_aerogel[i] = R0_tilt[i] - (T_r_plus_g[i]) * std::cos(theta_bi[i]); + R0_aerogel[i] = R0_tilt[i] - (T_r_plus_g[i] - bRichRadiatorThickness / 2.0) * std::cos(theta_bi[i]); rad_centers[i].SetXYZ(R0_aerogel[i], 0, R0_aerogel[i] * std::tan(theta_bi[i])); angle_centers[i] = theta_bi[i]; + photodetrctor_length[i] = l_detector_z[i]; + gap_thickness[i] = (det_centers[i] - rad_centers[i]).Mag() - bRichRadiatorThickness / 2.0; } + // DEBUG + // std::cout << std::endl << std::endl; + // for (int i = 0; i < number_of_sectors_in_z; i++) { + // std::cout << "Sector " << i << ": Gap = " << gap_thickness[i] << " cm, Index aerogel = " << aerogel_rindex[i] << ", Gap thickness = " << gap_thickness[i] << " cm" << std::endl; + // } + // std::cout << std::endl << std::endl; } - void init(o2::framework::InitContext&) + void init(o2::framework::InitContext& /*initContext*/) { pRandomNumberGenerator.SetSeed(0); // fully randomize @@ -243,7 +350,14 @@ struct OnTheFlyRichPid { if (doQAplots) { const AxisSpec axisMomentum{static_cast(nBinsP), 0.0f, +20.0f, "#it{p} (GeV/#it{c})"}; const AxisSpec axisAngle{static_cast(nBinsThetaRing), 0.0f, +0.30f, "Measured Cherenkov angle (rad)"}; + const AxisSpec axisEta{static_cast(nBinsEta), -2.0f, +2.0f, "#eta"}; + const AxisSpec axisSector{static_cast(bRichNumberOfSectors), -0.5f, static_cast(bRichNumberOfSectors) - 0.5f, "Sector ID number"}; + const AxisSpec axisRingAngularResolution{static_cast(nBinsAngularRes), 0.0f, +5.0f, "Ring angular resolution - rec. only (mrad)"}; histos.add("h2dAngleVsMomentumBarrelRICH", "h2dAngleVsMomentumBarrelRICH", kTH2F, {axisMomentum, axisAngle}); + histos.add("h2dAngleVsEtaBarrelRICH", "h2dAngleVsEtaBarrelRICH", kTH2F, {axisEta, axisAngle}); + histos.add("h2dAngularResolutionVsMomentumBarrelRICH", "h2dAngularResolutionVsMomentumBarrelRICH", kTH2F, {axisMomentum, axisRingAngularResolution}); + histos.add("h2dAngularResolutionVsEtaBarrelRICH", "h2dAngularResolutionVsEtaBarrelRICH", kTH2F, {axisEta, axisRingAngularResolution}); + histos.add("hSectorID", "hSectorID", kTH1F, {axisSector}); std::string particle_names1[5] = {"#it{e}", "#it{#mu}", "#it{#pi}", "#it{K}", "#it{p}"}; std::string particle_names2[5] = {"Elec", "Muon", "Pion", "Kaon", "Prot"}; @@ -268,6 +382,49 @@ struct OnTheFlyRichPid { } } } + // Load all sector refractive indices + /*bRichRefractiveIndexSector.push_back(bRichRefractiveIndexSector0AndNMinus1); + bRichRefractiveIndexSector.push_back(bRichRefractiveIndexSector1AndNMinus2); + bRichRefractiveIndexSector.push_back(bRichRefractiveIndexSector2AndNMinus3); + bRichRefractiveIndexSector.push_back(bRichRefractiveIndexSector3AndNMinus4); + bRichRefractiveIndexSector.push_back(bRichRefractiveIndexSector4AndNMinus5); + bRichRefractiveIndexSector.push_back(bRichRefractiveIndexSector5AndNMinus6); + bRichRefractiveIndexSector.push_back(bRichRefractiveIndexSector6AndNMinus7); + bRichRefractiveIndexSector.push_back(bRichRefractiveIndexSector7AndNMinus8); + bRichRefractiveIndexSector.push_back(bRichRefractiveIndexSector8AndNMinus9); + bRichRefractiveIndexSector.push_back(bRichRefractiveIndexSector9AndNMinus10); + bRichRefractiveIndexSector.push_back(bRichRefractiveIndexSector10AndNMinus11); + bRichRefractiveIndexSector.push_back(bRichRefractiveIndexSector11AndNMinus12); + bRichRefractiveIndexSector.push_back(bRichRefractiveIndexSector12AndNMinus13); + bRichRefractiveIndexSector.push_back(bRichRefractiveIndexSector13AndNMinus14); + bRichRefractiveIndexSector.push_back(bRichRefractiveIndexSector14AndNMinus15); + bRichRefractiveIndexSector.push_back(bRichRefractiveIndexSector15AndNMinus16); + bRichRefractiveIndexSector.push_back(bRichRefractiveIndexSector16AndNMinus17); + bRichRefractiveIndexSector.push_back(bRichRefractiveIndexSector17AndNMinus18); + bRichRefractiveIndexSector.push_back(bRichRefractiveIndexSector18AndNMinus19); + bRichRefractiveIndexSector.push_back(bRichRefractiveIndexSector19AndNMinus20); + bRichRefractiveIndexSector.push_back(bRichRefractiveIndexSector20AndNMinus21);*/ + bRichRefractiveIndexSector.push_back(bRichRefractiveIndexSector0); + bRichRefractiveIndexSector.push_back(bRichRefractiveIndexSector1); + bRichRefractiveIndexSector.push_back(bRichRefractiveIndexSector2); + bRichRefractiveIndexSector.push_back(bRichRefractiveIndexSector3); + bRichRefractiveIndexSector.push_back(bRichRefractiveIndexSector4); + bRichRefractiveIndexSector.push_back(bRichRefractiveIndexSector5); + bRichRefractiveIndexSector.push_back(bRichRefractiveIndexSector6); + bRichRefractiveIndexSector.push_back(bRichRefractiveIndexSector7); + bRichRefractiveIndexSector.push_back(bRichRefractiveIndexSector8); + bRichRefractiveIndexSector.push_back(bRichRefractiveIndexSector9); + bRichRefractiveIndexSector.push_back(bRichRefractiveIndexSector10); + bRichRefractiveIndexSector.push_back(bRichRefractiveIndexSector11); + bRichRefractiveIndexSector.push_back(bRichRefractiveIndexSector12); + bRichRefractiveIndexSector.push_back(bRichRefractiveIndexSector13); + bRichRefractiveIndexSector.push_back(bRichRefractiveIndexSector14); + bRichRefractiveIndexSector.push_back(bRichRefractiveIndexSector15); + bRichRefractiveIndexSector.push_back(bRichRefractiveIndexSector16); + bRichRefractiveIndexSector.push_back(bRichRefractiveIndexSector17); + bRichRefractiveIndexSector.push_back(bRichRefractiveIndexSector18); + bRichRefractiveIndexSector.push_back(bRichRefractiveIndexSector19); + bRichRefractiveIndexSector.push_back(bRichRefractiveIndexSector20); // Update projective parameters updateProjectiveParameters(); @@ -322,20 +479,26 @@ struct OnTheFlyRichPid { } } - /// returns radiator radius in cm at considered eta (accounting for sector inclination) + /// returns sector hit by the track (if any), -1 otherwise /// \param eta the pseudorapidity of the tarck (assuming primary vertex at origin) - float radiusRipple(float eta) + int findSector(float eta) { float polar = 2.0 * std::atan(std::exp(-eta)); - float i_sector = 0; - bool flag_sector = false; for (int j_sec = 0; j_sec < mNumberSectors; j_sec++) { if (polar > theta_max[j_sec] && polar < theta_min[j_sec]) { - flag_sector = true; - i_sector = j_sec; + return j_sec; } } - if (flag_sector) { + return -1; + } + + /// returns radiator radius in cm at considered eta (accounting for sector inclination) + /// \param eta the pseudorapidity of the tarck (assuming primary vertex at origin) + /// \param i_sector the index of the track RICH sector + float radiusRipple(float eta, int i_sector) + { + float polar = 2.0 * std::atan(std::exp(-eta)); + if (i_sector > 0) { float R_sec_rich = rad_centers[i_sector].X(); float z_sec_rich = rad_centers[i_sector].Z(); return (std::pow(R_sec_rich, 2) + std::pow(z_sec_rich, 2)) / (R_sec_rich + z_sec_rich / std::tan(polar)); @@ -347,12 +510,13 @@ struct OnTheFlyRichPid { /// returns Cherenkov angle in rad (above threshold) or bad flag (below threshold) /// \param momentum the momentum of the tarck /// \param mass the mass of the particle - float CherenkovAngle(float momentum, float mass) + /// \param n the refractive index of the considered sector + float CherenkovAngle(float momentum, float mass, float n) { // Check if particle is above the threshold - if (momentum > mass / std::sqrt(bRichRefractiveIndex * bRichRefractiveIndex - 1.0)) { + if (momentum > mass / std::sqrt(n * n - 1.0)) { // Calculate angle - float angle = std::acos(std::sqrt(momentum * momentum + mass * mass) / (momentum * bRichRefractiveIndex)); + float angle = std::acos(std::sqrt(momentum * momentum + mass * mass) / (momentum * n)); // Mean number of detected photons (SiPM PDE is accountd in multiplicative factor!!!) float meanNumberofDetectedPhotons = 230. * std::sin(angle) * std::sin(angle) * bRichRadiatorThickness; @@ -409,6 +573,127 @@ struct OnTheFlyRichPid { } } + /// To account border effects in bRICH + /// Approximation for analytic calculation: track along projective sector normal (reasonable) + /// \param eta the pseudorapidity of the tarck (assuming primary vertex at origin) + /// \param tile_z_length the Z-length of the photodetector plane of the considered sector + /// \param radius the nominal radius of the Cherenkov ring + float fractionPhotonsProjectiveRICH(float eta, float tile_z_length, float radius) + { + float polar = 2.0 * std::atan(std::exp(-eta)); + int i_sector = 0; + bool flag_sector = false; + for (int j_sec = 0; j_sec < mNumberSectors; j_sec++) { + if (polar > theta_max[j_sec] && polar < theta_min[j_sec]) { + flag_sector = true; + i_sector = j_sec; + } + } + if (flag_sector == false) { + return error_value; // <-- Returning negative value + } + float R_sec_rich = rad_centers[i_sector].X(); + float z_sec_rich = rad_centers[i_sector].Z(); + // float R_sec_tof = det_centers[i_sector].X(); + // float z_sec_tof = det_centers[i_sector].Z(); + float radius_ripple = (std::pow(R_sec_rich, 2) + std::pow(z_sec_rich, 2)) / (R_sec_rich + z_sec_rich / std::tan(polar)); + float z_ripple = radius_ripple / std::tan(polar); + float absZ = std::hypot(radius_ripple - R_sec_rich, z_ripple - z_sec_rich); + float fraction = 1.; + if (tile_z_length / 2. - absZ < radius) { + fraction = fraction - (1. / M_PI) * std::acos((tile_z_length / 2. - absZ) / radius); + if (tile_z_length / 2. + absZ < radius) { + fraction = fraction - (1. / M_PI) * std::acos((tile_z_length / 2. + absZ) / radius); + } + } + return fraction; + } + + /// returns refined ring angular resolution + /// \param eta the pseudorapidity of the tarck (assuming primary vertex at origin) + /// \param n the refractive index of the considered sector + /// \param n_g the refractive index of the gas filling the RICH proximity gap + /// \param T_r the radiator thickness in cm + /// \param T_g the proximity gap thickness of the considered sector in cm + /// \param pixel_size the SiPM pixel size in cm + /// \param theta_c the Cherenkov angle for the considered track + /// \param tile_z_length the Z-length of the photodetector plane of the considered sector + float extract_ring_angular_resolution(float eta, float n, float n_g, float T_r, float T_g, float pixel_size, float theta_c, float tile_z_length) + { + // Check if input angle is error value + if (theta_c <= error_value + 1) + return error_value; + // Parametrization variables (notation from https://doi.org/10.1016/0168-9002(94)90532-0) + float phi_c = 0.; + float theta_p = 0.; + float sin_theta_c = std::sin(theta_c); + float cos_theta_c = std::cos(theta_c); + float x_p = std::sin(theta_p); + float z_p = std::cos(theta_p); + float sin_phi = std::sin(phi_c); + float cos_phi = std::cos(phi_c); + // float ze = T_r / (2. * z_p); + float az = z_p * cos_theta_c - x_p * sin_theta_c * cos_phi; + float e3z = std::sqrt(az * az + (n_g / n) * (n_g / n) - 1.); + float Z = T_g; + float alpha = e3z / az; + float etac = e3z * n * n; + float k = T_r / (2. * Z); + float m = 1. / (n * n); + float lambda = (1. + k * alpha * alpha * alpha) / (1. + k * alpha); + // Derivative d(theta_c)/dx + float temp1 = etac / Z; + float temp2 = alpha * e3z * cos_phi; + float temp3 = x_p * sin_theta_c * sin_phi * sin_phi; + float d_theta_x = temp1 * (temp2 - temp3); + // Derivative d(theta_c)/dy + float temp4 = etac * sin_phi / Z; + float temp5 = cos_theta_c - z_p * (1 - m) / az; + float d_theta_y = temp4 * temp5; + // Derivative d(theta_c)/dze + float temp8 = etac * sin_theta_c; + float temp9 = Z * (1.0 + k * alpha * alpha * alpha * n * n); + float temp10 = alpha * alpha * (1.0 - x_p * x_p * sin_phi * sin_phi) + lambda * x_p * x_p * sin_phi * sin_phi; + float d_theta_ze = temp8 * temp10 / temp9; + // Derivative d(theta_c)/dn + float d_theta_n = z_p / (n * az * sin_theta_c); + // RMS wavelength (using Sellmeier formula with measured aerogel parameters) + float a0 = 0.0616; + float w0 = 56.5; + float n0 = 1.0307; + float w_mean = 436.0; // 450.0;//484.9;//426.0; //450;//485;//450; // nm //450 426 493.5 // 426.0 + float scaling = n / n0; + float temp11 = a0 * w0 * w0 * w_mean; + float temp12 = std::pow(w_mean * w_mean - w0 * w0, 1.5); + float temp13 = std::sqrt(w_mean * w_mean * (1.0 + a0) - w0 * w0); + float d_n_w = temp11 / (temp12 * temp13) * scaling; + float sigma_w = 115.0; + // RMS x y + float sigma_theta_x = pixel_size / std::sqrt(12.0); + float sigma_theta_y = pixel_size / std::sqrt(12.0); + // RMS emission point + float sigma_theta_ze = T_r / (z_p * std::sqrt(12.0)); + // Single photon angular resolution + float res_x = d_theta_x * sigma_theta_x; + float res_y = d_theta_y * sigma_theta_y; + float res_ze = d_theta_ze * sigma_theta_ze; + float res_n = d_theta_n * d_n_w * sigma_w; + float single_photon_angular_resolution = std::sqrt(std::pow(res_x, 2) + std::pow(res_y, 2) + std::pow(res_ze, 2) + std::pow(res_n, 2)); + // Fraction of photons in rings (to account loss close to sector boundary in projective geometry) + float radius = (T_r / 2.0) * std::tan(theta_c) + T_g * std::tan(std::asin((n / n_g) * std::sin(theta_c))); + float N0 = 24. * T_r / 2.; // photons for N = 1.03 at saturation ( 24/2 factor per radiator cm ) + float multiplicity_spectrum_factor = std::pow(std::sin(theta_c), 2.) / std::pow(std::sin(std::acos(1. / 1.03)), 2.); // scale multiplicity w.r.t. N = 1.03 at saturation + // Considering average resolution (integrated over the sector) + // float n_photons = (tile_z_length / 2.0 > radius) ? N0 * multiplicity_spectrum_factor * (1.-(2.0*radius)/(M_PI*tile_z_length)) : N0 * multiplicity_spectrum_factor * (1.-(2.0*radius)/(M_PI*tile_z_length) - (2.0/(tile_z_length*M_PI))*(-(tile_z_length/(2.0))*std::acos(tile_z_length/(2.0*radius)) + radius*std::sqrt(1.-std::pow(tile_z_length/(2.0*radius),2.0)))); + // Considering "exact" resolution (eta by eta) + float n_photons = N0 * multiplicity_spectrum_factor * fractionPhotonsProjectiveRICH(eta, tile_z_length, radius); + if (n_photons <= error_value + 1) + return error_value; + // Ring angular resolution + float ring_angular_resolution = single_photon_angular_resolution / std::sqrt(n_photons); + return ring_angular_resolution; + } + /// returns track angular resolution /// \param pt the transverse momentum of the tarck /// \param eta the pseudorapidity of the tarck @@ -416,7 +701,7 @@ struct OnTheFlyRichPid { /// \param track_pt_resolution the absolute resolution on eta /// \param mass the mass of the particle /// \param refractive_index the refractive index of the radiator - double calculate_track_time_resolution_advanced(float pt, float eta, float track_pt_resolution, float track_eta_resolution, float mass, float refractive_index) + double calculate_track_angular_resolution_advanced(float pt, float eta, float track_pt_resolution, float track_eta_resolution, float mass, float refractive_index) { // Compute tracking contribution to timing using the error propagation formula // Uses light speed in m/ps, magnetic field in T (*0.1 for conversion kGauss -> T) @@ -430,6 +715,8 @@ struct OnTheFlyRichPid { void process(soa::Join::iterator const& collision, soa::Join const& tracks, aod::McParticles const&, aod::McCollisions const&) { + // for (int i = 0; i < 1000; i++) + // std::cout << "Prova" << std::endl; o2::dataformats::VertexBase pvVtx({collision.posX(), collision.posY(), collision.posZ()}, {collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()}); @@ -487,9 +774,17 @@ struct OnTheFlyRichPid { if (pdgInfo == nullptr) { continue; } - float expectedAngleBarrelRich = CherenkovAngle(o2track.getP(), pdgInfo->Mass()); - float barrelRICHAngularResolution = AngularResolution(o2track.getEta()); - float projectiveRadiatorRadius = radiusRipple(o2track.getEta()); + + // find track bRICH sector + int i_sector = findSector(o2track.getEta()); + if (i_sector < 0) { + continue; + } + + float expectedAngleBarrelRich = CherenkovAngle(o2track.getP(), pdgInfo->Mass(), aerogel_rindex[i_sector]); + // float barrelRICHAngularResolution = AngularResolution(o2track.getEta()); + float barrelRICHAngularResolution = extract_ring_angular_resolution(o2track.getEta(), aerogel_rindex[i_sector], bRichGapRefractiveIndex, bRichRadiatorThickness, gap_thickness[i_sector], bRICHPixelSize, expectedAngleBarrelRich, photodetrctor_length[i_sector]); + float projectiveRadiatorRadius = radiusRipple(o2track.getEta(), i_sector); bool flagReachesRadiator = false; if (projectiveRadiatorRadius > error_value + 1.) { flagReachesRadiator = checkMagfieldLimit(o2track, projectiveRadiatorRadius, dBz); @@ -502,7 +797,7 @@ struct OnTheFlyRichPid { // Smear with expected resolutions float measuredAngleBarrelRich = pRandomNumberGenerator.Gaus(expectedAngleBarrelRich, barrelRICHAngularResolution); - // Now we calculate the expected arrival time following certain mass hypotheses + // Now we calculate the expected Cherenkov angle following certain mass hypotheses // and the (imperfect!) reconstructed track parametrizations auto recoTrack = getTrackParCov(track); if (recoTrack.propagateToDCA(pvVtx, dBz)) { @@ -519,7 +814,7 @@ struct OnTheFlyRichPid { auto pdgInfoThis = pdg->GetParticle(lpdg_array[ii]); masses[ii] = pdgInfoThis->Mass(); - float hypothesisAngleBarrelRich = CherenkovAngle(recoTrack.getP(), masses[ii]); + float hypothesisAngleBarrelRich = CherenkovAngle(recoTrack.getP(), masses[ii], aerogel_rindex[i_sector]); // Evaluate total sigma (layer + tracking resolution) float barrelTotalAngularReso = barrelRICHAngularResolution; @@ -531,7 +826,7 @@ struct OnTheFlyRichPid { eta_resolution = mSmearer.getAbsEtaRes(pdgInfoThis->PdgCode(), dNdEta, recoTrack.getEta(), recoTrack.getP() / std::cosh(recoTrack.getEta())); } // cout << endl << "Pt resolution: " << pt_resolution << ", Eta resolution: " << eta_resolution << endl << endl; - float barrelTrackAngularReso = calculate_track_time_resolution_advanced(recoTrack.getP() / std::cosh(recoTrack.getEta()), recoTrack.getEta(), pt_resolution, eta_resolution, masses[ii], bRichRefractiveIndex); + float barrelTrackAngularReso = calculate_track_angular_resolution_advanced(recoTrack.getP() / std::cosh(recoTrack.getEta()), recoTrack.getEta(), pt_resolution, eta_resolution, masses[ii], aerogel_rindex[i_sector]); barrelTotalAngularReso = std::hypot(barrelRICHAngularResolution, barrelTrackAngularReso); if (doQAplots && hypothesisAngleBarrelRich > error_value + 1. && measuredAngleBarrelRich > error_value + 1. && barrelRICHAngularResolution > error_value + 1. && flagReachesRadiator) { float momentum = recoTrack.getP(); @@ -572,10 +867,15 @@ struct OnTheFlyRichPid { // Fill histograms if (doQAplots) { float momentum = recoTrack.getP(); + float pseudorapidity = recoTrack.getEta(); float barrelRichTheta = measuredAngleBarrelRich; if (barrelRichTheta > error_value + 1. && barrelRICHAngularResolution > error_value + 1. && flagReachesRadiator) { histos.fill(HIST("h2dAngleVsMomentumBarrelRICH"), momentum, barrelRichTheta); + histos.fill(HIST("h2dAngleVsEtaBarrelRICH"), pseudorapidity, barrelRichTheta); + histos.fill(HIST("h2dAngularResolutionVsMomentumBarrelRICH"), momentum, 1000 * barrelRICHAngularResolution); + histos.fill(HIST("h2dAngularResolutionVsEtaBarrelRICH"), pseudorapidity, 1000 * barrelRICHAngularResolution); + histos.fill(HIST("hSectorID"), i_sector); if (std::fabs(mcParticle.pdgCode()) == pdg->GetParticle(lpdg_array[0])->PdgCode()) { histos.fill(HIST("h2dBarrelNsigmaTrueElecVsElecHypothesis"), momentum, nSigmaBarrelRich[0]); diff --git a/ALICE3/TableProducer/OTF/onTheFlyTOFPID.cxx b/ALICE3/TableProducer/OTF/onTheFlyTOFPID.cxx deleted file mode 100644 index 3a907d47342..00000000000 --- a/ALICE3/TableProducer/OTF/onTheFlyTOFPID.cxx +++ /dev/null @@ -1,609 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// 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. - -// -// Task to add a table of track parameters propagated to the primary vertex -// - -#include - -#include - -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "Framework/ASoAHelpers.h" -#include "Common/DataModel/TrackSelectionTables.h" -#include "Common/Core/trackUtilities.h" -#include "ReconstructionDataFormats/DCA.h" -#include "DetectorsBase/Propagator.h" -#include "DetectorsBase/GeometryManager.h" -#include "CommonUtils/NameConf.h" -#include "CCDB/CcdbApi.h" -#include "CCDB/BasicCCDBManager.h" -#include "DataFormatsParameters/GRPMagField.h" -#include "DataFormatsCalibration/MeanVertexObject.h" -#include "CommonConstants/GeomConstants.h" -#include "CommonConstants/PhysicsConstants.h" -#include "TRandom3.h" -#include "ALICE3/DataModel/OTFTOF.h" -#include "DetectorsVertexing/HelixHelper.h" -#include "TableHelper.h" -#include "ALICE3/Core/DelphesO2TrackSmearer.h" - -/// \file onTheFlyTOFPID.cxx -/// -/// \brief This task goes straight from a combination of track table and mcParticles -/// and a custom TOF configuration to a table of TOF NSigmas for the particles -/// being analysed. It currently contemplates 5 particle types: -/// electrons, pions, kaons, protons and muons -/// -/// More particles could be added but would have to be added to the LUT -/// being used in the onTheFly tracker task. -/// -/// \author David Dobrigkeit Chinellato, UNICAMP, Nicola Nicassio, University and INFN Bari - -using namespace o2; -using namespace o2::framework; - -struct OnTheFlyTOFPID { - Produces upgradeTof; - - // necessary for particle charges - Service pdg; - - // these are the settings governing the TOF layers to be used - // note that there are two layers foreseen for now: inner and outer TOF - // more could be added (especially a disk TOF at a certain z?) - // in the evolution of this effort - Configurable dBz{"dBz", 20, "magnetic field (kilogauss)"}; - Configurable innerTOFRadius{"innerTOFRadius", 20, "barrel inner TOF radius (cm)"}; - Configurable outerTOFRadius{"outerTOFRadius", 80, "barrel outer TOF radius (cm)"}; - Configurable innerTOFTimeReso{"innerTOFTimeReso", 20, "barrel inner TOF time error (ps)"}; - Configurable outerTOFTimeReso{"outerTOFTimeReso", 20, "barrel outer TOF time error (ps)"}; - Configurable nStepsLIntegrator{"nStepsLIntegrator", 200, "number of steps in length integrator"}; - Configurable doQAplots{"doQAplots", true, "do basic velocity plot qa"}; - Configurable nBinsBeta{"nBinsBeta", 2200, "number of bins in beta"}; - Configurable nBinsP{"nBinsP", 80, "number of bins in momentum"}; - Configurable nBinsTrackLengthInner{"nBinsTrackLengthInner", 300, "number of bins in track length"}; - Configurable nBinsTrackLengthOuter{"nBinsTrackLengthOuter", 300, "number of bins in track length"}; - Configurable nBinsTrackDeltaLength{"nBinsTrackDeltaLength", 100, "number of bins in delta track length"}; - Configurable nBinsNsigmaCorrectSpecies{"nBinsNsigmaCorrectSpecies", 200, "number of bins in Nsigma plot (correct speies)"}; - Configurable nBinsNsigmaWrongSpecies{"nBinsNsigmaWrongSpecies", 200, "number of bins in Nsigma plot (wrong species)"}; - Configurable minNsigmaRange{"minNsigmaRange", -10, "lower limit for the nsigma axis"}; - Configurable maxNsigmaRange{"maxNsigmaRange", +10, "upper limit for the nsigma axis"}; - Configurable nBinsTimeRes{"nBinsTimeRes", 400, "number of bins plots time resolution"}; - Configurable nBinsRelativeEtaPt{"nBinsRelativeEtaPt", 400, "number of bins plots pt and eta relative errors"}; - Configurable nBinsEta{"nBinsEta", 400, "number of bins plot relative eta error"}; - Configurable flagIncludeTrackTimeRes{"flagIncludeTrackTimeRes", true, "flag to include or exclude track time resolution"}; - Configurable multiplicityEtaRange{"multiplicityEtaRange", 0.800000012, "eta range to compute the multiplicity"}; - Configurable flagTOFLoadDelphesLUTs{"flagTOFLoadDelphesLUTs", false, "flag to load Delphes LUTs for tracking correction (use recoTrack parameters if false)"}; - - Configurable lutEl{"lutEl", "lutCovm.el.dat", "LUT for electrons"}; - Configurable lutMu{"lutMu", "lutCovm.mu.dat", "LUT for muons"}; - Configurable lutPi{"lutPi", "lutCovm.pi.dat", "LUT for pions"}; - Configurable lutKa{"lutKa", "lutCovm.ka.dat", "LUT for kaons"}; - Configurable lutPr{"lutPr", "lutCovm.pr.dat", "LUT for protons"}; - - o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrNONE; - - // Track smearer (here used to get absolute pt and eta uncertainties if flagTOFLoadDelphesLUTs is true) - o2::delphes::DelphesO2TrackSmearer mSmearer; - - // needed: random number generator for smearing - TRandom3 pRandomNumberGenerator; - - // for handling basic QA histograms if requested - HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; - - void init(o2::framework::InitContext&) - { - pRandomNumberGenerator.SetSeed(0); // fully randomize - - // Load LUT for pt and eta smearing - if (flagIncludeTrackTimeRes && flagTOFLoadDelphesLUTs) { - std::map mapPdgLut; - const char* lutElChar = lutEl->c_str(); - const char* lutMuChar = lutMu->c_str(); - const char* lutPiChar = lutPi->c_str(); - const char* lutKaChar = lutKa->c_str(); - const char* lutPrChar = lutPr->c_str(); - - LOGF(info, "Will load electron lut file ..: %s for TOF PID", lutElChar); - LOGF(info, "Will load muon lut file ......: %s for TOF PID", lutMuChar); - LOGF(info, "Will load pion lut file ......: %s for TOF PID", lutPiChar); - LOGF(info, "Will load kaon lut file ......: %s for TOF PID", lutKaChar); - LOGF(info, "Will load proton lut file ....: %s for TOF PID", lutPrChar); - - mapPdgLut.insert(std::make_pair(11, lutElChar)); - mapPdgLut.insert(std::make_pair(13, lutMuChar)); - mapPdgLut.insert(std::make_pair(211, lutPiChar)); - mapPdgLut.insert(std::make_pair(321, lutKaChar)); - mapPdgLut.insert(std::make_pair(2212, lutPrChar)); - - for (auto e : mapPdgLut) { - if (!mSmearer.loadTable(e.first, e.second)) { - LOG(fatal) << "Having issue with loading the LUT " << e.first << " " << e.second; - } - } - } - - if (doQAplots) { - const AxisSpec axisMomentum{static_cast(nBinsP), 0.0f, +10.0f, "#it{p} (GeV/#it{c})"}; - const AxisSpec axisMomentumSmall{static_cast(nBinsP), 0.0f, +1.0f, "#it{p} (GeV/#it{c})"}; - const AxisSpec axisVelocity{static_cast(nBinsBeta), 0.0f, +1.1f, "Measured #beta"}; - const AxisSpec axisTrackLengthInner{static_cast(nBinsTrackLengthInner), 0.0f, 60.0f, "Track length (cm)"}; - const AxisSpec axisTrackLengthOuter{static_cast(nBinsTrackLengthOuter), 0.0f, 300.0f, "Track length (cm)"}; - const AxisSpec axisTrackDeltaLength{static_cast(nBinsTrackDeltaLength), 0.0f, 30.0f, "Delta Track length (cm)"}; - histos.add("h2dVelocityVsMomentumInner", "h2dVelocityVsMomentumInner", kTH2F, {axisMomentum, axisVelocity}); - histos.add("h2dVelocityVsMomentumOuter", "h2dVelocityVsMomentumOuter", kTH2F, {axisMomentum, axisVelocity}); - histos.add("h2dTrackLengthInnerVsPt", "h2dTrackLengthInnerVsPt", kTH2F, {axisMomentumSmall, axisTrackLengthInner}); - histos.add("h2dTrackLengthOuterVsPt", "h2dTrackLengthOuterVsPt", kTH2F, {axisMomentumSmall, axisTrackLengthOuter}); - - histos.add("h2dTrackLengthInnerRecoVsPt", "h2dTrackLengthInnerRecoVsPt", kTH2F, {axisMomentumSmall, axisTrackLengthInner}); - histos.add("h2dTrackLengthOuterRecoVsPt", "h2dTrackLengthOuterRecoVsPt", kTH2F, {axisMomentumSmall, axisTrackLengthOuter}); - - histos.add("h2dDeltaTrackLengthInnerVsPt", "h2dDeltaTrackLengthInnerVsPt", kTH2F, {axisMomentumSmall, axisTrackDeltaLength}); - histos.add("h2dDeltaTrackLengthOuterVsPt", "h2dDeltaTrackLengthOuterVsPt", kTH2F, {axisMomentumSmall, axisTrackDeltaLength}); - - const AxisSpec axisPt{static_cast(nBinsP), 0.0f, +4.0f, "#it{p_{T}} (GeV/#it{c})"}; - const AxisSpec axisEta{static_cast(nBinsEta), -2.0f, +2.0f, "#eta"}; - const AxisSpec axisRelativePt{static_cast(nBinsRelativeEtaPt), 0.0f, +10.0f, "#it{#sigma_{p_{T}}} / #it{p_{T}} (%)"}; - const AxisSpec axisRelativeEta{static_cast(nBinsRelativeEtaPt), 0.0f, +10.0f, "#it{#sigma_{#eta}} / #it{#eta} (%)"}; - histos.add("h2dRelativePtResolution", "h2dRelativePtResolution", kTH2F, {axisPt, axisRelativePt}); - histos.add("h2dRelativeEtaResolution", "h2dRelativeEtaResolution", kTH2F, {axisEta, axisRelativeEta}); - - std::string particle_names1[5] = {"#it{e}", "#it{#mu}", "#it{#pi}", "#it{K}", "#it{p}"}; - std::string particle_names2[5] = {"Elec", "Muon", "Pion", "Kaon", "Prot"}; - for (int i_true = 0; i_true < 5; i_true++) { - std::string name_title_inner_track_res = "h2dInnerTimeResTrack" + particle_names2[i_true] + "VsP"; - std::string name_title_inner_total_res = "h2dInnerTimeResTotal" + particle_names2[i_true] + "VsP"; - std::string name_title_outer_track_res = "h2dOuterTimeResTrack" + particle_names2[i_true] + "VsP"; - std::string name_title_outer_total_res = "h2dOuterTimeResTotal" + particle_names2[i_true] + "VsP"; - const AxisSpec axisTrackTimeRes{static_cast(nBinsTimeRes), 0.0f, +200.0f, "Track time resolution - " + particle_names1[i_true] + " (ps)"}; - const AxisSpec axisTotalTimeRes{static_cast(nBinsTimeRes), 0.0f, +200.0f, "Total time resolution - " + particle_names1[i_true] + " (ps)"}; - histos.add(name_title_inner_track_res.c_str(), name_title_inner_track_res.c_str(), kTH2F, {axisMomentum, axisTrackTimeRes}); - histos.add(name_title_inner_total_res.c_str(), name_title_inner_total_res.c_str(), kTH2F, {axisMomentum, axisTotalTimeRes}); - histos.add(name_title_outer_track_res.c_str(), name_title_outer_track_res.c_str(), kTH2F, {axisMomentum, axisTrackTimeRes}); - histos.add(name_title_outer_total_res.c_str(), name_title_outer_total_res.c_str(), kTH2F, {axisMomentum, axisTotalTimeRes}); - } - - for (int i_true = 0; i_true < 5; i_true++) { - for (int i_hyp = 0; i_hyp < 5; i_hyp++) { - std::string name_title_inner = "h2dInnerNsigmaTrue" + particle_names2[i_true] + "Vs" + particle_names2[i_hyp] + "Hypothesis"; - std::string name_title_outer = "h2dOuterNsigmaTrue" + particle_names2[i_true] + "Vs" + particle_names2[i_hyp] + "Hypothesis"; - if (i_true == i_hyp) { - const AxisSpec axisNsigmaCorrect{static_cast(nBinsNsigmaCorrectSpecies), minNsigmaRange, maxNsigmaRange, "N#sigma - True " + particle_names1[i_true] + " vs " + particle_names1[i_hyp] + " hypothesis"}; - histos.add(name_title_inner.c_str(), name_title_inner.c_str(), kTH2F, {axisMomentum, axisNsigmaCorrect}); - histos.add(name_title_outer.c_str(), name_title_outer.c_str(), kTH2F, {axisMomentum, axisNsigmaCorrect}); - } else { - const AxisSpec axisNsigmaWrong{static_cast(nBinsNsigmaWrongSpecies), minNsigmaRange, maxNsigmaRange, "N#sigma - True " + particle_names1[i_true] + " vs " + particle_names1[i_hyp] + " hypothesis"}; - histos.add(name_title_inner.c_str(), name_title_inner.c_str(), kTH2F, {axisMomentum, axisNsigmaWrong}); - histos.add(name_title_outer.c_str(), name_title_outer.c_str(), kTH2F, {axisMomentum, axisNsigmaWrong}); - } - } - } - } - } - - /// Function to convert a McParticle into a perfect Track - /// \param particle the particle to convert (mcParticle) - /// \param o2track the address of the resulting TrackParCov - template - o2::track::TrackParCov convertMCParticleToO2Track(McParticleType& particle) - { - // FIXME: this is a fundamentally important piece of code. - // It could be placed in a utility file instead of here. - auto pdgInfo = pdg->GetParticle(particle.pdgCode()); - int charge = 0; - if (pdgInfo != nullptr) { - charge = pdgInfo->Charge() / 3; - } - std::array params; - std::array covm = {0.}; - float s, c, x; - o2::math_utils::sincos(particle.phi(), s, c); - o2::math_utils::rotateZInv(particle.vx(), particle.vy(), x, params[0], s, c); - params[1] = particle.vz(); - params[2] = 0.; // since alpha = phi - auto theta = 2. * std::atan(std::exp(-particle.eta())); - params[3] = 1. / std::tan(theta); - params[4] = charge / particle.pt(); - - // Return TrackParCov - return o2::track::TrackParCov(x, particle.phi(), params, covm); - } - - /// function to calculate track length of this track up to a certain radius - /// \param track the input track - /// \param radius the radius of the layer you're calculating the length to - /// \param magneticField the magnetic field to use when propagating - float trackLength(o2::track::TrackParCov track, float radius, float magneticField) - { - // don't make use of the track parametrization - float length = -100; - - o2::math_utils::CircleXYf_t trcCircle; - float sna, csa; - track.getCircleParams(magneticField, trcCircle, sna, csa); - - // distance between circle centers (one circle is at origin -> easy) - float centerDistance = std::hypot(trcCircle.xC, trcCircle.yC); - - // condition of circles touching - if not satisfied returned length will be -100 - if (centerDistance < trcCircle.rC + radius && centerDistance > fabs(trcCircle.rC - radius)) { - length = 0.0f; - - // base radical direction - float ux = trcCircle.xC / centerDistance; - float uy = trcCircle.yC / centerDistance; - // calculate perpendicular vector (normalized) for +/- displacement - float vx = -uy; - float vy = +ux; - // calculate coordinate for radical line - float radical = (centerDistance * centerDistance - trcCircle.rC * trcCircle.rC + radius * radius) / (2.0f * centerDistance); - // calculate absolute displacement from center-to-center axis - float displace = (0.5f / centerDistance) * TMath::Sqrt( - (-centerDistance + trcCircle.rC - radius) * - (-centerDistance - trcCircle.rC + radius) * - (-centerDistance + trcCircle.rC + radius) * - (centerDistance + trcCircle.rC + radius)); - - // possible intercept points of track and TOF layer in 2D plane - float point1[2] = {radical * ux + displace * vx, radical * uy + displace * vy}; - float point2[2] = {radical * ux - displace * vx, radical * uy - displace * vy}; - - // decide on correct intercept point - std::array mom; - track.getPxPyPzGlo(mom); - float scalarProduct1 = point1[0] * mom[0] + point1[1] * mom[1]; - float scalarProduct2 = point2[0] * mom[0] + point2[1] * mom[1]; - - // get start point - std::array startPoint; - track.getXYZGlo(startPoint); - - float cosAngle = -1000, modulus = -1000; - - if (scalarProduct1 > scalarProduct2) { - modulus = std::hypot(point1[0] - trcCircle.xC, point1[1] - trcCircle.yC) * std::hypot(startPoint[0] - trcCircle.xC, startPoint[1] - trcCircle.yC); - cosAngle = (point1[0] - trcCircle.xC) * (startPoint[0] - trcCircle.xC) + (point1[1] - trcCircle.yC) * (startPoint[1] - trcCircle.yC); - } else { - modulus = std::hypot(point2[0] - trcCircle.xC, point2[1] - trcCircle.yC) * std::hypot(startPoint[0] - trcCircle.xC, startPoint[1] - trcCircle.yC); - cosAngle = (point2[0] - trcCircle.xC) * (startPoint[0] - trcCircle.xC) + (point2[1] - trcCircle.yC) * (startPoint[1] - trcCircle.yC); - } - cosAngle /= modulus; - length = trcCircle.rC * TMath::ACos(cosAngle); - length *= sqrt(1.0f + track.getTgl() * track.getTgl()); - } - return length; - } - - /// returns velocity in centimeters per picoseconds - /// \param momentum the momentum of the tarck - /// \param mass the mass of the particle - float velocity(float momentum, float mass) - { - float a = std::pow(momentum / mass, 2); - // uses light speed in cm/ps so output is in those units - return (o2::constants::physics::LightSpeedCm2NS / 1e+3) * std::sqrt(a / (1 + a)); - } - - /// returns track time resolution - /// \param pt the transverse momentum of the tarck - /// \param eta the pseudorapidity of the tarck - /// \param track_pt_resolution the absolute resolution on pt - /// \param track_pt_resolution the absolute resolution on eta - /// \param mass the mass of the particle - /// \param det_radius the radius of the cylindrical layer - /// \param magneticField the magnetic field (along Z) - double calculate_track_time_resolution_advanced(float pt, float eta, float track_pt_resolution, float track_eta_resolution, float mass, float det_radius, float magneticField) - { - // Compute tracking contribution to timing using the error propagation formula - // Uses light speed in m/ps, magnetic field in T (*0.1 for conversion kGauss -> T) - double a0 = mass * mass; - double a1 = 0.299792458 * (0.1 * magneticField) * (0.01 * o2::constants::physics::LightSpeedCm2NS / 1e+3); - double a2 = (det_radius * 0.01) * (det_radius * 0.01) * (0.299792458) * (0.299792458) * (0.1 * magneticField) * (0.1 * magneticField) / 2.0; - double dtof_on_dpt = (std::pow(pt, 4) * std::pow(std::cosh(eta), 2) * std::acos(1.0 - a2 / std::pow(pt, 2)) - 2.0 * a2 * std::pow(pt, 2) * (a0 + std::pow(pt * std::cosh(eta), 2)) / std::sqrt(a2 * (2.0 * std::pow(pt, 2) - a2))) / (a1 * std::pow(pt, 3) * std::sqrt(a0 + std::pow(pt * std::cosh(eta), 2))); - double dtof_on_deta = std::pow(pt, 2) * std::sinh(eta) * std::cosh(eta) * std::acos(1.0 - a2 / std::pow(pt, 2)) / (a1 * std::sqrt(a0 + std::pow(pt * std::cosh(eta), 2))); - double track_time_resolution = std::hypot(std::fabs(dtof_on_dpt) * track_pt_resolution, std::fabs(dtof_on_deta) * track_eta_resolution); - return track_time_resolution; - } - - void process(soa::Join::iterator const& collision, soa::Join const& tracks, aod::McParticles const&, aod::McCollisions const&) - { - o2::dataformats::VertexBase pvVtx({collision.posX(), collision.posY(), collision.posZ()}, - {collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()}); - - std::array mcPvCov = {0.}; - o2::dataformats::VertexBase mcPvVtx({0.0f, 0.0f, 0.0f}, mcPvCov); - if (collision.has_mcCollision()) { - auto mcCollision = collision.mcCollision(); - mcPvVtx.setX(mcCollision.posX()); - mcPvVtx.setY(mcCollision.posY()); - mcPvVtx.setZ(mcCollision.posZ()); - } // else remains untreated for now - - // First we compute the number of charged particles in the event if LUTs are loaded - float dNdEta = 0.f; - if (flagTOFLoadDelphesLUTs) { - for (const auto& track : tracks) { - if (!track.has_mcParticle()) - continue; - auto mcParticle = track.mcParticle(); - if (std::abs(mcParticle.eta()) > multiplicityEtaRange) { - continue; - } - if (mcParticle.has_daughters()) { - continue; - } - const auto& pdgInfo = pdg->GetParticle(mcParticle.pdgCode()); - if (!pdgInfo) { - // LOG(warning) << "PDG code " << mcParticle.pdgCode() << " not found in the database"; - continue; - } - if (pdgInfo->Charge() == 0) { - continue; - } - dNdEta += 1.f; - } - } - - for (const auto& track : tracks) { - // first step: find precise arrival time (if any) - // --- convert track into perfect track - if (!track.has_mcParticle()) // should always be OK but check please - continue; - - auto mcParticle = track.mcParticle(); - o2::track::TrackParCov o2track = convertMCParticleToO2Track(mcParticle); - - float xPv = -100, trackLengthInnerTOF = -1, trackLengthOuterTOF = -1; - if (o2track.propagateToDCA(mcPvVtx, dBz)) - xPv = o2track.getX(); - if (xPv > -99.) { - trackLengthInnerTOF = trackLength(o2track, innerTOFRadius, dBz); - trackLengthOuterTOF = trackLength(o2track, outerTOFRadius, dBz); - } - - // get mass to calculate velocity - auto pdgInfo = pdg->GetParticle(mcParticle.pdgCode()); - if (pdgInfo == nullptr) { - continue; - } - float expectedTimeInnerTOF = trackLengthInnerTOF / velocity(o2track.getP(), pdgInfo->Mass()); - float expectedTimeOuterTOF = trackLengthOuterTOF / velocity(o2track.getP(), pdgInfo->Mass()); - - // Smear with expected resolutions - float measuredTimeInnerTOF = pRandomNumberGenerator.Gaus(expectedTimeInnerTOF, innerTOFTimeReso); - float measuredTimeOuterTOF = pRandomNumberGenerator.Gaus(expectedTimeOuterTOF, outerTOFTimeReso); - - // Now we calculate the expected arrival time following certain mass hypotheses - // and the (imperfect!) reconstructed track parametrizations - float trackLengthRecoInnerTOF = -1, trackLengthRecoOuterTOF = -1; - auto recoTrack = getTrackParCov(track); - if (recoTrack.propagateToDCA(pvVtx, dBz)) - xPv = recoTrack.getX(); - if (xPv > -99.) { - trackLengthRecoInnerTOF = trackLength(recoTrack, innerTOFRadius, dBz); - trackLengthRecoOuterTOF = trackLength(recoTrack, outerTOFRadius, dBz); - } - - // Straight to Nsigma - float deltaTimeInnerTOF[5], nSigmaInnerTOF[5]; - float deltaTimeOuterTOF[5], nSigmaOuterTOF[5]; - int lpdg_array[5] = {kElectron, kMuonMinus, kPiPlus, kKPlus, kProton}; - float masses[5]; - - if (doQAplots) { - float momentum = recoTrack.getP(); - // unit conversion: length in cm, time in ps - float innerBeta = 1e+3 * (trackLengthInnerTOF / measuredTimeInnerTOF) / o2::constants::physics::LightSpeedCm2NS; - float outerBeta = 1e+3 * (trackLengthOuterTOF / measuredTimeOuterTOF) / o2::constants::physics::LightSpeedCm2NS; - if (trackLengthRecoInnerTOF > 0) { - histos.fill(HIST("h2dVelocityVsMomentumInner"), momentum, innerBeta); - histos.fill(HIST("h2dTrackLengthInnerVsPt"), o2track.getPt(), trackLengthInnerTOF); - histos.fill(HIST("h2dTrackLengthInnerRecoVsPt"), o2track.getPt(), trackLengthRecoInnerTOF); - } - if (trackLengthRecoOuterTOF > 0) { - histos.fill(HIST("h2dVelocityVsMomentumOuter"), momentum, outerBeta); - histos.fill(HIST("h2dTrackLengthOuterVsPt"), o2track.getPt(), trackLengthOuterTOF); - histos.fill(HIST("h2dTrackLengthOuterRecoVsPt"), o2track.getPt(), trackLengthRecoOuterTOF); - } - } - - for (int ii = 0; ii < 5; ii++) { - nSigmaInnerTOF[ii] = -100; - nSigmaOuterTOF[ii] = -100; - - auto pdgInfoThis = pdg->GetParticle(lpdg_array[ii]); - masses[ii] = pdgInfoThis->Mass(); - deltaTimeInnerTOF[ii] = trackLengthRecoInnerTOF / velocity(recoTrack.getP(), masses[ii]) - measuredTimeInnerTOF; - deltaTimeOuterTOF[ii] = trackLengthRecoOuterTOF / velocity(recoTrack.getP(), masses[ii]) - measuredTimeOuterTOF; - - // Evaluate total sigma (layer + tracking resolution) - float innerTotalTimeReso = innerTOFTimeReso; - float outerTotalTimeReso = outerTOFTimeReso; - if (flagIncludeTrackTimeRes) { - double pt_resolution = std::pow(recoTrack.getP() / std::cosh(recoTrack.getEta()), 2) * std::sqrt(recoTrack.getSigma1Pt2()); - double eta_resolution = std::fabs(std::sin(2.0 * std::atan(std::exp(-recoTrack.getEta())))) * std::sqrt(recoTrack.getSigmaTgl2()); - if (flagTOFLoadDelphesLUTs) { - pt_resolution = mSmearer.getAbsPtRes(pdgInfoThis->PdgCode(), dNdEta, recoTrack.getEta(), recoTrack.getP() / std::cosh(recoTrack.getEta())); - eta_resolution = mSmearer.getAbsEtaRes(pdgInfoThis->PdgCode(), dNdEta, recoTrack.getEta(), recoTrack.getP() / std::cosh(recoTrack.getEta())); - } - float innerTrackTimeReso = calculate_track_time_resolution_advanced(recoTrack.getP() / std::cosh(recoTrack.getEta()), recoTrack.getEta(), pt_resolution, eta_resolution, masses[ii], innerTOFRadius, dBz); - float outerTrackTimeReso = calculate_track_time_resolution_advanced(recoTrack.getP() / std::cosh(recoTrack.getEta()), recoTrack.getEta(), pt_resolution, eta_resolution, masses[ii], outerTOFRadius, dBz); - innerTotalTimeReso = std::hypot(innerTOFTimeReso, innerTrackTimeReso); - outerTotalTimeReso = std::hypot(outerTOFTimeReso, outerTrackTimeReso); - - if (doQAplots && trackLengthRecoInnerTOF > 0) { - float momentum = recoTrack.getP(); - if (ii == 0 && std::fabs(mcParticle.pdgCode()) == pdg->GetParticle(lpdg_array[0])->PdgCode()) { - histos.fill(HIST("h2dInnerTimeResTrackElecVsP"), momentum, innerTrackTimeReso); - histos.fill(HIST("h2dInnerTimeResTotalElecVsP"), momentum, innerTotalTimeReso); - } - if (ii == 1 && std::fabs(mcParticle.pdgCode()) == pdg->GetParticle(lpdg_array[1])->PdgCode()) { - histos.fill(HIST("h2dInnerTimeResTrackMuonVsP"), momentum, innerTrackTimeReso); - histos.fill(HIST("h2dInnerTimeResTotalMuonVsP"), momentum, innerTotalTimeReso); - } - if (ii == 2 && std::fabs(mcParticle.pdgCode()) == pdg->GetParticle(lpdg_array[2])->PdgCode()) { - histos.fill(HIST("h2dInnerTimeResTrackPionVsP"), momentum, innerTrackTimeReso); - histos.fill(HIST("h2dInnerTimeResTotalPionVsP"), momentum, innerTotalTimeReso); - } - if (ii == 3 && std::fabs(mcParticle.pdgCode()) == pdg->GetParticle(lpdg_array[3])->PdgCode()) { - histos.fill(HIST("h2dInnerTimeResTrackKaonVsP"), momentum, innerTrackTimeReso); - histos.fill(HIST("h2dInnerTimeResTotalKaonVsP"), momentum, innerTotalTimeReso); - } - if (ii == 4 && std::fabs(mcParticle.pdgCode()) == pdg->GetParticle(lpdg_array[4])->PdgCode()) { - histos.fill(HIST("h2dInnerTimeResTrackProtVsP"), momentum, innerTrackTimeReso); - histos.fill(HIST("h2dInnerTimeResTotalProtVsP"), momentum, innerTotalTimeReso); - } - } - if (doQAplots && trackLengthRecoOuterTOF > 0) { - float momentum = recoTrack.getP(); - float pseudorapidity = recoTrack.getEta(); - float transverse_momentum = momentum / std::cosh(pseudorapidity); - if (ii == 0 && std::fabs(mcParticle.pdgCode()) == pdg->GetParticle(lpdg_array[0])->PdgCode()) { - histos.fill(HIST("h2dOuterTimeResTrackElecVsP"), momentum, outerTrackTimeReso); - histos.fill(HIST("h2dOuterTimeResTotalElecVsP"), momentum, outerTotalTimeReso); - } - if (ii == 1 && std::fabs(mcParticle.pdgCode()) == pdg->GetParticle(lpdg_array[1])->PdgCode()) { - histos.fill(HIST("h2dOuterTimeResTrackMuonVsP"), momentum, outerTrackTimeReso); - histos.fill(HIST("h2dOuterTimeResTotalMuonVsP"), momentum, outerTotalTimeReso); - } - if (ii == 2 && std::fabs(mcParticle.pdgCode()) == pdg->GetParticle(lpdg_array[2])->PdgCode()) { - histos.fill(HIST("h2dOuterTimeResTrackPionVsP"), momentum, outerTrackTimeReso); - histos.fill(HIST("h2dOuterTimeResTotalPionVsP"), momentum, outerTotalTimeReso); - - histos.fill(HIST("h2dRelativePtResolution"), transverse_momentum, 100.0 * pt_resolution / transverse_momentum); - histos.fill(HIST("h2dRelativeEtaResolution"), pseudorapidity, 100.0 * eta_resolution / (std::fabs(pseudorapidity) + 1e-6)); - } - if (ii == 3 && std::fabs(mcParticle.pdgCode()) == pdg->GetParticle(lpdg_array[3])->PdgCode()) { - histos.fill(HIST("h2dOuterTimeResTrackKaonVsP"), momentum, outerTrackTimeReso); - histos.fill(HIST("h2dOuterTimeResTotalKaonVsP"), momentum, outerTotalTimeReso); - } - if (ii == 4 && std::fabs(mcParticle.pdgCode()) == pdg->GetParticle(lpdg_array[4])->PdgCode()) { - histos.fill(HIST("h2dOuterTimeResTrackProtVsP"), momentum, outerTrackTimeReso); - histos.fill(HIST("h2dOuterTimeResTotalProtVsP"), momentum, outerTotalTimeReso); - } - } - } - - // Fixme: assumes dominant resolution effect is the TOF resolution - // and not the tracking itself. It's *probably* a fair assumption - // but it should be tested further! --> FIXED IN THIS VERSION - if (trackLengthInnerTOF > 0 && trackLengthRecoInnerTOF > 0) - nSigmaInnerTOF[ii] = deltaTimeInnerTOF[ii] / innerTotalTimeReso; - if (trackLengthOuterTOF > 0 && trackLengthRecoOuterTOF > 0) - nSigmaOuterTOF[ii] = deltaTimeOuterTOF[ii] / outerTotalTimeReso; - } - - if (doQAplots) { - float momentum = recoTrack.getP(); - if (trackLengthRecoInnerTOF > 0) { - if (std::fabs(mcParticle.pdgCode()) == pdg->GetParticle(lpdg_array[0])->PdgCode()) { - histos.fill(HIST("h2dInnerNsigmaTrueElecVsElecHypothesis"), momentum, nSigmaInnerTOF[0]); - histos.fill(HIST("h2dInnerNsigmaTrueElecVsMuonHypothesis"), momentum, nSigmaInnerTOF[1]); - histos.fill(HIST("h2dInnerNsigmaTrueElecVsPionHypothesis"), momentum, nSigmaInnerTOF[2]); - histos.fill(HIST("h2dInnerNsigmaTrueElecVsKaonHypothesis"), momentum, nSigmaInnerTOF[3]); - histos.fill(HIST("h2dInnerNsigmaTrueElecVsProtHypothesis"), momentum, nSigmaInnerTOF[4]); - } - if (std::fabs(mcParticle.pdgCode()) == pdg->GetParticle(lpdg_array[1])->PdgCode()) { - histos.fill(HIST("h2dInnerNsigmaTrueMuonVsElecHypothesis"), momentum, nSigmaInnerTOF[0]); - histos.fill(HIST("h2dInnerNsigmaTrueMuonVsMuonHypothesis"), momentum, nSigmaInnerTOF[1]); - histos.fill(HIST("h2dInnerNsigmaTrueMuonVsPionHypothesis"), momentum, nSigmaInnerTOF[2]); - histos.fill(HIST("h2dInnerNsigmaTrueMuonVsKaonHypothesis"), momentum, nSigmaInnerTOF[3]); - histos.fill(HIST("h2dInnerNsigmaTrueMuonVsProtHypothesis"), momentum, nSigmaInnerTOF[4]); - } - if (std::fabs(mcParticle.pdgCode()) == pdg->GetParticle(lpdg_array[2])->PdgCode()) { - histos.fill(HIST("h2dInnerNsigmaTruePionVsElecHypothesis"), momentum, nSigmaInnerTOF[0]); - histos.fill(HIST("h2dInnerNsigmaTruePionVsMuonHypothesis"), momentum, nSigmaInnerTOF[1]); - histos.fill(HIST("h2dInnerNsigmaTruePionVsPionHypothesis"), momentum, nSigmaInnerTOF[2]); - histos.fill(HIST("h2dInnerNsigmaTruePionVsKaonHypothesis"), momentum, nSigmaInnerTOF[3]); - histos.fill(HIST("h2dInnerNsigmaTruePionVsProtHypothesis"), momentum, nSigmaInnerTOF[4]); - } - if (std::fabs(mcParticle.pdgCode()) == pdg->GetParticle(lpdg_array[3])->PdgCode()) { - histos.fill(HIST("h2dInnerNsigmaTrueKaonVsElecHypothesis"), momentum, nSigmaInnerTOF[0]); - histos.fill(HIST("h2dInnerNsigmaTrueKaonVsMuonHypothesis"), momentum, nSigmaInnerTOF[1]); - histos.fill(HIST("h2dInnerNsigmaTrueKaonVsPionHypothesis"), momentum, nSigmaInnerTOF[2]); - histos.fill(HIST("h2dInnerNsigmaTrueKaonVsKaonHypothesis"), momentum, nSigmaInnerTOF[3]); - histos.fill(HIST("h2dInnerNsigmaTrueKaonVsProtHypothesis"), momentum, nSigmaInnerTOF[4]); - } - if (std::fabs(mcParticle.pdgCode()) == pdg->GetParticle(lpdg_array[4])->PdgCode()) { - histos.fill(HIST("h2dInnerNsigmaTrueProtVsElecHypothesis"), momentum, nSigmaInnerTOF[0]); - histos.fill(HIST("h2dInnerNsigmaTrueProtVsMuonHypothesis"), momentum, nSigmaInnerTOF[1]); - histos.fill(HIST("h2dInnerNsigmaTrueProtVsPionHypothesis"), momentum, nSigmaInnerTOF[2]); - histos.fill(HIST("h2dInnerNsigmaTrueProtVsKaonHypothesis"), momentum, nSigmaInnerTOF[3]); - histos.fill(HIST("h2dInnerNsigmaTrueProtVsProtHypothesis"), momentum, nSigmaInnerTOF[4]); - } - } - if (trackLengthRecoOuterTOF > 0) { - if (std::fabs(mcParticle.pdgCode()) == pdg->GetParticle(lpdg_array[0])->PdgCode()) { - histos.fill(HIST("h2dOuterNsigmaTrueElecVsElecHypothesis"), momentum, nSigmaOuterTOF[0]); - histos.fill(HIST("h2dOuterNsigmaTrueElecVsMuonHypothesis"), momentum, nSigmaOuterTOF[1]); - histos.fill(HIST("h2dOuterNsigmaTrueElecVsPionHypothesis"), momentum, nSigmaOuterTOF[2]); - histos.fill(HIST("h2dOuterNsigmaTrueElecVsKaonHypothesis"), momentum, nSigmaOuterTOF[3]); - histos.fill(HIST("h2dOuterNsigmaTrueElecVsProtHypothesis"), momentum, nSigmaOuterTOF[4]); - } - if (std::fabs(mcParticle.pdgCode()) == pdg->GetParticle(lpdg_array[1])->PdgCode()) { - histos.fill(HIST("h2dOuterNsigmaTrueMuonVsElecHypothesis"), momentum, nSigmaOuterTOF[0]); - histos.fill(HIST("h2dOuterNsigmaTrueMuonVsMuonHypothesis"), momentum, nSigmaOuterTOF[1]); - histos.fill(HIST("h2dOuterNsigmaTrueMuonVsPionHypothesis"), momentum, nSigmaOuterTOF[2]); - histos.fill(HIST("h2dOuterNsigmaTrueMuonVsKaonHypothesis"), momentum, nSigmaOuterTOF[3]); - histos.fill(HIST("h2dOuterNsigmaTrueMuonVsProtHypothesis"), momentum, nSigmaOuterTOF[4]); - } - if (std::fabs(mcParticle.pdgCode()) == pdg->GetParticle(lpdg_array[2])->PdgCode()) { - histos.fill(HIST("h2dOuterNsigmaTruePionVsElecHypothesis"), momentum, nSigmaOuterTOF[0]); - histos.fill(HIST("h2dOuterNsigmaTruePionVsMuonHypothesis"), momentum, nSigmaOuterTOF[1]); - histos.fill(HIST("h2dOuterNsigmaTruePionVsPionHypothesis"), momentum, nSigmaOuterTOF[2]); - histos.fill(HIST("h2dOuterNsigmaTruePionVsKaonHypothesis"), momentum, nSigmaOuterTOF[3]); - histos.fill(HIST("h2dOuterNsigmaTruePionVsProtHypothesis"), momentum, nSigmaOuterTOF[4]); - } - if (std::fabs(mcParticle.pdgCode()) == pdg->GetParticle(lpdg_array[3])->PdgCode()) { - histos.fill(HIST("h2dOuterNsigmaTrueKaonVsElecHypothesis"), momentum, nSigmaOuterTOF[0]); - histos.fill(HIST("h2dOuterNsigmaTrueKaonVsMuonHypothesis"), momentum, nSigmaOuterTOF[1]); - histos.fill(HIST("h2dOuterNsigmaTrueKaonVsPionHypothesis"), momentum, nSigmaOuterTOF[2]); - histos.fill(HIST("h2dOuterNsigmaTrueKaonVsKaonHypothesis"), momentum, nSigmaOuterTOF[3]); - histos.fill(HIST("h2dOuterNsigmaTrueKaonVsProtHypothesis"), momentum, nSigmaOuterTOF[4]); - } - if (std::fabs(mcParticle.pdgCode()) == pdg->GetParticle(lpdg_array[4])->PdgCode()) { - histos.fill(HIST("h2dOuterNsigmaTrueProtVsElecHypothesis"), momentum, nSigmaOuterTOF[0]); - histos.fill(HIST("h2dOuterNsigmaTrueProtVsMuonHypothesis"), momentum, nSigmaOuterTOF[1]); - histos.fill(HIST("h2dOuterNsigmaTrueProtVsPionHypothesis"), momentum, nSigmaOuterTOF[2]); - histos.fill(HIST("h2dOuterNsigmaTrueProtVsKaonHypothesis"), momentum, nSigmaOuterTOF[3]); - histos.fill(HIST("h2dOuterNsigmaTrueProtVsProtHypothesis"), momentum, nSigmaOuterTOF[4]); - } - } - } - - float deltaTrackLengthInnerTOF = abs(trackLengthInnerTOF - trackLengthRecoInnerTOF); - if (trackLengthInnerTOF > 0 && trackLengthRecoInnerTOF > 0) { - histos.fill(HIST("h2dDeltaTrackLengthInnerVsPt"), o2track.getPt(), deltaTrackLengthInnerTOF); - } - float deltaTrackLengthOuterTOF = abs(trackLengthOuterTOF - trackLengthRecoOuterTOF); - if (trackLengthOuterTOF > 0 && trackLengthRecoOuterTOF > 0) { - histos.fill(HIST("h2dDeltaTrackLengthOuterVsPt"), o2track.getPt(), deltaTrackLengthInnerTOF); - } - - // Sigmas have been fully calculated. Please populate the NSigma helper table (once per track) - upgradeTof(nSigmaInnerTOF[0], nSigmaInnerTOF[1], nSigmaInnerTOF[2], nSigmaInnerTOF[3], nSigmaInnerTOF[4], trackLengthInnerTOF, trackLengthRecoInnerTOF, deltaTrackLengthInnerTOF, - nSigmaOuterTOF[0], nSigmaOuterTOF[1], nSigmaOuterTOF[2], nSigmaOuterTOF[3], nSigmaOuterTOF[4], trackLengthOuterTOF, trackLengthRecoOuterTOF, deltaTrackLengthOuterTOF); - } - } -}; - -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) -{ - return WorkflowSpec{adaptAnalysisTask(cfgc)}; -} diff --git a/ALICE3/TableProducer/OTF/onTheFlyTofPid.cxx b/ALICE3/TableProducer/OTF/onTheFlyTofPid.cxx new file mode 100644 index 00000000000..435b616d927 --- /dev/null +++ b/ALICE3/TableProducer/OTF/onTheFlyTofPid.cxx @@ -0,0 +1,722 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// 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. +/// +/// \file onTheFlyTofPid.cxx +/// +/// \brief This task goes straight from a combination of track table and mcParticles +/// and a custom TOF configuration to a table of TOF NSigmas for the particles +/// being analysed. It currently contemplates 5 particle types: +/// electrons, pions, kaons, protons and muons +/// +/// More particles could be added but would have to be added to the LUT +/// being used in the onTheFly tracker task. +/// +/// \author David Dobrigkeit Chinellato, UNICAMP +/// \author Nicola Nicassio, University and INFN Bari +/// \since May 22, 2024 +/// + +#include +#include +#include +#include + +#include + +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" +#include "Framework/RunningWorkflowInfo.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/O2DatabasePDGPlugin.h" +#include "Framework/ASoAHelpers.h" +#include "Common/DataModel/TrackSelectionTables.h" +#include "Common/Core/trackUtilities.h" +#include "ReconstructionDataFormats/DCA.h" +#include "DetectorsBase/Propagator.h" +#include "DetectorsBase/GeometryManager.h" +#include "CommonUtils/NameConf.h" +#include "CCDB/CcdbApi.h" +#include "CCDB/BasicCCDBManager.h" +#include "DataFormatsParameters/GRPMagField.h" +#include "DataFormatsCalibration/MeanVertexObject.h" +#include "CommonConstants/GeomConstants.h" +#include "CommonConstants/PhysicsConstants.h" +#include "TRandom3.h" +#include "ALICE3/DataModel/OTFTOF.h" +#include "DetectorsVertexing/HelixHelper.h" +#include "TableHelper.h" +#include "ALICE3/Core/DelphesO2TrackSmearer.h" + +using namespace o2; +using namespace o2::framework; + +std::array, 5> h2dInnerTimeResTrack; +std::array, 5> h2dInnerTimeResTotal; +std::array, 5> h2dOuterTimeResTrack; +std::array, 5> h2dOuterTimeResTotal; +std::array, 5>, 5> h2dInnerNsigmaTrue; +std::array, 5>, 5> h2dOuterNsigmaTrue; +std::array, 5>, 5> h2dInnerDeltaTrue; +std::array, 5>, 5> h2dOuterDeltaTrue; + +struct OnTheFlyTofPid { + Produces upgradeTofMC; + Produces upgradeTof; + Produces upgradeTofExpectedTime; + + // necessary for particle charges + Service pdg; + + // these are the settings governing the TOF layers to be used + // note that there are two layers foreseen for now: inner and outer TOF + // more could be added (especially a disk TOF at a certain z?) + // in the evolution of this effort + struct : ConfigurableGroup { + Configurable dBz{"dBz", 20, "magnetic field (kilogauss)"}; + Configurable considerEventTime{"considerEventTime", true, "flag to consider event time"}; + Configurable innerTOFRadius{"innerTOFRadius", 20, "barrel inner TOF radius (cm)"}; + Configurable outerTOFRadius{"outerTOFRadius", 80, "barrel outer TOF radius (cm)"}; + Configurable innerTOFTimeReso{"innerTOFTimeReso", 20, "barrel inner TOF time error (ps)"}; + Configurable outerTOFTimeReso{"outerTOFTimeReso", 20, "barrel outer TOF time error (ps)"}; + Configurable nStepsLIntegrator{"nStepsLIntegrator", 200, "number of steps in length integrator"}; + Configurable multiplicityEtaRange{"multiplicityEtaRange", 0.800000012, "eta range to compute the multiplicity"}; + Configurable flagIncludeTrackTimeRes{"flagIncludeTrackTimeRes", true, "flag to include or exclude track time resolution"}; + Configurable flagTOFLoadDelphesLUTs{"flagTOFLoadDelphesLUTs", false, "flag to load Delphes LUTs for tracking correction (use recoTrack parameters if false)"}; + Configurable lutEl{"lutEl", "inherit", "LUT for electrons (if inherit, inherits from otf tracker task)"}; + Configurable lutMu{"lutMu", "inherit", "LUT for muons (if inherit, inherits from otf tracker task)"}; + Configurable lutPi{"lutPi", "inherit", "LUT for pions (if inherit, inherits from otf tracker task)"}; + Configurable lutKa{"lutKa", "inherit", "LUT for kaons (if inherit, inherits from otf tracker task)"}; + Configurable lutPr{"lutPr", "inherit", "LUT for protons (if inherit, inherits from otf tracker task)"}; + } simConfig; + + struct : ConfigurableGroup { + Configurable doQAplots{"doQAplots", true, "do basic velocity plot qa"}; + Configurable doSeparationVsPt{"doSeparationVsPt", true, "Produce plots vs pt or p"}; + Configurable nBinsBeta{"nBinsBeta", 2200, "number of bins in beta"}; + Configurable nBinsP{"nBinsP", 80, "number of bins in momentum/pT depending on doSeparationVsPt"}; + Configurable nBinsTrackLengthInner{"nBinsTrackLengthInner", 300, "number of bins in track length"}; + Configurable nBinsTrackLengthOuter{"nBinsTrackLengthOuter", 300, "number of bins in track length"}; + Configurable nBinsTrackDeltaLength{"nBinsTrackDeltaLength", 100, "number of bins in delta track length"}; + Configurable nBinsNsigmaCorrectSpecies{"nBinsNsigmaCorrectSpecies", 200, "number of bins in Nsigma plot (correct speies)"}; + Configurable nBinsNsigmaWrongSpecies{"nBinsNsigmaWrongSpecies", 200, "number of bins in Nsigma plot (wrong species)"}; + Configurable minNsigmaRange{"minNsigmaRange", -10, "lower limit for the nsigma axis"}; + Configurable maxNsigmaRange{"maxNsigmaRange", +10, "upper limit for the nsigma axis"}; + Configurable nBinsDeltaCorrectSpecies{"nBinsDeltaCorrectSpecies", 200, "number of bins in Delta plot (correct speies)"}; + Configurable nBinsDeltaWrongSpecies{"nBinsDeltaWrongSpecies", 200, "number of bins in Delta plot (wrong species)"}; + Configurable minDeltaRange{"minDeltaRange", -100, "lower limit for the nsigma axis"}; + Configurable maxDeltaRange{"maxDeltaRange", +100, "upper limit for the nsigma axis"}; + Configurable nBinsTimeRes{"nBinsTimeRes", 400, "number of bins plots time resolution"}; + Configurable nBinsRelativeEtaPt{"nBinsRelativeEtaPt", 400, "number of bins plots pt and eta relative errors"}; + Configurable nBinsEta{"nBinsEta", 400, "number of bins plot relative eta error"}; + } plotsConfig; + + o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrNONE; + + // Track smearer (here used to get absolute pt and eta uncertainties if simConfig.flagTOFLoadDelphesLUTs is true) + o2::delphes::DelphesO2TrackSmearer mSmearer; + + // needed: random number generator for smearing + TRandom3 pRandomNumberGenerator; + + // for handling basic QA histograms if requested + HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + static constexpr int kParticles = 5; + + void init(o2::framework::InitContext& initContext) + { + pRandomNumberGenerator.SetSeed(0); // fully randomize + + // Check if inheriting the LUT configuration + auto configLutPath = [&](Configurable& lut) { + if (lut.value != "inherit") { + return; + } + if (!getTaskOptionValue(initContext, "on-the-fly-tracker", lut.name, lut.value, true)) { + LOG(fatal) << "Could not get " << lut.name << " from on-the-fly-tracker task"; + } + }; + configLutPath(simConfig.lutEl); + configLutPath(simConfig.lutMu); + configLutPath(simConfig.lutPi); + configLutPath(simConfig.lutKa); + configLutPath(simConfig.lutPr); + + // Load LUT for pt and eta smearing + if (simConfig.flagIncludeTrackTimeRes && simConfig.flagTOFLoadDelphesLUTs) { + std::map mapPdgLut; + const char* lutElChar = simConfig.lutEl->c_str(); + const char* lutMuChar = simConfig.lutMu->c_str(); + const char* lutPiChar = simConfig.lutPi->c_str(); + const char* lutKaChar = simConfig.lutKa->c_str(); + const char* lutPrChar = simConfig.lutPr->c_str(); + + LOGF(info, "Will load electron lut file ..: %s for TOF PID", lutElChar); + LOGF(info, "Will load muon lut file ......: %s for TOF PID", lutMuChar); + LOGF(info, "Will load pion lut file ......: %s for TOF PID", lutPiChar); + LOGF(info, "Will load kaon lut file ......: %s for TOF PID", lutKaChar); + LOGF(info, "Will load proton lut file ....: %s for TOF PID", lutPrChar); + + mapPdgLut.insert(std::make_pair(11, lutElChar)); + mapPdgLut.insert(std::make_pair(13, lutMuChar)); + mapPdgLut.insert(std::make_pair(211, lutPiChar)); + mapPdgLut.insert(std::make_pair(321, lutKaChar)); + mapPdgLut.insert(std::make_pair(2212, lutPrChar)); + + for (const auto& e : mapPdgLut) { + if (!mSmearer.loadTable(e.first, e.second)) { + LOG(fatal) << "Having issue with loading the LUT " << e.first << " " << e.second; + } + } + } + + if (plotsConfig.doQAplots) { + const AxisSpec axisdNdeta{200, 0.0f, 1000.0f, Form("dN/d#eta in |#eta| < %f", simConfig.multiplicityEtaRange.value)}; + + histos.add("h1dNdeta", "h2dNdeta", kTH1F, {axisdNdeta}); + histos.add("h2dEventTime", "h2dEventTime", kTH2F, {{200, -1000, 1000, "computed"}, {200, -1000, 1000, "generated"}}); + histos.add("h1dEventTimegen", "h1dEventTimegen", kTH1F, {{200, -1000, 1000, "generated"}}); + histos.add("h1dEventTimerec", "h1dEventTimerec", kTH1F, {{200, -1000, 1000, "computed"}}); + histos.add("h2dEventTimeres", "h2dEventTimeres", kTH2F, {axisdNdeta, {300, 0, 300, "resolution"}}); + + const AxisSpec axisMomentum{static_cast(plotsConfig.nBinsP), 0.0f, +10.0f, "#it{p} (GeV/#it{c})"}; + const AxisSpec axisMomentumSmall{static_cast(plotsConfig.nBinsP), 0.0f, +1.0f, "#it{p} (GeV/#it{c})"}; + const AxisSpec axisVelocity{static_cast(plotsConfig.nBinsBeta), 0.0f, +1.1f, "Measured #beta"}; + const AxisSpec axisTrackLengthInner{static_cast(plotsConfig.nBinsTrackLengthInner), 0.0f, 60.0f, "Track length (cm)"}; + const AxisSpec axisTrackLengthOuter{static_cast(plotsConfig.nBinsTrackLengthOuter), 0.0f, 300.0f, "Track length (cm)"}; + const AxisSpec axisTrackDeltaLength{static_cast(plotsConfig.nBinsTrackDeltaLength), 0.0f, 30.0f, "Delta Track length (cm)"}; + histos.add("h2dVelocityVsMomentumInner", "h2dVelocityVsMomentumInner", kTH2F, {axisMomentum, axisVelocity}); + histos.add("h2dVelocityVsMomentumOuter", "h2dVelocityVsMomentumOuter", kTH2F, {axisMomentum, axisVelocity}); + histos.add("h2dTrackLengthInnerVsPt", "h2dTrackLengthInnerVsPt", kTH2F, {axisMomentumSmall, axisTrackLengthInner}); + histos.add("h2dTrackLengthOuterVsPt", "h2dTrackLengthOuterVsPt", kTH2F, {axisMomentumSmall, axisTrackLengthOuter}); + + histos.add("h2dTrackLengthInnerRecoVsPt", "h2dTrackLengthInnerRecoVsPt", kTH2F, {axisMomentumSmall, axisTrackLengthInner}); + histos.add("h2dTrackLengthOuterRecoVsPt", "h2dTrackLengthOuterRecoVsPt", kTH2F, {axisMomentumSmall, axisTrackLengthOuter}); + + histos.add("h2dDeltaTrackLengthInnerVsPt", "h2dDeltaTrackLengthInnerVsPt", kTH2F, {axisMomentumSmall, axisTrackDeltaLength}); + histos.add("h2dDeltaTrackLengthOuterVsPt", "h2dDeltaTrackLengthOuterVsPt", kTH2F, {axisMomentumSmall, axisTrackDeltaLength}); + + const AxisSpec axisPt{static_cast(plotsConfig.nBinsP), 0.0f, +4.0f, "#it{p_{T}} (GeV/#it{c})"}; + const AxisSpec axisEta{static_cast(plotsConfig.nBinsEta), -2.0f, +2.0f, "#eta"}; + const AxisSpec axisRelativePt{static_cast(plotsConfig.nBinsRelativeEtaPt), 0.0f, +10.0f, "#it{#sigma_{p_{T}}} / #it{p_{T}} (%)"}; + const AxisSpec axisRelativeEta{static_cast(plotsConfig.nBinsRelativeEtaPt), 0.0f, +10.0f, "#it{#sigma_{#eta}} / #it{#eta} (%)"}; + histos.add("h2dRelativePtResolution", "h2dRelativePtResolution", kTH2F, {axisPt, axisRelativePt}); + histos.add("h2dRelativeEtaResolution", "h2dRelativeEtaResolution", kTH2F, {axisEta, axisRelativeEta}); + + std::string particleNames[kParticles] = {"#it{e}", "#it{#mu}", "#it{#pi}", "#it{K}", "#it{p}"}; + std::string particleNames2[kParticles] = {"Elec", "Muon", "Pion", "Kaon", "Prot"}; + for (int i_true = 0; i_true < kParticles; i_true++) { + std::string nameTitleInnerTrackRes = "h2dInnerTimeResTrack" + particleNames2[i_true] + "VsP"; + std::string nameTitleTotalRes = "h2dInnerTimeResTotal" + particleNames2[i_true] + "VsP"; + std::string nameTitleOuterTrackRes = "h2dOuterTimeResTrack" + particleNames2[i_true] + "VsP"; + std::string nameTitleOuterTotalRes = "h2dOuterTimeResTotal" + particleNames2[i_true] + "VsP"; + const AxisSpec axisTrackTimeRes{static_cast(plotsConfig.nBinsTimeRes), 0.0f, +200.0f, "Track time resolution - " + particleNames[i_true] + " (ps)"}; + const AxisSpec axisTotalTimeRes{static_cast(plotsConfig.nBinsTimeRes), 0.0f, +200.0f, "Total time resolution - " + particleNames[i_true] + " (ps)"}; + h2dInnerTimeResTrack[i_true] = histos.add(nameTitleInnerTrackRes, nameTitleInnerTrackRes.c_str(), kTH2F, {axisMomentum, axisTrackTimeRes}); + h2dInnerTimeResTotal[i_true] = histos.add(nameTitleTotalRes, nameTitleTotalRes.c_str(), kTH2F, {axisMomentum, axisTotalTimeRes}); + h2dOuterTimeResTrack[i_true] = histos.add(nameTitleOuterTrackRes, nameTitleOuterTrackRes.c_str(), kTH2F, {axisMomentum, axisTrackTimeRes}); + h2dOuterTimeResTotal[i_true] = histos.add(nameTitleOuterTotalRes, nameTitleOuterTotalRes.c_str(), kTH2F, {axisMomentum, axisTotalTimeRes}); + for (int i_hyp = 0; i_hyp < kParticles; i_hyp++) { + std::string nameTitleInner = "h2dInnerNsigmaTrue" + particleNames2[i_true] + "Vs" + particleNames2[i_hyp] + "Hypothesis"; + std::string nameTitleOuter = "h2dOuterNsigmaTrue" + particleNames2[i_true] + "Vs" + particleNames2[i_hyp] + "Hypothesis"; + std::string nameTitleInnerDelta = "h2dInnerDeltaTrue" + particleNames2[i_true] + "Vs" + particleNames2[i_hyp] + "Hypothesis"; + std::string nameTitleOuterDelta = "h2dOuterDeltaTrue" + particleNames2[i_true] + "Vs" + particleNames2[i_hyp] + "Hypothesis"; + const AxisSpec axisX{plotsConfig.doSeparationVsPt.value ? axisPt : axisMomentum}; + if (i_true == i_hyp) { + const AxisSpec axisNsigmaCorrect{static_cast(plotsConfig.nBinsNsigmaCorrectSpecies), plotsConfig.minNsigmaRange, plotsConfig.maxNsigmaRange, "N#sigma - True " + particleNames[i_true] + " vs " + particleNames[i_hyp] + " hypothesis"}; + h2dInnerNsigmaTrue[i_true][i_hyp] = histos.add(nameTitleInner, nameTitleInner.c_str(), kTH2F, {axisX, axisNsigmaCorrect}); + h2dOuterNsigmaTrue[i_true][i_hyp] = histos.add(nameTitleOuter, nameTitleOuter.c_str(), kTH2F, {axisX, axisNsigmaCorrect}); + + const AxisSpec axisDeltaCorrect{static_cast(plotsConfig.nBinsDeltaCorrectSpecies), plotsConfig.minDeltaRange, plotsConfig.maxDeltaRange, "#Delta - True " + particleNames[i_true] + " vs " + particleNames[i_hyp] + " hypothesis"}; + h2dInnerDeltaTrue[i_true][i_hyp] = histos.add(nameTitleInnerDelta, nameTitleInnerDelta.c_str(), kTH2F, {axisX, axisDeltaCorrect}); + h2dOuterDeltaTrue[i_true][i_hyp] = histos.add(nameTitleOuterDelta, nameTitleOuterDelta.c_str(), kTH2F, {axisX, axisDeltaCorrect}); + } else { + const AxisSpec axisNsigmaWrong{static_cast(plotsConfig.nBinsNsigmaWrongSpecies), plotsConfig.minNsigmaRange, plotsConfig.maxNsigmaRange, "N#sigma - True " + particleNames[i_true] + " vs " + particleNames[i_hyp] + " hypothesis"}; + h2dInnerNsigmaTrue[i_true][i_hyp] = histos.add(nameTitleInner, nameTitleInner.c_str(), kTH2F, {axisX, axisNsigmaWrong}); + h2dOuterNsigmaTrue[i_true][i_hyp] = histos.add(nameTitleOuter, nameTitleOuter.c_str(), kTH2F, {axisX, axisNsigmaWrong}); + + const AxisSpec axisDeltaWrong{static_cast(plotsConfig.nBinsDeltaWrongSpecies), plotsConfig.minDeltaRange, plotsConfig.maxDeltaRange, "#Delta - True " + particleNames[i_true] + " vs " + particleNames[i_hyp] + " hypothesis"}; + h2dInnerDeltaTrue[i_true][i_hyp] = histos.add(nameTitleInnerDelta, nameTitleInnerDelta.c_str(), kTH2F, {axisX, axisDeltaWrong}); + h2dOuterDeltaTrue[i_true][i_hyp] = histos.add(nameTitleOuterDelta, nameTitleOuterDelta.c_str(), kTH2F, {axisX, axisDeltaWrong}); + } + } + } + } + } + + /// Function to convert a McParticle into a perfect Track + /// \param particle the particle to convert (mcParticle) + /// \param o2track the address of the resulting TrackParCov + template + o2::track::TrackParCov convertMCParticleToO2Track(McParticleType& particle) + { + // FIXME: this is a fundamentally important piece of code. + // It could be placed in a utility file instead of here. + auto pdgInfo = pdg->GetParticle(particle.pdgCode()); + int charge = 0; + if (pdgInfo != nullptr) { + charge = pdgInfo->Charge() / 3; + } + std::array params; + std::array covm = {0.}; + float s, c, x; + o2::math_utils::sincos(particle.phi(), s, c); + o2::math_utils::rotateZInv(particle.vx(), particle.vy(), x, params[0], s, c); + params[1] = particle.vz(); + params[2] = 0.; // since alpha = phi + auto theta = 2. * std::atan(std::exp(-particle.eta())); + params[3] = 1. / std::tan(theta); + params[4] = charge / particle.pt(); + + // Return TrackParCov + return o2::track::TrackParCov(x, particle.phi(), params, covm); + } + + /// function to calculate track length of this track up to a certain radius + /// \param track the input track + /// \param radius the radius of the layer you're calculating the length to + /// \param magneticField the magnetic field to use when propagating + float trackLength(o2::track::TrackParCov track, float radius, float magneticField) + { + // don't make use of the track parametrization + float length = -100; + + o2::math_utils::CircleXYf_t trcCircle; + float sna, csa; + track.getCircleParams(magneticField, trcCircle, sna, csa); + + // distance between circle centers (one circle is at origin -> easy) + float centerDistance = std::hypot(trcCircle.xC, trcCircle.yC); + + // condition of circles touching - if not satisfied returned length will be -100 + if (centerDistance < trcCircle.rC + radius && centerDistance > std::fabs(trcCircle.rC - radius)) { + length = 0.0f; + + // base radical direction + float ux = trcCircle.xC / centerDistance; + float uy = trcCircle.yC / centerDistance; + // calculate perpendicular vector (normalized) for +/- displacement + float vx = -uy; + float vy = +ux; + // calculate coordinate for radical line + float radical = (centerDistance * centerDistance - trcCircle.rC * trcCircle.rC + radius * radius) / (2.0f * centerDistance); + // calculate absolute displacement from center-to-center axis + float displace = (0.5f / centerDistance) * std::sqrt( + (-centerDistance + trcCircle.rC - radius) * + (-centerDistance - trcCircle.rC + radius) * + (-centerDistance + trcCircle.rC + radius) * + (centerDistance + trcCircle.rC + radius)); + + // possible intercept points of track and TOF layer in 2D plane + float point1[2] = {radical * ux + displace * vx, radical * uy + displace * vy}; + float point2[2] = {radical * ux - displace * vx, radical * uy - displace * vy}; + + // decide on correct intercept point + std::array mom; + track.getPxPyPzGlo(mom); + float scalarProduct1 = point1[0] * mom[0] + point1[1] * mom[1]; + float scalarProduct2 = point2[0] * mom[0] + point2[1] * mom[1]; + + // get start point + std::array startPoint; + track.getXYZGlo(startPoint); + + float cosAngle = -1000, modulus = -1000; + + if (scalarProduct1 > scalarProduct2) { + modulus = std::hypot(point1[0] - trcCircle.xC, point1[1] - trcCircle.yC) * std::hypot(startPoint[0] - trcCircle.xC, startPoint[1] - trcCircle.yC); + cosAngle = (point1[0] - trcCircle.xC) * (startPoint[0] - trcCircle.xC) + (point1[1] - trcCircle.yC) * (startPoint[1] - trcCircle.yC); + } else { + modulus = std::hypot(point2[0] - trcCircle.xC, point2[1] - trcCircle.yC) * std::hypot(startPoint[0] - trcCircle.xC, startPoint[1] - trcCircle.yC); + cosAngle = (point2[0] - trcCircle.xC) * (startPoint[0] - trcCircle.xC) + (point2[1] - trcCircle.yC) * (startPoint[1] - trcCircle.yC); + } + cosAngle /= modulus; + length = trcCircle.rC * std::acos(cosAngle); + length *= std::sqrt(1.0f + track.getTgl() * track.getTgl()); + } + return length; + } + + /// returns velocity in centimeters per picoseconds + /// \param momentum the momentum of the tarck + /// \param mass the mass of the particle + float particleVelocity(float momentum, float mass) + { + const float a = momentum / mass; + // uses light speed in cm/ps so output is in those units + return o2::constants::physics::LightSpeedCm2PS * a / std::sqrt((1.f + a * a)); + } + + struct TracksWithTime { + TracksWithTime(int pdgCode, + std::pair innerTOFTime, + std::pair outerTOFTime, + std::pair trackLengthInnerTOF, + std::pair trackLengthOuterTOF, + std::pair momentum, + std::pair pseudorapidity, + float noSmearingPt) + : mPdgCode(pdgCode), + mInnerTOFTime(innerTOFTime), + mOuterTOFTime(outerTOFTime), + mTrackLengthInnerTOF(trackLengthInnerTOF), + mTrackLengthOuterTOF(trackLengthOuterTOF), + mMomentum(momentum), + mPseudorapidity{pseudorapidity}, + mNoSmearingPt{noSmearingPt} {} + + int mPdgCode; + std::pair mInnerTOFTime; // Measured time and expected resolution at the inner TOF [ps] + std::pair mOuterTOFTime; // Measured time and expected resolution at the outer TOF [ps] + std::pair mTrackLengthInnerTOF; // Measured and generated length at the innerTOF [cm] + std::pair mTrackLengthOuterTOF; // Measured and generated length at the outerTOF [cm] + std::pair mMomentum; // Measured momentum and uncertainty on the momentum [GeV/c] + std::pair mPseudorapidity; // Measured pseudorapidity and uncertainty on the pseudorapidity + float mNoSmearingPt; // No smearing pt + }; + + std::vector tracksWithTime; + bool eventTime(std::vector& tracks, + std::array& tzero) + { + + float sum = 0.; + float sumw = 0.; + + // Todo: check the different mass hypothesis iteratively + for (const auto& track : tracks) { + auto pdgInfo = pdg->GetParticle(track.mPdgCode); + if (pdgInfo == nullptr) { + continue; + } + const float mass = pdgInfo->Mass(); + const float mass2 = mass * mass; + const float tof = track.mInnerTOFTime.first; // [ps] + const float etof = track.mInnerTOFTime.second; // [ps] + const float length = track.mTrackLengthInnerTOF.first; // [cm] + float p = track.mMomentum.first; // [GeV/c] + p *= std::abs(pdgInfo->Charge()) / 3.; // Total momentum + const float ep = track.mMomentum.second; // [GeV/c] + const float p2 = p * p; + const float lengthOverC = length * o2::constants::physics::invLightSpeedCm2PS; + const float texp = lengthOverC / p * std::sqrt(mass2 + p2); + // LOG(info) << "TOF: " << tof << " " << etof << " vs " << texp; + const float etexp = lengthOverC * mass2 / p2 / std::sqrt(mass2 + p2) * ep; + const float sigma = std::sqrt(etexp * etexp + etof * etof); + const float deltat = tof - texp; + + const float w = 1. / (sigma * sigma); + + sum += w * deltat; + sumw += w; + } + + if (sumw <= 0.) { + tzero[0] = 0.; // [ps] + tzero[1] = 200.f; // [ps] + return false; + } + + tzero[0] = sum / sumw; + tzero[1] = std::sqrt(1. / sumw); + return true; + } + + /// returns track time resolution + /// \param pt the transverse momentum of the tarck + /// \param eta the pseudorapidity of the tarck + /// \param trackPtResolution the absolute resolution on pt + /// \param trackEtaResolution the absolute resolution on eta + /// \param mass the mass of the particle + /// \param detRadius the radius of the cylindrical layer + /// \param magneticField the magnetic field (along Z) + double calculateTrackTimeResolutionAdvanced(float pt, + float eta, + float trackPtResolution, + float trackEtaResolution, + float mass, + float detRadius, + float magneticField) + { + // Compute tracking contribution to timing using the error propagation formula + // Uses light speed in m/ps, magnetic field in T (*0.1 for conversion kGauss -> T) + double a0 = mass * mass; + double a1 = 0.299792458 * (0.1 * magneticField) * (0.01 * o2::constants::physics::LightSpeedCm2NS / 1e+3); + double a2 = (detRadius * 0.01) * (detRadius * 0.01) * (0.299792458) * (0.299792458) * (0.1 * magneticField) * (0.1 * magneticField) / 2.0; + double dtofOndPt = (std::pow(pt, 4) * std::pow(std::cosh(eta), 2) * std::acos(1.0 - a2 / std::pow(pt, 2)) - 2.0 * a2 * std::pow(pt, 2) * (a0 + std::pow(pt * std::cosh(eta), 2)) / std::sqrt(a2 * (2.0 * std::pow(pt, 2) - a2))) / (a1 * std::pow(pt, 3) * std::sqrt(a0 + std::pow(pt * std::cosh(eta), 2))); + double dtofOndEta = std::pow(pt, 2) * std::sinh(eta) * std::cosh(eta) * std::acos(1.0 - a2 / std::pow(pt, 2)) / (a1 * std::sqrt(a0 + std::pow(pt * std::cosh(eta), 2))); + double trackTimeResolution = std::hypot(std::fabs(dtofOndPt) * trackPtResolution, std::fabs(dtofOndEta) * trackEtaResolution); + return trackTimeResolution; + } + + void process(soa::Join::iterator const& collision, + soa::Join const& tracks, + aod::McParticles const&, + aod::McCollisions const&) + { + o2::dataformats::VertexBase pvVtx({collision.posX(), collision.posY(), collision.posZ()}, + {collision.covXX(), collision.covXY(), collision.covYY(), + collision.covXZ(), collision.covYZ(), collision.covZZ()}); + + std::array mcPvCov = {0.}; + o2::dataformats::VertexBase mcPvVtx({0.0f, 0.0f, 0.0f}, mcPvCov); + const float eventCollisionTimePS = (simConfig.considerEventTime.value ? collision.collisionTime() * 1e3 : 0.f); // convert ns to ps + if (collision.has_mcCollision()) { + auto mcCollision = collision.mcCollision(); + mcPvVtx.setX(mcCollision.posX()); + mcPvVtx.setY(mcCollision.posY()); + mcPvVtx.setZ(mcCollision.posZ()); + } // else remains untreated for now + + // First we compute the number of charged particles in the event if LUTs are loaded + float dNdEta = 0.f; + for (const auto& track : tracks) { + if (!track.has_mcParticle()) + continue; + auto mcParticle = track.mcParticle(); + if (std::abs(mcParticle.eta()) > simConfig.multiplicityEtaRange) { + continue; + } + if (mcParticle.has_daughters()) { + continue; + } + const auto& pdgInfo = pdg->GetParticle(mcParticle.pdgCode()); + if (!pdgInfo) { + // LOG(warning) << "PDG code " << mcParticle.pdgCode() << " not found in the database"; + continue; + } + if (pdgInfo->Charge() == 0) { + continue; + } + dNdEta += 1.f; + } + if (plotsConfig.doQAplots) { + histos.fill(HIST("h1dNdeta"), dNdEta); + } + + tracksWithTime.clear(); // clear the vector of tracks with time to prepare the cache for the next event + tracksWithTime.reserve(tracks.size()); + // First loop to generate the arrival time of the particles to the TOF layers + for (const auto& track : tracks) { + // first step: find precise arrival time (if any) + // --- convert track into perfect track + if (!track.has_mcParticle()) // should always be OK but check please + continue; + const auto& mcParticle = track.mcParticle(); + o2::track::TrackParCov o2track = convertMCParticleToO2Track(mcParticle); + + float xPv = -100, trackLengthInnerTOF = -1, trackLengthOuterTOF = -1; + static constexpr float kTrkXThreshold = -99.f; // Threshold to consider a good propagation of the track + if (o2track.propagateToDCA(mcPvVtx, simConfig.dBz)) { + xPv = o2track.getX(); + } + if (xPv > kTrkXThreshold) { + trackLengthInnerTOF = trackLength(o2track, simConfig.innerTOFRadius, simConfig.dBz); + trackLengthOuterTOF = trackLength(o2track, simConfig.outerTOFRadius, simConfig.dBz); + } + + // get mass to calculate velocity + auto pdgInfo = pdg->GetParticle(mcParticle.pdgCode()); + if (pdgInfo == nullptr) { + continue; + } + const float v = particleVelocity(o2track.getP(), pdgInfo->Mass()); + const float expectedTimeInnerTOF = trackLengthInnerTOF / v + eventCollisionTimePS; // arrival time to the Inner TOF in ps + const float expectedTimeOuterTOF = trackLengthOuterTOF / v + eventCollisionTimePS; // arrival time to the Outer TOF in ps + upgradeTofMC(expectedTimeInnerTOF, trackLengthInnerTOF, expectedTimeOuterTOF, trackLengthOuterTOF); + + // Smear with expected resolutions + const float measuredTimeInnerTOF = pRandomNumberGenerator.Gaus(expectedTimeInnerTOF, simConfig.innerTOFTimeReso); + const float measuredTimeOuterTOF = pRandomNumberGenerator.Gaus(expectedTimeOuterTOF, simConfig.outerTOFTimeReso); + + // Now we calculate the expected arrival time following certain mass hypotheses + // and the (imperfect!) reconstructed track parametrizations + float trackLengthRecoInnerTOF = -1, trackLengthRecoOuterTOF = -1; + auto recoTrack = getTrackParCov(track); + if (recoTrack.propagateToDCA(pvVtx, simConfig.dBz)) { + xPv = recoTrack.getX(); + } + if (xPv > kTrkXThreshold) { + trackLengthRecoInnerTOF = trackLength(recoTrack, simConfig.innerTOFRadius, simConfig.dBz); + trackLengthRecoOuterTOF = trackLength(recoTrack, simConfig.outerTOFRadius, simConfig.dBz); + } + + // cache the track info needed for the event time calculation + // Reuse or emplace a new object in the vector + tracksWithTime.emplace_back(TracksWithTime{mcParticle.pdgCode(), + {measuredTimeInnerTOF, simConfig.innerTOFTimeReso}, + {measuredTimeOuterTOF, simConfig.outerTOFTimeReso}, + {trackLengthRecoInnerTOF, trackLengthInnerTOF}, + {trackLengthRecoOuterTOF, trackLengthOuterTOF}, + {recoTrack.getP(), recoTrack.getSigma1Pt2()}, + {recoTrack.getEta(), recoTrack.getSigmaTgl2()}, + o2track.getPt()}); + } + + // Now we compute the event time for the tracks + + std::array tzero = {0.f, 0.f}; + if (simConfig.considerEventTime.value) { + const bool etStatus = eventTime(tracksWithTime, tzero); + if (!etStatus) { + LOG(warning) << "Event time calculation failed with " << tracksWithTime.size() << " tracks"; + } + } + + if (plotsConfig.doQAplots) { + histos.fill(HIST("h2dEventTime"), tzero[0], eventCollisionTimePS); + histos.fill(HIST("h1dEventTimegen"), eventCollisionTimePS); + histos.fill(HIST("h1dEventTimerec"), tzero[0]); + histos.fill(HIST("h2dEventTimeres"), dNdEta, tzero[1]); + } + + // Then we do a second loop to compute the measured quantities with the measured event time + int trackWithTimeIndex = 0; + for (const auto& track : tracks) { + if (!track.has_mcParticle()) // should always be OK but check please + continue; + const auto& mcParticle = track.mcParticle(); + + const auto& trkWithTime = tracksWithTime[trackWithTimeIndex++]; + const float trackLengthRecoInnerTOF = trkWithTime.mTrackLengthInnerTOF.first; + const float trackLengthRecoOuterTOF = trkWithTime.mTrackLengthOuterTOF.first; + const float trackLengthInnerTOF = trkWithTime.mTrackLengthInnerTOF.second; + const float trackLengthOuterTOF = trkWithTime.mTrackLengthOuterTOF.second; + // Todo: remove the bias of the track used in the event time calculation for low multiplicity events + const float measuredTimeInnerTOF = trkWithTime.mInnerTOFTime.first - tzero[0]; + const float measuredTimeOuterTOF = trkWithTime.mOuterTOFTime.first - tzero[0]; + const float momentum = trkWithTime.mMomentum.first; + const float pseudorapidity = trkWithTime.mPseudorapidity.first; + const float noSmearingPt = trkWithTime.mNoSmearingPt; + + // Straight to Nsigma + static std::array expectedTimeInnerTOF, expectedTimeOuterTOF; + static std::array deltaTimeInnerTOF, deltaTimeOuterTOF; + static std::array nSigmaInnerTOF, nSigmaOuterTOF; + static constexpr int kParticlePdgs[kParticles] = {kElectron, kMuonMinus, kPiPlus, kKPlus, kProton}; + float masses[kParticles]; + + if (plotsConfig.doQAplots) { + // unit conversion: length in cm, time in ps + const float innerBeta = (trackLengthInnerTOF / measuredTimeInnerTOF) / o2::constants::physics::LightSpeedCm2PS; + const float outerBeta = (trackLengthOuterTOF / measuredTimeOuterTOF) / o2::constants::physics::LightSpeedCm2PS; + if (trackLengthRecoInnerTOF > 0) { + histos.fill(HIST("h2dVelocityVsMomentumInner"), momentum, innerBeta); + histos.fill(HIST("h2dTrackLengthInnerVsPt"), noSmearingPt, trackLengthInnerTOF); + histos.fill(HIST("h2dTrackLengthInnerRecoVsPt"), noSmearingPt, trackLengthRecoInnerTOF); + } + if (trackLengthRecoOuterTOF > 0) { + histos.fill(HIST("h2dVelocityVsMomentumOuter"), momentum, outerBeta); + histos.fill(HIST("h2dTrackLengthOuterVsPt"), noSmearingPt, trackLengthOuterTOF); + histos.fill(HIST("h2dTrackLengthOuterRecoVsPt"), noSmearingPt, trackLengthRecoOuterTOF); + } + } + + for (int ii = 0; ii < kParticles; ii++) { + nSigmaInnerTOF[ii] = -100; + nSigmaOuterTOF[ii] = -100; + + auto pdgInfoThis = pdg->GetParticle(kParticlePdgs[ii]); + masses[ii] = pdgInfoThis->Mass(); + const float v = particleVelocity(momentum, masses[ii]); + + expectedTimeInnerTOF[ii] = trackLengthInnerTOF / v; + expectedTimeOuterTOF[ii] = trackLengthOuterTOF / v; + + deltaTimeInnerTOF[ii] = measuredTimeInnerTOF - expectedTimeInnerTOF[ii]; + deltaTimeOuterTOF[ii] = measuredTimeOuterTOF - expectedTimeInnerTOF[ii]; + + // Evaluate total sigma (layer + tracking resolution) + float innerTotalTimeReso = simConfig.innerTOFTimeReso; + float outerTotalTimeReso = simConfig.outerTOFTimeReso; + if (simConfig.flagIncludeTrackTimeRes) { + double ptResolution = std::pow(momentum / std::cosh(pseudorapidity), 2) * std::sqrt(trkWithTime.mMomentum.second); + double etaResolution = std::fabs(std::sin(2.0 * std::atan(std::exp(-pseudorapidity)))) * std::sqrt(trkWithTime.mPseudorapidity.second); + if (simConfig.flagTOFLoadDelphesLUTs) { + ptResolution = mSmearer.getAbsPtRes(pdgInfoThis->PdgCode(), dNdEta, pseudorapidity, momentum / std::cosh(pseudorapidity)); + etaResolution = mSmearer.getAbsEtaRes(pdgInfoThis->PdgCode(), dNdEta, pseudorapidity, momentum / std::cosh(pseudorapidity)); + } + float innerTrackTimeReso = calculateTrackTimeResolutionAdvanced(momentum / std::cosh(pseudorapidity), pseudorapidity, ptResolution, etaResolution, masses[ii], simConfig.innerTOFRadius, simConfig.dBz); + float outerTrackTimeReso = calculateTrackTimeResolutionAdvanced(momentum / std::cosh(pseudorapidity), pseudorapidity, ptResolution, etaResolution, masses[ii], simConfig.outerTOFRadius, simConfig.dBz); + innerTotalTimeReso = std::hypot(simConfig.innerTOFTimeReso, innerTrackTimeReso); + outerTotalTimeReso = std::hypot(simConfig.outerTOFTimeReso, outerTrackTimeReso); + + if (plotsConfig.doQAplots) { + if (std::fabs(mcParticle.pdgCode()) == pdg->GetParticle(kParticlePdgs[ii])->PdgCode()) { + if (trackLengthRecoInnerTOF > 0) { + h2dInnerTimeResTrack[ii]->Fill(momentum, innerTrackTimeReso); + h2dInnerTimeResTotal[ii]->Fill(momentum, innerTotalTimeReso); + } + if (trackLengthRecoOuterTOF > 0) { + const float transverseMomentum = momentum / std::cosh(pseudorapidity); + h2dOuterTimeResTrack[ii]->Fill(momentum, outerTrackTimeReso); + h2dOuterTimeResTotal[ii]->Fill(momentum, outerTotalTimeReso); + static constexpr int kIdPion = 2; + if (ii == kIdPion) { + histos.fill(HIST("h2dRelativePtResolution"), transverseMomentum, 100.0 * ptResolution / transverseMomentum); + histos.fill(HIST("h2dRelativeEtaResolution"), pseudorapidity, 100.0 * etaResolution / (std::fabs(pseudorapidity) + 1e-6)); + } + } + } + } + } + + // Fixme: assumes dominant resolution effect is the TOF resolution + // and not the tracking itself. It's *probably* a fair assumption + // but it should be tested further! --> FIXED IN THIS VERSION + if (trackLengthInnerTOF > 0 && trackLengthRecoInnerTOF > 0) + nSigmaInnerTOF[ii] = deltaTimeInnerTOF[ii] / std::sqrt(innerTotalTimeReso * innerTotalTimeReso + tzero[1] * tzero[1]); + if (trackLengthOuterTOF > 0 && trackLengthRecoOuterTOF > 0) + nSigmaOuterTOF[ii] = deltaTimeOuterTOF[ii] / std::sqrt(outerTotalTimeReso * outerTotalTimeReso + tzero[1] * tzero[1]); + } + + if (plotsConfig.doQAplots) { + for (int ii = 0; ii < kParticles; ii++) { + if (std::fabs(mcParticle.pdgCode()) != pdg->GetParticle(kParticlePdgs[ii])->PdgCode()) { + continue; + } + if (trackLengthRecoInnerTOF > 0) { + for (int iii = 0; iii < kParticles; iii++) { + h2dInnerNsigmaTrue[ii][iii]->Fill(momentum, nSigmaInnerTOF[iii]); + h2dInnerDeltaTrue[ii][iii]->Fill(momentum, deltaTimeInnerTOF[iii]); + } + } + if (trackLengthRecoOuterTOF > 0) { + for (int iii = 0; iii < kParticles; iii++) { + h2dOuterNsigmaTrue[ii][iii]->Fill(momentum, nSigmaOuterTOF[iii]); + h2dOuterDeltaTrue[ii][iii]->Fill(momentum, deltaTimeOuterTOF[iii]); + } + } + } + } + + float deltaTrackLengthInnerTOF = std::abs(trackLengthInnerTOF - trackLengthRecoInnerTOF); + if (trackLengthInnerTOF > 0 && trackLengthRecoInnerTOF > 0) { + histos.fill(HIST("h2dDeltaTrackLengthInnerVsPt"), noSmearingPt, deltaTrackLengthInnerTOF); + } + float deltaTrackLengthOuterTOF = std::abs(trackLengthOuterTOF - trackLengthRecoOuterTOF); + if (trackLengthOuterTOF > 0 && trackLengthRecoOuterTOF > 0) { + histos.fill(HIST("h2dDeltaTrackLengthOuterVsPt"), noSmearingPt, deltaTrackLengthOuterTOF); + } + + // Sigmas have been fully calculated. Please populate the NSigma helper table (once per track) + upgradeTof(tzero[0], tzero[1], + nSigmaInnerTOF[0], nSigmaInnerTOF[1], nSigmaInnerTOF[2], nSigmaInnerTOF[3], nSigmaInnerTOF[4], + measuredTimeInnerTOF, trackLengthRecoInnerTOF, + nSigmaOuterTOF[0], nSigmaOuterTOF[1], nSigmaOuterTOF[2], nSigmaOuterTOF[3], nSigmaOuterTOF[4], + measuredTimeOuterTOF, trackLengthRecoOuterTOF); + upgradeTofExpectedTime(expectedTimeInnerTOF[0], expectedTimeInnerTOF[1], expectedTimeInnerTOF[2], expectedTimeInnerTOF[3], expectedTimeInnerTOF[4], + expectedTimeOuterTOF[0], expectedTimeOuterTOF[1], expectedTimeOuterTOF[2], expectedTimeOuterTOF[3], expectedTimeOuterTOF[4]); + } + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{adaptAnalysisTask(cfgc)}; } diff --git a/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx b/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx index 9fa7920d2ac..6806bbca9db 100644 --- a/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx +++ b/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx @@ -561,6 +561,7 @@ struct OnTheFlyTracker { // generate collision time auto ir = irSampler.generateCollisionTime(); + const float eventCollisionTime = ir.timeInBCNS; // First we compute the number of charged particles in the event dNdEta = 0.f; @@ -659,7 +660,7 @@ struct OnTheFlyTracker { isDecayDaughter = true; multiplicityCounter++; - const float t = (ir.timeInBCNS + gRandom->Gaus(0., 100.)) * 1e-3; + const float t = (eventCollisionTime + gRandom->Gaus(0., 100.)) * 1e-3; std::vector xiDaughterTrackParCovsPerfect(3); std::vector xiDaughterTrackParCovsTracked(3); std::vector isReco(3); @@ -1023,7 +1024,7 @@ struct OnTheFlyTracker { primaryVertex.getSigmaX2(), primaryVertex.getSigmaXY(), primaryVertex.getSigmaY2(), primaryVertex.getSigmaXZ(), primaryVertex.getSigmaYZ(), primaryVertex.getSigmaZ2(), 0, primaryVertex.getChi2(), primaryVertex.getNContributors(), - 0, 0); + eventCollisionTime, 0.f); // For the moment the event collision time is taken as the "GEANT" time, the computation of the event time is done a posteriori from the tracks in the OTF TOF PID task collLabels(mcCollision.globalIndex(), 0); collisionsAlice3(dNdEta); // *+~+*+~+*+~+*+~+*+~+*+~+*+~+*+~+*+~+*+~+*+~+*+~+*+~+*+~+* diff --git a/ALICE3/TableProducer/alice3-multicharm.cxx b/ALICE3/TableProducer/alice3-multicharm.cxx index d2ac55f8f11..a6f3933ac20 100644 --- a/ALICE3/TableProducer/alice3-multicharm.cxx +++ b/ALICE3/TableProducer/alice3-multicharm.cxx @@ -69,7 +69,7 @@ using FullTracksExt = soa::Join; using labeledTracks = soa::Join; using tofTracks = soa::Join; using richTracks = soa::Join; -using alice3tracks = soa::Join; +using alice3tracks = soa::Join; struct alice3multicharm { SliceCache cache; @@ -89,6 +89,8 @@ struct alice3multicharm { Configurable piFromXiC_dcaZconstant{"piFromXiC_dcaZconstant", 0.001f, "[0] in |DCAxy| > [0]+[1]/pT"}; Configurable piFromXiC_dcaXYpTdep{"piFromXiC_dcaXYpTdep", 0.0, "[1] in |DCAxy| > [0]+[1]/pT"}; Configurable piFromXiC_dcaZpTdep{"piFromXiC_dcaZpTdep", 0.0, "[1] in |DCAxy| > [0]+[1]/pT"}; + Configurable piFromXiC_tofDiffInner{"piFromXiC_tofDiffInner", 50, "|signal - expected| (ps)"}; + Configurable piFromXiCC_tofDiffInner{"piFromXiCC_tofDiffInner", 50, "|signal - expected| (ps)"}; Configurable piFromXiCC_dcaXYconstant{"piFromXiCC_dcaXYconstant", 0.001f, "[0] in |DCAxy| > [0]+[1]/pT"}; Configurable piFromXiCC_dcaZconstant{"piFromXiCC_dcaZconstant", 0.001f, "[0] in |DCAxy| > [0]+[1]/pT"}; Configurable piFromXiCC_dcaXYpTdep{"piFromXiCC_dcaXYpTdep", 0.0, "[1] in |DCAxy| > [0]+[1]/pT"}; @@ -107,21 +109,27 @@ struct alice3multicharm { Configurable minPiCCPt{"minPiCCPt", 0.3, "Minimum pT for XiCC pions"}; Configurable minNTracks{"minNTracks", -1, "Minimum number of tracks"}; + Configurable minXiRadius{"minXiRadius", 0.5, "Minimum R2D for XiC decay (cm)"}; Configurable minXiCRadius{"minXiCRadius", 0.001, "Minimum R2D for XiC decay (cm)"}; Configurable minXiCCRadius{"minXiCCRadius", 0.005, "Minimum R2D for XiCC decay (cm)"}; + Configurable xicMinDecayDistanceFromPV{"xicMinDecayDistanceFromPV", 0.002, "Minimum distance for XiC decay from PV (cm)"}; Configurable xicMinProperLength{"xicMinProperLength", 0.002, "Minimum proper length for XiC decay (cm)"}; Configurable xicMaxProperLength{"xicMaxProperLength", 0.06, "Minimum proper length for XiC decay (cm)"}; Configurable xiccMinProperLength{"xiccMinProperLength", 0.004, "Minimum proper length for XiCC decay (cm)"}; Configurable xiccMaxProperLength{"xiccMaxProperLength", 999, "Minimum proper length for XiCC decay (cm)"}; - Configurable massWindowXi{"massWindowXi", 0.015, "Mass window around Xi peak"}; - Configurable massWindowXiC{"massWindowXiC", 0.015, "Mass window around XiC peak"}; + Configurable xiccMaxEta{"xiccMaxEta", 1.5, "Max eta"}; + Configurable massWindowXi{"massWindowXi", 0.015, "Mass window around Xi peak (GeV/c)"}; + Configurable massWindowXiC{"massWindowXiC", 0.015, "Mass window around XiC peak (GeV/c)"}; ConfigurableAxis axisEta{"axisEta", {80, -4.0f, +4.0f}, "#eta"}; ConfigurableAxis axisPt{"axisPt", {VARIABLE_WIDTH, 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1.0f, 1.1f, 1.2f, 1.3f, 1.4f, 1.5f, 1.6f, 1.7f, 1.8f, 1.9f, 2.0f, 2.2f, 2.4f, 2.6f, 2.8f, 3.0f, 3.2f, 3.4f, 3.6f, 3.8f, 4.0f, 4.4f, 4.8f, 5.2f, 5.6f, 6.0f, 6.5f, 7.0f, 7.5f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 17.0f, 19.0f, 21.0f, 23.0f, 25.0f, 30.0f, 35.0f, 40.0f, 50.0f}, "pt axis for QA histograms"}; - ConfigurableAxis axisDCA2d{"axisDCA2d", {400, -200, 200}, "DCA2d (#mum)"}; - ConfigurableAxis axisDCA{"axisDCA", {200, 0, 200}, "DCA (#mum)"}; - ConfigurableAxis axisRadius{"axisRadius", {1000, 0, 1000}, "Decay radius (#mum)"}; + ConfigurableAxis axisDCA2D{"axisDCA2D", {400, -200, 200}, "DCA2d (#mum)"}; + ConfigurableAxis axisDCA{"axisDCA", {400, 0, 400}, "DCA (#mum)"}; + ConfigurableAxis axisRadius{"axisRadius", {10000, 0, 10000}, "Decay radius (#mum)"}; + ConfigurableAxis axisRadius2D{"axisRadius2D", {1000, 0, 100000}, "Decay radius (#mum)"}; + ConfigurableAxis axisRadius2DXi{"axisRadius2DXi", {1000, 0, 20}, "Decay radius (cm)"}; ConfigurableAxis axisDecayLength{"axisDecayLength", {2000, 0, 2000}, "Decay lenght (#mum)"}; + ConfigurableAxis axisTOFTrack{"axisTOFTrack", {1000, 0, 5000}, "TOF track time"}; ConfigurableAxis axisXiMass{"axisXiMass", {200, 1.221f, 1.421f}, "Xi Inv Mass (GeV/c^{2})"}; ConfigurableAxis axisXiCMass{"axisXiCMass", {200, 2.368f, 2.568f}, "XiC Inv Mass (GeV/c^{2})"}; @@ -421,12 +429,21 @@ struct alice3multicharm { histos.add("hPi2cPt", "hPi2cPt", kTH1D, {axisPt}); histos.add("hPiccPt", "hPiccPt", kTH1D, {axisPt}); + histos.add("hMinXiDecayRadius", "hMinXiDecayRadius", kTH1D, {axisRadius2DXi}); histos.add("hMinXiCDecayRadius", "hMinXiCDecayRadius", kTH1D, {axisRadius}); histos.add("hMinXiCCDecayRadius", "hMinXiCCDecayRadius", kTH1D, {axisRadius}); + histos.add("hMinxicDecayDistanceFromPV", "hMinxicDecayDistanceFromPV", kTH1D, {axisDecayLength}); histos.add("hProperLengthXiC", "hProperLengthXiC", kTH1D, {axisDecayLength}); histos.add("hProperLengthXiCC", "hProperLengthXiCC", kTH1D, {axisDecayLength}); + histos.add("hInnerTOFTrackTimeRecoPi1c", "hInnerTOFTrackTimeRecoPi1c", kTH1D, {axisTOFTrack}); + histos.add("hInnerTOFTrackTimeRecoPi2c", "hInnerTOFTrackTimeRecoPi2c", kTH1D, {axisTOFTrack}); + histos.add("hInnerTOFTrackTimeRecoPicc", "hInnerTOFTrackTimeRecoPicc", kTH1D, {axisTOFTrack}); + + histos.add("hXiRadiusVsXicRadius", "hXiRadiusVsXicRadius", kTH2D, {axisRadius2D, axisRadius2D}); + histos.add("hXicRadiusVsXiccRadius", "hXicRadiusVsXiccRadius", kTH2D, {axisRadius2D, axisRadius2D}); + // These histograms bookkeep the exact number of combinations attempted // CombinationsXiC: triplets Xi-pi-pi considered per Xi // CombinationsXiCC: doublets XiC-pi considered per XiC @@ -436,9 +453,9 @@ struct alice3multicharm { histos.add("hNTracks", "hNTracks", kTH1D, {{20000, 0, 20000}}); if (doDCAplots) { - histos.add("h2dDCAxyVsPtXiFromXiC", "h2dDCAxyVsPtXiFromXiC", kTH2D, {axisPt, axisDCA2d}); - histos.add("h2dDCAxyVsPtPiFromXiC", "h2dDCAxyVsPtPiFromXiC", kTH2D, {axisPt, axisDCA2d}); - histos.add("h2dDCAxyVsPtPiFromXiCC", "h2dDCAxyVsPtPiFromXiCC", kTH2D, {axisPt, axisDCA2d}); + histos.add("h2dDCAxyVsPtXiFromXiC", "h2dDCAxyVsPtXiFromXiC", kTH2D, {axisPt, axisDCA2D}); + histos.add("h2dDCAxyVsPtPiFromXiC", "h2dDCAxyVsPtPiFromXiC", kTH2D, {axisPt, axisDCA2D}); + histos.add("h2dDCAxyVsPtPiFromXiCC", "h2dDCAxyVsPtPiFromXiCC", kTH2D, {axisPt, axisDCA2D}); } } @@ -503,6 +520,9 @@ struct alice3multicharm { continue; if (std::fabs(xi.dcaXY()) < xiFromXiC_dcaXYconstant || std::fabs(xi.dcaZ()) < xiFromXiC_dcaZconstant) + continue; // likely a primary xi + + if (xiCand.cascRadius() < minXiRadius) continue; for (auto const& pi1c : tracksPiFromXiCgrouped) { @@ -511,19 +531,29 @@ struct alice3multicharm { if (xiCand.posTrackId() == pi1c.globalIndex() || xiCand.negTrackId() == pi1c.globalIndex() || xiCand.bachTrackId() == pi1c.globalIndex()) continue; // avoid using any track that was already used if (pi1c.pt() < minPiCPt) - continue; + continue; // too low momentum + + double pi1cTOFDiffInner = std::fabs(pi1c.innerTOFTrackTimeReco() - pi1c.innerTOFExpectedTimePi()); + if (pi1cTOFDiffInner > piFromXiC_tofDiffInner) + continue; // did not arrive at expected time // second pion from XiC decay for starts here for (auto const& pi2c : tracksPiFromXiCgrouped) { - if (mcSameMotherCheck && !checkSameMother(xi, pi2c)) continue; // keep only if same mother + if (pi1c.globalIndex() >= pi2c.globalIndex()) continue; // avoid same-mother, avoid double-counting + if (xiCand.posTrackId() == pi2c.globalIndex() || xiCand.negTrackId() == pi2c.globalIndex() || xiCand.bachTrackId() == pi2c.globalIndex()) continue; // avoid using any track that was already used + if (pi2c.pt() < minPiCPt) - continue; + continue; // too low momentum + + double pi2cTOFDiffInner = std::fabs(pi2c.innerTOFTrackTimeReco() - pi2c.innerTOFExpectedTimePi()); + if (pi2cTOFDiffInner > piFromXiC_tofDiffInner) + continue; // did not arrive at expected time // if I am here, it means this is a triplet to be considered for XiC vertexing. // will now attempt to build a three-body decay candidate with these three track rows. @@ -535,6 +565,7 @@ struct alice3multicharm { if (std::fabs(thisXiCcandidate.mass - o2::constants::physics::MassXiCPlus) > massWindowXiC) continue; // out of mass region + histos.fill(HIST("hCharmBuilding"), 1.0f); const std::array momentumC = { @@ -547,9 +578,12 @@ struct alice3multicharm { if (xicDecayRadius2D < minXiCRadius) continue; // do not take if radius too small, likely a primary combination + histos.fill(HIST("hXiRadiusVsXicRadius"), xiCand.cascRadius() * 1e+4, xicDecayRadius2D * 1e+4); + if (xicDecayRadius2D > xiCand.cascRadius()) + continue; + o2::dataformats::DCA dcaInfo; float xicdcaXY = 1e+10, xicdcaZ = 1e+10; - ; o2::track::TrackParCov xicTrackCopy(xicTrack); // paranoia o2::vertexing::PVertex primaryVertex; primaryVertex.setXYZ(collision.posX(), collision.posY(), collision.posZ()); @@ -560,7 +594,7 @@ struct alice3multicharm { } if (std::fabs(xicdcaXY) < xiCFromXiCC_dcaXY || std::fabs(xicdcaZ) < xiCFromXiCC_dcaZ) - continue; + continue; // likely a primary xic histos.fill(HIST("hMassXiC"), thisXiCcandidate.mass); @@ -569,10 +603,16 @@ struct alice3multicharm { for (auto const& picc : tracksPiFromXiCCgrouped) { if (mcSameMotherCheck && !checkSameMotherExtra(xi, picc)) continue; + if (xiCand.posTrackId() == picc.globalIndex() || xiCand.negTrackId() == picc.globalIndex() || xiCand.bachTrackId() == picc.globalIndex()) continue; // avoid using any track that was already used + if (picc.pt() < minPiCCPt) - continue; + continue; // too low momentum + + double piccTOFDiffInner = std::fabs(picc.innerTOFTrackTimeReco() - picc.innerTOFExpectedTimePi()); + if (piccTOFDiffInner > piFromXiCC_tofDiffInner) + continue; // did not arrive at expected time o2::track::TrackParCov piccTrack = getTrackParCov(picc); nCombinationsCC++; @@ -591,14 +631,34 @@ struct alice3multicharm { continue; // do not take if radius too small, likely a primary combination double totalMomentumC = std::hypot(momentumC[0], momentumC[1], momentumC[2]); - double xicProperLength = std::fabs(std::hypot(thisXiCcandidate.xyz[0], thisXiCcandidate.xyz[1], thisXiCcandidate.xyz[2]) - std::hypot(thisXiCCcandidate.xyz[0], thisXiCCcandidate.xyz[1], thisXiCCcandidate.xyz[2]) * totalMomentumC) / (std::fabs(totalMomentumC) * thisXiCcandidate.mass); + double decayLengthXiC = std::hypot( + thisXiCcandidate.xyz[0] - thisXiCCcandidate.xyz[0], + thisXiCcandidate.xyz[1] - thisXiCCcandidate.xyz[1], + thisXiCcandidate.xyz[2] - thisXiCCcandidate.xyz[2]); + double xicProperLength = decayLengthXiC * thisXiCcandidate.mass / totalMomentumC; if (xicProperLength < xicMinProperLength || xicProperLength > xicMaxProperLength) - continue; + continue; // likely background + + double xicDistanceFromPV = std::hypot( + thisXiCcandidate.xyz[0] - collision.posX(), + thisXiCcandidate.xyz[1] - collision.posY(), + thisXiCcandidate.xyz[2] - collision.posZ()); + double xicDecayDistanceFromPV = xicDistanceFromPV * thisXiCcandidate.mass / totalMomentumC; + if (xicDecayDistanceFromPV < xicMinDecayDistanceFromPV) + continue; // too close to PV double totalMomentumCC = std::hypot(momentumCC[0], momentumCC[1], momentumCC[2]); - double xiccProperLength = std::fabs(std::hypot(collision.posX(), collision.posY(), collision.posZ()) - std::hypot(thisXiCCcandidate.xyz[0], thisXiCCcandidate.xyz[1], thisXiCCcandidate.xyz[2]) * totalMomentumCC) / (std::fabs(totalMomentumCC) * thisXiCCcandidate.mass); + double decayLengthXiCC = std::hypot( + thisXiCCcandidate.xyz[0] - collision.posX(), + thisXiCCcandidate.xyz[1] - collision.posY(), + thisXiCCcandidate.xyz[2] - collision.posZ()); + double xiccProperLength = decayLengthXiCC * thisXiCCcandidate.mass / totalMomentumCC; if (xiccProperLength < xiccMinProperLength || xiccProperLength > xicMaxProperLength) - continue; + continue; // likely background + + histos.fill(HIST("hXicRadiusVsXiccRadius"), xicDecayRadius2D * 1e+4, xiccDecayRadius2D * 1e+4); + if (xiccDecayRadius2D > xicDecayRadius2D) + continue; // XiCC should decay before XiC float xiccdcaXY = 1e+10, xiccdcaZ = 1e+10; if (xiccTrack.propagateToDCA(primaryVertex, magneticField, &dcaInfo)) { @@ -607,16 +667,24 @@ struct alice3multicharm { } if (std::fabs(xiccdcaXY) > xiCC_dcaXY || std::fabs(xiccdcaZ) > xiCC_dcaZ) - continue; + continue; // not pointing to PV + if (std::fabs(thisXiCcandidate.eta) > xiccMaxEta) + continue; // not in central barrel + + histos.fill(HIST("hMinxicDecayDistanceFromPV"), xicDecayDistanceFromPV * 1e+4); + histos.fill(HIST("hInnerTOFTrackTimeRecoPi1c"), pi1cTOFDiffInner); + histos.fill(HIST("hInnerTOFTrackTimeRecoPi2c"), pi2cTOFDiffInner); + histos.fill(HIST("hInnerTOFTrackTimeRecoPicc"), piccTOFDiffInner); histos.fill(HIST("hDCAXiCDaughters"), thisXiCcandidate.dca * 1e+4); histos.fill(HIST("hDCAXiCCDaughters"), thisXiCCcandidate.dca * 1e+4); histos.fill(HIST("hProperLengthXiCC"), xiccProperLength * 1e+4); histos.fill(HIST("hProperLengthXiC"), xicProperLength * 1e+4); histos.fill(HIST("hMinXiCCDecayRadius"), xiccDecayRadius2D * 1e+4); histos.fill(HIST("hMinXiCDecayRadius"), xicDecayRadius2D * 1e+4); - histos.fill(HIST("hPi2cPt"), pi2c.pt()); + histos.fill(HIST("hMinXiDecayRadius"), xiCand.cascRadius()); histos.fill(HIST("hPi1cPt"), pi1c.pt()); + histos.fill(HIST("hPi2cPt"), pi2c.pt()); histos.fill(HIST("hPiccPt"), picc.pt()); histos.fill(HIST("hDCAxyXi"), std::fabs(xi.dcaXY() * 1e+4)); histos.fill(HIST("hDCAzXi"), std::fabs(xi.dcaZ() * 1e+4)); diff --git a/ALICE3/Tasks/alice3-dilepton.cxx b/ALICE3/Tasks/alice3-dilepton.cxx index ef8d1ff4b53..e3632fc5a02 100644 --- a/ALICE3/Tasks/alice3-dilepton.cxx +++ b/ALICE3/Tasks/alice3-dilepton.cxx @@ -531,9 +531,9 @@ struct Alice3Dilepton { FillPairGen(neg_mcParticles_coll, neg_mcParticles_coll, mcParticles); } // end of mc collision loop - } // end of processGen + } // end of processGen - using MyTracksMC = soa::Join; + using MyTracksMC = soa::Join; // Filter trackFilter = etaMin < o2::aod::track::eta && // o2::aod::track::eta < etaMax && // ptMin < o2::aod::track::pt && @@ -616,7 +616,7 @@ struct Alice3Dilepton { FillPairRec(negTracks_coll, negTracks_coll, mcParticles); } // end of collision loop - } // end of processRec + } // end of processRec PROCESS_SWITCH(Alice3Dilepton, processGen, "Run for generated particle", true); PROCESS_SWITCH(Alice3Dilepton, processRec, "Run for reconstructed track", false); diff --git a/CODEOWNERS b/CODEOWNERS index ecd3c4c9aa7..b8f27eef641 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -41,14 +41,14 @@ /PWGHF @alibuild @vkucera @fcolamar @fgrosa @fcatalan92 @mfaggin @mmazzilli @deepathoms @NicoleBastid @hahassan7 @jpxrk @apalasciano @zhangbiao-phy # PWG-LF /PWGLF @alibuild @njacazio @skundu692 -/PWGLF/Tasks/GlobalEventProperties @alibuild @njacazio @skundu692 @gbencedi @omvazque -/PWGLF/TableProducer/GlobalEventProperties @alibuild @njacazio @skundu692 @gbencedi @omvazque +/PWGLF/Tasks/GlobalEventProperties @alibuild @njacazio @skundu692 @gbencedi @abmodak +/PWGLF/TableProducer/GlobalEventProperties @alibuild @njacazio @skundu692 @gbencedi @abmodak /PWGLF/Tasks/Nuspex @alibuild @njacazio @skundu692 @fmazzasc @chiarapinto @maciacco /PWGLF/TableProducer/Nuspex @alibuild @njacazio @skundu692 @fmazzasc @chiarapinto @maciacco /PWGLF/Tasks/Resonances @alibuild @njacazio @skundu692 @dmallick2 @smaff92 /PWGLF/TableProducer/Resonances @alibuild @njacazio @skundu692 @dmallick2 @smaff92 -/PWGLF/Tasks/Strangeness @alibuild @njacazio @skundu692 @ercolessi @ChiaraDeMartin95 -/PWGLF/TableProducer/Strangeness @alibuild @njacazio @skundu692 @ercolessi @ChiaraDeMartin95 +/PWGLF/Tasks/Strangeness @alibuild @njacazio @skundu692 @ercolessi @romainschotter +/PWGLF/TableProducer/Strangeness @alibuild @njacazio @skundu692 @ercolessi @romainschotter # PWG-MM /PWGMM @alibuild @njacazio @skundu692 @aalkin @@ -65,6 +65,6 @@ /Tutorials/PWGEM @alibuild @mikesas @rbailhac @dsekihat @ivorobye @feisenhu /Tutorials/PWGHF @alibuild @vkucera @fcolamar @fgrosa /Tutorials/PWGJE @alibuild @lhavener @maoyx @nzardosh @mfasDa @fjonasALICE -/Tutorials/PWGLF @alibuild @alcaliva @lbariogl @chiarapinto @BongHwi @lbarnby @mbombara @iravasen @njacazio @ChiaraDeMartin95 @skundu692 +/Tutorials/PWGLF @alibuild @alcaliva @lbariogl @chiarapinto @BongHwi @lbarnby @ercolessi @iravasen @njacazio @romainschotter @skundu692 /Tutorials/PWGMM @alibuild @aalkin @ddobrigk /Tutorials/PWGUD @alibuild @pbuehler diff --git a/Common/CCDB/CMakeLists.txt b/Common/CCDB/CMakeLists.txt index 63584528a38..52f4ec8ffde 100644 --- a/Common/CCDB/CMakeLists.txt +++ b/Common/CCDB/CMakeLists.txt @@ -19,4 +19,5 @@ o2physics_target_root_dictionary(AnalysisCCDB HEADERS EventSelectionParams.h HEADERS TriggerAliases.h HEADERS ctpRateFetcher.h + HEADERS RCTSelectionFlags.h LINKDEF AnalysisCCDBLinkDef.h) diff --git a/Common/DataModel/CMakeLists.txt b/Common/DataModel/CMakeLists.txt index 4891b1a95e9..79e6cba8b5d 100644 --- a/Common/DataModel/CMakeLists.txt +++ b/Common/DataModel/CMakeLists.txt @@ -16,6 +16,9 @@ o2physics_add_header_only_library(DataModel FT0Corrected.h Multiplicity.h PIDResponse.h + PIDResponseITS.h + PIDResponseTOF.h + PIDResponseTPC.h CollisionAssociationTables.h TrackSelectionTables.h McCollisionExtra.h diff --git a/Common/DataModel/PIDResponse.h b/Common/DataModel/PIDResponse.h index 90eb0e55112..eee2e4df2e3 100644 --- a/Common/DataModel/PIDResponse.h +++ b/Common/DataModel/PIDResponse.h @@ -13,802 +13,34 @@ /// \file PIDResponse.h /// \author Nicolò Jacazio nicolo.jacazio@cern.ch /// \brief Set of tables, tasks and utilities to provide the interface between -/// the analysis data model and the PID response +/// the analysis data model and the PID response. This is interim. To be removed /// #ifndef COMMON_DATAMODEL_PIDRESPONSE_H_ #define COMMON_DATAMODEL_PIDRESPONSE_H_ -#include - -// O2 includes -#include "Framework/ASoA.h" -#include "Framework/AnalysisDataModel.h" -#include "ReconstructionDataFormats/PID.h" -#include "Framework/Logger.h" +#include "PIDResponseTOF.h" +#include "PIDResponseTPC.h" +#include "PIDResponseCombined.h" namespace o2::aod { namespace pidutils { -// Function to pack a float into a binned value in table +// Function to pack a float into a binned value in table (interim solution) template void packInTable(const float& valueToBin, T& table) { - if (valueToBin <= binningType::binned_min) { - table(binningType::underflowBin); - } else if (valueToBin >= binningType::binned_max) { - table(binningType::overflowBin); - } else if (valueToBin >= 0) { - table(static_cast((valueToBin / binningType::bin_width) + 0.5f)); - } else { - table(static_cast((valueToBin / binningType::bin_width) - 0.5f)); - } + binningType::packInTable(valueToBin, table); } // Function to unpack a binned value into a float template float unPackInTable(const typename binningType::binned_t& valueToUnpack) { - return binningType::bin_width * static_cast(valueToUnpack); -} - -// Checkers for TOF PID hypothesis availability (runtime) -template -using hasTOFEl = decltype(std::declval().tofNSigmaEl()); -template -using hasTOFMu = decltype(std::declval().tofNSigmaMu()); -template -using hasTOFPi = decltype(std::declval().tofNSigmaPi()); -template -using hasTOFKa = decltype(std::declval().tofNSigmaKa()); -template -using hasTOFPr = decltype(std::declval().tofNSigmaPr()); -template -using hasTOFDe = decltype(std::declval().tofNSigmaDe()); -template -using hasTOFTr = decltype(std::declval().tofNSigmaTr()); -template -using hasTOFHe = decltype(std::declval().tofNSigmaHe()); -template -using hasTOFAl = decltype(std::declval().tofNSigmaAl()); - -// Checkers for TPC PID hypothesis availability (runtime) -template -using hasTPCEl = decltype(std::declval().tpcNSigmaEl()); -template -using hasTPCMu = decltype(std::declval().tpcNSigmaMu()); -template -using hasTPCPi = decltype(std::declval().tpcNSigmaPi()); -template -using hasTPCKa = decltype(std::declval().tpcNSigmaKa()); -template -using hasTPCPr = decltype(std::declval().tpcNSigmaPr()); -template -using hasTPCDe = decltype(std::declval().tpcNSigmaDe()); -template -using hasTPCTr = decltype(std::declval().tpcNSigmaTr()); -template -using hasTPCHe = decltype(std::declval().tpcNSigmaHe()); -template -using hasTPCAl = decltype(std::declval().tpcNSigmaAl()); - -// PID index as template argument -#define PER_SPECIES_WRAPPER(functionName) \ - template \ - auto functionName(const TrackType& track) \ - { \ - if constexpr (index == o2::track::PID::Electron) { \ - return track.functionName##El(); \ - } else if constexpr (index == o2::track::PID::Muon) { \ - return track.functionName##Mu(); \ - } else if constexpr (index == o2::track::PID::Pion) { \ - return track.functionName##Pi(); \ - } else if constexpr (index == o2::track::PID::Kaon) { \ - return track.functionName##Ka(); \ - } else if constexpr (index == o2::track::PID::Proton) { \ - return track.functionName##Pr(); \ - } else if constexpr (index == o2::track::PID::Deuteron) { \ - return track.functionName##De(); \ - } else if constexpr (index == o2::track::PID::Triton) { \ - return track.functionName##Tr(); \ - } else if constexpr (index == o2::track::PID::Helium3) { \ - return track.functionName##He(); \ - } else if constexpr (index == o2::track::PID::Alpha) { \ - return track.functionName##Al(); \ - } \ - } - -PER_SPECIES_WRAPPER(tofNSigma); -PER_SPECIES_WRAPPER(tofExpSigma); -template -auto tofExpSignal(const TrackType& track) -{ - if constexpr (index == o2::track::PID::Electron) { - return track.tofExpSignalEl(track.tofSignal()); - } else if constexpr (index == o2::track::PID::Muon) { - return track.tofExpSignalMu(track.tofSignal()); - } else if constexpr (index == o2::track::PID::Pion) { - return track.tofExpSignalPi(track.tofSignal()); - } else if constexpr (index == o2::track::PID::Kaon) { - return track.tofExpSignalKa(track.tofSignal()); - } else if constexpr (index == o2::track::PID::Proton) { - return track.tofExpSignalPr(track.tofSignal()); - } else if constexpr (index == o2::track::PID::Deuteron) { - return track.tofExpSignalDe(track.tofSignal()); - } else if constexpr (index == o2::track::PID::Triton) { - return track.tofExpSignalTr(track.tofSignal()); - } else if constexpr (index == o2::track::PID::Helium3) { - return track.tofExpSignalHe(track.tofSignal()); - } else if constexpr (index == o2::track::PID::Alpha) { - return track.tofExpSignalAl(track.tofSignal()); - } -} -PER_SPECIES_WRAPPER(tofExpSignalDiff); - -PER_SPECIES_WRAPPER(tpcNSigma); -PER_SPECIES_WRAPPER(tpcExpSigma); -template -auto tpcExpSignal(const TrackType& track) -{ - if constexpr (index == o2::track::PID::Electron) { - return track.tpcExpSignalEl(track.tpcSignal()); - } else if constexpr (index == o2::track::PID::Muon) { - return track.tpcExpSignalMu(track.tpcSignal()); - } else if constexpr (index == o2::track::PID::Pion) { - return track.tpcExpSignalPi(track.tpcSignal()); - } else if constexpr (index == o2::track::PID::Kaon) { - return track.tpcExpSignalKa(track.tpcSignal()); - } else if constexpr (index == o2::track::PID::Proton) { - return track.tpcExpSignalPr(track.tpcSignal()); - } else if constexpr (index == o2::track::PID::Deuteron) { - return track.tpcExpSignalDe(track.tpcSignal()); - } else if constexpr (index == o2::track::PID::Triton) { - return track.tpcExpSignalTr(track.tpcSignal()); - } else if constexpr (index == o2::track::PID::Helium3) { - return track.tpcExpSignalHe(track.tpcSignal()); - } else if constexpr (index == o2::track::PID::Alpha) { - return track.tpcExpSignalAl(track.tpcSignal()); - } -} -PER_SPECIES_WRAPPER(tpcExpSignalDiff); - -#undef PER_SPECIES_WRAPPER - -// PID index as function argument for TOF -#define PER_SPECIES_WRAPPER(functionName) \ - template \ - auto functionName(const o2::track::PID::ID index, const TrackType& track) \ - { \ - switch (index) { \ - case o2::track::PID::Electron: \ - if constexpr (std::experimental::is_detected::value) { \ - return track.functionName##El(); \ - } \ - case o2::track::PID::Muon: \ - if constexpr (std::experimental::is_detected::value) { \ - return track.functionName##Mu(); \ - } \ - case o2::track::PID::Pion: \ - if constexpr (std::experimental::is_detected::value) { \ - return track.functionName##Pi(); \ - } \ - case o2::track::PID::Kaon: \ - if constexpr (std::experimental::is_detected::value) { \ - return track.functionName##Ka(); \ - } \ - case o2::track::PID::Proton: \ - if constexpr (std::experimental::is_detected::value) { \ - return track.functionName##Pr(); \ - } \ - case o2::track::PID::Deuteron: \ - if constexpr (std::experimental::is_detected::value) { \ - return track.functionName##De(); \ - } \ - case o2::track::PID::Triton: \ - if constexpr (std::experimental::is_detected::value) { \ - return track.functionName##Tr(); \ - } \ - case o2::track::PID::Helium3: \ - if constexpr (std::experimental::is_detected::value) { \ - return track.functionName##He(); \ - } \ - case o2::track::PID::Alpha: \ - if constexpr (std::experimental::is_detected::value) { \ - return track.functionName##Al(); \ - } \ - default: \ - LOGF(fatal, "TOF PID table for PID index %i (%s) is not available", index, o2::track::PID::getName(index)); \ - return 0.f; \ - } \ - } - -PER_SPECIES_WRAPPER(tofNSigma); -PER_SPECIES_WRAPPER(tofExpSigma); -template -auto tofExpSignal(const o2::track::PID::ID index, const TrackType& track) -{ - switch (index) { - case o2::track::PID::Electron: - if constexpr (std::experimental::is_detected::value) { - return track.tofExpSignalEl(track.tofSignal()); - } - case o2::track::PID::Muon: - if constexpr (std::experimental::is_detected::value) { - return track.tofExpSignalMu(track.tofSignal()); - } - case o2::track::PID::Pion: - if constexpr (std::experimental::is_detected::value) { - return track.tofExpSignalPi(track.tofSignal()); - } - case o2::track::PID::Kaon: - if constexpr (std::experimental::is_detected::value) { - return track.tofExpSignalKa(track.tofSignal()); - } - case o2::track::PID::Proton: - if constexpr (std::experimental::is_detected::value) { - return track.tofExpSignalPr(track.tofSignal()); - } - case o2::track::PID::Deuteron: - if constexpr (std::experimental::is_detected::value) { - return track.tofExpSignalDe(track.tofSignal()); - } - case o2::track::PID::Triton: - if constexpr (std::experimental::is_detected::value) { - return track.tofExpSignalTr(track.tofSignal()); - } - case o2::track::PID::Helium3: - if constexpr (std::experimental::is_detected::value) { - return track.tofExpSignalHe(track.tofSignal()); - } - case o2::track::PID::Alpha: - if constexpr (std::experimental::is_detected::value) { - return track.tofExpSignalAl(track.tofSignal()); - } - default: - LOGF(fatal, "TOF PID table for PID index %i (%s) is not available", index, o2::track::PID::getName(index)); - return 0.f; - } -} -PER_SPECIES_WRAPPER(tofExpSignalDiff); - -#undef PER_SPECIES_WRAPPER - -// PID index as function argument for TPC -#define PER_SPECIES_WRAPPER(functionName) \ - template \ - auto functionName(const o2::track::PID::ID index, const TrackType& track) \ - { \ - switch (index) { \ - case o2::track::PID::Electron: \ - if constexpr (std::experimental::is_detected::value) { \ - return track.functionName##El(); \ - } \ - case o2::track::PID::Muon: \ - if constexpr (std::experimental::is_detected::value) { \ - return track.functionName##Mu(); \ - } \ - case o2::track::PID::Pion: \ - if constexpr (std::experimental::is_detected::value) { \ - return track.functionName##Pi(); \ - } \ - case o2::track::PID::Kaon: \ - if constexpr (std::experimental::is_detected::value) { \ - return track.functionName##Ka(); \ - } \ - case o2::track::PID::Proton: \ - if constexpr (std::experimental::is_detected::value) { \ - return track.functionName##Pr(); \ - } \ - case o2::track::PID::Deuteron: \ - if constexpr (std::experimental::is_detected::value) { \ - return track.functionName##De(); \ - } \ - case o2::track::PID::Triton: \ - if constexpr (std::experimental::is_detected::value) { \ - return track.functionName##Tr(); \ - } \ - case o2::track::PID::Helium3: \ - if constexpr (std::experimental::is_detected::value) { \ - return track.functionName##He(); \ - } \ - case o2::track::PID::Alpha: \ - if constexpr (std::experimental::is_detected::value) { \ - return track.functionName##Al(); \ - } \ - default: \ - LOGF(fatal, "TPC PID table for PID index %i (%s) is not available", index, o2::track::PID::getName(index)); \ - return 0.f; \ - } \ - } - -PER_SPECIES_WRAPPER(tpcNSigma); -PER_SPECIES_WRAPPER(tpcExpSigma); -template -auto tpcExpSignal(const o2::track::PID::ID index, const TrackType& track) -{ - switch (index) { - case o2::track::PID::Electron: - if constexpr (std::experimental::is_detected::value) { - return track.tpcExpSignalEl(track.tpcSignal()); - } - case o2::track::PID::Muon: - if constexpr (std::experimental::is_detected::value) { - return track.tpcExpSignalMu(track.tpcSignal()); - } - case o2::track::PID::Pion: - if constexpr (std::experimental::is_detected::value) { - return track.tpcExpSignalPi(track.tpcSignal()); - } - case o2::track::PID::Kaon: - if constexpr (std::experimental::is_detected::value) { - return track.tpcExpSignalKa(track.tpcSignal()); - } - case o2::track::PID::Proton: - if constexpr (std::experimental::is_detected::value) { - return track.tpcExpSignalPr(track.tpcSignal()); - } - case o2::track::PID::Deuteron: - if constexpr (std::experimental::is_detected::value) { - return track.tpcExpSignalDe(track.tpcSignal()); - } - case o2::track::PID::Triton: - if constexpr (std::experimental::is_detected::value) { - return track.tpcExpSignalTr(track.tpcSignal()); - } - case o2::track::PID::Helium3: - if constexpr (std::experimental::is_detected::value) { - return track.tpcExpSignalHe(track.tpcSignal()); - } - case o2::track::PID::Alpha: - if constexpr (std::experimental::is_detected::value) { - return track.tpcExpSignalAl(track.tpcSignal()); - } - default: - LOGF(fatal, "TPC PID table for PID index %i (%s) is not available", index, o2::track::PID::getName(index)); - return 0.f; - } + return binningType::unPackInTable(valueToUnpack); } -PER_SPECIES_WRAPPER(tpcExpSignalDiff); - -#undef PER_SPECIES_WRAPPER - } // namespace pidutils - -namespace pidflags -{ - -namespace enums -{ -enum PIDFlags : uint8_t { - EvTimeUndef = 0x0, // Event collision not set, corresponding to the LHC Fill event time - EvTimeTOF = 0x1, // Event collision time from TOF - EvTimeT0AC = 0x2, // Event collision time from the FT0AC - EvTimeTOFT0AC = 0x4 // Event collision time from the TOF and FT0AC -}; -} - -DECLARE_SOA_COLUMN(GoodTOFMatch, goodTOFMatch, bool); //! Bool for the TOF PID information on the single track information -DECLARE_SOA_COLUMN(TOFFlags, tofFlags, uint8_t); //! Flag for the complementary TOF PID information for the event time -DECLARE_SOA_DYNAMIC_COLUMN(IsEvTimeDefined, isEvTimeDefined, //! True if the Event Time was computed with any method i.e. there is a usable event time - [](uint8_t flags) -> bool { return (flags > 0); }); -DECLARE_SOA_DYNAMIC_COLUMN(IsEvTimeTOF, isEvTimeTOF, //! True if the Event Time was computed with the TOF - [](uint8_t flags) -> bool { return (flags & enums::PIDFlags::EvTimeTOF) == enums::PIDFlags::EvTimeTOF; }); -DECLARE_SOA_DYNAMIC_COLUMN(IsEvTimeT0AC, isEvTimeT0AC, //! True if the Event Time was computed with the T0AC - [](uint8_t flags) -> bool { return (flags & enums::PIDFlags::EvTimeT0AC) == enums::PIDFlags::EvTimeT0AC; }); -DECLARE_SOA_DYNAMIC_COLUMN(IsEvTimeTOFT0AC, isEvTimeTOFT0AC, //! True if the Event Time was computed with the TOF and T0AC - [](uint8_t flags) -> bool { return (flags & enums::PIDFlags::EvTimeTOFT0AC) == enums::PIDFlags::EvTimeTOFT0AC; }); - -} // namespace pidflags - -namespace pidtofsignal -{ -DECLARE_SOA_COLUMN(TOFSignal, tofSignal, float); //! TOF signal from track time -DECLARE_SOA_DYNAMIC_COLUMN(EventCollisionTime, eventCollisionTime, //! Event collision time used for the track. Needs the TOF - [](float signal, float tMinusTexp, float texp) -> float { return texp + tMinusTexp - signal; }); - -} // namespace pidtofsignal - -namespace pidtofevtime -{ -DECLARE_SOA_COLUMN(TOFEvTime, tofEvTime, float); //! event time for TOF signal. Can be obtained via a combination of detectors e.g. TOF, FT0A, FT0C -DECLARE_SOA_COLUMN(TOFEvTimeErr, tofEvTimeErr, float); //! event time error for TOF. Can be obtained via a combination of detectors e.g. TOF, FT0A, FT0C -} // namespace pidtofevtime - -namespace pidtofbeta -{ -DECLARE_SOA_COLUMN(Beta, beta, float); //! TOF beta -DECLARE_SOA_COLUMN(BetaError, betaerror, float); //! Uncertainty on the TOF beta -// -DECLARE_SOA_COLUMN(ExpBetaEl, expbetael, float); //! Expected beta of electron -DECLARE_SOA_COLUMN(ExpBetaElError, expbetaelerror, float); //! Expected uncertainty on the beta of electron -// -DECLARE_SOA_COLUMN(SeparationBetaEl, separationbetael, float); //! Separation computed with the expected beta for electrons -DECLARE_SOA_DYNAMIC_COLUMN(DiffBetaEl, diffbetael, //! Difference between the measured and the expected beta for electrons - [](float beta, float expbetael) -> float { return beta - expbetael; }); -} // namespace pidtofbeta - -namespace pidtofmass -{ -DECLARE_SOA_COLUMN(TOFMass, mass, float); //! TOF mass -} // namespace pidtofmass - -namespace pidtof -{ -// Expected times -DECLARE_SOA_DYNAMIC_COLUMN(TOFExpSignalEl, tofExpSignalEl, //! Expected time for electron - [](float nsigma, float sigma, float tofsignal) -> float { return tofsignal - nsigma * sigma; }); -DECLARE_SOA_DYNAMIC_COLUMN(TOFExpSignalMu, tofExpSignalMu, //! Expected time for muon - [](float nsigma, float sigma, float tofsignal) -> float { return tofsignal - nsigma * sigma; }); -DECLARE_SOA_DYNAMIC_COLUMN(TOFExpSignalPi, tofExpSignalPi, //! Expected time for pion - [](float nsigma, float sigma, float tofsignal) -> float { return tofsignal - nsigma * sigma; }); -DECLARE_SOA_DYNAMIC_COLUMN(TOFExpSignalKa, tofExpSignalKa, //! Expected time for kaon - [](float nsigma, float sigma, float tofsignal) -> float { return tofsignal - nsigma * sigma; }); -DECLARE_SOA_DYNAMIC_COLUMN(TOFExpSignalPr, tofExpSignalPr, //! Expected time for proton - [](float nsigma, float sigma, float tofsignal) -> float { return tofsignal - nsigma * sigma; }); -DECLARE_SOA_DYNAMIC_COLUMN(TOFExpSignalDe, tofExpSignalDe, //! Expected time for deuteron - [](float nsigma, float sigma, float tofsignal) -> float { return tofsignal - nsigma * sigma; }); -DECLARE_SOA_DYNAMIC_COLUMN(TOFExpSignalTr, tofExpSignalTr, //! Expected time for triton - [](float nsigma, float sigma, float tofsignal) -> float { return tofsignal - nsigma * sigma; }); -DECLARE_SOA_DYNAMIC_COLUMN(TOFExpSignalHe, tofExpSignalHe, //! Expected time for helium3 - [](float nsigma, float sigma, float tofsignal) -> float { return tofsignal - nsigma * sigma; }); -DECLARE_SOA_DYNAMIC_COLUMN(TOFExpSignalAl, tofExpSignalAl, //! Expected time for alpha - [](float nsigma, float sigma, float tofsignal) -> float { return tofsignal - nsigma * sigma; }); -// Delta with respect to signal -DECLARE_SOA_DYNAMIC_COLUMN(TOFExpSignalDiffEl, tofExpSignalDiffEl, //! Difference between signal and expected for electron - [](float nsigma, float sigma) -> float { return nsigma * sigma; }); -DECLARE_SOA_DYNAMIC_COLUMN(TOFExpSignalDiffMu, tofExpSignalDiffMu, //! Difference between signal and expected for muon - [](float nsigma, float sigma) -> float { return nsigma * sigma; }); -DECLARE_SOA_DYNAMIC_COLUMN(TOFExpSignalDiffPi, tofExpSignalDiffPi, //! Difference between signal and expected for pion - [](float nsigma, float sigma) -> float { return nsigma * sigma; }); -DECLARE_SOA_DYNAMIC_COLUMN(TOFExpSignalDiffKa, tofExpSignalDiffKa, //! Difference between signal and expected for kaon - [](float nsigma, float sigma) -> float { return nsigma * sigma; }); -DECLARE_SOA_DYNAMIC_COLUMN(TOFExpSignalDiffPr, tofExpSignalDiffPr, //! Difference between signal and expected for proton - [](float nsigma, float sigma) -> float { return nsigma * sigma; }); -DECLARE_SOA_DYNAMIC_COLUMN(TOFExpSignalDiffDe, tofExpSignalDiffDe, //! Difference between signal and expected for deuteron - [](float nsigma, float sigma) -> float { return nsigma * sigma; }); -DECLARE_SOA_DYNAMIC_COLUMN(TOFExpSignalDiffTr, tofExpSignalDiffTr, //! Difference between signal and expected for triton - [](float nsigma, float sigma) -> float { return nsigma * sigma; }); -DECLARE_SOA_DYNAMIC_COLUMN(TOFExpSignalDiffHe, tofExpSignalDiffHe, //! Difference between signal and expected for helium3 - [](float nsigma, float sigma) -> float { return nsigma * sigma; }); -DECLARE_SOA_DYNAMIC_COLUMN(TOFExpSignalDiffAl, tofExpSignalDiffAl, //! Difference between signal and expected for alpha - [](float nsigma, float sigma) -> float { return nsigma * sigma; }); -// Expected sigma -DECLARE_SOA_COLUMN(TOFExpSigmaEl, tofExpSigmaEl, float); //! Expected resolution with the TOF detector for electron -DECLARE_SOA_COLUMN(TOFExpSigmaMu, tofExpSigmaMu, float); //! Expected resolution with the TOF detector for muon -DECLARE_SOA_COLUMN(TOFExpSigmaPi, tofExpSigmaPi, float); //! Expected resolution with the TOF detector for pion -DECLARE_SOA_COLUMN(TOFExpSigmaKa, tofExpSigmaKa, float); //! Expected resolution with the TOF detector for kaon -DECLARE_SOA_COLUMN(TOFExpSigmaPr, tofExpSigmaPr, float); //! Expected resolution with the TOF detector for proton -DECLARE_SOA_COLUMN(TOFExpSigmaDe, tofExpSigmaDe, float); //! Expected resolution with the TOF detector for deuteron -DECLARE_SOA_COLUMN(TOFExpSigmaTr, tofExpSigmaTr, float); //! Expected resolution with the TOF detector for triton -DECLARE_SOA_COLUMN(TOFExpSigmaHe, tofExpSigmaHe, float); //! Expected resolution with the TOF detector for helium3 -DECLARE_SOA_COLUMN(TOFExpSigmaAl, tofExpSigmaAl, float); //! Expected resolution with the TOF detector for alpha -// NSigma -DECLARE_SOA_COLUMN(TOFNSigmaEl, tofNSigmaEl, float); //! Nsigma separation with the TOF detector for electron -DECLARE_SOA_COLUMN(TOFNSigmaMu, tofNSigmaMu, float); //! Nsigma separation with the TOF detector for muon -DECLARE_SOA_COLUMN(TOFNSigmaPi, tofNSigmaPi, float); //! Nsigma separation with the TOF detector for pion -DECLARE_SOA_COLUMN(TOFNSigmaKa, tofNSigmaKa, float); //! Nsigma separation with the TOF detector for kaon -DECLARE_SOA_COLUMN(TOFNSigmaPr, tofNSigmaPr, float); //! Nsigma separation with the TOF detector for proton -DECLARE_SOA_COLUMN(TOFNSigmaDe, tofNSigmaDe, float); //! Nsigma separation with the TOF detector for deuteron -DECLARE_SOA_COLUMN(TOFNSigmaTr, tofNSigmaTr, float); //! Nsigma separation with the TOF detector for triton -DECLARE_SOA_COLUMN(TOFNSigmaHe, tofNSigmaHe, float); //! Nsigma separation with the TOF detector for helium3 -DECLARE_SOA_COLUMN(TOFNSigmaAl, tofNSigmaAl, float); //! Nsigma separation with the TOF detector for alpha -} // namespace pidtof - -// Macro to convert the stored Nsigmas to floats -#define DEFINE_UNWRAP_NSIGMA_COLUMN(COLUMN, COLUMN_NAME) \ - DECLARE_SOA_DYNAMIC_COLUMN(COLUMN, COLUMN_NAME, \ - [](binning::binned_t nsigma_binned) -> float { return o2::aod::pidutils::unPackInTable(nsigma_binned); }); - -namespace pidtof_tiny -{ -struct binning { - public: - typedef int8_t binned_t; - static constexpr int nbins = (1 << 8 * sizeof(binned_t)) - 2; - static constexpr binned_t overflowBin = nbins >> 1; - static constexpr binned_t underflowBin = -(nbins >> 1); - static constexpr float binned_max = 6.35; - static constexpr float binned_min = -6.35; - static constexpr float bin_width = (binned_max - binned_min) / nbins; -}; - -// NSigma with reduced size 8 bit -DECLARE_SOA_COLUMN(TOFNSigmaStoreEl, tofNSigmaStoreEl, binning::binned_t); //! Stored binned nsigma with the TOF detector for electron -DECLARE_SOA_COLUMN(TOFNSigmaStoreMu, tofNSigmaStoreMu, binning::binned_t); //! Stored binned nsigma with the TOF detector for muon -DECLARE_SOA_COLUMN(TOFNSigmaStorePi, tofNSigmaStorePi, binning::binned_t); //! Stored binned nsigma with the TOF detector for pion -DECLARE_SOA_COLUMN(TOFNSigmaStoreKa, tofNSigmaStoreKa, binning::binned_t); //! Stored binned nsigma with the TOF detector for kaon -DECLARE_SOA_COLUMN(TOFNSigmaStorePr, tofNSigmaStorePr, binning::binned_t); //! Stored binned nsigma with the TOF detector for proton -DECLARE_SOA_COLUMN(TOFNSigmaStoreDe, tofNSigmaStoreDe, binning::binned_t); //! Stored binned nsigma with the TOF detector for deuteron -DECLARE_SOA_COLUMN(TOFNSigmaStoreTr, tofNSigmaStoreTr, binning::binned_t); //! Stored binned nsigma with the TOF detector for triton -DECLARE_SOA_COLUMN(TOFNSigmaStoreHe, tofNSigmaStoreHe, binning::binned_t); //! Stored binned nsigma with the TOF detector for helium3 -DECLARE_SOA_COLUMN(TOFNSigmaStoreAl, tofNSigmaStoreAl, binning::binned_t); //! Stored binned nsigma with the TOF detector for alpha -// NSigma with reduced size in [binned_min, binned_max] bin size bin_width -DEFINE_UNWRAP_NSIGMA_COLUMN(TOFNSigmaEl, tofNSigmaEl); //! Unwrapped (float) nsigma with the TOF detector for electron -DEFINE_UNWRAP_NSIGMA_COLUMN(TOFNSigmaMu, tofNSigmaMu); //! Unwrapped (float) nsigma with the TOF detector for muon -DEFINE_UNWRAP_NSIGMA_COLUMN(TOFNSigmaPi, tofNSigmaPi); //! Unwrapped (float) nsigma with the TOF detector for pion -DEFINE_UNWRAP_NSIGMA_COLUMN(TOFNSigmaKa, tofNSigmaKa); //! Unwrapped (float) nsigma with the TOF detector for kaon -DEFINE_UNWRAP_NSIGMA_COLUMN(TOFNSigmaPr, tofNSigmaPr); //! Unwrapped (float) nsigma with the TOF detector for proton -DEFINE_UNWRAP_NSIGMA_COLUMN(TOFNSigmaDe, tofNSigmaDe); //! Unwrapped (float) nsigma with the TOF detector for deuteron -DEFINE_UNWRAP_NSIGMA_COLUMN(TOFNSigmaTr, tofNSigmaTr); //! Unwrapped (float) nsigma with the TOF detector for triton -DEFINE_UNWRAP_NSIGMA_COLUMN(TOFNSigmaHe, tofNSigmaHe); //! Unwrapped (float) nsigma with the TOF detector for helium3 -DEFINE_UNWRAP_NSIGMA_COLUMN(TOFNSigmaAl, tofNSigmaAl); //! Unwrapped (float) nsigma with the TOF detector for alpha - -} // namespace pidtof_tiny - -DECLARE_SOA_TABLE(TOFSignal, "AOD", "TOFSignal", //! Table of the TOF signal - pidtofsignal::TOFSignal, - pidtofsignal::EventCollisionTime); - -DECLARE_SOA_TABLE(TOFEvTime, "AOD", "TOFEvTime", //! Table of the TOF event time. One entry per track. - pidtofevtime::TOFEvTime, - pidtofevtime::TOFEvTimeErr); - -DECLARE_SOA_TABLE(pidTOFFlags, "AOD", "pidTOFFlags", //! Table of the flags for TOF signal quality on the track level - pidflags::GoodTOFMatch); - -DECLARE_SOA_TABLE(pidTOFbeta, "AOD", "pidTOFbeta", //! Table of the TOF beta - pidtofbeta::Beta, pidtofbeta::BetaError); - -DECLARE_SOA_TABLE(pidTOFmass, "AOD", "pidTOFmass", //! Table of the TOF mass - pidtofmass::TOFMass); - -DECLARE_SOA_TABLE(pidEvTimeFlags, "AOD", "pidEvTimeFlags", //! Table of the PID flags for the event time tables - pidflags::TOFFlags, - pidflags::IsEvTimeDefined, - pidflags::IsEvTimeTOF, - pidflags::IsEvTimeT0AC, - pidflags::IsEvTimeTOFT0AC); - -// Per particle tables -DECLARE_SOA_TABLE(pidTOFFullEl, "AOD", "pidTOFFullEl", //! Table of the TOF (full) response with expected signal, expected resolution and Nsigma for electron - pidtof::TOFExpSignalDiffEl, - pidtof::TOFExpSignalEl, - pidtof::TOFExpSigmaEl, pidtof::TOFNSigmaEl); -DECLARE_SOA_TABLE(pidTOFFullMu, "AOD", "pidTOFFullMu", //! Table of the TOF (full) response with expected signal, expected resolution and Nsigma for muon - pidtof::TOFExpSignalDiffMu, - pidtof::TOFExpSignalMu, - pidtof::TOFExpSigmaMu, pidtof::TOFNSigmaMu); -DECLARE_SOA_TABLE(pidTOFFullPi, "AOD", "pidTOFFullPi", //! Table of the TOF (full) response with expected signal, expected resolution and Nsigma for pion - pidtof::TOFExpSignalDiffPi, - pidtof::TOFExpSignalPi, - pidtof::TOFExpSigmaPi, pidtof::TOFNSigmaPi); -DECLARE_SOA_TABLE(pidTOFFullKa, "AOD", "pidTOFFullKa", //! Table of the TOF (full) response with expected signal, expected resolution and Nsigma for kaon - pidtof::TOFExpSignalDiffKa, - pidtof::TOFExpSignalKa, - pidtof::TOFExpSigmaKa, pidtof::TOFNSigmaKa); -DECLARE_SOA_TABLE(pidTOFFullPr, "AOD", "pidTOFFullPr", //! Table of the TOF (full) response with expected signal, expected resolution and Nsigma for proton - pidtof::TOFExpSignalDiffPr, - pidtof::TOFExpSignalPr, - pidtof::TOFExpSigmaPr, pidtof::TOFNSigmaPr); -DECLARE_SOA_TABLE(pidTOFFullDe, "AOD", "pidTOFFullDe", //! Table of the TOF (full) response with expected signal, expected resolution and Nsigma for deuteron - pidtof::TOFExpSignalDiffDe, - pidtof::TOFExpSignalDe, - pidtof::TOFExpSigmaDe, pidtof::TOFNSigmaDe); -DECLARE_SOA_TABLE(pidTOFFullTr, "AOD", "pidTOFFullTr", //! Table of the TOF (full) response with expected signal, expected resolution and Nsigma for triton - pidtof::TOFExpSignalDiffTr, - pidtof::TOFExpSignalTr, - pidtof::TOFExpSigmaTr, pidtof::TOFNSigmaTr); -DECLARE_SOA_TABLE(pidTOFFullHe, "AOD", "pidTOFFullHe", //! Table of the TOF (full) response with expected signal, expected resolution and Nsigma for helium3 - pidtof::TOFExpSignalDiffHe, - pidtof::TOFExpSignalHe, - pidtof::TOFExpSigmaHe, pidtof::TOFNSigmaHe); -DECLARE_SOA_TABLE(pidTOFFullAl, "AOD", "pidTOFFullAl", //! Table of the TOF (full) response with expected signal, expected resolution and Nsigma for alpha - pidtof::TOFExpSignalDiffAl, - pidtof::TOFExpSignalAl, - pidtof::TOFExpSigmaAl, pidtof::TOFNSigmaAl); - -// Tiny size tables -DECLARE_SOA_TABLE(pidTOFEl, "AOD", "pidTOFEl", //! Table of the TOF response with binned Nsigma for electron - pidtof_tiny::TOFNSigmaStoreEl, pidtof_tiny::TOFNSigmaEl); -DECLARE_SOA_TABLE(pidTOFMu, "AOD", "pidTOFMu", //! Table of the TOF response with binned Nsigma for muon - pidtof_tiny::TOFNSigmaStoreMu, pidtof_tiny::TOFNSigmaMu); -DECLARE_SOA_TABLE(pidTOFPi, "AOD", "pidTOFPi", //! Table of the TOF response with binned Nsigma for pion - pidtof_tiny::TOFNSigmaStorePi, pidtof_tiny::TOFNSigmaPi); -DECLARE_SOA_TABLE(pidTOFKa, "AOD", "pidTOFKa", //! Table of the TOF response with binned Nsigma for kaon - pidtof_tiny::TOFNSigmaStoreKa, pidtof_tiny::TOFNSigmaKa); -DECLARE_SOA_TABLE(pidTOFPr, "AOD", "pidTOFPr", //! Table of the TOF response with binned Nsigma for proton - pidtof_tiny::TOFNSigmaStorePr, pidtof_tiny::TOFNSigmaPr); -DECLARE_SOA_TABLE(pidTOFDe, "AOD", "pidTOFDe", //! Table of the TOF response with binned Nsigma for deuteron - pidtof_tiny::TOFNSigmaStoreDe, pidtof_tiny::TOFNSigmaDe); -DECLARE_SOA_TABLE(pidTOFTr, "AOD", "pidTOFTr", //! Table of the TOF response with binned Nsigma for triton - pidtof_tiny::TOFNSigmaStoreTr, pidtof_tiny::TOFNSigmaTr); -DECLARE_SOA_TABLE(pidTOFHe, "AOD", "pidTOFHe", //! Table of the TOF response with binned Nsigma for helium3 - pidtof_tiny::TOFNSigmaStoreHe, pidtof_tiny::TOFNSigmaHe); -DECLARE_SOA_TABLE(pidTOFAl, "AOD", "pidTOFAl", //! Table of the TOF response with binned Nsigma for alpha - pidtof_tiny::TOFNSigmaStoreAl, pidtof_tiny::TOFNSigmaAl); - -namespace mcpidtpc -{ -// Tuned MC on data -DECLARE_SOA_COLUMN(DeDxTunedMc, mcTunedTPCSignal, float); //! TPC signal after TuneOnData application for MC -} // namespace mcpidtpc - -DECLARE_SOA_TABLE(mcTPCTuneOnData, "AOD", "MCTPCTUNEONDATA", mcpidtpc::DeDxTunedMc); - -namespace pidtpc -{ -// Expected signals -DECLARE_SOA_DYNAMIC_COLUMN(TPCExpSignalEl, tpcExpSignalEl, //! Expected signal with the TPC detector for electron - [](float nsigma, float sigma, float tpcsignal) -> float { return tpcsignal - nsigma * sigma; }); -DECLARE_SOA_DYNAMIC_COLUMN(TPCExpSignalMu, tpcExpSignalMu, //! Expected signal with the TPC detector for muon - [](float nsigma, float sigma, float tpcsignal) -> float { return tpcsignal - nsigma * sigma; }); -DECLARE_SOA_DYNAMIC_COLUMN(TPCExpSignalPi, tpcExpSignalPi, //! Expected signal with the TPC detector for pion - [](float nsigma, float sigma, float tpcsignal) -> float { return tpcsignal - nsigma * sigma; }); -DECLARE_SOA_DYNAMIC_COLUMN(TPCExpSignalKa, tpcExpSignalKa, //! Expected signal with the TPC detector for kaon - [](float nsigma, float sigma, float tpcsignal) -> float { return tpcsignal - nsigma * sigma; }); -DECLARE_SOA_DYNAMIC_COLUMN(TPCExpSignalPr, tpcExpSignalPr, //! Expected signal with the TPC detector for proton - [](float nsigma, float sigma, float tpcsignal) -> float { return tpcsignal - nsigma * sigma; }); -DECLARE_SOA_DYNAMIC_COLUMN(TPCExpSignalDe, tpcExpSignalDe, //! Expected signal with the TPC detector for deuteron - [](float nsigma, float sigma, float tpcsignal) -> float { return tpcsignal - nsigma * sigma; }); -DECLARE_SOA_DYNAMIC_COLUMN(TPCExpSignalTr, tpcExpSignalTr, //! Expected signal with the TPC detector for triton - [](float nsigma, float sigma, float tpcsignal) -> float { return tpcsignal - nsigma * sigma; }); -DECLARE_SOA_DYNAMIC_COLUMN(TPCExpSignalHe, tpcExpSignalHe, //! Expected signal with the TPC detector for helium3 - [](float nsigma, float sigma, float tpcsignal) -> float { return tpcsignal - nsigma * sigma; }); -DECLARE_SOA_DYNAMIC_COLUMN(TPCExpSignalAl, tpcExpSignalAl, //! Expected signal with the TPC detector for alpha - [](float nsigma, float sigma, float tpcsignal) -> float { return tpcsignal - nsigma * sigma; }); -// Expected signals difference -DECLARE_SOA_DYNAMIC_COLUMN(TPCExpSignalDiffEl, tpcExpSignalDiffEl, //! Difference between signal and expected for electron - [](float nsigma, float sigma) -> float { return nsigma * sigma; }); -DECLARE_SOA_DYNAMIC_COLUMN(TPCExpSignalDiffMu, tpcExpSignalDiffMu, //! Difference between signal and expected for muon - [](float nsigma, float sigma) -> float { return nsigma * sigma; }); -DECLARE_SOA_DYNAMIC_COLUMN(TPCExpSignalDiffPi, tpcExpSignalDiffPi, //! Difference between signal and expected for pion - [](float nsigma, float sigma) -> float { return nsigma * sigma; }); -DECLARE_SOA_DYNAMIC_COLUMN(TPCExpSignalDiffKa, tpcExpSignalDiffKa, //! Difference between signal and expected for kaon - [](float nsigma, float sigma) -> float { return nsigma * sigma; }); -DECLARE_SOA_DYNAMIC_COLUMN(TPCExpSignalDiffPr, tpcExpSignalDiffPr, //! Difference between signal and expected for proton - [](float nsigma, float sigma) -> float { return nsigma * sigma; }); -DECLARE_SOA_DYNAMIC_COLUMN(TPCExpSignalDiffDe, tpcExpSignalDiffDe, //! Difference between signal and expected for deuteron - [](float nsigma, float sigma) -> float { return nsigma * sigma; }); -DECLARE_SOA_DYNAMIC_COLUMN(TPCExpSignalDiffTr, tpcExpSignalDiffTr, //! Difference between signal and expected for triton - [](float nsigma, float sigma) -> float { return nsigma * sigma; }); -DECLARE_SOA_DYNAMIC_COLUMN(TPCExpSignalDiffHe, tpcExpSignalDiffHe, //! Difference between signal and expected for helium3 - [](float nsigma, float sigma) -> float { return nsigma * sigma; }); -DECLARE_SOA_DYNAMIC_COLUMN(TPCExpSignalDiffAl, tpcExpSignalDiffAl, //! Difference between signal and expected for alpha - [](float nsigma, float sigma) -> float { return nsigma * sigma; }); -// Expected sigma -DECLARE_SOA_COLUMN(TPCExpSigmaEl, tpcExpSigmaEl, float); //! Expected resolution with the TPC detector for electron -DECLARE_SOA_COLUMN(TPCExpSigmaMu, tpcExpSigmaMu, float); //! Expected resolution with the TPC detector for muon -DECLARE_SOA_COLUMN(TPCExpSigmaPi, tpcExpSigmaPi, float); //! Expected resolution with the TPC detector for pion -DECLARE_SOA_COLUMN(TPCExpSigmaKa, tpcExpSigmaKa, float); //! Expected resolution with the TPC detector for kaon -DECLARE_SOA_COLUMN(TPCExpSigmaPr, tpcExpSigmaPr, float); //! Expected resolution with the TPC detector for proton -DECLARE_SOA_COLUMN(TPCExpSigmaDe, tpcExpSigmaDe, float); //! Expected resolution with the TPC detector for deuteron -DECLARE_SOA_COLUMN(TPCExpSigmaTr, tpcExpSigmaTr, float); //! Expected resolution with the TPC detector for triton -DECLARE_SOA_COLUMN(TPCExpSigmaHe, tpcExpSigmaHe, float); //! Expected resolution with the TPC detector for helium3 -DECLARE_SOA_COLUMN(TPCExpSigmaAl, tpcExpSigmaAl, float); //! Expected resolution with the TPC detector for alpha -// NSigma -DECLARE_SOA_COLUMN(TPCNSigmaEl, tpcNSigmaEl, float); //! Nsigma separation with the TPC detector for electron -DECLARE_SOA_COLUMN(TPCNSigmaMu, tpcNSigmaMu, float); //! Nsigma separation with the TPC detector for muon -DECLARE_SOA_COLUMN(TPCNSigmaPi, tpcNSigmaPi, float); //! Nsigma separation with the TPC detector for pion -DECLARE_SOA_COLUMN(TPCNSigmaKa, tpcNSigmaKa, float); //! Nsigma separation with the TPC detector for kaon -DECLARE_SOA_COLUMN(TPCNSigmaPr, tpcNSigmaPr, float); //! Nsigma separation with the TPC detector for proton -DECLARE_SOA_COLUMN(TPCNSigmaDe, tpcNSigmaDe, float); //! Nsigma separation with the TPC detector for deuteron -DECLARE_SOA_COLUMN(TPCNSigmaTr, tpcNSigmaTr, float); //! Nsigma separation with the TPC detector for triton -DECLARE_SOA_COLUMN(TPCNSigmaHe, tpcNSigmaHe, float); //! Nsigma separation with the TPC detector for helium3 -DECLARE_SOA_COLUMN(TPCNSigmaAl, tpcNSigmaAl, float); //! Nsigma separation with the TPC detector for alpha - -} // namespace pidtpc - -namespace pidtpc_tiny -{ - -struct binning { - public: - typedef int8_t binned_t; - static constexpr int nbins = (1 << 8 * sizeof(binned_t)) - 2; - static constexpr binned_t overflowBin = nbins >> 1; - static constexpr binned_t underflowBin = -(nbins >> 1); - static constexpr float binned_max = 6.35; - static constexpr float binned_min = -6.35; - static constexpr float bin_width = (binned_max - binned_min) / nbins; -}; - -// NSigma with reduced size -DECLARE_SOA_COLUMN(TPCNSigmaStoreEl, tpcNSigmaStoreEl, binning::binned_t); //! Stored binned nsigma with the TPC detector for electron -DECLARE_SOA_COLUMN(TPCNSigmaStoreMu, tpcNSigmaStoreMu, binning::binned_t); //! Stored binned nsigma with the TPC detector for muon -DECLARE_SOA_COLUMN(TPCNSigmaStorePi, tpcNSigmaStorePi, binning::binned_t); //! Stored binned nsigma with the TPC detector for pion -DECLARE_SOA_COLUMN(TPCNSigmaStoreKa, tpcNSigmaStoreKa, binning::binned_t); //! Stored binned nsigma with the TPC detector for kaon -DECLARE_SOA_COLUMN(TPCNSigmaStorePr, tpcNSigmaStorePr, binning::binned_t); //! Stored binned nsigma with the TPC detector for proton -DECLARE_SOA_COLUMN(TPCNSigmaStoreDe, tpcNSigmaStoreDe, binning::binned_t); //! Stored binned nsigma with the TPC detector for deuteron -DECLARE_SOA_COLUMN(TPCNSigmaStoreTr, tpcNSigmaStoreTr, binning::binned_t); //! Stored binned nsigma with the TPC detector for triton -DECLARE_SOA_COLUMN(TPCNSigmaStoreHe, tpcNSigmaStoreHe, binning::binned_t); //! Stored binned nsigma with the TPC detector for helium3 -DECLARE_SOA_COLUMN(TPCNSigmaStoreAl, tpcNSigmaStoreAl, binning::binned_t); //! Stored binned nsigma with the TPC detector for alpha -// NSigma with reduced size in [binned_min, binned_max] bin size bin_width -DEFINE_UNWRAP_NSIGMA_COLUMN(TPCNSigmaEl, tpcNSigmaEl); //! Unwrapped (float) nsigma with the TPC detector for electron -DEFINE_UNWRAP_NSIGMA_COLUMN(TPCNSigmaMu, tpcNSigmaMu); //! Unwrapped (float) nsigma with the TPC detector for muon -DEFINE_UNWRAP_NSIGMA_COLUMN(TPCNSigmaPi, tpcNSigmaPi); //! Unwrapped (float) nsigma with the TPC detector for pion -DEFINE_UNWRAP_NSIGMA_COLUMN(TPCNSigmaKa, tpcNSigmaKa); //! Unwrapped (float) nsigma with the TPC detector for kaon -DEFINE_UNWRAP_NSIGMA_COLUMN(TPCNSigmaPr, tpcNSigmaPr); //! Unwrapped (float) nsigma with the TPC detector for proton -DEFINE_UNWRAP_NSIGMA_COLUMN(TPCNSigmaDe, tpcNSigmaDe); //! Unwrapped (float) nsigma with the TPC detector for deuteron -DEFINE_UNWRAP_NSIGMA_COLUMN(TPCNSigmaTr, tpcNSigmaTr); //! Unwrapped (float) nsigma with the TPC detector for triton -DEFINE_UNWRAP_NSIGMA_COLUMN(TPCNSigmaHe, tpcNSigmaHe); //! Unwrapped (float) nsigma with the TPC detector for helium3 -DEFINE_UNWRAP_NSIGMA_COLUMN(TPCNSigmaAl, tpcNSigmaAl); //! Unwrapped (float) nsigma with the TPC detector for alpha - -} // namespace pidtpc_tiny - -// Per particle tables -DECLARE_SOA_TABLE(pidTPCFullEl, "AOD", "pidTPCFullEl", //! Table of the TPC (full) response with expected signal, expected resolution and Nsigma for electron - pidtpc::TPCExpSignalEl, pidtpc::TPCExpSignalDiffEl, pidtpc::TPCExpSigmaEl, pidtpc::TPCNSigmaEl); -DECLARE_SOA_TABLE(pidTPCFullMu, "AOD", "pidTPCFullMu", //! Table of the TPC (full) response with expected signal, expected resolution and Nsigma for muon - pidtpc::TPCExpSignalMu, pidtpc::TPCExpSignalDiffMu, pidtpc::TPCExpSigmaMu, pidtpc::TPCNSigmaMu); -DECLARE_SOA_TABLE(pidTPCFullPi, "AOD", "pidTPCFullPi", //! Table of the TPC (full) response with expected signal, expected resolution and Nsigma for pion - pidtpc::TPCExpSignalPi, pidtpc::TPCExpSignalDiffPi, pidtpc::TPCExpSigmaPi, pidtpc::TPCNSigmaPi); -DECLARE_SOA_TABLE(pidTPCFullKa, "AOD", "pidTPCFullKa", //! Table of the TPC (full) response with expected signal, expected resolution and Nsigma for kaon - pidtpc::TPCExpSignalKa, pidtpc::TPCExpSignalDiffKa, pidtpc::TPCExpSigmaKa, pidtpc::TPCNSigmaKa); -DECLARE_SOA_TABLE(pidTPCFullPr, "AOD", "pidTPCFullPr", //! Table of the TPC (full) response with expected signal, expected resolution and Nsigma for proton - pidtpc::TPCExpSignalPr, pidtpc::TPCExpSignalDiffPr, pidtpc::TPCExpSigmaPr, pidtpc::TPCNSigmaPr); -DECLARE_SOA_TABLE(pidTPCFullDe, "AOD", "pidTPCFullDe", //! Table of the TPC (full) response with expected signal, expected resolution and Nsigma for deuteron - pidtpc::TPCExpSignalDe, pidtpc::TPCExpSignalDiffDe, pidtpc::TPCExpSigmaDe, pidtpc::TPCNSigmaDe); -DECLARE_SOA_TABLE(pidTPCFullTr, "AOD", "pidTPCFullTr", //! Table of the TPC (full) response with expected signal, expected resolution and Nsigma for triton - pidtpc::TPCExpSignalTr, pidtpc::TPCExpSignalDiffTr, pidtpc::TPCExpSigmaTr, pidtpc::TPCNSigmaTr); -DECLARE_SOA_TABLE(pidTPCFullHe, "AOD", "pidTPCFullHe", //! Table of the TPC (full) response with expected signal, expected resolution and Nsigma for helium3 - pidtpc::TPCExpSignalHe, pidtpc::TPCExpSignalDiffHe, pidtpc::TPCExpSigmaHe, pidtpc::TPCNSigmaHe); -DECLARE_SOA_TABLE(pidTPCFullAl, "AOD", "pidTPCFullAl", //! Table of the TPC (full) response with expected signal, expected resolution and Nsigma for alpha - pidtpc::TPCExpSignalAl, pidtpc::TPCExpSignalDiffAl, pidtpc::TPCExpSigmaAl, pidtpc::TPCNSigmaAl); - -// Tiny size tables -DECLARE_SOA_TABLE(pidTPCEl, "AOD", "pidTPCEl", //! Table of the TPC response with binned Nsigma for electron - pidtpc_tiny::TPCNSigmaStoreEl, pidtpc_tiny::TPCNSigmaEl); -DECLARE_SOA_TABLE(pidTPCMu, "AOD", "pidTPCMu", //! Table of the TPC response with binned Nsigma for muon - pidtpc_tiny::TPCNSigmaStoreMu, pidtpc_tiny::TPCNSigmaMu); -DECLARE_SOA_TABLE(pidTPCPi, "AOD", "pidTPCPi", //! Table of the TPC response with binned Nsigma for pion - pidtpc_tiny::TPCNSigmaStorePi, pidtpc_tiny::TPCNSigmaPi); -DECLARE_SOA_TABLE(pidTPCKa, "AOD", "pidTPCKa", //! Table of the TPC response with binned Nsigma for kaon - pidtpc_tiny::TPCNSigmaStoreKa, pidtpc_tiny::TPCNSigmaKa); -DECLARE_SOA_TABLE(pidTPCPr, "AOD", "pidTPCPr", //! Table of the TPC response with binned Nsigma for proton - pidtpc_tiny::TPCNSigmaStorePr, pidtpc_tiny::TPCNSigmaPr); -DECLARE_SOA_TABLE(pidTPCDe, "AOD", "pidTPCDe", //! Table of the TPC response with binned Nsigma for deuteron - pidtpc_tiny::TPCNSigmaStoreDe, pidtpc_tiny::TPCNSigmaDe); -DECLARE_SOA_TABLE(pidTPCTr, "AOD", "pidTPCTr", //! Table of the TPC response with binned Nsigma for triton - pidtpc_tiny::TPCNSigmaStoreTr, pidtpc_tiny::TPCNSigmaTr); -DECLARE_SOA_TABLE(pidTPCHe, "AOD", "pidTPCHe", //! Table of the TPC response with binned Nsigma for helium3 - pidtpc_tiny::TPCNSigmaStoreHe, pidtpc_tiny::TPCNSigmaHe); -DECLARE_SOA_TABLE(pidTPCAl, "AOD", "pidTPCAl", //! Table of the TPC response with binned Nsigma for alpha - pidtpc_tiny::TPCNSigmaStoreAl, pidtpc_tiny::TPCNSigmaAl); - -#undef DEFINE_UNWRAP_NSIGMA_COLUMN - -namespace pidbayes -{ -typedef int8_t binned_prob_t; -// Bayesian probabilities with reduced size -DECLARE_SOA_COLUMN(BayesEl, bayesEl, binned_prob_t); //! Bayesian probability for electron expressed in % -DECLARE_SOA_COLUMN(BayesMu, bayesMu, binned_prob_t); //! Bayesian probability for muon expressed in % -DECLARE_SOA_COLUMN(BayesPi, bayesPi, binned_prob_t); //! Bayesian probability for pion expressed in % -DECLARE_SOA_COLUMN(BayesKa, bayesKa, binned_prob_t); //! Bayesian probability for kaon expressed in % -DECLARE_SOA_COLUMN(BayesPr, bayesPr, binned_prob_t); //! Bayesian probability for proton expressed in % -DECLARE_SOA_COLUMN(BayesDe, bayesDe, binned_prob_t); //! Bayesian probability for deuteron expressed in % -DECLARE_SOA_COLUMN(BayesTr, bayesTr, binned_prob_t); //! Bayesian probability for triton expressed in % -DECLARE_SOA_COLUMN(BayesHe, bayesHe, binned_prob_t); //! Bayesian probability for helium3 expressed in % -DECLARE_SOA_COLUMN(BayesAl, bayesAl, binned_prob_t); //! Bayesian probability for alpha expressed in % -DECLARE_SOA_COLUMN(BayesProb, bayesProb, binned_prob_t); //! Bayesian probability of the most probable ID -DECLARE_SOA_COLUMN(BayesID, bayesID, o2::track::pid_constants::ID); //! Most probable ID - -} // namespace pidbayes - -// Table for each particle hypothesis -DECLARE_SOA_TABLE(pidBayesEl, "AOD", "pidBayesEl", //! Binned (in percentage) Bayesian probability of having a Electron - pidbayes::BayesEl); -DECLARE_SOA_TABLE(pidBayesMu, "AOD", "pidBayesMu", //! Binned (in percentage) Bayesian probability of having a Muon - pidbayes::BayesMu); -DECLARE_SOA_TABLE(pidBayesPi, "AOD", "pidBayesPi", //! Binned (in percentage) Bayesian probability of having a Pion - pidbayes::BayesPi); -DECLARE_SOA_TABLE(pidBayesKa, "AOD", "pidBayesKa", //! Binned (in percentage) Bayesian probability of having a Kaon - pidbayes::BayesKa); -DECLARE_SOA_TABLE(pidBayesPr, "AOD", "pidBayesPr", //! Binned (in percentage) Bayesian probability of having a Proton - pidbayes::BayesPr); -DECLARE_SOA_TABLE(pidBayesDe, "AOD", "pidBayesDe", //! Binned (in percentage) Bayesian probability of having a Deuteron - pidbayes::BayesDe); -DECLARE_SOA_TABLE(pidBayesTr, "AOD", "pidBayesTr", //! Binned (in percentage) Bayesian probability of having a Triton - pidbayes::BayesTr); -DECLARE_SOA_TABLE(pidBayesHe, "AOD", "pidBayesHe", //! Binned (in percentage) Bayesian probability of having a Helium3 - pidbayes::BayesHe); -DECLARE_SOA_TABLE(pidBayesAl, "AOD", "pidBayesAl", //! Binned (in percentage) Bayesian probability of having a Alpha - pidbayes::BayesAl); - -// Table for the most probable particle -DECLARE_SOA_TABLE(pidBayes, "AOD", "pidBayes", pidbayes::BayesProb, pidbayes::BayesID); //! Index of the most probable ID and its bayesian probability - } // namespace o2::aod #endif // COMMON_DATAMODEL_PIDRESPONSE_H_ diff --git a/Common/DataModel/PIDResponseCombined.h b/Common/DataModel/PIDResponseCombined.h new file mode 100644 index 00000000000..4b54d214838 --- /dev/null +++ b/Common/DataModel/PIDResponseCombined.h @@ -0,0 +1,76 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// 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. + +/// +/// \file PIDResponseCombined.h +/// \author Nicolò Jacazio nicolo.jacazio@cern.ch +/// \brief Set of tables, tasks and utilities to provide the interface between +/// the analysis data model and the combined PID response +/// + +#ifndef COMMON_DATAMODEL_PIDRESPONSECOMBINED_H_ +#define COMMON_DATAMODEL_PIDRESPONSECOMBINED_H_ + +#include + +// O2 includes +#include "Framework/ASoA.h" +#include "Framework/AnalysisDataModel.h" +#include "ReconstructionDataFormats/PID.h" +#include "Framework/Logger.h" + +namespace o2::aod +{ + +namespace pidbayes +{ +typedef int8_t binned_prob_t; +// Bayesian probabilities with reduced size +DECLARE_SOA_COLUMN(BayesEl, bayesEl, binned_prob_t); //! Bayesian probability for electron expressed in % +DECLARE_SOA_COLUMN(BayesMu, bayesMu, binned_prob_t); //! Bayesian probability for muon expressed in % +DECLARE_SOA_COLUMN(BayesPi, bayesPi, binned_prob_t); //! Bayesian probability for pion expressed in % +DECLARE_SOA_COLUMN(BayesKa, bayesKa, binned_prob_t); //! Bayesian probability for kaon expressed in % +DECLARE_SOA_COLUMN(BayesPr, bayesPr, binned_prob_t); //! Bayesian probability for proton expressed in % +DECLARE_SOA_COLUMN(BayesDe, bayesDe, binned_prob_t); //! Bayesian probability for deuteron expressed in % +DECLARE_SOA_COLUMN(BayesTr, bayesTr, binned_prob_t); //! Bayesian probability for triton expressed in % +DECLARE_SOA_COLUMN(BayesHe, bayesHe, binned_prob_t); //! Bayesian probability for helium3 expressed in % +DECLARE_SOA_COLUMN(BayesAl, bayesAl, binned_prob_t); //! Bayesian probability for alpha expressed in % +DECLARE_SOA_COLUMN(BayesProb, bayesProb, binned_prob_t); //! Bayesian probability of the most probable ID +DECLARE_SOA_COLUMN(BayesID, bayesID, o2::track::pid_constants::ID); //! Most probable ID + +} // namespace pidbayes + +// Table for each particle hypothesis +DECLARE_SOA_TABLE(pidBayesEl, "AOD", "pidBayesEl", //! Binned (in percentage) Bayesian probability of having a Electron + pidbayes::BayesEl); +DECLARE_SOA_TABLE(pidBayesMu, "AOD", "pidBayesMu", //! Binned (in percentage) Bayesian probability of having a Muon + pidbayes::BayesMu); +DECLARE_SOA_TABLE(pidBayesPi, "AOD", "pidBayesPi", //! Binned (in percentage) Bayesian probability of having a Pion + pidbayes::BayesPi); +DECLARE_SOA_TABLE(pidBayesKa, "AOD", "pidBayesKa", //! Binned (in percentage) Bayesian probability of having a Kaon + pidbayes::BayesKa); +DECLARE_SOA_TABLE(pidBayesPr, "AOD", "pidBayesPr", //! Binned (in percentage) Bayesian probability of having a Proton + pidbayes::BayesPr); +DECLARE_SOA_TABLE(pidBayesDe, "AOD", "pidBayesDe", //! Binned (in percentage) Bayesian probability of having a Deuteron + pidbayes::BayesDe); +DECLARE_SOA_TABLE(pidBayesTr, "AOD", "pidBayesTr", //! Binned (in percentage) Bayesian probability of having a Triton + pidbayes::BayesTr); +DECLARE_SOA_TABLE(pidBayesHe, "AOD", "pidBayesHe", //! Binned (in percentage) Bayesian probability of having a Helium3 + pidbayes::BayesHe); +DECLARE_SOA_TABLE(pidBayesAl, "AOD", "pidBayesAl", //! Binned (in percentage) Bayesian probability of having a Alpha + pidbayes::BayesAl); + +// Table for the most probable particle +DECLARE_SOA_TABLE(pidBayes, "AOD", "pidBayes", pidbayes::BayesProb, pidbayes::BayesID); //! Index of the most probable ID and its bayesian probability + +} // namespace o2::aod + +#endif // COMMON_DATAMODEL_PIDRESPONSECOMBINED_H_ diff --git a/Common/DataModel/PIDResponseTOF.h b/Common/DataModel/PIDResponseTOF.h new file mode 100644 index 00000000000..aa3d768c8d2 --- /dev/null +++ b/Common/DataModel/PIDResponseTOF.h @@ -0,0 +1,485 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// 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. + +/// +/// \file PIDResponseTOF.h +/// \since 2024-11-15 +/// \author Nicolò Jacazio nicolo.jacazio@cern.ch +/// \brief Set of tables, tasks and utilities to provide the interface between +/// the analysis data model and the PID response of the TOF +/// + +#ifndef COMMON_DATAMODEL_PIDRESPONSETOF_H_ +#define COMMON_DATAMODEL_PIDRESPONSETOF_H_ + +#include + +// O2 includes +#include "Framework/ASoA.h" +#include "Framework/AnalysisDataModel.h" +#include "ReconstructionDataFormats/PID.h" +#include "Framework/Logger.h" + +namespace o2::aod +{ +namespace pidutils +{ + +// Checkers for TOF PID hypothesis availability (runtime) +template +using hasTOFEl = decltype(std::declval().tofNSigmaEl()); +template +using hasTOFMu = decltype(std::declval().tofNSigmaMu()); +template +using hasTOFPi = decltype(std::declval().tofNSigmaPi()); +template +using hasTOFKa = decltype(std::declval().tofNSigmaKa()); +template +using hasTOFPr = decltype(std::declval().tofNSigmaPr()); +template +using hasTOFDe = decltype(std::declval().tofNSigmaDe()); +template +using hasTOFTr = decltype(std::declval().tofNSigmaTr()); +template +using hasTOFHe = decltype(std::declval().tofNSigmaHe()); +template +using hasTOFAl = decltype(std::declval().tofNSigmaAl()); + +// PID index as template argument +#define perSpeciesWrapper(functionName) \ + template \ + auto functionName(const TrackType& track) \ + { \ + if constexpr (index == o2::track::PID::Electron) { \ + return track.functionName##El(); \ + } else if constexpr (index == o2::track::PID::Muon) { \ + return track.functionName##Mu(); \ + } else if constexpr (index == o2::track::PID::Pion) { \ + return track.functionName##Pi(); \ + } else if constexpr (index == o2::track::PID::Kaon) { \ + return track.functionName##Ka(); \ + } else if constexpr (index == o2::track::PID::Proton) { \ + return track.functionName##Pr(); \ + } else if constexpr (index == o2::track::PID::Deuteron) { \ + return track.functionName##De(); \ + } else if constexpr (index == o2::track::PID::Triton) { \ + return track.functionName##Tr(); \ + } else if constexpr (index == o2::track::PID::Helium3) { \ + return track.functionName##He(); \ + } else if constexpr (index == o2::track::PID::Alpha) { \ + return track.functionName##Al(); \ + } \ + } + +perSpeciesWrapper(tofNSigma); +perSpeciesWrapper(tofExpSigma); +template +auto tofExpSignal(const TrackType& track) +{ + if constexpr (index == o2::track::PID::Electron) { + return track.tofExpSignalEl(track.tofSignal()); + } else if constexpr (index == o2::track::PID::Muon) { + return track.tofExpSignalMu(track.tofSignal()); + } else if constexpr (index == o2::track::PID::Pion) { + return track.tofExpSignalPi(track.tofSignal()); + } else if constexpr (index == o2::track::PID::Kaon) { + return track.tofExpSignalKa(track.tofSignal()); + } else if constexpr (index == o2::track::PID::Proton) { + return track.tofExpSignalPr(track.tofSignal()); + } else if constexpr (index == o2::track::PID::Deuteron) { + return track.tofExpSignalDe(track.tofSignal()); + } else if constexpr (index == o2::track::PID::Triton) { + return track.tofExpSignalTr(track.tofSignal()); + } else if constexpr (index == o2::track::PID::Helium3) { + return track.tofExpSignalHe(track.tofSignal()); + } else if constexpr (index == o2::track::PID::Alpha) { + return track.tofExpSignalAl(track.tofSignal()); + } +} +perSpeciesWrapper(tofExpSignalDiff); + +#undef perSpeciesWrapper + +// PID index as function argument for TOF +#define perSpeciesWrapper(functionName) \ + template \ + auto functionName(const o2::track::PID::ID index, const TrackType& track) \ + { \ + switch (index) { \ + case o2::track::PID::Electron: \ + if constexpr (std::experimental::is_detected::value) { \ + return track.functionName##El(); \ + } \ + case o2::track::PID::Muon: \ + if constexpr (std::experimental::is_detected::value) { \ + return track.functionName##Mu(); \ + } \ + case o2::track::PID::Pion: \ + if constexpr (std::experimental::is_detected::value) { \ + return track.functionName##Pi(); \ + } \ + case o2::track::PID::Kaon: \ + if constexpr (std::experimental::is_detected::value) { \ + return track.functionName##Ka(); \ + } \ + case o2::track::PID::Proton: \ + if constexpr (std::experimental::is_detected::value) { \ + return track.functionName##Pr(); \ + } \ + case o2::track::PID::Deuteron: \ + if constexpr (std::experimental::is_detected::value) { \ + return track.functionName##De(); \ + } \ + case o2::track::PID::Triton: \ + if constexpr (std::experimental::is_detected::value) { \ + return track.functionName##Tr(); \ + } \ + case o2::track::PID::Helium3: \ + if constexpr (std::experimental::is_detected::value) { \ + return track.functionName##He(); \ + } \ + case o2::track::PID::Alpha: \ + if constexpr (std::experimental::is_detected::value) { \ + return track.functionName##Al(); \ + } \ + default: \ + LOGF(fatal, "TOF PID table for PID index %i (%s) is not available", index, o2::track::PID::getName(index)); \ + return 0.f; \ + } \ + } + +perSpeciesWrapper(tofNSigma); +perSpeciesWrapper(tofExpSigma); +template +auto tofExpSignal(const o2::track::PID::ID index, const TrackType& track) +{ + switch (index) { + case o2::track::PID::Electron: + if constexpr (std::experimental::is_detected::value) { + return track.tofExpSignalEl(track.tofSignal()); + } + case o2::track::PID::Muon: + if constexpr (std::experimental::is_detected::value) { + return track.tofExpSignalMu(track.tofSignal()); + } + case o2::track::PID::Pion: + if constexpr (std::experimental::is_detected::value) { + return track.tofExpSignalPi(track.tofSignal()); + } + case o2::track::PID::Kaon: + if constexpr (std::experimental::is_detected::value) { + return track.tofExpSignalKa(track.tofSignal()); + } + case o2::track::PID::Proton: + if constexpr (std::experimental::is_detected::value) { + return track.tofExpSignalPr(track.tofSignal()); + } + case o2::track::PID::Deuteron: + if constexpr (std::experimental::is_detected::value) { + return track.tofExpSignalDe(track.tofSignal()); + } + case o2::track::PID::Triton: + if constexpr (std::experimental::is_detected::value) { + return track.tofExpSignalTr(track.tofSignal()); + } + case o2::track::PID::Helium3: + if constexpr (std::experimental::is_detected::value) { + return track.tofExpSignalHe(track.tofSignal()); + } + case o2::track::PID::Alpha: + if constexpr (std::experimental::is_detected::value) { + return track.tofExpSignalAl(track.tofSignal()); + } + default: + LOGF(fatal, "TOF PID table for PID index %i (%s) is not available", index, o2::track::PID::getName(index)); + return 0.f; + } +} +perSpeciesWrapper(tofExpSignalDiff); + +#undef perSpeciesWrapper + +} // namespace pidutils + +namespace pidtof +{ +// Expected signals +DECLARE_SOA_DYNAMIC_COLUMN(TOFExpSignalEl, tofExpSignalEl, //! Expected time for electron + [](float nsigma, float sigma, float tofsignal) -> float { return tofsignal - nsigma * sigma; }); +DECLARE_SOA_DYNAMIC_COLUMN(TOFExpSignalMu, tofExpSignalMu, //! Expected time for muon + [](float nsigma, float sigma, float tofsignal) -> float { return tofsignal - nsigma * sigma; }); +DECLARE_SOA_DYNAMIC_COLUMN(TOFExpSignalPi, tofExpSignalPi, //! Expected time for pion + [](float nsigma, float sigma, float tofsignal) -> float { return tofsignal - nsigma * sigma; }); +DECLARE_SOA_DYNAMIC_COLUMN(TOFExpSignalKa, tofExpSignalKa, //! Expected time for kaon + [](float nsigma, float sigma, float tofsignal) -> float { return tofsignal - nsigma * sigma; }); +DECLARE_SOA_DYNAMIC_COLUMN(TOFExpSignalPr, tofExpSignalPr, //! Expected time for proton + [](float nsigma, float sigma, float tofsignal) -> float { return tofsignal - nsigma * sigma; }); +DECLARE_SOA_DYNAMIC_COLUMN(TOFExpSignalDe, tofExpSignalDe, //! Expected time for deuteron + [](float nsigma, float sigma, float tofsignal) -> float { return tofsignal - nsigma * sigma; }); +DECLARE_SOA_DYNAMIC_COLUMN(TOFExpSignalTr, tofExpSignalTr, //! Expected time for triton + [](float nsigma, float sigma, float tofsignal) -> float { return tofsignal - nsigma * sigma; }); +DECLARE_SOA_DYNAMIC_COLUMN(TOFExpSignalHe, tofExpSignalHe, //! Expected time for helium3 + [](float nsigma, float sigma, float tofsignal) -> float { return tofsignal - nsigma * sigma; }); +DECLARE_SOA_DYNAMIC_COLUMN(TOFExpSignalAl, tofExpSignalAl, //! Expected time for alpha + [](float nsigma, float sigma, float tofsignal) -> float { return tofsignal - nsigma * sigma; }); +// Delta with respect to signal +DECLARE_SOA_DYNAMIC_COLUMN(TOFExpSignalDiffEl, tofExpSignalDiffEl, //! Difference between signal and expected for electron + [](float nsigma, float sigma) -> float { return nsigma * sigma; }); +DECLARE_SOA_DYNAMIC_COLUMN(TOFExpSignalDiffMu, tofExpSignalDiffMu, //! Difference between signal and expected for muon + [](float nsigma, float sigma) -> float { return nsigma * sigma; }); +DECLARE_SOA_DYNAMIC_COLUMN(TOFExpSignalDiffPi, tofExpSignalDiffPi, //! Difference between signal and expected for pion + [](float nsigma, float sigma) -> float { return nsigma * sigma; }); +DECLARE_SOA_DYNAMIC_COLUMN(TOFExpSignalDiffKa, tofExpSignalDiffKa, //! Difference between signal and expected for kaon + [](float nsigma, float sigma) -> float { return nsigma * sigma; }); +DECLARE_SOA_DYNAMIC_COLUMN(TOFExpSignalDiffPr, tofExpSignalDiffPr, //! Difference between signal and expected for proton + [](float nsigma, float sigma) -> float { return nsigma * sigma; }); +DECLARE_SOA_DYNAMIC_COLUMN(TOFExpSignalDiffDe, tofExpSignalDiffDe, //! Difference between signal and expected for deuteron + [](float nsigma, float sigma) -> float { return nsigma * sigma; }); +DECLARE_SOA_DYNAMIC_COLUMN(TOFExpSignalDiffTr, tofExpSignalDiffTr, //! Difference between signal and expected for triton + [](float nsigma, float sigma) -> float { return nsigma * sigma; }); +DECLARE_SOA_DYNAMIC_COLUMN(TOFExpSignalDiffHe, tofExpSignalDiffHe, //! Difference between signal and expected for helium3 + [](float nsigma, float sigma) -> float { return nsigma * sigma; }); +DECLARE_SOA_DYNAMIC_COLUMN(TOFExpSignalDiffAl, tofExpSignalDiffAl, //! Difference between signal and expected for alpha + [](float nsigma, float sigma) -> float { return nsigma * sigma; }); +// Expected sigma +DECLARE_SOA_COLUMN(TOFExpSigmaEl, tofExpSigmaEl, float); //! Expected resolution with the TOF detector for electron +DECLARE_SOA_COLUMN(TOFExpSigmaMu, tofExpSigmaMu, float); //! Expected resolution with the TOF detector for muon +DECLARE_SOA_COLUMN(TOFExpSigmaPi, tofExpSigmaPi, float); //! Expected resolution with the TOF detector for pion +DECLARE_SOA_COLUMN(TOFExpSigmaKa, tofExpSigmaKa, float); //! Expected resolution with the TOF detector for kaon +DECLARE_SOA_COLUMN(TOFExpSigmaPr, tofExpSigmaPr, float); //! Expected resolution with the TOF detector for proton +DECLARE_SOA_COLUMN(TOFExpSigmaDe, tofExpSigmaDe, float); //! Expected resolution with the TOF detector for deuteron +DECLARE_SOA_COLUMN(TOFExpSigmaTr, tofExpSigmaTr, float); //! Expected resolution with the TOF detector for triton +DECLARE_SOA_COLUMN(TOFExpSigmaHe, tofExpSigmaHe, float); //! Expected resolution with the TOF detector for helium3 +DECLARE_SOA_COLUMN(TOFExpSigmaAl, tofExpSigmaAl, float); //! Expected resolution with the TOF detector for alpha +// NSigma +DECLARE_SOA_COLUMN(TOFNSigmaEl, tofNSigmaEl, float); //! Nsigma separation with the TOF detector for electron +DECLARE_SOA_COLUMN(TOFNSigmaMu, tofNSigmaMu, float); //! Nsigma separation with the TOF detector for muon +DECLARE_SOA_COLUMN(TOFNSigmaPi, tofNSigmaPi, float); //! Nsigma separation with the TOF detector for pion +DECLARE_SOA_COLUMN(TOFNSigmaKa, tofNSigmaKa, float); //! Nsigma separation with the TOF detector for kaon +DECLARE_SOA_COLUMN(TOFNSigmaPr, tofNSigmaPr, float); //! Nsigma separation with the TOF detector for proton +DECLARE_SOA_COLUMN(TOFNSigmaDe, tofNSigmaDe, float); //! Nsigma separation with the TOF detector for deuteron +DECLARE_SOA_COLUMN(TOFNSigmaTr, tofNSigmaTr, float); //! Nsigma separation with the TOF detector for triton +DECLARE_SOA_COLUMN(TOFNSigmaHe, tofNSigmaHe, float); //! Nsigma separation with the TOF detector for helium3 +DECLARE_SOA_COLUMN(TOFNSigmaAl, tofNSigmaAl, float); //! Nsigma separation with the TOF detector for alpha + +} // namespace pidtof + +namespace pidtof_tiny +{ +struct binning { + public: + typedef int8_t binned_t; + static constexpr int nbins = (1 << 8 * sizeof(binned_t)) - 2; + static constexpr binned_t overflowBin = nbins >> 1; + static constexpr binned_t underflowBin = -(nbins >> 1); + static constexpr float binned_max = 6.35; + static constexpr float binned_min = -6.35; + static constexpr float bin_width = (binned_max - binned_min) / nbins; + + // Function to pack a float into a binned value in table + template + static void packInTable(const float& valueToBin, T& table) + { + if (valueToBin <= binned_min) { + table(underflowBin); + } else if (valueToBin >= binned_max) { + table(overflowBin); + } else if (valueToBin >= 0) { + table(static_cast((valueToBin / bin_width) + 0.5f)); + } else { + table(static_cast((valueToBin / bin_width) - 0.5f)); + } + } + + // Function to unpack a binned value into a float + static float unPackInTable(const binned_t& valueToUnpack) + { + return bin_width * static_cast(valueToUnpack); + } +}; + +// NSigma with reduced size 8 bit +DECLARE_SOA_COLUMN(TOFNSigmaStoreEl, tofNSigmaStoreEl, binning::binned_t); //! Stored binned nsigma with the TOF detector for electron +DECLARE_SOA_COLUMN(TOFNSigmaStoreMu, tofNSigmaStoreMu, binning::binned_t); //! Stored binned nsigma with the TOF detector for muon +DECLARE_SOA_COLUMN(TOFNSigmaStorePi, tofNSigmaStorePi, binning::binned_t); //! Stored binned nsigma with the TOF detector for pion +DECLARE_SOA_COLUMN(TOFNSigmaStoreKa, tofNSigmaStoreKa, binning::binned_t); //! Stored binned nsigma with the TOF detector for kaon +DECLARE_SOA_COLUMN(TOFNSigmaStorePr, tofNSigmaStorePr, binning::binned_t); //! Stored binned nsigma with the TOF detector for proton +DECLARE_SOA_COLUMN(TOFNSigmaStoreDe, tofNSigmaStoreDe, binning::binned_t); //! Stored binned nsigma with the TOF detector for deuteron +DECLARE_SOA_COLUMN(TOFNSigmaStoreTr, tofNSigmaStoreTr, binning::binned_t); //! Stored binned nsigma with the TOF detector for triton +DECLARE_SOA_COLUMN(TOFNSigmaStoreHe, tofNSigmaStoreHe, binning::binned_t); //! Stored binned nsigma with the TOF detector for helium3 +DECLARE_SOA_COLUMN(TOFNSigmaStoreAl, tofNSigmaStoreAl, binning::binned_t); //! Stored binned nsigma with the TOF detector for alpha + +// NSigma with reduced size in [binned_min, binned_max] bin size bin_width +DECLARE_SOA_DYNAMIC_COLUMN(TOFNSigmaEl, tofNSigmaEl, //! Unwrapped (float) nsigma with the TOF detector for electron + [](binning::binned_t nsigma_binned) -> float { return binning::unPackInTable(nsigma_binned); }); +DECLARE_SOA_DYNAMIC_COLUMN(TOFNSigmaMu, tofNSigmaMu, //! Unwrapped (float) nsigma with the TOF detector for muon + [](binning::binned_t nsigma_binned) -> float { return binning::unPackInTable(nsigma_binned); }); +DECLARE_SOA_DYNAMIC_COLUMN(TOFNSigmaPi, tofNSigmaPi, //! Unwrapped (float) nsigma with the TOF detector for pion + [](binning::binned_t nsigma_binned) -> float { return binning::unPackInTable(nsigma_binned); }); +DECLARE_SOA_DYNAMIC_COLUMN(TOFNSigmaKa, tofNSigmaKa, //! Unwrapped (float) nsigma with the TOF detector for kaon + [](binning::binned_t nsigma_binned) -> float { return binning::unPackInTable(nsigma_binned); }); +DECLARE_SOA_DYNAMIC_COLUMN(TOFNSigmaPr, tofNSigmaPr, //! Unwrapped (float) nsigma with the TOF detector for proton + [](binning::binned_t nsigma_binned) -> float { return binning::unPackInTable(nsigma_binned); }); +DECLARE_SOA_DYNAMIC_COLUMN(TOFNSigmaDe, tofNSigmaDe, //! Unwrapped (float) nsigma with the TOF detector for deuteron + [](binning::binned_t nsigma_binned) -> float { return binning::unPackInTable(nsigma_binned); }); +DECLARE_SOA_DYNAMIC_COLUMN(TOFNSigmaTr, tofNSigmaTr, //! Unwrapped (float) nsigma with the TOF detector for triton + [](binning::binned_t nsigma_binned) -> float { return binning::unPackInTable(nsigma_binned); }); +DECLARE_SOA_DYNAMIC_COLUMN(TOFNSigmaHe, tofNSigmaHe, //! Unwrapped (float) nsigma with the TOF detector for helium3 + [](binning::binned_t nsigma_binned) -> float { return binning::unPackInTable(nsigma_binned); }); +DECLARE_SOA_DYNAMIC_COLUMN(TOFNSigmaAl, tofNSigmaAl, //! Unwrapped (float) nsigma with the TOF detector for alpha + [](binning::binned_t nsigma_binned) -> float { return binning::unPackInTable(nsigma_binned); }); + +} // namespace pidtof_tiny + +// Per particle tables +DECLARE_SOA_TABLE(pidTOFFullEl, "AOD", "pidTOFFullEl", //! Table of the TOF (full) response with expected signal, expected resolution and Nsigma for electron + pidtof::TOFExpSignalDiffEl, + pidtof::TOFExpSignalEl, + pidtof::TOFExpSigmaEl, pidtof::TOFNSigmaEl); +DECLARE_SOA_TABLE(pidTOFFullMu, "AOD", "pidTOFFullMu", //! Table of the TOF (full) response with expected signal, expected resolution and Nsigma for muon + pidtof::TOFExpSignalDiffMu, + pidtof::TOFExpSignalMu, + pidtof::TOFExpSigmaMu, pidtof::TOFNSigmaMu); +DECLARE_SOA_TABLE(pidTOFFullPi, "AOD", "pidTOFFullPi", //! Table of the TOF (full) response with expected signal, expected resolution and Nsigma for pion + pidtof::TOFExpSignalDiffPi, + pidtof::TOFExpSignalPi, + pidtof::TOFExpSigmaPi, pidtof::TOFNSigmaPi); +DECLARE_SOA_TABLE(pidTOFFullKa, "AOD", "pidTOFFullKa", //! Table of the TOF (full) response with expected signal, expected resolution and Nsigma for kaon + pidtof::TOFExpSignalDiffKa, + pidtof::TOFExpSignalKa, + pidtof::TOFExpSigmaKa, pidtof::TOFNSigmaKa); +DECLARE_SOA_TABLE(pidTOFFullPr, "AOD", "pidTOFFullPr", //! Table of the TOF (full) response with expected signal, expected resolution and Nsigma for proton + pidtof::TOFExpSignalDiffPr, + pidtof::TOFExpSignalPr, + pidtof::TOFExpSigmaPr, pidtof::TOFNSigmaPr); +DECLARE_SOA_TABLE(pidTOFFullDe, "AOD", "pidTOFFullDe", //! Table of the TOF (full) response with expected signal, expected resolution and Nsigma for deuteron + pidtof::TOFExpSignalDiffDe, + pidtof::TOFExpSignalDe, + pidtof::TOFExpSigmaDe, pidtof::TOFNSigmaDe); +DECLARE_SOA_TABLE(pidTOFFullTr, "AOD", "pidTOFFullTr", //! Table of the TOF (full) response with expected signal, expected resolution and Nsigma for triton + pidtof::TOFExpSignalDiffTr, + pidtof::TOFExpSignalTr, + pidtof::TOFExpSigmaTr, pidtof::TOFNSigmaTr); +DECLARE_SOA_TABLE(pidTOFFullHe, "AOD", "pidTOFFullHe", //! Table of the TOF (full) response with expected signal, expected resolution and Nsigma for helium3 + pidtof::TOFExpSignalDiffHe, + pidtof::TOFExpSignalHe, + pidtof::TOFExpSigmaHe, pidtof::TOFNSigmaHe); +DECLARE_SOA_TABLE(pidTOFFullAl, "AOD", "pidTOFFullAl", //! Table of the TOF (full) response with expected signal, expected resolution and Nsigma for alpha + pidtof::TOFExpSignalDiffAl, + pidtof::TOFExpSignalAl, + pidtof::TOFExpSigmaAl, pidtof::TOFNSigmaAl); + +// Tiny size tables +DECLARE_SOA_TABLE(pidTOFEl, "AOD", "pidTOFEl", //! Table of the TOF response with binned Nsigma for electron + pidtof_tiny::TOFNSigmaStoreEl, pidtof_tiny::TOFNSigmaEl); +DECLARE_SOA_TABLE(pidTOFMu, "AOD", "pidTOFMu", //! Table of the TOF response with binned Nsigma for muon + pidtof_tiny::TOFNSigmaStoreMu, pidtof_tiny::TOFNSigmaMu); +DECLARE_SOA_TABLE(pidTOFPi, "AOD", "pidTOFPi", //! Table of the TOF response with binned Nsigma for pion + pidtof_tiny::TOFNSigmaStorePi, pidtof_tiny::TOFNSigmaPi); +DECLARE_SOA_TABLE(pidTOFKa, "AOD", "pidTOFKa", //! Table of the TOF response with binned Nsigma for kaon + pidtof_tiny::TOFNSigmaStoreKa, pidtof_tiny::TOFNSigmaKa); +DECLARE_SOA_TABLE(pidTOFPr, "AOD", "pidTOFPr", //! Table of the TOF response with binned Nsigma for proton + pidtof_tiny::TOFNSigmaStorePr, pidtof_tiny::TOFNSigmaPr); +DECLARE_SOA_TABLE(pidTOFDe, "AOD", "pidTOFDe", //! Table of the TOF response with binned Nsigma for deuteron + pidtof_tiny::TOFNSigmaStoreDe, pidtof_tiny::TOFNSigmaDe); +DECLARE_SOA_TABLE(pidTOFTr, "AOD", "pidTOFTr", //! Table of the TOF response with binned Nsigma for triton + pidtof_tiny::TOFNSigmaStoreTr, pidtof_tiny::TOFNSigmaTr); +DECLARE_SOA_TABLE(pidTOFHe, "AOD", "pidTOFHe", //! Table of the TOF response with binned Nsigma for helium3 + pidtof_tiny::TOFNSigmaStoreHe, pidtof_tiny::TOFNSigmaHe); +DECLARE_SOA_TABLE(pidTOFAl, "AOD", "pidTOFAl", //! Table of the TOF response with binned Nsigma for alpha + pidtof_tiny::TOFNSigmaStoreAl, pidtof_tiny::TOFNSigmaAl); + +// Extra tables +namespace pidflags +{ + +namespace enums +{ +enum PIDFlags : uint8_t { + EvTimeUndef = 0x0, // Event collision not set, corresponding to the LHC Fill event time + EvTimeTOF = 0x1, // Event collision time from TOF + EvTimeT0AC = 0x2, // Event collision time from the FT0AC + EvTimeTOFT0AC = 0x4 // Event collision time from the TOF and FT0AC +}; +} + +DECLARE_SOA_COLUMN(GoodTOFMatch, goodTOFMatch, bool); //! Bool for the TOF PID information on the single track information +DECLARE_SOA_COLUMN(TOFFlags, tofFlags, uint8_t); //! Flag for the complementary TOF PID information for the event time +DECLARE_SOA_DYNAMIC_COLUMN(IsEvTimeDefined, isEvTimeDefined, //! True if the Event Time was computed with any method i.e. there is a usable event time + [](uint8_t flags) -> bool { return (flags > 0); }); +DECLARE_SOA_DYNAMIC_COLUMN(IsEvTimeTOF, isEvTimeTOF, //! True if the Event Time was computed with the TOF + [](uint8_t flags) -> bool { return (flags & enums::PIDFlags::EvTimeTOF) == enums::PIDFlags::EvTimeTOF; }); +DECLARE_SOA_DYNAMIC_COLUMN(IsEvTimeT0AC, isEvTimeT0AC, //! True if the Event Time was computed with the T0AC + [](uint8_t flags) -> bool { return (flags & enums::PIDFlags::EvTimeT0AC) == enums::PIDFlags::EvTimeT0AC; }); +DECLARE_SOA_DYNAMIC_COLUMN(IsEvTimeTOFT0AC, isEvTimeTOFT0AC, //! True if the Event Time was computed with the TOF and T0AC + [](uint8_t flags) -> bool { return (flags & enums::PIDFlags::EvTimeTOFT0AC) == enums::PIDFlags::EvTimeTOFT0AC; }); + +} // namespace pidflags + +DECLARE_SOA_TABLE(pidTOFFlags, "AOD", "pidTOFFlags", //! Table of the flags for TOF signal quality on the track level + pidflags::GoodTOFMatch); + +DECLARE_SOA_TABLE(pidEvTimeFlags, "AOD", "pidEvTimeFlags", //! Table of the PID flags for the event time tables + pidflags::TOFFlags, + pidflags::IsEvTimeDefined, + pidflags::IsEvTimeTOF, + pidflags::IsEvTimeT0AC, + pidflags::IsEvTimeTOFT0AC); + +namespace pidtofsignal +{ +DECLARE_SOA_COLUMN(TOFSignal, tofSignal, float); //! TOF signal from track time +DECLARE_SOA_DYNAMIC_COLUMN(EventCollisionTime, eventCollisionTime, //! Event collision time used for the track. Needs the TOF + [](float signal, float tMinusTexp, float texp) -> float { return texp + tMinusTexp - signal; }); + +} // namespace pidtofsignal + +DECLARE_SOA_TABLE(TOFSignal, "AOD", "TOFSignal", //! Table of the TOF signal + pidtofsignal::TOFSignal, + pidtofsignal::EventCollisionTime); + +namespace pidtofevtime +{ +DECLARE_SOA_COLUMN(TOFEvTime, tofEvTime, float); //! event time for TOF signal. Can be obtained via a combination of detectors e.g. TOF, FT0A, FT0C +DECLARE_SOA_COLUMN(TOFEvTimeErr, tofEvTimeErr, float); //! event time error for TOF. Can be obtained via a combination of detectors e.g. TOF, FT0A, FT0C +} // namespace pidtofevtime + +DECLARE_SOA_TABLE(TOFEvTime, "AOD", "TOFEvTime", //! Table of the TOF event time. One entry per track. + pidtofevtime::TOFEvTime, + pidtofevtime::TOFEvTimeErr); + +namespace pidtofbeta +{ +DECLARE_SOA_COLUMN(Beta, beta, float); //! TOF beta +DECLARE_SOA_COLUMN(BetaError, betaerror, float); //! Uncertainty on the TOF beta +// +DECLARE_SOA_COLUMN(ExpBetaEl, expbetael, float); //! Expected beta of electron +DECLARE_SOA_COLUMN(ExpBetaElError, expbetaelerror, float); //! Expected uncertainty on the beta of electron +// +DECLARE_SOA_COLUMN(SeparationBetaEl, separationbetael, float); //! Separation computed with the expected beta for electrons +DECLARE_SOA_DYNAMIC_COLUMN(DiffBetaEl, diffbetael, //! Difference between the measured and the expected beta for electrons + [](float beta, float expbetael) -> float { return beta - expbetael; }); +} // namespace pidtofbeta + +DECLARE_SOA_TABLE(pidTOFbeta, "AOD", "pidTOFbeta", //! Table of the TOF beta + pidtofbeta::Beta, pidtofbeta::BetaError); + +namespace pidtofmass +{ +DECLARE_SOA_COLUMN(TOFMass, mass, float); //! TOF mass +} // namespace pidtofmass + +DECLARE_SOA_TABLE(pidTOFmass, "AOD", "pidTOFmass", //! Table of the TOF mass + pidtofmass::TOFMass); + +} // namespace o2::aod + +#endif // COMMON_DATAMODEL_PIDRESPONSETOF_H_ diff --git a/Common/DataModel/PIDResponseTPC.h b/Common/DataModel/PIDResponseTPC.h new file mode 100644 index 00000000000..a22d5c9c008 --- /dev/null +++ b/Common/DataModel/PIDResponseTPC.h @@ -0,0 +1,411 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// 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. + +/// +/// \file PIDResponseTPC.h +/// \since 2024-11-15 +/// \author Nicolò Jacazio nicolo.jacazio@cern.ch +/// \brief Set of tables, tasks and utilities to provide the interface between +/// the analysis data model and the PID response of the TPC +/// + +#ifndef COMMON_DATAMODEL_PIDRESPONSETPC_H_ +#define COMMON_DATAMODEL_PIDRESPONSETPC_H_ + +#include + +// O2 includes +#include "Framework/ASoA.h" +#include "Framework/AnalysisDataModel.h" +#include "ReconstructionDataFormats/PID.h" +#include "Framework/Logger.h" + +namespace o2::aod +{ +namespace pidutils +{ + +// Checkers for TPC PID hypothesis availability (runtime) +template +using hasTPCEl = decltype(std::declval().tpcNSigmaEl()); +template +using hasTPCMu = decltype(std::declval().tpcNSigmaMu()); +template +using hasTPCPi = decltype(std::declval().tpcNSigmaPi()); +template +using hasTPCKa = decltype(std::declval().tpcNSigmaKa()); +template +using hasTPCPr = decltype(std::declval().tpcNSigmaPr()); +template +using hasTPCDe = decltype(std::declval().tpcNSigmaDe()); +template +using hasTPCTr = decltype(std::declval().tpcNSigmaTr()); +template +using hasTPCHe = decltype(std::declval().tpcNSigmaHe()); +template +using hasTPCAl = decltype(std::declval().tpcNSigmaAl()); + +// PID index as template argument +#define perSpeciesWrapper(functionName) \ + template \ + auto functionName(const TrackType& track) \ + { \ + if constexpr (index == o2::track::PID::Electron) { \ + return track.functionName##El(); \ + } else if constexpr (index == o2::track::PID::Muon) { \ + return track.functionName##Mu(); \ + } else if constexpr (index == o2::track::PID::Pion) { \ + return track.functionName##Pi(); \ + } else if constexpr (index == o2::track::PID::Kaon) { \ + return track.functionName##Ka(); \ + } else if constexpr (index == o2::track::PID::Proton) { \ + return track.functionName##Pr(); \ + } else if constexpr (index == o2::track::PID::Deuteron) { \ + return track.functionName##De(); \ + } else if constexpr (index == o2::track::PID::Triton) { \ + return track.functionName##Tr(); \ + } else if constexpr (index == o2::track::PID::Helium3) { \ + return track.functionName##He(); \ + } else if constexpr (index == o2::track::PID::Alpha) { \ + return track.functionName##Al(); \ + } \ + } + +perSpeciesWrapper(tpcNSigma); +perSpeciesWrapper(tpcExpSigma); +template +auto tpcExpSignal(const TrackType& track) +{ + if constexpr (index == o2::track::PID::Electron) { + return track.tpcExpSignalEl(track.tpcSignal()); + } else if constexpr (index == o2::track::PID::Muon) { + return track.tpcExpSignalMu(track.tpcSignal()); + } else if constexpr (index == o2::track::PID::Pion) { + return track.tpcExpSignalPi(track.tpcSignal()); + } else if constexpr (index == o2::track::PID::Kaon) { + return track.tpcExpSignalKa(track.tpcSignal()); + } else if constexpr (index == o2::track::PID::Proton) { + return track.tpcExpSignalPr(track.tpcSignal()); + } else if constexpr (index == o2::track::PID::Deuteron) { + return track.tpcExpSignalDe(track.tpcSignal()); + } else if constexpr (index == o2::track::PID::Triton) { + return track.tpcExpSignalTr(track.tpcSignal()); + } else if constexpr (index == o2::track::PID::Helium3) { + return track.tpcExpSignalHe(track.tpcSignal()); + } else if constexpr (index == o2::track::PID::Alpha) { + return track.tpcExpSignalAl(track.tpcSignal()); + } +} +perSpeciesWrapper(tpcExpSignalDiff); + +#undef perSpeciesWrapper + +// PID index as function argument for TPC +#define perSpeciesWrapper(functionName) \ + template \ + auto functionName(const o2::track::PID::ID index, const TrackType& track) \ + { \ + switch (index) { \ + case o2::track::PID::Electron: \ + if constexpr (std::experimental::is_detected::value) { \ + return track.functionName##El(); \ + } \ + case o2::track::PID::Muon: \ + if constexpr (std::experimental::is_detected::value) { \ + return track.functionName##Mu(); \ + } \ + case o2::track::PID::Pion: \ + if constexpr (std::experimental::is_detected::value) { \ + return track.functionName##Pi(); \ + } \ + case o2::track::PID::Kaon: \ + if constexpr (std::experimental::is_detected::value) { \ + return track.functionName##Ka(); \ + } \ + case o2::track::PID::Proton: \ + if constexpr (std::experimental::is_detected::value) { \ + return track.functionName##Pr(); \ + } \ + case o2::track::PID::Deuteron: \ + if constexpr (std::experimental::is_detected::value) { \ + return track.functionName##De(); \ + } \ + case o2::track::PID::Triton: \ + if constexpr (std::experimental::is_detected::value) { \ + return track.functionName##Tr(); \ + } \ + case o2::track::PID::Helium3: \ + if constexpr (std::experimental::is_detected::value) { \ + return track.functionName##He(); \ + } \ + case o2::track::PID::Alpha: \ + if constexpr (std::experimental::is_detected::value) { \ + return track.functionName##Al(); \ + } \ + default: \ + LOGF(fatal, "TPC PID table for PID index %i (%s) is not available", index, o2::track::PID::getName(index)); \ + return 0.f; \ + } \ + } + +perSpeciesWrapper(tpcNSigma); +perSpeciesWrapper(tpcExpSigma); +template +auto tpcExpSignal(const o2::track::PID::ID index, const TrackType& track) +{ + switch (index) { + case o2::track::PID::Electron: + if constexpr (std::experimental::is_detected::value) { + return track.tpcExpSignalEl(track.tpcSignal()); + } + case o2::track::PID::Muon: + if constexpr (std::experimental::is_detected::value) { + return track.tpcExpSignalMu(track.tpcSignal()); + } + case o2::track::PID::Pion: + if constexpr (std::experimental::is_detected::value) { + return track.tpcExpSignalPi(track.tpcSignal()); + } + case o2::track::PID::Kaon: + if constexpr (std::experimental::is_detected::value) { + return track.tpcExpSignalKa(track.tpcSignal()); + } + case o2::track::PID::Proton: + if constexpr (std::experimental::is_detected::value) { + return track.tpcExpSignalPr(track.tpcSignal()); + } + case o2::track::PID::Deuteron: + if constexpr (std::experimental::is_detected::value) { + return track.tpcExpSignalDe(track.tpcSignal()); + } + case o2::track::PID::Triton: + if constexpr (std::experimental::is_detected::value) { + return track.tpcExpSignalTr(track.tpcSignal()); + } + case o2::track::PID::Helium3: + if constexpr (std::experimental::is_detected::value) { + return track.tpcExpSignalHe(track.tpcSignal()); + } + case o2::track::PID::Alpha: + if constexpr (std::experimental::is_detected::value) { + return track.tpcExpSignalAl(track.tpcSignal()); + } + default: + LOGF(fatal, "TPC PID table for PID index %i (%s) is not available", index, o2::track::PID::getName(index)); + return 0.f; + } +} +perSpeciesWrapper(tpcExpSignalDiff); + +#undef perSpeciesWrapper + +} // namespace pidutils + +namespace pidtpc +{ +// Expected signals +DECLARE_SOA_DYNAMIC_COLUMN(TPCExpSignalEl, tpcExpSignalEl, //! Expected signal with the TPC detector for electron + [](float nsigma, float sigma, float tpcsignal) -> float { return tpcsignal - nsigma * sigma; }); +DECLARE_SOA_DYNAMIC_COLUMN(TPCExpSignalMu, tpcExpSignalMu, //! Expected signal with the TPC detector for muon + [](float nsigma, float sigma, float tpcsignal) -> float { return tpcsignal - nsigma * sigma; }); +DECLARE_SOA_DYNAMIC_COLUMN(TPCExpSignalPi, tpcExpSignalPi, //! Expected signal with the TPC detector for pion + [](float nsigma, float sigma, float tpcsignal) -> float { return tpcsignal - nsigma * sigma; }); +DECLARE_SOA_DYNAMIC_COLUMN(TPCExpSignalKa, tpcExpSignalKa, //! Expected signal with the TPC detector for kaon + [](float nsigma, float sigma, float tpcsignal) -> float { return tpcsignal - nsigma * sigma; }); +DECLARE_SOA_DYNAMIC_COLUMN(TPCExpSignalPr, tpcExpSignalPr, //! Expected signal with the TPC detector for proton + [](float nsigma, float sigma, float tpcsignal) -> float { return tpcsignal - nsigma * sigma; }); +DECLARE_SOA_DYNAMIC_COLUMN(TPCExpSignalDe, tpcExpSignalDe, //! Expected signal with the TPC detector for deuteron + [](float nsigma, float sigma, float tpcsignal) -> float { return tpcsignal - nsigma * sigma; }); +DECLARE_SOA_DYNAMIC_COLUMN(TPCExpSignalTr, tpcExpSignalTr, //! Expected signal with the TPC detector for triton + [](float nsigma, float sigma, float tpcsignal) -> float { return tpcsignal - nsigma * sigma; }); +DECLARE_SOA_DYNAMIC_COLUMN(TPCExpSignalHe, tpcExpSignalHe, //! Expected signal with the TPC detector for helium3 + [](float nsigma, float sigma, float tpcsignal) -> float { return tpcsignal - nsigma * sigma; }); +DECLARE_SOA_DYNAMIC_COLUMN(TPCExpSignalAl, tpcExpSignalAl, //! Expected signal with the TPC detector for alpha + [](float nsigma, float sigma, float tpcsignal) -> float { return tpcsignal - nsigma * sigma; }); +// Delta with respect to signal +DECLARE_SOA_DYNAMIC_COLUMN(TPCExpSignalDiffEl, tpcExpSignalDiffEl, //! Difference between signal and expected for electron + [](float nsigma, float sigma) -> float { return nsigma * sigma; }); +DECLARE_SOA_DYNAMIC_COLUMN(TPCExpSignalDiffMu, tpcExpSignalDiffMu, //! Difference between signal and expected for muon + [](float nsigma, float sigma) -> float { return nsigma * sigma; }); +DECLARE_SOA_DYNAMIC_COLUMN(TPCExpSignalDiffPi, tpcExpSignalDiffPi, //! Difference between signal and expected for pion + [](float nsigma, float sigma) -> float { return nsigma * sigma; }); +DECLARE_SOA_DYNAMIC_COLUMN(TPCExpSignalDiffKa, tpcExpSignalDiffKa, //! Difference between signal and expected for kaon + [](float nsigma, float sigma) -> float { return nsigma * sigma; }); +DECLARE_SOA_DYNAMIC_COLUMN(TPCExpSignalDiffPr, tpcExpSignalDiffPr, //! Difference between signal and expected for proton + [](float nsigma, float sigma) -> float { return nsigma * sigma; }); +DECLARE_SOA_DYNAMIC_COLUMN(TPCExpSignalDiffDe, tpcExpSignalDiffDe, //! Difference between signal and expected for deuteron + [](float nsigma, float sigma) -> float { return nsigma * sigma; }); +DECLARE_SOA_DYNAMIC_COLUMN(TPCExpSignalDiffTr, tpcExpSignalDiffTr, //! Difference between signal and expected for triton + [](float nsigma, float sigma) -> float { return nsigma * sigma; }); +DECLARE_SOA_DYNAMIC_COLUMN(TPCExpSignalDiffHe, tpcExpSignalDiffHe, //! Difference between signal and expected for helium3 + [](float nsigma, float sigma) -> float { return nsigma * sigma; }); +DECLARE_SOA_DYNAMIC_COLUMN(TPCExpSignalDiffAl, tpcExpSignalDiffAl, //! Difference between signal and expected for alpha + [](float nsigma, float sigma) -> float { return nsigma * sigma; }); +// Expected sigma +DECLARE_SOA_COLUMN(TPCExpSigmaEl, tpcExpSigmaEl, float); //! Expected resolution with the TPC detector for electron +DECLARE_SOA_COLUMN(TPCExpSigmaMu, tpcExpSigmaMu, float); //! Expected resolution with the TPC detector for muon +DECLARE_SOA_COLUMN(TPCExpSigmaPi, tpcExpSigmaPi, float); //! Expected resolution with the TPC detector for pion +DECLARE_SOA_COLUMN(TPCExpSigmaKa, tpcExpSigmaKa, float); //! Expected resolution with the TPC detector for kaon +DECLARE_SOA_COLUMN(TPCExpSigmaPr, tpcExpSigmaPr, float); //! Expected resolution with the TPC detector for proton +DECLARE_SOA_COLUMN(TPCExpSigmaDe, tpcExpSigmaDe, float); //! Expected resolution with the TPC detector for deuteron +DECLARE_SOA_COLUMN(TPCExpSigmaTr, tpcExpSigmaTr, float); //! Expected resolution with the TPC detector for triton +DECLARE_SOA_COLUMN(TPCExpSigmaHe, tpcExpSigmaHe, float); //! Expected resolution with the TPC detector for helium3 +DECLARE_SOA_COLUMN(TPCExpSigmaAl, tpcExpSigmaAl, float); //! Expected resolution with the TPC detector for alpha +// NSigma +DECLARE_SOA_COLUMN(TPCNSigmaEl, tpcNSigmaEl, float); //! Nsigma separation with the TPC detector for electron +DECLARE_SOA_COLUMN(TPCNSigmaMu, tpcNSigmaMu, float); //! Nsigma separation with the TPC detector for muon +DECLARE_SOA_COLUMN(TPCNSigmaPi, tpcNSigmaPi, float); //! Nsigma separation with the TPC detector for pion +DECLARE_SOA_COLUMN(TPCNSigmaKa, tpcNSigmaKa, float); //! Nsigma separation with the TPC detector for kaon +DECLARE_SOA_COLUMN(TPCNSigmaPr, tpcNSigmaPr, float); //! Nsigma separation with the TPC detector for proton +DECLARE_SOA_COLUMN(TPCNSigmaDe, tpcNSigmaDe, float); //! Nsigma separation with the TPC detector for deuteron +DECLARE_SOA_COLUMN(TPCNSigmaTr, tpcNSigmaTr, float); //! Nsigma separation with the TPC detector for triton +DECLARE_SOA_COLUMN(TPCNSigmaHe, tpcNSigmaHe, float); //! Nsigma separation with the TPC detector for helium3 +DECLARE_SOA_COLUMN(TPCNSigmaAl, tpcNSigmaAl, float); //! Nsigma separation with the TPC detector for alpha + +} // namespace pidtpc + +namespace pidtpc_tiny +{ +struct binning { + public: + typedef int8_t binned_t; + static constexpr int nbins = (1 << 8 * sizeof(binned_t)) - 2; + static constexpr binned_t overflowBin = nbins >> 1; + static constexpr binned_t underflowBin = -(nbins >> 1); + static constexpr float binned_max = 6.35; + static constexpr float binned_min = -6.35; + static constexpr float bin_width = (binned_max - binned_min) / nbins; + + // Function to pack a float into a binned value in table + template + static void packInTable(const float& valueToBin, T& table) + { + if (valueToBin <= binned_min) { + table(underflowBin); + } else if (valueToBin >= binned_max) { + table(overflowBin); + } else if (valueToBin >= 0) { + table(static_cast((valueToBin / bin_width) + 0.5f)); + } else { + table(static_cast((valueToBin / bin_width) - 0.5f)); + } + } + + // Function to unpack a binned value into a float + static float unPackInTable(const binned_t& valueToUnpack) + { + return bin_width * static_cast(valueToUnpack); + } +}; + +// NSigma with reduced size 8 bit +DECLARE_SOA_COLUMN(TPCNSigmaStoreEl, tpcNSigmaStoreEl, binning::binned_t); //! Stored binned nsigma with the TPC detector for electron +DECLARE_SOA_COLUMN(TPCNSigmaStoreMu, tpcNSigmaStoreMu, binning::binned_t); //! Stored binned nsigma with the TPC detector for muon +DECLARE_SOA_COLUMN(TPCNSigmaStorePi, tpcNSigmaStorePi, binning::binned_t); //! Stored binned nsigma with the TPC detector for pion +DECLARE_SOA_COLUMN(TPCNSigmaStoreKa, tpcNSigmaStoreKa, binning::binned_t); //! Stored binned nsigma with the TPC detector for kaon +DECLARE_SOA_COLUMN(TPCNSigmaStorePr, tpcNSigmaStorePr, binning::binned_t); //! Stored binned nsigma with the TPC detector for proton +DECLARE_SOA_COLUMN(TPCNSigmaStoreDe, tpcNSigmaStoreDe, binning::binned_t); //! Stored binned nsigma with the TPC detector for deuteron +DECLARE_SOA_COLUMN(TPCNSigmaStoreTr, tpcNSigmaStoreTr, binning::binned_t); //! Stored binned nsigma with the TPC detector for triton +DECLARE_SOA_COLUMN(TPCNSigmaStoreHe, tpcNSigmaStoreHe, binning::binned_t); //! Stored binned nsigma with the TPC detector for helium3 +DECLARE_SOA_COLUMN(TPCNSigmaStoreAl, tpcNSigmaStoreAl, binning::binned_t); //! Stored binned nsigma with the TPC detector for alpha + +// NSigma with reduced size in [binned_min, binned_max] bin size bin_width +DECLARE_SOA_DYNAMIC_COLUMN(TPCNSigmaEl, tpcNSigmaEl, //! Unwrapped (float) nsigma with the TPC detector for electron + [](binning::binned_t nsigma_binned) -> float { return binning::unPackInTable(nsigma_binned); }); +DECLARE_SOA_DYNAMIC_COLUMN(TPCNSigmaMu, tpcNSigmaMu, //! Unwrapped (float) nsigma with the TPC detector for muon + [](binning::binned_t nsigma_binned) -> float { return binning::unPackInTable(nsigma_binned); }); +DECLARE_SOA_DYNAMIC_COLUMN(TPCNSigmaPi, tpcNSigmaPi, //! Unwrapped (float) nsigma with the TPC detector for pion + [](binning::binned_t nsigma_binned) -> float { return binning::unPackInTable(nsigma_binned); }); +DECLARE_SOA_DYNAMIC_COLUMN(TPCNSigmaKa, tpcNSigmaKa, //! Unwrapped (float) nsigma with the TPC detector for kaon + [](binning::binned_t nsigma_binned) -> float { return binning::unPackInTable(nsigma_binned); }); +DECLARE_SOA_DYNAMIC_COLUMN(TPCNSigmaPr, tpcNSigmaPr, //! Unwrapped (float) nsigma with the TPC detector for proton + [](binning::binned_t nsigma_binned) -> float { return binning::unPackInTable(nsigma_binned); }); +DECLARE_SOA_DYNAMIC_COLUMN(TPCNSigmaDe, tpcNSigmaDe, //! Unwrapped (float) nsigma with the TPC detector for deuteron + [](binning::binned_t nsigma_binned) -> float { return binning::unPackInTable(nsigma_binned); }); +DECLARE_SOA_DYNAMIC_COLUMN(TPCNSigmaTr, tpcNSigmaTr, //! Unwrapped (float) nsigma with the TPC detector for triton + [](binning::binned_t nsigma_binned) -> float { return binning::unPackInTable(nsigma_binned); }); +DECLARE_SOA_DYNAMIC_COLUMN(TPCNSigmaHe, tpcNSigmaHe, //! Unwrapped (float) nsigma with the TPC detector for helium3 + [](binning::binned_t nsigma_binned) -> float { return binning::unPackInTable(nsigma_binned); }); +DECLARE_SOA_DYNAMIC_COLUMN(TPCNSigmaAl, tpcNSigmaAl, //! Unwrapped (float) nsigma with the TPC detector for alpha + [](binning::binned_t nsigma_binned) -> float { return binning::unPackInTable(nsigma_binned); }); + +} // namespace pidtpc_tiny + +// Per particle tables +DECLARE_SOA_TABLE(pidTPCFullEl, "AOD", "pidTPCFullEl", //! Table of the TPC (full) response with expected signal, expected resolution and Nsigma for electron + pidtpc::TPCExpSignalEl, + pidtpc::TPCExpSignalDiffEl, + pidtpc::TPCExpSigmaEl, pidtpc::TPCNSigmaEl); +DECLARE_SOA_TABLE(pidTPCFullMu, "AOD", "pidTPCFullMu", //! Table of the TPC (full) response with expected signal, expected resolution and Nsigma for muon + pidtpc::TPCExpSignalMu, + pidtpc::TPCExpSignalDiffMu, + pidtpc::TPCExpSigmaMu, pidtpc::TPCNSigmaMu); +DECLARE_SOA_TABLE(pidTPCFullPi, "AOD", "pidTPCFullPi", //! Table of the TPC (full) response with expected signal, expected resolution and Nsigma for pion + pidtpc::TPCExpSignalPi, + pidtpc::TPCExpSignalDiffPi, + pidtpc::TPCExpSigmaPi, pidtpc::TPCNSigmaPi); +DECLARE_SOA_TABLE(pidTPCFullKa, "AOD", "pidTPCFullKa", //! Table of the TPC (full) response with expected signal, expected resolution and Nsigma for kaon + pidtpc::TPCExpSignalKa, + pidtpc::TPCExpSignalDiffKa, + pidtpc::TPCExpSigmaKa, pidtpc::TPCNSigmaKa); +DECLARE_SOA_TABLE(pidTPCFullPr, "AOD", "pidTPCFullPr", //! Table of the TPC (full) response with expected signal, expected resolution and Nsigma for proton + pidtpc::TPCExpSignalPr, + pidtpc::TPCExpSignalDiffPr, + pidtpc::TPCExpSigmaPr, pidtpc::TPCNSigmaPr); +DECLARE_SOA_TABLE(pidTPCFullDe, "AOD", "pidTPCFullDe", //! Table of the TPC (full) response with expected signal, expected resolution and Nsigma for deuteron + pidtpc::TPCExpSignalDe, + pidtpc::TPCExpSignalDiffDe, + pidtpc::TPCExpSigmaDe, pidtpc::TPCNSigmaDe); +DECLARE_SOA_TABLE(pidTPCFullTr, "AOD", "pidTPCFullTr", //! Table of the TPC (full) response with expected signal, expected resolution and Nsigma for triton + pidtpc::TPCExpSignalTr, + pidtpc::TPCExpSignalDiffTr, + pidtpc::TPCExpSigmaTr, pidtpc::TPCNSigmaTr); +DECLARE_SOA_TABLE(pidTPCFullHe, "AOD", "pidTPCFullHe", //! Table of the TPC (full) response with expected signal, expected resolution and Nsigma for helium3 + pidtpc::TPCExpSignalHe, + pidtpc::TPCExpSignalDiffHe, + pidtpc::TPCExpSigmaHe, pidtpc::TPCNSigmaHe); +DECLARE_SOA_TABLE(pidTPCFullAl, "AOD", "pidTPCFullAl", //! Table of the TPC (full) response with expected signal, expected resolution and Nsigma for alpha + pidtpc::TPCExpSignalAl, + pidtpc::TPCExpSignalDiffAl, + pidtpc::TPCExpSigmaAl, pidtpc::TPCNSigmaAl); + +// Tiny size tables +DECLARE_SOA_TABLE(pidTPCEl, "AOD", "pidTPCEl", //! Table of the TPC response with binned Nsigma for electron + pidtpc_tiny::TPCNSigmaStoreEl, pidtpc_tiny::TPCNSigmaEl); +DECLARE_SOA_TABLE(pidTPCMu, "AOD", "pidTPCMu", //! Table of the TPC response with binned Nsigma for muon + pidtpc_tiny::TPCNSigmaStoreMu, pidtpc_tiny::TPCNSigmaMu); +DECLARE_SOA_TABLE(pidTPCPi, "AOD", "pidTPCPi", //! Table of the TPC response with binned Nsigma for pion + pidtpc_tiny::TPCNSigmaStorePi, pidtpc_tiny::TPCNSigmaPi); +DECLARE_SOA_TABLE(pidTPCKa, "AOD", "pidTPCKa", //! Table of the TPC response with binned Nsigma for kaon + pidtpc_tiny::TPCNSigmaStoreKa, pidtpc_tiny::TPCNSigmaKa); +DECLARE_SOA_TABLE(pidTPCPr, "AOD", "pidTPCPr", //! Table of the TPC response with binned Nsigma for proton + pidtpc_tiny::TPCNSigmaStorePr, pidtpc_tiny::TPCNSigmaPr); +DECLARE_SOA_TABLE(pidTPCDe, "AOD", "pidTPCDe", //! Table of the TPC response with binned Nsigma for deuteron + pidtpc_tiny::TPCNSigmaStoreDe, pidtpc_tiny::TPCNSigmaDe); +DECLARE_SOA_TABLE(pidTPCTr, "AOD", "pidTPCTr", //! Table of the TPC response with binned Nsigma for triton + pidtpc_tiny::TPCNSigmaStoreTr, pidtpc_tiny::TPCNSigmaTr); +DECLARE_SOA_TABLE(pidTPCHe, "AOD", "pidTPCHe", //! Table of the TPC response with binned Nsigma for helium3 + pidtpc_tiny::TPCNSigmaStoreHe, pidtpc_tiny::TPCNSigmaHe); +DECLARE_SOA_TABLE(pidTPCAl, "AOD", "pidTPCAl", //! Table of the TPC response with binned Nsigma for alpha + pidtpc_tiny::TPCNSigmaStoreAl, pidtpc_tiny::TPCNSigmaAl); + +// Extra tables +namespace mcpidtpc +{ +// Tuned MC on data +DECLARE_SOA_COLUMN(DeDxTunedMc, mcTunedTPCSignal, float); //! TPC signal after TuneOnData application for MC +} // namespace mcpidtpc + +DECLARE_SOA_TABLE(mcTPCTuneOnData, "AOD", "MCTPCTUNEONDATA", mcpidtpc::DeDxTunedMc); + +} // namespace o2::aod + +#endif // COMMON_DATAMODEL_PIDRESPONSETPC_H_ diff --git a/Common/TableProducer/PID/pidBayes.cxx b/Common/TableProducer/PID/pidBayes.cxx index c990875e967..abedb281668 100644 --- a/Common/TableProducer/PID/pidBayes.cxx +++ b/Common/TableProducer/PID/pidBayes.cxx @@ -16,6 +16,12 @@ /// Only the tables for the mass hypotheses requested are filled, the others are sent empty. /// +#include +#include +#include +#include +#include + // O2 includes #include "Framework/AnalysisTask.h" #include "Framework/HistogramRegistry.h" @@ -28,7 +34,9 @@ #include "Common/Core/PID/PIDTOF.h" #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "Common/DataModel/PIDResponse.h" +#include "Common/DataModel/PIDResponseCombined.h" +#include "Common/DataModel/PIDResponseTPC.h" +#include "Common/DataModel/PIDResponseTOF.h" #include "pidTOFBase.h" diff --git a/Common/TableProducer/PID/pidTOF.cxx b/Common/TableProducer/PID/pidTOF.cxx index f26df966313..076cc0c26de 100644 --- a/Common/TableProducer/PID/pidTOF.cxx +++ b/Common/TableProducer/PID/pidTOF.cxx @@ -232,40 +232,31 @@ struct tofPid { { switch (id) { case 0: - aod::pidutils::packInTable(-999.f, - tablePIDEl); + aod::pidtof_tiny::binning::packInTable(-999.f, tablePIDEl); break; case 1: - aod::pidutils::packInTable(-999.f, - tablePIDMu); + aod::pidtof_tiny::binning::packInTable(-999.f, tablePIDMu); break; case 2: - aod::pidutils::packInTable(-999.f, - tablePIDPi); + aod::pidtof_tiny::binning::packInTable(-999.f, tablePIDPi); break; case 3: - aod::pidutils::packInTable(-999.f, - tablePIDKa); + aod::pidtof_tiny::binning::packInTable(-999.f, tablePIDKa); break; case 4: - aod::pidutils::packInTable(-999.f, - tablePIDPr); + aod::pidtof_tiny::binning::packInTable(-999.f, tablePIDPr); break; case 5: - aod::pidutils::packInTable(-999.f, - tablePIDDe); + aod::pidtof_tiny::binning::packInTable(-999.f, tablePIDDe); break; case 6: - aod::pidutils::packInTable(-999.f, - tablePIDTr); + aod::pidtof_tiny::binning::packInTable(-999.f, tablePIDTr); break; case 7: - aod::pidutils::packInTable(-999.f, - tablePIDHe); + aod::pidtof_tiny::binning::packInTable(-999.f, tablePIDHe); break; case 8: - aod::pidutils::packInTable(-999.f, - tablePIDAl); + aod::pidtof_tiny::binning::packInTable(-999.f, tablePIDAl); break; default: LOG(fatal) << "Wrong particle ID in makeTableEmpty()"; @@ -326,40 +317,40 @@ struct tofPid { for (auto const& pidId : mEnabledParticles) { // Loop on enabled particle hypotheses switch (pidId) { case 0: - aod::pidutils::packInTable(responseEl.GetSeparation(mRespParamsV2, trkInColl), - tablePIDEl); + aod::pidtof_tiny::binning::packInTable(responseEl.GetSeparation(mRespParamsV2, trkInColl), + tablePIDEl); break; case 1: - aod::pidutils::packInTable(responseMu.GetSeparation(mRespParamsV2, trkInColl), - tablePIDMu); + aod::pidtof_tiny::binning::packInTable(responseMu.GetSeparation(mRespParamsV2, trkInColl), + tablePIDMu); break; case 2: - aod::pidutils::packInTable(responsePi.GetSeparation(mRespParamsV2, trkInColl), - tablePIDPi); + aod::pidtof_tiny::binning::packInTable(responsePi.GetSeparation(mRespParamsV2, trkInColl), + tablePIDPi); break; case 3: - aod::pidutils::packInTable(responseKa.GetSeparation(mRespParamsV2, trkInColl), - tablePIDKa); + aod::pidtof_tiny::binning::packInTable(responseKa.GetSeparation(mRespParamsV2, trkInColl), + tablePIDKa); break; case 4: - aod::pidutils::packInTable(responsePr.GetSeparation(mRespParamsV2, trkInColl), - tablePIDPr); + aod::pidtof_tiny::binning::packInTable(responsePr.GetSeparation(mRespParamsV2, trkInColl), + tablePIDPr); break; case 5: - aod::pidutils::packInTable(responseDe.GetSeparation(mRespParamsV2, trkInColl), - tablePIDDe); + aod::pidtof_tiny::binning::packInTable(responseDe.GetSeparation(mRespParamsV2, trkInColl), + tablePIDDe); break; case 6: - aod::pidutils::packInTable(responseTr.GetSeparation(mRespParamsV2, trkInColl), - tablePIDTr); + aod::pidtof_tiny::binning::packInTable(responseTr.GetSeparation(mRespParamsV2, trkInColl), + tablePIDTr); break; case 7: - aod::pidutils::packInTable(responseHe.GetSeparation(mRespParamsV2, trkInColl), - tablePIDHe); + aod::pidtof_tiny::binning::packInTable(responseHe.GetSeparation(mRespParamsV2, trkInColl), + tablePIDHe); break; case 8: - aod::pidutils::packInTable(responseAl.GetSeparation(mRespParamsV2, trkInColl), - tablePIDAl); + aod::pidtof_tiny::binning::packInTable(responseAl.GetSeparation(mRespParamsV2, trkInColl), + tablePIDAl); break; default: LOG(fatal) << "Wrong particle ID in processWSlice()"; @@ -414,40 +405,40 @@ struct tofPid { for (auto const& pidId : mEnabledParticles) { // Loop on enabled particle hypotheses switch (pidId) { case 0: - aod::pidutils::packInTable(responseEl.GetSeparation(mRespParamsV2, track), - tablePIDEl); + aod::pidtof_tiny::binning::packInTable(responseEl.GetSeparation(mRespParamsV2, track), + tablePIDEl); break; case 1: - aod::pidutils::packInTable(responseMu.GetSeparation(mRespParamsV2, track), - tablePIDMu); + aod::pidtof_tiny::binning::packInTable(responseMu.GetSeparation(mRespParamsV2, track), + tablePIDMu); break; case 2: - aod::pidutils::packInTable(responsePi.GetSeparation(mRespParamsV2, track), - tablePIDPi); + aod::pidtof_tiny::binning::packInTable(responsePi.GetSeparation(mRespParamsV2, track), + tablePIDPi); break; case 3: - aod::pidutils::packInTable(responseKa.GetSeparation(mRespParamsV2, track), - tablePIDKa); + aod::pidtof_tiny::binning::packInTable(responseKa.GetSeparation(mRespParamsV2, track), + tablePIDKa); break; case 4: - aod::pidutils::packInTable(responsePr.GetSeparation(mRespParamsV2, track), - tablePIDPr); + aod::pidtof_tiny::binning::packInTable(responsePr.GetSeparation(mRespParamsV2, track), + tablePIDPr); break; case 5: - aod::pidutils::packInTable(responseDe.GetSeparation(mRespParamsV2, track), - tablePIDDe); + aod::pidtof_tiny::binning::packInTable(responseDe.GetSeparation(mRespParamsV2, track), + tablePIDDe); break; case 6: - aod::pidutils::packInTable(responseTr.GetSeparation(mRespParamsV2, track), - tablePIDTr); + aod::pidtof_tiny::binning::packInTable(responseTr.GetSeparation(mRespParamsV2, track), + tablePIDTr); break; case 7: - aod::pidutils::packInTable(responseHe.GetSeparation(mRespParamsV2, track), - tablePIDHe); + aod::pidtof_tiny::binning::packInTable(responseHe.GetSeparation(mRespParamsV2, track), + tablePIDHe); break; case 8: - aod::pidutils::packInTable(responseAl.GetSeparation(mRespParamsV2, track), - tablePIDAl); + aod::pidtof_tiny::binning::packInTable(responseAl.GetSeparation(mRespParamsV2, track), + tablePIDAl); break; default: LOG(fatal) << "Wrong particle ID in processWoSlice()"; diff --git a/Common/TableProducer/PID/pidTOFBase.h b/Common/TableProducer/PID/pidTOFBase.h index 2861cf883ce..44367eacb75 100644 --- a/Common/TableProducer/PID/pidTOFBase.h +++ b/Common/TableProducer/PID/pidTOFBase.h @@ -24,6 +24,7 @@ // O2Physics #include "PID/ParamBase.h" #include "PID/PIDTOF.h" +#include "Common/DataModel/PIDResponseTOF.h" #include "Common/DataModel/PIDResponse.h" static constexpr int nSpecies = 9; diff --git a/Common/TableProducer/PID/pidTOFMerge.cxx b/Common/TableProducer/PID/pidTOFMerge.cxx index 2d2fd282bfd..7de835f4653 100644 --- a/Common/TableProducer/PID/pidTOFMerge.cxx +++ b/Common/TableProducer/PID/pidTOFMerge.cxx @@ -1083,72 +1083,63 @@ struct tofPidMerge { if (fullTable) { tablePIDFullEl(-999.f, -999.f); } else { - aod::pidutils::packInTable(-999.f, - tablePIDEl); + aod::pidtof_tiny::binning::packInTable(-999.f, tablePIDEl); } break; case kIdxMu: if (fullTable) { tablePIDFullMu(-999.f, -999.f); } else { - aod::pidutils::packInTable(-999.f, - tablePIDMu); + aod::pidtof_tiny::binning::packInTable(-999.f, tablePIDMu); } break; case kIdxPi: if (fullTable) { tablePIDFullPi(-999.f, -999.f); } else { - aod::pidutils::packInTable(-999.f, - tablePIDPi); + aod::pidtof_tiny::binning::packInTable(-999.f, tablePIDPi); } break; case kIdxKa: if (fullTable) { tablePIDFullKa(-999.f, -999.f); } else { - aod::pidutils::packInTable(-999.f, - tablePIDKa); + aod::pidtof_tiny::binning::packInTable(-999.f, tablePIDKa); } break; case kIdxPr: if (fullTable) { tablePIDFullPr(-999.f, -999.f); } else { - aod::pidutils::packInTable(-999.f, - tablePIDPr); + aod::pidtof_tiny::binning::packInTable(-999.f, tablePIDPr); } break; case kIdxDe: if (fullTable) { tablePIDFullDe(-999.f, -999.f); } else { - aod::pidutils::packInTable(-999.f, - tablePIDDe); + aod::pidtof_tiny::binning::packInTable(-999.f, tablePIDDe); } break; case kIdxTr: if (fullTable) { tablePIDFullTr(-999.f, -999.f); } else { - aod::pidutils::packInTable(-999.f, - tablePIDTr); + aod::pidtof_tiny::binning::packInTable(-999.f, tablePIDTr); } break; case kIdxHe: if (fullTable) { tablePIDFullHe(-999.f, -999.f); } else { - aod::pidutils::packInTable(-999.f, - tablePIDHe); + aod::pidtof_tiny::binning::packInTable(-999.f, tablePIDHe); } break; case kIdxAl: if (fullTable) { tablePIDFullAl(-999.f, -999.f); } else { - aod::pidutils::packInTable(-999.f, - tablePIDAl); + aod::pidtof_tiny::binning::packInTable(-999.f, tablePIDAl); } break; default: @@ -1202,47 +1193,47 @@ struct tofPidMerge { switch (pidId) { case kIdxEl: { nsigma = responseEl.GetSeparation(mRespParamsV3, trk); - aod::pidutils::packInTable(nsigma, tablePIDEl); + aod::pidtof_tiny::binning::packInTable(nsigma, tablePIDEl); break; } case kIdxMu: { nsigma = responseMu.GetSeparation(mRespParamsV3, trk); - aod::pidutils::packInTable(nsigma, tablePIDMu); + aod::pidtof_tiny::binning::packInTable(nsigma, tablePIDMu); break; } case kIdxPi: { nsigma = responsePi.GetSeparation(mRespParamsV3, trk); - aod::pidutils::packInTable(nsigma, tablePIDPi); + aod::pidtof_tiny::binning::packInTable(nsigma, tablePIDPi); break; } case kIdxKa: { nsigma = responseKa.GetSeparation(mRespParamsV3, trk); - aod::pidutils::packInTable(nsigma, tablePIDKa); + aod::pidtof_tiny::binning::packInTable(nsigma, tablePIDKa); break; } case kIdxPr: { nsigma = responsePr.GetSeparation(mRespParamsV3, trk); - aod::pidutils::packInTable(nsigma, tablePIDPr); + aod::pidtof_tiny::binning::packInTable(nsigma, tablePIDPr); break; } case kIdxDe: { nsigma = responseDe.GetSeparation(mRespParamsV3, trk); - aod::pidutils::packInTable(nsigma, tablePIDDe); + aod::pidtof_tiny::binning::packInTable(nsigma, tablePIDDe); break; } case kIdxTr: { nsigma = responseTr.GetSeparation(mRespParamsV3, trk); - aod::pidutils::packInTable(nsigma, tablePIDTr); + aod::pidtof_tiny::binning::packInTable(nsigma, tablePIDTr); break; } case kIdxHe: { nsigma = responseHe.GetSeparation(mRespParamsV3, trk); - aod::pidutils::packInTable(nsigma, tablePIDHe); + aod::pidtof_tiny::binning::packInTable(nsigma, tablePIDHe); break; } case kIdxAl: { nsigma = responseAl.GetSeparation(mRespParamsV3, trk); - aod::pidutils::packInTable(nsigma, tablePIDAl); + aod::pidtof_tiny::binning::packInTable(nsigma, tablePIDAl); break; } default: @@ -1364,47 +1355,47 @@ struct tofPidMerge { switch (pidId) { case kIdxEl: { nsigma = responseEl.GetSeparation(mRespParamsV3, trk); - aod::pidutils::packInTable(nsigma, tablePIDEl); + aod::pidtof_tiny::binning::packInTable(nsigma, tablePIDEl); break; } case kIdxMu: { nsigma = responseMu.GetSeparation(mRespParamsV3, trk); - aod::pidutils::packInTable(nsigma, tablePIDMu); + aod::pidtof_tiny::binning::packInTable(nsigma, tablePIDMu); break; } case kIdxPi: { nsigma = responsePi.GetSeparation(mRespParamsV3, trk); - aod::pidutils::packInTable(nsigma, tablePIDPi); + aod::pidtof_tiny::binning::packInTable(nsigma, tablePIDPi); break; } case kIdxKa: { nsigma = responseKa.GetSeparation(mRespParamsV3, trk); - aod::pidutils::packInTable(nsigma, tablePIDKa); + aod::pidtof_tiny::binning::packInTable(nsigma, tablePIDKa); break; } case kIdxPr: { nsigma = responsePr.GetSeparation(mRespParamsV3, trk); - aod::pidutils::packInTable(nsigma, tablePIDPr); + aod::pidtof_tiny::binning::packInTable(nsigma, tablePIDPr); break; } case kIdxDe: { nsigma = responseDe.GetSeparation(mRespParamsV3, trk); - aod::pidutils::packInTable(nsigma, tablePIDDe); + aod::pidtof_tiny::binning::packInTable(nsigma, tablePIDDe); break; } case kIdxTr: { nsigma = responseTr.GetSeparation(mRespParamsV3, trk); - aod::pidutils::packInTable(nsigma, tablePIDTr); + aod::pidtof_tiny::binning::packInTable(nsigma, tablePIDTr); break; } case kIdxHe: { nsigma = responseHe.GetSeparation(mRespParamsV3, trk); - aod::pidutils::packInTable(nsigma, tablePIDHe); + aod::pidtof_tiny::binning::packInTable(nsigma, tablePIDHe); break; } case kIdxAl: { nsigma = responseAl.GetSeparation(mRespParamsV3, trk); - aod::pidutils::packInTable(nsigma, tablePIDAl); + aod::pidtof_tiny::binning::packInTable(nsigma, tablePIDAl); break; } default: diff --git a/Common/TableProducer/PID/pidTPC.cxx b/Common/TableProducer/PID/pidTPC.cxx index 1fe071f2717..64500a47cb7 100644 --- a/Common/TableProducer/PID/pidTPC.cxx +++ b/Common/TableProducer/PID/pidTPC.cxx @@ -35,7 +35,7 @@ #include "Framework/ASoAHelpers.h" #include "ReconstructionDataFormats/Track.h" #include "CCDB/CcdbApi.h" -#include "Common/DataModel/PIDResponse.h" +#include "Common/DataModel/PIDResponseTPC.h" #include "Common/Core/PID/TPCPIDResponse.h" #include "Framework/AnalysisDataModel.h" #include "Common/DataModel/Multiplicity.h" @@ -458,7 +458,7 @@ struct tpcPid { if (flagFull) tableFull(expSigma, nSigma); if (flagTiny) - aod::pidutils::packInTable(nSigma, tableTiny); + aod::pidtpc_tiny::binning::packInTable(nSigma, tableTiny); }; void processStandard(Coll const& collisions, Trks const& tracks, aod::BCsWithTimestamps const& bcs) diff --git a/Common/TableProducer/PID/pidTPCBase.h b/Common/TableProducer/PID/pidTPCBase.h index a882a598ef9..937eea21c48 100644 --- a/Common/TableProducer/PID/pidTPCBase.h +++ b/Common/TableProducer/PID/pidTPCBase.h @@ -19,7 +19,7 @@ #define COMMON_TABLEPRODUCER_PID_PIDTPCBASE_H_ #include "Common/DataModel/Multiplicity.h" -#include "Common/DataModel/PIDResponse.h" +#include "Common/DataModel/PIDResponseTPC.h" namespace o2::aod { diff --git a/Common/TableProducer/match-mft-mch-data.cxx b/Common/TableProducer/match-mft-mch-data.cxx index b566d9531f8..01139da21ba 100644 --- a/Common/TableProducer/match-mft-mch-data.cxx +++ b/Common/TableProducer/match-mft-mch-data.cxx @@ -19,7 +19,6 @@ #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Centrality.h" #include "Common/CCDB/TriggerAliases.h" -#include "Common/DataModel/PIDResponse.h" #include "Common/DataModel/TrackSelectionTables.h" #include "Common/DataModel/MftmchMatchingML.h" #include "Common/DataModel/MatchMFTMuonData.h" diff --git a/Common/TableProducer/mcCollsExtra.cxx b/Common/TableProducer/mcCollsExtra.cxx index c085969c5af..452930494ba 100644 --- a/Common/TableProducer/mcCollsExtra.cxx +++ b/Common/TableProducer/mcCollsExtra.cxx @@ -39,7 +39,6 @@ #include "Common/DataModel/TrackSelectionTables.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Centrality.h" -#include "Common/DataModel/PIDResponse.h" #include "DetectorsBase/Propagator.h" #include "DetectorsBase/GeometryManager.h" #include "DataFormatsParameters/GRPObject.h" diff --git a/Common/Tools/PID/checkPidPacking.cxx b/Common/Tools/PID/checkPidPacking.cxx index c503ee1b288..84f72c4f48c 100644 --- a/Common/Tools/PID/checkPidPacking.cxx +++ b/Common/Tools/PID/checkPidPacking.cxx @@ -16,7 +16,10 @@ /// \since 03/05/2024 /// -#include "Common/DataModel/PIDResponse.h" +#include + +#include "Common/DataModel/PIDResponseTOF.h" +#include "Common/DataModel/PIDResponseTPC.h" #include "TH1F.h" #include "TCanvas.h" #include "TRandom.h" @@ -32,7 +35,7 @@ bool process(std::string outputName, int nevents = 100000) NsigmaContainer() {} void operator()(const int8_t& packed) { mPacked = packed; } int8_t mPacked = 0; - float unpack() { return aod::pidutils::unPackInTable(mPacked); } + float unpack() { return T::unPackInTable(mPacked); } } container; TH1F* hgaus = new TH1F("hgaus", "", 20 / T::bin_width, @@ -55,12 +58,12 @@ bool process(std::string outputName, int nevents = 100000) for (int i = 0; i < nevents; i++) { float nsigma = gRandom->Gaus(0, 1); hgaus->Fill(nsigma); - aod::pidutils::packInTable(nsigma, container); + T::packInTable(nsigma, container); hgausPacked->Fill(container.unpack()); nsigma = gRandom->Uniform(-10, 10); huniform->Fill(nsigma); - aod::pidutils::packInTable(nsigma, container); + T::packInTable(nsigma, container); huniformPacked->Fill(container.unpack()); } diff --git a/Common/Tools/aodDataModelGraph.cxx b/Common/Tools/aodDataModelGraph.cxx index 3b1afaba2ca..da854a700f5 100644 --- a/Common/Tools/aodDataModelGraph.cxx +++ b/Common/Tools/aodDataModelGraph.cxx @@ -8,10 +8,15 @@ // 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 +#include +#include +#include #include "Framework/AnalysisDataModel.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" -#include "Common/DataModel/PIDResponse.h" +#include "Common/DataModel/PIDResponseTOF.h" +#include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/TrackSelectionTables.h" @@ -87,8 +92,13 @@ template Style getStyleFor() { auto label = MetadataTrait::metadata::tableLabel(); - auto entry = std::find_if(tableStyles.begin(), tableStyles.end(), [&](auto&& x) { if (std::string(label).find(x.first) != std::string::npos) { return true; -}return false; }); + auto entry = std::find_if(tableStyles.begin(), tableStyles.end(), + [&](auto&& x) { + if (std::string(label).find(x.first) != std::string::npos) { + return true; + } + return false; + }); if (entry != tableStyles.end()) { auto value = *entry; return styles[value.second]; diff --git a/DPG/Tasks/TPC/tpcSkimsTableCreator.cxx b/DPG/Tasks/TPC/tpcSkimsTableCreator.cxx index 77b563c5567..480e3c9d04b 100644 --- a/DPG/Tasks/TPC/tpcSkimsTableCreator.cxx +++ b/DPG/Tasks/TPC/tpcSkimsTableCreator.cxx @@ -20,6 +20,7 @@ #include #include #include +#include /// ROOT #include "TRandom3.h" /// O2 @@ -53,6 +54,7 @@ struct TreeWriterTpcV0 { using Trks = soa::Join; using Colls = soa::Join; using MyBCTable = soa::Join; + using V0sWithID = soa::Join; /// Tables to be produced Produces rowTPCTree; @@ -63,6 +65,7 @@ struct TreeWriterTpcV0 { Configurable nClNorm{"nClNorm", 152., "Number of cluster normalization. Run 2: 159, Run 3 152"}; Configurable applyEvSel{"applyEvSel", 2, "Flag to apply rapidity cut: 0 -> no event selection, 1 -> Run 2 event selection, 2 -> Run 3 event selection"}; Configurable trackSelection{"trackSelection", 1, "Track selection: 0 -> No Cut, 1 -> kGlobalTrack, 2 -> kGlobalTrackWoPtEta, 3 -> kGlobalTrackWoDCA, 4 -> kQualityTracks, 5 -> kInAcceptanceTracks"}; + Configurable irSource{"irSource", "T0VTX", "Estimator of the interaction rate (Recommended: pp --> T0VTX, Pb-Pb --> ZNC hadronic)"}; /// Configurables downsampling Configurable dwnSmplFactor_Pi{"dwnSmplFactor_Pi", 1., "downsampling factor for pions, default fraction to keep is 1."}; Configurable dwnSmplFactor_Pr{"dwnSmplFactor_Pr", 1., "downsampling factor for protons, default fraction to keep is 1."}; @@ -90,6 +93,7 @@ struct TreeWriterTpcV0 { { const double ncl = track.tpcNClsFound(); + const double nclPID = track.tpcNClsFindableMinusPID(); const double p = track.tpcInnerParam(); const double mass = o2::track::pid_constants::sMasses[id]; const double bg = p / mass; @@ -118,6 +122,7 @@ struct TreeWriterTpcV0 { bg, multTPC / 11000., std::sqrt(nClNorm / ncl), + nclPID, id, nSigmaTPC, nSigmaTOF, @@ -140,6 +145,7 @@ struct TreeWriterTpcV0 { { const double ncl = track.tpcNClsFound(); + const double nclPID = track.tpcNClsFindableMinusPID(); const double p = track.tpcInnerParam(); const double mass = o2::track::pid_constants::sMasses[id]; const double bg = p / mass; @@ -168,6 +174,7 @@ struct TreeWriterTpcV0 { bg, multTPC / 11000., std::sqrt(nClNorm / ncl), + nclPID, id, nSigmaTPC, nSigmaTOF, @@ -252,7 +259,7 @@ struct TreeWriterTpcV0 { } /// Apply a track quality selection with a filter! - void processStandard(Colls::iterator const& collision, soa::Filtered const& tracks, aod::V0Datas const& v0s, aod::BCsWithTimestamps const&) + void processStandard(Colls::iterator const& collision, soa::Filtered const& tracks, V0sWithID const& v0s, aod::BCsWithTimestamps const&) { /// Check event slection if (!isEventSelected(collision, tracks)) { @@ -260,7 +267,7 @@ struct TreeWriterTpcV0 { } auto bc = collision.bc_as(); const int runnumber = bc.runNumber(); - float hadronicRate = mRateFetcher.fetch(ccdb.service, bc.timestamp(), runnumber, "ZNC hadronic") * 1.e-3; + float hadronicRate = mRateFetcher.fetch(ccdb.service, bc.timestamp(), runnumber, irSource) * 1.e-3; rowTPCTree.reserve(tracks.size()); @@ -268,6 +275,9 @@ struct TreeWriterTpcV0 { for (const auto& v0 : v0s) { auto posTrack = v0.posTrack_as>(); auto negTrack = v0.negTrack_as>(); + if (v0.v0addid() == -1) { + continue; + } // gamma if (static_cast(posTrack.pidbit() & (1 << 0)) && static_cast(negTrack.pidbit() & (1 << 0))) { if (downsampleTsalisCharged(posTrack.pt(), downsamplingTsalisElectrons, sqrtSNN, o2::track::pid_constants::sMasses[o2::track::PID::Electron], maxPt4dwnsmplTsalisElectrons)) { @@ -313,8 +323,8 @@ struct TreeWriterTpcV0 { PROCESS_SWITCH(TreeWriterTpcV0, processStandard, "Standard V0 Samples for PID", true); Preslice perCollisionTracks = aod::track::collisionId; - Preslice perCollisionV0s = aod::v0data::collisionId; - void processWithTrQA(Colls const& collisions, Trks const& myTracks, aod::V0Datas const& myV0s, MyBCTable const&, aod::TracksQA_002 const& tracksQA) + Preslice perCollisionV0s = aod::v0data::collisionId; + void processWithTrQA(Colls const& collisions, Trks const& myTracks, V0sWithID const& myV0s, MyBCTable const&, aod::TracksQA_002 const& tracksQA) { std::vector labelTrack2TrackQA; labelTrack2TrackQA.clear(); @@ -333,7 +343,7 @@ struct TreeWriterTpcV0 { } auto bc = collision.bc_as(); const int runnumber = bc.runNumber(); - float hadronicRate = mRateFetcher.fetch(ccdb.service, bc.timestamp(), runnumber, "ZNC hadronic") * 1.e-3; + float hadronicRate = mRateFetcher.fetch(ccdb.service, bc.timestamp(), runnumber, irSource) * 1.e-3; const int bcGlobalIndex = bc.globalIndex(); const int bcTimeFrameId = bc.tfId(); const int bcBcInTimeFrame = bc.bcInTF(); @@ -342,6 +352,9 @@ struct TreeWriterTpcV0 { for (const auto& v0 : v0s) { auto posTrack = v0.posTrack_as(); auto negTrack = v0.negTrack_as(); + if (v0.v0addid() == -1) { + continue; + } aod::TracksQA_002::iterator posTrackQA; aod::TracksQA_002::iterator negTrackQA; bool existPosTrkQA; @@ -432,6 +445,7 @@ struct TreeWriterTPCTOF { Configurable applyEvSel{"applyEvSel", 2, "Flag to apply rapidity cut: 0 -> no event selection, 1 -> Run 2 event selection, 2 -> Run 3 event selection"}; Configurable applyTrkSel{"applyTrkSel", 1, "Flag to apply track selection: 0 -> no track selection, 1 -> track selection"}; Configurable trackSelection{"trackSelection", 1, "Track selection: 0 -> No Cut, 1 -> kGlobalTrack, 2 -> kGlobalTrackWoPtEta, 3 -> kGlobalTrackWoDCA, 4 -> kQualityTracks, 5 -> kInAcceptanceTracks"}; + Configurable irSource{"irSource", "T0VTX", "Estimator of the interaction rate (Recommended: pp --> T0VTX, Pb-Pb --> ZNC hadronic)"}; /// Triton Configurable maxMomTPCOnlyTr{"maxMomTPCOnlyTr", 1.5, "Maximum momentum for TPC only cut triton"}; Configurable maxMomHardCutOnlyTr{"maxMomHardCutOnlyTr", 50, "Maximum TPC inner momentum for triton"}; @@ -517,6 +531,7 @@ struct TreeWriterTPCTOF { { const double ncl = track.tpcNClsFound(); + const double nclPID = track.tpcNClsFindableMinusPID(); const double p = track.tpcInnerParam(); const double mass = o2::track::pid_constants::sMasses[id]; const double bg = p / mass; @@ -538,6 +553,7 @@ struct TreeWriterTPCTOF { bg, multTPC / 11000., std::sqrt(nClNorm / ncl), + nclPID, id, nSigmaTPC, nSigmaTOF, @@ -553,6 +569,7 @@ struct TreeWriterTPCTOF { { const double ncl = track.tpcNClsFound(); + const double nclPID = track.tpcNClsFindableMinusPID(); const double p = track.tpcInnerParam(); const double mass = o2::track::pid_constants::sMasses[id]; const double bg = p / mass; @@ -574,6 +591,7 @@ struct TreeWriterTPCTOF { bg, multTPC / 11000., std::sqrt(nClNorm / ncl), + nclPID, id, nSigmaTPC, nSigmaTOF, @@ -628,7 +646,7 @@ struct TreeWriterTPCTOF { } auto bc = collision.bc_as(); const int runnumber = bc.runNumber(); - float hadronicRate = mRateFetcher.fetch(ccdb.service, bc.timestamp(), runnumber, "ZNC hadronic") * 1.e-3; + float hadronicRate = mRateFetcher.fetch(ccdb.service, bc.timestamp(), runnumber, irSource) * 1.e-3; rowTPCTOFTree.reserve(tracks.size()); for (auto const& trk : tracks) { @@ -688,7 +706,7 @@ struct TreeWriterTPCTOF { } auto bc = collision.bc_as(); const int runnumber = bc.runNumber(); - float hadronicRate = mRateFetcher.fetch(ccdb.service, bc.timestamp(), runnumber, "ZNC hadronic") * 1.e-3; + float hadronicRate = mRateFetcher.fetch(ccdb.service, bc.timestamp(), runnumber, irSource) * 1.e-3; const int bcGlobalIndex = bc.globalIndex(); const int bcTimeFrameId = bc.tfId(); const int bcBcInTimeFrame = bc.bcInTF(); diff --git a/DPG/Tasks/TPC/tpcSkimsTableCreator.h b/DPG/Tasks/TPC/tpcSkimsTableCreator.h index 0f7e2264a25..1dcab1abfae 100644 --- a/DPG/Tasks/TPC/tpcSkimsTableCreator.h +++ b/DPG/Tasks/TPC/tpcSkimsTableCreator.h @@ -33,6 +33,7 @@ DECLARE_SOA_COLUMN(Mass, mass, float); DECLARE_SOA_COLUMN(BetaGamma, bg, float); DECLARE_SOA_COLUMN(NormMultTPC, normMultTPC, float); DECLARE_SOA_COLUMN(NormNClustersTPC, normNClustersTPC, float); +DECLARE_SOA_COLUMN(NormNClustersTPCPID, normNClustersTPCPID, float); DECLARE_SOA_COLUMN(PidIndex, pidIndexTPC, uint8_t); DECLARE_SOA_COLUMN(NSigTPC, nsigTPC, float); DECLARE_SOA_COLUMN(NSigTOF, nsigTOF, float); @@ -64,6 +65,7 @@ DECLARE_SOA_TABLE(SkimmedTPCV0Tree, "AOD", "TPCSKIMV0TREE", tpcskims::BetaGamma, tpcskims::NormMultTPC, tpcskims::NormNClustersTPC, + tpcskims::NormNClustersTPCPID, tpcskims::PidIndex, tpcskims::NSigTPC, tpcskims::NSigTOF, @@ -90,6 +92,7 @@ DECLARE_SOA_TABLE(SkimmedTPCV0TreeWithTrkQA, "AOD", "TPCSKIMV0WQA", tpcskims::BetaGamma, tpcskims::NormMultTPC, tpcskims::NormNClustersTPC, + tpcskims::NormNClustersTPCPID, tpcskims::PidIndex, tpcskims::NSigTPC, tpcskims::NSigTOF, @@ -129,6 +132,7 @@ DECLARE_SOA_TABLE(SkimmedTPCTOFTree, "AOD", "TPCTOFSKIMTREE", tpcskims::BetaGamma, tpcskims::NormMultTPC, tpcskims::NormNClustersTPC, + tpcskims::NormNClustersTPCPID, tpcskims::PidIndex, tpcskims::NSigTPC, tpcskims::NSigTOF, @@ -150,6 +154,7 @@ DECLARE_SOA_TABLE(SkimmedTPCTOFTreeWithTrkQA, "AOD", "TPCTOFSKIMWQA", tpcskims::BetaGamma, tpcskims::NormMultTPC, tpcskims::NormNClustersTPC, + tpcskims::NormNClustersTPCPID, tpcskims::PidIndex, tpcskims::NSigTPC, tpcskims::NSigTOF, diff --git a/EventFiltering/CMakeLists.txt b/EventFiltering/CMakeLists.txt index d67c1589457..554431848c9 100644 --- a/EventFiltering/CMakeLists.txt +++ b/EventFiltering/CMakeLists.txt @@ -54,7 +54,7 @@ o2physics_add_dpl_workflow(hf-filter-prepare-ml-samples o2physics_add_dpl_workflow(cf-filter SOURCES PWGCF/CFFilterAll.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore KFParticle::KFParticle O2::ReconstructionDataFormats O2::DetectorsBase COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(cf-filter-qa @@ -109,7 +109,7 @@ o2physics_add_dpl_workflow(heavy-neutral-meson-filter o2physics_add_dpl_workflow(lf-f1proton-filter SOURCES PWGLF/filterf1proton.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2::DetectorsBase + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore KFParticle::KFParticle O2::DetectorsBase COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(lf-doublephi-filter diff --git a/EventFiltering/PWGCF/CFFilterAll.cxx b/EventFiltering/PWGCF/CFFilterAll.cxx index 4e326968b03..4df821ec669 100644 --- a/EventFiltering/PWGCF/CFFilterAll.cxx +++ b/EventFiltering/PWGCF/CFFilterAll.cxx @@ -14,1433 +14,1196 @@ /// /// \author Laura Serksnyte, TU München, laura.serksnyte@cern.ch; Anton Riedel, TU München, anton.riedel@cern.ch; Maximilian Korwieser, TU Munich, maximilian.korwieser@cern.ch -#include -#include #include #include #include "../filterTables.h" +#include "CCDB/BasicCCDBManager.h" +#include "DataFormatsParameters/GRPMagField.h" +#include "DCAFitter/DCAFitterN.h" +#include "DetectorsBase/Propagator.h" + #include "fairlogger/Logger.h" -#include "Framework/Configurable.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/runDataProcessing.h" -#include "CommonConstants/MathConstants.h" -#include "Common/Core/TrackSelection.h" -#include "Common/DataModel/TrackSelectionTables.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponse.h" #include "Common/DataModel/PIDResponseITS.h" -#include "PWGLF/DataModel/LFStrangenessTables.h" -#include "DataFormatsTPC/BetheBlochAleph.h" -#include "CCDB/BasicCCDBManager.h" -#include "CCDB/CcdbApi.h" +#include "Common/DataModel/TrackSelectionTables.h" +#include "Common/Core/RecoDecay.h" + +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/Configurable.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/runDataProcessing.h" + +#include "PWGLF/Utils/strangenessBuilderHelper.h" #include "Math/GenVector/Boost.h" #include "Math/Vector4D.h" #include "TMath.h" -#include "TRandom3.h" using namespace o2; +using namespace o2::aod; using namespace o2::framework; using namespace o2::framework::expressions; -namespace CFTrigger +namespace cf_trigger { // enums -enum CFThreeBodyTriggers { kPPP, - kPPL, - kPLL, - kLLL, - kPPPhi, - kPPRho, - kNThreeBodyTriggers }; -enum CFTwoBodyTriggers { kPD, - kLD, - kNTwoBodyTriggers -}; -enum ParticleSpecies { - kProton, - kDeuteron, - kPion, - kLambda, - kNParticleSpecies +enum CFTriggers { + kPPP, + kPPL, + kPLL, + kLLL, + kPPPhi, + kPPRho, + kPD, + kLD, + kRhoD, + kPhiD, + kNTriggers }; -enum V0Daughters { - kDaughPion, - kDaughProton, - kNV0Daughters + +// variables for track selection +const std::vector trackNames{"Pion", "Kaon", "Proton", "Deuteron"}; +const uint32_t nTrackNames = 4; + +const std::vector trackSelectionNames{"AbsEtaMax", "TpcClusterMin", "TpcRowMin", "TpcCrossedOverFoundMin", "TpcSharedMax", "TpcFracSharedMax", "ItsClusterMin", "ItsIbClusterMin", "AbsDcaXyMax", "AbsDcaZMax", "Chi2TpcMax", "Chi2ItsMax"}; +const uint32_t nTrackSelectionNames = 12; + +const float trackSelectionTable[nTrackNames][nTrackSelectionNames] = { + {0.85, 90, 80, 0.83, 160, 1, 1, 0, 0.15, 0.15, 99, 99}, // Pion + {0.85, 90, 80, 0.83, 160, 1, 1, 0, 0.15, 0.15, 99, 99}, // Kaon + {0.85, 90, 80, 0.83, 160, 1, 1, 0, 0.15, 0.15, 99, 99}, // Proton + {0.85, 90, 80, 0.83, 160, 1, 1, 0, 0.15, 0.15, 99, 99}, // Deuteron }; -enum ParticleRejection { kRejProton, - kRejPion, - kRejElectron, - kNParticleRejection + +const std::vector pidSelectionNames{"ItsMin", "ItsMax", "TpcMin", "TpcMax", "TpcTofMax"}; +const uint32_t nPidSelectionNames = 5; + +const float pidSelectionTable[nTrackNames][nPidSelectionNames] = { + {-99, 99, -4, 4, 4}, // Pion + {-99, 99, -4, 4, 4}, // Kaon + {-99, 99, -4, 4, 4}, // Proton + {-3.5, 3.5, -3.5, 3.5, 3.5}, // Deuteron }; -enum PIDLimits { kTPCMin, - kTPCMax, - kTOFMin, - kTOFMax, - kTPCTOF, - kITSmin, - kITSmax, - kNPIDLimits + +const std::vector momentumSelectionNames{"PtMin", "PtMax", "PThres", "UseInnerParam"}; +const uint32_t nMomentumSelectionNames = 4; + +const float momentumSelectionTable[nTrackNames][nMomentumSelectionNames] = { + {0, 6, 0.4, -1}, // Pion + {0, 6, 0.5, -1}, // Kaon + {0.3, 6, 0.75, -1}, // Proton + {0.4, 2, 1.2, -1}, // Deuteron }; -// For configurable tables -static const std::vector CFTriggerNamesALL{"ppp", "ppL", "pLL", "LLL", "ppPhi", "ppRho", "pd", "Ld"}; -static const std::vector SpeciesNameAll{"Proton", "Deuteron", "Lambda", "Pion"}; -static const std::vector SpeciesName{"Proton", "Deuteron", "Pion"}; -static const std::vector SpeciesNameAnti{"AntiProton", "AntiDeuteron", "AntiPion"}; -static const std::vector SpeciesV0DaughterName{"Pion", "Proton"}; -static const std::vector SpeciesRejectionName{"Proton", "Pion", "Electron"}; -static const std::vector TPCCutName{"TPC min", "TPC max"}; -static const std::vector SpeciesMinTPCClustersName{"Proton", "Deuteron", "Pion"}; -static const std::vector SpeciesAvgTPCTOFName{"Proton", "AntiProton", "Deuteron", "AntiDeuteron", "Pion", "AntiPion"}; -static const std::vector TPCTOFAvgName{"TPC Avg", "TOF Avg"}; -static const std::vector PidCutsName{"TPC min", "TPC max", "TOF min", "TOF max", "TPCTOF max", "ITS min", "ITS max"}; -static const std::vector PtCutsName{"Pt min (particle)", "Pt max (particle)", "Pt min (antiparticle)", "Pt max (antiparticle)", "P thres"}; -static const std::vector MomCorCutsName{"Momemtum Correlation min", "Momemtum Correlation max"}; -static const std::vector PIDForTrackingName{"Switch", "Momemtum Threshold"}; -static const std::vector ThreeBodyFilterNames{"PPP", "PPL", "PLL", "LLL", "PPPhi", "PPRho"}; -static const std::vector TwoBodyFilterNames{"PD", "LD"}; -static const std::vector ParticleNames{"PPP", "aPaPaP", "PPL", "aPaPaL", "PLL", "aPaLaL", "LLL", "aLaLaL", "PPPhi", "aPaPPhi", "PPRho", "aPaPRho", "PD", "aPaD", "LD", "aLaD"}; - -static const int nPidRejection = 2; -static const int nTracks = 3; -static const int nPidAvg = 6; -static const int nPidCutsDaughers = 2; -static const int nPtCuts = 5; -static const int nAllTriggers = 8; -static const int nTriggerAllNames = 16; -static const int nMomCorCuts = 2; -static const int nTPCTOFAvg = 2; - -static const float pidcutsTable[nTracks][kNPIDLimits]{ - {-6.f, 6.f, -6.f, 6.f, 6.f, -99.f, 99.f}, - {-6.f, 6.f, -99.f, 99.f, 99.f, -6.f, 6.f}, - {-6.f, 6.f, -99.f, 99.f, 99.f, -9999.f, 9999.f}}; -static const float pidcutsTableAnti[nTracks][kNPIDLimits]{ - {-6.f, 6.f, -6.f, 6.f, 6.f, -99.f, 99.f}, - {-6.f, 6.f, -99.f, 99.f, 99.f, -6.f, 6.f}, - {-6.f, 6.f, -99.f, 99.f, 99.f, -9999.f, 9999.f}}; -static const float pidRejectionTable[kNParticleRejection][nPidRejection]{ - {-2.f, 2.f}, - {-2.f, 2.f}, - {-999.f, 999.f}}; -static const double pidTPCTOFAvgTable[nPidAvg][nTPCTOFAvg]{ - {0.f, 0.f}, - {0.f, 0.f}, - {0.f, 0.f}, - {0.f, 0.f}, - {0.f, 0.f}, - {0.f, 0.f}}; -static const float pidcutsV0DaughterTable[kNV0Daughters][nPidCutsDaughers]{ - {-6.f, 6.f}, - {-6.f, 6.f}}; -static const float ptcutsTable[kNParticleSpecies][nPtCuts]{ - {0.35f, 6.f, 0.35f, 6.0f, 0.75f}, - {0.35f, 1.6f, 0.35f, 1.6f, 99.f}, - {0.f, 6.f, 0.f, 6.f, 99.f}, - {0.f, 6.f, 0.f, 6.f, 99.f}}; -static const float NClustersMin[1][nTracks]{ - {60.0f, 60.0f, 60.0f}}; -static const float MomCorLimits[3][nMomCorCuts] = - {{-99, 99}, - {-99, 99}, - {-99, 99}}; -static const float PIDForTrackingTable[nTracks][2]{ - {-1, 0.75}, - {-1, 1.2}, - {-1, 1.2}}; -static const float ITSCutsTable[1][nTracks] = { - {1, 1, 0}}; - -static const float triggerSwitches[1][nAllTriggers]{ - {1, 1, 1, 1, 1, 1, 1, 1}}; - -static const float Q3Limits[1][kNThreeBodyTriggers]{ - {0.6f, 0.6f, 0.6f, 0.6f, 0.6f, 0.6f}}; - -static const float KstarLimits[1][kNTwoBodyTriggers]{ - {1.2f, 1.2f}}; - -static const float Downsample[2][nTriggerAllNames]{ - {-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.}}; - -} // namespace CFTrigger - -namespace o2::aod -{ -using FemtoFullCollision = - soa::Join::iterator; +// variables for triggers +const std::vector filterNames{"PPP", "PPL", "PLL", "LLL", "PPPhi", "PPRho", "PD", "LD", "PhiD", "RhoD"}; +const uint32_t nFilterNames = 10; -using FemtoFullTracks = - soa::Join; -} // namespace o2::aod +const std::vector switches{"Switch"}; +const uint32_t nSwitches = 1; -struct CFFilter { +const float filterTable[nSwitches][nFilterNames]{ + {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}}; - Produces tags; +const std::vector limitNames{"Tight Limit", "Loose Limit"}; +const uint32_t nLimitNames = 2; - Service ccdb; - o2::ccdb::CcdbApi ccdbApi; +const float limitTable[nLimitNames][nFilterNames]{ + {0.6f, 0.6f, 0.6f, 0.6f, 0.6f, 0.6f, 0.5f, 0.5f, 0.5f, 0.5f}, + {1.2f, 1.2f, 1.2f, 1.2f, 1.2f, 1.2f, 1.0f, 1.0f, 1.0f, 1.0f}}; + +using FullCollisions = soa::Join; +using FullCollision = FullCollisions::iterator; + +using FullTracks = soa::Join; - Configurable ConfRngSeed{"ConfRngSeed", 69, "Seed for downsampling"}; - TRandom3* rng; +} // namespace cf_trigger + +struct CFFilterAll { + + Produces tags; // Configs for events - Configurable ConfIsRun3{ - "ConfIsRun3", - true, - "Is Run3"}; - - Configurable ConfEvtSelectZvtx{ - "ConfEvtSelectZvtx", - true, - "Event selection includes max. z-Vertex"}; - Configurable ConfEvtZvtx{"ConfEvtZvtx", - 10.f, - "Evt sel: Max. z-Vertex (cm)"}; - Configurable ConfEvtOfflineCheck{ - "ConfEvtOfflineCheck", - false, - "Evt sel: check for offline selection"}; - Configurable ConfEvtTimeFrameBorderCheck{ - "ConfEvtTimeFrameBorderCheck", - true, - "Evt sel: check for offline selection"}; - Configurable ConfAutocorRejection{ - "ConfAutocorRejection", - true, - "Rejection autocorrelation pL pairs"}; + struct : ConfigurableGroup { + std::string prefix = "EventSel"; + Configurable zvtx{"zvtx", 12.f, "Max. z-Vertex (cm)"}; + Configurable eventSel{"eventSel", true, "Use sel8"}; + } EventSelection; // Configs for tracks - Configurable ConfDeuteronThPVMom{ - "ConfDeuteronThPVMom", - false, - "True: use momentum at PV instead of TPCinnerparameter for threshold"}; - - Configurable ConfUseManualPIDproton{ - "ConfUseManualPIDproton", - false, - "True: use home-made PID solution for proton "}; - Configurable ConfPIDBBProton{ - "ConfPIDBBProton", - "Users/l/lserksny/PIDProton", - "Path to the CCDB ocject for proton BB param"}; - Configurable ConfPIDBBAntiProton{ - "ConfPIDBBAntiProton", - "Users/l/lserksny/PIDAntiProton", - "Path to the CCDB ocject for antiproton BB param"}; - - Configurable ConfUseManualPIDdeuteron{ - "ConfUseManualPIDdeuteron", - false, - "True: use home-made PID solution for deuteron "}; - Configurable ConfPIDBBDeuteron{ - "ConfPIDBBDeuteron", - "Users/l/lserksny/PIDDeuteron", - "Path to the CCDB ocject for Deuteron BB param"}; - Configurable ConfPIDBBAntiDeuteron{ - "ConfPIDBBAntiDeuteron", - "Users/l/lserksny/PIDAntiDeuteron", - "Path to the CCDB ocject for antiDeuteron BB param"}; - - Configurable ConfUseManualPIDpion{ - "ConfUseManualPIDpion", - false, - "True: use home-made PID solution for pions"}; - Configurable ConfPIDBBPion{ - "ConfPIDBBPion", - "Users/l/lserksny/PIDPion", - "Path to the CCDB ocject for Pion BB param"}; - Configurable ConfPIDBBAntiPion{ - "ConfPIDBBAntiPion", - "Users/l/lserksny/PIDAntiPion", - "Path to the CCDB ocject for antiPion BB param"}; - - Configurable ConfUseManualPIDel{ - "ConfUseManualPIDel", - false, - "True: use home-made PID solution for electron"}; - Configurable ConfPIDBBElectron{ - "ConfPIDBBElectron", - "Users/l/lserksny/PIDElectron", - "Path to the CCDB ocject for Electron BB param"}; - Configurable ConfPIDBBAntiElectron{ - "ConfPIDBBAntiElectron", - "Users/l/lserksny/PIDAntiElectron", - "Path to the CCDB ocject for antiElectron BB param"}; - - Configurable ConfUseManualPIDdaughterPion{ - "ConfUseManualPIDdaughterPion", - false, - "True: use home-made PID solution for pion from V0"}; - Configurable ConfUseManualPIDdaughterProton{ - "ConfUseManualPIDdaughterProton", - false, - "True: use home-made PID solution for proton from V0"}; - - Configurable ConfUseAvgFromCCDB{ - "ConfUseAvgFromCCDB", - false, - "True: use TOF and TPC averages from CCDB"}; - Configurable ConfAvgPath{ - "ConfAvgPath", - "Users/l/lserksny/TPCTOFAvg", - "Path to the CCDB ocject for TOF and TPC averages"}; - - Configurable ConfRejectNotPropagatedTracks{ - "ConfRejectNotPropagatedTracks", - false, - "True: reject not propagated tracks"}; - Configurable ConfTrkEta{ - "ConfTrkEta", - 0.85, - "Eta"}; - Configurable> ConfTPCNClustersMin{ - "ConfTPCNClustersMin", - {CFTrigger::NClustersMin[0], 1, CFTrigger::nTracks, std::vector{"TPCNClusMin"}, CFTrigger::SpeciesMinTPCClustersName}, - "kstar limit for two body trigger"}; - Configurable ConfTrkTPCfCls{ - "ConfTrkTPCfCls", - 0.83, - "Minimum fraction of crossed rows over findable clusters"}; - Configurable ConfTrkTPCcRowsMin{ - "ConfTrkTPCcRowsMin", - 70, - "Minimum number of crossed TPC rows"}; - Configurable ConfTrkTPCsClsMax{ - "ConfTrkTPCsClsMax", - 160, - "Maximum number of shared TPC clusters"}; - Configurable> ConfTrkITSnclsMin{ - "ConfTrkITSnclsMin", - {CFTrigger::ITSCutsTable[0], 1, CFTrigger::nTracks, std::vector{"Cut"}, CFTrigger::SpeciesName}, - "Minimum number of ITS clusters"}; - Configurable> ConfTrkITSnclsIBMin{ - "ConfTrkITSnclsIBMin", - {CFTrigger::ITSCutsTable[0], 1, CFTrigger::nTracks, std::vector{"Cut"}, CFTrigger::SpeciesName}, - "Minimum number of ITS clusters in the inner barrel"}; - Configurable ConfTrkDCAxyMax{ - "ConfTrkDCAxyMax", - 0.15, - "Maximum DCA_xy"}; - Configurable ConfTrkDCAzMax{ - "ConfTrkDCAzMax", - 0.3, - "Maximum DCA_z"}; - // Checks taken from global track definition - Configurable ConfTrkRequireChi2MaxTPC{ - "ConfTrkRequireChi2MaxTPC", false, - "True: require max chi2 per TPC cluster"}; - Configurable ConfTrkRequireChi2MaxITS{ - "ConfTrkRequireChi2MaxITS", false, - "True: require max chi2 per ITS cluster"}; - Configurable - ConfTrkMaxChi2PerClusterTPC{ - "ConfTrkMaxChi2PerClusterTPC", - 4.0f, - "Minimal track selection: max allowed chi2 per TPC cluster"}; // 4.0 is default of - // global tracks - // on 20.01.2023 - Configurable - ConfTrkMaxChi2PerClusterITS{ - "ConfTrkMaxChi2PerClusterITS", - 36.0f, - "Minimal track selection: max allowed chi2 per ITS cluster"}; // 36.0 is default of - // global tracks - // on 20.01.2023 - Configurable ConfTrkTPCRefit{ - "ConfTrkTPCRefit", - false, - "True: require TPC refit"}; - Configurable ConfTrkITSRefit{ - "ConfTrkITSRefit", - false, - "True: require ITS refit"}; - - // PID selections - Configurable> ConfPIDCuts{ - "ConfPIDCuts", - {CFTrigger::pidcutsTable[0], CFTrigger::nTracks, CFTrigger::kNPIDLimits, CFTrigger::SpeciesName, CFTrigger::PidCutsName}, - "Particle PID selections"}; - Configurable> ConfPIDCutsAnti{ - "ConfPIDCutsAnti", - {CFTrigger::pidcutsTableAnti[0], CFTrigger::nTracks, CFTrigger::kNPIDLimits, CFTrigger::SpeciesNameAnti, CFTrigger::PidCutsName}, - "Particle PID selections for antiparticles; perfect case scenario identical to particles"}; - Configurable ConfRejectNOTDeuteron{ - "ConfRejectNOTDeuteron", - false, - "Reject deuteron candidates if they are compatible with electron, pion, proton"}; - Configurable> ConfPIDRejection{ - "ConfPIDRejection", - {CFTrigger::pidRejectionTable[0], CFTrigger::kNParticleRejection, CFTrigger::nPidRejection, CFTrigger::SpeciesRejectionName, CFTrigger::TPCCutName}, - "Particle PID Rejection selections (Deuteron candidates only)"}; - Configurable> ConfPIDTPCTOFAvg{ - "ConfPIDTPCTOFAvg", - {CFTrigger::pidTPCTOFAvgTable[0], CFTrigger::nPidAvg, CFTrigger::nTPCTOFAvg, CFTrigger::SpeciesAvgTPCTOFName, CFTrigger::TPCTOFAvgName}, - "Average expected nSigma of TPC and TOF, which is substracted in calculation of combined TPC and TOF nSigma"}; - - // Momentum selections - Configurable> ConfMomCorDifCut{ - "ConfMomCorDifCuts", - {CFTrigger::MomCorLimits[0], CFTrigger::nTracks, CFTrigger::nMomCorCuts, CFTrigger::SpeciesName, CFTrigger::MomCorCutsName}, - "ratio on momentum correlation difference (particle)"}; - Configurable> ConfMomCorDifCutAnti{ - "ConfMomCorDifCutsAnti", - {CFTrigger::MomCorLimits[0], CFTrigger::nTracks, CFTrigger::nMomCorCuts, CFTrigger::SpeciesNameAnti, CFTrigger::MomCorCutsName}, - "Cut on momentum correlation difference (antipartilce)"}; - Configurable ConfMomCorDifCutFlag{"ConfMomCorDifFlag", false, "Flag for cut on momentum correlation difference"}; - - Configurable> ConfMomCorRatioCut{ - "ConfMomCorRatioCuts", - {CFTrigger::MomCorLimits[0], CFTrigger::nTracks, CFTrigger::nMomCorCuts, CFTrigger::SpeciesName, CFTrigger::MomCorCutsName}, - "Cut on momentum correlation ratio (particle)"}; - Configurable> ConfMomCorRatioCutAnti{ - "ConfMomCorRatioCutsAnti", - {CFTrigger::MomCorLimits[0], CFTrigger::nTracks, CFTrigger::nMomCorCuts, CFTrigger::SpeciesNameAnti, CFTrigger::MomCorCutsName}, - "Cut on momentum correlation ratio (antipartilce)"}; - Configurable ConfMomCorRatioCutFlag{"ConfMomCorRatioFlag", false, "Flag for cut on momentum correlation ratio"}; - - Configurable> ConfPIDForTracking{ - "ConfPIDForTracking", - {CFTrigger::PIDForTrackingTable[0], CFTrigger::nTracks, 2, CFTrigger::SpeciesName, CFTrigger::PIDForTrackingName}, - "Use PID used in tracking up to momentum threshold"}; - - Configurable> ConfPtCuts{ - "ConfPtCuts", - {CFTrigger::ptcutsTable[0], CFTrigger::kNParticleSpecies, CFTrigger::nPtCuts, CFTrigger::SpeciesNameAll, CFTrigger::PtCutsName}, - "Particle Momentum selections"}; + struct : ConfigurableGroup { + std::string prefix = "TrackSel"; + Configurable> trackProperties{"trackProperties", + {cf_trigger::trackSelectionTable[0], + cf_trigger::nTrackNames, + cf_trigger::nTrackSelectionNames, + cf_trigger::trackNames, + cf_trigger::trackSelectionNames}, + "Track Selections"}; + + Configurable> momentum{"momentum", + {cf_trigger::momentumSelectionTable[0], + cf_trigger::nTrackNames, + cf_trigger::nMomentumSelectionNames, + cf_trigger::trackNames, + cf_trigger::momentumSelectionNames}, + "Momentum Selections"}; + + Configurable> pid{"pid", + {cf_trigger::pidSelectionTable[0], + cf_trigger::nTrackNames, + cf_trigger::nPidSelectionNames, + cf_trigger::trackNames, + cf_trigger::pidSelectionNames}, + "PID Selections"}; + } TrackSelections; // Configs for V0 - Configurable ConfV0PtMin{ - "ConfV0PtMin", - 0.f, - "Minimum transverse momentum of V0"}; - Configurable ConfV0DCADaughMax{ - "ConfV0DCADaughMax", - 1.8f, - "Maximum DCA between the V0 daughters"}; - Configurable ConfV0CPAMin{ - "ConfV0CPAMin", - 0.985f, - "Minimum CPA of V0"}; - Configurable ConfV0TranRadV0Min{ - "ConfV0TranRadV0Min", - 0.2f, - "Minimum transverse radius"}; - Configurable ConfV0TranRadV0Max{ - "ConfV0TranRadV0Max", - 100.f, - "Maximum transverse radius"}; - Configurable ConfV0DecVtxMax{"ConfV0DecVtxMax", - 100.f, - "Maximum distance from primary vertex"}; - Configurable ConfV0InvMassLowLimit{ - "ConfV0InvMassLowLimit", - 1.05, - "Lower limit of the V0 invariant mass"}; - Configurable ConfV0InvMassUpLimit{ - "ConfV0InvMassUpLimit", - 1.18, - "Upper limit of the V0 invariant mass"}; - - Configurable ConfV0RejectKaons{"ConfV0RejectKaons", - true, - "Switch to reject kaons"}; - Configurable ConfV0InvKaonMassLowLimit{ - "ConfV0InvKaonMassLowLimit", - 0.49, - "Lower limit of the V0 invariant mass for Kaon rejection"}; - Configurable ConfV0InvKaonMassUpLimit{ - "ConfV0InvKaonMassUpLimit", - 0.505, - "Upper limit of the V0 invariant mass for Kaon rejection"}; - - // config for V0 daughters - Configurable ConfDaughEta{ - "ConfDaughEta", - 0.85f, - "V0 Daugh sel: max eta"}; - Configurable ConfDaughTPCnclsMin{ - "ConfDaughTPCnclsMin", - 60.f, - "V0 Daugh sel: Min. nCls TPC"}; - Configurable ConfDaughDCAMin{ - "ConfDaughDCAMin", - 0.04f, - "V0 Daugh sel: Max. DCA Daugh to PV (cm)"}; - Configurable> ConfDaughPIDCuts{ - "ConfDaughPIDCuts", - {CFTrigger::pidcutsV0DaughterTable[0], CFTrigger::kNV0Daughters, CFTrigger::nPidCutsDaughers, CFTrigger::SpeciesV0DaughterName, CFTrigger::TPCCutName}, - "PID selections for Lambda daughters"}; - - // config for ppPhi struct : ConfigurableGroup { - std::string prefix = "PPPhi"; - Configurable ConfResoInvMassLowLimit{"ConfResoInvMassLowLimit", 1.011461, "Lower limit of the Reso invariant mass"}; - Configurable ConfResoInvMassUpLimit{"ConfResoInvMassUpLimit", 1.027461, "Upper limit of the Reso invariant mass"}; - - Configurable ConfTrkEtaKa{"ConfTrkEtaKa", 0.85, "Eta kaon daughters"}; // 0.8 - Configurable ConfTrkDCAxyKa{"ConfTrkDCAxyKa", 0.15, "DCAxy kaon daughters"}; // 0.1 - Configurable ConfTrkDCAzKa{"ConfTrkDCAzKa", 0.3, "DCAz kaon daughters"}; // 0.2 - Configurable ConfNClusKa{"ConfNClusKa", 70, "NClusters kaon daughters"}; // 0.2 - Configurable ConfNCrossedKa{"ConfNCrossedKa", 65, "NCrossedRows kaon daughters"}; // 0.2 - Configurable ConfTrkTPCfClsKa{"ConfTrkTPCfClsKa", 0.80, "Minimum fraction of crossed rows over findable clusters kaon daughters"}; // 0.2 - - Configurable ConfTrkPtKaUp{"ConfTrkPtKaUp", 6.0, "Pt_up kaon daughters"}; // 2.0 - Configurable ConfTrkPtKaDown{"ConfTrkPtKaDown", 0.05, "Pt_down kaon daughters"}; // 0.15 - Configurable ConfTrkPTPCKaThr{"ConfTrkPTPCKaThr", 0.40, "p_TPC,Thr kaon daughters"}; // 0.4 - Configurable ConfTrkKaSigmaPID{"ConfTrkKaSigmaPID", 3.50, "n_sigma kaon daughters"}; // 3.0 - } PPPhi; - - // config collection for ppRho // + std::string prefix = "V0BuilderOpts"; + Configurable minCrossedRows{"minCrossedRows", 70, "minimum TPC crossed rows for daughter tracks"}; + Configurable dcanegtopv{"dcanegtopv", 0.04, "DCA Neg To PV"}; + Configurable dcapostopv{"dcapostopv", 0.04, "DCA Pos To PV"}; + Configurable v0cospa{"v0cospa", 0.95, "V0 CosPA"}; // double -> N.B. dcos(x)/dx = 0 at x=0) + Configurable dcav0dau{"dcav0dau", 2.0, "DCA V0 Daughters"}; + Configurable v0radius{"v0radius", 0, "v0radius"}; + Configurable maxDaughterEta{"maxDaughterEta", 5, "Maximum daughter eta (in abs value)"}; + Configurable ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + } V0BuilderOpts; + + struct : ConfigurableGroup { + std::string prefix = "FitterOpts"; + Configurable propagateToPCA{"propagateToPCA", true, "Create tracks version propagated to PCA"}; + Configurable maxR{"maxR", 200., "reject PCA's above this radius"}; + Configurable minParamChange{"minParamChange", 1.e-3, "stop iterations if largest change of any X is smaller than this"}; + Configurable minRelChi2Change{"minRelChi2Change", 0.9, "stop iteraterions if chi2/chi2old > this"}; + Configurable maxDzIni{"maxDzIni", 1.e9, "reject (if>0) PCA candicate if tracks DZ exceeds threshold"}; + Configurable maxDxyIni{"maxDxyIni", 4., "Same as above for DXY"}; + Configurable maxChi2{"maxChi2", 1.e9, "Maximum chi2"}; + Configurable useAbsDCA{"useAbsDCA", true, "Minimise abs. distance rather than chi2"}; + Configurable weightedFinalPCA{"weightedFinalPCA", false, "Weight final PCA"}; + } FitterOpts; + + struct : ConfigurableGroup { + std::string prefix = "LambdaSel"; + Configurable ptMin{"ptMin", 0.f, "Minimum transverse momentum of V0"}; + Configurable dcaDaughMax{"dcaDaughMax", 2.f, "Maximum DCA between the V0 daughters"}; + Configurable cpaMin{"cpaMin", 0.95f, "Minimum CPA of V0"}; + Configurable tranRadMin{"tranRadMin", 0.f, "Minimum transverse radius"}; + Configurable tranRadMax{"tranRadMax", 100.f, "Maximum transverse radius"}; + Configurable decVtxMax{"decVtxMax", 100.f, "Maximum distance from primary vertex"}; + Configurable invMassLow{"invMassLow", 1.05, "Lower limit of the V0 invariant mass"}; + Configurable invMassUp{"invMassUp", 1.18, "Upper limit of the V0 invariant mass"}; + Configurable rejectKaons{"rejectKaons", true, "Switch to reject kaons"}; + Configurable invKaonMassLow{"invKaonMassLow", 0.49, "Lower limit of the V0 invariant mass for Kaon rejection"}; + Configurable invKaonMassUp{"invKaonMassUp", 0.505, "Upper limit of the V0 invariant mass for Kaon rejection"}; + } LambdaSelections; + + struct : ConfigurableGroup { + std::string prefix = "LambdaDaughterSel"; + Configurable absEtaMax{"absEtaMax", 0.85f, "V0 Daugh sel: max eta"}; + Configurable tpcClusterMin{"tpcClusterMin", 70.f, "V0 Daugh sel: Min. nCls TPC"}; + Configurable dcaMin{"dcaMin", 0.04f, "V0 Daugh sel: Max. DCA Daugh to PV (cm)"}; + Configurable tpcMax{"tpcMax", 5, "PID selections for Lambda daughters"}; + } LambdaDaughterSelections; + struct : ConfigurableGroup { - std::string prefix = "PPRho"; - Configurable ConfResoRho0InvMassLowLimit{"ConfResoRho0InvMassLowLimit", 0.7, "Lower limit of the RhoReso invariant mass"}; - Configurable ConfResoRho0InvMassUpLimit{"ConfResoRho0InvMassUpLimit", 0.85, "Upper limit of the RhoReso invariant mass"}; + std::string prefix = "PhiSel"; + Configurable invMassLow{"invMassLow", 1.011461, "Lower limit of Phi invariant mass"}; + Configurable invMassUp{"invMassUp", 1.027461, "Upper limit of Phi invariant mass"}; + Configurable tightInvMassLow{"tightInvMassLow", 1.011461, "Lower tight limit of Phi invariant mass"}; + Configurable tightInvMassUp{"tightInvMassUp", 1.027461, "Upper tight limit of Phi invariant mass"}; + } PhiSelections; - Configurable ConfTrkPtRho0CandLowLimit{"ConfTrkPtRho0CandLowLimit", 1.8, "Pt_LowLimit Rho0Cand"}; - Configurable ConfTrkPtRho0CandUpLimit{"ConfTrkPtRho0CandUpLimit", 10., "Pt_UpLimit Rho0Cand"}; - } PPRho; + struct : ConfigurableGroup { + std::string prefix = "RhoSel"; + Configurable invMassLow{"invMassLow", 0.7, "Lower limit of Rho invariant mass"}; + Configurable invMassUp{"invMassUp", 0.85, "Upper limit of Rho invariant mass"}; + Configurable ptLow{"ptLow", 3, "Lower pt limit for rho"}; + Configurable tightInvMassLow{"tightInvMassLow", 0.73, "Lower tight limit of Rho invariant mass"}; + Configurable tightInvMassUp{"tightInvMassUp", 0.82, "Upper tight limit of Rho invariant mass"}; + } RhoSelections; // Trigger selections - Configurable> ConfTriggerSwitches{ - "ConfTriggerSwitches", - {CFTrigger::triggerSwitches[0], 1, CFTrigger::nAllTriggers, std::vector{"Switch"}, CFTrigger::CFTriggerNamesALL}, - "Turn on specific trigger"}; - - Configurable> ConfQ3Limits{ - "ConfQ3Limits", - {CFTrigger::Q3Limits[0], 1, CFTrigger::kNThreeBodyTriggers, std::vector{"Limit"}, CFTrigger::ThreeBodyFilterNames}, - "Q3 limits for three body trigger"}; - - Configurable> ConfKstarLimits{ - "ConfKstarLimits", - {CFTrigger::KstarLimits[0], 1, CFTrigger::kNTwoBodyTriggers, std::vector{"Limit"}, CFTrigger::TwoBodyFilterNames}, - "kstar limit for two body trigger"}; - - Configurable> ConfDownsample{ - "ConfDownsample", - {CFTrigger::Downsample[0], 2, CFTrigger::nTriggerAllNames, std::vector{"Switch", "Factor"}, CFTrigger::ParticleNames}, - "Downsample individual particle species (Switch has to be larger than 0, Factor has to smaller than 1)"}; - - HistogramRegistry registry{"registry", {}, OutputObjHandlingPolicy::AnalysisObject}; - // HistogramRegistry registryQA{"registryQA", {}, OutputObjHandlingPolicy::AnalysisObject}; - - std::vector BBProton, BBAntiproton, BBDeuteron, BBAntideuteron, BBPion, BBAntipion, BBElectron, BBAntielectron, TPCTOFAvg; + struct : ConfigurableGroup { + std::string prefix = "Triggers"; + Configurable> filterSwitches{"filterSwitches", + {cf_trigger::filterTable[0], + cf_trigger::nSwitches, + cf_trigger::nFilterNames, + cf_trigger::switches, + cf_trigger::filterNames}, + "Switch for triggers"}; + Configurable> limits{"limits", + {cf_trigger::limitTable[0], + cf_trigger::nLimitNames, + cf_trigger::nFilterNames, + cf_trigger::limitNames, + cf_trigger::filterNames}, + "Limits for trigger. Tight limit without downsampling and loose with downsampling"}; + } TriggerSelections; + + struct : ConfigurableGroup { + std::string prefix = "Binning"; + ConfigurableAxis multiplicity{"multiplicity", {200, 0, 200}, "Binning Multiplicity"}; + ConfigurableAxis zvtx{"zvtx", {30, -15, 15}, "Binning Zvertex"}; + + ConfigurableAxis momentum{"momentum", {600, 0, 6}, "Binning Momentum"}; + ConfigurableAxis eta{"eta", {200, -1, 1}, "Binning eta"}; + ConfigurableAxis phi{"phi", {720, 0, o2::constants::math::TwoPI}, "Binning phi"}; + ConfigurableAxis dca{"dca", {100, -0.2, 0.2}, "Binning Dca"}; + + ConfigurableAxis nsigma{"nsigma", {500, -5, 5}, "Binning nsigma"}; + ConfigurableAxis nsigmaComb{"nsigmaComb", {500, 0, 5}, "Binning nsigma comb"}; + ConfigurableAxis tpcSignal{"tpcSignal", {500, 0, 500}, "Binning Tpc Signal"}; + ConfigurableAxis itsSignal{"itsSignal", {150, 0, 15}, "Binning Its Signal"}; + ConfigurableAxis tofSignal{"tofSignal", {120, 0, 1.2}, "Binning Tof Signal"}; + ConfigurableAxis tpcCluster{"tpcCluster", {153, 0, 153}, "Binning Tpc Clusters"}; + ConfigurableAxis tpcChi2{"tpcChi2", {100, 0, 5}, "Binning TPC chi2"}; + ConfigurableAxis itsCluster{"itsCluster", {8, -0.5, 7.5}, "Binning Its Clusters"}; + ConfigurableAxis itsIbCluster{"itsIbCluster", {4, -0.5, 3.5}, "Binning Its Inner Barrel Clusters"}; + ConfigurableAxis itsChi2{"itsChi2", {100, 0, 50}, "Binning ITS chi2"}; + + ConfigurableAxis momCor{"momCor", {100, -1, 1}, "Binning Ratios"}; + ConfigurableAxis ratio{"ratio", {200, 0, 2}, "Binning Ratios"}; + + ConfigurableAxis invMassLambda{"invMassLambda", {200, 1, 1.2}, "Binning Invariant Mass Lambda"}; + ConfigurableAxis invMassK0short{"invMassK0short", {100, 0.48, 0.52}, "Binning Invariant Mass K0short"}; + + ConfigurableAxis dcaDaugh{"dcaDaugh", {200, 0, 2}, "Binning daughter DCA at decay vertex"}; + ConfigurableAxis cpa{"cpa", {100, 0.9, 1}, "Binning CPA"}; + ConfigurableAxis transRad{"transRad", {100, 0, 100}, "Binning Transverse Radius"}; + ConfigurableAxis decayVtx{"decayVtx", {100, 0, 100}, "Binning Decay Vertex"}; + + ConfigurableAxis invMassPhi{"invMassPhi", {700, 0.8, 1.5}, "Binning Invariant Mass Phi"}; + + ConfigurableAxis invMassRho{"invMassRho", {600, 0.6, 1.2}, "Binning Invariant Mass Rho"}; + + ConfigurableAxis q3{"q3", {300, 0, 3}, "Binning Decay Q3"}; + ConfigurableAxis kstar{"kstar", {300, 0, 3}, "Binning Decay Kstar"}; + + } Binning; + + // define histogram registry + // because we have so many histograms, we need to have 2 registries + HistogramRegistry registryParticleQA{"ParticleQA", {}, OutputObjHandlingPolicy::AnalysisObject}; + HistogramRegistry registryTriggerQA{"TriggerQA", {}, OutputObjHandlingPolicy::AnalysisObject}; + + // helper object flor building lambdas + o2::pwglf::strangenessBuilderHelper mStraHelper; + Service ccdb; + int mRunNumber = 0; + float mBz = 0.; + + // 4vectors for all particles + std::vector vecProton, vecAntiProton, vecDeuteron, vecAntiDeuteron, vecLambda, vecAntiLambda, vecKaon, vecAntiKaon, vecPhi, vecPion, vecAntiPion, vecRho; + // indices for all particles + std::vector idxProton, idxAntiProton, idxDeuteron, idxAntiDeuteron, idxKaon, idxAntiKaon, idxPion, idxAntiPion; + // indices for lambda daughters + std::vector idxLambdaDaughProton, idxLambdaDaughPion, idxAntiLambdaDaughProton, idxAntiLambdaDaughPion, idxPhiDaughPos, idxPhiDaughNeg, idxRhoDaughPos, idxRhoDaughNeg; + + // arrays to store found pairs/tripplets and trigger decisions + std::array keepEventTightLimit; + std::array keepEventLooseLimit; + std::array signalTightLimit; + std::array signalLooseLimit; + void init(o2::framework::InitContext&) { - rng = new TRandom3(ConfRngSeed.value); - - // init the ccdb - ccdb->setURL("http://alice-ccdb.cern.ch"); - ccdbApi.init("http://alice-ccdb.cern.ch"); - ccdb->setCaching(true); - ccdb->setLocalObjectValidityChecking(); - - // Set avg if not taking from ccdb - if (!ConfUseAvgFromCCDB) { - TPCTOFAvg = {ConfPIDTPCTOFAvg->get("Proton", "TPC Avg"), - ConfPIDTPCTOFAvg->get("Proton", "TOF Avg"), - ConfPIDTPCTOFAvg->get("AntiProton", "TPC Avg"), - ConfPIDTPCTOFAvg->get("AntiProton", "TOF Avg"), - ConfPIDTPCTOFAvg->get("Deuteron", "TPC Avg"), - ConfPIDTPCTOFAvg->get("Deuteron", "TOF Avg"), - ConfPIDTPCTOFAvg->get("AntiDeuteron", "TPC Avg"), - ConfPIDTPCTOFAvg->get("AntiDeuteron", "TOF Avg")}; - } - - // global histograms - registry.add("fProcessedEvents", "CF - event filtered;;Events", HistType::kTH1F, {{10, -0.5, 9.5}}); - std::vector eventTitles = {"all", "rejected", "ppp", "ppL", "pLL", "LLL", "ppPhi", "ppRho", "pD", "LD"}; - for (size_t iBin = 0; iBin < eventTitles.size(); iBin++) { - registry.get(HIST("fProcessedEvents"))->GetXaxis()->SetBinLabel(iBin + 1, eventTitles[iBin].data()); + // setup strangeness builder + mStraHelper.v0selections.minCrossedRows = V0BuilderOpts.minCrossedRows.value; + mStraHelper.v0selections.dcanegtopv = V0BuilderOpts.dcanegtopv.value; + mStraHelper.v0selections.dcapostopv = V0BuilderOpts.dcapostopv.value; + mStraHelper.v0selections.v0cospa = V0BuilderOpts.v0cospa.value; + mStraHelper.v0selections.dcav0dau = V0BuilderOpts.dcav0dau.value; + mStraHelper.v0selections.v0radius = V0BuilderOpts.v0radius.value; + mStraHelper.v0selections.maxDaughterEta = V0BuilderOpts.maxDaughterEta.value; + + mStraHelper.fitter.setPropagateToPCA(FitterOpts.propagateToPCA.value); + mStraHelper.fitter.setMaxR(FitterOpts.maxR.value); + mStraHelper.fitter.setMinParamChange(FitterOpts.minParamChange.value); + mStraHelper.fitter.setMinRelChi2Change(FitterOpts.minRelChi2Change.value); + mStraHelper.fitter.setMaxDZIni(FitterOpts.maxDzIni.value); + mStraHelper.fitter.setMaxDXYIni(FitterOpts.maxDxyIni.value); + mStraHelper.fitter.setMaxChi2(FitterOpts.maxChi2.value); + mStraHelper.fitter.setUseAbsDCA(FitterOpts.useAbsDCA.value); + mStraHelper.fitter.setWeightedFinalPCA(FitterOpts.weightedFinalPCA.value); + + // setup histograms + int allTriggers = 2 * cf_trigger::nFilterNames; + int prossedEventsBins = 3 + allTriggers; + std::vector triggerTitles = {"ppp_LooseQ3", "ppp_TightQ3", + "ppL_LooseQ3", "ppL_TightQ3", + "pLL_LooseQ3", "pLL_TightQ3", + "LLL_LooseQ3", "LLL_TightQ3", + "ppPhi_LooseQ3", "ppPhi_TightQ3", + "ppRho_LooseQ3", "ppRho_TightQ3", + "pD_LooseKstar", "pD_TightKstar", + "LD_LooseKstar", "LD_TightKstar", + "PhiD_LooseKstar", "PhiD_TightKstar", + "RhoD_LooseKstar", "RhoD_TightKstar"}; + + registryTriggerQA.add("fProcessedEvents", "CF - event filtered;;Events", HistType::kTH1F, {{prossedEventsBins, -0.5, prossedEventsBins - 0.5}}); + registryTriggerQA.get(HIST("fProcessedEvents"))->GetXaxis()->SetBinLabel(1, "all"); + registryTriggerQA.get(HIST("fProcessedEvents"))->GetXaxis()->SetBinLabel(2, "accepted_loose"); + registryTriggerQA.get(HIST("fProcessedEvents"))->GetXaxis()->SetBinLabel(3, "accepted_tight"); + + registryTriggerQA.add("fTriggerCorrelations", "CF - Trigger correlations", HistType::kTH2F, {{allTriggers, -0.5, allTriggers - 0.5}, {allTriggers, -0.5, allTriggers - 0.5}}); + + for (size_t iBin = 0; iBin < triggerTitles.size(); iBin++) { + registryTriggerQA.get(HIST("fProcessedEvents"))->GetXaxis()->SetBinLabel(iBin + 4, triggerTitles[iBin].data()); // start triggers from 4th bin + registryTriggerQA.get(HIST("fTriggerCorrelations"))->GetXaxis()->SetBinLabel(iBin + 1, triggerTitles[iBin].data()); + registryTriggerQA.get(HIST("fTriggerCorrelations"))->GetYaxis()->SetBinLabel(iBin + 1, triggerTitles[iBin].data()); } // event cuts - registry.add("EventCuts/fMultiplicityBefore", "Multiplicity of all processed events;Mult;Entries", HistType::kTH1F, {{500, 0, 500}}); - registry.add("EventCuts/fMultiplicityAfter", "Multiplicity after event cuts;Mult;Entries", HistType::kTH1F, {{500, 0, 500}}); - registry.add("EventCuts/fZvtxBefore", "Zvtx of all processed events;Z_{vtx};Entries", HistType::kTH1F, {{500, -15, 15}}); - registry.add("EventCuts/fZvtxAfter", "Zvtx after event cuts;Z_{vtx};Entries", HistType::kTH1F, {{500, -15, 15}}); - - // mom correlations p vs pTPC - registry.add("TrackCuts/TracksBefore/fMomCorrelationPos", "fMomCorrelation;p (GeV/c);p_{TPC} (GeV/c)", {HistType::kTH2F, {{500, 0.0f, 20.0f}, {500, 0.0f, 20.0f}}}); - registry.add("TrackCuts/TracksBefore/fMomCorrelationAfterCutsPos", "fMomCorrelationAfterCuts;p (GeV/c);p_{TPC} (GeV/c)", {HistType::kTH2F, {{500, 0.0f, 20.0f}, {500, 0.0f, 20.0f}}}); - registry.add("TrackCuts/TracksBefore/fMomCorrelationNeg", "fMomCorrelation;p (GeV/c);p_{TPC} (GeV/c)", {HistType::kTH2F, {{500, 0.0f, 20.0f}, {500, 0.0f, 20.0f}}}); - registry.add("TrackCuts/TracksBefore/fMomCorrelationAfterCutsNeg", "fMomCorrelationAfterCuts;p (GeV/c);p_{TPC} (GeV/c)", {HistType::kTH2F, {{500, 0.0f, 20.0f}, {500, 0.0f, 20.0f}}}); - - registry.add("TrackCuts/TracksBefore/fMomCorrelationAfterCutsProton", "fMomCorrelation;p (GeV/c);p_{TPC} (GeV/c)", {HistType::kTH2F, {{500, 0.0f, 20.0f}, {500, 0.0f, 20.0f}}}); - registry.add("TrackCuts/TracksBefore/fMomCorrelationAfterCutsAntiProton", "fMomCorrelation;p (GeV/c);p_{TPC} (GeV/c)", {HistType::kTH2F, {{500, 0.0f, 20.0f}, {500, 0.0f, 20.0f}}}); - registry.add("TrackCuts/TracksBefore/fMomCorrelationAfterCutsDeuteron", "fMomCorrelation;p (GeV/c);p_{TPC} (GeV/c)", {HistType::kTH2F, {{500, 0.0f, 20.0f}, {500, 0.0f, 20.0f}}}); - registry.add("TrackCuts/TracksBefore/fMomCorrelationAfterCutsAntiDeuteron", "fMomCorrelation;p (GeV/c);p_{TPC} (GeV/c)", {HistType::kTH2F, {{500, 0.0f, 20.0f}, {500, 0.0f, 20.0f}}}); - - registry.add("TrackCuts/TracksBefore/fMomCorrelationAfterCutsPion", "fMomCorrelation;p (GeV/c);p_{TPC} (GeV/c)", {HistType::kTH2F, {{1000, 0.0f, 20.0f}, {1000, 0.0f, 20.0f}}}); - registry.add("TrackCuts/TracksBefore/fMomCorrelationAfterCutsAntiPion", "fMomCorrelation;p (GeV/c);p_{TPC} (GeV/c)", {HistType::kTH2F, {{1000, 0.0f, 20.0f}, {1000, 0.0f, 20.0f}}}); - - // all tracks - registry.add("TrackCuts/TracksBefore/fPtTrackBefore", "Transverse momentum of all processed tracks;p_{T} (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - registry.add("TrackCuts/TracksBefore/fEtaTrackBefore", "Pseudorapidity of all processed tracks;#eta;Entries", HistType::kTH1F, {{500, -2, 2}}); - registry.add("TrackCuts/TracksBefore/fPhiTrackBefore", "Azimuthal angle of all processed tracks;#phi;Entries", HistType::kTH1F, {{720, 0, TMath::TwoPi()}}); + registryParticleQA.add("EventQA/Before/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); + registryParticleQA.add("EventQA/Before/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); + + registryParticleQA.add("EventQA/After/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); + registryParticleQA.add("EventQA/After/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); + + // all tracks before cuts + registryParticleQA.add("TrackQA/Before/Particle/fPt", "Transverse;p_{T} (GeV/c);Entries", HistType::kTH1F, {Binning.momentum}); + registryParticleQA.add("TrackQA/Before/Particle/fEta", "Pseudorapidity;#eta;Entries", HistType::kTH1F, {Binning.eta}); + registryParticleQA.add("TrackQA/Before/Particle/fPhi", "Azimuthal;#varphi;Entries", HistType::kTH1F, {Binning.phi}); + registryParticleQA.add("TrackQA/Before/Particle/fMomCor", "Momentum correlation;p_{reco} (GeV/c); p_{TPC} - p_{reco} / p_{reco}", {HistType::kTH2F, {Binning.momentum, Binning.momCor}}); + registryParticleQA.add("TrackQA/Before/Particle/fItsSignal", "ITSSignal;p_{TPC} (GeV/c);ITS Signal", {HistType::kTH2F, {Binning.momentum, Binning.itsSignal}}); + registryParticleQA.add("TrackQA/Before/Particle/fTpcSignal", "TPCSignal;p_{TPC} (GeV/c);TPC Signal", {HistType::kTH2F, {Binning.momentum, Binning.tpcSignal}}); + registryParticleQA.add("TrackQA/Before/Particle/fTofSignal", "TOFSignal;p_{TPC} (GeV/c);TOF Signal", {HistType::kTH2F, {Binning.momentum, Binning.tofSignal}}); + + registryParticleQA.add("TrackQA/Before/AntiParticle/fPt", "Transverse momentum;p_{T} (GeV/c);Entries", HistType::kTH1F, {Binning.momentum}); + registryParticleQA.add("TrackQA/Before/AntiParticle/fEta", "Pseudorapidity;#eta;Entries", HistType::kTH1F, {Binning.eta}); + registryParticleQA.add("TrackQA/Before/AntiParticle/fPhi", "Azimuthal angle;#varphi;Entries", HistType::kTH1F, {Binning.phi}); + registryParticleQA.add("TrackQA/Before/AntiParticle/fMomCor", "Momentum correlation;p_{reco} (GeV/c); p_{TPC} - p_{reco} / p_{reco}", {HistType::kTH2F, {Binning.momentum, Binning.momCor}}); + registryParticleQA.add("TrackQA/Before/AntiParticle/fItsSignal", "ITSSignal;p_{TPC} (GeV/c);ITS Signal", {HistType::kTH2F, {Binning.momentum, Binning.itsSignal}}); + registryParticleQA.add("TrackQA/Before/AntiParticle/fTpcSignal", "TPCSignal;p_{TPC} (GeV/c);TPC Signal", {HistType::kTH2F, {Binning.momentum, Binning.tpcSignal}}); + registryParticleQA.add("TrackQA/Before/AntiParticle/fTofSignal", "TOFSignal;p_{TPC} (GeV/c);TOF Signal", {HistType::kTH2F, {Binning.momentum, Binning.tofSignal}}); // PID vs momentum before cuts - registry.add("TrackCuts/NSigmaBefore/fNsigmaTPCvsPProtonBefore", "NSigmaTPC Proton Before;p_{TPC} (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - registry.add("TrackCuts/NSigmaBefore/fNsigmaTOFvsPProtonBefore", "NSigmaTOF Proton Before;p_{TPC} (GeV/c);n#sigma_{TOF}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - registry.add("TrackCuts/NSigmaBefore/fNsigmaTPCTOFvsPProtonBefore", "NsigmaTPCTOF Proton Before;p_{TPC} (GeV/c);n#sigma_{comb}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, 0.f, 10.f}}}); - registry.add("TrackCuts/NSigmaBefore/fNsigmaITSvsPProtonBefore", "NSigmaITS Proton Before;p (GeV/c);n#sigma_{ITS}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - registry.add("TrackCuts/NSigmaBefore/fNsigmaTPCvsPAntiProtonBefore", "NSigmaTPC AntiProton Before;p_{TPC} (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - registry.add("TrackCuts/NSigmaBefore/fNsigmaTOFvsPAntiProtonBefore", "NSigmaTOF AntiProton Before;p_{TPC} (GeV/c);n#sigma_{TOF}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - registry.add("TrackCuts/NSigmaBefore/fNsigmaTPCTOFvsPAntiProtonBefore", "NSigmaTPCTOF AntiProton Before;p_{TPC} (GeV/c);n#sigma_{comb}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, 0.f, 10.f}}}); - registry.add("TrackCuts/NSigmaBefore/fNsigmaITSvsPAntiProtonBefore", "NSigmaITS AntiProton Before;p (GeV/c);n#sigma_{ITS}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - registry.add("TrackCuts/NSigmaBefore/fNsigmaTPCvsPDeuteronBefore", "NSigmaTPC Deuteron Before;p_{TPC} (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - registry.add("TrackCuts/NSigmaBefore/fNsigmaTOFvsPDeuteronBefore", "NSigmaTOF Deuteron Before;p_{TPC} (GeV/c);n#sigma_{TOF}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - registry.add("TrackCuts/NSigmaBefore/fNsigmaTPCTOFvsPDeuteronBefore", "NSigmaTPCTOF Deuteron Before;p_{TPC} (GeV/c);n#sigma_{comb}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, 0.f, 10.f}}}); - registry.add("TrackCuts/NSigmaBefore/fNsigmaITSvsPDeuteronBefore", "NSigmaITS Deuteron Before;p (GeV/c);n#sigma_{comb}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - - registry.add("TrackCuts/NSigmaBefore/fNsigmaTPCvsPAntiDeuteronBefore", "NSigmaTPC AntiDeuteron Before;p_{TPC} (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - registry.add("TrackCuts/NSigmaBefore/fNsigmaTOFvsPAntiDeuteronBefore", "NSigmaTOF AntiDeuteron Before;p_{TPC} (GeV/c);n#sigma_{TOF}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - registry.add("TrackCuts/NSigmaBefore/fNsigmaTPCTOFvsPAntiDeuteronBefore", "NSigmaTPCTOF AntiDeuteron Before;p_{TPC} (GeV/c);n#sigma_{comb}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, 0.f, 10.f}}}); - registry.add("TrackCuts/NSigmaBefore/fNsigmaITSvsPAntiDeuteronBefore", "NSigmaITS AntiDeuteron Before;p (GeV/c);n#sigma_{ITS}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - - registry.add("TrackCuts/NSigmaBefore/fNsigmaTPCvsPDeuteronBeforeP", "NSigmaTPC Deuteron BeforeP;p (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - registry.add("TrackCuts/NSigmaBefore/fNsigmaTPCvsPAntiDeuteronBeforeP", "NSigmaTPC AntiDeuteron BeforeP;p (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - - // TPC signal - registry.add("TrackCuts/TPCSignal/fTPCSignal", "TPCSignal;p_{TPC} (GeV/c);dE/dx", {HistType::kTH2F, {{500, 0.0f, 6.0f}, {2000, -100.f, 500.f}}}); - registry.add("TrackCuts/TPCSignal/fTPCSignalP", "TPCSignalP;p (GeV/c);dE/dx", {HistType::kTH2F, {{500, 0.0f, 6.0f}, {2000, -100.f, 500.f}}}); - registry.add("TrackCuts/TPCSignal/fTPCSignalALLCUTS", "TPCSignalALLCUTS;p_{TPC} (GeV/c);dE/dx", {HistType::kTH2F, {{500, 0.0f, 6.0f}, {2000, -100.f, 500.f}}}); - registry.add("TrackCuts/TPCSignal/fTPCSignalALLCUTSP", "TPCSignalALLCUTSP;p (GeV/c);dE/dx", {HistType::kTH2F, {{500, 0.0f, 6.0f}, {2000, -100.f, 500.f}}}); - - // TPC signal anti - registry.add("TrackCuts/TPCSignal/fTPCSignalAnti", "TPCSignal;p_{TPC} (GeV/c);dE/dx", {HistType::kTH2F, {{500, 0.0f, 6.0f}, {2000, -100.f, 500.f}}}); - registry.add("TrackCuts/TPCSignal/fTPCSignalAntiP", "TPCSignalP;p (GeV/c);dE/dx", {HistType::kTH2F, {{500, 0.0f, 6.0f}, {2000, -100.f, 500.f}}}); - registry.add("TrackCuts/TPCSignal/fTPCSignalAntiALLCUTS", "TPCSignalALLCUTS;p_{TPC} (GeV/c);dE/dx", {HistType::kTH2F, {{500, 0.0f, 6.0f}, {2000, -100.f, 500.f}}}); - registry.add("TrackCuts/TPCSignal/fTPCSignalAntiALLCUTSP", "TPCSignalALLCUTSP;p(GeV/c);dE/dx", {HistType::kTH2F, {{500, 0.0f, 6.0f}, {2000, -100.f, 500.f}}}); - - // TPC signal particles - registry.add("TrackCuts/TPCSignal/fTPCSignalProton", "fTPCSignalProton;p_{TPC} (GeV/c);dE/dx", {HistType::kTH2F, {{500, 0.0f, 6.0f}, {10000, -100.f, 500.f}}}); - registry.add("TrackCuts/TPCSignal/fTPCSignalAntiProton", "fTPCSignalAntiProton;p_{TPC} (GeV/c);dE/dx", {HistType::kTH2F, {{500, 0.0f, 6.0f}, {10000, -100.f, 500.f}}}); - registry.add("TrackCuts/TPCSignal/fTPCSignalDeuteron", "fTPCSignalDeuteron;p_{TPC} (GeV/c);dE/dx", {HistType::kTH2F, {{500, 0.0f, 6.0f}, {10000, -100.f, 500.f}}}); - registry.add("TrackCuts/TPCSignal/fTPCSignalAntiDeuteron", "fTPCSignalAntiDeuteron;p_{TPC} (GeV/c);dE/dx", {HistType::kTH2F, {{500, 0.0f, 6.0f}, {10000, -100.f, 500.f}}}); - registry.add("TrackCuts/TPCSignal/fTPCSignalPionMinusV0Daughter", "fTPCSignalPionMinusV0Daughter;p_{TPC} (GeV/c);dE/dx", {HistType::kTH2F, {{500, 0.0f, 6.0f}, {10000, -100.f, 500.f}}}); - registry.add("TrackCuts/TPCSignal/fTPCSignalPionPlusV0Daughter", "fTPCSignalPionPlusV0Daughter;p_{TPC} (GeV/c);dE/dx", {HistType::kTH2F, {{500, 0.0f, 6.0f}, {10000, -100.f, 500.f}}}); - registry.add("TrackCuts/TPCSignal/fTPCSignalProtonMinusV0Daughter", "fTPCSignalProtonMinusV0Daughter;p_{TPC} (GeV/c);dE/dx", {HistType::kTH2F, {{500, 0.0f, 6.0f}, {10000, -100.f, 500.f}}}); - registry.add("TrackCuts/TPCSignal/fTPCSignalProtonPlusV0Daughter", "fTPCSignalProtonPlusV0Daughter;p_{TPC} (GeV/c);dE/dx", {HistType::kTH2F, {{500, 0.0f, 6.0f}, {10000, -100.f, 500.f}}}); - registry.add("TrackCuts/TPCSignal/fTPCSignalPion", "fTPCSignalPion;p_{TPC} (GeV/c);dE/dx", {HistType::kTH2F, {{500, 0.0f, 6.0f}, {10000, -100.f, 500.f}}}); - registry.add("TrackCuts/TPCSignal/fTPCSignalAntiPion", "fTPCSignalAntiPion;p_{TPC} (GeV/c);dE/dx", {HistType::kTH2F, {{500, 0.0f, 6.0f}, {10000, -100.f, 500.f}}}); - - // PID vs momentum before cuts daughters - registry.add("TrackCuts/NSigmaBefore/fNsigmaTPCvsPProtonV0DaughBefore", "NSigmaTPC Proton V0Daught Before;p_{TPC} (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - registry.add("TrackCuts/NSigmaBefore/fNsigmaTPCvsPPionMinusV0DaughBefore", "NSigmaTPC AntiPion V0Daught Before;p_{TPC} (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - registry.add("TrackCuts/NSigmaBefore/fNsigmaTPCvsPAntiProtonAntiV0DaughBefore", "NSigmaTPC AntiProton antiV0Daught Before;p_{TPC} (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - registry.add("TrackCuts/NSigmaBefore/fNsigmaTPCvsPPionPlusAntiV0DaughBefore", "NSigmaTPC Pion antiV0Daught Before;p_{TPC} (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); + registryParticleQA.add("TrackQA/Before/Pion/fNsigmaITS", "NSigmaITS;p (GeV/c);n#sigma_{ITS}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); + registryParticleQA.add("TrackQA/Before/Pion/fNsigmaTPC", "NSigmaTPC;p_{TPC} (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); + registryParticleQA.add("TrackQA/Before/Pion/fNsigmaTOF", "NSigmaTOF;p_{TPC} (GeV/c);n#sigma_{TOF}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); + registryParticleQA.add("TrackQA/Before/Pion/fNsigmaTPCTOF", "NsigmaTPCTOF;p_{TPC} (GeV/c);n#sigma_{comb}", {HistType::kTH2F, {Binning.momentum, Binning.nsigmaComb}}); + + registryParticleQA.add("TrackQA/Before/AntiPion/fNsigmaITS", "NSigmaITS;p (GeV/c);n#sigma_{ITS}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); + registryParticleQA.add("TrackQA/Before/AntiPion/fNsigmaTPC", "NSigmaTPC;p_{TPC} (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); + registryParticleQA.add("TrackQA/Before/AntiPion/fNsigmaTOF", "NSigmaTOF;p_{TPC} (GeV/c);n#sigma_{TOF}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); + registryParticleQA.add("TrackQA/Before/AntiPion/fNsigmaTPCTOF", "NsigmaTPCTOF;p_{TPC} (GeV/c);n#sigma_{comb}", {HistType::kTH2F, {Binning.momentum, Binning.nsigmaComb}}); + + registryParticleQA.add("TrackQA/Before/Kaon/fNsigmaITS", "NSigmaITS;p (GeV/c);n#sigma_{ITS}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); + registryParticleQA.add("TrackQA/Before/Kaon/fNsigmaTPC", "NSigmaTPC;p_{TPC} (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); + registryParticleQA.add("TrackQA/Before/Kaon/fNsigmaTOF", "NSigmaTOF;p_{TPC} (GeV/c);n#sigma_{TOF}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); + registryParticleQA.add("TrackQA/Before/Kaon/fNsigmaTPCTOF", "NsigmaTPCTOF;p_{TPC} (GeV/c);n#sigma_{comb}", {HistType::kTH2F, {Binning.momentum, Binning.nsigmaComb}}); + + registryParticleQA.add("TrackQA/Before/AntiKaon/fNsigmaITS", "NSigmaITS;p (GeV/c);n#sigma_{ITS}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); + registryParticleQA.add("TrackQA/Before/AntiKaon/fNsigmaTPC", "NSigmaTPC;p_{TPC} (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); + registryParticleQA.add("TrackQA/Before/AntiKaon/fNsigmaTOF", "NSigmaTOF;p_{TPC} (GeV/c);n#sigma_{TOF}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); + registryParticleQA.add("TrackQA/Before/AntiKaon/fNsigmaTPCTOF", "NsigmaTPCTOF;p_{TPC} (GeV/c);n#sigma_{comb}", {HistType::kTH2F, {Binning.momentum, Binning.nsigmaComb}}); + + registryParticleQA.add("TrackQA/Before/Proton/fNsigmaITS", "NSigmaITS;p (GeV/c);n#sigma_{ITS}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); + registryParticleQA.add("TrackQA/Before/Proton/fNsigmaTPC", "NSigmaTPC;p_{TPC} (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); + registryParticleQA.add("TrackQA/Before/Proton/fNsigmaTOF", "NSigmaTOF;p_{TPC} (GeV/c);n#sigma_{TOF}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); + registryParticleQA.add("TrackQA/Before/Proton/fNsigmaTPCTOF", "NsigmaTPCTOF;p_{TPC} (GeV/c);n#sigma_{comb}", {HistType::kTH2F, {Binning.momentum, Binning.nsigmaComb}}); + + registryParticleQA.add("TrackQA/Before/AntiProton/fNsigmaITS", "NSigmaITS;p (GeV/c);n#sigma_{ITS}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); + registryParticleQA.add("TrackQA/Before/AntiProton/fNsigmaTPC", "NSigmaTPC;p_{TPC} (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); + registryParticleQA.add("TrackQA/Before/AntiProton/fNsigmaTOF", "NSigmaTOF;p_{TPC} (GeV/c);n#sigma_{TOF}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); + registryParticleQA.add("TrackQA/Before/AntiProton/fNsigmaTPCTOF", "NsigmaTPCTOF;p_{TPC} (GeV/c);n#sigma_{comb}", {HistType::kTH2F, {Binning.momentum, Binning.nsigmaComb}}); + + registryParticleQA.add("TrackQA/Before/Deuteron/fNsigmaITS", "NSigmaITS;p (GeV/c);n#sigma_{ITS}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); + registryParticleQA.add("TrackQA/Before/Deuteron/fNsigmaTPC", "NSigmaTPC;p_{TPC} (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); + registryParticleQA.add("TrackQA/Before/Deuteron/fNsigmaTOF", "NSigmaTOF;p_{TPC} (GeV/c);n#sigma_{TOF}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); + registryParticleQA.add("TrackQA/Before/Deuteron/fNsigmaTPCTOF", "NsigmaTPCTOF;p_{TPC} (GeV/c);n#sigma_{comb}", {HistType::kTH2F, {Binning.momentum, Binning.nsigmaComb}}); + + registryParticleQA.add("TrackQA/Before/AntiDeuteron/fNsigmaITS", "NSigmaITS;p (GeV/c);n#sigma_{ITS}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); + registryParticleQA.add("TrackQA/Before/AntiDeuteron/fNsigmaTPC", "NSigmaTPC;p_{TPC} (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); + registryParticleQA.add("TrackQA/Before/AntiDeuteron/fNsigmaTOF", "NSigmaTOF;p_{TPC} (GeV/c);n#sigma_{TOF}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); + registryParticleQA.add("TrackQA/Before/AntiDeuteron/fNsigmaTPCTOF", "NsigmaTPCTOF;p_{TPC} (GeV/c);n#sigma_{comb}", {HistType::kTH2F, {Binning.momentum, Binning.nsigmaComb}}); + + // Pion + registryParticleQA.add("TrackQA/After/Pion/fPt", "Transverse Momentum;p_{T} (GeV/c);Entries", HistType::kTH1F, {Binning.momentum}); + registryParticleQA.add("TrackQA/After/Pion/fPTpc", "Momentum at TPC inner wall;p_{TPC} (GeV/c);Entries", HistType::kTH1F, {Binning.momentum}); + registryParticleQA.add("TrackQA/After/Pion/fMomCor", "Momentum correlation;p_{reco} (GeV/c); p_{TPC} - p_{reco} / p_{reco}", {HistType::kTH2F, {Binning.momentum, Binning.momCor}}); + registryParticleQA.add("TrackQA/After/Pion/fEta", "Pseudorapidity;#eta;Entries", HistType::kTH1F, {Binning.eta}); + registryParticleQA.add("TrackQA/After/Pion/fPhi", "Azimuthal angle;#varphi;Entries", HistType::kTH1F, {Binning.phi}); + + registryParticleQA.add("TrackQA/After/Pion/fNsigmaIts", "NSigmaITS;p (GeV/c);n#sigma_{ITS}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); + registryParticleQA.add("TrackQA/After/Pion/fNsigmaTpc", "NSigmaTPC;p (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); + registryParticleQA.add("TrackQA/After/Pion/fNsigmaTof", "NSigmaTOF;p (GeV/c);n#sigma_{TOF}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); + registryParticleQA.add("TrackQA/After/Pion/fNsigmaTpcTof", "NSigmaTPCTOF;p (GeV/c);n#sigma_{comb}", {HistType::kTH2F, {Binning.momentum, Binning.nsigmaComb}}); + + registryParticleQA.add("TrackQA/After/Pion/fItsSignal", "ITS Signal;p (GeV/c); (cm)", {HistType::kTH2F, {Binning.momentum, Binning.itsSignal}}); + registryParticleQA.add("TrackQA/After/Pion/fTpcSignal", "TPC Signal;p (GeV/c);TPC Signal", {HistType::kTH2F, {Binning.momentum, Binning.tpcSignal}}); + registryParticleQA.add("TrackQA/After/Pion/fTofBeta", "TOF #beta;p (GeV/c);#beta_{TOF}", {HistType::kTH2F, {Binning.momentum, Binning.tofSignal}}); + + registryParticleQA.add("TrackQA/After/Pion/fDcaXy", "DCA_{xy};p_{T} (GeV/c); DCA_{XY};Entries", HistType::kTH2F, {Binning.momentum, Binning.dca}); + registryParticleQA.add("TrackQA/After/Pion/fDcaZ", "DCA_{z};p_{T} (GeV/c); DCA_{Z};Entries", HistType::kTH2F, {Binning.momentum, Binning.dca}); + + registryParticleQA.add("TrackQA/After/Pion/fTpcClusters", "TPC Clusters;TPC Clusters;Entries", HistType::kTH1F, {Binning.tpcCluster}); + registryParticleQA.add("TrackQA/After/Pion/fTpcCrossedRows", "TPC Crossed Rows;TPC Crossed Rows;Entries", HistType::kTH1F, {Binning.tpcCluster}); + registryParticleQA.add("TrackQA/After/Pion/fTpcSharedClusters", "TPC Shared Clusters;TPC Shared Clusters;Entries", HistType::kTH1F, {Binning.tpcCluster}); + registryParticleQA.add("TrackQA/After/Pion/fTpcSharedClusterOverClusterss", "TPC Shared Clusters/Clusters;TPC Shared Clusters/Clusters;Entries", HistType::kTH1F, {Binning.ratio}); + registryParticleQA.add("TrackQA/After/Pion/fTpcFindableOverRows", "TPC Findabled/Crossed Rows;TPC Findable/CrossedRows;Entries", HistType::kTH1F, {Binning.ratio}); + registryParticleQA.add("TrackQA/After/Pion/fTpcChi2OverCluster", "TPC #chi^{2}/Cluster;TPC #chi^{2}/Cluster;Entries", HistType::kTH1F, {Binning.tpcChi2}); + + registryParticleQA.add("TrackQA/After/Pion/fItsClusters", "ITS Clusters;ITS Clusters;Entries", HistType::kTH1F, {Binning.itsCluster}); + registryParticleQA.add("TrackQA/After/Pion/fItsIbClusters", "ITS Inner Barrel Clusters;ITS Inner Barrel Clusters;Entries", HistType::kTH1F, {Binning.itsIbCluster}); + registryParticleQA.add("TrackQA/After/Pion/fItsChi2OverCluster", "ITS #chi^{2}/Cluster;ITS #chi^{2}/Cluster;Entries", HistType::kTH1F, {Binning.itsChi2}); + + // antiPion + registryParticleQA.add("TrackQA/After/AntiPion/fPt", "Transverse Momentum;p_{T} (GeV/c);Entries", HistType::kTH1F, {Binning.momentum}); + registryParticleQA.add("TrackQA/After/AntiPion/fPTpc", "Momentum at TPC inner wall;p_{TPC} (GeV/c);Entries", HistType::kTH1F, {Binning.momentum}); + registryParticleQA.add("TrackQA/After/AntiPion/fMomCor", "Momentum correlation;p_{reco} (GeV/c); p_{TPC} - p_{reco} / p_{reco}", {HistType::kTH2F, {Binning.momentum, Binning.momCor}}); + registryParticleQA.add("TrackQA/After/AntiPion/fEta", "Pseudorapidity;#eta;Entries", HistType::kTH1F, {Binning.eta}); + registryParticleQA.add("TrackQA/After/AntiPion/fPhi", "Azimuthal angle;#varphi;Entries", HistType::kTH1F, {Binning.phi}); + + registryParticleQA.add("TrackQA/After/AntiPion/fNsigmaIts", "NSigmaITS;p (GeV/c);n#sigma_{ITS}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); + registryParticleQA.add("TrackQA/After/AntiPion/fNsigmaTpc", "NSigmaTPC;p (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); + registryParticleQA.add("TrackQA/After/AntiPion/fNsigmaTof", "NSigmaTOF;p (GeV/c);n#sigma_{TOF}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); + registryParticleQA.add("TrackQA/After/AntiPion/fNsigmaTpcTof", "NSigmaTPCTOF;p (GeV/c);n#sigma_{comb}", {HistType::kTH2F, {Binning.momentum, Binning.nsigmaComb}}); + + registryParticleQA.add("TrackQA/After/AntiPion/fItsSignal", "ITS Signal;p (GeV/c); (cm)", {HistType::kTH2F, {Binning.momentum, Binning.itsSignal}}); + registryParticleQA.add("TrackQA/After/AntiPion/fTpcSignal", "TPC Signal;p (GeV/c);TPC Signal", {HistType::kTH2F, {Binning.momentum, Binning.tpcSignal}}); + registryParticleQA.add("TrackQA/After/AntiPion/fTofBeta", "TOF #beta;p (GeV/c);#beta_{TOF}", {HistType::kTH2F, {Binning.momentum, Binning.tofSignal}}); + + registryParticleQA.add("TrackQA/After/AntiPion/fDcaXy", "DCA_{xy};p_{T} (GeV/c); DCA_{XY};Entries", HistType::kTH2F, {Binning.momentum, Binning.dca}); + registryParticleQA.add("TrackQA/After/AntiPion/fDcaZ", "DCA_{z};p_{T} (GeV/c); DCA_{Z};Entries", HistType::kTH2F, {Binning.momentum, Binning.dca}); + + registryParticleQA.add("TrackQA/After/AntiPion/fTpcClusters", "TPC Clusters;TPC Clusters;Entries", HistType::kTH1F, {Binning.tpcCluster}); + registryParticleQA.add("TrackQA/After/AntiPion/fTpcCrossedRows", "TPC Crossed Rows;TPC Crossed Rows;Entries", HistType::kTH1F, {Binning.tpcCluster}); + registryParticleQA.add("TrackQA/After/AntiPion/fTpcSharedClusters", "TPC Shared Clusters;TPC Shared Clusters;Entries", HistType::kTH1F, {Binning.tpcCluster}); + registryParticleQA.add("TrackQA/After/AntiPion/fTpcSharedClusterOverClusterss", "TPC Shared Clusters/Clusters;TPC Shared Clusters/Clusters;Entries", HistType::kTH1F, {Binning.ratio}); + registryParticleQA.add("TrackQA/After/AntiPion/fTpcFindableOverRows", "TPC Findabled/Crossed Rows;TPC Findable/CrossedRows;Entries", HistType::kTH1F, {Binning.ratio}); + registryParticleQA.add("TrackQA/After/AntiPion/fTpcChi2OverCluster", "TPC #chi^{2}/Cluster;TPC #chi^{2}/Cluster;Entries", HistType::kTH1F, {Binning.tpcChi2}); + + registryParticleQA.add("TrackQA/After/AntiPion/fItsClusters", "ITS Clusters;ITS Clusters;Entries", HistType::kTH1F, {Binning.itsCluster}); + registryParticleQA.add("TrackQA/After/AntiPion/fItsIbClusters", "ITS Inner Barrel Clusters;ITS Inner Barrel Clusters;Entries", HistType::kTH1F, {Binning.itsIbCluster}); + registryParticleQA.add("TrackQA/After/AntiPion/fItsChi2OverCluster", "ITS #chi^{2}/Cluster;ITS #chi^{2}/Cluster;Entries", HistType::kTH1F, {Binning.itsChi2}); + + // Kaon + registryParticleQA.add("TrackQA/After/Kaon/fPt", "Transverse Momentum;p_{T} (GeV/c);Entries", HistType::kTH1F, {Binning.momentum}); + registryParticleQA.add("TrackQA/After/Kaon/fPTpc", "Momentum at TPC inner wall;p_{TPC} (GeV/c);Entries", HistType::kTH1F, {Binning.momentum}); + registryParticleQA.add("TrackQA/After/Kaon/fMomCor", "Momentum correlation;p_{reco} (GeV/c); p_{TPC} - p_{reco} / p_{reco}", {HistType::kTH2F, {Binning.momentum, Binning.momCor}}); + registryParticleQA.add("TrackQA/After/Kaon/fEta", "Pseudorapidity;#eta;Entries", HistType::kTH1F, {Binning.eta}); + registryParticleQA.add("TrackQA/After/Kaon/fPhi", "Azimuthal angle;#varphi;Entries", HistType::kTH1F, {Binning.phi}); + + registryParticleQA.add("TrackQA/After/Kaon/fNsigmaIts", "NSigmaITS;p (GeV/c);n#sigma_{ITS}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); + registryParticleQA.add("TrackQA/After/Kaon/fNsigmaTpc", "NSigmaTPC;p (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); + registryParticleQA.add("TrackQA/After/Kaon/fNsigmaTof", "NSigmaTOF;p (GeV/c);n#sigma_{TOF}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); + registryParticleQA.add("TrackQA/After/Kaon/fNsigmaTpcTof", "NSigmaTPCTOF;p (GeV/c);n#sigma_{comb}", {HistType::kTH2F, {Binning.momentum, Binning.nsigmaComb}}); + + registryParticleQA.add("TrackQA/After/Kaon/fItsSignal", "ITS Signal;p (GeV/c); (cm)", {HistType::kTH2F, {Binning.momentum, Binning.itsSignal}}); + registryParticleQA.add("TrackQA/After/Kaon/fTpcSignal", "TPC Signal;p (GeV/c);TPC Signal", {HistType::kTH2F, {Binning.momentum, Binning.tpcSignal}}); + registryParticleQA.add("TrackQA/After/Kaon/fTofBeta", "TOF #beta;p (GeV/c);#beta_{TOF}", {HistType::kTH2F, {Binning.momentum, Binning.tofSignal}}); + + registryParticleQA.add("TrackQA/After/Kaon/fDcaXy", "DCA_{xy};p_{T} (GeV/c); DCA_{XY};Entries", HistType::kTH2F, {Binning.momentum, Binning.dca}); + registryParticleQA.add("TrackQA/After/Kaon/fDcaZ", "DCA_{z};p_{T} (GeV/c); DCA_{Z};Entries", HistType::kTH2F, {Binning.momentum, Binning.dca}); + + registryParticleQA.add("TrackQA/After/Kaon/fTpcClusters", "TPC Clusters;TPC Clusters;Entries", HistType::kTH1F, {Binning.tpcCluster}); + registryParticleQA.add("TrackQA/After/Kaon/fTpcCrossedRows", "TPC Crossed Rows;TPC Crossed Rows;Entries", HistType::kTH1F, {Binning.tpcCluster}); + registryParticleQA.add("TrackQA/After/Kaon/fTpcSharedClusters", "TPC Shared Clusters;TPC Shared Clusters;Entries", HistType::kTH1F, {Binning.tpcCluster}); + registryParticleQA.add("TrackQA/After/Kaon/fTpcSharedClusterOverClusterss", "TPC Shared Clusters/Clusters;TPC Shared Clusters/Clusters;Entries", HistType::kTH1F, {Binning.ratio}); + registryParticleQA.add("TrackQA/After/Kaon/fTpcFindableOverRows", "TPC Findabled/Crossed Rows;TPC Findable/CrossedRows;Entries", HistType::kTH1F, {Binning.ratio}); + registryParticleQA.add("TrackQA/After/Kaon/fTpcChi2OverCluster", "TPC #chi^{2}/Cluster;TPC #chi^{2}/Cluster;Entries", HistType::kTH1F, {Binning.tpcChi2}); + + registryParticleQA.add("TrackQA/After/Kaon/fItsClusters", "ITS Clusters;ITS Clusters;Entries", HistType::kTH1F, {Binning.itsCluster}); + registryParticleQA.add("TrackQA/After/Kaon/fItsIbClusters", "ITS Inner Barrel Clusters;ITS Inner Barrel Clusters;Entries", HistType::kTH1F, {Binning.itsIbCluster}); + registryParticleQA.add("TrackQA/After/Kaon/fItsChi2OverCluster", "ITS #chi^{2}/Cluster;ITS #chi^{2}/Cluster;Entries", HistType::kTH1F, {Binning.itsChi2}); + + // antiKaon + registryParticleQA.add("TrackQA/After/AntiKaon/fPt", "Transverse Momentum;p_{T} (GeV/c);Entries", HistType::kTH1F, {Binning.momentum}); + registryParticleQA.add("TrackQA/After/AntiKaon/fPTpc", "Momentum at TPC inner wall;p_{TPC} (GeV/c);Entries", HistType::kTH1F, {Binning.momentum}); + registryParticleQA.add("TrackQA/After/AntiKaon/fMomCor", "Momentum correlation;p_{reco} (GeV/c); p_{TPC} - p_{reco} / p_{reco}", {HistType::kTH2F, {Binning.momentum, Binning.momCor}}); + registryParticleQA.add("TrackQA/After/AntiKaon/fEta", "Pseudorapidity;#eta;Entries", HistType::kTH1F, {Binning.eta}); + registryParticleQA.add("TrackQA/After/AntiKaon/fPhi", "Azimuthal angle;#varphi;Entries", HistType::kTH1F, {Binning.phi}); + + registryParticleQA.add("TrackQA/After/AntiKaon/fNsigmaIts", "NSigmaITS;p (GeV/c);n#sigma_{ITS}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); + registryParticleQA.add("TrackQA/After/AntiKaon/fNsigmaTpc", "NSigmaTPC;p (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); + registryParticleQA.add("TrackQA/After/AntiKaon/fNsigmaTof", "NSigmaTOF;p (GeV/c);n#sigma_{TOF}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); + registryParticleQA.add("TrackQA/After/AntiKaon/fNsigmaTpcTof", "NSigmaTPCTOF;p (GeV/c);n#sigma_{comb}", {HistType::kTH2F, {Binning.momentum, Binning.nsigmaComb}}); + + registryParticleQA.add("TrackQA/After/AntiKaon/fItsSignal", "ITS Signal;p (GeV/c); (cm)", {HistType::kTH2F, {Binning.momentum, Binning.itsSignal}}); + registryParticleQA.add("TrackQA/After/AntiKaon/fTpcSignal", "TPC Signal;p (GeV/c);TPC Signal", {HistType::kTH2F, {Binning.momentum, Binning.tpcSignal}}); + registryParticleQA.add("TrackQA/After/AntiKaon/fTofBeta", "TOF #beta;p (GeV/c);#beta_{TOF}", {HistType::kTH2F, {Binning.momentum, Binning.tofSignal}}); + + registryParticleQA.add("TrackQA/After/AntiKaon/fDcaXy", "DCA_{xy};p_{T} (GeV/c); DCA_{XY};Entries", HistType::kTH2F, {Binning.momentum, Binning.dca}); + registryParticleQA.add("TrackQA/After/AntiKaon/fDcaZ", "DCA_{z};p_{T} (GeV/c); DCA_{Z};Entries", HistType::kTH2F, {Binning.momentum, Binning.dca}); + + registryParticleQA.add("TrackQA/After/AntiKaon/fTpcClusters", "TPC Clusters;TPC Clusters;Entries", HistType::kTH1F, {Binning.tpcCluster}); + registryParticleQA.add("TrackQA/After/AntiKaon/fTpcCrossedRows", "TPC Crossed Rows;TPC Crossed Rows;Entries", HistType::kTH1F, {Binning.tpcCluster}); + registryParticleQA.add("TrackQA/After/AntiKaon/fTpcSharedClusters", "TPC Shared Clusters;TPC Shared Clusters;Entries", HistType::kTH1F, {Binning.tpcCluster}); + registryParticleQA.add("TrackQA/After/AntiKaon/fTpcSharedClusterOverClusterss", "TPC Shared Clusters/Clusters;TPC Shared Clusters/Clusters;Entries", HistType::kTH1F, {Binning.ratio}); + registryParticleQA.add("TrackQA/After/AntiKaon/fTpcFindableOverRows", "TPC Findabled/Crossed Rows;TPC Findable/CrossedRows;Entries", HistType::kTH1F, {Binning.ratio}); + registryParticleQA.add("TrackQA/After/AntiKaon/fTpcChi2OverCluster", "TPC #chi^{2}/Cluster;TPC #chi^{2}/Cluster;Entries", HistType::kTH1F, {Binning.tpcChi2}); + + registryParticleQA.add("TrackQA/After/AntiKaon/fItsClusters", "ITS Clusters;ITS Clusters;Entries", HistType::kTH1F, {Binning.itsCluster}); + registryParticleQA.add("TrackQA/After/AntiKaon/fItsIbClusters", "ITS Inner Barrel Clusters;ITS Inner Barrel Clusters;Entries", HistType::kTH1F, {Binning.itsIbCluster}); + registryParticleQA.add("TrackQA/After/AntiKaon/fItsChi2OverCluster", "ITS #chi^{2}/Cluster;ITS #chi^{2}/Cluster;Entries", HistType::kTH1F, {Binning.itsChi2}); // proton - // TEST P TPC - registry.add("TrackCuts/Proton/fPProton", "Momentum of protons at PV;p (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - registry.add("TrackCuts/Proton/fPTPCProton", "Momentum of protons at TPC inner wall;p_{TPC} (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - registry.add("TrackCuts/Proton/fPtProton", "Transverse momentum of all processed tracks;p_{T} (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - registry.add("TrackCuts/Proton/fMomCorProtonDif", "Momentum correlation;p_{reco} (GeV/c); (p_{TPC} - p_{reco}) (GeV/c)", {HistType::kTH2F, {{500, 0, 10}, {600, -3, 3}}}); - registry.add("TrackCuts/Proton/fMomCorProtonRatio", "Momentum correlation;p_{reco} (GeV/c); p_{TPC} - p_{reco} / p_{reco}", {HistType::kTH2F, {{500, 0, 10}, {200, -1, 1}}}); - registry.add("TrackCuts/Proton/fEtaProton", "Pseudorapidity of all processed tracks;#eta;Entries", HistType::kTH1F, {{500, -2, 2}}); - registry.add("TrackCuts/Proton/fPhiProton", "Azimuthal angle of all processed tracks;#phi;Entries", HistType::kTH1F, {{720, 0, TMath::TwoPi()}}); - registry.add("TrackCuts/Proton/fNsigmaTPCvsPProton", "NSigmaTPC Proton;p_{TPC} (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - registry.add("TrackCuts/Proton/fNsigmaTOFvsPProton", "NSigmaTOF Proton;p_{TPC} (GeV/c);n#sigma_{TOF}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - registry.add("TrackCuts/Proton/fNsigmaTPCTOFvsPProton", "NSigmaTPCTOF Proton;p_{TPC} (GeV/c);n#sigma_{comb}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, 0.f, 10.f}}}); - registry.add("TrackCuts/Proton/fNsigmaITSvsPProton", "NSigmaITS Proton;p (GeV/c);n#sigma_{ITS}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - - registry.add("TrackCuts/Proton/fNsigmaTPCvsPProtonP", "NSigmaTPC Proton P;p (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - registry.add("TrackCuts/Proton/fNsigmaTOFvsPProtonP", "NSigmaTOF Proton P;p (GeV/c);n#sigma_{TOF}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - registry.add("TrackCuts/Proton/fNsigmaTPCTOFvsPProtonP", "NSigmaTPCTOF Proton P;p (GeV/c);n#sigma_{comb}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, 0.f, 10.f}}}); - - registry.add("TrackCuts/Proton/fDCAxyProton", "fDCAxy Proton;DCA_{XY};Entries", HistType::kTH1F, {{500, -0.5f, 0.5f}}); - registry.add("TrackCuts/Proton/fDCAzProton", "fDCAz Proton;DCA_{Z};Entries", HistType::kTH1F, {{500, -0.5f, 0.5f}}); - registry.add("TrackCuts/Proton/fTPCsClsProton", "fTPCsCls Proton;TPC Shared Clusters;Entries", HistType::kTH1F, {{163, -1.0f, 162.0f}}); - registry.add("TrackCuts/Proton/fTPCcRowsProton", "fTPCcRows Proton;TPC Crossed Rows;Entries", HistType::kTH1F, {{163, -1.0f, 162.0f}}); - registry.add("TrackCuts/Proton/fTrkTPCfClsProton", "fTrkTPCfCls Proton;TPC Findable/CrossedRows;Entries", HistType::kTH1F, {{500, 0.0f, 3.0f}}); - registry.add("TrackCuts/Proton/fTPCnclsProton", "fTPCncls Proton;TPC Clusters;Entries", HistType::kTH1F, {{163, -1.0f, 162.0f}}); + registryParticleQA.add("TrackQA/After/Proton/fPt", "Transverse Momentum;p_{T} (GeV/c);Entries", HistType::kTH1F, {Binning.momentum}); + registryParticleQA.add("TrackQA/After/Proton/fPTpc", "Momentum at TPC inner wall;p_{TPC} (GeV/c);Entries", HistType::kTH1F, {Binning.momentum}); + registryParticleQA.add("TrackQA/After/Proton/fMomCor", "Momentum correlation;p_{reco} (GeV/c); p_{TPC} - p_{reco} / p_{reco}", {HistType::kTH2F, {Binning.momentum, Binning.momCor}}); + registryParticleQA.add("TrackQA/After/Proton/fEta", "Pseudorapidity;#eta;Entries", HistType::kTH1F, {Binning.eta}); + registryParticleQA.add("TrackQA/After/Proton/fPhi", "Azimuthal angle;#varphi;Entries", HistType::kTH1F, {Binning.phi}); + + registryParticleQA.add("TrackQA/After/Proton/fNsigmaIts", "NSigmaITS;p (GeV/c);n#sigma_{ITS}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); + registryParticleQA.add("TrackQA/After/Proton/fNsigmaTpc", "NSigmaTPC;p (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); + registryParticleQA.add("TrackQA/After/Proton/fNsigmaTof", "NSigmaTOF;p (GeV/c);n#sigma_{TOF}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); + registryParticleQA.add("TrackQA/After/Proton/fNsigmaTpcTof", "NSigmaTPCTOF;p (GeV/c);n#sigma_{comb}", {HistType::kTH2F, {Binning.momentum, Binning.nsigmaComb}}); + + registryParticleQA.add("TrackQA/After/Proton/fItsSignal", "ITS Signal;p (GeV/c); (cm)", {HistType::kTH2F, {Binning.momentum, Binning.itsSignal}}); + registryParticleQA.add("TrackQA/After/Proton/fTpcSignal", "TPC Signal;p (GeV/c);TPC Signal", {HistType::kTH2F, {Binning.momentum, Binning.tpcSignal}}); + registryParticleQA.add("TrackQA/After/Proton/fTofBeta", "TOF #beta;p (GeV/c);#beta_{TOF}", {HistType::kTH2F, {Binning.momentum, Binning.tofSignal}}); + + registryParticleQA.add("TrackQA/After/Proton/fDcaXy", "DCA_{xy};p_{T} (GeV/c); DCA_{XY};Entries", HistType::kTH2F, {Binning.momentum, Binning.dca}); + registryParticleQA.add("TrackQA/After/Proton/fDcaZ", "DCA_{z};p_{T} (GeV/c); DCA_{Z};Entries", HistType::kTH2F, {Binning.momentum, Binning.dca}); + + registryParticleQA.add("TrackQA/After/Proton/fTpcClusters", "TPC Clusters;TPC Clusters;Entries", HistType::kTH1F, {Binning.tpcCluster}); + registryParticleQA.add("TrackQA/After/Proton/fTpcCrossedRows", "TPC Crossed Rows;TPC Crossed Rows;Entries", HistType::kTH1F, {Binning.tpcCluster}); + registryParticleQA.add("TrackQA/After/Proton/fTpcSharedClusters", "TPC Shared Clusters;TPC Shared Clusters;Entries", HistType::kTH1F, {Binning.tpcCluster}); + registryParticleQA.add("TrackQA/After/Proton/fTpcSharedClusterOverClusterss", "TPC Shared Clusters/Clusters;TPC Shared Clusters/Clusters;Entries", HistType::kTH1F, {Binning.ratio}); + registryParticleQA.add("TrackQA/After/Proton/fTpcFindableOverRows", "TPC Findabled/Crossed Rows;TPC Findable/CrossedRows;Entries", HistType::kTH1F, {Binning.ratio}); + registryParticleQA.add("TrackQA/After/Proton/fTpcChi2OverCluster", "TPC #chi^{2}/Cluster;TPC #chi^{2}/Cluster;Entries", HistType::kTH1F, {Binning.tpcChi2}); + + registryParticleQA.add("TrackQA/After/Proton/fItsClusters", "ITS Clusters;ITS Clusters;Entries", HistType::kTH1F, {Binning.itsCluster}); + registryParticleQA.add("TrackQA/After/Proton/fItsIbClusters", "ITS Inner Barrel Clusters;ITS Inner Barrel Clusters;Entries", HistType::kTH1F, {Binning.itsIbCluster}); + registryParticleQA.add("TrackQA/After/Proton/fItsChi2OverCluster", "ITS #chi^{2}/Cluster;ITS #chi^{2}/Cluster;Entries", HistType::kTH1F, {Binning.itsChi2}); // antiproton - registry.add("TrackCuts/AntiProton/fPtAntiProton", "Transverse momentum of all processed tracks;p_{T} (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - registry.add("TrackCuts/AntiProton/fMomCorAntiProtonDif", "Momentum correlation;p_{reco} (GeV/c); (p_{TPC} - p_{reco}) (GeV/c)", {HistType::kTH2F, {{500, 0, 10}, {600, -3, 3}}}); - registry.add("TrackCuts/AntiProton/fMomCorAntiProtonRatio", "Momentum correlation;p_{reco} (GeV/c); |p_{TPC} - p_{reco}| (GeV/c)", {HistType::kTH2F, {{500, 0, 10}, {200, -1, 1}}}); - registry.add("TrackCuts/AntiProton/fEtaAntiProton", "Pseudorapidity of all processed tracks;#eta;Entries", HistType::kTH1F, {{500, -2, 2}}); - registry.add("TrackCuts/AntiProton/fPhiAntiProton", "Azimuthal angle of all processed tracks;#phi;Entries", HistType::kTH1F, {{720, 0, TMath::TwoPi()}}); - registry.add("TrackCuts/AntiProton/fNsigmaTPCvsPAntiProton", "NSigmaTPC AntiProton;p_{TPC} (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - registry.add("TrackCuts/AntiProton/fNsigmaTOFvsPAntiProton", "NSigmaTOF AntiProton;p_{TPC} (GeV/c);n#sigma_{TOF}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - registry.add("TrackCuts/AntiProton/fNsigmaTPCTOFvsPAntiProton", "NSigmaTPCTOF AntiProton;p_{TPC} (GeV/c);n#sigma_{comb}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, 0.f, 10.f}}}); - registry.add("TrackCuts/AntiProton/fNsigmaITSvsPAntiProton", "NSigmaITS AntiProton;p (GeV/c);n#sigma_{ITS}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - - registry.add("TrackCuts/AntiProton/fNsigmaTPCvsPAntiProtonP", "NSigmaTPC AntiProton P;p (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - registry.add("TrackCuts/AntiProton/fNsigmaTOFvsPAntiProtonP", "NSigmaTOF AntiProton P;p (GeV/c);n#sigma_{TOF}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - registry.add("TrackCuts/AntiProton/fNsigmaTPCTOFvsPAntiProtonP", "NSigmaTPCTOF AntiProton P;p (GeV/c);n#sigma_{comb}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, 0.f, 10.f}}}); - - registry.add("TrackCuts/AntiProton/fDCAxyAntiProton", "fDCAxy AntiProton;DCA_{XY};Entries", HistType::kTH1F, {{500, -0.5f, 0.5f}}); - registry.add("TrackCuts/AntiProton/fDCAzAntiProton", "fDCAz AntiProton;DCA_{Z};Entries", HistType::kTH1F, {{500, -0.5f, 0.5f}}); - registry.add("TrackCuts/AntiProton/fTPCsClsAntiProton", "fTPCsCls AntiProton;TPC Shared Clusters;Entries", HistType::kTH1F, {{163, -1.0f, 162.0f}}); - registry.add("TrackCuts/AntiProton/fTPCcRowsAntiProton", "fTPCcRows AntiProton;TPC Crossed Rows;Entries", HistType::kTH1F, {{163, -1.0f, 162.0f}}); - registry.add("TrackCuts/AntiProton/fTrkTPCfClsAntiProton", "fTrkTPCfCls AntiProton;TPC Findable/CrossedRows;Entries", HistType::kTH1F, {{500, 0.0f, 3.0f}}); - registry.add("TrackCuts/AntiProton/fTPCnclsAntiProton", "fTPCncls AntiProton;TPC Clusters;Entries", HistType::kTH1F, {{163, -1.0f, 162.0f}}); - - // deuteron - registry.add("TrackCuts/Deuteron/fPtDeuteron", "Transverse momentum of all processed tracks;p_{T} (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - registry.add("TrackCuts/Deuteron/fMomCorDeuteronDif", "Momentum correlation;p_{reco} (GeV/c); (p_{TPC} - p_{reco}) (GeV/c)", {HistType::kTH2F, {{500, 0, 10}, {600, -3, 3}}}); - registry.add("TrackCuts/Deuteron/fMomCorDeuteronRatio", "Momentum correlation;p_{reco} (GeV/c); |p_{TPC} - p_{reco}| (GeV/c)", {HistType::kTH2F, {{500, 0, 10}, {200, -1, 1}}}); - registry.add("TrackCuts/Deuteron/fEtaDeuteron", "Pseudorapidity of all processed tracks;#eta;Entries", HistType::kTH1F, {{500, -2, 2}}); - registry.add("TrackCuts/Deuteron/fPhiDeuteron", "Azimuthal angle of all processed tracks;#phi;Entries", HistType::kTH1F, {{720, 0, TMath::TwoPi()}}); - registry.add("TrackCuts/Deuteron/fNsigmaTPCvsPDeuteron", "NSigmaTPC Deuteron;p_{TPC} (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - registry.add("TrackCuts/Deuteron/fNsigmaTOFvsPDeuteron", "NSigmaTOF Deuteron;p_{TPC} (GeV/c);n#sigma_{TOF}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - registry.add("TrackCuts/Deuteron/fNsigmaTPCTOFvsPDeuteron", "NSigmaTPCTOF Deuteron;p_{TPC} (GeV/c);n#sigma_{comb}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, 0.f, 10.f}}}); - registry.add("TrackCuts/Deuteron/fNsigmaITSvsPDeuteron", "NSigmaITS Deuteron;p (GeV/c);n#sigma_{ITS}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - - registry.add("TrackCuts/Deuteron/fNsigmaTPCvsPDeuteronP", "NSigmaTPC Deuteron vd P;p (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - registry.add("TrackCuts/Deuteron/fNsigmaTOFvsPDeuteronP", "NSigmaTOF Deuteron P;p (GeV/c);n#sigma_{TOF}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - registry.add("TrackCuts/Deuteron/fNsigmaTPCTOFvsPDeuteronP", "NSigmaTPCTOF Deuteron P;p (GeV/c);n#sigma_{comb}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, 0.f, 10.f}}}); - - registry.add("TrackCuts/Deuteron/fDCAxyDeuteron", "fDCAxy Deuteron;DCA_{XY};Entries", HistType::kTH1F, {{500, -0.5f, 0.5f}}); - registry.add("TrackCuts/Deuteron/fDCAzDeuteron", "fDCAz Deuteron;DCA_{Z};Entries", HistType::kTH1F, {{500, -0.5f, 0.5f}}); - registry.add("TrackCuts/Deuteron/fTPCsClsDeuteron", "fTPCsCls Deuteron;TPC Shared Clusters;Entries", HistType::kTH1F, {{163, -1.0f, 162.0f}}); - registry.add("TrackCuts/Deuteron/fTPCcRowsDeuteron", "fTPCcRows Deuteron;TPC Crossed Rows;Entries", HistType::kTH1F, {{163, -1.0f, 162.0f}}); - registry.add("TrackCuts/Deuteron/fTrkTPCfClsDeuteron", "fTrkTPCfCls Deuteron;TPC Findable/CrossedRows;Entries", HistType::kTH1F, {{500, 0.0f, 3.0f}}); - registry.add("TrackCuts/Deuteron/fTPCnclsDeuteron", "fTPCncls Deuteron;TPC Clusters;Entries", HistType::kTH1F, {{163, -1.0f, 162.0f}}); - - // antideuteron - registry.add("TrackCuts/AntiDeuteron/fPtAntiDeuteron", "Transverse momentum of all processed tracks;p_{T} (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - registry.add("TrackCuts/AntiDeuteron/fMomCorAntiDeuteronDif", "Momentum correlation;p_{reco} (GeV/c); (p_{TPC} - p_{reco}) (GeV/c)", {HistType::kTH2F, {{500, 0, 10}, {600, -3, 3}}}); - registry.add("TrackCuts/AntiDeuteron/fMomCorAntiDeuteronRatio", "Momentum correlation;p_{reco} (GeV/c); (p_{TPC} - p_{reco}) (GeV/c)", {HistType::kTH2F, {{500, 0, 10}, {200, -1, 1}}}); - registry.add("TrackCuts/AntiDeuteron/fEtaAntiDeuteron", "Pseudorapidity of all processed tracks;#eta;Entries", HistType::kTH1F, {{500, -2, 2}}); - registry.add("TrackCuts/AntiDeuteron/fPhiAntiDeuteron", "Azimuthal angle of all processed tracks;#phi;Entries", HistType::kTH1F, {{720, 0, TMath::TwoPi()}}); - registry.add("TrackCuts/AntiDeuteron/fNsigmaTPCvsPAntiDeuteron", "NSigmaTPC AntiDeuteron;p_{TPC} (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - registry.add("TrackCuts/AntiDeuteron/fNsigmaTOFvsPAntiDeuteron", "NSigmaTOF AntiDeuteron;p_{TPC} (GeV/c);n#sigma_{TOF}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - registry.add("TrackCuts/AntiDeuteron/fNsigmaTPCTOFvsPAntiDeuteron", "NSigmaTPCTOF AntiDeuteron;p_{TPC} (GeV/c);n#sigma_{comb}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, 0.f, 10.f}}}); - registry.add("TrackCuts/AntiDeuteron/fNsigmaITSvsPAntiDeuteron", "NSigmaITS AntiDeuteron;p (GeV/c);n#sigma_{ITS}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - - registry.add("TrackCuts/AntiDeuteron/fNsigmaTPCvsPAntiDeuteronP", "NSigmaTPC AntiDeuteron P;p (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - registry.add("TrackCuts/AntiDeuteron/fNsigmaTOFvsPAntiDeuteronP", "NSigmaTOF AntiDeuteron P;p (GeV/c);n#sigma_{TOF}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - registry.add("TrackCuts/AntiDeuteron/fNsigmaTPCTOFvsPAntiDeuteronP", "NSigmaTPCTOF AntiDeuteron P;p (GeV/c);n#sigma_{comb}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, 0.f, 10.f}}}); - - registry.add("TrackCuts/AntiDeuteron/fDCAxyAntiDeuteron", "fDCAxy AntiDeuteron;DCA_{XY};Entries", HistType::kTH1F, {{500, -0.5f, 0.5f}}); - registry.add("TrackCuts/AntiDeuteron/fDCAzAntiDeuteron", "fDCAz AntiDeuteron;DCA_{Z};Entries", HistType::kTH1F, {{500, -0.5f, 0.5f}}); - registry.add("TrackCuts/AntiDeuteron/fTPCsClsAntiDeuteron", "fTPCsCls AntiDeuteron;TPC Shared Clusters;Entries", HistType::kTH1F, {{163, -1.0f, 162.0f}}); - registry.add("TrackCuts/AntiDeuteron/fTPCcRowsAntiDeuteron", "fTPCcRows AntiDeuteron;TPC Crossed Rows;Entries", HistType::kTH1F, {{163, -1.0f, 162.0f}}); - registry.add("TrackCuts/AntiDeuteron/fTrkTPCfClsAntiDeuteron", "fTrkTPCfCls AntiDeuteron;TPC Findable/CrossedRows;Entries", HistType::kTH1F, {{500, 0.0f, 3.0f}}); - registry.add("TrackCuts/AntiDeuteron/fTPCnclsAntiDeuteron", "fTPCncls AntiDeuteron;TPC Clusters;Entries", HistType::kTH1F, {{163, -1.0f, 162.0f}}); - - // lambda before selections - registry.add("TrackCuts/V0Before/fInvMassLambdavsAntiLambda", "Invariant mass of Lambda vs AntiLambda;M_{#pi p};Entries", HistType::kTH2F, {{500, 1.03, 1.5}, {500, 1.03, 1.5}}); - registry.add("TrackCuts/V0Before/fPtLambdaBefore", "Transverse momentum of all processed V0s before cuts;p_{T} (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - registry.add("TrackCuts/V0Before/fInvMassLambdaBefore", "Invariant mass of all processed V0s (Lambda) before cuts;M_{#pi p};Entries", HistType::kTH1F, {{500, 1.03, 1.5}}); - registry.add("TrackCuts/V0Before/fInvMassAntiLambdaBefore", "Invariant mass of all processed V0s (antiLambda) before cuts;M_{#pi p};Entries", HistType::kTH1F, {{500, 1.03, 1.5}}); - registry.add("TrackCuts/V0Before/fInvMassV0BeforeKaonvsV0Before", "Invariant mass of rejected K0 vs V0s (V0Before);M_{#pi p};;M_{#pi #pi}", HistType::kTH2F, {{500, 1.03, 1.5}, {500, 0.3, 0.6}}); - registry.add("TrackCuts/V0Before/fV0DCADaugh", "V0DCADaugh;DCA_{daugh};Entries", HistType::kTH1F, {{500, -4, 4}}); - registry.add("TrackCuts/V0Before/fV0CPA", "V0 CPA;CPA;Entries", HistType::kTH1F, {{500, 0.7, 1}}); - registry.add("TrackCuts/V0Before/fV0TranRad", "V0 TranRad;TranRad;Entries", HistType::kTH1F, {{500, 0, 150}}); - registry.add("TrackCuts/V0Before/f0DecVtxX", "V0 DecVtxX;DecVtX;Entries", HistType::kTH1F, {{500, 0, 150}}); - registry.add("TrackCuts/V0Before/f0DecVtxY", "V0 DecVtxY;DecVtY;Entries", HistType::kTH1F, {{500, 0, 150}}); - registry.add("TrackCuts/V0Before/f0DecVtxZ", "V0 DecVtxZ;DecVtz;Entries", HistType::kTH1F, {{500, 0, 150}}); - - registry.add("TrackCuts/V0Before/PosDaughter/Eta", "V0Before Pos Daugh Eta;#eta;Entries", HistType::kTH1F, {{500, -2, 2}}); - registry.add("TrackCuts/V0Before/PosDaughter/DCAXY", "V0Before Pos Daugh DCAXY;DCA_{XY};Entries", HistType::kTH1F, {{500, -2.5f, 2.5f}}); - registry.add("TrackCuts/V0Before/PosDaughter/fTPCncls", "V0Before Pos Daugh TPCncls;TPC Clusters;Entries", HistType::kTH1F, {{163, -1.0f, 162.0f}}); - registry.add("TrackCuts/V0Before/NegDaughter/Eta", "V0Before Neg Daugh Eta;#eta;Entries", HistType::kTH1F, {{500, -2, 2}}); - registry.add("TrackCuts/V0Before/NegDaughter/DCAXY", "V0Before Neg Daugh DCAXY;DCA_{XY};Entries", HistType::kTH1F, {{500, -2.5f, 2.5f}}); - registry.add("TrackCuts/V0Before/NegDaughter/fTPCncls", "V0Before Neg Daugh TPCncls;TPC Clusters;Entries", HistType::kTH1F, {{163, -1.0f, 162.0f}}); - registry.add("TrackCuts/V0Before/PosDaughter/fNsigmaTPCvsPProtonV0Daugh", "NSigmaTPC Proton V0Daught;p_{TPC} (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - registry.add("TrackCuts/V0Before/NegDaughter/fNsigmaTPCvsPPionMinusV0Daugh", "NSigmaTPC AntiPion V0Daught;p_{TPC} (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - registry.add("TrackCuts/V0Before/NegDaughter/fNsigmaTPCvsPAntiProtonV0Daugh", "NSigmaTPC Proton V0Daught;p_{TPC} (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - registry.add("TrackCuts/V0Before/PosDaughter/fNsigmaTPCvsPPionPlusV0Daugh", "NSigmaTPC AntiPion V0Daught;p_{TPC} (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - - // lambda - registry.add("TrackCuts/Lambda/fPtLambda", "Transverse momentum V0s;p_{T} (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - registry.add("TrackCuts/Lambda/fInvMassLambda", "Invariant mass V0s (Lambda);M_{#pi p};Entries", HistType::kTH1F, {{500, 1.03, 1.5}}); - registry.add("TrackCuts/Lambda/fInvMassLambdaKaonvsLambda", "Invariant mass of rejected K0 vs V0s (Lambda);M_{#pi p};M_{#pi #pi}", HistType::kTH2F, {{500, 1.03, 1.5}, {500, 0.3, 0.6}}); - registry.add("TrackCuts/Lambda/fV0DCADaugh", "V0DCADaugh;DCA_{daugh};Entries", HistType::kTH1F, {{500, -4, 4}}); - registry.add("TrackCuts/Lambda/fV0CPA", "V0 CPA;CPA;Entries", HistType::kTH1F, {{500, 0.7, 1}}); - registry.add("TrackCuts/Lambda/fV0TranRad", "V0 TranRad;TranRad;Entries", HistType::kTH1F, {{500, 0, 150}}); - registry.add("TrackCuts/Lambda/f0DecVtxX", "V0 DecVtxX;DecVtX;Entries", HistType::kTH1F, {{500, 0, 150}}); - registry.add("TrackCuts/Lambda/f0DecVtxY", "V0 DecVtxY;DecVtY;Entries", HistType::kTH1F, {{500, 0, 150}}); - registry.add("TrackCuts/Lambda/f0DecVtxZ", "V0 DecVtxZ;DecVtZ;Entries", HistType::kTH1F, {{500, 0, 150}}); - - // Lambda daughter - registry.add("TrackCuts/Lambda/PosDaughter/Eta", "Lambda Pos Daugh Eta;#eta;Entries", HistType::kTH1F, {{500, -2, 2}}); - registry.add("TrackCuts/Lambda/PosDaughter/DCAXY", "Lambda Pos Daugh DCAXY;DCA_{XY};Entries", HistType::kTH1F, {{500, -2.5f, 2.5f}}); - registry.add("TrackCuts/Lambda/PosDaughter/fTPCncls", "Lambda Pos Daugh TPCncls;TPC Clusters;Entries", HistType::kTH1F, {{163, -1.0f, 162.0f}}); - registry.add("TrackCuts/Lambda/NegDaughter/Eta", "Lambda Neg Daugh Eta;#eta;Entries", HistType::kTH1F, {{500, -2, 2}}); - registry.add("TrackCuts/Lambda/NegDaughter/DCAXY", "Lambda Neg Daugh DCAXY;DCA_{XY};Entries", HistType::kTH1F, {{500, -2.5f, 2.5f}}); - registry.add("TrackCuts/Lambda/NegDaughter/fTPCncls", "Lambda Neg Daugh TPCncls;TPC Clusters;Entries", HistType::kTH1F, {{163, -1.0f, 162.0f}}); - registry.add("TrackCuts/Lambda/PosDaughter/fNsigmaTPCvsPProtonV0Daugh", "NSigmaTPC Proton V0Daught;p_{TPC} (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - registry.add("TrackCuts/Lambda/NegDaughter/fNsigmaTPCvsPPionMinusV0Daugh", "NSigmaTPC AntiPion V0Daught;p_{TPC} (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - - // antilambda - registry.add("TrackCuts/AntiLambda/fPtAntiLambda", "Transverse momentum V0s;p_{T} (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - registry.add("TrackCuts/AntiLambda/fInvMassAntiLambda", "Invariant mass V0s (Lambda);M_{#pi p};Entries", HistType::kTH1F, {{500, 1.03, 1.5}}); - registry.add("TrackCuts/AntiLambda/fInvMassAntiLambdaKaonvsAntiLambda", "Invariant mass of rejected K0 vs V0s (Lambda);M_{#pi p};M_{#pi #pi}", HistType::kTH2F, {{500, 1.03, 1.5}, {500, 0.3, 0.6}}); - registry.add("TrackCuts/AntiLambda/fV0DCADaugh", "V0DCADaugh;DCA_{daugh};Entries", HistType::kTH1F, {{500, -4, 4}}); - registry.add("TrackCuts/AntiLambda/fV0CPA", "V0 CPA;CPA;Entries", HistType::kTH1F, {{500, 0.7, 1}}); - registry.add("TrackCuts/AntiLambda/fV0TranRad", "V0 TranRad;TranRad;Entries", HistType::kTH1F, {{500, 0, 150}}); - registry.add("TrackCuts/AntiLambda/f0DecVtxX", "V0 DecVtxX;DecVtX;Entries", HistType::kTH1F, {{500, 0, 150}}); - registry.add("TrackCuts/AntiLambda/f0DecVtxY", "V0 DecVtxY;DecVtY;Entries", HistType::kTH1F, {{500, 0, 150}}); - registry.add("TrackCuts/AntiLambda/f0DecVtxZ", "V0 DecVtxZ;DecVtZ;Entries", HistType::kTH1F, {{500, 0, 150}}); - - // AntiLambda daughter - registry.add("TrackCuts/AntiLambda/PosDaughter/Eta", "AntiLambda Pos Daugh Eta;#eta;Entries", HistType::kTH1F, {{500, -2, 2}}); - registry.add("TrackCuts/AntiLambda/PosDaughter/DCAXY", "AntiLambda Pos Daugh DCAXY;DCA_{XY};Entries", HistType::kTH1F, {{500, -2.5f, 2.5f}}); - registry.add("TrackCuts/AntiLambda/PosDaughter/fTPCncls", "AntiLambda Pos Daugh TPCncls;TPC Clusters;Entries", HistType::kTH1F, {{163, -1.0f, 162.0f}}); - registry.add("TrackCuts/AntiLambda/NegDaughter/Eta", "AntiLambda Neg Daugh Eta;#eta;Entries", HistType::kTH1F, {{500, -2, 2}}); - registry.add("TrackCuts/AntiLambda/NegDaughter/DCAXY", "AntiLambda Neg Daugh DCAXY;DCA_{XY};Entries", HistType::kTH1F, {{500, -2.5f, 2.5f}}); - registry.add("TrackCuts/AntiLambda/NegDaughter/fTPCncls", "AntiLambda Neg Daugh TPCncls;TPC Clusters;Entries", HistType::kTH1F, {{163, -1.0f, 162.0f}}); - registry.add("TrackCuts/AntiLambda/NegDaughter/fNsigmaTPCvsPAntiProtonAntiV0Daugh", "NSigmaTPC AntiProton antiV0Daught;p_{TPC} (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - registry.add("TrackCuts/AntiLambda/PosDaughter/fNsigmaTPCvsPPionPlusAntiV0Daugh", "NSigmaTPC Pion antiV0Daught;p_{TPC} (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - - // Phi - - registry.add("TrackCuts/Phi/Before/fInvMass", "Invariant mass V0s;M_{KK};Entries", HistType::kTH1F, {{7000, 0.8, 1.5}}); - registry.add("TrackCuts/Phi/Before/fPt", "Transverse momentum V0s;p_{T} (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - registry.add("TrackCuts/Phi/Before/fEta", "Pseudorapidity of V0;#eta;Entries", HistType::kTH1F, {{500, -2, 2}}); - registry.add("TrackCuts/Phi/Before/fPhi", "Azimuthal angle of V0;#phi;Entries", HistType::kTH1F, {{720, 0, TMath::TwoPi()}}); - - registry.add("TrackCuts/Phi/Before/PosDaughter/fP", "Momentum of Kaons at PV;p (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - registry.add("TrackCuts/Phi/Before/PosDaughter/fPTPC", "Momentum of Kaons at TPC inner wall;p_{TPC} (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - registry.add("TrackCuts/Phi/Before/PosDaughter/fPt", "Transverse momentum of all processed tracks;p_{T} (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - registry.add("TrackCuts/Phi/Before/PosDaughter/fMomCorDif", "Momentum correlation;p_{reco} (GeV/c); (p_{TPC} - p_{reco}) (GeV/c)", {HistType::kTH2F, {{500, 0, 10}, {600, -3, 3}}}); - registry.add("TrackCuts/Phi/Before/PosDaughter/fMomCorRatio", "Momentum correlation;p_{reco} (GeV/c); p_{TPC} - p_{reco} / p_{reco}", {HistType::kTH2F, {{500, 0, 10}, {200, -1, 1}}}); - registry.add("TrackCuts/Phi/Before/PosDaughter/fEta", "Pseudorapidity of all processed tracks;#eta;Entries", HistType::kTH1F, {{500, -2, 2}}); - registry.add("TrackCuts/Phi/Before/PosDaughter/fPhi", "Azimuthal angle of all processed tracks;#phi;Entries", HistType::kTH1F, {{720, 0, TMath::TwoPi()}}); - registry.add("TrackCuts/Phi/Before/PosDaughter/fNsigmaTPCvsP", "NSigmaTPC Kaon;p_{TPC} (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - registry.add("TrackCuts/Phi/Before/PosDaughter/fNsigmaTOFvsP", "NSigmaTOF Kaon;p_{TPC} (GeV/c);n#sigma_{TOF}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - registry.add("TrackCuts/Phi/Before/PosDaughter/fNsigmaTPCTOFvsP", "NSigmaTPCTOF Kaon;p_{TPC} (GeV/c);n#sigma_{comb}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, 0.f, 10.f}}}); - registry.add("TrackCuts/Phi/Before/PosDaughter/fDCAxy", "fDCAxy Kaon;DCA_{XY};Entries", HistType::kTH1F, {{500, -0.5f, 0.5f}}); - registry.add("TrackCuts/Phi/Before/PosDaughter/fDCAz", "fDCAz Kaon;DCA_{Z};Entries", HistType::kTH1F, {{500, -0.5f, 0.5f}}); - registry.add("TrackCuts/Phi/Before/PosDaughter/fTPCsCls", "fTPCsCls Kaon;TPC Shared Clusters;Entries", HistType::kTH1F, {{163, -1.0f, 162.0f}}); - registry.add("TrackCuts/Phi/Before/PosDaughter/fTPCcRows", "fTPCcRows Kaon;TPC Crossed Rows;Entries", HistType::kTH1F, {{163, -1.0f, 162.0f}}); - registry.add("TrackCuts/Phi/Before/PosDaughter/fTrkTPCfCls", "fTrkTPCfCls Kaon;TPC Findable/CrossedRows;Entries", HistType::kTH1F, {{500, 0.0f, 3.0f}}); - registry.add("TrackCuts/Phi/Before/PosDaughter/fTPCncls", "fTPCncls Kaon;TPC Clusters;Entries", HistType::kTH1F, {{163, -1.0f, 162.0f}}); - - registry.add("TrackCuts/Phi/Before/NegDaughter/fP", "Momentum of Kaons at PV;p (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - registry.add("TrackCuts/Phi/Before/NegDaughter/fPTPC", "Momentum of Kaons at TPC inner wall;p_{TPC} (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - registry.add("TrackCuts/Phi/Before/NegDaughter/fPt", "Transverse momentum of all processed tracks;p_{T} (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - registry.add("TrackCuts/Phi/Before/NegDaughter/fMomCorDif", "Momentum correlation;p_{reco} (GeV/c); (p_{TPC} - p_{reco}) (GeV/c)", {HistType::kTH2F, {{500, 0, 10}, {600, -3, 3}}}); - registry.add("TrackCuts/Phi/Before/NegDaughter/fMomCorRatio", "Momentum correlation;p_{reco} (GeV/c); p_{TPC} - p_{reco} / p_{reco}", {HistType::kTH2F, {{500, 0, 10}, {200, -1, 1}}}); - registry.add("TrackCuts/Phi/Before/NegDaughter/fEta", "Pseudorapidity of all processed tracks;#eta;Entries", HistType::kTH1F, {{500, -2, 2}}); - registry.add("TrackCuts/Phi/Before/NegDaughter/fPhi", "Azimuthal angle of all processed tracks;#phi;Entries", HistType::kTH1F, {{720, 0, TMath::TwoPi()}}); - registry.add("TrackCuts/Phi/Before/NegDaughter/fNsigmaTPCvsP", "NSigmaTPC Kaon;p_{TPC} (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - registry.add("TrackCuts/Phi/Before/NegDaughter/fNsigmaTOFvsP", "NSigmaTOF Kaon;p_{TPC} (GeV/c);n#sigma_{TOF}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - registry.add("TrackCuts/Phi/Before/NegDaughter/fNsigmaTPCTOFvsP", "NSigmaTPCTOF Kaon;p_{TPC} (GeV/c);n#sigma_{comb}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, 0.f, 10.f}}}); - registry.add("TrackCuts/Phi/Before/NegDaughter/fDCAxy", "fDCAxy Kaon;DCA_{XY};Entries", HistType::kTH1F, {{500, -0.5f, 0.5f}}); - registry.add("TrackCuts/Phi/Before/NegDaughter/fDCAz", "fDCAz Kaon;DCA_{Z};Entries", HistType::kTH1F, {{500, -0.5f, 0.5f}}); - registry.add("TrackCuts/Phi/Before/NegDaughter/fTPCsCls", "fTPCsCls Kaon;TPC Shared Clusters;Entries", HistType::kTH1F, {{163, -1.0f, 162.0f}}); - registry.add("TrackCuts/Phi/Before/NegDaughter/fTPCcRows", "fTPCcRows Kaon;TPC Crossed Rows;Entries", HistType::kTH1F, {{163, -1.0f, 162.0f}}); - registry.add("TrackCuts/Phi/Before/NegDaughter/fTrkTPCfCls", "fTrkTPCfCls Kaon;TPC Findable/CrossedRows;Entries", HistType::kTH1F, {{500, 0.0f, 3.0f}}); - registry.add("TrackCuts/Phi/Before/NegDaughter/fTPCncls", "fTPCncls Kaon;TPC Clusters;Entries", HistType::kTH1F, {{163, -1.0f, 162.0f}}); - - registry.add("TrackCuts/Phi/After/fInvMass", "Invariant mass V0s;M_{KK};Entries", HistType::kTH1F, {{7000, 0.8, 1.5}}); - registry.add("TrackCuts/Phi/After/fPt", "Transverse momentum V0s;p_{T} (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - registry.add("TrackCuts/Phi/After/fEta", "Pseudorapidity of V0;#eta;Entries", HistType::kTH1F, {{500, -2, 2}}); - registry.add("TrackCuts/Phi/After/fPhi", "Azimuthal angle of V0;#phi;Entries", HistType::kTH1F, {{720, 0, TMath::TwoPi()}}); - - // phi daughter - registry.add("TrackCuts/Phi/After/PosDaughter/fPt", "Transverse momentum Pos Daugh tracks;p_{T} (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - registry.add("TrackCuts/Phi/After/PosDaughter/fEta", "Phi Pos Daugh Eta;#eta;Entries", HistType::kTH1F, {{500, -2, 2}}); - registry.add("TrackCuts/Phi/After/PosDaughter/fPhi", "Azimuthal angle of Pos Daugh tracks;#phi;Entries", HistType::kTH1F, {{720, 0, TMath::TwoPi()}}); - - registry.add("TrackCuts/Phi/After/NegDaughter/fPt", "Transverse momentum Neg Daugh tracks;p_{T} (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - registry.add("TrackCuts/Phi/After/NegDaughter/fEta", "Phi Neg Daugh Eta;#eta;Entries", HistType::kTH1F, {{500, -2, 2}}); - registry.add("TrackCuts/Phi/After/NegDaughter/fPhi", "Azimuthal angle of Neg Daugh tracks;#phi;Entries", HistType::kTH1F, {{720, 0, TMath::TwoPi()}}); - - // pions - registry.add("TrackCuts/Pion/fPPion", "Momentum of Pions at PV;p (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - registry.add("TrackCuts/Pion/fPTPCPion", "Momentum of Pions at TPC inner wall;p_{TPC} (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - registry.add("TrackCuts/Pion/fPtPion", "Transverse momentum of all processed tracks;p_{T} (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - registry.add("TrackCuts/Pion/fMomCorPionDif", "Momentum correlation;p_{reco} (GeV/c); (p_{TPC} - p_{reco}) (GeV/c)", {HistType::kTH2F, {{500, 0, 10}, {600, -3, 3}}}); - registry.add("TrackCuts/Pion/fMomCorPionRatio", "Momentum correlation;p_{reco} (GeV/c); p_{TPC} - p_{reco} / p_{reco}", {HistType::kTH2F, {{500, 0, 10}, {200, -1, 1}}}); - registry.add("TrackCuts/Pion/fEtaPion", "Pseudorapidity of all processed tracks;#eta;Entries", HistType::kTH1F, {{500, -2, 2}}); - registry.add("TrackCuts/Pion/fPhiPion", "Azimuthal angle of all processed tracks;#phi;Entries", HistType::kTH1F, {{720, 0, TMath::TwoPi()}}); - registry.add("TrackCuts/Pion/fNsigmaTPCvsPPion", "NSigmaTPC Pion;p_{TPC} (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - registry.add("TrackCuts/Pion/fNsigmaTOFvsPPion", "NSigmaTOF Pion;p_{TPC} (GeV/c);n#sigma_{TOF}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - registry.add("TrackCuts/Pion/fNsigmaTPCTOFvsPPion", "NSigmaTPCTOF Pion;p_{TPC} (GeV/c);n#sigma_{comb}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, 0.f, 10.f}}}); - - registry.add("TrackCuts/Pion/fNsigmaTPCvsPPionP", "NSigmaTPC Pion P;p (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - registry.add("TrackCuts/Pion/fNsigmaTOFvsPPionP", "NSigmaTOF Pion P;p (GeV/c);n#sigma_{TOF}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - registry.add("TrackCuts/Pion/fNsigmaTPCTOFvsPPionP", "NSigmaTPCTOF Pion P;p (GeV/c);n#sigma_{comb}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, 0.f, 10.f}}}); - - registry.add("TrackCuts/Pion/fDCAxyPion", "fDCAxy Pion;DCA_{XY};Entries", HistType::kTH1F, {{500, -0.5f, 0.5f}}); - registry.add("TrackCuts/Pion/fDCAzPion", "fDCAz Pion;DCA_{Z};Entries", HistType::kTH1F, {{500, -0.5f, 0.5f}}); - registry.add("TrackCuts/Pion/fTPCsClsPion", "fTPCsCls Pion;TPC Shared Clusters;Entries", HistType::kTH1F, {{163, -1.0f, 162.0f}}); - registry.add("TrackCuts/Pion/fTPCcRowsPion", "fTPCcRows Pion;TPC Crossed Rows;Entries", HistType::kTH1F, {{163, -1.0f, 162.0f}}); - registry.add("TrackCuts/Pion/fTrkTPCfClsPion", "fTrkTPCfCls Pion;TPC Findable/CrossedRows;Entries", HistType::kTH1F, {{500, 0.0f, 3.0f}}); - registry.add("TrackCuts/Pion/fTPCnclsPion", "fTPCncls Pion;TPC Clusters;Entries", HistType::kTH1F, {{163, -1.0f, 162.0f}}); - - // anti-pions - registry.add("TrackCuts/AntiPion/fPtAntiPion", "Transverse momentum of all processed tracks;p_{T} (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - registry.add("TrackCuts/AntiPion/fMomCorAntiPionDif", "Momentum correlation;p_{reco} (GeV/c); (p_{TPC} - p_{reco}) (GeV/c)", {HistType::kTH2F, {{500, 0, 10}, {600, -3, 3}}}); - registry.add("TrackCuts/AntiPion/fMomCorAntiPionRatio", "Momentum correlation;p_{reco} (GeV/c); |p_{TPC} - p_{reco}| (GeV/c)", {HistType::kTH2F, {{500, 0, 10}, {200, -1, 1}}}); - registry.add("TrackCuts/AntiPion/fEtaAntiPion", "Pseudorapidity of all processed tracks;#eta;Entries", HistType::kTH1F, {{500, -2, 2}}); - registry.add("TrackCuts/AntiPion/fPhiAntiPion", "Azimuthal angle of all processed tracks;#phi;Entries", HistType::kTH1F, {{720, 0, TMath::TwoPi()}}); - registry.add("TrackCuts/AntiPion/fNsigmaTPCvsPAntiPion", "NSigmaTPC AntiPion;p_{TPC} (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - registry.add("TrackCuts/AntiPion/fNsigmaTOFvsPAntiPion", "NSigmaTOF AntiPion;p_{TPC} (GeV/c);n#sigma_{TOF}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - registry.add("TrackCuts/AntiPion/fNsigmaTPCTOFvsPAntiPion", "NSigmaTPCTOF AntiPion;p_{TPC} (GeV/c);n#sigma_{comb}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, 0.f, 10.f}}}); - - registry.add("TrackCuts/AntiPion/fNsigmaTPCvsPAntiPionP", "NSigmaTPC AntiPion P;p (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - registry.add("TrackCuts/AntiPion/fNsigmaTOFvsPAntiPionP", "NSigmaTOF AntiPion P;p (GeV/c);n#sigma_{TOF}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - registry.add("TrackCuts/AntiPion/fNsigmaTPCTOFvsPAntiPionP", "NSigmaTPCTOF AntiPion P;p (GeV/c);n#sigma_{comb}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, 0.f, 10.f}}}); - - registry.add("TrackCuts/AntiPion/fDCAxyAntiPion", "fDCAxy AntiPion;DCA_{XY};Entries", HistType::kTH1F, {{500, -0.5f, 0.5f}}); - registry.add("TrackCuts/AntiPion/fDCAzAntiPion", "fDCAz AntiPion;DCA_{Z};Entries", HistType::kTH1F, {{500, -0.5f, 0.5f}}); - registry.add("TrackCuts/AntiPion/fTPCsClsAntiPion", "fTPCsCls AntiPion;TPC Shared Clusters;Entries", HistType::kTH1F, {{163, -1.0f, 162.0f}}); - registry.add("TrackCuts/AntiPion/fTPCcRowsAntiPion", "fTPCcRows AntiPion;TPC Crossed Rows;Entries", HistType::kTH1F, {{163, -1.0f, 162.0f}}); - registry.add("TrackCuts/AntiPion/fTrkTPCfClsAntiPion", "fTrkTPCfCls AntiPion;TPC Findable/CrossedRows;Entries", HistType::kTH1F, {{500, 0.0f, 3.0f}}); - registry.add("TrackCuts/AntiPion/fTPCnclsAntiPion", "fTPCncls AntiPion;TPC Clusters;Entries", HistType::kTH1F, {{163, -1.0f, 162.0f}}); - - // rho QA - // daughter pos before - registry.add("TrackCuts/Rho/Before/PosDaughter/fInvMass", "Invariant mass Rho Pos Daugh;M_{#pi};Entries", HistType::kTH1F, {{500, 0, 1}}); - registry.add("TrackCuts/Rho/Before/PosDaughter/fPt", "Transverse momentum Rho Pos Daugh tracks;p_{T} (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - registry.add("TrackCuts/Rho/Before/PosDaughter/fEta", "Rho Pos Daugh Eta;#eta;Entries", HistType::kTH1F, {{500, -2, 2}}); - registry.add("TrackCuts/Rho/Before/PosDaughter/fPhi", "Azimuthal angle of Rho Pos Daugh tracks;#phi;Entries", HistType::kTH1F, {{720, 0, TMath::TwoPi()}}); - // daughter neg before - registry.add("TrackCuts/Rho/Before/NegDaughter/fInvMass", "Invariant mass Rho Neg Daugh;M_{#pi};Entries", HistType::kTH1F, {{500, 0, 1}}); - registry.add("TrackCuts/Rho/Before/NegDaughter/fPt", "Transverse momentum Rho Neg Daugh tracks;p_{T} (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - registry.add("TrackCuts/Rho/Before/NegDaughter/fEta", "Rho Neg Daugh Eta;#eta;Entries", HistType::kTH1F, {{500, -2, 2}}); - registry.add("TrackCuts/Rho/Before/NegDaughter/fPhi", "Azimuthal angle of Rho Neg Daugh tracks;#phi;Entries", HistType::kTH1F, {{720, 0, TMath::TwoPi()}}); - // rhoCand before - registry.add("TrackCuts/Rho/Before/fInvMass", "Invariant mass RhoCand;M_{#pi#pi};Entries", HistType::kTH1F, {{5000, 0, 5}}); - registry.add("TrackCuts/Rho/Before/fPt", "Transverse momentum RhoCand;p_{T} (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - registry.add("TrackCuts/Rho/Before/fEta", "Pseudorapidity of RhoCand;#eta;Entries", HistType::kTH1F, {{500, -2, 2}}); - registry.add("TrackCuts/Rho/Before/fPhi", "Azimuthal angle of RhoCand;#phi;Entries", HistType::kTH1F, {{720, 0, TMath::TwoPi()}}); - // daughter pos after - registry.add("TrackCuts/Rho/After/PosDaughter/fPt", "Transverse momentum RhoCand Pos Daugh tracks;p_{T} (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - registry.add("TrackCuts/Rho/After/PosDaughter/fEta", "RhoCand Pos Daugh Eta;#eta;Entries", HistType::kTH1F, {{500, -2, 2}}); - registry.add("TrackCuts/Rho/After/PosDaughter/fPhi", "Azimuthal angle of RhoCand Pos Daugh tracks;#phi;Entries", HistType::kTH1F, {{720, 0, TMath::TwoPi()}}); - // daughter neg after - registry.add("TrackCuts/Rho/After/NegDaughter/fPt", "Transverse momentum RhoCand Neg Daugh tracks;p_{T} (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - registry.add("TrackCuts/Rho/After/NegDaughter/fEta", "RhoCand Neg Daugh Eta;#eta;Entries", HistType::kTH1F, {{500, -2, 2}}); - registry.add("TrackCuts/Rho/After/NegDaughter/fPhi", "Azimuthal angle of RhoCand Neg Daugh tracks;#phi;Entries", HistType::kTH1F, {{720, 0, TMath::TwoPi()}}); - // rhoCand after - registry.add("TrackCuts/Rho/After/fInvMass", "Invariant mass RhoCand;M_{#pi#pi};Entries", HistType::kTH1F, {{5000, 0, 5}}); - registry.add("TrackCuts/Rho/After/fPt", "Transverse momentum RhoCand;p_{T} (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - registry.add("TrackCuts/Rho/After/fEta", "Pseudorapidity of RhoCand;#eta;Entries", HistType::kTH1F, {{500, -2, 2}}); - registry.add("TrackCuts/Rho/After/fPhi", "Azimuthal angle of RhoCand;#phi;Entries", HistType::kTH1F, {{720, 0, TMath::TwoPi()}}); + registryParticleQA.add("TrackQA/After/AntiProton/fPt", "Transverse Momentum;p_{T} (GeV/c);Entries", HistType::kTH1F, {Binning.momentum}); + registryParticleQA.add("TrackQA/After/AntiProton/fPTpc", "Momentum at TPC inner wall;p_{TPC} (GeV/c);Entries", HistType::kTH1F, {Binning.momentum}); + registryParticleQA.add("TrackQA/After/AntiProton/fMomCor", "Momentum correlation;p_{reco} (GeV/c); p_{TPC} - p_{reco} / p_{reco}", {HistType::kTH2F, {Binning.momentum, Binning.momCor}}); + registryParticleQA.add("TrackQA/After/AntiProton/fEta", "Pseudorapidity;#eta;Entries", HistType::kTH1F, {Binning.eta}); + registryParticleQA.add("TrackQA/After/AntiProton/fPhi", "Azimuthal angle;#varphi;Entries", HistType::kTH1F, {Binning.phi}); + + registryParticleQA.add("TrackQA/After/AntiProton/fNsigmaIts", "NSigmaITS;p (GeV/c);n#sigma_{ITS}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); + registryParticleQA.add("TrackQA/After/AntiProton/fNsigmaTpc", "NSigmaTPC;p (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); + registryParticleQA.add("TrackQA/After/AntiProton/fNsigmaTof", "NSigmaTOF;p (GeV/c);n#sigma_{TOF}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); + registryParticleQA.add("TrackQA/After/AntiProton/fNsigmaTpcTof", "NSigmaTPCTOF;p (GeV/c);n#sigma_{comb}", {HistType::kTH2F, {Binning.momentum, Binning.nsigmaComb}}); + + registryParticleQA.add("TrackQA/After/AntiProton/fItsSignal", "ITS Signal;p (GeV/c); (cm)", {HistType::kTH2F, {Binning.momentum, Binning.itsSignal}}); + registryParticleQA.add("TrackQA/After/AntiProton/fTpcSignal", "TPC Signal;p (GeV/c);TPC Signal", {HistType::kTH2F, {Binning.momentum, Binning.tpcSignal}}); + registryParticleQA.add("TrackQA/After/AntiProton/fTofBeta", "TOF #beta;p (GeV/c);#beta_{TOF}", {HistType::kTH2F, {Binning.momentum, Binning.tofSignal}}); + + registryParticleQA.add("TrackQA/After/AntiProton/fDcaXy", "DCA_{xy};p_{T} (GeV/c); DCA_{XY};Entries", HistType::kTH2F, {Binning.momentum, Binning.dca}); + registryParticleQA.add("TrackQA/After/AntiProton/fDcaZ", "DCA_{z};p_{T} (GeV/c); DCA_{Z};Entries", HistType::kTH2F, {Binning.momentum, Binning.dca}); + + registryParticleQA.add("TrackQA/After/AntiProton/fTpcClusters", "TPC Clusters;TPC Clusters;Entries", HistType::kTH1F, {Binning.tpcCluster}); + registryParticleQA.add("TrackQA/After/AntiProton/fTpcCrossedRows", "TPC Crossed Rows;TPC Crossed Rows;Entries", HistType::kTH1F, {Binning.tpcCluster}); + registryParticleQA.add("TrackQA/After/AntiProton/fTpcSharedClusters", "TPC Shared Clusters;TPC Shared Clusters;Entries", HistType::kTH1F, {Binning.tpcCluster}); + registryParticleQA.add("TrackQA/After/AntiProton/fTpcSharedClusterOverClusterss", "TPC Shared Clusters/Clusters;TPC Shared Clusters/Clusters;Entries", HistType::kTH1F, {Binning.ratio}); + registryParticleQA.add("TrackQA/After/AntiProton/fTpcFindableOverRows", "TPC Findabled/Crossed Rows;TPC Findable/CrossedRows;Entries", HistType::kTH1F, {Binning.ratio}); + registryParticleQA.add("TrackQA/After/AntiProton/fTpcChi2OverCluster", "TPC #chi^{2}/Cluster;TPC #chi^{2}/Cluster;Entries", HistType::kTH1F, {Binning.tpcChi2}); + + registryParticleQA.add("TrackQA/After/AntiProton/fItsClusters", "ITS Clusters;ITS Clusters;Entries", HistType::kTH1F, {Binning.itsCluster}); + registryParticleQA.add("TrackQA/After/AntiProton/fItsIbClusters", "ITS Inner Barrel Clusters;ITS Inner Barrel Clusters;Entries", HistType::kTH1F, {Binning.itsIbCluster}); + registryParticleQA.add("TrackQA/After/AntiProton/fItsChi2OverCluster", "ITS #chi^{2}/Cluster;ITS #chi^{2}/Cluster;Entries", HistType::kTH1F, {Binning.itsChi2}); + + // Deuteron + registryParticleQA.add("TrackQA/After/Deuteron/fPt", "Transverse Momentum;p_{T} (GeV/c);Entries", HistType::kTH1F, {Binning.momentum}); + registryParticleQA.add("TrackQA/After/Deuteron/fPTpc", "Momentum at TPC inner wall;p_{TPC} (GeV/c);Entries", HistType::kTH1F, {Binning.momentum}); + registryParticleQA.add("TrackQA/After/Deuteron/fMomCor", "Momentum correlation;p_{reco} (GeV/c); p_{TPC} - p_{reco} / p_{reco}", {HistType::kTH2F, {Binning.momentum, Binning.momCor}}); + registryParticleQA.add("TrackQA/After/Deuteron/fEta", "Pseudorapidity;#eta;Entries", HistType::kTH1F, {Binning.eta}); + registryParticleQA.add("TrackQA/After/Deuteron/fPhi", "Azimuthal angle;#varphi;Entries", HistType::kTH1F, {Binning.phi}); + + registryParticleQA.add("TrackQA/After/Deuteron/fNsigmaIts", "NSigmaITS;p (GeV/c);n#sigma_{ITS}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); + registryParticleQA.add("TrackQA/After/Deuteron/fNsigmaTpc", "NSigmaTPC;p (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); + registryParticleQA.add("TrackQA/After/Deuteron/fNsigmaTof", "NSigmaTOF;p (GeV/c);n#sigma_{TOF}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); + registryParticleQA.add("TrackQA/After/Deuteron/fNsigmaTpcTof", "NSigmaTPCTOF;p (GeV/c);n#sigma_{comb}", {HistType::kTH2F, {Binning.momentum, Binning.nsigmaComb}}); + + registryParticleQA.add("TrackQA/After/Deuteron/fItsSignal", "ITS Signal;p (GeV/c); (cm)", {HistType::kTH2F, {Binning.momentum, Binning.itsSignal}}); + registryParticleQA.add("TrackQA/After/Deuteron/fTpcSignal", "TPC Signal;p (GeV/c);TPC Signal", {HistType::kTH2F, {Binning.momentum, Binning.tpcSignal}}); + registryParticleQA.add("TrackQA/After/Deuteron/fTofBeta", "TOF #beta;p (GeV/c);#beta_{TOF}", {HistType::kTH2F, {Binning.momentum, Binning.tofSignal}}); + + registryParticleQA.add("TrackQA/After/Deuteron/fDcaXy", "DCA_{xy};p_{T} (GeV/c); DCA_{XY};Entries", HistType::kTH2F, {Binning.momentum, Binning.dca}); + registryParticleQA.add("TrackQA/After/Deuteron/fDcaZ", "DCA_{z};p_{T} (GeV/c); DCA_{Z};Entries", HistType::kTH2F, {Binning.momentum, Binning.dca}); + + registryParticleQA.add("TrackQA/After/Deuteron/fTpcClusters", "TPC Clusters;TPC Clusters;Entries", HistType::kTH1F, {Binning.tpcCluster}); + registryParticleQA.add("TrackQA/After/Deuteron/fTpcCrossedRows", "TPC Crossed Rows;TPC Crossed Rows;Entries", HistType::kTH1F, {Binning.tpcCluster}); + registryParticleQA.add("TrackQA/After/Deuteron/fTpcSharedClusters", "TPC Shared Clusters;TPC Shared Clusters;Entries", HistType::kTH1F, {Binning.tpcCluster}); + registryParticleQA.add("TrackQA/After/Deuteron/fTpcSharedClusterOverClusterss", "TPC Shared Clusters/Clusters;TPC Shared Clusters/Clusters;Entries", HistType::kTH1F, {Binning.ratio}); + registryParticleQA.add("TrackQA/After/Deuteron/fTpcFindableOverRows", "TPC Findabled/Crossed Rows;TPC Findable/CrossedRows;Entries", HistType::kTH1F, {Binning.ratio}); + registryParticleQA.add("TrackQA/After/Deuteron/fTpcChi2OverCluster", "TPC #chi^{2}/Cluster;TPC #chi^{2}/Cluster;Entries", HistType::kTH1F, {Binning.tpcChi2}); + + registryParticleQA.add("TrackQA/After/Deuteron/fItsClusters", "ITS Clusters;ITS Clusters;Entries", HistType::kTH1F, {Binning.itsCluster}); + registryParticleQA.add("TrackQA/After/Deuteron/fItsIbClusters", "ITS Inner Barrel Clusters;ITS Inner Barrel Clusters;Entries", HistType::kTH1F, {Binning.itsIbCluster}); + registryParticleQA.add("TrackQA/After/Deuteron/fItsChi2OverCluster", "ITS #chi^{2}/Cluster;ITS #chi^{2}/Cluster;Entries", HistType::kTH1F, {Binning.itsChi2}); + + // AntiDeuteron + registryParticleQA.add("TrackQA/After/AntiDeuteron/fPt", "Transverse Momentum;p_{T} (GeV/c);Entries", HistType::kTH1F, {Binning.momentum}); + registryParticleQA.add("TrackQA/After/AntiDeuteron/fPTpc", "Momentum at TPC inner wall;p_{TPC} (GeV/c);Entries", HistType::kTH1F, {Binning.momentum}); + registryParticleQA.add("TrackQA/After/AntiDeuteron/fMomCor", "Momentum correlation;p_{reco} (GeV/c); p_{TPC} - p_{reco} / p_{reco}", {HistType::kTH2F, {Binning.momentum, Binning.momCor}}); + registryParticleQA.add("TrackQA/After/AntiDeuteron/fEta", "Pseudorapidity;#eta;Entries", HistType::kTH1F, {Binning.eta}); + registryParticleQA.add("TrackQA/After/AntiDeuteron/fPhi", "Azimuthal angle;#varphi;Entries", HistType::kTH1F, {Binning.phi}); + + registryParticleQA.add("TrackQA/After/AntiDeuteron/fNsigmaIts", "NSigmaITS;p (GeV/c);n#sigma_{ITS}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); + registryParticleQA.add("TrackQA/After/AntiDeuteron/fNsigmaTpc", "NSigmaTPC;p (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); + registryParticleQA.add("TrackQA/After/AntiDeuteron/fNsigmaTof", "NSigmaTOF;p (GeV/c);n#sigma_{TOF}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); + registryParticleQA.add("TrackQA/After/AntiDeuteron/fNsigmaTpcTof", "NSigmaTPCTOF;p (GeV/c);n#sigma_{comb}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); + + registryParticleQA.add("TrackQA/After/AntiDeuteron/fItsSignal", "ITS Signal;p (GeV/c); (cm)", {HistType::kTH2F, {Binning.momentum, Binning.itsSignal}}); + registryParticleQA.add("TrackQA/After/AntiDeuteron/fTpcSignal", "TPC Signal;p (GeV/c);TPC Signal", {HistType::kTH2F, {Binning.momentum, Binning.tpcSignal}}); + registryParticleQA.add("TrackQA/After/AntiDeuteron/fTofBeta", "TOF #beta;p (GeV/c);#beta_{TOF}", {HistType::kTH2F, {Binning.momentum, Binning.tofSignal}}); + + registryParticleQA.add("TrackQA/After/AntiDeuteron/fDcaXy", "DCA_{xy};p_{T} (GeV/c); DCA_{XY};Entries", HistType::kTH2F, {Binning.momentum, Binning.dca}); + registryParticleQA.add("TrackQA/After/AntiDeuteron/fDcaZ", "DCA_{z};p_{T} (GeV/c); DCA_{Z};Entries", HistType::kTH2F, {Binning.momentum, Binning.dca}); + + registryParticleQA.add("TrackQA/After/AntiDeuteron/fTpcClusters", "TPC Clusters;TPC Clusters;Entries", HistType::kTH1F, {Binning.tpcCluster}); + registryParticleQA.add("TrackQA/After/AntiDeuteron/fTpcCrossedRows", "TPC Crossed Rows;TPC Crossed Rows;Entries", HistType::kTH1F, {Binning.tpcCluster}); + registryParticleQA.add("TrackQA/After/AntiDeuteron/fTpcSharedClusters", "TPC Shared Clusters;TPC Shared Clusters;Entries", HistType::kTH1F, {Binning.tpcCluster}); + registryParticleQA.add("TrackQA/After/AntiDeuteron/fTpcSharedClusterOverClusterss", "TPC Shared Clusters/Clusters;TPC Shared Clusters/Clusters;Entries", HistType::kTH1F, {Binning.ratio}); + registryParticleQA.add("TrackQA/After/AntiDeuteron/fTpcFindableOverRows", "TPC Findabled/Crossed Rows;TPC Findable/CrossedRows;Entries", HistType::kTH1F, {Binning.ratio}); + registryParticleQA.add("TrackQA/After/AntiDeuteron/fTpcChi2OverCluster", "TPC #chi^{2}/Cluster;TPC #chi^{2}/Cluster;Entries", HistType::kTH1F, {Binning.tpcChi2}); + + registryParticleQA.add("TrackQA/After/AntiDeuteron/fItsClusters", "ITS Clusters;ITS Clusters;Entries", HistType::kTH1F, {Binning.itsCluster}); + registryParticleQA.add("TrackQA/After/AntiDeuteron/fItsIbClusters", "ITS Inner Barrel Clusters;ITS Inner Barrel Clusters;Entries", HistType::kTH1F, {Binning.itsIbCluster}); + registryParticleQA.add("TrackQA/After/AntiDeuteron/fItsChi2OverCluster", "ITS #chi^{2}/Cluster;ITS #chi^{2}/Cluster;Entries", HistType::kTH1F, {Binning.itsChi2}); + + // Lambda before + registryParticleQA.add("LambdaQA/Before/fPt", "Transverse momentum;p_{T} (GeV/c);Entries", HistType::kTH1F, {Binning.momentum}); + registryParticleQA.add("LambdaQA/Before/fEta", "Psedurapidity;#eta;Entries", HistType::kTH1F, {Binning.eta}); + registryParticleQA.add("LambdaQA/Before/fPhi", "Azimuthal Angle;#varphi;Entries", HistType::kTH1F, {Binning.phi}); + registryParticleQA.add("LambdaQA/Before/fInvMassLambda", "Invariant mass Lambda;M_{#pi p};Entries", HistType::kTH1F, {Binning.invMassLambda}); + registryParticleQA.add("LambdaQA/Before/fInvMassAntiLambda", "Invariant mass AntiLambda;M_{#pi p};Entries", HistType::kTH1F, {Binning.invMassLambda}); + registryParticleQA.add("LambdaQA/Before/fInvMassLambdaVsAntiLambda", "Invariant mass of Lambda vs AntiLambda;M_{#pi p};Entries", HistType::kTH2F, {Binning.invMassLambda, Binning.invMassLambda}); + registryParticleQA.add("LambdaQA/Before/fInvMassLambdaVsKaon", "Invariant mass of Lambda vs K0;M_{#pi p};;M_{#pi #pi}", HistType::kTH2F, {Binning.invMassLambda, Binning.invMassK0short}); + registryParticleQA.add("LambdaQA/Before/fInvMassAntiLambdaVsKaon", "Invariant mass of AntiLambda vs K0;M_{#pi p};;M_{#pi #pi}", HistType::kTH2F, {Binning.invMassLambda, Binning.invMassK0short}); + registryParticleQA.add("LambdaQA/Before/fDcaDaugh", "DCA_{Daugh};DCA_{daugh};Entries", HistType::kTH1F, {Binning.dcaDaugh}); + registryParticleQA.add("LambdaQA/Before/fCpa", "Cosine of pointing angle;CPA;Entries", HistType::kTH1F, {Binning.cpa}); + registryParticleQA.add("LambdaQA/Before/fTranRad", "Transverse Radisu;TranRad;Entries", HistType::kTH1F, {Binning.transRad}); + registryParticleQA.add("LambdaQA/Before/fDecVtx", "Decay vertex displacement;DecVtx;Entries", HistType::kTH1F, {Binning.decayVtx}); + registryParticleQA.add("LambdaQA/Before/PosDaughter/fPt", "Transverse Momentum;p_{T} (GeV/c);Entries", HistType::kTH1F, {Binning.momentum}); + registryParticleQA.add("LambdaQA/Before/PosDaughter/fEta", "Pseudorapidity;#eta;Entries", HistType::kTH1F, {Binning.eta}); + registryParticleQA.add("LambdaQA/Before/PosDaughter/fPhi", "Azimuthal Angle;#varphi;Entries", HistType::kTH1F, {Binning.phi}); + registryParticleQA.add("LambdaQA/Before/PosDaughter/fDcaXy", "DCA_{XY};p_{T} (GeV/c); DCA_{XY};Entries", HistType::kTH2F, {Binning.momentum, Binning.dca}); + registryParticleQA.add("LambdaQA/Before/PosDaughter/fTpcClusters", "TPC Clusters;TPC Clusters;Entries", HistType::kTH1F, {Binning.tpcCluster}); + registryParticleQA.add("LambdaQA/Before/PosDaughter/fNsigmaTpcProton", "NSigmaTPC Proton;p_{TPC} (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); + registryParticleQA.add("LambdaQA/Before/PosDaughter/fNsigmaTpcPion", "NSigmaTPC Pion;p_{TPC} (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); + registryParticleQA.add("LambdaQA/Before/NegDaughter/fPt", "Transverse Momentum;p_{T} (GeV/c);Entries", HistType::kTH1F, {Binning.momentum}); + registryParticleQA.add("LambdaQA/Before/NegDaughter/fEta", "Pseudorapidity;#eta;Entries", HistType::kTH1F, {Binning.eta}); + registryParticleQA.add("LambdaQA/Before/NegDaughter/fPhi", "Azimuthal Angle;#varphi;Entries", HistType::kTH1F, {Binning.phi}); + registryParticleQA.add("LambdaQA/Before/NegDaughter/fDcaXy", "DCA_{XY};p_{T} (GeV/c); DCA_{XY};Entries", HistType::kTH2F, {Binning.momentum, Binning.dca}); + registryParticleQA.add("LambdaQA/Before/NegDaughter/fTpcClusters", "TPC Clusters;TPC Clusters;Entries", HistType::kTH1F, {Binning.tpcCluster}); + registryParticleQA.add("LambdaQA/Before/NegDaughter/fNsigmaTpcProton", "NSigmaTPC AnitProton;p_{TPC} (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); + registryParticleQA.add("LambdaQA/Before/NegDaughter/fNsigmaTpcPion", "NSigmaTPC AntiPion;p_{TPC} (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); + + // Lambda after + registryParticleQA.add("LambdaQA/After/Lambda/fPt", "Transverse momentum;p_{T} (GeV/c);Entries", HistType::kTH1F, {Binning.momentum}); + registryParticleQA.add("LambdaQA/After/Lambda/fEta", "Psedurapidity;#eta;Entries", HistType::kTH1F, {Binning.eta}); + registryParticleQA.add("LambdaQA/After/Lambda/fPhi", "Azimuthal Angle;#varphi;Entries", HistType::kTH1F, {Binning.phi}); + registryParticleQA.add("LambdaQA/After/Lambda/fInvMass", "Invariant mass;M_{#pi p};Entries", HistType::kTH1F, {Binning.invMassLambda}); + registryParticleQA.add("LambdaQA/After/Lambda/fInvMassLambdaVsAntiLambda", "Invariant mass of Lambda vs AntiLambda;M_{#pi p};Entries", HistType::kTH2F, {Binning.invMassLambda, Binning.invMassLambda}); + registryParticleQA.add("LambdaQA/After/Lambda/fInvMassLambdaVsKaon", "Invariant mass of rejected K0 vs V0s;M_{#pi p};;M_{#pi #pi}", HistType::kTH2F, {Binning.invMassLambda, Binning.invMassK0short}); + registryParticleQA.add("LambdaQA/After/Lambda/fDcaDaugh", "DCA_{Daugh};DCA_{daugh};Entries", HistType::kTH1F, {Binning.dcaDaugh}); + registryParticleQA.add("LambdaQA/After/Lambda/fCpa", "Cosine of pointing angle;CPA;Entries", HistType::kTH1F, {Binning.cpa}); + registryParticleQA.add("LambdaQA/After/Lambda/fTranRad", "Transverse Radisu;TranRad;Entries", HistType::kTH1F, {Binning.transRad}); + registryParticleQA.add("LambdaQA/After/Lambda/fDecVtx", "Decay vertex displacement;DecVtx;Entries", HistType::kTH1F, {Binning.decayVtx}); + registryParticleQA.add("LambdaQA/After/Lambda/PosDaughter/fPt", "Transverse Momentum;p_{T} (GeV/c);Entries", HistType::kTH1F, {Binning.momentum}); + registryParticleQA.add("LambdaQA/After/Lambda/PosDaughter/fEta", "Pseudorapidity;#eta;Entries", HistType::kTH1F, {Binning.eta}); + registryParticleQA.add("LambdaQA/After/Lambda/PosDaughter/fPhi", "Azimuthal Angle;#varphi;Entries", HistType::kTH1F, {Binning.phi}); + registryParticleQA.add("LambdaQA/After/Lambda/PosDaughter/fDcaXy", "DCA_{XY};p_{T} (GeV/c); DCA_{XY};Entries", HistType::kTH2F, {Binning.momentum, Binning.dca}); + registryParticleQA.add("LambdaQA/After/Lambda/PosDaughter/fTpcClusters", "TPC Clusters;TPC Clusters;Entries", HistType::kTH1F, {Binning.tpcCluster}); + registryParticleQA.add("LambdaQA/After/Lambda/PosDaughter/fNsigmaTpc", "NSigmaTPC Proton;p_{TPC} (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); + registryParticleQA.add("LambdaQA/After/Lambda/NegDaughter/fPt", "Transverse Momentum;p_{T} (GeV/c);Entries", HistType::kTH1F, {Binning.momentum}); + registryParticleQA.add("LambdaQA/After/Lambda/NegDaughter/fEta", "Pseudorapidity;#eta;Entries", HistType::kTH1F, {Binning.eta}); + registryParticleQA.add("LambdaQA/After/Lambda/NegDaughter/fPhi", "Azimuthal Angle;#varphi;Entries", HistType::kTH1F, {Binning.phi}); + registryParticleQA.add("LambdaQA/After/Lambda/NegDaughter/fDcaXy", "DCA_{XY};p_{T} (GeV/c); DCA_{XY};Entries", HistType::kTH2F, {Binning.momentum, Binning.dca}); + registryParticleQA.add("LambdaQA/After/Lambda/NegDaughter/fTpcClusters", "TPC Clusters;TPC Clusters;Entries", HistType::kTH1F, {Binning.tpcCluster}); + registryParticleQA.add("LambdaQA/After/Lambda/NegDaughter/fNsigmaTpc", "NSigmaTPC AntiPion;p_{TPC} (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); + + // AntiLambda after + registryParticleQA.add("LambdaQA/After/AntiLambda/fPt", "Transverse momentum;p_{T} (GeV/c);Entries", HistType::kTH1F, {Binning.momentum}); + registryParticleQA.add("LambdaQA/After/AntiLambda/fEta", "Psedurapidity;#eta;Entries", HistType::kTH1F, {Binning.eta}); + registryParticleQA.add("LambdaQA/After/AntiLambda/fPhi", "Azimuthal Angle;#varphi;Entries", HistType::kTH1F, {Binning.phi}); + registryParticleQA.add("LambdaQA/After/AntiLambda/fInvMass", "Invariant mass;M_{#pi p};Entries", HistType::kTH1F, {Binning.invMassLambda}); + registryParticleQA.add("LambdaQA/After/AntiLambda/fInvMassAntiLambdaVsLambda", "Invariant mass of Lambda vs AntiLambda;M_{#pi p};Entries", HistType::kTH2F, {Binning.invMassLambda, Binning.invMassLambda}); + registryParticleQA.add("LambdaQA/After/AntiLambda/fInvMassAntiLambdaVsKaon", "Invariant mass of rejected K0 vs V0s;M_{#pi p};;M_{#pi #pi}", HistType::kTH2F, {Binning.invMassLambda, Binning.invMassK0short}); + registryParticleQA.add("LambdaQA/After/AntiLambda/fDcaDaugh", "DCA_{Daugh};DCA_{daugh};Entries", HistType::kTH1F, {Binning.dcaDaugh}); + registryParticleQA.add("LambdaQA/After/AntiLambda/fCpa", "Cosine of pointing angle;CPA;Entries", HistType::kTH1F, {Binning.cpa}); + registryParticleQA.add("LambdaQA/After/AntiLambda/fTranRad", "Transverse Radisu;TranRad;Entries", HistType::kTH1F, {Binning.transRad}); + registryParticleQA.add("LambdaQA/After/AntiLambda/fDecVtx", "Decay vertex displacement;DecVtx;Entries", HistType::kTH1F, {Binning.decayVtx}); + registryParticleQA.add("LambdaQA/After/AntiLambda/PosDaughter/fPt", "Transverse Momentum;p_{T} (GeV/c);Entries", HistType::kTH1F, {Binning.momentum}); + registryParticleQA.add("LambdaQA/After/AntiLambda/PosDaughter/fEta", "Pseudorapidity;#eta;Entries", HistType::kTH1F, {Binning.eta}); + registryParticleQA.add("LambdaQA/After/AntiLambda/PosDaughter/fPhi", "Azimuthal Angle;#varphi;Entries", HistType::kTH1F, {Binning.phi}); + registryParticleQA.add("LambdaQA/After/AntiLambda/PosDaughter/fDcaXy", "DCA_{XY};p_{T} (GeV/c); DCA_{XY};Entries", HistType::kTH2F, {Binning.momentum, Binning.dca}); + registryParticleQA.add("LambdaQA/After/AntiLambda/PosDaughter/fTpcClusters", "TPC Clusters;TPC Clusters;Entries", HistType::kTH1F, {Binning.tpcCluster}); + registryParticleQA.add("LambdaQA/After/AntiLambda/PosDaughter/fNsigmaTpc", "NSigmaTPC Proton;p_{TPC} (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); + registryParticleQA.add("LambdaQA/After/AntiLambda/NegDaughter/fPt", "Transverse Momentum;p_{T} (GeV/c);Entries", HistType::kTH1F, {Binning.momentum}); + registryParticleQA.add("LambdaQA/After/AntiLambda/NegDaughter/fEta", "Pseudorapidity;#eta;Entries", HistType::kTH1F, {Binning.eta}); + registryParticleQA.add("LambdaQA/After/AntiLambda/NegDaughter/fPhi", "Azimuthal Angle;#varphi;Entries", HistType::kTH1F, {Binning.phi}); + registryParticleQA.add("LambdaQA/After/AntiLambda/NegDaughter/fDcaXy", "DCA_{XY};p_{T} (GeV/c); DCA_{XY};Entries", HistType::kTH2F, {Binning.momentum, Binning.dca}); + registryParticleQA.add("LambdaQA/After/AntiLambda/NegDaughter/fTpcClusters", "TPC Clusters;TPC Clusters;Entries", HistType::kTH1F, {Binning.tpcCluster}); + registryParticleQA.add("LambdaQA/After/AntiLambda/NegDaughter/fNsigmaTpc", "NSigmaTPC AntiPion;p_{TPC} (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); + + // Phi before + registryParticleQA.add("PhiQA/Before/fInvMass", "Invariant mass #phi;M_{KK};Entries", HistType::kTH1F, {Binning.invMassPhi}); + registryParticleQA.add("PhiQA/Before/fPt", "Transverse momentum #phi;p_{T} (GeV/c);Entries", HistType::kTH1F, {Binning.momentum}); + registryParticleQA.add("PhiQA/Before/fEta", "Pseudorapidity of V0;#eta;Entries", HistType::kTH1F, {Binning.eta}); + registryParticleQA.add("PhiQA/Before/fPhi", "Azimuthal angle of #phi;#varphi;Entries", HistType::kTH1F, {Binning.phi}); + + // Phi after + registryParticleQA.add("PhiQA/After/fInvMass", "Invariant mass #phi;M_{KK};Entries", HistType::kTH1F, {Binning.invMassPhi}); + registryParticleQA.add("PhiQA/After/fPt", "Transverse momentum #phi;p_{T} (GeV/c);Entries", HistType::kTH1F, {Binning.momentum}); + registryParticleQA.add("PhiQA/After/fEta", "Pseudorapidity of #phi;#eta;Entries", HistType::kTH1F, {Binning.eta}); + registryParticleQA.add("PhiQA/After/fPhi", "Azimuthal angle of #Phi;#varphi;Entries", HistType::kTH1F, {Binning.phi}); + + // Rho before + registryParticleQA.add("RhoQA/Before/fInvMass", "Invariant mass #rho;M_{#pi#pi};Entries", HistType::kTH1F, {Binning.invMassRho}); + registryParticleQA.add("RhoQA/Before/fPt", "Transverse momentum #rho;p_{T} (GeV/c);Entries", HistType::kTH1F, {Binning.momentum}); + registryParticleQA.add("RhoQA/Before/fEta", "Pseudorapidity of #rho;#eta;Entries", HistType::kTH1F, {Binning.eta}); + registryParticleQA.add("RhoQA/Before/fPhi", "Azimuthal angle of #rho;#varphi;Entries", HistType::kTH1F, {Binning.phi}); + + // Rho after + registryParticleQA.add("RhoQA/After/fInvMass", "Invariant mass #rho;M_{#pi#pi};Entries", HistType::kTH1F, {Binning.invMassRho}); + registryParticleQA.add("RhoQA/After/fPt", "Transverse momentum #rho;p_{T} (GeV/c);Entries", HistType::kTH1F, {Binning.momentum}); + registryParticleQA.add("RhoQA/After/fEta", "Pseudorapidity of #rho;#eta;Entries", HistType::kTH1F, {Binning.eta}); + registryParticleQA.add("RhoQA/After/fPhi", "Azimuthal angle of #rho;#phi;Entries", HistType::kTH1F, {Binning.phi}); // for ppp - registry.add("ppp/fMultiplicity", "Multiplicity of all processed events;Mult;Entries", HistType::kTH1F, {{500, 0, 500}}); - registry.add("ppp/fZvtx", "Zvtx of all processed events;Z_{vtx};Entries", HistType::kTH1F, {{500, -15, 15}}); - registry.add("ppp/fSE_particle", "Same Event distribution", HistType::kTH1F, {{8000, 0, 8}}); - registry.add("ppp/fSE_particle_downsample", "Same Event distribution (downsampled)", HistType::kTH1F, {{8000, 0, 8}}); - registry.add("ppp/fSE_antiparticle", "Same Event distribution", HistType::kTH1F, {{8000, 0, 8}}); - registry.add("ppp/fSE_antiparticle_downsample", "Same Event distribution (downsampled)", HistType::kTH1F, {{8000, 0, 8}}); - registry.add("ppp/fProtonPtVsQ3", "pT (proton) vs Q_{3};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {{150, 0, 1.5}, {500, 0, 10}}}); - registry.add("ppp/fAntiProtonPtVsQ3", "pT (antiproton) vs Q_{3};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {{150, 0, 1.5}, {500, 0, 10}}}); + registryTriggerQA.add("PPP/all/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); + registryTriggerQA.add("PPP/all/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); + registryTriggerQA.add("PPP/all/fSE_particle", "Same Event distribution;Q_{3} (GeV/c);Entries", HistType::kTH1F, {Binning.q3}); + registryTriggerQA.add("PPP/all/fSE_antiparticle", "Same Event distribution;Q_{3} (GeV/c);Entries", HistType::kTH1F, {Binning.q3}); + registryTriggerQA.add("PPP/all/fProtonPtVsQ3", "Proton p_{T} vs Q_{3};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); + registryTriggerQA.add("PPP/all/fAntiProtonPtVsQ3", "AntiProton p_{T} vs Q_{3};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); + registryTriggerQA.add("PPP/loose/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); + registryTriggerQA.add("PPP/loose/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); + registryTriggerQA.add("PPP/loose/fSE_particle", "Same Event distribution;Q_{3} (GeV/c);Entries", HistType::kTH1F, {Binning.q3}); + registryTriggerQA.add("PPP/loose/fSE_antiparticle", "Same Event distribution;Q_{3} (GeV/c);Entries", HistType::kTH1F, {Binning.q3}); + registryTriggerQA.add("PPP/loose/fProtonPtVsQ3", "Proton p_{T} vs Q_{3};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); + registryTriggerQA.add("PPP/loose/fAntiProtonPtVsQ3", "AntiProton p_{T} vs Q_{3};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); + registryTriggerQA.add("PPP/tight/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); + registryTriggerQA.add("PPP/tight/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); + registryTriggerQA.add("PPP/tight/fSE_particle", "Same Event distribution;Q_{3} (GeV/c);Entries", HistType::kTH1F, {Binning.q3}); + registryTriggerQA.add("PPP/tight/fSE_antiparticle", "Same Event distribution;Q_{3} (GeV/c);Entries", HistType::kTH1F, {Binning.q3}); + registryTriggerQA.add("PPP/tight/fProtonPtVsQ3", "Proton p_{T} vs Q_{3};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); + registryTriggerQA.add("PPP/tight/fAntiProtonPtVsQ3", "AntiProton p_{T} vs Q_{3};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); // for ppl - registry.add("ppl/fMultiplicity", "Multiplicity of all processed events;Mult;Entries", HistType::kTH1F, {{500, 0, 500}}); - registry.add("ppl/fZvtx", "Zvtx of all processed events;Z_{vtx};Entries", HistType::kTH1F, {{500, -15, 15}}); - registry.add("ppl/fSE_particle", "Same Event distribution;SE;Q_{3} (GeV/c)", HistType::kTH1F, {{8000, 0, 8}}); - registry.add("ppl/fSE_particle_downsample", "Same Event distribution;SE;Q_{3} (GeV/c)", HistType::kTH1F, {{8000, 0, 8}}); - registry.add("ppl/fSE_antiparticle", "Same Event distribution;SE;Q_{3} (GeV/c)", HistType::kTH1F, {{8000, 0, 8}}); - registry.add("ppl/fSE_antiparticle_downsample", "Same Event distribution;SE;Q_{3} (GeV/c)", HistType::kTH1F, {{8000, 0, 8}}); - registry.add("ppl/fProtonPtVsQ3", "pT (proton) vs Q_{3};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {{150, 0, 1.5}, {500, 0, 10}}}); - registry.add("ppl/fAntiProtonPtVsQ3", "pT (proton) vs Q_{3};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {{150, 0, 1.5}, {500, 0, 10}}}); - registry.add("ppl/fLambdaPtVsQ3", "pT (lambda) vs Q_{3};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {{150, 0, 1.5}, {500, 0, 10}}}); - registry.add("ppl/fAntiLambdaPtVsQ3", "pT (antilambda) vs Q_{3};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {{150, 0, 1.5}, {500, 0, 10}}}); + registryTriggerQA.add("PPL/all/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); + registryTriggerQA.add("PPL/all/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); + registryTriggerQA.add("PPL/all/fSE_particle", "Same Event distribution;Q_{3} (GeV/c);Entries", HistType::kTH1F, {Binning.q3}); + registryTriggerQA.add("PPL/all/fSE_antiparticle", "Same Event distribution;Q_{3} (GeV/c);Entries", HistType::kTH1F, {Binning.q3}); + registryTriggerQA.add("PPL/all/fProtonPtVsQ3", "Proton p_{T} vs Q_{3};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); + registryTriggerQA.add("PPL/all/fAntiProtonPtVsQ3", "AntiProton p_{T} vs Q_{3};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); + registryTriggerQA.add("PPL/all/fLambdaPtVsQ3", "Lambda p_{T} vs Q_{3};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); + registryTriggerQA.add("PPL/all/fAntiLambdaPtVsQ3", "AntiLambda p_{T} vs Q_{3};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); + registryTriggerQA.add("PPL/loose/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); + registryTriggerQA.add("PPL/loose/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); + registryTriggerQA.add("PPL/loose/fSE_particle", "Same Event distribution;Q_{3} (GeV/c);Entries", HistType::kTH1F, {Binning.q3}); + registryTriggerQA.add("PPL/loose/fSE_antiparticle", "Same Event distribution;Q_{3} (GeV/c);Entries", HistType::kTH1F, {Binning.q3}); + registryTriggerQA.add("PPL/loose/fProtonPtVsQ3", "Proton p_{T} vs Q_{3};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); + registryTriggerQA.add("PPL/loose/fAntiProtonPtVsQ3", "AntiProton p_{T} vs Q_{3};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); + registryTriggerQA.add("PPL/loose/fLambdaPtVsQ3", "Lambda p_{T} vs Q_{3};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); + registryTriggerQA.add("PPL/loose/fAntiLambdaPtVsQ3", "AntiLambda p_{T} vs Q_{3};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); + registryTriggerQA.add("PPL/tight/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); + registryTriggerQA.add("PPL/tight/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); + registryTriggerQA.add("PPL/tight/fSE_particle", "Same Event distribution;Q_{3} (GeV/c);Entries", HistType::kTH1F, {Binning.q3}); + registryTriggerQA.add("PPL/tight/fSE_antiparticle", "Same Event distribution;Q_{3} (GeV/c);Entries", HistType::kTH1F, {Binning.q3}); + registryTriggerQA.add("PPL/tight/fProtonPtVsQ3", "Proton p_{T} vs Q_{3};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); + registryTriggerQA.add("PPL/tight/fAntiProtonPtVsQ3", "AntiProton p_{T} vs Q_{3};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); + registryTriggerQA.add("PPL/tight/fLambdaPtVsQ3", "Lambda p_{T} vs Q_{3};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); + registryTriggerQA.add("PPL/tight/fAntiLambdaPtVsQ3", "AntiLambda p_{T} vs Q_{3};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); // for pll - registry.add("pll/fMultiplicity", "Multiplicity of all processed events;Mult;Entries", HistType::kTH1F, {{500, 0, 500}}); - registry.add("pll/fZvtx", "Zvtx of all processed events;Z_{vtx};Entries", HistType::kTH1F, {{500, -15, 15}}); - registry.add("pll/fSE_particle", "Same Event distribution;SE;Q_{3} (GeV/c)", HistType::kTH1F, {{8000, 0, 8}}); - registry.add("pll/fSE_particle_downsample", "Same Event distribution;SE;Q_{3} (GeV/c)", HistType::kTH1F, {{8000, 0, 8}}); - registry.add("pll/fSE_antiparticle", "Same Event distribution;SE;Q_{3} (GeV/c)", HistType::kTH1F, {{8000, 0, 8}}); - registry.add("pll/fSE_antiparticle_downsample", "Same Event distribution;SE;Q_{3} (GeV/c)", HistType::kTH1F, {{8000, 0, 8}}); - registry.add("pll/fProtonPtVsQ3", "Q3 vs pT (proton)", {HistType::kTH2F, {{150, 0, 1.5}, {500, 0, 10}}}); - registry.add("pll/fAntiProtonPtVsQ3", "Q3 vs pT (antiproton)", {HistType::kTH2F, {{150, 0, 1.5}, {500, 0, 10}}}); - registry.add("pll/fLambdaPtVsQ3", "Q3 vs pT (lambda)", {HistType::kTH2F, {{150, 0, 1.5}, {500, 0, 10}}}); - registry.add("pll/fAntiLambdaPtVsQ3", "Q3 vs pT (antilambda)", {HistType::kTH2F, {{150, 0, 1.5}, {500, 0, 10}}}); + registryTriggerQA.add("PLL/all/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); + registryTriggerQA.add("PLL/all/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); + registryTriggerQA.add("PLL/all/fSE_particle", "Same Event distribution;Q_{3} (GeV/c);SE", HistType::kTH1F, {Binning.q3}); + registryTriggerQA.add("PLL/all/fSE_antiparticle", "Same Event distribution;Q_{3} (GeV/c);SE", HistType::kTH1F, {Binning.q3}); + registryTriggerQA.add("PLL/all/fProtonPtVsQ3", "Proton p_{T}Q3 vs pT", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); + registryTriggerQA.add("PLL/all/fAntiProtonPtVsQ3", "AntiProton p_{T} vs Q3", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); + registryTriggerQA.add("PLL/all/fLambdaPtVsQ3", "Lambda p_{T} vs Q3", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); + registryTriggerQA.add("PLL/all/fAntiLambdaPtVsQ3", "AntiLambda p_{T} vs Q3", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); + registryTriggerQA.add("PLL/loose/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); + registryTriggerQA.add("PLL/loose/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); + registryTriggerQA.add("PLL/loose/fSE_particle", "Same Event distribution;Q_{3} (GeV/c);SE", HistType::kTH1F, {Binning.q3}); + registryTriggerQA.add("PLL/loose/fSE_antiparticle", "Same Event distribution;Q_{3} (GeV/c);SE", HistType::kTH1F, {Binning.q3}); + registryTriggerQA.add("PLL/loose/fProtonPtVsQ3", "Proton p_{T}Q3 vs pT", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); + registryTriggerQA.add("PLL/loose/fAntiProtonPtVsQ3", "AntiProton p_{T} vs Q3", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); + registryTriggerQA.add("PLL/loose/fLambdaPtVsQ3", "Lambda p_{T} vs Q3", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); + registryTriggerQA.add("PLL/loose/fAntiLambdaPtVsQ3", "AntiLambda p_{T} vs Q3", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); + registryTriggerQA.add("PLL/tight/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); + registryTriggerQA.add("PLL/tight/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); + registryTriggerQA.add("PLL/tight/fSE_particle", "Same Event distribution;Q_{3} (GeV/c);SE", HistType::kTH1F, {Binning.q3}); + registryTriggerQA.add("PLL/tight/fSE_antiparticle", "Same Event distribution;Q_{3} (GeV/c);SE", HistType::kTH1F, {Binning.q3}); + registryTriggerQA.add("PLL/tight/fProtonPtVsQ3", "Proton p_{T}Q3 vs pT", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); + registryTriggerQA.add("PLL/tight/fAntiProtonPtVsQ3", "AntiProton p_{T} vs Q3", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); + registryTriggerQA.add("PLL/tight/fLambdaPtVsQ3", "Lambda p_{T} vs Q3", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); + registryTriggerQA.add("PLL/tight/fAntiLambdaPtVsQ3", "AntiLambda p_{T} vs Q3", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); // for lll - registry.add("lll/fMultiplicity", "Multiplicity of all processed events;Mult;Entries", HistType::kTH1F, {{500, 0, 500}}); - registry.add("lll/fZvtx", "Zvtx of all processed events;Z_{vtx};Entries", HistType::kTH1F, {{500, -15, 15}}); - registry.add("lll/fSE_particle", "Same Event distribution;SE;Q_{3} (GeV/c)", HistType::kTH1F, {{8000, 0, 8}}); - registry.add("lll/fSE_particle_downsample", "Same Event distribution;SE;Q_{3} (GeV/c)", HistType::kTH1F, {{8000, 0, 8}}); - registry.add("lll/fSE_antiparticle", "Same Event distribution;SE;Q_{3} (GeV/c)", HistType::kTH1F, {{8000, 0, 8}}); - registry.add("lll/fSE_antiparticle_downsample", "Same Event distribution;SE;Q_{3} (GeV/c)", HistType::kTH1F, {{8000, 0, 8}}); - registry.add("lll/fLambdaPtVsQ3", "Q3 vs pT (lambda)", {HistType::kTH2F, {{150, 0, 1.5}, {500, 0, 10}}}); - registry.add("lll/fAntiLambdaPtVsQ3", "Q3 vs pT (antilambda)", {HistType::kTH2F, {{150, 0, 1.5}, {500, 0, 10}}}); + registryTriggerQA.add("LLL/all/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); + registryTriggerQA.add("LLL/all/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); + registryTriggerQA.add("LLL/all/fSE_particle", "Same Event distribution;Q_{3} (GeV/c);Entries", HistType::kTH1F, {Binning.q3}); + registryTriggerQA.add("LLL/all/fSE_antiparticle", "Same Event distribution;Q_{3} (GeV/c);Entries", HistType::kTH1F, {Binning.q3}); + registryTriggerQA.add("LLL/all/fLambdaPtVsQ3", "Lambda p_{T} vs Q3", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); + registryTriggerQA.add("LLL/all/fAntiLambdaPtVsQ3", "AntiLambda p_{T} vs Q3", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); + registryTriggerQA.add("LLL/loose/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); + registryTriggerQA.add("LLL/loose/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); + registryTriggerQA.add("LLL/loose/fSE_particle", "Same Event distribution;Q_{3} (GeV/c);Entries", HistType::kTH1F, {Binning.q3}); + registryTriggerQA.add("LLL/loose/fSE_antiparticle", "Same Event distribution;Q_{3} (GeV/c);Entries", HistType::kTH1F, {Binning.q3}); + registryTriggerQA.add("LLL/loose/fLambdaPtVsQ3", "Lambda p_{T} vs Q3", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); + registryTriggerQA.add("LLL/loose/fAntiLambdaPtVsQ3", "AntiLambda p_{T} vs Q3", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); + registryTriggerQA.add("LLL/tight/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); + registryTriggerQA.add("LLL/tight/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); + registryTriggerQA.add("LLL/tight/fSE_particle", "Same Event distribution;Q_{3} (GeV/c);Entries", HistType::kTH1F, {Binning.q3}); + registryTriggerQA.add("LLL/tight/fSE_antiparticle", "Same Event distribution;Q_{3} (GeV/c);Entries", HistType::kTH1F, {Binning.q3}); + registryTriggerQA.add("LLL/tight/fLambdaPtVsQ3", "Lambda p_{T} vs Q3", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); + registryTriggerQA.add("LLL/tight/fAntiLambdaPtVsQ3", "AntiLambda p_{T} vs Q3", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); // for ppPhi - registry.add("ppphi/fMultiplicity", "Multiplicity of all triggered events;Mult;Entries", HistType::kTH1F, {{500, 0, 500}}); - registry.add("ppphi/fZvtx", "Zvtx of all triggered events;Z_{vtx};Entries", HistType::kTH1F, {{500, -15, 15}}); - registry.add("ppphi/fSE_particle", "Same Event distribution;SE;Q_{3} (GeV/c)", HistType::kTH1F, {{8000, 0, 8}}); - registry.add("ppphi/fSE_particle_downsample", "Same Event distribution;SE;Q_{3} (GeV/c)", HistType::kTH1F, {{8000, 0, 8}}); - registry.add("ppphi/fSE_antiparticle", "Same Event distribution;SE;Q_{3} (GeV/c)", HistType::kTH1F, {{8000, 0, 8}}); - registry.add("ppphi/fSE_antiparticle_downsample", "Same Event distribution;SE;Q_{3} (GeV/c)", HistType::kTH1F, {{8000, 0, 8}}); - registry.add("ppphi/fProtonPtVsQ3", "Same Event distribution;SE;Q_{3} (GeV/c)", HistType::kTH1F, {{8000, 0, 8}}); - registry.add("ppphi/fPhiPtVsQ3", "Same Event distribution;SE;Q_{3} (GeV/c)", HistType::kTH1F, {{8000, 0, 8}}); - registry.add("ppphi/fAntiProtonPtVsQ3", "Same Event distribution;SE;Q_{3} (GeV/c)", HistType::kTH1F, {{8000, 0, 8}}); - registry.add("ppphi/fAntiPhiPtVsQ3", "Same Event distribution;SE;Q_{3} (GeV/c)", HistType::kTH1F, {{8000, 0, 8}}); + registryTriggerQA.add("PPPhi/all/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); + registryTriggerQA.add("PPPhi/all/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); + registryTriggerQA.add("PPPhi/all/fSE_particle", "Same Event distribution;Q_{3} (GeV/c);Entries", HistType::kTH1F, {Binning.q3}); + registryTriggerQA.add("PPPhi/all/fSE_antiparticle", "Same Event distribution;Q_{3} (GeV/c);Entries", HistType::kTH1F, {Binning.q3}); + registryTriggerQA.add("PPPhi/all/fProtonPtVsQ3", "Proton p_{T} vs Q_{3}", HistType::kTH2F, {Binning.momentum, Binning.q3}); + registryTriggerQA.add("PPPhi/all/fAntiProtonPtVsQ3", "AntiLambda p_{T} vs Q3", HistType::kTH2F, {Binning.momentum, Binning.q3}); + registryTriggerQA.add("PPPhi/all/fPhiPtVsQ3", "#phi p_{T} vs Q_{3};p_{T} (GeV/c); Q_{3} (GeV/c)", HistType::kTH2F, {Binning.momentum, Binning.q3}); + registryTriggerQA.add("PPPhi/all/fPhiInvMassVsQ3", "#phi mass vs Q_{3};M_{K^{+}K^{-}} (GeV/c^{2});Q_{3} (GeV/c)", HistType::kTH2F, {Binning.invMassPhi, Binning.q3}); + registryTriggerQA.add("PPPhi/loose/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); + registryTriggerQA.add("PPPhi/loose/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); + registryTriggerQA.add("PPPhi/loose/fSE_particle", "Same Event distribution;Q_{3} (GeV/c);Entries", HistType::kTH1F, {Binning.q3}); + registryTriggerQA.add("PPPhi/loose/fSE_antiparticle", "Same Event distribution;Q_{3} (GeV/c);Entries", HistType::kTH1F, {Binning.q3}); + registryTriggerQA.add("PPPhi/loose/fProtonPtVsQ3", "Proton p_{T} vs Q_{3}", HistType::kTH2F, {Binning.momentum, Binning.q3}); + registryTriggerQA.add("PPPhi/loose/fAntiProtonPtVsQ3", "AntiLambda p_{T} vs Q3", HistType::kTH2F, {Binning.momentum, Binning.q3}); + registryTriggerQA.add("PPPhi/loose/fPhiPtVsQ3", "#phi p_{T} vs Q_{3};p_{T} (GeV/c); Q_{3} (GeV/c)", HistType::kTH2F, {Binning.momentum, Binning.q3}); + registryTriggerQA.add("PPPhi/loose/fPhiInvMassVsQ3", "#phi mass vs Q_{3};M_{K^{+}K^{-}} (GeV/c^{2});Q_{3} (GeV/c)", HistType::kTH2F, {Binning.invMassPhi, Binning.q3}); + registryTriggerQA.add("PPPhi/tight/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); + registryTriggerQA.add("PPPhi/tight/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); + registryTriggerQA.add("PPPhi/tight/fSE_particle", "Same Event distribution;Q_{3} (GeV/c);Entries", HistType::kTH1F, {Binning.q3}); + registryTriggerQA.add("PPPhi/tight/fSE_antiparticle", "Same Event distribution;Q_{3} (GeV/c);Entries", HistType::kTH1F, {Binning.q3}); + registryTriggerQA.add("PPPhi/tight/fProtonPtVsQ3", "Proton p_{T} vs Q_{3}", HistType::kTH2F, {Binning.momentum, Binning.q3}); + registryTriggerQA.add("PPPhi/tight/fAntiProtonPtVsQ3", "AntiLambda p_{T} vs Q3", HistType::kTH2F, {Binning.momentum, Binning.q3}); + registryTriggerQA.add("PPPhi/tight/fPhiPtVsQ3", "#phi p_{T} vs Q_{3};p_{T} (GeV/c); Q_{3} (GeV/c)", HistType::kTH2F, {Binning.momentum, Binning.q3}); + registryTriggerQA.add("PPPhi/tight/fPhiInvMassVsQ3", "#phi mass vs Q_{3};M_{K^{+}K^{-}} (GeV/c^{2});Q_{3} (GeV/c)", HistType::kTH2F, {Binning.invMassPhi, Binning.q3}); // for ppRho - registry.add("ppRho/fMultiplicity", "Multiplicity of all triggered events;Mult;Entries", HistType::kTH1F, {{500, 0, 500}}); - registry.add("ppRho/fZvtx", "Zvtx of all triggered events;Z_{vtx};Entries", HistType::kTH1F, {{500, -15, 15}}); - registry.add("ppRho/fSE_particle", "Same Event distribution;Q_{3} (GeV/c);SE", HistType::kTH1F, {{8000, 0, 8}}); - registry.add("ppRho/fSE_particle_downsample", "Same Event distribution;Q_{3} (GeV/c);SE", HistType::kTH1F, {{8000, 0, 8}}); - registry.add("ppRho/fSE_antiparticle", "Same Event distribution;Q_{3} (GeV/c);SE", HistType::kTH1F, {{8000, 0, 8}}); - registry.add("ppRho/fSE_antiparticle_downsample", "Same Event distribution;Q_{3} (GeV/c);SE", HistType::kTH1F, {{8000, 0, 8}}); - registry.add("ppRho/fProtonPtVsQ3", "Same Event distribution;Q_{3} (GeV/c);SE", HistType::kTH1F, {{8000, 0, 8}}); - registry.add("ppRho/fAntiProtonPtVsQ3", "Same Event distribution;Q_{3} (GeV/c);SE", HistType::kTH1F, {{8000, 0, 8}}); - registry.add("ppRho/fRhoCandPtVsQ3", "Same Event distribution;Q_{3} (GeV/c);SE", HistType::kTH1F, {{8000, 0, 8}}); + registryTriggerQA.add("PPRho/all/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); + registryTriggerQA.add("PPRho/all/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); + registryTriggerQA.add("PPRho/all/fSE_particle", "Same Event distribution;Q_{3} (GeV/c);SE", HistType::kTH1F, {Binning.q3}); + registryTriggerQA.add("PPRho/all/fSE_antiparticle", "Same Event distribution;Q_{3} (GeV/c);SE", HistType::kTH1F, {Binning.q3}); + registryTriggerQA.add("PPRho/all/fProtonPtVsQ3", "Proton p_{T} vs Q3", HistType::kTH2F, {Binning.momentum, Binning.q3}); + registryTriggerQA.add("PPRho/all/fAntiProtonPtVsQ3", "AntiProton p_{T} vs Q3", HistType::kTH2F, {Binning.momentum, Binning.q3}); + registryTriggerQA.add("PPRho/all/fRhoPtVsQ3", "#rho p_{T} vs Q3;Q_{3} (GeV/c);SE", HistType::kTH2F, {Binning.momentum, Binning.q3}); + registryTriggerQA.add("PPRho/all/fRhoInvMassVsQ3", "#rho mass vs Q_{3};M_{#pi^{+}#pi^{-}} (GeV/c^{2});Q_{3} (GeV/c)", HistType::kTH2F, {Binning.invMassRho, Binning.q3}); + registryTriggerQA.add("PPRho/loose/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); + registryTriggerQA.add("PPRho/loose/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); + registryTriggerQA.add("PPRho/loose/fSE_particle", "Same Event distribution;Q_{3} (GeV/c);SE", HistType::kTH1F, {Binning.q3}); + registryTriggerQA.add("PPRho/loose/fSE_antiparticle", "Same Event distribution;Q_{3} (GeV/c);SE", HistType::kTH1F, {Binning.q3}); + registryTriggerQA.add("PPRho/loose/fProtonPtVsQ3", "Proton p_{T} vs Q3", HistType::kTH2F, {Binning.momentum, Binning.q3}); + registryTriggerQA.add("PPRho/loose/fAntiProtonPtVsQ3", "AntiProton p_{T} vs Q3", HistType::kTH2F, {Binning.momentum, Binning.q3}); + registryTriggerQA.add("PPRho/loose/fRhoPtVsQ3", "#rho p_{T} vs Q3;Q_{3} (GeV/c);SE", HistType::kTH2F, {Binning.momentum, Binning.q3}); + registryTriggerQA.add("PPRho/loose/fRhoInvMassVsQ3", "#rho mass vs Q_{3};M_{#pi^{+}#pi^{-}} (GeV/c^{2});Q_{3} (GeV/c)", HistType::kTH2F, {Binning.invMassRho, Binning.q3}); + registryTriggerQA.add("PPRho/tight/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); + registryTriggerQA.add("PPRho/tight/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); + registryTriggerQA.add("PPRho/tight/fSE_particle", "Same Event distribution;Q_{3} (GeV/c);SE", HistType::kTH1F, {Binning.q3}); + registryTriggerQA.add("PPRho/tight/fSE_antiparticle", "Same Event distribution;Q_{3} (GeV/c);SE", HistType::kTH1F, {Binning.q3}); + registryTriggerQA.add("PPRho/tight/fProtonPtVsQ3", "Proton p_{T} vs Q3", HistType::kTH2F, {Binning.momentum, Binning.q3}); + registryTriggerQA.add("PPRho/tight/fAntiProtonPtVsQ3", "AntiProton p_{T} vs Q3", HistType::kTH2F, {Binning.momentum, Binning.q3}); + registryTriggerQA.add("PPRho/tight/fRhoPtVsQ3", "#rho p_{T} vs Q3;Q_{3} (GeV/c);SE", HistType::kTH2F, {Binning.momentum, Binning.q3}); + registryTriggerQA.add("PPRho/tight/fRhoInvMassVsQ3", "#rho mass vs Q_{3};M_{#pi^{+}#pi^{-}} (GeV/c^{2});Q_{3} (GeV/c)", HistType::kTH2F, {Binning.invMassRho, Binning.q3}); // for pd - registry.add("pd/fMultiplicity", "Multiplicity of all processed events;Mult;Entries", HistType::kTH1F, {{500, 0, 500}}); - registry.add("pd/fZvtx", "Zvtx of all processed events;Z_{vtx};Entries", HistType::kTH1F, {{500, -15, 15}}); - registry.add("pd/fSE_particle", "Same Event distribution;SE;Q_{3} (GeV/c)", HistType::kTH1F, {{8000, 0, 8}}); - registry.add("pd/fSE_particle_downsample", "Same Event distribution;SE;Q_{3} (GeV/c)", HistType::kTH1F, {{8000, 0, 8}}); - registry.add("pd/fSE_antiparticle", "Same Event distribution;SE;Q_{3} (GeV/c)", HistType::kTH1F, {{8000, 0, 8}}); - registry.add("pd/fSE_antiparticle_downsample", "Same Event distribution;SE;Q_{3} (GeV/c)", HistType::kTH1F, {{8000, 0, 8}}); - registry.add("pd/fProtonPtVskstar", "pT (proton) vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {{150, 0, 1.5}, {500, 0, 10}}}); - registry.add("pd/fAntiProtonPtVskstar", "pT (antiproton) vs k^{*};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {{150, 0, 1.5}, {500, 0, 10}}}); - registry.add("pd/fDeuteronPtVskstar", "pT (deuteron) vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {{150, 0, 1.5}, {500, 0, 10}}}); - registry.add("pd/fAntiDeuteronPtVskstar", "pT (antideuteron) vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {{150, 0, 1.5}, {500, 0, 10}}}); + registryTriggerQA.add("PD/all/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); + registryTriggerQA.add("PD/all/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); + registryTriggerQA.add("PD/all/fSE_particle", "Same Event distribution;k^{*} (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); + registryTriggerQA.add("PD/all/fSE_antiparticle", "Same Event distribution;k^{*} (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); + registryTriggerQA.add("PD/all/fProtonPtVskstar", "Proton p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); + registryTriggerQA.add("PD/all/fAntiProtonPtVskstar", "AntiProton p_{T} vs k^{*};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); + registryTriggerQA.add("PD/all/fDeuteronPtVskstar", "Deuteron p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); + registryTriggerQA.add("PD/all/fAntiDeuteronPtVskstar", "AntiDeuteron p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); + registryTriggerQA.add("PD/loose/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); + registryTriggerQA.add("PD/loose/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); + registryTriggerQA.add("PD/loose/fSE_particle", "Same Event distribution;k^{*} (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); + registryTriggerQA.add("PD/loose/fSE_antiparticle", "Same Event distribution;k^{*} (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); + registryTriggerQA.add("PD/loose/fProtonPtVskstar", "Proton p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); + registryTriggerQA.add("PD/loose/fAntiProtonPtVskstar", "AntiProton p_{T} vs k^{*};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); + registryTriggerQA.add("PD/loose/fDeuteronPtVskstar", "Deuteron p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); + registryTriggerQA.add("PD/loose/fAntiDeuteronPtVskstar", "AntiDeuteron p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); + registryTriggerQA.add("PD/tight/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); + registryTriggerQA.add("PD/tight/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); + registryTriggerQA.add("PD/tight/fSE_particle", "Same Event distribution;k^{*} (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); + registryTriggerQA.add("PD/tight/fSE_antiparticle", "Same Event distribution;k^{*} (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); + registryTriggerQA.add("PD/tight/fProtonPtVskstar", "Proton p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); + registryTriggerQA.add("PD/tight/fAntiProtonPtVskstar", "AntiProton p_{T} vs k^{*};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); + registryTriggerQA.add("PD/tight/fDeuteronPtVskstar", "Deuteron p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); + registryTriggerQA.add("PD/tight/fAntiDeuteronPtVskstar", "AntiDeuteron p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); // for ld - registry.add("ld/fMultiplicity", "Multiplicity of all processed events", HistType::kTH1F, {{500, 0, 500}}); - registry.add("ld/fZvtx", "Zvtx of all processed events;Z_{vtx};Entries", HistType::kTH1F, {{500, -15, 15}}); - registry.add("ld/fSE_particle", "Same Event distribution;SE;Q_{3} (GeV/c)", HistType::kTH1F, {{8000, 0, 8}}); - registry.add("ld/fSE_particle_downsample", "Same Event distribution;SE;Q_{3} (GeV/c)", HistType::kTH1F, {{8000, 0, 8}}); - registry.add("ld/fSE_antiparticle", "Same Event distribution;SE;Q_{3} (GeV/c)", HistType::kTH1F, {{8000, 0, 8}}); - registry.add("ld/fSE_antiparticle_downsample", "Same Event distribution;SE;Q_{3} (GeV/c)", HistType::kTH1F, {{8000, 0, 8}}); - registry.add("ld/fDeuteronPtVskstar", "pT (deuteron) vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {{150, 0, 1.5}, {500, 0, 10}}}); - registry.add("ld/fAntiDeuteronPtVskstar", "pT (antideuteron) vs k^{*};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {{150, 0, 1.5}, {500, 0, 10}}}); - registry.add("ld/fLambdaPtVskstar", "pT (lambda) vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {{150, 0, 1.5}, {500, 0, 10}}}); - registry.add("ld/fAntiLambdaPtVskstar", "pT (antilambda) vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {{150, 0, 1.5}, {500, 0, 10}}}); + registryTriggerQA.add("LD/all/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); + registryTriggerQA.add("LD/all/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); + registryTriggerQA.add("LD/all/fSE_particle", "Same Event distribution;k^{*} (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); + registryTriggerQA.add("LD/all/fSE_antiparticle", "Same Event distribution;k^{*} (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); + registryTriggerQA.add("LD/all/fDeuteronPtVskstar", "Deuteron p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); + registryTriggerQA.add("LD/all/fAntiDeuteronPtVskstar", "AntiDeuteron p_{T} vs k^{*};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); + registryTriggerQA.add("LD/all/fLambdaPtVskstar", "Lambda p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); + registryTriggerQA.add("LD/all/fAntiLambdaPtVskstar", "AntiLambda p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); + registryTriggerQA.add("LD/loose/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); + registryTriggerQA.add("LD/loose/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); + registryTriggerQA.add("LD/loose/fSE_particle", "Same Event distribution;k^{*} (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); + registryTriggerQA.add("LD/loose/fSE_antiparticle", "Same Event distribution;k^{*} (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); + registryTriggerQA.add("LD/loose/fDeuteronPtVskstar", "Deuteron p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); + registryTriggerQA.add("LD/loose/fAntiDeuteronPtVskstar", "AntiDeuteron p_{T} vs k^{*};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); + registryTriggerQA.add("LD/loose/fLambdaPtVskstar", "Lambda p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); + registryTriggerQA.add("LD/loose/fAntiLambdaPtVskstar", "AntiLambda p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); + registryTriggerQA.add("LD/tight/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); + registryTriggerQA.add("LD/tight/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); + registryTriggerQA.add("LD/tight/fSE_particle", "Same Event distribution;k^{*} (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); + registryTriggerQA.add("LD/tight/fSE_antiparticle", "Same Event distribution;k^{*} (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); + registryTriggerQA.add("LD/tight/fDeuteronPtVskstar", "Deuteron p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); + registryTriggerQA.add("LD/tight/fAntiDeuteronPtVskstar", "AntiDeuteron p_{T} vs k^{*};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); + registryTriggerQA.add("LD/tight/fLambdaPtVskstar", "Lambda p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); + registryTriggerQA.add("LD/tight/fAntiLambdaPtVskstar", "AntiLambda p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); + + // for phid + registryTriggerQA.add("PhiD/all/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); + registryTriggerQA.add("PhiD/all/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); + registryTriggerQA.add("PhiD/all/fSE_particle", "Same Event distribution;k^{*} (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); + registryTriggerQA.add("PhiD/all/fSE_antiparticle", "Same Event distribution;k^{*} (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); + registryTriggerQA.add("PhiD/all/fPhiPtVskstar", "Phi p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); + registryTriggerQA.add("PhiD/all/fDeuteronPtVskstar", "Deuteron p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); + registryTriggerQA.add("PhiD/all/fAntiDeuteronPtVskstar", "AntiDeuteron p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); + registryTriggerQA.add("PhiD/all/fPhiInvMassVskstar", "#phi mass vs k^{*};M_{K^{+}K^{-}} (GeV/c^{2});k^{*} (GeV/c)", HistType::kTH2F, {Binning.invMassRho, Binning.kstar}); + registryTriggerQA.add("PhiD/loose/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); + registryTriggerQA.add("PhiD/loose/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); + registryTriggerQA.add("PhiD/loose/fSE_particle", "Same Event distribution;k^{*} (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); + registryTriggerQA.add("PhiD/loose/fSE_antiparticle", "Same Event distribution;k^{*} (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); + registryTriggerQA.add("PhiD/loose/fPhiPtVskstar", "Phi p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); + registryTriggerQA.add("PhiD/loose/fDeuteronPtVskstar", "Deuteron p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); + registryTriggerQA.add("PhiD/loose/fAntiDeuteronPtVskstar", "AntiDeuteron p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); + registryTriggerQA.add("PhiD/loose/fPhiInvMassVskstar", "#phi mass vs k^{*};M_{K^{+}K^{-}} (GeV/c^{2});k^{*} (GeV/c)", HistType::kTH2F, {Binning.invMassRho, Binning.kstar}); + registryTriggerQA.add("PhiD/tight/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); + registryTriggerQA.add("PhiD/tight/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); + registryTriggerQA.add("PhiD/tight/fSE_particle", "Same Event distribution;k^{*} (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); + registryTriggerQA.add("PhiD/tight/fSE_antiparticle", "Same Event distribution;k^{*} (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); + registryTriggerQA.add("PhiD/tight/fPhiPtVskstar", "Phi p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); + registryTriggerQA.add("PhiD/tight/fDeuteronPtVskstar", "Deuteron p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); + registryTriggerQA.add("PhiD/tight/fAntiDeuteronPtVskstar", "AntiDeuteron p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); + registryTriggerQA.add("PhiD/tight/fPhiInvMassVskstar", "#phi mass vs k^{*};M_{K^{+}K^{-}} (GeV/c^{2});k^{*} (GeV/c)", HistType::kTH2F, {Binning.invMassRho, Binning.kstar}); + + // for rhod + registryTriggerQA.add("RhoD/all/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); + registryTriggerQA.add("RhoD/all/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); + registryTriggerQA.add("RhoD/all/fSE_particle", "Same Event distribution;k^{*} (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); + registryTriggerQA.add("RhoD/all/fSE_antiparticle", "Same Event distribution;k^{*} (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); + registryTriggerQA.add("RhoD/all/fRhoPtVskstar", "Rho p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); + registryTriggerQA.add("RhoD/all/fDeuteronPtVskstar", "Deuteron p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); + registryTriggerQA.add("RhoD/all/fAntiDeuteronPtVskstar", "AntiDeuteron p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); + registryTriggerQA.add("RhoD/all/fRhoInvMassVskstar", "#rho mass vs k^{*};M_{#pi^{+}#pi^{-}} (GeV/c^{2});k^{*} (GeV/c)", HistType::kTH2F, {Binning.invMassRho, Binning.kstar}); + registryTriggerQA.add("RhoD/loose/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); + registryTriggerQA.add("RhoD/loose/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); + registryTriggerQA.add("RhoD/loose/fSE_particle", "Same Event distribution;k^{*} (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); + registryTriggerQA.add("RhoD/loose/fSE_antiparticle", "Same Event distribution;k^{*} (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); + registryTriggerQA.add("RhoD/loose/fRhoPtVskstar", "Rho p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); + registryTriggerQA.add("RhoD/loose/fDeuteronPtVskstar", "Deuteron p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); + registryTriggerQA.add("RhoD/loose/fAntiDeuteronPtVskstar", "AntiDeuteron p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); + registryTriggerQA.add("RhoD/loose/fRhoInvMassVskstar", "#rho mass vs k^{*};M_{#pi^{+}#pi^{-}} (GeV/c^{2});k^{*} (GeV/c)", HistType::kTH2F, {Binning.invMassRho, Binning.kstar}); + registryTriggerQA.add("RhoD/tight/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); + registryTriggerQA.add("RhoD/tight/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); + registryTriggerQA.add("RhoD/tight/fSE_particle", "Same Event distribution;k^{*} (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); + registryTriggerQA.add("RhoD/tight/fSE_antiparticle", "Same Event distribution;k^{*} (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); + registryTriggerQA.add("RhoD/tight/fRhoPtVskstar", "Rho p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); + registryTriggerQA.add("RhoD/tight/fDeuteronPtVskstar", "Deuteron p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); + registryTriggerQA.add("RhoD/tight/fAntiDeuteronPtVskstar", "AntiDeuteron p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); + registryTriggerQA.add("RhoD/tight/fRhoInvMassVskstar", "#rho mass vs k^{*};M_{#pi^{+}#pi^{-}} (GeV/c^{2});k^{*} (GeV/c)", HistType::kTH2F, {Binning.invMassRho, Binning.kstar}); } - float mMassElectron = o2::constants::physics::MassElectron; - float mMassPion = o2::constants::physics::MassPionCharged; - float mMassProton = o2::constants::physics::MassProton; - float mMassLambda = o2::constants::physics::MassLambda; - float mMassDeuteron = o2::constants::physics::MassDeuteron; - float mMassPhi = o2::constants::physics::MassPhi; - float mMassKaonPlus = o2::constants::physics::MassKPlus; - float mMassKaonMinus = o2::constants::physics::MassKMinus; - float mMassRho0 = 0.7665; // GeV/c^2 // o2::constants::physics::MassRho0; //Will not work as this is missing in the central framework, also ROOT reports the lepton production value of 0.77549 GeV/c^2, which is wrong for the hadron production at ALICE. + void initCCDB(int run) + { + if (run != mRunNumber) { + mRunNumber = run; + o2::parameters::GRPMagField* grpmag = ccdb->getForRun("GLO/Config/GRPMagField", run); + o2::base::Propagator::initFieldFromGRP(grpmag); + mBz = static_cast(grpmag->getNominalL3Field()); - int currentRunNumber = -999; - int lastRunNumber = -999; + mStraHelper.fitter.setBz(mBz); + } + if (!mStraHelper.lut) { /// done only once + ccdb->setURL(V0BuilderOpts.ccdbUrl); + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); + ccdb->setFatalWhenNull(true); + auto* lut = o2::base::MatLayerCylSet::rectifyPtrFromFile(ccdb->get("GLO/Param/MatLUT")); + o2::base::Propagator::Instance()->setMatLUT(lut); + mStraHelper.lut = lut; + } + } template - bool isSelectedEvent(T const& col) + bool checkEvent(T const& col) { - if (ConfEvtSelectZvtx && std::abs(col.posZ()) > ConfEvtZvtx) { + if (std::abs(col.posZ()) > EventSelection.zvtx.value) { return false; } - if (ConfEvtOfflineCheck && !col.sel8()) { + if (EventSelection.eventSel.value && !col.sel8()) { return false; } - // if event is close to the timeframe border, return false - if (ConfEvtTimeFrameBorderCheck && !col.selection_bit(aod::evsel::kNoTimeFrameBorder)) { - return false; - } - return true; } template - bool isSelectedTrack(T const& track, CFTrigger::ParticleSpecies partSpecies) + bool checkTrack(T const& track, std::string trackName) { - const auto charge = track.sign(); - const auto pT = track.pt(); - float momCorDif = track.tpcInnerParam() - track.p(); - float momCorRatio = momCorDif / track.p(); - const auto eta = track.eta(); - const auto tpcNClsF = track.tpcNClsFound(); - const auto tpcRClsC = track.tpcCrossedRowsOverFindableCls(); - const auto tpcNClsC = track.tpcNClsCrossedRows(); - const auto tpcNClsS = track.tpcNClsShared(); - const auto itsNCls = track.itsNCls(); - const auto itsNClsIB = track.itsNClsInnerBarrel(); - const auto dcaXY = track.dcaXY(); - const auto dcaZ = track.dcaZ(); - - if (charge > 0) { - if (pT < ConfPtCuts->get(partSpecies, "Pt min (particle)")) { - return false; - } - if (pT > ConfPtCuts->get(partSpecies, "Pt max (particle)")) { - return false; - } - if (ConfMomCorDifCutFlag.value && momCorDif < ConfMomCorDifCut->get(partSpecies, "Momemtum Correlation min")) { - return false; - } - if (ConfMomCorDifCutFlag.value && momCorDif > ConfMomCorDifCut->get(partSpecies, "Momemtum Correlation max")) { - return false; - } - if (ConfMomCorRatioCutFlag.value && momCorRatio < ConfMomCorRatioCut->get(partSpecies, "Momemtum Correlation min")) { - return false; - } - if (ConfMomCorRatioCutFlag.value && momCorRatio > ConfMomCorRatioCut->get(partSpecies, "Momemtum Correlation max")) { - return false; - } - } - if (charge < 0) { - if (pT < ConfPtCuts->get(partSpecies, "Pt min (antiparticle)")) { - return false; - } - if (pT > ConfPtCuts->get(partSpecies, "Pt max (antiparticle)")) { - return false; - } - if (ConfMomCorDifCutFlag.value && momCorDif < ConfMomCorDifCutAnti->get(partSpecies, "Momemtum Correlation min")) { - return false; - } - if (ConfMomCorDifCutFlag.value && momCorDif > ConfMomCorDifCutAnti->get(partSpecies, "Momemtum Correlation max")) { - return false; - } - if (ConfMomCorRatioCutFlag.value && momCorRatio < ConfMomCorRatioCutAnti->get(partSpecies, "Momemtum Correlation min")) { - return false; - } - if (ConfMomCorRatioCutFlag.value && momCorRatio > ConfMomCorRatioCutAnti->get(partSpecies, "Momemtum Correlation max")) { - return false; - } - } - - if (std::abs(eta) > ConfTrkEta) { + if (track.pt() < TrackSelections.momentum->get(trackName.c_str(), "PtMin")) { return false; } - if (tpcNClsF < ConfTPCNClustersMin->get("TPCNClusMin", partSpecies)) { + if (track.pt() > TrackSelections.momentum->get(trackName.c_str(), "PtMax")) { return false; } - if (tpcRClsC < ConfTrkTPCfCls) { + if (std::abs(track.eta()) > TrackSelections.trackProperties->get(trackName.c_str(), "AbsEtaMax")) { return false; } - if (tpcNClsC < ConfTrkTPCcRowsMin) { + if (track.tpcNClsFound() < TrackSelections.trackProperties->get(trackName.c_str(), "TpcClusterMin")) { return false; } - if (tpcNClsS > ConfTrkTPCsClsMax) { + if (track.tpcNClsCrossedRows() < TrackSelections.trackProperties->get(trackName.c_str(), "TpcRowMin")) { return false; } - if (itsNCls < ConfTrkITSnclsMin->get(static_cast(0), partSpecies)) { + if (track.tpcCrossedRowsOverFindableCls() < TrackSelections.trackProperties->get(trackName.c_str(), "TpcCrossedOverFoundMin")) { return false; } - if (itsNClsIB < ConfTrkITSnclsIBMin->get(static_cast(0), partSpecies)) { + if (track.tpcNClsShared() > TrackSelections.trackProperties->get(trackName.c_str(), "TpcSharedMax")) { return false; } - if (std::abs(dcaXY) > ConfTrkDCAxyMax) { + if (track.tpcFractionSharedCls() > TrackSelections.trackProperties->get(trackName.c_str(), "TpcFracSharedMax")) { return false; } - if (std::abs(dcaZ) > ConfTrkDCAzMax) { + if (track.itsNCls() < TrackSelections.trackProperties->get(trackName.c_str(), "ItsClusterMin")) { return false; } - // TODO: which dca, put dcaxy for now - if (ConfRejectNotPropagatedTracks && std::abs(dcaXY) > 1e3) { + if (track.itsNClsInnerBarrel() < TrackSelections.trackProperties->get(trackName.c_str(), "ItsIbClusterMin")) { return false; } - if (ConfTrkRequireChi2MaxTPC && track.tpcChi2NCl() >= ConfTrkMaxChi2PerClusterTPC) { + if (std::abs(track.dcaXY()) > TrackSelections.trackProperties->get(trackName.c_str(), "AbsDcaXyMax")) { return false; } - if (ConfTrkRequireChi2MaxITS && track.itsChi2NCl() >= ConfTrkMaxChi2PerClusterITS) { + if (std::abs(track.dcaZ()) > TrackSelections.trackProperties->get(trackName.c_str(), "AbsDcaZMax")) { return false; } - if (ConfTrkTPCRefit && !track.hasTPC()) { + if (track.tpcChi2NCl() > TrackSelections.trackProperties->get(trackName.c_str(), "Chi2TpcMax")) { return false; } - if (ConfTrkITSRefit && !track.hasITS()) { + if (track.itsChi2NCl() > TrackSelections.trackProperties->get(trackName.c_str(), "Chi2ItsMax")) { return false; } return true; } - template - bool isSelectedV0Daughter(T const& track, V const& v0, float charge, CFTrigger::V0Daughters species, double nSigmaTPCDaug[2]) + template + bool checkTrackPid(T const& track, std::string trackName) { - const auto tpcNClsF = track.tpcNClsFound(); - float eta = -1; - float dca = -1; - if (charge > 0) { - eta = v0.positiveeta(); - dca = v0.dcapostopv(); - } else if (charge < 0) { - eta = v0.negativeeta(); - dca = v0.dcanegtopv(); - } - const auto sign = track.sign(); - double nSigmaTPC = -999.f; - - if (charge < 0 && sign > 0) { - return false; - } - if (charge > 0 && sign < 0) { - return false; - } - if (std::abs(eta) > ConfDaughEta) { - return false; - } - if (tpcNClsF < ConfDaughTPCnclsMin) { - return false; - } - if (std::abs(dca) < ConfDaughDCAMin) { - return false; - } - - switch (species) { - case CFTrigger::kDaughPion: - nSigmaTPC = nSigmaTPCDaug[1]; - break; - case CFTrigger::kDaughProton: - nSigmaTPC = nSigmaTPCDaug[0]; - break; - default: - LOG(fatal) << "Particle species for V0 daughters not found"; - } + float momentum = -99; - if (nSigmaTPC < ConfDaughPIDCuts->get(species, "TPC min") || - nSigmaTPC > ConfDaughPIDCuts->get(species, "TPC max")) { - return false; + if (TrackSelections.momentum->get(trackName.c_str(), "UseInnerParam") < 0) { + momentum = track.p(); + } else { + momentum = track.tpcInnerParam(); } - return true; - } - template - bool isSelectedTrackPID(T const& track, CFTrigger::ParticleSpecies partSpecies, bool Rejection, double nSigmaTPC[2], int charge) - { - // nSigma should have entries [proton, deuteron, pion] - bool isSelected = false; - bool pThres = true; - float nSigma = -999.; - float nSigmaIts = -999.; - - // check tracking PID - uint8_t SpeciesForTracking = 0; - if (partSpecies == CFTrigger::kProton) { - SpeciesForTracking = o2::track::PID::Proton; - } else if (partSpecies == CFTrigger::kDeuteron) { - SpeciesForTracking = o2::track::PID::Deuteron; - } else if (partSpecies == CFTrigger::kPion) { - SpeciesForTracking = o2::track::PID::Pion; + float nsigmaITS = -99; + float nsigmaTPC = -99; + float nsigmaTPCTOF = -99; + + if (trackName == std::string("Pion")) { + nsigmaITS = track.itsNSigmaPi(); + nsigmaTPC = track.tpcNSigmaPi(); + nsigmaTPCTOF = RecoDecay::sqrtSumOfSquares(track.tpcNSigmaPi(), track.tofNSigmaPi()); + } else if (trackName == std::string("Kaon")) { + nsigmaITS = track.itsNSigmaKa(); + nsigmaTPC = track.tpcNSigmaKa(); + nsigmaTPCTOF = RecoDecay::sqrtSumOfSquares(track.tpcNSigmaKa(), track.tofNSigmaKa()); + } else if (trackName == std::string("Proton")) { + nsigmaITS = track.itsNSigmaPr(); + nsigmaTPC = track.tpcNSigmaPr(); + nsigmaTPCTOF = RecoDecay::sqrtSumOfSquares(track.tpcNSigmaPr(), track.tofNSigmaPr()); + } else if (trackName == std::string("Deuteron")) { + nsigmaITS = track.itsNSigmaDe(); + nsigmaTPC = track.tpcNSigmaDe(); + nsigmaTPCTOF = RecoDecay::sqrtSumOfSquares(track.tpcNSigmaDe(), track.tofNSigmaDe()); } else { - LOG(warn) << "Unknown PID for tracking encountered"; + LOG(fatal) << "Unsupported track type"; } - if (ConfPIDForTracking->get(partSpecies, "Switch") > 0 && track.tpcInnerParam() < ConfPIDForTracking->get(partSpecies, "Momemtum Threshold")) { - if (track.pidForTracking() != SpeciesForTracking) { + if (momentum < TrackSelections.momentum->get(trackName.c_str(), "PThres")) { + if (nsigmaITS < TrackSelections.pid->get(trackName.c_str(), "ItsMin") || nsigmaITS > TrackSelections.pid->get(trackName.c_str(), "ItsMax")) { return false; } - } - - // check momentum threshold - if (track.tpcInnerParam() <= ConfPtCuts->get(partSpecies, "P thres")) { - pThres = true; - } else { - pThres = false; - } - if (CFTrigger::kDeuteron == partSpecies && ConfDeuteronThPVMom) { - if (track.p() <= ConfPtCuts->get(partSpecies, "P thres")) { - pThres = true; - } else { - pThres = false; - } - } - // compute nsigma - switch (partSpecies) { - case CFTrigger::kProton: - nSigmaIts = track.itsNSigmaPr(); - if (pThres) { - nSigma = nSigmaTPC[0]; - } else { - if (charge > 0) { - nSigma = std::sqrt(std::pow(nSigmaTPC[0] - TPCTOFAvg[0], 2) + std::pow(track.tofNSigmaPr() - TPCTOFAvg[1], 2)); - } else { - nSigma = std::sqrt(std::pow(nSigmaTPC[0] - TPCTOFAvg[2], 2) + std::pow(track.tofNSigmaPr() - TPCTOFAvg[3], 2)); - } - } - break; - case CFTrigger::kDeuteron: - nSigmaIts = track.itsNSigmaDe(); - if (pThres) { - nSigma = nSigmaTPC[1]; - } else { - if (charge > 0) { - nSigma = std::sqrt(std::pow(nSigmaTPC[1] - TPCTOFAvg[4], 2) + std::pow(track.tofNSigmaDe() - TPCTOFAvg[5], 2)); - } else { - nSigma = std::sqrt(std::pow(nSigmaTPC[1] - TPCTOFAvg[6], 2) + std::pow(track.tofNSigmaDe() - TPCTOFAvg[7], 2)); - } - } - break; - case CFTrigger::kLambda: - LOG(fatal) << "No PID selection for Lambdas"; - break; - case CFTrigger::kPion: - nSigmaIts = track.itsNSigmaPi(); - if (pThres) { - nSigma = nSigmaTPC[2]; - } else { - if (charge > 0) { - nSigma = std::sqrt(std::pow(nSigmaTPC[2] - TPCTOFAvg[8], 2) + std::pow(track.tofNSigmaPr() - TPCTOFAvg[9], 2)); - } else { - nSigma = std::sqrt(std::pow(nSigmaTPC[2] - TPCTOFAvg[10], 2) + std::pow(track.tofNSigmaPr() - TPCTOFAvg[11], 2)); - } - } - break; - default: - LOG(fatal) << "Particle species not known"; - } - // check if track is selected - - auto TPCmin = (charge > 0) ? ConfPIDCuts->get(partSpecies, CFTrigger::kTPCMin) - : ConfPIDCutsAnti->get(partSpecies, CFTrigger::kTPCMin); - - auto TPCmax = (charge > 0) ? ConfPIDCuts->get(partSpecies, CFTrigger::kTPCMax) - : ConfPIDCutsAnti->get(partSpecies, CFTrigger::kTPCMax); - - auto TPCTOFmax = (charge > 0) ? ConfPIDCuts->get(partSpecies, CFTrigger::kTPCTOF) - : ConfPIDCutsAnti->get(partSpecies, CFTrigger::kTPCTOF); - - auto ITSmin = (charge > 0) ? ConfPIDCuts->get(partSpecies, CFTrigger::kITSmin) - : ConfPIDCutsAnti->get(partSpecies, CFTrigger::kITSmin); - - auto ITSmax = (charge < 0) ? ConfPIDCuts->get(partSpecies, CFTrigger::kITSmax) - : ConfPIDCutsAnti->get(partSpecies, CFTrigger::kITSmax); - - if (pThres) { - if (nSigma > TPCmin && - nSigma < TPCmax && - nSigmaIts > ITSmin && - nSigmaIts < ITSmax) { - isSelected = true; + if (nsigmaTPC < TrackSelections.pid->get(trackName.c_str(), "TpcMin") || nsigmaTPC > TrackSelections.pid->get(trackName.c_str(), "TpcMax")) { + return false; } } else { - if (nSigma < TPCTOFmax) { - isSelected = true; - } - } - // for deuterons normally, we want to reject tracks that have a high - // probablilty of being another particle - if (Rejection) { - double nSigmaPi = track.tpcNSigmaPi(); - double nSigmaEl = track.tpcNSigmaEl(); - if (ConfUseManualPIDpion) { - auto bgScalingPion = 1 / mMassPion; // momentum scaling? - if (BBPion.size() == 6 && charge > 0) - nSigmaPi = updatePID(track, bgScalingPion, BBPion); - if (BBAntipion.size() == 6 && charge < 0) - nSigmaPi = updatePID(track, bgScalingPion, BBAntipion); - } - if (ConfUseManualPIDel) { - auto bgScalingElectron = 1 / mMassElectron; // momentum scaling? - if (BBElectron.size() == 6 && charge < 0) - nSigmaEl = updatePID(track, bgScalingElectron, BBElectron); - if (BBAntielectron.size() == 6 && charge > 0) - nSigmaEl = updatePID(track, bgScalingElectron, BBAntielectron); - } - if ((ConfPIDRejection->get(CFTrigger::kRejProton, CFTrigger::kTPCMin) < nSigmaTPC[0] && - ConfPIDRejection->get(CFTrigger::kRejProton, CFTrigger::kTPCMax) > nSigmaTPC[0]) || - (ConfPIDRejection->get(CFTrigger::kRejPion, CFTrigger::kTPCMin) < nSigmaPi && - ConfPIDRejection->get(CFTrigger::kRejPion, CFTrigger::kTPCMax) > nSigmaPi) || - (ConfPIDRejection->get(CFTrigger::kRejElectron, CFTrigger::kTPCMin) < nSigmaEl && - ConfPIDRejection->get(CFTrigger::kRejElectron, CFTrigger::kTPCMax) > nSigmaEl)) { + if (nsigmaTPCTOF > TrackSelections.pid->get(trackName.c_str(), "TpcTofMax")) { return false; } } - return isSelected; + return true; } - template - bool isSelectedMinimalV0(C const& /*col*/, V const& v0, T const& posTrack, - T const& negTrack, float charge, double nSigmaTPCPos[2], double nSigmaTPCNeg[2]) + bool checkLambda(float lambdaPt, float lambdaDauDca, float lambdaCpa, float lambdaRadius, float lambdaPos, float kaonMass, float lambdaMass) { - const auto signPos = posTrack.sign(); - const auto signNeg = negTrack.sign(); - if (signPos < 0 || signNeg > 0) { - LOG(info) << "Something wrong in isSelectedMinimal"; - LOG(info) << "ERROR - Wrong sign for V0 daughters"; - } - const float pT = v0.pt(); - const std::vector decVtx = {v0.x(), v0.y(), v0.z()}; - const float tranRad = v0.v0radius(); - const float dcaDaughv0 = v0.dcaV0daughters(); - const float cpav0 = v0.v0cosPA(); - - const float invMassLambda = v0.mLambda(); - const float invMassAntiLambda = v0.mAntiLambda(); - - if (charge > 0 && (invMassLambda < ConfV0InvMassLowLimit || invMassLambda > ConfV0InvMassUpLimit)) { - return false; - } - if (charge < 0 && (invMassAntiLambda < ConfV0InvMassLowLimit || invMassAntiLambda > ConfV0InvMassUpLimit)) { + if (lambdaPt < LambdaSelections.ptMin) { return false; } - if (ConfV0RejectKaons) { - const float invMassKaon = v0.mK0Short(); - if (invMassKaon > ConfV0InvKaonMassLowLimit && invMassKaon < ConfV0InvKaonMassUpLimit) { - return false; - } - } - if (pT < ConfV0PtMin) { + if (lambdaDauDca > LambdaSelections.dcaDaughMax) { return false; } - if (dcaDaughv0 > ConfV0DCADaughMax) { + if (lambdaCpa < LambdaSelections.cpaMin) { return false; } - if (cpav0 < ConfV0CPAMin) { + if (lambdaRadius < LambdaSelections.tranRadMin) { return false; } - if (tranRad < ConfV0TranRadV0Min) { + if (lambdaRadius > LambdaSelections.tranRadMax) { return false; } - if (tranRad > ConfV0TranRadV0Max) { + if (lambdaPos > LambdaSelections.decVtxMax) { return false; } - for (size_t i = 0; i < decVtx.size(); i++) { - if (decVtx.at(i) > ConfV0DecVtxMax) { + if (LambdaSelections.rejectKaons) { + if (kaonMass > LambdaSelections.invKaonMassLow && kaonMass < LambdaSelections.invKaonMassUp) { return false; } } - if (charge > 0) { - if (!isSelectedV0Daughter(posTrack, v0, 1, CFTrigger::kDaughProton, nSigmaTPCPos)) { - return false; - } - if (!isSelectedV0Daughter(negTrack, v0, -1, CFTrigger::kDaughPion, nSigmaTPCNeg)) { - return false; - } + if (lambdaMass < LambdaSelections.invMassLow) { + return false; } - if (charge < 0) { - if (!isSelectedV0Daughter(posTrack, v0, 1, CFTrigger::kDaughPion, nSigmaTPCPos)) { - return false; - } - if (!isSelectedV0Daughter(negTrack, v0, -1, CFTrigger::kDaughProton, nSigmaTPCNeg)) { - return false; - } + if (lambdaMass > LambdaSelections.invMassUp) { + return false; } return true; } template - bool isSelectedTrackKaon(T const& track) + bool checkLambdaDaughter(T const& track, float eta, float dca, float nSigmaTPC) { - bool isSelected = false; - if (track.pt() <= PPPhi.ConfTrkPtKaUp.value && track.pt() >= PPPhi.ConfTrkPtKaDown.value && std::abs(track.eta()) <= PPPhi.ConfTrkEtaKa.value && std::abs(track.dcaXY()) <= PPPhi.ConfTrkDCAxyKa.value && std::abs(track.dcaZ()) <= PPPhi.ConfTrkDCAzKa.value && track.tpcNClsCrossedRows() >= PPPhi.ConfNCrossedKa.value && track.tpcNClsFound() >= PPPhi.ConfNClusKa.value && track.tpcCrossedRowsOverFindableCls() >= PPPhi.ConfTrkTPCfClsKa.value) { - if (track.tpcInnerParam() < PPPhi.ConfTrkPTPCKaThr.value && std::abs(track.tpcNSigmaKa()) <= PPPhi.ConfTrkKaSigmaPID.value) { - isSelected = true; - } - if (track.tpcInnerParam() >= PPPhi.ConfTrkPTPCKaThr.value && std::abs(std::sqrt(track.tpcNSigmaKa() * track.tpcNSigmaKa() + track.tofNSigmaKa() * track.tofNSigmaKa())) <= PPPhi.ConfTrkKaSigmaPID.value) { - isSelected = true; - } + if (std::abs(eta) > LambdaDaughterSelections.absEtaMax.value) { + return false; } - return isSelected; - } - - double translatePhi(double phi) - { - if (phi < 0) { - phi += 2 * M_PI; // Add 2 pi to make it positive + if (std::abs(dca) < LambdaDaughterSelections.dcaMin.value) { + return false; + } + if (track.tpcNClsFound() < LambdaDaughterSelections.tpcClusterMin.value) { + return false; + } + if (std::abs(nSigmaTPC) > LambdaDaughterSelections.tpcMax.value) { + return false; } - return phi; + return true; } float getkstar(const ROOT::Math::PtEtaPhiMVector part1, @@ -1453,18 +1216,18 @@ struct CFFilter { const float betay = beta * std::sin(trackSum.Phi()) * std::sin(trackSum.Theta()); const float betaz = beta * std::cos(trackSum.Theta()); - ROOT::Math::PxPyPzMVector PartOneCMS(part1); - ROOT::Math::PxPyPzMVector PartTwoCMS(part2); + ROOT::Math::PxPyPzMVector partOneCMS(part1); + ROOT::Math::PxPyPzMVector partTwoCMS(part2); const ROOT::Math::Boost boostPRF = ROOT::Math::Boost(-betax, -betay, -betaz); - PartOneCMS = boostPRF(PartOneCMS); - PartTwoCMS = boostPRF(PartTwoCMS); - const ROOT::Math::PxPyPzMVector trackRelK = PartOneCMS - PartTwoCMS; + partOneCMS = boostPRF(partOneCMS); + partTwoCMS = boostPRF(partTwoCMS); + const ROOT::Math::PxPyPzMVector trackRelK = partOneCMS - partTwoCMS; return 0.5 * trackRelK.P(); } - ROOT::Math::PxPyPzEVector getqij(const ROOT::Math::PtEtaPhiMVector parti, - const ROOT::Math::PtEtaPhiMVector partj) + ROOT::Math::PxPyPzEVector + getqij(const ROOT::Math::PtEtaPhiMVector parti, const ROOT::Math::PtEtaPhiMVector partj) { ROOT::Math::PxPyPzEVector vecparti(parti); ROOT::Math::PxPyPzEVector vecpartj(partj); @@ -1473,1137 +1236,1374 @@ struct CFFilter { float scaling = trackDifference.Dot(trackSum) / trackSum.Dot(trackSum); return trackDifference - scaling * trackSum; } - float getQ3(const ROOT::Math::PtEtaPhiMVector part1, - const ROOT::Math::PtEtaPhiMVector part2, - const ROOT::Math::PtEtaPhiMVector part3) + float getQ3(const ROOT::Math::PtEtaPhiMVector part1, const ROOT::Math::PtEtaPhiMVector part2, const ROOT::Math::PtEtaPhiMVector part3) { ROOT::Math::PxPyPzEVector q12 = getqij(part1, part2); ROOT::Math::PxPyPzEVector q23 = getqij(part2, part3); ROOT::Math::PxPyPzEVector q31 = getqij(part3, part1); - float Q32 = q12.M2() + q23.M2() + q31.M2(); - return sqrt(-Q32); - } - - std::vector setValuesBB(aod::BCsWithTimestamps::iterator const& bunchCrossing, const std::string ccdbPath) - { - map metadata; - auto h = ccdbApi.retrieveFromTFileAny(ccdbPath, metadata, bunchCrossing.timestamp()); - // auto h = ccdb->getForTimeStamp(ccdbPath, bunchCrossing.timestamp()); //check if possible to use this without getting fatal - if (!h) { - std::vector dummy; - LOG(info) << "File from CCDB in path " << ccdbPath << " was not found for run " << bunchCrossing.runNumber() << ". Will use default PID task values!"; - return dummy; - } - LOG(info) << "File from CCDB in path " << ccdbPath << " was found for run " << bunchCrossing.runNumber() << "!"; - - TAxis* axis = h->GetXaxis(); - std::vector v{static_cast(h->GetBinContent(axis->FindBin("bb1"))), - static_cast(h->GetBinContent(axis->FindBin("bb2"))), - static_cast(h->GetBinContent(axis->FindBin("bb3"))), - static_cast(h->GetBinContent(axis->FindBin("bb4"))), - static_cast(h->GetBinContent(axis->FindBin("bb5"))), - static_cast(h->GetBinContent(axis->FindBin("Resolution")))}; - return v; - } - - std::vector setValuesAvg(aod::BCsWithTimestamps::iterator const& bunchCrossing, const std::string ccdbPath) - { - map metadata; - auto h = ccdbApi.retrieveFromTFileAny(ccdbPath, metadata, bunchCrossing.timestamp()); - // auto h = ccdb->getForTimeStamp(ccdbPath, bunchCrossing.timestamp()); //check if possible to use this without getting fatal - if (!h) { - std::vector dummy{ConfPIDTPCTOFAvg->get("Proton", "TPC Avg"), - ConfPIDTPCTOFAvg->get("Proton", "TOF Avg"), - ConfPIDTPCTOFAvg->get("AntiProton", "TPC Avg"), - ConfPIDTPCTOFAvg->get("AntiProton", "TOF Avg"), - ConfPIDTPCTOFAvg->get("Deuteron", "TPC Avg"), - ConfPIDTPCTOFAvg->get("Deuteron", "TOF Avg"), - ConfPIDTPCTOFAvg->get("AntiDeuteron", "TPC Avg"), - ConfPIDTPCTOFAvg->get("AntiDeuteron", "TOF Avg")}; - LOG(info) << "File from CCDB in path " << ccdbPath << " was not found for run " << bunchCrossing.runNumber() << ". Will use constant values from ConfPIDTPCTOFAvg!"; - return dummy; - } - LOG(info) << "File from CCDB in path " << ccdbPath << " was found for run " << bunchCrossing.runNumber() << "!"; - - TAxis* axis = h->GetXaxis(); - std::vector v{static_cast(h->GetBinContent(axis->FindBin("TPCProton"))), - static_cast(h->GetBinContent(axis->FindBin("TOFProton"))), - static_cast(h->GetBinContent(axis->FindBin("TPCAntiproton"))), - static_cast(h->GetBinContent(axis->FindBin("TOFAntiproton"))), - static_cast(h->GetBinContent(axis->FindBin("TPCDeuteron"))), - static_cast(h->GetBinContent(axis->FindBin("TOFDeuteron"))), - static_cast(h->GetBinContent(axis->FindBin("TPCAntideuteron"))), - static_cast(h->GetBinContent(axis->FindBin("TOFAntideuteron")))}; - return v; + float q32 = q12.M2() + q23.M2() + q31.M2(); + return std::sqrt(-q32); } template - double updatePID(T const& track, double bgScaling, std::vector BB) + float itsSignal(T const& track) { - double expBethe = tpc::BetheBlochAleph(static_cast(track.tpcInnerParam() * bgScaling), BB[0], BB[1], BB[2], BB[3], BB[4]); - double expSigma = expBethe * BB[5]; - return static_cast((track.tpcSignal() - expBethe) / expSigma); - } - - void process(aod::FemtoFullCollision const& col, aod::BCsWithTimestamps const&, aod::FemtoFullTracks const& tracks, o2::aod::V0Datas const& fullV0s) + uint32_t clsizeflag = track.itsClusterSizes(); + auto clSizeLayer0 = (clsizeflag >> (0 * 4)) & 0xf; + auto clSizeLayer1 = (clsizeflag >> (1 * 4)) & 0xf; + auto clSizeLayer2 = (clsizeflag >> (2 * 4)) & 0xf; + auto clSizeLayer3 = (clsizeflag >> (3 * 4)) & 0xf; + auto clSizeLayer4 = (clsizeflag >> (4 * 4)) & 0xf; + auto clSizeLayer5 = (clsizeflag >> (5 * 4)) & 0xf; + auto clSizeLayer6 = (clsizeflag >> (6 * 4)) & 0xf; + int numLayers = 7; + int sumClusterSizes = clSizeLayer1 + clSizeLayer2 + clSizeLayer3 + clSizeLayer4 + clSizeLayer5 + clSizeLayer6 + clSizeLayer0; + float cosLamnda = 1. / std::cosh(track.eta()); + return (static_cast(sumClusterSizes) / numLayers) * cosLamnda; + }; + + void process(cf_trigger::FullCollision const& col, aod::BCs const&, cf_trigger::FullTracks const& tracks, o2::aod::V0s const& v0s) { - if (!ConfIsRun3) { - LOG(fatal) << "Run 2 processing is not implemented!"; + auto tracksWithItsPid = soa::Attach(tracks); + + // reset all arrays + keepEventTightLimit.fill(false); + keepEventLooseLimit.fill(false); + signalTightLimit.fill(0); + signalLooseLimit.fill(0); + + registryTriggerQA.fill(HIST("fProcessedEvents"), 0); + registryParticleQA.fill(HIST("EventQA/Before/fMultiplicity"), col.multNTracksPV()); + registryParticleQA.fill(HIST("EventQA/Before/fZvtx"), col.posZ()); + + if (!checkEvent(col)) { + tags(keepEventTightLimit[cf_trigger::kPPP], keepEventLooseLimit[cf_trigger::kPPP], + keepEventTightLimit[cf_trigger::kPPL], keepEventLooseLimit[cf_trigger::kPPL], + keepEventTightLimit[cf_trigger::kPLL], keepEventLooseLimit[cf_trigger::kPLL], + keepEventTightLimit[cf_trigger::kLLL], keepEventLooseLimit[cf_trigger::kLLL], + keepEventTightLimit[cf_trigger::kPPPhi], keepEventLooseLimit[cf_trigger::kPPPhi], + keepEventTightLimit[cf_trigger::kPPRho], keepEventLooseLimit[cf_trigger::kPPRho], + keepEventTightLimit[cf_trigger::kPD], keepEventLooseLimit[cf_trigger::kPD], + keepEventTightLimit[cf_trigger::kLD], keepEventLooseLimit[cf_trigger::kLD], + keepEventTightLimit[cf_trigger::kPhiD], keepEventLooseLimit[cf_trigger::kPhiD], + keepEventTightLimit[cf_trigger::kRhoD], keepEventLooseLimit[cf_trigger::kRhoD]); + return; } - if (ConfUseManualPIDproton || ConfUseManualPIDdeuteron || ConfUseAvgFromCCDB) { - currentRunNumber = col.bc_as().runNumber(); - if (currentRunNumber != lastRunNumber) { - auto bc = col.bc_as(); - if (ConfUseManualPIDproton || ConfUseManualPIDdaughterProton) { - BBProton = setValuesBB(bc, ConfPIDBBProton); - BBAntiproton = setValuesBB(bc, ConfPIDBBAntiProton); - } - if (ConfUseManualPIDdeuteron) { - BBDeuteron = setValuesBB(bc, ConfPIDBBDeuteron); - BBAntideuteron = setValuesBB(bc, ConfPIDBBAntiDeuteron); - } - if (ConfUseManualPIDpion || ConfUseManualPIDdaughterPion) { - BBPion = setValuesBB(bc, ConfPIDBBPion); - BBAntipion = setValuesBB(bc, ConfPIDBBAntiPion); - } - if (ConfUseManualPIDpion) { - BBElectron = setValuesBB(bc, ConfPIDBBElectron); - BBAntielectron = setValuesBB(bc, ConfPIDBBAntiElectron); + registryParticleQA.fill(HIST("EventQA/After/fMultiplicity"), col.multNTracksPV()); + registryParticleQA.fill(HIST("EventQA/After/fZvtx"), col.posZ()); + + initCCDB(col.bc().runNumber()); + + // clear particle vectors + vecProton.clear(); + vecAntiProton.clear(); + vecDeuteron.clear(); + vecAntiDeuteron.clear(); + vecLambda.clear(); + vecAntiLambda.clear(); + vecKaon.clear(); + vecAntiKaon.clear(); + vecPhi.clear(); + vecPion.clear(); + vecAntiPion.clear(); + vecRho.clear(); + // clear index vectors for all particles + idxProton.clear(); + idxAntiProton.clear(); + idxDeuteron.clear(); + idxAntiDeuteron.clear(); + idxKaon.clear(); + idxAntiKaon.clear(); + idxPion.clear(); + idxAntiPion.clear(); + // clear index vectors for daughters + idxLambdaDaughProton.clear(); + idxLambdaDaughPion.clear(); + idxAntiLambdaDaughProton.clear(); + idxAntiLambdaDaughPion.clear(); + idxPhiDaughPos.clear(); + idxPhiDaughNeg.clear(); + idxRhoDaughPos.clear(); + idxRhoDaughNeg.clear(); + + for (auto const& track : tracksWithItsPid) { + + // get paritcles + if (track.sign() > 0) { + registryParticleQA.fill(HIST("TrackQA/Before/Particle/fPt"), track.pt()); + registryParticleQA.fill(HIST("TrackQA/Before/Particle/fEta"), track.eta()); + registryParticleQA.fill(HIST("TrackQA/Before/Particle/fPhi"), track.phi()); + registryParticleQA.fill(HIST("TrackQA/Before/Particle/fMomCor"), track.p(), (track.tpcInnerParam() - track.p()) / track.p()); + registryParticleQA.fill(HIST("TrackQA/Before/Particle/fItsSignal"), track.p(), itsSignal(track)); + registryParticleQA.fill(HIST("TrackQA/Before/Particle/fTpcSignal"), track.p(), track.tpcSignal()); + registryParticleQA.fill(HIST("TrackQA/Before/Particle/fTofSignal"), track.p(), track.beta()); + + registryParticleQA.fill(HIST("TrackQA/Before/Pion/fNsigmaITS"), track.p(), track.itsNSigmaPi()); + registryParticleQA.fill(HIST("TrackQA/Before/Pion/fNsigmaTPC"), track.p(), track.tpcNSigmaPi()); + registryParticleQA.fill(HIST("TrackQA/Before/Pion/fNsigmaTOF"), track.p(), track.tofNSigmaPi()); + registryParticleQA.fill(HIST("TrackQA/Before/Pion/fNsigmaTPCTOF"), track.p(), RecoDecay::sqrtSumOfSquares(track.tpcNSigmaPi(), track.tofNSigmaPi())); + + registryParticleQA.fill(HIST("TrackQA/Before/Kaon/fNsigmaITS"), track.p(), track.itsNSigmaKa()); + registryParticleQA.fill(HIST("TrackQA/Before/Kaon/fNsigmaTPC"), track.p(), track.tpcNSigmaKa()); + registryParticleQA.fill(HIST("TrackQA/Before/Kaon/fNsigmaTOF"), track.p(), track.tofNSigmaKa()); + registryParticleQA.fill(HIST("TrackQA/Before/Kaon/fNsigmaTPCTOF"), track.p(), RecoDecay::sqrtSumOfSquares(track.tpcNSigmaKa(), track.tofNSigmaKa())); + + registryParticleQA.fill(HIST("TrackQA/Before/Proton/fNsigmaITS"), track.p(), track.itsNSigmaPr()); + registryParticleQA.fill(HIST("TrackQA/Before/Proton/fNsigmaTPC"), track.p(), track.tpcNSigmaPr()); + registryParticleQA.fill(HIST("TrackQA/Before/Proton/fNsigmaTOF"), track.p(), track.tofNSigmaPr()); + registryParticleQA.fill(HIST("TrackQA/Before/Proton/fNsigmaTPCTOF"), track.p(), RecoDecay::sqrtSumOfSquares(track.tpcNSigmaPr(), track.tofNSigmaPr())); + + registryParticleQA.fill(HIST("TrackQA/Before/Deuteron/fNsigmaITS"), track.p(), track.itsNSigmaDe()); + registryParticleQA.fill(HIST("TrackQA/Before/Deuteron/fNsigmaTPC"), track.p(), track.tpcNSigmaDe()); + registryParticleQA.fill(HIST("TrackQA/Before/Deuteron/fNsigmaTOF"), track.p(), track.tofNSigmaDe()); + registryParticleQA.fill(HIST("TrackQA/Before/Deuteron/fNsigmaTPCTOF"), track.p(), RecoDecay::sqrtSumOfSquares(track.tpcNSigmaDe(), track.tofNSigmaDe())); + + if (checkTrack(track, std::string("Pion")) && checkTrackPid(track, std::string("Pion"))) { + vecPion.emplace_back(track.pt(), track.eta(), track.phi(), o2::constants::physics::MassPionCharged); + idxPion.push_back(track.globalIndex()); + + registryParticleQA.fill(HIST("TrackQA/After/Pion/fPt"), track.pt()); + registryParticleQA.fill(HIST("TrackQA/After/Pion/fPTpc"), track.tpcInnerParam()); + registryParticleQA.fill(HIST("TrackQA/After/Pion/fMomCor"), track.p(), (track.tpcInnerParam() - track.p()) / track.p()); + registryParticleQA.fill(HIST("TrackQA/After/Pion/fEta"), track.eta()); + registryParticleQA.fill(HIST("TrackQA/After/Pion/fPhi"), track.phi()); + + registryParticleQA.fill(HIST("TrackQA/After/Pion/fNsigmaIts"), track.p(), track.itsNSigmaPi()); + registryParticleQA.fill(HIST("TrackQA/After/Pion/fNsigmaTpc"), track.p(), track.tpcNSigmaPi()); + registryParticleQA.fill(HIST("TrackQA/After/Pion/fNsigmaTof"), track.p(), track.tofNSigmaPi()); + registryParticleQA.fill(HIST("TrackQA/After/Pion/fNsigmaTpcTof"), track.p(), RecoDecay::sqrtSumOfSquares(track.tpcNSigmaPi(), track.tofNSigmaPi())); + + registryParticleQA.fill(HIST("TrackQA/After/Pion/fItsSignal"), track.p(), itsSignal(track)); + registryParticleQA.fill(HIST("TrackQA/After/Pion/fTpcSignal"), track.p(), track.tpcSignal()); + registryParticleQA.fill(HIST("TrackQA/After/Pion/fTofBeta"), track.p(), track.beta()); + + registryParticleQA.fill(HIST("TrackQA/After/Pion/fDcaXy"), track.pt(), track.dcaXY()); + registryParticleQA.fill(HIST("TrackQA/After/Pion/fDcaZ"), track.pt(), track.dcaZ()); + + registryParticleQA.fill(HIST("TrackQA/After/Pion/fTpcClusters"), track.tpcNClsFound()); + registryParticleQA.fill(HIST("TrackQA/After/Pion/fTpcCrossedRows"), track.tpcNClsCrossedRows()); + registryParticleQA.fill(HIST("TrackQA/After/Pion/fTpcSharedClusters"), track.tpcNClsShared()); + registryParticleQA.fill(HIST("TrackQA/After/Pion/fTpcSharedClusterOverClusterss"), track.tpcFractionSharedCls()); + registryParticleQA.fill(HIST("TrackQA/After/Pion/fTpcFindableOverRows"), track.tpcCrossedRowsOverFindableCls()); + registryParticleQA.fill(HIST("TrackQA/After/Pion/fTpcChi2OverCluster"), track.tpcChi2NCl()); + + registryParticleQA.fill(HIST("TrackQA/After/Pion/fItsClusters"), track.itsNCls()); + registryParticleQA.fill(HIST("TrackQA/After/Pion/fItsIbClusters"), track.itsNClsInnerBarrel()); + registryParticleQA.fill(HIST("TrackQA/After/Pion/fItsChi2OverCluster"), track.itsChi2NCl()); } - if (ConfUseAvgFromCCDB) { - TPCTOFAvg = setValuesAvg(bc, ConfAvgPath); - } - lastRunNumber = currentRunNumber; - } - } - - auto tracksWithItsPid = soa::Attach(tracks); - - registry.fill(HIST("fProcessedEvents"), 0); - registry.fill(HIST("EventCuts/fMultiplicityBefore"), col.multNTracksPV()); - registry.fill(HIST("EventCuts/fZvtxBefore"), col.posZ()); - bool keepEvent3N[CFTrigger::kNThreeBodyTriggers] = {false, false, false, false, false, false}; - int lowQ3Triplets[CFTrigger::kNThreeBodyTriggers] = {0, 0, 0, 0, 0, 0}; - - bool keepEvent2N[CFTrigger::kNTwoBodyTriggers] = {false, false}; - int lowKstarPairs[CFTrigger::kNTwoBodyTriggers] = {0, 0}; - - if (isSelectedEvent(col)) { - - registry.fill(HIST("EventCuts/fMultiplicityAfter"), col.multNTracksPV()); - registry.fill(HIST("EventCuts/fZvtxAfter"), col.posZ()); - - // keep track of proton indices - std::vector ProtonIndex = {}; - std::vector AntiProtonIndex = {}; - - // Prepare vectors for different species - std::vector protons, antiprotons, deuterons, antideuterons, lambdas, antilambdas, kaons, antikaons, phi, pions, antipions, rho; - - // create deuteron and proton vectors (and corresponding antiparticles) for pair and triplet creation - for (auto& track : tracksWithItsPid) { - - double nTPCSigmaP[3]{track.tpcNSigmaPr(), track.tpcNSigmaDe(), track.tpcNSigmaPi()}; - double nTPCSigmaN[3]{track.tpcNSigmaPr(), track.tpcNSigmaDe(), track.tpcNSigmaPi()}; - - if (ConfUseManualPIDproton) { - auto bgScalingProton = 1 / mMassProton; // momentum scaling? - if (BBProton.size() == 6) - nTPCSigmaP[0] = updatePID(track, bgScalingProton, BBProton); - if (BBAntiproton.size() == 6) - nTPCSigmaN[0] = updatePID(track, bgScalingProton, BBAntiproton); - } - if (ConfUseManualPIDdeuteron) { - auto bgScalingDeuteron = 1 / mMassDeuteron; // momentum scaling? - if (BBDeuteron.size() == 6) - nTPCSigmaP[1] = updatePID(track, bgScalingDeuteron, BBDeuteron); - if (BBAntideuteron.size() == 6) - nTPCSigmaN[1] = updatePID(track, bgScalingDeuteron, BBAntideuteron); + if (checkTrack(track, std::string("Kaon")) && checkTrackPid(track, std::string("Kaon"))) { + vecKaon.emplace_back(track.pt(), track.eta(), track.phi(), o2::constants::physics::MassKaonCharged); + idxKaon.push_back(track.globalIndex()); + + registryParticleQA.fill(HIST("TrackQA/After/Kaon/fPt"), track.pt()); + registryParticleQA.fill(HIST("TrackQA/After/Kaon/fPTpc"), track.tpcInnerParam()); + registryParticleQA.fill(HIST("TrackQA/After/Kaon/fMomCor"), track.p(), (track.tpcInnerParam() - track.p()) / track.p()); + registryParticleQA.fill(HIST("TrackQA/After/Kaon/fEta"), track.eta()); + registryParticleQA.fill(HIST("TrackQA/After/Kaon/fPhi"), track.phi()); + + registryParticleQA.fill(HIST("TrackQA/After/Kaon/fNsigmaIts"), track.p(), track.itsNSigmaKa()); + registryParticleQA.fill(HIST("TrackQA/After/Kaon/fNsigmaTpc"), track.p(), track.tpcNSigmaKa()); + registryParticleQA.fill(HIST("TrackQA/After/Kaon/fNsigmaTof"), track.p(), track.tofNSigmaKa()); + registryParticleQA.fill(HIST("TrackQA/After/Kaon/fNsigmaTpcTof"), track.p(), RecoDecay::sqrtSumOfSquares(track.tpcNSigmaKa(), track.tofNSigmaKa())); + + registryParticleQA.fill(HIST("TrackQA/After/Kaon/fItsSignal"), track.p(), itsSignal(track)); + registryParticleQA.fill(HIST("TrackQA/After/Kaon/fTpcSignal"), track.p(), track.tpcSignal()); + registryParticleQA.fill(HIST("TrackQA/After/Kaon/fTofBeta"), track.p(), track.beta()); + + registryParticleQA.fill(HIST("TrackQA/After/Kaon/fDcaXy"), track.pt(), track.dcaXY()); + registryParticleQA.fill(HIST("TrackQA/After/Kaon/fDcaZ"), track.pt(), track.dcaZ()); + + registryParticleQA.fill(HIST("TrackQA/After/Kaon/fTpcClusters"), track.tpcNClsFound()); + registryParticleQA.fill(HIST("TrackQA/After/Kaon/fTpcCrossedRows"), track.tpcNClsCrossedRows()); + registryParticleQA.fill(HIST("TrackQA/After/Kaon/fTpcSharedClusters"), track.tpcNClsShared()); + registryParticleQA.fill(HIST("TrackQA/After/Kaon/fTpcSharedClusterOverClusterss"), track.tpcFractionSharedCls()); + registryParticleQA.fill(HIST("TrackQA/After/Kaon/fTpcFindableOverRows"), track.tpcCrossedRowsOverFindableCls()); + registryParticleQA.fill(HIST("TrackQA/After/Kaon/fTpcChi2OverCluster"), track.tpcChi2NCl()); + + registryParticleQA.fill(HIST("TrackQA/After/Kaon/fItsClusters"), track.itsNCls()); + registryParticleQA.fill(HIST("TrackQA/After/Kaon/fItsIbClusters"), track.itsNClsInnerBarrel()); + registryParticleQA.fill(HIST("TrackQA/After/Kaon/fItsChi2OverCluster"), track.itsChi2NCl()); } - registry.fill(HIST("TrackCuts/TracksBefore/fPtTrackBefore"), track.pt()); - registry.fill(HIST("TrackCuts/TracksBefore/fEtaTrackBefore"), track.eta()); - registry.fill(HIST("TrackCuts/TracksBefore/fPhiTrackBefore"), track.phi()); - - if (track.sign() > 0) { - // Fill PID info - registry.fill(HIST("TrackCuts/TPCSignal/fTPCSignal"), track.tpcInnerParam(), track.tpcSignal()); - registry.fill(HIST("TrackCuts/TPCSignal/fTPCSignalP"), track.p(), track.tpcSignal()); - if (isSelectedTrack(track, CFTrigger::kProton)) { - registry.fill(HIST("TrackCuts/TPCSignal/fTPCSignalALLCUTS"), track.tpcInnerParam(), track.tpcSignal()); - registry.fill(HIST("TrackCuts/TPCSignal/fTPCSignalALLCUTSP"), track.p(), track.tpcSignal()); - registry.fill(HIST("TrackCuts/TracksBefore/fMomCorrelationAfterCutsPos"), track.p(), track.tpcInnerParam()); - } - registry.fill(HIST("TrackCuts/NSigmaBefore/fNsigmaTPCvsPProtonBefore"), track.tpcInnerParam(), nTPCSigmaP[0]); - registry.fill(HIST("TrackCuts/NSigmaBefore/fNsigmaTOFvsPProtonBefore"), track.tpcInnerParam(), track.tofNSigmaPr()); - registry.fill(HIST("TrackCuts/NSigmaBefore/fNsigmaTPCTOFvsPProtonBefore"), track.tpcInnerParam(), std::sqrt(std::pow(nTPCSigmaP[0] - TPCTOFAvg[0], 2) + std::pow(track.tofNSigmaPr() - TPCTOFAvg[1], 2))); - registry.fill(HIST("TrackCuts/NSigmaBefore/fNsigmaITSvsPProtonBefore"), track.p(), track.itsNSigmaPr()); - registry.fill(HIST("TrackCuts/NSigmaBefore/fNsigmaTPCvsPDeuteronBefore"), track.tpcInnerParam(), nTPCSigmaP[1]); - registry.fill(HIST("TrackCuts/NSigmaBefore/fNsigmaTOFvsPDeuteronBefore"), track.tpcInnerParam(), track.tofNSigmaDe()); - registry.fill(HIST("TrackCuts/NSigmaBefore/fNsigmaTPCTOFvsPDeuteronBefore"), track.tpcInnerParam(), std::sqrt(std::pow(nTPCSigmaP[1] - TPCTOFAvg[4], 2) + std::pow(track.tofNSigmaDe() - TPCTOFAvg[5], 2))); - registry.fill(HIST("TrackCuts/NSigmaBefore/fNsigmaITSvsPDeuteronBefore"), track.p(), track.itsNSigmaDe()); - registry.fill(HIST("TrackCuts/NSigmaBefore/fNsigmaTPCvsPDeuteronBeforeP"), track.p(), nTPCSigmaP[1]); - registry.fill(HIST("TrackCuts/TracksBefore/fMomCorrelationPos"), track.p(), track.tpcInnerParam()); - } - if (track.sign() < 0) { - - registry.fill(HIST("TrackCuts/TPCSignal/fTPCSignalAnti"), track.tpcInnerParam(), track.tpcSignal()); - registry.fill(HIST("TrackCuts/TPCSignal/fTPCSignalAntiP"), track.p(), track.tpcSignal()); - if (isSelectedTrack(track, CFTrigger::kProton)) { - registry.fill(HIST("TrackCuts/TPCSignal/fTPCSignalAntiALLCUTS"), track.tpcInnerParam(), track.tpcSignal()); - registry.fill(HIST("TrackCuts/TPCSignal/fTPCSignalAntiALLCUTSP"), track.p(), track.tpcSignal()); - registry.fill(HIST("TrackCuts/TracksBefore/fMomCorrelationAfterCutsNeg"), track.p(), track.tpcInnerParam()); - } - - registry.fill(HIST("TrackCuts/NSigmaBefore/fNsigmaTPCvsPAntiProtonBefore"), track.tpcInnerParam(), nTPCSigmaN[0]); - registry.fill(HIST("TrackCuts/NSigmaBefore/fNsigmaTOFvsPAntiProtonBefore"), track.tpcInnerParam(), track.tofNSigmaPr()); - registry.fill(HIST("TrackCuts/NSigmaBefore/fNsigmaTPCTOFvsPAntiProtonBefore"), track.tpcInnerParam(), std::sqrt(std::pow(nTPCSigmaN[0] - TPCTOFAvg[2], 2) + std::pow(track.tofNSigmaPr() - TPCTOFAvg[3], 2))); - registry.fill(HIST("TrackCuts/NSigmaBefore/fNsigmaITSvsPAntiProtonBefore"), track.p(), track.itsNSigmaPr()); - registry.fill(HIST("TrackCuts/NSigmaBefore/fNsigmaTPCvsPAntiDeuteronBefore"), track.tpcInnerParam(), nTPCSigmaN[1]); - registry.fill(HIST("TrackCuts/NSigmaBefore/fNsigmaTOFvsPAntiDeuteronBefore"), track.tpcInnerParam(), track.tofNSigmaDe()); - registry.fill(HIST("TrackCuts/NSigmaBefore/fNsigmaTPCTOFvsPAntiDeuteronBefore"), track.tpcInnerParam(), std::sqrt(std::pow(nTPCSigmaN[1] - TPCTOFAvg[6], 2) + std::pow(track.tofNSigmaDe() - TPCTOFAvg[7], 2))); - registry.fill(HIST("TrackCuts/NSigmaBefore/fNsigmaITSvsPAntiDeuteronBefore"), track.p(), track.itsNSigmaDe()); - registry.fill(HIST("TrackCuts/NSigmaBefore/fNsigmaTPCvsPAntiDeuteronBeforeP"), track.p(), nTPCSigmaN[1]); - registry.fill(HIST("TrackCuts/TracksBefore/fMomCorrelationNeg"), track.p(), track.tpcInnerParam()); + if (checkTrack(track, std::string("Proton")) && checkTrackPid(track, std::string("Proton"))) { + vecProton.emplace_back(track.pt(), track.eta(), track.phi(), o2::constants::physics::MassProton); + idxProton.push_back(track.globalIndex()); + + registryParticleQA.fill(HIST("TrackQA/After/Proton/fPt"), track.pt()); + registryParticleQA.fill(HIST("TrackQA/After/Proton/fPTpc"), track.tpcInnerParam()); + registryParticleQA.fill(HIST("TrackQA/After/Proton/fMomCor"), track.p(), (track.tpcInnerParam() - track.p()) / track.p()); + registryParticleQA.fill(HIST("TrackQA/After/Proton/fEta"), track.eta()); + registryParticleQA.fill(HIST("TrackQA/After/Proton/fPhi"), track.phi()); + + registryParticleQA.fill(HIST("TrackQA/After/Proton/fNsigmaIts"), track.p(), track.itsNSigmaPr()); + registryParticleQA.fill(HIST("TrackQA/After/Proton/fNsigmaTpc"), track.p(), track.tpcNSigmaPr()); + registryParticleQA.fill(HIST("TrackQA/After/Proton/fNsigmaTof"), track.p(), track.tofNSigmaPr()); + registryParticleQA.fill(HIST("TrackQA/After/Proton/fNsigmaTpcTof"), track.p(), RecoDecay::sqrtSumOfSquares(track.tpcNSigmaPr(), track.tofNSigmaPr())); + + registryParticleQA.fill(HIST("TrackQA/After/Proton/fItsSignal"), track.p(), itsSignal(track)); + registryParticleQA.fill(HIST("TrackQA/After/Proton/fTpcSignal"), track.p(), track.tpcSignal()); + registryParticleQA.fill(HIST("TrackQA/After/Proton/fTofBeta"), track.p(), track.beta()); + + registryParticleQA.fill(HIST("TrackQA/After/Proton/fDcaXy"), track.pt(), track.dcaXY()); + registryParticleQA.fill(HIST("TrackQA/After/Proton/fDcaZ"), track.pt(), track.dcaZ()); + + registryParticleQA.fill(HIST("TrackQA/After/Proton/fTpcClusters"), track.tpcNClsFound()); + registryParticleQA.fill(HIST("TrackQA/After/Proton/fTpcCrossedRows"), track.tpcNClsCrossedRows()); + registryParticleQA.fill(HIST("TrackQA/After/Proton/fTpcSharedClusters"), track.tpcNClsShared()); + registryParticleQA.fill(HIST("TrackQA/After/Proton/fTpcSharedClusterOverClusterss"), track.tpcFractionSharedCls()); + registryParticleQA.fill(HIST("TrackQA/After/Proton/fTpcFindableOverRows"), track.tpcCrossedRowsOverFindableCls()); + registryParticleQA.fill(HIST("TrackQA/After/Proton/fTpcChi2OverCluster"), track.tpcChi2NCl()); + + registryParticleQA.fill(HIST("TrackQA/After/Proton/fItsClusters"), track.itsNCls()); + registryParticleQA.fill(HIST("TrackQA/After/Proton/fItsIbClusters"), track.itsNClsInnerBarrel()); + registryParticleQA.fill(HIST("TrackQA/After/Proton/fItsChi2OverCluster"), track.itsChi2NCl()); } - // get protons - if (isSelectedTrack(track, CFTrigger::kProton)) { - ROOT::Math::PtEtaPhiMVector temp(track.pt(), track.eta(), track.phi(), mMassProton); - if (track.sign() > 0 && isSelectedTrackPID(track, CFTrigger::kProton, false, nTPCSigmaP, 1)) { - protons.push_back(temp); - ProtonIndex.push_back(track.globalIndex()); - - registry.fill(HIST("TrackCuts/TracksBefore/fMomCorrelationAfterCutsProton"), track.p(), track.tpcInnerParam()); - - registry.fill(HIST("TrackCuts/TPCSignal/fTPCSignalProton"), track.tpcInnerParam(), track.tpcSignal()); - registry.fill(HIST("TrackCuts/Proton/fPProton"), track.p()); - registry.fill(HIST("TrackCuts/Proton/fPTPCProton"), track.tpcInnerParam()); - registry.fill(HIST("TrackCuts/Proton/fPtProton"), track.pt()); - registry.fill(HIST("TrackCuts/Proton/fMomCorProtonDif"), track.p(), track.tpcInnerParam() - track.p()); - registry.fill(HIST("TrackCuts/Proton/fMomCorProtonRatio"), track.p(), (track.tpcInnerParam() - track.p()) / track.p()); - registry.fill(HIST("TrackCuts/Proton/fEtaProton"), track.eta()); - registry.fill(HIST("TrackCuts/Proton/fPhiProton"), track.phi()); - registry.fill(HIST("TrackCuts/Proton/fNsigmaTPCvsPProton"), track.tpcInnerParam(), nTPCSigmaP[0]); - registry.fill(HIST("TrackCuts/Proton/fNsigmaTOFvsPProton"), track.tpcInnerParam(), track.tofNSigmaPr()); - registry.fill(HIST("TrackCuts/Proton/fNsigmaTPCTOFvsPProton"), track.tpcInnerParam(), std::sqrt(std::pow(nTPCSigmaP[0] - TPCTOFAvg[0], 2) + std::pow(track.tofNSigmaPr() - TPCTOFAvg[1], 2))); - registry.fill(HIST("TrackCuts/Proton/fNsigmaITSvsPProton"), track.p(), track.itsNSigmaPr()); - - registry.fill(HIST("TrackCuts/Proton/fNsigmaTPCvsPProtonP"), track.p(), nTPCSigmaP[0]); - registry.fill(HIST("TrackCuts/Proton/fNsigmaTOFvsPProtonP"), track.p(), track.tofNSigmaPr()); - registry.fill(HIST("TrackCuts/Proton/fNsigmaTPCTOFvsPProtonP"), track.p(), std::sqrt(std::pow(nTPCSigmaP[0] - TPCTOFAvg[0], 2) + std::pow(track.tofNSigmaPr() - TPCTOFAvg[1], 2))); - - registry.fill(HIST("TrackCuts/Proton/fDCAxyProton"), track.dcaXY()); - registry.fill(HIST("TrackCuts/Proton/fDCAzProton"), track.dcaZ()); - registry.fill(HIST("TrackCuts/Proton/fTPCsClsProton"), track.tpcNClsShared()); - registry.fill(HIST("TrackCuts/Proton/fTPCcRowsProton"), track.tpcNClsCrossedRows()); - registry.fill(HIST("TrackCuts/Proton/fTrkTPCfClsProton"), track.tpcCrossedRowsOverFindableCls()); - registry.fill(HIST("TrackCuts/Proton/fTPCnclsProton"), track.tpcNClsFound()); - } - if (track.sign() < 0 && isSelectedTrackPID(track, CFTrigger::kProton, false, nTPCSigmaN, -1)) { - antiprotons.push_back(temp); - AntiProtonIndex.push_back(track.globalIndex()); - - registry.fill(HIST("TrackCuts/TracksBefore/fMomCorrelationAfterCutsAntiProton"), track.p(), track.tpcInnerParam()); - - registry.fill(HIST("TrackCuts/TPCSignal/fTPCSignalAntiProton"), track.tpcInnerParam(), track.tpcSignal()); - registry.fill(HIST("TrackCuts/AntiProton/fPtAntiProton"), track.pt()); - registry.fill(HIST("TrackCuts/AntiProton/fMomCorAntiProtonDif"), track.p(), track.tpcInnerParam() - track.p()); - registry.fill(HIST("TrackCuts/AntiProton/fMomCorAntiProtonRatio"), track.p(), (track.tpcInnerParam() - track.p()) / track.p()); - registry.fill(HIST("TrackCuts/AntiProton/fEtaAntiProton"), track.eta()); - registry.fill(HIST("TrackCuts/AntiProton/fPhiAntiProton"), track.phi()); - registry.fill(HIST("TrackCuts/AntiProton/fNsigmaTPCvsPAntiProton"), track.tpcInnerParam(), nTPCSigmaN[0]); - registry.fill(HIST("TrackCuts/AntiProton/fNsigmaTOFvsPAntiProton"), track.tpcInnerParam(), track.tofNSigmaPr()); - registry.fill(HIST("TrackCuts/AntiProton/fNsigmaTPCTOFvsPAntiProton"), track.tpcInnerParam(), std::sqrt(std::pow(nTPCSigmaN[0] - TPCTOFAvg[2], 2) + std::pow(track.tofNSigmaPr() - TPCTOFAvg[3], 2))); - registry.fill(HIST("TrackCuts/AntiProton/fNsigmaITSvsPAntiProton"), track.p(), track.itsNSigmaPr()); - - registry.fill(HIST("TrackCuts/AntiProton/fNsigmaTPCvsPAntiProtonP"), track.p(), nTPCSigmaN[0]); - registry.fill(HIST("TrackCuts/AntiProton/fNsigmaTOFvsPAntiProtonP"), track.p(), track.tofNSigmaPr()); - registry.fill(HIST("TrackCuts/AntiProton/fNsigmaTPCTOFvsPAntiProtonP"), track.p(), std::sqrt(std::pow(nTPCSigmaN[0] - TPCTOFAvg[2], 2) + std::pow(track.tofNSigmaPr() - TPCTOFAvg[3], 2))); - - registry.fill(HIST("TrackCuts/AntiProton/fDCAxyAntiProton"), track.dcaXY()); - registry.fill(HIST("TrackCuts/AntiProton/fDCAzAntiProton"), track.dcaZ()); - registry.fill(HIST("TrackCuts/AntiProton/fTPCsClsAntiProton"), track.tpcNClsShared()); - registry.fill(HIST("TrackCuts/AntiProton/fTPCcRowsAntiProton"), track.tpcNClsCrossedRows()); - registry.fill(HIST("TrackCuts/AntiProton/fTrkTPCfClsAntiProton"), track.tpcCrossedRowsOverFindableCls()); - registry.fill(HIST("TrackCuts/AntiProton/fTPCnclsAntiProton"), track.tpcNClsFound()); - } - } - // get deuterons - if (isSelectedTrack(track, CFTrigger::kDeuteron)) { - ROOT::Math::PtEtaPhiMVector temp(track.pt(), track.eta(), track.phi(), mMassDeuteron); - if (track.sign() > 0 && isSelectedTrackPID(track, CFTrigger::kDeuteron, ConfRejectNOTDeuteron.value, nTPCSigmaP, 1)) { - deuterons.push_back(temp); - - registry.fill(HIST("TrackCuts/TracksBefore/fMomCorrelationAfterCutsDeuteron"), track.p(), track.tpcInnerParam()); - - registry.fill(HIST("TrackCuts/TPCSignal/fTPCSignalDeuteron"), track.tpcInnerParam(), track.tpcSignal()); - registry.fill(HIST("TrackCuts/Deuteron/fPtDeuteron"), track.pt()); - registry.fill(HIST("TrackCuts/Deuteron/fMomCorDeuteronDif"), track.p(), track.tpcInnerParam() - track.p()); - registry.fill(HIST("TrackCuts/Deuteron/fMomCorDeuteronRatio"), track.p(), (track.tpcInnerParam() - track.p()) / track.p()); - registry.fill(HIST("TrackCuts/Deuteron/fEtaDeuteron"), track.eta()); - registry.fill(HIST("TrackCuts/Deuteron/fPhiDeuteron"), track.phi()); - registry.fill(HIST("TrackCuts/Deuteron/fNsigmaTPCvsPDeuteron"), track.tpcInnerParam(), nTPCSigmaP[1]); - registry.fill(HIST("TrackCuts/Deuteron/fNsigmaTOFvsPDeuteron"), track.tpcInnerParam(), track.tofNSigmaDe()); - registry.fill(HIST("TrackCuts/Deuteron/fNsigmaTPCTOFvsPDeuteron"), track.tpcInnerParam(), std::sqrt(std::pow(nTPCSigmaP[1] - TPCTOFAvg[4], 2) + std::pow(track.tofNSigmaDe() - TPCTOFAvg[5], 2))); - registry.fill(HIST("TrackCuts/Deuteron/fNsigmaITSvsPDeuteron"), track.p(), track.itsNSigmaDe()); - - registry.fill(HIST("TrackCuts/Deuteron/fNsigmaTPCvsPDeuteronP"), track.p(), nTPCSigmaP[1]); - registry.fill(HIST("TrackCuts/Deuteron/fNsigmaTOFvsPDeuteronP"), track.p(), track.tofNSigmaDe()); - registry.fill(HIST("TrackCuts/Deuteron/fNsigmaTPCTOFvsPDeuteronP"), track.p(), std::sqrt(std::pow(nTPCSigmaP[1] - TPCTOFAvg[4], 2) + std::pow(track.tofNSigmaDe() - TPCTOFAvg[5], 2))); - - registry.fill(HIST("TrackCuts/Deuteron/fDCAxyDeuteron"), track.dcaXY()); - registry.fill(HIST("TrackCuts/Deuteron/fDCAzDeuteron"), track.dcaZ()); - registry.fill(HIST("TrackCuts/Deuteron/fTPCsClsDeuteron"), track.tpcNClsShared()); - registry.fill(HIST("TrackCuts/Deuteron/fTPCcRowsDeuteron"), track.tpcNClsCrossedRows()); - registry.fill(HIST("TrackCuts/Deuteron/fTrkTPCfClsDeuteron"), track.tpcCrossedRowsOverFindableCls()); - registry.fill(HIST("TrackCuts/Deuteron/fTPCnclsDeuteron"), track.tpcNClsFound()); - } - if (track.sign() < 0 && isSelectedTrackPID(track, CFTrigger::kDeuteron, ConfRejectNOTDeuteron.value, nTPCSigmaN, -1)) { - antideuterons.push_back(temp); - - registry.fill(HIST("TrackCuts/TracksBefore/fMomCorrelationAfterCutsAntiDeuteron"), track.p(), track.tpcInnerParam()); - - registry.fill(HIST("TrackCuts/TPCSignal/fTPCSignalAntiDeuteron"), track.tpcInnerParam(), track.tpcSignal()); - registry.fill(HIST("TrackCuts/AntiDeuteron/fPtAntiDeuteron"), track.pt()); - registry.fill(HIST("TrackCuts/AntiDeuteron/fMomCorAntiDeuteronDif"), track.p(), track.tpcInnerParam() - track.p()); - registry.fill(HIST("TrackCuts/AntiDeuteron/fMomCorAntiDeuteronRatio"), track.p(), (track.tpcInnerParam() - track.p()) / track.p()); - registry.fill(HIST("TrackCuts/AntiDeuteron/fEtaAntiDeuteron"), track.eta()); - registry.fill(HIST("TrackCuts/AntiDeuteron/fPhiAntiDeuteron"), track.phi()); - registry.fill(HIST("TrackCuts/AntiDeuteron/fNsigmaTPCvsPAntiDeuteron"), track.tpcInnerParam(), nTPCSigmaN[1]); - registry.fill(HIST("TrackCuts/AntiDeuteron/fNsigmaTOFvsPAntiDeuteron"), track.tpcInnerParam(), track.tofNSigmaDe()); - registry.fill(HIST("TrackCuts/AntiDeuteron/fNsigmaTPCTOFvsPAntiDeuteron"), track.tpcInnerParam(), std::sqrt(std::pow(nTPCSigmaN[1] - TPCTOFAvg[6], 2) + std::pow(track.tofNSigmaDe() - TPCTOFAvg[7], 2))); - registry.fill(HIST("TrackCuts/AntiDeuteron/fNsigmaITSvsPAntiDeuteron"), track.p(), track.itsNSigmaDe()); - - registry.fill(HIST("TrackCuts/AntiDeuteron/fNsigmaTPCvsPAntiDeuteronP"), track.p(), nTPCSigmaN[1]); - registry.fill(HIST("TrackCuts/AntiDeuteron/fNsigmaTOFvsPAntiDeuteronP"), track.p(), track.tofNSigmaDe()); - registry.fill(HIST("TrackCuts/AntiDeuteron/fNsigmaTPCTOFvsPAntiDeuteronP"), track.p(), std::sqrt(std::pow(nTPCSigmaN[1] - TPCTOFAvg[6], 2) + std::pow(track.tofNSigmaDe() - TPCTOFAvg[7], 2))); - - registry.fill(HIST("TrackCuts/AntiDeuteron/fDCAxyAntiDeuteron"), track.dcaXY()); - registry.fill(HIST("TrackCuts/AntiDeuteron/fDCAzAntiDeuteron"), track.dcaZ()); - registry.fill(HIST("TrackCuts/AntiDeuteron/fTPCsClsAntiDeuteron"), track.tpcNClsShared()); - registry.fill(HIST("TrackCuts/AntiDeuteron/fTPCcRowsAntiDeuteron"), track.tpcNClsCrossedRows()); - registry.fill(HIST("TrackCuts/AntiDeuteron/fTrkTPCfClsAntiDeuteron"), track.tpcCrossedRowsOverFindableCls()); - registry.fill(HIST("TrackCuts/AntiDeuteron/fTPCnclsAntiDeuteron"), track.tpcNClsFound()); - } - } - // get Kaons (Phi Daughters) - if (ConfTriggerSwitches->get("Switch", "ppPhi") > 0.) { - if (isSelectedTrackKaon(track)) { - ROOT::Math::PtEtaPhiMVector temp(track.pt(), track.eta(), track.phi(), mMassKaonPlus); - if (track.sign() > 0) { - temp.SetM(mMassKaonPlus); - kaons.push_back(temp); - registry.fill(HIST("TrackCuts/Phi/Before/PosDaughter/fP"), track.p()); - registry.fill(HIST("TrackCuts/Phi/Before/PosDaughter/fPTPC"), track.tpcInnerParam()); - registry.fill(HIST("TrackCuts/Phi/Before/PosDaughter/fPt"), track.pt()); - registry.fill(HIST("TrackCuts/Phi/Before/PosDaughter/fMomCorDif"), track.p(), track.tpcInnerParam() - track.p()); - registry.fill(HIST("TrackCuts/Phi/Before/PosDaughter/fMomCorRatio"), track.p(), (track.tpcInnerParam() - track.p()) / track.p()); - registry.fill(HIST("TrackCuts/Phi/Before/PosDaughter/fEta"), track.eta()); - registry.fill(HIST("TrackCuts/Phi/Before/PosDaughter/fPhi"), track.phi()); - registry.fill(HIST("TrackCuts/Phi/Before/PosDaughter/fNsigmaTPCvsP"), track.tpcInnerParam(), track.tpcNSigmaKa()); - registry.fill(HIST("TrackCuts/Phi/Before/PosDaughter/fNsigmaTOFvsP"), track.tpcInnerParam(), track.tofNSigmaKa()); - registry.fill(HIST("TrackCuts/Phi/Before/PosDaughter/fNsigmaTPCTOFvsP"), track.tpcInnerParam(), std::abs(std::sqrt(track.tpcNSigmaKa() * track.tpcNSigmaKa() + track.tofNSigmaKa() * track.tofNSigmaKa()))); - - registry.fill(HIST("TrackCuts/Phi/Before/PosDaughter/fDCAxy"), track.dcaXY()); - registry.fill(HIST("TrackCuts/Phi/Before/PosDaughter/fDCAz"), track.dcaZ()); - registry.fill(HIST("TrackCuts/Phi/Before/PosDaughter/fTPCsCls"), track.tpcNClsShared()); - registry.fill(HIST("TrackCuts/Phi/Before/PosDaughter/fTPCcRows"), track.tpcNClsCrossedRows()); - registry.fill(HIST("TrackCuts/Phi/Before/PosDaughter/fTrkTPCfCls"), track.tpcCrossedRowsOverFindableCls()); - registry.fill(HIST("TrackCuts/Phi/Before/PosDaughter/fTPCncls"), track.tpcNClsFound()); - } - if (track.sign() < 0) { - temp.SetM(mMassKaonMinus); - antikaons.push_back(temp); - registry.fill(HIST("TrackCuts/Phi/Before/NegDaughter/fP"), track.p()); - registry.fill(HIST("TrackCuts/Phi/Before/NegDaughter/fPTPC"), track.tpcInnerParam()); - registry.fill(HIST("TrackCuts/Phi/Before/NegDaughter/fPt"), track.pt()); - registry.fill(HIST("TrackCuts/Phi/Before/NegDaughter/fMomCorDif"), track.p(), track.tpcInnerParam() - track.p()); - registry.fill(HIST("TrackCuts/Phi/Before/NegDaughter/fMomCorRatio"), track.p(), (track.tpcInnerParam() - track.p()) / track.p()); - registry.fill(HIST("TrackCuts/Phi/Before/NegDaughter/fEta"), track.eta()); - registry.fill(HIST("TrackCuts/Phi/Before/NegDaughter/fPhi"), track.phi()); - registry.fill(HIST("TrackCuts/Phi/Before/NegDaughter/fNsigmaTPCvsP"), track.tpcInnerParam(), track.tpcNSigmaKa()); - registry.fill(HIST("TrackCuts/Phi/Before/NegDaughter/fNsigmaTOFvsP"), track.tpcInnerParam(), track.tofNSigmaKa()); - registry.fill(HIST("TrackCuts/Phi/Before/NegDaughter/fNsigmaTPCTOFvsP"), track.tpcInnerParam(), std::abs(std::sqrt(track.tpcNSigmaKa() * track.tpcNSigmaKa() + track.tofNSigmaKa() * track.tofNSigmaKa()))); - - registry.fill(HIST("TrackCuts/Phi/Before/NegDaughter/fDCAxy"), track.dcaXY()); - registry.fill(HIST("TrackCuts/Phi/Before/NegDaughter/fDCAz"), track.dcaZ()); - registry.fill(HIST("TrackCuts/Phi/Before/NegDaughter/fTPCsCls"), track.tpcNClsShared()); - registry.fill(HIST("TrackCuts/Phi/Before/NegDaughter/fTPCcRows"), track.tpcNClsCrossedRows()); - registry.fill(HIST("TrackCuts/Phi/Before/NegDaughter/fTrkTPCfCls"), track.tpcCrossedRowsOverFindableCls()); - registry.fill(HIST("TrackCuts/Phi/Before/NegDaughter/fTPCncls"), track.tpcNClsFound()); - } - } - } - // get pions - if (isSelectedTrack(track, CFTrigger::kPion)) { - ROOT::Math::PtEtaPhiMVector temp(track.pt(), track.eta(), track.phi(), mMassPion); - if (track.sign() > 0 && isSelectedTrackPID(track, CFTrigger::kPion, false, nTPCSigmaP, 1)) { - pions.push_back(temp); - - registry.fill(HIST("TrackCuts/TracksBefore/fMomCorrelationAfterCutsPion"), track.p(), track.tpcInnerParam()); - - registry.fill(HIST("TrackCuts/TPCSignal/fTPCSignalPion"), track.tpcInnerParam(), track.tpcSignal()); - registry.fill(HIST("TrackCuts/Pion/fPPion"), track.p()); - registry.fill(HIST("TrackCuts/Pion/fPTPCPion"), track.tpcInnerParam()); - registry.fill(HIST("TrackCuts/Pion/fPtPion"), track.pt()); - registry.fill(HIST("TrackCuts/Pion/fMomCorPionDif"), track.p(), track.tpcInnerParam() - track.p()); - registry.fill(HIST("TrackCuts/Pion/fMomCorPionRatio"), track.p(), (track.tpcInnerParam() - track.p()) / track.p()); - registry.fill(HIST("TrackCuts/Pion/fEtaPion"), track.eta()); - registry.fill(HIST("TrackCuts/Pion/fPhiPion"), track.phi()); - registry.fill(HIST("TrackCuts/Pion/fNsigmaTPCvsPPion"), track.tpcInnerParam(), nTPCSigmaP[2]); - registry.fill(HIST("TrackCuts/Pion/fNsigmaTOFvsPPion"), track.tpcInnerParam(), track.tofNSigmaPi()); - registry.fill(HIST("TrackCuts/Pion/fNsigmaTPCTOFvsPPion"), track.tpcInnerParam(), std::sqrt(std::pow(nTPCSigmaP[2] - TPCTOFAvg[8], 2) + std::pow(track.tofNSigmaPi() - TPCTOFAvg[9], 2))); - - registry.fill(HIST("TrackCuts/Pion/fNsigmaTPCvsPPionP"), track.p(), nTPCSigmaP[2]); - registry.fill(HIST("TrackCuts/Pion/fNsigmaTOFvsPPionP"), track.p(), track.tofNSigmaPi()); - registry.fill(HIST("TrackCuts/Pion/fNsigmaTPCTOFvsPPionP"), track.p(), std::sqrt(std::pow(nTPCSigmaP[2] - TPCTOFAvg[8], 2) + std::pow(track.tofNSigmaPi() - TPCTOFAvg[9], 2))); - - registry.fill(HIST("TrackCuts/Pion/fDCAxyPion"), track.dcaXY()); - registry.fill(HIST("TrackCuts/Pion/fDCAzPion"), track.dcaZ()); - registry.fill(HIST("TrackCuts/Pion/fTPCsClsPion"), track.tpcNClsShared()); - registry.fill(HIST("TrackCuts/Pion/fTPCcRowsPion"), track.tpcNClsCrossedRows()); - registry.fill(HIST("TrackCuts/Pion/fTrkTPCfClsPion"), track.tpcCrossedRowsOverFindableCls()); - registry.fill(HIST("TrackCuts/Pion/fTPCnclsPion"), track.tpcNClsFound()); - } - if (track.sign() < 0 && isSelectedTrackPID(track, CFTrigger::kPion, false, nTPCSigmaN, -1)) { - antipions.push_back(temp); - - registry.fill(HIST("TrackCuts/TracksBefore/fMomCorrelationAfterCutsAntiPion"), track.p(), track.tpcInnerParam()); - - registry.fill(HIST("TrackCuts/TPCSignal/fTPCSignalAntiPion"), track.tpcInnerParam(), track.tpcSignal()); - registry.fill(HIST("TrackCuts/AntiPion/fPtAntiPion"), track.pt()); - registry.fill(HIST("TrackCuts/AntiPion/fMomCorAntiPionDif"), track.p(), track.tpcInnerParam() - track.p()); - registry.fill(HIST("TrackCuts/AntiPion/fMomCorAntiPionRatio"), track.p(), (track.tpcInnerParam() - track.p()) / track.p()); - registry.fill(HIST("TrackCuts/AntiPion/fEtaAntiPion"), track.eta()); - registry.fill(HIST("TrackCuts/AntiPion/fPhiAntiPion"), track.phi()); - registry.fill(HIST("TrackCuts/AntiPion/fNsigmaTPCvsPAntiPion"), track.tpcInnerParam(), nTPCSigmaN[2]); - registry.fill(HIST("TrackCuts/AntiPion/fNsigmaTOFvsPAntiPion"), track.tpcInnerParam(), track.tofNSigmaPi()); - registry.fill(HIST("TrackCuts/AntiPion/fNsigmaTPCTOFvsPAntiPion"), track.tpcInnerParam(), std::sqrt(std::pow(nTPCSigmaN[2] - TPCTOFAvg[10], 2) + std::pow(track.tofNSigmaPi() - TPCTOFAvg[11], 2))); - - registry.fill(HIST("TrackCuts/AntiPion/fNsigmaTPCvsPAntiPionP"), track.p(), nTPCSigmaN[2]); - registry.fill(HIST("TrackCuts/AntiPion/fNsigmaTOFvsPAntiPionP"), track.p(), track.tofNSigmaPi()); - registry.fill(HIST("TrackCuts/AntiPion/fNsigmaTPCTOFvsPAntiPionP"), track.p(), std::sqrt(std::pow(nTPCSigmaN[2] - TPCTOFAvg[10], 2) + std::pow(track.tofNSigmaPi() - TPCTOFAvg[11], 2))); - - registry.fill(HIST("TrackCuts/AntiPion/fDCAxyAntiPion"), track.dcaXY()); - registry.fill(HIST("TrackCuts/AntiPion/fDCAzAntiPion"), track.dcaZ()); - registry.fill(HIST("TrackCuts/AntiPion/fTPCsClsAntiPion"), track.tpcNClsShared()); - registry.fill(HIST("TrackCuts/AntiPion/fTPCcRowsAntiPion"), track.tpcNClsCrossedRows()); - registry.fill(HIST("TrackCuts/AntiPion/fTrkTPCfClsAntiPion"), track.tpcCrossedRowsOverFindableCls()); - registry.fill(HIST("TrackCuts/AntiPion/fTPCnclsAntiPion"), track.tpcNClsFound()); - } + if (checkTrack(track, std::string("Deuteron")) && checkTrackPid(track, std::string("Deuteron"))) { + vecDeuteron.emplace_back(track.pt(), track.eta(), track.phi(), o2::constants::physics::MassDeuteron); + idxDeuteron.push_back(track.globalIndex()); + + registryParticleQA.fill(HIST("TrackQA/After/Deuteron/fPt"), track.pt()); + registryParticleQA.fill(HIST("TrackQA/After/Deuteron/fPTpc"), track.tpcInnerParam()); + registryParticleQA.fill(HIST("TrackQA/After/Deuteron/fMomCor"), track.p(), (track.tpcInnerParam() - track.p()) / track.p()); + registryParticleQA.fill(HIST("TrackQA/After/Deuteron/fEta"), track.eta()); + registryParticleQA.fill(HIST("TrackQA/After/Deuteron/fPhi"), track.phi()); + + registryParticleQA.fill(HIST("TrackQA/After/Deuteron/fNsigmaIts"), track.p(), track.itsNSigmaDe()); + registryParticleQA.fill(HIST("TrackQA/After/Deuteron/fNsigmaTpc"), track.p(), track.tpcNSigmaDe()); + registryParticleQA.fill(HIST("TrackQA/After/Deuteron/fNsigmaTof"), track.p(), track.tofNSigmaDe()); + registryParticleQA.fill(HIST("TrackQA/After/Deuteron/fNsigmaTpcTof"), track.p(), RecoDecay::sqrtSumOfSquares(track.tpcNSigmaDe(), track.tofNSigmaDe())); + + registryParticleQA.fill(HIST("TrackQA/After/Deuteron/fItsSignal"), track.p(), itsSignal(track)); + registryParticleQA.fill(HIST("TrackQA/After/Deuteron/fTpcSignal"), track.p(), track.tpcSignal()); + registryParticleQA.fill(HIST("TrackQA/After/Deuteron/fTofBeta"), track.p(), track.beta()); + + registryParticleQA.fill(HIST("TrackQA/After/Deuteron/fDcaXy"), track.pt(), track.dcaXY()); + registryParticleQA.fill(HIST("TrackQA/After/Deuteron/fDcaZ"), track.pt(), track.dcaZ()); + + registryParticleQA.fill(HIST("TrackQA/After/Deuteron/fTpcClusters"), track.tpcNClsFound()); + registryParticleQA.fill(HIST("TrackQA/After/Deuteron/fTpcCrossedRows"), track.tpcNClsCrossedRows()); + registryParticleQA.fill(HIST("TrackQA/After/Deuteron/fTpcSharedClusters"), track.tpcNClsShared()); + registryParticleQA.fill(HIST("TrackQA/After/Deuteron/fTpcSharedClusterOverClusterss"), track.tpcFractionSharedCls()); + registryParticleQA.fill(HIST("TrackQA/After/Deuteron/fTpcFindableOverRows"), track.tpcCrossedRowsOverFindableCls()); + registryParticleQA.fill(HIST("TrackQA/After/Deuteron/fTpcChi2OverCluster"), track.tpcChi2NCl()); + + registryParticleQA.fill(HIST("TrackQA/After/Deuteron/fItsClusters"), track.itsNCls()); + registryParticleQA.fill(HIST("TrackQA/After/Deuteron/fItsIbClusters"), track.itsNClsInnerBarrel()); + registryParticleQA.fill(HIST("TrackQA/After/Deuteron/fItsChi2OverCluster"), track.itsChi2NCl()); } } - // keep track of daugher indices to avoid selfcorrelations - std::vector LambdaPosDaughIndex = {}; - std::vector LambdaNegDaughIndex = {}; - std::vector AntiLambdaPosDaughIndex = {}; - std::vector AntiLambdaNegDaughIndex = {}; - - for (auto& v0 : fullV0s) { - - auto postrack = v0.template posTrack_as(); - auto negtrack = v0.template negTrack_as(); - double nTPCSigmaPos[2]{postrack.tpcNSigmaPr(), postrack.tpcNSigmaPi()}; - double nTPCSigmaNeg[2]{negtrack.tpcNSigmaPr(), negtrack.tpcNSigmaPi()}; - if (ConfUseManualPIDdaughterPion) { - auto bgScalingPion = 1 / mMassPion; // momentum scaling? - if (BBPion.size() == 6) - nTPCSigmaPos[1] = updatePID(postrack, bgScalingPion, BBPion); - if (BBAntipion.size() == 6) - nTPCSigmaNeg[1] = updatePID(negtrack, bgScalingPion, BBAntipion); + if (track.sign() < 0) { + registryParticleQA.fill(HIST("TrackQA/Before/AntiParticle/fPt"), track.pt()); + registryParticleQA.fill(HIST("TrackQA/Before/AntiParticle/fEta"), track.eta()); + registryParticleQA.fill(HIST("TrackQA/Before/AntiParticle/fPhi"), track.phi()); + registryParticleQA.fill(HIST("TrackQA/Before/AntiParticle/fMomCor"), track.p(), (track.tpcInnerParam() - track.p()) / track.p()); + registryParticleQA.fill(HIST("TrackQA/Before/AntiParticle/fItsSignal"), track.p(), itsSignal(track)); + registryParticleQA.fill(HIST("TrackQA/Before/AntiParticle/fTpcSignal"), track.p(), track.tpcSignal()); + registryParticleQA.fill(HIST("TrackQA/Before/AntiParticle/fTofSignal"), track.p(), track.beta()); + + registryParticleQA.fill(HIST("TrackQA/Before/AntiPion/fNsigmaITS"), track.p(), track.itsNSigmaPi()); + registryParticleQA.fill(HIST("TrackQA/Before/AntiPion/fNsigmaTPC"), track.p(), track.tpcNSigmaPi()); + registryParticleQA.fill(HIST("TrackQA/Before/AntiPion/fNsigmaTOF"), track.p(), track.tofNSigmaPi()); + registryParticleQA.fill(HIST("TrackQA/Before/AntiPion/fNsigmaTPCTOF"), track.p(), RecoDecay::sqrtSumOfSquares(track.tpcNSigmaPi(), track.tofNSigmaPi())); + + registryParticleQA.fill(HIST("TrackQA/Before/AntiKaon/fNsigmaITS"), track.p(), track.itsNSigmaKa()); + registryParticleQA.fill(HIST("TrackQA/Before/AntiKaon/fNsigmaTPC"), track.p(), track.tpcNSigmaKa()); + registryParticleQA.fill(HIST("TrackQA/Before/AntiKaon/fNsigmaTOF"), track.p(), track.tofNSigmaKa()); + registryParticleQA.fill(HIST("TrackQA/Before/AntiKaon/fNsigmaTPCTOF"), track.p(), RecoDecay::sqrtSumOfSquares(track.tpcNSigmaKa(), track.tofNSigmaKa())); + + registryParticleQA.fill(HIST("TrackQA/Before/AntiProton/fNsigmaITS"), track.p(), track.itsNSigmaPr()); + registryParticleQA.fill(HIST("TrackQA/Before/AntiProton/fNsigmaTPC"), track.p(), track.tpcNSigmaPr()); + registryParticleQA.fill(HIST("TrackQA/Before/AntiProton/fNsigmaTOF"), track.p(), track.tofNSigmaPr()); + registryParticleQA.fill(HIST("TrackQA/Before/AntiProton/fNsigmaTPCTOF"), track.p(), RecoDecay::sqrtSumOfSquares(track.tpcNSigmaPr(), track.tofNSigmaPr())); + + registryParticleQA.fill(HIST("TrackQA/Before/AntiDeuteron/fNsigmaITS"), track.p(), track.itsNSigmaDe()); + registryParticleQA.fill(HIST("TrackQA/Before/AntiDeuteron/fNsigmaTPC"), track.p(), track.tpcNSigmaDe()); + registryParticleQA.fill(HIST("TrackQA/Before/AntiDeuteron/fNsigmaTOF"), track.p(), track.tofNSigmaDe()); + registryParticleQA.fill(HIST("TrackQA/Before/AntiDeuteron/fNsigmaTPCTOF"), track.p(), RecoDecay::sqrtSumOfSquares(track.tpcNSigmaDe(), track.tofNSigmaDe())); + + if (checkTrack(track, std::string("Pion")) && checkTrackPid(track, std::string("Pion"))) { + vecAntiPion.emplace_back(track.pt(), track.eta(), track.phi(), o2::constants::physics::MassPionCharged); + idxAntiPion.push_back(track.globalIndex()); + + registryParticleQA.fill(HIST("TrackQA/After/AntiPion/fPt"), track.pt()); + registryParticleQA.fill(HIST("TrackQA/After/AntiPion/fPTpc"), track.tpcInnerParam()); + registryParticleQA.fill(HIST("TrackQA/After/AntiPion/fMomCor"), track.p(), (track.tpcInnerParam() - track.p()) / track.p()); + registryParticleQA.fill(HIST("TrackQA/After/AntiPion/fEta"), track.eta()); + registryParticleQA.fill(HIST("TrackQA/After/AntiPion/fPhi"), track.phi()); + + registryParticleQA.fill(HIST("TrackQA/After/AntiPion/fNsigmaIts"), track.p(), track.itsNSigmaPi()); + registryParticleQA.fill(HIST("TrackQA/After/AntiPion/fNsigmaTpc"), track.p(), track.tpcNSigmaPi()); + registryParticleQA.fill(HIST("TrackQA/After/AntiPion/fNsigmaTof"), track.p(), track.tofNSigmaPi()); + registryParticleQA.fill(HIST("TrackQA/After/AntiPion/fNsigmaTpcTof"), track.p(), RecoDecay::sqrtSumOfSquares(track.tpcNSigmaPi(), track.tofNSigmaPi())); + + registryParticleQA.fill(HIST("TrackQA/After/AntiPion/fItsSignal"), track.p(), itsSignal(track)); + registryParticleQA.fill(HIST("TrackQA/After/AntiPion/fTpcSignal"), track.p(), track.tpcSignal()); + registryParticleQA.fill(HIST("TrackQA/After/AntiPion/fTofBeta"), track.p(), track.beta()); + + registryParticleQA.fill(HIST("TrackQA/After/AntiPion/fDcaXy"), track.pt(), track.dcaXY()); + registryParticleQA.fill(HIST("TrackQA/After/AntiPion/fDcaZ"), track.pt(), track.dcaZ()); + + registryParticleQA.fill(HIST("TrackQA/After/AntiPion/fTpcClusters"), track.tpcNClsFound()); + registryParticleQA.fill(HIST("TrackQA/After/AntiPion/fTpcCrossedRows"), track.tpcNClsCrossedRows()); + registryParticleQA.fill(HIST("TrackQA/After/AntiPion/fTpcSharedClusters"), track.tpcNClsShared()); + registryParticleQA.fill(HIST("TrackQA/After/AntiPion/fTpcSharedClusterOverClusterss"), track.tpcFractionSharedCls()); + registryParticleQA.fill(HIST("TrackQA/After/AntiPion/fTpcFindableOverRows"), track.tpcCrossedRowsOverFindableCls()); + registryParticleQA.fill(HIST("TrackQA/After/AntiPion/fTpcChi2OverCluster"), track.tpcChi2NCl()); + + registryParticleQA.fill(HIST("TrackQA/After/AntiPion/fItsClusters"), track.itsNCls()); + registryParticleQA.fill(HIST("TrackQA/After/AntiPion/fItsIbClusters"), track.itsNClsInnerBarrel()); + registryParticleQA.fill(HIST("TrackQA/After/AntiPion/fItsChi2OverCluster"), track.itsChi2NCl()); } - if (ConfUseManualPIDdaughterProton) { - auto bgScalingProton = 1 / mMassProton; // momentum scaling? - if (BBProton.size() == 6) - nTPCSigmaPos[0] = updatePID(postrack, bgScalingProton, BBProton); - if (BBAntiproton.size() == 6) - nTPCSigmaNeg[0] = updatePID(negtrack, bgScalingProton, BBAntiproton); + + if (checkTrack(track, std::string("Kaon")) && checkTrackPid(track, std::string("Kaon"))) { + vecAntiKaon.emplace_back(track.pt(), track.eta(), track.phi(), o2::constants::physics::MassKaonCharged); + idxAntiKaon.push_back(track.globalIndex()); + + registryParticleQA.fill(HIST("TrackQA/After/AntiKaon/fPt"), track.pt()); + registryParticleQA.fill(HIST("TrackQA/After/AntiKaon/fPTpc"), track.tpcInnerParam()); + registryParticleQA.fill(HIST("TrackQA/After/AntiKaon/fMomCor"), track.p(), (track.tpcInnerParam() - track.p()) / track.p()); + registryParticleQA.fill(HIST("TrackQA/After/AntiKaon/fEta"), track.eta()); + registryParticleQA.fill(HIST("TrackQA/After/AntiKaon/fPhi"), track.phi()); + + registryParticleQA.fill(HIST("TrackQA/After/AntiKaon/fNsigmaIts"), track.p(), track.itsNSigmaKa()); + registryParticleQA.fill(HIST("TrackQA/After/AntiKaon/fNsigmaTpc"), track.p(), track.tpcNSigmaKa()); + registryParticleQA.fill(HIST("TrackQA/After/AntiKaon/fNsigmaTof"), track.p(), track.tofNSigmaKa()); + registryParticleQA.fill(HIST("TrackQA/After/AntiKaon/fNsigmaTpcTof"), track.p(), RecoDecay::sqrtSumOfSquares(track.tpcNSigmaKa(), track.tofNSigmaKa())); + + registryParticleQA.fill(HIST("TrackQA/After/AntiKaon/fItsSignal"), track.p(), itsSignal(track)); + registryParticleQA.fill(HIST("TrackQA/After/AntiKaon/fTpcSignal"), track.p(), track.tpcSignal()); + registryParticleQA.fill(HIST("TrackQA/After/AntiKaon/fTofBeta"), track.p(), track.beta()); + + registryParticleQA.fill(HIST("TrackQA/After/AntiKaon/fDcaXy"), track.pt(), track.dcaXY()); + registryParticleQA.fill(HIST("TrackQA/After/AntiKaon/fDcaZ"), track.pt(), track.dcaZ()); + + registryParticleQA.fill(HIST("TrackQA/After/AntiKaon/fTpcClusters"), track.tpcNClsFound()); + registryParticleQA.fill(HIST("TrackQA/After/AntiKaon/fTpcCrossedRows"), track.tpcNClsCrossedRows()); + registryParticleQA.fill(HIST("TrackQA/After/AntiKaon/fTpcSharedClusters"), track.tpcNClsShared()); + registryParticleQA.fill(HIST("TrackQA/After/AntiKaon/fTpcSharedClusterOverClusterss"), track.tpcFractionSharedCls()); + registryParticleQA.fill(HIST("TrackQA/After/AntiKaon/fTpcFindableOverRows"), track.tpcCrossedRowsOverFindableCls()); + registryParticleQA.fill(HIST("TrackQA/After/AntiKaon/fTpcChi2OverCluster"), track.tpcChi2NCl()); + + registryParticleQA.fill(HIST("TrackQA/After/AntiKaon/fItsClusters"), track.itsNCls()); + registryParticleQA.fill(HIST("TrackQA/After/AntiKaon/fItsIbClusters"), track.itsNClsInnerBarrel()); + registryParticleQA.fill(HIST("TrackQA/After/AntiKaon/fItsChi2OverCluster"), track.itsChi2NCl()); } - registry.fill(HIST("TrackCuts/V0Before/fPtLambdaBefore"), v0.pt()); - registry.fill(HIST("TrackCuts/V0Before/fInvMassLambdaBefore"), v0.mLambda()); - registry.fill(HIST("TrackCuts/V0Before/fInvMassAntiLambdaBefore"), v0.mAntiLambda()); - registry.fill(HIST("TrackCuts/V0Before/fInvMassLambdavsAntiLambda"), v0.mLambda(), v0.mAntiLambda()); - registry.fill(HIST("TrackCuts/V0Before/fInvMassV0BeforeKaonvsV0Before"), v0.mK0Short(), v0.mLambda()); - registry.fill(HIST("TrackCuts/V0Before/fV0DCADaugh"), v0.dcaV0daughters()); - registry.fill(HIST("TrackCuts/V0Before/fV0CPA"), v0.v0cosPA()); - registry.fill(HIST("TrackCuts/V0Before/fV0TranRad"), v0.v0radius()); - registry.fill(HIST("TrackCuts/V0Before/f0DecVtxX"), v0.x()); - registry.fill(HIST("TrackCuts/V0Before/f0DecVtxY"), v0.y()); - registry.fill(HIST("TrackCuts/V0Before/f0DecVtxZ"), v0.z()); - - registry.fill(HIST("TrackCuts/V0Before/PosDaughter/Eta"), postrack.eta()); - registry.fill(HIST("TrackCuts/V0Before/PosDaughter/DCAXY"), postrack.dcaXY()); - registry.fill(HIST("TrackCuts/V0Before/PosDaughter/fTPCncls"), postrack.tpcNClsFound()); - registry.fill(HIST("TrackCuts/V0Before/NegDaughter/Eta"), negtrack.eta()); - registry.fill(HIST("TrackCuts/V0Before/NegDaughter/DCAXY"), negtrack.dcaXY()); - registry.fill(HIST("TrackCuts/V0Before/NegDaughter/fTPCncls"), negtrack.tpcNClsFound()); - registry.fill(HIST("TrackCuts/V0Before/PosDaughter/fNsigmaTPCvsPProtonV0Daugh"), postrack.tpcInnerParam(), nTPCSigmaPos[0]); - registry.fill(HIST("TrackCuts/V0Before/NegDaughter/fNsigmaTPCvsPPionMinusV0Daugh"), negtrack.tpcInnerParam(), nTPCSigmaNeg[1]); - registry.fill(HIST("TrackCuts/V0Before/NegDaughter/fNsigmaTPCvsPAntiProtonV0Daugh"), negtrack.tpcInnerParam(), nTPCSigmaNeg[0]); - registry.fill(HIST("TrackCuts/V0Before/PosDaughter/fNsigmaTPCvsPPionPlusV0Daugh"), postrack.tpcInnerParam(), nTPCSigmaPos[1]); - - registry.fill(HIST("TrackCuts/NSigmaBefore/fNsigmaTPCvsPProtonV0DaughBefore"), postrack.tpcInnerParam(), nTPCSigmaPos[0]); - registry.fill(HIST("TrackCuts/NSigmaBefore/fNsigmaTPCvsPPionPlusAntiV0DaughBefore"), postrack.tpcInnerParam(), nTPCSigmaNeg[1]); - - registry.fill(HIST("TrackCuts/NSigmaBefore/fNsigmaTPCvsPPionMinusV0DaughBefore"), negtrack.tpcInnerParam(), nTPCSigmaNeg[1]); - registry.fill(HIST("TrackCuts/NSigmaBefore/fNsigmaTPCvsPAntiProtonAntiV0DaughBefore"), negtrack.tpcInnerParam(), nTPCSigmaNeg[0]); - - if (isSelectedMinimalV0(col, v0, postrack, negtrack, 1, nTPCSigmaPos, nTPCSigmaNeg)) { - ROOT::Math::PtEtaPhiMVector temp(v0.pt(), v0.eta(), v0.phi(), mMassLambda); - lambdas.push_back(temp); - LambdaPosDaughIndex.push_back(postrack.globalIndex()); - LambdaNegDaughIndex.push_back(negtrack.globalIndex()); - registry.fill(HIST("TrackCuts/TPCSignal/fTPCSignalProtonPlusV0Daughter"), postrack.tpcInnerParam(), postrack.tpcSignal()); - registry.fill(HIST("TrackCuts/TPCSignal/fTPCSignalPionMinusV0Daughter"), negtrack.tpcInnerParam(), negtrack.tpcSignal()); - registry.fill(HIST("TrackCuts/Lambda/fPtLambda"), v0.pt()); - registry.fill(HIST("TrackCuts/Lambda/fInvMassLambda"), v0.mLambda()); - registry.fill(HIST("TrackCuts/Lambda/fInvMassLambdaKaonvsLambda"), v0.mK0Short(), v0.mLambda()); - registry.fill(HIST("TrackCuts/Lambda/fV0DCADaugh"), v0.dcaV0daughters()); - registry.fill(HIST("TrackCuts/Lambda/fV0CPA"), v0.v0cosPA()); - registry.fill(HIST("TrackCuts/Lambda/fV0TranRad"), v0.v0radius()); - registry.fill(HIST("TrackCuts/Lambda/f0DecVtxX"), v0.x()); - registry.fill(HIST("TrackCuts/Lambda/f0DecVtxY"), v0.y()); - registry.fill(HIST("TrackCuts/Lambda/f0DecVtxZ"), v0.z()); - - registry.fill(HIST("TrackCuts/Lambda/PosDaughter/Eta"), postrack.eta()); - registry.fill(HIST("TrackCuts/Lambda/PosDaughter/DCAXY"), postrack.dcaXY()); - registry.fill(HIST("TrackCuts/Lambda/PosDaughter/fTPCncls"), postrack.tpcNClsFound()); - registry.fill(HIST("TrackCuts/Lambda/NegDaughter/Eta"), negtrack.eta()); - registry.fill(HIST("TrackCuts/Lambda/NegDaughter/DCAXY"), negtrack.dcaXY()); - registry.fill(HIST("TrackCuts/Lambda/NegDaughter/fTPCncls"), negtrack.tpcNClsFound()); - registry.fill(HIST("TrackCuts/Lambda/PosDaughter/fNsigmaTPCvsPProtonV0Daugh"), postrack.tpcInnerParam(), nTPCSigmaPos[0]); - registry.fill(HIST("TrackCuts/Lambda/NegDaughter/fNsigmaTPCvsPPionMinusV0Daugh"), negtrack.tpcInnerParam(), nTPCSigmaNeg[1]); + + if (checkTrack(track, std::string("Proton")) && checkTrackPid(track, std::string("Proton"))) { + vecAntiProton.emplace_back(track.pt(), track.eta(), track.phi(), o2::constants::physics::MassProton); + idxAntiProton.push_back(track.globalIndex()); + + registryParticleQA.fill(HIST("TrackQA/After/AntiProton/fPt"), track.pt()); + registryParticleQA.fill(HIST("TrackQA/After/AntiProton/fPTpc"), track.tpcInnerParam()); + registryParticleQA.fill(HIST("TrackQA/After/AntiProton/fMomCor"), track.p(), (track.tpcInnerParam() - track.p()) / track.p()); + registryParticleQA.fill(HIST("TrackQA/After/AntiProton/fEta"), track.eta()); + registryParticleQA.fill(HIST("TrackQA/After/AntiProton/fPhi"), track.phi()); + + registryParticleQA.fill(HIST("TrackQA/After/AntiProton/fNsigmaIts"), track.p(), track.itsNSigmaPr()); + registryParticleQA.fill(HIST("TrackQA/After/AntiProton/fNsigmaTpc"), track.p(), track.tpcNSigmaPr()); + registryParticleQA.fill(HIST("TrackQA/After/AntiProton/fNsigmaTof"), track.p(), track.tofNSigmaPr()); + registryParticleQA.fill(HIST("TrackQA/After/AntiProton/fNsigmaTpcTof"), track.p(), RecoDecay::sqrtSumOfSquares(track.tpcNSigmaPr(), track.tofNSigmaPr())); + + registryParticleQA.fill(HIST("TrackQA/After/AntiProton/fItsSignal"), track.p(), itsSignal(track)); + registryParticleQA.fill(HIST("TrackQA/After/AntiProton/fTpcSignal"), track.p(), track.tpcSignal()); + registryParticleQA.fill(HIST("TrackQA/After/AntiProton/fTofBeta"), track.p(), track.beta()); + + registryParticleQA.fill(HIST("TrackQA/After/AntiProton/fDcaXy"), track.pt(), track.dcaXY()); + registryParticleQA.fill(HIST("TrackQA/After/AntiProton/fDcaZ"), track.pt(), track.dcaZ()); + + registryParticleQA.fill(HIST("TrackQA/After/AntiProton/fTpcClusters"), track.tpcNClsFound()); + registryParticleQA.fill(HIST("TrackQA/After/AntiProton/fTpcCrossedRows"), track.tpcNClsCrossedRows()); + registryParticleQA.fill(HIST("TrackQA/After/AntiProton/fTpcSharedClusters"), track.tpcNClsShared()); + registryParticleQA.fill(HIST("TrackQA/After/AntiProton/fTpcSharedClusterOverClusterss"), track.tpcFractionSharedCls()); + registryParticleQA.fill(HIST("TrackQA/After/AntiProton/fTpcFindableOverRows"), track.tpcCrossedRowsOverFindableCls()); + registryParticleQA.fill(HIST("TrackQA/After/AntiProton/fTpcChi2OverCluster"), track.tpcChi2NCl()); + + registryParticleQA.fill(HIST("TrackQA/After/AntiProton/fItsClusters"), track.itsNCls()); + registryParticleQA.fill(HIST("TrackQA/After/AntiProton/fItsIbClusters"), track.itsNClsInnerBarrel()); + registryParticleQA.fill(HIST("TrackQA/After/AntiProton/fItsChi2OverCluster"), track.itsChi2NCl()); } - if (isSelectedMinimalV0(col, v0, postrack, negtrack, -1, nTPCSigmaPos, nTPCSigmaNeg)) { - ROOT::Math::PtEtaPhiMVector temp(v0.pt(), v0.eta(), v0.phi(), mMassLambda); - antilambdas.push_back(temp); - AntiLambdaPosDaughIndex.push_back(postrack.globalIndex()); - AntiLambdaNegDaughIndex.push_back(negtrack.globalIndex()); - registry.fill(HIST("TrackCuts/TPCSignal/fTPCSignalPionPlusV0Daughter"), postrack.tpcInnerParam(), postrack.tpcSignal()); - registry.fill(HIST("TrackCuts/TPCSignal/fTPCSignalProtonMinusV0Daughter"), negtrack.tpcInnerParam(), negtrack.tpcSignal()); - registry.fill(HIST("TrackCuts/AntiLambda/fPtAntiLambda"), v0.pt()); - registry.fill(HIST("TrackCuts/AntiLambda/fInvMassAntiLambda"), v0.mAntiLambda()); - registry.fill(HIST("TrackCuts/AntiLambda/fInvMassAntiLambdaKaonvsAntiLambda"), v0.mK0Short(), v0.mAntiLambda()); - registry.fill(HIST("TrackCuts/AntiLambda/fV0DCADaugh"), v0.dcaV0daughters()); - registry.fill(HIST("TrackCuts/AntiLambda/fV0CPA"), v0.v0cosPA()); - registry.fill(HIST("TrackCuts/AntiLambda/fV0TranRad"), v0.v0radius()); - registry.fill(HIST("TrackCuts/AntiLambda/f0DecVtxX"), v0.x()); - registry.fill(HIST("TrackCuts/AntiLambda/f0DecVtxY"), v0.y()); - registry.fill(HIST("TrackCuts/AntiLambda/f0DecVtxZ"), v0.z()); - - registry.fill(HIST("TrackCuts/AntiLambda/PosDaughter/Eta"), postrack.eta()); - registry.fill(HIST("TrackCuts/AntiLambda/PosDaughter/DCAXY"), postrack.dcaXY()); - registry.fill(HIST("TrackCuts/AntiLambda/PosDaughter/fTPCncls"), postrack.tpcNClsFound()); - registry.fill(HIST("TrackCuts/AntiLambda/NegDaughter/Eta"), negtrack.eta()); - registry.fill(HIST("TrackCuts/AntiLambda/NegDaughter/DCAXY"), negtrack.dcaXY()); - registry.fill(HIST("TrackCuts/AntiLambda/NegDaughter/fTPCncls"), negtrack.tpcNClsFound()); - registry.fill(HIST("TrackCuts/AntiLambda/NegDaughter/fNsigmaTPCvsPAntiProtonAntiV0Daugh"), negtrack.tpcInnerParam(), nTPCSigmaNeg[0]); - registry.fill(HIST("TrackCuts/AntiLambda/PosDaughter/fNsigmaTPCvsPPionPlusAntiV0Daugh"), postrack.tpcInnerParam(), nTPCSigmaPos[1]); + + if (checkTrack(track, std::string("Deuteron")) && checkTrackPid(track, std::string("Deuteron"))) { + vecAntiDeuteron.emplace_back(track.pt(), track.eta(), track.phi(), o2::constants::physics::MassDeuteron); + idxAntiDeuteron.push_back(track.globalIndex()); + + registryParticleQA.fill(HIST("TrackQA/After/AntiDeuteron/fPt"), track.pt()); + registryParticleQA.fill(HIST("TrackQA/After/AntiDeuteron/fPTpc"), track.tpcInnerParam()); + registryParticleQA.fill(HIST("TrackQA/After/AntiDeuteron/fMomCor"), track.p(), (track.tpcInnerParam() - track.p()) / track.p()); + registryParticleQA.fill(HIST("TrackQA/After/AntiDeuteron/fEta"), track.eta()); + registryParticleQA.fill(HIST("TrackQA/After/AntiDeuteron/fPhi"), track.phi()); + + registryParticleQA.fill(HIST("TrackQA/After/AntiDeuteron/fNsigmaIts"), track.p(), track.itsNSigmaDe()); + registryParticleQA.fill(HIST("TrackQA/After/AntiDeuteron/fNsigmaTpc"), track.p(), track.tpcNSigmaDe()); + registryParticleQA.fill(HIST("TrackQA/After/AntiDeuteron/fNsigmaTof"), track.p(), track.tofNSigmaDe()); + registryParticleQA.fill(HIST("TrackQA/After/AntiDeuteron/fNsigmaTpcTof"), track.p(), RecoDecay::sqrtSumOfSquares(track.tpcNSigmaDe(), track.tofNSigmaDe())); + + registryParticleQA.fill(HIST("TrackQA/After/AntiDeuteron/fItsSignal"), track.p(), itsSignal(track)); + registryParticleQA.fill(HIST("TrackQA/After/AntiDeuteron/fTpcSignal"), track.p(), track.tpcSignal()); + registryParticleQA.fill(HIST("TrackQA/After/AntiDeuteron/fTofBeta"), track.p(), track.beta()); + + registryParticleQA.fill(HIST("TrackQA/After/AntiDeuteron/fDcaXy"), track.pt(), track.dcaXY()); + registryParticleQA.fill(HIST("TrackQA/After/AntiDeuteron/fDcaZ"), track.pt(), track.dcaZ()); + + registryParticleQA.fill(HIST("TrackQA/After/AntiDeuteron/fTpcClusters"), track.tpcNClsFound()); + registryParticleQA.fill(HIST("TrackQA/After/AntiDeuteron/fTpcCrossedRows"), track.tpcNClsCrossedRows()); + registryParticleQA.fill(HIST("TrackQA/After/AntiDeuteron/fTpcSharedClusters"), track.tpcNClsShared()); + registryParticleQA.fill(HIST("TrackQA/After/AntiDeuteron/fTpcSharedClusterOverClusterss"), track.tpcFractionSharedCls()); + registryParticleQA.fill(HIST("TrackQA/After/AntiDeuteron/fTpcFindableOverRows"), track.tpcCrossedRowsOverFindableCls()); + registryParticleQA.fill(HIST("TrackQA/After/AntiDeuteron/fTpcChi2OverCluster"), track.tpcChi2NCl()); + + registryParticleQA.fill(HIST("TrackQA/After/AntiDeuteron/fItsClusters"), track.itsNCls()); + registryParticleQA.fill(HIST("TrackQA/After/AntiDeuteron/fItsIbClusters"), track.itsNClsInnerBarrel()); + registryParticleQA.fill(HIST("TrackQA/After/AntiDeuteron/fItsChi2OverCluster"), track.itsChi2NCl()); } } + } - if (ConfTriggerSwitches->get("Switch", "ppPhi") > 0.) { + // loop over and build v0s + for (auto const& v0 : v0s) { - for (const auto& postrack : kaons) { - for (const auto& negtrack : antikaons) { + auto posTrack = v0.posTrack_as(); + auto negTrack = v0.negTrack_as(); - ROOT::Math::PtEtaPhiMVector temp = postrack + negtrack; + auto posTrackPar = getTrackParCov(posTrack); + auto negTrackPar = getTrackParCov(negTrack); - registry.fill(HIST("TrackCuts/Phi/Before/fInvMass"), temp.M()); - registry.fill(HIST("TrackCuts/Phi/Before/fPt"), temp.pt()); - registry.fill(HIST("TrackCuts/Phi/Before/fEta"), temp.eta()); - registry.fill(HIST("TrackCuts/Phi/Before/fPhi"), translatePhi(temp.phi())); + if (!mStraHelper.buildV0Candidate(v0.collisionId(), col.posX(), col.posY(), col.posZ(), posTrack, negTrack, posTrackPar, negTrackPar, false, false, false)) { + continue; + } - if ((temp.M() >= PPPhi.ConfResoInvMassLowLimit.value) && (temp.M() <= PPPhi.ConfResoInvMassUpLimit.value)) { + float lambdaPt = RecoDecay::sqrtSumOfSquares(mStraHelper.v0.momentum[0], mStraHelper.v0.momentum[1]); + float lambdaPos = std::hypot(mStraHelper.v0.position[0] - col.posX(), mStraHelper.v0.position[1] - col.posY(), mStraHelper.v0.position[2] - col.posZ()); + float lambdaRadius = std::hypot(mStraHelper.v0.position[0], mStraHelper.v0.position[1]); + float lambdaEta = RecoDecay::eta(std::array{mStraHelper.v0.momentum[0], mStraHelper.v0.momentum[1], mStraHelper.v0.momentum[2]}); + float lambdaPhi = RecoDecay::phi(mStraHelper.v0.momentum[0], mStraHelper.v0.momentum[1]); + float lambdaCpa = std::cos(mStraHelper.v0.pointingAngle); + float lambdaDauDca = mStraHelper.v0.daughterDCA; + float lambdaMass = mStraHelper.v0.massLambda; + float antiLambdaMass = mStraHelper.v0.massAntiLambda; + float kaonMass = mStraHelper.v0.massK0Short; + + float posTrackEta = RecoDecay::eta(std::array{mStraHelper.v0.positiveMomentum[0], mStraHelper.v0.positiveMomentum[1], mStraHelper.v0.positiveMomentum[2]}); + float posTrackDca = mStraHelper.v0.positiveDCAxy; + float negTrackEta = RecoDecay::eta(std::array{mStraHelper.v0.negativeMomentum[0], mStraHelper.v0.negativeMomentum[1], mStraHelper.v0.negativeMomentum[2]}); + float negTrackDca = mStraHelper.v0.negativeDCAxy; + + registryParticleQA.fill(HIST("LambdaQA/Before/fPt"), lambdaPt); + registryParticleQA.fill(HIST("LambdaQA/Before/fEta"), lambdaEta); + registryParticleQA.fill(HIST("LambdaQA/Before/fPhi"), lambdaPhi); + registryParticleQA.fill(HIST("LambdaQA/Before/fInvMassLambda"), lambdaMass); + registryParticleQA.fill(HIST("LambdaQA/Before/fInvMassAntiLambda"), antiLambdaMass); + registryParticleQA.fill(HIST("LambdaQA/Before/fInvMassLambdaVsAntiLambda"), lambdaMass, antiLambdaMass); + registryParticleQA.fill(HIST("LambdaQA/Before/fInvMassLambdaVsKaon"), lambdaMass, kaonMass); + registryParticleQA.fill(HIST("LambdaQA/Before/fInvMassAntiLambdaVsKaon"), antiLambdaMass, kaonMass); + registryParticleQA.fill(HIST("LambdaQA/Before/fDcaDaugh"), lambdaDauDca); + registryParticleQA.fill(HIST("LambdaQA/Before/fCpa"), lambdaCpa); + registryParticleQA.fill(HIST("LambdaQA/Before/fTranRad"), lambdaRadius); + registryParticleQA.fill(HIST("LambdaQA/Before/fDecVtx"), lambdaPos); + + registryParticleQA.fill(HIST("LambdaQA/Before/PosDaughter/fPt"), posTrack.pt()); + registryParticleQA.fill(HIST("LambdaQA/Before/PosDaughter/fEta"), posTrackEta); + registryParticleQA.fill(HIST("LambdaQA/Before/PosDaughter/fPhi"), posTrack.phi()); + registryParticleQA.fill(HIST("LambdaQA/Before/PosDaughter/fDcaXy"), posTrack.pt(), posTrackDca); + registryParticleQA.fill(HIST("LambdaQA/Before/PosDaughter/fTpcClusters"), posTrack.tpcNClsFound()); + registryParticleQA.fill(HIST("LambdaQA/Before/PosDaughter/fNsigmaTpcProton"), posTrack.p(), posTrack.tpcNSigmaPr()); + registryParticleQA.fill(HIST("LambdaQA/Before/PosDaughter/fNsigmaTpcPion"), posTrack.p(), posTrack.tpcNSigmaPi()); + + registryParticleQA.fill(HIST("LambdaQA/Before/NegDaughter/fPt"), negTrack.pt()); + registryParticleQA.fill(HIST("LambdaQA/Before/NegDaughter/fEta"), negTrackEta); + registryParticleQA.fill(HIST("LambdaQA/Before/NegDaughter/fPhi"), negTrack.phi()); + registryParticleQA.fill(HIST("LambdaQA/Before/NegDaughter/fDcaXy"), negTrack.pt(), negTrackDca); + registryParticleQA.fill(HIST("LambdaQA/Before/NegDaughter/fTpcClusters"), negTrack.tpcNClsFound()); + registryParticleQA.fill(HIST("LambdaQA/Before/NegDaughter/fNsigmaTpcProton"), negTrack.p(), negTrack.tpcNSigmaPr()); + registryParticleQA.fill(HIST("LambdaQA/Before/NegDaughter/fNsigmaTpcPion"), negTrack.p(), negTrack.tpcNSigmaPi()); + + if (checkLambda(lambdaPt, lambdaDauDca, lambdaCpa, lambdaRadius, lambdaPos, kaonMass, lambdaMass) && checkLambdaDaughter(posTrack, posTrackEta, posTrackDca, posTrack.tpcNSigmaPr()) && checkLambdaDaughter(negTrack, negTrackEta, negTrackDca, negTrack.tpcNSigmaPi())) { + vecLambda.emplace_back(lambdaPt, lambdaEta, lambdaPhi, o2::constants::physics::MassLambda0); + idxLambdaDaughProton.push_back(posTrack.globalIndex()); + idxLambdaDaughPion.push_back(negTrack.globalIndex()); + + registryParticleQA.fill(HIST("LambdaQA/After/Lambda/fPt"), lambdaPt); + registryParticleQA.fill(HIST("LambdaQA/After/Lambda/fEta"), lambdaEta); + registryParticleQA.fill(HIST("LambdaQA/After/Lambda/fPhi"), lambdaPhi); + registryParticleQA.fill(HIST("LambdaQA/After/Lambda/fInvMass"), lambdaMass); + registryParticleQA.fill(HIST("LambdaQA/After/Lambda/fInvMassLambdaVsAntiLambda"), lambdaMass, antiLambdaMass); + registryParticleQA.fill(HIST("LambdaQA/After/Lambda/fInvMassLambdaVsKaon"), lambdaMass, kaonMass); + registryParticleQA.fill(HIST("LambdaQA/After/Lambda/fDcaDaugh"), lambdaDauDca); + registryParticleQA.fill(HIST("LambdaQA/After/Lambda/fCpa"), lambdaCpa); + registryParticleQA.fill(HIST("LambdaQA/After/Lambda/fTranRad"), lambdaRadius); + registryParticleQA.fill(HIST("LambdaQA/After/Lambda/fDecVtx"), lambdaPos); + + registryParticleQA.fill(HIST("LambdaQA/After/Lambda/PosDaughter/fPt"), posTrack.pt()); + registryParticleQA.fill(HIST("LambdaQA/After/Lambda/PosDaughter/fEta"), posTrackEta); + registryParticleQA.fill(HIST("LambdaQA/After/Lambda/PosDaughter/fPhi"), posTrack.phi()); + registryParticleQA.fill(HIST("LambdaQA/After/Lambda/PosDaughter/fDcaXy"), posTrack.pt(), posTrackDca); + registryParticleQA.fill(HIST("LambdaQA/After/Lambda/PosDaughter/fTpcClusters"), posTrack.tpcNClsFound()); + registryParticleQA.fill(HIST("LambdaQA/After/Lambda/PosDaughter/fNsigmaTpc"), posTrack.p(), posTrack.tpcNSigmaPr()); + + registryParticleQA.fill(HIST("LambdaQA/After/Lambda/NegDaughter/fPt"), negTrack.pt()); + registryParticleQA.fill(HIST("LambdaQA/After/Lambda/NegDaughter/fEta"), negTrackEta); + registryParticleQA.fill(HIST("LambdaQA/After/Lambda/NegDaughter/fPhi"), negTrack.phi()); + registryParticleQA.fill(HIST("LambdaQA/After/Lambda/NegDaughter/fDcaXy"), negTrack.pt(), negTrackDca); + registryParticleQA.fill(HIST("LambdaQA/After/Lambda/NegDaughter/fTpcClusters"), negTrack.tpcNClsFound()); + registryParticleQA.fill(HIST("LambdaQA/After/Lambda/NegDaughter/fNsigmaTpc"), negTrack.p(), negTrack.tpcNSigmaPi()); + } - phi.push_back(temp); + if (checkLambda(lambdaPt, lambdaDauDca, lambdaCpa, lambdaRadius, lambdaPos, kaonMass, antiLambdaMass) && checkLambdaDaughter(posTrack, posTrackEta, posTrackDca, posTrack.tpcNSigmaPi()) && checkLambdaDaughter(negTrack, negTrackEta, negTrackDca, negTrack.tpcNSigmaPr())) { + vecAntiLambda.emplace_back(lambdaPt, lambdaEta, lambdaPhi, o2::constants::physics::MassLambda0); + + idxAntiLambdaDaughProton.push_back(negTrack.globalIndex()); + idxAntiLambdaDaughPion.push_back(posTrack.globalIndex()); + + registryParticleQA.fill(HIST("LambdaQA/After/AntiLambda/fPt"), lambdaPt); + registryParticleQA.fill(HIST("LambdaQA/After/AntiLambda/fEta"), lambdaEta); + registryParticleQA.fill(HIST("LambdaQA/After/AntiLambda/fPhi"), lambdaPhi); + registryParticleQA.fill(HIST("LambdaQA/After/AntiLambda/fInvMass"), antiLambdaMass); + registryParticleQA.fill(HIST("LambdaQA/After/AntiLambda/fInvMassAntiLambdaVsLambda"), antiLambdaMass, lambdaMass); + registryParticleQA.fill(HIST("LambdaQA/After/AntiLambda/fInvMassAntiLambdaVsKaon"), antiLambdaMass, kaonMass); + registryParticleQA.fill(HIST("LambdaQA/After/AntiLambda/fDcaDaugh"), lambdaDauDca); + registryParticleQA.fill(HIST("LambdaQA/After/AntiLambda/fCpa"), lambdaCpa); + registryParticleQA.fill(HIST("LambdaQA/After/AntiLambda/fTranRad"), lambdaRadius); + registryParticleQA.fill(HIST("LambdaQA/After/AntiLambda/fDecVtx"), lambdaPos); + + registryParticleQA.fill(HIST("LambdaQA/After/AntiLambda/PosDaughter/fPt"), posTrack.pt()); + registryParticleQA.fill(HIST("LambdaQA/After/AntiLambda/PosDaughter/fEta"), posTrackEta); + registryParticleQA.fill(HIST("LambdaQA/After/AntiLambda/PosDaughter/fPhi"), posTrack.phi()); + registryParticleQA.fill(HIST("LambdaQA/After/AntiLambda/PosDaughter/fDcaXy"), posTrack.pt(), posTrackDca); + registryParticleQA.fill(HIST("LambdaQA/After/AntiLambda/PosDaughter/fTpcClusters"), posTrack.tpcNClsFound()); + registryParticleQA.fill(HIST("LambdaQA/After/AntiLambda/PosDaughter/fNsigmaTpc"), posTrack.p(), posTrack.tpcNSigmaPr()); + + registryParticleQA.fill(HIST("LambdaQA/After/AntiLambda/NegDaughter/fPt"), negTrack.pt()); + registryParticleQA.fill(HIST("LambdaQA/After/AntiLambda/NegDaughter/fEta"), negTrackEta); + registryParticleQA.fill(HIST("LambdaQA/After/AntiLambda/NegDaughter/fPhi"), negTrack.phi()); + registryParticleQA.fill(HIST("LambdaQA/After/AntiLambda/NegDaughter/fDcaXy"), negTrack.pt(), negTrackDca); + registryParticleQA.fill(HIST("LambdaQA/After/AntiLambda/NegDaughter/fTpcClusters"), negTrack.tpcNClsFound()); + registryParticleQA.fill(HIST("LambdaQA/After/AntiLambda/NegDaughter/fNsigmaTpc"), negTrack.p(), negTrack.tpcNSigmaPi()); + } + } - registry.fill(HIST("TrackCuts/Phi/After/fInvMass"), temp.M()); - registry.fill(HIST("TrackCuts/Phi/After/fPt"), temp.pt()); - registry.fill(HIST("TrackCuts/Phi/After/fEta"), temp.eta()); - registry.fill(HIST("TrackCuts/Phi/After/fPhi"), translatePhi(temp.phi())); + // build phi candidates + for (size_t k1 = 0; k1 < vecKaon.size(); k1++) { + for (size_t k2 = 0; k2 < vecAntiKaon.size(); k2++) { + ROOT::Math::PtEtaPhiMVector phi = vecKaon.at(k1) + vecAntiKaon.at(k2); + + registryParticleQA.fill(HIST("PhiQA/Before/fInvMass"), phi.M()); + registryParticleQA.fill(HIST("PhiQA/Before/fPt"), phi.Pt()); + registryParticleQA.fill(HIST("PhiQA/Before/fEta"), phi.Eta()); + registryParticleQA.fill(HIST("PhiQA/Before/fPhi"), RecoDecay::constrainAngle(phi.Phi())); + + if ((phi.M() >= PhiSelections.invMassLow.value) && + (phi.M() <= PhiSelections.invMassUp.value)) { + vecPhi.push_back(phi); + idxPhiDaughPos.push_back(idxKaon.at(k1)); + idxPhiDaughNeg.push_back(idxAntiKaon.at(k2)); + + registryParticleQA.fill(HIST("PhiQA/After/fInvMass"), phi.M()); + registryParticleQA.fill(HIST("PhiQA/After/fPt"), phi.Pt()); + registryParticleQA.fill(HIST("PhiQA/After/fEta"), phi.Eta()); + registryParticleQA.fill(HIST("PhiQA/After/fPhi"), RecoDecay::constrainAngle(phi.Phi())); + } + } + } - registry.fill(HIST("TrackCuts/Phi/After/PosDaughter/fPt"), postrack.pt()); - registry.fill(HIST("TrackCuts/Phi/After/PosDaughter/fEta"), postrack.eta()); - registry.fill(HIST("TrackCuts/Phi/After/PosDaughter/fPhi"), translatePhi(postrack.phi())); + // build rho candidates + for (size_t p1 = 0; p1 < vecPion.size(); p1++) { + for (size_t p2 = 0; p2 < vecAntiPion.size(); p2++) { + ROOT::Math::PtEtaPhiMVector rho = vecPion.at(p1) + vecAntiPion.at(p2); + + registryParticleQA.fill(HIST("RhoQA/Before/fInvMass"), rho.M()); + registryParticleQA.fill(HIST("RhoQA/Before/fPt"), rho.Pt()); + registryParticleQA.fill(HIST("RhoQA/Before/fEta"), rho.Eta()); + registryParticleQA.fill(HIST("RhoQA/Before/fPhi"), RecoDecay::constrainAngle(rho.Phi())); + + if (((rho.M() >= RhoSelections.invMassLow.value) && (rho.M() <= RhoSelections.invMassUp.value)) && (rho.Pt() >= RhoSelections.ptLow)) { + vecRho.push_back(rho); + idxRhoDaughPos.push_back(idxPion.at(p1)); + idxRhoDaughNeg.push_back(idxAntiPion.at(p2)); + + registryParticleQA.fill(HIST("RhoQA/After/fInvMass"), rho.M()); + registryParticleQA.fill(HIST("RhoQA/After/fPt"), rho.Pt()); + registryParticleQA.fill(HIST("RhoQA/After/fEta"), rho.Eta()); + registryParticleQA.fill(HIST("RhoQA/After/fPhi"), RecoDecay::constrainAngle(rho.Phi())); + } + } + } - registry.fill(HIST("TrackCuts/Phi/After/NegDaughter/fPt"), negtrack.pt()); - registry.fill(HIST("TrackCuts/Phi/After/NegDaughter/fEta"), negtrack.eta()); - registry.fill(HIST("TrackCuts/Phi/After/NegDaughter/fPhi"), translatePhi(negtrack.phi())); + float q3 = 999.f, kstar = 999.f; + + // PPP + if (TriggerSelections.filterSwitches->get("Switch", "PPP") > 0) { + for (size_t p1 = 0; p1 < vecProton.size(); p1++) { + for (size_t p2 = p1 + 1; p2 < vecProton.size(); p2++) { + for (size_t p3 = p2 + 1; p3 < vecProton.size(); p3++) { + q3 = getQ3(vecProton.at(p1), vecProton.at(p2), vecProton.at(p3)); + registryTriggerQA.fill(HIST("PPP/all/fMultiplicity"), col.multNTracksPV()); + registryTriggerQA.fill(HIST("PPP/all/fZvtx"), col.posZ()); + registryTriggerQA.fill(HIST("PPP/all/fSE_particle"), q3); + registryTriggerQA.fill(HIST("PPP/all/fProtonPtVsQ3"), vecProton.at(p1).Pt(), q3); + registryTriggerQA.fill(HIST("PPP/all/fProtonPtVsQ3"), vecProton.at(p2).Pt(), q3); + registryTriggerQA.fill(HIST("PPP/all/fProtonPtVsQ3"), vecProton.at(p3).Pt(), q3); + if (q3 < TriggerSelections.limits->get("Loose Limit", "PPP")) { + signalLooseLimit[cf_trigger::kPPP] += 1; + registryTriggerQA.fill(HIST("PPP/loose/fMultiplicity"), col.multNTracksPV()); + registryTriggerQA.fill(HIST("PPP/loose/fZvtx"), col.posZ()); + registryTriggerQA.fill(HIST("PPP/loose/fSE_particle"), q3); + registryTriggerQA.fill(HIST("PPP/loose/fProtonPtVsQ3"), vecProton.at(p1).Pt(), q3); + registryTriggerQA.fill(HIST("PPP/loose/fProtonPtVsQ3"), vecProton.at(p2).Pt(), q3); + registryTriggerQA.fill(HIST("PPP/loose/fProtonPtVsQ3"), vecProton.at(p3).Pt(), q3); + if (q3 < TriggerSelections.limits->get("Tight Limit", "PPP")) { + signalTightLimit[cf_trigger::kPPP] += 1; + registryTriggerQA.fill(HIST("PPP/tight/fMultiplicity"), col.multNTracksPV()); + registryTriggerQA.fill(HIST("PPP/tight/fZvtx"), col.posZ()); + registryTriggerQA.fill(HIST("PPP/tight/fSE_particle"), q3); + registryTriggerQA.fill(HIST("PPP/tight/fProtonPtVsQ3"), vecProton.at(p1).Pt(), q3); + registryTriggerQA.fill(HIST("PPP/tight/fProtonPtVsQ3"), vecProton.at(p2).Pt(), q3); + registryTriggerQA.fill(HIST("PPP/tight/fProtonPtVsQ3"), vecProton.at(p3).Pt(), q3); + } } } } } - - // construct rho cand - if (ConfTriggerSwitches->get("Switch", "ppRho") > 0.) { // here we could select on extra pion properties important for the Rho0Cands - - for (const auto& postrack : pions) { - for (const auto& negtrack : antipions) { - - ROOT::Math::PtEtaPhiMVector temp = postrack + negtrack; - - registry.fill(HIST("TrackCuts/Rho/Before/fInvMass"), temp.M()); - registry.fill(HIST("TrackCuts/Rho/Before/fPt"), temp.pt()); - registry.fill(HIST("TrackCuts/Rho/Before/fEta"), temp.eta()); - registry.fill(HIST("TrackCuts/Rho/Before/fPhi"), translatePhi(temp.phi())); - - registry.fill(HIST("TrackCuts/Rho/Before/PosDaughter/fInvMass"), postrack.M()); - registry.fill(HIST("TrackCuts/Rho/Before/PosDaughter/fPt"), postrack.pt()); - registry.fill(HIST("TrackCuts/Rho/Before/PosDaughter/fEta"), postrack.eta()); - registry.fill(HIST("TrackCuts/Rho/Before/PosDaughter/fPhi"), translatePhi(postrack.phi())); - - registry.fill(HIST("TrackCuts/Rho/Before/PosDaughter/fInvMass"), negtrack.M()); - registry.fill(HIST("TrackCuts/Rho/Before/NegDaughter/fPt"), negtrack.pt()); - registry.fill(HIST("TrackCuts/Rho/Before/NegDaughter/fEta"), negtrack.eta()); - registry.fill(HIST("TrackCuts/Rho/Before/NegDaughter/fPhi"), translatePhi(negtrack.phi())); - - if ((temp.M() >= PPRho.ConfResoRho0InvMassLowLimit.value) && (temp.M() <= PPRho.ConfResoRho0InvMassUpLimit.value) && (temp.pt() >= PPRho.ConfTrkPtRho0CandLowLimit.value) && (temp.pt() <= PPRho.ConfTrkPtRho0CandUpLimit.value)) { - - rho.push_back(temp); - - registry.fill(HIST("TrackCuts/Rho/After/fInvMass"), temp.M()); - registry.fill(HIST("TrackCuts/Rho/After/fPt"), temp.pt()); - registry.fill(HIST("TrackCuts/Rho/After/fEta"), temp.eta()); - registry.fill(HIST("TrackCuts/Rho/After/fPhi"), translatePhi(temp.phi())); - - registry.fill(HIST("TrackCuts/Rho/After/PosDaughter/fPt"), postrack.pt()); - registry.fill(HIST("TrackCuts/Rho/After/PosDaughter/fEta"), postrack.eta()); - registry.fill(HIST("TrackCuts/Rho/After/PosDaughter/fPhi"), translatePhi(postrack.phi())); - - registry.fill(HIST("TrackCuts/Rho/After/NegDaughter/fPt"), negtrack.pt()); - registry.fill(HIST("TrackCuts/Rho/After/NegDaughter/fEta"), negtrack.eta()); - registry.fill(HIST("TrackCuts/Rho/After/NegDaughter/fPhi"), translatePhi(negtrack.phi())); + for (size_t p1 = 0; p1 < vecAntiProton.size(); p1++) { + for (size_t p2 = p1 + 1; p2 < vecAntiProton.size(); p2++) { + for (size_t p3 = p2 + 1; p3 < vecAntiProton.size(); p3++) { + q3 = getQ3(vecAntiProton.at(p1), vecAntiProton.at(p2), vecAntiProton.at(p3)); + registryTriggerQA.fill(HIST("PPP/all/fMultiplicity"), col.multNTracksPV()); + registryTriggerQA.fill(HIST("PPP/all/fZvtx"), col.posZ()); + registryTriggerQA.fill(HIST("PPP/all/fSE_antiparticle"), q3); + registryTriggerQA.fill(HIST("PPP/all/fAntiProtonPtVsQ3"), vecAntiProton.at(p1).Pt(), q3); + registryTriggerQA.fill(HIST("PPP/all/fAntiProtonPtVsQ3"), vecAntiProton.at(p2).Pt(), q3); + registryTriggerQA.fill(HIST("PPP/all/fAntiProtonPtVsQ3"), vecAntiProton.at(p3).Pt(), q3); + if (q3 < TriggerSelections.limits->get("Loose Limit", "PPP")) { + signalLooseLimit[cf_trigger::kPPP] += 1; + registryTriggerQA.fill(HIST("PPP/loose/fMultiplicity"), col.multNTracksPV()); + registryTriggerQA.fill(HIST("PPP/loose/fZvtx"), col.posZ()); + registryTriggerQA.fill(HIST("PPP/loose/fSE_antiparticle"), q3); + registryTriggerQA.fill(HIST("PPP/loose/fAntiProtonPtVsQ3"), vecAntiProton.at(p1).Pt(), q3); + registryTriggerQA.fill(HIST("PPP/loose/fAntiProtonPtVsQ3"), vecAntiProton.at(p2).Pt(), q3); + registryTriggerQA.fill(HIST("PPP/loose/fAntiProtonPtVsQ3"), vecAntiProton.at(p3).Pt(), q3); + if (q3 < TriggerSelections.limits->get("Tight Limit", "PPP")) { + signalTightLimit[cf_trigger::kPPP] += 1; + registryTriggerQA.fill(HIST("PPP/tight/fMultiplicity"), col.multNTracksPV()); + registryTriggerQA.fill(HIST("PPP/tight/fZvtx"), col.posZ()); + registryTriggerQA.fill(HIST("PPP/tight/fSE_antiparticle"), q3); + registryTriggerQA.fill(HIST("PPP/tight/fAntiProtonPtVsQ3"), vecAntiProton.at(p1).Pt(), q3); + registryTriggerQA.fill(HIST("PPP/tight/fAntiProtonPtVsQ3"), vecAntiProton.at(p2).Pt(), q3); + registryTriggerQA.fill(HIST("PPP/tight/fAntiProtonPtVsQ3"), vecAntiProton.at(p3).Pt(), q3); + } } } } } - - float Q3 = 999.f, kstar = 999.f; - if (ConfTriggerSwitches->get("Switch", "ppp") > 0.) { - // ppp trigger - for (auto iProton1 = protons.begin(); iProton1 != protons.end(); ++iProton1) { - auto iProton2 = iProton1 + 1; - for (; iProton2 != protons.end(); ++iProton2) { - auto iProton3 = iProton2 + 1; - for (; iProton3 != protons.end(); ++iProton3) { - Q3 = getQ3(*iProton1, *iProton2, *iProton3); - registry.fill(HIST("ppp/fSE_particle"), Q3); - registry.fill(HIST("ppp/fProtonPtVsQ3"), Q3, (*iProton1).Pt()); - registry.fill(HIST("ppp/fProtonPtVsQ3"), Q3, (*iProton2).Pt()); - registry.fill(HIST("ppp/fProtonPtVsQ3"), Q3, (*iProton3).Pt()); - if (Q3 < ConfQ3Limits->get(static_cast(0), CFTrigger::kPPP)) { - if (ConfDownsample->get("Switch", "PPP") > 0) { - if (rng->Uniform(0., 1.) < ConfDownsample->get("Factor", "PPP")) { - registry.fill(HIST("ppp/fSE_particle_downsample"), Q3); - lowQ3Triplets[CFTrigger::kPPP] += 1; - } - } else { - lowQ3Triplets[CFTrigger::kPPP] += 1; - } + } + // PPL + if (TriggerSelections.filterSwitches->get("Switch", "PPL") > 0) { + for (size_t p1 = 0; p1 < vecProton.size(); p1++) { + for (size_t p2 = p1 + 1; p2 < vecProton.size(); p2++) { + for (size_t l1 = 0; l1 < vecLambda.size(); l1++) { + if (idxProton.at(p1) == idxLambdaDaughProton.at(l1) || idxProton.at(p2) == idxLambdaDaughProton.at(l1)) { + continue; + } + q3 = getQ3(vecProton.at(p1), vecProton.at(p2), vecLambda.at(l1)); + registryTriggerQA.fill(HIST("PPL/all/fMultiplicity"), col.multNTracksPV()); + registryTriggerQA.fill(HIST("PPL/all/fZvtx"), col.posZ()); + registryTriggerQA.fill(HIST("PPL/all/fSE_particle"), q3); + registryTriggerQA.fill(HIST("PPL/all/fProtonPtVsQ3"), vecProton.at(p1).Pt(), q3); + registryTriggerQA.fill(HIST("PPL/all/fProtonPtVsQ3"), vecProton.at(p2).Pt(), q3); + registryTriggerQA.fill(HIST("PPL/all/fLambdaPtVsQ3"), vecLambda.at(l1).Pt(), q3); + if (q3 < TriggerSelections.limits->get("Loose Limit", "PPL")) { + signalLooseLimit[cf_trigger::kPPL] += 1; + registryTriggerQA.fill(HIST("PPL/loose/fMultiplicity"), col.multNTracksPV()); + registryTriggerQA.fill(HIST("PPL/loose/fZvtx"), col.posZ()); + registryTriggerQA.fill(HIST("PPL/loose/fSE_particle"), q3); + registryTriggerQA.fill(HIST("PPL/loose/fProtonPtVsQ3"), vecProton.at(p1).Pt(), q3); + registryTriggerQA.fill(HIST("PPL/loose/fProtonPtVsQ3"), vecProton.at(p2).Pt(), q3); + registryTriggerQA.fill(HIST("PPL/loose/fLambdaPtVsQ3"), vecLambda.at(l1).Pt(), q3); + if (q3 < TriggerSelections.limits->get("Tight Limit", "PPL")) { + signalTightLimit[cf_trigger::kPPL] += 1; + registryTriggerQA.fill(HIST("PPL/tight/fMultiplicity"), col.multNTracksPV()); + registryTriggerQA.fill(HIST("PPL/tight/fZvtx"), col.posZ()); + registryTriggerQA.fill(HIST("PPL/tight/fSE_particle"), q3); + registryTriggerQA.fill(HIST("PPL/tight/fProtonPtVsQ3"), vecProton.at(p1).Pt(), q3); + registryTriggerQA.fill(HIST("PPL/tight/fProtonPtVsQ3"), vecProton.at(p2).Pt(), q3); + registryTriggerQA.fill(HIST("PPL/tight/fLambdaPtVsQ3"), vecLambda.at(l1).Pt(), q3); } } } } - for (auto iAntiProton1 = antiprotons.begin(); iAntiProton1 != antiprotons.end(); ++iAntiProton1) { - auto iAntiProton2 = iAntiProton1 + 1; - for (; iAntiProton2 != antiprotons.end(); ++iAntiProton2) { - auto iAntiProton3 = iAntiProton2 + 1; - for (; iAntiProton3 != antiprotons.end(); ++iAntiProton3) { - Q3 = getQ3(*iAntiProton1, *iAntiProton2, *iAntiProton3); - registry.fill(HIST("ppp/fSE_antiparticle"), Q3); - registry.fill(HIST("ppp/fAntiProtonPtVsQ3"), Q3, (*iAntiProton1).Pt()); - registry.fill(HIST("ppp/fAntiProtonPtVsQ3"), Q3, (*iAntiProton2).Pt()); - registry.fill(HIST("ppp/fAntiProtonPtVsQ3"), Q3, (*iAntiProton3).Pt()); - if (Q3 < ConfQ3Limits->get(static_cast(0), CFTrigger::kPPP)) { - if (ConfDownsample->get("Switch", "aPaPaP") > 0) { - if (rng->Uniform(0., 1.) < ConfDownsample->get("Factor", "aPaPaP")) { - registry.fill(HIST("ppp/fSE_antiparticle_downsample"), Q3); - lowQ3Triplets[CFTrigger::kPPP] += 1; - } - } else { - lowQ3Triplets[CFTrigger::kPPP] += 1; - } + } + for (size_t p1 = 0; p1 < vecAntiProton.size(); p1++) { + for (size_t p2 = p1 + 1; p2 < vecAntiProton.size(); p2++) { + for (size_t l1 = 0; l1 < vecAntiLambda.size(); l1++) { + if (idxAntiProton.at(p1) == idxAntiLambdaDaughProton.at(l1) || idxAntiProton.at(p2) == idxAntiLambdaDaughProton.at(l1)) { + continue; + } + q3 = getQ3(vecAntiProton.at(p1), vecAntiProton.at(p2), vecAntiLambda.at(l1)); + registryTriggerQA.fill(HIST("PPL/all/fMultiplicity"), col.multNTracksPV()); + registryTriggerQA.fill(HIST("PPL/all/fZvtx"), col.posZ()); + registryTriggerQA.fill(HIST("PPL/all/fSE_particle"), q3); + registryTriggerQA.fill(HIST("PPL/all/fAntiProtonPtVsQ3"), vecAntiProton.at(p1).Pt(), q3); + registryTriggerQA.fill(HIST("PPL/all/fAntiProtonPtVsQ3"), vecAntiProton.at(p2).Pt(), q3); + registryTriggerQA.fill(HIST("PPL/all/fAntiLambdaPtVsQ3"), vecAntiLambda.at(l1).Pt(), q3); + if (q3 < TriggerSelections.limits->get("Loose Limit", "PPL")) { + signalLooseLimit[cf_trigger::kPPL] += 1; + registryTriggerQA.fill(HIST("PPL/loose/fMultiplicity"), col.multNTracksPV()); + registryTriggerQA.fill(HIST("PPL/loose/fZvtx"), col.posZ()); + registryTriggerQA.fill(HIST("PPL/loose/fSE_antiparticle"), q3); + registryTriggerQA.fill(HIST("PPL/loose/fAntiProtonPtVsQ3"), vecAntiProton.at(p1).Pt(), q3); + registryTriggerQA.fill(HIST("PPL/loose/fAntiProtonPtVsQ3"), vecAntiProton.at(p2).Pt(), q3); + registryTriggerQA.fill(HIST("PPL/loose/fAntiLambdaPtVsQ3"), vecAntiLambda.at(l1).Pt(), q3); + if (q3 < TriggerSelections.limits->get("Tight Limit", "PPL")) { + signalTightLimit[cf_trigger::kPPL] += 1; + registryTriggerQA.fill(HIST("PPL/tight/fMultiplicity"), col.multNTracksPV()); + registryTriggerQA.fill(HIST("PPL/tight/fZvtx"), col.posZ()); + registryTriggerQA.fill(HIST("PPL/tight/fSE_antiparticle"), q3); + registryTriggerQA.fill(HIST("PPL/tight/fAntiProtonPtVsQ3"), vecAntiProton.at(p1).Pt(), q3); + registryTriggerQA.fill(HIST("PPL/tight/fAntiProtonPtVsQ3"), vecAntiProton.at(p2).Pt(), q3); + registryTriggerQA.fill(HIST("PPL/tight/fAntiLambdaPtVsQ3"), vecAntiLambda.at(l1).Pt(), q3); } } } } } - if (ConfTriggerSwitches->get("Switch", "ppL") > 0.) { - // ppl trigger - for (auto iProton1 = protons.begin(); iProton1 != protons.end(); ++iProton1) { - auto iProton2 = iProton1 + 1; - auto i1 = std::distance(protons.begin(), iProton1); - for (; iProton2 != protons.end(); ++iProton2) { - auto i2 = std::distance(protons.begin(), iProton2); - for (auto iLambda1 = lambdas.begin(); iLambda1 != lambdas.end(); ++iLambda1) { - auto i3 = std::distance(lambdas.begin(), iLambda1); - if (ConfAutocorRejection.value && - (ProtonIndex.at(i1) == LambdaPosDaughIndex.at(i3) || - ProtonIndex.at(i2) == LambdaPosDaughIndex.at(i3))) { - continue; - } - Q3 = getQ3(*iProton1, *iProton2, *iLambda1); - registry.fill(HIST("ppl/fSE_particle"), Q3); - registry.fill(HIST("ppl/fProtonPtVsQ3"), Q3, (*iProton1).Pt()); - registry.fill(HIST("ppl/fProtonPtVsQ3"), Q3, (*iProton2).Pt()); - registry.fill(HIST("ppl/fLambdaPtVsQ3"), Q3, (*iLambda1).Pt()); - if (Q3 < ConfQ3Limits->get(static_cast(0), CFTrigger::kPPL)) { - if (ConfDownsample->get("Switch", "PPL") > 0) { - if (rng->Uniform(0., 1.) < ConfDownsample->get("Factor", "PPL")) { - registry.fill(HIST("ppl/fSE_particle_downsample"), Q3); - lowQ3Triplets[CFTrigger::kPPL] += 1; - } - } else { - lowQ3Triplets[CFTrigger::kPPL] += 1; - } + } + // PLL + if (TriggerSelections.filterSwitches->get("Switch", "PLL") > 0) { + for (size_t l1 = 0; l1 < vecLambda.size(); l1++) { + for (size_t l2 = l1 + 1; l2 < vecLambda.size(); l2++) { + for (size_t p1 = 0; p1 < vecProton.size(); p1++) { + if (idxProton.at(p1) == idxLambdaDaughProton.at(l1) || idxProton.at(p1) == idxLambdaDaughProton.at(l2)) { + continue; + } + if (idxLambdaDaughProton.at(l1) == idxLambdaDaughProton.at(l2) || idxLambdaDaughPion.at(l1) == idxLambdaDaughPion.at(l2)) { + continue; + } + q3 = getQ3(vecLambda.at(l1), vecLambda.at(l2), vecProton.at(p1)); + registryTriggerQA.fill(HIST("PLL/all/fMultiplicity"), col.multNTracksPV()); + registryTriggerQA.fill(HIST("PLL/all/fZvtx"), col.posZ()); + registryTriggerQA.fill(HIST("PLL/all/fSE_particle"), q3); + registryTriggerQA.fill(HIST("PLL/all/fLambdaPtVsQ3"), vecLambda.at(l1).Pt(), q3); + registryTriggerQA.fill(HIST("PLL/all/fLambdaPtVsQ3"), vecLambda.at(l2).Pt(), q3); + registryTriggerQA.fill(HIST("PLL/all/fProtonPtVsQ3"), vecProton.at(p1).Pt(), q3); + if (q3 < TriggerSelections.limits->get("Loose Limit", "PLL")) { + signalLooseLimit[cf_trigger::kPLL] += 1; + registryTriggerQA.fill(HIST("PLL/loose/fMultiplicity"), col.multNTracksPV()); + registryTriggerQA.fill(HIST("PLL/loose/fZvtx"), col.posZ()); + registryTriggerQA.fill(HIST("PLL/loose/fSE_particle"), q3); + registryTriggerQA.fill(HIST("PLL/loose/fLambdaPtVsQ3"), vecLambda.at(l1).Pt(), q3); + registryTriggerQA.fill(HIST("PLL/loose/fLambdaPtVsQ3"), vecLambda.at(l2).Pt(), q3); + registryTriggerQA.fill(HIST("PLL/loose/fProtonPtVsQ3"), vecProton.at(p1).Pt(), q3); + if (q3 < TriggerSelections.limits->get("Tight Limit", "PLL")) { + signalTightLimit[cf_trigger::kPLL] += 1; + registryTriggerQA.fill(HIST("PLL/tight/fMultiplicity"), col.multNTracksPV()); + registryTriggerQA.fill(HIST("PLL/tight/fZvtx"), col.posZ()); + registryTriggerQA.fill(HIST("PLL/tight/fSE_particle"), q3); + registryTriggerQA.fill(HIST("PLL/tight/fLambdaPtVsQ3"), vecLambda.at(l1).Pt(), q3); + registryTriggerQA.fill(HIST("PLL/tight/fLambdaPtVsQ3"), vecLambda.at(l2).Pt(), q3); + registryTriggerQA.fill(HIST("PLL/tight/fProtonPtVsQ3"), vecProton.at(p1).Pt(), q3); } } } } - for (auto iAntiProton1 = antiprotons.begin(); iAntiProton1 != antiprotons.end(); ++iAntiProton1) { - auto iAntiProton2 = iAntiProton1 + 1; - auto i1 = std::distance(antiprotons.begin(), iAntiProton1); - for (; iAntiProton2 != antiprotons.end(); ++iAntiProton2) { - auto i2 = std::distance(antiprotons.begin(), iAntiProton2); - for (auto iAntiLambda1 = antilambdas.begin(); iAntiLambda1 != antilambdas.end(); ++iAntiLambda1) { - auto i3 = std::distance(antilambdas.begin(), iAntiLambda1); - if (ConfAutocorRejection.value && - (AntiProtonIndex.at(i1) == AntiLambdaNegDaughIndex.at(i3) || - AntiProtonIndex.at(i2) == AntiLambdaNegDaughIndex.at(i3))) { - continue; - } - Q3 = getQ3(*iAntiProton1, *iAntiProton2, *iAntiLambda1); - registry.fill(HIST("ppl/fSE_antiparticle"), Q3); - registry.fill(HIST("ppl/fAntiProtonPtVsQ3"), Q3, (*iAntiProton1).Pt()); - registry.fill(HIST("ppl/fAntiProtonPtVsQ3"), Q3, (*iAntiProton2).Pt()); - registry.fill(HIST("ppl/fAntiLambdaPtVsQ3"), Q3, (*iAntiLambda1).Pt()); - if (Q3 < ConfQ3Limits->get(static_cast(0), CFTrigger::kPPL)) { - if (ConfDownsample->get("Switch", "aPaPaL") > 0) { - if (rng->Uniform(0., 1.) < ConfDownsample->get("Factor", "aPaPaL")) { - registry.fill(HIST("ppl/fSE_antiparticle_downsample"), Q3); - lowQ3Triplets[CFTrigger::kPPL] += 1; - } - } else { - lowQ3Triplets[CFTrigger::kPPL] += 1; - } + } + for (size_t l1 = 0; l1 < vecAntiLambda.size(); l1++) { + for (size_t l2 = l1 + 1; l2 < vecAntiLambda.size(); l2++) { + for (size_t p1 = 0; p1 < vecAntiProton.size(); p1++) { + if (idxAntiProton.at(p1) == idxAntiLambdaDaughProton.at(l1) || idxAntiProton.at(p1) == idxAntiLambdaDaughProton.at(l2)) { + continue; + } + if (idxAntiLambdaDaughProton.at(l1) == idxAntiLambdaDaughProton.at(l2) || idxAntiLambdaDaughPion.at(l1) == idxAntiLambdaDaughPion.at(l2)) { + continue; + } + q3 = getQ3(vecAntiLambda.at(l1), vecAntiLambda.at(l2), vecAntiProton.at(p1)); + registryTriggerQA.fill(HIST("PLL/all/fMultiplicity"), col.multNTracksPV()); + registryTriggerQA.fill(HIST("PLL/all/fZvtx"), col.posZ()); + registryTriggerQA.fill(HIST("PLL/all/fSE_antiparticle"), q3); + registryTriggerQA.fill(HIST("PLL/all/fAntiLambdaPtVsQ3"), vecAntiLambda.at(l1).Pt(), q3); + registryTriggerQA.fill(HIST("PLL/all/fAntiLambdaPtVsQ3"), vecAntiLambda.at(l2).Pt(), q3); + registryTriggerQA.fill(HIST("PLL/all/fAntiProtonPtVsQ3"), vecAntiProton.at(p1).Pt(), q3); + if (q3 < TriggerSelections.limits->get("Loose Limit", "PLL")) { + signalLooseLimit[cf_trigger::kPLL] += 1; + registryTriggerQA.fill(HIST("PLL/loose/fMultiplicity"), col.multNTracksPV()); + registryTriggerQA.fill(HIST("PLL/loose/fZvtx"), col.posZ()); + registryTriggerQA.fill(HIST("PLL/loose/fSE_antiparticle"), q3); + registryTriggerQA.fill(HIST("PLL/loose/fAntiLambdaPtVsQ3"), vecAntiLambda.at(l1).Pt(), q3); + registryTriggerQA.fill(HIST("PLL/loose/fAntiLambdaPtVsQ3"), vecAntiLambda.at(l2).Pt(), q3); + registryTriggerQA.fill(HIST("PLL/loose/fAntiProtonPtVsQ3"), vecAntiProton.at(p1).Pt(), q3); + if (q3 < TriggerSelections.limits->get("Tight Limit", "PLL")) { + signalTightLimit[cf_trigger::kPLL] += 1; + registryTriggerQA.fill(HIST("PLL/tight/fMultiplicity"), col.multNTracksPV()); + registryTriggerQA.fill(HIST("PLL/tight/fZvtx"), col.posZ()); + registryTriggerQA.fill(HIST("PLL/tight/fSE_antiparticle"), q3); + registryTriggerQA.fill(HIST("PLL/tight/fAntiLambdaPtVsQ3"), vecAntiLambda.at(l1).Pt(), q3); + registryTriggerQA.fill(HIST("PLL/tight/fAntiLambdaPtVsQ3"), vecAntiLambda.at(l2).Pt(), q3); + registryTriggerQA.fill(HIST("PLL/tight/fAntiProtonPtVsQ3"), vecAntiProton.at(p1).Pt(), q3); } } } } } - if (ConfTriggerSwitches->get("Switch", "pLL") > 0.) { - // pll trigger - for (auto iLambda1 = lambdas.begin(); iLambda1 != lambdas.end(); ++iLambda1) { - auto iLambda2 = iLambda1 + 1; - auto i1 = std::distance(lambdas.begin(), iLambda1); - for (; iLambda2 != lambdas.end(); ++iLambda2) { - auto i2 = std::distance(lambdas.begin(), iLambda2); - if (ConfAutocorRejection.value && - (LambdaPosDaughIndex.at(i1) == LambdaPosDaughIndex.at(i2) || - LambdaNegDaughIndex.at(i1) == LambdaNegDaughIndex.at(i2))) { + } + // LLL + if (TriggerSelections.filterSwitches->get("Switch", "LLL") > 0) { + for (size_t l1 = 0; l1 < vecLambda.size(); l1++) { + for (size_t l2 = l1 + 1; l2 < vecLambda.size(); l2++) { + for (size_t l3 = l2 + 1; l3 < vecLambda.size(); l3++) { + if (idxLambdaDaughProton.at(l1) == idxLambdaDaughProton.at(l2) || idxLambdaDaughPion.at(l1) == idxLambdaDaughPion.at(l2) || + idxLambdaDaughProton.at(l2) == idxLambdaDaughProton.at(l3) || idxLambdaDaughPion.at(l2) == idxLambdaDaughPion.at(l3) || + idxLambdaDaughProton.at(l3) == idxLambdaDaughProton.at(l1) || idxLambdaDaughPion.at(l3) == idxLambdaDaughPion.at(l1)) { continue; } - for (auto iProton1 = protons.begin(); iProton1 != protons.end(); ++iProton1) { - auto i3 = std::distance(protons.begin(), iProton1); - if (ConfAutocorRejection.value && - (LambdaPosDaughIndex.at(i1) == ProtonIndex.at(i3) || - LambdaPosDaughIndex.at(i2) == ProtonIndex.at(i3))) { - continue; - } - Q3 = getQ3(*iLambda1, *iLambda2, *iProton1); - registry.fill(HIST("pll/fSE_particle"), Q3); - registry.fill(HIST("pll/fProtonPtVsQ3"), Q3, (*iProton1).Pt()); - registry.fill(HIST("pll/fLambdaPtVsQ3"), Q3, (*iLambda1).Pt()); - registry.fill(HIST("pll/fLambdaPtVsQ3"), Q3, (*iLambda2).Pt()); - if (Q3 < ConfQ3Limits->get(static_cast(0), CFTrigger::kPLL)) { - if (ConfDownsample->get("Switch", "PLL") > 0) { - if (rng->Uniform(0., 1.) < ConfDownsample->get("Factor", "PLL")) { - registry.fill(HIST("pll/fSE_particle_downsample"), Q3); - lowQ3Triplets[CFTrigger::kPLL] += 1; - } - } else { - lowQ3Triplets[CFTrigger::kPLL] += 1; - } + q3 = getQ3(vecLambda.at(l1), vecLambda.at(l2), vecLambda.at(l3)); + registryTriggerQA.fill(HIST("LLL/all/fMultiplicity"), col.multNTracksPV()); + registryTriggerQA.fill(HIST("LLL/all/fZvtx"), col.posZ()); + registryTriggerQA.fill(HIST("LLL/all/fSE_particle"), q3); + registryTriggerQA.fill(HIST("LLL/all/fLambdaPtVsQ3"), vecLambda.at(l1).Pt(), q3); + registryTriggerQA.fill(HIST("LLL/all/fLambdaPtVsQ3"), vecLambda.at(l2).Pt(), q3); + registryTriggerQA.fill(HIST("LLL/all/fLambdaPtVsQ3"), vecLambda.at(l3).Pt(), q3); + if (q3 < TriggerSelections.limits->get("Loose Limit", "LLL")) { + signalLooseLimit[cf_trigger::kLLL] += 1; + registryTriggerQA.fill(HIST("LLL/loose/fMultiplicity"), col.multNTracksPV()); + registryTriggerQA.fill(HIST("LLL/loose/fZvtx"), col.posZ()); + registryTriggerQA.fill(HIST("LLL/loose/fSE_particle"), q3); + registryTriggerQA.fill(HIST("LLL/loose/fLambdaPtVsQ3"), vecLambda.at(l1).Pt(), q3); + registryTriggerQA.fill(HIST("LLL/loose/fLambdaPtVsQ3"), vecLambda.at(l2).Pt(), q3); + registryTriggerQA.fill(HIST("LLL/loose/fLambdaPtVsQ3"), vecLambda.at(l3).Pt(), q3); + if (q3 < TriggerSelections.limits->get("Tight Limit", "LLL")) { + signalTightLimit[cf_trigger::kLLL] += 1; + registryTriggerQA.fill(HIST("LLL/tight/fMultiplicity"), col.multNTracksPV()); + registryTriggerQA.fill(HIST("LLL/tight/fZvtx"), col.posZ()); + registryTriggerQA.fill(HIST("LLL/tight/fSE_particle"), q3); + registryTriggerQA.fill(HIST("LLL/tight/fLambdaPtVsQ3"), vecLambda.at(l1).Pt(), q3); + registryTriggerQA.fill(HIST("LLL/tight/fLambdaPtVsQ3"), vecLambda.at(l2).Pt(), q3); + registryTriggerQA.fill(HIST("LLL/tight/fLambdaPtVsQ3"), vecLambda.at(l3).Pt(), q3); } } } } - for (auto iAntiLambda1 = antilambdas.begin(); iAntiLambda1 != antilambdas.end(); ++iAntiLambda1) { - auto iAntiLambda2 = iAntiLambda1 + 1; - auto i1 = std::distance(antilambdas.begin(), iAntiLambda1); - for (; iAntiLambda2 != antilambdas.end(); ++iAntiLambda2) { - auto i2 = std::distance(antilambdas.begin(), iAntiLambda2); - if (ConfAutocorRejection.value && - (AntiLambdaPosDaughIndex.at(i1) == AntiLambdaPosDaughIndex.at(i2) || - AntiLambdaNegDaughIndex.at(i1) == AntiLambdaNegDaughIndex.at(i2))) { + } + for (size_t l1 = 0; l1 < vecAntiLambda.size(); l1++) { + for (size_t l2 = l1 + 1; l2 < vecAntiLambda.size(); l2++) { + for (size_t l3 = l2 + 1; l3 < vecAntiLambda.size(); l3++) { + if (idxAntiLambdaDaughProton.at(l1) == idxAntiLambdaDaughProton.at(l2) || idxAntiLambdaDaughPion.at(l1) == idxAntiLambdaDaughPion.at(l2) || + idxAntiLambdaDaughProton.at(l2) == idxAntiLambdaDaughProton.at(l3) || idxAntiLambdaDaughPion.at(l2) == idxAntiLambdaDaughPion.at(l3) || + idxAntiLambdaDaughProton.at(l3) == idxAntiLambdaDaughProton.at(l1) || idxAntiLambdaDaughPion.at(l3) == idxAntiLambdaDaughPion.at(l1)) { continue; } - for (auto iAntiProton1 = antiprotons.begin(); iAntiProton1 != antiprotons.end(); ++iAntiProton1) { - auto i3 = std::distance(antiprotons.begin(), iAntiProton1); - if (ConfAutocorRejection.value && - (AntiLambdaNegDaughIndex.at(i1) == AntiProtonIndex.at(i3) || - AntiLambdaNegDaughIndex.at(i2) == AntiProtonIndex.at(i3))) { - continue; - } - Q3 = getQ3(*iAntiLambda1, *iAntiLambda2, *iAntiProton1); - registry.fill(HIST("pll/fSE_antiparticle"), Q3); - registry.fill(HIST("pll/fAntiProtonPtVsQ3"), Q3, (*iAntiProton1).Pt()); - registry.fill(HIST("pll/fAntiLambdaPtVsQ3"), Q3, (*iAntiLambda1).Pt()); - registry.fill(HIST("pll/fAntiLambdaPtVsQ3"), Q3, (*iAntiLambda2).Pt()); - if (Q3 < ConfQ3Limits->get(static_cast(0), CFTrigger::kPLL)) { - if (ConfDownsample->get("Switch", "aPaLaL") > 0) { - if (rng->Uniform(0., 1.) < ConfDownsample->get("Factor", "aPaLaL")) { - registry.fill(HIST("pll/fSE_antiparticle_downsample"), Q3); - lowQ3Triplets[CFTrigger::kPLL] += 1; - } - } else { - lowQ3Triplets[CFTrigger::kPLL] += 1; - } + q3 = getQ3(vecAntiLambda.at(l1), vecAntiLambda.at(l2), vecAntiLambda.at(l3)); + registryTriggerQA.fill(HIST("LLL/all/fMultiplicity"), col.multNTracksPV()); + registryTriggerQA.fill(HIST("LLL/all/fZvtx"), col.posZ()); + registryTriggerQA.fill(HIST("LLL/all/fSE_antiparticle"), q3); + registryTriggerQA.fill(HIST("LLL/all/fLambdaPtVsQ3"), vecAntiLambda.at(l1).Pt(), q3); + registryTriggerQA.fill(HIST("LLL/all/fLambdaPtVsQ3"), vecAntiLambda.at(l2).Pt(), q3); + registryTriggerQA.fill(HIST("LLL/all/fLambdaPtVsQ3"), vecAntiLambda.at(l3).Pt(), q3); + if (q3 < TriggerSelections.limits->get("Loose Limit", "LLL")) { + signalLooseLimit[cf_trigger::kLLL] += 1; + registryTriggerQA.fill(HIST("LLL/loose/fMultiplicity"), col.multNTracksPV()); + registryTriggerQA.fill(HIST("LLL/loose/fZvtx"), col.posZ()); + registryTriggerQA.fill(HIST("LLL/loose/fSE_antiparticle"), q3); + registryTriggerQA.fill(HIST("LLL/loose/fLambdaPtVsQ3"), vecAntiLambda.at(l1).Pt(), q3); + registryTriggerQA.fill(HIST("LLL/loose/fLambdaPtVsQ3"), vecAntiLambda.at(l2).Pt(), q3); + registryTriggerQA.fill(HIST("LLL/loose/fLambdaPtVsQ3"), vecAntiLambda.at(l3).Pt(), q3); + if (q3 < TriggerSelections.limits->get("Tight Limit", "LLL")) { + signalTightLimit[cf_trigger::kLLL] += 1; + registryTriggerQA.fill(HIST("LLL/tight/fMultiplicity"), col.multNTracksPV()); + registryTriggerQA.fill(HIST("LLL/tight/fZvtx"), col.posZ()); + registryTriggerQA.fill(HIST("LLL/tight/fSE_antiparticle"), q3); + registryTriggerQA.fill(HIST("LLL/tight/fLambdaPtVsQ3"), vecAntiLambda.at(l1).Pt(), q3); + registryTriggerQA.fill(HIST("LLL/tight/fLambdaPtVsQ3"), vecAntiLambda.at(l2).Pt(), q3); + registryTriggerQA.fill(HIST("LLL/tight/fLambdaPtVsQ3"), vecAntiLambda.at(l3).Pt(), q3); } } } } } - if (ConfTriggerSwitches->get("Switch", "LLL") > 0.) { - // lll trigger - for (auto iLambda1 = lambdas.begin(); iLambda1 != lambdas.end(); ++iLambda1) { - auto iLambda2 = iLambda1 + 1; - auto i1 = std::distance(lambdas.begin(), iLambda1); - for (; iLambda2 != lambdas.end(); ++iLambda2) { - auto i2 = std::distance(lambdas.begin(), iLambda2); - if (ConfAutocorRejection.value && - (LambdaPosDaughIndex.at(i1) == LambdaPosDaughIndex.at(i2) || - LambdaNegDaughIndex.at(i1) == LambdaNegDaughIndex.at(i2))) { + } + // PPPhi + if (TriggerSelections.filterSwitches->get("Switch", "PPPhi") > 0) { + for (size_t p1 = 0; p1 < vecProton.size(); p1++) { + for (size_t p2 = p1 + 1; p2 < vecProton.size(); p2++) { + for (size_t phi1 = 0; phi1 < vecPhi.size(); phi1++) { + if (idxProton.at(p1) == idxPhiDaughPos.at(phi1) || idxProton.at(p2) == idxPhiDaughPos.at(phi1)) { continue; } - auto iLambda3 = iLambda2 + 1; - for (; iLambda3 != lambdas.end(); ++iLambda3) { - auto i3 = std::distance(lambdas.begin(), iLambda3); - if (ConfAutocorRejection.value && - (LambdaPosDaughIndex.at(i1) == LambdaPosDaughIndex.at(i3) || - LambdaNegDaughIndex.at(i1) == LambdaNegDaughIndex.at(i3) || - LambdaPosDaughIndex.at(i2) == LambdaPosDaughIndex.at(i3) || - LambdaNegDaughIndex.at(i2) == LambdaNegDaughIndex.at(i3))) { - continue; - } - Q3 = getQ3(*iLambda1, *iLambda2, *iLambda3); - registry.fill(HIST("lll/fSE_particle"), Q3); - registry.fill(HIST("lll/fLambdaPtVsQ3"), Q3, (*iLambda1).Pt()); - registry.fill(HIST("lll/fLambdaPtVsQ3"), Q3, (*iLambda2).Pt()); - registry.fill(HIST("lll/fLambdaPtVsQ3"), Q3, (*iLambda3).Pt()); - if (Q3 < ConfQ3Limits->get(static_cast(0), CFTrigger::kLLL)) { - if (ConfDownsample->get("Switch", "LLL") > 0) { - if (rng->Uniform(0., 1.) < ConfDownsample->get("Factor", "LLL")) { - registry.fill(HIST("lll/fSE_particle_downsample"), Q3); - lowQ3Triplets[CFTrigger::kLLL] += 1; - } - } else { - lowQ3Triplets[CFTrigger::kLLL] += 1; - } + q3 = getQ3(vecProton.at(p1), vecProton.at(p2), vecPhi.at(phi1)); + registryTriggerQA.fill(HIST("PPPhi/all/fMultiplicity"), col.multNTracksPV()); + registryTriggerQA.fill(HIST("PPPhi/all/fZvtx"), col.posZ()); + registryTriggerQA.fill(HIST("PPPhi/all/fSE_particle"), q3); + registryTriggerQA.fill(HIST("PPPhi/all/fProtonPtVsQ3"), vecProton.at(p1).Pt(), q3); + registryTriggerQA.fill(HIST("PPPhi/all/fProtonPtVsQ3"), vecProton.at(p2).Pt(), q3); + registryTriggerQA.fill(HIST("PPPhi/all/fPhiPtVsQ3"), vecPhi.at(phi1).Pt(), q3); + registryTriggerQA.fill(HIST("PPPhi/all/fPhiInvMassVsQ3"), vecPhi.at(phi1).M(), q3); + if (q3 < TriggerSelections.limits->get("Loose Limit", "PPPhi")) { + signalLooseLimit[cf_trigger::kPPPhi] += 1; + registryTriggerQA.fill(HIST("PPPhi/loose/fMultiplicity"), col.multNTracksPV()); + registryTriggerQA.fill(HIST("PPPhi/loose/fZvtx"), col.posZ()); + registryTriggerQA.fill(HIST("PPPhi/loose/fSE_particle"), q3); + registryTriggerQA.fill(HIST("PPPhi/loose/fProtonPtVsQ3"), vecProton.at(p1).Pt(), q3); + registryTriggerQA.fill(HIST("PPPhi/loose/fProtonPtVsQ3"), vecProton.at(p2).Pt(), q3); + registryTriggerQA.fill(HIST("PPPhi/loose/fPhiPtVsQ3"), vecPhi.at(phi1).Pt(), q3); + registryTriggerQA.fill(HIST("PPPhi/loose/fPhiInvMassVsQ3"), vecPhi.at(phi1).M(), q3); + if (q3 < TriggerSelections.limits->get("Tight Limit", "PPPhi") && + vecPhi.at(phi1).M() > PhiSelections.tightInvMassLow.value && vecPhi.at(phi1).M() < PhiSelections.tightInvMassUp.value) { + signalTightLimit[cf_trigger::kPPPhi] += 1; + registryTriggerQA.fill(HIST("PPPhi/tight/fMultiplicity"), col.multNTracksPV()); + registryTriggerQA.fill(HIST("PPPhi/tight/fZvtx"), col.posZ()); + registryTriggerQA.fill(HIST("PPPhi/tight/fSE_particle"), q3); + registryTriggerQA.fill(HIST("PPPhi/tight/fProtonPtVsQ3"), vecProton.at(p1).Pt(), q3); + registryTriggerQA.fill(HIST("PPPhi/tight/fProtonPtVsQ3"), vecProton.at(p2).Pt(), q3); + registryTriggerQA.fill(HIST("PPPhi/tight/fPhiPtVsQ3"), vecPhi.at(phi1).Pt(), q3); + registryTriggerQA.fill(HIST("PPPhi/tight/fPhiInvMassVsQ3"), vecPhi.at(phi1).M(), q3); } } } } - for (auto iAntiLambda1 = antilambdas.begin(); iAntiLambda1 != antilambdas.end(); ++iAntiLambda1) { - auto iAntiLambda2 = iAntiLambda1 + 1; - auto i1 = std::distance(antilambdas.begin(), iAntiLambda1); - for (; iAntiLambda2 != antilambdas.end(); ++iAntiLambda2) { - auto i2 = std::distance(antilambdas.begin(), iAntiLambda2); - if (ConfAutocorRejection.value && - (AntiLambdaPosDaughIndex.at(i1) == AntiLambdaPosDaughIndex.at(i2) || - AntiLambdaNegDaughIndex.at(i1) == AntiLambdaNegDaughIndex.at(i2))) { + } + for (size_t p1 = 0; p1 < vecAntiProton.size(); p1++) { + for (size_t p2 = p1 + 1; p2 < vecAntiProton.size(); p2++) { + for (size_t phi1 = 0; phi1 < vecPhi.size(); phi1++) { + if (idxAntiProton.at(p1) == idxPhiDaughNeg.at(phi1) || idxAntiProton.at(p2) == idxPhiDaughNeg.at(phi1)) { continue; } - auto iAntiLambda3 = iAntiLambda2 + 1; - for (; iAntiLambda3 != antilambdas.end(); ++iAntiLambda3) { - auto i3 = std::distance(antilambdas.begin(), iAntiLambda3); - if (ConfAutocorRejection.value && - (AntiLambdaPosDaughIndex.at(i1) == AntiLambdaPosDaughIndex.at(i3) || - AntiLambdaNegDaughIndex.at(i1) == AntiLambdaNegDaughIndex.at(i3) || - AntiLambdaPosDaughIndex.at(i2) == AntiLambdaPosDaughIndex.at(i3) || - AntiLambdaNegDaughIndex.at(i2) == AntiLambdaNegDaughIndex.at(i3))) { - continue; - } - Q3 = getQ3(*iAntiLambda1, *iAntiLambda2, *iAntiLambda3); - registry.fill(HIST("lll/fSE_antiparticle"), Q3); - registry.fill(HIST("lll/fAntiLambdaPtVsQ3"), Q3, (*iAntiLambda1).Pt()); - registry.fill(HIST("lll/fAntiLambdaPtVsQ3"), Q3, (*iAntiLambda2).Pt()); - registry.fill(HIST("lll/fAntiLambdaPtVsQ3"), Q3, (*iAntiLambda3).Pt()); - if (Q3 < ConfQ3Limits->get(static_cast(0), CFTrigger::kLLL)) { - if (ConfDownsample->get("Switch", "aLaLaL") > 0) { - if (rng->Uniform(0., 1.) < ConfDownsample->get("Factor", "aLaLaL")) { - registry.fill(HIST("lll/fSE_antiparticle_downsample"), Q3); - lowQ3Triplets[CFTrigger::kLLL] += 1; - } - } else { - lowQ3Triplets[CFTrigger::kLLL] += 1; - } + q3 = getQ3(vecAntiProton.at(p1), vecAntiProton.at(p2), vecPhi.at(phi1)); + registryTriggerQA.fill(HIST("PPPhi/all/fMultiplicity"), col.multNTracksPV()); + registryTriggerQA.fill(HIST("PPPhi/all/fZvtx"), col.posZ()); + registryTriggerQA.fill(HIST("PPPhi/all/fSE_antiparticle"), q3); + registryTriggerQA.fill(HIST("PPPhi/all/fAntiProtonPtVsQ3"), vecAntiProton.at(p1).Pt(), q3); + registryTriggerQA.fill(HIST("PPPhi/all/fAntiProtonPtVsQ3"), vecAntiProton.at(p2).Pt(), q3); + registryTriggerQA.fill(HIST("PPPhi/all/fPhiPtVsQ3"), vecPhi.at(phi1).Pt(), q3); + registryTriggerQA.fill(HIST("PPPhi/all/fPhiInvMassVsQ3"), vecPhi.at(phi1).M(), q3); + if (q3 < TriggerSelections.limits->get("Loose Limit", "PPPhi")) { + signalLooseLimit[cf_trigger::kPPPhi] += 1; + registryTriggerQA.fill(HIST("PPPhi/loose/fMultiplicity"), col.multNTracksPV()); + registryTriggerQA.fill(HIST("PPPhi/loose/fZvtx"), col.posZ()); + registryTriggerQA.fill(HIST("PPPhi/loose/fSE_antiparticle"), q3); + registryTriggerQA.fill(HIST("PPPhi/loose/fAntiProtonPtVsQ3"), vecAntiProton.at(p1).Pt(), q3); + registryTriggerQA.fill(HIST("PPPhi/loose/fAntiProtonPtVsQ3"), vecAntiProton.at(p2).Pt(), q3); + registryTriggerQA.fill(HIST("PPPhi/loose/fPhiPtVsQ3"), vecPhi.at(phi1).Pt(), q3); + registryTriggerQA.fill(HIST("PPPhi/loose/fPhiInvMassVsQ3"), vecPhi.at(phi1).M(), q3); + if (q3 < TriggerSelections.limits->get("Tight Limit", "PPPhi") && + vecPhi.at(phi1).M() > PhiSelections.tightInvMassLow.value && vecPhi.at(phi1).M() < PhiSelections.tightInvMassUp.value) { + signalTightLimit[cf_trigger::kPPPhi] += 1; + registryTriggerQA.fill(HIST("PPPhi/tight/fMultiplicity"), col.multNTracksPV()); + registryTriggerQA.fill(HIST("PPPhi/tight/fZvtx"), col.posZ()); + registryTriggerQA.fill(HIST("PPPhi/tight/fSE_antiparticle"), q3); + registryTriggerQA.fill(HIST("PPPhi/tight/fAntiProtonPtVsQ3"), vecAntiProton.at(p1).Pt(), q3); + registryTriggerQA.fill(HIST("PPPhi/tight/fAntiProtonPtVsQ3"), vecAntiProton.at(p2).Pt(), q3); + registryTriggerQA.fill(HIST("PPPhi/tight/fPhiPtVsQ3"), vecPhi.at(phi1).Pt(), q3); + registryTriggerQA.fill(HIST("PPPhi/tight/fPhiInvMassVsQ3"), vecPhi.at(phi1).M(), q3); } } } } } - if (ConfTriggerSwitches->get("Switch", "ppPhi") > 0.) { - // ppphi trigger - for (auto iProton1 = protons.begin(); iProton1 != protons.end(); ++iProton1) { - auto iProton2 = iProton1 + 1; - for (; iProton2 != protons.end(); ++iProton2) { - for (auto iPhi1 = phi.begin(); iPhi1 != phi.end(); ++iPhi1) { - Q3 = getQ3(*iProton1, *iProton2, *iPhi1); - registry.fill(HIST("ppphi/fSE_particle"), Q3); - registry.fill(HIST("ppphi/fProtonPtVsQ3"), Q3, (*iProton1).Pt()); - registry.fill(HIST("ppphi/fProtonPtVsQ3"), Q3, (*iProton2).Pt()); - registry.fill(HIST("ppphi/fPhiPtVsQ3"), Q3, (*iPhi1).Pt()); - if (Q3 < ConfQ3Limits->get(static_cast(0), CFTrigger::kPPPhi)) { - if (ConfDownsample->get("Switch", "PPPhi") > 0) { - if (rng->Uniform(0., 1.) < ConfDownsample->get("Factor", "PPPhi")) { - registry.fill(HIST("ppphi/fSE_particle_downsample"), Q3); - lowQ3Triplets[CFTrigger::kPPPhi] += 1; - } - } else { - lowQ3Triplets[CFTrigger::kPPPhi] += 1; - } + } + // PPRho + if (TriggerSelections.filterSwitches->get("Switch", "PPRho") > 0) { + for (size_t p1 = 0; p1 < vecProton.size(); p1++) { + for (size_t p2 = p1 + 1; p2 < vecProton.size(); p2++) { + for (size_t r1 = 0; r1 < vecRho.size(); r1++) { + if (idxProton.at(p1) == idxRhoDaughPos.at(r1) || idxProton.at(p2) == idxRhoDaughPos.at(r1)) { + continue; + } + q3 = getQ3(vecProton.at(p1), vecProton.at(p2), vecRho.at(r1)); + registryTriggerQA.fill(HIST("PPRho/all/fMultiplicity"), col.multNTracksPV()); + registryTriggerQA.fill(HIST("PPRho/all/fZvtx"), col.posZ()); + registryTriggerQA.fill(HIST("PPRho/all/fSE_particle"), q3); + registryTriggerQA.fill(HIST("PPRho/all/fProtonPtVsQ3"), vecProton.at(p1).Pt(), q3); + registryTriggerQA.fill(HIST("PPRho/all/fProtonPtVsQ3"), vecProton.at(p2).Pt(), q3); + registryTriggerQA.fill(HIST("PPRho/all/fRhoPtVsQ3"), vecRho.at(r1).Pt(), q3); + registryTriggerQA.fill(HIST("PPRho/all/fRhoInvMassVsQ3"), vecRho.at(r1).M(), q3); + if (q3 < TriggerSelections.limits->get("Loose Limit", "PPRho")) { + signalLooseLimit[cf_trigger::kPPRho] += 1; + registryTriggerQA.fill(HIST("PPRho/loose/fMultiplicity"), col.multNTracksPV()); + registryTriggerQA.fill(HIST("PPRho/loose/fZvtx"), col.posZ()); + registryTriggerQA.fill(HIST("PPRho/loose/fSE_particle"), q3); + registryTriggerQA.fill(HIST("PPRho/loose/fProtonPtVsQ3"), vecProton.at(p1).Pt(), q3); + registryTriggerQA.fill(HIST("PPRho/loose/fProtonPtVsQ3"), vecProton.at(p2).Pt(), q3); + registryTriggerQA.fill(HIST("PPRho/loose/fRhoPtVsQ3"), vecRho.at(r1).Pt(), q3); + registryTriggerQA.fill(HIST("PPRho/loose/fRhoInvMassVsQ3"), vecRho.at(r1).M(), q3); + if (q3 < TriggerSelections.limits->get("Tight Limit", "PPRho") && + vecRho.at(r1).M() > RhoSelections.tightInvMassLow.value && vecRho.at(r1).M() < RhoSelections.tightInvMassUp.value) { + signalTightLimit[cf_trigger::kPPRho] += 1; + registryTriggerQA.fill(HIST("PPRho/tight/fMultiplicity"), col.multNTracksPV()); + registryTriggerQA.fill(HIST("PPRho/tight/fZvtx"), col.posZ()); + registryTriggerQA.fill(HIST("PPRho/tight/fSE_particle"), q3); + registryTriggerQA.fill(HIST("PPRho/tight/fProtonPtVsQ3"), vecProton.at(p1).Pt(), q3); + registryTriggerQA.fill(HIST("PPRho/tight/fProtonPtVsQ3"), vecProton.at(p2).Pt(), q3); + registryTriggerQA.fill(HIST("PPRho/tight/fRhoPtVsQ3"), vecRho.at(r1).Pt(), q3); + registryTriggerQA.fill(HIST("PPRho/tight/fRhoInvMassVsQ3"), vecRho.at(r1).M(), q3); } } } } - // apapphi trigger - for (auto iAntiProton1 = antiprotons.begin(); iAntiProton1 != antiprotons.end(); ++iAntiProton1) { - auto iAntiProton2 = iAntiProton1 + 1; - for (; iAntiProton2 != antiprotons.end(); ++iAntiProton2) { - for (auto iPhi1 = phi.begin(); iPhi1 != phi.end(); ++iPhi1) { - Q3 = getQ3(*iAntiProton1, *iAntiProton2, *iPhi1); - registry.fill(HIST("ppphi/fSE_antiparticle"), Q3); - registry.fill(HIST("ppphi/fAntiProtonPtVsQ3"), Q3, (*iAntiProton1).Pt()); - registry.fill(HIST("ppphi/fAntiProtonPtVsQ3"), Q3, (*iAntiProton2).Pt()); - registry.fill(HIST("ppphi/fAntiPhiPtVsQ3"), Q3, (*iPhi1).Pt()); - if (Q3 < ConfQ3Limits->get(static_cast(0), CFTrigger::kPPPhi)) { - if (ConfDownsample->get("Switch", "aPaPPhi") > 0) { - if (rng->Uniform(0., 1.) < ConfDownsample->get("Factor", "aPaPPhi")) { - registry.fill(HIST("ppphi/fSE_antiparticle_downsample"), Q3); - lowQ3Triplets[CFTrigger::kPPPhi] += 1; - } - } else { - lowQ3Triplets[CFTrigger::kPPPhi] += 1; - } + } + for (size_t p1 = 0; p1 < vecAntiProton.size(); p1++) { + for (size_t p2 = p1 + 1; p2 < vecAntiProton.size(); p2++) { + for (size_t r1 = 0; r1 < vecRho.size(); r1++) { + if (idxAntiProton.at(p1) == idxRhoDaughNeg.at(r1) || idxAntiProton.at(p2) == idxRhoDaughNeg.at(r1)) { + continue; + } + q3 = getQ3(vecAntiProton.at(p1), vecAntiProton.at(p2), vecRho.at(r1)); + registryTriggerQA.fill(HIST("PPRho/all/fMultiplicity"), col.multNTracksPV()); + registryTriggerQA.fill(HIST("PPRho/all/fZvtx"), col.posZ()); + registryTriggerQA.fill(HIST("PPRho/all/fSE_antiparticle"), q3); + registryTriggerQA.fill(HIST("PPRho/all/fAntiProtonPtVsQ3"), vecAntiProton.at(p1).Pt(), q3); + registryTriggerQA.fill(HIST("PPRho/all/fAntiProtonPtVsQ3"), vecAntiProton.at(p2).Pt(), q3); + registryTriggerQA.fill(HIST("PPRho/all/fRhoPtVsQ3"), vecRho.at(r1).Pt(), q3); + registryTriggerQA.fill(HIST("PPRho/all/fRhoInvMassVsQ3"), vecRho.at(r1).M(), q3); + if (q3 < TriggerSelections.limits->get("Loose Limit", "PPRho")) { + signalLooseLimit[cf_trigger::kPPRho] += 1; + registryTriggerQA.fill(HIST("PPRho/loose/fMultiplicity"), col.multNTracksPV()); + registryTriggerQA.fill(HIST("PPRho/loose/fZvtx"), col.posZ()); + registryTriggerQA.fill(HIST("PPRho/loose/fSE_antiparticle"), q3); + registryTriggerQA.fill(HIST("PPRho/loose/fAntiProtonPtVsQ3"), vecAntiProton.at(p1).Pt(), q3); + registryTriggerQA.fill(HIST("PPRho/loose/fAntiProtonPtVsQ3"), vecAntiProton.at(p2).Pt(), q3); + registryTriggerQA.fill(HIST("PPRho/loose/fRhoPtVsQ3"), vecRho.at(r1).Pt(), q3); + registryTriggerQA.fill(HIST("PPRho/loose/fRhoInvMassVsQ3"), vecRho.at(r1).M(), q3); + if (q3 < TriggerSelections.limits->get("Tight Limit", "PPRho") && + vecRho.at(r1).M() > RhoSelections.tightInvMassLow.value && vecRho.at(r1).M() < RhoSelections.tightInvMassUp.value) { + signalTightLimit[cf_trigger::kPPRho] += 1; + registryTriggerQA.fill(HIST("PPRho/tight/fMultiplicity"), col.multNTracksPV()); + registryTriggerQA.fill(HIST("PPRho/tight/fZvtx"), col.posZ()); + registryTriggerQA.fill(HIST("PPRho/tight/fSE_antiparticle"), q3); + registryTriggerQA.fill(HIST("PPRho/tight/fAntiProtonPtVsQ3"), vecAntiProton.at(p1).Pt(), q3); + registryTriggerQA.fill(HIST("PPRho/tight/fAntiProtonPtVsQ3"), vecAntiProton.at(p2).Pt(), q3); + registryTriggerQA.fill(HIST("PPRho/tight/fRhoPtVsQ3"), vecRho.at(r1).Pt(), q3); + registryTriggerQA.fill(HIST("PPRho/tight/fRhoInvMassVsQ3"), vecRho.at(r1).M(), q3); } } } } } - if (ConfTriggerSwitches->get("Switch", "ppRho") > 0.) { - // ppRho trigger - for (size_t i = 0; i < protons.size(); ++i) { - for (size_t j = i + 1; j < protons.size(); ++j) { - for (const auto& rhoParticle : rho) { - const auto& Proton1 = protons[i]; - const auto& Proton2 = protons[j]; - - Q3 = getQ3(Proton1, Proton2, rhoParticle); - - registry.fill(HIST("ppRho/fSE_particle"), Q3); - registry.fill(HIST("ppRho/fProtonPtVsQ3"), Q3, Proton1.Pt()); - registry.fill(HIST("ppRho/fProtonPtVsQ3"), Q3, Proton2.Pt()); - registry.fill(HIST("ppRho/fRhoCandPtVsQ3"), Q3, rhoParticle.Pt()); - - if (Q3 < ConfQ3Limits->get(static_cast(0), CFTrigger::kPPRho)) { - if (ConfDownsample->get("Switch", "PPRho") > 0) { - if (rng->Uniform(0., 1.) < ConfDownsample->get("Factor", "PPRho")) { - registry.fill(HIST("ppRho/fSE_particle_downsample"), Q3); - lowQ3Triplets[CFTrigger::kPPRho] += 1; - } - } else { - lowQ3Triplets[CFTrigger::kPPRho] += 1; - } - } + } + // PD + if (TriggerSelections.filterSwitches->get("Switch", "PD") > 0) { + for (size_t p1 = 0; p1 < vecProton.size(); p1++) { + for (size_t d1 = 0; d1 < vecDeuteron.size(); d1++) { + if (idxProton.at(p1) == idxDeuteron.at(d1)) { + continue; + } + kstar = getkstar(vecProton.at(p1), vecDeuteron.at(d1)); + registryTriggerQA.fill(HIST("PD/all/fMultiplicity"), col.multNTracksPV()); + registryTriggerQA.fill(HIST("PD/all/fZvtx"), col.posZ()); + registryTriggerQA.fill(HIST("PD/all/fSE_particle"), kstar); + registryTriggerQA.fill(HIST("PD/all/fProtonPtVskstar"), vecProton.at(p1).Pt(), kstar); + registryTriggerQA.fill(HIST("PD/all/fDeuteronPtVskstar"), vecDeuteron.at(d1).Pt(), kstar); + if (kstar < TriggerSelections.limits->get("Loose Limit", "PD")) { + signalLooseLimit[cf_trigger::kPD] += 1; + registryTriggerQA.fill(HIST("PD/loose/fMultiplicity"), col.multNTracksPV()); + registryTriggerQA.fill(HIST("PD/loose/fZvtx"), col.posZ()); + registryTriggerQA.fill(HIST("PD/loose/fSE_particle"), kstar); + registryTriggerQA.fill(HIST("PD/loose/fProtonPtVskstar"), vecProton.at(p1).Pt(), kstar); + registryTriggerQA.fill(HIST("PD/loose/fDeuteronPtVskstar"), vecDeuteron.at(d1).Pt(), kstar); + if (kstar < TriggerSelections.limits->get("Tight Limit", "PD")) { + signalTightLimit[cf_trigger::kPD] += 1; + registryTriggerQA.fill(HIST("PD/tight/fMultiplicity"), col.multNTracksPV()); + registryTriggerQA.fill(HIST("PD/tight/fZvtx"), col.posZ()); + registryTriggerQA.fill(HIST("PD/tight/fSE_particle"), kstar); + registryTriggerQA.fill(HIST("PD/tight/fProtonPtVskstar"), vecProton.at(p1).Pt(), kstar); + registryTriggerQA.fill(HIST("PD/tight/fDeuteronPtVskstar"), vecDeuteron.at(d1).Pt(), kstar); } } } - // apapRho trigger - for (size_t i = 0; i < antiprotons.size(); ++i) { - for (size_t j = i + 1; j < antiprotons.size(); ++j) { - for (const auto& rhoParticle : rho) { - const auto& antiProton1 = antiprotons[i]; - const auto& antiProton2 = antiprotons[j]; - - Q3 = getQ3(antiProton1, antiProton2, rhoParticle); - - registry.fill(HIST("ppRho/fSE_antiparticle"), Q3); - registry.fill(HIST("ppRho/fAntiProtonPtVsQ3"), Q3, antiProton1.Pt()); - registry.fill(HIST("ppRho/fAntiProtonPtVsQ3"), Q3, antiProton2.Pt()); - registry.fill(HIST("ppRho/fRhoCandPtVsQ3"), Q3, rhoParticle.Pt()); - - if (Q3 < ConfQ3Limits->get(static_cast(0), CFTrigger::kPPRho)) { - if (ConfDownsample->get("Switch", "aPaPRho") > 0) { - if (rng->Uniform(0., 1.) < ConfDownsample->get("Factor", "aPaPRho")) { - registry.fill(HIST("ppRho/fSE_antiparticle_downsample"), Q3); - lowQ3Triplets[CFTrigger::kPPRho] += 1; - } - } else { - lowQ3Triplets[CFTrigger::kPPRho] += 1; - } - } + } + for (size_t p1 = 0; p1 < vecAntiProton.size(); p1++) { + for (size_t d1 = 0; d1 < vecAntiDeuteron.size(); d1++) { + if (idxAntiProton.at(p1) == idxAntiDeuteron.at(d1)) { + continue; + } + kstar = getkstar(vecAntiProton.at(p1), vecAntiDeuteron.at(d1)); + registryTriggerQA.fill(HIST("PD/all/fMultiplicity"), col.multNTracksPV()); + registryTriggerQA.fill(HIST("PD/all/fZvtx"), col.posZ()); + registryTriggerQA.fill(HIST("PD/all/fSE_antiparticle"), kstar); + registryTriggerQA.fill(HIST("PD/all/fAntiProtonPtVskstar"), vecAntiProton.at(p1).Pt(), kstar); + registryTriggerQA.fill(HIST("PD/all/fAntiDeuteronPtVskstar"), vecAntiDeuteron.at(d1).Pt(), kstar); + if (kstar < TriggerSelections.limits->get("Loose Limit", "PD")) { + signalLooseLimit[cf_trigger::kPD] += 1; + registryTriggerQA.fill(HIST("PD/loose/fMultiplicity"), col.multNTracksPV()); + registryTriggerQA.fill(HIST("PD/loose/fZvtx"), col.posZ()); + registryTriggerQA.fill(HIST("PD/loose/fSE_antiparticle"), kstar); + registryTriggerQA.fill(HIST("PD/loose/fAntiProtonPtVskstar"), vecAntiProton.at(p1).Pt(), kstar); + registryTriggerQA.fill(HIST("PD/loose/fAntiDeuteronPtVskstar"), vecAntiDeuteron.at(d1).Pt(), kstar); + if (kstar < TriggerSelections.limits->get("Tight Limit", "PD")) { + signalTightLimit[cf_trigger::kPD] += 1; + registryTriggerQA.fill(HIST("PD/tight/fMultiplicity"), col.multNTracksPV()); + registryTriggerQA.fill(HIST("PD/tight/fZvtx"), col.posZ()); + registryTriggerQA.fill(HIST("PD/tight/fSE_antiparticle"), kstar); + registryTriggerQA.fill(HIST("PD/tight/fAntiProtonPtVskstar"), vecAntiProton.at(p1).Pt(), kstar); + registryTriggerQA.fill(HIST("PD/tight/fAntiDeuteronPtVskstar"), vecAntiDeuteron.at(d1).Pt(), kstar); } } } } - - if (ConfTriggerSwitches->get("Switch", "pd") > 0.) { - // pd trigger - for (auto iProton = protons.begin(); iProton != protons.end(); ++iProton) { - for (auto iDeuteron = deuterons.begin(); iDeuteron != deuterons.end(); ++iDeuteron) { - kstar = getkstar(*iProton, *iDeuteron); - registry.fill(HIST("pd/fSE_particle"), kstar); - registry.fill(HIST("pd/fProtonPtVskstar"), kstar, (*iProton).Pt()); - registry.fill(HIST("pd/fDeuteronPtVskstar"), kstar, (*iDeuteron).Pt()); - if (kstar < ConfKstarLimits->get(static_cast(0), CFTrigger::kPD)) { - if (ConfDownsample->get("Switch", "PD") > 0) { - if (rng->Uniform(0., 1.) < ConfDownsample->get("Factor", "PD")) { - registry.fill(HIST("pd/fSE_particle_downsample"), kstar); - lowKstarPairs[CFTrigger::kPD] += 1; - } - } else { - lowKstarPairs[CFTrigger::kPD] += 1; - } + } + // LD + if (TriggerSelections.filterSwitches->get("Switch", "LD") > 0) { + for (size_t l1 = 0; l1 < vecLambda.size(); l1++) { + for (size_t d1 = 0; d1 < vecDeuteron.size(); d1++) { + if (idxLambdaDaughProton.at(l1) == idxDeuteron.at(d1)) { + continue; + } + kstar = getkstar(vecLambda.at(l1), vecDeuteron.at(d1)); + registryTriggerQA.fill(HIST("LD/all/fMultiplicity"), col.multNTracksPV()); + registryTriggerQA.fill(HIST("LD/all/fZvtx"), col.posZ()); + registryTriggerQA.fill(HIST("LD/all/fSE_particle"), kstar); + registryTriggerQA.fill(HIST("LD/all/fLambdaPtVskstar"), vecLambda.at(l1).Pt(), kstar); + registryTriggerQA.fill(HIST("LD/all/fDeuteronPtVskstar"), vecDeuteron.at(d1).Pt(), kstar); + if (kstar < TriggerSelections.limits->get("Loose Limit", "LD")) { + signalLooseLimit[cf_trigger::kLD] += 1; + registryTriggerQA.fill(HIST("LD/loose/fMultiplicity"), col.multNTracksPV()); + registryTriggerQA.fill(HIST("LD/loose/fZvtx"), col.posZ()); + registryTriggerQA.fill(HIST("LD/loose/fSE_particle"), kstar); + registryTriggerQA.fill(HIST("LD/loose/fLambdaPtVskstar"), vecLambda.at(l1).Pt(), kstar); + registryTriggerQA.fill(HIST("LD/loose/fDeuteronPtVskstar"), vecDeuteron.at(d1).Pt(), kstar); + if (kstar < TriggerSelections.limits->get("Tight Limit", "LD")) { + signalTightLimit[cf_trigger::kLD] += 1; + registryTriggerQA.fill(HIST("LD/tight/fMultiplicity"), col.multNTracksPV()); + registryTriggerQA.fill(HIST("LD/tight/fZvtx"), col.posZ()); + registryTriggerQA.fill(HIST("LD/tight/fSE_particle"), kstar); + registryTriggerQA.fill(HIST("LD/tight/fLambdaPtVskstar"), vecLambda.at(l1).Pt(), kstar); + registryTriggerQA.fill(HIST("LD/tight/fDeuteronPtVskstar"), vecDeuteron.at(d1).Pt(), kstar); } } } - - for (auto iAntiProton = antiprotons.begin(); iAntiProton != antiprotons.end(); ++iAntiProton) { - for (auto iAntiDeuteron = antideuterons.begin(); iAntiDeuteron != antideuterons.end(); ++iAntiDeuteron) { - kstar = getkstar(*iAntiProton, *iAntiDeuteron); - registry.fill(HIST("pd/fSE_antiparticle"), kstar); - registry.fill(HIST("pd/fAntiProtonPtVskstar"), kstar, (*iAntiProton).Pt()); - registry.fill(HIST("pd/fAntiDeuteronPtVskstar"), kstar, (*iAntiDeuteron).Pt()); - if (kstar < ConfKstarLimits->get(static_cast(0), CFTrigger::kPD)) { - if (ConfDownsample->get("Switch", "aPaD") > 0) { - if (rng->Uniform(0., 1.) < ConfDownsample->get("Factor", "aPaD")) { - registry.fill(HIST("pd/fSE_antiparticle_downsample"), kstar); - lowKstarPairs[CFTrigger::kPD] += 1; - } - } else { - lowKstarPairs[CFTrigger::kPD] += 1; - } + } + for (size_t l1 = 0; l1 < vecAntiLambda.size(); l1++) { + for (size_t d1 = 0; d1 < vecAntiDeuteron.size(); d1++) { + if (idxAntiLambdaDaughProton.at(l1) == idxAntiDeuteron.at(d1)) { + continue; + } + kstar = getkstar(vecAntiLambda.at(l1), vecAntiDeuteron.at(d1)); + registryTriggerQA.fill(HIST("LD/all/fMultiplicity"), col.multNTracksPV()); + registryTriggerQA.fill(HIST("LD/all/fZvtx"), col.posZ()); + registryTriggerQA.fill(HIST("LD/all/fSE_antiparticle"), kstar); + registryTriggerQA.fill(HIST("LD/all/fAntiLambdaPtVskstar"), vecAntiLambda.at(l1).Pt(), kstar); + registryTriggerQA.fill(HIST("LD/all/fAntiDeuteronPtVskstar"), vecAntiDeuteron.at(d1).Pt(), kstar); + if (kstar < TriggerSelections.limits->get("Loose Limit", "LD")) { + signalLooseLimit[cf_trigger::kLD] += 1; + registryTriggerQA.fill(HIST("LD/loose/fMultiplicity"), col.multNTracksPV()); + registryTriggerQA.fill(HIST("LD/loose/fZvtx"), col.posZ()); + registryTriggerQA.fill(HIST("LD/loose/fSE_antiparticle"), kstar); + registryTriggerQA.fill(HIST("LD/loose/fAntiLambdaPtVskstar"), vecAntiLambda.at(l1).Pt(), kstar); + registryTriggerQA.fill(HIST("LD/loose/fAntiDeuteronPtVskstar"), vecAntiDeuteron.at(d1).Pt(), kstar); + if (kstar < TriggerSelections.limits->get("Tight Limit", "LD")) { + signalTightLimit[cf_trigger::kLD] += 1; + registryTriggerQA.fill(HIST("LD/tight/fMultiplicity"), col.multNTracksPV()); + registryTriggerQA.fill(HIST("LD/tight/fZvtx"), col.posZ()); + registryTriggerQA.fill(HIST("LD/tight/fSE_antiparticle"), kstar); + registryTriggerQA.fill(HIST("LD/tight/fAntiLambdaPtVskstar"), vecAntiLambda.at(l1).Pt(), kstar); + registryTriggerQA.fill(HIST("LD/tight/fAntiDeuteronPtVskstar"), vecAntiDeuteron.at(d1).Pt(), kstar); } } } } - if (ConfTriggerSwitches->get("Switch", "Ld") > 0.) { - // ld trigger - for (auto iDeuteron = deuterons.begin(); iDeuteron != deuterons.end(); ++iDeuteron) { - for (auto iLambda = lambdas.begin(); iLambda != lambdas.end(); ++iLambda) { - kstar = getkstar(*iDeuteron, *iLambda); - registry.fill(HIST("ld/fSE_particle"), kstar); - registry.fill(HIST("ld/fDeuteronPtVskstar"), kstar, (*iDeuteron).Pt()); - registry.fill(HIST("ld/fLambdaPtVskstar"), kstar, (*iLambda).Pt()); - if (kstar < ConfKstarLimits->get(static_cast(0), CFTrigger::kLD)) { - if (ConfDownsample->get("Switch", "LD") > 0) { - if (rng->Uniform(0., 1.) < ConfDownsample->get("Factor", "LD")) { - registry.fill(HIST("ld/fSE_particle_downsample"), kstar); - lowKstarPairs[CFTrigger::kLD] += 1; - } - } else { - lowKstarPairs[CFTrigger::kLD] += 1; - } + } + // PhiD + if (TriggerSelections.filterSwitches->get("Switch", "PhiD") > 0) { + for (size_t phi1 = 0; phi1 < vecPhi.size(); phi1++) { + for (size_t d1 = 0; d1 < vecDeuteron.size(); d1++) { + if (idxPhiDaughPos.at(phi1) == idxDeuteron.at(d1)) { + continue; + } + kstar = getkstar(vecPhi.at(phi1), vecDeuteron.at(d1)); + registryTriggerQA.fill(HIST("PhiD/all/fMultiplicity"), col.multNTracksPV()); + registryTriggerQA.fill(HIST("PhiD/all/fZvtx"), col.posZ()); + registryTriggerQA.fill(HIST("PhiD/all/fSE_particle"), kstar); + registryTriggerQA.fill(HIST("PhiD/all/fPhiPtVskstar"), vecPhi.at(phi1).Pt(), kstar); + registryTriggerQA.fill(HIST("PhiD/all/fDeuteronPtVskstar"), vecDeuteron.at(d1).Pt(), kstar); + registryTriggerQA.fill(HIST("PhiD/all/fPhiInvMassVskstar"), vecPhi.at(phi1).M(), kstar); + if (kstar < TriggerSelections.limits->get("Loose Limit", "PhiD")) { + signalLooseLimit[cf_trigger::kPhiD] += 1; + registryTriggerQA.fill(HIST("PhiD/loose/fMultiplicity"), col.multNTracksPV()); + registryTriggerQA.fill(HIST("PhiD/loose/fZvtx"), col.posZ()); + registryTriggerQA.fill(HIST("PhiD/loose/fSE_particle"), kstar); + registryTriggerQA.fill(HIST("PhiD/loose/fPhiPtVskstar"), vecPhi.at(phi1).Pt(), kstar); + registryTriggerQA.fill(HIST("PhiD/loose/fDeuteronPtVskstar"), vecDeuteron.at(d1).Pt(), kstar); + registryTriggerQA.fill(HIST("PhiD/loose/fPhiInvMassVskstar"), vecPhi.at(phi1).M(), kstar); + if (kstar < TriggerSelections.limits->get("Tight Limit", "PhiD") && + vecPhi.at(phi1).M() > PhiSelections.tightInvMassLow.value && vecPhi.at(phi1).M() < PhiSelections.tightInvMassUp.value) { + signalTightLimit[cf_trigger::kPhiD] += 1; + registryTriggerQA.fill(HIST("PhiD/tight/fMultiplicity"), col.multNTracksPV()); + registryTriggerQA.fill(HIST("PhiD/tight/fZvtx"), col.posZ()); + registryTriggerQA.fill(HIST("PhiD/tight/fSE_particle"), kstar); + registryTriggerQA.fill(HIST("PhiD/tight/fPhiPtVskstar"), vecPhi.at(phi1).Pt(), kstar); + registryTriggerQA.fill(HIST("PhiD/tight/fDeuteronPtVskstar"), vecDeuteron.at(d1).Pt(), kstar); + registryTriggerQA.fill(HIST("PhiD/tight/fPhiInvMassVskstar"), vecPhi.at(phi1).M(), kstar); } } } - for (auto iAntiDeuteron = antideuterons.begin(); iAntiDeuteron != antideuterons.end(); ++iAntiDeuteron) { - for (auto iAntiLambda = antilambdas.begin(); iAntiLambda != antilambdas.end(); ++iAntiLambda) { - kstar = getkstar(*iAntiDeuteron, *iAntiLambda); - registry.fill(HIST("ld/fSE_antiparticle"), kstar); - registry.fill(HIST("ld/fAntiDeuteronPtVskstar"), kstar, (*iAntiDeuteron).Pt()); - registry.fill(HIST("ld/fAntiLambdaPtVskstar"), kstar, (*iAntiLambda).Pt()); - if (kstar < ConfKstarLimits->get(static_cast(0), CFTrigger::kLD)) { - if (ConfDownsample->get("Switch", "aLaD") > 0) { - if (rng->Uniform(0., 1.) < ConfDownsample->get("Factor", "aLaD")) { - registry.fill(HIST("ld/fSE_antiparticle_downsample"), kstar); - lowKstarPairs[CFTrigger::kLD] += 1; - } - } else { - lowKstarPairs[CFTrigger::kLD] += 1; - } + } + for (size_t phi1 = 0; phi1 < vecPhi.size(); phi1++) { + for (size_t d1 = 0; d1 < vecAntiDeuteron.size(); d1++) { + if (idxPhiDaughNeg.at(phi1) == idxAntiDeuteron.at(d1)) { + continue; + } + kstar = getkstar(vecPhi.at(phi1), vecAntiDeuteron.at(d1)); + registryTriggerQA.fill(HIST("PhiD/all/fMultiplicity"), col.multNTracksPV()); + registryTriggerQA.fill(HIST("PhiD/all/fZvtx"), col.posZ()); + registryTriggerQA.fill(HIST("PhiD/all/fSE_antiparticle"), kstar); + registryTriggerQA.fill(HIST("PhiD/all/fPhiPtVskstar"), vecPhi.at(phi1).Pt(), kstar); + registryTriggerQA.fill(HIST("PhiD/all/fAntiDeuteronPtVskstar"), vecAntiDeuteron.at(d1).Pt(), kstar); + registryTriggerQA.fill(HIST("PhiD/all/fPhiInvMassVskstar"), vecPhi.at(phi1).M(), kstar); + if (kstar < TriggerSelections.limits->get("Loose Limit", "PhiD")) { + signalLooseLimit[cf_trigger::kPhiD] += 1; + registryTriggerQA.fill(HIST("PhiD/loose/fMultiplicity"), col.multNTracksPV()); + registryTriggerQA.fill(HIST("PhiD/loose/fZvtx"), col.posZ()); + registryTriggerQA.fill(HIST("PhiD/loose/fSE_antiparticle"), kstar); + registryTriggerQA.fill(HIST("PhiD/loose/fPhiPtVskstar"), vecPhi.at(phi1).Pt(), kstar); + registryTriggerQA.fill(HIST("PhiD/loose/fAntiDeuteronPtVskstar"), vecAntiDeuteron.at(d1).Pt(), kstar); + registryTriggerQA.fill(HIST("PhiD/loose/fPhiInvMassVskstar"), vecPhi.at(phi1).M(), kstar); + if (kstar < TriggerSelections.limits->get("Tight Limit", "PhiD") && + vecPhi.at(phi1).M() > PhiSelections.tightInvMassLow.value && vecPhi.at(phi1).M() < PhiSelections.tightInvMassUp.value) { + signalTightLimit[cf_trigger::kPhiD] += 1; + registryTriggerQA.fill(HIST("PhiD/tight/fMultiplicity"), col.multNTracksPV()); + registryTriggerQA.fill(HIST("PhiD/tight/fZvtx"), col.posZ()); + registryTriggerQA.fill(HIST("PhiD/tight/fSE_antiparticle"), kstar); + registryTriggerQA.fill(HIST("PhiD/tight/fPhiPtVskstar"), vecPhi.at(phi1).Pt(), kstar); + registryTriggerQA.fill(HIST("PhiD/tight/fAntiDeuteronPtVskstar"), vecAntiDeuteron.at(d1).Pt(), kstar); + registryTriggerQA.fill(HIST("PhiD/tight/fPhiInvMassVskstar"), vecPhi.at(phi1).M(), kstar); } } } } - } // if(isSelectedEvent) - - // create tags for three body triggers - if (lowQ3Triplets[CFTrigger::kPPP] > 0) { - keepEvent3N[CFTrigger::kPPP] = true; - registry.fill(HIST("fProcessedEvents"), 2); - registry.fill(HIST("ppp/fMultiplicity"), col.multNTracksPV()); - registry.fill(HIST("ppp/fZvtx"), col.posZ()); - } - if (lowQ3Triplets[CFTrigger::kPPL] > 0) { - keepEvent3N[CFTrigger::kPPL] = true; - registry.fill(HIST("fProcessedEvents"), 3); - registry.fill(HIST("ppl/fMultiplicity"), col.multNTracksPV()); - registry.fill(HIST("ppl/fZvtx"), col.posZ()); - } - if (lowQ3Triplets[CFTrigger::kPLL] > 0) { - keepEvent3N[CFTrigger::kPLL] = true; - registry.fill(HIST("fProcessedEvents"), 4); - registry.fill(HIST("pll/fMultiplicity"), col.multNTracksPV()); - registry.fill(HIST("pll/fZvtx"), col.posZ()); - } - if (lowQ3Triplets[CFTrigger::kLLL] > 0) { - keepEvent3N[CFTrigger::kLLL] = true; - registry.fill(HIST("fProcessedEvents"), 5); - registry.fill(HIST("lll/fMultiplicity"), col.multNTracksPV()); - registry.fill(HIST("lll/fZvtx"), col.posZ()); - } - if (lowQ3Triplets[CFTrigger::kPPPhi] > 0) { - keepEvent3N[CFTrigger::kPPPhi] = true; - registry.fill(HIST("fProcessedEvents"), 6); - registry.fill(HIST("ppphi/fMultiplicity"), col.multNTracksPV()); - registry.fill(HIST("ppphi/fZvtx"), col.posZ()); } - if (lowQ3Triplets[CFTrigger::kPPRho] > 0) { - keepEvent3N[CFTrigger::kPPRho] = true; - registry.fill(HIST("fProcessedEvents"), 7); - registry.fill(HIST("ppRho/fMultiplicity"), col.multNTracksPV()); - registry.fill(HIST("ppRho/fZvtx"), col.posZ()); + // RhoD + if (TriggerSelections.filterSwitches->get("Switch", "RhoD") > 0) { + for (size_t r1 = 0; r1 < vecRho.size(); r1++) { + for (size_t d1 = 0; d1 < vecDeuteron.size(); d1++) { + if (idxRhoDaughPos.at(r1) == idxDeuteron.at(d1)) { + continue; + } + kstar = getkstar(vecRho.at(r1), vecDeuteron.at(d1)); + registryTriggerQA.fill(HIST("RhoD/all/fMultiplicity"), col.multNTracksPV()); + registryTriggerQA.fill(HIST("RhoD/all/fZvtx"), col.posZ()); + registryTriggerQA.fill(HIST("RhoD/all/fSE_particle"), kstar); + registryTriggerQA.fill(HIST("RhoD/all/fRhoPtVskstar"), vecRho.at(r1).Pt(), kstar); + registryTriggerQA.fill(HIST("RhoD/all/fDeuteronPtVskstar"), vecDeuteron.at(d1).Pt(), kstar); + registryTriggerQA.fill(HIST("RhoD/all/fRhoInvMassVskstar"), vecRho.at(r1).M(), kstar); + if (kstar < TriggerSelections.limits->get("Loose Limit", "RhoD")) { + signalLooseLimit[cf_trigger::kRhoD] += 1; + registryTriggerQA.fill(HIST("RhoD/loose/fMultiplicity"), col.multNTracksPV()); + registryTriggerQA.fill(HIST("RhoD/loose/fZvtx"), col.posZ()); + registryTriggerQA.fill(HIST("RhoD/loose/fSE_particle"), kstar); + registryTriggerQA.fill(HIST("RhoD/loose/fRhoPtVskstar"), vecRho.at(r1).Pt(), kstar); + registryTriggerQA.fill(HIST("RhoD/loose/fDeuteronPtVskstar"), vecDeuteron.at(d1).Pt(), kstar); + registryTriggerQA.fill(HIST("RhoD/loose/fRhoInvMassVskstar"), vecRho.at(r1).M(), kstar); + if (kstar < TriggerSelections.limits->get("Tight Limit", "RhoD") && + vecRho.at(r1).M() > RhoSelections.tightInvMassLow.value && vecRho.at(r1).M() < RhoSelections.tightInvMassUp.value) { + signalTightLimit[cf_trigger::kRhoD] += 1; + registryTriggerQA.fill(HIST("RhoD/tight/fMultiplicity"), col.multNTracksPV()); + registryTriggerQA.fill(HIST("RhoD/tight/fZvtx"), col.posZ()); + registryTriggerQA.fill(HIST("RhoD/tight/fSE_particle"), kstar); + registryTriggerQA.fill(HIST("RhoD/tight/fRhoPtVskstar"), vecRho.at(r1).Pt(), kstar); + registryTriggerQA.fill(HIST("RhoD/tight/fDeuteronPtVskstar"), vecDeuteron.at(d1).Pt(), kstar); + registryTriggerQA.fill(HIST("RhoD/tight/fRhoInvMassVskstar"), vecRho.at(r1).M(), kstar); + } + } + } + } + for (size_t r1 = 0; r1 < vecRho.size(); r1++) { + for (size_t d1 = 0; d1 < vecAntiDeuteron.size(); d1++) { + if (idxRhoDaughNeg.at(r1) == idxAntiDeuteron.at(d1)) { + continue; + } + kstar = getkstar(vecRho.at(r1), vecAntiDeuteron.at(d1)); + registryTriggerQA.fill(HIST("RhoD/all/fMultiplicity"), col.multNTracksPV()); + registryTriggerQA.fill(HIST("RhoD/all/fZvtx"), col.posZ()); + registryTriggerQA.fill(HIST("RhoD/all/fSE_antiparticle"), kstar); + registryTriggerQA.fill(HIST("RhoD/all/fRhoPtVskstar"), vecRho.at(r1).Pt(), kstar); + registryTriggerQA.fill(HIST("RhoD/all/fAntiDeuteronPtVskstar"), vecAntiDeuteron.at(d1).Pt(), kstar); + registryTriggerQA.fill(HIST("RhoD/all/fRhoInvMassVskstar"), vecRho.at(r1).M(), kstar); + if (kstar < TriggerSelections.limits->get("Loose Limit", "RhoD")) { + signalLooseLimit[cf_trigger::kRhoD] += 1; + registryTriggerQA.fill(HIST("RhoD/loose/fMultiplicity"), col.multNTracksPV()); + registryTriggerQA.fill(HIST("RhoD/loose/fZvtx"), col.posZ()); + registryTriggerQA.fill(HIST("RhoD/loose/fSE_antiparticle"), kstar); + registryTriggerQA.fill(HIST("RhoD/loose/fRhoPtVskstar"), vecRho.at(r1).Pt(), kstar); + registryTriggerQA.fill(HIST("RhoD/loose/fAntiDeuteronPtVskstar"), vecAntiDeuteron.at(d1).Pt(), kstar); + registryTriggerQA.fill(HIST("RhoD/loose/fRhoInvMassVskstar"), vecRho.at(r1).M(), kstar); + if (kstar < TriggerSelections.limits->get("Tight Limit", "RhoD") && + vecRho.at(r1).M() > RhoSelections.tightInvMassLow.value && vecRho.at(r1).M() < RhoSelections.tightInvMassUp.value) { + signalTightLimit[cf_trigger::kRhoD] += 1; + registryTriggerQA.fill(HIST("RhoD/tight/fMultiplicity"), col.multNTracksPV()); + registryTriggerQA.fill(HIST("RhoD/tight/fZvtx"), col.posZ()); + registryTriggerQA.fill(HIST("RhoD/tight/fSE_antiparticle"), kstar); + registryTriggerQA.fill(HIST("RhoD/tight/fRhoPtVskstar"), vecRho.at(r1).Pt(), kstar); + registryTriggerQA.fill(HIST("RhoD/tight/fAntiDeuteronPtVskstar"), vecAntiDeuteron.at(d1).Pt(), kstar); + registryTriggerQA.fill(HIST("RhoD/tight/fRhoInvMassVskstar"), vecRho.at(r1).M(), kstar); + } + } + } + } } - // create tags for two body triggers - if (lowKstarPairs[CFTrigger::kPD] > 0) { - keepEvent2N[CFTrigger::kPD] = true; - registry.fill(HIST("fProcessedEvents"), 8); - registry.fill(HIST("pd/fMultiplicity"), col.multNTracksPV()); - registry.fill(HIST("pd/fZvtx"), col.posZ()); + for (int i = 0; i < cf_trigger::kNTriggers; i++) { + if (signalLooseLimit[i] > 0) { + registryTriggerQA.fill(HIST("fProcessedEvents"), 3 + 2 * i); // need offset for filling + keepEventLooseLimit[i] = true; + } + if (signalTightLimit[i] > 0) { + registryTriggerQA.fill(HIST("fProcessedEvents"), 3 + 2 * i + 1); // need offset for filling + keepEventTightLimit[i] = true; + } + for (int j = i; j < cf_trigger::kNTriggers; j++) { + if (signalLooseLimit[i] > 0 && signalLooseLimit[j]) { + registryTriggerQA.fill(HIST("fTriggerCorrelations"), 2 * i, 2 * j); + } + if (signalLooseLimit[i] > 0 && signalTightLimit[j]) { // only one combination needed, fill only entries above diagonal + registryTriggerQA.fill(HIST("fTriggerCorrelations"), 2 * i, 2 * j + 1); + } + if (signalTightLimit[i] > 0 && signalTightLimit[j]) { + registryTriggerQA.fill(HIST("fTriggerCorrelations"), 2 * i + 1, 2 * j + 1); + } + } } - if (lowKstarPairs[CFTrigger::kLD] > 0) { - keepEvent2N[CFTrigger::kLD] = true; - registry.fill(HIST("fProcessedEvents"), 9); - registry.fill(HIST("ld/fMultiplicity"), col.multNTracksPV()); - registry.fill(HIST("ld/fZvtx"), col.posZ()); + + if (keepEventLooseLimit[cf_trigger::kPPP] || + keepEventLooseLimit[cf_trigger::kPPL] || + keepEventLooseLimit[cf_trigger::kPLL] || + keepEventLooseLimit[cf_trigger::kLLL] || + keepEventLooseLimit[cf_trigger::kPPPhi] || + keepEventLooseLimit[cf_trigger::kPPRho] || + keepEventLooseLimit[cf_trigger::kPD] || + keepEventLooseLimit[cf_trigger::kLD] || + keepEventLooseLimit[cf_trigger::kPhiD] || + keepEventLooseLimit[cf_trigger::kRhoD]) { + registryTriggerQA.fill(HIST("fProcessedEvents"), 1); } - tags(keepEvent3N[CFTrigger::kPPP], - keepEvent3N[CFTrigger::kPPL], - keepEvent3N[CFTrigger::kPLL], - keepEvent3N[CFTrigger::kLLL], - keepEvent3N[CFTrigger::kPPPhi], - // keepEvent3N[CFTrigger::kPPRho], //To be changed once trigger is integrated - keepEvent2N[CFTrigger::kPD], - keepEvent2N[CFTrigger::kLD]); - - if (!keepEvent3N[CFTrigger::kPPP] && !keepEvent3N[CFTrigger::kPPL] && !keepEvent3N[CFTrigger::kPLL] && !keepEvent3N[CFTrigger::kLLL] && !keepEvent3N[CFTrigger::kPPPhi] && !keepEvent3N[CFTrigger::kPPRho] && - !keepEvent2N[CFTrigger::kPD] && !keepEvent2N[CFTrigger::kLD]) { - registry.fill(HIST("fProcessedEvents"), 1); + if (keepEventTightLimit[cf_trigger::kPPP] || + keepEventTightLimit[cf_trigger::kPPL] || + keepEventTightLimit[cf_trigger::kPLL] || + keepEventTightLimit[cf_trigger::kLLL] || + keepEventTightLimit[cf_trigger::kPPPhi] || + keepEventTightLimit[cf_trigger::kPPRho] || + keepEventTightLimit[cf_trigger::kPD] || + keepEventTightLimit[cf_trigger::kLD] || + keepEventTightLimit[cf_trigger::kPhiD] || + keepEventTightLimit[cf_trigger::kRhoD]) { + registryTriggerQA.fill(HIST("fProcessedEvents"), 2); } - } + + tags(keepEventTightLimit[cf_trigger::kPPP], keepEventLooseLimit[cf_trigger::kPPP], + keepEventTightLimit[cf_trigger::kPPL], keepEventLooseLimit[cf_trigger::kPPL], + keepEventTightLimit[cf_trigger::kPLL], keepEventLooseLimit[cf_trigger::kPLL], + keepEventTightLimit[cf_trigger::kLLL], keepEventLooseLimit[cf_trigger::kLLL], + keepEventTightLimit[cf_trigger::kPPPhi], keepEventLooseLimit[cf_trigger::kPPPhi], + keepEventTightLimit[cf_trigger::kPPRho], keepEventLooseLimit[cf_trigger::kPPRho], + keepEventTightLimit[cf_trigger::kPD], keepEventLooseLimit[cf_trigger::kPD], + keepEventTightLimit[cf_trigger::kLD], keepEventLooseLimit[cf_trigger::kLD], + keepEventTightLimit[cf_trigger::kPhiD], keepEventLooseLimit[cf_trigger::kPhiD], + keepEventTightLimit[cf_trigger::kRhoD], keepEventLooseLimit[cf_trigger::kRhoD]); + }; }; WorkflowSpec defineDataProcessing(ConfigContext const& cfg) { - return WorkflowSpec{adaptAnalysisTask(cfg)}; + return WorkflowSpec{adaptAnalysisTask(cfg)}; } diff --git a/EventFiltering/PWGEM/HeavyNeutralMesonFilter.cxx b/EventFiltering/PWGEM/HeavyNeutralMesonFilter.cxx index a2941317ec6..abfc9dec88f 100644 --- a/EventFiltering/PWGEM/HeavyNeutralMesonFilter.cxx +++ b/EventFiltering/PWGEM/HeavyNeutralMesonFilter.cxx @@ -11,13 +11,12 @@ /// /// \file HeavyNeutralMesonFilter.cxx /// -/// \brief This code loops over collisions to filter events contaning heavy mesons (omega or eta') using EMCal clusters and V0s (PCM) +/// \brief This code loops over collisions to filter events contaning heavy neutral mesons (omega or eta') using EMCal clusters and V0s (PCM) /// -/// \author Nicolas Strangmann (nicolas.strangmann@cern.ch) - Goethe University Frankfurt; Maximilian Korwieser (maximilian.korwieser@cern.ch) - Technical University Munich +/// \author Nicolas Strangmann (nicolas.strangmann@cern.ch) - Goethe University Frankfurt; Maximilian Korwieser (maximilian.korwieser@cern.ch) - Technical University Munich /// #include -#include #include #include @@ -27,6 +26,7 @@ #include "TRandom3.h" #include "PWGEM/PhotonMeson/Utils/HNMUtilities.h" +#include "PWGJE/DataModel/EMCALMatchedCollisions.h" #include "Common/DataModel/PIDResponse.h" #include "Common/DataModel/PIDResponseITS.h" @@ -51,16 +51,16 @@ using namespace o2::aod::pwgem::photonmeson; namespace o2::aod { using MyBCs = soa::Join; -using MyCollisions = soa::Join; +using MyCollisions = soa::Join; using MyCollision = MyCollisions::iterator; using SelectedTracks = soa::Join; } // namespace o2::aod -namespace CFTrigger +namespace hnmtrigger { -enum CFFemtoTriggers { +enum FemtoTriggers { kPPOmega, kPPEtaPrime, kOmegaD, @@ -70,7 +70,7 @@ enum CFFemtoTriggers { kNFemtoTriggers }; -enum FemtoPartners { +enum TracksPID { kProton, kDeuteron, kPion, @@ -84,13 +84,10 @@ enum PIDLimits { kTPCMin, kITSmax, kNPIDLimits }; -const std::vector SpeciesName{"proton", "Deuteron", "pion"}; // ToDo include charged pions - -const std::vector PtCutsName{"Pt min", "Pt max", "P TOF thres"}; - -const std::vector PidCutsName{"TPC min", "TPC max", "TPCTOF max", "ITS min", "ITS max"}; - -const std::vector FemtoFilterNames{"PPOmega", "PPEtaPrime", "Omegad", "EtaPrimed", "OmegaP", "EtaPrimeP"}; +const std::vector speciesName{"proton", "Deuteron", "pion"}; +const std::vector pTCutsName{"Pt min", "Pt max", "P TOF thres"}; +const std::vector pidCutsName{"TPC min", "TPC max", "TPCTOF max", "ITS min", "ITS max"}; +const std::vector femtoFilterNames{"PPOmega", "PPEtaPrime", "Omegad", "EtaPrimed", "OmegaP", "EtaPrimeP"}; // configs for tracks const float pidcutsTable[kNFemtoPartners][kNPIDLimits]{ @@ -103,165 +100,115 @@ const float ptcutsTable[kNFemtoPartners][3]{ {0.55f, 2.f, 1.2f}, {0.35f, 6.f, 0.75f}}; -const float TPCNClustersMin[1][kNFemtoPartners]{ - {80.0f, 80.0f, 80.0f}}; -const float ITSNClustersMin[1][kNFemtoPartners]{ - {4, 4, 4}}; +const float nClusterMinTPC[1][kNFemtoPartners]{{80.0f, 80.0f, 80.0f}}; +const float nClusterMinITS[1][kNFemtoPartners]{{4, 4, 4}}; -static const float triggerSwitches[1][kNFemtoTriggers]{ - {1, 1, 1, 1, 1, 1}}; -const float TriggerLimits[1][kNFemtoTriggers]{ - {1.f, 1.f, 1.f, 1.f, 1.f, 1.f}}; -} // namespace CFTrigger +static const float triggerSwitches[1][kNFemtoTriggers]{{1, 1, 1, 1, 1, 1}}; +const float triggerLimits[1][kNFemtoTriggers]{{1.f, 1.f, 1.f, 1.f, 1.f, 1.f}}; +} // namespace hnmtrigger struct HeavyNeutralMesonFilter { + Produces tags; + + // --------------------------------> Configurables <------------------------------------ + // - Event selection cuts + // - Track selection cuts + // - Cluster shifts + // - HNM mass selection windows + // - HNM min pTs / k*'s + // ------------------------------------------------------------------------------------- + // ---> Event selection + Configurable confEvtSelectZvtx{"confEvtSelectZvtx", true, "Event selection includes max. z-Vertex"}; + Configurable confEvtZvtx{"confEvtZvtx", 10.f, "Evt sel: Max. z-Vertex (cm)"}; + Configurable confEvtRequireSel8{"confEvtRequireSel8", false, "Evt sel: check for offline selection (sel8)"}; + + // ---> Track selection + Configurable> cfgPtCuts{"cfgPtCuts", {hnmtrigger::ptcutsTable[0], hnmtrigger::kNFemtoPartners, 3, hnmtrigger::speciesName, hnmtrigger::pTCutsName}, "Track pT selections"}; + Configurable cfgTrkEta{"cfgTrkEta", 0.9, "Eta"}; + Configurable> cfgTPCNClustersMin{"cfgTPCNClustersMin", {hnmtrigger::nClusterMinTPC[0], 1, hnmtrigger::kNFemtoPartners, std::vector{"TPCNClusMin"}, hnmtrigger::speciesName}, "Mininum of TPC Clusters"}; + Configurable cfgTrkTPCfCls{"cfgTrkTPCfCls", 0.83, "Minimum fraction of crossed rows over findable clusters"}; + Configurable cfgTrkTPCcRowsMin{"cfgTrkTPCcRowsMin", 70, "Minimum number of crossed TPC rows"}; + Configurable cfgTrkTPCsClsSharedFrac{"cfgTrkTPCsClsSharedFrac", 1.f, "Fraction of shared TPC clusters"}; + Configurable> cfgTrkITSnclsMin{"cfgTrkITSnclsMin", {hnmtrigger::nClusterMinITS[0], 1, hnmtrigger::kNFemtoPartners, std::vector{"Cut"}, hnmtrigger::speciesName}, "Minimum number of ITS clusters"}; + Configurable cfgTrkDCAxyMax{"cfgTrkDCAxyMax", 0.15, "Maximum DCA_xy"}; + Configurable cfgTrkDCAzMax{"cfgTrkDCAzMax", 0.3, "Maximum DCA_z"}; + Configurable cfgTrkMaxChi2PerClusterTPC{"cfgTrkMaxChi2PerClusterTPC", 4.0f, "Minimal track selection: max allowed chi2 per TPC cluster"}; // 4.0 is default of global tracks on 20.01.2023 + Configurable cfgTrkMaxChi2PerClusterITS{"cfgTrkMaxChi2PerClusterITS", 36.0f, "Minimal track selection: max allowed chi2 per ITS cluster"}; // 36.0 is default of global tracks on 20.01.2023 + + Configurable> cfgPIDCuts{"cfgPIDCuts", {hnmtrigger::pidcutsTable[0], hnmtrigger::kNFemtoPartners, hnmtrigger::kNPIDLimits, hnmtrigger::speciesName, hnmtrigger::pidCutsName}, "Femtopartner PID nsigma selections"}; // PID selections + + // ---> Configurables to allow for a shift in eta/phi of EMCal clusters to better align with extrapolated TPC tracks + Configurable cfgDoEMCShift{"cfgDoEMCShift", false, "Apply SM-wise shift in eta and phi to EMCal clusters to align with TPC tracks"}; + Configurable> cfgEMCEtaShift{"cfgEMCEtaShift", {0.f}, "values for SM-wise shift in eta to be added to EMCal clusters to align with TPC tracks"}; + Configurable> cfgEMCPhiShift{"cfgEMCPhiShift", {0.f}, "values for SM-wise shift in phi to be added to EMCal clusters to align with TPC tracks"}; + static const int nSMs = 20; + std::array emcEtaShift = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + std::array emcPhiShift = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + + // ---> Shift the omega/eta' mass based on the difference of the reconstructed mass of the pi0/eta to its PDG mass to reduce smearing caused by EMCal/PCM in photon measurement + Configurable cfgHNMMassCorrection{"cfgHNMMassCorrection", 1, "Use GG PDG mass to correct HNM mass (0 = off, 1 = subDeltaPi0, 2 = subLambda)"}; + + // ---> Mass windows for the selection of heavy neutral mesons (also based on mass of their light neutral meson decay daughter) + static constexpr float DefaultMassWindows[2][4] = {{0., 0.4, 0.6, 1.}, {0.4, 0.8, 0.8, 1.2}}; + Configurable> cfgMassWindowOmega{"cfgMassWindowOmega", {DefaultMassWindows[0], 4, {"pi0_min", "pi0_max", "omega_min", "omega_max"}}, "Mass window for selected omegas and their decay pi0"}; + Configurable> cfgMassWindowEtaPrime{"cfgMassWindowEtaPrime", {DefaultMassWindows[1], 4, {"eta_min", "eta_max", "etaprime_min", "etaprime_max"}}, "Mass window for selected eta' and their decay eta"}; + + // ---> Minimum pT values for the trigger decisions of the spectra and femto trigger. The femto triggers additionally require a given k*/Q3 + static constexpr float DefaultSpectraMinPts[4] = {1.8, 1.8, 2.6, 2.6}; + static constexpr float DefaultFemtoMinPts[4] = {1.8, 1.8, 2.6, 2.6}; + Configurable> cfgMinHNMPtsSpectrumTrigger{"cfgMinHNMPtsSpectrumTrigger", {DefaultSpectraMinPts, 4, {"PCM_omega", "PCM_etaprime", "EMC_omega", "EMC_etaprime"}}, "Minimum pT values for the spetra trigger decisions (GeV/c)"}; + Configurable> cfgMinHNMPtsFemtoTrigger{"cfgMinHNMPtsFemtoTrigger", {DefaultFemtoMinPts, 4, {"PCM_omega", "PCM_etaprime", "EMC_omega", "EMC_etaprime"}}, "Minimum pT values for the femto trigger decisions (GeV/c)"}; + Configurable> cfgKinematicLimits{"cfgKinematicLimits", {hnmtrigger::triggerLimits[0], 1, hnmtrigger::kNFemtoTriggers, std::vector{"Limit"}, hnmtrigger::femtoFilterNames}, "Maximum K* (Q_3) for two (three) body femto trigger"}; + + Configurable> cfgTriggerSwitches{"cfgTriggerSwitches", {hnmtrigger::triggerSwitches[0], 1, hnmtrigger::kNFemtoTriggers, std::vector{"Switch"}, hnmtrigger::femtoFilterNames}, "Turn on specific trigger"}; + + HistogramRegistry mHistManager{"HeavyNeutralMesonFilterHistograms", {}, OutputObjHandlingPolicy::AnalysisObject}; + + // Prepare vectors for different species + std::vector vGGs; + std::vector vHNMs; + std::vector etaPrimeEMC, etaPrimePCM, omegaEMC, omegaPCM, proton, antiproton, deuteron, antideuteron, pion, antipion; + float mMassProton = constants::physics::MassProton; + float mMassDeuteron = constants::physics::MassDeuteron; + float mMassPionCharged = constants::physics::MassPionCharged; - Configurable> ConfTriggerSwitches{ - "ConfTriggerSwitches", - {CFTrigger::triggerSwitches[0], 1, CFTrigger::kNFemtoTriggers, std::vector{"Switch"}, CFTrigger::FemtoFilterNames}, - "Turn on specific trigger"}; - - Configurable ConfKeepTwoBody{ - "ConfKeepTwoBody", - true, - "Turn on specific trigger selection"}; - - // PID selections - Configurable> - ConfPIDCuts{ - "ConfPIDCuts", - {CFTrigger::pidcutsTable[0], CFTrigger::kNFemtoPartners, CFTrigger::kNPIDLimits, CFTrigger::SpeciesName, CFTrigger::PidCutsName}, - "Femtopartner PID nsigma selections"}; - - Configurable> ConfPtCuts{ - "ConfPtCuts", - {CFTrigger::ptcutsTable[0], CFTrigger::kNFemtoPartners, 3, CFTrigger::SpeciesName, CFTrigger::PtCutsName}, - "Femtopartner pT selections"}; - - Configurable ConfTrkEta{ - "ConfTrkEta", - 0.9, - "Eta"}; - - Configurable> ConfTPCNClustersMin{ - "ConfTPCNClustersMin", - {CFTrigger::TPCNClustersMin[0], 1, CFTrigger::kNFemtoPartners, std::vector{"TPCNClusMin"}, CFTrigger::SpeciesName}, - "Mininum of TPC Clusters"}; - - Configurable ConfTrkTPCfCls{ - "ConfTrkTPCfCls", - 0.83, - "Minimum fraction of crossed rows over findable clusters"}; - Configurable ConfTrkTPCcRowsMin{ - "ConfTrkTPCcRowsMin", - 70, - "Minimum number of crossed TPC rows"}; - Configurable ConfTrkTPCsClsSharedFrac{ - "ConfTrkTPCsClsSharedFrac", - 1.f, - "Fraction of shared TPC clusters"}; - - Configurable> ConfTrkITSnclsMin{ - "ConfTrkITSnclsMin", - {CFTrigger::ITSNClustersMin[0], 1, CFTrigger::kNFemtoPartners, std::vector{"Cut"}, CFTrigger::SpeciesName}, - "Minimum number of ITS clusters"}; - - Configurable ConfTrkDCAxyMax{ - "ConfTrkDCAxyMax", - 0.15, - "Maximum DCA_xy"}; - Configurable ConfTrkDCAzMax{ - "ConfTrkDCAzMax", - 0.3, - "Maximum DCA_z"}; - - Configurable - ConfTrkMaxChi2PerClusterTPC{ - "ConfTrkMaxChi2PerClusterTPC", - 4.0f, - "Minimal track selection: max allowed chi2 per TPC cluster"}; // 4.0 is default of - // global tracks - // on 20.01.2023 - Configurable - ConfTrkMaxChi2PerClusterITS{ - "ConfTrkMaxChi2PerClusterITS", - 36.0f, - "Minimal track selection: max allowed chi2 per ITS cluster"}; // 36.0 is default of - // global tracks - // on 20.01.2023 - - Configurable> ConfKinematicLimits{ - "ConfKstarLimits", - {CFTrigger::TriggerLimits[0], 1, CFTrigger::kNFemtoTriggers, std::vector{"Limit"}, CFTrigger::FemtoFilterNames}, - "hypermomentum limit for two body trigger"}; - - // Configs for events - Configurable ConfEvtSelectZvtx{ - "ConfEvtSelectZvtx", - true, - "Event selection includes max. z-Vertex"}; - Configurable ConfEvtZvtx{"ConfEvtZvtx", - 10.f, - "Evt sel: Max. z-Vertex (cm)"}; - Configurable ConfEvtOfflineCheck{ - "ConfEvtOfflineCheck", - false, - "Evt sel: check for offline selection"}; - - Configurable ConfDoEMCShift{"ConfDoEMCShift", false, "Apply SM-wise shift in eta and phi to EMCal clusters to align with TPC tracks"}; - Configurable> ConfEMCEtaShift{"ConfEMCEtaShift", {0.f}, "values for SM-wise shift in eta to be added to EMCal clusters to align with TPC tracks"}; - Configurable> ConfEMCPhiShift{"ConfEMCPhiShift", {0.f}, "values for SM-wise shift in phi to be added to EMCal clusters to align with TPC tracks"}; - std::array EMCEtaShift = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - std::array EMCPhiShift = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + Preslice perCollisionPCM = aod::v0photonkf::collisionId; + Preslice perCollisionEMC = aod::skimmedcluster::collisionId; + + bool colContainsPCMOmega, colContainsEMCOmega, colContainsPCMEtaPrime, colContainsEMCEtaPrime = false; template - bool isSelectedTrack(T const& track, CFTrigger::FemtoPartners partSpecies) + bool isSelectedTrack(T const& track, hnmtrigger::TracksPID partSpecies) { - const auto pT = track.pt(); - const auto eta = track.eta(); - const auto tpcNClsF = track.tpcNClsFound(); - const auto tpcRClsC = track.tpcCrossedRowsOverFindableCls(); - const auto tpcNClsC = track.tpcNClsCrossedRows(); - const auto tpcNClsSFrac = track.tpcFractionSharedCls(); - const auto itsNCls = track.itsNCls(); - const auto dcaXY = track.dcaXY(); - const auto dcaZ = track.dcaZ(); - - if (pT < ConfPtCuts->get(partSpecies, "Pt min")) { + if (track.pt() < cfgPtCuts->get(partSpecies, "Pt min")) return false; - } - if (pT > ConfPtCuts->get(partSpecies, "Pt max")) { + if (track.pt() > cfgPtCuts->get(partSpecies, "Pt max")) return false; - } - if (std::abs(eta) > ConfTrkEta) { + if (std::abs(track.eta()) > cfgTrkEta) return false; - } - if (tpcNClsF < ConfTPCNClustersMin->get("TPCNClusMin", partSpecies)) { + if (track.tpcNClsFound() < cfgTPCNClustersMin->get("TPCNClusMin", partSpecies)) return false; - } - if (tpcRClsC < ConfTrkTPCfCls) { + if (track.tpcCrossedRowsOverFindableCls() < cfgTrkTPCfCls) return false; - } - if (tpcNClsC < ConfTrkTPCcRowsMin) { + if (track.tpcNClsCrossedRows() < cfgTrkTPCcRowsMin) return false; - } - if (tpcNClsSFrac > ConfTrkTPCsClsSharedFrac) { + if (track.tpcFractionSharedCls() > cfgTrkTPCsClsSharedFrac) return false; - } - if (itsNCls < ConfTrkITSnclsMin->get(static_cast(0), partSpecies)) { + if (track.itsNCls() < cfgTrkITSnclsMin->get(static_cast(0), partSpecies)) return false; - } - if (std::abs(dcaXY) > ConfTrkDCAxyMax) { + if (std::abs(track.dcaXY()) > cfgTrkDCAxyMax) return false; - } - if (std::abs(dcaZ) > ConfTrkDCAzMax) { + if (std::abs(track.dcaZ()) > cfgTrkDCAzMax) + return false; + if (track.tpcChi2NCl() > cfgTrkMaxChi2PerClusterTPC) + return false; + if (track.itsChi2NCl() > cfgTrkMaxChi2PerClusterITS) return false; - } return true; } template - bool isSelectedTrackPID(T const& track, CFTrigger::FemtoPartners partSpecies) + bool isSelectedTrackPID(T const& track, hnmtrigger::TracksPID partSpecies) { // nSigma should have entries [proton, deuteron, pion] bool isSelected = false; @@ -270,20 +217,18 @@ struct HeavyNeutralMesonFilter { float nSigmaTrackTOF = -999.f; float nSigmaTrackITS = -999.f; - float nSigmaTrackTPCTOF = -999.f; - switch (partSpecies) { - case CFTrigger::kProton: + case hnmtrigger::kProton: nSigmaTrackTPC = track.tpcNSigmaPr(); nSigmaTrackTOF = track.tofNSigmaPr(); nSigmaTrackITS = track.itsNSigmaPr(); break; - case CFTrigger::kDeuteron: + case hnmtrigger::kDeuteron: nSigmaTrackTPC = track.tpcNSigmaDe(); nSigmaTrackTOF = track.tofNSigmaDe(); nSigmaTrackITS = track.itsNSigmaDe(); break; - case CFTrigger::kPion: + case hnmtrigger::kPion: nSigmaTrackTPC = track.tpcNSigmaPi(); nSigmaTrackTOF = track.tofNSigmaPi(); nSigmaTrackITS = track.itsNSigmaPi(); @@ -292,24 +237,17 @@ struct HeavyNeutralMesonFilter { LOG(fatal) << "Particle species not known"; } - nSigmaTrackTPCTOF = std::sqrt(std::pow(nSigmaTrackTPC, 2) + std::pow(nSigmaTrackTOF, 2)); - - // check if track is selected - auto TPCmin = ConfPIDCuts->get(partSpecies, CFTrigger::kTPCMin); - auto TPCmax = ConfPIDCuts->get(partSpecies, CFTrigger::kTPCMax); - auto TPCTOFmax = ConfPIDCuts->get(partSpecies, CFTrigger::kTPCTOF); - auto ITSmin = ConfPIDCuts->get(partSpecies, CFTrigger::kITSmin); - auto ITSmax = ConfPIDCuts->get(partSpecies, CFTrigger::kITSmax); + float nSigmaTrackTPCTOF = std::sqrt(std::pow(nSigmaTrackTPC, 2) + std::pow(nSigmaTrackTOF, 2)); - if (track.p() <= ConfPtCuts->get(partSpecies, "P TOF thres")) { - if (nSigmaTrackTPC > TPCmin && - nSigmaTrackTPC < TPCmax && - nSigmaTrackITS > ITSmin && - nSigmaTrackITS < ITSmax) { + if (track.p() <= cfgPtCuts->get(partSpecies, "P TOF thres")) { + if (nSigmaTrackTPC > cfgPIDCuts->get(partSpecies, hnmtrigger::kTPCMin) && + nSigmaTrackTPC < cfgPIDCuts->get(partSpecies, hnmtrigger::kTPCMax) && + nSigmaTrackITS > cfgPIDCuts->get(partSpecies, hnmtrigger::kITSmin) && + nSigmaTrackITS < cfgPIDCuts->get(partSpecies, hnmtrigger::kITSmax)) { isSelected = true; } } else { - if (nSigmaTrackTPCTOF < TPCTOFmax) { + if (nSigmaTrackTPCTOF < cfgPIDCuts->get(partSpecies, hnmtrigger::kTPCTOF)) { isSelected = true; } } @@ -319,12 +257,10 @@ struct HeavyNeutralMesonFilter { template bool isSelectedEvent(T const& col) { - if (ConfEvtSelectZvtx && std::abs(col.posZ()) > ConfEvtZvtx) { + if (confEvtSelectZvtx && std::abs(col.posZ()) > confEvtZvtx) return false; - } - if (ConfEvtOfflineCheck && !col.sel8()) { + if (confEvtRequireSel8 && !col.sel8()) return false; - } return true; } @@ -333,18 +269,15 @@ struct HeavyNeutralMesonFilter { { const ROOT::Math::PtEtaPhiMVector trackSum = part1 + part2; const float beta = trackSum.Beta(); - const float betax = - beta * std::cos(trackSum.Phi()) * std::sin(trackSum.Theta()); - const float betay = - beta * std::sin(trackSum.Phi()) * std::sin(trackSum.Theta()); + const float betax = beta * std::cos(trackSum.Phi()) * std::sin(trackSum.Theta()); + const float betay = beta * std::sin(trackSum.Phi()) * std::sin(trackSum.Theta()); const float betaz = beta * std::cos(trackSum.Theta()); - ROOT::Math::PxPyPzMVector PartOneCMS(part1); - ROOT::Math::PxPyPzMVector PartTwoCMS(part2); - const ROOT::Math::Boost boostPRF = - ROOT::Math::Boost(-betax, -betay, -betaz); - PartOneCMS = boostPRF(PartOneCMS); - PartTwoCMS = boostPRF(PartTwoCMS); - const ROOT::Math::PxPyPzMVector trackRelK = PartOneCMS - PartTwoCMS; + ROOT::Math::PxPyPzMVector partOneCMS(part1); + ROOT::Math::PxPyPzMVector partTwoCMS(part2); + const ROOT::Math::Boost boostPRF = ROOT::Math::Boost(-betax, -betay, -betaz); + partOneCMS = boostPRF(partOneCMS); + partTwoCMS = boostPRF(partTwoCMS); + const ROOT::Math::PxPyPzMVector trackRelK = partOneCMS - partTwoCMS; return 0.5 * trackRelK.P(); } @@ -365,447 +298,171 @@ struct HeavyNeutralMesonFilter { ROOT::Math::PxPyPzEVector q12 = getqij(part1, part2); ROOT::Math::PxPyPzEVector q23 = getqij(part2, part3); ROOT::Math::PxPyPzEVector q31 = getqij(part3, part1); - float Q32 = q12.M2() + q23.M2() + q31.M2(); - return sqrt(-Q32); - } - - // Circumvent missing of different phi mappings, enforce [0, 2 * M_PI] - // Tracks have domain [0, 2 * M_PI] - // TLorentVectors have domain [-M_PI, M_PI] - double translatePhi(double phi) - { - if (phi < 0) { - phi += 2 * M_PI; // Add 2 pi to make it positive - } - return phi; + float q32 = q12.M2() + q23.M2() + q31.M2(); + return std::sqrt(-q32); } - Produces tags; - - HistogramRegistry mHistManager{"HeavyNeutralMesonFilterHistograms", {}, OutputObjHandlingPolicy::AnalysisObject}; - - Configurable cfgHNMMassCorrection{"cfgHNMMassCorrection", 1, "Use GG PDG mass to correct HNM mass (0 = off, 1 = subDeltaPi0, 2 = subLambda)"}; - static constexpr float defaultMassWindows[2][4] = {{0., 0.4, 0.6, 1.}, {0.4, 0.8, 0.8, 1.2}}; - Configurable> massWindowOmega{"massWindowOmega", {defaultMassWindows[0], 4, {"pi0_min", "pi0_max", "omega_min", "omega_max"}}, "Mass window for selected omegas and their decay pi0"}; - Configurable> massWindowEtaPrime{"massWindowEtaPrime", {defaultMassWindows[1], 4, {"eta_min", "eta_max", "etaprime_min", "etaprime_max"}}, "Mass window for selected eta' and their decay eta"}; - - static constexpr float defaultMinPts[4] = {1.8, 1.8, 2.6, 2.6}; - static constexpr float defaultFemtoMinPts[4] = {1.8, 1.8, 2.6, 2.6}; - - Configurable> minHNMPts{"minHNMPts", {defaultMinPts, 4, {"PCM_omega", "PCM_etaprime", "EMC_omega", "EMC_etaprime"}}, "Minimum pT values for the trigger decisions (GeV/c)"}; - - Configurable> minFemtoHNMPts{"minFemtoHNMPts", {defaultFemtoMinPts, 4, {"PCM_omega", "PCM_etaprime", "EMC_omega", "EMC_etaprime"}}, "Minimum pT values for the femto trigger decisions (GeV/c)"}; - - std::vector vGGs; - std::vector vHNMs; - - bool colContainsPCMOmega, colContainsEMCOmega, colContainsPCMEtaPrime, colContainsEMCEtaPrime = false; - - emcal::Geometry* emcalGeom; - - // Femto - // Prepare vectors for different species - std::vector etaPrimeEMC, etaPrimePCM, omegaEMC, omegaPCM, proton, antiproton, deuteron, antideuteron, pion, antipion; - float mMassProton = o2::constants::physics::MassProton; - float mMassDeuteron = o2::constants::physics::MassDeuteron; - float mMassOmega = 0.782; - float mMassEtaPrime = 0.957; - float mMassPionCharged = o2::constants::physics::MassPionCharged; - void init(InitContext const&) { - emcalGeom = emcal::Geometry::GetInstanceFromRunNumber(300000); - auto hCollisionCounter = mHistManager.add("Event/hCollisionCounter", "Number of collisions;;#bf{#it{N}_{Coll}}", HistType::kTH1F, {{6, -0.5, 5.5}}); - hCollisionCounter->GetXaxis()->SetBinLabel(1, "all"); - hCollisionCounter->GetXaxis()->SetBinLabel(2, "kTVXinEMC"); - hCollisionCounter->GetXaxis()->SetBinLabel(3, "PCM #omega"); - hCollisionCounter->GetXaxis()->SetBinLabel(4, "EMC #omega"); - hCollisionCounter->GetXaxis()->SetBinLabel(5, "PCM #eta'"); - hCollisionCounter->GetXaxis()->SetBinLabel(6, "EMC #eta'"); - - mHistManager.add("Event/nGGs", "Number of (selected) #gamma#gamma paris;#bf{#it{N}_{#gamma#gamma}};#bf{#it{N}_{#gamma#gamma}^{selected}}", HistType::kTH2F, {{51, -0.5, 50.5}, {51, -0.5, 50.5}}); - mHistManager.add("Event/nTracks", "Number of tracks;#bf{N_{tracks}};#bf{#it{N}_{Coll}}", HistType::kTH1F, {{51, -0.5, 50.5}}); - mHistManager.add("Event/nHeavyNeutralMesons", "Number of (selected) HNM candidates;#bf{#it{N}_{HNM}};#bf{#it{N}_{HNM}^{selected}}", HistType::kTH2F, {{51, -0.5, 50.5}, {51, -0.5, 50.5}}); - mHistManager.add("Event/nClustersVsV0s", "Number of clusters and V0s in the collision;#bf{#it{N}_{clusters}};#bf{#it{N}_{V0s}}", HistType::kTH2F, {{26, -0.5, 25.5}, {26, -0.5, 25.5}}); - - mHistManager.add("GG/invMassVsPt_PCM", "Invariant mass and pT of gg candidates;#bf{#it{M}_{#gamma#gamma}};#bf{#it{pT}_{#gamma#gamma}}", HistType::kTH2F, {{400, 0., 0.8}, {250, 0., 25.}}); - mHistManager.add("GG/invMassVsPt_PCMEMC", "Invariant mass and pT of gg candidates;#bf{#it{M}_{#gamma#gamma}};#bf{#it{pT}_{#gamma#gamma}}", HistType::kTH2F, {{400, 0., 0.8}, {250, 0., 25.}}); - mHistManager.add("GG/invMassVsPt_EMC", "Invariant mass and pT of gg candidates;#bf{#it{M}_{#gamma#gamma}};#bf{#it{pT}_{#gamma#gamma}}", HistType::kTH2F, {{400, 0., 0.8}, {250, 0., 25.}}); - - mHistManager.add("Omega/invMassVsPt_PCM", "Invariant mass and pT of omega meson candidates;#bf{#it{M}_{#pi^{+}#pi^{-}#gamma#gamma}};#bf{#it{pT}_{#pi^{+}#pi^{-}#gamma#gamma}}", HistType::kTH2F, {{400, 0.6, 1.}, {250, 0., 25.}}); - mHistManager.add("Omega/invMassVsPt_PCMEMC", "Invariant mass and pT of omega meson candidates;#bf{#it{M}_{#pi^{+}#pi^{-}#gamma#gamma}};#bf{#it{pT}_{#pi^{+}#pi^{-}#gamma#gamma}}", HistType::kTH2F, {{400, 0.6, 1.}, {250, 0., 25.}}); - mHistManager.add("Omega/invMassVsPt_EMC", "Invariant mass and pT of omega meson candidates;#bf{#it{M}_{#pi^{+}#pi^{-}#gamma#gamma}};#bf{#it{pT}_{#pi^{+}#pi^{-}#gamma#gamma}}", HistType::kTH2F, {{400, 0.6, 1.}, {250, 0., 25.}}); - - mHistManager.add("EtaPrime/invMassVsPt_PCM", "Invariant mass and pT of eta' candidates;#bf{#it{M}_{#pi^{+}#pi^{-}#gamma#gamma}};#bf{#it{pT}_{#pi^{+}#pi^{-}#gamma#gamma}}", HistType::kTH2F, {{400, 0.8, 1.2}, {250, 0., 25.}}); - mHistManager.add("EtaPrime/invMassVsPt_PCMEMC", "Invariant mass and pT of eta' candidates;#bf{#it{M}_{#pi^{+}#pi^{-}#gamma#gamma}};#bf{#it{pT}_{#pi^{+}#pi^{-}#gamma#gamma}}", HistType::kTH2F, {{400, 0.8, 1.2}, {250, 0., 25.}}); - mHistManager.add("EtaPrime/invMassVsPt_EMC", "Invariant mass and pT of eta' candidates;#bf{#it{M}_{#pi^{+}#pi^{-}#gamma#gamma}};#bf{#it{pT}_{#pi^{+}#pi^{-}#gamma#gamma}}", HistType::kTH2F, {{400, 0.8, 1.2}, {250, 0., 25.}}); - - // include all femto histograms - mHistManager.add("fProcessedEvents", "CF - event filtered;;Events", HistType::kTH1F, {{15, -0.5, 14.5}}); - std::vector eventTitles = {"all", "rejected", "PPOmega", "PPEtaPrime", "Omegad", "EtaPrimed", "OmegaP", "EtaPrimeP", "kTVXinEMC", "PCM #omega", "EMC #omega", "PCM #eta'", "EMC #eta'"}; - for (size_t iBin = 0; iBin < eventTitles.size(); iBin++) { - mHistManager.get(HIST("fProcessedEvents"))->GetXaxis()->SetBinLabel(iBin + 1, eventTitles[iBin].data()); - } - - // event cuts - mHistManager.add("EventCuts/fMultiplicityBefore", "Multiplicity of all processed events;Mult;Entries", HistType::kTH1F, {{500, 0, 500}}); - mHistManager.add("EventCuts/fMultiplicityAfter", "Multiplicity after event cuts;Mult;Entries", HistType::kTH1F, {{500, 0, 500}}); - mHistManager.add("EventCuts/fZvtxBefore", "Zvtx of all processed events;Z_{vtx};Entries", HistType::kTH1F, {{500, -15, 15}}); - mHistManager.add("EventCuts/fZvtxAfter", "Zvtx after event cuts;Z_{vtx};Entries", HistType::kTH1F, {{500, -15, 15}}); - - // mom correlations p vs pTPC - mHistManager.add("TrackCuts/TracksBefore/fMomCorrelationPos", "fMomCorrelation;p (GeV/c);p_{TPC} (GeV/c)", {HistType::kTH2F, {{500, 0.0f, 20.0f}, {500, 0.0f, 20.0f}}}); - mHistManager.add("TrackCuts/TracksBefore/fMomCorrelationNeg", "fMomCorrelation;p (GeV/c);p_{TPC} (GeV/c)", {HistType::kTH2F, {{500, 0.0f, 20.0f}, {500, 0.0f, 20.0f}}}); + mHistManager.add("Event/nGGs", "Number of (selected) #gamma#gamma paris;#bf{#it{N}^{#gamma#gamma}};#bf{#it{N}_{selected}^{#gamma#gamma}}", HistType::kTH2F, {{51, -0.5, 50.5}, {51, -0.5, 50.5}}); + mHistManager.add("Event/nHeavyNeutralMesons", "Number of (selected) HNM candidates;#bf{#it{N}^{HNM}};#bf{#it{N}_{selected}^{HNM}}", HistType::kTH2F, {{51, -0.5, 50.5}, {51, -0.5, 50.5}}); + mHistManager.add("Event/nClustersVsV0s", "Number of clusters and V0s in the collision;#bf{#it{N}^{clusters}};#bf{#it{N}^{V0s}}", HistType::kTH2F, {{26, -0.5, 25.5}, {26, -0.5, 25.5}}); + mHistManager.add("Event/nEMCalEvents", "Number of collisions with a certain combination of EMCal triggers;;#bf{#it{N}_{collisions}}", HistType::kTH1F, {{5, -0.5, 4.5}}); + std::vector nEventTitles = {"Cells & kTVXinEMC", "Cells & L0", "Cells & !kTVXinEMC & !L0", "!Cells & kTVXinEMC", "!Cells & L0"}; + for (size_t iBin = 0; iBin < nEventTitles.size(); iBin++) + mHistManager.get(HIST("Event/nEMCalEvents"))->GetXaxis()->SetBinLabel(iBin + 1, nEventTitles[iBin].data()); + mHistManager.add("Event/fMultiplicityBefore", "Multiplicity of all processed events;#bf{#it{N}_{tracks}};#bf{#it{N}_{collisions}}", HistType::kTH1F, {{500, 0, 500}}); + mHistManager.add("Event/fMultiplicityAfter", "Multiplicity after event cuts;#bf{#it{N}_{tracks}};#bf{#it{N}_{collisions}}", HistType::kTH1F, {{500, 0, 500}}); + mHistManager.add("Event/fZvtxBefore", "Zvtx of all processed events;#bf{z_{vtx} (cm)};#bf{#it{N}_{collisions}}", HistType::kTH1F, {{500, -15, 15}}); + mHistManager.add("Event/fZvtxAfter", "Zvtx after event cuts;#bf{z_{vtx} (cm)};#bf{#it{N}_{collisions}}", HistType::kTH1F, {{500, -15, 15}}); + mHistManager.add("fProcessedEvents", "CF - event filtered;;Events", HistType::kTH1F, {{12, -0.5, 11.5}}); + std::vector pEventTitles = {"all", "rejected", "PCM #omega", "EMC #omega", "PCM #eta'", "EMC #eta'", "PPOmega", "PPEtaPrime", "Omegad", "EtaPrimed", "OmegaP", "EtaPrimeP"}; + for (size_t iBin = 0; iBin < pEventTitles.size(); iBin++) + mHistManager.get(HIST("fProcessedEvents"))->GetXaxis()->SetBinLabel(iBin + 1, pEventTitles[iBin].data()); + + mHistManager.add("GG/invMassVsPt_PCM", "Invariant mass and pT of gg candidates;#bf{#it{M}^{#gamma#gamma} (GeV/#it{c}^{2})};#bf{#it{p}_{T}^{#gamma#gamma} (GeV/#it{c})}", HistType::kTH2F, {{400, 0., 0.8}, {250, 0., 25.}}); + mHistManager.add("GG/invMassVsPt_PCMEMC", "Invariant mass and pT of gg candidates;#bf{#it{M}^{#gamma#gamma} (GeV/#it{c}^{2})};#bf{#it{p}_{T}^{#gamma#gamma} (GeV/#it{c})}", HistType::kTH2F, {{400, 0., 0.8}, {250, 0., 25.}}); + mHistManager.add("GG/invMassVsPt_EMC", "Invariant mass and pT of gg candidates;#bf{#it{M}^{#gamma#gamma} (GeV/#it{c}^{2})};#bf{#it{p}_{T}^{#gamma#gamma} (GeV/#it{c})}", HistType::kTH2F, {{400, 0., 0.8}, {250, 0., 25.}}); + + // Momentum correlations p vs p_TPC + mHistManager.add("TrackCuts/TracksBefore/fMomCorrelationPos", "fMomCorrelation;#bf{#it{p} (GeV/#it{c})};#bf{#it{p}_{TPC} (GeV/#it{c})}", {HistType::kTH2F, {{500, 0.0f, 20.0f}, {500, 0.0f, 20.0f}}}); + mHistManager.add("TrackCuts/TracksBefore/fMomCorrelationNeg", "fMomCorrelation;#bf{#it{p} (GeV/#it{c})};#bf{#it{p}_{TPC} (GeV/#it{c})}", {HistType::kTH2F, {{500, 0.0f, 20.0f}, {500, 0.0f, 20.0f}}}); + + // All tracks + mHistManager.add("TrackCuts/TracksBefore/fPtTrackBefore", "Transverse momentum of all processed tracks;#bf{#it{p}_{T} (GeV/#it{c})};#bf{#it{N}_{tracks}}", HistType::kTH1F, {{500, 0, 10}}); + mHistManager.add("TrackCuts/TracksBefore/fEtaTrackBefore", "Pseudorapidity of all processed tracks;#eta;#bf{#it{N}_{tracks}}", HistType::kTH1F, {{500, -2, 2}}); + mHistManager.add("TrackCuts/TracksBefore/fPhiTrackBefore", "Azimuthal angle of all processed tracks;#phi;#bf{#it{N}_{tracks}}", HistType::kTH1F, {{720, 0, constants::math::TwoPI}}); - mHistManager.add("TrackCuts/TracksBefore/fMomCorrelationAfterCutsProton", "fMomCorrelation;p (GeV/c);p_{TPC} (GeV/c)", {HistType::kTH2F, {{500, 0.0f, 20.0f}, {500, 0.0f, 20.0f}}}); - mHistManager.add("TrackCuts/TracksBefore/fMomCorrelationAfterCutsAntiProton", "fMomCorrelation;p (GeV/c);p_{TPC} (GeV/c)", {HistType::kTH2F, {{500, 0.0f, 20.0f}, {500, 0.0f, 20.0f}}}); - mHistManager.add("TrackCuts/TracksBefore/fMomCorrelationAfterCutsDeuteron", "fMomCorrelation;p (GeV/c);p_{TPC} (GeV/c)", {HistType::kTH2F, {{500, 0.0f, 20.0f}, {500, 0.0f, 20.0f}}}); - mHistManager.add("TrackCuts/TracksBefore/fMomCorrelationAfterCutsAntiDeuteron", "fMomCorrelation;p (GeV/c);p_{TPC} (GeV/c)", {HistType::kTH2F, {{500, 0.0f, 20.0f}, {500, 0.0f, 20.0f}}}); + // TPC signal + mHistManager.add("TrackCuts/TPCSignal/fTPCSignalTPCP", "TPCSignal;#bf{#it{p}_{TPC} (GeV/#it{c})};#bf{TPC d#it{E}/d#it{x}}", {HistType::kTH2F, {{500, 0.0f, 6.0f}, {2000, -100.f, 500.f}}}); + mHistManager.add("TrackCuts/TPCSignal/fTPCSignal", "TPCSignalP;#bf{#it{p} (GeV/#it{c})};#bf{TPC d#it{E}/d#it{x}}", {HistType::kTH2F, {{500, 0.0f, 6.0f}, {2000, -100.f, 500.f}}}); + // TPC signal antiparticles (negative charge) + mHistManager.add("TrackCuts/TPCSignal/fTPCSignalAntiTPCP", "TPCSignal;#bf{#it{p}_{TPC} (GeV/#it{c})};#bf{TPC d#it{E}/d#it{x}}", {HistType::kTH2F, {{500, 0.0f, 6.0f}, {2000, -100.f, 500.f}}}); + mHistManager.add("TrackCuts/TPCSignal/fTPCSignalAnti", "TPCSignalP;#bf{#it{p} (GeV/#it{c})};#bf{TPC d#it{E}/d#it{x}}", {HistType::kTH2F, {{500, 0.0f, 6.0f}, {2000, -100.f, 500.f}}}); + + const int nTrackSpecies = 2 * hnmtrigger::kNFemtoPartners; // x2 because of anti particles + const char* particleSpecies[nTrackSpecies] = {"Proton", "AntiProton", "Deuteron", "AntiDeuteron", "Pion", "AntiPion"}; + const char* particleSpeciesLatex[nTrackSpecies] = {"p", "#bar{p}", "d", "#bar{d}", "#pi^{+}", "#pi^{-}"}; + + for (int iParticle = 0; iParticle < nTrackSpecies; iParticle++) { + mHistManager.add(Form("TrackCuts/TracksBefore/fMomCorrelationAfterCuts%s", particleSpecies[iParticle]), Form("%s momentum correlation;#bf{#it{p} (GeV/#it{c})};#bf{#it{p}_{TPC} (GeV/#it{c})}", particleSpecies[iParticle]), {HistType::kTH2F, {{500, 0.0f, 20.0f}, {500, 0.0f, 20.0f}}}); + mHistManager.add(Form("TrackCuts/TPCSignal/fTPCSignal%s", particleSpecies[iParticle]), Form("%s TPC energy loss;#bf{#it{p}_{TPC}^{%s} (GeV/#it{c})};#bf{TPC d#it{E}/d#it{x}}", particleSpecies[iParticle], particleSpeciesLatex[iParticle]), {HistType::kTH2F, {{500, 0.0f, 6.0f}, {10000, -100.f, 500.f}}}); + + mHistManager.add(Form("TrackCuts/%s/fP", particleSpecies[iParticle]), Form("%s momentum at PV;#bf{#it{p}^{%s} (GeV/#it{c})};#bf{#it{N}^{%s}}", particleSpecies[iParticle], particleSpeciesLatex[iParticle], particleSpeciesLatex[iParticle]), HistType::kTH1F, {{500, 0, 10}}); + mHistManager.add(Form("TrackCuts/%s/fPt", particleSpecies[iParticle]), Form("%s transverse momentum;#bf{#it{p}_{T}^{%s} (GeV/#it{c})};#bf{#it{N}^{%s}}", particleSpecies[iParticle], particleSpeciesLatex[iParticle], particleSpeciesLatex[iParticle]), HistType::kTH1F, {{500, 0, 10}}); + mHistManager.add(Form("TrackCuts/%s/fMomCorDif", particleSpecies[iParticle]), Form("Momentum correlation;#bf{#it{p}^{%s} (GeV/#it{c})};#bf{#it{p}_{TPC}^{%s} - #it{p}^{%s} (GeV/#it{c})}", particleSpeciesLatex[iParticle], particleSpeciesLatex[iParticle], particleSpeciesLatex[iParticle]), {HistType::kTH2F, {{500, 0, 10}, {600, -3, 3}}}); + mHistManager.add(Form("TrackCuts/%s/fMomCorRatio", particleSpecies[iParticle]), Form("Relative momentum correlation;#bf{#it{p}^{%s} (GeV/#it{c})};#bf{#it{p}_{TPC}^{%s} - #it{p}^{%s} / #it{p}^{%s}}", particleSpeciesLatex[iParticle], particleSpeciesLatex[iParticle], particleSpeciesLatex[iParticle], particleSpeciesLatex[iParticle]), {HistType::kTH2F, {{500, 0, 10}, {200, -1, 1}}}); + mHistManager.add(Form("TrackCuts/%s/fEta", particleSpecies[iParticle]), Form("%s pseudorapidity distribution;#eta;#bf{#it{N}^{%s}}", particleSpecies[iParticle], particleSpeciesLatex[iParticle]), HistType::kTH1F, {{500, -2, 2}}); + mHistManager.add(Form("TrackCuts/%s/fPhi", particleSpecies[iParticle]), Form("%s azimuthal angle distribution;#phi;#bf{#it{N}^{%s}}", particleSpecies[iParticle], particleSpeciesLatex[iParticle]), HistType::kTH1F, {{720, 0, constants::math::TwoPI}}); + + mHistManager.add(Form("TrackCuts/%s/fNsigmaTPCvsTPCP", particleSpecies[iParticle]), Form("NSigmaTPC %s;#bf{#it{p}_{TPC}^{%s} (GeV/#it{c})};#bf{n#sigma_{TPC}^{%s}}", particleSpecies[iParticle], particleSpeciesLatex[iParticle], particleSpeciesLatex[iParticle]), {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); + mHistManager.add(Form("TrackCuts/%s/fNsigmaTOFvsTPCP", particleSpecies[iParticle]), Form("NSigmaTOF %s;#bf{#it{p}_{TPC}^{%s} (GeV/#it{c})};#bf{n#sigma_{TOF}^{%s}}", particleSpecies[iParticle], particleSpeciesLatex[iParticle], particleSpeciesLatex[iParticle]), {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); + mHistManager.add(Form("TrackCuts/%s/fNsigmaTPCTOFvsTPCP", particleSpecies[iParticle]), Form("NSigmaTPCTOF %s;#bf{#it{p}_{TPC}^{%s} (GeV/#it{c})};n#sigma_{comb}^{%s}}", particleSpecies[iParticle], particleSpeciesLatex[iParticle], particleSpeciesLatex[iParticle]), {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, 0.f, 10.f}}}); + mHistManager.add(Form("TrackCuts/%s/fNsigmaITSvsP", particleSpecies[iParticle]), Form("NSigmaITS %s;#bf{#it{p}^{%s} (GeV/#it{c})};#bf{n#sigma_{ITS}^{%s}}", particleSpecies[iParticle], particleSpeciesLatex[iParticle], particleSpeciesLatex[iParticle]), {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); + mHistManager.add(Form("TrackCuts/%s/fNsigmaTPCvsP", particleSpecies[iParticle]), Form("NSigmaTPC %s P;#bf{#it{p}^{%s} (GeV/#it{c})};#bf{n#sigma_{TPC}^{%s}}", particleSpecies[iParticle], particleSpeciesLatex[iParticle], particleSpeciesLatex[iParticle]), {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); + mHistManager.add(Form("TrackCuts/%s/fNsigmaTOFvsP", particleSpecies[iParticle]), Form("NSigmaTOF %s P;#bf{#it{p}^{%s} (GeV/#it{c})};#bf{n#sigma_{TOF}^{%s}}", particleSpecies[iParticle], particleSpeciesLatex[iParticle], particleSpeciesLatex[iParticle]), {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); + mHistManager.add(Form("TrackCuts/%s/fNsigmaTPCTOFvsP", particleSpecies[iParticle]), Form("NSigmaTPCTOF %s P;#bf{#it{p}^{%s} (GeV/#it{c})};#bf{n#sigma_{comb}^{%s}}", particleSpecies[iParticle], particleSpeciesLatex[iParticle], particleSpeciesLatex[iParticle]), {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, 0.f, 10.f}}}); + + mHistManager.add(Form("TrackCuts/%s/fDCAxy", particleSpecies[iParticle]), Form("fDCAxy %s;#bf{DCA_{xy}};#bf{#it{N}^{%s}}", particleSpecies[iParticle], particleSpeciesLatex[iParticle]), HistType::kTH1F, {{500, -0.5f, 0.5f}}); + mHistManager.add(Form("TrackCuts/%s/fDCAz", particleSpecies[iParticle]), Form("fDCAz %s;#bf{DCA_{z}};#bf{#it{N}^{%s}}", particleSpecies[iParticle], particleSpeciesLatex[iParticle]), HistType::kTH1F, {{500, -0.5f, 0.5f}}); + mHistManager.add(Form("TrackCuts/%s/fTPCsCls", particleSpecies[iParticle]), Form("fTPCsCls %s;#bf{TPC Shared Clusters};#bf{#it{N}^{%s}}", particleSpecies[iParticle], particleSpeciesLatex[iParticle]), HistType::kTH1F, {{163, -1.0f, 162.0f}}); + mHistManager.add(Form("TrackCuts/%s/fTPCcRows", particleSpecies[iParticle]), Form("fTPCcRows %s;#bf{TPC Crossed Rows};#bf{#it{N}^{%s}}", particleSpecies[iParticle], particleSpeciesLatex[iParticle]), HistType::kTH1F, {{163, -1.0f, 162.0f}}); + mHistManager.add(Form("TrackCuts/%s/fTrkTPCfCls", particleSpecies[iParticle]), Form("fTrkTPCfCls %s;#bf{TPC Findable/CrossedRows};#bf{#it{N}^{%s}}", particleSpecies[iParticle], particleSpeciesLatex[iParticle]), HistType::kTH1F, {{500, 0.0f, 3.0f}}); + mHistManager.add(Form("TrackCuts/%s/fTPCncls", particleSpecies[iParticle]), Form("fTPCncls %s;#bf{TPC Clusters};#bf{#it{N}^{%s}}", particleSpecies[iParticle], particleSpeciesLatex[iParticle]), HistType::kTH1F, {{163, -1.0f, 162.0f}}); + } - mHistManager.add("TrackCuts/TracksBefore/fMomCorrelationAfterCutsPion", "fMomCorrelation;p (GeV/c);p_{TPC} (GeV/c)", {HistType::kTH2F, {{1000, 0.0f, 20.0f}, {1000, 0.0f, 20.0f}}}); - mHistManager.add("TrackCuts/TracksBefore/fMomCorrelationAfterCutsAntiPion", "fMomCorrelation;p (GeV/c);p_{TPC} (GeV/c)", {HistType::kTH2F, {{1000, 0.0f, 20.0f}, {1000, 0.0f, 20.0f}}}); + // --> HNM QA + // pi+ daughter + mHistManager.add("HNM/Before/PosDaughter/fInvMass", "Invariant mass HMN Pos Daugh;#bf{#it{M}^{#pi^{+}} (GeV/#it{c}^{2})};#bf{#it{N}^{#pi^{+}}}", HistType::kTH1F, {{200, 0, 0.2}}); + mHistManager.add("HNM/Before/PosDaughter/fPt", "Transverse momentum HMN Pos Daugh tracks;#bf{#it{p}_{T} (GeV/#it{c})};#bf{#it{N}^{#pi^{+}}}", HistType::kTH1F, {{500, 0, 10}}); + mHistManager.add("HNM/Before/PosDaughter/fEta", "HMN Pos Daugh Eta;#eta;#bf{#it{N}^{#pi^{+}}}", HistType::kTH1F, {{500, -2, 2}}); + mHistManager.add("HNM/Before/PosDaughter/fPhi", "Azimuthal angle of HMN Pos Daugh tracks;#phi;#bf{#it{N}^{#pi^{+}}}", HistType::kTH1F, {{720, 0, constants::math::TwoPI}}); + // pi- daughter + mHistManager.add("HNM/Before/NegDaughter/fInvMass", "Invariant mass HMN Neg Daugh;#bf{#it{M}^{#pi^{-}} (GeV/#it{c}^{2})};#bf{#it{N}^{#pi^{-}}}", HistType::kTH1F, {{200, 0, 0.2}}); + mHistManager.add("HNM/Before/NegDaughter/fPt", "Transverse momentum HMN Neg Daugh tracks;#bf{#it{p}_{T} (GeV/#it{c})};#bf{#it{N}^{#pi^{-}}}", HistType::kTH1F, {{500, 0, 10}}); + mHistManager.add("HNM/Before/NegDaughter/fEta", "HMN Neg Daugh Eta;#eta;#bf{#it{N}^{#pi^{-}}}", HistType::kTH1F, {{500, -2, 2}}); + mHistManager.add("HNM/Before/NegDaughter/fPhi", "Azimuthal angle of HMN Neg Daugh tracks;#phi;#bf{#it{N}^{#pi^{-}}}", HistType::kTH1F, {{720, 0, constants::math::TwoPI}}); + // Properties of the pi+pi- pair + mHistManager.add("HNM/Before/PiPlPiMi/fInvMassVsPt", "Invariant mass and pT of #pi^+pi^- pairs;#bf{#it{M}^{#pi^{+}#pi^{-}} (GeV/#it{c}^{2})};#bf{#it{p}_{T}^{#pi^{+}#pi^{-}} (GeV/#it{c})}", HistType::kTH2F, {{400, 0.2, 1.}, {250, 0., 25.}}); + mHistManager.add("HNM/Before/PiPlPiMi/fEta", "Pseudorapidity of HMNCand;#eta;#bf{#it{N}^{#pi^{+}#pi^{-}}}", HistType::kTH1F, {{500, -2, 2}}); + mHistManager.add("HNM/Before/PiPlPiMi/fPhi", "Azimuthal angle of HMNCand;#phi;#bf{#it{N}^{#pi^{+}#pi^{-}}}", HistType::kTH1F, {{720, 0, constants::math::TwoPI}}); + + for (const auto& BeforeAfterString : {"Before", "After"}) { + for (const auto& iHNM : {"Omega", "EtaPrime"}) { + for (const auto& MethodString : {"PCM", "EMC"}) { + mHistManager.add(Form("HNM/%s/%s/%s/fInvMassVsPt", BeforeAfterString, iHNM, MethodString), "Invariant mass and pT of heavy neutral meson candidates;#bf{#it{M}^{#pi^{+}#pi^{-}#gamma#gamma} (GeV/#it{c}^{2})};#bf{#it{p}_{T}^{#pi^{+}#pi^{-}#gamma#gamma} (GeV/#it{c})}", HistType::kTH2F, {{600, 0.6, 1.2}, {250, 0., 25.}}); + mHistManager.add(Form("HNM/%s/%s/%s/fEta", BeforeAfterString, iHNM, MethodString), "Pseudorapidity of HNM candidate;#eta;#bf{#it{N}^{#pi^{+}#pi^{-}#gamma#gamma}}", HistType::kTH1F, {{500, -2, 2}}); + mHistManager.add(Form("HNM/%s/%s/%s/fPhi", BeforeAfterString, iHNM, MethodString), "Azimuthal angle of HNM candidate;#phi;#bf{#it{N}^{#pi^{+}#pi^{-}#gamma#gamma}}", HistType::kTH1F, {{720, 0, constants::math::TwoPI}}); + } + } + } + mHistManager.add("HNM/Before/Omega/PCMEMC/fInvMassVsPt", "Invariant mass and pT of omega meson candidates;#bf{#it{M}^{#pi^{+}#pi^{-}#gamma#gamma} (GeV/#it{c}^{2})};#bf{#it{p}_{T}^{#pi^{+}#pi^{-}#gamma#gamma} (GeV/#it{c})}", HistType::kTH2F, {{600, 0.6, 1.2}, {250, 0., 25.}}); + mHistManager.add("HNM/Before/Omega/PCMEMC/fEta", "Pseudorapidity of HMNCand;#eta;#bf{#it{N}^{#pi^{+}#pi^{-}#gamma#gamma}}", HistType::kTH1F, {{500, -2, 2}}); + mHistManager.add("HNM/Before/Omega/PCMEMC/fPhi", "Azimuthal angle of HMNCand;#phi;#bf{#it{N}^{#pi^{+}#pi^{-}#gamma#gamma}}", HistType::kTH1F, {{720, 0, constants::math::TwoPI}}); + mHistManager.add("HNM/Before/EtaPrime/PCMEMC/fInvMassVsPt", "Invariant mass and pT of eta' meson candidates;#bf{#it{M}^{#pi^{+}#pi^{-}#gamma#gamma} (GeV/#it{c}^{2})};#bf{#it{p}_{T}^{#pi^{+}#pi^{-}#gamma#gamma} (GeV/#it{c})}", HistType::kTH2F, {{600, 0.8, 1.2}, {250, 0., 25.}}); + mHistManager.add("HNM/Before/EtaPrime/PCMEMC/fEta", "Pseudorapidity of HMNCand;#eta;#bf{#it{N}^{#pi^{+}#pi^{-}#gamma#gamma}}", HistType::kTH1F, {{500, -2, 2}}); + mHistManager.add("HNM/Before/EtaPrime/PCMEMC/fPhi", "Azimuthal angle of HMNCand;#phi;#bf{#it{N}^{#pi^{+}#pi^{-}#gamma#gamma}}", HistType::kTH1F, {{720, 0, constants::math::TwoPI}}); + + // --> Two body femto histograms + for (const auto& iFemtoPartner : {"p", "d"}) { + for (const auto& iHNM : {"omega", "etaprime"}) { + mHistManager.add(Form("%s%s/fMultiplicity", iHNM, iFemtoPartner), "Multiplicity of all processed events;#bf{#it{N}_{tracks}};#bf{#it{N}_{collisions}}", HistType::kTH1F, {{500, 0, 500}}); + mHistManager.add(Form("%s%s/fZvtx", iHNM, iFemtoPartner), "Zvtx of all processed events;#bf{z_{vtx} (cm)};#bf{#it{N}_{collisions}}", HistType::kTH1F, {{500, -15, 15}}); + for (const auto& iEMCPCM : {"PCM", "EMC"}) { + mHistManager.add(Form("%s%s/fSE_particle_%s", iHNM, iFemtoPartner, iEMCPCM), Form("Same Event distribution;#bf{#it{K}^{*} (GeV/#it{c})};#bf{#it{N}^{%s}}", iFemtoPartner), HistType::kTH1F, {{8000, 0, 8}}); + mHistManager.add(Form("%s%s/fSE_Antiparticle_%s", iHNM, iFemtoPartner, iEMCPCM), Form("Same Event distribution;#bf{#it{K}^{*} (GeV/#it{c})};#bf{#it{N}^{#bar{%s}}}", iFemtoPartner), HistType::kTH1F, {{8000, 0, 8}}); + mHistManager.add(Form("%s%s/f%sPtVskstar_%s", iHNM, iFemtoPartner, iHNM, iEMCPCM), Form("K* vs %s pt;#bf{#it{K}^{*} (GeV/#it{c})};#bf{#it{p}_{T}^{%s} (GeV/#it{c})}", iHNM, iHNM), HistType::kTH2F, {{{150, 0, 1.5}, {500, 0, 10}}}); + mHistManager.add(Form("%s%s/f%sPtVskstar_%s", iHNM, iFemtoPartner, iFemtoPartner, iEMCPCM), Form("K* vs %s pt;#bf{#it{K}^{*} (GeV/#it{c})};#bf{#it{p}_{T}^{%s} (GeV/#it{c})}", iFemtoPartner, iFemtoPartner), HistType::kTH2F, {{{150, 0, 1.5}, {500, 0, 10}}}); + mHistManager.add(Form("%s%s/fAnti%sPtVskstar_%s", iHNM, iFemtoPartner, iFemtoPartner, iEMCPCM), Form("K* vs #bar{%s} pt;#bf{#it{K}^{*} (GeV/#it{c})};#bf{#it{p}_{T}^{#bar{%s}} (GeV/#it{c})}", iFemtoPartner, iFemtoPartner), HistType::kTH2F, {{{150, 0, 1.5}, {500, 0, 10}}}); + mHistManager.add(Form("%s%s/fInvMassVsKStar_%s", iHNM, iFemtoPartner, iEMCPCM), "Invariant mass and K* of heavy neutral meson candidates;#bf{#it{M}^{#pi^{+}#pi^{-}#gamma#gamma} (GeV/#it{c}^{2})};#bf{#it{K}^{*} (GeV/#it{c})}", HistType::kTH2F, {{600, 0.6, 1.2}, {250, 0., 1.}}); + } + } + } - // all tracks - mHistManager.add("TrackCuts/TracksBefore/fPtTrackBefore", "Transverse momentum of all processed tracks;p_{T} (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - mHistManager.add("TrackCuts/TracksBefore/fEtaTrackBefore", "Pseudorapidity of all processed tracks;#eta;Entries", HistType::kTH1F, {{500, -2, 2}}); - mHistManager.add("TrackCuts/TracksBefore/fPhiTrackBefore", "Azimuthal angle of all processed tracks;#phi;Entries", HistType::kTH1F, {{720, 0, TMath::TwoPi()}}); + // --> Three body femto histograms + for (const auto& iHNM : {"omega", "etaprime"}) { + mHistManager.add(Form("pp%s/fMultiplicity", iHNM), "Multiplicity of all processed events;#bf{#it{N}_{tracks}};#bf{#it{N}_{collisions}}", HistType::kTH1F, {{500, 0, 500}}); + mHistManager.add(Form("pp%s/fZvtx", iHNM), "Zvtx of all processed events;#bf{z_{vtx} (cm)};#bf{#it{N}_{collisions}}", HistType::kTH1F, {{500, -15, 15}}); + for (const auto& iEMCPCM : {"PCM", "EMC"}) { + mHistManager.add(Form("pp%s/fSE_particle_%s", iHNM, iEMCPCM), "Same Event distribution;#bf{#it{Q}_{3} (GeV/#it{c})};#bf{#it{N}^{pp}}", HistType::kTH1F, {{8000, 0, 8}}); + mHistManager.add(Form("pp%s/fSE_Antiparticle_%s", iHNM, iEMCPCM), "Same Event distribution;#bf{#it{Q}_{3} (GeV/#it{c})};#bf{#it{N}^{#bar{p}#bar{p}}}", HistType::kTH1F, {{8000, 0, 8}}); + mHistManager.add(Form("pp%s/fProtonPtVsQ3_%s", iHNM, iEMCPCM), "pT (proton) vs Q_{3};#bf{#it{Q}_{3} (GeV/#it{c})};#bf{#it{p}_{T}^{p} (GeV/#it{c})}", HistType::kTH2F, {{{150, 0, 1.5}, {500, 0, 10}}}); + mHistManager.add(Form("pp%s/f%sCandPtVsQ3_%s", iHNM, iHNM, iEMCPCM), Form("pT (%s) vs Q_{3};#bf{#it{Q}_{3} (GeV/#it{c})};#bf{#it{p}_{T}^{%s} (GeV/#it{c})}", iHNM, iHNM), HistType::kTH2F, {{{150, 0, 1.5}, {500, 0, 10}}}); + mHistManager.add(Form("pp%s/fAntiProtonPtVsQ3_%s", iHNM, iEMCPCM), "pT (antiproton) vs Q_{3};#bf{#it{Q}_{3} (GeV/#it{c})};#bf{#it{p}_{T}^{#bar{p}} (GeV/#it{c})}", HistType::kTH2F, {{{150, 0, 1.5}, {500, 0, 10}}}); + mHistManager.add(Form("pp%s/fInvMassVsQ3_%s", iHNM, iEMCPCM), "Invariant mass and Q3 of heavy neutral meson candidates;#bf{#it{M}^{#pi^{+}#pi^{-}#gamma#gamma} (GeV/#it{c}^{2})};#bf{#it{Q}_{3} (GeV/#it{c})}", HistType::kTH2F, {{600, 0.6, 1.2}, {250, 0., 1.}}); + } + } - // TPC signal - mHistManager.add("TrackCuts/TPCSignal/fTPCSignal", "TPCSignal;p_{TPC} (GeV/c);dE/dx", {HistType::kTH2F, {{500, 0.0f, 6.0f}, {2000, -100.f, 500.f}}}); - mHistManager.add("TrackCuts/TPCSignal/fTPCSignalP", "TPCSignalP;p (GeV/c);dE/dx", {HistType::kTH2F, {{500, 0.0f, 6.0f}, {2000, -100.f, 500.f}}}); - // TPC signal anti - mHistManager.add("TrackCuts/TPCSignal/fTPCSignalAnti", "TPCSignal;p_{TPC} (GeV/c);dE/dx", {HistType::kTH2F, {{500, 0.0f, 6.0f}, {2000, -100.f, 500.f}}}); - mHistManager.add("TrackCuts/TPCSignal/fTPCSignalAntiP", "TPCSignalP;p (GeV/c);dE/dx", {HistType::kTH2F, {{500, 0.0f, 6.0f}, {2000, -100.f, 500.f}}}); - - // TPC signal particles - mHistManager.add("TrackCuts/TPCSignal/fTPCSignalProton", "fTPCSignalProton;p_{TPC} (GeV/c);dE/dx", {HistType::kTH2F, {{500, 0.0f, 6.0f}, {10000, -100.f, 500.f}}}); - mHistManager.add("TrackCuts/TPCSignal/fTPCSignalAntiProton", "fTPCSignalAntiProton;p_{TPC} (GeV/c);dE/dx", {HistType::kTH2F, {{500, 0.0f, 6.0f}, {10000, -100.f, 500.f}}}); - mHistManager.add("TrackCuts/TPCSignal/fTPCSignalDeuteron", "fTPCSignalDeuteron;p_{TPC} (GeV/c);dE/dx", {HistType::kTH2F, {{500, 0.0f, 6.0f}, {10000, -100.f, 500.f}}}); - mHistManager.add("TrackCuts/TPCSignal/fTPCSignalAntiDeuteron", "fTPCSignalAntiDeuteron;p_{TPC} (GeV/c);dE/dx", {HistType::kTH2F, {{500, 0.0f, 6.0f}, {10000, -100.f, 500.f}}}); - mHistManager.add("TrackCuts/TPCSignal/fTPCSignalPion", "fTPCSignalPion;p_{TPC} (GeV/c);dE/dx", {HistType::kTH2F, {{500, 0.0f, 6.0f}, {10000, -100.f, 500.f}}}); - mHistManager.add("TrackCuts/TPCSignal/fTPCSignalAntiPion", "fTPCSignalAntiPion;p_{TPC} (GeV/c);dE/dx", {HistType::kTH2F, {{500, 0.0f, 6.0f}, {10000, -100.f, 500.f}}}); - - // proton - mHistManager.add("TrackCuts/Proton/fPProton", "Momentum of protons at PV;p (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - mHistManager.add("TrackCuts/Proton/fPTPCProton", "Momentum of protons at TPC inner wall;p_{TPC} (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - mHistManager.add("TrackCuts/Proton/fPtProton", "Transverse momentum of all processed tracks;p_{T} (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - mHistManager.add("TrackCuts/Proton/fMomCorProtonDif", "Momentum correlation;p_{reco} (GeV/c); (p_{TPC} - p_{reco}) (GeV/c)", {HistType::kTH2F, {{500, 0, 10}, {600, -3, 3}}}); - mHistManager.add("TrackCuts/Proton/fMomCorProtonRatio", "Momentum correlation;p_{reco} (GeV/c); p_{TPC} - p_{reco} / p_{reco}", {HistType::kTH2F, {{500, 0, 10}, {200, -1, 1}}}); - mHistManager.add("TrackCuts/Proton/fEtaProton", "Pseudorapidity of all processed tracks;#eta;Entries", HistType::kTH1F, {{500, -2, 2}}); - mHistManager.add("TrackCuts/Proton/fPhiProton", "Azimuthal angle of all processed tracks;#phi;Entries", HistType::kTH1F, {{720, 0, TMath::TwoPi()}}); - mHistManager.add("TrackCuts/Proton/fNsigmaTPCvsPProton", "NSigmaTPC Proton;p_{TPC} (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - mHistManager.add("TrackCuts/Proton/fNsigmaTOFvsPProton", "NSigmaTOF Proton;p_{TPC} (GeV/c);n#sigma_{TOF}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - mHistManager.add("TrackCuts/Proton/fNsigmaTPCTOFvsPProton", "NSigmaTPCTOF Proton;p_{TPC} (GeV/c);n#sigma_{comb}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, 0.f, 10.f}}}); - mHistManager.add("TrackCuts/Proton/fNsigmaITSvsPProton", "NSigmaITS Proton;p (GeV/c);n#sigma_{ITS}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - - mHistManager.add("TrackCuts/Proton/fNsigmaTPCvsPProtonP", "NSigmaTPC Proton P;p (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - mHistManager.add("TrackCuts/Proton/fNsigmaTOFvsPProtonP", "NSigmaTOF Proton P;p (GeV/c);n#sigma_{TOF}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - mHistManager.add("TrackCuts/Proton/fNsigmaTPCTOFvsPProtonP", "NSigmaTPCTOF Proton P;p (GeV/c);n#sigma_{comb}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, 0.f, 10.f}}}); - - mHistManager.add("TrackCuts/Proton/fDCAxyProton", "fDCAxy Proton;DCA_{XY};Entries", HistType::kTH1F, {{500, -0.5f, 0.5f}}); - mHistManager.add("TrackCuts/Proton/fDCAzProton", "fDCAz Proton;DCA_{Z};Entries", HistType::kTH1F, {{500, -0.5f, 0.5f}}); - mHistManager.add("TrackCuts/Proton/fTPCsClsProton", "fTPCsCls Proton;TPC Shared Clusters;Entries", HistType::kTH1F, {{163, -1.0f, 162.0f}}); - mHistManager.add("TrackCuts/Proton/fTPCcRowsProton", "fTPCcRows Proton;TPC Crossed Rows;Entries", HistType::kTH1F, {{163, -1.0f, 162.0f}}); - mHistManager.add("TrackCuts/Proton/fTrkTPCfClsProton", "fTrkTPCfCls Proton;TPC Findable/CrossedRows;Entries", HistType::kTH1F, {{500, 0.0f, 3.0f}}); - mHistManager.add("TrackCuts/Proton/fTPCnclsProton", "fTPCncls Proton;TPC Clusters;Entries", HistType::kTH1F, {{163, -1.0f, 162.0f}}); - - // antiproton - mHistManager.add("TrackCuts/AntiProton/fPtAntiProton", "Transverse momentum of all processed tracks;p_{T} (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - mHistManager.add("TrackCuts/AntiProton/fMomCorAntiProtonDif", "Momentum correlation;p_{reco} (GeV/c); (p_{TPC} - p_{reco}) (GeV/c)", {HistType::kTH2F, {{500, 0, 10}, {600, -3, 3}}}); - mHistManager.add("TrackCuts/AntiProton/fMomCorAntiProtonRatio", "Momentum correlation;p_{reco} (GeV/c); |p_{TPC} - p_{reco}| (GeV/c)", {HistType::kTH2F, {{500, 0, 10}, {200, -1, 1}}}); - mHistManager.add("TrackCuts/AntiProton/fEtaAntiProton", "Pseudorapidity of all processed tracks;#eta;Entries", HistType::kTH1F, {{500, -2, 2}}); - mHistManager.add("TrackCuts/AntiProton/fPhiAntiProton", "Azimuthal angle of all processed tracks;#phi;Entries", HistType::kTH1F, {{720, 0, TMath::TwoPi()}}); - mHistManager.add("TrackCuts/AntiProton/fNsigmaTPCvsPAntiProton", "NSigmaTPC AntiProton;p_{TPC} (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - mHistManager.add("TrackCuts/AntiProton/fNsigmaTOFvsPAntiProton", "NSigmaTOF AntiProton;p_{TPC} (GeV/c);n#sigma_{TOF}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - mHistManager.add("TrackCuts/AntiProton/fNsigmaTPCTOFvsPAntiProton", "NSigmaTPCTOF AntiProton;p_{TPC} (GeV/c);n#sigma_{comb}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, 0.f, 10.f}}}); - mHistManager.add("TrackCuts/AntiProton/fNsigmaITSvsPAntiProton", "NSigmaITS AntiProton;p (GeV/c);n#sigma_{ITS}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - - mHistManager.add("TrackCuts/AntiProton/fNsigmaTPCvsPAntiProtonP", "NSigmaTPC AntiProton P;p (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - mHistManager.add("TrackCuts/AntiProton/fNsigmaTOFvsPAntiProtonP", "NSigmaTOF AntiProton P;p (GeV/c);n#sigma_{TOF}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - mHistManager.add("TrackCuts/AntiProton/fNsigmaTPCTOFvsPAntiProtonP", "NSigmaTPCTOF AntiProton P;p (GeV/c);n#sigma_{comb}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, 0.f, 10.f}}}); - - mHistManager.add("TrackCuts/AntiProton/fDCAxyAntiProton", "fDCAxy AntiProton;DCA_{XY};Entries", HistType::kTH1F, {{500, -0.5f, 0.5f}}); - mHistManager.add("TrackCuts/AntiProton/fDCAzAntiProton", "fDCAz AntiProton;DCA_{Z};Entries", HistType::kTH1F, {{500, -0.5f, 0.5f}}); - mHistManager.add("TrackCuts/AntiProton/fTPCsClsAntiProton", "fTPCsCls AntiProton;TPC Shared Clusters;Entries", HistType::kTH1F, {{163, -1.0f, 162.0f}}); - mHistManager.add("TrackCuts/AntiProton/fTPCcRowsAntiProton", "fTPCcRows AntiProton;TPC Crossed Rows;Entries", HistType::kTH1F, {{163, -1.0f, 162.0f}}); - mHistManager.add("TrackCuts/AntiProton/fTrkTPCfClsAntiProton", "fTrkTPCfCls AntiProton;TPC Findable/CrossedRows;Entries", HistType::kTH1F, {{500, 0.0f, 3.0f}}); - mHistManager.add("TrackCuts/AntiProton/fTPCnclsAntiProton", "fTPCncls AntiProton;TPC Clusters;Entries", HistType::kTH1F, {{163, -1.0f, 162.0f}}); - - // deuteron - mHistManager.add("TrackCuts/Deuteron/fPtDeuteron", "Transverse momentum of all processed tracks;p_{T} (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - mHistManager.add("TrackCuts/Deuteron/fMomCorDeuteronDif", "Momentum correlation;p_{reco} (GeV/c); (p_{TPC} - p_{reco}) (GeV/c)", {HistType::kTH2F, {{500, 0, 10}, {600, -3, 3}}}); - mHistManager.add("TrackCuts/Deuteron/fMomCorDeuteronRatio", "Momentum correlation;p_{reco} (GeV/c); |p_{TPC} - p_{reco}| (GeV/c)", {HistType::kTH2F, {{500, 0, 10}, {200, -1, 1}}}); - mHistManager.add("TrackCuts/Deuteron/fEtaDeuteron", "Pseudorapidity of all processed tracks;#eta;Entries", HistType::kTH1F, {{500, -2, 2}}); - mHistManager.add("TrackCuts/Deuteron/fPhiDeuteron", "Azimuthal angle of all processed tracks;#phi;Entries", HistType::kTH1F, {{720, 0, TMath::TwoPi()}}); - mHistManager.add("TrackCuts/Deuteron/fNsigmaTPCvsPDeuteron", "NSigmaTPC Deuteron;p_{TPC} (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - mHistManager.add("TrackCuts/Deuteron/fNsigmaTOFvsPDeuteron", "NSigmaTOF Deuteron;p_{TPC} (GeV/c);n#sigma_{TOF}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - mHistManager.add("TrackCuts/Deuteron/fNsigmaTPCTOFvsPDeuteron", "NSigmaTPCTOF Deuteron;p_{TPC} (GeV/c);n#sigma_{comb}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, 0.f, 10.f}}}); - mHistManager.add("TrackCuts/Deuteron/fNsigmaITSvsPDeuteron", "NSigmaITS Deuteron;p (GeV/c);n#sigma_{ITS}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - - mHistManager.add("TrackCuts/Deuteron/fNsigmaTPCvsPDeuteronP", "NSigmaTPC Deuteron vd P;p (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - mHistManager.add("TrackCuts/Deuteron/fNsigmaTOFvsPDeuteronP", "NSigmaTOF Deuteron P;p (GeV/c);n#sigma_{TOF}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - mHistManager.add("TrackCuts/Deuteron/fNsigmaTPCTOFvsPDeuteronP", "NSigmaTPCTOF Deuteron P;p (GeV/c);n#sigma_{comb}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, 0.f, 10.f}}}); - - mHistManager.add("TrackCuts/Deuteron/fDCAxyDeuteron", "fDCAxy Deuteron;DCA_{XY};Entries", HistType::kTH1F, {{500, -0.5f, 0.5f}}); - mHistManager.add("TrackCuts/Deuteron/fDCAzDeuteron", "fDCAz Deuteron;DCA_{Z};Entries", HistType::kTH1F, {{500, -0.5f, 0.5f}}); - mHistManager.add("TrackCuts/Deuteron/fTPCsClsDeuteron", "fTPCsCls Deuteron;TPC Shared Clusters;Entries", HistType::kTH1F, {{163, -1.0f, 162.0f}}); - mHistManager.add("TrackCuts/Deuteron/fTPCcRowsDeuteron", "fTPCcRows Deuteron;TPC Crossed Rows;Entries", HistType::kTH1F, {{163, -1.0f, 162.0f}}); - mHistManager.add("TrackCuts/Deuteron/fTrkTPCfClsDeuteron", "fTrkTPCfCls Deuteron;TPC Findable/CrossedRows;Entries", HistType::kTH1F, {{500, 0.0f, 3.0f}}); - mHistManager.add("TrackCuts/Deuteron/fTPCnclsDeuteron", "fTPCncls Deuteron;TPC Clusters;Entries", HistType::kTH1F, {{163, -1.0f, 162.0f}}); - - // antideuteron - mHistManager.add("TrackCuts/AntiDeuteron/fPtAntiDeuteron", "Transverse momentum of all processed tracks;p_{T} (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - mHistManager.add("TrackCuts/AntiDeuteron/fMomCorAntiDeuteronDif", "Momentum correlation;p_{reco} (GeV/c); (p_{TPC} - p_{reco}) (GeV/c)", {HistType::kTH2F, {{500, 0, 10}, {600, -3, 3}}}); - mHistManager.add("TrackCuts/AntiDeuteron/fMomCorAntiDeuteronRatio", "Momentum correlation;p_{reco} (GeV/c); (p_{TPC} - p_{reco}) (GeV/c)", {HistType::kTH2F, {{500, 0, 10}, {200, -1, 1}}}); - mHistManager.add("TrackCuts/AntiDeuteron/fEtaAntiDeuteron", "Pseudorapidity of all processed tracks;#eta;Entries", HistType::kTH1F, {{500, -2, 2}}); - mHistManager.add("TrackCuts/AntiDeuteron/fPhiAntiDeuteron", "Azimuthal angle of all processed tracks;#phi;Entries", HistType::kTH1F, {{720, 0, TMath::TwoPi()}}); - mHistManager.add("TrackCuts/AntiDeuteron/fNsigmaTPCvsPAntiDeuteron", "NSigmaTPC AntiDeuteron;p_{TPC} (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - mHistManager.add("TrackCuts/AntiDeuteron/fNsigmaTOFvsPAntiDeuteron", "NSigmaTOF AntiDeuteron;p_{TPC} (GeV/c);n#sigma_{TOF}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - mHistManager.add("TrackCuts/AntiDeuteron/fNsigmaTPCTOFvsPAntiDeuteron", "NSigmaTPCTOF AntiDeuteron;p_{TPC} (GeV/c);n#sigma_{comb}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, 0.f, 10.f}}}); - mHistManager.add("TrackCuts/AntiDeuteron/fNsigmaITSvsPAntiDeuteron", "NSigmaITS AntiDeuteron;p (GeV/c);n#sigma_{ITS}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - - mHistManager.add("TrackCuts/AntiDeuteron/fNsigmaTPCvsPAntiDeuteronP", "NSigmaTPC AntiDeuteron P;p (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - mHistManager.add("TrackCuts/AntiDeuteron/fNsigmaTOFvsPAntiDeuteronP", "NSigmaTOF AntiDeuteron P;p (GeV/c);n#sigma_{TOF}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - mHistManager.add("TrackCuts/AntiDeuteron/fNsigmaTPCTOFvsPAntiDeuteronP", "NSigmaTPCTOF AntiDeuteron P;p (GeV/c);n#sigma_{comb}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, 0.f, 10.f}}}); - - mHistManager.add("TrackCuts/AntiDeuteron/fDCAxyAntiDeuteron", "fDCAxy AntiDeuteron;DCA_{XY};Entries", HistType::kTH1F, {{500, -0.5f, 0.5f}}); - mHistManager.add("TrackCuts/AntiDeuteron/fDCAzAntiDeuteron", "fDCAz AntiDeuteron;DCA_{Z};Entries", HistType::kTH1F, {{500, -0.5f, 0.5f}}); - mHistManager.add("TrackCuts/AntiDeuteron/fTPCsClsAntiDeuteron", "fTPCsCls AntiDeuteron;TPC Shared Clusters;Entries", HistType::kTH1F, {{163, -1.0f, 162.0f}}); - mHistManager.add("TrackCuts/AntiDeuteron/fTPCcRowsAntiDeuteron", "fTPCcRows AntiDeuteron;TPC Crossed Rows;Entries", HistType::kTH1F, {{163, -1.0f, 162.0f}}); - mHistManager.add("TrackCuts/AntiDeuteron/fTrkTPCfClsAntiDeuteron", "fTrkTPCfCls AntiDeuteron;TPC Findable/CrossedRows;Entries", HistType::kTH1F, {{500, 0.0f, 3.0f}}); - mHistManager.add("TrackCuts/AntiDeuteron/fTPCnclsAntiDeuteron", "fTPCncls AntiDeuteron;TPC Clusters;Entries", HistType::kTH1F, {{163, -1.0f, 162.0f}}); - - // pions - mHistManager.add("TrackCuts/Pion/fPPion", "Momentum of Pions at PV;p (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - mHistManager.add("TrackCuts/Pion/fPTPCPion", "Momentum of Pions at TPC inner wall;p_{TPC} (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - mHistManager.add("TrackCuts/Pion/fPtPion", "Transverse momentum of all processed tracks;p_{T} (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - mHistManager.add("TrackCuts/Pion/fMomCorPionDif", "Momentum correlation;p_{reco} (GeV/c); (p_{TPC} - p_{reco}) (GeV/c)", {HistType::kTH2F, {{500, 0, 10}, {600, -3, 3}}}); - mHistManager.add("TrackCuts/Pion/fMomCorPionRatio", "Momentum correlation;p_{reco} (GeV/c); p_{TPC} - p_{reco} / p_{reco}", {HistType::kTH2F, {{500, 0, 10}, {200, -1, 1}}}); - mHistManager.add("TrackCuts/Pion/fEtaPion", "Pseudorapidity of all processed tracks;#eta;Entries", HistType::kTH1F, {{500, -2, 2}}); - mHistManager.add("TrackCuts/Pion/fPhiPion", "Azimuthal angle of all processed tracks;#phi;Entries", HistType::kTH1F, {{720, 0, TMath::TwoPi()}}); - mHistManager.add("TrackCuts/Pion/fNsigmaTPCvsPPion", "NSigmaTPC Pion;p_{TPC} (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - mHistManager.add("TrackCuts/Pion/fNsigmaTOFvsPPion", "NSigmaTOF Pion;p_{TPC} (GeV/c);n#sigma_{TOF}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - mHistManager.add("TrackCuts/Pion/fNsigmaTPCTOFvsPPion", "NSigmaTPCTOF Pion;p_{TPC} (GeV/c);n#sigma_{comb}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, 0.f, 10.f}}}); - - mHistManager.add("TrackCuts/Pion/fNsigmaTPCvsPPionP", "NSigmaTPC Pion P;p (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - mHistManager.add("TrackCuts/Pion/fNsigmaTOFvsPPionP", "NSigmaTOF Pion P;p (GeV/c);n#sigma_{TOF}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - mHistManager.add("TrackCuts/Pion/fNsigmaTPCTOFvsPPionP", "NSigmaTPCTOF Pion P;p (GeV/c);n#sigma_{comb}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, 0.f, 10.f}}}); - - mHistManager.add("TrackCuts/Pion/fDCAxyPion", "fDCAxy Pion;DCA_{XY};Entries", HistType::kTH1F, {{500, -0.5f, 0.5f}}); - mHistManager.add("TrackCuts/Pion/fDCAzPion", "fDCAz Pion;DCA_{Z};Entries", HistType::kTH1F, {{500, -0.5f, 0.5f}}); - mHistManager.add("TrackCuts/Pion/fTPCsClsPion", "fTPCsCls Pion;TPC Shared Clusters;Entries", HistType::kTH1F, {{163, -1.0f, 162.0f}}); - mHistManager.add("TrackCuts/Pion/fTPCcRowsPion", "fTPCcRows Pion;TPC Crossed Rows;Entries", HistType::kTH1F, {{163, -1.0f, 162.0f}}); - mHistManager.add("TrackCuts/Pion/fTrkTPCfClsPion", "fTrkTPCfCls Pion;TPC Findable/CrossedRows;Entries", HistType::kTH1F, {{500, 0.0f, 3.0f}}); - mHistManager.add("TrackCuts/Pion/fTPCnclsPion", "fTPCncls Pion;TPC Clusters;Entries", HistType::kTH1F, {{163, -1.0f, 162.0f}}); - - // anti-pions - mHistManager.add("TrackCuts/AntiPion/fPtAntiPion", "Transverse momentum of all processed tracks;p_{T} (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - mHistManager.add("TrackCuts/AntiPion/fMomCorAntiPionDif", "Momentum correlation;p_{reco} (GeV/c); (p_{TPC} - p_{reco}) (GeV/c)", {HistType::kTH2F, {{500, 0, 10}, {600, -3, 3}}}); - mHistManager.add("TrackCuts/AntiPion/fMomCorAntiPionRatio", "Momentum correlation;p_{reco} (GeV/c); |p_{TPC} - p_{reco}| (GeV/c)", {HistType::kTH2F, {{500, 0, 10}, {200, -1, 1}}}); - mHistManager.add("TrackCuts/AntiPion/fEtaAntiPion", "Pseudorapidity of all processed tracks;#eta;Entries", HistType::kTH1F, {{500, -2, 2}}); - mHistManager.add("TrackCuts/AntiPion/fPhiAntiPion", "Azimuthal angle of all processed tracks;#phi;Entries", HistType::kTH1F, {{720, 0, TMath::TwoPi()}}); - mHistManager.add("TrackCuts/AntiPion/fNsigmaTPCvsPAntiPion", "NSigmaTPC AntiPion;p_{TPC} (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - mHistManager.add("TrackCuts/AntiPion/fNsigmaTOFvsPAntiPion", "NSigmaTOF AntiPion;p_{TPC} (GeV/c);n#sigma_{TOF}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - mHistManager.add("TrackCuts/AntiPion/fNsigmaTPCTOFvsPAntiPion", "NSigmaTPCTOF AntiPion;p_{TPC} (GeV/c);n#sigma_{comb}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, 0.f, 10.f}}}); - - mHistManager.add("TrackCuts/AntiPion/fNsigmaTPCvsPAntiPionP", "NSigmaTPC AntiPion P;p (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - mHistManager.add("TrackCuts/AntiPion/fNsigmaTOFvsPAntiPionP", "NSigmaTOF AntiPion P;p (GeV/c);n#sigma_{TOF}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - mHistManager.add("TrackCuts/AntiPion/fNsigmaTPCTOFvsPAntiPionP", "NSigmaTPCTOF AntiPion P;p (GeV/c);n#sigma_{comb}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, 0.f, 10.f}}}); - - mHistManager.add("TrackCuts/AntiPion/fDCAxyAntiPion", "fDCAxy AntiPion;DCA_{XY};Entries", HistType::kTH1F, {{500, -0.5f, 0.5f}}); - mHistManager.add("TrackCuts/AntiPion/fDCAzAntiPion", "fDCAz AntiPion;DCA_{Z};Entries", HistType::kTH1F, {{500, -0.5f, 0.5f}}); - mHistManager.add("TrackCuts/AntiPion/fTPCsClsAntiPion", "fTPCsCls AntiPion;TPC Shared Clusters;Entries", HistType::kTH1F, {{163, -1.0f, 162.0f}}); - mHistManager.add("TrackCuts/AntiPion/fTPCcRowsAntiPion", "fTPCcRows AntiPion;TPC Crossed Rows;Entries", HistType::kTH1F, {{163, -1.0f, 162.0f}}); - mHistManager.add("TrackCuts/AntiPion/fTrkTPCfClsAntiPion", "fTrkTPCfCls AntiPion;TPC Findable/CrossedRows;Entries", HistType::kTH1F, {{500, 0.0f, 3.0f}}); - mHistManager.add("TrackCuts/AntiPion/fTPCnclsAntiPion", "fTPCncls AntiPion;TPC Clusters;Entries", HistType::kTH1F, {{163, -1.0f, 162.0f}}); - - // HNM - // omega QA - // daughter pos before - mHistManager.add("TrackCuts/HMN/Before/PosDaughter/fInvMass", "Invariant mass HMN Pos Daugh;M_{#pi};Entries", HistType::kTH1F, {{500, 0, 1}}); - mHistManager.add("TrackCuts/HMN/Before/PosDaughter/fPt", "Transverse momentum HMN Pos Daugh tracks;p_{T} (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - mHistManager.add("TrackCuts/HMN/Before/PosDaughter/fEta", "HMN Pos Daugh Eta;#eta;Entries", HistType::kTH1F, {{500, -2, 2}}); - mHistManager.add("TrackCuts/HMN/Before/PosDaughter/fPhi", "Azimuthal angle of HMN Pos Daugh tracks;#phi;Entries", HistType::kTH1F, {{720, 0, TMath::TwoPi()}}); - // daughter neg before - mHistManager.add("TrackCuts/HMN/Before/NegDaughter/fInvMass", "Invariant mass HMN Neg Daugh;M_{#pi};Entries", HistType::kTH1F, {{500, 0, 1}}); - mHistManager.add("TrackCuts/HMN/Before/NegDaughter/fPt", "Transverse momentum HMN Neg Daugh tracks;p_{T} (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - mHistManager.add("TrackCuts/HMN/Before/NegDaughter/fEta", "HMN Neg Daugh Eta;#eta;Entries", HistType::kTH1F, {{500, -2, 2}}); - mHistManager.add("TrackCuts/HMN/Before/NegDaughter/fPhi", "Azimuthal angle of HMN Neg Daugh tracks;#phi;Entries", HistType::kTH1F, {{720, 0, TMath::TwoPi()}}); - // HMNCand tracks before - mHistManager.add("TrackCuts/HMN/Before/fInvMass_tracks", "Invariant mass HMNCand;M_{#pi#pi#gammg#gamma};Entries", HistType::kTH1F, {{5000, 0, 5}}); - mHistManager.add("TrackCuts/HMN/Before/fPt_tracks", "Transverse momentum HMNCand;p_{T} (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - mHistManager.add("TrackCuts/HMN/Before/fEta_tracks", "Pseudorapidity of HMNCand;#eta;Entries", HistType::kTH1F, {{500, -2, 2}}); - mHistManager.add("TrackCuts/HMN/Before/fPhi_tracks", "Azimuthal angle of HMNCand;#phi;Entries", HistType::kTH1F, {{720, 0, TMath::TwoPi()}}); - // Right now we loose the information about the used tracks and gg properties after creating the HeavyNeutralMeson struct: Maybe it is better to keep track of these? - /*// daughter pos after - mHistManager.add("TrackCuts/omega/After/PosDaughter/fPt", "Transverse momentum omegaCand Pos Daugh tracks;p_{T} (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - mHistManager.add("TrackCuts/omega/After/PosDaughter/fEta", "omegaCandPos Daugh Eta;#eta;Entries", HistType::kTH1F, {{500, -2, 2}}); - mHistManager.add("TrackCuts/omega/After/PosDaughter/fPhi", "Azimuthal angle of omegaCand Pos Daugh tracks;#phi;Entries", HistType::kTH1F, {{720, 0, TMath::TwoPi()}}); - // daughter neg after - mHistManager.add("TrackCuts/omega/After/NegDaughter/fPt", "Transverse momentum omegaCand Neg Daugh tracks;p_{T} (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - mHistManager.add("TrackCuts/omega/After/NegDaughter/fEta", "omegaCand Neg Daugh Eta;#eta;Entries", HistType::kTH1F, {{500, -2, 2}}); - mHistManager.add("TrackCuts/omega/After/NegDaughter/fPhi", "Azimuthal angle of omegaCand Neg Daugh tracks;#phi;Entries", HistType::kTH1F, {{720, 0, TMath::TwoPi()}});*/ - // omegaCand after - // HMNCand full information - mHistManager.add("TrackCuts/HMN/Before/PCM/fInvMass", "Invariant mass HMNCand;M_{#pi#pi#gammg#gamma};Entries", HistType::kTH1F, {{5000, 0, 5}}); - mHistManager.add("TrackCuts/HMN/Before/PCM/fPt", "Transverse momentum HMNCand;p_{T} (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - mHistManager.add("TrackCuts/HMN/Before/PCM/fEta", "Pseudorapidity of HMNCand;#eta;Entries", HistType::kTH1F, {{500, -2, 2}}); - mHistManager.add("TrackCuts/HMN/Before/PCM/fPhi", "Azimuthal angle of HMNCand;#phi;Entries", HistType::kTH1F, {{720, 0, TMath::TwoPi()}}); - mHistManager.add("TrackCuts/HMN/Before/EMC/fInvMass", "Invariant mass HMNCand;M_{#pi#pi#gammg#gamma};Entries", HistType::kTH1F, {{5000, 0, 5}}); - mHistManager.add("TrackCuts/HMN/Before/EMC/fPt", "Transverse momentum HMNCand;p_{T} (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - mHistManager.add("TrackCuts/HMN/Before/EMC/fEta", "Pseudorapidity of HMNCand;#eta;Entries", HistType::kTH1F, {{500, -2, 2}}); - mHistManager.add("TrackCuts/HMN/Before/EMC/fPhi", "Azimuthal angle of HMNCand;#phi;Entries", HistType::kTH1F, {{720, 0, TMath::TwoPi()}}); - mHistManager.add("TrackCuts/HMN/Before/PCMEMC/fInvMass", "Invariant mass HMNCand;M_{#pi#pi#gammg#gamma};Entries", HistType::kTH1F, {{5000, 0, 5}}); - mHistManager.add("TrackCuts/HMN/Before/PCMEMC/fPt", "Transverse momentum HMNCand;p_{T} (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - mHistManager.add("TrackCuts/HMN/Before/PCMEMC/fEta", "Pseudorapidity of HMNCand;#eta;Entries", HistType::kTH1F, {{500, -2, 2}}); - mHistManager.add("TrackCuts/HMN/Before/PCMEMC/fPhi", "Azimuthal angle of HMNCand;#phi;Entries", HistType::kTH1F, {{720, 0, TMath::TwoPi()}}); - // OmegaCand - mHistManager.add("TrackCuts/HMN/After/Omega/PCM/fInvMass", "Invariant mass omegaCand;M_{#pi#pi};Entries", HistType::kTH1F, {{5000, 0, 5}}); - mHistManager.add("TrackCuts/HMN/After/Omega/PCM/fPt", "Transverse momentum omegaCand;p_{T} (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - mHistManager.add("TrackCuts/HMN/After/Omega/PCM/fEta", "Pseudorapidity of omegaCand;#eta;Entries", HistType::kTH1F, {{500, -2, 2}}); - mHistManager.add("TrackCuts/HMN/After/Omega/PCM/fPhi", "Azimuthal angle of omegaCand;#phi;Entries", HistType::kTH1F, {{720, 0, TMath::TwoPi()}}); - mHistManager.add("TrackCuts/HMN/After/Omega/EMC/fInvMass", "Invariant mass omegaCand;M_{#pi#pi};Entries", HistType::kTH1F, {{5000, 0, 5}}); - mHistManager.add("TrackCuts/HMN/After/Omega/EMC/fPt", "Transverse momentum omegaCand;p_{T} (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - mHistManager.add("TrackCuts/HMN/After/Omega/EMC/fEta", "Pseudorapidity of omegaCand;#eta;Entries", HistType::kTH1F, {{500, -2, 2}}); - mHistManager.add("TrackCuts/HMN/After/Omega/EMC/fPhi", "Azimuthal angle of omegaCand;#phi;Entries", HistType::kTH1F, {{720, 0, TMath::TwoPi()}}); - // EtaPrimeCand - mHistManager.add("TrackCuts/HMN/After/EtaPrime/PCM/fInvMass", "Invariant mass EtaPrimeCand;M_{#pi#pi};Entries", HistType::kTH1F, {{5000, 0, 5}}); - mHistManager.add("TrackCuts/HMN/After/EtaPrime/PCM/fPt", "Transverse momentum EtaPrimeCand;p_{T} (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - mHistManager.add("TrackCuts/HMN/After/EtaPrime/PCM/fEta", "Pseudorapidity of EtaPrimeCand;#eta;Entries", HistType::kTH1F, {{500, -2, 2}}); - mHistManager.add("TrackCuts/HMN/After/EtaPrime/PCM/fPhi", "Azimuthal angle of EtaPrimeCand;#phi;Entries", HistType::kTH1F, {{720, 0, TMath::TwoPi()}}); - mHistManager.add("TrackCuts/HMN/After/EtaPrime/EMC/fInvMass", "Invariant mass EtaPrimeCand;M_{#pi#pi};Entries", HistType::kTH1F, {{5000, 0, 5}}); - mHistManager.add("TrackCuts/HMN/After/EtaPrime/EMC/fPt", "Transverse momentum EtaPrimeCand;p_{T} (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - mHistManager.add("TrackCuts/HMN/After/EtaPrime/EMC/fEta", "Pseudorapidity of EtaPrimeCand;#eta;Entries", HistType::kTH1F, {{500, -2, 2}}); - mHistManager.add("TrackCuts/HMN/After/EtaPrime/EMC/fPhi", "Azimuthal angle of EtaPrimeCand;#phi;Entries", HistType::kTH1F, {{720, 0, TMath::TwoPi()}}); - - // Trigger combs - // for ppomega - mHistManager.add("ppomega/fMultiplicity", "Multiplicity of all processed events;Mult;Entries", HistType::kTH1F, {{500, 0, 500}}); - mHistManager.add("ppomega/fZvtx", "Zvtx of all processed events;Z_{vtx};Entries", HistType::kTH1F, {{500, -15, 15}}); - - mHistManager.add("ppomega/fSE_particle_EMC", "Same Event distribution", HistType::kTH1F, {{8000, 0, 8}}); - mHistManager.add("ppomega/fSE_Antiparticle_EMC", "Same Event distribution", HistType::kTH1F, {{8000, 0, 8}}); - mHistManager.add("ppomega/fProtonPtVsQ3_EMC", "pT (proton) vs Q_{3};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {{150, 0, 1.5}, {500, 0, 10}}}); - mHistManager.add("ppomega/fOmegaCandPtVsQ3_EMC", "pT (omega) vs Q_{3};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {{150, 0, 1.5}, {500, 0, 10}}}); - mHistManager.add("ppomega/fAntiProtonPtVsQ3_EMC", "pT (antiproton) vs Q_{3};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {{150, 0, 1.5}, {500, 0, 10}}}); - - mHistManager.add("ppomega/fSE_particle_PCM", "Same Event distribution", HistType::kTH1F, {{8000, 0, 8}}); - mHistManager.add("ppomega/fSE_Antiparticle_PCM", "Same Event distribution", HistType::kTH1F, {{8000, 0, 8}}); - mHistManager.add("ppomega/fProtonPtVsQ3_PCM", "pT (proton) vs Q_{3};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {{150, 0, 1.5}, {500, 0, 10}}}); - mHistManager.add("ppomega/fOmegaCandPtVsQ3_PCM", "pT (omega) vs Q_{3};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {{150, 0, 1.5}, {500, 0, 10}}}); - mHistManager.add("ppomega/fAntiProtonPtVsQ3_PCM", "pT (antiproton) vs Q_{3};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {{150, 0, 1.5}, {500, 0, 10}}}); - // for ppetaprime - mHistManager.add("ppetaprime/fMultiplicity", "Multiplicity of all processed events;Mult;Entries", HistType::kTH1F, {{500, 0, 500}}); - mHistManager.add("ppetaprime/fZvtx", "Zvtx of all processed events;Z_{vtx};Entries", HistType::kTH1F, {{500, -15, 15}}); - - mHistManager.add("ppetaprime/fSE_particle_EMC", "Same Event distribution", HistType::kTH1F, {{8000, 0, 8}}); - mHistManager.add("ppetaprime/fSE_Antiparticle_EMC", "Same Event distribution", HistType::kTH1F, {{8000, 0, 8}}); - mHistManager.add("ppetaprime/fProtonPtVsQ3_EMC", "pT (proton) vs Q_{3};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {{150, 0, 1.5}, {500, 0, 10}}}); - mHistManager.add("ppetaprime/fEtaPrimeCandPtVsQ3_EMC", "pT (etaprime) vs Q_{3};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {{150, 0, 1.5}, {500, 0, 10}}}); - mHistManager.add("ppetaprime/fAntiProtonPtVsQ3_EMC", "pT (antiproton) vs Q_{3};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {{150, 0, 1.5}, {500, 0, 10}}}); - - mHistManager.add("ppetaprime/fSE_particle_PCM", "Same Event distribution", HistType::kTH1F, {{8000, 0, 8}}); - mHistManager.add("ppetaprime/fSE_Antiparticle_PCM", "Same Event distribution", HistType::kTH1F, {{8000, 0, 8}}); - mHistManager.add("ppetaprime/fProtonPtVsQ3_PCM", "pT (proton) vs Q_{3};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {{150, 0, 1.5}, {500, 0, 10}}}); - mHistManager.add("ppetaprime/fEtaPrimeCandPtVsQ3_PCM", "pT (etaprime) vs Q_{3};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {{150, 0, 1.5}, {500, 0, 10}}}); - mHistManager.add("ppetaprime/fAntiProtonPtVsQ3_PCM", "pT (antiproton) vs Q_{3};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {{150, 0, 1.5}, {500, 0, 10}}}); - - // two body - // omegad - mHistManager.add("omegad/fMultiplicity", "Multiplicity of all processed events;Mult;Entries", HistType::kTH1F, {{500, 0, 500}}); - mHistManager.add("omegad/fZvtx", "Zvtx of all processed events;Z_{vtx};Entries", HistType::kTH1F, {{500, -15, 15}}); - - mHistManager.add("omegad/fSE_particle_PCM", "Same Event distribution", HistType::kTH1F, {{8000, 0, 8}}); - mHistManager.add("omegad/fSE_Antiparticle_PCM", "Same Event distribution", HistType::kTH1F, {{8000, 0, 8}}); - mHistManager.add("omegad/fomegaPtVskstar_PCM", "Same Event distribution", HistType::kTH1F, {{8000, 0, 8}}); - mHistManager.add("omegad/fDeuteronPtVskstar_PCM", "Same Event distribution", HistType::kTH1F, {{8000, 0, 8}}); - mHistManager.add("omegad/fAntiDeuteronPtVskstar_PCM", "Same Event distribution", HistType::kTH1F, {{8000, 0, 8}}); - mHistManager.add("omegad/fSE_particle_EMC", "Same Event distribution", HistType::kTH1F, {{8000, 0, 8}}); - mHistManager.add("omegad/fSE_Antiparticle_EMC", "Same Event distribution", HistType::kTH1F, {{8000, 0, 8}}); - mHistManager.add("omegad/fomegaPtVskstar_EMC", "Same Event distribution", HistType::kTH1F, {{8000, 0, 8}}); - mHistManager.add("omegad/fDeuteronPtVskstar_EMC", "Same Event distribution", HistType::kTH1F, {{8000, 0, 8}}); - mHistManager.add("omegad/fAntiDeuteronPtVskstar_EMC", "Same Event distribution", HistType::kTH1F, {{8000, 0, 8}}); - - // etaprimed - mHistManager.add("etaprimed/fMultiplicity", "Multiplicity of all processed events;Mult;Entries", HistType::kTH1F, {{500, 0, 500}}); - mHistManager.add("etaprimed/fZvtx", "Zvtx of all processed events;Z_{vtx};Entries", HistType::kTH1F, {{500, -15, 15}}); - - mHistManager.add("etaprimed/fSE_particle_PCM", "Same Event distribution", HistType::kTH1F, {{8000, 0, 8}}); - mHistManager.add("etaprimed/fSE_Antiparticle_PCM", "Same Event distribution", HistType::kTH1F, {{8000, 0, 8}}); - mHistManager.add("etaprimed/fetaprimePtVskstar_PCM", "Same Event distribution", HistType::kTH1F, {{8000, 0, 8}}); - mHistManager.add("etaprimed/fDeuteronPtVskstar_PCM", "Same Event distribution", HistType::kTH1F, {{8000, 0, 8}}); - mHistManager.add("etaprimed/fAntiDeuteronPtVskstar_PCM", "Same Event distribution", HistType::kTH1F, {{8000, 0, 8}}); - mHistManager.add("etaprimed/fSE_particle_EMC", "Same Event distribution", HistType::kTH1F, {{8000, 0, 8}}); - mHistManager.add("etaprimed/fSE_Antiparticle_EMC", "Same Event distribution", HistType::kTH1F, {{8000, 0, 8}}); - mHistManager.add("etaprimed/fetaprimePtVskstar_EMC", "Same Event distribution", HistType::kTH1F, {{8000, 0, 8}}); - mHistManager.add("etaprimed/fDeuteronPtVskstar_EMC", "Same Event distribution", HistType::kTH1F, {{8000, 0, 8}}); - mHistManager.add("etaprimed/fAntiDeuteronPtVskstar_EMC", "Same Event distribution", HistType::kTH1F, {{8000, 0, 8}}); - - // omegap - mHistManager.add("omegap/fMultiplicity", "Multiplicity of all processed events;Mult;Entries", HistType::kTH1F, {{500, 0, 500}}); - mHistManager.add("omegap/fZvtx", "Zvtx of all processed events;Z_{vtx};Entries", HistType::kTH1F, {{500, -15, 15}}); - - mHistManager.add("omegap/fSE_particle_PCM", "Same Event distribution", HistType::kTH1F, {{8000, 0, 8}}); - mHistManager.add("omegap/fSE_Antiparticle_PCM", "Same Event distribution", HistType::kTH1F, {{8000, 0, 8}}); - mHistManager.add("omegap/fomegaPtVskstar_PCM", "Same Event distribution", HistType::kTH1F, {{8000, 0, 8}}); - mHistManager.add("omegap/fProtonPtVskstar_PCM", "Same Event distribution", HistType::kTH1F, {{8000, 0, 8}}); - mHistManager.add("omegap/fAntiProtonPtVskstar_PCM", "Same Event distribution", HistType::kTH1F, {{8000, 0, 8}}); - mHistManager.add("omegap/fSE_particle_EMC", "Same Event distribution", HistType::kTH1F, {{8000, 0, 8}}); - mHistManager.add("omegap/fSE_Antiparticle_EMC", "Same Event distribution", HistType::kTH1F, {{8000, 0, 8}}); - mHistManager.add("omegap/fomegaPtVskstar_EMC", "Same Event distribution", HistType::kTH1F, {{8000, 0, 8}}); - mHistManager.add("omegap/fProtonPtVskstar_EMC", "Same Event distribution", HistType::kTH1F, {{8000, 0, 8}}); - mHistManager.add("omegap/fAntiProtonPtVskstar_EMC", "Same Event distribution", HistType::kTH1F, {{8000, 0, 8}}); - - // etaprimep - mHistManager.add("etaprimep/fMultiplicity", "Multiplicity of all processed events;Mult;Entries", HistType::kTH1F, {{500, 0, 500}}); - mHistManager.add("etaprimep/fZvtx", "Zvtx of all processed events;Z_{vtx};Entries", HistType::kTH1F, {{500, -15, 15}}); - - mHistManager.add("etaprimep/fSE_particle_PCM", "Same Event distribution", HistType::kTH1F, {{8000, 0, 8}}); - mHistManager.add("etaprimep/fSE_Antiparticle_PCM", "Same Event distribution", HistType::kTH1F, {{8000, 0, 8}}); - mHistManager.add("etaprimep/fetaprimePtVskstar_PCM", "Same Event distribution", HistType::kTH1F, {{8000, 0, 8}}); - mHistManager.add("etaprimep/fProtonPtVskstar_PCM", "Same Event distribution", HistType::kTH1F, {{8000, 0, 8}}); - mHistManager.add("etaprimep/fAntiProtonPtVskstar_PCM", "Same Event distribution", HistType::kTH1F, {{8000, 0, 8}}); - mHistManager.add("etaprimep/fSE_particle_EMC", "Same Event distribution", HistType::kTH1F, {{8000, 0, 8}}); - mHistManager.add("etaprimep/fSE_Antiparticle_EMC", "Same Event distribution", HistType::kTH1F, {{8000, 0, 8}}); - mHistManager.add("etaprimep/fetaprimePtVskstar_EMC", "Same Event distribution", HistType::kTH1F, {{8000, 0, 8}}); - mHistManager.add("etaprimep/fProtonPtVskstar_EMC", "Same Event distribution", HistType::kTH1F, {{8000, 0, 8}}); - mHistManager.add("etaprimep/fAntiProtonPtVskstar_EMC", "Same Event distribution", HistType::kTH1F, {{8000, 0, 8}}); - - if (ConfDoEMCShift.value) { - for (int iSM = 0; iSM < 20; iSM++) { - EMCEtaShift[iSM] = ConfEMCEtaShift.value[iSM]; - EMCPhiShift[iSM] = ConfEMCPhiShift.value[iSM]; - LOG(info) << "SM-wise shift in eta/phi for SM " << iSM << ": " << EMCEtaShift[iSM] << " / " << EMCPhiShift[iSM]; + if (cfgDoEMCShift.value) { + for (int iSM = 0; iSM < nSMs; iSM++) { + emcEtaShift[iSM] = cfgEMCEtaShift.value[iSM]; + emcPhiShift[iSM] = cfgEMCPhiShift.value[iSM]; + LOG(info) << "SM-wise shift in eta/phi for SM " << iSM << ": " << emcEtaShift[iSM] << " / " << emcPhiShift[iSM]; } } } - Preslice perCollision_pcm = aod::v0photonkf::collisionId; - Preslice perCollision_emc = aod::skimmedcluster::collisionId; void process(aod::MyCollision const& collision, aod::MyBCs const&, aod::SkimEMCClusters const& clusters, aod::V0PhotonsKF const& v0s, aod::SelectedTracks const& tracks) { // inlcude ITS PID information auto tracksWithItsPid = soa::Attach(tracks); - mHistManager.fill(HIST("Event/hCollisionCounter"), 0.); - // QA all evts mHistManager.fill(HIST("fProcessedEvents"), 0); - mHistManager.fill(HIST("EventCuts/fMultiplicityBefore"), collision.multNTracksPV()); - mHistManager.fill(HIST("EventCuts/fZvtxBefore"), collision.posZ()); + mHistManager.fill(HIST("Event/fMultiplicityBefore"), collision.multNTracksPV()); + mHistManager.fill(HIST("Event/fZvtxBefore"), collision.posZ()); // Ensure evts are consistent with Sel8 and Vtx-z selection - if (!isSelectedEvent(collision)) { + if (!isSelectedEvent(collision)) return; - } // QA accepted evts - mHistManager.fill(HIST("EventCuts/fMultiplicityAfter"), collision.multNTracksPV()); - mHistManager.fill(HIST("EventCuts/fZvtxAfter"), collision.posZ()); + mHistManager.fill(HIST("Event/fMultiplicityAfter"), collision.multNTracksPV()); + mHistManager.fill(HIST("Event/fZvtxAfter"), collision.posZ()); - colContainsPCMOmega = colContainsEMCOmega = colContainsPCMEtaPrime = colContainsEMCEtaPrime = false; - bool keepFemtoEvent[CFTrigger::kNFemtoTriggers] = {false, false, false, false, false, false}; - int lowMomentumMultiplets[CFTrigger::kNFemtoTriggers] = {0, 0, 0, 0, 0, 0}; + colContainsPCMOmega = colContainsEMCOmega = colContainsPCMEtaPrime = colContainsEMCEtaPrime = false; // Used by spectrum trigger to flag events with high-pT omega/eta' candidates + int lowMomentumMultiplets[hnmtrigger::kNFemtoTriggers] = {0, 0, 0, 0, 0, 0}; // Number of found femto pairs/triplets for each femto trigger + bool keepFemtoEvent[hnmtrigger::kNFemtoTriggers] = {false, false, false, false, false, false}; // Set based on number of found pairs (see above) - used to flag femto events // clean vecs // HNM candidates @@ -824,646 +481,679 @@ struct HeavyNeutralMesonFilter { vHNMs.clear(); // vGGs vector is cleared in reconstructGGs. - if (collision.foundBC_as().alias_bit(kTVXinEMC)) { - mHistManager.fill(HIST("Event/hCollisionCounter"), 1.); - mHistManager.fill(HIST("fProcessedEvents"), 8); - } - - auto v0sInThisCollision = v0s.sliceBy(perCollision_pcm, collision.globalIndex()); - auto clustersInThisCollision = clusters.sliceBy(perCollision_emc, collision.globalIndex()); - + // ---------------------------------> EMCal event QA <---------------------------------- + // - Fill Event/nEMCalEvents histogram for EMCal event QA + // ------------------------------------------------------------------------------------- + bool bcHasEMCCells = collision.isemcreadout(); + bool iskTVXinEMC = collision.foundBC_as().alias_bit(kTVXinEMC); + bool isL0Triggered = collision.foundBC_as().alias_bit(kEMC7) || collision.foundBC_as().alias_bit(kEG1) || collision.foundBC_as().alias_bit(kEG2); + + if (bcHasEMCCells && iskTVXinEMC) + mHistManager.fill(HIST("Event/nEMCalEvents"), 0); + if (bcHasEMCCells && isL0Triggered) + mHistManager.fill(HIST("Event/nEMCalEvents"), 1); + if (bcHasEMCCells && !iskTVXinEMC && !isL0Triggered) + mHistManager.fill(HIST("Event/nEMCalEvents"), 2); + if (!bcHasEMCCells && iskTVXinEMC) + mHistManager.fill(HIST("Event/nEMCalEvents"), 3); + if (!bcHasEMCCells && isL0Triggered) + mHistManager.fill(HIST("Event/nEMCalEvents"), 4); + + // --------------------------------> Process Photons <---------------------------------- + // - Slice clusters and V0s by collision ID to get the ones in this collision + // - Store the clusters and V0s in the vGammas vector + // - Reconstruct gamma-gamma pairs + // ------------------------------------------------------------------------------------- + auto v0sInThisCollision = v0s.sliceBy(perCollisionPCM, collision.globalIndex()); + auto clustersInThisCollision = clusters.sliceBy(perCollisionEMC, collision.globalIndex()); mHistManager.fill(HIST("Event/nClustersVsV0s"), clustersInThisCollision.size(), v0sInThisCollision.size()); - mHistManager.fill(HIST("Event/nTracks"), tracksWithItsPid.size()); std::vector vGammas; - hnmutilities::storeGammasInVector(clustersInThisCollision, v0sInThisCollision, vGammas, EMCEtaShift, EMCPhiShift); + hnmutilities::storeGammasInVector(clustersInThisCollision, v0sInThisCollision, vGammas, emcEtaShift, emcPhiShift); hnmutilities::reconstructGGs(vGammas, vGGs); vGammas.clear(); processGGs(vGGs); - bool isProton = false; - bool isDeuteron = false; - bool isPion = false; - - // #femtoPart + // ------------------------------> Loop over all tracks <------------------------------- + // - Sort them into vectors based on PID ((anti)protons, (anti)deuterons, (anti)pions) + // - Fill QA histograms for all tracks and per particle species + // ------------------------------------------------------------------------------------- for (const auto& track : tracksWithItsPid) { - // General QA mHistManager.fill(HIST("TrackCuts/TracksBefore/fPtTrackBefore"), track.pt()); mHistManager.fill(HIST("TrackCuts/TracksBefore/fEtaTrackBefore"), track.eta()); mHistManager.fill(HIST("TrackCuts/TracksBefore/fPhiTrackBefore"), track.phi()); - // Fill PID info - if (track.sign() > 0) { - mHistManager.fill(HIST("TrackCuts/TPCSignal/fTPCSignal"), track.tpcInnerParam(), track.tpcSignal()); - mHistManager.fill(HIST("TrackCuts/TPCSignal/fTPCSignalP"), track.p(), track.tpcSignal()); + if (track.sign() > 0) { // All particles (positive electric charge) + mHistManager.fill(HIST("TrackCuts/TPCSignal/fTPCSignalTPCP"), track.tpcInnerParam(), track.tpcSignal()); + mHistManager.fill(HIST("TrackCuts/TPCSignal/fTPCSignal"), track.p(), track.tpcSignal()); mHistManager.fill(HIST("TrackCuts/TracksBefore/fMomCorrelationPos"), track.p(), track.tpcInnerParam()); } - if (track.sign() < 0) { - - mHistManager.fill(HIST("TrackCuts/TPCSignal/fTPCSignalAnti"), track.tpcInnerParam(), track.tpcSignal()); - mHistManager.fill(HIST("TrackCuts/TPCSignal/fTPCSignalAntiP"), track.p(), track.tpcSignal()); + if (track.sign() < 0) { // All anti-particles (negative electric charge) + mHistManager.fill(HIST("TrackCuts/TPCSignal/fTPCSignalAntiTPCP"), track.tpcInnerParam(), track.tpcSignal()); + mHistManager.fill(HIST("TrackCuts/TPCSignal/fTPCSignalAnti"), track.p(), track.tpcSignal()); mHistManager.fill(HIST("TrackCuts/TracksBefore/fMomCorrelationNeg"), track.p(), track.tpcInnerParam()); } - // #fill protons and deuterons - isProton = (isSelectedTrackPID(track, CFTrigger::kProton) && isSelectedTrack(track, CFTrigger::kProton)); - isDeuteron = (isSelectedTrackPID(track, CFTrigger::kDeuteron) && isSelectedTrack(track, CFTrigger::kDeuteron)); - isPion = (isSelectedTrackPID(track, CFTrigger::kPion) && isSelectedTrack(track, CFTrigger::kPion)); + // For each track, check if it fulfills track and PID criteria to be identified as a proton, deuteron or pion + bool isProton = (isSelectedTrackPID(track, hnmtrigger::kProton) && isSelectedTrack(track, hnmtrigger::kProton)); + bool isDeuteron = (isSelectedTrackPID(track, hnmtrigger::kDeuteron) && isSelectedTrack(track, hnmtrigger::kDeuteron)); + bool isPion = (isSelectedTrackPID(track, hnmtrigger::kPion) && isSelectedTrack(track, hnmtrigger::kPion)); - if (track.sign() > 0) { // part + if (track.sign() > 0) { // Positive charge -> Particles if (isProton) { proton.emplace_back(track.pt(), track.eta(), track.phi(), mMassProton); mHistManager.fill(HIST("TrackCuts/TracksBefore/fMomCorrelationAfterCutsProton"), track.p(), track.tpcInnerParam()); - mHistManager.fill(HIST("TrackCuts/TPCSignal/fTPCSignalProton"), track.tpcInnerParam(), track.tpcSignal()); - mHistManager.fill(HIST("TrackCuts/Proton/fPProton"), track.p()); - mHistManager.fill(HIST("TrackCuts/Proton/fPTPCProton"), track.tpcInnerParam()); - mHistManager.fill(HIST("TrackCuts/Proton/fPtProton"), track.pt()); - mHistManager.fill(HIST("TrackCuts/Proton/fMomCorProtonDif"), track.p(), track.tpcInnerParam() - track.p()); - mHistManager.fill(HIST("TrackCuts/Proton/fMomCorProtonRatio"), track.p(), (track.tpcInnerParam() - track.p()) / track.p()); - mHistManager.fill(HIST("TrackCuts/Proton/fEtaProton"), track.eta()); - mHistManager.fill(HIST("TrackCuts/Proton/fPhiProton"), track.phi()); - mHistManager.fill(HIST("TrackCuts/Proton/fNsigmaTPCvsPProton"), track.tpcInnerParam(), track.tpcNSigmaPr()); - mHistManager.fill(HIST("TrackCuts/Proton/fNsigmaTOFvsPProton"), track.tpcInnerParam(), track.tofNSigmaPr()); + + mHistManager.fill(HIST("TrackCuts/Proton/fP"), track.p()); + mHistManager.fill(HIST("TrackCuts/Proton/fPt"), track.pt()); + mHistManager.fill(HIST("TrackCuts/Proton/fMomCorDif"), track.p(), track.tpcInnerParam() - track.p()); + mHistManager.fill(HIST("TrackCuts/Proton/fMomCorRatio"), track.p(), (track.tpcInnerParam() - track.p()) / track.p()); + mHistManager.fill(HIST("TrackCuts/Proton/fEta"), track.eta()); + mHistManager.fill(HIST("TrackCuts/Proton/fPhi"), track.phi()); + + mHistManager.fill(HIST("TrackCuts/Proton/fNsigmaTPCvsTPCP"), track.tpcInnerParam(), track.tpcNSigmaPr()); + mHistManager.fill(HIST("TrackCuts/Proton/fNsigmaTOFvsTPCP"), track.tpcInnerParam(), track.tofNSigmaPr()); auto nSigmaTrackTPCTOF = std::sqrt(std::pow(track.tpcNSigmaPr(), 2) + std::pow(track.tofNSigmaPr(), 2)); - mHistManager.fill(HIST("TrackCuts/Proton/fNsigmaTPCTOFvsPProton"), track.tpcInnerParam(), std::sqrt(std::pow(track.tpcNSigmaPr() - nSigmaTrackTPCTOF, 2) + std::pow(track.tofNSigmaPr() - nSigmaTrackTPCTOF, 2))); - mHistManager.fill(HIST("TrackCuts/Proton/fNsigmaITSvsPProton"), track.p(), track.itsNSigmaPr()); - - mHistManager.fill(HIST("TrackCuts/Proton/fNsigmaTPCvsPProtonP"), track.p(), track.tpcNSigmaPr()); - mHistManager.fill(HIST("TrackCuts/Proton/fNsigmaTOFvsPProtonP"), track.p(), track.tofNSigmaPr()); - mHistManager.fill(HIST("TrackCuts/Proton/fNsigmaTPCTOFvsPProtonP"), track.p(), std::sqrt(std::pow(track.tpcNSigmaPr() - nSigmaTrackTPCTOF, 2) + std::pow(track.tofNSigmaPr() - nSigmaTrackTPCTOF, 2))); - - mHistManager.fill(HIST("TrackCuts/Proton/fDCAxyProton"), track.dcaXY()); - mHistManager.fill(HIST("TrackCuts/Proton/fDCAzProton"), track.dcaZ()); - mHistManager.fill(HIST("TrackCuts/Proton/fTPCsClsProton"), track.tpcNClsShared()); - mHistManager.fill(HIST("TrackCuts/Proton/fTPCcRowsProton"), track.tpcNClsCrossedRows()); - mHistManager.fill(HIST("TrackCuts/Proton/fTrkTPCfClsProton"), track.tpcCrossedRowsOverFindableCls()); - mHistManager.fill(HIST("TrackCuts/Proton/fTPCnclsProton"), track.tpcNClsFound()); + mHistManager.fill(HIST("TrackCuts/Proton/fNsigmaTPCTOFvsTPCP"), track.tpcInnerParam(), std::sqrt(std::pow(track.tpcNSigmaPr() - nSigmaTrackTPCTOF, 2) + std::pow(track.tofNSigmaPr() - nSigmaTrackTPCTOF, 2))); + mHistManager.fill(HIST("TrackCuts/Proton/fNsigmaITSvsP"), track.p(), track.itsNSigmaPr()); + mHistManager.fill(HIST("TrackCuts/Proton/fNsigmaTPCvsP"), track.p(), track.tpcNSigmaPr()); + mHistManager.fill(HIST("TrackCuts/Proton/fNsigmaTOFvsP"), track.p(), track.tofNSigmaPr()); + mHistManager.fill(HIST("TrackCuts/Proton/fNsigmaTPCTOFvsP"), track.p(), std::sqrt(std::pow(track.tpcNSigmaPr() - nSigmaTrackTPCTOF, 2) + std::pow(track.tofNSigmaPr() - nSigmaTrackTPCTOF, 2))); + + mHistManager.fill(HIST("TrackCuts/Proton/fDCAxy"), track.dcaXY()); + mHistManager.fill(HIST("TrackCuts/Proton/fDCAz"), track.dcaZ()); + mHistManager.fill(HIST("TrackCuts/Proton/fTPCsCls"), track.tpcNClsShared()); + mHistManager.fill(HIST("TrackCuts/Proton/fTPCcRows"), track.tpcNClsCrossedRows()); + mHistManager.fill(HIST("TrackCuts/Proton/fTrkTPCfCls"), track.tpcCrossedRowsOverFindableCls()); + mHistManager.fill(HIST("TrackCuts/Proton/fTPCncls"), track.tpcNClsFound()); } if (isDeuteron) { deuteron.emplace_back(track.pt(), track.eta(), track.phi(), mMassDeuteron); mHistManager.fill(HIST("TrackCuts/TracksBefore/fMomCorrelationAfterCutsDeuteron"), track.p(), track.tpcInnerParam()); - mHistManager.fill(HIST("TrackCuts/TPCSignal/fTPCSignalDeuteron"), track.tpcInnerParam(), track.tpcSignal()); - mHistManager.fill(HIST("TrackCuts/Deuteron/fPtDeuteron"), track.pt()); - mHistManager.fill(HIST("TrackCuts/Deuteron/fMomCorDeuteronDif"), track.p(), track.tpcInnerParam() - track.p()); - mHistManager.fill(HIST("TrackCuts/Deuteron/fMomCorDeuteronRatio"), track.p(), (track.tpcInnerParam() - track.p()) / track.p()); - mHistManager.fill(HIST("TrackCuts/Deuteron/fEtaDeuteron"), track.eta()); - mHistManager.fill(HIST("TrackCuts/Deuteron/fPhiDeuteron"), track.phi()); - mHistManager.fill(HIST("TrackCuts/Deuteron/fNsigmaTPCvsPDeuteron"), track.tpcInnerParam(), track.tpcNSigmaDe()); - mHistManager.fill(HIST("TrackCuts/Deuteron/fNsigmaTOFvsPDeuteron"), track.tpcInnerParam(), track.tofNSigmaDe()); + + mHistManager.fill(HIST("TrackCuts/Deuteron/fP"), track.p()); + mHistManager.fill(HIST("TrackCuts/Deuteron/fPt"), track.pt()); + mHistManager.fill(HIST("TrackCuts/Deuteron/fMomCorDif"), track.p(), track.tpcInnerParam() - track.p()); + mHistManager.fill(HIST("TrackCuts/Deuteron/fMomCorRatio"), track.p(), (track.tpcInnerParam() - track.p()) / track.p()); + mHistManager.fill(HIST("TrackCuts/Deuteron/fEta"), track.eta()); + mHistManager.fill(HIST("TrackCuts/Deuteron/fPhi"), track.phi()); + + mHistManager.fill(HIST("TrackCuts/Deuteron/fNsigmaTPCvsTPCP"), track.tpcInnerParam(), track.tpcNSigmaDe()); + mHistManager.fill(HIST("TrackCuts/Deuteron/fNsigmaTOFvsTPCP"), track.tpcInnerParam(), track.tofNSigmaDe()); auto nSigmaTrackTPCTOF = std::sqrt(std::pow(track.tpcNSigmaDe(), 2) + std::pow(track.tofNSigmaDe(), 2)); - mHistManager.fill(HIST("TrackCuts/Deuteron/fNsigmaTPCTOFvsPDeuteron"), track.tpcInnerParam(), std::sqrt(std::pow(track.tpcNSigmaDe() - nSigmaTrackTPCTOF, 2) + std::pow(track.tofNSigmaDe() - nSigmaTrackTPCTOF, 2))); - mHistManager.fill(HIST("TrackCuts/Deuteron/fNsigmaITSvsPDeuteron"), track.p(), track.itsNSigmaDe()); - - mHistManager.fill(HIST("TrackCuts/Deuteron/fNsigmaTPCvsPDeuteronP"), track.p(), track.tpcNSigmaDe()); - mHistManager.fill(HIST("TrackCuts/Deuteron/fNsigmaTOFvsPDeuteronP"), track.p(), track.tofNSigmaDe()); - mHistManager.fill(HIST("TrackCuts/Deuteron/fNsigmaTPCTOFvsPDeuteronP"), track.p(), std::sqrt(std::pow(track.tpcNSigmaDe() - nSigmaTrackTPCTOF, 2) + std::pow(track.tofNSigmaDe() - nSigmaTrackTPCTOF, 2))); - - mHistManager.fill(HIST("TrackCuts/Deuteron/fDCAxyDeuteron"), track.dcaXY()); - mHistManager.fill(HIST("TrackCuts/Deuteron/fDCAzDeuteron"), track.dcaZ()); - mHistManager.fill(HIST("TrackCuts/Deuteron/fTPCsClsDeuteron"), track.tpcNClsShared()); - mHistManager.fill(HIST("TrackCuts/Deuteron/fTPCcRowsDeuteron"), track.tpcNClsCrossedRows()); - mHistManager.fill(HIST("TrackCuts/Deuteron/fTrkTPCfClsDeuteron"), track.tpcCrossedRowsOverFindableCls()); - mHistManager.fill(HIST("TrackCuts/Deuteron/fTPCnclsDeuteron"), track.tpcNClsFound()); + mHistManager.fill(HIST("TrackCuts/Deuteron/fNsigmaTPCTOFvsTPCP"), track.tpcInnerParam(), std::sqrt(std::pow(track.tpcNSigmaDe() - nSigmaTrackTPCTOF, 2) + std::pow(track.tofNSigmaDe() - nSigmaTrackTPCTOF, 2))); + mHistManager.fill(HIST("TrackCuts/Deuteron/fNsigmaITSvsP"), track.p(), track.itsNSigmaDe()); + mHistManager.fill(HIST("TrackCuts/Deuteron/fNsigmaTPCvsP"), track.p(), track.tpcNSigmaDe()); + mHistManager.fill(HIST("TrackCuts/Deuteron/fNsigmaTOFvsP"), track.p(), track.tofNSigmaDe()); + mHistManager.fill(HIST("TrackCuts/Deuteron/fNsigmaTPCTOFvsP"), track.p(), std::sqrt(std::pow(track.tpcNSigmaDe() - nSigmaTrackTPCTOF, 2) + std::pow(track.tofNSigmaDe() - nSigmaTrackTPCTOF, 2))); + + mHistManager.fill(HIST("TrackCuts/Deuteron/fDCAxy"), track.dcaXY()); + mHistManager.fill(HIST("TrackCuts/Deuteron/fDCAz"), track.dcaZ()); + mHistManager.fill(HIST("TrackCuts/Deuteron/fTPCsCls"), track.tpcNClsShared()); + mHistManager.fill(HIST("TrackCuts/Deuteron/fTPCcRows"), track.tpcNClsCrossedRows()); + mHistManager.fill(HIST("TrackCuts/Deuteron/fTrkTPCfCls"), track.tpcCrossedRowsOverFindableCls()); + mHistManager.fill(HIST("TrackCuts/Deuteron/fTPCncls"), track.tpcNClsFound()); } if (isPion) { pion.emplace_back(track.pt(), track.eta(), track.phi(), mMassPionCharged); mHistManager.fill(HIST("TrackCuts/TracksBefore/fMomCorrelationAfterCutsPion"), track.p(), track.tpcInnerParam()); - mHistManager.fill(HIST("TrackCuts/TPCSignal/fTPCSignalPion"), track.tpcInnerParam(), track.tpcSignal()); - mHistManager.fill(HIST("TrackCuts/Pion/fPPion"), track.p()); - mHistManager.fill(HIST("TrackCuts/Pion/fPTPCPion"), track.tpcInnerParam()); - mHistManager.fill(HIST("TrackCuts/Pion/fPtPion"), track.pt()); - mHistManager.fill(HIST("TrackCuts/Pion/fMomCorPionDif"), track.p(), track.tpcInnerParam() - track.p()); - mHistManager.fill(HIST("TrackCuts/Pion/fMomCorPionRatio"), track.p(), (track.tpcInnerParam() - track.p()) / track.p()); - mHistManager.fill(HIST("TrackCuts/Pion/fEtaPion"), track.eta()); - mHistManager.fill(HIST("TrackCuts/Pion/fPhiPion"), track.phi()); - mHistManager.fill(HIST("TrackCuts/Pion/fNsigmaTPCvsPPion"), track.tpcInnerParam(), track.tpcNSigmaPi()); - mHistManager.fill(HIST("TrackCuts/Pion/fNsigmaTOFvsPPion"), track.tpcInnerParam(), track.tofNSigmaPi()); + + mHistManager.fill(HIST("TrackCuts/Pion/fP"), track.p()); + mHistManager.fill(HIST("TrackCuts/Pion/fPt"), track.pt()); + mHistManager.fill(HIST("TrackCuts/Pion/fMomCorDif"), track.p(), track.tpcInnerParam() - track.p()); + mHistManager.fill(HIST("TrackCuts/Pion/fMomCorRatio"), track.p(), (track.tpcInnerParam() - track.p()) / track.p()); + mHistManager.fill(HIST("TrackCuts/Pion/fEta"), track.eta()); + mHistManager.fill(HIST("TrackCuts/Pion/fPhi"), track.phi()); + + mHistManager.fill(HIST("TrackCuts/Pion/fNsigmaTPCvsTPCP"), track.tpcInnerParam(), track.tpcNSigmaPi()); + mHistManager.fill(HIST("TrackCuts/Pion/fNsigmaTOFvsTPCP"), track.tpcInnerParam(), track.tofNSigmaPi()); auto nSigmaTrackTPCTOF = std::sqrt(std::pow(track.tpcNSigmaPi(), 2) + std::pow(track.tofNSigmaPi(), 2)); - mHistManager.fill(HIST("TrackCuts/Pion/fNsigmaTPCTOFvsPPion"), track.tpcInnerParam(), std::sqrt(std::pow(track.tpcNSigmaPi() - nSigmaTrackTPCTOF, 2) + std::pow(track.tofNSigmaPi() - nSigmaTrackTPCTOF, 2))); - - mHistManager.fill(HIST("TrackCuts/Pion/fNsigmaTPCvsPPionP"), track.p(), track.tpcNSigmaPi()); - mHistManager.fill(HIST("TrackCuts/Pion/fNsigmaTOFvsPPionP"), track.p(), track.tofNSigmaPi()); - mHistManager.fill(HIST("TrackCuts/Pion/fNsigmaTPCTOFvsPPionP"), track.p(), std::sqrt(std::pow(track.tpcNSigmaPi() - nSigmaTrackTPCTOF, 2) + std::pow(track.tofNSigmaPi() - nSigmaTrackTPCTOF, 2))); - - mHistManager.fill(HIST("TrackCuts/Pion/fDCAxyPion"), track.dcaXY()); - mHistManager.fill(HIST("TrackCuts/Pion/fDCAzPion"), track.dcaZ()); - mHistManager.fill(HIST("TrackCuts/Pion/fTPCsClsPion"), track.tpcNClsShared()); - mHistManager.fill(HIST("TrackCuts/Pion/fTPCcRowsPion"), track.tpcNClsCrossedRows()); - mHistManager.fill(HIST("TrackCuts/Pion/fTrkTPCfClsPion"), track.tpcCrossedRowsOverFindableCls()); - mHistManager.fill(HIST("TrackCuts/Pion/fTPCnclsPion"), track.tpcNClsFound()); + mHistManager.fill(HIST("TrackCuts/Pion/fNsigmaTPCTOFvsTPCP"), track.tpcInnerParam(), std::sqrt(std::pow(track.tpcNSigmaPi() - nSigmaTrackTPCTOF, 2) + std::pow(track.tofNSigmaPi() - nSigmaTrackTPCTOF, 2))); + mHistManager.fill(HIST("TrackCuts/Pion/fNsigmaITSvsP"), track.p(), track.itsNSigmaPi()); + mHistManager.fill(HIST("TrackCuts/Pion/fNsigmaTPCvsP"), track.p(), track.tpcNSigmaPi()); + mHistManager.fill(HIST("TrackCuts/Pion/fNsigmaTOFvsP"), track.p(), track.tofNSigmaPi()); + mHistManager.fill(HIST("TrackCuts/Pion/fNsigmaTPCTOFvsP"), track.p(), std::sqrt(std::pow(track.tpcNSigmaPi() - nSigmaTrackTPCTOF, 2) + std::pow(track.tofNSigmaPi() - nSigmaTrackTPCTOF, 2))); + + mHistManager.fill(HIST("TrackCuts/Pion/fDCAxy"), track.dcaXY()); + mHistManager.fill(HIST("TrackCuts/Pion/fDCAz"), track.dcaZ()); + mHistManager.fill(HIST("TrackCuts/Pion/fTPCsCls"), track.tpcNClsShared()); + mHistManager.fill(HIST("TrackCuts/Pion/fTPCcRows"), track.tpcNClsCrossedRows()); + mHistManager.fill(HIST("TrackCuts/Pion/fTrkTPCfCls"), track.tpcCrossedRowsOverFindableCls()); + mHistManager.fill(HIST("TrackCuts/Pion/fTPCncls"), track.tpcNClsFound()); } - - } else { // antipart + } else { // Negative charge -> Anti-particles if (isProton) { antiproton.emplace_back(track.pt(), track.eta(), track.phi(), mMassProton); mHistManager.fill(HIST("TrackCuts/TracksBefore/fMomCorrelationAfterCutsAntiProton"), track.p(), track.tpcInnerParam()); - mHistManager.fill(HIST("TrackCuts/TPCSignal/fTPCSignalAntiProton"), track.tpcInnerParam(), track.tpcSignal()); - mHistManager.fill(HIST("TrackCuts/AntiProton/fPtAntiProton"), track.pt()); - mHistManager.fill(HIST("TrackCuts/AntiProton/fMomCorAntiProtonDif"), track.p(), track.tpcInnerParam() - track.p()); - mHistManager.fill(HIST("TrackCuts/AntiProton/fMomCorAntiProtonRatio"), track.p(), (track.tpcInnerParam() - track.p()) / track.p()); - mHistManager.fill(HIST("TrackCuts/AntiProton/fEtaAntiProton"), track.eta()); - mHistManager.fill(HIST("TrackCuts/AntiProton/fPhiAntiProton"), track.phi()); - mHistManager.fill(HIST("TrackCuts/AntiProton/fNsigmaTPCvsPAntiProton"), track.tpcInnerParam(), track.tpcNSigmaPr()); - mHistManager.fill(HIST("TrackCuts/AntiProton/fNsigmaTOFvsPAntiProton"), track.tpcInnerParam(), track.tofNSigmaPr()); + + mHistManager.fill(HIST("TrackCuts/AntiProton/fP"), track.p()); + mHistManager.fill(HIST("TrackCuts/AntiProton/fPt"), track.pt()); + mHistManager.fill(HIST("TrackCuts/AntiProton/fMomCorDif"), track.p(), track.tpcInnerParam() - track.p()); + mHistManager.fill(HIST("TrackCuts/AntiProton/fMomCorRatio"), track.p(), (track.tpcInnerParam() - track.p()) / track.p()); + mHistManager.fill(HIST("TrackCuts/AntiProton/fEta"), track.eta()); + mHistManager.fill(HIST("TrackCuts/AntiProton/fPhi"), track.phi()); + + mHistManager.fill(HIST("TrackCuts/AntiProton/fNsigmaTPCvsTPCP"), track.tpcInnerParam(), track.tpcNSigmaPr()); + mHistManager.fill(HIST("TrackCuts/AntiProton/fNsigmaTOFvsTPCP"), track.tpcInnerParam(), track.tofNSigmaPr()); auto nSigmaTrackTPCTOF = std::sqrt(std::pow(track.tpcNSigmaPr(), 2) + std::pow(track.tofNSigmaPr(), 2)); - mHistManager.fill(HIST("TrackCuts/AntiProton/fNsigmaTPCTOFvsPAntiProton"), track.tpcInnerParam(), std::sqrt(std::pow(track.tpcNSigmaPr() - nSigmaTrackTPCTOF, 2) + std::pow(track.tofNSigmaPr() - nSigmaTrackTPCTOF, 2))); - mHistManager.fill(HIST("TrackCuts/AntiProton/fNsigmaITSvsPAntiProton"), track.p(), track.itsNSigmaPr()); - - mHistManager.fill(HIST("TrackCuts/AntiProton/fNsigmaTPCvsPAntiProtonP"), track.p(), track.tpcNSigmaPr()); - mHistManager.fill(HIST("TrackCuts/AntiProton/fNsigmaTOFvsPAntiProtonP"), track.p(), track.tofNSigmaPr()); - mHistManager.fill(HIST("TrackCuts/AntiProton/fNsigmaTPCTOFvsPAntiProtonP"), track.p(), std::sqrt(std::pow(track.tpcNSigmaPr() - nSigmaTrackTPCTOF, 2) + std::pow(track.tofNSigmaPr() - nSigmaTrackTPCTOF, 2))); - - mHistManager.fill(HIST("TrackCuts/AntiProton/fDCAxyAntiProton"), track.dcaXY()); - mHistManager.fill(HIST("TrackCuts/AntiProton/fDCAzAntiProton"), track.dcaZ()); - mHistManager.fill(HIST("TrackCuts/AntiProton/fTPCsClsAntiProton"), track.tpcNClsShared()); - mHistManager.fill(HIST("TrackCuts/AntiProton/fTPCcRowsAntiProton"), track.tpcNClsCrossedRows()); - mHistManager.fill(HIST("TrackCuts/AntiProton/fTrkTPCfClsAntiProton"), track.tpcCrossedRowsOverFindableCls()); - mHistManager.fill(HIST("TrackCuts/AntiProton/fTPCnclsAntiProton"), track.tpcNClsFound()); + mHistManager.fill(HIST("TrackCuts/AntiProton/fNsigmaTPCTOFvsTPCP"), track.tpcInnerParam(), std::sqrt(std::pow(track.tpcNSigmaPr() - nSigmaTrackTPCTOF, 2) + std::pow(track.tofNSigmaPr() - nSigmaTrackTPCTOF, 2))); + mHistManager.fill(HIST("TrackCuts/AntiProton/fNsigmaITSvsP"), track.p(), track.itsNSigmaPr()); + mHistManager.fill(HIST("TrackCuts/AntiProton/fNsigmaTPCvsP"), track.p(), track.tpcNSigmaPr()); + mHistManager.fill(HIST("TrackCuts/AntiProton/fNsigmaTOFvsP"), track.p(), track.tofNSigmaPr()); + mHistManager.fill(HIST("TrackCuts/AntiProton/fNsigmaTPCTOFvsP"), track.p(), std::sqrt(std::pow(track.tpcNSigmaPr() - nSigmaTrackTPCTOF, 2) + std::pow(track.tofNSigmaPr() - nSigmaTrackTPCTOF, 2))); + + mHistManager.fill(HIST("TrackCuts/AntiProton/fDCAxy"), track.dcaXY()); + mHistManager.fill(HIST("TrackCuts/AntiProton/fDCAz"), track.dcaZ()); + mHistManager.fill(HIST("TrackCuts/AntiProton/fTPCsCls"), track.tpcNClsShared()); + mHistManager.fill(HIST("TrackCuts/AntiProton/fTPCcRows"), track.tpcNClsCrossedRows()); + mHistManager.fill(HIST("TrackCuts/AntiProton/fTrkTPCfCls"), track.tpcCrossedRowsOverFindableCls()); + mHistManager.fill(HIST("TrackCuts/AntiProton/fTPCncls"), track.tpcNClsFound()); } if (isDeuteron) { antideuteron.emplace_back(track.pt(), track.eta(), track.phi(), mMassDeuteron); mHistManager.fill(HIST("TrackCuts/TracksBefore/fMomCorrelationAfterCutsAntiDeuteron"), track.p(), track.tpcInnerParam()); - mHistManager.fill(HIST("TrackCuts/TPCSignal/fTPCSignalAntiDeuteron"), track.tpcInnerParam(), track.tpcSignal()); - mHistManager.fill(HIST("TrackCuts/AntiDeuteron/fPtAntiDeuteron"), track.pt()); - mHistManager.fill(HIST("TrackCuts/AntiDeuteron/fMomCorAntiDeuteronDif"), track.p(), track.tpcInnerParam() - track.p()); - mHistManager.fill(HIST("TrackCuts/AntiDeuteron/fMomCorAntiDeuteronRatio"), track.p(), (track.tpcInnerParam() - track.p()) / track.p()); - mHistManager.fill(HIST("TrackCuts/AntiDeuteron/fEtaAntiDeuteron"), track.eta()); - mHistManager.fill(HIST("TrackCuts/AntiDeuteron/fPhiAntiDeuteron"), track.phi()); - mHistManager.fill(HIST("TrackCuts/AntiDeuteron/fNsigmaTPCvsPAntiDeuteron"), track.tpcInnerParam(), track.tpcNSigmaDe()); - mHistManager.fill(HIST("TrackCuts/AntiDeuteron/fNsigmaTOFvsPAntiDeuteron"), track.tpcInnerParam(), track.tofNSigmaDe()); + + mHistManager.fill(HIST("TrackCuts/AntiDeuteron/fP"), track.p()); + mHistManager.fill(HIST("TrackCuts/AntiDeuteron/fPt"), track.pt()); + mHistManager.fill(HIST("TrackCuts/AntiDeuteron/fMomCorDif"), track.p(), track.tpcInnerParam() - track.p()); + mHistManager.fill(HIST("TrackCuts/AntiDeuteron/fMomCorRatio"), track.p(), (track.tpcInnerParam() - track.p()) / track.p()); + mHistManager.fill(HIST("TrackCuts/AntiDeuteron/fEta"), track.eta()); + mHistManager.fill(HIST("TrackCuts/AntiDeuteron/fPhi"), track.phi()); + + mHistManager.fill(HIST("TrackCuts/AntiDeuteron/fNsigmaTPCvsTPCP"), track.tpcInnerParam(), track.tpcNSigmaDe()); + mHistManager.fill(HIST("TrackCuts/AntiDeuteron/fNsigmaTOFvsTPCP"), track.tpcInnerParam(), track.tofNSigmaDe()); auto nSigmaTrackTPCTOF = std::sqrt(std::pow(track.tpcNSigmaDe(), 2) + std::pow(track.tofNSigmaDe(), 2)); - mHistManager.fill(HIST("TrackCuts/AntiDeuteron/fNsigmaTPCTOFvsPAntiDeuteron"), track.tpcInnerParam(), std::sqrt(std::pow(track.tpcNSigmaDe() - nSigmaTrackTPCTOF, 2) + std::pow(track.tofNSigmaDe() - nSigmaTrackTPCTOF, 2))); - mHistManager.fill(HIST("TrackCuts/AntiDeuteron/fNsigmaITSvsPAntiDeuteron"), track.p(), track.itsNSigmaDe()); - - mHistManager.fill(HIST("TrackCuts/AntiDeuteron/fNsigmaTPCvsPAntiDeuteronP"), track.p(), track.tpcNSigmaDe()); - mHistManager.fill(HIST("TrackCuts/AntiDeuteron/fNsigmaTOFvsPAntiDeuteronP"), track.p(), track.tofNSigmaDe()); - mHistManager.fill(HIST("TrackCuts/AntiDeuteron/fNsigmaTPCTOFvsPAntiDeuteronP"), track.p(), std::sqrt(std::pow(track.tpcNSigmaDe() - nSigmaTrackTPCTOF, 2) + std::pow(track.tofNSigmaDe() - nSigmaTrackTPCTOF, 2))); - - mHistManager.fill(HIST("TrackCuts/AntiDeuteron/fDCAxyAntiDeuteron"), track.dcaXY()); - mHistManager.fill(HIST("TrackCuts/AntiDeuteron/fDCAzAntiDeuteron"), track.dcaZ()); - mHistManager.fill(HIST("TrackCuts/AntiDeuteron/fTPCsClsAntiDeuteron"), track.tpcNClsShared()); - mHistManager.fill(HIST("TrackCuts/AntiDeuteron/fTPCcRowsAntiDeuteron"), track.tpcNClsCrossedRows()); - mHistManager.fill(HIST("TrackCuts/AntiDeuteron/fTrkTPCfClsAntiDeuteron"), track.tpcCrossedRowsOverFindableCls()); - mHistManager.fill(HIST("TrackCuts/AntiDeuteron/fTPCnclsAntiDeuteron"), track.tpcNClsFound()); + mHistManager.fill(HIST("TrackCuts/AntiDeuteron/fNsigmaTPCTOFvsTPCP"), track.tpcInnerParam(), std::sqrt(std::pow(track.tpcNSigmaDe() - nSigmaTrackTPCTOF, 2) + std::pow(track.tofNSigmaDe() - nSigmaTrackTPCTOF, 2))); + mHistManager.fill(HIST("TrackCuts/AntiDeuteron/fNsigmaITSvsP"), track.p(), track.itsNSigmaDe()); + mHistManager.fill(HIST("TrackCuts/AntiDeuteron/fNsigmaTPCvsP"), track.p(), track.tpcNSigmaDe()); + mHistManager.fill(HIST("TrackCuts/AntiDeuteron/fNsigmaTOFvsP"), track.p(), track.tofNSigmaDe()); + mHistManager.fill(HIST("TrackCuts/AntiDeuteron/fNsigmaTPCTOFvsP"), track.p(), std::sqrt(std::pow(track.tpcNSigmaDe() - nSigmaTrackTPCTOF, 2) + std::pow(track.tofNSigmaDe() - nSigmaTrackTPCTOF, 2))); + + mHistManager.fill(HIST("TrackCuts/AntiDeuteron/fDCAxy"), track.dcaXY()); + mHistManager.fill(HIST("TrackCuts/AntiDeuteron/fDCAz"), track.dcaZ()); + mHistManager.fill(HIST("TrackCuts/AntiDeuteron/fTPCsCls"), track.tpcNClsShared()); + mHistManager.fill(HIST("TrackCuts/AntiDeuteron/fTPCcRows"), track.tpcNClsCrossedRows()); + mHistManager.fill(HIST("TrackCuts/AntiDeuteron/fTrkTPCfCls"), track.tpcCrossedRowsOverFindableCls()); + mHistManager.fill(HIST("TrackCuts/AntiDeuteron/fTPCncls"), track.tpcNClsFound()); } if (isPion) { antipion.emplace_back(track.pt(), track.eta(), track.phi(), mMassPionCharged); mHistManager.fill(HIST("TrackCuts/TracksBefore/fMomCorrelationAfterCutsAntiPion"), track.p(), track.tpcInnerParam()); - mHistManager.fill(HIST("TrackCuts/TPCSignal/fTPCSignalAntiPion"), track.tpcInnerParam(), track.tpcSignal()); - mHistManager.fill(HIST("TrackCuts/AntiPion/fPtAntiPion"), track.pt()); - mHistManager.fill(HIST("TrackCuts/AntiPion/fMomCorAntiPionDif"), track.p(), track.tpcInnerParam() - track.p()); - mHistManager.fill(HIST("TrackCuts/AntiPion/fMomCorAntiPionRatio"), track.p(), (track.tpcInnerParam() - track.p()) / track.p()); - mHistManager.fill(HIST("TrackCuts/AntiPion/fEtaAntiPion"), track.eta()); - mHistManager.fill(HIST("TrackCuts/AntiPion/fPhiAntiPion"), track.phi()); - mHistManager.fill(HIST("TrackCuts/AntiPion/fNsigmaTPCvsPAntiPion"), track.tpcInnerParam(), track.tpcNSigmaPi()); - mHistManager.fill(HIST("TrackCuts/AntiPion/fNsigmaTOFvsPAntiPion"), track.tpcInnerParam(), track.tofNSigmaPi()); + + mHistManager.fill(HIST("TrackCuts/AntiPion/fP"), track.p()); + mHistManager.fill(HIST("TrackCuts/AntiPion/fPt"), track.pt()); + mHistManager.fill(HIST("TrackCuts/AntiPion/fMomCorDif"), track.p(), track.tpcInnerParam() - track.p()); + mHistManager.fill(HIST("TrackCuts/AntiPion/fMomCorRatio"), track.p(), (track.tpcInnerParam() - track.p()) / track.p()); + mHistManager.fill(HIST("TrackCuts/AntiPion/fEta"), track.eta()); + mHistManager.fill(HIST("TrackCuts/AntiPion/fPhi"), track.phi()); + + mHistManager.fill(HIST("TrackCuts/AntiPion/fNsigmaTPCvsTPCP"), track.tpcInnerParam(), track.tpcNSigmaPi()); + mHistManager.fill(HIST("TrackCuts/AntiPion/fNsigmaTOFvsTPCP"), track.tpcInnerParam(), track.tofNSigmaPi()); auto nSigmaTrackTPCTOF = std::sqrt(std::pow(track.tpcNSigmaPi(), 2) + std::pow(track.tofNSigmaPi(), 2)); - mHistManager.fill(HIST("TrackCuts/AntiPion/fNsigmaTPCTOFvsPAntiPion"), track.tpcInnerParam(), std::sqrt(std::pow(track.tpcNSigmaPi() - nSigmaTrackTPCTOF, 2) + std::pow(track.tofNSigmaPi() - nSigmaTrackTPCTOF, 2))); - - mHistManager.fill(HIST("TrackCuts/AntiPion/fNsigmaTPCvsPAntiPionP"), track.p(), track.tpcNSigmaPi()); - mHistManager.fill(HIST("TrackCuts/AntiPion/fNsigmaTOFvsPAntiPionP"), track.p(), track.tofNSigmaPi()); - mHistManager.fill(HIST("TrackCuts/AntiPion/fNsigmaTPCTOFvsPAntiPionP"), track.p(), std::sqrt(std::pow(track.tpcNSigmaPi() - nSigmaTrackTPCTOF, 2) + std::pow(track.tofNSigmaPi() - nSigmaTrackTPCTOF, 2))); - - mHistManager.fill(HIST("TrackCuts/AntiPion/fDCAxyAntiPion"), track.dcaXY()); - mHistManager.fill(HIST("TrackCuts/AntiPion/fDCAzAntiPion"), track.dcaZ()); - mHistManager.fill(HIST("TrackCuts/AntiPion/fTPCsClsAntiPion"), track.tpcNClsShared()); - mHistManager.fill(HIST("TrackCuts/AntiPion/fTPCcRowsAntiPion"), track.tpcNClsCrossedRows()); - mHistManager.fill(HIST("TrackCuts/AntiPion/fTrkTPCfClsAntiPion"), track.tpcCrossedRowsOverFindableCls()); - mHistManager.fill(HIST("TrackCuts/AntiPion/fTPCnclsAntiPion"), track.tpcNClsFound()); + mHistManager.fill(HIST("TrackCuts/AntiPion/fNsigmaTPCTOFvsTPCP"), track.tpcInnerParam(), std::sqrt(std::pow(track.tpcNSigmaPi() - nSigmaTrackTPCTOF, 2) + std::pow(track.tofNSigmaPi() - nSigmaTrackTPCTOF, 2))); + mHistManager.fill(HIST("TrackCuts/AntiPion/fNsigmaITSvsP"), track.p(), track.itsNSigmaPi()); + mHistManager.fill(HIST("TrackCuts/AntiPion/fNsigmaTPCvsP"), track.p(), track.tpcNSigmaPi()); + mHistManager.fill(HIST("TrackCuts/AntiPion/fNsigmaTOFvsP"), track.p(), track.tofNSigmaPi()); + mHistManager.fill(HIST("TrackCuts/AntiPion/fNsigmaTPCTOFvsP"), track.p(), std::sqrt(std::pow(track.tpcNSigmaPi() - nSigmaTrackTPCTOF, 2) + std::pow(track.tofNSigmaPi() - nSigmaTrackTPCTOF, 2))); + + mHistManager.fill(HIST("TrackCuts/AntiPion/fDCAxy"), track.dcaXY()); + mHistManager.fill(HIST("TrackCuts/AntiPion/fDCAz"), track.dcaZ()); + mHistManager.fill(HIST("TrackCuts/AntiPion/fTPCsCls"), track.tpcNClsShared()); + mHistManager.fill(HIST("TrackCuts/AntiPion/fTPCcRows"), track.tpcNClsCrossedRows()); + mHistManager.fill(HIST("TrackCuts/AntiPion/fTrkTPCfCls"), track.tpcCrossedRowsOverFindableCls()); + mHistManager.fill(HIST("TrackCuts/AntiPion/fTPCncls"), track.tpcNClsFound()); } } } - // reconstruct HMN candidates + // -------------------------> Reconstruct HNM candidates <------------------------------ + // - Based on the previously filled (anti)pion vectors + // - Fill QA histograms for kinematics of the pions and their combinations + // ------------------------------------------------------------------------------------- for (const auto& posPion : pion) { for (const auto& negPion : antipion) { - hnmutilities::reconstructHeavyNeutralMesons(posPion, negPion, vGGs, vHNMs); - - ROOT::Math::PtEtaPhiMVector temp = posPion + negPion; - - mHistManager.fill(HIST("TrackCuts/HMN/Before/fInvMass_tracks"), temp.M()); - mHistManager.fill(HIST("TrackCuts/HMN/Before/fPt_tracks"), temp.pt()); - mHistManager.fill(HIST("TrackCuts/HMN/Before/fEta_tracks"), temp.eta()); - mHistManager.fill(HIST("TrackCuts/HMN/Before/fPhi_tracks"), translatePhi(temp.phi())); - - mHistManager.fill(HIST("TrackCuts/HMN/Before/PosDaughter/fInvMass"), posPion.M()); - mHistManager.fill(HIST("TrackCuts/HMN/Before/PosDaughter/fPt"), posPion.pt()); - mHistManager.fill(HIST("TrackCuts/HMN/Before/PosDaughter/fEta"), posPion.eta()); - mHistManager.fill(HIST("TrackCuts/HMN/Before/PosDaughter/fPhi"), translatePhi(posPion.phi())); - - mHistManager.fill(HIST("TrackCuts/HMN/Before/NegDaughter/fInvMass"), negPion.M()); - mHistManager.fill(HIST("TrackCuts/HMN/Before/NegDaughter/fPt"), negPion.pt()); - mHistManager.fill(HIST("TrackCuts/HMN/Before/NegDaughter/fEta"), negPion.eta()); - mHistManager.fill(HIST("TrackCuts/HMN/Before/NegDaughter/fPhi"), translatePhi(negPion.phi())); + ROOT::Math::PtEtaPhiMVector vecPiPlPiMi = posPion + negPion; + hnmutilities::reconstructHeavyNeutralMesons(vecPiPlPiMi, vGGs, vHNMs); + + mHistManager.fill(HIST("HNM/Before/PiPlPiMi/fInvMassVsPt"), vecPiPlPiMi.M(), vecPiPlPiMi.pt()); + mHistManager.fill(HIST("HNM/Before/PiPlPiMi/fEta"), vecPiPlPiMi.eta()); + mHistManager.fill(HIST("HNM/Before/PiPlPiMi/fPhi"), RecoDecay::constrainAngle(vecPiPlPiMi.phi())); + + mHistManager.fill(HIST("HNM/Before/PosDaughter/fInvMass"), posPion.M()); + mHistManager.fill(HIST("HNM/Before/PosDaughter/fPt"), posPion.pt()); + mHistManager.fill(HIST("HNM/Before/PosDaughter/fEta"), posPion.eta()); + mHistManager.fill(HIST("HNM/Before/PosDaughter/fPhi"), RecoDecay::constrainAngle(posPion.phi())); + + mHistManager.fill(HIST("HNM/Before/NegDaughter/fInvMass"), negPion.M()); + mHistManager.fill(HIST("HNM/Before/NegDaughter/fPt"), negPion.pt()); + mHistManager.fill(HIST("HNM/Before/NegDaughter/fEta"), negPion.eta()); + mHistManager.fill(HIST("HNM/Before/NegDaughter/fPhi"), RecoDecay::constrainAngle(negPion.phi())); } } - processHNMs(vHNMs); // Contains QA of HMN properties - - // build triplets - float Q3 = 999.f, kstar = 999.f; - // omega - if (ConfTriggerSwitches->get("Switch", "PPOmega") > 0.) { - // ppomega trigger - + // ---------------------------> Process HNM candidates <-------------------------------- + // - Fill invMassVsPt histograms separated into HNM types (based on GG mass) and gamma reco method + // - Set colContains* flags for each HNM type to be used in the high-pt spectrum trigger + // - Fill femto HNM vectors (omegaPCM, etaPrimePCM, omegaEMC, etaPrimeEMC) + // ------------------------------------------------------------------------------------- + processHNMs(vHNMs); + + // ------------------------------> Build triplets <------------------------------------- + // - Calculate Q3 for each triplet (p-p-omega, p-p-eta', anti-p-anti-p-omega, anti-p-anti-p-eta') + // - Fill QA histograms for Q3 and pT of the triplet and its daughters + // - Increment lowMomentumMultiplets for each triplet with Q3 < kinematic limit (used in femto trigger) + // ------------------------------------------------------------------------------------- + if (cfgTriggerSwitches->get("Switch", "PPOmega") > 0.) { // -----> p-p-omega femtoscopy for (size_t i = 0; i < proton.size(); ++i) { for (size_t j = i + 1; j < proton.size(); ++j) { - const auto& Proton1 = proton[i]; - const auto& Proton2 = proton[j]; - // PCM - for (const auto& omegaParticles : omegaPCM) { + const auto& proton1 = proton[i]; + const auto& proton2 = proton[j]; + for (const auto& omegaParticles : omegaPCM) { // ---> PCM - Q3 = getQ3(Proton1, Proton2, omegaParticles); + float q3 = getQ3(proton1, proton2, omegaParticles); - mHistManager.fill(HIST("ppomega/fSE_particle_PCM"), Q3); - mHistManager.fill(HIST("ppomega/fProtonPtVsQ3_PCM"), Q3, Proton1.Pt()); - mHistManager.fill(HIST("ppomega/fProtonPtVsQ3_PCM"), Q3, Proton2.Pt()); - mHistManager.fill(HIST("ppomega/fOmegaCandPtVsQ3_PCM"), Q3, omegaParticles.Pt()); + mHistManager.fill(HIST("ppomega/fSE_particle_PCM"), q3); + mHistManager.fill(HIST("ppomega/fProtonPtVsQ3_PCM"), q3, proton1.Pt()); + mHistManager.fill(HIST("ppomega/fProtonPtVsQ3_PCM"), q3, proton2.Pt()); + mHistManager.fill(HIST("ppomega/fomegaCandPtVsQ3_PCM"), q3, omegaParticles.Pt()); + mHistManager.fill(HIST("ppomega/fInvMassVsQ3_PCM"), omegaParticles.M(), q3); - if (Q3 < ConfKinematicLimits->get(static_cast(0), CFTrigger::kPPOmega)) { - lowMomentumMultiplets[CFTrigger::kPPOmega] += 1; - } + if (q3 < cfgKinematicLimits->get(static_cast(0), hnmtrigger::kPPOmega)) + lowMomentumMultiplets[hnmtrigger::kPPOmega] += 1; } - // EMC - for (const auto& omegaParticles : omegaEMC) { + for (const auto& omegaParticles : omegaEMC) { // ---> EMC - Q3 = getQ3(Proton1, Proton2, omegaParticles); + float q3 = getQ3(proton1, proton2, omegaParticles); - mHistManager.fill(HIST("ppomega/fSE_particle_EMC"), Q3); - mHistManager.fill(HIST("ppomega/fProtonPtVsQ3_EMC"), Q3, Proton1.Pt()); - mHistManager.fill(HIST("ppomega/fProtonPtVsQ3_EMC"), Q3, Proton2.Pt()); - mHistManager.fill(HIST("ppomega/fOmegaCandPtVsQ3_EMC"), Q3, omegaParticles.Pt()); + mHistManager.fill(HIST("ppomega/fSE_particle_EMC"), q3); + mHistManager.fill(HIST("ppomega/fProtonPtVsQ3_EMC"), q3, proton1.Pt()); + mHistManager.fill(HIST("ppomega/fProtonPtVsQ3_EMC"), q3, proton2.Pt()); + mHistManager.fill(HIST("ppomega/fomegaCandPtVsQ3_EMC"), q3, omegaParticles.Pt()); + mHistManager.fill(HIST("ppomega/fInvMassVsQ3_EMC"), omegaParticles.M(), q3); - if (Q3 < ConfKinematicLimits->get(static_cast(0), CFTrigger::kPPOmega)) { - lowMomentumMultiplets[CFTrigger::kPPOmega] += 1; - } + if (q3 < cfgKinematicLimits->get(static_cast(0), hnmtrigger::kPPOmega)) + lowMomentumMultiplets[hnmtrigger::kPPOmega] += 1; } } } - // apapomega trigger - // PCM - for (size_t i = 0; i < antiproton.size(); ++i) { + for (size_t i = 0; i < antiproton.size(); ++i) { // -----> antip-antip-omega femtoscopy for (size_t j = i + 1; j < antiproton.size(); ++j) { const auto& antiProton1 = antiproton[i]; const auto& antiProton2 = antiproton[j]; - // PCM - for (const auto& omegaParticles : omegaPCM) { + for (const auto& omegaParticles : omegaPCM) { // ---> PCM - Q3 = getQ3(antiProton1, antiProton2, omegaParticles); + float q3 = getQ3(antiProton1, antiProton2, omegaParticles); - mHistManager.fill(HIST("ppomega/fSE_Antiparticle_PCM"), Q3); - mHistManager.fill(HIST("ppomega/fAntiProtonPtVsQ3_PCM"), Q3, antiProton1.Pt()); - mHistManager.fill(HIST("ppomega/fAntiProtonPtVsQ3_PCM"), Q3, antiProton2.Pt()); - mHistManager.fill(HIST("ppomega/fOmegaCandPtVsQ3_PCM"), Q3, omegaParticles.Pt()); + mHistManager.fill(HIST("ppomega/fSE_Antiparticle_PCM"), q3); + mHistManager.fill(HIST("ppomega/fAntiProtonPtVsQ3_PCM"), q3, antiProton1.Pt()); + mHistManager.fill(HIST("ppomega/fAntiProtonPtVsQ3_PCM"), q3, antiProton2.Pt()); + mHistManager.fill(HIST("ppomega/fomegaCandPtVsQ3_PCM"), q3, omegaParticles.Pt()); + mHistManager.fill(HIST("ppomega/fInvMassVsQ3_PCM"), omegaParticles.M(), q3); - if (Q3 < ConfKinematicLimits->get(static_cast(0), CFTrigger::kPPOmega)) { - lowMomentumMultiplets[CFTrigger::kPPOmega] += 1; - } + if (q3 < cfgKinematicLimits->get(static_cast(0), hnmtrigger::kPPOmega)) + lowMomentumMultiplets[hnmtrigger::kPPOmega] += 1; } - // EMC - for (const auto& omegaParticles : omegaEMC) { + for (const auto& omegaParticles : omegaEMC) { // ---> EMC - Q3 = getQ3(antiProton1, antiProton2, omegaParticles); + float q3 = getQ3(antiProton1, antiProton2, omegaParticles); - mHistManager.fill(HIST("ppomega/fSE_Antiparticle_EMC"), Q3); - mHistManager.fill(HIST("ppomega/fAntiProtonPtVsQ3_EMC"), Q3, antiProton1.Pt()); - mHistManager.fill(HIST("ppomega/fAntiProtonPtVsQ3_EMC"), Q3, antiProton2.Pt()); - mHistManager.fill(HIST("ppomega/fOmegaCandPtVsQ3_EMC"), Q3, omegaParticles.Pt()); + mHistManager.fill(HIST("ppomega/fSE_Antiparticle_EMC"), q3); + mHistManager.fill(HIST("ppomega/fAntiProtonPtVsQ3_EMC"), q3, antiProton1.Pt()); + mHistManager.fill(HIST("ppomega/fAntiProtonPtVsQ3_EMC"), q3, antiProton2.Pt()); + mHistManager.fill(HIST("ppomega/fomegaCandPtVsQ3_EMC"), q3, omegaParticles.Pt()); + mHistManager.fill(HIST("ppomega/fInvMassVsQ3_EMC"), omegaParticles.M(), q3); - if (Q3 < ConfKinematicLimits->get(static_cast(0), CFTrigger::kPPOmega)) { - lowMomentumMultiplets[CFTrigger::kPPOmega] += 1; - } + if (q3 < cfgKinematicLimits->get(static_cast(0), hnmtrigger::kPPOmega)) + lowMomentumMultiplets[hnmtrigger::kPPOmega] += 1; } } } } - - // etaprime - if (ConfTriggerSwitches->get("Switch", "PPEtaPrime") > 0.) { - // ppetaprimetrigger + if (cfgTriggerSwitches->get("Switch", "PPEtaPrime") > 0.) { // -----> p-p-eta' femtoscopy for (size_t i = 0; i < proton.size(); ++i) { for (size_t j = i + 1; j < proton.size(); ++j) { - const auto& Proton1 = proton[i]; - const auto& Proton2 = proton[j]; - // PCM - for (const auto& etaParticles : etaPrimePCM) { + const auto& proton1 = proton[i]; + const auto& proton2 = proton[j]; + for (const auto& etaParticles : etaPrimePCM) { // ---> PCM - Q3 = getQ3(Proton1, Proton2, etaParticles); + float q3 = getQ3(proton1, proton2, etaParticles); - mHistManager.fill(HIST("ppetaprime/fSE_particle_PCM"), Q3); - mHistManager.fill(HIST("ppetaprime/fProtonPtVsQ3_PCM"), Q3, Proton1.Pt()); - mHistManager.fill(HIST("ppetaprime/fProtonPtVsQ3_PCM"), Q3, Proton2.Pt()); - mHistManager.fill(HIST("ppetaprime/fEtaPrimeCandPtVsQ3_PCM"), Q3, etaParticles.Pt()); + mHistManager.fill(HIST("ppetaprime/fSE_particle_PCM"), q3); + mHistManager.fill(HIST("ppetaprime/fProtonPtVsQ3_PCM"), q3, proton1.Pt()); + mHistManager.fill(HIST("ppetaprime/fProtonPtVsQ3_PCM"), q3, proton2.Pt()); + mHistManager.fill(HIST("ppetaprime/fetaprimeCandPtVsQ3_PCM"), q3, etaParticles.Pt()); + mHistManager.fill(HIST("ppetaprime/fInvMassVsQ3_PCM"), etaParticles.M(), q3); - if (Q3 < ConfKinematicLimits->get(static_cast(0), CFTrigger::kPPEtaPrime)) { - lowMomentumMultiplets[CFTrigger::kPPEtaPrime] += 1; - } + if (q3 < cfgKinematicLimits->get(static_cast(0), hnmtrigger::kPPEtaPrime)) + lowMomentumMultiplets[hnmtrigger::kPPEtaPrime] += 1; } - // EMC - for (const auto& etaParticles : etaPrimeEMC) { + for (const auto& etaParticles : etaPrimeEMC) { // ---> EMC - Q3 = getQ3(Proton1, Proton2, etaParticles); + float q3 = getQ3(proton1, proton2, etaParticles); - mHistManager.fill(HIST("ppetaprime/fSE_particle_EMC"), Q3); - mHistManager.fill(HIST("ppetaprime/fProtonPtVsQ3_EMC"), Q3, Proton1.Pt()); - mHistManager.fill(HIST("ppetaprime/fProtonPtVsQ3_EMC"), Q3, Proton2.Pt()); - mHistManager.fill(HIST("ppetaprime/fEtaPrimeCandPtVsQ3_EMC"), Q3, etaParticles.Pt()); + mHistManager.fill(HIST("ppetaprime/fSE_particle_EMC"), q3); + mHistManager.fill(HIST("ppetaprime/fProtonPtVsQ3_EMC"), q3, proton1.Pt()); + mHistManager.fill(HIST("ppetaprime/fProtonPtVsQ3_EMC"), q3, proton2.Pt()); + mHistManager.fill(HIST("ppetaprime/fetaprimeCandPtVsQ3_EMC"), q3, etaParticles.Pt()); + mHistManager.fill(HIST("ppetaprime/fInvMassVsQ3_EMC"), etaParticles.M(), q3); - if (Q3 < ConfKinematicLimits->get(static_cast(0), CFTrigger::kPPEtaPrime)) { - lowMomentumMultiplets[CFTrigger::kPPEtaPrime] += 1; - } + if (q3 < cfgKinematicLimits->get(static_cast(0), hnmtrigger::kPPEtaPrime)) + lowMomentumMultiplets[hnmtrigger::kPPEtaPrime] += 1; } } } - // apapetaprime trigger - for (size_t i = 0; i < antiproton.size(); ++i) { + for (size_t i = 0; i < antiproton.size(); ++i) { // -----> antip-antip-eta' femtoscopy for (size_t j = i + 1; j < antiproton.size(); ++j) { const auto& antiProton1 = antiproton[i]; const auto& antiProton2 = antiproton[j]; - // PCM - for (const auto& etaParticles : etaPrimePCM) { + for (const auto& etaParticles : etaPrimePCM) { // ---> PCM - Q3 = getQ3(antiProton1, antiProton2, etaParticles); + float q3 = getQ3(antiProton1, antiProton2, etaParticles); - mHistManager.fill(HIST("ppetaprime/fSE_Antiparticle_PCM"), Q3); - mHistManager.fill(HIST("ppetaprime/fAntiProtonPtVsQ3_PCM"), Q3, antiProton1.Pt()); - mHistManager.fill(HIST("ppetaprime/fAntiProtonPtVsQ3_PCM"), Q3, antiProton2.Pt()); - mHistManager.fill(HIST("ppetaprime/fEtaPrimeCandPtVsQ3_PCM"), Q3, etaParticles.Pt()); + mHistManager.fill(HIST("ppetaprime/fSE_Antiparticle_PCM"), q3); + mHistManager.fill(HIST("ppetaprime/fAntiProtonPtVsQ3_PCM"), q3, antiProton1.Pt()); + mHistManager.fill(HIST("ppetaprime/fAntiProtonPtVsQ3_PCM"), q3, antiProton2.Pt()); + mHistManager.fill(HIST("ppetaprime/fetaprimeCandPtVsQ3_PCM"), q3, etaParticles.Pt()); + mHistManager.fill(HIST("ppetaprime/fInvMassVsQ3_PCM"), etaParticles.M(), q3); - if (Q3 < ConfKinematicLimits->get(static_cast(0), CFTrigger::kPPEtaPrime)) { - lowMomentumMultiplets[CFTrigger::kPPEtaPrime] += 1; - } + if (q3 < cfgKinematicLimits->get(static_cast(0), hnmtrigger::kPPEtaPrime)) + lowMomentumMultiplets[hnmtrigger::kPPEtaPrime] += 1; } - // EMC - for (const auto& etaParticles : etaPrimeEMC) { + for (const auto& etaParticles : etaPrimeEMC) { // ---> EMC - Q3 = getQ3(antiProton1, antiProton2, etaParticles); + float q3 = getQ3(antiProton1, antiProton2, etaParticles); - mHistManager.fill(HIST("ppetaprime/fSE_Antiparticle_EMC"), Q3); - mHistManager.fill(HIST("ppetaprime/fAntiProtonPtVsQ3_EMC"), Q3, antiProton1.Pt()); - mHistManager.fill(HIST("ppetaprime/fAntiProtonPtVsQ3_EMC"), Q3, antiProton2.Pt()); - mHistManager.fill(HIST("ppetaprime/fEtaPrimeCandPtVsQ3_EMC"), Q3, etaParticles.Pt()); + mHistManager.fill(HIST("ppetaprime/fSE_Antiparticle_EMC"), q3); + mHistManager.fill(HIST("ppetaprime/fAntiProtonPtVsQ3_EMC"), q3, antiProton1.Pt()); + mHistManager.fill(HIST("ppetaprime/fAntiProtonPtVsQ3_EMC"), q3, antiProton2.Pt()); + mHistManager.fill(HIST("ppetaprime/fetaprimeCandPtVsQ3_EMC"), q3, etaParticles.Pt()); + mHistManager.fill(HIST("ppetaprime/fInvMassVsQ3_EMC"), etaParticles.M(), q3); - if (Q3 < ConfKinematicLimits->get(static_cast(0), CFTrigger::kPPEtaPrime)) { - lowMomentumMultiplets[CFTrigger::kPPEtaPrime] += 1; - } + if (q3 < cfgKinematicLimits->get(static_cast(0), hnmtrigger::kPPEtaPrime)) + lowMomentumMultiplets[hnmtrigger::kPPEtaPrime] += 1; } } } } - // build pairs - if (ConfTriggerSwitches->get("Switch", "Omegad") > 0.) { - // PCM - // omegad trigger - for (auto iomega = omegaPCM.begin(); iomega != omegaPCM.end(); ++iomega) { - for (auto iDeuteron = deuteron.begin(); iDeuteron != deuteron.end(); ++iDeuteron) { - kstar = getkstar(*iomega, *iDeuteron); + // --------------------------------> Build Pairs <-------------------------------------- + // - Calculate k* for each pair ((anti)d-omega, (anti)d-eta', (anti)p-omega, (anti)p-eta') + // - Fill QA histograms for k* and pT of the pairs + // - Increment lowMomentumMultiplets for each triplet with k* < kinematic limit (used in femto trigger) + // ------------------------------------------------------------------------------------- + if (cfgTriggerSwitches->get("Switch", "Omegad") > 0.) { + for (auto iomega = omegaPCM.begin(); iomega != omegaPCM.end(); ++iomega) { // -----> PCM + for (auto iDeuteron = deuteron.begin(); iDeuteron != deuteron.end(); ++iDeuteron) { // ---> d-omega femtoscopy + + float kstar = getkstar(*iomega, *iDeuteron); + mHistManager.fill(HIST("omegad/fSE_particle_PCM"), kstar); mHistManager.fill(HIST("omegad/fomegaPtVskstar_PCM"), kstar, (*iomega).Pt()); - mHistManager.fill(HIST("omegad/fDeuteronPtVskstar_PCM"), kstar, (*iDeuteron).Pt()); - if (kstar < ConfKinematicLimits->get(static_cast(0), CFTrigger::kOmegaD)) { - lowMomentumMultiplets[CFTrigger::kOmegaD] += 1; - } + mHistManager.fill(HIST("omegad/fdPtVskstar_PCM"), kstar, (*iDeuteron).Pt()); + mHistManager.fill(HIST("omegad/fInvMassVsKStar_PCM"), (*iomega).M(), kstar); + + if (kstar < cfgKinematicLimits->get(static_cast(0), hnmtrigger::kOmegaD)) + lowMomentumMultiplets[hnmtrigger::kOmegaD] += 1; } - // omegaAd trigger - for (auto iAntiDeuteron = antideuteron.begin(); iAntiDeuteron != antideuteron.end(); ++iAntiDeuteron) { - kstar = getkstar(*iomega, *iAntiDeuteron); + for (auto iAntiDeuteron = antideuteron.begin(); iAntiDeuteron != antideuteron.end(); ++iAntiDeuteron) { // ---> antid-omega femtoscopy + + float kstar = getkstar(*iomega, *iAntiDeuteron); + mHistManager.fill(HIST("omegad/fSE_Antiparticle_PCM"), kstar); mHistManager.fill(HIST("omegad/fomegaPtVskstar_PCM"), kstar, (*iomega).Pt()); - mHistManager.fill(HIST("omegad/fAntiDeuteronPtVskstar_PCM"), kstar, (*iAntiDeuteron).Pt()); - if (kstar < ConfKinematicLimits->get(static_cast(0), CFTrigger::kOmegaD)) { - lowMomentumMultiplets[CFTrigger::kOmegaD] += 1; - } + mHistManager.fill(HIST("omegad/fAntidPtVskstar_PCM"), kstar, (*iAntiDeuteron).Pt()); + mHistManager.fill(HIST("omegad/fInvMassVsKStar_PCM"), (*iomega).M(), kstar); + + if (kstar < cfgKinematicLimits->get(static_cast(0), hnmtrigger::kOmegaD)) + lowMomentumMultiplets[hnmtrigger::kOmegaD] += 1; } } - // EMC - // omegad trigger - for (auto iomega = omegaEMC.begin(); iomega != omegaEMC.end(); ++iomega) { - for (auto iDeuteron = deuteron.begin(); iDeuteron != deuteron.end(); ++iDeuteron) { - kstar = getkstar(*iomega, *iDeuteron); + for (auto iomega = omegaEMC.begin(); iomega != omegaEMC.end(); ++iomega) { // -----> EMC + for (auto iDeuteron = deuteron.begin(); iDeuteron != deuteron.end(); ++iDeuteron) { // ---> d-omega femtoscopy + + float kstar = getkstar(*iomega, *iDeuteron); + mHistManager.fill(HIST("omegad/fSE_particle_EMC"), kstar); mHistManager.fill(HIST("omegad/fomegaPtVskstar_EMC"), kstar, (*iomega).Pt()); - mHistManager.fill(HIST("omegad/fDeuteronPtVskstar_EMC"), kstar, (*iDeuteron).Pt()); - if (kstar < ConfKinematicLimits->get(static_cast(0), CFTrigger::kOmegaD)) { - lowMomentumMultiplets[CFTrigger::kOmegaD] += 1; - } + mHistManager.fill(HIST("omegad/fdPtVskstar_EMC"), kstar, (*iDeuteron).Pt()); + mHistManager.fill(HIST("omegad/fInvMassVsKStar_EMC"), (*iomega).M(), kstar); + + if (kstar < cfgKinematicLimits->get(static_cast(0), hnmtrigger::kOmegaD)) + lowMomentumMultiplets[hnmtrigger::kOmegaD] += 1; } - // omegaAd trigger - for (auto iAntiDeuteron = antideuteron.begin(); iAntiDeuteron != antideuteron.end(); ++iAntiDeuteron) { - kstar = getkstar(*iomega, *iAntiDeuteron); + for (auto iAntiDeuteron = antideuteron.begin(); iAntiDeuteron != antideuteron.end(); ++iAntiDeuteron) { // ---> antid-omega femtoscopy + + float kstar = getkstar(*iomega, *iAntiDeuteron); + mHistManager.fill(HIST("omegad/fSE_Antiparticle_EMC"), kstar); mHistManager.fill(HIST("omegad/fomegaPtVskstar_EMC"), kstar, (*iomega).Pt()); - mHistManager.fill(HIST("omegad/fAntiDeuteronPtVskstar_EMC"), kstar, (*iAntiDeuteron).Pt()); - if (kstar < ConfKinematicLimits->get(static_cast(0), CFTrigger::kOmegaD)) { - lowMomentumMultiplets[CFTrigger::kOmegaD] += 1; - } + mHistManager.fill(HIST("omegad/fAntidPtVskstar_EMC"), kstar, (*iAntiDeuteron).Pt()); + mHistManager.fill(HIST("omegad/fInvMassVsKStar_EMC"), (*iomega).M(), kstar); + + if (kstar < cfgKinematicLimits->get(static_cast(0), hnmtrigger::kOmegaD)) + lowMomentumMultiplets[hnmtrigger::kOmegaD] += 1; } } } - if (ConfTriggerSwitches->get("Switch", "EtaPrimed") > 0.) { - // PCM - // etaPrimed trigger - for (auto ietaprime = etaPrimePCM.begin(); ietaprime != etaPrimePCM.end(); ++ietaprime) { - for (auto iDeuteron = deuteron.begin(); iDeuteron != deuteron.end(); ++iDeuteron) { - kstar = getkstar(*ietaprime, *iDeuteron); + if (cfgTriggerSwitches->get("Switch", "EtaPrimed") > 0.) { + for (auto ietaprime = etaPrimePCM.begin(); ietaprime != etaPrimePCM.end(); ++ietaprime) { // -----> PCM + for (auto iDeuteron = deuteron.begin(); iDeuteron != deuteron.end(); ++iDeuteron) { // ---> d-eta' femtoscopy + + float kstar = getkstar(*ietaprime, *iDeuteron); + mHistManager.fill(HIST("etaprimed/fSE_particle_PCM"), kstar); mHistManager.fill(HIST("etaprimed/fetaprimePtVskstar_PCM"), kstar, (*ietaprime).Pt()); - mHistManager.fill(HIST("etaprimed/fDeuteronPtVskstar_PCM"), kstar, (*iDeuteron).Pt()); - if (kstar < ConfKinematicLimits->get(static_cast(0), CFTrigger::kEtaPrimeD)) { - lowMomentumMultiplets[CFTrigger::kEtaPrimeD] += 1; - } + mHistManager.fill(HIST("etaprimed/fdPtVskstar_PCM"), kstar, (*iDeuteron).Pt()); + mHistManager.fill(HIST("etaprimed/fInvMassVsKStar_PCM"), (*ietaprime).M(), kstar); + + if (kstar < cfgKinematicLimits->get(static_cast(0), hnmtrigger::kEtaPrimeD)) + lowMomentumMultiplets[hnmtrigger::kEtaPrimeD] += 1; } - // etaPrimeAd trigger - for (auto iAntiDeuteron = antideuteron.begin(); iAntiDeuteron != antideuteron.end(); ++iAntiDeuteron) { - kstar = getkstar(*ietaprime, *iAntiDeuteron); + for (auto iAntiDeuteron = antideuteron.begin(); iAntiDeuteron != antideuteron.end(); ++iAntiDeuteron) { // ---> antid-eta' femtoscopy + + float kstar = getkstar(*ietaprime, *iAntiDeuteron); + mHistManager.fill(HIST("etaprimed/fSE_Antiparticle_PCM"), kstar); mHistManager.fill(HIST("etaprimed/fetaprimePtVskstar_PCM"), kstar, (*ietaprime).Pt()); - mHistManager.fill(HIST("etaprimed/fAntiDeuteronPtVskstar_PCM"), kstar, (*iAntiDeuteron).Pt()); - if (kstar < ConfKinematicLimits->get(static_cast(0), CFTrigger::kEtaPrimeD)) { - lowMomentumMultiplets[CFTrigger::kEtaPrimeD] += 1; - } + mHistManager.fill(HIST("etaprimed/fAntidPtVskstar_PCM"), kstar, (*iAntiDeuteron).Pt()); + mHistManager.fill(HIST("etaprimed/fInvMassVsKStar_PCM"), (*ietaprime).M(), kstar); + + if (kstar < cfgKinematicLimits->get(static_cast(0), hnmtrigger::kEtaPrimeD)) + lowMomentumMultiplets[hnmtrigger::kEtaPrimeD] += 1; } } - // EMC - // etaPrimed trigger - for (auto ietaprime = etaPrimeEMC.begin(); ietaprime != etaPrimeEMC.end(); ++ietaprime) { - for (auto iDeuteron = deuteron.begin(); iDeuteron != deuteron.end(); ++iDeuteron) { - kstar = getkstar(*ietaprime, *iDeuteron); + for (auto ietaprime = etaPrimeEMC.begin(); ietaprime != etaPrimeEMC.end(); ++ietaprime) { // -----> EMC + for (auto iDeuteron = deuteron.begin(); iDeuteron != deuteron.end(); ++iDeuteron) { // ---> d-eta' femtoscopy + + float kstar = getkstar(*ietaprime, *iDeuteron); + mHistManager.fill(HIST("etaprimed/fSE_particle_EMC"), kstar); mHistManager.fill(HIST("etaprimed/fetaprimePtVskstar_EMC"), kstar, (*ietaprime).Pt()); - mHistManager.fill(HIST("etaprimed/fDeuteronPtVskstar_EMC"), kstar, (*iDeuteron).Pt()); - if (kstar < ConfKinematicLimits->get(static_cast(0), CFTrigger::kEtaPrimeD)) { - lowMomentumMultiplets[CFTrigger::kEtaPrimeD] += 1; - } + mHistManager.fill(HIST("etaprimed/fdPtVskstar_EMC"), kstar, (*iDeuteron).Pt()); + mHistManager.fill(HIST("etaprimed/fInvMassVsKStar_EMC"), (*ietaprime).M(), kstar); + + if (kstar < cfgKinematicLimits->get(static_cast(0), hnmtrigger::kEtaPrimeD)) + lowMomentumMultiplets[hnmtrigger::kEtaPrimeD] += 1; } - // etaPrimeAd trigger - for (auto iAntiDeuteron = antideuteron.begin(); iAntiDeuteron != antideuteron.end(); ++iAntiDeuteron) { - kstar = getkstar(*ietaprime, *iAntiDeuteron); + for (auto iAntiDeuteron = antideuteron.begin(); iAntiDeuteron != antideuteron.end(); ++iAntiDeuteron) { // ---> antid-eta' femtoscopy + + float kstar = getkstar(*ietaprime, *iAntiDeuteron); + mHistManager.fill(HIST("etaprimed/fSE_Antiparticle_EMC"), kstar); mHistManager.fill(HIST("etaprimed/fetaprimePtVskstar_EMC"), kstar, (*ietaprime).Pt()); - mHistManager.fill(HIST("etaprimed/fAntiDeuteronPtVskstar_EMC"), kstar, (*iAntiDeuteron).Pt()); - if (kstar < ConfKinematicLimits->get(static_cast(0), CFTrigger::kEtaPrimeD)) { - lowMomentumMultiplets[CFTrigger::kEtaPrimeD] += 1; - } + mHistManager.fill(HIST("etaprimed/fAntidPtVskstar_EMC"), kstar, (*iAntiDeuteron).Pt()); + mHistManager.fill(HIST("etaprimed/fInvMassVsKStar_EMC"), (*ietaprime).M(), kstar); + + if (kstar < cfgKinematicLimits->get(static_cast(0), hnmtrigger::kEtaPrimeD)) + lowMomentumMultiplets[hnmtrigger::kEtaPrimeD] += 1; } } } - if (ConfTriggerSwitches->get("Switch", "OmegaP") > 0.) { - // PCM - // omegap trigger - for (auto iomega = omegaPCM.begin(); iomega != omegaPCM.end(); ++iomega) { - for (auto iProton = proton.begin(); iProton != proton.end(); ++iProton) { - kstar = getkstar(*iomega, *iProton); + if (cfgTriggerSwitches->get("Switch", "OmegaP") > 0.) { + for (auto iomega = omegaPCM.begin(); iomega != omegaPCM.end(); ++iomega) { // -----> PCM + for (auto iProton = proton.begin(); iProton != proton.end(); ++iProton) { // ---> p-omega femtoscopy + + float kstar = getkstar(*iomega, *iProton); + mHistManager.fill(HIST("omegap/fSE_particle_PCM"), kstar); mHistManager.fill(HIST("omegap/fomegaPtVskstar_PCM"), kstar, (*iomega).Pt()); - mHistManager.fill(HIST("omegap/fProtonPtVskstar_PCM"), kstar, (*iProton).Pt()); - if (kstar < ConfKinematicLimits->get(static_cast(0), CFTrigger::kOmegaP)) { - lowMomentumMultiplets[CFTrigger::kOmegaP] += 1; - } + mHistManager.fill(HIST("omegap/fpPtVskstar_PCM"), kstar, (*iProton).Pt()); + mHistManager.fill(HIST("omegap/fInvMassVsKStar_PCM"), (*iomega).M(), kstar); + + if (kstar < cfgKinematicLimits->get(static_cast(0), hnmtrigger::kOmegaP)) + lowMomentumMultiplets[hnmtrigger::kOmegaP] += 1; } - // omegaAp trigger - for (auto iAntiProton = antiproton.begin(); iAntiProton != antiproton.end(); ++iAntiProton) { - kstar = getkstar(*iomega, *iAntiProton); + for (auto iAntiProton = antiproton.begin(); iAntiProton != antiproton.end(); ++iAntiProton) { // ---> antip-omega femtoscopy + + float kstar = getkstar(*iomega, *iAntiProton); + mHistManager.fill(HIST("omegap/fSE_Antiparticle_PCM"), kstar); mHistManager.fill(HIST("omegap/fomegaPtVskstar_PCM"), kstar, (*iomega).Pt()); - mHistManager.fill(HIST("omegap/fAntiProtonPtVskstar_PCM"), kstar, (*iAntiProton).Pt()); - if (kstar < ConfKinematicLimits->get(static_cast(0), CFTrigger::kOmegaP)) { - lowMomentumMultiplets[CFTrigger::kOmegaP] += 1; - } + mHistManager.fill(HIST("omegap/fAntipPtVskstar_PCM"), kstar, (*iAntiProton).Pt()); + mHistManager.fill(HIST("omegap/fInvMassVsKStar_PCM"), (*iomega).M(), kstar); + + if (kstar < cfgKinematicLimits->get(static_cast(0), hnmtrigger::kOmegaP)) + lowMomentumMultiplets[hnmtrigger::kOmegaP] += 1; } } - // EMC - // omegap trigger - for (auto iomega = omegaEMC.begin(); iomega != omegaEMC.end(); ++iomega) { - for (auto iProton = proton.begin(); iProton != proton.end(); ++iProton) { - kstar = getkstar(*iomega, *iProton); + for (auto iomega = omegaEMC.begin(); iomega != omegaEMC.end(); ++iomega) { // -----> EMC + for (auto iProton = proton.begin(); iProton != proton.end(); ++iProton) { // ---> p-omega femtoscopy + + float kstar = getkstar(*iomega, *iProton); + mHistManager.fill(HIST("omegap/fSE_particle_EMC"), kstar); mHistManager.fill(HIST("omegap/fomegaPtVskstar_EMC"), kstar, (*iomega).Pt()); - mHistManager.fill(HIST("omegap/fProtonPtVskstar_EMC"), kstar, (*iProton).Pt()); - if (kstar < ConfKinematicLimits->get(static_cast(0), CFTrigger::kOmegaP)) { - lowMomentumMultiplets[CFTrigger::kOmegaP] += 1; - } + mHistManager.fill(HIST("omegap/fpPtVskstar_EMC"), kstar, (*iProton).Pt()); + mHistManager.fill(HIST("omegap/fInvMassVsKStar_EMC"), (*iomega).M(), kstar); + + if (kstar < cfgKinematicLimits->get(static_cast(0), hnmtrigger::kOmegaP)) + lowMomentumMultiplets[hnmtrigger::kOmegaP] += 1; } - // omegaAp trigger - for (auto iAntiProton = antiproton.begin(); iAntiProton != antiproton.end(); ++iAntiProton) { - kstar = getkstar(*iomega, *iAntiProton); + for (auto iAntiProton = antiproton.begin(); iAntiProton != antiproton.end(); ++iAntiProton) { // ---> antip-omega femtoscopy + + float kstar = getkstar(*iomega, *iAntiProton); + mHistManager.fill(HIST("omegap/fSE_Antiparticle_EMC"), kstar); mHistManager.fill(HIST("omegap/fomegaPtVskstar_EMC"), kstar, (*iomega).Pt()); - mHistManager.fill(HIST("omegap/fAntiProtonPtVskstar_EMC"), kstar, (*iAntiProton).Pt()); - if (kstar < ConfKinematicLimits->get(static_cast(0), CFTrigger::kOmegaP)) { - lowMomentumMultiplets[CFTrigger::kOmegaP] += 1; - } + mHistManager.fill(HIST("omegap/fAntipPtVskstar_EMC"), kstar, (*iAntiProton).Pt()); + mHistManager.fill(HIST("omegap/fInvMassVsKStar_EMC"), (*iomega).M(), kstar); + + if (kstar < cfgKinematicLimits->get(static_cast(0), hnmtrigger::kOmegaP)) + lowMomentumMultiplets[hnmtrigger::kOmegaP] += 1; } } } - if (ConfTriggerSwitches->get("Switch", "EtaPrimeP") > 0.) { - // PCM - // etaPrimep trigger - for (auto ietaprime = etaPrimePCM.begin(); ietaprime != etaPrimePCM.end(); ++ietaprime) { - for (auto iProton = proton.begin(); iProton != proton.end(); ++iProton) { - kstar = getkstar(*ietaprime, *iProton); + if (cfgTriggerSwitches->get("Switch", "EtaPrimeP") > 0.) { + for (auto ietaprime = etaPrimePCM.begin(); ietaprime != etaPrimePCM.end(); ++ietaprime) { // -----> PCM + for (auto iProton = proton.begin(); iProton != proton.end(); ++iProton) { // ---> p-eta' femtoscopy + + float kstar = getkstar(*ietaprime, *iProton); + mHistManager.fill(HIST("etaprimep/fSE_particle_PCM"), kstar); mHistManager.fill(HIST("etaprimep/fetaprimePtVskstar_PCM"), kstar, (*ietaprime).Pt()); - mHistManager.fill(HIST("etaprimep/fProtonPtVskstar_PCM"), kstar, (*iProton).Pt()); - if (kstar < ConfKinematicLimits->get(static_cast(0), CFTrigger::kEtaPrimeP)) { - lowMomentumMultiplets[CFTrigger::kEtaPrimeP] += 1; - } + mHistManager.fill(HIST("etaprimep/fpPtVskstar_PCM"), kstar, (*iProton).Pt()); + mHistManager.fill(HIST("etaprimep/fInvMassVsKStar_PCM"), (*ietaprime).M(), kstar); + + if (kstar < cfgKinematicLimits->get(static_cast(0), hnmtrigger::kEtaPrimeP)) + lowMomentumMultiplets[hnmtrigger::kEtaPrimeP] += 1; } - // etaPrimeAp trigger - for (auto iAntiProton = antiproton.begin(); iAntiProton != antiproton.end(); ++iAntiProton) { - kstar = getkstar(*ietaprime, *iAntiProton); + for (auto iAntiProton = antiproton.begin(); iAntiProton != antiproton.end(); ++iAntiProton) { // ---> antip-eta' femtoscopy + + float kstar = getkstar(*ietaprime, *iAntiProton); + mHistManager.fill(HIST("etaprimep/fSE_Antiparticle_PCM"), kstar); mHistManager.fill(HIST("etaprimep/fetaprimePtVskstar_PCM"), kstar, (*ietaprime).Pt()); - mHistManager.fill(HIST("etaprimep/fAntiProtonPtVskstar_PCM"), kstar, (*iAntiProton).Pt()); - if (kstar < ConfKinematicLimits->get(static_cast(0), CFTrigger::kEtaPrimeP)) { - lowMomentumMultiplets[CFTrigger::kEtaPrimeP] += 1; - } + mHistManager.fill(HIST("etaprimep/fAntipPtVskstar_PCM"), kstar, (*iAntiProton).Pt()); + mHistManager.fill(HIST("etaprimep/fInvMassVsKStar_PCM"), (*ietaprime).M(), kstar); + + if (kstar < cfgKinematicLimits->get(static_cast(0), hnmtrigger::kEtaPrimeP)) + lowMomentumMultiplets[hnmtrigger::kEtaPrimeP] += 1; } } - // EMC - // etaPrimep trigger - for (auto ietaprime = etaPrimeEMC.begin(); ietaprime != etaPrimeEMC.end(); ++ietaprime) { - for (auto iProton = proton.begin(); iProton != proton.end(); ++iProton) { - kstar = getkstar(*ietaprime, *iProton); + for (auto ietaprime = etaPrimeEMC.begin(); ietaprime != etaPrimeEMC.end(); ++ietaprime) { // -----> EMC + for (auto iProton = proton.begin(); iProton != proton.end(); ++iProton) { // ---> p-eta' femtoscopy + + float kstar = getkstar(*ietaprime, *iProton); + mHistManager.fill(HIST("etaprimep/fSE_particle_EMC"), kstar); mHistManager.fill(HIST("etaprimep/fetaprimePtVskstar_EMC"), kstar, (*ietaprime).Pt()); - mHistManager.fill(HIST("etaprimep/fProtonPtVskstar_EMC"), kstar, (*iProton).Pt()); - if (kstar < ConfKinematicLimits->get(static_cast(0), CFTrigger::kEtaPrimeP)) { - lowMomentumMultiplets[CFTrigger::kEtaPrimeP] += 1; - } + mHistManager.fill(HIST("etaprimep/fpPtVskstar_EMC"), kstar, (*iProton).Pt()); + mHistManager.fill(HIST("etaprimep/fInvMassVsKStar_EMC"), (*ietaprime).M(), kstar); + + if (kstar < cfgKinematicLimits->get(static_cast(0), hnmtrigger::kEtaPrimeP)) + lowMomentumMultiplets[hnmtrigger::kEtaPrimeP] += 1; } - // etaPrimeAp trigger - for (auto iAntiProton = antiproton.begin(); iAntiProton != antiproton.end(); ++iAntiProton) { - kstar = getkstar(*ietaprime, *iAntiProton); + for (auto iAntiProton = antiproton.begin(); iAntiProton != antiproton.end(); ++iAntiProton) { // ---> antip-eta' femtoscopy + + float kstar = getkstar(*ietaprime, *iAntiProton); + mHistManager.fill(HIST("etaprimep/fSE_Antiparticle_EMC"), kstar); mHistManager.fill(HIST("etaprimep/fetaprimePtVskstar_EMC"), kstar, (*ietaprime).Pt()); - mHistManager.fill(HIST("etaprimep/fAntiProtonPtVskstar_EMC"), kstar, (*iAntiProton).Pt()); - if (kstar < ConfKinematicLimits->get(static_cast(0), CFTrigger::kEtaPrimeP)) { - lowMomentumMultiplets[CFTrigger::kEtaPrimeP] += 1; - } + mHistManager.fill(HIST("etaprimep/fAntipPtVskstar_EMC"), kstar, (*iAntiProton).Pt()); + mHistManager.fill(HIST("etaprimep/fInvMassVsKStar_EMC"), (*ietaprime).M(), kstar); + + if (kstar < cfgKinematicLimits->get(static_cast(0), hnmtrigger::kEtaPrimeP)) + lowMomentumMultiplets[hnmtrigger::kEtaPrimeP] += 1; } } } - // create tags for three body triggers - if (lowMomentumMultiplets[CFTrigger::kPPOmega] > 0) { - keepFemtoEvent[CFTrigger::kPPOmega] = true; - mHistManager.fill(HIST("fProcessedEvents"), 2); + // -----------------------------> Create femto tags <----------------------------------- + // - Set keepFemtoEvent flags for each HNM type based on the lowMomentumMultiplets + // - Fill histograms for the multiplicity and z-vertex of femto-accepted events + // ------------------------------------------------------------------------------------- + if (lowMomentumMultiplets[hnmtrigger::kPPOmega] > 0) { + keepFemtoEvent[hnmtrigger::kPPOmega] = true; + mHistManager.fill(HIST("fProcessedEvents"), 6); mHistManager.fill(HIST("ppomega/fMultiplicity"), collision.multNTracksPV()); mHistManager.fill(HIST("ppomega/fZvtx"), collision.posZ()); } - if (lowMomentumMultiplets[CFTrigger::kPPEtaPrime] > 0) { - keepFemtoEvent[CFTrigger::kPPEtaPrime] = true; - mHistManager.fill(HIST("fProcessedEvents"), 3); + if (lowMomentumMultiplets[hnmtrigger::kPPEtaPrime] > 0) { + keepFemtoEvent[hnmtrigger::kPPEtaPrime] = true; + mHistManager.fill(HIST("fProcessedEvents"), 7); mHistManager.fill(HIST("ppetaprime/fMultiplicity"), collision.multNTracksPV()); mHistManager.fill(HIST("ppetaprime/fZvtx"), collision.posZ()); } - if (lowMomentumMultiplets[CFTrigger::kOmegaD] > 0) { - keepFemtoEvent[CFTrigger::kOmegaD] = true; - mHistManager.fill(HIST("fProcessedEvents"), 4); + if (lowMomentumMultiplets[hnmtrigger::kOmegaD] > 0) { + keepFemtoEvent[hnmtrigger::kOmegaD] = true; + mHistManager.fill(HIST("fProcessedEvents"), 8); mHistManager.fill(HIST("omegad/fMultiplicity"), collision.multNTracksPV()); mHistManager.fill(HIST("omegad/fZvtx"), collision.posZ()); } - if (lowMomentumMultiplets[CFTrigger::kEtaPrimeD] > 0) { - keepFemtoEvent[CFTrigger::kEtaPrimeD] = true; - mHistManager.fill(HIST("fProcessedEvents"), 5); + if (lowMomentumMultiplets[hnmtrigger::kEtaPrimeD] > 0) { + keepFemtoEvent[hnmtrigger::kEtaPrimeD] = true; + mHistManager.fill(HIST("fProcessedEvents"), 9); mHistManager.fill(HIST("etaprimed/fMultiplicity"), collision.multNTracksPV()); mHistManager.fill(HIST("etaprimed/fZvtx"), collision.posZ()); } - if (lowMomentumMultiplets[CFTrigger::kOmegaP] > 0) { - keepFemtoEvent[CFTrigger::kOmegaP] = true; - mHistManager.fill(HIST("fProcessedEvents"), 6); + if (lowMomentumMultiplets[hnmtrigger::kOmegaP] > 0) { + keepFemtoEvent[hnmtrigger::kOmegaP] = true; + mHistManager.fill(HIST("fProcessedEvents"), 10); mHistManager.fill(HIST("omegap/fMultiplicity"), collision.multNTracksPV()); mHistManager.fill(HIST("omegap/fZvtx"), collision.posZ()); } - if (lowMomentumMultiplets[CFTrigger::kEtaPrimeP] > 0) { - keepFemtoEvent[CFTrigger::kEtaPrimeP] = true; - mHistManager.fill(HIST("fProcessedEvents"), 7); + if (lowMomentumMultiplets[hnmtrigger::kEtaPrimeP] > 0) { + keepFemtoEvent[hnmtrigger::kEtaPrimeP] = true; + mHistManager.fill(HIST("fProcessedEvents"), 11); mHistManager.fill(HIST("etaprimep/fMultiplicity"), collision.multNTracksPV()); mHistManager.fill(HIST("etaprimep/fZvtx"), collision.posZ()); } - // #set flag for tag - if (ConfKeepTwoBody.value) { - tags(colContainsPCMOmega, colContainsEMCOmega, colContainsPCMEtaPrime, colContainsEMCEtaPrime, - keepFemtoEvent[CFTrigger::kPPOmega] || keepFemtoEvent[CFTrigger::kOmegaP], keepFemtoEvent[CFTrigger::kPPEtaPrime] || keepFemtoEvent[CFTrigger::kEtaPrimeP], - keepFemtoEvent[CFTrigger::kOmegaD], keepFemtoEvent[CFTrigger::kEtaPrimeD]); - } else { - tags(colContainsPCMOmega, colContainsEMCOmega, colContainsPCMEtaPrime, colContainsEMCEtaPrime, - keepFemtoEvent[CFTrigger::kPPOmega], keepFemtoEvent[CFTrigger::kPPEtaPrime], - keepFemtoEvent[CFTrigger::kOmegaD], keepFemtoEvent[CFTrigger::kEtaPrimeD]); - } + // -----------------------------> Set trigger flags <----------------------------------- + // - 4 high pT spectrum trigger flags (PCM & EMC * omega & eta') + // - 4 femto trigger flags (p-omega, p-eta', d-omega || pp-omega, d-eta' || pp-eta') + // ------------------------------------------------------------------------------------- + tags(keepFemtoEvent[hnmtrigger::kOmegaP], keepFemtoEvent[hnmtrigger::kPPOmega], keepFemtoEvent[hnmtrigger::kOmegaD], keepFemtoEvent[hnmtrigger::kEtaPrimeP], keepFemtoEvent[hnmtrigger::kPPEtaPrime], keepFemtoEvent[hnmtrigger::kEtaPrimeD]); + // tags(colContainsPCMOmega, colContainsEMCOmega, colContainsPCMEtaPrime, colContainsEMCEtaPrime, keepFemtoEvent[hnmtrigger::kOmegaP], keepFemtoEvent[hnmtrigger::kEtaPrimeP], + // keepFemtoEvent[hnmtrigger::kPPOmega] || keepFemtoEvent[hnmtrigger::kOmegaD], keepFemtoEvent[hnmtrigger::kPPEtaPrime] || keepFemtoEvent[hnmtrigger::kEtaPrimeD]); - if (!keepFemtoEvent[CFTrigger::kPPOmega] && !keepFemtoEvent[CFTrigger::kOmegaP] && !keepFemtoEvent[CFTrigger::kPPEtaPrime] && !keepFemtoEvent[CFTrigger::kEtaPrimeP] && - !keepFemtoEvent[CFTrigger::kOmegaD] && !keepFemtoEvent[CFTrigger::kEtaPrimeD]) { - mHistManager.fill(HIST("fProcessedEvents"), 1); - } + if (!keepFemtoEvent[hnmtrigger::kPPOmega] && !keepFemtoEvent[hnmtrigger::kOmegaP] && !keepFemtoEvent[hnmtrigger::kPPEtaPrime] && !keepFemtoEvent[hnmtrigger::kEtaPrimeP] && !keepFemtoEvent[hnmtrigger::kOmegaD] && !keepFemtoEvent[hnmtrigger::kEtaPrimeD]) + mHistManager.fill(HIST("fProcessedEvents"), 1); // Fill "rejected", if no trigger selected the event } /// \brief Loop over the GG candidates, fill the mass/pt histograms and set the isPi0/isEta flags based on the reconstructed mass @@ -1481,9 +1171,9 @@ struct HeavyNeutralMesonFilter { mHistManager.fill(HIST("GG/invMassVsPt_PCMEMC"), lightMeson->m(), lightMeson->pT()); } - if (lightMeson->m() > massWindowOmega->get("pi0_min") && lightMeson->m() < massWindowOmega->get("pi0_max")) { + if (lightMeson->m() > cfgMassWindowOmega->get("pi0_min") && lightMeson->m() < cfgMassWindowOmega->get("pi0_max")) { lightMeson->isPi0 = true; - } else if (lightMeson->m() > massWindowEtaPrime->get("eta_min") && lightMeson->m() < massWindowEtaPrime->get("eta_max")) { + } else if (lightMeson->m() > cfgMassWindowEtaPrime->get("eta_min") && lightMeson->m() < cfgMassWindowEtaPrime->get("eta_max")) { lightMeson->isEta = true; } else { vGGs.erase(vGGs.begin() + iGG); @@ -1497,93 +1187,82 @@ struct HeavyNeutralMesonFilter { void processHNMs(std::vector& vHNMs) { int nHNMsBeforeMassCuts = vHNMs.size(); + for (unsigned int iHNM = 0; iHNM < vHNMs.size(); iHNM++) { auto heavyNeutralMeson = vHNMs.at(iHNM); - float massHNM = heavyNeutralMeson.m(cfgHNMMassCorrection); + if (heavyNeutralMeson.gg->reconstructionType == photonpair::kPCMPCM) { - if (heavyNeutralMeson.gg->isPi0) - mHistManager.fill(HIST("Omega/invMassVsPt_PCM"), massHNM, heavyNeutralMeson.pT()); - else if (heavyNeutralMeson.gg->isEta) - mHistManager.fill(HIST("EtaPrime/invMassVsPt_PCM"), massHNM, heavyNeutralMeson.pT()); - // QA - mHistManager.fill(HIST("TrackCuts/HMN/Before/PCM/fInvMass"), massHNM); - mHistManager.fill(HIST("TrackCuts/HMN/Before/PCM/fPt"), heavyNeutralMeson.pT()); - mHistManager.fill(HIST("TrackCuts/HMN/Before/PCM/fEta"), heavyNeutralMeson.eta()); - mHistManager.fill(HIST("TrackCuts/HMN/Before/PCM/fPhi"), translatePhi(heavyNeutralMeson.phi())); + if (heavyNeutralMeson.gg->isPi0) { + mHistManager.fill(HIST("HNM/Before/Omega/PCM/fInvMassVsPt"), massHNM, heavyNeutralMeson.pT()); + mHistManager.fill(HIST("HNM/Before/Omega/PCM/fEta"), heavyNeutralMeson.eta()); + mHistManager.fill(HIST("HNM/Before/Omega/PCM/fPhi"), RecoDecay::constrainAngle(heavyNeutralMeson.phi())); + } else if (heavyNeutralMeson.gg->isEta) { + mHistManager.fill(HIST("HNM/Before/EtaPrime/PCM/fInvMassVsPt"), massHNM, heavyNeutralMeson.pT()); + mHistManager.fill(HIST("HNM/Before/EtaPrime/PCM/fEta"), heavyNeutralMeson.eta()); + mHistManager.fill(HIST("HNM/Before/EtaPrime/PCM/fPhi"), RecoDecay::constrainAngle(heavyNeutralMeson.phi())); + } } else if (heavyNeutralMeson.gg->reconstructionType == photonpair::kEMCEMC) { - if (heavyNeutralMeson.gg->isPi0) - mHistManager.fill(HIST("Omega/invMassVsPt_EMC"), massHNM, heavyNeutralMeson.pT()); - else if (heavyNeutralMeson.gg->isEta) - mHistManager.fill(HIST("EtaPrime/invMassVsPt_EMC"), massHNM, heavyNeutralMeson.pT()); - // QA - mHistManager.fill(HIST("TrackCuts/HMN/Before/EMC/fInvMass"), massHNM); - mHistManager.fill(HIST("TrackCuts/HMN/Before/EMC/fPt"), heavyNeutralMeson.pT()); - mHistManager.fill(HIST("TrackCuts/HMN/Before/EMC/fEta"), heavyNeutralMeson.eta()); - mHistManager.fill(HIST("TrackCuts/HMN/Before/EMC/fPhi"), translatePhi(heavyNeutralMeson.phi())); + if (heavyNeutralMeson.gg->isPi0) { + mHistManager.fill(HIST("HNM/Before/Omega/EMC/fInvMassVsPt"), massHNM, heavyNeutralMeson.pT()); + mHistManager.fill(HIST("HNM/Before/Omega/EMC/fEta"), heavyNeutralMeson.eta()); + mHistManager.fill(HIST("HNM/Before/Omega/EMC/fPhi"), RecoDecay::constrainAngle(heavyNeutralMeson.phi())); + } else if (heavyNeutralMeson.gg->isEta) { + mHistManager.fill(HIST("HNM/Before/EtaPrime/EMC/fInvMassVsPt"), massHNM, heavyNeutralMeson.pT()); + mHistManager.fill(HIST("HNM/Before/EtaPrime/EMC/fEta"), heavyNeutralMeson.eta()); + mHistManager.fill(HIST("HNM/Before/EtaPrime/EMC/fPhi"), RecoDecay::constrainAngle(heavyNeutralMeson.phi())); + } } else { - if (heavyNeutralMeson.gg->isPi0) - mHistManager.fill(HIST("Omega/invMassVsPt_PCMEMC"), massHNM, heavyNeutralMeson.pT()); - else if (heavyNeutralMeson.gg->isEta) - mHistManager.fill(HIST("EtaPrime/invMassVsPt_PCMEMC"), massHNM, heavyNeutralMeson.pT()); - // QA - mHistManager.fill(HIST("TrackCuts/HMN/Before/PCMEMC/fInvMass"), massHNM); - mHistManager.fill(HIST("TrackCuts/HMN/Before/PCMEMC/fPt"), heavyNeutralMeson.pT()); - mHistManager.fill(HIST("TrackCuts/HMN/Before/PCMEMC/fEta"), heavyNeutralMeson.eta()); - mHistManager.fill(HIST("TrackCuts/HMN/Before/PCMEMC/fPhi"), translatePhi(heavyNeutralMeson.phi())); + if (heavyNeutralMeson.gg->isPi0) { + mHistManager.fill(HIST("HNM/Before/Omega/PCMEMC/fInvMassVsPt"), massHNM, heavyNeutralMeson.pT()); + mHistManager.fill(HIST("HNM/Before/Omega/PCMEMC/fEta"), heavyNeutralMeson.eta()); + mHistManager.fill(HIST("HNM/Before/Omega/PCMEMC/fPhi"), RecoDecay::constrainAngle(heavyNeutralMeson.phi())); + } else if (heavyNeutralMeson.gg->isEta) { + mHistManager.fill(HIST("HNM/Before/EtaPrime/PCMEMC/fInvMassVsPt"), massHNM, heavyNeutralMeson.pT()); + mHistManager.fill(HIST("HNM/Before/EtaPrime/PCMEMC/fEta"), heavyNeutralMeson.eta()); + mHistManager.fill(HIST("HNM/Before/EtaPrime/PCMEMC/fPhi"), RecoDecay::constrainAngle(heavyNeutralMeson.phi())); + } } - if (heavyNeutralMeson.gg->isPi0 && massHNM > massWindowOmega->get("omega_min") && massHNM < massWindowOmega->get("omega_max")) { + if (heavyNeutralMeson.gg->isPi0 && massHNM > cfgMassWindowOmega->get("omega_min") && massHNM < cfgMassWindowOmega->get("omega_max")) { if (heavyNeutralMeson.gg->reconstructionType == photonpair::kPCMPCM) { - if (heavyNeutralMeson.pT() > minFemtoHNMPts->get("PCM_omega")) { - omegaPCM.emplace_back(heavyNeutralMeson.pT(), heavyNeutralMeson.eta(), translatePhi(heavyNeutralMeson.phi()), mMassOmega); - // QA - mHistManager.fill(HIST("TrackCuts/HMN/After/Omega/PCM/fInvMass"), massHNM); - mHistManager.fill(HIST("TrackCuts/HMN/After/Omega/PCM/fPt"), heavyNeutralMeson.pT()); - mHistManager.fill(HIST("TrackCuts/HMN/After/Omega/PCM/fEta"), heavyNeutralMeson.eta()); - mHistManager.fill(HIST("TrackCuts/HMN/After/Omega/PCM/fPhi"), translatePhi(heavyNeutralMeson.phi())); + if (heavyNeutralMeson.pT() > cfgMinHNMPtsFemtoTrigger->get("PCM_omega")) { + omegaPCM.emplace_back(heavyNeutralMeson.pT(), heavyNeutralMeson.eta(), RecoDecay::constrainAngle(heavyNeutralMeson.phi()), massHNM); + mHistManager.fill(HIST("HNM/After/Omega/PCM/fInvMassVsPt"), massHNM, heavyNeutralMeson.pT()); + mHistManager.fill(HIST("HNM/After/Omega/PCM/fEta"), heavyNeutralMeson.eta()); + mHistManager.fill(HIST("HNM/After/Omega/PCM/fPhi"), RecoDecay::constrainAngle(heavyNeutralMeson.phi())); } - if (heavyNeutralMeson.pT() > minHNMPts->get("PCM_omega")) { + if (heavyNeutralMeson.pT() > cfgMinHNMPtsSpectrumTrigger->get("PCM_omega")) colContainsPCMOmega = true; - } } else if (heavyNeutralMeson.gg->reconstructionType == photonpair::kEMCEMC) { - if (heavyNeutralMeson.pT() > minFemtoHNMPts->get("EMC_omega")) { - omegaEMC.emplace_back(heavyNeutralMeson.pT(), heavyNeutralMeson.eta(), translatePhi(heavyNeutralMeson.phi()), mMassOmega); - // QA - mHistManager.fill(HIST("TrackCuts/HMN/After/Omega/EMC/fInvMass"), massHNM); - mHistManager.fill(HIST("TrackCuts/HMN/After/Omega/EMC/fPt"), heavyNeutralMeson.pT()); - mHistManager.fill(HIST("TrackCuts/HMN/After/Omega/EMC/fEta"), heavyNeutralMeson.eta()); - mHistManager.fill(HIST("TrackCuts/HMN/After/Omega/EMC/fPhi"), translatePhi(heavyNeutralMeson.phi())); + if (heavyNeutralMeson.pT() > cfgMinHNMPtsFemtoTrigger->get("EMC_omega")) { + omegaEMC.emplace_back(heavyNeutralMeson.pT(), heavyNeutralMeson.eta(), RecoDecay::constrainAngle(heavyNeutralMeson.phi()), massHNM); + mHistManager.fill(HIST("HNM/After/Omega/EMC/fInvMassVsPt"), massHNM, heavyNeutralMeson.pT()); + mHistManager.fill(HIST("HNM/After/Omega/EMC/fEta"), heavyNeutralMeson.eta()); + mHistManager.fill(HIST("HNM/After/Omega/EMC/fPhi"), RecoDecay::constrainAngle(heavyNeutralMeson.phi())); } - if (heavyNeutralMeson.pT() > minHNMPts->get("EMC_omega")) { + if (heavyNeutralMeson.pT() > cfgMinHNMPtsSpectrumTrigger->get("EMC_omega")) colContainsEMCOmega = true; - } } - } else if (heavyNeutralMeson.gg->isEta && massHNM > massWindowEtaPrime->get("etaprime_min") && massHNM < massWindowEtaPrime->get("etaprime_max")) { + } else if (heavyNeutralMeson.gg->isEta && massHNM > cfgMassWindowEtaPrime->get("etaprime_min") && massHNM < cfgMassWindowEtaPrime->get("etaprime_max")) { if (heavyNeutralMeson.gg->reconstructionType == photonpair::kPCMPCM) { - if (heavyNeutralMeson.pT() > minFemtoHNMPts->get("PCM_etaprime")) { - etaPrimePCM.emplace_back(heavyNeutralMeson.pT(), heavyNeutralMeson.eta(), translatePhi(heavyNeutralMeson.phi()), mMassEtaPrime); - // QA - mHistManager.fill(HIST("TrackCuts/HMN/After/EtaPrime/PCM/fInvMass"), massHNM); - mHistManager.fill(HIST("TrackCuts/HMN/After/EtaPrime/PCM/fPt"), heavyNeutralMeson.pT()); - mHistManager.fill(HIST("TrackCuts/HMN/After/EtaPrime/PCM/fEta"), heavyNeutralMeson.eta()); - mHistManager.fill(HIST("TrackCuts/HMN/After/EtaPrime/PCM/fPhi"), translatePhi(heavyNeutralMeson.phi())); + if (heavyNeutralMeson.pT() > cfgMinHNMPtsFemtoTrigger->get("PCM_etaprime")) { + etaPrimePCM.emplace_back(heavyNeutralMeson.pT(), heavyNeutralMeson.eta(), RecoDecay::constrainAngle(heavyNeutralMeson.phi()), massHNM); + mHistManager.fill(HIST("HNM/After/EtaPrime/PCM/fInvMassVsPt"), massHNM, heavyNeutralMeson.pT()); + mHistManager.fill(HIST("HNM/After/EtaPrime/PCM/fEta"), heavyNeutralMeson.eta()); + mHistManager.fill(HIST("HNM/After/EtaPrime/PCM/fPhi"), RecoDecay::constrainAngle(heavyNeutralMeson.phi())); } - if (heavyNeutralMeson.pT() > minHNMPts->get("PCM_etaprime")) { + if (heavyNeutralMeson.pT() > cfgMinHNMPtsSpectrumTrigger->get("PCM_etaprime")) colContainsPCMEtaPrime = true; - } } else if (heavyNeutralMeson.gg->reconstructionType == photonpair::kEMCEMC) { - if (heavyNeutralMeson.pT() > minFemtoHNMPts->get("EMC_etaprime")) { - etaPrimeEMC.emplace_back(heavyNeutralMeson.pT(), heavyNeutralMeson.eta(), translatePhi(heavyNeutralMeson.phi()), mMassEtaPrime); - // QA - mHistManager.fill(HIST("TrackCuts/HMN/After/EtaPrime/EMC/fInvMass"), massHNM); - mHistManager.fill(HIST("TrackCuts/HMN/After/EtaPrime/EMC/fPt"), heavyNeutralMeson.pT()); - mHistManager.fill(HIST("TrackCuts/HMN/After/EtaPrime/EMC/fEta"), heavyNeutralMeson.eta()); - mHistManager.fill(HIST("TrackCuts/HMN/After/EtaPrime/EMC/fPhi"), translatePhi(heavyNeutralMeson.phi())); + if (heavyNeutralMeson.pT() > cfgMinHNMPtsFemtoTrigger->get("EMC_etaprime")) { + etaPrimeEMC.emplace_back(heavyNeutralMeson.pT(), heavyNeutralMeson.eta(), RecoDecay::constrainAngle(heavyNeutralMeson.phi()), massHNM); + mHistManager.fill(HIST("HNM/After/EtaPrime/EMC/fInvMassVsPt"), massHNM, heavyNeutralMeson.pT()); + mHistManager.fill(HIST("HNM/After/EtaPrime/EMC/fEta"), heavyNeutralMeson.eta()); + mHistManager.fill(HIST("HNM/After/EtaPrime/EMC/fPhi"), RecoDecay::constrainAngle(heavyNeutralMeson.phi())); } - if (heavyNeutralMeson.pT() > minHNMPts->get("EMC_etaprime")) { + if (heavyNeutralMeson.pT() > cfgMinHNMPtsSpectrumTrigger->get("EMC_etaprime")) colContainsEMCEtaPrime = true; - } } } else { vHNMs.erase(vHNMs.begin() + iHNM); @@ -1592,26 +1271,15 @@ struct HeavyNeutralMesonFilter { } mHistManager.fill(HIST("Event/nHeavyNeutralMesons"), nHNMsBeforeMassCuts, vHNMs.size()); - if (colContainsPCMOmega) { - mHistManager.fill(HIST("Event/hCollisionCounter"), 2.); - mHistManager.fill(HIST("fProcessedEvents"), 9); - } - if (colContainsEMCOmega) { - mHistManager.fill(HIST("Event/hCollisionCounter"), 3.); - mHistManager.fill(HIST("fProcessedEvents"), 10); - } - if (colContainsPCMEtaPrime) { - mHistManager.fill(HIST("Event/hCollisionCounter"), 4.); - mHistManager.fill(HIST("fProcessedEvents"), 11); - } - if (colContainsEMCEtaPrime) { - mHistManager.fill(HIST("Event/hCollisionCounter"), 5.); - mHistManager.fill(HIST("fProcessedEvents"), 12); - } + if (colContainsPCMOmega) + mHistManager.fill(HIST("fProcessedEvents"), 2); + if (colContainsEMCOmega) + mHistManager.fill(HIST("fProcessedEvents"), 3); + if (colContainsPCMEtaPrime) + mHistManager.fill(HIST("fProcessedEvents"), 4); + if (colContainsEMCEtaPrime) + mHistManager.fill(HIST("fProcessedEvents"), 5); } }; -WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& cfgc) -{ - return WorkflowSpec{adaptAnalysisTask(cfgc)}; -} +WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& cfgc) { return WorkflowSpec{adaptAnalysisTask(cfgc)}; } diff --git a/EventFiltering/PWGHF/HFFilter.cxx b/EventFiltering/PWGHF/HFFilter.cxx index a0830524997..14390515f56 100644 --- a/EventFiltering/PWGHF/HFFilter.cxx +++ b/EventFiltering/PWGHF/HFFilter.cxx @@ -75,7 +75,7 @@ struct HfFilter { // Main struct for HF triggers // nsigma PID (except for V0 and cascades) Configurable> nSigmaPidCuts{"nSigmaPidCuts", {cutsNsigma[0], 4, 8, labelsRowsNsigma, labelsColumnsNsigma}, "Nsigma cuts for ITS/TPC/TOF PID (except for V0 and cascades)"}; // min and max pts for tracks and bachelors (except for V0 and cascades) - Configurable> ptCuts{"ptCuts", {cutsPt[0], 2, 9, labelsRowsCutsPt, labelsColumnsCutsPt}, "minimum and maximum pT for bachelor tracks (except for V0 and cascades)"}; + Configurable> ptCuts{"ptCuts", {cutsPt[0], 2, 10, labelsRowsCutsPt, labelsColumnsCutsPt}, "minimum and maximum pT for bachelor tracks (except for V0 and cascades)"}; // parameters for high-pT triggers Configurable> ptThresholds{"ptThresholds", {cutsHighPtThresholds[0], 1, 2, labelsEmpty, labelsColumnsHighPtThresholds}, "pT treshold for high pT charm hadron candidates for kHighPt triggers in GeV/c"}; @@ -208,6 +208,7 @@ struct HfFilter { // Main struct for HF triggers helper.setPtLimitsDeuteronForFemto(ptCuts->get(0u, 6u), ptCuts->get(1u, 6u)); helper.setPtLimitsCharmBaryonBachelor(ptCuts->get(0u, 3u), ptCuts->get(1u, 3u)); helper.setPtLimitsLcResonanceBachelor(ptCuts->get(0u, 8u), ptCuts->get(1u, 8u)); + helper.setPtLimitsThetaCBachelor(ptCuts->get(0u, 9u), ptCuts->get(1u, 9u)); helper.setCutsSingleTrackBeauty(cutsTrackBeauty3Prong, cutsTrackBeauty4Prong, cutsTrackBeauty4Prong); helper.setCutsSingleTrackCharmBaryonBachelor(cutsTrackCharmBaryonBachelor); helper.setCutsBhadrons(cutsBtoHadrons.cutsBplus, cutsBtoHadrons.cutsBzeroToDstar, cutsBtoHadrons.cutsBc, cutsBtoHadrons.cutsBzero, cutsBtoHadrons.cutsBs, cutsBtoHadrons.cutsLb, cutsBtoHadrons.cutsXib); @@ -977,11 +978,14 @@ struct HfFilter { // Main struct for HF triggers o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackParBachelorProton, 2.f, noMatCorr, &dcaInfoBachProton); } std::array pVecProton = trackProton.pVector(); - bool isSelProton = helper.isSelectedProtonFromLcReso(trackProton); - if (isSelProton) { + bool isSelPIDProton = helper.isSelectedProton4CharmOrBeautyBaryons(trackProton); + if (isSelPIDProton) { if (!keepEvent[kPrCharm2P]) { // we first look for a D*+ for (const auto& trackBachelorId : trackIdsThisCollision) { // start loop over tracks to find bachelor pion + if (!helper.isSelectedProtonFromLcResoOrThetaC(trackProton)) { + continue; + } // stop here if proton below pT threshold for thetaC to avoid computational losses auto trackBachelor = tracks.rawIteratorAt(trackBachelorId.trackId()); if (trackBachelor.globalIndex() == trackPos.globalIndex() || trackBachelor.globalIndex() == trackNeg.globalIndex() || trackBachelor.globalIndex() == trackProton.globalIndex()) { continue; @@ -1064,6 +1068,9 @@ struct HfFilter { // Main struct for HF triggers if (pt2Prong < cutsPtDeltaMassCharmReso->get(3u, 11u)) { continue; } + if (!helper.isSelectedProtonFromLcResoOrThetaC(trackProton)) { + continue; + } float massLcStarCand{-999.}, massLcStarBarCand{-999.}; float massDiffLcStarCand{-999.}, massDiffLcStarBarCand{-999.}; bool isRightSignLcStar{false}, isRightSignLcStarBar{false}; diff --git a/EventFiltering/PWGHF/HFFilterHelpers.h b/EventFiltering/PWGHF/HFFilterHelpers.h index bbd792841a3..798a96b1ec7 100644 --- a/EventFiltering/PWGHF/HFFilterHelpers.h +++ b/EventFiltering/PWGHF/HFFilterHelpers.h @@ -298,9 +298,9 @@ constexpr float cutsPtThresholdsForFemto[1][2] = {{8., 1.4}}; // proton, deutero static const std::vector labelsColumnsPtThresholdsForFemto = {"Proton", "Deuteron"}; // min and max pT for all tracks combined (except for V0 and cascades) -constexpr float cutsPt[2][9] = {{1., 0.1, 0.8, 0.5, 0.1, 0.2, 0.4, 0.5, 0.3}, - {100000., 100000., 5., 100000., 100000., 100000., 100000., 100000., 100000.}}; // beauty, D*, femto, SigmaC, Xic*+ -> SigmaC++K-, beauty to JPsi, Lc*->D0p -static const std::vector labelsColumnsCutsPt = {"Beauty", "DstarPlus", "PrForFemto", "CharmBaryon", "SoftPiSigmaC", "SoftKaonXicResoToSigmaC", "DeForFemto", "BeautyToJPsi", "PrForLcReso"}; +constexpr float cutsPt[2][10] = {{1., 0.1, 0.8, 0.5, 0.1, 0.2, 0.4, 0.5, 0.3, 0.3}, + {100000., 100000., 5., 100000., 100000., 100000., 100000., 100000., 100000., 100000.}}; // beauty, D*, femto, SigmaC, Xic*+ -> SigmaC++K-, beauty to JPsi, Lc*->D0p +static const std::vector labelsColumnsCutsPt = {"Beauty", "DstarPlus", "PrForFemto", "CharmBaryon", "SoftPiSigmaC", "SoftKaonXicResoToSigmaC", "DeForFemto", "BeautyToJPsi", "PrForLcReso", "PrForThetaC"}; static const std::vector labelsRowsCutsPt = {"Minimum", "Maximum"}; // PID cuts @@ -481,6 +481,11 @@ class HfFilterHelper mPtMinLcResonanceBachelor = minPt; mPtMaxLcResonanceBachelor = maxPt; } + void setPtLimitsThetaCBachelor(float minPt, float maxPt) + { + mPtMinThetaCBachelor = minPt; + mPtMaxThetaCBachelor = maxPt; + } void setNsigmaProtonCutsForFemto(std::array nSigmaCuts) { mNSigmaPrCutsForFemto = nSigmaCuts; } void setNsigmaDeuteronCutsForFemto(std::array nSigmaCuts) { mNSigmaDeCutsForFemto = nSigmaCuts; } @@ -628,8 +633,8 @@ class HfFilterHelper bool isSelectedXiBach(T const& trackParCasc, T const& trackParBachelor, int8_t isSelBachelor, C const& collision, o2::vertexing::DCAFitterN<2>& dcaFitter, const int& activateQA, H2 hMassVsPtXiPi, H2 hMassVsPtXiKa); template bool isSelectedXiBachBach(T const& trackParCasc, std::array const& trackParBachelor, C const& collision, o2::vertexing::DCAFitterN& dcaFitter, const int& activateQA, H2 hMassVsPtXiPiPi); - template - bool isSelectedProtonFromLcReso(const T& track); + template + bool isSelectedProtonFromLcResoOrThetaC(const T& track); // helpers template T computeRelativeMomentum(const std::array& pTrack, const std::array& CharmCandMomentum, const T& CharmMass); @@ -682,6 +687,7 @@ class HfFilterHelper float mPtMinDeuteronForFemto{0.8}; // minimum pt for the deuteron for femto float mPtMinCharmBaryonBachelor{0.5}; // minimum pt for the bachelor pion from Xic/Omegac decays float mPtMinLcResonanceBachelor{0.3}; // minimum pt for the bachelor proton from Lc resonance decays + float mPtMinThetaCBachelor{0.3}; // minimum pt for the bachelor proton from ThetaC decays float mPtMaxSoftPionForDstar{2.}; // maximum pt for the D*+ soft pion float mPtMaxBeautyBachelor{100000.}; // maximum pt for the b-hadron pion daughter float mPtMaxBeautyToJPsiBachelor{100000.}; // maximum pt for the b-hadron -> JPsi X daughters (not the muons) @@ -689,6 +695,7 @@ class HfFilterHelper float mPtMaxDeuteronForFemto{5.0}; // maximum pt for the deuteron for femto float mPtMaxCharmBaryonBachelor{100000.}; // maximum pt for the bachelor pion from Xic/Omegac decays float mPtMaxLcResonanceBachelor{100000.}; // maximum pt for the bachelor proton from Lc resonance decays + float mPtMaxThetaCBachelor{100000.}; // maximum pt for the bachelor proton from ThetaC decays float mPtThresholdProtonForFemto{8.}; // pt threshold to change strategy for proton PID for femto float mPtThresholdDeuteronForFemto{1.4}; // pt threshold to change strategy for deuteron PID for femto float mPtMinSigmaCZero{0.f}; // pt min SigmaC0 candidate @@ -1945,19 +1952,22 @@ inline bool HfFilterHelper::isSelectedKaon4Charm3ProngOrBeautyToJPsi(const T& tr /// Basic selection of proton candidates forLc and ThetaC decays /// \param track is a track /// \return true if track passes all cuts -template -inline bool HfFilterHelper::isSelectedProtonFromLcReso(const T& track) +template +inline bool HfFilterHelper::isSelectedProtonFromLcResoOrThetaC(const T& track) { // pt selections float pt = track.pt(); - if (pt < mPtMinLcResonanceBachelor || pt > mPtMaxLcResonanceBachelor) { - return false; + if constexpr (is4ThetaC) { + if (pt < mPtMinThetaCBachelor || pt > mPtMaxThetaCBachelor) { + return false; + } + } else { + if (pt < mPtMinLcResonanceBachelor || pt > mPtMaxLcResonanceBachelor) { + return false; + } } - /// PID selection - return isSelectedProton4CharmOrBeautyBaryons(track); - return true; } diff --git a/EventFiltering/PWGLF/filterdoublephi.cxx b/EventFiltering/PWGLF/filterdoublephi.cxx index e6561a07c8c..0ee9f34b535 100644 --- a/EventFiltering/PWGLF/filterdoublephi.cxx +++ b/EventFiltering/PWGLF/filterdoublephi.cxx @@ -131,10 +131,10 @@ struct filterdoublephi { return true; } if (candidate.pt() >= 0.5) { - if (!candidate.hasTOF() && candidate.tpcNSigmaKa() > nsigmaCutTPC && candidate.tpcNSigmaKa() < 3.0) { + if (!candidate.hasTOF() && candidate.tpcNSigmaKa() > nsigmaCutTPC && candidate.tpcNSigmaKa() < 2.0) { return true; } - if (candidate.hasTOF() && candidate.beta() > cfgCutTOFBeta && candidate.tpcNSigmaKa() > nsigmaCutTPC && candidate.tpcNSigmaKa() < 3.0 && TMath::Abs(candidate.tofNSigmaKa()) < nsigmaCutTOF) { + if (candidate.hasTOF() && candidate.beta() > cfgCutTOFBeta && TMath::Sqrt(candidate.tpcNSigmaKa() * candidate.tpcNSigmaKa() + candidate.tofNSigmaKa() * candidate.tofNSigmaKa()) < nsigmaCutTOF) { return true; } } @@ -146,11 +146,14 @@ struct filterdoublephi { if (candidate.pt() < 0.5 && candidate.tpcNSigmaKa() > nsigmaCutTPC && candidate.tpcNSigmaKa() < 3.0) { return true; } - if (candidate.pt() >= 0.5) { - if (candidate.hasTOF() && candidate.beta() > cfgCutTOFBeta && candidate.tpcNSigmaKa() > nsigmaCutTPC && candidate.tpcNSigmaKa() < 3.0 && TMath::Abs(candidate.tofNSigmaKa()) < nsigmaCutTOF) { + if (candidate.pt() >= 0.5 && candidate.pt() < 5.0) { + if (candidate.hasTOF() && candidate.beta() > cfgCutTOFBeta && TMath::Sqrt(candidate.tpcNSigmaKa() * candidate.tpcNSigmaKa() + candidate.tofNSigmaKa() * candidate.tofNSigmaKa()) < nsigmaCutTOF) { return true; } } + if (candidate.pt() >= 5.0 && candidate.tpcNSigmaKa() > nsigmaCutTPC && candidate.tpcNSigmaKa() < 2.0) { + return true; + } return false; } // deep angle cut on pair to remove photon conversion @@ -259,7 +262,7 @@ struct filterdoublephi { auto i6 = std::distance(phiresonance.begin(), if2); PhiVectorDummy2 = phiresonance.at(i6); PhiPair = PhiVectorDummy + PhiVectorDummy2; - if ((Phid1Index.at(i5) != Phid1Index.at(i6)) && (Phid2Index.at(i5) != Phid2Index.at(i6)) && PhiPair.M() > MinPhiPairMass && PhiPair.M() < MaxPhiPairMass && PhiPair.Pt() > MinPhiPairPt) { + if (!(Phid1Index.at(i5) == Phid1Index.at(i6) || Phid2Index.at(i5) == Phid2Index.at(i6)) && PhiPair.M() > MinPhiPairMass && PhiPair.M() < MaxPhiPairMass && PhiPair.Pt() > MinPhiPairPt) { qaRegistry.fill(HIST("hInvMassDoublePhi"), PhiPair.M(), PhiPair.Pt()); keepEventDoublePhi = true; } diff --git a/EventFiltering/PWGLF/filterf1proton.cxx b/EventFiltering/PWGLF/filterf1proton.cxx index 0d3d643207e..abdfe9c272a 100644 --- a/EventFiltering/PWGLF/filterf1proton.cxx +++ b/EventFiltering/PWGLF/filterf1proton.cxx @@ -17,12 +17,20 @@ #include #include #include +#include #include #include #include #include #include - +#include + +#include "DataFormatsParameters/GRPMagField.h" +#include "DataFormatsParameters/GRPObject.h" +#include "ReconstructionDataFormats/Track.h" +#include "ReconstructionDataFormats/TrackParametrization.h" +#include "Common/Core/RecoDecay.h" +#include "Common/Core/trackUtilities.h" #include "../filterTables.h" #include "Framework/ASoAHelpers.h" #include "Framework/AnalysisDataModel.h" @@ -36,6 +44,8 @@ #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponse.h" #include "PWGLF/DataModel/LFStrangenessTables.h" +#include "PWGLF/Utils/strangenessBuilderHelper.h" +#include "PWGLF/DataModel/LFParticleIdentification.h" #include "CommonConstants/PhysicsConstants.h" #include "DataFormatsTPC/BetheBlochAleph.h" #include "CCDB/BasicCCDBManager.h" @@ -151,8 +161,22 @@ struct filterf1proton { }, OutputObjHandlingPolicy::AnalysisObject}; + // helper object + o2::pwglf::strangenessBuilderHelper mStraHelper; + int mRunNumber = 0; + float mBz = 0.; + void init(o2::framework::InitContext&) { + // set V0 parameters in the helper + mStraHelper.v0selections.minCrossedRows = ConfDaughTPCnclsMin; + mStraHelper.v0selections.dcanegtopv = ConfDaughDCAMin; + mStraHelper.v0selections.dcapostopv = ConfDaughDCAMin; // get the minimum one + mStraHelper.v0selections.v0cospa = ConfV0CPAMin; + mStraHelper.v0selections.dcav0dau = ConfV0DCADaughMax; + mStraHelper.v0selections.v0radius = ConfV0TranRadV0Min; + mStraHelper.v0selections.maxDaughterEta = ConfDaughEta; + ccdb->setURL(url.value); ccdbApi.init(url); ccdb->setCaching(true); @@ -163,6 +187,26 @@ struct filterf1proton { hProcessedEvents->GetXaxis()->SetBinLabel(3, aod::filtering::TriggerEventF1Proton::columnLabel()); } + void initCCDB(int run) + { + if (run != mRunNumber) { + mRunNumber = run; + o2::parameters::GRPMagField* grpmag = ccdb->getForRun("GLO/Config/GRPMagField", run); + o2::base::Propagator::initFieldFromGRP(grpmag); + mBz = static_cast(grpmag->getNominalL3Field()); + mStraHelper.fitter.setBz(mBz); + } + if (!mStraHelper.lut) { /// done only once + ccdb->setURL(url.value); + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); + ccdb->setFatalWhenNull(true); + auto* lut = o2::base::MatLayerCylSet::rectifyPtrFromFile(ccdb->get("GLO/Param/MatLUT")); + o2::base::Propagator::Instance()->setMatLUT(lut); + mStraHelper.lut = lut; + } + } + template bool isSelectedEvent(T const& col) { @@ -257,10 +301,10 @@ struct filterf1proton { bool isSelectedV0Daughter(T const& track, float charge, double nsigmaV0Daughter) { const auto eta = track.eta(); - const auto tpcNClsF = track.tpcNClsFound(); + // const auto tpcNClsF = track.tpcNClsFound(); + const auto tpcNClsF = track.tpcNClsCrossedRows(); const auto dcaXY = track.dcaXY(); const auto sign = track.sign(); - if (charge < 0 && sign > 0) { return false; } @@ -276,7 +320,6 @@ struct filterf1proton { if (std::abs(dcaXY) < ConfDaughDCAMin) { return false; } - if (std::abs(nsigmaV0Daughter) > ConfDaughPIDCuts) { return false; } @@ -439,6 +482,7 @@ struct filterf1proton { aod::pidTPCFullPi, aod::pidTOFFullPi, aod::pidTPCFullKa, aod::pidTOFFullKa, aod::pidTPCFullPr, aod::pidTOFFullPr>>; + using PrimaryTrackCandidatesIU = soa::Filtered>; void processF1Proton(EventCandidates::iterator const& collision, aod::BCsWithTimestamps const&, PrimaryTrackCandidates const& tracks, ResoV0s const& V0s) { @@ -572,8 +616,8 @@ struct filterf1proton { if (!SelectionV0(collision, v0)) { continue; } - auto postrack = v0.template posTrack_as(); - auto negtrack = v0.template negTrack_as(); + auto postrack = v0.posTrack_as(); + auto negtrack = v0.negTrack_as(); double nTPCSigmaPos[1]{postrack.tpcNSigmaPi()}; double nTPCSigmaNeg[1]{negtrack.tpcNSigmaPi()}; if (ConfUseManualPIDdaughterPion) { @@ -655,7 +699,207 @@ struct filterf1proton { } tags(keepEventF1Proton); } - PROCESS_SWITCH(filterf1proton, processF1Proton, "Process for trigger", true); + PROCESS_SWITCH(filterf1proton, processF1Proton, "Process for trigger", false); + TLorentzVector v0Dummy; + void processF1ProtonHelper(EventCandidates::iterator const& collision, aod::BCs const&, PrimaryTrackCandidatesIU const& tracks, aod::V0s const& V0s) + { + initCCDB(collision.bc().runNumber()); + bool keepEventF1Proton = false; + int numberF1 = 0; + if (isSelectedEvent(collision)) { + + // keep track of indices + std::vector PionIndex = {}; + std::vector KaonIndex = {}; + std::vector ProtonIndex = {}; + + // keep charge of track + std::vector PionCharge = {}; + std::vector KaonCharge = {}; + std::vector ProtonCharge = {}; + + // Prepare vectors for different species + std::vector protons, kaons, pions, kshorts; + float kstar = 999.f; + + for (auto& track : tracks) { + + if (!isSelectedTrack(track)) + continue; + qaRegistry.fill(HIST("hDCAxy"), track.dcaXY()); + qaRegistry.fill(HIST("hDCAz"), track.dcaZ()); + qaRegistry.fill(HIST("hEta"), track.eta()); + qaRegistry.fill(HIST("hPhi"), track.phi()); + double nTPCSigmaP[3]{track.tpcNSigmaPi(), track.tpcNSigmaKa(), track.tpcNSigmaPr()}; + double nTPCSigmaN[3]{track.tpcNSigmaPi(), track.tpcNSigmaKa(), track.tpcNSigmaPr()}; + + if ((track.sign() > 0 && SelectionPID(track, strategyPIDPion, 0, nTPCSigmaP[0])) || (track.sign() < 0 && SelectionPID(track, strategyPIDPion, 0, nTPCSigmaN[0]))) { + ROOT::Math::PtEtaPhiMVector temp(track.pt(), track.eta(), track.phi(), massPi); + pions.push_back(temp); + PionIndex.push_back(track.globalIndex()); + PionCharge.push_back(track.sign()); + if (track.sign() > 0) { + qaRegistry.fill(HIST("hNsigmaPtpionTPC"), nTPCSigmaP[0], track.pt()); + } + if (track.sign() < 0) { + qaRegistry.fill(HIST("hNsigmaPtpionTPC"), nTPCSigmaN[0], track.pt()); + } + if (track.hasTOF()) { + qaRegistry.fill(HIST("hNsigmaPtpionTOF"), track.tofNSigmaPi(), track.pt()); + } + } + + if ((track.pt() > cMinKaonPt && track.sign() > 0 && SelectionPID(track, strategyPIDKaon, 1, nTPCSigmaP[1])) || (track.pt() > cMinKaonPt && track.sign() < 0 && SelectionPID(track, strategyPIDKaon, 1, nTPCSigmaN[1]))) { + ROOT::Math::PtEtaPhiMVector temp(track.pt(), track.eta(), track.phi(), massKa); + kaons.push_back(temp); + KaonIndex.push_back(track.globalIndex()); + KaonCharge.push_back(track.sign()); + if (track.sign() > 0) { + qaRegistry.fill(HIST("hNsigmaPtkaonTPC"), nTPCSigmaP[1], track.pt()); + } + if (track.sign() < 0) { + qaRegistry.fill(HIST("hNsigmaPtkaonTPC"), nTPCSigmaN[1], track.pt()); + } + if (track.hasTOF()) { + qaRegistry.fill(HIST("hNsigmaPtkaonTOF"), track.tofNSigmaKa(), track.pt()); + } + } + + if ((track.pt() < cMaxProtonPt && track.sign() > 0 && SelectionPID(track, strategyPIDProton, 2, nTPCSigmaP[2])) || (track.pt() < cMaxProtonPt && track.sign() < 0 && SelectionPID(track, strategyPIDProton, 2, nTPCSigmaN[2]))) { + ROOT::Math::PtEtaPhiMVector temp(track.pt(), track.eta(), track.phi(), massPr); + qaRegistry.fill(HIST("hMommentumCorr"), track.p() / track.sign(), track.p() - track.tpcInnerParam()); + if (ConfFakeProton && !isFakeProton(track)) { + protons.push_back(temp); + ProtonIndex.push_back(track.globalIndex()); + ProtonCharge.push_back(track.sign()); + } + if (track.sign() > 0) { + qaRegistry.fill(HIST("hNsigmaPtprotonTPC"), nTPCSigmaP[2], track.pt()); + } + if (track.sign() < 0) { + qaRegistry.fill(HIST("hNsigmaPtprotonTPC"), nTPCSigmaN[2], track.pt()); + } + if (track.hasTOF()) { + qaRegistry.fill(HIST("hNsigmaPtprotonTOF"), track.tofNSigmaPr(), track.pt()); + } + } + } // track loop end + + // keep track of daugher indices to avoid selfcorrelations + std::vector KshortPosDaughIndex = {}; + std::vector KshortNegDaughIndex = {}; + + for (auto& v0 : V0s) { + + auto postrack = v0.template posTrack_as(); + auto negtrack = v0.template negTrack_as(); + auto trackparpos = getTrackParCov(postrack); + auto trackparneg = getTrackParCov(negtrack); + if (!mStraHelper.buildV0Candidate(v0.collisionId(), collision.posX(), collision.posY(), collision.posZ(), postrack, negtrack, trackparpos, trackparneg)) { + continue; + } + + if (fabs(mStraHelper.v0.dcaToPV) > cMaxV0DCA) { + continue; + } + auto v0px = mStraHelper.v0.momentum[0]; + auto v0py = mStraHelper.v0.momentum[1]; + auto v0pz = mStraHelper.v0.momentum[2]; + auto pT = std::sqrt(v0px * v0px + v0py * v0py); + if (pT < ConfV0PtMin) { + continue; + } + if (std::hypot(mStraHelper.v0.position[0], mStraHelper.v0.position[1]) < ConfV0TranRadV0Min) { + continue; + } + if (std::hypot(mStraHelper.v0.position[0], mStraHelper.v0.position[1]) > ConfV0TranRadV0Max) { + continue; + } + double distovertotmom = std::hypot(mStraHelper.v0.position[0] - collision.posX(), mStraHelper.v0.position[1] - collision.posY(), mStraHelper.v0.position[2] - collision.posZ()) / (std::hypot(mStraHelper.v0.momentum[0], mStraHelper.v0.momentum[1], mStraHelper.v0.momentum[2]) + 1e-13); + if (distovertotmom * o2::constants::physics::MassK0Short > cMaxV0LifeTime) { + continue; + } + float lowmasscutks0 = 0.497 - 2.0 * cSigmaMassKs0; + float highmasscutks0 = 0.497 + 2.0 * cSigmaMassKs0; + if (mStraHelper.v0.massK0Short < lowmasscutks0 || mStraHelper.v0.massK0Short > highmasscutks0) { + continue; + } + double nTPCSigmaPos[1]{postrack.tpcNSigmaPi()}; + double nTPCSigmaNeg[1]{negtrack.tpcNSigmaPi()}; + if (!isSelectedV0Daughter(postrack, 1, nTPCSigmaPos[0])) { + continue; + } + if (!isSelectedV0Daughter(negtrack, -1, nTPCSigmaNeg[0])) { + continue; + } + v0Dummy.SetXYZM(v0px, v0py, v0pz, mStraHelper.v0.massK0Short); + qaRegistry.fill(HIST("hInvMassk0"), v0Dummy.M(), pT); + ROOT::Math::PtEtaPhiMVector temp(pT, v0Dummy.Eta(), v0Dummy.Phi(), mStraHelper.v0.massK0Short); + kshorts.push_back(temp); + KshortPosDaughIndex.push_back(postrack.globalIndex()); + KshortNegDaughIndex.push_back(negtrack.globalIndex()); + } + + if (pions.size() != 0 && kaons.size() != 0 && kshorts.size() != 0) { + for (auto ipion = pions.begin(); ipion != pions.end(); ++ipion) { + for (auto ikaon = kaons.begin(); ikaon != kaons.end(); ++ikaon) { + auto i1 = std::distance(pions.begin(), ipion); + auto i2 = std::distance(kaons.begin(), ikaon); + // if(PionCharge.at(i1)*KaonCharge.at(i2)>0)continue; + if (PionIndex.at(i1) == KaonIndex.at(i2)) + continue; + for (auto ikshort = kshorts.begin(); ikshort != kshorts.end(); ++ikshort) { + auto i3 = std::distance(kshorts.begin(), ikshort); + if (PionIndex.at(i1) == KshortPosDaughIndex.at(i3)) + continue; + if (PionIndex.at(i1) == KshortNegDaughIndex.at(i3)) + continue; + KKs0Vector = kaons.at(i2) + kshorts.at(i3); + if (KKs0Vector.M() > cMaxMassKKs0) + continue; + F1Vector = KKs0Vector + pions.at(i1); + if (F1Vector.M() > cMaxMassF1) + continue; + if (F1Vector.Pt() < cMinF1Pt) + continue; + if (PionCharge.at(i1) * KaonCharge.at(i2) > 0) { + qaRegistry.fill(HIST("hInvMassf1Like"), F1Vector.M(), F1Vector.Pt()); + continue; + } + qaRegistry.fill(HIST("hInvMassf1"), F1Vector.M(), F1Vector.Pt()); + numberF1 = numberF1 + 1; + for (auto iproton = protons.begin(); iproton != protons.end(); ++iproton) { + auto i4 = std::distance(protons.begin(), iproton); + if (ProtonIndex.at(i4) == PionIndex.at(i1)) + continue; + if (ProtonIndex.at(i4) == KaonIndex.at(i2)) + continue; + if (ProtonIndex.at(i4) == KshortPosDaughIndex.at(i3)) + continue; + if (ProtonIndex.at(i4) == KshortNegDaughIndex.at(i3)) + continue; + kstar = getkstar(F1Vector, *iproton); + qaRegistry.fill(HIST("hkstarDist"), kstar); + if (kstar > cMaxRelMom) + continue; + qaRegistry.fill(HIST("hInvMassf1kstar"), F1Vector.M(), F1Vector.Pt(), kstar); + keepEventF1Proton = true; + } + } + } + } + } + } + hProcessedEvents->Fill(0.5); + if (numberF1 > 0) { + hProcessedEvents->Fill(1.5); + } + if (keepEventF1Proton) { + hProcessedEvents->Fill(2.5); + } + tags(keepEventF1Proton); + } + PROCESS_SWITCH(filterf1proton, processF1ProtonHelper, "Process for trigger with helper v0 task", true); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfg) diff --git a/EventFiltering/PWGLF/nucleiFilter.cxx b/EventFiltering/PWGLF/nucleiFilter.cxx index de8a35a4993..4b22c95c3b1 100644 --- a/EventFiltering/PWGLF/nucleiFilter.cxx +++ b/EventFiltering/PWGLF/nucleiFilter.cxx @@ -102,6 +102,7 @@ struct nucleiFilter { Configurable cfgCutDCAxy{"cfgCutDCAxy", 3, "Max DCAxy"}; Configurable cfgCutDCAz{"cfgCutDCAz", 10, "Max DCAz"}; Configurable cfgCutKstar{"cfgCutKstar", 1.f, "Kstar cut for triton femto trigger"}; + Configurable cfgCutCosPAheV0{"cfgCutCosPAheV0", 0.99, "CosPA cut for HeV0"}; Configurable> cfgBetheBlochParams{"cfgBetheBlochParams", {betheBlochDefault[0], nNuclei, 6, nucleiNames, betheBlochParNames}, "TPC Bethe-Bloch parameterisation for light nuclei"}; Configurable> cfgMomentumScalingBetheBloch{"cfgMomentumScalingBetheBloch", {bbMomScalingDefault[0], nNuclei, 2, nucleiNames, matterOrNot}, "TPC Bethe-Bloch momentum scaling for light nuclei"}; @@ -112,16 +113,17 @@ struct nucleiFilter { // variable/tool for hypertriton 3body decay int mRunNumber; - float d_bz; + float mBz; Service ccdb; using TrackCandidates = soa::Join; // FIXME: positio has been changed o2::aod::pidtofgeneric::TofPidNewCollision bachelorTOFPID; o2::base::MatLayerCylSet* lut = nullptr; + o2::vertexing::DCAFitterN<2> fitter2body; o2::vertexing::DCAFitterN<3> fitter3body; o2::pid::tof::TOFResoParamsV2 mRespParamsV2; // configurable for hypertriton 3body decay struct : ConfigurableGroup { - Configurable d_bz_input{"trgH3L3Body.d_bz", -999, "bz field, -999 is automatic"}; + Configurable bFieldInput{"trgH3L3Body.mBz", -999, "bz field, -999 is automatic"}; Configurable minCosPA3body{"trgH3L3Body.minCosPA3body", 0.9995, "minCosPA3body"}; Configurable dcavtxdau{"trgH3L3Body.dcavtxdau", 0.02, "meen DCA among Daughters"}; Configurable dcapiontopv{"trgH3L3Body.dcapiontopv", 0.05, "DCA Pion To PV"}; @@ -200,6 +202,14 @@ struct nucleiFilter { fitter3body.setMaxChi2(1e9); fitter3body.setUseAbsDCA(true); + fitter2body.setPropagateToPCA(true); + fitter2body.setMaxR(200.); + fitter2body.setMinParamChange(1e-3); + fitter2body.setMinRelChi2Change(0.9); + fitter2body.setMaxDZIni(1e9); + fitter2body.setMaxChi2(1e9); + fitter2body.setUseAbsDCA(true); + ccdb->setURL(trgH3L3Body.ccdburl); ccdb->setCaching(true); ccdb->setLocalObjectValidityChecking(); @@ -213,12 +223,11 @@ struct nucleiFilter { } // In case override, don't proceed, please - no CCDB access required - if (trgH3L3Body.d_bz_input > -990) { - d_bz = trgH3L3Body.d_bz_input; - fitter3body.setBz(d_bz); + if (trgH3L3Body.bFieldInput > -990) { + mBz = trgH3L3Body.bFieldInput; o2::parameters::GRPMagField grpmag; - if (std::fabs(d_bz) > 1e-5) { - grpmag.setL3Current(30000.f / (d_bz / 5.0f)); + if (std::fabs(mBz) > 1e-5) { + grpmag.setL3Current(30000.f / (mBz / 5.0f)); } o2::base::Propagator::initFieldFromGRP(&grpmag); mRunNumber = bc.runNumber(); @@ -231,8 +240,8 @@ struct nucleiFilter { if (grpo) { o2::base::Propagator::initFieldFromGRP(grpo); // Fetch magnetic field from ccdb for current collision - d_bz = grpo->getNominalL3Field(); - LOG(info) << "Retrieved GRP for timestamp " << run3grp_timestamp << " with magnetic field of " << d_bz << " kZG"; + mBz = grpo->getNominalL3Field(); + LOG(info) << "Retrieved GRP for timestamp " << run3grp_timestamp << " with magnetic field of " << mBz << " kZG"; } else { grpmag = ccdb->getForTimeStamp(trgH3L3Body.grpmagPath, run3grp_timestamp); if (!grpmag) { @@ -240,13 +249,14 @@ struct nucleiFilter { } o2::base::Propagator::initFieldFromGRP(grpmag); // Fetch magnetic field from ccdb for current collision - // d_bz = std::lround(5.f * grpmag->getL3Current() / 30000.f); - d_bz = o2::base::Propagator::Instance()->getNominalBz(); - LOG(info) << "Retrieved GRP for timestamp " << run3grp_timestamp << " with magnetic field of " << d_bz << " kZG"; + // mBz = std::lround(5.f * grpmag->getL3Current() / 30000.f); + mBz = o2::base::Propagator::Instance()->getNominalBz(); + LOG(info) << "Retrieved GRP for timestamp " << run3grp_timestamp << " with magnetic field of " << mBz << " kZG"; } mRunNumber = bc.runNumber(); // Set magnetic field value once known - fitter3body.setBz(d_bz); + fitter2body.setBz(mBz); + fitter3body.setBz(mBz); if (trgH3L3Body.useMatCorrType == 2) { // setMatLUT only after magfield has been initalized @@ -448,8 +458,8 @@ struct nucleiFilter { } for (const auto& v0 : v0s) { - const auto& posTrack = tracks.rawIteratorAt(v0.posTrackId()); - const auto& negTrack = tracks.rawIteratorAt(v0.negTrackId()); + const auto& posTrack = v0.posTrack_as(); + const auto& negTrack = v0.negTrack_as(); if ((posTrack.itsNCls() < cfgCutNclusITS || posTrack.tpcNClsFound() < cfgCutNclusTPC) && (negTrack.itsNCls() < cfgCutNclusITS || negTrack.tpcNClsFound() < cfgCutNclusTPC)) { continue; @@ -457,11 +467,29 @@ struct nucleiFilter { float nSigmas[2]{ cfgBetheBlochParams->get(2, 5u) > 0.f ? getNsigma(posTrack, 2, 0) : posTrack.tpcNSigmaHe(), cfgBetheBlochParams->get(2, 5u) > 0.f ? getNsigma(negTrack, 2, 1) : negTrack.tpcNSigmaHe()}; - if ((nSigmas[0] > cfgCutsPID->get(2, 0u) && nSigmas[0] < cfgCutsPID->get(2, 1u)) || - (nSigmas[1] > cfgCutsPID->get(2, 0u) && nSigmas[1] < cfgCutsPID->get(2, 1u))) { - keepEvent[kHeV0] = true; - break; + if ((nSigmas[0] < cfgCutsPID->get(2, 0u) || nSigmas[0] > cfgCutsPID->get(2, 1u)) && + (nSigmas[1] < cfgCutsPID->get(2, 0u) || nSigmas[1] > cfgCutsPID->get(2, 1u))) { + continue; + } + int n2bodyVtx = fitter2body.process(getTrackParCov(posTrack), getTrackParCov(negTrack)); + if (n2bodyVtx == 0) { + continue; + } + auto vtxXYZ = fitter2body.getPCACandidate(); + o2::gpu::gpustd::array mom = {0.}; + vtxXYZ[0] -= collision.posX(); + vtxXYZ[1] -= collision.posY(); + vtxXYZ[2] -= collision.posZ(); + auto momTrackParCov = fitter2body.createParentTrackPar(); + momTrackParCov.getPxPyPzGlo(mom); + double cosPA = (vtxXYZ[0] * mom[0] + vtxXYZ[1] * mom[1] + vtxXYZ[2] * mom[2]) / + std::sqrt((vtxXYZ[0] * vtxXYZ[0] + vtxXYZ[1] * vtxXYZ[1] + vtxXYZ[2] * vtxXYZ[2]) * + (mom[0] * mom[0] + mom[1] * mom[1] + mom[2] * mom[2])); + if (cosPA < cfgCutCosPAheV0) { + continue; } + keepEvent[kHeV0] = true; + break; } // diff --git a/EventFiltering/PWGLF/strangenessFilter.cxx b/EventFiltering/PWGLF/strangenessFilter.cxx index ef311a4a221..fea1290cc0c 100644 --- a/EventFiltering/PWGLF/strangenessFilter.cxx +++ b/EventFiltering/PWGLF/strangenessFilter.cxx @@ -15,6 +15,7 @@ /// \since June 1, 2021 #include +#include "TVector3.h" #include "CCDB/BasicCCDBManager.h" #include "DataFormatsParameters/GRPMagField.h" #include "DataFormatsParameters/GRPObject.h" @@ -25,6 +26,7 @@ #include "Framework/AnalysisDataModel.h" #include "Framework/ASoAHelpers.h" #include "ReconstructionDataFormats/Track.h" +#include "ReconstructionDataFormats/TrackParametrization.h" #include "Common/Core/RecoDecay.h" #include "Common/Core/trackUtilities.h" #include "PWGLF/DataModel/LFStrangenessTables.h" @@ -59,7 +61,7 @@ static const std::vector speciesNames{"Xi", "Omega"}; float CalculateDCAStraightToPV(float X, float Y, float Z, float Px, float Py, float Pz, float pvX, float pvY, float pvZ) { - return std::hypot((pvY - Y) * Pz - (pvZ - Z) * Py, (pvX - X) * Pz - (pvZ - Z) * Px, (pvX - X) * Py - (pvY - Y) * Px) / (Px * Px + Py * Py + Pz * Pz); + return std::hypot((pvY - Y) * Pz - (pvZ - Z) * Py, (pvX - X) * Pz - (pvZ - Z) * Px, (pvX - X) * Py - (pvY - Y) * Px) / std::sqrt(Px * Px + Py * Py + Pz * Pz); } struct strangenessFilter { @@ -73,10 +75,38 @@ struct strangenessFilter { HistogramRegistry QAHistosTriggerParticles{"QAHistosTriggerParticles", {}, OutputObjHandlingPolicy::AnalysisObject, false, true}; HistogramRegistry QAHistosStrangenessTracking{"QAHistosStrangenessTracking", {}, OutputObjHandlingPolicy::AnalysisObject, false, true}; HistogramRegistry EventsvsMultiplicity{"EventsvsMultiplicity", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; - OutputObj hProcessedEvents{TH1D("hProcessedEvents", "Strangeness - event filtered;; Number of events", 16, -1., 15.)}; + OutputObj hProcessedEvents{TH1D("hProcessedEvents", "Strangeness - event filtered;; Number of events", 17, -1., 16.)}; OutputObj hCandidate{TH1F("hCandidate", "; Candidate pass selection; Number of events", 30, 0., 30.)}; OutputObj hEvtvshMinPt{TH1F("hEvtvshMinPt", " Number of h-Omega events with pT_h higher than thrd; min p_{T, trigg} (GeV/c); Number of events", 11, 0., 11.)}; + // Dedicated selection criteria for lambda-lambda + struct : ConfigurableGroup { + Configurable cfgv0radiusMin{"cfgv0radiusMin", 1.2, "minimum decay radius"}; + Configurable cfgDCAPosToPVMin{"cfgDCAPosToPVMin", 0.05, "minimum DCA to PV for positive track"}; + Configurable cfgDCANegToPVMin{"cfgDCANegToPVMin", 0.2, "minimum DCA to PV for negative track"}; + Configurable cfgv0CosPA{"cfgv0CosPA", 0.995, "minimum v0 cosine"}; + Configurable cfgDCAV0Dau{"cfgDCAV0Dau", 1.0, "maximum DCA between daughters"}; + Configurable cfgV0PtMin{"cfgV0PtMin", 0, "minimum pT for lambda"}; + Configurable cfgV0RapMin{"cfgV0RapMin", -0.5, "maximum rapidity"}; + Configurable cfgV0RapMax{"cfgV0RapMax", 0.5, "maximum rapidity"}; + Configurable cfgV0LifeTime{"cfgV0LifeTime", 30., "maximum lambda lifetime"}; + Configurable cfgDaughTPCnclsMin{"cfgDaughTPCnclsMin", 70, "minimum fired crossed rows"}; + Configurable cfgITSNclus{"cfgITSNclus", 1, "minimum its cluster"}; + Configurable cfgRCrossedFindable{"cfgRCrossedFindable", 0.0, "minimum ratio of crossed rows over findable clusters"}; + Configurable cfgDaughPIDCutsTPCPr{"cfgDaughPIDCutsTPCPr", 5, "proton nsigma for TPC"}; + Configurable cfgDaughPIDCutsTPCPi{"cfgDaughPIDCutsTPCPi", 5, "pion nsigma for TPC"}; + Configurable cfgDaughEtaMin{"cfgDaughEtaMin", -0.8, "minimum daughter eta"}; + Configurable cfgDaughEtaMax{"cfgDaughEtaMax", 0.8, "maximum daughter eta"}; + Configurable cfgDaughPrPt{"cfgDaughPrPt", 0.5, "minimum daughter proton pt"}; + Configurable cfgDaughPiPt{"cfgDaughPiPt", 0.5, "minimum daughter pion pt"}; + Configurable cfgLambdaMassWindow{"cfgLambdaMassWindow", 0.01, "window for lambda mass selection"}; + Configurable cfgCompV0Rej{"cfgCompV0Rej", 0.01, "competing V0 rejection"}; + Configurable cfgMinCPAV0V0{"cfgMinCPAV0V0", 0.8, "minimum CPA of v0v0"}; + Configurable cfgMaxRadiusV0V0{"cfgMaxRadiusV0V0", 10.0, "maximum radius of v0v0"}; + Configurable cfgMaxDistanceV0V0{"cfgMaxDistanceV0V0", 5.0, "maximum distance of v0v0"}; + Configurable cfgMaxDCAV0V0{"cfgMaxDCAV0V0", 5.0, "maximum DCA of v0v0"}; + } cfgLLCuts; + // Selection criteria for cascades Configurable useCascadeMomentumAtPrimVtx{"useCascadeMomentumAtPrimVtx", false, "use cascade momentum at PV"}; Configurable doextraQA{"doextraQA", 1, "do extra QA"}; @@ -178,6 +208,81 @@ struct strangenessFilter { return track.pt() > hMinPt && std::abs(track.eta()) < hEta && track.tpcNClsCrossedRows() >= tpcmincrossedrows && track.tpcCrossedRowsOverFindableCls() >= 0.8f && track.tpcChi2NCl() <= 4.f && track.itsChi2NCl() <= 36.f && (track.itsClusterMap() & 0x7) != 0; } + float getV0V0DCA(TVector3 v01pos, TVector3 v01mom, TVector3 v02pos, TVector3 v02mom) + { + TVector3 posdiff = v02pos - v01pos; + TVector3 cross = v01mom.Cross(v02mom); + TVector3 dcaVec = (posdiff.Dot(cross) / cross.Mag2()) * cross; + return dcaVec.Mag(); + } + float getV0V0CPA(TVector3 v01mom, TVector3 v02mom) + { + return v01mom.Dot(v02mom) / (v01mom.Mag() * v02mom.Mag()); + } + float getV0V0Distance(TVector3 v01pos, TVector3 v02pos) + { + TVector3 posdiff = v02pos - v01pos; + return posdiff.Mag(); + } + float getV0V0Radius(TVector3 v01pos, TVector3 v01mom, TVector3 v02pos, TVector3 v02mom) + { + TVector3 posdiff = v02pos - v01pos; + v01mom *= 1. / v01mom.Mag(); + v02mom *= 1. / v02mom.Mag(); + float dd = 1. - TMath::Power(v01mom.Dot(v02mom), 2); + if (dd < 1e-5) + return 999; + float tt = posdiff.Dot(v01mom - v01mom.Dot(v02mom) * v02mom) / dd; + float ss = -posdiff.Dot(v02mom - v01mom.Dot(v02mom) * v01mom) / dd; + TVector3 radVec = v01pos + v02pos + tt * v01mom + ss * v02mom; + radVec *= 0.5; + return radVec.Mag(); + } + bool isSelectedV0V0(TVector3 v01pos, TVector3 v01mom, TVector3 v02pos, TVector3 v02mom) + { + if (getV0V0DCA(v01pos, v01mom, v02pos, v02mom) > cfgLLCuts.cfgMaxDCAV0V0) + return false; + if (getV0V0CPA(v01mom, v02mom) < cfgLLCuts.cfgMinCPAV0V0) + return false; + if (getV0V0Distance(v01pos, v02pos) > cfgLLCuts.cfgMaxDistanceV0V0) + return false; + if (getV0V0Radius(v01pos, v01mom, v02pos, v02mom) > cfgLLCuts.cfgMaxRadiusV0V0) + return false; + + return true; + } + + template + bool isSelectedV0Daughter(T const& track) + { + if (track.tpcNClsCrossedRows() < cfgLLCuts.cfgDaughTPCnclsMin) + return false; + if (track.tpcCrossedRowsOverFindableCls() < cfgLLCuts.cfgRCrossedFindable) + return false; + if (track.itsNCls() < cfgLLCuts.cfgITSNclus) + return false; + if (track.eta() > cfgLLCuts.cfgDaughEtaMax) + return false; + if (track.eta() < cfgLLCuts.cfgDaughEtaMin) + return false; + + return true; + } + template + bool isSelectedV0DaughterPID(T const& track, int pid) // pid 0: proton, pid 1: pion + { + if (pid == 0 && std::abs(track.tpcNSigmaPr()) > cfgLLCuts.cfgDaughPIDCutsTPCPr) + return false; + if (pid == 1 && std::abs(track.tpcNSigmaPi()) > cfgLLCuts.cfgDaughPIDCutsTPCPi) + return false; + if (pid == 0 && track.pt() < cfgLLCuts.cfgDaughPrPt) + return false; + if (pid == 1 && track.pt() < cfgLLCuts.cfgDaughPiPt) + return false; + + return true; + } + void init(o2::framework::InitContext&) { // set V0 parameters in the helper @@ -223,6 +328,7 @@ struct strangenessFilter { hProcessedEvents->GetXaxis()->SetBinLabel(14, aod::filtering::OmegaHighMult::columnLabel()); hProcessedEvents->GetXaxis()->SetBinLabel(15, aod::filtering::DoubleOmega::columnLabel()); hProcessedEvents->GetXaxis()->SetBinLabel(16, aod::filtering::OmegaXi::columnLabel()); + hProcessedEvents->GetXaxis()->SetBinLabel(17, "LL"); hCandidate->GetXaxis()->SetBinLabel(1, "All"); hCandidate->GetXaxis()->SetBinLabel(2, "PassBuilderSel"); @@ -449,14 +555,14 @@ struct strangenessFilter { void fillTriggerTable(bool keepEvent[]) { - strgtable(keepEvent[0], keepEvent[1], keepEvent[2], keepEvent[3], keepEvent[4], keepEvent[5], keepEvent[6], keepEvent[7], keepEvent[8], keepEvent[9], keepEvent[10], keepEvent[11]); + strgtable(keepEvent[0], keepEvent[1], keepEvent[2], keepEvent[3], keepEvent[4], keepEvent[5], keepEvent[6], keepEvent[7], keepEvent[8], keepEvent[9], keepEvent[10], keepEvent[11], keepEvent[12]); } - void process(CollisionCandidates const& collision, TrackCandidates const& tracks, aod::Cascades const& cascadesBase, aod::AssignedTrackedCascades const& trackedCascades, aod::AssignedTrackedV0s const& /*trackedV0s*/, aod::AssignedTracked3Bodys const& /*tracked3Bodys*/, aod::V0s const&, aod::BCs const&, aod::FT0s const& /*ft0s*/) + void process(CollisionCandidates const& collision, TrackCandidates const& tracks, aod::Cascades const& cascadesBase, aod::AssignedTrackedCascades const& trackedCascades, aod::AssignedTrackedV0s const& /*trackedV0s*/, aod::AssignedTracked3Bodys const& /*tracked3Bodys*/, aod::V0s const& v0Base, aod::BCs const&, aod::FT0s const& /*ft0s*/) { // Is event good? [0] = Omega, [1] = high-pT hadron + Omega, [2] = 2Xi, [3] = 3Xi, [4] = 4Xi, [5] single-Xi, [6] Omega with high radius // [7] tracked Xi, [8] tracked Omega, [9] Omega + high mult event - bool keepEvent[12]{}; // explicitly zero-initialised + bool keepEvent[13]{}; // explicitly zero-initialised std::vector> v0sFromOmegaID; std::vector> v0sFromXiID; @@ -573,6 +679,102 @@ struct strangenessFilter { const auto primaryVertex = getPrimaryVertex(collision); o2::dataformats::DCA impactParameterTrk; + std::vector> v0sSelTuple; + for (auto& v00 : v0Base) { // loop over v0 for pre selection + hCandidate->Fill(0.5); // All candidates + + if (v00.v0Type() != 1) { + continue; + } + + const auto posTrack0 = v00.posTrack_as(); + const auto negTrack0 = v00.negTrack_as(); + + if (!isSelectedV0Daughter(posTrack0) || !isSelectedV0Daughter(negTrack0)) { + continue; + } + + auto trackParPos0 = getTrackParCov(posTrack0); + auto trackParNeg0 = getTrackParCov(negTrack0); + + if (!mStraHelper.buildV0Candidate(v00.collisionId(), pvPos[0], pvPos[1], pvPos[2], posTrack0, negTrack0, trackParPos0, trackParNeg0)) { + continue; + } + + if (std::hypot(mStraHelper.v0.position[0], mStraHelper.v0.position[1]) < cfgLLCuts.cfgv0radiusMin) { + continue; + } + if (std::fabs(mStraHelper.v0.positiveDCAxy) < cfgLLCuts.cfgDCAPosToPVMin) { + continue; + } + if (std::fabs(mStraHelper.v0.negativeDCAxy) < cfgLLCuts.cfgDCANegToPVMin) { + continue; + } + if (TMath::Cos(mStraHelper.v0.pointingAngle) < cfgLLCuts.cfgv0CosPA) { + continue; + } + if (std::fabs(mStraHelper.v0.daughterDCA) > cfgLLCuts.cfgDCAV0Dau) { + continue; + } + if (std::hypot(mStraHelper.v0.momentum[0], mStraHelper.v0.momentum[1]) < cfgLLCuts.cfgV0PtMin) { + continue; + } + double yLambda = RecoDecay::y(array{mStraHelper.v0.momentum[0], mStraHelper.v0.momentum[1], mStraHelper.v0.momentum[2]}, o2::constants::physics::MassLambda0); + if (yLambda < cfgLLCuts.cfgV0RapMin) { + continue; + } + if (yLambda > cfgLLCuts.cfgV0RapMax) { + continue; + } + double distovertotmom = std::hypot(mStraHelper.v0.position[0] - collision.posX(), mStraHelper.v0.position[1] - collision.posY(), mStraHelper.v0.position[2] - collision.posZ()) / (std::hypot(mStraHelper.v0.momentum[0], mStraHelper.v0.momentum[1], mStraHelper.v0.momentum[2]) + 1e-13); + if (distovertotmom * o2::constants::physics::MassLambda0 > cfgLLCuts.cfgV0LifeTime) { + continue; + } + + int Tag = 0; + if (isSelectedV0DaughterPID(posTrack0, 0) && isSelectedV0DaughterPID(negTrack0, 1)) { + if (cfgLLCuts.cfgLambdaMassWindow > std::fabs(mStraHelper.v0.massLambda - o2::constants::physics::MassLambda0)) { + if (cfgLLCuts.cfgCompV0Rej < std::fabs(mStraHelper.v0.massK0Short - o2::constants::physics::MassLambda0)) { + Tag++; + } + } + } // lambda + if (isSelectedV0DaughterPID(posTrack0, 1) && isSelectedV0DaughterPID(negTrack0, 0)) { + if (cfgLLCuts.cfgLambdaMassWindow > std::fabs(mStraHelper.v0.massAntiLambda - o2::constants::physics::MassLambda0)) { + if (cfgLLCuts.cfgCompV0Rej < std::fabs(mStraHelper.v0.massK0Short - o2::constants::physics::MassLambda0)) { + Tag++; + } + } + } // anti lambda + if (Tag != 1) { // Select when only one hypothesis is satisfied + continue; + } + + TVector3 v0pos(mStraHelper.v0.position[0], mStraHelper.v0.position[1], mStraHelper.v0.position[2]); + TVector3 v0mom(mStraHelper.v0.momentum[0], mStraHelper.v0.momentum[1], mStraHelper.v0.momentum[2]); + + v0sSelTuple.emplace_back(posTrack0.globalIndex(), negTrack0.globalIndex(), v0pos, v0mom); + } + + for (size_t i = 0; i < v0sSelTuple.size(); ++i) { + for (size_t j = i + 1; j < v0sSelTuple.size(); ++j) { + auto d00 = std::get<0>(v0sSelTuple[i]); + auto d01 = std::get<1>(v0sSelTuple[i]); + auto d10 = std::get<0>(v0sSelTuple[j]); + auto d11 = std::get<1>(v0sSelTuple[j]); + if (d00 == d10 || d00 == d11 || d01 == d10 || d01 == d11) { + continue; + } + auto v00pos = std::get<2>(v0sSelTuple[i]); + auto v00mom = std::get<3>(v0sSelTuple[i]); + auto v01pos = std::get<2>(v0sSelTuple[j]); + auto v01mom = std::get<3>(v0sSelTuple[j]); + if (isSelectedV0V0(v00pos, v00mom, v01pos, v01mom)) { + keepEvent[12] = true; + } + } + } + for (auto& casc : cascadesBase) { // loop over cascades hCandidate->Fill(0.5); // All candidates @@ -1149,7 +1351,9 @@ struct strangenessFilter { if (keepEvent[11]) { hProcessedEvents->Fill(14.5); } - + if (keepEvent[12]) { + hProcessedEvents->Fill(15.5); + } // Filling the table fillTriggerTable(keepEvent); } diff --git a/EventFiltering/filterTables.h b/EventFiltering/filterTables.h index 7ec3b46ccaa..7200c4f7347 100644 --- a/EventFiltering/filterTables.h +++ b/EventFiltering/filterTables.h @@ -102,15 +102,28 @@ DECLARE_SOA_COLUMN(HfBtoJPsiPrKa, hasHfBtoJPsiPrKa, bool); DECLARE_SOA_COLUMN(HfBtoJPsiPi, hasHfBtoJPsiPi, bool); //! Bc -> JPsi(->mumu)pi+ // CF two body triggers -DECLARE_SOA_COLUMN(PD, hasPD, bool); //! has d-p pair -DECLARE_SOA_COLUMN(LD, hasLD, bool); //! has l-d pair +DECLARE_SOA_COLUMN(PD_TightKstar, hasPD_TightKstar, bool); //! has d-p pair with tight kstar limit +DECLARE_SOA_COLUMN(PD_LooseKstar, hasPD_LooseKstar, bool); //! has d-p pair with loose kstar limit +DECLARE_SOA_COLUMN(LD_TightKstar, hasLD_TightKstar, bool); //! has l-d pair with tight kstar limit +DECLARE_SOA_COLUMN(LD_LooseKstar, hasLD_LooseKstar, bool); //! has l-d pair with loose kstar limit +DECLARE_SOA_COLUMN(PHID_TightKstar, hasPHID_TightKstar, bool); //! has phi-d pair with tight kstar limit +DECLARE_SOA_COLUMN(PHID_LooseKstar, hasPHID_LooseKstar, bool); //! has phi-d pair with loose kstar limit +DECLARE_SOA_COLUMN(RHOD_TightKstar, hasRHOD_TightKstar, bool); //! has rho-d pair with tight kstar limit +DECLARE_SOA_COLUMN(RHOD_LooseKstar, hasRHOD_LooseKstar, bool); //! has rho-d pair with loose kstar limit // CF three body triggers -DECLARE_SOA_COLUMN(PPP, hasPPP, bool); //! has p-p-p triplet -DECLARE_SOA_COLUMN(PPL, hasPPL, bool); //! has p-p-L triplet -DECLARE_SOA_COLUMN(PLL, hasPLL, bool); //! has p-L-L triplet -DECLARE_SOA_COLUMN(LLL, hasLLL, bool); //! has L-L-L tripletD -DECLARE_SOA_COLUMN(PPPHI, hasPPPHI, bool); //! has P-P-PHI triplet +DECLARE_SOA_COLUMN(PPP_TightQ3, hasPPP_TightQ3, bool); //! has p-p-p triplet with tight Q3 limit +DECLARE_SOA_COLUMN(PPP_LooseQ3, hasPPP_LooseQ3, bool); //! has p-p-p triplet with loose Q3 limit +DECLARE_SOA_COLUMN(PPL_TightQ3, hasPPL_TightQ3, bool); //! has p-p-L triplet with tight Q3 limit +DECLARE_SOA_COLUMN(PPL_LooseQ3, hasPPL_LooseQ3, bool); //! has p-p-L triplet with loose Q3 limit +DECLARE_SOA_COLUMN(PLL_TightQ3, hasPLL_TightQ3, bool); //! has p-L-L triplet with tight Q3 limit +DECLARE_SOA_COLUMN(PLL_LooseQ3, hasPLL_LooseQ3, bool); //! has p-L-L triplet with loose Q3 limit +DECLARE_SOA_COLUMN(LLL_TightQ3, hasLLL_TightQ3, bool); //! has L-L-L tripletD with tight Q3 limit +DECLARE_SOA_COLUMN(LLL_LooseQ3, hasLLL_LooseQ3, bool); //! has L-L-L tripletD with loose Q3 limit +DECLARE_SOA_COLUMN(PPPHI_TightQ3, hasPPPHI_TightQ3, bool); //! has P-P-PHI triplet with tight Q3 limit +DECLARE_SOA_COLUMN(PPPHI_LooseQ3, hasPPPHI_LooseQ3, bool); //! has P-P-PHI triplet with loose Q3 limit +DECLARE_SOA_COLUMN(PPRHO_TightQ3, hasPPRHO_TightQ3, bool); //! has P-P-RHO triplet with tight Q3 limit +DECLARE_SOA_COLUMN(PPRHO_LooseQ3, hasPPRHO_highQ3, bool); //! has P-P-RHO triplet with loose Q3 limit // jets DECLARE_SOA_COLUMN(JetChLowPt, hasJetChLowPt, bool); //! low-pT charged jet @@ -154,6 +167,7 @@ DECLARE_SOA_COLUMN(TrackedXi, hasTrackedXi, bool); //! at least 1 DECLARE_SOA_COLUMN(TrackedOmega, hasTrackedOmega, bool); //! at least 1 tracked Omega DECLARE_SOA_COLUMN(Tracked3Body, hasTracked3Body, bool); //! at least 1 tracked 3Body DECLARE_SOA_COLUMN(OmegaHighMult, hasOmegaHighMult, bool); //! at least 1 Omega + high-mult event +DECLARE_SOA_COLUMN(LambdaLambda, lambdaLambda, bool); //! at least 2 lambda satisfying selection // F1-proton DECLARE_SOA_COLUMN(TriggerEventF1Proton, triggereventf1proton, bool); //! F1 - proton femto trigger event @@ -182,14 +196,16 @@ DECLARE_SOA_COLUMN(PCMHighPtPhoton, hasPCMHighPtPhoton, bool); //! PCM high pT p DECLARE_SOA_COLUMN(PCMandEE, hasPCMandEE, bool); //! PCM and ee // heavy meson filters -DECLARE_SOA_COLUMN(PCMOmegaMeson, hasPCMOmegaMeson, bool); //! Omega meson candidate (3pi) in the collision -DECLARE_SOA_COLUMN(EMCOmegaMeson, hasEMCOmegaMeson, bool); //! Omega meson candidate (3pi) in the collision -DECLARE_SOA_COLUMN(PCMEtaPrimeMeson, hasPCMEtaPrimeMeson, bool); //! Eta' meson candidate (3pi) in the collision -DECLARE_SOA_COLUMN(EMCEtaPrimeMeson, hasEMCEtaPrimeMeson, bool); //! Eta' meson candidate (3pi) in the collision -DECLARE_SOA_COLUMN(PPOmega, hasPPOmega, bool); //! PPomega meson candidate (3pi) in the collision -DECLARE_SOA_COLUMN(PPEtaPrime, hasPPEtaPrime, bool); //! PPEta' meson candidate (3pi) in the collision -DECLARE_SOA_COLUMN(Omegad, hasOmegad, bool); //! Omegad' meson candidate (3pi) in the collision -DECLARE_SOA_COLUMN(EtaPrimed, hasEtaPrimed, bool); //! Eta'd meson candidate (3pi) in the collision +// DECLARE_SOA_COLUMN(PCMOmegaMeson, hasPCMOmegaMeson, bool); //! Omega meson candidate (3pi) in the collision +// DECLARE_SOA_COLUMN(EMCOmegaMeson, hasEMCOmegaMeson, bool); //! Omega meson candidate (3pi) in the collision +// DECLARE_SOA_COLUMN(PCMEtaPrimeMeson, hasPCMEtaPrimeMeson, bool); //! Eta' meson candidate (3pi) in the collision +// DECLARE_SOA_COLUMN(EMCEtaPrimeMeson, hasEMCEtaPrimeMeson, bool); //! Eta' meson candidate (3pi) in the collision +DECLARE_SOA_COLUMN(OmegaP, hasOmegaP, bool); //! omegaP meson candidate (3pi) in the collision +DECLARE_SOA_COLUMN(OmegaPP, hasOmegaPP, bool); //! omegaPP meson candidate (3pi) in the collision +DECLARE_SOA_COLUMN(Omegad, hasOmegad, bool); //! omegad meson candidate (3pi) in the collision +DECLARE_SOA_COLUMN(EtaPrimeP, hasEtaPrimeP, bool); //! eta'P meson candidate (3pi) in the collision +DECLARE_SOA_COLUMN(EtaPrimePP, hasEtaPrimePP, bool); //! eta'PP meson candidate (3pi) in the collision +DECLARE_SOA_COLUMN(EtaPrimed, hasEtaPrimed, bool); //! eta'd meson candidate (3pi) in the collision } // namespace filtering @@ -268,7 +284,17 @@ DECLARE_SOA_TABLE(HfFilters, "AOD", "HfFilters", //! using HfFilter = HfFilters::iterator; DECLARE_SOA_TABLE(CFFilters, "AOD", "CFFilters", //! - filtering::PPP, filtering::PPL, filtering::PLL, filtering::LLL, filtering::PPPHI, filtering::PD, filtering::LD); + filtering::PPP_TightQ3, filtering::PPP_LooseQ3, + filtering::PPL_TightQ3, filtering::PPL_LooseQ3, + filtering::PLL_TightQ3, filtering::PLL_LooseQ3, + filtering::LLL_TightQ3, filtering::LLL_LooseQ3, + filtering::PPPHI_TightQ3, filtering::PPPHI_LooseQ3, + filtering::PPRHO_TightQ3, filtering::PPRHO_LooseQ3, + filtering::PD_TightKstar, filtering::PD_LooseKstar, + filtering::LD_TightKstar, filtering::LD_LooseKstar, + filtering::PHID_TightKstar, filtering::PHID_LooseKstar, + filtering::RHOD_TightKstar, filtering::RHOD_LooseKstar); + using CfFilter = CFFilters::iterator; // jets @@ -295,7 +321,7 @@ using FullJetFilter = FullJetFilters::iterator; // strangeness (lf) DECLARE_SOA_TABLE(StrangenessFilters, "AOD", "LFStrgFilters", //! - filtering::Omega, filtering::hadronOmega, filtering::DoubleXi, filtering::TripleXi, filtering::QuadrupleXi, filtering::SingleXiYN, filtering::OmegaLargeRadius, filtering::TrackedXi, filtering::TrackedOmega, filtering::OmegaHighMult, filtering::DoubleOmega, filtering::OmegaXi); + filtering::Omega, filtering::hadronOmega, filtering::DoubleXi, filtering::TripleXi, filtering::QuadrupleXi, filtering::SingleXiYN, filtering::OmegaLargeRadius, filtering::TrackedXi, filtering::TrackedOmega, filtering::OmegaHighMult, filtering::DoubleOmega, filtering::OmegaXi, filtering::LambdaLambda); using StrangenessFilter = StrangenessFilters::iterator; @@ -305,7 +331,7 @@ DECLARE_SOA_TABLE(F1ProtonFilters, "AOD", "F1ProtonFilters", //! using F1ProtonFilter = F1ProtonFilters::iterator; // Double Phi -DECLARE_SOA_TABLE(DoublePhiFilters, "AOD", "DoublePhiFilters", //! +DECLARE_SOA_TABLE(DoublePhiFilters, "AOD", "LF2PhiFilters", //! filtering::TriggerEventDoublePhi); using DoublePhiFilter = DoublePhiFilters::iterator; @@ -323,10 +349,8 @@ using PhotonFilter = PhotonFilters::iterator; // heavy mesons DECLARE_SOA_TABLE(HeavyNeutralMesonFilters, "AOD", "HeavyNeutralMesonFilters", //! - filtering::PCMOmegaMeson, filtering::EMCOmegaMeson, - filtering::PCMEtaPrimeMeson, filtering::EMCEtaPrimeMeson, - filtering::PPOmega, filtering::PPEtaPrime, - filtering::Omegad, filtering::EtaPrimed); + filtering::OmegaP, filtering::OmegaPP, filtering::Omegad, + filtering::EtaPrimeP, filtering::EtaPrimePP, filtering::EtaPrimed); using HeavyNeutralMesonFilter = HeavyNeutralMesonFilters::iterator; @@ -343,7 +367,7 @@ using BCRange = BCRanges::iterator; /// List of the available filters, the description of their tables and the name of the tasks constexpr int NumberOfFilters{14}; constexpr std::array AvailableFilters{"NucleiFilters", "DiffractionFilters", "DqFilters", "HfFilters", "CFFilters", "JetFilters", "JetHFFilters", "FullJetFilters", "StrangenessFilters", "MultFilters", "PhotonFilters", "F1ProtonFilters", "DoublePhiFilters", "HeavyNeutralMesonFilters"}; -constexpr std::array FilterDescriptions{"NucleiFilters", "DiffFilters", "DqFilters", "HfFilters", "CFFilters", "JetFilters", "JetHFFilters", "FullJetFilters", "LFStrgFilters", "MultFilters", "PhotonFilters", "F1ProtonFilters", "2PhiFilters", "HNMesonFilters"}; +constexpr std::array FilterDescriptions{"NucleiFilters", "DiffFilters", "DqFilters", "HfFilters", "CFFilters", "JetFilters", "JetHFFilters", "FullJetFilters", "LFStrgFilters", "MultFilters", "PhotonFilters", "F1ProtonFilters", "LF2PhiFilters", "HNMesonFilters"}; constexpr std::array FilteringTaskNames{"o2-analysis-nuclei-filter", "o2-analysis-diffraction-filter", "o2-analysis-dq-filter-pp-with-association", "o2-analysis-hf-filter", "o2-analysis-cf-filter", "o2-analysis-je-filter", "o2-analysis-je-hf-filter", "o2-analysis-fje-filter", "o2-analysis-lf-strangeness-filter", "o2-analysis-mult-filter", "o2-analysis-em-photon-filter", "o2-analysis-lf-f1proton-filter", "o2-analysis-lf-doublephi-filter", "o2-analysis-heavy-meson-filter"}; constexpr o2::framework::pack FiltersPack; static_assert(o2::framework::pack_size(FiltersPack) == NumberOfFilters); diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniverseEfficiencyBase.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniverseEfficiencyBase.cxx index cad94a05c60..490540b9dea 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniverseEfficiencyBase.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniverseEfficiencyBase.cxx @@ -30,65 +30,89 @@ using namespace o2::framework; using namespace o2::framework::expressions; using namespace o2::soa; -struct femtoUniverseEfficiencyBase { +struct FemtoUniverseEfficiencyBase { SliceCache cache; using FemtoFullParticles = soa::Join; Preslice perCol = aod::femtouniverseparticle::fdCollisionId; - Configurable ConfIsDebug{"ConfIsDebug", true, "Enable debug histograms"}; + Configurable confIsDebug{"confIsDebug", true, "Enable debug histograms"}; // Collisions - Configurable ConfZVertex{"ConfZVertex", 10.f, "Event sel: Maximum z-Vertex (cm)"}; + Configurable confZVertex{"confZVertex", 10.f, "Event sel: Maximum z-Vertex (cm)"}; - Filter collisionFilter = (nabs(aod::collision::posZ) < ConfZVertex); + Filter collisionFilter = (nabs(aod::collision::posZ) < confZVertex); using FilteredFDCollisions = soa::Filtered; using FilteredFDCollision = FilteredFDCollisions::iterator; /// Particle selection part /// Configurables for both particles - ConfigurableAxis ConfTempFitVarpTBins{"ConfTempFitVarpTBins", {20, 0.5, 4.05}, "Binning of the pT in the pT vs. TempFitVar plot"}; - ConfigurableAxis ConfTempFitVarPDGBins{"ConfTempFitVarPDGBins", {6000, -2300, 2300}, "Binning of the PDG code in the pT vs. TempFitVar plot"}; - ConfigurableAxis ConfTempFitVarCPABins{"ConfTempFitVarCPABins", {1000, 0.9, 1}, "Binning of the pointing angle cosinus in the pT vs. TempFitVar plot"}; - ConfigurableAxis ConfTempFitVarDCABins{"ConfTempFitVarDCABins", {1000, -5, 5}, "Binning of the PDG code in the pT vs. TempFitVar plot"}; + ConfigurableAxis confTempFitVarpTBins{"confTempFitVarpTBins", {20, 0.5, 4.05}, "Binning of the pT in the pT vs. TempFitVar plot"}; + ConfigurableAxis confTempFitVarPDGBins{"confTempFitVarPDGBins", {6000, -2300, 2300}, "Binning of the PDG code in the pT vs. TempFitVar plot"}; + ConfigurableAxis confTempFitVarCPABins{"confTempFitVarCPABins", {1000, 0.9, 1}, "Binning of the pointing angle cosinus in the pT vs. TempFitVar plot"}; + ConfigurableAxis confTempFitVarDCABins{"confTempFitVarDCABins", {1000, -5, 5}, "Binning of the PDG code in the pT vs. TempFitVar plot"}; struct : o2::framework::ConfigurableGroup { - Configurable ConfEtaMax{"ConfEtaMax", 0.8f, "Higher limit for |Eta| (the same for both particles)"}; - Configurable ConfMomProton{"ConfMomProton", 0.75, "Momentum threshold for proton identification using TOF"}; - Configurable ConfMomPion{"ConfMomPion", 0.75, "Momentum threshold for pion identification using TOF"}; - Configurable ConfNsigmaCombinedProton{"ConfNsigmaCombinedProton", 3.0, "TPC and TOF Proton Sigma (combined) for momentum > ConfMomProton"}; - Configurable ConfNsigmaTPCProton{"ConfNsigmaTPCProton", 3.0, "TPC Proton Sigma for momentum < ConfMomProton"}; - Configurable ConfNsigmaCombinedPion{"ConfNsigmaCombinedPion", 3.0, "TPC and TOF Pion Sigma (combined) for momentum > ConfMomPion"}; - Configurable ConfNsigmaTPCPion{"ConfNsigmaTPCPion", 3.0, "TPC Pion Sigma for momentum < ConfMomPion"}; + Configurable confEtaMax{"confEtaMax", 0.8f, "Higher limit for |Eta| (the same for both particles)"}; + Configurable confMomProton{"confMomProton", 0.75, "Momentum threshold for proton identification using TOF"}; + Configurable confMomPion{"confMomPion", 0.75, "Momentum threshold for pion identification using TOF"}; + Configurable confNsigmaCombinedProton{"confNsigmaCombinedProton", 3.0, "TPC and TOF Proton Sigma (combined) for momentum > confMomProton"}; + Configurable confNsigmaTPCProton{"confNsigmaTPCProton", 3.0, "TPC Proton Sigma for momentum < confMomProton"}; + Configurable confNsigmaCombinedPion{"confNsigmaCombinedPion", 3.0, "TPC and TOF Pion Sigma (combined) for momentum > confMomPion"}; + Configurable confNsigmaTPCPion{"confNsigmaTPCPion", 3.0, "TPC Pion Sigma for momentum < confMomPion"}; } ConfBothTracks; /// Lambda cuts - Configurable ConfV0InvMassLowLimit{"ConfV0InvV0MassLowLimit", 1.10, "Lower limit of the V0 invariant mass"}; - Configurable ConfV0InvMassUpLimit{"ConfV0InvV0MassUpLimit", 1.13, "Upper limit of the V0 invariant mass"}; + Configurable confV0InvMassLowLimit{"confV0InvMassLowLimit", 1.10, "Lower limit of the V0 invariant mass"}; + Configurable confV0InvMassUpLimit{"confV0InvMassUpLimit", 1.13, "Upper limit of the V0 invariant mass"}; /// Kaon configurable - Configurable IsKaonRun2{"IsKaonRun2", false, "Enable kaon selection used in Run2"}; // to check consistency with Run2 results + Configurable isKaonRun2{"isKaonRun2", false, "Enable kaon selection used in Run2"}; // to check consistency with Run2 results + struct : o2::framework::ConfigurableGroup { + // Momentum thresholds for Run2 and Run3 + Configurable confMomKaonRun2{"confMomKaonRun2", 0.4, "Momentum threshold for kaon identification using ToF (Run2)"}; + Configurable confMomKaonRun3{"confMomKaonRun3", 0.3, "Momentum threshold for kaon identification using ToF (Run3)"}; + Configurable confMomKaon045{"confMomKaon045", 0.45, "Momentum threshold for kaon identification pT = 0.45 GeV/c"}; + Configurable confMomKaon055{"confMomKaon055", 0.55, "Momentum threshold for kaon identification pT = 0.55 GeV/c"}; + Configurable confMomKaon08{"confMomKaon08", 0.8, "Momentum threshold for kaon identification pT = 0.8 GeV/c"}; + Configurable confMomKaon15{"confMomKaon15", 1.5, "Momentum threshold for kaon identification pT = 1.5 GeV/c"}; + // n sigma cuts for Run 2 + Configurable confKaonNsigmaTPCbelow04Run2{"confKaonNsigmaTPCbelow04Run2", 2.0, "Reject kaons with pT below 0.4 if TPC n sigma is above this value."}; + Configurable confKaonNsigmaTPCfrom04to045Run2{"confKaonNsigmaTPCfrom04to045Run2", 1.0, "Reject kaons within pT from 0.4 to 0.45 if TPC n sigma is above this value."}; + Configurable confKaonNsigmaTPCfrom045to08Run2{"confKaonNsigmaTPCfrom045to08Run2", 3.0, "Reject kaons within pT from 0.45 to 0.8 if TPC n sigma is above this value."}; + Configurable confKaonNsigmaTOFfrom045to08Run2{"confKaonNsigmaTOFfrom045to08Run2", 2.0, "Reject kaons within pT from 0.45 to 0.8 if ToF n sigma is above this value."}; + Configurable confKaonNsigmaTPCfrom08to15Run2{"confKaonNsigmaTPCfrom08to15Run2", 3.0, "Reject kaons within pT from 0.8 to 1.5 if TPC n sigma is above this value."}; + Configurable confKaonNsigmaTOFfrom08to15Run2{"confKaonNsigmaTOFfrom08to15Run2", 1.5, "Reject kaons within pT from 0.8 to 1.5 if ToF n sigma is above this value."}; + // n sigma cuts for Run 3 + Configurable confKaonNsigmaTPCfrom0to03{"confKaonNsigmaTPCfrom0to03", 3.0, "Reject kaons within pT from 0.0 to 0.3 if TPC n sigma is above this value."}; + Configurable confKaonNsigmaTPCfrom03to045{"confKaonNsigmaTPCfrom03to045", 2.0, "Reject kaons within pT from 0.3 to 0.45 if TPC n sigma is above this value."}; + Configurable confKaonNsigmaTPCfrom045to055{"confKaonNsigmaTPCfrom045to055", 1.0, "Reject kaons within pT from 0.45 to 0.55 if TPC n sigma is above this value."}; + Configurable confKaonNsigmaTPCfrom055to15{"confKaonNsigmaTPCfrom055to15", 3.0, "Reject kaons within pT from 0.55 to 1.5 if TPC n sigma is above this value."}; + Configurable confKaonNsigmaTOFfrom055to15{"confKaonNsigmaTOFfrom055to15", 3.0, "Reject kaons within pT from 0.55 to 1.5 if ToF n sigma is above this value."}; + Configurable confKaonNsigmaTPCfrom15{"confKaonNsigmaTPCfrom15", 3.0, "Reject kaons with pT above 1.5 if TPC n sigma is above this value."}; + Configurable confKaonNsigmaTOFfrom15{"confKaonNsigmaTOFfrom15", 2.0, "Reject kaons with pT above 1.5 if ToF n sigma is above this value.."}; + } ConfKaonSelection; /// Deuteron configurables struct : o2::framework::ConfigurableGroup { - Configurable ConfNsigmaTPCDe{"ConfNsigmaTPCDe", 2.0f, "TPC Deuteron Sigma for momentum < ConfTOFpMinDe"}; - Configurable ConfNsigmaTOFDe{"ConfNsigmaTOFDe", 2.0f, "TOF Deuteron Sigma"}; - Configurable ConfTOFpMinDe{"ConfTOFpMinDe", 0.5f, "Min. momentum for deuterons for which TOF is required for PID"}; - Configurable ConfPLowDe{"ConfPLowDe", 0.8f, "Lower limit for momentum for deuterons"}; - Configurable ConfPHighDe{"ConfPHighDe", 1.8f, "Higher limit for momentum for deuterons"}; + Configurable confNsigmaTPCDe{"confNsigmaTPCDe", 2.0f, "TPC Deuteron Sigma for momentum < confTOFpMinDe"}; + Configurable confNsigmaTOFDe{"confNsigmaTOFDe", 2.0f, "TOF Deuteron Sigma"}; + Configurable confTOFpMinDe{"confTOFpMinDe", 0.5f, "Min. momentum for deuterons for which TOF is required for PID"}; + Configurable confPLowDe{"confPLowDe", 0.8f, "Lower limit for momentum for deuterons"}; + Configurable confPHighDe{"confPHighDe", 1.8f, "Higher limit for momentum for deuterons"}; } deuteronconfigs; /// Particle 1 - Configurable ConfPDGCodePartOne{"ConfPDGCodePartOne", 2212, "Particle 1 - PDG code"}; - Configurable ConfParticleTypePartOne{"ConfParticleTypePartOne", aod::femtouniverseparticle::ParticleType::kTrack, "Particle 1 - particle type: 0 - track, 2 - V0, 6 - phi"}; - Configurable ConfNoPDGPartOne{"ConfNoPDGPartOne", false, "0: selecting part one by PDG, 1: no PID selection"}; - Configurable ConfPtLowPart1{"ConfPtLowPart1", 0.2, "Lower limit for Pt for the first particle"}; - Configurable ConfPtHighPart1{"ConfPtHighPart1", 2.5, "Higher limit for Pt for the first particle"}; - Configurable ConfChargePart1{"ConfChargePart1", 1, "Charge of the first particle"}; + Configurable confPDGCodePartOne{"confPDGCodePartOne", 2212, "Particle 1 - PDG code"}; + Configurable confParticleTypePartOne{"confParticleTypePartOne", aod::femtouniverseparticle::ParticleType::kTrack, "Particle 1 - particle type: 0 - track, 2 - V0, 6 - phi"}; + Configurable confNoPDGPartOne{"confNoPDGPartOne", false, "0: selecting part one by PDG, 1: no PID selection"}; + Configurable confPtLowPart1{"confPtLowPart1", 0.2, "Lower limit for Pt for the first particle"}; + Configurable confPtHighPart1{"confPtHighPart1", 2.5, "Higher limit for Pt for the first particle"}; + Configurable confChargePart1{"confChargePart1", 1, "Charge of the first particle"}; /// Partition for particle 1 - Partition partsOneMCGen = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kMCTruthTrack)) && aod::femtouniverseparticle::pt < ConfPtHighPart1 && aod::femtouniverseparticle::pt > ConfPtLowPart1&& nabs(aod::femtouniverseparticle::eta) < ConfBothTracks.ConfEtaMax; + Partition partsOneMCGen = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kMCTruthTrack)) && (aod::femtouniverseparticle::pt < confPtHighPart1) && (aod::femtouniverseparticle::pt > confPtLowPart1) && (nabs(aod::femtouniverseparticle::eta) < ConfBothTracks.confEtaMax); - Partition partsTrackOneMCReco = aod::femtouniverseparticle::pt < ConfPtHighPart1 && aod::femtouniverseparticle::pt > ConfPtLowPart1&& nabs(aod::femtouniverseparticle::eta) < ConfBothTracks.ConfEtaMax; + Partition partsTrackOneMCReco = (aod::femtouniverseparticle::pt < confPtHighPart1) && (aod::femtouniverseparticle::pt > confPtLowPart1) && (nabs(aod::femtouniverseparticle::eta) < ConfBothTracks.confEtaMax); /// Histogramming for particle 1 FemtoUniverseParticleHisto trackHistoPartOneGen; @@ -98,18 +122,18 @@ struct femtoUniverseEfficiencyBase { FemtoUniverseParticleHisto trackHistoV0OneChildNegRec; /// Particle 2 - Configurable ConfIsSame{"ConfIsSame", false, "Pairs of the same particle"}; - Configurable ConfPDGCodePartTwo{"ConfPDGCodePartTwo", 333, "Particle 2 - PDG code"}; - Configurable ConfParticleTypePartTwo{"ConfParticleTypePartTwo", aod::femtouniverseparticle::ParticleType::kTrack, "Particle 2 - particle type: 0 - track, 2 - V0, 6 - phi"}; - Configurable ConfNoPDGPartTwo{"ConfNoPDGPartTwo", false, "0: selecting part two by PDG, 1: no PID selection"}; - Configurable ConfPtLowPart2{"ConfPtLowPart2", 0.2, "Lower limit for Pt for the second particle"}; - Configurable ConfPtHighPart2{"ConfPtHighPart2", 2.5, "Higher limit for Pt for the second particle"}; - Configurable ConfChargePart2{"ConfChargePart2", 1, "Charge of the second particle"}; + Configurable confIsSame{"confIsSame", false, "Pairs of the same particle"}; + Configurable confPDGCodePartTwo{"confPDGCodePartTwo", 333, "Particle 2 - PDG code"}; + Configurable confParticleTypePartTwo{"confParticleTypePartTwo", aod::femtouniverseparticle::ParticleType::kTrack, "Particle 2 - particle type: 0 - track, 2 - V0, 6 - phi"}; + Configurable confNoPDGPartTwo{"confNoPDGPartTwo", false, "0: selecting part two by PDG, 1: no PID selection"}; + Configurable confPtLowPart2{"confPtLowPart2", 0.2, "Lower limit for Pt for the second particle"}; + Configurable confPtHighPart2{"confPtHighPart2", 2.5, "Higher limit for Pt for the second particle"}; + Configurable confChargePart2{"confChargePart2", 1, "Charge of the second particle"}; /// Partition for particle 2 - Partition partsTwoGen = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kMCTruthTrack)) && aod::femtouniverseparticle::pt < ConfPtHighPart2 && aod::femtouniverseparticle::pt > ConfPtLowPart2&& nabs(aod::femtouniverseparticle::eta) < ConfBothTracks.ConfEtaMax; + Partition partsTwoMCGen = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kMCTruthTrack)) && (aod::femtouniverseparticle::pt < confPtHighPart2) && (aod::femtouniverseparticle::pt > confPtLowPart2) && (nabs(aod::femtouniverseparticle::eta) < ConfBothTracks.confEtaMax); - Partition partsTrackTwoMCReco = aod::femtouniverseparticle::pt < ConfPtHighPart2 && aod::femtouniverseparticle::pt > ConfPtLowPart2&& nabs(aod::femtouniverseparticle::eta) < ConfBothTracks.ConfEtaMax; + Partition partsTrackTwoMCReco = (aod::femtouniverseparticle::pt < confPtHighPart2) && (aod::femtouniverseparticle::pt > confPtLowPart2) && (nabs(aod::femtouniverseparticle::eta) < ConfBothTracks.confEtaMax); /// Histogramming for particle 2 FemtoUniverseParticleHisto trackHistoPartTwoGen; @@ -132,43 +156,43 @@ struct femtoUniverseEfficiencyBase { { eventHisto.init(&qaRegistry); - trackHistoPartOneGen.init(&qaRegistry, ConfTempFitVarpTBins, ConfTempFitVarPDGBins, 0, ConfPDGCodePartOne, false); - trackHistoPartOneRec.init(&qaRegistry, ConfTempFitVarpTBins, ConfTempFitVarDCABins, 0, ConfPDGCodePartOne, ConfIsDebug); + trackHistoPartOneGen.init(&qaRegistry, confTempFitVarpTBins, confTempFitVarPDGBins, 0, confPDGCodePartOne, false); + trackHistoPartOneRec.init(&qaRegistry, confTempFitVarpTBins, confTempFitVarDCABins, 0, confPDGCodePartOne, confIsDebug); registryMCOrigin.add("part1/hPt", " ;#it{p}_{T} (GeV/c); Entries", {HistType::kTH1F, {{240, 0, 6}}}); registryPDG.add("part1/PDGvspT", "PDG;#it{p}_{T} (GeV/c); PDG", {HistType::kTH2F, {{500, 0, 5}, {16001, -8000.5, 8000.5}}}); - if (ConfParticleTypePartOne == uint8_t(aod::femtouniverseparticle::ParticleType::kV0)) { - trackHistoV0OneRec.init(&qaRegistry, ConfTempFitVarpTBins, ConfTempFitVarCPABins, 0, ConfPDGCodePartOne, ConfIsDebug); - trackHistoV0OneChildPosRec.init(&qaRegistry, ConfTempFitVarpTBins, ConfTempFitVarDCABins, 0, 0, ConfIsDebug, "posChildV0_1"); - trackHistoV0OneChildNegRec.init(&qaRegistry, ConfTempFitVarpTBins, ConfTempFitVarDCABins, 0, 0, ConfIsDebug, "negChildV0_1"); + if (confParticleTypePartOne == uint8_t(aod::femtouniverseparticle::ParticleType::kV0)) { + trackHistoV0OneRec.init(&qaRegistry, confTempFitVarpTBins, confTempFitVarCPABins, 0, confPDGCodePartOne, confIsDebug); + trackHistoV0OneChildPosRec.init(&qaRegistry, confTempFitVarpTBins, confTempFitVarDCABins, 0, 0, confIsDebug, "posChildV0_1"); + trackHistoV0OneChildNegRec.init(&qaRegistry, confTempFitVarpTBins, confTempFitVarDCABins, 0, 0, confIsDebug, "negChildV0_1"); registryPDG.add("part1/dpositive/PDGvspT", "PDG;#it{p}_{T} (GeV/c); PDG", {HistType::kTH2F, {{500, 0, 5}, {16001, -8000.5, 8000.5}}}); registryPDG.add("part1/dnegative/PDGvspT", "PDG;#it{p}_{T} (GeV/c); PDG", {HistType::kTH2F, {{500, 0, 5}, {16001, -8000.5, 8000.5}}}); } registryPDG.add("part2/PDGvspT", "PDG;#it{p}_{T} (GeV/c); PDG", {HistType::kTH2F, {{500, 0, 5}, {16001, -8000.5, 8000.5}}}); - if (!ConfIsSame) { - trackHistoPartTwoGen.init(&qaRegistry, ConfTempFitVarpTBins, ConfTempFitVarPDGBins, 0, ConfPDGCodePartTwo, false); - trackHistoPartTwoRec.init(&qaRegistry, ConfTempFitVarpTBins, ConfTempFitVarDCABins, 0, ConfPDGCodePartTwo, ConfIsDebug); + if (!confIsSame) { + trackHistoPartTwoGen.init(&qaRegistry, confTempFitVarpTBins, confTempFitVarPDGBins, 0, confPDGCodePartTwo, false); + trackHistoPartTwoRec.init(&qaRegistry, confTempFitVarpTBins, confTempFitVarDCABins, 0, confPDGCodePartTwo, confIsDebug); registryMCOrigin.add("part2/hPt", " ;#it{p}_{T} (GeV/c); Entries", {HistType::kTH1F, {{240, 0, 6}}}); - if (ConfParticleTypePartTwo == uint8_t(aod::femtouniverseparticle::ParticleType::kV0)) { - trackHistoV0TwoRec.init(&qaRegistry, ConfTempFitVarpTBins, ConfTempFitVarCPABins, 0, ConfPDGCodePartTwo, ConfIsDebug); - trackHistoV0TwoChildPosRec.init(&qaRegistry, ConfTempFitVarpTBins, ConfTempFitVarDCABins, 0, 0, ConfIsDebug, "posChildV0_2"); - trackHistoV0TwoChildNegRec.init(&qaRegistry, ConfTempFitVarpTBins, ConfTempFitVarDCABins, 0, 0, ConfIsDebug, "negChildV0_2"); + if (confParticleTypePartTwo == uint8_t(aod::femtouniverseparticle::ParticleType::kV0)) { + trackHistoV0TwoRec.init(&qaRegistry, confTempFitVarpTBins, confTempFitVarCPABins, 0, confPDGCodePartTwo, confIsDebug); + trackHistoV0TwoChildPosRec.init(&qaRegistry, confTempFitVarpTBins, confTempFitVarDCABins, 0, 0, confIsDebug, "posChildV0_2"); + trackHistoV0TwoChildNegRec.init(&qaRegistry, confTempFitVarpTBins, confTempFitVarDCABins, 0, 0, confIsDebug, "negChildV0_2"); registryPDG.add("part2/dpositive/PDGvspT", "PDG;#it{p}_{T} (GeV/c); PDG", {HistType::kTH2F, {{500, 0, 5}, {16001, -8000.5, 8000.5}}}); registryPDG.add("part2/dnegative/PDGvspT", "PDG;#it{p}_{T} (GeV/c); PDG", {HistType::kTH2F, {{500, 0, 5}, {16001, -8000.5, 8000.5}}}); } } } - bool IsProtonNSigma(float mom, float nsigmaTPCPr, float nsigmaTOFPr) // previous version from: https://github.com/alisw/AliPhysics/blob/master/PWGCF/FEMTOSCOPY/AliFemtoUser/AliFemtoMJTrackCut.cxx + bool isProtonNSigma(float mom, float nsigmaTPCPr, float nsigmaTOFPr) // previous version from: https://github.com/alisw/AliPhysics/blob/master/PWGCF/FEMTOSCOPY/AliFemtoUser/AliFemtoMJTrackCut.cxx { - if (mom < ConfBothTracks.ConfMomProton) { - if (TMath::Abs(nsigmaTPCPr) < ConfBothTracks.ConfNsigmaTPCProton) { + if (mom < ConfBothTracks.confMomProton) { + if (std::abs(nsigmaTPCPr) < ConfBothTracks.confNsigmaTPCProton) { return true; } else { return false; } } else { - if (TMath::Hypot(nsigmaTOFPr, nsigmaTPCPr) < ConfBothTracks.ConfNsigmaCombinedProton) { + if (std::hypot(nsigmaTOFPr, nsigmaTPCPr) < ConfBothTracks.confNsigmaCombinedProton) { return true; } else { return false; @@ -177,49 +201,49 @@ struct femtoUniverseEfficiencyBase { return false; } - bool IsKaonNSigma(float mom, float nsigmaTPCK, float nsigmaTOFK) + bool isKaonNSigma(float mom, float nsigmaTPCK, float nsigmaTOFK) { - if (IsKaonRun2 == true) { - if (mom < 0.4) { - return TMath::Abs(nsigmaTPCK) < 2; - } else if (mom > 0.4 && mom < 0.45) { - return TMath::Abs(nsigmaTPCK) < 1; - } else if (mom > 0.45 && mom < 0.8) { - return (TMath::Abs(nsigmaTPCK) < 3 && TMath::Abs(nsigmaTOFK) < 2); - } else if (mom > 0.8 && mom < 1.5) { - return (TMath::Abs(nsigmaTPCK) < 3 && TMath::Abs(nsigmaTOFK) < 1.5); + if (isKaonRun2 == true) { + if (mom < ConfKaonSelection.confMomKaonRun2) { // < 0.4 GeV/c + return std::abs(nsigmaTPCK) < ConfKaonSelection.confKaonNsigmaTPCbelow04Run2; + } else if (mom > ConfKaonSelection.confMomKaonRun2 && mom < ConfKaonSelection.confMomKaon045) { // 0.4 - 0.45 + return std::abs(nsigmaTPCK) < ConfKaonSelection.confKaonNsigmaTPCfrom04to045Run2; + } else if (mom > ConfKaonSelection.confMomKaon045 && mom < ConfKaonSelection.confMomKaon08) { // 0.45 - 0.8 + return (std::abs(nsigmaTPCK) < ConfKaonSelection.confKaonNsigmaTPCfrom045to08Run2 && std::abs(nsigmaTOFK) < ConfKaonSelection.confKaonNsigmaTOFfrom045to08Run2); + } else if (mom > ConfKaonSelection.confMomKaon08 && mom < ConfKaonSelection.confMomKaon15) { // 0.8 - 1.5 + return (std::abs(nsigmaTPCK) < ConfKaonSelection.confKaonNsigmaTPCfrom08to15Run2 && std::abs(nsigmaTOFK) < ConfKaonSelection.confKaonNsigmaTOFfrom08to15Run2); } else { return false; } } else { - if (mom < 0.3) { // 0.0-0.3 - if (TMath::Abs(nsigmaTPCK) < 3.0) { + if (mom < ConfKaonSelection.confMomKaonRun3) { // 0.0-0.3 + if (std::abs(nsigmaTPCK) < ConfKaonSelection.confKaonNsigmaTPCfrom0to03) { return true; } else { return false; } - } else if (mom < 0.45) { // 0.30 - 0.45 - if (TMath::Abs(nsigmaTPCK) < 2.0) { + } else if (mom < ConfKaonSelection.confMomKaon045) { // 0.30 - 0.45 + if (std::abs(nsigmaTPCK) < ConfKaonSelection.confKaonNsigmaTPCfrom03to045) { return true; } else { return false; } - } else if (mom < 0.55) { // 0.45-0.55 - if (TMath::Abs(nsigmaTPCK) < 1.0) { + } else if (mom < ConfKaonSelection.confMomKaon055) { // 0.45-0.55 + if (std::abs(nsigmaTPCK) < ConfKaonSelection.confKaonNsigmaTPCfrom045to055) { return true; } else { return false; } - } else if (mom < 1.5) { // 0.55-1.5 (now we use TPC and TOF) - if ((TMath::Abs(nsigmaTOFK) < 3.0) && (TMath::Abs(nsigmaTPCK) < 3.0)) { + } else if (mom < ConfKaonSelection.confMomKaon15) { // 0.55-1.5 (now we use TPC and TOF) + if ((std::abs(nsigmaTOFK) < ConfKaonSelection.confKaonNsigmaTOFfrom055to15) && (std::abs(nsigmaTPCK) < ConfKaonSelection.confKaonNsigmaTPCfrom055to15)) { { return true; } } else { return false; } - } else if (mom > 1.5) { // 1.5 - - if ((TMath::Abs(nsigmaTOFK) < 2.0) && (TMath::Abs(nsigmaTPCK) < 3.0)) { + } else if (mom > ConfKaonSelection.confMomKaon15) { // > 1.5 GeV/c + if ((std::abs(nsigmaTOFK) < ConfKaonSelection.confKaonNsigmaTOFfrom15) && (std::abs(nsigmaTPCK) < ConfKaonSelection.confKaonNsigmaTPCfrom15)) { return true; } else { return false; @@ -230,16 +254,16 @@ struct femtoUniverseEfficiencyBase { } } - bool IsPionNSigma(float mom, float nsigmaTPCPi, float nsigmaTOFPi) + bool isPionNSigma(float mom, float nsigmaTPCPi, float nsigmaTOFPi) { - if (mom < ConfBothTracks.ConfMomPion) { - if (TMath::Abs(nsigmaTPCPi) < ConfBothTracks.ConfNsigmaTPCPion) { + if (mom < ConfBothTracks.confMomPion) { + if (std::abs(nsigmaTPCPi) < ConfBothTracks.confNsigmaTPCPion) { return true; } else { return false; } } else { - if (TMath::Hypot(nsigmaTOFPi, nsigmaTPCPi) < ConfBothTracks.ConfNsigmaCombinedPion) { + if (std::hypot(nsigmaTOFPi, nsigmaTPCPi) < ConfBothTracks.confNsigmaCombinedPion) { return true; } else { return false; @@ -248,37 +272,37 @@ struct femtoUniverseEfficiencyBase { return false; } - bool IsDeuteronNSigma(float mom, float nsigmaTPCDe, float nsigmaTOFDe) + bool isDeuteronNSigma(float mom, float nsigmaTPCDe, float nsigmaTOFDe) { - if (mom > deuteronconfigs.ConfPLowDe && mom < deuteronconfigs.ConfPHighDe) { - if (mom < deuteronconfigs.ConfTOFpMinDe) { - return (TMath::Abs(nsigmaTPCDe) < deuteronconfigs.ConfNsigmaTPCDe); + if (mom > deuteronconfigs.confPLowDe && mom < deuteronconfigs.confPHighDe) { + if (mom < deuteronconfigs.confTOFpMinDe) { + return (std::abs(nsigmaTPCDe) < deuteronconfigs.confNsigmaTPCDe); } else { - return (TMath::Abs(nsigmaTOFDe) < deuteronconfigs.ConfNsigmaTOFDe && (TMath::Abs(nsigmaTPCDe) < deuteronconfigs.ConfNsigmaTPCDe)); + return (std::abs(nsigmaTOFDe) < deuteronconfigs.confNsigmaTOFDe && (std::abs(nsigmaTPCDe) < deuteronconfigs.confNsigmaTPCDe)); } } else { return false; } } - bool IsParticleNSigma(int pdgCode, float mom, float nsigmaTPCPr, float nsigmaTOFPr, float nsigmaTPCPi, float nsigmaTOFPi, float nsigmaTPCK, float nsigmaTOFK, float nsigmaTPCDe, float nsigmaTOFDe) + bool isParticleNSigma(int pdgCode, float mom, float nsigmaTPCPr, float nsigmaTOFPr, float nsigmaTPCPi, float nsigmaTOFPi, float nsigmaTPCK, float nsigmaTOFK, float nsigmaTPCDe, float nsigmaTOFDe) { switch (pdgCode) { case 2212: // Proton case -2212: // anty Proton - return IsProtonNSigma(mom, nsigmaTPCPr, nsigmaTOFPr); + return isProtonNSigma(mom, nsigmaTPCPr, nsigmaTOFPr); break; case 211: // Pion case -211: // Pion- - return IsPionNSigma(mom, nsigmaTPCPi, nsigmaTOFPi); + return isPionNSigma(mom, nsigmaTPCPi, nsigmaTOFPi); break; case 321: // Kaon+ case -321: // Kaon- - return IsKaonNSigma(mom, nsigmaTPCK, nsigmaTOFK); + return isKaonNSigma(mom, nsigmaTPCK, nsigmaTOFK); break; case 1000010020: // Deuteron case -1000010020: // Antideuteron - return IsDeuteronNSigma(mom, nsigmaTPCDe, nsigmaTOFDe); + return isDeuteronNSigma(mom, nsigmaTPCDe, nsigmaTOFDe); break; default: return false; @@ -287,7 +311,7 @@ struct femtoUniverseEfficiencyBase { bool invMLambda(float invMassLambda, float invMassAntiLambda) { - if ((invMassLambda < ConfV0InvMassLowLimit || invMassLambda > ConfV0InvMassUpLimit) && (invMassAntiLambda < ConfV0InvMassLowLimit || invMassAntiLambda > ConfV0InvMassUpLimit)) { + if ((invMassLambda < confV0InvMassLowLimit || invMassLambda > confV0InvMassUpLimit) && (invMassAntiLambda < confV0InvMassLowLimit || invMassAntiLambda > confV0InvMassUpLimit)) { return false; } return true; @@ -308,16 +332,16 @@ struct femtoUniverseEfficiencyBase { void doMCGen(PartitionType grouppartsOneMCGen, PartitionType grouppartsTwoMCGen) { /// Histogramming same event - for (auto& part : grouppartsOneMCGen) { - if (!ConfNoPDGPartOne && part.tempFitVar() != ConfPDGCodePartOne) { + for (const auto& part : grouppartsOneMCGen) { + if (!confNoPDGPartOne && part.tempFitVar() != confPDGCodePartOne) { continue; } trackHistoPartOneGen.fillQA(part); } - if (!ConfIsSame) { - for (auto& part : grouppartsTwoMCGen) { - if (!ConfNoPDGPartTwo && part.tempFitVar() != ConfPDGCodePartTwo) { + if (!confIsSame) { + for (const auto& part : grouppartsTwoMCGen) { + if (!confNoPDGPartTwo && part.tempFitVar() != confPDGCodePartTwo) { continue; } trackHistoPartTwoGen.fillQA(part); @@ -335,34 +359,49 @@ struct femtoUniverseEfficiencyBase { void doMCRecTrackTrack(PartitionType grouppartsOneMCRec, PartitionType grouppartsTwoMCRec) { /// Histogramming same event - for (auto& part : grouppartsOneMCRec) { - if (part.partType() != ConfParticleTypePartOne || part.sign() != ConfChargePart1 || !IsParticleNSigma(ConfPDGCodePartOne, part.p(), trackCuts.getNsigmaTPC(part, o2::track::PID::Proton), trackCuts.getNsigmaTOF(part, o2::track::PID::Proton), trackCuts.getNsigmaTPC(part, o2::track::PID::Pion), trackCuts.getNsigmaTOF(part, o2::track::PID::Pion), trackCuts.getNsigmaTPC(part, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(part, o2::track::PID::Kaon), trackCuts.getNsigmaTPC(part, o2::track::PID::Deuteron), trackCuts.getNsigmaTOF(part, o2::track::PID::Deuteron))) { + for (const auto& part : grouppartsOneMCRec) { + if (part.partType() != confParticleTypePartOne || part.sign() != confChargePart1 || !isParticleNSigma(confPDGCodePartOne, part.p(), trackCuts.getNsigmaTPC(part, o2::track::PID::Proton), trackCuts.getNsigmaTOF(part, o2::track::PID::Proton), trackCuts.getNsigmaTPC(part, o2::track::PID::Pion), trackCuts.getNsigmaTOF(part, o2::track::PID::Pion), trackCuts.getNsigmaTPC(part, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(part, o2::track::PID::Kaon), trackCuts.getNsigmaTPC(part, o2::track::PID::Deuteron), trackCuts.getNsigmaTOF(part, o2::track::PID::Deuteron))) { continue; } - trackHistoPartOneRec.fillQA(part); if (!part.has_fdMCParticle()) { continue; } const auto mcParticle = part.fdMCParticle(); + if (!(mcParticle.partOriginMCTruth() == aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kPrimary)) { + continue; + } + + if (!(std::abs(mcParticle.pdgMCTruth()) == std::abs(confPDGCodePartOne))) { + continue; + } + + trackHistoPartOneRec.fillQA(part); registryPDG.fill(HIST("part1/PDGvspT"), part.pt(), mcParticle.pdgMCTruth()); registryMCOrigin.fill(HIST("part1/hPt"), mcParticle.pt()); } - if (!ConfIsSame) { - for (auto& part : grouppartsTwoMCRec) { - if (part.partType() != ConfParticleTypePartTwo || part.sign() != ConfChargePart2 || !IsParticleNSigma(ConfPDGCodePartTwo, part.p(), trackCuts.getNsigmaTPC(part, o2::track::PID::Proton), trackCuts.getNsigmaTOF(part, o2::track::PID::Proton), trackCuts.getNsigmaTPC(part, o2::track::PID::Pion), trackCuts.getNsigmaTOF(part, o2::track::PID::Pion), trackCuts.getNsigmaTPC(part, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(part, o2::track::PID::Kaon), trackCuts.getNsigmaTPC(part, o2::track::PID::Deuteron), trackCuts.getNsigmaTOF(part, o2::track::PID::Deuteron))) { + if (!confIsSame) { + for (const auto& part : grouppartsTwoMCRec) { + if (part.partType() != confParticleTypePartTwo || part.sign() != confChargePart2 || !isParticleNSigma(confPDGCodePartTwo, part.p(), trackCuts.getNsigmaTPC(part, o2::track::PID::Proton), trackCuts.getNsigmaTOF(part, o2::track::PID::Proton), trackCuts.getNsigmaTPC(part, o2::track::PID::Pion), trackCuts.getNsigmaTOF(part, o2::track::PID::Pion), trackCuts.getNsigmaTPC(part, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(part, o2::track::PID::Kaon), trackCuts.getNsigmaTPC(part, o2::track::PID::Deuteron), trackCuts.getNsigmaTOF(part, o2::track::PID::Deuteron))) { continue; } - trackHistoPartTwoRec.fillQA(part); - if (!part.has_fdMCParticle()) { continue; } const auto mcParticle = part.fdMCParticle(); + if (!(mcParticle.partOriginMCTruth() == aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kPrimary)) { + continue; + } + + if (!(std::abs(mcParticle.pdgMCTruth()) == std::abs(confPDGCodePartTwo))) { + continue; + } + + trackHistoPartTwoRec.fillQA(part); registryPDG.fill(HIST("part2/PDGvspT"), part.pt(), mcParticle.pdgMCTruth()); registryMCOrigin.fill(HIST("part2/hPt"), mcParticle.pt()); } @@ -379,8 +418,8 @@ struct femtoUniverseEfficiencyBase { void doMCRecTrackPhi(PartitionType grouppartsOneMCRec, PartitionType grouppartsTwoMCRec) { // part1 is track and part2 is Phi - for (auto& part : grouppartsOneMCRec) { - if (part.partType() != ConfParticleTypePartOne || part.sign() != ConfChargePart1 || !IsParticleNSigma(ConfPDGCodePartOne, part.p(), trackCuts.getNsigmaTPC(part, o2::track::PID::Proton), trackCuts.getNsigmaTOF(part, o2::track::PID::Proton), trackCuts.getNsigmaTPC(part, o2::track::PID::Pion), trackCuts.getNsigmaTOF(part, o2::track::PID::Pion), trackCuts.getNsigmaTPC(part, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(part, o2::track::PID::Kaon), trackCuts.getNsigmaTPC(part, o2::track::PID::Deuteron), trackCuts.getNsigmaTOF(part, o2::track::PID::Deuteron))) { + for (const auto& part : grouppartsOneMCRec) { + if (part.partType() != confParticleTypePartOne || part.sign() != confChargePart1 || !isParticleNSigma(confPDGCodePartOne, part.p(), trackCuts.getNsigmaTPC(part, o2::track::PID::Proton), trackCuts.getNsigmaTOF(part, o2::track::PID::Proton), trackCuts.getNsigmaTPC(part, o2::track::PID::Pion), trackCuts.getNsigmaTOF(part, o2::track::PID::Pion), trackCuts.getNsigmaTPC(part, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(part, o2::track::PID::Kaon), trackCuts.getNsigmaTPC(part, o2::track::PID::Deuteron), trackCuts.getNsigmaTOF(part, o2::track::PID::Deuteron))) { continue; } trackHistoPartOneRec.fillQA(part); @@ -394,9 +433,9 @@ struct femtoUniverseEfficiencyBase { registryMCOrigin.fill(HIST("part1/hPt"), mcParticle.pt()); } - if (!ConfIsSame) { - for (auto& part : grouppartsTwoMCRec) { - if (part.partType() != ConfParticleTypePartTwo || part.sign() != ConfChargePart2) { + if (!confIsSame) { + for (const auto& part : grouppartsTwoMCRec) { + if (part.partType() != confParticleTypePartTwo || part.sign() != confChargePart2) { continue; } @@ -425,19 +464,19 @@ struct femtoUniverseEfficiencyBase { void doMCRecV0V0(PartitionType grouppartsOneMCRec, PartitionType grouppartsTwoMCRec, ParticlesType parts) { /// Histogramming same event - for (auto& part : grouppartsOneMCRec) { + for (const auto& part : grouppartsOneMCRec) { - if (part.partType() != ConfParticleTypePartOne || !invMLambda(part.mLambda(), part.mAntiLambda())) { + if (part.partType() != confParticleTypePartOne || !invMLambda(part.mLambda(), part.mAntiLambda())) { continue; } const auto& posChild = parts.iteratorAt(part.index() - 2); const auto& negChild = parts.iteratorAt(part.index() - 1); - if (ConfPDGCodePartOne > 0 && (!IsProtonNSigma(0, trackCuts.getNsigmaTPC(posChild, o2::track::PID::Proton), trackCuts.getNsigmaTOF(posChild, o2::track::PID::Proton)) || !IsPionNSigma(0, trackCuts.getNsigmaTPC(negChild, o2::track::PID::Pion), trackCuts.getNsigmaTOF(negChild, o2::track::PID::Pion)))) { // give momentum as 0 to only check TPC nSigma, not combined with TOF + if (confPDGCodePartOne > 0 && (!isProtonNSigma(0, trackCuts.getNsigmaTPC(posChild, o2::track::PID::Proton), trackCuts.getNsigmaTOF(posChild, o2::track::PID::Proton)) || !isPionNSigma(0, trackCuts.getNsigmaTPC(negChild, o2::track::PID::Pion), trackCuts.getNsigmaTOF(negChild, o2::track::PID::Pion)))) { // give momentum as 0 to only check TPC nSigma, not combined with TOF continue; } - if (ConfPDGCodePartOne < 0 && (!IsProtonNSigma(0, trackCuts.getNsigmaTPC(negChild, o2::track::PID::Proton), trackCuts.getNsigmaTOF(negChild, o2::track::PID::Proton)) || !IsPionNSigma(0, trackCuts.getNsigmaTPC(posChild, o2::track::PID::Pion), trackCuts.getNsigmaTOF(posChild, o2::track::PID::Pion)))) { // give momentum as 0 to only check TPC nSigma, not combined with TOF + if (confPDGCodePartOne < 0 && (!isProtonNSigma(0, trackCuts.getNsigmaTPC(negChild, o2::track::PID::Proton), trackCuts.getNsigmaTOF(negChild, o2::track::PID::Proton)) || !isPionNSigma(0, trackCuts.getNsigmaTPC(posChild, o2::track::PID::Pion), trackCuts.getNsigmaTOF(posChild, o2::track::PID::Pion)))) { // give momentum as 0 to only check TPC nSigma, not combined with TOF continue; } @@ -458,20 +497,20 @@ struct femtoUniverseEfficiencyBase { registryMCOrigin.fill(HIST("part1/hPt"), mcParticle.pt()); } - if (!ConfIsSame) { - for (auto& part : grouppartsTwoMCRec) { + if (!confIsSame) { + for (const auto& part : grouppartsTwoMCRec) { - if (part.partType() != ConfParticleTypePartTwo || !invMLambda(part.mLambda(), part.mAntiLambda())) { + if (part.partType() != confParticleTypePartTwo || !invMLambda(part.mLambda(), part.mAntiLambda())) { continue; } const auto& posChild = parts.iteratorAt(part.index() - 2); const auto& negChild = parts.iteratorAt(part.index() - 1); - if (ConfPDGCodePartTwo > 0 && (!IsProtonNSigma(0, trackCuts.getNsigmaTPC(posChild, o2::track::PID::Proton), trackCuts.getNsigmaTOF(posChild, o2::track::PID::Proton)) || !IsPionNSigma(0, trackCuts.getNsigmaTPC(negChild, o2::track::PID::Pion), trackCuts.getNsigmaTOF(negChild, o2::track::PID::Pion)))) { // give momentum as 0 to only check TPC nSigma, not combined with TOF + if (confPDGCodePartTwo > 0 && (!isProtonNSigma(0, trackCuts.getNsigmaTPC(posChild, o2::track::PID::Proton), trackCuts.getNsigmaTOF(posChild, o2::track::PID::Proton)) || !isPionNSigma(0, trackCuts.getNsigmaTPC(negChild, o2::track::PID::Pion), trackCuts.getNsigmaTOF(negChild, o2::track::PID::Pion)))) { // give momentum as 0 to only check TPC nSigma, not combined with TOF continue; } - if (ConfPDGCodePartTwo < 0 && (!IsProtonNSigma(0, trackCuts.getNsigmaTPC(negChild, o2::track::PID::Proton), trackCuts.getNsigmaTOF(negChild, o2::track::PID::Proton)) || !IsPionNSigma(0, trackCuts.getNsigmaTPC(posChild, o2::track::PID::Pion), trackCuts.getNsigmaTOF(posChild, o2::track::PID::Pion)))) { // give momentum as 0 to only check TPC nSigma, not combined with TOF + if (confPDGCodePartTwo < 0 && (!isProtonNSigma(0, trackCuts.getNsigmaTPC(negChild, o2::track::PID::Proton), trackCuts.getNsigmaTOF(negChild, o2::track::PID::Proton)) || !isPionNSigma(0, trackCuts.getNsigmaTPC(posChild, o2::track::PID::Pion), trackCuts.getNsigmaTOF(posChild, o2::track::PID::Pion)))) { // give momentum as 0 to only check TPC nSigma, not combined with TOF continue; } @@ -507,8 +546,8 @@ struct femtoUniverseEfficiencyBase { { // part1 is track and part2 is V0 /// Histogramming same event - for (auto& part : grouppartsOneMCRec) { - if (part.partType() != ConfParticleTypePartOne || part.sign() != ConfChargePart1 || !IsParticleNSigma(ConfPDGCodePartOne, part.p(), trackCuts.getNsigmaTPC(part, o2::track::PID::Proton), trackCuts.getNsigmaTOF(part, o2::track::PID::Proton), trackCuts.getNsigmaTPC(part, o2::track::PID::Pion), trackCuts.getNsigmaTOF(part, o2::track::PID::Pion), trackCuts.getNsigmaTPC(part, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(part, o2::track::PID::Kaon), trackCuts.getNsigmaTPC(part, o2::track::PID::Deuteron), trackCuts.getNsigmaTOF(part, o2::track::PID::Deuteron))) { + for (const auto& part : grouppartsOneMCRec) { + if (part.partType() != confParticleTypePartOne || part.sign() != confChargePart1 || !isParticleNSigma(confPDGCodePartOne, part.p(), trackCuts.getNsigmaTPC(part, o2::track::PID::Proton), trackCuts.getNsigmaTOF(part, o2::track::PID::Proton), trackCuts.getNsigmaTPC(part, o2::track::PID::Pion), trackCuts.getNsigmaTOF(part, o2::track::PID::Pion), trackCuts.getNsigmaTPC(part, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(part, o2::track::PID::Kaon), trackCuts.getNsigmaTPC(part, o2::track::PID::Deuteron), trackCuts.getNsigmaTOF(part, o2::track::PID::Deuteron))) { continue; } @@ -521,19 +560,19 @@ struct femtoUniverseEfficiencyBase { registryMCOrigin.fill(HIST("part1/hPt"), mcParticle.pt()); } - if (!ConfIsSame) { - for (auto& part : grouppartsTwoMCRec) { + if (!confIsSame) { + for (const auto& part : grouppartsTwoMCRec) { - if (part.partType() != ConfParticleTypePartTwo || !invMLambda(part.mLambda(), part.mAntiLambda())) { + if (part.partType() != confParticleTypePartTwo || !invMLambda(part.mLambda(), part.mAntiLambda())) { continue; } const auto& posChild = parts.iteratorAt(part.index() - 2); const auto& negChild = parts.iteratorAt(part.index() - 1); - if (ConfPDGCodePartTwo > 0 && (!IsProtonNSigma(0, trackCuts.getNsigmaTPC(posChild, o2::track::PID::Proton), trackCuts.getNsigmaTOF(posChild, o2::track::PID::Proton)) || !IsPionNSigma(0, trackCuts.getNsigmaTPC(negChild, o2::track::PID::Pion), trackCuts.getNsigmaTOF(negChild, o2::track::PID::Pion)))) { // give momentum as 0 to only check TPC nSigma, not combined with TOF + if (confPDGCodePartTwo > 0 && (!isProtonNSigma(0, trackCuts.getNsigmaTPC(posChild, o2::track::PID::Proton), trackCuts.getNsigmaTOF(posChild, o2::track::PID::Proton)) || !isPionNSigma(0, trackCuts.getNsigmaTPC(negChild, o2::track::PID::Pion), trackCuts.getNsigmaTOF(negChild, o2::track::PID::Pion)))) { // give momentum as 0 to only check TPC nSigma, not combined with TOF continue; } - if (ConfPDGCodePartTwo < 0 && (!IsProtonNSigma(0, trackCuts.getNsigmaTPC(negChild, o2::track::PID::Proton), trackCuts.getNsigmaTOF(negChild, o2::track::PID::Proton)) || !IsPionNSigma(0, trackCuts.getNsigmaTPC(posChild, o2::track::PID::Pion), trackCuts.getNsigmaTOF(posChild, o2::track::PID::Pion)))) { // give momentum as 0 to only check TPC nSigma, not combined with TOF + if (confPDGCodePartTwo < 0 && (!isProtonNSigma(0, trackCuts.getNsigmaTPC(negChild, o2::track::PID::Proton), trackCuts.getNsigmaTOF(negChild, o2::track::PID::Proton)) || !isPionNSigma(0, trackCuts.getNsigmaTPC(posChild, o2::track::PID::Pion), trackCuts.getNsigmaTOF(posChild, o2::track::PID::Pion)))) { // give momentum as 0 to only check TPC nSigma, not combined with TOF continue; } @@ -558,96 +597,96 @@ struct femtoUniverseEfficiencyBase { /// process function for to call doMCRecTrackTrack with Data /// \param col subscribe to the collision table (Data) - void processTrackTrack(FilteredFDCollision& col, - FemtoFullParticles&, aod::FdMCParticles const&) + void processTrackTrack(FilteredFDCollision const& col, + FemtoFullParticles const&, aod::FdMCParticles const&) { fillCollision(col); // MCGen auto thegrouppartsOneMCGen = partsOneMCGen->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); - auto thegrouppartsTwoMCGen = partsTwoGen->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); + auto thegrouppartsTwoMCGen = partsTwoMCGen->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); doMCGen(thegrouppartsOneMCGen, thegrouppartsTwoMCGen); // MCRec auto thegroupPartsTrackOneRec = partsTrackOneMCReco->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); auto thegroupPartsTrackTwoRec = partsTrackTwoMCReco->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); - if (ConfIsDebug) { + if (confIsDebug) { doMCRecTrackTrack(thegroupPartsTrackOneRec, thegroupPartsTrackTwoRec); } else { doMCRecTrackTrack(thegroupPartsTrackOneRec, thegroupPartsTrackTwoRec); } } - PROCESS_SWITCH(femtoUniverseEfficiencyBase, processTrackTrack, "Enable processing track-track efficiency task", true); + PROCESS_SWITCH(FemtoUniverseEfficiencyBase, processTrackTrack, "Enable processing track-track efficiency task", true); /// process function for to call doMCRecTrackPhi with Data /// \param col subscribe to the collision table (Data) - void processTrackPhi(FilteredFDCollision& col, - FemtoFullParticles&, aod::FdMCParticles const&) + void processTrackPhi(FilteredFDCollision const& col, + FemtoFullParticles const&, aod::FdMCParticles const&) { fillCollision(col); // MCGen auto thegrouppartsOneMCGen = partsOneMCGen->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); - auto thegrouppartsTwoMCGen = partsTwoGen->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); + auto thegrouppartsTwoMCGen = partsTwoMCGen->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); doMCGen(thegrouppartsOneMCGen, thegrouppartsTwoMCGen); // MCRec auto thegroupPartsTrackOneRec = partsTrackOneMCReco->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); auto thegroupPartsTrackTwoRec = partsTrackTwoMCReco->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); - if (ConfIsDebug) { + if (confIsDebug) { doMCRecTrackPhi(thegroupPartsTrackOneRec, thegroupPartsTrackTwoRec); } else { doMCRecTrackPhi(thegroupPartsTrackOneRec, thegroupPartsTrackTwoRec); } } - PROCESS_SWITCH(femtoUniverseEfficiencyBase, processTrackPhi, "Enable processing track-phi efficiency task", false); + PROCESS_SWITCH(FemtoUniverseEfficiencyBase, processTrackPhi, "Enable processing track-phi efficiency task", false); /// process function for to call doMCRecV0V0 with Data /// \param col subscribe to the collision table (Data) /// \param parts subscribe to the femtoUniverseParticleTable - void processV0V0(FilteredFDCollision& col, - FemtoFullParticles& parts, aod::FdMCParticles const&) + void processV0V0(FilteredFDCollision const& col, + FemtoFullParticles const& parts, aod::FdMCParticles const&) { fillCollision(col); // MCGen auto thegrouppartsOneMCGen = partsOneMCGen->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); - auto thegrouppartsTwoMCGen = partsTwoGen->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); + auto thegrouppartsTwoMCGen = partsTwoMCGen->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); doMCGen(thegrouppartsOneMCGen, thegrouppartsTwoMCGen); // MCRec auto thegroupPartsTrackOneRec = partsTrackOneMCReco->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); auto thegroupPartsTrackTwoRec = partsTrackTwoMCReco->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); - if (ConfIsDebug) { + if (confIsDebug) { doMCRecV0V0(thegroupPartsTrackOneRec, thegroupPartsTrackTwoRec, parts); } else { doMCRecV0V0(thegroupPartsTrackOneRec, thegroupPartsTrackTwoRec, parts); } } - PROCESS_SWITCH(femtoUniverseEfficiencyBase, processV0V0, "Enable processing V0-V0 efficiency task", false); + PROCESS_SWITCH(FemtoUniverseEfficiencyBase, processV0V0, "Enable processing V0-V0 efficiency task", false); /// process function for to call doMCRecTrackV0 with Data /// \param col subscribe to the collision table (Data) /// \param parts subscribe to the femtoUniverseParticleTable - void processTrackV0(FilteredFDCollision& col, - FemtoFullParticles& parts, aod::FdMCParticles const&) + void processTrackV0(FilteredFDCollision const& col, + FemtoFullParticles const& parts, aod::FdMCParticles const&) { fillCollision(col); // MCGen auto thegrouppartsOneMCGen = partsOneMCGen->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); - auto thegrouppartsTwoMCGen = partsTwoGen->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); + auto thegrouppartsTwoMCGen = partsTwoMCGen->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); doMCGen(thegrouppartsOneMCGen, thegrouppartsTwoMCGen); // MCRec auto thegroupPartsTrackOneRec = partsTrackOneMCReco->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); auto thegroupPartsTrackTwoRec = partsTrackTwoMCReco->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); - if (ConfIsDebug) { + if (confIsDebug) { doMCRecTrackV0(thegroupPartsTrackOneRec, thegroupPartsTrackTwoRec, parts); } else { doMCRecTrackV0(thegroupPartsTrackOneRec, thegroupPartsTrackTwoRec, parts); } } - PROCESS_SWITCH(femtoUniverseEfficiencyBase, processTrackV0, "Enable processing track-V0 efficiency task", false); + PROCESS_SWITCH(FemtoUniverseEfficiencyBase, processTrackV0, "Enable processing track-V0 efficiency task", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { WorkflowSpec workflow{ - adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc), }; return workflow; } diff --git a/PWGCF/Flow/TableProducer/zdcQVectors.cxx b/PWGCF/Flow/TableProducer/zdcQVectors.cxx index 13c2064e28f..f0052000fe6 100644 --- a/PWGCF/Flow/TableProducer/zdcQVectors.cxx +++ b/PWGCF/Flow/TableProducer/zdcQVectors.cxx @@ -64,10 +64,6 @@ using namespace o2::framework::expressions; using namespace o2::aod::track; using namespace o2::aod::evsel; -// define my..... -using UsedCollisions = soa::Join; -using BCsRun3 = soa::Join; - namespace o2::analysis::qvectortask { int counter = 0; @@ -85,6 +81,7 @@ 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 qNoEq(4); // start values of [QxA, QyA, QxC, QyC] // for energy calibration std::vector eZN(8); // uncalibrated energy for the 2x4 towers (a1, a2, a3, a4, c1, c2, c3, c4) @@ -112,9 +109,9 @@ struct ZdcQVectors { ConfigurableAxis axisVxBig{"axisVxBig", {3, -0.01, 0.01}, "for Pos X of collision"}; ConfigurableAxis axisVyBig{"axisVyBig", {3, -0.01, 0.01}, "for Pos Y of collision"}; ConfigurableAxis axisVzBig{"axisVzBig", {3, -10, 10}, "for Pos Z of collision"}; - ConfigurableAxis axisVx{"axisVx", {10, -0.01, 0.01}, "for Pos X of collision"}; - ConfigurableAxis axisVy{"axisVy", {10, -0.01, 0.01}, "for Pos Y of collision"}; - ConfigurableAxis axisVz{"axisVz", {10, -10, 1}, "for vz of collision"}; + ConfigurableAxis axisVx{"axisVx", {100, -0.01, 0.01}, "for Pos X of collision"}; + ConfigurableAxis axisVy{"axisVy", {100, -0.01, 0.01}, "for Pos Y of collision"}; + ConfigurableAxis axisVz{"axisVz", {100, -10, 10}, "for vz of collision"}; // Centrality Estimators -> standard is FT0C O2_DEFINE_CONFIGURABLE(cfgFT0Cvariant1, bool, false, "Set centrality estimator to cfgFT0Cvariant1"); @@ -122,7 +119,7 @@ struct ZdcQVectors { O2_DEFINE_CONFIGURABLE(cfgFV0A, bool, false, "Set centrality estimator to cfgFV0A"); O2_DEFINE_CONFIGURABLE(cfgNGlobal, bool, false, "Set centrality estimator to cfgNGlobal"); - O2_DEFINE_CONFIGURABLE(cfgCutVertex, float, 10.0f, "Accepted z-vertex range") + O2_DEFINE_CONFIGURABLE(cfgVtxZ, float, 10.0f, "Accepted z-vertex range") O2_DEFINE_CONFIGURABLE(cfgCutPtPOIMin, float, 0.2f, "Minimal.q pT for poi tracks") O2_DEFINE_CONFIGURABLE(cfgCutPtPOIMax, float, 10.0f, "Maximal pT for poi tracks") O2_DEFINE_CONFIGURABLE(cfgCutPtMin, float, 0.2f, "Minimal pT for ref tracks") @@ -133,12 +130,44 @@ struct ZdcQVectors { O2_DEFINE_CONFIGURABLE(cfgEnergyCal, std::string, "Users/c/ckoster/ZDC/LHC23_zzh_pass4/Energy", "ccdb path for energy calibration histos") O2_DEFINE_CONFIGURABLE(cfgMeanv, std::string, "Users/c/ckoster/ZDC/LHC23_zzh_pass4/vmean", "ccdb path for mean v histos") O2_DEFINE_CONFIGURABLE(cfgMinEntriesSparseBin, int, 100, "Minimal number of entries allowed in 4D recentering histogram to use for recentering.") + O2_DEFINE_CONFIGURABLE(cfgRec, std::string, "Users/c/ckoster/ZDC/LHC23_PbPb_pass4", "ccdb path for recentering histos"); + O2_DEFINE_CONFIGURABLE(cfgFillCommonRegistry, bool, true, "Fill common registry with histograms"); + + // Additional event selections + O2_DEFINE_CONFIGURABLE(cfgEvSelsMaxOccupancy, int, 10000, "Maximum occupancy of selected events"); + O2_DEFINE_CONFIGURABLE(cfgEvSelsNoSameBunchPileupCut, bool, true, "kNoSameBunchPileupCut"); + O2_DEFINE_CONFIGURABLE(cfgEvSelsIsGoodZvtxFT0vsPV, bool, true, "kIsGoodZvtxFT0vsPV"); + O2_DEFINE_CONFIGURABLE(cfgEvSelsNoCollInTimeRangeStandard, bool, true, "kNoCollInTimeRangeStandard"); + O2_DEFINE_CONFIGURABLE(cfgEvSelsDoOccupancySel, bool, true, "Bool for event selection on detector occupancy"); + O2_DEFINE_CONFIGURABLE(cfgEvSelsIsVertexITSTPC, bool, true, "Selects collisions with at least one ITS-TPC track"); + O2_DEFINE_CONFIGURABLE(cfgEvSelsIsGoodITSLayersAll, bool, true, "Cut time intervals with dead ITS staves"); + O2_DEFINE_CONFIGURABLE(cfgEvSelsCentMin, float, 0, "Minimum cenrality for selected events"); + O2_DEFINE_CONFIGURABLE(cfgEvSelsCentMax, float, 90, "Maximum cenrality for selected events"); + + // define my..... + // Filter collisionFilter = nabs(aod::collision::posZ) < cfgVtxZ; + using UsedCollisions = soa::Join; + using BCsRun3 = soa::Join; + + enum SelectionCriteria { + evSel_Zvtx, + evSel_sel8, + evSel_occupancy, + evSel_kNoSameBunchPileup, + evSel_kIsGoodZvtxFT0vsPV, + evSel_kNoCollInTimeRangeStandard, + evSel_kIsVertexITSTPC, + evSel_CentCuts, + evSel_kIsGoodITSLayersAll, + evSel_isSelectedZDC, + nEventSelections + }; - Configurable> cfgRec1{"cfgRec1", {"Users/c/ckoster/ZDC/LHC23_zzh_pass4/it1_step1", "Users/c/ckoster/ZDC/LHC23_zzh_pass4/it1_step2", "Users/c/ckoster/ZDC/LHC23_zzh_pass4/it1_step3", "Users/c/ckoster/ZDC/LHC23_zzh_pass4/it1_step4", "Users/c/ckoster/ZDC/LHC23_zzh_pass4/it1_step5"}, "ccdb paths for recentering calibration histos iteration 1"}; - Configurable> cfgRec2{"cfgRec2", {"Users/c/ckoster/ZDC/LHC23_zzh_pass4/it2_step1", "Users/c/ckoster/ZDC/LHC23_zzh_pass4/it2_step2", "Users/c/ckoster/ZDC/LHC23_zzh_pass4/it2_step3", "Users/c/ckoster/ZDC/LHC23_zzh_pass4/it2_step4", "Users/c/ckoster/ZDC/LHC23_zzh_pass4/it2_step5"}, "ccdb paths for recentering calibration histos iteration 2"}; - Configurable> cfgRec3{"cfgRec3", {"Users/c/ckoster/ZDC/LHC23_zzh_pass4/it3_step1", "Users/c/ckoster/ZDC/LHC23_zzh_pass4/it3_step2", "Users/c/ckoster/ZDC/LHC23_zzh_pass4/it3_step3", "Users/c/ckoster/ZDC/LHC23_zzh_pass4/it3_step4", "Users/c/ckoster/ZDC/LHC23_zzh_pass4/it3_step5"}, "ccdb paths for recentering calibration histos iteration 3"}; - Configurable> cfgRec4{"cfgRec4", {"Users/c/ckoster/ZDC/LHC23_zzh_pass4/it4_step1", "Users/c/ckoster/ZDC/LHC23_zzh_pass4/it4_step2", "Users/c/ckoster/ZDC/LHC23_zzh_pass4/it4_step3", "Users/c/ckoster/ZDC/LHC23_zzh_pass4/it4_step4", "Users/c/ckoster/ZDC/LHC23_zzh_pass4/it4_step5"}, "ccdb paths for recentering calibration histos iteration 4"}; - Configurable> cfgRec5{"cfgRec5", {"Users/c/ckoster/ZDC/LHC23_zzh_pass4/it5_step1", "Users/c/ckoster/ZDC/LHC23_zzh_pass4/it5_step2", "Users/c/ckoster/ZDC/LHC23_zzh_pass4/it5_step3", "Users/c/ckoster/ZDC/LHC23_zzh_pass4/it5_step4", "Users/c/ckoster/ZDC/LHC23_zzh_pass4/it5_step5"}, "ccdb paths for recentering calibration histos iteration 5"}; + enum CalibModes { + kEnergyCal, + kMeanv, + kRec + }; // Define output HistogramRegistry registry{"Registry"}; @@ -147,8 +176,8 @@ struct ZdcQVectors { // keep track of calibration histos for each given step and iteration struct Calib { - std::vector> calibList = std::vector>(7, std::vector(8, nullptr)); - std::vector> calibfilesLoaded = std::vector>(7, std::vector(8, false)); + std::vector calibList = std::vector(3, nullptr); // [0] Enerfy cal, [1] vmean, [2] recentering + std::vector calibfilesLoaded = std::vector(3, false); int atStep = 0; int atIteration = 0; } cal; @@ -170,23 +199,21 @@ struct ZdcQVectors { std::vector sides = {"A", "C"}; std::vector capCOORDS = {"X", "Y"}; - // Tower mean energies vs. centrality used for tower gain equalisation - for (int tower = 0; tower < 10; tower++) { - namesEcal[tower] = TString::Format("hZN%s_mean_t%i_cent", sides[(tower < 5) ? 0 : 1], tower % 5); - registry.add(Form("Energy/%s", namesEcal[tower].Data()), Form("%s", namesEcal[tower].Data()), kTProfile2D, {{1, 0, 1}, axisCent}); - } - - registry.add(Form("before/QA/hSPplaneA"), "hSPplaneA", kTH2D, {{100, -4, 4}, axisCent10}); - registry.add(Form("before/QA/hSPplaneC"), "hSPplaneC", kTH2D, {{100, -4, 4}, axisCent10}); - registry.add(Form("before/QA/hSPplaneFull"), "hSPplaneFull", kTH2D, {{100, -4, 4}, axisCent10}); - for (const auto& side : sides) { - registry.add(Form("before/hZN%s_Qx_vs_Qy", side), Form("hZN%s_Qx_vs_Qy", side), kTH2F, {axisQ, axisQ}); - } + if (cfgFillCommonRegistry) { + registry.add(Form("QA/before/hSPplaneA"), "hSPplaneA", kTH2D, {{100, -4, 4}, axisCent10}); + registry.add(Form("QA/before/hSPplaneC"), "hSPplaneC", kTH2D, {{100, -4, 4}, axisCent10}); + registry.add(Form("QA/before/hSPplaneFull"), "hSPplaneFull", kTH2D, {{100, -4, 4}, axisCent10}); + for (const auto& side : sides) { + registry.add(Form("QA/before/hZN%s_Qx_vs_Qy", side), Form("hZN%s_Qx_vs_Qy", side), kTH2F, {axisQ, axisQ}); + } for (const auto& COORD1 : capCOORDS) { for (const auto& COORD2 : capCOORDS) { // Now we get: & vs. Centrality - registry.add(Form("before/QA/hQ%sA_Q%sC_vs_cent", COORD1, COORD2), Form("hQ%sA_Q%sC_vs_cent", COORD1, COORD2), kTProfile, {axisCent}); + registry.add(Form("QA/before/hQ%sA_Q%sC_vs_cent", COORD1, COORD2), Form("hQ%sA_Q%sC_vs_cent", COORD1, COORD2), kTProfile, {axisCent}); + registry.add(Form("QA/before/hQ%sA_Q%sC_vs_vx", COORD1, COORD2), Form("hQ%sA_Q%sC_vs_vx", COORD1, COORD2), kTProfile, {axisVx}); + registry.add(Form("QA/before/hQ%sA_Q%sC_vs_vy", COORD1, COORD2), Form("hQ%sA_Q%sC_vs_vy", COORD1, COORD2), kTProfile, {axisVy}); + registry.add(Form("QA/before/hQ%sA_Q%sC_vs_vz", COORD1, COORD2), Form("hQ%sA_Q%sC_vs_vz", COORD1, COORD2), kTProfile, {axisVz}); } } @@ -194,10 +221,10 @@ struct ZdcQVectors { // Sides is {A,C} and capcoords is {X,Y} for (const auto& side : sides) { for (const auto& coord : capCOORDS) { - registry.add(Form("before/QA/hQ%s%s_vs_cent", coord, side), Form("hQ%s%s_vs_cent", coord, side), {HistType::kTProfile, {axisCent10}}); - registry.add(Form("before/QA/hQ%s%s_vs_vx", coord, side), Form("hQ%s%s_vs_vx", coord, side), {HistType::kTProfile, {axisVx}}); - registry.add(Form("before/QA/hQ%s%s_vs_vy", coord, side), Form("hQ%s%s_vs_vy", coord, side), {HistType::kTProfile, {axisVy}}); - registry.add(Form("before/QA/hQ%s%s_vs_vz", coord, side), Form("hQ%s%s_vs_vz", coord, side), {HistType::kTProfile, {axisVz}}); + registry.add(Form("QA/before/hQ%s%s_vs_cent", coord, side), Form("hQ%s%s_vs_cent", coord, side), {HistType::kTProfile, {axisCent10}}); + registry.add(Form("QA/before/hQ%s%s_vs_vx", coord, side), Form("hQ%s%s_vs_vx", coord, side), {HistType::kTProfile, {axisVx}}); + registry.add(Form("QA/before/hQ%s%s_vs_vy", coord, side), Form("hQ%s%s_vs_vy", coord, side), {HistType::kTProfile, {axisVy}}); + registry.add(Form("QA/before/hQ%s%s_vs_vz", coord, side), Form("hQ%s%s_vs_vz", coord, side), {HistType::kTProfile, {axisVz}}); names[0].push_back(TString::Format("hQ%s%s_mean_Cent_V_run", coord, side)); names[1].push_back(TString::Format("hQ%s%s_mean_cent_run", coord, side)); @@ -207,142 +234,235 @@ struct ZdcQVectors { } // end of capCOORDS } // end of sides - // recentered q-vectors (to check what steps are finished in the end) - - registry.add("vmean/hvertex_vx", "hvertex_vx", kTProfile, {{1, 0., 1.}}); - registry.add("vmean/hvertex_vy", "hvertex_vy", kTProfile, {{1, 0., 1.}}); - registry.add("vmean/hvertex_vz", "hvertex_vz", kTProfile, {{1, 0., 1.}}); - registry.add("QA/centrality_before", "centrality_before", kTH1D, {{200, 0, 100}}); registry.add("QA/centrality_after", "centrality_after", kTH1D, {{200, 0, 100}}); registry.add("QA/ZNA_Energy", "ZNA_Energy", kTProfile, {{8, 0, 8}}); registry.add("QA/ZNC_Energy", "ZNC_Energy", kTProfile, {{8, 0, 8}}); - registry.addClone("before/", "after/"); + registry.add("QA/before/ZNA_pm1", "ZNA_pm1", kTProfile, {{1, 0, 1.}}); + registry.add("QA/before/ZNA_pm2", "ZNA_pm2", kTProfile, {{1, 0, 1.}}); + registry.add("QA/before/ZNA_pm3", "ZNA_pm3", kTProfile, {{1, 0, 1.}}); + registry.add("QA/before/ZNA_pm4", "ZNA_pm4", kTProfile, {{1, 0, 1.}}); + + registry.add("QA/before/ZNC_pm1", "ZNC_pm1", kTProfile, {{1, 0, 1.}}); + registry.add("QA/before/ZNC_pm2", "ZNC_pm2", kTProfile, {{1, 0, 1.}}); + registry.add("QA/before/ZNC_pm3", "ZNC_pm3", kTProfile, {{1, 0, 1.}}); + registry.add("QA/before/ZNC_pm4", "ZNC_pm4", kTProfile, {{1, 0, 1.}}); + + registry.add("QA/before/ZNA_Qx", "ZNA_Qx", kTProfile, {{1, 0, 1.}}); + registry.add("QA/before/ZNA_Qy", "ZNA_Qy", kTProfile, {{1, 0, 1.}}); + registry.add("QA/before/ZNC_Qx", "ZNC_Qx", kTProfile, {{1, 0, 1.}}); + registry.add("QA/before/ZNC_Qy", "ZNC_Qy", kTProfile, {{1, 0, 1.}}); + + registry.add("QA/before/ZNA_Qx_noEq", "ZNA_Qx_noEq", kTProfile, {{1, 0, 1.}}); + registry.add("QA/before/ZNA_Qy_noEq", "ZNA_Qy_noEq", kTProfile, {{1, 0, 1.}}); + registry.add("QA/before/ZNC_Qx_noEq", "ZNC_Qx_noEq", kTProfile, {{1, 0, 1.}}); + registry.add("QA/before/ZNC_Qy_noEq", "ZNC_Qy_noEq", kTProfile, {{1, 0, 1.}}); + + registry.addClone("QA/before/", "QA/after/"); + } + + // Tower mean energies vs. centrality used for tower gain equalisation + int totalTowers = 10; + int totalTowersPerSide = 5; + for (int tower = 0; tower < totalTowers; tower++) { + namesEcal[tower] = TString::Format("hZN%s_mean_t%i_cent", sides[(tower < totalTowersPerSide) ? 0 : 1], tower % 5); + registry.add(Form("Energy/%s", namesEcal[tower].Data()), Form("%s", namesEcal[tower].Data()), kTProfile2D, {{1, 0, 1}, axisCent}); + } + + // recentered q-vectors (to check what steps are finished in the end) + registry.add("vmean/hvertex_vx", "hvertex_vx", kTProfile, {{1, 0., 1.}}); + registry.add("vmean/hvertex_vy", "hvertex_vy", kTProfile, {{1, 0., 1.}}); + registry.add("vmean/hvertex_vz", "hvertex_vz", kTProfile, {{1, 0., 1.}}); + + registry.add("hEventCount", "Number of Event; Cut; #Events Passed Cut", {HistType::kTH1D, {{nEventSelections, 0, nEventSelections}}}); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_Zvtx + 1, "Z vertex cut event"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_sel8 + 1, "Sel8"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_occupancy + 1, "kOccupancy"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_kNoSameBunchPileup + 1, "kNoSameBunchPileup"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_kIsGoodZvtxFT0vsPV + 1, "kIsGoodZvtxFT0vsPV"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_kNoCollInTimeRangeStandard + 1, "kNoCollInTimeRangeStandard"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_kIsVertexITSTPC + 1, "kIsVertexITSTPC"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_CentCuts + 1, "Cenrality range"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_kIsGoodITSLayersAll + 1, "kkIsGoodITSLayersAll"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_isSelectedZDC + 1, "isSelected"); } - template - inline void fillCommonRegistry(double qxa, double qya, double qxc, double qyc, std::vector v, double centrality) + template + bool eventSelected(TCollision collision, const float& centrality) { - // loop for filling multiple histograms with different naming patterns - // Always fill the uncentered "raw" Q-vector histos! - static constexpr std::string_view Time[] = {"before", "after"}; + if (std::fabs(collision.posZ()) > cfgVtxZ) + return 0; + registry.fill(HIST("hEventCount"), evSel_sel8); + + if (!collision.sel8()) + return 0; + registry.fill(HIST("hEventCount"), evSel_sel8); + + // Occupancy + if (cfgEvSelsDoOccupancySel) { + auto occupancy = collision.trackOccupancyInTimeRange(); + if (occupancy > cfgEvSelsMaxOccupancy) { + return 0; + } + registry.fill(HIST("hEventCount"), evSel_occupancy); + } - registry.fill(HIST(Time[ft]) + HIST("/hZNA_Qx_vs_Qy"), qxa, qya); - registry.fill(HIST(Time[ft]) + HIST("/hZNC_Qx_vs_Qy"), qxc, qyc); + if (cfgEvSelsNoSameBunchPileupCut) { + if (!collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) { + // rejects collisions which are associated with the same "found-by-T0" bunch crossing + // https://indico.cern.ch/event/1396220/#1-event-selection-with-its-rof + return 0; + } + registry.fill(HIST("hEventCount"), evSel_kNoSameBunchPileup); + } + if (cfgEvSelsIsGoodZvtxFT0vsPV) { + if (!collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) { + // removes collisions with large differences between z of PV by tracks and z of PV from FT0 A-C time difference + // use this cut at low multiplicities with caution + return 0; + } + registry.fill(HIST("hEventCount"), evSel_kIsGoodZvtxFT0vsPV); + } + if (cfgEvSelsNoCollInTimeRangeStandard) { + if (!collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { + // Rejection of the collisions which have other events nearby + return 0; + } + registry.fill(HIST("hEventCount"), evSel_kNoCollInTimeRangeStandard); + } - registry.fill(HIST(Time[ft]) + HIST("/QA/hQXA_QXC_vs_cent"), centrality, qxa * qxc); - registry.fill(HIST(Time[ft]) + HIST("/QA/hQYA_QYC_vs_cent"), centrality, qya * qyc); - registry.fill(HIST(Time[ft]) + HIST("/QA/hQYA_QXC_vs_cent"), centrality, qya * qxc); - registry.fill(HIST(Time[ft]) + HIST("/QA/hQXA_QYC_vs_cent"), centrality, qxa * qyc); + if (cfgEvSelsIsVertexITSTPC) { + if (!collision.selection_bit(o2::aod::evsel::kIsVertexITSTPC)) { + // selects collisions with at least one ITS-TPC track, and thus rejects vertices built from ITS-only tracks + return 0; + } + registry.fill(HIST("hEventCount"), evSel_kIsVertexITSTPC); + } - registry.fill(HIST(Time[ft]) + HIST("/QA/hQXA_vs_cent"), centrality, qxa); - registry.fill(HIST(Time[ft]) + HIST("/QA/hQYA_vs_cent"), centrality, qya); - registry.fill(HIST(Time[ft]) + HIST("/QA/hQXC_vs_cent"), centrality, qxc); - registry.fill(HIST(Time[ft]) + HIST("/QA/hQYC_vs_cent"), centrality, qyc); + if (centrality > cfgEvSelsCentMax || centrality < cfgEvSelsCentMin) + return 0; + registry.fill(HIST("hEventCount"), evSel_CentCuts); - registry.fill(HIST(Time[ft]) + HIST("/QA/hQXA_vs_vx"), v[0], qxa); - registry.fill(HIST(Time[ft]) + HIST("/QA/hQYA_vs_vx"), v[0], qya); - registry.fill(HIST(Time[ft]) + HIST("/QA/hQXC_vs_vx"), v[0], qxc); - registry.fill(HIST(Time[ft]) + HIST("/QA/hQYC_vs_vx"), v[0], qyc); + if (cfgEvSelsIsGoodITSLayersAll) { + if (!collision.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { + // New event selection bits to cut time intervals with dead ITS staves + // https://indico.cern.ch/event/1493023/ (09-01-2025) + return 0; + } + registry.fill(HIST("hEventCount"), evSel_kIsGoodITSLayersAll); + } - registry.fill(HIST(Time[ft]) + HIST("/QA/hQXA_vs_vy"), v[1], qxa); - registry.fill(HIST(Time[ft]) + HIST("/QA/hQYA_vs_vy"), v[1], qya); - registry.fill(HIST(Time[ft]) + HIST("/QA/hQXC_vs_vy"), v[1], qxc); - registry.fill(HIST(Time[ft]) + HIST("/QA/hQYC_vs_vy"), v[1], qyc); + return 1; + } + + template + inline void fillCommonRegistry(double qxa, double qya, double qxc, double qyc, std::vector v, double centrality) + { + // loop for filling multiple histograms with different naming patterns + // Always fill the uncentered "raw" Q-vector histos! + static constexpr std::string_view Time[] = {"before", "after"}; - registry.fill(HIST(Time[ft]) + HIST("/QA/hQXA_vs_vz"), v[2], qxa); - registry.fill(HIST(Time[ft]) + HIST("/QA/hQYA_vs_vz"), v[2], qya); - registry.fill(HIST(Time[ft]) + HIST("/QA/hQXC_vs_vz"), v[2], qxc); - registry.fill(HIST(Time[ft]) + HIST("/QA/hQYC_vs_vz"), v[2], qyc); + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hZNA_Qx_vs_Qy"), qxa, qya); + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hZNC_Qx_vs_Qy"), qxc, qyc); + + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQXA_QXC_vs_cent"), centrality, qxa * qxc); + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQYA_QYC_vs_cent"), centrality, qya * qyc); + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQYA_QXC_vs_cent"), centrality, qya * qxc); + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQXA_QYC_vs_cent"), centrality, qxa * qyc); + + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQXA_vs_cent"), centrality, qxa); + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQYA_vs_cent"), centrality, qya); + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQXC_vs_cent"), centrality, qxc); + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQYC_vs_cent"), centrality, qyc); + + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQXA_vs_vx"), v[0], qxa); + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQYA_vs_vx"), v[0], qya); + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQXC_vs_vx"), v[0], qxc); + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQYC_vs_vx"), v[0], qyc); + + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQXA_QXC_vs_vx"), v[0], qxa * qxc); + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQYA_QYC_vs_vx"), v[0], qya * qyc); + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQYA_QXC_vs_vx"), v[0], qya * qxc); + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQXA_QYC_vs_vx"), v[0], qxa * qyc); + + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQXA_vs_vy"), v[1], qxa); + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQYA_vs_vy"), v[1], qya); + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQXC_vs_vy"), v[1], qxc); + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQYC_vs_vy"), v[1], qyc); + + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQXA_QXC_vs_vy"), v[1], qxa * qxc); + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQYA_QYC_vs_vy"), v[1], qya * qyc); + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQYA_QXC_vs_vy"), v[1], qya * qxc); + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQXA_QYC_vs_vy"), v[1], qxa * qyc); + + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQXA_vs_vz"), v[2], qxa); + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQYA_vs_vz"), v[2], qya); + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQXC_vs_vz"), v[2], qxc); + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQYC_vs_vz"), v[2], qyc); + + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQXA_QXC_vs_vz"), v[2], qxa * qxc); + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQYA_QYC_vs_vz"), v[2], qya * qyc); + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQYA_QXC_vs_vz"), v[2], qya * qxc); + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQXA_QYC_vs_vz"), v[2], qxa * qyc); // add psi!! double psiA = 1.0 * std::atan2(qxc, qxa); - registry.fill(HIST(Time[ft]) + HIST("/QA/hSPplaneA"), psiA, centrality, 1); + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hSPplaneA"), psiA, centrality, 1); double psiC = 1.0 * std::atan2(qyc, qya); - registry.fill(HIST(Time[ft]) + HIST("/QA/hSPplaneC"), psiC, centrality, 1); + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hSPplaneC"), psiC, centrality, 1); double psiFull = 1.0 * std::atan2(qxc + qyc, qxa + qya); - registry.fill(HIST(Time[ft]) + HIST("/QA/hSPplaneFull"), psiFull, centrality, 1); + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hSPplaneFull"), psiFull, centrality, 1); } - void loadCalibrations(int iteration, int step, uint64_t timestamp, std::string ccdb_dir, std::vector names) + template + void loadCalibrations(uint64_t timestamp, std::string ccdb_dir) { // iteration = 0 (Energy calibration) -> step 0 only // iteration 1,2,3,4,5 = recentering -> 5 steps per iteration (1x 4D + 4x 1D) - if (cal.calibfilesLoaded[iteration][step]) + if (cal.calibfilesLoaded[cm]) return; if (ccdb_dir.empty() == false) { - - cal.calibList[iteration][step] = ccdb->getForTimeStamp(ccdb_dir, timestamp); - - if (cal.calibList[iteration][step]) { - for (std::size_t i = 0; i < names.size(); i++) { - TObject* obj = reinterpret_cast(cal.calibList[iteration][step]->FindObject(Form("%s", names[i].Data()))); - if (!obj) { - if (counter < 1) { - LOGF(error, "Object %s not found!!", names[i].Data()); - return; - } - } - // Try to cast to TProfile - if (TProfile* profile = dynamic_cast(obj)) { - if (profile->GetEntries() < 1) { - if (counter < 1) - LOGF(info, "%s (TProfile) is empty! Produce calibration file at given step", names[i].Data()); - cal.calibfilesLoaded[iteration][step] = false; - return; - } - if (counter < 1) - LOGF(info, "Loaded TProfile: %s", names[i].Data()); - } else if (TProfile2D* profile2D = dynamic_cast(obj)) { - if (profile2D->GetEntries() < 1) { - if (counter < 1) - LOGF(info, "%s (TProfile2D) is empty! Produce calibration file at given step", names[i].Data()); - cal.calibfilesLoaded[iteration][step] = false; - return; - } - if (counter < 1) - LOGF(info, "Loaded TProfile2D: %s", names[i].Data()); - } else if (THnSparse* sparse = dynamic_cast(obj)) { - if (sparse->GetEntries() < 1) { - if (counter < 1) - LOGF(info, "%s (THnSparse) is empty! Produce calibration file at given step", names[i].Data()); - cal.calibfilesLoaded[iteration][step] = false; - return; - } - if (counter < 1) - LOGF(info, "Loaded THnSparse: %s", names[i].Data()); - } - } // end of for loop - } else { - // when (cal.calib[iteration][step])=false! - if (counter < 1) - LOGF(warning, "Could not load TList with calibration histos from %s", ccdb_dir.c_str()); - cal.calibfilesLoaded[iteration][step] = false; - return; + cal.calibList[cm] = ccdb->getForTimeStamp(ccdb_dir, timestamp); + cal.calibfilesLoaded[cm] = true; + LOGF(info, "Loaded calibration histos from %s", ccdb_dir.c_str()); + if (cm == kRec) { + cal.atStep = 5; + cal.atIteration = 5; } - if (counter < 1) - LOGF(info, "<--------OK----------> Calibrations loaded for cal.calibfilesLoaded[%i][%i]", iteration, step); - cal.calibfilesLoaded[iteration][step] = true; - cal.atIteration = iteration; - cal.atStep = step; - return; } else { - if (counter < 1) - LOGF(info, "<--------X-----------> Calibrations not loaded for iteration %i and step %i cfg = empty!", iteration, step); + LOGF(info, "No ccdb path given for calibration histos. Do not recenter."); } } - template - double getCorrection(int iteration, int step, const char* objName) + template + double getCorrection(const char* objName, int iteration = 0, int step = 0) { T* hist = nullptr; double calibConstant{0}; - hist = reinterpret_cast(cal.calibList[iteration][step]->FindObject(Form("%s", objName))); + if (cm == kEnergyCal) { + TList* list = cal.calibList[cm]; + hist = reinterpret_cast(list->FindObject(Form("%s", objName))); + } else if (cm == kMeanv) { + TList* list = cal.calibList[cm]; + hist = reinterpret_cast(list->FindObject(Form("%s", objName))); + } else if (cm == kRec) { + TList* list = reinterpret_cast(cal.calibList[cm]->FindObject(Form("it%i_step%i", iteration, step))); + if (!list) { + LOGF(fatal, "No calibration list for iteration %i and step %i", iteration, step); + } + hist = reinterpret_cast(list->FindObject(Form("%s", objName))); + if (!hist) { + LOGF(fatal, "No calibration histo for iteration %i and step %i -> %s", iteration, step, objName); + } + cal.atStep = step; + cal.atIteration = iteration; + } + if (!hist) { LOGF(fatal, "%s not available.. Abort..", objName); } @@ -402,9 +522,9 @@ struct ZdcQVectors { { // for Q-vector calculation // A[0] & C[1] - std::vector sumZN(2, 0.); - std::vector xEnZN(2, 0.); - std::vector yEnZN(2, 0.); + std::vector sumZN(2, 0.), sumZN_noEq(2, 0.); + std::vector xEnZN(2, 0.), xEnZN_noEq(2, 0.); + std::vector yEnZN(2, 0.), yEnZN_noEq(2, 0.); isSelected = true; @@ -419,15 +539,16 @@ struct ZdcQVectors { if (cfgNGlobal) cent = collision.centNGlobal(); - if (cent < 0 || cent > 90) { + registry.fill(HIST("QA/centrality_before"), cent); + + if (!eventSelected(collision, cent)) { + // event not selected isSelected = false; spTableZDC(runnumber, cent, v[0], v[1], v[2], 0, 0, 0, 0, isSelected, 0, 0); counter++; return; } - registry.fill(HIST("QA/centrality_before"), cent); - const auto& foundBC = collision.foundBC_as(); if (!foundBC.has_zdc()) { @@ -445,35 +566,33 @@ struct ZdcQVectors { // load new calibrations for new runs only if (runnumber != lastRunNumber) { - cal.calibfilesLoaded.clear(); - cal.calibfilesLoaded.resize(7, std::vector(8, false)); - - cal.calibList.clear(); - cal.calibList.resize(7, std::vector(8, nullptr)); + cal.calibfilesLoaded[2] = false; + cal.calibList[2] = nullptr; lastRunNumber = runnumber; } const auto& zdcCol = foundBC.zdc(); // Get the raw energies eZN[8] (not the common A,C) - for (int tower = 0; tower < 8; tower++) { - eZN[tower] = (tower < 4) ? zdcCol.energySectorZNA()[tower] : zdcCol.energySectorZNC()[tower % 4]; + int nTowers = 8; + int nTowersPerSide = 4; + + for (int tower = 0; tower < nTowers; tower++) { + eZN[tower] = (tower < nTowersPerSide) ? zdcCol.energySectorZNA()[tower] : zdcCol.energySectorZNC()[tower % nTowersPerSide]; } // load the calibration histos for iteration 0 step 0 (Energy Calibration) - loadCalibrations(0, 0, foundBC.timestamp(), cfgEnergyCal.value, namesEcal); + loadCalibrations(foundBC.timestamp(), cfgEnergyCal.value); - if (!cal.calibfilesLoaded[0][0]) { + if (!cal.calibfilesLoaded[0]) { if (counter < 1) { LOGF(info, " --> No Energy calibration files found.. -> Only Energy calibration will be done. "); } } // load the calibrations for the mean v - loadCalibrations(0, 1, foundBC.timestamp(), cfgMeanv.value, vnames); + loadCalibrations(foundBC.timestamp(), cfgMeanv.value); - if (!cal.calibfilesLoaded[0][1]) { - if (counter < 1) - LOGF(warning, " --> No mean V found.. -> THis wil lead to wrong axis for vx, vy (will be created in vmean/)"); + if (!cal.calibfilesLoaded[1]) { registry.get(HIST("vmean/hvertex_vx"))->Fill(Form("%d", runnumber), v[0]); registry.get(HIST("vmean/hvertex_vy"))->Fill(Form("%d", runnumber), v[1]); registry.get(HIST("vmean/hvertex_vz"))->Fill(Form("%d", runnumber), v[2]); @@ -482,10 +601,10 @@ struct ZdcQVectors { bool isZNAhit = true; bool isZNChit = true; - for (int i = 0; i < 8; ++i) { - if (i < 4 && eZN[i] <= 0) + for (int i = 0; i < nTowers; ++i) { + if (i < nTowersPerSide && eZN[i] <= 0) isZNAhit = false; - if (i > 3 && eZN[i] <= 0) + if (i >= nTowersPerSide && eZN[i] <= 0) isZNChit = false; } @@ -518,7 +637,10 @@ struct ZdcQVectors { return; } - if (!cal.calibfilesLoaded[0][0]) { + registry.fill(HIST("hEventCount"), evSel_isSelectedZDC); + + // Do not continue if Energy calibration is not loaded + if (!cal.calibfilesLoaded[0]) { counter++; isSelected = false; spTableZDC(runnumber, centrality, v[0], v[1], v[2], 0, 0, 0, 0, isSelected, 0, 0); @@ -527,8 +649,8 @@ struct ZdcQVectors { // Now start gain equalisation! // Fill the list with calibration constants. - for (int tower = 0; tower < 10; tower++) { - meanEZN[tower] = getCorrection(0, 0, namesEcal[tower].Data()); + for (int tower = 0; tower < (nTowers + 2); tower++) { + meanEZN[tower] = getCorrection(namesEcal[tower].Data()); } // Use the calibration constants but now only loop over towers 1-4 @@ -537,72 +659,99 @@ struct ZdcQVectors { for (const auto& tower : towersNocom) { if (meanEZN[tower] > 0) { - double ecommon = (tower > 4) ? meanEZN[5] : meanEZN[0]; + double ecommon = (tower > nTowersPerSide) ? meanEZN[5] : meanEZN[0]; e[calibtower] = eZN[calibtower] * (0.25 * ecommon) / meanEZN[tower]; } calibtower++; } - for (int i = 0; i < 4; i++) { + for (int i = 0; i < nTowersPerSide; i++) { float bincenter = i + .5; registry.fill(HIST("QA/ZNA_Energy"), bincenter, eZN[i]); registry.fill(HIST("QA/ZNA_Energy"), bincenter + 4, e[i]); registry.fill(HIST("QA/ZNC_Energy"), bincenter, eZN[i + 4]); registry.fill(HIST("QA/ZNC_Energy"), bincenter + 4, e[i + 4]); + + registry.get(HIST("QA/before/ZNA_pm1"))->Fill(Form("%d", runnumber), eZN[0]); + registry.get(HIST("QA/before/ZNA_pm2"))->Fill(Form("%d", runnumber), eZN[1]); + registry.get(HIST("QA/before/ZNA_pm3"))->Fill(Form("%d", runnumber), eZN[2]); + registry.get(HIST("QA/before/ZNA_pm4"))->Fill(Form("%d", runnumber), eZN[3]); + registry.get(HIST("QA/before/ZNC_pm1"))->Fill(Form("%d", runnumber), eZN[4]); + registry.get(HIST("QA/before/ZNC_pm2"))->Fill(Form("%d", runnumber), eZN[5]); + registry.get(HIST("QA/before/ZNC_pm3"))->Fill(Form("%d", runnumber), eZN[6]); + registry.get(HIST("QA/before/ZNC_pm4"))->Fill(Form("%d", runnumber), eZN[7]); + + registry.get(HIST("QA/after/ZNA_pm1"))->Fill(Form("%d", runnumber), e[0]); + registry.get(HIST("QA/after/ZNA_pm2"))->Fill(Form("%d", runnumber), e[1]); + registry.get(HIST("QA/after/ZNA_pm3"))->Fill(Form("%d", runnumber), e[2]); + registry.get(HIST("QA/after/ZNA_pm4"))->Fill(Form("%d", runnumber), e[3]); + registry.get(HIST("QA/after/ZNC_pm1"))->Fill(Form("%d", runnumber), e[4]); + registry.get(HIST("QA/after/ZNC_pm2"))->Fill(Form("%d", runnumber), e[5]); + registry.get(HIST("QA/after/ZNC_pm3"))->Fill(Form("%d", runnumber), e[6]); + registry.get(HIST("QA/after/ZNC_pm4"))->Fill(Form("%d", runnumber), e[7]); } // Now calculate Q-vector - for (int tower = 0; tower < 8; tower++) { - int side = (tower > 3) ? 1 : 0; - int sector = tower % 4; + for (int tower = 0; tower < nTowers; tower++) { + int side = (tower >= nTowersPerSide) ? 1 : 0; + int sector = tower % nTowersPerSide; double energy = std::pow(e[tower], alphaZDC); sumZN[side] += energy; xEnZN[side] += (side == 0) ? -1.0 * pxZDC[sector] * energy : pxZDC[sector] * energy; yEnZN[side] += pyZDC[sector] * energy; + + // Also calculate the Q-vector for the non-equalized energy + double energyNoEq = std::pow(eZN[tower], alphaZDC); + sumZN_noEq[side] += energyNoEq; + xEnZN_noEq[side] += (side == 0) ? -1.0 * pxZDC[sector] * energyNoEq : pxZDC[sector] * energyNoEq; + yEnZN_noEq[side] += pyZDC[sector] * energyNoEq; } // "QXA", "QYA", "QXC", "QYC" - for (int i = 0; i < 2; ++i) { + int sides = 2; + for (int i = 0; i < sides; ++i) { if (sumZN[i] > 0) { q[i * 2] = xEnZN[i] / sumZN[i]; // for QXA[0] and QXC[2] q[i * 2 + 1] = yEnZN[i] / sumZN[i]; // for QYA[1] and QYC[3] } + if (sumZN_noEq[i] > 0) { + qNoEq[i * 2] = xEnZN_noEq[i] / sumZN_noEq[i]; // for QXA[0] and QXC[2] + qNoEq[i * 2 + 1] = yEnZN_noEq[i] / sumZN_noEq[i]; // for QYA[1] and QYC[3] + } } - if (cal.calibfilesLoaded[0][1]) { - v[0] = v[0] - getCorrection(0, 1, vnames[0].Data()); - v[1] = v[1] - getCorrection(0, 1, vnames[1].Data()); + if (cal.calibfilesLoaded[1]) { + v[0] = v[0] - getCorrection(vnames[0].Data()); + v[1] = v[1] - getCorrection(vnames[1].Data()); + } else { + LOGF(warning, " --> No mean V found.. -> THis wil lead to wrong axis for vx, vy (will be created in vmean/)"); + return; } - for (int iteration = 1; iteration < 6; iteration++) { - std::vector ccdbDirs; - if (iteration == 1) - ccdbDirs = cfgRec1.value; - if (iteration == 2) - ccdbDirs = cfgRec2.value; - if (iteration == 3) - ccdbDirs = cfgRec3.value; - if (iteration == 4) - ccdbDirs = cfgRec4.value; - if (iteration == 5) - ccdbDirs = cfgRec5.value; - - for (int step = 0; step < 5; step++) { - loadCalibrations(iteration, step, foundBC.timestamp(), (ccdbDirs)[step], names[step]); - } - } + loadCalibrations(foundBC.timestamp(), cfgRec.value); std::vector qRec(q); + registry.get(HIST("QA/before/ZNA_Qx"))->Fill(Form("%d", runnumber), q[0]); + registry.get(HIST("QA/before/ZNA_Qy"))->Fill(Form("%d", runnumber), q[1]); + registry.get(HIST("QA/before/ZNC_Qx"))->Fill(Form("%d", runnumber), q[2]); + registry.get(HIST("QA/before/ZNC_Qy"))->Fill(Form("%d", runnumber), q[3]); + + registry.get(HIST("QA/before/ZNA_Qx_noEq"))->Fill(Form("%d", runnumber), qNoEq[0]); + registry.get(HIST("QA/before/ZNA_Qy_noEq"))->Fill(Form("%d", runnumber), qNoEq[1]); + registry.get(HIST("QA/before/ZNC_Qx_noEq"))->Fill(Form("%d", runnumber), qNoEq[2]); + registry.get(HIST("QA/before/ZNC_Qy_noEq"))->Fill(Form("%d", runnumber), qNoEq[3]); + if (cal.atIteration == 0) { - if (isSelected) + if (isSelected && cfgFillCommonRegistry) fillCommonRegistry(q[0], q[1], q[2], q[3], v, centrality); spTableZDC(runnumber, centrality, v[0], v[1], v[2], q[0], q[1], q[2], q[3], isSelected, 0, 0); counter++; return; - } else if (cal.atIteration == 5 && cal.atStep == 4) { - fillCommonRegistry(q[0], q[1], q[2], q[3], v, centrality); + } else { + if (cfgFillCommonRegistry) + fillCommonRegistry(q[0], q[1], q[2], q[3], v, centrality); // vector of 4 std::vector corrQxA; @@ -612,18 +761,21 @@ struct ZdcQVectors { int pb = 0; - for (int it = 1; it < 6; it++) { - corrQxA.push_back(getCorrection(it, 0, names[0][0].Data())); - corrQyA.push_back(getCorrection(it, 0, names[0][1].Data())); - corrQxC.push_back(getCorrection(it, 0, names[0][2].Data())); - corrQyC.push_back(getCorrection(it, 0, names[0][3].Data())); + int nIterations = 5; + int nSteps = 5; + + for (int it = 1; it <= nIterations; it++) { + corrQxA.push_back(getCorrection(names[0][0].Data(), it, 1)); + corrQyA.push_back(getCorrection(names[0][1].Data(), it, 1)); + corrQxC.push_back(getCorrection(names[0][2].Data(), it, 1)); + corrQyC.push_back(getCorrection(names[0][3].Data(), it, 1)); pb++; - for (int step = 1; step < 5; step++) { - corrQxA.push_back(getCorrection(it, step, names[step][0].Data())); - corrQyA.push_back(getCorrection(it, step, names[step][1].Data())); - corrQxC.push_back(getCorrection(it, step, names[step][2].Data())); - corrQyC.push_back(getCorrection(it, step, names[step][3].Data())); + for (int step = 2; step <= nSteps; step++) { + corrQxA.push_back(getCorrection(names[step - 1][0].Data(), it, step)); + corrQyA.push_back(getCorrection(names[step - 1][1].Data(), it, step)); + corrQxC.push_back(getCorrection(names[step - 1][2].Data(), it, step)); + corrQyC.push_back(getCorrection(names[step - 1][3].Data(), it, step)); pb++; } } @@ -635,9 +787,13 @@ struct ZdcQVectors { qRec[3] -= corrQyC[cor]; } - if (isSelected) { + if (isSelected && cfgFillCommonRegistry) { fillCommonRegistry(qRec[0], qRec[1], qRec[2], qRec[3], v, centrality); registry.fill(HIST("QA/centrality_after"), centrality); + registry.get(HIST("QA/after/ZNA_Qx"))->Fill(Form("%d", runnumber), qRec[0]); + registry.get(HIST("QA/after/ZNA_Qy"))->Fill(Form("%d", runnumber), qRec[1]); + registry.get(HIST("QA/after/ZNC_Qx"))->Fill(Form("%d", runnumber), qRec[2]); + registry.get(HIST("QA/after/ZNC_Qy"))->Fill(Form("%d", runnumber), qRec[3]); } spTableZDC(runnumber, centrality, v[0], v[1], v[2], qRec[0], qRec[1], qRec[2], qRec[3], isSelected, cal.atIteration, cal.atStep); @@ -646,9 +802,6 @@ struct ZdcQVectors { counter++; return; - } else { - if (counter < 1) - LOGF(info, "Recentering not complete!! q-vectors at iteration %i and step %i!!!!", cal.atIteration, cal.atStep + 1); } LOGF(warning, "We return without saving table... -> THis is a problem"); } // end of process diff --git a/PWGCF/Flow/Tasks/CMakeLists.txt b/PWGCF/Flow/Tasks/CMakeLists.txt index c62480f8d79..c59895487cf 100644 --- a/PWGCF/Flow/Tasks/CMakeLists.txt +++ b/PWGCF/Flow/Tasks/CMakeLists.txt @@ -60,7 +60,7 @@ o2physics_add_dpl_workflow(flow-gfw-omega-xi COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(flow-pid-cme - SOURCES pidcme.cxx + SOURCES flowPidCme.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::GFWCore COMPONENT_NAME Analysis) @@ -78,3 +78,8 @@ o2physics_add_dpl_workflow(flow-efficiency-casc SOURCES flowEfficiencyCasc.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::GFWCore COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(flow-ese-p-he3 + SOURCES flowEsePHe3.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::GFWCore + COMPONENT_NAME Analysis) diff --git a/PWGCF/Flow/Tasks/flowEsePHe3.cxx b/PWGCF/Flow/Tasks/flowEsePHe3.cxx new file mode 100644 index 00000000000..61582f233b3 --- /dev/null +++ b/PWGCF/Flow/Tasks/flowEsePHe3.cxx @@ -0,0 +1,983 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// 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. + +/// \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 "Framework/ASoA.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/runDataProcessing.h" +#include "Framework/RunningWorkflowInfo.h" +#include "Framework/StaticFor.h" + +#include "Common/DataModel/Qvectors.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/TrackSelectionTables.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/Core/EventPlaneHelper.h" +#include "Common/Core/TrackSelection.h" +#include "Common/DataModel/PIDResponse.h" +#include "Common/DataModel/PIDResponseITS.h" + +#include "CommonConstants/PhysicsConstants.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; + +namespace o2::aod +{ +namespace flow_ese_p_he3 +{ +DECLARE_SOA_COLUMN(NPidFlag, nPidFlag, int8_t); // unqualified -1, hadron 0, proton 1, he3 2, proton+he3 3 +} // namespace flow_ese_p_he3 +DECLARE_SOA_TABLE(PHe3ESEFlags, "AOD", "PHe3ESEFlags", flow_ese_p_he3::NPidFlag); +} // namespace o2::aod + +namespace pid_flags +{ +// constexpr int8_t kUnqualified = -1; +// constexpr int8_t kUnPOIHadron = 0; +constexpr int8_t kProton = 1; +constexpr int8_t kHe3 = 2; +constexpr int8_t kProtonHe3 = 3; +} // namespace pid_flags + +namespace event_selection +{ +constexpr int kFT0AV0ASigma = 5; +} + +namespace fourier_mode +{ +// constexpr int kMode1 = 1; +constexpr int kMode2 = 2; +// constexpr int kMode3 = 3; +} // namespace fourier_mode + +using TracksPID = soa::Join; +struct FillPIDcolums { + + HistogramRegistry histosQA{"histosQAPID", {}, OutputObjHandlingPolicy::AnalysisObject}; + + Configurable cfgMinPtPID{"cfgMinPtPID", 0.15, "Minimum track #P_{t} for PID"}; + Configurable cfgMaxPtPID{"cfgMaxPtPID", 99.9, "Maximum track #P_{t} for PID"}; + Configurable cfgMaxEtaPID{"cfgMaxEtaPID", 0.8, "Maximum track #eta for PID"}; + Configurable cfgMinTPCChi2NCl{"cfgMinTPCChi2NCl", 0, "Minimum chi2 per cluster TPC for PID if not use costom track cuts"}; + Configurable cfgMinChi2NClITS{"cfgMinChi2NClITS", 0, "Minimum chi2 per cluster ITS for PID if not use costom track cuts"}; + Configurable cfgMaxTPCChi2NCl{"cfgMaxTPCChi2NCl", 4, "Maximum chi2 per cluster TPC for PID if not use costom track cuts"}; + Configurable cfgMaxChi2NClITS{"cfgMaxChi2NClITS", 36, "Maximum chi2 per cluster ITS for PID if not use costom track cuts"}; + Configurable cfgMinTPCCls{"cfgMinTPCCls", 70, "Minimum TPC clusters for PID if not use costom track cuts"}; + Configurable cfgMinITSCls{"cfgMinITSCls", 1, "Minimum ITS clusters for PID if not use costom track cuts"}; + Configurable cfgMaxTPCCls{"cfgMaxTPCCls", 999, "Max TPC clusters for PID if not use costom track cuts"}; + Configurable cfgMaxITSCls{"cfgMaxITSCls", 999, "Max ITS clusters for PID if not use costom track cuts"}; + Configurable cfgMaxDCAxy{"cfgMaxDCAxy", 99, "Maxium DCAxy for standard PID tracking"}; + Configurable cfgMaxDCAz{"cfgMaxDCAz", 2, "Maxium DCAz for standard PID tracking"}; + Configurable cfgPtMaxforTPCOnlyPIDPrton{"cfgPtMaxforTPCOnlyPIDPrton", 0.4, "Maxmium track pt for TPC only PID, at RMS PID mode for proton"}; + Configurable cfgPtMaxforTPCOnlyPIDHe3{"cfgPtMaxforTPCOnlyPIDHe3", 0.5, "Maxmium track pt for TPC only PID, at RMS PID mode for he3"}; + + Configurable cfgProtonPIDMode{"cfgProtonPIDMode", 2, "Proton PID mode: 0 for TPC + RMS(TPC,TOF), 1 for TPC only, 2 for TOF only"}; + Configurable cfgHe3PIDMode{"cfgHe3PIDMode", 1, "He3 PID mode: 0 for TPC + RMS(TPC,TOF), 1 for TPC only, 2 for TOF only"}; + + Configurable cfgOpenpassedITSNCls{"cfgOpenpassedITSNCls", false, "useTrackSelectionTables passedITSNCls for basic track selection"}; + Configurable cfgOpenpassedITSChi2NDF{"cfgOpenpassedITSChi2NDF", false, "useTrackSelectionTables passedITSChi2NDF for basic track selection"}; + Configurable cfgOpenpassedITSHits{"cfgOpenpassedITSHits", false, "useTrackSelectionTables passedITSHits for basic track selection"}; + Configurable cfgOpenpassedTPCChi2NDF{"cfgOpenpassedTPCChi2NDF", false, "useTrackSelectionTables passedTPCChi2NDF for basic track selection"}; + Configurable cfgOpenpassedTPCCrossedRowsOverNCls{"cfgOpenpassedTPCCrossedRowsOverNCls", false, "useTrackSelectionTables passedTPCCrossedRowsOverNCls for basic track selection"}; + Configurable cfgOpenpassedDCAxy{"cfgOpenpassedDCAxy", false, "useTrackSelectionTables passedDCAxy for basic track selection"}; + Configurable cfgOpenpassedDCAz{"cfgOpenpassedDCAz", false, "useTrackSelectionTables passedDCAz for basic track selection"}; + + Configurable cfgQuietMode{"cfgQuietMode", false, "open quiet mode for saving cpu cost and only do some basic QA plots"}; + Configurable cfgOpenPIDITSProton{"cfgOpenPIDITSProton", true, "open ITS assistance cut for proton PID"}; + Configurable cfgOpenPIDITSHe3{"cfgOpenPIDITSHe3", false, "open ITS assistance cut for He3 PID"}; + Configurable cfgOpenPIDByPtProtonMain{"cfgOpenPIDByPtProtonMain", false, "Selection Proton by pt its pt binnings for main selection"}; + Configurable cfgOpenPIDByPtHe3Main{"cfgOpenPIDByPtHe3Main", false, "Selection He3 by pt its pt binnings for main selection"}; + Configurable cfgOpenPIDByPtProtonITS{"cfgOpenPIDByPtProtonITS", false, "Selection Proton by pt its pt binnings for ITS selection"}; + Configurable cfgOpenPIDByPtHe3ITS{"cfgOpenPIDByPtHe3ITS", false, "Selection He3 by pt its pt binnings for ITS selection"}; + Configurable cfgOpenHe3ITSPtCut{"cfgOpenHe3ITSPtCut", true, "Do He3 ITS contamination cut"}; + Configurable cfgOpenAllowCrossTrack{"cfgOpenAllowCrossTrack", false, "Allow one track to be identified as different kind of PID particles"}; + + Configurable cfgOpenPlotnSigmaTOFITSPt{"cfgOpenPlotnSigmaTOFITSPt", true, "plot nSigmaTOF vs nSigmaITS vs Pt"}; + Configurable cfgOpenPlotnSigmaITSTPCPt{"cfgOpenPlotnSigmaITSTPCPt", true, "plot nSigmaITS vs nSigmaTOF vs Pt"}; + Configurable cfgOpenPlotnSigmaTOFTPCPt{"cfgOpenPlotnSigmaTOFTPCPt", true, "plot nSigmaTOF vs nSigmaTPC vs Pt"}; + + Configurable> cfgPtCutProton{"cfgPtCutProton", {0.15, 99.}, "Pt limit for Proton"}; + Configurable> cfgPtCutHe3{"cfgPtCutHe3", {0.15, 99.}, "Pt limit for He3"}; + Configurable> cfgnSigmaCutTPCProton{"cfgnSigmaCutTPCProton", {-3, 3}, "TPC nsigma cut limit for Proton"}; + Configurable> cfgnSigmaCutTPCHe3{"cfgnSigmaCutTPCHe3", {-2, 2}, "TPC nsigma cut limit for He3"}; + Configurable> cfgnSigmaCutTOFProton{"cfgnSigmaCutTOFProton", {-1.5, 1.5}, "TOF nsigma cut limit for Proton"}; + Configurable> cfgnSigmaCutTOFHe3{"cfgnSigmaCutTOFHe3", {-1.5, 1.5}, "TOF nsigma cut limit for He3"}; + Configurable> cfgnSigmaCutITSProton{"cfgnSigmaCutITSProton", {-3, 3}, "ITS nsigma cut limit for Proton"}; + Configurable> cfgnSigmaCutITSHe3{"cfgnSigmaCutITSHe3", {-3, 3}, "ITS nsigma cut limit for He3"}; + Configurable> cfgnSigmaCutRMSProton{"cfgnSigmaCutRMSProton", {-3, 3}, "RMS nsigma cut limit for Proton"}; + Configurable> cfgnSigmaCutRMSHe3{"cfgnSigmaCutRMSHe3", {-3, 3}, "RMS nsigma cut limit for He3"}; + + Configurable> cfgPtBinProtonPID{"cfgPtBinProtonPID", {0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.25, 1.5, 1.75, 2.0, 2.25, 2.5, 3.0, 3.5, 4.0, 5.0, 6.0}, "pt bin for pion PIDnsigma"}; + Configurable> cfgPtBinHe3PID{"cfgPtBinHe3PID", {2, 2.2, 2.4, 2.6, 2.8, 3, 3.2, 3.6, 4, 4.4, 4.8, 5.2, 5.6, 6, 6.4, 7.2, 8, 10}, "pt bin for pion PIDnsigma"}; + + Configurable> cfgnSigmaTPCProtonPtUpper{"cfgnSigmaTPCProtonPtUpper", {3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}, "nSigmaTPC cut upper limit anchored to proton pt bins"}; + Configurable> cfgnSigmaTOFProtonPtUpper{"cfgnSigmaTOFProtonPtUpper", {1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5}, "nSigmaTOF cut upper limit anchored to proton pt bins"}; + Configurable> cfgnSigmaITSProtonPtUpper{"cfgnSigmaITSProtonPtUpper", {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}, "nSigmaITS cut upper limit anchored to proton pt bins"}; + Configurable> cfgnSigmaRMSProtonPtUpper{"cfgnSigmaRMSProtonPtUpper", {3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}, "nSigmaRMS cut upper limit anchored to proton pt bins"}; + Configurable> cfgnSigmaTPCProtonPtLower{"cfgnSigmaTPCProtonPtLower", {-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3}, "nSigmaTPC cut lower limit anchored to proton pt bins"}; + Configurable> cfgnSigmaTOFProtonPtLower{"cfgnSigmaTOFProtonPtLower", {-1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5}, "nSigmaTOF cut lower limit anchored to proton pt bins"}; + Configurable> cfgnSigmaITSProtonPtLower{"cfgnSigmaITSProtonPtLower", {-2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2}, "nSigmaITS cut lower limit anchored to proton pt bins"}; + Configurable> cfgnSigmaRMSProtonPtLower{"cfgnSigmaRMSProtonPtLower", {-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3}, "nSigmaRMS cut lower limit anchored to proton pt bins"}; + Configurable> cfgnSigmaTPCHe3PtUpper{"cfgnSigmaTPCHe3PtUpper", {3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}, "nSigmaTPC cut upper limit anchored to He3 pt bins"}; + Configurable> cfgnSigmaTOFHe3PtUpper{"cfgnSigmaTOFHe3PtUpper", {1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5}, "nSigmaTOF cut upper limit anchored to He3 pt bins"}; + Configurable> cfgnSigmaITSHe3PtUpper{"cfgnSigmaITSHe3PtUpper", {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}, "nSigmaITS cut upper limit anchored to He3 pt bins"}; + Configurable> cfgnSigmaRMSHe3PtUpper{"cfgnSigmaRMSHe3PtUpper", {3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}, "nSigmaRMS cut upper limit anchored to He3 pt bins"}; + Configurable> cfgnSigmaTPCHe3PtLower{"cfgnSigmaTPCHe3PtLower", {-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3}, "nSigmaTPC cut lower limit anchored to He3 pt bins"}; + Configurable> cfgnSigmaTOFHe3PtLower{"cfgnSigmaTOFHe3PtLower", {-1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5}, "nSigmaTOF cut lower limit anchored to He3 pt bins"}; + Configurable> cfgnSigmaITSHe3PtLower{"cfgnSigmaITSHe3PtLower", {-2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2}, "nSigmaITS cut lower limit anchored to He3 pt bins"}; + Configurable> cfgnSigmaRMSHe3PtLower{"cfgnSigmaRMSHe3PtLower", {-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3}, "nSigmaRMS cut lower limit anchored to He3 pt bins"}; + + ConfigurableAxis cfgrigidityBins{"cfgrigidityBins", {200, -10.f, 10.f}, "Binning for rigidity #it{p}^{TPC}/#it{z}"}; + ConfigurableAxis cfgdedxBins{"cfgdedxBins", {1000, 0.f, 1000.f}, "Binning for dE/dx"}; + ConfigurableAxis cfgnSigmaBinsTPC{"cfgnSigmaBinsTPC", {200, -5.f, 5.f}, "Binning for n sigma TPC"}; + ConfigurableAxis cfgnSigmaBinsTOF{"cfgnSigmaBinsTOF", {200, -5.f, 5.f}, "Binning for n sigma TOF"}; + ConfigurableAxis cfgnSigmaBinsITS{"cfgnSigmaBinsITS", {200, -5.f, 5.f}, "Binning for n sigma ITS"}; + ConfigurableAxis cfgnSigmaBinsRMS{"cfgnSigmaBinsRMS", {100, 0.f, 10.f}, "Combination Binning for TPC&TOF nsigma"}; + ConfigurableAxis cfgaxisptPID{"cfgaxisptPID", {120, 0, 12}, "Binning for P_{t} PID"}; + ConfigurableAxis cfgaxispPID{"cfgaxispPID", {50, 0, 5}, "Binning for P PID"}; + ConfigurableAxis cfgaxisetaPID{"cfgaxisetaPID", {90, -0.9, 0.9}, "Binning for Pt QA"}; + ConfigurableAxis cfgaxisDCAz{"cfgaxisDCAz", {200, -1, 1}, "Binning for DCAz"}; + ConfigurableAxis cfgaxisDCAxy{"cfgaxisDCAxy", {100, -0.5, 0.5}, "Binning for DCAxy"}; + ConfigurableAxis cfgaxisChi2Ncls{"cfgaxisChi2Ncls", {100, 0, 100}, "Binning for Chi2Ncls TPC/ITS"}; + + // Function for He3 TPC-ITS mismatching cuts referd to by chiara's slides + TF1* fNSigmaITSPt = nullptr; + + template + bool trackSelBasic(const TrackType track) + { + if ((track.pt() < cfgMinPtPID) || (track.pt() > cfgMaxPtPID)) + return false; + if (std::abs(track.eta()) > cfgMaxEtaPID) + return false; + if (cfgOpenpassedITSNCls) { + if (!track.passedITSNCls()) + return false; + } else { + if (track.itsNCls() < cfgMinITSCls || track.itsNCls() > cfgMaxITSCls) + return false; + } + if (cfgOpenpassedITSChi2NDF) { + if (!track.passedITSChi2NDF()) + return false; + } else { + if (track.itsChi2NCl() < cfgMinChi2NClITS || track.itsChi2NCl() > cfgMaxChi2NClITS) + return false; + } + if (cfgOpenpassedITSHits) { + if (!track.passedITSHits()) + return false; + } + if (cfgOpenpassedTPCChi2NDF) { + if (!track.passedTPCChi2NDF()) + return false; + } else { + if (track.tpcChi2NCl() < cfgMinTPCChi2NCl || track.tpcChi2NCl() > cfgMaxTPCChi2NCl) + return false; + } + if (cfgOpenpassedTPCCrossedRowsOverNCls) { + if (!track.passedTPCCrossedRowsOverNCls()) + return false; + } + if (cfgOpenpassedDCAxy) { + if (!track.passedDCAxy()) + return false; + } else { + if (std::abs(track.dcaXY()) > cfgMaxDCAxy) + return false; + } + if (cfgOpenpassedDCAz) { + if (!track.passedDCAz()) + return false; + } else { + if (std::abs(track.dcaZ()) > cfgMaxDCAz) + return false; + } + if (track.tpcNClsFound() < cfgMinTPCCls || track.tpcNClsFound() > cfgMaxTPCCls) + return false; + return true; + } + + template + bool pidProtonSel(const TrackType track, float nSigmaLower, float nSigmaUpper) + { // proton == 1 , He3 == 2 + if (track.pt() < cfgPtCutProton.value[0] || track.pt() > cfgPtCutProton.value[1]) + return false; + float nSigmaUse = -999; + switch (cfgProtonPIDMode) { + case 0: // RMS + nSigmaUse = (track.pt() > cfgPtMaxforTPCOnlyPIDPrton) ? std::hypot(track.tpcNSigmaPr(), track.tofNSigmaPr()) : track.tpcNSigmaPr(); + break; + case 1: // TPC only + nSigmaUse = track.tpcNSigmaPr(); + break; + case 2: // TOF only + nSigmaUse = track.tofNSigmaPr(); + break; + } + if (nSigmaUse < nSigmaLower || nSigmaUse > nSigmaUpper) { + return false; + } else { + return true; + } + } + + template + bool pidHe3Sel(const TrackType track, float nSigmaLower, float nSigmaUpper) + { // proton == 1 , He3 == 2 + if (track.pt() < cfgPtCutHe3.value[0] || track.pt() > cfgPtCutHe3.value[1]) + return false; + float nSigmaUse = -999; + switch (cfgHe3PIDMode) { + case 0: // RMS + nSigmaUse = (track.pt() > cfgPtMaxforTPCOnlyPIDHe3) ? std::hypot(track.tpcNSigmaHe(), track.tofNSigmaHe()) : track.tpcNSigmaHe(); + break; + case 1: // TPC only + nSigmaUse = track.tpcNSigmaHe(); + break; + case 2: // TOF only + nSigmaUse = track.tofNSigmaHe(); + break; + } + if (nSigmaUse < nSigmaLower || nSigmaUse > nSigmaUpper) { + return false; + } else { + return true; + } + } + + template + int crossTrackID(const TrackType track) + { + if (track.tpcNSigmaPr() < track.tpcNSigmaHe()) { + return 0; + } else { + return 1; + } + } + + void init(InitContext const&) + { + if (cfgOpenHe3ITSPtCut) { + fNSigmaITSPt = new TF1("fNSigmaITSPt", "[0]/pow(x,0.5) - [2]", 0.02, 1000); + fNSigmaITSPt->SetParameters(4.6, 0.5, 4.5); + } + AxisSpec axisITSNcls = {10, -1.5, 8.5, "ITSNcls"}; + AxisSpec axisTPCNcls = {160, 0, 160, "TPCNcls"}; + if (!cfgQuietMode) { + histosQA.add("QA/hist_dEdxTPC_All", ";#it{p}^{TPC}/#it{z} (GeV/c);d#it{E}/d#it{x}", {HistType::kTH2F, {cfgrigidityBins, cfgdedxBins}}); + histosQA.add("QA/Proton/hist_dEdxTPC_Pr", ";#it{p}^{TPC}/#it{z} (GeV/c);d#it{E}/d#it{x}", {HistType::kTH2F, {cfgrigidityBins, cfgdedxBins}}); + histosQA.add("QA/He3/hist_dEdxTPC_He3", ";#it{p}^{TPC}/#it{z} (GeV/c);d#it{E}/d#it{x}", {HistType::kTH2F, {cfgrigidityBins, cfgdedxBins}}); + histosQA.add("QA/hist_pt_All", ";#it{p}_{T};counts", {HistType::kTH1F, {cfgaxisptPID}}); + histosQA.add("QA/Proton/hist_pt_Pr", ";#it{p}_{T};counts", {HistType::kTH1F, {cfgaxisptPID}}); + histosQA.add("QA/He3/hist_pt_He3", ";#it{p}_{T};counts", {HistType::kTH1F, {cfgaxisptPID}}); + histosQA.add("QA/hist_eta_All", ";#it{#eta};counts", {HistType::kTH1F, {cfgaxisetaPID}}); + histosQA.add("QA/Proton/hist_eta_Pr", ";#it{#eta};counts", {HistType::kTH1F, {cfgaxisetaPID}}); + histosQA.add("QA/He3/hist_eta_He3", ";#it{#eta};counts", {HistType::kTH1F, {cfgaxisetaPID}}); + histosQA.add("QA/hist_ITSNcls_All", ";ITSNcls;counts", {HistType::kTH1F, {axisITSNcls}}); + histosQA.add("QA/Proton/hist_ITSNcls_Pr", ";ITSNcls;counts", {HistType::kTH1F, {axisITSNcls}}); + histosQA.add("QA/He3/hist_ITSNcls_He3", ";ITSNcls;counts", {HistType::kTH1F, {axisITSNcls}}); + histosQA.add("QA/hist_TPCNcls_All", ";TPCNcls;counts", {HistType::kTH1F, {axisTPCNcls}}); + histosQA.add("QA/Proton/hist_TPCNcls_Pr", ";TPCNcls;counts", {HistType::kTH1F, {axisTPCNcls}}); + histosQA.add("QA/He3/hist_TPCNcls_He3", ";TPCNcls;counts", {HistType::kTH1F, {axisTPCNcls}}); + histosQA.add("QA/hist_ITSChi2NDF_All", ";ITS#it{#chi^{2}}/NDF;counts", {HistType::kTH1F, {cfgaxisChi2Ncls}}); + histosQA.add("QA/Proton/hist_ITSChi2NDF_Pr", ";ITS#it{#chi^{2}}/NDF;counts", {HistType::kTH1F, {cfgaxisChi2Ncls}}); + histosQA.add("QA/He3/hist_ITSChi2NDF_He3", ";ITS#it{#chi^{2}}/NDF;counts", {HistType::kTH1F, {cfgaxisChi2Ncls}}); + histosQA.add("QA/hist_TPCChi2NDF_All", ";TPC#it{#chi^{2}}/NDF;counts", {HistType::kTH1F, {cfgaxisChi2Ncls}}); + histosQA.add("QA/Proton/hist_TPCChi2NDF_Pr", ";TPC#it{#chi^{2}}/NDF;counts", {HistType::kTH1F, {cfgaxisChi2Ncls}}); + histosQA.add("QA/He3/hist_TPCChi2NDF_He3", ";TPC#it{#chi^{2}}/NDF;counts", {HistType::kTH1F, {cfgaxisChi2Ncls}}); + histosQA.add("QA/hist_DCAxy_All", ";#it{DCA_{xy}};counts", {HistType::kTH1F, {cfgaxisDCAxy}}); + histosQA.add("QA/Proton/hist_DCAxy_Pr", ";#it{DCA_{xy}};counts", {HistType::kTH1F, {cfgaxisDCAxy}}); + histosQA.add("QA/He3/hist_DCAxy_He3", ";#it{DCA_{xy}};counts", {HistType::kTH1F, {cfgaxisDCAxy}}); + histosQA.add("QA/hist_DCAz_All", ";#it{DCA_{xy}};counts", {HistType::kTH1F, {cfgaxisDCAz}}); + histosQA.add("QA/Proton/hist_DCAz_Pr", ";#it{DCA_{xy}};counts", {HistType::kTH1F, {cfgaxisDCAz}}); + histosQA.add("QA/He3/hist_DCAz_He3", ";#it{DCA_{xy}};counts", {HistType::kTH1F, {cfgaxisDCAz}}); + histosQA.add("QA/Proton/hist_nSigmaTPC_Pr", ";n_{#sigma}TPC", {HistType::kTH1F, {cfgnSigmaBinsTPC}}); + histosQA.add("QA/Proton/hist_nSigmaTPCPt_Pr", ";#it{p}_{T};n_{#sigma}TPC", {HistType::kTH2F, {cfgaxisptPID, cfgnSigmaBinsTPC}}); + histosQA.add("QA/Proton/hist_nSigmaTOF_Pr", ";n_{#sigma}TOF", {HistType::kTH1F, {cfgnSigmaBinsTOF}}); + histosQA.add("QA/Proton/hist_nSigmaTOFPt_Pr", ";#it{p}_{T};n_{#sigma}TOF", {HistType::kTH2F, {cfgaxisptPID, cfgnSigmaBinsTOF}}); + histosQA.add("QA/Proton/hist_nSigmaITS_Pr", ";n_{#sigma}ITS", {HistType::kTH1F, {cfgnSigmaBinsITS}}); + histosQA.add("QA/Proton/hist_nSigmaITSPt_Pr", ";#it{p}_{T};n_{#sigma}ITS", {HistType::kTH2F, {cfgaxisptPID, cfgnSigmaBinsITS}}); + histosQA.add("QA/Proton/hist_nSigmaRMS_Pr", ";n_{#sigma}RMS", {HistType::kTH1F, {cfgnSigmaBinsRMS}}); + histosQA.add("QA/Proton/hist_nSigmaRMSPt_Pr", ";#it{p}_{T};n_{#sigma}RMS", {HistType::kTH2F, {cfgaxisptPID, cfgnSigmaBinsRMS}}); + histosQA.add("QA/He3/hist_nSigmaTPC_He3", ";n_{#sigma}TPC", {HistType::kTH1F, {cfgnSigmaBinsTPC}}); + histosQA.add("QA/He3/hist_nSigmaTPCPt_He3", ";#it{p}_{T};n_{#sigma}TPC", {HistType::kTH2F, {cfgaxisptPID, cfgnSigmaBinsTPC}}); + histosQA.add("QA/He3/hist_nSigmaTOF_He3", ";n_{#sigma}TOF", {HistType::kTH1F, {cfgnSigmaBinsTOF}}); + histosQA.add("QA/He3/hist_nSigmaTOFPt_He3", ";#it{p}_{T};n_{#sigma}TOF", {HistType::kTH2F, {cfgaxisptPID, cfgnSigmaBinsTOF}}); + histosQA.add("QA/He3/hist_nSigmaITS_He3", ";n_{#sigma}ITS", {HistType::kTH1F, {cfgnSigmaBinsITS}}); + histosQA.add("QA/He3/hist_nSigmaITSPt_He3", ";#it{p}_{T};n_{#sigma}ITS", {HistType::kTH2F, {cfgaxisptPID, cfgnSigmaBinsITS}}); + histosQA.add("QA/He3/hist_nSigmaRMS_He3", ";n_{#sigma}RMS", {HistType::kTH1F, {cfgnSigmaBinsRMS}}); + histosQA.add("QA/He3/hist_nSigmaRMSPt_He3", ";#it{p}_{T};n_{#sigma}RMS", {HistType::kTH2F, {cfgaxisptPID, cfgnSigmaBinsRMS}}); + if (cfgOpenHe3ITSPtCut) { + histosQA.add("QA/He3/hist_nSigmaITSPt_He3_unCuted", ";#it{p}_{T};n_{#sigma}ITS", {HistType::kTH2F, {cfgaxisptPID, cfgnSigmaBinsITS}}); + } + if (cfgOpenPlotnSigmaTOFITSPt) { + histosQA.add("QA/Proton/hist_nSigmaTOFITSPt_Pr", ";n_{#sigma}TOF;n_{#sigma}ITS;#it{p}_{T}", {HistType::kTH3F, {cfgnSigmaBinsTOF, cfgnSigmaBinsITS, cfgaxisptPID}}); + histosQA.add("QA/He3/hist_nSigmaTOFITSPt_He3", ";n_{#sigma}TOF;n_{#sigma}ITS;#it{p}_{T}", {HistType::kTH3F, {cfgnSigmaBinsTOF, cfgnSigmaBinsITS, cfgaxisptPID}}); + } + if (cfgOpenPlotnSigmaITSTPCPt) { + histosQA.add("QA/Proton/hist_nSigmaITSTPCPt_Pr", ";n_{#sigma}ITS;n_{#sigma}TPC;#it{p}_{T}", {HistType::kTH3F, {cfgnSigmaBinsITS, cfgnSigmaBinsTPC, cfgaxisptPID}}); + histosQA.add("QA/He3/hist_nSigmaITSTPCPt_He3", ";n_{#sigma}ITS;n_{#sigma}TPC;#it{p}_{T}", {HistType::kTH3F, {cfgnSigmaBinsITS, cfgnSigmaBinsTPC, cfgaxisptPID}}); + } + if (cfgOpenPlotnSigmaTOFTPCPt) { + histosQA.add("QA/Proton/hist_nSigmaTOFTPCPt_Pr", ";n_{#sigma}TOF;n_{#sigma}TPC;#it{p}_{T}", {HistType::kTH3F, {cfgnSigmaBinsTOF, cfgnSigmaBinsTPC, cfgaxisptPID}}); + histosQA.add("QA/He3/hist_nSigmaTOFTPCPt_He3", ";n_{#sigma}TOF;n_{#sigma}TPC;#it{p}_{T}", {HistType::kTH3F, {cfgnSigmaBinsTOF, cfgnSigmaBinsTPC, cfgaxisptPID}}); + } + } + } + Produces pidEsePHe3Table; + void process(TracksPID const& tracks) + { + auto tracksWithITSPid = soa::Attach(tracks); + int8_t pidFlag; + for (const auto& track : tracksWithITSPid) { + histosQA.fill(HIST("QA/hist_dEdxTPC_All"), track.sign() * track.tpcInnerParam(), track.tpcSignal()); + histosQA.fill(HIST("QA/hist_pt_All"), track.pt()); + histosQA.fill(HIST("QA/hist_eta_All"), track.eta()); + histosQA.fill(HIST("QA/hist_ITSNcls_All"), track.itsNCls()); + histosQA.fill(HIST("QA/hist_TPCNcls_All"), track.tpcNClsFound()); + histosQA.fill(HIST("QA/hist_ITSChi2NDF_All"), track.itsChi2NCl()); + histosQA.fill(HIST("QA/hist_TPCChi2NDF_All"), track.tpcChi2NCl()); + histosQA.fill(HIST("QA/hist_DCAxy_All"), track.dcaXY()); + histosQA.fill(HIST("QA/hist_DCAz_All"), track.dcaZ()); + if (!trackSelBasic(track)) { + pidFlag = -1; + } else { + int currentPtBinPr = -1, currentPtBinHe3 = -1; + if (cfgOpenPIDByPtProtonMain || (cfgOpenPIDByPtProtonITS && cfgOpenPIDITSProton)) { + for (int i = 0; i < static_cast(cfgPtBinProtonPID.value.size()) - 1; ++i) { + if (track.pt() >= cfgPtBinProtonPID.value[i] && track.pt() < cfgPtBinProtonPID.value[i + 1]) { + currentPtBinPr = i; + break; + } + } + } + if (cfgOpenPIDByPtHe3Main || (cfgOpenPIDByPtHe3ITS && cfgOpenPIDITSHe3)) { + for (int i = 0; i < static_cast(cfgPtBinHe3PID.value.size()) - 1; ++i) { + if (track.pt() >= cfgPtBinHe3PID.value[i] && track.pt() < cfgPtBinHe3PID.value[i + 1]) { + currentPtBinHe3 = i; + break; + } + } + } + float nSigmaTPCCutPrPtLower = (currentPtBinPr == -1) ? cfgnSigmaCutTPCProton.value[0] : cfgnSigmaTPCProtonPtLower.value[currentPtBinPr]; + float nSigmaTPCCutPrPtUpper = (currentPtBinPr == -1) ? cfgnSigmaCutTPCProton.value[1] : cfgnSigmaTPCProtonPtUpper.value[currentPtBinPr]; + float nSigmaTOFCutPrPtLower = (currentPtBinPr == -1) ? cfgnSigmaCutTOFProton.value[0] : cfgnSigmaTOFProtonPtLower.value[currentPtBinPr]; + float nSigmaTOFCutPrPtUpper = (currentPtBinPr == -1) ? cfgnSigmaCutTOFProton.value[1] : cfgnSigmaTOFProtonPtUpper.value[currentPtBinPr]; + float nSigmaRMSCutPrPtLower = (currentPtBinPr == -1) ? cfgnSigmaCutRMSProton.value[0] : cfgnSigmaRMSProtonPtLower.value[currentPtBinPr]; + float nSigmaRMSCutPrPtUpper = (currentPtBinPr == -1) ? cfgnSigmaCutRMSProton.value[1] : cfgnSigmaRMSProtonPtUpper.value[currentPtBinPr]; + float nSigmaITSCutPrPtLower = (currentPtBinPr == -1) ? cfgnSigmaCutITSProton.value[0] : cfgnSigmaITSProtonPtLower.value[currentPtBinPr]; + float nSigmaITSCutPrPtUpper = (currentPtBinPr == -1) ? cfgnSigmaCutITSProton.value[1] : cfgnSigmaITSProtonPtUpper.value[currentPtBinPr]; + float nSigmaTPCCutHe3PtLower = (currentPtBinHe3 == -1) ? cfgnSigmaCutTPCHe3.value[0] : cfgnSigmaTPCHe3PtLower.value[currentPtBinHe3]; + float nSigmaTPCCutHe3PtUpper = (currentPtBinHe3 == -1) ? cfgnSigmaCutTPCHe3.value[1] : cfgnSigmaTPCHe3PtUpper.value[currentPtBinHe3]; + float nSigmaTOFCutHe3PtLower = (currentPtBinHe3 == -1) ? cfgnSigmaCutTOFHe3.value[0] : cfgnSigmaTOFHe3PtLower.value[currentPtBinHe3]; + float nSigmaTOFCutHe3PtUpper = (currentPtBinHe3 == -1) ? cfgnSigmaCutTOFHe3.value[1] : cfgnSigmaTOFHe3PtUpper.value[currentPtBinHe3]; + float nSigmaRMSCutHe3PtLower = (currentPtBinHe3 == -1) ? cfgnSigmaCutRMSHe3.value[0] : cfgnSigmaRMSHe3PtLower.value[currentPtBinHe3]; + float nSigmaRMSCutHe3PtUpper = (currentPtBinHe3 == -1) ? cfgnSigmaCutRMSHe3.value[1] : cfgnSigmaRMSHe3PtUpper.value[currentPtBinHe3]; + float nSigmaITSCutHe3PtLower = (currentPtBinHe3 == -1) ? cfgnSigmaCutITSHe3.value[0] : cfgnSigmaITSHe3PtLower.value[currentPtBinHe3]; + float nSigmaITSCutHe3PtUpper = (currentPtBinHe3 == -1) ? cfgnSigmaCutITSHe3.value[1] : cfgnSigmaITSHe3PtUpper.value[currentPtBinHe3]; + float nSigmaMainLowerPr = -999, nSigmaMainUpperPr = -999; + float nSigmaMainLowerHe3 = -999, nSigmaMainUpperHe3 = -999; + switch (cfgProtonPIDMode) { + case 0: + nSigmaMainLowerPr = nSigmaRMSCutPrPtLower; + nSigmaMainUpperPr = nSigmaRMSCutPrPtUpper; + break; + case 1: + nSigmaMainLowerPr = nSigmaTPCCutPrPtLower; + nSigmaMainUpperPr = nSigmaTPCCutPrPtUpper; + break; + case 2: + nSigmaMainLowerPr = nSigmaTOFCutPrPtLower; + nSigmaMainUpperPr = nSigmaTOFCutPrPtUpper; + break; + } + switch (cfgHe3PIDMode) { + case 0: + nSigmaMainLowerHe3 = nSigmaRMSCutHe3PtLower; + nSigmaMainUpperHe3 = nSigmaRMSCutHe3PtUpper; + break; + case 1: + nSigmaMainLowerHe3 = nSigmaTPCCutHe3PtLower; + nSigmaMainUpperHe3 = nSigmaTPCCutHe3PtUpper; + break; + case 2: + nSigmaMainLowerHe3 = nSigmaTOFCutHe3PtLower; + nSigmaMainUpperHe3 = nSigmaTOFCutHe3PtUpper; + break; + } + bool kIsPr = false, kIsHe3 = false; + // Identify Proton + if (pidProtonSel(track, nSigmaMainLowerPr, nSigmaMainUpperPr)) { + kIsPr = true; + if (cfgOpenPIDITSProton) { + if (track.itsNSigmaPr() < nSigmaITSCutPrPtLower || track.itsNSigmaPr() > nSigmaITSCutPrPtUpper) { + kIsPr = false; + } + } + } + // Identify He3 + if (pidHe3Sel(track, nSigmaMainLowerHe3, nSigmaMainUpperHe3)) { + kIsHe3 = true; + if (cfgOpenPIDITSHe3) { + if (track.itsNSigmaHe() < nSigmaITSCutHe3PtLower || track.itsNSigmaHe() > nSigmaITSCutHe3PtUpper) { + kIsHe3 = false; + } + } + } + // Cross track rejection + if (!cfgOpenAllowCrossTrack) { + if (kIsPr && kIsHe3) { + switch (crossTrackID(track)) { + case 0: + kIsPr = true; + kIsHe3 = false; + break; + case 1: + kIsPr = false; + kIsHe3 = true; + break; + } + } + } + // Filter He3 contaimination + if (cfgOpenHe3ITSPtCut && kIsHe3) { + if (!cfgQuietMode) { + histosQA.fill(HIST("QA/He3/hist_nSigmaITSPt_He3_unCuted"), track.pt(), track.itsNSigmaHe()); + } + if (track.itsNSigmaHe() < fNSigmaITSPt->Eval(track.pt())) { + kIsHe3 = false; + } + } + pidFlag = (kIsHe3 << 1) | kIsPr; + // Fill QA histograms + if (!cfgQuietMode) { + if (kIsPr) { + histosQA.fill(HIST("QA/Proton/hist_dEdxTPC_Pr"), track.sign() * track.tpcInnerParam(), track.tpcSignal()); + histosQA.fill(HIST("QA/Proton/hist_pt_Pr"), track.pt()); + histosQA.fill(HIST("QA/Proton/hist_eta_Pr"), track.eta()); + histosQA.fill(HIST("QA/Proton/hist_ITSNcls_Pr"), track.itsNCls()); + histosQA.fill(HIST("QA/Proton/hist_TPCNcls_Pr"), track.tpcNClsFound()); + histosQA.fill(HIST("QA/Proton/hist_ITSChi2NDF_Pr"), track.itsChi2NCl()); + histosQA.fill(HIST("QA/Proton/hist_TPCChi2NDF_Pr"), track.tpcChi2NCl()); + histosQA.fill(HIST("QA/Proton/hist_DCAxy_Pr"), track.dcaXY()); + histosQA.fill(HIST("QA/Proton/hist_DCAz_Pr"), track.dcaZ()); + histosQA.fill(HIST("QA/Proton/hist_nSigmaTPC_Pr"), track.tpcNSigmaPr()); + histosQA.fill(HIST("QA/Proton/hist_nSigmaTPCPt_Pr"), track.pt(), track.tpcNSigmaPr()); + histosQA.fill(HIST("QA/Proton/hist_nSigmaTOF_Pr"), track.tofNSigmaPr()); + histosQA.fill(HIST("QA/Proton/hist_nSigmaTOFPt_Pr"), track.pt(), track.tofNSigmaPr()); + histosQA.fill(HIST("QA/Proton/hist_nSigmaITS_Pr"), track.itsNSigmaPr()); + histosQA.fill(HIST("QA/Proton/hist_nSigmaITSPt_Pr"), track.pt(), track.itsNSigmaPr()); + histosQA.fill(HIST("QA/Proton/hist_nSigmaRMS_Pr"), std::hypot(track.tpcNSigmaPr(), track.tofNSigmaPr())); + histosQA.fill(HIST("QA/Proton/hist_nSigmaRMSPt_Pr"), track.pt(), std::hypot(track.tpcNSigmaPr(), track.tofNSigmaPr())); + if (cfgOpenPlotnSigmaTOFITSPt) { + histosQA.fill(HIST("QA/Proton/hist_nSigmaTOFITSPt_Pr"), track.tofNSigmaPr(), track.itsNSigmaPr(), track.pt()); + } + if (cfgOpenPlotnSigmaITSTPCPt) { + histosQA.fill(HIST("QA/Proton/hist_nSigmaITSTPCPt_Pr"), track.itsNSigmaPr(), track.tpcNSigmaPr(), track.pt()); + } + if (cfgOpenPlotnSigmaTOFTPCPt) { + histosQA.fill(HIST("QA/Proton/hist_nSigmaTOFTPCPt_Pr"), track.tofNSigmaPr(), track.tpcNSigmaPr(), track.pt()); + } + } + if (kIsHe3) { + histosQA.fill(HIST("QA/He3/hist_dEdxTPC_He3"), track.sign() * track.tpcInnerParam(), track.tpcSignal()); + histosQA.fill(HIST("QA/He3/hist_pt_He3"), track.pt()); + histosQA.fill(HIST("QA/He3/hist_eta_He3"), track.eta()); + histosQA.fill(HIST("QA/He3/hist_ITSNcls_He3"), track.itsNCls()); + histosQA.fill(HIST("QA/He3/hist_TPCNcls_He3"), track.tpcNClsFound()); + histosQA.fill(HIST("QA/He3/hist_ITSChi2NDF_He3"), track.itsChi2NCl()); + histosQA.fill(HIST("QA/He3/hist_TPCChi2NDF_He3"), track.tpcChi2NCl()); + histosQA.fill(HIST("QA/He3/hist_DCAxy_He3"), track.dcaXY()); + histosQA.fill(HIST("QA/He3/hist_DCAz_He3"), track.dcaZ()); + histosQA.fill(HIST("QA/He3/hist_nSigmaTPC_He3"), track.tpcNSigmaHe()); + histosQA.fill(HIST("QA/He3/hist_nSigmaTPCPt_He3"), track.pt(), track.tpcNSigmaHe()); + histosQA.fill(HIST("QA/He3/hist_nSigmaTOF_He3"), track.tofNSigmaHe()); + histosQA.fill(HIST("QA/He3/hist_nSigmaTOFPt_He3"), track.pt(), track.tofNSigmaHe()); + histosQA.fill(HIST("QA/He3/hist_nSigmaITS_He3"), track.itsNSigmaHe()); + histosQA.fill(HIST("QA/He3/hist_nSigmaITSPt_He3"), track.pt(), track.itsNSigmaHe()); + histosQA.fill(HIST("QA/He3/hist_nSigmaRMS_He3"), std::hypot(track.tpcNSigmaHe(), track.tofNSigmaHe())); + histosQA.fill(HIST("QA/He3/hist_nSigmaRMSPt_He3"), track.pt(), std::hypot(track.tpcNSigmaHe(), track.tofNSigmaHe())); + if (cfgOpenPlotnSigmaTOFITSPt) { + histosQA.fill(HIST("QA/He3/hist_nSigmaTOFITSPt_He3"), track.tofNSigmaHe(), track.itsNSigmaHe(), track.pt()); + } + if (cfgOpenPlotnSigmaITSTPCPt) { + histosQA.fill(HIST("QA/He3/hist_nSigmaITSTPCPt_He3"), track.itsNSigmaHe(), track.tpcNSigmaHe(), track.pt()); + } + if (cfgOpenPlotnSigmaTOFTPCPt) { + histosQA.fill(HIST("QA/He3/hist_nSigmaTOFTPCPt_He3"), track.tofNSigmaHe(), track.tpcNSigmaHe(), track.pt()); + } + } + } + } + pidEsePHe3Table(pidFlag); + } + } +}; + +struct FlowEsePHe3 { + HistogramRegistry histos{"histosmain", {}, OutputObjHandlingPolicy::AnalysisObject}; + + Configurable> cfgnMods{"cfgnMods", {2}, "Modulation of interest"}; + Configurable cfgDetName{"cfgDetName", "FT0C", "The name of detector to be analyzed"}; + Configurable cfgRefAName{"cfgRefAName", "TPCpos", "The name of detector for reference A"}; + Configurable cfgRefBName{"cfgRefBName", "TPCneg", "The name of detector for reference B"}; + Configurable cfgnTotalSystem{"cfgnTotalSystem", 7, "total qvector number"}; + + Configurable cfgVtzCut{"cfgVtzCut", 10.0f, "Accepted z-vertex range"}; + Configurable cfgCentMin{"cfgCentMin", 0.0f, "Centrality min"}; + Configurable cfgCentMax{"cfgCentMax", 100.0f, "Centrality max"}; + + Configurable cfgCutOccupancyLow{"cfgCutOccupancyLow", 0, "Low boundary cut on TPC occupancy"}; + Configurable cfgCutOccupancyHigh{"cfgCutOccupancyHigh", 3000, "High boundary cut on TPC occupancy"}; + Configurable cfgUseAdditionalEventCut{"cfgUseAdditionalEventCut", true, "Use additional event cut beyond sel8"}; + Configurable cfgOpenEvSelkIsGoodZvtxFT0vsPV{"cfgOpenEvSelkIsGoodZvtxFT0vsPV", true, "removes collisions with large differences between z of PV by tracks and z of PV from FT0 A-C time difference, use this cut at low multiplicities with caution"}; + Configurable cfgOpenEvSelkNoSameBunchPileup{"cfgOpenEvSelkNoSameBunchPileup", true, "rejects collisions which are associated with the same found-by-T0 bunch crossing"}; + Configurable cfgOpenEvSelkNoCollInTimeRangeStandard{"cfgOpenEvSelkNoCollInTimeRangeStandard", true, "no collisions in specified time range"}; + Configurable cfgOpenEvSelkIsGoodITSLayersAll{"cfgOpenEvSelkIsGoodITSLayersAll", true, "cut time intervals with dead ITS staves"}; + Configurable cfgOpenEvSelkNoCollInRofStandard{"cfgOpenEvSelkNoCollInRofStandard", true, "no other collisions in this Readout Frame with per-collision multiplicity above threshold"}; + Configurable cfgOpenEvSelkNoHighMultCollInPrevRof{"cfgOpenEvSelkNoHighMultCollInPrevRof", true, "veto an event if FT0C amplitude in previous ITS ROF is above threshold"}; + Configurable cfgOpenEvSelOccupancy{"cfgOpenEvSelOccupancy", true, "Occupancy cut"}; + Configurable cfgOpenEvSelMultCorrelationPVTracks{"cfgOpenEvSelMultCorrelationPVTracks", true, "Multiplicity correlation cut for PVtracks vs centrality(FT0C)"}; + Configurable cfgOpenEvSelMultCorrelationGlobalTracks{"cfgOpenEvSelMultCorrelationGlobalTracks", false, "Multiplicity correlation cut for Globaltracks vs centrality(FT0C)"}; + Configurable cfgOpenEvSelV0AT0ACut{"cfgOpenEvSelV0AT0ACut", true, "V0A T0A 5 sigma cut"}; + Configurable cfgOpenFullEventQA{"cfgOpenFullEventQA", true, "Open full QA plots for event QA"}; + Configurable cfgOpenv2q{"cfgOpenv2q", true, "Open v2(EP)and q calculation for Proton and He3"}; + Configurable cfgOpenESE{"cfgOpenESE", true, "Open ESE process"}; + Configurable cfgOpenESEChargeSeperation{"cfgOpenESEChargeSeperation", true, "Open ESE for postive and negative charge repectivily"}; + Configurable cfgOpenESEProton{"cfgOpenESEProton", true, "Open ESE Proton process"}; + Configurable cfgOpenESEHe3{"cfgOpenESEHe3", true, "Open ESE He3 process"}; + + ConfigurableAxis cfgaxisQvecF{"cfgaxisQvecF", {300, -1, 1}, ""}; + ConfigurableAxis cfgaxisCent{"cfgaxisCent", {90, 0, 90}, ""}; + ConfigurableAxis cfgaxispt{"cfgaxispt", {100, 0, 10}, ""}; + ConfigurableAxis cfgaxisCentForQA{"cfgaxisCentForQA", {100, 0, 100}, "centrality for event QA"}; + ConfigurableAxis cfgaxisNch{"cfgaxisNch", {4000, 0, 4000}, "N_{ch}"}; + ConfigurableAxis cfgaxisT0C{"cfgaxisT0C", {70, 0, 70000}, "N_{ch} (T0C)"}; + ConfigurableAxis cfgaxisT0A{"cfgaxisT0A", {200, 0, 200000}, "N_{ch} (T0A)"}; + ConfigurableAxis cfgaxisNchPV{"cfgaxisNchPV", {4000, 0, 4000}, "N_{ch} (PV)"}; + ConfigurableAxis cfgaxisq2{"cfgaxisq2", {120, 0, 12}, "Binning for P_{t} PID"}; + + EventPlaneHelper helperEP; + SliceCache cache; + + int detId; + int refAId; + int refBId; + // Additional Event selection cuts - Copy from flowGenericFramework.cxx + TF1* fMultPVCutLow = nullptr; + TF1* fMultPVCutHigh = nullptr; + TF1* fMultCutLow = nullptr; + TF1* fMultCutHigh = nullptr; + TF1* fT0AV0AMean = nullptr; + TF1* fT0AV0ASigma = nullptr; + + Filter collisionFilter = (nabs(aod::collision::posZ) < cfgVtzCut) && (aod::cent::centFT0C > cfgCentMin) && (aod::cent::centFT0C < cfgCentMax); + Filter properPIDfilter = aod::flow_ese_p_he3::nPidFlag >= (int8_t)0; // Only POI + + Partition>> protonTrackSet = ((aod::flow_ese_p_he3::nPidFlag == pid_flags::kProton) || (aod::flow_ese_p_he3::nPidFlag == pid_flags::kProtonHe3)); + Partition>> he3TrackSet = ((aod::flow_ese_p_he3::nPidFlag == pid_flags::kHe3) || (aod::flow_ese_p_he3::nPidFlag == pid_flags::kProtonHe3)); + + template + int getDetId(const T& name) + { + if (name.value == "BPos" || name.value == "BNeg" || name.value == "BTot") { + LOGF(warning, "Using deprecated label: %s. Please use TPCpos, TPCneg, TPCall instead.", name.value); + } + if (name.value == "FT0C") { + return 0; + } else if (name.value == "FT0A") { + return 1; + } else if (name.value == "FT0M") { + return 2; + } else if (name.value == "FV0A") { + return 3; + } else if (name.value == "TPCpos" || name.value == "BPos") { + return 4; + } else if (name.value == "TPCneg" || name.value == "BNeg") { + return 5; + } else if (name.value == "TPCall" || name.value == "BTot") { + return 6; + } else { + return 0; + } + } + + template + bool selEvent(const CollType& collision, const int multTrk, const float centrality) + { + histos.fill(HIST("QA/histEventCountDetail"), 0.5); + if (cfgOpenEvSelkIsGoodZvtxFT0vsPV && !collision.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV)) { + return false; + } + if (cfgOpenEvSelkIsGoodZvtxFT0vsPV) { + histos.fill(HIST("QA/histEventCountDetail"), 1.5); + } + if (cfgOpenEvSelkNoSameBunchPileup && !collision.selection_bit(aod::evsel::kNoSameBunchPileup)) { + return false; + } + if (cfgOpenEvSelkNoSameBunchPileup) { + histos.fill(HIST("QA/histEventCountDetail"), 2.5); + } + if (cfgOpenEvSelkNoCollInTimeRangeStandard && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { + return false; + } + if (cfgOpenEvSelkNoCollInTimeRangeStandard) { + histos.fill(HIST("QA/histEventCountDetail"), 3.5); + } + if (cfgOpenEvSelkIsGoodITSLayersAll && !collision.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { + return false; + } + if (cfgOpenEvSelkIsGoodITSLayersAll) { + histos.fill(HIST("QA/histEventCountDetail"), 4.5); + } + if (cfgOpenEvSelkNoCollInRofStandard && !collision.selection_bit(o2::aod::evsel::kNoCollInRofStandard)) { + return false; + } + if (cfgOpenEvSelkNoCollInRofStandard) { + histos.fill(HIST("QA/histEventCountDetail"), 5.5); + } + if (cfgOpenEvSelkNoHighMultCollInPrevRof && !collision.selection_bit(o2::aod::evsel::kNoHighMultCollInPrevRof)) { + return false; + } + if (cfgOpenEvSelkNoHighMultCollInPrevRof) { + histos.fill(HIST("QA/histEventCountDetail"), 6.5); + } + auto multNTracksPV = collision.multNTracksPV(); + auto occupancy = collision.trackOccupancyInTimeRange(); + if (cfgOpenEvSelOccupancy && (occupancy < cfgCutOccupancyLow || occupancy > cfgCutOccupancyHigh)) { + return false; + } + if (cfgOpenEvSelOccupancy) { + histos.fill(HIST("QA/histEventCountDetail"), 7.5); + } + if (cfgOpenEvSelMultCorrelationPVTracks) { + if (multNTracksPV < fMultPVCutLow->Eval(centrality)) + return false; + if (multNTracksPV > fMultPVCutHigh->Eval(centrality)) + return false; + } + if (cfgOpenEvSelMultCorrelationPVTracks) { + histos.fill(HIST("QA/histEventCountDetail"), 8.5); + } + if (cfgOpenEvSelMultCorrelationGlobalTracks) { + if (multTrk < fMultCutLow->Eval(centrality)) + return false; + if (multTrk > fMultCutHigh->Eval(centrality)) + return false; + } + if (cfgOpenEvSelMultCorrelationGlobalTracks) { + histos.fill(HIST("QA/histEventCountDetail"), 9.5); + } + if (cfgOpenEvSelV0AT0ACut && (std::fabs(collision.multFV0A() - fT0AV0AMean->Eval(collision.multFT0A())) > event_selection::kFT0AV0ASigma * fT0AV0ASigma->Eval(collision.multFT0A()))) { + return false; + } + if (cfgOpenEvSelV0AT0ACut) { + histos.fill(HIST("QA/histEventCountDetail"), 10.5); + } + return true; + } + + template + void fillHistosQvec(const CollType& collision, int nmode) + { + int detInd = detId * 4 + cfgnTotalSystem * 4 * (nmode - 2); + int refAInd = refAId * 4 + cfgnTotalSystem * 4 * (nmode - 2); + int refBInd = refBId * 4 + cfgnTotalSystem * 4 * (nmode - 2); + if (nmode == fourier_mode::kMode2) { + if (collision.qvecAmp()[detId] > 1e-8) { + histos.fill(HIST("QA/histQvec_CorrL0_V2"), collision.qvecRe()[detInd], collision.qvecIm()[detInd], collision.centFT0C()); + histos.fill(HIST("QA/histQvec_CorrL1_V2"), collision.qvecRe()[detInd + 1], collision.qvecIm()[detInd + 1], collision.centFT0C()); + histos.fill(HIST("QA/histQvec_CorrL2_V2"), collision.qvecRe()[detInd + 2], collision.qvecIm()[detInd + 2], collision.centFT0C()); + histos.fill(HIST("QA/histQvec_CorrL3_V2"), collision.qvecRe()[detInd + 3], collision.qvecIm()[detInd + 3], collision.centFT0C()); + histos.fill(HIST("QA/histEvtPl_CorrL0_V2"), helperEP.GetEventPlane(collision.qvecRe()[detInd], collision.qvecIm()[detInd], nmode), collision.centFT0C()); + histos.fill(HIST("QA/histEvtPl_CorrL1_V2"), helperEP.GetEventPlane(collision.qvecRe()[detInd + 1], collision.qvecIm()[detInd + 1], nmode), collision.centFT0C()); + histos.fill(HIST("QA/histEvtPl_CorrL2_V2"), helperEP.GetEventPlane(collision.qvecRe()[detInd + 2], collision.qvecIm()[detInd + 2], nmode), collision.centFT0C()); + histos.fill(HIST("QA/histEvtPl_CorrL3_V2"), helperEP.GetEventPlane(collision.qvecRe()[detInd + 3], collision.qvecIm()[detInd + 3], nmode), collision.centFT0C()); + } + if (collision.qvecAmp()[detId] > 1e-8 && collision.qvecAmp()[refAId] > 1e-8 && collision.qvecAmp()[refBId] > 1e-8) { + histos.fill(HIST("QA/histQvecRes_SigRefAV2"), collision.centFT0C(), helperEP.GetResolution(helperEP.GetEventPlane(collision.qvecRe()[detInd + 3], collision.qvecIm()[detInd + 3], nmode), helperEP.GetEventPlane(collision.qvecRe()[refAInd + 3], collision.qvecIm()[refAInd + 3], nmode), nmode)); + histos.fill(HIST("QA/histQvecRes_SigRefBV2"), collision.centFT0C(), helperEP.GetResolution(helperEP.GetEventPlane(collision.qvecRe()[detInd + 3], collision.qvecIm()[detInd + 3], nmode), helperEP.GetEventPlane(collision.qvecRe()[refBInd + 3], collision.qvecIm()[refBInd + 3], nmode), nmode)); + histos.fill(HIST("QA/histQvecRes_RefARefBV2"), collision.centFT0C(), helperEP.GetResolution(helperEP.GetEventPlane(collision.qvecRe()[refAInd + 3], collision.qvecIm()[refAInd + 3], nmode), helperEP.GetEventPlane(collision.qvecRe()[refBInd + 3], collision.qvecIm()[refBInd + 3], nmode), nmode)); + } + } + } + + template + float calculateq2(const TrackType tracks, float psi2, float cent, int pidmode) // pidmode 1 for proton , 2 for he3 + { + int multi = tracks.size(); + if (multi > 0) { + float q2x = 0, q2y = 0; + for (const auto& track : tracks) { + q2x += std::cos(2 * track.phi()); + q2y += std::sin(2 * track.phi()); + if (pidmode == pid_flags::kProton) { + if (track.sign() > 0) { + histos.fill(HIST("V2/histCosV2EP_Pr_Pos"), track.pt(), cent, std::cos(2 * (track.phi() - psi2))); + } else { + histos.fill(HIST("V2/histCosV2EP_Pr_Neg"), track.pt(), cent, std::cos(2 * (track.phi() - psi2))); + } + } + if (pidmode == pid_flags::kHe3) { + if (track.sign() > 0) { + histos.fill(HIST("V2/histCosV2EP_He3_Pos"), track.pt(), cent, std::cos(2 * (track.phi() - psi2))); + } else { + histos.fill(HIST("V2/histCosV2EP_He3_Neg"), track.pt(), cent, std::cos(2 * (track.phi() - psi2))); + } + } + } + return std::hypot(q2x, q2y) / std::sqrt(multi); + } else { + return 0; + } + } + + template + void processESE(const TrackType tracks, float psi2, float q2, float cent, int pidmode, bool spcharge) // pidmode 1 for proton , 2 for he3 + { + for (const auto& track : tracks) { + if (pidmode == pid_flags::kProton) { + if (spcharge) { + if (track.sign() > 0) { + histos.fill(HIST("ESE/hist_v2PosPr_Cent_Pt_q2He3"), track.pt(), cent, q2, std::cos(2 * (track.phi() - psi2))); + } else { + histos.fill(HIST("ESE/hist_v2NegPr_Cent_Pt_q2He3"), track.pt(), cent, q2, std::cos(2 * (track.phi() - psi2))); + } + } else { + histos.fill(HIST("ESE/hist_v2Pr_Cent_Pt_q2He3"), track.pt(), cent, q2, std::cos(2 * (track.phi() - psi2))); + } + } + if (pidmode == pid_flags::kHe3) { + if (spcharge) { + if (track.sign() > 0) { + histos.fill(HIST("ESE/hist_v2PosHe3_Cent_Pt_q2Pr"), track.pt(), cent, q2, std::cos(2 * (track.phi() - psi2))); + } else { + histos.fill(HIST("ESE/hist_v2NegHe3_Cent_Pt_q2Pr"), track.pt(), cent, q2, std::cos(2 * (track.phi() - psi2))); + } + } else { + histos.fill(HIST("ESE/hist_v2He3_Cent_Pt_q2Pr"), track.pt(), cent, q2, std::cos(2 * (track.phi() - psi2))); + } + } + } + } + + void init(InitContext const&) + { + detId = getDetId(cfgDetName); + refAId = getDetId(cfgRefAName); + refBId = getDetId(cfgRefBName); + if (detId == refAId || detId == refBId || refAId == refBId) { + LOGF(info, "Wrong detector configuration \n The FT0C will be used to get Q-Vector \n The TPCpos and TPCneg will be used as reference systems"); + detId = 0; + refAId = 4; + refBId = 5; + } + if (cfgUseAdditionalEventCut) { + fMultPVCutLow = new TF1("fMultPVCutLow", "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x - 3.5*([5]+[6]*x+[7]*x*x+[8]*x*x*x+[9]*x*x*x*x)", 0, 100); + fMultPVCutLow->SetParameters(3257.29, -121.848, 1.98492, -0.0172128, 6.47528e-05, 154.756, -1.86072, -0.0274713, 0.000633499, -3.37757e-06); + fMultPVCutHigh = new TF1("fMultPVCutHigh", "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x + 3.5*([5]+[6]*x+[7]*x*x+[8]*x*x*x+[9]*x*x*x*x)", 0, 100); + fMultPVCutHigh->SetParameters(3257.29, -121.848, 1.98492, -0.0172128, 6.47528e-05, 154.756, -1.86072, -0.0274713, 0.000633499, -3.37757e-06); + + fMultCutLow = new TF1("fMultCutLow", "[0]+[1]*x+[2]*x*x+[3]*x*x*x - 2.*([4]+[5]*x+[6]*x*x+[7]*x*x*x+[8]*x*x*x*x)", 0, 100); + fMultCutLow->SetParameters(1654.46, -47.2379, 0.449833, -0.0014125, 150.773, -3.67334, 0.0530503, -0.000614061, 3.15956e-06); + fMultCutHigh = new TF1("fMultCutHigh", "[0]+[1]*x+[2]*x*x+[3]*x*x*x + 3.*([4]+[5]*x+[6]*x*x+[7]*x*x*x+[8]*x*x*x*x)", 0, 100); + fMultCutHigh->SetParameters(1654.46, -47.2379, 0.449833, -0.0014125, 150.773, -3.67334, 0.0530503, -0.000614061, 3.15956e-06); + + fT0AV0AMean = new TF1("fT0AV0AMean", "[0]+[1]*x", 0, 200000); + fT0AV0AMean->SetParameters(-1601.0581, 9.417652e-01); + fT0AV0ASigma = new TF1("fT0AV0ASigma", "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x", 0, 200000); + fT0AV0ASigma->SetParameters(463.4144, 6.796509e-02, -9.097136e-07, 7.971088e-12, -2.600581e-17); + } + AxisSpec axisEvtPl = {100, -1.0 * constants::math::PI, constants::math::PI}; + AxisSpec axisvertexz = {100, -15., 15., "vrtx_{Z} [cm]"}; + histos.add("QA/histEventCount", "", {HistType::kTH1F, {{3, 0.0, 3.0}}}); + histos.get(HIST("QA/histEventCount"))->GetXaxis()->SetBinLabel(1, "Filtered event"); + histos.get(HIST("QA/histEventCount"))->GetXaxis()->SetBinLabel(2, "after sel8"); + histos.get(HIST("QA/histEventCount"))->GetXaxis()->SetBinLabel(3, "after additional event cut"); + if (cfgUseAdditionalEventCut) { + histos.add("QA/histEventCountDetail", "Number of Event;; Count", {HistType::kTH1F, {{11, 0, 11}}}); + histos.get(HIST("QA/histEventCountDetail"))->GetXaxis()->SetBinLabel(1, "after sel8"); + histos.get(HIST("QA/histEventCountDetail"))->GetXaxis()->SetBinLabel(2, "kIsGoodZvtxFT0vsPV"); + histos.get(HIST("QA/histEventCountDetail"))->GetXaxis()->SetBinLabel(3, "kNoSameBunchPileup"); + histos.get(HIST("QA/histEventCountDetail"))->GetXaxis()->SetBinLabel(4, "kNoCollInTimeRangeStandard"); + histos.get(HIST("QA/histEventCountDetail"))->GetXaxis()->SetBinLabel(5, "kIsGoodITSLayersAll"); + histos.get(HIST("QA/histEventCountDetail"))->GetXaxis()->SetBinLabel(6, "kNoCollInRofStandard"); + histos.get(HIST("QA/histEventCountDetail"))->GetXaxis()->SetBinLabel(7, "kNoHighMultCollInPrevRof"); + histos.get(HIST("QA/histEventCountDetail"))->GetXaxis()->SetBinLabel(8, "occupancy"); + histos.get(HIST("QA/histEventCountDetail"))->GetXaxis()->SetBinLabel(9, "MultCorrelationPVTracks"); + histos.get(HIST("QA/histEventCountDetail"))->GetXaxis()->SetBinLabel(10, "MultCorrelationGlobalTracks"); + histos.get(HIST("QA/histEventCountDetail"))->GetXaxis()->SetBinLabel(11, "cfgEvSelV0AT0ACut"); + } + if (cfgOpenFullEventQA) { + histos.add("QA/hist_globalTracks_centT0C_before", "before cut;Centrality T0C;mulplicity global tracks", {HistType::kTH2D, {cfgaxisCentForQA, cfgaxisNch}}); + histos.add("QA/hist_PVTracks_centT0C_before", "before cut;Centrality T0C;mulplicity PV tracks", {HistType::kTH2D, {cfgaxisCentForQA, cfgaxisNchPV}}); + histos.add("QA/hist_globalTracks_PVTracks_before", "before cut;mulplicity PV tracks;mulplicity global tracks", {HistType::kTH2D, {cfgaxisNchPV, cfgaxisNch}}); + histos.add("QA/hist_globalTracks_multT0A_before", "before cut;mulplicity T0A;mulplicity global tracks", {HistType::kTH2D, {cfgaxisT0A, cfgaxisNch}}); + histos.add("QA/hist_globalTracks_multV0A_before", "before cut;mulplicity V0A;mulplicity global tracks", {HistType::kTH2D, {cfgaxisT0A, cfgaxisNch}}); + histos.add("QA/hist_multV0A_multT0A_before", "before cut;mulplicity T0A;mulplicity V0A", {HistType::kTH2D, {cfgaxisT0A, cfgaxisT0A}}); + histos.add("QA/hist_multT0C_centT0C_before", "before cut;Centrality T0C;mulplicity T0C", {HistType::kTH2D, {cfgaxisCentForQA, cfgaxisT0C}}); + histos.add("QA/hist_globalTracks_centT0C_after", "after cut;Centrality T0C;mulplicity global tracks", {HistType::kTH2D, {cfgaxisCentForQA, cfgaxisNch}}); + histos.add("QA/hist_PVTracks_centT0C_after", "after cut;Centrality T0C;mulplicity PV tracks", {HistType::kTH2D, {cfgaxisCentForQA, cfgaxisNchPV}}); + histos.add("QA/hist_globalTracks_PVTracks_after", "after cut;mulplicity PV tracks;mulplicity global tracks", {HistType::kTH2D, {cfgaxisNchPV, cfgaxisNch}}); + histos.add("QA/hist_globalTracks_multT0A_after", "after cut;mulplicity T0A;mulplicity global tracks", {HistType::kTH2D, {cfgaxisT0A, cfgaxisNch}}); + histos.add("QA/hist_globalTracks_multV0A_after", "after cut;mulplicity V0A;mulplicity global tracks", {HistType::kTH2D, {cfgaxisT0A, cfgaxisNch}}); + histos.add("QA/hist_multV0A_multT0A_after", "after cut;mulplicity T0A;mulplicity V0A", {HistType::kTH2D, {cfgaxisT0A, cfgaxisT0A}}); + histos.add("QA/hist_multT0C_centT0C_after", "after cut;Centrality T0C;mulplicity T0C", {HistType::kTH2D, {cfgaxisCentForQA, cfgaxisT0C}}); + } + histos.add("QA/histVertexZRec", ";vrtx_{Z} [cm];counts", {HistType::kTH1F, {axisvertexz}}); + histos.add("QA/histCentrality", ";Centrality;counts", {HistType::kTH1F, {cfgaxisCentForQA}}); + histos.add("QA/histProtonNum", "ProtonNum;counts", {HistType::kTH1F, {{100, 0, 100}}}); + histos.add("QA/histHe3Num", "He3Num;counts", {HistType::kTH1F, {{20, 0, 20}}}); + histos.add("QA/histQvec_CorrL0_V2", ";#it{Q_{x}};#it{Q_{y}};Centrality", {HistType::kTH3F, {cfgaxisQvecF, cfgaxisQvecF, cfgaxisCent}}); + histos.add("QA/histQvec_CorrL1_V2", ";#it{Q_{x}};#it{Q_{y}};Centrality", {HistType::kTH3F, {cfgaxisQvecF, cfgaxisQvecF, cfgaxisCent}}); + histos.add("QA/histQvec_CorrL2_V2", ";#it{Q_{x}};#it{Q_{y}};Centrality", {HistType::kTH3F, {cfgaxisQvecF, cfgaxisQvecF, cfgaxisCent}}); + histos.add("QA/histQvec_CorrL3_V2", ";#it{Q_{x}};#it{Q_{y}};Centrality", {HistType::kTH3F, {cfgaxisQvecF, cfgaxisQvecF, cfgaxisCent}}); + histos.add("QA/histEvtPl_CorrL0_V2", ";EventPlane angle;Centrality", {HistType::kTH2F, {axisEvtPl, cfgaxisCent}}); + histos.add("QA/histEvtPl_CorrL1_V2", ";EventPlane angle;Centrality", {HistType::kTH2F, {axisEvtPl, cfgaxisCent}}); + histos.add("QA/histEvtPl_CorrL2_V2", ";EventPlane angle;Centrality", {HistType::kTH2F, {axisEvtPl, cfgaxisCent}}); + histos.add("QA/histEvtPl_CorrL3_V2", ";EventPlane angle;Centrality", {HistType::kTH2F, {axisEvtPl, cfgaxisCent}}); + histos.add("QA/histQvecRes_SigRefAV2", ";Centrality;Cos(Sig-RefA)", {HistType::kTProfile, {cfgaxisCent}}); + histos.add("QA/histQvecRes_SigRefBV2", ";Centrality;Cos(Sig-RefB)", {HistType::kTProfile, {cfgaxisCent}}); + histos.add("QA/histQvecRes_RefARefBV2", ";Centrality;Cos(RefA-RefB)", {HistType::kTProfile, {cfgaxisCent}}); + if (cfgOpenv2q) { + histos.add("V2/histCosV2EP_Pr_Pos", ";#it{p}_{T};Centrality", {HistType::kTProfile2D, {cfgaxispt, cfgaxisCent}}); + histos.add("V2/histCosV2EP_Pr_Neg", ";#it{p}_{T};Centrality", {HistType::kTProfile2D, {cfgaxispt, cfgaxisCent}}); + histos.add("V2/histCosV2EP_He3_Pos", ";#it{p}_{T};Centrality", {HistType::kTProfile2D, {cfgaxispt, cfgaxisCent}}); + histos.add("V2/histCosV2EP_He3_Neg", ";#it{p}_{T};Centrality", {HistType::kTProfile2D, {cfgaxispt, cfgaxisCent}}); + histos.add("q2/hist_q2_Cen_Pr", ";q_{2} (TPC);Centrality", {HistType::kTH2F, {cfgaxisq2, cfgaxisCent}}); + histos.add("q2/hist_q2_Cen_He3", ";q_{2} (TPC);Centrality", {HistType::kTH2F, {cfgaxisq2, cfgaxisCent}}); + histos.add("q2/hist_q2_Pr", ";q_{2} (TPC);counts", {HistType::kTH1F, {cfgaxisq2}}); + histos.add("q2/hist_q2_He3", ";q_{2} (TPC);counts", {HistType::kTH1F, {cfgaxisq2}}); + } + if (cfgOpenESE) { + if (cfgOpenESEChargeSeperation) { + if (cfgOpenESEProton) { + histos.add("ESE/hist_v2PosPr_Cent_Pt_q2He3", ";#it{p}_{T};q_{2}(He3);Centrality", HistType::kTProfile3D, {cfgaxispt, cfgaxisq2, cfgaxisCent}); + histos.add("ESE/hist_v2NegPr_Cent_Pt_q2He3", ";#it{p}_{T};q_{2}(He3);Centrality", HistType::kTProfile3D, {cfgaxispt, cfgaxisq2, cfgaxisCent}); + } + if (cfgOpenESEHe3) { + histos.add("ESE/hist_v2PosHe3_Cent_Pt_q2Pr", ";#it{p}_{T};q_{2}(Proton);Centrality", HistType::kTProfile3D, {cfgaxispt, cfgaxisq2, cfgaxisCent}); + histos.add("ESE/hist_v2NegHe3_Cent_Pt_q2Pr", ";#it{p}_{T};q_{2}(Proton);Centrality", HistType::kTProfile3D, {cfgaxispt, cfgaxisq2, cfgaxisCent}); + } + } else { + if (cfgOpenESEProton) { + histos.add("ESE/hist_v2Pr_Cent_Pt_q2He3", ";#it{p}_{T};q_{2}(He3);Centrality", HistType::kTProfile3D, {cfgaxispt, cfgaxisq2, cfgaxisCent}); + } + if (cfgOpenESEHe3) { + histos.add("ESE/hist_v2He3_Cent_Pt_q2Pr", ";#it{p}_{T};q_{2}(Proton);Centrality", HistType::kTProfile3D, {cfgaxispt, cfgaxisq2, cfgaxisCent}); + } + } + } + } + + void process(soa::Filtered>::iterator const& collision, soa::Filtered> const& tracks) + { + const auto cent = collision.centFT0C(); + histos.fill(HIST("QA/histEventCount"), 0.5); + if (!collision.sel8()) + return; + if (tracks.size() < 1) + return; + histos.fill(HIST("QA/histEventCount"), 1.5); + if (cfgOpenFullEventQA) { + histos.fill(HIST("QA/hist_globalTracks_centT0C_before"), cent, tracks.size()); + histos.fill(HIST("QA/hist_PVTracks_centT0C_before"), cent, collision.multNTracksPV()); + histos.fill(HIST("QA/hist_globalTracks_PVTracks_before"), collision.multNTracksPV(), tracks.size()); + histos.fill(HIST("QA/hist_globalTracks_multT0A_before"), collision.multFT0A(), tracks.size()); + histos.fill(HIST("QA/hist_globalTracks_multV0A_before"), collision.multFV0A(), tracks.size()); + histos.fill(HIST("QA/hist_multV0A_multT0A_before"), collision.multFT0A(), collision.multFV0A()); + histos.fill(HIST("QA/hist_multT0C_centT0C_before"), cent, collision.multFT0C()); + } + if (cfgUseAdditionalEventCut && !selEvent(collision, tracks.size(), cent)) { + return; + } + histos.fill(HIST("QA/histEventCount"), 2.5); + histos.fill(HIST("QA/histCentrality"), cent); + histos.fill(HIST("QA/histVertexZRec"), collision.posZ()); + if (cfgOpenFullEventQA) { + histos.fill(HIST("QA/hist_globalTracks_centT0C_after"), cent, tracks.size()); + histos.fill(HIST("QA/hist_PVTracks_centT0C_after"), cent, collision.multNTracksPV()); + histos.fill(HIST("QA/hist_globalTracks_PVTracks_after"), collision.multNTracksPV(), tracks.size()); + histos.fill(HIST("QA/hist_globalTracks_multT0A_after"), collision.multFT0A(), tracks.size()); + histos.fill(HIST("QA/hist_globalTracks_multV0A_after"), collision.multFV0A(), tracks.size()); + histos.fill(HIST("QA/hist_multV0A_multT0A_after"), collision.multFT0A(), collision.multFV0A()); + histos.fill(HIST("QA/hist_multT0C_centT0C_after"), cent, collision.multFT0C()); + } + auto tracksPr = protonTrackSet->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); + auto tracksHe3 = he3TrackSet->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); + int multiPr = tracksPr.size(); + int multiHe3 = tracksHe3.size(); + // LOGF(info, Form("Collison ID + 1; Proton Num:%d; He3 Num:%d;\n", multiPr, multiHe3)); + histos.fill(HIST("QA/histProtonNum"), multiPr); + histos.fill(HIST("QA/histHe3Num"), multiHe3); + if (multiPr < 1 && multiHe3 < 1) + return; // Reject Collisions without enough POI + for (auto i = 0; i < static_cast(cfgnMods->size()); i++) { + int detIndGlobal = detId * 4 + cfgnTotalSystem * 4 * (cfgnMods->at(i) - 2); + float psiNGlobal = helperEP.GetEventPlane(collision.qvecRe()[detIndGlobal + 3], collision.qvecIm()[detIndGlobal + 3], cfgnMods->at(i)); + if (cfgnMods->at(i) == fourier_mode::kMode2) { + // LOGF(info, "Process q2\n"); + float q2Proton = calculateq2(tracksPr, psiNGlobal, cent, 1); + float q2He3 = calculateq2(tracksHe3, psiNGlobal, cent, 2); + histos.fill(HIST("q2/hist_q2_Pr"), q2Proton); + histos.fill(HIST("q2/hist_q2_He3"), q2He3); + histos.fill(HIST("q2/hist_q2_Cen_Pr"), q2Proton, cent); + histos.fill(HIST("q2/hist_q2_Cen_He3"), q2He3, cent); + if (cfgOpenESE && multiPr > 0 && multiHe3 > 0) { + // LOGF(info, "Process ESE\n"); + if (cfgOpenESEProton) { + processESE(tracksPr, psiNGlobal, q2Proton, cent, 1, cfgOpenESEChargeSeperation); + } + if (cfgOpenESEHe3) { + processESE(tracksHe3, psiNGlobal, q2He3, cent, 2, cfgOpenESEChargeSeperation); + } + } + // LOGF(info, "Process for this event over\n"); + } + fillHistosQvec(collision, cfgnMods->at(i)); + } + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc), + }; +} diff --git a/PWGCF/Flow/Tasks/flowPbpbPikp.cxx b/PWGCF/Flow/Tasks/flowPbpbPikp.cxx index 311cccc5b84..a70ab3a32c6 100644 --- a/PWGCF/Flow/Tasks/flowPbpbPikp.cxx +++ b/PWGCF/Flow/Tasks/flowPbpbPikp.cxx @@ -52,6 +52,7 @@ #include #include +#include using namespace o2; using namespace o2::framework; @@ -88,6 +89,18 @@ struct FlowPbpbPikp { O2_DEFINE_CONFIGURABLE(cfgCutOccupancy, int, 3000, "Occupancy cut") O2_DEFINE_CONFIGURABLE(cfgUseGlobalTrack, bool, true, "use Global track") O2_DEFINE_CONFIGURABLE(cfgITScluster, int, 0, "Number of ITS cluster") + O2_DEFINE_CONFIGURABLE(cfgTrackDensityCorrUse, bool, true, "Use track density efficiency correction") + + O2_DEFINE_CONFIGURABLE(cfgUseWeightPhiEtaVtxz, bool, false, "Use Phi, Eta, VertexZ dependent NUA weights") + O2_DEFINE_CONFIGURABLE(cfgUseWeightPhiPtCent, bool, false, "Use Phi, Pt, Centrality dependent NUA weights") + O2_DEFINE_CONFIGURABLE(cfgUseWeightPhiEtaPt, bool, true, "Use Phi, Eta, Pt dependent NUA weights") + O2_DEFINE_CONFIGURABLE(cfgUseStrictPID, bool, true, "Use strict PID cuts for TPC") + + Configurable> cfgTrackDensityP0{"cfgTrackDensityP0", std::vector{0.7217476707, 0.7384792571, 0.7542625668, 0.7640680200, 0.7701951667, 0.7755299053, 0.7805901710, 0.7849446786, 0.7957356586, 0.8113039262, 0.8211968966, 0.8280558878, 0.8329342135}, "parameter 0 for track density efficiency correction"}; + Configurable> cfgTrackDensityP1{"cfgTrackDensityP1", std::vector{-2.169488e-05, -2.191913e-05, -2.295484e-05, -2.556538e-05, -2.754463e-05, -2.816832e-05, -2.846502e-05, -2.843857e-05, -2.705974e-05, -2.477018e-05, -2.321730e-05, -2.203315e-05, -2.109474e-05}, "parameter 1 for track density efficiency correction"}; + + Configurable> cfgTofNsigmaCut{"cfgTofNsigmaCut", std::vector{1.5, 1.5, 1.5}, "TOF n-sigma cut for pions, kaons, protons"}; + Configurable> cfgItsNsigmaCut{"cfgItsNsigmaCut", std::vector{3, 2.5, 2}, "ITS n-sigma cut for pions, kaons, protons"}; ConfigurableAxis axisVertex{"axisVertex", {20, -10, 10}, "vertex axis for histograms"}; ConfigurableAxis axisPhi{"axisPhi", {60, 0.0, constants::math::TwoPI}, "phi axis for histograms"}; @@ -99,6 +112,9 @@ struct FlowPbpbPikp { ConfigurableAxis axisParticles{"axisParticles", {3, 0, 3}, "axis for different hadrons"}; ConfigurableAxis axisTPCsignal{"axisTPCsignal", {10000, 0, 1000}, "axis for TPC signal"}; + std::vector tofNsigmaCut = cfgTofNsigmaCut; + std::vector itsNsigmaCut = cfgItsNsigmaCut; + 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); @@ -127,6 +143,13 @@ struct FlowPbpbPikp { std::vector mAcceptance; bool correctionsLoaded = false; + // local track density correction + std::vector funcEff; + TH1D* hFindPtBin; + TF1* funcV2; + TF1* funcV3; + TF1* funcV4; + void init(InitContext const&) { ccdb->setURL(ccdbUrl.value); @@ -140,15 +163,22 @@ struct FlowPbpbPikp { histos.add("hPhiWeighted", "", {HistType::kTH1D, {axisPhi}}); histos.add("hEta", "", {HistType::kTH1D, {axisEta}}); histos.add("hPt", "", {HistType::kTH1D, {axisPt}}); - histos.add("c22_gap08", "", {HistType::kTProfile, {axisMultiplicity}}); - histos.add("c22_gap08_pi", "", {HistType::kTProfile, {axisMultiplicity}}); - histos.add("c22_gap08_ka", "", {HistType::kTProfile, {axisMultiplicity}}); - histos.add("c22_gap08_pr", "", {HistType::kTProfile, {axisMultiplicity}}); - histos.add("c24_full", "", {HistType::kTProfile, {axisMultiplicity}}); - histos.add("c24_gap08", "", {HistType::kTProfile, {axisMultiplicity}}); - histos.add("c24_gap08_pi", "", {HistType::kTProfile, {axisMultiplicity}}); - histos.add("c24_gap08_ka", "", {HistType::kTProfile, {axisMultiplicity}}); - histos.add("c24_gap08_pr", "", {HistType::kTProfile, {axisMultiplicity}}); + histos.add("c22_full_ch", "", {HistType::kTProfile, {axisMultiplicity}}); + histos.add("c22_full_pi", "", {HistType::kTProfile, {axisMultiplicity}}); + histos.add("c22_full_ka", "", {HistType::kTProfile, {axisMultiplicity}}); + histos.add("c22_full_pr", "", {HistType::kTProfile, {axisMultiplicity}}); + histos.add("c22_gap08F_ch", "", {HistType::kTProfile, {axisMultiplicity}}); + histos.add("c22_gap08F_pi", "", {HistType::kTProfile, {axisMultiplicity}}); + histos.add("c22_gap08F_ka", "", {HistType::kTProfile, {axisMultiplicity}}); + histos.add("c22_gap08F_pr", "", {HistType::kTProfile, {axisMultiplicity}}); + histos.add("c22_gap08B_ch", "", {HistType::kTProfile, {axisMultiplicity}}); + histos.add("c22_gap08B_pi", "", {HistType::kTProfile, {axisMultiplicity}}); + histos.add("c22_gap08B_ka", "", {HistType::kTProfile, {axisMultiplicity}}); + histos.add("c22_gap08B_pr", "", {HistType::kTProfile, {axisMultiplicity}}); + histos.add("c24_full_ch", "", {HistType::kTProfile, {axisMultiplicity}}); + histos.add("c24_full_pi", "", {HistType::kTProfile, {axisMultiplicity}}); + histos.add("c24_full_ka", "", {HistType::kTProfile, {axisMultiplicity}}); + histos.add("c24_full_pr", "", {HistType::kTProfile, {axisMultiplicity}}); histos.add("TofTpcNsigma", "", {HistType::kTHnSparseD, {{axisParticles, axisNsigmaTPC, axisNsigmaTOF, axisPt}}}); histos.add("partCount", "", {HistType::kTHnSparseD, {{axisParticles, axisMultiplicity, axisPt}}}); if (cfgOutputNUAWeights && !cfgOutputRunByRun) { @@ -157,6 +187,18 @@ struct FlowPbpbPikp { histos.add("NUA/hPhiEtaVtxz_pi", ";#varphi;#eta;v_{z}", {HistType::kTH3D, {axisPhi, {64, -1.6, 1.6}, {40, -10, 10}}}); histos.add("NUA/hPhiEtaVtxz_ka", ";#varphi;#eta;v_{z}", {HistType::kTH3D, {axisPhi, {64, -1.6, 1.6}, {40, -10, 10}}}); histos.add("NUA/hPhiEtaVtxz_pr", ";#varphi;#eta;v_{z}", {HistType::kTH3D, {axisPhi, {64, -1.6, 1.6}, {40, -10, 10}}}); + + histos.add("NUA/hPhiPtCent_ref", ";#varphi;p_{T};Cent", {HistType::kTH3D, {axisPhi, axisPt, {20, 0, 100}}}); + histos.add("NUA/hPhiPtCent_ch", ";#varphi;p_{T};Cent", {HistType::kTH3D, {axisPhi, axisPt, {20, 0, 100}}}); + histos.add("NUA/hPhiPtCent_pi", ";#varphi;p_{T};Cent", {HistType::kTH3D, {axisPhi, axisPt, {20, 0, 100}}}); + histos.add("NUA/hPhiPtCent_ka", ";#varphi;p_{T};Cent", {HistType::kTH3D, {axisPhi, axisPt, {20, 0, 100}}}); + histos.add("NUA/hPhiPtCent_pr", ";#varphi;p_{T};Cent", {HistType::kTH3D, {axisPhi, axisPt, {20, 0, 100}}}); + + histos.add("NUA/hPhiEtaPt_ref", ";#varphi;#eta;p_{T}", {HistType::kTH3D, {axisPhi, {64, -1.6, 1.6}, axisPt}}); + histos.add("NUA/hPhiEtaPt_ch", ";#varphi;#eta;p_{T}", {HistType::kTH3D, {axisPhi, {64, -1.6, 1.6}, axisPt}}); + histos.add("NUA/hPhiEtaPt_pi", ";#varphi;#eta;p_{T}", {HistType::kTH3D, {axisPhi, {64, -1.6, 1.6}, axisPt}}); + histos.add("NUA/hPhiEtaPt_ka", ";#varphi;#eta;p_{T}", {HistType::kTH3D, {axisPhi, {64, -1.6, 1.6}, axisPt}}); + histos.add("NUA/hPhiEtaPt_pr", ";#varphi;#eta;p_{T}", {HistType::kTH3D, {axisPhi, {64, -1.6, 1.6}, axisPt}}); } o2::framework::AxisSpec axis = axisPt; @@ -168,36 +210,54 @@ struct FlowPbpbPikp { oba->Add(new TNamed("ChFull22", "ChFull22")); for (int i = 0; i < fPtAxis->GetNbins(); i++) oba->Add(new TNamed(Form("ChFull22_pt_%i", i + 1), "ChFull22_pTDiff")); + oba->Add(new TNamed("PiFull22", "PiFull22")); + for (int i = 0; i < fPtAxis->GetNbins(); i++) + oba->Add(new TNamed(Form("PiFull22_pt_%i", i + 1), "PiFull22_pTDiff")); + oba->Add(new TNamed("KaFull22", "KaFull22")); + for (int i = 0; i < fPtAxis->GetNbins(); i++) + oba->Add(new TNamed(Form("KaFull22_pt_%i", i + 1), "KaFull22_pTDiff")); + oba->Add(new TNamed("PrFull22", "PrFull22")); + for (int i = 0; i < fPtAxis->GetNbins(); i++) + oba->Add(new TNamed(Form("PrFull22_pt_%i", i + 1), "PrFull22_pTDiff")); - oba->Add(new TNamed("Ch08Gap22", "Ch08Gap22")); + oba->Add(new TNamed("Ch08FGap22", "Ch08FGap22")); for (int i = 0; i < fPtAxis->GetNbins(); i++) - oba->Add(new TNamed(Form("Ch08Gap22_pt_%i", i + 1), "Ch08Gap22_pTDiff")); - oba->Add(new TNamed("Pi08Gap22", "Pi08Gap22")); + oba->Add(new TNamed(Form("Ch08FGap22_pt_%i", i + 1), "Ch08FGap22_pTDiff")); + oba->Add(new TNamed("Pi08FGap22", "Pi08FGap22")); for (int i = 0; i < fPtAxis->GetNbins(); i++) - oba->Add(new TNamed(Form("Pi08Gap22_pt_%i", i + 1), "Pi08Gap22_pTDiff")); - oba->Add(new TNamed("Ka08Gap22", "Ka08Gap22")); + oba->Add(new TNamed(Form("Pi08FGap22_pt_%i", i + 1), "Pi08FGap22_pTDiff")); + oba->Add(new TNamed("Ka08FGap22", "Ka08FGap22")); for (int i = 0; i < fPtAxis->GetNbins(); i++) - oba->Add(new TNamed(Form("Ka08Gap22_pt_%i", i + 1), "Ka08Gap22_pTDiff")); - oba->Add(new TNamed("Pr08Gap22", "Pr08Gap22")); + oba->Add(new TNamed(Form("Ka08FGap22_pt_%i", i + 1), "Ka08FGap22_pTDiff")); + oba->Add(new TNamed("Pr08FGap22", "Pr08FGap22")); for (int i = 0; i < fPtAxis->GetNbins(); i++) - oba->Add(new TNamed(Form("Pr08Gap22_pt_%i", i + 1), "Pr08Gap22_pTDiff")); + oba->Add(new TNamed(Form("Pr08FGap22_pt_%i", i + 1), "Pr08FGap22_pTDiff")); oba->Add(new TNamed("ChFull24", "ChFull24")); for (int i = 0; i < fPtAxis->GetNbins(); i++) oba->Add(new TNamed(Form("ChFull24_pt_%i", i + 1), "ChFull24_pTDiff")); + oba->Add(new TNamed("PiFull24", "PiFull24")); + for (int i = 0; i < fPtAxis->GetNbins(); i++) + oba->Add(new TNamed(Form("PiFull24_pt_%i", i + 1), "PiFull24_pTDiff")); + oba->Add(new TNamed("KaFull24", "KaFull24")); + for (int i = 0; i < fPtAxis->GetNbins(); i++) + oba->Add(new TNamed(Form("KaFull24_pt_%i", i + 1), "KaFull24_pTDiff")); + oba->Add(new TNamed("PrFull24", "PrFull24")); + for (int i = 0; i < fPtAxis->GetNbins(); i++) + oba->Add(new TNamed(Form("PrFull24_pt_%i", i + 1), "PrFull24_pTDiff")); - oba->Add(new TNamed("Ch08Gap24", "Ch08Gap24")); + oba->Add(new TNamed("Ch08BGap22", "Ch08BGap22")); for (int i = 0; i < fPtAxis->GetNbins(); i++) - oba->Add(new TNamed(Form("Ch08Gap24_pt_%i", i + 1), "Ch08Gap24_pTDiff")); - oba->Add(new TNamed("Pi08Gap24", "Pi08Gap24")); + oba->Add(new TNamed(Form("Ch08BGap22_pt_%i", i + 1), "Ch08BGap22_pTDiff")); + oba->Add(new TNamed("Pi08BGap22", "Pi08BGap22")); for (int i = 0; i < fPtAxis->GetNbins(); i++) - oba->Add(new TNamed(Form("Pi08Gap24_pt_%i", i + 1), "Pi08Gap24_pTDiff")); - oba->Add(new TNamed("Ka08Gap24", "Ka08Gap24")); + oba->Add(new TNamed(Form("Pi08BGap22_pt_%i", i + 1), "Pi08BGap22_pTDiff")); + oba->Add(new TNamed("Ka08BGap22", "Ka08BGap22")); for (int i = 0; i < fPtAxis->GetNbins(); i++) - oba->Add(new TNamed(Form("Ka08Gap24_pt_%i", i + 1), "Ka08Gap24_pTDiff")); - oba->Add(new TNamed("Pr08Gap24", "Pr08Gap24")); + oba->Add(new TNamed(Form("Ka08BGap22_pt_%i", i + 1), "Ka08BGap22_pTDiff")); + oba->Add(new TNamed("Pr08BGap22", "Pr08BGap22")); for (int i = 0; i < fPtAxis->GetNbins(); i++) - oba->Add(new TNamed(Form("Pr08Gap24_pt_%i", i + 1), "Pr08Gap24_pTDiff")); + oba->Add(new TNamed(Form("Pr08BGap22_pt_%i", i + 1), "Pr08BGap22_pTDiff")); fFC->SetName("FlowContainer"); fFC->SetXAxis(fPtAxis); @@ -207,51 +267,107 @@ struct FlowPbpbPikp { // reference particles fGFW->AddRegion("refN08", -0.8, -0.4, 1, 1); fGFW->AddRegion("refP08", 0.4, 0.8, 1, 1); - fGFW->AddRegion("full", -0.8, 0.8, 1, 512); + fGFW->AddRegion("full", -0.8, 0.8, 1, 1); // pt dependent charged particles - fGFW->AddRegion("poiN", -0.8, -0.4, 1 + fPtAxis->GetNbins(), 128); - fGFW->AddRegion("olN", -0.8, -0.4, 1 + fPtAxis->GetNbins(), 256); - fGFW->AddRegion("poi", -0.8, 0.8, 1 + fPtAxis->GetNbins(), 1024); - fGFW->AddRegion("ol", -0.8, 0.8, 1 + fPtAxis->GetNbins(), 2048); + fGFW->AddRegion("poiN", -0.8, -0.4, 1 + fPtAxis->GetNbins(), 128); // Negative poi eta range + fGFW->AddRegion("olN", -0.8, -0.4, 1 + fPtAxis->GetNbins(), 256); // Negative overlap eta range + + fGFW->AddRegion("poiP", 0.4, 0.8, 1 + fPtAxis->GetNbins(), 128); // Positive poi eta range + fGFW->AddRegion("olP", 0.4, 0.8, 1 + fPtAxis->GetNbins(), 256); // Positive overlap eta range + + fGFW->AddRegion("poi", -0.8, 0.8, 1 + fPtAxis->GetNbins(), 128); // Full poi eta range + fGFW->AddRegion("ol", -0.8, 0.8, 1 + fPtAxis->GetNbins(), 256); // Full overlap eta range // pion - fGFW->AddRegion("poiNpi", -0.8, -0.4, 1 + fPtAxis->GetNbins(), 2); - fGFW->AddRegion("olNpi", -0.8, -0.4, 1 + fPtAxis->GetNbins(), 16); + fGFW->AddRegion("poiNpi", -0.8, -0.4, 1 + fPtAxis->GetNbins(), 2); // Negative poi eta range + fGFW->AddRegion("olNpi", -0.8, -0.4, 1 + fPtAxis->GetNbins(), 16); // Negative overlap eta range + + fGFW->AddRegion("poiPpi", 0.4, 0.8, 1 + fPtAxis->GetNbins(), 2); // Positive poi eta range + fGFW->AddRegion("olPpi", 0.4, 0.8, 1 + fPtAxis->GetNbins(), 16); // Positive overlap eta range + + fGFW->AddRegion("poifullpi", -0.8, 0.8, 1 + fPtAxis->GetNbins(), 2); // Full poi eta range + fGFW->AddRegion("olfullpi", -0.8, 0.8, 1 + fPtAxis->GetNbins(), 16); // Full overlap eta range // kaon - fGFW->AddRegion("poiNk", -0.8, -0.4, 1 + fPtAxis->GetNbins(), 4); - fGFW->AddRegion("olNk", -0.8, -0.4, 1 + fPtAxis->GetNbins(), 32); + fGFW->AddRegion("poiNk", -0.8, -0.4, 1 + fPtAxis->GetNbins(), 4); // Negative poi eta range + fGFW->AddRegion("olNk", -0.8, -0.4, 1 + fPtAxis->GetNbins(), 32); // Negative overlap eta range + + fGFW->AddRegion("poiPk", 0.4, 0.8, 1 + fPtAxis->GetNbins(), 4); // Positive poi eta range + fGFW->AddRegion("olPk", 0.4, 0.8, 1 + fPtAxis->GetNbins(), 32); // Positive overlap eta range + + fGFW->AddRegion("poifullk", -0.8, 0.8, 1 + fPtAxis->GetNbins(), 4); // Full poi eta range + fGFW->AddRegion("olfullk", -0.8, 0.8, 1 + fPtAxis->GetNbins(), 32); // Full overlap eta range // proton - fGFW->AddRegion("poiNpr", -0.8, -0.4, 1 + fPtAxis->GetNbins(), 8); - fGFW->AddRegion("olNpr", -0.8, -0.4, 1 + fPtAxis->GetNbins(), 64); + fGFW->AddRegion("poiNpr", -0.8, -0.4, 1 + fPtAxis->GetNbins(), 8); // Negative poi eta range + fGFW->AddRegion("olNpr", -0.8, -0.4, 1 + fPtAxis->GetNbins(), 64); // Negative overlap eta range + + fGFW->AddRegion("poiPpr", 0.4, 0.8, 1 + fPtAxis->GetNbins(), 8); // Positive poi eta range + fGFW->AddRegion("olPpr", 0.4, 0.8, 1 + fPtAxis->GetNbins(), 64); // Positive overlap eta range + + fGFW->AddRegion("poifullpr", -0.8, 0.8, 1 + fPtAxis->GetNbins(), 8); // Full poi eta range + fGFW->AddRegion("olfullpr", -0.8, 0.8, 1 + fPtAxis->GetNbins(), 64); // Full overlap eta range // reference particles corrconfigs.push_back(fGFW->GetCorrelatorConfig("full {2 -2}", "ChFull22", kFALSE)); - corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN08 {2} refP08 {-2}", "Ch08Gap22", kFALSE)); - corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN08 {2} refP08 {-2}", "Pi08Gap22", kFALSE)); - corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN08 {2} refP08 {-2}", "Ka08Gap22", kFALSE)); - corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN08 {2} refP08 {-2}", "Pr08Gap22", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("full {2 -2}", "PiFull22", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("full {2 -2}", "KaFull22", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("full {2 -2}", "PrFull22", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN08 {2} refP08 {-2}", "Ch08FGap22", kFALSE)); // Forward correlations + corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN08 {2} refP08 {-2}", "Pi08FGap22", kFALSE)); // Forward correlations + corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN08 {2} refP08 {-2}", "Ka08FGap22", kFALSE)); // Forward correlations + corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN08 {2} refP08 {-2}", "Pr08FGap22", kFALSE)); // Forward correlations + corrconfigs.push_back(fGFW->GetCorrelatorConfig("refP08 {-2} refN08 {2}", "Ch08BGap22", kFALSE)); // Backward correlations + corrconfigs.push_back(fGFW->GetCorrelatorConfig("refP08 {-2} refN08 {2}", "Pi08BGap22", kFALSE)); // Backward correlations + corrconfigs.push_back(fGFW->GetCorrelatorConfig("refP08 {-2} refN08 {2}", "Ka08BGap22", kFALSE)); // Backward correlations + corrconfigs.push_back(fGFW->GetCorrelatorConfig("refP08 {-2} refN08 {2}", "Pr08BGap22", kFALSE)); // Backward correlations corrconfigs.push_back(fGFW->GetCorrelatorConfig("full {2 2 -2 -2}", "ChFull24", kFALSE)); - corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN08 {2 2} refP08 {-2 -2}", "Ch08Gap24", kFALSE)); - corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN08 {2 2} refP08 {-2 -2}", "Pi08Gap24", kFALSE)); - corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN08 {2 2} refP08 {-2 -2}", "Ka08Gap24", kFALSE)); - corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN08 {2 2} refP08 {-2 -2}", "Pr08Gap24", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("full {2 2 -2 -2}", "PiFull24", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("full {2 2 -2 -2}", "KaFull24", kFALSE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("full {2 2 -2 -2}", "PrFull24", kFALSE)); // pt differential pois corrconfigs.push_back(fGFW->GetCorrelatorConfig("poi full | ol {2 -2}", "ChFull22", kTRUE)); - corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiN refN08 | olN {2} refP08 {-2}", "Ch08Gap22", kTRUE)); - corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiNpi refN08 | olNpi {2} refP08 {-2}", "Pi08Gap22", kTRUE)); - corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiNk refN08 | olNk {2} refP08 {-2}", "Ka08Gap22", kTRUE)); - corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiNpr refN08 | olNpr {2} refP08 {-2}", "Pr08Gap22", kTRUE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("poifullpi full | olfullpi {2 -2}", "PiFull22", kTRUE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("poifullk full | olfullk {2 -2}", "KaFull22", kTRUE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("poifullpr full | olfullpr {2 -2}", "PrFull22", kTRUE)); + + corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiN refN08 | olN {2} refP08 {-2}", "Ch08FGap22", kTRUE)); // Forward correlations + corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiNpi refN08 | olNpi {2} refP08 {-2}", "Pi08FGap22", kTRUE)); // Forward correlations + corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiNk refN08 | olNk {2} refP08 {-2}", "Ka08FGap22", kTRUE)); // Forward correlations + corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiNpr refN08 | olNpr {2} refP08 {-2}", "Pr08FGap22", kTRUE)); // Forward correlations + + corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiP refP08 | olP {2} refN08 {-2}", "Ch08BGap22", kTRUE)); // Backward correlations + corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiPpi refP08 | olPpi {2} refN08 {-2}", "Pi08BGap22", kTRUE)); // Backward correlations + corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiPk refP08 | olPk {2} refN08 {-2}", "Ka08BGap22", kTRUE)); // Backward correlations + corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiPpr refP08 | olPpr {2} refN08 {-2}", "Pr08BGap22", kTRUE)); // Backward correlations + corrconfigs.push_back(fGFW->GetCorrelatorConfig("poi full | ol {2 2 -2 -2}", "ChFull24", kTRUE)); - corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiN refN08 | olN {2 2} refP08 {-2 -2}", "Ch08Gap24", kTRUE)); - corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiNpi refN08 | olNpi {2 2} refP08 {-2 -2}", "Pi08Gap24", kTRUE)); - corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiNk refN08 | olNk {2 2} refP08 {-2 -2}", "Ka08Gap24", kTRUE)); - corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiNpr refN08 | olNpr {2 2} refP08 {-2 -2}", "Pr08Gap24", kTRUE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("poifullpi full | olfullpi {2 2 -2 -2}", "PiFull24", kTRUE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("poifullk full | olfullk {2 2 -2 -2}", "KaFull24", kTRUE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("poifullpr full | olfullpr {2 2 -2 -2}", "PrFull24", kTRUE)); fGFW->CreateRegions(); + + if (cfgTrackDensityCorrUse) { + std::vector pTEffBins = {0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.4, 1.8, 2.2, 2.6, 3.0}; + hFindPtBin = new TH1D("hFindPtBin", "hFindPtBin", pTEffBins.size() - 1, &pTEffBins[0]); + funcEff.resize(pTEffBins.size() - 1); + // LHC24g3 Eff + std::vector f1p0 = cfgTrackDensityP0; + std::vector f1p1 = cfgTrackDensityP1; + for (uint ifunc = 0; ifunc < pTEffBins.size() - 1; ifunc++) { + funcEff[ifunc] = new TF1(Form("funcEff%i", ifunc), "[0]+[1]*x", 0, 3000); + funcEff[ifunc]->SetParameters(f1p0[ifunc], f1p1[ifunc]); + } + funcV2 = new TF1("funcV2", "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x", 0, 100); + funcV2->SetParameters(0.0186111, 0.00351907, -4.38264e-05, 1.35383e-07, -3.96266e-10); + funcV3 = new TF1("funcV3", "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x", 0, 100); + funcV3->SetParameters(0.0174056, 0.000703329, -1.45044e-05, 1.91991e-07, -1.62137e-09); + funcV4 = new TF1("funcV4", "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x", 0, 100); + funcV4->SetParameters(0.008845, 0.000259668, -3.24435e-06, 4.54837e-08, -6.01825e-10); + } } enum Particles { @@ -273,7 +389,7 @@ struct FlowPbpbPikp { } template - int getNsigmaPID(TTrack track) + int getNsigmaPIDTpcTof(TTrack track) { // Computing Nsigma arrays for pion, kaon, and protons std::array nSigmaTPC = {track.tpcNSigmaPi(), track.tpcNSigmaKa(), track.tpcNSigmaPr()}; @@ -286,11 +402,18 @@ struct FlowPbpbPikp { if (track.pt() >= cfgTofPtCut && !track.hasTOF()) return -1; + const int numSpecies = 3; + int pidCount = 0; // Select particle with the lowest nsigma - for (int i = 0; i < 3; ++i) { + for (int i = 0; i < numSpecies; ++i) { if (std::abs(nSigmaToUse[i]) < nsigma) { + if (pidCount > 0 && cfgUseStrictPID) + return -1; // more than one particle with low nsigma + + pidCount++; pid = i; - nsigma = std::abs(nSigmaToUse[i]); + if (!cfgUseStrictPID) + nsigma = std::abs(nSigmaToUse[i]); } } return pid + 1; // shift the pid by 1, 1 = pion, 2 = kaon, 3 = proton @@ -303,8 +426,10 @@ struct FlowPbpbPikp { int bayesid = -1; int prob = 0; - for (int i = 0; i < 3; ++i) { - if (bayesprobs[i] > prob && bayesprobs[i] > 80) { + const int nParts = 3; + const int bayesCut = 80; + for (int i = 0; i < nParts; ++i) { + if (bayesprobs[i] > prob && bayesprobs[i] > bayesCut) { bayesid = i; prob = bayesprobs[i]; } @@ -317,12 +442,13 @@ struct FlowPbpbPikp { { int maxProb[3] = {80, 80, 80}; int pidID = -1; + const int nParts = 3; std::pair idprob = getBayesID(track); if (idprob.first == PIONS || idprob.first == KAONS || idprob.first == PROTONS) { // 0 = pion, 1 = kaon, 2 = proton pidID = idprob.first; float nsigmaTPC[3] = {track.tpcNSigmaPi(), track.tpcNSigmaKa(), track.tpcNSigmaPr()}; if (idprob.second > maxProb[pidID]) { - if (std::fabs(nsigmaTPC[pidID]) > 3) + if (std::fabs(nsigmaTPC[pidID]) > nParts) return 0; return pidID + 1; // shift the pid by 1, 1 = pion, 2 = kaon, 3 = proton } else { @@ -436,26 +562,40 @@ struct FlowPbpbPikp { correctionsLoaded = true; } - template - double getAcceptance(TTrack track, const double& vtxz, int index) - { // 0 ref, 1 ch, 2 pi, 3 ka, 4 pr + template + double getAcceptance(TTrack track, const TCollision collision, int index) + { // 0 = ref, 1 = ch, 2 = pi, 3 = ka, 4 = pr if (index < 0 || index >= kCount_OutputSpecies) { return 1; } double wacc = 1; + double cent = collision.centFT0C(); + double vtxz = collision.posZ(); + + if ((cfgUseWeightPhiEtaVtxz && cfgUseWeightPhiPtCent) || (cfgUseWeightPhiEtaPt && cfgUseWeightPhiPtCent) || (cfgUseWeightPhiEtaVtxz && cfgUseWeightPhiEtaPt)) { + LOGF(fatal, "Only one of the three weight options can be used at a time"); + } + if (!mAcceptance.empty() && correctionsLoaded) { if (!mAcceptance[index]) { LOGF(fatal, "Acceptance weights not loaded for index %d", index); return 1; } - wacc = mAcceptance[index]->getNUA(track.phi(), track.eta(), vtxz); + if (cfgUseWeightPhiEtaVtxz) + wacc = mAcceptance[index]->getNUA(track.phi(), track.eta(), vtxz); + if (cfgUseWeightPhiPtCent) + wacc = mAcceptance[index]->getNUA(track.phi(), track.pt(), cent); + if (cfgUseWeightPhiEtaPt) + wacc = mAcceptance[index]->getNUA(track.phi(), track.eta(), track.pt()); } return wacc; } - template - void fillWeights(const TTrack track, const double vtxz, const int& pid_index, const int& run) + template + void fillWeights(const TTrack track, const TCollision collision, const int& pid_index, const int& run) { + double cent = collision.centFT0C(); + double vtxz = collision.posZ(); double pt = track.pt(); bool withinPtPOI = (cfgCutPtPOIMin < pt) && (pt < cfgCutPtPOIMax); // within POI pT range bool withinPtRef = (cfgCutPtMin < pt) && (pt < cfgCutPtMax); // within RF pT range @@ -466,21 +606,33 @@ struct FlowPbpbPikp { if (withinPtPOI) th3sList[run][hCharge + pid_index]->Fill(track.phi(), track.eta(), vtxz); // charged and id'ed particle weights } else { - if (withinPtRef && !pid_index) + if (withinPtRef && !pid_index) { histos.fill(HIST("NUA/hPhiEtaVtxz_ref"), track.phi(), track.eta(), vtxz); // pt-subset of charged particles for ref flow + histos.fill(HIST("NUA/hPhiPtCent_ref"), track.phi(), track.pt(), cent); + histos.fill(HIST("NUA/hPhiEtaPt_ref"), track.phi(), track.eta(), track.pt()); + } + if (withinPtPOI) { switch (pid_index) { case 0: histos.fill(HIST("NUA/hPhiEtaVtxz_ch"), track.phi(), track.eta(), vtxz); // charged particle weights + histos.fill(HIST("NUA/hPhiPtCent_ch"), track.phi(), track.pt(), cent); + histos.fill(HIST("NUA/hPhiEtaPt_ch"), track.phi(), track.eta(), track.pt()); break; case 1: histos.fill(HIST("NUA/hPhiEtaVtxz_pi"), track.phi(), track.eta(), vtxz); // pion weights + histos.fill(HIST("NUA/hPhiPtCent_pi"), track.phi(), track.pt(), cent); + histos.fill(HIST("NUA/hPhiEtaPt_pi"), track.phi(), track.eta(), track.pt()); break; case 2: histos.fill(HIST("NUA/hPhiEtaVtxz_ka"), track.phi(), track.eta(), vtxz); // kaon weights + histos.fill(HIST("NUA/hPhiPtCent_ka"), track.phi(), track.pt(), cent); + histos.fill(HIST("NUA/hPhiEtaPt_ka"), track.phi(), track.eta(), track.pt()); break; case 3: histos.fill(HIST("NUA/hPhiEtaVtxz_pr"), track.phi(), track.eta(), vtxz); // proton weights + histos.fill(HIST("NUA/hPhiPtCent_pr"), track.phi(), track.pt(), cent); + histos.fill(HIST("NUA/hPhiEtaPt_pr"), track.phi(), track.eta(), track.pt()); break; } } @@ -523,6 +675,37 @@ struct FlowPbpbPikp { int pidIndex; loadCorrections(bc); // load corrections for the each event + // Track loop for calculating the Qn angles + double psi2Est = 0, psi3Est = 0, psi4Est = 0; + float wEPeff = 1; + double v2 = 0, v3 = 0, v4 = 0; + // be cautious, this only works for Pb-Pb + // esimate the Qn angles and vn for this event + if (cfgTrackDensityCorrUse) { + double q2x = 0, q2y = 0; + double q3x = 0, q3y = 0; + double q4x = 0, q4y = 0; + for (const auto& track : tracks) { + bool withinPtRef = (cfgCutPtMin < track.pt()) && (track.pt() < cfgCutPtMax); // within RF pT range + if (withinPtRef) { + q2x += std::cos(2 * track.phi()); + q2y += std::sin(2 * track.phi()); + q3x += std::cos(3 * track.phi()); + q3y += std::sin(3 * track.phi()); + q4x += std::cos(4 * track.phi()); + q4y += std::sin(4 * track.phi()); + } + } + psi2Est = std::atan2(q2y, q2x) / 2.; + psi3Est = std::atan2(q3y, q3x) / 3.; + psi4Est = std::atan2(q4y, q4x) / 4.; + + v2 = funcV2->Eval(cent); + v3 = funcV3->Eval(cent); + v4 = funcV4->Eval(cent); + } + + // Actual track loop for (auto const& track : tracks) { if (!selectionTrack(track)) continue; @@ -539,29 +722,43 @@ struct FlowPbpbPikp { bool withinPtRef = (cfgCutPtMin < pt) && (pt < cfgCutPtMax); // within RF pT range // pidIndex = getBayesPIDIndex(track); - pidIndex = getNsigmaPID(track); + pidIndex = getNsigmaPIDTpcTof(track); + + weff = 1; // Initializing weff for each track + // NUA weights if (cfgOutputNUAWeights) - fillWeights(track, vtxz, pidIndex, runNumber); + fillWeights(track, collision, pidIndex, runNumber); if (!withinPtPOI && !withinPtRef) return; - double waccRef = getAcceptance(track, vtxz, 0); - double waccPOI = withinPtPOI ? getAcceptance(track, vtxz, pidIndex + 1) : getAcceptance(track, vtxz, 0); + double waccRef = getAcceptance(track, collision, 0); + double waccPOI = withinPtPOI ? getAcceptance(track, collision, pidIndex + 1) : getAcceptance(track, collision, 0); if (withinPtRef && withinPtPOI && pidIndex) waccRef = waccPOI; // if particle is both (then it's overlap), override ref with POI + // Track density correction + if (cfgTrackDensityCorrUse && withinPtRef) { + double fphi = v2 * std::cos(2 * (track.phi() - psi2Est)) + v3 * std::cos(3 * (track.phi() - psi3Est)) + v4 * std::cos(4 * (track.phi() - psi4Est)); + fphi = (1 + 2 * fphi); + int pTBinForEff = hFindPtBin->FindBin(track.pt()); + if (pTBinForEff >= 1 && pTBinForEff <= hFindPtBin->GetNbinsX()) { + wEPeff = funcEff[pTBinForEff - 1]->Eval(fphi * tracks.size()); + if (wEPeff > 0.) { + wEPeff = 1. / wEPeff; + weff *= wEPeff; + } + } + } // end of track density correction loop + if (withinPtRef) { histos.fill(HIST("hPhiWeighted"), track.phi(), waccRef); fGFW->Fill(track.eta(), fPtAxis->FindBin(pt) - 1, track.phi(), waccRef * weff, 1); - fGFW->Fill(track.eta(), 1, track.phi(), waccRef * weff, 512); } if (withinPtPOI) { fGFW->Fill(track.eta(), fPtAxis->FindBin(pt) - 1, track.phi(), waccPOI * weff, 128); - fGFW->Fill(track.eta(), fPtAxis->FindBin(pt) - 1, track.phi(), waccPOI * weff, 1024); } if (withinPtPOI && withinPtRef) { fGFW->Fill(track.eta(), fPtAxis->FindBin(pt) - 1, track.phi(), waccPOI * weff, 256); - fGFW->Fill(track.eta(), fPtAxis->FindBin(pt) - 1, track.phi(), waccPOI * weff, 2048); } if (pidIndex) { @@ -574,15 +771,22 @@ struct FlowPbpbPikp { } // track loop ends // Filling cumulants with ROOT TProfile - fillProfile(corrconfigs.at(1), HIST("c22_gap08"), cent); - fillProfile(corrconfigs.at(2), HIST("c22_gap08_pi"), cent); - fillProfile(corrconfigs.at(3), HIST("c22_gap08_ka"), cent); - fillProfile(corrconfigs.at(4), HIST("c22_gap08_pr"), cent); - fillProfile(corrconfigs.at(5), HIST("c24_full"), cent); - fillProfile(corrconfigs.at(6), HIST("c24_gap08"), cent); - fillProfile(corrconfigs.at(7), HIST("c24_gap08_pi"), cent); - fillProfile(corrconfigs.at(8), HIST("c24_gap08_ka"), cent); - fillProfile(corrconfigs.at(9), HIST("c24_gap08_pr"), cent); + fillProfile(corrconfigs.at(0), HIST("c22_full_ch"), cent); + fillProfile(corrconfigs.at(1), HIST("c22_full_pi"), cent); + fillProfile(corrconfigs.at(2), HIST("c22_full_ka"), cent); + fillProfile(corrconfigs.at(3), HIST("c22_full_pr"), cent); + fillProfile(corrconfigs.at(4), HIST("c22_gap08F_ch"), cent); + fillProfile(corrconfigs.at(5), HIST("c22_gap08F_pi"), cent); + fillProfile(corrconfigs.at(6), HIST("c22_gap08F_ka"), cent); + fillProfile(corrconfigs.at(7), HIST("c22_gap08F_pr"), cent); + fillProfile(corrconfigs.at(8), HIST("c22_gap08B_ch"), cent); + fillProfile(corrconfigs.at(9), HIST("c22_gap08B_pi"), cent); + fillProfile(corrconfigs.at(10), HIST("c22_gap08B_ka"), cent); + fillProfile(corrconfigs.at(11), HIST("c22_gap08B_pr"), cent); + fillProfile(corrconfigs.at(12), HIST("c24_full_ch"), cent); + fillProfile(corrconfigs.at(13), HIST("c24_full_pi"), cent); + fillProfile(corrconfigs.at(14), HIST("c24_full_ka"), cent); + fillProfile(corrconfigs.at(15), HIST("c24_full_pr"), cent); for (uint l_ind = 0; l_ind < corrconfigs.size(); l_ind++) { fillFC(corrconfigs.at(l_ind), cent, lRandom); diff --git a/PWGCF/Flow/Tasks/pidcme.cxx b/PWGCF/Flow/Tasks/flowPidCme.cxx similarity index 97% rename from PWGCF/Flow/Tasks/pidcme.cxx rename to PWGCF/Flow/Tasks/flowPidCme.cxx index 8242b9af48b..bd91bdc4450 100644 --- a/PWGCF/Flow/Tasks/pidcme.cxx +++ b/PWGCF/Flow/Tasks/flowPidCme.cxx @@ -10,10 +10,9 @@ // or submit itself to any jurisdiction. /// \author ZhengqingWang(zhengqing.wang@cern.ch) -/// \file pidcme.cxx +/// \file flowPidCme.cxx /// \brief task to calculate the pikp cme signal and bacground. // C++/ROOT includes. -// o2-linter: disable=name/workflow-file #include #include #include @@ -75,6 +74,38 @@ DECLARE_SOA_TABLE(Flags, "AOD", "Flags", cme_track_pid_columns::NPidFlag); DECLARE_SOA_TABLE(PidInfo, "AOD", "PidInfo", cme_track_pid_columns::AverClusterSizeCosl, cme_track_pid_columns::NSigmaPiITS, cme_track_pid_columns::NSigmaKaITS, cme_track_pid_columns::NSigmaPrITS, cme_track_pid_columns::NSigmaPiTPC, cme_track_pid_columns::NSigmaKaTPC, cme_track_pid_columns::NSigmaPrTPC, cme_track_pid_columns::NSigmaPiTOF, cme_track_pid_columns::NSigmaKaTOF, cme_track_pid_columns::NSigmaPrTOF); } // namespace o2::aod +namespace pid_flags +{ +constexpr int8_t kUnqualified = -1; +constexpr int8_t kUnPOIHadron = 0; +constexpr int8_t kPion = 1; +constexpr int8_t kKaon = 2; +constexpr int8_t kProton = 3; +constexpr int8_t kPionITSleft = 4; +constexpr int8_t kKaonITSleft = 5; +constexpr int8_t kProtonITSleft = 6; +constexpr int8_t kPionKaon = 7; +constexpr int8_t kPionProton = 8; +constexpr int8_t kKaonProton = 9; +constexpr int8_t kPionKaonProton = 10; +constexpr int8_t kPionKaonITSleft = 11; +constexpr int8_t kPionProtonITSleft = 12; +constexpr int8_t kKaonProtonITSleft = 13; +constexpr int8_t kPionKaonProtonITSleft = 14; +} // namespace pid_flags + +namespace event_selection +{ +constexpr int kFT0AV0ASigma = 5; +} + +namespace fourier_mode +{ +// constexpr int kMode1 = 1; +constexpr int kMode2 = 2; +// constexpr int kMode3 = 3; +} // namespace fourier_mode + using TracksPID = soa::Join; using CollisionPID = soa::Join; struct FillPIDcolums { @@ -182,8 +213,9 @@ struct FillPIDcolums { float average = 0; int nclusters = 0; const float cosl = 1. / std::cosh(eta); + const int nlayerITS = 7; - for (int layer = 0; layer < 7; layer++) { + for (int layer = 0; layer < nlayerITS; layer++) { if ((itsClusterSizes >> (layer * 4)) & 0xf) { nclusters++; average += (itsClusterSizes >> (layer * 4)) & 0xf; @@ -284,10 +316,14 @@ struct FillPIDcolums { pidVectorLower = (candidate.pt() > cfgPtMaxforTPCOnlyPID && candidate.hasTOF()) ? cfgnSigmaCutRMSLower.value : cfgnSigmaCutTPCLower.value; } float nsigma = 9999.99; + const int nPOI = 3; + const int piCase = 0; + const int kaCase = 1; + const int prCase = 2; // Fill cross pid QA - for (int i = 0; i < 3; ++i) { + for (int i = 0; i < nPOI; ++i) { if (nSigmaToUse[i] > pidVectorLower[i] && nSigmaToUse[i] < pidVectorUpper[i]) { - if (i == 0) { + if (i == piCase) { kIsPi = true; if (!cfgQuietMode) { if (cfgOpenCrossTrackQAPlots) { @@ -328,7 +364,7 @@ struct FillPIDcolums { } } } - if (i == 1) { + if (i == kaCase) { kIsKa = true; if (!cfgQuietMode) { if (cfgOpenCrossTrackQAPlots) { @@ -369,7 +405,7 @@ struct FillPIDcolums { } } } - if (i == 2) { + if (i == prCase) { kIsPr = true; if (!cfgQuietMode) { if (cfgOpenCrossTrackQAPlots) { @@ -419,7 +455,7 @@ struct FillPIDcolums { return map[index]; } else { // Select particle with the lowest nsigma (If not allow cross track) - for (int i = 0; i < 3; ++i) { + for (int i = 0; i < nPOI; ++i) { if (std::abs(nSigmaToUse[i]) < nsigma && (nSigmaToUse[i] > pidVectorLower[i] && nSigmaToUse[i] < pidVectorUpper[i])) { pid = i; nsigma = std::abs(nSigmaToUse[i]); @@ -984,16 +1020,16 @@ struct FillPIDcolums { } } pidFlag = selectionPidtpctof(track, nSigmaTOFCutPtUpper, nSigmaTOFCutPtLower, nSigmaTPCCutPtUpper, nSigmaTPCCutPtLower); - if (!(pidFlag == 0 || pidFlag == -1)) { + if (!(pidFlag == pid_flags::kUnqualified || pidFlag == pid_flags::kUnPOIHadron)) { // First fill ITS uncut plots - if ((pidFlag == 1) || (pidFlag == 7) || (pidFlag == 8) || (pidFlag == 10)) { + if ((pidFlag == pid_flags::kPion) || (pidFlag == pid_flags::kPionKaon) || (pidFlag == pid_flags::kPionProton) || (pidFlag == pid_flags::kPionKaonProton)) { if (cfgOpenTPCAssistanceTOFOnlyPID && !(track.tpcNSigmaPi() > nSigmaTPCCutPiPtLower && track.tpcNSigmaPi() < nSigmaTPCCutPiPtUpper)) { pidFlag = 0; } if (cfgOpenPIDPtSelection && !(track.pt() > cfgPtCutLower.value[0] && track.pt() < cfgPtCutUpper.value[0])) { pidFlag = 0; } - if (!(cfgQuietMode || pidFlag == 0)) { + if (!(cfgQuietMode || pidFlag == pid_flags::kUnPOIHadron)) { histosQA.fill(HIST("QA/PID/histnSigmaITS_nSigmaTPC_Pi"), track.itsNSigmaPi(), track.tpcNSigmaPi()); histosQA.fill(HIST("QA/PID/histnSigmaTOF_nSigmaITS_Pi"), track.tofNSigmaPi(), track.itsNSigmaPi()); histosQA.fill(HIST("QA/PID/histnSigmaTOF_nSigmaTPC_Pi"), track.tofNSigmaPi(), track.tpcNSigmaPi()); @@ -1048,14 +1084,14 @@ struct FillPIDcolums { } } } - if ((pidFlag == 2) || (pidFlag == 7) || (pidFlag == 9) || (pidFlag == 10)) { + if ((pidFlag == pid_flags::kKaon) || (pidFlag == pid_flags::kPionKaon) || (pidFlag == pid_flags::kKaonProton) || (pidFlag == pid_flags::kPionKaonProton)) { if (cfgOpenTPCAssistanceTOFOnlyPID && !(track.tpcNSigmaKa() > nSigmaTPCCutKaPtLower && track.tpcNSigmaKa() < nSigmaTPCCutKaPtUpper)) { pidFlag = 0; } if (cfgOpenPIDPtSelection && !(track.pt() > cfgPtCutLower.value[1] && track.pt() < cfgPtCutUpper.value[1])) { pidFlag = 0; } - if (!(cfgQuietMode || pidFlag == 0)) { + if (!(cfgQuietMode || pid_flags::kUnPOIHadron)) { histosQA.fill(HIST("QA/PID/histnSigmaITS_nSigmaTPC_Ka"), track.itsNSigmaKa(), track.tpcNSigmaKa()); histosQA.fill(HIST("QA/PID/histnSigmaTOF_nSigmaITS_Ka"), track.tofNSigmaKa(), track.itsNSigmaKa()); histosQA.fill(HIST("QA/PID/histnSigmaTOF_nSigmaTPC_Ka"), track.tofNSigmaKa(), track.tpcNSigmaKa()); @@ -1110,14 +1146,14 @@ struct FillPIDcolums { } } } - if ((pidFlag == 3) || (pidFlag == 8) || (pidFlag == 9) || (pidFlag == 10)) { + if ((pidFlag == pid_flags::kProton) || (pidFlag == pid_flags::kPionProton) || (pidFlag == pid_flags::kKaonProton) || (pidFlag == pid_flags::kPionKaonProton)) { if (cfgOpenTPCAssistanceTOFOnlyPID && !(track.tpcNSigmaPr() > nSigmaTPCCutPrPtLower && track.tpcNSigmaPr() < nSigmaTPCCutPrPtUpper)) { pidFlag = 0; } if (cfgOpenPIDPtSelection && !(track.pt() > cfgPtCutLower.value[2] && track.pt() < cfgPtCutUpper.value[2])) { pidFlag = 0; } - if (!(cfgQuietMode || pidFlag == 0)) { + if (!(cfgQuietMode || pidFlag == pid_flags::kUnPOIHadron)) { histosQA.fill(HIST("QA/PID/histnSigmaITS_nSigmaTPC_Pr"), track.itsNSigmaPr(), track.tpcNSigmaPr()); histosQA.fill(HIST("QA/PID/histnSigmaTOF_nSigmaITS_Pr"), track.tofNSigmaPr(), track.itsNSigmaPr()); histosQA.fill(HIST("QA/PID/histnSigmaTOF_nSigmaTPC_Pr"), track.tofNSigmaPr(), track.tpcNSigmaPr()); @@ -1284,7 +1320,7 @@ struct FillPIDcolums { histosQA.fill(HIST("QA/PID/histTPCChi2Ncls_total_AfterITS"), track.tpcChi2NCl()); histosQA.fill(HIST("QA/PID/histITSChi2Ncls_total_AfterITS"), track.itsChi2NCl()); } - if ((pidFlag == 1) || (pidFlag == 7) || (pidFlag == 8) || (pidFlag == 10)) { + if ((pidFlag == pid_flags::kPion) || (pidFlag == pid_flags::kPionKaon) || (pidFlag == pid_flags::kPionProton) || (pidFlag == pid_flags::kPionKaonProton)) { histosQA.fill(HIST("QA/PID/histnSigmaITS_nSigmaTPC_AfterITS_Pi"), track.itsNSigmaPi(), track.tpcNSigmaPi()); histosQA.fill(HIST("QA/PID/histnSigmaTOF_nSigmaITS_AfterITS_Pi"), track.tofNSigmaPi(), track.itsNSigmaPi()); histosQA.fill(HIST("QA/PID/histnSigmaTOF_nSigmaTPC_AfterITS_Pi"), track.tofNSigmaPi(), track.tpcNSigmaPi()); @@ -1333,7 +1369,7 @@ struct FillPIDcolums { } } } - if ((pidFlag == 2) || (pidFlag == 7) || (pidFlag == 9) || (pidFlag == 10)) { + if ((pidFlag == pid_flags::kKaon) || (pidFlag == pid_flags::kPionKaon) || (pidFlag == pid_flags::kKaonProton) || (pidFlag == pid_flags::kPionKaonProton)) { histosQA.fill(HIST("QA/PID/histnSigmaITS_nSigmaTPC_AfterITS_Ka"), track.itsNSigmaKa(), track.tpcNSigmaKa()); histosQA.fill(HIST("QA/PID/histnSigmaTOF_nSigmaITS_AfterITS_Ka"), track.tofNSigmaKa(), track.itsNSigmaKa()); histosQA.fill(HIST("QA/PID/histnSigmaTOF_nSigmaTPC_AfterITS_Ka"), track.tofNSigmaKa(), track.tpcNSigmaKa()); @@ -1382,7 +1418,7 @@ struct FillPIDcolums { } } } - if ((pidFlag == 3) || (pidFlag == 8) || (pidFlag == 9) || (pidFlag == 10)) { + if ((pidFlag == pid_flags::kProton) || (pidFlag == pid_flags::kPionProton) || (pidFlag == pid_flags::kKaonProton) || (pidFlag == pid_flags::kPionKaonProton)) { histosQA.fill(HIST("QA/PID/histnSigmaITS_nSigmaTPC_AfterITS_Pr"), track.itsNSigmaPr(), track.tpcNSigmaPr()); histosQA.fill(HIST("QA/PID/histnSigmaTOF_nSigmaITS_AfterITS_Pr"), track.tofNSigmaPr(), track.itsNSigmaPr()); histosQA.fill(HIST("QA/PID/histnSigmaTOF_nSigmaTPC_AfterITS_Pr"), track.tofNSigmaPr(), track.tpcNSigmaPr()); @@ -1712,9 +1748,9 @@ struct QAProcessCent { for (const auto& trk : tracks) { int8_t pidFlag = trk.nPidFlag(); if (cfgOpenPi) { - if ((pidFlag == 1) || (pidFlag == 4) || (pidFlag == 7) || (pidFlag == 8) || (pidFlag == 10) || (pidFlag == 11) || (pidFlag == 12) || (pidFlag == 14)) { + if ((pidFlag == pid_flags::kPion) || (pidFlag == pid_flags::kPionITSleft) || (pidFlag == pid_flags::kPionKaon) || (pidFlag == pid_flags::kPionProton) || (pidFlag == pid_flags::kPionKaonProton) || (pidFlag == pid_flags::kPionKaonITSleft) || (pidFlag == pid_flags::kPionProtonITSleft) || (pidFlag == pid_flags::kPionKaonProtonITSleft)) { if (trk.sign() > 0) { - if (!((pidFlag == 4) || (pidFlag == 11) || (pidFlag == 12) || (pidFlag == 14))) { + if (!((pidFlag == pid_flags::kPionITSleft) || (pidFlag == pid_flags::kPionKaonITSleft) || (pidFlag == pid_flags::kPionProtonITSleft) || (pidFlag == pid_flags::kPionKaonProtonITSleft))) { if (cfgOpenPtEtaPhi) { vhistPhiPtEtaPosPiCen[currentBin]->Fill(trk.phi(), trk.pt(), trk.eta()); } @@ -1746,7 +1782,7 @@ struct QAProcessCent { vhistnSigmaTOFTPCPtPosPiBeforeCen[currentBin]->Fill(trk.nSigmaPiTOF(), trk.nSigmaPiTPC(), trk.pt()); } } else if (trk.sign() < 0) { - if (!((pidFlag == 4) || (pidFlag == 11) || (pidFlag == 12) || (pidFlag == 14))) { + if (!((pidFlag == pid_flags::kPionITSleft) || (pidFlag == pid_flags::kPionKaonITSleft) || (pidFlag == pid_flags::kPionProtonITSleft) || (pidFlag == pid_flags::kPionKaonProtonITSleft))) { if (cfgOpenPtEtaPhi) { vhistPhiPtEtaNegPiCen[currentBin]->Fill(trk.phi(), trk.pt(), trk.eta()); } @@ -1781,9 +1817,9 @@ struct QAProcessCent { } } if (cfgOpenKa) { - if ((pidFlag == 2) || (pidFlag == 5) || (pidFlag == 7) || (pidFlag == 9) || (pidFlag == 10) || (pidFlag == 11) || (pidFlag == 13) || (pidFlag == 14)) { + if ((pidFlag == pid_flags::kKaon) || (pidFlag == pid_flags::kKaonITSleft) || (pidFlag == pid_flags::kPionKaon) || (pidFlag == pid_flags::kKaonProton) || (pidFlag == pid_flags::kPionKaonProton) || (pidFlag == pid_flags::kPionKaonITSleft) || (pidFlag == pid_flags::kKaonProtonITSleft) || (pidFlag == pid_flags::kPionKaonProtonITSleft)) { if (trk.sign() > 0) { - if (!((pidFlag == 5) || (pidFlag == 11) || (pidFlag == 13) || (pidFlag == 14))) { + if (!((pidFlag == pid_flags::kKaonITSleft) || (pidFlag == pid_flags::kPionKaonITSleft) || (pidFlag == pid_flags::kKaonProtonITSleft) || (pidFlag == pid_flags::kPionKaonProtonITSleft))) { if (cfgOpenPtEtaPhi) { vhistPhiPtEtaPosKaCen[currentBin]->Fill(trk.phi(), trk.pt(), trk.eta()); } @@ -1815,7 +1851,7 @@ struct QAProcessCent { vhistnSigmaTOFTPCPtPosKaBeforeCen[currentBin]->Fill(trk.nSigmaKaTOF(), trk.nSigmaKaTPC(), trk.pt()); } } else if (trk.sign() < 0) { - if (!((pidFlag == 5) || (pidFlag == 11) || (pidFlag == 13) || (pidFlag == 14))) { + if (!((pidFlag == pid_flags::kKaonITSleft) || (pidFlag == pid_flags::kPionKaonITSleft) || (pidFlag == pid_flags::kKaonProtonITSleft) || (pidFlag == pid_flags::kPionKaonProtonITSleft))) { if (cfgOpenPtEtaPhi) { vhistPhiPtEtaNegKaCen[currentBin]->Fill(trk.phi(), trk.pt(), trk.eta()); } @@ -1850,9 +1886,9 @@ struct QAProcessCent { } } if (cfgOpenPr) { - if ((pidFlag == 3) || (pidFlag == 6) || (pidFlag == 8) || (pidFlag == 9) || (pidFlag == 10) || (pidFlag == 12) || (pidFlag == 13) || (pidFlag == 14)) { + if ((pidFlag == pid_flags::kProton) || (pidFlag == pid_flags::kProtonITSleft) || (pidFlag == pid_flags::kPionProton) || (pidFlag == pid_flags::kKaonProton) || (pidFlag == pid_flags::kPionKaonProton) || (pidFlag == pid_flags::kPionProtonITSleft) || (pidFlag == pid_flags::kKaonProtonITSleft) || (pidFlag == pid_flags::kPionKaonProtonITSleft)) { if (trk.sign() > 0) { - if (!((pidFlag == 6) || (pidFlag == 12) || (pidFlag == 13) || (pidFlag == 14))) { + if (!((pidFlag == pid_flags::kProtonITSleft) || (pidFlag == pid_flags::kPionProtonITSleft) || (pidFlag == pid_flags::kKaonProtonITSleft) || (pidFlag == pid_flags::kPionKaonProtonITSleft))) { if (cfgOpenPtEtaPhi) { vhistPhiPtEtaPosPrCen[currentBin]->Fill(trk.phi(), trk.pt(), trk.eta()); } @@ -1884,7 +1920,7 @@ struct QAProcessCent { vhistnSigmaTOFTPCPtPosPrBeforeCen[currentBin]->Fill(trk.nSigmaPrTOF(), trk.nSigmaPrTPC(), trk.pt()); } } else if (trk.sign() < 0) { - if (!((pidFlag == 6) || (pidFlag == 12) || (pidFlag == 13) || (pidFlag == 14))) { + if (!((pidFlag == pid_flags::kProtonITSleft) || (pidFlag == pid_flags::kPionProtonITSleft) || (pidFlag == pid_flags::kKaonProtonITSleft) || (pidFlag == pid_flags::kPionKaonProtonITSleft))) { if (cfgOpenPtEtaPhi) { vhistPhiPtEtaNegPrCen[currentBin]->Fill(trk.phi(), trk.pt(), trk.eta()); } @@ -1924,7 +1960,7 @@ struct QAProcessCent { } }; -struct pidcme { // o2-linter: disable=name/struct(keep the saving dir name for offline analysis) +struct FlowPidCme { HistogramRegistry histosQA{"histosmain", {}, OutputObjHandlingPolicy::AnalysisObject}; Configurable> cfgnMods{"cfgnMods", {2}, "Modulation of interest"}; @@ -2055,9 +2091,9 @@ struct pidcme { // o2-linter: disable=name/struct(keep the saving dir name for o Filter etafilter = aod::track::eta < cfgMaxEta; Filter properPIDfilter = aod::cme_track_pid_columns::nPidFlag >= (int8_t)0; - Partition>> tracksSet1 = ((aod::cme_track_pid_columns::nPidFlag == 1) || (aod::cme_track_pid_columns::nPidFlag == 7) || (aod::cme_track_pid_columns::nPidFlag == 8) || (aod::cme_track_pid_columns::nPidFlag == 10)); - Partition>> tracksSet2 = ((aod::cme_track_pid_columns::nPidFlag == 2) || (aod::cme_track_pid_columns::nPidFlag == 7) || (aod::cme_track_pid_columns::nPidFlag == 9) || (aod::cme_track_pid_columns::nPidFlag == 10)); - Partition>> tracksSet3 = ((aod::cme_track_pid_columns::nPidFlag == 3) || (aod::cme_track_pid_columns::nPidFlag == 8) || (aod::cme_track_pid_columns::nPidFlag == 9) || (aod::cme_track_pid_columns::nPidFlag == 10)); + Partition>> tracksSet1 = ((aod::cme_track_pid_columns::nPidFlag == pid_flags::kPion) || (aod::cme_track_pid_columns::nPidFlag == pid_flags::kPionKaon) || (aod::cme_track_pid_columns::nPidFlag == pid_flags::kPionProton) || (aod::cme_track_pid_columns::nPidFlag == pid_flags::kPionKaonProton)); + Partition>> tracksSet2 = ((aod::cme_track_pid_columns::nPidFlag == pid_flags::kKaon) || (aod::cme_track_pid_columns::nPidFlag == pid_flags::kPionKaon) || (aod::cme_track_pid_columns::nPidFlag == pid_flags::kKaonProton) || (aod::cme_track_pid_columns::nPidFlag == pid_flags::kPionKaonProton)); + Partition>> tracksSet3 = ((aod::cme_track_pid_columns::nPidFlag == pid_flags::kProton) || (aod::cme_track_pid_columns::nPidFlag == pid_flags::kPionProton) || (aod::cme_track_pid_columns::nPidFlag == pid_flags::kKaonProton) || (aod::cme_track_pid_columns::nPidFlag == pid_flags::kPionKaonProton)); void init(InitContext const&) { @@ -2561,7 +2597,7 @@ struct pidcme { // o2-linter: disable=name/struct(keep the saving dir name for o if (cfgOpenEvSelMultCorrelationGlobalTracks) { histosQA.fill(HIST("QA/histEventCountDetail"), 9.5); } - if (cfgOpenEvSelV0AT0ACut && (std::fabs(collision.multFV0A() - fT0AV0AMean->Eval(collision.multFT0A())) > 5 * fT0AV0ASigma->Eval(collision.multFT0A()))) { + if (cfgOpenEvSelV0AT0ACut && (std::fabs(collision.multFV0A() - fT0AV0AMean->Eval(collision.multFT0A())) > event_selection::kFT0AV0ASigma * fT0AV0ASigma->Eval(collision.multFT0A()))) { return 0; } if (cfgOpenEvSelV0AT0ACut) { @@ -2608,7 +2644,7 @@ struct pidcme { // o2-linter: disable=name/struct(keep the saving dir name for o } } if ((cenBin >= 0) && (ptBin >= 0)) { - if ((track.nPidFlag() == 3) || (track.nPidFlag() == 8) || (track.nPidFlag() == 9) || (track.nPidFlag() == 10)) { + if ((track.nPidFlag() == pid_flags::kProton) || (track.nPidFlag() == pid_flags::kPionProton) || (track.nPidFlag() == pid_flags::kKaonProton) || (track.nPidFlag() == pid_flags::kPionKaonProton)) { if (cfgkOpenDebugPIDCME) { LOGF(info, Form("=========cen_bin: %d pt_bin: %d=========", cenBin, ptBin)); } @@ -2646,7 +2682,7 @@ struct pidcme { // o2-linter: disable=name/struct(keep the saving dir name for o int detInd = detId * 4 + cfgnTotalSystem * 4 * (nmode - 2); int refAInd = refAId * 4 + cfgnTotalSystem * 4 * (nmode - 2); int refBInd = refBId * 4 + cfgnTotalSystem * 4 * (nmode - 2); - if (nmode == 2) { + if (nmode == fourier_mode::kMode2) { if (collision.qvecAmp()[detId] > 1e-8) { histosQA.fill(HIST("QA/histQvec_CorrL0_V2"), collision.qvecRe()[detInd], collision.qvecIm()[detInd], collision.centFT0C()); histosQA.fill(HIST("QA/histQvec_CorrL1_V2"), collision.qvecRe()[detInd + 1], collision.qvecIm()[detInd + 1], collision.centFT0C()); @@ -2678,7 +2714,7 @@ struct pidcme { // o2-linter: disable=name/struct(keep the saving dir name for o for (const auto& trk : track1) { if (!selTrack(trk, cent)) continue; - if (nmode == 2) { + if (nmode == fourier_mode::kMode2) { if (trk.sign() > 0) { histosQA.fill(HIST("V2/PID/histCosDetV2_Pi"), cent, trk.pt(), std::cos(static_cast(nmode) * (trk.phi() - psiN))); @@ -2715,7 +2751,7 @@ struct pidcme { // o2-linter: disable=name/struct(keep the saving dir name for o for (const auto& trk : track2) { if (!selTrack(trk, cent)) continue; - if (nmode == 2) { + if (nmode == fourier_mode::kMode2) { if (trk.sign() > 0) { histosQA.fill(HIST("V2/PID/histCosDetV2_Ka"), cent, trk.pt(), std::cos(static_cast(nmode) * (trk.phi() - psiN))); @@ -2752,7 +2788,7 @@ struct pidcme { // o2-linter: disable=name/struct(keep the saving dir name for o for (const auto& trk : track3) { if (!selTrack(trk, cent)) continue; - if (nmode == 2) { + if (nmode == fourier_mode::kMode2) { if (trk.sign() > 0) { histosQA.fill(HIST("V2/PID/histCosDetV2_Pr"), cent, trk.pt(), std::cos(static_cast(nmode) * (trk.phi() - psiN))); @@ -2797,7 +2833,7 @@ struct pidcme { // o2-linter: disable=name/struct(keep the saving dir name for o continue; if (!selTrack(trk2, cent)) continue; - if (nmode == 2) { + if (nmode == fourier_mode::kMode2) { if (trk1.sign() == trk2.sign()) { histosQA.fill(HIST("PIDCME/histgamma_PiPi_ss"), cent, std::cos((trk1.phi() + trk2.phi() - static_cast(nmode) * psiN))); histosQA.fill(HIST("PIDCME/histdelta_PiPi_ss"), cent, std::cos((trk1.phi() - trk2.phi()))); @@ -2876,7 +2912,7 @@ struct pidcme { // o2-linter: disable=name/struct(keep the saving dir name for o continue; if (!selTrack(trk2, cent)) continue; - if (nmode == 2) { + if (nmode == fourier_mode::kMode2) { if (trk1.sign() == trk2.sign()) { histosQA.fill(HIST("PIDCME/histgamma_KaKa_ss"), cent, std::cos((trk1.phi() + trk2.phi() - static_cast(nmode) * psiN))); histosQA.fill(HIST("PIDCME/histdelta_KaKa_ss"), cent, std::cos((trk1.phi() - trk2.phi()))); @@ -2955,7 +2991,7 @@ struct pidcme { // o2-linter: disable=name/struct(keep the saving dir name for o continue; if (!selTrack(trk2, cent)) continue; - if (nmode == 2) { + if (nmode == fourier_mode::kMode2) { if (trk1.sign() == trk2.sign()) { histosQA.fill(HIST("PIDCME/histgamma_PrPr_ss"), cent, std::cos((trk1.phi() + trk2.phi() - static_cast(nmode) * psiN))); histosQA.fill(HIST("PIDCME/histdelta_PrPr_ss"), cent, std::cos((trk1.phi() - trk2.phi()))); @@ -3034,7 +3070,7 @@ struct pidcme { // o2-linter: disable=name/struct(keep the saving dir name for o continue; if (!selTrack(trk2, cent)) continue; - if (nmode == 2) { + if (nmode == fourier_mode::kMode2) { if (trk1.sign() == trk2.sign()) { histosQA.fill(HIST("PIDCME/histgamma_PiKa_ss"), cent, std::cos((trk1.phi() + trk2.phi() - static_cast(nmode) * psiN))); histosQA.fill(HIST("PIDCME/histdelta_PiKa_ss"), cent, std::cos((trk1.phi() - trk2.phi()))); @@ -3113,7 +3149,7 @@ struct pidcme { // o2-linter: disable=name/struct(keep the saving dir name for o continue; if (!selTrack(trk3, cent)) continue; - if (nmode == 2) { + if (nmode == fourier_mode::kMode2) { if (trk1.sign() == trk3.sign()) { histosQA.fill(HIST("PIDCME/histgamma_PiPr_ss"), cent, std::cos((trk1.phi() + trk3.phi() - static_cast(nmode) * psiN))); histosQA.fill(HIST("PIDCME/histdelta_PiPr_ss"), cent, std::cos((trk1.phi() - trk3.phi()))); @@ -3192,7 +3228,7 @@ struct pidcme { // o2-linter: disable=name/struct(keep the saving dir name for o continue; if (!selTrack(trk3, cent)) continue; - if (nmode == 2) { + if (nmode == fourier_mode::kMode2) { if (trk2.sign() == trk3.sign()) { histosQA.fill(HIST("PIDCME/histgamma_KaPr_ss"), cent, std::cos((trk2.phi() + trk3.phi() - static_cast(nmode) * psiN))); histosQA.fill(HIST("PIDCME/histdelta_KaPr_ss"), cent, std::cos((trk2.phi() - trk3.phi()))); @@ -3317,6 +3353,8 @@ struct pidcme { // o2-linter: disable=name/struct(keep the saving dir name for o mult3 = tracks3.size(); if (mult1 < 1 || mult2 < 1 || mult3 < 1) // Reject Collisions without sufficient particles return; + const float cenPlotMin = 20; + const float cenPlotMax = 30; for (auto i = 0; i < static_cast(cfgnMods->size()); i++) { int detIndGlobal = detId * 4 + cfgnTotalSystem * 4 * (cfgnMods->at(i) - 2); float psiNGlobal = helperEP.GetEventPlane(collision.qvecRe()[detIndGlobal + 3], collision.qvecIm()[detIndGlobal + 3], cfgnMods->at(i)); @@ -3324,8 +3362,8 @@ struct pidcme { // o2-linter: disable=name/struct(keep the saving dir name for o if (!selTrack(trk, cent)) continue; if (cfgkOpenTPCITSPurityCut && cfgkOpenTPCITSPurityCutQA) { - if (cent >= 20 && cent < 30) { - if ((trk.nPidFlag() == 3) || (trk.nPidFlag() == 8) || (trk.nPidFlag() == 9) || (trk.nPidFlag() == 10)) { + if (cent >= cenPlotMin && cent < cenPlotMax) { + if ((trk.nPidFlag() == pid_flags::kProton) || (trk.nPidFlag() == pid_flags::kPionProton) || (trk.nPidFlag() == pid_flags::kKaonProton) || (trk.nPidFlag() == pid_flags::kPionKaonProton)) { if (trk.sign() > 0) { histosQA.fill(HIST("QA/histITSPuritycheck_Pr_Pos_Cen_20_30"), trk.nSigmaPrTPC(), trk.nSigmaPrITS(), trk.pt()); } else { @@ -3341,7 +3379,7 @@ struct pidcme { // o2-linter: disable=name/struct(keep the saving dir name for o std::cos(static_cast(cfgnMods->at(i)) * (trk.phi() - psiNGlobal))); } } - if (cfgkOpenCME && cfgkOpenHaHa && cfgnMods->at(i) == 2) { + if (cfgkOpenCME && cfgkOpenHaHa && cfgnMods->at(i) == fourier_mode::kMode2) { for (const auto& trk1 : tracks) { if (!selTrack(trk1, cent)) continue; @@ -3429,6 +3467,6 @@ WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) return WorkflowSpec{ adaptAnalysisTask(cfgc), adaptAnalysisTask(cfgc), - adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc), }; } diff --git a/PWGCF/Flow/Tasks/flowSP.cxx b/PWGCF/Flow/Tasks/flowSP.cxx index 9be9242c107..0d524aadcdf 100644 --- a/PWGCF/Flow/Tasks/flowSP.cxx +++ b/PWGCF/Flow/Tasks/flowSP.cxx @@ -62,14 +62,14 @@ struct FlowSP { O2_DEFINE_CONFIGURABLE(cfgCentFV0A, bool, false, "Set centrality estimator to cfgCentFV0A"); O2_DEFINE_CONFIGURABLE(cfgCentNGlobal, bool, false, "Set centrality estimator to cfgCentNGlobal"); // Standard selections - O2_DEFINE_CONFIGURABLE(cfgDCAxy, float, 0.2, "Cut on DCA in the transverse direction (cm)"); - O2_DEFINE_CONFIGURABLE(cfgDCAz, float, 2, "Cut on DCA in the longitudinal direction (cm)"); - O2_DEFINE_CONFIGURABLE(cfgNcls, float, 70, "Cut on number of TPC clusters found"); - O2_DEFINE_CONFIGURABLE(cfgFshcls, float, 0.2, "Cut on fraction of shared TPC clusters found"); - O2_DEFINE_CONFIGURABLE(cfgPtmin, float, 0.2, "minimum pt (GeV/c)"); - O2_DEFINE_CONFIGURABLE(cfgPtmax, float, 10, "maximum pt (GeV/c)"); - O2_DEFINE_CONFIGURABLE(cfgEta, float, 0.8, "eta cut"); - O2_DEFINE_CONFIGURABLE(cfgVtxZ, float, 10, "vertex cut (cm)"); + O2_DEFINE_CONFIGURABLE(cfgTrackSelsDCAxy, float, 0.2, "Cut on DCA in the transverse direction (cm)"); + O2_DEFINE_CONFIGURABLE(cfgTrackSelsDCAz, float, 2, "Cut on DCA in the longitudinal direction (cm)"); + O2_DEFINE_CONFIGURABLE(cfgTrackSelsNcls, float, 70, "Cut on number of TPC clusters found"); + O2_DEFINE_CONFIGURABLE(cfgTrackSelsFshcls, float, 0.4, "Cut on fraction of shared TPC clusters found"); + O2_DEFINE_CONFIGURABLE(cfgTrackSelsPtmin, float, 0.2, "minimum pt (GeV/c)"); + O2_DEFINE_CONFIGURABLE(cfgTrackSelsPtmax, float, 10, "maximum pt (GeV/c)"); + O2_DEFINE_CONFIGURABLE(cfgTrackSelsEta, float, 0.8, "eta cut"); + O2_DEFINE_CONFIGURABLE(cfgEvSelsVtxZ, float, 10, "vertex cut (cm)"); O2_DEFINE_CONFIGURABLE(cfgMagField, float, 99999, "Configurable magnetic field;default CCDB will be queried"); O2_DEFINE_CONFIGURABLE(cfgCentMin, float, 0, "Minimum cenrality for selected events"); @@ -78,39 +78,40 @@ struct FlowSP { O2_DEFINE_CONFIGURABLE(cfgFillWeights, bool, true, "Fill NUA weights"); O2_DEFINE_CONFIGURABLE(cfgFillWeightsPOS, bool, false, "Fill NUA weights only for positive charges"); O2_DEFINE_CONFIGURABLE(cfgFillWeightsNEG, bool, false, "Fill NUA weights only for negative charges"); - O2_DEFINE_CONFIGURABLE(cfgNUA, std::string, "", "ccdb dir for NUA corrections"); - O2_DEFINE_CONFIGURABLE(cfgNUE, std::string, "", "ccdb dir for NUE corrections"); // Additional track Selections - O2_DEFINE_CONFIGURABLE(cfgUseAdditionalTrackCut, bool, true, "Bool to enable Additional Track Cut"); - O2_DEFINE_CONFIGURABLE(cfgDoubleTrackFunction, bool, true, "Include track cut at low pt"); - O2_DEFINE_CONFIGURABLE(cfgTrackCutSize, float, 0.06, "Spread of track cut"); + O2_DEFINE_CONFIGURABLE(cfgTrackSelsUseAdditionalTrackCut, bool, true, "Bool to enable Additional Track Cut"); + O2_DEFINE_CONFIGURABLE(cfgTrackSelsDoubleTrackFunction, bool, true, "Include track cut at low pt"); + O2_DEFINE_CONFIGURABLE(cfgTrackSelsTrackCutSize, float, 0.06, "Spread of track cut"); + O2_DEFINE_CONFIGURABLE(cfgTrackSelsDoDCApt, bool, true, "Apply Pt dependent DCAz cut"); + O2_DEFINE_CONFIGURABLE(cfgTrackSelsDCApt1, float, 0.1, "DcaZ < a * b / pt^1.1 -> this sets a"); + O2_DEFINE_CONFIGURABLE(cfgTrackSelsDCApt2, float, 0.035, "DcaZ < a * b / pt^1.1 -> this sets b"); // Additional event selections - O2_DEFINE_CONFIGURABLE(cfgUseAdditionalEventCut, bool, true, "Bool to enable Additional Event Cut"); - O2_DEFINE_CONFIGURABLE(cfgnSigmaMultCuts, int, 1, "Sigma cut on Additional event cut: 1 (default), 2 or 3 sigma available"); - O2_DEFINE_CONFIGURABLE(cfgManualEventParameters, bool, false, "Use manual event parameters for the pile up fits. Needed for Cent estimaters other than FT0C"); - O2_DEFINE_CONFIGURABLE(cfgMultPv, std::vector, {}, "Multiplicity cuts for PV first 5 parameters cutLOW last 5 cutHIGH"); - O2_DEFINE_CONFIGURABLE(cfgMult, std::vector, {}, "Multiplicity cuts for T0C first 5 parameters cutLOW last 5 cutHIGH"); - O2_DEFINE_CONFIGURABLE(cfgMaxOccupancy, int, 10000, "Maximum occupancy of selected events"); - O2_DEFINE_CONFIGURABLE(cfgNoSameBunchPileupCut, bool, true, "kNoSameBunchPileupCut"); - O2_DEFINE_CONFIGURABLE(cfgIsGoodZvtxFT0vsPV, bool, true, "kIsGoodZvtxFT0vsPV"); - O2_DEFINE_CONFIGURABLE(cfgNoCollInTimeRangeStandard, bool, true, "kNoCollInTimeRangeStandard"); - O2_DEFINE_CONFIGURABLE(cfgDoOccupancySel, bool, true, "Bool for event selection on detector occupancy"); - O2_DEFINE_CONFIGURABLE(cfgTVXinTRD, bool, false, "Use kTVXinTRD (reject TRD triggered events)"); - O2_DEFINE_CONFIGURABLE(cfgIsVertexITSTPC, bool, true, "Selects collisions with at least one ITS-TPC track"); - O2_DEFINE_CONFIGURABLE(cfgIsGoodITSLayersAll, bool, true, "Cut time intervals with dead ITS staves"); + O2_DEFINE_CONFIGURABLE(cfgEvSelsUseAdditionalEventCut, bool, true, "Bool to enable Additional Event Cut"); + O2_DEFINE_CONFIGURABLE(cfgEvSelsnSigmaMultCuts, int, 1, "Sigma cut on Additional event cut: 1 (default), 2 or 3 sigma available"); + O2_DEFINE_CONFIGURABLE(cfgEvSelsManualEventParameters, bool, false, "Use manual event parameters for the pile up fits. Needed for Cent estimaters other than FT0C"); + O2_DEFINE_CONFIGURABLE(cfgEvSelsMultPv, std::vector, {}, "Multiplicity cuts for PV first 5 parameters cutLOW last 5 cutHIGH"); + O2_DEFINE_CONFIGURABLE(cfgEvSelsMult, std::vector, {}, "Multiplicity cuts for T0C first 5 parameters cutLOW last 5 cutHIGH"); + O2_DEFINE_CONFIGURABLE(cfgEvSelsMaxOccupancy, int, 10000, "Maximum occupancy of selected events"); + O2_DEFINE_CONFIGURABLE(cfgEvSelsNoSameBunchPileupCut, bool, true, "kNoSameBunchPileupCut"); + O2_DEFINE_CONFIGURABLE(cfgEvSelsIsGoodZvtxFT0vsPV, bool, true, "kIsGoodZvtxFT0vsPV"); + O2_DEFINE_CONFIGURABLE(cfgEvSelsNoCollInTimeRangeStandard, bool, true, "kNoCollInTimeRangeStandard"); + O2_DEFINE_CONFIGURABLE(cfgEvSelsDoOccupancySel, bool, true, "Bool for event selection on detector occupancy"); + O2_DEFINE_CONFIGURABLE(cfgEvSelsTVXinTRD, bool, false, "Use kTVXinTRD (reject TRD triggered events)"); + O2_DEFINE_CONFIGURABLE(cfgEvSelsIsVertexITSTPC, bool, true, "Selects collisions with at least one ITS-TPC track"); + O2_DEFINE_CONFIGURABLE(cfgEvSelsIsGoodITSLayersAll, bool, true, "Cut time intervals with dead ITS staves"); // harmonics for v coefficients O2_DEFINE_CONFIGURABLE(cfgHarm, int, 1, "Flow harmonic n for ux and uy: (Cos(n*phi), Sin(n*phi))"); - O2_DEFINE_CONFIGURABLE(cfgHarmMixed, int, 2, "Flow harmonic n for ux and uy in mixed harmonics (MH): (Cos(n*phi), Sin(n*phi))"); + O2_DEFINE_CONFIGURABLE(cfgHarmMixed1, int, 2, "Flow harmonic n for ux and uy in mixed harmonics (MH): (Cos(n*phi), Sin(n*phi))"); + O2_DEFINE_CONFIGURABLE(cfgHarmMixed2, int, 3, "Flow harmonic n for ux and uy in mixed harmonics (MH): (Cos(n*phi), Sin(n*phi))"); // settings for CCDB data - O2_DEFINE_CONFIGURABLE(cfgLoadAverageQQ, bool, true, "Load average values for QQ (in centrality bins)"); - O2_DEFINE_CONFIGURABLE(cfgCCDBdir, std::string, "Users/c/ckoster/ZDC/LHC23_zzh_pass4_small/meanQQ", "ccdb dir for average QQ values in 1% centrality bins"); - O2_DEFINE_CONFIGURABLE(cfgLoadSPPlaneRes, bool, false, "Load ZDC spectator plane resolution"); - O2_DEFINE_CONFIGURABLE(cfgCCDBdir_SP, std::string, "Users/c/ckoster/ZDC/LHC23_zzh_pass4_small/SPPlaneRes", "ccdb dir for average event plane resolution in 1% centrality bins"); - // axis - - 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 trackFilterMC = nabs(aod::mcparticle::eta) < cfgEta && aod::mcparticle::pt > cfgPtmin&& aod::mcparticle::pt < cfgPtmax; + O2_DEFINE_CONFIGURABLE(cfgCCDBdir_QQ, std::string, "", "ccdb dir for average QQ values in 1% centrality bins"); + O2_DEFINE_CONFIGURABLE(cfgCCDBdir_SP, std::string, "", "ccdb dir for average event plane resolution in 1% centrality bins"); + O2_DEFINE_CONFIGURABLE(cfgCCDB_NUA, std::string, "", "ccdb dir for NUA corrections"); + O2_DEFINE_CONFIGURABLE(cfgCCDB_NUE, std::string, "", "ccdb dir for NUE corrections"); + + 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 trackFilterMC = nabs(aod::mcparticle::eta) < cfgTrackSelsEta && aod::mcparticle::pt > cfgTrackSelsPtmin&& aod::mcparticle::pt < cfgTrackSelsPtmax; using UsedCollisions = soa::Filtered>; using UsedTracks = soa::Filtered>; @@ -293,6 +294,7 @@ struct FlowSP { registry.add("incl/QA/hDCAz_pt", "", kTH2D, {axisPt, axisDCAz}); registry.add("incl/QA/hSharedClusters_pt", "", {HistType::kTH2D, {axisPt, axisShCl}}); registry.add("incl/QA/hCrossedRows_pt", "", {HistType::kTH2D, {axisPt, axisCl}}); + registry.add("incl/QA/hCrossedRows_vs_SharedClusters", "", {HistType::kTH2D, {axisCl, axisShCl}}); } } @@ -455,7 +457,7 @@ struct FlowSP { registry.get(HIST("hTrackCount"))->GetXaxis()->SetBinLabel(trackSel_ZeroCharge + 1, "Only charged"); registry.get(HIST("hTrackCount"))->GetXaxis()->SetBinLabel(trackSel_ParticleWeights + 1, "Apply weights"); - if (cfgUseAdditionalEventCut) { + if (cfgEvSelsUseAdditionalEventCut) { int twoSigma = 2; int threeSigma = 3; @@ -469,13 +471,13 @@ struct FlowSP { double fitParamLowPV4 = -0.00974862; double fitParamLowPV5 = 2.71433e-05; - if (cfgnSigmaMultCuts == twoSigma) { + if (cfgEvSelsnSigmaMultCuts == twoSigma) { fitParamLowPV1 = 2665.68; fitParamLowPV2 = -93.3784; fitParamLowPV3 = 1.27137; fitParamLowPV4 = -0.00818936; fitParamLowPV5 = 2.115e-05; - } else if (cfgnSigmaMultCuts == threeSigma) { + } else if (cfgEvSelsnSigmaMultCuts == threeSigma) { fitParamLowPV1 = 2389.99; fitParamLowPV2 = -83.8483; fitParamLowPV3 = 1.11062; @@ -494,13 +496,13 @@ struct FlowSP { double fitParamHighPV4 = -0.0145343; double fitParamHighPV5 = 4.80688e-05; - if (cfgnSigmaMultCuts == twoSigma) { + if (cfgEvSelsnSigmaMultCuts == twoSigma) { fitParamHighPV1 = 3787.93; fitParamHighPV2 = -135.184; fitParamHighPV3 = 2.07683; fitParamHighPV4 = -0.0165997; fitParamHighPV5 = 5.68725e-05; - } else if (cfgnSigmaMultCuts == threeSigma) { + } else if (cfgEvSelsnSigmaMultCuts == threeSigma) { fitParamHighPV1 = 4067.4; fitParamHighPV2 = -145.485; fitParamHighPV3 = 2.27273; @@ -517,13 +519,13 @@ struct FlowSP { double fitParamLow4 = -0.00235284; double fitParamLow5 = 3.01132e-06; - if (cfgnSigmaMultCuts == twoSigma) { + if (cfgEvSelsnSigmaMultCuts == twoSigma) { fitParamLow1 = 1307.92; fitParamLow2 = -39.9168; fitParamLow3 = 0.412675; fitParamLow4 = -0.00148081; fitParamLow5 = 1.10868e-07; - } else if (cfgnSigmaMultCuts == threeSigma) { + } else if (cfgEvSelsnSigmaMultCuts == threeSigma) { fitParamLow1 = 1048.48; fitParamLow2 = -31.4568; fitParamLow3 = 0.287794; @@ -540,13 +542,13 @@ struct FlowSP { double fitParamHigh4 = -0.00496563; double fitParamHigh5 = 1.34314e-05; - if (cfgnSigmaMultCuts == twoSigma) { + if (cfgEvSelsnSigmaMultCuts == twoSigma) { fitParamHigh1 = 2350.39; fitParamHigh2 = -74.6939; fitParamHigh3 = 0.953287; fitParamHigh4 = -0.006162; fitParamHigh5 = 1.80808e-05; - } else if (cfgnSigmaMultCuts == threeSigma) { + } else if (cfgEvSelsnSigmaMultCuts == threeSigma) { fitParamHigh1 = 2610.98; fitParamHigh2 = -83.3983; fitParamHigh3 = 1.0893; @@ -556,15 +558,15 @@ struct FlowSP { fMultCutHigh->SetParameters(fitParamHigh1, fitParamHigh2, fitParamHigh3, fitParamHigh4, fitParamHigh5); - if (cfgManualEventParameters) { - fMultPVCutLow->SetParameters((cfgMultPv.value)[0], (cfgMultPv.value)[1], (cfgMultPv.value)[2], (cfgMultPv.value)[3], (cfgMultPv.value)[4]); - fMultPVCutHigh->SetParameters((cfgMultPv.value)[5], (cfgMultPv.value)[6], (cfgMultPv.value)[7], (cfgMultPv.value)[8], (cfgMultPv.value)[9]); - fMultCutLow->SetParameters((cfgMult.value)[0], (cfgMult.value)[1], (cfgMult.value)[2], (cfgMult.value)[3], (cfgMult.value)[4]); - fMultCutHigh->SetParameters((cfgMult.value)[5], (cfgMult.value)[6], (cfgMult.value)[7], (cfgMult.value)[8], (cfgMult.value)[9]); + if (cfgEvSelsManualEventParameters) { + fMultPVCutLow->SetParameters((cfgEvSelsMultPv.value)[0], (cfgEvSelsMultPv.value)[1], (cfgEvSelsMultPv.value)[2], (cfgEvSelsMultPv.value)[3], (cfgEvSelsMultPv.value)[4]); + fMultPVCutHigh->SetParameters((cfgEvSelsMultPv.value)[5], (cfgEvSelsMultPv.value)[6], (cfgEvSelsMultPv.value)[7], (cfgEvSelsMultPv.value)[8], (cfgEvSelsMultPv.value)[9]); + fMultCutLow->SetParameters((cfgEvSelsMult.value)[0], (cfgEvSelsMult.value)[1], (cfgEvSelsMult.value)[2], (cfgEvSelsMult.value)[3], (cfgEvSelsMult.value)[4]); + fMultCutHigh->SetParameters((cfgEvSelsMult.value)[5], (cfgEvSelsMult.value)[6], (cfgEvSelsMult.value)[7], (cfgEvSelsMult.value)[8], (cfgEvSelsMult.value)[9]); } } - if (cfgUseAdditionalTrackCut) { + if (cfgTrackSelsUseAdditionalTrackCut) { fPhiCutLow = new TF1("fPhiCutLow", "0.06/x+pi/18.0-0.06", 0, 100); fPhiCutHigh = new TF1("fPhiCutHigh", "0.1/x+pi/18.0+0.06", 0, 100); } @@ -596,31 +598,31 @@ struct FlowSP { int nWeights = 3; - if (cfgNUA.value.empty() == false) { - TList* listCorrections = ccdb->getForTimeStamp(cfgNUA, timestamp); + if (cfgCCDB_NUA.value.empty() == false) { + TList* listCorrections = ccdb->getForTimeStamp(cfgCCDB_NUA, timestamp); cfg.mAcceptance.push_back(reinterpret_cast(listCorrections->FindObject("weights"))); cfg.mAcceptance.push_back(reinterpret_cast(listCorrections->FindObject("weights_positive"))); cfg.mAcceptance.push_back(reinterpret_cast(listCorrections->FindObject("weights_negative"))); int sizeAcc = cfg.mAcceptance.size(); if (sizeAcc < nWeights) - LOGF(warning, "Could not load acceptance weights from %s", cfgNUA.value.c_str()); + LOGF(warning, "Could not load acceptance weights from %s", cfgCCDB_NUA.value.c_str()); else - LOGF(info, "Loaded acceptance weights from %s", cfgNUA.value.c_str()); + LOGF(info, "Loaded acceptance weights from %s", cfgCCDB_NUA.value.c_str()); } else { - LOGF(info, "cfgNUA empty! No corrections loaded"); + LOGF(info, "cfgCCDB_NUA empty! No corrections loaded"); } - if (cfgNUE.value.empty() == false) { - TList* listCorrections = ccdb->getForTimeStamp(cfgNUE, timestamp); + if (cfgCCDB_NUE.value.empty() == false) { + TList* listCorrections = ccdb->getForTimeStamp(cfgCCDB_NUE, timestamp); cfg.mEfficiency.push_back(reinterpret_cast(listCorrections->FindObject("Efficiency"))); cfg.mEfficiency.push_back(reinterpret_cast(listCorrections->FindObject("Efficiency_pos"))); cfg.mEfficiency.push_back(reinterpret_cast(listCorrections->FindObject("Efficiency_neg"))); int sizeEff = cfg.mEfficiency.size(); if (sizeEff < nWeights) - LOGF(fatal, "Could not load efficiency histogram for trigger particles from %s", cfgNUE.value.c_str()); + LOGF(fatal, "Could not load efficiency histogram for trigger particles from %s", cfgCCDB_NUE.value.c_str()); else - LOGF(info, "Loaded efficiency histogram from %s", cfgNUE.value.c_str()); + LOGF(info, "Loaded efficiency histogram from %s", cfgCCDB_NUE.value.c_str()); } else { - LOGF(info, "cfgNUE empty! No corrections loaded"); + LOGF(info, "cfgCCDB_NUE empty! No corrections loaded"); } cfg.correctionsLoaded = true; } @@ -653,15 +655,15 @@ struct FlowSP { registry.fill(HIST("hEventCount"), evSel_sel8); // Occupancy - if (cfgDoOccupancySel) { + if (cfgEvSelsDoOccupancySel) { auto occupancy = collision.trackOccupancyInTimeRange(); - if (occupancy > cfgMaxOccupancy) { + if (occupancy > cfgEvSelsMaxOccupancy) { return 0; } registry.fill(HIST("hEventCount"), evSel_occupancy); } - if (cfgTVXinTRD) { + if (cfgEvSelsTVXinTRD) { if (collision.alias_bit(kTVXinTRD)) { // TRD triggered // "CMTVX-B-NOPF-TRD,minbias_TVX" @@ -670,7 +672,7 @@ struct FlowSP { registry.fill(HIST("hEventCount"), evSel_kTVXinTRD); } - if (cfgNoSameBunchPileupCut) { + if (cfgEvSelsNoSameBunchPileupCut) { if (!collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) { // rejects collisions which are associated with the same "found-by-T0" bunch crossing // https://indico.cern.ch/event/1396220/#1-event-selection-with-its-rof @@ -678,7 +680,7 @@ struct FlowSP { } registry.fill(HIST("hEventCount"), evSel_kNoSameBunchPileup); } - if (cfgIsGoodZvtxFT0vsPV) { + if (cfgEvSelsIsGoodZvtxFT0vsPV) { if (!collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) { // removes collisions with large differences between z of PV by tracks and z of PV from FT0 A-C time difference // use this cut at low multiplicities with caution @@ -686,7 +688,7 @@ struct FlowSP { } registry.fill(HIST("hEventCount"), evSel_kIsGoodZvtxFT0vsPV); } - if (cfgNoCollInTimeRangeStandard) { + if (cfgEvSelsNoCollInTimeRangeStandard) { if (!collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { // Rejection of the collisions which have other events nearby return 0; @@ -694,7 +696,7 @@ struct FlowSP { registry.fill(HIST("hEventCount"), evSel_kNoCollInTimeRangeStandard); } - if (cfgIsVertexITSTPC) { + if (cfgEvSelsIsVertexITSTPC) { if (!collision.selection_bit(o2::aod::evsel::kIsVertexITSTPC)) { // selects collisions with at least one ITS-TPC track, and thus rejects vertices built from ITS-only tracks return 0; @@ -702,7 +704,7 @@ struct FlowSP { registry.fill(HIST("hEventCount"), evSel_kIsVertexITSTPC); } - if (cfgUseAdditionalEventCut) { + if (cfgEvSelsUseAdditionalEventCut) { float vtxz = -999; if (collision.numContrib() > 1) { vtxz = collision.posZ(); @@ -715,7 +717,7 @@ struct FlowSP { auto multNTracksPV = collision.multNTracksPV(); - if (vtxz > cfgVtxZ || vtxz < -cfgVtxZ) + if (vtxz > cfgEvSelsVtxZ || vtxz < -cfgEvSelsVtxZ) return 0; if (multNTracksPV < fMultPVCutLow->Eval(collision.centFT0C())) return 0; @@ -733,7 +735,7 @@ struct FlowSP { return 0; registry.fill(HIST("hEventCount"), evSel_CentCuts); - if (cfgIsGoodITSLayersAll) { + if (cfgEvSelsIsGoodITSLayersAll) { if (!collision.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { // New event selection bits to cut time intervals with dead ITS staves // https://indico.cern.ch/event/1493023/ (09-01-2025) @@ -748,32 +750,35 @@ struct FlowSP { template bool trackSelected(TrackObject track, const int& field) { - if (std::fabs(track.eta()) > cfgEta) + if (std::fabs(track.eta()) > cfgTrackSelsEta) return false; registry.fill(HIST("hTrackCount"), trackSel_Eta); - if (track.pt() < cfgPtmin || track.pt() > cfgPtmax) + if (track.pt() < cfgTrackSelsPtmin || track.pt() > cfgTrackSelsPtmax) return false; registry.fill(HIST("hTrackCount"), trackSel_Pt); - if (track.dcaXY() > cfgDCAxy) + if (track.dcaXY() > cfgTrackSelsDCAxy) return false; registry.fill(HIST("hTrackCount"), trackSel_DCAxy); - if (track.dcaZ() > cfgDCAz) + if (track.dcaZ() > cfgTrackSelsDCAz) + return false; + + if (cfgTrackSelsDoDCApt && std::fabs(track.dcaZ()) > (cfgTrackSelsDCApt1 * cfgTrackSelsDCApt2) / (std::pow(track.pt(), 1.1))) return false; registry.fill(HIST("hTrackCount"), trackSel_DCAz); // registry.fill(HIST("hTrackCount"), trackSel_GlobalTracks); - if (track.tpcNClsFound() < cfgNcls) + if (track.tpcNClsFound() < cfgTrackSelsNcls) return false; registry.fill(HIST("hTrackCount"), trackSel_NCls); - if (track.tpcFractionSharedCls() > cfgFshcls) + if (track.tpcFractionSharedCls() > cfgTrackSelsFshcls) return false; registry.fill(HIST("hTrackCount"), trackSel_FshCls); @@ -790,7 +795,7 @@ struct FlowSP { if (cfgFillQAHistos) registry.fill(HIST("QA/before/pt_phi"), track.pt(), phimodn); - if (cfgUseAdditionalTrackCut) { + if (cfgTrackSelsUseAdditionalTrackCut) { if (phimodn < fPhiCutHigh->Eval(track.pt()) && phimodn > fPhiCutLow->Eval(track.pt())) return false; // reject track } @@ -843,7 +848,7 @@ struct FlowSP { } template - inline void fillHistograms(TrackObject track, float wacc, float weff, double ux, double uy, double uxMH, double uyMH, double qxA, double qyA, double qxC, double qyC, double corrQQx, double corrQQy, double corrQQ, double vnA, double vnC, double vnFull, double centrality) + inline void fillHistograms(TrackObject track, float wacc, float weff, double ux, double uy, double uxMH, double uyMH, double uxMH2, double uyMH2, double qxA, double qyA, double qxC, double qyC, double corrQQx, double corrQQy, double corrQQ, double vnA, double vnC, double vnFull, double centrality) { registry.fill(HIST(Charge[ct]) + HIST("vnA_eta"), track.eta(), (uy * qyA + ux * qxA) / std::sqrt(std::fabs(corrQQ)), wacc * weff); registry.fill(HIST(Charge[ct]) + HIST("vnC_eta"), track.eta(), (uy * qyC + ux * qxC) / std::sqrt(std::fabs(corrQQ)), wacc * weff); @@ -866,6 +871,23 @@ struct FlowSP { registry.fill(HIST(Charge[ct]) + HIST("vnAxCyUx_cent_MH"), centrality, (uxMH * qyA * qyC) / corrQQy, wacc * weff); registry.fill(HIST(Charge[ct]) + HIST("vnAxCyUy_cent_MH"), centrality, (uyMH * qxA * qyC) / corrQQx, wacc * weff); registry.fill(HIST(Charge[ct]) + HIST("vnAyCxUy_cent_MH"), centrality, (uyMH * qyA * qxC) / corrQQy, wacc * weff); + + // -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + registry.fill(HIST(Charge[ct]) + HIST("vnAxCxUx_eta_MH"), track.eta(), (uxMH2 * qxA * qxC) / corrQQx, wacc * weff); + registry.fill(HIST(Charge[ct]) + HIST("vnAxCyUx_eta_MH"), track.eta(), (uxMH2 * qyA * qyC) / corrQQy, wacc * weff); + registry.fill(HIST(Charge[ct]) + HIST("vnAxCyUy_eta_MH"), track.eta(), (uyMH2 * qxA * qyC) / corrQQx, wacc * weff); + registry.fill(HIST(Charge[ct]) + HIST("vnAyCxUy_eta_MH"), track.eta(), (uyMH2 * qyA * qxC) / corrQQy, wacc * weff); + + registry.fill(HIST(Charge[ct]) + HIST("vnAxCxUx_pt_MH"), track.pt(), (uxMH2 * qxA * qxC) / corrQQx, wacc * weff); + registry.fill(HIST(Charge[ct]) + HIST("vnAxCyUx_pt_MH"), track.pt(), (uxMH2 * qyA * qyC) / corrQQy, wacc * weff); + registry.fill(HIST(Charge[ct]) + HIST("vnAxCyUy_pt_MH"), track.pt(), (uyMH2 * qxA * qyC) / corrQQx, wacc * weff); + registry.fill(HIST(Charge[ct]) + HIST("vnAyCxUy_pt_MH"), track.pt(), (uyMH2 * qyA * qxC) / corrQQy, wacc * weff); + + registry.fill(HIST(Charge[ct]) + HIST("vnAxCxUx_cent_MH"), centrality, (uxMH2 * qxA * qxC) / corrQQx, wacc * weff); + registry.fill(HIST(Charge[ct]) + HIST("vnAxCyUx_cent_MH"), centrality, (uxMH2 * qyA * qyC) / corrQQy, wacc * weff); + registry.fill(HIST(Charge[ct]) + HIST("vnAxCyUy_cent_MH"), centrality, (uyMH2 * qxA * qyC) / corrQQx, wacc * weff); + registry.fill(HIST(Charge[ct]) + HIST("vnAyCxUy_cent_MH"), centrality, (uyMH2 * qyA * qxC) / corrQQy, wacc * weff); } if (cfgFillXandYterms) { @@ -937,6 +959,7 @@ struct FlowSP { registry.fill(HIST(Charge[ct]) + HIST("QA/hDCAz_pt"), track.pt(), track.dcaZ()); registry.fill(HIST(Charge[ct]) + HIST("QA/hSharedClusters_pt"), track.pt(), track.tpcFractionSharedCls()); registry.fill(HIST(Charge[ct]) + HIST("QA/hCrossedRows_pt"), track.pt(), track.tpcNClsFound()); + registry.fill(HIST(Charge[ct]) + HIST("QA/hCrossedRows_vs_SharedClusters"), track.tpcNClsFound(), track.tpcFractionSharedCls()); } template @@ -1047,9 +1070,9 @@ struct FlowSP { // Load correlations and SP resolution needed for Scalar Product and event plane methods. // Only load once! // If not loaded set to 1 - if (cfgLoadAverageQQ) { + if (cfgCCDBdir_QQ.value.empty() == false) { if (!cfg.clQQ) { - TList* hcorrList = ccdb->getForTimeStamp(cfgCCDBdir.value, bc.timestamp()); + TList* hcorrList = ccdb->getForTimeStamp(cfgCCDBdir_QQ.value, bc.timestamp()); cfg.hcorrQQ = reinterpret_cast(hcorrList->FindObject("qAqCXY")); cfg.hcorrQQx = reinterpret_cast(hcorrList->FindObject("qAqCX")); cfg.hcorrQQy = reinterpret_cast(hcorrList->FindObject("qAqCY")); @@ -1061,7 +1084,7 @@ struct FlowSP { } double evPlaneRes = 1.; - if (cfgLoadSPPlaneRes) { + if (cfgCCDBdir_SP.value.empty() == false) { if (!cfg.clEvPlaneRes) { cfg.hEvPlaneRes = ccdb->getForTimeStamp(cfgCCDBdir_SP.value, bc.timestamp()); cfg.clEvPlaneRes = true; @@ -1124,25 +1147,28 @@ struct FlowSP { auto ux = std::cos(cfgHarm * phi); auto uy = std::sin(cfgHarm * phi); - auto uxMH = std::cos(cfgHarmMixed * phi); - auto uyMH = std::sin(cfgHarmMixed * phi); + auto uxMH = std::cos(cfgHarmMixed1 * phi); + auto uyMH = std::sin(cfgHarmMixed1 * phi); + + auto uxMH2 = std::cos(cfgHarmMixed2 * phi); + auto uyMH2 = std::sin(cfgHarmMixed2 * phi); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - double vnA = std::cos(cfgHarm * (phi - psiA)) / evPlaneRes; double vnC = std::cos(cfgHarm * (phi - psiC)) / evPlaneRes; double vnFull = std::cos(cfgHarm * (phi - psiFull)) / evPlaneRes; - fillHistograms(track, wacc, weff, ux, uy, uxMH, uyMH, qxA, qyA, qxC, qyC, corrQQx, corrQQy, corrQQ, vnA, vnC, vnFull, centrality); + fillHistograms(track, wacc, weff, ux, uy, uxMH, uyMH, uxMH2, uyMH2, qxA, qyA, qxC, qyC, corrQQx, corrQQy, corrQQ, vnA, vnC, vnFull, centrality); if (cfgFillQAHistos) fillTrackQA(track, vtxz, wacc, weff); if (cfgFillChargeDependence) { if (pos) { - fillHistograms(track, waccP, weffP, ux, uy, uxMH, uyMH, qxA, qyA, qxC, qyC, corrQQx, corrQQy, corrQQ, vnA, vnC, vnFull, centrality); + fillHistograms(track, wacc, weff, ux, uy, uxMH, uyMH, uxMH2, uyMH2, qxA, qyA, qxC, qyC, corrQQx, corrQQy, corrQQ, vnA, vnC, vnFull, centrality); fillTrackQA(track, vtxz, waccP, weffP); } else { - fillHistograms(track, waccN, weffN, ux, uy, uxMH, uyMH, qxA, qyA, qxC, qyC, corrQQx, corrQQy, corrQQ, vnA, vnC, vnFull, centrality); + fillHistograms(track, wacc, weff, ux, uy, uxMH, uyMH, uxMH2, uyMH2, qxA, qyA, qxC, qyC, corrQQx, corrQQy, corrQQ, vnA, vnC, vnFull, centrality); fillTrackQA(track, vtxz, waccN, weffN); } } @@ -1213,7 +1239,7 @@ struct FlowSP { } PROCESS_SWITCH(FlowSP, processMCReco, "Process analysis for MC reconstructed events", false); - // Filter mcCollFilter = nabs(aod::mccollision::posZ) < cfgVtxZ; + // Filter mcCollFilter = nabs(aod::mccollision::posZ) < cfgEvSelsVtxZ; void processMCGen(aod::McCollisions const& mcCollisions, CCs const& collisions, TCs const& tracks, FilteredTCs const& filteredTracks, MCs const& McParts) { // LOGF(info, "Size of mccollisions: %i", mcCollisions.size()); @@ -1291,7 +1317,7 @@ struct FlowSP { registry.fill(HIST("trackMCGen/before/neg/phi_eta_vtxZ_gen"), particle.phi(), particle.eta(), vtxz); } - if (particle.eta() < -cfgEta || particle.eta() > cfgEta || particle.pt() < cfgPtmin || particle.pt() > cfgPtmax) + if (particle.eta() < -cfgTrackSelsEta || particle.eta() > cfgTrackSelsEta || particle.pt() < cfgTrackSelsPtmin || particle.pt() > cfgTrackSelsPtmax) continue; fillMCPtHistos(particle, pdgCode); diff --git a/PWGCF/Flow/Tasks/resonancesGfwFlow.cxx b/PWGCF/Flow/Tasks/resonancesGfwFlow.cxx index 6bde6c05c99..8f6db97fde8 100644 --- a/PWGCF/Flow/Tasks/resonancesGfwFlow.cxx +++ b/PWGCF/Flow/Tasks/resonancesGfwFlow.cxx @@ -38,6 +38,7 @@ #include "Common/DataModel/Multiplicity.h" #include "Common/Core/TrackSelection.h" #include "Common/Core/trackUtilities.h" +#include "Common/Core/RecoDecay.h" #include "CommonConstants/PhysicsConstants.h" #include "PWGLF/DataModel/EPCalibrationTables.h" @@ -135,10 +136,19 @@ struct ResonancesGfwFlow { O2_DEFINE_CONFIGURABLE(cfgUseWeightPhiEtaPt, bool, false, "Use Phi, Eta, Pt dependent NUA weights") O2_DEFINE_CONFIGURABLE(cfgNbootstrap, int, 10, "Number of subsamples") O2_DEFINE_CONFIGURABLE(cfgUseBootStrap, bool, true, "Use bootstrap for error estimation") - O2_DEFINE_CONFIGURABLE(cfgTrackDensityCorrUse, bool, false, "Use track density efficiency correction") + O2_DEFINE_CONFIGURABLE(cfgTrackDensityCorrUse, bool, true, "Use track density efficiency correction") + O2_DEFINE_CONFIGURABLE(cfgUsePhi, bool, true, "Analyze Phi") O2_DEFINE_CONFIGURABLE(cfgUseK0, bool, true, "Analyze K0") O2_DEFINE_CONFIGURABLE(cfgUseLambda, bool, true, "Analyze Lambda") - O2_DEFINE_CONFIGURABLE(cfgUsePhi, bool, true, "Analyze Phi") + + enum OutputSpecies { + Ref = 0, + K0 = 1, + Lambda = 2, + AnLambda = 3, + Phi = 4, + kCount_OutputSpecies + }; struct : ConfigurableGroup { Configurable> cfgCosPAs{"cfgCosPAs", std::vector{0.97f, 0.995f, 0.04f}, "Minimum Pointing angle for resonances [K0, Lambda, Phi]"}; @@ -146,7 +156,7 @@ struct ResonancesGfwFlow { Configurable> cfgMassMin{"cfgMassMin", std::vector{0.44f, 1.1f, 0.99f}, "Minimum mass for resonances [K0, Lambda, Phi]"}; Configurable> cfgMassMax{"cfgMassMax", std::vector{0.56f, 1.16f, 1.06f}, "Maximum mass for resonances [K0, Lambda, Phi]"}; Configurable> cfgNMassBins{"cfgNMassBins", std::vector{70, 70, 70}, "Invariant mass bins for resonances [K0, Lambda, Phi]"}; - Configurable> cfgMccCut{"cfgMccCut", std::vector{0.005f, 0.01f}, "MCC cut for resonances [K0, Lambda]"}; + Configurable> cfgMccCut{"cfgMccCut", std::vector{0.005f, 0.01f, 0.0f}, "MCC cut for resonances [K0, Lambda, Phi]"}; Configurable> cfgPosTrackPt{"cfgPosTrackPt", std::vector{0.15f, 0.15f, 0.15f}, "Pt cut for positive track of resonances [K0, Lambda, Phi]"}; Configurable> cfgNegTrackPt{"cfgNegTrackPt", std::vector{0.15f, 0.15f, 0.15f}, "Pt cut for negative track of resonances [K0, Lambda, Phi]"}; } resoCuts; @@ -200,15 +210,6 @@ struct ResonancesGfwFlow { TAxis* fLambdaMassAxis; TRandom3* fRndm = new TRandom3(0); - enum OutputSpecies { - Ref = 0, - K0 = 1, - Lambda = 2, - AnLambda = 3, - Phi = 4, - kCount_OutputSpecies - }; - std::vector mAcceptance; bool correctionsLoaded = false; @@ -243,13 +244,40 @@ struct ResonancesGfwFlow { histos.add("hPhiPhi", "", {HistType::kTH1D, {axisPhi}}); histos.add("hPhiEta", "", {HistType::kTH1D, {axisEta}}); histos.add("hPhiMass_sparse", "", {HistType::kTHnSparseD, {{axisPhiMass, axisPt, axisMultiplicity}}}); + histos.add("hPhimassSparse_RD", "", {HistType::kTHnSparseD, {{axisPhiMass, axisPt, axisMultiplicity}}}); histos.add("Phid22Fpt", "", {HistType::kTProfile3D, {axisPt, axisPhiMass, axisMultiplicity}}); histos.add("Phid24Fpt", "", {HistType::kTProfile3D, {axisPt, axisPhiMass, axisMultiplicity}}); histos.add("Phid22Bpt", "", {HistType::kTProfile3D, {axisPt, axisPhiMass, axisMultiplicity}}); histos.add("Phid24Bpt", "", {HistType::kTProfile3D, {axisPt, axisPhiMass, axisMultiplicity}}); } + if (cfgUseK0) { + histos.add("PlusTPC_K0", "", {HistType::kTH2D, {{axisPt, axisTPCsignal}}}); + histos.add("MinusTPC_K0", "", {HistType::kTH2D, {{axisPt, axisTPCsignal}}}); + histos.add("PlusTOF_K0", "", {HistType::kTH2D, {{axisPt, axisTOFsignal}}}); + histos.add("MinusTOF_K0", "", {HistType::kTH2D, {{axisPt, axisTOFsignal}}}); + histos.add("hK0Phi", "", {HistType::kTH1D, {axisPhi}}); + histos.add("hK0Eta", "", {HistType::kTH1D, {axisEta}}); + histos.add("hK0Mass_sparse", "", {HistType::kTHnSparseF, {{axisK0Mass, axisPt, axisMultiplicity}}}); + histos.add("hK0s", "", {HistType::kTH1D, {singleCount}}); + + histos.add("K0d22Fpt", "", {HistType::kTProfile3D, {axisPt, axisK0Mass, axisMultiplicity}}); + histos.add("K0d24Fpt", "", {HistType::kTProfile3D, {axisPt, axisK0Mass, axisMultiplicity}}); + histos.add("K0d22Bpt", "", {HistType::kTProfile3D, {axisPt, axisK0Mass, axisMultiplicity}}); + histos.add("K0d24Bpt", "", {HistType::kTProfile3D, {axisPt, axisK0Mass, axisMultiplicity}}); + histos.add("hK0Count", "Number of K0;; Count", {HistType::kTH1D, {{10, 0, 10}}}); + histos.get(HIST("hK0Count"))->GetXaxis()->SetBinLabel(1, "K0 candidates"); + histos.get(HIST("hK0Count"))->GetXaxis()->SetBinLabel(2, "Daughter pt"); + histos.get(HIST("hK0Count"))->GetXaxis()->SetBinLabel(3, "Mass cut"); + histos.get(HIST("hK0Count"))->GetXaxis()->SetBinLabel(4, "Rapidity cut"); + histos.get(HIST("hK0Count"))->GetXaxis()->SetBinLabel(5, "DCA to PV"); + histos.get(HIST("hK0Count"))->GetXaxis()->SetBinLabel(6, "DCA between daughters"); + histos.get(HIST("hK0Count"))->GetXaxis()->SetBinLabel(7, "V0radius"); + histos.get(HIST("hK0Count"))->GetXaxis()->SetBinLabel(8, "CosPA"); + histos.get(HIST("hK0Count"))->GetXaxis()->SetBinLabel(9, "Proper lifetime"); + histos.get(HIST("hK0Count"))->GetXaxis()->SetBinLabel(10, "Daughter track selection"); + } if (cfgUseLambda) { histos.add("PlusTPC_L", "", {HistType::kTH2D, {{axisPt, axisTPCsignal}}}); histos.add("MinusTPC_L", "", {HistType::kTH2D, {{axisPt, axisTPCsignal}}}); @@ -277,7 +305,7 @@ struct ResonancesGfwFlow { histos.add("AnLambdad22Bpt", "", {HistType::kTProfile3D, {axisPt, axisLambdaMass, axisMultiplicity}}); histos.add("AnLambdad24Bpt", "", {HistType::kTProfile3D, {axisPt, axisLambdaMass, axisMultiplicity}}); - histos.add("hLambdaCount", "Number of Lambda;; Count", {HistType::kTH1D, {{11, 0, 11}}}); + histos.add("hLambdaCount", "Number of Lambda;; Count", {HistType::kTH1D, {{10, 0, 10}}}); histos.get(HIST("hLambdaCount"))->GetXaxis()->SetBinLabel(1, "Lambda candidates"); histos.get(HIST("hLambdaCount"))->GetXaxis()->SetBinLabel(2, "Daughter pt"); histos.get(HIST("hLambdaCount"))->GetXaxis()->SetBinLabel(3, "Mass cut"); @@ -288,36 +316,6 @@ struct ResonancesGfwFlow { histos.get(HIST("hLambdaCount"))->GetXaxis()->SetBinLabel(8, "CosPA"); histos.get(HIST("hLambdaCount"))->GetXaxis()->SetBinLabel(9, "Proper lifetime"); histos.get(HIST("hLambdaCount"))->GetXaxis()->SetBinLabel(10, "Daughter track selection"); - histos.get(HIST("hLambdaCount"))->GetXaxis()->SetBinLabel(11, "Mass cross check"); - } - - if (cfgUseK0) { - histos.add("PlusTPC_K0", "", {HistType::kTH2D, {{axisPt, axisTPCsignal}}}); - histos.add("MinusTPC_K0", "", {HistType::kTH2D, {{axisPt, axisTPCsignal}}}); - histos.add("PlusTOF_K0", "", {HistType::kTH2D, {{axisPt, axisTOFsignal}}}); - histos.add("MinusTOF_K0", "", {HistType::kTH2D, {{axisPt, axisTOFsignal}}}); - histos.add("hK0Phi", "", {HistType::kTH1D, {axisPhi}}); - histos.add("hK0Eta", "", {HistType::kTH1D, {axisEta}}); - histos.add("hK0Mass_sparse", "", {HistType::kTHnSparseF, {{axisK0Mass, axisPt, axisMultiplicity}}}); - histos.add("hK0s", "", {HistType::kTH1D, {singleCount}}); - - histos.add("K0d22Fpt", "", {HistType::kTProfile3D, {axisPt, axisK0Mass, axisMultiplicity}}); - histos.add("K0d24Fpt", "", {HistType::kTProfile3D, {axisPt, axisK0Mass, axisMultiplicity}}); - histos.add("K0d22Bpt", "", {HistType::kTProfile3D, {axisPt, axisK0Mass, axisMultiplicity}}); - histos.add("K0d24Bpt", "", {HistType::kTProfile3D, {axisPt, axisK0Mass, axisMultiplicity}}); - - histos.add("hK0Count", "Number of K0;; Count", {HistType::kTH1D, {{11, 0, 11}}}); - histos.get(HIST("hK0Count"))->GetXaxis()->SetBinLabel(1, "K0 candidates"); - histos.get(HIST("hK0Count"))->GetXaxis()->SetBinLabel(2, "Daughter pt"); - histos.get(HIST("hK0Count"))->GetXaxis()->SetBinLabel(3, "Mass cut"); - histos.get(HIST("hK0Count"))->GetXaxis()->SetBinLabel(4, "Rapidity cut"); - histos.get(HIST("hK0Count"))->GetXaxis()->SetBinLabel(5, "DCA to PV"); - histos.get(HIST("hK0Count"))->GetXaxis()->SetBinLabel(6, "DCA between daughters"); - histos.get(HIST("hK0Count"))->GetXaxis()->SetBinLabel(7, "V0radius"); - histos.get(HIST("hK0Count"))->GetXaxis()->SetBinLabel(8, "CosPA"); - histos.get(HIST("hK0Count"))->GetXaxis()->SetBinLabel(9, "Proper lifetime"); - histos.get(HIST("hK0Count"))->GetXaxis()->SetBinLabel(10, "Daughter track selection"); - histos.get(HIST("hK0Count"))->GetXaxis()->SetBinLabel(11, "Mass cross check"); } histos.add("hEventCount", "Number of Event;; Count", {HistType::kTH1D, {{8, 0, 8}}}); @@ -355,10 +353,10 @@ struct ResonancesGfwFlow { refC22Boot[i] = histos.add(Form("BootStrap/Refc22_bootstrap_%d", i), "", {HistType::kTProfile, {axisMultiplicity}}); refC24Boot[i] = histos.add(Form("BootStrap/Refc24_bootstrap_%d", i), "", {HistType::kTProfile, {axisMultiplicity}}); if (cfgUsePhi) { - phiD22FPtBoot[i] = histos.add(Form("BootStrap/Phid22Fpt_bootstrap_%d", i), "", {HistType::kTProfile3D, {axisPt, axisPhiMass, axisMultiplicity}}); - phiD24FPtBoot[i] = histos.add(Form("BootStrap/Phid24Fpt_bootstrap_%d", i), "", {HistType::kTProfile3D, {axisPt, axisPhiMass, axisMultiplicity}}); - phiD22BPtBoot[i] = histos.add(Form("BootStrap/Phid22Bpt_bootstrap_%d", i), "", {HistType::kTProfile3D, {axisPt, axisPhiMass, axisMultiplicity}}); - phiD24BPtBoot[i] = histos.add(Form("BootStrap/Phid24Bpt_bootstrap_%d", i), "", {HistType::kTProfile3D, {axisPt, axisPhiMass, axisMultiplicity}}); + phiD22FPtBoot[i] = histos.add(Form("BootStrap/phid22Fpt_bootstrap_%d", i), "", {HistType::kTProfile3D, {axisPt, axisPhiMass, axisMultiplicity}}); + phiD24FPtBoot[i] = histos.add(Form("BootStrap/phid24Fpt_bootstrap_%d", i), "", {HistType::kTProfile3D, {axisPt, axisPhiMass, axisMultiplicity}}); + phiD22BPtBoot[i] = histos.add(Form("BootStrap/phid22Bpt_bootstrap_%d", i), "", {HistType::kTProfile3D, {axisPt, axisPhiMass, axisMultiplicity}}); + phiD24BPtBoot[i] = histos.add(Form("BootStrap/phid24Bpt_bootstrap_%d", i), "", {HistType::kTProfile3D, {axisPt, axisPhiMass, axisMultiplicity}}); } if (cfgUseK0) { k0D22FPtBoot[i] = histos.add(Form("BootStrap/k0d22Fpt_bootstrap_%d", i), "", {HistType::kTProfile3D, {axisPt, axisK0Mass, axisMultiplicity}}); @@ -385,7 +383,7 @@ struct ResonancesGfwFlow { double* ptBins = &(axis.binEdges)[0]; fPtAxis = new TAxis(nPtBins, ptBins); - fPhiMassAxis = new TAxis(vMassBins[Phi - 2], 0.99, 1.06); + fPhiMassAxis = new TAxis(vMassBins[Phi - 2], vMassMin[Phi - 2], vMassMax[Phi - 2]); fK0MassAxis = new TAxis(vMassBins[K0 - 1], vMassMin[K0 - 1], vMassMax[K0 - 1]); fLambdaMassAxis = new TAxis(vMassBins[Lambda - 1], vMassMin[Lambda - 1], vMassMax[Lambda - 1]); @@ -433,29 +431,29 @@ struct ResonancesGfwFlow { corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN08 {2 2} refP08 {-2 -2}", "Ref08Gap24", kFALSE)); //--------- pt differential pois - if (cfgUsePhi) { - corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiNphi refN08 | olNphi {2} refP08 {-2}", "PhiF08Gap22", kTRUE)); - corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiNphi refN08 | olNphi {2 2} refP08 {-2 -2}", "PhiF08Gap24", kTRUE)); - corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiPphi refP08 | olPphi {2} refN08 {-2}", "PhiB08Gap22", kTRUE)); - corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiPphi refP08 | olPphi {2 2} refN08 {-2 -2}", "PhiB08Gap24", kTRUE)); - } - if (cfgUseK0) { - corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiNk0 refN08 | olNk0 {2} refP08 {-2}", "KsF08Gap22", kTRUE)); - corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiNk0 refN08 | olNk0 {2 2} refP08 {-2 -2}", "KsF08Gap24", kTRUE)); - corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiPk0 refP08 | olPk0 {2} refN08 {-2}", "KsB08Gap22", kTRUE)); - corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiPk0 refP08 | olPk0 {2 2} refN08 {-2 -2}", "KsB08Gap24", kTRUE)); - } - if (cfgUseLambda) { - corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiNlam refN08 | olNlam {2} refP08 {-2}", "LamF08Gap22", kTRUE)); - corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiNlam refN08 | olNlam {2 2} refP08 {-2 -2}", "LamF08Gap24", kTRUE)); - corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiPlam refP08 | olPlam {2} refN08 {-2}", "LamB08Gap22", kTRUE)); - corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiPlam refP08 | olPlam {2 2} refN08 {-2 -2}", "LamB08Gap24", kTRUE)); - - corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiNantilam refN08 | olNantilam {2} refP08 {-2}", "AnLamF08Gap22", kTRUE)); - corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiNantilam refN08 | olNantilam {2 2} refP08 {-2 -2}", "AnLamF08Gap24", kTRUE)); - corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiPantilam refP08 | olPantilam {2} refN08 {-2}", "AnLamB08Gap22", kTRUE)); - corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiPantilam refP08 | olPantilam {2 2} refN08 {-2 -2}", "AnLamB08Gap24", kTRUE)); - } + // Phi + corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiNphi refN08 | olNphi {2} refP08 {-2}", "PhiF08Gap22", kTRUE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiNphi refN08 | olNphi {2 2} refP08 {-2 -2}", "PhiF08Gap24", kTRUE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiPphi refP08 | olPphi {2} refN08 {-2}", "PhiB08Gap22", kTRUE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiPphi refP08 | olPphi {2 2} refN08 {-2 -2}", "PhiB08Gap24", kTRUE)); + + // K0 + corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiNk0 refN08 | olNk0 {2} refP08 {-2}", "KsF08Gap22", kTRUE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiNk0 refN08 | olNk0 {2 2} refP08 {-2 -2}", "KsF08Gap24", kTRUE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiPk0 refP08 | olPk0 {2} refN08 {-2}", "KsB08Gap22", kTRUE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiPk0 refP08 | olPk0 {2 2} refN08 {-2 -2}", "KsB08Gap24", kTRUE)); + + // Lambda + corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiNlam refN08 | olNlam {2} refP08 {-2}", "LamF08Gap22", kTRUE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiNlam refN08 | olNlam {2 2} refP08 {-2 -2}", "LamF08Gap24", kTRUE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiPlam refP08 | olPlam {2} refN08 {-2}", "LamB08Gap22", kTRUE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiPlam refP08 | olPlam {2 2} refN08 {-2 -2}", "LamB08Gap24", kTRUE)); + + // Antilambda + corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiNantilam refN08 | olNantilam {2} refP08 {-2}", "AnLamF08Gap22", kTRUE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiNantilam refN08 | olNantilam {2 2} refP08 {-2 -2}", "AnLamF08Gap24", kTRUE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiPantilam refP08 | olPantilam {2} refN08 {-2}", "AnLamB08Gap22", kTRUE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiPantilam refP08 | olPantilam {2 2} refN08 {-2 -2}", "AnLamB08Gap24", kTRUE)); fGFW->CreateRegions(); @@ -480,7 +478,7 @@ struct ResonancesGfwFlow { } template - void fillResoProfile(const GFW::CorrConfig& corrconf, const ConstStr& tarName, const double& cent, TAxis* partaxis) + void fillResoProfile(const GFW::CorrConfig& corrconf, const ConstStr& tarName, const double cent, TAxis* partaxis) { double dnx, val; if (!corrconf.pTDif) { @@ -684,6 +682,8 @@ struct ResonancesGfwFlow { double wacc = 1; double cent = collision.centFT0C(); double vtxz = collision.posZ(); + double phi = mom.Phi(); + phi = RecoDecay::constrainAngle(phi, 0.0, 1); // constrain azimuthal angle to [0,2pi] if ((cfgUseWeightPhiEtaVtxz && cfgUseWeightPhiPtCent) || (cfgUseWeightPhiEtaPt && cfgUseWeightPhiPtCent) || (cfgUseWeightPhiEtaVtxz && cfgUseWeightPhiEtaPt)) { LOGF(fatal, "Only one of the three weight options can be used at a time"); @@ -694,11 +694,11 @@ struct ResonancesGfwFlow { return 1; } if (cfgUseWeightPhiEtaVtxz) - wacc = mAcceptance[pid_index_reso]->getNUA(mom.Phi(), mom.Eta(), vtxz); + wacc = mAcceptance[pid_index_reso]->getNUA(phi, mom.Eta(), vtxz); if (cfgUseWeightPhiPtCent) - wacc = mAcceptance[pid_index_reso]->getNUA(mom.Phi(), mom.Pt(), cent); + wacc = mAcceptance[pid_index_reso]->getNUA(phi, mom.Pt(), cent); if (cfgUseWeightPhiEtaPt) - wacc = mAcceptance[pid_index_reso]->getNUA(mom.Phi(), mom.Eta(), mom.Pt()); + wacc = mAcceptance[pid_index_reso]->getNUA(phi, mom.Eta(), mom.Pt()); } return wacc; } @@ -761,34 +761,45 @@ struct ResonancesGfwFlow { histos.fill(HIST("KaminusTPC"), partminus.pt(), partminus.tpcNSigmaKa()); histos.fill(HIST("KaminusTOF"), partminus.pt(), partminus.tofNSigmaKa()); + std::array, 2> ptarr = {{{partplus.px(), partplus.py(), partplus.pz()}, {partminus.px(), partminus.py(), partminus.pz()}}}; + std::array massarr = {plusmass, plusmass}; + + // Calculation using RecoDecay + double invMassRD = RecoDecay::m2(ptarr, massarr); + double ptRD = std::sqrt(RecoDecay::sumOfSquares(partplus.pt(), partminus.pt())); + + // Calculation using ROOT vectors plusdaug = ROOT::Math::PxPyPzMVector(partplus.px(), partplus.py(), partplus.pz(), plusmass); minusdaug = ROOT::Math::PxPyPzMVector(partminus.px(), partminus.py(), partminus.pz(), plusmass); mom = plusdaug + minusdaug; double pt = mom.Pt(); double invMass = mom.M(); + double phi = mom.Phi(); bool withinPtPOI = (cfgCutPtPOIMin < pt) && (pt < cfgCutPtPOIMax); // within POI pT range bool withinPtRef = (cfgCutPtMin < pt) && (pt < cfgCutPtMax); + phi = RecoDecay::constrainAngle(phi, 0.0, 1); // constrain azimuthal angle to [0,2pi] + if (std::abs(mom.Rapidity()) < cfgRapidityCut) { histos.fill(hist, invMass, pt, collision.centFT0C()); - histos.fill(HIST("hPhiPhi"), mom.Phi()); + histos.fill(HIST("hPhiPhi"), phi); histos.fill(HIST("hPhiEta"), mom.Eta()); + histos.fill(HIST("hPhimassSparse_RD"), invMassRD, ptRD, collision.centFT0C()); // fill RecoDecay mass and pt // Fill Phi weights if (cfgOutputNUAWeights && withinPtPOI) { - histos.fill(HIST("NUA/hPhiEtaVtxz_phi"), mom.Phi(), mom.Eta(), collision.posZ()); - histos.fill(HIST("NUA/hPhiPtCent_phi"), mom.Phi(), pt, collision.centFT0C()); - histos.fill(HIST("NUA/hPhiEtaPt_phi"), mom.Phi(), mom.Eta(), pt); + histos.fill(HIST("NUA/hPhiEtaVtxz_phi"), phi, mom.Eta(), collision.posZ()); + histos.fill(HIST("NUA/hPhiPtCent_phi"), phi, pt, collision.centFT0C()); + histos.fill(HIST("NUA/hPhiEtaPt_phi"), phi, mom.Eta(), pt); } - double weff = 1; double waccPOI = getAcceptancePhi(mom, collision, Phi); if (withinPtPOI) - fGFW->Fill(mom.Eta(), ((fPtAxis->FindBin(pt) - 1) * fPhiMassAxis->GetNbins()) + (fPhiMassAxis->FindBin(invMass) - 1), mom.Phi(), weff * waccPOI, 2); + fGFW->Fill(mom.Eta(), ((fPtAxis->FindBin(pt) - 1) * fPhiMassAxis->GetNbins()) + (fPhiMassAxis->FindBin(invMass) - 1), phi, weff * waccPOI, 2); if (withinPtPOI && withinPtRef) - fGFW->Fill(mom.Eta(), ((fPtAxis->FindBin(pt) - 1) * fPhiMassAxis->GetNbins()) + (fPhiMassAxis->FindBin(invMass) - 1), mom.Phi(), weff * waccPOI, 32); + fGFW->Fill(mom.Eta(), ((fPtAxis->FindBin(pt) - 1) * fPhiMassAxis->GetNbins()) + (fPhiMassAxis->FindBin(invMass) - 1), phi, weff * waccPOI, 32); } } return; @@ -875,10 +886,6 @@ struct ResonancesGfwFlow { return false; } histos.fill(HIST("hLambdaCount"), 9.5); - // Mass cross check - if (cfgUseMCCLambda && std::abs(massK0Short - 0.497614) < vMccCut[Lambda - 1]) - return false; - histos.fill(HIST("hLambdaCount"), 10.5); bool withinPtPOI = (cfgCutPtPOIMin < candidate.pt()) && (candidate.pt() < cfgCutPtPOIMax); // within POI pT range bool withinPtRef = (cfgCutPtMin < candidate.pt()) && (candidate.pt() < cfgCutPtMax); @@ -965,12 +972,6 @@ struct ResonancesGfwFlow { if (!selectionV0Daughter(postrack, 0) || !selectionV0Daughter(negtrack, 0)) return false; histos.fill(HIST("hK0Count"), 9.5); - // Mass cross check - if (cfgUseMCCK0 && std::abs(massLambda - 1.11568) < vMccCut[K0 - 1]) - return false; - if (cfgUseMCCK0 && std::abs(massLambda - 1.11568) < vMccCut[K0 - 1]) - return false; - histos.fill(HIST("hK0Count"), 10.5); bool withinPtPOI = (cfgCutPtPOIMin < candidate.pt()) && (candidate.pt() < cfgCutPtPOIMax); // within POI pT range bool withinPtRef = (cfgCutPtMin < candidate.pt()) && (candidate.pt() < cfgCutPtMax); @@ -1087,6 +1088,8 @@ struct ResonancesGfwFlow { double pt = track.pt(); bool withinPtRef = (cfgCutPtMin < pt) && (pt < cfgCutPtMax); + weff = 1; // Initializing weff for each track + if (withinPtRef) if (cfgOutputNUAWeights) fillWeights(track, collision, Ref); @@ -1117,19 +1120,18 @@ struct ResonancesGfwFlow { } for (auto const& v0s : V0s) { - if (cfgUseLambda) { - if (selectionLambda(collision, v0s) == true) - histos.fill(HIST("hLambdas"), 1); - } if (cfgUseK0) { if (selectionK0(collision, v0s) == true) histos.fill(HIST("hK0s"), 1); } + if (cfgUseLambda) { + if (selectionLambda(collision, v0s) == true) + histos.fill(HIST("hLambdas"), 1); + } } // End of v0 loop fillResoProfile(corrconfigs.at(0), HIST("Refc22"), cent, fPhiMassAxis); fillResoProfile(corrconfigs.at(1), HIST("Refc24"), cent, fPhiMassAxis); - if (cfgUsePhi) { fillResoProfile(corrconfigs.at(2), HIST("Phid22Fpt"), cent, fPhiMassAxis); fillResoProfile(corrconfigs.at(3), HIST("Phid24Fpt"), cent, fPhiMassAxis); @@ -1185,7 +1187,6 @@ struct ResonancesGfwFlow { fillProfileBoot3D(corrconfigs.at(16), anLambdaD22BPtBoot[bootId], cent, fLambdaMassAxis); fillProfileBoot3D(corrconfigs.at(17), anLambdaD24BPtBoot[bootId], cent, fLambdaMassAxis); } - } // end of bootstrap condition } // end of process }; diff --git a/PWGCF/GenericFramework/Core/FlowPtContainer.cxx b/PWGCF/GenericFramework/Core/FlowPtContainer.cxx index d12ee4d3d4d..33f2e303711 100644 --- a/PWGCF/GenericFramework/Core/FlowPtContainer.cxx +++ b/PWGCF/GenericFramework/Core/FlowPtContainer.cxx @@ -140,6 +140,17 @@ void FlowPtContainer::initialise(const o2::framework::AxisSpec axis, const int& fCovList->Add(new BootstrapProfile("ChFull22pt1_Mpt0", "ChFull22pt1_Mpt0", nMultiBins, &multiBins[0])); fCovList->Add(new BootstrapProfile("ChFull22pt1_Mpt1", "ChFull22pt1_Mpt1", nMultiBins, &multiBins[0])); + + fCovList->Add(new BootstrapProfile("ChFull22pt3_Mpt0", "ChFull22pt3_Mpt0", nMultiBins, &multiBins[0])); + fCovList->Add(new BootstrapProfile("ChFull22pt3_Mpt1", "ChFull22pt3_Mpt1", nMultiBins, &multiBins[0])); + fCovList->Add(new BootstrapProfile("ChFull22pt3_Mpt2", "ChFull22pt3_Mpt2", nMultiBins, &multiBins[0])); + fCovList->Add(new BootstrapProfile("ChFull22pt3_Mpt3", "ChFull22pt3_Mpt3", nMultiBins, &multiBins[0])); + + fCovList->Add(new BootstrapProfile("ChFull22pt4_Mpt0", "ChFull22pt4_Mpt0", nMultiBins, &multiBins[0])); + fCovList->Add(new BootstrapProfile("ChFull22pt4_Mpt1", "ChFull22pt4_Mpt1", nMultiBins, &multiBins[0])); + fCovList->Add(new BootstrapProfile("ChFull22pt4_Mpt2", "ChFull22pt4_Mpt2", nMultiBins, &multiBins[0])); + fCovList->Add(new BootstrapProfile("ChFull22pt4_Mpt3", "ChFull22pt4_Mpt3", nMultiBins, &multiBins[0])); + fCovList->Add(new BootstrapProfile("ChFull22pt4_Mpt4", "ChFull22pt4_Mpt4", nMultiBins, &multiBins[0])); } else { fCovList->Add(new BootstrapProfile("ChFull24pt2", "ChFull24pt2", nMultiBins, &multiBins[0])); fCovList->Add(new BootstrapProfile("ChFull24pt1", "ChFull24pt1", nMultiBins, &multiBins[0])); @@ -161,8 +172,8 @@ void FlowPtContainer::initialise(const o2::framework::AxisSpec axis, const int& }; void FlowPtContainer::initialise(int nbinsx, double* xbins, const int& m, const GFWCorrConfigs& configs, const int& nsub) { - arr.resize(3 * 3 * 3 * 3); - warr.resize(3 * 3 * 3 * 3); + arr.resize(3 * 3 * 5 * 5); + warr.resize(3 * 3 * 5 * 5); if (!mpar) mpar = m; if (fCMTermList) @@ -214,6 +225,17 @@ void FlowPtContainer::initialise(int nbinsx, double* xbins, const int& m, const fCovList->Add(new BootstrapProfile("ChFull22pt1_Mpt0", "ChFull22pt1_Mpt0", nbinsx, xbins)); fCovList->Add(new BootstrapProfile("ChFull22pt1_Mpt1", "ChFull22pt1_Mpt1", nbinsx, xbins)); + + fCovList->Add(new BootstrapProfile("ChFull22pt3_Mpt0", "ChFull22pt3_Mpt0", nbinsx, xbins)); + fCovList->Add(new BootstrapProfile("ChFull22pt3_Mpt1", "ChFull22pt3_Mpt1", nbinsx, xbins)); + fCovList->Add(new BootstrapProfile("ChFull22pt3_Mpt2", "ChFull22pt3_Mpt2", nbinsx, xbins)); + fCovList->Add(new BootstrapProfile("ChFull22pt3_Mpt3", "ChFull22pt3_Mpt3", nbinsx, xbins)); + + fCovList->Add(new BootstrapProfile("ChFull22pt4_Mpt0", "ChFull22pt4_Mpt0", nbinsx, xbins)); + fCovList->Add(new BootstrapProfile("ChFull22pt4_Mpt1", "ChFull22pt4_Mpt1", nbinsx, xbins)); + fCovList->Add(new BootstrapProfile("ChFull22pt4_Mpt2", "ChFull22pt4_Mpt2", nbinsx, xbins)); + fCovList->Add(new BootstrapProfile("ChFull22pt4_Mpt3", "ChFull22pt4_Mpt3", nbinsx, xbins)); + fCovList->Add(new BootstrapProfile("ChFull22pt4_Mpt4", "ChFull22pt4_Mpt4", nbinsx, xbins)); } else { fCovList->Add(new BootstrapProfile("ChFull24pt2", "ChFull24pt2", nbinsx, xbins)); fCovList->Add(new BootstrapProfile("ChFull24pt1", "ChFull24pt1", nbinsx, xbins)); @@ -233,8 +255,8 @@ void FlowPtContainer::initialise(int nbinsx, double* xbins, const int& m, const }; void FlowPtContainer::initialise(int nbinsx, double xlow, double xhigh, const int& m, const GFWCorrConfigs& configs, const int& nsub) { - arr.resize(3 * 3 * 3 * 3); - warr.resize(3 * 3 * 3 * 3); + arr.resize(3 * 3 * 5 * 5); + warr.resize(3 * 3 * 5 * 5); if (!mpar) mpar = m; if (fCMTermList) @@ -286,6 +308,17 @@ void FlowPtContainer::initialise(int nbinsx, double xlow, double xhigh, const in fCovList->Add(new BootstrapProfile("ChFull22pt1_Mpt0", "ChFull22pt1_Mpt0", nbinsx, xlow, xhigh)); fCovList->Add(new BootstrapProfile("ChFull22pt1_Mpt1", "ChFull22pt1_Mpt1", nbinsx, xlow, xhigh)); + + fCovList->Add(new BootstrapProfile("ChFull22pt3_Mpt0", "ChFull22pt3_Mpt0", nbinsx, xlow, xhigh)); + fCovList->Add(new BootstrapProfile("ChFull22pt3_Mpt1", "ChFull22pt3_Mpt1", nbinsx, xlow, xhigh)); + fCovList->Add(new BootstrapProfile("ChFull22pt3_Mpt2", "ChFull22pt3_Mpt2", nbinsx, xlow, xhigh)); + fCovList->Add(new BootstrapProfile("ChFull22pt3_Mpt3", "ChFull22pt3_Mpt3", nbinsx, xlow, xhigh)); + + fCovList->Add(new BootstrapProfile("ChFull22pt4_Mpt0", "ChFull22pt4_Mpt0", nbinsx, xlow, xhigh)); + fCovList->Add(new BootstrapProfile("ChFull22pt4_Mpt1", "ChFull22pt4_Mpt1", nbinsx, xlow, xhigh)); + fCovList->Add(new BootstrapProfile("ChFull22pt4_Mpt2", "ChFull22pt4_Mpt2", nbinsx, xlow, xhigh)); + fCovList->Add(new BootstrapProfile("ChFull22pt4_Mpt3", "ChFull22pt4_Mpt3", nbinsx, xlow, xhigh)); + fCovList->Add(new BootstrapProfile("ChFull22pt4_Mpt4", "ChFull22pt4_Mpt4", nbinsx, xlow, xhigh)); } else { fCovList->Add(new BootstrapProfile("ChFull24pt2", "ChFull24pt2", nbinsx, xlow, xhigh)); fCovList->Add(new BootstrapProfile("ChFull24pt1", "ChFull24pt1", nbinsx, xlow, xhigh)); @@ -430,6 +463,33 @@ void FlowPtContainer::fillVnDeltaPtStdProfiles(const double& centmult, const dou double wABD = getStdABD(warr); if (wABD != 0) dynamic_cast(fCovList->At(9))->FillProfile(centmult, getStdABD(arr) / wABD, (fEventWeight == UnityWeight) ? 1.0 : wABD, rn); + double wABCCCC = getStdABCCCC(warr); + if (wABCCCC != 0.) + dynamic_cast(fCovList->At(14))->FillProfile(centmult, getStdABCCCC(arr) / wABCCCC, (fEventWeight == UnityWeight) ? 1. : wABCCCC, rn); + double wABCCCD = getStdABCCCD(warr); + if (wABCCCD != 0.) + dynamic_cast(fCovList->At(15))->FillProfile(centmult, getStdABCCCD(arr) / wABCCCD, (fEventWeight == UnityWeight) ? 1. : wABCCCD, rn); + double wABCCDD = getStdABCCDD(warr); + if (wABCCDD != 0.) + dynamic_cast(fCovList->At(16))->FillProfile(centmult, getStdABCCDD(arr) / wABCCDD, (fEventWeight == UnityWeight) ? 1. : wABCCDD, rn); + double wABCDDD = getStdABCDDD(warr); + if (wABCDDD != 0.) + dynamic_cast(fCovList->At(17))->FillProfile(centmult, getStdABCDDD(arr) / wABCDDD, (fEventWeight == UnityWeight) ? 1. : wABCDDD, rn); + double wABDDDD = getStdABDDDD(warr); + if (wABDDDD != 0.) + dynamic_cast(fCovList->At(18))->FillProfile(centmult, getStdABDDDD(arr) / wABDDDD, (fEventWeight == UnityWeight) ? 1. : wABDDDD, rn); + double wABCCC = getStdABCCC(warr); + if (wABCCC != 0.) + dynamic_cast(fCovList->At(10))->FillProfile(centmult, getStdABCCC(arr) / wABCCC, (fEventWeight == UnityWeight) ? 1. : wABCCC, rn); + double wABCCD = getStdABCCD(warr); + if (wABCCD != 0.) + dynamic_cast(fCovList->At(11))->FillProfile(centmult, getStdABCCD(arr) / wABCCD, (fEventWeight == UnityWeight) ? 1. : wABCCD, rn); + double wABCDD = getStdABCDD(warr); + if (wABCDD != 0.) + dynamic_cast(fCovList->At(12))->FillProfile(centmult, getStdABCDD(arr) / wABCDD, (fEventWeight == UnityWeight) ? 1. : wABCDD, rn); + double wABDDD = getStdABDDD(warr); + if (wABDDD != 0.) + dynamic_cast(fCovList->At(13))->FillProfile(centmult, getStdABDDD(arr) / wABDDD, (fEventWeight == UnityWeight) ? 1. : wABDDD, rn); return; } void FlowPtContainer::fillCMProfiles(const double& centmult, const double& rn) @@ -466,7 +526,7 @@ void FlowPtContainer::fillCMProfiles(const double& centmult, const double& rn) return; cmVal.push_back(1 / cmDen[4] * (sumP[getVectorIndex(1, 1)] * sumP[getVectorIndex(1, 1)] * sumP[getVectorIndex(1, 1)] * sumP[getVectorIndex(1, 1)] - 6 * sumP[getVectorIndex(2, 2)] * sumP[getVectorIndex(1, 1)] * sumP[getVectorIndex(1, 1)] + 3 * sumP[getVectorIndex(2, 2)] * sumP[getVectorIndex(2, 2)] + 8 * sumP[getVectorIndex(3, 3)] * sumP[getVectorIndex(1, 1)] - 6 * sumP[getVectorIndex(4, 4)])); dynamic_cast(fCMTermList->At(6))->FillProfile(centmult, cmVal[7], (fEventWeight == EventWeight::UnityWeight) ? 1.0 : cmDen[4], rn); - cmVal.push_back(-4 * 1 / cmDen[4] * (sumP[getVectorIndex(1, 1)] * sumP[getVectorIndex(1, 1)] * sumP[getVectorIndex(1, 1)] * sumP[getVectorIndex(1, 0)] - 3 * sumP[getVectorIndex(2, 2)] * sumP[getVectorIndex(1, 1)] * sumP[getVectorIndex(1, 0)] - 3 * sumP[getVectorIndex(1, 1)] * sumP[getVectorIndex(1, 1)] * sumP[getVectorIndex(2, 1)] + 3 * sumP[getVectorIndex(2, 2)] * sumP[getVectorIndex(2, 1)] + 6 * sumP[getVectorIndex(1, 1)] * sumP[getVectorIndex(3, 2)] - 6 * sumP[getVectorIndex(4, 3)])); + cmVal.push_back(-4 * 1 / cmDen[4] * (sumP[getVectorIndex(1, 1)] * sumP[getVectorIndex(1, 1)] * sumP[getVectorIndex(1, 1)] * sumP[getVectorIndex(1, 0)] - 3 * sumP[getVectorIndex(2, 2)] * sumP[getVectorIndex(1, 1)] * sumP[getVectorIndex(1, 0)] - 3 * sumP[getVectorIndex(1, 1)] * sumP[getVectorIndex(1, 1)] * sumP[getVectorIndex(2, 1)] + 3 * sumP[getVectorIndex(2, 2)] * sumP[getVectorIndex(2, 1)] + 2 * sumP[getVectorIndex(3, 3)] * sumP[getVectorIndex(1, 0)] + 6 * sumP[getVectorIndex(1, 1)] * sumP[getVectorIndex(3, 2)] - 6 * sumP[getVectorIndex(4, 3)])); dynamic_cast(fCMTermList->At(7))->FillProfile(centmult, cmVal[8], (fEventWeight == EventWeight::UnityWeight) ? 1.0 : cmDen[4], rn); cmVal.push_back(6 * 1 / cmDen[4] * (sumP[getVectorIndex(1, 1)] * sumP[getVectorIndex(1, 1)] * sumP[getVectorIndex(1, 0)] * sumP[getVectorIndex(1, 0)] - sumP[getVectorIndex(2, 2)] * sumP[getVectorIndex(1, 0)] * sumP[getVectorIndex(1, 0)] - sumP[getVectorIndex(2, 0)] * sumP[getVectorIndex(1, 1)] * sumP[getVectorIndex(1, 1)] + sumP[getVectorIndex(2, 0)] * sumP[getVectorIndex(2, 2)] - 4 * sumP[getVectorIndex(2, 1)] * sumP[getVectorIndex(1, 1)] * sumP[getVectorIndex(1, 0)] + 4 * sumP[getVectorIndex(3, 2)] * sumP[getVectorIndex(1, 0)] + 4 * sumP[getVectorIndex(3, 1)] * sumP[getVectorIndex(1, 1)] + 2 * sumP[getVectorIndex(2, 1)] * sumP[getVectorIndex(2, 1)] - 6 * sumP[getVectorIndex(4, 2)])); dynamic_cast(fCMTermList->At(8))->FillProfile(centmult, cmVal[9], (fEventWeight == EventWeight::UnityWeight) ? 1.0 : cmDen[4], rn); @@ -476,11 +536,11 @@ void FlowPtContainer::fillCMProfiles(const double& centmult, const double& rn) } void FlowPtContainer::fillArray(FillType a, FillType b, double c, double d) { - for (int idx = 0; idx < 81; ++idx) { + for (int idx = 0; idx < 225; ++idx) { int i = idx % 3; int j = ((idx - i) / 3) % 3; - int k = ((idx - j * 3 - i) / 9) % 3; - int l = ((idx - k * 9 - j * 3 - i) / 27) % 3; + int k = ((idx - j * 3 - i) / 9) % 5; + int l = ((idx - k * 9 - j * 3 - i) / 45) % 5; if (std::holds_alternative>(a) && std::holds_alternative>(b)) { arr[idx] += std::pow(std::get<0>(a), i) * std::pow(std::get<0>(b), j) * std::pow(c, k) * std::pow(d, l); } else if (std::holds_alternative(a) && std::holds_alternative(b)) { @@ -667,21 +727,21 @@ double FlowPtContainer::getStdAABBD(T& inarr) { std::complex a = inarr[getVectorIndex(1, 0, 0, 0)]; std::complex b = inarr[getVectorIndex(0, 1, 0, 0)]; - std::complex d = inarr[getVectorIndex(0, 0, 1, 0)]; + std::complex d = inarr[getVectorIndex(0, 0, 0, 1)]; std::complex aa = inarr[getVectorIndex(2, 0, 0, 0)]; std::complex ab = inarr[getVectorIndex(1, 1, 0, 0)]; - std::complex ad = inarr[getVectorIndex(1, 0, 1, 0)]; + std::complex ad = inarr[getVectorIndex(1, 0, 0, 1)]; std::complex bb = inarr[getVectorIndex(0, 2, 0, 0)]; - std::complex bd = inarr[getVectorIndex(0, 1, 1, 0)]; + std::complex bd = inarr[getVectorIndex(0, 1, 0, 1)]; std::complex aab = inarr[getVectorIndex(2, 1, 0, 0)]; - std::complex aad = inarr[getVectorIndex(2, 0, 1, 0)]; + std::complex aad = inarr[getVectorIndex(2, 0, 0, 1)]; std::complex abb = inarr[getVectorIndex(1, 2, 0, 0)]; - std::complex abd = inarr[getVectorIndex(1, 1, 1, 0)]; - std::complex bbd = inarr[getVectorIndex(0, 2, 1, 0)]; + std::complex abd = inarr[getVectorIndex(1, 1, 0, 1)]; + std::complex bbd = inarr[getVectorIndex(0, 2, 0, 1)]; std::complex aabb = inarr[getVectorIndex(2, 2, 0, 0)]; - std::complex aabd = inarr[getVectorIndex(2, 1, 1, 0)]; - std::complex abbd = inarr[getVectorIndex(1, 2, 1, 0)]; - std::complex aabbd = inarr[getVectorIndex(2, 2, 1, 0)]; + std::complex aabd = inarr[getVectorIndex(2, 1, 0, 1)]; + std::complex abbd = inarr[getVectorIndex(1, 2, 0, 1)]; + std::complex aabbd = inarr[getVectorIndex(2, 2, 0, 1)]; return (a * a * b * b * d - aa * b * b * d - a * a * bb * d - 4. * ab * a * b * d - 2. * a * ad * b * b - 2. * a * a * bd * b + 2. * ab * ab * d + 4. * ab * ad * b + 4. * ab * bd * a + 8. * abd * a * b + 4. * aab * b * d + 2. * aad * b * b + 4. * abb * a * d + 2. * bbd * a * a + aa * bb * d + 2. * aa * b * bd + 2. * bb * a * ad - 12. * aabd * b - 12. * abbd * a - 6. * aabb * d - 8. * abd * ab - 2. * bbd * aa - 2. * aad * bb - 4. * aab * bd - 4. * abb * ad + 24. * aabbd).real(); } template @@ -763,6 +823,347 @@ double FlowPtContainer::getStdABD(T& inarr) std::complex abd = inarr[getVectorIndex(1, 1, 0, 1)]; return (a * b * d - ab * d - ad * b - a * bd + 2. * abd).real(); } +template +double FlowPtContainer::getStdABCCCC(T& inarr) +{ + std::complex a = inarr[getVectorIndex(1, 0, 0, 0)]; + std::complex b = inarr[getVectorIndex(0, 1, 0, 0)]; + std::complex c = inarr[getVectorIndex(0, 0, 1, 0)]; + std::complex ab = inarr[getVectorIndex(1, 1, 0, 0)]; + std::complex ac = inarr[getVectorIndex(1, 0, 1, 0)]; + std::complex bc = inarr[getVectorIndex(0, 1, 1, 0)]; + std::complex cc = inarr[getVectorIndex(0, 0, 2, 0)]; + std::complex abc = inarr[getVectorIndex(1, 1, 1, 0)]; + std::complex acc = inarr[getVectorIndex(1, 0, 2, 0)]; + std::complex bcc = inarr[getVectorIndex(0, 1, 2, 0)]; + std::complex ccc = inarr[getVectorIndex(0, 0, 3, 0)]; + std::complex abcc = inarr[getVectorIndex(1, 1, 2, 0)]; + std::complex accc = inarr[getVectorIndex(1, 0, 3, 0)]; + std::complex bccc = inarr[getVectorIndex(0, 1, 3, 0)]; + std::complex cccc = inarr[getVectorIndex(0, 0, 4, 0)]; + std::complex abccc = inarr[getVectorIndex(1, 1, 3, 0)]; + std::complex acccc = inarr[getVectorIndex(1, 0, 4, 0)]; + std::complex bcccc = inarr[getVectorIndex(0, 1, 4, 0)]; + std::complex abcccc = inarr[getVectorIndex(1, 1, 4, 0)]; + return (-120. * abcccc + 24. * acccc * b + 24. * accc * bc + 24. * acc * bcc + + 24. * ac * bccc + 24. * a * bcccc + 96. * abccc * c - 24. * accc * b * c - 24. * acc * bc * c - + 24. * ac * bcc * c - 24. * a * bccc * c - 36. * abcc * c * c + 12. * acc * b * c * c + + 12. * ac * bc * c * c + 12. * a * bcc * c * c + 8. * abc * c * c * c - 4. * ac * b * c * c * c - 4. * a * bc * c * c * c - + ab * c * c * c * c + a * b * c * c * c * c + 36. * abcc * cc - 12. * acc * b * cc - 12. * ac * bc * cc - 12. * a * bcc * cc - 24. * abc * c * cc + 12. * ac * b * c * cc + 12. * a * bc * c * cc + 6. * ab * c * c * cc - 6. * a * b * c * c * cc - 3. * ab * cc * cc + 3. * a * b * cc * cc + 16. * abc * ccc - 8. * ac * b * ccc - 8. * a * bc * ccc - 8. * ab * c * ccc + 8. * a * b * c * ccc + 6. * ab * cccc - 6. * a * b * cccc) + .real(); +} +template +double FlowPtContainer::getStdABCCCD(T& inarr) +{ + std::complex a = inarr[getVectorIndex(1, 0, 0, 0)]; + std::complex b = inarr[getVectorIndex(0, 1, 0, 0)]; + std::complex c = inarr[getVectorIndex(0, 0, 1, 0)]; + std::complex d = inarr[getVectorIndex(0, 0, 0, 1)]; + std::complex ab = inarr[getVectorIndex(1, 1, 0, 0)]; + std::complex ac = inarr[getVectorIndex(1, 0, 1, 0)]; + std::complex ad = inarr[getVectorIndex(1, 0, 0, 1)]; + std::complex bc = inarr[getVectorIndex(0, 1, 1, 0)]; + std::complex bd = inarr[getVectorIndex(0, 1, 0, 1)]; + std::complex cc = inarr[getVectorIndex(0, 0, 2, 0)]; + std::complex cd = inarr[getVectorIndex(0, 0, 1, 1)]; + std::complex abc = inarr[getVectorIndex(1, 1, 1, 0)]; + std::complex abd = inarr[getVectorIndex(1, 1, 0, 1)]; + std::complex acc = inarr[getVectorIndex(1, 0, 2, 0)]; + std::complex acd = inarr[getVectorIndex(1, 0, 1, 1)]; + std::complex bcc = inarr[getVectorIndex(0, 1, 2, 0)]; + std::complex bcd = inarr[getVectorIndex(0, 1, 1, 1)]; + std::complex ccc = inarr[getVectorIndex(0, 0, 3, 0)]; + std::complex ccd = inarr[getVectorIndex(0, 0, 2, 1)]; + std::complex abcc = inarr[getVectorIndex(1, 1, 2, 0)]; + std::complex abcd = inarr[getVectorIndex(1, 1, 1, 1)]; + std::complex accc = inarr[getVectorIndex(1, 0, 3, 0)]; + std::complex accd = inarr[getVectorIndex(1, 0, 2, 1)]; + std::complex bccc = inarr[getVectorIndex(0, 1, 3, 0)]; + std::complex bccd = inarr[getVectorIndex(0, 1, 2, 1)]; + std::complex cccd = inarr[getVectorIndex(0, 0, 3, 1)]; + std::complex abccc = inarr[getVectorIndex(1, 1, 3, 0)]; + std::complex abccd = inarr[getVectorIndex(1, 1, 2, 1)]; + std::complex acccd = inarr[getVectorIndex(1, 0, 3, 1)]; + std::complex bcccd = inarr[getVectorIndex(0, 1, 3, 1)]; + std::complex abcccd = inarr[getVectorIndex(1, 1, 3, 1)]; + return (-120. * abcccd + 24. * acccd * b + 18. * accd * bc + 12. * acd * bcc + 6. * ad * bccc + + 24. * a * bcccd + 18. * ac * bccd + 12. * acc * bcd + 6. * accc * bd + 72. * abccd * c - + 18. * accd * b * c - 12. * acd * bc * c - 6. * ad * bcc * c - 18. * a * bccd * c - 12. * ac * bcd * c - + 6. * acc * bd * c - 18. * abcd * c * c + 6. * acd * b * c * c + 3. * ad * bc * c * c + 6. * a * bcd * c * c + + 3. * ac * bd * c * c + 2. * abd * c * c * c - ad * b * c * c * c - a * bd * c * c * c + 18. * abcd * cc - + 6. * acd * b * cc - 3. * ad * bc * cc - 6. * a * bcd * cc - 3. * ac * bd * cc - 6. * abd * c * cc + + 3. * ad * b * c * cc + 3. * a * bd * c * cc + 4. * abd * ccc - 2. * ad * b * ccc - 2. * a * bd * ccc + + 6. * ab * cccd - 6. * a * b * cccd + 12. * abc * ccd - 6. * ac * b * ccd - 6. * a * bc * ccd - + 6. * ab * c * ccd + 6. * a * b * c * ccd + 18. * abcc * cd - 6. * acc * b * cd - 6. * ac * bc * cd - + 6. * a * bcc * cd - 12. * abc * c * cd + 6. * ac * b * c * cd + 6. * a * bc * c * cd + 3. * ab * c * c * cd - + 3. * a * b * c * c * cd - 3. * ab * cc * cd + 3. * a * b * cc * cd + 24. * abccc * d - 6. * accc * b * d - + 6. * acc * bc * d - 6. * ac * bcc * d - 6. * a * bccc * d - 18. * abcc * c * d + 6. * acc * b * c * d + + 6. * ac * bc * c * d + 6. * a * bcc * c * d + 6. * abc * c * c * d - 3. * ac * b * c * c * d - + 3. * a * bc * c * c * d - ab * c * c * c * d + a * b * c * c * c * d - 6. * abc * cc * d + 3. * ac * b * cc * d + + 3. * a * bc * cc * d + 3. * ab * c * cc * d - 3. * a * b * c * cc * d - 2. * ab * ccc * d + 2. * a * b * ccc * d) + .real(); +} +template +double FlowPtContainer::getStdABCCDD(T& inarr) +{ + std::complex a = inarr[getVectorIndex(1, 0, 0, 0)]; + std::complex b = inarr[getVectorIndex(0, 1, 0, 0)]; + std::complex c = inarr[getVectorIndex(0, 0, 1, 0)]; + std::complex d = inarr[getVectorIndex(0, 0, 0, 1)]; + std::complex ab = inarr[getVectorIndex(1, 1, 0, 0)]; + std::complex ac = inarr[getVectorIndex(1, 0, 1, 0)]; + std::complex ad = inarr[getVectorIndex(1, 0, 0, 1)]; + std::complex bc = inarr[getVectorIndex(0, 1, 1, 0)]; + std::complex bd = inarr[getVectorIndex(0, 1, 0, 1)]; + std::complex cc = inarr[getVectorIndex(0, 0, 2, 0)]; + std::complex cd = inarr[getVectorIndex(0, 0, 1, 1)]; + std::complex dd = inarr[getVectorIndex(0, 0, 0, 2)]; + std::complex abc = inarr[getVectorIndex(1, 1, 1, 0)]; + std::complex abd = inarr[getVectorIndex(1, 1, 0, 1)]; + std::complex acc = inarr[getVectorIndex(1, 0, 2, 0)]; + std::complex acd = inarr[getVectorIndex(1, 0, 1, 1)]; + std::complex add = inarr[getVectorIndex(1, 0, 0, 2)]; + std::complex bcc = inarr[getVectorIndex(0, 1, 2, 0)]; + std::complex bcd = inarr[getVectorIndex(0, 1, 1, 1)]; + std::complex bdd = inarr[getVectorIndex(0, 1, 0, 2)]; + std::complex ccd = inarr[getVectorIndex(0, 0, 2, 1)]; + std::complex cdd = inarr[getVectorIndex(0, 0, 1, 2)]; + std::complex abcc = inarr[getVectorIndex(1, 1, 2, 0)]; + std::complex abcd = inarr[getVectorIndex(1, 1, 1, 1)]; + std::complex abdd = inarr[getVectorIndex(1, 1, 0, 2)]; + std::complex accd = inarr[getVectorIndex(1, 0, 2, 1)]; + std::complex acdd = inarr[getVectorIndex(1, 0, 1, 2)]; + std::complex bccd = inarr[getVectorIndex(0, 1, 2, 1)]; + std::complex bcdd = inarr[getVectorIndex(0, 1, 1, 2)]; + std::complex ccdd = inarr[getVectorIndex(0, 0, 2, 2)]; + std::complex abccd = inarr[getVectorIndex(1, 1, 2, 1)]; + std::complex abcdd = inarr[getVectorIndex(1, 1, 1, 2)]; + std::complex accdd = inarr[getVectorIndex(1, 0, 2, 2)]; + std::complex bccdd = inarr[getVectorIndex(0, 1, 2, 2)]; + std::complex abccdd = inarr[getVectorIndex(1, 1, 2, 2)]; + return (-120. * abccdd + 24. * accdd * b + 12. * acdd * bc + 4. * add * bcc + 12. * ad * bccd + + 24. * a * bccdd + 16. * acd * bcd + 12. * ac * bcdd + 12. * accd * bd + 4. * acc * bdd + + 48. * abcdd * c - 12. * acdd * b * c - 4. * add * bc * c - 8. * ad * bcd * c - 12. * a * bcdd * c - + 8. * acd * bd * c - 4. * ac * bdd * c - 6. * abdd * c * c + 2. * add * b * c * c + 2. * ad * bd * c * c + + 2. * a * bdd * c * c + 6. * abdd * cc - 2. * add * b * cc - 2. * ad * bd * cc - 2. * a * bdd * cc + + 8. * abd * ccd - 4. * ad * b * ccd - 4. * a * bd * ccd + 6. * ab * ccdd - 6. * a * b * ccdd + + 24. * abcd * cd - 8. * acd * b * cd - 4. * ad * bc * cd - 8. * a * bcd * cd - 4. * ac * bd * cd - + 8. * abd * c * cd + 4. * ad * b * c * cd + 4. * a * bd * c * cd - 2. * ab * cd * d + 2. * a * b * cd * d + + 8. * abc * cdd - 4. * ac * b * cdd - 4. * a * bc * cdd - 4. * ab * c * cdd + 4. * a * b * c * cdd + + 48. * abccd * d - 12. * accd * b * d - 8. * acd * bc * d - 4. * ad * bcc * d - 12. * a * bccd * d - + 8. * ac * bcd * d - 4. * acc * bd * d - 24. * abcd * c * d + 8. * acd * b * c * d + 4. * ad * bc * c * d + + 8. * a * bcd * c * d + 4. * ac * bd * c * d + 4. * abd * c * c * d - 2. * ad * b * c * c * d - + 2. * a * bd * c * c * d - 4. * abd * cc * d + 2. * ad * b * cc * d + 2. * a * bd * cc * d - 4. * ab * ccd * d + + 4. * a * b * ccd * d - 8. * abc * cd * d + 4. * ac * b * cd * d + 4. * a * bc * cd * d + 4. * ab * c * cd * d - + 4. * a * b * c * cd * d - 6. * abcc * d * d + 2. * acc * b * d * d + 2. * ac * bc * d * d + + 2. * a * bcc * d * d + 4. * abc * c * d * d - 2. * ac * b * c * d * d - 2. * a * bc * c * d * d - + ab * c * c * d * d + a * b * c * c * d * d + ab * cc * d * d - a * b * cc * d * d + 6. * abcc * dd - + 2. * acc * b * dd - 2. * ac * bc * dd - 2. * a * bcc * dd - 4. * abc * c * dd + 2. * ac * b * c * dd + + 2. * a * bc * c * dd + ab * c * c * dd - a * b * c * c * dd - ab * cc * dd + a * b * cc * dd) + .real(); +} +template +double FlowPtContainer::getStdABCDDD(T& inarr) +{ + std::complex a = inarr[getVectorIndex(1, 0, 0, 0)]; + std::complex b = inarr[getVectorIndex(0, 1, 0, 0)]; + std::complex c = inarr[getVectorIndex(0, 0, 1, 0)]; + std::complex d = inarr[getVectorIndex(0, 0, 0, 1)]; + std::complex ab = inarr[getVectorIndex(1, 1, 0, 0)]; + std::complex ac = inarr[getVectorIndex(1, 0, 1, 0)]; + std::complex ad = inarr[getVectorIndex(1, 0, 0, 1)]; + std::complex bc = inarr[getVectorIndex(0, 1, 1, 0)]; + std::complex bd = inarr[getVectorIndex(0, 1, 0, 1)]; + std::complex cd = inarr[getVectorIndex(0, 0, 1, 1)]; + std::complex dd = inarr[getVectorIndex(0, 0, 0, 2)]; + std::complex abc = inarr[getVectorIndex(1, 1, 1, 0)]; + std::complex abd = inarr[getVectorIndex(1, 1, 0, 1)]; + std::complex acd = inarr[getVectorIndex(1, 0, 1, 1)]; + std::complex add = inarr[getVectorIndex(1, 0, 0, 2)]; + std::complex bcd = inarr[getVectorIndex(0, 1, 1, 1)]; + std::complex bdd = inarr[getVectorIndex(0, 1, 0, 2)]; + std::complex cdd = inarr[getVectorIndex(0, 0, 1, 2)]; + std::complex ddd = inarr[getVectorIndex(0, 0, 0, 3)]; + std::complex abcd = inarr[getVectorIndex(1, 1, 1, 1)]; + std::complex abdd = inarr[getVectorIndex(1, 1, 0, 2)]; + std::complex acdd = inarr[getVectorIndex(1, 0, 1, 2)]; + std::complex addd = inarr[getVectorIndex(1, 0, 0, 3)]; + std::complex bcdd = inarr[getVectorIndex(0, 1, 1, 2)]; + std::complex bddd = inarr[getVectorIndex(0, 1, 0, 3)]; + std::complex cddd = inarr[getVectorIndex(0, 0, 1, 3)]; + std::complex abcdd = inarr[getVectorIndex(1, 1, 1, 2)]; + std::complex abddd = inarr[getVectorIndex(1, 1, 0, 3)]; + std::complex acddd = inarr[getVectorIndex(1, 0, 1, 3)]; + std::complex bcddd = inarr[getVectorIndex(0, 1, 1, 3)]; + std::complex abcddd = inarr[getVectorIndex(1, 1, 1, 3)]; + return (-120. * abcddd + 24. * acddd * b + 6. * addd * bc + 12. * add * bcd + 18. * ad * bcdd + + 24. * a * bcddd + 18. * acdd * bd + 12. * acd * bdd + 6. * ac * bddd + 24. * abddd * c - + 6. * addd * b * c - 6. * add * bd * c - 6. * ad * bdd * c - 6. * a * bddd * c + 18. * abdd * cd - + 6. * add * b * cd - 6. * ad * bd * cd - 6. * a * bdd * cd + 12. * abd * cdd - 6. * ad * b * cdd - + 6. * a * bd * cdd + 6. * ab * cddd - 6. * a * b * cddd + 72. * abcdd * d - 18. * acdd * b * d - + 6. * add * bc * d - 12. * ad * bcd * d - 18. * a * bcdd * d - 12. * acd * bd * d - 6. * ac * bdd * d - + 18. * abdd * c * d + 6. * add * b * c * d + 6. * ad * bd * c * d + 6. * a * bdd * c * d - + 12. * abd * cd * d + 6. * ad * b * cd * d + 6. * a * bd * cd * d - 6. * ab * cdd * d + 6. * a * b * cdd * d - + 18. * abcd * d * d + 6. * acd * b * d * d + 3. * ad * bc * d * d + 6. * a * bcd * d * d + + 3. * ac * bd * d * d + 6. * abd * c * d * d - 3. * ad * b * c * d * d - 3. * a * bd * c * d * d + + 3. * ab * cd * d * d - 3. * a * b * cd * d * d + 2. * abc * d * d * d - ac * b * d * d * d - a * bc * d * d * d - + ab * c * d * d * d + a * b * c * d * d * d + 18. * abcd * dd - 6. * acd * b * dd - 3. * ad * bc * dd - + 6. * a * bcd * dd - 3. * ac * bd * dd - 6. * abd * c * dd + 3. * ad * b * c * dd + 3. * a * bd * c * dd - + 3. * ab * cd * dd + 3. * a * b * cd * dd - 6. * abc * d * dd + 3. * ac * b * d * dd + 3. * a * bc * d * dd + + 3. * ab * c * d * dd - 3. * a * b * c * d * dd + 4. * abc * ddd - 2. * ac * b * ddd - 2. * a * bc * ddd - + 2. * ab * c * ddd + 2. * a * b * c * ddd) + .real(); +} +template +double FlowPtContainer::getStdABDDDD(T& inarr) +{ + std::complex a = inarr[getVectorIndex(1, 0, 0, 0)]; + std::complex b = inarr[getVectorIndex(0, 1, 0, 0)]; + std::complex d = inarr[getVectorIndex(0, 0, 0, 1)]; + std::complex ab = inarr[getVectorIndex(1, 1, 0, 0)]; + std::complex ad = inarr[getVectorIndex(1, 0, 0, 1)]; + std::complex bd = inarr[getVectorIndex(0, 1, 0, 1)]; + std::complex dd = inarr[getVectorIndex(0, 0, 0, 2)]; + std::complex abd = inarr[getVectorIndex(1, 1, 0, 1)]; + std::complex add = inarr[getVectorIndex(1, 0, 0, 2)]; + std::complex bdd = inarr[getVectorIndex(0, 1, 0, 2)]; + std::complex ddd = inarr[getVectorIndex(0, 0, 0, 3)]; + std::complex abdd = inarr[getVectorIndex(1, 1, 0, 2)]; + std::complex addd = inarr[getVectorIndex(1, 0, 0, 3)]; + std::complex bddd = inarr[getVectorIndex(0, 1, 0, 3)]; + std::complex dddd = inarr[getVectorIndex(0, 0, 0, 4)]; + std::complex abddd = inarr[getVectorIndex(1, 1, 0, 3)]; + std::complex adddd = inarr[getVectorIndex(1, 0, 0, 4)]; + std::complex bdddd = inarr[getVectorIndex(0, 1, 0, 4)]; + std::complex abdddd = inarr[getVectorIndex(1, 1, 0, 4)]; + return (-120. * abdddd + 24. * adddd * b + 24. * addd * bd + 24. * add * bdd + 24. * ad * bddd + + 24. * a * bdddd + 96. * abddd * d - 24. * addd * b * d - 24. * add * bd * d - 24. * ad * bdd * d - + 24. * a * bddd * d - 36. * abdd * d * d + 12. * add * b * d * d + 12. * ad * bd * d * d + + 12. * a * bdd * d * d + 8. * abd * d * d * d - 4. * ad * b * d * d * d - 4. * a * bd * d * d * d - ab * d * d * d * d + + a * b * d * d * d * d + 36. * abdd * dd - 12. * add * b * dd - 12. * ad * bd * dd - 12. * a * bdd * dd - + 24. * abd * d * dd + 12. * ad * b * d * dd + 12. * a * bd * d * dd + 6. * ab * d * d * dd - + 6. * a * b * d * d * dd - 3. * ab * dd * d + 3. * a * b * dd * d + 16. * abd * ddd - 8. * ad * b * ddd - + 8. * a * bd * ddd - 8. * ab * d * ddd + 8. * a * b * d * ddd + 6. * ab * dddd - 6. * a * b * dddd) + .real(); +} +template +double FlowPtContainer::getStdABCCC(T& inarr) +{ + std::complex a = inarr[getVectorIndex(1, 0, 0, 0)]; + std::complex b = inarr[getVectorIndex(0, 1, 0, 0)]; + std::complex c = inarr[getVectorIndex(0, 0, 1, 0)]; + std::complex ab = inarr[getVectorIndex(1, 1, 0, 0)]; + std::complex ac = inarr[getVectorIndex(1, 0, 1, 0)]; + std::complex bc = inarr[getVectorIndex(0, 1, 1, 0)]; + std::complex cc = inarr[getVectorIndex(0, 0, 2, 0)]; + std::complex abc = inarr[getVectorIndex(1, 1, 1, 0)]; + std::complex acc = inarr[getVectorIndex(1, 0, 2, 0)]; + std::complex bcc = inarr[getVectorIndex(0, 1, 2, 0)]; + std::complex ccc = inarr[getVectorIndex(0, 0, 3, 0)]; + std::complex abcc = inarr[getVectorIndex(1, 1, 2, 0)]; + std::complex accc = inarr[getVectorIndex(1, 0, 3, 0)]; + std::complex bccc = inarr[getVectorIndex(0, 1, 3, 0)]; + std::complex abccc = inarr[getVectorIndex(1, 1, 3, 0)]; + return (24. * abccc - 6. * accc * b - 6. * acc * bc - 6. * ac * bcc - 6. * a * bccc - 18. * abcc * c + + 6. * acc * b * c + 6. * ac * bc * c + 6. * a * bcc * c + 6. * abc * c * c - 3. * ac * b * c * c - + 3. * a * bc * c * c - ab * c * c * c + a * b * c * c * c - 6. * abc * cc + 3. * ac * b * cc + 3. * a * bc * cc + + 3. * ab * c * cc - 3. * a * b * c * cc - 2. * ab * ccc + 2. * a * b * ccc) + .real(); +} +template +double FlowPtContainer::getStdABCCD(T& inarr) +{ + std::complex a = inarr[getVectorIndex(1, 0, 0, 0)]; + std::complex b = inarr[getVectorIndex(0, 1, 0, 0)]; + std::complex c = inarr[getVectorIndex(0, 0, 1, 0)]; + std::complex d = inarr[getVectorIndex(0, 0, 0, 1)]; + std::complex ab = inarr[getVectorIndex(1, 1, 0, 0)]; + std::complex ac = inarr[getVectorIndex(1, 0, 1, 0)]; + std::complex ad = inarr[getVectorIndex(1, 0, 0, 1)]; + std::complex bc = inarr[getVectorIndex(0, 1, 1, 0)]; + std::complex bd = inarr[getVectorIndex(0, 1, 0, 1)]; + std::complex cc = inarr[getVectorIndex(0, 0, 2, 0)]; + std::complex cd = inarr[getVectorIndex(0, 0, 1, 1)]; + std::complex abc = inarr[getVectorIndex(1, 1, 1, 0)]; + std::complex abd = inarr[getVectorIndex(1, 1, 0, 1)]; + std::complex acc = inarr[getVectorIndex(1, 0, 2, 0)]; + std::complex bcc = inarr[getVectorIndex(0, 1, 2, 0)]; + std::complex ccd = inarr[getVectorIndex(0, 0, 2, 1)]; + std::complex acd = inarr[getVectorIndex(1, 0, 1, 1)]; + std::complex bcd = inarr[getVectorIndex(0, 1, 1, 1)]; + std::complex abcc = inarr[getVectorIndex(1, 1, 2, 0)]; + std::complex abcd = inarr[getVectorIndex(1, 1, 1, 1)]; + std::complex accd = inarr[getVectorIndex(1, 0, 2, 1)]; + std::complex bccd = inarr[getVectorIndex(0, 1, 2, 1)]; + std::complex abccd = inarr[getVectorIndex(1, 1, 2, 1)]; + return (24. * abccd - 6. * accd * b - 4. * acd * bc - 2. * ad * bcc - 6. * a * bccd - 4. * ac * bcd - + 2. * acc * bd - 12. * abcd * c + 4. * acd * b * c + 2. * ad * bc * c + 4. * a * bcd * c + + 2. * ac * bd * c + 2. * abd * c * c - ad * b * c * c - a * bd * c * c - 2. * abd * cc + ad * b * cc + + a * bd * cc - 2. * ab * ccd + 2. * a * b * ccd - 4. * abc * cd + 2. * ac * b * cd + 2. * a * bc * cd + + 2. * ab * c * cd - 2. * a * b * c * cd - 6. * abcc * d + 2. * acc * b * d + 2. * ac * bc * d + + 2. * a * bcc * d + 4. * abc * c * d - 2. * ac * b * c * d - 2. * a * bc * c * d - ab * c * c * d + + a * b * c * c * d + ab * cc * d - a * b * cc * d) + .real(); +} +template +double FlowPtContainer::getStdABCDD(T& inarr) +{ + std::complex a = inarr[getVectorIndex(1, 0, 0, 0)]; + std::complex b = inarr[getVectorIndex(0, 1, 0, 0)]; + std::complex c = inarr[getVectorIndex(0, 0, 1, 0)]; + std::complex d = inarr[getVectorIndex(0, 0, 0, 1)]; + std::complex ab = inarr[getVectorIndex(1, 1, 0, 0)]; + std::complex ac = inarr[getVectorIndex(1, 0, 1, 0)]; + std::complex ad = inarr[getVectorIndex(1, 0, 0, 1)]; + std::complex bc = inarr[getVectorIndex(0, 1, 1, 0)]; + std::complex bd = inarr[getVectorIndex(0, 1, 0, 1)]; + std::complex cd = inarr[getVectorIndex(0, 0, 1, 1)]; + std::complex dd = inarr[getVectorIndex(0, 0, 0, 2)]; + std::complex abc = inarr[getVectorIndex(1, 1, 1, 0)]; + std::complex abd = inarr[getVectorIndex(1, 1, 0, 1)]; + std::complex add = inarr[getVectorIndex(1, 0, 0, 2)]; + std::complex bdd = inarr[getVectorIndex(0, 1, 0, 2)]; + std::complex cdd = inarr[getVectorIndex(0, 0, 1, 2)]; + std::complex acd = inarr[getVectorIndex(1, 0, 1, 1)]; + std::complex bcd = inarr[getVectorIndex(0, 1, 1, 1)]; + std::complex abdd = inarr[getVectorIndex(1, 1, 0, 2)]; + std::complex abcd = inarr[getVectorIndex(1, 1, 1, 1)]; + std::complex acdd = inarr[getVectorIndex(1, 0, 1, 2)]; + std::complex bcdd = inarr[getVectorIndex(0, 1, 1, 2)]; + std::complex abcdd = inarr[getVectorIndex(1, 1, 1, 2)]; + return (24. * abcdd - 6. * acdd * b - 2. * add * bc - 4. * ad * bcd - 6. * a * bcdd - 4. * acd * bd - + 2. * ac * bdd - 6. * abdd * c + 2. * add * b * c + 2. * ad * bd * c + 2. * a * bdd * c - 4. * abd * cd + + 2. * ad * b * cd + 2. * a * bd * cd - 2. * ab * cdd + 2. * a * b * cdd - 12. * abcd * d + + 4. * acd * b * d + 2. * ad * bc * d + 4. * a * bcd * d + 2. * ac * bd * d + 4. * abd * c * d - + 2. * ad * b * c * d - 2. * a * bd * c * d + 2. * ab * cd * d - 2. * a * b * cd * d + 2. * abc * d * d - + ac * b * d * d - a * bc * d * d - ab * c * d * d + a * b * c * d * d - 2. * abc * dd + ac * b * dd + + a * bc * dd + ab * c * dd - a * b * c * dd) + .real(); +} +template +double FlowPtContainer::getStdABDDD(T& inarr) +{ + std::complex a = inarr[getVectorIndex(1, 0, 0, 0)]; + std::complex b = inarr[getVectorIndex(0, 1, 0, 0)]; + std::complex d = inarr[getVectorIndex(0, 0, 0, 1)]; + std::complex ab = inarr[getVectorIndex(1, 1, 0, 0)]; + std::complex ad = inarr[getVectorIndex(1, 0, 0, 1)]; + std::complex bd = inarr[getVectorIndex(0, 1, 0, 1)]; + std::complex dd = inarr[getVectorIndex(0, 0, 0, 2)]; + std::complex abd = inarr[getVectorIndex(1, 1, 0, 1)]; + std::complex add = inarr[getVectorIndex(1, 0, 0, 2)]; + std::complex bdd = inarr[getVectorIndex(0, 1, 0, 2)]; + std::complex ddd = inarr[getVectorIndex(0, 0, 0, 3)]; + std::complex abdd = inarr[getVectorIndex(1, 1, 0, 2)]; + std::complex addd = inarr[getVectorIndex(1, 0, 0, 3)]; + std::complex bddd = inarr[getVectorIndex(0, 1, 0, 3)]; + std::complex abddd = inarr[getVectorIndex(1, 1, 0, 3)]; + return (24. * abddd - 6. * addd * b - 6. * add * bd - 6. * ad * bdd - 6. * a * bddd - 18. * abdd * d + + 6. * add * b * d + 6. * ad * bd * d + 6. * a * bdd * d + 6. * abd * d * d - 3. * ad * b * d * d - + 3. * a * bd * d * d - ab * d * d * d + a * b * d * d * d - 6. * abd * dd + 3. * ad * b * dd + 3. * a * bd * dd + + 3. * ab * d * dd - 3. * a * b * d * dd - 2. * ab * ddd + 2. * a * b * ddd) + .real(); +} double FlowPtContainer::orderedAddition(std::vector vec) { double sum = 0; diff --git a/PWGCF/GenericFramework/Core/FlowPtContainer.h b/PWGCF/GenericFramework/Core/FlowPtContainer.h index 91442985cc0..207e1a36fe7 100644 --- a/PWGCF/GenericFramework/Core/FlowPtContainer.h +++ b/PWGCF/GenericFramework/Core/FlowPtContainer.h @@ -53,7 +53,7 @@ class FlowPtContainer : public TNamed void fill(const double& w, const double& pt); void fillArray(FillType a, FillType b, double c, double d); int getVectorIndex(const int i, const int j) { return j * (mpar + 1) + i; } // index for 2d array for storing pt correlations - int getVectorIndex(const int i, const int j, const int k, const int l) { return i + j * 3 + k * 3 * 3 + l * 3 * 3 * 3; } // index for 4d array for std vnpt correlation - size 3x3x3x3 + int getVectorIndex(const int i, const int j, const int k, const int l) { return i + j * 3 + k * 3 * 3 + l * 3 * 3 * 5; } // index for 4d array for std vnpt correlation - size 3x3x3x3 void calculateCorrelations(); void calculateCMTerms(); void fillPtProfiles(const double& lMult, const double& rn); @@ -104,9 +104,9 @@ class FlowPtContainer : public TNamed cmDen.clear(); fillCounter = 0; arr.clear(); - arr.resize(3 * 3 * 3 * 3, {0.0, 0.0}); + arr.resize(3 * 3 * 5 * 5, {0.0, 0.0}); warr.clear(); - warr.resize(3 * 3 * 3 * 3, 0.0); + warr.resize(3 * 3 * 5 * 5, 0.0); }; TList* fCMTermList; @@ -115,11 +115,11 @@ class FlowPtContainer : public TNamed TList* fCumulantList; TList* fCentralMomentList; - int mpar; //! + int mpar; int fillCounter; //! unsigned int fEventWeight; //! - bool fUseCentralMoments; //! - bool fUseGap; //! + bool fUseCentralMoments; + bool fUseGap; void mergeBSLists(TList* source, TList* target); TH1* raiseHistToPower(TH1* inh, double p); std::vector sumP; //! @@ -149,6 +149,24 @@ class FlowPtContainer : public TNamed double getStdABC(T& inarr); template double getStdABD(T& inarr); + template + double getStdABCCCC(T& inarr); + template + double getStdABCCCD(T& inarr); + template + double getStdABCCDD(T& inarr); + template + double getStdABCDDD(T& inarr); + template + double getStdABDDDD(T& inarr); + template + double getStdABCCC(T& inarr); + template + double getStdABCCD(T& inarr); + template + double getStdABCDD(T& inarr); + template + double getStdABDDD(T& inarr); private: static constexpr float FactorialArray[9] = {1., 1., 2., 6., 24., 120., 720., 5040., 40320.}; diff --git a/PWGCF/GenericFramework/Tasks/flowGenericFramework.cxx b/PWGCF/GenericFramework/Tasks/flowGenericFramework.cxx index 03f4a82a3fd..271f3b16493 100644 --- a/PWGCF/GenericFramework/Tasks/flowGenericFramework.cxx +++ b/PWGCF/GenericFramework/Tasks/flowGenericFramework.cxx @@ -86,6 +86,7 @@ struct FlowGenericFramework { O2_DEFINE_CONFIGURABLE(cfgNbootstrap, int, 10, "Number of subsamples") O2_DEFINE_CONFIGURABLE(cfgMpar, int, 8, "Highest order of pt-pt correlations") + O2_DEFINE_CONFIGURABLE(cfgCentEstimator, int, 0, "0:FT0C; 1:FT0CVariant1; 2:FT0M; 3:FT0A") O2_DEFINE_CONFIGURABLE(cfgUseNch, bool, false, "Do correlations as function of Nch") O2_DEFINE_CONFIGURABLE(cfgFillWeights, bool, false, "Fill NUA weights") O2_DEFINE_CONFIGURABLE(cfgRunByRun, bool, false, "Fill histograms on a run-by-run basis") @@ -115,6 +116,9 @@ struct FlowGenericFramework { O2_DEFINE_CONFIGURABLE(cfgIsVertexITSTPC, bool, true, "Selects collisions with at least one ITS-TPC track"); O2_DEFINE_CONFIGURABLE(cfgMagField, float, 99999, "Configurable magnetic field; default CCDB will be queried"); O2_DEFINE_CONFIGURABLE(cfgTofPtCut, float, 0.5, "pt cut on TOF for PID"); + O2_DEFINE_CONFIGURABLE(cfgUseDensityDependentCorrection, bool, false, "Use density dependent efficiency correction based on Run 2 measurements"); + Configurable> cfgTrackDensityP0{"cfgTrackDensityP0", std::vector{0.7217476707, 0.7384792571, 0.7542625668, 0.7640680200, 0.7701951667, 0.7755299053, 0.7805901710, 0.7849446786, 0.7957356586, 0.8113039262, 0.8211968966, 0.8280558878, 0.8329342135}, "parameter 0 for track density efficiency correction"}; + Configurable> cfgTrackDensityP1{"cfgTrackDensityP1", std::vector{-2.169488e-05, -2.191913e-05, -2.295484e-05, -2.556538e-05, -2.754463e-05, -2.816832e-05, -2.846502e-05, -2.843857e-05, -2.705974e-05, -2.477018e-05, -2.321730e-05, -2.203315e-05, -2.109474e-05}, "parameter 1 for track density efficiency correction"}; Configurable cfgGFWBinning{"cfgGFWBinning", {40, 16, 72, 300, 0, 3000, 0.2, 10.0, 0.2, 3.0, {0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2, 2.2, 2.4, 2.6, 2.8, 3, 3.5, 4, 5, 6, 8, 10}, {0, 5, 10, 20, 30, 40, 50, 60, 70, 80, 90}}, "Configuration for binning"}; Configurable cfgRegions{"cfgRegions", {{"refN", "refP", "refFull"}, {-0.8, 0.4, -0.8}, {-0.4, 0.8, 0.8}, {0, 0, 0}, {1, 1, 1}}, "Configurations for GFW regions"}; @@ -137,6 +141,7 @@ struct FlowGenericFramework { OutputObj fFCgen{FlowContainer("FlowContainer_gen")}; HistogramRegistry registry{"registry"}; + // QA outputs std::map>> th1sList; std::map>> th3sList; enum OutputTH1Names { @@ -148,6 +153,7 @@ struct FlowGenericFramework { hEventSel, kCount_TH1Names }; + // NUA outputs enum OutputTH3Names { hNUAref = 0, hNUAch, @@ -156,14 +162,40 @@ struct FlowGenericFramework { hNUApr, kCount_TH3Names }; + enum CentEstimators { + kCentFT0C = 0, + kCentFT0CVariant1, + kCentFT0M, + kCentFV0A + }; - // define global variables + // Define global variables + // Generic Framework GFW* fGFW = new GFW(); std::vector corrconfigs; + TRandom3* fRndm = new TRandom3(0); TAxis* fPtAxis; int lastRun = -1; std::vector runNumbers; + + // Density dependent eff correction + std::vector funcEff; + TH1D* hFindPtBin; + TF1* funcV2; + TF1* funcV3; + TF1* funcV4; + struct DensityCorr { + double psi2Est; + double psi3Est; + double psi4Est; + double v2; + double v3; + double v4; + int density; + DensityCorr() : psi2Est(0.), psi3Est(0.), psi4Est(0.), v2(0.), v3(0.), v4(0.), density(0) {} + }; + // Event selection cuts - Alex TF1* fPhiCutLow = nullptr; TF1* fPhiCutHigh = nullptr; @@ -209,7 +241,25 @@ struct FlowGenericFramework { AxisSpec etaAxis = {etabins, -cfgEta, cfgEta, "#eta"}; AxisSpec vtxAxis = {vtxZbins, -cfgVtxZ, cfgVtxZ, "Vtx_{z} (cm)"}; AxisSpec ptAxis = {ptbinning, "#it{p}_{T} GeV/#it{c}"}; - AxisSpec centAxis = {centbinning, "Centrality (%)"}; + std::string sCentralityEstimator; + switch (cfgCentEstimator) { + case kCentFT0C: + sCentralityEstimator = "FT0C"; + break; + case kCentFT0CVariant1: + sCentralityEstimator = "FT0C variant 1"; + break; + case kCentFT0M: + sCentralityEstimator = "FT0M"; + break; + case kCentFV0A: + sCentralityEstimator = "FV0A"; + break; + default: + sCentralityEstimator = "FT0C"; + } + sCentralityEstimator += " centrality (%)"; + AxisSpec centAxis = {centbinning, sCentralityEstimator.c_str()}; std::vector nchbinning; int nchskip = (nchup - nchlow) / nchbins; for (int i = 0; i <= nchbins; ++i) { @@ -240,10 +290,18 @@ struct FlowGenericFramework { if (doprocessMCReco || doprocessData || doprocessRun2) { registry.add("trackQA/before/phi_eta_vtxZ", "", {HistType::kTH3D, {phiAxis, etaAxis, vtxAxis}}); registry.add("trackQA/before/pt_dcaXY_dcaZ", "", {HistType::kTH3D, {ptAxis, dcaXYAXis, dcaZAXis}}); + registry.add("trackQA/before/chi2prTPCcls", "#chi^{2}/cluster for the TPC track segment", {HistType::kTH1D, {{100, 0., 5.}}}); + registry.add("trackQA/before/chi2prITScls", "#chi^{2}/cluster for the ITS track", {HistType::kTH1D, {{100, 0., 50.}}}); + registry.add("trackQA/before/nTPCClusters", "Number of found TPC clusters", {HistType::kTH1D, {{100, 40, 180}}}); + registry.add("trackQA/before/nITSClusters", "Number of found ITS clusters", {HistType::kTH1D, {{100, 0, 20}}}); + registry.add("trackQA/before/nTPCCrossedRows", "Number of crossed TPC Rows", {HistType::kTH1D, {{100, 40, 180}}}); + registry.addClone("trackQA/before/", "trackQA/after/"); registry.add("trackQA/after/pt_ref", "", {HistType::kTH1D, {{100, ptreflow, ptrefup}}}); registry.add("trackQA/after/pt_poi", "", {HistType::kTH1D, {{100, ptpoilow, ptpoiup}}}); + registry.add("eventQA/before/centrality", "", {HistType::kTH1D, {centAxis}}); + registry.add("eventQA/before/multiplicity", "", {HistType::kTH1D, {nchAxis}}); registry.add("eventQA/before/globalTracks_centT0C", "", {HistType::kTH2D, {centAxis, nchAxis}}); registry.add("eventQA/before/PVTracks_centT0C", "", {HistType::kTH2D, {centAxis, multpvAxis}}); registry.add("eventQA/before/globalTracks_PVTracks", "", {HistType::kTH2D, {multpvAxis, nchAxis}}); @@ -317,6 +375,24 @@ struct FlowGenericFramework { fMultCutHigh = new TF1("fMultCutHigh", "[0]+[1]*x+[2]*x*x+[3]*x*x*x + 3.*([4]+[5]*x+[6]*x*x+[7]*x*x*x+[8]*x*x*x*x)", 0, 100); fMultCutHigh->SetParameters(1654.46, -47.2379, 0.449833, -0.0014125, 150.773, -3.67334, 0.0530503, -0.000614061, 3.15956e-06); } + if (cfgUseDensityDependentCorrection) { + std::vector pTEffBins = {0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.4, 1.8, 2.2, 2.6, 3.0}; + hFindPtBin = new TH1D("hFindPtBin", "hFindPtBin", pTEffBins.size() - 1, &pTEffBins[0]); + funcEff.resize(pTEffBins.size() - 1); + // LHC24g3 Eff + std::vector f1p0 = cfgTrackDensityP0; + std::vector f1p1 = cfgTrackDensityP1; + for (uint ifunc = 0; ifunc < pTEffBins.size() - 1; ifunc++) { + funcEff[ifunc] = new TF1(Form("funcEff%i", ifunc), "[0]+[1]*x", 0, 3000); + funcEff[ifunc]->SetParameters(f1p0[ifunc], f1p1[ifunc]); + } + funcV2 = new TF1("funcV2", "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x", 0, 100); + funcV2->SetParameters(0.0186111, 0.00351907, -4.38264e-05, 1.35383e-07, -3.96266e-10); + funcV3 = new TF1("funcV3", "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x", 0, 100); + funcV3->SetParameters(0.0174056, 0.000703329, -1.45044e-05, 1.91991e-07, -1.62137e-09); + funcV4 = new TF1("funcV4", "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x", 0, 100); + funcV4->SetParameters(0.008845, 0.000259668, -3.24435e-06, 4.54837e-08, -6.01825e-10); + } } static constexpr std::string_view FillTimeName[] = {"before/", "after/"}; @@ -576,12 +652,14 @@ struct FlowGenericFramework { AxisSpec phiAxis = {phibins, philow, phiup, "#phi"}; AxisSpec etaAxis = {etabins, -cfgEta, cfgEta, "#eta"}; AxisSpec vtxAxis = {vtxZbins, -cfgVtxZ, cfgVtxZ, "Vtx_{z} (cm)"}; + AxisSpec nchAxis = {nchbins, nchlow, nchup, "N_{ch}"}; + AxisSpec centAxis = {centbinning, "Centrality (%)"}; std::vector> histos(kCount_TH1Names); histos[hPhi] = registry.add(Form("%d/phi", run), "", {HistType::kTH1D, {phiAxis}}); histos[hEta] = registry.add(Form("%d/eta", run), "", {HistType::kTH1D, {etaAxis}}); histos[hVtxZ] = registry.add(Form("%d/vtxz", run), "", {HistType::kTH1D, {vtxAxis}}); - histos[hMult] = registry.add(Form("%d/mult", run), "", {HistType::kTH1D, {{3000, 0.5, 3000.5}}}); - histos[hCent] = registry.add(Form("%d/cent", run), "", {HistType::kTH1D, {{90, 0, 90}}}); + histos[hMult] = registry.add(Form("%d/mult", run), "", {HistType::kTH1D, {nchAxis}}); + histos[hCent] = registry.add(Form("%d/cent", run), "", {HistType::kTH1D, {centAxis}}); histos[hEventSel] = registry.add(Form("%d/eventSel", run), "Number of Events;; Counts", {HistType::kTH1D, {{11, 0, 11}}}); histos[hEventSel]->GetXaxis()->SetBinLabel(1, "Filtered event"); histos[hEventSel]->GetXaxis()->SetBinLabel(2, "sel8"); @@ -661,15 +739,51 @@ struct FlowGenericFramework { fGFW->Clear(); fFCpt->clearVector(); float lRandom = fRndm->Rndm(); + + // be cautious, this only works for Pb-Pb + // esimate the Event plane and vn for this event + DensityCorr densitycorrections; + if (cfgUseDensityDependentCorrection) { + double psi2Est = 0, psi3Est = 0, psi4Est = 0; + double v2 = 0, v3 = 0, v4 = 0; + double q2x = 0, q2y = 0; + double q3x = 0, q3y = 0; + double q4x = 0, q4y = 0; + for (const auto& track : tracks) { + bool withinPtRef = (ptreflow < track.pt()) && (track.pt() < ptrefup); // within RF pT rang + if (withinPtRef) { + q2x += std::cos(2 * track.phi()); + q2y += std::sin(2 * track.phi()); + q3x += std::cos(3 * track.phi()); + q3y += std::sin(3 * track.phi()); + q4x += std::cos(4 * track.phi()); + q4y += std::sin(4 * track.phi()); + } + } + psi2Est = std::atan2(q2y, q2x) / 2.; + psi3Est = std::atan2(q3y, q3x) / 3.; + psi4Est = std::atan2(q4y, q4x) / 4.; + v2 = funcV2->Eval(centrality); + v3 = funcV3->Eval(centrality); + v4 = funcV4->Eval(centrality); + densitycorrections.psi2Est = psi2Est; + densitycorrections.psi3Est = psi3Est; + densitycorrections.psi4Est = psi4Est; + densitycorrections.v2 = v2; + densitycorrections.v3 = v3; + densitycorrections.v4 = v4; + densitycorrections.density = tracks.size(); + } + for (const auto& track : tracks) { - processTrack(track, vtxz, run); + processTrack(track, vtxz, run, densitycorrections); } if (!cfgFillWeights) fillOutputContainers
((cfgUseNch) ? tracks.size() : centrality, lRandom); } template - inline void processTrack(TTrack const& track, const float& vtxz, const int& run) + inline void processTrack(TTrack const& track, const float& vtxz, const int& run, DensityCorr densitycorrections) { if constexpr (framework::has_type_v) { if (track.mcParticleId() < 0 || !(track.has_mcParticle())) @@ -698,7 +812,7 @@ struct FlowGenericFramework { fillWeights(mcParticle, vtxz, 0, run); } else { fillPtSums(track, vtxz); - fillGFW(mcParticle, vtxz, pidIndex); + fillGFW(mcParticle, vtxz, pidIndex, densitycorrections); } if (cfgFillQA) { @@ -729,7 +843,7 @@ struct FlowGenericFramework { } fillPtSums(track, vtxz); - fillGFW(track, vtxz, pidIndex); + fillGFW(track, vtxz, pidIndex, densitycorrections); if (cfgFillQA) fillTrackQA(track, vtxz); @@ -748,7 +862,7 @@ struct FlowGenericFramework { fillWeights(track, vtxz, pidIndex, run); } else { fillPtSums(track, vtxz); - fillGFW(track, vtxz, pidIndex); + fillGFW(track, vtxz, pidIndex, densitycorrections); } if (cfgFillQA) { fillTrackQA(track, vtxz); @@ -779,7 +893,7 @@ struct FlowGenericFramework { } template - inline void fillGFW(TTrack track, const double& vtxz, int pid_index) + inline void fillGFW(TTrack track, const double& vtxz, int pid_index, DensityCorr densitycorrections) { if (cfgUsePID) { // Analysing POI flow with id'ed particles double ptmins[] = {ptpoilow, ptpoilow, 0.3, 0.5}; @@ -812,6 +926,18 @@ struct FlowGenericFramework { double weff = (dt == kGen) ? 1. : getEfficiency(track); if (weff < 0) return; + if (cfgUseDensityDependentCorrection && withinPtRef && dt != kGen) { + double fphi = densitycorrections.v2 * std::cos(2 * (track.phi() - densitycorrections.psi2Est)) + densitycorrections.v3 * std::cos(3 * (track.phi() - densitycorrections.psi3Est)) + densitycorrections.v4 * std::cos(4 * (track.phi() - densitycorrections.psi4Est)); + fphi = (1 + 2 * fphi); + int pTBinForEff = hFindPtBin->FindBin(track.pt()); + if (pTBinForEff >= 1 && pTBinForEff <= hFindPtBin->GetNbinsX()) { + float wEPeff = funcEff[pTBinForEff - 1]->Eval(fphi * densitycorrections.density); + if (wEPeff > 0.) { + wEPeff = 1. / wEPeff; + weff *= wEPeff; + } + } + } double wacc = (dt == kGen) ? 1. : getAcceptance(track, vtxz, 0); if (withinPtRef) fGFW->Fill(track.eta(), fPtAxis->FindBin(track.pt()) - 1, track.phi(), weff * wacc, 1); @@ -833,6 +959,13 @@ struct FlowGenericFramework { double wacc = getAcceptance(track, vtxz, 0); registry.fill(HIST("trackQA/") + HIST(FillTimeName[ft]) + HIST("phi_eta_vtxZ"), track.phi(), track.eta(), vtxz, (ft == kAfter) ? wacc : 1.0); registry.fill(HIST("trackQA/") + HIST(FillTimeName[ft]) + HIST("pt_dcaXY_dcaZ"), track.pt(), track.dcaXY(), track.dcaZ()); + + registry.fill(HIST("trackQA/") + HIST(FillTimeName[ft]) + HIST("chi2prTPCcls"), track.tpcChi2NCl()); + registry.fill(HIST("trackQA/") + HIST(FillTimeName[ft]) + HIST("chi2prITScls"), track.itsChi2NCl()); + registry.fill(HIST("trackQA/") + HIST(FillTimeName[ft]) + HIST("nTPCClusters"), track.tpcNClsFound()); + registry.fill(HIST("trackQA/") + HIST(FillTimeName[ft]) + HIST("nITSClusters"), track.itsNCls()); + registry.fill(HIST("trackQA/") + HIST(FillTimeName[ft]) + HIST("nTPCCrossedRows"), track.tpcNClsCrossedRows()); + if (ft == kAfter) { registry.fill(HIST("trackQA/") + HIST(FillTimeName[ft]) + HIST("pt_ref"), track.pt()); registry.fill(HIST("trackQA/") + HIST(FillTimeName[ft]) + HIST("pt_poi"), track.pt()); @@ -857,7 +990,7 @@ struct FlowGenericFramework { 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 GFWTracks = soa::Filtered>; - void processData(soa::Filtered>::iterator const& collision, aod::BCsWithTimestamps const&, GFWTracks const& tracks) + void processData(soa::Filtered>::iterator const& collision, aod::BCsWithTimestamps const&, GFWTracks const& tracks) { auto bc = collision.bc_as(); int run = bc.runNumber(); @@ -894,13 +1027,33 @@ struct FlowGenericFramework { registry.fill(HIST("eventQA/eventSel"), 2.5); if (cfgRunByRun) th1sList[run][hEventSel]->Fill(2.5); - const auto centrality = collision.centFT0C(); + float centrality; + switch (cfgCentEstimator) { + case kCentFT0C: + centrality = collision.centFT0C(); + break; + case kCentFT0CVariant1: + centrality = collision.centFT0CVariant1(); + break; + case kCentFT0M: + centrality = collision.centFT0M(); + break; + case kCentFV0A: + centrality = collision.centFV0A(); + break; + default: + centrality = collision.centFT0C(); + } if (cfgFillQA) fillEventQA(collision, tracks); + registry.fill(HIST("eventQA/before/centrality"), centrality); + registry.fill(HIST("eventQA/before/multiplicity"), tracks.size()); if (cfgUseAdditionalEventCut && !eventSelected(collision, tracks.size(), centrality, run)) return; if (cfgFillQA) fillEventQA(collision, tracks); + registry.fill(HIST("eventQA/after/centrality"), centrality); + registry.fill(HIST("eventQA/after/multiplicity"), tracks.size()); processCollision(collision, tracks, centrality, run); } PROCESS_SWITCH(FlowGenericFramework, processData, "Process analysis for non-derived data", true); diff --git a/PWGCF/MultiparticleCorrelations/Core/MuPa-Configurables.h b/PWGCF/MultiparticleCorrelations/Core/MuPa-Configurables.h index 6a91e2f6e4b..551376fad0e 100644 --- a/PWGCF/MultiparticleCorrelations/Core/MuPa-Configurables.h +++ b/PWGCF/MultiparticleCorrelations/Core/MuPa-Configurables.h @@ -9,6 +9,10 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. +/// \file MuPa-Configurables.h +/// \brief ... TBI 20250425 +/// \author Ante.Bilandzic@cern.ch + #ifndef PWGCF_MULTIPARTICLECORRELATIONS_CORE_MUPA_CONFIGURABLES_H_ #define PWGCF_MULTIPARTICLECORRELATIONS_CORE_MUPA_CONFIGURABLES_H_ @@ -34,11 +38,14 @@ struct : ConfigurableGroup { 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 TMath::Abs(f1 - f2) < fFloatingPointPrecision"}; + 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."}; } cf_tc; // *) QA: @@ -116,8 +123,8 @@ struct : ConfigurableGroup { 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 TF1 formula for the upper boundary cut in RefMult_vs_NContr correlation"}; - Configurable cfRefMultVsNContrLow{"cfRefMultVsNContrLow", "-650. + 0.08*x", "set here some TF1 formula for the lower boundary cut in RefMult_vs_NContr correlation"}; + 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\""}; @@ -274,32 +281,32 @@ struct : ConfigurableGroup { Configurable cfSaveResultsHistograms{"cfSaveResultsHistograms", false, "save or not results histograms"}; // Fixed-length binning (default): - Configurable> cfFixedLength_mult_bins{"cfFixedLength_mult_bins", {2000, 0., 20000.}, "nMultBins, multMin, multMax (only for results histograms)"}; - Configurable> cfFixedLength_cent_bins{"cfFixedLength_cent_bins", {110, 0., 110.}, "nCentBins, centMin, centMax (only for results histograms)"}; - Configurable> cfFixedLength_pt_bins{"cfFixedLength_pt_bins", {1000, 0., 10.}, "nPtBins, ptMin, ptMax (only for results histograms)"}; - Configurable> cfFixedLength_eta_bins{"cfFixedLength_eta_bins", {80, -2., 2.}, "nEtaBins, etaMin, etaMax (only for results histograms)"}; - Configurable> cfFixedLength_occu_bins{"cfFixedLength_occu_bins", {200, 0., 60000.}, "nOccuBins, occuMin, occuMax (only for results histograms)"}; - Configurable> cfFixedLength_ir_bins{"cfFixedLength_ir_bins", {1000, 0., 100.}, "nirBins, irMin, irMax (only for results histograms)"}; - Configurable> cfFixedLength_crd_bins{"cfFixedLength_crd_bins", {100000, 0., 100000.}, "ncrdBins, crdMin, crdMax (only for results histograms)"}; - Configurable> cfFixedLength_vz_bins{"cfFixedLength_vz_bins", {400, -20., 20.}, "nvzBins, vzMin, vzMax (only for results histograms)"}; + 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 cfUseVariableLength_mult_bins{"cfUseVariableLength_mult_bins", false, "use or not variable-length multiplicity bins"}; - Configurable> cfVariableLength_mult_bins{"cfVariableLength_mult_bins", {0., 5., 6., 7., 8., 9., 100., 200., 500., 1000., 10000.}, "variable-length multiplicity bins"}; - Configurable cfUseVariableLength_cent_bins{"cfUseVariableLength_cent_bins", false, "use or not variable-length centrality bins"}; - Configurable> cfVariableLength_cent_bins{"cfVariableLength_cent_bins", {0., 10., 50., 100.}, "variable-length centrality bins"}; - Configurable cfUseVariableLength_pt_bins{"cfUseVariableLength_pt_bins", true, "use or not variable-length pt bins"}; - Configurable> cfVariableLength_pt_bins{"cfVariableLength_pt_bins", {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 cfUseVariableLength_eta_bins{"cfUseVariableLength_eta_bins", true, "use or not variable-length eta bins"}; - Configurable> cfVariableLength_eta_bins{"cfVariableLength_eta_bins", {-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 cfUseVariableLength_occu_bins{"cfUseVariableLength_occu_bins", false, "use or not variable-length occupancy bins"}; - Configurable> cfVariableLength_occu_bins{"cfVariableLength_occu_bins", {0., 5., 6., 7., 8., 9., 100., 200., 500., 1000., 10000.}, "variable-length occupancy bins"}; - Configurable cfUseVariableLength_ir_bins{"cfUseVariableLength_ir_bins", false, "use or not variable-length interaction rate bins"}; - Configurable> cfVariableLength_ir_bins{"cfVariableLength_ir_bins", {0., 5., 10., 50., 100., 200.}, "variable-length ineraction rate bins"}; - Configurable cfUseVariableLength_crd_bins{"cfUseVariableLength_crd_bins", false, "use or not variable-length current run duration bins"}; - Configurable> cfVariableLength_crd_bins{"cfVariableLength_crd_bins", {0., 5., 10., 50., 100., 500.}, "variable-length current run duration bins"}; - Configurable cfUseVariableLength_vz_bins{"cfUseVariableLength_vz_bins", false, "use or not variable-length vertex z bins"}; - Configurable> cfVariableLength_vz_bins{"cfVariableLength_vz_bins", {-10., -8., -6., -4, -2., -1., 0., 1., 2., 4., 6., 8., 10.}, "variable-length vertex z bins"}; + 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; diff --git a/PWGCF/MultiparticleCorrelations/Core/MuPa-DataMembers.h b/PWGCF/MultiparticleCorrelations/Core/MuPa-DataMembers.h index 1a083a64471..ac1c22d7dc0 100644 --- a/PWGCF/MultiparticleCorrelations/Core/MuPa-DataMembers.h +++ b/PWGCF/MultiparticleCorrelations/Core/MuPa-DataMembers.h @@ -9,6 +9,10 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. +/// \file MuPa-DataMembers.h +/// \brief ... TBI 20250425 +/// \author Ante.Bilandzic@cern.ch + #ifndef PWGCF_MULTIPARTICLECORRELATIONS_CORE_MUPA_DATAMEMBERS_H_ #define PWGCF_MULTIPARTICLECORRELATIONS_CORE_MUPA_DATAMEMBERS_H_ @@ -33,7 +37,8 @@ TString sBaseListName = "Default list name"; // yes, I declare it separately, be OutputObj fBaseList{sBaseListName.Data(), OutputObjHandlingPolicy::AnalysisObject, 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 TMath::Abs(f1 - f2) < fFloatingPointPrecision (there is configurable for it) + 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 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 } tc; // "tc" labels an instance of this group of variables. // *) Event-by-event quantities: @@ -179,12 +188,14 @@ struct EventCuts { int fEventCutCounterBinNumber[2] = {1, 1}; // bin counter for set bin labels in fEventCutCounterHist float fdEventCuts[eEventCuts_N][2] = {{0.}}; // event cuts defined via [min,max) TString fsEventCuts[eEventCuts_N] = {""}; // event cuts defined via string - TH1F* fEventCutCounterHist[2][eCutCounter_N] = {{NULL}}; //! 0. - UInt_t fnEventsInternalValidation = 0; // how many on-the-fly events will be sampled for each real event, for internal validation + 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" or "persistent", 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 TArrayD* fInternalValidationVnPsin[2] = {NULL}; // 0 = { v1, v2, ... }, 1 = { Psi1, Psi2, ... } @@ -356,7 +367,6 @@ struct Test0 { 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 - TH1I* fTest0LabelsPlaceholder = NULL; // store all Test0 labels in this histogram } t0; // "t0" labels an instance of this group of histograms // *) Eta separations: diff --git a/PWGCF/MultiparticleCorrelations/Core/MuPa-Enums.h b/PWGCF/MultiparticleCorrelations/Core/MuPa-Enums.h index 026974d301c..e808d72551b 100644 --- a/PWGCF/MultiparticleCorrelations/Core/MuPa-Enums.h +++ b/PWGCF/MultiparticleCorrelations/Core/MuPa-Enums.h @@ -9,6 +9,10 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. +/// \file MuPa-Enums.h +/// \brief ... TBI 20250425 +/// \author Ante.Bilandzic@cern.ch + #ifndef PWGCF_MULTIPARTICLECORRELATIONS_CORE_MUPA_ENUMS_H_ #define PWGCF_MULTIPARTICLECORRELATIONS_CORE_MUPA_ENUMS_H_ @@ -34,6 +38,9 @@ enum eConfiguration { eUseSpecificCuts, eWhichSpecificCuts, eSkipTheseRuns, + eUseSetBinLabel, // Use or not setter SetBinLabel(...) + eUseClone, // Use or not ->Clone() + eUseFormula, // Use or not class TFormula eConfiguration_N }; diff --git a/PWGCF/MultiparticleCorrelations/Core/MuPa-GlobalConstants.h b/PWGCF/MultiparticleCorrelations/Core/MuPa-GlobalConstants.h index e7a31c445df..adacaf76282 100644 --- a/PWGCF/MultiparticleCorrelations/Core/MuPa-GlobalConstants.h +++ b/PWGCF/MultiparticleCorrelations/Core/MuPa-GlobalConstants.h @@ -9,6 +9,10 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. +/// \file MuPa-GlobalConstants.h +/// \brief ... TBI 20250425 +/// \author Ante.Bilandzic@cern.ch + #ifndef PWGCF_MULTIPARTICLECORRELATIONS_CORE_MUPA_GLOBALCONSTANTS_H_ #define PWGCF_MULTIPARTICLECORRELATIONS_CORE_MUPA_GLOBALCONSTANTS_H_ diff --git a/PWGCF/MultiparticleCorrelations/Core/MuPa-MemberFunctions.h b/PWGCF/MultiparticleCorrelations/Core/MuPa-MemberFunctions.h index dc33b8d3d30..c2a12790435 100644 --- a/PWGCF/MultiparticleCorrelations/Core/MuPa-MemberFunctions.h +++ b/PWGCF/MultiparticleCorrelations/Core/MuPa-MemberFunctions.h @@ -9,6 +9,10 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. +/// \file MuPa-MemberFunctions.h +/// \brief ... TBI 20250425 +/// \author Ante.Bilandzic@cern.ch + #ifndef PWGCF_MULTIPARTICLECORRELATIONS_CORE_MUPA_MEMBERFUNCTIONS_H_ #define PWGCF_MULTIPARTICLECORRELATIONS_CORE_MUPA_MEMBERFUNCTIONS_H_ @@ -23,7 +27,13 @@ void BookBaseList() // Book base TList and store task configuration. // a) Book base TList; - // b) Store task configuration. + // b) Book base profile fBasePro to hold task configuration; + // c) Define bin labels directly via SetBinLabel(...); + // d) Define bin labels indirectly by storing them in y-axis title + local executable PostprocessLabels.C. + // Algorithm: y-axis title is formatted with respect to 2 IFS, ":" and ";" as follows "1:first-bin-label; 2:second-bin-label; ..." + // Then, I tokenize with respect to ";" to get bin number and corresponding bin label. + // In the final step, I tokenize with respect to ":" to disentangle bin number and its bin label; + // e) Add configured base TProfile to the list. if (tc.fVerbose) { StartFunction(__FUNCTION__); @@ -34,7 +44,7 @@ void BookBaseList() temp->SetOwner(true); fBaseList.setObject(temp); - // b) Store task configuration: + // 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); @@ -43,65 +53,170 @@ void BookBaseList() // Remark: If I want to change the ordering of bin labels, simply change the // ordering in enum eConfiguration { ... }, nothing needs to be changed here. - fBasePro->GetXaxis()->SetBinLabel(eTaskIsConfiguredFromJson, Form("fTaskIsConfiguredFromJson = %s", tc.fTaskIsConfiguredFromJson.Data())); - fBasePro->GetXaxis()->SetBinLabel(eTaskName, Form("fTaskName = %s", tc.fTaskName.Data())); + 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)); + + } 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)); - 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(...) + yAxisTitle += TString::Format("%d:fPlainPrintout; ", static_cast(ePlainPrintout)); + fBasePro->Fill(ePlainPrintout, static_cast(tc.fPlainPrintout)); - fBasePro->GetXaxis()->SetBinLabel(eDryRun, "fDryRun"); - fBasePro->Fill(eDryRun, static_cast(tc.fDryRun)); + yAxisTitle += TString::Format("%d:fDoAdditionalInsanityChecks; ", static_cast(eDoAdditionalInsanityChecks)); + fBasePro->Fill(eDoAdditionalInsanityChecks, static_cast(tc.fDoAdditionalInsanityChecks)); - fBasePro->GetXaxis()->SetBinLabel(eVerbose, "fVerbose"); - fBasePro->Fill(eVerbose, static_cast(tc.fVerbose)); + yAxisTitle += TString::Format("%d:fInsanityCheckForEachParticle; ", static_cast(eInsanityCheckForEachParticle)); + fBasePro->Fill(eInsanityCheckForEachParticle, static_cast(tc.fInsanityCheckForEachParticle)); - fBasePro->GetXaxis()->SetBinLabel(eVerboseUtility, "fVerboseUtility"); - fBasePro->Fill(eVerboseUtility, static_cast(tc.fVerboseUtility)); + yAxisTitle += TString::Format("%d:fWhichProcess = %s; ", static_cast(eWhichProcess), tc.fWhichProcess.Data()); - fBasePro->GetXaxis()->SetBinLabel(eVerboseForEachParticle, "fVerboseForEachParticle"); - fBasePro->Fill(eVerboseForEachParticle, static_cast(tc.fVerboseForEachParticle)); + yAxisTitle += TString::Format("%d:fRandomSeed; ", static_cast(eRandomSeed)); + fBasePro->Fill(eRandomSeed, static_cast(tc.fRandomSeed)); - fBasePro->GetXaxis()->SetBinLabel(eVerboseEventCounter, "fVerboseEventCounter"); - fBasePro->Fill(eVerboseEventCounter, static_cast(tc.fVerboseEventCounter)); + yAxisTitle += TString::Format("%d:fUseFisherYates; ", static_cast(eUseFisherYates)); + fBasePro->Fill(eUseFisherYates, static_cast(tc.fUseFisherYates)); - fBasePro->GetXaxis()->SetBinLabel(ePlainPrintout, "fPlainPrintout"); - fBasePro->Fill(ePlainPrintout, static_cast(tc.fPlainPrintout)); + yAxisTitle += TString::Format("%d:fFixedNumberOfRandomlySelectedTracks; ", static_cast(eFixedNumberOfRandomlySelectedTracks)); + fBasePro->Fill(eFixedNumberOfRandomlySelectedTracks, static_cast(tc.fFixedNumberOfRandomlySelectedTracks)); - fBasePro->GetXaxis()->SetBinLabel(eDoAdditionalInsanityChecks, "fDoAdditionalInsanityChecks"); - fBasePro->Fill(eDoAdditionalInsanityChecks, static_cast(tc.fDoAdditionalInsanityChecks)); + yAxisTitle += TString::Format("%d:fUseStopwatch; ", static_cast(eUseStopwatch)); + fBasePro->Fill(eUseStopwatch, static_cast(tc.fUseStopwatch)); - fBasePro->GetXaxis()->SetBinLabel(eInsanityCheckForEachParticle, "fInsanityCheckForEachParticle"); - fBasePro->Fill(eInsanityCheckForEachParticle, static_cast(tc.fInsanityCheckForEachParticle)); + yAxisTitle += TString::Format("%d:fFloatingPointPrecision; ", static_cast(eFloatingPointPrecision)); + fBasePro->Fill(eFloatingPointPrecision, static_cast(tc.fFloatingPointPrecision)); - fBasePro->GetXaxis()->SetBinLabel(eWhichProcess, Form("WhichProcess = %s", tc.fWhichProcess.Data())); + yAxisTitle += TString::Format("%d:fSequentialBailout; ", static_cast(eSequentialBailout)); + fBasePro->Fill(eSequentialBailout, static_cast(tc.fSequentialBailout)); - fBasePro->GetXaxis()->SetBinLabel(eRandomSeed, "fRandomSeed"); - fBasePro->Fill(eRandomSeed, static_cast(tc.fRandomSeed)); + yAxisTitle += TString::Format("%d:fUseSpecificCuts; ", static_cast(eUseSpecificCuts)); + fBasePro->Fill(eUseSpecificCuts, static_cast(tc.fUseSpecificCuts)); - fBasePro->GetXaxis()->SetBinLabel(eUseFisherYates, "fUseFisherYates"); - fBasePro->Fill(eUseFisherYates, static_cast(tc.fUseFisherYates)); + yAxisTitle += TString::Format("%d:fWhichSpecificCuts = %s; ", static_cast(eWhichSpecificCuts), tc.fWhichSpecificCuts.Data()); - fBasePro->GetXaxis()->SetBinLabel(eFixedNumberOfRandomlySelectedTracks, "fFixedNumberOfRandomlySelectedTracks"); - fBasePro->Fill(eFixedNumberOfRandomlySelectedTracks, static_cast(tc.fFixedNumberOfRandomlySelectedTracks)); + yAxisTitle += TString::Format("%d:fSkipTheseRuns = %s; ", static_cast(eSkipTheseRuns), tc.fSkipTheseRuns.Data()); - fBasePro->GetXaxis()->SetBinLabel(eUseStopwatch, "fUseStopwatch"); - fBasePro->Fill(eUseStopwatch, static_cast(tc.fUseStopwatch)); + yAxisTitle += TString::Format("%d:fUseSetBinLabel; ", static_cast(eUseSetBinLabel)); + fBasePro->Fill(eUseSetBinLabel, static_cast(tc.fUseSetBinLabel)); - fBasePro->GetXaxis()->SetBinLabel(eFloatingPointPrecision, "fFloatingPointPrecision"); - fBasePro->Fill(eFloatingPointPrecision, tc.fFloatingPointPrecision); + yAxisTitle += TString::Format("%d:fUseClone; ", static_cast(eUseClone)); + fBasePro->Fill(eUseClone, static_cast(tc.fUseClone)); - fBasePro->GetXaxis()->SetBinLabel(eSequentialBailout, "fSequentialBailout"); - fBasePro->Fill(eSequentialBailout, static_cast(tc.fSequentialBailout)); + yAxisTitle += TString::Format("%d:fUseFormula; ", static_cast(eUseFormula)); + fBasePro->Fill(eUseFormula, static_cast(tc.fUseFormula)); - fBasePro->GetXaxis()->SetBinLabel(eUseSpecificCuts, "fUseSpecificCuts"); - fBasePro->Fill(eUseSpecificCuts, static_cast(tc.fUseSpecificCuts)); + // ... - fBasePro->GetXaxis()->SetBinLabel(eWhichSpecificCuts, Form("WhichSpecificCuts = %s", tc.fWhichSpecificCuts.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() != 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; - fBasePro->GetXaxis()->SetBinLabel(eSkipTheseRuns, Form("SkipTheseRuns = %s", tc.fSkipTheseRuns.Data())); + // *) Okay, set the title: + fBasePro->GetYaxis()->SetTitle(yAxisTitle.Data()); + } // else + + // e) Add configured base TProfile to the list: fBaseList->Add(fBasePro); if (tc.fVerbose) { @@ -146,6 +261,7 @@ void DefaultConfiguration() tc.fTaskName = TString(cf_tc.cfTaskName); tc.fDryRun = cf_tc.cfDryRun; tc.fVerbose = cf_tc.cfVerbose; + if (tc.fVerbose) { StartFunction(__FUNCTION__); // yes, here } @@ -228,6 +344,9 @@ void DefaultConfiguration() 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; // *) Event histograms (for QA see below): eh.fEventHistogramsName[eNumberOfEvents] = "NumberOfEvents"; @@ -1424,35 +1543,35 @@ void DefaultBinning() // e) Variable-length binning set via MuPa-Configurables.h: // *) Variable-length binning vs. multiplicity: - if (cf_res.cfUseVariableLength_mult_bins) { + if (cf_res.cfUseVariableLengthMultBins) { this->InitializeVariableLengthBins(AFO_MULTIPLICITY); } // *) Variable-length binning vs. centrality: - if (cf_res.cfUseVariableLength_cent_bins) { + if (cf_res.cfUseVariableLengthCentBins) { this->InitializeVariableLengthBins(AFO_CENTRALITY); } // *) Variable-length binning vs. pt: - if (cf_res.cfUseVariableLength_pt_bins) { + if (cf_res.cfUseVariableLengthPtBins) { this->InitializeVariableLengthBins(AFO_PT); } // *) Variable-length binning vs. eta: - if (cf_res.cfUseVariableLength_eta_bins) { + if (cf_res.cfUseVariableLengthEtaBins) { this->InitializeVariableLengthBins(AFO_ETA); } // *) Variable-length binning vs. occupancy: - if (cf_res.cfUseVariableLength_occu_bins) { + if (cf_res.cfUseVariableLengthOccuBins) { this->InitializeVariableLengthBins(AFO_OCCUPANCY); } // *) Variable-length binning vs. interaction rate: - if (cf_res.cfUseVariableLength_ir_bins) { + if (cf_res.cfUseVariableLengthIRBins) { this->InitializeVariableLengthBins(AFO_INTERACTIONRATE); } // *) Variable-length binning vs. run duration: - if (cf_res.cfUseVariableLength_crd_bins) { + if (cf_res.cfUseVariableLengthCRDBins) { this->InitializeVariableLengthBins(AFO_CURRENTRUNDURATION); } // *) Variable-length binning vs. vertex z position: - if (cf_res.cfUseVariableLength_vz_bins) { + if (cf_res.cfUseVariableLengthVzBins) { this->InitializeVariableLengthBins(AFO_VZ); } @@ -1478,35 +1597,35 @@ void InitializeFixedLengthBins(eAsFunctionOf AFO) switch (AFO) { case AFO_MULTIPLICITY: { - lFixedLength_bins = cf_res.cfFixedLength_mult_bins.value; + lFixedLength_bins = cf_res.cfFixedLengthMultBins.value; break; } case AFO_CENTRALITY: { - lFixedLength_bins = cf_res.cfFixedLength_cent_bins.value; + lFixedLength_bins = cf_res.cfFixedLengthCentBins.value; break; } case AFO_PT: { - lFixedLength_bins = cf_res.cfFixedLength_pt_bins.value; + lFixedLength_bins = cf_res.cfFixedLengthPtBins.value; break; } case AFO_ETA: { - lFixedLength_bins = cf_res.cfFixedLength_eta_bins.value; + lFixedLength_bins = cf_res.cfFixedLengthEtaBins.value; break; } case AFO_OCCUPANCY: { - lFixedLength_bins = cf_res.cfFixedLength_occu_bins.value; + lFixedLength_bins = cf_res.cfFixedLengthOccuBins.value; break; } case AFO_INTERACTIONRATE: { - lFixedLength_bins = cf_res.cfFixedLength_ir_bins.value; + lFixedLength_bins = cf_res.cfFixedLengthIRBins.value; break; } case AFO_CURRENTRUNDURATION: { - lFixedLength_bins = cf_res.cfFixedLength_crd_bins.value; + lFixedLength_bins = cf_res.cfFixedLengthCRDBins.value; break; } case AFO_VZ: { - lFixedLength_bins = cf_res.cfFixedLength_vz_bins.value; + lFixedLength_bins = cf_res.cfFixedLengthVzBins.value; break; } // ... @@ -1550,35 +1669,35 @@ void InitializeVariableLengthBins(eAsFunctionOf AFO) switch (AFO) { case AFO_MULTIPLICITY: { - lVariableLength_bins = cf_res.cfVariableLength_mult_bins.value; + lVariableLength_bins = cf_res.cfVariableLengthMultBins.value; break; } case AFO_CENTRALITY: { - lVariableLength_bins = cf_res.cfVariableLength_cent_bins.value; + lVariableLength_bins = cf_res.cfVariableLengthCentBins.value; break; } case AFO_PT: { - lVariableLength_bins = cf_res.cfVariableLength_pt_bins.value; + lVariableLength_bins = cf_res.cfVariableLengthPtBins.value; break; } case AFO_ETA: { - lVariableLength_bins = cf_res.cfVariableLength_eta_bins.value; + lVariableLength_bins = cf_res.cfVariableLengthEtaBins.value; break; } case AFO_OCCUPANCY: { - lVariableLength_bins = cf_res.cfVariableLength_occu_bins.value; + lVariableLength_bins = cf_res.cfVariableLengthOccuBins.value; break; } case AFO_INTERACTIONRATE: { - lVariableLength_bins = cf_res.cfVariableLength_ir_bins.value; + lVariableLength_bins = cf_res.cfVariableLengthIRBins.value; break; } case AFO_CURRENTRUNDURATION: { - lVariableLength_bins = cf_res.cfVariableLength_crd_bins.value; + lVariableLength_bins = cf_res.cfVariableLengthCRDBins.value; break; } case AFO_VZ: { - lVariableLength_bins = cf_res.cfVariableLength_vz_bins.value; + lVariableLength_bins = cf_res.cfVariableLengthVzBins.value; break; } // ... @@ -2899,13 +3018,10 @@ void InsanityChecksAfterBooking() // 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 (TString(fBasePro->GetXaxis()->GetBinLabel(eConfiguration_N - 1)).EqualTo("")) { - LOGF(fatal, "\033[1;31m%s at line %d : The very last bin of \"fBasePro\" doesn't have the title, check the booking of this hostogram. \033[0m", __FUNCTION__, __LINE__); - } - if (TMath::Abs(fBasePro->GetBinContent(0)) > 0.) { + 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 (TMath::Abs(fBasePro->GetBinContent(eConfiguration_N)) > 0.) { + 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__); } @@ -3172,22 +3288,66 @@ void BookQAHistograms() qa.fQAHistogramsPro->SetStats(false); qa.fQAHistogramsPro->SetLineColor(eColor); qa.fQAHistogramsPro->SetFillColor(eFillColor); - 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)); - // ... + 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); @@ -3846,18 +4006,8 @@ void BookQAHistograms() TString::Format("fParticleEventProEbyE[%s][%s]", gc.srs[rs].Data(), gc.sba[ba].Data()), TString::Format("%s, %s", gc.srs_long[rs].Data(), gc.sba_long[ba].Data()), eQAParticleEventProEbyE_N, 0., eQAParticleEventProEbyE_N); - qa.fQAParticleEventProEbyE[rs][ba]->GetXaxis()->SetBinLabel(eitsNClsEbyE, "#LTitsNCls#GT"); // TBI 20241214 this bin labeling is not really needed, as I never save this TProfile persistently - qa.fQAParticleEventProEbyE[rs][ba]->GetXaxis()->SetBinLabel(eitsNClsNegEtaEbyE, "#LTitsNClsNegEta#GT"); - qa.fQAParticleEventProEbyE[rs][ba]->GetXaxis()->SetBinLabel(eitsNClsPosEtaEbyE, "#LTitsNClsPosEta#GT"); - qa.fQAParticleEventProEbyE[rs][ba]->GetXaxis()->SetBinLabel(eEta0804EbyE, "#LTEta0804EbyE#GT"); - qa.fQAParticleEventProEbyE[rs][ba]->GetXaxis()->SetBinLabel(eEta0400EbyE, "#LTEta0400EbyE#GT"); - qa.fQAParticleEventProEbyE[rs][ba]->GetXaxis()->SetBinLabel(eEta0004EbyE, "#LTEta0004EbyE#GT"); - qa.fQAParticleEventProEbyE[rs][ba]->GetXaxis()->SetBinLabel(eEta0408EbyE, "#LTEta0408EbyE#GT"); - qa.fQAParticleEventProEbyE[rs][ba]->GetXaxis()->SetBinLabel(ePt0005EbyE, "#LTPt0005EbyE#GT"); - qa.fQAParticleEventProEbyE[rs][ba]->GetXaxis()->SetBinLabel(ePt0510EbyE, "#LTPt0510EbyE#GT"); - qa.fQAParticleEventProEbyE[rs][ba]->GetXaxis()->SetBinLabel(ePt1050EbyE, "#LTPt1050EbyE#GT"); - } - } + } // for (int ba = 0; ba < 2; ba++) // before/after cuts + } // for (int rs = 0; rs < 2; rs++) // reco/sim // f) Book specific QA 2D "correlations vs." histograms: @@ -4198,9 +4348,37 @@ void BookEventHistograms() eh.fEventHistogramsPro->SetStats(false); eh.fEventHistogramsPro->SetLineColor(eColor); eh.fEventHistogramsPro->SetFillColor(eFillColor); - eh.fEventHistogramsPro->GetXaxis()->SetBinLabel(1, "fFillEventHistograms"); - eh.fEventHistogramsPro->Fill(0.5, static_cast(eh.fFillEventHistograms)); - // ... + + 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: @@ -4271,10 +4449,37 @@ void BookEventCutsHistograms() 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++) { - ec.fEventCutsPro->GetXaxis()->SetBinLabel(1 + cut, ec.fEventCutName[cut].Data()); // Remark: check always if bin labels here correspond to ordering in enum eEventCuts + + 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: @@ -4321,21 +4526,47 @@ void BookEventCutsHistograms() // **) eRefMultVsNContrUp: if (ec.fUseEventCuts[eRefMultVsNContrUp]) { - ec.fEventCutsFormulas[eRefMultVsNContrUp_Formula] = new TFormula("RefMultVsNContrUp_Formula", ec.fsEventCuts[eRefMultVsNContrUp].Data()); - // 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__); - } - } + 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]) { - ec.fEventCutsFormulas[eRefMultVsNContrLow_Formula] = new TFormula("RefMultVsNContrLow_Formula", ec.fsEventCuts[eRefMultVsNContrLow].Data()); - // 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__); + 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__); @@ -4345,6 +4576,79 @@ 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. @@ -4366,9 +4670,36 @@ void BookParticleHistograms() ph.fParticleHistogramsPro->SetLineColor(eColor); ph.fParticleHistogramsPro->SetFillColor(eFillColor); ph.fParticleHistogramsPro->GetXaxis()->SetLabelSize(0.025); - ph.fParticleHistogramsPro->GetXaxis()->SetBinLabel(1, "fFillParticleHistograms"); - ph.fParticleHistogramsPro->Fill(0.5, static_cast(ph.fFillParticleHistograms)); - // ... + + 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: @@ -4701,10 +5032,36 @@ void BookParticleCutsHistograms() 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++) { - pc.fParticleCutsPro->GetXaxis()->SetBinLabel(1 + cut, pc.fParticleCutName[cut].Data()); // Remark: check always if bin labels here correspond to ordering in enum eParticleCuts + 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: @@ -4734,7 +5091,7 @@ void BookParticleCutsHistograms() continue; } - pc.fParticleCutCounterHist[rs][cc] = new TH1I(TString::Format("fParticleCutCounterHist[%s][%s]", gc.srs[rs].Data(), gc.scc[cc].Data()), TString::Format("%s, %s, particle cut counter (%s)", "__RUN_NUMBER__", gc.srs_long[rs].Data(), gc.scc_long[cc].Data()), eParticleCuts_N, 0.5, static_cast(eParticleCuts_N) + 0.5); + 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.srs_long[rs].Data(), gc.scc_long[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); @@ -4751,6 +5108,9 @@ void BookParticleCutsHistograms() // 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__); @@ -4784,12 +5144,47 @@ void BookQvectorHistograms() qv.fQvectorFlagsPro->SetLineColor(eColor); qv.fQvectorFlagsPro->SetFillColor(eFillColor); qv.fQvectorFlagsPro->GetXaxis()->SetLabelSize(0.05); - 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); + + 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) Book multiplicity distributions in A and B, for each eta separation: @@ -4857,9 +5252,36 @@ void BookCorrelationsHistograms() mupa.fCorrelationsFlagsPro->SetLineColor(eColor); mupa.fCorrelationsFlagsPro->SetFillColor(eFillColor); mupa.fCorrelationsFlagsPro->GetXaxis()->SetLabelSize(0.05); - mupa.fCorrelationsFlagsPro->GetXaxis()->SetBinLabel(1, "fCalculateCorrelations"); - mupa.fCorrelationsFlagsPro->Fill(0.5, mupa.fCalculateCorrelations); - // ... + + 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) { @@ -4913,7 +5335,20 @@ void BookCorrelationsHistograms() if (!res.fResultsPro[v]) { LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); } - mupa.fCorrelationsPro[k][n][v] = reinterpret_cast(res.fResultsPro[v]->Clone(Form("fCorrelationsPro[%d][%d][%s]", k, n, res.fResultsProRawName[v].Data()))); // yes + + 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 { + // TBI 20250412 this branch is temporary workaround until hist->Clone(...) large memory consumption is resolved + if (res.fUseResultsProVariableLengthBins[v]) { + // per demand, variable-length binning: + mupa.fCorrelationsPro[k][n][v] = new TProfile(Form("fCorrelationsPro[%d][%d][%s]", k, n, res.fResultsProRawName[v].Data()), "", res.fResultsProVariableLengthBins[v]->GetSize() - 1, res.fResultsProVariableLengthBins[v]->GetArray()); + } else { + // the default fixed-length binning: + mupa.fCorrelationsPro[k][n][v] = new TProfile(Form("fCorrelationsPro[%d][%d][%s]", k, n, res.fResultsProRawName[v].Data()), "", static_cast(res.fResultsProFixedLengthBins[v][0]), res.fResultsProFixedLengthBins[v][1], res.fResultsProFixedLengthBins[v][2]); + } // else + } // else + 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())); @@ -4958,25 +5393,69 @@ void BookWeightsHistograms() pw.fWeightsFlagsPro->SetLineColor(eColor); pw.fWeightsFlagsPro->SetFillColor(eFillColor); pw.fWeightsFlagsPro->GetXaxis()->SetLabelSize(0.035); - 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)}"); + if (tc.fUseSetBinLabel) { - // **) differential pt weights using sparse: - pw.fWeightsFlagsPro->GetXaxis()->SetBinLabel(12, "(w_{p_{T}})_{pt axis (sparse)}"); + 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 eta weights using sparse: - pw.fWeightsFlagsPro->GetXaxis()->SetBinLabel(13, "(w_{#eta})_{eta axis (sparse)}"); + // **) 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); + + // **) differential eta weights using sparse: + yAxisTitle += TString::Format("%d:(w_{#eta})_{eta axis (sparse)}; ", 13); + + // ... + + // *) 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] { @@ -5062,7 +5541,33 @@ void BookCentralityWeightsHistograms() cw.fCentralityWeightsFlagsPro->SetLineColor(eColor); cw.fCentralityWeightsFlagsPro->SetFillColor(eFillColor); cw.fCentralityWeightsFlagsPro->GetXaxis()->SetLabelSize(0.05); - cw.fCentralityWeightsFlagsPro->GetXaxis()->SetBinLabel(1, TString::Format("Use centrality weights for estimator %s", ec.fsEventCuts[eCentralityEstimator].Data())); + + 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? } @@ -5101,14 +5606,50 @@ void BookNestedLoopsHistograms() nl.fNestedLoopsFlagsPro->SetLineColor(eColor); nl.fNestedLoopsFlagsPro->SetFillColor(eFillColor); nl.fNestedLoopsFlagsPro->GetXaxis()->SetLabelSize(0.03); - 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); + + 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)) { @@ -5159,7 +5700,20 @@ void BookNestedLoopsHistograms() if (!res.fResultsPro[v]) { LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); } - nl.fNestedLoopsPro[k][n][v] = reinterpret_cast(res.fResultsPro[v]->Clone(Form("fNestedLoopsPro[%d][%d][%d]", k, n, v))); // yes + + if (tc.fUseClone) { + nl.fNestedLoopsPro[k][n][v] = reinterpret_cast(res.fResultsPro[v]->Clone(Form("fNestedLoopsPro[%d][%d][%d]", k, n, v))); // yes + } else { + // TBI 20250412 this branch is temporary workaround until hist->Clone(...) large memory consumption is resolved + if (res.fUseResultsProVariableLengthBins[v]) { + // per demand, variable-length binning: + nl.fNestedLoopsPro[k][n][v] = new TProfile(Form("fNestedLoopsPro[%d][%d][%s]", k, n, res.fResultsProRawName[v].Data()), "", res.fResultsProVariableLengthBins[v]->GetSize() - 1, res.fResultsProVariableLengthBins[v]->GetArray()); + } else { + // the default fixed-length binning: + nl.fNestedLoopsPro[k][n][v] = new TProfile(Form("fNestedLoopsPro[%d][%d][%s]", k, n, res.fResultsProRawName[v].Data()), "", static_cast(res.fResultsProFixedLengthBins[v][0]), res.fResultsProFixedLengthBins[v][1], res.fResultsProFixedLengthBins[v][2]); + } // else + } // else + 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(); @@ -5217,10 +5771,46 @@ void BookNUAHistograms() 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... - 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]"); + 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.); } @@ -5230,9 +5820,6 @@ void BookNUAHistograms() if (nua.fApplyNUAPDF[eEtaNUAPDF]) { nua.fNUAFlagsPro->Fill(static_cast(1 + eEtaNUAPDF), 1.); } - 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]"); if (nua.fUseDefaultNUAPDF[ePhiNUAPDF]) { nua.fNUAFlagsPro->Fill(static_cast(4 + ePhiNUAPDF), 1.); } @@ -5362,14 +5949,45 @@ void BookInternalValidationHistograms() iv.fInternalValidationFlagsPro->GetXaxis()->SetLabelSize(0.04); iv.fInternalValidationList->Add(iv.fInternalValidationFlagsPro); - 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, TString::Format("option = %s", iv.fHarmonicsOptionInternalValidation->Data())); - iv.fInternalValidationFlagsPro->Fill(3.5, 1); // redundant, because here I only care about bin label, but preserves symmetry in this code snippet... + 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, 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:option = %s; ", 4, 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) { @@ -5452,7 +6070,7 @@ TComplex TheoreticalValue(TArrayI* harmonics, TArrayD* amplitudes, TArrayD* plan 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(TMath::Abs(harmonics->GetAt(h)) - 1), 1. * harmonics->GetAt(h) * planes->GetAt(TMath::Abs(harmonics->GetAt(h)) - 1), true); + 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: @@ -5519,7 +6137,7 @@ void InternalValidation() // 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]*TMath::Cos(x-[1]-[18]) + 2.*[2]*TMath::Cos(2.*(x-[3]-[18])) + 2.*[4]*TMath::Cos(3.*(x-[5]-[18])) + 2.*[6]*TMath::Cos(4.*(x-[7]-[18])) + 2.*[8]*TMath::Cos(5.*(x-[9]-[18])) + 2.*[10]*TMath::Cos(6.*(x-[11]-[18])) + 2.*[12]*TMath::Cos(7.*(x-[13]-[18])) + 2.*[14]*TMath::Cos(8.*(x-[15]-[18])) + 2.*[16]*TMath::Cos(9.*(x-[17]-[18]))", 0., o2::constants::math::TwoPI); + fPhiPDF = new TF1("fPhiPDF", "1 + 2.*[0]*cos(x-[1]-[18]) + 2.*[2]*cos(2.*(x-[3]-[18])) + 2.*[4]*cos(3.*(x-[5]-[18])) + 2.*[6]*cos(4.*(x-[7]-[18])) + 2.*[8]*cos(5.*(x-[9]-[18])) + 2.*[10]*cos(6.*(x-[11]-[18])) + 2.*[12]*cos(7.*(x-[13]-[18])) + 2.*[14]*cos(8.*(x-[15]-[18])) + 2.*[16]*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 @@ -5552,7 +6170,7 @@ void InternalValidation() // 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]*TMath::Cos(x-[3]) + 2.*[1]*TMath::Cos(2.*(x-[3])) + 2.*[2]*TMath::Cos(3.*(x-[3]))", 0., o2::constants::math::TwoPI); + fPhiPDF = new TF1("fPhiPDF", "1 + 2.*[0]*cos(x-[3]) + 2.*[1]*cos(2.*(x-[3])) + 2.*[2]*cos(3.*(x-[3]))", 0., o2::constants::math::TwoPI); // With this parameterization, I have: // [0] => v1 // [1] => v2 @@ -5577,7 +6195,7 @@ void InternalValidation() // 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]*TMath::Cos(x-[3]) + 2.*[1]*TMath::Cos(2.*(x-[4])) + 2.*[2]*TMath::Cos(3.*(x-[5]))", 0., o2::constants::math::TwoPI); + fPhiPDF = new TF1("fPhiPDF", "1 + 2.*[0]*cos(x-[3]) + 2.*[1]*cos(2.*(x-[4])) + 2.*[2]*cos(3.*(x-[5]))", 0., o2::constants::math::TwoPI); // With this parameterization, I have: // [0] => v1 // [1] => v2 @@ -5882,9 +6500,8 @@ void BookTest0Histograms() // a) Book the profile holding flags; // b) Book placeholder and make sure all labels are stored in the placeholder; - // c) Retrieve labels from placeholder; - // d) Book what needs to be booked; - // e) Few quick insanity checks on booking. + // c) Book what needs to be booked; + // d) Few quick insanity checks on booking. if (tc.fVerbose) { StartFunction(__FUNCTION__); @@ -5894,7 +6511,37 @@ void BookTest0Histograms() t0.fTest0FlagsPro = new TProfile("fTest0FlagsPro", "flags for Test0", 1, 0., 1.); t0.fTest0FlagsPro->SetStats(false); t0.fTest0FlagsPro->GetXaxis()->SetLabelSize(0.04); - t0.fTest0FlagsPro->GetXaxis()->SetBinLabel(1, "fCalculateTest0"); + + if (tc.fUseSetBinLabel) { + t0.fTest0FlagsPro->GetXaxis()->SetBinLabel(1, "fCalculateTest0"); + + // ... + + } else { + // Workaround for SetBinLabel() large memory consumption: + TString yAxisTitle = ""; + + yAxisTitle += TString::Format("%d:fCalculateTest0; ", 1); + t0.fTest0FlagsPro->Fill(0.5, static_cast(t0.fCalculateTest0)); + + // ... + + // *) 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, t0.fCalculateTest0); t0.fTest0List->Add(t0.fTest0FlagsPro); @@ -5904,16 +6551,8 @@ void BookTest0Histograms() // b) Book placeholder and make sure all labels are stored in the placeholder: this->StoreLabelsInPlaceholder(); - if (t0.fTest0LabelsPlaceholder) { - t0.fTest0List->Add(t0.fTest0LabelsPlaceholder); - } - - // c) Retrieve labels from placeholder: - if (!(this->RetrieveCorrelationsLabels())) { - LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); - } - // d) Book what needs to be booked: + // c) Book what needs to be booked: for (int mo = 0; mo < gMaxCorrelator; mo++) { for (int mi = 0; mi < gMaxIndex; mi++) { if (!t0.fTest0Labels[mo][mi]) { @@ -5954,18 +6593,25 @@ void BookTest0Histograms() LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); } - t0.fTest0Pro[mo][mi][v] = reinterpret_cast(res.fResultsPro[v]->Clone(Form("fTest0Pro[%d][%d][%s]", mo, mi, res.fResultsProRawName[v].Data()))); // yes + 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 { + // TBI 20250412 this branch is temporary workaround until hist->Clone(...) large memory consumption is resolved + if (res.fUseResultsProVariableLengthBins[v]) { + // per demand, variable-length binning: + t0.fTest0Pro[mo][mi][v] = new TProfile(Form("fTest0Pro[%d][%d][%s]", mo, mi, res.fResultsProRawName[v].Data()), "", res.fResultsProVariableLengthBins[v]->GetSize() - 1, res.fResultsProVariableLengthBins[v]->GetArray()); + } else { + // the default fixed-length binning: + t0.fTest0Pro[mo][mi][v] = new TProfile(Form("fTest0Pro[%d][%d][%s]", mo, mi, res.fResultsProRawName[v].Data()), "", static_cast(res.fResultsProFixedLengthBins[v][0]), res.fResultsProFixedLengthBins[v][1], res.fResultsProFixedLengthBins[v][2]); + } // else + } // else + 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())); - /* - if(fUseFixedNumberOfRandomlySelectedParticles && 1==v) // just a warning for the meaning of multiplicity in this special case - { - fTest0Pro[mo][mi][1]->GetXaxis()->SetTitle("WARNING: for each multiplicity, fFixedNumberOfRandomlySelectedParticles is selected randomly in Q-vector"); - } - */ t0.fTest0List->Add(t0.fTest0Pro[mo][mi][v]); // yes, this has to be here + } // for(int v=0;vSetLineColor(eColor); es.fEtaSeparationsFlagsPro->SetFillColor(eFillColor); es.fEtaSeparationsFlagsPro->GetXaxis()->SetLabelSize(0.04); - es.fEtaSeparationsFlagsPro->GetXaxis()->SetBinLabel(1, "fCalculateEtaSeparations"); + + 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); @@ -6053,7 +6728,19 @@ void BookEtaSeparationsHistograms() LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); } - es.fEtaSeparationsPro[h][e][v] = reinterpret_cast(res.fResultsPro[v]->Clone(Form("fEtaSeparationsPro[%d][%d][%s]", h, e, res.fResultsProRawName[v].Data()))); // yes + 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 { + // TBI 20250412 this branch is temporary workaround until hist->Clone(...) large memory consumption is resolved + if (res.fUseResultsProVariableLengthBins[v]) { + // per demand, variable-length binning: + es.fEtaSeparationsPro[h][e][v] = new TProfile(Form("fEtaSeparationsPro[%d][%d][%s]", h, e, res.fResultsProRawName[v].Data()), "", res.fResultsProVariableLengthBins[v]->GetSize() - 1, res.fResultsProVariableLengthBins[v]->GetArray()); + } else { + // the default fixed-length binning: + es.fEtaSeparationsPro[h][e][v] = new TProfile(Form("fEtaSeparationsPro[%d][%d][%s]", h, e, res.fResultsProRawName[v].Data()), "", static_cast(res.fResultsProFixedLengthBins[v][0]), res.fResultsProFixedLengthBins[v][1], res.fResultsProFixedLengthBins[v][2]); + } // else + } // else + 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])); @@ -6095,9 +6782,35 @@ void BookResultsHistograms() res.fResultsFlagsPro->SetStats(false); res.fResultsFlagsPro->SetLineColor(eColor); res.fResultsFlagsPro->SetFillColor(eFillColor); - res.fResultsFlagsPro->GetXaxis()->SetBinLabel(1, "fSaveResultsHistograms"); - res.fResultsFlagsPro->Fill(0.5, res.fSaveResultsHistograms); - // ... + + 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 results histograms, which in addition act as a sort of "abstract" interface, which defines common binning, etc., for other groups of histograms: @@ -6177,6 +6890,7 @@ void Preprocess(T1 const& collision, T2 const& bcs) DetermineRunNumber(collision, bcs); PropagateRunNumber(); } + if (tc.fDoAdditionalInsanityChecks && tc.fRunNumberIsDetermined) { CheckCurrentRunNumber(collision, bcs); } @@ -6198,6 +6912,7 @@ void Preprocess(T1 const& collision, T2 const& bcs) // 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; } @@ -6308,7 +7023,13 @@ void PropagateRunNumber() } // *) base: - fBasePro->GetXaxis()->SetBinLabel(eRunNumber, Form("fRunNumber = %s", tc.fRunNumber.Data())); + 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 = ""; @@ -6556,6 +7277,7 @@ void CheckCurrentRunNumber(T1 const& collision, T2 const&) 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__); @@ -6786,18 +7508,48 @@ void EventCutsCounters(T1 const& collision, T2 const& tracks) if (!ec.fEventCutCounterHist[rec_sim][cc]) { continue; } - 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, 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 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... - } + + 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])); } @@ -6845,7 +7597,7 @@ 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. TMath::Abs(ebye.fCentrality - ec.fdEventCuts[eCentrality][eMax]) < tc.fFloatingPointPrecision , + // 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); @@ -6908,7 +7660,7 @@ bool EventCuts(T1 const& collision, T2 const& tracks, eCutModus cutModus) 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] || TMath::Abs(tracks.size() - ec.fdEventCuts[eTotalMultiplicity][eMax]) < tc.fFloatingPointPrecision) { + } 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; } @@ -6924,7 +7676,7 @@ bool EventCuts(T1 const& collision, T2 const& tracks, eCutModus cutModus) 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] || TMath::Abs(ebye.fReferenceMultiplicity - ec.fdEventCuts[eReferenceMultiplicity][eMax]) < tc.fFloatingPointPrecision) { + } 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; } @@ -6936,7 +7688,7 @@ bool EventCuts(T1 const& collision, T2 const& tracks, eCutModus cutModus) 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] || TMath::Abs(ebye.fCentrality - ec.fdEventCuts[eCentrality][eMax]) < tc.fFloatingPointPrecision) { + } 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; } @@ -6947,7 +7699,7 @@ bool EventCuts(T1 const& collision, T2 const& tracks, eCutModus cutModus) 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] || TMath::Abs(collision.posX() - ec.fdEventCuts[eVertexX][eMax]) < tc.fFloatingPointPrecision) { + } 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; } @@ -6958,7 +7710,7 @@ bool EventCuts(T1 const& collision, T2 const& tracks, eCutModus cutModus) 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] || TMath::Abs(collision.posY() - ec.fdEventCuts[eVertexY][eMax]) < tc.fFloatingPointPrecision) { + } 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; } @@ -6969,7 +7721,7 @@ bool EventCuts(T1 const& collision, T2 const& tracks, eCutModus cutModus) 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] || TMath::Abs(collision.posZ() - ec.fdEventCuts[eVertexZ][eMax]) < tc.fFloatingPointPrecision) { + } 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; } @@ -6991,7 +7743,7 @@ bool EventCuts(T1 const& collision, T2 const& tracks, eCutModus cutModus) 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] || TMath::Abs(collision.numContrib() - ec.fdEventCuts[eNContributors][eMax]) < tc.fFloatingPointPrecision) { + } 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; } @@ -7002,7 +7754,7 @@ bool EventCuts(T1 const& collision, T2 const& tracks, eCutModus cutModus) if (ec.fUseEventCuts[eRefMultVsNContrUp]) { if (cutModus == eCutCounterBinning) { EventCut(eRec, eRefMultVsNContrUp, eCutCounterBinning); - } else if (collision.numContrib() > ec.fEventCutsFormulas[eRefMultVsNContrUp_Formula]->Eval(ebye.fReferenceMultiplicity)) { + } 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; } @@ -7013,7 +7765,7 @@ bool EventCuts(T1 const& collision, T2 const& tracks, eCutModus cutModus) if (ec.fUseEventCuts[eRefMultVsNContrLow]) { if (cutModus == eCutCounterBinning) { EventCut(eRec, eRefMultVsNContrLow, eCutCounterBinning); - } else if (collision.numContrib() < ec.fEventCutsFormulas[eRefMultVsNContrLow_Formula]->Eval(ebye.fReferenceMultiplicity)) { + } 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; } @@ -7064,7 +7816,7 @@ bool EventCuts(T1 const& collision, T2 const& tracks, eCutModus cutModus) 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] || TMath::Abs(collision.impactParameter() - ec.fdEventCuts[eImpactParameter][eMax]) < tc.fFloatingPointPrecision) { + } 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; } @@ -7075,7 +7827,7 @@ bool EventCuts(T1 const& collision, T2 const& tracks, eCutModus cutModus) 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] || TMath::Abs(collision.eventPlaneAngle() - ec.fdEventCuts[eEventPlaneAngle][eMax]) < tc.fFloatingPointPrecision) { + } 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; } @@ -7094,7 +7846,7 @@ bool EventCuts(T1 const& collision, T2 const& tracks, eCutModus cutModus) 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] || TMath::Abs(collision.posX() - ec.fdEventCuts[eVertexX][eMax]) < tc.fFloatingPointPrecision) { + } 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; } @@ -7105,7 +7857,7 @@ bool EventCuts(T1 const& collision, T2 const& tracks, eCutModus cutModus) 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] || TMath::Abs(collision.posY() - ec.fdEventCuts[eVertexY][eMax]) < tc.fFloatingPointPrecision) { + } 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; } @@ -7116,7 +7868,7 @@ bool EventCuts(T1 const& collision, T2 const& tracks, eCutModus cutModus) 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] || TMath::Abs(collision.posZ() - ec.fdEventCuts[eVertexZ][eMax]) < tc.fFloatingPointPrecision) { + } 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; } @@ -7157,7 +7909,7 @@ bool EventCuts(T1 const& collision, T2 const& tracks, eCutModus cutModus) 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] || TMath::Abs(ebye.fOccupancy - ec.fdEventCuts[eOccupancy][eMax]) < tc.fFloatingPointPrecision) { + } 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; } @@ -7168,7 +7920,7 @@ bool EventCuts(T1 const& collision, T2 const& tracks, eCutModus cutModus) 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] || TMath::Abs(ebye.fInteractionRate - ec.fdEventCuts[eInteractionRate][eMax]) < tc.fFloatingPointPrecision) { + } 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; } @@ -7179,7 +7931,7 @@ bool EventCuts(T1 const& collision, T2 const& tracks, eCutModus cutModus) 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] || TMath::Abs(ebye.fCurrentRunDuration - ec.fdEventCuts[eCurrentRunDuration][eMax]) < tc.fFloatingPointPrecision) { + } 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; } @@ -7488,7 +8240,7 @@ bool EventCuts(T1 const& collision, T2 const& tracks, eCutModus cutModus) 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] || TMath::Abs(tracks.size() - ec.fdEventCuts[eTotalMultiplicity][eMax]) < tc.fFloatingPointPrecision) { + } 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; } @@ -7499,7 +8251,7 @@ bool EventCuts(T1 const& collision, T2 const& tracks, eCutModus cutModus) 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] || TMath::Abs(collision.posZ() - ec.fdEventCuts[eVertexZ][eMax]) < tc.fFloatingPointPrecision) { + } 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; } @@ -7510,7 +8262,7 @@ bool EventCuts(T1 const& collision, T2 const& tracks, eCutModus cutModus) 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] || TMath::Abs(ebye.fCentrality - ec.fdEventCuts[eCentrality][eMax]) < tc.fFloatingPointPrecision) { + } 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; } @@ -7609,7 +8361,7 @@ bool RemainingEventCuts() // *) 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] || TMath::Abs(ebye.fMultiplicity - ec.fdEventCuts[eMultiplicity][eMax]) < tc.fFloatingPointPrecision) { + 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 @@ -8334,15 +9086,26 @@ bool CentralityCorrelationCut() 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) { + 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 @@ -8353,11 +9116,11 @@ bool CentralityCorrelationCut() // *) ... if (ec.fCentralityValues[0] > 0. && ec.fCentralityValues[1] > 0.) { if (ec.fCentralityCorrelationsCutVersion.EqualTo("Relative")) { - if (TMath::Abs((ec.fCentralityValues[0] - ec.fCentralityValues[1]) / (ec.fCentralityValues[0] + ec.fCentralityValues[1])) > ec.fCentralityCorrelationsCutTreshold) { + 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 (TMath::Abs((ec.fCentralityValues[0] - ec.fCentralityValues[1])) > ec.fCentralityCorrelationsCutTreshold) { + if (std::abs((ec.fCentralityValues[0] - ec.fCentralityValues[1])) > ec.fCentralityCorrelationsCutTreshold) { alright = false; } } else { @@ -8399,17 +9162,47 @@ void ParticleCutsCounters(T const& track) if (!pc.fParticleCutCounterHist[rec_sim][cc]) { continue; } - 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... + + 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])); @@ -8445,7 +9238,7 @@ 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. TMath::Abs(track.eta() - pc.fdParticleCuts[eEta][eMax]) < tc.fFloatingPointPrecision , + // 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); @@ -8470,7 +9263,7 @@ bool ParticleCuts(T const& track, eCutModus cutModus) 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] || TMath::Abs(track.phi() - pc.fdParticleCuts[ePhi][eMax]) < tc.fFloatingPointPrecision) { + } 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; } @@ -8481,7 +9274,7 @@ bool ParticleCuts(T const& track, eCutModus cutModus) 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] || TMath::Abs(track.pt() - pc.fdParticleCuts[ePt][eMax]) < tc.fFloatingPointPrecision) { + } 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; } @@ -8492,7 +9285,7 @@ bool ParticleCuts(T const& track, eCutModus cutModus) 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] || TMath::Abs(track.eta() - pc.fdParticleCuts[eEta][eMax]) < tc.fFloatingPointPrecision) { + } 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; } @@ -8593,7 +9386,7 @@ bool ParticleCuts(T const& track, eCutModus cutModus) 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] || TMath::Abs(track.tpcCrossedRowsOverFindableCls() - pc.fdParticleCuts[etpcCrossedRowsOverFindableCls][eMax]) < tc.fFloatingPointPrecision) { + } 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; } @@ -8604,7 +9397,7 @@ bool ParticleCuts(T const& track, eCutModus cutModus) 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] || TMath::Abs(track.tpcFoundOverFindableCls() - pc.fdParticleCuts[etpcFoundOverFindableCls][eMax]) < tc.fFloatingPointPrecision) { + } 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; } @@ -8615,7 +9408,7 @@ bool ParticleCuts(T const& track, eCutModus cutModus) 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] || TMath::Abs(track.tpcFractionSharedCls() - pc.fdParticleCuts[etpcFractionSharedCls][eMax]) < tc.fFloatingPointPrecision) { + } 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; } @@ -8626,7 +9419,7 @@ bool ParticleCuts(T const& track, eCutModus cutModus) 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] || TMath::Abs(track.tpcChi2NCl() - pc.fdParticleCuts[etpcChi2NCl][eMax]) < tc.fFloatingPointPrecision) { + } 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; } @@ -8637,7 +9430,7 @@ bool ParticleCuts(T const& track, eCutModus cutModus) 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] || TMath::Abs(track.dcaXY() - pc.fdParticleCuts[edcaXY][eMax]) < tc.fFloatingPointPrecision) { + } 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; } @@ -8648,7 +9441,7 @@ bool ParticleCuts(T const& track, eCutModus cutModus) 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] || TMath::Abs(track.dcaZ() - pc.fdParticleCuts[edcaZ][eMax]) < tc.fFloatingPointPrecision) { + } 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; } @@ -8747,7 +9540,7 @@ bool ParticleCuts(T const& track, eCutModus cutModus) if (pc.fUseParticleCuts[ePtDependentDCAxyParameterization]) { if (cutModus == eCutCounterBinning) { ParticleCut(eRec, ePtDependentDCAxyParameterization, eCutCounterBinning); - } else if (TMath::Abs(track.dcaXY()) > pc.fPtDependentDCAxyFormula->Eval(track.pt())) { + } else if (std::abs(track.dcaXY()) > pc.fPtDependentDCAxyFormula->Eval(track.pt())) { if (!ParticleCut(eRec, ePtDependentDCAxyParameterization, cutModus)) { return false; } @@ -8814,7 +9607,7 @@ bool ParticleCuts(T const& track, eCutModus cutModus) 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] || TMath::Abs(track.phi() - pc.fdParticleCuts[ePhi][eMax]) < tc.fFloatingPointPrecision) { + } 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; } @@ -8825,7 +9618,7 @@ bool ParticleCuts(T const& track, eCutModus cutModus) 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] || TMath::Abs(track.pt() - pc.fdParticleCuts[ePt][eMax]) < tc.fFloatingPointPrecision) { + } 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; } @@ -8836,7 +9629,7 @@ bool ParticleCuts(T const& track, eCutModus cutModus) 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] || TMath::Abs(track.eta() - pc.fdParticleCuts[eEta][eMax]) < tc.fFloatingPointPrecision) { + } 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; } @@ -8945,7 +9738,7 @@ bool ParticleCuts(T const& track, eCutModus cutModus) 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] || TMath::Abs(track.phi() - pc.fdParticleCuts[ePhi][eMax]) < tc.fFloatingPointPrecision) { + } 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; } @@ -8956,7 +9749,7 @@ bool ParticleCuts(T const& track, eCutModus cutModus) 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] || TMath::Abs(track.pt() - pc.fdParticleCuts[ePt][eMax]) < tc.fFloatingPointPrecision) { + } 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; } @@ -8967,7 +9760,7 @@ bool ParticleCuts(T const& track, eCutModus cutModus) 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] || TMath::Abs(track.eta() - pc.fdParticleCuts[eEta][eMax]) < tc.fFloatingPointPrecision) { + } 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; } @@ -9129,7 +9922,7 @@ void FillParticleHistograms(T const& track, eBeforeAfter ba, int weight = 1) } if (tc.fInsanityCheckForEachParticle) { - if (1 != TMath::Abs(weight)) { + 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); } } @@ -9143,15 +9936,35 @@ void FillParticleHistograms(T const& track, eBeforeAfter ba, int weight = 1) // 1D: if (ph.fFillParticleHistograms) { // From o2::aod::Tracks + + // memStatus ~120 + !ph.fParticleHistograms[ePhi][eRec][ba] ? true : ph.fParticleHistograms[ePhi][eRec][ba]->Fill(track.phi(), weight); + + // memStatus ~125 + !ph.fParticleHistograms[ePt][eRec][ba] ? true : ph.fParticleHistograms[ePt][eRec][ba]->Fill(track.pt(), weight); + + // memStatus ~127 + !ph.fParticleHistograms[eEta][eRec][ba] ? true : ph.fParticleHistograms[eEta][eRec][ba]->Fill(track.eta(), weight); + + // memStatus ~133 + !ph.fParticleHistograms[eCharge][eRec][ba] ? true : ph.fParticleHistograms[eCharge][eRec][ba]->Fill(track.sign(), weight); + // memStatus ~139 + // 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); + + // memStatus ~140 + !ph.fParticleHistograms[eitsChi2NCl][eRec][ba] ? true : ph.fParticleHistograms[eitsChi2NCl][eRec][ba]->Fill(track.itsChi2NCl(), weight); + + // memStatus ~146 + !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); @@ -9502,7 +10315,7 @@ void CalculateCorrelations() harmonics->SetAt(h, 0); harmonics->SetAt(-h, 1); double nestedLoopValue = this->CalculateCustomNestedLoops(harmonics); - if (TMath::Abs(nestedLoopValue) > 0. && TMath::Abs(twoC - nestedLoopValue) > tc.fFloatingPointPrecision) { + 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); @@ -9512,7 +10325,7 @@ void CalculateCorrelations() } // if(nl.fCalculateCustomNestedLoops) // for on-the-fly and internal validation, rescale results with theoretical value: - if (iv.fUseInternalValidation && iv.fRescaleWithTheoreticalInput && iv.fInternalValidationVnPsin[eVn] && TMath::Abs(iv.fInternalValidationVnPsin[eVn]->GetAt(h - 1)) > 0.) { + if (iv.fUseInternalValidation && iv.fRescaleWithTheoreticalInput && iv.fInternalValidationVnPsin[eVn] && std::abs(iv.fInternalValidationVnPsin[eVn]->GetAt(h - 1)) > 0.) { twoC /= pow(iv.fInternalValidationVnPsin[eVn]->GetAt(h - 1), 2.); } @@ -9571,7 +10384,7 @@ void CalculateCorrelations() harmonics->SetAt(-h, 2); harmonics->SetAt(-h, 3); double nestedLoopValue = this->CalculateCustomNestedLoops(harmonics); - if (TMath::Abs(nestedLoopValue) > 0. && TMath::Abs(fourC - nestedLoopValue) > tc.fFloatingPointPrecision) { + 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); @@ -9581,7 +10394,7 @@ void CalculateCorrelations() } // if(nl.fCalculateCustomNestedLoops) // for on-the-fly and internal validation, rescale results with theoretical value: - if (iv.fUseInternalValidation && iv.fRescaleWithTheoreticalInput && iv.fInternalValidationVnPsin[eVn] && TMath::Abs(iv.fInternalValidationVnPsin[eVn]->GetAt(h - 1)) > 0.) { + if (iv.fUseInternalValidation && iv.fRescaleWithTheoreticalInput && iv.fInternalValidationVnPsin[eVn] && std::abs(iv.fInternalValidationVnPsin[eVn]->GetAt(h - 1)) > 0.) { fourC /= pow(iv.fInternalValidationVnPsin[eVn]->GetAt(h - 1), 4.); } @@ -9642,7 +10455,7 @@ void CalculateCorrelations() harmonics->SetAt(-h, 4); harmonics->SetAt(-h, 5); double nestedLoopValue = this->CalculateCustomNestedLoops(harmonics); - if (TMath::Abs(nestedLoopValue) > 0. && TMath::Abs(sixC - nestedLoopValue) > tc.fFloatingPointPrecision) { + 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); @@ -9652,7 +10465,7 @@ void CalculateCorrelations() } // if(nl.fCalculateCustomNestedLoops) // for on-the-fly and internal validation, rescale results with theoretical value: - if (iv.fUseInternalValidation && iv.fRescaleWithTheoreticalInput && iv.fInternalValidationVnPsin[eVn] && TMath::Abs(iv.fInternalValidationVnPsin[eVn]->GetAt(h - 1)) > 0.) { + if (iv.fUseInternalValidation && iv.fRescaleWithTheoreticalInput && iv.fInternalValidationVnPsin[eVn] && std::abs(iv.fInternalValidationVnPsin[eVn]->GetAt(h - 1)) > 0.) { sixC /= pow(iv.fInternalValidationVnPsin[eVn]->GetAt(h - 1), 6.); } @@ -9715,7 +10528,7 @@ void CalculateCorrelations() harmonics->SetAt(-h, 6); harmonics->SetAt(-h, 7); double nestedLoopValue = this->CalculateCustomNestedLoops(harmonics); - if (TMath::Abs(nestedLoopValue) > 0. && TMath::Abs(eightC - nestedLoopValue) > tc.fFloatingPointPrecision) { + 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); @@ -9725,7 +10538,7 @@ void CalculateCorrelations() } // if(nl.fCalculateCustomNestedLoops) // for on-the-fly and internal validation, rescale results with theoretical value: - if (iv.fUseInternalValidation && iv.fRescaleWithTheoreticalInput && iv.fInternalValidationVnPsin[eVn] && TMath::Abs(iv.fInternalValidationVnPsin[eVn]->GetAt(h - 1)) > 0.) { + if (iv.fUseInternalValidation && iv.fRescaleWithTheoreticalInput && iv.fInternalValidationVnPsin[eVn] && std::abs(iv.fInternalValidationVnPsin[eVn]->GetAt(h - 1)) > 0.) { eightC /= pow(iv.fInternalValidationVnPsin[eVn]->GetAt(h - 1), 8.); } @@ -9984,9 +10797,9 @@ void CalculateTest0() harmonics->SetAt(n[i], i); } double nestedLoopValue = this->CalculateCustomNestedLoops(harmonics); - if (!(TMath::Abs(nestedLoopValue) > 0.)) { + 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 (TMath::Abs(nestedLoopValue) > 0. && TMath::Abs(correlation / weight - nestedLoopValue) > tc.fFloatingPointPrecision) { + } 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()); @@ -10002,7 +10815,7 @@ void CalculateTest0() harmonics->SetAt(n[i], i); } TComplex theoreticalValue = this->TheoreticalValue(harmonics, iv.fInternalValidationVnPsin[eVn], iv.fInternalValidationVnPsin[ePsin]); - if (TMath::Abs(theoreticalValue.Re()) > 0.) { + 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... @@ -10092,7 +10905,7 @@ void CalculateKineTest0(eAsFunctionOf AFO_variable) 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] || TMath::Abs(qv.fqVectorEntries[qvKine][b] - ec.fdEventCuts[eMultiplicity][eMax]) < tc.fFloatingPointPrecision)) { + 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)); } @@ -10206,9 +11019,9 @@ void CalculateKineTest0(eAsFunctionOf AFO_variable) 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 (!(TMath::Abs(nestedLoopValue) > 0.)) { + 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 (TMath::Abs(nestedLoopValue) > 0. && TMath::Abs(correlation / weight - nestedLoopValue) > tc.fFloatingPointPrecision) { + } 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); @@ -10224,7 +11037,7 @@ void CalculateKineTest0(eAsFunctionOf AFO_variable) harmonics->SetAt(n[i], i); } TComplex theoreticalValue = TheoreticalValue(harmonics, iv.fInternalValidationVnPsin[eVn], iv.fInternalValidationVnPsin[ePsin]); - if (TMath::Abs(theoreticalValue.Re()) > 0.) { + 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... @@ -10297,7 +11110,7 @@ void CalculateEtaSeparations() 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] && TMath::Abs(iv.fInternalValidationVnPsin[eVn]->GetAt(h)) > 0.) { + if (iv.fUseInternalValidation && iv.fRescaleWithTheoreticalInput && iv.fInternalValidationVnPsin[eVn] && std::abs(iv.fInternalValidationVnPsin[eVn]->GetAt(h)) > 0.) { correlation /= pow(iv.fInternalValidationVnPsin[eVn]->GetAt(h), 2.); } @@ -10386,7 +11199,7 @@ void CalculateKineEtaSeparations(eAsFunctionOf AFO_variable) /* TBI 20241206 Do I need to adapt and apply this cut, also for Qa and Qb? If so, most likely I would need to apply it on sum, i.e. on entries in Qa + Qb // *) 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] || TMath::Abs(qv.fqVectorEntries[qvKine][b] - ec.fdEventCuts[eMultiplicity][eMax]) < tc.fFloatingPointPrecision)) { + 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)); } @@ -10414,7 +11227,7 @@ void CalculateKineEtaSeparations(eAsFunctionOf AFO_variable) weight = qv.fmab[0][b][e] * qv.fmab[1][b][e]; // for on-the-fly and internal validation, rescale results with theoretical value: - if (iv.fUseInternalValidation && iv.fRescaleWithTheoreticalInput && iv.fInternalValidationVnPsin[eVn] && TMath::Abs(iv.fInternalValidationVnPsin[eVn]->GetAt(h)) > 0.) { + if (iv.fUseInternalValidation && iv.fRescaleWithTheoreticalInput && iv.fInternalValidationVnPsin[eVn] && std::abs(iv.fInternalValidationVnPsin[eVn]->GetAt(h)) > 0.) { correlation /= pow(iv.fInternalValidationVnPsin[eVn]->GetAt(h), 2.); } @@ -10446,7 +11259,7 @@ void FillNestedLoopsContainers(const int& particleIndex, const double& dPhi, con if (particleIndex < 0) { LOGF(fatal, "\033[1;31m%s at line %d : particleIndex = %d\033[0m", __FUNCTION__, __LINE__, particleIndex); } - if (!(TMath::Abs(nl.ftaNestedLoops[0]->GetAt(particleIndex - 1)) > 0.)) { + 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 @@ -10508,8 +11321,8 @@ void CalculateNestedLoops() nParticles = 0; for(int i=0;iGetSize();i++) { - if(TMath::Abs(ftaNestedLoops[0]->GetAt(i)) > 0. && - TMath::Abs(ftaNestedLoops[1]->GetAt(i)) > 0.){nParticles++;} + if(std::abs(ftaNestedLoops[0]->GetAt(i)) > 0. && + std::abs(ftaNestedLoops[1]->GetAt(i)) > 0.){nParticles++;} } } cout<<"nParticles = "<Fill( - 0.5, TMath::Cos((h + 1.) * (dPhi1 - dPhi2)), dW1 * dW2); + 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, TMath::Cos((h + 1.) * (dPhi1 - dPhi2)), + 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, TMath::Cos((h + 1.) * (dPhi1 - dPhi2)), dW1 * dW2); + 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, TMath::Cos((h + 1.) * (dPhi1 - dPhi2)), dW1 * dW2); + 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, TMath::Cos((h + 1.) * (dPhi1 - dPhi2)), dW1 * dW2); + 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, TMath::Cos((h + 1.) * (dPhi1 - dPhi2)), dW1 * dW2); + 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, TMath::Cos((h + 1.) * (dPhi1 - dPhi2)), dW1 * dW2); + ebye.fVz, std::cos((h + 1.) * (dPhi1 - dPhi2)), dW1 * dW2); } } // for(int h=1; h<=6; h++) @@ -10607,31 +11420,31 @@ void CalculateNestedLoops() 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, TMath::Cos((h + 1.) * (dPhi1 + dPhi2 - dPhi3 - dPhi4)), dW1 * dW2 * dW3 * dW4); + 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, TMath::Cos((h + 1.) * (dPhi1 + dPhi2 - dPhi3 - dPhi4)), dW1 * dW2 * dW3 * dW4); + 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, TMath::Cos((h + 1.) * (dPhi1 + dPhi2 - dPhi3 - dPhi4)), dW1 * dW2 * dW3 * dW4); + 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, TMath::Cos((h + 1.) * (dPhi1 + dPhi2 - dPhi3 - dPhi4)), dW1 * dW2 * dW3 * dW4); + 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, TMath::Cos((h + 1.) * (dPhi1 + dPhi2 - dPhi3 - dPhi4)), dW1 * dW2 * dW3 * dW4); + 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, TMath::Cos((h + 1.) * (dPhi1 + dPhi2 - dPhi3 - dPhi4)), dW1 * dW2 * dW3 * dW4); + 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, TMath::Cos((h + 1.) * (dPhi1 + dPhi2 - dPhi3 - dPhi4)), dW1 * dW2 * dW3 * dW4); + 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; hFill(0.5, TMath::Cos((h + 1.) * (dPhi1 + dPhi2 + dPhi3 - dPhi4 - dPhi5 - dPhi6)), dW1 * dW2 * dW3 * dW4 * dW5 * dW6); + 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, TMath::Cos((h + 1.) * (dPhi1 + dPhi2 + dPhi3 - dPhi4 - dPhi5 - dPhi6)), dW1 * dW2 * dW3 * dW4 * dW5 * dW6); + 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, TMath::Cos((h + 1.) * (dPhi1 + dPhi2 + dPhi3 - dPhi4 - dPhi5 - dPhi6)), dW1 * dW2 * dW3 * dW4 * dW5 * dW6); + 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, TMath::Cos((h + 1.) * (dPhi1 + dPhi2 + dPhi3 - dPhi4 - dPhi5 - dPhi6)), dW1 * dW2 * dW3 * dW4 * dW5 * dW6); + 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, TMath::Cos((h + 1.) * (dPhi1 + dPhi2 + dPhi3 - dPhi4 - dPhi5 - dPhi6)), dW1 * dW2 * dW3 * dW4 * dW5 * dW6); + 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, TMath::Cos((h + 1.) * (dPhi1 + dPhi2 + dPhi3 - dPhi4 - dPhi5 - dPhi6)), dW1 * dW2 * dW3 * dW4 * dW5 * dW6); + 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, TMath::Cos((h + 1.) * (dPhi1 + dPhi2 + dPhi3 - dPhi4 - dPhi5 - dPhi6)), dW1 * dW2 * dW3 * dW4 * dW5 * dW6); + 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; hFill(0.5, TMath::Cos((h + 1.) * (dPhi1 + dPhi2 + dPhi3 + dPhi4 - dPhi5 - dPhi6 - dPhi7 - dPhi8)), dW1 * dW2 * dW3 * dW4 * dW5 * dW6 * dW7 * dW8); + 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, TMath::Cos((h + 1.) * (dPhi1 + dPhi2 + dPhi3 + dPhi4 - dPhi5 - dPhi6 - dPhi7 - dPhi8)), dW1 * dW2 * dW3 * dW4 * dW5 * dW6 * dW7 * dW8); + 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, TMath::Cos((h + 1.) * (dPhi1 + dPhi2 + dPhi3 + dPhi4 - dPhi5 - dPhi6 - dPhi7 - dPhi8)), dW1 * dW2 * dW3 * dW4 * dW5 * dW6 * dW7 * dW8); + 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, TMath::Cos((h + 1.) * (dPhi1 + dPhi2 + dPhi3 + dPhi4 - dPhi5 - dPhi6 - dPhi7 - dPhi8)), dW1 * dW2 * dW3 * dW4 * dW5 * dW6 * dW7 * dW8); + 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, TMath::Cos((h + 1.) * (dPhi1 + dPhi2 + dPhi3 + dPhi4 - dPhi5 - dPhi6 - dPhi7 - dPhi8)), dW1 * dW2 * dW3 * dW4 * dW5 * dW6 * dW7 * dW8); + 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, TMath::Cos((h + 1.) * (dPhi1 + dPhi2 + dPhi3 + dPhi4 - dPhi5 - dPhi6 - dPhi7 - dPhi8)), dW1 * dW2 * dW3 * dW4 * dW5 * dW6 * dW7 * dW8); + 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, TMath::Cos((h + 1.) * (dPhi1 + dPhi2 + dPhi3 + dPhi4 - dPhi5 - dPhi6 - dPhi7 - dPhi8)), dW1 * dW2 * dW3 * dW4 * dW5 * dW6 * dW7 * dW8); + 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; hGetBinContent(b); } - if (TMath::Abs(valueQV) > 0. && TMath::Abs(valueNL) > 0.) { + 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 (TMath::Abs(valueQV - valueNL) > tc.fFloatingPointPrecision) { + 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(TMath::Abs(valueQV)>0. && TMath::Abs(valueNL)>0.) + } // 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 @@ -11582,11 +12395,11 @@ TH1D* GetHistogramWithWeights(const char* filePath, const char* runNumber, const } // Compare with min and max value stored in external weights.root file using MakeWeights.C: - if (!(TMath::Abs(TString(oa->At(nEntries - 1)->GetName()).Atof() - max) < tc.fFloatingPointPrecision)) { + 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 (!(TMath::Abs(TString(oa->At(nEntries - 5)->GetName()).Atof() - min) < tc.fFloatingPointPrecision)) { + 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); } @@ -11863,11 +12676,11 @@ THnSparseF* GetSparseHistogramWithWeights(const char* filePath, const char* runN } // Compare with min and max value stored in external weights.root file using MakeWeights.C: - if (!(TMath::Abs(TString(oa->At(nEntries - 1)->GetName()).Atof() - max) < tc.fFloatingPointPrecision)) { + 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 (!(TMath::Abs(TString(oa->At(nEntries - 5)->GetName()).Atof() - min) < tc.fFloatingPointPrecision)) { + 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); } @@ -12180,6 +12993,205 @@ TObjArray* GetDefaultObjArrayWithLabels(const char* whichDefaultLabels) 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); } @@ -12207,7 +13219,8 @@ TObjArray* GetObjArrayWithLabels(const char* filePath) // 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. + // e) Handle the local case; + // f) Clean up. if (tc.fVerbose) { StartFunction(__FUNCTION__); @@ -12280,11 +13293,7 @@ TObjArray* GetObjArrayWithLabels(const char* filePath) // 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())); - + 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__); } @@ -12327,7 +13336,14 @@ TObjArray* GetObjArrayWithLabels(const char* filePath) ExitFunction(__FUNCTION__); } - return oa; + // f) Clean up: + if (oaFile) { + oaFile->Close(); + delete oaFile; + oaFile = nullptr; + } + + return oa; // "292535" (local) + 294291 (ccdb) } // TObjArray* GetObjArrayWithLabels(const char *filePath) @@ -12483,13 +13499,12 @@ void GetHistogramWithCustomNUA(const char* filePath, eNUAPDF variable) void StoreLabelsInPlaceholder() { - // Storal all Test0 labels in the temporary placeholder. + // Storal all Test0 labels in the placeholder. // a) Initialize all counters; - // b) Fetch TObjArray with labels from an external file; - // c) Book the placeholder fTest0LabelsPlaceholder for all labels; - // d) Finally, store the labels from external source into placeholder; - // e) Insanity check on labels. + // 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__); @@ -12501,12 +13516,24 @@ void StoreLabelsInPlaceholder() counter[o] = 0; } // now it's safe :-) - // b) Fetch TObjArray with labels from an external file: + // 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", @@ -12514,100 +13541,48 @@ void StoreLabelsInPlaceholder() LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); } - // c) Book the placeholder fTest0LabelsPlaceholder for all labels: + // c) Insanity check on labels: int nLabels = oa->GetEntries(); - t0.fTest0LabelsPlaceholder = - new TH1I("fTest0LabelsPlaceholder", - Form("placeholder for all labels, %d in total", nLabels), - nLabels, 0, nLabels); - t0.fTest0LabelsPlaceholder->SetStats(false); - - // d) Finally, store the labels from external source into placeholder: - int bin = 1; // used only for fTest0LabelsPlaceholder - int order = -44; + // 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(" "); - 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... - t0.fTest0LabelsPlaceholder->GetXaxis()->SetBinLabel( - bin++, t0.fTest0Labels[order - 1][counter[order - 1]]->Data()); - // cout<<__LINE__<<": - // "<Data()<GetEntries()<GetXaxis()->GetNbins(); b++) { - TObjArray* temp = TString(t0.fTest0LabelsPlaceholder->GetXaxis()->GetBinLabel(b)).Tokenize(" "); for (int h = 0; h < temp->GetEntries(); h++) { - if (TMath::Abs(TString(temp->At(h)->GetName()).Atoi()) > gMaxHarmonic) { - LOGF(info, "\033[1;31m bin = %d, label = %s, gMaxHarmonic = %d\033[0m", b, t0.fTest0LabelsPlaceholder->GetXaxis()->GetBinLabel(b), static_cast(gMaxHarmonic)); + 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 b = 1; b <= t0.fTest0LabelsPlaceholder->GetXaxis()->GetNbins(); b++) { - - if (tc.fVerbose) { - ExitFunction(__FUNCTION__); - } - -} // void StoreLabelsInPlaceholder() - -//============================================================ - -bool RetrieveCorrelationsLabels() -{ - // Generate the labels of all correlations of interest, i.e. retrieve them - // from TH1I *t0.fTest0LabelsPlaceholder - - if (tc.fVerbose) { - StartFunction(__FUNCTION__); - } - - int counter[gMaxCorrelator] = {0}; // is this safe? - for (int o = 0; o < gMaxCorrelator; o++) { - counter[o] = 0; - } // now it's safe :-) - - int nBins = t0.fTest0LabelsPlaceholder->GetXaxis()->GetNbins(); + } // for (int e = 0; e < nLabels; e++) { + // ... + // d) Finally, store the labels from external source into the placeholder: int order = -44; - for (int b = 1; b <= nBins; b++) { - TObjArray* oa = TString(t0.fTest0LabelsPlaceholder->GetXaxis()->GetBinLabel(b)) - .Tokenize(" "); - if (!oa) { + 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 = oa->GetEntries(); - delete oa; // yes, otherwise it's a memory leak + 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(t0.fTest0LabelsPlaceholder->GetXaxis()->GetBinLabel(b)); // okay... + t0.fTest0Labels[order - 1][counter[order - 1]] = new TString(oa->At(e)->GetName()); // okay... counter[order - 1]++; - } // for(int b=1;b<=nBins;b++) + } // for(int e=0; eGetSize();i++) { - if(TMath::Abs(nl.ftaNestedLoops[0]->GetAt(i)) > 0. && TMath::Abs(nl.ftaNestedLoops[1]->GetAt(i)) > 0.){nParticles++;} + if(std::abs(nl.ftaNestedLoops[0]->GetAt(i)) > 0. && std::abs(nl.ftaNestedLoops[1]->GetAt(i)) > 0.){nParticles++;} } } */ @@ -13408,7 +14383,7 @@ double CalculateCustomNestedLoops(TArrayI* harmonics) double dPhi1 = nl.ftaNestedLoops[0]->GetAt(i1); double dW1 = nl.ftaNestedLoops[1]->GetAt(i1); if (1 == order) { - value = TMath::Cos(harmonics->GetAt(0) * dPhi1); + value = std::cos(harmonics->GetAt(0) * dPhi1); weight = dW1; profile->Fill(0.5, value, weight); continue; @@ -13420,7 +14395,7 @@ double CalculateCustomNestedLoops(TArrayI* harmonics) double dPhi2 = nl.ftaNestedLoops[0]->GetAt(i2); double dW2 = nl.ftaNestedLoops[1]->GetAt(i2); if (2 == order) { - value = TMath::Cos(harmonics->GetAt(0) * dPhi1 + harmonics->GetAt(1) * dPhi2); + value = std::cos(harmonics->GetAt(0) * dPhi1 + harmonics->GetAt(1) * dPhi2); weight = dW1 * dW2; profile->Fill(0.5, value, weight); continue; @@ -13432,7 +14407,7 @@ double CalculateCustomNestedLoops(TArrayI* harmonics) double dPhi3 = nl.ftaNestedLoops[0]->GetAt(i3); double dW3 = nl.ftaNestedLoops[1]->GetAt(i3); if (3 == order) { - value = TMath::Cos(harmonics->GetAt(0) * dPhi1 + harmonics->GetAt(1) * dPhi2 + harmonics->GetAt(2) * dPhi3); + 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; @@ -13444,7 +14419,7 @@ double CalculateCustomNestedLoops(TArrayI* harmonics) double dPhi4 = nl.ftaNestedLoops[0]->GetAt(i4); double dW4 = nl.ftaNestedLoops[1]->GetAt(i4); if (4 == order) { - value = TMath::Cos(harmonics->GetAt(0) * dPhi1 + harmonics->GetAt(1) * dPhi2 + harmonics->GetAt(2) * dPhi3 + harmonics->GetAt(3) * dPhi4); + 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; @@ -13456,7 +14431,7 @@ double CalculateCustomNestedLoops(TArrayI* harmonics) double dPhi5 = nl.ftaNestedLoops[0]->GetAt(i5); double dW5 = nl.ftaNestedLoops[1]->GetAt(i5); if (5 == order) { - value = TMath::Cos(harmonics->GetAt(0) * dPhi1 + harmonics->GetAt(1) * dPhi2 + harmonics->GetAt(2) * dPhi3 + harmonics->GetAt(3) * dPhi4 + harmonics->GetAt(4) * dPhi5); + 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; @@ -13468,7 +14443,7 @@ double CalculateCustomNestedLoops(TArrayI* harmonics) double dPhi6 = nl.ftaNestedLoops[0]->GetAt(i6); double dW6 = nl.ftaNestedLoops[1]->GetAt(i6); if (6 == order) { - value = TMath::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); + 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; @@ -13480,7 +14455,7 @@ double CalculateCustomNestedLoops(TArrayI* harmonics) double dPhi7 = nl.ftaNestedLoops[0]->GetAt(i7); double dW7 = nl.ftaNestedLoops[1]->GetAt(i7); if (7 == order) { - value = TMath::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); + 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; @@ -13492,7 +14467,7 @@ double CalculateCustomNestedLoops(TArrayI* harmonics) double dPhi8 = nl.ftaNestedLoops[0]->GetAt(i8); double dW8 = nl.ftaNestedLoops[1]->GetAt(i8); if (8 == order) { - value = TMath::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); + 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; @@ -13504,7 +14479,7 @@ double CalculateCustomNestedLoops(TArrayI* harmonics) double dPhi9 = nl.ftaNestedLoops[0]->GetAt(i9); double dW9 = nl.ftaNestedLoops[1]->GetAt(i9); if (9 == order) { - value = TMath::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); + 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; @@ -13516,7 +14491,7 @@ double CalculateCustomNestedLoops(TArrayI* harmonics) double dPhi10 = nl.ftaNestedLoops[0]->GetAt(i10); double dW10 = nl.ftaNestedLoops[1]->GetAt(i10); if (10 == order) { - value = TMath::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); + 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; @@ -13528,7 +14503,7 @@ double CalculateCustomNestedLoops(TArrayI* harmonics) double dPhi11 = nl.ftaNestedLoops[0]->GetAt(i11); double dW11 = nl.ftaNestedLoops[1]->GetAt(i11); if (11 == order) { - value = TMath::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); + 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; @@ -13540,7 +14515,7 @@ double CalculateCustomNestedLoops(TArrayI* harmonics) double dPhi12 = nl.ftaNestedLoops[0]->GetAt(i12); double dW12 = nl.ftaNestedLoops[1]->GetAt(i12); if (12 == order) { - value = TMath::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); + 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; @@ -13624,7 +14599,7 @@ double CalculateKineCustomNestedLoops(TArrayI* harmonics, eAsFunctionOf AFO_vari // 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 (TMath::Abs(nl.ftaNestedLoopsKine[qvKine][bin][0]->GetAt(i)) > 0.) { + if (std::abs(nl.ftaNestedLoopsKine[qvKine][bin][0]->GetAt(i)) > 0.) { nParticles++; } } @@ -13659,7 +14634,7 @@ double CalculateKineCustomNestedLoops(TArrayI* harmonics, eAsFunctionOf AFO_vari double dPhi1 = nl.ftaNestedLoopsKine[qvKine][bin][0]->GetAt(i1); double dW1 = nl.ftaNestedLoopsKine[qvKine][bin][1]->GetAt(i1); if (1 == order) { - value = TMath::Cos(harmonics->GetAt(0) * dPhi1); + value = std::cos(harmonics->GetAt(0) * dPhi1); weight = dW1; profile->Fill(0.5, value, weight); continue; @@ -13671,7 +14646,7 @@ double CalculateKineCustomNestedLoops(TArrayI* harmonics, eAsFunctionOf AFO_vari double dPhi2 = nl.ftaNestedLoopsKine[qvKine][bin][0]->GetAt(i2); double dW2 = nl.ftaNestedLoopsKine[qvKine][bin][1]->GetAt(i2); if (2 == order) { - value = TMath::Cos(harmonics->GetAt(0) * dPhi1 + harmonics->GetAt(1) * dPhi2); + value = std::cos(harmonics->GetAt(0) * dPhi1 + harmonics->GetAt(1) * dPhi2); weight = dW1 * dW2; profile->Fill(0.5, value, weight); continue; @@ -13683,7 +14658,7 @@ double CalculateKineCustomNestedLoops(TArrayI* harmonics, eAsFunctionOf AFO_vari double dPhi3 = nl.ftaNestedLoopsKine[qvKine][bin][0]->GetAt(i3); double dW3 = nl.ftaNestedLoopsKine[qvKine][bin][1]->GetAt(i3); if (3 == order) { - value = TMath::Cos(harmonics->GetAt(0) * dPhi1 + harmonics->GetAt(1) * dPhi2 + harmonics->GetAt(2) * dPhi3); + 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; @@ -13695,7 +14670,7 @@ double CalculateKineCustomNestedLoops(TArrayI* harmonics, eAsFunctionOf AFO_vari double dPhi4 = nl.ftaNestedLoopsKine[qvKine][bin][0]->GetAt(i4); double dW4 = nl.ftaNestedLoopsKine[qvKine][bin][1]->GetAt(i4); if (4 == order) { - value = TMath::Cos(harmonics->GetAt(0) * dPhi1 + harmonics->GetAt(1) * dPhi2 + harmonics->GetAt(2) * dPhi3 + harmonics->GetAt(3) * dPhi4); + 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; @@ -13707,7 +14682,7 @@ double CalculateKineCustomNestedLoops(TArrayI* harmonics, eAsFunctionOf AFO_vari double dPhi5 = nl.ftaNestedLoopsKine[qvKine][bin][0]->GetAt(i5); double dW5 = nl.ftaNestedLoopsKine[qvKine][bin][1]->GetAt(i5); if (5 == order) { - value = TMath::Cos(harmonics->GetAt(0) * dPhi1 + harmonics->GetAt(1) * dPhi2 + harmonics->GetAt(2) * dPhi3 + harmonics->GetAt(3) * dPhi4 + harmonics->GetAt(4) * dPhi5); + 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; @@ -13719,7 +14694,7 @@ double CalculateKineCustomNestedLoops(TArrayI* harmonics, eAsFunctionOf AFO_vari double dPhi6 = nl.ftaNestedLoopsKine[qvKine][bin][0]->GetAt(i6); double dW6 = nl.ftaNestedLoopsKine[qvKine][bin][1]->GetAt(i6); if (6 == order) { - value = TMath::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); + 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; @@ -13731,7 +14706,7 @@ double CalculateKineCustomNestedLoops(TArrayI* harmonics, eAsFunctionOf AFO_vari double dPhi7 = nl.ftaNestedLoopsKine[qvKine][bin][0]->GetAt(i7); double dW7 = nl.ftaNestedLoopsKine[qvKine][bin][1]->GetAt(i7); if (7 == order) { - value = TMath::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); + 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; @@ -13743,7 +14718,7 @@ double CalculateKineCustomNestedLoops(TArrayI* harmonics, eAsFunctionOf AFO_vari double dPhi8 = nl.ftaNestedLoopsKine[qvKine][bin][0]->GetAt(i8); double dW8 = nl.ftaNestedLoopsKine[qvKine][bin][1]->GetAt(i8); if (8 == order) { - value = TMath::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); + 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; @@ -13755,7 +14730,7 @@ double CalculateKineCustomNestedLoops(TArrayI* harmonics, eAsFunctionOf AFO_vari double dPhi9 = nl.ftaNestedLoopsKine[qvKine][bin][0]->GetAt(i9); double dW9 = nl.ftaNestedLoopsKine[qvKine][bin][1]->GetAt(i9); if (9 == order) { - value = TMath::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); + 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; @@ -13767,7 +14742,7 @@ double CalculateKineCustomNestedLoops(TArrayI* harmonics, eAsFunctionOf AFO_vari double dPhi10 = nl.ftaNestedLoopsKine[qvKine][bin][0]->GetAt(i10); double dW10 = nl.ftaNestedLoopsKine[qvKine][bin][1]->GetAt(i10); if (10 == order) { - value = TMath::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); + 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; @@ -13779,7 +14754,7 @@ double CalculateKineCustomNestedLoops(TArrayI* harmonics, eAsFunctionOf AFO_vari double dPhi11 = nl.ftaNestedLoopsKine[qvKine][bin][0]->GetAt(i11); double dW11 = nl.ftaNestedLoopsKine[qvKine][bin][1]->GetAt(i11); if (11 == order) { - value = TMath::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); + 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; @@ -13791,7 +14766,7 @@ double CalculateKineCustomNestedLoops(TArrayI* harmonics, eAsFunctionOf AFO_vari double dPhi12 = nl.ftaNestedLoopsKine[qvKine][bin][0]->GetAt(i12); double dW12 = nl.ftaNestedLoopsKine[qvKine][bin][1]->GetAt(i12); if (12 == order) { - value = TMath::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); + 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; @@ -14113,20 +15088,27 @@ void DetermineInteractionRateAndCurrentRunDuration(T1 const& collision, T2 const StartFunction(__FUNCTION__); } - // a1) Determine interaction rate only for eRec: 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. - double hadronicRate = mRateFetcher.fetch(ccdb.service, static_cast(bc.timestamp()), static_cast(bc.runNumber()), "ZNC hadronic") * 1.e-3; - 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. - } + + // a1) Determine interaction rate only for eRec: + if (ec.fUseEventCuts[eInteractionRate] || qa.fFillQAEventHistograms2D || qa.fFillQACorrelationsVsInteractionRateVsProfiles2D || mupa.fCalculateCorrelationsAsFunctionOf[AFO_INTERACTIONRATE] || t0.fCalculateTest0AsFunctionOf[AFO_INTERACTIONRATE] || 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])); @@ -14586,9 +15568,9 @@ void FillQvector(const double& dPhi, const double& dPt, const double& dEta) for (int wp = 0; wp < gMaxCorrelator + 1; wp++) { // weight power if (pw.fUseWeights[wPHI] || pw.fUseWeights[wPT] || pw.fUseWeights[wETA]) { wToPowerP = pow(wPhi * wPt * wEta, wp); - qv.fQvector[h][wp] += TComplex(wToPowerP * TMath::Cos(h * dPhi), wToPowerP * TMath::Sin(h * dPhi)); // Q-vector with weights + qv.fQvector[h][wp] += TComplex(wToPowerP * std::cos(h * dPhi), wToPowerP * std::sin(h * dPhi)); // Q-vector with weights } else { - qv.fQvector[h][wp] += TComplex(TMath::Cos(h * dPhi), TMath::Sin(h * dPhi)); // bare Q-vector without weights + qv.fQvector[h][wp] += TComplex(std::cos(h * dPhi), std::sin(h * dPhi)); // bare Q-vector without weights } } // for(int wp=0;wp(track, eBefore); } + // memStatus ~163 (with 'continue') + // *) Particle cuts counters (use only during QA, as this is computationally heavy): if (pc.fUseParticleCutCounterAbsolute || pc.fUseParticleCutCounterSequential) { ParticleCutsCounters(track); } + // memStatus ~164 (with 'continue') + // *) Particle cuts: if (!ParticleCuts(track, eCut)) { // Main call for event cuts. continue; // not return!! } + // memStatus ~162 (with 'continue') + // *) Fill particle histograms after particle cuts: if (ph.fFillParticleHistograms || ph.fFillParticleHistograms2D || qa.fFillQAParticleHistograms2D) { FillParticleHistograms(track, eAfter); } + // memStatus ~164 (with 'continue') + // *) Intitialize local kinematic variables: // Remark: for "eRecSim" processing, kinematics is taken from "reconstructed". dPhi = track.phi(); @@ -15214,23 +16206,27 @@ void Steer(T1 const& collision, T2 const& bcs, T3 const& tracks) DetermineOccupancy(collision); // *) Determine collision interaction rate and current run duration: - DetermineInteractionRateAndCurrentRunDuration(collision, bcs); + DetermineInteractionRateAndCurrentRunDuration(collision, bcs); // TBI 20250414 temporary commented out, because of memory blow-up // *) Determine vertex z position: DetermineVertexZ(collision); // *) 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 subsription to additional non-standard tables was needed for QA purposes. + // 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); } + // memStatus: ~116 + // *) Fill event histograms before event cuts: if (eh.fFillEventHistograms || qa.fFillQAEventHistograms2D || qa.fFillQAParticleEventHistograms2D) { // Remark: I do not above the flag fFillQACorrelationsVsHistograms2D, because as a part of QA I calculate <2> only after cuts in any case FillEventHistograms(collision, tracks, eBefore); } + // memStatus: ~117 + // *) Print info on the current event number (total, before cuts): if (tc.fVerboseEventCounter) { PrintEventCounter(eBefore); @@ -15241,14 +16237,20 @@ void Steer(T1 const& collision, T2 const& bcs, T3 const& tracks) EventCutsCounters(collision, tracks); } + // memStatus: ~117 + // *) Event cuts: if (!EventCuts(collision, tracks, eCut)) { // Main call for event cuts return; } + // memStatus: ~117 + // *) Main loop over particles: MainLoopOverParticles(tracks); + // memStatus: ~162 (all particle histograms), ~133 (only phi, pt, eta) + // *) Determine multiplicity of this event, for all "vs. mult" results: DetermineMultiplicity(); @@ -15298,6 +16300,8 @@ void Steer(T1 const& collision, T2 const& bcs, T3 const& tracks) tc.fTimer[eGlobal]->Continue(); // yes } + // memStatus: ~160 +- 5 + if (tc.fVerbose) { ExitFunction(__FUNCTION__); } diff --git a/PWGCF/MultiparticleCorrelations/Tasks/multiparticle-correlations-ab.cxx b/PWGCF/MultiparticleCorrelations/Tasks/multiparticle-correlations-ab.cxx index f88933d8450..0ee4f0cd5eb 100644 --- a/PWGCF/MultiparticleCorrelations/Tasks/multiparticle-correlations-ab.cxx +++ b/PWGCF/MultiparticleCorrelations/Tasks/multiparticle-correlations-ab.cxx @@ -9,6 +9,10 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. +/// \file multiparticle-correlations-ab.cxx +/// \brief ... TBI 20250425 +/// \author Ante.Bilandzic@cern.ch + // O2: #include #include "Common/CCDB/ctpRateFetcher.h" @@ -135,6 +139,7 @@ struct MultiparticleCorrelationsAB // this name is used in lower-case format to DefaultCuts(); // here default values for cuts are either hardwired, or defined through default binning to ease bookeeping, // or values for cuts provided via configurables are taken into account // Remark: DefaultCuts() has to be called after DefaultBinning() + // *) Specific cuts: if (tc.fUseSpecificCuts) { SpecificCuts(tc.fWhichSpecificCuts); // after default cuts are applied, on top of them apply analysis-specific cuts. Has to be called after DefaultBinning() and DefaultCuts() @@ -152,7 +157,7 @@ struct MultiparticleCorrelationsAB // this name is used in lower-case format to // *) Book all remaining objects; BookAndNestAllLists(); - BookResultsHistograms(); // yes, this one has to be booked first, because it defines the commong binning for other groups of histograms + BookResultsHistograms(); // yes, this one has to be booked first, because it defines the common binning for other groups of histograms TBI 20250412 this is true only if I can use Clone() BookQAHistograms(); BookEventHistograms(); BookEventCutsHistograms(); @@ -167,7 +172,7 @@ struct MultiparticleCorrelationsAB // this name is used in lower-case format to BookInternalValidationHistograms(); BookTest0Histograms(); BookEtaSeparationsHistograms(); - BookTheRest(); // here I book everything that was not sorted (yet) in the specific functions above + BookTheRest(); // I book everything that was not sorted (yet) in the specific functions above // *) Insanity checks after booking: InsanityChecksAfterBooking(); // pointers of all local histograms, etc., are available, so I can do insanity checks directly on all booked objects diff --git a/PWGCF/MultiparticleCorrelations/Tasks/threeParticleCorrelations.cxx b/PWGCF/MultiparticleCorrelations/Tasks/threeParticleCorrelations.cxx index 2e94202f054..a9ae8ac562c 100644 --- a/PWGCF/MultiparticleCorrelations/Tasks/threeParticleCorrelations.cxx +++ b/PWGCF/MultiparticleCorrelations/Tasks/threeParticleCorrelations.cxx @@ -470,11 +470,13 @@ struct ThreeParticleCorrelations { // End of the MC Mixed-events Correlations } - void processMCGen(MyFilteredMCGenCollision const&, MyFilteredMCParticles const&) + void processMCGen(MyFilteredMCGenCollision const& collision, MyFilteredMCParticles const&) { + auto groupMCParticles = mcParticles->sliceByCached(aod::mcparticle::mcCollisionId, collision.globalIndex(), cache); + // Start of the Monte-Carlo generated QA - for (const auto& particle : mcParticles) { + for (const auto& particle : groupMCParticles) { if (particle.isPhysicalPrimary()) { // Efficiency - Generated diff --git a/PWGCF/TableProducer/dptdptfilter.cxx b/PWGCF/TableProducer/dptdptfilter.cxx index 93de67eff5c..cc29cd7ece8 100644 --- a/PWGCF/TableProducer/dptdptfilter.cxx +++ b/PWGCF/TableProducer/dptdptfilter.cxx @@ -540,6 +540,9 @@ struct DptDptFilter { void processWithoutCentDetectorLevel(aod::CollisionEvSel const& collision, DptDptFullTracksDetLevel const& ftracks, aod::McParticles const&, const aod::BCsWithTimestamps&); PROCESS_SWITCH(DptDptFilter, processWithoutCentDetectorLevel, "Process MC detector level without centrality", false); + void processWithoutCentWithoutEvSelDetectorLevel(soa::Join::iterator const& collision, DptDptFullTracksDetLevel const& ftracks, aod::McParticles const&, const aod::BCsWithTimestamps&); + PROCESS_SWITCH(DptDptFilter, processWithoutCentWithoutEvSelDetectorLevel, "Process MC detector level without centrality nor event selections", false); + template bool processGenerated(CollisionObject const& mccollision, ParticlesList const& mcparticles, float centormult); @@ -647,6 +650,11 @@ void DptDptFilter::processWithoutCentDetectorLevel(aod::CollisionEvSel const& co processReconstructed(collision, ftracks, 50.0); } +void DptDptFilter::processWithoutCentWithoutEvSelDetectorLevel(soa::Join::iterator const& collision, DptDptFullTracksDetLevel const& ftracks, aod::McParticles const&, aod::BCsWithTimestamps const&) +{ + processReconstructed(collision, ftracks, 50.0); +} + template bool DptDptFilter::processGenerated(CollisionObject const& mccollision, ParticlesList const&, float centormult) { diff --git a/PWGCF/Tasks/correlations.cxx b/PWGCF/Tasks/correlations.cxx index f0ef51ff0d7..7461cc4b671 100644 --- a/PWGCF/Tasks/correlations.cxx +++ b/PWGCF/Tasks/correlations.cxx @@ -22,6 +22,7 @@ #include #include #include +#include #include "Framework/runDataProcessing.h" #include "Framework/AnalysisTask.h" @@ -165,6 +166,7 @@ struct CorrelationTask { registry.add("invMass", "2-prong invariant mass (GeV/c^2)", {HistType::kTH3F, {axisInvMassHistogram, axisPtTrigger, axisMultiplicity}}); if (doprocessSame2Prong2Prong || doprocessSame2Prong2ProngML) { registry.add("invMassTwoPart", "2D 2-prong invariant mass (GeV/c^2)", {HistType::kTHnSparseF, {axisInvMassHistogram, axisInvMassHistogram, axisPtTrigger, axisPtAssoc, axisMultiplicity}}); + registry.add("invMassTwoPartDPhi", "2D 2-prong invariant mass (GeV/c^2)", {HistType::kTHnSparseF, {axisInvMassHistogram, axisInvMassHistogram, axisPtTrigger, axisPtAssoc, axisDeltaPhi}}); } } registry.add("multiplicity", "event multiplicity", {HistType::kTH1F, {{1000, 0, 100, "/multiplicity/centrality"}}}); @@ -328,6 +330,7 @@ struct CorrelationTask { if (cfgCorrelationMethod == 2 && track1.decay() == track2.decay()) continue; registry.fill(HIST("invMassTwoPart"), track1.invMass(), track2.invMass(), track1.pt(), track2.pt(), multiplicity); + registry.fill(HIST("invMassTwoPartDPhi"), track1.invMass(), track2.invMass(), track1.pt(), track2.pt(), TVector2::Phi_0_2pi(track1.phi() - track2.phi() + TMath::Pi() / 2.0) - TMath::Pi() / 2.0); } } } diff --git a/PWGCF/TwoParticleCorrelations/TableProducer/identifiedBfFilter.cxx b/PWGCF/TwoParticleCorrelations/TableProducer/identifiedBfFilter.cxx index 4b57042f15a..5eda3450473 100644 --- a/PWGCF/TwoParticleCorrelations/TableProducer/identifiedBfFilter.cxx +++ b/PWGCF/TwoParticleCorrelations/TableProducer/identifiedBfFilter.cxx @@ -1679,13 +1679,14 @@ inline int8_t IdentifiedBfFilterTracks::acceptParticle(ParticleObject& particle, } if (ptlow < particle.pt() && particle.pt() < ptup && etalow < particle.eta() && particle.eta() < etaup) { - MatchRecoGenSpecies sp; + MatchRecoGenSpecies sp = kWrongSpecies; if (recoIdMethod == recoIdMethods[0]) { sp = kIdBfCharged; } - if (recoIdMethod == recoIdMethods[1]) { + if (recoIdMethod == recoIdMethods[1] || recoIdMethod == recoIdMethods[2]) { sp = identifyParticle(particle); } + if (sp != kWrongSpecies) { if (sp != kIdBfCharged) { /* fill the charged particle histograms */ diff --git a/PWGCF/TwoParticleCorrelations/Tasks/corrSparse.cxx b/PWGCF/TwoParticleCorrelations/Tasks/corrSparse.cxx index 33cee50dbca..b80b3e2692b 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/corrSparse.cxx +++ b/PWGCF/TwoParticleCorrelations/Tasks/corrSparse.cxx @@ -28,6 +28,7 @@ #include "Common/Core/RecoDecay.h" #include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/TrackSelectionTables.h" #include "Common/DataModel/Centrality.h" #include "PWGCF/DataModel/CorrelationsDerived.h" @@ -54,39 +55,6 @@ DECLARE_SOA_TABLE(Multiplicity, "AOD", "MULTIPLICITY", // define the filtered collisions and tracks #define O2_DEFINE_CONFIGURABLE(NAME, TYPE, DEFAULT, HELP) Configurable NAME{#NAME, DEFAULT, HELP}; -struct CalcNch { - O2_DEFINE_CONFIGURABLE(cfgZVtxCut, float, 10.0f, "Accepted z-vertex range") - O2_DEFINE_CONFIGURABLE(cfgPtCutMin, float, 0.2f, "minimum accepted track pT") - O2_DEFINE_CONFIGURABLE(cfgPtCutMax, float, 10.0f, "maximum accepted track pT") - O2_DEFINE_CONFIGURABLE(cfgEtaCut, float, 10.0f, "Eta cut") - O2_DEFINE_CONFIGURABLE(cfgMinMixEventNum, int, 5, "Minimum number of events to mix") - - Filter trackFilter = (nabs(aod::track::eta) < cfgEtaCut) && (aod::track::pt > cfgPtCutMin) && (aod::track::pt < cfgPtCutMax) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true)); - - using AodCollisions = soa::Join; // aod::CentFT0Cs - using AodTracks = soa::Filtered>; - - Produces multiplicityNch; - - HistogramRegistry registry{"registry"}; - - void init(InitContext&) - { - AxisSpec axisNch = {100, 0, 100}; - AxisSpec axisVrtx = {10, -10, 10}; - - registry.add("Ncharge", "N_{charge}", {HistType::kTH1D, {axisNch}}); - registry.add("zVtx_all", "zVtx_all", {HistType::kTH1D, {axisVrtx}}); - } - - void process(AodCollisions::iterator const& collision, AodTracks const& tracks) - { - multiplicityNch(tracks.size()); - registry.fill(HIST("Ncharge"), tracks.size()); - registry.fill(HIST("zVtx_all"), collision.posZ()); - } -}; - struct CorrSparse { Service ccdb; @@ -100,13 +68,16 @@ struct CorrSparse { O2_DEFINE_CONFIGURABLE(cfgMergingCut, float, 0.0, "Merging cut on track merge") O2_DEFINE_CONFIGURABLE(cfgRadiusLow, float, 0.8, "Low radius for merging cut") O2_DEFINE_CONFIGURABLE(cfgRadiusHigh, float, 2.5, "High radius for merging cut") - O2_DEFINE_CONFIGURABLE(etaMftTrackMin, float, -5.0, "Minimum eta for MFT track") - O2_DEFINE_CONFIGURABLE(etaMftTrackMax, float, 0.0, "Maximum eta for MFT track") + O2_DEFINE_CONFIGURABLE(etaMftTrackMin, float, 3.6, "Minimum eta for MFT track") + O2_DEFINE_CONFIGURABLE(etaMftTrackMax, float, 2.5, "Maximum eta for MFT track") O2_DEFINE_CONFIGURABLE(nClustersMftTrack, int, 5, "Minimum number of clusters for MFT track") O2_DEFINE_CONFIGURABLE(cfgSampleSize, double, 10, "Sample size for mixed event") Configurable processMFT{"processMFT", true, "Associate particle from MFT"}; + SliceCache cache; + SliceCache cacheNch; + ConfigurableAxis axisVertex{"axisVertex", {10, -10, 10}, "vertex axis for histograms"}; ConfigurableAxis axisEta{"axisEta", {40, -1., 1.}, "eta axis for histograms"}; ConfigurableAxis axisPhi{"axisPhi", {72, 0.0, constants::math::TwoPI}, "phi axis for histograms"}; @@ -125,7 +96,7 @@ struct CorrSparse { ConfigurableAxis axisPtEfficiency{"axisPtEfficiency", {VARIABLE_WIDTH, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.25, 1.5, 1.75, 2.0, 2.25, 2.5, 2.75, 3.0, 3.25, 3.5, 3.75, 4.0, 4.5, 5.0, 6.0, 7.0, 8.0}, "pt axis for efficiency histograms"}; // make the filters and cuts. - Filter collisionFilter = (nabs(aod::collision::posZ) < cfgZVtxCut) && (aod::corrsparse::multiplicity) > cfgMinMult && (aod::corrsparse::multiplicity) < cfgMaxMult && (aod::evsel::sel8) == true; + Filter collisionFilter = (nabs(aod::collision::posZ) < cfgZVtxCut) && (aod::evsel::sel8) == true; Filter trackFilter = (nabs(aod::track::eta) < cfgEtaCut) && (aod::track::pt > cfgPtCutMin) && (aod::track::pt < cfgPtCutMax) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true)); // Define the outputs @@ -134,7 +105,7 @@ struct CorrSparse { HistogramRegistry registry{"registry"}; - using AodCollisions = soa::Filtered>; // aod::CentFT0Cs + using AodCollisions = soa::Filtered>; // aod::CentFT0Cs using AodTracks = soa::Filtered>; void init(InitContext&) @@ -155,11 +126,12 @@ struct CorrSparse { registry.add("Eta", "Eta", {HistType::kTH1D, {axisEta}}); registry.add("pT", "pT", {HistType::kTH1D, {axisPtTrigger}}); registry.add("Nch", "N_{ch}", {HistType::kTH1D, {axisMultiplicity}}); + registry.add("Nch_used", "N_{ch}", {HistType::kTH1D, {axisMultiplicity}}); // histogram to see how many events are in the same and mixed event registry.add("zVtx", "zVtx", {HistType::kTH1D, {axisVertex}}); - registry.add("Trig_hist", "", {HistType::kTHnSparseF, {{axisMultiplicity, axisVertex, axisPtTrigger}}}); + registry.add("Trig_hist", "", {HistType::kTHnSparseF, {{axisSample, axisVertex, axisPtTrigger}}}); - registry.add("eventcount", "bin", {HistType::kTH1F, {{3, 0, 3, "bin"}}}); // histogram to see how many events are in the same and mixed event + registry.add("eventcount", "bin", {HistType::kTH1F, {{4, 0, 4, "bin"}}}); // histogram to see how many events are in the same and mixed event std::vector corrAxis = {{axisSample, "Sample"}, {axisVertex, "z-vtx (cm)"}, @@ -219,11 +191,21 @@ struct CorrSparse { template void fillYield(TCollision collision, TTracks tracks) // function to fill the yield and etaphi histograms. { + registry.fill(HIST("Nch"), tracks.size()); registry.fill(HIST("zVtx"), collision.posZ()); for (auto const& track1 : tracks) { - registry.fill(HIST("Phi"), track1.phi()); + + if (processMFT) { + if constexpr (std::is_same_v) { + if (!isAcceptedMftTrack(track1)) { + continue; + } + } + } + + registry.fill(HIST("Phi"), RecoDecay::constrainAngle(track1.phi(), 0.0)); registry.fill(HIST("Eta"), track1.eta()); registry.fill(HIST("pT"), track1.pt()); } @@ -255,7 +237,7 @@ struct CorrSparse { // template - void fillCorrelations(TTracks tracks1, TTracksAssoc tracks2, float posZ, int system, float Nch, int magneticField) // function to fill the Output functions (sparse) and the delta eta and delta phi histograms + void fillCorrelations(TTracks tracks1, TTracksAssoc tracks2, float posZ, int system, int magneticField) // function to fill the Output functions (sparse) and the delta eta and delta phi histograms { int fSampleIndex = gRandom->Uniform(0, cfgSampleSize); @@ -264,7 +246,8 @@ struct CorrSparse { for (auto const& track1 : tracks1) { if (system == SameEvent) { - registry.fill(HIST("Trig_hist"), Nch, posZ, track1.pt()); + registry.fill(HIST("Nch_used"), tracks1.size()); + registry.fill(HIST("Trig_hist"), fSampleIndex, posZ, track1.pt()); } for (auto const& track2 : tracks2) { @@ -290,13 +273,13 @@ struct CorrSparse { const double kLimit = 3.0 * cfgMergingCut; - bool bIsBelow = kFALSE; + bool bIsBelow = false; if (std::abs(dPhiStarLow) < kLimit || std::abs(dPhiStarHigh) < kLimit || dPhiStarLow * dPhiStarHigh < 0) { for (double rad(cfgRadiusLow); rad < cfgRadiusHigh; rad += 0.01) { double dPhiStar = getDPhiStar(track1, track2, rad, magneticField); if (std::abs(dPhiStar) < kLimit) { - bIsBelow = kTRUE; + bIsBelow = true; break; } } @@ -325,58 +308,82 @@ struct CorrSparse { auto bc = collision.bc_as(); registry.fill(HIST("eventcount"), SameEvent); // because its same event i put it in the 1 bin - fillYield(collision, tracks); if (processMFT) { + fillYield(collision, mfts); + + if (tracks.size() < cfgMinMult || tracks.size() >= cfgMaxMult) { + return; + } - fillCorrelations(tracks, mfts, collision.posZ(), SameEvent, tracks.size(), getMagneticField(bc.timestamp())); + fillCorrelations(tracks, mfts, collision.posZ(), SameEvent, getMagneticField(bc.timestamp())); } else { + fillYield(collision, tracks); + + if (tracks.size() < cfgMinMult || tracks.size() >= cfgMaxMult) { + return; + } - fillCorrelations(tracks, tracks, collision.posZ(), SameEvent, tracks.size(), getMagneticField(bc.timestamp())); + fillCorrelations(tracks, tracks, collision.posZ(), SameEvent, getMagneticField(bc.timestamp())); } } PROCESS_SWITCH(CorrSparse, processSame, "Process same event", true); - // event mixing - SliceCache cache; - using MixedBinning = ColumnBinningPolicy; - // the process for filling the mixed events void processMixed(AodCollisions const& collisions, AodTracks const& tracks, aod::MFTTracks const& MFTtracks, aod::BCsWithTimestamps const&) { + auto getTracksSize = [&tracks, this](AodCollisions::iterator const& collision) { + auto associatedTracks = tracks.sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), this->cache); + auto mult = associatedTracks.size(); + return mult; + }; + + using MixedBinning = FlexibleBinningPolicy, aod::collision::PosZ, decltype(getTracksSize)>; + + MixedBinning binningOnVtxAndMult{{getTracksSize}, {vtxMix, multMix}, true}; + if (processMFT) { - MixedBinning binningOnVtxAndMult{{vtxMix, multMix}, true}; // true is for 'ignore overflows' (true by default) - auto tracksTuple = std::make_tuple(tracks, MFTtracks); - SameKindPair pairs{binningOnVtxAndMult, cfgMinMixEventNum, -1, collisions, tracksTuple, &cache}; // -1 is the number of the bin to skip - for (auto const& [collision1, tracks1, collision2, tracks2] : pairs) { + auto tracksTuple = std::make_tuple(tracks, MFTtracks); + Pair pair{binningOnVtxAndMult, cfgMinMixEventNum, -1, collisions, tracksTuple, &cache}; // -1 is the number of the bin to skip + for (auto const& [collision1, tracks1, collision2, tracks2] : pair) { registry.fill(HIST("eventcount"), MixedEvent); // fill the mixed event in the 3 bin auto bc = collision1.bc_as(); - fillCorrelations(tracks1, tracks2, collision1.posZ(), MixedEvent, tracks1.size(), getMagneticField(bc.timestamp())); + if ((tracks1.size() < cfgMinMult || tracks1.size() >= cfgMaxMult)) + continue; + + if ((tracks2.size() < cfgMinMult || tracks2.size() >= cfgMaxMult)) + continue; + + fillCorrelations(tracks1, tracks2, collision1.posZ(), MixedEvent, getMagneticField(bc.timestamp())); } } else { - MixedBinning binningOnVtxAndMult{{vtxMix, multMix}, true}; // true is for 'ignore overflows' (true by default) auto tracksTuple = std::make_tuple(tracks, tracks); - SameKindPair pairs{binningOnVtxAndMult, cfgMinMixEventNum, -1, collisions, tracksTuple, &cache}; // -1 is the number of the bin to skip - - for (auto const& [collision1, tracks1, collision2, tracks2] : pairs) { + Pair pair{binningOnVtxAndMult, cfgMinMixEventNum, -1, collisions, tracksTuple, &cache}; // -1 is the number of the bin to skip + for (auto const& [collision1, tracks1, collision2, tracks2] : pair) { registry.fill(HIST("eventcount"), MixedEvent); // fill the mixed event in the 3 bin auto bc = collision1.bc_as(); - fillCorrelations(tracks1, tracks2, collision1.posZ(), MixedEvent, tracks1.size(), getMagneticField(bc.timestamp())); + if ((tracks1.size() < cfgMinMult || tracks1.size() >= cfgMaxMult)) + continue; + + if ((tracks2.size() < cfgMinMult || tracks2.size() >= cfgMaxMult)) + continue; + + fillCorrelations(tracks1, tracks2, collision1.posZ(), MixedEvent, getMagneticField(bc.timestamp())); } } } + PROCESS_SWITCH(CorrSparse, processMixed, "Process mixed events", true); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{ - adaptAnalysisTask(cfgc), adaptAnalysisTask(cfgc), }; } diff --git a/PWGCF/TwoParticleCorrelations/Tasks/identifiedbf.cxx b/PWGCF/TwoParticleCorrelations/Tasks/identifiedbf.cxx index 7319f70d946..b357272c17c 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/identifiedbf.cxx +++ b/PWGCF/TwoParticleCorrelations/Tasks/identifiedbf.cxx @@ -100,6 +100,7 @@ struct IdentifiedbfTask { std::vector fhN1VsZEtaPhiPt{nch + 1, nullptr}; //! fhN1VsZEtaPhiPtPrimary{nch, nullptr}; //! fhN1VsZEtaPhiPtSecondary{nch, nullptr}; //! fhN1VsZEtaPhiPtPure{nch + 1, nullptr}; //! fhSum1PtVsZEtaPhiPt{nch, nullptr}; //! fhNuaNueVsZEtaPhiPt{nch, nullptr}; //! fhPtAvgVsEtaPhi{nch, nullptr}; //! + bool isSpeciesCheck(ParticleObject const& particle, int trkId) + { + int pdgcode = particle.pdgCode(); + int realPID = -1; + switch (pdgcode) { + case kPositron: + realPID = 0; + break; + case kElectron: + realPID = 1; + break; + case kPiPlus: + realPID = 2; + break; + case kPiMinus: + realPID = 3; + break; + case kKPlus: + realPID = 4; + break; + case kKMinus: + realPID = 5; + break; + case kProton: + realPID = 6; + break; + case kProtonBar: + realPID = 7; + break; + default: + realPID = -1; + break; + } + return (realPID == trkId); + } + + /// \brief checks whether MC track is a physical primary or secondary + /// \param particle passed MC track converted to MCParticle + template + bool isPrimarySpeciesCheck(TrackObject const& track, int trkId) + { + if constexpr (framework::has_type_v) { + return (isPrimaryCheck(track.template mcParticle_as()) && isSpeciesCheck(track.template mcParticle_as(), trkId)); + } + return false; + } + /// \brief fills the singles histograms in singles execution mode /// \param passedtracks filtered table with the tracks associated to the passed index /// \param tix index, in the singles histogram bank, for the passed filetered track table @@ -315,6 +366,9 @@ struct IdentifiedbfTask { fhN1VsZEtaPhiPt[track.trackacceptedid()]->Fill(zvtx, getEtaPhiIndex(track) + 0.5, track.pt(), corr); fhSum1PtVsZEtaPhiPt[track.trackacceptedid()]->Fill(zvtx, getEtaPhiIndex(track) + 0.5, track.pt(), track.pt() * corr); trackPrimaryCheck(track, zvtx, corr); + if (isPrimarySpeciesCheck(track, track.trackacceptedid())) { + fhN1VsZEtaPhiPtPure[track.trackacceptedid()]->Fill(zvtx, getEtaPhiIndex(track) + 0.5, track.pt(), corr); + } } index++; } @@ -583,6 +637,23 @@ struct IdentifiedbfTask { ptlow, ptup); + fhN1VsZEtaPhiPtPure[i] = new TH3F( + TString::Format("n1_%s_Pure_vsZ_vsEtaPhi_vsPt", tname[i].c_str()).Data(), + TString::Format("#LT n_{1} Pure #GT;vtx_{z};#eta_{%s}#times#varphi_{%s};p_{t,%s} (GeV/c)", + tname[i].c_str(), + tname[i].c_str(), + tname[i].c_str()) + .Data(), + zvtxbins, + zvtxlow, + zvtxup, + etabins * phibins, + 0.0, + static_cast(etabins * phibins), + ptbins, + ptlow, + ptup); + fhSum1PtVsZEtaPhiPt[i] = new TH3F( TString::Format("sumPt1_%s_vsZ_vsEtaPhi_vsPt", tname[i].c_str()).Data(), TString::Format( @@ -618,6 +689,8 @@ struct IdentifiedbfTask { fhN1VsZEtaPhiPtPrimary[i]->Sumw2(false); fhN1VsZEtaPhiPtSecondary[i]->SetBit(TH1::kIsNotW); fhN1VsZEtaPhiPtSecondary[i]->Sumw2(false); + fhN1VsZEtaPhiPtPure[i]->SetBit(TH1::kIsNotW); + fhN1VsZEtaPhiPtPure[i]->Sumw2(false); fhSum1PtVsZEtaPhiPt[i]->SetBit(TH1::kIsNotW); fhSum1PtVsZEtaPhiPt[i]->Sumw2(false); } @@ -632,6 +705,7 @@ struct IdentifiedbfTask { fOutputList->Add(fhN1VsZEtaPhiPt[i]); fOutputList->Add(fhN1VsZEtaPhiPtPrimary[i]); fOutputList->Add(fhN1VsZEtaPhiPtSecondary[i]); + fOutputList->Add(fhN1VsZEtaPhiPtPure[i]); fOutputList->Add(fhSum1PtVsZEtaPhiPt[i]); } } diff --git a/PWGCF/TwoParticleCorrelations/Tasks/neutronProtonCorrZdc.cxx b/PWGCF/TwoParticleCorrelations/Tasks/neutronProtonCorrZdc.cxx index b23be4f956c..1870c66da80 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/neutronProtonCorrZdc.cxx +++ b/PWGCF/TwoParticleCorrelations/Tasks/neutronProtonCorrZdc.cxx @@ -28,14 +28,29 @@ using namespace o2::framework; using namespace o2::framework::expressions; enum EventCounter { kNoSelection = 0, - kQualitySelection = 1, - kMaxCentralitySelection = 2, - kZDCSelection = 3 }; + kSel8 = 1, + kNoSameBunchPileUp = 2, + kIsGoodZvtxFT0vsPV = 3, + kNoCollInTimeRangeStandard = 4, + kMaxCentralitySelection = 5, + kZDCSelection = 6, + kTimeDifferenceZDC = 7 }; struct NeutronProtonCorrZdc { // Histogram registry: an object to hold your histograms HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + Configurable cfgZVertexCut{"cfgZVertexCut", 10., "Cut on Z vertex position"}; + Configurable cfgNoSameBunchPileupCut{"cfgNoSameBunchPileupCut", true, "kNoSameBunchPileUp Cut"}; + Configurable cfgIsGoodZvtxFT0vsPV{"cfgIsGoodZvtxFT0vsPV", true, "kIsGoodZvtxFT0vsPV Cut"}; + Configurable cfgNoCollInTimeRangeStandard{"cfgNoCollInTimeRangeStandard", true, "kNoCollInTimeRangeStandard Cut"}; + Configurable cfgMaxCentrality{"cfgMaxCentrality", 80, "Maximum collision centrality"}; + Configurable cfgZDCTimingInformationCut{"cfgZDCTimingInformationCut", true, "Use timing information in ZDC event selection"}; + Configurable cfgTimingBins{"cfgTimingBins", 200, "N bins for timing histograms"}; + Configurable cfgTDCZNmincut{"cfgTDCZNmincut", -3.0, "Min ZN TDC cut"}; + Configurable cfgTDCZNmaxcut{"cfgTDCZNmaxcut", 3.0, "Max ZN TDC cut"}; + Configurable cfgTDCZPmincut{"cfgTDCZPmincut", -3.0, "Min ZP TDC cut"}; + Configurable cfgTDCZPmaxcut{"cfgTDCZPmaxcut", 3.0, "Max ZP TDC cut"}; Configurable cfgNBinsZN{"cfgNBinsZN", 100, "N bins for ZNA and ZNC"}; Configurable cfgNBinsZP{"cfgNBinsZP", 100, "N bins for ZPA and ZPC"}; Configurable cfgZNmin{"cfgZNmin", -10, "Minimum value for ZN signal"}; @@ -47,13 +62,13 @@ struct NeutronProtonCorrZdc { Configurable cfgNBinsAlpha{"cfgNBinsAlpha", 100, "Number of bins for ZDC asymmetry"}; Configurable cfgAlphaZmin{"cfgAlphaZmin", -1, "Minimum value for ZDC asymmetry"}; Configurable cfgAlphaZmax{"cfgAlphaZmax", 1, "Maximum value for ZDC asymmetry"}; - Configurable cfgMaxCentrality{"cfgMaxCentrality", 80, "Maximum collision centrality"}; Configurable cfgCentralityEstimator{"cfgCentralityEstimator", 0, "Choice of centrality estimator"}; - Configurable cfgNBinsMultiplicity{"cfgNBinsMultiplicity", 1000, "N bins for multiplicity histograms"}; + Configurable cfgFillMultiplicityQAHistograms{"cfgFillMultiplicityQAHistograms", true, "Fill multiplicity QA plots"}; + Configurable cfgNBinsMultiplicity{"cfgNBinsMultiplicity", 500, "N bins for multiplicity histograms"}; ConfigurableAxis cfgAxisCent{"cfgAxisCent", {VARIABLE_WIDTH, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, 31.0, 32.0, 33.0, 34.0, 35.0, 36.0, 37.0, 38.0, 39.0, 40.0, 41.0, 42.0, 43.0, 44.0, 45.0, 46.0, 47.0, 48.0, 49.0, 50.0, 51.0, 52.0, 53.0, 54.0, 55.0, 56.0, 57.0, 58.0, 59.0, 60.0, 61.0, 62.0, 63.0, 64.0, 65.0, 66.0, 67.0, 68.0, 69.0, 70.0, 71.0, 72.0, 73.0, 74.0, 75.0, 76.0, 77.0, 78.0, 79.0, 80.0, 81.0, 82.0, 83.0, 84.0, 85.0, 86.0, 87.0, 88.0, 89.0, 90.0, 91.0, 92.0, 93.0, 94.0, 95.0, 96.0, 97.0, 98.0, 99.0, 100.0}, "Centrality [%]"}; - Filter collisionVtxZ = nabs(aod::collision::posZ) < 10.f; + Filter collisionVtxZ = nabs(aod::collision::posZ) < cfgZVertexCut; using CentralitiesRun3 = soa::Join; using CentralitiesRun2 = aod::CentRun2V0Ms; @@ -62,7 +77,8 @@ struct NeutronProtonCorrZdc { void init(InitContext const&) { // define axes you want to use - const AxisSpec axisCounter{4, -0.5, 3.5, ""}; + const AxisSpec axisCounter{8, -0.5, 7.5, ""}; + const AxisSpec axisZDCTiming{cfgTimingBins, -10, 10}; const AxisSpec axisZNSectorSignal{cfgNBinsZN, cfgZNmin, cfgZNmax / 3.}; const AxisSpec axisZPSectorSignal{cfgNBinsZP, cfgZPmin, cfgZPmax / 3.}; const AxisSpec axisZNASignal{cfgNBinsZN, cfgZNmin, cfgZNmax, "ZNA (a.u.)"}; @@ -80,13 +96,26 @@ struct NeutronProtonCorrZdc { const AxisSpec axisMultiplicityTPC{cfgNBinsMultiplicity, 0, 100000, "TPC"}; const AxisSpec axisMultiplicityMultNGlobal{cfgNBinsMultiplicity, 0, 3500, "MultsNGlobal"}; + HistogramConfigSpec defaultTimingHistogram({HistType::kTH2F, {cfgAxisCent, axisZDCTiming}}); HistogramConfigSpec defaultZNSectorHist({HistType::kTH2F, {cfgAxisCent, axisZNSectorSignal}}); HistogramConfigSpec defaultZPSectorHist({HistType::kTH2F, {cfgAxisCent, axisZPSectorSignal}}); HistogramConfigSpec defaultZDCDiffHist({HistType::kTH2F, {cfgAxisCent, axisZDiffSignal}}); // create histograms histos.add("eventCounter", "eventCounter", kTH1F, {axisCounter}); + histos.get(HIST("eventCounter"))->GetXaxis()->SetBinLabel(EventCounter::kSel8 + 1, "Sel8"); + histos.get(HIST("eventCounter"))->GetXaxis()->SetBinLabel(EventCounter::kNoSameBunchPileUp + 1, "kNoSameBunchPileup"); + histos.get(HIST("eventCounter"))->GetXaxis()->SetBinLabel(EventCounter::kIsGoodZvtxFT0vsPV + 1, "kIsGoodZvtxFT0vsPV"); + histos.get(HIST("eventCounter"))->GetXaxis()->SetBinLabel(EventCounter::kNoCollInTimeRangeStandard + 1, "kNoCollInTimeRangeStandard"); + histos.get(HIST("eventCounter"))->GetXaxis()->SetBinLabel(EventCounter::kMaxCentralitySelection + 1, "Cenrality range"); + histos.get(HIST("eventCounter"))->GetXaxis()->SetBinLabel(EventCounter::kZDCSelection + 1, "isSelectedZDC"); + histos.get(HIST("eventCounter"))->GetXaxis()->SetBinLabel(EventCounter::kTimeDifferenceZDC + 1, "ZDC time difference"); + histos.add("CentralityPercentile", "CentralityPercentile", kTH1F, {cfgAxisCent}); + histos.add("TimingZNAvsCent", "TimingZNAvsCent", defaultTimingHistogram); + histos.add("TimingZNCvsCent", "TimingZNCvsCent", defaultTimingHistogram); + histos.add("TimingZPAvsCent", "TimingZPAvsCent", defaultTimingHistogram); + histos.add("TimingZPCvsCent", "TimingZPCvsCent", defaultTimingHistogram); histos.add("ASide/CentvsZNSector0Signal", "CentvsZNASector0Signal", defaultZNSectorHist); histos.add("ASide/CentvsZNSector1Signal", "CentvsZNASector1Signal", defaultZNSectorHist); @@ -124,18 +153,61 @@ struct NeutronProtonCorrZdc { histos.add("CentvsZNCvsZPC", "CentvsZNCvsZPC", kTH3F, {cfgAxisCent, axisZNCSignal, axisZPCSignal}); histos.add("CentvsZNvsZP", "CentvsZNvsZP", kTH3F, {cfgAxisCent, axisZNSignal, axisZPSignal}); - histos.add("MultiplicityHistograms/FV0A", "FV0A", kTH1F, {axisMultiplicityF0A}); - histos.add("MultiplicityHistograms/FT0A", "FT0A", kTH1F, {axisMultiplicityF0A}); - histos.add("MultiplicityHistograms/FT0C", "FT0C", kTH1F, {axisMultiplicityF0C}); - histos.add("MultiplicityHistograms/FDDA", "FDDA", kTH1F, {axisMultiplicityFDD}); - histos.add("MultiplicityHistograms/FDDC", "FDDC", kTH1F, {axisMultiplicityFDD}); - histos.add("MultiplicityHistograms/TPC", "TPC", kTH1F, {axisMultiplicityTPC}); - histos.add("MultiplicityHistograms/NGlobal", "NGlobal", kTH1F, {axisMultiplicityMultNGlobal}); - histos.add("MultiplicityHistograms/CentvsFT0C", "CentvsFT0C", kTH2F, {cfgAxisCent, axisMultiplicityF0C}); - histos.add("MultiplicityHistograms/CentvsFT0CVar1", "CentvsFT0CVar1", kTH2F, {cfgAxisCent, axisMultiplicityF0C}); - histos.add("MultiplicityHistograms/CentvsFT0M", "CentvsFT0M", kTH2F, {cfgAxisCent, axisMultiplicityF0M}); - histos.add("MultiplicityHistograms/CentvsFV0A", "CentvsFV0A", kTH2F, {cfgAxisCent, axisMultiplicityF0A}); - histos.add("MultiplicityHistograms/CentvsNGlobal", "CentvsNGlobal", kTH2F, {cfgAxisCent, axisMultiplicityMultNGlobal}); + if (cfgFillMultiplicityQAHistograms) { + histos.add("MultiplicityHistograms/FV0A", "FV0A", kTH1F, {axisMultiplicityF0A}); + histos.add("MultiplicityHistograms/FT0A", "FT0A", kTH1F, {axisMultiplicityF0A}); + histos.add("MultiplicityHistograms/FT0C", "FT0C", kTH1F, {axisMultiplicityF0C}); + histos.add("MultiplicityHistograms/FDDA", "FDDA", kTH1F, {axisMultiplicityFDD}); + histos.add("MultiplicityHistograms/FDDC", "FDDC", kTH1F, {axisMultiplicityFDD}); + histos.add("MultiplicityHistograms/TPC", "TPC", kTH1F, {axisMultiplicityTPC}); + histos.add("MultiplicityHistograms/NGlobal", "NGlobal", kTH1F, {axisMultiplicityMultNGlobal}); + histos.add("MultiplicityHistograms/CentvsFT0C", "CentvsFT0C", kTH2F, {cfgAxisCent, axisMultiplicityF0C}); + histos.add("MultiplicityHistograms/CentvsFT0CVar1", "CentvsFT0CVar1", kTH2F, {cfgAxisCent, axisMultiplicityF0C}); + histos.add("MultiplicityHistograms/CentvsFT0M", "CentvsFT0M", kTH2F, {cfgAxisCent, axisMultiplicityF0M}); + histos.add("MultiplicityHistograms/CentvsFV0A", "CentvsFV0A", kTH2F, {cfgAxisCent, axisMultiplicityF0A}); + histos.add("MultiplicityHistograms/CentvsNGlobal", "CentvsNGlobal", kTH2F, {cfgAxisCent, axisMultiplicityMultNGlobal}); + } + } + + template + bool eventSelected(TCollision coll, const float centrality) + { + if (!coll.sel8()) + return 0; + histos.fill(HIST("eventCounter"), kSel8); + + if (cfgNoSameBunchPileupCut) { + if (!coll.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) { + // rejects collisions which are associated with the same "found-by-T0" bunch crossing + // https://indico.cern.ch/event/1396220/#1-event-selection-with-its-rof + return 0; + } + histos.fill(HIST("eventCounter"), EventCounter::kNoSameBunchPileUp); + } + + if (cfgIsGoodZvtxFT0vsPV) { + if (!coll.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) { + // removes collisions with large differences between z of PV by tracks and z of PV from FT0 A-C time difference + // use this cut at low multiplicities with caution + return 0; + } + histos.fill(HIST("eventCounter"), EventCounter::kIsGoodZvtxFT0vsPV); + } + + if (cfgNoCollInTimeRangeStandard) { + if (!coll.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { + // Rejection of the collisions which have other events nearby + return 0; + } + histos.fill(HIST("eventCounter"), EventCounter::kNoCollInTimeRangeStandard); + } + + if (centrality > cfgMaxCentrality) { + return 0; + } + histos.fill(HIST("eventCounter"), EventCounter::kMaxCentralitySelection); + + return 1; } template @@ -195,31 +267,55 @@ struct NeutronProtonCorrZdc { void processRun3(soa::Filtered>::iterator const& collision, BCsRun3 const&, aod::Zdcs const&) { histos.fill(HIST("eventCounter"), EventCounter::kNoSelection); - if (!collision.sel8()) { - return; - } - histos.fill(HIST("eventCounter"), EventCounter::kQualitySelection); const float centArray[] = {collision.centFT0C(), collision.centFT0CVariant1(), collision.centFT0M(), collision.centFV0A(), collision.centNGlobal()}; const auto cent = centArray[cfgCentralityEstimator]; - if (cent > cfgMaxCentrality) { + + if (!eventSelected(collision, cent)) return; - } - histos.fill(HIST("eventCounter"), EventCounter::kMaxCentralitySelection); const auto& foundBC = collision.foundBC_as(); if (foundBC.has_zdc()) { const auto& zdcread = foundBC.zdc(); histos.fill(HIST("eventCounter"), EventCounter::kZDCSelection); + + auto tZNA = zdcread.timeZNA(); + auto tZNC = zdcread.timeZNC(); + auto tZPA = zdcread.timeZPA(); + auto tZPC = zdcread.timeZPC(); + + histos.fill(HIST("TimingZNAvsCent"), cent, tZNA); + histos.fill(HIST("TimingZNCvsCent"), cent, tZNC); + histos.fill(HIST("TimingZPAvsCent"), cent, tZPA); + histos.fill(HIST("TimingZPCvsCent"), cent, tZPC); + + // Selection on timing for the ZDC + if (cfgZDCTimingInformationCut) { + if (tZNA <= cfgTDCZNmincut || tZNA >= cfgTDCZNmaxcut) { + return; + } + if (tZNC <= cfgTDCZNmincut || tZNC >= cfgTDCZNmaxcut) { + return; + } + if (tZPA <= cfgTDCZPmincut || tZPA >= cfgTDCZPmaxcut) { + return; + } + if (tZPC <= cfgTDCZPmincut || tZPC >= cfgTDCZPmaxcut) { + return; + } + } + histos.fill(HIST("eventCounter"), EventCounter::kTimeDifferenceZDC); histos.fill(HIST("CentralityPercentile"), cent); - static_for<0, 6>([&](auto i) { - fillMultHistosRun3(collision); // Fill multiplicity histograms - }); + if (cfgFillMultiplicityQAHistograms) { + static_for<0, 6>([&](auto i) { + fillMultHistosRun3(collision); // Fill multiplicity histograms + }); - static_for<0, 4>([&](auto i) { - fillCentHistosRun3(collision); // Fill centrality histograms - }); + static_for<0, 4>([&](auto i) { + fillCentHistosRun3(collision); // Fill centrality vs multiplicity histograms + }); + } static_for<0, 1>([&](auto i) { fillZDCSideCommonHistos(cent, zdcread); // Fill i-side common histograms @@ -264,7 +360,7 @@ struct NeutronProtonCorrZdc { if (!collision.alias_bit(kINT7)) { return; } - histos.fill(HIST("eventCounter"), EventCounter::kQualitySelection); + histos.fill(HIST("eventCounter"), EventCounter::kSel8); if (collision.centRun2V0M() > cfgMaxCentrality) { return; } diff --git a/PWGDQ/Core/CutsLibrary.cxx b/PWGDQ/Core/CutsLibrary.cxx index fdc539f3c38..ff2cfe9298d 100644 --- a/PWGDQ/Core/CutsLibrary.cxx +++ b/PWGDQ/Core/CutsLibrary.cxx @@ -2957,6 +2957,11 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } + if (!nameStr.compare("muonMinimalCuts")) { + cut->AddCut(GetAnalysisCut("muonMinimalCuts")); + return cut; + } + if (!nameStr.compare("muonQualityCuts")) { cut->AddCut(GetAnalysisCut("muonQualityCuts")); return cut; @@ -6038,6 +6043,14 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } + if (!nameStr.compare("muonMinimalCuts")) { + cut->AddCut(VarManager::kEta, -4.0, -2.5); + cut->AddCut(VarManager::kMuonRAtAbsorberEnd, 17.6, 89.5); + cut->AddCut(VarManager::kMuonPDca, 0.0, 594.0, false, VarManager::kMuonRAtAbsorberEnd, 17.6, 26.5); + cut->AddCut(VarManager::kMuonPDca, 0.0, 324.0, false, VarManager::kMuonRAtAbsorberEnd, 26.5, 89.5); + return cut; + } + if (!nameStr.compare("muonQualityCuts")) { cut->AddCut(VarManager::kEta, -4.0, -2.5); cut->AddCut(VarManager::kMuonRAtAbsorberEnd, 17.6, 89.5); diff --git a/PWGDQ/Core/HistogramsLibrary.cxx b/PWGDQ/Core/HistogramsLibrary.cxx index dfbda4a4a67..1fc7e65442c 100644 --- a/PWGDQ/Core/HistogramsLibrary.cxx +++ b/PWGDQ/Core/HistogramsLibrary.cxx @@ -916,6 +916,12 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h } if (!groupStr.CompareTo("pair")) { + if (subGroupStr.Contains("cepf")) { + hm->AddHistogram(histClass, "Mass", "", false, 300, 0.0, 12.0, VarManager::kMass); + hm->AddHistogram(histClass, "Mass_Pt", "", false, 300, 0.0, 12.0, VarManager::kMass, 10, 0.0, 20.0, VarManager::kPt); + hm->AddHistogram(histClass, "Mass_Y", "", false, 300, 0.0, 12.0, VarManager::kMass, 100, -5.0, 5.0, VarManager::kRap); + hm->AddHistogram(histClass, "Y_Pt", "", false, 100, -5.0, 5.0, VarManager::kRap, 20, 0.0, 20.0, VarManager::kPt); + } if (subGroupStr.Contains("mult_pvcontrib")) { hm->AddHistogram(histClass, "Mass_VtxNcontribReal", "Mass vs VtxNcontribReal", false, 200, 2.0, 5.0, VarManager::kMass, 200, 0, 200.0, VarManager::kVtxNcontribReal); } @@ -947,6 +953,7 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h if (subGroupStr.Contains("mult")) { hm->AddHistogram(histClass, "Mass_Pt_MultFV0A", "", false, 200, 0.0, 5.0, VarManager::kMass, 40, 0.0, 40.0, VarManager::kPt, 100, 0.0, 25000.0, VarManager::kMultFV0A); hm->AddHistogram(histClass, "Mass_VtxNcontribReal", "Mass vs VtxNcontribReal", false, 200, 0.0, 5.0, VarManager::kMass, 200, 0, 200.0, VarManager::kVtxNcontribReal); + hm->AddHistogram(histClass, "Mass_VtxNcontribReal_VtxZ", "Mass vs VtxNcontribReal vs VtxZ", false, 200, 2.0, 5.0, VarManager::kMass, 150, 0, 150.0, VarManager::kVtxNcontribReal, 20, -10.0, 10.0, VarManager::kVtxZ); hm->AddHistogram(histClass, "VtxZ_VtxNcontribReal", "VtxZ vs VtxNcontribReal", false, 240, -12.0, 12.0, VarManager::kVtxZ, 200, 0, 200.0, VarManager::kVtxNcontribReal); } if (subGroupStr.Contains("polarization")) { @@ -1195,6 +1202,18 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h hm->AddHistogram(histClass, "Mass_Pt_cosThetaCS_phiCS", "", 4, varspTCS, binspT, xminpT, xmaxpT, 0, -1, kFALSE); hm->AddHistogram(histClass, "Mass_y_cosThetaCS_phiCS", "", 4, varsrapCS, binsy, xminy, xmaxy, 0, -1, kFALSE); } + if (subGroupStr.Contains("dimuon-polarization-pp")) { + int varspTPP[4] = {VarManager::kMass, VarManager::kPt, VarManager::kCosThetaPP, VarManager::kPhiPP}; + int varsrapPP[4] = {VarManager::kMass, VarManager::kRap, VarManager::kCosThetaPP, VarManager::kPhiPP}; + int binspT[4] = {100, 20, 20, 20}; + int binsy[4] = {100, 10, 20, 20}; + double xminpT[4] = {1., 0., -1., -3.14}; + double xmaxpT[4] = {5., 20., 1., +3.14}; + double xminy[4] = {1., 2.5, -1., -3.14}; + double xmaxy[4] = {5., 4.0, 1., +3.14}; + hm->AddHistogram(histClass, "Mass_Pt_cosThetaPP_phiPP", "", 4, varspTPP, binspT, xminpT, xmaxpT, 0, -1, kFALSE); + hm->AddHistogram(histClass, "Mass_y_cosThetaPP_phiPP", "", 4, varsrapPP, binsy, xminy, xmaxy, 0, -1, kFALSE); + } if (subGroupStr.Contains("upsilon-polarization-he")) { int varspTHE[4] = {VarManager::kMass, VarManager::kPt, VarManager::kCosThetaHE, VarManager::kPhiHE}; int varsrapHE[4] = {VarManager::kMass, VarManager::kRap, VarManager::kCosThetaHE, VarManager::kPhiHE}; @@ -1635,6 +1654,8 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h hm->AddHistogram(histClass, "MassD0region_Rapidity_AveragePt", "", true, 140, 1.5, 2.2, VarManager::kMass, 10, -0.8, 0.8, VarManager::kRap, 150, 0.0, 30.0, VarManager::kPt); hm->AddHistogram(histClass, "MassD0region_Pt_ITStrackOccupancy", "Pair mass vs pair Pt vs event ITS occupancy", false, 70, 1.5, 2.2, VarManager::kMass, 160, 0., 20., VarManager::kPt, 200, 0., 20000., VarManager::kTrackOccupancyInTimeRange); hm->AddHistogram(histClass, "MassD0region_TPCnSigKa_pIN", "Pair mass vs kaon cand. pIN vs kaon cand. TPC n-#sigma(K)", false, 140, 1.5, 2.2, VarManager::kMass, 100, 0.0, 10.0, VarManager::kPin_leg1, 20, -5.0, 5.0, VarManager::kTPCnSigmaKa_leg1); + hm->AddHistogram(histClass, "Mass_Pt_Ft0cOccupancy", "", false, 150, 0.0, 5.0, VarManager::kMass, 10, 0., 10., VarManager::kPt, 20, 0., 20000., VarManager::kFT0COccupancyInTimeRange); + hm->AddHistogram(histClass, "Mass_Pt_ITStrackOccupancy", "", false, 150, 0.0, 5.0, VarManager::kMass, 10, 0., 10., VarManager::kPt, 20, 0., 20000., VarManager::kTrackOccupancyInTimeRange); } if (subGroupStr.Contains("lambdac")) { hm->AddHistogram(histClass, "MassLambdacRegion", "", false, 50, 2.15, 2.4, VarManager::kMass); diff --git a/PWGDQ/Core/MCSignalLibrary.cxx b/PWGDQ/Core/MCSignalLibrary.cxx index 7872429efb8..53bff5b2b3d 100644 --- a/PWGDQ/Core/MCSignalLibrary.cxx +++ b/PWGDQ/Core/MCSignalLibrary.cxx @@ -126,6 +126,11 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) signal = new MCSignal(name, "Inclusive jpsi", {prong}, {-1}); return signal; } + if (!nameStr.compare("Helium3")) { + MCProng prong(1, {1000020030}, {true}, {false}, {0}, {0}, {false}); + signal = new MCSignal(name, "Helium3", {prong}, {-1}); + return signal; + } if (!nameStr.compare("Helium3Primary")) { MCProng prong(1, {1000020030}, {true}, {false}, {0}, {0}, {false}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); @@ -1466,12 +1471,29 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) signal = new MCSignal(name, "D0", {prong}, {-1}); return signal; } + if (!nameStr.compare("nonPromptD0")) { + MCProng prong(2, {Pdg::kD0, 503}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); + signal = new MCSignal(name, "Non-prompt D0", {prong}, {-1}); + return signal; + } + if (!nameStr.compare("D0FS")) { + MCProng prong(1, {Pdg::kD0}, {true}, {false}, {0}, {0}, {false}); + prong.SetSourceBit(0, MCProng::kHEPMCFinalState); + signal = new MCSignal(name, "D0", {prong}, {-1}); + return signal; + } if (!nameStr.compare("KPiFromD0")) { MCProng prongKaon(2, {321, Pdg::kD0}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); MCProng prongPion(2, {211, Pdg::kD0}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "Kaon and pion pair from D0", {prongKaon, prongPion}, {1, 1}); return signal; } + if (!nameStr.compare("KPiFromD0Reflected")) { + MCProng prongFalseKaon(2, {211, Pdg::kD0}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); + MCProng prongFalsePion(2, {321, Pdg::kD0}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); + signal = new MCSignal(name, "Kaon and pion pair from D0 with reflected mass assumption", {prongFalseKaon, prongFalsePion}, {1, 1}); + return signal; + } if (!nameStr.compare("Dcharged")) { MCProng prong(1, {Pdg::kDPlus}, {true}, {false}, {0}, {0}, {false}); signal = new MCSignal(name, "D+/-", {prong}, {-1}); diff --git a/PWGDQ/Core/VarManager.cxx b/PWGDQ/Core/VarManager.cxx index f9a71a28c9b..c329641916a 100644 --- a/PWGDQ/Core/VarManager.cxx +++ b/PWGDQ/Core/VarManager.cxx @@ -28,9 +28,6 @@ bool VarManager::fgUsedVars[VarManager::kNVars] = {false}; bool VarManager::fgUsedKF = false; float VarManager::fgMagField = 0.5; float VarManager::fgValues[VarManager::kNVars] = {0.0f}; -std::map VarManager::fgRunMap; -TString VarManager::fgRunStr = ""; -std::vector VarManager::fgRunList = {0}; float VarManager::fgCenterOfMassEnergy = 13600; // GeV float VarManager::fgMassofCollidingParticle = 9.382720; // GeV float VarManager::fgTPCInterSectorBoundary = 1.0; // cm @@ -110,69 +107,6 @@ void VarManager::ResetValues(int startValue, int endValue, float* values) } } -//__________________________________________________________________ -void VarManager::SetRunNumbers(int n, int* runs) -{ - // - // maps the list of runs such that one can plot the list of runs nicely in a histogram axis - // - for (int i = 0; i < n; ++i) { - fgRunMap[runs[i]] = i + 1; - fgRunStr += Form("%d;", runs[i]); - } -} - -//__________________________________________________________________ -void VarManager::SetRunNumbers(std::vector runs) -{ - // - // maps the list of runs such that one can plot the list of runs nicely in a histogram axis - // - int i = 0; - for (auto run = runs.begin(); run != runs.end(); run++, i++) { - fgRunMap[*run] = i + 1; - fgRunStr += Form("%d;", *run); - } - fgRunList = runs; -} - -//__________________________________________________________________ -void VarManager::SetDummyRunlist(int InitRunnumber) -{ - // - // runlist for the different periods - fgRunList.clear(); - fgRunList.push_back(InitRunnumber); - fgRunList.push_back(InitRunnumber + 100); -} - -//__________________________________________________________________ -int VarManager::GetDummyFirst() -{ - // - // Get the fist index of the vector of run numbers - // - return fgRunList[0]; -} -//__________________________________________________________________ -int VarManager::GetDummyLast() -{ - // - // Get the last index of the vector of run numbers - // - return fgRunList[fgRunList.size() - 1]; -} -//_________________________________________________________________ -float VarManager::GetRunIndex(double Runnumber) -{ - // - // Get the index of RunNumber in it's runlist - // - int runNumber = static_cast(Runnumber); - auto runIndex = std::find(fgRunList.begin(), fgRunList.end(), runNumber); - float index = std::distance(fgRunList.begin(), runIndex); - return index; -} //__________________________________________________________________ void VarManager::SetCollisionSystem(TString system, float energy) { @@ -191,15 +125,12 @@ void VarManager::SetCollisionSystem(TString system, float energy) } //__________________________________________________________________ -void VarManager::FillEventDerived(float* values) -{ - // - // Fill event-wise derived quantities (these are all quantities which can be computed just based on the values already filled in the FillEvent() function) - // - if (fgUsedVars[kRunId]) { - values[kRunId] = (fgRunMap.size() > 0 ? fgRunMap[static_cast(values[kRunNo])] : 0); - } -} +// void VarManager::FillEventDerived(float* values) +// { +// // +// // Fill event-wise derived quantities (these are all quantities which can be computed just based on the values already filled in the FillEvent() function) +// // +// } //__________________________________________________________________ void VarManager::FillTrackDerived(float* values) @@ -230,8 +161,6 @@ void VarManager::SetDefaultVarNames() fgVariableNames[kRunNo] = "Run number"; fgVariableUnits[kRunNo] = ""; - fgVariableNames[kRunId] = "Run number"; - fgVariableUnits[kRunId] = ""; fgVariableNames[kBC] = "Bunch crossing"; fgVariableUnits[kBC] = ""; fgVariableNames[kTimeFromSOR] = "time since SOR"; @@ -991,7 +920,7 @@ void VarManager::SetDefaultVarNames() fgVariableUnits[kDeltaPhi] = "rad."; fgVariableNames[kDeltaPhiSym] = "#Delta#phi"; fgVariableUnits[kDeltaPhiSym] = "rad."; - fgVariableNames[kCosThetaHE] = "cos#it{#theta}"; + fgVariableNames[kCosThetaHE] = "cos#it{#theta}_{HE}"; fgVariableUnits[kCosThetaHE] = ""; fgVariableNames[kPhiHE] = "#varphi_{HE}"; fgVariableUnits[kPhiHE] = "rad."; @@ -999,6 +928,10 @@ void VarManager::SetDefaultVarNames() fgVariableUnits[kCosThetaCS] = ""; fgVariableNames[kPhiCS] = "#varphi_{CS}"; fgVariableUnits[kPhiCS] = "rad."; + fgVariableNames[kCosThetaPP] = "cos#it{#theta}_{PP}"; + fgVariableUnits[kCosThetaPP] = ""; + fgVariableNames[kPhiPP] = "#varphi_{PP}"; + fgVariableUnits[kPhiPP] = "rad."; fgVariableNames[kCosPhiVP] = "cos#it{#varphi}_{VP}"; fgVariableUnits[kCosPhiVP] = ""; fgVariableNames[kPhiVP] = "#varphi_{VP} - #Psi_{2}"; @@ -1095,8 +1028,6 @@ void VarManager::SetDefaultVarNames() // Set the variables short names map. This is needed for dynamic configuration via JSON files fgVarNamesMap["kNothing"] = kNothing; fgVarNamesMap["kRunNo"] = kRunNo; - fgVarNamesMap["kRunId"] = kRunId; - fgVarNamesMap["kRunIndex"] = kRunIndex; fgVarNamesMap["kNRunWiseVariables"] = kNRunWiseVariables; fgVarNamesMap["kTimestamp"] = kTimestamp; fgVarNamesMap["kTimeFromSOR"] = kTimeFromSOR; @@ -1540,8 +1471,10 @@ void VarManager::SetDefaultVarNames() fgVarNamesMap["kVertexingChi2PCA"] = kVertexingChi2PCA; fgVarNamesMap["kCosThetaHE"] = kCosThetaHE; fgVarNamesMap["kCosThetaCS"] = kCosThetaCS; + fgVarNamesMap["kCosThetaPP"] = kCosThetaPP; fgVarNamesMap["kPhiHE"] = kPhiHE; fgVarNamesMap["kPhiCS"] = kPhiCS; + fgVarNamesMap["kPhiPP"] = kPhiPP; fgVarNamesMap["kCosPhiVP"] = kCosPhiVP; fgVarNamesMap["kPhiVP"] = kPhiVP; fgVarNamesMap["kDeltaPhiPair2"] = kDeltaPhiPair2; diff --git a/PWGDQ/Core/VarManager.h b/PWGDQ/Core/VarManager.h index 5a193eb0415..0f27dd6f260 100644 --- a/PWGDQ/Core/VarManager.h +++ b/PWGDQ/Core/VarManager.h @@ -175,8 +175,6 @@ class VarManager : public TObject kNothing = -1, // Run wise variables kRunNo = 0, - kRunId, - kRunIndex, kNRunWiseVariables, // Event wise variables @@ -648,8 +646,10 @@ class VarManager : public TObject kVertexingChi2PCA, kCosThetaHE, kCosThetaCS, + kCosThetaPP, kPhiHE, kPhiCS, + kPhiPP, kCosPhiVP, kPhiVP, kDeltaPhiPair2, @@ -898,29 +898,6 @@ class VarManager : public TObject return false; } - static void SetRunNumbers(int n, int* runs); - static void SetRunNumbers(std::vector runs); - static float GetRunIndex(double); - static void SetDummyRunlist(int InitRunnumber); - static int GetDummyFirst(); - static int GetDummyLast(); - static int GetDummyNRuns() - { - if (fgRunMap.size() == 0) { - return 101; - } else { - return fgRunMap.size(); - } - } - static int GetNRuns() - { - return fgRunMap.size(); - } - static TString GetRunStr() - { - return fgRunStr; - } - // Setup the collision system static void SetCollisionSystem(TString system, float energy); @@ -1159,9 +1136,6 @@ class VarManager : public TObject static void SetVariableDependencies(); // toggle those variables on which other used variables might depend static float fgMagField; - static std::map fgRunMap; // map of runs to be used in histogram axes - static TString fgRunStr; // semi-colon separated list of runs, to be used for histogram axis labels - static std::vector fgRunList; // vector of runs, to be used for histogram axis static float fgCenterOfMassEnergy; // collision energy static float fgMassofCollidingParticle; // mass of the colliding particle static float fgTPCInterSectorBoundary; // TPC inter-sector border size at the TPC outer radius, in cm @@ -1172,7 +1146,7 @@ class VarManager : public TObject static uint64_t fgSOR; // Timestamp for start of run static uint64_t fgEOR; // Timestamp for end of run - static void FillEventDerived(float* values = nullptr); + // static void FillEventDerived(float* values = nullptr); static void FillTrackDerived(float* values = nullptr); template static auto getRotatedCovMatrixXX(const T& matrix, U phi, V theta); @@ -1442,7 +1416,6 @@ void VarManager::FillBC(T const& bc, float* values) values[kBCOrbit] = bc.globalBC() % o2::constants::lhc::LHCMaxBunches; values[kTimestamp] = bc.timestamp(); values[kTimeFromSOR] = (fgSOR > 0 ? (bc.timestamp() - fgSOR) / 60000. : -1.0); - values[kRunIndex] = GetRunIndex(bc.runNumber()); } template @@ -1611,7 +1584,6 @@ void VarManager::FillEvent(T const& event, float* values) if constexpr ((fillMap & ReducedEvent) > 0) { values[kRunNo] = event.runNumber(); - values[kRunIndex] = GetRunIndex(event.runNumber()); values[kVtxX] = event.posX(); values[kVtxY] = event.posY(); values[kVtxZ] = event.posZ(); @@ -1903,7 +1875,7 @@ void VarManager::FillEvent(T const& event, float* values) FillZDC(event, values); } - FillEventDerived(values); + // FillEventDerived(values); } template @@ -2856,6 +2828,9 @@ void VarManager::FillPair(T1 const& t1, T2 const& t2, float* values) ROOT::Math::XYZVectorF yaxis_CS{(Beam1_CM.Cross(Beam2_CM)).Unit()}; ROOT::Math::XYZVectorF xaxis_CS{(yaxis_CS.Cross(zaxis_CS)).Unit()}; + // Production frame + ROOT::Math::XYZVector normalVec = ROOT::Math::XYZVector(v12.Py(), -v12.Px(), 0.f); + if (fgUsedVars[kCosThetaHE]) { values[kCosThetaHE] = (t1.sign() > 0 ? zaxis_HE.Dot(v1_CM) : zaxis_HE.Dot(v2_CM)); } @@ -2872,6 +2847,14 @@ void VarManager::FillPair(T1 const& t1, T2 const& t2, float* values) values[kPhiCS] = (t1.sign() > 0 ? TMath::ATan2(yaxis_CS.Dot(v1_CM), xaxis_CS.Dot(v1_CM)) : TMath::ATan2(yaxis_CS.Dot(v2_CM), xaxis_CS.Dot(v2_CM))); } + if (fgUsedVars[kCosThetaPP]) { + values[kCosThetaPP] = (t1.sign() > 0 ? normalVec.Dot(v1_CM) : normalVec.Dot(v2_CM)); + } + + if (fgUsedVars[kPhiPP]) { + values[kPhiPP] = (t1.sign() > 0 ? TMath::ATan2((normalVec.Dot(v1_CM)), zaxis_HE.Dot(v1_CM)) : TMath::ATan2((normalVec.Dot(v2_CM)), zaxis_HE.Dot(v2_CM))); + } + if constexpr ((pairType == kDecayToEE) && ((fillMap & TrackCov) > 0 || (fillMap & ReducedTrackBarrelCov) > 0)) { if (fgUsedVars[kQuadDCAabsXY] || fgUsedVars[kQuadDCAsigXY] || fgUsedVars[kQuadDCAabsZ] || fgUsedVars[kQuadDCAsigZ] || fgUsedVars[kQuadDCAsigXYZ] || fgUsedVars[kSignQuadDCAsigXY]) { diff --git a/PWGDQ/DataModel/ReducedInfoTables.h b/PWGDQ/DataModel/ReducedInfoTables.h index 5a0f9809734..dcf27f9ac9c 100644 --- a/PWGDQ/DataModel/ReducedInfoTables.h +++ b/PWGDQ/DataModel/ReducedInfoTables.h @@ -1012,6 +1012,14 @@ DECLARE_SOA_TABLE(V0Bits, "AOD", "V0BITS", //! // iterators using V0Bit = V0Bits::iterator; +namespace v0mapID +{ +DECLARE_SOA_COLUMN(V0AddID, v0addid, int8_t); //! +} // namespace v0mapID + +DECLARE_SOA_TABLE(V0MapID, "AOD", "V0MAPID", //! + v0mapID::V0AddID); + namespace DalBits { DECLARE_SOA_COLUMN(DALITZBits, dalitzBits, uint8_t); //! diff --git a/PWGDQ/TableProducer/tableMaker.cxx b/PWGDQ/TableProducer/tableMaker.cxx index 74545704593..bde53864977 100644 --- a/PWGDQ/TableProducer/tableMaker.cxx +++ b/PWGDQ/TableProducer/tableMaker.cxx @@ -206,8 +206,6 @@ struct TableMaker { Configurable fConfigComputeTPCpostCalib{"cfgTPCpostCalib", false, "If true, compute TPC post-calibrated n-sigmas(electrons, pions, protons)"}; Configurable fConfigComputeTPCpostCalibKaon{"cfgTPCpostCalibKaon", false, "If true, compute TPC post-calibrated n-sigmas for kaons"}; Configurable fConfigIsOnlyforMaps{"cfgIsforMaps", false, "If true, run for postcalibration maps only"}; - Configurable fConfigDummyRunlist{"cfgDummyRunlist", false, "If true, use dummy runlist"}; - Configurable fConfigInitRunNumber{"cfgInitRunNumber", 543215, "Initial run number used in run by run checks"}; Configurable fPropMuon{"cfgPropMuon", false, "Propgate muon tracks through absorber"}; Configurable geoPath{"geoPath", "GLO/Config/GeometryAligned", "Path of the geometry file"}; Configurable grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; @@ -334,10 +332,6 @@ struct TableMaker { } } - if (fConfigDummyRunlist) { - VarManager::SetDummyRunlist(fConfigInitRunNumber); - } - DefineHistograms(histClasses); // define all histograms VarManager::SetUseVars(fHistMan->GetUsedVars()); // provide the list of required variables so that VarManager knows what to fill fOutputList.setObject(fHistMan->GetMainHistogramList()); @@ -441,7 +435,6 @@ struct TableMaker { VarManager::fgValues[VarManager::kRunNo] = bc.runNumber(); VarManager::fgValues[VarManager::kBC] = bc.globalBC(); VarManager::fgValues[VarManager::kTimestamp] = bc.timestamp(); - VarManager::fgValues[VarManager::kRunIndex] = VarManager::GetRunIndex(bc.runNumber()); VarManager::FillEvent(collision); // extract event information and place it in the fValues array if (fDoDetailedQA) { fHistMan->FillHistClass("Event_BeforeCuts", VarManager::fgValues); @@ -915,7 +908,6 @@ struct TableMaker { VarManager::fgValues[VarManager::kRunNo] = bc.runNumber(); VarManager::fgValues[VarManager::kBC] = bc.globalBC(); VarManager::fgValues[VarManager::kTimestamp] = bc.timestamp(); - VarManager::fgValues[VarManager::kRunIndex] = VarManager::GetRunIndex(bc.runNumber()); VarManager::FillEvent(collision); // extract event information and place it in the fValues array if (fDoDetailedQA) { fHistMan->FillHistClass("Event_BeforeCuts", VarManager::fgValues); diff --git a/PWGDQ/TableProducer/tableMakerMC_withAssoc.cxx b/PWGDQ/TableProducer/tableMakerMC_withAssoc.cxx index aa35c36a0ec..440a24a3ec1 100644 --- a/PWGDQ/TableProducer/tableMakerMC_withAssoc.cxx +++ b/PWGDQ/TableProducer/tableMakerMC_withAssoc.cxx @@ -16,6 +16,7 @@ // The skimmed MC stack includes the MC truth particles corresponding to the list of user specified MC signals (see MCsignal.h) // and the MC truth particles corresponding to the reconstructed tracks selected by the specified track cuts on reconstructed data. +#include #include #include #include @@ -86,6 +87,7 @@ using MyMuonsWithCov = soa::Join; using MyEventsWithMults = soa::Join; +using MyEventsWithMultsAndRapidityGapFilter = soa::Join; using MyEventsWithCent = soa::Join; using MyEventsWithCentAndMults = soa::Join; using MFTTrackLabeled = soa::Join; @@ -95,6 +97,7 @@ constexpr static uint32_t gkEventFillMap = VarManager::ObjTypes::BC | VarManager constexpr static uint32_t gkEventFillMapWithMults = VarManager::ObjTypes::BC | VarManager::ObjTypes::Collision | VarManager::ObjTypes::CollisionMult | VarManager::ObjTypes::CollisionMultExtra; // constexpr static uint32_t gkEventFillMapWithCent = VarManager::ObjTypes::BC | VarManager::ObjTypes::Collision | VarManager::ObjTypes::CollisionCent; constexpr static uint32_t gkEventFillMapWithCentAndMults = VarManager::ObjTypes::BC | VarManager::ObjTypes::Collision | VarManager::ObjTypes::CollisionCent | VarManager::CollisionMult | VarManager::CollisionMultExtra; +constexpr static uint32_t gkEventFillMapWithMultsRapidityGapFilter = VarManager::ObjTypes::BC | VarManager::ObjTypes::Collision | VarManager::ObjTypes::CollisionMult | VarManager::ObjTypes::CollisionMultExtra | VarManager::ObjTypes::RapidityGapFilter; // constexpr static uint32_t gkEventMCFillMap = VarManager::ObjTypes::CollisionMC; // constexpr static uint32_t gkTrackFillMap = VarManager::ObjTypes::Track | VarManager::ObjTypes::TrackExtra | VarManager::ObjTypes::TrackDCA | VarManager::ObjTypes::TrackSelection | VarManager::ObjTypes::TrackPID; constexpr static uint32_t gkTrackFillMapWithCov = VarManager::ObjTypes::Track | VarManager::ObjTypes::TrackExtra | VarManager::ObjTypes::TrackDCA | VarManager::ObjTypes::TrackSelection | VarManager::ObjTypes::TrackCov | VarManager::ObjTypes::TrackPID; @@ -236,7 +239,7 @@ struct TableMakerMC { { // Check whether barrel or muon are enabled bool isProcessBCenabled = context.mOptions.get("processPP"); - bool isBarrelEnabled = (context.mOptions.get("processPP") || context.mOptions.get("processPPBarrelOnly") || context.mOptions.get("processPbPbBarrelOnly")); + bool isBarrelEnabled = (context.mOptions.get("processPP") || context.mOptions.get("processPPBarrelOnly") || context.mOptions.get("processPbPbBarrelOnly") || context.mOptions.get("processPbPbWithFilterBarrelOnly")); bool isMuonEnabled = (context.mOptions.get("processPP") || context.mOptions.get("processPPMuonOnlyBasic") || context.mOptions.get("processPPMuonOnly") || context.mOptions.get("processPbPbMuonOnly")); // Make sure at least one process function is enabled if (!(isProcessBCenabled || isBarrelEnabled || isMuonEnabled)) { @@ -553,6 +556,13 @@ struct TableMakerMC { } (reinterpret_cast(fStatsList->At(0)))->Fill(1.0, static_cast(o2::aod::evsel::kNsel)); + // apply the event filter + if constexpr ((TEventFillMap & VarManager::ObjTypes::RapidityGapFilter) > 0) { + if (!collision.eventFilter()) { + continue; + } + } + auto bc = collision.template bc_as(); // store the selection decisions uint64_t tag = static_cast(0); @@ -562,6 +572,10 @@ struct TableMakerMC { if (bcEvSel.globalIndex() != bc.globalIndex()) { tag |= (static_cast(1) << 0); } + // Put the 8 first bits of the event filter in the last 8 bits of the tag + if constexpr ((TEventFillMap & VarManager::ObjTypes::RapidityGapFilter) > 0) { + tag |= (collision.eventFilter() << 56); + } // Compute BC and event quantities and fill histograms VarManager::ResetValues(0, VarManager::kNEventWiseVariables); @@ -602,16 +616,25 @@ struct TableMakerMC { event(tag, bc.runNumber(), collision.posX(), collision.posY(), collision.posZ(), collision.numContrib(), collision.collisionTime(), collision.collisionTimeRes()); if constexpr ((TEventFillMap & VarManager::ObjTypes::CollisionMult) > 0) { multTPC = collision.multTPC(); - multFV0A = collision.multFV0A(); multFV0C = collision.multFV0C(); - multFT0A = collision.multFT0A(); - multFT0C = collision.multFT0C(); - multFDDA = collision.multFDDA(); - multFDDC = collision.multFDDC(); multZNA = collision.multZNA(); multZNC = collision.multZNC(); multTracklets = collision.multTracklets(); multTracksPV = collision.multNTracksPV(); + if constexpr ((TEventFillMap & VarManager::ObjTypes::RapidityGapFilter) > 0) { + // Use the FIT signals from the nearest BC with FIT amplitude above threshold + multFV0A = collision.newBcMultFV0A(); + multFT0A = collision.newBcMultFT0A(); + multFT0C = collision.newBcMultFT0C(); + multFDDA = collision.newBcMultFDDA(); + multFDDC = collision.newBcMultFDDC(); + } else { + multFV0A = collision.multFV0A(); + multFT0A = collision.multFT0A(); + multFT0C = collision.multFT0C(); + multFDDA = collision.multFDDA(); + multFDDC = collision.multFDDC(); + } } if constexpr ((TEventFillMap & VarManager::ObjTypes::CollisionCent) > 0) { centFT0C = collision.centFT0C(); @@ -1338,6 +1361,13 @@ struct TableMakerMC { fullSkimming(collisions, bcs, tracksBarrel, nullptr, nullptr, trackAssocs, nullptr, nullptr, mcCollisions, mcParticles); } + void processPbPbWithFilterBarrelOnly(MyEventsWithMultsAndRapidityGapFilter const& collisions, aod::BCsWithTimestamps const& bcs, + MyBarrelTracksWithCov const& tracksBarrel, aod::TrackAssoc const& trackAssocs, + aod::McCollisions const& mcCollisions, aod::McParticles const& mcParticles) + { + fullSkimming(collisions, bcs, tracksBarrel, nullptr, nullptr, trackAssocs, nullptr, nullptr, mcCollisions, mcParticles); + } + void processPbPbMuonOnly(MyEventsWithCentAndMults const& collisions, aod::BCsWithTimestamps const& bcs, MyMuonsWithCov const& tracksMuon, MFTTrackLabeled const& mftTracks, aod::FwdTrackAssoc const& fwdTrackAssocs, aod::MFTTrackAssoc const& mftAssocs, @@ -1363,6 +1393,7 @@ struct TableMakerMC { PROCESS_SWITCH(TableMakerMC, processPPMuonOnly, "Produce only muon skims, pp settings", false); PROCESS_SWITCH(TableMakerMC, processPbPb, "Produce both barrel and muon skims, PbPb settings", false); PROCESS_SWITCH(TableMakerMC, processPbPbBarrelOnly, "Produce only barrel skims, PbPb settings", false); + PROCESS_SWITCH(TableMakerMC, processPbPbWithFilterBarrelOnly, "Produce only barrel skims, pp settings with rapidity gap filter ", false); PROCESS_SWITCH(TableMakerMC, processPbPbMuonOnly, "Produce only muon skims, PbPb settings", false); PROCESS_SWITCH(TableMakerMC, processOnlyBCs, "Analyze the BCs to store sampled lumi", false); }; diff --git a/PWGDQ/TableProducer/tableMaker_withAssoc.cxx b/PWGDQ/TableProducer/tableMaker_withAssoc.cxx index 7adb6fbf23c..a6d72986bef 100644 --- a/PWGDQ/TableProducer/tableMaker_withAssoc.cxx +++ b/PWGDQ/TableProducer/tableMaker_withAssoc.cxx @@ -36,6 +36,7 @@ #include "Common/DataModel/PIDResponse.h" #include "Common/DataModel/TrackSelectionTables.h" #include "Common/DataModel/MftmchMatchingML.h" +#include "Common/DataModel/FwdTrackReAlignTables.h" #include "Common/Core/TableHelper.h" #include "PWGDQ/DataModel/ReducedInfoTables.h" #include "PWGDQ/Core/VarManager.h" @@ -105,6 +106,7 @@ using MyEventsWithCentAndMults = soa::Join; using MyMuons = soa::Join; using MyMuonsWithCov = soa::Join; +using MyMuonsRealignWithCov = soa::Join; using MyMuonsColl = soa::Join; using MyMuonsCollWithCov = soa::Join; using MyBCs = soa::Join; @@ -130,6 +132,7 @@ constexpr static uint32_t gkTrackFillMapWithV0BitsNoTOF = VarManager::ObjTypes:: // constexpr static uint32_t gkTrackFillMapWithDalitzBits = gkTrackFillMap | VarManager::ObjTypes::DalitzBits; // constexpr static uint32_t gkMuonFillMap = VarManager::ObjTypes::Muon; constexpr static uint32_t gkMuonFillMapWithCov = VarManager::ObjTypes::Muon | VarManager::ObjTypes::MuonCov; +constexpr static uint32_t gkMuonRealignFillMapWithCov = VarManager::ObjTypes::MuonRealign | VarManager::ObjTypes::MuonCovRealign; // constexpr static uint32_t gkMuonFillMapWithAmbi = VarManager::ObjTypes::Muon | VarManager::ObjTypes::AmbiMuon; // constexpr static uint32_t gkMuonFillMapWithCovAmbi = VarManager::ObjTypes::Muon | VarManager::ObjTypes::MuonCov | VarManager::ObjTypes::AmbiMuon; // constexpr static uint32_t gkTrackFillMapWithAmbi = VarManager::ObjTypes::Track | VarManager::ObjTypes::AmbiTrack; @@ -233,8 +236,6 @@ struct TableMaker { Configurable fConfigComputeTPCpostCalibKaon{"cfgTPCpostCalibKaon", false, "If true, compute TPC post-calibrated n-sigmas for kaons"}; Configurable fConfigIsOnlyforMaps{"cfgIsforMaps", false, "If true, run for postcalibration maps only"}; Configurable fConfigSaveElectronSample{"cfgSaveElectronSample", false, "If true, only save electron sample"}; - Configurable fConfigDummyRunlist{"cfgDummyRunlist", false, "If true, use dummy runlist"}; - Configurable fConfigInitRunNumber{"cfgInitRunNumber", 543215, "Initial run number used in run by run checks"}; } fConfigPostCalibTPC; struct : ConfigurableGroup { @@ -289,6 +290,8 @@ struct TableMaker { Preslice trackIndicesPerCollision = aod::track_association::collisionId; Preslice fwdtrackIndicesPerCollision = aod::track_association::collisionId; Preslice mfttrackIndicesPerCollision = aod::track_association::collisionId; + PresliceUnsorted perCollisionMuonsRealign = aod::fwdtrackrealign::collisionId; + PresliceUnsorted fwdtrackRealignPerMuon = aod::fwdtrackrealign::fwdtrackId; Preslice preslice = aod::track::collisionId; Partition tracksPos = (((aod::track::flags & static_cast(o2::aod::track::PVContributor)) == static_cast(o2::aod::track::PVContributor)) && (aod::track::tgl > static_cast(0.05))); @@ -362,8 +365,8 @@ struct TableMaker { context.mOptions.get("processPbPb") || context.mOptions.get("processPbPbBarrelOnly") || context.mOptions.get("processPbPbBarrelOnlyWithV0Bits") || context.mOptions.get("processPbPbBarrelOnlyWithV0BitsNoTOF")) || context.mOptions.get("processPbPbWithFilterBarrelOnly") || context.mOptions.get("processPPBarrelOnlyWithV0s"); - bool enableMuonHistos = (context.mOptions.get("processPPWithFilter") || context.mOptions.get("processPPWithFilterMuonOnly") || context.mOptions.get("processPPWithFilterMuonMFT") || context.mOptions.get("processPPMuonOnly") || context.mOptions.get("processPPMuonMFT") || context.mOptions.get("processPPMuonMFTWithMultsExtra") || - context.mOptions.get("processPbPb") || context.mOptions.get("processPbPbMuonOnly") || context.mOptions.get("processPbPbMuonMFT")); + bool enableMuonHistos = (context.mOptions.get("processPPWithFilter") || context.mOptions.get("processPPWithFilterMuonOnly") || context.mOptions.get("processPPWithFilterMuonMFT") || context.mOptions.get("processPPMuonOnly") || context.mOptions.get("processPPRealignedMuonOnly") || context.mOptions.get("processPPMuonMFT") || context.mOptions.get("processPPMuonMFTWithMultsExtra") || + context.mOptions.get("processPbPb") || context.mOptions.get("processPbPbMuonOnly") || context.mOptions.get("processPbPbRealignedMuonOnly") || context.mOptions.get("processPbPbMuonMFT")); if (enableBarrelHistos) { // Barrel track histograms, before selections @@ -397,10 +400,6 @@ struct TableMaker { } } - if (fConfigPostCalibTPC.fConfigDummyRunlist) { - VarManager::SetDummyRunlist(fConfigPostCalibTPC.fConfigInitRunNumber); - } - DefineHistograms(histClasses); // define all histograms // Additional histogram via the JSON configurable TString addHistsStr = fConfigHistOutput.fConfigAddJSONHistograms.value; @@ -1116,8 +1115,8 @@ struct TableMaker { } } - template - void skimMuons(TEvent const& collision, TBCs const& /*bcs*/, TMuons const& muons, FwdTrackAssoc const& muonAssocs, TMFTTracks const& /*mftTracks*/) + template + void skimMuons(TEvent const& collision, TBCs const& /*bcs*/, TMuons const& muons, TMuonsRealign const& muonsRealign, FwdTrackAssoc const& muonAssocs, TMFTTracks const& /*mftTracks*/) { // Skim the fwd-tracks (muons) // Loop over the collision-track associations, recompute track properties depending on the collision assigned, and apply track cuts for selection @@ -1157,7 +1156,28 @@ struct TableMaker { auto mfttrack = muon.template matchMFTTrack_as(); VarManager::FillGlobalMuonRefit(muontrack, mfttrack, collision); } else { - VarManager::FillTrackCollision(muon, collision); + if constexpr ((static_cast(TMuonRealignFillMap))) { + if (static_cast(muon.trackType()) > 2) { + // refill kinematic info and recalculate propagation in case of using realigned muons + auto muonRealignSelected = muonsRealign.sliceBy(fwdtrackRealignPerMuon, assoc.fwdtrackId()); + if (muonRealignSelected.size() == 1) { + for (const auto& muonRealign : muonRealignSelected) { + // refill muon information with realigned tracks + VarManager::FillTrack(muonRealign); + + if (fConfigVariousOptions.fPropMuon) { + VarManager::FillPropagateMuon(muonRealign, collision); + } + + VarManager::FillTrackCollision(muonRealign, collision); + } + } else { + LOGF(fatal, "Inconsistent size of realigned muon track candidates."); + } + } + } else { + VarManager::FillTrackCollision(muon, collision); + } } if (fDoDetailedQA) { @@ -1228,23 +1248,46 @@ struct TableMaker { VarManager::FillPropagateMuon(muon, collision); } // recalculte pDca and global muon kinematics + int globalClusters = muon.nClusters(); if (static_cast(muon.trackType()) < 2 && fConfigVariousOptions.fRefitGlobalMuon) { auto muontrack = muon.template matchMCHTrack_as(); auto mfttrack = muon.template matchMFTTrack_as(); + globalClusters += mfttrack.nClusters(); VarManager::FillTrackCollision(muontrack, collision); VarManager::FillGlobalMuonRefit(muontrack, mfttrack, collision); } else { - VarManager::FillTrackCollision(muon, collision); + if constexpr ((static_cast(TMuonRealignFillMap))) { + if (static_cast(muon.trackType()) > 2) { + // refill kinematic info and recalculate propagation in case of using realigned muons + auto muonRealignSelected = muonsRealign.sliceBy(fwdtrackRealignPerMuon, muon.globalIndex()); + if (muonRealignSelected.size() == 1) { + for (const auto& muonRealign : muonRealignSelected) { + // refill muon information with realigned tracks + VarManager::FillTrack(muonRealign); + + if (fConfigVariousOptions.fPropMuon) { + VarManager::FillPropagateMuon(muonRealign, collision); + } + + VarManager::FillTrackCollision(muonRealign, collision); + } + } else { + LOGF(fatal, "Inconsistent size of realigned muon track candidates."); + } + } + } else { + VarManager::FillTrackCollision(muon, collision); + } } muonBasic(reducedEventIdx, mchIdx, mftIdx, fFwdTrackFilterMap[muon.globalIndex()], VarManager::fgValues[VarManager::kPt], VarManager::fgValues[VarManager::kEta], VarManager::fgValues[VarManager::kPhi], muon.sign(), 0); - muonExtra(muon.nClusters(), VarManager::fgValues[VarManager::kMuonPDca], VarManager::fgValues[VarManager::kMuonRAtAbsorberEnd], - muon.chi2(), muon.chi2MatchMCHMID(), muon.chi2MatchMCHMFT(), + muonExtra(globalClusters, VarManager::fgValues[VarManager::kMuonPDca], VarManager::fgValues[VarManager::kMuonRAtAbsorberEnd], + VarManager::fgValues[VarManager::kMuonChi2], muon.chi2MatchMCHMID(), muon.chi2MatchMCHMFT(), muon.matchScoreMCHMFT(), muon.mchBitMap(), muon.midBitMap(), muon.midBoards(), muon.trackType(), VarManager::fgValues[VarManager::kMuonDCAx], VarManager::fgValues[VarManager::kMuonDCAy], muon.trackTime(), muon.trackTimeRes()); muonInfo(muon.collisionId(), collision.posX(), collision.posY(), collision.posZ()); - if constexpr (static_cast(TMuonFillMap & VarManager::ObjTypes::MuonCov)) { + if constexpr (static_cast(TMuonFillMap & VarManager::ObjTypes::MuonCov) || static_cast(TMuonRealignFillMap & VarManager::ObjTypes::MuonCovRealign)) { muonCov(VarManager::fgValues[VarManager::kX], VarManager::fgValues[VarManager::kY], VarManager::fgValues[VarManager::kZ], VarManager::fgValues[VarManager::kPhi], VarManager::fgValues[VarManager::kTgl], muon.sign() / VarManager::fgValues[VarManager::kPt], VarManager::fgValues[VarManager::kMuonCXX], VarManager::fgValues[VarManager::kMuonCXY], VarManager::fgValues[VarManager::kMuonCYY], VarManager::fgValues[VarManager::kMuonCPhiX], VarManager::fgValues[VarManager::kMuonCPhiY], VarManager::fgValues[VarManager::kMuonCPhiPhi], VarManager::fgValues[VarManager::kMuonCTglX], VarManager::fgValues[VarManager::kMuonCTglY], VarManager::fgValues[VarManager::kMuonCTglPhi], VarManager::fgValues[VarManager::kMuonCTglTgl], VarManager::fgValues[VarManager::kMuonC1Pt2X], VarManager::fgValues[VarManager::kMuonC1Pt2Y], @@ -1254,11 +1297,11 @@ struct TableMaker { } // end skimMuons // Produce standard barrel + muon tables with event filter (typically for pp and p-Pb) ------------------------------------------------------ - template void fullSkimming(TEvents const& collisions, TBCs const& bcs, TZdcs const& zdcs, - TTracks const& tracksBarrel, TMuons const& muons, TMFTTracks const& mftTracks, + TTracks const& tracksBarrel, TMuons const& muons, TMuonsRealign const& muonsRealign, TMFTTracks const& mftTracks, TTrackAssoc const& trackAssocs, TFwdTrackAssoc const& fwdTrackAssocs, TMFTTrackAssoc const& mftAssocs) { @@ -1353,10 +1396,16 @@ struct TableMaker { if constexpr (static_cast(TMuonFillMap)) { if constexpr (static_cast(TMFTFillMap)) { auto groupedMuonIndices = fwdTrackAssocs.sliceBy(fwdtrackIndicesPerCollision, origIdx); - skimMuons(collision, bcs, muons, groupedMuonIndices, mftTracks); + skimMuons(collision, bcs, muons, nullptr, groupedMuonIndices, mftTracks); } else { - auto groupedMuonIndices = fwdTrackAssocs.sliceBy(fwdtrackIndicesPerCollision, origIdx); - skimMuons(collision, bcs, muons, groupedMuonIndices, nullptr); + if constexpr (static_cast(TMuonRealignFillMap)) { + auto groupedMuonIndices = fwdTrackAssocs.sliceBy(fwdtrackIndicesPerCollision, origIdx); + auto muonsRealignThisCollision = muonsRealign.sliceBy(perCollisionMuonsRealign, origIdx); + skimMuons(collision, bcs, muons, muonsRealignThisCollision, groupedMuonIndices, nullptr); + } else { + auto groupedMuonIndices = fwdTrackAssocs.sliceBy(fwdtrackIndicesPerCollision, origIdx); + skimMuons(collision, bcs, muons, nullptr, groupedMuonIndices, nullptr); + } } } } // end loop over skimmed collisions @@ -1373,7 +1422,7 @@ struct TableMaker { TrackAssoc const& trackAssocs, FwdTrackAssoc const& fwdTrackAssocs, MFTTrackAssoc const& mftAssocs) { - fullSkimming(collisions, bcs, nullptr, tracksBarrel, muons, mftTracks, trackAssocs, fwdTrackAssocs, mftAssocs); + fullSkimming(collisions, bcs, nullptr, tracksBarrel, muons, nullptr, mftTracks, trackAssocs, fwdTrackAssocs, mftAssocs); } // produce the barrel-only DQ skimmed data model typically for pp/p-Pb or UPC Pb-Pb (no centrality), subscribe to the DQ event filter (filter-pp or filter-PbPb) @@ -1381,14 +1430,14 @@ struct TableMaker { MyBarrelTracksWithCov const& tracksBarrel, TrackAssoc const& trackAssocs) { - fullSkimming(collisions, bcs, zdcs, tracksBarrel, nullptr, nullptr, trackAssocs, nullptr, nullptr); + fullSkimming(collisions, bcs, zdcs, tracksBarrel, nullptr, nullptr, nullptr, trackAssocs, nullptr, nullptr); } // produce the muon-only DQ skimmed data model typically for pp/p-Pb or UPC Pb-Pb (no centrality), subscribe to the DQ event filter (filter-pp or filter-PbPb) void processPPWithFilterMuonOnly(MyEventsWithMultsAndFilter const& collisions, BCsWithTimestamps const& bcs, MyMuonsWithCov const& muons, FwdTrackAssoc const& fwdTrackAssocs) { - fullSkimming(collisions, bcs, nullptr, nullptr, muons, nullptr, nullptr, fwdTrackAssocs, nullptr); + fullSkimming(collisions, bcs, nullptr, nullptr, muons, nullptr, nullptr, nullptr, fwdTrackAssocs, nullptr); } // produce the muon+mft DQ skimmed data model typically for pp/p-Pb or UPC Pb-Pb (no centrality), subscribe to the DQ event filter (filter-pp or filter-PbPb) @@ -1396,7 +1445,7 @@ struct TableMaker { MyMuonsWithCov const& muons, MFTTracks const& mftTracks, FwdTrackAssoc const& fwdTrackAssocs, MFTTrackAssoc const& mftAssocs) { - fullSkimming(collisions, bcs, nullptr, nullptr, muons, mftTracks, nullptr, fwdTrackAssocs, mftAssocs); + fullSkimming(collisions, bcs, nullptr, nullptr, muons, nullptr, mftTracks, nullptr, fwdTrackAssocs, mftAssocs); } // produce the barrel-only DQ skimmed data model typically for pp/p-Pb or UPC Pb-Pb (no centrality), meant to run on skimmed data @@ -1404,7 +1453,7 @@ struct TableMaker { MyBarrelTracksWithCov const& tracksBarrel, TrackAssoc const& trackAssocs) { - fullSkimming(collisions, bcs, zdcs, tracksBarrel, nullptr, nullptr, trackAssocs, nullptr, nullptr); + fullSkimming(collisions, bcs, zdcs, tracksBarrel, nullptr, nullptr, nullptr, trackAssocs, nullptr, nullptr); } // produce the barrel-only DQ skimmed barrel data model, with V0 tagged tracks @@ -1412,14 +1461,21 @@ struct TableMaker { MyBarrelTracksWithV0BitsNoTOF const& tracksBarrel, TrackAssoc const& trackAssocs) { - fullSkimming(collisions, bcs, nullptr, tracksBarrel, nullptr, nullptr, trackAssocs, nullptr, nullptr); + fullSkimming(collisions, bcs, nullptr, tracksBarrel, nullptr, nullptr, nullptr, trackAssocs, nullptr, nullptr); } // produce the muon-only DQ skimmed data model typically for pp/p-Pb or UPC Pb-Pb (no centrality), meant to run on skimmed data void processPPMuonOnly(MyEventsWithMults const& collisions, BCsWithTimestamps const& bcs, MyMuonsWithCov const& muons, FwdTrackAssoc const& fwdTrackAssocs) { - fullSkimming(collisions, bcs, nullptr, nullptr, muons, nullptr, nullptr, fwdTrackAssocs, nullptr); + fullSkimming(collisions, bcs, nullptr, nullptr, muons, nullptr, nullptr, nullptr, fwdTrackAssocs, nullptr); + } + + // produce the realigned muon-only DQ skimmed data model typically for pp/p-Pb or UPC Pb-Pb (no centrality), meant to run on skimmed data + void processPPRealignedMuonOnly(MyEventsWithMults const& collisions, BCsWithTimestamps const& bcs, + MyMuonsWithCov const& muons, MyMuonsRealignWithCov const& muonsRealign, FwdTrackAssoc const& fwdTrackAssocs) + { + fullSkimming(collisions, bcs, nullptr, nullptr, muons, muonsRealign, nullptr, nullptr, fwdTrackAssocs, nullptr); } // produce the muon+mft DQ skimmed data model typically for pp/p-Pb or UPC Pb-Pb (no centrality), meant to run on skimmed data @@ -1427,7 +1483,7 @@ struct TableMaker { MyMuonsWithCov const& muons, MFTTracks const& mftTracks, FwdTrackAssoc const& fwdTrackAssocs, MFTTrackAssoc const& mftAssocs) { - fullSkimming(collisions, bcs, nullptr, nullptr, muons, mftTracks, nullptr, fwdTrackAssocs, mftAssocs); + fullSkimming(collisions, bcs, nullptr, nullptr, muons, nullptr, mftTracks, nullptr, fwdTrackAssocs, mftAssocs); } // Central barrel multiplicity estimation @@ -1435,7 +1491,7 @@ struct TableMaker { MyMuonsWithCov const& muons, MFTTracks const& mftTracks, FwdTrackAssoc const& fwdTrackAssocs, MFTTrackAssoc const& mftAssocs) { - fullSkimming(collisions, bcs, nullptr, nullptr, muons, mftTracks, nullptr, fwdTrackAssocs, mftAssocs); + fullSkimming(collisions, bcs, nullptr, nullptr, muons, nullptr, mftTracks, nullptr, fwdTrackAssocs, mftAssocs); } // produce the full DQ skimmed data model typically for Pb-Pb (with centrality), no subscribtion to the DQ event filter @@ -1445,7 +1501,7 @@ struct TableMaker { TrackAssoc const& trackAssocs, FwdTrackAssoc const& fwdTrackAssocs, MFTTrackAssoc const& mftAssocs) { - fullSkimming(collisions, bcs, nullptr, tracksBarrel, muons, mftTracks, trackAssocs, fwdTrackAssocs, mftAssocs); + fullSkimming(collisions, bcs, nullptr, tracksBarrel, muons, nullptr, mftTracks, trackAssocs, fwdTrackAssocs, mftAssocs); } // produce the barrel only DQ skimmed data model typically for Pb-Pb (with centrality), no subscribtion to the DQ event filter @@ -1453,7 +1509,7 @@ struct TableMaker { MyBarrelTracksWithCov const& tracksBarrel, TrackAssoc const& trackAssocs) { - fullSkimming(collisions, bcs, nullptr, tracksBarrel, nullptr, nullptr, trackAssocs, nullptr, nullptr); + fullSkimming(collisions, bcs, nullptr, tracksBarrel, nullptr, nullptr, nullptr, trackAssocs, nullptr, nullptr); } // produce the barrel-only DQ skimmed data model typically for UPC Pb-Pb (no centrality), subscribe to the DQ rapidity gap event filter (filter-PbPb) @@ -1461,7 +1517,7 @@ struct TableMaker { MyBarrelTracksWithCov const& tracksBarrel, TrackAssoc const& trackAssocs) { - fullSkimming(collisions, bcs, zdcs, tracksBarrel, nullptr, nullptr, trackAssocs, nullptr, nullptr); + fullSkimming(collisions, bcs, zdcs, tracksBarrel, nullptr, nullptr, nullptr, trackAssocs, nullptr, nullptr); } // produce the barrel only DQ skimmed data model typically for Pb-Pb (with centrality), no subscribtion to the DQ event filter @@ -1470,7 +1526,7 @@ struct TableMaker { TrackAssoc const& trackAssocs) { computeOccupancyEstimators(collisions, tracksPos, tracksNeg, preslice, bcs); - fullSkimming(collisions, bcs, nullptr, tracksBarrel, nullptr, nullptr, trackAssocs, nullptr, nullptr); + fullSkimming(collisions, bcs, nullptr, tracksBarrel, nullptr, nullptr, nullptr, trackAssocs, nullptr, nullptr); } // produce the barrel only DQ skimmed data model typically for Pb-Pb (with centrality), no subscribtion to the DQ event filter @@ -1479,14 +1535,21 @@ struct TableMaker { TrackAssoc const& trackAssocs) { computeOccupancyEstimators(collisions, tracksPosNoTOF, tracksNegNoTOF, presliceNoTOF, bcs); - fullSkimming(collisions, bcs, nullptr, tracksBarrel, nullptr, nullptr, trackAssocs, nullptr, nullptr); + fullSkimming(collisions, bcs, nullptr, tracksBarrel, nullptr, nullptr, nullptr, trackAssocs, nullptr, nullptr); } // produce the muon only DQ skimmed data model typically for Pb-Pb (with centrality), no subscribtion to the DQ event filter void processPbPbMuonOnly(MyEventsWithCentAndMults const& collisions, BCsWithTimestamps const& bcs, MyMuonsWithCov const& muons, FwdTrackAssoc const& fwdTrackAssocs) { - fullSkimming(collisions, bcs, nullptr, nullptr, muons, nullptr, nullptr, fwdTrackAssocs, nullptr); + fullSkimming(collisions, bcs, nullptr, nullptr, muons, nullptr, nullptr, nullptr, fwdTrackAssocs, nullptr); + } + + // produce the realigned muon only DQ skimmed data model typically for Pb-Pb (with centrality), no subscribtion to the DQ event filter + void processPbPbRealignedMuonOnly(MyEventsWithCentAndMults const& collisions, BCsWithTimestamps const& bcs, + MyMuonsWithCov const& muons, MyMuonsRealignWithCov const& muonsRealign, FwdTrackAssoc const& fwdTrackAssocs) + { + fullSkimming(collisions, bcs, nullptr, nullptr, muons, muonsRealign, nullptr, nullptr, fwdTrackAssocs, nullptr); } // produce the muon+mft DQ skimmed data model typically for Pb-Pb (with centrality), no subscribtion to the DQ event filter @@ -1494,7 +1557,7 @@ struct TableMaker { MyMuonsWithCov const& muons, MFTTracks const& mftTracks, FwdTrackAssoc const& fwdTrackAssocs, MFTTrackAssoc const& mftAssocs) { - fullSkimming(collisions, bcs, nullptr, nullptr, muons, mftTracks, nullptr, fwdTrackAssocs, mftAssocs); + fullSkimming(collisions, bcs, nullptr, nullptr, muons, nullptr, mftTracks, nullptr, fwdTrackAssocs, mftAssocs); } // Process the BCs and store stats for luminosity retrieval ----------------------------------------------------------------------------------- @@ -1515,6 +1578,7 @@ struct TableMaker { PROCESS_SWITCH(TableMaker, processPPBarrelOnly, "Build barrel only DQ skimmed data model typically for pp/p-Pb and UPC Pb-Pb", false); PROCESS_SWITCH(TableMaker, processPPBarrelOnlyWithV0s, "Build barrel only DQ skimmed data model, pp like, with V0 tagged tracks", false); PROCESS_SWITCH(TableMaker, processPPMuonOnly, "Build muon only DQ skimmed data model typically for pp/p-Pb and UPC Pb-Pb", false); + PROCESS_SWITCH(TableMaker, processPPRealignedMuonOnly, "Build realigned muon only DQ skimmed data model typically for pp/p-Pb and UPC Pb-Pb", false); PROCESS_SWITCH(TableMaker, processPPMuonMFT, "Build muon + mft DQ skimmed data model typically for pp/p-Pb and UPC Pb-Pb", false); PROCESS_SWITCH(TableMaker, processPPMuonMFTWithMultsExtra, "Build muon + mft DQ skimmed data model typically for pp/p-Pb and UPC Pb-Pb", false); PROCESS_SWITCH(TableMaker, processPbPb, "Build full DQ skimmed data model typically for Pb-Pb, w/o event filtering", false); @@ -1523,6 +1587,7 @@ struct TableMaker { PROCESS_SWITCH(TableMaker, processPbPbBarrelOnlyWithV0Bits, "Build barrel only DQ skimmed data model typically for Pb-Pb, w/ V0 bits, w/o event filtering", false); PROCESS_SWITCH(TableMaker, processPbPbBarrelOnlyWithV0BitsNoTOF, "Build barrel only DQ skimmed data model typically for Pb-Pb, w/ V0 bits, no TOF, w/o event filtering", false); PROCESS_SWITCH(TableMaker, processPbPbMuonOnly, "Build muon only DQ skimmed data model typically for Pb-Pb, w/o event filtering", false); + PROCESS_SWITCH(TableMaker, processPbPbRealignedMuonOnly, "Build realigned muon only DQ skimmed data model typically for Pb-Pb, w/o event filtering", false); PROCESS_SWITCH(TableMaker, processPbPbMuonMFT, "Build muon + mft DQ skimmed data model typically for Pb-Pb, w/o event filtering", false); PROCESS_SWITCH(TableMaker, processOnlyBCs, "Analyze the BCs to store sampled lumi", false); }; diff --git a/PWGDQ/Tasks/dqEfficiency_withAssoc.cxx b/PWGDQ/Tasks/dqEfficiency_withAssoc.cxx index 99f508a8b1e..3e1a05fd34e 100644 --- a/PWGDQ/Tasks/dqEfficiency_withAssoc.cxx +++ b/PWGDQ/Tasks/dqEfficiency_withAssoc.cxx @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -117,6 +118,7 @@ using MyEvents = soa::Join; using MyEventsVtxCov = soa::Join; using MyEventsVtxCovSelected = soa::Join; +using MyEventsVtxCovSelectedMultExtra = soa::Join; using MyEventsVtxCovSelectedQvector = soa::Join; using MyEventsQvector = soa::Join; @@ -136,6 +138,7 @@ using MyMuonTracksWithCovWithAmbiguities = soa::Join fConfigNoLaterThan{"ccdb-no-later-than", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable timestamp of creation for the object"}; Configurable fConfigComputeTPCpostCalib{"cfgTPCpostCalib", false, "If true, compute TPC post-calibrated n-sigmas"}; Configurable grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; - Configurable fConfigDummyRunlist{"cfgDummyRunlist", false, "If true, use dummy runlist"}; - Configurable fConfigInitRunNumber{"cfgInitRunNumber", 543215, "Initial run number used in run by run checks"}; Configurable fConfigMCSignals{"cfgTrackMCSignals", "", "Comma separated list of MC signals"}; Configurable fConfigMCSignalsJSON{"cfgTrackMCsignalsJSON", "", "Additional list of MC signals via JSON"}; @@ -433,7 +434,7 @@ struct AnalysisTrackSelection { if (addTrackCutsStr != "") { std::vector addTrackCuts = dqcuts::GetCutsFromJSON(addTrackCutsStr.Data()); for (auto& t : addTrackCuts) { - fTrackCuts.push_back((AnalysisCompositeCut*)t); + fTrackCuts.push_back(reinterpret_cast(t)); } } VarManager::SetUseVars(AnalysisCut::fgUsedVars); // provide the list of required variables so that VarManager knows what to fill @@ -493,9 +494,6 @@ struct AnalysisTrackSelection { fOutputList.setObject(fHistMan->GetMainHistogramList()); } - if (fConfigDummyRunlist) { - VarManager::SetDummyRunlist(fConfigInitRunNumber); - } if (fConfigComputeTPCpostCalib) { fCCDB->setURL(fConfigCcdbUrl.value); fCCDB->setCaching(true); @@ -760,7 +758,7 @@ struct AnalysisMuonSelection { if (addCutsStr != "") { std::vector addCuts = dqcuts::GetCutsFromJSON(addCutsStr.Data()); for (auto& t : addCuts) { - fMuonCuts.push_back((AnalysisCompositeCut*)t); + fMuonCuts.push_back(reinterpret_cast(t)); } } VarManager::SetUseVars(AnalysisCut::fgUsedVars); // provide the list of required variables so that VarManager knows what to fill @@ -1254,7 +1252,7 @@ struct AnalysisSameEventPairing { Configurable recSignals{"cfgBarrelMCRecSignals", "", "Comma separated list of MC signals (reconstructed)"}; Configurable recSignalsJSON{"cfgMCRecSignalsJSON", "", "Comma separated list of MC signals (reconstructed) via JSON"}; Configurable skimSignalOnly{"cfgSkimSignalOnly", false, "Configurable to select only matched candidates"}; - Configurable runMCGenPair{"cfgRunMCGenPair", false, "Do pairing of true MC particles"}; + // Configurable runMCGenPair{"cfgRunMCGenPair", false, "Do pairing of true MC particles"}; } fConfigMC; struct : ConfigurableGroup { @@ -1269,6 +1267,7 @@ struct AnalysisSameEventPairing { Service fCCDB; // Filter filterEventSelected = aod::dqanalysisflags::isEventSelected & uint32_t(1); + Filter eventFilter = aod::dqanalysisflags::isEventSelected > static_cast(0); HistogramManager* fHistMan; @@ -1300,6 +1299,7 @@ struct AnalysisSameEventPairing { if (context.mOptions.get("processDummy")) { return; } + bool isMCGen = context.mOptions.get("processMCGen"); VarManager::SetDefaultVarNames(); fEnableBarrelHistos = context.mOptions.get("processAllSkimmed") || context.mOptions.get("processBarrelOnlySkimmed") || context.mOptions.get("processBarrelOnlyWithCollSkimmed"); @@ -1557,12 +1557,16 @@ struct AnalysisSameEventPairing { } } - for (auto& sig : fGenMCSignals) { - if (sig->GetNProngs() == 1) { - histNames += Form("MCTruthGen_%s;", sig->GetName()); // TODO: Add these names to a std::vector to avoid using Form in the process function - } else if (sig->GetNProngs() == 2) { - histNames += Form("MCTruthGenPair_%s;", sig->GetName()); - fHasTwoProngGenMCsignals = true; + if (isMCGen) { + for (auto& sig : fGenMCSignals) { + if (sig->GetNProngs() == 1) { + histNames += Form("MCTruthGen_%s;", sig->GetName()); // TODO: Add these names to a std::vector to avoid using Form in the process function + histNames += Form("MCTruthGenSel_%s;", sig->GetName()); + } else if (sig->GetNProngs() == 2) { + histNames += Form("MCTruthGenPair_%s;", sig->GetName()); + histNames += Form("MCTruthGenPairSel_%s;", sig->GetName()); + fHasTwoProngGenMCsignals = true; + } } } @@ -2046,9 +2050,10 @@ struct AnalysisSameEventPairing { { runSameEventPairing(events, trackAssocsPerCollision, barrelAssocs, barrelTracks, mcEvents, mcTracks); runSameEventPairing(events, muonAssocsPerCollision, muonAssocs, muons, mcEvents, mcTracks); - if (fConfigMC.runMCGenPair) { + // Feature replaced by processMCGen + /*if (fConfigMC.runMCGenPair) { runMCGen(mcEvents, mcTracks); - } + }*/ // runSameEventPairing(event, tracks, muons); } @@ -2057,9 +2062,10 @@ struct AnalysisSameEventPairing { MyBarrelTracksWithCovWithAmbiguities const& barrelTracks, ReducedMCEvents const& mcEvents, ReducedMCTracks const& mcTracks) { runSameEventPairing(events, trackAssocsPerCollision, barrelAssocs, barrelTracks, mcEvents, mcTracks); - if (fConfigMC.runMCGenPair) { + // Feature replaced by processMCGen + /*if (fConfigMC.runMCGenPair) { runMCGen(mcEvents, mcTracks); - } + }*/ } void processBarrelOnlyWithCollSkimmed(MyEventsVtxCovSelected const& events, @@ -2067,18 +2073,60 @@ struct AnalysisSameEventPairing { MyBarrelTracksWithCovWithAmbiguitiesWithColl const& barrelTracks, ReducedMCEvents const& mcEvents, ReducedMCTracks const& mcTracks) { runSameEventPairing(events, trackAssocsPerCollision, barrelAssocs, barrelTracks, mcEvents, mcTracks); - if (fConfigMC.runMCGenPair) { + // Feature replaced by processMCGen + /*if (fConfigMC.runMCGenPair) { runMCGen(mcEvents, mcTracks); - } + }*/ } void processMuonOnlySkimmed(MyEventsVtxCovSelected const& events, soa::Join const& muonAssocs, MyMuonTracksWithCovWithAmbiguities const& muons, ReducedMCEvents const& mcEvents, ReducedMCTracks const& mcTracks) { runSameEventPairing(events, muonAssocsPerCollision, muonAssocs, muons, mcEvents, mcTracks); - if (fConfigMC.runMCGenPair) { + // Feature replaced by processMCGen + /*if (fConfigMC.runMCGenPair) { runMCGen(mcEvents, mcTracks); + }*/ + } + + PresliceUnsorted perReducedMcGenEvent = aod::reducedtrackMC::reducedMCeventId; + + void processMCGen(soa::Filtered const& events, ReducedMCEvents const& /*mcEvents*/, ReducedMCTracks const& mcTracks) + { + // Fill Generated histograms taking into account all generated tracks + for (auto& mctrack : mcTracks) { + VarManager::FillTrackMC(mcTracks, mctrack); + // NOTE: Signals are checked here mostly based on the skimmed MC stack, so depending on the requested signal, the stack could be incomplete. + // NOTE: However, the working model is that the decisions on MC signals are precomputed during skimming and are stored in the mcReducedFlags member. + // TODO: Use the mcReducedFlags to select signals + for (auto& sig : fGenMCSignals) { + if (sig->CheckSignal(true, mctrack)) { + fHistMan->FillHistClass(Form("MCTruthGen_%s", sig->GetName()), VarManager::fgValues); + } + } } + + // Fill Generated histograms taking into account selected collisions + for (auto& event : events) { + if (!event.isEventSelected_bit(0)) { + continue; + } + if (!event.has_reducedMCevent()) { + continue; + } + + auto groupedMCTracks = mcTracks.sliceBy(perReducedMcGenEvent, event.reducedMCeventId()); + groupedMCTracks.bindInternalIndicesTo(&mcTracks); + for (auto& track : groupedMCTracks) { + VarManager::FillTrackMC(mcTracks, track); + auto track_raw = groupedMCTracks.rawIteratorAt(track.globalIndex()); + for (auto& sig : fGenMCSignals) { + if (sig->CheckSignal(true, track_raw)) { + fHistMan->FillHistClass(Form("MCTruthGenSel_%s", sig->GetName()), VarManager::fgValues); + } + } + } + } // end loop over reconstructed events } void processDummy(MyEvents&) @@ -2090,6 +2138,7 @@ struct AnalysisSameEventPairing { PROCESS_SWITCH(AnalysisSameEventPairing, processBarrelOnlySkimmed, "Run barrel only pairing, with skimmed tracks", false); PROCESS_SWITCH(AnalysisSameEventPairing, processBarrelOnlyWithCollSkimmed, "Run barrel only pairing, with skimmed tracks and with collision information", false); PROCESS_SWITCH(AnalysisSameEventPairing, processMuonOnlySkimmed, "Run muon only pairing, with skimmed tracks", false); + PROCESS_SWITCH(AnalysisSameEventPairing, processMCGen, "Loop over MC particle stack and fill generator level histograms", false); PROCESS_SWITCH(AnalysisSameEventPairing, processDummy, "Dummy function, enabled only if none of the others are enabled", false); }; @@ -2132,9 +2181,10 @@ struct AnalysisAsymmetricPairing { Configurable fConfigPropToPCA{"cfgPropToPCA", false, "Propagate tracks to secondary vertex"}; Configurable fConfigLutPath{"lutPath", "GLO/Param/MatLUT", "Path of the Lut parametrization"}; - Configurable fConfigRunMCGenPair{"cfgRunMCGenPair", false, "Do pairing of true MC particles"}; Configurable fConfigMCGenSignals{"cfgBarrelMCGenSignals", "", "Comma separated list of MC signals (generated)"}; Configurable fConfigMCRecSignals{"cfgBarrelMCRecSignals", "", "Comma separated list of MC signals (reconstructed)"}; + Configurable fConfigMCRecSignalsJSON{"cfgMCRecSignalsJSON", "", "Additional list of MC signals (reconstructed) via JSON"}; + Configurable fConfigMCGenSignalsJSON{"cfgMCGenSignalsJSON", "", "Comma separated list of MC signals (generated) via JSON"}; Service fCCDB; @@ -2145,8 +2195,8 @@ struct AnalysisAsymmetricPairing { std::vector fPairCuts; int fNPairHistPrefixes; - std::vector fRecMCSignals; - std::vector fGenMCSignals; + std::vector fRecMCSignals; + std::vector fGenMCSignals; // Filter masks to find legs in BarrelTrackCuts table uint32_t fLegAFilterMask; @@ -2165,6 +2215,8 @@ struct AnalysisAsymmetricPairing { int fNPairCuts = 0; int fNCommonTrackCuts; + Filter eventFilter = aod::dqanalysisflags::isEventSelected > static_cast(0); + Preslice> trackAssocsPerCollision = aod::reducedtrack_association::reducedeventId; // Partitions for triplets and asymmetric pairs @@ -2177,6 +2229,7 @@ struct AnalysisAsymmetricPairing { void init(o2::framework::InitContext& context) { + bool isMCGen = context.mOptions.get("processMCGen") || context.mOptions.get("processMCGenWithEventSelection"); if (context.mOptions.get("processDummy")) { return; } @@ -2203,7 +2256,7 @@ struct AnalysisAsymmetricPairing { if (addPairCutsStr != "") { std::vector addPairCuts = dqcuts::GetCutsFromJSON(addPairCutsStr.Data()); for (auto& t : addPairCuts) { - fPairCuts.push_back((AnalysisCompositeCut*)t); + fPairCuts.push_back(reinterpret_cast(t)); cutNamesStr += Form(",%s", t->GetName()); } } @@ -2215,7 +2268,7 @@ struct AnalysisAsymmetricPairing { for (int isig = 0; isig < objRecSigArray->GetEntries(); ++isig) { MCSignal* sig = o2::aod::dqmcsignals::GetMCSignal(objRecSigArray->At(isig)->GetName()); if (sig) { - fRecMCSignals.push_back(*sig); + fRecMCSignals.push_back(sig); } } @@ -2266,7 +2319,7 @@ struct AnalysisAsymmetricPairing { uint32_t fConstructedLegCFilterMask = 0; TString legCutsStr = fConfigLegCuts.value; std::unique_ptr objArrayLegs(legCutsStr.Tokenize(",")); - if (objArrayLegs->GetEntries() == 0) { + if (objArrayLegs->GetEntries() == 0 && !isMCGen) { LOG(fatal) << "No cuts defining legs. Check the config!"; } fNLegCuts = objArrayLegs->GetEntries(); @@ -2355,13 +2408,13 @@ struct AnalysisAsymmetricPairing { auto sig = fRecMCSignals.at(isig); int offset = fNLegCuts * isig * (1 + fNCommonTrackCuts + fNPairCuts + fNCommonTrackCuts * fNPairCuts); names = { - Form("TripletsBarrelSE_%s_%s", legsStr.Data(), sig.GetName())}; + Form("TripletsBarrelSE_%s_%s", legsStr.Data(), sig->GetName())}; histNames += Form("%s;", names[0].Data()); fBarrelHistNamesMCmatched[offset + icut] = names; for (int iCommonCut = 0; iCommonCut < fNCommonTrackCuts; ++iCommonCut) { names = {}; - names.push_back(Form("TripletsBarrelSE_%s_%s_%s", legsStr.Data(), objArrayCommon->At(iCommonCut)->GetName(), sig.GetName())); + names.push_back(Form("TripletsBarrelSE_%s_%s_%s", legsStr.Data(), objArrayCommon->At(iCommonCut)->GetName(), sig->GetName())); histNames += Form("%s;", names[0].Data()); fBarrelHistNamesMCmatched[offset + fNLegCuts + icut * fNCommonTrackCuts + iCommonCut] = names; } @@ -2370,12 +2423,12 @@ struct AnalysisAsymmetricPairing { std::unique_ptr objArrayPair(cutNamesStr.Tokenize(",")); for (int iPairCut = 0; iPairCut < fNPairCuts; ++iPairCut) { // loop over pair cuts names = {}; - names.push_back(Form("TripletsBarrelSE_%s_%s_%s", legsStr.Data(), objArrayPair->At(iPairCut)->GetName(), sig.GetName())); + names.push_back(Form("TripletsBarrelSE_%s_%s_%s", legsStr.Data(), objArrayPair->At(iPairCut)->GetName(), sig->GetName())); histNames += Form("%s;", names[0].Data()); fBarrelHistNamesMCmatched[offset + fNLegCuts * (fNCommonTrackCuts + 1) + icut * fNPairCuts + iPairCut] = names; for (int iCommonCut = 0; iCommonCut < fNCommonTrackCuts; ++iCommonCut) { names = {}; - names.push_back(Form("TripletsBarrelSE_%s_%s_%s_%s", legsStr.Data(), objArrayCommon->At(iCommonCut)->GetName(), objArrayPair->At(iPairCut)->GetName(), sig.GetName())); + names.push_back(Form("TripletsBarrelSE_%s_%s_%s_%s", legsStr.Data(), objArrayCommon->At(iCommonCut)->GetName(), objArrayPair->At(iPairCut)->GetName(), sig->GetName())); histNames += Form("%s;", names[0].Data()); fBarrelHistNamesMCmatched[offset + (fNLegCuts * (fNCommonTrackCuts + 1) + fNLegCuts * fNPairCuts) + icut * (fNPairCuts * fNCommonTrackCuts) + iCommonCut * (1 + fNPairCuts) + iPairCut] = names; } // end loop (common cuts) @@ -2436,7 +2489,7 @@ struct AnalysisAsymmetricPairing { names.push_back(Form("%s_%s_%s_%s", pairHistPrefixes[iPrefix].Data(), legsStr.Data(), objArrayCommon->At(iCommonCut)->GetName(), objArrayPair->At(iPairCut)->GetName())); histNames += Form("%s;", names[iPrefix].Data()); } - fTrackHistNames[(fNLegCuts * (fNCommonTrackCuts + 1) + fNLegCuts * fNPairCuts) + icut * (fNPairCuts * fNCommonTrackCuts) + iCommonCut * (1 + fNPairCuts) + iPairCut] = names; + fTrackHistNames[(fNLegCuts * (fNCommonTrackCuts + 1) + fNLegCuts * fNPairCuts) + icut * (fNPairCuts * fNCommonTrackCuts) + iCommonCut * fNPairCuts + iPairCut] = names; } // end loop (common cuts) } // end loop (pair cuts) } // end if (pair cuts) @@ -2448,12 +2501,12 @@ struct AnalysisAsymmetricPairing { names = {}; int offset = fNLegCuts * isig * (1 + fNCommonTrackCuts + fNPairCuts + fNCommonTrackCuts * fNPairCuts); for (int iPrefix = 0; iPrefix < fNPairHistPrefixes; ++iPrefix) { - names.push_back(Form("%s_%s_%s", pairHistPrefixes[iPrefix].Data(), legsStr.Data(), sig.GetName())); + names.push_back(Form("%s_%s_%s", pairHistPrefixes[iPrefix].Data(), legsStr.Data(), sig->GetName())); histNames += Form("%s;", names[iPrefix].Data()); } if (fConfigReflectedHistograms.value) { for (int iPrefix = 0; iPrefix < fNPairHistPrefixes; ++iPrefix) { - names.push_back(Form("%s_reflected_%s_%s", pairHistPrefixes[iPrefix].Data(), legsStr.Data(), sig.GetName())); + names.push_back(Form("%s_reflected_%s_%s", pairHistPrefixes[iPrefix].Data(), legsStr.Data(), sig->GetName())); histNames += Form("%s;", names[fNPairHistPrefixes + iPrefix].Data()); } } @@ -2462,7 +2515,7 @@ struct AnalysisAsymmetricPairing { for (int iCommonCut = 0; iCommonCut < fNCommonTrackCuts; ++iCommonCut) { names = {}; for (int iPrefix = 0; iPrefix < fNPairHistPrefixes; ++iPrefix) { - names.push_back(Form("%s_%s_%s_%s", pairHistPrefixes[iPrefix].Data(), legsStr.Data(), objArrayCommon->At(iCommonCut)->GetName(), sig.GetName())); + names.push_back(Form("%s_%s_%s_%s", pairHistPrefixes[iPrefix].Data(), legsStr.Data(), objArrayCommon->At(iCommonCut)->GetName(), sig->GetName())); histNames += Form("%s;", names[iPrefix].Data()); } fBarrelHistNamesMCmatched[offset + fNLegCuts + icut * fNCommonTrackCuts + iCommonCut] = names; @@ -2473,17 +2526,17 @@ struct AnalysisAsymmetricPairing { for (int iPairCut = 0; iPairCut < fNPairCuts; ++iPairCut) { // loop over pair cuts names = {}; for (int iPrefix = 0; iPrefix < fNPairHistPrefixes; ++iPrefix) { - names.push_back(Form("%s_%s_%s_%s", pairHistPrefixes[iPrefix].Data(), legsStr.Data(), objArrayPair->At(iPairCut)->GetName(), sig.GetName())); + names.push_back(Form("%s_%s_%s_%s", pairHistPrefixes[iPrefix].Data(), legsStr.Data(), objArrayPair->At(iPairCut)->GetName(), sig->GetName())); histNames += Form("%s;", names[iPrefix].Data()); } fBarrelHistNamesMCmatched[offset + fNLegCuts * (fNCommonTrackCuts + 1) + icut * fNPairCuts + iPairCut] = names; for (int iCommonCut = 0; iCommonCut < fNCommonTrackCuts; ++iCommonCut) { names = {}; for (int iPrefix = 0; iPrefix < fNPairHistPrefixes; ++iPrefix) { - names.push_back(Form("%s_%s_%s_%s_%s", pairHistPrefixes[iPrefix].Data(), legsStr.Data(), objArrayCommon->At(iCommonCut)->GetName(), objArrayPair->At(iPairCut)->GetName(), sig.GetName())); + names.push_back(Form("%s_%s_%s_%s_%s", pairHistPrefixes[iPrefix].Data(), legsStr.Data(), objArrayCommon->At(iCommonCut)->GetName(), objArrayPair->At(iPairCut)->GetName(), sig->GetName())); histNames += Form("%s;", names[iPrefix].Data()); } - fBarrelHistNamesMCmatched[offset + (fNLegCuts * (fNCommonTrackCuts + 1) + fNLegCuts * fNPairCuts) + icut * (fNPairCuts * fNCommonTrackCuts) + iCommonCut * (1 + fNPairCuts) + iPairCut] = names; + fBarrelHistNamesMCmatched[offset + (fNLegCuts * (fNCommonTrackCuts + 1) + fNLegCuts * fNPairCuts) + icut * (fNPairCuts * fNCommonTrackCuts) + iCommonCut * fNPairCuts + iPairCut] = names; } // end loop (common cuts) } // end loop (pair cuts) } // end if (pair cuts) @@ -2492,6 +2545,18 @@ struct AnalysisAsymmetricPairing { } } + // Add the reco MCSignals from the JSON config + TString addMCSignalsStr = fConfigMCRecSignalsJSON.value; + if (addMCSignalsStr != "") { + std::vector addMCSignals = dqmcsignals::GetMCSignalsFromJSON(addMCSignalsStr.Data()); + for (auto& mcIt : addMCSignals) { + if (mcIt->GetNProngs() != 3) { + LOG(fatal) << "Signal at reconstructed level requested (" << mcIt->GetName() << ") " << "does not have 3 prongs! Fix it"; + } + fRecMCSignals.push_back(mcIt); + } + } + // Add histogram classes for each specified MCsignal at the generator level // TODO: create a std::vector of hist classes to be used at Fill time, to avoid using Form in the process function TString sigGenNamesStr = fConfigMCGenSignals.value; @@ -2500,8 +2565,22 @@ struct AnalysisAsymmetricPairing { MCSignal* sig = o2::aod::dqmcsignals::GetMCSignal(objGenSigArray->At(isig)->GetName()); if (sig) { if (sig->GetNProngs() == 1) { // NOTE: 1-prong signals required - fGenMCSignals.push_back(*sig); + fGenMCSignals.push_back(sig); histNames += Form("MCTruthGen_%s;", sig->GetName()); // TODO: Add these names to a std::vector to avoid using Form in the process function + histNames += Form("MCTruthGenSel_%s;", sig->GetName()); // TODO: Add these names to a std::vector to avoid using Form in the process function + } + } + } + + // Add the gen MCSignals from the JSON config + addMCSignalsStr = fConfigMCGenSignalsJSON.value; + if (addMCSignalsStr != "") { + std::vector addMCSignals = dqmcsignals::GetMCSignalsFromJSON(addMCSignalsStr.Data()); + for (auto& mcIt : addMCSignals) { + if (mcIt->GetNProngs() == 1) { + fGenMCSignals.push_back(mcIt); + histNames += Form("MCTruthGen_%s;", mcIt->GetName()); // TODO: Add these names to a std::vector to avoid using Form in the process function + histNames += Form("MCTruthGenSel_%s;", mcIt->GetName()); // TODO: Add these names to a std::vector to avoid using Form in the process function } } } @@ -2684,7 +2763,7 @@ struct AnalysisAsymmetricPairing { for (auto sig = fRecMCSignals.begin(); sig != fRecMCSignals.end(); sig++, isig++) { if (t1.has_reducedMCTrack() && t2.has_reducedMCTrack()) { VarManager::FillPairMC(t1.reducedMCTrack(), t2.reducedMCTrack()); - if ((*sig).CheckSignal(true, t1.reducedMCTrack(), t2.reducedMCTrack())) { + if ((*sig)->CheckSignal(true, t1.reducedMCTrack(), t2.reducedMCTrack())) { mcDecision |= static_cast(1) << isig; } } @@ -2810,24 +2889,24 @@ struct AnalysisAsymmetricPairing { for (int iCommonCut = 0; iCommonCut < fNCommonTrackCuts; ++iCommonCut) { if (twoTrackCommonFilter & fCommonTrackCutFilterMasks[iCommonCut]) { if (sign1 * sign2 < 0) { - fHistMan->FillHistClass(histNames[(fNLegCuts * (fNCommonTrackCuts + 1) + fNLegCuts * fNPairCuts) + icut * (fNPairCuts * fNCommonTrackCuts) + iCommonCut * (1 + fNPairCuts) + iPairCut][0].Data(), VarManager::fgValues); + fHistMan->FillHistClass(histNames[(fNLegCuts * (fNCommonTrackCuts + 1) + fNLegCuts * fNPairCuts) + icut * (fNPairCuts * fNCommonTrackCuts) + iCommonCut * fNPairCuts + iPairCut][0].Data(), VarManager::fgValues); } else if (fConfigSameSignHistograms.value) { if (sign1 > 0) { - fHistMan->FillHistClass(histNames[(fNLegCuts * (fNCommonTrackCuts + 1) + fNLegCuts * fNPairCuts) + icut * (fNPairCuts * fNCommonTrackCuts) + iCommonCut * (1 + fNPairCuts) + iPairCut][1].Data(), VarManager::fgValues); + fHistMan->FillHistClass(histNames[(fNLegCuts * (fNCommonTrackCuts + 1) + fNLegCuts * fNPairCuts) + icut * (fNPairCuts * fNCommonTrackCuts) + iCommonCut * fNPairCuts + iPairCut][1].Data(), VarManager::fgValues); } else { - fHistMan->FillHistClass(histNames[(fNLegCuts * (fNCommonTrackCuts + 1) + fNLegCuts * fNPairCuts) + icut * (fNPairCuts * fNCommonTrackCuts) + iCommonCut * (1 + fNPairCuts) + iPairCut][2].Data(), VarManager::fgValues); + fHistMan->FillHistClass(histNames[(fNLegCuts * (fNCommonTrackCuts + 1) + fNLegCuts * fNPairCuts) + icut * (fNPairCuts * fNCommonTrackCuts) + iCommonCut * fNPairCuts + iPairCut][2].Data(), VarManager::fgValues); } } for (unsigned int isig = 0; isig < fRecMCSignals.size(); isig++) { // loop over MC signals int offset = fNLegCuts * isig * (1 + fNCommonTrackCuts + fNPairCuts + fNCommonTrackCuts * fNPairCuts); if (mcDecision & (static_cast(1) << isig)) { if (sign1 * sign2 < 0) { - fHistMan->FillHistClass(histNamesMC[offset + (fNLegCuts * (fNCommonTrackCuts + 1) + fNLegCuts * fNPairCuts) + icut * (fNPairCuts * fNCommonTrackCuts) + iCommonCut * (1 + fNPairCuts) + iPairCut][0].Data(), VarManager::fgValues); + fHistMan->FillHistClass(histNamesMC[offset + (fNLegCuts * (fNCommonTrackCuts + 1) + fNLegCuts * fNPairCuts) + icut * (fNPairCuts * fNCommonTrackCuts) + iCommonCut * fNPairCuts + iPairCut][0].Data(), VarManager::fgValues); } else if (fConfigSameSignHistograms.value) { if (sign1 > 0) { - fHistMan->FillHistClass(histNamesMC[offset + (fNLegCuts * (fNCommonTrackCuts + 1) + fNLegCuts * fNPairCuts) + icut * (fNPairCuts * fNCommonTrackCuts) + iCommonCut * (1 + fNPairCuts) + iPairCut][1].Data(), VarManager::fgValues); + fHistMan->FillHistClass(histNamesMC[offset + (fNLegCuts * (fNCommonTrackCuts + 1) + fNLegCuts * fNPairCuts) + icut * (fNPairCuts * fNCommonTrackCuts) + iCommonCut * fNPairCuts + iPairCut][1].Data(), VarManager::fgValues); } else { - fHistMan->FillHistClass(histNamesMC[offset + (fNLegCuts * (fNCommonTrackCuts + 1) + fNLegCuts * fNPairCuts) + icut * (fNPairCuts * fNCommonTrackCuts) + iCommonCut * (1 + fNPairCuts) + iPairCut][2].Data(), VarManager::fgValues); + fHistMan->FillHistClass(histNamesMC[offset + (fNLegCuts * (fNCommonTrackCuts + 1) + fNLegCuts * fNPairCuts) + icut * (fNPairCuts * fNCommonTrackCuts) + iCommonCut * fNPairCuts + iPairCut][2].Data(), VarManager::fgValues); } } } @@ -2972,7 +3051,7 @@ struct AnalysisAsymmetricPairing { mcDecision = 0; for (auto sig = fRecMCSignals.begin(); sig != fRecMCSignals.end(); sig++, isig++) { if (t1.has_reducedMCTrack() && t2.has_reducedMCTrack() && t3.has_reducedMCTrack()) { - if ((*sig).CheckSignal(true, t1.reducedMCTrack(), t2.reducedMCTrack(), t3.reducedMCTrack())) { + if ((*sig)->CheckSignal(true, t1.reducedMCTrack(), t2.reducedMCTrack(), t3.reducedMCTrack())) { mcDecision |= (static_cast(1) << isig); } } @@ -3039,48 +3118,76 @@ struct AnalysisAsymmetricPairing { } // end loop (cuts) } - PresliceUnsorted perReducedMcEvent = aod::reducedtrackMC::reducedMCeventId; + void processKaonPionSkimmed(MyEventsVtxCovSelected const& events, + soa::Join const& barrelAssocs, + MyBarrelTracksWithCovWithAmbiguities const& barrelTracks, + ReducedMCEvents const& mcEvents, ReducedMCTracks const& mcTracks) + { + runAsymmetricPairing(events, trackAssocsPerCollision, barrelAssocs, barrelTracks, mcEvents, mcTracks); + } - void runMCGen(ReducedMCTracks const& mcTracks) + void processKaonPionSkimmedMultExtra(MyEventsVtxCovSelectedMultExtra const& events, + soa::Join const& barrelAssocs, + MyBarrelTracksWithCovWithAmbiguities const& barrelTracks, + ReducedMCEvents const& mcEvents, ReducedMCTracks const& mcTracks) + { + runAsymmetricPairing(events, trackAssocsPerCollision, barrelAssocs, barrelTracks, mcEvents, mcTracks); + } + + void processKaonPionPionSkimmed(MyEventsVtxCovSelected const& events, + soa::Join const& barrelAssocs, + MyBarrelTracksWithCovWithAmbiguities const& barrelTracks, + ReducedMCEvents const& mcEvents, ReducedMCTracks const& mcTracks) + { + runThreeProng(events, trackAssocsPerCollision, barrelAssocs, barrelTracks, mcEvents, mcTracks, VarManager::kTripleCandidateToKPiPi); + } + + void processMCGen(ReducedMCTracks const& mcTracks) { // loop over mc stack and fill histograms for pure MC truth signals // group all the MC tracks which belong to the MC event corresponding to the current reconstructed event + // auto groupedMCTracks = tracksMC.sliceBy(aod::reducedtrackMC::reducedMCeventId, event.reducedMCevent().globalIndex()); for (auto& mctrack : mcTracks) { + VarManager::FillTrackMC(mcTracks, mctrack); // NOTE: Signals are checked here mostly based on the skimmed MC stack, so depending on the requested signal, the stack could be incomplete. // NOTE: However, the working model is that the decisions on MC signals are precomputed during skimming and are stored in the mcReducedFlags member. // TODO: Use the mcReducedFlags to select signals for (auto& sig : fGenMCSignals) { - if (sig.GetNProngs() != 1) { // NOTE: 1-prong signals required here - continue; - } - bool checked = false; - checked = sig.CheckSignal(true, mctrack); - if (checked) { - fHistMan->FillHistClass(Form("MCTruthGen_%s", sig.GetName()), VarManager::fgValues); + if (sig->CheckSignal(true, mctrack)) { + fHistMan->FillHistClass(Form("MCTruthGen_%s", sig->GetName()), VarManager::fgValues); } } } - } // end runMCGen - - void processKaonPionSkimmed(MyEventsVtxCovSelected const& events, - soa::Join const& barrelAssocs, - MyBarrelTracksWithCovWithAmbiguities const& barrelTracks, - ReducedMCEvents const& mcEvents, ReducedMCTracks const& mcTracks) - { - runAsymmetricPairing(events, trackAssocsPerCollision, barrelAssocs, barrelTracks, mcEvents, mcTracks); - if (fConfigRunMCGenPair) - runMCGen(mcTracks); } - void processKaonPionPionSkimmed(MyEventsVtxCovSelected const& events, - soa::Join const& barrelAssocs, - MyBarrelTracksWithCovWithAmbiguities const& barrelTracks, - ReducedMCEvents const& mcEvents, ReducedMCTracks const& mcTracks) + PresliceUnsorted perReducedMcEvent = aod::reducedtrackMC::reducedMCeventId; + + void processMCGenWithEventSelection(soa::Filtered const& events, + ReducedMCEvents const& /*mcEvents*/, ReducedMCTracks const& mcTracks) { - runThreeProng(events, trackAssocsPerCollision, barrelAssocs, barrelTracks, mcEvents, mcTracks, VarManager::kTripleCandidateToKPiPi); - if (fConfigRunMCGenPair) - runMCGen(mcTracks); + for (auto& event : events) { + if (!event.isEventSelected_bit(0)) { + continue; + } + if (!event.has_reducedMCevent()) { + continue; + } + + auto groupedMCTracks = mcTracks.sliceBy(perReducedMcEvent, event.reducedMCeventId()); + groupedMCTracks.bindInternalIndicesTo(&mcTracks); + for (auto& track : groupedMCTracks) { + + VarManager::FillTrackMC(mcTracks, track); + + auto track_raw = groupedMCTracks.rawIteratorAt(track.globalIndex()); + for (auto& sig : fGenMCSignals) { + if (sig->CheckSignal(true, track_raw)) { + fHistMan->FillHistClass(Form("MCTruthGenSel_%s", sig->GetName()), VarManager::fgValues); + } + } + } + } // end loop over reconstructed events } void processDummy(MyEvents&) @@ -3089,7 +3196,10 @@ struct AnalysisAsymmetricPairing { } PROCESS_SWITCH(AnalysisAsymmetricPairing, processKaonPionSkimmed, "Run kaon pion pairing, with skimmed tracks", false); + PROCESS_SWITCH(AnalysisAsymmetricPairing, processKaonPionSkimmedMultExtra, "Run kaon pion pairing, with skimmed tracks", false); PROCESS_SWITCH(AnalysisAsymmetricPairing, processKaonPionPionSkimmed, "Run kaon pion pion triplets, with skimmed tracks", false); + PROCESS_SWITCH(AnalysisAsymmetricPairing, processMCGen, "Loop over MC particle stack and fill generator level histograms", false); + PROCESS_SWITCH(AnalysisAsymmetricPairing, processMCGenWithEventSelection, "Loop over MC particle stack and fill generator level histograms", false); PROCESS_SWITCH(AnalysisAsymmetricPairing, processDummy, "Dummy function, enabled only if none of the others are enabled", true); }; @@ -3290,7 +3400,7 @@ struct AnalysisDileptonTrack { // loop over all the upstream cuts and make a bit mask for the track cuts specified in this task for (int icut = 0; icut < cfgTrackSelection_objArrayTrackCuts->GetEntries(); icut++) { if (cfgDileptonTrack_objArrayTrackCuts->FindObject(cfgTrackSelection_objArrayTrackCuts->At(icut)->GetName())) { - fTrackCutBitMap |= (uint32_t(1) << icut); + fTrackCutBitMap |= (static_cast(1) << icut); } } // finally, store the total number of upstream tasks, for easy access @@ -3358,7 +3468,7 @@ struct AnalysisDileptonTrack { for (int iCutTrack = 0; iCutTrack < fNCuts; iCutTrack++) { // here we check that this track cut is one of those required to associate with the dileptons - if (!(fTrackCutBitMap & (uint32_t(1) << iCutTrack))) { + if (!(fTrackCutBitMap & (static_cast(1) << iCutTrack))) { continue; } @@ -3593,13 +3703,13 @@ struct AnalysisDileptonTrack { // loop over specified track cuts (the tracks to be combined with the dileptons) for (int iTrackCut = 0; iTrackCut < fNCuts; iTrackCut++) { - if (!(trackSelection & (uint32_t(1) << iTrackCut))) { + if (!(trackSelection & (static_cast(1) << iTrackCut))) { continue; } fHistMan->FillHistClass(Form("DileptonTrack_%s_%s", fTrackCutNames[icut].Data(), fTrackCutNames[iTrackCut].Data()), fValuesHadron); for (uint32_t isig = 0; isig < fRecMCSignals.size(); isig++) { - if (mcDecision & (uint32_t(1) << isig)) { + if (mcDecision & (static_cast(1) << isig)) { fHistMan->FillHistClass(Form("DileptonTrackMCMatched_%s_%s_%s", fTrackCutNames[icut].Data(), fTrackCutNames[iTrackCut].Data(), fRecMCSignals[isig]->GetName()), fValuesHadron); } } @@ -3609,7 +3719,7 @@ struct AnalysisDileptonTrack { if (dilepton.commonFilterMap_bit(fCommonTrackCutMap[iCommonCut])) { fHistMan->FillHistClass(Form("DileptonTrack_%s_%s_%s", fTrackCutNames[icut].Data(), fCommonPairCutNames[iCommonCut].Data(), fTrackCutNames[iTrackCut].Data()), fValuesHadron); for (uint32_t isig = 0; isig < fRecMCSignals.size(); isig++) { - if (mcDecision & (uint32_t(1) << isig)) { + if (mcDecision & (static_cast(1) << isig)) { fHistMan->FillHistClass(Form("DileptonTrackMCMatched_%s_%s_%s_%s", fTrackCutNames[icut].Data(), fCommonPairCutNames[iCommonCut].Data(), fTrackCutNames[iTrackCut].Data(), fRecMCSignals[isig]->GetName()), fValuesHadron); } } @@ -3619,7 +3729,7 @@ struct AnalysisDileptonTrack { if (dilepton.pairFilterMap_bit(iPairCut)) { fHistMan->FillHistClass(Form("DileptonTrack_%s_%s_%s", fTrackCutNames[icut].Data(), fPairCutNames[iPairCut].Data(), fTrackCutNames[iTrackCut].Data()), fValuesHadron); for (uint32_t isig = 0; isig < fRecMCSignals.size(); isig++) { - if (mcDecision & (uint32_t(1) << isig)) { + if (mcDecision & (static_cast(1) << isig)) { fHistMan->FillHistClass(Form("DileptonTrackMCMatched_%s_%s_%s_%s", fTrackCutNames[icut].Data(), fPairCutNames[iPairCut].Data(), fTrackCutNames[iTrackCut].Data(), fRecMCSignals[isig]->GetName()), fValuesHadron); } } @@ -3627,7 +3737,7 @@ struct AnalysisDileptonTrack { if (dilepton.commonFilterMap_bit(fCommonTrackCutMap[iCommonCut])) { fHistMan->FillHistClass(Form("DileptonTrack_%s_%s_%s_%s", fTrackCutNames[icut].Data(), fCommonPairCutNames[iCommonCut].Data(), fPairCutNames[iPairCut].Data(), fTrackCutNames[iTrackCut].Data()), fValuesHadron); for (uint32_t isig = 0; isig < fRecMCSignals.size(); isig++) { - if (mcDecision & (uint32_t(1) << isig)) { + if (mcDecision & (static_cast(1) << isig)) { fHistMan->FillHistClass(Form("DileptonTrackMCMatched_%s_%s_%s_%s_%s", fTrackCutNames[icut].Data(), fCommonPairCutNames[iCommonCut].Data(), fPairCutNames[iPairCut].Data(), fTrackCutNames[iTrackCut].Data(), fRecMCSignals[isig]->GetName()), fValuesHadron); } } diff --git a/PWGDQ/Tasks/dqFlow.cxx b/PWGDQ/Tasks/dqFlow.cxx index d9210685a2e..ad500439924 100644 --- a/PWGDQ/Tasks/dqFlow.cxx +++ b/PWGDQ/Tasks/dqFlow.cxx @@ -16,11 +16,13 @@ /// o2-analysis-timestamp --aod-file AO2D.root -b | o2-analysis-event-selection -b | o2-analysis-multiplicity-table -b | o2-analysis-centrality-table -b | o2-analysis-fdd-converter -b | o2-analysis-trackselection -b | o2-analysis-trackextension -b | o2-analysis-pid-tpc-full -b | o2-analysis-pid-tof-full -b | o2-analysis-pid-tof-base -b | o2-analysis-pid-tof-beta -b | o2-analysis-dq-flow -b /// tested (June 2, 2022) on AO2D.root files from train production 242 +#include +#include +#include +#include #include #include #include -#include -#include #include #include "CCDB/BasicCCDBManager.h" #include "Framework/runDataProcessing.h" @@ -69,15 +71,18 @@ using MyEventsWithCentRun3 = soa::Join; using MyEventsWithCentQvectRun3 = soa::Join; -using MyBarrelTracks = soa::Join; -using MyBarrelTracksWithCov = soa::Join; +// using MyBarrelTracks = soa::Join; +// using MyBarrelTracksWithCov = soa::Joini; + +using MyBarrelTracks = soa::Join; +using MyBarrelTracksWithCov = soa::Join; using MyTracks = soa::Filtered>; using MyMuons = aod::FwdTracks; using MyMuonsWithCov = soa::Join; diff --git a/PWGDQ/Tasks/filterPPwithAssociation.cxx b/PWGDQ/Tasks/filterPPwithAssociation.cxx index 34a3d053312..532482e641b 100644 --- a/PWGDQ/Tasks/filterPPwithAssociation.cxx +++ b/PWGDQ/Tasks/filterPPwithAssociation.cxx @@ -717,7 +717,7 @@ struct DQFilterPPTask { histNames += value; histNames += ";"; } - DefineHistograms(fHistMan, histNames.Data()); + DefineHistograms(fHistMan, histNames.Data(), "cepf"); VarManager::SetUseVars(fHistMan->GetUsedVars()); fOutputList.setObject(fHistMan->GetMainHistogramList()); } diff --git a/PWGDQ/Tasks/tableReader.cxx b/PWGDQ/Tasks/tableReader.cxx index 2249aba8163..eb5d6dae897 100644 --- a/PWGDQ/Tasks/tableReader.cxx +++ b/PWGDQ/Tasks/tableReader.cxx @@ -326,8 +326,6 @@ struct AnalysisTrackSelection { Configurable fConfigNoLaterThan{"ccdb-no-later-than", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable timestamp of creation for the object"}; Configurable fConfigComputeTPCpostCalib{"cfgTPCpostCalib", false, "If true, compute TPC post-calibrated n-sigmas"}; Configurable fConfigRunPeriods{"cfgRunPeriods", "LHC22f", "run periods for used data"}; - Configurable fConfigDummyRunlist{"cfgDummyRunlist", false, "If true, use dummy runlist"}; - Configurable fConfigInitRunNumber{"cfgInitRunNumber", 543215, "Initial run number used in run by run checks"}; Service fCCDB; @@ -370,9 +368,6 @@ struct AnalysisTrackSelection { VarManager::SetUseVars(fHistMan->GetUsedVars()); // provide the list of required variables so that VarManager knows what to fill fOutputList.setObject(fHistMan->GetMainHistogramList()); } - if (fConfigDummyRunlist) { - VarManager::SetDummyRunlist(fConfigInitRunNumber); - } if (fConfigComputeTPCpostCalib) { // CCDB configuration fCCDB->setURL(fConfigCcdbUrl.value); diff --git a/PWGDQ/Tasks/tableReader_withAssoc.cxx b/PWGDQ/Tasks/tableReader_withAssoc.cxx index 5f7912211b2..7d19373fdb1 100644 --- a/PWGDQ/Tasks/tableReader_withAssoc.cxx +++ b/PWGDQ/Tasks/tableReader_withAssoc.cxx @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -486,8 +487,6 @@ struct AnalysisTrackSelection { Configurable fConfigComputeTPCpostCalib{"cfgTPCpostCalib", false, "If true, compute TPC post-calibrated n-sigmas"}; Configurable grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; - Configurable fConfigDummyRunlist{"cfgDummyRunlist", false, "If true, use dummy runlist"}; - Configurable fConfigInitRunNumber{"cfgInitRunNumber", 543215, "Initial run number used in run by run checks"}; // Track related options Configurable fPropTrack{"cfgPropTrack", true, "Propgate tracks to associated collision to recalculate DCA and momentum vector"}; @@ -522,7 +521,7 @@ struct AnalysisTrackSelection { if (addTrackCutsStr != "") { std::vector addTrackCuts = dqcuts::GetCutsFromJSON(addTrackCutsStr.Data()); for (auto& t : addTrackCuts) { - fTrackCuts.push_back((AnalysisCompositeCut*)t); + fTrackCuts.push_back(reinterpret_cast(t)); } } @@ -547,9 +546,6 @@ struct AnalysisTrackSelection { VarManager::SetUseVars(fHistMan->GetUsedVars()); // provide the list of required variables so that VarManager knows what to fill fOutputList.setObject(fHistMan->GetMainHistogramList()); } - if (fConfigDummyRunlist) { - VarManager::SetDummyRunlist(fConfigInitRunNumber); - } fCCDB->setURL(fConfigCcdbUrl.value); fCCDB->setCaching(true); @@ -770,7 +766,7 @@ struct AnalysisMuonSelection { if (addCutsStr != "") { std::vector addCuts = dqcuts::GetCutsFromJSON(addCutsStr.Data()); for (auto& t : addCuts) { - fMuonCuts.push_back((AnalysisCompositeCut*)t); + fMuonCuts.push_back(reinterpret_cast(t)); } } @@ -2144,7 +2140,7 @@ struct AnalysisAsymmetricPairing { if (addPairCutsStr != "") { std::vector addPairCuts = dqcuts::GetCutsFromJSON(addPairCutsStr.Data()); for (auto& t : addPairCuts) { - fPairCuts.push_back((AnalysisCompositeCut*)t); + fPairCuts.push_back(reinterpret_cast(t)); cutNamesStr += Form(",%s", t->GetName()); } } @@ -2928,7 +2924,7 @@ struct AnalysisDileptonTrack { } for (int icut = 0; icut < cfgTrackSelection_objArrayTrackCuts->GetEntries(); icut++) { if (cfgDileptonTrack_objArrayTrackCuts->FindObject(cfgTrackSelection_objArrayTrackCuts->At(icut)->GetName())) { - fTrackCutBitMap |= (uint32_t(1) << icut); + fTrackCutBitMap |= (static_cast(1) << icut); } } fNCuts = fTrackCutNames.size(); @@ -2995,7 +2991,7 @@ struct AnalysisDileptonTrack { for (int iCutTrack = 0; iCutTrack < fNCuts; iCutTrack++) { // here we check that this track cut is one of those required to associate with the dileptons - if (!(fTrackCutBitMap & (uint32_t(1) << iCutTrack))) { + if (!(fTrackCutBitMap & (static_cast(1) << iCutTrack))) { continue; } @@ -3174,7 +3170,7 @@ struct AnalysisDileptonTrack { // loop over specified track cuts (the tracks to be combined with the dileptons) for (int iTrackCut = 0; iTrackCut < fNCuts; iTrackCut++) { - if (!(trackSelection & (uint32_t(1) << iTrackCut))) { + if (!(trackSelection & (static_cast(1) << iTrackCut))) { continue; } fHistMan->FillHistClass(Form("DileptonTrack_%s_%s", fTrackCutNames[icut].Data(), fTrackCutNames[iTrackCut].Data()), fValuesHadron); @@ -3319,7 +3315,7 @@ struct AnalysisDileptonTrack { continue; } for (uint32_t iTrackCut = 0; iTrackCut < fTrackCutNames.size(); iTrackCut++) { - if (trackSelection & (uint32_t(1) << iTrackCut)) { + if (trackSelection & (static_cast(1) << iTrackCut)) { fHistMan->FillHistClass(Form("DileptonTrackME_%s_%s", fTrackCutNames[icut].Data(), fTrackCutNames[iTrackCut].Data()), VarManager::fgValues); } } @@ -3364,7 +3360,7 @@ struct AnalysisDileptonTrack { continue; } for (uint32_t iTrackCut = 0; iTrackCut < fTrackCutNames.size(); iTrackCut++) { - if (muonSelection & (uint32_t(1) << iTrackCut)) { + if (muonSelection & (static_cast(1) << iTrackCut)) { fHistMan->FillHistClass(Form("DileptonTrackME_%s_%s", fTrackCutNames[icut].Data(), fTrackCutNames[iTrackCut].Data()), VarManager::fgValues); } } diff --git a/PWGDQ/Tasks/taskFwdTrackPid.cxx b/PWGDQ/Tasks/taskFwdTrackPid.cxx index 7a135596d56..7fb6e8e3310 100644 --- a/PWGDQ/Tasks/taskFwdTrackPid.cxx +++ b/PWGDQ/Tasks/taskFwdTrackPid.cxx @@ -139,13 +139,11 @@ struct taskFwdTrackPid { template void runFwdTrackPid(TEvent const& event, Muons const& muons, MftTracks const& mftTracks) { - uint32_t mcDecision = 0; - fwdPidAllList.reserve(1); for (const auto& muon : muons) { if (muon.has_matchMFTTrack() && muon.trackType() == 0 && TMath::Abs(muon.fwdDcaX()) < fConfigMaxDCA && TMath::Abs(muon.fwdDcaY()) < fConfigMaxDCA) { auto mftTrack = muon.template matchMFTTrack_as(); - fwdPidAllList(muon.trackType(), event.posX(), event.posY(), event.posZ(), event.numContrib(), muon.pt(), muon.eta(), muon.phi(), muon.sign(), mftTrack.mftClusterSizesAndTrackFlags(), muon.fwdDcaX(), muon.fwdDcaY(), muon.chi2MatchMCHMID(), muon.chi2MatchMCHMFT(), mcDecision); + fwdPidAllList(muon.trackType(), event.posX(), event.posY(), event.posZ(), event.numContrib(), muon.pt(), muon.eta(), muon.phi(), muon.sign(), mftTrack.mftClusterSizesAndTrackFlags(), muon.fwdDcaX(), muon.fwdDcaY(), muon.chi2MatchMCHMID(), muon.chi2MatchMCHMFT(), 0); } } if constexpr (TMatchedOnly == false) { @@ -157,7 +155,7 @@ struct taskFwdTrackPid { continue; } } - fwdPidAllList(4, event.posX(), event.posY(), event.posZ(), event.numContrib(), mftTrack.pt(), mftTrack.eta(), mftTrack.phi(), mftTrack.sign(), mftTrack.mftClusterSizesAndTrackFlags(), mftTrack.fwdDcaX(), mftTrack.fwdDcaY(), -999, -999, mcDecision); + fwdPidAllList(4, event.posX(), event.posY(), event.posZ(), event.numContrib(), mftTrack.pt(), mftTrack.eta(), mftTrack.phi(), mftTrack.sign(), mftTrack.mftClusterSizesAndTrackFlags(), mftTrack.fwdDcaX(), mftTrack.fwdDcaY(), -999, -999, 0); } } } @@ -169,31 +167,16 @@ struct taskFwdTrackPid { { fwdPidAllList.reserve(1); for (const auto& muon : muons) { - uint32_t mcDecision = 0; - int isig = 0; - for (auto sig = fRecMCSignals.begin(); sig != fRecMCSignals.end(); sig++, isig++) { - if ((*sig).CheckSignal(false, muon.reducedMCTrack())) { - mcDecision |= (uint32_t(1) << isig); - } - } - if (muon.has_matchMFTTrack() && muon.trackType() == 0 && TMath::Abs(muon.fwdDcaX()) < fConfigMaxDCA && TMath::Abs(muon.fwdDcaY()) < fConfigMaxDCA) { auto mftTrack = muon.template matchMFTTrack_as(); - fwdPidAllList(muon.trackType(), event.posX(), event.posY(), event.posZ(), event.numContrib(), muon.pt(), muon.eta(), muon.phi(), muon.sign(), mftTrack.mftClusterSizesAndTrackFlags(), muon.fwdDcaX(), muon.fwdDcaY(), muon.chi2MatchMCHMID(), muon.chi2MatchMCHMFT(), mcDecision); + fwdPidAllList(muon.trackType(), event.posX(), event.posY(), event.posZ(), event.numContrib(), muon.pt(), muon.eta(), muon.phi(), muon.sign(), mftTrack.mftClusterSizesAndTrackFlags(), muon.fwdDcaX(), muon.fwdDcaY(), muon.chi2MatchMCHMID(), muon.chi2MatchMCHMFT(), muon.mcReducedFlags()); } } if constexpr (TMatchedOnly == false) { for (const auto& mftTrack : mftTracks) { - uint32_t mcDecision = 0; - int isig = 0; - for (auto sig = fRecMCSignals.begin(); sig != fRecMCSignals.end(); sig++, isig++) { - if ((*sig).CheckSignal(false, mftTrack.reducedMCTrack())) { - mcDecision |= (uint32_t(1) << isig); - } - } if (TMath::Abs(mftTrack.fwdDcaX()) < fConfigMaxDCA && TMath::Abs(mftTrack.fwdDcaY()) < fConfigMaxDCA) { - fwdPidAllList(4, event.posX(), event.posY(), event.posZ(), event.numContrib(), mftTrack.pt(), mftTrack.eta(), mftTrack.phi(), mftTrack.sign(), mftTrack.mftClusterSizesAndTrackFlags(), mftTrack.fwdDcaX(), mftTrack.fwdDcaY(), -999, -999, mcDecision); + fwdPidAllList(4, event.posX(), event.posY(), event.posZ(), event.numContrib(), mftTrack.pt(), mftTrack.eta(), mftTrack.phi(), mftTrack.sign(), mftTrack.mftClusterSizesAndTrackFlags(), mftTrack.fwdDcaX(), mftTrack.fwdDcaY(), -999, -999, mftTrack.mcReducedFlags()); } } } @@ -206,19 +189,10 @@ struct taskFwdTrackPid { for (auto& mctrack : groupedMCTracks) { VarManager::FillTrackMC(groupedMCTracks, mctrack); - for (auto& sig : fGenMCSignals) { - if (sig.GetNProngs() != 1) { // NOTE: 1-prong signals required - continue; - } - bool checked = false; - if constexpr (soa::is_soa_filtered_v) { - auto mctrack_raw = groupedMCTracks.rawIteratorAt(mctrack.globalIndex()); - checked = sig.CheckSignal(false, mctrack_raw); - } else { - checked = sig.CheckSignal(false, mctrack); - } - if (checked) { - fHistMan->FillHistClass(Form("MCTruthGen_%s", sig.GetName()), VarManager::fgValues); + int isig = 0; + for (auto sig = fGenMCSignals.begin(); sig != fGenMCSignals.end(); sig++, isig++) { + if (mctrack.mcReducedFlags() & (static_cast(1) << isig)) { + fHistMan->FillHistClass(Form("MCTruthGen_%s", sig->GetName()), VarManager::fgValues); } } } @@ -287,8 +261,7 @@ void DefineHistograms(HistogramManager* histMan, TString histClasses) if (classStr.Contains("MCTruthGen")) { dqhistograms::DefineHistograms(histMan, objArray->At(iclass)->GetName(), "mctruth"); histMan->AddHistogram(objArray->At(iclass)->GetName(), "Pt_Rapidity", "MC generator p_{T}, y distribution", false, 120, 0.0, 30.0, VarManager::kMCPt, 150, 2.5, 4.0, VarManager::kMCY); - histMan->AddHistogram(objArray->At(iclass)->GetName(), "Eta", "MC generator #eta distribution", false, 200, 2.5, 4.0, VarManager::kMCEta); - // histMan->AddHistogram(objArray->At(iclass)->GetName(), "Rapidity", "MC generator y distribution", false, 150, 2.5, 4.0, VarManager::kMCY); + histMan->AddHistogram(objArray->At(iclass)->GetName(), "Eta", "MC generator #eta distribution", false, 200, -5.0, 5.0, VarManager::kMCEta); histMan->AddHistogram(objArray->At(iclass)->GetName(), "Phi", "MC generator #varphi distribution", false, 50, 0.0, 2. * TMath::Pi(), VarManager::kMCPhi); } diff --git a/PWGDQ/Tasks/v0selector.cxx b/PWGDQ/Tasks/v0selector.cxx index 52068b44958..0c970d80c91 100644 --- a/PWGDQ/Tasks/v0selector.cxx +++ b/PWGDQ/Tasks/v0selector.cxx @@ -21,6 +21,7 @@ #include #include #include +#include #include "Math/Vector4D.h" #include "Framework/runDataProcessing.h" #include "Framework/AnalysisTask.h" @@ -74,6 +75,7 @@ struct v0selector { Configurable cutQTK0SHigh{"cutQTK0SHigh", 0.215, "cutQTK0SHigh"}; Configurable cutAPK0SLow{"cutAPK0SLow", 0.199, "cutAPK0SLow"}; Configurable cutAPK0SHigh{"cutAPK0SHigh", 0.8, "cutAPK0SHigh"}; + Configurable cutAPK0SHighTop{"cutAPK0SHighTop", 0.9, "cutAPK0SHighTop"}; // Lambda & A-Lambda cuts Configurable cutQTL{"cutQTL", 0.03, "cutQTL"}; Configurable cutAlphaLLow{"cutAlphaLLow", 0.35, "cutAlphaLLow"}; @@ -83,6 +85,7 @@ struct v0selector { Configurable cutAPL1{"cutAPL1", 0.107, "cutAPL1"}; Configurable cutAPL2{"cutAPL2", -0.69, "cutAPL2"}; Configurable cutAPL3{"cutAPL3", 0.5, "cutAPL3"}; + Configurable produceV0ID{"produceV0ID", false, "Produce additional V0ID table"}; enum { // Reconstructed V0 kUndef = -1, @@ -94,6 +97,7 @@ struct v0selector { }; Produces v0bits; + Produces v0mapID; // int checkV0(const array& ppos, const array& pneg) int checkV0(const float alpha, const float qt) @@ -117,31 +121,32 @@ struct v0selector { // const float cutAPL[3] = {0.107, -0.69, 0.5}; // parameters for curved QT cut if (qt < cutQTG) { - if ((TMath::Abs(alpha) < cutAlphaG)) { + if ((std::abs(alpha) < cutAlphaG)) { return kGamma; } } if (qt < cutQTG2) { // additional region - should help high pT gammas - if ((TMath::Abs(alpha) > cutAlphaGLow) && (TMath::Abs(alpha) < cutAlphaGHigh)) { + if ((std::abs(alpha) > cutAlphaGLow) && (std::abs(alpha) < cutAlphaGHigh)) { return kGamma; } } // Check for K0S candidates - float q = cutAPK0SLow * TMath::Sqrt(TMath::Abs(1 - alpha * alpha / (cutAPK0SHigh * cutAPK0SHigh))); - if ((qt > cutQTK0SLow) && (qt < cutQTK0SHigh) && (qt > q)) { + float q = cutAPK0SLow * std::sqrt(std::abs(1.0f - alpha * alpha / (cutAPK0SHigh * cutAPK0SHigh))); + float qtop = cutQTK0SHigh * std::sqrt(std::abs(1.0f - alpha * alpha / (cutAPK0SHighTop * cutAPK0SHighTop))); + if ((qt > cutQTK0SLow) && (qt < cutQTK0SHigh) && (qt > q) && (qt < qtop)) { return kK0S; } // Check for Lambda candidates - q = cutAPL1 * TMath::Sqrt(TMath::Abs(1 - ((alpha + cutAPL2) * (alpha + cutAPL2)) / (cutAPL3 * cutAPL3))); + q = cutAPL1 * std::sqrt(std::abs(1.0f - ((alpha + cutAPL2) * (alpha + cutAPL2)) / (cutAPL3 * cutAPL3))); if ((alpha > cutAlphaLLow) && (alpha < cutAlphaLHigh) && (qt > cutQTL) && (qt < q)) { return kLambda; } // Check for AntiLambda candidates - q = cutAPL1 * TMath::Sqrt(TMath::Abs(1 - ((alpha - cutAPL2) * (alpha - cutAPL2)) / (cutAPL3 * cutAPL3))); + q = cutAPL1 * std::sqrt(std::abs(1.0f - ((alpha - cutAPL2) * (alpha - cutAPL2)) / (cutAPL3 * cutAPL3))); if ((alpha > cutAlphaALLow) && (alpha < cutAlphaALHigh) && (qt > cutQTL) && (qt < q)) { return kAntiLambda; } @@ -189,14 +194,22 @@ struct v0selector { registry.add("hDCAzNegToPV", "hDCAzNegToPV", HistType::kTH1F, {{1000, -5.0f, 5.0f}}); registry.add("hDCAV0Dau", "hDCAV0Dau", HistType::kTH1F, {{1000, 0.0f, 10.0f}}); registry.add("hV0APplot", "hV0APplot", HistType::kTH2F, {{200, -1.0f, +1.0f}, {250, 0.0f, 0.25f}}); + registry.add("hV0APplotSelected", "hV0APplotSelected", HistType::kTH2F, {{200, -1.0f, +1.0f}, {250, 0.0f, 0.25f}}); registry.add("hV0Psi", "hV0Psi", HistType::kTH2F, {{100, 0, TMath::PiOver2()}, {100, 0, 0.1}}); } } void process(aod::V0Datas const& V0s, FullTracksExt const& tracks, aod::Collisions const&) { - std::map pidmap; - + std::vector pidmap; + pidmap.clear(); + pidmap.resize(tracks.size(), 0); + + std::vector v0pidmap; + v0pidmap.clear(); + if (produceV0ID.value) { + v0pidmap.resize(V0s.size(), -1); + } for (auto& V0 : V0s) { // if (!(V0.posTrack_as().trackType() & o2::aod::track::TPCrefit)) { // continue; @@ -209,10 +222,10 @@ struct v0selector { if (fillhisto) { registry.fill(HIST("hV0Candidate"), 1); } - if (fabs(V0.posTrack_as().eta()) > 0.9) { + if (std::fabs(V0.posTrack_as().eta()) > 0.9) { continue; } - if (fabs(V0.negTrack_as().eta()) > 0.9) { + if (std::fabs(V0.negTrack_as().eta()) > 0.9) { continue; } @@ -222,25 +235,22 @@ struct v0selector { if (V0.negTrack_as().tpcNClsCrossedRows() < mincrossedrows) { continue; } - if (V0.posTrack_as().tpcChi2NCl() > maxchi2tpc) { continue; } if (V0.negTrack_as().tpcChi2NCl() > maxchi2tpc) { continue; } - - if (fabs(V0.posTrack_as().dcaXY()) < dcamin) { + if (std::fabs(V0.posTrack_as().dcaXY()) < dcamin) { continue; } - if (fabs(V0.negTrack_as().dcaXY()) < dcamin) { + if (std::fabs(V0.negTrack_as().dcaXY()) < dcamin) { continue; } - - if (fabs(V0.posTrack_as().dcaXY()) > dcamax) { + if (std::fabs(V0.posTrack_as().dcaXY()) > dcamax) { continue; } - if (fabs(V0.negTrack_as().dcaXY()) > dcamax) { + if (std::fabs(V0.negTrack_as().dcaXY()) > dcamax) { continue; } @@ -304,15 +314,24 @@ struct v0selector { // printf("This is not [Gamma/K0S/Lambda/AntiLambda] candidate.\n"); continue; } + if (fillhisto) { + registry.fill(HIST("hV0APplotSelected"), V0.alpha(), V0.qtarm()); + } + auto storeV0AddID = [&](auto gix, auto id) { + if (produceV0ID.value) { + v0pidmap[gix] = id; + } + }; if (v0id == kGamma) { // photon conversion if (fillhisto) { registry.fill(HIST("hMassGamma"), V0radius, mGamma); registry.fill(HIST("hV0Psi"), psipair, mGamma); } - if (mGamma < v0max_mee && TMath::Abs(V0.posTrack_as().tpcNSigmaEl()) < cutNsigmaElTPC && TMath::Abs(V0.negTrack_as().tpcNSigmaEl()) < cutNsigmaElTPC && TMath::Abs(psipair) < maxpsipair) { + if (mGamma < v0max_mee && std::abs(V0.posTrack_as().tpcNSigmaEl()) < cutNsigmaElTPC && std::abs(V0.negTrack_as().tpcNSigmaEl()) < cutNsigmaElTPC && std::abs(psipair) < maxpsipair) { pidmap[V0.posTrackId()] |= (uint8_t(1) << kGamma); pidmap[V0.negTrackId()] |= (uint8_t(1) << kGamma); + storeV0AddID(V0.globalIndex(), kGamma); if (fillhisto) { registry.fill(HIST("hGammaRxy"), V0.x(), V0.y()); } @@ -324,33 +343,39 @@ struct v0selector { registry.fill(HIST("hMassK0SEta"), V0.eta(), mK0S); registry.fill(HIST("hMassK0SPhi"), V0.phi(), mK0S); } - if ((0.48 < mK0S && mK0S < 0.51) && TMath::Abs(V0.posTrack_as().tpcNSigmaPi()) < cutNsigmaPiTPC && TMath::Abs(V0.negTrack_as().tpcNSigmaPi()) < cutNsigmaPiTPC) { + if ((0.48 < mK0S && mK0S < 0.51) && std::abs(V0.posTrack_as().tpcNSigmaPi()) < cutNsigmaPiTPC && std::abs(V0.negTrack_as().tpcNSigmaPi()) < cutNsigmaPiTPC) { pidmap[V0.posTrackId()] |= (uint8_t(1) << kK0S); pidmap[V0.negTrackId()] |= (uint8_t(1) << kK0S); + storeV0AddID(V0.globalIndex(), kK0S); } } else if (v0id == kLambda) { // L->p + pi- if (fillhisto) { registry.fill(HIST("hMassLambda"), V0radius, mLambda); } - if (v0id == kLambda && (1.110 < mLambda && mLambda < 1.120) && TMath::Abs(V0.posTrack_as().tpcNSigmaPr()) < cutNsigmaPrTPC && TMath::Abs(V0.negTrack_as().tpcNSigmaPi()) < cutNsigmaPiTPC) { + if (v0id == kLambda && (1.110 < mLambda && mLambda < 1.120) && std::abs(V0.posTrack_as().tpcNSigmaPr()) < cutNsigmaPrTPC && std::abs(V0.negTrack_as().tpcNSigmaPi()) < cutNsigmaPiTPC) { pidmap[V0.posTrackId()] |= (uint8_t(1) << kLambda); pidmap[V0.negTrackId()] |= (uint8_t(1) << kLambda); + storeV0AddID(V0.globalIndex(), kLambda); } } else if (v0id == kAntiLambda) { // Lbar -> pbar + pi+ if (fillhisto) { registry.fill(HIST("hMassAntiLambda"), V0radius, mAntiLambda); } - if ((1.110 < mAntiLambda && mAntiLambda < 1.120) && TMath::Abs(V0.posTrack_as().tpcNSigmaPi()) < cutNsigmaPiTPC && TMath::Abs(V0.negTrack_as().tpcNSigmaPr()) < cutNsigmaPrTPC) { + if ((1.110 < mAntiLambda && mAntiLambda < 1.120) && std::abs(V0.posTrack_as().tpcNSigmaPi()) < cutNsigmaPiTPC && std::abs(V0.negTrack_as().tpcNSigmaPr()) < cutNsigmaPrTPC) { pidmap[V0.posTrackId()] |= (uint8_t(1) << kAntiLambda); pidmap[V0.negTrackId()] |= (uint8_t(1) << kAntiLambda); + storeV0AddID(V0.globalIndex(), kAntiLambda); } } - // printf("posTrackId = %d\n",V0.posTrackId()); // printf("negTrackId = %d\n",V0.negTrackId()); } // end of V0 loop - + if (produceV0ID.value) { + for (auto& V0 : V0s) { + v0mapID(v0pidmap[V0.globalIndex()]); + } + } for (auto& track : tracks) { // printf("setting pidmap[%lld] = %d\n",track.globalIndex(),pidmap[track.globalIndex()]); v0bits(pidmap[track.globalIndex()]); @@ -455,15 +480,15 @@ struct trackPIDQA { continue; } - if (fabs(track.dcaXY()) < dcamin) { + if (std::fabs(track.dcaXY()) < dcamin) { continue; } - if (fabs(track.dcaXY()) > dcamax) { + if (std::fabs(track.dcaXY()) > dcamax) { continue; } - if (fabs(track.eta()) > 0.9) { + if (std::fabs(track.eta()) > 0.9) { continue; } diff --git a/PWGEM/Dilepton/Tasks/lmeeHFCocktail.cxx b/PWGEM/Dilepton/Tasks/lmeeHFCocktail.cxx index d26c22c409a..31e66671809 100644 --- a/PWGEM/Dilepton/Tasks/lmeeHFCocktail.cxx +++ b/PWGEM/Dilepton/Tasks/lmeeHFCocktail.cxx @@ -160,11 +160,49 @@ struct MyConfigs : ConfigurableGroup { struct lmeehfcocktailprefilter { + HistogramRegistry registry{"registry", {}}; + std::vector> hRapQuark; Produces hfTable; + ConfigurableAxis fConfigRapBins{"cfgRapBins", {200, -10.f, 10.f}, "Quark rapidity binning"}; + + void init(o2::framework::InitContext&) + { + const int Nchannels = 2; + const char* typeNamesSingle[Nchannels] = {"b", "c"}; + const char* typeTitlesSingle[Nchannels] = {"b", "c"}; + + AxisSpec rap_axis = {fConfigRapBins, "y_{b}"}; + + // quark histograms + for (int i = 0; i < Nchannels; i++) { + hRapQuark.push_back(registry.add(Form("Quark_Rap_%s", typeNamesSingle[i]), Form("Rap Quark %s", typeTitlesSingle[i]), HistType::kTH1F, {rap_axis}, true)); + } + } + void process(aod::McParticles const& mcParticles) { for (auto const& p : mcParticles) { + // Look at quarks which fragment + if (abs(p.pdgCode()) == 5 || abs(p.pdgCode()) == 4) { + bool foundhadrons = kFALSE; + if (p.has_daughters()) { + const auto& daughtersSlice = p.daughters_as(); + for (auto& d : daughtersSlice) { + int pdgfragment = d.pdgCode(); + if (static_cast(abs(pdgfragment) / 100.) == abs(p.pdgCode()) || static_cast(abs(pdgfragment) / 1000.) == abs(p.pdgCode())) { + foundhadrons = kTRUE; + } + } + } + if (foundhadrons) { + if (abs(p.pdgCode()) == 4) + hRapQuark[1]->Fill(p.y()); + else if (abs(p.pdgCode()) == 5) + hRapQuark[0]->Fill(p.y()); + } + } + // Look at electrons if (abs(p.pdgCode()) != 11 || o2::mcgenstatus::getHepMCStatusCode(p.statusCode()) != 1 || !p.has_mothers()) { hfTable(EFromHFType::kNoE, -1, -1, -1, -1, -1, -1, -999., -999.); continue; diff --git a/PWGEM/Dilepton/Tasks/matchingMFT.cxx b/PWGEM/Dilepton/Tasks/matchingMFT.cxx index 895cbad111a..138a6325e1e 100644 --- a/PWGEM/Dilepton/Tasks/matchingMFT.cxx +++ b/PWGEM/Dilepton/Tasks/matchingMFT.cxx @@ -13,6 +13,7 @@ /// \brief a task to study matching MFT-[MCH-MID] in MC /// \author daiki.sekihata@cern.ch +#include #include #include #include @@ -67,12 +68,16 @@ struct matchingMFT { Configurable maxPDCAforLargeR{"maxPDCAforLargeR", 324.f, "max. pDCA for large R at absorber end"}; Configurable maxPDCAforSmallR{"maxPDCAforSmallR", 594.f, "max. pDCA for small R at absorber end"}; Configurable maxMatchingChi2MCHMFT{"maxMatchingChi2MCHMFT", 1e+10, "max. chi2 for MCH-MFT matching"}; - Configurable maxChi2SA{"maxChi2SA", 1e+6, "max. chi2 for standalone muon"}; - Configurable maxChi2GL{"maxChi2GL", 1e+6, "max. chi2 for global muon"}; - // Configurable maxChi2MFT{"maxChi2MFT", 1e+6, "max. chi2/ndf for MFT track in global muon"}; + Configurable maxChi2SA{"maxChi2SA", 1e+6f, "max. chi2 for standalone muon"}; + Configurable maxChi2GL{"maxChi2GL", 1e+6f, "max. chi2 for global muon"}; + Configurable maxChi2MFT{"maxChi2MFT", 1e+6f, "max. chi2/ndf for MFT track in global muon"}; Configurable minNclustersMFT{"minNclustersMFT", 5, "min nclusters MFT"}; Configurable refitGlobalMuon{"refitGlobalMuon", true, "flag to refit global muon"}; Configurable requireTrueAssociation{"requireTrueAssociation", false, "flag to require true mc collision association"}; + Configurable maxDEta{"maxDEta", 1e+10f, "max. deta between MFT-MCH-MID and MCH-MID"}; + Configurable maxDPhi{"maxDPhi", 1e+10f, "max. dphi between MFT-MCH-MID and MCH-MID"}; + Configurable requireMFTHitMap{"requireMFTHitMap", false, "flag to require MFT hit map"}; + Configurable> requiredMFTDisks{"requiredMFTDisks", std::vector{0}, "hit map on MFT disks [0,1,2,3,4]. logical-OR of each double-sided disk"}; Configurable cfgCentEstimator{"cfgCentEstimator", 2, "FT0M:0, FT0A:1, FT0C:2"}; Configurable cfgCentMin{"cfgCentMin", -1.f, "min. centrality"}; @@ -144,17 +149,21 @@ struct matchingMFT { hMuonType->GetXaxis()->SetBinLabel(4, "MCH-MID"); hMuonType->GetXaxis()->SetBinLabel(5, "MCH standalone"); + const AxisSpec axis_pt{{0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2, 3, 4, 5, 6, 7, 8, 9, 10}, "p_{T}^{gl} (GeV/c)"}; + fRegistry.add("MFTMCHMID/primary/correct/hPt", "pT;p_{T} (GeV/c)", kTH1F, {{100, 0.0f, 10}}, false); - fRegistry.add("MFTMCHMID/primary/correct/hEtaPhi", "#eta vs. #varphi;#varphi (rad.);#eta", kTH2F, {{180, 0, 2 * M_PI}, {100, -6.f, -1.f}}, false); - fRegistry.add("MFTMCHMID/primary/correct/hEtaPhi_MatchedMCHMID", "#eta vs. #varphi;#varphi (rad.);#eta", kTH2F, {{180, 0, 2 * M_PI}, {100, -6.f, -1.f}}, false); + fRegistry.add("MFTMCHMID/primary/correct/hEtaPhi", "#eta vs. #varphi;#varphi (rad.);#eta", kTH2F, {{180, 0, 2 * M_PI}, {80, -5.f, -1.f}}, false); + fRegistry.add("MFTMCHMID/primary/correct/hEtaPhi_MatchedMCHMID", "#eta vs. #varphi;#varphi (rad.);#eta", kTH2F, {{180, 0, 2 * M_PI}, {80, -5.f, -1.f}}, false); + fRegistry.add("MFTMCHMID/primary/correct/hsDelta", "diff. between GL and associated SA;p_{T}^{gl} (GeV/c);#Delta#eta;#Delta#varphi (rad.);", kTHnSparseF, {axis_pt, {100, -0.5, +0.5}, {90, -M_PI / 4, M_PI / 4}}, false); fRegistry.add("MFTMCHMID/primary/correct/hDiffCollId", "difference in collision index;collisionId_{TTCA} - collisionId_{MP}", kTH1F, {{41, -20.5, +20.5}}, false); fRegistry.add("MFTMCHMID/primary/correct/hSign", "sign;sign", kTH1F, {{3, -1.5, +1.5}}, false); fRegistry.add("MFTMCHMID/primary/correct/hNclusters", "Nclusters;Nclusters", kTH1F, {{21, -0.5f, 20.5}}, false); fRegistry.add("MFTMCHMID/primary/correct/hNclustersMFT", "NclustersMFT;Nclusters MFT", kTH1F, {{11, -0.5f, 10.5}}, false); + fRegistry.add("MFTMCHMID/primary/correct/hMFTClusterMap", "MFT cluster map", kTH1F, {{1024, -0.5, 1023.5}}, false); fRegistry.add("MFTMCHMID/primary/correct/hRatAbsorberEnd", "R at absorber end;R at absorber end (cm)", kTH1F, {{100, 0.0f, 100}}, false); fRegistry.add("MFTMCHMID/primary/correct/hPDCA_Rabs", "pDCA vs. Rabs;R at absorber end (cm);p #times DCA (GeV/c #upoint cm)", kTH2F, {{100, 0, 100}, {100, 0.0f, 1000}}, false); fRegistry.add("MFTMCHMID/primary/correct/hChi2", "chi2;chi2", kTH1F, {{100, 0.0f, 100}}, false); - fRegistry.add("MFTMCHMID/primary/correct/hChi2MFT", "chi2 MFT;chi2 MFT", kTH1F, {{100, 0.0f, 100}}, false); + fRegistry.add("MFTMCHMID/primary/correct/hChi2MFT", "chi2 MFT/ndf;chi2 MFT/ndf", kTH1F, {{100, 0.0f, 10}}, false); fRegistry.add("MFTMCHMID/primary/correct/hChi2MatchMCHMID", "chi2 match MCH-MID;chi2", kTH1F, {{100, 0.0f, 100}}, false); fRegistry.add("MFTMCHMID/primary/correct/hChi2MatchMCHMFT", "chi2 match MCH-MFT;chi2", kTH1F, {{100, 0.0f, 100}}, false); fRegistry.add("MFTMCHMID/primary/correct/hDCAxy2D", "DCA x vs. y;DCA_{x} (cm);DCA_{y} (cm)", kTH2F, {{200, -0.5, 0.5}, {200, -0.5, +0.5}}, false); @@ -165,15 +174,16 @@ struct matchingMFT { fRegistry.add("MFTMCHMID/primary/correct/hDCAxResolutionvsPt", "DCA_{x} resolution vs. p_{T};p_{T} (GeV/c);DCA_{x} resolution (#mum);", kTH2F, {{100, 0, 10.f}, {500, 0, 500}}, false); fRegistry.add("MFTMCHMID/primary/correct/hDCAyResolutionvsPt", "DCA_{y} resolution vs. p_{T};p_{T} (GeV/c);DCA_{y} resolution (#mum);", kTH2F, {{100, 0, 10.f}, {500, 0, 500}}, false); fRegistry.add("MFTMCHMID/primary/correct/hDCAxyResolutionvsPt", "DCA_{xy} resolution vs. p_{T};p_{T} (GeV/c);DCA_{xy} resolution (#mum);", kTH2F, {{100, 0, 10.f}, {500, 0, 500}}, false); - fRegistry.add("MFTMCHMID/primary/correct/hRelDeltaPt", "pT resolution;p_{T}^{gen} (GeV/c);(p_{T}^{rec} - p_{T}^{gen})/p_{T}^{gen}", kTH2F, {{100, 0, 10}, {400, -1, +1}}, true); - fRegistry.add("MFTMCHMID/primary/correct/hDeltaEta_Pos", "#eta resolution;p_{T}^{gen} (GeV/c);#eta^{rec} - #eta^{gen}", kTH2F, {{100, 0, 10}, {400, -0.2, +0.2}}, true); - fRegistry.add("MFTMCHMID/primary/correct/hDeltaEta_Neg", "#eta resolution;p_{T}^{gen} (GeV/c);#eta^{rec} - #eta^{gen}", kTH2F, {{100, 0, 10}, {400, -0.2, +0.2}}, true); - fRegistry.add("MFTMCHMID/primary/correct/hDeltaPhi_Pos", "#varphi resolution;p_{T}^{gen} (GeV/c);#varphi^{rec} - #varphi^{gen} (rad.)", kTH2F, {{100, 0, 10}, {400, -0.2, +0.2}}, true); - fRegistry.add("MFTMCHMID/primary/correct/hDeltaPhi_Neg", "#varphi resolution;p_{T}^{gen} (GeV/c);#varphi^{rec} - #varphi^{gen} (rad.)", kTH2F, {{100, 0, 10}, {400, -0.2, +0.2}}, true); + + fRegistry.add("MFTMCHMID/primary/correct/hProdVtxZ", "prod. vtx Z of muon;V_{z} (cm)", kTH1F, {{200, -100, 100}}, false); + fRegistry.add("MFTMCHMID/primary/correct/hRelDeltaPt", "pT resolution;p_{T}^{gen} (GeV/c);(p_{T}^{rec} - p_{T}^{gen})/p_{T}^{gen}", kTH2F, {{100, 0, 10}, {400, -1, +1}}, false); + fRegistry.add("MFTMCHMID/primary/correct/hDeltaEta_Pos", "#eta resolution;p_{T}^{gen} (GeV/c);#eta^{rec} - #eta^{gen}", kTH2F, {{100, 0, 10}, {400, -0.2, +0.2}}, false); + fRegistry.add("MFTMCHMID/primary/correct/hDeltaEta_Neg", "#eta resolution;p_{T}^{gen} (GeV/c);#eta^{rec} - #eta^{gen}", kTH2F, {{100, 0, 10}, {400, -0.2, +0.2}}, false); + fRegistry.add("MFTMCHMID/primary/correct/hDeltaPhi_Pos", "#varphi resolution;p_{T}^{gen} (GeV/c);#varphi^{rec} - #varphi^{gen} (rad.)", kTH2F, {{100, 0, 10}, {400, -0.2, +0.2}}, false); + fRegistry.add("MFTMCHMID/primary/correct/hDeltaPhi_Neg", "#varphi resolution;p_{T}^{gen} (GeV/c);#varphi^{rec} - #varphi^{gen} (rad.)", kTH2F, {{100, 0, 10}, {400, -0.2, +0.2}}, false); fRegistry.addClone("MFTMCHMID/primary/correct/", "MFTMCHMID/primary/wrong/"); fRegistry.addClone("MFTMCHMID/primary/", "MFTMCHMID/secondary/"); - - fRegistry.add("Generated/primary/hs", "gen. info;p_{T} (GeV/c);#eta;#varphi (rad.)", kTHnSparseF, {{100, 0.0f, 10}, {60, -5, -2}, {90, 0, 2.f * M_PI}}, false); + // fRegistry.add("Generated/primary/hs", "gen. info;p_{T} (GeV/c);#eta;#varphi (rad.)", kTHnSparseF, {{100, 0.0f, 10}, {60, -5, -2}, {90, 0, 2.f * M_PI}}, false); } bool isSelected(const float pt, const float eta, const float rAtAbsorberEnd, const float pDCA, const float chi2, const uint8_t trackType, const float dcaXY) @@ -212,6 +222,33 @@ struct matchingMFT { return true; } + template + uint16_t mftClusterMap(T const& track) + { + uint64_t mftClusterSizesAndTrackFlags = track.mftClusterSizesAndTrackFlags(); + uint16_t clmap = 0; + for (unsigned int layer = 0; layer < 10; layer++) { + if ((mftClusterSizesAndTrackFlags >> (layer * 6)) & 0x3f) { + clmap |= (1 << layer); + } + } + return clmap; + } + + template + bool hasMFT(T const& track) + { + // logical-OR + uint64_t mftClusterSizesAndTrackFlags = track.mftClusterSizesAndTrackFlags(); + uint16_t clmap = 0; + for (unsigned int layer = begin; layer <= end; layer++) { + if ((mftClusterSizesAndTrackFlags >> (layer * 6)) & 0x3f) { + clmap |= (1 << layer); + } + } + return (clmap > 0); + } + template void fillHistograms(TCollision const& collision, TFwdTrack fwdtrack, TFwdTracks const&, TMFTTracks const&) { @@ -272,15 +309,26 @@ struct matchingMFT { float rAtAbsorberEnd = fwdtrack.rAtAbsorberEnd(); // this works only for GlobalMuonTrack float dcaXY = std::sqrt(dcaX * dcaX + dcaY * dcaY); float dcaZ = -dcaXY * std::sinh(eta); + float det = cXXatDCA * cYYatDCA - cXYatDCA * cXYatDCA; // determinanat - float dFdx = dcaX / dcaXY; - float dFdy = dcaY / dcaXY; - float sigma_dcaXY = std::sqrt(cXXatDCA * dFdx * dFdx + cYYatDCA * dFdy * dFdy + 2.f * cXYatDCA * dFdx * dFdy); + float dcaXYinSigma = 999.f; + if (det < 0) { + dcaXYinSigma = 999.f; + } else { + dcaXYinSigma = std::sqrt(std::fabs((dcaX * dcaX * cYYatDCA + dcaY * dcaY * cXXatDCA - 2. * dcaX * dcaY * cXYatDCA) / det / 2.)); // dca xy in sigma + } + float sigma_dcaXY = dcaXY / dcaXYinSigma; o2::dataformats::GlobalFwdTrack propmuonAtPV_Matched = propagateMuon(mchtrack, collision, propagationPoint::kToVertex); float etaMatchedMCHMID = propmuonAtPV_Matched.getEta(); float phiMatchedMCHMID = propmuonAtPV_Matched.getPhi(); o2::math_utils::bringTo02Pi(phiMatchedMCHMID); + float deta = etaMatchedMCHMID - eta; + float dphi = phiMatchedMCHMID - phi; + o2::math_utils::bringToPMPi(dphi); + if (std::sqrt(std::pow(deta / maxDEta, 2) + std::pow(dphi / maxDPhi, 2)) > 1.f) { + return; + } o2::dataformats::GlobalFwdTrack propmuonAtDCA_Matched = propagateMuon(mchtrack, collision, propagationPoint::kToDCA); float dcaX_Matched = propmuonAtDCA_Matched.getX() - collision.posX(); @@ -288,11 +336,11 @@ struct matchingMFT { float dcaXY_Matched = std::sqrt(dcaX_Matched * dcaX_Matched + dcaY_Matched * dcaY_Matched); float pDCA = mchtrack.p() * dcaXY_Matched; int nClustersMFT = mfttrack.nClusters(); - // float chi2mft = mfttrack.chi2()/(2.f * nClustersMFT - 5.f); - float chi2mft = mfttrack.chi2(); - // if (chi2mft < 0.f || maxChi2MFT < chi2mft) { - // return; - // } + float chi2mft = mfttrack.chi2() / (2.f * nClustersMFT - 5.f); + // float chi2mft = mfttrack.chi2(); + if (chi2mft < 0.f || maxChi2MFT < chi2mft) { + return; + } if (refitGlobalMuon) { eta = mfttrack.eta(); @@ -305,16 +353,27 @@ struct matchingMFT { return; } + if (requireMFTHitMap) { + std::vector hasMFTs{hasMFT<0, 1>(mfttrack), hasMFT<2, 3>(mfttrack), hasMFT<4, 5>(mfttrack), hasMFT<6, 7>(mfttrack), hasMFT<8, 9>(mfttrack)}; + for (int i = 0; i < static_cast(requiredMFTDisks->size()); i++) { + if (!hasMFTs[requiredMFTDisks->at(i)]) { + return; + } + } + } + fRegistry.fill(HIST("hMuonType"), fwdtrack.trackType()); if (isPrimary) { if (isMatched) { fRegistry.fill(HIST("MFTMCHMID/primary/correct/hPt"), pt); fRegistry.fill(HIST("MFTMCHMID/primary/correct/hEtaPhi"), phi, eta); fRegistry.fill(HIST("MFTMCHMID/primary/correct/hEtaPhi_MatchedMCHMID"), phiMatchedMCHMID, etaMatchedMCHMID); + fRegistry.fill(HIST("MFTMCHMID/primary/correct/hsDelta"), pt, deta, dphi); fRegistry.fill(HIST("MFTMCHMID/primary/correct/hDiffCollId"), collision.globalIndex() - fwdtrack.collisionId()); fRegistry.fill(HIST("MFTMCHMID/primary/correct/hSign"), fwdtrack.sign()); fRegistry.fill(HIST("MFTMCHMID/primary/correct/hNclusters"), fwdtrack.nClusters()); fRegistry.fill(HIST("MFTMCHMID/primary/correct/hNclustersMFT"), nClustersMFT); + fRegistry.fill(HIST("MFTMCHMID/primary/correct/hMFTClusterMap"), mftClusterMap(mfttrack)); fRegistry.fill(HIST("MFTMCHMID/primary/correct/hPDCA_Rabs"), rAtAbsorberEnd, pDCA); fRegistry.fill(HIST("MFTMCHMID/primary/correct/hRatAbsorberEnd"), rAtAbsorberEnd); fRegistry.fill(HIST("MFTMCHMID/primary/correct/hChi2"), fwdtrack.chi2()); @@ -325,10 +384,11 @@ struct matchingMFT { fRegistry.fill(HIST("MFTMCHMID/primary/correct/hDCAz"), dcaZ); fRegistry.fill(HIST("MFTMCHMID/primary/correct/hDCAxy2DinSigma"), dcaX / std::sqrt(cXXatDCA), dcaY / std::sqrt(cYYatDCA)); fRegistry.fill(HIST("MFTMCHMID/primary/correct/hDCAxy"), dcaXY); - fRegistry.fill(HIST("MFTMCHMID/primary/correct/hDCAxyinSigma"), dcaXY / sigma_dcaXY); + fRegistry.fill(HIST("MFTMCHMID/primary/correct/hDCAxyinSigma"), dcaXYinSigma); fRegistry.fill(HIST("MFTMCHMID/primary/correct/hDCAxResolutionvsPt"), pt, std::sqrt(cXXatDCA) * 1e+4); // convert cm to um fRegistry.fill(HIST("MFTMCHMID/primary/correct/hDCAyResolutionvsPt"), pt, std::sqrt(cYYatDCA) * 1e+4); // convert cm to um fRegistry.fill(HIST("MFTMCHMID/primary/correct/hDCAxyResolutionvsPt"), pt, sigma_dcaXY * 1e+4); // convert cm to um + fRegistry.fill(HIST("MFTMCHMID/primary/correct/hProdVtxZ"), mcParticle_MFTMCHMID.vz()); fRegistry.fill(HIST("MFTMCHMID/primary/correct/hRelDeltaPt"), mcParticle_MFTMCHMID.pt(), (pt - mcParticle_MFTMCHMID.pt()) / mcParticle_MFTMCHMID.pt()); if (mcParticle_MFTMCHMID.pdgCode() > 0) { @@ -342,10 +402,12 @@ struct matchingMFT { fRegistry.fill(HIST("MFTMCHMID/primary/wrong/hPt"), pt); fRegistry.fill(HIST("MFTMCHMID/primary/wrong/hEtaPhi"), phi, eta); fRegistry.fill(HIST("MFTMCHMID/primary/wrong/hEtaPhi_MatchedMCHMID"), phiMatchedMCHMID, etaMatchedMCHMID); + fRegistry.fill(HIST("MFTMCHMID/primary/wrong/hsDelta"), pt, deta, dphi); fRegistry.fill(HIST("MFTMCHMID/primary/wrong/hDiffCollId"), collision.globalIndex() - fwdtrack.collisionId()); fRegistry.fill(HIST("MFTMCHMID/primary/wrong/hSign"), fwdtrack.sign()); fRegistry.fill(HIST("MFTMCHMID/primary/wrong/hNclusters"), fwdtrack.nClusters()); fRegistry.fill(HIST("MFTMCHMID/primary/wrong/hNclustersMFT"), nClustersMFT); + fRegistry.fill(HIST("MFTMCHMID/primary/wrong/hMFTClusterMap"), mftClusterMap(mfttrack)); fRegistry.fill(HIST("MFTMCHMID/primary/wrong/hPDCA_Rabs"), rAtAbsorberEnd, pDCA); fRegistry.fill(HIST("MFTMCHMID/primary/wrong/hRatAbsorberEnd"), rAtAbsorberEnd); fRegistry.fill(HIST("MFTMCHMID/primary/wrong/hChi2"), fwdtrack.chi2()); @@ -356,10 +418,11 @@ struct matchingMFT { fRegistry.fill(HIST("MFTMCHMID/primary/wrong/hDCAz"), dcaZ); fRegistry.fill(HIST("MFTMCHMID/primary/wrong/hDCAxy2DinSigma"), dcaX / std::sqrt(cXXatDCA), dcaY / std::sqrt(cYYatDCA)); fRegistry.fill(HIST("MFTMCHMID/primary/wrong/hDCAxy"), dcaXY); - fRegistry.fill(HIST("MFTMCHMID/primary/wrong/hDCAxyinSigma"), dcaXY / sigma_dcaXY); + fRegistry.fill(HIST("MFTMCHMID/primary/wrong/hDCAxyinSigma"), dcaXYinSigma); fRegistry.fill(HIST("MFTMCHMID/primary/wrong/hDCAxResolutionvsPt"), pt, std::sqrt(cXXatDCA) * 1e+4); // convert cm to um fRegistry.fill(HIST("MFTMCHMID/primary/wrong/hDCAyResolutionvsPt"), pt, std::sqrt(cYYatDCA) * 1e+4); // convert cm to um fRegistry.fill(HIST("MFTMCHMID/primary/wrong/hDCAxyResolutionvsPt"), pt, sigma_dcaXY * 1e+4); // convert cm to um + fRegistry.fill(HIST("MFTMCHMID/primary/wrong/hProdVtxZ"), mcParticle_MFTMCHMID.vz()); fRegistry.fill(HIST("MFTMCHMID/primary/wrong/hRelDeltaPt"), mcParticle_MFTMCHMID.pt(), (pt - mcParticle_MFTMCHMID.pt()) / mcParticle_MFTMCHMID.pt()); if (mcParticle_MFTMCHMID.pdgCode() > 0) { fRegistry.fill(HIST("MFTMCHMID/primary/wrong/hDeltaEta_Neg"), mcParticle_MFTMCHMID.pt(), eta - mcParticle_MFTMCHMID.eta()); @@ -374,10 +437,12 @@ struct matchingMFT { fRegistry.fill(HIST("MFTMCHMID/secondary/correct/hPt"), pt); fRegistry.fill(HIST("MFTMCHMID/secondary/correct/hEtaPhi"), phi, eta); fRegistry.fill(HIST("MFTMCHMID/secondary/correct/hEtaPhi_MatchedMCHMID"), phiMatchedMCHMID, etaMatchedMCHMID); + fRegistry.fill(HIST("MFTMCHMID/secondary/correct/hsDelta"), pt, deta, dphi); fRegistry.fill(HIST("MFTMCHMID/secondary/correct/hDiffCollId"), collision.globalIndex() - fwdtrack.collisionId()); fRegistry.fill(HIST("MFTMCHMID/secondary/correct/hSign"), fwdtrack.sign()); fRegistry.fill(HIST("MFTMCHMID/secondary/correct/hNclusters"), fwdtrack.nClusters()); fRegistry.fill(HIST("MFTMCHMID/secondary/correct/hNclustersMFT"), nClustersMFT); + fRegistry.fill(HIST("MFTMCHMID/secondary/correct/hMFTClusterMap"), mftClusterMap(mfttrack)); fRegistry.fill(HIST("MFTMCHMID/secondary/correct/hPDCA_Rabs"), rAtAbsorberEnd, pDCA); fRegistry.fill(HIST("MFTMCHMID/secondary/correct/hRatAbsorberEnd"), rAtAbsorberEnd); fRegistry.fill(HIST("MFTMCHMID/secondary/correct/hChi2"), fwdtrack.chi2()); @@ -388,10 +453,11 @@ struct matchingMFT { fRegistry.fill(HIST("MFTMCHMID/secondary/correct/hDCAz"), dcaZ); fRegistry.fill(HIST("MFTMCHMID/secondary/correct/hDCAxy2DinSigma"), dcaX / std::sqrt(cXXatDCA), dcaY / std::sqrt(cYYatDCA)); fRegistry.fill(HIST("MFTMCHMID/secondary/correct/hDCAxy"), dcaXY); - fRegistry.fill(HIST("MFTMCHMID/secondary/correct/hDCAxyinSigma"), dcaXY / sigma_dcaXY); + fRegistry.fill(HIST("MFTMCHMID/secondary/correct/hDCAxyinSigma"), dcaXYinSigma); fRegistry.fill(HIST("MFTMCHMID/secondary/correct/hDCAxResolutionvsPt"), pt, std::sqrt(cXXatDCA) * 1e+4); // convert cm to um fRegistry.fill(HIST("MFTMCHMID/secondary/correct/hDCAyResolutionvsPt"), pt, std::sqrt(cYYatDCA) * 1e+4); // convert cm to um fRegistry.fill(HIST("MFTMCHMID/secondary/correct/hDCAxyResolutionvsPt"), pt, sigma_dcaXY * 1e+4); // convert cm to um + fRegistry.fill(HIST("MFTMCHMID/secondary/correct/hProdVtxZ"), mcParticle_MFTMCHMID.vz()); fRegistry.fill(HIST("MFTMCHMID/secondary/correct/hRelDeltaPt"), mcParticle_MFTMCHMID.pt(), (pt - mcParticle_MFTMCHMID.pt()) / mcParticle_MFTMCHMID.pt()); if (mcParticle_MFTMCHMID.pdgCode() > 0) { fRegistry.fill(HIST("MFTMCHMID/secondary/correct/hDeltaEta_Neg"), mcParticle_MFTMCHMID.pt(), eta - mcParticle_MFTMCHMID.eta()); @@ -404,10 +470,12 @@ struct matchingMFT { fRegistry.fill(HIST("MFTMCHMID/secondary/wrong/hPt"), pt); fRegistry.fill(HIST("MFTMCHMID/secondary/wrong/hEtaPhi"), phi, eta); fRegistry.fill(HIST("MFTMCHMID/secondary/wrong/hEtaPhi_MatchedMCHMID"), phiMatchedMCHMID, etaMatchedMCHMID); + fRegistry.fill(HIST("MFTMCHMID/secondary/wrong/hsDelta"), pt, deta, dphi); fRegistry.fill(HIST("MFTMCHMID/secondary/wrong/hDiffCollId"), collision.globalIndex() - fwdtrack.collisionId()); fRegistry.fill(HIST("MFTMCHMID/secondary/wrong/hSign"), fwdtrack.sign()); fRegistry.fill(HIST("MFTMCHMID/secondary/wrong/hNclusters"), fwdtrack.nClusters()); fRegistry.fill(HIST("MFTMCHMID/secondary/wrong/hNclustersMFT"), nClustersMFT); + fRegistry.fill(HIST("MFTMCHMID/secondary/wrong/hMFTClusterMap"), mftClusterMap(mfttrack)); fRegistry.fill(HIST("MFTMCHMID/secondary/wrong/hPDCA_Rabs"), rAtAbsorberEnd, pDCA); fRegistry.fill(HIST("MFTMCHMID/secondary/wrong/hRatAbsorberEnd"), rAtAbsorberEnd); fRegistry.fill(HIST("MFTMCHMID/secondary/wrong/hChi2"), fwdtrack.chi2()); @@ -418,10 +486,11 @@ struct matchingMFT { fRegistry.fill(HIST("MFTMCHMID/secondary/wrong/hDCAz"), dcaZ); fRegistry.fill(HIST("MFTMCHMID/secondary/wrong/hDCAxy2DinSigma"), dcaX / std::sqrt(cXXatDCA), dcaY / std::sqrt(cYYatDCA)); fRegistry.fill(HIST("MFTMCHMID/secondary/wrong/hDCAxy"), dcaXY); - fRegistry.fill(HIST("MFTMCHMID/secondary/wrong/hDCAxyinSigma"), dcaXY / sigma_dcaXY); + fRegistry.fill(HIST("MFTMCHMID/secondary/wrong/hDCAxyinSigma"), dcaXYinSigma); fRegistry.fill(HIST("MFTMCHMID/secondary/wrong/hDCAxResolutionvsPt"), pt, std::sqrt(cXXatDCA) * 1e+4); // convert cm to um fRegistry.fill(HIST("MFTMCHMID/secondary/wrong/hDCAyResolutionvsPt"), pt, std::sqrt(cYYatDCA) * 1e+4); // convert cm to um fRegistry.fill(HIST("MFTMCHMID/secondary/wrong/hDCAxyResolutionvsPt"), pt, sigma_dcaXY * 1e+4); // convert cm to um + fRegistry.fill(HIST("MFTMCHMID/secondary/wrong/hProdVtxZ"), mcParticle_MFTMCHMID.vz()); fRegistry.fill(HIST("MFTMCHMID/secondary/wrong/hRelDeltaPt"), mcParticle_MFTMCHMID.pt(), (pt - mcParticle_MFTMCHMID.pt()) / mcParticle_MFTMCHMID.pt()); if (mcParticle_MFTMCHMID.pdgCode() > 0) { fRegistry.fill(HIST("MFTMCHMID/secondary/wrong/hDeltaEta_Neg"), mcParticle_MFTMCHMID.pt(), eta - mcParticle_MFTMCHMID.eta()); @@ -448,24 +517,24 @@ struct matchingMFT { fRegistry.fill(HIST("Event/hMultFT0CvsMultNTracksPV"), collision.multFT0C(), collision.multNTracksPV()); } - template - void runGen(TMCParticles const& mcParticles) - { - for (const auto& mcParticle : mcParticles) { - if (std::abs(mcParticle.pdgCode()) != 13) { // select true muon - continue; - } - if (!(mcParticle.isPhysicalPrimary() || mcParticle.producedByGenerator())) { - continue; - } - if (mcParticle.eta() < minEtaGL || maxEtaGL < mcParticle.eta()) { - continue; - } - - fRegistry.fill(HIST("Generated/primary/hs"), mcParticle.pt(), mcParticle.eta(), mcParticle.phi()); - - } // end of mc particles - } + // template + // void runGen(TMCParticles const& mcParticles) + // { + // for (const auto& mcParticle : mcParticles) { + // if (std::abs(mcParticle.pdgCode()) != 13) { // select true muon + // continue; + // } + // if (!(mcParticle.isPhysicalPrimary() || mcParticle.producedByGenerator())) { + // continue; + // } + // if (mcParticle.eta() < minEtaGL || maxEtaGL < mcParticle.eta()) { + // continue; + // } + + // fRegistry.fill(HIST("Generated/primary/hs"), mcParticle.pt(), mcParticle.eta(), mcParticle.phi()); + + // } // end of mc particles + // } SliceCache cache; PresliceUnsorted perMFTTrack = o2::aod::fwdtrack::matchMFTTrackId; @@ -477,7 +546,7 @@ struct matchingMFT { Filter collisionFilter_centrality = (cfgCentMin < o2::aod::cent::centFT0M && o2::aod::cent::centFT0M < cfgCentMax) || (cfgCentMin < o2::aod::cent::centFT0A && o2::aod::cent::centFT0A < cfgCentMax) || (cfgCentMin < o2::aod::cent::centFT0C && o2::aod::cent::centFT0C < cfgCentMax); using FilteredMyCollisions = soa::Filtered; - void processWithoutFTTCA(FilteredMyCollisions const& collisions, MyFwdTracks const& fwdtracks, MyMFTTracks const& mfttracks, aod::BCsWithTimestamps const&, aod::McParticles const& mcParticles) + void processWithoutFTTCA(FilteredMyCollisions const& collisions, MyFwdTracks const& fwdtracks, MyMFTTracks const& mfttracks, aod::BCsWithTimestamps const&, aod::McParticles const&) { for (const auto& collision : collisions) { const auto& bc = collision.template bc_as(); @@ -501,11 +570,11 @@ struct matchingMFT { fillHistograms(collision, fwdtrack, fwdtracks, mfttracks); } // end of fwdtrack loop } // end of collision loop - runGen(mcParticles); + // runGen(mcParticles); } PROCESS_SWITCH(matchingMFT, processWithoutFTTCA, "process without FTTCA", false); - void processWithFTTCA(FilteredMyCollisions const& collisions, MyFwdTracks const& fwdtracks, MyMFTTracks const& mfttracks, aod::BCsWithTimestamps const&, aod::FwdTrackAssoc const& fwdtrackIndices, aod::McParticles const& mcParticles) + void processWithFTTCA(FilteredMyCollisions const& collisions, MyFwdTracks const& fwdtracks, MyMFTTracks const& mfttracks, aod::BCsWithTimestamps const&, aod::FwdTrackAssoc const& fwdtrackIndices, aod::McParticles const&) { for (const auto& collision : collisions) { const auto& bc = collision.template bc_as(); @@ -530,7 +599,7 @@ struct matchingMFT { fillHistograms(collision, fwdtrack, fwdtracks, mfttracks); } // end of fwdtrack loop } // end of collision loop - runGen(mcParticles); + // runGen(mcParticles); } PROCESS_SWITCH(matchingMFT, processWithFTTCA, "process with FTTCA", true); }; diff --git a/PWGEM/Dilepton/Tasks/tableReaderBarrel.cxx b/PWGEM/Dilepton/Tasks/tableReaderBarrel.cxx index d78ef01676c..819a85efe65 100644 --- a/PWGEM/Dilepton/Tasks/tableReaderBarrel.cxx +++ b/PWGEM/Dilepton/Tasks/tableReaderBarrel.cxx @@ -291,8 +291,6 @@ struct AnalysisTrackSelection { Configurable fConfigNoLaterThan{"ccdb-no-later-than", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable timestamp of creation for the object"}; Configurable fConfigComputeTPCpostCalib{"cfgTPCpostCalib", false, "If true, compute TPC post-calibrated n-sigmas"}; Configurable fConfigRunPeriods{"cfgRunPeriods", "LHC22f", "run periods for used data"}; - Configurable fConfigDummyRunlist{"cfgDummyRunlist", false, "If true, use dummy runlist"}; - Configurable fConfigInitRunNumber{"cfgInitRunNumber", 543215, "Initial run number used in run by run checks"}; Configurable fConfigNbTrackCut{"cfgNbTrackCut", 1, "Number of cuts including prefilter cut, need to be below 30"}; std::vector fTrackCuts; @@ -372,9 +370,6 @@ struct AnalysisTrackSelection { VarManager::SetUseVars(fHistMan->GetUsedVars()); // provide the list of required variables so that VarManager knows what to fill fOutputList.setObject(fHistMan->GetMainHistogramList()); } - if (fConfigDummyRunlist) { - VarManager::SetDummyRunlist(fConfigInitRunNumber); - } if (fConfigComputeTPCpostCalib) { // CCDB configuration fCCDB->setURL(fConfigCcdbUrl.value); diff --git a/PWGEM/Dilepton/Utils/MCUtilities.h b/PWGEM/Dilepton/Utils/MCUtilities.h index 58484f6fe66..c6c1aacfe04 100644 --- a/PWGEM/Dilepton/Utils/MCUtilities.h +++ b/PWGEM/Dilepton/Utils/MCUtilities.h @@ -481,14 +481,16 @@ int searchMothers(T& p, U& mcParticles, int pdg, bool equal) for (int i : allmothersids) { auto mother = mcParticles.iteratorAt(i); int mpdg = mother.pdgCode(); - if (abs(mpdg) == pdg && mpdg * p.pdgCode() > 0) { // check for quark - if (quark_id > -1 || next_mother_id > -1) { // we already found a possible candidate in the list of mothers, so now we have (at least) two + // if (abs(mpdg) == pdg && mpdg * p.pdgCode() > 0) { // check for quark + if (abs(mpdg) == pdg) { // check for quark to allow for beauty and charm + oscillation + if (quark_id > -1 || next_mother_id > -1) { // we already found a possible candidate in the list of mothers, so now we have (at least) two // LOG(warning) << "Flavour tracking is ambiguous. Stopping here."; return -1; } quark_id = i; - } else if ((static_cast(abs(mpdg) / 100) == pdg || static_cast(abs(mpdg) / 1000) == pdg) && mpdg * p.pdgCode() > 0) { // check for other mothers with flavour content - if (quark_id > -1 || next_mother_id > -1) { // we already found a possible candidate in the list of mothers, so now we have (at least) two + //} else if ((static_cast(abs(mpdg) / 100) == pdg || static_cast(abs(mpdg) / 1000) == pdg) && mpdg * p.pdgCode() > 0) { // check for other mothers with flavour content + } else if ((static_cast(abs(mpdg) / 100) == pdg || static_cast(abs(mpdg) / 1000) == pdg)) { // check for other mothers with flavour content to allow for beauty and charm + if (quark_id > -1 || next_mother_id > -1) { // we already found a possible candidate in the list of mothers, so now we have (at least) two // LOG(warning) << "Flavour tracking is ambiguous. Stopping here."; return -1; } diff --git a/PWGEM/PhotonMeson/DataModel/bcWiseTables.h b/PWGEM/PhotonMeson/DataModel/bcWiseTables.h new file mode 100644 index 00000000000..903dfefa23d --- /dev/null +++ b/PWGEM/PhotonMeson/DataModel/bcWiseTables.h @@ -0,0 +1,144 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// 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. +/// +/// \file bcWiseTables.h +/// +/// \brief This header provides the table definitions to store very lightweight EMCal clusters per BC +/// +/// \author Nicolas Strangmann (nicolas.strangmann@cern.ch) - Goethe University Frankfurt +/// + +#ifndef PWGEM_PHOTONMESON_DATAMODEL_BCWISETABLES_H_ +#define PWGEM_PHOTONMESON_DATAMODEL_BCWISETABLES_H_ + +#include "Framework/AnalysisDataModel.h" + +namespace o2::aod +{ + +namespace emdownscaling +{ +enum Observables { + kDefinition, + kEnergy, + kEta, + kPhi, + kNCells, + kM02, + kTime, + kFT0MCent, + kZVtx, + kFT0Amp, + kpT, + nObservables +}; + +// Values in tables are stored in downscaled format to save disk space +const float downscalingFactors[nObservables]{ + 1E0, // Cluster definition + 1E3, // Cluster energy + 1E4, // Cluster eta + 1E4, // Cluster phi + 1E0, // Number of cells + 1E4, // M02 + 1E2, // Cluster time + 2E0, // FT0M centrality + 1E3, // Z-vertex position + 1E-1, // FT0M amplitude + 1E3}; // MC pi0 pt +} // namespace emdownscaling + +namespace bcwisebc +{ +DECLARE_SOA_COLUMN(HasFT0, hasFT0, bool); //! has_foundFT0() +DECLARE_SOA_COLUMN(HasTVX, hasTVX, bool); //! has the TVX trigger flag +DECLARE_SOA_COLUMN(HaskTVXinEMC, haskTVXinEMC, bool); //! kTVXinEMC +DECLARE_SOA_COLUMN(HasEMCCell, hasEMCCell, bool); //! at least one EMCal cell in the BC +DECLARE_SOA_COLUMN(HasNoTFROFBorder, hasNoTFROFBorder, bool); //! not in the TF border or ITS ROF border region +DECLARE_SOA_COLUMN(StoredFT0MAmplitude, storedFT0MAmplitude, uint16_t); //! ft0a+c amplitude + +DECLARE_SOA_DYNAMIC_COLUMN(FT0MAmplitude, ft0Amplitude, [](uint16_t storedFT0MAmplitude) -> float { return storedFT0MAmplitude / emdownscaling::downscalingFactors[emdownscaling::kFT0Amp]; }); //! FT0M amplitude +} // namespace bcwisebc +DECLARE_SOA_TABLE(BCWiseBCs, "AOD", "BCWISEBC", //! table of bc wise centrality estimation and event selection input + o2::soa::Index<>, bcwisebc::HasFT0, bcwisebc::HasTVX, bcwisebc::HaskTVXinEMC, bcwisebc::HasEMCCell, bcwisebc::HasNoTFROFBorder, + bcwisebc::StoredFT0MAmplitude, bcwisebc::FT0MAmplitude); + +DECLARE_SOA_INDEX_COLUMN(BCWiseBC, bcWiseBC); //! bunch crossing ID used as index + +namespace bcwisecollision +{ +DECLARE_SOA_COLUMN(StoredCentrality, storedCentrality, uint8_t); //! FT0M centrality (0-100) (x2) +DECLARE_SOA_COLUMN(StoredZVtx, storedZVtx, int16_t); //! Z-vertex position (x1000) + +DECLARE_SOA_DYNAMIC_COLUMN(Centrality, centrality, [](uint8_t storedcentrality) -> float { return storedcentrality / emdownscaling::downscalingFactors[emdownscaling::kFT0MCent]; }); //! Centrality (0-100) +DECLARE_SOA_DYNAMIC_COLUMN(ZVtx, zVtx, [](int16_t storedzvtx) -> float { return storedzvtx / emdownscaling::downscalingFactors[emdownscaling::kZVtx]; }); //! Centrality (0-100) +} // namespace bcwisecollision +DECLARE_SOA_TABLE(BCWiseCollisions, "AOD", "BCWISECOLL", //! table of skimmed EMCal clusters + o2::soa::Index<>, BCWiseBCId, bcwisecollision::StoredCentrality, bcwisecollision::StoredZVtx, + bcwisecollision::Centrality, bcwisecollision::ZVtx); + +namespace bcwisecluster +{ +DECLARE_SOA_COLUMN(StoredDefinition, storedDefinition, int8_t); //! cluster definition, see EMCALClusterDefinition.h +DECLARE_SOA_COLUMN(StoredE, storedE, int16_t); //! cluster energy (1 MeV -> Maximum cluster energy of ~32 GeV) +DECLARE_SOA_COLUMN(StoredEta, storedEta, int16_t); //! cluster pseudorapidity (x10,000) +DECLARE_SOA_COLUMN(StoredPhi, storedPhi, uint16_t); //! cluster azimuthal angle (x10 000) from 0 to 2pi +DECLARE_SOA_COLUMN(StoredNCells, storedNCells, int8_t); //! number of cells in cluster +DECLARE_SOA_COLUMN(StoredM02, storedM02, int16_t); //! shower shape long axis (x10 000) +DECLARE_SOA_COLUMN(StoredTime, storedTime, int16_t); //! cluster time (10 ps resolution) +DECLARE_SOA_COLUMN(StoredIsExotic, storedIsExotic, bool); //! flag to mark cluster as exotic + +DECLARE_SOA_DYNAMIC_COLUMN(Definition, definition, [](int8_t storedDefinition) -> int8_t { return storedDefinition; }); //! cluster definition, see EMCALClusterDefinition.h +DECLARE_SOA_DYNAMIC_COLUMN(E, e, [](int16_t storedE) -> float { return storedE / emdownscaling::downscalingFactors[emdownscaling::kEnergy]; }); //! cluster energy (GeV) +DECLARE_SOA_DYNAMIC_COLUMN(Eta, eta, [](int16_t storedEta) -> float { return storedEta / emdownscaling::downscalingFactors[emdownscaling::kEta]; }); //! cluster pseudorapidity +DECLARE_SOA_DYNAMIC_COLUMN(Phi, phi, [](uint16_t storedPhi) -> float { return storedPhi / emdownscaling::downscalingFactors[emdownscaling::kPhi]; }); //! cluster azimuthal angle (0 to 2pi) +DECLARE_SOA_DYNAMIC_COLUMN(NCells, nCells, [](int16_t storedNCells) -> int16_t { return storedNCells; }); //! number of cells in cluster +DECLARE_SOA_DYNAMIC_COLUMN(M02, m02, [](int16_t storedM02) -> float { return storedM02 / emdownscaling::downscalingFactors[emdownscaling::kM02]; }); //! shower shape long axis +DECLARE_SOA_DYNAMIC_COLUMN(Time, time, [](int16_t storedTime) -> float { return storedTime / emdownscaling::downscalingFactors[emdownscaling::kTime]; }); //! cluster time (ns) +DECLARE_SOA_DYNAMIC_COLUMN(IsExotic, isExotic, [](bool storedIsExotic) -> bool { return storedIsExotic; }); //! flag to mark cluster as exotic + +DECLARE_SOA_DYNAMIC_COLUMN(Pt, pt, [](float storedE, float storedEta) -> float { return storedE / emdownscaling::downscalingFactors[emdownscaling::kEnergy] / std::cosh(storedEta / emdownscaling::downscalingFactors[emdownscaling::kEta]); }); //! cluster pt, assuming m=0 (photons) +} // namespace bcwisecluster + +DECLARE_SOA_TABLE(BCWiseClusters, "AOD", "BCWISECLUSTER", //! table of skimmed EMCal clusters + o2::soa::Index<>, BCWiseBCId, bcwisecluster::StoredDefinition, bcwisecluster::StoredE, bcwisecluster::StoredEta, bcwisecluster::StoredPhi, bcwisecluster::StoredNCells, bcwisecluster::StoredM02, bcwisecluster::StoredTime, bcwisecluster::StoredIsExotic, + bcwisecluster::Definition, bcwisecluster::E, bcwisecluster::Eta, bcwisecluster::Phi, bcwisecluster::NCells, bcwisecluster::M02, bcwisecluster::Time, bcwisecluster::IsExotic, + bcwisecluster::Pt); + +namespace bcwisemcpi0s +{ +DECLARE_SOA_COLUMN(StoredPt, storedPt, uint16_t); //! Transverse momentum of generated pi0 (1 MeV -> Maximum pi0 pT of ~65 GeV) +DECLARE_SOA_COLUMN(IsAccepted, isAccepted, bool); //! Both decay photons are within the EMCal acceptance +DECLARE_SOA_COLUMN(IsPrimary, isPrimary, bool); //! mcParticle.isPhysicalPrimary() || mcParticle.producedByGenerator() +DECLARE_SOA_COLUMN(IsFromWD, isFromWD, bool); //! Pi0 from a weak decay according to pwgem::photonmeson::utils::mcutil::IsFromWD + +DECLARE_SOA_DYNAMIC_COLUMN(Pt, pt, [](uint16_t storedpt) -> float { return storedpt / emdownscaling::downscalingFactors[emdownscaling::kpT]; }); //! pT of pi0 (GeV) +} // namespace bcwisemcpi0s + +DECLARE_SOA_TABLE(BCWiseMCPi0s, "AOD", "BCWISEMCPI0", //! table of pi0s on MC level + o2::soa::Index<>, BCWiseBCId, bcwisemcpi0s::StoredPt, bcwisemcpi0s::IsAccepted, bcwisemcpi0s::IsPrimary, bcwisemcpi0s::IsFromWD, + bcwisemcpi0s::Pt); + +namespace bcwisemccluster +{ +DECLARE_SOA_COLUMN(Pi0ID, pi0ID, int32_t); //! Index of the mother pi0 (-1 if not from pi0) +DECLARE_SOA_COLUMN(StoredTrueE, storedTrueE, uint16_t); //! energy of cluster inducing particle (1 MeV -> Maximum cluster energy of ~65 GeV) + +DECLARE_SOA_DYNAMIC_COLUMN(TrueE, trueE, [](uint16_t storedTrueE) -> float { return storedTrueE / emdownscaling::downscalingFactors[emdownscaling::kEnergy]; }); //! energy of cluster inducing particle (GeV) +} // namespace bcwisemccluster + +DECLARE_SOA_TABLE(BCWiseMCClusters, "AOD", "BCWISEMCCLS", //! table of MC information for clusters -> To be joined with the cluster table + o2::soa::Index<>, BCWiseBCId, bcwisemccluster::Pi0ID, bcwisemccluster::StoredTrueE, + bcwisemccluster::TrueE); + +} // namespace o2::aod + +#endif // PWGEM_PHOTONMESON_DATAMODEL_BCWISETABLES_H_ diff --git a/PWGEM/PhotonMeson/TableProducer/CMakeLists.txt b/PWGEM/PhotonMeson/TableProducer/CMakeLists.txt index ede83862a3f..10266dcb8c2 100644 --- a/PWGEM/PhotonMeson/TableProducer/CMakeLists.txt +++ b/PWGEM/PhotonMeson/TableProducer/CMakeLists.txt @@ -44,6 +44,11 @@ o2physics_add_dpl_workflow(skimmer-gamma-calo PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(bc-wise-cluster-skimmer + SOURCES bcWiseClusterSkimmer.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2::EMCALBase O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(skimmer-phos SOURCES skimmerPHOS.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2::PHOSBase diff --git a/PWGEM/PhotonMeson/TableProducer/bcWiseClusterSkimmer.cxx b/PWGEM/PhotonMeson/TableProducer/bcWiseClusterSkimmer.cxx new file mode 100644 index 00000000000..da9ee8543dc --- /dev/null +++ b/PWGEM/PhotonMeson/TableProducer/bcWiseClusterSkimmer.cxx @@ -0,0 +1,300 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// 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. +/// +/// \file bcWiseClusterSkimmer.cxx +/// +/// \brief This task creates minimalistic skimmed tables containing EMC clusters and centrality information +/// +/// \author Nicolas Strangmann (nicolas.strangmann@cern.ch) - Goethe University Frankfurt +/// + +#include +#include +#include + +#include "Framework/runDataProcessing.h" +#include "Framework/AnalysisTask.h" + +#include "DetectorsBase/GeometryManager.h" +#include "EMCALBase/Geometry.h" + +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Centrality.h" +#include "PWGJE/DataModel/EMCALClusters.h" +#include "PWGEM/PhotonMeson/Utils/MCUtilities.h" +#include "PWGEM/PhotonMeson/DataModel/bcWiseTables.h" + +using namespace o2; +using namespace o2::aod::emdownscaling; +using namespace o2::framework; +using namespace o2::framework::expressions; + +using MyCollisions = soa::Join; +using MyMCCollisions = soa::Join; +using MyBCs = soa::Join; + +using SelectedUniqueClusters = soa::Filtered; // Clusters from collisions with only one collision in the BC +using SelectedUniqueMCClusters = soa::Filtered>; // Clusters from collisions with only one collision in the BC +using SelectedAmbiguousClusters = soa::Filtered; // Clusters from BCs with multiple collisions (no vertex assignment possible) +using SelectedAmbiguousMCClusters = soa::Filtered>; // Clusters from BCs with multiple collisions (no vertex assignment possible) +using SelectedCells = o2::soa::Filtered; + +struct bcWiseClusterSkimmer { + Produces bcTable; + Produces clusterTable; + Produces collisionTable; + Produces mcpi0Table; + Produces mcclusterTable; + + PresliceUnsorted perFoundBC = aod::evsel::foundBCId; + Preslice perCol = aod::emcalcluster::collisionId; + Preslice perBC = aod::emcalcluster::bcId; + Preslice cellsPerBC = aod::calo::bcId; + + Configurable cfgMinClusterEnergy{"cfgMinClusterEnergy", 0.5, "Minimum energy of selected clusters (GeV)"}; + Configurable cfgMaxClusterEnergy{"cfgMaxClusterEnergy", 30., "Maximum energy of selected clusters (GeV)"}; + Configurable cfgMinM02{"cfgMinM02", -1., "Minimum M02 of selected clusters"}; + Configurable cfgMaxM02{"cfgMaxM02", 5., "Maximum M02 of selected clusters"}; + Configurable cfgMinTime{"cfgMinTime", -25, "Minimum time of selected clusters (ns)"}; + Configurable cfgMaxTime{"cfgMaxTime", 25, "Maximum time of selected clusters (ns)"}; + Configurable cfgRapidityCut{"cfgRapidityCut", 0.8f, "Maximum absolute rapidity of counted generated particles"}; + Configurable cfgMinPtGenPi0{"cfgMinPtGenPi0", 0., "Minimum pT for stored generated pi0s (reduce disk space of derived data)"}; + + Configurable cfgRequirekTVXinEMC{"cfgRequirekTVXinEMC", false, "Only store kTVXinEMC triggered BCs"}; + Configurable cfgRequireGoodRCTQuality{"cfgRequireGoodRCTQuality", false, "Only store BCs with good quality of T0 and EMC in RCT"}; + + aod::rctsel::RCTFlagsChecker isFT0EMCGoodRCTChecker{aod::rctsel::kFT0Bad, aod::rctsel::kEMCBad}; + + Filter energyFilter = (aod::emcalcluster::energy > cfgMinClusterEnergy && aod::emcalcluster::energy < cfgMaxClusterEnergy); + Filter m02Filter = (aod::emcalcluster::nCells == 1 || (aod::emcalcluster::m02 > cfgMinM02 && aod::emcalcluster::m02 < cfgMaxM02)); + Filter timeFilter = (aod::emcalcluster::time > cfgMinTime && aod::emcalcluster::time < cfgMaxTime); + Filter emccellFilter = aod::calo::caloType == 1; + + HistogramRegistry mHistManager{"output", {}, OutputObjHandlingPolicy::AnalysisObject, false, false}; + + std::map fMapPi0Index; // Map to connect the MC index of the pi0 to the one saved in the derived table + + void init(framework::InitContext&) + { + const int nEventBins = 6; + mHistManager.add("nBCs", "Number of BCs;;#bf{#it{N}_{BCs}}", HistType::kTH1F, {{nEventBins, -0.5, 5.5}}); + const TString binLabels[nEventBins] = {"All", "FT0", "TVX", "kTVXinEMC", "Cell", "NoBorder"}; + for (int iBin = 0; iBin < nEventBins; iBin++) + mHistManager.get(HIST("nBCs"))->GetXaxis()->SetBinLabel(iBin + 1, binLabels[iBin]); + + LOG(info) << "BC wise cluster skimmer cuts:"; + LOG(info) << "------------------------------------"; + LOG(info) << "| Timing cut: " << cfgMinTime << " < t < " << cfgMaxTime; + LOG(info) << "| Shape cut: " << cfgMinM02 << " < M02 < " << cfgMaxM02; + LOG(info) << "| Energy cut: " << cfgMinClusterEnergy << " < E < " << cfgMaxClusterEnergy; + LOG(info) << "| Rapidity cut: |y| < " << cfgRapidityCut; + LOG(info) << "| Min gen pi0 pt: pT > " << cfgMinPtGenPi0; + + o2::emcal::Geometry::GetInstanceFromRunNumber(300000); + if (cfgRequireGoodRCTQuality) + isFT0EMCGoodRCTChecker.init({aod::rctsel::kFT0Bad, aod::rctsel::kEMCBad}); + } + + /// \brief Process EMCAL clusters (either ambigous or unique) + template + OutputType convertForStorage(InputType const& valueIn, Observables observable) + { + double valueToBeChecked = valueIn * downscalingFactors[observable]; + if (valueToBeChecked < std::numeric_limits::lowest()) { + LOG(warning) << "Value " << valueToBeChecked << " of observable " << observable << " below lowest possible value of " << typeid(OutputType).name() << ": " << static_cast(std::numeric_limits::lowest()); + valueToBeChecked = static_cast(std::numeric_limits::lowest()); + } + if (valueToBeChecked > std::numeric_limits::max()) { + LOG(warning) << "Value " << valueToBeChecked << " of observable " << observable << " obove highest possible value of " << typeid(OutputType).name() << ": " << static_cast(std::numeric_limits::max()); + valueToBeChecked = static_cast(std::numeric_limits::max()); + } + + return static_cast(valueToBeChecked); + } + + /// \brief Process EMCAL clusters (either ambigous or unique) + template + void processClusters(Clusters const& clusters, const int bcID) + { + for (const auto& cluster : clusters) { + clusterTable(bcID, + convertForStorage(cluster.definition(), kDefinition), + convertForStorage(cluster.energy(), kEnergy), + convertForStorage(cluster.eta(), kEta), + convertForStorage(cluster.phi(), kPhi), + convertForStorage(cluster.nCells(), kNCells), + convertForStorage(cluster.m02(), kM02), + convertForStorage(cluster.time(), kTime), + cluster.isExotic()); + } + } + + template + void processClusterMCInfo(Clusters const& clusters, const int bcID, aod::McParticles const& mcParticles) + { + for (const auto& cluster : clusters) { + float clusterInducerEnergy = 0.; + int32_t pi0MCIndex = -1; + if (cluster.amplitudeA().size() > 0) { + int clusterInducerId = cluster.mcParticleIds()[0]; + auto clusterInducer = mcParticles.iteratorAt(clusterInducerId); + clusterInducerEnergy = clusterInducer.e(); + int daughterId = aod::pwgem::photonmeson::utils::mcutil::FindMotherInChain(clusterInducer, mcParticles, std::vector{111}); + if (daughterId > 0) { + pi0MCIndex = mcParticles.iteratorAt(daughterId).mothersIds()[0]; + if (mcParticles.iteratorAt(pi0MCIndex).pt() < cfgMinPtGenPi0) + pi0MCIndex = -1; + } + } + if (pi0MCIndex >= 0) { + if (fMapPi0Index.find(pi0MCIndex) != fMapPi0Index.end()) // Some pi0s might not be found (not gg decay or too large y) + pi0MCIndex = fMapPi0Index[pi0MCIndex]; // If pi0 was stored in table, change index from the MC index to the pi0 index from this task + else // If pi0 was not stored, treat photon as if not from pi0 + pi0MCIndex = -1; + } + mcclusterTable(bcID, pi0MCIndex, convertForStorage(clusterInducerEnergy, kEnergy)); + } + } + + bool isBCSelected(const auto& bc) + { + if (cfgRequirekTVXinEMC && !bc.selection_bit(aod::evsel::kIsTriggerTVX)) + return false; + if (cfgRequireGoodRCTQuality && !isFT0EMCGoodRCTChecker(bc)) + return false; + return true; + } + + void processEventProperties(const auto& bc, const auto& collisionsInBC, const auto& cellsInBC) + { + bool hasFT0 = bc.has_foundFT0(); + bool hasTVX = bc.selection_bit(aod::evsel::kIsTriggerTVX); + bool haskTVXinEMC = bc.alias_bit(kTVXinEMC); + bool hasEMCCell = cellsInBC.size() > 0; + bool hasNoTFROFBorder = bc.selection_bit(aod::evsel::kNoTimeFrameBorder) && bc.selection_bit(aod::evsel::kNoITSROFrameBorder); + mHistManager.fill(HIST("nBCs"), 0); + if (hasFT0) + mHistManager.fill(HIST("nBCs"), 1); + if (hasTVX) + mHistManager.fill(HIST("nBCs"), 2); + if (haskTVXinEMC) + mHistManager.fill(HIST("nBCs"), 3); + if (hasEMCCell) + mHistManager.fill(HIST("nBCs"), 4); + if (hasNoTFROFBorder) + mHistManager.fill(HIST("nBCs"), 5); + + float ft0Amp = hasFT0 ? bc.foundFT0().sumAmpA() + bc.foundFT0().sumAmpC() : 0.; + + bcTable(hasFT0, hasTVX, haskTVXinEMC, hasEMCCell, hasNoTFROFBorder, convertForStorage(ft0Amp, kFT0Amp)); + + for (const auto& collision : collisionsInBC) { + collisionTable(bcTable.lastIndex(), convertForStorage(collision.centFT0M(), kFT0MCent), convertForStorage(collision.posZ(), kZVtx)); + } + } + + template + bool isGammaGammaDecay(TMCParticle mcParticle, TMCParticles mcParticles) + { + auto daughtersIds = mcParticle.daughtersIds(); + if (daughtersIds.size() != 2) + return false; + for (const auto& daughterId : daughtersIds) { + if (mcParticles.iteratorAt(daughterId).pdgCode() != 22) + return false; + } + return true; + } + + template + bool isAccepted(TMCParticle mcParticle, TMCParticles mcParticles) + { + auto daughtersIds = mcParticle.daughtersIds(); + if (daughtersIds.size() != 2) + return false; + for (const auto& daughterId : daughtersIds) { + if (mcParticles.iteratorAt(daughterId).pdgCode() != 22) + return false; + int iCellID = -1; + try { + iCellID = emcal::Geometry::GetInstance()->GetAbsCellIdFromEtaPhi(mcParticles.iteratorAt(daughterId).eta(), mcParticles.iteratorAt(daughterId).phi()); + } catch (emcal::InvalidPositionException& e) { + iCellID = -1; + } + if (iCellID == -1) + return false; + } + return true; + } + + void processData(MyBCs const& bcs, MyCollisions const& collisions, aod::FT0s const&, SelectedCells const& cells, SelectedUniqueClusters const& uClusters, SelectedAmbiguousClusters const& aClusters) + { + for (const auto& bc : bcs) { + if (!isBCSelected(bc)) + continue; + auto collisionsInBC = collisions.sliceBy(perFoundBC, bc.globalIndex()); + auto cellsInBC = cells.sliceBy(cellsPerBC, bc.globalIndex()); + + processEventProperties(bc, collisionsInBC, cellsInBC); + + if (collisionsInBC.size() == 1) { + auto clustersInBC = uClusters.sliceBy(perCol, collisionsInBC.begin().globalIndex()); + processClusters(clustersInBC, bcTable.lastIndex()); + } else { + auto clustersInBC = aClusters.sliceBy(perBC, bc.globalIndex()); + processClusters(clustersInBC, bcTable.lastIndex()); + } + } + } + PROCESS_SWITCH(bcWiseClusterSkimmer, processData, "Run skimming for data", true); + + Preslice mcCollperBC = aod::mccollision::bcId; + Preslice perMcCollision = aod::mcparticle::mcCollisionId; + + void processMC(MyBCs const& bcs, MyMCCollisions const& collisions, aod::McCollisions const& mcCollisions, aod::FT0s const&, SelectedCells const& cells, SelectedUniqueMCClusters const& uClusters, SelectedAmbiguousMCClusters const& aClusters, aod::McParticles const& mcParticles) + { + for (const auto& bc : bcs) { + if (!isBCSelected(bc)) + continue; + auto collisionsInBC = collisions.sliceBy(perFoundBC, bc.globalIndex()); + auto cellsInBC = cells.sliceBy(cellsPerBC, bc.globalIndex()); + + processEventProperties(bc, collisionsInBC, cellsInBC); + + auto mcCollisionsBC = mcCollisions.sliceBy(mcCollperBC, bc.globalIndex()); + for (const auto& mcCollision : mcCollisionsBC) { + auto mcParticlesInColl = mcParticles.sliceBy(perMcCollision, mcCollision.globalIndex()); + for (const auto& mcParticle : mcParticlesInColl) { + if (mcParticle.pdgCode() != 111 || std::abs(mcParticle.y()) > cfgRapidityCut || !isGammaGammaDecay(mcParticle, mcParticles) || mcParticle.pt() < cfgMinPtGenPi0) + continue; + bool isPrimary = mcParticle.isPhysicalPrimary() || mcParticle.producedByGenerator(); + bool isFromWD = (aod::pwgem::photonmeson::utils::mcutil::IsFromWD(mcCollision, mcParticle, mcParticles)) > 0; + mcpi0Table(bc.globalIndex(), convertForStorage(mcParticle.pt(), kpT), isAccepted(mcParticle, mcParticles), isPrimary, isFromWD); + fMapPi0Index[mcParticle.globalIndex()] = static_cast(mcpi0Table.lastIndex()); + } + } + + if (collisionsInBC.size() == 1) { + auto clustersInBC = uClusters.sliceBy(perCol, collisionsInBC.begin().globalIndex()); + processClusters(clustersInBC, bcTable.lastIndex()); + processClusterMCInfo(clustersInBC, bc.globalIndex(), mcParticles); + } else { + auto clustersInBC = aClusters.sliceBy(perBC, bc.globalIndex()); + processClusters(clustersInBC, bcTable.lastIndex()); + processClusterMCInfo(clustersInBC, bc.globalIndex(), mcParticles); + } + fMapPi0Index.clear(); + } + } + PROCESS_SWITCH(bcWiseClusterSkimmer, processMC, "Run skimming for MC", false); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{adaptAnalysisTask(cfgc)}; } diff --git a/PWGEM/PhotonMeson/Tasks/CMakeLists.txt b/PWGEM/PhotonMeson/Tasks/CMakeLists.txt index ef25948726c..975a217fab7 100644 --- a/PWGEM/PhotonMeson/Tasks/CMakeLists.txt +++ b/PWGEM/PhotonMeson/Tasks/CMakeLists.txt @@ -24,6 +24,11 @@ o2physics_add_dpl_workflow(emc-pi0-qc PUBLIC_LINK_LIBRARIES O2::Framework O2::EMCALBase O2::EMCALCalib O2Physics::AnalysisCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(emc-bc-wise-pi0 + SOURCES emcalBcWisePi0.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2::EMCALBase O2::EMCALCalib O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(pcm-qc SOURCES pcmQC.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2::DetectorsBase O2Physics::AnalysisCore O2Physics::PWGEMPhotonMesonCore diff --git a/PWGEM/PhotonMeson/Tasks/HeavyNeutralMeson.cxx b/PWGEM/PhotonMeson/Tasks/HeavyNeutralMeson.cxx index 98e620e413b..b416f173480 100644 --- a/PWGEM/PhotonMeson/Tasks/HeavyNeutralMeson.cxx +++ b/PWGEM/PhotonMeson/Tasks/HeavyNeutralMeson.cxx @@ -17,7 +17,6 @@ /// #include -#include #include #include @@ -27,6 +26,7 @@ #include "TRandom3.h" #include "PWGEM/PhotonMeson/Utils/HNMUtilities.h" +#include "PWGJE/DataModel/EMCALMatchedCollisions.h" #include "Common/DataModel/PIDResponse.h" #include "Common/DataModel/PIDResponseITS.h" @@ -51,14 +51,14 @@ using namespace o2::aod::pwgem::photonmeson; namespace o2::aod { using MyBCs = soa::Join; -using MyCollisions = soa::Join; +using MyCollisions = soa::Join; using MyCollision = MyCollisions::iterator; using SelectedTracks = soa::Join; } // namespace o2::aod -namespace HNMPID +namespace hnm { enum TracksPID { @@ -74,91 +74,110 @@ enum PIDLimits { kTPCMin, kNPIDLimits }; -const std::vector SpeciesName{"pion"}; // ToDo include charged pions -const std::vector PtCutsName{"Pt min", "Pt max", "P TOF thres"}; -const std::vector PidCutsName{"TPC min", "TPC max", "TPCTOF max", "ITS min", "ITS max"}; +const std::vector speciesName{"pion"}; // ToDo include charged pions +const std::vector pTCutsName{"Pt min", "Pt max", "P TOF thres"}; +const std::vector pidCutsName{"TPC min", "TPC max", "TPCTOF max", "ITS min", "ITS max"}; const float pidcutsTable[kNTracksPID][kNPIDLimits]{{-4.f, 4.f, 4.f, -99.f, 99.f}}; const float ptcutsTable[kNTracksPID][3]{{0.35f, 6.f, 0.75f}}; -const float TPCNClustersMin[1][kNTracksPID]{{80.0f}}; -const float ITSNClustersMin[1][kNTracksPID]{{4}}; +const float nClusterMinTPC[1][kNTracksPID]{{80.0f}}; +const float nClusterMinITS[1][kNTracksPID]{{4}}; -} // namespace HNMPID +} // namespace hnm struct HeavyNeutralMeson { - // PID selections - Configurable> ConfPIDCuts{"ConfPIDCuts", {HNMPID::pidcutsTable[0], HNMPID::kNTracksPID, HNMPID::kNPIDLimits, HNMPID::SpeciesName, HNMPID::PidCutsName}, "Heavy Neutral Meson PID nsigma selections"}; - Configurable> ConfPtCuts{"ConfPtCuts", {HNMPID::ptcutsTable[0], HNMPID::kNTracksPID, 3, HNMPID::SpeciesName, HNMPID::PtCutsName}, "Heavy Neutral Meson pT selections"}; - Configurable ConfTrkEta{"ConfTrkEta", 0.9, "Eta"}; - Configurable> ConfTPCNClustersMin{"ConfTPCNClustersMin", {HNMPID::TPCNClustersMin[0], 1, HNMPID::kNTracksPID, std::vector{"TPCNClusMin"}, HNMPID::SpeciesName}, "Mininum of TPC Clusters"}; - Configurable ConfTrkTPCfCls{"ConfTrkTPCfCls", 0.83, "Minimum fraction of crossed rows over findable clusters"}; - Configurable ConfTrkTPCcRowsMin{"ConfTrkTPCcRowsMin", 70, "Minimum number of crossed TPC rows"}; - Configurable ConfTrkTPCsClsSharedFrac{"ConfTrkTPCsClsSharedFrac", 1.f, "Fraction of shared TPC clusters"}; - Configurable> ConfTrkITSnclsMin{"ConfTrkITSnclsMin", {HNMPID::ITSNClustersMin[0], 1, HNMPID::kNTracksPID, std::vector{"Cut"}, HNMPID::SpeciesName}, "Minimum number of ITS clusters"}; - Configurable ConfTrkDCAxyMax{"ConfTrkDCAxyMax", 0.15, "Maximum DCA_xy"}; - Configurable ConfTrkDCAzMax{"ConfTrkDCAzMax", 0.3, "Maximum DCA_z"}; - Configurable ConfTrkMaxChi2PerClusterTPC{"ConfTrkMaxChi2PerClusterTPC", 4.0f, "Minimal track selection: max allowed chi2 per TPC cluster"}; // 4.0 is default of global tracks on 20.01.2023 - Configurable ConfTrkMaxChi2PerClusterITS{"ConfTrkMaxChi2PerClusterITS", 36.0f, "Minimal track selection: max allowed chi2 per ITS cluster"}; // 36.0 is default of global tracks on 20.01.2023 - Configurable ConfEvtSelectZvtx{"ConfEvtSelectZvtx", true, "Event selection includes max. z-Vertex"}; - Configurable ConfEvtZvtx{"ConfEvtZvtx", 10.f, "Evt sel: Max. z-Vertex (cm)"}; - Configurable ConfEvtOfflineCheck{"ConfEvtOfflineCheck", false, "Evt sel: check for offline selection"}; + // --------------------------------> Configurables <------------------------------------ + // - Event selection cuts + // - Track selection cuts + // - Cluster shifts + // - HNM mass selection windows + // ------------------------------------------------------------------------------------- + // ---> Event selection + Configurable confEvtSelectZvtx{"confEvtSelectZvtx", true, "Event selection includes max. z-Vertex"}; + Configurable confEvtZvtx{"confEvtZvtx", 10.f, "Evt sel: Max. z-Vertex (cm)"}; + Configurable confEvtRequireSel8{"confEvtRequireSel8", false, "Evt sel: check for offline selection (sel8)"}; + + // ---> Track selection + Configurable> cfgPtCuts{"cfgPtCuts", {hnm::ptcutsTable[0], 1, 3, hnm::speciesName, hnm::pTCutsName}, "Track pT selections"}; + Configurable cfgTrkEta{"cfgTrkEta", 0.9, "Eta"}; + Configurable> cfgTPCNClustersMin{"cfgTPCNClustersMin", {hnm::nClusterMinTPC[0], 1, 1, std::vector{"TPCNClusMin"}, hnm::speciesName}, "Mininum of TPC Clusters"}; + Configurable cfgTrkTPCfCls{"cfgTrkTPCfCls", 0.83, "Minimum fraction of crossed rows over findable clusters"}; + Configurable cfgTrkTPCcRowsMin{"cfgTrkTPCcRowsMin", 70, "Minimum number of crossed TPC rows"}; + Configurable cfgTrkTPCsClsSharedFrac{"cfgTrkTPCsClsSharedFrac", 1.f, "Fraction of shared TPC clusters"}; + Configurable> cfgTrkITSnclsMin{"cfgTrkITSnclsMin", {hnm::nClusterMinITS[0], 1, 1, std::vector{"Cut"}, hnm::speciesName}, "Minimum number of ITS clusters"}; + Configurable cfgTrkDCAxyMax{"cfgTrkDCAxyMax", 0.15, "Maximum DCA_xy"}; + Configurable cfgTrkDCAzMax{"cfgTrkDCAzMax", 0.3, "Maximum DCA_z"}; + Configurable cfgTrkMaxChi2PerClusterTPC{"cfgTrkMaxChi2PerClusterTPC", 4.0f, "Minimal track selection: max allowed chi2 per TPC cluster"}; // 4.0 is default of global tracks on 20.01.2023 + Configurable cfgTrkMaxChi2PerClusterITS{"cfgTrkMaxChi2PerClusterITS", 36.0f, "Minimal track selection: max allowed chi2 per ITS cluster"}; // 36.0 is default of global tracks on 20.01.2023 + + Configurable> cfgPIDCuts{"cfgPIDCuts", {hnm::pidcutsTable[0], 1, hnm::kNPIDLimits, hnm::speciesName, hnm::pidCutsName}, "Femtopartner PID nsigma selections"}; // PID selections + + // ---> Configurables to allow for a shift in eta/phi of EMCal clusters to better align with extrapolated TPC tracks + Configurable cfgDoEMCShift{"cfgDoEMCShift", false, "Apply SM-wise shift in eta and phi to EMCal clusters to align with TPC tracks"}; + Configurable> cfgEMCEtaShift{"cfgEMCEtaShift", {0.f}, "values for SM-wise shift in eta to be added to EMCal clusters to align with TPC tracks"}; + Configurable> cfgEMCPhiShift{"cfgEMCPhiShift", {0.f}, "values for SM-wise shift in phi to be added to EMCal clusters to align with TPC tracks"}; + static const int nSMs = 20; + std::array emcEtaShift = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + std::array emcPhiShift = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + + // ---> Shift the omega/eta' mass based on the difference of the reconstructed mass of the pi0/eta to its PDG mass to reduce smearing caused by EMCal/PCM in photon measurement Configurable cfgHNMMassCorrection{"cfgHNMMassCorrection", 1, "Use GG PDG mass to correct HNM mass (0 = off, 1 = subDeltaPi0, 2 = subLambda)"}; - static constexpr float defaultMassWindows[4] = {0.1, 0.17, 0.5, 6.}; - Configurable> massWindowLightNeutralMesons{"massWindowLightNeutralMesons", {defaultMassWindows, 4, {"pi0_min", "pi0_max", "eta_min", "eta_max"}}, "Mass window for selected light neutral meson decay daughters"}; - Configurable ConfDoEMCShift{"ConfDoEMCShift", false, "Apply SM-wise shift in eta and phi to EMCal clusters to align with TPC tracks"}; - Configurable> ConfEMCEtaShift{"ConfEMCEtaShift", {0.f}, "values for SM-wise shift in eta to be added to EMCal clusters to align with TPC tracks"}; - Configurable> ConfEMCPhiShift{"ConfEMCPhiShift", {0.f}, "values for SM-wise shift in phi to be added to EMCal clusters to align with TPC tracks"}; - std::array EMCEtaShift = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - std::array EMCPhiShift = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + + // ---> Mass windows for the selection of heavy neutral mesons (also based on mass of their light neutral meson decay daughter) + static constexpr float DefaultMassWindows[2][4] = {{0., 0.4, 0.6, 1.}, {0.4, 0.8, 0.8, 1.2}}; + Configurable> cfgMassWindowOmega{"cfgMassWindowOmega", {DefaultMassWindows[0], 4, {"pi0_min", "pi0_max", "omega_min", "omega_max"}}, "Mass window for selected omegas and their decay pi0"}; + Configurable> cfgMassWindowEtaPrime{"cfgMassWindowEtaPrime", {DefaultMassWindows[1], 4, {"eta_min", "eta_max", "etaprime_min", "etaprime_max"}}, "Mass window for selected eta' and their decay eta"}; + + Configurable cfgMaxMultiplicity{"cfgMaxMultiplicity", 5000, "Maximum number of tracks in a collision (can be used to increase the S/B -> Very experimental)"}; + Configurable cfgMinGGPtOverHNMPt{"cfgMinGGPtOverHNMPt", 0., "Minimum ratio of the pT of the gamma gamma pair over the pT of the HNM (can be used to increase the S/B)"}; + + HistogramRegistry mHistManager{"HeavyNeutralMesonHistograms", {}, OutputObjHandlingPolicy::AnalysisObject}; + + // Prepare vectors for different species + std::vector vGGs; + std::vector vHNMs; + std::vector etaPrimeEMC, etaPrimePCM, omegaEMC, omegaPCM, proton, antiproton, deuteron, antideuteron, pion, antipion; + float mMassProton = constants::physics::MassProton; + float mMassDeuteron = constants::physics::MassDeuteron; + float mMassOmega = 0.782; + float mMassEtaPrime = 0.957; + float mMassPionCharged = constants::physics::MassPionCharged; + + Preslice perCollisionPCM = aod::v0photonkf::collisionId; + Preslice perCollisionEMC = aod::skimmedcluster::collisionId; template - bool isSelectedTrack(T const& track, HNMPID::TracksPID partSpecies) + bool isSelectedTrack(T const& track, hnm::TracksPID partSpecies) { - const auto pT = track.pt(); - const auto eta = track.eta(); - const auto tpcNClsF = track.tpcNClsFound(); - const auto tpcRClsC = track.tpcCrossedRowsOverFindableCls(); - const auto tpcNClsC = track.tpcNClsCrossedRows(); - const auto tpcNClsSFrac = track.tpcFractionSharedCls(); - const auto itsNCls = track.itsNCls(); - const auto dcaXY = track.dcaXY(); - const auto dcaZ = track.dcaZ(); - - if (pT < ConfPtCuts->get(partSpecies, "Pt min")) { + if (track.pt() < cfgPtCuts->get(partSpecies, "Pt min")) return false; - } - if (pT > ConfPtCuts->get(partSpecies, "Pt max")) { + if (track.pt() > cfgPtCuts->get(partSpecies, "Pt max")) return false; - } - if (std::abs(eta) > ConfTrkEta) { + if (std::abs(track.eta()) > cfgTrkEta) return false; - } - if (tpcNClsF < ConfTPCNClustersMin->get("TPCNClusMin", partSpecies)) { + if (track.tpcNClsFound() < cfgTPCNClustersMin->get("TPCNClusMin", partSpecies)) return false; - } - if (tpcRClsC < ConfTrkTPCfCls) { + if (track.tpcCrossedRowsOverFindableCls() < cfgTrkTPCfCls) return false; - } - if (tpcNClsC < ConfTrkTPCcRowsMin) { + if (track.tpcNClsCrossedRows() < cfgTrkTPCcRowsMin) return false; - } - if (tpcNClsSFrac > ConfTrkTPCsClsSharedFrac) { + if (track.tpcFractionSharedCls() > cfgTrkTPCsClsSharedFrac) return false; - } - if (itsNCls < ConfTrkITSnclsMin->get(static_cast(0), partSpecies)) { + if (track.itsNCls() < cfgTrkITSnclsMin->get(static_cast(0), partSpecies)) return false; - } - if (std::abs(dcaXY) > ConfTrkDCAxyMax) { + if (std::abs(track.dcaXY()) > cfgTrkDCAxyMax) return false; - } - if (std::abs(dcaZ) > ConfTrkDCAzMax) { + if (std::abs(track.dcaZ()) > cfgTrkDCAzMax) + return false; + if (track.tpcChi2NCl() > cfgTrkMaxChi2PerClusterTPC) + return false; + if (track.itsChi2NCl() > cfgTrkMaxChi2PerClusterITS) return false; - } return true; } template - bool isSelectedTrackPID(T const& track, HNMPID::TracksPID partSpecies) + bool isSelectedTrackPID(T const& track, hnm::TracksPID partSpecies) { bool isSelected = false; @@ -168,22 +187,15 @@ struct HeavyNeutralMeson { float nSigmaTrackTPCTOF = std::sqrt(std::pow(nSigmaTrackTPC, 2) + std::pow(nSigmaTrackTOF, 2)); - // check if track is selected - auto TPCmin = ConfPIDCuts->get(partSpecies, HNMPID::kTPCMin); - auto TPCmax = ConfPIDCuts->get(partSpecies, HNMPID::kTPCMax); - auto TPCTOFmax = ConfPIDCuts->get(partSpecies, HNMPID::kTPCTOF); - auto ITSmin = ConfPIDCuts->get(partSpecies, HNMPID::kITSmin); - auto ITSmax = ConfPIDCuts->get(partSpecies, HNMPID::kITSmax); - - if (track.p() <= ConfPtCuts->get(partSpecies, "P TOF thres")) { - if (nSigmaTrackTPC > TPCmin && - nSigmaTrackTPC < TPCmax && - nSigmaTrackITS > ITSmin && - nSigmaTrackITS < ITSmax) { + if (track.p() <= cfgPtCuts->get(partSpecies, "P TOF thres")) { + if (nSigmaTrackTPC > cfgPIDCuts->get(partSpecies, hnm::kTPCMin) && + nSigmaTrackTPC < cfgPIDCuts->get(partSpecies, hnm::kTPCMax) && + nSigmaTrackITS > cfgPIDCuts->get(partSpecies, hnm::kITSmin) && + nSigmaTrackITS < cfgPIDCuts->get(partSpecies, hnm::kITSmax)) { isSelected = true; } } else { - if (nSigmaTrackTPCTOF < TPCTOFmax) { + if (nSigmaTrackTPCTOF < cfgPIDCuts->get(partSpecies, hnm::kTPCTOF)) { isSelected = true; } } @@ -193,324 +205,292 @@ struct HeavyNeutralMeson { template bool isSelectedEvent(T const& col) { - if (ConfEvtSelectZvtx && std::abs(col.posZ()) > ConfEvtZvtx) { + if (confEvtSelectZvtx && std::abs(col.posZ()) > confEvtZvtx) { return false; } - if (ConfEvtOfflineCheck && !col.sel8()) { + if (confEvtRequireSel8 && !col.sel8()) { return false; } - return true; - } - - // Circumvent missing of different phi mappings, enforce [0, 2 * M_PI] - // Tracks have domain [0, 2 * M_PI] - // TLorentVectors have domain [-M_PI, M_PI] - double translatePhi(double phi) - { - if (phi < 0) { - phi += 2 * M_PI; // Add 2 pi to make it positive + if (col.multNTracksPV() > cfgMaxMultiplicity) { + return false; } - return phi; + return true; } - HistogramRegistry mHistManager{"HeavyNeutralMesonHistograms", {}, OutputObjHandlingPolicy::AnalysisObject}; - - std::vector vGGs; - std::vector vHNMs; - - emcal::Geometry* emcalGeom; - - // Prepare vectors for different species - std::vector pion, antipion; - void init(InitContext const&) { - emcalGeom = emcal::Geometry::GetInstanceFromRunNumber(300000); - auto hCollisionCounter = mHistManager.add("Event/hCollisionCounter", "Number of collisions;;#bf{#it{N}_{Coll}}", HistType::kTH1F, {{6, -0.5, 5.5}}); - hCollisionCounter->GetXaxis()->SetBinLabel(1, "all"); - hCollisionCounter->GetXaxis()->SetBinLabel(2, "kTVXinEMC"); - hCollisionCounter->GetXaxis()->SetBinLabel(3, "PCM #omega"); - hCollisionCounter->GetXaxis()->SetBinLabel(4, "EMC #omega"); - hCollisionCounter->GetXaxis()->SetBinLabel(5, "PCM #eta'"); - hCollisionCounter->GetXaxis()->SetBinLabel(6, "EMC #eta'"); - mHistManager.add("Event/nGGs", "Number of (selected) #gamma#gamma paris;#bf{#it{N}_{#gamma#gamma}};#bf{#it{N}_{#gamma#gamma}^{selected}}", HistType::kTH2F, {{51, -0.5, 50.5}, {51, -0.5, 50.5}}); - mHistManager.add("Event/nTracks", "Number of tracks;#bf{N_{tracks}};#bf{#it{N}_{Coll}}", HistType::kTH1F, {{51, -0.5, 50.5}}); mHistManager.add("Event/nHeavyNeutralMesons", "Number of (selected) HNM candidates;#bf{#it{N}_{HNM}};#bf{#it{N}_{HNM}^{selected}}", HistType::kTH2F, {{51, -0.5, 50.5}, {51, -0.5, 50.5}}); mHistManager.add("Event/nClustersVsV0s", "Number of clusters and V0s in the collision;#bf{#it{N}_{clusters}};#bf{#it{N}_{V0s}}", HistType::kTH2F, {{26, -0.5, 25.5}, {26, -0.5, 25.5}}); + mHistManager.add("Event/nEMCalEvents", "Number of collisions with a certain combination of EMCal triggers;;#bf{#it{N}_{collisions}}", HistType::kTH1F, {{5, -0.5, 4.5}}); + std::vector nEventTitles = {"Cells & kTVXinEMC", "Cells & L0", "Cells & !kTVXinEMC & !L0", "!Cells & kTVXinEMC", "!Cells & L0"}; + for (size_t iBin = 0; iBin < nEventTitles.size(); iBin++) + mHistManager.get(HIST("Event/nEMCalEvents"))->GetXaxis()->SetBinLabel(iBin + 1, nEventTitles[iBin].data()); + mHistManager.add("Event/fMultiplicityBefore", "Multiplicity of all processed events;#bf{#it{N}_{tracks}};#bf{#it{N}_{collisions}}", HistType::kTH1F, {{500, 0, 500}}); + mHistManager.add("Event/fMultiplicityAfter", "Multiplicity after event cuts;#bf{#it{N}_{tracks}};#bf{#it{N}_{collisions}}", HistType::kTH1F, {{500, 0, 500}}); + mHistManager.add("Event/fZvtxBefore", "Zvtx of all processed events;#bf{z_{vtx} (cm)};#bf{#it{N}_{collisions}}", HistType::kTH1F, {{500, -15, 15}}); + mHistManager.add("Event/fZvtxAfter", "Zvtx after event cuts;#bf{z_{vtx} (cm)};#bf{#it{N}_{collisions}}", HistType::kTH1F, {{500, -15, 15}}); mHistManager.add("GG/invMassVsPt_PCM", "Invariant mass and pT of gg candidates;#bf{#it{M}_{#gamma#gamma}};#bf{#it{pT}_{#gamma#gamma}}", HistType::kTH2F, {{400, 0., 0.8}, {250, 0., 25.}}); mHistManager.add("GG/invMassVsPt_PCMEMC", "Invariant mass and pT of gg candidates;#bf{#it{M}_{#gamma#gamma}};#bf{#it{pT}_{#gamma#gamma}}", HistType::kTH2F, {{400, 0., 0.8}, {250, 0., 25.}}); mHistManager.add("GG/invMassVsPt_EMC", "Invariant mass and pT of gg candidates;#bf{#it{M}_{#gamma#gamma}};#bf{#it{pT}_{#gamma#gamma}}", HistType::kTH2F, {{400, 0., 0.8}, {250, 0., 25.}}); - mHistManager.add("Omega/invMassVsPt_PCM", "Invariant mass and pT of omega meson candidates;#bf{#it{M}_{#pi^{+}#pi^{-}#gamma#gamma}};#bf{#it{pT}_{#pi^{+}#pi^{-}#gamma#gamma}}", HistType::kTH2F, {{400, 0.6, 1.}, {250, 0., 25.}}); - mHistManager.add("Omega/invMassVsPt_PCMEMC", "Invariant mass and pT of omega meson candidates;#bf{#it{M}_{#pi^{+}#pi^{-}#gamma#gamma}};#bf{#it{pT}_{#pi^{+}#pi^{-}#gamma#gamma}}", HistType::kTH2F, {{400, 0.6, 1.}, {250, 0., 25.}}); - mHistManager.add("Omega/invMassVsPt_EMC", "Invariant mass and pT of omega meson candidates;#bf{#it{M}_{#pi^{+}#pi^{-}#gamma#gamma}};#bf{#it{pT}_{#pi^{+}#pi^{-}#gamma#gamma}}", HistType::kTH2F, {{400, 0.6, 1.}, {250, 0., 25.}}); - - mHistManager.add("EtaPrime/invMassVsPt_PCM", "Invariant mass and pT of eta' candidates;#bf{#it{M}_{#pi^{+}#pi^{-}#gamma#gamma}};#bf{#it{pT}_{#pi^{+}#pi^{-}#gamma#gamma}}", HistType::kTH2F, {{400, 0.8, 1.2}, {250, 0., 25.}}); - mHistManager.add("EtaPrime/invMassVsPt_PCMEMC", "Invariant mass and pT of eta' candidates;#bf{#it{M}_{#pi^{+}#pi^{-}#gamma#gamma}};#bf{#it{pT}_{#pi^{+}#pi^{-}#gamma#gamma}}", HistType::kTH2F, {{400, 0.8, 1.2}, {250, 0., 25.}}); - mHistManager.add("EtaPrime/invMassVsPt_EMC", "Invariant mass and pT of eta' candidates;#bf{#it{M}_{#pi^{+}#pi^{-}#gamma#gamma}};#bf{#it{pT}_{#pi^{+}#pi^{-}#gamma#gamma}}", HistType::kTH2F, {{400, 0.8, 1.2}, {250, 0., 25.}}); + // Momentum correlations p vs p_TPC + mHistManager.add("TrackCuts/TracksBefore/fMomCorrelationPos", "fMomCorrelation;#bf{#it{p} (GeV/#it{c})};#bf{#it{p}_{TPC} (GeV/#it{c})}", {HistType::kTH2F, {{500, 0.0f, 20.0f}, {500, 0.0f, 20.0f}}}); + mHistManager.add("TrackCuts/TracksBefore/fMomCorrelationNeg", "fMomCorrelation;#bf{#it{p} (GeV/#it{c})};#bf{#it{p}_{TPC} (GeV/#it{c})}", {HistType::kTH2F, {{500, 0.0f, 20.0f}, {500, 0.0f, 20.0f}}}); - // event cuts - mHistManager.add("EventCuts/fMultiplicityBefore", "Multiplicity of all processed events;Mult;Entries", HistType::kTH1F, {{500, 0, 500}}); - mHistManager.add("EventCuts/fMultiplicityAfter", "Multiplicity after event cuts;Mult;Entries", HistType::kTH1F, {{500, 0, 500}}); - mHistManager.add("EventCuts/fZvtxBefore", "Zvtx of all processed events;Z_{vtx};Entries", HistType::kTH1F, {{500, -15, 15}}); - mHistManager.add("EventCuts/fZvtxAfter", "Zvtx after event cuts;Z_{vtx};Entries", HistType::kTH1F, {{500, -15, 15}}); - - // mom correlations p vs pTPC - mHistManager.add("TrackCuts/TracksBefore/fMomCorrelationPos", "fMomCorrelation;p (GeV/c);p_{TPC} (GeV/c)", {HistType::kTH2F, {{500, 0.0f, 20.0f}, {500, 0.0f, 20.0f}}}); - mHistManager.add("TrackCuts/TracksBefore/fMomCorrelationNeg", "fMomCorrelation;p (GeV/c);p_{TPC} (GeV/c)", {HistType::kTH2F, {{500, 0.0f, 20.0f}, {500, 0.0f, 20.0f}}}); - - mHistManager.add("TrackCuts/TracksBefore/fMomCorrelationAfterCutsPion", "fMomCorrelation;p (GeV/c);p_{TPC} (GeV/c)", {HistType::kTH2F, {{1000, 0.0f, 20.0f}, {1000, 0.0f, 20.0f}}}); - mHistManager.add("TrackCuts/TracksBefore/fMomCorrelationAfterCutsAntiPion", "fMomCorrelation;p (GeV/c);p_{TPC} (GeV/c)", {HistType::kTH2F, {{1000, 0.0f, 20.0f}, {1000, 0.0f, 20.0f}}}); - - // all tracks - mHistManager.add("TrackCuts/TracksBefore/fPtTrackBefore", "Transverse momentum of all processed tracks;p_{T} (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - mHistManager.add("TrackCuts/TracksBefore/fEtaTrackBefore", "Pseudorapidity of all processed tracks;#eta;Entries", HistType::kTH1F, {{500, -2, 2}}); - mHistManager.add("TrackCuts/TracksBefore/fPhiTrackBefore", "Azimuthal angle of all processed tracks;#phi;Entries", HistType::kTH1F, {{720, 0, TMath::TwoPi()}}); + // All tracks + mHistManager.add("TrackCuts/TracksBefore/fPtTrackBefore", "Transverse momentum of all processed tracks;#bf{#it{p}_{T} (GeV/#it{c})};#bf{#it{N}_{tracks}}", HistType::kTH1F, {{500, 0, 10}}); + mHistManager.add("TrackCuts/TracksBefore/fEtaTrackBefore", "Pseudorapidity of all processed tracks;#eta;#bf{#it{N}_{tracks}}", HistType::kTH1F, {{500, -2, 2}}); + mHistManager.add("TrackCuts/TracksBefore/fPhiTrackBefore", "Azimuthal angle of all processed tracks;#phi;#bf{#it{N}_{tracks}}", HistType::kTH1F, {{720, 0, constants::math::TwoPI}}); // TPC signal - mHistManager.add("TrackCuts/TPCSignal/fTPCSignal", "TPCSignal;p_{TPC} (GeV/c);dE/dx", {HistType::kTH2F, {{500, 0.0f, 6.0f}, {2000, -100.f, 500.f}}}); - mHistManager.add("TrackCuts/TPCSignal/fTPCSignalP", "TPCSignalP;p (GeV/c);dE/dx", {HistType::kTH2F, {{500, 0.0f, 6.0f}, {2000, -100.f, 500.f}}}); - // TPC signal anti - mHistManager.add("TrackCuts/TPCSignal/fTPCSignalAnti", "TPCSignal;p_{TPC} (GeV/c);dE/dx", {HistType::kTH2F, {{500, 0.0f, 6.0f}, {2000, -100.f, 500.f}}}); - mHistManager.add("TrackCuts/TPCSignal/fTPCSignalAntiP", "TPCSignalP;p (GeV/c);dE/dx", {HistType::kTH2F, {{500, 0.0f, 6.0f}, {2000, -100.f, 500.f}}}); - - // TPC signal particles - mHistManager.add("TrackCuts/TPCSignal/fTPCSignalPion", "fTPCSignalPion;p_{TPC} (GeV/c);dE/dx", {HistType::kTH2F, {{500, 0.0f, 6.0f}, {10000, -100.f, 500.f}}}); - mHistManager.add("TrackCuts/TPCSignal/fTPCSignalAntiPion", "fTPCSignalAntiPion;p_{TPC} (GeV/c);dE/dx", {HistType::kTH2F, {{500, 0.0f, 6.0f}, {10000, -100.f, 500.f}}}); - // pions - mHistManager.add("TrackCuts/Pion/fPPion", "Momentum of Pions at PV;p (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - mHistManager.add("TrackCuts/Pion/fPTPCPion", "Momentum of Pions at TPC inner wall;p_{TPC} (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - mHistManager.add("TrackCuts/Pion/fPtPion", "Transverse momentum of all processed tracks;p_{T} (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - mHistManager.add("TrackCuts/Pion/fMomCorPionDif", "Momentum correlation;p_{reco} (GeV/c); (p_{TPC} - p_{reco}) (GeV/c)", {HistType::kTH2F, {{500, 0, 10}, {600, -3, 3}}}); - mHistManager.add("TrackCuts/Pion/fMomCorPionRatio", "Momentum correlation;p_{reco} (GeV/c); p_{TPC} - p_{reco} / p_{reco}", {HistType::kTH2F, {{500, 0, 10}, {200, -1, 1}}}); - mHistManager.add("TrackCuts/Pion/fEtaPion", "Pseudorapidity of all processed tracks;#eta;Entries", HistType::kTH1F, {{500, -2, 2}}); - mHistManager.add("TrackCuts/Pion/fPhiPion", "Azimuthal angle of all processed tracks;#phi;Entries", HistType::kTH1F, {{720, 0, TMath::TwoPi()}}); - mHistManager.add("TrackCuts/Pion/fNsigmaTPCvsPPion", "NSigmaTPC Pion;p_{TPC} (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - mHistManager.add("TrackCuts/Pion/fNsigmaTOFvsPPion", "NSigmaTOF Pion;p_{TPC} (GeV/c);n#sigma_{TOF}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - mHistManager.add("TrackCuts/Pion/fNsigmaTPCTOFvsPPion", "NSigmaTPCTOF Pion;p_{TPC} (GeV/c);n#sigma_{comb}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, 0.f, 10.f}}}); - - mHistManager.add("TrackCuts/Pion/fNsigmaTPCvsPPionP", "NSigmaTPC Pion P;p (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - mHistManager.add("TrackCuts/Pion/fNsigmaTOFvsPPionP", "NSigmaTOF Pion P;p (GeV/c);n#sigma_{TOF}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - mHistManager.add("TrackCuts/Pion/fNsigmaTPCTOFvsPPionP", "NSigmaTPCTOF Pion P;p (GeV/c);n#sigma_{comb}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, 0.f, 10.f}}}); - - mHistManager.add("TrackCuts/Pion/fDCAxyPion", "fDCAxy Pion;DCA_{XY};Entries", HistType::kTH1F, {{500, -0.5f, 0.5f}}); - mHistManager.add("TrackCuts/Pion/fDCAzPion", "fDCAz Pion;DCA_{Z};Entries", HistType::kTH1F, {{500, -0.5f, 0.5f}}); - mHistManager.add("TrackCuts/Pion/fTPCsClsPion", "fTPCsCls Pion;TPC Shared Clusters;Entries", HistType::kTH1F, {{163, -1.0f, 162.0f}}); - mHistManager.add("TrackCuts/Pion/fTPCcRowsPion", "fTPCcRows Pion;TPC Crossed Rows;Entries", HistType::kTH1F, {{163, -1.0f, 162.0f}}); - mHistManager.add("TrackCuts/Pion/fTrkTPCfClsPion", "fTrkTPCfCls Pion;TPC Findable/CrossedRows;Entries", HistType::kTH1F, {{500, 0.0f, 3.0f}}); - mHistManager.add("TrackCuts/Pion/fTPCnclsPion", "fTPCncls Pion;TPC Clusters;Entries", HistType::kTH1F, {{163, -1.0f, 162.0f}}); - - // anti-pions - mHistManager.add("TrackCuts/AntiPion/fPtAntiPion", "Transverse momentum of all processed tracks;p_{T} (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - mHistManager.add("TrackCuts/AntiPion/fMomCorAntiPionDif", "Momentum correlation;p_{reco} (GeV/c); (p_{TPC} - p_{reco}) (GeV/c)", {HistType::kTH2F, {{500, 0, 10}, {600, -3, 3}}}); - mHistManager.add("TrackCuts/AntiPion/fMomCorAntiPionRatio", "Momentum correlation;p_{reco} (GeV/c); |p_{TPC} - p_{reco}| (GeV/c)", {HistType::kTH2F, {{500, 0, 10}, {200, -1, 1}}}); - mHistManager.add("TrackCuts/AntiPion/fEtaAntiPion", "Pseudorapidity of all processed tracks;#eta;Entries", HistType::kTH1F, {{500, -2, 2}}); - mHistManager.add("TrackCuts/AntiPion/fPhiAntiPion", "Azimuthal angle of all processed tracks;#phi;Entries", HistType::kTH1F, {{720, 0, TMath::TwoPi()}}); - mHistManager.add("TrackCuts/AntiPion/fNsigmaTPCvsPAntiPion", "NSigmaTPC AntiPion;p_{TPC} (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - mHistManager.add("TrackCuts/AntiPion/fNsigmaTOFvsPAntiPion", "NSigmaTOF AntiPion;p_{TPC} (GeV/c);n#sigma_{TOF}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - mHistManager.add("TrackCuts/AntiPion/fNsigmaTPCTOFvsPAntiPion", "NSigmaTPCTOF AntiPion;p_{TPC} (GeV/c);n#sigma_{comb}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, 0.f, 10.f}}}); - - mHistManager.add("TrackCuts/AntiPion/fNsigmaTPCvsPAntiPionP", "NSigmaTPC AntiPion P;p (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - mHistManager.add("TrackCuts/AntiPion/fNsigmaTOFvsPAntiPionP", "NSigmaTOF AntiPion P;p (GeV/c);n#sigma_{TOF}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); - mHistManager.add("TrackCuts/AntiPion/fNsigmaTPCTOFvsPAntiPionP", "NSigmaTPCTOF AntiPion P;p (GeV/c);n#sigma_{comb}", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, 0.f, 10.f}}}); - - mHistManager.add("TrackCuts/AntiPion/fDCAxyAntiPion", "fDCAxy AntiPion;DCA_{XY};Entries", HistType::kTH1F, {{500, -0.5f, 0.5f}}); - mHistManager.add("TrackCuts/AntiPion/fDCAzAntiPion", "fDCAz AntiPion;DCA_{Z};Entries", HistType::kTH1F, {{500, -0.5f, 0.5f}}); - mHistManager.add("TrackCuts/AntiPion/fTPCsClsAntiPion", "fTPCsCls AntiPion;TPC Shared Clusters;Entries", HistType::kTH1F, {{163, -1.0f, 162.0f}}); - mHistManager.add("TrackCuts/AntiPion/fTPCcRowsAntiPion", "fTPCcRows AntiPion;TPC Crossed Rows;Entries", HistType::kTH1F, {{163, -1.0f, 162.0f}}); - mHistManager.add("TrackCuts/AntiPion/fTrkTPCfClsAntiPion", "fTrkTPCfCls AntiPion;TPC Findable/CrossedRows;Entries", HistType::kTH1F, {{500, 0.0f, 3.0f}}); - mHistManager.add("TrackCuts/AntiPion/fTPCnclsAntiPion", "fTPCncls AntiPion;TPC Clusters;Entries", HistType::kTH1F, {{163, -1.0f, 162.0f}}); - - // HNM - // omega QA - // daughter pos before - mHistManager.add("TrackCuts/HMN/PosDaughter/fInvMass", "Invariant mass HMN Pos Daugh;M_{#pi};Entries", HistType::kTH1F, {{500, 0, 1}}); - mHistManager.add("TrackCuts/HMN/PosDaughter/fPt", "Transverse momentum HMN Pos Daugh tracks;p_{T} (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - mHistManager.add("TrackCuts/HMN/PosDaughter/fEta", "HMN Pos Daugh Eta;#eta;Entries", HistType::kTH1F, {{500, -2, 2}}); - mHistManager.add("TrackCuts/HMN/PosDaughter/fPhi", "Azimuthal angle of HMN Pos Daugh tracks;#phi;Entries", HistType::kTH1F, {{720, 0, TMath::TwoPi()}}); - // daughter neg before - mHistManager.add("TrackCuts/HMN/NegDaughter/fInvMass", "Invariant mass HMN Neg Daugh;M_{#pi};Entries", HistType::kTH1F, {{500, 0, 1}}); - mHistManager.add("TrackCuts/HMN/NegDaughter/fPt", "Transverse momentum HMN Neg Daugh tracks;p_{T} (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - mHistManager.add("TrackCuts/HMN/NegDaughter/fEta", "HMN Neg Daugh Eta;#eta;Entries", HistType::kTH1F, {{500, -2, 2}}); - mHistManager.add("TrackCuts/HMN/NegDaughter/fPhi", "Azimuthal angle of HMN Neg Daugh tracks;#phi;Entries", HistType::kTH1F, {{720, 0, TMath::TwoPi()}}); - // HMNCand tracks before - mHistManager.add("TrackCuts/HMN/fInvMass_tracks", "Invariant mass HMNCand;M_{#pi#pi#gammg#gamma};Entries", HistType::kTH1F, {{5000, 0, 5}}); - mHistManager.add("TrackCuts/HMN/fInvMassPt_tracks", "Invariant mass HMNCand;M_{#pi^{+}#pi^{-}};pT_{#pi^{+}#pi^{-}}", HistType::kTH2F, {{5000, 0, 5}, {500, 0, 10}}); - mHistManager.add("TrackCuts/HMN/fPt_tracks", "Transverse momentum HMNCand;p_{T} (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - mHistManager.add("TrackCuts/HMN/fEta_tracks", "Pseudorapidity of HMNCand;#eta;Entries", HistType::kTH1F, {{500, -2, 2}}); - mHistManager.add("TrackCuts/HMN/fPhi_tracks", "Azimuthal angle of HMNCand;#phi;Entries", HistType::kTH1F, {{720, 0, TMath::TwoPi()}}); - mHistManager.add("TrackCuts/HMN/PCM/fInvMass", "Invariant mass HMNCand;M_{#pi#pi#gammg#gamma};Entries", HistType::kTH1F, {{5000, 0, 5}}); - mHistManager.add("TrackCuts/HMN/PCM/fPt", "Transverse momentum HMNCand;p_{T} (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - mHistManager.add("TrackCuts/HMN/PCM/fEta", "Pseudorapidity of HMNCand;#eta;Entries", HistType::kTH1F, {{500, -2, 2}}); - mHistManager.add("TrackCuts/HMN/PCM/fPhi", "Azimuthal angle of HMNCand;#phi;Entries", HistType::kTH1F, {{720, 0, TMath::TwoPi()}}); - mHistManager.add("TrackCuts/HMN/EMC/fInvMass", "Invariant mass HMNCand;M_{#pi#pi#gammg#gamma};Entries", HistType::kTH1F, {{5000, 0, 5}}); - mHistManager.add("TrackCuts/HMN/EMC/fPt", "Transverse momentum HMNCand;p_{T} (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - mHistManager.add("TrackCuts/HMN/EMC/fEta", "Pseudorapidity of HMNCand;#eta;Entries", HistType::kTH1F, {{500, -2, 2}}); - mHistManager.add("TrackCuts/HMN/EMC/fPhi", "Azimuthal angle of HMNCand;#phi;Entries", HistType::kTH1F, {{720, 0, TMath::TwoPi()}}); - mHistManager.add("TrackCuts/HMN/PCMEMC/fInvMass", "Invariant mass HMNCand;M_{#pi#pi#gammg#gamma};Entries", HistType::kTH1F, {{5000, 0, 5}}); - mHistManager.add("TrackCuts/HMN/PCMEMC/fPt", "Transverse momentum HMNCand;p_{T} (GeV/c);Entries", HistType::kTH1F, {{500, 0, 10}}); - mHistManager.add("TrackCuts/HMN/PCMEMC/fEta", "Pseudorapidity of HMNCand;#eta;Entries", HistType::kTH1F, {{500, -2, 2}}); - mHistManager.add("TrackCuts/HMN/PCMEMC/fPhi", "Azimuthal angle of HMNCand;#phi;Entries", HistType::kTH1F, {{720, 0, TMath::TwoPi()}}); - - if (ConfDoEMCShift.value) { - for (int iSM = 0; iSM < 20; iSM++) { - EMCEtaShift[iSM] = ConfEMCEtaShift.value[iSM]; - EMCPhiShift[iSM] = ConfEMCPhiShift.value[iSM]; - LOG(info) << "SM-wise shift in eta/phi for SM " << iSM << ": " << EMCEtaShift[iSM] << " / " << EMCPhiShift[iSM]; + mHistManager.add("TrackCuts/TPCSignal/fTPCSignalTPCP", "TPCSignal;#bf{#it{p}_{TPC} (GeV/#it{c})};dE/dx", {HistType::kTH2F, {{500, 0.0f, 6.0f}, {2000, -100.f, 500.f}}}); + mHistManager.add("TrackCuts/TPCSignal/fTPCSignal", "TPCSignalP;#bf{#it{p} (GeV/#it{c})};dE/dx", {HistType::kTH2F, {{500, 0.0f, 6.0f}, {2000, -100.f, 500.f}}}); + // TPC signal antiparticles (negative charge) + mHistManager.add("TrackCuts/TPCSignal/fTPCSignalAntiTPCP", "TPCSignal;#bf{#it{p}_{TPC} (GeV/#it{c})};dE/dx", {HistType::kTH2F, {{500, 0.0f, 6.0f}, {2000, -100.f, 500.f}}}); + mHistManager.add("TrackCuts/TPCSignal/fTPCSignalAnti", "TPCSignalP;#bf{#it{p} (GeV/#it{c})};dE/dx", {HistType::kTH2F, {{500, 0.0f, 6.0f}, {2000, -100.f, 500.f}}}); + + const int nTrackSpecies = 2; // x2 because of anti particles + const char* particleSpecies[nTrackSpecies] = {"Pion", "AntiPion"}; + const char* particleSpeciesLatex[nTrackSpecies] = {"#pi^{+}", "#pi^{-}"}; + + for (int iParticle = 0; iParticle < nTrackSpecies; iParticle++) { + mHistManager.add(Form("TrackCuts/TracksBefore/fMomCorrelationAfterCuts%s", particleSpecies[iParticle]), "fMomCorrelation;#bf{#it{p} (GeV/#it{c})};#bf{#it{p}_{TPC} (GeV/#it{c})}", {HistType::kTH2F, {{500, 0.0f, 20.0f}, {500, 0.0f, 20.0f}}}); + mHistManager.add(Form("TrackCuts/TPCSignal/fTPCSignal%s", particleSpecies[iParticle]), Form("%s TPC energy loss;#bf{#it{p}_{TPC}^{%s} (GeV/#it{c})};dE/dx", particleSpecies[iParticle], particleSpeciesLatex[iParticle]), {HistType::kTH2F, {{500, 0.0f, 6.0f}, {10000, -100.f, 500.f}}}); + + mHistManager.add(Form("TrackCuts/%s/fP", particleSpecies[iParticle]), Form("%s momentum at PV;#bf{#it{p}^{%s} (GeV/#it{c})};#bf{#it{N}^{%s}}", particleSpecies[iParticle], particleSpeciesLatex[iParticle], particleSpeciesLatex[iParticle]), HistType::kTH1F, {{500, 0, 10}}); + mHistManager.add(Form("TrackCuts/%s/fPt", particleSpecies[iParticle]), Form("%s transverse momentum;#bf{#it{p}_{T}^{%s} (GeV/#it{c})};#bf{#it{N}^{%s}}", particleSpecies[iParticle], particleSpeciesLatex[iParticle], particleSpeciesLatex[iParticle]), HistType::kTH1F, {{500, 0, 10}}); + mHistManager.add(Form("TrackCuts/%s/fMomCorDif", particleSpecies[iParticle]), Form("Momentum correlation;#bf{#it{p}^{%s} (GeV/#it{c})};#bf{#it{p}_{TPC}^{%s} - #it{p}^{%s} (GeV/#it{c})}", particleSpeciesLatex[iParticle], particleSpeciesLatex[iParticle], particleSpeciesLatex[iParticle]), {HistType::kTH2F, {{500, 0, 10}, {600, -3, 3}}}); + mHistManager.add(Form("TrackCuts/%s/fMomCorRatio", particleSpecies[iParticle]), Form("Relative momentum correlation;#bf{#it{p}^{%s} (GeV/#it{c})};#bf{#it{p}_{TPC}^{%s} - #it{p}^{%s} / #it{p}^{%s}}", particleSpeciesLatex[iParticle], particleSpeciesLatex[iParticle], particleSpeciesLatex[iParticle], particleSpeciesLatex[iParticle]), {HistType::kTH2F, {{500, 0, 10}, {200, -1, 1}}}); + mHistManager.add(Form("TrackCuts/%s/fEta", particleSpecies[iParticle]), Form("%s pseudorapidity distribution;#eta;#bf{#it{N}^{%s}}", particleSpecies[iParticle], particleSpeciesLatex[iParticle]), HistType::kTH1F, {{500, -2, 2}}); + mHistManager.add(Form("TrackCuts/%s/fPhi", particleSpecies[iParticle]), Form("%s azimuthal angle distribution;#phi;#bf{#it{N}^{%s}}", particleSpecies[iParticle], particleSpeciesLatex[iParticle]), HistType::kTH1F, {{720, 0, constants::math::TwoPI}}); + + mHistManager.add(Form("TrackCuts/%s/fNsigmaTPCvsTPCP", particleSpecies[iParticle]), Form("NSigmaTPC %s;#bf{#it{p}_{TPC}^{%s} (GeV/#it{c})};n#sigma_{TPC}^{%s}", particleSpecies[iParticle], particleSpeciesLatex[iParticle], particleSpeciesLatex[iParticle]), {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); + mHistManager.add(Form("TrackCuts/%s/fNsigmaTOFvsTPCP", particleSpecies[iParticle]), Form("NSigmaTOF %s;#bf{#it{p}_{TPC}^{%s} (GeV/#it{c})};n#sigma_{TOF}^{%s}", particleSpecies[iParticle], particleSpeciesLatex[iParticle], particleSpeciesLatex[iParticle]), {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); + mHistManager.add(Form("TrackCuts/%s/fNsigmaTPCTOFvsTPCP", particleSpecies[iParticle]), Form("NSigmaTPCTOF %s;#bf{#it{p}_{TPC}^{%s} (GeV/#it{c})};n#sigma_{comb}^{%s}", particleSpecies[iParticle], particleSpeciesLatex[iParticle], particleSpeciesLatex[iParticle]), {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, 0.f, 10.f}}}); + mHistManager.add(Form("TrackCuts/%s/fNsigmaITSvsP", particleSpecies[iParticle]), Form("NSigmaITS %s;#bf{#it{p}^{%s} (GeV/#it{c})};n#sigma_{ITS}^{%s}", particleSpecies[iParticle], particleSpeciesLatex[iParticle], particleSpeciesLatex[iParticle]), {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); + mHistManager.add(Form("TrackCuts/%s/fNsigmaTPCvsP", particleSpecies[iParticle]), Form("NSigmaTPC %s P;#bf{#it{p}^{%s} (GeV/#it{c})};n#sigma_{TPC}^{%s}", particleSpecies[iParticle], particleSpeciesLatex[iParticle], particleSpeciesLatex[iParticle]), {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); + mHistManager.add(Form("TrackCuts/%s/fNsigmaTOFvsP", particleSpecies[iParticle]), Form("NSigmaTOF %s P;#bf{#it{p}^{%s} (GeV/#it{c})};n#sigma_{TOF}^{%s}", particleSpecies[iParticle], particleSpeciesLatex[iParticle], particleSpeciesLatex[iParticle]), {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, -10.f, 10.f}}}); + mHistManager.add(Form("TrackCuts/%s/fNsigmaTPCTOFvsP", particleSpecies[iParticle]), Form("NSigmaTPCTOF %s P;#bf{#it{p}^{%s} (GeV/#it{c})};n#sigma_{comb}^{%s}", particleSpecies[iParticle], particleSpeciesLatex[iParticle], particleSpeciesLatex[iParticle]), {HistType::kTH2F, {{100, 0.0f, 10.0f}, {100, 0.f, 10.f}}}); + + mHistManager.add(Form("TrackCuts/%s/fDCAxy", particleSpecies[iParticle]), Form("fDCAxy %s;#bf{DCA_{xy}};#bf{#it{N}^{%s}}", particleSpecies[iParticle], particleSpeciesLatex[iParticle]), HistType::kTH1F, {{500, -0.5f, 0.5f}}); + mHistManager.add(Form("TrackCuts/%s/fDCAz", particleSpecies[iParticle]), Form("fDCAz %s;#bf{DCA_{z}};#bf{#it{N}^{%s}}", particleSpecies[iParticle], particleSpeciesLatex[iParticle]), HistType::kTH1F, {{500, -0.5f, 0.5f}}); + mHistManager.add(Form("TrackCuts/%s/fTPCsCls", particleSpecies[iParticle]), Form("fTPCsCls %s;#bf{TPC Shared Clusters};#bf{#it{N}^{%s}}", particleSpecies[iParticle], particleSpeciesLatex[iParticle]), HistType::kTH1F, {{163, -1.0f, 162.0f}}); + mHistManager.add(Form("TrackCuts/%s/fTPCcRows", particleSpecies[iParticle]), Form("fTPCcRows %s;#bf{TPC Crossed Rows};#bf{#it{N}^{%s}}", particleSpecies[iParticle], particleSpeciesLatex[iParticle]), HistType::kTH1F, {{163, -1.0f, 162.0f}}); + mHistManager.add(Form("TrackCuts/%s/fTrkTPCfCls", particleSpecies[iParticle]), Form("fTrkTPCfCls %s;#bf{TPC Findable/CrossedRows};#bf{#it{N}^{%s}}", particleSpecies[iParticle], particleSpeciesLatex[iParticle]), HistType::kTH1F, {{500, 0.0f, 3.0f}}); + mHistManager.add(Form("TrackCuts/%s/fTPCncls", particleSpecies[iParticle]), Form("fTPCncls %s;#bf{TPC Clusters};#bf{#it{N}^{%s}}", particleSpecies[iParticle], particleSpeciesLatex[iParticle]), HistType::kTH1F, {{163, -1.0f, 162.0f}}); + } + + // --> HNM QA + // pi+ daughter + mHistManager.add("HNM/Before/PosDaughter/fInvMass", "Invariant mass HMN Pos Daugh;#bf{#it{M}^{#pi^{+}} (GeV/#it{c}^{2})};#bf{#it{N}^{#pi^{+}}}", HistType::kTH1F, {{200, 0, 0.2}}); + mHistManager.add("HNM/Before/PosDaughter/fPt", "Transverse momentum HMN Pos Daugh tracks;#bf{#it{p}_{T} (GeV/#it{c})};#bf{#it{N}^{#pi^{+}}}", HistType::kTH1F, {{500, 0, 10}}); + mHistManager.add("HNM/Before/PosDaughter/fEta", "HMN Pos Daugh Eta;#eta;#bf{#it{N}^{#pi^{+}}}", HistType::kTH1F, {{500, -2, 2}}); + mHistManager.add("HNM/Before/PosDaughter/fPhi", "Azimuthal angle of HMN Pos Daugh tracks;#phi;#bf{#it{N}^{#pi^{+}}}", HistType::kTH1F, {{720, 0, constants::math::TwoPI}}); + // pi- daughter + mHistManager.add("HNM/Before/NegDaughter/fInvMass", "Invariant mass HMN Neg Daugh;#bf{#it{M}^{#pi^{-}} (GeV/#it{c}^{2})};#bf{#it{N}^{#pi^{-}}}", HistType::kTH1F, {{200, 0, 0.2}}); + mHistManager.add("HNM/Before/NegDaughter/fPt", "Transverse momentum HMN Neg Daugh tracks;#bf{#it{p}_{T} (GeV/#it{c})};#bf{#it{N}^{#pi^{-}}}", HistType::kTH1F, {{500, 0, 10}}); + mHistManager.add("HNM/Before/NegDaughter/fEta", "HMN Neg Daugh Eta;#eta;#bf{#it{N}^{#pi^{-}}}", HistType::kTH1F, {{500, -2, 2}}); + mHistManager.add("HNM/Before/NegDaughter/fPhi", "Azimuthal angle of HMN Neg Daugh tracks;#phi;#bf{#it{N}^{#pi^{-}}}", HistType::kTH1F, {{720, 0, constants::math::TwoPI}}); + // Properties of the pi+pi- pair + mHistManager.add("HNM/Before/PiPlPiMi/fInvMassVsPt", "Invariant mass and pT of #pi^+pi^- pairs;#bf{#it{M}^{#pi^{+}#pi^{-}} (GeV/#it{c}^{2})};#bf{#it{p}_{T}^{#pi^{+}#pi^{-}} (GeV/#it{c})}", HistType::kTH2F, {{400, 0.2, 1.}, {250, 0., 25.}}); + mHistManager.add("HNM/Before/PiPlPiMi/fEta", "Pseudorapidity of HMNCand;#eta;#bf{#it{N}^{#pi^{+}#pi^{-}}}", HistType::kTH1F, {{500, -2, 2}}); + mHistManager.add("HNM/Before/PiPlPiMi/fPhi", "Azimuthal angle of HMNCand;#phi;#bf{#it{N}^{#pi^{+}#pi^{-}}}", HistType::kTH1F, {{720, 0, constants::math::TwoPI}}); + + for (const auto& BeforeAfterString : {"Before", "After"}) { + for (const auto& iHNM : {"Omega", "EtaPrime"}) { + for (const auto& MethodString : {"PCM", "EMC"}) { + mHistManager.add(Form("HNM/%s/%s/%s/fInvMassVsPt", BeforeAfterString, iHNM, MethodString), "Invariant mass and pT of heavy neutral meson candidates;#bf{#it{M}^{#pi^{+}#pi^{-}#gamma#gamma} (GeV/#it{c}^{2})};#bf{#it{p}_{T}^{#pi^{+}#pi^{-}#gamma#gamma} (GeV/#it{c})}", HistType::kTH2F, {{600, 0.6, 1.2}, {250, 0., 25.}}); + mHistManager.add(Form("HNM/%s/%s/%s/fEta", BeforeAfterString, iHNM, MethodString), "Pseudorapidity of HNM candidate;#eta;#bf{#it{N}^{#pi^{+}#pi^{-}#gamma#gamma}}", HistType::kTH1F, {{500, -2, 2}}); + mHistManager.add(Form("HNM/%s/%s/%s/fPhi", BeforeAfterString, iHNM, MethodString), "Azimuthal angle of HNM candidate;#phi;#bf{#it{N}^{#pi^{+}#pi^{-}#gamma#gamma}}", HistType::kTH1F, {{720, 0, constants::math::TwoPI}}); + } + } + } + mHistManager.add("HNM/Before/Omega/PCMEMC/fInvMassVsPt", "Invariant mass and pT of omega meson candidates;#bf{#it{M}^{#pi^{+}#pi^{-}#gamma#gamma} (GeV/#it{c}^{2})};#bf{#it{p}_{T}^{#pi^{+}#pi^{-}#gamma#gamma} (GeV/#it{c})}", HistType::kTH2F, {{600, 0.6, 1.2}, {250, 0., 25.}}); + mHistManager.add("HNM/Before/Omega/PCMEMC/fEta", "Pseudorapidity of HMNCand;#eta;#bf{#it{N}^{#pi^{+}#pi^{-}#gamma#gamma}}", HistType::kTH1F, {{500, -2, 2}}); + mHistManager.add("HNM/Before/Omega/PCMEMC/fPhi", "Azimuthal angle of HMNCand;#phi;#bf{#it{N}^{#pi^{+}#pi^{-}#gamma#gamma}}", HistType::kTH1F, {{720, 0, constants::math::TwoPI}}); + mHistManager.add("HNM/Before/EtaPrime/PCMEMC/fInvMassVsPt", "Invariant mass and pT of eta' meson candidates;#bf{#it{M}^{#pi^{+}#pi^{-}#gamma#gamma} (GeV/#it{c}^{2})};#bf{#it{p}_{T}^{#pi^{+}#pi^{-}#gamma#gamma} (GeV/#it{c})}", HistType::kTH2F, {{600, 0.8, 1.2}, {250, 0., 25.}}); + mHistManager.add("HNM/Before/EtaPrime/PCMEMC/fEta", "Pseudorapidity of HMNCand;#eta;#bf{#it{N}^{#pi^{+}#pi^{-}#gamma#gamma}}", HistType::kTH1F, {{500, -2, 2}}); + mHistManager.add("HNM/Before/EtaPrime/PCMEMC/fPhi", "Azimuthal angle of HMNCand;#phi;#bf{#it{N}^{#pi^{+}#pi^{-}#gamma#gamma}}", HistType::kTH1F, {{720, 0, constants::math::TwoPI}}); + + if (cfgDoEMCShift.value) { + for (int iSM = 0; iSM < nSMs; iSM++) { + emcEtaShift[iSM] = cfgEMCEtaShift.value[iSM]; + emcPhiShift[iSM] = cfgEMCPhiShift.value[iSM]; + LOG(info) << "SM-wise shift in eta/phi for SM " << iSM << ": " << emcEtaShift[iSM] << " / " << emcPhiShift[iSM]; } } } - Preslice perCollision_pcm = aod::v0photonkf::collisionId; - Preslice perCollision_emc = aod::skimmedcluster::collisionId; void process(aod::MyCollision const& collision, aod::MyBCs const&, aod::SkimEMCClusters const& clusters, aod::V0PhotonsKF const& v0s, aod::SelectedTracks const& tracks) { // inlcude ITS PID information auto tracksWithItsPid = soa::Attach(tracks); - mHistManager.fill(HIST("Event/hCollisionCounter"), 0.); - // QA all evts - mHistManager.fill(HIST("EventCuts/fMultiplicityBefore"), collision.multNTracksPV()); - mHistManager.fill(HIST("EventCuts/fZvtxBefore"), collision.posZ()); + mHistManager.fill(HIST("Event/fMultiplicityBefore"), collision.multNTracksPV()); + mHistManager.fill(HIST("Event/fZvtxBefore"), collision.posZ()); // Ensure evts are consistent with Sel8 and Vtx-z selection - if (!isSelectedEvent(collision)) { + if (!isSelectedEvent(collision)) return; - } // QA accepted evts - mHistManager.fill(HIST("EventCuts/fMultiplicityAfter"), collision.multNTracksPV()); - mHistManager.fill(HIST("EventCuts/fZvtxAfter"), collision.posZ()); + mHistManager.fill(HIST("Event/fMultiplicityAfter"), collision.multNTracksPV()); + mHistManager.fill(HIST("Event/fZvtxAfter"), collision.posZ()); // clean vecs - // Pions for HNM pion.clear(); antipion.clear(); vHNMs.clear(); // vGGs vector is cleared in reconstructGGs. - if (collision.foundBC_as().alias_bit(kTVXinEMC)) { - mHistManager.fill(HIST("Event/hCollisionCounter"), 1.); - } - - auto v0sInThisCollision = v0s.sliceBy(perCollision_pcm, collision.globalIndex()); - auto clustersInThisCollision = clusters.sliceBy(perCollision_emc, collision.globalIndex()); - + // ---------------------------------> EMCal event QA <---------------------------------- + // - Fill Event/nEMCalEvents histogram for EMCal event QA + // ------------------------------------------------------------------------------------- + bool bcHasEMCCells = collision.isemcreadout(); + bool iskTVXinEMC = collision.foundBC_as().alias_bit(kTVXinEMC); + bool isL0Triggered = collision.foundBC_as().alias_bit(kEMC7) || collision.foundBC_as().alias_bit(kEG1) || collision.foundBC_as().alias_bit(kEG2); + + if (bcHasEMCCells && iskTVXinEMC) + mHistManager.fill(HIST("Event/nEMCalEvents"), 0); + if (bcHasEMCCells && isL0Triggered) + mHistManager.fill(HIST("Event/nEMCalEvents"), 1); + if (bcHasEMCCells && !iskTVXinEMC && !isL0Triggered) + mHistManager.fill(HIST("Event/nEMCalEvents"), 2); + if (!bcHasEMCCells && iskTVXinEMC) + mHistManager.fill(HIST("Event/nEMCalEvents"), 3); + if (!bcHasEMCCells && isL0Triggered) + mHistManager.fill(HIST("Event/nEMCalEvents"), 4); + + // --------------------------------> Process Photons <---------------------------------- + // - Slice clusters and V0s by collision ID to get the ones in this collision + // - Store the clusters and V0s in the vGammas vector + // - Reconstruct gamma-gamma pairs + // ------------------------------------------------------------------------------------- + auto v0sInThisCollision = v0s.sliceBy(perCollisionPCM, collision.globalIndex()); + auto clustersInThisCollision = clusters.sliceBy(perCollisionEMC, collision.globalIndex()); mHistManager.fill(HIST("Event/nClustersVsV0s"), clustersInThisCollision.size(), v0sInThisCollision.size()); - mHistManager.fill(HIST("Event/nTracks"), tracksWithItsPid.size()); std::vector vGammas; - hnmutilities::storeGammasInVector(clustersInThisCollision, v0sInThisCollision, vGammas, EMCEtaShift, EMCPhiShift); + hnmutilities::storeGammasInVector(clustersInThisCollision, v0sInThisCollision, vGammas, emcEtaShift, emcPhiShift); hnmutilities::reconstructGGs(vGammas, vGGs); vGammas.clear(); processGGs(vGGs); - bool isPion = false; - + // ------------------------------> Loop over all tracks <------------------------------- + // - Sort them into vectors based on PID ((anti)protons, (anti)deuterons, (anti)pions) + // - Fill QA histograms for all tracks and per particle species + // ------------------------------------------------------------------------------------- for (const auto& track : tracksWithItsPid) { - // General QA mHistManager.fill(HIST("TrackCuts/TracksBefore/fPtTrackBefore"), track.pt()); mHistManager.fill(HIST("TrackCuts/TracksBefore/fEtaTrackBefore"), track.eta()); mHistManager.fill(HIST("TrackCuts/TracksBefore/fPhiTrackBefore"), track.phi()); - // Fill PID info - if (track.sign() > 0) { - mHistManager.fill(HIST("TrackCuts/TPCSignal/fTPCSignal"), track.tpcInnerParam(), track.tpcSignal()); - mHistManager.fill(HIST("TrackCuts/TPCSignal/fTPCSignalP"), track.p(), track.tpcSignal()); + if (track.sign() > 0) { // All particles (positive electric charge) + mHistManager.fill(HIST("TrackCuts/TPCSignal/fTPCSignalTPCP"), track.tpcInnerParam(), track.tpcSignal()); + mHistManager.fill(HIST("TrackCuts/TPCSignal/fTPCSignal"), track.p(), track.tpcSignal()); mHistManager.fill(HIST("TrackCuts/TracksBefore/fMomCorrelationPos"), track.p(), track.tpcInnerParam()); } - if (track.sign() < 0) { - mHistManager.fill(HIST("TrackCuts/TPCSignal/fTPCSignalAnti"), track.tpcInnerParam(), track.tpcSignal()); - mHistManager.fill(HIST("TrackCuts/TPCSignal/fTPCSignalAntiP"), track.p(), track.tpcSignal()); + if (track.sign() < 0) { // All anti-particles (negative electric charge) + mHistManager.fill(HIST("TrackCuts/TPCSignal/fTPCSignalAntiTPCP"), track.tpcInnerParam(), track.tpcSignal()); + mHistManager.fill(HIST("TrackCuts/TPCSignal/fTPCSignalAnti"), track.p(), track.tpcSignal()); mHistManager.fill(HIST("TrackCuts/TracksBefore/fMomCorrelationNeg"), track.p(), track.tpcInnerParam()); } - isPion = (isSelectedTrackPID(track, HNMPID::kPion) && isSelectedTrack(track, HNMPID::kPion)); + // For each track, check if it fulfills track and PID criteria to be identified as a proton, deuteron or pion + bool isPion = (isSelectedTrackPID(track, hnm::kPion) && isSelectedTrack(track, hnm::kPion)); - if (isPion) { - if (track.sign() > 0) { // part - pion.emplace_back(track.pt(), track.eta(), track.phi(), o2::constants::physics::MassPionCharged); + if (track.sign() > 0) { // Positive charge -> Particles + if (isPion) { + pion.emplace_back(track.pt(), track.eta(), track.phi(), mMassPionCharged); mHistManager.fill(HIST("TrackCuts/TracksBefore/fMomCorrelationAfterCutsPion"), track.p(), track.tpcInnerParam()); - mHistManager.fill(HIST("TrackCuts/TPCSignal/fTPCSignalPion"), track.tpcInnerParam(), track.tpcSignal()); - mHistManager.fill(HIST("TrackCuts/Pion/fPPion"), track.p()); - mHistManager.fill(HIST("TrackCuts/Pion/fPTPCPion"), track.tpcInnerParam()); - mHistManager.fill(HIST("TrackCuts/Pion/fPtPion"), track.pt()); - mHistManager.fill(HIST("TrackCuts/Pion/fMomCorPionDif"), track.p(), track.tpcInnerParam() - track.p()); - mHistManager.fill(HIST("TrackCuts/Pion/fMomCorPionRatio"), track.p(), (track.tpcInnerParam() - track.p()) / track.p()); - mHistManager.fill(HIST("TrackCuts/Pion/fEtaPion"), track.eta()); - mHistManager.fill(HIST("TrackCuts/Pion/fPhiPion"), track.phi()); - mHistManager.fill(HIST("TrackCuts/Pion/fNsigmaTPCvsPPion"), track.tpcInnerParam(), track.tpcNSigmaPi()); - mHistManager.fill(HIST("TrackCuts/Pion/fNsigmaTOFvsPPion"), track.tpcInnerParam(), track.tofNSigmaPi()); + + mHistManager.fill(HIST("TrackCuts/Pion/fP"), track.p()); + mHistManager.fill(HIST("TrackCuts/Pion/fPt"), track.pt()); + mHistManager.fill(HIST("TrackCuts/Pion/fMomCorDif"), track.p(), track.tpcInnerParam() - track.p()); + mHistManager.fill(HIST("TrackCuts/Pion/fMomCorRatio"), track.p(), (track.tpcInnerParam() - track.p()) / track.p()); + mHistManager.fill(HIST("TrackCuts/Pion/fEta"), track.eta()); + mHistManager.fill(HIST("TrackCuts/Pion/fPhi"), track.phi()); + + mHistManager.fill(HIST("TrackCuts/Pion/fNsigmaTPCvsTPCP"), track.tpcInnerParam(), track.tpcNSigmaPi()); + mHistManager.fill(HIST("TrackCuts/Pion/fNsigmaTOFvsTPCP"), track.tpcInnerParam(), track.tofNSigmaPi()); auto nSigmaTrackTPCTOF = std::sqrt(std::pow(track.tpcNSigmaPi(), 2) + std::pow(track.tofNSigmaPi(), 2)); - mHistManager.fill(HIST("TrackCuts/Pion/fNsigmaTPCTOFvsPPion"), track.tpcInnerParam(), std::sqrt(std::pow(track.tpcNSigmaPi() - nSigmaTrackTPCTOF, 2) + std::pow(track.tofNSigmaPi() - nSigmaTrackTPCTOF, 2))); - - mHistManager.fill(HIST("TrackCuts/Pion/fNsigmaTPCvsPPionP"), track.p(), track.tpcNSigmaPi()); - mHistManager.fill(HIST("TrackCuts/Pion/fNsigmaTOFvsPPionP"), track.p(), track.tofNSigmaPi()); - mHistManager.fill(HIST("TrackCuts/Pion/fNsigmaTPCTOFvsPPionP"), track.p(), std::sqrt(std::pow(track.tpcNSigmaPi() - nSigmaTrackTPCTOF, 2) + std::pow(track.tofNSigmaPi() - nSigmaTrackTPCTOF, 2))); - - mHistManager.fill(HIST("TrackCuts/Pion/fDCAxyPion"), track.dcaXY()); - mHistManager.fill(HIST("TrackCuts/Pion/fDCAzPion"), track.dcaZ()); - mHistManager.fill(HIST("TrackCuts/Pion/fTPCsClsPion"), track.tpcNClsShared()); - mHistManager.fill(HIST("TrackCuts/Pion/fTPCcRowsPion"), track.tpcNClsCrossedRows()); - mHistManager.fill(HIST("TrackCuts/Pion/fTrkTPCfClsPion"), track.tpcCrossedRowsOverFindableCls()); - mHistManager.fill(HIST("TrackCuts/Pion/fTPCnclsPion"), track.tpcNClsFound()); - } else { // antipart - antipion.emplace_back(track.pt(), track.eta(), track.phi(), o2::constants::physics::MassPionCharged); + mHistManager.fill(HIST("TrackCuts/Pion/fNsigmaTPCTOFvsTPCP"), track.tpcInnerParam(), std::sqrt(std::pow(track.tpcNSigmaPi() - nSigmaTrackTPCTOF, 2) + std::pow(track.tofNSigmaPi() - nSigmaTrackTPCTOF, 2))); + mHistManager.fill(HIST("TrackCuts/Pion/fNsigmaITSvsP"), track.p(), track.itsNSigmaPi()); + mHistManager.fill(HIST("TrackCuts/Pion/fNsigmaTPCvsP"), track.p(), track.tpcNSigmaPi()); + mHistManager.fill(HIST("TrackCuts/Pion/fNsigmaTOFvsP"), track.p(), track.tofNSigmaPi()); + mHistManager.fill(HIST("TrackCuts/Pion/fNsigmaTPCTOFvsP"), track.p(), std::sqrt(std::pow(track.tpcNSigmaPi() - nSigmaTrackTPCTOF, 2) + std::pow(track.tofNSigmaPi() - nSigmaTrackTPCTOF, 2))); + + mHistManager.fill(HIST("TrackCuts/Pion/fDCAxy"), track.dcaXY()); + mHistManager.fill(HIST("TrackCuts/Pion/fDCAz"), track.dcaZ()); + mHistManager.fill(HIST("TrackCuts/Pion/fTPCsCls"), track.tpcNClsShared()); + mHistManager.fill(HIST("TrackCuts/Pion/fTPCcRows"), track.tpcNClsCrossedRows()); + mHistManager.fill(HIST("TrackCuts/Pion/fTrkTPCfCls"), track.tpcCrossedRowsOverFindableCls()); + mHistManager.fill(HIST("TrackCuts/Pion/fTPCncls"), track.tpcNClsFound()); + } + } else { // Negative charge -> Anti-particles + if (isPion) { + antipion.emplace_back(track.pt(), track.eta(), track.phi(), mMassPionCharged); mHistManager.fill(HIST("TrackCuts/TracksBefore/fMomCorrelationAfterCutsAntiPion"), track.p(), track.tpcInnerParam()); - mHistManager.fill(HIST("TrackCuts/TPCSignal/fTPCSignalAntiPion"), track.tpcInnerParam(), track.tpcSignal()); - mHistManager.fill(HIST("TrackCuts/AntiPion/fPtAntiPion"), track.pt()); - mHistManager.fill(HIST("TrackCuts/AntiPion/fMomCorAntiPionDif"), track.p(), track.tpcInnerParam() - track.p()); - mHistManager.fill(HIST("TrackCuts/AntiPion/fMomCorAntiPionRatio"), track.p(), (track.tpcInnerParam() - track.p()) / track.p()); - mHistManager.fill(HIST("TrackCuts/AntiPion/fEtaAntiPion"), track.eta()); - mHistManager.fill(HIST("TrackCuts/AntiPion/fPhiAntiPion"), track.phi()); - mHistManager.fill(HIST("TrackCuts/AntiPion/fNsigmaTPCvsPAntiPion"), track.tpcInnerParam(), track.tpcNSigmaPi()); - mHistManager.fill(HIST("TrackCuts/AntiPion/fNsigmaTOFvsPAntiPion"), track.tpcInnerParam(), track.tofNSigmaPi()); + + mHistManager.fill(HIST("TrackCuts/AntiPion/fP"), track.p()); + mHistManager.fill(HIST("TrackCuts/AntiPion/fPt"), track.pt()); + mHistManager.fill(HIST("TrackCuts/AntiPion/fMomCorDif"), track.p(), track.tpcInnerParam() - track.p()); + mHistManager.fill(HIST("TrackCuts/AntiPion/fMomCorRatio"), track.p(), (track.tpcInnerParam() - track.p()) / track.p()); + mHistManager.fill(HIST("TrackCuts/AntiPion/fEta"), track.eta()); + mHistManager.fill(HIST("TrackCuts/AntiPion/fPhi"), track.phi()); + + mHistManager.fill(HIST("TrackCuts/AntiPion/fNsigmaTPCvsTPCP"), track.tpcInnerParam(), track.tpcNSigmaPi()); + mHistManager.fill(HIST("TrackCuts/AntiPion/fNsigmaTOFvsTPCP"), track.tpcInnerParam(), track.tofNSigmaPi()); auto nSigmaTrackTPCTOF = std::sqrt(std::pow(track.tpcNSigmaPi(), 2) + std::pow(track.tofNSigmaPi(), 2)); - mHistManager.fill(HIST("TrackCuts/AntiPion/fNsigmaTPCTOFvsPAntiPion"), track.tpcInnerParam(), std::sqrt(std::pow(track.tpcNSigmaPi() - nSigmaTrackTPCTOF, 2) + std::pow(track.tofNSigmaPi() - nSigmaTrackTPCTOF, 2))); - - mHistManager.fill(HIST("TrackCuts/AntiPion/fNsigmaTPCvsPAntiPionP"), track.p(), track.tpcNSigmaPi()); - mHistManager.fill(HIST("TrackCuts/AntiPion/fNsigmaTOFvsPAntiPionP"), track.p(), track.tofNSigmaPi()); - mHistManager.fill(HIST("TrackCuts/AntiPion/fNsigmaTPCTOFvsPAntiPionP"), track.p(), std::sqrt(std::pow(track.tpcNSigmaPi() - nSigmaTrackTPCTOF, 2) + std::pow(track.tofNSigmaPi() - nSigmaTrackTPCTOF, 2))); - - mHistManager.fill(HIST("TrackCuts/AntiPion/fDCAxyAntiPion"), track.dcaXY()); - mHistManager.fill(HIST("TrackCuts/AntiPion/fDCAzAntiPion"), track.dcaZ()); - mHistManager.fill(HIST("TrackCuts/AntiPion/fTPCsClsAntiPion"), track.tpcNClsShared()); - mHistManager.fill(HIST("TrackCuts/AntiPion/fTPCcRowsAntiPion"), track.tpcNClsCrossedRows()); - mHistManager.fill(HIST("TrackCuts/AntiPion/fTrkTPCfClsAntiPion"), track.tpcCrossedRowsOverFindableCls()); - mHistManager.fill(HIST("TrackCuts/AntiPion/fTPCnclsAntiPion"), track.tpcNClsFound()); + mHistManager.fill(HIST("TrackCuts/AntiPion/fNsigmaTPCTOFvsTPCP"), track.tpcInnerParam(), std::sqrt(std::pow(track.tpcNSigmaPi() - nSigmaTrackTPCTOF, 2) + std::pow(track.tofNSigmaPi() - nSigmaTrackTPCTOF, 2))); + mHistManager.fill(HIST("TrackCuts/AntiPion/fNsigmaITSvsP"), track.p(), track.itsNSigmaPi()); + mHistManager.fill(HIST("TrackCuts/AntiPion/fNsigmaTPCvsP"), track.p(), track.tpcNSigmaPi()); + mHistManager.fill(HIST("TrackCuts/AntiPion/fNsigmaTOFvsP"), track.p(), track.tofNSigmaPi()); + mHistManager.fill(HIST("TrackCuts/AntiPion/fNsigmaTPCTOFvsP"), track.p(), std::sqrt(std::pow(track.tpcNSigmaPi() - nSigmaTrackTPCTOF, 2) + std::pow(track.tofNSigmaPi() - nSigmaTrackTPCTOF, 2))); + + mHistManager.fill(HIST("TrackCuts/AntiPion/fDCAxy"), track.dcaXY()); + mHistManager.fill(HIST("TrackCuts/AntiPion/fDCAz"), track.dcaZ()); + mHistManager.fill(HIST("TrackCuts/AntiPion/fTPCsCls"), track.tpcNClsShared()); + mHistManager.fill(HIST("TrackCuts/AntiPion/fTPCcRows"), track.tpcNClsCrossedRows()); + mHistManager.fill(HIST("TrackCuts/AntiPion/fTrkTPCfCls"), track.tpcCrossedRowsOverFindableCls()); + mHistManager.fill(HIST("TrackCuts/AntiPion/fTPCncls"), track.tpcNClsFound()); } } } - // reconstruct HMN candidates + // -------------------------> Reconstruct HNM candidates <------------------------------ + // - Based on the previously filled (anti)pion vectors + // - Fill QA histograms for kinematics of the pions and their combinations + // ------------------------------------------------------------------------------------- for (const auto& posPion : pion) { for (const auto& negPion : antipion) { - hnmutilities::reconstructHeavyNeutralMesons(posPion, negPion, vGGs, vHNMs); - - ROOT::Math::PtEtaPhiMVector temp = posPion + negPion; - - mHistManager.fill(HIST("TrackCuts/HMN/fInvMass_tracks"), temp.M()); - mHistManager.fill(HIST("TrackCuts/HMN/fPt_tracks"), temp.pt()); - mHistManager.fill(HIST("TrackCuts/HMN/fEta_tracks"), temp.eta()); - mHistManager.fill(HIST("TrackCuts/HMN/fPhi_tracks"), translatePhi(temp.phi())); - - mHistManager.fill(HIST("TrackCuts/HMN/PosDaughter/fInvMass"), posPion.M()); - mHistManager.fill(HIST("TrackCuts/HMN/PosDaughter/fPt"), posPion.pt()); - mHistManager.fill(HIST("TrackCuts/HMN/PosDaughter/fEta"), posPion.eta()); - mHistManager.fill(HIST("TrackCuts/HMN/PosDaughter/fPhi"), translatePhi(posPion.phi())); - - mHistManager.fill(HIST("TrackCuts/HMN/NegDaughter/fInvMass"), negPion.M()); - mHistManager.fill(HIST("TrackCuts/HMN/NegDaughter/fPt"), negPion.pt()); - mHistManager.fill(HIST("TrackCuts/HMN/NegDaughter/fEta"), negPion.eta()); - mHistManager.fill(HIST("TrackCuts/HMN/NegDaughter/fPhi"), translatePhi(negPion.phi())); + ROOT::Math::PtEtaPhiMVector vecPiPlPiMi = posPion + negPion; + hnmutilities::reconstructHeavyNeutralMesons(vecPiPlPiMi, vGGs, vHNMs); + + mHistManager.fill(HIST("HNM/Before/PiPlPiMi/fInvMassVsPt"), vecPiPlPiMi.M(), vecPiPlPiMi.pt()); + mHistManager.fill(HIST("HNM/Before/PiPlPiMi/fEta"), vecPiPlPiMi.eta()); + mHistManager.fill(HIST("HNM/Before/PiPlPiMi/fPhi"), RecoDecay::constrainAngle(vecPiPlPiMi.phi())); + + mHistManager.fill(HIST("HNM/Before/PosDaughter/fInvMass"), posPion.M()); + mHistManager.fill(HIST("HNM/Before/PosDaughter/fPt"), posPion.pt()); + mHistManager.fill(HIST("HNM/Before/PosDaughter/fEta"), posPion.eta()); + mHistManager.fill(HIST("HNM/Before/PosDaughter/fPhi"), RecoDecay::constrainAngle(posPion.phi())); + + mHistManager.fill(HIST("HNM/Before/NegDaughter/fInvMass"), negPion.M()); + mHistManager.fill(HIST("HNM/Before/NegDaughter/fPt"), negPion.pt()); + mHistManager.fill(HIST("HNM/Before/NegDaughter/fEta"), negPion.eta()); + mHistManager.fill(HIST("HNM/Before/NegDaughter/fPhi"), RecoDecay::constrainAngle(negPion.phi())); } } - processHNMs(vHNMs); // Contains QA of HMN properties + // ---------------------------> Process HNM candidates <-------------------------------- + // - Fill invMassVsPt histograms separated into HNM types (based on GG mass) and gamma reco method + // ------------------------------------------------------------------------------------- + processHNMs(vHNMs); } /// \brief Loop over the GG candidates, fill the mass/pt histograms and set the isPi0/isEta flags based on the reconstructed mass @@ -528,9 +508,9 @@ struct HeavyNeutralMeson { mHistManager.fill(HIST("GG/invMassVsPt_PCMEMC"), lightMeson->m(), lightMeson->pT()); } - if (lightMeson->m() > massWindowLightNeutralMesons->get("pi0_min") && lightMeson->m() < massWindowLightNeutralMesons->get("pi0_max")) { + if (lightMeson->m() > cfgMassWindowOmega->get("pi0_min") && lightMeson->m() < cfgMassWindowOmega->get("pi0_max")) { lightMeson->isPi0 = true; - } else if (lightMeson->m() > massWindowLightNeutralMesons->get("eta_min") && lightMeson->m() < massWindowLightNeutralMesons->get("eta_max")) { + } else if (lightMeson->m() > cfgMassWindowEtaPrime->get("eta_min") && lightMeson->m() < cfgMassWindowEtaPrime->get("eta_max")) { lightMeson->isEta = true; } else { vGGs.erase(vGGs.begin() + iGG); @@ -544,47 +524,74 @@ struct HeavyNeutralMeson { void processHNMs(std::vector& vHNMs) { int nHNMsBeforeMassCuts = vHNMs.size(); + for (unsigned int iHNM = 0; iHNM < vHNMs.size(); iHNM++) { auto heavyNeutralMeson = vHNMs.at(iHNM); - float massHNM = heavyNeutralMeson.m(cfgHNMMassCorrection); + if (heavyNeutralMeson.gg->reconstructionType == photonpair::kPCMPCM) { - if (heavyNeutralMeson.gg->isPi0) - mHistManager.fill(HIST("Omega/invMassVsPt_PCM"), massHNM, heavyNeutralMeson.pT()); - else if (heavyNeutralMeson.gg->isEta) - mHistManager.fill(HIST("EtaPrime/invMassVsPt_PCM"), massHNM, heavyNeutralMeson.pT()); - // QA - mHistManager.fill(HIST("TrackCuts/HMN/PCM/fInvMass"), massHNM); - mHistManager.fill(HIST("TrackCuts/HMN/PCM/fPt"), heavyNeutralMeson.pT()); - mHistManager.fill(HIST("TrackCuts/HMN/PCM/fEta"), heavyNeutralMeson.eta()); - mHistManager.fill(HIST("TrackCuts/HMN/PCM/fPhi"), translatePhi(heavyNeutralMeson.phi())); + if (heavyNeutralMeson.gg->isPi0) { + mHistManager.fill(HIST("HNM/Before/Omega/PCM/fInvMassVsPt"), massHNM, heavyNeutralMeson.pT()); + mHistManager.fill(HIST("HNM/Before/Omega/PCM/fEta"), heavyNeutralMeson.eta()); + mHistManager.fill(HIST("HNM/Before/Omega/PCM/fPhi"), RecoDecay::constrainAngle(heavyNeutralMeson.phi())); + } else if (heavyNeutralMeson.gg->isEta) { + mHistManager.fill(HIST("HNM/Before/EtaPrime/PCM/fInvMassVsPt"), massHNM, heavyNeutralMeson.pT()); + mHistManager.fill(HIST("HNM/Before/EtaPrime/PCM/fEta"), heavyNeutralMeson.eta()); + mHistManager.fill(HIST("HNM/Before/EtaPrime/PCM/fPhi"), RecoDecay::constrainAngle(heavyNeutralMeson.phi())); + } } else if (heavyNeutralMeson.gg->reconstructionType == photonpair::kEMCEMC) { - if (heavyNeutralMeson.gg->isPi0) - mHistManager.fill(HIST("Omega/invMassVsPt_EMC"), massHNM, heavyNeutralMeson.pT()); - else if (heavyNeutralMeson.gg->isEta) - mHistManager.fill(HIST("EtaPrime/invMassVsPt_EMC"), massHNM, heavyNeutralMeson.pT()); - // QA - mHistManager.fill(HIST("TrackCuts/HMN/EMC/fInvMass"), massHNM); - mHistManager.fill(HIST("TrackCuts/HMN/EMC/fPt"), heavyNeutralMeson.pT()); - mHistManager.fill(HIST("TrackCuts/HMN/EMC/fEta"), heavyNeutralMeson.eta()); - mHistManager.fill(HIST("TrackCuts/HMN/EMC/fPhi"), translatePhi(heavyNeutralMeson.phi())); + if (heavyNeutralMeson.gg->isPi0) { + mHistManager.fill(HIST("HNM/Before/Omega/EMC/fInvMassVsPt"), massHNM, heavyNeutralMeson.pT()); + mHistManager.fill(HIST("HNM/Before/Omega/EMC/fEta"), heavyNeutralMeson.eta()); + mHistManager.fill(HIST("HNM/Before/Omega/EMC/fPhi"), RecoDecay::constrainAngle(heavyNeutralMeson.phi())); + } else if (heavyNeutralMeson.gg->isEta) { + mHistManager.fill(HIST("HNM/Before/EtaPrime/EMC/fInvMassVsPt"), massHNM, heavyNeutralMeson.pT()); + mHistManager.fill(HIST("HNM/Before/EtaPrime/EMC/fEta"), heavyNeutralMeson.eta()); + mHistManager.fill(HIST("HNM/Before/EtaPrime/EMC/fPhi"), RecoDecay::constrainAngle(heavyNeutralMeson.phi())); + } } else { - if (heavyNeutralMeson.gg->isPi0) - mHistManager.fill(HIST("Omega/invMassVsPt_PCMEMC"), massHNM, heavyNeutralMeson.pT()); - else if (heavyNeutralMeson.gg->isEta) - mHistManager.fill(HIST("EtaPrime/invMassVsPt_PCMEMC"), massHNM, heavyNeutralMeson.pT()); - // QA - mHistManager.fill(HIST("TrackCuts/HMN/PCMEMC/fInvMass"), massHNM); - mHistManager.fill(HIST("TrackCuts/HMN/PCMEMC/fPt"), heavyNeutralMeson.pT()); - mHistManager.fill(HIST("TrackCuts/HMN/PCMEMC/fEta"), heavyNeutralMeson.eta()); - mHistManager.fill(HIST("TrackCuts/HMN/PCMEMC/fPhi"), translatePhi(heavyNeutralMeson.phi())); + if (heavyNeutralMeson.gg->isPi0) { + mHistManager.fill(HIST("HNM/Before/Omega/PCMEMC/fInvMassVsPt"), massHNM, heavyNeutralMeson.pT()); + mHistManager.fill(HIST("HNM/Before/Omega/PCMEMC/fEta"), heavyNeutralMeson.eta()); + mHistManager.fill(HIST("HNM/Before/Omega/PCMEMC/fPhi"), RecoDecay::constrainAngle(heavyNeutralMeson.phi())); + } else if (heavyNeutralMeson.gg->isEta) { + mHistManager.fill(HIST("HNM/Before/EtaPrime/PCMEMC/fInvMassVsPt"), massHNM, heavyNeutralMeson.pT()); + mHistManager.fill(HIST("HNM/Before/EtaPrime/PCMEMC/fEta"), heavyNeutralMeson.eta()); + mHistManager.fill(HIST("HNM/Before/EtaPrime/PCMEMC/fPhi"), RecoDecay::constrainAngle(heavyNeutralMeson.phi())); + } + } + + if (heavyNeutralMeson.gg->isPi0 && massHNM > cfgMassWindowOmega->get("omega_min") && massHNM < cfgMassWindowOmega->get("omega_max") && heavyNeutralMeson.gg->pT() / heavyNeutralMeson.pT() > cfgMinGGPtOverHNMPt) { + if (heavyNeutralMeson.gg->reconstructionType == photonpair::kPCMPCM) { + omegaPCM.emplace_back(heavyNeutralMeson.pT(), heavyNeutralMeson.eta(), RecoDecay::constrainAngle(heavyNeutralMeson.phi()), mMassOmega); + mHistManager.fill(HIST("HNM/After/Omega/PCM/fInvMassVsPt"), massHNM, heavyNeutralMeson.pT()); + mHistManager.fill(HIST("HNM/After/Omega/PCM/fEta"), heavyNeutralMeson.eta()); + mHistManager.fill(HIST("HNM/After/Omega/PCM/fPhi"), RecoDecay::constrainAngle(heavyNeutralMeson.phi())); + } else if (heavyNeutralMeson.gg->reconstructionType == photonpair::kEMCEMC) { + omegaEMC.emplace_back(heavyNeutralMeson.pT(), heavyNeutralMeson.eta(), RecoDecay::constrainAngle(heavyNeutralMeson.phi()), mMassOmega); + mHistManager.fill(HIST("HNM/After/Omega/EMC/fInvMassVsPt"), massHNM, heavyNeutralMeson.pT()); + mHistManager.fill(HIST("HNM/After/Omega/EMC/fEta"), heavyNeutralMeson.eta()); + mHistManager.fill(HIST("HNM/After/Omega/EMC/fPhi"), RecoDecay::constrainAngle(heavyNeutralMeson.phi())); + } + } else if (heavyNeutralMeson.gg->isEta && massHNM > cfgMassWindowEtaPrime->get("etaprime_min") && massHNM < cfgMassWindowEtaPrime->get("etaprime_max") && heavyNeutralMeson.gg->pT() / heavyNeutralMeson.pT() > cfgMinGGPtOverHNMPt) { + if (heavyNeutralMeson.gg->reconstructionType == photonpair::kPCMPCM) { + etaPrimePCM.emplace_back(heavyNeutralMeson.pT(), heavyNeutralMeson.eta(), RecoDecay::constrainAngle(heavyNeutralMeson.phi()), mMassEtaPrime); + mHistManager.fill(HIST("HNM/After/EtaPrime/PCM/fInvMassVsPt"), massHNM, heavyNeutralMeson.pT()); + mHistManager.fill(HIST("HNM/After/EtaPrime/PCM/fEta"), heavyNeutralMeson.eta()); + mHistManager.fill(HIST("HNM/After/EtaPrime/PCM/fPhi"), RecoDecay::constrainAngle(heavyNeutralMeson.phi())); + } else if (heavyNeutralMeson.gg->reconstructionType == photonpair::kEMCEMC) { + etaPrimeEMC.emplace_back(heavyNeutralMeson.pT(), heavyNeutralMeson.eta(), RecoDecay::constrainAngle(heavyNeutralMeson.phi()), mMassEtaPrime); + mHistManager.fill(HIST("HNM/After/EtaPrime/EMC/fInvMassVsPt"), massHNM, heavyNeutralMeson.pT()); + mHistManager.fill(HIST("HNM/After/EtaPrime/EMC/fEta"), heavyNeutralMeson.eta()); + mHistManager.fill(HIST("HNM/After/EtaPrime/EMC/fPhi"), RecoDecay::constrainAngle(heavyNeutralMeson.phi())); + } + } else { + vHNMs.erase(vHNMs.begin() + iHNM); + iHNM--; } } mHistManager.fill(HIST("Event/nHeavyNeutralMesons"), nHNMsBeforeMassCuts, vHNMs.size()); } }; -WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& cfgc) -{ - return WorkflowSpec{adaptAnalysisTask(cfgc)}; -} +WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& cfgc) { return WorkflowSpec{adaptAnalysisTask(cfgc)}; } diff --git a/PWGEM/PhotonMeson/Tasks/emcalBcWisePi0.cxx b/PWGEM/PhotonMeson/Tasks/emcalBcWisePi0.cxx new file mode 100644 index 00000000000..2aa8bd44889 --- /dev/null +++ b/PWGEM/PhotonMeson/Tasks/emcalBcWisePi0.cxx @@ -0,0 +1,316 @@ +// Copyright 2019-2024 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// 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. +// +/// +/// \file emcalBcWisePi0.cxx +/// +/// \brief Task that extracts pi0s from BC wise derived data of EMCal clusters +/// +/// \author Nicolas Strangmann (nicolas.strangmann@cern.ch) Goethe University Frankfurt +/// + +#include "Framework/runDataProcessing.h" +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" + +#include "TString.h" +#include "Math/Vector4D.h" +#include "Math/Vector3D.h" +#include "Math/LorentzRotation.h" +#include "Math/Rotation3D.h" +#include "Math/AxisAngle.h" + +#include "CommonConstants/MathConstants.h" +#include "EMCALBase/Geometry.h" +#include "PWGEM/PhotonMeson/DataModel/bcWiseTables.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; + +using SelectedClusters = soa::Filtered; +using SelectedMCClusters = soa::Filtered>; + +struct EmcalBcWisePi0 { + HistogramRegistry mHistManager{"EmcalGammaGammaBcWiseHistograms"}; + + Configurable cfgRequirekTVXinEMC{"cfgRequirekTVXinEMC", true, "Reconstruct pi0s only in kTVXinEMC triggered BCs"}; + Configurable cfgSelectOnlyUniqueAmbiguous{"cfgSelectOnlyUniqueAmbiguous", 0, "0: all clusters, 1: only unique clusters, 2: only ambiguous clusters"}; + + Configurable cfgClusterDefinition{"cfgClusterDefinition", 13, "Clusterizer to be selected, e.g. 13 for kV3MostSplitLowSeed"}; + Configurable cfgMinClusterEnergy{"cfgMinClusterEnergy", 700, "Minimum energy of selected clusters (MeV)"}; + Configurable cfgMinM02{"cfgMinM02", 1000, "Minimum M02 of selected clusters (x1000)"}; + Configurable cfgMaxM02{"cfgMaxM02", 7000, "Maximum M02 of selected clusters (x1000)"}; + Configurable cfgMinTime{"cfgMinTime", -1500, "Minimum time of selected clusters (10 ps)"}; + Configurable cfgMaxTime{"cfgMaxTime", 1500, "Maximum time of selected clusters (10 ps)"}; + Configurable cfgRapidityCut{"cfgRapidityCut", 0.8f, "Maximum absolute rapidity of counted particles"}; + Configurable cfgMinOpenAngle{"cfgMinOpenAngle", 0.0202, "Minimum opening angle between photons"}; + Configurable cfgDistanceToEdge{"cfgDistanceToEdge", 1, "Distance to edge in cells required for rotated cluster to be accepted"}; + Configurable cfgBGEventDownsampling{"cfgBGEventDownsampling", 1, "Only calculate background for every n-th event (performance reasons in PbPb)"}; + + static constexpr float DefaultCentralityWindow[2] = {-1., 101.}; + Configurable> cfgCentralityWindow{"cfgCentralityWindow", {DefaultCentralityWindow, 2, {"Min_Centrality", "Max_Centrality"}}, "Select centrality window (also requires unique collision)"}; + + Configurable cfgIsMC{"cfgIsMC", false, "Flag to indicate if the task is running on MC data and should fill MC histograms"}; + + Filter clusterDefinitionFilter = aod::bcwisecluster::storedDefinition == cfgClusterDefinition; + Filter energyFilter = aod::bcwisecluster::storedE > cfgMinClusterEnergy; + Filter m02Filter = (aod::bcwisecluster::storedNCells == 1 || (aod::bcwisecluster::storedM02 > cfgMinM02 && aod::bcwisecluster::storedM02 < cfgMaxM02)); + Filter timeFilter = (aod::bcwisecluster::storedTime > cfgMinTime && aod::bcwisecluster::storedTime < cfgMaxTime); + + emcal::Geometry* emcalGeom; + + void init(InitContext const&) + { + emcalGeom = emcal::Geometry::GetInstanceFromRunNumber(300000); + const int nEventBins = 8; + mHistManager.add("Event/nBCs", "Number of BCs;;#bf{#it{N}_{BC}}", HistType::kTH1F, {{nEventBins, -0.5, 7.5}}); + const TString binLabels[nEventBins] = {"All", "FT0", "TVX", "kTVXinEMC", "Cell", "Cluster", "NoBorder", "Collision"}; + for (int iBin = 0; iBin < nEventBins; iBin++) + mHistManager.get(HIST("Event/nBCs"))->GetXaxis()->SetBinLabel(iBin + 1, binLabels[iBin]); + + mHistManager.add("Event/nCollPerBC", "Number of collisions per BC;#bf{#it{N}_{coll}};#bf{#it{N}_{BC}}", HistType::kTH1F, {{5, -0.5, 4.5}}); + mHistManager.add("Event/Z1VsZ2", "Z vertex positions for BCs with two collisions;#bf{#it{z}_{vtx}^{1} (cm)};#bf{#it{z}_{vtx}^{2} (cm)}", HistType::kTH2F, {{150, -15, 15}, {150, -15, 15}}); + mHistManager.add("Event/dZ", "Distance between vertices for BCs with two collisions;#bf{#Delta #it{z}_{vtx} (cm)};#bf{#it{N}_{BC}}", HistType::kTH1F, {{600, -30, 30}}); + + mHistManager.add("Event/Centrality", "FT0M centrality;FT0M centrality (%);#bf{#it{N}_{BC} (only BCs containing exactly 1 collision)}", HistType::kTH1F, {{100, 0., 100.}}); + mHistManager.add("Event/CentralityVsAmplitude", "FT0M AmplitudeVsCentrality;FT0M Centrality;FT0M Amplitude", HistType::kTH2F, {{105, 0, 105}, {600, 0, 300000}}); + + mHistManager.add("Cluster/E", "Energy of cluster;#bf{#it{E} (GeV)};#bf{#it{N}_{clusters}}", HistType::kTH1F, {{200, 0, 20}}); + mHistManager.add("Cluster/M02", "Shape of cluster;#bf{#it{M}_{02}};#bf{#it{N}_{clusters}}", HistType::kTH1F, {{200, 0, 2}}); + mHistManager.add("Cluster/Time", "Time of cluster;#bf{#it{t} (ns)};#bf{#it{N}_{clusters}}", HistType::kTH1F, {{200, -100, 100}}); + mHistManager.add("Cluster/NCells", "Number of cells per cluster;#bf{#it{N}_{cells}};#bf{#it{N}_{clusters}}", HistType::kTH1F, {{51, 0., 50.5}}); + mHistManager.add("Cluster/Exotic", "Is cluster exotic?;#bf{Exotic?};#bf{#it{N}_{clusters}}", HistType::kTH1F, {{2, -0.5, 1.5}}); + mHistManager.add("Cluster/EtaPhi", "Eta/Phi distribution of clusters;#eta;#phi", HistType::kTH2F, {{400, -0.8, 0.8}, {400, 0, constants::math::TwoPI}}); + + mHistManager.add("GG/invMassVsPt", "Invariant mass and pT of meson candidates;#bf{#it{M}^{#gamma#gamma} (GeV/#it{c}^{2})};#bf{#it{p}_{T}^{#gamma#gamma} (GeV/#it{c})}", HistType::kTH2F, {{200, 0., 0.4}, {200, 0., 20.}}); + mHistManager.add("GG/invMassVsPtBackground", "Invariant mass and pT of background meson candidates;#bf{#it{M}^{#gamma#gamma} (GeV/#it{c}^{2})};#bf{#it{p}_{T}^{#gamma#gamma} (GeV/#it{c})}", HistType::kTH2F, {{200, 0., 0.4}, {200, 0., 20.}}); + + if (cfgIsMC) { + mHistManager.add("True/clusterERecVsETrue", "True vs reconstructed energy of cluster inducing particle;#bf{#it{E}_{rec} (GeV)};#bf{#it{E}_{true}^{cls inducing part} (GeV)}", HistType::kTH2F, {{200, 0, 20}, {200, 0, 20}}); + mHistManager.add("True/PtRecVsPtTrue", "True vs reconstructed pT of true pi0s;#bf{#it{p}_{T}^{rec} (GeV/#it{c})};#bf{#it{p}_{T}^{true} (GeV/#it{c})}", HistType::kTH2F, {{200, 0., 20.}, {200, 0., 20.}}); + mHistManager.add("True/invMassVsPt_Primary", "Invariant mass and pT of meson candidates", HistType::kTH2F, {{200, 0., 0.4}, {200, 0., 20.}}); + mHistManager.add("True/invMassVsPt_Secondary", "Invariant mass and pT of meson candidates", HistType::kTH2F, {{200, 0., 0.4}, {200, 0., 20.}}); + mHistManager.add("True/invMassVsPt_HadronicShower", "Invariant mass and pT of meson candidates", HistType::kTH2F, {{200, 0., 0.4}, {200, 0., 20.}}); + + mHistManager.add("Generated/pi0_AllBCs", "pT spectrum of generated pi0s in all BCs;#bf{#it{p}_{T} (GeV/#it{c})};#bf{#it{N}_{#pi^{0}}^{gen}}", HistType::kTH1F, {{200, 0, 20}}); + mHistManager.add("Generated/pi0_TVX", "pT spectrum of generated pi0s in TVX triggered BCs;#bf{#it{p}_{T} (GeV/#it{c})};#bf{#it{N}_{#pi^{0}}^{gen}}", HistType::kTH1F, {{200, 0, 20}}); + mHistManager.add("Generated/pi0_kTVXinEMC", "pT spectrum of generated pi0s in kTVXinEMC triggered BCs;#bf{#it{p}_{T} (GeV/#it{c})};#bf{#it{N}_{#pi^{0}}^{gen}}", HistType::kTH1F, {{200, 0, 20}}); + } + } + + /// \brief returns if cluster is too close to edge of EMCal + bool isTooCloseToEdge(const int cellID, const int DistanceToBorder = 1) + { + if (DistanceToBorder <= 0) + return false; + if (cellID < 0) + return true; + + // check distance to border in case the cell is okay + auto [iSupMod, iMod, iPhi, iEta] = emcalGeom->GetCellIndex(cellID); + auto [irow, icol] = emcalGeom->GetCellPhiEtaIndexInSModule(iSupMod, iMod, iPhi, iEta); + int iRowLast = (emcalGeom->GetSMType(iSupMod) == o2::emcal::EMCALSMType::EMCAL_THIRD || emcalGeom->GetSMType(iSupMod) == o2::emcal::EMCALSMType::DCAL_EXT) ? 8 : 24; + + return (irow < DistanceToBorder || (iRowLast - irow) <= DistanceToBorder); + } + + void fillEventHists(const auto& bc, const auto& collisions, const auto& clusters) + { + mHistManager.fill(HIST("Event/nBCs"), 0); + if (bc.hasFT0()) + mHistManager.fill(HIST("Event/nBCs"), 1); + if (bc.hasTVX()) + mHistManager.fill(HIST("Event/nBCs"), 2); + if (bc.haskTVXinEMC()) + mHistManager.fill(HIST("Event/nBCs"), 3); + if (bc.hasEMCCell()) + mHistManager.fill(HIST("Event/nBCs"), 4); + if (clusters.size() > 0) + mHistManager.fill(HIST("Event/nBCs"), 5); + if (bc.hasNoTFROFBorder()) + mHistManager.fill(HIST("Event/nBCs"), 6); + if (collisions.size() > 0) + mHistManager.fill(HIST("Event/nBCs"), 7); + + if (collisions.size() == 1) { + mHistManager.fill(HIST("Event/Centrality"), collisions.iteratorAt(0).centrality()); + mHistManager.fill(HIST("Event/CentralityVsAmplitude"), collisions.iteratorAt(0).centrality(), bc.ft0Amplitude()); + } else { + mHistManager.fill(HIST("Event/CentralityVsAmplitude"), 103, bc.ft0Amplitude()); + } + + mHistManager.fill(HIST("Event/nCollPerBC"), collisions.size()); + if (collisions.size() == 2) { + mHistManager.fill(HIST("Event/Z1VsZ2"), collisions.iteratorAt(0).zVtx(), collisions.iteratorAt(1).zVtx()); + mHistManager.fill(HIST("Event/dZ"), collisions.iteratorAt(0).zVtx() - collisions.iteratorAt(1).zVtx()); + } + } + + void fillClusterHists(const auto& clusters) + { + for (const auto& cluster : clusters) { + mHistManager.fill(HIST("Cluster/E"), cluster.e()); + mHistManager.fill(HIST("Cluster/M02"), cluster.m02()); + mHistManager.fill(HIST("Cluster/Time"), cluster.time()); + mHistManager.fill(HIST("Cluster/NCells"), cluster.nCells()); + mHistManager.fill(HIST("Cluster/EtaPhi"), cluster.eta(), cluster.phi()); + mHistManager.fill(HIST("Cluster/Exotic"), cluster.isExotic()); + } + } + + void reconstructMesons(const auto& clusters, int bcId) + { + for (const auto& [g1, g2] : soa::combinations(soa::CombinationsStrictlyUpperIndexPolicy(clusters, clusters))) { + ROOT::Math::PtEtaPhiMVector v1(g1.pt(), g1.eta(), g1.phi(), 0.); + ROOT::Math::PtEtaPhiMVector v2(g2.pt(), g2.eta(), g2.phi(), 0.); + ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; + if (std::fabs(v12.Rapidity()) > cfgRapidityCut) + continue; + + float openingAngle12 = std::acos(v1.Vect().Dot(v2.Vect()) / (v1.P() * v2.P())); + if (openingAngle12 < cfgMinOpenAngle) + continue; + + mHistManager.fill(HIST("GG/invMassVsPt"), v12.M(), v12.Pt()); + + if (clusters.size() < 3) + continue; + + if (bcId % cfgBGEventDownsampling != 0) + continue; + + // "else: Calculate background" + + ROOT::Math::AxisAngle rotationAxis(v12.Vect(), constants::math::PIHalf); + ROOT::Math::Rotation3D rotationMatrix(rotationAxis); + for (ROOT::Math::PtEtaPhiMVector vi : {v1, v2}) { + + vi = rotationMatrix * vi; + + try { + int iCellID = emcalGeom->GetAbsCellIdFromEtaPhi(vi.Eta(), vi.Phi()); + if (isTooCloseToEdge(iCellID, cfgDistanceToEdge)) + continue; + } catch (o2::emcal::InvalidPositionException& e) { + continue; + } + + for (const auto& g3 : clusters) { + if (g3.globalIndex() == g1.globalIndex() || g3.globalIndex() == g2.globalIndex()) + continue; + + ROOT::Math::PtEtaPhiMVector v3(g3.pt(), g3.eta(), g3.phi(), 0.); + + float openingAnglei3 = std::acos(vi.Vect().Dot(v3.Vect()) / (vi.P() * v3.P())); + if (openingAnglei3 < cfgMinOpenAngle) + continue; + + ROOT::Math::PtEtaPhiMVector vBG = v3 + vi; + + mHistManager.fill(HIST("GG/invMassVsPtBackground"), vBG.M(), vBG.Pt()); + } + } + } + } + void reconstructTrueMesons(const auto& clusters, const auto& mcPi0s) + { + for (const auto& [g1, g2] : soa::combinations(soa::CombinationsStrictlyUpperIndexPolicy(clusters, clusters))) { + if (g1.pi0ID() == -1 || g1.pi0ID() != g2.pi0ID()) + continue; + + ROOT::Math::PtEtaPhiMVector v1(g1.pt(), g1.eta(), g1.phi(), 0.); + ROOT::Math::PtEtaPhiMVector v2(g2.pt(), g2.eta(), g2.phi(), 0.); + ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; + if (std::fabs(v12.Rapidity()) > cfgRapidityCut) + continue; + + float openingAngle12 = std::acos(v1.Vect().Dot(v2.Vect()) / (v1.P() * v2.P())); + if (openingAngle12 < cfgMinOpenAngle) + continue; + + const auto& mcPi0 = mcPi0s.iteratorAt(g1.pi0ID() - mcPi0s.offset()); + + mHistManager.fill(HIST("True/PtRecVsPtTrue"), v12.Pt(), mcPi0.pt()); + + if (mcPi0.isPrimary()) + mHistManager.fill(HIST("True/invMassVsPt_Primary"), v12.M(), v12.Pt()); + else if (mcPi0.isFromWD()) + mHistManager.fill(HIST("True/invMassVsPt_Secondary"), v12.M(), v12.Pt()); + else + mHistManager.fill(HIST("True/invMassVsPt_HadronicShower"), v12.M(), v12.Pt()); + } + } + + bool isBCSelected(const auto& bc, const auto& collisions) + { + if (cfgRequirekTVXinEMC && !bc.haskTVXinEMC()) + return false; + + if (cfgCentralityWindow->get("Min_Centrality") > -0.5 || cfgCentralityWindow->get("Max_Centrality") < 100.5) { // Centrality window is set + if (collisions.size() != 1) + return false; + if (collisions.iteratorAt(0).centrality() < cfgCentralityWindow->get("Min_Centrality") || collisions.iteratorAt(0).centrality() > cfgCentralityWindow->get("Max_Centrality")) + return false; + } + + if (cfgSelectOnlyUniqueAmbiguous == 1 && collisions.size() != 1) + return false; + if (cfgSelectOnlyUniqueAmbiguous == 2 && collisions.size() == 1) + return false; + + return true; + } + + void fillGeneratedPi0Hists(const auto& mcPi0s, const auto& bc) + { + for (const auto& mcPi0 : mcPi0s) { + mHistManager.fill(HIST("Generated/pi0_AllBCs"), mcPi0.pt()); + if (bc.hasTVX()) + mHistManager.fill(HIST("Generated/pi0_TVX"), mcPi0.pt()); + if (bc.haskTVXinEMC()) + mHistManager.fill(HIST("Generated/pi0_kTVXinEMC"), mcPi0.pt()); + } + } + + void process(aod::BCWiseBCs::iterator const& bc, aod::BCWiseCollisions const& collisions, SelectedClusters const& clusters) + { + if (!isBCSelected(bc, collisions)) + return; + + fillEventHists(bc, collisions, clusters); + + fillClusterHists(clusters); + + reconstructMesons(clusters, bc.globalIndex()); + } + + void processMCInfo(aod::BCWiseBCs::iterator const& bc, aod::BCWiseCollisions const& collisions, SelectedMCClusters const& clusters, aod::BCWiseMCPi0s const& mcPi0s) + { + if (!cfgIsMC) { + LOG(fatal) << "MC processing is not enabled, but the task is running on MC data. Please set cfgIsMC to true."; + return; + } + + fillGeneratedPi0Hists(mcPi0s, bc); // Fill before BC selection to also store pi0s in BCs that were not triggered + + if (!isBCSelected(bc, collisions)) + return; + + for (const auto& cluster : clusters) + mHistManager.fill(HIST("True/clusterERecVsETrue"), cluster.e(), cluster.trueE()); + + reconstructTrueMesons(clusters, mcPi0s); + } + PROCESS_SWITCH(EmcalBcWisePi0, processMCInfo, "Run true and gen", false); +}; + +WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& cfgc) { return WorkflowSpec{adaptAnalysisTask(cfgc)}; } diff --git a/PWGEM/PhotonMeson/Utils/HNMUtilities.h b/PWGEM/PhotonMeson/Utils/HNMUtilities.h index c784fcabc97..bb985686285 100644 --- a/PWGEM/PhotonMeson/Utils/HNMUtilities.h +++ b/PWGEM/PhotonMeson/Utils/HNMUtilities.h @@ -36,11 +36,9 @@ #include "Common/DataModel/TrackSelectionTables.h" #include "EventFiltering/filterTables.h" -using namespace o2::aod::pwgem::photonmeson; - -// -------> Struct to store photons from EMC clusters or V0s namespace o2::aod::pwgem::photonmeson::hnmutilities { +// -------> Struct to store photons from EMC clusters or V0s struct Photon { Photon(float px, float py, float pz, bool isFromConversion) : px(px), py(py), pz(pz), pt(std::sqrt(px * px + py * py)), isFromConversion(isFromConversion) { @@ -125,12 +123,13 @@ struct HeavyNeutralMeson { float phi() const { return vHeavyNeutralMeson.Phi(); } }; -float smPhiEdges[9] = {1.75, 2.1, 2.45, 2.8, 3.14, 4., 4.89, 5.24, 5.58}; +const int nSMEdges = 9; +float smPhiEdges[nSMEdges] = {1.75, 2.1, 2.45, 2.8, 3.14, 4., 4.89, 5.24, 5.58}; -unsigned short getSMNumber(float eta, float phi) +int getSMNumber(float eta, float phi) { - unsigned short smNumber = 0; - for (int iPhiInterval = 0; iPhiInterval < 9; iPhiInterval++) { + int smNumber = 0; + for (int iPhiInterval = 0; iPhiInterval < nSMEdges; iPhiInterval++) { if (phi > smPhiEdges[iPhiInterval]) smNumber = 2 * (iPhiInterval + 1); } @@ -148,7 +147,7 @@ void storeGammasInVector(C clusters, V v0s, std::vector& vPhotons, std:: for (const auto& cluster : clusters) { float eta = cluster.eta(); float phi = cluster.phi(); - unsigned short smNumber = getSMNumber(eta, phi); + int smNumber = getSMNumber(eta, phi); // LOG(info) << "Shifting in sm " << smNumber << ", eta/phi = " << eta << " / " << phi << " to eta/phi = " << eta + EMCEtaShift[getSMNumber(eta, phi)] << " / " << phi + EMCPhiShift[getSMNumber(eta, phi)]; eta += EMCEtaShift[smNumber]; phi += EMCPhiShift[smNumber]; @@ -179,31 +178,11 @@ void reconstructGGs(std::vector vPhotons, std::vector& v } } -/// \brief Reconstruct heavy neutral mesons from tracks and GG candidates and fill them into the vHNMs vector -template -void reconstructHeavyNeutralMesons(Track const& tracks, std::vector& vGGs, std::vector& vHNMs) // ToDO: Pion comb. in main code, tracks -> 4-vectors -{ - vHNMs.clear(); - for (const auto& posTrack : tracks) { - if (!posTrack.isGlobalTrack() || posTrack.sign() < 0) - continue; - for (const auto& negTrack : tracks) { - if (!negTrack.isGlobalTrack() || negTrack.sign() > 0) - continue; - for (size_t iGG = 0; iGG < vGGs.size(); iGG++) { - HeavyNeutralMeson heavyNeutralMeson(&vGGs.at(iGG), posTrack.energy(constants::physics::MassPiPlus) + negTrack.energy(constants::physics::MassPiMinus), posTrack.px() + negTrack.px(), posTrack.py() + negTrack.py(), posTrack.pz() + negTrack.pz()); - vHNMs.push_back(heavyNeutralMeson); - } - } - } -} - -/// \brief Reconstruct heavy neutral mesons from pion and antipion and GG candidates and fill them into the vHNMs vector -void reconstructHeavyNeutralMesons(ROOT::Math::PtEtaPhiMVector const& posPion, ROOT::Math::PtEtaPhiMVector const& negPion, std::vector& vGGs, std::vector& vHNMs) // ToDO: Pion comb. in main code, tracks -> 4-vectors +/// \brief Reconstruct heavy neutral mesons from the given pion, antipion and the GG candidates and add them to the vHNMs vector +void reconstructHeavyNeutralMesons(ROOT::Math::PtEtaPhiMVector const& vecPiPlPiMi, std::vector& vGGs, std::vector& vHNMs) { - const ROOT::Math::PtEtaPhiMVector trackSum = posPion + negPion; for (size_t iGG = 0; iGG < vGGs.size(); iGG++) { - HeavyNeutralMeson heavyNeutralMeson(&vGGs.at(iGG), trackSum.E(), trackSum.Px(), trackSum.Py(), trackSum.Pz()); + HeavyNeutralMeson heavyNeutralMeson(&vGGs.at(iGG), vecPiPlPiMi.E(), vecPiPlPiMi.Px(), vecPiPlPiMi.Py(), vecPiPlPiMi.Pz()); vHNMs.push_back(heavyNeutralMeson); } } diff --git a/PWGHF/Core/HfMlResponseDplusToPiKPi.h b/PWGHF/Core/HfMlResponseDplusToPiKPi.h index 292ddcccb95..42dde77eda7 100644 --- a/PWGHF/Core/HfMlResponseDplusToPiKPi.h +++ b/PWGHF/Core/HfMlResponseDplusToPiKPi.h @@ -25,9 +25,9 @@ // Fill the map of available input features // the key is the feature's name (std::string) // the value is the corresponding value in EnumInputFeatures -#define FILL_MAP_DPLUS(FEATURE) \ - { \ -#FEATURE, static_cast < uint8_t>(InputFeaturesDplusToPiKPi::FEATURE) \ +#define FILL_MAP_DPLUS(FEATURE) \ + { \ + #FEATURE, static_cast(InputFeaturesDplusToPiKPi::FEATURE) \ } // Check if the index of mCachedIndices (index associated to a FEATURE) @@ -104,9 +104,8 @@ class HfMlResponseDplusToPiKPi : public HfMlResponse /// \param prong1 is the candidate's prong1 /// \param prong2 is the candidate's prong2 /// \return inputFeatures vector - template - std::vector getInputFeatures(T1 const& candidate, - T2 const& prong0, T2 const& prong1, T2 const& prong2) + template + std::vector getInputFeatures(T1 const& candidate) { std::vector inputFeatures; @@ -130,26 +129,26 @@ class HfMlResponseDplusToPiKPi : public HfMlResponse CHECK_AND_FILL_VEC_DPLUS(maxNormalisedDeltaIP); CHECK_AND_FILL_VEC_DPLUS(chi2PCA); // TPC PID variables - CHECK_AND_FILL_VEC_DPLUS_FULL(prong0, tpcNSigmaPi0, tpcNSigmaPi); - CHECK_AND_FILL_VEC_DPLUS_FULL(prong0, tpcNSigmaKa0, tpcNSigmaKa); - CHECK_AND_FILL_VEC_DPLUS_FULL(prong1, tpcNSigmaPi1, tpcNSigmaPi); - CHECK_AND_FILL_VEC_DPLUS_FULL(prong1, tpcNSigmaKa1, tpcNSigmaKa); - CHECK_AND_FILL_VEC_DPLUS_FULL(prong2, tpcNSigmaPi2, tpcNSigmaPi); - CHECK_AND_FILL_VEC_DPLUS_FULL(prong2, tpcNSigmaKa2, tpcNSigmaKa); + CHECK_AND_FILL_VEC_DPLUS_FULL(candidate, tpcNSigmaPi0, nSigTpcPi0); + CHECK_AND_FILL_VEC_DPLUS_FULL(candidate, tpcNSigmaKa0, nSigTpcKa0); + CHECK_AND_FILL_VEC_DPLUS_FULL(candidate, tpcNSigmaPi1, nSigTpcPi1); + CHECK_AND_FILL_VEC_DPLUS_FULL(candidate, tpcNSigmaKa1, nSigTpcKa1); + CHECK_AND_FILL_VEC_DPLUS_FULL(candidate, tpcNSigmaPi2, nSigTpcPi2); + CHECK_AND_FILL_VEC_DPLUS_FULL(candidate, tpcNSigmaKa2, nSigTpcKa2); // TOF PID variables - CHECK_AND_FILL_VEC_DPLUS_FULL(prong0, tofNSigmaPi0, tofNSigmaPi); - CHECK_AND_FILL_VEC_DPLUS_FULL(prong0, tofNSigmaKa0, tofNSigmaKa); - CHECK_AND_FILL_VEC_DPLUS_FULL(prong1, tofNSigmaPi1, tofNSigmaPi); - CHECK_AND_FILL_VEC_DPLUS_FULL(prong1, tofNSigmaKa1, tofNSigmaKa); - CHECK_AND_FILL_VEC_DPLUS_FULL(prong2, tofNSigmaPi2, tofNSigmaPi); - CHECK_AND_FILL_VEC_DPLUS_FULL(prong2, tofNSigmaKa2, tofNSigmaKa); + CHECK_AND_FILL_VEC_DPLUS_FULL(candidate, tofNSigmaPi0, nSigTofPi0); + CHECK_AND_FILL_VEC_DPLUS_FULL(candidate, tofNSigmaKa0, nSigTofKa0); + CHECK_AND_FILL_VEC_DPLUS_FULL(candidate, tofNSigmaPi1, nSigTofPi1); + CHECK_AND_FILL_VEC_DPLUS_FULL(candidate, tofNSigmaKa1, nSigTofKa1); + CHECK_AND_FILL_VEC_DPLUS_FULL(candidate, tofNSigmaPi2, nSigTofPi2); + CHECK_AND_FILL_VEC_DPLUS_FULL(candidate, tofNSigmaKa2, nSigTofKa2); // Combined PID variables - CHECK_AND_FILL_VEC_DPLUS_FULL(prong0, tpcTofNSigmaPi0, tpcTofNSigmaPi); - CHECK_AND_FILL_VEC_DPLUS_FULL(prong1, tpcTofNSigmaPi1, tpcTofNSigmaPi); - CHECK_AND_FILL_VEC_DPLUS_FULL(prong2, tpcTofNSigmaPi2, tpcTofNSigmaPi); - CHECK_AND_FILL_VEC_DPLUS_FULL(prong0, tpcTofNSigmaKa0, tpcTofNSigmaKa); - CHECK_AND_FILL_VEC_DPLUS_FULL(prong1, tpcTofNSigmaKa1, tpcTofNSigmaKa); - CHECK_AND_FILL_VEC_DPLUS_FULL(prong2, tpcTofNSigmaKa2, tpcTofNSigmaKa); + CHECK_AND_FILL_VEC_DPLUS_FULL(candidate, tpcTofNSigmaPi0, tpcTofNSigmaPi0); + CHECK_AND_FILL_VEC_DPLUS_FULL(candidate, tpcTofNSigmaPi1, tpcTofNSigmaPi1); + CHECK_AND_FILL_VEC_DPLUS_FULL(candidate, tpcTofNSigmaPi2, tpcTofNSigmaPi2); + CHECK_AND_FILL_VEC_DPLUS_FULL(candidate, tpcTofNSigmaKa0, tpcTofNSigmaKa0); + CHECK_AND_FILL_VEC_DPLUS_FULL(candidate, tpcTofNSigmaKa1, tpcTofNSigmaKa1); + CHECK_AND_FILL_VEC_DPLUS_FULL(candidate, tpcTofNSigmaKa2, tpcTofNSigmaKa2); } } diff --git a/PWGHF/Core/HfMlResponseDsToKKPi.h b/PWGHF/Core/HfMlResponseDsToKKPi.h index 1b27d52adde..ccb6a99e371 100644 --- a/PWGHF/Core/HfMlResponseDsToKKPi.h +++ b/PWGHF/Core/HfMlResponseDsToKKPi.h @@ -81,6 +81,18 @@ break; \ } +// Variation of CHECK_AND_FILL_VEC_DS_OBJECT_SIGNED(OBJECT, FEATURE, GETTER1, GETTER2) +// where GETTER1 and GETTER2 are methods of the OBJECT +#define CHECK_AND_FILL_VEC_DS_SIGNED(OBJECT, FEATURE, GETTER1, GETTER2) \ + case static_cast(InputFeaturesDsToKKPi::FEATURE): { \ + if (caseDsToKKPi) { \ + inputFeatures.emplace_back(OBJECT.GETTER1()); \ + } else { \ + inputFeatures.emplace_back(OBJECT.GETTER2()); \ + } \ + break; \ + } + namespace o2::analysis { enum class InputFeaturesDsToKKPi : uint8_t { @@ -148,9 +160,8 @@ class HfMlResponseDsToKKPi : public HfMlResponse /// \param prong2 is the candidate's prong2 /// \param caseDsToKKPi used to divide the case DsToKKPi from DsToPiKK /// \return inputFeatures vector - template - std::vector getInputFeatures(T1 const& candidate, - T2 const& prong0, T2 const& prong1, T2 const& prong2, bool const& caseDsToKKPi) + template + std::vector getInputFeatures(T1 const& candidate, bool const caseDsToKKPi) { std::vector inputFeatures; @@ -174,33 +185,33 @@ class HfMlResponseDsToKKPi : public HfMlResponse CHECK_AND_FILL_VEC_DS(impactParameterZ0); CHECK_AND_FILL_VEC_DS(impactParameterZ1); CHECK_AND_FILL_VEC_DS(impactParameterZ2); - // TPC PID variables - CHECK_AND_FILL_VEC_DS_FULL(prong0, nSigTpcPi0, tpcNSigmaPi); - CHECK_AND_FILL_VEC_DS_FULL(prong1, nSigTpcPi1, tpcNSigmaPi); - CHECK_AND_FILL_VEC_DS_FULL(prong2, nSigTpcPi2, tpcNSigmaPi); - CHECK_AND_FILL_VEC_DS_FULL(prong0, nSigTpcKa0, tpcNSigmaKa); - CHECK_AND_FILL_VEC_DS_FULL(prong1, nSigTpcKa1, tpcNSigmaKa); - CHECK_AND_FILL_VEC_DS_FULL(prong2, nSigTpcKa2, tpcNSigmaKa); - CHECK_AND_FILL_VEC_DS_FULL(prong0, nSigTofPi0, tofNSigmaPi); - CHECK_AND_FILL_VEC_DS_FULL(prong1, nSigTofPi1, tofNSigmaPi); - CHECK_AND_FILL_VEC_DS_FULL(prong2, nSigTofPi2, tofNSigmaPi); - CHECK_AND_FILL_VEC_DS_FULL(prong0, nSigTofKa0, tofNSigmaKa); - CHECK_AND_FILL_VEC_DS_FULL(prong1, nSigTofKa1, tofNSigmaKa); - CHECK_AND_FILL_VEC_DS_FULL(prong2, nSigTofKa2, tofNSigmaKa); - CHECK_AND_FILL_VEC_DS_OBJECT_SIGNED(prong0, prong2, nSigTpcKaExpKa0, tpcNSigmaKa); - CHECK_AND_FILL_VEC_DS_OBJECT_SIGNED(prong2, prong0, nSigTpcPiExpPi2, tpcNSigmaPi); - CHECK_AND_FILL_VEC_DS_OBJECT_SIGNED(prong0, prong2, nSigTofKaExpKa0, tofNSigmaKa); - CHECK_AND_FILL_VEC_DS_OBJECT_SIGNED(prong2, prong0, nSigTofPiExpPi2, tofNSigmaPi); + // TPC and TOF PID variables + CHECK_AND_FILL_VEC_DS_FULL(candidate, nSigTpcPi0, nSigTpcPi0); + CHECK_AND_FILL_VEC_DS_FULL(candidate, nSigTpcPi1, nSigTpcPi1); + CHECK_AND_FILL_VEC_DS_FULL(candidate, nSigTpcPi2, nSigTpcPi2); + CHECK_AND_FILL_VEC_DS_FULL(candidate, nSigTpcKa0, nSigTpcKa0); + CHECK_AND_FILL_VEC_DS_FULL(candidate, nSigTpcKa1, nSigTpcKa1); + CHECK_AND_FILL_VEC_DS_FULL(candidate, nSigTpcKa2, nSigTpcKa2); + CHECK_AND_FILL_VEC_DS_FULL(candidate, nSigTofPi0, nSigTofPi0); + CHECK_AND_FILL_VEC_DS_FULL(candidate, nSigTofPi1, nSigTofPi1); + CHECK_AND_FILL_VEC_DS_FULL(candidate, nSigTofPi2, nSigTofPi2); + CHECK_AND_FILL_VEC_DS_FULL(candidate, nSigTofKa0, nSigTofKa0); + CHECK_AND_FILL_VEC_DS_FULL(candidate, nSigTofKa1, nSigTofKa1); + CHECK_AND_FILL_VEC_DS_FULL(candidate, nSigTofKa2, nSigTofKa2); + CHECK_AND_FILL_VEC_DS_SIGNED(candidate, nSigTpcKaExpKa0, nSigTpcKa0, nSigTpcKa2); + CHECK_AND_FILL_VEC_DS_SIGNED(candidate, nSigTpcPiExpPi2, nSigTpcPi2, nSigTpcPi0); + CHECK_AND_FILL_VEC_DS_SIGNED(candidate, nSigTofKaExpKa0, nSigTofKa0, nSigTofKa2); + CHECK_AND_FILL_VEC_DS_SIGNED(candidate, nSigTofPiExpPi2, nSigTofPi2, nSigTofPi0); // Combined PID variables - CHECK_AND_FILL_VEC_DS_FULL(prong0, nSigTpcTofPi0, tpcTofNSigmaPi); - CHECK_AND_FILL_VEC_DS_FULL(prong1, nSigTpcTofPi1, tpcTofNSigmaPi); - CHECK_AND_FILL_VEC_DS_FULL(prong2, nSigTpcTofPi2, tpcTofNSigmaPi); - CHECK_AND_FILL_VEC_DS_FULL(prong0, nSigTpcTofKa0, tpcTofNSigmaKa); - CHECK_AND_FILL_VEC_DS_FULL(prong1, nSigTpcTofKa1, tpcTofNSigmaKa); - CHECK_AND_FILL_VEC_DS_FULL(prong2, nSigTpcTofKa2, tpcTofNSigmaKa); - CHECK_AND_FILL_VEC_DS_OBJECT_SIGNED(prong0, prong2, nSigTpcTofKaExpKa0, tpcTofNSigmaKa); - CHECK_AND_FILL_VEC_DS_OBJECT_SIGNED(prong2, prong0, nSigTpcTofPiExpPi2, tpcTofNSigmaPi); + CHECK_AND_FILL_VEC_DS_FULL(candidate, nSigTpcTofPi0, tpcTofNSigmaPi0); + CHECK_AND_FILL_VEC_DS_FULL(candidate, nSigTpcTofPi1, tpcTofNSigmaPi1); + CHECK_AND_FILL_VEC_DS_FULL(candidate, nSigTpcTofPi2, tpcTofNSigmaPi2); + CHECK_AND_FILL_VEC_DS_FULL(candidate, nSigTpcTofKa0, tpcTofNSigmaKa0); + CHECK_AND_FILL_VEC_DS_FULL(candidate, nSigTpcTofKa1, tpcTofNSigmaKa1); + CHECK_AND_FILL_VEC_DS_FULL(candidate, nSigTpcTofKa2, tpcTofNSigmaKa2); + CHECK_AND_FILL_VEC_DS_SIGNED(candidate, nSigTpcTofKaExpKa0, tpcTofNSigmaKa0, tpcTofNSigmaKa2); + CHECK_AND_FILL_VEC_DS_SIGNED(candidate, nSigTpcTofPiExpPi2, tpcTofNSigmaPi2, tpcTofNSigmaPi0); // Ds specific variables CHECK_AND_FILL_VEC_DS_HFHELPER_SIGNED(candidate, absCos3PiK, absCos3PiKDsToKKPi, absCos3PiKDsToPiKK); diff --git a/PWGHF/Core/HfMlResponseDstarToD0Pi.h b/PWGHF/Core/HfMlResponseDstarToD0Pi.h index 66fc3a712d4..be309743893 100644 --- a/PWGHF/Core/HfMlResponseDstarToD0Pi.h +++ b/PWGHF/Core/HfMlResponseDstarToD0Pi.h @@ -49,6 +49,14 @@ break; \ } +// Specific case of CHECK_AND_FILL_VEC_DSTAR_FULL(OBJECT, FEATURE, GETTER) +// where OBJECT is named candidate and FEATURE != GETTER +#define CHECK_AND_FILL_VEC_DSTAR_GETTER(FEATURE, GETTER) \ + case static_cast(InputFeaturesDstarToD0Pi::FEATURE): { \ + inputFeatures.emplace_back(candidate.GETTER()); \ + break; \ + } + // Very specific case of CHECK_AND_FILL_VEC_DSTAR_FULL(OBJECT, FEATURE, GETTER) // Use for push back different value for D*+ or D*- candidate #define CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(POSGETTER, NEGGETTER, FEATURENAME) \ @@ -151,9 +159,8 @@ class HfMlResponseDstarToD0Pi : public HfMlResponse /// \param prong1 is the candidate's prong1 /// \param prongSoftPi is the candidate's prongSoftPi /// \return inputFeatures vector - template - std::vector getInputFeatures(T1 const& candidate, - T2 const& prong0, T2 const& prong1, T2 const& prongSoftPi) + template + std::vector getInputFeatures(T1 const& candidate) { std::vector inputFeatures; @@ -186,24 +193,24 @@ class HfMlResponseDstarToD0Pi : public HfMlResponse CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(cosThetaStarD0, cosThetaStarD0Bar, cosThetaStarD0); CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(invMassD0, invMassD0Bar, massD0); CHECK_AND_FILL_VEC_DSTAR_DELTA_MASS_D0(deltaMassD0); - CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE_FROMOBJECT(prong0, prong1, nSigmaTPCPiPr0, tpcNSigmaPi); - CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE_FROMOBJECT(prong0, prong1, nSigmaTPCKaPr0, tpcNSigmaKa); - CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE_FROMOBJECT(prong0, prong1, nSigmaTOFPiPr0, tofNSigmaPi); - CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE_FROMOBJECT(prong0, prong1, nSigmaTOFKaPr0, tofNSigmaKa); - CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE_FROMOBJECT(prong0, prong1, nSigmaTPCTOFPiPr0, tpcTofNSigmaPi); - CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE_FROMOBJECT(prong0, prong1, nSigmaTPCTOFKaPr0, tpcTofNSigmaKa); - CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE_FROMOBJECT(prong1, prong0, nSigmaTPCPiPr1, tpcNSigmaPi); - CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE_FROMOBJECT(prong1, prong0, nSigmaTPCKaPr1, tpcNSigmaKa); - CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE_FROMOBJECT(prong1, prong0, nSigmaTOFPiPr1, tofNSigmaPi); - CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE_FROMOBJECT(prong1, prong0, nSigmaTOFKaPr1, tofNSigmaKa); - CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE_FROMOBJECT(prong1, prong0, nSigmaTPCTOFPiPr1, tpcTofNSigmaPi); - CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE_FROMOBJECT(prong1, prong0, nSigmaTPCTOFKaPr1, tpcTofNSigmaKa); - CHECK_AND_FILL_VEC_DSTAR_FULL(prongSoftPi, nSigmaTPCPiPrSoftPi, tpcNSigmaPi); - CHECK_AND_FILL_VEC_DSTAR_FULL(prongSoftPi, nSigmaTPCKaPrSoftPi, tpcNSigmaKa); - CHECK_AND_FILL_VEC_DSTAR_FULL(prongSoftPi, nSigmaTOFPiPrSoftPi, tofNSigmaPi); - CHECK_AND_FILL_VEC_DSTAR_FULL(prongSoftPi, nSigmaTOFKaPrSoftPi, tofNSigmaKa); - CHECK_AND_FILL_VEC_DSTAR_FULL(prongSoftPi, nSigmaTPCTOFPiPrSoftPi, tpcTofNSigmaPi); - CHECK_AND_FILL_VEC_DSTAR_FULL(prongSoftPi, nSigmaTPCTOFKaPrSoftPi, tpcTofNSigmaKa); + CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(nSigTpcPi0, nSigTpcPi1, nSigmaTPCPiPr0); + CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(nSigTpcKa0, nSigTpcKa1, nSigmaTPCKaPr0); + CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(nSigTofPi0, nSigTofPi1, nSigmaTOFPiPr0); + CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(nSigTofKa0, nSigTofKa1, nSigmaTOFKaPr0); + CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(tpcTofNSigmaPi0, tpcTofNSigmaPi1, nSigmaTPCTOFPiPr0); + CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(tpcTofNSigmaKa0, tpcTofNSigmaKa1, nSigmaTPCTOFKaPr0); + CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(nSigTpcPi1, nSigTpcPi0, nSigmaTPCPiPr1); + CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(nSigTpcKa1, nSigTpcKa0, nSigmaTPCKaPr1); + CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(nSigTofPi1, nSigTofPi0, nSigmaTOFPiPr1); + CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(nSigTofKa1, nSigTofKa0, nSigmaTOFKaPr1); + CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(tpcTofNSigmaPi1, tpcTofNSigmaPi0, nSigmaTPCTOFPiPr1); + CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(tpcTofNSigmaKa1, tpcTofNSigmaKa0, nSigmaTPCTOFKaPr1); + CHECK_AND_FILL_VEC_DSTAR_GETTER(nSigmaTPCPiPrSoftPi, nSigTpcPi2); + CHECK_AND_FILL_VEC_DSTAR_GETTER(nSigmaTPCKaPrSoftPi, nSigTpcKa2); + CHECK_AND_FILL_VEC_DSTAR_GETTER(nSigmaTOFPiPrSoftPi, nSigTofPi2); + CHECK_AND_FILL_VEC_DSTAR_GETTER(nSigmaTOFKaPrSoftPi, nSigTofKa2); + CHECK_AND_FILL_VEC_DSTAR_GETTER(nSigmaTPCTOFPiPrSoftPi, tpcTofNSigmaPi2); + CHECK_AND_FILL_VEC_DSTAR_GETTER(nSigmaTPCTOFKaPrSoftPi, tpcTofNSigmaKa2); } } @@ -270,5 +277,6 @@ class HfMlResponseDstarToD0Pi : public HfMlResponse #undef CHECK_AND_FILL_VEC_DSTAR #undef CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE #undef CHECK_AND_FILL_VEC_DSTAR_DELTA_MASS_D0 +#undef CHECK_AND_FILL_VEC_DSTAR_GETTER #endif // PWGHF_CORE_HFMLRESPONSEDSTARTOD0PI_H_ diff --git a/PWGHF/Core/HfMlResponseLcToPKPi.h b/PWGHF/Core/HfMlResponseLcToPKPi.h index ea4767b85c6..405e16cfc42 100644 --- a/PWGHF/Core/HfMlResponseLcToPKPi.h +++ b/PWGHF/Core/HfMlResponseLcToPKPi.h @@ -23,9 +23,9 @@ // Fill the map of available input features // the key is the feature's name (std::string) // the value is the corresponding value in EnumInputFeatures -#define FILL_MAP_LCTOPKPI(FEATURE) \ - { \ -#FEATURE, static_cast < uint8_t>(InputFeaturesLcToPKPi::FEATURE) \ +#define FILL_MAP_LCTOPKPI(FEATURE) \ + { \ + #FEATURE, static_cast(InputFeaturesLcToPKPi::FEATURE) \ } // Check if the index of mCachedIndices (index associated to a FEATURE) @@ -67,6 +67,18 @@ break; \ } +// Variation of CHECK_AND_FILL_VEC_LCTOPKPI_HFHELPER_SIGNED(OBJECT, FEATURE, GETTER1, GETTER2) +// where GETTER1 and GETTER2 are methods of the OBJECT +#define CHECK_AND_FILL_VEC_LCTOPKPI_SIGNED(OBJECT, FEATURE, GETTER1, GETTER2) \ + case static_cast(InputFeaturesLcToPKPi::FEATURE): { \ + if (caseLcToPKPi) { \ + inputFeatures.emplace_back(OBJECT.GETTER1()); \ + } else { \ + inputFeatures.emplace_back(OBJECT.GETTER2()); \ + } \ + break; \ + } + namespace o2::analysis { enum class InputFeaturesLcToPKPi : uint8_t { @@ -85,22 +97,22 @@ enum class InputFeaturesLcToPKPi : uint8_t { cpa, cpaXY, chi2PCA, - tpcNSigmaP0, // 0 + tpcNSigmaPr0, // 0 tpcNSigmaKa0, // 0 tpcNSigmaPi0, // 0 - tpcNSigmaP1, // 1 + tpcNSigmaPr1, // 1 tpcNSigmaKa1, // 1 tpcNSigmaPi1, // 1 - tpcNSigmaP2, // 2 + tpcNSigmaPr2, // 2 tpcNSigmaKa2, // 2 tpcNSigmaPi2, // 2 - tofNSigmaP0, // + tofNSigmaPr0, // tofNSigmaKa0, // tofNSigmaPi0, // - tofNSigmaP1, + tofNSigmaPr1, tofNSigmaKa1, tofNSigmaPi1, - tofNSigmaP2, + tofNSigmaPr2, tofNSigmaKa2, tofNSigmaPi2, tpcTofNSigmaPi0, @@ -135,9 +147,8 @@ class HfMlResponseLcToPKPi : public HfMlResponse /// \param prong1 is the candidate's prong1 /// \param prong2 is the candidate's prong2 /// \return inputFeatures vector - template - std::vector getInputFeatures(T1 const& candidate, - T2 const& prong0, T2 const& prong1, T2 const& prong2, bool const& caseLcToPKPi) + template + std::vector getInputFeatures(T1 const& candidate, bool const caseLcToPKPi) { std::vector inputFeatures; @@ -159,41 +170,47 @@ class HfMlResponseLcToPKPi : public HfMlResponse CHECK_AND_FILL_VEC_LCTOPKPI(cpaXY); CHECK_AND_FILL_VEC_LCTOPKPI(chi2PCA); // TPC PID variables - CHECK_AND_FILL_VEC_LCTOPKPI_FULL(prong0, tpcNSigmaP0, tpcNSigmaPr); - CHECK_AND_FILL_VEC_LCTOPKPI_FULL(prong0, tpcNSigmaKa0, tpcNSigmaKa); - CHECK_AND_FILL_VEC_LCTOPKPI_FULL(prong0, tpcNSigmaPi0, tpcNSigmaPi); - CHECK_AND_FILL_VEC_LCTOPKPI_FULL(prong1, tpcNSigmaP1, tpcNSigmaPr); - CHECK_AND_FILL_VEC_LCTOPKPI_FULL(prong1, tpcNSigmaKa1, tpcNSigmaKa); - CHECK_AND_FILL_VEC_LCTOPKPI_FULL(prong1, tpcNSigmaPi1, tpcNSigmaPi); - CHECK_AND_FILL_VEC_LCTOPKPI_FULL(prong2, tpcNSigmaP2, tpcNSigmaPr); - CHECK_AND_FILL_VEC_LCTOPKPI_FULL(prong2, tpcNSigmaKa2, tpcNSigmaKa); - CHECK_AND_FILL_VEC_LCTOPKPI_FULL(prong2, tpcNSigmaPi2, tpcNSigmaPi); - CHECK_AND_FILL_VEC_LCTOPKPI_OBJECT_SIGNED(prong0, prong2, tpcNSigmaPrExpPr0, tpcNSigmaPr); - CHECK_AND_FILL_VEC_LCTOPKPI_OBJECT_SIGNED(prong2, prong0, tpcNSigmaPiExpPi2, tpcNSigmaPi); + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(candidate, tpcNSigmaPr0, nSigTpcPr0); + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(candidate, tpcNSigmaKa0, nSigTpcKa0); + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(candidate, tpcNSigmaPi0, nSigTpcPi0); + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(candidate, tpcNSigmaPr1, nSigTpcPr1); + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(candidate, tpcNSigmaKa1, nSigTpcKa1); + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(candidate, tpcNSigmaPi1, nSigTpcPi1); + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(candidate, tpcNSigmaPr2, nSigTpcPr2); + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(candidate, tpcNSigmaKa2, nSigTpcKa2); + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(candidate, tpcNSigmaPi2, nSigTpcPi2); + // CHECK_AND_FILL_VEC_LCTOPKPI_OBJECT_SIGNED(prong0, prong2, tpcNSigmaPrExpPr0, tpcNSigmaPr); + // CHECK_AND_FILL_VEC_LCTOPKPI_OBJECT_SIGNED(prong2, prong0, tpcNSigmaPiExpPi2, tpcNSigmaPi); + CHECK_AND_FILL_VEC_LCTOPKPI_SIGNED(candidate, tpcNSigmaPrExpPr0, nSigTpcPr0, nSigTpcPr2); + CHECK_AND_FILL_VEC_LCTOPKPI_SIGNED(candidate, tpcNSigmaPiExpPi2, nSigTpcPi2, nSigTpcPi0); // TOF PID variables - CHECK_AND_FILL_VEC_LCTOPKPI_FULL(prong0, tofNSigmaP0, tofNSigmaPr); - CHECK_AND_FILL_VEC_LCTOPKPI_FULL(prong0, tofNSigmaKa0, tofNSigmaKa); - CHECK_AND_FILL_VEC_LCTOPKPI_FULL(prong0, tofNSigmaPi0, tofNSigmaPi); - CHECK_AND_FILL_VEC_LCTOPKPI_FULL(prong1, tofNSigmaP1, tofNSigmaPr); - CHECK_AND_FILL_VEC_LCTOPKPI_FULL(prong1, tofNSigmaKa1, tofNSigmaKa); - CHECK_AND_FILL_VEC_LCTOPKPI_FULL(prong1, tofNSigmaPi1, tofNSigmaPi); - CHECK_AND_FILL_VEC_LCTOPKPI_FULL(prong2, tofNSigmaP2, tofNSigmaPr); - CHECK_AND_FILL_VEC_LCTOPKPI_FULL(prong2, tofNSigmaKa2, tofNSigmaKa); - CHECK_AND_FILL_VEC_LCTOPKPI_FULL(prong2, tofNSigmaPi2, tofNSigmaPi); - CHECK_AND_FILL_VEC_LCTOPKPI_OBJECT_SIGNED(prong0, prong2, tofNSigmaPrExpPr0, tofNSigmaPr); - CHECK_AND_FILL_VEC_LCTOPKPI_OBJECT_SIGNED(prong2, prong0, tofNSigmaPiExpPi2, tofNSigmaPi); + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(candidate, tofNSigmaPr0, nSigTofPr0); + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(candidate, tofNSigmaKa0, nSigTofKa0); + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(candidate, tofNSigmaPi0, nSigTofPi0); + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(candidate, tofNSigmaPr1, nSigTofPr1); + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(candidate, tofNSigmaKa1, nSigTofKa1); + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(candidate, tofNSigmaPi1, nSigTofPi1); + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(candidate, tofNSigmaPr2, nSigTofPr2); + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(candidate, tofNSigmaKa2, nSigTofKa2); + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(candidate, tofNSigmaPi2, nSigTofPi2); + // CHECK_AND_FILL_VEC_LCTOPKPI_OBJECT_SIGNED(prong0, prong2, tofNSigmaPrExpPr0, tofNSigmaPr); + // CHECK_AND_FILL_VEC_LCTOPKPI_OBJECT_SIGNED(prong2, prong0, tofNSigmaPiExpPi2, tofNSigmaPi); + CHECK_AND_FILL_VEC_LCTOPKPI_SIGNED(candidate, tofNSigmaPrExpPr0, nSigTofPr0, nSigTofPr2); + CHECK_AND_FILL_VEC_LCTOPKPI_SIGNED(candidate, tofNSigmaPiExpPi2, nSigTofPi2, nSigTofPi0); // Combined PID variables - CHECK_AND_FILL_VEC_LCTOPKPI_FULL(prong0, tpcTofNSigmaPi0, tpcTofNSigmaPi); - CHECK_AND_FILL_VEC_LCTOPKPI_FULL(prong1, tpcTofNSigmaPi1, tpcTofNSigmaPi); - CHECK_AND_FILL_VEC_LCTOPKPI_FULL(prong2, tpcTofNSigmaPi2, tpcTofNSigmaPi); - CHECK_AND_FILL_VEC_LCTOPKPI_FULL(prong0, tpcTofNSigmaKa0, tpcTofNSigmaKa); - CHECK_AND_FILL_VEC_LCTOPKPI_FULL(prong1, tpcTofNSigmaKa1, tpcTofNSigmaKa); - CHECK_AND_FILL_VEC_LCTOPKPI_FULL(prong2, tpcTofNSigmaKa2, tpcTofNSigmaKa); - CHECK_AND_FILL_VEC_LCTOPKPI_FULL(prong0, tpcTofNSigmaPr0, tpcTofNSigmaPr); - CHECK_AND_FILL_VEC_LCTOPKPI_FULL(prong1, tpcTofNSigmaPr1, tpcTofNSigmaPr); - CHECK_AND_FILL_VEC_LCTOPKPI_FULL(prong2, tpcTofNSigmaPr2, tpcTofNSigmaPr); - CHECK_AND_FILL_VEC_LCTOPKPI_OBJECT_SIGNED(prong0, prong2, tpcTofNSigmaPrExpPr0, tpcTofNSigmaPr); - CHECK_AND_FILL_VEC_LCTOPKPI_OBJECT_SIGNED(prong2, prong0, tpcTofNSigmaPiExpPi2, tpcTofNSigmaPi); + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(candidate, tpcTofNSigmaPi0, tpcTofNSigmaPi0); + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(candidate, tpcTofNSigmaPi1, tpcTofNSigmaPi1); + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(candidate, tpcTofNSigmaPi2, tpcTofNSigmaPi2); + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(candidate, tpcTofNSigmaKa0, tpcTofNSigmaKa0); + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(candidate, tpcTofNSigmaKa1, tpcTofNSigmaKa1); + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(candidate, tpcTofNSigmaKa2, tpcTofNSigmaKa2); + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(candidate, tpcTofNSigmaPr0, tpcTofNSigmaPr0); + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(candidate, tpcTofNSigmaPr1, tpcTofNSigmaPr1); + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(candidate, tpcTofNSigmaPr2, tpcTofNSigmaPr2); + // CHECK_AND_FILL_VEC_LCTOPKPI_OBJECT_SIGNED(prong0, prong2, tpcTofNSigmaPrExpPr0, tpcTofNSigmaPr); + // CHECK_AND_FILL_VEC_LCTOPKPI_OBJECT_SIGNED(prong2, prong0, tpcTofNSigmaPiExpPi2, tpcTofNSigmaPi); + CHECK_AND_FILL_VEC_LCTOPKPI_SIGNED(candidate, tpcTofNSigmaPrExpPr0, tpcTofNSigmaPr0, tpcTofNSigmaPr2); + CHECK_AND_FILL_VEC_LCTOPKPI_SIGNED(candidate, tpcTofNSigmaPiExpPi2, tpcTofNSigmaPi2, tpcTofNSigmaPi0); } } @@ -221,25 +238,25 @@ class HfMlResponseLcToPKPi : public HfMlResponse FILL_MAP_LCTOPKPI(cpaXY), FILL_MAP_LCTOPKPI(chi2PCA), // TPC PID variables - FILL_MAP_LCTOPKPI(tpcNSigmaP0), + FILL_MAP_LCTOPKPI(tpcNSigmaPr0), FILL_MAP_LCTOPKPI(tpcNSigmaKa0), FILL_MAP_LCTOPKPI(tpcNSigmaPi0), - FILL_MAP_LCTOPKPI(tpcNSigmaP1), + FILL_MAP_LCTOPKPI(tpcNSigmaPr1), FILL_MAP_LCTOPKPI(tpcNSigmaKa1), FILL_MAP_LCTOPKPI(tpcNSigmaPi1), - FILL_MAP_LCTOPKPI(tpcNSigmaP2), + FILL_MAP_LCTOPKPI(tpcNSigmaPr2), FILL_MAP_LCTOPKPI(tpcNSigmaKa2), FILL_MAP_LCTOPKPI(tpcNSigmaPi2), FILL_MAP_LCTOPKPI(tpcNSigmaPrExpPr0), FILL_MAP_LCTOPKPI(tpcNSigmaPiExpPi2), // TOF PID variables - FILL_MAP_LCTOPKPI(tofNSigmaP0), + FILL_MAP_LCTOPKPI(tofNSigmaPr0), FILL_MAP_LCTOPKPI(tofNSigmaKa0), FILL_MAP_LCTOPKPI(tofNSigmaPi0), - FILL_MAP_LCTOPKPI(tofNSigmaP1), + FILL_MAP_LCTOPKPI(tofNSigmaPr1), FILL_MAP_LCTOPKPI(tofNSigmaKa1), FILL_MAP_LCTOPKPI(tofNSigmaPi1), - FILL_MAP_LCTOPKPI(tofNSigmaP2), + FILL_MAP_LCTOPKPI(tofNSigmaPr2), FILL_MAP_LCTOPKPI(tofNSigmaKa2), FILL_MAP_LCTOPKPI(tofNSigmaPi2), FILL_MAP_LCTOPKPI(tofNSigmaPrExpPr0), diff --git a/PWGHF/Core/HfMlResponseXicToPKPi.h b/PWGHF/Core/HfMlResponseXicToPKPi.h index 94542745772..d533c7fb8ab 100644 --- a/PWGHF/Core/HfMlResponseXicToPKPi.h +++ b/PWGHF/Core/HfMlResponseXicToPKPi.h @@ -61,6 +61,19 @@ break; \ } +// Variation of CHECK_AND_FILL_VEC_XIC_OBJECT_SIGNED(OBJECT, FEATURE, GETTER1, GETTER2) +// where GETTER1 and GETTER2 are methods of the OBJECT, and used +// depending on whether the candidate is a XicToPKPi or a XicToPiKP +#define CHECK_AND_FILL_VEC_XIC_SIGNED(OBJECT, FEATURE, GETTER1, GETTER2) \ + case static_cast(InputFeaturesXicToPKPi::FEATURE): { \ + if (caseXicToPKPi) { \ + inputFeatures.emplace_back(OBJECT.GETTER1()); \ + } else { \ + inputFeatures.emplace_back(OBJECT.GETTER2()); \ + } \ + break; \ + } + namespace o2::analysis { enum class InputFeaturesXicToPKPi : uint8_t { @@ -79,22 +92,22 @@ enum class InputFeaturesXicToPKPi : uint8_t { cpa, cpaXY, chi2PCA, - tpcNSigmaP0, // 0 + tpcNSigmaPr0, // 0 tpcNSigmaKa0, // 0 tpcNSigmaPi0, // 0 - tpcNSigmaP1, // 1 + tpcNSigmaPr1, // 1 tpcNSigmaKa1, // 1 tpcNSigmaPi1, // 1 - tpcNSigmaP2, // 2 + tpcNSigmaPr2, // 2 tpcNSigmaKa2, // 2 tpcNSigmaPi2, // 2 - tofNSigmaP0, // + tofNSigmaPr0, // tofNSigmaKa0, // tofNSigmaPi0, // - tofNSigmaP1, + tofNSigmaPr1, tofNSigmaKa1, tofNSigmaPi1, - tofNSigmaP2, + tofNSigmaPr2, tofNSigmaKa2, tofNSigmaPi2, tpcTofNSigmaPi0, @@ -129,9 +142,8 @@ class HfMlResponseXicToPKPi : public HfMlResponse /// \param prong1 is the candidate's prong1 /// \param prong2 is the candidate's prong2 /// \return inputFeatures vector - template - std::vector getInputFeatures(T1 const& candidate, - T2 const& prong0, T2 const& prong1, T2 const& prong2, bool const& caseXicToPKPi) + template + std::vector getInputFeatures(T1 const& candidate, bool const caseXicToPKPi) { std::vector inputFeatures; @@ -153,41 +165,41 @@ class HfMlResponseXicToPKPi : public HfMlResponse CHECK_AND_FILL_VEC_XIC(cpaXY); CHECK_AND_FILL_VEC_XIC(chi2PCA); // TPC PID variables - CHECK_AND_FILL_VEC_XIC_FULL(prong0, tpcNSigmaP0, tpcNSigmaPr); - CHECK_AND_FILL_VEC_XIC_FULL(prong0, tpcNSigmaKa0, tpcNSigmaKa); - CHECK_AND_FILL_VEC_XIC_FULL(prong0, tpcNSigmaPi0, tpcNSigmaPi); - CHECK_AND_FILL_VEC_XIC_FULL(prong1, tpcNSigmaP1, tpcNSigmaPr); - CHECK_AND_FILL_VEC_XIC_FULL(prong1, tpcNSigmaKa1, tpcNSigmaKa); - CHECK_AND_FILL_VEC_XIC_FULL(prong1, tpcNSigmaPi1, tpcNSigmaPi); - CHECK_AND_FILL_VEC_XIC_FULL(prong2, tpcNSigmaP2, tpcNSigmaPr); - CHECK_AND_FILL_VEC_XIC_FULL(prong2, tpcNSigmaKa2, tpcNSigmaKa); - CHECK_AND_FILL_VEC_XIC_FULL(prong2, tpcNSigmaPi2, tpcNSigmaPi); - CHECK_AND_FILL_VEC_XIC_OBJECT_SIGNED(prong0, prong2, tpcNSigmaPrExpPr0, tpcNSigmaPr); - CHECK_AND_FILL_VEC_XIC_OBJECT_SIGNED(prong2, prong0, tpcNSigmaPiExpPi2, tpcNSigmaPi); + CHECK_AND_FILL_VEC_XIC_FULL(candidate, tpcNSigmaPr0, nSigTpcPr0); + CHECK_AND_FILL_VEC_XIC_FULL(candidate, tpcNSigmaKa0, nSigTpcKa0); + CHECK_AND_FILL_VEC_XIC_FULL(candidate, tpcNSigmaPi0, nSigTpcPi0); + CHECK_AND_FILL_VEC_XIC_FULL(candidate, tpcNSigmaPr1, nSigTpcPr1); + CHECK_AND_FILL_VEC_XIC_FULL(candidate, tpcNSigmaKa1, nSigTpcKa1); + CHECK_AND_FILL_VEC_XIC_FULL(candidate, tpcNSigmaPi1, nSigTpcPi1); + CHECK_AND_FILL_VEC_XIC_FULL(candidate, tpcNSigmaPr2, nSigTpcPr2); + CHECK_AND_FILL_VEC_XIC_FULL(candidate, tpcNSigmaKa2, nSigTpcKa2); + CHECK_AND_FILL_VEC_XIC_FULL(candidate, tpcNSigmaPi2, nSigTpcPi2); + CHECK_AND_FILL_VEC_XIC_SIGNED(candidate, tpcNSigmaPrExpPr0, nSigTpcPr0, nSigTpcPr2); + CHECK_AND_FILL_VEC_XIC_SIGNED(candidate, tpcNSigmaPiExpPi2, nSigTpcPi2, nSigTpcPi0); // TOF PID variables - CHECK_AND_FILL_VEC_XIC_FULL(prong0, tofNSigmaP0, tofNSigmaPr); - CHECK_AND_FILL_VEC_XIC_FULL(prong0, tofNSigmaKa0, tofNSigmaKa); - CHECK_AND_FILL_VEC_XIC_FULL(prong0, tofNSigmaPi0, tofNSigmaPi); - CHECK_AND_FILL_VEC_XIC_FULL(prong1, tofNSigmaP1, tofNSigmaPr); - CHECK_AND_FILL_VEC_XIC_FULL(prong1, tofNSigmaKa1, tofNSigmaKa); - CHECK_AND_FILL_VEC_XIC_FULL(prong1, tofNSigmaPi1, tofNSigmaPi); - CHECK_AND_FILL_VEC_XIC_FULL(prong2, tofNSigmaP2, tofNSigmaPr); - CHECK_AND_FILL_VEC_XIC_FULL(prong2, tofNSigmaKa2, tofNSigmaKa); - CHECK_AND_FILL_VEC_XIC_FULL(prong2, tofNSigmaPi2, tofNSigmaPi); - CHECK_AND_FILL_VEC_XIC_OBJECT_SIGNED(prong0, prong2, tofNSigmaPrExpPr0, tofNSigmaPr); - CHECK_AND_FILL_VEC_XIC_OBJECT_SIGNED(prong2, prong0, tofNSigmaPiExpPi2, tofNSigmaPi); + CHECK_AND_FILL_VEC_XIC_FULL(candidate, tofNSigmaPr0, nSigTofPr0); + CHECK_AND_FILL_VEC_XIC_FULL(candidate, tofNSigmaKa0, nSigTofKa0); + CHECK_AND_FILL_VEC_XIC_FULL(candidate, tofNSigmaPi0, nSigTofPi0); + CHECK_AND_FILL_VEC_XIC_FULL(candidate, tofNSigmaPr1, nSigTofPr1); + CHECK_AND_FILL_VEC_XIC_FULL(candidate, tofNSigmaKa1, nSigTofKa1); + CHECK_AND_FILL_VEC_XIC_FULL(candidate, tofNSigmaPi1, nSigTofPi1); + CHECK_AND_FILL_VEC_XIC_FULL(candidate, tofNSigmaPr2, nSigTofPr2); + CHECK_AND_FILL_VEC_XIC_FULL(candidate, tofNSigmaKa2, nSigTofKa2); + CHECK_AND_FILL_VEC_XIC_FULL(candidate, tofNSigmaPi2, nSigTofPi2); + CHECK_AND_FILL_VEC_XIC_SIGNED(candidate, tofNSigmaPrExpPr0, nSigTofPr0, nSigTofPr2); + CHECK_AND_FILL_VEC_XIC_SIGNED(candidate, tofNSigmaPiExpPi2, nSigTofPi2, nSigTofPi0); // Combined PID variables - CHECK_AND_FILL_VEC_XIC_FULL(prong0, tpcTofNSigmaPi0, tpcTofNSigmaPi); - CHECK_AND_FILL_VEC_XIC_FULL(prong1, tpcTofNSigmaPi1, tpcTofNSigmaPi); - CHECK_AND_FILL_VEC_XIC_FULL(prong2, tpcTofNSigmaPi2, tpcTofNSigmaPi); - CHECK_AND_FILL_VEC_XIC_FULL(prong0, tpcTofNSigmaKa0, tpcTofNSigmaKa); - CHECK_AND_FILL_VEC_XIC_FULL(prong1, tpcTofNSigmaKa1, tpcTofNSigmaKa); - CHECK_AND_FILL_VEC_XIC_FULL(prong2, tpcTofNSigmaKa2, tpcTofNSigmaKa); - CHECK_AND_FILL_VEC_XIC_FULL(prong0, tpcTofNSigmaPr0, tpcTofNSigmaPr); - CHECK_AND_FILL_VEC_XIC_FULL(prong1, tpcTofNSigmaPr1, tpcTofNSigmaPr); - CHECK_AND_FILL_VEC_XIC_FULL(prong2, tpcTofNSigmaPr2, tpcTofNSigmaPr); - CHECK_AND_FILL_VEC_XIC_OBJECT_SIGNED(prong0, prong2, tpcTofNSigmaPrExpPr0, tpcTofNSigmaPr); - CHECK_AND_FILL_VEC_XIC_OBJECT_SIGNED(prong2, prong0, tpcTofNSigmaPiExpPi2, tpcTofNSigmaPi); + CHECK_AND_FILL_VEC_XIC_FULL(candidate, tpcTofNSigmaPi0, tpcTofNSigmaPi0); + CHECK_AND_FILL_VEC_XIC_FULL(candidate, tpcTofNSigmaPi1, tpcTofNSigmaPi1); + CHECK_AND_FILL_VEC_XIC_FULL(candidate, tpcTofNSigmaPi2, tpcTofNSigmaPi2); + CHECK_AND_FILL_VEC_XIC_FULL(candidate, tpcTofNSigmaKa0, tpcTofNSigmaKa0); + CHECK_AND_FILL_VEC_XIC_FULL(candidate, tpcTofNSigmaKa1, tpcTofNSigmaKa1); + CHECK_AND_FILL_VEC_XIC_FULL(candidate, tpcTofNSigmaKa2, tpcTofNSigmaKa2); + CHECK_AND_FILL_VEC_XIC_FULL(candidate, tpcTofNSigmaPr0, tpcTofNSigmaPr0); + CHECK_AND_FILL_VEC_XIC_FULL(candidate, tpcTofNSigmaPr1, tpcTofNSigmaPr1); + CHECK_AND_FILL_VEC_XIC_FULL(candidate, tpcTofNSigmaPr2, tpcTofNSigmaPr2); + CHECK_AND_FILL_VEC_XIC_SIGNED(candidate, tpcTofNSigmaPrExpPr0, tpcTofNSigmaPr0, tpcTofNSigmaPr2); + CHECK_AND_FILL_VEC_XIC_SIGNED(candidate, tpcTofNSigmaPiExpPi2, tpcTofNSigmaPi2, tpcTofNSigmaPi0); } } @@ -215,25 +227,25 @@ class HfMlResponseXicToPKPi : public HfMlResponse FILL_MAP_XIC(cpaXY), FILL_MAP_XIC(chi2PCA), // TPC PID variables - FILL_MAP_XIC(tpcNSigmaP0), + FILL_MAP_XIC(tpcNSigmaPr0), FILL_MAP_XIC(tpcNSigmaKa0), FILL_MAP_XIC(tpcNSigmaPi0), - FILL_MAP_XIC(tpcNSigmaP1), + FILL_MAP_XIC(tpcNSigmaPr1), FILL_MAP_XIC(tpcNSigmaKa1), FILL_MAP_XIC(tpcNSigmaPi1), - FILL_MAP_XIC(tpcNSigmaP2), + FILL_MAP_XIC(tpcNSigmaPr2), FILL_MAP_XIC(tpcNSigmaKa2), FILL_MAP_XIC(tpcNSigmaPi2), FILL_MAP_XIC(tpcNSigmaPrExpPr0), FILL_MAP_XIC(tpcNSigmaPiExpPi2), // TOF PID variables - FILL_MAP_XIC(tofNSigmaP0), + FILL_MAP_XIC(tofNSigmaPr0), FILL_MAP_XIC(tofNSigmaKa0), FILL_MAP_XIC(tofNSigmaPi0), - FILL_MAP_XIC(tofNSigmaP1), + FILL_MAP_XIC(tofNSigmaPr1), FILL_MAP_XIC(tofNSigmaKa1), FILL_MAP_XIC(tofNSigmaPi1), - FILL_MAP_XIC(tofNSigmaP2), + FILL_MAP_XIC(tofNSigmaPr2), FILL_MAP_XIC(tofNSigmaKa2), FILL_MAP_XIC(tofNSigmaPi2), FILL_MAP_XIC(tofNSigmaPrExpPr0), diff --git a/PWGHF/Core/SelectorCuts.h b/PWGHF/Core/SelectorCuts.h index a3313abe79e..b064642fe90 100644 --- a/PWGHF/Core/SelectorCuts.h +++ b/PWGHF/Core/SelectorCuts.h @@ -465,6 +465,7 @@ namespace hf_cuts_lc_to_p_k_pi { static constexpr int NBinsPt = 10; static constexpr int NCutVars = 11; +static constexpr int NCutKfVars = 12; // default values for the pT bin edges (can be used to configure histogram axis) // offset by 1 from the bin numbers in cuts array constexpr double BinsPt[NBinsPt + 1] = { @@ -493,6 +494,19 @@ constexpr double Cuts[NBinsPt][NCutVars] = {{0.4, 0.4, 0.4, 0.4, 0., 0.005, 0., {0.4, 0.4, 0.4, 0.4, 0., 0.005, 0., 0., 0., 1e+10, -1.}, /* 12 < pT < 24 */ {0.4, 0.4, 0.4, 0.4, 0., 0.005, 0., 0., 0., 1e+10, -1.}}; /* 24 < pT < 36 */ +// default value for the cuts Chi2Prim Chi2Geo DCA, cm Chi2Geo Chi2Topo +// P K Pi KPi PPi PK KPi PPi PK ↓ LdL ↓ +constexpr double CutsKf[NBinsPt][NCutKfVars] = {{3., 3., 3., 3., 3., 3., 0.01, 0.01, 0.01, 3., 5., 5.}, /* 0 < pT < 1 */ + {3., 3., 3., 3., 3., 3., 0.01, 0.01, 0.01, 3., 5., 5.}, /* 1 < pT < 2 */ + {3., 3., 3., 3., 3., 3., 0.01, 0.01, 0.01, 3., 5., 5.}, /* 2 < pT < 3 */ + {3., 3., 3., 3., 3., 3., 0.01, 0.01, 0.01, 3., 5., 5.}, /* 3 < pT < 4 */ + {3., 3., 3., 3., 3., 3., 0.01, 0.01, 0.01, 3., 5., 5.}, /* 4 < pT < 5 */ + {3., 3., 3., 3., 3., 3., 0.01, 0.01, 0.01, 3., 5., 5.}, /* 5 < pT < 6 */ + {3., 3., 3., 3., 3., 3., 0.01, 0.01, 0.01, 3., 5., 5.}, /* 6 < pT < 8 */ + {3., 3., 3., 3., 3., 3., 0.01, 0.01, 0.01, 3., 5., 5.}, /* 8 < pT < 12 */ + {3., 3., 3., 3., 3., 3., 0.01, 0.01, 0.01, 3., 5., 5.}, /* 12 < pT < 24 */ + {3., 3., 3., 3., 3., 3., 0.01, 0.01, 0.01, 3., 5., 5.}}; /* 24 < pT < 36 */ + // row labels static const std::vector labelsPt = { "pT bin 0", @@ -508,6 +522,7 @@ static const std::vector labelsPt = { // column labels static const std::vector labelsCutVar = {"m", "pT p", "pT K", "pT Pi", "Chi2PCA", "decay length", "cos pointing angle", "decLengthXY", "normDecLXY", "impParXY", "mass (Kpi)"}; +static const std::vector labelsCutKfVar = {"kfChi2PrimPr", "kfChi2PrimKa", "kfChi2PrimPi", "kfChi2GeoKaPi", "kfChi2GeoPrPi", "kfChi2GeoPrKa", "kfDcaKaPi", "kfDcaPrPi", "kfDcaPrKa", "kfChi2Geo", "kfLdL", "kfChi2Topo"}; } // namespace hf_cuts_lc_to_p_k_pi namespace hf_cuts_lc_to_k0s_p diff --git a/PWGHF/D2H/TableProducer/dataCreatorCharmHadPiReduced.cxx b/PWGHF/D2H/TableProducer/dataCreatorCharmHadPiReduced.cxx index 869e037c788..fc6c9487700 100644 --- a/PWGHF/D2H/TableProducer/dataCreatorCharmHadPiReduced.cxx +++ b/PWGHF/D2H/TableProducer/dataCreatorCharmHadPiReduced.cxx @@ -168,10 +168,10 @@ struct HfDataCreatorCharmHadPiReduced { using TracksPidWithSel = soa::Join; using TracksPidWithSelAndMc = soa::Join; - using CandsDplusFiltered = soa::Filtered>; - using CandsDplusFilteredWithMl = soa::Filtered>; - using CandsDsFiltered = soa::Filtered>; - using CandsDsFilteredWithMl = soa::Filtered>; + using CandsDplusFiltered = soa::Filtered>; + using CandsDplusFilteredWithMl = soa::Filtered>; + using CandsDsFiltered = soa::Filtered>; + using CandsDsFilteredWithMl = soa::Filtered>; using CandsD0Filtered = soa::Filtered>; using CandsD0FilteredWithMl = soa::Filtered>; @@ -291,6 +291,9 @@ struct HfDataCreatorCharmHadPiReduced { setLabelHistoCands(hCandidatesD0); setLabelHistoCands(hCandidatesDPlus); setLabelHistoCands(hCandidatesDs); + + // init HF event selection helper + hfEvSel.init(registry); } /// Pion selection (D Pi <-- B0) @@ -981,9 +984,9 @@ struct HfDataCreatorCharmHadPiReduced { trackParCovCharmHad.getSigmaTglSnp(), trackParCovCharmHad.getSigmaTgl2(), trackParCovCharmHad.getSigma1PtY(), trackParCovCharmHad.getSigma1PtZ(), trackParCovCharmHad.getSigma1PtSnp(), trackParCovCharmHad.getSigma1PtTgl(), trackParCovCharmHad.getSigma1Pt2()); - hfCandPidProng0(charmHadDauTracks[0].tpcNSigmaPi(), charmHadDauTracks[0].tofNSigmaPi(), charmHadDauTracks[0].tpcNSigmaKa(), charmHadDauTracks[0].tofNSigmaKa(), charmHadDauTracks[0].hasTOF(), charmHadDauTracks[0].hasTPC()); - hfCandPidProng1(charmHadDauTracks[1].tpcNSigmaPi(), charmHadDauTracks[1].tofNSigmaPi(), charmHadDauTracks[1].tpcNSigmaKa(), charmHadDauTracks[1].tofNSigmaKa(), charmHadDauTracks[1].hasTOF(), charmHadDauTracks[1].hasTPC()); - hfCandPidProng2(charmHadDauTracks[2].tpcNSigmaPi(), charmHadDauTracks[2].tofNSigmaPi(), charmHadDauTracks[2].tpcNSigmaKa(), charmHadDauTracks[2].tofNSigmaKa(), charmHadDauTracks[2].hasTOF(), charmHadDauTracks[2].hasTPC()); + hfCandPidProng0(candC.nSigTpcPi0(), candC.nSigTofPi0(), candC.nSigTpcKa0(), candC.nSigTofKa0(), charmHadDauTracks[0].hasTOF(), charmHadDauTracks[0].hasTPC()); + hfCandPidProng1(candC.nSigTpcPi1(), candC.nSigTofPi1(), candC.nSigTpcKa1(), candC.nSigTofKa1(), charmHadDauTracks[1].hasTOF(), charmHadDauTracks[1].hasTPC()); + hfCandPidProng2(candC.nSigTpcPi2(), candC.nSigTofPi2(), candC.nSigTpcKa2(), candC.nSigTofKa2(), charmHadDauTracks[2].hasTOF(), charmHadDauTracks[2].hasTPC()); if constexpr (withMl) { if constexpr (decChannel == DecayChannel::B0ToDminusPi) { hfCand3ProngMl(candC.mlProbDplusToPiKPi()[0], candC.mlProbDplusToPiKPi()[1], candC.mlProbDplusToPiKPi()[2], -1., -1., -1.); diff --git a/PWGHF/D2H/TableProducer/dataCreatorCharmResoReduced.cxx b/PWGHF/D2H/TableProducer/dataCreatorCharmResoReduced.cxx index 714de7448ac..d11a2db65d6 100644 --- a/PWGHF/D2H/TableProducer/dataCreatorCharmResoReduced.cxx +++ b/PWGHF/D2H/TableProducer/dataCreatorCharmResoReduced.cxx @@ -302,6 +302,9 @@ struct HfDataCreatorCharmResoReduced { fitter.setMaxChi2(1e9); fitter.setUseAbsDCA(true); fitter.setWeightedFinalPCA(false); + + // init HF event selection helper + hfEvSel.init(registry); } /// Basic track quality selections for V0 daughters diff --git a/PWGHF/D2H/Tasks/taskSigmac.cxx b/PWGHF/D2H/Tasks/taskSigmac.cxx index b7d77b1fea6..e7083d7283e 100644 --- a/PWGHF/D2H/Tasks/taskSigmac.cxx +++ b/PWGHF/D2H/Tasks/taskSigmac.cxx @@ -15,6 +15,8 @@ /// /// \author Mattia Faggin , University and INFN PADOVA +#include + #include "CommonConstants/PhysicsConstants.h" #include "Framework/AnalysisTask.h" #include "Framework/HistogramRegistry.h" @@ -39,9 +41,15 @@ struct HfTaskSigmac { /// consider the new parametrization of the fiducial acceptance (to be seen for reco signal in MC) Configurable yCandGenMax{"yCandGenMax", -1, "Maximum generated Sc rapidity"}; Configurable yCandRecoMax{"yCandRecoMax", -1, "Maximum Sc candidate rapidity"}; + Configurable enableTHn{"enableTHn", false, "enable the usage of THn for Λc+ and Σc0,++"}; + + HfHelper hfHelper; + bool isMc; + static constexpr std::size_t NDaughters{2u}; + + using RecoLc = soa::Join; /// THn for candidate Λc+ and Σc0,++ cut variation - Configurable enableTHn{"enableTHn", false, "enable the usage of THn for Λc+ and Σc0,++"}; ConfigurableAxis thnConfigAxisPt{"thnConfigAxisPt", {16, 0, 16}, ""}; ConfigurableAxis thnConfigAxisGenPt{"thnConfigAxisGenPt", {240, 0, 24}, "Gen pt prompt"}; ConfigurableAxis thnConfigAxisGenPtB{"thnConfigAxisGenPtB", {800, 0, 80}, "Gen pt non-prompt"}; @@ -53,8 +61,23 @@ struct HfTaskSigmac { ConfigurableAxis configAxisDeltaMassSigmaC{"configAxisDeltaMassSigmaC", {200, 0.13, 0.23}, ""}; ConfigurableAxis thnConfigAxisBdtScoreLcBkg{"thnConfigAxisBdtScoreLcBkg", {100, 0., 1.}, ""}; ConfigurableAxis thnConfigAxisBdtScoreLcNonPrompt{"thnConfigAxisBdtScoreLcNonPrompt", {100, 0., 1.}, ""}; - - HfHelper hfHelper; + const AxisSpec thnAxisMassLambdaC{configAxisMassLambdaC, "inv. mass (p K #pi) (GeV/#it{c}^{2})"}; + const AxisSpec thnAxisPtLambdaC{thnConfigAxisPt, "#it{p}_{T}(#Lambda_{c}^{+}) (GeV/#it{c})"}; + const AxisSpec thnAxisPtSigmaC{thnConfigAxisPt, "#it{p}_{T}(#Sigma_{c}^{0,++}) (GeV/#it{c})"}; + const AxisSpec thnAxisDecLength{thnConfigAxisDecLength, "decay length #Lambda_{c}^{+} (cm)"}; + const AxisSpec thnAxisDecLengthXY{thnConfigAxisDecLengthXY, "decay length XY #Lambda_{c}^{+} (cm)"}; + const AxisSpec thnAxisCPA{thnConfigAxisCPA, "cosine of pointing angle #Lambda_{c}^{+}"}; + const AxisSpec thnAxisCPAXY{thnConfigAxisCPAXY, "cosine of pointing angle XY #Lambda_{c}^{+}"}; + const AxisSpec thnAxisOriginMc{3, -0.5, 2.5, "0: none, 1: prompt, 2: non-prompt"}; + const AxisSpec thnAxisChargeSigmaC{3, -0.5, 2.5, "#Sigma_{c}-baryon charge"}; + const AxisSpec thnAxisChannel{4, -0.5, 3.5, "0: direct 1,2,3: resonant"}; + const AxisSpec thnAxisBdtScoreLcBkg{thnConfigAxisBdtScoreLcBkg, "BDT bkg score (Lc)"}; + const AxisSpec thnAxisBdtScoreLcNonPrompt{thnConfigAxisBdtScoreLcNonPrompt, "BDT non-prompt score (Lc)"}; + const AxisSpec thnAxisGenPtLambdaC{thnConfigAxisGenPt, "#it{p}_{T}^{gen}(#Lambda_{c}^{+}) (GeV/#it{c})"}; + const AxisSpec thnAxisGenPtSigmaC{thnConfigAxisGenPt, "#it{p}_{T}^{gen}(#Sigma_{c}^{0,++}) (GeV/#it{c})"}; + const AxisSpec thnAxisGenPtLambdaCBMother{thnConfigAxisGenPtB, "#it{p}_{T}^{gen}(#Lambda_{c}^{+} B mother) (GeV/#it{c})"}; + const AxisSpec thnAxisGenPtSigmaCBMother{thnConfigAxisGenPtB, "#it{p}_{T}^{gen}(#Sigma_{c}^{0,++} B mother) (GeV/#it{c})"}; + const AxisSpec thnAxisGenSigmaCSpecies = {o2::aod::hf_cand_sigmac::Species::NSpecies, -0.5f, +o2::aod::hf_cand_sigmac::Species::NSpecies - 0.5f, "bin 1: #Sigma_{c}(2455), bin 2: #Sigma_{c}(2520)"}; /// analysis histograms HistogramRegistry registry{ @@ -99,10 +122,6 @@ struct HfTaskSigmac { {"Data/hPhiLcFromSc0PlusPlus", "#Lambda_{c}^{+} #leftarrow #Sigma_{c}^{0,++} candidates; #varphi(#Lambda_{c}^{+} #leftarrow #Sigma_{c}^{0,++}); entries;", {HistType::kTH1D, {{72, 0, constants::math::TwoPI}}}}}}; //{"Data/hDeltaMassLcFromSc0PlusPlus", "#Lambda_{c}^{+} #leftarrow #Sigma_{c}^{0,++} candidates; #it{M}(pK#pi#pi) - #it{M}(pK#pi) (GeV/#it{c}^{2}); #it{p}_{T}(#Lambda_{c}^{+} #leftarrow #Sigma_{c}^{0,++}) (GeV/#it{c});", {HistType::kTH2D, {axisDeltaMassSigmaC, {36, 0., 36.}}}}}}; - using RecoLc = soa::Join; - - bool isMc; - /// @brief init function, to define the additional analysis histograms /// @param void init(InitContext&) @@ -246,37 +265,23 @@ struct HfTaskSigmac { /// THn for candidate Λc+ and Σc0,++ cut variation if (enableTHn) { - const AxisSpec thnAxisMassLambdaC{configAxisMassLambdaC, "inv. mass (p K #pi) (GeV/#it{c}^{2})"}; - const AxisSpec thnAxisPtLambdaC{thnConfigAxisPt, "#it{p}_{T}(#Lambda_{c}^{+}) (GeV/#it{c})"}; - const AxisSpec thnAxisPtSigmaC{thnConfigAxisPt, "#it{p}_{T}(#Sigma_{c}^{0,++}) (GeV/#it{c})"}; - const AxisSpec thnAxisDecLength{thnConfigAxisDecLength, "decay length #Lambda_{c}^{+} (cm)"}; - const AxisSpec thnAxisDecLengthXY{thnConfigAxisDecLengthXY, "decay length XY #Lambda_{c}^{+} (cm)"}; - const AxisSpec thnAxisCPA{thnConfigAxisCPA, "cosine of pointing angle #Lambda_{c}^{+}"}; - const AxisSpec thnAxisCPAXY{thnConfigAxisCPAXY, "cosine of pointing angle XY #Lambda_{c}^{+}"}; - const AxisSpec thnAxisOriginMc{3, -0.5, 2.5, "0: none, 1: prompt, 2: non-prompt"}; - const AxisSpec thnAxisChargeSigmaC{3, -0.5, 2.5, "#Sigma_{c}-baryon charge"}; - const AxisSpec thnAxisChannel{4, -0.5, 3.5, "0: direct 1,2,3: resonant"}; - const AxisSpec thnAxisBdtScoreLcBkg{thnConfigAxisBdtScoreLcBkg, "BDT bkg score (Lc)"}; - const AxisSpec thnAxisBdtScoreLcNonPrompt{thnConfigAxisBdtScoreLcNonPrompt, "BDT non-prompt score (Lc)"}; - const AxisSpec thnAxisGenPtLambdaC{thnConfigAxisGenPt, "#it{p}_{T}^{gen}(#Lambda_{c}^{+}) (GeV/#it{c})"}; - const AxisSpec thnAxisGenPtSigmaC{thnConfigAxisGenPt, "#it{p}_{T}^{gen}(#Sigma_{c}^{0,++}) (GeV/#it{c})"}; - const AxisSpec thnAxisGenPtLambdaCBMother{thnConfigAxisGenPtB, "#it{p}_{T}^{gen}(#Lambda_{c}^{+} B mother) (GeV/#it{c})"}; - const AxisSpec thnAxisGenPtSigmaCBMother{thnConfigAxisGenPtB, "#it{p}_{T}^{gen}(#Sigma_{c}^{0,++} B mother) (GeV/#it{c})"}; std::vector axesLambdaCWithMl = {thnAxisPtLambdaC, thnAxisMassLambdaC, thnAxisBdtScoreLcBkg, thnAxisBdtScoreLcNonPrompt, thnAxisOriginMc, thnAxisChannel}; std::vector axesSigmaCWithMl = {thnAxisPtLambdaC, axisDeltaMassSigmaC, thnAxisBdtScoreLcBkg, thnAxisBdtScoreLcNonPrompt, thnAxisOriginMc, thnAxisChannel, thnAxisPtSigmaC, thnAxisChargeSigmaC}; std::vector axesLambdaCWoMl = {thnAxisPtLambdaC, thnAxisMassLambdaC, thnAxisDecLength, thnAxisDecLengthXY, thnAxisCPA, thnAxisCPAXY, thnAxisOriginMc, thnAxisChannel}; std::vector axesSigmaCWoMl = {thnAxisPtLambdaC, axisDeltaMassSigmaC, thnAxisDecLength, thnAxisDecLengthXY, thnAxisCPA, thnAxisCPAXY, thnAxisOriginMc, thnAxisChannel, thnAxisPtSigmaC, thnAxisChargeSigmaC}; if (isMc) { - registry.add("hnLambdaCGen", "THn for Lambdac gen", HistType::kTHnSparseF, {thnAxisGenPtLambdaC, thnAxisGenPtLambdaCBMother, thnAxisOriginMc, thnAxisChannel}); - registry.add("hnSigmaCGen", "THn for Sigmac gen", HistType::kTHnSparseF, {thnAxisGenPtSigmaC, thnAxisGenPtSigmaCBMother, thnAxisOriginMc, thnAxisChannel, thnAxisGenPtLambdaC, thnAxisChargeSigmaC}); + registry.add("MC/generated/hnLambdaCGen", "THn for Lambdac gen", HistType::kTHnSparseF, {thnAxisGenPtLambdaC, thnAxisGenPtLambdaCBMother, thnAxisOriginMc, thnAxisChannel}); + registry.add("MC/generated/hnSigmaCGen", "THn for Sigmac gen", HistType::kTHnSparseF, {thnAxisGenPtSigmaC, thnAxisGenPtSigmaCBMother, thnAxisOriginMc, thnAxisChannel, thnAxisGenPtLambdaC, thnAxisChargeSigmaC, thnAxisGenSigmaCSpecies}); if (doprocessMcWithMl) { axesLambdaCWithMl.push_back(thnAxisGenPtLambdaCBMother); axesSigmaCWithMl.push_back(thnAxisGenPtSigmaCBMother); + axesSigmaCWithMl.push_back(thnAxisGenSigmaCSpecies); registry.add("hnLambdaC", "THn for Lambdac", HistType::kTHnSparseF, axesLambdaCWithMl); registry.add("hnSigmaC", "THn for Sigmac", HistType::kTHnSparseF, axesSigmaCWithMl); } else { axesLambdaCWoMl.push_back(thnAxisGenPtLambdaCBMother); axesSigmaCWoMl.push_back(thnAxisGenPtSigmaCBMother); + axesSigmaCWoMl.push_back(thnAxisGenSigmaCSpecies); registry.add("hnLambdaC", "THn for Lambdac", HistType::kTHnSparseF, axesLambdaCWoMl); registry.add("hnSigmaC", "THn for Sigmac", HistType::kTHnSparseF, axesSigmaCWoMl); } @@ -300,16 +305,16 @@ struct HfTaskSigmac { /// @param candSc Sc candidate /// @return 0: none; 1: only Λc+ → pK-π+ possible; 2: Λc+ → π+K-p possible; 3: both possible template - int isDecayToPKPiToPiKP(L& candidateLc, S& candSc) + int8_t isDecayToPKPiToPiKP(L& candidateLc, S& candSc) { - int channel = 0; + int8_t channel = 0; if ((candidateLc.isSelLcToPKPi() >= 1) && candSc.statusSpreadLcMinvPKPiFromPDG()) { // Λc+ → pK-π+ and within the requested mass to build the Σc0,++ - channel += 1; + SETBIT(channel, o2::aod::hf_cand_sigmac::Decays::PKPi); } if ((candidateLc.isSelLcToPiKP() >= 1) && candSc.statusSpreadLcMinvPiKPFromPDG()) { // Λc+ → π+K-p and within the requested mass to build the Σc0,++ - channel += 2; + SETBIT(channel, o2::aod::hf_cand_sigmac::Decays::PiKP); } return channel; /// 0: none; 1: pK-π+ only; 2: π+K-p only; 3: both possible } @@ -326,6 +331,12 @@ struct HfTaskSigmac { /// loop over the candidate Σc0,++ for (const auto& candSc : candidatesSc) { + /// rapidity selection on Σc0,++ + /// NB: since in data we cannot tag Sc(2455) and Sc(2520), then we use only Sc(2455) for y selection on reconstructed signal + if (yCandRecoMax >= 0. && std::abs(hfHelper.ySc0(candSc)) > yCandRecoMax && std::abs(hfHelper.yScPlusPlus(candSc)) > yCandRecoMax) { + continue; + } + const int8_t chargeSc = candSc.charge(); // either Σc0 or Σc++ /// get the candidate Λc+ used to build the candidate Σc0,++ @@ -333,7 +344,7 @@ struct HfTaskSigmac { const auto& candidateLc = candSc.prongLc_as(); // const int iscandidateLcpKpi = (candidateLc.isSelLcToPKPi() >= 1) && candSc.statusSpreadLcMinvPKPiFromPDG(); // Λc+ → pK-π+ and within the requested mass to build the Σc0,++ // const int iscandidateLcpiKp = (candidateLc.isSelLcToPiKP() >= 1) && candSc.statusSpreadLcMinvPiKPFromPDG(); // Λc+ → π+K-p and within the requested mass to build the Σc0,++ - const int isCandPKPiPiKP = isDecayToPKPiToPiKP(candidateLc, candSc); + const int8_t isCandPKPiPiKP = isDecayToPKPiToPiKP(candidateLc, candSc); double massSc(-1.), massLc(-1.), deltaMass(-1.); double ptSc(candSc.pt()), ptLc(candidateLc.pt()); double etaSc(candSc.eta()), etaLc(candidateLc.eta()); @@ -342,12 +353,12 @@ struct HfTaskSigmac { double decLengthLc(candidateLc.decayLength()), decLengthXYLc(candidateLc.decayLengthXY()); double cpaLc(candidateLc.cpa()), cpaXYLc(candidateLc.cpaXY()); /// candidate Λc+ → pK-π+ (and charge conjugate) within the range of M(pK-π+) chosen in the Σc0,++ builder - if (isCandPKPiPiKP == 1 || isCandPKPiPiKP == 3) { + if (TESTBIT(isCandPKPiPiKP, o2::aod::hf_cand_sigmac::Decays::PKPi)) { massSc = hfHelper.invMassScRecoLcToPKPi(candSc, candidateLc); massLc = hfHelper.invMassLcToPKPi(candidateLc); deltaMass = massSc - massLc; /// fill the histograms - if (chargeSc == 0) { + if (chargeSc == o2::aod::hf_cand_sigmac::ChargeNull) { registry.fill(HIST("Data/hPtSc0"), ptSc); registry.fill(HIST("Data/hEtaSc0"), etaSc); registry.fill(HIST("Data/hPhiSc0"), phiSc); @@ -415,12 +426,12 @@ struct HfTaskSigmac { } } /// end candidate Λc+ → pK-π+ (and charge conjugate) /// candidate Λc+ → π+K-p (and charge conjugate) within the range of M(π+K-p) chosen in the Σc0,++ builder - if (isCandPKPiPiKP == 2 || isCandPKPiPiKP == 3) { + if (TESTBIT(isCandPKPiPiKP, o2::aod::hf_cand_sigmac::Decays::PiKP)) { massSc = hfHelper.invMassScRecoLcToPiKP(candSc, candidateLc); massLc = hfHelper.invMassLcToPiKP(candidateLc); deltaMass = massSc - massLc; /// fill the histograms - if (chargeSc == 0) { + if (chargeSc == o2::aod::hf_cand_sigmac::ChargeNull) { registry.fill(HIST("Data/hPtSc0"), ptSc); registry.fill(HIST("Data/hEtaSc0"), etaSc); registry.fill(HIST("Data/hPhiSc0"), phiSc); @@ -487,7 +498,7 @@ struct HfTaskSigmac { } } } /// end candidate Λc+ → π+K-p (and charge conjugate) - } /// end loop over the candidate Σc0,++ + } /// end loop over the candidate Σc0,++ /// THn for candidate Λc+ cut variation w/o Σc0,++ mass-window cut if (enableTHn) { @@ -534,7 +545,7 @@ struct HfTaskSigmac { } } } /// end THn for candidate Λc+ cut variation w/o Σc0,++ mass-window cut - }; /// end fillHistosData + }; /// end fillHistosData /// @brief function to fill the histograms needed in analysis (MC) /// @param candidatesSc are the reconstructed candidate Σc0,++ with MC info @@ -553,9 +564,11 @@ struct HfTaskSigmac { for (const auto& particle : mcParticlesSc) { /// reject immediately particles different from Σc0,++ - bool isSc0Gen = (std::abs(particle.flagMcMatchGen()) == (1 << aod::hf_cand_sigmac::DecayType::Sc0ToPKPiPi)); - bool isScPlusPlusGen = (std::abs(particle.flagMcMatchGen()) == (1 << aod::hf_cand_sigmac::DecayType::ScplusplusToPKPiPi)); - if (!isSc0Gen && !isScPlusPlusGen) + bool isSc0Gen = (std::abs(particle.flagMcMatchGen()) == BIT(aod::hf_cand_sigmac::DecayType::Sc0ToPKPiPi)); + bool isScStar0Gen = (std::abs(particle.flagMcMatchGen()) == BIT(aod::hf_cand_sigmac::DecayType::ScStar0ToPKPiPi)); + bool isScPlusPlusGen = (std::abs(particle.flagMcMatchGen()) == BIT(aod::hf_cand_sigmac::DecayType::ScplusplusToPKPiPi)); + bool isScStarPlusPlusGen = (std::abs(particle.flagMcMatchGen()) == BIT(aod::hf_cand_sigmac::DecayType::ScStarPlusPlusToPKPiPi)); + if (!isSc0Gen && !isScPlusPlusGen && !isScStar0Gen && !isScStarPlusPlusGen) continue; /// look for generated particles in acceptance @@ -569,8 +582,20 @@ struct HfTaskSigmac { OR consider the new parametrization of the fiducial acceptance (to be seen for reco signal in MC) */ - if (yCandGenMax >= 0. && std::abs(RecoDecay::y(particle.pVector(), o2::constants::physics::MassSigmaC0)) > yCandGenMax) { - continue; + if (yCandGenMax >= 0.) { + double mass = -1; + if (isSc0Gen) { + mass = o2::constants::physics::MassSigmaC0; + } else if (isScPlusPlusGen) { + mass = o2::constants::physics::MassSigmaCPlusPlus; + } else if (isScStar0Gen) { + mass = o2::constants::physics::MassSigmaCStar0; + } else if (isScStarPlusPlusGen) { + mass = o2::constants::physics::MassSigmaCStarPlusPlus; + } + if (mass > -1. && std::abs(RecoDecay::y(particle.pVector(), mass)) > yCandGenMax) { + continue; + } } /// Get the kinematic information of Σc0,++ and the daughters @@ -579,7 +604,7 @@ struct HfTaskSigmac { double ptGenSc(particle.pt()), etaGenSc(particle.eta()), phiGenSc(particle.phi()); double ptGenScBMother(-1.); auto arrayDaughtersIds = particle.daughtersIds(); - if (arrayDaughtersIds.size() != 2) { + if (arrayDaughtersIds.size() != NDaughters) { /// This should never happen LOG(fatal) << "generated Σc0,++ has a number of daughter particles different than 2"; continue; @@ -617,7 +642,13 @@ struct HfTaskSigmac { } /// Fill histograms - if (isSc0Gen) { + int sigmacSpecies = -1; + if (isSc0Gen || isScPlusPlusGen) { + sigmacSpecies = o2::aod::hf_cand_sigmac::Sc2455; + } else if (isScStar0Gen || isScStarPlusPlusGen) { + sigmacSpecies = o2::aod::hf_cand_sigmac::Sc2520; + } + if (isSc0Gen || isScStar0Gen) { /// Generated Σc0 and Λc+ ← Σc0 signals registry.fill(HIST("MC/generated/hPtGenSc0Sig"), ptGenSc, origin, channel); registry.fill(HIST("MC/generated/hEtaGenSc0Sig"), etaGenSc, origin, channel); @@ -639,12 +670,19 @@ struct HfTaskSigmac { registry.fill(HIST("MC/generated/hEtaGenLcFromSc0PlusPlusSig"), etaGenLc, origin, channel); registry.fill(HIST("MC/generated/hPhiGenLcFromSc0PlusPlusSig"), phiGenLc, origin, channel); /// Generated Λc+ ← Σc0,++ signal if (origin == RecoDecay::OriginType::Prompt) { - registry.fill(HIST("hnSigmaCGen"), ptGenSc, ptGenScBMother, origin, channel, ptGenLc, 0); + registry.fill(HIST("MC/generated/hnSigmaCGen"), ptGenSc, ptGenScBMother, origin, channel, ptGenLc, 0, sigmacSpecies); } else { ptGenScBMother = mcParticlesSc.rawIteratorAt(particle.idxBhadMotherPart()).pt(); - registry.fill(HIST("hnSigmaCGen"), ptGenSc, ptGenScBMother, origin, channel, ptGenLc, 0); + registry.fill(HIST("MC/generated/hnSigmaCGen"), ptGenSc, ptGenScBMother, origin, channel, ptGenLc, 0, sigmacSpecies); } - } else if (isScPlusPlusGen) { + + // debug -- uncomment if needed + // it should be solved after the implementation of ev. selection for generated SigmaC particles + // if(origin != RecoDecay::OriginType::Prompt && origin != RecoDecay::OriginType::NonPrompt) { + // LOG(info) << " --> (Sc0 gen) origin " << static_cast(origin) << ", particle.originMcGen() " << static_cast(particle.originMcGen()) << ", particle.flagMcMatchGen() " << static_cast(particle.flagMcMatchGen()) << ", pdg " << particle.pdgCode(); + //} + + } else if (isScPlusPlusGen || isScStarPlusPlusGen) { /// Generated Σc++ and Λc+ ← Σc++ signals registry.fill(HIST("MC/generated/hPtGenScPlusPlusSig"), ptGenSc, origin, channel); registry.fill(HIST("MC/generated/hEtaGenScPlusPlusSig"), etaGenSc, origin, channel); @@ -666,18 +704,24 @@ struct HfTaskSigmac { registry.fill(HIST("MC/generated/hEtaGenLcFromSc0PlusPlusSig"), etaGenLc, origin, channel); registry.fill(HIST("MC/generated/hPhiGenLcFromSc0PlusPlusSig"), phiGenLc, origin, channel); /// Generated Λc+ ← Σc0,++ signal if (origin == RecoDecay::OriginType::Prompt) { - registry.fill(HIST("hnSigmaCGen"), ptGenSc, ptGenScBMother, origin, channel, ptGenLc, 2); + registry.fill(HIST("MC/generated/hnSigmaCGen"), ptGenSc, ptGenScBMother, origin, channel, ptGenLc, 2, sigmacSpecies); } else { ptGenScBMother = mcParticlesSc.rawIteratorAt(particle.idxBhadMotherPart()).pt(); - registry.fill(HIST("hnSigmaCGen"), ptGenSc, ptGenScBMother, origin, channel, ptGenLc, 2); + registry.fill(HIST("MC/generated/hnSigmaCGen"), ptGenSc, ptGenScBMother, origin, channel, ptGenLc, 2, sigmacSpecies); } + + // debug -- uncomment if needed + // it should be solved after the implementation of ev. selection for generated SigmaC particles + // if(origin != RecoDecay::OriginType::Prompt && origin != RecoDecay::OriginType::NonPrompt) { + // LOG(info) << " --> (Sc++ gen) origin " << static_cast(origin) << ", particle.originMcGen() " << static_cast(particle.originMcGen()) << ", particle.flagMcMatchGen() " << static_cast(particle.flagMcMatchGen()) << ", pdg " << particle.pdgCode(); + //} } } /// end loop over Sc generated particles /// loop over Lc generated particles for (const auto& particle : mcParticlesLc) { - if (std::abs(particle.flagMcMatchGen()) != 1 << aod::hf_cand_3prong::DecayType::LcToPKPi) { + if (std::abs(particle.flagMcMatchGen()) != BIT(aod::hf_cand_3prong::DecayType::LcToPKPi)) { continue; } if (yCandGenMax >= 0. && std::abs(RecoDecay::y(particle.pVector(), o2::constants::physics::MassLambdaCPlus)) > yCandGenMax) { @@ -687,10 +731,10 @@ struct HfTaskSigmac { int origin = particle.originMcGen(); int channel = particle.flagMcDecayChanGen(); if (origin == RecoDecay::OriginType::Prompt) { - registry.fill(HIST("hnLambdaCGen"), ptGenLc, ptGenLcBMother, origin, channel); + registry.fill(HIST("MC/generated/hnLambdaCGen"), ptGenLc, ptGenLcBMother, origin, channel); } else { ptGenLcBMother = mcParticlesLc.rawIteratorAt(particle.idxBhadMotherPart()).pt(); - registry.fill(HIST("hnLambdaCGen"), ptGenLc, ptGenLcBMother, origin, channel); + registry.fill(HIST("MC/generated/hnLambdaCGen"), ptGenLc, ptGenLcBMother, origin, channel); } } /// end loop over Lc generated particles @@ -698,10 +742,12 @@ struct HfTaskSigmac { for (const auto& candSc : candidatesSc) { /// Candidate selected as Σc0 and/or Σc++ - if (!(candSc.hfflag() & 1 << aod::hf_cand_sigmac::DecayType::Sc0ToPKPiPi) && !(candSc.hfflag() & 1 << aod::hf_cand_sigmac::DecayType::ScplusplusToPKPiPi)) { + if (!(candSc.hfflag() & BIT(aod::hf_cand_sigmac::DecayType::Sc0ToPKPiPi)) && !(candSc.hfflag() & BIT(aod::hf_cand_sigmac::DecayType::ScplusplusToPKPiPi)) && // Σc0,++(2455) + !(candSc.hfflag() & BIT(aod::hf_cand_sigmac::DecayType::ScStar0ToPKPiPi)) && !(candSc.hfflag() & BIT(aod::hf_cand_sigmac::DecayType::ScStarPlusPlusToPKPiPi))) { // Σc0,++(2520) continue; } /// rapidity selection on Σc0,++ + /// NB: since in data we cannot tag Sc(2455) and Sc(2520), then we use only Sc(2455) for y selection on reconstructed signal if (yCandRecoMax >= 0. && std::abs(hfHelper.ySc0(candSc)) > yCandRecoMax && std::abs(hfHelper.yScPlusPlus(candSc)) > yCandRecoMax) { continue; } @@ -712,14 +758,28 @@ struct HfTaskSigmac { /// get the candidate Λc+ used to build the Σc0 /// and understand which mass hypotheses are possible const auto& candidateLc = candSc.prongLc_as(); - const int isCandPKPiPiKP = isDecayToPKPiToPiKP(candidateLc, candSc); + const int8_t isCandPKPiPiKP = isDecayToPKPiToPiKP(candidateLc, candSc); // candidateLc.flagMcDecayChanRec(); - /// Reconstructed Σc0 signal - if (std::abs(candSc.flagMcMatchRec()) == 1 << aod::hf_cand_sigmac::DecayType::Sc0ToPKPiPi && (chargeSc == 0)) { + bool isTrueSc0Reco = std::abs(candSc.flagMcMatchRec()) == BIT(aod::hf_cand_sigmac::DecayType::Sc0ToPKPiPi); + bool isTrueScStar0Reco = std::abs(candSc.flagMcMatchRec()) == BIT(aod::hf_cand_sigmac::DecayType::ScStar0ToPKPiPi); + bool isTrueScPlusPlusReco = std::abs(candSc.flagMcMatchRec()) == BIT(aod::hf_cand_sigmac::DecayType::ScplusplusToPKPiPi); + bool isTrueScStarPlusPlusReco = std::abs(candSc.flagMcMatchRec()) == BIT(aod::hf_cand_sigmac::DecayType::ScStarPlusPlusToPKPiPi); + int sigmacSpecies = -1; + if ((isTrueSc0Reco || isTrueScStar0Reco) && (chargeSc == o2::aod::hf_cand_sigmac::ChargeNull)) { + /// Reconstructed Σc0 signal // Get the corresponding MC particle for Sc, found as the mother of the soft pion - auto indexMcScRec = RecoDecay::getMother(mcParticles, candSc.prong1_as().mcParticle(), o2::constants::physics::Pdg::kSigmaC0, true); + int indexMcScRec = -1; + if (isTrueSc0Reco) { + // Σc0(2455) + indexMcScRec = RecoDecay::getMother(mcParticles, candSc.prong1_as().mcParticle(), o2::constants::physics::Pdg::kSigmaC0, true); + sigmacSpecies = o2::aod::hf_cand_sigmac::Sc2455; + } else if (isTrueScStar0Reco) { + // Σc0(2520) + indexMcScRec = RecoDecay::getMother(mcParticles, candSc.prong1_as().mcParticle(), o2::constants::physics::Pdg::kSigmaCStar0, true); + sigmacSpecies = o2::aod::hf_cand_sigmac::Sc2520; + } auto particleSc = mcParticles.rawIteratorAt(indexMcScRec); // Get the corresponding MC particle for Lc auto arrayDaughtersLc = std::array{candidateLc.template prong0_as(), candidateLc.template prong1_as(), candidateLc.template prong2_as()}; @@ -743,7 +803,7 @@ struct HfTaskSigmac { auto channel = candidateLc.flagMcDecayChanRec(); /// 0: direct; 1: Λc± → p± K*; 2: Λc± → Δ(1232)±± K∓; 3: Λc± → Λ(1520) π± /// candidate Λc+ → pK-π+ (and charge conjugate) within the range of M(pK-π+) chosen in the Σc0,++ builder - if ((isCandPKPiPiKP == 1 || isCandPKPiPiKP == 3) && std::abs(candidateLc.template prong0_as().mcParticle().pdgCode()) == kProton) { + if ((TESTBIT(isCandPKPiPiKP, o2::aod::hf_cand_sigmac::Decays::PKPi)) && std::abs(candidateLc.template prong0_as().mcParticle().pdgCode()) == kProton) { massSc = hfHelper.invMassScRecoLcToPKPi(candSc, candidateLc); massLc = hfHelper.invMassLcToPKPi(candidateLc); deltaMass = massSc - massLc; @@ -808,16 +868,16 @@ struct HfTaskSigmac { outputMl.at(0) = candidateLc.mlProbLcToPKPi()[0]; /// bkg score outputMl.at(1) = candidateLc.mlProbLcToPKPi()[2]; /// non-prompt score } - registry.get(HIST("hnSigmaC"))->Fill(ptLc, deltaMass, outputMl.at(0), outputMl.at(1), origin, channel, ptSc, std::abs(chargeSc), candSc.ptBhadMotherPart()); + registry.get(HIST("hnSigmaC"))->Fill(ptLc, deltaMass, outputMl.at(0), outputMl.at(1), origin, channel, ptSc, std::abs(chargeSc), candSc.ptBhadMotherPart(), sigmacSpecies); } else { /// fill w/o BDT information - registry.get(HIST("hnSigmaC"))->Fill(ptLc, deltaMass, decLengthLc, decLengthXYLc, cpaLc, cpaXYLc, origin, channel, ptSc, std::abs(chargeSc), candSc.ptBhadMotherPart()); + registry.get(HIST("hnSigmaC"))->Fill(ptLc, deltaMass, decLengthLc, decLengthXYLc, cpaLc, cpaXYLc, origin, channel, ptSc, std::abs(chargeSc), candSc.ptBhadMotherPart(), sigmacSpecies); } } } /// end candidate Λc+ → pK-π+ (and charge conjugate) /// candidate Λc+ → π+K-p (and charge conjugate) within the range of M(π+K-p) chosen in the Σc0,++ builder - if ((isCandPKPiPiKP == 2 || isCandPKPiPiKP == 3) && std::abs(candidateLc.template prong0_as().mcParticle().pdgCode()) == kPiPlus) { + if ((TESTBIT(isCandPKPiPiKP, o2::aod::hf_cand_sigmac::Decays::PiKP)) && std::abs(candidateLc.template prong0_as().mcParticle().pdgCode()) == kPiPlus) { massSc = hfHelper.invMassScRecoLcToPiKP(candSc, candidateLc); massLc = hfHelper.invMassLcToPiKP(candidateLc); deltaMass = massSc - massLc; @@ -882,19 +942,28 @@ struct HfTaskSigmac { outputMl.at(0) = candidateLc.mlProbLcToPiKP()[0]; /// bkg score outputMl.at(1) = candidateLc.mlProbLcToPiKP()[2]; /// non-prompt score } - registry.get(HIST("hnSigmaC"))->Fill(ptLc, deltaMass, outputMl.at(0), outputMl.at(1), origin, channel, ptSc, std::abs(chargeSc), candSc.ptBhadMotherPart()); + registry.get(HIST("hnSigmaC"))->Fill(ptLc, deltaMass, outputMl.at(0), outputMl.at(1), origin, channel, ptSc, std::abs(chargeSc), candSc.ptBhadMotherPart(), sigmacSpecies); } else { /// fill w/o BDT information - registry.get(HIST("hnSigmaC"))->Fill(ptLc, deltaMass, decLengthLc, decLengthXYLc, cpaLc, cpaXYLc, origin, channel, ptSc, std::abs(chargeSc), candSc.ptBhadMotherPart()); + registry.get(HIST("hnSigmaC"))->Fill(ptLc, deltaMass, decLengthLc, decLengthXYLc, cpaLc, cpaXYLc, origin, channel, ptSc, std::abs(chargeSc), candSc.ptBhadMotherPart(), sigmacSpecies); } } } /// end candidate Λc+ → π+K-p (and charge conjugate) /// end reconstructed Σc0 signal - } else if (std::abs(candSc.flagMcMatchRec()) == 1 << aod::hf_cand_sigmac::DecayType::ScplusplusToPKPiPi && (std::abs(chargeSc) == 2)) { + } else if ((isTrueScPlusPlusReco || isTrueScStarPlusPlusReco) && (std::abs(chargeSc) == o2::aod::hf_cand_sigmac::ChargePlusPlus)) { /// Reconstructed Σc++ signal // Get the corresponding MC particle for Sc, found as the mother of the soft pion - auto indexMcScRec = RecoDecay::getMother(mcParticles, candSc.prong1_as().mcParticle(), o2::constants::physics::Pdg::kSigmaCPlusPlus, true); + int indexMcScRec = -1; + if (isTrueScPlusPlusReco) { + // Σc0(2455) + indexMcScRec = RecoDecay::getMother(mcParticles, candSc.prong1_as().mcParticle(), o2::constants::physics::Pdg::kSigmaCPlusPlus, true); + sigmacSpecies = o2::aod::hf_cand_sigmac::Sc2455; + } else if (isTrueScStarPlusPlusReco) { + // Σc0(2520) + indexMcScRec = RecoDecay::getMother(mcParticles, candSc.prong1_as().mcParticle(), o2::constants::physics::Pdg::kSigmaCStarPlusPlus, true); + sigmacSpecies = o2::aod::hf_cand_sigmac::Sc2520; + } auto particleSc = mcParticles.rawIteratorAt(indexMcScRec); // Get the corresponding MC particle for Lc auto arrayDaughtersLc = std::array{candidateLc.template prong0_as(), candidateLc.template prong1_as(), candidateLc.template prong2_as()}; @@ -918,7 +987,7 @@ struct HfTaskSigmac { auto channel = candidateLc.flagMcDecayChanRec(); /// 0: direct; 1: Λc± → p± K*; 2: Λc± → Δ(1232)±± K∓; 3: Λc± → Λ(1520) π± /// candidate Λc+ → pK-π+ (and charge conjugate) within the range of M(pK-π+) chosen in the Σc0,++ builder - if ((isCandPKPiPiKP == 1 || isCandPKPiPiKP == 3) && std::abs(candidateLc.template prong0_as().mcParticle().pdgCode()) == kProton) { + if ((TESTBIT(isCandPKPiPiKP, o2::aod::hf_cand_sigmac::Decays::PKPi)) && std::abs(candidateLc.template prong0_as().mcParticle().pdgCode()) == kProton) { massSc = hfHelper.invMassScRecoLcToPKPi(candSc, candidateLc); massLc = hfHelper.invMassLcToPKPi(candidateLc); deltaMass = massSc - massLc; @@ -983,16 +1052,16 @@ struct HfTaskSigmac { outputMl.at(0) = candidateLc.mlProbLcToPKPi()[0]; /// bkg score outputMl.at(1) = candidateLc.mlProbLcToPKPi()[2]; /// non-prompt score } - registry.get(HIST("hnSigmaC"))->Fill(ptLc, deltaMass, outputMl.at(0), outputMl.at(1), origin, channel, ptSc, std::abs(chargeSc), candSc.ptBhadMotherPart()); + registry.get(HIST("hnSigmaC"))->Fill(ptLc, deltaMass, outputMl.at(0), outputMl.at(1), origin, channel, ptSc, std::abs(chargeSc), candSc.ptBhadMotherPart(), sigmacSpecies); } else { /// fill w/o BDT information - registry.get(HIST("hnSigmaC"))->Fill(ptLc, deltaMass, decLengthLc, decLengthXYLc, cpaLc, cpaXYLc, origin, channel, ptSc, std::abs(chargeSc), candSc.ptBhadMotherPart()); + registry.get(HIST("hnSigmaC"))->Fill(ptLc, deltaMass, decLengthLc, decLengthXYLc, cpaLc, cpaXYLc, origin, channel, ptSc, std::abs(chargeSc), candSc.ptBhadMotherPart(), sigmacSpecies); } } } /// end candidate Λc+ → pK-π+ (and charge conjugate) /// candidate Λc+ → π+K-p (and charge conjugate) within the range of M(π+K-p) chosen in the Σc0,++ builder - if ((isCandPKPiPiKP == 2 || isCandPKPiPiKP == 3) && std::abs(candidateLc.template prong0_as().mcParticle().pdgCode()) == kPiPlus) { + if ((TESTBIT(isCandPKPiPiKP, o2::aod::hf_cand_sigmac::Decays::PiKP)) && std::abs(candidateLc.template prong0_as().mcParticle().pdgCode()) == kPiPlus) { massSc = hfHelper.invMassScRecoLcToPiKP(candSc, candidateLc); massLc = hfHelper.invMassLcToPiKP(candidateLc); deltaMass = massSc - massLc; @@ -1055,15 +1124,15 @@ struct HfTaskSigmac { outputMl.at(0) = candidateLc.mlProbLcToPiKP()[0]; /// bkg score outputMl.at(1) = candidateLc.mlProbLcToPiKP()[2]; /// non-prompt score } - registry.get(HIST("hnSigmaC"))->Fill(ptLc, deltaMass, outputMl.at(0), outputMl.at(1), origin, channel, ptSc, std::abs(chargeSc), candSc.ptBhadMotherPart()); + registry.get(HIST("hnSigmaC"))->Fill(ptLc, deltaMass, outputMl.at(0), outputMl.at(1), origin, channel, ptSc, std::abs(chargeSc), candSc.ptBhadMotherPart(), sigmacSpecies); } else { /// fill w/o BDT information - registry.get(HIST("hnSigmaC"))->Fill(ptLc, deltaMass, decLengthLc, decLengthXYLc, cpaLc, cpaXYLc, origin, channel, ptSc, std::abs(chargeSc), candSc.ptBhadMotherPart()); + registry.get(HIST("hnSigmaC"))->Fill(ptLc, deltaMass, decLengthLc, decLengthXYLc, cpaLc, cpaXYLc, origin, channel, ptSc, std::abs(chargeSc), candSc.ptBhadMotherPart(), sigmacSpecies); } } } /// end candidate Λc+ → π+K-p (and charge conjugate) - } /// end reconstructed Σc++ signal + } /// end reconstructed Σc++ signal } /// end loop on reconstructed Σc0,++ diff --git a/PWGHF/D2H/Tasks/taskXic.cxx b/PWGHF/D2H/Tasks/taskXic.cxx index 6ec5e39a687..24c3e1b3814 100644 --- a/PWGHF/D2H/Tasks/taskXic.cxx +++ b/PWGHF/D2H/Tasks/taskXic.cxx @@ -71,7 +71,7 @@ struct HfTaskXic { Filter filterSelectCandidates = (aod::hf_sel_candidate_xic::isSelXicToPKPi >= selectionFlagXic || aod::hf_sel_candidate_xic::isSelXicToPiKP >= selectionFlagXic); - Partition> selectedMCXicCandidates = (aod::hf_sel_candidate_xic::isSelXicToPKPi >= selectionFlagXic || aod::hf_sel_candidate_xic::isSelXicToPiKP >= selectionFlagXic); + Partition> selectedMCXicCandidates = (aod::hf_sel_candidate_xic::isSelXicToPKPi >= selectionFlagXic || aod::hf_sel_candidate_xic::isSelXicToPiKP >= selectionFlagXic); HistogramRegistry registry{ "registry", // histo not in pt bins @@ -325,30 +325,30 @@ struct HfTaskXic { auto momentumProng2 = trackProng2.p(); // TPC nSigma histograms - registry.fill(HIST("Data/hPVsTPCNSigmaPr_Prong0"), momentumProng0, trackProng0.tpcNSigmaPr()); - registry.fill(HIST("Data/hPVsTPCNSigmaPi_Prong0"), momentumProng0, trackProng0.tpcNSigmaPi()); - registry.fill(HIST("Data/hPVsTPCNSigmaKa_Prong0"), momentumProng0, trackProng0.tpcNSigmaKa()); + registry.fill(HIST("Data/hPVsTPCNSigmaPr_Prong0"), momentumProng0, candidate.nSigTpcPr0()); + registry.fill(HIST("Data/hPVsTPCNSigmaPi_Prong0"), momentumProng0, candidate.nSigTpcPi0()); + registry.fill(HIST("Data/hPVsTPCNSigmaKa_Prong0"), momentumProng0, candidate.nSigTpcKa0()); - registry.fill(HIST("Data/hPVsTPCNSigmaPr_Prong1"), momentumProng1, trackProng1.tpcNSigmaPr()); - registry.fill(HIST("Data/hPVsTPCNSigmaPi_Prong1"), momentumProng1, trackProng1.tpcNSigmaPi()); - registry.fill(HIST("Data/hPVsTPCNSigmaKa_Prong1"), momentumProng1, trackProng1.tpcNSigmaKa()); + registry.fill(HIST("Data/hPVsTPCNSigmaPr_Prong1"), momentumProng1, candidate.nSigTpcPr1()); + registry.fill(HIST("Data/hPVsTPCNSigmaPi_Prong1"), momentumProng1, candidate.nSigTpcPi1()); + registry.fill(HIST("Data/hPVsTPCNSigmaKa_Prong1"), momentumProng1, candidate.nSigTpcKa1()); - registry.fill(HIST("Data/hPVsTPCNSigmaPr_Prong2"), momentumProng2, trackProng2.tpcNSigmaPr()); - registry.fill(HIST("Data/hPVsTPCNSigmaPi_Prong2"), momentumProng2, trackProng2.tpcNSigmaPi()); - registry.fill(HIST("Data/hPVsTPCNSigmaKa_Prong2"), momentumProng2, trackProng2.tpcNSigmaKa()); + registry.fill(HIST("Data/hPVsTPCNSigmaPr_Prong2"), momentumProng2, candidate.nSigTpcPr2()); + registry.fill(HIST("Data/hPVsTPCNSigmaPi_Prong2"), momentumProng2, candidate.nSigTpcPi2()); + registry.fill(HIST("Data/hPVsTPCNSigmaKa_Prong2"), momentumProng2, candidate.nSigTpcKa2()); // TOF nSigma histograms - registry.fill(HIST("Data/hPVsTOFNSigmaPr_Prong0"), momentumProng0, trackProng0.tofNSigmaPr()); - registry.fill(HIST("Data/hPVsTOFNSigmaPi_Prong0"), momentumProng0, trackProng0.tofNSigmaPi()); - registry.fill(HIST("Data/hPVsTOFNSigmaKa_Prong0"), momentumProng0, trackProng0.tofNSigmaKa()); + registry.fill(HIST("Data/hPVsTOFNSigmaPr_Prong0"), momentumProng0, candidate.nSigTofPr0()); + registry.fill(HIST("Data/hPVsTOFNSigmaPi_Prong0"), momentumProng0, candidate.nSigTofPi0()); + registry.fill(HIST("Data/hPVsTOFNSigmaKa_Prong0"), momentumProng0, candidate.nSigTofKa0()); - registry.fill(HIST("Data/hPVsTOFNSigmaPr_Prong1"), momentumProng1, trackProng1.tofNSigmaPr()); - registry.fill(HIST("Data/hPVsTOFNSigmaPi_Prong1"), momentumProng1, trackProng1.tofNSigmaPi()); - registry.fill(HIST("Data/hPVsTOFNSigmaKa_Prong1"), momentumProng1, trackProng1.tofNSigmaKa()); + registry.fill(HIST("Data/hPVsTOFNSigmaPr_Prong1"), momentumProng1, candidate.nSigTofPr1()); + registry.fill(HIST("Data/hPVsTOFNSigmaPi_Prong1"), momentumProng1, candidate.nSigTofPi1()); + registry.fill(HIST("Data/hPVsTOFNSigmaKa_Prong1"), momentumProng1, candidate.nSigTofKa1()); - registry.fill(HIST("Data/hPVsTOFNSigmaPr_Prong2"), momentumProng2, trackProng2.tofNSigmaPr()); - registry.fill(HIST("Data/hPVsTOFNSigmaPi_Prong2"), momentumProng2, trackProng2.tofNSigmaPi()); - registry.fill(HIST("Data/hPVsTOFNSigmaKa_Prong2"), momentumProng2, trackProng2.tofNSigmaKa()); + registry.fill(HIST("Data/hPVsTOFNSigmaPr_Prong2"), momentumProng2, candidate.nSigTofPr2()); + registry.fill(HIST("Data/hPVsTOFNSigmaPi_Prong2"), momentumProng2, candidate.nSigTofPi2()); + registry.fill(HIST("Data/hPVsTOFNSigmaKa_Prong2"), momentumProng2, candidate.nSigTofKa2()); // THnSparse if (enableTHn) { @@ -383,11 +383,11 @@ struct HfTaskXic { } } } // thn for Xic - } // loop candidates - } // end process data + } // loop candidates + } // end process data void processDataStd(aod::Collision const& collision, - soa::Filtered> const& candidates, + soa::Filtered> const& candidates, TracksWPid const& tracks) { analysisData(collision, candidates, tracks); @@ -395,7 +395,7 @@ struct HfTaskXic { PROCESS_SWITCH(HfTaskXic, processDataStd, "Process Data with the standard method", true); void processDataWithMl(aod::Collision const& collision, - soa::Filtered> const& candidatesMl, TracksWPid const& tracks) + soa::Filtered> const& candidatesMl, TracksWPid const& tracks) { analysisData(collision, candidatesMl, tracks); } @@ -567,7 +567,7 @@ struct HfTaskXic { registry.fill(HIST("MC/reconstructed/background/hDecLenErrBg"), candidate.errorDecayLength(), ptCandidate); registry.fill(HIST("MC/reconstructed/background/hChi2PCARecBg"), candidate.chi2PCA(), ptCandidate); } // Xic background - } // candidate loop + } // candidate loop // MC gen. for (const auto& particle : mcParticles) { @@ -600,7 +600,7 @@ struct HfTaskXic { } } } - void processMcStd(soa::Filtered> const& selectedCandidatesMc, + void processMcStd(soa::Filtered> const& selectedCandidatesMc, soa::Join const& mcParticles, aod::TracksWMc const& tracksWithMc) { @@ -608,7 +608,7 @@ struct HfTaskXic { } PROCESS_SWITCH(HfTaskXic, processMcStd, "Process MC with the standard method", false); - void processMcWithMl(soa::Filtered> const& selectedCandidatesMlMc, + void processMcWithMl(soa::Filtered> const& selectedCandidatesMlMc, soa::Join const& mcParticles, aod::TracksWMc const& tracksWithMc) { diff --git a/PWGHF/DataModel/CandidateReconstructionTables.h b/PWGHF/DataModel/CandidateReconstructionTables.h index 7ee144ca397..1210ea896fa 100644 --- a/PWGHF/DataModel/CandidateReconstructionTables.h +++ b/PWGHF/DataModel/CandidateReconstructionTables.h @@ -1042,6 +1042,7 @@ DECLARE_SOA_EXTENDED_TABLE_USER(HfCand3ProngExt, HfCand3ProngBase, "HFCAND3PEXT" hf_cand_3prong::Px, hf_cand_3prong::Py, hf_cand_3prong::Pz); using HfCand3Prong = HfCand3ProngExt; +using HfCand3ProngWPid = soa::Join; DECLARE_SOA_TABLE(HfCand3ProngKF, "AOD", "HFCAND3PKF", hf_cand_3prong::KfXError, hf_cand_3prong::KfYError, hf_cand_3prong::KfZError, @@ -1368,6 +1369,58 @@ DECLARE_SOA_COLUMN(MassV0Chi2OverNdf, massV0Chi2OverNdf, float); DECLARE_SOA_COLUMN(MassCascChi2OverNdf, massCascChi2OverNdf, float); DECLARE_SOA_COLUMN(CascRejectInvmass, cascRejectInvmass, float); +// Kf QA results: +DECLARE_SOA_COLUMN(InvMassV0Err, invMassV0Err, float); +DECLARE_SOA_COLUMN(InvMassXiErr, invMassXiErr, float); +DECLARE_SOA_COLUMN(InvMassXic0Err, invMassXic0Err, float); +DECLARE_SOA_COLUMN(V0DauPosX, v0DauPosX, float); +DECLARE_SOA_COLUMN(V0DauPosY, v0DauPosY, float); +DECLARE_SOA_COLUMN(V0DauPosZ, v0DauPosZ, float); +DECLARE_SOA_COLUMN(V0DauPosXError, v0DauPosXError, float); +DECLARE_SOA_COLUMN(V0DauPosYError, v0DauPosYError, float); +DECLARE_SOA_COLUMN(V0DauPosZError, v0DauPosZError, float); +DECLARE_SOA_COLUMN(V0DauPosPt, v0DauPosPt, float); +DECLARE_SOA_COLUMN(V0DauNegX, v0DauNegX, float); +DECLARE_SOA_COLUMN(V0DauNegY, v0DauNegY, float); +DECLARE_SOA_COLUMN(V0DauNegZ, v0DauNegZ, float); +DECLARE_SOA_COLUMN(V0DauNegXError, v0DauNegXError, float); +DECLARE_SOA_COLUMN(V0DauNegYError, v0DauNegYError, float); +DECLARE_SOA_COLUMN(V0DauNegZError, v0DauNegZError, float); +DECLARE_SOA_COLUMN(V0DauNegPt, v0DauNegPt, float); + +DECLARE_SOA_COLUMN(V0VtxX, v0VtxX, float); +DECLARE_SOA_COLUMN(V0VtxY, v0VtxY, float); +DECLARE_SOA_COLUMN(V0VtxZ, v0VtxZ, float); +DECLARE_SOA_COLUMN(V0XError, v0XError, float); +DECLARE_SOA_COLUMN(V0YError, v0YError, float); +DECLARE_SOA_COLUMN(V0ZError, v0ZError, float); +DECLARE_SOA_COLUMN(V0Pt, v0Pt, float); +DECLARE_SOA_COLUMN(XiBachelorX, xiBachelorX, float); +DECLARE_SOA_COLUMN(XiBachelorY, xiBachelorY, float); +DECLARE_SOA_COLUMN(XiBachelorZ, xiBachelorZ, float); +DECLARE_SOA_COLUMN(XiBachelorPt, xiBachelorPt, float); +DECLARE_SOA_COLUMN(XiBachelorXError, xiBachelorXError, float); +DECLARE_SOA_COLUMN(XiBachelorYError, xiBachelorYError, float); +DECLARE_SOA_COLUMN(XiBachelorZError, xiBachelorZError, float); +DECLARE_SOA_COLUMN(XiX, xiX, float); +DECLARE_SOA_COLUMN(XiY, xiY, float); +DECLARE_SOA_COLUMN(XiZ, xiZ, float); +DECLARE_SOA_COLUMN(XiXError, xiXError, float); +DECLARE_SOA_COLUMN(XiYError, xiYError, float); +DECLARE_SOA_COLUMN(XiZError, xiZError, float); +DECLARE_SOA_COLUMN(XiPt, xiPt, float); +DECLARE_SOA_COLUMN(Xic0BachelorX, xic0BachelorX, float); +DECLARE_SOA_COLUMN(Xic0BachelorY, xic0BachelorY, float); +DECLARE_SOA_COLUMN(Xic0BachelorZ, xic0BachelorZ, float); +DECLARE_SOA_COLUMN(Xic0BachelorPt, xic0BachelorPt, float); +DECLARE_SOA_COLUMN(Xic0BachelorXError, xic0BachelorXError, float); +DECLARE_SOA_COLUMN(Xic0BachelorYError, xic0BachelorYError, float); +DECLARE_SOA_COLUMN(Xic0BachelorZError, xic0BachelorZError, float); +DECLARE_SOA_COLUMN(Xic0Pt, xic0Pt, float); +DECLARE_SOA_COLUMN(Xic0XError, xic0XError, float); +DECLARE_SOA_COLUMN(Xic0YError, xic0YError, float); +DECLARE_SOA_COLUMN(Xic0ZError, xic0ZError, float); + // MC matching result: DECLARE_SOA_COLUMN(FlagMcMatchRec, flagMcMatchRec, int8_t); // reconstruction level DECLARE_SOA_COLUMN(DebugMcRec, debugMcRec, int8_t); // debug flag for mis-association reconstruction level @@ -1557,6 +1610,19 @@ DECLARE_SOA_TABLE(HfCandToXiPiKf, "AOD", "HFCANDTOXIPIKF", //! hf_cand_xic0_omegac0::V0Chi2OverNdf, hf_cand_xic0_omegac0::CascChi2OverNdf, hf_cand_xic0_omegac0::XicChi2OverNdf, hf_cand_xic0_omegac0::MassV0Chi2OverNdf, hf_cand_xic0_omegac0::MassCascChi2OverNdf); +DECLARE_SOA_TABLE(HfCandToXiPiKfQa, "AOD", "HFCANDTOXIPIKFQA", + o2::soa::Index<>, + hf_cand_xic0_omegac0::InvMassLambda, hf_cand_xic0_omegac0::InvMassCascade, hf_cand_xic0_omegac0::InvMassCharmBaryon, hf_cand_xic0_omegac0::InvMassV0Err, hf_cand_xic0_omegac0::InvMassXiErr, hf_cand_xic0_omegac0::InvMassXic0Err, + hf_cand_xic0_omegac0::CollisionId, hf_track_index::V0Id, v0data::PosTrackId, v0data::NegTrackId, hf_cand_xic0_omegac0::CascadeId, hf_cand_xic0_omegac0::BachelorFromCharmBaryonId, cascdata::BachelorId, + hf_cand_xic0_omegac0::V0DauPosX, hf_cand_xic0_omegac0::V0DauPosY, hf_cand_xic0_omegac0::V0DauPosZ, hf_cand_xic0_omegac0::V0DauPosXError, hf_cand_xic0_omegac0::V0DauPosYError, hf_cand_xic0_omegac0::V0DauPosZError, hf_cand_xic0_omegac0::V0DauPosPt, + hf_cand_xic0_omegac0::V0DauNegX, hf_cand_xic0_omegac0::V0DauNegY, hf_cand_xic0_omegac0::V0DauNegZ, hf_cand_xic0_omegac0::V0DauNegXError, hf_cand_xic0_omegac0::V0DauNegYError, hf_cand_xic0_omegac0::V0DauNegZError, hf_cand_xic0_omegac0::V0DauNegPt, + hf_cand_xic0_omegac0::V0VtxX, hf_cand_xic0_omegac0::V0VtxY, hf_cand_xic0_omegac0::V0VtxZ, hf_cand_xic0_omegac0::V0XError, hf_cand_xic0_omegac0::V0YError, hf_cand_xic0_omegac0::V0ZError, hf_cand_xic0_omegac0::V0Pt, + hf_cand_xic0_omegac0::XiBachelorX, hf_cand_xic0_omegac0::XiBachelorY, hf_cand_xic0_omegac0::XiBachelorZ, hf_cand_xic0_omegac0::XiBachelorXError, hf_cand_xic0_omegac0::XiBachelorYError, hf_cand_xic0_omegac0::XiBachelorZError, hf_cand_xic0_omegac0::XiBachelorPt, + hf_cand_xic0_omegac0::XiX, hf_cand_xic0_omegac0::XiY, hf_cand_xic0_omegac0::XiZ, hf_cand_xic0_omegac0::XiXError, hf_cand_xic0_omegac0::XiYError, hf_cand_xic0_omegac0::XiZError, hf_cand_xic0_omegac0::XiPt, + hf_cand_xic0_omegac0::Xic0BachelorX, hf_cand_xic0_omegac0::Xic0BachelorY, hf_cand_xic0_omegac0::Xic0BachelorZ, hf_cand_xic0_omegac0::Xic0BachelorXError, hf_cand_xic0_omegac0::Xic0BachelorYError, hf_cand_xic0_omegac0::Xic0BachelorZError, hf_cand_xic0_omegac0::Xic0BachelorPt, + hf_cand_xic0_omegac0::XDecayVtxCharmBaryon, hf_cand_xic0_omegac0::YDecayVtxCharmBaryon, hf_cand_xic0_omegac0::ZDecayVtxCharmBaryon, hf_cand_xic0_omegac0::Xic0XError, hf_cand_xic0_omegac0::Xic0YError, hf_cand_xic0_omegac0::Xic0ZError, hf_cand_xic0_omegac0::Xic0Pt, + hf_cand_casc::V0X, hf_cand_casc::V0Y, hf_cand_casc::V0Z, hf_cand_xic0_omegac0::XDecayVtxCascade, hf_cand_xic0_omegac0::YDecayVtxCascade, hf_cand_xic0_omegac0::ZDecayVtxCascade); + // table with results of reconstruction level MC matching DECLARE_SOA_TABLE(HfXicToXiPiMCRec, "AOD", "HFXICXIPIMCREC", //! hf_cand_xic0_omegac0::FlagMcMatchRec, @@ -2064,7 +2130,17 @@ DECLARE_SOA_COLUMN(OriginMcGen, originMcGen, int8_t); //! particle origin, // mapping of decay types enum DecayType { Sc0ToPKPiPi = 0, - ScplusplusToPKPiPi }; + ScplusplusToPKPiPi, + ScStar0ToPKPiPi, + ScStarPlusPlusToPKPiPi }; +enum Species : int { Sc2455 = 0, + Sc2520, + NSpecies }; +enum Decays : int { PKPi = 0, + PiKP, + NDecays }; +constexpr int ChargeNull = 0; +constexpr int ChargePlusPlus = 2; } // namespace hf_cand_sigmac // declare dedicated Σc0,++ decay candidate table @@ -2293,8 +2369,8 @@ DECLARE_SOA_DYNAMIC_COLUMN(PtSoftPi, ptSoftPi, [](float pxSoftPi, float pySoftPi DECLARE_SOA_DYNAMIC_COLUMN(PVecSoftPi, pVecSoftPi, [](float px, float py, float pz) -> std::array { return std::array{px, py, pz}; }); // MC matching result: -DECLARE_SOA_COLUMN(FlagMcMatchRec, flagMcMatchRec, int8_t); //! reconstruction level -DECLARE_SOA_COLUMN(FlagMcMatchGen, flagMcMatchGen, int8_t); //! generator level +DECLARE_SOA_COLUMN(FlagMcMatchRec, flagMcMatchRec, int8_t); //! reconstruction level +DECLARE_SOA_COLUMN(FlagMcMatchGen, flagMcMatchGen, int8_t); //! generator level DECLARE_SOA_COLUMN(FlagMcMatchRecD0, flagMcMatchRecD0, int8_t); //! reconstruction level DECLARE_SOA_COLUMN(FlagMcMatchGenD0, flagMcMatchGenD0, int8_t); //! generator level @@ -2365,6 +2441,7 @@ DECLARE_SOA_EXTENDED_TABLE_USER(HfD0FromDstarExt, HfD0FromDstarBase, "HFD0FRMDST hf_cand_dstar::PxD0, hf_cand_dstar::PyD0, hf_cand_dstar::PzD0); using HfD0FromDstar = HfD0FromDstarExt; +using HfD0FromDstarWPid = soa::Join; DECLARE_SOA_TABLE(HfCandDstarBase, "AOD", "HFCANDDSTRBASE", o2::soa::Index<>, @@ -2415,6 +2492,7 @@ DECLARE_SOA_EXTENDED_TABLE_USER(HfCandDstarExt, HfCandDstarBase, "HFCANDDSTREXT" using HfCandDstars = HfCandDstarExt; using HfCandDstar = HfCandDstars::iterator; +using HfCandDstarsWPid = soa::Join; // table with results of reconstruction level MC matching DECLARE_SOA_TABLE(HfCandDstarMcRec, "AOD", "HFCANDDSTRMCREC", diff --git a/PWGHF/HFC/DataModel/CorrelationTables.h b/PWGHF/HFC/DataModel/CorrelationTables.h index 0ffeeea8868..3dad5548b27 100644 --- a/PWGHF/HFC/DataModel/CorrelationTables.h +++ b/PWGHF/HFC/DataModel/CorrelationTables.h @@ -342,6 +342,7 @@ DECLARE_SOA_COLUMN(PtHadron, ptHadron, float); //! T DECLARE_SOA_COLUMN(MD, mD, float); //! Invariant mass of D+ DECLARE_SOA_COLUMN(MlScoreBkg, mlScoreBkg, float); //! ML background score for D+ selection DECLARE_SOA_COLUMN(MlScorePrompt, mlScorePrompt, float); //! ML prompt score for D+ selection +DECLARE_SOA_COLUMN(MlScoreNonPrompt, mlScoreNonPrompt, float); //! ML non-prompt score for D+ selection DECLARE_SOA_COLUMN(SignalStatus, signalStatus, bool); //! Used in MC-Rec, D+ Signal DECLARE_SOA_COLUMN(PoolBin, poolBin, int); //! Pool Bin of event defined using zvtx and multiplicity DECLARE_SOA_COLUMN(TrackDcaXY, trackDcaXY, float); //! DCA xy of the track @@ -372,13 +373,15 @@ DECLARE_SOA_TABLE(DplusHadronGenInfo, "AOD", "DPLUSHGENINFO", //! Ds-Hadrons pai DECLARE_SOA_TABLE(DplusHadronMlInfo, "AOD", "DPLUSHMLINFO", //! D+-Hadrons pairs Machine Learning Information aod::hf_correlation_dplus_hadron::MlScoreBkg, - aod::hf_correlation_dplus_hadron::MlScorePrompt); + aod::hf_correlation_dplus_hadron::MlScorePrompt, + aod::hf_correlation_dplus_hadron::MlScoreNonPrompt); DECLARE_SOA_TABLE(DplusRecoInfo, "AOD", "DPLUSRECOINFO", //! D+ candidates Reconstructed Information aod::hf_correlation_dplus_hadron::MD, aod::hf_correlation_dplus_hadron::PtD, aod::hf_correlation_dplus_hadron::MlScoreBkg, - aod::hf_correlation_dplus_hadron::MlScorePrompt); + aod::hf_correlation_dplus_hadron::MlScorePrompt, + aod::hf_correlation_dplus_hadron::MlScoreNonPrompt); DECLARE_SOA_TABLE(DplusGenInfo, "AOD", "DPLUSGENOINFO", //! D+ candidates Generated Information aod::hf_correlation_dplus_hadron::IsPrompt); diff --git a/PWGHF/HFC/TableProducer/CMakeLists.txt b/PWGHF/HFC/TableProducer/CMakeLists.txt index 5d9a5d8d9a7..56b01bcd412 100644 --- a/PWGHF/HFC/TableProducer/CMakeLists.txt +++ b/PWGHF/HFC/TableProducer/CMakeLists.txt @@ -66,5 +66,5 @@ o2physics_add_dpl_workflow(correlator-lc-hadrons o2physics_add_dpl_workflow(femto-dream-producer SOURCES femtoDreamProducer.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2Physics::EventFilteringUtils + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2Physics::EventFilteringUtils O2Physics::MLCore COMPONENT_NAME Analysis) diff --git a/PWGHF/HFC/TableProducer/correlatorDplusHadrons.cxx b/PWGHF/HFC/TableProducer/correlatorDplusHadrons.cxx index d9ac67f59ae..d6c50370ed5 100644 --- a/PWGHF/HFC/TableProducer/correlatorDplusHadrons.cxx +++ b/PWGHF/HFC/TableProducer/correlatorDplusHadrons.cxx @@ -10,6 +10,7 @@ // or submit itself to any jurisdiction. /// \file correlatorDplusHadrons.cxx +/// \brief D+-Hadrons correlator task - data-like, MC-reco and MC-Gen analyses /// \author Shyam Kumar #include @@ -161,6 +162,7 @@ struct HfCorrelatorDplusHadrons { Produces entryTrackRecoInfo; Produces entryDplus; Produces entryHadron; + static constexpr std::size_t NDaughters{3u}; Configurable selectionFlagDplus{"selectionFlagDplus", 7, "Selection Flag for Dplus"}; // 7 corresponds to topo+PID cuts Configurable numberEventsMixed{"numberEventsMixed", 5, "Number of events mixed in ME process"}; @@ -182,19 +184,9 @@ struct HfCorrelatorDplusHadrons { Configurable> binsPtHadron{"binsPtHadron", std::vector{0.3, 2., 4., 8., 12., 50.}, "pT bin limits for assoc particle"}; Configurable> binsPtEfficiencyD{"binsPtEfficiencyD", std::vector{o2::analysis::hf_cuts_dplus_to_pi_k_pi::vecBinsPt}, "pT bin limits for efficiency"}; Configurable> efficiencyD{"efficiencyD", {1., 1., 1., 1., 1., 1.}, "efficiency values for D+ meson"}; - ConfigurableAxis binsMultiplicity{"binsMultiplicity", {VARIABLE_WIDTH, 0.0f, 2000.0f, 6000.0f, 100000.0f}, "Mixing bins - multiplicity"}; - ConfigurableAxis binsZVtx{"binsZVtx", {VARIABLE_WIDTH, -10.0f, -2.5f, 2.5f, 10.0f}, "Mixing bins - z-vertex"}; - ConfigurableAxis binsMultiplicityMc{"binsMultiplicityMc", {VARIABLE_WIDTH, 0.0f, 20.0f, 50.0f, 500.0f}, "Mixing bins - MC multiplicity"}; // In MCGen multiplicity is defined by counting tracks - ConfigurableAxis binsBdtScore{"binsBdtScore", {100, 0., 1.}, "Bdt output scores"}; - ConfigurableAxis binsEta{"binsEta", {50, -2., 2.}, "#it{#eta}"}; - ConfigurableAxis binsPhi{"binsPhi", {64, -PIHalf, 3. * PIHalf}, "#it{#varphi}"}; - ConfigurableAxis binsPoolBin{"binsPoolBin", {9, 0., 9.}, "PoolBin"}; - ConfigurableAxis binsMultFT0M{"binsMultFT0M", {600, 0., 6000.}, "Multiplicity as FT0M signal amplitude"}; - ConfigurableAxis binsMassD{"binsMassD", {200, 1.7, 2.10}, "inv. mass (#pi^{+}K^{-}#pi^{+}) (GeV/#it{c}^{2})"}; HfHelper hfHelper; SliceCache cache; - BinningType corrBinning{{binsZVtx, binsMultiplicity}, true}; // Event Mixing for the Data Mode using SelCollisionsWithDplus = soa::Filtered>; @@ -215,9 +207,16 @@ struct HfCorrelatorDplusHadrons { Filter dplusFilter = ((o2::aod::hf_track_index::hfflag & static_cast(1 << aod::hf_cand_3prong::DecayType::DplusToPiKPi)) != static_cast(0)) && aod::hf_sel_candidate_dplus::isSelDplusToPiKPi >= selectionFlagDplus; Filter trackFilter = (nabs(aod::track::eta) < etaTrackMax) && (nabs(aod::track::pt) > ptTrackMin) && (nabs(aod::track::dcaXY) < dcaXYTrackMax) && (nabs(aod::track::dcaZ) < dcaZTrackMax); // Filter particlesFilter = nabs(aod::mcparticle::pdgCode) == 411 || ((aod::mcparticle::flags & (uint8_t)o2::aod::mcparticle::enums::PhysicalPrimary) == (uint8_t)o2::aod::mcparticle::enums::PhysicalPrimary); - - Preslice perCol = aod::hf_cand::collisionId; - + ConfigurableAxis binsMultiplicity{"binsMultiplicity", {VARIABLE_WIDTH, 0.0f, 2000.0f, 6000.0f, 100000.0f}, "Mixing bins - multiplicity"}; + ConfigurableAxis binsZVtx{"binsZVtx", {VARIABLE_WIDTH, -10.0f, -2.5f, 2.5f, 10.0f}, "Mixing bins - z-vertex"}; + ConfigurableAxis binsMultiplicityMc{"binsMultiplicityMc", {VARIABLE_WIDTH, 0.0f, 20.0f, 50.0f, 500.0f}, "Mixing bins - MC multiplicity"}; // In MCGen multiplicity is defined by counting tracks + ConfigurableAxis binsBdtScore{"binsBdtScore", {100, 0., 1.}, "Bdt output scores"}; + ConfigurableAxis binsEta{"binsEta", {50, -2., 2.}, "#it{#eta}"}; + ConfigurableAxis binsPhi{"binsPhi", {64, -PIHalf, 3. * PIHalf}, "#it{#varphi}"}; + ConfigurableAxis binsPoolBin{"binsPoolBin", {9, 0., 9.}, "PoolBin"}; + ConfigurableAxis binsMultFT0M{"binsMultFT0M", {600, 0., 6000.}, "Multiplicity as FT0M signal amplitude"}; + ConfigurableAxis binsMassD{"binsMassD", {200, 1.7, 2.10}, "inv. mass (#pi^{+}K^{-}#pi^{+}) (GeV/#it{c}^{2})"}; + BinningType corrBinning{{binsZVtx, binsMultiplicity}, true}; HistogramRegistry registry{"registry", {}, OutputObjHandlingPolicy::AnalysisObject}; void init(InitContext&) @@ -344,7 +343,7 @@ struct HfCorrelatorDplusHadrons { for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) { outputMl[iclass] = candidate.mlProbDplusToPiKPi()[classMl->at(iclass)]; } - entryDplusCandRecoInfo(hfHelper.invMassDplusToPiKPi(candidate), candidate.pt(), outputMl[0], outputMl[1]); // 0: BkgBDTScore, 1:PromptBDTScore + entryDplusCandRecoInfo(hfHelper.invMassDplusToPiKPi(candidate), candidate.pt(), outputMl[0], outputMl[1], outputMl[2]); // 0: BkgBDTScore, 1:PromptBDTScore, 2: FDScore entryDplus(candidate.phi(), candidate.eta(), candidate.pt(), hfHelper.invMassDplusToPiKPi(candidate), poolBin, gCollisionId, timeStamp); // Dplus-Hadron correlation dedicated section @@ -366,7 +365,7 @@ struct HfCorrelatorDplusHadrons { track.pt(), poolBin); entryDplusHadronRecoInfo(hfHelper.invMassDplusToPiKPi(candidate), false); entryDplusHadronGenInfo(false, false, 0); - entryDplusHadronMlInfo(outputMl[0], outputMl[1]); + entryDplusHadronMlInfo(outputMl[0], outputMl[1], outputMl[2]); entryTrackRecoInfo(track.dcaXY(), track.dcaZ(), track.tpcNClsCrossedRows()); if (cntDplus == 0) { entryHadron(track.phi(), track.eta(), track.pt(), poolBin, gCollisionId, timeStamp); @@ -458,7 +457,7 @@ struct HfCorrelatorDplusHadrons { outputMl[iclass] = candidate.mlProbDplusToPiKPi()[classMl->at(iclass)]; } registry.fill(HIST("hMassDplusMcRecSig"), hfHelper.invMassDplusToPiKPi(candidate), candidate.pt(), efficiencyWeightD); - entryDplusCandRecoInfo(hfHelper.invMassDplusToPiKPi(candidate), candidate.pt(), outputMl[0], outputMl[1]); + entryDplusCandRecoInfo(hfHelper.invMassDplusToPiKPi(candidate), candidate.pt(), outputMl[0], outputMl[1], outputMl[2]); entryDplusCandGenInfo(isDplusPrompt); } else { registry.fill(HIST("hPtCandMcRecBkg"), candidate.pt()); @@ -487,7 +486,7 @@ struct HfCorrelatorDplusHadrons { candidate.pt(), track.pt(), poolBin); entryDplusHadronRecoInfo(hfHelper.invMassDplusToPiKPi(candidate), isDplusSignal); - entryDplusHadronMlInfo(outputMl[0], outputMl[1]); + entryDplusHadronMlInfo(outputMl[0], outputMl[1], outputMl[2]); if (track.has_mcParticle()) { auto mcParticle = track.template mcParticle_as(); isPhysicalPrimary = mcParticle.isPhysicalPrimary(); @@ -555,12 +554,12 @@ struct HfCorrelatorDplusHadrons { // prompt and non-prompt division std::vector listDaughters{}; - std::array arrDaughDplusPDG = {+kPiPlus, -kKPlus, kPiPlus}; - std::array prongsId; + std::array arrDaughDplusPDG = {+kPiPlus, -kKPlus, kPiPlus}; + std::array prongsId; listDaughters.clear(); RecoDecay::getDaughters(particle1, &listDaughters, arrDaughDplusPDG, 2); int counterDaughters = 0; - if (listDaughters.size() == 3) { + if (listDaughters.size() == NDaughters) { for (const auto& dauIdx : listDaughters) { auto daughI = mcParticles.rawIteratorAt(dauIdx - mcParticles.offset()); counterDaughters += 1; @@ -695,7 +694,7 @@ struct HfCorrelatorDplusHadrons { for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) { outputMl[iclass] = candidate.mlProbDplusToPiKPi()[classMl->at(iclass)]; } - entryDplusHadronMlInfo(outputMl[0], outputMl[1]); + entryDplusHadronMlInfo(outputMl[0], outputMl[1], outputMl[2]); entryTrackRecoInfo(pAssoc.dcaXY(), pAssoc.dcaZ(), pAssoc.tpcNClsCrossedRows()); } } diff --git a/PWGHF/HFC/TableProducer/femtoDreamProducer.cxx b/PWGHF/HFC/TableProducer/femtoDreamProducer.cxx index 026d7d80992..63b0a61b0b5 100644 --- a/PWGHF/HFC/TableProducer/femtoDreamProducer.cxx +++ b/PWGHF/HFC/TableProducer/femtoDreamProducer.cxx @@ -37,14 +37,17 @@ #include "PWGCF/FemtoDream/Core/femtoDreamUtils.h" #include "PWGHF/Core/HfHelper.h" +#include "PWGHF/Core/HfMlResponseLcToPKPi.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" #include "PWGHF/Utils/utilsBfieldCCDB.h" #include "PWGHF/Utils/utilsEvSelHf.h" #include "PWGHF/Core/CentralityEstimation.h" +#include "PWGHF/Core/SelectorCuts.h" using namespace o2; using namespace o2::framework; +using namespace o2::analysis; using namespace o2::framework::expressions; using namespace o2::analysis::femtoDream; using namespace o2::hf_evsel; @@ -60,6 +63,13 @@ enum Event : uint8_t { kPairSelected }; +// ml modes +enum MlMode : uint8_t { + kNoMl = 0, + kFillMlFromSelector, + kFillMlFromNewBDT +}; + struct HfFemtoDreamProducer { Produces outputCollision; @@ -82,6 +92,11 @@ struct HfFemtoDreamProducer { Configurable ccdbPathGrp{"ccdbPathGrp", "GLO/GRP/GRP", "Path of the grp file (Run 2)"}; Configurable ccdbPathGrpMag{"ccdbPathGrpMag", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object (Run 3)"}; + Configurable> modelPathsCCDB{"modelPathsCCDB", std::vector{"EventFiltering/PWGHF/BDTLc"}, "Paths of models on CCDB"}; + Configurable> onnxFileNames{"onnxFileNames", std::vector{"ModelHandler_onnx_LcToPKPi.onnx"}, "ONNX file names for each pT bin (if not from CCDB full path)"}; + Configurable timestampCCDB{"timestampCCDB", -1, "timestamp of the ONNX file for ML model used to query in CCDB"}; + Configurable loadModelsFromCCDB{"loadModelsFromCCDB", false, "Flag to enable or disable the loading of models from CCDB"}; + // Configurable isForceGRP{"isForceGRP", false, "Set true if the magnetic field configuration is not available in the usual CCDB directory (e.g. for Run 2 converted data or unanchorad Monte Carlo)"}; Configurable isDebug{"isDebug", true, "Enable Debug tables"}; @@ -108,47 +123,56 @@ struct HfFemtoDreamProducer { Configurable> trkTPCsCls{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kTPCsClsMax, "trk"), std::vector{0.1f, 160.f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kTPCsClsMax, "Track selection: ")}; Configurable> trkITSnclsIbMin{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kITSnClsIbMin, "trk"), std::vector{-1.f, 1.f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kITSnClsIbMin, "Track selection: ")}; Configurable> trkITSnclsMin{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kITSnClsMin, "trk"), std::vector{-1.f, 2.f, 4.f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kITSnClsMin, "Track selection: ")}; + // ML inference + Configurable applyMlMode{"applyMlMode", 1, "Occupancy estimation (None: 0, BDT model from Lc selector: 1, New BDT model on Top of Lc selector: 2)"}; + Configurable> binsPtMl{"binsPtMl", std::vector{hf_cuts_ml::vecBinsPt}, "pT bin limits for ML application"}; + Configurable> cutDirMl{"cutDirMl", std::vector{hf_cuts_ml::vecCutDir}, "Whether to reject score values greater or smaller than the threshold"}; + Configurable> cutsMl{"cutsMl", {hf_cuts_ml::Cuts[0], hf_cuts_ml::NBinsPt, hf_cuts_ml::NCutScores, hf_cuts_ml::labelsPt, hf_cuts_ml::labelsCutScore}, "ML selections per pT bin"}; + Configurable nClassesMl{"nClassesMl", static_cast(hf_cuts_ml::NCutScores), "Number of classes in ML model"}; + Configurable> namesInputFeatures{"namesInputFeatures", std::vector{"feature1", "feature2"}, "Names of ML model input features"}; + + FemtoDreamTrackSelection trackCuts; + + HfHelper hfHelper; + o2::analysis::HfMlResponseLcToPKPi hfMlResponse; + std::vector outputMlPKPi = {}; + std::vector outputMlPiKP = {}; + o2::ccdb::CcdbApi ccdbApi; + o2::hf_evsel::HfEventSelection hfEvSel; + Service ccdb; /// Accessing the CCDB + o2::base::MatLayerCylSet* lut; + // if (doPvRefit){ lut = o2::base::MatLayerCylSet::rectifyPtrFromFile(ccdb->get(ccdbPathLut));} //! may be it useful, will check later - using CandidateLc = soa::Join; - using CandidateLcMc = soa::Join; + float magField; + int runNumber; + using CandidateLc = soa::Join; + using CandidateLcMc = soa::Join; using FemtoFullCollision = soa::Join::iterator; using FemtoFullCollisionMc = soa::Join::iterator; using FemtoFullMcgenCollisions = soa::Join; using FemtoFullMcgenCollision = FemtoFullMcgenCollisions::iterator; - using FemtoHFTracks = soa::Join; + using FemtoHFTracks = soa::Join; using FemtoHFTrack = FemtoHFTracks::iterator; using FemtoHFMcTracks = soa::Join; using FemtoHFMcTrack = FemtoHFMcTracks::iterator; using GeneratedMc = soa::Filtered>; - FemtoDreamTrackSelection trackCuts; - Filter filterSelectCandidateLc = (aod::hf_sel_candidate_lc::isSelLcToPKPi >= selectionFlagLc || aod::hf_sel_candidate_lc::isSelLcToPiKP >= selectionFlagLc); HistogramRegistry qaRegistry{"QAHistos", {}, OutputObjHandlingPolicy::AnalysisObject}; - HistogramRegistry TrackRegistry{"Tracks", {}, OutputObjHandlingPolicy::AnalysisObject}; - - HfHelper hfHelper; - o2::hf_evsel::HfEventSelection hfEvSel; - - float magField; - int runNumber; - - Service ccdb; /// Accessing the CCDB - o2::base::MatLayerCylSet* lut; - // if (doPvRefit){ lut = o2::base::MatLayerCylSet::rectifyPtrFromFile(ccdb->get(ccdbPathLut));} //! may be it useful, will check later + HistogramRegistry trackRegistry{"Tracks", {}, OutputObjHandlingPolicy::AnalysisObject}; void init(InitContext&) { - std::array processes = {doprocessDataCharmHad, doprocessMcCharmHad, doprocessDataCharmHadWithML, doprocessMcCharmHadWithML, doprocessMcCharmHadGen}; + std::array processes = {doprocessDataCharmHad, doprocessMcCharmHad, doprocessMcCharmHadGen}; if (std::accumulate(processes.begin(), processes.end(), 0) != 1) { LOGP(fatal, "One and only one process function must be enabled at a time."); } - int CutBits = 8 * sizeof(o2::aod::femtodreamparticle::cutContainerType); - TrackRegistry.add("AnalysisQA/CutCounter", "; Bit; Counter", kTH1F, {{CutBits + 1, -0.5, CutBits + 0.5}}); + int cutBits = 8 * sizeof(o2::aod::femtodreamparticle::cutContainerType); + trackRegistry.add("AnalysisQA/CutCounter", "; Bit; Counter", kTH1F, {{cutBits + 1, -0.5, cutBits + 0.5}}); // event QA histograms constexpr int kEventTypes = kPairSelected + 1; @@ -181,7 +205,7 @@ struct HfFemtoDreamProducer { trackCuts.setSelection(trkPIDnSigmaMax, femtoDreamTrackSelection::kPIDnSigmaMax, femtoDreamSelection::kAbsUpperLimit); trackCuts.setPIDSpecies(trkPIDspecies); trackCuts.setnSigmaPIDOffset(trkPIDnSigmaOffsetTPC, trkPIDnSigmaOffsetTOF); - trackCuts.init(&qaRegistry, &TrackRegistry); + trackCuts.init(&qaRegistry, &trackRegistry); runNumber = 0; magField = 0.0; @@ -194,6 +218,18 @@ struct HfFemtoDreamProducer { int64_t now = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); ccdb->setCreatedNotAfter(now); + + if (applyMlMode) { + hfMlResponse.configure(binsPtMl, cutsMl, cutDirMl, nClassesMl); + if (loadModelsFromCCDB) { + ccdbApi.init(ccdbUrl); + hfMlResponse.setModelPathsCCDB(onnxFileNames, ccdbApi, modelPathsCCDB, timestampCCDB); + } else { + hfMlResponse.setModelPathsLocal(onnxFileNames); + } + hfMlResponse.cacheInputFeaturesIndices(namesInputFeatures); + hfMlResponse.init(); + } } /// Function to retrieve the nominal magnetic field in kG (0.1T) and convert it directly to T @@ -314,7 +350,7 @@ struct HfFemtoDreamProducer { // std::vector tmpIDtrack; // this vector keeps track of the matching of the primary track table row <-> aod::track table global index bool fIsTrackFilled = false; - for (auto& track : tracks) { + for (const auto& track : tracks) { /// if the most open selection criteria are not fulfilled there is no /// point looking further at the track if (!trackCuts.isSelectedMinimal(track)) { @@ -395,27 +431,45 @@ struct HfFemtoDreamProducer { // Filling candidate properties rowCandCharmHad.reserve(sizeCand); bool isTrackFilled = false; + bool isSelectedMlLcToPKPi = true; + bool isSelectedMlLcToPiKP = true; for (const auto& candidate : candidates) { - std::array outputMlPKPi{-1., -1., -1.}; - std::array outputMlPiKP{-1., -1., -1.}; + + auto trackPos1 = candidate.template prong0_as(); // positive daughter (negative for the antiparticles) + auto trackNeg = candidate.template prong1_as(); // negative daughter (positive for the antiparticles) + auto trackPos2 = candidate.template prong2_as(); // positive daughter (negative for the antiparticles) + if constexpr (useCharmMl) { /// fill with ML information /// BDT index 0: bkg score; BDT index 1: prompt score; BDT index 2: non-prompt score - if (candidate.mlProbLcToPKPi().size() > 0) { - outputMlPKPi.at(0) = candidate.mlProbLcToPKPi()[0]; /// bkg score - outputMlPKPi.at(1) = candidate.mlProbLcToPKPi()[1]; /// prompt score - outputMlPKPi.at(2) = candidate.mlProbLcToPKPi()[2]; /// non-prompt score - } - if (candidate.mlProbLcToPiKP().size() > 0) { - outputMlPiKP.at(0) = candidate.mlProbLcToPiKP()[0]; /// bkg score - outputMlPiKP.at(1) = candidate.mlProbLcToPiKP()[1]; /// prompt score - outputMlPiKP.at(2) = candidate.mlProbLcToPiKP()[2]; /// non-prompt score + if (applyMlMode == kFillMlFromSelector) { + if (candidate.mlProbLcToPKPi().size() > 0) { + outputMlPKPi.at(0) = candidate.mlProbLcToPKPi()[0]; /// bkg score + outputMlPKPi.at(1) = candidate.mlProbLcToPKPi()[1]; /// prompt score + outputMlPKPi.at(2) = candidate.mlProbLcToPKPi()[2]; /// non-prompt score + } + if (candidate.mlProbLcToPiKP().size() > 0) { + outputMlPiKP.at(0) = candidate.mlProbLcToPiKP()[0]; /// bkg score + outputMlPiKP.at(1) = candidate.mlProbLcToPiKP()[1]; /// prompt score + outputMlPiKP.at(2) = candidate.mlProbLcToPiKP()[2]; /// non-prompt score + } + } else if (applyMlMode == kFillMlFromNewBDT) { + isSelectedMlLcToPKPi = false; + isSelectedMlLcToPiKP = false; + if (candidate.mlProbLcToPKPi().size() > 0) { + std::vector inputFeaturesLcToPKPi = hfMlResponse.getInputFeatures(candidate, true); + isSelectedMlLcToPKPi = hfMlResponse.isSelectedMl(inputFeaturesLcToPKPi, candidate.pt(), outputMlPKPi); + } + if (candidate.mlProbLcToPiKP().size() > 0) { + std::vector inputFeaturesLcToPiKP = hfMlResponse.getInputFeatures(candidate, false); + isSelectedMlLcToPiKP = hfMlResponse.isSelectedMl(inputFeaturesLcToPiKP, candidate.pt(), outputMlPKPi); + } + if (!isSelectedMlLcToPKPi && !isSelectedMlLcToPiKP) + continue; + } else { + LOGF(fatal, "Please check your Ml configuration!!"); } } - auto trackPos1 = candidate.template prong0_as(); // positive daughter (negative for the antiparticles) - auto trackNeg = candidate.template prong1_as(); // negative daughter (positive for the antiparticles) - auto trackPos2 = candidate.template prong2_as(); // positive daughter (negative for the antiparticles) - auto fillTable = [&](int CandFlag, int FunctionSelection, float BDTScoreBkg, diff --git a/PWGHF/HFC/Tasks/taskCorrelationDplusHadrons.cxx b/PWGHF/HFC/Tasks/taskCorrelationDplusHadrons.cxx index 8ccda0a3b71..73d703ffde1 100644 --- a/PWGHF/HFC/Tasks/taskCorrelationDplusHadrons.cxx +++ b/PWGHF/HFC/Tasks/taskCorrelationDplusHadrons.cxx @@ -10,6 +10,7 @@ // or submit itself to any jurisdiction. /// \file taskCorrelationDplusHadrons.cxx +/// \brief D+-Hadrons azimuthal correlations analysis task - data-like, MC-reco and MC-Gen analyses /// \author Shyam Kumar #include // std::shared_ptr #include @@ -48,24 +49,25 @@ const TString stringMCGenDFd = "MC gen, non-prompt D+;"; const int npTBinsCorrelations = 8; const double pTBinsCorrelations[npTBinsCorrelations + 1] = {0., 2., 4., 6., 8., 12., 16., 24., 99.}; -auto pTBinsCorrelations_v = std::vector{pTBinsCorrelations, pTBinsCorrelations + npTBinsCorrelations + 1}; +auto ptBinsCorrelationsVec = std::vector{pTBinsCorrelations, pTBinsCorrelations + npTBinsCorrelations + 1}; const double signalRegionInnerDefault[npTBinsCorrelations] = {1.8490, 1.8490, 1.8490, 1.8490, 1.8490, 1.8490, 1.8490, 1.8490}; const double signalRegionOuterDefault[npTBinsCorrelations] = {1.8890, 1.8890, 1.8890, 1.8890, 1.8890, 1.8890, 1.8890, 1.8890}; const double sidebandLeftOuterDefault[npTBinsCorrelations] = {1.7690, 1.7690, 1.7690, 1.7690, 1.7690, 1.7690, 1.7690, 1.7690}; const double sidebandLeftInnerDefault[npTBinsCorrelations] = {1.8250, 1.8250, 1.8250, 1.8250, 1.8250, 1.8250, 1.8250, 1.8250}; const double sidebandRightInnerDefault[npTBinsCorrelations] = {1.9130, 1.9130, 1.9130, 1.9130, 1.9130, 1.9130, 1.9130, 1.9130}; const double sidebandRightOuterDefault[npTBinsCorrelations] = {1.9690, 1.9690, 1.9690, 1.9690, 1.9690, 1.9690, 1.9690, 1.9690}; -auto signalRegionInner_v = std::vector{signalRegionInnerDefault, signalRegionInnerDefault + npTBinsCorrelations}; -auto signalRegionOuter_v = std::vector{signalRegionOuterDefault, signalRegionOuterDefault + npTBinsCorrelations}; -auto sidebandLeftInner_v = std::vector{sidebandLeftInnerDefault, sidebandLeftInnerDefault + npTBinsCorrelations}; -auto sidebandLeftOuter_v = std::vector{sidebandLeftOuterDefault, sidebandLeftOuterDefault + npTBinsCorrelations}; -auto sidebandRightInner_v = std::vector{sidebandRightInnerDefault, sidebandRightInnerDefault + npTBinsCorrelations}; -auto sidebandRightOuter_v = std::vector{sidebandRightOuterDefault, sidebandRightOuterDefault + npTBinsCorrelations}; +auto signalRegionInnerVec = std::vector{signalRegionInnerDefault, signalRegionInnerDefault + npTBinsCorrelations}; +auto signalRegionOuterVec = std::vector{signalRegionOuterDefault, signalRegionOuterDefault + npTBinsCorrelations}; +auto sidebandLeftInnerVec = std::vector{sidebandLeftInnerDefault, sidebandLeftInnerDefault + npTBinsCorrelations}; +auto sidebandLeftOuterVec = std::vector{sidebandLeftOuterDefault, sidebandLeftOuterDefault + npTBinsCorrelations}; +auto sidebandRightInnerVec = std::vector{sidebandRightInnerDefault, sidebandRightInnerDefault + npTBinsCorrelations}; +auto sidebandRightOuterVec = std::vector{sidebandRightOuterDefault, sidebandRightOuterDefault + npTBinsCorrelations}; const int npTBinsEfficiency = o2::analysis::hf_cuts_dplus_to_pi_k_pi::NBinsPt; std::vector efficiencyDmeson(npTBinsEfficiency + 1); /// Dplus-Hadron correlation pair filling task, from pair tables - for real data and data-like analysis (i.e. reco-level w/o matching request via MC truth) struct HfTaskCorrelationDplusHadrons { + Configurable isPromptAnalysis{"isPromptAnalysis", true, "Flag for prompt D+-hadron correlations"}; Configurable fillHistoData{"fillHistoData", true, "Flag for filling histograms in data processes"}; Configurable fillHistoMcRec{"fillHistoMcRec", true, "Flag for filling histograms in MC Rec processes"}; Configurable fillHistoMcGen{"fillHistoMcGen", true, "Flag for filling histograms in MC Gen processes"}; @@ -75,10 +77,10 @@ struct HfTaskCorrelationDplusHadrons { Configurable selectionFlagDplus{"selectionFlagDplus", 7, "Selection Flag for D+"}; // 7 corresponds to topo+PID cuts Configurable selNoSameBunchPileUpColl{"selNoSameBunchPileUpColl", true, "Flag for rejecting the collisions associated with the same bunch crossing"}; Configurable> classMl{"classMl", {0, 1, 2}, "Indexes of ML scores to be stored. Three indexes max."}; - Configurable> mlOutputPrompt{"mlScorePrompt", {0.5, 0.5, 0.5, 0.5}, "Machine learning scores for prompt"}; - Configurable> mlOutputBkg{"mlScoreBkg", {0.5, 0.5, 0.5, 0.5}, "Machine learning scores for bkg"}; + Configurable> mlScorePromptOrNonPrompt{"mlScorePromptOrNonPrompt", {0.5, 0.5, 0.5, 0.5}, "Machine learning scores for prompt or Feed-down"}; + Configurable> mlScoreBkg{"mlScoreBkg", {0.5, 0.5, 0.5, 0.5}, "Machine learning scores for bkg"}; // pT ranges for correlation plots: the default values are those embedded in hf_cuts_dplus_to_pi_k_pi (i.e. the mass pT bins), but can be redefined via json files - Configurable> binsPtCorrelations{"binsPtCorrelations", std::vector{pTBinsCorrelations_v}, "pT bin limits for correlation plots"}; + Configurable> binsPtCorrelations{"binsPtCorrelations", std::vector{ptBinsCorrelationsVec}, "pT bin limits for correlation plots"}; Configurable> binsPtHadron{"binsPtHadron", std::vector{0.3, 2., 4., 8., 12., 50.}, "pT bin limits for assoc particle efficiency"}; Configurable> binsPtEfficiencyD{"binsPtEfficiencyD", std::vector{o2::analysis::hf_cuts_dplus_to_pi_k_pi::vecBinsPt}, "pT bin limits for efficiency"}; Configurable> binsPtEfficiencyHad{"binsPtEfficiencyHad", std::vector{0.3, 2., 4., 8., 12., 50.}, "pT bin limits for associated particle efficiency"}; @@ -86,12 +88,12 @@ struct HfTaskCorrelationDplusHadrons { Configurable> efficiencyFdD{"efficiencyFdD", {1., 1., 1., 1., 1., 1.}, "efficiency values for beauty feed-down D+ meson"}; Configurable> efficiencyHad{"efficiencyHad", {1., 1., 1., 1., 1., 1.}, "efficiency values for associated particles"}; // signal and sideband region edges, to be defined via json file (initialised to empty) - Configurable> signalRegionInner{"signalRegionInner", std::vector{signalRegionInner_v}, "Inner values of signal region vs pT"}; - Configurable> signalRegionOuter{"signalRegionOuter", std::vector{signalRegionOuter_v}, "Outer values of signal region vs pT"}; - Configurable> sidebandLeftInner{"sidebandLeftInner", std::vector{sidebandLeftInner_v}, "Inner values of left sideband vs pT"}; - Configurable> sidebandLeftOuter{"sidebandLeftOuter", std::vector{sidebandLeftOuter_v}, "Outer values of left sideband vs pT"}; - Configurable> sidebandRightInner{"sidebandRightInner", std::vector{sidebandRightInner_v}, "Inner values of right sideband vs pT"}; - Configurable> sidebandRightOuter{"sidebandRightOuter", std::vector{sidebandRightOuter_v}, "Outer values of right sideband vs pT"}; + Configurable> signalRegionInner{"signalRegionInner", std::vector{signalRegionInnerVec}, "Inner values of signal region vs pT"}; + Configurable> signalRegionOuter{"signalRegionOuter", std::vector{signalRegionOuterVec}, "Outer values of signal region vs pT"}; + Configurable> sidebandLeftInner{"sidebandLeftInner", std::vector{sidebandLeftInnerVec}, "Inner values of left sideband vs pT"}; + Configurable> sidebandLeftOuter{"sidebandLeftOuter", std::vector{sidebandLeftOuterVec}, "Outer values of left sideband vs pT"}; + Configurable> sidebandRightInner{"sidebandRightInner", std::vector{sidebandRightInnerVec}, "Inner values of right sideband vs pT"}; + Configurable> sidebandRightOuter{"sidebandRightOuter", std::vector{sidebandRightOuterVec}, "Outer values of right sideband vs pT"}; Configurable dcaXYTrackMax{"dcaXYTrackMax", 1., "max. DCA_xy of tracks"}; Configurable dcaZTrackMax{"dcaZTrackMax", 1., "max. DCA_z of tracks"}; Configurable etaTrackMax{"etaTrackMax", 0.8, "max. eta of tracks"}; @@ -112,20 +114,14 @@ struct HfTaskCorrelationDplusHadrons { Configurable fdEffCcdbPath{"fdEffCcdbPath", "", "CCDB path for trigger efficiency"}; Configurable timestampCcdb{"timestampCcdb", -1, "timestamp of the efficiency files used to query in CCDB"}; Configurable ccdbNoLaterThan{"ccdbNoLaterThan", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable timestamp of creation for the object"}; - // configurable axis definition - ConfigurableAxis binsMassD{"binsMassD", {200, 1.7, 2.10}, "inv. mass (#pi^{+}K^{-}#pi^{+}) (GeV/#it{c}^{2})"}; - ConfigurableAxis binsBdtScore{"binsBdtScore", {100, 0., 1.}, "Bdt output scores"}; - ConfigurableAxis binsEta{"binsEta", {100, -2., 2.}, "#it{#eta}"}; - ConfigurableAxis binsPhi{"binsPhi", {64, -PIHalf, 3. * PIHalf}, "#it{#varphi}"}; - ConfigurableAxis binsMultFT0M{"binsMultFT0M", {600, 0., 8000.}, "Multiplicity as FT0M signal amplitude"}; - ConfigurableAxis binsPoolBin{"binsPoolBin", {9, 0., 9.}, "PoolBin"}; + HfHelper hfHelper; Service ccdb; std::shared_ptr mEfficiencyPrompt = nullptr; std::shared_ptr mEfficiencyFD = nullptr; std::shared_ptr mEfficiencyAssociated = nullptr; - - HfHelper hfHelper; + std::shared_ptr effD = nullptr; + int idxBdtScore = 1; // Index BDTScore 1 for Prompt and 2 for FD Analysis enum CandidateStep { kCandidateStepMcGenAll = 0, kCandidateStepMcGenDplusToPiKPi, @@ -143,6 +139,13 @@ struct HfTaskCorrelationDplusHadrons { Filter dplusFilter = ((o2::aod::hf_track_index::hfflag & static_cast(1 << aod::hf_cand_3prong::DecayType::DplusToPiKPi)) != static_cast(0)) && aod::hf_sel_candidate_dplus::isSelDplusToPiKPi >= selectionFlagDplus; Filter trackFilter = (nabs(aod::track::eta) < etaTrackMax) && (aod::track::pt > ptTrackMin) && (aod::track::pt < ptTrackMax) && (nabs(aod::track::dcaXY) < dcaXYTrackMax) && (nabs(aod::track::dcaZ) < dcaZTrackMax); + // configurable axis definition + ConfigurableAxis binsMassD{"binsMassD", {200, 1.7, 2.10}, "inv. mass (#pi^{+}K^{-}#pi^{+}) (GeV/#it{c}^{2})"}; + ConfigurableAxis binsBdtScore{"binsBdtScore", {100, 0., 1.}, "Bdt output scores"}; + ConfigurableAxis binsEta{"binsEta", {100, -2., 2.}, "#it{#eta}"}; + ConfigurableAxis binsPhi{"binsPhi", {64, -PIHalf, 3. * PIHalf}, "#it{#varphi}"}; + ConfigurableAxis binsMultFT0M{"binsMultFT0M", {600, 0., 8000.}, "Multiplicity as FT0M signal amplitude"}; + ConfigurableAxis binsPoolBin{"binsPoolBin", {9, 0., 9.}, "PoolBin"}; HistogramRegistry registry{"registry", {}, OutputObjHandlingPolicy::AnalysisObject}; @@ -271,6 +274,8 @@ struct HfTaskCorrelationDplusHadrons { } LOGF(info, "Loaded associated efficiency histogram from %s", associatedEffCcdbPath.value.c_str()); } + auto effD = isPromptAnalysis ? mEfficiencyPrompt : mEfficiencyFD; + idxBdtScore = isPromptAnalysis ? 1 : 2; if (activateQA) { const int regionLimits = 6; @@ -297,22 +302,24 @@ struct HfTaskCorrelationDplusHadrons { float massD = candidate.mD(); float ptD = candidate.ptD(); float bdtScorePrompt = candidate.mlScorePrompt(); + float bdtScoreNonPrompt = candidate.mlScoreNonPrompt(); float bdtScoreBkg = candidate.mlScoreBkg(); int effBinD = o2::analysis::findBin(binsPtEfficiencyD, ptD); + float bdtScorePromptOrNonPrompt = isPromptAnalysis ? bdtScorePrompt : bdtScoreNonPrompt; // reject entries outside pT ranges of interest if (ptD < binsPtEfficiencyD->front() || ptD > binsPtEfficiencyD->back()) { continue; } - if (bdtScorePrompt < mlOutputPrompt->at(effBinD) || bdtScoreBkg > mlOutputBkg->at(effBinD)) { + if (bdtScorePromptOrNonPrompt < mlScorePromptOrNonPrompt->at(effBinD) || bdtScoreBkg > mlScoreBkg->at(effBinD)) { continue; } double efficiencyWeightD = 1.; if (applyEfficiency) { efficiencyWeightD = 1. / efficiencyD->at(o2::analysis::findBin(binsPtEfficiencyD, ptD)); if (loadAccXEffFromCCDB) { - efficiencyWeightD = 1. / mEfficiencyPrompt->GetBinContent(mEfficiencyPrompt->FindBin(ptD)); + efficiencyWeightD = 1. / effD->GetBinContent(effD->FindBin(ptD)); } } registry.fill(HIST("hMassDplusVsPt"), massD, ptD, efficiencyWeightD); @@ -328,6 +335,7 @@ struct HfTaskCorrelationDplusHadrons { float ptD = pairEntry.ptD(); float ptHadron = pairEntry.ptHadron(); float bdtScorePrompt = pairEntry.mlScorePrompt(); + float bdtScoreNonPrompt = pairEntry.mlScoreNonPrompt(); float bdtScoreBkg = pairEntry.mlScoreBkg(); float trackDcaXY = pairEntry.trackDcaXY(); float trackDcaZ = pairEntry.trackDcaZ(); @@ -336,13 +344,14 @@ struct HfTaskCorrelationDplusHadrons { double massD = pairEntry.mD(); int effBinD = o2::analysis::findBin(binsPtEfficiencyD, ptD); int pTBinD = o2::analysis::findBin(binsPtCorrelations, ptD); + float bdtScorePromptOrNonPrompt = isPromptAnalysis ? bdtScorePrompt : bdtScoreNonPrompt; // reject entries outside pT ranges of interest if (ptD < binsPtEfficiencyD->front() || ptD > binsPtEfficiencyD->back()) { continue; } - if (bdtScorePrompt < mlOutputPrompt->at(effBinD) || bdtScoreBkg > mlOutputBkg->at(effBinD)) { + if (bdtScorePromptOrNonPrompt < mlScorePromptOrNonPrompt->at(effBinD) || bdtScoreBkg > mlScoreBkg->at(effBinD)) { continue; } if (trackDcaXY > dcaXYTrackMax || trackDcaZ > dcaZTrackMax || trackTpcCrossedRows < nTpcCrossedRaws) { @@ -352,7 +361,7 @@ struct HfTaskCorrelationDplusHadrons { if (applyEfficiency) { efficiencyWeight = 1. / (efficiencyD->at(effBinD) * efficiencyHad->at(o2::analysis::findBin(binsPtEfficiencyHad, ptHadron))); if (loadAccXEffFromCCDB) { - efficiencyWeight = 1. / (mEfficiencyPrompt->GetBinContent(mEfficiencyPrompt->FindBin(ptD)) * mEfficiencyAssociated->GetBinContent(mEfficiencyAssociated->FindBin(ptHadron))); + efficiencyWeight = 1. / (effD->GetBinContent(effD->FindBin(ptD)) * mEfficiencyAssociated->GetBinContent(mEfficiencyAssociated->FindBin(ptHadron))); } } // check if correlation entry belongs to signal region, sidebands or is outside both, and fill correlation plots @@ -395,15 +404,17 @@ struct HfTaskCorrelationDplusHadrons { float massD = candidate.mD(); float ptD = candidate.ptD(); float bdtScorePrompt = candidate.mlScorePrompt(); + float bdtScoreNonPrompt = candidate.mlScoreNonPrompt(); float bdtScoreBkg = candidate.mlScoreBkg(); int effBinD = o2::analysis::findBin(binsPtEfficiencyD, ptD); bool isDplusPrompt = candidate.isPrompt(); + float bdtScorePromptOrNonPrompt = isPromptAnalysis ? bdtScorePrompt : bdtScoreNonPrompt; // reject entries outside pT ranges of interest if (ptD < binsPtEfficiencyD->front() || ptD > binsPtEfficiencyD->back()) continue; - if (bdtScorePrompt < mlOutputPrompt->at(effBinD) || bdtScoreBkg > mlOutputBkg->at(effBinD)) { + if (bdtScorePromptOrNonPrompt < mlScorePromptOrNonPrompt->at(effBinD) || bdtScoreBkg > mlScoreBkg->at(effBinD)) { continue; } double efficiencyWeightD = 1.; @@ -440,22 +451,24 @@ struct HfTaskCorrelationDplusHadrons { float ptHadron = pairEntry.ptHadron(); float massD = pairEntry.mD(); float bdtScorePrompt = pairEntry.mlScorePrompt(); + float bdtScoreNonPrompt = pairEntry.mlScoreNonPrompt(); float bdtScoreBkg = pairEntry.mlScoreBkg(); bool isPhysicalPrimary = pairEntry.isPhysicalPrimary(); float trackDcaXY = pairEntry.trackDcaXY(); float trackDcaZ = pairEntry.trackDcaZ(); int trackTpcCrossedRows = pairEntry.trackTPCNClsCrossedRows(); - int statusDplusPrompt = static_cast(pairEntry.isPrompt()); - int statusPromptHadron = pairEntry.trackOrigin(); + bool isDplusPrompt = pairEntry.isPrompt(); + int originHadron = pairEntry.trackOrigin(); int poolBin = pairEntry.poolBin(); int effBinD = o2::analysis::findBin(binsPtEfficiencyD, ptD); int pTBinD = o2::analysis::findBin(binsPtCorrelations, ptD); + float bdtScorePromptOrNonPrompt = isPromptAnalysis ? bdtScorePrompt : bdtScoreNonPrompt; // reject entries outside pT ranges of interest if (ptD < binsPtEfficiencyD->front() || ptD > binsPtEfficiencyD->back()) continue; - if (bdtScorePrompt < mlOutputPrompt->at(effBinD) || bdtScoreBkg > mlOutputBkg->at(effBinD)) { + if (bdtScorePromptOrNonPrompt < mlScorePromptOrNonPrompt->at(effBinD) || bdtScoreBkg > mlScoreBkg->at(effBinD)) { continue; } if (trackDcaXY > dcaXYTrackMax || trackDcaZ > dcaZTrackMax || trackTpcCrossedRows < nTpcCrossedRaws) { @@ -464,7 +477,7 @@ struct HfTaskCorrelationDplusHadrons { double efficiencyWeight = 1.; if (applyEfficiency) { - if (statusDplusPrompt) { + if (isDplusPrompt) { efficiencyWeight = 1. / (efficiencyD->at(effBinD) * efficiencyHad->at(o2::analysis::findBin(binsPtEfficiencyHad, ptHadron))); if (loadAccXEffFromCCDB) { efficiencyWeight = 1. / (mEfficiencyPrompt->GetBinContent(mEfficiencyPrompt->FindBin(ptD)) * mEfficiencyAssociated->GetBinContent(mEfficiencyAssociated->FindBin(ptHadron))); @@ -488,15 +501,15 @@ struct HfTaskCorrelationDplusHadrons { // check if correlation entry belongs to signal region, sidebands or is outside both, and fill correlation plots if (massD > signalRegionInner->at(pTBinD) && massD < signalRegionOuter->at(pTBinD)) { // in signal region - registry.fill(HIST("hCorrel2DVsPtSignalRegionMcRec"), deltaPhi, deltaEta, ptD, ptHadron, statusDplusPrompt, poolBin, efficiencyWeight); + registry.fill(HIST("hCorrel2DVsPtSignalRegionMcRec"), deltaPhi, deltaEta, ptD, ptHadron, static_cast(isDplusPrompt), poolBin, efficiencyWeight); registry.fill(HIST("hCorrel2DPtIntSignalRegionMcRec"), deltaPhi, deltaEta, efficiencyWeight); registry.fill(HIST("hDeltaEtaPtIntSignalRegionMcRec"), deltaEta, efficiencyWeight); registry.fill(HIST("hDeltaPhiPtIntSignalRegionMcRec"), deltaPhi, efficiencyWeight); if (isPhysicalPrimary) { - registry.fill(HIST("hCorrel2DVsPtPhysicalPrimaryMcRec"), deltaPhi, deltaEta, ptD, ptHadron, statusDplusPrompt, poolBin, efficiencyWeight); - if (statusDplusPrompt == 1 && statusPromptHadron == 1) { + registry.fill(HIST("hCorrel2DVsPtPhysicalPrimaryMcRec"), deltaPhi, deltaEta, ptD, ptHadron, static_cast(isDplusPrompt), poolBin, efficiencyWeight); + if (isDplusPrompt && originHadron == RecoDecay::OriginType::Prompt) { registry.fill(HIST("hCorrel2DVsPtSignalRegionPromptDplusPromptHadronMcRec"), deltaPhi, deltaEta, ptD, ptHadron, poolBin, efficiencyWeight); - } else if (statusDplusPrompt == 0 && statusPromptHadron == 2) { + } else if (!isDplusPrompt && originHadron == RecoDecay::OriginType::NonPrompt) { registry.fill(HIST("hCorrel2DVsPtSignalRegionNonPromptDplusNonPromptHadronMcRec"), deltaPhi, deltaEta, ptD, ptHadron, poolBin, efficiencyWeight); } } @@ -535,7 +548,7 @@ struct HfTaskCorrelationDplusHadrons { float ptD = pairEntry.ptD(); float ptHadron = pairEntry.ptHadron(); int poolBin = pairEntry.poolBin(); - int statusPromptHadron = pairEntry.trackOrigin(); + int originHadron = pairEntry.trackOrigin(); bool isDplusPrompt = pairEntry.isPrompt(); registry.fill(HIST("hCorrel2DVsPtMcGen"), deltaPhi, deltaEta, ptD, ptHadron, poolBin); @@ -543,12 +556,12 @@ struct HfTaskCorrelationDplusHadrons { registry.fill(HIST("hDeltaPhiPtIntMcGen"), deltaPhi); if (isDplusPrompt) { registry.fill(HIST("hCorrel2DVsPtMcGenPrompt"), deltaPhi, deltaEta, ptD, ptHadron, poolBin); - if (statusPromptHadron == 1) { + if (originHadron == RecoDecay::OriginType::Prompt) { registry.fill(HIST("hCorrel2DVsPtMcGenPromptDPromptHadron"), deltaPhi, deltaEta, ptD, ptHadron, poolBin); } } else { registry.fill(HIST("hCorrel2DVsPtMcGenNonPrompt"), deltaPhi, deltaEta, ptD, ptHadron, poolBin); - if (statusPromptHadron == 2) { + if (originHadron == RecoDecay::OriginType::NonPrompt) { registry.fill(HIST("hCorrel2DVsPtMcGenNonPromptDNonPromptHadron"), deltaPhi, deltaEta, ptD, ptHadron, poolBin); } } @@ -612,7 +625,7 @@ struct HfTaskCorrelationDplusHadrons { for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) { outputMl[iclass] = candidate.mlProbDplusToPiKPi()[classMl->at(iclass)]; } - if (outputMl[0] > mlOutputBkg->at(o2::analysis::findBin(binsPtEfficiencyD, candidate.pt())) || outputMl[1] < mlOutputPrompt->at(o2::analysis::findBin(binsPtEfficiencyD, candidate.pt()))) { + if (outputMl[0] > mlScoreBkg->at(o2::analysis::findBin(binsPtEfficiencyD, candidate.pt())) || outputMl[idxBdtScore] < mlScorePromptOrNonPrompt->at(o2::analysis::findBin(binsPtEfficiencyD, candidate.pt()))) { continue; } auto collision = candidate.template collision_as>(); diff --git a/PWGHF/HFC/Tasks/taskCorrelationDsHadrons.cxx b/PWGHF/HFC/Tasks/taskCorrelationDsHadrons.cxx index 76c4f88c04c..fc4c059c61b 100644 --- a/PWGHF/HFC/Tasks/taskCorrelationDsHadrons.cxx +++ b/PWGHF/HFC/Tasks/taskCorrelationDsHadrons.cxx @@ -66,7 +66,8 @@ struct HfTaskCorrelationDsHadrons { Configurable> classMl{"classMl", {0, 1, 2}, "Indexes of ML scores to be stored. Three indexes max."}; Configurable> binsPtD{"binsPtD", std::vector{o2::analysis::hf_cuts_ds_to_k_k_pi::vecBinsPt}, "pT bin limits for candidate mass plots and efficiency"}; Configurable> binsPtHadron{"binsPtHadron", std::vector{0.3, 2., 4., 8., 12., 50.}, "pT bin limits for assoc particle efficiency"}; - Configurable> mlOutputPrompt{"mlOutputPrompt", {0.5, 0.5, 0.5, 0.5}, "Machine learning scores for prompt"}; + Configurable> mlOutputPromptMin{"mlOutputPromptMin", {0.5, 0.5, 0.5, 0.5}, "Machine learning scores for prompt"}; + Configurable> mlOutputPromptMax{"mlOutputPromptMax", {1.0, 1.0, 1.0, 1.0}, "Machine learning scores for prompt"}; Configurable> mlOutputBkg{"mlOutputBkg", {0.5, 0.5, 0.5, 0.5}, "Machine learning scores for bkg"}; Configurable> binsPtEfficiencyD{"binsPtEfficiencyD", std::vector{o2::analysis::hf_cuts_ds_to_k_k_pi::vecBinsPt}, "pT bin limits for D-meson efficiency"}; Configurable> binsPtEfficiencyHad{"binsPtEfficiencyHad", std::vector{0.3, 2., 4., 8., 12., 50.}, "pT bin limits for associated particle efficiency"}; @@ -266,6 +267,12 @@ struct HfTaskCorrelationDsHadrons { } } + bool isSelectedCandidate(const int ptBinD, const float bdtScorePrompt, const float bdtScoreBkg) + { + + return (ptBinD != -1 && bdtScorePrompt >= mlOutputPromptMin->at(ptBinD) && bdtScorePrompt <= mlOutputPromptMax->at(ptBinD) && bdtScoreBkg <= mlOutputBkg->at(ptBinD)); + } + void processData(DsHadronPairWithMl const& pairEntries, aod::DsCandRecoInfo const& candidates) { @@ -276,9 +283,10 @@ struct HfTaskCorrelationDsHadrons { float bdtScoreBkg = candidate.mlScoreBkg(); int ptBinD = o2::analysis::findBin(binsPtD, ptD); - if (bdtScorePrompt < mlOutputPrompt->at(ptBinD) || bdtScoreBkg > mlOutputBkg->at(ptBinD)) { + if (!isSelectedCandidate(ptBinD, bdtScorePrompt, bdtScoreBkg)) { continue; } + double efficiencyWeightD = 1.; if (applyEfficiency) { efficiencyWeightD = 1. / efficiencyD->at(o2::analysis::findBin(binsPtEfficiencyD, ptD)); @@ -306,9 +314,10 @@ struct HfTaskCorrelationDsHadrons { int poolBin = pairEntry.poolBin(); int ptBinD = o2::analysis::findBin(binsPtD, ptD); - if (bdtScorePrompt < mlOutputPrompt->at(ptBinD) || bdtScoreBkg > mlOutputBkg->at(ptBinD)) { + if (!isSelectedCandidate(ptBinD, bdtScorePrompt, bdtScoreBkg)) { continue; } + if (trackDcaXY > dcaXYTrackMax || trackDcaZ > dcaZTrackMax || trackTpcCrossedRows < nTpcCrossedRaws) { continue; } @@ -354,9 +363,10 @@ struct HfTaskCorrelationDsHadrons { int ptBinD = o2::analysis::findBin(binsPtD, ptD); bool isDsPrompt = candidate.isPrompt(); - if (bdtScorePrompt < mlOutputPrompt->at(ptBinD) || bdtScoreBkg > mlOutputBkg->at(ptBinD)) { + if (!isSelectedCandidate(ptBinD, bdtScorePrompt, bdtScoreBkg)) { continue; } + double efficiencyWeightD = 1.; if (applyEfficiency) { efficiencyWeightD = 1. / efficiencyD->at(o2::analysis::findBin(binsPtEfficiencyD, ptD)); @@ -393,9 +403,10 @@ struct HfTaskCorrelationDsHadrons { int ptBinD = o2::analysis::findBin(binsPtD, ptD); bool isPhysicalPrimary = pairEntry.isPhysicalPrimary(); - if (bdtScorePrompt < mlOutputPrompt->at(ptBinD) || bdtScoreBkg > mlOutputBkg->at(ptBinD)) { + if (!isSelectedCandidate(ptBinD, bdtScorePrompt, bdtScoreBkg)) { continue; } + if (trackDcaXY > dcaXYTrackMax || trackDcaZ > dcaZTrackMax || trackTpcCrossedRows < nTpcCrossedRaws) { continue; } @@ -415,9 +426,9 @@ struct HfTaskCorrelationDsHadrons { registry.fill(HIST("hCorrel2DVsPtSignalRegionMcRec"), deltaPhi, deltaEta, ptD, ptHadron, statusDsPrompt, poolBin, efficiencyWeight); if (isPhysicalPrimary) { registry.fill(HIST("hCorrel2DVsPtPhysicalPrimaryMcRec"), deltaPhi, deltaEta, ptD, ptHadron, statusDsPrompt, poolBin, efficiencyWeight); - if (statusDsPrompt == 1 && statusPromptHadron == 1) { + if (statusDsPrompt == 1 && statusPromptHadron == RecoDecay::OriginType::Prompt) { registry.fill(HIST("hCorrel2DVsPtSignalRegionPromptDsPromptHadronMcRec"), deltaPhi, deltaEta, ptD, ptHadron, poolBin, efficiencyWeight); - } else if (statusDsPrompt == 0 && statusPromptHadron == 2) { + } else if (statusDsPrompt == 0 && statusPromptHadron == RecoDecay::OriginType::NonPrompt) { registry.fill(HIST("hCorrel2DVsPtSignalRegionNonPromptDsNonPromptHadronMcRec"), deltaPhi, deltaEta, ptD, ptHadron, poolBin, efficiencyWeight); } } @@ -457,12 +468,12 @@ struct HfTaskCorrelationDsHadrons { registry.fill(HIST("hDeltaPhiPtIntMcGen"), deltaPhi); if (isDsPrompt) { registry.fill(HIST("hCorrel2DVsPtMcGenPrompt"), deltaPhi, deltaEta, ptD, ptHadron, poolBin); - if (statusPromptHadron == 1) { + if (statusPromptHadron == RecoDecay::OriginType::Prompt) { registry.fill(HIST("hCorrel2DVsPtMcGenPromptDsPromptHadron"), deltaPhi, deltaEta, ptD, ptHadron, poolBin); } } else { registry.fill(HIST("hCorrel2DVsPtMcGenNonPrompt"), deltaPhi, deltaEta, ptD, ptHadron, poolBin); - if (statusPromptHadron == 2) { + if (statusPromptHadron == RecoDecay::OriginType::NonPrompt) { registry.fill(HIST("hCorrel2DVsPtMcGenNonPromptDsNonPromptHadron"), deltaPhi, deltaEta, ptD, ptHadron, poolBin); } } @@ -487,9 +498,10 @@ struct HfTaskCorrelationDsHadrons { int poolBin = pairEntry.poolBin(); int ptBinD = o2::analysis::findBin(binsPtD, ptD); - if (bdtScorePrompt < mlOutputPrompt->at(ptBinD) || bdtScoreBkg > mlOutputBkg->at(ptBinD)) { + if (!isSelectedCandidate(ptBinD, bdtScorePrompt, bdtScoreBkg)) { continue; } + if (trackDcaXY > dcaXYTrackMax || trackDcaZ > dcaZTrackMax || trackTpcCrossedRows < nTpcCrossedRaws) { continue; } @@ -586,9 +598,10 @@ struct HfTaskCorrelationDsHadrons { int ptBinD = o2::analysis::findBin(binsPtD, ptD); bool isPhysicalPrimary = pairEntry.isPhysicalPrimary(); - if (bdtScorePrompt < mlOutputPrompt->at(ptBinD) || bdtScoreBkg > mlOutputBkg->at(ptBinD)) { + if (!isSelectedCandidate(ptBinD, bdtScorePrompt, bdtScoreBkg)) { continue; } + if (trackDcaXY > dcaXYTrackMax || trackDcaZ > dcaZTrackMax || trackTpcCrossedRows < nTpcCrossedRaws) { continue; } @@ -608,9 +621,9 @@ struct HfTaskCorrelationDsHadrons { registry.fill(HIST("hCorrel2DVsPtSignalRegionMcRec"), deltaPhi, deltaEta, ptD, ptHadron, statusDsPrompt, poolBin, efficiencyWeight); if (isPhysicalPrimary) { registry.fill(HIST("hCorrel2DVsPtPhysicalPrimaryMcRec"), deltaPhi, deltaEta, ptD, ptHadron, statusDsPrompt, poolBin, efficiencyWeight); - if (statusDsPrompt == 1 && statusPromptHadron == 1) { + if (statusDsPrompt == 1 && statusPromptHadron == RecoDecay::OriginType::Prompt) { registry.fill(HIST("hCorrel2DVsPtSignalRegionPromptDsPromptHadronMcRec"), deltaPhi, deltaEta, ptD, ptHadron, poolBin, efficiencyWeight); - } else if (statusDsPrompt == 0 && statusPromptHadron == 2) { + } else if (statusDsPrompt == 0 && statusPromptHadron == RecoDecay::OriginType::NonPrompt) { registry.fill(HIST("hCorrel2DVsPtSignalRegionNonPromptDsNonPromptHadronMcRec"), deltaPhi, deltaEta, ptD, ptHadron, poolBin, efficiencyWeight); } } @@ -720,7 +733,7 @@ struct HfTaskCorrelationDsHadrons { outputMl[iclass] = candidate.mlProbDsToPiKK()[classMl->at(iclass)]; } } - if (outputMl[0] < mlOutputPrompt->at(o2::analysis::findBin(binsPtD, candidate.pt())) || outputMl[2] > mlOutputBkg->at(o2::analysis::findBin(binsPtD, candidate.pt()))) { + if (outputMl[0] < mlOutputPromptMin->at(o2::analysis::findBin(binsPtD, candidate.pt())) || outputMl[0] < mlOutputPromptMax->at(o2::analysis::findBin(binsPtD, candidate.pt())) || outputMl[2] > mlOutputBkg->at(o2::analysis::findBin(binsPtD, candidate.pt()))) { continue; } @@ -802,7 +815,7 @@ struct HfTaskCorrelationDsHadrons { outputMl[iclass] = candidate.mlProbDsToPiKK()[classMl->at(iclass)]; } } - if (outputMl[0] < mlOutputPrompt->at(o2::analysis::findBin(binsPtD, candidate.pt())) || outputMl[2] > mlOutputBkg->at(o2::analysis::findBin(binsPtD, candidate.pt()))) { + if (outputMl[0] < mlOutputPromptMin->at(o2::analysis::findBin(binsPtD, candidate.pt())) || outputMl[0] < mlOutputPromptMax->at(o2::analysis::findBin(binsPtD, candidate.pt())) || outputMl[2] > mlOutputBkg->at(o2::analysis::findBin(binsPtD, candidate.pt()))) { continue; } auto collision = candidate.template collision_as>(); @@ -897,9 +910,9 @@ struct HfTaskCorrelationDsHadrons { } if (separateTrackOrigins) { int trackOrigin = RecoDecay::getCharmHadronOrigin(mcParticles, mcParticle, true); - if (trackOrigin == 1) { // charm orgin + if (trackOrigin == RecoDecay::OriginType::Prompt) { // charm orgin registry.fill(HIST("hPtPrmPromptPartMcGen"), mcParticle.pt()); - } else if (trackOrigin == 2) { // beauty origin + } else if (trackOrigin == RecoDecay::OriginType::NonPrompt) { // beauty origin registry.fill(HIST("hPtPrmNonPromptPartMcGen"), mcParticle.pt()); } } @@ -938,9 +951,9 @@ struct HfTaskCorrelationDsHadrons { // check track origin if (separateTrackOrigins) { int trackOrigin = RecoDecay::getCharmHadronOrigin(mcParticles, mcParticle, true); - if (trackOrigin == 1) { // charm orgin + if (trackOrigin == RecoDecay::OriginType::Prompt) { // charm orgin registry.fill(HIST("hPtPrmPromptPartMcRec"), track.pt()); - } else if (trackOrigin == 2) { // beauty origin + } else if (trackOrigin == RecoDecay::OriginType::NonPrompt) { // beauty origin registry.fill(HIST("hPtPrmNonPromptPartMcRec"), track.pt()); } } diff --git a/PWGHF/TableProducer/CMakeLists.txt b/PWGHF/TableProducer/CMakeLists.txt index 22895a583ce..a2a0b107e74 100644 --- a/PWGHF/TableProducer/CMakeLists.txt +++ b/PWGHF/TableProducer/CMakeLists.txt @@ -92,7 +92,7 @@ o2physics_add_dpl_workflow(candidate-creator-xic0-omegac0 o2physics_add_dpl_workflow(candidate-creator-xic-to-xi-pi-pi SOURCES candidateCreatorXicToXiPiPi.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2::DCAFitter KFParticle::KFParticle + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2::DCAFitter KFParticle::KFParticle O2Physics::EventFilteringUtils COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(candidate-creator-xicc diff --git a/PWGHF/TableProducer/candidateCreator2Prong.cxx b/PWGHF/TableProducer/candidateCreator2Prong.cxx index 576e5413c11..66e11d2559d 100644 --- a/PWGHF/TableProducer/candidateCreator2Prong.cxx +++ b/PWGHF/TableProducer/candidateCreator2Prong.cxx @@ -147,7 +147,9 @@ struct HfCandidateCreator2Prong { registry.add("hDcaZProngs", "DCAz of 2-prong candidate daughters;#it{p}_{T} (GeV/#it{c};#it{d}_{z}) (#mum);entries", {HistType::kTH2F, {{100, 0., 20.}, {200, -500., 500.}}}); registry.add("hVertexerType", "Use KF or DCAFitterN;Vertexer type;entries", {HistType::kTH1D, {{2, -0.5, 1.5}}}); // See o2::aod::hf_cand::VertexerType hCandidates = registry.add("hCandidates", "candidates counter", {HistType::kTH1D, {axisCands}}); - hfEvSel.addHistograms(registry); // collision monitoring + + // init HF event selection helper + hfEvSel.init(registry); massPi = MassPiPlus; massK = MassKPlus; @@ -713,11 +715,11 @@ struct HfCandidateCreator2ProngExpressions { const auto& workflows = initContext.services().get(); for (const DeviceSpec& device : workflows.devices) { if (device.name.compare("hf-candidate-creator-2prong") == 0) { - hfEvSelMc.configureFromDevice(device); + // init HF event selection helper + hfEvSelMc.init(device, registry); break; } } - hfEvSelMc.addHistograms(registry); // particles monitoring } /// Performs MC matching. diff --git a/PWGHF/TableProducer/candidateCreator3Prong.cxx b/PWGHF/TableProducer/candidateCreator3Prong.cxx index 24d9496630c..b5d47d2cacc 100644 --- a/PWGHF/TableProducer/candidateCreator3Prong.cxx +++ b/PWGHF/TableProducer/candidateCreator3Prong.cxx @@ -47,8 +47,9 @@ #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/Utils/utilsBfieldCCDB.h" #include "PWGHF/Utils/utilsEvSelHf.h" -#include "PWGHF/Utils/utilsTrkCandHf.h" #include "PWGHF/Utils/utilsMcGen.h" +#include "PWGHF/Utils/utilsPid.h" +#include "PWGHF/Utils/utilsTrkCandHf.h" using namespace o2; using namespace o2::analysis; @@ -60,11 +61,21 @@ using namespace o2::hf_occupancy; using namespace o2::constants::physics; using namespace o2::framework; using namespace o2::framework::expressions; +using namespace o2::aod::pid_tpc_tof_utils; /// Reconstruction of heavy-flavour 3-prong decay candidates struct HfCandidateCreator3Prong { Produces rowCandidateBase; Produces rowCandidateKF; + Produces rowProng0PidPi; + Produces rowProng0PidKa; + Produces rowProng0PidPr; + Produces rowProng1PidPi; + Produces rowProng1PidKa; + Produces rowProng1PidPr; + Produces rowProng2PidPi; + Produces rowProng2PidKa; + Produces rowProng2PidPr; // vertexing Configurable propagateToPCA{"propagateToPCA", true, "create tracks version propagated to PCA"}; @@ -85,6 +96,9 @@ struct HfCandidateCreator3Prong { Configurable createDs{"createDs", false, "enable Ds+/- candidate creation"}; Configurable createLc{"createLc", false, "enable Lc+/- candidate creation"}; Configurable createXic{"createXic", false, "enable Xic+/- candidate creation"}; + // KF + Configurable applyTopoConstraint{"applyTopoConstraint", false, "apply origin from PV hypothesis for created candidate, works only in KF mode"}; + Configurable applyInvMassConstraint{"applyInvMassConstraint", false, "apply particle type hypothesis to recalculate created candidate's momentum, works only in KF mode"}; HfEventSelection hfEvSel; // event selection and monitoring o2::vertexing::DCAFitterN<3> df; // 3-prong vertex fitter @@ -108,6 +122,7 @@ struct HfCandidateCreator3Prong { using FilteredHf3Prongs = soa::Filtered; using FilteredPvRefitHf3Prongs = soa::Filtered>; + using TracksWCovExtraPidPiKaPr = soa::Join; // filter candidates Filter filterSelected3Prongs = (createDplus && (o2::aod::hf_track_index::hfflag & static_cast(BIT(aod::hf_cand_3prong::DecayType::DplusToPiKPi))) != static_cast(0)) || (createDs && (o2::aod::hf_track_index::hfflag & static_cast(BIT(aod::hf_cand_3prong::DecayType::DsToKKPi))) != static_cast(0)) || (createLc && (o2::aod::hf_track_index::hfflag & static_cast(BIT(aod::hf_cand_3prong::DecayType::LcToPKPi))) != static_cast(0)) || (createXic && (o2::aod::hf_track_index::hfflag & static_cast(BIT(aod::hf_cand_3prong::DecayType::XicToPKPi))) != static_cast(0)); @@ -149,6 +164,10 @@ struct HfCandidateCreator3Prong { LOGP(fatal, "At least one particle specie should be enabled for the creation."); } + if (createLc && createXic && applyInvMassConstraint) { + LOGP(fatal, "Unable to apply invariant mass constraint due to ambiguity of mass hypothesis: only one of Lc and Xic can be reconstructed."); + } + // histograms registry.add("hMass3PKPi", "3-prong candidates;inv. mass (pK#pi) (GeV/#it{c}^{2});entries", {HistType::kTH1D, {{1200, 1.8, 3.0}}}); registry.add("hMass3PiKP", "3-prong candidates;inv. mass (#pi Kp) (GeV/#it{c}^{2});entries", {HistType::kTH1D, {{1200, 1.8, 3.0}}}); @@ -168,7 +187,9 @@ struct HfCandidateCreator3Prong { registry.add("hDcaXYProngs", "DCAxy of 3-prong candidate daughters;#it{p}_{T} (GeV/#it{c};#it{d}_{xy}) (#mum);entries", {HistType::kTH2F, {{100, 0., 20.}, {200, -500., 500.}}}); registry.add("hDcaZProngs", "DCAz of 3-prong candidate daughters;#it{p}_{T} (GeV/#it{c};#it{d}_{z}) (#mum);entries", {HistType::kTH2F, {{100, 0., 20.}, {200, -500., 500.}}}); hCandidates = registry.add("hCandidates", "candidates counter", {HistType::kTH1D, {axisCands}}); - hfEvSel.addHistograms(registry); // collision monitoring + + // init HF event selection helper + hfEvSel.init(registry); massP = MassProton; massPi = MassPiPlus; @@ -193,10 +214,24 @@ struct HfCandidateCreator3Prong { setLabelHistoCands(hCandidates); } + template + void fillProngsPid(TRK const& track0, TRK const& track1, TRK const& track2) + { + fillProngPid(track0, rowProng0PidPi); + fillProngPid(track0, rowProng0PidKa); + fillProngPid(track0, rowProng0PidPr); + fillProngPid(track1, rowProng1PidPi); + fillProngPid(track1, rowProng1PidKa); + fillProngPid(track1, rowProng1PidPr); + fillProngPid(track2, rowProng2PidPi); + fillProngPid(track2, rowProng2PidKa); + fillProngPid(track2, rowProng2PidPr); + } + template void runCreator3ProngWithDCAFitterN(Coll const&, Cand const& rowsTrackIndexProng3, - aod::TracksWCovExtra const&, + TracksWCovExtraPidPiKaPr const&, aod::BCsWithTimestamps const& /*bcWithTimeStamps*/) { // loop over triplets of track indices @@ -211,9 +246,9 @@ struct HfCandidateCreator3Prong { continue; } - auto track0 = rowTrackIndexProng3.template prong0_as(); - auto track1 = rowTrackIndexProng3.template prong1_as(); - auto track2 = rowTrackIndexProng3.template prong2_as(); + auto track0 = rowTrackIndexProng3.template prong0_as(); + auto track1 = rowTrackIndexProng3.template prong1_as(); + auto track2 = rowTrackIndexProng3.template prong2_as(); auto trackParVar0 = getTrackParCov(track0); auto trackParVar1 = getTrackParCov(track1); auto trackParVar2 = getTrackParCov(track2); @@ -336,6 +371,9 @@ struct HfCandidateCreator3Prong { rowTrackIndexProng3.prong0Id(), rowTrackIndexProng3.prong1Id(), rowTrackIndexProng3.prong2Id(), nProngsContributorsPV, bitmapProngsContributorsPV, rowTrackIndexProng3.hfflag()); + // fill candidate prong PID rows + fillProngsPid(track0, track1, track2); + // fill histograms if (fillHistograms) { // calculate invariant mass @@ -361,7 +399,7 @@ struct HfCandidateCreator3Prong { template void runCreator3ProngWithKFParticle(Coll const&, Cand const& rowsTrackIndexProng3, - aod::TracksWCovExtra const&, + TracksWCovExtraPidPiKaPr const&, aod::BCsWithTimestamps const& /*bcWithTimeStamps*/) { for (const auto& rowTrackIndexProng3 : rowsTrackIndexProng3) { @@ -374,9 +412,9 @@ struct HfCandidateCreator3Prong { continue; } - auto track0 = rowTrackIndexProng3.template prong0_as(); - auto track1 = rowTrackIndexProng3.template prong1_as(); - auto track2 = rowTrackIndexProng3.template prong2_as(); + auto track0 = rowTrackIndexProng3.template prong0_as(); + auto track1 = rowTrackIndexProng3.template prong1_as(); + auto track2 = rowTrackIndexProng3.template prong2_as(); /// Set the magnetic field from ccdb. /// The static instance of the propagator was already modified in the HFTrackIndexSkimCreator, @@ -487,6 +525,15 @@ struct HfCandidateCreator3Prong { kfCandPiKK.SetConstructMethod(2); kfCandPiKK.Construct(kfDaughtersPiKK, 3); + const float chi2topo = kfCalculateChi2ToPrimaryVertex(kfCandPKPi, kfpV); + + if (applyTopoConstraint) { // constraints applied after chi2topo getter - to preserve unbiased value of chi2topo + for (const auto& kfCand : std::array{&kfCandPKPi, &kfCandPiKP, &kfCandPiKPi, &kfCandKKPi, &kfCandPiKK}) { + kfCand->SetProductionVertex(kfpV); + kfCand->TransportToDecayVertex(); + } + } + KFParticle kfPairKPi; const KFParticle* kfDaughtersKPi[3] = {&kfSecondKaon, &kfThirdPion}; kfPairKPi.SetConstructMethod(2); @@ -505,8 +552,15 @@ struct HfCandidateCreator3Prong { const float massKPi = kfPairKPi.GetMass(); const float massPiK = kfPairPiK.GetMass(); + if (applyInvMassConstraint) { // constraints applied after minv getters - to preserve unbiased values of minv + kfCandPKPi.SetNonlinearMassConstraint(createLc ? MassLambdaCPlus : MassXiCPlus); + kfCandPiKP.SetNonlinearMassConstraint(createLc ? MassLambdaCPlus : MassXiCPlus); + kfCandPiKPi.SetNonlinearMassConstraint(MassDPlus); + kfCandKKPi.SetNonlinearMassConstraint(MassDS); + kfCandPiKK.SetNonlinearMassConstraint(MassDS); + } + const float chi2geo = kfCandPKPi.Chi2() / kfCandPKPi.NDF(); - const float chi2topo = kfCalculateChi2ToPrimaryVertex(kfCandPKPi, kfpV); const std::pair ldl = kfCalculateLdL(kfCandPKPi, kfpV); std::array pProng0 = kfCalculateProngMomentumInSecondaryVertex(kfFirstProton, kfCandPiKP); @@ -564,6 +618,9 @@ struct HfCandidateCreator3Prong { chi2geoSecondThird, chi2geoFirstThird, chi2geoFirstSecond, chi2geo, ldl.first, ldl.second, chi2topo); + // fill candidate prong PID rows + fillProngsPid(track0, track1, track2); + // fill histograms if (fillHistograms) { registry.fill(HIST("hMass3PiKPi"), massPiKPi); @@ -586,7 +643,7 @@ struct HfCandidateCreator3Prong { /// @brief process function using DCA fitter w/ PV refit and w/o centrality selections void processPvRefitWithDCAFitterN(soa::Join const& collisions, FilteredPvRefitHf3Prongs const& rowsTrackIndexProng3, - aod::TracksWCovExtra const& tracks, + TracksWCovExtraPidPiKaPr const& tracks, aod::BCsWithTimestamps const& bcWithTimeStamps) { runCreator3ProngWithDCAFitterN(collisions, rowsTrackIndexProng3, tracks, bcWithTimeStamps); @@ -596,7 +653,7 @@ struct HfCandidateCreator3Prong { /// @brief process function using DCA fitter w/o PV refit and w/o centrality selections void processNoPvRefitWithDCAFitterN(soa::Join const& collisions, FilteredHf3Prongs const& rowsTrackIndexProng3, - aod::TracksWCovExtra const& tracks, + TracksWCovExtraPidPiKaPr const& tracks, aod::BCsWithTimestamps const& bcWithTimeStamps) { runCreator3ProngWithDCAFitterN(collisions, rowsTrackIndexProng3, tracks, bcWithTimeStamps); @@ -606,7 +663,7 @@ struct HfCandidateCreator3Prong { /// @brief process function using KFParticle package w/ PV refit and w/o centrality selections void processPvRefitWithKFParticle(soa::Join const& collisions, FilteredPvRefitHf3Prongs const& rowsTrackIndexProng3, - aod::TracksWCovExtra const& tracks, + TracksWCovExtraPidPiKaPr const& tracks, aod::BCsWithTimestamps const& bcWithTimeStamps) { runCreator3ProngWithKFParticle(collisions, rowsTrackIndexProng3, tracks, bcWithTimeStamps); @@ -616,7 +673,7 @@ struct HfCandidateCreator3Prong { /// @brief process function using KFParticle package w/o PV refit and w/o centrality selections void processNoPvRefitWithKFParticle(soa::Join const& collisions, FilteredHf3Prongs const& rowsTrackIndexProng3, - aod::TracksWCovExtra const& tracks, + TracksWCovExtraPidPiKaPr const& tracks, aod::BCsWithTimestamps const& bcWithTimeStamps) { runCreator3ProngWithKFParticle(collisions, rowsTrackIndexProng3, tracks, bcWithTimeStamps); @@ -632,7 +689,7 @@ struct HfCandidateCreator3Prong { /// @brief process function using DCA fitter w/ PV refit and w/ centrality selection on FT0C void processPvRefitWithDCAFitterNCentFT0C(soa::Join const& collisions, FilteredPvRefitHf3Prongs const& rowsTrackIndexProng3, - aod::TracksWCovExtra const& tracks, + TracksWCovExtraPidPiKaPr const& tracks, aod::BCsWithTimestamps const& bcWithTimeStamps) { runCreator3ProngWithDCAFitterN(collisions, rowsTrackIndexProng3, tracks, bcWithTimeStamps); @@ -642,7 +699,7 @@ struct HfCandidateCreator3Prong { /// @brief process function using DCA fitter w/o PV refit and w/ centrality selection on FT0C void processNoPvRefitWithDCAFitterNCentFT0C(soa::Join const& collisions, FilteredHf3Prongs const& rowsTrackIndexProng3, - aod::TracksWCovExtra const& tracks, + TracksWCovExtraPidPiKaPr const& tracks, aod::BCsWithTimestamps const& bcWithTimeStamps) { runCreator3ProngWithDCAFitterN(collisions, rowsTrackIndexProng3, tracks, bcWithTimeStamps); @@ -652,7 +709,7 @@ struct HfCandidateCreator3Prong { /// @brief process function using KFParticle package w/ PV refit and w/ centrality selection on FT0C void processPvRefitWithKFParticleCentFT0C(soa::Join const& collisions, FilteredPvRefitHf3Prongs const& rowsTrackIndexProng3, - aod::TracksWCovExtra const& tracks, + TracksWCovExtraPidPiKaPr const& tracks, aod::BCsWithTimestamps const& bcWithTimeStamps) { runCreator3ProngWithKFParticle(collisions, rowsTrackIndexProng3, tracks, bcWithTimeStamps); @@ -662,7 +719,7 @@ struct HfCandidateCreator3Prong { /// @brief process function using KFParticle package w/o PV refit and w/ centrality selection on FT0C void processNoPvRefitWithKFParticleCentFT0C(soa::Join const& collisions, FilteredHf3Prongs const& rowsTrackIndexProng3, - aod::TracksWCovExtra const& tracks, + TracksWCovExtraPidPiKaPr const& tracks, aod::BCsWithTimestamps const& bcWithTimeStamps) { runCreator3ProngWithKFParticle(collisions, rowsTrackIndexProng3, tracks, bcWithTimeStamps); @@ -678,7 +735,7 @@ struct HfCandidateCreator3Prong { /// @brief process function using DCA fitter w/ PV refit and w/ centrality selection on FT0M void processPvRefitWithDCAFitterNCentFT0M(soa::Join const& collisions, FilteredPvRefitHf3Prongs const& rowsTrackIndexProng3, - aod::TracksWCovExtra const& tracks, + TracksWCovExtraPidPiKaPr const& tracks, aod::BCsWithTimestamps const& bcWithTimeStamps) { runCreator3ProngWithDCAFitterN(collisions, rowsTrackIndexProng3, tracks, bcWithTimeStamps); @@ -688,7 +745,7 @@ struct HfCandidateCreator3Prong { /// @brief process function using DCA fitter w/o PV refit and w/ centrality selection on FT0M void processNoPvRefitWithDCAFitterNCentFT0M(soa::Join const& collisions, FilteredHf3Prongs const& rowsTrackIndexProng3, - aod::TracksWCovExtra const& tracks, + TracksWCovExtraPidPiKaPr const& tracks, aod::BCsWithTimestamps const& bcWithTimeStamps) { runCreator3ProngWithDCAFitterN(collisions, rowsTrackIndexProng3, tracks, bcWithTimeStamps); @@ -698,7 +755,7 @@ struct HfCandidateCreator3Prong { /// @brief process function using KFParticle package w/ PV refit and w/ centrality selection on FT0M void processPvRefitWithKFParticleCentFT0M(soa::Join const& collisions, FilteredPvRefitHf3Prongs const& rowsTrackIndexProng3, - aod::TracksWCovExtra const& tracks, + TracksWCovExtraPidPiKaPr const& tracks, aod::BCsWithTimestamps const& bcWithTimeStamps) { runCreator3ProngWithKFParticle(collisions, rowsTrackIndexProng3, tracks, bcWithTimeStamps); @@ -708,7 +765,7 @@ struct HfCandidateCreator3Prong { /// @brief process function using KFParticle package w/o PV refit and w/ centrality selection on FT0M void processNoPvRefitWithKFParticleCentFT0M(soa::Join const& collisions, FilteredHf3Prongs const& rowsTrackIndexProng3, - aod::TracksWCovExtra const& tracks, + TracksWCovExtraPidPiKaPr const& tracks, aod::BCsWithTimestamps const& bcWithTimeStamps) { runCreator3ProngWithKFParticle(collisions, rowsTrackIndexProng3, tracks, bcWithTimeStamps); @@ -787,6 +844,8 @@ struct HfCandidateCreator3ProngExpressions { Configurable matchKinkedDecayTopology{"matchKinkedDecayTopology", false, "Match also candidates with tracks that decay with kinked topology"}; Configurable matchInteractionsWithMaterial{"matchInteractionsWithMaterial", false, "Match also candidates with tracks that interact with material"}; + constexpr static std::size_t NDaughtersResonant{2u}; + HfEventSelectionMc hfEvSelMc; // mc event selection and monitoring using BCsInfo = soa::Join; @@ -813,12 +872,11 @@ struct HfCandidateCreator3ProngExpressions { const auto& workflows = initContext.services().get(); for (const DeviceSpec& device : workflows.devices) { if (device.name.compare("hf-candidate-creator-3prong") == 0) { - hfEvSelMc.configureFromDevice(device); + // init HF event selection helper + hfEvSelMc.init(device, registry); break; } } - - hfEvSelMc.addHistograms(registry); // particles monitoring } /// Performs MC matching. @@ -924,7 +982,7 @@ struct HfCandidateCreator3ProngExpressions { swapping = int8_t(std::abs(arrayDaughters[0].mcParticle().pdgCode()) == kPiPlus); } RecoDecay::getDaughters(mcParticles.rawIteratorAt(indexRec), &arrDaughIndex, std::array{0}, 1); - if (arrDaughIndex.size() == 2) { + if (arrDaughIndex.size() == NDaughtersResonant) { for (auto iProng = 0u; iProng < arrDaughIndex.size(); ++iProng) { auto daughI = mcParticles.rawIteratorAt(arrDaughIndex[iProng]); arrPDGDaugh[iProng] = std::abs(daughI.pdgCode()); @@ -970,7 +1028,7 @@ struct HfCandidateCreator3ProngExpressions { swapping = int8_t(std::abs(arrayDaughters[0].mcParticle().pdgCode()) == kPiPlus); } RecoDecay::getDaughters(mcParticles.rawIteratorAt(indexRec), &arrDaughIndex, std::array{0}, 1); - if (arrDaughIndex.size() == 2) { + if (arrDaughIndex.size() == NDaughtersResonant) { for (auto iProng = 0u; iProng < arrDaughIndex.size(); ++iProng) { auto daughI = mcParticles.rawIteratorAt(arrDaughIndex[iProng]); arrPDGDaugh[iProng] = std::abs(daughI.pdgCode()); diff --git a/PWGHF/TableProducer/candidateCreatorCascade.cxx b/PWGHF/TableProducer/candidateCreatorCascade.cxx index 23c26f7ae7c..25c7a343849 100644 --- a/PWGHF/TableProducer/candidateCreatorCascade.cxx +++ b/PWGHF/TableProducer/candidateCreatorCascade.cxx @@ -118,7 +118,9 @@ struct HfCandidateCreatorCascade { registry.add("hCovPVXX", "2-prong candidates;XX element of cov. matrix of prim. vtx. position (cm^{2});entries", {HistType::kTH1F, {{100, 0., 1.e-4}}}); registry.add("hCovSVXX", "2-prong candidates;XX element of cov. matrix of sec. vtx. position (cm^{2});entries", {HistType::kTH1F, {{100, 0., 0.2}}}); hCandidates = registry.add("hCandidates", "candidates counter", {HistType::kTH1D, {axisCands}}); - hfEvSel.addHistograms(registry); // collision monitoring + + // init HF event selection helper + hfEvSel.init(registry); massP = MassProton; massK0s = MassK0Short; @@ -471,11 +473,11 @@ struct HfCandidateCreatorCascadeMc { const auto& workflows = initContext.services().get(); for (const DeviceSpec& device : workflows.devices) { if (device.name.compare("hf-candidate-creator-cascade") == 0) { - hfEvSelMc.configureFromDevice(device); + // init HF event selection helper + hfEvSelMc.init(device, registry); break; } } - hfEvSelMc.addHistograms(registry); // particles monitoring } template diff --git a/PWGHF/TableProducer/candidateCreatorDstar.cxx b/PWGHF/TableProducer/candidateCreatorDstar.cxx index 110edad7cfb..8e2cca50cd5 100644 --- a/PWGHF/TableProducer/candidateCreatorDstar.cxx +++ b/PWGHF/TableProducer/candidateCreatorDstar.cxx @@ -35,6 +35,7 @@ #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/Utils/utilsBfieldCCDB.h" #include "PWGHF/Utils/utilsEvSelHf.h" +#include "PWGHF/Utils/utilsPid.h" #include "PWGHF/Utils/utilsTrkCandHf.h" using namespace o2; @@ -43,6 +44,7 @@ using namespace o2::hf_trkcandsel; using namespace o2::hf_centrality; using namespace o2::constants::physics; using namespace o2::framework; +using namespace o2::aod::pid_tpc_tof_utils; namespace o2::aod { @@ -53,6 +55,12 @@ using HfDstarsWithPvRefitInfo = soa::Join; struct HfCandidateCreatorDstar { Produces rowCandD0Base; Produces rowCandDstarBase; + Produces rowProng0PidPi; + Produces rowProng0PidKa; + Produces rowProng1PidPi; + Produces rowProng1PidKa; + Produces rowProngSoftPiPidPi; + Produces rowProngSoftPiPidKa; Configurable fillHistograms{"fillHistograms", true, "fill histograms"}; @@ -82,6 +90,8 @@ struct HfCandidateCreatorDstar { static constexpr float CmToMicrometers = 10000.; // from cm to µm double massPi, massK, massD0; + using TracksWCovExtraPidPiKa = soa::Join; + AxisSpec ptAxis = {100, 0., 2.0, "#it{p}_{T} (GeV/#it{c}"}; AxisSpec dcaAxis = {200, -500., 500., "#it{d}_{xy,z} (#mum)"}; @@ -136,7 +146,9 @@ struct HfCandidateCreatorDstar { } hCandidates = registry.add("hCandidates", "candidates counter", {HistType::kTH1D, {axisCands}}); - hfEvSel.addHistograms(registry); // collision monitoring + + // init HF event selection helper + hfEvSel.init(registry); // LOG(info) << "Init Function Invoked"; massPi = MassPiPlus; @@ -191,10 +203,10 @@ struct HfCandidateCreatorDstar { continue; } - auto trackPi = rowTrackIndexDstar.template prong0_as(); + auto trackPi = rowTrackIndexDstar.template prong0_as(); auto prongD0 = rowTrackIndexDstar.template prongD0_as(); - auto trackD0Prong0 = prongD0.template prong0_as(); - auto trackD0Prong1 = prongD0.template prong1_as(); + auto trackD0Prong0 = prongD0.template prong0_as(); + auto trackD0Prong1 = prongD0.template prong1_as(); // Extracts primary vertex position and covariance matrix from a collision auto primaryVertex = getPrimaryVertex(collision); @@ -344,6 +356,14 @@ struct HfCandidateCreatorDstar { std::sqrt(impactParameter0.getSigmaZ2()), std::sqrt(impactParameter1.getSigmaZ2()), prongD0.prong0Id(), prongD0.prong1Id(), prongD0.hfflag()); + // fill candidate D0 prong PID rows + fillProngPid(trackD0Prong0, rowProng0PidPi); + fillProngPid(trackD0Prong0, rowProng0PidKa); + fillProngPid(trackD0Prong1, rowProng1PidPi); + fillProngPid(trackD0Prong1, rowProng1PidKa); + // fill soft-pion PID rows + fillProngPid(trackPi, rowProngSoftPiPidPi); + fillProngPid(trackPi, rowProngSoftPiPidKa); if (fillHistograms) { registry.fill(HIST("QA/hPtD0"), ptD0); @@ -534,11 +554,11 @@ struct HfCandidateCreatorDstarExpressions { const auto& workflows = initContext.services().get(); for (const DeviceSpec& device : workflows.devices) { if (device.name.compare("hf-candidate-creator-dstar") == 0) { - hfEvSelMc.configureFromDevice(device); + // init HF event selection helper + hfEvSelMc.init(device, registry); break; } } - hfEvSelMc.addHistograms(registry); // particles monitoring } /// Perform MC Matching. diff --git a/PWGHF/TableProducer/candidateCreatorSigmac0plusplus.cxx b/PWGHF/TableProducer/candidateCreatorSigmac0plusplus.cxx index e882dcd2dba..1e6c7d982a4 100644 --- a/PWGHF/TableProducer/candidateCreatorSigmac0plusplus.cxx +++ b/PWGHF/TableProducer/candidateCreatorSigmac0plusplus.cxx @@ -39,6 +39,7 @@ #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" #include "PWGHF/Utils/utilsBfieldCCDB.h" // for dca recalculation +#include "PWGHF/Utils/utilsEvSelHf.h" using namespace o2; using namespace o2::analysis; @@ -142,7 +143,8 @@ struct HfCandidateCreatorSigmac0plusplus { softPiCuts.SetMaxChi2PerClusterITS(softPiChi2Max); // ITS hitmap std::set setSoftPiItsHitMap; // = {}; - for (int idItsLayer = 0; idItsLayer < 7; idItsLayer++) { + constexpr std::size_t NLayersIts = 7; + for (std::size_t idItsLayer = 0u; idItsLayer < NLayersIts; idItsLayer++) { if (TESTBIT(softPiItsHitMap, idItsLayer)) { setSoftPiItsHitMap.insert(static_cast(idItsLayer)); } @@ -178,7 +180,7 @@ struct HfCandidateCreatorSigmac0plusplus { /// keep only the candidates flagged as possible Λc+ (and charge conj.) decaying into a charged pion, kaon and proton /// if not selected, skip it and go to the next one - if (!(candLc.hfflag() & 1 << aod::hf_cand_3prong::DecayType::LcToPKPi)) { + if (!(candLc.hfflag() & BIT(aod::hf_cand_3prong::DecayType::LcToPKPi))) { continue; } /// keep only the candidates Λc+ (and charge conj.) within the desired rapidity @@ -234,7 +236,7 @@ struct HfCandidateCreatorSigmac0plusplus { int chargeLc = candLc.template prong0_as().sign() + candLc.template prong1_as().sign() + candLc.template prong2_as().sign(); int chargeSoftPi = trackSoftPi.sign(); int8_t chargeSigmac = chargeLc + chargeSoftPi; - if (std::abs(chargeSigmac) != 0 && std::abs(chargeSigmac) != 2) { + if (std::abs(chargeSigmac) != o2::aod::hf_cand_sigmac::ChargeNull && std::abs(chargeSigmac) != o2::aod::hf_cand_sigmac::ChargePlusPlus) { /// this shall never happen LOG(fatal) << ">>> Sc candidate with charge +1 built, not possible! Charge Lc: " << chargeLc << ", charge soft pion: " << chargeSoftPi; } @@ -387,23 +389,27 @@ struct HfCandidateSigmac0plusplusMc { Produces rowMCMatchScRec; Produces rowMCMatchScGen; + o2::hf_evsel::HfEventSelectionMc hfEvSelMc; // mc event selection and monitoring + + using BCsInfo = soa::Join; using LambdacMc = soa::Join; // using LambdacMcGen = soa::Join; + using McCollisionsNoCents = soa::Join; + + PresliceUnsorted colPerMcCollision = aod::mccollisionlabel::mcCollisionId; - float zPvPosMax{1000.f}; + HistogramRegistry registry{"registry"}; /// @brief init function void init(InitContext& initContext) { const auto& workflows = initContext.services().get(); for (const DeviceSpec& device : workflows.devices) { - if (device.name.compare("hf-candidate-creator-3prong") == 0) { // here we assume that the hf-candidate-creator-3prong is in the workflow - for (const auto& option : device.options) { - if (option.name.compare("hfEvSel.zPvPosMax") == 0) { - zPvPosMax = option.defaultValue.get(); - break; - } - } + // here we assume that the hf-candidate-creator-3prong is in the workflow + // configure the ev. sel from that workflow + if (device.name.compare("hf-candidate-creator-3prong") == 0) { + // init HF event selection helper + hfEvSelMc.init(device, registry); break; } } @@ -419,7 +425,9 @@ struct HfCandidateSigmac0plusplusMc { void processMc(aod::McParticles const& mcParticles, aod::TracksWMc const& tracks, LambdacMc const& candsLc /*, const LambdacMcGen&*/, - aod::McCollisions const&) + McCollisionsNoCents const& collInfos, + aod::McCollisions const&, + BCsInfo const&) { // Match reconstructed candidates. @@ -442,7 +450,7 @@ struct HfCandidateSigmac0plusplusMc { /// skip immediately the candidate Σc0,++ w/o a Λc+ matched to MC auto candLc = candSigmac.prongLc_as(); - if (!(std::abs(candLc.flagMcMatchRec()) == 1 << aod::hf_cand_3prong::DecayType::LcToPKPi)) { /// (*) + if (!(std::abs(candLc.flagMcMatchRec()) == BIT(aod::hf_cand_3prong::DecayType::LcToPKPi))) { /// (*) rowMCMatchScRec(flag, origin, -1.f, 0); continue; } @@ -453,25 +461,46 @@ struct HfCandidateSigmac0plusplusMc { candLc.prong2_as(), candSigmac.prong1_as()}; chargeSigmac = candSigmac.charge(); - if (chargeSigmac == 0) { + if (chargeSigmac == o2::aod::hf_cand_sigmac::ChargeNull) { /// candidate Σc0 /// 3 levels: /// 1. Σc0 → Λc+ π-,+ /// 2. Λc+ → pK-π+ direct (i) or Λc+ → resonant channel Λc± → p± K*, Λc± → Δ(1232)±± K∓ or Λc± → Λ(1520) π± (ii) /// 3. in case of (ii): resonant channel to pK-π+ + + /// look for Σc0(2455) indexRec = RecoDecay::getMatchedMCRec(mcParticles, arrayDaughters, Pdg::kSigmaC0, std::array{+kProton, -kKPlus, +kPiPlus, -kPiPlus}, true, &sign, 3); if (indexRec > -1) { /// due to (*) no need to check anything for LambdaC - flag = sign * (1 << aod::hf_cand_sigmac::DecayType::Sc0ToPKPiPi); + flag = sign * BIT(aod::hf_cand_sigmac::DecayType::Sc0ToPKPiPi); } - } else if (std::abs(chargeSigmac) == 2) { + + /// look for Σc0(2520) + if (flag == 0) { + indexRec = RecoDecay::getMatchedMCRec(mcParticles, arrayDaughters, Pdg::kSigmaCStar0, std::array{+kProton, -kKPlus, +kPiPlus, -kPiPlus}, true, &sign, 3); + if (indexRec > -1) { /// due to (*) no need to check anything for LambdaC + flag = sign * BIT(aod::hf_cand_sigmac::DecayType::ScStar0ToPKPiPi); + } + } + + } else if (std::abs(chargeSigmac) == o2::aod::hf_cand_sigmac::ChargePlusPlus) { /// candidate Σc++ /// 3 levels: /// 1. Σc0 → Λc+ π-,+ /// 2. Λc+ → pK-π+ direct (i) or Λc+ → resonant channel Λc± → p± K*, Λc± → Δ(1232)±± K∓ or Λc± → Λ(1520) π± (ii) /// 3. in case of (ii): resonant channel to pK-π+ + + /// look for Σc++(2455) indexRec = RecoDecay::getMatchedMCRec(mcParticles, arrayDaughters, Pdg::kSigmaCPlusPlus, std::array{+kProton, -kKPlus, +kPiPlus, +kPiPlus}, true, &sign, 3); if (indexRec > -1) { /// due to (*) no need to check anything for LambdaC - flag = sign * (1 << aod::hf_cand_sigmac::DecayType::ScplusplusToPKPiPi); + flag = sign * BIT(aod::hf_cand_sigmac::DecayType::ScplusplusToPKPiPi); + } + + /// look for Σc++(2520) + if (flag == 0) { + indexRec = RecoDecay::getMatchedMCRec(mcParticles, arrayDaughters, Pdg::kSigmaCStarPlusPlus, std::array{+kProton, -kKPlus, +kPiPlus, +kPiPlus}, true, &sign, 3); + if (indexRec > -1) { /// due to (*) no need to check anything for LambdaC + flag = sign * BIT(aod::hf_cand_sigmac::DecayType::ScStarPlusPlusToPKPiPi); + } } } @@ -495,9 +524,16 @@ struct HfCandidateSigmac0plusplusMc { origin = 0; std::vector idxBhadMothers{}; + /// MC ev. selection done w/o centrality estimator + /// In case of need, readapt the code templetizing the function auto mcCollision = particle.mcCollision(); - float zPv = mcCollision.posZ(); - if (zPv < -zPvPosMax || zPv > zPvPosMax) { // to avoid counting particles in collisions with Zvtx larger than the maximum, we do not match them + float centrality{-1.f}; + uint16_t rejectionMask{0}; + const auto collSlice = collInfos.sliceBy(colPerMcCollision, mcCollision.globalIndex()); + rejectionMask = hfEvSelMc.getHfMcCollisionRejectionMask(mcCollision, collSlice, centrality); + hfEvSelMc.fillHistograms(mcCollision, rejectionMask, 0); + if (rejectionMask != 0) { + // at least one event selection not satisfied --> reject gen particles from this collision rowMCMatchScGen(flag, origin, -1); continue; } @@ -507,36 +543,63 @@ struct HfCandidateSigmac0plusplusMc { /// 2. Λc+ → pK-π+ direct (i) or Λc+ → resonant channel Λc± → p± K*, Λc± → Δ(1232)±± K∓ or Λc± → Λ(1520) π± (ii) /// 3. in case of (ii): resonant channel to pK-π+ /// → here we check level 1. first, and then levels 2. and 3. are inherited by the Λc+ → pK-π+ MC matching in candidateCreator3Prong.cxx + + /// look for Σc0,++(2455) if (RecoDecay::isMatchedMCGen(mcParticles, particle, Pdg::kSigmaC0, std::array{static_cast(Pdg::kLambdaCPlus), static_cast(kPiMinus)}, true, &sign, 1)) { - // generated Σc0 - // for (const auto& daughter : particle.daughters_as()) { + // generated Σc0(2455) for (const auto& daughter : particle.daughters_as()) { // look for Λc+ daughter decaying in pK-π+ if (std::abs(daughter.pdgCode()) != Pdg::kLambdaCPlus) continue; - // if (std::abs(daughter.flagMcMatchGen()) == (1 << aod::hf_cand_3prong::DecayType::LcToPKPi)) { if (RecoDecay::isMatchedMCGen(mcParticles, daughter, Pdg::kLambdaCPlus, std::array{+kProton, -kKPlus, +kPiPlus}, true, &sign, 2)) { /// Λc+ daughter decaying in pK-π+ found! - flag = sign * (1 << aod::hf_cand_sigmac::DecayType::Sc0ToPKPiPi); + flag = sign * BIT(aod::hf_cand_sigmac::DecayType::Sc0ToPKPiPi); break; } } } else if (RecoDecay::isMatchedMCGen(mcParticles, particle, Pdg::kSigmaCPlusPlus, std::array{static_cast(Pdg::kLambdaCPlus), static_cast(kPiPlus)}, true, &sign, 1)) { - // generated Σc++ - // for (const auto& daughter : particle.daughters_as()) { + // generated Σc++(2455) for (const auto& daughter : particle.daughters_as()) { // look for Λc+ daughter decaying in pK-π+ if (std::abs(daughter.pdgCode()) != Pdg::kLambdaCPlus) continue; - // if (std::abs(daughter.flagMcMatchGen()) == (1 << aod::hf_cand_3prong::DecayType::LcToPKPi)) { if (RecoDecay::isMatchedMCGen(mcParticles, daughter, Pdg::kLambdaCPlus, std::array{+kProton, -kKPlus, +kPiPlus}, true, &sign, 2)) { /// Λc+ daughter decaying in pK-π+ found! - flag = sign * (1 << aod::hf_cand_sigmac::DecayType::ScplusplusToPKPiPi); + flag = sign * BIT(aod::hf_cand_sigmac::DecayType::ScplusplusToPKPiPi); break; } } } + /// look for Σc0,++(2520) + if (flag == 0) { + if (RecoDecay::isMatchedMCGen(mcParticles, particle, Pdg::kSigmaCStar0, std::array{static_cast(Pdg::kLambdaCPlus), static_cast(kPiMinus)}, true, &sign, 1)) { + // generated Σc0(2520) + for (const auto& daughter : particle.daughters_as()) { + // look for Λc+ daughter decaying in pK-π+ + if (std::abs(daughter.pdgCode()) != Pdg::kLambdaCPlus) + continue; + if (RecoDecay::isMatchedMCGen(mcParticles, daughter, Pdg::kLambdaCPlus, std::array{+kProton, -kKPlus, +kPiPlus}, true, &sign, 2)) { + /// Λc+ daughter decaying in pK-π+ found! + flag = sign * BIT(aod::hf_cand_sigmac::DecayType::ScStar0ToPKPiPi); + break; + } + } + } else if (RecoDecay::isMatchedMCGen(mcParticles, particle, Pdg::kSigmaCStarPlusPlus, std::array{static_cast(Pdg::kLambdaCPlus), static_cast(kPiPlus)}, true, &sign, 1)) { + // generated Σc++(2520) + for (const auto& daughter : particle.daughters_as()) { + // look for Λc+ daughter decaying in pK-π+ + if (std::abs(daughter.pdgCode()) != Pdg::kLambdaCPlus) + continue; + if (RecoDecay::isMatchedMCGen(mcParticles, daughter, Pdg::kLambdaCPlus, std::array{+kProton, -kKPlus, +kPiPlus}, true, &sign, 2)) { + /// Λc+ daughter decaying in pK-π+ found! + flag = sign * BIT(aod::hf_cand_sigmac::DecayType::ScStarPlusPlusToPKPiPi); + break; + } + } + } + } + /// check the origin (prompt vs. non-prompt) if (flag != 0) { origin = RecoDecay::getCharmHadronOrigin(mcParticles, particle, false, &idxBhadMothers); @@ -547,6 +610,12 @@ struct HfCandidateSigmac0plusplusMc { } else { rowMCMatchScGen(flag, origin, -1); } + + // debug + // if(origin != RecoDecay::OriginType::Prompt && origin != RecoDecay::OriginType::NonPrompt) { + // LOG(info) << " --> origin " << static_cast(origin) << ", flag " << static_cast(flag); + //} + } /// end loop over mcParticles } /// end processMc PROCESS_SWITCH(HfCandidateSigmac0plusplusMc, processMc, "Process MC", false); diff --git a/PWGHF/TableProducer/candidateCreatorXic0Omegac0.cxx b/PWGHF/TableProducer/candidateCreatorXic0Omegac0.cxx index 01a52fc073e..277fc56227e 100644 --- a/PWGHF/TableProducer/candidateCreatorXic0Omegac0.cxx +++ b/PWGHF/TableProducer/candidateCreatorXic0Omegac0.cxx @@ -88,6 +88,7 @@ struct HfCandidateCreatorXic0Omegac0 { Produces rowCandToOmegaK; Produces kfCandidateData; Produces kfCandidateXicData; + Produces rowKfXic0Qa; Configurable propagateToPCA{"propagateToPCA", false, "create tracks version propagated to PCA"}; Configurable useAbsDCA{"useAbsDCA", true, "Minimise abs. distance rather than chi2"}; @@ -118,6 +119,7 @@ struct HfCandidateCreatorXic0Omegac0 { Configurable kfConstructMethod{"kfConstructMethod", 2, "KF Construct Method"}; Configurable kfUseV0MassConstraint{"kfUseV0MassConstraint", false, "KF: use Lambda mass constraint"}; Configurable kfUseCascadeMassConstraint{"kfUseCascadeMassConstraint", false, "KF: use Cascade mass constraint"}; + Configurable kfResolutionQA{"kfResolutionQA", false, "KF: KFParticle Quality Assurance"}; HfEventSelection hfEvSel; // event selection and monitoring o2::vertexing::DCAFitterN<2> df; // 2-prong vertex fitter to build the omegac/xic vertex @@ -236,6 +238,7 @@ struct HfCandidateCreatorXic0Omegac0 { float chi2MassCasc; float etaXic; } kfXic0Candidate; + void init(InitContext const&) { std::array allProcesses = {doprocessNoCentToXiPi, doprocessNoCentToXiPiTraCasc, doprocessCentFT0CToXiPi, doprocessCentFT0MToXiPi, doprocessNoCentToOmegaPi, doprocessOmegacToOmegaPiWithKFParticle, doprocessCentFT0CToOmegaPi, doprocessCentFT0MToOmegaPi, doprocessNoCentToOmegaK, doprocessCentFT0CToOmegaK, doprocessCentFT0MToOmegaK, doprocessXicToXiPiWithKFParticle}; @@ -341,7 +344,9 @@ struct HfCandidateCreatorXic0Omegac0 { registry.add("hKFcosPaV0ToCasc", "hKFcosPaV0ToCasc", kTH1D, {{5000, 0.8f, 1.1f}}); registry.add("hKFcosPaCascToOmegac", "hKFcosPaCascToOmegac", kTH1D, {{5000, 0.8f, 1.1f}}); } - hfEvSel.addHistograms(registry); // collision monitoring + + // init HF event selection helper + hfEvSel.init(registry); df.setPropagateToPCA(propagateToPCA); df.setMaxR(maxR); @@ -1293,7 +1298,7 @@ struct HfCandidateCreatorXic0Omegac0 { KFParticle kfV0MassConstrained = kfV0; kfV0MassConstrained.SetNonlinearMassConstraint(o2::constants::physics::MassLambda); // set mass constrain to Lambda if (kfUseV0MassConstraint) { - KFParticle kfV0 = kfV0MassConstrained; + kfV0 = kfV0MassConstrained; } kfV0.TransportToDecayVertex(); @@ -1362,6 +1367,8 @@ struct HfCandidateCreatorXic0Omegac0 { KFPVertex kfVertex = createKFPVertexFromCollision(collision); KFParticle kfPV(kfVertex); + KFParticle kfPosOrigin = kfPos; + KFParticle kfNegOrigin = kfNeg; // set production vertex; kfNeg.SetProductionVertex(kfV0); kfPos.SetProductionVertex(kfV0); @@ -1616,7 +1623,19 @@ struct HfCandidateCreatorXic0Omegac0 { kfXic0Candidate.cosThetaStarPiFromXic, v0NDF, cascNDF, charmbaryonNDF, v0Ndfm, cascNdfm, v0Chi2OverNdf, cascChi2OverNdf, charmbaryonChi2OverNdf, v0Chi2OverNdfm, cascChi2OverNdfm); - + // fill QA table + if (kfResolutionQA) { + rowKfXic0Qa(massLam, massCasc, massXiC0, sigLam, sigCasc, sigXiC0, + collision.globalIndex(), v0index, casc.posTrackId(), casc.negTrackId(), casc.cascadeId(), trackCharmBachelor.globalIndex(), casc.bachelorId(), + kfPos.GetX(), kfPos.GetY(), kfPos.GetZ(), kfPos.GetErrX(), kfPos.GetErrY(), kfPos.GetErrZ(), kfPos.GetPt(), + kfNeg.GetX(), kfNeg.GetY(), kfNeg.GetZ(), kfNeg.GetErrX(), kfNeg.GetErrY(), kfNeg.GetErrZ(), kfNeg.GetPt(), + kfV0.GetX(), kfV0.GetY(), kfV0.GetZ(), kfV0.GetErrX(), kfV0.GetErrY(), kfV0.GetErrZ(), kfV0.GetPt(), + kfBachPionToXi.GetX(), kfBachPionToXi.GetY(), kfBachPionToXi.GetZ(), kfBachPionToXi.GetErrX(), kfBachPionToXi.GetErrY(), kfBachPionToXi.GetErrZ(), kfBachPionToXi.GetPt(), + kfXi.GetX(), kfXi.GetY(), kfXi.GetZ(), kfXi.GetErrX(), kfXi.GetErrY(), kfXi.GetErrZ(), kfXi.GetPt(), + kfCharmBachPionToXiC.GetX(), kfCharmBachPionToXiC.GetY(), kfCharmBachPionToXiC.GetZ(), kfCharmBachPionToXiC.GetErrX(), kfCharmBachPionToXiC.GetErrY(), kfCharmBachPionToXiC.GetErrZ(), kfCharmBachPionToXiC.GetPt(), + kfXiC0.GetX(), kfXiC0.GetY(), kfXiC0.GetZ(), kfXiC0.GetErrX(), kfXiC0.GetErrY(), kfXiC0.GetErrZ(), kfXiC0.GetPt(), + casc.xlambda(), casc.ylambda(), casc.zlambda(), casc.x(), casc.y(), casc.z()); + } } // loop over LF Cascade-bachelor candidates } /// @brief process function w/o centrality selections @@ -1859,7 +1878,7 @@ struct HfCandidateCreatorXic0Omegac0Mc { // inspect for which zPvPosMax cut was set for reconstructed void init(InitContext& initContext) { - std::array procCollisionsXicToXiPi{doprocessMcXicToXiPi, doprocessMcXicToXiPiFT0m, doprocessMcXicToXiPiFT0c, doprocessMcXicToXiPiKf}; + std::array procCollisionsXicToXiPi{doprocessMcXicToXiPi, doprocessMcXicToXiPiFT0m, doprocessMcXicToXiPiFT0c, doprocessMcXicToXiPiKf, doprocessMcXicToXiPiKfQa}; if (std::accumulate(procCollisionsXicToXiPi.begin(), procCollisionsXicToXiPi.end(), 0) > 1) { LOGP(fatal, "At most one process function for XicToXiPi collision study can be enabled at a time."); } @@ -1879,11 +1898,11 @@ struct HfCandidateCreatorXic0Omegac0Mc { const auto& workflows = initContext.services().get(); for (const DeviceSpec& device : workflows.devices) { if (device.name.compare("hf-candidate-creator-xic0-omegac0") == 0) { - hfEvSelMc.configureFromDevice(device); + // init HF event selection helper + hfEvSelMc.init(device, registry); break; } } - hfEvSelMc.addHistograms(registry); // particles monitoring hGenCharmBaryonPtRapidityTightXicToXiPi = registry.add("hGenCharmBaryonPtRapidityTightXicToXiPi", "Generated charm baryon #it{p}_{T};#it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1D, {{20, 0.0, 20.0}}}); // keep track of generated candidates pt when |y|<0.5 hGenCharmBaryonPtRapidityLooseXicToXiPi = registry.add("hGenCharmBaryonPtRapidityLooseXicToXiPi", "Generated charm baryon #it{p}_{T};#it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1D, {{20, 0.0, 20.0}}}); // keep track of generated candidates pt when |y|<0.8 @@ -1896,6 +1915,139 @@ struct HfCandidateCreatorXic0Omegac0Mc { hGenCharmBaryonPtRapidityTightOmegacToOmegaK = registry.add("hGenCharmBaryonPtRapidityTightOmegacToOmegaK", "Generated charm baryon #it{p}_{T};#it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1D, {{20, 0.0, 20.0}}}); hGenCharmBaryonPtRapidityLooseOmegacToOmegaK = registry.add("hGenCharmBaryonPtRapidityLooseOmegacToOmegaK", "Generated charm baryon #it{p}_{T};#it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1D, {{20, 0.0, 20.0}}}); + + // QA + if (doprocessMcXicToXiPiKfQa) { + AxisSpec axisPt{20, 0., 20.}; + AxisSpec axisPull{2000, -10., 10.}; + // mass over pt + registry.add("hV0MassPullVsPt", "m_{PULL}(V0) vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); + registry.add("hXiMassPullVsPt", "m_{PULL}(#Xi^{-}) vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); + registry.add("hXic0MassPullVsPt", "m_{PULL}(#Xic0) vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); + // delta + registry.add("hV0DauPosXDelta", "x^{p} - x^{MC}", kTH1D, {axisPull}); + registry.add("hV0DauPosYDelta", "y^{p} - y^{MC}", kTH1D, {axisPull}); + registry.add("hV0DauPosZDelta", "z^{p} - z^{MC}", kTH1D, {axisPull}); + registry.add("hV0DauNegXDelta", "x^{#pi^{-}} - x^{MC}", kTH1D, {axisPull}); + registry.add("hV0DauNegYDelta", "y^{#pi^{-}} - y^{MC}", kTH1D, {axisPull}); + registry.add("hV0DauNegZDelta", "z^{#pi^{-}} - z^{MC}", kTH1D, {axisPull}); + registry.add("hV0XDelta", "x^{#Lambda} - x^{MC}", kTH1D, {axisPull}); + registry.add("hV0YDelta", "y^{#Lambda} - y^{MC}", kTH1D, {axisPull}); + registry.add("hV0ZDelta", "z^{#Lambda} - z^{MC}", kTH1D, {axisPull}); + + registry.add("hXiBachelorXDelta", "x^{#pi^{-} from #Xi^{-}} - x^{MC}", kTH1D, {axisPull}); + registry.add("hXiBachelorYDelta", "y^{#pi^{-} from #Xi^{-}} - y^{MC}", kTH1D, {axisPull}); + registry.add("hXiBachelorZDelta", "z^{#pi^{-} from #Xi^{-}} - z^{MC}", kTH1D, {axisPull}); + + registry.add("hXiXDelta", "x^{#Xi^{-}} - x^{MC}", kTH1D, {axisPull}); + registry.add("hXiYDelta", "y^{#Xi^{-}} - y^{MC}", kTH1D, {axisPull}); + registry.add("hXiZDelta", "z^{#Xi^{-}} - z^{MC}", kTH1D, {axisPull}); + + registry.add("hXic0BachelorXDelta", "x^{#pi^{+} from #Xi_{c}^{0}} - x^{MC}", kTH1D, {axisPull}); + registry.add("hXic0BachelorYDelta", "y^{#pi^{+} from #Xi_{c}^{0}} - y^{MC}", kTH1D, {axisPull}); + registry.add("hXic0BachelorZDelta", "z^{#pi^{+} from #Xi_{c}^{0}} - z^{MC}", kTH1D, {axisPull}); + + registry.add("hXic0XDelta", "x^{#Xi_(c)^(0)} - x^{MC}", kTH1D, {axisPull}); + registry.add("hXic0YDelta", "y^{#Xi_(c)^(0)} - y^{MC}", kTH1D, {axisPull}); + registry.add("hXic0ZDelta", "z^{#Xi_(c)^(0)} - z^{MC}", kTH1D, {axisPull}); + // delta over pt + registry.add("hV0DauPosXDeltaVsPt", "#Delta_{x}(p) vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); + registry.add("hV0DauPosYDeltaVsPt", "#Delta_{y}(p) vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); + registry.add("hV0DauPosZDeltaVsPt", "#Delta_{z}(p) vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); + registry.add("hV0DauNegXDeltaVsPt", "#Delta_{x}(#pi) vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); + registry.add("hV0DauNegYDeltaVsPt", "#Delta_{y}(#pi) vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); + registry.add("hV0DauNegZDeltaVsPt", "#Delta_{z}(#pi) vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); + registry.add("hV0XDeltaVsPt", "#Delta_{x}(#Lambda) vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); + registry.add("hV0YDeltaVsPt", "#Delta_{y}(#Lambda) vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); + registry.add("hV0ZDeltaVsPt", "#Delta_{z}(#Lambda) vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); + + registry.add("hXiBachelorXDeltaVsPt", "#Delta_{x}(#pi^{-} from #Xi^{-}) vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); + registry.add("hXiBachelorYDeltaVsPt", "#Delta_{y}(#pi^{-} from #Xi^{-}) vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); + registry.add("hXiBachelorZDeltaVsPt", "#Delta_{z}(#pi^{-} from #Xi^{-}) vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); + + registry.add("hXiXDeltaVsPt", "#Delta_{x}(#Xi^{-}) vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); + registry.add("hXiYDeltaVsPt", "#Delta_{y}(#Xi^{-}) vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); + registry.add("hXiZDeltaVsPt", "#Delta_{z}(#Xi^{-}) vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); + + registry.add("hXic0BachelorXDeltaVsPt", "#Delta_{x}(#pi^{+} from #Xi_{c}^{0}) vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); + registry.add("hXic0BachelorYDeltaVsPt", "#Delta_{y}(#pi^{+} from #Xi_{c}^{0}) vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); + registry.add("hXic0BachelorZDeltaVsPt", "#Delta_{z}(#pi^{+} from #Xi_{c}^{0}) vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); + + registry.add("hXic0XDeltaVsPt", "#Delta_{x}(#Xi_{c}^{0}) vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); + registry.add("hXic0YDeltaVsPt", "#Delta_{y}(#Xi_{c}^{0}) vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); + registry.add("hXic0ZDeltaVsPt", "#Delta_{z}(#Xi_{c}^{0}) vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); + + // pull + registry.add("hV0DauPosXPull", "x^{PULL}", kTH1D, {axisPull}); + registry.add("hV0DauPosYPull", "y^{PULL}", kTH1D, {axisPull}); + registry.add("hV0DauPosZPull", "z^{PULL}", kTH1D, {axisPull}); + registry.add("hV0DauNegXPull", "x^{PULL}", kTH1D, {axisPull}); + registry.add("hV0DauNegYPull", "y^{PULL}", kTH1D, {axisPull}); + registry.add("hV0DauNegZPull", "z^{PULL}", kTH1D, {axisPull}); + registry.add("hV0XPull", "x^{PULL}(#Lambda)", kTH1D, {axisPull}); + registry.add("hV0YPull", "y^{PULL}(#Lambda)", kTH1D, {axisPull}); + registry.add("hV0ZPull", "z^{PULL}(#Lambda)", kTH1D, {axisPull}); + + registry.add("hXiBachelorXPull", "x^{PULL}", kTH1D, {axisPull}); + registry.add("hXiBachelorYPull", "y^{PULL}", kTH1D, {axisPull}); + registry.add("hXiBachelorZPull", "z^{PULL}", kTH1D, {axisPull}); + + registry.add("hXiXPull", "x^{PULL}(#Xi^{-})", kTH1D, {axisPull}); + registry.add("hXiYPull", "y^{PULL}(#Xi^{-})", kTH1D, {axisPull}); + registry.add("hXiZPull", "z^{PULL}(#Xi^{-})", kTH1D, {axisPull}); + + registry.add("hXic0BachelorXPull", "x^{PULL}", kTH1D, {axisPull}); + registry.add("hXic0BachelorYPull", "y^{PULL}", kTH1D, {axisPull}); + registry.add("hXic0BachelorZPull", "z^{PULL}", kTH1D, {axisPull}); + + registry.add("hXic0XPull", "x^{PULL}(#Xi_{c}^{0})", kTH1D, {axisPull}); + registry.add("hXic0YPull", "y^{PULL}(#Xi_{c}^{0})", kTH1D, {axisPull}); + registry.add("hXic0ZPull", "z^{PULL}(#Xi_{c}^{0})", kTH1D, {axisPull}); + // pull over pt + registry.add("hV0DauPosXPullVsPt", "x_{PULL} vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); + registry.add("hV0DauPosYPullVsPt", "y_{PULL} vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); + registry.add("hV0DauPosZPullVsPt", "z_{PULL} vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); + registry.add("hV0DauNegXPullVsPt", "x_{PULL} vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); + registry.add("hV0DauNegYPullVsPt", "y_{PULL} vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); + registry.add("hV0DauNegZPullVsPt", "z_{PULL} vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); + registry.add("hV0XPullVsPt", "x_{PULL}(#Lambda) vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); + registry.add("hV0YPullVsPt", "y_{PULL}(#Lambda) vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); + registry.add("hV0ZPullVsPt", "z_{PULL}(#Lambda) vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); + + registry.add("hXiBachelorXPullVsPt", "x_{PULL} vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); + registry.add("hXiBachelorYPullVsPt", "y_{PULL} vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); + registry.add("hXiBachelorZPullVsPt", "z_{PULL} vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); + + registry.add("hXiXPullVsPt", "x_{PULL}(#Xi^{-}) vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); + registry.add("hXiYPullVsPt", "y_{PULL}(#Xi^{-}) vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); + registry.add("hXiZPullVsPt", "z_{PULL}(#Xi^{-}) vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); + + registry.add("hXic0BachelorXPullVsPt", "x_{PULL} vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); + registry.add("hXic0BachelorYPullVsPt", "y_{PULL} vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); + registry.add("hXic0BachelorZPullVsPt", "z_{PULL} vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); + + registry.add("hXic0XPullVsPt", "x_{PULL}(#Xi_{c}^{0}) vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); + registry.add("hXic0YPullVsPt", "y_{PULL}(#Xi_{c}^{0}) vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); + registry.add("hXic0ZPullVsPt", "z_{PULL}(#Xi_{c}^{0}) vs. p_{T}", HistType::kTH2D, {axisPt, axisPull}); + + // Defaut delta + registry.add("hLambdaXDelta", "x^{#Lambda} - x^{MC}(Default)", kTH1D, {axisPull}); + registry.add("hLambdaYDelta", "y^{#Lambda} - y^{MC}(Default)", kTH1D, {axisPull}); + registry.add("hLambdaZDelta", "z^{#Lambda} - z^{MC}(Default)", kTH1D, {axisPull}); + + registry.add("hCascXDelta", "x^{#Xi^{-}} - x^{MC}(Default)", kTH1D, {axisPull}); + registry.add("hCascYDelta", "y^{#Xi^{-}} - y^{MC}(Default)", kTH1D, {axisPull}); + registry.add("hCascZDelta", "z^{#Xi^{-}} - z^{MC}(Default)", kTH1D, {axisPull}); + + // Pt Resolution + registry.add("hV0DauPosPtRes", "Pt Resolution (p)", kTH1D, {axisPull}); + registry.add("hV0DauNegPtRes", "Pt Resolution (#pi^{-} from #Lambda)", kTH1D, {axisPull}); + registry.add("hV0PtRes", "Pt Resolution (V0)", kTH1D, {axisPull}); + registry.add("hXiBachelorPtRes", "Pt Resolution (#pi^{-} from #Xi^{-})", kTH1D, {axisPull}); + registry.add("hXiPtRes", "Pt Resolution (#Xi^{-})", kTH1D, {axisPull}); + registry.add("hXic0BachelorPtRes", "Pt Resolution (#pi^{+} from #Xi_{c}^{0})", kTH1D, {axisPull}); + registry.add("hXic0PtRes", "Pt Resolution (#Xi_{c}^{0})", kTH1D, {axisPull}); + } } template @@ -2386,6 +2538,236 @@ struct HfCandidateCreatorXic0Omegac0Mc { } // close loop on MCCollisions } // close process + template + void runXic0Omegac0McQa(TMyRecoCand const& candidates, + MyTracksWMc const&, + aod::McParticles const& mcParticles, + BCsInfo const&) + { + int indexRec = -1; + int8_t sign = -9; + int8_t signCasc = -9; + int8_t signV0 = -9; + + for (const auto& candidate : candidates) { + + auto arrayDaughters = std::array{candidate.template bachelorFromCharmBaryon_as(), // bachelor <- charm baryon + candidate.template bachelor_as(), // bachelor <- cascade + candidate.template posTrack_as(), // p <- lambda + candidate.template negTrack_as()}; // pi <- lambda + auto arrayDaughtersCasc = std::array{candidate.template bachelor_as(), + candidate.template posTrack_as(), + candidate.template negTrack_as()}; + auto arrayDaughtersV0 = std::array{candidate.template posTrack_as(), + candidate.template negTrack_as()}; + + auto mcV0DauPos = arrayDaughtersV0[0].mcParticle(); + auto mcV0DauNeg = arrayDaughtersV0[1].mcParticle(); + auto mcXiBachelor = arrayDaughtersCasc[0].mcParticle(); + auto mcXic0Bachelor = arrayDaughters[0].mcParticle(); + + // Xic0 -> xi pi matching + if constexpr (decayChannel == aod::hf_cand_xic0_omegac0::DecayType::XiczeroToXiPi) { + // Lambda → p pi + indexRec = RecoDecay::getMatchedMCRec(mcParticles, arrayDaughtersV0, +kLambda0, std::array{+kProton, +kPiMinus}, true, &signV0, 1); + if (indexRec > -1 && signV0 == 1) { + auto mcV0 = mcParticles.rawIteratorAt(indexRec - mcParticles.offset()); + + float v0MassPull = (candidate.invMassLambda() - MassLambda0) / candidate.invMassV0Err(); + registry.fill(HIST("hV0MassPullVsPt"), candidate.v0Pt(), v0MassPull); + + float v0DauPosXDelta = candidate.v0DauPosX() - mcV0DauPos.vx(); + float v0DauPosYDelta = candidate.v0DauPosY() - mcV0DauPos.vy(); + float v0DauPosZDelta = candidate.v0DauPosZ() - mcV0DauPos.vz(); + float v0DauPosPt = mcV0DauPos.pt(); + float v0DauPosXPull = v0DauPosXDelta / candidate.v0DauPosXError(); + float v0DauPosYPull = v0DauPosYDelta / candidate.v0DauPosYError(); + float v0DauPosZPull = v0DauPosZDelta / candidate.v0DauPosZError(); + + float v0DauNegXDelta = candidate.v0DauNegX() - mcV0DauNeg.vx(); + float v0DauNegYDelta = candidate.v0DauNegY() - mcV0DauNeg.vy(); + float v0DauNegZDelta = candidate.v0DauNegZ() - mcV0DauNeg.vz(); + float v0DauNegPt = mcV0DauNeg.pt(); + float v0DauNegXPull = v0DauNegXDelta / candidate.v0DauNegXError(); + float v0DauNegYPull = v0DauNegYDelta / candidate.v0DauNegYError(); + float v0DauNegZPull = v0DauNegZDelta / candidate.v0DauNegZError(); + + float v0XDelta = candidate.v0VtxX() - mcV0DauNeg.vx(); + float v0YDelta = candidate.v0VtxY() - mcV0DauNeg.vy(); + float v0ZDelta = candidate.v0VtxZ() - mcV0DauNeg.vz(); + float v0Pt = mcV0.pt(); + float v0XPull = v0XDelta / candidate.v0XError(); + float v0YPull = v0YDelta / candidate.v0YError(); + float v0ZPull = v0ZDelta / candidate.v0ZError(); + + float lambdaXDelta = candidate.v0X() - mcV0DauNeg.vx(); + float lambdaYDelta = candidate.v0Y() - mcV0DauNeg.vy(); + float lambdaZDelta = candidate.v0Z() - mcV0DauNeg.vz(); + registry.fill(HIST("hV0DauPosXDelta"), v0DauPosXDelta); + registry.fill(HIST("hV0DauPosYDelta"), v0DauPosYDelta); + registry.fill(HIST("hV0DauPosZDelta"), v0DauPosZDelta); + registry.fill(HIST("hV0DauPosXDeltaVsPt"), v0DauPosPt, v0DauPosXDelta); + registry.fill(HIST("hV0DauPosYDeltaVsPt"), v0DauPosPt, v0DauPosYDelta); + registry.fill(HIST("hV0DauPosZDeltaVsPt"), v0DauPosPt, v0DauPosZDelta); + registry.fill(HIST("hV0DauPosXPull"), v0DauPosXPull); + registry.fill(HIST("hV0DauPosYPull"), v0DauPosYPull); + registry.fill(HIST("hV0DauPosZPull"), v0DauPosZPull); + registry.fill(HIST("hV0DauPosXPullVsPt"), v0DauPosPt, v0DauPosXPull); + registry.fill(HIST("hV0DauPosYPullVsPt"), v0DauPosPt, v0DauPosYPull); + registry.fill(HIST("hV0DauPosZPullVsPt"), v0DauPosPt, v0DauPosZPull); + + registry.fill(HIST("hV0DauNegXDelta"), v0DauNegXDelta); + registry.fill(HIST("hV0DauNegYDelta"), v0DauNegYDelta); + registry.fill(HIST("hV0DauNegZDelta"), v0DauNegZDelta); + registry.fill(HIST("hV0DauNegXDeltaVsPt"), v0DauNegPt, v0DauNegXDelta); + registry.fill(HIST("hV0DauNegYDeltaVsPt"), v0DauNegPt, v0DauNegYDelta); + registry.fill(HIST("hV0DauNegZDeltaVsPt"), v0DauNegPt, v0DauNegZDelta); + registry.fill(HIST("hV0DauNegXPull"), v0DauNegXPull); + registry.fill(HIST("hV0DauNegYPull"), v0DauNegYPull); + registry.fill(HIST("hV0DauNegZPull"), v0DauNegZPull); + registry.fill(HIST("hV0DauNegXPullVsPt"), v0DauNegPt, v0DauNegXPull); + registry.fill(HIST("hV0DauNegYPullVsPt"), v0DauNegPt, v0DauNegYPull); + registry.fill(HIST("hV0DauNegZPullVsPt"), v0DauNegPt, v0DauNegZPull); + + registry.fill(HIST("hV0XDelta"), v0XDelta); + registry.fill(HIST("hV0YDelta"), v0YDelta); + registry.fill(HIST("hV0ZDelta"), v0ZDelta); + registry.fill(HIST("hV0XDeltaVsPt"), v0Pt, v0XDelta); + registry.fill(HIST("hV0YDeltaVsPt"), v0Pt, v0YDelta); + registry.fill(HIST("hV0ZDeltaVsPt"), v0Pt, v0ZDelta); + registry.fill(HIST("hV0XPull"), v0XPull); + registry.fill(HIST("hV0YPull"), v0YPull); + registry.fill(HIST("hV0ZPull"), v0ZPull); + registry.fill(HIST("hV0XPullVsPt"), v0Pt, v0XPull); + registry.fill(HIST("hV0YPullVsPt"), v0Pt, v0YPull); + registry.fill(HIST("hV0ZPullVsPt"), v0Pt, v0ZPull); + + registry.fill(HIST("hLambdaXDelta"), lambdaXDelta); + registry.fill(HIST("hLambdaYDelta"), lambdaYDelta); + registry.fill(HIST("hLambdaZDelta"), lambdaZDelta); + + registry.fill(HIST("hV0DauPosPtRes"), (candidate.v0DauPosPt() - mcV0DauPos.pt()) / candidate.v0DauPosPt()); + registry.fill(HIST("hV0DauNegPtRes"), (candidate.v0DauNegPt() - mcV0DauNeg.pt()) / candidate.v0DauNegPt()); + registry.fill(HIST("hV0PtRes"), (candidate.v0Pt() - mcV0.pt()) / candidate.v0Pt()); + // Xi- → pi pi p + indexRec = RecoDecay::getMatchedMCRec(mcParticles, arrayDaughtersCasc, +kXiMinus, std::array{+kPiMinus, +kProton, +kPiMinus}, true, &signCasc, 2); + if (indexRec > -1 && signCasc == 1) { + // QA + float xiMassPull = (candidate.invMassCascade() - MassXiMinus) / candidate.invMassXiErr(); + registry.fill(HIST("hXiMassPullVsPt"), candidate.xiPt(), xiMassPull); + + float xiBachelorXDelta = candidate.xiBachelorX() - mcXiBachelor.vx(); + float xiBachelorYDelta = candidate.xiBachelorY() - mcXiBachelor.vy(); + float xiBachelorZDelta = candidate.xiBachelorZ() - mcXiBachelor.vz(); + float xiBachelorPt = mcXiBachelor.pt(); + float xiBachelorXPull = xiBachelorXDelta / candidate.xiBachelorXError(); + float xiBachelorYPull = xiBachelorYDelta / candidate.xiBachelorYError(); + float xiBachelorZPull = xiBachelorZDelta / candidate.xiBachelorZError(); + + auto mcXi = mcParticles.rawIteratorAt(indexRec - mcParticles.offset()); + + float xiXDelta = candidate.xiX() - mcXiBachelor.vx(); + float xiYDelta = candidate.xiY() - mcXiBachelor.vy(); + float xiZDelta = candidate.xiZ() - mcXiBachelor.vz(); + float xiPt = mcXi.pt(); + float xiXPull = xiXDelta / candidate.xiXError(); + float xiYPull = xiYDelta / candidate.xiYError(); + float xiZPull = xiZDelta / candidate.xiZError(); + + float cascXDelta = candidate.xDecayVtxCascade() - mcXiBachelor.vx(); + float cascYDelta = candidate.yDecayVtxCascade() - mcXiBachelor.vy(); + float cascZDelta = candidate.zDecayVtxCascade() - mcXiBachelor.vz(); + + registry.fill(HIST("hXiBachelorXDelta"), xiBachelorXDelta); + registry.fill(HIST("hXiBachelorYDelta"), xiBachelorYDelta); + registry.fill(HIST("hXiBachelorZDelta"), xiBachelorZDelta); + registry.fill(HIST("hXiBachelorXDeltaVsPt"), xiBachelorPt, xiBachelorXDelta); + registry.fill(HIST("hXiBachelorYDeltaVsPt"), xiBachelorPt, xiBachelorYDelta); + registry.fill(HIST("hXiBachelorZDeltaVsPt"), xiBachelorPt, xiBachelorZDelta); + registry.fill(HIST("hXiBachelorXPull"), xiBachelorXPull); + registry.fill(HIST("hXiBachelorYPull"), xiBachelorYPull); + registry.fill(HIST("hXiBachelorZPull"), xiBachelorZPull); + registry.fill(HIST("hXiBachelorXPullVsPt"), xiBachelorPt, xiBachelorXPull); + registry.fill(HIST("hXiBachelorYPullVsPt"), xiBachelorPt, xiBachelorYPull); + registry.fill(HIST("hXiBachelorZPullVsPt"), xiBachelorPt, xiBachelorZPull); + + registry.fill(HIST("hXiXDelta"), xiXDelta); + registry.fill(HIST("hXiYDelta"), xiYDelta); + registry.fill(HIST("hXiZDelta"), xiZDelta); + registry.fill(HIST("hXiXDeltaVsPt"), xiPt, xiXDelta); + registry.fill(HIST("hXiYDeltaVsPt"), xiPt, xiYDelta); + registry.fill(HIST("hXiZDeltaVsPt"), xiPt, xiZDelta); + registry.fill(HIST("hXiXPull"), xiXPull); + registry.fill(HIST("hXiYPull"), xiYPull); + registry.fill(HIST("hXiZPull"), xiZPull); + registry.fill(HIST("hXiXPullVsPt"), xiPt, xiXPull); + registry.fill(HIST("hXiYPullVsPt"), xiPt, xiYPull); + registry.fill(HIST("hXiZPullVsPt"), xiPt, xiZPull); + + registry.fill(HIST("hCascXDelta"), cascXDelta); + registry.fill(HIST("hCascYDelta"), cascYDelta); + registry.fill(HIST("hCascZDelta"), cascZDelta); + + registry.fill(HIST("hXiBachelorPtRes"), (candidate.xiBachelorPt() - mcXiBachelor.pt()) / candidate.xiBachelorPt()); + registry.fill(HIST("hXiPtRes"), (candidate.xiPt() - mcXi.pt()) / candidate.xiPt()); + + // Xic → pi pi pi p + indexRec = RecoDecay::getMatchedMCRec(mcParticles, arrayDaughters, +kXiC0, std::array{+kPiPlus, +kPiMinus, +kProton, +kPiMinus}, true, &sign, 3); + if (indexRec > -1 && sign == 1) { + auto mcXic0 = mcParticles.rawIteratorAt(indexRec - mcParticles.offset()); + float xic0MassPull = (candidate.invMassCharmBaryon() - MassXiC0) / candidate.invMassXic0Err(); + registry.fill(HIST("hXic0MassPullVsPt"), candidate.xic0Pt(), xic0MassPull); + + float xic0BachelorXDelta = candidate.xic0BachelorX() - mcXic0Bachelor.vx(); + float xic0BachelorYDelta = candidate.xic0BachelorY() - mcXic0Bachelor.vy(); + float xic0BachelorZDelta = candidate.xic0BachelorZ() - mcXic0Bachelor.vz(); + float xic0BachelorPt = mcXic0Bachelor.pt(); + float xic0BachelorXPull = xic0BachelorXDelta / candidate.xic0BachelorXError(); + float xic0BachelorYPull = xic0BachelorYDelta / candidate.xic0BachelorYError(); + float xic0BachelorZPull = xic0BachelorZDelta / candidate.xic0BachelorZError(); + + float xic0XDelta = candidate.xDecayVtxCharmBaryon() - mcXic0Bachelor.vx(); + float xic0YDelta = candidate.yDecayVtxCharmBaryon() - mcXic0Bachelor.vy(); + float xic0ZDelta = candidate.zDecayVtxCharmBaryon() - mcXic0Bachelor.vz(); + float xic0Pt = mcXic0.pt(); + float xic0XPull = xic0XDelta / candidate.xic0XError(); + float xic0YPull = xic0YDelta / candidate.xic0YError(); + float xic0ZPull = xic0ZDelta / candidate.xic0ZError(); + registry.fill(HIST("hXic0BachelorXDelta"), xic0BachelorXDelta); + registry.fill(HIST("hXic0BachelorYDelta"), xic0BachelorYDelta); + registry.fill(HIST("hXic0BachelorZDelta"), xic0BachelorZDelta); + registry.fill(HIST("hXic0BachelorXDeltaVsPt"), xic0BachelorPt, xic0BachelorXDelta); + registry.fill(HIST("hXic0BachelorYDeltaVsPt"), xic0BachelorPt, xic0BachelorYDelta); + registry.fill(HIST("hXic0BachelorZDeltaVsPt"), xic0BachelorPt, xic0BachelorZDelta); + registry.fill(HIST("hXic0BachelorXPull"), xic0BachelorXPull); + registry.fill(HIST("hXic0BachelorYPull"), xic0BachelorYPull); + registry.fill(HIST("hXic0BachelorZPull"), xic0BachelorZPull); + registry.fill(HIST("hXic0BachelorXPullVsPt"), xic0BachelorPt, xic0BachelorXPull); + registry.fill(HIST("hXic0BachelorYPullVsPt"), xic0BachelorPt, xic0BachelorYPull); + registry.fill(HIST("hXic0BachelorZPullVsPt"), xic0BachelorPt, xic0BachelorZPull); + + registry.fill(HIST("hXic0XDelta"), xic0XDelta); + registry.fill(HIST("hXic0YDelta"), xic0YDelta); + registry.fill(HIST("hXic0ZDelta"), xic0ZDelta); + registry.fill(HIST("hXic0XDeltaVsPt"), xic0Pt, xic0XDelta); + registry.fill(HIST("hXic0YDeltaVsPt"), xic0Pt, xic0YDelta); + registry.fill(HIST("hXic0ZDeltaVsPt"), xic0Pt, xic0ZDelta); + registry.fill(HIST("hXic0XPull"), xic0XPull); + registry.fill(HIST("hXic0YPull"), xic0YPull); + registry.fill(HIST("hXic0ZPull"), xic0ZPull); + registry.fill(HIST("hXic0XPullVsPt"), xic0Pt, xic0XPull); + registry.fill(HIST("hXic0YPullVsPt"), xic0Pt, xic0YPull); + registry.fill(HIST("hXic0ZPullVsPt"), xic0Pt, xic0ZPull); + + registry.fill(HIST("hXic0BachelorPtRes"), (candidate.xic0BachelorPt() - mcXic0Bachelor.pt()) / candidate.xic0BachelorPt()); + registry.fill(HIST("hXic0PtRes"), (candidate.xic0Pt() - mcXic0.pt()) / candidate.xic0Pt()); + } + } + } + } + } + } + void processDoNoMc(aod::Collisions::iterator const&) { // dummy process function - should not be required in the future @@ -2414,6 +2796,15 @@ struct HfCandidateCreatorXic0Omegac0Mc { } PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Mc, processMcXicToXiPiKf, "Run Xic0 to xi pi MC process function - no centrality", false); + void processMcXicToXiPiKfQa(aod::HfCandToXiPiKfQa const& candidates, + MyTracksWMc const& tracks, + aod::McParticles const& mcParticles, + BCsInfo const& bcs) + { + runXic0Omegac0McQa(candidates, tracks, mcParticles, bcs); + } + PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0Mc, processMcXicToXiPiKfQa, "Run Xic0 to xi pi MC QA process function - no centrality", false); + void processMcXicToXiPiFT0m(aod::HfCandToXiPi const& candidates, MyTracksWMc const& tracks, aod::McParticles const& mcParticles, diff --git a/PWGHF/TableProducer/candidateCreatorXicToXiPiPi.cxx b/PWGHF/TableProducer/candidateCreatorXicToXiPiPi.cxx index 22b43f88061..52d8686efdd 100644 --- a/PWGHF/TableProducer/candidateCreatorXicToXiPiPi.cxx +++ b/PWGHF/TableProducer/candidateCreatorXicToXiPiPi.cxx @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -39,6 +40,7 @@ #include "Framework/HistogramRegistry.h" #include "Framework/runDataProcessing.h" #include "ReconstructionDataFormats/DCA.h" +#include "Framework/RunningWorkflowInfo.h" #include "Common/Core/trackUtilities.h" #include "Common/DataModel/CollisionAssociationTables.h" @@ -48,12 +50,16 @@ #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/Utils/utilsBfieldCCDB.h" +#include "PWGHF/Utils/utilsEvSelHf.h" using namespace o2; using namespace o2::analysis; -using namespace o2::aod::hf_cand_xic_to_xi_pi_pi; using namespace o2::constants::physics; using namespace o2::framework; +using namespace o2::hf_evsel; +using namespace o2::hf_centrality; +using namespace o2::hf_occupancy; +using namespace o2::aod::hf_cand_xic_to_xi_pi_pi; /// Reconstruction of heavy-flavour 3-prong decay candidates struct HfCandidateCreatorXicToXiPiPi { @@ -92,12 +98,15 @@ struct HfCandidateCreatorXicToXiPiPi { o2::vertexing::DCAFitterN<3> df; + HfEventSelection hfEvSel; + int runNumber{0}; float massXiPiPi{0.}; float massXiPi0{0.}; float massXiPi1{0.}; double bz{0.}; - enum XicCandCounter { AllIdTriplets = 0, + enum XicCandCounter { TotalSkimmedTriplets = 0, + SelEvent, CascPreSel, VertexFit }; @@ -112,16 +121,17 @@ struct HfCandidateCreatorXicToXiPiPi { void init(InitContext const&) { - if ((doprocessXicplusWithDcaFitter + doprocessXicplusWithKFParticle) != 1) { - LOGP(fatal, "Only one process function can be enabled at a time."); + if ((doprocessNoCentXicplusWithDcaFitter + doprocessCentFT0CXicplusWithDcaFitter + doprocessCentFT0MXicplusWithDcaFitter + doprocessNoCentXicplusWithKFParticle + doprocessCentFT0CXicplusWithKFParticle + doprocessCentFT0MXicplusWithKFParticle) != 1) { + LOGP(fatal, "Only one process function for the Xic reconstruction can be enabled at a time."); } // add histograms to registry if (fillHistograms) { // counter registry.add("hVertexerType", "Use KF or DCAFitterN;Vertexer type;entries", {HistType::kTH1F, {{2, -0.5, 1.5}}}); // See o2::aod::hf_cand::VertexerType - registry.add("hCandCounter", "hCandCounter", {HistType::kTH1F, {{3, 0.5, 3.5}}}); - registry.get(HIST("hCandCounter"))->GetXaxis()->SetBinLabel(1 + AllIdTriplets, "total"); + registry.add("hCandCounter", "hCandCounter", {HistType::kTH1F, {{4, -0.5, 3.5}}}); + registry.get(HIST("hCandCounter"))->GetXaxis()->SetBinLabel(1 + TotalSkimmedTriplets, "total"); + registry.get(HIST("hCandCounter"))->GetXaxis()->SetBinLabel(1 + SelEvent, "Event selected"); registry.get(HIST("hCandCounter"))->GetXaxis()->SetBinLabel(1 + CascPreSel, "Cascade preselection"); registry.get(HIST("hCandCounter"))->GetXaxis()->SetBinLabel(1 + VertexFit, "Successful vertex fit"); // physical variables @@ -139,10 +149,10 @@ struct HfCandidateCreatorXicToXiPiPi { } // fill hVertexerType histogram - if (doprocessXicplusWithDcaFitter && fillHistograms) { + if ((doprocessNoCentXicplusWithDcaFitter || doprocessCentFT0CXicplusWithDcaFitter || doprocessCentFT0MXicplusWithDcaFitter) && fillHistograms) { registry.fill(HIST("hVertexerType"), aod::hf_cand::VertexerType::DCAFitter); } - if (doprocessXicplusWithKFParticle && fillHistograms) { + if ((doprocessNoCentXicplusWithKFParticle || doprocessCentFT0CXicplusWithKFParticle || doprocessCentFT0MXicplusWithKFParticle) && fillHistograms) { registry.fill(HIST("hVertexerType"), aod::hf_cand::VertexerType::KfParticle); } @@ -153,6 +163,9 @@ struct HfCandidateCreatorXicToXiPiPi { lut = o2::base::MatLayerCylSet::rectifyPtrFromFile(ccdb->get(ccdbPathLut)); runNumber = 0; + // initialize HF event selection helper + hfEvSel.init(registry); + // initialize 3-prong vertex fitter df.setPropagateToPCA(propagateToPCA); df.setMaxR(maxR); @@ -163,15 +176,33 @@ struct HfCandidateCreatorXicToXiPiPi { df.setWeightedFinalPCA(useWeightedFinalPCA); } - void processXicplusWithDcaFitter(aod::Collisions const&, - aod::HfCascLf3Prongs const& rowsTrackIndexXicPlus, - CascadesLinked const&, - CascFull const&, - TracksWCovDcaPidPrPi const&, - aod::BCsWithTimestamps const&) + template + void runXicplusCreatorWithDcaFitter(Collision const&, + aod::HfCascLf3Prongs const& rowsTrackIndexXicPlus, + CascadesLinked const&, + CascFull const&, + TracksWCovDcaPidPrPi const&, + aod::BCsWithTimestamps const&) { // loop over triplets of track indices for (const auto& rowTrackIndexXicPlus : rowsTrackIndexXicPlus) { + if (fillHistograms) { + registry.fill(HIST("hCandCounter"), TotalSkimmedTriplets); + } + + // check if the event is selected + auto collision = rowTrackIndexXicPlus.collision_as(); + float centrality{-1.f}; + const auto rejectionMask = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + if (rejectionMask != 0) { + /// at least one event selection not satisfied --> reject the candidate + continue; + } + if (fillHistograms) { + registry.fill(HIST("hCandCounter"), SelEvent); + } + + // Retrieve skimmed cascade and pion tracks auto cascAodElement = rowTrackIndexXicPlus.cascade_as(); if (!cascAodElement.has_cascData()) { continue; @@ -179,10 +210,6 @@ struct HfCandidateCreatorXicToXiPiPi { auto casc = cascAodElement.cascData_as(); auto trackCharmBachelor0 = rowTrackIndexXicPlus.prong0_as(); auto trackCharmBachelor1 = rowTrackIndexXicPlus.prong1_as(); - auto collision = rowTrackIndexXicPlus.collision(); - if (fillHistograms) { - registry.fill(HIST("hCandCounter"), 1 + AllIdTriplets); - } // preselect cascade candidates if (doCascadePreselection) { @@ -194,13 +221,13 @@ struct HfCandidateCreatorXicToXiPiPi { } } if (fillHistograms) { - registry.fill(HIST("hCandCounter"), 1 + CascPreSel); + registry.fill(HIST("hCandCounter"), CascPreSel); } //----------------------Set the magnetic field from ccdb--------------------------------------- /// The static instance of the propagator was already modified in the HFTrackIndexSkimCreator, /// but this is not true when running on Run2 data/MC already converted into AO2Ds. - auto bc = collision.bc_as(); + auto bc = collision.template bc_as(); if (runNumber != bc.runNumber()) { LOG(info) << ">>>>>>>>>>>> Current run number: " << runNumber; initCCDB(bc, runNumber, ccdb, isRun2 ? ccdbPathGrp : ccdbPathGrpMag, lut, isRun2); @@ -217,10 +244,11 @@ struct HfCandidateCreatorXicToXiPiPi { std::array covCasc = {0.}; //----------------create cascade track------------------------------------------------------------ - constexpr int MomInd[6] = {9, 13, 14, 18, 19, 20}; // cov matrix elements for momentum component - for (int i = 0; i < 6; i++) { - covCasc[MomInd[i]] = casc.momentumCovMat()[i]; + constexpr std::size_t NElementsCovMatrix{6u}; + constexpr std::array MomInd = {9, 13, 14, 18, 19, 20}; // cov matrix elements for momentum component + for (auto i = 0u; i < NElementsCovMatrix; i++) { covCasc[i] = casc.positionCovMat()[i]; + covCasc[MomInd[i]] = casc.momentumCovMat()[i]; } // create cascade track o2::track::TrackParCov trackCasc; @@ -248,7 +276,7 @@ struct HfCandidateCreatorXicToXiPiPi { continue; } if (fillHistograms) { - registry.fill(HIST("hCandCounter"), 1 + VertexFit); + registry.fill(HIST("hCandCounter"), VertexFit); } //----------------------------calculate physical properties----------------------- @@ -388,17 +416,34 @@ struct HfCandidateCreatorXicToXiPiPi { nSigTofPiFromXicPlus0, nSigTofPiFromXicPlus1, nSigTofBachelorPi, nSigTofPiFromLambda, nSigTofPrFromLambda); } // loop over track triplets } - PROCESS_SWITCH(HfCandidateCreatorXicToXiPiPi, processXicplusWithDcaFitter, "Run candidate creator with DCAFitter.", true); - - void processXicplusWithKFParticle(aod::Collisions const&, - aod::HfCascLf3Prongs const& rowsTrackIndexXicPlus, - KFCascadesLinked const&, - KFCascFull const&, - TracksWCovExtraPidPrPi const&, - aod::BCsWithTimestamps const&) + + template + void runXicplusCreatorWithKFParticle(Collision const&, + aod::HfCascLf3Prongs const& rowsTrackIndexXicPlus, + KFCascadesLinked const&, + KFCascFull const&, + TracksWCovExtraPidPrPi const&, + aod::BCsWithTimestamps const&) { // loop over triplets of track indices for (const auto& rowTrackIndexXicPlus : rowsTrackIndexXicPlus) { + if (fillHistograms) { + registry.fill(HIST("hCandCounter"), TotalSkimmedTriplets); + } + + // check if the event is selected + auto collision = rowTrackIndexXicPlus.collision_as(); + float centrality{-1.f}; + const auto rejectionMask = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + if (rejectionMask != 0) { + /// at least one event selection not satisfied --> reject the candidate + continue; + } + if (fillHistograms) { + registry.fill(HIST("hCandCounter"), SelEvent); + } + + // Retrieve skimmed cascade and pion tracks auto cascAodElement = rowTrackIndexXicPlus.cascade_as(); if (!cascAodElement.has_kfCascData()) { continue; @@ -406,10 +451,6 @@ struct HfCandidateCreatorXicToXiPiPi { auto casc = cascAodElement.kfCascData_as(); auto trackCharmBachelor0 = rowTrackIndexXicPlus.prong0_as(); auto trackCharmBachelor1 = rowTrackIndexXicPlus.prong1_as(); - auto collision = rowTrackIndexXicPlus.collision(); - if (fillHistograms) { - registry.fill(HIST("hCandCounter"), 1 + AllIdTriplets); - } //-------------------preselect cascade candidates-------------------------------------- if (doCascadePreselection) { @@ -421,13 +462,13 @@ struct HfCandidateCreatorXicToXiPiPi { } } if (fillHistograms) { - registry.fill(HIST("hCandCounter"), 1 + CascPreSel); + registry.fill(HIST("hCandCounter"), CascPreSel); } //----------------------Set the magnetic field from ccdb----------------------------- /// The static instance of the propagator was already modified in the HFTrackIndexSkimCreator, /// but this is not true when running on Run2 data/MC already converted into AO2Ds. - auto bc = collision.bc_as(); + auto bc = collision.template bc_as(); if (runNumber != bc.runNumber()) { LOG(info) << ">>>>>>>>>>>> Current run number: " << runNumber; initCCDB(bc, runNumber, ccdb, isRun2 ? ccdbPathGrp : ccdbPathGrpMag, lut, isRun2); @@ -457,11 +498,10 @@ struct HfCandidateCreatorXicToXiPiPi { // create Xi as KFParticle object // read {X,Y,Z,Px,Py,Pz} and corresponding covariance matrix from KF cascade Tables - std::array xyzpxpypz = {casc.x(), casc.y(), casc.z(), casc.px(), casc.py(), casc.pz()}; - float parPosMom[6]; - for (int i{0}; i < 6; ++i) { - parPosMom[i] = xyzpxpypz[i]; - } + constexpr std::size_t NElementsStateVector{6}; + std::array xyzpxpypz = {casc.x(), casc.y(), casc.z(), casc.px(), casc.py(), casc.pz()}; + float parPosMom[NElementsStateVector]; + std::copy(xyzpxpypz.begin(), xyzpxpypz.end(), parPosMom); // create KFParticle KFParticle kfXi; float massXi = casc.mXi(); @@ -481,7 +521,7 @@ struct HfCandidateCreatorXicToXiPiPi { continue; } if (fillHistograms) { - registry.fill(HIST("hCandCounter"), 1 + VertexFit); + registry.fill(HIST("hCandCounter"), VertexFit); } // get geometrical chi2 of XicPlus @@ -675,7 +715,141 @@ struct HfCandidateCreatorXicToXiPiPi { dcaPi0Pi1, dcaPi0Xi, dcaPi1Xi); } // loop over track triplets } - PROCESS_SWITCH(HfCandidateCreatorXicToXiPiPi, processXicplusWithKFParticle, "Run candidate creator with KFParticle using derived data from HfTrackIndexSkimCreatorLfCascades.", false); + + /////////////////////////////////////////////////////////// + /// /// + /// Process functions with DCAFitter /// + /// /// + /////////////////////////////////////////////////////////// + + void processNoCentXicplusWithDcaFitter(soa::Join const& collisions, + aod::HfCascLf3Prongs const& rowsTrackIndexXicPlus, + CascadesLinked const& cascadesLinked, + CascFull const& cascadesFull, + TracksWCovDcaPidPrPi const& tracks, + aod::BCsWithTimestamps const& bcs) + { + runXicplusCreatorWithDcaFitter(collisions, rowsTrackIndexXicPlus, cascadesLinked, cascadesFull, tracks, bcs); + } + PROCESS_SWITCH(HfCandidateCreatorXicToXiPiPi, processNoCentXicplusWithDcaFitter, "Run candidate creator with DCAFitter without centrality selection.", true); + + void processCentFT0CXicplusWithDcaFitter(soa::Join const& collisions, + aod::HfCascLf3Prongs const& rowsTrackIndexXicPlus, + CascadesLinked const& cascadesLinked, + CascFull const& cascadesFull, + TracksWCovDcaPidPrPi const& tracks, + aod::BCsWithTimestamps const& bcs) + { + runXicplusCreatorWithDcaFitter(collisions, rowsTrackIndexXicPlus, cascadesLinked, cascadesFull, tracks, bcs); + } + PROCESS_SWITCH(HfCandidateCreatorXicToXiPiPi, processCentFT0CXicplusWithDcaFitter, "Run candidate creator with DCAFitter with centrality selection on FT0C.", false); + + void processCentFT0MXicplusWithDcaFitter(soa::Join const& collisions, + aod::HfCascLf3Prongs const& rowsTrackIndexXicPlus, + CascadesLinked const& cascadesLinked, + CascFull const& cascadesFull, + TracksWCovDcaPidPrPi const& tracks, + aod::BCsWithTimestamps const& bcs) + { + runXicplusCreatorWithDcaFitter(collisions, rowsTrackIndexXicPlus, cascadesLinked, cascadesFull, tracks, bcs); + } + PROCESS_SWITCH(HfCandidateCreatorXicToXiPiPi, processCentFT0MXicplusWithDcaFitter, "Run candidate creator with DCAFitter with centrality selection on FT0M.", false); + + /////////////////////////////////////////////////////////// + /// /// + /// Process functions with KFParticle /// + /// /// + /////////////////////////////////////////////////////////// + + void processNoCentXicplusWithKFParticle(soa::Join const& collisions, + aod::HfCascLf3Prongs const& rowsTrackIndexXicPlus, + KFCascadesLinked const& kfCascadesLinked, + KFCascFull const& kfCascadesFull, + TracksWCovExtraPidPrPi const& tracks, + aod::BCsWithTimestamps const& bcs) + { + runXicplusCreatorWithKFParticle(collisions, rowsTrackIndexXicPlus, kfCascadesLinked, kfCascadesFull, tracks, bcs); + } + PROCESS_SWITCH(HfCandidateCreatorXicToXiPiPi, processNoCentXicplusWithKFParticle, "Run candidate creator with KFParticle without centrality selection.", false); + + void processCentFT0CXicplusWithKFParticle(soa::Join const& collisions, + aod::HfCascLf3Prongs const& rowsTrackIndexXicPlus, + KFCascadesLinked const& kfCascadesLinked, + KFCascFull const& kfCascadesFull, + TracksWCovExtraPidPrPi const& tracks, + aod::BCsWithTimestamps const& bcs) + { + runXicplusCreatorWithKFParticle(collisions, rowsTrackIndexXicPlus, kfCascadesLinked, kfCascadesFull, tracks, bcs); + } + PROCESS_SWITCH(HfCandidateCreatorXicToXiPiPi, processCentFT0CXicplusWithKFParticle, "Run candidate creator with KFParticle with centrality selection on FT0C.", false); + + void processCentFT0MXicplusWithKFParticle(soa::Join const& collisions, + aod::HfCascLf3Prongs const& rowsTrackIndexXicPlus, + KFCascadesLinked const& kfCascadesLinked, + KFCascFull const& kfCascadesFull, + TracksWCovExtraPidPrPi const& tracks, + aod::BCsWithTimestamps const& bcs) + { + runXicplusCreatorWithKFParticle(collisions, rowsTrackIndexXicPlus, kfCascadesLinked, kfCascadesFull, tracks, bcs); + } + PROCESS_SWITCH(HfCandidateCreatorXicToXiPiPi, processCentFT0MXicplusWithKFParticle, "Run candidate creator with KFParticle with centrality selection on FT0M.", false); + + /////////////////////////////////////////////////////////// + /// /// + /// Process functions only for collision monitoring /// + /// /// + /////////////////////////////////////////////////////////// + + void processCollisions(soa::Join const& collisions, aod::BCsWithTimestamps const&) + { + /// loop over collisions + for (const auto& collision : collisions) { + + /// bitmask with event. selection info + float centrality{-1.f}; + float occupancy = getOccupancyColl(collision, OccupancyEstimator::Its); + const auto rejectionMask = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + + /// monitor the satisfied event selections + hfEvSel.fillHistograms(collision, rejectionMask, centrality, occupancy); + + } /// end loop over collisions + } + PROCESS_SWITCH(HfCandidateCreatorXicToXiPiPi, processCollisions, "Collision monitoring - no centrality", false); + + void processCollisionsCentFT0C(soa::Join const& collisions, aod::BCsWithTimestamps const&) + { + /// loop over collisions + for (const auto& collision : collisions) { + + /// bitmask with event. selection info + float centrality{-1.f}; + float occupancy = getOccupancyColl(collision, OccupancyEstimator::Its); + const auto rejectionMask = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + + /// monitor the satisfied event selections + hfEvSel.fillHistograms(collision, rejectionMask, centrality, occupancy); + + } /// end loop over collisions + } + PROCESS_SWITCH(HfCandidateCreatorXicToXiPiPi, processCollisionsCentFT0C, "Collision monitoring - FT0C centrality", false); + + void processCollisionsCentFT0M(soa::Join const& collisions, aod::BCsWithTimestamps const&) + { + /// loop over collisions + for (const auto& collision : collisions) { + + /// bitmask with event. selection info + float centrality{-1.f}; + float occupancy = getOccupancyColl(collision, OccupancyEstimator::Its); + const auto rejectionMask = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + + /// monitor the satisfied event selections + hfEvSel.fillHistograms(collision, rejectionMask, centrality, occupancy); + + } /// end loop over collisions + } + PROCESS_SWITCH(HfCandidateCreatorXicToXiPiPi, processCollisionsCentFT0M, "Collision monitoring - FT0M centrality", false); }; // struct /// Performs MC matching. @@ -684,10 +858,39 @@ struct HfCandidateCreatorXicToXiPiPiExpressions { Produces rowMcMatchRec; Produces rowMcMatchGen; - void init(InitContext const&) {} + using McCollisionsNoCents = soa::Join; + using McCollisionsFT0Cs = soa::Join; + using McCollisionsFT0Ms = soa::Join; + using McCollisionsCentFT0Ms = soa::Join; + using BCsInfo = soa::Join; - void processMc(aod::TracksWMc const& tracks, - aod::McParticles const& mcParticles) + Preslice mcParticlesPerMcCollision = aod::mcparticle::mcCollisionId; + PresliceUnsorted colPerMcCollision = aod::mccollisionlabel::mcCollisionId; + PresliceUnsorted colPerMcCollisionFT0C = aod::mccollisionlabel::mcCollisionId; + PresliceUnsorted colPerMcCollisionFT0M = aod::mccollisionlabel::mcCollisionId; + + HistogramRegistry registry{"registry"}; + + HfEventSelectionMc hfEvSelMc; + + void init(InitContext& initContext) + { + const auto& workflows = initContext.services().get(); + for (const DeviceSpec& device : workflows.devices) { + if (device.name.compare("hf-candidate-creator-xic-to-xi-pi-pi") == 0) { + // init HF event selection helper + hfEvSelMc.init(device, registry); + break; + } + } + } + + template + void runMcMatching(aod::TracksWMc const& tracks, + aod::McParticles const& mcParticles, + McCollisions const& mcCollisions, + CollInfos const& collInfos, + BCsInfo const&) { rowCandidateXic->bindExternalIndices(&tracks); @@ -699,8 +902,9 @@ struct HfCandidateCreatorXicToXiPiPiExpressions { int8_t debug = 0; // for resonance matching: std::vector arrDaughIndex; - std::array arrPDGDaugh; - std::array arrXiResonance = {3324, kPiPlus}; // 3324: Ξ(1530) + constexpr std::size_t NDaughtersResonant{2u}; + std::array arrPDGDaugh; + std::array arrXiResonance = {3324, kPiPlus}; // 3324: Ξ(1530) // Match reconstructed candidates. for (const auto& candidate : *rowCandidateXic) { @@ -741,8 +945,8 @@ struct HfCandidateCreatorXicToXiPiPiExpressions { } if (indexRec > -1) { RecoDecay::getDaughters(mcParticles.rawIteratorAt(indexRecXicPlus), &arrDaughIndex, std::array{0}, 1); - if (arrDaughIndex.size() == 2) { - for (auto iProng = 0u; iProng < arrDaughIndex.size(); ++iProng) { + if (arrDaughIndex.size() == NDaughtersResonant) { + for (auto iProng = 0u; iProng < NDaughtersResonant; ++iProng) { auto daughI = mcParticles.rawIteratorAt(arrDaughIndex[iProng]); arrPDGDaugh[iProng] = std::abs(daughI.pdgCode()); } @@ -768,58 +972,115 @@ struct HfCandidateCreatorXicToXiPiPiExpressions { } // close loop over candidates // Match generated particles. - for (const auto& particle : mcParticles) { - flag = 0; - sign = 0; - debug = 0; - origin = RecoDecay::OriginType::None; - arrDaughIndex.clear(); + for (const auto& mcCollision : mcCollisions) { + // Slice the particles table to get the particles for the current MC collision + const auto mcParticlesPerMcColl = mcParticles.sliceBy(mcParticlesPerMcCollision, mcCollision.globalIndex()); + // Slice the collisions table to get the collision info for the current MC collision + float centrality{-1.f}; + uint16_t rejectionMask{0}; + int nSplitColl = 0; + if constexpr (centEstimator == o2::hf_centrality::CentralityEstimator::FT0C) { + const auto collSlice = collInfos.sliceBy(colPerMcCollisionFT0C, mcCollision.globalIndex()); + rejectionMask = hfEvSelMc.getHfMcCollisionRejectionMask(mcCollision, collSlice, centrality); + } else if constexpr (centEstimator == o2::hf_centrality::CentralityEstimator::FT0M) { + const auto collSlice = collInfos.sliceBy(colPerMcCollisionFT0M, mcCollision.globalIndex()); + nSplitColl = collSlice.size(); + rejectionMask = hfEvSelMc.getHfMcCollisionRejectionMask(mcCollision, collSlice, centrality); + } else if constexpr (centEstimator == o2::hf_centrality::CentralityEstimator::None) { + const auto collSlice = collInfos.sliceBy(colPerMcCollision, mcCollision.globalIndex()); + rejectionMask = hfEvSelMc.getHfMcCollisionRejectionMask(mcCollision, collSlice, centrality); + } + hfEvSelMc.fillHistograms(mcCollision, rejectionMask, nSplitColl); + if (rejectionMask != 0) { + // at least one event selection not satisfied --> reject all particles from this collision + for (unsigned int i = 0; i < mcParticlesPerMcColl.size(); ++i) { + rowMcMatchGen(0, 0, -1); + } + continue; + } - // Xic → Xi pi pi - if (RecoDecay::isMatchedMCGen(mcParticles, particle, Pdg::kXiCPlus, std::array{+kXiMinus, +kPiPlus, +kPiPlus}, true, &sign, 2)) { - debug = 1; - // Xi- -> Lambda pi - auto cascMC = mcParticles.rawIteratorAt(particle.daughtersIds().front()); - // Find Xi- from Xi(1530) -> Xi pi in case of resonant decay - RecoDecay::getDaughters(particle, &arrDaughIndex, std::array{0}, 1); - if (arrDaughIndex.size() == 2) { - auto cascStarMC = mcParticles.rawIteratorAt(particle.daughtersIds().front()); - if (RecoDecay::isMatchedMCGen(mcParticles, cascStarMC, +3324, std::array{+kXiMinus, +kPiPlus}, true)) { - cascMC = mcParticles.rawIteratorAt(cascStarMC.daughtersIds().front()); + for (const auto& particle : mcParticlesPerMcColl) { + flag = 0; + sign = 0; + debug = 0; + origin = RecoDecay::OriginType::None; + arrDaughIndex.clear(); + + // Xic → Xi pi pi + if (RecoDecay::isMatchedMCGen(mcParticles, particle, Pdg::kXiCPlus, std::array{+kXiMinus, +kPiPlus, +kPiPlus}, true, &sign, 2)) { + debug = 1; + // Xi- -> Lambda pi + auto cascMC = mcParticles.rawIteratorAt(particle.daughtersIds().front()); + // Find Xi- from Xi(1530) -> Xi pi in case of resonant decay + RecoDecay::getDaughters(particle, &arrDaughIndex, std::array{0}, 1); + if (arrDaughIndex.size() == NDaughtersResonant) { + auto cascStarMC = mcParticles.rawIteratorAt(particle.daughtersIds().front()); + if (RecoDecay::isMatchedMCGen(mcParticles, cascStarMC, +3324, std::array{+kXiMinus, +kPiPlus}, true)) { + cascMC = mcParticles.rawIteratorAt(cascStarMC.daughtersIds().front()); + } } - } - if (RecoDecay::isMatchedMCGen(mcParticles, cascMC, +kXiMinus, std::array{+kLambda0, +kPiMinus}, true)) { - debug = 2; - // Lambda -> p pi - auto v0MC = mcParticles.rawIteratorAt(cascMC.daughtersIds().front()); - if (RecoDecay::isMatchedMCGen(mcParticles, v0MC, +kLambda0, std::array{+kProton, +kPiMinus}, true)) { - debug = 3; - if (arrDaughIndex.size() == 2) { - for (auto iProng = 0u; iProng < arrDaughIndex.size(); ++iProng) { - auto daughI = mcParticles.rawIteratorAt(arrDaughIndex[iProng]); - arrPDGDaugh[iProng] = std::abs(daughI.pdgCode()); - } - if ((arrPDGDaugh[0] == arrXiResonance[0] && arrPDGDaugh[1] == arrXiResonance[1]) || (arrPDGDaugh[0] == arrXiResonance[1] && arrPDGDaugh[1] == arrXiResonance[0])) { - flag = sign * (1 << aod::hf_cand_xic_to_xi_pi_pi::DecayType::XicToXiResPiToXiPiPi); + if (RecoDecay::isMatchedMCGen(mcParticles, cascMC, +kXiMinus, std::array{+kLambda0, +kPiMinus}, true)) { + debug = 2; + // Lambda -> p pi + auto v0MC = mcParticles.rawIteratorAt(cascMC.daughtersIds().front()); + if (RecoDecay::isMatchedMCGen(mcParticles, v0MC, +kLambda0, std::array{+kProton, +kPiMinus}, true)) { + debug = 3; + if (arrDaughIndex.size() == NDaughtersResonant) { + for (auto iProng = 0u; iProng < NDaughtersResonant; ++iProng) { + auto daughI = mcParticles.rawIteratorAt(arrDaughIndex[iProng]); + arrPDGDaugh[iProng] = std::abs(daughI.pdgCode()); + } + if ((arrPDGDaugh[0] == arrXiResonance[0] && arrPDGDaugh[1] == arrXiResonance[1]) || (arrPDGDaugh[0] == arrXiResonance[1] && arrPDGDaugh[1] == arrXiResonance[0])) { + flag = sign * (1 << aod::hf_cand_xic_to_xi_pi_pi::DecayType::XicToXiResPiToXiPiPi); + } else { + debug = 4; + } } else { - debug = 4; + flag = sign * (1 << aod::hf_cand_xic_to_xi_pi_pi::DecayType::XicToXiPiPi); } - } else { - flag = sign * (1 << aod::hf_cand_xic_to_xi_pi_pi::DecayType::XicToXiPiPi); } } } - } - // Check whether the charm baryon is non-prompt (from a b quark). - if (flag != 0) { - origin = RecoDecay::getCharmHadronOrigin(mcParticles, particle, false); - } + // Check whether the charm baryon is non-prompt (from a b quark). + if (flag != 0) { + origin = RecoDecay::getCharmHadronOrigin(mcParticles, particle, false); + } + + rowMcMatchGen(flag, debug, origin); + } // close loop over generated particles + } // close loop over McCollisions + } // close template function - rowMcMatchGen(flag, debug, origin); - } // close loop over generated particles - } // close process - PROCESS_SWITCH(HfCandidateCreatorXicToXiPiPiExpressions, processMc, "Process MC", false); + void processMc(aod::TracksWMc const& tracks, + aod::McParticles const& mcParticles, + aod::McCollisions const& mcCollisions, + McCollisionsNoCents const& mcCollisionsNoCents, + BCsInfo const& bcs) + { + runMcMatching(tracks, mcParticles, mcCollisions, mcCollisionsNoCents, bcs); + } + PROCESS_SWITCH(HfCandidateCreatorXicToXiPiPiExpressions, processMc, "Perform MC matching with no centrality selection.", true); + + void processMcCentFT0C(aod::TracksWMc const& tracks, + aod::McParticles const& mcParticles, + aod::McCollisions const& mcCollisions, + McCollisionsFT0Cs const& mcCollisionsFT0Cs, + BCsInfo const& bcs) + { + runMcMatching(tracks, mcParticles, mcCollisions, mcCollisionsFT0Cs, bcs); + } + PROCESS_SWITCH(HfCandidateCreatorXicToXiPiPiExpressions, processMcCentFT0C, "Perform MC matching with centrality selection on FT0C.", false); + + void processMcCentFT0M(aod::TracksWMc const& tracks, + aod::McParticles const& mcParticles, + McCollisionsCentFT0Ms const& mcCollisionsCentFT0Ms, + McCollisionsFT0Ms const& mcCollisionsFT0Ms, + BCsInfo const& bcs) + { + runMcMatching(tracks, mcParticles, mcCollisionsCentFT0Ms, mcCollisionsFT0Ms, bcs); + } + PROCESS_SWITCH(HfCandidateCreatorXicToXiPiPiExpressions, processMcCentFT0M, "Perform MC matching with centrality selection on FT0M.", false); }; // close struct WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGHF/TableProducer/candidateSelectorDplusToPiKPi.cxx b/PWGHF/TableProducer/candidateSelectorDplusToPiKPi.cxx index 776596c9df8..890122c8b77 100644 --- a/PWGHF/TableProducer/candidateSelectorDplusToPiKPi.cxx +++ b/PWGHF/TableProducer/candidateSelectorDplusToPiKPi.cxx @@ -217,7 +217,7 @@ struct HfCandidateSelectorDplusToPiKPi { return true; } - void process(aod::HfCand3Prong const& candidates, + void process(aod::HfCand3ProngWPid const& candidates, TracksSel const&) { // looping over 3-prong candidates @@ -266,13 +266,13 @@ struct HfCandidateSelectorDplusToPiKPi { int pidTrackPos2Pion = -1; if (usePidTpcAndTof) { - pidTrackPos1Pion = selectorPion.statusTpcAndTof(trackPos1); - pidTrackNegKaon = selectorKaon.statusTpcAndTof(trackNeg); - pidTrackPos2Pion = selectorPion.statusTpcAndTof(trackPos2); + pidTrackPos1Pion = selectorPion.statusTpcAndTof(trackPos1, candidate.nSigTpcPi0(), candidate.nSigTofPi0()); + pidTrackNegKaon = selectorKaon.statusTpcAndTof(trackNeg, candidate.nSigTpcKa1(), candidate.nSigTofKa1()); + pidTrackPos2Pion = selectorPion.statusTpcAndTof(trackPos2, candidate.nSigTpcPi2(), candidate.nSigTofPi2()); } else { - pidTrackPos1Pion = selectorPion.statusTpcOrTof(trackPos1); - pidTrackNegKaon = selectorKaon.statusTpcOrTof(trackNeg); - pidTrackPos2Pion = selectorPion.statusTpcOrTof(trackPos2); + pidTrackPos1Pion = selectorPion.statusTpcOrTof(trackPos1, candidate.nSigTpcPi0(), candidate.nSigTofPi0()); + pidTrackNegKaon = selectorKaon.statusTpcOrTof(trackNeg, candidate.nSigTpcKa1(), candidate.nSigTofKa1()); + pidTrackPos2Pion = selectorPion.statusTpcOrTof(trackPos2, candidate.nSigTpcPi2(), candidate.nSigTofPi2()); } if (!selectionPID(pidTrackPos1Pion, pidTrackNegKaon, pidTrackPos2Pion)) { // exclude D± @@ -289,7 +289,7 @@ struct HfCandidateSelectorDplusToPiKPi { if (applyMl) { // ML selections - std::vector inputFeatures = hfMlResponse.getInputFeatures(candidate, trackPos1, trackNeg, trackPos2); + std::vector inputFeatures = hfMlResponse.getInputFeatures(candidate); bool isSelectedMl = hfMlResponse.isSelectedMl(inputFeatures, ptCand, outputMl); hfMlDplusToPiKPiCandidate(outputMl); diff --git a/PWGHF/TableProducer/candidateSelectorDsToKKPi.cxx b/PWGHF/TableProducer/candidateSelectorDsToKKPi.cxx index 3fee66bf344..c6e552b7ab3 100644 --- a/PWGHF/TableProducer/candidateSelectorDsToKKPi.cxx +++ b/PWGHF/TableProducer/candidateSelectorDsToKKPi.cxx @@ -251,7 +251,7 @@ struct HfCandidateSelectorDsToKKPi { return true; } - void process(aod::HfCand3Prong const& candidates, + void process(aod::HfCand3ProngWPid const& candidates, TracksSel const&) { // looping over 3-prong candidates @@ -320,17 +320,17 @@ struct HfCandidateSelectorDsToKKPi { int pidTrackNegKaon = -1; if (usePidTpcAndTof) { - pidTrackPos1Pion = selectorPion.statusTpcAndTof(trackPos1); - pidTrackPos1Kaon = selectorKaon.statusTpcAndTof(trackPos1); - pidTrackPos2Pion = selectorPion.statusTpcAndTof(trackPos2); - pidTrackPos2Kaon = selectorKaon.statusTpcAndTof(trackPos2); - pidTrackNegKaon = selectorKaon.statusTpcAndTof(trackNeg); + pidTrackPos1Pion = selectorPion.statusTpcAndTof(trackPos1, candidate.nSigTpcPi0(), candidate.nSigTofPi0()); + pidTrackPos1Kaon = selectorKaon.statusTpcAndTof(trackPos1, candidate.nSigTpcKa0(), candidate.nSigTofKa0()); + pidTrackPos2Pion = selectorPion.statusTpcAndTof(trackPos2, candidate.nSigTpcPi2(), candidate.nSigTofPi2()); + pidTrackPos2Kaon = selectorKaon.statusTpcAndTof(trackPos2, candidate.nSigTpcKa2(), candidate.nSigTofKa2()); + pidTrackNegKaon = selectorKaon.statusTpcAndTof(trackNeg, candidate.nSigTpcKa1(), candidate.nSigTofKa1()); } else { - pidTrackPos1Pion = selectorPion.statusTpcOrTof(trackPos1); - pidTrackPos1Kaon = selectorKaon.statusTpcOrTof(trackPos1); - pidTrackPos2Pion = selectorPion.statusTpcOrTof(trackPos2); - pidTrackPos2Kaon = selectorKaon.statusTpcOrTof(trackPos2); - pidTrackNegKaon = selectorKaon.statusTpcOrTof(trackNeg); + pidTrackPos1Pion = selectorPion.statusTpcOrTof(trackPos1, candidate.nSigTpcPi0(), candidate.nSigTofPi0()); + pidTrackPos1Kaon = selectorKaon.statusTpcOrTof(trackPos1, candidate.nSigTpcKa0(), candidate.nSigTofKa0()); + pidTrackPos2Pion = selectorPion.statusTpcOrTof(trackPos2, candidate.nSigTpcPi2(), candidate.nSigTofPi2()); + pidTrackPos2Kaon = selectorKaon.statusTpcOrTof(trackPos2, candidate.nSigTpcKa2(), candidate.nSigTofKa2()); + pidTrackNegKaon = selectorKaon.statusTpcOrTof(trackNeg, candidate.nSigTpcKa1(), candidate.nSigTofKa1()); } bool pidDsToKKPi = !(pidTrackPos1Kaon == TrackSelectorPID::Rejected || @@ -364,11 +364,11 @@ struct HfCandidateSelectorDsToKKPi { bool isSelectedMlDsToPiKK = false; if (topolDsToKKPi && pidDsToKKPi) { - std::vector inputFeaturesDsToKKPi = hfMlResponse.getInputFeatures(candidate, trackPos1, trackNeg, trackPos2, true); + std::vector inputFeaturesDsToKKPi = hfMlResponse.getInputFeatures(candidate, true); isSelectedMlDsToKKPi = hfMlResponse.isSelectedMl(inputFeaturesDsToKKPi, candidate.pt(), outputMlDsToKKPi); } if (topolDsToPiKK && pidDsToPiKK) { - std::vector inputFeaturesDsToPiKK = hfMlResponse.getInputFeatures(candidate, trackPos1, trackNeg, trackPos2, false); + std::vector inputFeaturesDsToPiKK = hfMlResponse.getInputFeatures(candidate, false); isSelectedMlDsToPiKK = hfMlResponse.isSelectedMl(inputFeaturesDsToPiKK, candidate.pt(), outputMlDsToPiKK); } diff --git a/PWGHF/TableProducer/candidateSelectorDstarToD0Pi.cxx b/PWGHF/TableProducer/candidateSelectorDstarToD0Pi.cxx index a94f510f01c..d8b729dc748 100644 --- a/PWGHF/TableProducer/candidateSelectorDstarToD0Pi.cxx +++ b/PWGHF/TableProducer/candidateSelectorDstarToD0Pi.cxx @@ -108,7 +108,7 @@ struct HfCandidateSelectorDstarToD0Pi { using TracksSel = soa::Join; // using TracksSel = soa::Join; - using HfFullDstarCandidate = soa::Join; + using HfFullDstarCandidate = soa::Join; AxisSpec axisBdtScore{100, 0.f, 1.f}; AxisSpec axisSelStatus{2, -0.5f, 1.5f}; @@ -365,10 +365,6 @@ struct HfCandidateSelectorDstarToD0Pi { outputMlDstarToD0Pi.clear(); auto ptCand = candDstar.pt(); - auto prongPi = candDstar.prongPi_as(); - auto prong0 = candDstar.prong0_as(); - auto prong1 = candDstar.prong1_as(); - if (!TESTBIT(candDstar.hfflag(), aod::hf_cand_2prong::DecayType::D0ToPiK)) { hfSelDstarCandidate(statusDstar, statusD0Flag, statusTopol, statusCand, statusPID); if (applyMl) { @@ -417,16 +413,18 @@ struct HfCandidateSelectorDstarToD0Pi { int pidTrackNegKaon = -1; int pidTrackNegPion = -1; + auto prong0 = candDstar.prong0_as(); + auto prong1 = candDstar.prong1_as(); if (usePidTpcAndTof) { - pidTrackPosKaon = selectorKaon.statusTpcAndTof(candDstar.prong0_as()); - pidTrackPosPion = selectorPion.statusTpcAndTof(candDstar.prong0_as()); - pidTrackNegKaon = selectorKaon.statusTpcAndTof(candDstar.prong1_as()); - pidTrackNegPion = selectorPion.statusTpcAndTof(candDstar.prong1_as()); + pidTrackPosKaon = selectorKaon.statusTpcAndTof(prong0, candDstar.nSigTpcKa0(), candDstar.nSigTofKa0()); + pidTrackPosPion = selectorPion.statusTpcAndTof(prong0, candDstar.nSigTpcPi0(), candDstar.nSigTofPi0()); + pidTrackNegKaon = selectorKaon.statusTpcAndTof(prong1, candDstar.nSigTpcKa1(), candDstar.nSigTofKa1()); + pidTrackNegPion = selectorPion.statusTpcAndTof(prong1, candDstar.nSigTpcPi1(), candDstar.nSigTofPi1()); } else { - pidTrackPosKaon = selectorKaon.statusTpcOrTof(candDstar.prong0_as()); - pidTrackPosPion = selectorPion.statusTpcOrTof(candDstar.prong0_as()); - pidTrackNegKaon = selectorKaon.statusTpcOrTof(candDstar.prong1_as()); - pidTrackNegPion = selectorPion.statusTpcOrTof(candDstar.prong1_as()); + pidTrackPosKaon = selectorKaon.statusTpcOrTof(prong0, candDstar.nSigTpcKa0(), candDstar.nSigTofKa0()); + pidTrackPosPion = selectorPion.statusTpcOrTof(prong0, candDstar.nSigTpcPi0(), candDstar.nSigTofPi0()); + pidTrackNegKaon = selectorKaon.statusTpcOrTof(prong1, candDstar.nSigTpcKa1(), candDstar.nSigTofKa1()); + pidTrackNegPion = selectorPion.statusTpcOrTof(prong1, candDstar.nSigTpcPi1(), candDstar.nSigTofPi1()); } int pidDstar = -1; @@ -465,7 +463,7 @@ struct HfCandidateSelectorDstarToD0Pi { // ML selections bool isSelectedMlDstar = false; - std::vector inputFeatures = hfMlResponse.getInputFeatures(candDstar, prong0, prong1, prongPi); + std::vector inputFeatures = hfMlResponse.getInputFeatures(candDstar); isSelectedMlDstar = hfMlResponse.isSelectedMl(inputFeatures, ptCand, outputMlDstarToD0Pi); hfMlDstarCandidate(outputMlDstarToD0Pi); diff --git a/PWGHF/TableProducer/candidateSelectorLc.cxx b/PWGHF/TableProducer/candidateSelectorLc.cxx index 0585fd66b5f..b06db12e2ec 100644 --- a/PWGHF/TableProducer/candidateSelectorLc.cxx +++ b/PWGHF/TableProducer/candidateSelectorLc.cxx @@ -73,6 +73,9 @@ struct HfCandidateSelectorLc { // topological cuts Configurable> binsPt{"binsPt", std::vector{hf_cuts_lc_to_p_k_pi::vecBinsPt}, "pT bin limits"}; Configurable> cuts{"cuts", {hf_cuts_lc_to_p_k_pi::Cuts[0], hf_cuts_lc_to_p_k_pi::NBinsPt, hf_cuts_lc_to_p_k_pi::NCutVars, hf_cuts_lc_to_p_k_pi::labelsPt, hf_cuts_lc_to_p_k_pi::labelsCutVar}, "Lc candidate selection per pT bin"}; + Configurable> kfCuts{"kfCuts", {hf_cuts_lc_to_p_k_pi::CutsKf[0], hf_cuts_lc_to_p_k_pi::NBinsPt, hf_cuts_lc_to_p_k_pi::NCutKfVars, hf_cuts_lc_to_p_k_pi::labelsPt, hf_cuts_lc_to_p_k_pi::labelsCutKfVar}, "Lc candidate selection per pT bin with KF-associated variables"}; + Configurable applyNonKfCuts{"applyNonKfCuts", true, "Whether to apply non-KF cuts when running in KF mode. In DCAFitter mode this field is not effective"}; + Configurable applyKfCuts{"applyKfCuts", true, "Whether to apply KF cuts when running in KF mode. In DCAFitter mode this field is not effective"}; // QA switch Configurable activateQA{"activateQA", false, "Flag to enable QA histogram"}; // ML inference @@ -175,7 +178,7 @@ struct HfCandidateSelectorLc { /// Conjugate-independent topological cuts /// \param candidate is candidate /// \return true if candidate passes all cuts - template + template bool selectionTopol(const T& candidate) { auto candpT = candidate.pt(); @@ -190,33 +193,54 @@ struct HfCandidateSelectorLc { return false; } - // cosine of pointing angle - if (candidate.cpa() <= cuts->get(pTBin, "cos pointing angle")) { - return false; - } + if (reconstructionType == aod::hf_cand::VertexerType::DCAFitter || (reconstructionType == aod::hf_cand::VertexerType::KfParticle && applyNonKfCuts)) { + // cosine of pointing angle + if (candidate.cpa() <= cuts->get(pTBin, "cos pointing angle")) { + return false; + } - // candidate chi2PCA - if (candidate.chi2PCA() > cuts->get(pTBin, "Chi2PCA")) { - return false; - } + // candidate chi2PCA + if (candidate.chi2PCA() > cuts->get(pTBin, "Chi2PCA")) { + return false; + } - if (candidate.decayLength() <= cuts->get(pTBin, "decay length")) { - return false; - } + if (candidate.decayLength() <= cuts->get(pTBin, "decay length")) { + return false; + } - // candidate decay length XY - if (candidate.decayLengthXY() <= cuts->get(pTBin, "decLengthXY")) { - return false; - } + // candidate decay length XY + if (candidate.decayLengthXY() <= cuts->get(pTBin, "decLengthXY")) { + return false; + } - // candidate normalized decay length XY - if (candidate.decayLengthXYNormalised() < cuts->get(pTBin, "normDecLXY")) { - return false; + // candidate normalized decay length XY + if (candidate.decayLengthXYNormalised() < cuts->get(pTBin, "normDecLXY")) { + return false; + } + + // candidate impact parameter XY + if (std::abs(candidate.impactParameterXY()) > cuts->get(pTBin, "impParXY")) { + return false; + } } - // candidate impact parameter XY - if (std::abs(candidate.impactParameterXY()) > cuts->get(pTBin, "impParXY")) { - return false; + if constexpr (reconstructionType == aod::hf_cand::VertexerType::KfParticle) { + if (applyKfCuts) { + // candidate chi2geo of the triplet of prongs + if (candidate.kfChi2Geo() > kfCuts->get(pTBin, "kfChi2Geo")) { + return false; + } + + // candidate's decay point separation from the PV in terms of its error + if (candidate.kfDecayLength() / candidate.kfDecayLengthError() < kfCuts->get(pTBin, "kfLdL")) { + return false; + } + + // candidate's chi2 to the PV + if (candidate.kfChi2Topo() > kfCuts->get(pTBin, "kfChi2Topo")) { + return false; + } + } } if (!isSelectedCandidateProngDca(candidate)) { @@ -242,40 +266,117 @@ struct HfCandidateSelectorLc { return false; } - // cut on daughter pT - if (trackProton.pt() < cuts->get(pTBin, "pT p") || trackKaon.pt() < cuts->get(pTBin, "pT K") || trackPion.pt() < cuts->get(pTBin, "pT Pi")) { - return false; - } + if (reconstructionType == aod::hf_cand::VertexerType::DCAFitter || (reconstructionType == aod::hf_cand::VertexerType::KfParticle && applyNonKfCuts)) { - // cut on Lc->pKpi, piKp mass values - /// cut on the Kpi pair invariant mass, to study Lc->pK*(->Kpi) - float massLc, massKPi; - if constexpr (reconstructionType == aod::hf_cand::VertexerType::DCAFitter) { - if (trackProton.globalIndex() == candidate.prong0Id()) { - massLc = hfHelper.invMassLcToPKPi(candidate); - massKPi = hfHelper.invMassKPiPairLcToPKPi(candidate); - } else { - massLc = hfHelper.invMassLcToPiKP(candidate); - massKPi = hfHelper.invMassKPiPairLcToPiKP(candidate); + // cut on daughter pT + if (trackProton.pt() < cuts->get(pTBin, "pT p") || trackKaon.pt() < cuts->get(pTBin, "pT K") || trackPion.pt() < cuts->get(pTBin, "pT Pi")) { + return false; } - } else if constexpr (reconstructionType == aod::hf_cand::VertexerType::KfParticle) { - if (trackProton.globalIndex() == candidate.prong0Id()) { - massLc = candidate.kfMassPKPi(); - massKPi = candidate.kfMassKPi(); - } else { - massLc = candidate.kfMassPiKP(); - massKPi = candidate.kfMassPiK(); + + float massLc, massKPi; + if constexpr (reconstructionType == aod::hf_cand::VertexerType::DCAFitter) { + if (trackProton.globalIndex() == candidate.prong0Id()) { + massLc = hfHelper.invMassLcToPKPi(candidate); + massKPi = hfHelper.invMassKPiPairLcToPKPi(candidate); + } else { + massLc = hfHelper.invMassLcToPiKP(candidate); + massKPi = hfHelper.invMassKPiPairLcToPiKP(candidate); + } + } else if constexpr (reconstructionType == aod::hf_cand::VertexerType::KfParticle) { + if (trackProton.globalIndex() == candidate.prong0Id()) { + massLc = candidate.kfMassPKPi(); + massKPi = candidate.kfMassKPi(); + } else { + massLc = candidate.kfMassPiKP(); + massKPi = candidate.kfMassPiK(); + } } - } - if (std::abs(massLc - o2::constants::physics::MassLambdaCPlus) > cuts->get(pTBin, "m")) { - return false; + // cut on Lc->pKpi, piKp mass values + if (std::abs(massLc - o2::constants::physics::MassLambdaCPlus) > cuts->get(pTBin, "m")) { + return false; + } + + /// cut on the Kpi pair invariant mass, to study Lc->pK*(->Kpi) + const double cutMassKPi = cuts->get(pTBin, "mass (Kpi)"); + if (cutMassKPi > 0 && std::abs(massKPi - massK0Star892) > cutMassKPi) { + return false; + } } - /// cut on the Kpi pair invariant mass, to study Lc->pK*(->Kpi) - const double cutMassKPi = cuts->get(pTBin, "mass (Kpi)"); - if (cutMassKPi > 0 && std::abs(massKPi - massK0Star892) > cutMassKPi) { - return false; + if constexpr (reconstructionType == aod::hf_cand::VertexerType::KfParticle) { + if (applyKfCuts) { + const float chi2PrimProng0 = candidate.kfChi2PrimProng0(); + const float chi2PrimProng1 = candidate.kfChi2PrimProng1(); + const float chi2PrimProng2 = candidate.kfChi2PrimProng2(); + + const float chi2GeoProng1Prong2 = candidate.kfChi2GeoProng1Prong2(); + const float chi2GeoProng0Prong2 = candidate.kfChi2GeoProng0Prong2(); + const float chi2GeoProng0Prong1 = candidate.kfChi2GeoProng0Prong1(); + + const float dcaProng1Prong2 = candidate.kfDcaProng1Prong2(); + const float dcaProng0Prong2 = candidate.kfDcaProng0Prong2(); + const float dcaProng0Prong1 = candidate.kfDcaProng0Prong1(); + + const double cutChi2PrimPr = kfCuts->get(pTBin, "kfChi2PrimPr"); + const double cutChi2PrimKa = kfCuts->get(pTBin, "kfChi2PrimKa"); + const double cutChi2PrimPi = kfCuts->get(pTBin, "kfChi2PrimPi"); + + const double cutChi2GeoKaPi = kfCuts->get(pTBin, "kfChi2GeoKaPi"); + const double cutChi2GeoPrPi = kfCuts->get(pTBin, "kfChi2GeoPrPi"); + const double cutChi2GeoPrKa = kfCuts->get(pTBin, "kfChi2GeoPrKa"); + + const double cutDcaKaPi = kfCuts->get(pTBin, "kfDcaKaPi"); + const double cutDcaPrPi = kfCuts->get(pTBin, "kfDcaPrPi"); + const double cutDcaPrKa = kfCuts->get(pTBin, "kfDcaPrKa"); + + // kaon's chi2 to the PV + if (chi2PrimProng1 < cutChi2PrimKa) { + return false; + } + + // chi2geo between proton and pion + if (chi2GeoProng0Prong2 > cutChi2GeoPrPi) { + return false; + } + + // dca between proton and pion + if (dcaProng0Prong2 > cutDcaPrPi) { + return false; + } + + const bool isPKPi = trackProton.globalIndex() == candidate.prong0Id(); + + // 0-th prong chi2 to the PV + if (chi2PrimProng0 < (isPKPi ? cutChi2PrimPr : cutChi2PrimPi)) { + return false; + } + + // 2-nd prong chi2 to the PV + if (chi2PrimProng2 < (isPKPi ? cutChi2PrimPi : cutChi2PrimPr)) { + return false; + } + + // chi2geo between 1-st and 2-nd prongs + if (chi2GeoProng1Prong2 > (isPKPi ? cutChi2GeoKaPi : cutChi2GeoPrKa)) { + return false; + } + + // chi2geo between 0-th and 1-st prongs + if (chi2GeoProng0Prong1 > (isPKPi ? cutChi2GeoPrKa : cutChi2GeoKaPi)) { + return false; + } + + // dca between 1-st and 2-nd prongs + if (dcaProng1Prong2 > (isPKPi ? cutDcaKaPi : cutDcaPrKa)) { + return false; + } + + // dca between 0-th and 1-st prongs + if (dcaProng0Prong1 > (isPKPi ? cutDcaPrKa : cutDcaKaPi)) { + return false; + } + } } return true; @@ -358,7 +459,7 @@ struct HfCandidateSelectorLc { } // conjugate-independent topological selection - if (!selectionTopol(candidate)) { + if (!selectionTopol(candidate)) { hfSelLcCandidate(statusLcToPKPi, statusLcToPiKP); if (applyMl) { hfMlLcToPKPiCandidate(outputMlLcToPKPi, outputMlLcToPiKP); @@ -396,17 +497,17 @@ struct HfCandidateSelectorLc { TrackSelectorPID::Status pidTrackPos2Pion = TrackSelectorPID::Accepted; TrackSelectorPID::Status pidTrackNegKaon = TrackSelectorPID::Accepted; if (usePidTpcAndTof) { - pidTrackPos1Proton = selectorProton.statusTpcAndTof(trackPos1); - pidTrackPos2Proton = selectorProton.statusTpcAndTof(trackPos2); - pidTrackPos1Pion = selectorPion.statusTpcAndTof(trackPos1); - pidTrackPos2Pion = selectorPion.statusTpcAndTof(trackPos2); - pidTrackNegKaon = selectorKaon.statusTpcAndTof(trackNeg); + pidTrackPos1Proton = selectorProton.statusTpcAndTof(trackPos1, candidate.nSigTpcPr0(), candidate.nSigTofPr0()); + pidTrackPos2Proton = selectorProton.statusTpcAndTof(trackPos2, candidate.nSigTpcPr2(), candidate.nSigTofPr2()); + pidTrackPos1Pion = selectorPion.statusTpcAndTof(trackPos1, candidate.nSigTpcPi0(), candidate.nSigTofPi0()); + pidTrackPos2Pion = selectorPion.statusTpcAndTof(trackPos2, candidate.nSigTpcPi2(), candidate.nSigTofPi2()); + pidTrackNegKaon = selectorKaon.statusTpcAndTof(trackNeg, candidate.nSigTpcKa1(), candidate.nSigTofKa1()); } else { - pidTrackPos1Proton = selectorProton.statusTpcOrTof(trackPos1); - pidTrackPos2Proton = selectorProton.statusTpcOrTof(trackPos2); - pidTrackPos1Pion = selectorPion.statusTpcOrTof(trackPos1); - pidTrackPos2Pion = selectorPion.statusTpcOrTof(trackPos2); - pidTrackNegKaon = selectorKaon.statusTpcOrTof(trackNeg); + pidTrackPos1Proton = selectorProton.statusTpcOrTof(trackPos1, candidate.nSigTpcPr0(), candidate.nSigTofPr0()); + pidTrackPos2Proton = selectorProton.statusTpcOrTof(trackPos2, candidate.nSigTpcPr2(), candidate.nSigTofPr2()); + pidTrackPos1Pion = selectorPion.statusTpcOrTof(trackPos1, candidate.nSigTpcPi0(), candidate.nSigTofPi0()); + pidTrackPos2Pion = selectorPion.statusTpcOrTof(trackPos2, candidate.nSigTpcPi2(), candidate.nSigTofPi2()); + pidTrackNegKaon = selectorKaon.statusTpcOrTof(trackNeg, candidate.nSigTpcKa1(), candidate.nSigTofKa1()); } if (!isSelectedPID(pidTrackPos1Proton, pidTrackNegKaon, pidTrackPos2Pion)) { @@ -453,11 +554,11 @@ struct HfCandidateSelectorLc { isSelectedMlLcToPiKP = false; if (pidLcToPKPi == 1 && pidBayesLcToPKPi == 1 && topolLcToPKPi) { - std::vector inputFeaturesLcToPKPi = hfMlResponse.getInputFeatures(candidate, trackPos1, trackNeg, trackPos2, true); + std::vector inputFeaturesLcToPKPi = hfMlResponse.getInputFeatures(candidate, true); isSelectedMlLcToPKPi = hfMlResponse.isSelectedMl(inputFeaturesLcToPKPi, candidate.pt(), outputMlLcToPKPi); } if (pidLcToPiKP == 1 && pidBayesLcToPiKP == 1 && topolLcToPiKP) { - std::vector inputFeaturesLcToPiKP = hfMlResponse.getInputFeatures(candidate, trackPos1, trackNeg, trackPos2, false); + std::vector inputFeaturesLcToPiKP = hfMlResponse.getInputFeatures(candidate, false); isSelectedMlLcToPiKP = hfMlResponse.isSelectedMl(inputFeaturesLcToPiKP, candidate.pt(), outputMlLcToPiKP); } @@ -487,7 +588,7 @@ struct HfCandidateSelectorLc { /// \brief process function w/o Bayes PID with DCAFitterN /// \param candidates Lc candidate table /// \param tracks track table - void processNoBayesPidWithDCAFitterN(aod::HfCand3Prong const& candidates, + void processNoBayesPidWithDCAFitterN(aod::HfCand3ProngWPid const& candidates, TracksSel const& tracks) { runSelectLc(candidates, tracks); @@ -497,7 +598,7 @@ struct HfCandidateSelectorLc { /// \brief process function with Bayes PID with DCAFitterN /// \param candidates Lc candidate table /// \param tracks track table with Bayes PID information - void processBayesPidWithDCAFitterN(aod::HfCand3Prong const& candidates, + void processBayesPidWithDCAFitterN(aod::HfCand3ProngWPid const& candidates, TracksSelBayesPid const& tracks) { runSelectLc(candidates, tracks); @@ -507,7 +608,7 @@ struct HfCandidateSelectorLc { /// \brief process function w/o Bayes PID with KFParticle /// \param candidates Lc candidate table /// \param tracks track table - void processNoBayesPidWithKFParticle(soa::Join const& candidates, + void processNoBayesPidWithKFParticle(soa::Join const& candidates, TracksSel const& tracks) { runSelectLc(candidates, tracks); @@ -517,7 +618,7 @@ struct HfCandidateSelectorLc { /// \brief process function with Bayes PID with KFParticle /// \param candidates Lc candidate table /// \param tracks track table with Bayes PID information - void processBayesPidWithKFParticle(soa::Join const& candidates, + void processBayesPidWithKFParticle(soa::Join const& candidates, TracksSelBayesPid const& tracks) { runSelectLc(candidates, tracks); diff --git a/PWGHF/TableProducer/candidateSelectorLcPidMl.cxx b/PWGHF/TableProducer/candidateSelectorLcPidMl.cxx index 2e127ff2829..45e91a39dbb 100644 --- a/PWGHF/TableProducer/candidateSelectorLcPidMl.cxx +++ b/PWGHF/TableProducer/candidateSelectorLcPidMl.cxx @@ -149,7 +149,7 @@ struct HfCandidateSelectorLcPidMl { } } - void process(aod::HfCand3Prong const& candidates, + void process(aod::HfCand3ProngWPid const& candidates, TracksSel const&) { // looping over 3-prong candidates @@ -181,11 +181,11 @@ struct HfCandidateSelectorLcPidMl { pidLcToPiKP = 1; } else { // track-level PID selection - int pidTrackPos1Proton = selectorProton.statusTpcOrTof(trackPos1); - int pidTrackPos2Proton = selectorProton.statusTpcOrTof(trackPos2); - int pidTrackPos1Pion = selectorPion.statusTpcOrTof(trackPos1); - int pidTrackPos2Pion = selectorPion.statusTpcOrTof(trackPos2); - int pidTrackNegKaon = selectorKaon.statusTpcOrTof(trackNeg); + TrackSelectorPID::Status pidTrackPos1Proton = selectorProton.statusTpcOrTof(trackPos1, candidate.nSigTpcPr0(), candidate.nSigTofPr0()); + TrackSelectorPID::Status pidTrackPos2Proton = selectorProton.statusTpcOrTof(trackPos2, candidate.nSigTpcPr2(), candidate.nSigTofPr2()); + TrackSelectorPID::Status pidTrackPos1Pion = selectorPion.statusTpcOrTof(trackPos1, candidate.nSigTpcPi0(), candidate.nSigTofPi0()); + TrackSelectorPID::Status pidTrackPos2Pion = selectorPion.statusTpcOrTof(trackPos2, candidate.nSigTpcPi2(), candidate.nSigTofPi2()); + TrackSelectorPID::Status pidTrackNegKaon = selectorKaon.statusTpcOrTof(trackNeg, candidate.nSigTpcKa1(), candidate.nSigTofKa1()); if (pidTrackPos1Proton == TrackSelectorPID::Accepted && pidTrackNegKaon == TrackSelectorPID::Accepted && diff --git a/PWGHF/TableProducer/candidateSelectorXicToPKPi.cxx b/PWGHF/TableProducer/candidateSelectorXicToPKPi.cxx index f9bd95d6aa7..4436a0834c2 100644 --- a/PWGHF/TableProducer/candidateSelectorXicToPKPi.cxx +++ b/PWGHF/TableProducer/candidateSelectorXicToPKPi.cxx @@ -222,7 +222,7 @@ struct HfCandidateSelectorXicToPKPi { return true; } - void process(aod::HfCand3Prong const& candidates, + void process(aod::HfCand3ProngWPid const& candidates, TracksSel const&) { // looping over 3-prong candidates @@ -307,17 +307,17 @@ struct HfCandidateSelectorXicToPKPi { TrackSelectorPID::Status pidTrackNegKaon = TrackSelectorPID::Accepted; if (usePidTpcAndTof) { - pidTrackPos1Proton = selectorProton.statusTpcAndTof(trackPos1); - pidTrackPos2Proton = selectorProton.statusTpcAndTof(trackPos2); - pidTrackPos1Pion = selectorPion.statusTpcAndTof(trackPos1); - pidTrackPos2Pion = selectorPion.statusTpcAndTof(trackPos2); - pidTrackNegKaon = selectorKaon.statusTpcAndTof(trackNeg); + pidTrackPos1Proton = selectorProton.statusTpcAndTof(trackPos1, candidate.nSigTpcPr0(), candidate.nSigTofPr0()); + pidTrackPos2Proton = selectorProton.statusTpcAndTof(trackPos2, candidate.nSigTpcPr2(), candidate.nSigTofPr2()); + pidTrackPos1Pion = selectorPion.statusTpcAndTof(trackPos1, candidate.nSigTpcPi0(), candidate.nSigTofPi0()); + pidTrackPos2Pion = selectorPion.statusTpcAndTof(trackPos2, candidate.nSigTpcPi2(), candidate.nSigTofPi2()); + pidTrackNegKaon = selectorKaon.statusTpcAndTof(trackNeg, candidate.nSigTpcKa1(), candidate.nSigTofKa1()); } else { - pidTrackPos1Proton = selectorProton.statusTpcOrTof(trackPos1); - pidTrackPos2Proton = selectorProton.statusTpcOrTof(trackPos2); - pidTrackPos1Pion = selectorPion.statusTpcOrTof(trackPos1); - pidTrackPos2Pion = selectorPion.statusTpcOrTof(trackPos2); - pidTrackNegKaon = selectorKaon.statusTpcOrTof(trackNeg); + pidTrackPos1Proton = selectorProton.statusTpcOrTof(trackPos1, candidate.nSigTpcPr0(), candidate.nSigTofPr0()); + pidTrackPos2Proton = selectorProton.statusTpcOrTof(trackPos2, candidate.nSigTpcPr2(), candidate.nSigTofPr2()); + pidTrackPos1Pion = selectorPion.statusTpcOrTof(trackPos1, candidate.nSigTpcPi0(), candidate.nSigTofPi0()); + pidTrackPos2Pion = selectorPion.statusTpcOrTof(trackPos2, candidate.nSigTpcPi2(), candidate.nSigTofPi2()); + pidTrackNegKaon = selectorKaon.statusTpcOrTof(trackNeg, candidate.nSigTpcKa1(), candidate.nSigTofKa1()); } if (pidTrackPos1Proton == TrackSelectorPID::Accepted && @@ -364,11 +364,11 @@ struct HfCandidateSelectorXicToPKPi { bool isSelectedMlXicToPiKP = false; if (topolXicToPKPi && pidXicToPKPi) { - std::vector inputFeaturesXicToPKPi = hfMlResponse.getInputFeatures(candidate, trackPos1, trackNeg, trackPos2, true); + std::vector inputFeaturesXicToPKPi = hfMlResponse.getInputFeatures(candidate, true); isSelectedMlXicToPKPi = hfMlResponse.isSelectedMl(inputFeaturesXicToPKPi, ptCand, outputMlXicToPKPi); } if (topolXicToPiKP && pidXicToPiKP) { - std::vector inputFeaturesXicToPiKP = hfMlResponse.getInputFeatures(candidate, trackPos1, trackNeg, trackPos2, false); + std::vector inputFeaturesXicToPiKP = hfMlResponse.getInputFeatures(candidate, false); isSelectedMlXicToPiKP = hfMlResponse.isSelectedMl(inputFeaturesXicToPiKP, ptCand, outputMlXicToPiKP); } diff --git a/PWGHF/TableProducer/derivedDataCreatorDplusToPiKPi.cxx b/PWGHF/TableProducer/derivedDataCreatorDplusToPiKPi.cxx index cf4f828b498..b9a4d357685 100644 --- a/PWGHF/TableProducer/derivedDataCreatorDplusToPiKPi.cxx +++ b/PWGHF/TableProducer/derivedDataCreatorDplusToPiKPi.cxx @@ -79,10 +79,10 @@ struct HfDerivedDataCreatorDplusToPiKPi { using CollisionsWCentMult = soa::Join; using CollisionsWMcCentMult = soa::Join; using TracksWPid = soa::Join; - using SelectedCandidates = soa::Filtered>; - using SelectedCandidatesMc = soa::Filtered>; - using SelectedCandidatesMl = soa::Filtered>; - using SelectedCandidatesMcMl = soa::Filtered>; + using SelectedCandidates = soa::Filtered>; + using SelectedCandidatesMc = soa::Filtered>; + using SelectedCandidatesMl = soa::Filtered>; + using SelectedCandidatesMcMl = soa::Filtered>; using MatchedGenCandidatesMc = soa::Filtered>; using TypeMcCollisions = soa::Join; @@ -115,8 +115,8 @@ struct HfDerivedDataCreatorDplusToPiKPi { rowsCommon.init(confDerData); } - template - void fillTablesCandidate(const T& candidate, const U& prong0, const U& prong1, const U& prong2, int candFlag, double invMass, + template + void fillTablesCandidate(const T& candidate, int candFlag, double invMass, double ct, double y, int8_t flagMc, int8_t origin, int8_t swapping, int8_t flagDecayChan, const std::vector& mlScores) { rowsCommon.fillTablesCandidate(candidate, invMass, y); @@ -139,15 +139,15 @@ struct HfDerivedDataCreatorDplusToPiKPi { candidate.impactParameterNormalised0(), candidate.impactParameterNormalised1(), candidate.impactParameterNormalised2(), - prong0.tpcNSigmaPi(), - prong0.tofNSigmaPi(), - prong0.tpcTofNSigmaPi(), - prong1.tpcNSigmaKa(), - prong1.tofNSigmaKa(), - prong1.tpcTofNSigmaKa(), - prong2.tpcNSigmaPi(), - prong2.tofNSigmaPi(), - prong2.tpcTofNSigmaPi()); + candidate.nSigTpcPi0(), + candidate.nSigTofPi0(), + candidate.tpcTofNSigmaPi0(), + candidate.nSigTpcKa1(), + candidate.nSigTofKa1(), + candidate.tpcTofNSigmaKa1(), + candidate.nSigTpcPi2(), + candidate.nSigTofPi2(), + candidate.tpcTofNSigmaPi2()); } if (fillCandidateParE) { rowCandidateParE( @@ -269,9 +269,6 @@ struct HfDerivedDataCreatorDplusToPiKPi { } } } - auto prong0 = candidate.template prong0_as(); - auto prong1 = candidate.template prong1_as(); - auto prong2 = candidate.template prong2_as(); double ct = hfHelper.ctDplus(candidate); double y = hfHelper.yDplus(candidate); float massDplusToPiKPi = hfHelper.invMassDplusToPiKPi(candidate); @@ -279,7 +276,7 @@ struct HfDerivedDataCreatorDplusToPiKPi { if constexpr (isMl) { std::copy(candidate.mlProbDplusToPiKPi().begin(), candidate.mlProbDplusToPiKPi().end(), std::back_inserter(mlScoresDplusToPiKPi)); } - fillTablesCandidate(candidate, prong0, prong1, prong2, 0, massDplusToPiKPi, ct, y, flagMcRec, origin, swapping, flagDecayChanRec, mlScoresDplusToPiKPi); + fillTablesCandidate(candidate, 0, massDplusToPiKPi, ct, y, flagMcRec, origin, swapping, flagDecayChanRec, mlScoresDplusToPiKPi); } } } diff --git a/PWGHF/TableProducer/derivedDataCreatorLcToPKPi.cxx b/PWGHF/TableProducer/derivedDataCreatorLcToPKPi.cxx index 61d2398a0d7..28b2b276b48 100644 --- a/PWGHF/TableProducer/derivedDataCreatorLcToPKPi.cxx +++ b/PWGHF/TableProducer/derivedDataCreatorLcToPKPi.cxx @@ -79,10 +79,10 @@ struct HfDerivedDataCreatorLcToPKPi { using CollisionsWCentMult = soa::Join; using CollisionsWMcCentMult = soa::Join; using TracksWPid = soa::Join; - using SelectedCandidates = soa::Filtered>; - using SelectedCandidatesMc = soa::Filtered>; - using SelectedCandidatesMl = soa::Filtered>; - using SelectedCandidatesMcMl = soa::Filtered>; + using SelectedCandidates = soa::Filtered>; + using SelectedCandidatesMc = soa::Filtered>; + using SelectedCandidatesMl = soa::Filtered>; + using SelectedCandidatesMcMl = soa::Filtered>; using MatchedGenCandidatesMc = soa::Filtered>; using TypeMcCollisions = soa::Join; @@ -115,8 +115,8 @@ struct HfDerivedDataCreatorLcToPKPi { rowsCommon.init(confDerData); } - template - void fillTablesCandidate(const T& candidate, const U& prong0, const U& prong1, const U& prong2, int candFlag, double invMass, + template + void fillTablesCandidate(const T& candidate, int candFlag, double invMass, double ct, double y, int8_t flagMc, int8_t origin, int8_t swapping, const std::vector& mlScores) { rowsCommon.fillTablesCandidate(candidate, invMass, y); @@ -139,21 +139,21 @@ struct HfDerivedDataCreatorLcToPKPi { candidate.impactParameterNormalised0(), candidate.impactParameterNormalised1(), candidate.impactParameterNormalised2(), - prong0.tpcNSigmaPi(), - prong0.tpcNSigmaPr(), - prong0.tofNSigmaPi(), - prong0.tofNSigmaPr(), - prong0.tpcTofNSigmaPi(), - prong0.tpcTofNSigmaPr(), - prong1.tpcNSigmaKa(), - prong1.tofNSigmaKa(), - prong1.tpcTofNSigmaKa(), - prong2.tpcNSigmaPi(), - prong2.tpcNSigmaPr(), - prong2.tofNSigmaPi(), - prong2.tofNSigmaPr(), - prong2.tpcTofNSigmaPi(), - prong2.tpcTofNSigmaPr()); + candidate.nSigTpcPi0(), + candidate.nSigTpcPr0(), + candidate.nSigTofPi0(), + candidate.nSigTofPr0(), + candidate.tpcTofNSigmaPi0(), + candidate.tpcTofNSigmaPr0(), + candidate.nSigTpcKa1(), + candidate.nSigTofKa1(), + candidate.tpcTofNSigmaKa1(), + candidate.nSigTpcPi2(), + candidate.nSigTpcPr2(), + candidate.nSigTofPi2(), + candidate.nSigTofPr2(), + candidate.tpcTofNSigmaPi2(), + candidate.tpcTofNSigmaPr2()); } if (fillCandidateParE) { rowCandidateParE( @@ -268,9 +268,6 @@ struct HfDerivedDataCreatorLcToPKPi { } } } - auto prong0 = candidate.template prong0_as(); - auto prong1 = candidate.template prong1_as(); - auto prong2 = candidate.template prong2_as(); double ct = hfHelper.ctLc(candidate); double y = hfHelper.yLc(candidate); float massLcToPKPi = hfHelper.invMassLcToPKPi(candidate); @@ -281,10 +278,10 @@ struct HfDerivedDataCreatorLcToPKPi { std::copy(candidate.mlProbLcToPiKP().begin(), candidate.mlProbLcToPiKP().end(), std::back_inserter(mlScoresLcToPiKP)); } if (candidate.isSelLcToPKPi()) { - fillTablesCandidate(candidate, prong0, prong1, prong2, 0, massLcToPKPi, ct, y, flagMcRec, origin, swapping, mlScoresLcToPKPi); + fillTablesCandidate(candidate, 0, massLcToPKPi, ct, y, flagMcRec, origin, swapping, mlScoresLcToPKPi); } if (candidate.isSelLcToPiKP()) { - fillTablesCandidate(candidate, prong0, prong1, prong2, 1, massLcToPiKP, ct, y, flagMcRec, origin, swapping, mlScoresLcToPiKP); + fillTablesCandidate(candidate, 1, massLcToPiKP, ct, y, flagMcRec, origin, swapping, mlScoresLcToPiKP); } } } diff --git a/PWGHF/TableProducer/treeCreatorDplusToPiKPi.cxx b/PWGHF/TableProducer/treeCreatorDplusToPiKPi.cxx index 8a8705cacce..ed3957f8e01 100644 --- a/PWGHF/TableProducer/treeCreatorDplusToPiKPi.cxx +++ b/PWGHF/TableProducer/treeCreatorDplusToPiKPi.cxx @@ -252,7 +252,6 @@ struct HfTreeCreatorDplusToPiKPi { Configurable fillCandidateLiteTable{"fillCandidateLiteTable", false, "Switch to fill lite table with candidate properties"}; // parameters for production of training samples Configurable fillOnlySignal{"fillOnlySignal", false, "Flag to fill derived tables with signal for ML trainings"}; - Configurable fillOnlySignalMl{"fillOnlySignalMl", false, "Flag to fill derived tables with MC and ML info"}; Configurable fillOnlyBackground{"fillOnlyBackground", false, "Flag to fill derived tables with background for ML trainings"}; Configurable downSampleBkgFactor{"downSampleBkgFactor", 1., "Fraction of background candidates to keep for ML trainings"}; Configurable ptMaxForDownSample{"ptMaxForDownSample", 10., "Maximum pt for the application of the downsampling factor"}; @@ -261,9 +260,9 @@ struct HfTreeCreatorDplusToPiKPi { HfHelper hfHelper; - using SelectedCandidatesMc = soa::Filtered>; + using SelectedCandidatesMc = soa::Filtered>; using MatchedGenCandidatesMc = soa::Filtered>; - using SelectedCandidatesMcWithMl = soa::Filtered>; + using SelectedCandidatesMcWithMl = soa::Filtered>; using TracksWPid = soa::Join; using CollisionsCent = soa::Join; @@ -314,10 +313,6 @@ struct HfTreeCreatorDplusToPiKPi { outputMl[1]); } - auto prong0 = candidate.template prong0_as(); - auto prong1 = candidate.template prong1_as(); - auto prong2 = candidate.template prong2_as(); - float cent{-1.}; auto coll = candidate.template collision_as(); if (std::is_same_v && centEstimator != CentralityEstimator::None) { @@ -340,24 +335,24 @@ struct HfTreeCreatorDplusToPiKPi { candidate.impactParameterZ0(), candidate.impactParameterZ1(), candidate.impactParameterZ2(), - prong0.tpcNSigmaPi(), - prong0.tpcNSigmaKa(), - prong0.tofNSigmaPi(), - prong0.tofNSigmaKa(), - prong0.tpcTofNSigmaPi(), - prong0.tpcTofNSigmaKa(), - prong1.tpcNSigmaPi(), - prong1.tpcNSigmaKa(), - prong1.tofNSigmaPi(), - prong1.tofNSigmaKa(), - prong1.tpcTofNSigmaPi(), - prong1.tpcTofNSigmaKa(), - prong2.tpcNSigmaPi(), - prong2.tpcNSigmaKa(), - prong2.tofNSigmaPi(), - prong2.tofNSigmaKa(), - prong2.tpcTofNSigmaPi(), - prong2.tpcTofNSigmaKa(), + candidate.nSigTpcPi0(), + candidate.nSigTpcKa0(), + candidate.nSigTofPi0(), + candidate.nSigTofKa0(), + candidate.tpcTofNSigmaPi0(), + candidate.tpcTofNSigmaKa0(), + candidate.nSigTpcPi1(), + candidate.nSigTpcKa1(), + candidate.nSigTofPi1(), + candidate.nSigTofKa1(), + candidate.tpcTofNSigmaPi1(), + candidate.tpcTofNSigmaKa1(), + candidate.nSigTpcPi2(), + candidate.nSigTpcKa2(), + candidate.nSigTofPi2(), + candidate.nSigTofKa2(), + candidate.tpcTofNSigmaPi2(), + candidate.tpcTofNSigmaKa2(), candidate.isSelDplusToPiKPi(), hfHelper.invMassDplusToPiKPi(candidate), candidate.pt(), @@ -419,24 +414,24 @@ struct HfTreeCreatorDplusToPiKPi { candidate.errorImpactParameterZ0(), candidate.errorImpactParameterZ1(), candidate.errorImpactParameterZ2(), - prong0.tpcNSigmaPi(), - prong0.tpcNSigmaKa(), - prong0.tofNSigmaPi(), - prong0.tofNSigmaKa(), - prong0.tpcTofNSigmaPi(), - prong0.tpcTofNSigmaKa(), - prong1.tpcNSigmaPi(), - prong1.tpcNSigmaKa(), - prong1.tofNSigmaPi(), - prong1.tofNSigmaKa(), - prong1.tpcTofNSigmaPi(), - prong1.tpcTofNSigmaKa(), - prong2.tpcNSigmaPi(), - prong2.tpcNSigmaKa(), - prong2.tofNSigmaPi(), - prong2.tofNSigmaKa(), - prong2.tpcTofNSigmaPi(), - prong2.tpcTofNSigmaKa(), + candidate.nSigTpcPi0(), + candidate.nSigTpcKa0(), + candidate.nSigTofPi0(), + candidate.nSigTofKa0(), + candidate.tpcTofNSigmaPi0(), + candidate.tpcTofNSigmaKa0(), + candidate.nSigTpcPi1(), + candidate.nSigTpcKa1(), + candidate.nSigTofPi1(), + candidate.nSigTofKa1(), + candidate.tpcTofNSigmaPi1(), + candidate.tpcTofNSigmaKa1(), + candidate.nSigTpcPi2(), + candidate.nSigTpcKa2(), + candidate.nSigTofPi2(), + candidate.nSigTofKa2(), + candidate.tpcTofNSigmaPi2(), + candidate.tpcTofNSigmaKa2(), candidate.isSelDplusToPiKPi(), hfHelper.invMassDplusToPiKPi(candidate), candidate.pt(), @@ -457,7 +452,7 @@ struct HfTreeCreatorDplusToPiKPi { } void processData(aod::Collisions const& collisions, - soa::Filtered> const& candidates, + soa::Filtered> const& candidates, TracksWPid const&) { // Filling event properties @@ -485,89 +480,8 @@ struct HfTreeCreatorDplusToPiKPi { PROCESS_SWITCH(HfTreeCreatorDplusToPiKPi, processData, "Process data", true); - void processMc(aod::Collisions const& collisions, - aod::McCollisions const&, - SelectedCandidatesMc const& candidates, - MatchedGenCandidatesMc const& particles, - SelectedCandidatesMcWithMl const&, - TracksWPid const&) - { - // Filling event properties - rowCandidateFullEvents.reserve(collisions.size()); - for (const auto& collision : collisions) { - fillEvent(collision, 0, 1); - } - - // Filling candidate properties - if (fillOnlySignal) { - if (fillCandidateLiteTable) { - rowCandidateLite.reserve(reconstructedCandSig.size()); - } else { - rowCandidateFull.reserve(reconstructedCandSig.size()); - } - for (const auto& candidate : reconstructedCandSig) { - fillCandidateTable(candidate); - } - } else if (fillOnlySignalMl) { - rowCandidateMl.reserve(reconstructedCandSigMl.size()); - if (fillCandidateLiteTable) { - rowCandidateLite.reserve(reconstructedCandSigMl.size()); - } else { - rowCandidateFull.reserve(reconstructedCandSigMl.size()); - } - for (const auto& candidate : reconstructedCandSigMl) { - if (downSampleBkgFactor < 1.) { - float pseudoRndm = candidate.ptProng0() * 1000. - static_cast(candidate.ptProng0() * 1000); - if (candidate.pt() < ptMaxForDownSample && pseudoRndm >= downSampleBkgFactor) { - continue; - } - } - fillCandidateTable(candidate); - } - } else if (fillOnlyBackground) { - if (fillCandidateLiteTable) { - rowCandidateLite.reserve(reconstructedCandBkg.size()); - } else { - rowCandidateFull.reserve(reconstructedCandBkg.size()); - } - for (const auto& candidate : reconstructedCandBkg) { - if (downSampleBkgFactor < 1.) { - float pseudoRndm = candidate.ptProng0() * 1000. - static_cast(candidate.ptProng0() * 1000); - if (candidate.pt() < ptMaxForDownSample && pseudoRndm >= downSampleBkgFactor) { - continue; - } - } - fillCandidateTable(candidate); - } - } else { - if (fillCandidateLiteTable) { - rowCandidateLite.reserve(candidates.size()); - } else { - rowCandidateFull.reserve(candidates.size()); - } - for (const auto& candidate : candidates) { - fillCandidateTable(candidate); - } - } - - // Filling particle properties - rowCandidateFullParticles.reserve(particles.size()); - for (const auto& particle : particles) { - rowCandidateFullParticles( - particle.mcCollision().bcId(), - particle.pt(), - particle.eta(), - particle.phi(), - RecoDecay::y(particle.pVector(), o2::constants::physics::MassDPlus), - particle.flagMcMatchGen(), - particle.originMcGen()); - } - } - - PROCESS_SWITCH(HfTreeCreatorDplusToPiKPi, processMc, "Process MC", false); - void processDataWCent(CollisionsCent const& collisions, - soa::Filtered> const& candidates, + soa::Filtered> const& candidates, TracksWPid const&) { // Filling event properties @@ -595,12 +509,12 @@ struct HfTreeCreatorDplusToPiKPi { PROCESS_SWITCH(HfTreeCreatorDplusToPiKPi, processDataWCent, "Process data with cent", false); - void processMcWCent(CollisionsCent const& collisions, - aod::McCollisions const&, - SelectedCandidatesMc const& candidates, - MatchedGenCandidatesMc const& particles, - SelectedCandidatesMcWithMl const&, - TracksWPid const&) + template + void fillMcTables(CollType const& collisions, + aod::McCollisions const&, + CandType const& candidates, + MatchedGenCandidatesMc const& particles, + TracksWPid const&) { // Filling event properties rowCandidateFullEvents.reserve(collisions.size()); @@ -609,55 +523,19 @@ struct HfTreeCreatorDplusToPiKPi { } // Filling candidate properties - if (fillOnlySignal) { - if (fillCandidateLiteTable) { - rowCandidateLite.reserve(reconstructedCandSig.size()); - } else { - rowCandidateFull.reserve(reconstructedCandSig.size()); - } - for (const auto& candidate : reconstructedCandSig) { - fillCandidateTable(candidate); - } - } else if (fillOnlySignalMl) { - rowCandidateMl.reserve(reconstructedCandSigMl.size()); - if (fillCandidateLiteTable) { - rowCandidateLite.reserve(reconstructedCandSigMl.size()); - } else { - rowCandidateFull.reserve(reconstructedCandSigMl.size()); - } - for (const auto& candidate : reconstructedCandSigMl) { - if (downSampleBkgFactor < 1.) { - float pseudoRndm = candidate.ptProng0() * 1000. - static_cast(candidate.ptProng0() * 1000); - if (candidate.pt() < ptMaxForDownSample && pseudoRndm >= downSampleBkgFactor) { - continue; - } - } - fillCandidateTable(candidate); - } - } else if (fillOnlyBackground) { - if (fillCandidateLiteTable) { - rowCandidateLite.reserve(reconstructedCandBkg.size()); - } else { - rowCandidateFull.reserve(reconstructedCandBkg.size()); - } - for (const auto& candidate : reconstructedCandBkg) { - if (downSampleBkgFactor < 1.) { - float pseudoRndm = candidate.ptProng0() * 1000. - static_cast(candidate.ptProng0() * 1000); - if (candidate.pt() < ptMaxForDownSample && pseudoRndm >= downSampleBkgFactor) { - continue; - } - } - fillCandidateTable(candidate); - } + if (fillCandidateLiteTable) { + rowCandidateLite.reserve(candidates.size()); } else { - if (fillCandidateLiteTable) { - rowCandidateLite.reserve(candidates.size()); - } else { - rowCandidateFull.reserve(candidates.size()); - } - for (const auto& candidate : candidates) { - fillCandidateTable(candidate); + rowCandidateFull.reserve(candidates.size()); + } + for (const auto& candidate : candidates) { + if (downSampleBkgFactor < 1.) { + float pseudoRndm = candidate.ptProng0() * 1000. - static_cast(candidate.ptProng0() * 1000); + if (candidate.pt() < ptMaxForDownSample && pseudoRndm >= downSampleBkgFactor) { + continue; + } } + fillCandidateTable(candidate); } // Filling particle properties @@ -674,7 +552,61 @@ struct HfTreeCreatorDplusToPiKPi { } } + void processMc(aod::Collisions const& collisions, + aod::McCollisions const& mccollisions, + SelectedCandidatesMc const& candidates, + MatchedGenCandidatesMc const& particles, + TracksWPid const& tracks) + { + if (fillOnlySignal) { + fillMcTables(collisions, mccollisions, reconstructedCandSig, particles, tracks); + } else if (fillOnlyBackground) { + fillMcTables(collisions, mccollisions, reconstructedCandBkg, particles, tracks); + } else { + fillMcTables(collisions, mccollisions, candidates, particles, tracks); + } + } + + PROCESS_SWITCH(HfTreeCreatorDplusToPiKPi, processMc, "Process MC", false); + + void processMcWCent(CollisionsCent const& collisions, + aod::McCollisions const& mccollisions, + SelectedCandidatesMc const& candidates, + MatchedGenCandidatesMc const& particles, + TracksWPid const& tracks) + { + if (fillOnlySignal) { + fillMcTables(collisions, mccollisions, reconstructedCandSig, particles, tracks); + } else if (fillOnlyBackground) { + fillMcTables(collisions, mccollisions, reconstructedCandBkg, particles, tracks); + } else { + fillMcTables(collisions, mccollisions, candidates, particles, tracks); + } + } + PROCESS_SWITCH(HfTreeCreatorDplusToPiKPi, processMcWCent, "Process MC with cent", false); + + void processMcSgnWMl(aod::Collisions const& collisions, + aod::McCollisions const& mccollisions, + SelectedCandidatesMcWithMl const&, + MatchedGenCandidatesMc const& particles, + TracksWPid const& tracks) + { + fillMcTables(collisions, mccollisions, reconstructedCandSigMl, particles, tracks); + } + + PROCESS_SWITCH(HfTreeCreatorDplusToPiKPi, processMcSgnWMl, "Process MC signal with ML info", false); + + void processMcSgnWCentMl(CollisionsCent const& collisions, + aod::McCollisions const& mccollisions, + SelectedCandidatesMcWithMl const&, + MatchedGenCandidatesMc const& particles, + TracksWPid const& tracks) + { + fillMcTables(collisions, mccollisions, reconstructedCandSigMl, particles, tracks); + } + + PROCESS_SWITCH(HfTreeCreatorDplusToPiKPi, processMcSgnWCentMl, "Process MC signal with cent and ML info", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGHF/TableProducer/treeCreatorDsToKKPi.cxx b/PWGHF/TableProducer/treeCreatorDsToKKPi.cxx index bb854c441fb..916063dbfd3 100644 --- a/PWGHF/TableProducer/treeCreatorDsToKKPi.cxx +++ b/PWGHF/TableProducer/treeCreatorDsToKKPi.cxx @@ -248,8 +248,8 @@ struct HfTreeCreatorDsToKKPi { HfHelper hfHelper; - using CandDsData = soa::Filtered>; - using CandDsMcReco = soa::Filtered>; + using CandDsData = soa::Filtered>; + using CandDsMcReco = soa::Filtered>; using CandDsMcGen = soa::Filtered>; using TracksWPid = soa::Join; @@ -344,24 +344,24 @@ struct HfTreeCreatorDsToKKPi { candidate.impactParameter0(), candidate.impactParameter1(), candidate.impactParameter2(), - prong0.tpcNSigmaPi(), - prong0.tpcNSigmaKa(), - prong0.tofNSigmaPi(), - prong0.tofNSigmaKa(), - prong0.tpcTofNSigmaPi(), - prong0.tpcTofNSigmaKa(), - prong1.tpcNSigmaPi(), - prong1.tpcNSigmaKa(), - prong1.tofNSigmaPi(), - prong1.tofNSigmaKa(), - prong1.tpcTofNSigmaPi(), - prong1.tpcTofNSigmaKa(), - prong2.tpcNSigmaPi(), - prong2.tpcNSigmaKa(), - prong2.tofNSigmaPi(), - prong2.tofNSigmaKa(), - prong2.tpcTofNSigmaPi(), - prong2.tpcTofNSigmaKa(), + candidate.nSigTpcPi0(), + candidate.nSigTpcKa0(), + candidate.nSigTofPi0(), + candidate.nSigTofKa0(), + candidate.tpcTofNSigmaPi0(), + candidate.tpcTofNSigmaKa0(), + candidate.nSigTpcPi1(), + candidate.nSigTpcKa1(), + candidate.nSigTofPi1(), + candidate.nSigTofKa1(), + candidate.tpcTofNSigmaPi1(), + candidate.tpcTofNSigmaKa1(), + candidate.nSigTpcPi2(), + candidate.nSigTpcKa2(), + candidate.nSigTofPi2(), + candidate.nSigTofKa2(), + candidate.tpcTofNSigmaPi2(), + candidate.tpcTofNSigmaKa2(), massHypo == 0 ? candidate.isSelDsToKKPi() : -1, massHypo == 1 ? candidate.isSelDsToPiKK() : -1, invMassDs, @@ -412,24 +412,24 @@ struct HfTreeCreatorDsToKKPi { candidate.impactParameter0(), candidate.impactParameter1(), candidate.impactParameter2(), - prong0.tpcNSigmaPi(), - prong0.tpcNSigmaKa(), - prong0.tofNSigmaPi(), - prong0.tofNSigmaKa(), - prong0.tpcTofNSigmaPi(), - prong0.tpcTofNSigmaKa(), - prong1.tpcNSigmaPi(), - prong1.tpcNSigmaKa(), - prong1.tofNSigmaPi(), - prong1.tofNSigmaKa(), - prong1.tpcTofNSigmaPi(), - prong1.tpcTofNSigmaKa(), - prong2.tpcNSigmaPi(), - prong2.tpcNSigmaKa(), - prong2.tofNSigmaPi(), - prong2.tofNSigmaKa(), - prong2.tpcTofNSigmaPi(), - prong2.tpcTofNSigmaKa(), + candidate.nSigTpcPi0(), + candidate.nSigTpcKa0(), + candidate.nSigTofPi0(), + candidate.nSigTofKa0(), + candidate.tpcTofNSigmaPi0(), + candidate.tpcTofNSigmaKa0(), + candidate.nSigTpcPi1(), + candidate.nSigTpcKa1(), + candidate.nSigTofPi1(), + candidate.nSigTofKa1(), + candidate.tpcTofNSigmaPi1(), + candidate.tpcTofNSigmaKa1(), + candidate.nSigTpcPi2(), + candidate.nSigTpcKa2(), + candidate.nSigTofPi2(), + candidate.nSigTofKa2(), + candidate.tpcTofNSigmaPi2(), + candidate.tpcTofNSigmaKa2(), massHypo == 0 ? candidate.isSelDsToKKPi() : -1, massHypo == 1 ? candidate.isSelDsToPiKK() : -1, candidate.xSecondaryVertex(), diff --git a/PWGHF/TableProducer/treeCreatorDstarToD0Pi.cxx b/PWGHF/TableProducer/treeCreatorDstarToD0Pi.cxx index fd11fad78b1..00d2bea174f 100644 --- a/PWGHF/TableProducer/treeCreatorDstarToD0Pi.cxx +++ b/PWGHF/TableProducer/treeCreatorDstarToD0Pi.cxx @@ -255,8 +255,8 @@ struct HfTreeCreatorDstarToD0Pi { Configurable downSampleBkgFactor{"downSampleBkgFactor", 1., "Fraction of background candidates to keep for ML trainings"}; Configurable ptMaxForDownSample{"ptMaxForDownSample", 10., "Maximum pt for the application of the downsampling factor"}; - using CandDstarWSelFlag = soa::Filtered>; - using CandDstarWSelFlagMcRec = soa::Filtered>; + using CandDstarWSelFlag = soa::Filtered>; + using CandDstarWSelFlagMcRec = soa::Filtered>; using TracksWPid = soa::Join; using CandDstarMcGen = soa::Filtered>; @@ -295,7 +295,6 @@ struct HfTreeCreatorDstarToD0Pi { TracksWPid::iterator prong0; TracksWPid::iterator prong1; - auto prongSoftPi = candidate.template prongPi_as(); float massD0{-1.f}; float massDStar{-1.f}; @@ -360,24 +359,24 @@ struct HfTreeCreatorDstarToD0Pi { impParameterNormalisedProng0, impParameterNormalisedProng1, candidate.normalisedImpParamSoftPi(), - prong0.tpcNSigmaPi(), - prong0.tpcNSigmaKa(), - prong0.tofNSigmaPi(), - prong0.tofNSigmaKa(), - prong0.tpcTofNSigmaPi(), - prong0.tpcTofNSigmaKa(), - prong1.tpcNSigmaPi(), - prong1.tpcNSigmaKa(), - prong1.tofNSigmaPi(), - prong1.tofNSigmaKa(), - prong1.tpcTofNSigmaPi(), - prong1.tpcTofNSigmaKa(), - prongSoftPi.tpcNSigmaPi(), - prongSoftPi.tpcNSigmaKa(), - prongSoftPi.tofNSigmaPi(), - prongSoftPi.tofNSigmaKa(), - prongSoftPi.tpcTofNSigmaPi(), - prongSoftPi.tpcTofNSigmaKa(), + candidate.nSigTpcPi0(), + candidate.nSigTpcKa0(), + candidate.nSigTofPi0(), + candidate.nSigTofKa0(), + candidate.tpcTofNSigmaPi0(), + candidate.tpcTofNSigmaKa0(), + candidate.nSigTpcPi1(), + candidate.nSigTpcKa1(), + candidate.nSigTofPi1(), + candidate.nSigTofKa1(), + candidate.tpcTofNSigmaPi1(), + candidate.tpcTofNSigmaKa1(), + candidate.nSigTpcPi2(), + candidate.nSigTpcKa2(), + candidate.nSigTofPi2(), + candidate.nSigTofKa2(), + candidate.tpcTofNSigmaPi2(), + candidate.tpcTofNSigmaKa2(), massD0, candidate.ptD0(), candidate.etaD0(), @@ -429,24 +428,24 @@ struct HfTreeCreatorDstarToD0Pi { candidate.errorImpactParameter0(), candidate.errorImpactParameter1(), candidate.errorImpParamSoftPi(), - prong0.tpcNSigmaPi(), - prong0.tpcNSigmaKa(), - prong0.tofNSigmaPi(), - prong0.tofNSigmaKa(), - prong0.tpcTofNSigmaPi(), - prong0.tpcTofNSigmaKa(), - prong1.tpcNSigmaPi(), - prong1.tpcNSigmaKa(), - prong1.tofNSigmaPi(), - prong1.tofNSigmaKa(), - prong1.tpcTofNSigmaPi(), - prong1.tpcTofNSigmaKa(), - prongSoftPi.tpcNSigmaPi(), - prongSoftPi.tpcNSigmaKa(), - prongSoftPi.tofNSigmaPi(), - prongSoftPi.tofNSigmaKa(), - prongSoftPi.tpcTofNSigmaPi(), - prongSoftPi.tpcTofNSigmaKa(), + candidate.nSigTpcPi0(), + candidate.nSigTpcKa0(), + candidate.nSigTofPi0(), + candidate.nSigTofKa0(), + candidate.tpcTofNSigmaPi0(), + candidate.tpcTofNSigmaKa0(), + candidate.nSigTpcPi1(), + candidate.nSigTpcKa1(), + candidate.nSigTofPi1(), + candidate.nSigTofKa1(), + candidate.tpcTofNSigmaPi1(), + candidate.tpcTofNSigmaKa1(), + candidate.nSigTpcPi2(), + candidate.nSigTpcKa2(), + candidate.nSigTofPi2(), + candidate.nSigTofKa2(), + candidate.tpcTofNSigmaPi2(), + candidate.tpcTofNSigmaKa2(), massD0, candidate.ptD0(), candidate.pD0(), diff --git a/PWGHF/TableProducer/treeCreatorLbToLcPi.cxx b/PWGHF/TableProducer/treeCreatorLbToLcPi.cxx index d69de17d4e8..f256125e990 100644 --- a/PWGHF/TableProducer/treeCreatorLbToLcPi.cxx +++ b/PWGHF/TableProducer/treeCreatorLbToLcPi.cxx @@ -192,7 +192,7 @@ struct HfTreeCreatorLbToLcPi { using TracksWPid = soa::Join; void process(soa::Join const& candidates, - soa::Join const&, + soa::Join const&, TracksWPid const&) { // Filling candidate properties @@ -202,7 +202,7 @@ struct HfTreeCreatorLbToLcPi { float FunctionInvMass, float FunctionCt, float FunctionY) { - auto candLc = candidate.prong0_as>(); + auto candLc = candidate.prong0_as>(); auto track0 = candidate.prong1_as(); // daughter pion track auto track1 = candLc.prong0_as(); // granddaughter tracks (lc decay particles) auto track2 = candLc.prong1_as(); @@ -245,18 +245,18 @@ struct HfTreeCreatorLbToLcPi { candidate.impactParameter1(), candidate.errorImpactParameter0(), candidate.errorImpactParameter1(), - track1.tpcNSigmaPi(), - track1.tpcNSigmaKa(), - track1.tpcNSigmaPr(), - track2.tpcNSigmaPi(), - track2.tpcNSigmaKa(), - track2.tpcNSigmaPr(), - track3.tpcNSigmaPi(), - track3.tpcNSigmaKa(), - track3.tpcNSigmaPr(), - track1.tofNSigmaPr(), - track2.tofNSigmaKa(), - track3.tofNSigmaPi(), + candLc.nSigTpcPi0(), + candLc.nSigTpcKa0(), + candLc.nSigTpcPr0(), + candLc.nSigTpcPi1(), + candLc.nSigTpcKa1(), + candLc.nSigTpcPr1(), + candLc.nSigTpcPi2(), + candLc.nSigTpcKa2(), + candLc.nSigTpcPr2(), + candLc.nSigTofPr0(), + candLc.nSigTofKa1(), + candLc.nSigTofPi2(), hfHelper.invMassLcToPKPi(candLc), hfHelper.ctLc(candLc), hfHelper.yLc(candLc), diff --git a/PWGHF/TableProducer/treeCreatorLcToPKPi.cxx b/PWGHF/TableProducer/treeCreatorLcToPKPi.cxx index 5b2c5225ba0..be5349f8589 100644 --- a/PWGHF/TableProducer/treeCreatorLcToPKPi.cxx +++ b/PWGHF/TableProducer/treeCreatorLcToPKPi.cxx @@ -82,7 +82,7 @@ DECLARE_SOA_COLUMN(FlagMc, flagMc, int8_t); DECLARE_SOA_COLUMN(OriginMcRec, originMcRec, int8_t); DECLARE_SOA_COLUMN(OriginMcGen, originMcGen, int8_t); DECLARE_SOA_COLUMN(IsCandidateSwapped, isCandidateSwapped, int8_t); -DECLARE_SOA_INDEX_COLUMN_FULL(Candidate, candidate, int, HfCand3Prong, "_0"); +DECLARE_SOA_INDEX_COLUMN_FULL(Candidate, candidate, int, HfCand3ProngWPid, "_0"); DECLARE_SOA_INDEX_COLUMN(McParticle, mcParticle); DECLARE_SOA_COLUMN(Channel, channel, int8_t); // direct or resonant // Events @@ -131,8 +131,28 @@ DECLARE_SOA_COLUMN(ErrP, errP, float); //! mom DECLARE_SOA_COLUMN(ErrPt, errPt, float); //! transverse momentum error DECLARE_SOA_COLUMN(IsSelected, isSelected, int); //! flag whether candidate was selected in candidateSelectorLc task DECLARE_SOA_COLUMN(SigBgStatus, sigBgStatus, int); //! 0 bg, 1 prompt, 2 non-prompt, 3 wrong order of prongs, -1 default value (impossible, should not be the case), -999 for data +DECLARE_SOA_COLUMN(NSigTpcPi, nSigTpcPi, float); +DECLARE_SOA_COLUMN(NSigTpcKa, nSigTpcKa, float); +DECLARE_SOA_COLUMN(NSigTpcPr, nSigTpcPr, float); +DECLARE_SOA_COLUMN(NSigTofPi, nSigTofPi, float); +DECLARE_SOA_COLUMN(NSigTofKa, nSigTofKa, float); +DECLARE_SOA_COLUMN(NSigTofPr, nSigTofPr, float); +DECLARE_SOA_COLUMN(NSigTpcTofPi, nSigTpcTofPi, float); +DECLARE_SOA_COLUMN(NSigTpcTofKa, nSigTpcTofKa, float); +DECLARE_SOA_COLUMN(NSigTpcTofPr, nSigTpcTofPr, float); +DECLARE_SOA_COLUMN(MultNTracksPV, multNTracksPV, int); } // namespace kf +namespace kf_collision +{ +DECLARE_SOA_COLUMN(PosXErr, posXErr, float); //! PV X coordinate uncertainty +DECLARE_SOA_COLUMN(PosYErr, posYErr, float); //! PV Y coordinate uncertainty +DECLARE_SOA_COLUMN(PosZErr, posZErr, float); //! PV Z coordinate uncertainty +DECLARE_SOA_COLUMN(McPosX, mcPosX, float); //! PV X coordinate uncertainty +DECLARE_SOA_COLUMN(McPosY, mcPosY, float); //! PV Y coordinate uncertainty +DECLARE_SOA_COLUMN(McPosZ, mcPosZ, float); //! PV Z coordinate uncertainty +} // namespace kf_collision + namespace mc_match { DECLARE_SOA_COLUMN(P, p, float); //! Momentum, GeV/c @@ -161,7 +181,17 @@ DECLARE_SOA_TABLE(HfCandLcKFs, "AOD", "HFCANDLCKF", kf::Chi2GeoProtonKaon, kf::Chi2GeoProtonPion, kf::Chi2GeoPionKaon, kf::Chi2Geo, kf::Chi2Topo, kf::DecayLength, kf::DecayLengthError, kf::DecayLengthNormalised, kf::T, kf::ErrT, kf::MassInv, kf::P, kf::Pt, kf::ErrP, kf::ErrPt, - kf::IsSelected, kf::SigBgStatus); + kf::IsSelected, kf::SigBgStatus, + kf::MultNTracksPV, + kf::NSigTpcPr, + kf::NSigTpcKa, + kf::NSigTpcPi, + kf::NSigTofPr, + kf::NSigTofKa, + kf::NSigTofPi, + kf::NSigTpcTofPr, + kf::NSigTpcTofKa, + kf::NSigTpcTofPi); DECLARE_SOA_TABLE(HfCandLcLites, "AOD", "HFCANDLCLITE", collision::PosX, @@ -293,6 +323,12 @@ DECLARE_SOA_TABLE(HfCandLcFullEvs, "AOD", "HFCANDLCFULLEV", collision::PosX, collision::PosY, collision::PosZ, + kf_collision::PosXErr, + kf_collision::PosYErr, + kf_collision::PosZErr, + kf_collision::McPosX, + kf_collision::McPosY, + kf_collision::McPosZ, full::IsEventReject, full::RunNumber, full::CentFT0A, @@ -300,7 +336,8 @@ DECLARE_SOA_TABLE(HfCandLcFullEvs, "AOD", "HFCANDLCFULLEV", full::CentFT0M, full::CentFV0A, full::CentFDDM, - full::MultZeqNTracksPV); + full::MultZeqNTracksPV, + kf::MultNTracksPV); DECLARE_SOA_TABLE(HfCandLcFullPs, "AOD", "HFCANDLCFULLP", full::Pt, @@ -308,7 +345,16 @@ DECLARE_SOA_TABLE(HfCandLcFullPs, "AOD", "HFCANDLCFULLP", full::Phi, full::Y, full::FlagMc, - full::OriginMcGen); + full::OriginMcGen, + mc_match::P, + mc_match::XDecay, + mc_match::YDecay, + mc_match::ZDecay, + mc_match::LDecay, + mc_match::TDecay, + mc_match::XEvent, + mc_match::YEvent, + mc_match::ZEvent); } // namespace o2::aod @@ -351,10 +397,10 @@ struct HfTreeCreatorLcToPKPi { /// \brief function which determines if the candidate corresponds to MC-particle or belongs to a combinatorial background /// \param candidate candidate to be checked for being signal or background - /// \param CandFlag 0 for PKPi hypothesis and 1 for PiKP hypothesis + /// \param candFlag 0 for PKPi hypothesis and 1 for PiKP hypothesis /// \return SigBgStatus enum with value encoding MC status of the candidate template - SigBgStatus determineSignalBgStatus(const CandType& candidate, int CandFlag) + SigBgStatus determineSignalBgStatus(const CandType& candidate, int candFlag) { const int flag = candidate.flagMcMatchRec(); const int origin = candidate.originMcRec(); @@ -364,7 +410,7 @@ struct HfTreeCreatorLcToPKPi { if (std::abs(flag) == (1 << o2::aod::hf_cand_3prong::DecayType::LcToPKPi)) { if (swapped == 0) { - if (CandFlag == 0) { + if (candFlag == 0) { if (origin == RecoDecay::OriginType::Prompt) status = Prompt; else if (origin == RecoDecay::OriginType::NonPrompt) @@ -373,7 +419,7 @@ struct HfTreeCreatorLcToPKPi { status = WrongOrder; } } else { - if (CandFlag == 1) { + if (candFlag == 1) { if (origin == RecoDecay::OriginType::Prompt) status = Prompt; else if (origin == RecoDecay::OriginType::NonPrompt) @@ -431,6 +477,8 @@ struct HfTreeCreatorLcToPKPi { centFDDM = collision.centFDDM(); } + auto mcCollision = collision.template mcCollision_as(); + rowCandidateFullEvents( collision.globalIndex(), collision.mcCollisionId(), @@ -438,6 +486,12 @@ struct HfTreeCreatorLcToPKPi { collision.posX(), collision.posY(), collision.posZ(), + std::sqrt(collision.covXX()), + std::sqrt(collision.covYY()), + std::sqrt(collision.covZZ()), + mcCollision.posX(), + mcCollision.posY(), + mcCollision.posZ(), 0, collision.bc().runNumber(), centFT0A, @@ -445,7 +499,8 @@ struct HfTreeCreatorLcToPKPi { centFT0M, centFV0A, centFDDM, - collision.multZeqNTracksPV()); + collision.multZeqNTracksPV(), + collision.multNTracksPV()); } // Filling candidate properties @@ -466,26 +521,28 @@ struct HfTreeCreatorLcToPKPi { rowCandidateMC.reserve(candidates.size() * 2); } for (const auto& candidate : candidates) { - auto trackPos1 = candidate.template prong0_as>(); // positive daughter (negative for the antiparticles) - auto trackNeg = candidate.template prong1_as>(); // negative daughter (positive for the antiparticles) - auto trackPos2 = candidate.template prong2_as>(); // positive daughter (negative for the antiparticles) - auto fillTable = [&](int CandFlag) { - double pseudoRndm = trackPos1.pt() * 1000. - static_cast(trackPos1.pt() * 1000); - const int FunctionSelection = CandFlag == 0 ? candidate.isSelLcToPKPi() : candidate.isSelLcToPiKP(); - const int sigbgstatus = determineSignalBgStatus(candidate, CandFlag); - bool isMcCandidateSignal = (sigbgstatus == Prompt) || (sigbgstatus == NonPrompt); - if (FunctionSelection >= selectionFlagLc && (/*keep all*/ (!keepOnlySignalMc && !keepOnlyBkg) || /*keep only signal*/ (keepOnlySignalMc && isMcCandidateSignal) || /*keep only background and downsample it*/ (keepOnlyBkg && !isMcCandidateSignal && (candidate.pt() > downSampleBkgPtMax || (pseudoRndm < downSampleBkgFactor && candidate.pt() < downSampleBkgPtMax))))) { - float FunctionInvMass, FunctionInvMassKPi; + float ptProng0 = candidate.ptProng0(); + auto collision = candidate.template collision_as(); + auto fillTable = [&](int candFlag) { + double pseudoRndm = ptProng0 * 1000. - static_cast(ptProng0 * 1000); + const int functionSelection = candFlag == 0 ? candidate.isSelLcToPKPi() : candidate.isSelLcToPiKP(); + const int sigbgstatus = determineSignalBgStatus(candidate, candFlag); + const bool isMcCandidateSignal = (sigbgstatus == Prompt) || (sigbgstatus == NonPrompt); + const bool passSelection = functionSelection >= selectionFlagLc; + const bool keepAll = !keepOnlySignalMc && !keepOnlyBkg; + const bool notSkippedBkg = isMcCandidateSignal || candidate.pt() > downSampleBkgPtMax || pseudoRndm < downSampleBkgFactor; + if (passSelection && notSkippedBkg && (keepAll || (keepOnlySignalMc && isMcCandidateSignal) || (keepOnlyBkg && !isMcCandidateSignal))) { + float functionInvMass, functionInvMassKPi; if constexpr (reconstructionType == aod::hf_cand::VertexerType::DCAFitter) { - FunctionInvMass = CandFlag == 0 ? hfHelper.invMassLcToPKPi(candidate) : hfHelper.invMassLcToPiKP(candidate); - FunctionInvMassKPi = CandFlag == 0 ? hfHelper.invMassKPiPairLcToPKPi(candidate) : hfHelper.invMassKPiPairLcToPiKP(candidate); + functionInvMass = candFlag == 0 ? hfHelper.invMassLcToPKPi(candidate) : hfHelper.invMassLcToPiKP(candidate); + functionInvMassKPi = candFlag == 0 ? hfHelper.invMassKPiPairLcToPKPi(candidate) : hfHelper.invMassKPiPairLcToPiKP(candidate); } else { - FunctionInvMass = CandFlag == 0 ? candidate.kfMassPKPi() : candidate.kfMassPiKP(); - FunctionInvMassKPi = CandFlag == 0 ? candidate.kfMassKPi() : candidate.kfMassPiK(); + functionInvMass = candFlag == 0 ? candidate.kfMassPKPi() : candidate.kfMassPiKP(); + functionInvMassKPi = candFlag == 0 ? candidate.kfMassKPi() : candidate.kfMassPiK(); } - const float FunctionCt = hfHelper.ctLc(candidate); - const float FunctionY = hfHelper.yLc(candidate); - const float FunctionE = hfHelper.eLc(candidate); + const float functionCt = hfHelper.ctLc(candidate); + const float functionY = hfHelper.yLc(candidate); + const float functionE = hfHelper.eLc(candidate); if (fillCandidateLiteTable) { rowCandidateLite( candidate.posX(), @@ -502,35 +559,35 @@ struct HfTreeCreatorLcToPKPi { candidate.impactParameter0(), candidate.impactParameter1(), candidate.impactParameter2(), - trackPos1.tpcNSigmaPi(), - trackPos1.tpcNSigmaPr(), - trackPos1.tofNSigmaPi(), - trackPos1.tofNSigmaPr(), - trackNeg.tpcNSigmaKa(), - trackNeg.tofNSigmaKa(), - trackPos2.tpcNSigmaPi(), - trackPos2.tpcNSigmaPr(), - trackPos2.tofNSigmaPi(), - trackPos2.tofNSigmaPr(), - trackPos1.tpcTofNSigmaPi(), - trackPos1.tpcTofNSigmaPr(), - trackNeg.tpcTofNSigmaKa(), - trackPos2.tpcTofNSigmaPi(), - trackPos2.tpcTofNSigmaPr(), - 1 << CandFlag, - FunctionInvMass, + candidate.nSigTpcPi0(), + candidate.nSigTpcPr0(), + candidate.nSigTofPi0(), + candidate.nSigTofPr0(), + candidate.nSigTpcKa1(), + candidate.nSigTofKa1(), + candidate.nSigTpcPi2(), + candidate.nSigTpcPr2(), + candidate.nSigTofPi2(), + candidate.nSigTofPr2(), + candidate.tpcTofNSigmaPi0(), + candidate.tpcTofNSigmaPr0(), + candidate.tpcTofNSigmaKa1(), + candidate.tpcTofNSigmaPi2(), + candidate.tpcTofNSigmaPr2(), + 1 << candFlag, + functionInvMass, candidate.pt(), candidate.cpa(), candidate.cpaXY(), - FunctionCt, + functionCt, candidate.eta(), candidate.phi(), - FunctionY, + functionY, candidate.flagMcMatchRec(), candidate.originMcRec(), candidate.isCandidateSwapped(), candidate.flagMcDecayChanRec(), - FunctionInvMassKPi); + functionInvMassKPi); if (fillCollIdTable) { /// save also candidate collision indices @@ -579,41 +636,86 @@ struct HfTreeCreatorLcToPKPi { candidate.errorImpactParameter0(), candidate.errorImpactParameter1(), candidate.errorImpactParameter2(), - trackPos1.tpcNSigmaPi(), - trackPos1.tpcNSigmaPr(), - trackPos1.tofNSigmaPi(), - trackPos1.tofNSigmaPr(), - trackNeg.tpcNSigmaKa(), - trackNeg.tofNSigmaKa(), - trackPos2.tpcNSigmaPi(), - trackPos2.tpcNSigmaPr(), - trackPos2.tofNSigmaPi(), - trackPos2.tofNSigmaPr(), - trackPos1.tpcTofNSigmaPi(), - trackPos1.tpcTofNSigmaPr(), - trackNeg.tpcTofNSigmaKa(), - trackPos2.tpcTofNSigmaPi(), - trackPos2.tpcTofNSigmaPr(), - 1 << CandFlag, - FunctionInvMass, + candidate.nSigTpcPi0(), + candidate.nSigTpcPr0(), + candidate.nSigTofPi0(), + candidate.nSigTofPr0(), + candidate.nSigTpcKa1(), + candidate.nSigTofKa1(), + candidate.nSigTpcPi2(), + candidate.nSigTpcPr2(), + candidate.nSigTofPi2(), + candidate.nSigTofPr2(), + candidate.tpcTofNSigmaPi0(), + candidate.tpcTofNSigmaPr0(), + candidate.tpcTofNSigmaKa1(), + candidate.tpcTofNSigmaPi2(), + candidate.tpcTofNSigmaPr2(), + 1 << candFlag, + functionInvMass, candidate.pt(), candidate.p(), candidate.cpa(), candidate.cpaXY(), - FunctionCt, + functionCt, candidate.eta(), candidate.phi(), - FunctionY, - FunctionE, + functionY, + functionE, candidate.flagMcMatchRec(), candidate.originMcRec(), candidate.isCandidateSwapped(), candidate.globalIndex(), candidate.flagMcDecayChanRec(), - FunctionInvMassKPi); + functionInvMassKPi); } if constexpr (reconstructionType == aod::hf_cand::VertexerType::KfParticle) { + float chi2primProton; + float chi2primPion; + float dcaProtonKaon; + float dcaPionKaon; + float chi2GeoProtonKaon; + float chi2GeoPionKaon; + float mass; + float valueTpcNSigmaPr; + const float valueTpcNSigmaKa = candidate.nSigTpcKa1(); + float valueTpcNSigmaPi; + float valueTofNSigmaPr; + const float valueTofNSigmaKa = candidate.nSigTofKa1(); + float valueTofNSigmaPi; + float valueTpcTofNSigmaPr; + const float valueTpcTofNSigmaKa = candidate.tpcTofNSigmaKa1(); + float valueTpcTofNSigmaPi; + if (candFlag == 0) { + chi2primProton = candidate.kfChi2PrimProng0(); + chi2primPion = candidate.kfChi2PrimProng2(); + dcaProtonKaon = candidate.kfDcaProng0Prong1(); + dcaPionKaon = candidate.kfDcaProng1Prong2(); + chi2GeoProtonKaon = candidate.kfChi2GeoProng0Prong1(); + chi2GeoPionKaon = candidate.kfChi2GeoProng1Prong2(); + mass = candidate.kfMassPKPi(); + valueTpcNSigmaPr = candidate.nSigTpcPr0(); + valueTpcNSigmaPi = candidate.nSigTpcPi2(); + valueTofNSigmaPr = candidate.nSigTofPr0(); + valueTofNSigmaPi = candidate.nSigTofPi2(); + valueTpcTofNSigmaPr = candidate.tpcTofNSigmaPr0(); + valueTpcTofNSigmaPi = candidate.tpcTofNSigmaPi2(); + } else { + chi2primProton = candidate.kfChi2PrimProng2(); + chi2primPion = candidate.kfChi2PrimProng0(); + dcaProtonKaon = candidate.kfDcaProng1Prong2(); + dcaPionKaon = candidate.kfDcaProng0Prong1(); + chi2GeoProtonKaon = candidate.kfChi2GeoProng1Prong2(); + chi2GeoPionKaon = candidate.kfChi2GeoProng0Prong1(); + mass = candidate.kfMassPiKP(); + valueTpcNSigmaPr = candidate.nSigTpcPr2(); + valueTpcNSigmaPi = candidate.nSigTpcPi0(); + valueTofNSigmaPr = candidate.nSigTofPr2(); + valueTofNSigmaPi = candidate.nSigTofPi0(); + valueTpcTofNSigmaPr = candidate.tpcTofNSigmaPr2(); + valueTpcTofNSigmaPi = candidate.tpcTofNSigmaPi0(); + } const float svX = candidate.xSecondaryVertex(); const float svY = candidate.ySecondaryVertex(); const float svZ = candidate.zSecondaryVertex(); @@ -623,18 +725,12 @@ struct HfTreeCreatorLcToPKPi { const float pvErrX = candidate.kfXPVError(); const float pvErrY = candidate.kfYPVError(); const float pvErrZ = candidate.kfZPVError(); - const float chi2primProton = CandFlag == 0 ? candidate.kfChi2PrimProng0() : candidate.kfChi2PrimProng2(); const float chi2primKaon = candidate.kfChi2PrimProng1(); - const float chi2primPion = CandFlag == 0 ? candidate.kfChi2PrimProng2() : candidate.kfChi2PrimProng0(); - const float dcaProtonKaon = CandFlag == 0 ? candidate.kfDcaProng0Prong1() : candidate.kfDcaProng1Prong2(); const float dcaProtonPion = candidate.kfDcaProng0Prong2(); - const float dcaPionKaon = CandFlag == 0 ? candidate.kfDcaProng1Prong2() : candidate.kfDcaProng0Prong1(); - const float chi2GeoProtonKaon = CandFlag == 0 ? candidate.kfChi2GeoProng0Prong1() : candidate.kfChi2GeoProng1Prong2(); const float chi2GeoProtonPion = candidate.kfChi2GeoProng0Prong2(); - const float chi2GeoPionKaon = CandFlag == 0 ? candidate.kfChi2GeoProng1Prong2() : candidate.kfChi2GeoProng0Prong1(); const float chi2Geo = candidate.kfChi2Geo(); const float chi2Topo = candidate.kfChi2Topo(); - const float l = candidate.kfDecayLength(); + const float decayLength = candidate.kfDecayLength(); const float dl = candidate.kfDecayLengthError(); const float pt = std::sqrt(candidate.kfPx() * candidate.kfPx() + candidate.kfPy() * candidate.kfPy()); const float deltaPt = std::sqrt(candidate.kfPx() * candidate.kfPx() * candidate.kfErrorPx() * candidate.kfErrorPx() + @@ -644,21 +740,30 @@ struct HfTreeCreatorLcToPKPi { const float deltaP = std::sqrt(pt * pt * deltaPt * deltaPt + candidate.kfPz() * candidate.kfPz() * candidate.kfErrorPz() * candidate.kfErrorPz()) / p; - const float t = l * MassLambdaCPlus / LightSpeedCm2PS / p; + const float lifetime = decayLength * MassLambdaCPlus / LightSpeedCm2PS / p; const float deltaT = dl * MassLambdaCPlus / LightSpeedCm2PS / p; - const float mass = CandFlag == 0 ? candidate.kfMassPKPi() : candidate.kfMassPiKP(); rowCandidateKF( svX, svY, svZ, svErrX, svErrY, svErrZ, pvErrX, pvErrY, pvErrZ, chi2primProton, chi2primKaon, chi2primPion, dcaProtonKaon, dcaProtonPion, dcaPionKaon, chi2GeoProtonKaon, chi2GeoProtonPion, chi2GeoPionKaon, - chi2Geo, chi2Topo, l, dl, l / dl, t, deltaT, + chi2Geo, chi2Topo, decayLength, dl, decayLength / dl, lifetime, deltaT, mass, p, pt, deltaP, deltaPt, - FunctionSelection, sigbgstatus); + functionSelection, sigbgstatus, + collision.multNTracksPV(), + valueTpcNSigmaPr, + valueTpcNSigmaKa, + valueTpcNSigmaPi, + valueTofNSigmaPr, + valueTofNSigmaKa, + valueTofNSigmaPi, + valueTpcTofNSigmaPr, + valueTpcTofNSigmaKa, + valueTpcTofNSigmaPi); } if (fillCandidateMcTable) { - float p, pt, svX, svY, svZ, pvX, pvY, pvZ, l, t; + float p, pt, svX, svY, svZ, pvX, pvY, pvZ, decayLength, lifetime; if (!isMcCandidateSignal) { p = UndefValueFloat; pt = UndefValueFloat; @@ -668,8 +773,8 @@ struct HfTreeCreatorLcToPKPi { pvX = UndefValueFloat; pvY = UndefValueFloat; pvZ = UndefValueFloat; - l = UndefValueFloat; - t = UndefValueFloat; + decayLength = UndefValueFloat; + lifetime = UndefValueFloat; } else { auto mcParticleProng0 = candidate.template prong0_as>().template mcParticle_as>(); auto indexMother = RecoDecay::getMother(particles, mcParticleProng0, o2::constants::physics::Pdg::kLambdaCPlus, true); @@ -685,12 +790,12 @@ struct HfTreeCreatorLcToPKPi { svX = mcParticleProng0.vx(); svY = mcParticleProng0.vy(); svZ = mcParticleProng0.vz(); - l = std::sqrt((svX - pvX) * (svX - pvX) + (svY - pvY) * (svY - pvY) + (svZ - pvZ) * (svZ - pvZ)); - t = mcParticleProng0.vt() * NanoToPico / gamma; // from ns to ps * from lab time to proper time + decayLength = RecoDecay::distance(std::array{svX, svY, svZ}, std::array{pvX, pvY, pvZ}); + lifetime = mcParticleProng0.vt() * NanoToPico / gamma; // from ns to ps * from lab time to proper time } rowCandidateMC( p, pt, - svX, svY, svZ, l, t, + svX, svY, svZ, decayLength, lifetime, pvX, pvY, pvZ); } } @@ -704,13 +809,29 @@ struct HfTreeCreatorLcToPKPi { rowCandidateFullParticles.reserve(particles.size()); for (const auto& particle : particles) { if (std::abs(particle.flagMcMatchGen()) == 1 << aod::hf_cand_3prong::DecayType::LcToPKPi) { + auto mcDaughter0 = particle.template daughters_as>().begin(); + auto mcCollision = particle.template mcCollision_as(); + auto p = particle.p(); + const float p2m = p / MassLambdaCPlus; + const float gamma = std::sqrt(1 + p2m * p2m); // mother's particle Lorentz factor + const float pvX = mcCollision.posX(); + const float pvY = mcCollision.posY(); + const float pvZ = mcCollision.posZ(); + const float svX = mcDaughter0.vx(); + const float svY = mcDaughter0.vy(); + const float svZ = mcDaughter0.vz(); + const float l = RecoDecay::distance(std::array{svX, svY, svZ}, std::array{pvX, pvY, pvZ}); + const float t = mcDaughter0.vt() * NanoToPico / gamma; // from ns to ps * from lab time to proper time rowCandidateFullParticles( particle.pt(), particle.eta(), particle.phi(), RecoDecay::y(particle.pVector(), o2::constants::physics::MassLambdaCPlus), particle.flagMcMatchGen(), - particle.originMcGen()); + particle.originMcGen(), + p, + svX, svY, svZ, l, t, + pvX, pvY, pvZ); } } } @@ -722,9 +843,9 @@ struct HfTreeCreatorLcToPKPi { /// \param particles Generated particle table /// \param tracks Track table /// \param bcs Bunch-crossing table - void processMcNoCentralityWithDCAFitterN(soa::Join const& collisions, + void processMcNoCentralityWithDCAFitterN(soa::Join const& collisions, aod::McCollisions const& mcCollisions, - soa::Join const& candidates, + soa::Join const& candidates, soa::Join const& particles, soa::Join const& tracks, aod::BCs const& bcs) { @@ -738,9 +859,9 @@ struct HfTreeCreatorLcToPKPi { /// \param candidates Lc->pKpi candidate table /// \param tracks Track table /// \param bcs Bunch-crossing table - void processMcWithCentralityWithDCAFitterN(soa::Join const& collisions, + void processMcWithCentralityWithDCAFitterN(soa::Join const& collisions, aod::McCollisions const& mcCollisions, - soa::Join const& candidates, + soa::Join const& candidates, soa::Join const& particles, soa::Join const& tracks, aod::BCs const& bcs) { @@ -755,9 +876,9 @@ struct HfTreeCreatorLcToPKPi { /// \param particles Generated particle table /// \param tracks Track table /// \param bcs Bunch-crossing table - void processMcNoCentralityWithKFParticle(soa::Join const& collisions, + void processMcNoCentralityWithKFParticle(soa::Join const& collisions, aod::McCollisions const& mcCollisions, - soa::Join const& candidates, + soa::Join const& candidates, soa::Join const& particles, soa::Join const& tracks, aod::BCs const& bcs) { @@ -771,9 +892,9 @@ struct HfTreeCreatorLcToPKPi { /// \param candidates Lc->pKpi candidate table /// \param tracks Track table /// \param bcs Bunch-crossing table - void processMcWithCentralityWithKFParticle(soa::Join const& collisions, + void processMcWithCentralityWithKFParticle(soa::Join const& collisions, aod::McCollisions const& mcCollisions, - soa::Join const& candidates, + soa::Join const& candidates, soa::Join const& particles, soa::Join const& tracks, aod::BCs const& bcs) { @@ -814,6 +935,12 @@ struct HfTreeCreatorLcToPKPi { collision.posX(), collision.posY(), collision.posZ(), + std::sqrt(collision.covXX()), + std::sqrt(collision.covYY()), + std::sqrt(collision.covZZ()), + UndefValueFloat, + UndefValueFloat, + UndefValueFloat, 0, collision.bc().runNumber(), centFT0A, @@ -821,7 +948,8 @@ struct HfTreeCreatorLcToPKPi { centFT0M, centFV0A, centFDDM, - collision.multZeqNTracksPV()); + collision.multZeqNTracksPV(), + collision.multNTracksPV()); } // Filling candidate properties @@ -839,24 +967,23 @@ struct HfTreeCreatorLcToPKPi { rowCollisionId.reserve(candidates.size()); } for (const auto& candidate : candidates) { - auto trackPos1 = candidate.template prong0_as(); // positive daughter (negative for the antiparticles) - auto trackNeg = candidate.template prong1_as(); // negative daughter (positive for the antiparticles) - auto trackPos2 = candidate.template prong2_as(); // positive daughter (negative for the antiparticles) - auto fillTable = [&](int CandFlag) { - double pseudoRndm = trackPos1.pt() * 1000. - static_cast(trackPos1.pt() * 1000); - const int FunctionSelection = CandFlag == 0 ? candidate.isSelLcToPKPi() : candidate.isSelLcToPiKP(); - if (FunctionSelection >= selectionFlagLc && (candidate.pt() > downSampleBkgPtMax || (pseudoRndm < downSampleBkgFactor && candidate.pt() < downSampleBkgPtMax))) { - float FunctionInvMass, FunctionInvMassKPi; + float ptProng0 = candidate.ptProng0(); + auto collision = candidate.template collision_as(); + auto fillTable = [&](int candFlag) { + double pseudoRndm = ptProng0 * 1000. - static_cast(ptProng0 * 1000); + const int functionSelection = candFlag == 0 ? candidate.isSelLcToPKPi() : candidate.isSelLcToPiKP(); + if (functionSelection >= selectionFlagLc && (candidate.pt() > downSampleBkgPtMax || (pseudoRndm < downSampleBkgFactor && candidate.pt() < downSampleBkgPtMax))) { + float functionInvMass, functionInvMassKPi; if constexpr (reconstructionType == aod::hf_cand::VertexerType::DCAFitter) { - FunctionInvMass = CandFlag == 0 ? hfHelper.invMassLcToPKPi(candidate) : hfHelper.invMassLcToPiKP(candidate); - FunctionInvMassKPi = CandFlag == 0 ? hfHelper.invMassKPiPairLcToPKPi(candidate) : hfHelper.invMassKPiPairLcToPiKP(candidate); + functionInvMass = candFlag == 0 ? hfHelper.invMassLcToPKPi(candidate) : hfHelper.invMassLcToPiKP(candidate); + functionInvMassKPi = candFlag == 0 ? hfHelper.invMassKPiPairLcToPKPi(candidate) : hfHelper.invMassKPiPairLcToPiKP(candidate); } else { - FunctionInvMass = CandFlag == 0 ? candidate.kfMassPKPi() : candidate.kfMassPiKP(); - FunctionInvMassKPi = CandFlag == 0 ? candidate.kfMassKPi() : candidate.kfMassPiK(); + functionInvMass = candFlag == 0 ? candidate.kfMassPKPi() : candidate.kfMassPiKP(); + functionInvMassKPi = candFlag == 0 ? candidate.kfMassKPi() : candidate.kfMassPiK(); } - const float FunctionCt = hfHelper.ctLc(candidate); - const float FunctionY = hfHelper.yLc(candidate); - const float FunctionE = hfHelper.eLc(candidate); + const float functionCt = hfHelper.ctLc(candidate); + const float functionY = hfHelper.yLc(candidate); + const float functionE = hfHelper.eLc(candidate); if (fillCandidateLiteTable) { rowCandidateLite( candidate.posX(), @@ -873,35 +1000,35 @@ struct HfTreeCreatorLcToPKPi { candidate.impactParameter0(), candidate.impactParameter1(), candidate.impactParameter2(), - trackPos1.tpcNSigmaPi(), - trackPos1.tpcNSigmaPr(), - trackPos1.tofNSigmaPi(), - trackPos1.tofNSigmaPr(), - trackNeg.tpcNSigmaKa(), - trackNeg.tofNSigmaKa(), - trackPos2.tpcNSigmaPi(), - trackPos2.tpcNSigmaPr(), - trackPos2.tofNSigmaPi(), - trackPos2.tofNSigmaPr(), - trackPos1.tpcTofNSigmaPi(), - trackPos1.tpcTofNSigmaPr(), - trackNeg.tpcTofNSigmaKa(), - trackPos2.tpcTofNSigmaPi(), - trackPos2.tpcTofNSigmaPr(), - 1 << CandFlag, - FunctionInvMass, + candidate.nSigTpcPi0(), + candidate.nSigTpcPr0(), + candidate.nSigTofPi0(), + candidate.nSigTofPr0(), + candidate.nSigTpcKa1(), + candidate.nSigTofKa1(), + candidate.nSigTpcPi2(), + candidate.nSigTpcPr2(), + candidate.nSigTofPi2(), + candidate.nSigTofPr2(), + candidate.tpcTofNSigmaPi0(), + candidate.tpcTofNSigmaPr0(), + candidate.tpcTofNSigmaKa1(), + candidate.tpcTofNSigmaPi2(), + candidate.tpcTofNSigmaPr2(), + 1 << candFlag, + functionInvMass, candidate.pt(), candidate.cpa(), candidate.cpaXY(), - FunctionCt, + functionCt, candidate.eta(), candidate.phi(), - FunctionY, + functionY, 0., 0., 0., -1, - FunctionInvMassKPi); + functionInvMassKPi); if (fillCollIdTable) { /// save also candidate collision indices @@ -951,59 +1078,98 @@ struct HfTreeCreatorLcToPKPi { candidate.errorImpactParameter0(), candidate.errorImpactParameter1(), candidate.errorImpactParameter2(), - trackPos1.tpcNSigmaPi(), - trackPos1.tpcNSigmaPr(), - trackPos1.tofNSigmaPi(), - trackPos1.tofNSigmaPr(), - trackNeg.tpcNSigmaKa(), - trackNeg.tofNSigmaKa(), - trackPos2.tpcNSigmaPi(), - trackPos2.tpcNSigmaPr(), - trackPos2.tofNSigmaPi(), - trackPos2.tofNSigmaPr(), - trackPos1.tpcTofNSigmaPi(), - trackPos1.tpcTofNSigmaPr(), - trackNeg.tpcTofNSigmaKa(), - trackPos2.tpcTofNSigmaPi(), - trackPos2.tpcTofNSigmaPr(), - 1 << CandFlag, - FunctionInvMass, + candidate.nSigTpcPi0(), + candidate.nSigTpcPr0(), + candidate.nSigTofPi0(), + candidate.nSigTofPr0(), + candidate.nSigTpcKa1(), + candidate.nSigTofKa1(), + candidate.nSigTpcPi2(), + candidate.nSigTpcPr2(), + candidate.nSigTofPi2(), + candidate.nSigTofPr2(), + candidate.tpcTofNSigmaPi0(), + candidate.tpcTofNSigmaPr0(), + candidate.tpcTofNSigmaKa1(), + candidate.tpcTofNSigmaPi2(), + candidate.tpcTofNSigmaPr2(), + 1 << candFlag, + functionInvMass, candidate.pt(), candidate.p(), candidate.cpa(), candidate.cpaXY(), - FunctionCt, + functionCt, candidate.eta(), candidate.phi(), - FunctionY, - FunctionE, + functionY, + functionE, 0., 0., 0., candidate.globalIndex(), -1, - FunctionInvMassKPi); + functionInvMassKPi); } if constexpr (reconstructionType == aod::hf_cand::VertexerType::KfParticle) { - const float X = candidate.xSecondaryVertex(); - const float Y = candidate.ySecondaryVertex(); - const float Z = candidate.zSecondaryVertex(); - const float ErrX = candidate.kfXError(); - const float ErrY = candidate.kfYError(); - const float ErrZ = candidate.kfZError(); - const float ErrPVX = candidate.kfXPVError(); - const float ErrPVY = candidate.kfYPVError(); - const float ErrPVZ = candidate.kfZPVError(); - const float chi2prim_proton = CandFlag == 0 ? candidate.kfChi2PrimProng0() : candidate.kfChi2PrimProng2(); - const float chi2prim_kaon = candidate.kfChi2PrimProng1(); - const float chi2prim_pion = CandFlag == 0 ? candidate.kfChi2PrimProng2() : candidate.kfChi2PrimProng0(); - const float dca_proton_kaon = CandFlag == 0 ? candidate.kfDcaProng0Prong1() : candidate.kfDcaProng1Prong2(); - const float dca_proton_pion = candidate.kfDcaProng0Prong2(); - const float dca_pion_kaon = CandFlag == 0 ? candidate.kfDcaProng1Prong2() : candidate.kfDcaProng0Prong1(); - const float chi2Geo_proton_kaon = CandFlag == 0 ? candidate.kfChi2GeoProng0Prong1() : candidate.kfChi2GeoProng1Prong2(); - const float chi2Geo_proton_pion = candidate.kfChi2GeoProng0Prong2(); - const float chi2Geo_pion_kaon = CandFlag == 0 ? candidate.kfChi2GeoProng1Prong2() : candidate.kfChi2GeoProng0Prong1(); + float chi2primProton; + float chi2primPion; + float dcaProtonKaon; + float dcaPionKaon; + float chi2GeoProtonKaon; + float chi2GeoPionKaon; + float mass; + float valueTpcNSigmaPr; + const float valueTpcNSigmaKa = candidate.nSigTpcKa1(); + float valueTpcNSigmaPi; + float valueTofNSigmaPr; + const float valueTofNSigmaKa = candidate.nSigTofKa1(); + float valueTofNSigmaPi; + float valueTpcTofNSigmaPr; + const float valueTpcTofNSigmaKa = candidate.tpcTofNSigmaKa1(); + float valueTpcTofNSigmaPi; + if (candFlag == 0) { + chi2primProton = candidate.kfChi2PrimProng0(); + chi2primPion = candidate.kfChi2PrimProng2(); + dcaProtonKaon = candidate.kfDcaProng0Prong1(); + dcaPionKaon = candidate.kfDcaProng1Prong2(); + chi2GeoProtonKaon = candidate.kfChi2GeoProng0Prong1(); + chi2GeoPionKaon = candidate.kfChi2GeoProng1Prong2(); + mass = candidate.kfMassPKPi(); + valueTpcNSigmaPr = candidate.nSigTpcPr0(); + valueTpcNSigmaPi = candidate.nSigTpcPi2(); + valueTofNSigmaPr = candidate.nSigTofPr0(); + valueTofNSigmaPi = candidate.nSigTofPi2(); + valueTpcTofNSigmaPr = candidate.tpcTofNSigmaPr0(); + valueTpcTofNSigmaPi = candidate.tpcTofNSigmaPi2(); + } else { + chi2primProton = candidate.kfChi2PrimProng2(); + chi2primPion = candidate.kfChi2PrimProng0(); + dcaProtonKaon = candidate.kfDcaProng1Prong2(); + dcaPionKaon = candidate.kfDcaProng0Prong1(); + chi2GeoProtonKaon = candidate.kfChi2GeoProng1Prong2(); + chi2GeoPionKaon = candidate.kfChi2GeoProng0Prong1(); + mass = candidate.kfMassPiKP(); + valueTpcNSigmaPr = candidate.nSigTpcPr2(); + valueTpcNSigmaPi = candidate.nSigTpcPi0(); + valueTofNSigmaPr = candidate.nSigTofPr2(); + valueTofNSigmaPi = candidate.nSigTofPi0(); + valueTpcTofNSigmaPr = candidate.tpcTofNSigmaPr2(); + valueTpcTofNSigmaPi = candidate.tpcTofNSigmaPi0(); + } + const float x = candidate.xSecondaryVertex(); + const float y = candidate.ySecondaryVertex(); + const float z = candidate.zSecondaryVertex(); + const float errX = candidate.kfXError(); + const float errY = candidate.kfYError(); + const float errZ = candidate.kfZError(); + const float errPVX = candidate.kfXPVError(); + const float errPVY = candidate.kfYPVError(); + const float errPVZ = candidate.kfZPVError(); + const float chi2primKaon = candidate.kfChi2PrimProng1(); + const float dcaProtonPion = candidate.kfDcaProng0Prong2(); + const float chi2GeoProtonPion = candidate.kfChi2GeoProng0Prong2(); const float chi2Geo = candidate.kfChi2Geo(); const float chi2Topo = candidate.kfChi2Topo(); const float l = candidate.kfDecayLength(); @@ -1016,18 +1182,27 @@ struct HfTreeCreatorLcToPKPi { const float deltaP = std::sqrt(pt * pt * deltaPt * deltaPt + candidate.kfPz() * candidate.kfPz() * candidate.kfErrorPz() * candidate.kfErrorPz()) / p; - const float T = l * MassLambdaCPlus / LightSpeedCm2PS / p; + const float t = l * MassLambdaCPlus / LightSpeedCm2PS / p; const float deltaT = dl * MassLambdaCPlus / LightSpeedCm2PS / p; - const float mass = CandFlag == 0 ? candidate.kfMassPKPi() : candidate.kfMassPiKP(); rowCandidateKF( - X, Y, Z, ErrX, ErrY, ErrZ, - ErrPVX, ErrPVY, ErrPVZ, - chi2prim_proton, chi2prim_kaon, chi2prim_pion, - dca_proton_kaon, dca_proton_pion, dca_pion_kaon, - chi2Geo_proton_kaon, chi2Geo_proton_pion, chi2Geo_pion_kaon, - chi2Geo, chi2Topo, l, dl, l / dl, T, deltaT, + x, y, z, errX, errY, errZ, + errPVX, errPVY, errPVZ, + chi2primProton, chi2primKaon, chi2primPion, + dcaProtonKaon, dcaProtonPion, dcaPionKaon, + chi2GeoProtonKaon, chi2GeoProtonPion, chi2GeoPionKaon, + chi2Geo, chi2Topo, l, dl, l / dl, t, deltaT, mass, p, pt, deltaP, deltaPt, - FunctionSelection, UndefValueInt); + functionSelection, UndefValueInt, + collision.multNTracksPV(), + valueTpcNSigmaPr, + valueTpcNSigmaKa, + valueTpcNSigmaPi, + valueTofNSigmaPr, + valueTofNSigmaKa, + valueTofNSigmaPi, + valueTpcTofNSigmaPr, + valueTpcTofNSigmaKa, + valueTpcTofNSigmaPi); } } }; @@ -1042,8 +1217,8 @@ struct HfTreeCreatorLcToPKPi { /// \param candidates Lc->pKpi candidate table /// \param tracks Track table /// \param bcs Bunch-crossing table - void processDataNoCentralityWithDCAFitterN(soa::Join const& collisions, - soa::Join const& candidates, + void processDataNoCentralityWithDCAFitterN(soa::Join const& collisions, + soa::Join const& candidates, TracksWPid const& tracks, aod::BCs const& bcs) { fillTablesData(collisions, candidates, tracks, bcs); @@ -1055,8 +1230,8 @@ struct HfTreeCreatorLcToPKPi { /// \param candidates Lc->pKpi candidate table /// \param tracks Track table /// \param bcs Bunch-crossing table - void processDataWithCentralityWithDCAFitterN(soa::Join const& collisions, - soa::Join const& candidates, + void processDataWithCentralityWithDCAFitterN(soa::Join const& collisions, + soa::Join const& candidates, TracksWPid const& tracks, aod::BCs const& bcs) { fillTablesData(collisions, candidates, tracks, bcs); @@ -1068,8 +1243,8 @@ struct HfTreeCreatorLcToPKPi { /// \param candidates Lc->pKpi candidate table /// \param tracks Track table /// \param bcs Bunch-crossing table - void processDataNoCentralityWithKFParticle(soa::Join const& collisions, - soa::Join const& candidates, + void processDataNoCentralityWithKFParticle(soa::Join const& collisions, + soa::Join const& candidates, TracksWPid const& tracks, aod::BCs const& bcs) { fillTablesData(collisions, candidates, tracks, bcs); @@ -1081,8 +1256,8 @@ struct HfTreeCreatorLcToPKPi { /// \param candidates Lc->pKpi candidate table /// \param tracks Track table /// \param bcs Bunch-crossing table - void processDataWithCentralityWithKFParticle(soa::Join const& collisions, - soa::Join const& candidates, + void processDataWithCentralityWithKFParticle(soa::Join const& collisions, + soa::Join const& candidates, TracksWPid const& tracks, aod::BCs const& bcs) { fillTablesData(collisions, candidates, tracks, bcs); diff --git a/PWGHF/TableProducer/treeCreatorXicToPKPi.cxx b/PWGHF/TableProducer/treeCreatorXicToPKPi.cxx index 915cfba1bda..94ad232d565 100644 --- a/PWGHF/TableProducer/treeCreatorXicToPKPi.cxx +++ b/PWGHF/TableProducer/treeCreatorXicToPKPi.cxx @@ -226,10 +226,9 @@ struct HfTreeCreatorXicToPKPi { HfHelper hfHelper; - using CandXicData = soa::Filtered>; - using CandXicMcReco = soa::Filtered>; + using CandXicData = soa::Filtered>; + using CandXicMcReco = soa::Filtered>; using CandXicMcGen = soa::Filtered>; - using TracksWPid = soa::Join; Filter filterSelectCandidates = aod::hf_sel_candidate_xic::isSelXicToPKPi >= selectionFlagXic || aod::hf_sel_candidate_xic::isSelXicToPiKP >= selectionFlagXic; Filter filterMcGenMatching = nabs(o2::aod::hf_cand_3prong::flagMcMatchGen) == static_cast(BIT(aod::hf_cand_3prong::DecayType::XicToPKPi)); @@ -279,10 +278,6 @@ struct HfTreeCreatorXicToPKPi { invMassXic = hfHelper.invMassXicToPiKP(candidate); } - auto trackPos1 = candidate.template prong0_as(); // positive daughter (negative for the antiparticles) - auto trackNeg = candidate.template prong1_as(); // negative daughter (positive for the antiparticles) - auto trackPos2 = candidate.template prong2_as(); // positive daughter (negative for the antiparticles) - if (fillCandidateLiteTable) { rowCandidateLite( candidate.chi2PCA(), @@ -296,21 +291,21 @@ struct HfTreeCreatorXicToPKPi { candidate.impactParameter0(), candidate.impactParameter1(), candidate.impactParameter2(), - trackPos1.tpcNSigmaPi(), - trackPos1.tpcNSigmaPr(), - trackPos1.tofNSigmaPi(), - trackPos1.tofNSigmaPr(), - trackNeg.tpcNSigmaKa(), - trackNeg.tofNSigmaKa(), - trackPos2.tpcNSigmaPi(), - trackPos2.tpcNSigmaPr(), - trackPos2.tofNSigmaPi(), - trackPos2.tofNSigmaPr(), - trackPos1.tpcTofNSigmaPi(), - trackPos1.tpcTofNSigmaPr(), - trackNeg.tpcTofNSigmaKa(), - trackPos2.tpcTofNSigmaPi(), - trackPos2.tpcTofNSigmaPr(), + candidate.nSigTpcPi0(), + candidate.nSigTpcPr0(), + candidate.nSigTofPi0(), + candidate.nSigTofPr0(), + candidate.nSigTpcKa1(), + candidate.nSigTofKa1(), + candidate.nSigTpcPi2(), + candidate.nSigTpcPr2(), + candidate.nSigTofPi2(), + candidate.nSigTofPr2(), + candidate.tpcTofNSigmaPi0(), + candidate.tpcTofNSigmaPr0(), + candidate.tpcTofNSigmaKa1(), + candidate.tpcTofNSigmaPi2(), + candidate.tpcTofNSigmaPr2(), candidate.isSelXicToPKPi(), candidate.isSelXicToPiKP(), invMassXic, @@ -363,21 +358,21 @@ struct HfTreeCreatorXicToPKPi { candidate.errorImpactParameter0(), candidate.errorImpactParameter1(), candidate.errorImpactParameter2(), - trackPos1.tpcNSigmaPi(), - trackPos1.tpcNSigmaPr(), - trackPos1.tofNSigmaPi(), - trackPos1.tofNSigmaPr(), - trackNeg.tpcNSigmaKa(), - trackNeg.tofNSigmaKa(), - trackPos2.tpcNSigmaPi(), - trackPos2.tpcNSigmaPr(), - trackPos2.tofNSigmaPi(), - trackPos2.tofNSigmaPr(), - trackPos1.tpcTofNSigmaPi(), - trackPos1.tpcTofNSigmaPr(), - trackNeg.tpcTofNSigmaKa(), - trackPos2.tpcTofNSigmaPi(), - trackPos2.tpcTofNSigmaPr(), + candidate.nSigTpcPi0(), + candidate.nSigTpcPr0(), + candidate.nSigTofPi0(), + candidate.nSigTofPr0(), + candidate.nSigTpcKa1(), + candidate.nSigTofKa1(), + candidate.nSigTpcPi2(), + candidate.nSigTpcPr2(), + candidate.nSigTofPi2(), + candidate.nSigTofPr2(), + candidate.tpcTofNSigmaPi0(), + candidate.tpcTofNSigmaPr0(), + candidate.tpcTofNSigmaKa1(), + candidate.tpcTofNSigmaPi2(), + candidate.tpcTofNSigmaPr2(), candidate.isSelXicToPKPi(), candidate.isSelXicToPiKP(), invMassXic, @@ -397,8 +392,7 @@ struct HfTreeCreatorXicToPKPi { } void processData(aod::Collisions const& collisions, - CandXicData const&, - TracksWPid const&) + CandXicData const&) { // Filling event properties rowCandidateFullEvents.reserve(collisions.size()); @@ -438,8 +432,7 @@ struct HfTreeCreatorXicToPKPi { void processMc(aod::Collisions const& collisions, aod::McCollisions const&, CandXicMcReco const&, - CandXicMcGen const& mcParticles, - TracksWPid const&) + CandXicMcGen const& mcParticles) { // Filling event properties rowCandidateFullEvents.reserve(collisions.size()); diff --git a/PWGHF/Tasks/taskPidStudies.cxx b/PWGHF/Tasks/taskPidStudies.cxx index 55e3bef23ac..6f5056d9a9c 100644 --- a/PWGHF/Tasks/taskPidStudies.cxx +++ b/PWGHF/Tasks/taskPidStudies.cxx @@ -18,6 +18,7 @@ /// \author Luca Aglietta , Università and INFN Torino #include +#include #include "TPDGCode.h" @@ -42,14 +43,25 @@ using namespace o2::framework::expressions; using namespace o2::hf_evsel; using namespace o2::hf_centrality; -namespace o2::aod -{ -namespace pid_studies -{ enum Particle { NotMatched = 0, K0s, Lambda, Omega }; + +enum TrackCuts { All = 0, + HasIts, + HasTpc, + TpcNClsCrossedRows, + Eta, + Pt, + TpcChi2NCls, + ItsChi2NCls, + NCuts }; + +namespace o2::aod +{ +namespace pid_studies +{ // V0s DECLARE_SOA_COLUMN(MassK0, massK0, float); //! Candidate mass DECLARE_SOA_COLUMN(MassLambda, massLambda, float); //! Candidate mass @@ -91,12 +103,6 @@ DECLARE_SOA_COLUMN(OccupancyIts, occupancyIts, float); //! Occupancy from IT DECLARE_SOA_COLUMN(CentralityFT0C, centralityFT0C, float); //! Centrality from FT0C DECLARE_SOA_COLUMN(CentralityFT0M, centralityFT0M, float); //! Centrality from FT0M DECLARE_SOA_COLUMN(CandFlag, candFlag, int); //! Flag for MC matching - -const int minTpcNClsCrossedRows = 70; // Minimum number of crossed rows in TPC -const float maxEta = 0.8; // Maximum pseudorapidity -const float minPt = 0.1; // Minimum transverse momentum -const float maxTpcChi2NCl = 4; // Maximum TPC chi2 per number of TPC clusters -const float maxItsChi2NCl = 36; // Maximum ITS chi2 per number of ITS clusters } // namespace pid_studies DECLARE_SOA_TABLE(PidV0s, "AOD", "PIDV0S", //! Table with PID information @@ -155,6 +161,11 @@ struct HfTaskPidStudies { Configurable applyEvSels{"applyEvSels", true, "Apply event selections"}; Configurable applyTrackSels{"applyTrackSels", true, "Apply track selections"}; + Configurable tpcNClsCrossedRowsTrackMin{"tpcNClsCrossedRowsTrackMin", 70, "Minimum number of crossed rows in TPC"}; + Configurable etaTrackMax{"etaTrackMax", 0.8, "Maximum pseudorapidity"}; + Configurable ptTrackMin{"ptTrackMin", 0.1, "Minimum transverse momentum"}; + Configurable tpcChi2NClTrackMax{"tpcChi2NClTrackMax", 4, "Maximum TPC chi2 per number of TPC clusters"}; + Configurable itsChi2NClTrackMax{"itsChi2NClTrackMax", 36, "Maximum ITS chi2 per number of ITS clusters"}; Configurable massK0Min{"massK0Min", 0.4, "Minimum mass for K0"}; Configurable massK0Max{"massK0Max", 0.6, "Maximum mass for K0"}; Configurable massLambdaMin{"massLambdaMin", 1.0, "Minimum mass for lambda"}; @@ -195,6 +206,18 @@ struct HfTaskPidStudies { ccdb->setCaching(true); ccdb->setLocalObjectValidityChecking(); hfEvSel.addHistograms(registry); + + std::shared_ptr hTrackSel = registry.add("hTrackSel", "Track selection;;Counts", {HistType::kTH1F, {{TrackCuts::NCuts, 0, TrackCuts::NCuts}}}); + + // Set Labels for hTrackSel + hTrackSel->GetXaxis()->SetBinLabel(TrackCuts::All + 1, "All"); + hTrackSel->GetXaxis()->SetBinLabel(TrackCuts::HasIts + 1, "HasITS"); + hTrackSel->GetXaxis()->SetBinLabel(TrackCuts::HasTpc + 1, "HasTPC"); + hTrackSel->GetXaxis()->SetBinLabel(TrackCuts::TpcNClsCrossedRows + 1, "TPC NCls/CrossedRows"); + hTrackSel->GetXaxis()->SetBinLabel(TrackCuts::Eta + 1, "#eta"); + hTrackSel->GetXaxis()->SetBinLabel(TrackCuts::Pt + 1, "#it{p}_{T}"); + hTrackSel->GetXaxis()->SetBinLabel(TrackCuts::TpcChi2NCls + 1, "TPC #chi^{2}/NCls"); + hTrackSel->GetXaxis()->SetBinLabel(TrackCuts::ItsChi2NCls + 1, "ITS #chi^{2}/NCls"); } template @@ -266,22 +289,22 @@ struct HfTaskPidStudies { { if constexpr (std::is_same::value) { if (!cand.has_v0MCCore()) { - return aod::pid_studies::Particle::NotMatched; + return Particle::NotMatched; } auto v0MC = cand.template v0MCCore_as(); if (v0MC.pdgCode() == kK0Short && v0MC.pdgCodeNegative() == -kPiPlus && v0MC.pdgCodePositive() == kPiPlus) { - return aod::pid_studies::Particle::K0s; + return Particle::K0s; } if (v0MC.pdgCode() == kLambda0 && v0MC.pdgCodeNegative() == -kPiPlus && v0MC.pdgCodePositive() == kProton) { - return aod::pid_studies::Particle::Lambda; + return Particle::Lambda; } if (v0MC.pdgCode() == -kLambda0 && v0MC.pdgCodeNegative() == -kProton && v0MC.pdgCodePositive() == kPiPlus) { - return -aod::pid_studies::Particle::Lambda; + return -Particle::Lambda; } } if constexpr (std::is_same::value) { if (!cand.has_cascMCCore()) { - return aod::pid_studies::Particle::NotMatched; + return Particle::NotMatched; } auto cascMC = cand.template cascMCCore_as(); if (cascMC.pdgCode() == kOmegaMinus && @@ -289,17 +312,17 @@ struct HfTaskPidStudies { cascMC.pdgCodeV0() == kLambda0 && cascMC.pdgCodePositive() == kProton && cascMC.pdgCodeNegative() == -kPiPlus) { - return aod::pid_studies::Particle::Omega; + return Particle::Omega; } if (cascMC.pdgCode() == -kOmegaMinus && cascMC.pdgCodeBachelor() == kKPlus && cascMC.pdgCodeV0() == -kLambda0 && cascMC.pdgCodePositive() == kPiPlus && cascMC.pdgCodeNegative() == -kProton) { - return -aod::pid_studies::Particle::Omega; + return -Particle::Omega; } } - return aod::pid_studies::Particle::NotMatched; + return Particle::NotMatched; } template @@ -317,38 +340,66 @@ struct HfTaskPidStudies { { const auto& posTrack = candidate.template posTrack_as(); const auto& negTrack = candidate.template negTrack_as(); - if (posTrack.tpcNClsCrossedRows() < o2::aod::pid_studies::minTpcNClsCrossedRows || negTrack.tpcNClsCrossedRows() < o2::aod::pid_studies::minTpcNClsCrossedRows) { - return false; - } - if (std::abs(posTrack.eta()) > o2::aod::pid_studies::maxEta || std::abs(negTrack.eta()) > o2::aod::pid_studies::maxEta) { - return false; - } - if (posTrack.pt() < o2::aod::pid_studies::minPt || negTrack.pt() < o2::aod::pid_studies::minPt) { - return false; - } - if (posTrack.tpcChi2NCl() > o2::aod::pid_studies::maxTpcChi2NCl || negTrack.tpcChi2NCl() > o2::aod::pid_studies::maxTpcChi2NCl) { - return false; - } - if (posTrack.itsChi2NCl() > o2::aod::pid_studies::maxItsChi2NCl || negTrack.itsChi2NCl() > o2::aod::pid_studies::maxItsChi2NCl) { - return false; - } - if constexpr (!isV0) { + registry.fill(HIST("hTrackSel"), TrackCuts::All); + if constexpr (isV0) { + if (!posTrack.hasITS() || !negTrack.hasITS()) { + return false; + } + registry.fill(HIST("hTrackSel"), TrackCuts::HasIts); + if (!posTrack.hasTPC() || !negTrack.hasTPC()) { + return false; + } + registry.fill(HIST("hTrackSel"), TrackCuts::HasTpc); + if (posTrack.tpcNClsCrossedRows() < tpcNClsCrossedRowsTrackMin || negTrack.tpcNClsCrossedRows() < tpcNClsCrossedRowsTrackMin) { + return false; + } + registry.fill(HIST("hTrackSel"), TrackCuts::TpcNClsCrossedRows); + if (std::abs(posTrack.eta()) > etaTrackMax || std::abs(negTrack.eta()) > etaTrackMax) { + return false; + } + registry.fill(HIST("hTrackSel"), TrackCuts::Eta); + if (posTrack.pt() < ptTrackMin || negTrack.pt() < ptTrackMin) { + return false; + } + registry.fill(HIST("hTrackSel"), TrackCuts::Pt); + if (posTrack.tpcChi2NCl() > tpcChi2NClTrackMax || negTrack.tpcChi2NCl() > tpcChi2NClTrackMax) { + return false; + } + registry.fill(HIST("hTrackSel"), TrackCuts::TpcChi2NCls); + if (posTrack.itsChi2NCl() > itsChi2NClTrackMax || negTrack.itsChi2NCl() > itsChi2NClTrackMax) { + return false; + } + registry.fill(HIST("hTrackSel"), TrackCuts::ItsChi2NCls); + } else { const auto& bachTrack = candidate.template bachelor_as(); - if (bachTrack.tpcNClsCrossedRows() < o2::aod::pid_studies::minTpcNClsCrossedRows) { + if (!posTrack.hasITS() || !negTrack.hasITS() || !bachTrack.hasITS()) { + return false; + } + registry.fill(HIST("hTrackSel"), TrackCuts::HasIts); + if (!posTrack.hasTPC() || !negTrack.hasTPC() || !bachTrack.hasTPC()) { + return false; + } + registry.fill(HIST("hTrackSel"), TrackCuts::HasTpc); + if (posTrack.tpcNClsCrossedRows() < tpcNClsCrossedRowsTrackMin || negTrack.tpcNClsCrossedRows() < tpcNClsCrossedRowsTrackMin || bachTrack.tpcNClsCrossedRows() < tpcNClsCrossedRowsTrackMin) { return false; } - if (std::abs(bachTrack.eta()) > o2::aod::pid_studies::maxEta) { + registry.fill(HIST("hTrackSel"), TrackCuts::TpcNClsCrossedRows); + if (std::abs(posTrack.eta()) > etaTrackMax || std::abs(negTrack.eta()) > etaTrackMax || std::abs(bachTrack.eta()) > etaTrackMax) { return false; } - if (bachTrack.pt() < o2::aod::pid_studies::minPt) { + registry.fill(HIST("hTrackSel"), TrackCuts::Eta); + if (posTrack.pt() < ptTrackMin || negTrack.pt() < ptTrackMin || bachTrack.pt() < ptTrackMin) { return false; } - if (bachTrack.tpcChi2NCl() > o2::aod::pid_studies::maxTpcChi2NCl) { + registry.fill(HIST("hTrackSel"), TrackCuts::Pt); + if (posTrack.tpcChi2NCl() > tpcChi2NClTrackMax || negTrack.tpcChi2NCl() > tpcChi2NClTrackMax || bachTrack.tpcChi2NCl() > tpcChi2NClTrackMax) { return false; } - if (bachTrack.itsChi2NCl() > o2::aod::pid_studies::maxItsChi2NCl) { + registry.fill(HIST("hTrackSel"), TrackCuts::TpcChi2NCls); + if (posTrack.itsChi2NCl() > itsChi2NClTrackMax || negTrack.itsChi2NCl() > itsChi2NClTrackMax || bachTrack.itsChi2NCl() > itsChi2NClTrackMax) { return false; } + registry.fill(HIST("hTrackSel"), TrackCuts::ItsChi2NCls); } return true; } @@ -439,14 +490,14 @@ struct HfTaskPidStudies { { for (const auto& v0 : V0s) { if (applyEvSels && !isCollSelected(v0.collision_as())) { - return; + continue; } if (applyTrackSels && !isTrackSelected(v0)) { - return; + continue; } if (isSelectedV0AsK0s(v0) || isSelectedV0AsLambda(v0)) { int matched = isMatched(v0); - if (matched != aod::pid_studies::Particle::NotMatched) { + if (matched != Particle::NotMatched) { fillTree(v0, matched); } } @@ -461,13 +512,13 @@ struct HfTaskPidStudies { { for (const auto& v0 : V0s) { if (applyEvSels && !isCollSelected(v0.collision_as())) { - return; + continue; } if (applyTrackSels && !isTrackSelected(v0)) { - return; + continue; } if (isSelectedV0AsK0s(v0) || isSelectedV0AsLambda(v0)) { - fillTree(v0, aod::pid_studies::Particle::NotMatched); + fillTree(v0, Particle::NotMatched); } } } @@ -482,14 +533,14 @@ struct HfTaskPidStudies { { for (const auto& casc : cascades) { if (applyEvSels && !isCollSelected(casc.collision_as())) { - return; + continue; } if (applyTrackSels && !isTrackSelected(casc)) { - return; + continue; } if (isSelectedCascAsOmega(casc)) { int matched = isMatched(casc); - if (matched != aod::pid_studies::Particle::NotMatched) { + if (matched != Particle::NotMatched) { fillTree(casc, matched); } } @@ -504,13 +555,13 @@ struct HfTaskPidStudies { { for (const auto& casc : cascades) { if (applyEvSels && !isCollSelected(casc.collision_as())) { - return; + continue; } if (applyTrackSels && !isTrackSelected(casc)) { - return; + continue; } if (isSelectedCascAsOmega(casc)) { - fillTree(casc, aod::pid_studies::Particle::NotMatched); + fillTree(casc, Particle::NotMatched); } } } diff --git a/PWGHF/Utils/utilsEvSelHf.h b/PWGHF/Utils/utilsEvSelHf.h index a3500da73da..4103cd517de 100644 --- a/PWGHF/Utils/utilsEvSelHf.h +++ b/PWGHF/Utils/utilsEvSelHf.h @@ -27,6 +27,7 @@ #include "Framework/OutputObjHeader.h" #include "Common/CCDB/EventSelectionParams.h" +#include "Common/CCDB/RCTSelectionFlags.h" #include "EventFiltering/Zorro.h" #include "EventFiltering/ZorroSummary.h" #include "PWGLF/DataModel/mcCentrality.h" @@ -82,6 +83,7 @@ namespace o2::hf_evsel // event rejection types enum EventRejection { None = 0, + Rct, SoftwareTrigger, Centrality, Trigger, @@ -110,6 +112,7 @@ void setEventRejectionLabels(Histo& hRejection, std::string softwareTriggerLabel { // Puts labels on the collision monitoring histogram. hRejection->GetXaxis()->SetBinLabel(EventRejection::None + 1, "All"); + hRejection->GetXaxis()->SetBinLabel(EventRejection::Rct + 1, "RCT"); hRejection->GetXaxis()->SetBinLabel(EventRejection::SoftwareTrigger + 1, softwareTriggerLabel.data()); hRejection->GetXaxis()->SetBinLabel(EventRejection::Centrality + 1, "Centrality"); hRejection->GetXaxis()->SetBinLabel(EventRejection::Trigger + 1, "Trigger"); @@ -155,6 +158,10 @@ struct HfEventSelection : o2::framework::ConfigurableGroup { o2::framework::Configurable ccdbPathSoftwareTrigger{"ccdbPathSoftwareTrigger", "Users/m/mpuccio/EventFiltering/OTS/Chunked/", "ccdb path for ZORRO objects"}; o2::framework::ConfigurableAxis th2ConfigAxisCent{"th2ConfigAxisCent", {100, 0., 100.}, ""}; o2::framework::ConfigurableAxis th2ConfigAxisOccupancy{"th2ConfigAxisOccupancy", {14, 0, 14000}, ""}; + o2::framework::Configurable requireGoodRct{"requireGoodRct", false, "Flag to require good RCT"}; + o2::framework::Configurable rctLabel{"rctLabel", "CBT_hadronPID", "RCT selection flag (CBT, CBT_hadronPID, CBT_electronPID, CCBT_calo, CBT_muon, CBT_muon_glo)"}; + o2::framework::Configurable rctCheckZDC{"rctCheckZDC", false, "RCT flag to check whether the ZDC is present or not"}; + o2::framework::Configurable rctTreatLimitedAcceptanceAsBad{"rctTreatLimitedAcceptanceAsBad", false, "RCT flag to reject events with limited acceptance for selected detectors"}; // histogram names static constexpr char NameHistCollisions[] = "hCollisions"; @@ -169,6 +176,9 @@ struct HfEventSelection : o2::framework::ConfigurableGroup { std::shared_ptr hCollisions, hSelCollisionsCent, hPosZBeforeEvSel, hPosZAfterEvSel, hPosXAfterEvSel, hPosYAfterEvSel, hNumPvContributorsAfterSel; std::shared_ptr hCollisionsCentOcc; + // util to retrieve the RCT info from CCDB + o2::aod::rctsel::RCTFlagsChecker rctChecker; + // util to retrieve trigger mask in case of software triggers Zorro zorro; o2::framework::OutputObj zorroSummary{"zorroSummary"}; @@ -190,11 +200,24 @@ struct HfEventSelection : o2::framework::ConfigurableGroup { const o2::framework::AxisSpec th2AxisCent{th2ConfigAxisCent, "Centrality"}; const o2::framework::AxisSpec th2AxisOccupancy{th2ConfigAxisOccupancy, "Occupancy"}; hCollisionsCentOcc = registry.add(NameHistCollisionsCentOcc, "selected events;Centrality; Occupancy", {o2::framework::HistType::kTH2D, {th2AxisCent, th2AxisOccupancy}}); + } + + /// \brief Inits the HF event selection object + /// \param registry reference to the histogram registry + void init(o2::framework::HistogramRegistry& registry) + { + // we initialise the RCT checker + if (requireGoodRct) { + rctChecker.init(rctLabel.value, rctCheckZDC.value, rctTreatLimitedAcceptanceAsBad.value); + } // we initialise the summary object if (softwareTrigger.value != "") { zorroSummary.setObject(zorro.getZorroSummary()); } + + // we initialise histograms + addHistograms(registry); } /// \brief Applies event selection. @@ -218,6 +241,10 @@ struct HfEventSelection : o2::framework::ConfigurableGroup { } if constexpr (useEvSel) { + /// RCT condition + if (requireGoodRct && !rctChecker.checkTable(collision)) { + SETBIT(rejectionMask, EventRejection::Rct); + } /// trigger condition if ((useSel8Trigger && !collision.sel8()) || (!useSel8Trigger && triggerClass > -1 && !collision.alias_bit(triggerClass))) { SETBIT(rejectionMask, EventRejection::Trigger); @@ -333,14 +360,21 @@ struct HfEventSelection : o2::framework::ConfigurableGroup { struct HfEventSelectionMc { // event selection parameters (in chronological order of application) - bool useSel8Trigger{false}; // Apply the Sel8 selection - bool useTvxTrigger{false}; // Apply the TVX trigger - bool useTimeFrameBorderCut{true}; // Apply TF border cut - bool useItsRofBorderCut{false}; // Apply the ITS RO frame border cut - float zPvPosMin{-1000.f}; // Minimum PV posZ (cm) - float zPvPosMax{1000.f}; // Maximum PV posZ (cm) - float centralityMin{0.f}; // Minimum centrality - float centralityMax{100.f}; // Maximum centrality + bool useSel8Trigger{false}; // Apply the Sel8 selection + bool useTvxTrigger{false}; // Apply the TVX trigger + bool useTimeFrameBorderCut{true}; // Apply TF border cut + bool useItsRofBorderCut{false}; // Apply the ITS RO frame border cut + float zPvPosMin{-1000.f}; // Minimum PV posZ (cm) + float zPvPosMax{1000.f}; // Maximum PV posZ (cm) + float centralityMin{0.f}; // Minimum centrality + float centralityMax{100.f}; // Maximum centrality + bool requireGoodRct{false}; // Apply RCT selection + std::string rctLabel{""}; // RCT selection flag + bool rctCheckZDC; // require ZDC from RCT + bool rctTreatLimitedAcceptanceAsBad; // RCT flag to reject events with limited acceptance for selected detectors + + // util to retrieve the RCT info from CCDB + o2::aod::rctsel::RCTFlagsChecker rctChecker; // histogram names static constexpr char NameHistGenCollisionsCent[] = "hGenCollisionsCent"; @@ -364,6 +398,9 @@ struct HfEventSelectionMc { setEventRejectionLabels(hParticles); } + /// \brief Configures the object from the reco workflow + /// \param registry reference to the histogram registry + /// \param device device spec to get the configs from the reco workflow void configureFromDevice(const o2::framework::DeviceSpec& device) { for (const auto& option : device.options) { @@ -383,10 +420,35 @@ struct HfEventSelectionMc { centralityMin = option.defaultValue.get(); } else if (option.name.compare("hfEvSel.centralityMax") == 0) { centralityMax = option.defaultValue.get(); + } else if (option.name.compare("hfEvSel.requireGoodRct") == 0) { + requireGoodRct = option.defaultValue.get(); + } else if (option.name.compare("hfEvSel.rctLabel") == 0) { + rctLabel = option.defaultValue.get(); + } else if (option.name.compare("hfEvSel.rctCheckZDC") == 0) { + rctCheckZDC = option.defaultValue.get(); + } else if (option.name.compare("hfEvSel.rctTreatLimitedAcceptanceAsBad") == 0) { + rctTreatLimitedAcceptanceAsBad = option.defaultValue.get(); } } } + /// \brief Inits the HF event selection object + /// \param device device spec to get the configs from the reco workflow + /// \param registry reference to the histogram registry + void init(const o2::framework::DeviceSpec& device, o2::framework::HistogramRegistry& registry) + { + // we get the configuration from the reco workflow + configureFromDevice(device); + + // we initialise the RCT checker + if (requireGoodRct) { + rctChecker.init(rctLabel, rctCheckZDC, rctTreatLimitedAcceptanceAsBad); + } + + // we initialise histograms + addHistograms(registry); + } + /// \brief Function to apply event selections to generated MC collisions /// \param mcCollision MC collision to test against the selection criteria /// \param collSlice collection of reconstructed collisions @@ -406,6 +468,16 @@ struct HfEventSelectionMc { SETBIT(rejectionMask, EventRejection::Centrality); } } + + /// RCT condition + if (requireGoodRct) { + for (auto const& collision : collSlice) { + if (!rctChecker.checkTable(collision)) { + SETBIT(rejectionMask, EventRejection::Rct); + break; + } + } + } /// Sel8 trigger selection if (useSel8Trigger && (!bc.selection_bit(o2::aod::evsel::kIsTriggerTVX) || !bc.selection_bit(o2::aod::evsel::kNoTimeFrameBorder) || !bc.selection_bit(o2::aod::evsel::kNoITSROFrameBorder))) { SETBIT(rejectionMask, EventRejection::Trigger); diff --git a/PWGJE/Core/utilsBcSelEMC.h b/PWGJE/Core/utilsBcSelEMC.h index 1796d130d7f..c613bba70e2 100644 --- a/PWGJE/Core/utilsBcSelEMC.h +++ b/PWGJE/Core/utilsBcSelEMC.h @@ -35,11 +35,6 @@ enum EventRejection { TvxTrigger, TimeFrameBorderCut, ItsRofBorderCut, - IsGoodZvtxFT0vsPV, - NoSameBunchPileup, - NoCollInTimeRangeNarrow, - NoCollInTimeRangeStandard, - NoCollInRofStandard, NEventRejection }; @@ -56,11 +51,6 @@ void setEventRejectionLabels(Histo& hRejection) hRejection->GetXaxis()->SetBinLabel(EventRejection::TvxTrigger + 1, "TVX Trigger"); hRejection->GetXaxis()->SetBinLabel(EventRejection::TimeFrameBorderCut + 1, "TF border"); hRejection->GetXaxis()->SetBinLabel(EventRejection::ItsRofBorderCut + 1, "ITS ROF border"); - hRejection->GetXaxis()->SetBinLabel(EventRejection::IsGoodZvtxFT0vsPV + 1, "PV #it{z} consistency FT0 timing"); - hRejection->GetXaxis()->SetBinLabel(EventRejection::NoSameBunchPileup + 1, "No same-bunch pile-up"); - hRejection->GetXaxis()->SetBinLabel(EventRejection::NoCollInTimeRangeNarrow + 1, "No coll timerange narrow"); - hRejection->GetXaxis()->SetBinLabel(EventRejection::NoCollInTimeRangeStandard + 1, "No coll timerange strict"); - hRejection->GetXaxis()->SetBinLabel(EventRejection::NoCollInRofStandard + 1, "No coll in ROF std"); } struct EMCEventSelection : o2::framework::ConfigurableGroup { @@ -71,12 +61,6 @@ struct EMCEventSelection : o2::framework::ConfigurableGroup { o2::framework::Configurable useTvxTrigger{"useTvxTrigger", true, "Apply TVX trigger sel"}; o2::framework::Configurable useTimeFrameBorderCut{"useTimeFrameBorderCut", true, "Apply TF border cut"}; o2::framework::Configurable useItsRofBorderCut{"useItsRofBorderCut", true, "Apply ITS ROF border cut"}; - o2::framework::Configurable useIsGoodZvtxFT0vsPV{"useIsGoodZvtxFT0vsPV", false, "Check consistency between PVz from central barrel with that from FT0 timing"}; - o2::framework::Configurable useNoSameBunchPileup{"useNoSameBunchPileup", false, "Exclude collisions in bunches with more than 1 reco. PV"}; - o2::framework::Configurable useNoCollInTimeRangeNarrow{"useNoCollInTimeRangeNarrow", false, "Reject collisions in time range narrow"}; - o2::framework::Configurable useNoCollInTimeRangeStandard{"useNoCollInTimeRangeStandard", false, "Reject collisions in time range strict"}; - o2::framework::Configurable useNoCollInRofStandard{"useNoCollInRofStandard", false, "Reject collisions in ROF standard"}; - // histogram names static constexpr char NameHistBCs[] = "hBCs"; @@ -103,8 +87,8 @@ struct EMCEventSelection : o2::framework::ConfigurableGroup { if constexpr (useEvSel) { /// trigger condition - bool sel8 = bc.selection_bit(o2::aod::evsel::kIsBBT0A) && bc.selection_bit(o2::aod::evsel::kIsBBT0C); - if ((useSel8Trigger && sel8) || (!useSel8Trigger && triggerClass > -1 && !bc.alias_bit(triggerClass))) { + bool sel8 = bc.selection_bit(o2::aod::evsel::kIsTriggerTVX) && bc.selection_bit(o2::aod::evsel::kNoTimeFrameBorder) && bc.selection_bit(o2::aod::evsel::kNoITSROFrameBorder); + if ((useSel8Trigger && !sel8) || (!useSel8Trigger && triggerClass > -1 && !bc.alias_bit(triggerClass))) { SETBIT(rejectionMask, EventRejection::Trigger); } /// TVX trigger selection @@ -119,27 +103,6 @@ struct EMCEventSelection : o2::framework::ConfigurableGroup { if (useItsRofBorderCut && !bc.selection_bit(o2::aod::evsel::kNoITSROFrameBorder)) { SETBIT(rejectionMask, EventRejection::ItsRofBorderCut); } - /// PVz consistency tracking - FT0 timing - if (useIsGoodZvtxFT0vsPV && !bc.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) { - SETBIT(rejectionMask, EventRejection::IsGoodZvtxFT0vsPV); - } - /// remove collisions in bunches with more than 1 reco bc - /// POTENTIALLY BAD FOR BEAUTY ANALYSES - if (useNoSameBunchPileup && !bc.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) { - SETBIT(rejectionMask, EventRejection::NoSameBunchPileup); - } - /// No collisions in time range narrow - if (useNoCollInTimeRangeNarrow && !bc.selection_bit(o2::aod::evsel::kNoCollInTimeRangeNarrow)) { - SETBIT(rejectionMask, EventRejection::NoCollInTimeRangeNarrow); - } - /// No collisions in time range strict - if (useNoCollInTimeRangeStandard && !bc.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { - SETBIT(rejectionMask, EventRejection::NoCollInTimeRangeStandard); - } - /// No collisions in ROF standard - if (useNoCollInRofStandard && !bc.selection_bit(o2::aod::evsel::kNoCollInRofStandard)) { - SETBIT(rejectionMask, EventRejection::NoCollInRofStandard); - } } return rejectionMask; } diff --git a/PWGJE/DataModel/EMCALClusters.h b/PWGJE/DataModel/EMCALClusters.h index 1981fd635aa..c634b4b017e 100644 --- a/PWGJE/DataModel/EMCALClusters.h +++ b/PWGJE/DataModel/EMCALClusters.h @@ -135,6 +135,12 @@ DECLARE_SOA_TABLE(EMCALMCClusters, "AOD", "EMCALMCCLUSTERS", //! using EMCALMCCluster = EMCALMCClusters::iterator; +// table of cluster MC info that could not be matched to a collision +DECLARE_SOA_TABLE(EMCALAmbiguousMCClusters, "AOD", "EMCALAMBMCCLS", //! + emcalclustermc::McParticleIds, emcalclustermc::AmplitudeA); + +using EMCALAmbiguousMCCluster = EMCALAmbiguousMCClusters::iterator; + namespace emcalclustercell { // declare index column pointing to cluster table diff --git a/PWGJE/DataModel/GammaJetAnalysisTree.h b/PWGJE/DataModel/GammaJetAnalysisTree.h index 7d468a339e7..cfd58f75773 100644 --- a/PWGJE/DataModel/GammaJetAnalysisTree.h +++ b/PWGJE/DataModel/GammaJetAnalysisTree.h @@ -52,7 +52,7 @@ DECLARE_SOA_COLUMN(Time, time, float); //! clust DECLARE_SOA_COLUMN(IsExotic, isExotic, bool); //! flag to mark cluster as exotic DECLARE_SOA_COLUMN(DistanceToBadChannel, distanceToBadChannel, float); //! distance to bad channel DECLARE_SOA_COLUMN(NLM, nlm, ushort); //! number of local maxima -DECLARE_SOA_COLUMN(IsoRaw, isoraw, ushort); //! isolation in cone not corrected for Rho +DECLARE_SOA_COLUMN(IsoRaw, isoraw, float); //! isolation in cone not corrected for Rho DECLARE_SOA_COLUMN(PerpConeRho, perpconerho, float); //! rho in perpendicular cone DECLARE_SOA_COLUMN(TMdeltaPhi, tmdeltaphi, float); //! delta phi between cluster and closest match DECLARE_SOA_COLUMN(TMdeltaEta, tmdeltaeta, float); //! delta eta between cluster and closest match diff --git a/PWGJE/TableProducer/derivedDataProducer.cxx b/PWGJE/TableProducer/derivedDataProducer.cxx index a946d93b997..3398b33ce42 100644 --- a/PWGJE/TableProducer/derivedDataProducer.cxx +++ b/PWGJE/TableProducer/derivedDataProducer.cxx @@ -241,12 +241,11 @@ struct JetDerivedDataProducerTask { void processMcCollisionLabels(soa::Join::iterator const& collision, aod::McCollisions const&) { + products.jMcCollisionsLabelTable(collision.mcCollisionId()); // collision.mcCollisionId() returns -1 if collision has no associated mcCollision if (collision.has_mcCollision()) { - products.jMcCollisionsLabelTable(collision.mcCollisionId()); products.jCollisionMcInfosTable(collision.mcCollision().weight(), collision.mcCollision().getSubGeneratorId()); } else { - products.jMcCollisionsLabelTable(-1); - products.jCollisionMcInfosTable(-1.0, jetderiveddatautilities::JCollisionSubGeneratorId::none); + products.jCollisionMcInfosTable(0.0, jetderiveddatautilities::JCollisionSubGeneratorId::none); } } PROCESS_SWITCH(JetDerivedDataProducerTask, processMcCollisionLabels, "produces derived MC collision labels table", false); diff --git a/PWGJE/TableProducer/emcalCorrectionTask.cxx b/PWGJE/TableProducer/emcalCorrectionTask.cxx index 2b121530d5d..bf72e3275d6 100644 --- a/PWGJE/TableProducer/emcalCorrectionTask.cxx +++ b/PWGJE/TableProducer/emcalCorrectionTask.cxx @@ -65,6 +65,7 @@ struct EmcalCorrectionTask { Produces clusters; Produces mcclusters; Produces clustersAmbiguous; + Produces mcclustersAmbiguous; Produces clustercells; // cells belonging to given cluster Produces clustercellsambiguous; Produces matchedTracks; @@ -702,6 +703,10 @@ struct EmcalCorrectionTask { { int cellindex = -1; clustersAmbiguous.reserve(mAnalysisClusters.size()); + if (mClusterLabels.size() > 0) { + mcclustersAmbiguous.reserve(mClusterLabels.size()); + } + unsigned int iCluster = 0; for (const auto& cluster : mAnalysisClusters) { auto pos = cluster.getGlobalPosition(); pos = pos - math_utils::Point3D{0., 0., 0.}; @@ -730,12 +735,16 @@ struct EmcalCorrectionTask { cluster.getM20(), cluster.getNCells(), cluster.getClusterTime(), cluster.getIsExotic(), cluster.getDistanceToBadChannel(), cluster.getNExMax(), static_cast(mClusterDefinitions.at(iClusterizer))); + if (mClusterLabels.size() > 0) { + mcclustersAmbiguous(mClusterLabels[iCluster].getLabels(), mClusterLabels[iCluster].getEnergyFractions()); + } clustercellsambiguous.reserve(cluster.getNCells()); for (int ncell = 0; ncell < cluster.getNCells(); ncell++) { cellindex = cluster.getCellIndex(ncell); clustercellsambiguous(clustersAmbiguous.lastIndex(), cellIndicesBC[cellindex]); } // end of cells of cluster loop + iCluster++; } // end of cluster loop } diff --git a/PWGJE/TableProducer/jetEventWeightMCD.cxx b/PWGJE/TableProducer/jetEventWeightMCD.cxx index 0709a362d7f..40ea278c51e 100644 --- a/PWGJE/TableProducer/jetEventWeightMCD.cxx +++ b/PWGJE/TableProducer/jetEventWeightMCD.cxx @@ -40,14 +40,14 @@ struct JetEventWeightMCDTask { void processMCDetectorLevelEventWeight(MCDetectorLevelJetTable const& jet, soa::Join const&, aod::JetMcCollisions const&) { auto collision = jet.template collision_as>(); - mcDetectorLevelWeightsTable(jet.globalIndex(), collision.mcCollision().weight()); + mcDetectorLevelWeightsTable(jet.globalIndex(), collision.weight()); } PROCESS_SWITCH(JetEventWeightMCDTask, processMCDetectorLevelEventWeight, "Fill event weight tables for detector level MC jets", false); void processMCDetectorLevelEventWiseSubtractedEventWeight(MCDetectorLevelEventWiseSubtractedJetTable const& jet, soa::Join const&, aod::JetMcCollisions const&) { auto collision = jet.template collision_as>(); - mcDetectorLevelEventWiseSubtractedWeightsTable(jet.globalIndex(), collision.mcCollision().weight()); + mcDetectorLevelEventWiseSubtractedWeightsTable(jet.globalIndex(), collision.weight()); } PROCESS_SWITCH(JetEventWeightMCDTask, processMCDetectorLevelEventWiseSubtractedEventWeight, "Fill event weight tables for detector level MC jets", false); }; diff --git a/PWGJE/TableProducer/jetTaggerHF.cxx b/PWGJE/TableProducer/jetTaggerHF.cxx index 785118fa180..0ab545fe414 100644 --- a/PWGJE/TableProducer/jetTaggerHF.cxx +++ b/PWGJE/TableProducer/jetTaggerHF.cxx @@ -64,7 +64,11 @@ struct JetTaggerHFTask { Configurable trackProbQA{"trackProbQA", false, "fill track probability histograms separately for geometric positive and negative tracks for QA"}; Configurable numCount{"numCount", 3, "number of track counting"}; Configurable resoFuncMatching{"resoFuncMatching", 0, "matching parameters of resolution function as MC samble (0: custom, 1: custom & inc, 2: MB, 3: MB & inc, 4: JJ, 5: JJ & inc)"}; - Configurable> pathsCCDBforIPparamer{"pathsCCDBforIPparamer", std::vector{"Users/l/leehy/LHC24g4/f_inclusive_0"}, "Paths for fitting parameters of resolution functions for IP method on CCDB"}; + Configurable> pathsCCDBforIPDataparameter{"pathsCCDBforIPDataparameter", std::vector{"Users/l/leehy/LHC24g4/f_inclusive_0"}, "Paths for fitting parameters of resolution functions of data for IP method on CCDB"}; + Configurable> pathsCCDBforIPIncparameter{"pathsCCDBforIPIncparameter", std::vector{"Users/l/leehy/LHC24g4/f_inclusive_0"}, "Paths for fitting parameters of resolution functions of inclusive for IP method on CCDB"}; + Configurable> pathsCCDBforIPBeautyparameter{"pathsCCDBforIPBeautyparameter", std::vector{"Users/l/leehy/LHC24g4/f_inclusive_0"}, "Paths for fitting parameters of resolution functions of beauty for IP method on CCDB"}; + Configurable> pathsCCDBforIPCharmparameter{"pathsCCDBforIPCharmparameter", std::vector{"Users/l/leehy/LHC24g4/f_inclusive_0"}, "Paths for fitting parameters of resolution functions of charm for IP method on CCDB"}; + Configurable> pathsCCDBforIPLfparameter{"pathsCCDBforIPLfparameter", std::vector{"Users/l/leehy/LHC24g4/f_inclusive_0"}, "Paths for fitting parameters of resolution functions of light flavour for IP method on CCDB"}; Configurable usepTcategorize{"usepTcategorize", false, "p_T categorize TF1 function with Inclusive jet"}; Configurable> paramsResoFuncData{"paramsResoFuncData", std::vector{-1.0}, "parameters of gaus(0)+expo(3)+expo(5)+expo(7))"}; Configurable> paramsResoFuncIncJetMC{"paramsResoFuncIncJetMC", std::vector{-1.0}, "parameters of gaus(0)+expo(3)+expo(5)+expo(7)))"}; @@ -135,8 +139,17 @@ struct JetTaggerHFTask { std::unique_ptr fSignImpXYSigBeautyJetMC = nullptr; std::unique_ptr fSignImpXYSigLfJetMC = nullptr; + std::vector> vecParamsDataJetCCDB; std::vector> vecParamsIncJetMcCCDB; + std::vector> vecParamsBeautyJetMcCCDB; + std::vector> vecParamsCharmJetMcCCDB; + std::vector> vecParamsLfJetMcCCDB; + + std::vector> vecfSignImpXYSigDataJetCCDB; std::vector> vecfSignImpXYSigIncJetMcCCDB; + std::vector> vecfSignImpXYSigCharmJetMcCCDB; + std::vector> vecfSignImpXYSigBeautyJetMcCCDB; + std::vector> vecfSignImpXYSigLfJetMcCCDB; std::vector decisionNonML; std::vector scoreML; @@ -148,7 +161,11 @@ struct JetTaggerHFTask { { float jetProb = -1.0; if (!isMC) { - jetProb = jettaggingutilities::getJetProbability(fSignImpXYSigData, jet, tracks, trackDcaXYMax, trackDcaZMax, minSignImpXYSig); + if (usepTcategorize) { + jetProb = jettaggingutilities::getJetProbability(vecfSignImpXYSigDataJetCCDB, jet, tracks, trackDcaXYMax, trackDcaZMax, minSignImpXYSig); + } else { + jetProb = jettaggingutilities::getJetProbability(fSignImpXYSigData, jet, tracks, trackDcaXYMax, trackDcaZMax, minSignImpXYSig); + } } else { if (useResoFuncFromIncJet) { if (usepTcategorize) { @@ -158,11 +175,23 @@ struct JetTaggerHFTask { } } else { if (origin == JetTaggingSpecies::charm) { - jetProb = jettaggingutilities::getJetProbability(fSignImpXYSigCharmJetMC, jet, tracks, trackDcaXYMax, trackDcaZMax, minSignImpXYSig); + if (usepTcategorize) { + jetProb = jettaggingutilities::getJetProbability(vecfSignImpXYSigCharmJetMcCCDB, jet, tracks, trackDcaXYMax, trackDcaZMax, minSignImpXYSig); + } else { + jetProb = jettaggingutilities::getJetProbability(fSignImpXYSigCharmJetMC, jet, tracks, trackDcaXYMax, trackDcaZMax, minSignImpXYSig); + } } else if (origin == JetTaggingSpecies::beauty) { - jetProb = jettaggingutilities::getJetProbability(fSignImpXYSigBeautyJetMC, jet, tracks, trackDcaXYMax, trackDcaZMax, minSignImpXYSig); + if (usepTcategorize) { + jetProb = jettaggingutilities::getJetProbability(vecfSignImpXYSigBeautyJetMcCCDB, jet, tracks, trackDcaXYMax, trackDcaZMax, minSignImpXYSig); + } else { + jetProb = jettaggingutilities::getJetProbability(fSignImpXYSigBeautyJetMC, jet, tracks, trackDcaXYMax, trackDcaZMax, minSignImpXYSig); + } } else { - jetProb = jettaggingutilities::getJetProbability(fSignImpXYSigLfJetMC, jet, tracks, trackDcaXYMax, trackDcaZMax, minSignImpXYSig); + if (usepTcategorize) { + jetProb = jettaggingutilities::getJetProbability(vecfSignImpXYSigLfJetMcCCDB, jet, tracks, trackDcaXYMax, trackDcaZMax, minSignImpXYSig); + } else { + jetProb = jettaggingutilities::getJetProbability(fSignImpXYSigLfJetMC, jet, tracks, trackDcaXYMax, trackDcaZMax, minSignImpXYSig); + } } } } @@ -215,12 +244,12 @@ struct JetTaggerHFTask { } if (useJetProb) { if constexpr (isMC) { - jetProb = calculateJetProbability(origin, jet, tracks); + jetProb = calculateJetProbability(origin, jet, tracks, isMC); if (trackProbQA) { evaluateTrackProbQA(origin, jet, tracks, isMC); } } else { - jetProb = calculateJetProbability(0, jet, tracks); + jetProb = calculateJetProbability(0, jet, tracks, isMC); if (trackProbQA) { evaluateTrackProbQA(0, jet, tracks, isMC); } @@ -256,21 +285,59 @@ struct JetTaggerHFTask { std::vector vecParamsCharmJetMC; std::vector vecParamsBeautyJetMC; std::vector vecParamsLfJetMC; - std::vector resoFuncCCDB; + + std::vector resoFuncDataCCDB; + std::vector resoFuncIncCCDB; + std::vector resoFuncBeautyCCDB; + std::vector resoFuncCharmCCDB; + std::vector resoFuncLfCCDB; ccdbApi.init(ccdbUrl); + + std::map metadata; + resoFuncMatch = resoFuncMatching; + + const int IPmethodResolutionFunctionSize = 7; + + auto loadCCDBforIP = [&](const std::vector& paths, std::vector& targetVec, const std::string& name) { + if (paths.size() != IPmethodResolutionFunctionSize) { + usepTcategorize.value = false; + LOG(info) << name << " does not have 7 entries. Disabling pT categorization (usepTcategorize = false)."; + resoFuncMatch = 0; + return; + } + for (int i = 0; i < IPmethodResolutionFunctionSize; i++) { + targetVec.push_back(ccdbApi.retrieveFromTFileAny(paths[i], metadata, -1)); + } + }; + if (usepTcategorize) { - std::map metadata; // dummy meta data (will be updated) - // fill the timestamp directly of each TF1 according to p_T track range (0, 0.5, 1, 2, 4, 6, 9) - for (int i = 0; i < 7; i++) { - resoFuncCCDB.push_back(ccdbApi.retrieveFromTFileAny(pathsCCDBforIPparamer->at(i), metadata, -1)); + switch (resoFuncMatch) { + case 6: + loadCCDBforIP(pathsCCDBforIPIncparameter, resoFuncIncCCDB, "pathsCCDBforIPIncparameter"); + break; + + case 7: + loadCCDBforIP(pathsCCDBforIPBeautyparameter, resoFuncBeautyCCDB, "pathsCCDBforIPBeautyparameter"); + loadCCDBforIP(pathsCCDBforIPCharmparameter, resoFuncCharmCCDB, "pathsCCDBforIPCharmparameter"); + loadCCDBforIP(pathsCCDBforIPLfparameter, resoFuncLfCCDB, "pathsCCDBforIPLfparameter"); + break; + + case 8: + loadCCDBforIP(pathsCCDBforIPDataparameter, resoFuncDataCCDB, "pathsCCDBforIPDataparameter"); + break; + + default: + LOG(info) << "resoFuncMatching is neither 6 nor 7, although usepTcategorize is set to true. Resetting resoFuncMatching to 0."; + resoFuncMatch = 0; + break; } } maxOrder = numCount + 1; // 0: untagged, >1 : N ordering + const int IPmethodNumOfParameters = 9; // Set up the resolution function - resoFuncMatch = resoFuncMatching; switch (resoFuncMatch) { case 0: vecParamsData = (std::vector)paramsResoFuncData; @@ -313,12 +380,11 @@ struct JetTaggerHFTask { break; case 6: // TODO vecParamsData = (std::vector)paramsResoFuncData; - vecParamsIncJetMC = (std::vector)paramsResoFuncData; - for (size_t j = 0; j < resoFuncCCDB.size(); j++) { + for (size_t j = 0; j < resoFuncIncCCDB.size(); j++) { std::vector params; - if (resoFuncCCDB[j]) { - for (int i = 0; i < 9; i++) { - params.emplace_back(resoFuncCCDB[j]->GetParameter(i)); + if (resoFuncIncCCDB[j]) { + for (int i = 0; i < IPmethodNumOfParameters; i++) { + params.emplace_back(resoFuncIncCCDB[j]->GetParameter(i)); } } vecParamsIncJetMcCCDB.emplace_back(params); @@ -326,6 +392,49 @@ struct JetTaggerHFTask { LOG(info) << "defined parameters of resolution function from CCDB"; useResoFuncFromIncJet = true; break; + case 7: // TODO + vecParamsData = (std::vector)paramsResoFuncData; + for (size_t j = 0; j < resoFuncBeautyCCDB.size(); j++) { + std::vector params; + if (resoFuncBeautyCCDB[j]) { + for (int i = 0; i < IPmethodNumOfParameters; i++) { + params.emplace_back(resoFuncBeautyCCDB[j]->GetParameter(i)); + } + } + vecParamsBeautyJetMcCCDB.emplace_back(params); + } + for (size_t j = 0; j < resoFuncCharmCCDB.size(); j++) { + std::vector params; + if (resoFuncCharmCCDB[j]) { + for (int i = 0; i < IPmethodNumOfParameters; i++) { + params.emplace_back(resoFuncCharmCCDB[j]->GetParameter(i)); + } + } + vecParamsCharmJetMcCCDB.emplace_back(params); + } + for (size_t j = 0; j < resoFuncLfCCDB.size(); j++) { + std::vector params; + if (resoFuncLfCCDB[j]) { + for (int i = 0; i < IPmethodNumOfParameters; i++) { + params.emplace_back(resoFuncLfCCDB[j]->GetParameter(i)); + } + } + vecParamsLfJetMcCCDB.emplace_back(params); + } + LOG(info) << "defined parameters of resolution function from CCDB for each flavour"; + break; + case 8: + for (size_t j = 0; j < resoFuncDataCCDB.size(); j++) { + std::vector params; + if (resoFuncDataCCDB[j]) { + for (int i = 0; i < IPmethodNumOfParameters; i++) { + params.emplace_back(resoFuncDataCCDB[j]->GetParameter(i)); + } + } + vecParamsDataJetCCDB.emplace_back(params); + } + LOG(info) << "defined parameters of resolution function from CCDB for data"; + break; default: LOG(fatal) << "undefined parameters of resolution function. Fix it!"; break; @@ -337,9 +446,21 @@ struct JetTaggerHFTask { fSignImpXYSigBeautyJetMC = jettaggingutilities::setResolutionFunction(vecParamsBeautyJetMC); fSignImpXYSigLfJetMC = jettaggingutilities::setResolutionFunction(vecParamsLfJetMC); + for (const auto& params : vecParamsDataJetCCDB) { + vecfSignImpXYSigDataJetCCDB.emplace_back(jettaggingutilities::setResolutionFunction(params)); + } for (const auto& params : vecParamsIncJetMcCCDB) { vecfSignImpXYSigIncJetMcCCDB.emplace_back(jettaggingutilities::setResolutionFunction(params)); } + for (const auto& params : vecParamsBeautyJetMcCCDB) { + vecfSignImpXYSigBeautyJetMcCCDB.emplace_back(jettaggingutilities::setResolutionFunction(params)); + } + for (const auto& params : vecParamsCharmJetMcCCDB) { + vecfSignImpXYSigCharmJetMcCCDB.emplace_back(jettaggingutilities::setResolutionFunction(params)); + } + for (const auto& params : vecParamsLfJetMcCCDB) { + vecfSignImpXYSigLfJetMcCCDB.emplace_back(jettaggingutilities::setResolutionFunction(params)); + } // Use QA for effectivness of track probability if (trackProbQA) { diff --git a/PWGJE/Tasks/CMakeLists.txt b/PWGJE/Tasks/CMakeLists.txt index 0b8443531f8..1a0854a2fbf 100644 --- a/PWGJE/Tasks/CMakeLists.txt +++ b/PWGJE/Tasks/CMakeLists.txt @@ -160,8 +160,8 @@ if(FastJet_FOUND) SOURCES triggerCorrelations.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2::EMCALBase O2::EMCALCalib O2Physics::PWGJECore O2Physics::AnalysisCore COMPONENT_NAME Analysis) - o2physics_add_dpl_workflow(jet-charged-trigger-qa - SOURCES ChJetTriggerQATask.cxx + o2physics_add_dpl_workflow(jet-trigger-charged-qa + SOURCES jetTriggerChargedQa.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(jet-full-trigger-qa @@ -269,4 +269,4 @@ if(FastJet_FOUND) SOURCES jetShape.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore COMPONENT_NAME Analysis) -endif() \ No newline at end of file +endif() diff --git a/PWGJE/Tasks/dijetFinderQA.cxx b/PWGJE/Tasks/dijetFinderQA.cxx index 4f094c68cd9..4dd9292a1ac 100644 --- a/PWGJE/Tasks/dijetFinderQA.cxx +++ b/PWGJE/Tasks/dijetFinderQA.cxx @@ -48,71 +48,58 @@ struct DijetFinderQATask { HistogramRegistry registry; - Configurable setJetPtCut{"setJetPtCut", 20, "set jet pt minimum cut"}; - Configurable selectedJetsRadius{"selectedJetsRadius", 0.4, "resolution parameter for histograms without radius"}; - Configurable jetPtMax{"jetPtMax", 200., "set jet pT bin max"}; - Configurable vertexZCut{"vertexZCut", 10.0f, "Accepted z-vertex range"}; Configurable centralityMin{"centralityMin", -999.0, "minimum centrality"}; Configurable centralityMax{"centralityMax", 999.0, "maximum centrality"}; - Configurable jetAreaFractionMin{"jetAreaFractionMin", -99.0, "used to make a cut on the jet areas"}; - Configurable leadingConstituentPtMin{"leadingConstituentPtMin", -99.0, "minimum pT selection on jet constituent"}; - Configurable leadingConstituentPtMax{"leadingConstituentPtMax", 9999.0, "maximum pT selection on jet constituent"}; + Configurable eventSelections{"eventSelections", "sel8", "choose event selection"}; + Configurable vertexZCut{"vertexZCut", 10.0f, "Accepted z-vertex range"}; + Configurable trackSelections{"trackSelections", "globalTracks", "set track selections"}; Configurable trackPtMin{"trackPtMin", 0.15, "minimum pT acceptance for tracks"}; - Configurable trackPtMax{"trackPtMax", 100.0, "maximum pT acceptance for tracks"}; + Configurable trackPtMax{"trackPtMax", 1000.0, "maximum pT acceptance for tracks"}; Configurable trackEtaMin{"trackEtaMin", -0.9, "minimum eta acceptance for tracks"}; Configurable trackEtaMax{"trackEtaMax", 0.9, "maximum eta acceptance for tracks"}; + Configurable leadingConstituentPtMin{"leadingConstituentPtMin", -99.0, "minimum pT selection on jet constituent"}; + Configurable leadingConstituentPtMax{"leadingConstituentPtMax", 9999.0, "maximum pT selection on jet constituent"}; + Configurable setJetPtCut{"setJetPtCut", 20., "set jet pt minimum cut"}; + Configurable setPhiCut{"setPhiCut", 0.5, "set phicut"}; + Configurable jetR{"jetR", 0.4, "jet resolution parameter"}; + Configurable jetPtMin{"jetPtMin", 20.0, "minimum jet pT cut"}; + Configurable jetPtMax{"jetPtMax", 200., "set jet pT bin max"}; Configurable jetEtaMin{"jetEtaMin", -0.5, "minimum jet pseudorapidity"}; Configurable jetEtaMax{"jetEtaMax", 0.5, "maximum jet pseudorapidity"}; - Configurable jetPtMin{"jetPtMin", 20.0, "minimum jet pT cut"}; - Configurable jetR{"jetR", 0.4, "jet resolution parameter"}; - Configurable eventSelections{"eventSelections", "sel8", "choose event selection"}; - Configurable trackSelections{"trackSelections", "globalTracks", "set track selections"}; - Configurable checkMcCollisionIsMatched{"checkMcCollisionIsMatched", false, "0: count whole MCcollisions, 1: select MCcollisions which only have their correspond collisions"}; + Configurable jetAreaFractionMin{"jetAreaFractionMin", -99.0, "used to make a cut on the jet areas"}; - std::vector eventSelectionBits; + std::vector eventSelection; int trackSelection = -1; - std::vector jetPtBins; + std::vector dijetMassBins; void init(o2::framework::InitContext&) { - eventSelectionBits = jetderiveddatautilities::initialiseEventSelectionBits(static_cast(eventSelections)); + eventSelection = jetderiveddatautilities::initialiseEventSelectionBits(static_cast(eventSelections)); trackSelection = jetderiveddatautilities::initialiseTrackSelection(static_cast(trackSelections)); - auto jetPtTemp = 0.0; - jetPtBins.push_back(jetPtTemp); - while (jetPtTemp < jetPtMax) { - if (jetPtTemp < 100.0) { - jetPtTemp += 1.0; - jetPtBins.push_back(jetPtTemp); - } else if (jetPtTemp < 200.0) { - jetPtTemp += 5.0; - jetPtBins.push_back(jetPtTemp); - } else { - jetPtTemp += 10.0; - jetPtBins.push_back(jetPtTemp); - } + auto dijetMassTemp = 0.0; + while (dijetMassTemp <= 2 * jetPtMax) { + dijetMassBins.push_back(dijetMassTemp); + dijetMassTemp += 5.0; } - AxisSpec jetPtAxis = {jetPtBins, "M_{jj} (GeV/#it{c}^2)"}; + AxisSpec dijetMassAxis = {dijetMassBins, "M_{jj} (GeV/#it{c}^2)"}; if (doprocessDijetMCP) { - registry.add("h_part_jet_pt", "Jet pt MCP;;entries", {HistType::kTH1F, {jetPtAxis}}); - registry.add("h_part_dijet_mass", "Dijet invariant mass;;entries", {HistType::kTH1F, {jetPtAxis}}); + registry.add("h_part_dijet_mass", "Dijet invariant mass;;entries", {HistType::kTH1F, {dijetMassAxis}}); } if (doprocessDijetMCD) { - registry.add("h_detec_jet_pt", "Jet pt MCD;;entries", {HistType::kTH1F, {jetPtAxis}}); - registry.add("h_detec_dijet_mass", "Dijet invariant mass;;entries", {HistType::kTH1F, {jetPtAxis}}); + registry.add("h_detec_dijet_mass", "Dijet invariant mass;;entries", {HistType::kTH1F, {dijetMassAxis}}); } if (doprocessDijetData) { - registry.add("h_data_jet_pt", "Jet pt Data;;entries", {HistType::kTH1F, {jetPtAxis}}); - registry.add("h_data_dijet_mass", "Dijet invariant mass;;entries", {HistType::kTH1F, {jetPtAxis}}); + registry.add("h_data_dijet_mass", "Dijet invariant mass;;entries", {HistType::kTH1F, {dijetMassAxis}}); } if (doprocessDijetMCMatched) { - registry.add("h_matched_dijet_mass", "M_{jj matched};M_{jj part}; M_{jj det}", {HistType::kTH2F, {jetPtAxis, jetPtAxis}}); + registry.add("h_matched_dijet_mass", "M_{jj matched};M_{jj part}; M_{jj det}", {HistType::kTH2F, {dijetMassAxis, dijetMassAxis}}); } } @@ -120,8 +107,7 @@ struct DijetFinderQATask { Filter trackCuts = (aod::jtrack::pt >= trackPtMin && aod::jtrack::pt < trackPtMax && aod::jtrack::eta > trackEtaMin && aod::jtrack::eta < trackEtaMax); Filter eventCuts = (nabs(aod::jcollision::posZ) < vertexZCut && aod::jcollision::centrality >= centralityMin && aod::jcollision::centrality < centralityMax); Filter mcCollisionsFilter = nabs(aod::jmccollision::posZ) < vertexZCut; - Filter jetCuts = aod::jet::pt > jetPtMin&& aod::jet::r == nround(jetR.node() * 100.0f); // ********** - PresliceUnsorted> CollisionsPerMCPCollision = aod::jmccollisionlb::mcCollisionId; + Filter jetCuts = aod::jet::pt > jetPtMin&& aod::jet::r == nround(jetR.node() * 100.0f); /****************************************************************************************************************************************************************/ template @@ -160,30 +146,6 @@ struct DijetFinderQATask { return true; } - template - void fillJetPtHistogramsMCP(T const& jet) - { - if (jet.r() == round(selectedJetsRadius * 100.0f)) { - registry.fill(HIST("h_part_jet_pt"), jet.pt()); - } - } - - template - void fillJetPtHistogramsMCD(T const& jet) - { - if (jet.r() == round(selectedJetsRadius * 100.0f)) { - registry.fill(HIST("h_detec_jet_pt"), jet.pt()); - } - } - - template - void fillJetPtHistogramsData(T const& jet) - { - if (jet.r() == round(selectedJetsRadius * 100.0f)) { - registry.fill(HIST("h_data_jet_pt"), jet.pt()); - } - } - template void fillMassHistogramsMCP(T const& mass) { @@ -217,7 +179,6 @@ struct DijetFinderQATask { { std::vector> jetPtcuts; for (auto& jet : jets) { - fillJetPtHistogramsMCP(jet); jetPtcuts.push_back({jet.pt(), jet.eta(), jet.phi()}); } @@ -227,18 +188,14 @@ struct DijetFinderQATask { for (size_t i = 1; i < jetPtcuts.size() && !found_pair; i++) { auto& candidate_jet = jetPtcuts[i]; - Double_t dphi = fabs(candidate_jet[2] - leading_jet[2]); - if (dphi > M_PI) { - dphi = 2 * M_PI - dphi; - } - if (dphi > 2 * M_PI / 3) { - double pt1 = leading_jet[0]; - double pt2 = candidate_jet[0]; - double eta1 = leading_jet[1]; - double eta2 = candidate_jet[1]; - double phi1 = leading_jet[2]; - double phi2 = candidate_jet[2]; - double dijet_mass = sqrt(2 * pt1 * pt2 * (cosh(eta1 - eta2) - cos(phi1 - phi2))); + Double_t dphi = fabs(leading_jet[2] - candidate_jet[2]); + Double_t deta = fabs(leading_jet[1] - candidate_jet[1]); + Double_t condition = fabs(dphi - M_PI); + + if (condition < setPhiCut * M_PI) { + Double_t pt1 = leading_jet[0]; + Double_t pt2 = candidate_jet[0]; + Double_t dijet_mass = sqrt(2 * pt1 * pt2 * (cosh(deta) - cos(dphi))); fillMassHistogramsMCP(dijet_mass); found_pair = true; } @@ -249,12 +206,11 @@ struct DijetFinderQATask { void processDijetMCD(soa::Filtered::iterator const& collision, soa::Filtered const& jets) { - if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits)) { + if (!jetderiveddatautilities::selectCollision(collision, eventSelection)) { return; } std::vector> jetPtcuts; for (auto& jet : jets) { - fillJetPtHistogramsMCD(jet); jetPtcuts.push_back({jet.pt(), jet.eta(), jet.phi()}); } @@ -264,18 +220,14 @@ struct DijetFinderQATask { for (size_t i = 1; i < jetPtcuts.size() && !found_pair; i++) { auto& candidate_jet = jetPtcuts[i]; - Double_t dphi = fabs(candidate_jet[2] - leading_jet[2]); - if (dphi > M_PI) { - dphi = 2 * M_PI - dphi; - } - if (dphi > 2 * M_PI / 3) { - double pt1 = leading_jet[0]; - double pt2 = candidate_jet[0]; - double eta1 = leading_jet[1]; - double eta2 = candidate_jet[1]; - double phi1 = leading_jet[2]; - double phi2 = candidate_jet[2]; - double dijet_mass = sqrt(2 * pt1 * pt2 * (cosh(eta1 - eta2) - cos(phi1 - phi2))); + Double_t dphi = fabs(leading_jet[2] - candidate_jet[2]); + Double_t deta = fabs(leading_jet[1] - candidate_jet[1]); + Double_t condition = fabs(dphi - M_PI); + + if (condition < setPhiCut * M_PI) { + Double_t pt1 = leading_jet[0]; + Double_t pt2 = candidate_jet[0]; + Double_t dijet_mass = sqrt(2 * pt1 * pt2 * (cosh(deta) - cos(dphi))); fillMassHistogramsMCD(dijet_mass); found_pair = true; } @@ -286,13 +238,12 @@ struct DijetFinderQATask { void processDijetData(soa::Filtered::iterator const& collision, soa::Filtered const& jets) { - if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits)) { + if (!jetderiveddatautilities::selectCollision(collision, eventSelection)) { return; } std::vector> jetPtcuts; for (auto& jet : jets) { - fillJetPtHistogramsData(jet); jetPtcuts.push_back({jet.pt(), jet.eta(), jet.phi()}); } @@ -302,18 +253,14 @@ struct DijetFinderQATask { for (size_t i = 1; i < jetPtcuts.size() && !found_pair; i++) { auto& candidate_jet = jetPtcuts[i]; - Double_t dphi = fabs(candidate_jet[2] - leading_jet[2]); - if (dphi > M_PI) { - dphi = 2 * M_PI - dphi; - } - if (dphi > 2 * M_PI / 3) { - double pt1 = leading_jet[0]; - double pt2 = candidate_jet[0]; - double eta1 = leading_jet[1]; - double eta2 = candidate_jet[1]; - double phi1 = leading_jet[2]; - double phi2 = candidate_jet[2]; - double dijet_mass = sqrt(2 * pt1 * pt2 * (cosh(eta1 - eta2) - cos(phi1 - phi2))); + Double_t dphi = fabs(leading_jet[2] - candidate_jet[2]); + Double_t deta = fabs(leading_jet[1] - candidate_jet[1]); + Double_t condition = fabs(dphi - M_PI); + + if (condition < setPhiCut * M_PI) { + Double_t pt1 = leading_jet[0]; + Double_t pt2 = candidate_jet[0]; + Double_t dijet_mass = sqrt(2 * pt1 * pt2 * (cosh(deta) - cos(dphi))); fillMassHistogramsData(dijet_mass); found_pair = true; } @@ -327,7 +274,7 @@ struct DijetFinderQATask { soa::Filtered> const& mcdjets, JetMCPTable const&, aod::JetTracks const&, aod::JetParticles const&) { - if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits)) { + if (!jetderiveddatautilities::selectCollision(collision, eventSelection)) { return; } @@ -355,26 +302,20 @@ struct DijetFinderQATask { auto& candidate_jet_D = jetPtcuts_D[i]; auto& candidate_jet_P = jetPtcuts_P[i]; - Double_t dphi_D = fabs(candidate_jet_D[2] - leading_jet_D[2]); - if (dphi_D > M_PI) { - dphi_D = 2 * M_PI - dphi_D; - } - if (dphi_D > 2 * M_PI / 3) { + Double_t dphi_D = fabs(leading_jet_D[2] - candidate_jet_D[2]); + Double_t deta_D = fabs(leading_jet_D[1] - candidate_jet_D[1]); + Double_t dphi_P = fabs(leading_jet_P[2] - candidate_jet_P[2]); + Double_t deta_P = fabs(leading_jet_P[1] - candidate_jet_P[1]); + Double_t condition = fabs(dphi_D - M_PI); + + if (condition < setPhiCut * M_PI) { double pt1_D = leading_jet_D[0]; double pt2_D = candidate_jet_D[0]; - double eta1_D = leading_jet_D[1]; - double eta2_D = candidate_jet_D[1]; - double phi1_D = leading_jet_D[2]; - double phi2_D = candidate_jet_D[2]; - double dijet_mass_D = sqrt(2 * pt1_D * pt2_D * (cosh(eta1_D - eta2_D) - cos(phi1_D - phi2_D))); + double dijet_mass_D = sqrt(2 * pt1_D * pt2_D * (cosh(deta_D) - cos(dphi_D))); double pt1_P = leading_jet_P[0]; double pt2_P = candidate_jet_P[0]; - double eta1_P = leading_jet_P[1]; - double eta2_P = candidate_jet_P[1]; - double phi1_P = leading_jet_P[2]; - double phi2_P = candidate_jet_P[2]; - double dijet_mass_P = sqrt(2 * pt1_P * pt2_P * (cosh(eta1_P - eta2_P) - cos(phi1_P - phi2_P))); + double dijet_mass_P = sqrt(2 * pt1_P * pt2_P * (cosh(deta_P) - cos(dphi_P))); fillMassHistogramsMCMatched(dijet_mass_P, dijet_mass_D); found_pair = true; diff --git a/PWGJE/Tasks/fullJetSpectraPP.cxx b/PWGJE/Tasks/fullJetSpectraPP.cxx index 8cdc23ebf9c..a8eb7399502 100644 --- a/PWGJE/Tasks/fullJetSpectraPP.cxx +++ b/PWGJE/Tasks/fullJetSpectraPP.cxx @@ -49,8 +49,7 @@ using namespace o2; using namespace o2::analysis; using namespace o2::framework; using namespace o2::framework::expressions; - -using EMCCollisions = o2::soa::Join; // needed for the workaround to access EMCAL trigger bits +// using namespace jetderiveddatautilities; struct FullJetSpectrapp { @@ -61,8 +60,9 @@ struct FullJetSpectrapp { Configurable centralityMin{"centralityMin", -999.0, "minimum centrality"}; Configurable centralityMax{"centralityMax", 999.0, "maximum centrality"}; Configurable doEMCALEventWorkaround{"doEMCALEventWorkaround", false, "apply the workaround to read the EMC trigger bit by requiring a cell content in the EMCAL"}; - Configurable doMBGapTrigger{"doMBGapTrigger", true, "set to true only when using MB-Gap Trigger JJ MC"}; - Configurable doMBMC{"doMBMC", false, "set to true only when using MB MC"}; + Configurable doMBGapTrigger{"doMBGapTrigger", true, "set to true only when using MB-Gap Trigger JJ MC to reject MB events at the collision and track level"}; + // Configurable doMBMC{"doMBMC", false, "set to true only when using MB MC"}; + Configurable checkMcCollisionIsMatched{"checkMcCollisionIsMatched", false, "0: count whole MCcollisions, 1: select MCcollisions which only have their correspond collisions"}; // Jet configurables Configurable selectedJetsRadius{"selectedJetsRadius", 0.4, "resolution parameter for histograms without radius"}; @@ -84,7 +84,7 @@ struct FullJetSpectrapp { Configurable trackPhiMin{"trackPhiMin", 1.396, "minimum track phi"}; Configurable trackPhiMax{"trackPhiMax", 3.283, "maximum track phi"}; Configurable trackSelections{"trackSelections", "globalTracks", "set track selections"}; - Configurable eventSelections{"eventSelections", "sel8Full", "choose event selection"}; + Configurable eventSelections{"eventSelections", "selMCFull", "choose event selection"}; Configurable particleSelections{"particleSelections", "PhysicalPrimary", "set particle selections"}; // Cluster configurables @@ -95,13 +95,13 @@ struct FullJetSpectrapp { Configurable clusterPhiMin{"clusterPhiMin", 1.396, "minimum cluster phi"}; Configurable clusterPhiMax{"clusterPhiMax", 3.283, "maximum cluster phi"}; Configurable clusterEnergyMin{"clusterEnergyMin", 0.3, "minimum cluster energy in EMCAL (GeV)"}; - Configurable clusterTimeMin{"clusterTimeMin", -20., "minimum cluster time (ns)"}; + Configurable clusterTimeMin{"clusterTimeMin", -15., "minimum cluster time (ns)"}; Configurable clusterTimeMax{"clusterTimeMax", 15., "maximum cluster time (ns)"}; Configurable clusterRejectExotics{"clusterRejectExotics", true, "Reject exotic clusters"}; Configurable pTHatMaxMCD{"pTHatMaxMCD", 999.0, "maximum fraction of hard scattering for jet acceptance in detector MC"}; Configurable pTHatMaxMCP{"pTHatMaxMCP", 999.0, "maximum fraction of hard scattering for jet acceptance in particle MC"}; - Configurable pTHatExponent{"pTHatExponent", 4.0, "exponent of the event weight for the calculation of pTHat"}; // 6 for MB MC and 4 for JJ MC + Configurable pTHatExponent{"pTHatExponent", 4.0, "exponent of the event weight for the calculation of pTHeventSelectionBitsat"}; // 6 for MB MC and 4 for JJ MC Configurable pTHatAbsoluteMin{"pTHatAbsoluteMin", -99.0, "minimum value of pTHat"}; int trackSelection = -1; @@ -118,30 +118,40 @@ struct FullJetSpectrapp { { if (doprocessTracks) { auto h_collisions_unweighted = registry.get(HIST("h_collisions_unweighted")); - h_collisions_unweighted->GetXaxis()->SetBinLabel(1, "total events"); - h_collisions_unweighted->GetXaxis()->SetBinLabel(2, "JetsData with kTVXinEMC"); - h_collisions_unweighted->GetXaxis()->SetBinLabel(3, "JetsMCD with kTVXinEMC"); - h_collisions_unweighted->GetXaxis()->SetBinLabel(4, "Tracks with kTVXinEMC"); - h_collisions_unweighted->GetXaxis()->SetBinLabel(5, "JetsMCPMCDMatched with kTVXinEMC"); - h_collisions_unweighted->GetXaxis()->SetBinLabel(6, "JetsData w/o kTVXinEMC"); - h_collisions_unweighted->GetXaxis()->SetBinLabel(7, "JetsMCD w/o kTVXinEMC"); - h_collisions_unweighted->GetXaxis()->SetBinLabel(8, "Tracks w/o kTVXinEMC"); - h_collisions_unweighted->GetXaxis()->SetBinLabel(9, "JetsMCPMCDMatched w/o kTVXinEMC"); - h_collisions_unweighted->GetXaxis()->SetBinLabel(10, "Fake Matched MCD Jets"); - h_collisions_unweighted->GetXaxis()->SetBinLabel(11, "Fake Matched MCP Jets"); + h_collisions_unweighted->GetXaxis()->SetBinLabel(1, "AllUnweightedDetColl"); + h_collisions_unweighted->GetXaxis()->SetBinLabel(2, "UnweightedCollWithVertexZ"); + h_collisions_unweighted->GetXaxis()->SetBinLabel(3, "EMCAcceptedUnweightedColl"); + h_collisions_unweighted->GetXaxis()->SetBinLabel(4, "UnweightedCollAfterTrackSel"); } if (doprocessTracksWeighted) { auto h_collisions_weighted = registry.get(HIST("h_collisions_weighted")); - h_collisions_weighted->GetXaxis()->SetBinLabel(1, "total events"); - h_collisions_weighted->GetXaxis()->SetBinLabel(2, "JetsMCDWeighted with kTVXinEMC"); - h_collisions_weighted->GetXaxis()->SetBinLabel(3, "JetsMCPMCDMatchedWeighted with kTVXinEMC"); - h_collisions_weighted->GetXaxis()->SetBinLabel(4, "TracksWeighted with kTVXinEMC"); - h_collisions_weighted->GetXaxis()->SetBinLabel(5, "JetsMCDWeighted w/o kTVXinEMC"); - h_collisions_weighted->GetXaxis()->SetBinLabel(6, "JetsMCPMCDMatchedWeighted w/o kTVXinEMC"); - h_collisions_weighted->GetXaxis()->SetBinLabel(7, "TracksWeighted w/o kTVXinEMC"); - h_collisions_weighted->GetXaxis()->SetBinLabel(8, "Fake Matched Weighted MCD Jets"); - h_collisions_weighted->GetXaxis()->SetBinLabel(9, "Fake Matched Weighted MCP Jets"); + h_collisions_weighted->GetXaxis()->SetBinLabel(1, "AllWeightedDetColl"); + h_collisions_weighted->GetXaxis()->SetBinLabel(2, "WeightedCollWithVertexZ"); + h_collisions_weighted->GetXaxis()->SetBinLabel(3, "EMCAcceptedWeightedColl"); + h_collisions_weighted->GetXaxis()->SetBinLabel(4, "WeightedCollAfterTrackSel"); + } + + if (doprocessJetsData || doprocessJetsMCD || doprocessJetsMCDWeighted) { + auto h_Detcollision_counter = registry.get(HIST("h_Detcollision_counter")); + h_Detcollision_counter->GetXaxis()->SetBinLabel(1, "allDetColl"); + h_Detcollision_counter->GetXaxis()->SetBinLabel(2, "DetCollWithVertexZ"); + h_Detcollision_counter->GetXaxis()->SetBinLabel(3, "EMCAcceptedDetColl"); + } + + if (doprocessJetsMCP || doprocessJetsMCPWeighted) { + auto h_Partcollision_counter = registry.get(HIST("h_Partcollision_counter")); + h_Partcollision_counter->GetXaxis()->SetBinLabel(1, "allMcColl"); + h_Partcollision_counter->GetXaxis()->SetBinLabel(2, "McCollWithVertexZ"); + h_Partcollision_counter->GetXaxis()->SetBinLabel(3, "DetCollWithSize>1"); + h_Partcollision_counter->GetXaxis()->SetBinLabel(4, "EMCAcceptedDetColl"); + } + + if (doprocessJetsMCPMCDMatched || doprocessJetsMCPMCDMatchedWeighted) { + auto h_Matchedcollision_counter = registry.get(HIST("h_Matchedcollision_counter")); + h_Matchedcollision_counter->GetXaxis()->SetBinLabel(1, "allDetColl"); + h_Matchedcollision_counter->GetXaxis()->SetBinLabel(2, "DetCollWithVertexZ"); + h_Matchedcollision_counter->GetXaxis()->SetBinLabel(3, "EMCAcceptedDetColl"); } } @@ -187,6 +197,8 @@ struct FullJetSpectrapp { // Jet QA histograms if (doprocessJetsData || doprocessJetsMCD || doprocessJetsMCDWeighted) { + registry.add("h_Detcollision_counter", "event status;event status;entries", {HistType::kTH1F, {{10, 0.0, 10.}}}); + registry.add("h_full_jet_pt", "#it{p}_{T,jet};#it{p}_{T_jet} (GeV/#it{c});entries", {HistType::kTH1F, {{350, 0., 350.}}}); registry.add("h_full_jet_pt_pTHatcut", "#it{p}_{T,jet};#it{p}_{T_jet} (GeV/#it{c});entries", {HistType::kTH1F, {{350, 0., 350.}}}); registry.add("h_full_jet_eta", "jet #eta;#eta_{jet};entries", {HistType::kTH1F, {{100, -1., 1.}}}); @@ -216,6 +228,8 @@ struct FullJetSpectrapp { registry.add("h2_jet_etaphi", "jet #eta vs jet #varphi; #eta_{jet};#varphi_{jet}", {HistType::kTH2F, {{100, -1., 1.}, {160, -1., 7.}}}); } if (doprocessJetsMCP || doprocessJetsMCPWeighted) { + registry.add("h_Partcollision_counter", "event status;event status;entries", {HistType::kTH1F, {{10, 0.0, 10.0}}}); + registry.add("h_full_mcpjet_tablesize", "", {HistType::kTH1F, {{4, 0., 5.}}}); registry.add("h_full_mcpjet_ntracks", "", {HistType::kTH1F, {{200, -0.5, 200.}}}); registry.add("h_full_jet_pt_part", "jet pT;#it{p}_{T_jet} (GeV/#it{c});entries", {HistType::kTH1F, {{350, 0., 350.}}}); @@ -238,9 +252,14 @@ struct FullJetSpectrapp { registry.add("h2_track_etaphi_part", "jet_track #eta vs jet_track #varphi; #eta_{track};#varphi_{track}", {HistType::kTH2F, {{500, -5., 5.}, {160, -1., 7.}}}); registry.add("h2_jet_etaphi_part", "jet #eta vs jet #varphi; #eta_{jet};#varphi_{jet}", {HistType::kTH2F, {{100, -1., 1.}, {160, -1., 7.}}}); + + registry.add("h_NOmcpemcalcollisions", "event status;entries", {HistType::kTH1F, {{100, 0., 100.}}}); + registry.add("h_mcpemcalcollisions", "event status;entries", {HistType::kTH1F, {{100, 0., 100.}}}); } if (doprocessJetsMCPMCDMatched || doprocessJetsMCPMCDMatchedWeighted) { + registry.add("h_Matchedcollision_counter", "event status;event status;entries", {HistType::kTH1F, {{10, 0.0, 10.0}}}); + registry.add("h_full_matchedmcdjet_tablesize", "", {HistType::kTH1F, {{350, 0., 350.}}}); registry.add("h_full_matchedmcpjet_tablesize", "", {HistType::kTH1F, {{350, 0., 350.}}}); registry.add("h_full_matchedmcdjet_ntracks", "", {HistType::kTH1F, {{200, -0.5, 200.}}}); @@ -269,7 +288,14 @@ struct FullJetSpectrapp { registry.add("h2_full_fakemcdjets", "Fake MCD Jets; p_{T,det} (GeV/c); NCounts", {HistType::kTH2F, {{350, 0., 350.}, {100, 0., 100.}}}); registry.add("h2_full_fakemcpjets", "Fake MCP Jets; p_{T,part} (GeV/c); NCounts", {HistType::kTH2F, {{350, 0., 350.}, {100, 0., 100.}}}); // Response Matrix - registry.add("h_full_jet_ResponseMatrix", "Full Jets Response Matrix; p_{T,det} (GeV/c); p_{T,part} (GeV/c)", {HistType::kTH2F, {{200, 0., 200.}, {200, 0., 200.}}}); + registry.add("h_full_jet_ResponseMatrix", "Full Jets Response Matrix; p_{T,det} (GeV/c); p_{T,part} (GeV/c)", {HistType::kTH2F, {{350, 0., 350.}, {350, 0., 350.}}}); + } + + if (doprocessCollisionsWeightedWithMultiplicity || doprocessMBCollisionsWithMultiplicity) { + registry.add("h_FT0Mults_occupancy", "", {HistType::kTH1F, {{3500, 0., 3500.}}}); + registry.add("h2_full_jet_FT0Amplitude", "; FT0C Amplitude; Counts", {HistType::kTH1F, {{3500, 0., 3500.}}}); + registry.add("h2_full_jet_jetpTDetVsFT0Mults", "; p_{T,det} (GeV/c); FT0C Multiplicity", {HistType::kTH2F, {{350, 0., 350.}, {3500, 0., 3500.}}}); + registry.add("h3_full_jet_jetpTDet_FT0Mults_NEF", "; p_{T,det} (GeV/c); FT0C Multiplicity, NEF", {HistType::kTH3F, {{350, 0., 350.}, {3500, 0., 3500.}, {105, 0.0, 1.05}}}); } // Label the histograms @@ -277,6 +303,9 @@ struct FullJetSpectrapp { } // init + using EMCCollisionsData = o2::soa::Join; // JetCollisions with EMCAL Collision Labels + using EMCCollisionsMCD = o2::soa::Join; // where, JetCollisionsMCD = JetCollisions+JMcCollisionLbs + using FullJetTableDataJoined = soa::Join; using JetTableMCDJoined = soa::Join; using JetTableMCDWeightedJoined = soa::Join; @@ -297,6 +326,7 @@ struct FullJetSpectrapp { aod::EMCALClusterDefinition clusterDefinition = aod::emcalcluster::getClusterDefinitionFromString(clusterDefinitionS.value); Filter clusterFilter = (aod::jcluster::definition == static_cast(clusterDefinition) && aod::jcluster::eta > clusterEtaMin && aod::jcluster::eta < clusterEtaMax && aod::jcluster::phi >= clusterPhiMin && aod::jcluster::phi <= clusterPhiMax && aod::jcluster::energy >= clusterEnergyMin && aod::jcluster::time > clusterTimeMin && aod::jcluster::time < clusterTimeMax && (clusterRejectExotics && aod::jcluster::isExotic != true)); Preslice JetMCPPerMcCollision = aod::jet::mcCollisionId; + PresliceUnsorted> CollisionsPerMCPCollision = aod::jmccollisionlb::mcCollisionId; template bool isAcceptedJet(U const& jet) @@ -471,37 +501,37 @@ struct FullJetSpectrapp { return; } - if (jetBase.has_matchedJetGeo()) { // geometrical jet matching only needed for pp - here,matching Base(Det.level) with Tag (Part. level) jets - registry.fill(HIST("h_full_matchedmcdjet_tablesize"), jetBase.size(), weight); - registry.fill(HIST("h_full_matchedmcdjet_ntracks"), jetBase.tracksIds().size(), weight); - registry.fill(HIST("h2_matchedjet_etaphiDet"), jetBase.eta(), jetBase.phi(), weight); + if (jetBase.has_matchedJetGeo()) { // geometrical jet matching only needed for pp - here,matching Base(Det.level) with Tag (Part. level) jets + registry.fill(HIST("h_full_matchedmcdjet_tablesize"), jetBase.size(), weight); + registry.fill(HIST("h_full_matchedmcdjet_ntracks"), jetBase.tracksIds().size(), weight); + registry.fill(HIST("h2_matchedjet_etaphiDet"), jetBase.eta(), jetBase.phi(), weight); - for (auto& jetTag : jetBase.template matchedJetGeo_as>()) { - if (jetTag.pt() > pTHatMaxMCP * pTHat || pTHat < pTHatAbsoluteMin) { // MCP outlier rejection - continue; - } - auto deltaEta = jetBase.eta() - jetTag.eta(); - auto deltaPhi = jetBase.phi() - jetTag.phi(); - auto deltaR = jetutilities::deltaR(jetBase, jetTag); - - registry.fill(HIST("h_full_jet_deltaR"), deltaR, weight); - registry.fill(HIST("h_full_matchedmcpjet_tablesize"), jetTag.size(), weight); - registry.fill(HIST("h_full_matchedmcpjet_ntracks"), jetTag.tracksIds().size(), weight); - registry.fill(HIST("h2_matchedjet_etaphiPart"), jetTag.eta(), jetTag.phi(), weight); - registry.fill(HIST("h2_matchedjet_deltaEtaCorr"), jetBase.eta(), jetTag.eta(), weight); - registry.fill(HIST("h2_matchedjet_deltaPhiCorr"), jetBase.phi(), jetTag.phi(), weight); - - // JES for fulljets - registry.fill(HIST("h2_full_jet_energyscaleDet"), jetBase.pt(), (jetBase.pt() - jetTag.pt()) / jetTag.pt(), weight); - registry.fill(HIST("h2_full_jet_energyscalePart"), jetTag.pt(), (jetBase.pt() - jetTag.pt()) / jetTag.pt(), weight); - registry.fill(HIST("h3_full_jet_energyscalePart"), jetBase.r() / 100.0, jetTag.pt(), (jetBase.pt() - jetTag.pt()) / jetTag.pt(), weight); - registry.fill(HIST("h2_full_jet_etaresolutionPart"), jetTag.pt(), deltaEta / jetTag.eta(), weight); - registry.fill(HIST("h2_full_jet_phiresolutionPart"), jetTag.pt(), deltaPhi / jetTag.phi(), weight); - - // Response Matrix - registry.fill(HIST("h_full_jet_ResponseMatrix"), jetBase.pt(), jetTag.pt(), weight); // MCD vs MCP jet pT - } // jetTag - } // jetBase + for (auto& jetTag : jetBase.template matchedJetGeo_as>()) { + if (jetTag.pt() > pTHatMaxMCP * pTHat || pTHat < pTHatAbsoluteMin) { // MCP outlier rejection + continue; + } + auto deltaEta = jetBase.eta() - jetTag.eta(); + auto deltaPhi = jetBase.phi() - jetTag.phi(); + auto deltaR = jetutilities::deltaR(jetBase, jetTag); + + registry.fill(HIST("h_full_jet_deltaR"), deltaR, weight); + registry.fill(HIST("h_full_matchedmcpjet_tablesize"), jetTag.size(), weight); + registry.fill(HIST("h_full_matchedmcpjet_ntracks"), jetTag.tracksIds().size(), weight); + registry.fill(HIST("h2_matchedjet_etaphiPart"), jetTag.eta(), jetTag.phi(), weight); + registry.fill(HIST("h2_matchedjet_deltaEtaCorr"), jetBase.eta(), jetTag.eta(), weight); + registry.fill(HIST("h2_matchedjet_deltaPhiCorr"), jetBase.phi(), jetTag.phi(), weight); + + // JES for fulljets + registry.fill(HIST("h2_full_jet_energyscaleDet"), jetBase.pt(), (jetBase.pt() - jetTag.pt()) / jetTag.pt(), weight); + registry.fill(HIST("h2_full_jet_energyscalePart"), jetTag.pt(), (jetBase.pt() - jetTag.pt()) / jetTag.pt(), weight); + registry.fill(HIST("h3_full_jet_energyscalePart"), jetBase.r() / 100.0, jetTag.pt(), (jetBase.pt() - jetTag.pt()) / jetTag.pt(), weight); + registry.fill(HIST("h2_full_jet_etaresolutionPart"), jetTag.pt(), deltaEta / jetTag.eta(), weight); + registry.fill(HIST("h2_full_jet_phiresolutionPart"), jetTag.pt(), deltaPhi / jetTag.phi(), weight); + + // Response Matrix + registry.fill(HIST("h_full_jet_ResponseMatrix"), jetBase.pt(), jetTag.pt(), weight); // MCD vs MCP jet pT + } // jetTag + } // jetBase } void processDummy(aod::JetCollisions const&) @@ -509,31 +539,34 @@ struct FullJetSpectrapp { } PROCESS_SWITCH(FullJetSpectrapp, processDummy, "dummy task", true); - void processJetsData(soa::Filtered::iterator const& collision, FullJetTableDataJoined const& jets, aod::JetTracks const&, aod::JetClusters const&) + void processJetsData(soa::Filtered::iterator const& collision, FullJetTableDataJoined const& jets, aod::JetTracks const&, aod::JetClusters const&) { - registry.fill(HIST("h_collisions_unweighted"), 1.0); // total events bool eventAccepted = false; + registry.fill(HIST("h_Detcollision_counter"), 0.5); - // if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits)) { - // return; - // } - + if (fabs(collision.posZ()) > VertexZCut) { + return; + } + registry.fill(HIST("h_Detcollision_counter"), 1.5); + if (doMBGapTrigger && collision.subGeneratorId() == jetderiveddatautilities::JCollisionSubGeneratorId::mbGap) { + return; + } + if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits, doMBGapTrigger)) { + return; + } if (doEMCALEventWorkaround) { if (collision.isEmcalReadout() && !collision.isAmbiguous()) { // i.e. EMCAL has a cell content eventAccepted = true; if (collision.alias_bit(kTVXinEMC)) { - registry.fill(HIST("h_collisions_unweighted"), 2.0); // JetsData with kTVXinEMC } } } else { if (!collision.isAmbiguous() && jetderiveddatautilities::eventEMCAL(collision) && collision.alias_bit(kTVXinEMC)) { eventAccepted = true; - registry.fill(HIST("h_collisions_unweighted"), 2.0); // JetsData with kTVXinEMC } } if (!eventAccepted) { - registry.fill(HIST("h_collisions_unweighted"), 6.0); // JetsData w/o kTVXinEMC for (auto const& jet : jets) { if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax) || !isAcceptedJet(jet)) { fillRejectedJetHistograms(jet, 1.0); @@ -541,6 +574,7 @@ struct FullJetSpectrapp { } return; } + registry.fill(HIST("h_Detcollision_counter"), 2.5); for (auto const& jet : jets) { if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { @@ -557,27 +591,34 @@ struct FullJetSpectrapp { } PROCESS_SWITCH(FullJetSpectrapp, processJetsData, "Full Jets Data", false); - void processJetsMCD(soa::Filtered>::iterator const& collision, JetTableMCDJoined const& jets, aod::JetTracks const&, aod::JetClusters const&) + void processJetsMCD(soa::Filtered::iterator const& collision, JetTableMCDJoined const& jets, aod::JetTracks const&, aod::JetClusters const&) { - registry.fill(HIST("h_collisions_unweighted"), 1.0); // total events bool eventAccepted = false; + registry.fill(HIST("h_Detcollision_counter"), 0.5); + if (fabs(collision.posZ()) > VertexZCut) { + return; + } + registry.fill(HIST("h_Detcollision_counter"), 1.5); + if (doMBGapTrigger && collision.subGeneratorId() == jetderiveddatautilities::JCollisionSubGeneratorId::mbGap) { + return; + } + if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits, doMBGapTrigger)) { + return; + } if (doEMCALEventWorkaround) { if (collision.isEmcalReadout() && !collision.isAmbiguous()) { // i.e. EMCAL has a cell content eventAccepted = true; if (collision.alias_bit(kTVXinEMC)) { - registry.fill(HIST("h_collisions_unweighted"), 3.0); // JetsMCD with kTVXinEMC } } } else { if (!collision.isAmbiguous() && jetderiveddatautilities::eventEMCAL(collision) && collision.alias_bit(kTVXinEMC)) { eventAccepted = true; - registry.fill(HIST("h_collisions_unweighted"), 3.0); // JetsMCD with kTVXinEMC } } if (!eventAccepted) { - registry.fill(HIST("h_collisions_unweighted"), 7.0); // JetsMCD w/o kTVXinEMC for (auto const& jet : jets) { if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax) || !isAcceptedJet(jet)) { fillRejectedJetHistograms(jet, 1.0); @@ -585,6 +626,7 @@ struct FullJetSpectrapp { } return; } + registry.fill(HIST("h_Detcollision_counter"), 2.5); for (auto const& jet : jets) { if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { @@ -601,32 +643,35 @@ struct FullJetSpectrapp { } PROCESS_SWITCH(FullJetSpectrapp, processJetsMCD, "Full Jets at Detector Level", false); - void processJetsMCDWeighted(soa::Filtered>::iterator const& collision, JetTableMCDWeightedJoined const& jets, aod::JMcCollisions const&, aod::JetTracks const&, aod::JetClusters const&) + void processJetsMCDWeighted(soa::Filtered::iterator const& collision, JetTableMCDWeightedJoined const& jets, aod::JMcCollisions const&, aod::JetTracks const&, aod::JetClusters const&) { - registry.fill(HIST("h_collisions_weighted"), 1.0); // total events bool eventAccepted = false; - // if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits)) { - // return; - // } + registry.fill(HIST("h_Detcollision_counter"), 0.5); + if (fabs(collision.posZ()) > VertexZCut) { + return; + } + registry.fill(HIST("h_Detcollision_counter"), 1.5); + if (doMBGapTrigger && collision.subGeneratorId() == jetderiveddatautilities::JCollisionSubGeneratorId::mbGap) { + return; + } + if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits, doMBGapTrigger)) { + return; + } if (doEMCALEventWorkaround) { if (collision.isEmcalReadout() && !collision.isAmbiguous()) { // i.e. EMCAL has a cell content eventAccepted = true; if (collision.alias_bit(kTVXinEMC)) { - registry.fill(HIST("h_collisions_weighted"), 2.0); // JetsMCDWeighted with kTVXinEMC } } } else { if (!collision.isAmbiguous() && jetderiveddatautilities::eventEMCAL(collision) && collision.alias_bit(kTVXinEMC)) { eventAccepted = true; - registry.fill(HIST("h_collisions_weighted"), 2.0); // JetsMCDWeighted with kTVXinEMC } } if (!eventAccepted) { - registry.fill(HIST("h_collisions_weighted"), 5.0); // JetsMCDWeighted w/o kTVXinEMC - for (auto const& jet : jets) { if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax) || !isAcceptedJet(jet)) { fillRejectedJetHistograms(jet, collision.mcCollision().weight()); @@ -634,6 +679,7 @@ struct FullJetSpectrapp { } return; } + registry.fill(HIST("h_Detcollision_counter"), 2.5); for (auto const& jet : jets) { if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { @@ -645,9 +691,6 @@ struct FullJetSpectrapp { if (!isAcceptedJet(jet)) { continue; } - if (doMBGapTrigger && collision.mcCollision().weight() == 1) { - continue; - } // this cut only to be used for calculating Jet Purity and not for Response Matrix // this is mainly applied to remove all high weight jets causing big fluctuations @@ -661,116 +704,160 @@ struct FullJetSpectrapp { } PROCESS_SWITCH(FullJetSpectrapp, processJetsMCDWeighted, "Full Jets at Detector Level on weighted events", false); - void processJetsMCP(typename JetTableMCPJoined::iterator const& jet, aod::JetParticles const&) - { - if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { - return; - } - if (!isAcceptedJet(jet)) { - return; - } - fillMCPHistograms(jet); - } - PROCESS_SWITCH(FullJetSpectrapp, processJetsMCP, "Full Jets at Particle Level", false); - - void processJetsMCPWeighted(typename JetTableMCPWeightedJoined::iterator const& jet, aod::JetParticles const&, aod::JetMcCollisions const&) + void processJetsMCP(aod::JetMcCollision const& mccollision, JetTableMCPJoined const& jets, aod::JetParticles const&, soa::SmallGroups const& collisions) { + bool eventAccepted = false; - if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { + registry.fill(HIST("h_Partcollision_counter"), 0.5); + if (fabs(mccollision.posZ()) > VertexZCut) { return; } - if (!isAcceptedJet(jet)) { + registry.fill(HIST("h_Partcollision_counter"), 1.5); + if (collisions.size() < 1) { return; } - if (doMBGapTrigger && jet.eventWeight() == 1) { + registry.fill(HIST("h_Partcollision_counter"), 2.5); + for (auto const& collision : collisions) { + if (doMBGapTrigger && collision.subGeneratorId() == jetderiveddatautilities::JCollisionSubGeneratorId::mbGap) { + return; + } + if (jetderiveddatautilities::selectCollision(collision, eventSelectionBits, doMBGapTrigger)) { + eventAccepted = true; + // return; + } + if (doEMCALEventWorkaround) { + if (collision.isEmcalReadout() && !collision.isAmbiguous()) { // i.e. EMCAL has a cell content + eventAccepted = true; + if (collision.alias_bit(kTVXinEMC)) { + } + } + } else { + if (!collision.isAmbiguous() && jetderiveddatautilities::eventEMCAL(collision) && collision.alias_bit(kTVXinEMC)) { + eventAccepted = true; + } + } + } + if (!eventAccepted) { return; } + registry.fill(HIST("h_Partcollision_counter"), 3.5); - fillMCPHistograms(jet, jet.eventWeight()); + for (auto const& jet : jets) { + if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { + continue; + } + if (!isAcceptedJet(jet)) { + continue; + } + if (checkMcCollisionIsMatched) { // basically checks if the same collisions are generated at the Part level as those at the Det level + auto collisionspermcpjet = collisions.sliceBy(CollisionsPerMCPCollision, jet.mcCollisionId()); + if (collisionspermcpjet.size() >= 1 && jetderiveddatautilities::selectCollision(collisionspermcpjet.begin(), eventSelectionBits)) { + // Now here for every matched collision, I fill the corresponding jet histograms. + fillMCPHistograms(jet); + } + } else { + fillMCPHistograms(jet); + } + } } - PROCESS_SWITCH(FullJetSpectrapp, processJetsMCPWeighted, "Full Jets at Particle Level on weighted events", false); + PROCESS_SWITCH(FullJetSpectrapp, processJetsMCP, "Full Jets at Particle Level", false); - void processTracks(soa::Filtered::iterator const& collision, soa::Filtered const& tracks, soa::Filtered const& clusters) + void processJetsMCPWeighted(aod::JetMcCollision const& mccollision, JetTableMCPWeightedJoined const& jets, aod::JetParticles const&, soa::SmallGroups const& collisions) { - registry.fill(HIST("h_collisions_unweighted"), 1.0); // total events bool eventAccepted = false; - if (fabs(collision.posZ()) > VertexZCut) { + + registry.fill(HIST("h_Partcollision_counter"), 0.5); + if (fabs(mccollision.posZ()) > VertexZCut) { return; } - // if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits)) { - // return; - // } - // needed for the workaround to access EMCAL trigger bits. - This is needed for the MC productions in which the EMC trigger bits are missing. (MB MC LHC24f3, for ex.) - // It first requires for atleast a cell in EMCAL to have energy content. - // Once it finds a cell content, - // it then checks if the collision is not an ambiguous collision (i.e. it has to be a unique collision = no bunch pile up) - // If all of these conditions are satisfied then it checks for the required trigger bit in EMCAL. - // For LHC22o, since the EMCAL didn't have hardware triggers, one would only require MB trigger (kTVXinEMC) in the EMCAL. - - if (doEMCALEventWorkaround) { - if (collision.isEmcalReadout() && !collision.isAmbiguous()) { // i.e. EMCAL has a cell content - eventAccepted = true; - if (collision.alias_bit(kTVXinEMC)) { - registry.fill(HIST("h_collisions_unweighted"), 4.0); // Tracks with kTVXinEMC - } + registry.fill(HIST("h_Partcollision_counter"), 1.5); + if (collisions.size() < 1) { + return; + } + registry.fill(HIST("h_Partcollision_counter"), 2.5); + for (auto const& collision : collisions) { + if (doMBGapTrigger && collision.subGeneratorId() == jetderiveddatautilities::JCollisionSubGeneratorId::mbGap) { + return; } - } else { - // Check if EMCAL was readout with the MB trigger(kTVXinEMC) fired. If not then reject the event and exit the function. - // This is the default check for the simulations with proper trigger flags not requiring the above workaround. - if (!collision.isAmbiguous() && jetderiveddatautilities::eventEMCAL(collision) && collision.alias_bit(kTVXinEMC)) { + if (jetderiveddatautilities::selectCollision(collision, eventSelectionBits, doMBGapTrigger)) { eventAccepted = true; - registry.fill(HIST("h_collisions_unweighted"), 4.0); // Tracks with kTVXinEMC + } + if (doEMCALEventWorkaround) { + if (collision.isEmcalReadout() && !collision.isAmbiguous()) { // i.e. EMCAL has a cell content + eventAccepted = true; + if (collision.alias_bit(kTVXinEMC)) { + } + } + } else { + if (!collision.isAmbiguous() && jetderiveddatautilities::eventEMCAL(collision) && collision.alias_bit(kTVXinEMC)) { + eventAccepted = true; + } } } - if (!eventAccepted) { - registry.fill(HIST("h_collisions_unweighted"), 8.0); // Tracks w/o kTVXinEMC return; } - // Fill Accepted events histos - fillTrackHistograms(tracks, clusters, 1.0); + registry.fill(HIST("h_Partcollision_counter"), 3.5); + + for (auto const& jet : jets) { + if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { + return; + } + if (!isAcceptedJet(jet)) { + return; + } + if (doMBGapTrigger && jet.eventWeight() == 1) { + return; + } + + if (checkMcCollisionIsMatched) { + auto collisionspermcpjet = collisions.sliceBy(CollisionsPerMCPCollision, jet.mcCollisionId()); + + if (collisionspermcpjet.size() >= 1 && jetderiveddatautilities::selectCollision(collisionspermcpjet.begin(), eventSelectionBits)) { + fillMCPHistograms(jet, jet.eventWeight()); + } + } else { + fillMCPHistograms(jet, jet.eventWeight()); + } + } } - PROCESS_SWITCH(FullJetSpectrapp, processTracks, "Full Jet tracks", false); + PROCESS_SWITCH(FullJetSpectrapp, processJetsMCPWeighted, "Full Jets at Particle Level on weighted events", false); - void processJetsMCPMCDMatched(soa::Filtered>::iterator const& collision, JetTableMCDMatchedJoined const& mcdjets, JetTableMCPMatchedJoined const& mcpjets, aod::JMcCollisions const&, aod::JetTracks const&, aod::JetClusters const&, aod::JetParticles const&) + void processJetsMCPMCDMatched(soa::Filtered::iterator const& collision, JetTableMCDMatchedJoined const& mcdjets, JetTableMCPMatchedJoined const& mcpjets, aod::JMcCollisions const&, aod::JetTracks const&, aod::JetClusters const&, aod::JetParticles const&) { - registry.fill(HIST("h_collisions_unweighted"), 1.0); // total events bool eventAccepted = false; int fakemcdjet = 0; int fakemcpjet = 0; - // float pTHat = 10. / (std::pow(eventWeight, 1.0 / pTHatExponent)); + const auto mcpJetsPerMcCollision = mcpjets.sliceBy(JetMCPPerMcCollision, collision.mcCollisionId()); + + registry.fill(HIST("h_Matchedcollision_counter"), 0.5); + if (fabs(collision.posZ()) > VertexZCut) { // making double sure this condition is satisfied return; } - // if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits)) { - // return; - // } - const auto mcpJetsPerMcCollision = mcpjets.sliceBy(JetMCPPerMcCollision, collision.mcCollisionId()); + registry.fill(HIST("h_Matchedcollision_counter"), 1.5); - // for (auto mcpjet : mcpJetsPerMcCollision) { - // if (mcpjet.pt() > pTHatMaxMCP * pTHat) { // outlier rejection for MCP - // return; - // } - // } - //**start of event selection** + if (doMBGapTrigger && collision.subGeneratorId() == jetderiveddatautilities::JCollisionSubGeneratorId::mbGap) { + return; + } + if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits, doMBGapTrigger)) { + return; + } if (doEMCALEventWorkaround) { if (collision.isEmcalReadout() && !collision.isAmbiguous()) { // i.e. EMCAL has a cell content eventAccepted = true; if (collision.alias_bit(kTVXinEMC)) { - registry.fill(HIST("h_collisions_unweighted"), 5.0); // JetsMCPMCDMatched with kTVXinEMC } } } else { if (!collision.isAmbiguous() && jetderiveddatautilities::eventEMCAL(collision) && collision.alias_bit(kTVXinEMC)) { eventAccepted = true; - registry.fill(HIST("h_collisions_unweighted"), 5.0); // JetsMCPMCDMatched with kTVXinEMC } } if (!eventAccepted) { - registry.fill(HIST("h_collisions_unweighted"), 9.0); // JetsMCPMCDMatched w/o kTVXinEMC return; } - //**end of event selection** + registry.fill(HIST("h_Matchedcollision_counter"), 2.5); for (const auto& mcdjet : mcdjets) { if (!jetfindingutilities::isInEtaAcceptance(mcdjet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { @@ -779,47 +866,41 @@ struct FullJetSpectrapp { // Check if MCD jet is within the EMCAL fiducial region; if not then flag it as a fake jet if (mcdjet.phi() < jetPhiMin || mcdjet.phi() > jetPhiMax || mcdjet.eta() < jetEtaMin || mcdjet.eta() > jetEtaMax) { fakemcdjet++; - registry.fill(HIST("h_collisions_unweighted"), 10.0); // Fake Matched MCD Jets registry.fill(HIST("h2_full_fakemcdjets"), mcdjet.pt(), fakemcdjet, 1.0); continue; } if (!isAcceptedJet(mcdjet)) { continue; } - for (auto& mcpjet : mcdjet.template matchedJetGeo_as()) { // apply emcal fiducial cuts to the matched particle level jets if (mcpjet.eta() > jetEtaMax || mcpjet.eta() < jetEtaMin || mcpjet.phi() > jetPhiMax || mcpjet.phi() < jetPhiMin) { fakemcpjet++; - registry.fill(HIST("h_collisions_unweighted"), 11.0); // Fake Matched MCP Jets registry.fill(HIST("h2_full_fakemcpjets"), mcpjet.pt(), fakemcpjet, 1.0); continue; } } // mcpjet loop - - // // Fill MCD jet histograms if a valid MCP jet match was found within the EMCAL region - // registry.fill(HIST("h_full_matchedmcpjet_eta"), mcpjet.eta(), 1.0); - // registry.fill(HIST("h_full_matchedmcpjet_phi"), mcpjet.phi(), 1.0); - fillMatchedHistograms(mcdjet); + fillMatchedHistograms(mcdjet); } // mcdjet loop } PROCESS_SWITCH(FullJetSpectrapp, processJetsMCPMCDMatched, "Full Jet finder MCP matched to MCD", false); - void processJetsMCPMCDMatchedWeighted(soa::Filtered>::iterator const& collision, JetTableMCDMatchedWeightedJoined const& mcdjets, JetTableMCPMatchedWeightedJoined const& mcpjets, aod::JMcCollisions const&, aod::JetTracks const&, aod::JetClusters const&, aod::JetParticles const&) + void processJetsMCPMCDMatchedWeighted(soa::Filtered::iterator const& collision, JetTableMCDMatchedWeightedJoined const& mcdjets, JetTableMCPMatchedWeightedJoined const& mcpjets, aod::JMcCollisions const&, aod::JetTracks const&, aod::JetClusters const&, aod::JetParticles const&) { float eventWeight = collision.mcCollision().weight(); + registry.fill(HIST("h_Matchedcollision_counter"), 0.5); if (fabs(collision.posZ()) > VertexZCut) { // making double sure this condition is satisfied return; } - if (doMBGapTrigger && eventWeight == 1) { + registry.fill(HIST("h_Matchedcollision_counter"), 1.5); + + if (doMBGapTrigger && collision.subGeneratorId() == jetderiveddatautilities::JCollisionSubGeneratorId::mbGap) { + return; + } + if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits, doMBGapTrigger)) { return; } - // if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits)) { - // return; - // } - - registry.fill(HIST("h_collisions_weighted"), 1.0, eventWeight); // total events with eventWeight!=1 bool eventAccepted = false; int fakemcdjet = 0; int fakemcpjet = 0; @@ -831,31 +912,28 @@ struct FullJetSpectrapp { return; } } - if (doEMCALEventWorkaround) { if (collision.isEmcalReadout() && !collision.isAmbiguous()) { // i.e. EMCAL has a cell content eventAccepted = true; if (collision.alias_bit(kTVXinEMC)) { - registry.fill(HIST("h_collisions_weighted"), 3.0, eventWeight); // JetsMCPMCDMatchedWeighted with kTVXinEMC + registry.fill(HIST("h_Matchedcollision_counter"), eventWeight); } } } else { if (!collision.isAmbiguous() && jetderiveddatautilities::eventEMCAL(collision) && collision.alias_bit(kTVXinEMC)) { eventAccepted = true; - registry.fill(HIST("h_collisions_weighted"), 3.0, eventWeight); // JetsMCPMCDMatchedWeighted with kTVXinEMC + registry.fill(HIST("h_Matchedcollision_counter"), eventWeight); } } - if (!eventAccepted) { - registry.fill(HIST("h_collisions_weighted"), 6.0, eventWeight); // JetsMCPMCDMatchedWeighted w/o kTVXinEMC return; } + registry.fill(HIST("h_Matchedcollision_counter"), 2.5); for (const auto& mcdjet : mcdjets) { // Check if MCD jet is within the EMCAL fiducial region; if not then flag it as a fake jet if (mcdjet.phi() < jetPhiMin || mcdjet.phi() > jetPhiMax || mcdjet.eta() < jetEtaMin || mcdjet.eta() > jetEtaMax) { fakemcdjet++; - registry.fill(HIST("h_collisions_weighted"), 8.0); // Fake Matched Weighted MCD Jets registry.fill(HIST("h2_full_fakemcdjets"), mcdjet.pt(), fakemcdjet, eventWeight); continue; } @@ -870,7 +948,6 @@ struct FullJetSpectrapp { // apply emcal fiducial cuts to the matched particle level jets if (mcpjet.eta() > jetEtaMax || mcpjet.eta() < jetEtaMin || mcpjet.phi() > jetPhiMax || mcpjet.phi() < jetPhiMin) { fakemcpjet++; - registry.fill(HIST("h_collisions_weighted"), 9.0); // Fake Matched Weighted MCP Jets registry.fill(HIST("h2_full_fakemcpjets"), mcpjet.pt(), fakemcpjet, eventWeight); continue; } @@ -878,31 +955,87 @@ struct FullJetSpectrapp { registry.fill(HIST("h_full_matchedmcpjet_eta"), mcpjet.eta(), eventWeight); registry.fill(HIST("h_full_matchedmcpjet_phi"), mcpjet.phi(), eventWeight); } // mcpjet - // Fill MCD jet histograms if a valid MCP jet match was found within the EMCAL region - // registry.fill(HIST("h_full_matchedmcdjet_eta"), mcdjet.eta(), eventWeight); - // registry.fill(HIST("h_full_matchedmcdjet_phi"), mcdjet.phi(), eventWeight); - fillMatchedHistograms(mcdjet, mcdjet.eventWeight()); + fillMatchedHistograms(mcdjet, eventWeight); } // mcdjet } PROCESS_SWITCH(FullJetSpectrapp, processJetsMCPMCDMatchedWeighted, "Full Jet finder MCP matched to MCD on weighted events", false); - void processTracksWeighted(soa::Filtered>::iterator const& collision, + void processTracks(soa::Filtered::iterator const& collision, soa::Filtered const& tracks, soa::Filtered const& clusters) + { + bool eventAccepted = false; + + registry.fill(HIST("h_collisions_unweighted"), 0.5); + if (fabs(collision.posZ()) > VertexZCut) { + return; + } + registry.fill(HIST("h_collisions_unweighted"), 1.5); + if (doMBGapTrigger && collision.subGeneratorId() == jetderiveddatautilities::JCollisionSubGeneratorId::mbGap) { + return; + } + if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits, doMBGapTrigger)) { + return; + } + // needed for the workaround to access EMCAL trigger bits. - This is needed for the MC productions in which the EMC trigger bits are missing. (MB MC LHC24f3, for ex.) + // It first requires for atleast a cell in EMCAL to have energy content. + // Once it finds a cell content, + // it then checks if the collision is not an ambiguous collision (i.e. it has to be a unique collision = no bunch pile up) + // If all of these conditions are satisfied then it checks for the required trigger bit in EMCAL. + // For LHC22o, since the EMCAL didn't have hardware triggers, one would only require MB trigger (kTVXinEMC) in the EMCAL. + + if (doEMCALEventWorkaround) { + if (collision.isEmcalReadout() && !collision.isAmbiguous()) { // i.e. EMCAL has a cell content + eventAccepted = true; + if (collision.alias_bit(kTVXinEMC)) { + registry.fill(HIST("h_collisions_unweighted"), 4.0); // Tracks with kTVXinEMC + registry.fill(HIST("h_Detcollision_counter"), 1.0); + } + } + } else { + // Check if EMCAL was readout with the MB trigger(kTVXinEMC) fired. If not then reject the event and exit the function. + // This is the default check for the simulations with proper trigger flags not requiring the above workaround. + if (!collision.isAmbiguous() && jetderiveddatautilities::eventEMCAL(collision) && collision.alias_bit(kTVXinEMC)) { + eventAccepted = true; + registry.fill(HIST("h_collisions_unweighted"), 4.0); // Tracks with kTVXinEMC + registry.fill(HIST("h_Detcollision_counter"), 1.0); + } + } + + if (!eventAccepted) { + registry.fill(HIST("h_collisions_unweighted"), 8.0); // Tracks w/o kTVXinEMC + return; + } + registry.fill(HIST("h_collisions_unweighted"), 2.5); + + for (auto const& track : tracks) { + if (!jetderiveddatautilities::selectTrack(track, trackSelection)) { + continue; + } + // Fill Accepted events histos + fillTrackHistograms(tracks, clusters, 1.0); + } + registry.fill(HIST("h_collisions_unweighted"), 3.5); + } + PROCESS_SWITCH(FullJetSpectrapp, processTracks, "Full Jet tracks", false); + + void processTracksWeighted(soa::Filtered::iterator const& collision, aod::JMcCollisions const&, soa::Filtered const& tracks, soa::Filtered const& clusters) { bool eventAccepted = false; float eventWeight = collision.mcCollision().weight(); + + registry.fill(HIST("h_collisions_weighted"), 0.5); if (fabs(collision.posZ()) > VertexZCut) { return; } - if (eventWeight == 1) { + registry.fill(HIST("h_collisions_weighted"), 1.5); + if (doMBGapTrigger && collision.subGeneratorId() == jetderiveddatautilities::JCollisionSubGeneratorId::mbGap) { + return; + } + if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits, doMBGapTrigger)) { return; } - // if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits)) { - // return; - // } - // set "doMBGapTrigger" to true only if you are testing with MB Gap-triggers if (doMBGapTrigger && eventWeight == 1) { return; } @@ -917,8 +1050,6 @@ struct FullJetSpectrapp { } } } else { - // Check if EMCAL was readout with the MB trigger(kTVXinEMC) fired. If not then reject the event and exit the function. - // This is the default check for the simulations with proper trigger flags not requiring the above workaround. if (!collision.isAmbiguous() && jetderiveddatautilities::eventEMCAL(collision) && collision.alias_bit(kTVXinEMC)) { eventAccepted = true; registry.fill(HIST("h_collisions_weighted"), 4.0, eventWeight); // TracksWeighted with kTVXinEMC @@ -929,11 +1060,148 @@ struct FullJetSpectrapp { registry.fill(HIST("h_collisions_weighted"), 7.0, eventWeight); // TracksWeighted w/o kTVXinEMC return; } - // registry.fill(HIST("h_gaptrig_collisions"), 1.0, eventWeight); - fillTrackHistograms(tracks, clusters, eventWeight); + registry.fill(HIST("h_collisions_weighted"), 2.5); + + for (auto const& track : tracks) { + if (!jetderiveddatautilities::selectTrack(track, trackSelection)) { + continue; + } + // Fill Accepted events histos + fillTrackHistograms(tracks, clusters, 1.0); + } + registry.fill(HIST("h_collisions_weighted"), 3.5); } PROCESS_SWITCH(FullJetSpectrapp, processTracksWeighted, "Full Jet tracks weighted", false); + void processCollisionsWeightedWithMultiplicity(soa::Filtered>::iterator const& collision, JetTableMCDWeightedJoined const& mcdjets, aod::JMcCollisions const&, soa::Filtered const& tracks, soa::Filtered const& clusters) + { + bool eventAccepted = false; + float eventWeight = collision.mcCollision().weight(); + float neutralEnergy = 0.0; + + if (fabs(collision.posZ()) > VertexZCut) { + return; + } + if (doMBGapTrigger && collision.subGeneratorId() == jetderiveddatautilities::JCollisionSubGeneratorId::mbGap) { + return; + } + if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits, doMBGapTrigger)) { + return; + } + if (doMBGapTrigger && eventWeight == 1) { + return; + } + + if (doEMCALEventWorkaround) { + if (collision.isEmcalReadout() && !collision.isAmbiguous()) { // i.e. EMCAL has a cell content + eventAccepted = true; + fillTrackHistograms(tracks, clusters, eventWeight); + if (collision.alias_bit(kTVXinEMC)) { + } + } + } else { + if (!collision.isAmbiguous() && jetderiveddatautilities::eventEMCAL(collision) && collision.alias_bit(kTVXinEMC)) { + eventAccepted = true; + } + } + + if (!eventAccepted) { + return; + } + for (auto const& track : tracks) { + if (!jetderiveddatautilities::selectTrack(track, trackSelection)) { + continue; + } + } + registry.fill(HIST("h_FT0Mults_occupancy"), collision.multiplicity()); + + for (auto const& mcdjet : mcdjets) { + float pTHat = 10. / (std::pow(eventWeight, 1.0 / pTHatExponent)); + if (mcdjet.pt() > pTHatMaxMCD * pTHat || pTHat < pTHatAbsoluteMin) { // MCD jets outlier rejection + return; + } + if (!jetfindingutilities::isInEtaAcceptance(mcdjet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { + continue; + } + if (mcdjet.phi() < jetPhiMin || mcdjet.phi() > jetPhiMax) { + continue; + } + if (!isAcceptedJet(mcdjet)) { + continue; + } + registry.fill(HIST("h2_full_jet_jetpTDetVsFT0Mults"), mcdjet.pt(), collision.multiplicity(), eventWeight); + + for (auto const& cluster : clusters) { + neutralEnergy += cluster.energy(); + } + auto NEF = neutralEnergy / mcdjet.energy(); + registry.fill(HIST("h3_full_jet_jetpTDet_FT0Mults_NEF"), mcdjet.pt(), collision.multiplicity(), NEF, eventWeight); + } + } + PROCESS_SWITCH(FullJetSpectrapp, processCollisionsWeightedWithMultiplicity, "Weighted Collisions for Full Jets Multiplicity Studies", false); + + void processMBCollisionsWithMultiplicity(soa::Filtered>::iterator const& collision, JetTableMCDJoined const& mcdjets, aod::JMcCollisions const&, soa::Filtered const& tracks, soa::Filtered const& clusters) + { + bool eventAccepted = false; + float pTHat = 10. / (std::pow(1.0, 1.0 / pTHatExponent)); + float neutralEnergy = 0.0; + + if (fabs(collision.posZ()) > VertexZCut) { + return; + } + if (doMBGapTrigger && collision.subGeneratorId() == jetderiveddatautilities::JCollisionSubGeneratorId::mbGap) { + return; + } + if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits, doMBGapTrigger)) { + return; + } + + if (doEMCALEventWorkaround) { + if (collision.isEmcalReadout() && !collision.isAmbiguous()) { // i.e. EMCAL has a cell content + eventAccepted = true; + fillTrackHistograms(tracks, clusters, 1.0); + if (collision.alias_bit(kTVXinEMC)) { + } + } + } else { + if (!collision.isAmbiguous() && jetderiveddatautilities::eventEMCAL(collision) && collision.alias_bit(kTVXinEMC)) { + eventAccepted = true; + } + } + + if (!eventAccepted) { + return; + } + for (auto const& track : tracks) { + if (!jetderiveddatautilities::selectTrack(track, trackSelection)) { + continue; + } + } + registry.fill(HIST("h_FT0Mults_occupancy"), collision.multiplicity()); + + for (auto const& mcdjet : mcdjets) { + if (mcdjet.pt() > pTHatMaxMCD * pTHat || pTHat < pTHatAbsoluteMin) { // MCD (Detector Level) Outlier Rejection + return; + } + if (!jetfindingutilities::isInEtaAcceptance(mcdjet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { + continue; + } + if (mcdjet.phi() < jetPhiMin || mcdjet.phi() > jetPhiMax) { + continue; + } + if (!isAcceptedJet(mcdjet)) { + continue; + } + registry.fill(HIST("h2_full_jet_jetpTDetVsFT0Mults"), mcdjet.pt(), collision.multiplicity(), 1.0); + + for (auto const& cluster : clusters) { + neutralEnergy += cluster.energy(); + } + auto NEF = neutralEnergy / mcdjet.energy(); + registry.fill(HIST("h3_full_jet_jetpTDet_FT0Mults_NEF"), mcdjet.pt(), collision.multiplicity(), NEF, 1.0); + } + } + PROCESS_SWITCH(FullJetSpectrapp, processMBCollisionsWithMultiplicity, "MB Collisions for Full Jets Multiplicity Studies", false); }; // struct WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGJE/Tasks/fullJetTriggerQATask.cxx b/PWGJE/Tasks/fullJetTriggerQATask.cxx index c9a9152381d..bbab8a61f0d 100644 --- a/PWGJE/Tasks/fullJetTriggerQATask.cxx +++ b/PWGJE/Tasks/fullJetTriggerQATask.cxx @@ -88,6 +88,7 @@ struct JetTriggerQA { Configurable b_DoFiducialCut{"b_DoFiducialCut", false, "do a fiducial cut on jets to check if they are in the emcal"}; Configurable b_RejectExoticClusters{"b_RejectExoticClusters", true, "Reject exotic clusters"}; Configurable f_GammaObservable{"f_gammaObservable", 0, "Observable for gamma trigger (0 - energy, 1 - pt)"}; + Configurable b_doLightOutput{"b_doLightOutput", true, "do light output (disables most histograms not needed for QA)"}; Configurable cfgVertexCut{"cfgVertexCut", 10.0f, "Accepted z-vertex range"}; Configurable mClusterDefinition{"clusterDefinition", "kV3Default", "cluster definition to be selected, e.g. V3Default"}; @@ -103,18 +104,18 @@ struct JetTriggerQA { jetReclusterer.algorithm = fastjet::JetAlgorithm::cambridge_algorithm; jetReclusterer.jetR = f_jetR * 2.5; // Use larger R for CA reclustering to prevent losing particles - Int_t nPtBins = 200; - Float_t kMinPt = 0.; - Float_t kMaxPt = 201.; - Int_t nPhiBins = 18 * 8; - Float_t kMinPhi = 0.; - Float_t kMaxPhi = 2. * TMath::Pi(); - Int_t nEtaBins = 100; - Float_t kMinEta = -1.; - Float_t kMaxEta = 1.; - Int_t nRBins = 6; - Float_t kMinR = 0.05; - Float_t kMaxR = 0.65; + int nPtBins = 200; + float kMinPt = 0.; + float kMaxPt = 201.; + int nPhiBins = 18 * 8; + float kMinPhi = 0.; + float kMaxPhi = o2::constants::math::TwoPI; + int nEtaBins = 100; + float kMinEta = -1.; + float kMaxEta = 1.; + int nRBins = 6; + float kMinR = 0.05; + float kMaxR = 0.65; // EMCAL gamma observables (for histogram and axis title) std::string observableName = (f_GammaObservable == 0) ? "Energy" : "#it{p}_{T}", @@ -137,9 +138,11 @@ struct JetTriggerQA { HistogramConfigSpec hJetRMaxPtEtaPhiNoFiducial({HistType::kTHnF, {rAxis, jetPtAxis, etaAxis, phiAxis}}); registry.add("jetRPtEtaPhi", "JetRPtEtaPhi", hJetRPtEtaPhi); - registry.add("jetRMaxPtEtaPhi", "JetRMaxPtEtaPhi", hJetRMaxPtEtaPhi); + if (!b_doLightOutput) + registry.add("jetRMaxPtEtaPhi", "JetRMaxPtEtaPhi", hJetRMaxPtEtaPhi); registry.add("jetRPtEtaPhiNoFiducial", "JetRPtEtaPhiNoFiducial", hJetRPtEtaPhiNoFiducial); - registry.add("jetRMaxPtEtaPhiNoFiducial", "JetRMaxPtEtaPhiNoFiducial", hJetRMaxPtEtaPhiNoFiducial); + if (!b_doLightOutput) + registry.add("jetRMaxPtEtaPhiNoFiducial", "JetRMaxPtEtaPhiNoFiducial", hJetRMaxPtEtaPhiNoFiducial); registry.add("hProcessedEvents", "Processed events", HistType::kTH1D, {{15, -0.5, 14.5, "Trigger type"}}); auto histProcessed = registry.get(HIST("hProcessedEvents")); @@ -170,156 +173,192 @@ struct JetTriggerQA { // Histograms for events where the EMCAL is live registry.add("hJetRPtEta", "Jets #it{p}_{T} and #eta", HistType::kTH3F, {rAxis, jetPtAxis, etaAxis}); registry.add("hJetRPtPhi", "Jets #it{p}_{T} and #phi", HistType::kTH3F, {rAxis, jetPtAxis, phiAxis}); - registry.add("hJetRMaxPtEta", "Leading jets #it{p}_{T} and #eta", HistType::kTH3F, {rAxis, jetPtAxis, etaAxis}); - registry.add("hJetRMaxPtPhi", "Leading jets #it{p}_{T} and #phi", HistType::kTH3F, {rAxis, jetPtAxis, phiAxis}); - registry.add("hJetRMaxPtEtaMinBias", "Leading jets #it{p}_{T} and #eta (min. bias)", HistType::kTH3F, {rAxis, jetPtAxis, etaAxis}); - registry.add("hJetRMaxPtPhiMinBias", "Leading jets #it{p}_{T} and #phi (min. bias)", HistType::kTH3F, {rAxis, jetPtAxis, phiAxis}); - registry.add("hJetRMaxPtEtaLevel0", "Leading jets #it{p}_{T} and #eta (level0)", HistType::kTH3F, {rAxis, jetPtAxis, etaAxis}); - registry.add("hJetRMaxPtPhiLevel0", "Leading jets #it{p}_{T} and #phi (level0)", HistType::kTH3F, {rAxis, jetPtAxis, phiAxis}); + if (!b_doLightOutput) { + registry.add("hJetRMaxPtEta", "Leading jets #it{p}_{T} and #eta", HistType::kTH3F, {rAxis, jetPtAxis, etaAxis}); + registry.add("hJetRMaxPtPhi", "Leading jets #it{p}_{T} and #phi", HistType::kTH3F, {rAxis, jetPtAxis, phiAxis}); + registry.add("hJetRMaxPtEtaMinBias", "Leading jets #it{p}_{T} and #eta (min. bias)", HistType::kTH3F, {rAxis, jetPtAxis, etaAxis}); + registry.add("hJetRMaxPtPhiMinBias", "Leading jets #it{p}_{T} and #phi (min. bias)", HistType::kTH3F, {rAxis, jetPtAxis, phiAxis}); + registry.add("hJetRMaxPtEtaLevel0", "Leading jets #it{p}_{T} and #eta (level0)", HistType::kTH3F, {rAxis, jetPtAxis, etaAxis}); + registry.add("hJetRMaxPtPhiLevel0", "Leading jets #it{p}_{T} and #phi (level0)", HistType::kTH3F, {rAxis, jetPtAxis, phiAxis}); + } registry.add("hClusterPtEtaPhi", Form("Cluster %s, #eta and #phi", observableName.data()), HistType::kTH3F, {observableAxisCluster, etaAxis, phiAxis}); registry.add("hClusterPtEtaPhiMinBias", Form("Cluster %s (Min. bias trigger), #eta and #phi", observableName.data()), HistType::kTH3F, {observableAxisCluster, etaAxis, phiAxis}); registry.add("hClusterPtEtaPhiLevel0", Form("Cluster %s (Level-0 trigger), #eta and #phi", observableName.data()), HistType::kTH3F, {observableAxisCluster, etaAxis, phiAxis}); - registry.add("hClusterEMCALMaxPtEtaPhi", Form("Leading cluster %s, #eta and #phi (EMCAL)", observableName.data()), HistType::kTH3F, {observableAxisCluster, etaAxis, phiAxis}); - registry.add("hClusterEMCALMaxPtEtaPhiMinBias", Form("Leading cluster %s, #eta and #phi (EMCAL, min. bias trigger)", observableName.data()), HistType::kTH3F, {observableAxisCluster, etaAxis, phiAxis}); - registry.add("hClusterEMCALMaxPtEtaPhiLevel0", Form("Leading cluster %s, #eta and #phi (EMCAL, Level-0 trigger)", observableName.data()), HistType::kTH3F, {observableAxisCluster, etaAxis, phiAxis}); - registry.add("hClusterDCALMaxPtEtaPhi", Form("Leading cluster %s, #eta and #phi (DCAL)", observableName.data()), HistType::kTH3F, {observableAxisCluster, etaAxis, phiAxis}); - registry.add("hClusterDCALMaxPtEtaPhiMinBias", Form("Leading cluster %s, #eta and #phi (DCAL, min, bias trigger)", observableName.data()), HistType::kTH3F, {observableAxisCluster, etaAxis, phiAxis}); - registry.add("hClusterDCALMaxPtEtaPhiLevel0", Form("Leading cluster %s, #eta and #phi (DCAL, Level-0 trigger)", observableName.data()), HistType::kTH3F, {observableAxisCluster, etaAxis, phiAxis}); - registry.add("hEventsNoMaxClusterEMCAL", "Events with no max. cluster in EMCAL", HistType::kTH1D, {{1, 0.5, 1.5}}); - registry.add("hEventsNoMaxClusterEMCALMinBias", "Events with no max. cluster in EMCAL (min. bias trigger)", HistType::kTH1D, {{1, 0.5, 1.5}}); - registry.add("hEventsNoMaxClusterEMCALLevel0", "Events with no max. cluster in EMCAL (level0 trigger)", HistType::kTH1D, {{1, 0.5, 1.5}}); - registry.add("hEventsNoMaxClusterDCAL", ("Events with no max. cluster in DCAL"), HistType::kTH1D, {{1, 0.5, 1.5}}); - registry.add("hEventsNoMaxClusterDCALMinBias", "Events with no max. cluster in DCAL (min. bias trigger)", HistType::kTH1D, {{1, 0.5, 1.5}}); - registry.add("hEventsNoMaxClusterDCALLevel0", "Events with no max. cluster in DCAL (level0 trigger)", HistType::kTH1D, {{1, 0.5, 1.5}}); - registry.add("hEventsNoMaxJet", "Events with no max. jet", HistType::kTH1D, {{rAxis}}); - registry.add("hEventsNoMaxJetMinBias", "Events with no max. jet (min. bias trigger)", HistType::kTH1D, {{rAxis}}); - registry.add("hEventsNoMaxJetLevel0", "Events with no max. jet (level0 trigger)", HistType::kTH1D, {{rAxis}}); - registry.add("hJetRPtTrackPt", "Jets", HistType::kTH3F, {rAxis, jetPtAxis, ptAxisTrackInJet}); - registry.add("hJetRPtClusterPt", "Jets", HistType::kTH3F, {rAxis, jetPtAxis, ptAxisClusterInJet}); - registry.add("hJetRPtPtd", "Jets", HistType::kTH3F, {rAxis, jetPtAxis, {nPtBins / 2, 0., 1., "p_{t,D}"}}); - registry.add("hJetRPtChargeFrag", "Jets", HistType::kTH3F, {rAxis, jetPtAxis, {nPtBins / 2, 0., 1., "z"}}); - registry.add("hJetRPtNEF", "Jets", HistType::kTH3F, {rAxis, jetPtAxis, {nPtBins / 2, 0., 1., "NEF"}}); - registry.add("hJetRPtZTheta", "Jets", HistType::kTH3F, {rAxis, jetPtAxis, {nPtBins / 2, 0., 1., "z#theta"}}); - registry.add("hJetRPtZSqTheta", "Jets", HistType::kTH3F, {rAxis, jetPtAxis, {nPtBins / 2, 0., 1., "z^{2} #theta"}}); - registry.add("hJetRPtZThetaSq", "Jets", HistType::kTH3F, {rAxis, jetPtAxis, {nPtBins / 2, 0., 1., "z #theta^{2}"}}); - registry.add("hJetRMaxPtClusterMaxPt", "Leading jets and clusters", HistType::kTH3F, {rAxis, jetPtAxis, observableAxisCluster}); + + if (!b_doLightOutput) { + registry.add("hClusterEMCALMaxPtEtaPhi", Form("Leading cluster %s, #eta and #phi (EMCAL)", observableName.data()), HistType::kTH3F, {observableAxisCluster, etaAxis, phiAxis}); + registry.add("hClusterEMCALMaxPtEtaPhiMinBias", Form("Leading cluster %s, #eta and #phi (EMCAL, min. bias trigger)", observableName.data()), HistType::kTH3F, {observableAxisCluster, etaAxis, phiAxis}); + registry.add("hClusterEMCALMaxPtEtaPhiLevel0", Form("Leading cluster %s, #eta and #phi (EMCAL, Level-0 trigger)", observableName.data()), HistType::kTH3F, {observableAxisCluster, etaAxis, phiAxis}); + registry.add("hClusterDCALMaxPtEtaPhi", Form("Leading cluster %s, #eta and #phi (DCAL)", observableName.data()), HistType::kTH3F, {observableAxisCluster, etaAxis, phiAxis}); + registry.add("hClusterDCALMaxPtEtaPhiMinBias", Form("Leading cluster %s, #eta and #phi (DCAL, min, bias trigger)", observableName.data()), HistType::kTH3F, {observableAxisCluster, etaAxis, phiAxis}); + registry.add("hClusterDCALMaxPtEtaPhiLevel0", Form("Leading cluster %s, #eta and #phi (DCAL, Level-0 trigger)", observableName.data()), HistType::kTH3F, {observableAxisCluster, etaAxis, phiAxis}); + registry.add("hEventsNoMaxClusterEMCAL", "Events with no max. cluster in EMCAL", HistType::kTH1D, {{1, 0.5, 1.5}}); + registry.add("hEventsNoMaxClusterEMCALMinBias", "Events with no max. cluster in EMCAL (min. bias trigger)", HistType::kTH1D, {{1, 0.5, 1.5}}); + registry.add("hEventsNoMaxClusterEMCALLevel0", "Events with no max. cluster in EMCAL (level0 trigger)", HistType::kTH1D, {{1, 0.5, 1.5}}); + registry.add("hEventsNoMaxClusterDCAL", ("Events with no max. cluster in DCAL"), HistType::kTH1D, {{1, 0.5, 1.5}}); + registry.add("hEventsNoMaxClusterDCALMinBias", "Events with no max. cluster in DCAL (min. bias trigger)", HistType::kTH1D, {{1, 0.5, 1.5}}); + registry.add("hEventsNoMaxClusterDCALLevel0", "Events with no max. cluster in DCAL (level0 trigger)", HistType::kTH1D, {{1, 0.5, 1.5}}); + registry.add("hEventsNoMaxJet", "Events with no max. jet", HistType::kTH1D, {{rAxis}}); + registry.add("hEventsNoMaxJetMinBias", "Events with no max. jet (min. bias trigger)", HistType::kTH1D, {{rAxis}}); + registry.add("hEventsNoMaxJetLevel0", "Events with no max. jet (level0 trigger)", HistType::kTH1D, {{rAxis}}); + + registry.add("hJetRPtTrackPt", "Jets", HistType::kTH3F, {rAxis, jetPtAxis, ptAxisTrackInJet}); + registry.add("hJetRPtClusterPt", "Jets", HistType::kTH3F, {rAxis, jetPtAxis, ptAxisClusterInJet}); + registry.add("hJetRPtPtd", "Jets", HistType::kTH3F, {rAxis, jetPtAxis, {nPtBins / 2, 0., 1., "p_{t,D}"}}); + registry.add("hJetRPtChargeFrag", "Jets", HistType::kTH3F, {rAxis, jetPtAxis, {nPtBins / 2, 0., 1., "z"}}); + registry.add("hJetRPtNEF", "Jets", HistType::kTH3F, {rAxis, jetPtAxis, {nPtBins / 2, 0., 1., "NEF"}}); + registry.add("hJetRPtZTheta", "Jets", HistType::kTH3F, {rAxis, jetPtAxis, {nPtBins / 2, 0., 1., "z#theta"}}); + registry.add("hJetRPtZSqTheta", "Jets", HistType::kTH3F, {rAxis, jetPtAxis, {nPtBins / 2, 0., 1., "z^{2} #theta"}}); + registry.add("hJetRPtZThetaSq", "Jets", HistType::kTH3F, {rAxis, jetPtAxis, {nPtBins / 2, 0., 1., "z #theta^{2}"}}); + + registry.add("hJetRMaxPtClusterMaxPt", "Leading jets and clusters", HistType::kTH3F, {rAxis, jetPtAxis, observableAxisCluster}); + } // Histograms for triggered events registry.add("hSelectedClusterPtEtaPhi", Form("Selected cluster %s, #eta and #phi", observableName.data()), HistType::kTH3F, {observableAxisCluster, etaAxis, phiAxis}); - registry.add("hSelectedClusterMaxPtEtaPhi", Form("Leading Selected cluster %s, #eta and #phi", observableName.data()), HistType::kTH3F, {observableAxisCluster, etaAxis, phiAxis}); + + if (!b_doLightOutput) { + registry.add("hSelectedClusterMaxPtEtaPhi", Form("Leading Selected cluster %s, #eta and #phi", observableName.data()), HistType::kTH3F, {observableAxisCluster, etaAxis, phiAxis}); + } // Jet high trigger - registry.add("hSelectedJetRMaxPtEta", "Leading selected jets #it{p}_{T} and #eta", HistType::kTH3F, {rAxis, jetPtAxis, etaAxis}); - registry.add("hSelectedJetRMaxPtPhi", "Leading selected jets #it{p}_{T} and #phi", HistType::kTH3F, {rAxis, jetPtAxis, phiAxis}); + if (!b_doLightOutput) { + registry.add("hSelectedJetRMaxPtEta", "Leading selected jets #it{p}_{T} and #eta", HistType::kTH3F, {rAxis, jetPtAxis, etaAxis}); + registry.add("hSelectedJetRMaxPtPhi", "Leading selected jets #it{p}_{T} and #phi", HistType::kTH3F, {rAxis, jetPtAxis, phiAxis}); + } registry.add("hSelectedJetRPtEta", "Selected jets #it{p}_{T} and #eta", HistType::kTH3F, {rAxis, jetPtAxis, etaAxis}); registry.add("hSelectedJetRPtPhi", "Selected jets #it{p}_{T} and #phi", HistType::kTH3F, {rAxis, jetPtAxis, phiAxis}); - registry.add("hSelectedJetRPtTrackPt", "Selected jets", HistType::kTH3F, {rAxis, jetPtAxis, ptAxisTrackInJet}); - registry.add("hSelectedJetRPtClusterPt", "Selected jets", HistType::kTH3F, {rAxis, jetPtAxis, ptAxisClusterInJet}); - registry.add("hSelectedJetRPtPtd", "Selected jets", HistType::kTH3F, {rAxis, jetPtAxis, {nPtBins / 2, 0., 1., "p_{t,D}"}}); - registry.add("hSelectedJetRPtChargeFrag", "Selected jets", HistType::kTH3F, {rAxis, jetPtAxis, {nPtBins / 2, 0., 1., "z"}}); - registry.add("hSelectedJetRPtNEF", "Selected jets", HistType::kTH3F, {rAxis, jetPtAxis, {nPtBins / 2, 0., 1., "NEF"}}); - registry.add("hSelectedJetRPtZTheta", "Selected jets", HistType::kTH3F, {rAxis, jetPtAxis, {nPtBins / 2, 0., 1., "z#theta"}}); - registry.add("hSelectedJetRPtZSqTheta", "Selected jets", HistType::kTH3F, {rAxis, jetPtAxis, {nPtBins / 2, 0., 1., "z^{2} #theta"}}); - registry.add("hSelectedJetRPtZThetaSq", "Selected jets", HistType::kTH3F, {rAxis, jetPtAxis, {nPtBins / 2, 0., 1., "z #theta^{2}"}}); + if (!b_doLightOutput) { + registry.add("hSelectedJetRPtTrackPt", "Selected jets", HistType::kTH3F, {rAxis, jetPtAxis, ptAxisTrackInJet}); + registry.add("hSelectedJetRPtClusterPt", "Selected jets", HistType::kTH3F, {rAxis, jetPtAxis, ptAxisClusterInJet}); + registry.add("hSelectedJetRPtPtd", "Selected jets", HistType::kTH3F, {rAxis, jetPtAxis, {nPtBins / 2, 0., 1., "p_{t,D}"}}); + registry.add("hSelectedJetRPtChargeFrag", "Selected jets", HistType::kTH3F, {rAxis, jetPtAxis, {nPtBins / 2, 0., 1., "z"}}); + registry.add("hSelectedJetRPtNEF", "Selected jets", HistType::kTH3F, {rAxis, jetPtAxis, {nPtBins / 2, 0., 1., "NEF"}}); + registry.add("hSelectedJetRPtZTheta", "Selected jets", HistType::kTH3F, {rAxis, jetPtAxis, {nPtBins / 2, 0., 1., "z#theta"}}); + registry.add("hSelectedJetRPtZSqTheta", "Selected jets", HistType::kTH3F, {rAxis, jetPtAxis, {nPtBins / 2, 0., 1., "z^{2} #theta"}}); + registry.add("hSelectedJetRPtZThetaSq", "Selected jets", HistType::kTH3F, {rAxis, jetPtAxis, {nPtBins / 2, 0., 1., "z #theta^{2}"}}); + } // Jet low trigger - registry.add("hSelectedJetLowRMaxPtEta", "Leading selected jets (low threshold) #it{p}_{T} and #eta", HistType::kTH3F, {rAxis, jetPtAxis, etaAxis}); - registry.add("hSelectedJetLowRMaxPtPhi", "Leading selected jets (low threshold) #it{p}_{T} and #phi", HistType::kTH3F, {rAxis, jetPtAxis, phiAxis}); + if (!b_doLightOutput) { + registry.add("hSelectedJetLowRMaxPtEta", "Leading selected jets (low threshold) #it{p}_{T} and #eta", HistType::kTH3F, {rAxis, jetPtAxis, etaAxis}); + registry.add("hSelectedJetLowRMaxPtPhi", "Leading selected jets (low threshold) #it{p}_{T} and #phi", HistType::kTH3F, {rAxis, jetPtAxis, phiAxis}); + } registry.add("hSelectedJetLowRPtEta", "Selected jets (low threshold) #it{p}_{T} and #eta", HistType::kTH3F, {rAxis, jetPtAxis, etaAxis}); registry.add("hSelectedJetLowRPtPhi", "Selected jets (low threshold) #it{p}_{T} and #phi", HistType::kTH3F, {rAxis, jetPtAxis, phiAxis}); - registry.add("hSelectedJetLowRPtTrackPt", "Selected jets (low threshold)", HistType::kTH3F, {rAxis, jetPtAxis, ptAxisTrackInJet}); - registry.add("hSelectedJetLowRPtClusterPt", "Selected jets (low threshold)", HistType::kTH3F, {rAxis, jetPtAxis, ptAxisClusterInJet}); - registry.add("hSelectedJetLowRPtPtd", "Selected jets (low threshold)", HistType::kTH3F, {rAxis, jetPtAxis, {nPtBins / 2, 0., 1., "p_{t,D}"}}); - registry.add("hSelectedJetLowRPtChargeFrag", "Selected jets (low threshold)", HistType::kTH3F, {rAxis, jetPtAxis, {nPtBins / 2, 0., 1., "z"}}); - registry.add("hSelectedJetLowRPtNEF", "Selected jets (low threshold)", HistType::kTH3F, {rAxis, jetPtAxis, {nPtBins / 2, 0., 1., "NEF"}}); - registry.add("hSelectedJetLowRPtZTheta", "Selected jets (low threshold)", HistType::kTH3F, {rAxis, jetPtAxis, {nPtBins / 2, 0., 1., "z#theta"}}); - registry.add("hSelectedJetLowRPtZSqTheta", "Selected jets (low threshold)", HistType::kTH3F, {rAxis, jetPtAxis, {nPtBins / 2, 0., 1., "z^{2} #theta"}}); - registry.add("hSelectedJetLowRPtZThetaSq", "Selected jets (low threshold)", HistType::kTH3F, {rAxis, jetPtAxis, {nPtBins / 2, 0., 1., "z #theta^{2}"}}); + + if (!b_doLightOutput) { + registry.add("hSelectedJetLowRPtTrackPt", "Selected jets (low threshold)", HistType::kTH3F, {rAxis, jetPtAxis, ptAxisTrackInJet}); + registry.add("hSelectedJetLowRPtClusterPt", "Selected jets (low threshold)", HistType::kTH3F, {rAxis, jetPtAxis, ptAxisClusterInJet}); + registry.add("hSelectedJetLowRPtPtd", "Selected jets (low threshold)", HistType::kTH3F, {rAxis, jetPtAxis, {nPtBins / 2, 0., 1., "p_{t,D}"}}); + registry.add("hSelectedJetLowRPtChargeFrag", "Selected jets (low threshold)", HistType::kTH3F, {rAxis, jetPtAxis, {nPtBins / 2, 0., 1., "z"}}); + registry.add("hSelectedJetLowRPtNEF", "Selected jets (low threshold)", HistType::kTH3F, {rAxis, jetPtAxis, {nPtBins / 2, 0., 1., "NEF"}}); + registry.add("hSelectedJetLowRPtZTheta", "Selected jets (low threshold)", HistType::kTH3F, {rAxis, jetPtAxis, {nPtBins / 2, 0., 1., "z#theta"}}); + registry.add("hSelectedJetLowRPtZSqTheta", "Selected jets (low threshold)", HistType::kTH3F, {rAxis, jetPtAxis, {nPtBins / 2, 0., 1., "z^{2} #theta"}}); + registry.add("hSelectedJetLowRPtZThetaSq", "Selected jets (low threshold)", HistType::kTH3F, {rAxis, jetPtAxis, {nPtBins / 2, 0., 1., "z #theta^{2}"}}); + } // EMCAL gamma very-high trigger registry.add("hSelectedGammaEMCALPtEtaPhiVeryHigh", Form("Selected Gamma %s, #eta and #phi (EMCAL, very high threshold)", observableName.data()), HistType::kTH3F, {observableAxisCluster, etaAxis, phiAxis}); - registry.add("hSelectedGammaEMCALMaxPtEtaPhiVeryHigh", Form("Leading selected gamma %s, #eta and #phi (EMCAL, very high treshold)", observableName.data()), HistType::kTH3F, {observableAxisCluster, etaAxis, phiAxis}); + if (!b_doLightOutput) + registry.add("hSelectedGammaEMCALMaxPtEtaPhiVeryHigh", Form("Leading selected gamma %s, #eta and #phi (EMCAL, very high treshold)", observableName.data()), HistType::kTH3F, {observableAxisCluster, etaAxis, phiAxis}); // DCAL gamma very-high trigger registry.add("hSelectedGammaDCALPtEtaPhiVeryHigh", Form("Selected gamma %s, #eta and #phi (DCAL, very high treshold)", observableName.data()), HistType::kTH3F, {observableAxisCluster, etaAxis, phiAxis}); - registry.add("hSelectedGammaDCALMaxPtEtaPhiVeryHigh", Form("Leading selected gamma %s, #eta and #phi (DCAL, very high treshold)", observableName.data()), HistType::kTH3F, {observableAxisCluster, etaAxis, phiAxis}); + if (!b_doLightOutput) + registry.add("hSelectedGammaDCALMaxPtEtaPhiVeryHigh", Form("Leading selected gamma %s, #eta and #phi (DCAL, very high treshold)", observableName.data()), HistType::kTH3F, {observableAxisCluster, etaAxis, phiAxis}); // EG1 trigger registry.add("hSelectedGammaEMCALPtEtaPhi", Form("Selected Gamma %s, #eta and #phi (EMCAL, high threshold)", observableName.data()), HistType::kTH3F, {observableAxisCluster, etaAxis, phiAxis}); - registry.add("hSelectedGammaEMCALMaxPtEtaPhi", Form("Leading selected gamma %s, #eta and #phi (EMCAL, high treshold)", observableName.data()), HistType::kTH3F, {observableAxisCluster, etaAxis, phiAxis}); + if (!b_doLightOutput) + registry.add("hSelectedGammaEMCALMaxPtEtaPhi", Form("Leading selected gamma %s, #eta and #phi (EMCAL, high treshold)", observableName.data()), HistType::kTH3F, {observableAxisCluster, etaAxis, phiAxis}); // DG1 trigger registry.add("hSelectedGammaDCALPtEtaPhi", Form("Selected gamma %s, #eta and #phi (DCAL, high treshold)", observableName.data()), HistType::kTH3F, {observableAxisCluster, etaAxis, phiAxis}); - registry.add("hSelectedGammaDCALMaxPtEtaPhi", Form("Leading selected gamma %s, #eta and #phi (DCAL, high treshold)", observableName.data()), HistType::kTH3F, {observableAxisCluster, etaAxis, phiAxis}); + if (!b_doLightOutput) + registry.add("hSelectedGammaDCALMaxPtEtaPhi", Form("Leading selected gamma %s, #eta and #phi (DCAL, high treshold)", observableName.data()), HistType::kTH3F, {observableAxisCluster, etaAxis, phiAxis}); // EG2 trigger registry.add("hSelectedGammaEMCALPtEtaPhiLow", Form("Selected gamma %s, #eta and #phi (EMCAL, low threshold)", observableName.data()), HistType::kTH3F, {observableAxisCluster, etaAxis, phiAxis}); - registry.add("hSelectedGammaEMCALMaxPtEtaPhiLow", Form("Leading selected gamma %s, #eta and #phi (EMCAL, low threshold)", observableName.data()), HistType::kTH3F, {observableAxisCluster, etaAxis, phiAxis}); + if (!b_doLightOutput) + registry.add("hSelectedGammaEMCALMaxPtEtaPhiLow", Form("Leading selected gamma %s, #eta and #phi (EMCAL, low threshold)", observableName.data()), HistType::kTH3F, {observableAxisCluster, etaAxis, phiAxis}); // DG2 trigger registry.add("hSelectedGammaDCALPtEtaPhiLow", Form("Selected gamma %s, #eta and #phi (DCAL, low threshold)", observableName.data()), HistType::kTH3F, {observableAxisCluster, etaAxis, phiAxis}); - registry.add("hSelectedGammaDCALMaxPtEtaPhiLow", Form("Leading selected gamma %s, #eta and #phi (DCAL, low threshold)", observableName.data()), HistType::kTH3F, {observableAxisCluster, etaAxis, phiAxis}); + if (!b_doLightOutput) + registry.add("hSelectedGammaDCALMaxPtEtaPhiLow", Form("Leading selected gamma %s, #eta and #phi (DCAL, low threshold)", observableName.data()), HistType::kTH3F, {observableAxisCluster, etaAxis, phiAxis}); // EMCAL gamma very-low trigger registry.add("hSelectedGammaEMCALPtEtaPhiVeryLow", Form("Selected gamma %s, #eta and #phi (EMCAL, very low threshold)", observableName.data()), HistType::kTH3F, {observableAxisCluster, etaAxis, phiAxis}); - registry.add("hSelectedGammaEMCALMaxPtEtaPhiVeryLow", Form("Leading selected gamma %s, #eta and #phi (EMCAL, very low threshold)", observableName.data()), HistType::kTH3F, {observableAxisCluster, etaAxis, phiAxis}); + if (!b_doLightOutput) + registry.add("hSelectedGammaEMCALMaxPtEtaPhiVeryLow", Form("Leading selected gamma %s, #eta and #phi (EMCAL, very low threshold)", observableName.data()), HistType::kTH3F, {observableAxisCluster, etaAxis, phiAxis}); // DCAL gamma very-low trigger registry.add("hSelectedGammaDCALPtEtaPhiVeryLow", Form("Selected gamma %s, #eta and #phi (DCAL, low threshold)", observableName.data()), HistType::kTH3F, {observableAxisCluster, etaAxis, phiAxis}); - registry.add("hSelectedGammaDCALMaxPtEtaPhiVeryLow", Form("Leading selected gamma %s, #eta and #phi (DCAL, low threshold)", observableName.data()), HistType::kTH3F, {observableAxisCluster, etaAxis, phiAxis}); - - registry.add("hSelectedJetRMaxPtClusterMaxPt", "Leading selected jets and clusters", HistType::kTH3F, {rAxis, jetPtAxis, observableAxisCluster}); - registry.add("hJetRMaxPtJetPt", "Leading jet #it{p}_{T} vs jet #it{p}_{T}", HistType::kTH3F, {rAxis, jetMaxPtAxis, jetPtAxis}); - registry.add("hJetRMaxPtJetPtNoFiducial", "Leading jet #it{p}_{T} vs jet #it{p}_{T} (no fiducial cut)", HistType::kTH3F, {rAxis, jetMaxPtAxis, jetPtAxis}); - registry.add("hClusterEMCALMaxPtClusterEMCALPt", Form("Leading clusterEMCAL %s vs clusterEMCAL %s", observableName.data(), observableName.data()), HistType::kTH2F, {observableAxisMaxCluster, observableAxisCluster}); - registry.add("hClusterDCALMaxPtClusterDCALPt", Form("Leading clusterDCAL %s vs clusterDCAL %s", observableName.data(), observableName.data()), HistType::kTH2F, {observableAxisMaxCluster, observableAxisCluster}); + if (!b_doLightOutput) + registry.add("hSelectedGammaDCALMaxPtEtaPhiVeryLow", Form("Leading selected gamma %s, #eta and #phi (DCAL, low threshold)", observableName.data()), HistType::kTH3F, {observableAxisCluster, etaAxis, phiAxis}); + + if (!b_doLightOutput) { + registry.add("hSelectedJetRMaxPtClusterMaxPt", "Leading selected jets and clusters", HistType::kTH3F, {rAxis, jetPtAxis, observableAxisCluster}); + registry.add("hJetRMaxPtJetPt", "Leading jet #it{p}_{T} vs jet #it{p}_{T}", HistType::kTH3F, {rAxis, jetMaxPtAxis, jetPtAxis}); + registry.add("hJetRMaxPtJetPtNoFiducial", "Leading jet #it{p}_{T} vs jet #it{p}_{T} (no fiducial cut)", HistType::kTH3F, {rAxis, jetMaxPtAxis, jetPtAxis}); + registry.add("hClusterEMCALMaxPtClusterEMCALPt", Form("Leading clusterEMCAL %s vs clusterEMCAL %s", observableName.data(), observableName.data()), HistType::kTH2F, {observableAxisMaxCluster, observableAxisCluster}); + registry.add("hClusterDCALMaxPtClusterDCALPt", Form("Leading clusterDCAL %s vs clusterDCAL %s", observableName.data(), observableName.data()), HistType::kTH2F, {observableAxisMaxCluster, observableAxisCluster}); + } if (b_JetsInEmcalOnly) { registry.get(HIST("hJetRPtEta"))->SetTitle("Jets (in emcal only) #it{p}_{T} and #eta"); registry.get(HIST("hJetRPtPhi"))->SetTitle("Jets (in emcal only) #it{p}_{T} and #phi"); - registry.get(HIST("hJetRPtTrackPt"))->SetTitle("Jets (in emcal only)"); - registry.get(HIST("hJetRPtClusterPt"))->SetTitle("Jets (in emcal only)"); - registry.get(HIST("hJetRPtPtd"))->SetTitle("Jets (in emcal only)"); - registry.get(HIST("hJetRPtChargeFrag"))->SetTitle("Jets (in emcal only)"); - registry.get(HIST("hJetRPtNEF"))->SetTitle("Jets (in emcal only)"); - registry.get(HIST("hJetRPtZTheta"))->SetTitle("Jets (in emcal only)"); - registry.get(HIST("hJetRPtZSqTheta"))->SetTitle("Jets (in emcal only)"); - registry.get(HIST("hJetRPtZThetaSq"))->SetTitle("Jets (in emcal only)"); - registry.get(HIST("hJetRMaxPtEta"))->SetTitle("Leading jets (in emcal only) #it{p}_{T} and #eta"); - registry.get(HIST("hJetRMaxPtPhi"))->SetTitle("Leading jets (in emcal only) #it{p}_{T} and #phi"); - registry.get(HIST("hJetRMaxPtEtaMinBias"))->SetTitle("Leading jets (in emcal only, min. bias) #it{p}_{T} and #eta"); - registry.get(HIST("hJetRMaxPtPhiMinBias"))->SetTitle("Leading jets (in emcal only, min. bias) #it{p}_{T} and #phi"); - registry.get(HIST("hJetRMaxPtEtaLevel0"))->SetTitle("Leading jets (in emcal only, level-0) #it{p}_{T} and #eta"); - registry.get(HIST("hJetRMaxPtPhiLevel0"))->SetTitle("Leading jets (in emcal only, level-0) #it{p}_{T} and #phi"); - registry.get(HIST("hJetRMaxPtClusterMaxPt"))->SetTitle("Leading jets (in emcal only) and clusters"); + if (!b_doLightOutput) { + registry.get(HIST("hJetRPtTrackPt"))->SetTitle("Jets (in emcal only)"); + registry.get(HIST("hJetRPtClusterPt"))->SetTitle("Jets (in emcal only)"); + registry.get(HIST("hJetRPtPtd"))->SetTitle("Jets (in emcal only)"); + registry.get(HIST("hJetRPtChargeFrag"))->SetTitle("Jets (in emcal only)"); + registry.get(HIST("hJetRPtNEF"))->SetTitle("Jets (in emcal only)"); + registry.get(HIST("hJetRPtZTheta"))->SetTitle("Jets (in emcal only)"); + registry.get(HIST("hJetRPtZSqTheta"))->SetTitle("Jets (in emcal only)"); + registry.get(HIST("hJetRPtZThetaSq"))->SetTitle("Jets (in emcal only)"); + + registry.get(HIST("hJetRMaxPtEta"))->SetTitle("Leading jets (in emcal only) #it{p}_{T} and #eta"); + registry.get(HIST("hJetRMaxPtPhi"))->SetTitle("Leading jets (in emcal only) #it{p}_{T} and #phi"); + registry.get(HIST("hJetRMaxPtEtaMinBias"))->SetTitle("Leading jets (in emcal only, min. bias) #it{p}_{T} and #eta"); + registry.get(HIST("hJetRMaxPtPhiMinBias"))->SetTitle("Leading jets (in emcal only, min. bias) #it{p}_{T} and #phi"); + registry.get(HIST("hJetRMaxPtEtaLevel0"))->SetTitle("Leading jets (in emcal only, level-0) #it{p}_{T} and #eta"); + registry.get(HIST("hJetRMaxPtPhiLevel0"))->SetTitle("Leading jets (in emcal only, level-0) #it{p}_{T} and #phi"); + registry.get(HIST("hJetRMaxPtClusterMaxPt"))->SetTitle("Leading jets (in emcal only) and clusters"); + } registry.get(HIST("hSelectedJetRPtEta"))->SetTitle("Selected jets (in emcal only) #it{p}_{T} and #eta"); registry.get(HIST("hSelectedJetRPtPhi"))->SetTitle("Selected jets (in emcal only) #it{p}_{T} and #phi"); - registry.get(HIST("hSelectedJetRPtTrackPt"))->SetTitle("Selected jets (in emcal only)"); - registry.get(HIST("hSelectedJetRPtClusterPt"))->SetTitle("Selected jets (in emcal only)"); - registry.get(HIST("hSelectedJetRPtPtd"))->SetTitle("Selected jets (in emcal only)"); - registry.get(HIST("hSelectedJetRPtChargeFrag"))->SetTitle("Selected jets (in emcal only)"); - registry.get(HIST("hSelectedJetRPtNEF"))->SetTitle("Selected jets (in emcal only)"); - registry.get(HIST("hSelectedJetRPtZTheta"))->SetTitle("Selected jets (in emcal only)"); - registry.get(HIST("hSelectedJetRPtZSqTheta"))->SetTitle("Selected jets (in emcal only)"); - registry.get(HIST("hSelectedJetRPtZThetaSq"))->SetTitle("Selected jets (in emcal only)"); + if (!b_doLightOutput) { + registry.get(HIST("hSelectedJetRPtTrackPt"))->SetTitle("Selected jets (in emcal only)"); + registry.get(HIST("hSelectedJetRPtClusterPt"))->SetTitle("Selected jets (in emcal only)"); + registry.get(HIST("hSelectedJetRPtPtd"))->SetTitle("Selected jets (in emcal only)"); + registry.get(HIST("hSelectedJetRPtChargeFrag"))->SetTitle("Selected jets (in emcal only)"); + registry.get(HIST("hSelectedJetRPtNEF"))->SetTitle("Selected jets (in emcal only)"); + registry.get(HIST("hSelectedJetRPtZTheta"))->SetTitle("Selected jets (in emcal only)"); + registry.get(HIST("hSelectedJetRPtZSqTheta"))->SetTitle("Selected jets (in emcal only)"); + registry.get(HIST("hSelectedJetRPtZThetaSq"))->SetTitle("Selected jets (in emcal only)"); + } registry.get(HIST("hSelectedJetLowRPtEta"))->SetTitle("Selected jets (low threshold, in emcal only) #it{p}_{T} and #eta"); registry.get(HIST("hSelectedJetLowRPtPhi"))->SetTitle("Selected jets (low threshold, in emcal only) #it{p}_{T} and #phi"); - registry.get(HIST("hSelectedJetLowRPtTrackPt"))->SetTitle("Selected jets (low threshold, in emcal only)"); - registry.get(HIST("hSelectedJetLowRPtClusterPt"))->SetTitle("Selected jets (low threshold, in emcal only)"); - registry.get(HIST("hSelectedJetLowRPtPtd"))->SetTitle("Selected jets (low threshold, in emcal only)"); - registry.get(HIST("hSelectedJetLowRPtChargeFrag"))->SetTitle("Selected jets (low threshold, in emcal only)"); - registry.get(HIST("hSelectedJetLowRPtNEF"))->SetTitle("Selected jets (low threshold, in emcal only)"); - registry.get(HIST("hSelectedJetLowRPtZTheta"))->SetTitle("Selected jets (low threshold, in emcal only)"); - registry.get(HIST("hSelectedJetLowRPtZSqTheta"))->SetTitle("Selected jets (low threshold, in emcal only)"); - registry.get(HIST("hSelectedJetLowRPtZThetaSq"))->SetTitle("Selected jets (low threshold, in emcal only)"); - - registry.get(HIST("hSelectedJetRMaxPtEta"))->SetTitle("Leading selected jets (in emcal only) #it{p}_{T} and #eta"); - registry.get(HIST("hSelectedJetRMaxPtPhi"))->SetTitle("Leading selected jets (in emcal only) #it{p}_{T} and #phi"); - registry.get(HIST("hSelectedJetRMaxPtClusterMaxPt"))->SetTitle("Leading selected jets (in emcal only) and clusters"); - - registry.get(HIST("hJetRMaxPtJetPt"))->SetTitle("Leading jet #it{p}_{T} vs jet #it{p}_{T} (in emcal only)"); + if (!b_doLightOutput) { + registry.get(HIST("hSelectedJetLowRPtTrackPt"))->SetTitle("Selected jets (low threshold, in emcal only)"); + registry.get(HIST("hSelectedJetLowRPtClusterPt"))->SetTitle("Selected jets (low threshold, in emcal only)"); + registry.get(HIST("hSelectedJetLowRPtPtd"))->SetTitle("Selected jets (low threshold, in emcal only)"); + registry.get(HIST("hSelectedJetLowRPtChargeFrag"))->SetTitle("Selected jets (low threshold, in emcal only)"); + registry.get(HIST("hSelectedJetLowRPtNEF"))->SetTitle("Selected jets (low threshold, in emcal only)"); + registry.get(HIST("hSelectedJetLowRPtZTheta"))->SetTitle("Selected jets (low threshold, in emcal only)"); + registry.get(HIST("hSelectedJetLowRPtZSqTheta"))->SetTitle("Selected jets (low threshold, in emcal only)"); + registry.get(HIST("hSelectedJetLowRPtZThetaSq"))->SetTitle("Selected jets (low threshold, in emcal only)"); + + registry.get(HIST("hSelectedJetRMaxPtEta"))->SetTitle("Leading selected jets (in emcal only) #it{p}_{T} and #eta"); + registry.get(HIST("hSelectedJetRMaxPtPhi"))->SetTitle("Leading selected jets (in emcal only) #it{p}_{T} and #phi"); + registry.get(HIST("hSelectedJetRMaxPtClusterMaxPt"))->SetTitle("Leading selected jets (in emcal only) and clusters"); + + registry.get(HIST("hJetRMaxPtJetPt"))->SetTitle("Leading jet #it{p}_{T} vs jet #it{p}_{T} (in emcal only)"); + } } } // init @@ -328,16 +367,16 @@ struct JetTriggerQA { double check_dphi(double dphi) const { - if (dphi > TMath::Pi()) { - dphi -= TMath::Pi(); - } else if (dphi <= -1 * TMath::Pi()) { - dphi += TMath::Pi(); + if (dphi > o2::constants::math::PI) { + dphi -= o2::constants::math::PI; + } else if (dphi <= -1 * o2::constants::math::PI) { + dphi += o2::constants::math::PI; } return dphi; } template - Bool_t isJetInEmcal(T const& jet) + bool isJetInEmcal(T const& jet) { double emcalEtaMin = -0.7, emcalEtaMax = 0.7, emcalPhiMin = 1.40, emcalPhiMax = 3.26; // Phi: 80 - 187 deg double R = jet.r() * 1e-2; // Jet R is saved as round(100*R) @@ -351,7 +390,7 @@ struct JetTriggerQA { { std::array selectAliases = {{triggerAliases::kTVXinEMC, triggerAliases::kEMC7, triggerAliases::kDMC7, triggerAliases::kEG1, triggerAliases::kEG2, triggerAliases::kDG1, triggerAliases::kDG2, triggerAliases::kEJ1, triggerAliases::kEJ2, triggerAliases::kDJ1, triggerAliases::kDJ2}}; bool found = false; - for (auto alias : selectAliases) { + for (const auto& alias : selectAliases) { if (collision.alias_bit(alias)) { found = true; break; @@ -360,7 +399,7 @@ struct JetTriggerQA { return found; } - Bool_t isClusterInEmcal(selectedClusters::iterator const& cluster) + bool isClusterInEmcal(selectedClusters::iterator const& cluster) { if (cluster.phi() < f_PhiEmcalOrDcal) { return true; @@ -466,78 +505,79 @@ struct JetTriggerQA { registry.fill(HIST("hSelectedGammaDCALPtEtaPhiVeryLow"), clusterObservable, cluster.eta(), cluster.phi()); } } // for clusters - - if (maxClusterObservableEMCAL > 0) { - registry.fill(HIST("hClusterEMCALMaxPtEtaPhi"), maxClusterObservableEMCAL, maxClusterEMCAL.eta(), maxClusterEMCAL.phi()); - if (hwtrg.test(EMCALHardwareTrigger::TRG_MB)) { - registry.fill(HIST("hClusterEMCALMaxPtEtaPhiMinBias"), maxClusterObservableEMCAL, maxClusterEMCAL.eta(), maxClusterEMCAL.phi()); - } - if (hwtrg.test(EMCALHardwareTrigger::TRG_EMC7)) { - registry.fill(HIST("hClusterEMCALMaxPtEtaPhiLevel0"), maxClusterObservableEMCAL, maxClusterEMCAL.eta(), maxClusterEMCAL.phi()); - } - for (const auto& cluster : analysedClusters) { - if (cluster.mEMCALcluster) { - registry.fill(HIST("hClusterEMCALMaxPtClusterEMCALPt"), maxClusterObservableEMCAL, cluster.mTriggerObservable); + if (!b_doLightOutput) { + if (maxClusterObservableEMCAL > 0) { + registry.fill(HIST("hClusterEMCALMaxPtEtaPhi"), maxClusterObservableEMCAL, maxClusterEMCAL.eta(), maxClusterEMCAL.phi()); + if (hwtrg.test(EMCALHardwareTrigger::TRG_MB)) { + registry.fill(HIST("hClusterEMCALMaxPtEtaPhiMinBias"), maxClusterObservableEMCAL, maxClusterEMCAL.eta(), maxClusterEMCAL.phi()); } - } - if (isTrigger(TriggerType_t::kEmcalJetFull) || isTrigger(TriggerType_t::kEmcalJetNeutral)) { - registry.fill(HIST("hSelectedClusterMaxPtEtaPhi"), maxClusterObservableEMCAL, maxClusterEMCAL.eta(), maxClusterEMCAL.phi()); - } - if (isTrigger(TriggerType_t::kEmcalGammaVeryHigh)) { - registry.fill(HIST("hSelectedGammaEMCALMaxPtEtaPhiVeryHigh"), maxClusterObservableEMCAL, maxClusterEMCAL.eta(), maxClusterEMCAL.phi()); - } - if (isTrigger(TriggerType_t::kEmcalGammaHigh)) { - registry.fill(HIST("hSelectedGammaEMCALMaxPtEtaPhi"), maxClusterObservableEMCAL, maxClusterEMCAL.eta(), maxClusterEMCAL.phi()); - } - if (isTrigger(TriggerType_t::kEmcalGammaLow)) { - registry.fill(HIST("hSelectedGammaEMCALMaxPtEtaPhiLow"), maxClusterObservableEMCAL, maxClusterEMCAL.eta(), maxClusterEMCAL.phi()); - } - if (isTrigger(TriggerType_t::kEmcalGammaVeryLow)) { - registry.fill(HIST("hSelectedGammaEMCALMaxPtEtaPhiVeryLow"), maxClusterObservableEMCAL, maxClusterEMCAL.eta(), maxClusterEMCAL.phi()); - } - } else { - // count events where max. cluster has not been found - registry.fill(HIST("hEventsNoMaxClusterEMCAL"), 1.); - if (hwtrg.test(EMCALHardwareTrigger::TRG_MB)) { - registry.fill(HIST("hEventsNoMaxClusterEMCALMinBias"), 1.); - } - if (hwtrg.test(EMCALHardwareTrigger::TRG_EMC7)) { - registry.fill(HIST("hEventsNoMaxClusterEMCALLevel0"), 1.); - } - } - if (maxClusterObservableDCAL > 0) { - registry.fill(HIST("hClusterDCALMaxPtEtaPhi"), maxClusterObservableDCAL, maxClusterDCAL.eta(), maxClusterDCAL.phi()); - if (hwtrg.test(EMCALHardwareTrigger::TRG_MB)) { - registry.fill(HIST("hClusterDCALMaxPtEtaPhiMinBias"), maxClusterObservableDCAL, maxClusterDCAL.eta(), maxClusterDCAL.phi()); - } - if (hwtrg.test(EMCALHardwareTrigger::TRG_DMC7)) { - registry.fill(HIST("hClusterDCALMaxPtEtaPhiLevel0"), maxClusterObservableDCAL, maxClusterDCAL.eta(), maxClusterDCAL.phi()); - } - for (const auto& cluster : analysedClusters) { - if (!cluster.mEMCALcluster) { - registry.fill(HIST("hClusterDCALMaxPtClusterDCALPt"), maxClusterObservableDCAL, cluster.mTriggerObservable); + if (hwtrg.test(EMCALHardwareTrigger::TRG_EMC7)) { + registry.fill(HIST("hClusterEMCALMaxPtEtaPhiLevel0"), maxClusterObservableEMCAL, maxClusterEMCAL.eta(), maxClusterEMCAL.phi()); + } + for (const auto& cluster : analysedClusters) { + if (cluster.mEMCALcluster) { + registry.fill(HIST("hClusterEMCALMaxPtClusterEMCALPt"), maxClusterObservableEMCAL, cluster.mTriggerObservable); + } + } + if (isTrigger(TriggerType_t::kEmcalJetFull) || isTrigger(TriggerType_t::kEmcalJetNeutral)) { + registry.fill(HIST("hSelectedClusterMaxPtEtaPhi"), maxClusterObservableEMCAL, maxClusterEMCAL.eta(), maxClusterEMCAL.phi()); + } + if (isTrigger(TriggerType_t::kEmcalGammaVeryHigh)) { + registry.fill(HIST("hSelectedGammaEMCALMaxPtEtaPhiVeryHigh"), maxClusterObservableEMCAL, maxClusterEMCAL.eta(), maxClusterEMCAL.phi()); + } + if (isTrigger(TriggerType_t::kEmcalGammaHigh)) { + registry.fill(HIST("hSelectedGammaEMCALMaxPtEtaPhi"), maxClusterObservableEMCAL, maxClusterEMCAL.eta(), maxClusterEMCAL.phi()); + } + if (isTrigger(TriggerType_t::kEmcalGammaLow)) { + registry.fill(HIST("hSelectedGammaEMCALMaxPtEtaPhiLow"), maxClusterObservableEMCAL, maxClusterEMCAL.eta(), maxClusterEMCAL.phi()); + } + if (isTrigger(TriggerType_t::kEmcalGammaVeryLow)) { + registry.fill(HIST("hSelectedGammaEMCALMaxPtEtaPhiVeryLow"), maxClusterObservableEMCAL, maxClusterEMCAL.eta(), maxClusterEMCAL.phi()); + } + } else { + // count events where max. cluster has not been found + registry.fill(HIST("hEventsNoMaxClusterEMCAL"), 1.); + if (hwtrg.test(EMCALHardwareTrigger::TRG_MB)) { + registry.fill(HIST("hEventsNoMaxClusterEMCALMinBias"), 1.); + } + if (hwtrg.test(EMCALHardwareTrigger::TRG_EMC7)) { + registry.fill(HIST("hEventsNoMaxClusterEMCALLevel0"), 1.); } } - if (isTrigger(TriggerType_t::kDcalGammaVeryHigh)) { - registry.fill(HIST("hSelectedGammaDCALMaxPtEtaPhiVeryHigh"), maxClusterObservableDCAL, maxClusterDCAL.eta(), maxClusterDCAL.phi()); - } - if (isTrigger(TriggerType_t::kDcalGammaHigh)) { - registry.fill(HIST("hSelectedGammaDCALMaxPtEtaPhi"), maxClusterObservableDCAL, maxClusterDCAL.eta(), maxClusterDCAL.phi()); - } - if (isTrigger(TriggerType_t::kDcalGammaLow)) { - registry.fill(HIST("hSelectedGammaDCALMaxPtEtaPhiLow"), maxClusterObservableDCAL, maxClusterDCAL.eta(), maxClusterDCAL.phi()); - } - if (isTrigger(TriggerType_t::kDcalGammaVeryLow)) { - registry.fill(HIST("hSelectedGammaDCALMaxPtEtaPhiVeryLow"), maxClusterObservableDCAL, maxClusterDCAL.eta(), maxClusterDCAL.phi()); - } - } else { - registry.fill(HIST("hEventsNoMaxClusterDCAL"), 1.); - // count events where max. cluster has not been found - if (hwtrg.test(EMCALHardwareTrigger::TRG_MB)) { - registry.fill(HIST("hEventsNoMaxClusterDCALMinBias"), 1.); - } - if (hwtrg.test(EMCALHardwareTrigger::TRG_DMC7)) { - registry.fill(HIST("hEventsNoMaxClusterDCALLevel0"), 1.); + if (maxClusterObservableDCAL > 0) { + registry.fill(HIST("hClusterDCALMaxPtEtaPhi"), maxClusterObservableDCAL, maxClusterDCAL.eta(), maxClusterDCAL.phi()); + if (hwtrg.test(EMCALHardwareTrigger::TRG_MB)) { + registry.fill(HIST("hClusterDCALMaxPtEtaPhiMinBias"), maxClusterObservableDCAL, maxClusterDCAL.eta(), maxClusterDCAL.phi()); + } + if (hwtrg.test(EMCALHardwareTrigger::TRG_DMC7)) { + registry.fill(HIST("hClusterDCALMaxPtEtaPhiLevel0"), maxClusterObservableDCAL, maxClusterDCAL.eta(), maxClusterDCAL.phi()); + } + for (const auto& cluster : analysedClusters) { + if (!cluster.mEMCALcluster) { + registry.fill(HIST("hClusterDCALMaxPtClusterDCALPt"), maxClusterObservableDCAL, cluster.mTriggerObservable); + } + } + if (isTrigger(TriggerType_t::kDcalGammaVeryHigh)) { + registry.fill(HIST("hSelectedGammaDCALMaxPtEtaPhiVeryHigh"), maxClusterObservableDCAL, maxClusterDCAL.eta(), maxClusterDCAL.phi()); + } + if (isTrigger(TriggerType_t::kDcalGammaHigh)) { + registry.fill(HIST("hSelectedGammaDCALMaxPtEtaPhi"), maxClusterObservableDCAL, maxClusterDCAL.eta(), maxClusterDCAL.phi()); + } + if (isTrigger(TriggerType_t::kDcalGammaLow)) { + registry.fill(HIST("hSelectedGammaDCALMaxPtEtaPhiLow"), maxClusterObservableDCAL, maxClusterDCAL.eta(), maxClusterDCAL.phi()); + } + if (isTrigger(TriggerType_t::kDcalGammaVeryLow)) { + registry.fill(HIST("hSelectedGammaDCALMaxPtEtaPhiVeryLow"), maxClusterObservableDCAL, maxClusterDCAL.eta(), maxClusterDCAL.phi()); + } + } else { + registry.fill(HIST("hEventsNoMaxClusterDCAL"), 1.); + // count events where max. cluster has not been found + if (hwtrg.test(EMCALHardwareTrigger::TRG_MB)) { + registry.fill(HIST("hEventsNoMaxClusterDCALMinBias"), 1.); + } + if (hwtrg.test(EMCALHardwareTrigger::TRG_DMC7)) { + registry.fill(HIST("hEventsNoMaxClusterDCALLevel0"), 1.); + } } } return std::make_pair(maxClusterObservableEMCAL, maxClusterObservableDCAL); @@ -568,80 +608,90 @@ struct JetTriggerQA { // This gives us access to all jet substructure information // auto tracksInJet = jetTrackConstituents.sliceBy(perJetTrackConstituents, jet.globalIndex()); // for (const auto& trackList : tracksInJet) { - for (auto& track : jet.template tracks_as()) { - auto trackPt = track.pt(); - auto chargeFrag = track.px() * jet.px() + track.py() * jet.py() + track.pz() * jet.pz(); - chargeFrag /= (jet.p() * jet.p()); - auto z = trackPt / jetPt; - auto dphi = jet.phi() - track.phi(); - dphi = check_dphi(dphi); - auto dR = TMath::Sqrt(dphi * dphi + TMath::Power(jet.eta() - track.eta(), 2)); - zTheta += z * dR / jetR; - zSqTheta += z * z * dR / jetR; - zThetaSq += z * dR * dR / (jetR * jetR); - ptD += z * z; - registry.fill(HIST("hJetRPtTrackPt"), jetR, jetPt, trackPt); - registry.fill(HIST("hJetRPtChargeFrag"), jetR, jetPt, chargeFrag); - if (isTrigger(TriggerType_t::kEmcalJetFull) || isTrigger(TriggerType_t::kEmcalJetNeutral)) { - registry.fill(HIST("hSelectedJetRPtTrackPt"), jetR, jetPt, trackPt); - registry.fill(HIST("hSelectedJetRPtChargeFrag"), jetR, jetPt, chargeFrag); - } - if (isTrigger(TriggerType_t::kEmcalJetFullLow) || isTrigger(TriggerType_t::kEmcalJetNeutralLow)) { - registry.fill(HIST("hSelectedJetLowRPtTrackPt"), jetR, jetPt, trackPt); - registry.fill(HIST("hSelectedJetLowRPtChargeFrag"), jetR, jetPt, chargeFrag); - } - } // for tracks in jet + if (!b_doLightOutput) { + for (const auto& track : jet.template tracks_as()) { + auto trackPt = track.pt(); + auto chargeFrag = track.px() * jet.px() + track.py() * jet.py() + track.pz() * jet.pz(); + chargeFrag /= (jet.p() * jet.p()); + auto z = trackPt / jetPt; + auto dphi = jet.phi() - track.phi(); + dphi = check_dphi(dphi); + auto dR = std::sqrt(dphi * dphi + std::pow(jet.eta() - track.eta(), 2)); + zTheta += z * dR / jetR; + zSqTheta += z * z * dR / jetR; + zThetaSq += z * dR * dR / (jetR * jetR); + ptD += z * z; + registry.fill(HIST("hJetRPtTrackPt"), jetR, jetPt, trackPt); + registry.fill(HIST("hJetRPtChargeFrag"), jetR, jetPt, chargeFrag); + if (isTrigger(TriggerType_t::kEmcalJetFull) || isTrigger(TriggerType_t::kEmcalJetNeutral)) { + registry.fill(HIST("hSelectedJetRPtTrackPt"), jetR, jetPt, trackPt); + registry.fill(HIST("hSelectedJetRPtChargeFrag"), jetR, jetPt, chargeFrag); + } + if (isTrigger(TriggerType_t::kEmcalJetFullLow) || isTrigger(TriggerType_t::kEmcalJetNeutralLow)) { + registry.fill(HIST("hSelectedJetLowRPtTrackPt"), jetR, jetPt, trackPt); + registry.fill(HIST("hSelectedJetLowRPtChargeFrag"), jetR, jetPt, chargeFrag); + } + } // for tracks in jet + } // auto clustersInJet = jetClusterConstituents.sliceBy(perJetClusterConstituents, jet.globalIndex()); // for (const auto& clusterList : clustersInJet) { - for (auto& cluster : jet.template clusters_as()) { - auto clusterPt = cluster.energy() / std::cosh(cluster.eta()); - neutralEnergyFraction += cluster.energy(); - auto z = clusterPt / jetPt; - auto dphi = jet.phi() - cluster.phi(); - dphi = check_dphi(dphi); - auto dR = TMath::Sqrt(dphi * dphi + TMath::Power(jet.eta() - cluster.eta(), 2)); - zTheta += z * dR / jetR; - zSqTheta += z * z * dR / jetR; - zThetaSq += z * dR * dR / (jetR * jetR); - ptD += z * z; - registry.fill(HIST("hJetRPtClusterPt"), jetR, jetPt, clusterPt); - if (isTrigger(TriggerType_t::kEmcalJetFull) || isTrigger(TriggerType_t::kEmcalJetNeutral)) { - registry.fill(HIST("hSelectedJetRPtClusterPt"), jetR, jetPt, clusterPt); - } - if (isTrigger(TriggerType_t::kEmcalJetFullLow) || isTrigger(TriggerType_t::kEmcalJetNeutralLow)) { - registry.fill(HIST("hSelectedJetLowRPtClusterPt"), jetR, jetPt, clusterPt); - } - } // for clusters in jet + if (!b_doLightOutput) { + for (const auto& cluster : jet.template clusters_as()) { + auto clusterPt = cluster.energy() / std::cosh(cluster.eta()); + neutralEnergyFraction += cluster.energy(); + auto z = clusterPt / jetPt; + auto dphi = jet.phi() - cluster.phi(); + dphi = check_dphi(dphi); + auto dR = std::sqrt(dphi * dphi + std::pow(jet.eta() - cluster.eta(), 2)); + zTheta += z * dR / jetR; + zSqTheta += z * z * dR / jetR; + zThetaSq += z * dR * dR / (jetR * jetR); + ptD += z * z; + registry.fill(HIST("hJetRPtClusterPt"), jetR, jetPt, clusterPt); + if (isTrigger(TriggerType_t::kEmcalJetFull) || isTrigger(TriggerType_t::kEmcalJetNeutral)) { + registry.fill(HIST("hSelectedJetRPtClusterPt"), jetR, jetPt, clusterPt); + } + if (isTrigger(TriggerType_t::kEmcalJetFullLow) || isTrigger(TriggerType_t::kEmcalJetNeutralLow)) { + registry.fill(HIST("hSelectedJetLowRPtClusterPt"), jetR, jetPt, clusterPt); + } + } // for clusters in jet + } neutralEnergyFraction /= jet.energy(); - ptD = TMath::Sqrt(ptD); + ptD = std::sqrt(ptD); // Fillng histograms registry.fill(HIST("hJetRPtEta"), jetR, jetPt, jet.eta()); registry.fill(HIST("hJetRPtPhi"), jetR, jetPt, jet.phi()); - registry.fill(HIST("hJetRPtPtd"), jetR, jetPt, ptD); - registry.fill(HIST("hJetRPtNEF"), jetR, jetPt, neutralEnergyFraction); - registry.fill(HIST("hJetRPtZTheta"), jetR, jetPt, zTheta); - registry.fill(HIST("hJetRPtZSqTheta"), jetR, jetPt, zSqTheta); - registry.fill(HIST("hJetRPtZThetaSq"), jetR, jetPt, zThetaSq); + if (!b_doLightOutput) { + registry.fill(HIST("hJetRPtPtd"), jetR, jetPt, ptD); + registry.fill(HIST("hJetRPtNEF"), jetR, jetPt, neutralEnergyFraction); + registry.fill(HIST("hJetRPtZTheta"), jetR, jetPt, zTheta); + registry.fill(HIST("hJetRPtZSqTheta"), jetR, jetPt, zSqTheta); + registry.fill(HIST("hJetRPtZThetaSq"), jetR, jetPt, zThetaSq); + } registry.get(HIST("jetRPtEtaPhi"))->Fill(jetR, jetPt, jet.eta(), jet.phi()); if (isTrigger(TriggerType_t::kEmcalJetFull) || isTrigger(TriggerType_t::kEmcalJetNeutral)) { registry.fill(HIST("hSelectedJetRPtEta"), jetR, jetPt, jet.eta()); registry.fill(HIST("hSelectedJetRPtPhi"), jetR, jetPt, jet.phi()); - registry.fill(HIST("hSelectedJetRPtPtd"), jetR, jetPt, ptD); - registry.fill(HIST("hSelectedJetRPtNEF"), jetR, jetPt, neutralEnergyFraction); - registry.fill(HIST("hSelectedJetRPtZTheta"), jetR, jetPt, zTheta); - registry.fill(HIST("hSelectedJetRPtZSqTheta"), jetR, jetPt, zSqTheta); - registry.fill(HIST("hSelectedJetRPtZThetaSq"), jetR, jetPt, zThetaSq); + if (!b_doLightOutput) { + registry.fill(HIST("hSelectedJetRPtPtd"), jetR, jetPt, ptD); + registry.fill(HIST("hSelectedJetRPtNEF"), jetR, jetPt, neutralEnergyFraction); + registry.fill(HIST("hSelectedJetRPtZTheta"), jetR, jetPt, zTheta); + registry.fill(HIST("hSelectedJetRPtZSqTheta"), jetR, jetPt, zSqTheta); + registry.fill(HIST("hSelectedJetRPtZThetaSq"), jetR, jetPt, zThetaSq); + } } if (isTrigger(TriggerType_t::kEmcalJetFullLow) || isTrigger(TriggerType_t::kEmcalJetNeutralLow)) { registry.fill(HIST("hSelectedJetLowRPtEta"), jetR, jetPt, jet.eta()); registry.fill(HIST("hSelectedJetLowRPtPhi"), jetR, jetPt, jet.phi()); - registry.fill(HIST("hSelectedJetLowRPtPtd"), jetR, jetPt, ptD); - registry.fill(HIST("hSelectedJetLowRPtNEF"), jetR, jetPt, neutralEnergyFraction); - registry.fill(HIST("hSelectedJetLowRPtZTheta"), jetR, jetPt, zTheta); - registry.fill(HIST("hSelectedJetLowRPtZSqTheta"), jetR, jetPt, zSqTheta); - registry.fill(HIST("hSelectedJetLowRPtZThetaSq"), jetR, jetPt, zThetaSq); + if (!b_doLightOutput) { + registry.fill(HIST("hSelectedJetLowRPtPtd"), jetR, jetPt, ptD); + registry.fill(HIST("hSelectedJetLowRPtNEF"), jetR, jetPt, neutralEnergyFraction); + registry.fill(HIST("hSelectedJetLowRPtZTheta"), jetR, jetPt, zTheta); + registry.fill(HIST("hSelectedJetLowRPtZSqTheta"), jetR, jetPt, zSqTheta); + registry.fill(HIST("hSelectedJetLowRPtZThetaSq"), jetR, jetPt, zThetaSq); + } } } // for jets return std::make_pair(vecMaxJet, vecMaxJetNoFiducial); @@ -761,67 +811,74 @@ struct JetTriggerQA { std::array foundMaxJet; std::fill(foundMaxJet.begin(), foundMaxJet.end(), false); - for (auto maxJet : vecMaxJet) { - double jetR = maxJet.r() * 1e-2, jetPt = maxJet.pt(), jetEta = maxJet.eta(), jetPhi = maxJet.phi(); - foundMaxJet[static_cast(maxJet.r() * 1e-1) - 2] = true; - registry.fill(HIST("hJetRMaxPtEta"), jetR, jetPt, jetEta); - registry.fill(HIST("hJetRMaxPtPhi"), jetR, jetPt, jetPhi); - if (hardwaretriggers.test(EMCALHardwareTrigger::TRG_MB)) { - registry.fill(HIST("hJetRMaxPtEtaMinBias"), jetR, jetPt, jetEta); - registry.fill(HIST("hJetRMaxPtPhiMinBias"), jetR, jetPt, jetPhi); - } - if (hardwaretriggers.test(EMCALHardwareTrigger::TRG_EMC7)) { - registry.fill(HIST("hJetRMaxPtEtaLevel0"), jetR, jetPt, jetEta); - registry.fill(HIST("hJetRMaxPtPhiLevel0"), jetR, jetPt, jetPhi); - } - // hJetRMaxPtEtaPhi->Fill(jetR, jetPt, jetEta, jetPhi); - registry.get(HIST("jetRMaxPtEtaPhi"))->Fill(jetR, jetPt, jetEta, jetPhi); - if (isTrigger(TriggerType_t::kEmcalJetFull) || isTrigger(TriggerType_t::kEmcalJetNeutral)) { - registry.fill(HIST("hSelectedJetRMaxPtEta"), jetR, jetPt, jetEta); - registry.fill(HIST("hSelectedJetRMaxPtPhi"), jetR, jetPt, jetPhi); - } - if (isTrigger(TriggerType_t::kEmcalJetFullLow) || isTrigger(TriggerType_t::kEmcalJetNeutralLow)) { - registry.fill(HIST("hSelectedJetLowRMaxPtEta"), jetR, jetPt, jetEta); - registry.fill(HIST("hSelectedJetLowRMaxPtPhi"), jetR, jetPt, jetPhi); - } - if (maxClusterObservableEMCAL > 0) { - registry.fill(HIST("hJetRMaxPtClusterMaxPt"), jetR, jetPt, maxClusterObservableEMCAL); + if (!b_doLightOutput) { + for (const auto& maxJet : vecMaxJet) { + double jetR = maxJet.r() * 1e-2, jetPt = maxJet.pt(), jetEta = maxJet.eta(), jetPhi = maxJet.phi(); + foundMaxJet[static_cast(maxJet.r() * 1e-1) - 2] = true; + registry.fill(HIST("hJetRMaxPtEta"), jetR, jetPt, jetEta); + registry.fill(HIST("hJetRMaxPtPhi"), jetR, jetPt, jetPhi); + if (hardwaretriggers.test(EMCALHardwareTrigger::TRG_MB)) { + registry.fill(HIST("hJetRMaxPtEtaMinBias"), jetR, jetPt, jetEta); + registry.fill(HIST("hJetRMaxPtPhiMinBias"), jetR, jetPt, jetPhi); + } + if (hardwaretriggers.test(EMCALHardwareTrigger::TRG_EMC7)) { + registry.fill(HIST("hJetRMaxPtEtaLevel0"), jetR, jetPt, jetEta); + registry.fill(HIST("hJetRMaxPtPhiLevel0"), jetR, jetPt, jetPhi); + } + // hJetRMaxPtEtaPhi->Fill(jetR, jetPt, jetEta, jetPhi); + registry.get(HIST("jetRMaxPtEtaPhi"))->Fill(jetR, jetPt, jetEta, jetPhi); if (isTrigger(TriggerType_t::kEmcalJetFull) || isTrigger(TriggerType_t::kEmcalJetNeutral)) { - registry.fill(HIST("hSelectedJetRMaxPtClusterMaxPt"), jetR, jetPt, maxClusterObservableEMCAL); + registry.fill(HIST("hSelectedJetRMaxPtEta"), jetR, jetPt, jetEta); + registry.fill(HIST("hSelectedJetRMaxPtPhi"), jetR, jetPt, jetPhi); } - } // if maxClusterPt - if (maxJet.r() == std::round(f_jetR * 100)) { - for (const auto& jet : jets) { - if (isJetInEmcal(jet)) { - registry.fill(HIST("hJetRMaxPtJetPt"), jet.r() * 1e-2, jetPt, jet.pt()); + if (isTrigger(TriggerType_t::kEmcalJetFullLow) || isTrigger(TriggerType_t::kEmcalJetNeutralLow)) { + registry.fill(HIST("hSelectedJetLowRMaxPtEta"), jetR, jetPt, jetEta); + registry.fill(HIST("hSelectedJetLowRMaxPtPhi"), jetR, jetPt, jetPhi); + } + if (maxClusterObservableEMCAL > 0) { + registry.fill(HIST("hJetRMaxPtClusterMaxPt"), jetR, jetPt, maxClusterObservableEMCAL); + if (isTrigger(TriggerType_t::kEmcalJetFull) || isTrigger(TriggerType_t::kEmcalJetNeutral)) { + registry.fill(HIST("hSelectedJetRMaxPtClusterMaxPt"), jetR, jetPt, maxClusterObservableEMCAL); } - } // for jets - } // if maxJet.r() == std::round(f_jetR * 100) - } // for maxJet + } // if maxClusterPt + if (maxJet.r() == std::round(f_jetR * 100)) { + for (const auto& jet : jets) { + if (isJetInEmcal(jet)) { + registry.fill(HIST("hJetRMaxPtJetPt"), jet.r() * 1e-2, jetPt, jet.pt()); + } + } // for jets + } // if maxJet.r() == std::round(f_jetR * 100) + } // for maxJet + } // Fill counters for events without max jets - for (std::size_t ir = 0; ir < foundMaxJet.size(); ir++) { - if (!foundMaxJet[ir]) { - double rval = static_cast(ir) / 10.; - registry.fill(HIST("hEventsNoMaxJet"), rval); - if (hardwaretriggers.test(EMCALHardwareTrigger::TRG_MB)) { - registry.fill(HIST("hEventsNoMaxJetMinBias"), rval); - } - if (hardwaretriggers.test(EMCALHardwareTrigger::TRG_EMC7)) { - registry.fill(HIST("hEventsNoMaxJetLevel0"), rval); + if (!b_doLightOutput) { + for (std::size_t ir = 0; ir < foundMaxJet.size(); ir++) { + if (!foundMaxJet[ir]) { + double rval = static_cast(ir) / 10.; + registry.fill(HIST("hEventsNoMaxJet"), rval); + if (hardwaretriggers.test(EMCALHardwareTrigger::TRG_MB)) { + registry.fill(HIST("hEventsNoMaxJetMinBias"), rval); + } + if (hardwaretriggers.test(EMCALHardwareTrigger::TRG_EMC7)) { + registry.fill(HIST("hEventsNoMaxJetLevel0"), rval); + } } } } - for (auto maxJet : vecMaxJetNoFiducial) { - double jetR = maxJet.r() * 1e-2, jetPt = maxJet.pt(), jetEta = maxJet.eta(), jetPhi = maxJet.phi(); - // hJetRMaxPtEtaPhiNoFiducial->Fill(jetR, jetPt, jetEta, jetPhi); - registry.get(HIST("jetRMaxPtEtaPhiNoFiducial"))->Fill(jetR, jetPt, jetEta, jetPhi); - if (maxJet.r() == std::round(f_jetR * 100)) { - for (const auto& jet : jets) { - registry.fill(HIST("hJetRMaxPtJetPtNoFiducial"), jet.r() * 1e-2, jetPt, jet.pt()); - } // for jets - } // if maxJet.r() == std::round(f_jetR * 100) - } // for maxjet no fiducial + if (!b_doLightOutput) { + for (const auto& maxJet : vecMaxJetNoFiducial) { + double jetR = maxJet.r() * 1e-2, jetPt = maxJet.pt(), jetEta = maxJet.eta(), jetPhi = maxJet.phi(); + // hJetRMaxPtEtaPhiNoFiducial->Fill(jetR, jetPt, jetEta, jetPhi); + registry.get(HIST("jetRMaxPtEtaPhiNoFiducial"))->Fill(jetR, jetPt, jetEta, jetPhi); + if (maxJet.r() == std::round(f_jetR * 100)) { + for (const auto& jet : jets) { + if (!b_doLightOutput) + registry.fill(HIST("hJetRMaxPtJetPtNoFiducial"), jet.r() * 1e-2, jetPt, jet.pt()); + } // for jets + } // if maxJet.r() == std::round(f_jetR * 100) + } // for maxjet no fiducial + } } // process void processFullJets(collisionWithTrigger const& collision, diff --git a/PWGJE/Tasks/jetChargedV2.cxx b/PWGJE/Tasks/jetChargedV2.cxx index c88f40cb990..cb98a8bef7b 100644 --- a/PWGJE/Tasks/jetChargedV2.cxx +++ b/PWGJE/Tasks/jetChargedV2.cxx @@ -80,6 +80,7 @@ struct JetChargedV2 { Configurable> jetRadii{"jetRadii", std::vector{0.4}, "jet resolution parameters"}; Configurable vertexZCut{"vertexZCut", 10.0f, "Accepted z-vertex range"}; + Configurable trackDcaZmax{"trackDcaZmax", 99, "additional cut on dcaZ to PV for tracks; uniformTracks in particular don't cut on this at all"}; Configurable centralityMin{"centralityMin", -999.0, "minimum centrality"}; Configurable centralityMax{"centralityMax", 999.0, "maximum centrality"}; Configurable trackPtMin{"trackPtMin", 0.15, "minimum pT acceptance for tracks"}; @@ -96,6 +97,9 @@ struct JetChargedV2 { Configurable jetEtaMax{"jetEtaMax", 0.9, "maximum eta acceptance for jets"}; Configurable jetRadius{"jetRadius", 0.2, "jet resolution parameters"}; + Configurable localRhoFitPtMin{"localRhoFitPtMin", 0.2, "Minimum track pT used for local rho fluctuation fit"}; + Configurable localRhoFitPtMax{"localRhoFitPtMax", 5, "Maximum track pT used for local rho fluctuation fit"}; + Configurable randomConeR{"randomConeR", 0.4, "size of random Cone for estimating background fluctuations"}; Configurable trackOccupancyInTimeRangeMax{"trackOccupancyInTimeRangeMax", 999999, "maximum occupancy of tracks in neighbouring collisions in a given time range; only applied to reconstructed collisions (data and mcd jets), not mc collisions (mcp jets)"}; Configurable trackOccupancyInTimeRangeMin{"trackOccupancyInTimeRangeMin", -999999, "minimum occupancy of tracks in neighbouring collisions in a given time range; only applied to reconstructed collisions (data and mcd jets), not mc collisions (mcp jets)"}; @@ -173,12 +177,14 @@ struct JetChargedV2 { jetPtBins.push_back(jetPtTemp); jetPtBinsRhoAreaSub.push_back(jetPtTemp); while (jetPtTemp < jetPtMax) { - if (jetPtTemp < 100.0) { + double jetPtTempA = 100.0; + double jetPtTempB = 100.0; + if (jetPtTemp < jetPtTempA) { jetPtTemp += 1.0; jetPtBins.push_back(jetPtTemp); jetPtBinsRhoAreaSub.push_back(jetPtTemp); jetPtBinsRhoAreaSub.push_back(-jetPtTemp); - } else if (jetPtTemp < 200.0) { + } else if (jetPtTemp < jetPtTempB) { jetPtTemp += 5.0; jetPtBins.push_back(jetPtTemp); jetPtBinsRhoAreaSub.push_back(jetPtTemp); @@ -204,7 +210,18 @@ struct JetChargedV2 { eventSelectionBits = jetderiveddatautilities::initialiseEventSelectionBits(static_cast(eventSelections)); trackSelection = jetderiveddatautilities::initialiseTrackSelection(static_cast(trackSelections)); + //< Track efficiency plots >// registry.add("h_collisions", "event status;event status;entries", {HistType::kTH1F, {{4, 0.0, 4.0}}}); + registry.add("h2_centrality_collisions", "centrality vs collisions; centrality; collisions", {HistType::kTH2F, {{120, -10., 110.}, {4, 0.0, 4.0}}}); + registry.add("h2_centrality_track_pt", "centrality vs track pT; centrality; #it{p}_{T,track} (GeV/#it{c})", {HistType::kTH2F, {{1200, -10.0, 110.0}, {200, 0., 200.}}}); + registry.add("h2_centrality_track_eta", "centrality vs track #eta; centrality; #eta_{track}", {HistType::kTH2F, {{1200, -10.0, 110.0}, {100, -1.0, 1.0}}}); + registry.add("h2_centrality_track_phi", "centrality vs track #varphi; centrality; #varphi_{track}", {HistType::kTH2F, {{1200, -10.0, 110.0}, {160, -1.0, 7.}}}); + registry.add("h2_centrality_track_energy", "centrality vs track energy; centrality; Energy GeV", {HistType::kTH2F, {{120, -10., 110.}, {100, 0.0, 100.0}}}); + registry.add("h2_track_pt_track_sigmapt", "#sigma(#it{p}_{T})/#it{p}_{T}; #it{p}_{T,track} (GeV/#it{c})", {HistType::kTH2F, {{100, 0., 10.}, {100000, 0.0, 100.0}}}); + registry.add("h2_track_pt_high_track_sigmapt", "#sigma(#it{p}_{T})/#it{p}_{T}; #it{p}_{T,track} (GeV/#it{c})", {HistType::kTH2F, {{90, 10., 100.}, {100000, 0.0, 100.0}}}); + registry.add("h2_track_pt_track_sigma1overpt", "#sigma(1/#it{p}_{T}); #it{p}_{T,track} (GeV/#it{c})", {HistType::kTH2F, {{100, 0., 10.}, {1000, 0.0, 10.0}}}); + registry.add("h2_track_pt_high_track_sigma1overpt", "#sigma(1/#it{p}_{T}); #it{p}_{T,track} (GeV/#it{c})", {HistType::kTH2F, {{90, 10., 100.}, {1000, 0.0, 10.0}}}); + //< \sigma p_T at local rho test plot > registry.add("h_accept_Track", "all and accept track;Track;entries", {HistType::kTH1F, {{10, 0.0, 10.0}}}); registry.add("h_accept_Track_init", "all and accept track;Track;entries", {HistType::kTH1F, {{10, 0.0, 10.0}}}); @@ -251,10 +268,6 @@ struct JetChargedV2 { registry.add("h3_centrality_rhovsphi_phi", "centrality; #rho(#varphi); #Delta#varphi_{jet}", {HistType::kTH3F, {{120, -10.0, 110.0}, {200, 0.0, 200.0}, {40, 0., o2::constants::math::TwoPI}}}); //< \sigma p_T at local rho test plot | end > - registry.add("h2_centrality_track_pt", "centrality vs track pT; centrality; #it{p}_{T,track} (GeV/#it{c})", {HistType::kTH2F, {{1200, -10.0, 110.0}, {200, 0., 200.}}}); - registry.add("h2_centrality_track_eta", "centrality vs track #eta; centrality; #eta_{track}", {HistType::kTH2F, {{1200, -10.0, 110.0}, {100, -1.0, 1.0}}}); - registry.add("h2_centrality_track_phi", "centrality vs track #varphi; centrality; #varphi_{track}", {HistType::kTH2F, {{1200, -10.0, 110.0}, {160, -1.0, 7.}}}); - registry.add("h_jet_pt_rhoareasubtracted", "jet pT rhoareasubtracted;#it{p}_{T,jet} (GeV/#it{c}); entries", {HistType::kTH1F, {jetPtAxisRhoAreaSub}}); registry.add("h_jet_pt_rholocal", "jet pT rholocal;#it{p}_{T,jet} (GeV/#it{c});entries", {HistType::kTH1F, {jetPtAxisRhoAreaSub}}); @@ -270,8 +283,6 @@ struct JetChargedV2 { registry.add("h2_centrality_deltapT_RandomCornPhi_RCprocess_rhorandomconewithoutleadingjet", "#it{p}_{T,random cone} - #it{area, random cone} * #it{rho}; #Delta#varphi_{jet}", {HistType::kTH2F, {{400, -200.0, 200.0}, {100, 0., o2::constants::math::TwoPI}}}); registry.add("h3_centrality_deltapT_RandomCornPhi_localrhovsphiwithoutleadingjet", "centrality; #it{p}_{T,random cone} - #it{area, random cone} * #it{rho}(#varphi); #Delta#varphi_{jet}", {HistType::kTH3F, {{100, 0.0, 100.0}, {400, -200.0, 200.0}, {100, 0., o2::constants::math::TwoPI}}}); - registry.add("h3_centrality_deltapT_RandomCornPhi_localrhovsphiwithoutoneleadingjet", "centrality; #it{p}_{T,random cone} - #it{area, random cone} * #it{rho}(#varphi); #Delta#varphi_{jet}", {HistType::kTH3F, {{100, 0.0, 100.0}, {400, -200.0, 200.0}, {100, 0., o2::constants::math::TwoPI}}}); - registry.add("h3_centrality_deltapT_RandomCornPhi_localrhovsphiwithouttwoleadingjet", "centrality; #it{p}_{T,random cone} - #it{area, random cone} * #it{rho}(#varphi); #Delta#varphi_{jet}", {HistType::kTH3F, {{100, 0.0, 100.0}, {400, -200.0, 200.0}, {100, 0., o2::constants::math::TwoPI}}}); //< bkg sub plot | end >// //< median rho >// registry.add("h_jet_pt_in_plane_v2", "jet pT;#it{p}^{in-plane}_{T,jet} (GeV/#it{c});entries", {HistType::kTH1F, {jetPtAxisRhoAreaSub}}); @@ -331,14 +342,16 @@ struct JetChargedV2 { template bool isAcceptedJet(U const& jet) { - if (jetAreaFractionMin > -98.0) { + double jetAreaFractionMinCfgMin = -98.0; + double jetAreaFractionMinCfgMax = 9998.0; + if (jetAreaFractionMin > jetAreaFractionMinCfgMin) { if (jet.area() < jetAreaFractionMin * o2::constants::math::PI * (jet.r() / 100.0) * (jet.r() / 100.0)) { return false; } } bool checkConstituentPt = true; - bool checkConstituentMinPt = (leadingConstituentPtMin > -98.0); - bool checkConstituentMaxPt = (leadingConstituentPtMax < 9998.0); + bool checkConstituentMinPt = (leadingConstituentPtMin > jetAreaFractionMinCfgMin); + bool checkConstituentMaxPt = (leadingConstituentPtMax < jetAreaFractionMinCfgMax); if (!checkConstituentMinPt && !checkConstituentMaxPt) { checkConstituentPt = false; } @@ -374,6 +387,24 @@ struct JetChargedV2 { return false; } + template + void fillTrackHistograms(T const& collision, U const& tracks, float weight = 1.0) + { + for (auto const& track : tracks) { + if (!(jetderiveddatautilities::selectTrack(track, trackSelection) && jetderiveddatautilities::selectTrackDcaZ(track, trackDcaZmax))) { + continue; + } + registry.fill(HIST("h2_centrality_track_pt"), collision.centrality(), track.pt(), weight); + registry.fill(HIST("h2_centrality_track_eta"), collision.centrality(), track.eta(), weight); + registry.fill(HIST("h2_centrality_track_phi"), collision.centrality(), track.phi(), weight); + registry.fill(HIST("h2_centrality_track_energy"), collision.centrality(), track.energy(), weight); + registry.fill(HIST("h2_track_pt_track_sigma1overpt"), track.pt(), track.sigma1Pt(), weight); + registry.fill(HIST("h2_track_pt_track_sigmapt"), track.pt(), track.sigma1Pt() * track.pt(), weight); + registry.fill(HIST("h2_track_pt_high_track_sigma1overpt"), track.pt(), track.sigma1Pt(), weight); + registry.fill(HIST("h2_track_pt_high_track_sigmapt"), track.pt(), track.sigma1Pt() * track.pt(), weight); + } + } + void fillLeadingJetQA(double leadingJetPt, double leadingJetPhi, double leadingJetEta) { registry.fill(HIST("leadJetPt"), leadingJetPt); @@ -403,7 +434,12 @@ struct JetChargedV2 { int detInd = detId * 4 + cfgnTotalSystem * 4 * (nmode - 2); int refAInd = refAId * 4 + cfgnTotalSystem * 4 * (nmode - 2); int refBInd = refBId * 4 + cfgnTotalSystem * 4 * (nmode - 2); - if (nmode == 2) { + int cfgNmodA = 2; + int cfgNmodB = 3; + int evtPlnAngleA = 7; + int evtPlnAngleB = 3; + int evtPlnAngleC = 5; + if (nmode == cfgNmodA) { if (collision.qvecAmp()[detId] > 1e-8 || collision.qvecAmp()[refAId] < 1e-8 || collision.qvecAmp()[refBId] < 1e-8) { histosQA.fill(HIST("histQvecUncorV2"), collision.qvecRe()[detInd], collision.qvecIm()[detInd], collision.cent()); histosQA.fill(HIST("histQvecRectrV2"), collision.qvecRe()[detInd + 1], collision.qvecIm()[detInd + 1], collision.cent()); @@ -419,7 +455,7 @@ struct JetChargedV2 { histosQA.fill(HIST("histEvtPlRes_SigRefBV2"), helperEP.GetResolution(helperEP.GetEventPlane(collision.qvecRe()[detInd + 3], collision.qvecIm()[detInd + 3], nmode), helperEP.GetEventPlane(collision.qvecRe()[refBInd + 3], collision.qvecIm()[refBInd + 3], nmode), nmode), collision.cent()); histosQA.fill(HIST("histEvtPlRes_RefARefBV2"), helperEP.GetResolution(helperEP.GetEventPlane(collision.qvecRe()[refAInd + 3], collision.qvecIm()[refAInd + 3], nmode), helperEP.GetEventPlane(collision.qvecRe()[refBInd + 3], collision.qvecIm()[refBInd + 3], nmode), nmode), collision.cent()); } - } else if (nmode == 3) { + } else if (nmode == cfgNmodB) { histosQA.fill(HIST("histQvecUncorV3"), collision.qvecRe()[detInd], collision.qvecIm()[detInd], collision.cent()); histosQA.fill(HIST("histQvecRectrV3"), collision.qvecRe()[detInd + 1], collision.qvecIm()[detInd + 1], collision.cent()); histosQA.fill(HIST("histQvecTwistV3"), collision.qvecRe()[detInd + 2], collision.qvecIm()[detInd + 2], collision.cent()); @@ -435,7 +471,7 @@ struct JetChargedV2 { histosQA.fill(HIST("histEvtPlRes_RefARefBV3"), helperEP.GetResolution(helperEP.GetEventPlane(collision.qvecRe()[refAInd + 3], collision.qvecIm()[refAInd + 3], nmode), helperEP.GetEventPlane(collision.qvecRe()[refBInd + 3], collision.qvecIm()[refBInd + 3], nmode), nmode), collision.cent()); } - if (nmode == 2) { + if (nmode == cfgNmodA) { double phiMinusPsi2; if (collision.qvecAmp()[detId] < 1e-8) { continue; @@ -455,8 +491,7 @@ struct JetChargedV2 { registry.fill(HIST("h2_centrality_jet_pt_rhoareasubtracted"), collision.centrality(), jet.pt() - (collision.rho() * jet.area()), 1.0); phiMinusPsi2 = jet.phi() - ep2; - - if ((phiMinusPsi2 < o2::constants::math::PIQuarter) || (phiMinusPsi2 >= 7 * o2::constants::math::PIQuarter) || (phiMinusPsi2 >= 3 * o2::constants::math::PIQuarter && phiMinusPsi2 < 5 * o2::constants::math::PIQuarter)) { + if ((phiMinusPsi2 < o2::constants::math::PIQuarter) || (phiMinusPsi2 >= evtPlnAngleA * o2::constants::math::PIQuarter) || (phiMinusPsi2 >= evtPlnAngleB * o2::constants::math::PIQuarter && phiMinusPsi2 < evtPlnAngleC * o2::constants::math::PIQuarter)) { registry.fill(HIST("h_jet_pt_in_plane_v2"), jet.pt() - (collision.rho() * jet.area()), 1.0); registry.fill(HIST("h2_centrality_jet_pt_in_plane_v2"), collision.centrality(), jet.pt() - (collision.rho() * jet.area()), 1.0); } else { @@ -464,7 +499,7 @@ struct JetChargedV2 { registry.fill(HIST("h2_centrality_jet_pt_out_of_plane_v2"), collision.centrality(), jet.pt() - (collision.rho() * jet.area()), 1.0); } } - } else if (nmode == 3) { + } else if (nmode == cfgNmodB) { double phiMinusPsi3; float ep3 = helperEP.GetEventPlane(collision.qvecRe()[detInd], collision.qvecIm()[detInd], nmode); for (auto const& jet : jets) { @@ -479,7 +514,7 @@ struct JetChargedV2 { } phiMinusPsi3 = jet.phi() - ep3; - if ((phiMinusPsi3 < o2::constants::math::PIQuarter) || (phiMinusPsi3 >= 7 * o2::constants::math::PIQuarter) || (phiMinusPsi3 >= 3 * o2::constants::math::PIQuarter && phiMinusPsi3 < 5 * o2::constants::math::PIQuarter)) { + if ((phiMinusPsi3 < o2::constants::math::PIQuarter) || (phiMinusPsi3 >= evtPlnAngleA * o2::constants::math::PIQuarter) || (phiMinusPsi3 >= evtPlnAngleB * o2::constants::math::PIQuarter && phiMinusPsi3 < evtPlnAngleC * o2::constants::math::PIQuarter)) { registry.fill(HIST("h_jet_pt_in_plane_v3"), jet.pt() - (collision.rho() * jet.area()), 1.0); registry.fill(HIST("h2_centrality_jet_pt_in_plane_v3"), collision.centrality(), jet.pt() - (collision.rho() * jet.area()), 1.0); } else { @@ -520,7 +555,7 @@ struct JetChargedV2 { int nTrk = 0; if (jets.size() > 0) { for (auto const& track : tracks) { - if (jetderiveddatautilities::selectTrack(track, trackSelection) && (std::fabs(track.eta() - leadingJetEta) > jetRadius) && track.pt() >= 0.2 && track.pt() <= 5.) { + if (jetderiveddatautilities::selectTrack(track, trackSelection) && (std::fabs(track.eta() - leadingJetEta) > jetRadius) && track.pt() >= localRhoFitPtMin && track.pt() <= localRhoFitPtMax) { registry.fill(HIST("h_accept_Track"), 2.5); nTrk += 1; } @@ -537,7 +572,7 @@ struct JetChargedV2 { if (jets.size() > 0) { for (auto const& trackfit : tracks) { registry.fill(HIST("h_accept_Track"), 0.5); - if (jetderiveddatautilities::selectTrack(trackfit, trackSelection) && (std::fabs(trackfit.eta() - leadingJetEta) > jetRadius) && trackfit.pt() >= 0.2 && trackfit.pt() <= 5.) { + if (jetderiveddatautilities::selectTrack(trackfit, trackSelection) && (std::fabs(trackfit.eta() - leadingJetEta) > jetRadius) && trackfit.pt() >= localRhoFitPtMin && trackfit.pt() <= localRhoFitPtMax) { registry.fill(HIST("h_accept_Track_Fit"), 0.5); fitTrack += 1; } @@ -545,7 +580,7 @@ struct JetChargedV2 { for (auto const& track : tracks) { registry.fill(HIST("h_accept_Track"), 1.5); - if (jetderiveddatautilities::selectTrack(track, trackSelection) && (std::fabs(track.eta() - leadingJetEta) > jetRadius) && track.pt() >= 0.2 && track.pt() <= 5.) { + if (jetderiveddatautilities::selectTrack(track, trackSelection) && (std::fabs(track.eta() - leadingJetEta) > jetRadius) && track.pt() >= localRhoFitPtMin && track.pt() <= localRhoFitPtMax) { accptTrack += 1; registry.fill(HIST("h_accept_Track"), 2.5); hPtsumSumptFit->Fill(track.phi(), track.pt()); @@ -563,14 +598,19 @@ struct JetChargedV2 { double ep2 = 0.; double ep3 = 0.; + int cfgNmodA = 2; + int cfgNmodB = 3; + int evtPlnAngleA = 7; + int evtPlnAngleB = 3; + int evtPlnAngleC = 5; for (uint i = 0; i < cfgnMods->size(); i++) { int nmode = cfgnMods->at(i); int detInd = detId * 4 + cfgnTotalSystem * 4 * (nmode - 2); - if (nmode == 2) { + if (nmode == cfgNmodA) { if (collision.qvecAmp()[detId] > 1e-8) { ep2 = helperEP.GetEventPlane(collision.qvecRe()[detInd + 3], collision.qvecIm()[detInd + 3], nmode); } - } else if (nmode == 3) { + } else if (nmode == cfgNmodB) { if (collision.qvecAmp()[detId] > 1e-8) { ep3 = helperEP.GetEventPlane(collision.qvecRe()[detInd + 3], collision.qvecIm()[detInd + 3], nmode); } @@ -609,7 +649,8 @@ struct JetChargedV2 { temppara[2] = fFitModulationV2v3->GetParameter(2); temppara[3] = fFitModulationV2v3->GetParameter(3); temppara[4] = fFitModulationV2v3->GetParameter(4); - for (int i = 1; i <= 5; i++) { + int paraNum = 5; + for (int i = 1; i <= paraNum; i++) { registry.fill(HIST("h2_evt_fitpara"), evtnum, i - 0.5, temppara[i - 1]); } @@ -652,9 +693,13 @@ struct JetChargedV2 { registry.fill(HIST("h2_PChi2_CombinFit"), cDF, chiSqr / (static_cast(nDF))); registry.fill(HIST("Thn_PChi2_CombinFitCent"), collision.centrality(), cDF, chiSqr / (static_cast(nDF))); double evtcent = collision.centrality(); - if (evtcent >= 0 && evtcent <= 5) { + int evtCentAreaMin = 0; + int evtCentAreaMax = 5; + int evtMidAreaMin = 30; + int evtMidAreaMax = 50; + if (evtcent >= evtCentAreaMin && evtcent <= evtCentAreaMax) { registry.fill(HIST("h2_PChi2_CombinFitA"), cDF, chiSqr / (static_cast(nDF))); - } else if (evtcent >= 30 && evtcent <= 50) { + } else if (evtcent >= evtMidAreaMin && evtcent <= evtMidAreaMax) { registry.fill(HIST("h2_PChi2_CombinFitB"), cDF, chiSqr / (static_cast(nDF))); } for (uint i = 0; i < cfgnMods->size(); i++) { @@ -680,7 +725,7 @@ struct JetChargedV2 { registry.fill(HIST("h2_phi_rholocal_cent"), collision.centrality(), rholocal, 1.0); registry.fill(HIST("h3_centrality_localrho_phi"), collision.centrality(), rholocal, jet.phi() - ep2); - if (nmode == 2) { + if (nmode == cfgNmodA) { registry.fill(HIST("h_jet_pt_rholocal"), jet.pt() - (rholocal * jet.area()), 1.0); double phiMinusPsi2; @@ -692,14 +737,14 @@ struct JetChargedV2 { registry.fill(HIST("h2_phi_rholocal"), jet.phi() - ep2, rholocal, 1.0); registry.fill(HIST("h_jet_pt_inclusive_v2_rho"), jet.pt() - (rholocal * jet.area()), 1.0); - if ((phiMinusPsi2 < o2::constants::math::PIQuarter) || (phiMinusPsi2 >= 7 * o2::constants::math::PIQuarter) || (phiMinusPsi2 >= 3 * o2::constants::math::PIQuarter && phiMinusPsi2 < 5 * o2::constants::math::PIQuarter)) { + if ((phiMinusPsi2 < o2::constants::math::PIQuarter) || (phiMinusPsi2 >= evtPlnAngleA * o2::constants::math::PIQuarter) || (phiMinusPsi2 >= evtPlnAngleB * o2::constants::math::PIQuarter && phiMinusPsi2 < evtPlnAngleC * o2::constants::math::PIQuarter)) { registry.fill(HIST("h_jet_pt_in_plane_v2_rho"), jet.pt() - (rholocal * jet.area()), 1.0); registry.fill(HIST("h2_centrality_jet_pt_in_plane_v2_rho"), collision.centrality(), jet.pt() - (rholocal * jet.area()), 1.0); } else { registry.fill(HIST("h_jet_pt_out_of_plane_v2_rho"), jet.pt() - (rholocal * jet.area()), 1.0); registry.fill(HIST("h2_centrality_jet_pt_out_of_plane_v2_rho"), collision.centrality(), jet.pt() - (rholocal * jet.area()), 1.0); } - } else if (nmode == 3) { + } else if (nmode == cfgNmodB) { double phiMinusPsi3; if (collision.qvecAmp()[detId] < 1e-8) { continue; @@ -707,7 +752,7 @@ struct JetChargedV2 { ep3 = helperEP.GetEventPlane(collision.qvecRe()[detInd], collision.qvecIm()[detInd], nmode); phiMinusPsi3 = jet.phi() - ep3; - if ((phiMinusPsi3 < o2::constants::math::PIQuarter) || (phiMinusPsi3 >= 7 * o2::constants::math::PIQuarter) || (phiMinusPsi3 >= 3 * o2::constants::math::PIQuarter && phiMinusPsi3 < 5 * o2::constants::math::PIQuarter)) { + if ((phiMinusPsi3 < o2::constants::math::PIQuarter) || (phiMinusPsi3 >= evtPlnAngleA * o2::constants::math::PIQuarter) || (phiMinusPsi3 >= evtPlnAngleB * o2::constants::math::PIQuarter && phiMinusPsi3 < evtPlnAngleC * o2::constants::math::PIQuarter)) { registry.fill(HIST("h_jet_pt_in_plane_v3_rho"), jet.pt() - (rholocal * jet.area()), 1.0); registry.fill(HIST("h2_centrality_jet_pt_in_plane_v3_rho"), collision.centrality(), jet.pt() - (rholocal * jet.area()), 1.0); } else { @@ -723,12 +768,11 @@ struct JetChargedV2 { float randomConeEta = randomNumber.Uniform(trackEtaMin + randomConeR, trackEtaMax - randomConeR); float randomConePhi = randomNumber.Uniform(0.0, o2::constants::math::TwoPI); float randomConePt = 0; - double integralValueRC = fFitModulationV2v3->Integral(randomConePhi - randomConeR, randomConePhi + randomConeR); double rholocalRC = collision.rho() / (2 * randomConeR * temppara[0]) * integralValueRC; int nmode = cfgnMods->at(i); - if (nmode == 2) { + if (nmode == cfgNmodA) { double rcPhiPsi2; rcPhiPsi2 = randomConePhi - ep2; @@ -745,17 +789,24 @@ struct JetChargedV2 { // removing the leading jet from the random cone if (jets.size() > 0) { // if there are no jets in the acceptance (from the jetfinder cuts) then there can be no leading jet - float dPhiLeadingJet = RecoDecay::constrainAngle(jets.iteratorAt(0).phi() - randomConePhi, static_cast(-o2::constants::math::PI)); - float dEtaLeadingJet = jets.iteratorAt(0).eta() - randomConeEta; + float leadingJetEta = jets.iteratorAt(0).eta(); + float leadingJetPhi = jets.iteratorAt(0).phi(); + float etaBandWidth = 2 * randomConeR; bool jetWasInCone = false; - while (std::sqrt(dEtaLeadingJet * dEtaLeadingJet + dPhiLeadingJet * dPhiLeadingJet) < jets.iteratorAt(0).r() / 100.0 + randomConeR) { - jetWasInCone = true; + do { randomConeEta = randomNumber.Uniform(trackEtaMin + randomConeR, trackEtaMax - randomConeR); randomConePhi = randomNumber.Uniform(0.0, o2::constants::math::TwoPI); - dPhiLeadingJet = RecoDecay::constrainAngle(jets.iteratorAt(0).phi() - randomConePhi, static_cast(-o2::constants::math::PI)); - dEtaLeadingJet = jets.iteratorAt(0).eta() - randomConeEta; - } + + float dEta = randomConeEta - leadingJetEta; + float dPhi = RecoDecay::constrainAngle(randomConePhi - leadingJetPhi, static_cast(-o2::constants::math::PI)); + + if (std::abs(dEta) > etaBandWidth && std::sqrt(dEta * dEta + dPhi * dPhi) > randomConeR + jets.iteratorAt(0).r() / 100.0) { + break; + } + jetWasInCone = true; + } while (true); + if (jetWasInCone) { randomConePt = 0.0; for (auto const& track : tracks) { @@ -771,27 +822,7 @@ struct JetChargedV2 { } registry.fill(HIST("h3_centrality_deltapT_RandomCornPhi_localrhovsphiwithoutleadingjet"), collision.centrality(), randomConePt - o2::constants::math::PI * randomConeR * randomConeR * rholocalRC, rcPhiPsi2, 1.0); registry.fill(HIST("h3_centrality_deltapT_RandomCornPhi_rhorandomconewithoutleadingjet"), collision.centrality(), randomConePt - o2::constants::math::PI * randomConeR * randomConeR * collision.rho(), rcPhiPsi2, 1.0); - - // randomised eta,phi for tracks, to assess part of fluctuations coming from statistically independently emitted particles, removing tracks from 2 leading jets - double randomConePtWithoutOneLeadJet = 0; - double randomConePtWithoutTwoLeadJet = 0; - for (auto const& track : tracks) { - if (jetderiveddatautilities::selectTrack(track, trackSelection)) { - float dPhi = RecoDecay::constrainAngle(randomNumber.Uniform(0.0, o2::constants::math::TwoPI) - randomConePhi, static_cast(-o2::constants::math::PI)); - float dEta = randomNumber.Uniform(trackEtaMin, trackEtaMax) - randomConeEta; - if (std::sqrt(dEta * dEta + dPhi * dPhi) < randomConeR) { - if (!trackIsInJet(track, jets.iteratorAt(0))) { - randomConePtWithoutOneLeadJet += track.pt(); - if (!trackIsInJet(track, jets.iteratorAt(1))) { - randomConePtWithoutTwoLeadJet += track.pt(); - } - } - } - } - } - registry.fill(HIST("h3_centrality_deltapT_RandomCornPhi_localrhovsphiwithoutoneleadingjet"), collision.centrality(), randomConePtWithoutOneLeadJet - o2::constants::math::PI * randomConeR * randomConeR * rholocalRC, rcPhiPsi2, 1.0); - registry.fill(HIST("h3_centrality_deltapT_RandomCornPhi_localrhovsphiwithouttwoleadingjet"), collision.centrality(), randomConePtWithoutTwoLeadJet - o2::constants::math::PI * randomConeR * randomConeR * rholocalRC, rcPhiPsi2, 1.0); - } else if (nmode == 3) { + } else if (nmode == cfgNmodB) { continue; } } @@ -819,8 +850,9 @@ struct JetChargedV2 { int nmode = cfgnMods->at(i); int detInd = detId * 4 + cfgnTotalSystem * 4 * (nmode - 2); - - if (nmode == 2) { + int cfgNmodA = 2; + int cfgNmodB = 3; + if (nmode == cfgNmodA) { double rcPhiPsi2; float evtPl2 = helperEP.GetEventPlane(collision.qvecRe()[detInd], collision.qvecIm()[detInd], nmode); rcPhiPsi2 = randomConePhi - evtPl2; @@ -861,7 +893,7 @@ struct JetChargedV2 { } } registry.fill(HIST("h2_centrality_deltapT_RandomCornPhi_RCprocess_rhorandomconewithoutleadingjet"), randomConePt - o2::constants::math::PI * randomConeR * randomConeR * collision.rho(), rcPhiPsi2, 1.0); - } else if (nmode == 3) { + } else if (nmode == cfgNmodB) { continue; } } @@ -869,24 +901,23 @@ struct JetChargedV2 { PROCESS_SWITCH(JetChargedV2, processRandomConeDataV2, "QA for random cone estimation of background fluctuations in data", true); void processTracksQA(soa::Filtered>::iterator const& collision, - soa::Filtered const& tracks) + soa::Filtered> const& tracks) { - if (collision.trackOccupancyInTimeRange() < trackOccupancyInTimeRangeMin || trackOccupancyInTimeRangeMax < collision.trackOccupancyInTimeRange()) { - return; - } + registry.fill(HIST("h_collisions"), 0.5); + registry.fill(HIST("h2_centrality_collisions"), collision.centrality(), 0.5); if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits)) { return; } - for (auto const& track : tracks) { - if (!jetderiveddatautilities::selectTrack(track, trackSelection)) { - continue; - } - registry.fill(HIST("h2_centrality_track_pt"), collision.centrality(), track.pt()); - registry.fill(HIST("h2_centrality_track_eta"), collision.centrality(), track.eta()); - registry.fill(HIST("h2_centrality_track_phi"), collision.centrality(), track.phi()); + registry.fill(HIST("h_collisions"), 1.5); + registry.fill(HIST("h2_centrality_collisions"), collision.centrality(), 1.5); + if (collision.trackOccupancyInTimeRange() < trackOccupancyInTimeRangeMin || trackOccupancyInTimeRangeMax < collision.trackOccupancyInTimeRange()) { + return; } + registry.fill(HIST("h_collisions"), 2.5); + registry.fill(HIST("h2_centrality_collisions"), collision.centrality(), 2.5); + fillTrackHistograms(collision, tracks); } - PROCESS_SWITCH(JetChargedV2, processTracksQA, "QA for charged tracks", true); + PROCESS_SWITCH(JetChargedV2, processTracksQA, "QA for charged tracks", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGJE/Tasks/jetFinderQA.cxx b/PWGJE/Tasks/jetFinderQA.cxx index 106ad4b4e1e..c2fd285a7a2 100644 --- a/PWGJE/Tasks/jetFinderQA.cxx +++ b/PWGJE/Tasks/jetFinderQA.cxx @@ -77,6 +77,8 @@ struct JetFinderQATask { Configurable trackOccupancyInTimeRangeMax{"trackOccupancyInTimeRangeMax", 999999, "maximum occupancy of tracks in neighbouring collisions in a given time range; only applied to reconstructed collisions (data and mcd jets), not mc collisions (mcp jets)"}; Configurable trackOccupancyInTimeRangeMin{"trackOccupancyInTimeRangeMin", -999999, "minimum occupancy of tracks in neighbouring collisions in a given time range; only applied to reconstructed collisions (data and mcd jets), not mc collisions (mcp jets)"}; Configurable skipMBGapEvents{"skipMBGapEvents", false, "flag to choose to reject min. bias gap events; jet-level rejection applied at the jet finder level, here rejection is applied for collision and track process functions"}; + Configurable intRateNBins{"intRateNBins", 50, "number of bins for interaction rate axis"}; + Configurable intRateMax{"intRateMax", 50000.0, "maximum value of interaction rate axis"}; std::vector filledJetR_Both; std::vector filledJetR_Low; @@ -136,7 +138,10 @@ struct JetFinderQATask { AxisSpec jetEtaAxis = {nBinsEta, jetEtaMin, jetEtaMax, "#eta"}; AxisSpec trackEtaAxis = {nBinsEta, trackEtaMin, trackEtaMax, "#eta"}; + AxisSpec intRateAxis = {intRateNBins, 0., intRateMax, "int. rate (kHz)"}; + if (doprocessJetsData || doprocessJetsMCD || doprocessJetsMCDWeighted) { + registry.add("h_jet_pt", "jet pT;#it{p}_{T,jet} (GeV/#it{c});entries", {HistType::kTH1F, {jetPtAxis}}); registry.add("h_jet_eta", "jet #eta;#eta_{jet};entries", {HistType::kTH1F, {jetEtaAxis}}); registry.add("h_jet_phi", "jet #varphi;#varphi_{jet};entries", {HistType::kTH1F, {{160, -1.0, 7.}}}); @@ -159,6 +164,7 @@ struct JetFinderQATask { registry.add("h_jet_ptcut", "p_{T} cut;p_{T,jet} (GeV/#it{c});N;entries", {HistType::kTH2F, {{300, 0, 300}, {20, 0, 5}}}); registry.add("h_jet_phat_weighted", "jet #hat{p};#hat{p} (GeV/#it{c});entries", {HistType::kTH1F, {{1000, 0, 1000}}}); registry.add("h3_centrality_occupancy_jet_pt", "centrality; occupancy; #it{p}_{T,jet} (GeV/#it{c})", {HistType::kTH3F, {{120, -10.0, 110.0}, {60, 0, 30000}, jetPtAxis}}); + registry.add("h2_intrate_jet_pt", "int. rate vs #it{p}_{T,jet}; int. rate (kHz); #it{p}_{T,jet} (GeV/#it{c});", {HistType::kTH2F, {intRateAxis, jetPtAxis}}); } if (doprocessJetsRhoAreaSubData || doprocessJetsRhoAreaSubMCD) { @@ -182,6 +188,7 @@ struct JetFinderQATask { registry.add("h3_jet_r_jet_pt_track_phi_rhoareasubtracted", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#varphi_{jet tracks}", {HistType::kTH3F, {{jetRadiiBins, ""}, jetPtAxisRhoAreaSub, {160, -1.0, 7.}}}); registry.add("h3_jet_r_jet_pt_jet_pt_rhoareasubtracted", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#it{p}_{T,jet} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, jetPtAxis, jetPtAxisRhoAreaSub}}); registry.add("h3_centrality_occupancy_jet_pt_rhoareasubtracted", "centrality; occupancy; #it{p}_{T,jet} (GeV/#it{c})", {HistType::kTH3F, {{120, -10.0, 110.0}, {60, 0, 30000}, jetPtAxisRhoAreaSub}}); + registry.add("h2_intrate_jet_pt_rhoareasubtracted", "int. rate vs #it{p}_{T,jet}; int. rate (kHz); #it{p}_{T,jet} (GeV/#it{c});", {HistType::kTH2F, {intRateAxis, jetPtAxisRhoAreaSub}}); } if (doprocessEvtWiseConstSubJetsData || doprocessEvtWiseConstSubJetsMCD) { @@ -202,6 +209,7 @@ struct JetFinderQATask { registry.add("h3_jet_r_jet_pt_track_pt_eventwiseconstituentsubtracted", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#it{p}_{T,jet tracks} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, jetPtAxis, jetPtAxis}}); registry.add("h3_jet_r_jet_pt_track_eta_eventwiseconstituentsubtracted", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#eta_{jet tracks}", {HistType::kTH3F, {{jetRadiiBins, ""}, jetPtAxis, trackEtaAxis}}); registry.add("h3_jet_r_jet_pt_track_phi_eventwiseconstituentsubtracted", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#varphi_{jet tracks}", {HistType::kTH3F, {{jetRadiiBins, ""}, jetPtAxis, {160, -1.0, 7.}}}); + registry.add("h2_intrate_jet_pt_eventwiseconstituentsubtracted", "int. rate vs #it{p}_{T,jet}; int. rate (kHz); #it{p}_{T,jet} (GeV/#it{c});", {HistType::kTH2F, {intRateAxis, jetPtAxis}}); } if (doprocessRho) { @@ -434,6 +442,7 @@ struct JetFinderQATask { registry.fill(HIST("h2_centrality_jet_phi"), centrality, jet.phi(), weight); registry.fill(HIST("h2_centrality_jet_ntracks"), centrality, jet.tracksIds().size(), weight); registry.fill(HIST("h3_centrality_occupancy_jet_pt"), centrality, occupancy, jet.pt(), weight); + registry.fill(HIST("h2_intrate_jet_pt"), jet.collision().hadronicRate(), jet.pt(), weight); } registry.fill(HIST("h3_jet_r_jet_pt_centrality"), jet.r() / 100.0, jet.pt(), centrality, weight); @@ -466,6 +475,7 @@ struct JetFinderQATask { registry.fill(HIST("h2_centrality_jet_phi_rhoareasubtracted"), centrality, jet.phi(), weight); registry.fill(HIST("h2_centrality_jet_ntracks_rhoareasubtracted"), centrality, jet.tracksIds().size(), weight); } + registry.fill(HIST("h2_intrate_jet_pt_rhoareasubtracted"), jet.collision().hadronicRate(), jet.pt() - (rho * jet.area()), weight); } registry.fill(HIST("h3_jet_r_jet_pt_centrality_rhoareasubtracted"), jet.r() / 100.0, jet.pt() - (rho * jet.area()), centrality, weight); @@ -496,6 +506,7 @@ struct JetFinderQATask { registry.fill(HIST("h2_centrality_jet_eta_eventwiseconstituentsubtracted"), centrality, jet.eta(), weight); registry.fill(HIST("h2_centrality_jet_phi_eventwiseconstituentsubtracted"), centrality, jet.phi(), weight); registry.fill(HIST("h2_centrality_jet_ntracks_eventwiseconstituentsubtracted"), centrality, jet.tracksIds().size(), weight); + registry.fill(HIST("h2_intrate_jet_pt_eventwiseconstituentsubtracted"), jet.collision().hadronicRate(), jet.pt(), weight); } registry.fill(HIST("h3_jet_r_jet_pt_centrality_eventwiseconstituentsubtracted"), jet.r() / 100.0, jet.pt(), centrality, weight); @@ -1180,7 +1191,7 @@ struct JetFinderQATask { aod::JetMcCollisions const&, soa::Filtered> const& tracks) { - float eventWeight = collision.mcCollision().weight(); + float eventWeight = collision.weight(); if (skipMBGapEvents && collision.subGeneratorId() == jetderiveddatautilities::JCollisionSubGeneratorId::mbGap) { return; } diff --git a/PWGJE/Tasks/jetSpectraCharged.cxx b/PWGJE/Tasks/jetSpectraCharged.cxx index 67495485bb6..f1dfda25418 100644 --- a/PWGJE/Tasks/jetSpectraCharged.cxx +++ b/PWGJE/Tasks/jetSpectraCharged.cxx @@ -69,6 +69,7 @@ struct JetSpectraCharged { Configurable pTHatMaxMCD{"pTHatMaxMCD", 999.0, "maximum fraction of hard scattering for jet acceptance in detector MC"}; Configurable pTHatMaxMCP{"pTHatMaxMCP", 999.0, "maximum fraction of hard scattering for jet acceptance in particle MC"}; Configurable pTHatExponent{"pTHatExponent", 6.0, "exponent of the event weight for the calculation of pTHat"}; + Configurable pTHatAbsoluteMin{"pTHatAbsoluteMin", -99.0, "minimum value of pTHat"}; Configurable jetPtMax{"jetPtMax", 200., "set jet pT bin max"}; Configurable jetEtaMin{"jetEtaMin", -0.7, "minimum jet pseudorapidity"}; Configurable jetEtaMax{"jetEtaMax", 0.7, "maximum jet pseudorapidity"}; @@ -293,6 +294,10 @@ struct JetSpectraCharged { template void fillJetHistograms(TJets const& jet, float centrality, float weight = 1.0) { + float pTHat = 10. / (std::pow(weight, 1.0 / pTHatExponent)); + if (jet.pt() > pTHatMaxMCD * pTHat || pTHat < pTHatAbsoluteMin) { + return; + } if (jet.r() == round(selectedJetsRadius * 100.0f)) { registry.fill(HIST("h_jet_pt"), jet.pt(), weight); registry.fill(HIST("h_jet_eta"), jet.eta(), weight); @@ -313,6 +318,10 @@ struct JetSpectraCharged { template void fillJetAreaSubHistograms(TJets const& jet, float centrality, float rho, float weight = 1.0) { + float pTHat = 10. / (std::pow(weight, 1.0 / pTHatExponent)); + if (jet.pt() > pTHatMaxMCD * pTHat || pTHat < pTHatAbsoluteMin) { + return; + } double jetcorrpt = jet.pt() - (rho * jet.area()); if (jet.r() == round(selectedJetsRadius * 100.0f)) { // fill jet histograms after area-based subtraction @@ -338,6 +347,10 @@ struct JetSpectraCharged { template void fillMCPHistograms(TJets const& jet, float weight = 1.0) { + float pTHat = 10. / (std::pow(weight, 1.0 / pTHatExponent)); + if (jet.pt() > pTHatMaxMCP * pTHat || pTHat < pTHatAbsoluteMin) { + return; + } if (jet.r() == round(selectedJetsRadius * 100.0f)) { // fill mcp jet histograms registry.fill(HIST("h_jet_pt_part"), jet.pt(), weight); @@ -356,6 +369,10 @@ struct JetSpectraCharged { template void fillMCPAreaSubHistograms(TJets const& jet, float rho = 0.0, float weight = 1.0) { + float pTHat = 10. / (std::pow(weight, 1.0 / pTHatExponent)); + if (jet.pt() > pTHatMaxMCP * pTHat || pTHat < pTHatAbsoluteMin) { + return; + } if (jet.r() == round(selectedJetsRadius * 100.0f)) { // fill mcp jet histograms double jetcorrpt = jet.pt() - (rho * jet.area()); @@ -373,6 +390,10 @@ struct JetSpectraCharged { template void fillEventWiseConstituentSubtractedHistograms(TJets const& jet, float centrality, float weight = 1.0) { + float pTHat = 10. / (std::pow(weight, 1.0 / pTHatExponent)); + if (jet.pt() > pTHatMaxMCD * pTHat || pTHat < pTHatAbsoluteMin) { + return; + } if (jet.r() == round(selectedJetsRadius * 100.0f)) { registry.fill(HIST("h2_centrality_jet_pt_eventwiseconstituentsubtracted"), centrality, jet.pt(), weight); registry.fill(HIST("jet_observables_eventwiseconstituentsubtracted"), jet.pt(), jet.eta(), jet.phi(), weight); @@ -390,14 +411,14 @@ struct JetSpectraCharged { void fillMatchedHistograms(TBase const& jetMCD, float weight = 1.0) { float pTHat = 10. / (std::pow(weight, 1.0 / pTHatExponent)); - if (jetMCD.pt() > pTHatMaxMCD * pTHat) { + if (jetMCD.pt() > pTHatMaxMCD * pTHat || pTHat < pTHatAbsoluteMin) { return; } // fill geometry matched histograms if (checkGeoMatched) { if (jetMCD.has_matchedJetGeo()) { for (const auto& jetMCP : jetMCD.template matchedJetGeo_as>()) { - if (jetMCP.pt() > pTHatMaxMCP * pTHat) { + if (jetMCP.pt() > pTHatMaxMCP * pTHat || pTHat < pTHatAbsoluteMin) { continue; } if (jetMCD.r() == round(selectedJetsRadius * 100.0f)) { @@ -531,10 +552,7 @@ struct JetSpectraCharged { aod::JetMcCollisions const&, soa::Filtered> const& tracks) { - if (!collision.has_mcCollision()) { // the collision is fake and has no associated mc coll; skip as .mccollision() cannot be called - return; - } - float eventWeight = collision.mcCollision().weight(); + float eventWeight = collision.weight(); if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits, skipMBGapEvents)) { return; } @@ -569,11 +587,10 @@ struct JetSpectraCharged { void processCollisionsWeighted(soa::Join::iterator const& collision, aod::JetMcCollisions const&) { - if (!collision.has_mcCollision()) { // the collision is fake and has no associated mc coll; skip as .mccollision() cannot be called + if (!collision.has_mcCollision()) { registry.fill(HIST("h_fakecollisions"), 0.5); - return; } - float eventWeight = collision.mcCollision().weight(); + float eventWeight = collision.weight(); registry.fill(HIST("h_collisions"), 0.5); registry.fill(HIST("h_collisions_weighted"), 0.5, eventWeight); if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits, skipMBGapEvents)) { diff --git a/PWGJE/Tasks/jetTaggerHFQA.cxx b/PWGJE/Tasks/jetTaggerHFQA.cxx index 2f51f5e787f..7e2efeceaa3 100644 --- a/PWGJE/Tasks/jetTaggerHFQA.cxx +++ b/PWGJE/Tasks/jetTaggerHFQA.cxx @@ -149,12 +149,18 @@ struct JetTaggerHFQA { AxisSpec axisSigmaLxyz = {binSigmaLxyz, "#sigma_{L_{XYZ}} [cm]"}; if (doprocessTracksDca) { - registry.add("h_impact_parameter_xy", "", {HistType::kTH1F, {{axisImpactParameterXY}}}); - registry.add("h_impact_parameter_xy_significance", "", {HistType::kTH1F, {{axisImpactParameterXYSignificance}}}); - registry.add("h_impact_parameter_z", "", {HistType::kTH1F, {{axisImpactParameterZ}}}); - registry.add("h_impact_parameter_z_significance", "", {HistType::kTH1F, {{axisImpactParameterZSignificance}}}); - registry.add("h_impact_parameter_xyz", "", {HistType::kTH1F, {{axisImpactParameterXYZ}}}); - registry.add("h_impact_parameter_xyz_significance", "", {HistType::kTH1F, {{axisImpactParameterXYZSignificance}}}); + if (fillIPxy) { + registry.add("h_impact_parameter_xy", "", {HistType::kTH1F, {{axisImpactParameterXY}}}); + registry.add("h_impact_parameter_xy_significance", "", {HistType::kTH1F, {{axisImpactParameterXYSignificance}}}); + } + if (fillIPz) { + registry.add("h_impact_parameter_z", "", {HistType::kTH1F, {{axisImpactParameterZ}}}); + registry.add("h_impact_parameter_z_significance", "", {HistType::kTH1F, {{axisImpactParameterZSignificance}}}); + } + if (fillIPxyz) { + registry.add("h_impact_parameter_xyz", "", {HistType::kTH1F, {{axisImpactParameterXYZ}}}); + registry.add("h_impact_parameter_xyz_significance", "", {HistType::kTH1F, {{axisImpactParameterXYZSignificance}}}); + } } if (doprocessValFlavourDefMCD) { registry.add("h2_flavour_dist_quark_flavour_dist_hadron", "", {HistType::kTH2F, {{axisJetFlavour}, {axisJetFlavour}}}); @@ -193,21 +199,27 @@ struct JetTaggerHFQA { registry.add("h3_jet_pt_track_pt_sign_impact_parameter_xyz_significance", "", {HistType::kTH3F, {{axisJetPt}, {axisTrackPt}, {axisImpactParameterXYZSignificance}}}); } if (fillTrackCounting) { - registry.add("h2_jet_pt_sign_impact_parameter_xy_significance_N1", "", {HistType::kTH2F, {{axisJetPt}, {axisImpactParameterXYSignificance}}}); - registry.add("h2_jet_pt_sign_impact_parameter_xy_significance_N2", "", {HistType::kTH2F, {{axisJetPt}, {axisImpactParameterXYSignificance}}}); - registry.add("h2_jet_pt_sign_impact_parameter_xy_significance_N3", "", {HistType::kTH2F, {{axisJetPt}, {axisImpactParameterXYSignificance}}}); - registry.add("h2_jet_pt_sign_impact_parameter_z_significance_N1", "", {HistType::kTH2F, {{axisJetPt}, {axisImpactParameterXYSignificance}}}); - registry.add("h2_jet_pt_sign_impact_parameter_z_significance_N2", "", {HistType::kTH2F, {{axisJetPt}, {axisImpactParameterXYSignificance}}}); - registry.add("h2_jet_pt_sign_impact_parameter_z_significance_N3", "", {HistType::kTH2F, {{axisJetPt}, {axisImpactParameterXYSignificance}}}); - registry.add("h2_jet_pt_sign_impact_parameter_xyz_significance_N1", "", {HistType::kTH2F, {{axisJetPt}, {axisImpactParameterXYSignificance}}}); - registry.add("h2_jet_pt_sign_impact_parameter_xyz_significance_N2", "", {HistType::kTH2F, {{axisJetPt}, {axisImpactParameterXYSignificance}}}); - registry.add("h2_jet_pt_sign_impact_parameter_xyz_significance_N3", "", {HistType::kTH2F, {{axisJetPt}, {axisImpactParameterXYSignificance}}}); - registry.add("h3_jet_pt_sign_impact_parameter_xy_significance_tc", "", {HistType::kTH3F, {{axisJetPt}, {axisImpactParameterXYSignificance}, {axisNumOrder}}}); - registry.add("h3_jet_pt_sign_impact_parameter_z_significance_tc", "", {HistType::kTH3F, {{axisJetPt}, {axisImpactParameterZSignificance}, {axisNumOrder}}}); - registry.add("h3_jet_pt_sign_impact_parameter_xyz_significance_tc", "", {HistType::kTH3F, {{axisJetPt}, {axisImpactParameterXYZSignificance}, {axisNumOrder}}}); - registry.add("h3_track_pt_sign_impact_parameter_xy_significance_tc", "", {HistType::kTH3F, {{axisTrackPt}, {axisImpactParameterXYSignificance}, {axisNumOrder}}}); - registry.add("h3_track_pt_sign_impact_parameter_z_significance_tc", "", {HistType::kTH3F, {{axisTrackPt}, {axisImpactParameterZSignificance}, {axisNumOrder}}}); - registry.add("h3_track_pt_sign_impact_parameter_xyz_significance_tc", "", {HistType::kTH3F, {{axisTrackPt}, {axisImpactParameterXYZSignificance}, {axisNumOrder}}}); + if (fillIPxy) { + registry.add("h2_jet_pt_sign_impact_parameter_xy_significance_N1", "", {HistType::kTH2F, {{axisJetPt}, {axisImpactParameterXYSignificance}}}); + registry.add("h2_jet_pt_sign_impact_parameter_xy_significance_N2", "", {HistType::kTH2F, {{axisJetPt}, {axisImpactParameterXYSignificance}}}); + registry.add("h2_jet_pt_sign_impact_parameter_xy_significance_N3", "", {HistType::kTH2F, {{axisJetPt}, {axisImpactParameterXYSignificance}}}); + registry.add("h3_jet_pt_sign_impact_parameter_xy_significance_tc", "", {HistType::kTH3F, {{axisJetPt}, {axisImpactParameterXYSignificance}, {axisNumOrder}}}); + registry.add("h3_track_pt_sign_impact_parameter_xy_significance_tc", "", {HistType::kTH3F, {{axisTrackPt}, {axisImpactParameterXYSignificance}, {axisNumOrder}}}); + } + if (fillIPz) { + registry.add("h2_jet_pt_sign_impact_parameter_z_significance_N1", "", {HistType::kTH2F, {{axisJetPt}, {axisImpactParameterXYSignificance}}}); + registry.add("h2_jet_pt_sign_impact_parameter_z_significance_N2", "", {HistType::kTH2F, {{axisJetPt}, {axisImpactParameterXYSignificance}}}); + registry.add("h2_jet_pt_sign_impact_parameter_z_significance_N3", "", {HistType::kTH2F, {{axisJetPt}, {axisImpactParameterXYSignificance}}}); + registry.add("h3_jet_pt_sign_impact_parameter_z_significance_tc", "", {HistType::kTH3F, {{axisJetPt}, {axisImpactParameterZSignificance}, {axisNumOrder}}}); + registry.add("h3_track_pt_sign_impact_parameter_z_significance_tc", "", {HistType::kTH3F, {{axisTrackPt}, {axisImpactParameterZSignificance}, {axisNumOrder}}}); + } + if (fillIPxyz) { + registry.add("h2_jet_pt_sign_impact_parameter_xyz_significance_N1", "", {HistType::kTH2F, {{axisJetPt}, {axisImpactParameterXYSignificance}}}); + registry.add("h2_jet_pt_sign_impact_parameter_xyz_significance_N2", "", {HistType::kTH2F, {{axisJetPt}, {axisImpactParameterXYSignificance}}}); + registry.add("h2_jet_pt_sign_impact_parameter_xyz_significance_N3", "", {HistType::kTH2F, {{axisJetPt}, {axisImpactParameterXYSignificance}}}); + registry.add("h3_jet_pt_sign_impact_parameter_xyz_significance_tc", "", {HistType::kTH3F, {{axisJetPt}, {axisImpactParameterXYZSignificance}, {axisNumOrder}}}); + registry.add("h3_track_pt_sign_impact_parameter_xyz_significance_tc", "", {HistType::kTH3F, {{axisTrackPt}, {axisImpactParameterXYZSignificance}, {axisNumOrder}}}); + } } } if (doprocessIPsMCD || doprocessIPsMCDWeighted || doprocessIPsMCPMCDMatched || doprocessIPsMCPMCDMatchedWeighted) { @@ -249,18 +261,24 @@ struct JetTaggerHFQA { registry.add("h3_track_pt_sign_impact_parameter_xyz_significance_flavour", "", {HistType::kTH3F, {{axisTrackPt}, {axisImpactParameterXYZSignificance}, {axisJetFlavour}}}); } if (fillTrackCounting) { - registry.add("h3_jet_pt_sign_impact_parameter_xy_significance_flavour_N1", "", {HistType::kTH3F, {{axisJetPt}, {axisImpactParameterXYSignificance}, {axisJetFlavour}}}); - registry.add("h3_jet_pt_sign_impact_parameter_xy_significance_flavour_N2", "", {HistType::kTH3F, {{axisJetPt}, {axisImpactParameterXYSignificance}, {axisJetFlavour}}}); - registry.add("h3_jet_pt_sign_impact_parameter_xy_significance_flavour_N3", "", {HistType::kTH3F, {{axisJetPt}, {axisImpactParameterXYSignificance}, {axisJetFlavour}}}); - registry.add("h3_jet_pt_sign_impact_parameter_z_significance_flavour_N1", "", {HistType::kTH3F, {{axisJetPt}, {axisImpactParameterZSignificance}, {axisJetFlavour}}}); - registry.add("h3_jet_pt_sign_impact_parameter_z_significance_flavour_N2", "", {HistType::kTH3F, {{axisJetPt}, {axisImpactParameterZSignificance}, {axisJetFlavour}}}); - registry.add("h3_jet_pt_sign_impact_parameter_z_significance_flavour_N3", "", {HistType::kTH3F, {{axisJetPt}, {axisImpactParameterZSignificance}, {axisJetFlavour}}}); - registry.add("h3_jet_pt_sign_impact_parameter_xyz_significance_flavour_N1", "", {HistType::kTH3F, {{axisJetPt}, {axisImpactParameterXYZSignificance}, {axisJetFlavour}}}); - registry.add("h3_jet_pt_sign_impact_parameter_xyz_significance_flavour_N2", "", {HistType::kTH3F, {{axisJetPt}, {axisImpactParameterXYZSignificance}, {axisJetFlavour}}}); - registry.add("h3_jet_pt_sign_impact_parameter_xyz_significance_flavour_N3", "", {HistType::kTH3F, {{axisJetPt}, {axisImpactParameterXYZSignificance}, {axisJetFlavour}}}); - registry.add("h3_sign_impact_parameter_xy_significance_tc_flavour", "", {HistType::kTH3F, {{axisImpactParameterXYSignificance}, {axisNumOrder}, {axisJetFlavour}}}); - registry.add("h3_sign_impact_parameter_z_significance_tc_flavour", "", {HistType::kTH3F, {{axisImpactParameterZSignificance}, {axisNumOrder}, {axisJetFlavour}}}); - registry.add("h3_sign_impact_parameter_xyz_significance_tc_flavour", "", {HistType::kTH3F, {{axisImpactParameterXYZSignificance}, {axisNumOrder}, {axisJetFlavour}}}); + if (fillIPxy) { + registry.add("h3_jet_pt_sign_impact_parameter_xy_significance_flavour_N1", "", {HistType::kTH3F, {{axisJetPt}, {axisImpactParameterXYSignificance}, {axisJetFlavour}}}); + registry.add("h3_jet_pt_sign_impact_parameter_xy_significance_flavour_N2", "", {HistType::kTH3F, {{axisJetPt}, {axisImpactParameterXYSignificance}, {axisJetFlavour}}}); + registry.add("h3_jet_pt_sign_impact_parameter_xy_significance_flavour_N3", "", {HistType::kTH3F, {{axisJetPt}, {axisImpactParameterXYSignificance}, {axisJetFlavour}}}); + registry.add("h3_sign_impact_parameter_xy_significance_tc_flavour", "", {HistType::kTH3F, {{axisImpactParameterXYSignificance}, {axisNumOrder}, {axisJetFlavour}}}); + } + if (fillIPz) { + registry.add("h3_jet_pt_sign_impact_parameter_z_significance_flavour_N1", "", {HistType::kTH3F, {{axisJetPt}, {axisImpactParameterZSignificance}, {axisJetFlavour}}}); + registry.add("h3_jet_pt_sign_impact_parameter_z_significance_flavour_N2", "", {HistType::kTH3F, {{axisJetPt}, {axisImpactParameterZSignificance}, {axisJetFlavour}}}); + registry.add("h3_jet_pt_sign_impact_parameter_z_significance_flavour_N3", "", {HistType::kTH3F, {{axisJetPt}, {axisImpactParameterZSignificance}, {axisJetFlavour}}}); + registry.add("h3_sign_impact_parameter_z_significance_tc_flavour", "", {HistType::kTH3F, {{axisImpactParameterZSignificance}, {axisNumOrder}, {axisJetFlavour}}}); + } + if (fillIPxyz) { + registry.add("h3_jet_pt_sign_impact_parameter_xyz_significance_flavour_N1", "", {HistType::kTH3F, {{axisJetPt}, {axisImpactParameterXYZSignificance}, {axisJetFlavour}}}); + registry.add("h3_jet_pt_sign_impact_parameter_xyz_significance_flavour_N2", "", {HistType::kTH3F, {{axisJetPt}, {axisImpactParameterXYZSignificance}, {axisJetFlavour}}}); + registry.add("h3_jet_pt_sign_impact_parameter_xyz_significance_flavour_N3", "", {HistType::kTH3F, {{axisJetPt}, {axisImpactParameterXYZSignificance}, {axisJetFlavour}}}); + registry.add("h3_sign_impact_parameter_xyz_significance_tc_flavour", "", {HistType::kTH3F, {{axisImpactParameterXYZSignificance}, {axisNumOrder}, {axisJetFlavour}}}); + } } } if (doprocessIPsMCP || doprocessIPsMCPWeighted) { @@ -1057,12 +1075,18 @@ struct JetTaggerHFQA { varImpXYZ = dcaXYZ * jettaggingutilities::cmTomum; varImpXYZSig = dcaXYZ / sigmadcaXYZ; - registry.fill(HIST("h_impact_parameter_xy"), varImpXY); - registry.fill(HIST("h_impact_parameter_xy_significance"), varImpXYSig); - registry.fill(HIST("h_impact_parameter_z"), varImpZ); - registry.fill(HIST("h_impact_parameter_z_significance"), varImpZSig); - registry.fill(HIST("h_impact_parameter_xyz"), varImpXYZ); - registry.fill(HIST("h_impact_parameter_xyz_significance"), varImpXYZSig); + if (fillIPxy) { + registry.fill(HIST("h_impact_parameter_xy"), varImpXY); + registry.fill(HIST("h_impact_parameter_xy_significance"), varImpXYSig); + } + if (fillIPz) { + registry.fill(HIST("h_impact_parameter_z"), varImpZ); + registry.fill(HIST("h_impact_parameter_z_significance"), varImpZSig); + } + if (fillIPxyz) { + registry.fill(HIST("h_impact_parameter_xyz"), varImpXYZ); + registry.fill(HIST("h_impact_parameter_xyz_significance"), varImpXYZSig); + } } } PROCESS_SWITCH(JetTaggerHFQA, processTracksDca, "Fill inclusive tracks' imformation for data", false); diff --git a/PWGJE/Tasks/ChJetTriggerQATask.cxx b/PWGJE/Tasks/jetTriggerChargedQa.cxx similarity index 54% rename from PWGJE/Tasks/ChJetTriggerQATask.cxx rename to PWGJE/Tasks/jetTriggerChargedQa.cxx index 6b60b68569d..3cbb9e18070 100644 --- a/PWGJE/Tasks/ChJetTriggerQATask.cxx +++ b/PWGJE/Tasks/jetTriggerChargedQa.cxx @@ -9,15 +9,16 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -// jet Trigger QA Task -// -/// \author Filip Krizek +/// \author Filip Krizek +/// \author Kotliarov Artem +/// \file jetTriggerChargedQa.cxx +/// \brief QA of trigger performance for charged jets + #include #include #include #include #include -#include #include "Framework/ASoA.h" #include "Framework/AnalysisDataModel.h" @@ -26,6 +27,7 @@ #include "EventFiltering/filterTables.h" +#include "CommonConstants/MathConstants.h" #include "Common/Core/TrackSelection.h" #include "Common/Core/TrackSelectionDefaults.h" #include "Common/DataModel/EventSelection.h" @@ -44,14 +46,14 @@ using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; -using filteredColl = soa::Filtered>::iterator; -using filteredJTracks = soa::Filtered>; -using filteredJets = soa::Filtered>; -using joinedTracks = soa::Join; +using FilteredColl = soa::Filtered>::iterator; +using FilteredJTracks = soa::Filtered>; +using FilteredJets = soa::Filtered>; +using JoinedTracks = soa::Join; -float DcaXYPtCut(float tracPt) +float dcaXYPtCut(float tracPt) { - return 0.0105f + 0.0350f / pow(tracPt, 1.1f); + return 0.0105f + 0.0350f / std::pow(tracPt, 1.1f); } // What this task should do @@ -64,7 +66,7 @@ float DcaXYPtCut(float tracPt) // b) from events selected by EPN // It would be good to run it for several jet radii e.g. 0.2, 0.4, 0.6 -struct ChJetTriggerQATask { +struct JetTriggerChargedQa { Configurable evSel{"evSel", "sel8", "choose event selection"}; Configurable cfgVertexCut{"cfgVertexCut", 10.0, "Accepted z-vertex range"}; @@ -80,19 +82,21 @@ struct ChJetTriggerQATask { Configurable bHighPtTrigger{"bHighPtTrigger", false, "charged jet high pT trigger selection"}; Configurable bTrackLowPtTrigger{"bTrackLowPtTrigger", false, "track low pT trigger selection"}; Configurable bTrackHighPtTrigger{"bTrackHighPtTrigger", false, "track high pT trigger selection"}; - Configurable bAddSupplementHistosToOutput{"bAddAdditionalHistosToOutput", false, "add supplementary histos to the output"}; + Configurable bAddSupplementHistosToOutput{"bAddSupplementHistosToOutput", false, "add supplementary histos to the output"}; + Configurable bStudyPhiTrack{"bStudyPhiTrack", false, "add histos for detailed study of track phi distribution"}; Configurable phiAngleRestriction{"phiAngleRestriction", 0.3, "angle to restrict track phi for plotting tpc momentum"}; - Configurable dcaXY_multFact{"dcaXY_multFact", 3., "mult factor to relax pT dependent dcaXY cut for quality tracks"}; - Configurable dcaZ_cut{"dcaZ_cut", 3., "cut on dcaZ for quality tracks"}; + Configurable dcaXYMultFact{"dcaXYMultFact", 3., "mult factor to relax pT dependent dcaXY cut for quality tracks"}; + Configurable dcaZCut{"dcaZCut", 3., "cut on dcaZ for quality tracks"}; - ConfigurableAxis dcaXY_Binning{"dcaXY_Binning", {100, -5., 5.}, ""}; - ConfigurableAxis dcaZ_Binning{"dcaZ_Binning", {100, -3., 3.}, ""}; + float twoPi = constants::math::TwoPI; + ConfigurableAxis dcaXYBinning{"dcaXYBinning", {100, -5., 5.}, ""}; + ConfigurableAxis dcaZBinning{"dcaZBinning", {100, -3., 3.}, ""}; - ConfigurableAxis xPhiAxis{"xPhiAxis", {180, 0., TMath::TwoPi()}, ""}; + ConfigurableAxis xPhiAxis{"xPhiAxis", {40, 0., twoPi}, ""}; ConfigurableAxis yQ1pTAxis{"yQ1pTAxis", {200, -0.5, 0.5}, ""}; - float fiducialVolume; // 0.9 - jetR + float fiducialVolume = 0.0; // 0.9 - jetR HistogramRegistry spectra; @@ -106,47 +110,50 @@ struct ChJetTriggerQATask { trackSelection = jetderiveddatautilities::initialiseTrackSelection(static_cast(trackSelections)); // Basic histos - spectra.add("vertexZ", "z vertex", {HistType::kTH1F, {{400, -20., +20.}}}); - spectra.add("ptphiTrackInclGood", "pT vs phi inclusive good tracks", {HistType::kTH2F, {{100, 0., +100.}, {60, 0, TMath::TwoPi()}}}); - spectra.add("ptetaTrackInclGood", "pT vs eta inclusive good tracks", {HistType::kTH2F, {{100, 0., +100.}, {80, -1., 1.}}}); - spectra.add("ptLeadingTrack", "pT leading track", {HistType::kTH1F, {{100, 0., +100.}}}); - spectra.add("ptJetChInclFidVol", "inclusive charged jet pT in fiducial volume", {HistType::kTH1F, {{200, 0., +200.}}}); - spectra.add("ptphiJetChInclFidVol", "inclusive charged jet pT vs phi in fiducial volume", {HistType::kTH2F, {{100, 0., +100.}, {60, 0, TMath::TwoPi()}}}); - spectra.add("ptphiJetChInclFullVol", "inclusive charged jet pT vs phi in full TPC volume", {HistType::kTH2F, {{100, 0., +100.}, {60, 0, TMath::TwoPi()}}}); - spectra.add("ptetaJetChInclFidVol", "inclusive charged jet pT vs eta in fiducial volume", {HistType::kTH2F, {{100, 0., +100.}, {80, -1., 1.}}}); - spectra.add("ptetaJetChInclFullVol", "inclusive charged jet pT vs eta in full TPC volume", {HistType::kTH2F, {{100, 0., +100.}, {80, -1., 1.}}}); - spectra.add("ptetaLeadingJetFullVol", "pT vs eta leading jet", {HistType::kTH2F, {{100, 0., +100.}, {80, -1., 1.}}}); - spectra.add("ptphiLeadingJetFullVol", "pT vs phi leading jet", {HistType::kTH2F, {{100, 0., +100.}, {60, 0, TMath::TwoPi()}}}); - - spectra.add("globalP_tpcglobalPDiff_withoutcuts", "difference of global and TPC inner momentum vs global momentum without any selection applied", {HistType::kTH2F, {{100, 0., +100.}, {200, -100., +100.}}}); - spectra.add("globalP_tpcglobalPDiff", "difference of global and TPC inner momentum vs global momentum with selection applied", {HistType::kTH2F, {{100, 0., +100.}, {200, -100., +100.}}}); - spectra.add("global1overP_tpcglobalPDiff", "difference of global and TPC inner momentum vs global momentum with selection applied", {HistType::kTH2F, {{100, 0., +100.}, {500, -8., +8.}}}); - - spectra.add("globalP_tpcglobalPDiff_withoutcuts_phirestrict", "difference of global and TPC inner momentum vs global momentum without any selection applied in a restricted phi", {HistType::kTH2F, {{100, 0., +100.}, {200, -100., +100.}}}); - spectra.add("globalP_tpcglobalPDiff_phirestrict", "difference of global and TPC inner momentum vs global momentum with selection applied restricted phi", {HistType::kTH2F, {{100, 0., +100.}, {200, -100., +100.}}}); - spectra.add("global1overP_tpcglobalPDiff_phirestrict", "difference of 1/p global and TPC inner momentum vs global momentum with selection applied restricted phi", {HistType::kTH2F, {{100, 0., +100.}, {500, -8., +8.}}}); - - spectra.add("DCAxy_track_Phi_pT", "track DCAxy vs phi & pT of tracks w. nITSClusters #geq 4", kTH3F, {dcaXY_Binning, {60, 0., TMath::TwoPi()}, {100, 0., 100.}}); - spectra.add("DCAz_track_Phi_pT", "track DCAz vs phi & pT of tracks w. nITSClusters #geq 4", kTH3F, {dcaZ_Binning, {60, 0., TMath::TwoPi()}, {100, 0., 100.}}); - spectra.add("nITSClusters_TrackPt", "Number of ITS hits vs phi & pT of tracks", kTH3F, {{7, 1., 8.}, {60, 0., TMath::TwoPi()}, {100, 0., 100.}}); - spectra.add("ptphiQualityTracks", "pT vs phi of quality tracks", {HistType::kTH2F, {{100, 0., 100.}, {60, 0, TMath::TwoPi()}}}); - spectra.add("ptphiAllTracks", "pT vs phi of all tracks", {HistType::kTH2F, {{100, 0., +100.}, {60, 0, TMath::TwoPi()}}}); - spectra.add("phi_Q1pT", "Track phi vs. q/pT", kTH2F, {xPhiAxis, yQ1pTAxis}); + spectra.add("vertexZ", "z vertex", kTH1F, {{60, -12., 12.}}); + spectra.add("ptphiTrackInclGood", "pT vs phi inclusive good tracks", kTH2F, {{100, 0., 100.}, {40, 0, twoPi}}); + spectra.add("ptetaTrackInclGood", "pT vs eta inclusive good tracks", kTH2F, {{100, 0., 100.}, {40, -1., 1.}}); + spectra.add("ptLeadingTrack", "pT leading track", kTH1F, {{100, 0., 100.}}); + spectra.add("ptJetChInclFidVol", "inclusive charged jet pT in fiducial volume", kTH1F, {{200, 0., 200.}}); + spectra.add("ptphiJetChInclFidVol", "inclusive charged jet pT vs phi in fiducial volume", kTH2F, {{100, 0., 100.}, {40, 0, twoPi}}); + spectra.add("ptphiJetChInclFullVol", "inclusive charged jet pT vs phi in full TPC volume", kTH2F, {{100, 0., 100.}, {40, 0, twoPi}}); + spectra.add("ptetaJetChInclFidVol", "inclusive charged jet pT vs eta in fiducial volume", kTH2F, {{100, 0., 100.}, {40, -1., 1.}}); + spectra.add("ptetaJetChInclFullVol", "inclusive charged jet pT vs eta in full TPC volume", kTH2F, {{100, 0., 100.}, {40, -1., 1.}}); + spectra.add("ptetaLeadingJetFullVol", "pT vs eta leading jet", kTH2F, {{100, 0., 100.}, {40, -1., 1.}}); + spectra.add("ptphiLeadingJetFullVol", "pT vs phi leading jet", kTH2F, {{100, 0., 100.}, {40, 0, twoPi}}); // Supplementary plots if (bAddSupplementHistosToOutput) { - spectra.add("ptJetChInclFullVol", "inclusive charged jet pT in full volume", {HistType::kTH1F, {{200, 0., +200.}}}); - spectra.add("phietaTrackAllInclGood", "phi vs eta all inclusive good tracks", {HistType::kTH2F, {{80, -1., 1.}, {60, 0, TMath::TwoPi()}}}); - spectra.add("phietaTrackHighPtInclGood", "phi vs eta inclusive good tracks with pT > 10 GeV", {HistType::kTH2F, {{80, -1., 1.}, {60, 0, TMath::TwoPi()}}}); - spectra.add("phietaJetChInclFidVol", "inclusive charged jet phi vs eta in fiducial volume", {HistType::kTH2F, {{80, -1., 1.}, {60, 0, TMath::TwoPi()}}}); - spectra.add("phietaJetChInclFullVol", "inclusive charged jet phi vs eta in full TPC volume", {HistType::kTH2F, {{80, -1., 1.}, {60, 0, TMath::TwoPi()}}}); - spectra.add("phietaJetChInclHighPtFidVol", "inclusive charged jet phi vs eta in fiducial volume", {HistType::kTH2F, {{80, -1., 1.}, {60, 0, TMath::TwoPi()}}}); - spectra.add("phietaJetChInclHighPtFullVol", "inclusive charged jet phi vs eta in full TPC volume", {HistType::kTH2F, {{80, -1., 1.}, {60, 0, TMath::TwoPi()}}}); - spectra.add("ptetaLeadingTrack", "pT vs eta leading tracks", {HistType::kTH2F, {{100, 0., +100.}, {80, -1., 1.}}}); - spectra.add("ptphiLeadingTrack", "pT vs phi leading tracks", {HistType::kTH2F, {{100, 0., +100.}, {60, 0, TMath::TwoPi()}}}); - spectra.add("jetAreaFullVol", "area of all jets in full TPC volume", {HistType::kTH2F, {{100, 0., +100.}, {50, 0., 2.}}}); - spectra.add("jetAreaFidVol", "area of all jets in fiducial volume", {HistType::kTH2F, {{100, 0., +100.}, {50, 0., 2.}}}); - spectra.add("fLeadJetChPtVsLeadingTrack", "inclusive charged jet pT in TPC volume", {HistType::kTH2F, {{100, 0., +100.}, {100, 0., +100.}}}); + spectra.add("ptJetChInclFullVol", "inclusive charged jet pT in full volume", kTH1F, {{200, 0., 200.}}); + spectra.add("phietaTrackAllInclGood", "phi vs eta all inclusive good tracks", kTH2F, {{80, -1., 1.}, {40, 0, twoPi}}); + spectra.add("phietaTrackHighPtInclGood", "phi vs eta inclusive good tracks with pT > 10 GeV", kTH2F, {{40, -1., 1.}, {40, 0, twoPi}}); + spectra.add("phietaJetChInclFidVol", "inclusive charged jet phi vs eta in fiducial volume", kTH2F, {{40, -1., 1.}, {40, 0, twoPi}}); + spectra.add("phietaJetChInclFullVol", "inclusive charged jet phi vs eta in full TPC volume", kTH2F, {{40, -1., 1.}, {40, 0, twoPi}}); + spectra.add("phietaJetChInclHighPtFidVol", "inclusive charged jet phi vs eta in fiducial volume", kTH2F, {{40, -1., 1.}, {40, 0, twoPi}}); + spectra.add("phietaJetChInclHighPtFullVol", "inclusive charged jet phi vs eta in full TPC volume", kTH2F, {{40, -1., 1.}, {40, 0, twoPi}}); + spectra.add("ptetaLeadingTrack", "pT vs eta leading tracks", kTH2F, {{100, 0., 100.}, {40, -1., 1.}}); + spectra.add("ptphiLeadingTrack", "pT vs phi leading tracks", kTH2F, {{100, 0., 100.}, {40, 0, twoPi}}); + spectra.add("jetAreaFullVol", "area of all jets in full TPC volume", kTH2F, {{100, 0., 100.}, {50, 0., 2.}}); + spectra.add("jetAreaFidVol", "area of all jets in fiducial volume", kTH2F, {{100, 0., 100.}, {50, 0., 2.}}); + spectra.add("fLeadJetChPtVsLeadingTrack", "inclusive charged jet pT in TPC volume", kTH2F, {{100, 0., 100.}, {100, 0., 100.}}); + } + + // Study of non-uniformity of phi distribution of tracks + if (bStudyPhiTrack) { + spectra.add("globalP_tpcglobalPDiff_withoutcuts", "difference of global and TPC inner momentum vs global momentum without any selection applied", kTH2F, {{100, 0., 100.}, {200, -100., 100.}}); + spectra.add("globalP_tpcglobalPDiff", "difference of global and TPC inner momentum vs global momentum with selection applied", kTH2F, {{100, 0., 100.}, {200, -100., 100.}}); + spectra.add("global1overP_tpcglobalPDiff", "difference of global and TPC inner momentum vs global momentum with selection applied", kTH2F, {{100, 0., 100.}, {125, -8., 8.}}); + + spectra.add("globalP_tpcglobalPDiff_withoutcuts_phirestrict", "difference of global and TPC inner momentum vs global momentum without any selection applied in a restricted phi", kTH2F, {{100, 0., 100.}, {200, -100., 100.}}); + spectra.add("globalP_tpcglobalPDiff_phirestrict", "difference of global and TPC inner momentum vs global momentum with selection applied restricted phi", kTH2F, {{100, 0., 100.}, {200, -100., 100.}}); + spectra.add("global1overP_tpcglobalPDiff_phirestrict", "difference of 1/p global and TPC inner momentum vs global momentum with selection applied restricted phi", kTH2F, {{100, 0., 100.}, {500, -8., 8.}}); + + spectra.add("DCAxy_track_Phi_pT", "track DCAxy vs phi & pT of tracks w. nITSClusters #geq 4", kTH3F, {dcaXYBinning, {40, 0., twoPi}, {100, 0., 100.}}); + spectra.add("DCAz_track_Phi_pT", "track DCAz vs phi & pT of tracks w. nITSClusters #geq 4", kTH3F, {dcaZBinning, {40, 0., twoPi}, {100, 0., 100.}}); + spectra.add("nITSClusters_TrackPt", "Number of ITS hits vs phi & pT of tracks", kTH3F, {{7, 1., 8.}, {40, 0., twoPi}, {100, 0., 100.}}); + spectra.add("ptphiQualityTracks", "pT vs phi of quality tracks", kTH2F, {{100, 0., 100.}, {40, 0, twoPi}}); + spectra.add("ptphiAllTracks", "pT vs phi of all tracks", kTH2F, {{100, 0., 100.}, {40, 0, twoPi}}); + spectra.add("phi_Q1pT", "Track phi vs. q/pT", kTH2F, {xPhiAxis, yQ1pTAxis}); } } @@ -159,7 +166,7 @@ struct ChJetTriggerQATask { // declare filters on jets Filter jetRadiusSelection = (aod::jet::r == nround(cfgJetR.node() * 100.0f)); - void process(filteredColl const& collision, filteredJTracks const& tracks, filteredJets const& jets, joinedTracks const&) + void process(FilteredColl const& collision, FilteredJTracks const& tracks, FilteredJets const& jets, JoinedTracks const&) { if (!collision.selection_bit(aod::evsel::kNoTimeFrameBorder)) { @@ -191,72 +198,70 @@ struct ChJetTriggerQATask { float leadingTrackEta = -2.0; float leadingTrackPhi = -1.0; - spectra.fill(HIST("vertexZ"), - collision.posZ()); // Inclusive Track Cross TPC Rows + spectra.fill(HIST("vertexZ"), collision.posZ()); // Inclusive Track Cross TPC Rows - for (auto const& track : tracks) { // loop over filtered tracks in full TPC volume having pT > 100 MeV + // loop over filtered tracks in full TPC volume having pT > 100 MeV + for (auto const& track : tracks) { - auto const& originalTrack = track.track_as(); + auto const& originalTrack = track.track_as(); - spectra.fill(HIST("globalP_tpcglobalPDiff_withoutcuts"), track.p(), track.p() - originalTrack.tpcInnerParam()); + if (bStudyPhiTrack) { - if (TMath::Abs(track.phi() - TMath::Pi()) < phiAngleRestriction) { - spectra.fill(HIST("globalP_tpcglobalPDiff_withoutcuts_phirestrict"), track.p(), track.p() - originalTrack.tpcInnerParam()); - } + spectra.fill(HIST("globalP_tpcglobalPDiff_withoutcuts"), track.p(), track.p() - originalTrack.tpcInnerParam()); + spectra.fill(HIST("ptphiAllTracks"), track.pt(), track.phi()); - spectra.fill(HIST("ptphiAllTracks"), track.pt(), track.phi()); + if (std::fabs(track.phi() - constants::math::PI) < phiAngleRestriction) { + spectra.fill(HIST("globalP_tpcglobalPDiff_withoutcuts_phirestrict"), track.p(), track.p() - originalTrack.tpcInnerParam()); + } + } - if (!jetderiveddatautilities::selectTrack(track, trackSelection)) { + if (!jetderiveddatautilities::selectTrack(track, trackSelection)) continue; - } - spectra.fill(HIST("phi_Q1pT"), originalTrack.phi(), originalTrack.sign() / originalTrack.pt()); - spectra.fill(HIST("ptphiQualityTracks"), track.pt(), track.phi()); + spectra.fill(HIST("ptphiTrackInclGood"), track.pt(), track.phi()); // Inclusive Track pT vs phi spectrum in TPC volume + spectra.fill(HIST("ptetaTrackInclGood"), track.pt(), track.eta()); // Inclusive Track pT vs eta spectrum in TPC volume - bool bDcaCondition = (fabs(track.dcaZ()) < dcaZ_cut) && (fabs(track.dcaXY()) < dcaXY_multFact * DcaXYPtCut(track.pt())); - if (originalTrack.itsNCls() >= 4 && bDcaCondition) { // correspond to number of track hits in ITS layers - spectra.fill(HIST("DCAxy_track_Phi_pT"), track.dcaXY(), track.phi(), track.pt()); - spectra.fill(HIST("DCAz_track_Phi_pT"), track.dcaZ(), track.phi(), track.pt()); - } + if (bAddSupplementHistosToOutput) { + spectra.fill(HIST("phietaTrackAllInclGood"), track.eta(), track.phi()); // Inclusive Track pT vs eta spectrum in TPC volume - spectra.fill(HIST("nITSClusters_TrackPt"), originalTrack.itsNCls(), track.phi(), track.pt()); + float trackPtCut = 5.0; + if (track.pt() > trackPtCut) { + spectra.fill(HIST("phietaTrackHighPtInclGood"), track.eta(), track.phi()); // Inclusive Track pT vs eta spectrum in TPC volume + } + } - spectra.fill(HIST("globalP_tpcglobalPDiff"), track.p(), track.p() - originalTrack.tpcInnerParam()); - if (track.p() > 0 && originalTrack.tpcInnerParam() > 0) { - spectra.fill(HIST("global1overP_tpcglobalPDiff"), track.p(), 1. / track.p() - 1. / originalTrack.tpcInnerParam()); + if (track.pt() > leadingTrackPt) { // Find leading track pT in full TPC volume + leadingTrackPt = track.pt(); + leadingTrackEta = track.eta(); + leadingTrackPhi = track.phi(); } - if (TMath::Abs(track.phi() - TMath::Pi()) < phiAngleRestriction) { - spectra.fill(HIST("globalP_tpcglobalPDiff_phirestrict"), track.p(), track.p() - originalTrack.tpcInnerParam()); - if (track.p() > 0 && originalTrack.tpcInnerParam() > 0) { - spectra.fill(HIST("global1overP_tpcglobalPDiff_phirestrict"), track.p(), 1. / track.p() - 1. / originalTrack.tpcInnerParam()); + if (bStudyPhiTrack) { + spectra.fill(HIST("phi_Q1pT"), originalTrack.phi(), originalTrack.sign() / originalTrack.pt()); + spectra.fill(HIST("ptphiQualityTracks"), track.pt(), track.phi()); + + bool bDcaCondition = (std::fabs(track.dcaZ()) < dcaZCut) && (std::fabs(track.dcaXY()) < dcaXYMultFact * dcaXYPtCut(track.pt())); + + int nITSClusters = 4; + if (originalTrack.itsNCls() >= nITSClusters && bDcaCondition) { // correspond to number of track hits in ITS layers + spectra.fill(HIST("DCAxy_track_Phi_pT"), track.dcaXY(), track.phi(), track.pt()); + spectra.fill(HIST("DCAz_track_Phi_pT"), track.dcaZ(), track.phi(), track.pt()); } - } - spectra.fill( - HIST("ptphiTrackInclGood"), track.pt(), - track.phi()); // Inclusive Track pT vs phi spectrum in TPC volume - spectra.fill( - HIST("ptetaTrackInclGood"), track.pt(), - track.eta()); // Inclusive Track pT vs eta spectrum in TPC volume + spectra.fill(HIST("nITSClusters_TrackPt"), originalTrack.itsNCls(), track.phi(), track.pt()); - if (bAddSupplementHistosToOutput) { - spectra.fill( - HIST("phietaTrackAllInclGood"), track.eta(), - track.phi()); // Inclusive Track pT vs eta spectrum in TPC volume - - if (track.pt() > 5.0) { - spectra.fill( - HIST("phietaTrackHighPtInclGood"), track.eta(), - track.phi()); // Inclusive Track pT vs eta spectrum in TPC volume + spectra.fill(HIST("globalP_tpcglobalPDiff"), track.p(), track.p() - originalTrack.tpcInnerParam()); + if (track.p() > 0 && originalTrack.tpcInnerParam() > 0) { + spectra.fill(HIST("global1overP_tpcglobalPDiff"), track.p(), 1. / track.p() - 1. / originalTrack.tpcInnerParam()); } - } - if (track.pt() > - leadingTrackPt) { // Find leading track pT in full TPC volume - leadingTrackPt = track.pt(); - leadingTrackEta = track.eta(); - leadingTrackPhi = track.phi(); + if (std::fabs(track.phi() - constants::math::PI) < phiAngleRestriction) { + spectra.fill(HIST("globalP_tpcglobalPDiff_phirestrict"), track.p(), track.p() - originalTrack.tpcInnerParam()); + + if (track.p() > 0 && originalTrack.tpcInnerParam() > 0) { + spectra.fill(HIST("global1overP_tpcglobalPDiff_phirestrict"), track.p(), 1. / track.p() - 1. / originalTrack.tpcInnerParam()); + } + } } } @@ -266,16 +271,14 @@ struct ChJetTriggerQATask { if (bAddSupplementHistosToOutput) { if (leadingTrackPt > -1.) { - spectra.fill(HIST("ptphiLeadingTrack"), leadingTrackPt, - leadingTrackPhi); - spectra.fill(HIST("ptetaLeadingTrack"), leadingTrackPt, - leadingTrackEta); + spectra.fill(HIST("ptphiLeadingTrack"), leadingTrackPt, leadingTrackPhi); + spectra.fill(HIST("ptetaLeadingTrack"), leadingTrackPt, leadingTrackEta); } } // Find leading jet pT in full TPC volume - for (auto& jet : jets) { - if (fabs(jet.eta()) < static_cast(cfgTPCVolume)) { + for (const auto& jet : jets) { + if (std::fabs(jet.eta()) < static_cast(cfgTPCVolume)) { if (jet.pt() > leadingJetPt) { leadingJetPt = jet.pt(); @@ -292,28 +295,29 @@ struct ChJetTriggerQATask { if (bAddSupplementHistosToOutput) { if (leadingJetPt > -1. && leadingTrackPt > -1.) { - spectra.fill(HIST("fLeadJetChPtVsLeadingTrack"), leadingTrackPt, - leadingJetPt); // leading jet pT versus leading track pT + spectra.fill(HIST("fLeadJetChPtVsLeadingTrack"), leadingTrackPt, leadingJetPt); // leading jet pT versus leading track pT } } // Inclusive Jet pT spectrum in Fiducial volume - for (auto& jet : jets) { - if (fabs(jet.eta()) < fiducialVolume) { + for (const auto& jet : jets) { + if (std::fabs(jet.eta()) < fiducialVolume) { spectra.fill(HIST("ptJetChInclFidVol"), jet.pt()); spectra.fill(HIST("ptphiJetChInclFidVol"), jet.pt(), jet.phi()); spectra.fill(HIST("ptetaJetChInclFidVol"), jet.pt(), jet.eta()); if (bAddSupplementHistosToOutput) { spectra.fill(HIST("phietaJetChInclFidVol"), jet.eta(), jet.phi()); - if (jet.pt() > 10.0) { + + float jetPtCut = 10.0; + if (jet.pt() > jetPtCut) { spectra.fill(HIST("phietaJetChInclHighPtFidVol"), jet.eta(), jet.phi()); } spectra.fill(HIST("jetAreaFidVol"), jet.pt(), jet.area()); } } - if (fabs(jet.eta()) < static_cast(cfgTPCVolume)) { + if (std::fabs(jet.eta()) < static_cast(cfgTPCVolume)) { spectra.fill(HIST("ptphiJetChInclFullVol"), jet.pt(), jet.phi()); spectra.fill(HIST("ptetaJetChInclFullVol"), jet.pt(), jet.eta()); @@ -321,7 +325,9 @@ struct ChJetTriggerQATask { spectra.fill(HIST("ptJetChInclFullVol"), jet.pt()); spectra.fill(HIST("phietaJetChInclFullVol"), jet.eta(), jet.phi()); - if (jet.pt() > 10.0) { + + float jetPtCut = 10.0; + if (jet.pt() > jetPtCut) { spectra.fill(HIST("phietaJetChInclHighPtFullVol"), jet.eta(), jet.phi()); } spectra.fill(HIST("jetAreaFullVol"), jet.pt(), jet.area()); @@ -332,9 +338,4 @@ struct ChJetTriggerQATask { } }; -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) -{ - - return WorkflowSpec{adaptAnalysisTask( - cfgc, TaskName{"jet-charged-trigger-qa"})}; -} +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{adaptAnalysisTask(cfgc)}; } diff --git a/PWGJE/Tasks/nucleiInJets.cxx b/PWGJE/Tasks/nucleiInJets.cxx index 150824d438b..0d620b1986f 100644 --- a/PWGJE/Tasks/nucleiInJets.cxx +++ b/PWGJE/Tasks/nucleiInJets.cxx @@ -41,7 +41,6 @@ #include "EventFiltering/ZorroSummary.h" #include "ReconstructionDataFormats/Track.h" - #include "PWGLF/DataModel/LFParticleIdentification.h" #include "PWGJE/Core/FastJetUtilities.h" @@ -698,13 +697,13 @@ struct nucleiInJets { } if (useTOFNsigmaPreSel && trk.hasTOF()) { - if (std::fabs(trk.tofNSigmaPr()) < cfgnTPCPIDPrTOF) + if (std::abs(trk.tofNSigmaPr()) < cfgnTPCPIDPrTOF) jetHist.fill(HIST("tracks/proton/h3PtVsProtonNSigmaTPCVsPtJet_jet"), trk.pt(), trk.tpcNSigmaPr(), jetPt); - if (std::fabs(trk.tofNSigmaDe()) < cfgnTPCPIDDeTOF) + if (std::abs(trk.tofNSigmaDe()) < cfgnTPCPIDDeTOF) jetHist.fill(HIST("tracks/deuteron/h3PtVsDeuteronNSigmaTPCVsPtJet_jet"), trk.pt(), trk.tpcNSigmaDe(), jetPt); - if (std::fabs(trk.tofNSigmaHe()) < cfgnTPCPIDHeTOF) + if (std::abs(trk.tofNSigmaHe()) < cfgnTPCPIDHeTOF) jetHist.fill(HIST("tracks/helium/h3PtVsHeliumNSigmaTPCVsPtJet_jet"), trk.pt(), trk.tpcNSigmaHe(), jetPt); - if (std::fabs(trk.tofNSigmaTr()) < cfgnTPCPIDTrTOF) + if (std::abs(trk.tofNSigmaTr()) < cfgnTPCPIDTrTOF) jetHist.fill(HIST("tracks/triton/h3PtVsTritonNSigmaTPCVsPtJet_jet"), trk.pt(), trk.tpcNSigmaTr(), jetPt); } else if (!useTOFNsigmaPreSel) { jetHist.fill(HIST("tracks/proton/h3PtVsProtonNSigmaTPCVsPtJet_jet"), trk.pt(), trk.tpcNSigmaPr(), jetPt); @@ -720,7 +719,7 @@ struct nucleiInJets { jetHist.fill(HIST("tracks/deuteron/dca/after/hDCAxyVsPtDeuteron_jet"), trk.dcaXY(), trk.pt()); jetHist.fill(HIST("tracks/deuteron/dca/after/hDCAzVsPtDeuteron_jet"), trk.dcaZ(), trk.pt()); } - if (cEnableTritonQA && std::abs(trk.tpcNSigmaHe()) < cfgnTPCPIDTr) { + if (cEnableTritonQA && std::abs(trk.tpcNSigmaTr()) < cfgnTPCPIDTr) { jetHist.fill(HIST("tracks/triton/dca/after/hDCAxyVsPtTriton_jet"), trk.dcaXY(), trk.pt()); jetHist.fill(HIST("tracks/triton/dca/after/hDCAzVsPtTriton_jet"), trk.dcaZ(), trk.pt()); } @@ -746,24 +745,24 @@ struct nucleiInJets { jetHist.fill(HIST("tracks/proton/h3TpcNsigmaTofNsigmaProtonVsPt_jet"), trk.tpcNSigmaPr(), trk.tofNSigmaPr(), trk.pt()); jetHist.fill(HIST("tracks/deuteron/h3TpcNsigmaTofNsigmaDeuteronVsPt_jet"), trk.tpcNSigmaDe(), trk.tofNSigmaDe(), trk.pt()); } else { - if (trk.tpcNSigmaPr() < useTPCpreSel) { + if (std::abs(trk.tpcNSigmaPr()) < cfgnTPCPIDPr) { jetHist.fill(HIST("tracks/proton/h2TOFmassProtonVsPt_jet"), massTOF, trk.pt()); jetHist.fill(HIST("tracks/proton/h2TOFmass2ProtonVsPt_jet"), massTOF * massTOF - gMassProton * gMassProton, trk.pt()); jetHist.fill(HIST("tracks/proton/h2TofNsigmaProtonVsPt_jet"), trk.tofNSigmaPr(), trk.pt()); jetHist.fill(HIST("tracks/proton/h3TpcNsigmaTofNsigmaProtonVsPt_jet"), trk.tpcNSigmaPr(), trk.tofNSigmaPr(), trk.pt()); } - if (trk.tpcNSigmaDe() < useTPCpreSel) { + if (std::abs(trk.tpcNSigmaDe()) < cfgnTPCPIDDe) { jetHist.fill(HIST("tracks/deuteron/h2TOFmassDeuteronVsPt_jet"), massTOF, trk.pt()); jetHist.fill(HIST("tracks/deuteron/h2TOFmass2DeuteronVsPt_jet"), massTOF * massTOF - gMassDeuteron * gMassDeuteron, trk.pt()); jetHist.fill(HIST("tracks/deuteron/h2TofNsigmaDeuteronVsPt_jet"), trk.tofNSigmaDe(), trk.pt()); jetHist.fill(HIST("tracks/deuteron/h3TpcNsigmaTofNsigmaDeuteronVsPt_jet"), trk.tpcNSigmaDe(), trk.tofNSigmaDe(), trk.pt()); } - if (trk.tpcNSigmaTr() < useTPCpreSel) { + if (std::abs(trk.tpcNSigmaTr()) < cfgnTPCPIDTr) { jetHist.fill(HIST("tracks/triton/h2TOFmassTritonVsPt_jet"), massTOF, trk.pt()); jetHist.fill(HIST("tracks/triton/h2TOFmass2TritonVsPt_jet"), massTOF * massTOF - gMassTriton * gMassTriton, trk.pt()); jetHist.fill(HIST("tracks/triton/h2TofNsigmaTritonVsPt_jet"), trk.tofNSigmaTr(), trk.pt()); } - if (trk.tpcNSigmaHe() < useTPCpreSel) { + if (std::abs(trk.tpcNSigmaHe()) < cfgnTPCPIDHe) { jetHist.fill(HIST("tracks/helium/h2TOFmassHeliumVsPt_jet"), massTOF, trk.pt()); jetHist.fill(HIST("tracks/helium/h2TOFmass2HeliumVsPt_jet"), massTOF * massTOF - gMassHelium * gMassHelium, trk.pt()); jetHist.fill(HIST("tracks/helium/h2TofNsigmaHeliumVsPt_jet"), trk.tofNSigmaHe(), trk.pt()); @@ -807,7 +806,7 @@ struct nucleiInJets { jetHist.fill(HIST("tracks/antiDeuteron/dca/after/hDCAxyVsPtantiDeuteron_jet"), trk.dcaXY(), trk.pt()); jetHist.fill(HIST("tracks/antiDeuteron/dca/after/hDCAzVsPtantiDeuteron_jet"), trk.dcaZ(), trk.pt()); } - if (cEnableHeliumQA && std::abs(trk.tpcNSigmaHe()) < cfgnTPCPIDHe) { + if (cEnableHeliumQA && std::abs(trk.tpcNSigmaTr()) < cfgnTPCPIDTr) { jetHist.fill(HIST("tracks/antiTriton/dca/after/hDCAxyVsPtantiTriton_jet"), trk.dcaXY(), trk.pt()); jetHist.fill(HIST("tracks/antiTriton/dca/after/hDCAzVsPtantiTriton_jet"), trk.dcaZ(), trk.pt()); } @@ -836,24 +835,24 @@ struct nucleiInJets { jetHist.fill(HIST("tracks/antiHelium/h2TOFmass2antiHeliumVsPt_jet"), massTOF * massTOF - gMassHelium * gMassHelium, trk.pt()); jetHist.fill(HIST("tracks/antiHelium/h2TofNsigmaantiHeliumVsPt_jet"), trk.tofNSigmaHe(), trk.pt()); } else { - if (trk.tpcNSigmaPr() < useTPCpreSel) { + if (std::abs(trk.tpcNSigmaPr()) < cfgnTPCPIDPr) { jetHist.fill(HIST("tracks/antiProton/h2TOFmassantiProtonVsPt_jet"), massTOF, trk.pt()); jetHist.fill(HIST("tracks/antiProton/h2TOFmass2antiProtonVsPt_jet"), massTOF * massTOF - gMassProton * gMassProton, trk.pt()); jetHist.fill(HIST("tracks/antiProton/h2TofNsigmaantiProtonVsPt_jet"), trk.tofNSigmaPr(), trk.pt()); jetHist.fill(HIST("tracks/antiProton/h3TpcNsigmaTofNsigmaantiProtonVsPt_jet"), trk.tpcNSigmaPr(), trk.tofNSigmaPr(), trk.pt()); } - if (trk.tpcNSigmaDe() < useTPCpreSel) { + if (std::abs(trk.tpcNSigmaDe()) < cfgnTPCPIDDe) { jetHist.fill(HIST("tracks/antiDeuteron/h2TOFmassantiDeuteronVsPt_jet"), massTOF, trk.pt()); jetHist.fill(HIST("tracks/antiDeuteron/h2TOFmass2antiDeuteronVsPt_jet"), massTOF * massTOF - gMassDeuteron * gMassDeuteron, trk.pt()); jetHist.fill(HIST("tracks/antiDeuteron/h2TofNsigmaantiDeuteronVsPt_jet"), trk.tofNSigmaDe(), trk.pt()); jetHist.fill(HIST("tracks/antiDeuteron/h3TpcNsigmaTofNsigmaantiDeuteronVsPt_jet"), trk.tpcNSigmaDe(), trk.tofNSigmaDe(), trk.pt()); } - if (trk.tpcNSigmaTr() < useTPCpreSel) { + if (std::abs(trk.tpcNSigmaTr()) < cfgnTPCPIDTr) { jetHist.fill(HIST("tracks/antiTriton/h2TOFmassantiTritonVsPt_jet"), massTOF, trk.pt()); jetHist.fill(HIST("tracks/antiTriton/h2TOFmass2antiTritonVsPt_jet"), massTOF * massTOF - gMassTriton * gMassTriton, trk.pt()); jetHist.fill(HIST("tracks/antiTriton/h2TofNsigmaantiTritonVsPt_jet"), trk.tofNSigmaTr(), trk.pt()); } - if (trk.tpcNSigmaHe() < useTPCpreSel) { + if (std::abs(trk.tpcNSigmaHe()) < cfgnTPCPIDHe) { jetHist.fill(HIST("tracks/antiHelium/h2TOFmassantiHeliumVsPt_jet"), massTOF, trk.pt()); jetHist.fill(HIST("tracks/antiHelium/h2TOFmass2antiHeliumVsPt_jet"), massTOF * massTOF - gMassHelium * gMassHelium, trk.pt()); jetHist.fill(HIST("tracks/antiHelium/h2TofNsigmaantiHeliumVsPt_jet"), trk.tofNSigmaHe(), trk.pt()); @@ -864,10 +863,10 @@ struct nucleiInJets { jetHist.fill(HIST("tracks/antiPion/h2TofNsigmaantiPionVsPt_jet"), trk.tofNSigmaPi(), trk.pt()); jetHist.fill(HIST("tracks/antiKaon/h2TofNsigmaantiKaonVsPt_jet"), trk.tofNSigmaKa(), trk.pt()); } else { - if (trk.tpcNSigmaPi() < useTPCpreSel) { + if (std::abs(trk.tpcNSigmaPi()) < useTPCpreSel) { jetHist.fill(HIST("tracks/antiPion/h2TofNsigmaantiPionVsPt_jet"), trk.tofNSigmaPi(), trk.pt()); } - if (trk.tpcNSigmaKa() < useTPCpreSel) { + if (std::abs(trk.tpcNSigmaKa()) < useTPCpreSel) { jetHist.fill(HIST("tracks/antiKaon/h2TofNsigmaantiKaonVsPt_jet"), trk.tofNSigmaKa(), trk.pt()); } } @@ -917,7 +916,7 @@ struct nucleiInJets { jetHist.fill(HIST("tracks/deuteron/dca/after/hDCAxyVsPtDeuteron"), trk.dcaXY(), trk.pt()); jetHist.fill(HIST("tracks/deuteron/dca/after/hDCAzVsPtDeuteron"), trk.dcaZ(), trk.pt()); } - if (cEnableTritonQA && std::abs(trk.tpcNSigmaHe()) < cfgnTPCPIDTr) { + if (cEnableTritonQA && std::abs(trk.tpcNSigmaTr()) < cfgnTPCPIDTr) { jetHist.fill(HIST("tracks/triton/dca/after/hDCAxyVsPtTriton"), trk.dcaXY(), trk.pt()); jetHist.fill(HIST("tracks/triton/dca/after/hDCAzVsPtTriton"), trk.dcaZ(), trk.pt()); } @@ -943,28 +942,28 @@ struct nucleiInJets { jetHist.fill(HIST("tracks/helium/h2TOFmass2HeliumVsPt"), massTOF * massTOF - gMassHelium * gMassHelium, trk.pt()); jetHist.fill(HIST("tracks/triton/h2TofNsigmaTritonVsPt"), trk.tofNSigmaTr(), trk.pt()); } else { - if (trk.tpcNSigmaPr() < useTPCpreSel) { + if (std::abs(trk.tpcNSigmaPr()) < cfgnTPCPIDPr) { jetHist.fill(HIST("tracks/proton/h2TOFmassProtonVsPt"), massTOF, trk.pt()); jetHist.fill(HIST("tracks/proton/h2TOFmass2ProtonVsPt"), massTOF * massTOF - gMassProton * gMassProton, trk.pt()); jetHist.fill(HIST("tracks/proton/h2TofNsigmaProtonVsPt"), trk.tofNSigmaPr(), trk.pt()); if (jetFlagPerpCone && isWithLeadingJet) jetHist.fill(HIST("tracks/perpCone/proton/h2TofNsigmaProtonVsPt"), trk.tofNSigmaPr(), trk.pt()); } - if (trk.tpcNSigmaDe() < useTPCpreSel) { + if (std::abs(trk.tpcNSigmaDe()) < cfgnTPCPIDDe) { jetHist.fill(HIST("tracks/deuteron/h2TOFmassDeuteronVsPt"), massTOF, trk.pt()); jetHist.fill(HIST("tracks/deuteron/h2TOFmass2DeuteronVsPt"), massTOF * massTOF - gMassDeuteron * gMassDeuteron, trk.pt()); jetHist.fill(HIST("tracks/deuteron/h2TofNsigmaDeuteronVsPt"), trk.tofNSigmaDe(), trk.pt()); if (jetFlagPerpCone && isWithLeadingJet) jetHist.fill(HIST("tracks/perpCone/deuteron/h2TofNsigmaDeuteronVsPt"), trk.tofNSigmaDe(), trk.pt()); } - if (trk.tpcNSigmaTr() < useTPCpreSel) { + if (std::abs(trk.tpcNSigmaTr()) < cfgnTPCPIDTr) { jetHist.fill(HIST("tracks/triton/h2TOFmassTritonVsPt"), massTOF, trk.pt()); jetHist.fill(HIST("tracks/triton/h2TOFmass2TritonVsPt"), massTOF * massTOF - gMassTriton * gMassTriton, trk.pt()); jetHist.fill(HIST("tracks/triton/h2TofNsigmaTritonVsPt"), trk.tofNSigmaTr(), trk.pt()); if (jetFlagPerpCone && isWithLeadingJet) jetHist.fill(HIST("tracks/perpCone/triton/h2TofNsigmaTritonVsPt"), trk.tofNSigmaTr(), trk.pt()); } - if (trk.tpcNSigmaHe() < useTPCpreSel) { + if (std::abs(trk.tpcNSigmaHe()) < cfgnTPCPIDHe) { jetHist.fill(HIST("tracks/helium/h2TOFmassHeliumVsPt"), massTOF, trk.pt()); jetHist.fill(HIST("tracks/helium/h2TOFmass2HeliumVsPt"), massTOF * massTOF - gMassHelium * gMassHelium, trk.pt()); jetHist.fill(HIST("tracks/helium/h2TofNsigmaHeliumVsPt"), trk.tofNSigmaHe(), trk.pt()); @@ -978,7 +977,6 @@ struct nucleiInJets { jetHist.fill(HIST("tracks/antiDeuteron/h3PtVsantiDeuteronNSigmaTPC"), trk.pt(), trk.tpcNSigmaDe()); // De jetHist.fill(HIST("tracks/antiHelium/h3PtVsantiHeliumNSigmaTPC"), trk.pt(), trk.tpcNSigmaHe()); // He jetHist.fill(HIST("tracks/antiTriton/h3PtVsantiTritonNSigmaTPC"), trk.pt(), trk.tpcNSigmaTr()); // Tr - // perpCone if (jetFlagPerpCone && isWithLeadingJet) { // antiparticle info @@ -1033,28 +1031,28 @@ struct nucleiInJets { jetHist.fill(HIST("tracks/antiHelium/h2TOFmass2antiHeliumVsPt"), massTOF * massTOF - gMassHelium * gMassHelium, trk.pt()); jetHist.fill(HIST("tracks/antiTriton/h2TofNsigmaantiTritonVsPt"), trk.tofNSigmaTr(), trk.pt()); } else { - if (trk.tpcNSigmaPr() < useTPCpreSel) { + if (std::abs(trk.tpcNSigmaPr()) < cfgnTPCPIDPr) { jetHist.fill(HIST("tracks/antiProton/h2TOFmassantiProtonVsPt"), massTOF, trk.pt()); jetHist.fill(HIST("tracks/antiProton/h2TOFmass2antiProtonVsPt"), massTOF * massTOF - gMassProton * gMassProton, trk.pt()); jetHist.fill(HIST("tracks/antiProton/h2TofNsigmaantiProtonVsPt"), trk.tofNSigmaPr(), trk.pt()); if (jetFlagPerpCone && isWithLeadingJet) jetHist.fill(HIST("tracks/perpCone/antiProton/h2TofNsigmaantiProtonVsPt"), trk.tofNSigmaPr(), trk.pt()); } - if (trk.tpcNSigmaDe() < useTPCpreSel) { + if (std::abs(trk.tpcNSigmaDe()) < cfgnTPCPIDDe) { jetHist.fill(HIST("tracks/antiDeuteron/h2TOFmassantiDeuteronVsPt"), massTOF, trk.pt()); jetHist.fill(HIST("tracks/antiDeuteron/h2TOFmass2antiDeuteronVsPt"), massTOF * massTOF - gMassDeuteron * gMassDeuteron, trk.pt()); jetHist.fill(HIST("tracks/antiDeuteron/h2TofNsigmaantiDeuteronVsPt"), trk.tofNSigmaDe(), trk.pt()); if (jetFlagPerpCone && isWithLeadingJet) jetHist.fill(HIST("tracks/perpCone/antiDeuteron/h2TofNsigmaantiDeuteronVsPt"), trk.tofNSigmaDe(), trk.pt()); } - if (trk.tpcNSigmaTr() < useTPCpreSel) { + if (std::abs(trk.tpcNSigmaTr()) < cfgnTPCPIDTr) { jetHist.fill(HIST("tracks/antiTriton/h2TOFmassantiTritonVsPt"), massTOF, trk.pt()); jetHist.fill(HIST("tracks/antiTriton/h2TOFmass2antiTritonVsPt"), massTOF * massTOF - gMassTriton * gMassTriton, trk.pt()); jetHist.fill(HIST("tracks/antiTriton/h2TofNsigmaantiTritonVsPt"), trk.tofNSigmaTr(), trk.pt()); if (jetFlagPerpCone && isWithLeadingJet) jetHist.fill(HIST("tracks/perpCone/antiTriton/h2TofNsigmaantiTritonVsPt"), trk.tofNSigmaTr(), trk.pt()); } - if (trk.tpcNSigmaHe() < useTPCpreSel) { + if (std::abs(trk.tpcNSigmaHe()) < cfgnTPCPIDHe) { jetHist.fill(HIST("tracks/antiHelium/h2TOFmassantiHeliumVsPt"), massTOF, trk.pt()); jetHist.fill(HIST("tracks/antiHelium/h2TOFmass2antiHeliumVsPt"), massTOF * massTOF - gMassHelium * gMassHelium, trk.pt()); jetHist.fill(HIST("tracks/antiHelium/h2TofNsigmaantiHeliumVsPt"), trk.tofNSigmaHe(), trk.pt()); @@ -1082,7 +1080,7 @@ struct nucleiInJets { } jetHist.fill(HIST("hNEvents"), 1.5); } - if (fabs(collision.posZ()) > 10) + if (std::abs(collision.posZ()) > 10) return; jetHist.fill(HIST("hNEvents"), 2.5); if (!jetderiveddatautilities::selectCollision(collision, jetderiveddatautilities::initialiseEventSelectionBits("sel8"))) @@ -1133,7 +1131,7 @@ struct nucleiInJets { } jetHist.fill(HIST("hNEvents"), 1.5); } - if (fabs(collision.posZ()) > 10) + if (std::abs(collision.posZ()) > 10) return; jetHist.fill(HIST("hNEvents"), 2.5); if (!jetderiveddatautilities::selectCollision(collision, jetderiveddatautilities::initialiseEventSelectionBits("sel8"))) @@ -1175,7 +1173,7 @@ struct nucleiInJets { jetHist.fill(HIST("mcpJet/eventStat"), 0.5); jetHist.fill(HIST("mcpJet/eventStat"), 1.5); - if (fabs(collision.posZ()) > 10) // bad vertex + if (std::abs(collision.posZ()) > 10) // bad vertex return; jetHist.fill(HIST("mcpJet/eventStat"), 2.5); @@ -1184,7 +1182,7 @@ struct nucleiInJets { bool INELgt0 = false; for (const auto& mcParticle : mcParticles) { - if (fabs(mcParticle.eta()) < cfgtrkMaxEta) { + if (std::fabs(mcParticle.eta()) < cfgtrkMaxEta) { INELgt0 = true; break; } @@ -1205,9 +1203,9 @@ struct nucleiInJets { for (const auto& mcParticle : mcParticles) { if (!mcParticle.isPhysicalPrimary()) continue; - if (fabs(mcParticle.eta()) > cfgtrkMaxEta) + if (std::fabs(mcParticle.eta()) > cfgtrkMaxEta) continue; - if (fabs(mcParticle.y()) > cfgtrkMaxRap) + if (std::fabs(mcParticle.y()) > cfgtrkMaxRap) continue; bool jetFlag = false; @@ -1236,13 +1234,13 @@ struct nucleiInJets { // bool jetFlag = kFALSE; jetHist.fill(HIST("mcdJet/eventStat"), 1.5); - if (fabs(collisionJet.posZ()) > 10) + if (std::abs(collisionJet.posZ()) > 10) return; jetHist.fill(HIST("mcdJet/eventStat"), 2.5); bool INELgt0 = false; for (const auto& track : tracks) { - if (fabs(track.eta()) < cfgtrkMaxEta) { + if (std::fabs(track.eta()) < cfgtrkMaxEta) { INELgt0 = true; break; } @@ -1275,7 +1273,7 @@ struct nucleiInJets { if (!track.has_mcParticle()) continue; auto mcTrack = track.mcParticle_as(); - if (fabs(mcTrack.eta()) > cfgtrkMaxEta) + if (std::fabs(mcTrack.eta()) > cfgtrkMaxEta) continue; if (!mcTrack.isPhysicalPrimary()) continue; @@ -1319,7 +1317,7 @@ struct nucleiInJets { soa::Join const& tracks, JetMCPartTable const&, TrackCandidatesMC const&, aod::JetParticles const& particleTracks, aod::JMcCollisions const&) { - if (fabs(collision.posZ()) > 10) + if (std::abs(collision.posZ()) > 10) return; if (!jetderiveddatautilities::selectCollision(collision, jetderiveddatautilities::initialiseEventSelectionBits("sel8"))) return; @@ -1327,7 +1325,7 @@ struct nucleiInJets { jetHist.fill(HIST("recmatched/vertexZ"), collision.posZ()); bool INELgt0 = false; for (const auto& track : tracks) { - if (fabs(track.eta()) < cfgtrkMaxEta) { + if (std::fabs(track.eta()) < cfgtrkMaxEta) { INELgt0 = true; break; } @@ -1403,7 +1401,7 @@ struct nucleiInJets { for (const auto& track : tracks) { auto completeTrack = track.track_as(); - if (fabs(completeTrack.eta()) > cfgtrkMaxEta) + if (std::fabs(completeTrack.eta()) > cfgtrkMaxEta) continue; if (!isTrackSelected(completeTrack)) continue; @@ -1412,7 +1410,7 @@ struct nucleiInJets { auto mcTrack = track.mcParticle_as(); if (!mcTrack.isPhysicalPrimary()) continue; - if (fabs(mcTrack.y()) > cfgtrkMaxRap) + if (std::fabs(mcTrack.y()) > cfgtrkMaxRap) continue; bool isTpcPassed(true); @@ -1487,9 +1485,9 @@ struct nucleiInJets { for (const auto& mcParticle : mcParticles_per_coll) { if (!mcParticle.isPhysicalPrimary()) continue; - if (fabs(mcParticle.eta()) > cfgtrkMaxEta) + if (std::fabs(mcParticle.eta()) > cfgtrkMaxEta) continue; - if (fabs(mcParticle.y()) > cfgtrkMaxRap) + if (std::fabs(mcParticle.y()) > cfgtrkMaxRap) continue; bool jetFlagMC = false; bool jetFlagPerpConeMC = false; @@ -1546,7 +1544,7 @@ struct nucleiInJets { if (!jetderiveddatautilities::selectCollision(recocoll, jetderiveddatautilities::initialiseEventSelectionBits("sel8"))) return; } - if (fabs(collision.posZ()) > 10) + if (std::abs(collision.posZ()) > 10) return; jetHist.fill(HIST("genmatched/vertexZ"), collision.posZ()); std::vector mcdJetPt{}; @@ -1612,7 +1610,7 @@ struct nucleiInJets { } // leading jet only for (const auto& mcParticle : mcParticles) { - if (fabs(mcParticle.eta()) > cfgtrkMaxEta) + if (std::fabs(mcParticle.eta()) > cfgtrkMaxEta) continue; // add pid later diff --git a/PWGJE/Tasks/phiInJets.cxx b/PWGJE/Tasks/phiInJets.cxx index be99a57a576..b4e6f5c1c49 100644 --- a/PWGJE/Tasks/phiInJets.cxx +++ b/PWGJE/Tasks/phiInJets.cxx @@ -84,13 +84,17 @@ struct phiInJets { Configurable cfgMCRecMBHists{"cfgMCRecMBHists", false, "Enables MCRec MB Hists"}; Configurable cfgMCRecInsideHists{"cfgMCRecInsideHists", false, "Enables MCRec Inside Hists"}; Configurable cfgMCRecRotationalHists{"cfgMCRecRotationalHists", false, "Enables MCRotational Hists"}; + Configurable cfgPIDQAHists{"cfgPIDQAHists", false, "Enables PIDQA Hists"}; + Configurable cfgDaughterQAHists{"cfgDaughterQAHists", false, "Enables DaughterQA Hists"}; + Configurable cfgJetQAHists{"cfgJetQAHists", false, "Enables JetQA Hists"}; + Configurable cfgMCGenHists{"cfgMCGenHists", false, "Enables MCGenHists"}; Configurable cfgMCGenMATCHEDHists{"cfgMCGenMATCHEDHists", false, "Enables MCGenMATCHEDHists"}; Configurable cfgMCRecMATCHEDHists{"cfgMCRecMATCHEDHists", false, "Enables MCRecMATCHEDHists"}; - Configurable cfgMinvNBins{"cfgMinvNBins", 500, "Number of bins for Minv axis"}; - Configurable cfgMinvMin{"cfgMinvMin", 0.75, "Minimum Minv value"}; - Configurable cfgMinvMax{"cfgMinvMax", 1.25, "Maximum Minv value"}; + Configurable cfgMinvNBins{"cfgMinvNBins", 300, "Number of bins for Minv axis"}; + Configurable cfgMinvMin{"cfgMinvMin", 0.60, "Minimum Minv value"}; + Configurable cfgMinvMax{"cfgMinvMax", 1.20, "Maximum Minv value"}; // CONFIG DONE ///////////////////////////////////////// //INIT @@ -152,54 +156,54 @@ struct phiInJets { if (cfgMCRecHists) { JEhistos.add("nEvents_MCRec", "nEvents_MCRec", kTH1F, {{4, 0.0, 4.0}}); - - JEhistos.add("h_jet_pt", "jet pT;#it{p}_{T,jet} (GeV/#it{c});entries", {HistType::kTH1F, {{4000, 0., 200.}}}); - JEhistos.add("h_jet_eta", "jet #eta;#eta_{jet};entries", {HistType::kTH1F, {{100, -1.0, 1.0}}}); - JEhistos.add("h_jet_phi", "jet #phi;#phi_{jet};entries", {HistType::kTH1F, {{80, -1.0, 7.}}}); - - JEhistos.add("ptJEHistogramPion", "ptJEHistogramPion", kTH1F, {PtAxis}); - JEhistos.add("ptJEHistogramKaon", "ptJEHistogramKaon", kTH1F, {PtAxis}); - JEhistos.add("ptJEHistogramProton", "ptJEHistogramProton", kTH1F, {PtAxis}); - JEhistos.add("ptJEHistogramPhi", "ptJEHistogramPhi", kTH1F, {PtAxis}); - JEhistos.add("ptJEHistogramPhi_JetTrigger", "ptJEHistogramPhi_JetTrigger", kTH1F, {PtAxis}); - JEhistos.add("minvJEHistogramPhi", "minvJEHistogramPhi", kTH1F, {MinvAxis}); - JEhistos.add("hNRealPhiVPhiCand", "hNRealPhiVPhiCand", kTH2F, {{10, 0, 10}, {10, 0, 10}}); - JEhistos.add("hNRealPhiWithJetVPhiCand", "hNRealPhiWithJetVPhiCand", kTH2F, {{10, 0, 10}, {10, 0, 10}}); - JEhistos.add("hNRealPhiInJetVPhiCand", "hNRealPhiInJetVPhiCand", kTH2F, {{10, 0, 10}, {10, 0, 10}}); - - JEhistos.add("hMCRec_nonmatch_hUSS_KtoKangle_v_pt", "hMCRec_nonmatch_hUSS_KtoKangle_v_pt", kTH2F, {axisEta, PtAxis}); - JEhistos.add("hMCRec_nonmatch_hUSS_Kangle_v_pt", "hMCRec_nonmatch_hUSS_Kangle_v_pt", kTH2F, {axisEta, PtAxis}); - JEhistos.add("hMCRec_nonmatch_hUSS_INSIDE_pt_v_eta", "hMCRec_nonmatch_hUSS_INSIDE_pt_v_eta", kTH2F, {PtAxis, axisEta}); - JEhistos.add("JetVsPhi_REC", "JetVsPhi_REC", kTH2F, {{4000, 0., 200.}, {200, 0, 20.0}}); - + if (cfgJetQAHists) { + JEhistos.add("h_jet_pt", "jet pT;#it{p}_{T,jet} (GeV/#it{c});entries", {HistType::kTH1F, {{4000, 0., 200.}}}); + JEhistos.add("h_jet_eta", "jet #eta;#eta_{jet};entries", {HistType::kTH1F, {{100, -1.0, 1.0}}}); + JEhistos.add("h_jet_phi", "jet #phi;#phi_{jet};entries", {HistType::kTH1F, {{80, -1.0, 7.}}}); + } + if (cfgPIDQAHists) { + JEhistos.add("ptJEHistogramPion", "ptJEHistogramPion", kTH1F, {PtAxis}); + JEhistos.add("ptJEHistogramKaon", "ptJEHistogramKaon", kTH1F, {PtAxis}); + JEhistos.add("ptJEHistogramProton", "ptJEHistogramProton", kTH1F, {PtAxis}); + JEhistos.add("ptJEHistogramPhi", "ptJEHistogramPhi", kTH1F, {PtAxis}); + JEhistos.add("ptJEHistogramPhi_JetTrigger", "ptJEHistogramPhi_JetTrigger", kTH1F, {PtAxis}); + } + if (cfgDaughterQAHists) { + JEhistos.add("hNRealPhiVPhiCand", "hNRealPhiVPhiCand", kTH2F, {{10, 0, 10}, {10, 0, 10}}); + JEhistos.add("hNRealPhiWithJetVPhiCand", "hNRealPhiWithJetVPhiCand", kTH2F, {{10, 0, 10}, {10, 0, 10}}); + JEhistos.add("hNRealPhiInJetVPhiCand", "hNRealPhiInJetVPhiCand", kTH2F, {{10, 0, 10}, {10, 0, 10}}); + JEhistos.add("hMCRec_nonmatch_hUSS_KtoKangle_v_pt", "hMCRec_nonmatch_hUSS_KtoKangle_v_pt", kTH2F, {axisEta, PtAxis}); + JEhistos.add("hMCRec_nonmatch_hUSS_Kangle_v_pt", "hMCRec_nonmatch_hUSS_Kangle_v_pt", kTH2F, {axisEta, PtAxis}); + JEhistos.add("hMCRec_nonmatch_hUSS_INSIDE_pt_v_eta", "hMCRec_nonmatch_hUSS_INSIDE_pt_v_eta", kTH2F, {PtAxis, axisEta}); + } // used for Minv closure tests // MB if (cfgMCRecMBHists) { JEhistos.add("hMCRec_hUSS", "hMCRec_hUSS", kTHnSparseF, {dRAxis, PtAxis, MinvAxis}); JEhistos.add("hMCRec_hLSS", "hMCRec_hLSS", kTHnSparseF, {dRAxis, PtAxis, MinvAxis}); JEhistos.add("hMCRecTrue_hUSS", "hMCRecTrue_hUSS", kTHnSparseF, {dRAxis, PtAxis, MinvAxis}); - JEhistos.add("hMCRecTrue_hLSS", "hMCRecTrue_hLSS", kTHnSparseF, {dRAxis, PtAxis, MinvAxis}); + } + + if (cfgMCRecRotationalHists) { JEhistos.add("hMCRec_R_distribution", "hMCRec_R_distribution", kTH1F, {{100, 0.0, 2 * TMath::Pi()}}); JEhistos.add("hMCRec_dPhi_distribution", "hMCRec_dPhi_distribution", kTH1F, {{80, -5.0, 7.0}}); JEhistos.add("hMCRec_dEta_distribution", "hMCRec_dEta_distribution", kTH1F, {{100, -2.0, 2.0}}); - } - if (cfgMCRecRotationalHists) { JEhistos.add("hMCRec_hUSS_Rotational", "hMCRec_hUSS_Rotational", kTHnSparseF, {dRAxis, PtAxis, MinvAxis}); JEhistos.add("hMCRec_R_Rotation_distribution", "hMCRec_R_Rotation_distribution", HistType::kTH1F, {{100, 0.0, 2 * TMath::Pi()}}); JEhistos.add("hMCRec_dPhi_rot_distribution", "hMCRec_dPhi_rot_distribution", kTH1F, {{80, -5.0, 7.0}}); JEhistos.add("hMCRec_dEta_rot_distribution", "hMCRec_dEta_rot_distribution", kTH1F, {{100, -2.0, 2.0}}); JEhistos.add("hMCRec_dEta_qa_rot_distribution", "hMCRec_dEta_qa_rot_distribution", kTH1F, {{100, -4.0, 2.0}}); } - } - // INSIDE - if (cfgMCRecInsideHists) { - JEhistos.add("hMCRec_hUSS_INSIDE", "hMCRec_hUSS_INSIDE", kTHnSparseF, {dRAxis, PtAxis, MinvAxis}); - JEhistos.add("hMCRec_hLSS_INSIDE", "hMCRec_hLSS_INSIDE", kTHnSparseF, {dRAxis, PtAxis, MinvAxis}); - JEhistos.add("hMCRecTrue_hUSS_INSIDE", "hMCRecTrue_hUSS_INSIDE", kTHnSparseF, {dRAxis, PtAxis, MinvAxis}); - JEhistos.add("hMCRecTrue_hLSS_INSIDE", "hMCRecTrue_hLSS_INSIDE", kTHnSparseF, {dRAxis, PtAxis, MinvAxis}); - JEhistos.add("hMCRec_nonmatch_hUSS_INSIDE", "hMCRec_nonmatch_hUSS_INSIDE", kTHnSparseF, {dRAxis, PtAxis, MinvAxis}); - JEhistos.add("hMCRec_nonmatch_hUSS_INSIDE_1D", "hMCRec_nonmatch_hUSS_INSIDE_1D", kTH1F, {MinvAxis}); - JEhistos.add("hMCRec_nonmatch_hUSS_INSIDE_1D_2_3", "hMCRec_nonmatch_hUSS_INSIDE_1D_2_3", kTH1F, {MinvAxis}); + + // INSIDE + if (cfgMCRecInsideHists) { + JEhistos.add("hMCRec_hUSS_INSIDE", "hMCRec_hUSS_INSIDE", kTHnSparseF, {dRAxis, PtAxis, MinvAxis}); + JEhistos.add("hMCRec_hLSS_INSIDE", "hMCRec_hLSS_INSIDE", kTHnSparseF, {dRAxis, PtAxis, MinvAxis}); + JEhistos.add("hMCRecTrue_hUSS_INSIDE", "hMCRecTrue_hUSS_INSIDE", kTHnSparseF, {dRAxis, PtAxis, MinvAxis}); + JEhistos.add("hMCRec_nonmatch_hUSS_INSIDE", "hMCRec_nonmatch_hUSS_INSIDE", kTHnSparseF, {dRAxis, PtAxis, MinvAxis}); + JEhistos.add("JetVsPhi_REC", "JetVsPhi_REC", kTH2F, {{4000, 0., 200.}, {200, 0, 20.0}}); + JEhistos.add("minvJEHistogramPhi", "minvJEHistogramPhi", kTH1F, {MinvAxis}); + } } if (cfgMCGenHists) { @@ -554,7 +558,7 @@ struct phiInJets { } JEhistos.fill(HIST("nEvents"), 0.5); - if (fabs(collision.posZ()) > cfgVtxCut) + if (std::fabs(collision.posZ()) > cfgVtxCut) return; if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits)) return; @@ -640,14 +644,14 @@ struct phiInJets { // # of Events //================= JEhistos.fill(HIST("nEvents_MCRec"), 0.5); - if (fabs(collision.posZ()) > cfgVtxCut) + if (std::fabs(collision.posZ()) > cfgVtxCut) return; if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits)) return; bool INELgt0 = false; for (const auto& track : tracks) { - if (fabs(track.eta()) < cfgtrkMaxEta) { + if (std::fabs(track.eta()) < cfgtrkMaxEta) { INELgt0 = true; break; } @@ -667,9 +671,11 @@ struct phiInJets { mcd_pt.push_back(mcdjet.pt()); mcd_eta.push_back(mcdjet.eta()); mcd_phi.push_back(mcdjet.phi()); - JEhistos.fill(HIST("h_jet_pt"), mcdjet.pt()); - JEhistos.fill(HIST("h_jet_eta"), mcdjet.eta()); - JEhistos.fill(HIST("h_jet_phi"), mcdjet.phi()); + if (cfgJetQAHists) { + JEhistos.fill(HIST("h_jet_pt"), mcdjet.pt()); + JEhistos.fill(HIST("h_jet_eta"), mcdjet.eta()); + JEhistos.fill(HIST("h_jet_phi"), mcdjet.phi()); + } } if (hasJets) JEhistos.fill(HIST("nEvents_MCRec"), 2.5); @@ -690,14 +696,15 @@ struct phiInJets { if (track.has_mcParticle()) { auto mcParticle = track.mcParticle(); - - if (mcParticle.isPhysicalPrimary() && fabs(mcParticle.eta()) <= cfgtrkMaxEta) { - if (abs(mcParticle.pdgCode()) == 211) - JEhistos.fill(HIST("ptJEHistogramPion"), mcParticle.pt()); - if (abs(mcParticle.pdgCode()) == 321) - JEhistos.fill(HIST("ptJEHistogramKaon"), mcParticle.pt()); - if (abs(mcParticle.pdgCode()) == 2212) - JEhistos.fill(HIST("ptJEHistogramProton"), mcParticle.pt()); + if (cfgPIDQAHists) { + if (mcParticle.isPhysicalPrimary() && std::fabs(mcParticle.eta()) <= cfgtrkMaxEta) { + if (abs(mcParticle.pdgCode()) == 211) + JEhistos.fill(HIST("ptJEHistogramPion"), mcParticle.pt()); + if (abs(mcParticle.pdgCode()) == 321) + JEhistos.fill(HIST("ptJEHistogramKaon"), mcParticle.pt()); + if (abs(mcParticle.pdgCode()) == 2212) + JEhistos.fill(HIST("ptJEHistogramProton"), mcParticle.pt()); + } } } for (const auto& track2 : tracks) { @@ -714,20 +721,20 @@ struct phiInJets { if (originalTrack.globalIndex() == originalTrack2.globalIndex()) continue; } - if (fabs(originalTrack.eta()) > cfgtrkMaxEta || fabs(originalTrack2.eta()) > cfgtrkMaxEta) + if (std::fabs(originalTrack.eta()) > cfgtrkMaxEta || std::fabs(originalTrack2.eta()) > cfgtrkMaxEta) continue; double dPhi = TVector2::Phi_mpi_pi(originalTrack.phi() - originalTrack2.phi()); double dEta = originalTrack.eta() - originalTrack2.eta(); - JEhistos.fill(HIST("hMCRec_dPhi_distribution"), dPhi); - JEhistos.fill(HIST("hMCRec_dEta_distribution"), dEta); - + if (cfgMCRecRotationalHists) { + JEhistos.fill(HIST("hMCRec_dPhi_distribution"), dPhi); + JEhistos.fill(HIST("hMCRec_dEta_distribution"), dEta); + } double dR = TMath::Sqrt(dPhi * dPhi + dEta * dEta); double dR_rot = 0; TLorentzVector lDecayDaughter1, lDecayDaughter2, lResonance, lRotationalTrack, lRotationalResonance; lDecayDaughter1.SetXYZM(originalTrack.px(), originalTrack.py(), originalTrack.pz(), massKa); //----------------------------------------------------------------------- - TRandom* trand = new TRandom(); double shift = trand->Uniform(TMath::Pi() - TMath::Pi() / 10.0, TMath::Pi() + TMath::Pi() / 10.0); // double shift = TMath::Pi(); @@ -737,57 +744,41 @@ struct phiInJets { } else { lDecayDaughter2.SetXYZM(originalTrack2.px(), originalTrack2.py(), originalTrack2.pz(), massPi); - // double pTog = TMath::Sqrt(originalTrack2.px() * originalTrack2.px() + originalTrack2.py() * originalTrack2.py()); - // double Pxrot = pTog*TMath::Cos(originalTrack2.phi() + shift); - // double Pyrot = pTog*TMath::Sin(originalTrack2.phi() + shift); - - // if(gDebug){ - // double Ptrot = TMath::Sqrt(Pxrot*Pxrot + Pyrot*Pyrot); - // if(TMath::Abs(Ptrot-pTog)>0.1) { - // std::cout<<"We are jottettta"< cfgtrkMaxEta) + if (std::fabs(lResonance.Eta()) > cfgtrkMaxEta) continue; - if (lResonance.M() > 1.005 && lResonance.M() < 1.035) - PhiCand++; - + if (cfgDaughterQAHists) { + if (lResonance.M() > 1.005 && lResonance.M() < 1.035) + PhiCand++; + } //================== // 1.MB REC Closure //================== if (cfgMCRecMBHists) { if (originalTrack.sign() * originalTrack2.sign() < 0) { JEhistos.fill(HIST("hMCRec_hUSS"), 1.0, lResonance.Pt(), lResonance.M()); - // normal R - JEhistos.fill(HIST("hMCRec_R_distribution"), dR); - // switch because of memory if (cfgMCRecRotationalHists && cfgIsKstar) { + JEhistos.fill(HIST("hMCRec_R_distribution"), dR); JEhistos.fill(HIST("hMCRec_hUSS_Rotational"), 1.0, lRotationalResonance.Pt(), lResonance.M()); - // Rotational R JEhistos.fill(HIST("hMCRec_R_Rotation_distribution"), dR_rot); } } else if (originalTrack.sign() * originalTrack2.sign() > 0) { @@ -802,9 +793,11 @@ struct phiInJets { double jetpt = 0; for (std::size_t i = 0; i < mcd_pt.size(); i++) { - if (i == 0) { - if (lResonance.M() > 1.005 && lResonance.M() < 1.035) { - RealPhiCandWithJet++; + if (cfgDaughterQAHists) { + if (i == 0) { + if (lResonance.M() > 1.005 && lResonance.M() < 1.035) { + RealPhiCandWithJet++; + } } } double phidiff = TVector2::Phi_mpi_pi(mcd_phi[i] - lResonance.Phi()); @@ -818,7 +811,7 @@ struct phiInJets { double phidiff_K2 = TVector2::Phi_mpi_pi(mcd_phi[i] - lDecayDaughter2.Phi()); double etadiff_K2 = mcd_eta[i] - lDecayDaughter2.Eta(); double R_K2 = TMath::Sqrt((etadiff_K2 * etadiff_K2) + (phidiff_K2 * phidiff_K2)); - if (R < cfgjetR) { + if (cfgDaughterQAHists && R < cfgjetR) { JEhistos.fill(HIST("hMCRec_nonmatch_hUSS_Kangle_v_pt"), R_K1, lResonance.Pt()); JEhistos.fill(HIST("hMCRec_nonmatch_hUSS_Kangle_v_pt"), R_K2, lResonance.Pt()); } @@ -845,13 +838,13 @@ struct phiInJets { if (track.has_mcParticle() && track2.has_mcParticle()) { auto part1 = track.mcParticle(); auto part2 = track2.mcParticle(); - if (fabs(part1.pdgCode()) != 321) + if (std::fabs(part1.pdgCode()) != 321) continue; // Not Kaon if (!cfgIsKstar) { - if (fabs(part2.pdgCode()) != 321) + if (std::fabs(part2.pdgCode()) != 321) continue; // Not Kaon } else { - if (fabs(part2.pdgCode()) != 211) + if (std::fabs(part2.pdgCode()) != 211) continue; // Not Kaon } @@ -888,20 +881,22 @@ struct phiInJets { if (mothers1[0] != mothers2[0]) continue; // Kaons not from the same phi - double phidiff_Kaons = TVector2::Phi_mpi_pi(lDecayDaughter2.Phi() - lDecayDaughter1.Phi()); - double etadiff_Kaons = lDecayDaughter2.Eta() - lDecayDaughter1.Eta(); - double R_Kaons = TMath::Sqrt((etadiff_Kaons * etadiff_Kaons) + (phidiff_Kaons * phidiff_Kaons)); - JEhistos.fill(HIST("hMCRec_nonmatch_hUSS_KtoKangle_v_pt"), R_Kaons, lResonance.Pt()); - JEhistos.fill(HIST("ptJEHistogramPhi"), lResonance.Pt()); + if (cfgDaughterQAHists) { + double phidiff_Kaons = TVector2::Phi_mpi_pi(lDecayDaughter2.Phi() - lDecayDaughter1.Phi()); + double etadiff_Kaons = lDecayDaughter2.Eta() - lDecayDaughter1.Eta(); + double R_Kaons = TMath::Sqrt((etadiff_Kaons * etadiff_Kaons) + (phidiff_Kaons * phidiff_Kaons)); + JEhistos.fill(HIST("hMCRec_nonmatch_hUSS_KtoKangle_v_pt"), R_Kaons, lResonance.Pt()); + } + if (cfgPIDQAHists) { + JEhistos.fill(HIST("ptJEHistogramPhi"), lResonance.Pt()); + } //===================== // 4.MB True Closure //===================== if (cfgMCRecMBHists) { if (originalTrack.sign() * originalTrack2.sign() < 0) { JEhistos.fill(HIST("hMCRecTrue_hUSS"), 1.0, lResonance.Pt(), lResonance.M()); - } else if (originalTrack.sign() * originalTrack2.sign() > 0) { - JEhistos.fill(HIST("hMCRecTrue_hLSS"), 1.0, lResonance.Pt(), lResonance.M()); } } //=========================== @@ -911,14 +906,13 @@ struct phiInJets { if (jetFlag) { if (originalTrack.sign() * originalTrack2.sign() < 0) { JEhistos.fill(HIST("hMCRecTrue_hUSS_INSIDE"), 1.0, lResonance.Pt(), lResonance.M()); - } else if (originalTrack.sign() * originalTrack2.sign() > 0) { - JEhistos.fill(HIST("hMCRecTrue_hLSS_INSIDE"), 1.0, lResonance.Pt(), lResonance.M()); } } } - if (lResonance.M() > 1.005 && lResonance.M() < 1.035) - RealPhiCand++; - + if (cfgDaughterQAHists) { + if (lResonance.M() > 1.005 && lResonance.M() < 1.035) + RealPhiCand++; + } // Now we do jets if (cfgMCRecInsideHists) { if (cfgSingleJet) @@ -926,30 +920,40 @@ struct phiInJets { jetpt = DistinguishJetsMC(mcd_pt, mcd_phi, mcd_eta, lResonance); if (jetFlag) { - if (lResonance.M() > 1.005 && lResonance.M() < 1.035) - RealPhiCandInJet++; - JEhistos.fill(HIST("hMCRec_nonmatch_hUSS_INSIDE_pt_v_eta"), lResonance.Pt(), lResonance.Eta()); - JEhistos.fill(HIST("hMCRec_nonmatch_hUSS_INSIDE_1D"), lResonance.M()); - if (lResonance.Pt() > 2.0 && lResonance.Pt() < 3) - JEhistos.fill(HIST("hMCRec_nonmatch_hUSS_INSIDE_1D_2_3"), lResonance.M()); - JEhistos.fill(HIST("hMCRec_nonmatch_hUSS_INSIDE"), jetpt, lResonance.Pt(), lResonance.M()); + if (cfgDaughterQAHists) { + if (lResonance.M() > 1.005 && lResonance.M() < 1.035) + RealPhiCandInJet++; + } + if (cfgDaughterQAHists) { + JEhistos.fill(HIST("hMCRec_nonmatch_hUSS_INSIDE_pt_v_eta"), lResonance.Pt(), lResonance.Eta()); + // if (lResonance.Pt() > 2.0 && lResonance.Pt() < 3) + // JEhistos.fill(HIST("hMCRec_nonmatch_hUSS_INSIDE_1D_2_3"), lResonance.M()); + JEhistos.fill(HIST("hMCRec_nonmatch_hUSS_INSIDE"), jetpt, lResonance.Pt(), lResonance.M()); + } } if (hasJets) { - JEhistos.fill(HIST("ptJEHistogramPhi_JetTrigger"), lResonance.Pt()); + if (cfgPIDQAHists) + JEhistos.fill(HIST("ptJEHistogramPhi_JetTrigger"), lResonance.Pt()); + auto triggerjet = std::min_element(mcd_pt.begin(), mcd_pt.end()); double triggerjet_pt = *triggerjet; - JEhistos.fill(HIST("JetVsPhi_REC"), triggerjet_pt, lResonance.Pt()); + if (!cfgIsKstar) { + JEhistos.fill(HIST("JetVsPhi_REC"), triggerjet_pt, lResonance.Pt()); + } + } + if (cfgDaughterQAHists) { + JEhistos.fill(HIST("minvJEHistogramPhi"), lResonance.M()); } - JEhistos.fill(HIST("minvJEHistogramPhi"), lResonance.M()); } } // mcpart check } // tracks2 } // tracks1 - JEhistos.fill(HIST("hNRealPhiVPhiCand"), PhiCand, RealPhiCand); - JEhistos.fill(HIST("hNRealPhiWithJetVPhiCand"), PhiCand, RealPhiCandWithJet); - JEhistos.fill(HIST("hNRealPhiInJetVPhiCand"), PhiCand, RealPhiCandInJet); - + if (cfgDaughterQAHists) { + JEhistos.fill(HIST("hNRealPhiVPhiCand"), PhiCand, RealPhiCand); + JEhistos.fill(HIST("hNRealPhiWithJetVPhiCand"), PhiCand, RealPhiCandWithJet); + JEhistos.fill(HIST("hNRealPhiInJetVPhiCand"), PhiCand, RealPhiCandInJet); + } // Jet Eff } PROCESS_SWITCH(phiInJets, processRec, "pikp detector level MC JE", true); @@ -979,11 +983,11 @@ struct phiInJets { return; } - if (fabs(collision.posZ()) > cfgVtxCut) // bad vertex + if (std::fabs(collision.posZ()) > cfgVtxCut) // bad vertex return; bool INELgt0 = false; for (const auto& mcParticle : mcParticles) { - if (fabs(mcParticle.eta()) < cfgtrkMaxEta) { + if (std::fabs(mcParticle.eta()) < cfgtrkMaxEta) { INELgt0 = true; break; } @@ -1013,7 +1017,7 @@ struct phiInJets { // Check pikp and phi for (const auto& mcParticle : mcParticles) { - if (mcParticle.isPhysicalPrimary() && fabs(mcParticle.eta()) <= cfgtrkMaxEta) { // watch out for context!!! + if (mcParticle.isPhysicalPrimary() && std::fabs(mcParticle.eta()) <= cfgtrkMaxEta) { // watch out for context!!! if (abs(mcParticle.pdgCode()) == 211) JEhistos.fill(HIST("ptGeneratedPion"), mcParticle.pt()); if (abs(mcParticle.pdgCode()) == 321) @@ -1021,7 +1025,7 @@ struct phiInJets { if (abs(mcParticle.pdgCode()) == 2212) JEhistos.fill(HIST("ptGeneratedProton"), mcParticle.pt()); } - if (fabs(mcParticle.eta()) <= cfgtrkMaxEta) { // watch out for context!!! + if (std::fabs(mcParticle.eta()) <= cfgtrkMaxEta) { // watch out for context!!! TLorentzVector lResonance; lResonance.SetPxPyPzE(mcParticle.px(), mcParticle.py(), mcParticle.pz(), mcParticle.e()); @@ -1041,12 +1045,12 @@ struct phiInJets { if (!cfgIsKstar) { if (mcParticle.has_daughters()) for (auto& dgth : mcParticle.daughters_as()) - if (fabs(dgth.pdgCode()) != 321) + if (std::fabs(dgth.pdgCode()) != 321) skip = true; } else { if (mcParticle.has_daughters()) for (auto& dgth : mcParticle.daughters_as()) - if (fabs(dgth.pdgCode()) != 321 || fabs(dgth.pdgCode()) != 211) + if (std::fabs(dgth.pdgCode()) != 321 || std::fabs(dgth.pdgCode()) != 211) skip = true; } @@ -1135,7 +1139,7 @@ struct phiInJets { JEhistos.fill(HIST("nEvents_MCGen_MATCHED"), 0.5); - if (fabs(collision.posZ()) > cfgVtxCut) + if (std::fabs(collision.posZ()) > cfgVtxCut) return; if (recocolls.size() <= 0) // not reconstructed @@ -1192,7 +1196,7 @@ struct phiInJets { // First we do GEN part for (const auto& mcParticle : mcParticles) { - if (fabs(mcParticle.eta()) > cfgtrkMaxEta) + if (std::fabs(mcParticle.eta()) > cfgtrkMaxEta) continue; int GenPID = 0; @@ -1202,7 +1206,7 @@ struct phiInJets { else GenPID = 313; - if (fabs(mcParticle.pdgCode()) == GenPID) { + if (std::fabs(mcParticle.pdgCode()) == GenPID) { bool skip = false; double phi_dgth_px[2] = {0}; double phi_dgth_py[2] = {0}; @@ -1218,7 +1222,7 @@ struct phiInJets { if (!cfgIsKstar) { if (mcParticle.has_daughters()) { for (auto& dgth : mcParticle.daughters_as()) { - if (fabs(dgth.pdgCode()) != 321) { + if (std::fabs(dgth.pdgCode()) != 321) { skip = true; break; } @@ -1226,7 +1230,7 @@ struct phiInJets { auto trk = track.track_as(); if (!trackSelection(trk)) continue; - if (fabs(trk.eta()) > cfgtrkMaxEta) + if (std::fabs(trk.eta()) > cfgtrkMaxEta) continue; if (cfgSimPID) { if (!trackPID(trk, true)) @@ -1257,7 +1261,7 @@ struct phiInJets { } else { // check for kstar if (mcParticle.has_daughters()) for (auto& dgth : mcParticle.daughters_as()) - if (fabs(dgth.pdgCode()) != 321 || fabs(dgth.pdgCode()) != 211) + if (std::fabs(dgth.pdgCode()) != 321 || std::fabs(dgth.pdgCode()) != 211) skip = true; } @@ -1348,19 +1352,19 @@ struct phiInJets { if ((nprocessRecJEEvents + 1) % 10000 == 0) { double histmem = JEhistos.getSize(); std::cout << histmem << std::endl; - std::cout << "processMatched Rec Events: " << nprocessRecJEEvents << std::endl; + std::cout << "processMatchedRec: " << nprocessRecEvents << std::endl; } } JEhistos.fill(HIST("nEvents_MCRec_MATCHED"), 0.5); - if (fabs(collision.posZ()) > cfgVtxCut) + if (std::fabs(collision.posZ()) > cfgVtxCut) return; if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits)) return; bool INELgt0 = false; for (const auto& track : tracks) { - if (fabs(track.eta()) < cfgtrkMaxEta) { + if (std::fabs(track.eta()) < cfgtrkMaxEta) { INELgt0 = true; break; } @@ -1412,7 +1416,7 @@ struct phiInJets { if (trk1.globalIndex() == trk2.globalIndex()) continue; } - if (fabs(trk1.eta()) > cfgtrkMaxEta || fabs(trk2.eta()) > cfgtrkMaxEta) + if (std::fabs(trk1.eta()) > cfgtrkMaxEta || std::fabs(trk2.eta()) > cfgtrkMaxEta) continue; if ((trk1.sign() * trk2.sign()) > 0) continue; // Not K+K- @@ -1426,13 +1430,13 @@ struct phiInJets { if (track1.has_mcParticle() && track2.has_mcParticle()) { auto part1 = track1.mcParticle(); auto part2 = track2.mcParticle(); - if (fabs(part1.pdgCode()) != 321) + if (std::fabs(part1.pdgCode()) != 321) continue; // Not Kaon if (!cfgIsKstar) { - if (fabs(part2.pdgCode()) != 321) + if (std::fabs(part2.pdgCode()) != 321) continue; // Not Kaon } else { - if (fabs(part2.pdgCode()) != 211) + if (std::fabs(part2.pdgCode()) != 211) continue; // Not Kaon } if (!part1.has_mothers()) @@ -1479,7 +1483,7 @@ struct phiInJets { lDecayDaughter2.SetXYZM(trk2.px(), trk2.py(), trk2.pz(), massPi); lResonance = lDecayDaughter1 + lDecayDaughter2; - if (fabs(lResonance.Eta()) > cfgtrkMaxEta) + if (std::fabs(lResonance.Eta()) > cfgtrkMaxEta) continue; bool jetFlag = false; diff --git a/PWGJE/Tasks/recoilJets.cxx b/PWGJE/Tasks/recoilJets.cxx index ba1a2a08351..f39d1c9fe25 100644 --- a/PWGJE/Tasks/recoilJets.cxx +++ b/PWGJE/Tasks/recoilJets.cxx @@ -68,6 +68,7 @@ struct RecoilJets { Configurable trkSel{"trkSel", "globalTracks", "Set track selection"}; Configurable vertexZCut{"vertexZCut", 10., "Accepted z-vertex range"}; Configurable fracSig{"fracSig", 0.9, "Fraction of events to use for signal TT"}; + Configurable bGetMissJets{"bGetMissJets", false, "Flag to get miss histo for particle level jets"}; Configurable trkPtMin{"trkPtMin", 0.15, "Minimum pT of acceptanced tracks"}; Configurable trkPtMax{"trkPtMax", 100., "Maximum pT of acceptanced tracks"}; @@ -76,10 +77,12 @@ struct RecoilJets { Configurable jetR{"jetR", 0.4, "Jet cone radius"}; Configurable triggerMasks{"triggerMasks", "", "Relevant trigger masks: fTrackLowPt,fTrackHighPt"}; + Configurable skipMBGapEvents{"skipMBGapEvents", false, "flag to choose to reject min. bias gap events; jet-level rejection applied at the jet finder level, here rejection is applied for collision and track process functions"}; // List of configurable parameters for MC Configurable pTHatExponent{"pTHatExponent", 4.0, "Exponent of the event weight for the calculation of pTHat"}; Configurable pTHatMax{"pTHatMax", 999.0, "Maximum fraction of hard scattering for jet acceptance in MC"}; + Configurable pTHatMaxTrack{"pTHatMaxTrack", 999.0, "Maximum fraction of hard scattering for track acceptance in MC"}; // Parameters for recoil jet selection Configurable ptTTrefMin{"ptTTrefMin", 5., "Minimum pT of reference TT"}; @@ -134,8 +137,14 @@ struct RecoilJets { // List of raw and MC det. distributions if (doprocessData || doprocessMCDetLevel || doprocessMCDetLevelWeighted) { spectra.add("vertexZ", "Z vertex of collisions", kTH1F, {{60, -12., 12.}}); + spectra.add("hHasAssocMcCollision", "Has det. level coll. associat. MC coll.", kTH1F, {{2, 0.0, 2.}}); + spectra.get(HIST("hHasAssocMcCollision"))->GetXaxis()->SetBinLabel(1, "Yes"); + spectra.get(HIST("hHasAssocMcCollision"))->GetXaxis()->SetBinLabel(2, "No"); spectra.add("hTrackPtEtaPhi", "Charact. of tracks", kTH3F, {pT, pseudorap, phiAngle}); + + spectra.add("hTTSig_pT", "pT spectrum of all found TT_{Sig} cand.", kTH1F, {{40, 10., 50.}}); // needed to distinguish merged data from diff. wagons + spectra.add("hNtrig", "Total number of selected triggers per class", kTH1F, {{2, 0.0, 2.}}); spectra.get(HIST("hNtrig"))->GetXaxis()->SetBinLabel(1, "TT_{ref}"); spectra.get(HIST("hNtrig"))->GetXaxis()->SetBinLabel(2, "TT_{sig}"); @@ -161,6 +170,9 @@ struct RecoilJets { // List of MC particle level distributions if (doprocessMCPartLevel || doprocessMCPartLevelWeighted) { + spectra.add("vertexZMC", "Z vertex of jmccollision", kTH1F, {{60, -12., 12.}}); + spectra.add("ptHat", "Distribution of pT hat", kTH1F, {{500, 0.0, 100.}}); + spectra.add("hPartPtEtaPhi", "Charact. of particles", kTH3F, {pT, pseudorap, phiAngle}); spectra.add("hNtrig_Part", "Total number of selected triggers per class", kTH1F, {{2, 0.0, 2.}}); spectra.get(HIST("hNtrig_Part"))->GetXaxis()->SetBinLabel(1, "TT_{ref}"); @@ -187,26 +199,30 @@ struct RecoilJets { // Jet matching: part. vs. det. if (doprocessJetsMatched || doprocessJetsMatchedWeighted) { - spectra.add("hJetPt_PartLevel_vs_DetLevel", "Correlation jet pT at part. vs. det. levels", kTH2F, {{200, 0.0, 200.}, {200, 0.0, 200.}}); + spectra.add("hJetPt_DetLevel_vs_PartLevel", "Correlation jet pT at det. vs. part. levels", kTH2F, {{200, 0.0, 200.}, {200, 0.0, 200.}}); // spectra.add("hJetPt_Corr_PartLevel_vs_DetLevel", "Correlation jet pT at part. vs. det. levels", kTH2F, {jetPTcorr, jetPTcorr}); - spectra.add("hJetPt_PartLevel_vs_DetLevel_RecoilJets", "Correlation recoil jet pT at part. vs. det. levels", kTH2F, {{200, 0.0, 200.}, {200, 0.0, 200.}}); + spectra.add("hJetPt_DetLevel_vs_PartLevel_RecoilJets", "Correlation recoil jet pT at part. vs. det. levels", kTH2F, {{200, 0.0, 200.}, {200, 0.0, 200.}}); // spectra.add("hJetPt_Corr_PartLevel_vs_DetLevel_RecoilJets", "Correlation recoil jet pT at part. vs. det. levels", kTH2F, {jetPTcorr, jetPTcorr}); - spectra.add("hMissedJets_pT", "Part. level jets w/o matched pair", kTH1F, {{200, 0.0, 200.}}); - // spectra.add("hMissedJets_Corr_pT", "Part. level jets w/o matched pair", kTH1F, {jetPTcorr}); - // spectra.add("hMissedJets_pT_RecoilJets", "Part. level jets w/o matched pair", kTH1F, {{200, 0.0, 200.}}); - // spectra.add("hMissedJets_Corr_pT_RecoilJets", "Part. level jets w/o matched pair", kTH1F, {jetPTcorr}); - - spectra.add("hFakeJets_pT", "Det. level jets w/o matched pair", kTH1F, {{200, 0.0, 200.}}); - // spectra.add("hFakeJets_Corr_pT", "Det. level jets w/o matched pair", kTH1F, {jetPTcorr}); - spectra.add("hFakeJets_pT_RecoilJets", "Det. level jets w/o matched pair", kTH1F, {{200, 0.0, 200.}}); - // spectra.add("hFakeJets_Corr_pT_RecoilJets", "Det. level jets w/o matched pair", kTH1F, {jetPTcorr}); + if (bGetMissJets) { + spectra.add("hMissedJets_pT", "Part. level jets w/o matched pair", kTH1F, {{200, 0.0, 200.}}); + // spectra.add("hMissedJets_Corr_pT", "Part. level jets w/o matched pair", kTH1F, {jetPTcorr}); + spectra.add("hMissedJets_pT_RecoilJets", "Part. level jets w/o matched pair", kTH1F, {{200, 0.0, 200.}}); + // spectra.add("hMissedJets_Corr_pT_RecoilJets", "Part. level jets w/o matched pair", kTH1F, {jetPTcorr}); + } else { + spectra.add("hFakeJets_pT", "Det. level jets w/o matched pair", kTH1F, {{200, 0.0, 200.}}); + // spectra.add("hFakeJets_Corr_pT", "Det. level jets w/o matched pair", kTH1F, {jetPTcorr}); + spectra.add("hFakeJets_pT_RecoilJets", "Det. level jets w/o matched pair", kTH1F, {{200, 0.0, 200.}}); + // spectra.add("hFakeJets_Corr_pT_RecoilJets", "Det. level jets w/o matched pair", kTH1F, {jetPTcorr}); + } spectra.add("hJetPt_resolution", "Jet p_{T} relative resolution as a func. of jet #it{p}_{T, part}", kTH2F, {{100, -5., 5.}, pT}); spectra.add("hJetPt_resolution_RecoilJets", "Jet p_{T} relative resolution as a func. of jet #it{p}_{T, part}", kTH2F, {{100, -5., 5.}, pT}); spectra.add("hJetPhi_resolution", "#varphi resolution as a func. of jet #it{p}_{T, part}", kTH2F, {{40, -1., 1.}, pT}); spectra.add("hJetPhi_resolution_RecoilJets", "#varphi resolution as a func. of jet #it{p}_{T, part}", kTH2F, {{40, -1., 1.}, pT}); + + spectra.add("hNumberMatchedJetsPerOneBaseJet", "# of taged jets per 1 base jet vs. jet pT", kTH2F, {{10, 0.5, 10.5}, {100, 0.0, 100.}}); } } @@ -231,11 +247,15 @@ struct RecoilJets { if (skipTrack(track)) continue; + if (bIsMC && (track.pt() > pTHatMaxTrack * pTHat)) + continue; + spectra.fill(HIST("hTrackPtEtaPhi"), track.pt(), track.eta(), track.phi(), weight); // Search for TT candidate if (bSigEv && (track.pt() > ptTTsigMin && track.pt() < ptTTsigMax)) { vPhiOfTT.push_back(track.phi()); + spectra.fill(HIST("hTTSig_pT"), track.pt(), weight); ++nTT; } @@ -301,6 +321,7 @@ struct RecoilJets { double phiTT = 0.; int nTT = 0; float pTHat = getPtHat(weight); + spectra.fill(HIST("ptHat"), pTHat, weight); auto dice = rand->Rndm(); if (dice < fracSig) @@ -316,6 +337,9 @@ struct RecoilJets { if (bParticleNeutral || !particle.isPhysicalPrimary()) continue; + if (particle.pt() > pTHatMaxTrack * pTHat) + continue; + spectra.fill(HIST("hPartPtEtaPhi"), particle.pt(), particle.eta(), particle.phi(), weight); if (bSigEv && (particle.pt() > ptTTsigMin && particle.pt() < ptTTsigMax)) { @@ -379,70 +403,36 @@ struct RecoilJets { } } - /// TODO: Add functionality to get rho for particle and detector level - template - void fillMatchedHistograms(Tracks const& tracks, DetLevelJets const& jets_det_level, PartLevelJets const& jets_part_level, float weight = 1.) + template + void fillMatchedHistograms(TracksTable const& tracks, JetsBase const& jetsBase, JetsTag const& jetsTag, float weight = 1.) { std::vector vPhiOfTT; - double phiTT = 0.; + double phiTTSig = 0.; float pTHat = getPtHat(weight); for (const auto& track : tracks) { if (skipTrack(track)) continue; + if (track.pt() > pTHatMaxTrack * pTHat) + continue; + if (track.pt() > ptTTsigMin && track.pt() < ptTTsigMax) { vPhiOfTT.push_back(track.phi()); } } - bool bTT = vPhiOfTT.size() > 0; - if (bTT) - phiTT = getPhiTT(vPhiOfTT); - - for (const auto& jet_det_level : jets_det_level) { - if (jet_det_level.pt() > pTHatMax * pTHat) - continue; + bool bIsThereTTSig = vPhiOfTT.size() > 0; - bool bRecoilJet = get<1>(isRecoilJet(jet_det_level, phiTT)) && bTT; + if (bIsThereTTSig) + phiTTSig = getPhiTT(vPhiOfTT); - if (jet_det_level.has_matchedJetGeo()) { - - const auto jetsMatchedPartLevel = jet_det_level.template matchedJetGeo_as>(); // we can add "matchedJetPt_as" later - - for (const auto& jet_matched_part_level : jetsMatchedPartLevel) { - - /* - Which histos we want: - 1) det pT vs. part. pT for inclusive jets (corrected for rho*A and not) - 2) det pT vs. part. pT for recoil jets - 3) same as (1) and (2) but 4D with dphi parts - 4) distribution of fake and miss jets - 5) pT and phi resolutions - */ - - spectra.fill(HIST("hJetPt_PartLevel_vs_DetLevel"), jet_det_level.pt(), jet_matched_part_level.pt(), weight); - spectra.fill(HIST("hJetPt_resolution"), (jet_matched_part_level.pt() - jet_det_level.pt()) / jet_matched_part_level.pt(), jet_matched_part_level.pt(), weight); - spectra.fill(HIST("hJetPhi_resolution"), jet_matched_part_level.phi() - jet_det_level.phi(), jet_matched_part_level.pt(), weight); - - if (bRecoilJet) { - spectra.fill(HIST("hJetPt_PartLevel_vs_DetLevel_RecoilJets"), jet_det_level.pt(), jet_matched_part_level.pt(), weight); - spectra.fill(HIST("hJetPt_resolution_RecoilJets"), (jet_matched_part_level.pt() - jet_det_level.pt()) / jet_matched_part_level.pt(), jet_matched_part_level.pt(), weight); - spectra.fill(HIST("hJetPhi_resolution_RecoilJets"), jet_matched_part_level.phi() - jet_det_level.phi(), jet_matched_part_level.pt(), weight); - } - } - } else { - spectra.fill(HIST("hFakeJets_pT"), jet_det_level.pt(), weight); - if (bRecoilJet) - spectra.fill(HIST("hFakeJets_pT_RecoilJets"), jet_det_level.pt(), weight); - } - } + for (const auto& jetBase : jetsBase) { + if (jetBase.pt() > pTHatMax * pTHat) + continue; - // Missed jets - for (const auto& jet_part_level : jets_part_level) { - if (!jet_part_level.has_matchedJetGeo()) { - spectra.fill(HIST("hMissedJets_pT"), jet_part_level.pt(), weight); - } + bool bIsBaseJetRecoil = get<1>(isRecoilJet(jetBase, phiTTSig)) && bIsThereTTSig; + dataForUnfolding(jetBase, jetsTag, bIsBaseJetRecoil, weight); } } @@ -462,7 +452,7 @@ struct RecoilJets { FilteredTracks const& tracks, FilteredJetsDetLevel const& jets) { - if (skipEvent(collision)) + if (skipEvent(collision) || skipMBGapEvent(collision)) return; spectra.fill(HIST("vertexZ"), collision.posZ()); @@ -475,12 +465,18 @@ struct RecoilJets { FilteredTracks const& tracks, FilteredJetsDetLevel const& jets) { - if (skipEvent(collision)) + if (skipEvent(collision) || skipMBGapEvent(collision)) return; - /// \TODO: should we implement function to check whether Collision was reconstructed (has_mcCollision() function)? Example: https://github.com/AliceO2Group/O2Physics/blob/1cba330514ab47c15c0095d8cee9633723d8e2a7/PWGJE/Tasks/v0qa.cxx#L166? auto weight = collision.mcCollision().weight(); spectra.fill(HIST("vertexZ"), collision.posZ(), weight); + + if (collision.has_mcCollision()) { + spectra.fill(HIST("hHasAssocMcCollision"), 0.5, weight); + } else { + spectra.fill(HIST("hHasAssocMcCollision"), 1.5, weight); + } + fillHistograms(collision, jets, tracks, true, weight); } PROCESS_SWITCH(RecoilJets, processMCDetLevelWeighted, "process MC detector level with event weight", false); @@ -489,7 +485,10 @@ struct RecoilJets { aod::JetParticles const& particles, FilteredJetsPartLevel const& jets) { - spectra.fill(HIST("vertexZ"), collision.posZ()); + if (skipMBGapEvent(collision)) + return; + + spectra.fill(HIST("vertexZMC"), collision.posZ()); fillMCPHistograms(collision, jets, particles); } PROCESS_SWITCH(RecoilJets, processMCPartLevel, "process MC particle level", false); @@ -498,8 +497,11 @@ struct RecoilJets { aod::JetParticles const& particles, FilteredJetsPartLevel const& jets) { + if (skipMBGapEvent(collision)) + return; + auto weight = collision.weight(); - spectra.fill(HIST("vertexZ"), collision.posZ(), weight); + spectra.fill(HIST("vertexZMC"), collision.posZ(), weight); fillMCPHistograms(collision, jets, particles, weight); } PROCESS_SWITCH(RecoilJets, processMCPartLevelWeighted, "process MC particle level with event weight", false); @@ -510,10 +512,16 @@ struct RecoilJets { FilteredMatchedJetsDetLevel const& mcdjets, FilteredMatchedJetsPartLevel const& mcpjets) { - if (skipEvent(collision)) + if (skipEvent(collision) || skipMBGapEvent(collision)) return; + auto mcpjetsPerMCCollision = mcpjets.sliceBy(partJetsPerCollision, collision.mcCollisionId()); - fillMatchedHistograms(tracks, mcdjets, mcpjetsPerMCCollision); + + if (bGetMissJets) { + fillMatchedHistograms(tracks, mcpjetsPerMCCollision, mcdjets); + } else { + fillMatchedHistograms(tracks, mcdjets, mcpjetsPerMCCollision); + } } PROCESS_SWITCH(RecoilJets, processJetsMatched, "process matching of MC jets (no weight)", false); @@ -523,13 +531,17 @@ struct RecoilJets { FilteredMatchedJetsDetLevel const& mcdjets, FilteredMatchedJetsPartLevel const& mcpjets) { - if (skipEvent(collision)) + if (skipEvent(collision) || skipMBGapEvent(collision)) return; auto mcpjetsPerMCCollision = mcpjets.sliceBy(partJetsPerCollision, collision.mcCollisionId()); auto weight = collision.mcCollision().weight(); - fillMatchedHistograms(tracks, mcdjets, mcpjetsPerMCCollision, weight); + if (bGetMissJets) { + fillMatchedHistograms(tracks, mcpjetsPerMCCollision, mcdjets, weight); + } else { + fillMatchedHistograms(tracks, mcdjets, mcpjetsPerMCCollision, weight); + } } PROCESS_SWITCH(RecoilJets, processJetsMatchedWeighted, "process matching of MC jets (weighted)", false); @@ -542,6 +554,12 @@ struct RecoilJets { return !jetderiveddatautilities::selectCollision(coll, eventSelectionBits) || !jetderiveddatautilities::selectTrigger(coll, triggerMaskBits); } + template + bool skipMBGapEvent(const Collision& coll) + { + return skipMBGapEvents && coll.subGeneratorId() == jetderiveddatautilities::JCollisionSubGeneratorId::mbGap; + } + template bool skipTrack(const Track& track) { @@ -566,6 +584,55 @@ struct RecoilJets { { return 10. / (std::pow(weight, 1.0 / pTHatExponent)); } + + template + void dataForUnfolding(JetBase const& jetBase, JetsTag const&, bool bIsBaseJetRecoil, float weight = 1.0) + { + + bool bIsThereMatchedJet = jetBase.has_matchedJetGeo(); + if (bIsThereMatchedJet) { + const auto& jetsMatched = jetBase.template matchedJetGeo_as>(); + + for (const auto& jetMatched : jetsMatched) { + spectra.fill(HIST("hNumberMatchedJetsPerOneBaseJet"), jetsMatched.size(), jetMatched.pt(), weight); + + if (bGetMissJets) { + // Mean that base jet is particle level jet + spectra.fill(HIST("hJetPt_DetLevel_vs_PartLevel"), jetMatched.pt(), jetBase.pt(), weight); + spectra.fill(HIST("hJetPt_resolution"), (jetBase.pt() - jetMatched.pt()) / jetBase.pt(), jetBase.pt(), weight); + spectra.fill(HIST("hJetPhi_resolution"), jetBase.phi() - jetMatched.phi(), jetBase.pt(), weight); + + if (bIsBaseJetRecoil) { + spectra.fill(HIST("hJetPt_DetLevel_vs_PartLevel_RecoilJets"), jetMatched.pt(), jetBase.pt(), weight); + spectra.fill(HIST("hJetPt_resolution_RecoilJets"), (jetBase.pt() - jetMatched.pt()) / jetBase.pt(), jetBase.pt(), weight); + spectra.fill(HIST("hJetPhi_resolution_RecoilJets"), jetBase.phi() - jetMatched.phi(), jetBase.pt(), weight); + } + } else { + // Mean that base jet is detector level jet + spectra.fill(HIST("hJetPt_DetLevel_vs_PartLevel"), jetBase.pt(), jetMatched.pt(), weight); + spectra.fill(HIST("hJetPt_resolution"), (jetMatched.pt() - jetBase.pt()) / jetMatched.pt(), jetMatched.pt(), weight); + spectra.fill(HIST("hJetPhi_resolution"), jetMatched.phi() - jetBase.phi(), jetMatched.phi(), weight); + + if (bIsBaseJetRecoil) { + spectra.fill(HIST("hJetPt_DetLevel_vs_PartLevel_RecoilJets"), jetBase.pt(), jetMatched.pt(), weight); + spectra.fill(HIST("hJetPt_resolution_RecoilJets"), (jetMatched.pt() - jetBase.pt()) / jetMatched.pt(), jetMatched.pt(), weight); + spectra.fill(HIST("hJetPhi_resolution_RecoilJets"), jetMatched.phi() - jetBase.phi(), jetMatched.phi(), weight); + } + } + } + } else { + // No closest jet + if (bGetMissJets) { + spectra.fill(HIST("hMissedJets_pT"), jetBase.pt(), weight); + if (bIsBaseJetRecoil) + spectra.fill(HIST("hMissedJets_pT_RecoilJets"), jetBase.pt(), weight); + } else { + spectra.fill(HIST("hFakeJets_pT"), jetBase.pt(), weight); + if (bIsBaseJetRecoil) + spectra.fill(HIST("hFakeJets_pT_RecoilJets"), jetBase.pt(), weight); + } + } + } }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{adaptAnalysisTask(cfgc)}; } diff --git a/PWGJE/Tasks/trackEfficiency.cxx b/PWGJE/Tasks/trackEfficiency.cxx index 10ff3365974..b9fde50abde 100644 --- a/PWGJE/Tasks/trackEfficiency.cxx +++ b/PWGJE/Tasks/trackEfficiency.cxx @@ -52,6 +52,7 @@ struct TrackEfficiencyJets { Configurable eventSelections{"eventSelections", "sel8", "choose event selection"}; Configurable trackSelections{"trackSelections", "globalTracks", "set track selections; other option: uniformTracks"}; + Configurable skipMBGapEvents{"skipMBGapEvents", false, "flag to choose to reject min. bias gap events"}; // Tracking efficiency process function configurables: Configurable checkPrimaryPart{"checkPrimaryPart", true, "0: doesn't check mcparticle.isPhysicalPrimary() - 1: checks particle.isPhysicalPrimary()"}; @@ -72,6 +73,10 @@ struct TrackEfficiencyJets { Configurable trackOccupancyInTimeRangeMax{"trackOccupancyInTimeRangeMax", 999999, "maximum occupancy of tracks in neighbouring collisions in a given time range; only applied for reconstructed tracks, not mc particles"}; Configurable trackOccupancyInTimeRangeMin{"trackOccupancyInTimeRangeMin", -999999, "minimum occupancy of tracks in neighbouring collisions in a given time range; only applied for reconstructed tracks, not mc particles"}; + Configurable> centralityBinning{"centralityBinning", {0., 10., 50., 70.}, "binning of centrality histograms"}; + Configurable intRateNBins{"intRateNBins", 50, "number of bins for interaction rate axis"}; + Configurable intRateMax{"intRateMax", 50000.0, "maximum value of interaction rate axis"}; + std::vector eventSelectionBits; int trackSelection = -1; @@ -100,6 +105,7 @@ struct TrackEfficiencyJets { registry.fill(HIST("h2_track_pt_track_sigmapt"), track.pt(), track.sigma1Pt() * track.pt(), weight); registry.fill(HIST("h2_track_pt_high_track_sigma1overpt"), track.pt(), track.sigma1Pt(), weight); registry.fill(HIST("h2_track_pt_high_track_sigmapt"), track.pt(), track.sigma1Pt() * track.pt(), weight); + registry.fill(HIST("h3_intrate_centrality_track_pt"), collision.hadronicRate(), collision.centrality(), track.pt(), weight); } } @@ -111,6 +117,7 @@ struct TrackEfficiencyJets { registry.fill(HIST("h2_centrality_particle_eta"), collision.centrality(), mcparticle.eta(), weight); registry.fill(HIST("h2_centrality_particle_phi"), collision.centrality(), mcparticle.phi(), weight); registry.fill(HIST("h2_centrality_particle_energy"), collision.centrality(), mcparticle.energy(), weight); + registry.fill(HIST("h3_intrate_centrality_particle_pt"), collision.hadronicRate(), collision.centrality(), mcparticle.pt(), weight); } } @@ -182,7 +189,8 @@ struct TrackEfficiencyJets { } if (doprocessTracks || doprocessTracksWeighted) { - AxisSpec centAxis = {121, -10., 111., "centrality (%)"}; + AxisSpec centAxis = {centralityBinning, "centrality (%)"}; + AxisSpec intRateAxis = {intRateNBins, 0., intRateMax, "int. rate (kHz)"}; registry.add("h2_centrality_track_pt", "centrality vs track pT; centrality; #it{p}_{T,track} (GeV/#it{c})", {HistType::kTH2F, {centAxis, {200, 0., 200.}}}); registry.add("h2_centrality_track_eta", "centrality vs track #eta; centrality; #eta_{track}", {HistType::kTH2F, {centAxis, {100, -1.0, 1.0}}}); registry.add("h2_centrality_track_phi", "centrality vs track #varphi; centrality; #varphi_{track}", {HistType::kTH2F, {centAxis, {160, -1.0, 7.}}}); @@ -191,24 +199,27 @@ struct TrackEfficiencyJets { registry.add("h2_track_pt_high_track_sigmapt", "#sigma(#it{p}_{T})/#it{p}_{T}; #it{p}_{T,track} (GeV/#it{c})", {HistType::kTH2F, {{90, 10., 100.}, {100000, 0.0, 100.0}}}); registry.add("h2_track_pt_track_sigma1overpt", "#sigma(1/#it{p}_{T}); #it{p}_{T,track} (GeV/#it{c})", {HistType::kTH2F, {{100, 0., 10.}, {1000, 0.0, 10.0}}}); registry.add("h2_track_pt_high_track_sigma1overpt", "#sigma(1/#it{p}_{T}); #it{p}_{T,track} (GeV/#it{c})", {HistType::kTH2F, {{90, 10., 100.}, {1000, 0.0, 10.0}}}); + registry.add("h3_intrate_centrality_track_pt", "interaction rate vs centrality vs track pT; int. rate; centrality; #it{p}_{T,track} (GeV/#it{c})", {HistType::kTH3F, {intRateAxis, centAxis, {200, 0., 200.}}}); } if (doprocessParticles || doprocessParticlesWeighted) { - AxisSpec centAxis = {121, -10., 111., "centrality (%)"}; - registry.add("h2_centrality_particle_pt", "centrality vs track pT; centrality; #it{p}_{T,track} (GeV/#it{c})", {HistType::kTH2F, {centAxis, {200, 0., 200.}}}); - registry.add("h2_centrality_particle_eta", "centrality vs track #eta; centrality; #eta_{track}", {HistType::kTH2F, {centAxis, {100, -1.0, 1.0}}}); - registry.add("h2_centrality_particle_phi", "centrality vs track #varphi; centrality; #varphi_{track}", {HistType::kTH2F, {centAxis, {160, -1.0, 7.}}}); - registry.add("h2_centrality_particle_energy", "centrality vs track energy; centrality; Energy GeV", {HistType::kTH2F, {centAxis, {100, 0.0, 100.0}}}); + AxisSpec centAxis = {centralityBinning, "centrality (%)"}; + AxisSpec intRateAxis = {intRateNBins, 0., intRateMax, "int. rate (kHz)"}; + registry.add("h2_centrality_particle_pt", "centrality vs particle pT; centrality; #it{p}_{T,part} (GeV/#it{c})", {HistType::kTH2F, {centAxis, {200, 0., 200.}}}); + registry.add("h2_centrality_particle_eta", "centrality vs particle #eta; centrality; #eta_{part}", {HistType::kTH2F, {centAxis, {100, -1.0, 1.0}}}); + registry.add("h2_centrality_particle_phi", "centrality vs particle #varphi; centrality; #varphi_{part}", {HistType::kTH2F, {centAxis, {160, -1.0, 7.}}}); + registry.add("h2_centrality_particle_energy", "centrality vs particle energy; centrality; Energy GeV", {HistType::kTH2F, {centAxis, {100, 0.0, 100.0}}}); + registry.add("h3_intrate_centrality_particle_pt", "interaction rate vs centrality vs particle pT; int. rate; centrality; #it{p}_{T,part} (GeV/#it{c})", {HistType::kTH3F, {intRateAxis, centAxis, {200, 0., 200.}}}); } if (doprocessTracks || doprocessTracksWeighted) { - AxisSpec centAxis = {121, -10., 111., "centrality (%)"}; + AxisSpec centAxis = {centralityBinning, "centrality (%)"}; registry.add("h_collisions", "event status;event status;entries", {HistType::kTH1F, {{4, 0.0, 4.0}}}); registry.add("h_fakecollisions", "event status;event status;entries", {HistType::kTH1F, {{4, 0.0, 4.0}}}); registry.add("h2_centrality_collisions", "centrality vs collisions; centrality; collisions", {HistType::kTH2F, {centAxis, {4, 0.0, 4.0}}}); } if (doprocessParticles || doprocessParticlesWeighted) { - AxisSpec centAxis = {121, -10., 111., "centrality (%)"}; + AxisSpec centAxis = {centralityBinning, "centrality (%)"}; registry.add("h_mccollisions", "event status;event status;entries", {HistType::kTH1F, {{4, 0.0, 4.0}}}); registry.add("h2_centrality_mccollisions", "centrality vs mccollisions; centrality; collisions", {HistType::kTH2F, {centAxis, {4, 0.0, 4.0}}}); } @@ -258,7 +269,7 @@ struct TrackEfficiencyJets { bool hasSel8Coll = false; bool centralityCheck = false; if (acceptSplitCollisions == 2) { // check only that the first reconstructed collision passes the check - if (jetderiveddatautilities::selectCollision(collisions.begin(), eventSelectionBits)) { // Skipping MC events that have not a single selected reconstructed collision ; effect unclear if mcColl is split + if (jetderiveddatautilities::selectCollision(collisions.begin(), eventSelectionBits, skipMBGapEvents)) { // Skipping MC events that have not a single selected reconstructed collision ; effect unclear if mcColl is split hasSel8Coll = true; } if (!checkCentrality || ((centralityMin < collisions.begin().centrality()) && (collisions.begin().centrality() < centralityMax))) { // effect unclear if mcColl is split @@ -266,7 +277,7 @@ struct TrackEfficiencyJets { } } else { // check that at least one of the reconstructed collisions passes the checks for (auto& collision : collisions) { - if (jetderiveddatautilities::selectCollision(collision, eventSelectionBits)) { // Skipping MC events that have not a single selected reconstructed collision ; effect unclear if mcColl is split + if (jetderiveddatautilities::selectCollision(collision, eventSelectionBits, skipMBGapEvents)) { // Skipping MC events that have not a single selected reconstructed collision ; effect unclear if mcColl is split hasSel8Coll = true; } if (!checkCentrality || ((centralityMin < collision.centrality()) && (collision.centrality() < centralityMax))) { // effect unclear if mcColl is split @@ -317,7 +328,7 @@ struct TrackEfficiencyJets { return; } - if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits) || !(abs(collision.posZ()) < vertexZCut)) { + if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits, skipMBGapEvents) || !(abs(collision.posZ()) < vertexZCut)) { continue; } @@ -392,7 +403,7 @@ struct TrackEfficiencyJets { { registry.fill(HIST("h_collisions"), 0.5); registry.fill(HIST("h2_centrality_collisions"), collision.centrality(), 0.5); - if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits)) { + if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits, skipMBGapEvents)) { return; } registry.fill(HIST("h_collisions"), 1.5); @@ -417,7 +428,7 @@ struct TrackEfficiencyJets { float eventWeight = collision.mcCollision().weight(); registry.fill(HIST("h_collisions"), 0.5); registry.fill(HIST("h_collisions_weighted"), 0.5, eventWeight); - if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits)) { + if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits, skipMBGapEvents)) { return; } registry.fill(HIST("h_collisions"), 1.5); @@ -451,7 +462,7 @@ struct TrackEfficiencyJets { bool hasSel8Coll = false; bool centralityCheck = false; if (acceptSplitCollisions == 2) { // check only that the first reconstructed collision passes the check - if (jetderiveddatautilities::selectCollision(collisions.begin(), eventSelectionBits)) { // Skipping MC events that have not a single selected reconstructed collision ; effect unclear if mcColl is split + if (jetderiveddatautilities::selectCollision(collisions.begin(), eventSelectionBits, skipMBGapEvents)) { // Skipping MC events that have not a single selected reconstructed collision ; effect unclear if mcColl is split hasSel8Coll = true; } if (!checkCentrality || ((centralityMin < collisions.begin().centrality()) && (collisions.begin().centrality() < centralityMax))) { // effect unclear if mcColl is split @@ -459,7 +470,7 @@ struct TrackEfficiencyJets { } } else { // check that at least one of the reconstructed collisions passes the checks for (auto& collision : collisions) { - if (jetderiveddatautilities::selectCollision(collision, eventSelectionBits)) { // Skipping MC events that have not a single selected reconstructed collision ; effect unclear if mcColl is split + if (jetderiveddatautilities::selectCollision(collision, eventSelectionBits, skipMBGapEvents)) { // Skipping MC events that have not a single selected reconstructed collision ; effect unclear if mcColl is split hasSel8Coll = true; } if (!checkCentrality || ((centralityMin < collision.centrality()) && (collision.centrality() < centralityMax))) { // effect unclear if mcColl is split @@ -484,6 +495,10 @@ struct TrackEfficiencyJets { soa::SmallGroups const& collisions, soa::Filtered const& mcparticles) { + if (skipMBGapEvents && mcCollision.subGeneratorId() == jetderiveddatautilities::JCollisionSubGeneratorId::mbGap) { + return; + } + float eventWeight = mcCollision.weight(); registry.fill(HIST("h_mccollisions"), 0.5); registry.fill(HIST("h_mccollisions_weighted"), 0.5, eventWeight); @@ -501,7 +516,7 @@ struct TrackEfficiencyJets { bool hasSel8Coll = false; bool centralityCheck = false; if (acceptSplitCollisions == 2) { // check only that the first reconstructed collision passes the check - if (jetderiveddatautilities::selectCollision(collisions.begin(), eventSelectionBits)) { // Skipping MC events that have not a single selected reconstructed collision ; effect unclear if mcColl is split + if (jetderiveddatautilities::selectCollision(collisions.begin(), eventSelectionBits, skipMBGapEvents)) { // Skipping MC events that have not a single selected reconstructed collision ; effect unclear if mcColl is split hasSel8Coll = true; } if (!checkCentrality || ((centralityMin < collisions.begin().centrality()) && (collisions.begin().centrality() < centralityMax))) { // effect unclear if mcColl is split @@ -509,7 +524,7 @@ struct TrackEfficiencyJets { } } else { // check that at least one of the reconstructed collisions passes the checks for (auto& collision : collisions) { - if (jetderiveddatautilities::selectCollision(collision, eventSelectionBits)) { // Skipping MC events that have not a single selected reconstructed collision ; effect unclear if mcColl is split + if (jetderiveddatautilities::selectCollision(collision, eventSelectionBits, skipMBGapEvents)) { // Skipping MC events that have not a single selected reconstructed collision ; effect unclear if mcColl is split hasSel8Coll = true; } if (!checkCentrality || ((centralityMin < collision.centrality()) && (collision.centrality() < centralityMax))) { // effect unclear if mcColl is split diff --git a/PWGLF/DataModel/LFSigmaTables.h b/PWGLF/DataModel/LFSigmaTables.h index 08b511bf1ca..0980b6891ad 100644 --- a/PWGLF/DataModel/LFSigmaTables.h +++ b/PWGLF/DataModel/LFSigmaTables.h @@ -36,6 +36,7 @@ DECLARE_SOA_COLUMN(SigmaOPAngle, sigmaOPAngle, float); DECLARE_SOA_COLUMN(SigmaCentrality, sigmaCentrality, float); DECLARE_SOA_COLUMN(SigmaRunNumber, sigmaRunNumber, int); DECLARE_SOA_COLUMN(SigmaTimestamp, sigmaTimestamp, uint64_t); +DECLARE_SOA_COLUMN(SigmaIR, sigmaIR, float); } // namespace sigma0Core @@ -46,7 +47,8 @@ DECLARE_SOA_TABLE(Sigma0Cores, "AOD", "SIGMA0CORES", sigma0Core::SigmaOPAngle, sigma0Core::SigmaCentrality, sigma0Core::SigmaRunNumber, - sigma0Core::SigmaTimestamp); + sigma0Core::SigmaTimestamp, + sigma0Core::SigmaIR); // For Photon extra info namespace sigmaPhotonExtra @@ -81,6 +83,8 @@ DECLARE_SOA_COLUMN(PhotonPosITSCls, photonPosITSCls, int); DECLARE_SOA_COLUMN(PhotonNegITSCls, photonNegITSCls, int); DECLARE_SOA_COLUMN(PhotonPosITSChi2PerNcl, photonPosITSChi2PerNcl, float); DECLARE_SOA_COLUMN(PhotonNegITSChi2PerNcl, photonNegITSChi2PerNcl, float); +DECLARE_SOA_COLUMN(PhotonPosTrackCode, photonPosTrackCode, uint8_t); +DECLARE_SOA_COLUMN(PhotonNegTrackCode, photonNegTrackCode, uint8_t); DECLARE_SOA_COLUMN(PhotonV0Type, photonV0Type, uint8_t); DECLARE_SOA_COLUMN(GammaBDTScore, gammaBDTScore, float); @@ -117,6 +121,8 @@ DECLARE_SOA_TABLE(SigmaPhotonExtras, "AOD", "SIGMA0PHOTON", sigmaPhotonExtra::PhotonNegITSCls, sigmaPhotonExtra::PhotonPosITSChi2PerNcl, sigmaPhotonExtra::PhotonNegITSChi2PerNcl, + sigmaPhotonExtra::PhotonPosTrackCode, + sigmaPhotonExtra::PhotonNegTrackCode, sigmaPhotonExtra::PhotonV0Type, sigmaPhotonExtra::GammaBDTScore); @@ -159,6 +165,8 @@ DECLARE_SOA_COLUMN(LambdaPosITSCls, lambdaPosITSCls, int); DECLARE_SOA_COLUMN(LambdaNegITSCls, lambdaNegITSCls, int); DECLARE_SOA_COLUMN(LambdaPosITSChi2PerNcl, lambdaPosChi2PerNcl, float); DECLARE_SOA_COLUMN(LambdaNegITSChi2PerNcl, lambdaNegChi2PerNcl, float); +DECLARE_SOA_COLUMN(LambdaPosTrackCode, lambdaPosTrackCode, uint8_t); +DECLARE_SOA_COLUMN(LambdaNegTrackCode, lambdaNegTrackCode, uint8_t); DECLARE_SOA_COLUMN(LambdaV0Type, lambdaV0Type, uint8_t); DECLARE_SOA_COLUMN(LambdaBDTScore, lambdaBDTScore, float); DECLARE_SOA_COLUMN(AntiLambdaBDTScore, antilambdaBDTScore, float); @@ -202,6 +210,8 @@ DECLARE_SOA_TABLE(SigmaLambdaExtras, "AOD", "SIGMA0LAMBDA", sigmaLambdaExtra::LambdaNegITSCls, sigmaLambdaExtra::LambdaPosITSChi2PerNcl, sigmaLambdaExtra::LambdaNegITSChi2PerNcl, + sigmaLambdaExtra::LambdaPosTrackCode, + sigmaLambdaExtra::LambdaNegTrackCode, sigmaLambdaExtra::LambdaV0Type, sigmaLambdaExtra::LambdaBDTScore, sigmaLambdaExtra::AntiLambdaBDTScore); @@ -216,10 +226,12 @@ DECLARE_SOA_COLUMN(PhotonCandPDGCode, photonCandPDGCode, int); DECLARE_SOA_COLUMN(PhotonCandPDGCodeMother, photonCandPDGCodeMother, int); DECLARE_SOA_COLUMN(IsPhotonCandPrimary, isPhotonCandPrimary, bool); DECLARE_SOA_COLUMN(PhotonMCPt, photonMCPt, float); +DECLARE_SOA_COLUMN(PhotonIsCorrectlyAssoc, photonIsCorrectlyAssoc, bool); DECLARE_SOA_COLUMN(LambdaCandPDGCode, lambdaCandPDGCode, int); DECLARE_SOA_COLUMN(LambdaCandPDGCodeMother, lambdaCandPDGCodeMother, int); DECLARE_SOA_COLUMN(IsLambdaCandPrimary, isLambdaCandPrimary, bool); DECLARE_SOA_COLUMN(LambdaMCPt, lambdaMCPt, float); +DECLARE_SOA_COLUMN(LambdaIsCorrectlyAssoc, lambdaIsCorrectlyAssoc, bool); } // namespace sigmaMCCore @@ -231,10 +243,12 @@ DECLARE_SOA_TABLE(SigmaMCCores, "AOD", "SIGMA0MCCORES", sigmaMCCore::PhotonCandPDGCodeMother, sigmaMCCore::IsPhotonCandPrimary, sigmaMCCore::PhotonMCPt, + sigmaMCCore::PhotonIsCorrectlyAssoc, sigmaMCCore::LambdaCandPDGCode, sigmaMCCore::LambdaCandPDGCodeMother, sigmaMCCore::IsLambdaCandPrimary, - sigmaMCCore::LambdaMCPt); + sigmaMCCore::LambdaMCPt, + sigmaMCCore::LambdaIsCorrectlyAssoc); } // namespace o2::aod #endif // PWGLF_DATAMODEL_LFSIGMATABLES_H_ diff --git a/PWGLF/TableProducer/Nuspex/hypertriton3bodyfinder.cxx b/PWGLF/TableProducer/Nuspex/hypertriton3bodyfinder.cxx index b4445a5619a..40019d82533 100644 --- a/PWGLF/TableProducer/Nuspex/hypertriton3bodyfinder.cxx +++ b/PWGLF/TableProducer/Nuspex/hypertriton3bodyfinder.cxx @@ -865,7 +865,7 @@ struct hypertriton3bodyFinder { auto ntracks = Ntracks.sliceBy(perCollisionGoodNegTracks, collision.globalIndex()); auto goodtracks = Goodtracks.sliceBy(perCollisionGoodTracks, collision.globalIndex()); - if (!cffilter.hasLD() && UseCFFilter) { + if (!cffilter.hasLD_LooseKstar() && UseCFFilter) { continue; } registry.fill(HIST("hEventCounter"), 1.5); @@ -902,7 +902,7 @@ struct hypertriton3bodyFinder { VirtualLambdaCheck(collision, v0s, 0); VirtualLambdaCheck(collision, fullv0s, 3); - if (!cffilter.hasLD() && UseCFFilter) { + if (!cffilter.hasLD_LooseKstar() && UseCFFilter) { continue; } registry.fill(HIST("hEventCounter"), 1.5); diff --git a/PWGLF/TableProducer/Resonances/resonanceMergeDF.cxx b/PWGLF/TableProducer/Resonances/resonanceMergeDF.cxx index e7c31d1010e..99ba4ec391d 100644 --- a/PWGLF/TableProducer/Resonances/resonanceMergeDF.cxx +++ b/PWGLF/TableProducer/Resonances/resonanceMergeDF.cxx @@ -98,18 +98,32 @@ struct ResonanceMergeDF { std::vector> vecOfTuples; std::vector>> vecOfVecOfTuples; + std::vector>> + vecOfVecOfTuplesCasc; void processTrackDataDF(aod::ResoCollisions::iterator const& collision, aod::ResoTracks const& tracks) { int nCollisions = nDF; vecOfTuples.push_back(std::make_tuple(collision.posX(), collision.posY(), collision.posZ(), collision.cent(), 0, 0, 0)); std::vector> @@ -143,7 +157,6 @@ struct ResonanceMergeDF { track.px(), track.py(), track.pz(), - track.sign(), (uint8_t)track.tpcNClsCrossedRows(), (uint8_t)track.tpcNClsFound(), static_cast(track.dcaXY() * 10000), @@ -196,11 +209,213 @@ struct ResonanceMergeDF { } vecOfTuples.clear(); - vecOfVecOfTuples.clear(); // + vecOfVecOfTuples.clear(); } PROCESS_SWITCH(ResonanceMergeDF, processTrackDataDF, "Process for data merged DF", true); + void processTrackDataDFCasc(aod::ResoCollisions::iterator const& collision, aod::ResoTracks const& tracks, aod::ResoCascades const& trackCascs) + { + + int nCollisions = nDF; + vecOfTuples.push_back(std::make_tuple(collision.posX(), collision.posY(), collision.posZ(), collision.cent(), 0, 0, 0)); + std::vector> + innerVector; + std::vector> + innerVectorCasc; + for (const auto& track : tracks) { + if (cpidCut) { + if (!track.hasTOF()) { + if (std::abs(track.tpcNSigmaPr()) > nsigmaPr && std::abs(track.tpcNSigmaKa()) > nsigmaKa) + continue; + + if (crejtpc && (std::abs(track.tpcNSigmaPr()) > std::abs(track.tpcNSigmaPi()) && std::abs(track.tpcNSigmaKa()) > std::abs(track.tpcNSigmaPi()))) + continue; + + } else { + if (std::abs(track.tofNSigmaPr()) > nsigmatofPr && std::abs(track.tofNSigmaKa()) > nsigmatofKa) + continue; + + if (crejtof && (std::abs(track.tofNSigmaPr()) > std::abs(track.tofNSigmaPi()) && std::abs(track.tofNSigmaKa()) > std::abs(track.tofNSigmaPi()))) + continue; + } + + if (std::abs(track.dcaXY()) > cDCAXY) + continue; + if (std::abs(track.dcaZ()) > cDCAZ) + continue; + } + + innerVector.push_back(std::make_tuple( + // track.trackId(), + track.pt(), + track.px(), + track.py(), + track.pz(), + (uint8_t)track.tpcNClsCrossedRows(), + (uint8_t)track.tpcNClsFound(), + static_cast(track.dcaXY() * 10000), + static_cast(track.dcaZ() * 10000), + (int8_t)(track.tpcNSigmaPi() * 10), + (int8_t)(track.tpcNSigmaKa() * 10), + (int8_t)(track.tpcNSigmaPr() * 10), + (int8_t)(track.tofNSigmaPi() * 10), + (int8_t)(track.tofNSigmaKa() * 10), + (int8_t)(track.tofNSigmaPr() * 10), + (int8_t)(track.tpcSignal() * 10), + track.trackFlags())); + } + + for (const auto& trackCasc : trackCascs) { + innerVectorCasc.push_back(std::make_tuple( + trackCasc.pt(), + trackCasc.px(), + trackCasc.py(), + trackCasc.pz(), + const_cast(trackCasc.cascadeIndices()), + (int8_t)(trackCasc.daughterTPCNSigmaPosPi() * 10), + (int8_t)(trackCasc.daughterTPCNSigmaPosKa() * 10), + (int8_t)(trackCasc.daughterTPCNSigmaPosPr() * 10), + (int8_t)(trackCasc.daughterTPCNSigmaNegPi() * 10), + (int8_t)(trackCasc.daughterTPCNSigmaNegKa() * 10), + (int8_t)(trackCasc.daughterTPCNSigmaNegPr() * 10), + (int8_t)(trackCasc.daughterTPCNSigmaBachPi() * 10), + (int8_t)(trackCasc.daughterTPCNSigmaBachKa() * 10), + (int8_t)(trackCasc.daughterTPCNSigmaBachPr() * 10), + (int8_t)(trackCasc.daughterTOFNSigmaPosPi() * 10), + (int8_t)(trackCasc.daughterTOFNSigmaPosKa() * 10), + (int8_t)(trackCasc.daughterTOFNSigmaPosPr() * 10), + (int8_t)(trackCasc.daughterTOFNSigmaNegPi() * 10), + (int8_t)(trackCasc.daughterTOFNSigmaNegKa() * 10), + (int8_t)(trackCasc.daughterTOFNSigmaNegPr() * 10), + (int8_t)(trackCasc.daughterTOFNSigmaBachPi() * 10), + (int8_t)(trackCasc.daughterTOFNSigmaBachKa() * 10), + (int8_t)(trackCasc.daughterTOFNSigmaBachPr() * 10), + trackCasc.v0CosPA(), + trackCasc.cascCosPA(), + trackCasc.daughDCA(), + trackCasc.cascDaughDCA(), + trackCasc.dcapostopv(), + trackCasc.dcanegtopv(), + trackCasc.dcabachtopv(), + trackCasc.dcav0topv(), + trackCasc.dcaXYCascToPV(), + trackCasc.dcaZCascToPV(), + trackCasc.sign(), + trackCasc.mLambda(), + trackCasc.mXi(), + trackCasc.transRadius(), trackCasc.cascTransRadius(), trackCasc.decayVtxX(), trackCasc.decayVtxY(), trackCasc.decayVtxZ())); + } + + vecOfVecOfTuples.push_back(innerVector); + vecOfVecOfTuplesCasc.push_back(innerVectorCasc); + innerVector.clear(); + innerVectorCasc.clear(); + + df++; + LOGF(info, "collisions: df = %i", df); + if (df < nCollisions) + return; + df = 0; + + for (size_t i = 0; i < vecOfTuples.size(); ++i) { + const auto& tuple = vecOfTuples[i]; + const auto& innerVector = vecOfVecOfTuples[i]; + const auto& innerVectorCasc = vecOfVecOfTuplesCasc[i]; + + histos.fill(HIST("Event/h1d_ft0_mult_percentile"), std::get<3>(tuple)); + resoCollisionsdf(0, std::get<0>(tuple), std::get<1>(tuple), std::get<2>(tuple), std::get<3>(tuple), std::get<4>(tuple), std::get<5>(tuple), 0., 0., 0., 0., 0, std::get<6>(tuple)); + // LOGF(info, "collisions: Index = %d ) %f - %f - %f %f %d -- %d", std::get<0>(tuple).globalIndex(),std::get<1>(tuple),std::get<2>(tuple), std::get<3>(tuple), std::get<4>(tuple), std::get<5>(tuple).size(),resoCollisionsdf.lastIndex()); + + for (const auto& tuple : innerVector) { + reso2trksdf(resoCollisionsdf.lastIndex(), + std::get<0>(tuple), + std::get<1>(tuple), + std::get<2>(tuple), + std::get<3>(tuple), + std::get<4>(tuple), + std::get<5>(tuple), + std::get<6>(tuple), + std::get<7>(tuple), + std::get<8>(tuple), + std::get<9>(tuple), + std::get<10>(tuple), + std::get<11>(tuple), + std::get<12>(tuple), + std::get<13>(tuple), + std::get<14>(tuple), + std::get<15>(tuple)); + } + + for (const auto& tuple : innerVectorCasc) { + reso2cascadesdf(resoCollisionsdf.lastIndex(), + std::get<0>(tuple), + std::get<1>(tuple), + std::get<2>(tuple), + std::get<3>(tuple), + std::get<4>(tuple), + std::get<5>(tuple), + std::get<6>(tuple), + std::get<7>(tuple), + std::get<8>(tuple), + std::get<9>(tuple), + std::get<10>(tuple), + std::get<11>(tuple), + std::get<12>(tuple), + std::get<13>(tuple), + std::get<14>(tuple), + std::get<15>(tuple), + std::get<16>(tuple), + std::get<17>(tuple), + std::get<18>(tuple), + std::get<19>(tuple), + std::get<20>(tuple), + std::get<21>(tuple), + std::get<22>(tuple), + std::get<23>(tuple), + std::get<24>(tuple), + std::get<25>(tuple), + std::get<26>(tuple), + std::get<27>(tuple), + std::get<28>(tuple), + std::get<29>(tuple), + std::get<30>(tuple), + std::get<31>(tuple), + std::get<32>(tuple), + std::get<33>(tuple), + std::get<34>(tuple), + std::get<35>(tuple), + std::get<36>(tuple), + std::get<37>(tuple), + std::get<38>(tuple), + std::get<39>(tuple), + std::get<40>(tuple)); + } + } + + vecOfTuples.clear(); + vecOfVecOfTuples.clear(); + vecOfVecOfTuplesCasc.clear(); // + } + + PROCESS_SWITCH(ResonanceMergeDF, processTrackDataDFCasc, "Process for data merged DF for cascade", false); + void processLambdaStarCandidate(aod::ResoCollisions::iterator const& collision, aod::ResoTracks const& tracks) { diff --git a/PWGLF/TableProducer/Strangeness/CMakeLists.txt b/PWGLF/TableProducer/Strangeness/CMakeLists.txt index 84f22d54d1d..6d9f2c04646 100644 --- a/PWGLF/TableProducer/Strangeness/CMakeLists.txt +++ b/PWGLF/TableProducer/Strangeness/CMakeLists.txt @@ -149,7 +149,7 @@ o2physics_add_dpl_workflow(cascademlselection o2physics_add_dpl_workflow(sigma0builder SOURCES sigma0builder.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2Physics::MLCore + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2Physics::MLCore O2Physics::AnalysisCCDB COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(lambdajetpolarizationbuilder diff --git a/PWGLF/TableProducer/Strangeness/sigma0builder.cxx b/PWGLF/TableProducer/Strangeness/sigma0builder.cxx index 8dfb0cfed27..d633b5b7566 100644 --- a/PWGLF/TableProducer/Strangeness/sigma0builder.cxx +++ b/PWGLF/TableProducer/Strangeness/sigma0builder.cxx @@ -38,6 +38,7 @@ #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/PIDResponse.h" +#include "Common/CCDB/ctpRateFetcher.h" #include "PWGLF/DataModel/LFStrangenessTables.h" #include "PWGLF/DataModel/LFStrangenessPIDTables.h" #include "PWGLF/DataModel/LFStrangenessMLTables.h" @@ -55,11 +56,13 @@ using namespace o2::framework; using namespace o2::framework::expressions; using std::array; using dauTracks = soa::Join; -// using V0DerivedMCDatas = soa::Join; using V0DerivedMCDatas = soa::Join; using V0StandardDerivedDatas = soa::Join; struct sigma0builder { + Service ccdb; + ctpRateFetcher rateFetcher; + SliceCache cache; Produces sigma0cores; // save sigma0 candidates for analysis @@ -71,11 +74,27 @@ struct sigma0builder { Preslice perCollisionMCDerived = o2::aod::v0data::straCollisionId; Preslice perCollisionSTDDerived = o2::aod::v0data::straCollisionId; + // pack track quality but separte also afterburner + // dynamic range: 0-31 + enum selection : int { hasTPC = 0, + hasITSTracker, + hasITSAfterburner, + hasTRD, + hasTOF }; + // Histogram registry HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; - // Event selection + Configurable fillQAhistos{"fillQAhistos", false, "if true, fill QA histograms"}; + Configurable fillBkgQAhistos{"fillBkgQAhistos", false, "if true, fill MC QA histograms for Bkg study"}; + Configurable doPi0QA{"doPi0QA", true, "Flag to fill QA histos for pi0 rejection study."}; + Configurable doAssocStudy{"doAssocStudy", false, "Do v0 to collision association study."}; + + // Event level Configurable doPPAnalysis{"doPPAnalysis", true, "if in pp, set to true"}; + Configurable fGetIR{"fGetIR", false, "Flag to retrieve the IR info."}; + Configurable fIRCrashOnNull{"fIRCrashOnNull", false, "Flag to avoid CTP RateFetcher crash."}; + Configurable irSource{"irSource", "T0VTX", "Estimator of the interaction rate (Recommended: pp --> T0VTX, Pb-Pb --> ZNC hadronic)"}; struct : ConfigurableGroup { Configurable requireSel8{"requireSel8", true, "require sel8 event selection"}; @@ -131,7 +150,6 @@ struct sigma0builder { Configurable SigmaMaxRap{"SigmaMaxRap", 0.8, "Max sigma0 rapidity"}; //// Extras: - Configurable doPi0QA{"doPi0QA", true, "Flag to fill QA histos for pi0 rejection study."}; Configurable Pi0PhotonMinDCADauToPv{"Pi0PhotonMinDCADauToPv", 0.0, "Min DCA daughter To PV (cm)"}; Configurable Pi0PhotonMaxDCAV0Dau{"Pi0PhotonMaxDCAV0Dau", 3.5, "Max DCA V0 Daughters (cm)"}; Configurable Pi0PhotonMinTPCCrossedRows{"Pi0PhotonMinTPCCrossedRows", 0, "Min daughter TPC Crossed Rows"}; @@ -148,13 +166,13 @@ struct sigma0builder { // base properties ConfigurableAxis axisPt{"axisPt", {VARIABLE_WIDTH, 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1.0f, 1.1f, 1.2f, 1.3f, 1.4f, 1.5f, 1.6f, 1.7f, 1.8f, 1.9f, 2.0f, 2.2f, 2.4f, 2.6f, 2.8f, 3.0f, 3.2f, 3.4f, 3.6f, 3.8f, 4.0f, 4.4f, 4.8f, 5.2f, 5.6f, 6.0f, 6.5f, 7.0f, 7.5f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 17.0f, 19.0f, 21.0f, 23.0f, 25.0f, 30.0f, 35.0f, 40.0f, 50.0f}, "pt axis for analysis"}; ConfigurableAxis axisCentrality{"axisCentrality", {VARIABLE_WIDTH, 0.0f, 5.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 60.0f, 70.0f, 80.0f, 90.0f, 100.0f, 110.0f}, "Centrality"}; - ConfigurableAxis axisInvPt{"axisInvPt", {VARIABLE_WIDTH, 0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 2.0, 5.0, 10.0, 20.0, 50.0}, ""}; - ConfigurableAxis axisDeltaPt{"axisDeltaPt", {200, -500.0, 500.0}, ""}; // Invariant Mass - ConfigurableAxis axisSigmaMass{"axisSigmaMass", {1000, 1.10f, 1.30f}, "M_{#Sigma^{0}} (GeV/c^{2})"}; + ConfigurableAxis axisSigmaMass{"axisSigmaMass", {500, 1.10f, 1.30f}, "M_{#Sigma^{0}} (GeV/c^{2})"}; ConfigurableAxis axisLambdaMass{"axisLambdaMass", {200, 1.05f, 1.151f}, "M_{#Lambda} (GeV/c^{2})"}; - ConfigurableAxis axisPhotonMass{"axisPhotonMass", {600, -0.1f, 0.5f}, "M_{#Gamma}"}; + ConfigurableAxis axisPhotonMass{"axisPhotonMass", {200, -0.1f, 0.5f}, "M_{#Gamma}"}; + ConfigurableAxis axisPi0Mass{"axisPi0Mass", {200, 0.08f, 0.18f}, "M_{#Pi^{0}}"}; + ConfigurableAxis axisK0SMass{"axisK0SMass", {200, 0.4f, 0.6f}, "M_{K^{0}}"}; // AP plot axes ConfigurableAxis axisAPAlpha{"axisAPAlpha", {220, -1.1f, 1.1f}, "V0 AP alpha"}; @@ -165,16 +183,25 @@ struct sigma0builder { // topological variable QA axes ConfigurableAxis axisDCAtoPV{"axisDCAtoPV", {500, 0.0f, 50.0f}, "DCA (cm)"}; + ConfigurableAxis axisXY{"axisXY", {120, -120.0f, 120.0f}, "XY axis"}; ConfigurableAxis axisDCAdau{"axisDCAdau", {50, 0.0f, 5.0f}, "DCA (cm)"}; ConfigurableAxis axisRadius{"axisRadius", {240, 0.0f, 120.0f}, "V0 radius (cm)"}; + ConfigurableAxis axisPA{"axisPA", {100, 0.0f, 1}, "Pointing angle"}; ConfigurableAxis axisRapidity{"axisRapidity", {100, -2.0f, 2.0f}, "Rapidity"}; - ConfigurableAxis axisCandSel{"axisCandSel", {13, 0.5f, +13.5f}, "Candidate Selection"}; + ConfigurableAxis axisCandSel{"axisCandSel", {7, 0.5f, +7.5f}, "Candidate Selection"}; + ConfigurableAxis axisMonteCarloNch{"axisMonteCarloNch", {300, 0.0f, 3000.0f}, "N_{ch} MC"}; + ConfigurableAxis axisIRBinning{"axisIRBinning", {150, 0, 1500}, "Binning for the interaction rate (kHz)"}; int nSigmaCandidates = 0; void init(InitContext const&) { + // setting CCDB service + ccdb->setURL("http://alice-ccdb.cern.ch"); + ccdb->setCaching(true); + ccdb->setFatalWhenNull(false); + // Event Counters - histos.add("hEventSelection", "hEventSelection", kTH1F, {{20, -0.5f, +18.5f}}); + histos.add("hEventSelection", "hEventSelection", kTH1D, {{19, -0.5f, +18.5f}}); histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(1, "All collisions"); histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(2, "sel8 cut"); histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(3, "kIsTriggerTVX"); @@ -199,93 +226,121 @@ struct sigma0builder { histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(18, "Above max occup."); } - histos.add("hEventCentrality", "hEventCentrality", kTH1F, {axisCentrality}); - histos.add("hCandidateBuilderSelection", "hCandidateBuilderSelection", kTH1F, {axisCandSel}); - histos.get(HIST("hCandidateBuilderSelection"))->GetXaxis()->SetBinLabel(1, "No Sel"); - histos.get(HIST("hCandidateBuilderSelection"))->GetXaxis()->SetBinLabel(2, "Photon Mass Cut"); - histos.get(HIST("hCandidateBuilderSelection"))->GetXaxis()->SetBinLabel(3, "Photon DauEta Cut"); - histos.get(HIST("hCandidateBuilderSelection"))->GetXaxis()->SetBinLabel(4, "Photon DCAToPV Cut"); - histos.get(HIST("hCandidateBuilderSelection"))->GetXaxis()->SetBinLabel(5, "Photon DCADau Cut"); - histos.get(HIST("hCandidateBuilderSelection"))->GetXaxis()->SetBinLabel(6, "Photon Radius Cut"); - histos.get(HIST("hCandidateBuilderSelection"))->GetXaxis()->SetBinLabel(7, "Lambda Mass Cut"); - histos.get(HIST("hCandidateBuilderSelection"))->GetXaxis()->SetBinLabel(8, "Lambda DauEta Cut"); - histos.get(HIST("hCandidateBuilderSelection"))->GetXaxis()->SetBinLabel(9, "Lambda DCAToPV Cut"); - histos.get(HIST("hCandidateBuilderSelection"))->GetXaxis()->SetBinLabel(10, "Lambda Radius Cut"); - histos.get(HIST("hCandidateBuilderSelection"))->GetXaxis()->SetBinLabel(11, "Lambda DCADau Cut"); - histos.get(HIST("hCandidateBuilderSelection"))->GetXaxis()->SetBinLabel(12, "Sigma Mass Window"); - histos.get(HIST("hCandidateBuilderSelection"))->GetXaxis()->SetBinLabel(13, "Sigma Y Window"); - - // For QA: - histos.add("Selection/hPhotonMass", "hPhotonMass", kTH1F, {axisPhotonMass}); - histos.add("Selection/hPhotonNegEta", "hPhotonNegEta", kTH1F, {axisRapidity}); - histos.add("Selection/hPhotonPosEta", "hPhotonPosEta", kTH1F, {axisRapidity}); - histos.add("Selection/hPhotonDCANegToPV", "hPhotonDCANegToPV", kTH1F, {axisDCAtoPV}); - histos.add("Selection/hPhotonDCAPosToPV", "hPhotonDCAPosToPV", kTH1F, {axisDCAtoPV}); - histos.add("Selection/hPhotonDCADau", "hPhotonDCADau", kTH1F, {axisDCAdau}); - histos.add("Selection/hPhotonRadius", "hPhotonRadius", kTH1F, {axisRadius}); - histos.add("Selection/hLambdaMass", "hLambdaMass", kTH1F, {axisLambdaMass}); - histos.add("Selection/hAntiLambdaMass", "hAntiLambdaMass", kTH1F, {axisLambdaMass}); - histos.add("Selection/hLambdaNegEta", "hLambdaNegEta", kTH1F, {axisRapidity}); - histos.add("Selection/hLambdaPosEta", "hLambdaPosEta", kTH1F, {axisRapidity}); - histos.add("Selection/hLambdaDCANegToPV", "hLambdaDCANegToPV", kTH1F, {axisDCAtoPV}); - histos.add("Selection/hLambdaDCAPosToPV", "hLambdaDCAPosToPV", kTH1F, {axisDCAtoPV}); - histos.add("Selection/hLambdaDCADau", "hLambdaDCADau", kTH1F, {axisDCAdau}); - histos.add("Selection/hLambdaRadius", "hLambdaRadius", kTH1F, {axisRadius}); - histos.add("Selection/hSigmaMass", "hSigmaMass", kTH1F, {axisSigmaMass}); - histos.add("Selection/hSigmaMassWindow", "hSigmaMassWindow", kTH1F, {{1000, -0.09f, 0.11f}}); - histos.add("Selection/hSigmaY", "hSigmaY", kTH1F, {axisRapidity}); - - histos.add("GeneralQA/h2dMassGammaVsK0S", "h2dMassGammaVsK0S", kTH2D, {axisPhotonMass, {200, 0.4f, 0.6f}}); - histos.add("GeneralQA/h2dMassLambdaVsK0S", "h2dMassLambdaVsK0S", kTH2D, {axisLambdaMass, {200, 0.4f, 0.6f}}); - histos.add("GeneralQA/h2dMassGammaVsLambda", "h2dMassGammaVsLambda", kTH2D, {axisPhotonMass, axisLambdaMass}); - histos.add("GeneralQA/h3dMassSigma0VsDaupTs", "h3dMassSigma0VsDaupTs", kTH3F, {axisPt, axisPt, axisSigmaMass}); - histos.add("GeneralQA/h2dMassGammaVsK0SAfterMassSel", "h2dMassGammaVsK0SAfterMassSel", kTH2D, {axisPhotonMass, {200, 0.4f, 0.6f}}); - histos.add("GeneralQA/h2dMassLambdaVsK0SAfterMassSel", "h2dMassLambdaVsK0SAfterMassSel", kTH2D, {axisLambdaMass, {200, 0.4f, 0.6f}}); - histos.add("GeneralQA/h2dMassGammaVsLambdaAfterMassSel", "h2dMassGammaVsLambdaAfterMassSel", kTH2D, {axisPhotonMass, axisLambdaMass}); - histos.add("GeneralQA/h2dPtVsMassPi0BeforeSel_Candidates", "h2dPtVsMassPi0BeforeSel_Candidates", kTH2D, {axisPt, {500, 0.08f, 0.18f}}); - histos.add("GeneralQA/h2dPtVsMassPi0AfterSel_Candidates", "h2dPtVsMassPi0AfterSel_Candidates", kTH2D, {axisPt, {500, 0.08f, 0.18f}}); - histos.add("GeneralQA/h3dV0XYZ", "h3dV0XYZ", kTH3F, {{400, -200, 200}, {400, -200, 200}, {240, -120.0f, 120.0f}}); + histos.add("hEventCentrality", "hEventCentrality", kTH1D, {axisCentrality}); + + histos.add("PhotonSel/hSelectionStatistics", "hSelectionStatistics", kTH1D, {axisCandSel}); + histos.get(HIST("PhotonSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(1, "No Sel"); + histos.get(HIST("PhotonSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(2, "Photon Mass Cut"); + histos.get(HIST("PhotonSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(3, "Photon DauEta Cut"); + histos.get(HIST("PhotonSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(4, "Photon DCAToPV Cut"); + histos.get(HIST("PhotonSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(5, "Photon DCADau Cut"); + histos.get(HIST("PhotonSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(6, "Photon Radius Cut"); + + histos.add("PhotonSel/hPhotonMass", "hPhotonMass", kTH1F, {axisPhotonMass}); + histos.add("PhotonSel/hPhotonNegEta", "hPhotonNegEta", kTH1F, {axisRapidity}); + histos.add("PhotonSel/hPhotonPosEta", "hPhotonPosEta", kTH1F, {axisRapidity}); + histos.add("PhotonSel/hPhotonDCANegToPV", "hPhotonDCANegToPV", kTH1F, {axisDCAtoPV}); + histos.add("PhotonSel/hPhotonDCAPosToPV", "hPhotonDCAPosToPV", kTH1F, {axisDCAtoPV}); + histos.add("PhotonSel/hPhotonDCADau", "hPhotonDCADau", kTH1F, {axisDCAdau}); + histos.add("PhotonSel/hPhotonRadius", "hPhotonRadius", kTH1F, {axisRadius}); + + histos.add("LambdaSel/hSelectionStatistics", "hSelectionStatistics", kTH1D, {axisCandSel}); + histos.get(HIST("LambdaSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(1, "No Sel"); + histos.get(HIST("LambdaSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(2, "Lambda Mass Cut"); + histos.get(HIST("LambdaSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(3, "Lambda DauEta Cut"); + histos.get(HIST("LambdaSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(4, "Lambda DCAToPV Cut"); + histos.get(HIST("LambdaSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(5, "Lambda Radius Cut"); + histos.get(HIST("LambdaSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(6, "Lambda DCADau Cut"); + + histos.add("LambdaSel/hLambdaMass", "hLambdaMass", kTH1F, {axisLambdaMass}); + histos.add("LambdaSel/hAntiLambdaMass", "hAntiLambdaMass", kTH1F, {axisLambdaMass}); + histos.add("LambdaSel/hLambdaNegEta", "hLambdaNegEta", kTH1F, {axisRapidity}); + histos.add("LambdaSel/hLambdaPosEta", "hLambdaPosEta", kTH1F, {axisRapidity}); + histos.add("LambdaSel/hLambdaDCANegToPV", "hLambdaDCANegToPV", kTH1F, {axisDCAtoPV}); + histos.add("LambdaSel/hLambdaDCAPosToPV", "hLambdaDCAPosToPV", kTH1F, {axisDCAtoPV}); + histos.add("LambdaSel/hLambdaDCADau", "hLambdaDCADau", kTH1F, {axisDCAdau}); + histos.add("LambdaSel/hLambdaRadius", "hLambdaRadius", kTH1F, {axisRadius}); + + histos.add("SigmaSel/hSelectionStatistics", "hSelectionStatistics", kTH1D, {axisCandSel}); + histos.get(HIST("SigmaSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(1, "No Sel"); + histos.get(HIST("SigmaSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(2, "Sigma Mass Window"); + histos.get(HIST("SigmaSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(3, "Sigma Y Window"); + + // For selection: + histos.add("SigmaSel/h3dMassSigma0BeforeSel", "h3dMassSigma0BeforeSel", kTH3F, {axisCentrality, axisPt, axisSigmaMass}); + histos.add("SigmaSel/hSigmaMass", "hSigmaMass", kTH1F, {axisSigmaMass}); + histos.add("SigmaSel/hSigmaMassWindow", "hSigmaMassWindow", kTH1F, {{200, -0.09f, 0.11f}}); + histos.add("SigmaSel/hSigmaY", "hSigmaY", kTH1F, {axisRapidity}); + histos.add("SigmaSel/hSigmaMassSelected", "hSigmaMassSelected", kTH1F, {axisSigmaMass}); + histos.add("SigmaSel/h3dMassSigma0AfterSel", "h3dMassSigma0AfterSel", kTH3F, {axisCentrality, axisPt, axisSigmaMass}); + + if (fillQAhistos) { + histos.add("GeneralQA/h2dMassGammaVsK0S", "h2dMassGammaVsK0S", kTH2D, {axisPhotonMass, axisK0SMass}); + histos.add("GeneralQA/h2dMassLambdaVsK0S", "h2dMassLambdaVsK0S", kTH2D, {axisLambdaMass, axisK0SMass}); + histos.add("GeneralQA/h2dMassGammaVsLambda", "h2dMassGammaVsLambda", kTH2D, {axisPhotonMass, axisLambdaMass}); + histos.add("GeneralQA/h2dMassLambdaVsGamma", "h2dMassLambdaVsGamma", kTH2D, {axisLambdaMass, axisPhotonMass}); + histos.add("GeneralQA/h3dMassSigma0VsDaupTs", "h3dMassSigma0VsDaupTs", kTH3F, {axisPt, axisPt, axisSigmaMass}); + histos.add("GeneralQA/h2dMassGammaVsK0SAfterMassSel", "h2dMassGammaVsK0SAfterMassSel", kTH2D, {axisPhotonMass, axisK0SMass}); + histos.add("GeneralQA/h2dMassLambdaVsK0SAfterMassSel", "h2dMassLambdaVsK0SAfterMassSel", kTH2D, {axisLambdaMass, axisK0SMass}); + histos.add("GeneralQA/h2dMassGammaVsLambdaAfterMassSel", "h2dMassGammaVsLambdaAfterMassSel", kTH2D, {axisPhotonMass, axisLambdaMass}); + histos.add("GeneralQA/h2dV0XY", "h2dV0XY", kTH2F, {axisXY, axisXY}); + } + + if (fGetIR) { + histos.add("GeneralQA/hRunNumberNegativeIR", "", kTH1D, {{1, 0., 1.}}); + histos.add("GeneralQA/hInteractionRate", "hInteractionRate", kTH1F, {axisIRBinning}); + histos.add("GeneralQA/hCentralityVsInteractionRate", "hCentralityVsInteractionRate", kTH2F, {axisCentrality, axisIRBinning}); + } + + if (doAssocStudy && doprocessMonteCarlo) { + histos.add("V0AssoQA/h2dIRVsPt_TrueGamma", "h2dIRVsPt_TrueGamma", kTH2F, {axisIRBinning, axisPt}); + histos.add("V0AssoQA/h3dPAVsIRVsPt_TrueGamma", "h3dPAVsIRVsPt_TrueGamma", kTH3F, {axisPA, axisIRBinning, axisPt}); + histos.add("V0AssoQA/h2dIRVsPt_TrueGamma_BadCollAssig", "h2dIRVsPt_TrueGamma_BadCollAssig", kTH2F, {axisIRBinning, axisPt}); + histos.add("V0AssoQA/h3dPAVsIRVsPt_TrueGamma_BadCollAssig", "h3dPAVsIRVsPt_TrueGamma_BadCollAssig", kTH3F, {axisPA, axisIRBinning, axisPt}); + + histos.add("V0AssoQA/h2dIRVsPt_TrueLambda", "h2dIRVsPt_TrueLambda", kTH2F, {axisIRBinning, axisPt}); + histos.add("V0AssoQA/h3dPAVsIRVsPt_TrueLambda", "h3dPAVsIRVsPt_TrueLambda", kTH3F, {axisPA, axisIRBinning, axisPt}); + histos.add("V0AssoQA/h2dIRVsPt_TrueLambda_BadCollAssig", "h2dIRVsPt_TrueLambda_BadCollAssig", kTH2F, {axisIRBinning, axisPt}); + histos.add("V0AssoQA/h3dPAVsIRVsPt_TrueLambda_BadCollAssig", "h3dPAVsIRVsPt_TrueLambda_BadCollAssig", kTH3F, {axisPA, axisIRBinning, axisPt}); + } // MC - histos.add("MC/h2dPtVsCentrality_GammaBeforeSel", "h2dPtVsCentrality_GammaBeforeSel", kTH2D, {axisCentrality, axisPt}); - histos.add("MC/h2dPtVsCentrality_LambdaBeforeSel", "h2dPtVsCentrality_LambdaBeforeSel", kTH2D, {axisCentrality, axisPt}); - histos.add("MC/h2dPtVsCentrality_AntiLambdaBeforeSel", "h2dPtVsCentrality_AntiLambdaBeforeSel", kTH2D, {axisCentrality, axisPt}); - histos.add("MC/h2dPtVsCentrality_GammaSigma0", "h2dPtVsCentrality_GammaSigma0", kTH2D, {axisCentrality, axisPt}); - histos.add("MC/h2dPtVsCentrality_LambdaSigma0", "h2dPtVsCentrality_LambdaSigma0", kTH2D, {axisCentrality, axisPt}); - histos.add("MC/h2dPtVsCentrality_Sigma0BeforeSel", "h2dPtVsCentrality_Sigma0BeforeSel", kTH2D, {axisCentrality, axisPt}); - histos.add("MC/h2dPtVsCentrality_Sigma0AfterSel", "h2dPtVsCentrality_Sigma0AfterSel", kTH2D, {axisCentrality, axisPt}); - histos.add("MC/h2dPtVsCentrality_AntiSigma0BeforeSel", "h2dPtVsCentrality_AntiSigma0BeforeSel", kTH2D, {axisCentrality, axisPt}); - histos.add("MC/h2dPtVsCentrality_GammaAntiSigma0", "h2dPtVsCentrality_GammaAntiSigma0", kTH2D, {axisCentrality, axisPt}); - histos.add("MC/h2dPtVsCentrality_LambdaAntiSigma0", "h2dPtVsCentrality_LambdaAntiSigma0", kTH2D, {axisCentrality, axisPt}); - histos.add("MC/h2dPtVsCentrality_AntiSigma0AfterSel", "h2dPtVsCentrality_AntiSigma0AfterSel", kTH2D, {axisCentrality, axisPt}); - histos.add("MC/h3dGammasXYZ", "h3dGammasXYZ", kTH3F, {{400, -200, 200}, {400, -200, 200}, {240, -120.0f, 120.0f}}); - - // Sigma vs Daughters pT - histos.add("MC/h2dSigmaPtVsLambdaPt", "h2dSigmaPtVsLambdaPt", kTH2D, {axisPt, axisPt}); - histos.add("MC/h2dSigmaPtVsGammaPt", "h2dSigmaPtVsGammaPt", kTH2D, {axisPt, axisPt}); - - // pT Resolution: - histos.add("MC/h2dLambdaPtResolution", "h2dLambdaPtResolution", kTH2D, {axisInvPt, axisDeltaPt}); - histos.add("MC/h2dGammaPtResolution", "h2dGammaPtResolution", kTH2D, {axisInvPt, axisDeltaPt}); + if (doprocessMonteCarlo) { + histos.add("MC/h2dPtVsCentralityBeforeSel_MCAssocGamma", "h2dPtVsCentralityBeforeSel_MCAssocGamma", kTH2D, {axisCentrality, axisPt}); + histos.add("MC/h2dPtVsCentralityBeforeSel_MCAssocLambda", "h2dPtVsCentralityBeforeSel_MCAssocLambda", kTH2D, {axisCentrality, axisPt}); + histos.add("MC/h2dPtVsCentralityBeforeSel_MCAssocALambda", "h2dPtVsCentralityBeforeSel_MCAssocALambda", kTH2D, {axisCentrality, axisPt}); + histos.add("MC/h2dPtVsCentralityBeforeSel_MCAssocSigma0", "h2dPtVsCentralityBeforeSel_MCAssocSigma0", kTH2D, {axisCentrality, axisPt}); + histos.add("MC/h2dPtVsCentralityBeforeSel_MCAssocASigma0", "h2dPtVsCentralityBeforeSel_MCAssocASigma0", kTH2D, {axisCentrality, axisPt}); + histos.add("MC/h2dSigma0PtVsLambdaPtBeforeSel_MCAssoc", "h2dSigma0PtVsLambdaPtBeforeSel_MCAssoc", kTH2D, {axisPt, axisPt}); + histos.add("MC/h2dSigma0PtVsGammaPtBeforeSel_MCAssoc", "h2dSigma0PtVsGammaPtBeforeSel_MCAssoc", kTH2D, {axisPt, axisPt}); + histos.add("MC/h2dPtVsCentralityAfterSel_MCAssocSigma0", "h2dPtVsCentralityAfterSel_MCAssocSigma0", kTH2D, {axisCentrality, axisPt}); + histos.add("MC/h2dPtVsCentralityAfterSel_MCAssocASigma0", "h2dPtVsCentralityAfterSel_MCAssocASigma0", kTH2D, {axisCentrality, axisPt}); + histos.add("MC/h2dGammaXYConversion", "h2dGammaXYConversion", kTH2F, {axisXY, axisXY}); + } // For background decomposition - histos.add("MC/h2dPtVsMassSigma_All", "h2dPtVsMassSigma_All", kTH2D, {axisPt, axisSigmaMass}); - histos.add("MC/h2dPtVsMassSigma_SignalOnly", "h2dPtVsMassSigma_SignalOnly", kTH2D, {axisPt, axisSigmaMass}); - histos.add("MC/h2dPtVsMassSigma_TrueDaughters", "h2dPtVsMassSigma_TrueDaughters", kTH2D, {axisPt, axisSigmaMass}); - histos.add("MC/h2dPtVsMassSigma_TrueGammaFakeLambda", "h2dPtVsMassSigma_TrueGammaFakeLambda", kTH2D, {axisPt, axisSigmaMass}); - histos.add("MC/h2dPtVsMassSigma_FakeGammaTrueLambda", "h2dPtVsMassSigma_FakeGammaTrueLambda", kTH2D, {axisPt, axisSigmaMass}); - histos.add("MC/h2dPtVsMassSigma_FakeDaughters", "h2dPtVsMassSigma_FakeDaughters", kTH2D, {axisPt, axisSigmaMass}); - histos.add("MC/h2dTrueDaughtersMatrix", "h2dTrueDaughtersMatrix", kTHnSparseD, {{10001, -5000.5f, +5000.5f}, {10001, -5000.5f, +5000.5f}}); - histos.add("MC/h2dTrueGammaFakeLambdaMatrix", "h2dTrueGammaFakeLambdaMatrix", kTHnSparseD, {{10001, -5000.5f, +5000.5f}, {10001, -5000.5f, +5000.5f}}); - histos.add("MC/h2dFakeGammaTrueLambdaMatrix", "h2dFakeGammaTrueLambdaMatrix", kTHnSparseD, {{10001, -5000.5f, +5000.5f}, {10001, -5000.5f, +5000.5f}}); - histos.add("MC/h2dFakeDaughtersMatrix", "h2dFakeDaughtersMatrix", kTHnSparseD, {{10001, -5000.5f, +5000.5f}, {10001, -5000.5f, +5000.5f}}); + if (fillBkgQAhistos && doprocessMonteCarlo) { + histos.add("BkgStudy/h2dPtVsMassSigma_All", "h2dPtVsMassSigma_All", kTH2D, {axisPt, axisSigmaMass}); + histos.add("BkgStudy/h2dPtVsMassSigma_TrueDaughters", "h2dPtVsMassSigma_TrueDaughters", kTH2D, {axisPt, axisSigmaMass}); + histos.add("BkgStudy/h2dPtVsMassSigma_TrueGammaFakeLambda", "h2dPtVsMassSigma_TrueGammaFakeLambda", kTH2D, {axisPt, axisSigmaMass}); + histos.add("BkgStudy/h2dPtVsMassSigma_FakeGammaTrueLambda", "h2dPtVsMassSigma_FakeGammaTrueLambda", kTH2D, {axisPt, axisSigmaMass}); + histos.add("BkgStudy/h2dPtVsMassSigma_FakeDaughters", "h2dPtVsMassSigma_FakeDaughters", kTH2D, {axisPt, axisSigmaMass}); + histos.add("BkgStudy/h2dTrueDaughtersMatrix", "h2dTrueDaughtersMatrix", kTHnSparseD, {{10001, -5000.5f, +5000.5f}, {10001, -5000.5f, +5000.5f}}); + histos.add("BkgStudy/h2dTrueGammaFakeLambdaMatrix", "h2dTrueGammaFakeLambdaMatrix", kTHnSparseD, {{10001, -5000.5f, +5000.5f}, {10001, -5000.5f, +5000.5f}}); + histos.add("BkgStudy/h2dFakeGammaTrueLambdaMatrix", "h2dFakeGammaTrueLambdaMatrix", kTHnSparseD, {{10001, -5000.5f, +5000.5f}, {10001, -5000.5f, +5000.5f}}); + histos.add("BkgStudy/h2dFakeDaughtersMatrix", "h2dFakeDaughtersMatrix", kTHnSparseD, {{10001, -5000.5f, +5000.5f}, {10001, -5000.5f, +5000.5f}}); + } // For Pi0 QA - histos.add("MC/h2dPtVsMassPi0BeforeSel_SignalOnly", "h2dPtVsMassPi0BeforeSel_SignalOnly", kTH2D, {axisPt, {500, 0.08f, 0.18f}}); - histos.add("MC/h2dPtVsMassPi0AfterSel_SignalOnly", "h2dPtVsMassPi0AfterSel_SignalOnly", kTH2D, {axisPt, {500, 0.08f, 0.18f}}); + if (doPi0QA) { + histos.add("Pi0QA/h2dPtVsMassPi0BeforeSel_MCAssoc", "h2dPtVsMassPi0BeforeSel_MCAssoc", kTH2D, {axisPt, axisPi0Mass}); + histos.add("Pi0QA/h2dPtVsMassPi0AfterSel_MCAssoc", "h2dPtVsMassPi0AfterSel_MCAssoc", kTH2D, {axisPt, axisPi0Mass}); + histos.add("Pi0QA/h2dPtVsMassPi0BeforeSel_Candidates", "h2dPtVsMassPi0BeforeSel_Candidates", kTH2D, {axisPt, axisPi0Mass}); + histos.add("Pi0QA/h2dPtVsMassPi0AfterSel_Candidates", "h2dPtVsMassPi0AfterSel_Candidates", kTH2D, {axisPt, axisPi0Mass}); + } - histos.add("h3dMassSigmasBeforeSel", "h3dMassSigmasBeforeSel", kTH3F, {axisCentrality, axisPt, axisSigmaMass}); - histos.add("h3dMassSigmasAfterSel", "h3dMassSigmasAfterSel", kTH3F, {axisCentrality, axisPt, axisSigmaMass}); + if (doprocessGeneratedCollRun3) + histos.add("Gen/hNEventsNch", "hNEventsNch", kTH1D, {axisMonteCarloNch}); } template @@ -396,15 +451,74 @@ struct sigma0builder { return true; } + void runBkgAnalysis(bool fIsSigma, bool fIsAntiSigma, int PhotonPDGCode, int PhotonPDGCodeMother, int LambdaPDGCode, int LambdaPDGCodeMother, float sigmapT, float sigmaMass) + { + histos.fill(HIST("BkgStudy/h2dPtVsMassSigma_All"), sigmapT, sigmaMass); + + // Real Gamma x Real Lambda - but not from the same sigma0/antisigma0! + if ((PhotonPDGCode == 22) && ((LambdaPDGCode == 3122) || (LambdaPDGCode == -3122)) && (!fIsSigma && !fIsAntiSigma)) { + histos.fill(HIST("BkgStudy/h2dPtVsMassSigma_TrueDaughters"), sigmapT, sigmaMass); + histos.fill(HIST("BkgStudy/h2dTrueDaughtersMatrix"), LambdaPDGCodeMother, PhotonPDGCodeMother); + } + + // Real Gamma x fake Lambda + if ((PhotonPDGCode == 22) && (LambdaPDGCode != 3122) && (LambdaPDGCode != -3122)) { + histos.fill(HIST("BkgStudy/h2dPtVsMassSigma_TrueGammaFakeLambda"), sigmapT, sigmaMass); + histos.fill(HIST("BkgStudy/h2dTrueGammaFakeLambdaMatrix"), LambdaPDGCodeMother, PhotonPDGCodeMother); + } + + // Fake Gamma x Real Lambda + if ((PhotonPDGCode != 22) && ((LambdaPDGCode == 3122) || (LambdaPDGCode == -3122))) { + histos.fill(HIST("BkgStudy/h2dPtVsMassSigma_FakeGammaTrueLambda"), sigmapT, sigmaMass); + histos.fill(HIST("BkgStudy/h2dFakeGammaTrueLambdaMatrix"), LambdaPDGCodeMother, PhotonPDGCodeMother); + } + + // Fake Gamma x Fake Lambda + if ((PhotonPDGCode != 22) && (LambdaPDGCode != 3122) && (LambdaPDGCode != -3122)) { + histos.fill(HIST("BkgStudy/h2dPtVsMassSigma_FakeDaughters"), sigmapT, sigmaMass); + histos.fill(HIST("BkgStudy/h2dFakeDaughtersMatrix"), LambdaPDGCodeMother, PhotonPDGCodeMother); + } + } + + template + void analyzeV0CollAssoc(TCollision const& collision, TV0Object const& fullv0s, std::vector selV0Indices, float IR) + { + auto v0MCCollision = collision.template straMCCollision_as>(); + + for (size_t i = 0; i < selV0Indices.size(); ++i) { + auto v0 = fullv0s.rawIteratorAt(selV0Indices[i]); + auto v0MC = v0.template v0MCCore_as>(); + + float V0MCpT = RecoDecay::pt(array{v0MC.pxMC(), v0MC.pyMC()}); + float V0PA = TMath::ACos(v0.v0cosPA()); + bool fIsV0CorrectlyAssigned = (v0MC.straMCCollisionId() == v0MCCollision.globalIndex()); + + if (v0MC.pdgCode() == 22) { // True Gamma + histos.fill(HIST("V0AssoQA/h2dIRVsPt_TrueGamma"), IR, V0MCpT); + histos.fill(HIST("V0AssoQA/h3dPAVsIRVsPt_TrueGamma"), V0PA, IR, V0MCpT); + + if (!fIsV0CorrectlyAssigned) { + histos.fill(HIST("V0AssoQA/h2dIRVsPt_TrueGamma_BadCollAssig"), IR, V0MCpT); + histos.fill(HIST("V0AssoQA/h3dPAVsIRVsPt_TrueGamma_BadCollAssig"), V0PA, IR, V0MCpT); + } + } + if (v0MC.pdgCode() == 3122) { // True Lambda + histos.fill(HIST("V0AssoQA/h2dIRVsPt_TrueLambda"), IR, V0MCpT); + histos.fill(HIST("V0AssoQA/h3dPAVsIRVsPt_TrueLambda"), V0PA, IR, V0MCpT); + + if (!fIsV0CorrectlyAssigned) { + histos.fill(HIST("V0AssoQA/h2dIRVsPt_TrueLambda_BadCollAssig"), IR, V0MCpT); + histos.fill(HIST("V0AssoQA/h3dPAVsIRVsPt_TrueLambda_BadCollAssig"), V0PA, IR, V0MCpT); + } + } + } + } template void runPi0QA(TV0Object const& gamma1, TV0Object const& gamma2) { - // Check if both V0s are made of the same tracks if (gamma1.posTrackExtraId() == gamma2.posTrackExtraId() || - gamma1.negTrackExtraId() == gamma2.negTrackExtraId() || - gamma1.posTrackExtraId() == gamma2.negTrackExtraId() || - gamma1.negTrackExtraId() == gamma2.posTrackExtraId()) { + gamma1.negTrackExtraId() == gamma2.negTrackExtraId()) { return; } @@ -430,13 +544,13 @@ struct sigma0builder { gamma1MC.pdgCodeMother() == 111 && gamma2MC.pdgCodeMother() == 111 && gamma1.motherMCPartId() == gamma2.motherMCPartId()) { fIsPi0 = true; - histos.fill(HIST("MC/h2dPtVsMassPi0BeforeSel_SignalOnly"), pi0Pt, pi0Mass); + histos.fill(HIST("Pi0QA/h2dPtVsMassPi0BeforeSel_MCAssoc"), pi0Pt, pi0Mass); } } - } else { - histos.fill(HIST("GeneralQA/h2dPtVsMassPi0BeforeSel_Candidates"), pi0Pt, pi0Mass); } + histos.fill(HIST("Pi0QA/h2dPtVsMassPi0BeforeSel_Candidates"), pi0Pt, pi0Mass); + // Photon-specific selections auto posTrackGamma1 = gamma1.template posTrackExtra_as(); auto negTrackGamma1 = gamma1.template negTrackExtra_as(); @@ -491,23 +605,16 @@ struct sigma0builder { } // Fill histograms - if (fIsMC) { - if (fIsPi0) - histos.fill(HIST("MC/h2dPtVsMassPi0AfterSel_SignalOnly"), pi0Pt, pi0Mass); - } else { - histos.fill(HIST("GeneralQA/h2dPtVsMassPi0AfterSel_Candidates"), pi0Pt, pi0Mass); - } + histos.fill(HIST("Pi0QA/h2dPtVsMassPi0AfterSel_Candidates"), pi0Pt, pi0Mass); + if (fIsMC && fIsPi0) + histos.fill(HIST("Pi0QA/h2dPtVsMassPi0AfterSel_MCAssoc"), pi0Pt, pi0Mass); } - // Process sigma candidate and store properties in object + // Process photon candidate template - bool processSigmaCandidate(TV0Object const& lambda, TV0Object const& gamma) + bool processPhotonCandidate(TV0Object const& gamma) { - if ((lambda.v0Type() == 0) || (gamma.v0Type() == 0)) - return false; - - // Checking if both V0s are made of the very same tracks - if ((gamma.posTrackExtraId() == lambda.posTrackExtraId()) || (gamma.negTrackExtraId() == lambda.negTrackExtraId()) || (gamma.posTrackExtraId() == lambda.negTrackExtraId()) || (gamma.negTrackExtraId() == lambda.posTrackExtraId()) || (gamma.posTrackExtraId() == lambda.negTrackExtraId())) + if (gamma.v0Type() == 0) return false; if (useMLScores) { @@ -515,120 +622,126 @@ struct sigma0builder { if (gamma.gammaBDTScore() <= Gamma_MLThreshold) return false; - // Lambda and AntiLambda selection - if ((lambda.lambdaBDTScore() <= Lambda_MLThreshold) && (lambda.antiLambdaBDTScore() <= AntiLambda_MLThreshold)) - return false; - } else { // Standard selection // Gamma basic selection criteria: - histos.fill(HIST("hCandidateBuilderSelection"), 1.); - histos.fill(HIST("Selection/hPhotonMass"), gamma.mGamma()); + histos.fill(HIST("PhotonSel/hSelectionStatistics"), 1.); + histos.fill(HIST("PhotonSel/hPhotonMass"), gamma.mGamma()); if ((gamma.mGamma() < 0) || (gamma.mGamma() > PhotonMaxMass)) return false; - histos.fill(HIST("Selection/hPhotonNegEta"), gamma.negativeeta()); - histos.fill(HIST("Selection/hPhotonPosEta"), gamma.positiveeta()); - histos.fill(HIST("hCandidateBuilderSelection"), 2.); + histos.fill(HIST("PhotonSel/hPhotonNegEta"), gamma.negativeeta()); + histos.fill(HIST("PhotonSel/hPhotonPosEta"), gamma.positiveeta()); + histos.fill(HIST("PhotonSel/hSelectionStatistics"), 2.); if ((TMath::Abs(gamma.negativeeta()) > PhotonMaxDauPseudoRap) || (TMath::Abs(gamma.positiveeta()) > PhotonMaxDauPseudoRap)) return false; - histos.fill(HIST("Selection/hPhotonDCANegToPV"), TMath::Abs(gamma.dcanegtopv())); - histos.fill(HIST("Selection/hPhotonDCAPosToPV"), TMath::Abs(gamma.dcapostopv())); - histos.fill(HIST("hCandidateBuilderSelection"), 3.); + histos.fill(HIST("PhotonSel/hPhotonDCANegToPV"), TMath::Abs(gamma.dcanegtopv())); + histos.fill(HIST("PhotonSel/hPhotonDCAPosToPV"), TMath::Abs(gamma.dcapostopv())); + histos.fill(HIST("PhotonSel/hSelectionStatistics"), 3.); if ((TMath::Abs(gamma.dcapostopv()) < PhotonMinDCAToPv) || (TMath::Abs(gamma.dcanegtopv()) < PhotonMinDCAToPv)) return false; - histos.fill(HIST("Selection/hPhotonDCADau"), TMath::Abs(gamma.dcaV0daughters())); - histos.fill(HIST("hCandidateBuilderSelection"), 4.); + histos.fill(HIST("PhotonSel/hPhotonDCADau"), TMath::Abs(gamma.dcaV0daughters())); + histos.fill(HIST("PhotonSel/hSelectionStatistics"), 4.); if (TMath::Abs(gamma.dcaV0daughters()) > PhotonMaxDCAV0Dau) return false; - histos.fill(HIST("Selection/hPhotonRadius"), gamma.v0radius()); - histos.fill(HIST("hCandidateBuilderSelection"), 5.); + histos.fill(HIST("PhotonSel/hPhotonRadius"), gamma.v0radius()); + histos.fill(HIST("PhotonSel/hSelectionStatistics"), 5.); if ((gamma.v0radius() < PhotonMinRadius) || (gamma.v0radius() > PhotonMaxRadius)) return false; + histos.fill(HIST("PhotonSel/hSelectionStatistics"), 6.); + } + return true; + } + + // Process photon candidate + template + bool processLambdaCandidate(TV0Object const& lambda) + { + if (lambda.v0Type() != 1) + return false; + + if (useMLScores) { + if ((lambda.lambdaBDTScore() <= Lambda_MLThreshold) && (lambda.antiLambdaBDTScore() <= AntiLambda_MLThreshold)) + return false; + } else { // Lambda basic selection criteria: - histos.fill(HIST("hCandidateBuilderSelection"), 6.); - histos.fill(HIST("Selection/hLambdaMass"), lambda.mLambda()); - histos.fill(HIST("Selection/hAntiLambdaMass"), lambda.mAntiLambda()); + histos.fill(HIST("LambdaSel/hSelectionStatistics"), 1.); + histos.fill(HIST("LambdaSel/hLambdaMass"), lambda.mLambda()); + histos.fill(HIST("LambdaSel/hAntiLambdaMass"), lambda.mAntiLambda()); if ((TMath::Abs(lambda.mLambda() - o2::constants::physics::MassLambda0) > LambdaWindow) && (TMath::Abs(lambda.mAntiLambda() - o2::constants::physics::MassLambda0) > LambdaWindow)) return false; - histos.fill(HIST("Selection/hLambdaNegEta"), lambda.negativeeta()); - histos.fill(HIST("Selection/hLambdaPosEta"), lambda.positiveeta()); - histos.fill(HIST("hCandidateBuilderSelection"), 7.); + histos.fill(HIST("LambdaSel/hLambdaNegEta"), lambda.negativeeta()); + histos.fill(HIST("LambdaSel/hLambdaPosEta"), lambda.positiveeta()); + histos.fill(HIST("LambdaSel/hSelectionStatistics"), 2.); if ((TMath::Abs(lambda.negativeeta()) > LambdaDauPseudoRap) || (TMath::Abs(lambda.positiveeta()) > LambdaDauPseudoRap)) return false; - histos.fill(HIST("Selection/hLambdaDCANegToPV"), lambda.dcanegtopv()); - histos.fill(HIST("Selection/hLambdaDCAPosToPV"), lambda.dcapostopv()); - histos.fill(HIST("hCandidateBuilderSelection"), 8.); + histos.fill(HIST("LambdaSel/hLambdaDCANegToPV"), lambda.dcanegtopv()); + histos.fill(HIST("LambdaSel/hLambdaDCAPosToPV"), lambda.dcapostopv()); + histos.fill(HIST("LambdaSel/hSelectionStatistics"), 3.); if ((TMath::Abs(lambda.dcapostopv()) < LambdaMinDCAPosToPv) || (TMath::Abs(lambda.dcanegtopv()) < LambdaMinDCANegToPv)) return false; - histos.fill(HIST("Selection/hLambdaRadius"), lambda.v0radius()); - histos.fill(HIST("hCandidateBuilderSelection"), 9.); + histos.fill(HIST("LambdaSel/hLambdaRadius"), lambda.v0radius()); + histos.fill(HIST("LambdaSel/hSelectionStatistics"), 4.); if ((lambda.v0radius() < LambdaMinv0radius) || (lambda.v0radius() > LambdaMaxv0radius)) return false; - histos.fill(HIST("Selection/hLambdaDCADau"), lambda.dcaV0daughters()); - histos.fill(HIST("hCandidateBuilderSelection"), 10.); + histos.fill(HIST("LambdaSel/hLambdaDCADau"), lambda.dcaV0daughters()); + histos.fill(HIST("LambdaSel/hSelectionStatistics"), 5.); if (TMath::Abs(lambda.dcaV0daughters()) > LambdaMaxDCAV0Dau) return false; - histos.fill(HIST("hCandidateBuilderSelection"), 11.); + histos.fill(HIST("LambdaSel/hSelectionStatistics"), 6.); + } + + return true; + } + /////////// + // Process sigma candidate and store properties in object + template + bool buildSigma0(TV0Object const& lambda, TV0Object const& gamma) + { + // Checking if both V0s are made of the very same tracks + if (gamma.posTrackExtraId() == lambda.posTrackExtraId() || + gamma.negTrackExtraId() == lambda.negTrackExtraId()) { + return false; } + // Sigma0 candidate properties std::array pVecPhotons{gamma.px(), gamma.py(), gamma.pz()}; std::array pVecLambda{lambda.px(), lambda.py(), lambda.pz()}; auto arrMom = std::array{pVecPhotons, pVecLambda}; float sigmamass = RecoDecay::m(arrMom, std::array{o2::constants::physics::MassPhoton, o2::constants::physics::MassLambda0}); float sigmarap = RecoDecay::y(std::array{gamma.px() + lambda.px(), gamma.py() + lambda.py(), gamma.pz() + lambda.pz()}, o2::constants::physics::MassSigma0); - float SigmapT = RecoDecay::pt(array{gamma.px() + lambda.px(), gamma.py() + lambda.py()}); - - histos.fill(HIST("Selection/hSigmaMass"), sigmamass); - histos.fill(HIST("Selection/hSigmaMassWindow"), sigmamass - 1.192642); - histos.fill(HIST("GeneralQA/h2dMassGammaVsK0S"), gamma.mGamma(), gamma.mK0Short()); - histos.fill(HIST("GeneralQA/h2dMassLambdaVsK0S"), lambda.mLambda(), lambda.mK0Short()); - histos.fill(HIST("GeneralQA/h2dMassGammaVsLambda"), gamma.mGamma(), lambda.mLambda()); - histos.fill(HIST("GeneralQA/h3dMassSigma0VsDaupTs"), gamma.pt(), lambda.pt(), sigmamass); - - if constexpr (requires { gamma.pdgCode(); } && requires { lambda.pdgCode(); }) { - - histos.fill(HIST("MC/h2dPtVsMassSigma_All"), SigmapT, sigmamass); - - // Real Gamma x Real Lambda - but not from the same sigma0/antisigma0! - if ((gamma.pdgCode() == 22) && ((lambda.pdgCode() == 3122) || (lambda.pdgCode() == -3122)) && (gamma.motherMCPartId() != lambda.motherMCPartId())) { - histos.fill(HIST("MC/h2dPtVsMassSigma_TrueDaughters"), SigmapT, sigmamass); - histos.fill(HIST("MC/h2dTrueDaughtersMatrix"), lambda.pdgCodeMother(), gamma.pdgCodeMother()); - } - - // Real Gamma x fake Lambda - if ((gamma.pdgCode() == 22) && (lambda.pdgCode() != 3122) && (lambda.pdgCode() != -3122)) { - histos.fill(HIST("MC/h2dPtVsMassSigma_TrueGammaFakeLambda"), SigmapT, sigmamass); - histos.fill(HIST("MC/h2dTrueGammaFakeLambdaMatrix"), lambda.pdgCodeMother(), gamma.pdgCodeMother()); - } - // Fake Gamma x Real Lambda - if ((gamma.pdgCode() != 22) && ((lambda.pdgCode() == 3122) || (lambda.pdgCode() == -3122))) { - histos.fill(HIST("MC/h2dPtVsMassSigma_FakeGammaTrueLambda"), SigmapT, sigmamass); - histos.fill(HIST("MC/h2dFakeGammaTrueLambdaMatrix"), lambda.pdgCodeMother(), gamma.pdgCodeMother()); - } + histos.fill(HIST("SigmaSel/hSelectionStatistics"), 1.); + histos.fill(HIST("SigmaSel/hSigmaMass"), sigmamass); + histos.fill(HIST("SigmaSel/hSigmaMassWindow"), sigmamass - 1.192642); - // Fake Gamma x Fake Lambda - if ((gamma.pdgCode() != 22) && (lambda.pdgCode() != 3122) && (lambda.pdgCode() != -3122)) { - histos.fill(HIST("MC/h2dPtVsMassSigma_FakeDaughters"), SigmapT, sigmamass); - histos.fill(HIST("MC/h2dFakeDaughtersMatrix"), lambda.pdgCodeMother(), gamma.pdgCodeMother()); - } + if (fillQAhistos) { + histos.fill(HIST("GeneralQA/h2dMassGammaVsK0S"), gamma.mGamma(), gamma.mK0Short()); + histos.fill(HIST("GeneralQA/h2dMassLambdaVsK0S"), lambda.mLambda(), lambda.mK0Short()); + histos.fill(HIST("GeneralQA/h2dMassGammaVsLambda"), gamma.mGamma(), gamma.mLambda()); + histos.fill(HIST("GeneralQA/h2dMassLambdaVsGamma"), lambda.mLambda(), lambda.mGamma()); + histos.fill(HIST("GeneralQA/h3dMassSigma0VsDaupTs"), gamma.pt(), lambda.pt(), sigmamass); } if (TMath::Abs(sigmamass - 1.192642) > Sigma0Window) return false; - histos.fill(HIST("GeneralQA/h2dMassGammaVsK0SAfterMassSel"), gamma.mGamma(), gamma.mK0Short()); - histos.fill(HIST("GeneralQA/h2dMassLambdaVsK0SAfterMassSel"), lambda.mLambda(), lambda.mK0Short()); - histos.fill(HIST("GeneralQA/h2dMassGammaVsLambdaAfterMassSel"), gamma.mGamma(), lambda.mLambda()); - histos.fill(HIST("Selection/hSigmaY"), sigmarap); - histos.fill(HIST("hCandidateBuilderSelection"), 12.); + histos.fill(HIST("SigmaSel/hSigmaY"), sigmarap); + histos.fill(HIST("SigmaSel/hSelectionStatistics"), 2.); if (TMath::Abs(sigmarap) > SigmaMaxRap) return false; - histos.fill(HIST("hCandidateBuilderSelection"), 13.); - histos.fill(HIST("GeneralQA/h3dV0XYZ"), gamma.x(), gamma.y(), gamma.z()); + histos.fill(HIST("SigmaSel/hSigmaMassSelected"), sigmamass); + histos.fill(HIST("SigmaSel/hSelectionStatistics"), 3.); + + if (fillQAhistos) { + histos.fill(HIST("GeneralQA/h2dMassGammaVsK0SAfterMassSel"), gamma.mGamma(), gamma.mK0Short()); + histos.fill(HIST("GeneralQA/h2dMassLambdaVsK0SAfterMassSel"), lambda.mLambda(), lambda.mK0Short()); + histos.fill(HIST("GeneralQA/h2dMassGammaVsLambdaAfterMassSel"), gamma.mGamma(), lambda.mLambda()); + histos.fill(HIST("GeneralQA/h2dV0XY"), gamma.x(), gamma.y()); + } + return true; } @@ -636,7 +749,6 @@ struct sigma0builder { template void fillTables(TV0Object const& lambda, TV0Object const& gamma, TCollision const& coll) { - float GammaBDTScore = gamma.gammaBDTScore(); float LambdaBDTScore = lambda.lambdaBDTScore(); float AntiLambdaBDTScore = lambda.antiLambdaBDTScore(); @@ -678,6 +790,18 @@ struct sigma0builder { float fPhotonNegITSChi2PerNcl = negTrackGamma.itsChi2PerNcl(); uint8_t fPhotonV0Type = gamma.v0Type(); + uint8_t fPhotonPosTrackCode = ((uint8_t(posTrackGamma.hasTPC()) << hasTPC) | + (uint8_t(posTrackGamma.hasITSTracker()) << hasITSTracker) | + (uint8_t(posTrackGamma.hasITSAfterburner()) << hasITSAfterburner) | + (uint8_t(posTrackGamma.hasTRD()) << hasTRD) | + (uint8_t(posTrackGamma.hasTOF()) << hasTOF)); + + uint8_t fPhotonNegTrackCode = ((uint8_t(negTrackGamma.hasTPC()) << hasTPC) | + (uint8_t(negTrackGamma.hasITSTracker()) << hasITSTracker) | + (uint8_t(negTrackGamma.hasITSAfterburner()) << hasITSAfterburner) | + (uint8_t(negTrackGamma.hasTRD()) << hasTRD) | + (uint8_t(negTrackGamma.hasTOF()) << hasTOF)); + // Lambda auto posTrackLambda = lambda.template posTrackExtra_as(); auto negTrackLambda = lambda.template negTrackExtra_as(); @@ -722,6 +846,18 @@ struct sigma0builder { float fLambdaNegITSChi2PerNcl = negTrackLambda.itsChi2PerNcl(); uint8_t fLambdaV0Type = lambda.v0Type(); + uint8_t fLambdaPosTrackCode = ((uint8_t(posTrackLambda.hasTPC()) << hasTPC) | + (uint8_t(posTrackLambda.hasITSTracker()) << hasITSTracker) | + (uint8_t(posTrackLambda.hasITSAfterburner()) << hasITSAfterburner) | + (uint8_t(posTrackLambda.hasTRD()) << hasTRD) | + (uint8_t(posTrackLambda.hasTOF()) << hasTOF)); + + uint8_t fLambdaNegTrackCode = ((uint8_t(negTrackLambda.hasTPC()) << hasTPC) | + (uint8_t(negTrackLambda.hasITSTracker()) << hasITSTracker) | + (uint8_t(negTrackLambda.hasITSAfterburner()) << hasITSAfterburner) | + (uint8_t(negTrackLambda.hasTRD()) << hasTRD) | + (uint8_t(negTrackLambda.hasTOF()) << hasTOF)); + // Sigma0 candidate properties std::array pVecPhotons{gamma.px(), gamma.py(), gamma.pz()}; std::array pVecLambda{lambda.px(), lambda.py(), lambda.pz()}; @@ -735,18 +871,22 @@ struct sigma0builder { float fSigmaRap = RecoDecay::y(std::array{gamma.px() + lambda.px(), gamma.py() + lambda.py(), gamma.pz() + lambda.pz()}, o2::constants::physics::MassSigma0); float fSigmaOPAngle = v1.Angle(v2); float fSigmaCentrality = coll.centFT0C(); - float fSigmaTimeStamp = coll.timestamp(); - float fSigmaRunNumber = coll.runNumber(); + uint64_t fSigmaTimeStamp = coll.timestamp(); + int fSigmaRunNumber = coll.runNumber(); + float fSigmaIR = -1; + + if (fGetIR) + fSigmaIR = rateFetcher.fetch(ccdb.service, coll.timestamp(), coll.runNumber(), irSource, fIRCrashOnNull) * 1.e-3; // Filling TTree for ML analysis - sigma0cores(fSigmapT, fSigmaMass, fSigmaRap, fSigmaOPAngle, fSigmaCentrality, fSigmaRunNumber, fSigmaTimeStamp); + sigma0cores(fSigmapT, fSigmaMass, fSigmaRap, fSigmaOPAngle, fSigmaCentrality, fSigmaRunNumber, fSigmaTimeStamp, fSigmaIR); sigmaPhotonExtras(fPhotonPt, fPhotonMass, fPhotonQt, fPhotonAlpha, fPhotonRadius, fPhotonCosPA, fPhotonDCADau, fPhotonDCANegPV, fPhotonDCAPosPV, fPhotonZconv, fPhotonEta, fPhotonY, fPhotonPhi, fPhotonPosTPCNSigmaEl, fPhotonNegTPCNSigmaEl, fPhotonPosTPCNSigmaPi, fPhotonNegTPCNSigmaPi, fPhotonPosTPCCrossedRows, fPhotonNegTPCCrossedRows, fPhotonPosPt, fPhotonNegPt, fPhotonPosEta, fPhotonNegEta, fPhotonPosY, fPhotonNegY, fPhotonPsiPair, - fPhotonPosITSCls, fPhotonNegITSCls, fPhotonPosITSChi2PerNcl, fPhotonNegITSChi2PerNcl, + fPhotonPosITSCls, fPhotonNegITSCls, fPhotonPosITSChi2PerNcl, fPhotonNegITSChi2PerNcl, fPhotonPosTrackCode, fPhotonNegTrackCode, fPhotonV0Type, GammaBDTScore); sigmaLambdaExtras(fLambdaPt, fLambdaMass, fAntiLambdaMass, fLambdaQt, fLambdaAlpha, fLambdaLifeTime, @@ -756,83 +896,118 @@ struct sigma0builder { fLambdaPrTOFNSigma, fLambdaPiTOFNSigma, fALambdaPrTOFNSigma, fALambdaPiTOFNSigma, fLambdaPosTPCCrossedRows, fLambdaNegTPCCrossedRows, fLambdaPosPt, fLambdaNegPt, fLambdaPosEta, fLambdaNegEta, fLambdaPosPrY, fLambdaPosPiY, fLambdaNegPrY, fLambdaNegPiY, - fLambdaPosITSCls, fLambdaNegITSCls, fLambdaPosITSChi2PerNcl, fLambdaNegITSChi2PerNcl, + fLambdaPosITSCls, fLambdaNegITSCls, fLambdaPosITSChi2PerNcl, fLambdaNegITSChi2PerNcl, fLambdaPosTrackCode, fLambdaNegTrackCode, fLambdaV0Type, LambdaBDTScore, AntiLambdaBDTScore); } - void processMonteCarlo(soa::Join const& collisions, V0DerivedMCDatas const& V0s, dauTracks const&, aod::MotherMCParts const&, soa::Join const&, soa::Join const&) + void processMonteCarlo(soa::Join const& collisions, V0DerivedMCDatas const& fullV0s, dauTracks const&, aod::MotherMCParts const&, soa::Join const&, soa::Join const&) { for (const auto& coll : collisions) { - if (!IsEventAccepted(coll, true)) { + + if (!IsEventAccepted(coll, true)) continue; - } + // Do analysis with collision-grouped V0s, retain full collision information const uint64_t collIdx = coll.globalIndex(); - auto V0Table_thisCollision = V0s.sliceBy(perCollisionMCDerived, collIdx); + auto V0s = fullV0s.sliceBy(perCollisionMCDerived, collIdx); - histos.fill(HIST("hEventCentrality"), coll.centFT0C()); - // V0 table sliced - for (auto& gamma : V0Table_thisCollision) { // selecting photons from Sigma0 - float centrality = coll.centFT0C(); + float centrality = coll.centFT0C(); + histos.fill(HIST("hEventCentrality"), centrality); - if (!gamma.has_v0MCCore()) + bool fhasMCColl = false; + if (coll.has_straMCCollision()) + fhasMCColl = true; + + //_______________________________________________ + // Retrieving IR info + float interactionRate = -1; + if (fGetIR) { + interactionRate = rateFetcher.fetch(ccdb.service, coll.timestamp(), coll.runNumber(), irSource, fIRCrashOnNull) * 1.e-3; + + if (interactionRate < 0) + histos.get(HIST("GeneralQA/hRunNumberNegativeIR"))->Fill(Form("%d", coll.runNumber()), 1); + + histos.fill(HIST("GeneralQA/hInteractionRate"), interactionRate); + histos.fill(HIST("GeneralQA/hCentralityVsInteractionRate"), centrality, interactionRate); + } + + std::vector bestGammasArray; + std::vector bestLambdasArray; + + //_______________________________________________ + // V0s loop + for (auto& v0 : V0s) { + if (!v0.has_v0MCCore()) continue; - auto gammaMC = gamma.v0MCCore_as>(); + auto v0MC = v0.v0MCCore_as>(); - // Auxiliary histograms: - if (gammaMC.pdgCode() == 22) { - histos.fill(HIST("MC/h3dGammasXYZ"), gamma.x(), gamma.y(), gamma.z()); - float GammaY = TMath::Abs(RecoDecay::y(std::array{gamma.px(), gamma.py(), gamma.pz()}, o2::constants::physics::MassGamma)); - float gammaMCpT = RecoDecay::pt(array{gammaMC.pxMC(), gammaMC.pyMC()}); + if (v0MC.pdgCode() == 22) { + histos.fill(HIST("MC/h2dGammaXYConversion"), v0.x(), v0.y()); + float GammaY = TMath::Abs(RecoDecay::y(std::array{v0.px(), v0.py(), v0.pz()}, o2::constants::physics::MassGamma)); if (GammaY < 0.5) { // rapidity selection - histos.fill(HIST("MC/h2dPtVsCentrality_GammaBeforeSel"), centrality, gamma.pt()); // isgamma - if (gammaMCpT > 0) - histos.fill(HIST("MC/h2dGammaPtResolution"), 1.f / gammaMCpT, gamma.pt() - gammaMCpT); // pT resolution - - if (gammaMC.pdgCodeMother() == 3212) { - histos.fill(HIST("MC/h2dPtVsCentrality_GammaSigma0"), centrality, gamma.pt()); // isgamma from sigma - } - if (gammaMC.pdgCodeMother() == -3212) { - histos.fill(HIST("MC/h2dPtVsCentrality_GammaAntiSigma0"), centrality, gamma.pt()); // isgamma from sigma - } + histos.fill(HIST("MC/h2dPtVsCentralityBeforeSel_MCAssocGamma"), centrality, v0.pt()); // isgamma } } - if (gammaMC.pdgCode() == 3122) { // Is Lambda - float LambdaY = TMath::Abs(RecoDecay::y(std::array{gamma.px(), gamma.py(), gamma.pz()}, o2::constants::physics::MassLambda)); - float lambdaMCpT = RecoDecay::pt(array{gammaMC.pxMC(), gammaMC.pyMC()}); - if (LambdaY < 0.5) { // rapidity selection - histos.fill(HIST("MC/h2dPtVsCentrality_LambdaBeforeSel"), centrality, gamma.pt()); - if (lambdaMCpT > 0) - histos.fill(HIST("MC/h2dLambdaPtResolution"), 1.f / lambdaMCpT, gamma.pt() - lambdaMCpT); // pT resolution - if (gammaMC.pdgCodeMother() == 3212) { - histos.fill(HIST("MC/h2dPtVsCentrality_LambdaSigma0"), centrality, gamma.pt()); - } - } + + float lambdaY = TMath::Abs(RecoDecay::y(std::array{v0.px(), v0.py(), v0.pz()}, o2::constants::physics::MassLambda)); + if (lambdaY < 0.5) { + if (v0MC.pdgCode() == 3122) // Is Lambda + histos.fill(HIST("MC/h2dPtVsCentralityBeforeSel_MCAssocLambda"), centrality, v0.pt()); + if (v0MC.pdgCode() == -3122) // Is AntiLambda + histos.fill(HIST("MC/h2dPtVsCentralityBeforeSel_MCAssocALambda"), centrality, v0.pt()); } - if (gammaMC.pdgCode() == -3122) { // Is AntiLambda - float AntiLambdaY = TMath::Abs(RecoDecay::y(std::array{gamma.px(), gamma.py(), gamma.pz()}, o2::constants::physics::MassLambda)); - if (AntiLambdaY < 0.5) { // rapidity selection - histos.fill(HIST("MC/h2dPtVsCentrality_AntiLambdaBeforeSel"), centrality, gamma.pt()); - if (gammaMC.pdgCodeMother() == -3212) { - histos.fill(HIST("MC/h2dPtVsCentrality_LambdaAntiSigma0"), centrality, gamma.pt()); // isantilambda from antisigma - } + + if (processPhotonCandidate(v0)) // selecting photons + bestGammasArray.push_back(v0.globalIndex()); // Save indices of best gamma candidates + + if (processLambdaCandidate(v0)) // selecting lambdas + bestLambdasArray.push_back(v0.globalIndex()); // Save indices of best lambda candidates + } + + //_______________________________________________ + // Pi0 optional loop + if (doPi0QA) { + for (size_t i = 0; i < bestGammasArray.size(); ++i) { + auto gamma1 = fullV0s.rawIteratorAt(bestGammasArray[i]); + for (size_t j = i + 1; j < bestGammasArray.size(); ++j) { + auto gamma2 = fullV0s.rawIteratorAt(bestGammasArray[j]); + runPi0QA(gamma1, gamma2); } } + } - for (auto& lambda : V0Table_thisCollision) { // selecting lambdas from Sigma0 - if (!lambda.has_v0MCCore()) - continue; + //_______________________________________________ + // Wrongly collision association study + if (doAssocStudy && fhasMCColl) { + analyzeV0CollAssoc(coll, fullV0s, bestGammasArray, interactionRate); // Gamma + analyzeV0CollAssoc(coll, fullV0s, bestLambdasArray, interactionRate); // Lambda + } + + //_______________________________________________ + // Sigma0 loop + for (size_t i = 0; i < bestGammasArray.size(); ++i) { + auto gamma = fullV0s.rawIteratorAt(bestGammasArray[i]); + + if (!gamma.has_v0MCCore()) + continue; + + auto gammaMC = gamma.v0MCCore_as>(); + + bool fIsPhotonCorrectlyAssign = false; + if (fhasMCColl) { + auto gammaMCCollision = coll.template straMCCollision_as>(); + fIsPhotonCorrectlyAssign = (gammaMC.straMCCollisionId() == gammaMCCollision.globalIndex()); + } + + for (size_t j = 0; j < bestLambdasArray.size(); ++j) { + auto lambda = fullV0s.iteratorAt(bestLambdasArray[j]); - if (lambda.v0Type() != 1) { // safeguard to avoid TPC-only photons + if (!lambda.has_v0MCCore()) continue; - } auto lambdaMC = lambda.v0MCCore_as>(); - if (doPi0QA) // Pi0 QA study - runPi0QA(gamma, lambda); - // Sigma0 candidate properties std::array pVecPhotons{gamma.px(), gamma.py(), gamma.pz()}; std::array pVecLambda{lambda.px(), lambda.py(), lambda.pz()}; @@ -841,78 +1016,135 @@ struct sigma0builder { float SigmapT = RecoDecay::pt(array{gamma.px() + lambda.px(), gamma.py() + lambda.py()}); float SigmaY = TMath::Abs(RecoDecay::y(std::array{gamma.px() + lambda.px(), gamma.py() + lambda.py(), gamma.pz() + lambda.pz()}, o2::constants::physics::MassSigma0)); - if ((gammaMC.pdgCode() == 22) && (gammaMC.pdgCodeMother() == 3212) && (lambdaMC.pdgCode() == 3122) && (lambdaMC.pdgCodeMother() == 3212) && (gamma.motherMCPartId() == lambda.motherMCPartId()) && (SigmaY < 0.5)) { - histos.fill(HIST("MC/h2dPtVsCentrality_Sigma0BeforeSel"), centrality, RecoDecay::pt(array{gamma.px() + lambda.px(), gamma.py() + lambda.py()})); - histos.fill(HIST("MC/h2dSigmaPtVsLambdaPt"), SigmapT, lambda.pt()); - histos.fill(HIST("MC/h2dSigmaPtVsGammaPt"), SigmapT, gamma.pt()); - } - if ((gammaMC.pdgCode() == 22) && (gammaMC.pdgCodeMother() == -3212) && (lambdaMC.pdgCode() == -3122) && (lambdaMC.pdgCodeMother() == -3212) && (gamma.motherMCPartId() == lambda.motherMCPartId()) && (SigmaY < 0.5)) - histos.fill(HIST("MC/h2dPtVsCentrality_AntiSigma0BeforeSel"), centrality, SigmapT); - - if (!processSigmaCandidate(lambda, gamma)) // basic selection - continue; - + // MC properties bool fIsSigma = false; bool fIsAntiSigma = false; - float SigmaMCpT = RecoDecay::pt(array{gammaMC.pxMC() + lambdaMC.pxMC(), gammaMC.pyMC() + lambdaMC.pyMC()}); bool fIsPhotonPrimary = gammaMC.isPhysicalPrimary(); + bool fIsLambdaPrimary = lambdaMC.isPhysicalPrimary(); + bool fIsLambdaCorrectlyAssign = false; + int PhotonCandPDGCode = gammaMC.pdgCode(); int PhotonCandPDGCodeMother = gammaMC.pdgCodeMother(); - float PhotonMCpT = RecoDecay::pt(array{gammaMC.pxMC(), gammaMC.pyMC()}); - bool fIsLambdaPrimary = lambdaMC.isPhysicalPrimary(); int LambdaCandPDGCode = lambdaMC.pdgCode(); int LambdaCandPDGCodeMother = lambdaMC.pdgCodeMother(); + + float SigmaMCpT = RecoDecay::pt(array{gammaMC.pxMC() + lambdaMC.pxMC(), gammaMC.pyMC() + lambdaMC.pyMC()}); + float PhotonMCpT = RecoDecay::pt(array{gammaMC.pxMC(), gammaMC.pyMC()}); float LambdaMCpT = RecoDecay::pt(array{lambdaMC.pxMC(), lambdaMC.pyMC()}); - if ((gammaMC.pdgCode() == 22) && (gammaMC.pdgCodeMother() == 3212) && (lambdaMC.pdgCode() == 3122) && (lambdaMC.pdgCodeMother() == 3212) && (gamma.motherMCPartId() == lambda.motherMCPartId())) { - fIsSigma = true; - histos.fill(HIST("MC/h2dPtVsCentrality_Sigma0AfterSel"), centrality, RecoDecay::pt(array{gamma.px() + lambda.px(), gamma.py() + lambda.py()})); + if (fhasMCColl) { + auto lambdaMCCollision = coll.template straMCCollision_as>(); + fIsLambdaCorrectlyAssign = (lambdaMC.straMCCollisionId() == lambdaMCCollision.globalIndex()); } - if ((gammaMC.pdgCode() == 22) && (gammaMC.pdgCodeMother() == -3212) && (lambdaMC.pdgCode() == -3122) && (lambdaMC.pdgCodeMother() == -3212) && (gamma.motherMCPartId() == lambda.motherMCPartId())) { + + if ((PhotonCandPDGCode == 22) && (PhotonCandPDGCodeMother == 3212) && (LambdaCandPDGCode == 3122) && (LambdaCandPDGCodeMother == 3212) && (gamma.motherMCPartId() == lambda.motherMCPartId())) + fIsSigma = true; + if ((PhotonCandPDGCode == 22) && (PhotonCandPDGCodeMother == -3212) && (LambdaCandPDGCode == -3122) && (LambdaCandPDGCodeMother == -3212) && (gamma.motherMCPartId() == lambda.motherMCPartId())) fIsAntiSigma = true; - histos.fill(HIST("MC/h2dPtVsCentrality_AntiSigma0AfterSel"), centrality, RecoDecay::pt(array{gamma.px() + lambda.px(), gamma.py() + lambda.py()})); - // TH3D Mass histogram + + if (SigmaY < 0.5) { + if (fIsSigma) { + histos.fill(HIST("MC/h2dPtVsCentralityBeforeSel_MCAssocSigma0"), centrality, SigmaMCpT); + histos.fill(HIST("MC/h2dSigma0PtVsLambdaPtBeforeSel_MCAssoc"), SigmaMCpT, LambdaMCpT); + histos.fill(HIST("MC/h2dSigma0PtVsGammaPtBeforeSel_MCAssoc"), SigmaMCpT, PhotonMCpT); + } + if (fIsAntiSigma) + histos.fill(HIST("MC/h2dPtVsCentralityBeforeSel_MCAssocASigma0"), centrality, SigmaMCpT); } + + histos.fill(HIST("SigmaSel/h3dMassSigma0BeforeSel"), centrality, SigmapT, SigmaMass); + + // Build sigma0 candidate, please + if (!buildSigma0(lambda, gamma)) + continue; + + // Filling histos and tables + histos.fill(HIST("SigmaSel/h3dMassSigma0AfterSel"), centrality, SigmapT, SigmaMass); + + if (SigmaY < 0.5) { + if (fIsSigma) + histos.fill(HIST("MC/h2dPtVsCentralityAfterSel_MCAssocSigma0"), centrality, SigmaMCpT); + if (fIsAntiSigma) + histos.fill(HIST("MC/h2dPtVsCentralityAfterSel_MCAssocASigma0"), centrality, SigmaMCpT); + } + + if (fillBkgQAhistos) + runBkgAnalysis(fIsSigma, fIsAntiSigma, PhotonCandPDGCode, PhotonCandPDGCodeMother, LambdaCandPDGCode, LambdaCandPDGCodeMother, SigmapT, SigmaMass); + + // Fill Tables please sigma0mccores(fIsSigma, fIsAntiSigma, SigmaMCpT, - PhotonCandPDGCode, PhotonCandPDGCodeMother, fIsPhotonPrimary, PhotonMCpT, - LambdaCandPDGCode, LambdaCandPDGCodeMother, fIsLambdaPrimary, LambdaMCpT); + PhotonCandPDGCode, PhotonCandPDGCodeMother, fIsPhotonPrimary, PhotonMCpT, fIsPhotonCorrectlyAssign, + LambdaCandPDGCode, LambdaCandPDGCodeMother, fIsLambdaPrimary, LambdaMCpT, fIsLambdaCorrectlyAssign); fillTables(lambda, gamma, coll); // filling tables with accepted candidates nSigmaCandidates++; - if (nSigmaCandidates % 5000 == 0) { + if (nSigmaCandidates % 10000 == 0) LOG(info) << "Sigma0 Candidates built: " << nSigmaCandidates; - } - - // QA histograms - // Signal only (sigma0+antisigma0) - if (fIsSigma || fIsAntiSigma) - histos.fill(HIST("MC/h2dPtVsMassSigma_SignalOnly"), SigmapT, SigmaMass); } } } } - void processRealData(soa::Join const& collisions, V0StandardDerivedDatas const& V0s, dauTracks const&) + void processRealData(soa::Join const& collisions, V0StandardDerivedDatas const& fullV0s, dauTracks const&) { for (const auto& coll : collisions) { - if (!IsEventAccepted(coll, true)) { + + if (!IsEventAccepted(coll, true)) continue; - } + // Do analysis with collision-grouped V0s, retain full collision information const uint64_t collIdx = coll.globalIndex(); - auto V0Table_thisCollision = V0s.sliceBy(perCollisionSTDDerived, collIdx); + auto V0s = fullV0s.sliceBy(perCollisionSTDDerived, collIdx); - histos.fill(HIST("hEventCentrality"), coll.centFT0C()); - // V0 table sliced - for (auto& gamma : V0Table_thisCollision) { // selecting photons from Sigma0 - for (auto& lambda : V0Table_thisCollision) { // selecting lambdas from Sigma0 - if (doPi0QA) // Pi0 QA study - runPi0QA(gamma, lambda); + float centrality = coll.centFT0C(); + histos.fill(HIST("hEventCentrality"), centrality); - if (lambda.v0Type() != 1) { // safeguard to avoid TPC-only photons - continue; + //_______________________________________________ + // Retrieving IR info + float interactionRate = -1; + if (fGetIR) { + interactionRate = rateFetcher.fetch(ccdb.service, coll.timestamp(), coll.runNumber(), irSource, fIRCrashOnNull) * 1.e-3; + + if (interactionRate < 0) + histos.get(HIST("GeneralQA/hRunNumberNegativeIR"))->Fill(Form("%d", coll.runNumber()), 1); + + histos.fill(HIST("GeneralQA/hInteractionRate"), interactionRate); + histos.fill(HIST("GeneralQA/hCentralityVsInteractionRate"), centrality, interactionRate); + } + + std::vector bestGammasArray; + std::vector bestLambdasArray; + + //_______________________________________________ + // V0s loop + for (auto& v0 : V0s) { + if (processPhotonCandidate(v0)) // selecting photons + bestGammasArray.push_back(v0.globalIndex()); // Save indices of best gamma candidates + + if (processLambdaCandidate(v0)) // selecting lambdas + bestLambdasArray.push_back(v0.globalIndex()); // Save indices of best lambda candidates + } + + //_______________________________________________ + // Pi0 optional loop + if (doPi0QA) { + for (size_t i = 0; i < bestGammasArray.size(); ++i) { + auto gamma1 = fullV0s.rawIteratorAt(bestGammasArray[i]); + for (size_t j = i + 1; j < bestGammasArray.size(); ++j) { + auto gamma2 = fullV0s.rawIteratorAt(bestGammasArray[j]); + runPi0QA(gamma1, gamma2); } + } + } + + //_______________________________________________ + // Sigma0 nested loop + for (size_t i = 0; i < bestGammasArray.size(); ++i) { + auto gamma = fullV0s.rawIteratorAt(bestGammasArray[i]); + + for (size_t j = 0; j < bestLambdasArray.size(); ++j) { + auto lambda = fullV0s.iteratorAt(bestLambdasArray[j]); // Sigma0 candidate properties std::array pVecPhotons{gamma.px(), gamma.py(), gamma.pz()}; @@ -920,27 +1152,34 @@ struct sigma0builder { auto arrMom = std::array{pVecPhotons, pVecLambda}; float SigmaMass = RecoDecay::m(arrMom, std::array{o2::constants::physics::MassPhoton, o2::constants::physics::MassLambda0}); float SigmapT = RecoDecay::pt(array{gamma.px() + lambda.px(), gamma.py() + lambda.py()}); - // float SigmaY = TMath::Abs(RecoDecay::y(std::array{gamma.px() + lambda.px(), gamma.py() + lambda.py(), gamma.pz() + lambda.pz()}, o2::constants::physics::MassSigma0)); - histos.fill(HIST("h3dMassSigmasBeforeSel"), coll.centFT0C(), SigmapT, SigmaMass); - if (!processSigmaCandidate(lambda, gamma)) // applying selection for reconstruction - continue; + histos.fill(HIST("SigmaSel/h3dMassSigma0BeforeSel"), centrality, SigmapT, SigmaMass); - histos.fill(HIST("h3dMassSigmasAfterSel"), coll.centFT0C(), SigmapT, SigmaMass); + // Building sigma0 candidate + if (!buildSigma0(lambda, gamma)) + continue; fillTables(lambda, gamma, coll); // filling tables with accepted candidates + histos.fill(HIST("SigmaSel/h3dMassSigma0AfterSel"), centrality, SigmapT, SigmaMass); + nSigmaCandidates++; - if (nSigmaCandidates % 5000 == 0) { + if (nSigmaCandidates % 10000 == 0) LOG(info) << "Sigma0 Candidates built: " << nSigmaCandidates; - } } } } } + // Simulated processing in Run 3 (subscribes to MC information too) + void processGeneratedCollRun3(soa::Join::iterator const& mcCollision) + { + histos.fill(HIST("Gen/hNEventsNch"), mcCollision.multMCNParticlesEta05()); + } + PROCESS_SWITCH(sigma0builder, processMonteCarlo, "process as if MC data", false); PROCESS_SWITCH(sigma0builder, processRealData, "process as if real data", true); + PROCESS_SWITCH(sigma0builder, processGeneratedCollRun3, "process generated MC collisions", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGLF/TableProducer/Strangeness/strangederivedbuilder.cxx b/PWGLF/TableProducer/Strangeness/strangederivedbuilder.cxx index 6a67077dff3..f6ffacc7733 100644 --- a/PWGLF/TableProducer/Strangeness/strangederivedbuilder.cxx +++ b/PWGLF/TableProducer/Strangeness/strangederivedbuilder.cxx @@ -842,12 +842,14 @@ struct strangederivedbuilder { //__________________________________________________ // mark mcParticles for referencing - for (auto const& v0 : V0s) + for (auto const& v0 : V0s) { if (v0.has_mcMotherParticle()) motherReference[v0.mcMotherParticleId()] = 0; - for (auto const& ca : Cascades) + } + for (auto const& ca : Cascades) { if (ca.has_mcMotherParticle()) motherReference[ca.mcMotherParticleId()] = 0; + } //__________________________________________________ // Figure out the numbering of the new mcMother table // assume filling per order @@ -859,10 +861,20 @@ struct strangederivedbuilder { } //__________________________________________________ // populate track references - for (auto const& v0 : V0s) - v0mothers(motherReference[v0.mcMotherParticleId()]); // joinable with V0Datas - for (auto const& ca : Cascades) - cascmothers(motherReference[ca.mcMotherParticleId()]); // joinable with CascDatas + for (auto const& v0 : V0s) { + if (v0.mcMotherParticleId() > -1) { + v0mothers(motherReference[v0.mcMotherParticleId()]); // joinable with V0Datas + } else { + v0mothers(-1); // joinable with V0Datas + } + } + for (auto const& ca : Cascades) { + if (ca.mcMotherParticleId() > -1) { + cascmothers(motherReference[ca.mcMotherParticleId()]); // joinable with CascDatas + } else { + cascmothers(-1); // joinable with CascDatas + } + } //__________________________________________________ // populate motherMCParticles for (auto const& tr : mcParticles) { diff --git a/PWGLF/TableProducer/Strangeness/strangenessbuilder.cxx b/PWGLF/TableProducer/Strangeness/strangenessbuilder.cxx index 553a0f74e36..32a9f027b18 100644 --- a/PWGLF/TableProducer/Strangeness/strangenessbuilder.cxx +++ b/PWGLF/TableProducer/Strangeness/strangenessbuilder.cxx @@ -29,12 +29,13 @@ // task will adapt algorithm to spare / spend CPU accordingly // -- mc_findableMode ....: 0: only found (default), 1: add findable to found, 2: all findable // When using findables, refer to FoundTag bools for checking if found -// -- v0builderopts ......: V0-specific building options (topological, etc) +// -- v0builderopts ......: V0-specific building options (topological, deduplication, etc) // -- cascadebuilderopts .: cascade-specific building options (topological, etc) #include #include +#include "Framework/DataSpecUtils.h" #include "Framework/runDataProcessing.h" #include "Framework/AnalysisTask.h" #include "Framework/AnalysisDataModel.h" @@ -486,6 +487,7 @@ struct StrangenessBuilder { LOGF(info, "Configuring tables to generate"); auto& workflows = context.services().get(); + TString listOfRequestors[nTables]; for (int i = 0; i < nTables; i++) { // adjust bookkeeping histogram h->GetXaxis()->SetBinLabel(i + 1, tableNames[i].c_str()); @@ -495,6 +497,7 @@ struct StrangenessBuilder { int f = enabledTables->get(tableNames[i].c_str(), "enable"); if (f == 1) { mEnabledTables[i] = 1; + listOfRequestors[i] = "manual enabling"; } if (f == -1) { // autodetect this table in other devices @@ -503,9 +506,17 @@ struct StrangenessBuilder { for (auto const& input : device.inputs) { if (device.name.compare("strangenessbuilder-initializer") == 0) continue; // don't listen to the initializer - if (input.matcher.binding == tableNames[i]) { - LOGF(info, "Device %s has subscribed to %s", device.name, tableNames[i]); - mEnabledTables[i] = 1; + if (DataSpecUtils::partialMatch(input.matcher, o2::header::DataOrigin("AOD"))) { + auto&& [origin, description, version] = DataSpecUtils::asConcreteDataMatcher(input.matcher); + std::string tableNameWithVersion = tableNames[i]; + if (version > 0) { + tableNameWithVersion += Form("_%03d", version); + } + if (input.matcher.binding == tableNameWithVersion) { + LOGF(info, "Device %s has subscribed to %s (version %i)", device.name, tableNames[i], version); + listOfRequestors[i].Append(Form("%s ", device.name.c_str())); + mEnabledTables[i] = 1; + } } } } @@ -540,7 +551,7 @@ struct StrangenessBuilder { for (int i = 0; i < nTables; i++) { // printout to be improved in the future if (mEnabledTables[i]) { - LOGF(info, " -~> Table enabled: %s", tableNames[i]); + LOGF(info, " -~> Table enabled: %s, requested by %s", tableNames[i], listOfRequestors[i].Data()); h->SetBinContent(i + 1, 0); // mark enabled } } @@ -1005,9 +1016,6 @@ struct StrangenessBuilder { // simple passthrough: copy existing cascades to build list for (const auto& cascade : cascades) { auto const& v0 = cascade.v0(); - if (v0.v0Type() > 1) { - continue; // skip any unexpected stuff (FIXME: follow-up) - } currentCascadeEntry.globalId = cascade.globalIndex(); currentCascadeEntry.collisionId = cascade.collisionId(); currentCascadeEntry.v0Id = ao2dV0toV0List[v0.globalIndex()]; diff --git a/PWGLF/Tasks/GlobalEventProperties/heavyionMultiplicity.cxx b/PWGLF/Tasks/GlobalEventProperties/heavyionMultiplicity.cxx index 435fc106062..35e3c99b958 100644 --- a/PWGLF/Tasks/GlobalEventProperties/heavyionMultiplicity.cxx +++ b/PWGLF/Tasks/GlobalEventProperties/heavyionMultiplicity.cxx @@ -49,11 +49,13 @@ using namespace o2::aod::track; using namespace o2::aod::evsel; using CollisionDataTable = soa::Join; +using ColDataTablepp = soa::Join; using TrackDataTable = soa::Join; using FilTrackDataTable = soa::Filtered; using CollisionMCTrueTable = aod::McCollisions; using TrackMCTrueTable = aod::McParticles; using CollisionMCRecTable = soa::SmallGroups>; +using ColMCRecTablepp = soa::SmallGroups>; using TrackMCRecTable = soa::Join; using FilTrackMCRecTable = soa::Filtered; using V0TrackCandidates = soa::Join; @@ -113,8 +115,6 @@ AxisSpec axisMassLambda = {200, 1.07, 1.17, "Lambda/AntiLamda Mass", "Lambda/Ant AxisSpec axisTracks{9, 0.5, 9.5, "#tracks", "TrackAxis"}; auto static constexpr kMinCharge = 3.f; auto static constexpr kMinpTcut = 0.1f; -auto static constexpr kMinCent = 0.0f; -auto static constexpr kMaxCent = 100.0f; auto static constexpr kEtaInelgt0 = 1.0f; auto static constexpr kNItslayers = 7; @@ -184,11 +184,10 @@ struct HeavyionMultiplicity { x->SetBinLabel(2, "sel8"); x->SetBinLabel(3, "kNoSameBunchPileup"); // reject collisions in case of pileup with another collision in the same foundBC x->SetBinLabel(4, "kIsGoodZvtxFT0vsPV"); // small difference between z-vertex from PV and from FT0 - x->SetBinLabel(5, "Centrality"); - x->SetBinLabel(6, "ApplyExtraCorrCut"); - x->SetBinLabel(7, "ApplyNoCollInTimeRangeStandard"); - x->SetBinLabel(8, "ApplyNoCollInRofStandard"); - x->SetBinLabel(9, "ApplyNoHighMultCollInPrevRof"); + x->SetBinLabel(5, "ApplyExtraCorrCut"); + x->SetBinLabel(6, "ApplyNoCollInTimeRangeStandard"); + x->SetBinLabel(7, "ApplyNoCollInRofStandard"); + x->SetBinLabel(8, "ApplyNoHighMultCollInPrevRof"); if (doprocessData) { histos.add("CentPercentileHist", "CentPercentileHist", kTH1D, {axisCent}, false); @@ -275,30 +274,25 @@ struct HeavyionMultiplicity { } histos.fill(HIST("EventHist"), 4); - if (selColCent(col) < kMinCent || selColCent(col) > kMaxCent) { - return false; - } - histos.fill(HIST("EventHist"), 5); - if (isApplyExtraCorrCut && col.multNTracksPV() > npvTracksCut && col.multFT0C() < (10 * col.multNTracksPV() - ft0cCut)) { return false; } - histos.fill(HIST("EventHist"), 6); + histos.fill(HIST("EventHist"), 5); if (isApplyNoCollInTimeRangeStandard && !col.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { return false; } - histos.fill(HIST("EventHist"), 7); + histos.fill(HIST("EventHist"), 6); if (isApplyNoCollInRofStandard && !col.selection_bit(o2::aod::evsel::kNoCollInRofStandard)) { return false; } - histos.fill(HIST("EventHist"), 8); + histos.fill(HIST("EventHist"), 7); if (isApplyNoHighMultCollInPrevRof && !col.selection_bit(o2::aod::evsel::kNoHighMultCollInPrevRof)) { return false; } - histos.fill(HIST("EventHist"), 9); + histos.fill(HIST("EventHist"), 8); return true; } @@ -649,7 +643,7 @@ struct HeavyionMultiplicity { } PROCESS_SWITCH(HeavyionMultiplicity, processStrangeYield, "Strange particle yield", false); - void processppData(CollisionDataTable::iterator const& cols, FilTrackDataTable const& tracks) + void processppData(ColDataTablepp::iterator const& cols, FilTrackDataTable const& tracks) { if (!isEventSelected(cols)) { return; @@ -667,28 +661,28 @@ struct HeavyionMultiplicity { } // track loop if (nTrks > 0) { - histos.fill(HIST("EventHist"), 10); + histos.fill(HIST("EventHist"), 9); histos.fill(HIST("VtxZHist"), cols.posZ()); - histos.fill(HIST("MultPercentileHist"), selColCent(cols)); - histos.fill(HIST("hdatazvtxmultpp"), cols.posZ(), selColCent(cols)); + histos.fill(HIST("MultPercentileHist"), cols.centFT0M()); + histos.fill(HIST("hdatazvtxmultpp"), cols.posZ(), cols.centFT0M()); for (const auto& track : tracks) { if (!isTrackSelected(track)) { continue; } histos.fill(HIST("PhiVsEtaHistpp"), track.phi(), track.eta()); - histos.fill(HIST("hdatadndetapp"), cols.posZ(), selColCent(cols), track.eta(), track.phi(), kGlobalplusITS); + histos.fill(HIST("hdatadndetapp"), cols.posZ(), cols.centFT0M(), track.eta(), track.phi(), kGlobalplusITS); if (track.hasTPC()) { - histos.fill(HIST("hdatadndetapp"), cols.posZ(), selColCent(cols), track.eta(), track.phi(), kGlobalonly); + histos.fill(HIST("hdatadndetapp"), cols.posZ(), cols.centFT0M(), track.eta(), track.phi(), kGlobalonly); } else { - histos.fill(HIST("hdatadndetapp"), cols.posZ(), selColCent(cols), track.eta(), track.phi(), kITSonly); + histos.fill(HIST("hdatadndetapp"), cols.posZ(), cols.centFT0M(), track.eta(), track.phi(), kITSonly); } } // track loop } // nTrks>0 } PROCESS_SWITCH(HeavyionMultiplicity, processppData, "process pp data", false); - void processppMonteCarlo(CollisionMCTrueTable::iterator const&, CollisionMCRecTable const& RecCols, TrackMCTrueTable const& GenParticles, FilTrackMCRecTable const& RecTracks) + void processppMonteCarlo(CollisionMCTrueTable::iterator const&, ColMCRecTablepp const& RecCols, TrackMCTrueTable const& GenParticles, FilTrackMCRecTable const& RecTracks) { for (const auto& RecCol : RecCols) { if (!isEventSelected(RecCol)) { @@ -709,21 +703,21 @@ struct HeavyionMultiplicity { } if (nTrks > 0) { - histos.fill(HIST("EventHist"), 10); + histos.fill(HIST("EventHist"), 9); histos.fill(HIST("VtxZHist"), RecCol.posZ()); - histos.fill(HIST("MultPercentileMCRecHist"), selColCent(RecCol)); - histos.fill(HIST("hmczvtxmultpp"), RecCol.posZ(), selColCent(RecCol)); + histos.fill(HIST("MultPercentileMCRecHist"), RecCol.centFT0M()); + histos.fill(HIST("hmczvtxmultpp"), RecCol.posZ(), RecCol.centFT0M()); for (const auto& Rectrack : recTracksPart) { if (!isTrackSelected(Rectrack)) { continue; } histos.fill(HIST("MCrecPhiVsEtaHistpp"), Rectrack.phi(), Rectrack.eta()); - histos.fill(HIST("hmcrecdndetapp"), RecCol.posZ(), selColCent(RecCol), Rectrack.eta(), Rectrack.phi(), static_cast(kSpAll), kGlobalplusITS); + histos.fill(HIST("hmcrecdndetapp"), RecCol.posZ(), RecCol.centFT0M(), Rectrack.eta(), Rectrack.phi(), static_cast(kSpAll), kGlobalplusITS); if (Rectrack.hasTPC()) { - histos.fill(HIST("hmcrecdndetapp"), RecCol.posZ(), selColCent(RecCol), Rectrack.eta(), Rectrack.phi(), static_cast(kSpAll), kGlobalonly); + histos.fill(HIST("hmcrecdndetapp"), RecCol.posZ(), RecCol.centFT0M(), Rectrack.eta(), Rectrack.phi(), static_cast(kSpAll), kGlobalonly); } else { - histos.fill(HIST("hmcrecdndetapp"), RecCol.posZ(), selColCent(RecCol), Rectrack.eta(), Rectrack.phi(), static_cast(kSpAll), kITSonly); + histos.fill(HIST("hmcrecdndetapp"), RecCol.posZ(), RecCol.centFT0M(), Rectrack.eta(), Rectrack.phi(), static_cast(kSpAll), kITSonly); } if (Rectrack.has_mcParticle()) { @@ -757,9 +751,9 @@ struct HeavyionMultiplicity { pid = kBkg; } mclabels.push_back(Rectrack.mcParticleId()); - histos.fill(HIST("hmcrecdndetapp"), RecCol.posZ(), selColCent(RecCol), Rectrack.eta(), Rectrack.phi(), static_cast(pid), kGlobalplusITS); + histos.fill(HIST("hmcrecdndetapp"), RecCol.posZ(), RecCol.centFT0M(), Rectrack.eta(), Rectrack.phi(), static_cast(pid), kGlobalplusITS); } else { - histos.fill(HIST("hmcrecdndetapp"), RecCol.posZ(), selColCent(RecCol), Rectrack.eta(), Rectrack.phi(), static_cast(kBkg), kGlobalplusITS); + histos.fill(HIST("hmcrecdndetapp"), RecCol.posZ(), RecCol.centFT0M(), Rectrack.eta(), Rectrack.phi(), static_cast(kBkg), kGlobalplusITS); } } // track (mcrec) loop } // nTrks>0 @@ -780,13 +774,13 @@ struct HeavyionMultiplicity { if (!isGenTrackSelected(particle)) { continue; } - histos.fill(HIST("hmcgendndetapp"), RecCol.posZ(), selColCent(RecCol), particle.eta(), particle.phi(), static_cast(kSpAll), kNoGenpTVar); + histos.fill(HIST("hmcgendndetapp"), RecCol.posZ(), RecCol.centFT0M(), particle.eta(), particle.phi(), static_cast(kSpAll), kNoGenpTVar); if (particle.pt() < kMinpTcut) { - histos.fill(HIST("hmcgendndetapp"), RecCol.posZ(), selColCent(RecCol), particle.eta(), particle.phi(), static_cast(kSpAll), kGenpTup, -10.0 * particle.pt() + 2); - histos.fill(HIST("hmcgendndetapp"), RecCol.posZ(), selColCent(RecCol), particle.eta(), particle.phi(), static_cast(kSpAll), kGenpTdown, 5.0 * particle.pt() + 0.5); + histos.fill(HIST("hmcgendndetapp"), RecCol.posZ(), RecCol.centFT0M(), particle.eta(), particle.phi(), static_cast(kSpAll), kGenpTup, -10.0 * particle.pt() + 2); + histos.fill(HIST("hmcgendndetapp"), RecCol.posZ(), RecCol.centFT0M(), particle.eta(), particle.phi(), static_cast(kSpAll), kGenpTdown, 5.0 * particle.pt() + 0.5); } else { - histos.fill(HIST("hmcgendndetapp"), RecCol.posZ(), selColCent(RecCol), particle.eta(), particle.phi(), static_cast(kSpAll), kGenpTup); - histos.fill(HIST("hmcgendndetapp"), RecCol.posZ(), selColCent(RecCol), particle.eta(), particle.phi(), static_cast(kSpAll), kGenpTdown); + histos.fill(HIST("hmcgendndetapp"), RecCol.posZ(), RecCol.centFT0M(), particle.eta(), particle.phi(), static_cast(kSpAll), kGenpTup); + histos.fill(HIST("hmcgendndetapp"), RecCol.posZ(), RecCol.centFT0M(), particle.eta(), particle.phi(), static_cast(kSpAll), kGenpTdown); } int pid = 0; @@ -804,7 +798,7 @@ struct HeavyionMultiplicity { pid = kSpOther; break; } - histos.fill(HIST("hmcgendndetapp"), RecCol.posZ(), selColCent(RecCol), particle.eta(), particle.phi(), static_cast(pid), kNoGenpTVar); + histos.fill(HIST("hmcgendndetapp"), RecCol.posZ(), RecCol.centFT0M(), particle.eta(), particle.phi(), static_cast(pid), kNoGenpTVar); } // track (mcgen) loop } // npart>0 } // collision loop diff --git a/PWGLF/Tasks/GlobalEventProperties/uccZdc.cxx b/PWGLF/Tasks/GlobalEventProperties/uccZdc.cxx index 72a89b7d5de..f93284b0a16 100644 --- a/PWGLF/Tasks/GlobalEventProperties/uccZdc.cxx +++ b/PWGLF/Tasks/GlobalEventProperties/uccZdc.cxx @@ -25,6 +25,7 @@ #include #include #include +#include #include "Common/CCDB/EventSelectionParams.h" #include "Common/CCDB/TriggerAliases.h" @@ -55,17 +56,11 @@ using namespace o2::constants::math; namespace o2::aod { -using ColEvSels = - soa::Join; -using BCsRun3 = - soa::Join; -using TracksSel = soa::Join; -using SimCollisions = soa::Join; -using SimTracks = soa::Join; +using ColEvSels = soa::Join; +using BCsRun3 = soa::Join; +using TracksSel = soa::Join; +using SimCollisions = soa::Join; +using SimTracks = soa::Join; } // namespace o2::aod struct UccZdc { @@ -95,13 +90,10 @@ struct UccZdc { Configurable nBinsTDC{"nBinsTDC", 150, "nbinsTDC"}; Configurable minTdc{"minTdc", -15.0, "minimum TDC"}; Configurable maxTdc{"maxTdc", 15.0, "maximum TDC"}; - Configurable minMeanpT{"minMeanpT", 0.5, "minimum [pT]"}; - Configurable maxMeanpT{"maxMeanpT", 1.1, "maximum [pT]"}; - Configurable nBinsMeanpT{"nBinsMeanpT", 160, "# bins [pT]"}; ConfigurableAxis binsPt{"binsPt", {VARIABLE_WIDTH, 0.0, 0.1, 0.12}, "pT binning"}; ConfigurableAxis binsCent{"binsCent", {VARIABLE_WIDTH, 0., 10., 20., 30., 40., 50., 60., 70., 80., 90., 100.}, "T0C binning"}; - // Configurable event selectiond and flags ZDC + // Configurables Event Selection Configurable isNoCollInTimeRangeStrict{"isNoCollInTimeRangeStrict", true, "isNoCollInTimeRangeStrict?"}; Configurable isNoCollInTimeRangeStandard{"isNoCollInTimeRangeStandard", false, "isNoCollInTimeRangeStandard?"}; Configurable isNoCollInRofStrict{"isNoCollInRofStrict", true, "isNoCollInRofStrict?"}; @@ -110,14 +102,10 @@ struct UccZdc { Configurable isNoCollInTimeRangeNarrow{"isNoCollInTimeRangeNarrow", false, "isNoCollInTimeRangeNarrow?"}; Configurable isOccupancyCut{"isOccupancyCut", true, "Occupancy cut?"}; Configurable isApplyFT0CbasedOccupancy{"isApplyFT0CbasedOccupancy", false, "T0C Occu cut?"}; - Configurable isAmpZDC{"isAmpZDC", false, "Use amplitude ZDC?"}; - Configurable isCommPMT{"isCommPMT", false, "Use common PMT ZDC?"}; - Configurable isSumTowers{"isSumTowers", false, "Use sum of Tow ZDC?"}; Configurable isTDCcut{"isTDCcut", false, "Use TDC cut?"}; Configurable isZEMcut{"isZEMcut", true, "Use ZEM cut?"}; - Configurable isZNbasedSel{"isZNbasedSel", false, "Use ZN based Sel."}; - Configurable isZNAbasedSel{"isZNAbasedSel", false, "Use ZNA based Sel."}; - Configurable isZNCbasedSel{"isZNCbasedSel", false, "Use ZNC based Sel."}; + + Configurable minNchSel{"minNchSel", 5., "min Nch Selection"}; Configurable znBasedCut{"znBasedCut", 100, "ZN-based cut"}; Configurable zemCut{"zemCut", 1000., "ZEM cut"}; Configurable tdcCut{"tdcCut", 1., "TDC cut"}; @@ -145,12 +133,8 @@ struct UccZdc { Zem }; - // Histograms names - static constexpr std::string_view PsTitles[4] = { - ";#it{N}_{ch} (|#eta| < 0.8, Corrected);#LT[#it{p}_{T}^{(1)}]#GT;", - ";#it{N}_{ch} (|#eta| < 0.8, Corrected);#LT[#it{p}_{T}^{(2)}]#GT;", - ";#it{N}_{ch} (|#eta| < 0.8, Corrected);#LT[#it{p}_{T}^{(3)}]#GT;", - ";#it{N}_{ch} (|#eta| < 0.8, Corrected);#LT[#it{p}_{T}^{(4)}]#GT;"}; + static constexpr float zEro{0.}; + static constexpr float oneHalf{0.5}; // Filters // Filter trackFilter = ((aod::track::eta > minEta) && (aod::track::eta < maxEta) && (aod::track::pt > minPt) && (aod::track::pt < maxPt) && requireGlobalTrackInFilter()); @@ -167,17 +151,13 @@ struct UccZdc { using TheFilteredSimTracks = soa::Filtered; // Histograms: Data - HistogramRegistry registry{ - "registry", - {}, - OutputObjHandlingPolicy::AnalysisObject, - true, - true}; + HistogramRegistry registry{"registry", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; Service ccdb; Configurable paTH{"paTH", "Users/o/omvazque/TrackingEfficiency", "base path to the ccdb object"}; Configurable uRl{"uRl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; - Configurable noLaterThan{"noLaterThan", 1740173636328, "latest acceptable timestamp of creation for the object"}; + // Configurable noLaterThan{"noLaterThan", 1740173636328, "latest acceptable timestamp of creation for the object"}; + Configurable noLaterThan{"noLaterThan", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable timestamp of creation for the object"}; // the efficiency has been previously stored in the CCDB as TH1F histogram TH1F* efficiency = nullptr; @@ -218,119 +198,114 @@ struct UccZdc { // Histograms: paritcle-level info if (doprocessZdcCollAss) { - registry.add("NchVsZpos", ";#it{N}_{ch} (|#eta| < 0.8);Vtx_{z};", - kTProfile, {{nBinsNch, minNch, maxNch}}); + registry.add("T0Ccent", ";;Entries", kTH1F, {axisCent}); registry.add("ZposVsEta", "", kTProfile, {axisZpos}); - registry.add("EtaVsPhi", ";#eta;#varphi", kTH2F, - {{{axisEta}, {100, -0.1 * PI, +2.1 * PI}}}); - registry.add("NchVsPt", ";#it{N}_{ch} (|#eta| < 0.8, Corrected);;", kTH2F, - {{{nBinsNch, minNch, maxNch}, {axisPt}}}); - registry.add("sigma1Pt", ";;#sigma(p_{T})/p_{T};", kTProfile, {axisPt}); - registry.add("dcaXYvspT", ";DCA_{xy} (cm);;", kTH2F, - {{{50, -1., 1.}, {axisPt}}}); registry.add("ZN", ";ZNA+ZNC;Entries;", kTH1F, {{nBinsZDC, -0.5, maxZN}}); - registry.add("ZNA", ";ZNA;Entries;", kTH1F, {{nBinsZDC, -0.5, maxZN}}); - registry.add("ZPA", ";ZPA;Entries;", kTH1F, {{nBinsZDC, -0.5, maxZP}}); - registry.add("ZNC", ";ZNC;Entries;", kTH1F, {{nBinsZDC, -0.5, maxZN}}); - registry.add("ZPC", ";ZPC;Entries;", kTH1F, {{nBinsZDC, -0.5, maxZP}}); - registry.add("ZNVsZEM", ";ZEM;ZNA+ZNC;", kTH2F, - {{{60, -0.5, maxZEM}, {60, -0.5, maxZN}}}); - registry.add("ZNAVsZNC", ";ZNC;ZNA", kTH2F, - {{{30, -0.5, maxZN}, {30, -0.5, maxZN}}}); - registry.add("ZPAVsZPC", ";ZPC;ZPA;", kTH2F, - {{{100, -0.5, maxZP}, {100, -0.5, maxZP}}}); - registry.add("ZNAVsZPA", ";ZPA;ZNA;", kTH2F, - {{{20, -0.5, maxZP}, {30, -0.5, maxZN}}}); - registry.add("ZNCVsZPC", ";ZPC;ZNC;", kTH2F, - {{{20, -0.5, maxZP}, {30, -0.5, maxZN}}}); - registry.add("ZNCVstdc", ";t_{ZNC};ZNC;", kTH2F, - {{{30, -15., 15.}, {nBinsZDC, -0.5, maxZN}}}); - registry.add("ZNAVstdc", ";t_{ZNA};ZNA;", kTH2F, - {{{30, -15., 15.}, {30, -0.5, maxZN}}}); - registry.add("ZPCVstdc", ";t_{ZPC};ZPC;", kTH2F, - {{{30, -15., 15}, {20, -0.5, maxZP}}}); - registry.add("ZPAVstdc", ";t_{ZPA};ZPA;", kTH2F, - {{{30, -15., 15.}, {20, -0.5, maxZP}}}); - registry.add("ZEM1Vstdc", ";t_{ZEM1};ZEM1;", kTH2F, - {{{30, -15., 15.}, {30, -0.5, 2000.5}}}); - registry.add("ZEM2Vstdc", ";t_{ZEM2};ZEM2;", kTH2F, - {{{30, -15., 15.}, {30, -0.5, 2000.5}}}); - registry.add("debunch", ";t_{ZDC}-t_{ZDA};t_{ZDC}+t_{ZDA}", kTH2F, - {{{nBinsTDC, minTdc, maxTdc}, {nBinsTDC, minTdc, maxTdc}}}); - registry.add("NchVsFT0C", ";T0C (#times 1/100);#it{N}_{ch} (|#eta|<0.8);", kTProfile, {{nBinsAmpFT0, 0., 950.}}); - registry.add("NchVsFT0M", ";T0A+T0C (#times 1/100);#it{N}_{ch} (|#eta|<0.8);", kTProfile, {{nBinsAmpFT0, 0., 3000.}}); - registry.add("NchVsFT0A", ";T0A (#times 1/100);#it{N}_{ch} (|#eta|<0.8);", kTProfile, {{nBinsAmpFT0, 0., maxAmpFT0}}); - registry.add("NchVsFV0A", ";V0A (#times 1/100);#it{N}_{ch} (|#eta|<0.8);", kTProfile, {{nBinsAmpFV0, 0., maxAmpFV0}}); - registry.add("NchVsNPV", ";#it{N}_{PV} (|#eta|<1);#LT ITS+TPC tracks #GT (|#eta|<0.8);", kTProfile, {{nBinsNch, minNch, maxNch}}); - registry.add("NchVsITStracks", ";ITS tracks nCls >= 5;#LTITS+TPC tracks#GT (|#eta|<0.8);", kTProfile, {{nBinsNch, minNch, maxNch}}); - registry.add("ZNCVsNch", ";#it{N}_{ch} (|#eta|<0.8);ZNC;", kTH2F, - {{{nBinsNch, minNch, maxNch}, {nBinsZDC, minNch, maxZN}}}); - registry.add("ZNAVsNch", ";#it{N}_{ch} (|#eta|<0.8);ZNA;", kTH2F, - {{{nBinsNch, minNch, maxNch}, {nBinsZDC, minNch, maxZN}}}); - registry.add("ZNVsNch", ";#it{N}_{ch} (|#eta|<0.8);ZNA+ZNC;", kTH2F, - {{{nBinsNch, minNch, maxNch}, {nBinsZDC, minNch, maxZN}}}); - registry.add("ZNVsFT0A", ";T0A (#times 1/100);ZNA+ZNC;", kTH2F, - {{{nBinsAmpFT0, 0., maxAmpFT0}, {nBinsZDC, minNch, maxZN}}}); - registry.add("ZNVsFT0C", ";T0C (#times 1/100);ZNA+ZNC;", kTH2F, - {{{nBinsAmpFT0, 0., maxAmpFT0}, {nBinsZDC, minNch, maxZN}}}); - registry.add("ZNVsFT0M", ";T0A+T0C (#times 1/100);ZNA+ZNC;", kTH2F, - {{{nBinsAmpFT0, 0., 3000.}, {nBinsZDC, minNch, maxZN}}}); - registry.add("ZNDifVsNch", ";#it{N}_{ch} (|#eta|<0.8);ZNA-ZNC;", kTH2F, - {{{nBinsNch, minNch, maxNch}, {100, -50., 50.}}}); - } - - if (doprocessMCclosure || doprocessZdcCollAss) { - registry.add("NchRaw", ";#it{N}_{ch} (|#eta| < 0.8);", kTH1F, - {{nBinsNch, minNch, maxNch}}); - registry.add("Nch", ";#it{N}_{ch} (|#eta| < 0.8, Corrected);", kTH1F, - {{nBinsNch, minNch, maxNch}}); - registry.add("T0Ccent", ";;Entries", kTH1F, {axisCent}); - registry.add("NchVsOneParCorr", PsTitles[0].data(), kTProfile, - {{nBinsNch, minNch, maxNch}}); - registry.add("NchVsTwoParCorr", PsTitles[1].data(), kTProfile, - {{nBinsNch, minNch, maxNch}}); - registry.add("NchVsThreeParCorr", PsTitles[2].data(), kTProfile, - {{nBinsNch, minNch, maxNch}}); - registry.add("NchVsFourParCorr", PsTitles[3].data(), kTProfile, - {{nBinsNch, minNch, maxNch}}); + registry.add("EtaVsPhi", ";#eta;#varphi", kTH2F, {{{axisEta}, {100, -0.1 * PI, +2.1 * PI}}}); + registry.add("sigma1Pt", ";;#sigma(p_{T})/p_{T};", kTProfile, {axisPt}); + registry.add("dcaXYvspT", ";DCA_{xy} (cm);;", kTH2F, {{{50, -1., 1.}, {axisPt}}}); + + registry.add("Nch", ";#it{N}_{ch} (|#eta| < 0.8, Corrected);", kTH1F, {{nBinsNch, minNch, maxNch}}); + registry.add("NchVsPt", ";#it{N}_{ch} (|#eta| < 0.8, Corrected);;", kTH2F, {{{nBinsNch, minNch, maxNch}, {axisPt}}}); + registry.add("NchVsOneParCorr", ";#it{N}_{ch} (|#eta| < 0.8, Corrected);#LT[#it{p}_{T}^{(1)}]#GT (GeV/#it{c})", kTProfile, {{nBinsNch, minNch, maxNch}}); + registry.add("NchVsOneParCorrVsZN", ";#it{N}_{ch} (|#eta| < 0.8, Corrected); ZNA+ZNC; #LT[#it{p}_{T}^{(1)}]#GT", kTProfile2D, {{{nBinsNch, minNch, maxNch}, {nBinsZDC, -0.5, maxZN}}}); + registry.add("NchVsTwoParCorrVsZN", ";#it{N}_{ch} (|#eta| < 0.8, Corrected);ZNA+ZNC;#LT[#it{p}_{T}^{(2)}]#GT", kTProfile2D, {{{nBinsNch, minNch, maxNch}, {nBinsZDC, -0.5, maxZN}}}); + registry.add("NchVsThreeParCorrVsZN", ";#it{N}_{ch} (|#eta| < 0.8, Corrected);ZNA+ZNC;#LT[#it{p}_{T}^{(3)}]#GT", kTProfile2D, {{{nBinsNch, minNch, maxNch}, {nBinsZDC, -0.5, maxZN}}}); + registry.add("NchVsFourParCorrVsZN", ";#it{N}_{ch} (|#eta| < 0.8, Corrected);ZNA+ZNC;#LT[#it{p}_{T}^{(4)}]#GT", kTProfile2D, {{{nBinsNch, minNch, maxNch}, {nBinsZDC, -0.5, maxZN}}}); } // MC Histograms - if (doprocesspTEff) { - registry.add("T0Ccent", ";;Entries", kTH1F, {axisCent}); + if (doprocessMCclosure) { + registry.add("RandomNumber", "", kTH1F, {{100, 0., 1.}}); + registry.add("EvtsDivided", ";Event type;Entries;", kTH1F, {{2, -0.5, 1.5}}); + auto hEvtsDiv = registry.get(HIST("EvtsDivided")); + auto* xEvtsDiv = hEvtsDiv->GetXaxis(); + xEvtsDiv->SetBinLabel(1, "MC closure"); + xEvtsDiv->SetBinLabel(2, "Corrections"); + + registry.add("NchGen", "MC closure;#it{N}_{ch} (|#eta| < 0.8);Entries;", kTH1F, {{nBinsNch, minNch, maxNch}}); + registry.add("NchvsOneParCorrGen", "MC closure;#it{N}_{ch} (|#eta| < 0.8);#LT[#it{p}_{T}^{(1)}]#GT (GeV/#it{c})", kTProfile, {{nBinsNch, minNch, maxNch}}); + registry.add("NchvsTwoParCorrGen", "MC closure;#it{N}_{ch} (|#eta| < 0.8);#LT[#it{p}_{T}^{(2)}]#GT", kTProfile, {{nBinsNch, minNch, maxNch}}); + registry.add("NchvsThreeParCorrGen", "MC closure;#it{N}_{ch} (|#eta| < 0.8);#LT[#it{p}_{T}^{(3)}]#GT", kTProfile, {{nBinsNch, minNch, maxNch}}); + registry.add("NchvsFourParCorrGen", "MC closure;#it{N}_{ch} (|#eta| < 0.8);#LT[#it{p}_{T}^{(4)}]#GT", kTProfile, {{nBinsNch, minNch, maxNch}}); + + registry.add("T0Ccent", "Filled at MC closure + Corrections;;Entries", kTH1F, {axisCent}); + registry.add("NchRaw", "MC closure;#it{N}_{ch} (|#eta| < 0.8);Entries;", kTH1F, {{nBinsNch, minNch, maxNch}}); + registry.add("Nch", "MC closure;#it{N}_{ch} (|#eta| < 0.8, Corrected);Entries;", kTH1F, {{nBinsNch, minNch, maxNch}}); + registry.add("NchVsOneParCorr", "MC closure;#it{N}_{ch} (|#eta| < 0.8, Corrected);#LT[#it{p}_{T}^{(1)}]#GT (GeV/#it{c})", kTProfile, {{nBinsNch, minNch, maxNch}}); + registry.add("NchVsTwoParCorr", "MC closure;#it{N}_{ch} (|#eta| < 0.8, Corrected);#LT[#it{p}_{T}^{(2)}]#GT", kTProfile, {{nBinsNch, minNch, maxNch}}); + registry.add("NchVsThreeParCorr", "MC closure;#it{N}_{ch} (|#eta| < 0.8, Corrected);#LT[#it{p}_{T}^{(3)}]#GT", kTProfile, {{nBinsNch, minNch, maxNch}}); + registry.add("NchVsFourParCorr", "MC closure;#it{N}_{ch} (|#eta| < 0.8, Corrected);#LT[#it{p}_{T}^{(4)}]#GT", kTProfile, {{nBinsNch, minNch, maxNch}}); + + // Corrections registry.add("nRecColvsCent", "", kTH2F, {{6, -0.5, 5.5}, {{axisCent}}}); - registry.add("Pt_all_ch", "", kTH2F, {{axisCent}, {axisPt}}); - registry.add("Pt_ch", "", kTH2F, {{axisCent}, {axisPt}}); - registry.add("Pt_pi", "", kTH2F, {{axisCent}, {axisPt}}); - registry.add("Pt_ka", "", kTH2F, {{axisCent}, {axisPt}}); - registry.add("Pt_pr", "", kTH2F, {{axisCent}, {axisPt}}); - registry.add("Pt_sigpos", "", kTH2F, {{axisCent}, {axisPt}}); - registry.add("Pt_signeg", "", kTH2F, {{axisCent}, {axisPt}}); - registry.add("Pt_re", "", kTH2F, {{axisCent}, {axisPt}}); - registry.add("EtaVsPhi", ";;#varphi;", kTH2F, - {{{axisEta}, {100, -0.1 * PI, +2.1 * PI}}}); + registry.add("Pt_all_ch", "Corrections;;;", kTH2F, {{axisCent}, {axisPt}}); + registry.add("Pt_ch", "Corrections;;;", kTH2F, {{axisCent}, {axisPt}}); + registry.add("Pt_pi", "Corrections;;;", kTH2F, {{axisCent}, {axisPt}}); + registry.add("Pt_ka", "Corrections;;;", kTH2F, {{axisCent}, {axisPt}}); + registry.add("Pt_pr", "Corrections;;;", kTH2F, {{axisCent}, {axisPt}}); + registry.add("Pt_sigpos", "Corrections;;;", kTH2F, {{axisCent}, {axisPt}}); + registry.add("Pt_signeg", "Corrections;;;", kTH2F, {{axisCent}, {axisPt}}); + registry.add("Pt_re", "Corrections;;;", kTH2F, {{axisCent}, {axisPt}}); + registry.add("EtaVsPhi", "Corrections;;#varphi;", kTH2F, {{{axisEta}, {100, -0.1 * PI, +2.1 * PI}}}); registry.add("hEventCounterMC", "Event counter", kTH1F, {axisEvent}); - registry.add("zPosMC", ";;Entries;", kTH1F, {axisZpos}); - registry.add("PtMC_ch", "", kTH2F, {{axisCent}, {axisPt}}); - registry.add("PtMC_pi", "", kTH2F, {{axisCent}, {axisPt}}); - registry.add("PtMC_ka", "", kTH2F, {{axisCent}, {axisPt}}); - registry.add("PtMC_pr", "", kTH2F, {{axisCent}, {axisPt}}); - registry.add("PtMC_sigpos", "", kTH2F, {{axisCent}, {axisPt}}); - registry.add("PtMC_signeg", "", kTH2F, {{axisCent}, {axisPt}}); - registry.add("PtMC_re", "", kTH2F, {{axisCent}, {axisPt}}); + registry.add("zPosMC", "Filled at MC closure + Corrections;;Entries;", kTH1F, {axisZpos}); + registry.add("PtMC_ch", "Corrections;;;", kTH2F, {{axisCent}, {axisPt}}); + registry.add("PtMC_pi", "Corrections;;;", kTH2F, {{axisCent}, {axisPt}}); + registry.add("PtMC_ka", "Corrections;;;", kTH2F, {{axisCent}, {axisPt}}); + registry.add("PtMC_pr", "Corrections;;;", kTH2F, {{axisCent}, {axisPt}}); + registry.add("PtMC_sigpos", "Corrections;;;", kTH2F, {{axisCent}, {axisPt}}); + registry.add("PtMC_signeg", "Corrections;;;", kTH2F, {{axisCent}, {axisPt}}); + registry.add("PtMC_re", "Corrections;;;", kTH2F, {{axisCent}, {axisPt}}); + + auto hECMC = registry.get(HIST("hEventCounterMC")); + auto* x = hECMC->GetXaxis(); + x->SetBinLabel(1, "All"); + x->SetBinLabel(13, "VtxZ cut"); } - if (doprocessMCclosure) { - registry.add("NchGen", ";Nch;Entries;", kTH1F, - {{nBinsNch, minNch, maxNch}}); - registry.add("NchvsOneParCorrGen", PsTitles[0].data(), kTProfile, - {{nBinsNch, minNch, maxNch}}); - registry.add("NchvsTwoParCorrGen", PsTitles[1].data(), kTProfile, - {{nBinsNch, minNch, maxNch}}); - registry.add("NchvsThreeParCorrGen", PsTitles[2].data(), kTProfile, - {{nBinsNch, minNch, maxNch}}); - registry.add("NchvsFourParCorrGen", PsTitles[3].data(), kTProfile, - {{nBinsNch, minNch, maxNch}}); + if (doprocessQA) { + registry.add("T0Ccent", ";;Entries", kTH1F, {axisCent}); + + registry.add("ZNVsFT0A", ";T0A (#times 1/100);ZNA+ZNC;", kTH2F, {{{nBinsAmpFT0, 0., maxAmpFT0}, {nBinsZDC, -0.5, maxZN}}}); + registry.add("ZNVsFT0C", ";T0C (#times 1/100);ZNA+ZNC;", kTH2F, {{{nBinsAmpFT0, 0., maxAmpFT0}, {nBinsZDC, -0.5, maxZN}}}); + registry.add("ZNVsFT0M", ";T0A+T0C (#times 1/100);ZNA+ZNC;", kTH2F, {{{nBinsAmpFT0, 0., 3000.}, {nBinsZDC, -0.5, maxZN}}}); + + registry.add("ZN", ";ZNA+ZNC;Entries;", kTH1F, {{nBinsZDC, -0.5, maxZN}}); + registry.add("ZNA", ";ZNA;Entries;", kTH1F, {{nBinsZDC, -0.5, maxZN}}); + registry.add("ZPA", ";ZPA;Entries;", kTH1F, {{nBinsZDC, -0.5, maxZP}}); + registry.add("ZNC", ";ZNC;Entries;", kTH1F, {{nBinsZDC, -0.5, maxZN}}); + registry.add("ZPC", ";ZPC;Entries;", kTH1F, {{nBinsZDC, -0.5, maxZP}}); + registry.add("ZNAVsZNC", ";ZNC;ZNA", kTH2F, {{{30, -0.5, maxZN}, {30, -0.5, maxZN}}}); + registry.add("ZPAVsZPC", ";ZPC;ZPA;", kTH2F, {{{100, -0.5, maxZP}, {100, -0.5, maxZP}}}); + registry.add("ZNAVsZPA", ";ZPA;ZNA;", kTH2F, {{{20, -0.5, maxZP}, {30, -0.5, maxZN}}}); + registry.add("ZNCVsZPC", ";ZPC;ZNC;", kTH2F, {{{20, -0.5, maxZP}, {30, -0.5, maxZN}}}); + registry.add("ZNCcvsZNCsum", ";ZNC common;ZNC sum towers;", kTH2F, {{{30, -0.5, maxZN}, {30, -0.5, maxZN}}}); + registry.add("ZNAcvsZNAsum", ";ZNA common;ZNA sum towers;", kTH2F, {{{30, -0.5, maxZN}, {30, -0.5, maxZN}}}); + registry.add("ZPCcvsZPCsum", ";ZPC common;ZPC sum towers;", kTH2F, {{{30, -0.5, maxZP}, {30, -0.5, maxZP}}}); + registry.add("ZPAcvsZPAsum", ";ZPA common;ZPA sum towers;", kTH2F, {{{30, -0.5, maxZP}, {30, -0.5, maxZP}}}); + registry.add("ZNVsZEM", ";ZEM;ZNA+ZNC;", kTH2F, {{{60, -0.5, maxZEM}, {60, -0.5, maxZN}}}); + registry.add("ZNCVstdc", ";t_{ZNC};ZNC;", kTH2F, {{{30, -15., 15.}, {nBinsZDC, -0.5, maxZN}}}); + registry.add("ZNAVstdc", ";t_{ZNA};ZNA;", kTH2F, {{{30, -15., 15.}, {30, -0.5, maxZN}}}); + registry.add("ZPCVstdc", ";t_{ZPC};ZPC;", kTH2F, {{{30, -15., 15}, {20, -0.5, maxZP}}}); + registry.add("ZPAVstdc", ";t_{ZPA};ZPA;", kTH2F, {{{30, -15., 15.}, {20, -0.5, maxZP}}}); + registry.add("ZEM1Vstdc", ";t_{ZEM1};ZEM1;", kTH2F, {{{30, -15., 15.}, {30, -0.5, 2000.5}}}); + registry.add("ZEM2Vstdc", ";t_{ZEM2};ZEM2;", kTH2F, {{{30, -15., 15.}, {30, -0.5, 2000.5}}}); + registry.add("debunch", ";t_{ZDC}-t_{ZDA};t_{ZDC}+t_{ZDA}", kTH2F, {{{nBinsTDC, minTdc, maxTdc}, {nBinsTDC, minTdc, maxTdc}}}); + + registry.add("NchVsFT0C", ";T0C (#times 1/100, -3.3 < #eta < -2.1);#it{N}_{ch} (|#eta|<0.8);", kTH2F, {{{nBinsAmpFT0, 0., 950.}, {nBinsNch, minNch, maxNch}}}); + registry.add("NchVsFT0M", ";T0A+T0C (#times 1/100, -3.3 < #eta < -2.1 and 3.5 < #eta < 4.9);#it{N}_{ch} (|#eta|<0.8);", kTH2F, {{{nBinsAmpFT0, 0., 3000.}, {nBinsNch, minNch, maxNch}}}); + registry.add("NchVsFT0A", ";T0A (#times 1/100, 3.5 < #eta < 4.9);#it{N}_{ch} (|#eta|<0.8);", kTH2F, {{{nBinsAmpFT0, 0., maxAmpFT0}, {nBinsNch, minNch, maxNch}}}); + registry.add("NchVsFV0A", ";V0A (#times 1/100, 2.2 < #eta < 5);#it{N}_{ch} (|#eta|<0.8);", kTH2F, {{{nBinsAmpFV0, 0., maxAmpFV0}, {nBinsNch, minNch, maxNch}}}); + + registry.add("NchVsEt", ";#it{E}_{T} (|#eta|<0.8);#LTITS+TPC tracks#GT (|#eta|<0.8);", kTH2F, {{{nBinsNch, minNch, maxNch}, {nBinsNch, minNch, maxNch}}}); + registry.add("NchVsMeanPt", ";#it{N}_{ch} (|#eta|<0.8);#LT[#it{p}_{T}]#GT (|#eta|<0.8);", kTProfile, {{nBinsNch, minNch, maxNch}}); + registry.add("NchVsNPV", ";#it{N}_{PV} (|#eta|<1);ITS+TPC tracks (|#eta|<0.8);", kTH2F, {{{300, -0.5, 5999.5}, {nBinsNch, minNch, maxNch}}}); + registry.add("NchVsITStracks", ";ITS tracks nCls >= 5;TITS+TPC tracks (|#eta|<0.8);", kTH2F, {{{300, -0.5, 5999.5}, {nBinsNch, minNch, maxNch}}}); + registry.add("ZNCVsNch", ";#it{N}_{ch} (|#eta|<0.8);ZNC;", kTH2F, {{{nBinsNch, minNch, maxNch}, {nBinsZDC, minNch, maxZN}}}); + registry.add("ZNAVsNch", ";#it{N}_{ch} (|#eta|<0.8);ZNA;", kTH2F, {{{nBinsNch, minNch, maxNch}, {nBinsZDC, minNch, maxZN}}}); + registry.add("ZNVsNch", ";#it{N}_{ch} (|#eta|<0.8);ZNA+ZNC;", kTH2F, {{{nBinsNch, minNch, maxNch}, {nBinsZDC, minNch, maxZN}}}); + registry.add("ZNDifVsNch", ";#it{N}_{ch} (|#eta|<0.8);ZNA-ZNC;", kTH2F, {{{nBinsNch, minNch, maxNch}, {100, -50., 50.}}}); } ccdb->setURL(uRl.value); @@ -341,10 +316,10 @@ struct UccZdc { // This avoids that users can replace objects **while** a train is running ccdb->setCreatedNotAfter(noLaterThan.value); LOGF(info, "Getting object %s", paTH.value.data()); - efficiency = ccdb->getForTimeStamp(paTH.value, noLaterThan); - if (!efficiency) { - LOGF(fatal, "Efficiency object not found!"); - } + // efficiency = ccdb->getForTimeStamp(paTH.value, noLaterThan); + // if (!efficiency) { + // LOGF(fatal, "Efficiency object not found!"); + // } } template @@ -410,12 +385,10 @@ struct UccZdc { } if (isOccupancyCut) { - auto occuValue{isApplyFT0CbasedOccupancy - ? col.ft0cOccupancyInTimeRange() - : col.trackOccupancyInTimeRange()}; - - if (occuValue < minOccCut || occuValue > maxOccCut) + auto occuValue{isApplyFT0CbasedOccupancy ? col.ft0cOccupancyInTimeRange() : col.trackOccupancyInTimeRange()}; + if (occuValue < minOccCut || occuValue > maxOccCut) { return false; + } } registry.fill(HIST("hEventCounter"), EvCutLabel::OccuCut); @@ -433,85 +406,24 @@ struct UccZdc { return true; } - void processZdcCollAss(o2::aod::ColEvSels::iterator const& collision, - o2::aod::BCsRun3 const& /*bcs*/, - aod::Zdcs const& /*zdcs*/, aod::FV0As const& /*fv0as*/, - aod::FT0s const& /*ft0s*/, - TheFilteredTracks const& tracks) + void processQA(o2::aod::ColEvSels::iterator const& collision, o2::aod::BCsRun3 const& /**/, aod::Zdcs const& /**/, aod::FV0As const& /**/, aod::FT0s const& /**/, TheFilteredTracks const& tracks) { + + // LOG(info) << " Collisions size: " << collisions.size() << " Table's size: " << collisions.tableSize() << "\n"; + const auto& foundBC = collision.foundBC_as(); + // LOG(info) << "Run number: " << foundBC.runNumber() << "\n"; if (!isEventSelected(collision)) { return; } - const auto& foundBC = collision.foundBC_as(); - if (!foundBC.has_zdc()) { // has ZDC? + // has ZDC? + if (!foundBC.has_zdc()) { return; } registry.fill(HIST("hEventCounter"), EvCutLabel::Zdc); + auto zdc = foundBC.zdc(); - float aT0A{0.0}; - float aT0C{0.0}; - float aV0A{0.0}; - float znA{0.0}; - float znC{0.0}; - float zpA{0.0}; - float zpC{0.0}; - float aZEM1{0.0}; - float aZEM2{0.0}; - float tZEM1{0.0}; - float tZEM2{0.0}; - float tZNA{0.0}; - float tZNC{0.0}; - float tZPA{0.0}; - float tZPC{0.0}; - float sumZNs{0.0}; - float sumZEMs{0.0}; - float tZDCdif{0.0}; - float tZDCsum{0.0}; - - aZEM1 = foundBC.zdc().amplitudeZEM1(); - aZEM2 = foundBC.zdc().amplitudeZEM2(); - tZEM1 = foundBC.zdc().timeZEM1(); - tZEM2 = foundBC.zdc().timeZEM2(); - tZNA = foundBC.zdc().timeZNA(); - tZNC = foundBC.zdc().timeZNC(); - tZPA = foundBC.zdc().timeZPA(); - tZPC = foundBC.zdc().timeZPC(); - tZDCdif = tZNC + tZPC - tZNA - tZPA; - tZDCsum = tZNC + tZPC + tZNA + tZPA; - - if (isAmpZDC) { - znA = foundBC.zdc().amplitudeZNA(); - znC = foundBC.zdc().amplitudeZNC(); - zpA = foundBC.zdc().amplitudeZPA(); - zpC = foundBC.zdc().amplitudeZPC(); - } else if (isCommPMT) { - znA = foundBC.zdc().energyCommonZNA(); - znC = foundBC.zdc().energyCommonZNC(); - zpA = foundBC.zdc().energyCommonZPA(); - zpC = foundBC.zdc().energyCommonZPC(); - } else if (isSumTowers) { - for (const auto& eZNA : foundBC.zdc().energySectorZNA()) - znA += eZNA; - for (const auto& eZNC : foundBC.zdc().energySectorZNC()) - znC += eZNC; - for (const auto& eZPA : foundBC.zdc().energySectorZPA()) - zpA += eZPA; - for (const auto& eZPC : foundBC.zdc().energySectorZPC()) - zpC += eZPC; - } else { - znA = -999.; - znC = -999.; - zpA = -999.; - zpC = -999.; - } - znA /= 2.81; - znC /= 2.81; - zpA /= 2.81; - zpC /= 2.81; - sumZNs = znA + znC; - sumZEMs = aZEM1 + aZEM2; - + float aT0A = 0., aT0C = 0., aV0A = 0.; if (foundBC.has_ft0()) { for (const auto& amplitude : foundBC.ft0().amplitudeA()) { aT0A += amplitude; @@ -532,6 +444,13 @@ struct UccZdc { aV0A = -999.; } + float tZNA{zdc.timeZNA()}; + float tZNC{zdc.timeZNC()}; + float tZPA{zdc.timeZPA()}; + float tZPC{zdc.timeZPC()}; + float tZDCdif{tZNC + tZPC - tZNA - tZPA}; + float tZDCsum{tZNC + tZPC + tZNA + tZPA}; + // TDC cut if (isTDCcut) { if (std::sqrt(std::pow(tZDCdif, 2.) + std::pow(tZDCsum, 2.)) > tdcCut) { @@ -540,6 +459,10 @@ struct UccZdc { registry.fill(HIST("hEventCounter"), EvCutLabel::Tdc); } + float aZEM1{zdc.amplitudeZEM1()}; + float aZEM2{zdc.amplitudeZEM2()}; + float sumZEMs{aZEM1 + aZEM2}; + // ZEM cut if (isZEMcut) { if (sumZEMs < zemCut) { @@ -548,13 +471,51 @@ struct UccZdc { registry.fill(HIST("hEventCounter"), EvCutLabel::Zem); } + float znA{zdc.amplitudeZNA()}; + float znC{zdc.amplitudeZNC()}; + float zpA{zdc.amplitudeZPA()}; + float zpC{zdc.amplitudeZPC()}; + znA /= 2.81; + znC /= 2.81; + zpA /= 2.81; + zpC /= 2.81; + + float tZEM1{zdc.timeZEM1()}; + float tZEM2{zdc.timeZEM2()}; + float sumZNs{znA + znC}; + + float sumZNC = (zdc.energySectorZNC())[0] + (zdc.energySectorZNC())[1] + (zdc.energySectorZNC())[2] + (zdc.energySectorZNC())[3]; + float sumZNA = (zdc.energySectorZNA())[0] + (zdc.energySectorZNA())[1] + (zdc.energySectorZNA())[2] + (zdc.energySectorZNA())[3]; + float sumZPC = (zdc.energySectorZPC())[0] + (zdc.energySectorZPC())[1] + (zdc.energySectorZPC())[2] + (zdc.energySectorZPC())[3]; + float sumZPA = (zdc.energySectorZPA())[0] + (zdc.energySectorZPA())[1] + (zdc.energySectorZPA())[2] + (zdc.energySectorZPA())[3]; + + int itsTracks = 0, glbTracks = 0; + float et = 0., meanpt = 0.; + for (const auto& track : tracks) { + if (track.hasITS() && track.itsNCls() >= minITSnCls) { + itsTracks++; + } + // Track Selection + if (track.isGlobalTrack()) { + glbTracks++; + meanpt += track.pt(); + et += std::sqrt(std::pow(track.pt(), 2.) + std::pow(o2::constants::physics::MassPionCharged, 2.)); + } + } + registry.fill(HIST("zPos"), collision.posZ()); registry.fill(HIST("T0Ccent"), collision.centFT0C()); - registry.fill(HIST("ZN"), znA + znC); + + registry.fill(HIST("ZNCcvsZNCsum"), sumZNC / 2.81, zdc.energyCommonZNC() / 2.81); + registry.fill(HIST("ZNAcvsZNAsum"), sumZNA / 2.81, zdc.energyCommonZNA() / 2.81); + registry.fill(HIST("ZPCcvsZPCsum"), sumZPC / 2.81, zdc.energyCommonZPC() / 2.81); + registry.fill(HIST("ZPAcvsZPAsum"), sumZPA / 2.81, zdc.energyCommonZPA() / 2.81); + registry.fill(HIST("ZNA"), znA); registry.fill(HIST("ZNC"), znC); registry.fill(HIST("ZPA"), zpA); registry.fill(HIST("ZPC"), zpC); + registry.fill(HIST("ZN"), znA + znC); registry.fill(HIST("ZNAVsZNC"), znC, znA); registry.fill(HIST("ZNAVsZPA"), zpA, znA); registry.fill(HIST("ZNCVsZPC"), zpC, znC); @@ -568,20 +529,103 @@ struct UccZdc { registry.fill(HIST("ZEM2Vstdc"), tZEM2, aZEM2); registry.fill(HIST("debunch"), tZDCdif, tZDCsum); + registry.fill(HIST("ZNVsFT0A"), aT0A / 100., sumZNs); + registry.fill(HIST("ZNVsFT0C"), aT0C / 100., sumZNs); + registry.fill(HIST("ZNVsFT0M"), (aT0A + aT0C) / 100., sumZNs); + + if (sumZNs > znBasedCut) { + return; + } + + registry.fill(HIST("NchVsFV0A"), aV0A / 100., glbTracks); + registry.fill(HIST("NchVsFT0A"), aT0A / 100., glbTracks); + registry.fill(HIST("NchVsFT0C"), aT0C / 100., glbTracks); + registry.fill(HIST("NchVsFT0M"), (aT0A + aT0C) / 100., glbTracks); + + registry.fill(HIST("NchVsEt"), et, glbTracks); + registry.fill(HIST("NchVsNPV"), collision.multNTracksPVeta1(), glbTracks); + registry.fill(HIST("NchVsITStracks"), itsTracks, glbTracks); + registry.fill(HIST("ZNAVsNch"), glbTracks, znA); + registry.fill(HIST("ZNCVsNch"), glbTracks, znC); + registry.fill(HIST("ZNVsNch"), glbTracks, sumZNs); + registry.fill(HIST("ZNDifVsNch"), glbTracks, znA - znC); + if (glbTracks >= minNchSel) { + registry.fill(HIST("NchVsMeanPt"), glbTracks, meanpt / glbTracks); + } + } + PROCESS_SWITCH(UccZdc, processQA, "Process QA", true); + + void processZdcCollAss(o2::aod::ColEvSels::iterator const& collision, o2::aod::BCsRun3 const& /*bcs*/, aod::Zdcs const& /*zdcs*/, aod::FV0As const& /*fv0as*/, aod::FT0s const& /*ft0s*/, TheFilteredTracks const& tracks) + { + + if (!isEventSelected(collision)) { + return; + } + + const auto& foundBC = collision.foundBC_as(); + // LOGF(info, "Getting object %s for run number %i from timestamp=%llu", paTH.value.data(), foundBC.runNumber(), foundBC.timestamp()); + + // auto efficiency = ccdb->getForTimeStamp(paTH.value, foundBC.timestamp()); + auto efficiency = ccdb->getForRun(paTH.value, foundBC.runNumber()); + if (!efficiency) { + LOGF(fatal, "Efficiency object not found!"); + } + + // has ZDC? + if (!foundBC.has_zdc()) { + return; + } + registry.fill(HIST("hEventCounter"), EvCutLabel::Zdc); + + if (!foundBC.has_ft0()) { + return; + } + registry.fill(HIST("hEventCounter"), EvCutLabel::TZero); + + float znA{foundBC.zdc().amplitudeZNA()}; + float znC{foundBC.zdc().amplitudeZNC()}; + float aZEM1{foundBC.zdc().amplitudeZEM1()}; + float aZEM2{foundBC.zdc().amplitudeZEM2()}; + float tZNA{foundBC.zdc().timeZNA()}; + float tZNC{foundBC.zdc().timeZNC()}; + float tZPA{foundBC.zdc().timeZPA()}; + float tZPC{foundBC.zdc().timeZPC()}; + float tZDCdif{tZNC + tZPC - tZNA - tZPA}; + float tZDCsum{tZNC + tZPC + tZNA + tZPA}; + znA /= 2.81; + znC /= 2.81; + float sumZNs{znA + znC}; + float sumZEMs{aZEM1 + aZEM2}; + + // TDC cut + if (isTDCcut) { + if (std::sqrt(std::pow(tZDCdif, 2.) + std::pow(tZDCsum, 2.)) > tdcCut) { + return; + } + registry.fill(HIST("hEventCounter"), EvCutLabel::Tdc); + } + + // ZEM cut + if (isZEMcut) { + if (sumZEMs < zemCut) { + return; + } + registry.fill(HIST("hEventCounter"), EvCutLabel::Zem); + } + + registry.fill(HIST("zPos"), collision.posZ()); + registry.fill(HIST("T0Ccent"), collision.centFT0C()); + std::vector pTs; std::vector wIs; - float itsTracks{0.}; - // Calculates the event weight, W_k for (const auto& track : tracks) { - if (track.hasITS() && track.itsNCls() >= minITSnCls) { - itsTracks++; - } // Track Selection if (!track.isGlobalTrack()) { continue; } + registry.fill(HIST("ZposVsEta"), collision.posZ(), track.eta()); registry.fill(HIST("EtaVsPhi"), track.eta(), track.phi()); registry.fill(HIST("sigma1Pt"), track.pt(), track.sigma1Pt()); registry.fill(HIST("dcaXYvspT"), track.dcaXY(), track.pt()); @@ -598,317 +642,285 @@ struct UccZdc { p1 = p2 = p3 = p4 = w1 = w2 = w3 = w4 = 0.0; getPTpowers(pTs, wIs, p1, w1, p2, w2, p3, w3, p4, w4); const double nch{static_cast(pTs.size())}; - if (!(nch != 0.)) + if (nch < minNchSel) { return; + } - registry.fill(HIST("NchVsFV0A"), aV0A / 100., nch); - registry.fill(HIST("NchVsFT0A"), aT0A / 100., nch); - registry.fill(HIST("NchVsFT0C"), aT0C / 100., nch); - registry.fill(HIST("NchVsFT0M"), (aT0A + aT0C) / 100., nch); - registry.fill(HIST("ZNVsFT0A"), aT0A / 100., sumZNs); - registry.fill(HIST("ZNVsFT0C"), aT0C / 100., sumZNs); - registry.fill(HIST("ZNVsFT0M"), (aT0A + aT0C) / 100., sumZNs); - registry.fill(HIST("NchVsNPV"), collision.multNTracksPVeta1(), nch); - registry.fill(HIST("NchVsITStracks"), itsTracks, nch); - registry.fill(HIST("ZNAVsNch"), nch, znA); - registry.fill(HIST("ZNCVsNch"), nch, znC); - registry.fill(HIST("ZNVsNch"), nch, sumZNs); - registry.fill(HIST("ZNDifVsNch"), nch, znA - znC); - registry.fill(HIST("NchVsZpos"), nch, collision.posZ()); - - // QA check + // To calculate event-averaged for (const auto& track : tracks) { // Track Selection if (!track.isGlobalTrack()) { continue; } registry.fill(HIST("NchVsPt"), w1, track.pt()); - registry.fill(HIST("ZposVsEta"), collision.posZ(), track.eta()); } // EbE one-particle pT correlation - // P1 / W1 double oneParCorr{p1 / w1}; // EbE two-particle pT correlation - // (P1^{2} - P2)/(W1^{2} - W2) double denTwoParCorr{std::pow(w1, 2.) - w2}; double numTwoParCorr{std::pow(p1, 2.) - p2}; double twoParCorr{numTwoParCorr / denTwoParCorr}; // EbE three-particle pT correlation - // (P1^{3} − 3P2P1 + 2P3)/(W1^{3} − 3W2W1 + 2W3) double denThreeParCorr{std::pow(w1, 3.) - 3. * w2 * w1 + 2. * w3}; double numThreeParCorr{std::pow(p1, 3.) - 3. * p2 * p1 + 2. * p3}; double threeParCorr{numThreeParCorr / denThreeParCorr}; // EbE four-particle pT correlation - // (P1^{4} − 6P2P1^{2} + 3P2^{2} + 8P3P1 − 6P4)/(W1^{4} − 6W2W1^{2} + - // 3W2^{2} + 8W3W1 − 6W4) - double denFourParCorr{std::pow(w1, 4.) - 6. * w2 * std::pow(w1, 2.) + - 3. * std::pow(w2, 2.) + 8 * w3 * w1 - 6. * w4}; - double numFourParCorr{std::pow(p1, 4.) - 6. * p2 * std::pow(p1, 2.) + - 3. * std::pow(p2, 2.) + 8 * p3 * p1 - 6. * p4}; + double denFourParCorr{std::pow(w1, 4.) - 6. * w2 * std::pow(w1, 2.) + 3. * std::pow(w2, 2.) + 8 * w3 * w1 - 6. * w4}; + double numFourParCorr{std::pow(p1, 4.) - 6. * p2 * std::pow(p1, 2.) + 3. * std::pow(p2, 2.) + 8 * p3 * p1 - 6. * p4}; double fourParCorr{numFourParCorr / denFourParCorr}; - if (isZNbasedSel && (sumZNs > znBasedCut)) - return; - if (isZNAbasedSel && (znA > znBasedCut)) - return; - if (isZNCbasedSel && (znC > znBasedCut)) + if (sumZNs > znBasedCut) { return; + } registry.fill(HIST("Nch"), w1); - registry.fill(HIST("NchRaw"), nch); + registry.fill(HIST("ZN"), sumZNs); registry.fill(HIST("NchVsOneParCorr"), w1, oneParCorr, w1); - registry.fill(HIST("NchVsTwoParCorr"), w1, twoParCorr, denTwoParCorr); - registry.fill(HIST("NchVsThreeParCorr"), w1, threeParCorr, denThreeParCorr); - registry.fill(HIST("NchVsFourParCorr"), w1, fourParCorr, denFourParCorr); + registry.fill(HIST("NchVsOneParCorrVsZN"), w1, sumZNs, oneParCorr, w1); + registry.fill(HIST("NchVsTwoParCorrVsZN"), w1, sumZNs, twoParCorr, denTwoParCorr); + registry.fill(HIST("NchVsThreeParCorrVsZN"), w1, sumZNs, threeParCorr, denThreeParCorr); + registry.fill(HIST("NchVsFourParCorrVsZN"), w1, sumZNs, fourParCorr, denFourParCorr); } PROCESS_SWITCH(UccZdc, processZdcCollAss, "Process ZDC W/Coll Ass.", true); - void processMCclosure( - aod::McCollisions::iterator const& mccollision, - soa::SmallGroups const& collisions, - aod::McParticles const& mcParticles, - TheFilteredSimTracks const& simTracks) + // Preslice perMCCollision = aod::mcparticle::mcCollisionId; + Preslice perCollision = aod::track::collisionId; + TRandom* randPointer = new TRandom(); + void processMCclosure(aod::McCollisions::iterator const& mccollision, soa::SmallGroups const& collisions, o2::aod::BCsRun3 const& /*bcs*/, aod::McParticles const& mcParticles, TheFilteredSimTracks const& simTracks) { - //----- MC reconstructed -----// - for (const auto& collision : collisions) { - // Event selection - if (!isEventSelected(collision)) - continue; - // MC collision? - if (!collision.has_mcCollision()) - continue; - - const auto& cent{collision.centFT0C()}; - registry.fill(HIST("T0Ccent"), cent); - registry.fill(HIST("zPos"), collision.posZ()); - // registry.fill(HIST("nRecColvsCent"), collisions.size(), cent); - - const auto& groupedTracks = - simTracks.sliceBy(perCollision, collision.globalIndex()); - std::vector pTs; - std::vector wIs; - - // Calculates the event weight, W_k - for (const auto& track : groupedTracks) { - // Track Selection - if (!track.isGlobalTrack()) - continue; - - // To match the primary particles - if (!track.has_mcParticle()) - continue; - const auto& particle = track.mcParticle(); - if (!particle.isPhysicalPrimary()) - continue; - - float pt{track.pt()}; - double trkEff{efficiency->GetBinContent(efficiency->FindBin(pt))}; - if (trkEff > 0.) { - pTs.emplace_back(pt); - wIs.emplace_back(1. / trkEff); + float rndNum = randPointer->Uniform(0.0, 1.0); + registry.fill(HIST("RandomNumber"), rndNum); + + // Half of the statistics for MC closure + if (rndNum >= zEro && rndNum < oneHalf) { + registry.fill(HIST("EvtsDivided"), 0); + //----- MC reconstructed -----// + for (const auto& collision : collisions) { + + // To use run-by-run efficiency + const auto& foundBC = collision.foundBC_as(); + // auto efficiency = ccdb->getForTimeStamp(paTH.value, foundBC.timestamp()); + auto efficiency = ccdb->getForRun(paTH.value, foundBC.runNumber()); + if (!efficiency) { + LOGF(fatal, "Efficiency object not found!"); } - } - const double nch{static_cast(pTs.size())}; - if (!(nch != 0.)) - return; - - double p1, p2, p3, p4, w1, w2, w3, w4; - p1 = p2 = p3 = p4 = w1 = w2 = w3 = w4 = 0.0; - getPTpowers(pTs, wIs, p1, w1, p2, w2, p3, w3, p4, w4); - - const double denTwoParCorr{std::pow(w1, 2.) - w2}; - const double numTwoParCorr{std::pow(p1, 2.) - p2}; - const double denThreeParCorr{std::pow(w1, 3.) - 3. * w2 * w1 + 2. * w3}; - const double numThreeParCorr{std::pow(p1, 3.) - 3. * p2 * p1 + 2. * p3}; - const double denFourParCorr{ - std::pow(w1, 4.) - 6. * w2 * std::pow(w1, 2.) + - 3. * std::pow(w2, 2.) + 8 * w3 * w1 - 6. * w4}; - const double numFourParCorr{ - std::pow(p1, 4.) - 6. * p2 * std::pow(p1, 2.) + - 3. * std::pow(p2, 2.) + 8 * p3 * p1 - 6. * p4}; - - const double oneParCorr{p1 / w1}; - const double twoParCorr{numTwoParCorr / denTwoParCorr}; - const double threeParCorr{numThreeParCorr / denThreeParCorr}; - const double fourParCorr{numFourParCorr / denFourParCorr}; - - registry.fill(HIST("Nch"), w1); - registry.fill(HIST("NchRaw"), nch); - registry.fill(HIST("NchVsOneParCorr"), w1, oneParCorr, w1); - registry.fill(HIST("NchVsTwoParCorr"), w1, twoParCorr, denTwoParCorr); - registry.fill(HIST("NchVsThreeParCorr"), w1, threeParCorr, - denThreeParCorr); - registry.fill(HIST("NchVsFourParCorr"), w1, fourParCorr, denFourParCorr); - - //--------------------------- Generated MC --------------------------- - if (std::fabs(mccollision.posZ()) > posZcut) - continue; - - std::vector pTsMC; - std::vector wIsMC; - - // Calculates the event weight, W_k - for (const auto& particle : mcParticles) { - if (particle.eta() < minEta || particle.eta() > maxEta) - continue; - if (particle.pt() < minPt || particle.pt() > maxPt) + // Event selection + if (!isEventSelected(collision)) { continue; - if (!particle.isPhysicalPrimary()) + } + // MC collision? + if (!collision.has_mcCollision()) { continue; + } - float pt{particle.pt()}; - pTsMC.emplace_back(pt); - wIsMC.emplace_back(1.); - } - - const double nchMC{static_cast(pTsMC.size())}; - double p1MC, p2MC, p3MC, p4MC, w1MC, w2MC, w3MC, w4MC; - p1MC = p2MC = p3MC = p4MC = w1MC = w2MC = w3MC = w4MC = 0.0; - getPTpowers(pTsMC, wIsMC, p1MC, w1MC, p2MC, w2MC, p3MC, w3MC, p4MC, w4MC); - - const double denTwoParCorrMC{std::pow(w1MC, 2.) - w2MC}; - const double numTwoParCorrMC{std::pow(p1MC, 2.) - p2MC}; - const double denThreeParCorrMC{std::pow(w1MC, 3.) - 3. * w2MC * w1MC + - 2. * w3MC}; - const double numThreeParCorrMC{std::pow(p1MC, 3.) - 3. * p2MC * p1MC + - 2. * p3MC}; - const double denFourParCorrMC{ - std::pow(w1MC, 4.) - 6. * w2MC * std::pow(w1MC, 2.) + - 3. * std::pow(w2MC, 2.) + 8 * w3MC * w1MC - 6. * w4MC}; - const double numFourParCorrMC{ - std::pow(p1MC, 4.) - 6. * p2MC * std::pow(p1MC, 2.) + - 3. * std::pow(p2MC, 2.) + 8 * p3MC * p1MC - 6. * p4MC}; - - const double oneParCorrMC{p1MC / w1MC}; - const double twoParCorrMC{numTwoParCorrMC / denTwoParCorrMC}; - const double threeParCorrMC{numThreeParCorrMC / denThreeParCorrMC}; - const double fourParCorrMC{numFourParCorrMC / denFourParCorrMC}; - - registry.fill(HIST("NchGen"), nchMC); - registry.fill(HIST("NchvsOneParCorrGen"), nchMC, oneParCorrMC, w1MC); - registry.fill(HIST("NchvsTwoParCorrGen"), nchMC, twoParCorrMC, - denTwoParCorrMC); - registry.fill(HIST("NchvsThreeParCorrGen"), nchMC, threeParCorrMC, - denThreeParCorrMC); - registry.fill(HIST("NchvsFourParCorrGen"), nchMC, fourParCorrMC, - denFourParCorrMC); - } - } - PROCESS_SWITCH(UccZdc, processMCclosure, "Process MC closure", false); - - Preslice perMCCollision = aod::mcparticle::mcCollisionId; - Preslice perCollision = aod::track::collisionId; - void processpTEff(aod::McCollisions::iterator const& mccollision, - soa::SmallGroups const& collisions, - aod::McParticles const& mcParticles, - TheFilteredSimTracks const& simTracks) - { - //----- MC reconstructed -----// - for (const auto& collision : collisions) { - // Event selection - if (!isEventSelected(collision)) - continue; - - // MC collision? - if (!collision.has_mcCollision()) - continue; - - registry.fill(HIST("zPos"), collision.posZ()); - registry.fill(HIST("nRecColvsCent"), collisions.size(), - collision.centFT0C()); - - const auto& cent{collision.centFT0C()}; - registry.fill(HIST("T0Ccent"), cent); - - const auto& groupedTracks = - simTracks.sliceBy(perCollision, collision.globalIndex()); - for (const auto& track : groupedTracks) { - if (!track.has_mcParticle()) - continue; + registry.fill(HIST("T0Ccent"), collision.centFT0C()); + registry.fill(HIST("zPos"), collision.posZ()); + + const auto& groupedTracks{simTracks.sliceBy(perCollision, collision.globalIndex())}; + + std::vector pTs; + std::vector wIs; + // Calculates the event weight, W_k + for (const auto& track : groupedTracks) { + // Track Selection + if (!track.isGlobalTrack()) { + continue; + } + + float pt{track.pt()}; + double weight{efficiency->GetBinContent(efficiency->FindBin(pt))}; + if (weight > 0.) { + pTs.emplace_back(pt); + wIs.emplace_back(weight); + } + } - const auto& particle = track.mcParticle(); - registry.fill(HIST("Pt_all_ch"), cent, track.pt()); - registry.fill(HIST("EtaVsPhi"), track.eta(), track.phi()); + const double nch{static_cast(pTs.size())}; + if (nch < minNchSel) { + return; + } - if (!particle.isPhysicalPrimary()) + double p1, p2, p3, p4, w1, w2, w3, w4; + p1 = p2 = p3 = p4 = w1 = w2 = w3 = w4 = 0.0; + getPTpowers(pTs, wIs, p1, w1, p2, w2, p3, w3, p4, w4); + + const double denTwoParCorr{std::pow(w1, 2.) - w2}; + const double numTwoParCorr{std::pow(p1, 2.) - p2}; + const double denThreeParCorr{std::pow(w1, 3.) - 3. * w2 * w1 + 2. * w3}; + const double numThreeParCorr{std::pow(p1, 3.) - 3. * p2 * p1 + 2. * p3}; + const double denFourParCorr{std::pow(w1, 4.) - 6. * w2 * std::pow(w1, 2.) + 3. * std::pow(w2, 2.) + 8 * w3 * w1 - 6. * w4}; + const double numFourParCorr{std::pow(p1, 4.) - 6. * p2 * std::pow(p1, 2.) + 3. * std::pow(p2, 2.) + 8 * p3 * p1 - 6. * p4}; + + const double oneParCorr{p1 / w1}; + const double twoParCorr{numTwoParCorr / denTwoParCorr}; + const double threeParCorr{numThreeParCorr / denThreeParCorr}; + const double fourParCorr{numFourParCorr / denFourParCorr}; + + registry.fill(HIST("Nch"), w1); + registry.fill(HIST("NchRaw"), nch); + registry.fill(HIST("NchVsOneParCorr"), w1, oneParCorr, w1); + registry.fill(HIST("NchVsTwoParCorr"), w1, twoParCorr, denTwoParCorr); + registry.fill(HIST("NchVsThreeParCorr"), w1, threeParCorr, denThreeParCorr); + registry.fill(HIST("NchVsFourParCorr"), w1, fourParCorr, denFourParCorr); + + //--------------------------- Generated MC --------------------------- + registry.fill(HIST("hEventCounterMC"), EvCutLabel::All); + if (std::fabs(mccollision.posZ()) > posZcut) { continue; - - registry.fill(HIST("Pt_ch"), cent, track.pt()); - if (particle.pdgCode() == PDG_t::kPiPlus || - particle.pdgCode() == PDG_t::kPiMinus) { - registry.fill(HIST("Pt_pi"), cent, track.pt()); - } else if (particle.pdgCode() == PDG_t::kKPlus || - particle.pdgCode() == PDG_t::kKMinus) { - registry.fill(HIST("Pt_ka"), cent, track.pt()); - } else if (particle.pdgCode() == PDG_t::kProton || - particle.pdgCode() == PDG_t::kProtonBar) { - registry.fill(HIST("Pt_pr"), cent, track.pt()); - } else if (particle.pdgCode() == PDG_t::kSigmaPlus || - particle.pdgCode() == PDG_t::kSigmaBarMinus) { - registry.fill(HIST("Pt_sigpos"), cent, track.pt()); - } else if (particle.pdgCode() == PDG_t::kSigmaMinus || - particle.pdgCode() == PDG_t::kSigmaBarPlus) { - registry.fill(HIST("Pt_signeg"), cent, track.pt()); - } else { - registry.fill(HIST("Pt_re"), cent, track.pt()); } - } + registry.fill(HIST("zPosMC"), mccollision.posZ()); + registry.fill(HIST("hEventCounterMC"), EvCutLabel::VtxZ); + + std::vector pTsMC; + std::vector wIsMC; + // Calculates the event weight, W_k + for (const auto& particle : mcParticles) { + if (particle.eta() < minEta || particle.eta() > maxEta) { + continue; + } + if (particle.pt() < minPt || particle.pt() > maxPt) { + continue; + } + if (!particle.isPhysicalPrimary()) { + continue; + } + + float pt{particle.pt()}; + pTsMC.emplace_back(pt); + wIsMC.emplace_back(1.); + } - // Generated MC - registry.fill(HIST("hEventCounterMC"), EvCutLabel::All); - if (std::fabs(mccollision.posZ()) > posZcut) - continue; - registry.fill(HIST("zPosMC"), mccollision.posZ()); - registry.fill(HIST("hEventCounterMC"), EvCutLabel::VtxZ); + const double nchMC{static_cast(pTsMC.size())}; + if (nchMC < minNchSel) { + return; + } - for (const auto& particle : mcParticles) { - if (particle.eta() < minEta || particle.eta() > maxEta) { + double p1MC, p2MC, p3MC, p4MC, w1MC, w2MC, w3MC, w4MC; + p1MC = p2MC = p3MC = p4MC = w1MC = w2MC = w3MC = w4MC = 0.0; + getPTpowers(pTsMC, wIsMC, p1MC, w1MC, p2MC, w2MC, p3MC, w3MC, p4MC, w4MC); + + const double denTwoParCorrMC{std::pow(w1MC, 2.) - w2MC}; + const double numTwoParCorrMC{std::pow(p1MC, 2.) - p2MC}; + const double denThreeParCorrMC{std::pow(w1MC, 3.) - 3. * w2MC * w1MC + 2. * w3MC}; + const double numThreeParCorrMC{std::pow(p1MC, 3.) - 3. * p2MC * p1MC + 2. * p3MC}; + const double denFourParCorrMC{std::pow(w1MC, 4.) - 6. * w2MC * std::pow(w1MC, 2.) + 3. * std::pow(w2MC, 2.) + 8 * w3MC * w1MC - 6. * w4MC}; + const double numFourParCorrMC{std::pow(p1MC, 4.) - 6. * p2MC * std::pow(p1MC, 2.) + 3. * std::pow(p2MC, 2.) + 8 * p3MC * p1MC - 6. * p4MC}; + + const double oneParCorrMC{p1MC / w1MC}; + const double twoParCorrMC{numTwoParCorrMC / denTwoParCorrMC}; + const double threeParCorrMC{numThreeParCorrMC / denThreeParCorrMC}; + const double fourParCorrMC{numFourParCorrMC / denFourParCorrMC}; + + registry.fill(HIST("NchGen"), nchMC); + registry.fill(HIST("NchvsOneParCorrGen"), nchMC, oneParCorrMC, w1MC); + registry.fill(HIST("NchvsTwoParCorrGen"), nchMC, twoParCorrMC, denTwoParCorrMC); + registry.fill(HIST("NchvsThreeParCorrGen"), nchMC, threeParCorrMC, denThreeParCorrMC); + registry.fill(HIST("NchvsFourParCorrGen"), nchMC, fourParCorrMC, denFourParCorrMC); + } + } else { // Correction with the remaining half of the sample + registry.fill(HIST("EvtsDivided"), 1); + //----- MC reconstructed -----// + for (const auto& collision : collisions) { + // Event selection + if (!isEventSelected(collision)) { continue; } - if (particle.pt() < minPt || particle.pt() > maxPt) { + // MC collision? + if (!collision.has_mcCollision()) { continue; } - if (!particle.isPhysicalPrimary()) { + + registry.fill(HIST("zPos"), collision.posZ()); + registry.fill(HIST("nRecColvsCent"), collisions.size(), collision.centFT0C()); + + const auto& cent{collision.centFT0C()}; + registry.fill(HIST("T0Ccent"), cent); + + const auto& groupedTracks{simTracks.sliceBy(perCollision, collision.globalIndex())}; + for (const auto& track : groupedTracks) { + // Track Selection + if (!track.isGlobalTrack()) { + continue; + } + + // Has MC particle? + if (!track.has_mcParticle()) { + continue; + } + + const auto& particle{track.mcParticle()}; + registry.fill(HIST("Pt_all_ch"), cent, track.pt()); + registry.fill(HIST("EtaVsPhi"), track.eta(), track.phi()); + + if (!particle.isPhysicalPrimary()) { + continue; + } + + registry.fill(HIST("Pt_ch"), cent, track.pt()); + if (particle.pdgCode() == PDG_t::kPiPlus || particle.pdgCode() == PDG_t::kPiMinus) { + registry.fill(HIST("Pt_pi"), cent, track.pt()); + } else if (particle.pdgCode() == PDG_t::kKPlus || particle.pdgCode() == PDG_t::kKMinus) { + registry.fill(HIST("Pt_ka"), cent, track.pt()); + } else if (particle.pdgCode() == PDG_t::kProton || particle.pdgCode() == PDG_t::kProtonBar) { + registry.fill(HIST("Pt_pr"), cent, track.pt()); + } else if (particle.pdgCode() == PDG_t::kSigmaPlus || particle.pdgCode() == PDG_t::kSigmaBarMinus) { + registry.fill(HIST("Pt_sigpos"), cent, track.pt()); + } else if (particle.pdgCode() == PDG_t::kSigmaMinus || particle.pdgCode() == PDG_t::kSigmaBarPlus) { + registry.fill(HIST("Pt_signeg"), cent, track.pt()); + } else { + registry.fill(HIST("Pt_re"), cent, track.pt()); + } + } + + // Generated MC + registry.fill(HIST("hEventCounterMC"), EvCutLabel::All); + if (std::fabs(mccollision.posZ()) > posZcut) { continue; } - registry.fill(HIST("PtMC_ch"), cent, particle.pt()); - if (particle.pdgCode() == PDG_t::kPiPlus || - particle.pdgCode() == PDG_t::kPiMinus) { // pion - registry.fill(HIST("PtMC_pi"), cent, particle.pt()); - } else if (particle.pdgCode() == PDG_t::kKPlus || - particle.pdgCode() == PDG_t::kKMinus) { // kaon - registry.fill(HIST("PtMC_ka"), cent, particle.pt()); - } else if (particle.pdgCode() == PDG_t::kProton || - particle.pdgCode() == PDG_t::kProtonBar) { // proton - registry.fill(HIST("PtMC_pr"), cent, particle.pt()); - } else if (particle.pdgCode() == PDG_t::kSigmaPlus || - particle.pdgCode() == - PDG_t::kSigmaBarMinus) { // positive sigma - registry.fill(HIST("PtMC_sigpos"), cent, particle.pt()); - } else if (particle.pdgCode() == PDG_t::kSigmaMinus || - particle.pdgCode() == - PDG_t::kSigmaBarPlus) { // negative sigma - registry.fill(HIST("PtMC_signeg"), cent, particle.pt()); - } else { // rest - registry.fill(HIST("PtMC_re"), cent, particle.pt()); + registry.fill(HIST("zPosMC"), mccollision.posZ()); + registry.fill(HIST("hEventCounterMC"), EvCutLabel::VtxZ); + + for (const auto& particle : mcParticles) { + if (particle.eta() < minEta || particle.eta() > maxEta) { + continue; + } + if (particle.pt() < minPt || particle.pt() > maxPt) { + continue; + } + if (!particle.isPhysicalPrimary()) { + continue; + } + + registry.fill(HIST("PtMC_ch"), cent, particle.pt()); + if (particle.pdgCode() == PDG_t::kPiPlus || particle.pdgCode() == PDG_t::kPiMinus) { // pion + registry.fill(HIST("PtMC_pi"), cent, particle.pt()); + } else if (particle.pdgCode() == PDG_t::kKPlus || particle.pdgCode() == PDG_t::kKMinus) { // kaon + registry.fill(HIST("PtMC_ka"), cent, particle.pt()); + } else if (particle.pdgCode() == PDG_t::kProton || particle.pdgCode() == PDG_t::kProtonBar) { // proton + registry.fill(HIST("PtMC_pr"), cent, particle.pt()); + } else if (particle.pdgCode() == PDG_t::kSigmaPlus || particle.pdgCode() == PDG_t::kSigmaBarMinus) { // positive sigma + registry.fill(HIST("PtMC_sigpos"), cent, particle.pt()); + } else if (particle.pdgCode() == PDG_t::kSigmaMinus || particle.pdgCode() == PDG_t::kSigmaBarPlus) { // negative sigma + registry.fill(HIST("PtMC_signeg"), cent, particle.pt()); + } else { // rest + registry.fill(HIST("PtMC_re"), cent, particle.pt()); + } } } - } + } // Half of statistics for corrections } - PROCESS_SWITCH(UccZdc, processpTEff, "Process pT Eff", false); + PROCESS_SWITCH(UccZdc, processMCclosure, "Process MC closure", false); template - void getPTpowers(const T& pTs, const T& wIs, U& pOne, U& wOne, U& pTwo, - U& wTwo, U& pThree, U& wThree, U& pFour, U& wFour) + void getPTpowers(const T& pTs, const T& wIs, U& pOne, U& wOne, U& pTwo, U& wTwo, U& pThree, U& wThree, U& pFour, U& wFour) { pOne = wOne = pTwo = wTwo = pThree = wThree = pFour = wFour = 0.; - for (std::size_t i = 0; i < pTs.size(); ++i) { const float pTi{pTs.at(i)}; const float wEighti{wIs.at(i)}; diff --git a/PWGLF/Tasks/Nuspex/CMakeLists.txt b/PWGLF/Tasks/Nuspex/CMakeLists.txt index cc9e0599e7a..0f16d5e7b58 100644 --- a/PWGLF/Tasks/Nuspex/CMakeLists.txt +++ b/PWGLF/Tasks/Nuspex/CMakeLists.txt @@ -149,6 +149,11 @@ o2physics_add_dpl_workflow(nuclei-from-hypertriton-map PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(hyperhelium4sigma-analysis + SOURCES hyperhelium4sigmaAnalysis.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + if(FastJet_FOUND) o2physics_add_dpl_workflow(angular-correlations-in-jets SOURCES angularCorrelationsInJets.cxx diff --git a/PWGLF/Tasks/Nuspex/NucleitpcPbPb.cxx b/PWGLF/Tasks/Nuspex/NucleitpcPbPb.cxx index b3e72ed23a5..100072becbb 100644 --- a/PWGLF/Tasks/Nuspex/NucleitpcPbPb.cxx +++ b/PWGLF/Tasks/Nuspex/NucleitpcPbPb.cxx @@ -8,99 +8,86 @@ // 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. -/// \author jaideep tanwar +/// \file NucleitpcPbPb.cxx +/// \brief Analysis task for light nuclei spectra in Pb–Pb collisions using TPC +/// \author Jaideep Tanwar, +/// \since Jan 2025 /// #include -#include #include -#include -#include -#include -#include -#include +#include +#include +#include #include "Framework/runDataProcessing.h" #include "Framework/AnalysisTask.h" #include "Framework/AnalysisDataModel.h" #include "Framework/ASoAHelpers.h" -#include "ReconstructionDataFormats/Track.h" #include "Common/Core/RecoDecay.h" #include "Common/Core/trackUtilities.h" +#include "Common/Core/PID/TPCPIDResponse.h" #include "Common/DataModel/TrackSelectionTables.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Centrality.h" -#include "DetectorsBase/Propagator.h" +#include "Common/DataModel/PIDResponse.h" +#include "Common/DataModel/CollisionAssociationTables.h" +#include "ReconstructionDataFormats/Track.h" +#include "DataFormatsTPC/BetheBlochAleph.h" #include "DataFormatsParameters/GRPObject.h" #include "DataFormatsParameters/GRPMagField.h" +#include "DetectorsBase/GeometryManager.h" +#include "DetectorsBase/Propagator.h" #include "CCDB/BasicCCDBManager.h" -#include "CommonConstants/PhysicsConstants.h" -#include "Common/Core/PID/TPCPIDResponse.h" -#include "DataFormatsTPC/BetheBlochAleph.h" -#include "Common/DataModel/PIDResponse.h" -#include "TRandom3.h" -#include "Common/DataModel/CollisionAssociationTables.h" - +#include "DCAFitter/DCAFitterN.h" using namespace o2; -using namespace o2::track; using namespace o2::framework; using namespace o2::framework::expressions; - using CollisionsFull = soa::Join; -/* -using CollisionsFullMC = soa::Join; -*/ -using TracksFull = soa::Join; +using TracksFull = soa::Join; +//--------------------------------------------------------------------------------------------------------------------------------- namespace { -static const int number_of_particles = 6; -static const std::vector particleNames{"pion", "proton", "deuteron", "triton", "helium3", "alpha"}; -static const std::vector antiparticleNames{"anti-pion", "anti-proton", "anti-deuteron", "anti-triton", "anti-helium3", "anti-alpha"}; +static const int nParticles = 6; +static const std::vector particleNames{"pion", "proton", "deuteron", "triton", "helion", "alpha"}; static const std::vector particlePdgCodes{211, 2212, o2::constants::physics::kDeuteron, o2::constants::physics::kTriton, o2::constants::physics::kHelium3, o2::constants::physics::kAlpha}; static const std::vector particleMasses{o2::constants::physics::MassPionCharged, o2::constants::physics::MassProton, o2::constants::physics::MassDeuteron, o2::constants::physics::MassTriton, o2::constants::physics::MassHelium3, o2::constants::physics::MassAlpha}; static const std::vector particleCharge{1, 1, 1, 1, 2, 2}; -const int no_BBparam = 6; +const int nBetheParams = 6; static const std::vector betheBlochParNames{"p0", "p1", "p2", "p3", "p4", "resolution"}; -// default bethbloch parameters -constexpr double betheBlochDefault[number_of_particles][no_BBparam]{ +constexpr double betheBlochDefault[nParticles][nBetheParams]{ {13.611469, 3.598765, -0.021138, 2.039562, 0.651040, 0.09}, // pion {5.393020, 7.859534, 0.004048, 2.323197, 1.609307, 0.09}, // proton {5.393020, 7.859534, 0.004048, 2.323197, 1.609307, 0.09}, // deuteron {5.393020, 7.859534, 0.004048, 2.323197, 1.609307, 0.09}, // triton - {-126.557359, -0.858569, 1.111643, 1.210323, 2.656374, 0.09}, // helium3 + {-126.557359, -0.858569, 1.111643, 1.210323, 2.656374, 0.09}, // helion {-126.557359, -0.858569, 1.111643, 1.210323, 2.656374, 0.09}}; // alpha -const int no_trackcuts = 15; -static const std::vector trackPIDsettingsNames{"useBBparams", "minITSnCls", "minTPCnCls", "maxTPCchi2", "maxITSchi2", "minRigidity", "maxRigidity", "maxTPCnSigma", "TOFrequiredabove", "minTOFmass", "maxTOFmass", "minDcaToPvXY", "minDcaToPvZ", "minITSclsSize", "maxITSclsSize"}; -constexpr double trackPIDsettings[number_of_particles][no_trackcuts]{ - {0, 0, 60, 3.0, 100, 0.15, 1.2, 3.0, 1, 0, 100, 0., 0., 0., 1000}, - {1, 0, 60, 3.0, 100, 0.20, 4.0, 3.0, 1, 0, 100, 0., 0., 0., 1000}, - {1, 0, 60, 3.0, 100, 0.50, 5.0, 3.0, 1, 0, 100, 0., 0., 0., 1000}, - {1, 0, 60, 3.0, 100, 0.50, 5.0, 3.0, 1, 0, 100, 0., 0., 0., 1000}, - {1, 0, 60, 3.0, 100, 0.50, 5.0, 3.0, 1, 0, 100, 0., 0., 0., 1000}, - {1, 0, 60, 3.0, 100, 0.50, 5.0, 3.0, 1, 0, 100, 0., 0., 0., 1000}}; -struct Particle { +const int nTrkSettings = 15; +static const std::vector trackPIDsettingsNames{"useBBparams", "minITSnCls", "minTPCnCls", "maxTPCchi2", "maxITSchi2", "minRigidity", "maxRigidity", "maxTPCnSigma", "TOFrequiredabove", "minTOFmass", "maxTOFmass", "maxDcaXY", "maxDcaZ", "minITSclsSize", "maxITSclsSize"}; +constexpr double trackPIDsettings[nParticles][nTrkSettings]{ + {0, 0, 60, 3.0, 100, 0.15, 1.2, 2.5, -1, 0, 100, 2., 2., 0., 1000}, + {1, 0, 70, 2.5, 100, 0.20, 4.0, 3.0, -1, 0, 100, 2., 2., 0., 1000}, + {1, 0, 70, 5.0, 100, 0.50, 5.0, 3.0, -1, 0, 100, 2., 2., 0., 1000}, + {1, 0, 70, 5.0, 100, 0.50, 5.0, 3.0, -1, 0, 100, 2., 2., 0., 1000}, + {1, 0, 75, 1.5, 100, 0.50, 5.0, 3.0, -1, 0, 100, 2., 2., 0., 1000}, + {1, 0, 70, 1.5, 100, 0.50, 5.0, 3.0, -1, 0, 100, 2., 2., 0., 1000}}; +struct PrimParticles { TString name; int pdgCode, charge; double mass, resolution; std::vector betheParams; bool active; - Particle(std::string name_, int pdgCode_, double mass_, int charge_, LabeledArray bethe) : name(name_), pdgCode(pdgCode_), charge(charge_), mass(mass_), active(false) + PrimParticles(std::string name_, int pdgCode_, double mass_, int charge_, LabeledArray bethe) : name(name_), pdgCode(pdgCode_), charge(charge_), mass(mass_), active(false) { resolution = bethe.get(name, "resolution"); betheParams.clear(); - for (unsigned int i = 0; i < 5; i++) + constexpr unsigned int kNSpecies = 5; + for (unsigned int i = 0; i < kNSpecies; i++) betheParams.push_back(bethe.get(name, i)); } -}; // struct Particle +}; // struct PrimParticles //---------------------------------------------------------------------------------------------------------------- std::vector> hDeDx; -std::vector> hDeDxanti; -std::vector> hnsigma_pt; -std::vector> hnsigma_ptanti; -std::vector> hdcaXY_pt; -std::vector> hdcaXY_ptanti; -std::vector> hrapidity; -std::vector> hmass_pt; -std::vector> hmass_ptanti; -std::vector> hdelta_mass; +std::vector> hNsigmaPt; +std::vector> hmass; } // namespace //---------------------------------------------------------------------------------------------------------------- struct NucleitpcPbPb { @@ -108,12 +95,20 @@ struct NucleitpcPbPb { HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; Configurable cfgDebug{"cfgDebug", 1, "debug level"}; Configurable cfgRigidityCorrection{"cfgRigidityCorrection", false, "apply rigidity correction"}; - Configurable cfgCutEta{"cfgCutEta", 0.8f, "Eta range for tracks"}; - Configurable centcut{"centcut", 80.0f, "centrality cut"}; + Configurable cfgCutEta{"cfgCutEta", 0.9f, "Eta range for tracks"}; Configurable cfgUsePVcontributors{"cfgUsePVcontributors", true, "use tracks that are PV contibutors"}; - Configurable> cfgBetheBlochParams{"cfgBetheBlochParams", {betheBlochDefault[0], number_of_particles, no_BBparam, particleNames, betheBlochParNames}, "TPC Bethe-Bloch parameterisation for light nuclei"}; - Configurable> cfgTrackPIDsettings{"cfgTrackPIDsettings", {trackPIDsettings[0], number_of_particles, no_trackcuts, particleNames, trackPIDsettingsNames}, "track selection and PID criteria"}; - Configurable maxDcaXYFactor{"maxDcaXYFactor", 2.0f, "DCA xy factor"}; + Configurable> cfgBetheBlochParams{"cfgBetheBlochParams", {betheBlochDefault[0], nParticles, nBetheParams, particleNames, betheBlochParNames}, "TPC Bethe-Bloch parameterisation for light nuclei"}; + Configurable> cfgTrackPIDsettings{"cfgTrackPIDsettings", {trackPIDsettings[0], nParticles, nTrkSettings, particleNames, trackPIDsettingsNames}, "track selection and PID criteria"}; + Configurable cfgFillDeDxWithoutCut{"cfgFillDeDxWithoutCut", false, "Fill without cut beth bloch"}; + Configurable cfgFillDeDxWithCut{"cfgFillDeDxWithCut", false, "Fill with cut beth bloch"}; + Configurable cfgFillnsigma{"cfgFillnsigma", false, "Fill n-sigma histograms"}; + Configurable cfgFillmass{"cfgFillmass", true, "Fill mass histograms"}; + Configurable centcut{"centcut", 80.0f, "centrality cut"}; + Configurable cfgCutRapidity{"cfgCutRapidity", 0.5f, "Rapidity range"}; + Configurable cfgZvertex{"cfgZvertex", 10, "Min Z Vertex"}; + Configurable cfgtpcNClsFound{"cfgtpcNClsFound", 100.0f, "min. no. of tpcNClsFound"}; + Configurable cfgitsNCls{"cfgitsNCls", 2.0f, "min. no. of itsNCls"}; + // CCDB Service ccdb; Configurable bField{"bField", -999, "bz field, -999 is automatic"}; @@ -123,15 +118,12 @@ struct NucleitpcPbPb { Configurable lutPath{"lutPath", "GLO/Param/MatLUT", "Path of the Lut parametrization"}; Configurable geoPath{"geoPath", "GLO/Config/GeometryAligned", "Path of the geometry file"}; Configurable pidPath{"pidPath", "", "Path to the PID response object"}; - //-------------------------------------------------------------------------------------------------------------------- - std::vector primaryParticles; + std::vector primaryParticles; std::vector primVtx, cents; bool collHasCandidate, collPassedEvSel; int mRunNumber, occupancy; - float dBz; + float dBz, momn; TRandom3 rand; - double momn; - //---------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------- void init(InitContext const&) { @@ -142,93 +134,82 @@ struct NucleitpcPbPb { ccdb->setCaching(true); ccdb->setLocalObjectValidityChecking(); ccdb->setFatalWhenNull(false); - for (int i = 0; i < number_of_particles; i++) { // create primaryparticles - primaryParticles.push_back(Particle(particleNames.at(i), particlePdgCodes.at(i), particleMasses.at(i), particleCharge.at(i), cfgBetheBlochParams)); + for (int i = 0; i < nParticles; i++) { // create primaryParticles + primaryParticles.push_back(PrimParticles(particleNames.at(i), particlePdgCodes.at(i), particleMasses.at(i), particleCharge.at(i), cfgBetheBlochParams)); } - std::vector ptBinning = {0.1, 0.5, 1.0, 1.5, 2.0, 2.4, 3.2, 4., 5., 6., 8., 10., 12., 14.}; - std::vector etaBinning = {-1.0, -0.9, -0.8, -0.7, -0.6, -0.5, -0.4, -0.3, -0.2, -0.1, 0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0}; // define histogram axes const AxisSpec axisMagField{10, -10., 10., "magnetic field"}; - const AxisSpec axisNev{3, 0., 5., "Number of events"}; + const AxisSpec axisNev{3, 0., 3., "Number of events"}; const AxisSpec axisRigidity{4000, -10., 10., "#it{p}^{TPC}/#it{z}"}; - const AxisSpec axisdEdx{30000, 0, 3000, "d#it{E}/d#it{x}"}; + const AxisSpec axisdEdx{2000, 0, 2000, "d#it{E}/d#it{x}"}; const AxisSpec axisCent{100, 0, 100, "centrality"}; const AxisSpec axisVtxZ{100, -20, 20, "z"}; - const AxisSpec axisDCAZ{100, -10, 10, "z"}; - // const AxisSpec axiseta{100, -1, 1, "eta"}; + const AxisSpec ptAxis{100, 0, 20, "#it{p}_{T} (GeV/#it{c})"}; + const AxisSpec axiseta{100, -1, 1, "eta"}; const AxisSpec axisrapidity{100, -2, 2, "rapidity"}; - AxisSpec axiseta = {etaBinning, "#eta"}; - AxisSpec axismass = {100, -0.5, 15, "mass^{2}"}; - AxisSpec axisdelta_mass = {100, -6, 6, "#delta mass^{2}"}; - AxisSpec ptAxis = {ptBinning, "#it{p}_{T} (GeV/#it{c})"}; - AxisSpec dcaXY = {100, -2, 2, "dcaXY"}; + const AxisSpec axismass{100, 0, 20, "mass^{2}"}; AxisSpec nsigmaAxis = {160, -20, 20, "n#sigma_{#pi^{+}}"}; // create histograms - histos.add("histMagField", "histMagField", kTH1F, {axisMagField}); - histos.add("histNev", "histNev", kTH1F, {axisNev}); - histos.add("histVtxZ", "histVtxZ", kTH1F, {axisVtxZ}); - histos.add("histCentFT0A", "histCentFT0A", kTH1F, {axisCent}); - histos.add("histCentFT0C", "histCentFT0C", kTH1F, {axisCent}); - histos.add("histCentFTOC_cut", "histCentFTOC_cut", kTH1F, {axisCent}); - histos.add("histCentFT0M", "histCentFT0M", kTH1F, {axisCent}); histos.add("histeta", "histeta", kTH1F, {axiseta}); + histos.add("histCentFTOC_cut", "histCentFTOC_cut", kTH1F, {axisCent}); histos.add("Tof_signal", "Tof_signal", kTH2F, {axisRigidity, {4000, 0.2, 1.2, "#beta"}}); histos.add("histDcaZVsPtData_particle", "dcaZ vs Pt (particle)", HistType::kTH2F, {{1000, 0, 20}, {1000, -2.5, 2.5, "dca"}}); histos.add("histDcaXYVsPtData_particle", "dcaXY vs Pt (particle)", HistType::kTH2F, {{1000, 0, 20}, {1000, -2.0, 2.0, "dca"}}); histos.add("histDcaZVsPtData_antiparticle", "dcaZ vs Pt (antiparticle)", HistType::kTH2F, {{1000, 0, 20}, {1000, -2.5, 2.5, "dca"}}); histos.add("histDcaXYVsPtData_antiparticle", "dcaXY vs Pt (antiparticle)", HistType::kTH2F, {{1000, 0, 20}, {1000, -2.0, 2.0, "dca"}}); - hDeDx.resize(2 * number_of_particles + 2); - hDeDxanti.resize(2 * number_of_particles + 2); - hnsigma_pt.resize(2 * number_of_particles + 2); - hnsigma_ptanti.resize(2 * number_of_particles + 2); - hdcaXY_pt.resize(2 * number_of_particles + 2); - hdcaXY_ptanti.resize(2 * number_of_particles + 2); - hrapidity.resize(2 * number_of_particles + 2); - hmass_pt.resize(2 * number_of_particles + 2); - hmass_ptanti.resize(2 * number_of_particles + 2); - hdelta_mass.resize(2 * number_of_particles + 2); - for (int i = 0; i <= number_of_particles; i++) { - TString histName = i < number_of_particles ? primaryParticles[i].name : "all"; - hDeDx[2 * i] = histos.add(Form("full/histdEdx_%s", histName.Data()), ";p_{TPC}/z (GeV/#it{c}); d#it{E}/d#it{x}", HistType::kTH2F, {axisRigidity, axisdEdx}); - hDeDx[2 * i + 1] = histos.add(Form("cuts/histdEdx_%s_Cuts", histName.Data()), ";p_{TPC}/z (GeV/#it{c}); d#it{E}/d#it{x}", HistType::kTH2F, {axisRigidity, axisdEdx}); - hDeDxanti[2 * i] = histos.add(Form("antifull/histdEdx_%s", histName.Data()), ";p_{TPC}/z (GeV/#it{c}); d#it{E}/d#it{x}", HistType::kTH2F, {axisRigidity, axisdEdx}); - hDeDxanti[2 * i + 1] = histos.add(Form("anticuts/histdEdx_%s_Cuts", histName.Data()), ";p_{TPC}/z (GeV/#it{c}); d#it{E}/d#it{x}", HistType::kTH2F, {axisRigidity, axisdEdx}); + histos.add("histMagField", "histMagField", kTH1F, {axisMagField}); + histos.add("histNev", "histNev", kTH1F, {axisNev}); + histos.add("histVtxZ", "histVtxZ", kTH1F, {axisVtxZ}); + histos.add("histCentFT0C", "histCentFT0C", kTH1F, {axisCent}); + histos.add("histCentFT0M", "histCentFT0M", kTH1F, {axisCent}); + hDeDx.resize(2 * nParticles + 2); + hNsigmaPt.resize(2 * nParticles + 2); + hmass.resize(2 * nParticles + 2); + for (int i = 0; i < nParticles + 1; i++) { + TString histName = i < nParticles ? primaryParticles[i].name : "all"; + if (cfgFillDeDxWithoutCut) { + hDeDx[2 * i] = histos.add(Form("dedx/histdEdx_%s", histName.Data()), ";p_{TPC}/z (GeV/#it{c}); d#it{E}/d#it{x}", HistType::kTH2F, {axisRigidity, axisdEdx}); + } + if (cfgFillDeDxWithCut) { + hDeDx[2 * i + 1] = histos.add(Form("dedx/histdEdx_%s_Cuts", histName.Data()), ";p_{TPC}/z (GeV/#it{c}); d#it{E}/d#it{x}", HistType::kTH2F, {axisRigidity, axisdEdx}); + } } - for (int i = 0; i < number_of_particles; i++) { + for (int i = 0; i < nParticles; i++) { TString histName = primaryParticles[i].name; - hnsigma_pt[2 * i] = histos.add(Form("histnsigma_pt/histnsigmaTPC_%s", histName.Data()), ";p_T{TPC} (GeV/#it{c}); TPCnsigma", HistType::kTH2F, {ptAxis, nsigmaAxis}); - hnsigma_ptanti[2 * i] = histos.add(Form("histnsigma_ptanti/histnsigmaTPC_%s", histName.Data()), ";p_T{TPC} (GeV/#it{c}); TPCnsigma", HistType::kTH2F, {ptAxis, nsigmaAxis}); - hdcaXY_pt[2 * i] = histos.add(Form("histdcaXY_pt/histdcaXY_%s", histName.Data()), ";p_T{TPC} (GeV/#it{c}); dcaXY", HistType::kTH2F, {ptAxis, dcaXY}); - hdcaXY_ptanti[2 * i] = histos.add(Form("histdcaXY_ptanti/histdcaXY_%s", histName.Data()), ";p_T{TPC} (GeV/#it{c}); dcaXY", HistType::kTH2F, {ptAxis, dcaXY}); - hmass_pt[2 * i] = histos.add(Form("histmass_pt/histmass_%s", histName.Data()), ";p_T{TPC} (GeV/#it{c}); mass^{2}", HistType::kTH2F, {ptAxis, axismass}); - hmass_ptanti[2 * i] = histos.add(Form("histmass_ptanti/histmass_%s", histName.Data()), ";p_T{TPC} (GeV/#it{c}); mass^{2}", HistType::kTH2F, {ptAxis, axismass}); - hrapidity[2 * i] = histos.add(Form("rapidity/histrapidity_%s", histName.Data()), "; rapidity", HistType::kTH1F, {axisrapidity}); - hdelta_mass[2 * i] = histos.add(Form("histdelta/histmass_%s", histName.Data()), ";p_T{TPC} (GeV/#it{c}); #Delta mass", HistType::kTH2F, {ptAxis, axisdelta_mass}); + if (cfgFillnsigma) { + hNsigmaPt[2 * i] = histos.add(Form("histnsigmaTPC_%s", histName.Data()), ";p_T{TPC} (GeV/#it{c}); TPCnsigma", HistType::kTH2F, {ptAxis, nsigmaAxis}); + hNsigmaPt[2 * i + 1] = histos.add(Form("histnsigmaTPC_anti_%s", histName.Data()), ";p_T{TPC} (GeV/#it{c}); TPCnsigma", HistType::kTH2F, {ptAxis, nsigmaAxis}); + } + if (cfgFillmass) { + hmass[2 * i] = histos.add(Form("histmass_pt/histmass_%s", histName.Data()), ";p_T{TPC} (GeV/#it{c}); mass^{2}", HistType::kTH2F, {ptAxis, axismass}); + hmass[2 * i + 1] = histos.add(Form("histmass_ptanti/histmass_%s", histName.Data()), ";p_T{TPC} (GeV/#it{c}); mass^{2}", HistType::kTH2F, {ptAxis, axismass}); + } } - } // completed void init bracket + } //---------------------------------------------------------------------------------------------------------------- void findprimaryParticles(aod::TrackAssoc const& tracksByColl, TracksFull const& tracks) { - // track loop, store primary candidates in std::vector + // track loop, store daughter candidates in std::vector for (const auto& trackId : tracksByColl) { const auto& track = tracks.rawIteratorAt(trackId.trackId()); - /* - if (!track.isPVContributor()) - continue; - */ - filldedx(track, number_of_particles); - if (track.sign() > 0) { - histos.fill(HIST("histDcaZVsPtData_particle"), track.pt(), track.dcaZ()); - histos.fill(HIST("histDcaXYVsPtData_particle"), track.pt(), track.dcaXY()); - } - if (track.sign() < 0) { - histos.fill(HIST("histDcaZVsPtData_antiparticle"), track.pt(), track.dcaZ()); - histos.fill(HIST("histDcaXYVsPtData_antiparticle"), track.pt(), track.dcaXY()); - } + filldedx(track, nParticles); if (std::abs(track.eta()) > cfgCutEta) continue; histos.fill(HIST("histeta"), track.eta()); for (size_t i = 0; i < primaryParticles.size(); i++) { + if (std::abs(getRapidity(track, i)) > cfgCutRapidity) + continue; + bool insideDCAxy = (std::abs(track.dcaXY()) <= (cfgTrackPIDsettings->get(i, "maxDcaXY") * (0.0105f + 0.0350f / std::pow(track.pt(), 1.1f)))); + if (!(insideDCAxy) || std::abs(track.dcaZ()) > cfgTrackPIDsettings->get(i, "maxDcaZ")) + continue; + if (track.sign() > 0) { + histos.fill(HIST("histDcaZVsPtData_particle"), track.pt(), track.dcaZ()); + histos.fill(HIST("histDcaXYVsPtData_particle"), track.pt(), track.dcaXY()); + } + if (track.sign() < 0) { + histos.fill(HIST("histDcaZVsPtData_antiparticle"), track.pt(), track.dcaZ()); + histos.fill(HIST("histDcaXYVsPtData_antiparticle"), track.pt(), track.dcaXY()); + } if (track.tpcNClsFound() < cfgTrackPIDsettings->get(i, "minTPCnCls")) continue; if (track.tpcChi2NCl() > cfgTrackPIDsettings->get(i, "maxTPCchi2")) @@ -237,37 +218,24 @@ struct NucleitpcPbPb { continue; if (track.itsChi2NCl() > cfgTrackPIDsettings->get(i, "maxITSchi2")) continue; - if (getMeanItsClsSize(track) < cfgTrackPIDsettings->get(i, "minITSclsSize")) - continue; - if (getMeanItsClsSize(track) > cfgTrackPIDsettings->get(i, "maxITSclsSize")) - continue; - if (i == 4 || i == 5) { - momn = 2 * track.pt(); - } else { - momn = track.pt(); - } - bool insideDCAxy = (std::abs(track.dcaXY()) <= (maxDcaXYFactor.value * (0.0105f + 0.0350f / pow(track.pt(), 1.1f)))); - if (!(insideDCAxy) || TMath::Abs(track.dcaZ()) > 2) - continue; - if (TMath::Abs(getRapidity(track, i)) > 0.5) - continue; - fillhsigma(track, i); + fillnsigma(track, i); if (std::abs(getTPCnSigma(track, primaryParticles.at(i))) > cfgTrackPIDsettings->get(i, "maxTPCnSigma")) continue; filldedx(track, i); - fillhdcaXY(track, i); fillhmass(track, i); - fillhrapidity(track, i); - fillhdelta_mass(track, i); + if (getMeanItsClsSize(track) < cfgTrackPIDsettings->get(i, "minITSclsSize")) + continue; + if (getMeanItsClsSize(track) > cfgTrackPIDsettings->get(i, "maxITSclsSize")) + continue; if (getRigidity(track) < cfgTrackPIDsettings->get(i, "minRigidity") || getRigidity(track) > cfgTrackPIDsettings->get(i, "maxRigidity")) continue; if (cfgTrackPIDsettings->get(i, "TOFrequiredabove") >= 0 && getRigidity(track) > cfgTrackPIDsettings->get(i, "TOFrequiredabove") && (track.mass() < cfgTrackPIDsettings->get(i, "minTOFmass") || track.mass() > cfgTrackPIDsettings->get(i, "maxTOFmass"))) continue; - histos.fill(HIST("Tof_signal"), track.sign() * momn, track.beta()); } } // track loop } //---------------------------------------------------------------------------------------------------------------- + //---------------------------------------------------------------------------------------------------------------- void processData(CollisionsFull const& collisions, TracksFull const& tracks, aod::BCsWithTimestamps const&, aod::TrackAssoc const& tracksColl) { for (const auto& collision : collisions) { @@ -276,13 +244,14 @@ struct NucleitpcPbPb { initCollision(collision); if (!collPassedEvSel) continue; + if (collision.centFT0C() > centcut) + continue; + histos.fill(HIST("histCentFTOC_cut"), collision.centFT0C()); const uint64_t collIdx = collision.globalIndex(); auto tracksByColl = tracksColl.sliceBy(perCollision, collIdx); findprimaryParticles(tracksByColl, tracks); if (!collHasCandidate) continue; - if (collision.centFT0C() > centcut) - continue; } } PROCESS_SWITCH(NucleitpcPbPb, processData, "data analysis", true); @@ -292,13 +261,14 @@ struct NucleitpcPbPb { if (mRunNumber == bc.runNumber()) { return; } + constexpr float kInvalidBField = -990.f; auto run3grpTimestamp = bc.timestamp(); dBz = 0; o2::parameters::GRPObject* grpo = ccdb->getForTimeStamp(grpPath, run3grpTimestamp); o2::parameters::GRPMagField* grpmag = 0x0; if (grpo) { o2::base::Propagator::initFieldFromGRP(grpo); - if (bField < -990) { + if (bField < kInvalidBField) { // Fetch magnetic field from ccdb for current collision dBz = grpo->getNominalL3Field(); LOG(info) << "Retrieved GRP for timestamp " << run3grpTimestamp << " with magnetic field of " << dBz << " kZG"; @@ -311,7 +281,7 @@ struct NucleitpcPbPb { LOG(fatal) << "Got nullptr from CCDB for path " << grpmagPath << " of object GRPMagField and " << grpPath << " of object GRPObject for timestamp " << run3grpTimestamp; } o2::base::Propagator::initFieldFromGRP(grpmag); - if (bField < -990) { + if (bField < kInvalidBField) { // Fetch magnetic field from ccdb for current collision dBz = std::lround(5.f * grpmag->getL3Current() / 30000.f); LOG(info) << "Retrieved GRP for timestamp " << run3grpTimestamp << " with magnetic field of " << dBz << " kZG"; @@ -328,23 +298,16 @@ struct NucleitpcPbPb { collHasCandidate = false; histos.fill(HIST("histMagField"), dBz); histos.fill(HIST("histNev"), 0.5); - collPassedEvSel = collision.sel8() && std::abs(collision.posZ()) < 10; - if (collision.sel8()) { - histos.fill(HIST("histNev"), 1.5); - if (std::abs(collision.posZ()) < 10.0000000000000000) { - histos.fill(HIST("histNev"), 2.5); - } - } + collPassedEvSel = collision.sel8() && std::abs(collision.posZ()) < cfgZvertex; + occupancy = collision.trackOccupancyInTimeRange(); if (collPassedEvSel) { + histos.fill(HIST("histNev"), 1.5); histos.fill(HIST("histVtxZ"), collision.posZ()); - histos.fill(HIST("histCentFT0A"), collision.centFT0A()); + // histos.fill(HIST("histCentFT0A"), collision.centFT0A()); histos.fill(HIST("histCentFT0C"), collision.centFT0C()); histos.fill(HIST("histCentFT0M"), collision.centFT0M()); - if (collision.centFT0C() < centcut) { - histos.fill(HIST("histCentFTOC_cut"), collision.centFT0C()); - } + // histos.fill(HIST("histEvents"), collision.centFT0C(), occupancy); } - occupancy = collision.trackOccupancyInTimeRange(); primVtx.assign({collision.posX(), collision.posY(), collision.posZ()}); cents.assign({collision.centFT0A(), collision.centFT0C(), collision.centFT0M()}); } @@ -353,126 +316,89 @@ struct NucleitpcPbPb { void filldedx(T const& track, int species) { const float rigidity = getRigidity(track); - int idx = 2 * species; - if (species != 6) { - auto& hist = (track.sign() > 0) ? hDeDx[idx] : hDeDxanti[idx]; - hist->Fill(track.sign() * rigidity, track.tpcSignal()); - } else { - hDeDx[idx]->Fill(track.sign() * rigidity, track.tpcSignal()); - hDeDxanti[idx]->Fill(track.sign() * rigidity, track.tpcSignal()); + if (cfgFillDeDxWithoutCut) { + hDeDx[2 * species]->Fill(track.sign() * rigidity, track.tpcSignal()); } - if (track.tpcNClsFound() < 100 || track.itsNCls() < 2) - return; - - auto& hist2 = (track.sign() > 0) ? hDeDx[idx + 1] : hDeDxanti[idx + 1]; - hist2->Fill(track.sign() * rigidity, track.tpcSignal()); - } - template - void fillhsigma(T const& track, int species) - { - if (track.tpcNClsFound() < 100 || track.itsNCls() < 2) + if (track.tpcNClsFound() < cfgtpcNClsFound || track.itsNCls() < cfgitsNCls) return; - int i = species; - const float tpcNsigma = getTPCnSigma(track, primaryParticles.at(i)); - double momn; - if (species == 4 || species == 5) { - momn = 2 * track.pt(); - } else { - momn = track.pt(); - } - if (track.sign() > 0) { - hnsigma_pt[2 * species]->Fill(momn, tpcNsigma); - } - if (track.sign() < 0) { - hnsigma_ptanti[2 * species]->Fill(momn, tpcNsigma); + if (cfgFillDeDxWithCut) { + hDeDx[2 * species + 1]->Fill(track.sign() * rigidity, track.tpcSignal()); } } + //---------------------------------------------------------------------------------------------------------------- template - void fillhdcaXY(T const& track, int species) + void fillnsigma(T const& track, int species) { - if (track.tpcNClsFound() < 100 || track.itsNCls() < 2) + if (track.tpcNClsFound() < cfgtpcNClsFound || track.itsNCls() < cfgitsNCls) return; - double momn; - if (species == 4 || species == 5) { - momn = 2 * track.pt(); - } else { - momn = track.pt(); - } - const float dcaXY = track.dcaXY(); - if (track.sign() > 0) { - hdcaXY_pt[2 * species]->Fill(momn, dcaXY); - } - if (track.sign() < 0) { - hdcaXY_ptanti[2 * species]->Fill(momn, dcaXY); + if (cfgFillnsigma) { + int i = species; + const float tpcNsigma = getTPCnSigma(track, primaryParticles.at(i)); + double momn; + int speciesHe3 = 4; + int speciesHe4 = 5; + if (species == speciesHe3 || species == speciesHe4) { + momn = 2 * track.pt(); + } else { + momn = track.pt(); + } + if (track.sign() > 0) { + hNsigmaPt[2 * species]->Fill(momn, tpcNsigma); + } + if (track.sign() < 0) { + hNsigmaPt[2 * species + 1]->Fill(momn, tpcNsigma); + } } } + //---------------------------------------------------------------------------------------------------------------- template void fillhmass(T const& track, int species) { - if (track.tpcNClsFound() < 100 || track.itsNCls() < 2) + if (track.tpcNClsFound() < cfgtpcNClsFound || track.itsNCls() < cfgitsNCls) return; - double mass; - if (species == 4 || species == 5) { - mass = 2 * track.mass(); - } else { - mass = track.mass(); - } - double momn; - if (species == 4 || species == 5) { - momn = 2 * track.pt(); - } else { - momn = track.pt(); - } - if (track.sign() > 0) { - hmass_pt[2 * species]->Fill(momn, mass * mass); - } - if (track.sign() < 0) { - hmass_ptanti[2 * species]->Fill(momn, mass * mass); - } - } - template - void fillhdelta_mass(T const& track, int species) - { - if (track.tpcNClsFound() < 100 || track.itsNCls() < 2) - return; - double mass; - if (species == 4 || species == 5) { - mass = 2 * track.mass(); - } else { - mass = track.mass(); + if (cfgFillmass) { + double mass; + int speciesHe3 = 4; + int speciesHe4 = 5; + if (species == speciesHe3 || species == speciesHe4) { + mass = 2 * track.mass(); + } else { + mass = track.mass(); + } + double momn; + if (species == speciesHe3 || species == speciesHe4) { + momn = 2 * track.pt(); + } else { + momn = track.pt(); + } + if (track.sign() > 0) { + hmass[2 * species]->Fill(momn, mass * mass); + } + if (track.sign() < 0) { + hmass[2 * species + 1]->Fill(momn, mass * mass); + } } - - double delta_mass = (mass - particleMasses[species]); - - hdelta_mass[2 * species]->Fill(track.pt() * particleCharge[species], delta_mass); - } - template - void fillhrapidity(T const& track, int species) - { - if (track.tpcNClsFound() < 100 || track.itsNCls() < 2) - return; - double rap = getRapidity(track, species); - hrapidity[2 * species]->Fill(rap); } //---------------------------------------------------------------------------------------------------------------- template - float getTPCnSigma(T const& track, Particle const& particle) + float getTPCnSigma(T const& track, PrimParticles const& particle) { const float rigidity = getRigidity(track); if (!track.hasTPC()) return -999; - if (particle.name == "pion" && cfgTrackPIDsettings->get("pion", "useBBparams") == 0) - return track.tpcNSigmaPi(); - if (particle.name == "proton" && cfgTrackPIDsettings->get("proton", "useBBparams") == 0) - return track.tpcNSigmaPr(); - if (particle.name == "deuteron" && cfgTrackPIDsettings->get("deuteron", "useBBparams") == 0) - return track.tpcNSigmaDe(); - if (particle.name == "triton" && cfgTrackPIDsettings->get("triton", "useBBparams") == 0) - return track.tpcNSigmaTr(); - if (particle.name == "helium3" && cfgTrackPIDsettings->get("helium3", "useBBparams") == 0) - return track.tpcNSigmaHe(); - if (particle.name == "alpha" && cfgTrackPIDsettings->get("alpha", "useBBparams") == 0) - return track.tpcNSigmaAl(); + if (particle.name == "pion" && cfgTrackPIDsettings->get("pion", "useBBparams") < 1) + return cfgTrackPIDsettings->get("pion", "useBBparams") == 0 ? track.tpcNSigmaPi() : 0; + if (particle.name == "proton" && cfgTrackPIDsettings->get("proton", "useBBparams") < 1) + return cfgTrackPIDsettings->get("proton", "useBBparams") == 0 ? track.tpcNSigmaPr() : 0; + if (particle.name == "deuteron" && cfgTrackPIDsettings->get("deuteron", "useBBparams") < 1) + return cfgTrackPIDsettings->get("deuteron", "useBBparams") == 0 ? track.tpcNSigmaDe() : 0; + if (particle.name == "triton" && cfgTrackPIDsettings->get("triton", "useBBparams") < 1) + return cfgTrackPIDsettings->get("triton", "useBBparams") == 0 ? track.tpcNSigmaTr() : 0; + if (particle.name == "helion" && cfgTrackPIDsettings->get("helion", "useBBparams") < 1) + return cfgTrackPIDsettings->get("helion", "useBBparams") == 0 ? track.tpcNSigmaHe() : 0; + if (particle.name == "alpha" && cfgTrackPIDsettings->get("alpha", "useBBparams") < 1) + return cfgTrackPIDsettings->get("alpha", "useBBparams") == 0 ? track.tpcNSigmaAl() : 0; + double expBethe{tpc::BetheBlochAleph(static_cast(particle.charge * rigidity / particle.mass), particle.betheParams[0], particle.betheParams[1], particle.betheParams[2], particle.betheParams[3], particle.betheParams[4])}; double expSigma{expBethe * particle.resolution}; float sigmaTPC = static_cast((track.tpcSignal() - expBethe) / expSigma); @@ -483,7 +409,8 @@ struct NucleitpcPbPb { float getMeanItsClsSize(T const& track) { int sum = 0, n = 0; - for (int i = 0; i < 8; i++) { + constexpr int kNITSLayers = 8; + for (int i = 0; i < kNITSLayers; i++) { sum += (track.itsClusterSizes() >> (4 * i) & 15); if (track.itsClusterSizes() >> (4 * i) & 15) n++; @@ -499,18 +426,21 @@ struct NucleitpcPbPb { bool hePID = track.pidForTracking() == o2::track::PID::Helium3 || track.pidForTracking() == o2::track::PID::Alpha; return hePID ? track.tpcInnerParam() / 2 : track.tpcInnerParam(); } + //---------------------------------------------------------------------------------------------------------------- template float getRapidity(T const& track, int species) { + using PtEtaPhiMVector = ROOT::Math::LorentzVector>; double momn; - TLorentzVector lorentzVector_particle; - if (species == 4 || species == 5) { + int speciesHe3 = 4; + int speciesHe4 = 5; + if (species == speciesHe3 || species == speciesHe4) { momn = 2 * track.pt(); } else { momn = track.pt(); } - lorentzVector_particle.SetPtEtaPhiM(momn, track.eta(), track.phi(), particleMasses[species]); - return lorentzVector_particle.Rapidity(); + PtEtaPhiMVector lorentzVectorParticle(momn, track.eta(), track.phi(), particleMasses[species]); + return lorentzVectorParticle.Rapidity(); } }; // end of the task here //---------------------------------------------------------------------------------------------------------------- diff --git a/PWGLF/Tasks/Nuspex/angularCorrelationsInJets.cxx b/PWGLF/Tasks/Nuspex/angularCorrelationsInJets.cxx index a0cbae145e3..98ee6bfa968 100644 --- a/PWGLF/Tasks/Nuspex/angularCorrelationsInJets.cxx +++ b/PWGLF/Tasks/Nuspex/angularCorrelationsInJets.cxx @@ -18,6 +18,7 @@ #include #include #include +#include #include "Framework/runDataProcessing.h" #include "Framework/AnalysisTask.h" @@ -66,6 +67,8 @@ struct AngularCorrelationsInJets { Configurable doJetCorrelations{"doJetCorrelations", false, "measure correlations for all particles inside jets"}; Configurable doFullCorrelations{"doFullCorrelations", false, "measure correlations for all particles in an event"}; Configurable measureKaons{"measureKaons", false, "measure correlations for K-K"}; + Configurable rejectEvents{"rejectEvents", false, "reject some events"}; + Configurable rejectionPercentage{"rejectionPercentage", 3, "percentage of events to reject"}; // Track Cuts Configurable minNCrossedRowsTPC{"minNCrossedRowsTPC", 80, "min number of crossed rows TPC"}; @@ -163,6 +166,7 @@ struct AngularCorrelationsInJets { // Counters registryData.add("numberOfEvents", "Number of events", HistType::kTH1I, {{1, 0, 1}}); + registryData.add("numberRejectedEvents", "Number of events rejected", HistType::kTH1I, {{2, 0, 2, "counter"}}); registryData.add("numberOfJets", "Total number of jets", HistType::kTH1I, {{1, 0, 1}}); registryData.add("eventProtocol", "Event protocol", HistType::kTH1I, {{20, 0, 20}}); registryData.add("trackProtocol", "Track protocol", HistType::kTH1I, {{20, 0, 20}}); @@ -312,6 +316,18 @@ struct AngularCorrelationsInJets { mRunNumber = bc.runNumber(); } + bool shouldRejectEvent() + { + static std::random_device rd; + static std::mt19937 gen(rd()); + static std::uniform_int_distribution<> dis(0, 99); + int randomNumber = dis(gen); + if (randomNumber > rejectionPercentage) { + return false; // accept event + } + return true; // reject event + } + template bool hasITSHit(const T& track, int layer) { @@ -1250,6 +1266,16 @@ struct AngularCorrelationsInJets { BCsWithRun2Info const&) { for (const auto& collision : collisions) { + if (rejectEvents) { + // event counter: before event rejection + registryData.fill(HIST("numberRejectedEvents"), 0); + + if (shouldRejectEvent()) + continue; + + // event counter: after event rejection + registryData.fill(HIST("numberRejectedEvents"), 1); + } auto bc = collision.bc_as(); initCCDB(bc); @@ -1270,6 +1296,16 @@ struct AngularCorrelationsInJets { soa::Filtered const& tracks) { for (const auto& collision : collisions) { + if (rejectEvents) { + // event counter: before event rejection + registryData.fill(HIST("numberRejectedEvents"), 0); + + if (shouldRejectEvent()) + continue; + + // event counter: after event rejection + registryData.fill(HIST("numberRejectedEvents"), 1); + } registryData.fill(HIST("eventProtocol"), 0); if (!collision.sel8()) continue; @@ -1288,6 +1324,16 @@ struct AngularCorrelationsInJets { void processMCRun2(McCollisions const& collisions, soa::Filtered const& tracks, BCsWithRun2Info const&, aod::McParticles const&, aod::McCollisions const&) { for (const auto& collision : collisions) { + if (rejectEvents) { + // event counter: before event rejection + registryData.fill(HIST("numberRejectedEvents"), 0); + + if (shouldRejectEvent()) + continue; + + // event counter: after event rejection + registryData.fill(HIST("numberRejectedEvents"), 1); + } auto bc = collision.bc_as(); initCCDB(bc); @@ -1307,6 +1353,16 @@ struct AngularCorrelationsInJets { void processMCRun3(McCollisions const& collisions, soa::Filtered const& tracks, aod::McParticles const&, aod::McCollisions const&) { for (const auto& collision : collisions) { + if (rejectEvents) { + // event counter: before event rejection + registryData.fill(HIST("numberRejectedEvents"), 0); + + if (shouldRejectEvent()) + continue; + + // event counter: after event rejection + registryData.fill(HIST("numberRejectedEvents"), 1); + } registryData.fill(HIST("eventProtocol"), 0); if (!collision.sel8()) continue; diff --git a/PWGLF/Tasks/Nuspex/hyperhelium4sigmaAnalysis.cxx b/PWGLF/Tasks/Nuspex/hyperhelium4sigmaAnalysis.cxx new file mode 100644 index 00000000000..e60773cfbc8 --- /dev/null +++ b/PWGLF/Tasks/Nuspex/hyperhelium4sigmaAnalysis.cxx @@ -0,0 +1,338 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// 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. +// +/// \file hyperhelium4sigmaAnalysis.cxx +/// \brief Simple check for injected hyper-helium4sigma (H4S) in MC productions +/// \author Yuanzhe Wang + +#include + +#include "Framework/runDataProcessing.h" +#include "Framework/AnalysisTask.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/ASoAHelpers.h" +#include "ReconstructionDataFormats/Track.h" +#include "Common/Core/RecoDecay.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/PIDResponse.h" +#include "CommonConstants/PhysicsConstants.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; +using std::array; +using FullTracksExtIU = soa::Join; +using MCLabeledTracksIU = soa::Join; + +//-------------------------------Check the decay channel of H4S------------------------------- +enum Channel { + k2body = 0, // helium4, pion0 + k3body_p, // triton, proton, pion0 + k3body_n, // triton, neutron, pion+ + kNDecayChannel +}; + +template +Channel getDecayChannelH4S(TMCParticle const& particle) +{ + if (std::abs(particle.pdgCode()) != o2::constants::physics::Pdg::kHyperHelium4Sigma) { + return kNDecayChannel; + } + bool haveAlpha = false, haveTriton = false, haveProton = false, haveNeuteron = false; + bool haveAntiAlpha = false, haveAntiTriton = false, haveAntiProton = false, haveAntiNeuteron = false; + bool havePionPlus = false, havePionMinus = false, havePion0 = false; + auto daughters = particle.template daughters_as(); + for (const auto& mcDaughter : particle.template daughters_as()) { + if (mcDaughter.pdgCode() == o2::constants::physics::Pdg::kAlpha) { + haveAlpha = true; + } + if (mcDaughter.pdgCode() == -o2::constants::physics::Pdg::kAlpha) { + haveAntiAlpha = true; + } + if (mcDaughter.pdgCode() == o2::constants::physics::Pdg::kTriton) { + haveTriton = true; + } + if (mcDaughter.pdgCode() == -o2::constants::physics::Pdg::kTriton) { + haveAntiTriton = true; + } + if (mcDaughter.pdgCode() == PDG_t::kProton) { + haveProton = true; + } + if (mcDaughter.pdgCode() == -PDG_t::kProton) { + haveAntiProton = true; + } + if (mcDaughter.pdgCode() == PDG_t::kNeutron) { + haveNeuteron = true; + } + if (mcDaughter.pdgCode() == -PDG_t::kNeutron) { + haveAntiNeuteron = true; + } + if (mcDaughter.pdgCode() == PDG_t::kPiPlus) { + havePionPlus = true; + } + if (mcDaughter.pdgCode() == -PDG_t::kPiPlus) { + havePionMinus = true; + } + if (mcDaughter.pdgCode() == PDG_t::kPi0) { + havePion0 = true; + } + } + + if ((haveAlpha && havePion0) || (haveAntiAlpha && havePion0)) { + return k2body; + } else if ((haveTriton && haveProton && havePion0) || (haveAntiTriton && haveAntiProton && havePion0)) { + return k3body_p; + } else if ((haveTriton && haveNeuteron && havePionPlus) || (haveAntiTriton && haveAntiNeuteron && havePionMinus)) { + return k3body_n; + } + + return kNDecayChannel; +} +//-------------------------------------------------------------- + +// check the performance of mcparticle +struct Hyperhelium4sigmaAnalysis { + // Basic checks + HistogramRegistry registry{ + "registry", + { + {"hCollCounter", "hCollCounter", {HistType::kTH1F, {{2, 0.0f, 2.0f}}}}, + {"hMcCollCounter", "hMcCollCounter", {HistType::kTH1F, {{2, 0.0f, 2.0f}}}}, + }, + }; + + ConfigurableAxis ptBins{"ptBins", {200, 0.f, 10.f}, "Binning for #it{p}_{T} (GeV/#it{c})"}; + ConfigurableAxis ctBins{"ctBins", {100, 0.f, 25.f}, "Binning for c#it{t} (cm)"}; + ConfigurableAxis rigidityBins{"rigidityBins", {200, -10.f, 10.f}, "Binning for #it{p}_{T} (GeV/#it{c})"}; + ConfigurableAxis nsigmaBins{"nsigmaBins", {120, -6.f, 6.f}, "Binning for n sigma"}; + ConfigurableAxis invMassBins{"invMassBins", {100, 3.85, 4.15f}, "Binning for invariant mass (GeV/#it{c}^{2})"}; + + void init(InitContext&) + { + const AxisSpec ptAxis{ptBins, "#it{p}_{T} (GeV/#it{c})"}; + const AxisSpec ctAxis{ctBins, "c#it{t} (cm)"}; + const AxisSpec rigidityAxis{rigidityBins, "p/z (GeV/#it{c})"}; + const AxisSpec nsigmaAxis{nsigmaBins, "TPC n#sigma"}; + const AxisSpec invMassAxis{invMassBins, "Inv Mass (GeV/#it{c}^{2})"}; + + registry.get(HIST("hCollCounter"))->GetXaxis()->SetBinLabel(1, "Reconstructed Collisions"); + registry.get(HIST("hCollCounter"))->GetXaxis()->SetBinLabel(2, "Selected"); + registry.get(HIST("hMcCollCounter"))->GetXaxis()->SetBinLabel(1, "MC Collisions"); + registry.get(HIST("hMcCollCounter"))->GetXaxis()->SetBinLabel(2, "Reconstructed"); + + auto hGenHyperHelium4SigmaCounter = registry.add("hGenHyperHelium4SigmaCounter", "", HistType::kTH1F, {{10, 0.f, 10.f}}); + registry.get(HIST("hGenHyperHelium4SigmaCounter"))->GetXaxis()->SetBinLabel(1, "H4S All"); + registry.get(HIST("hGenHyperHelium4SigmaCounter"))->GetXaxis()->SetBinLabel(2, "Matter"); + registry.get(HIST("hGenHyperHelium4SigmaCounter"))->GetXaxis()->SetBinLabel(3, "AntiMatter"); + registry.get(HIST("hGenHyperHelium4SigmaCounter"))->GetXaxis()->SetBinLabel(4, "#alpha + #pi^{0}"); + registry.get(HIST("hGenHyperHelium4SigmaCounter"))->GetXaxis()->SetBinLabel(5, "#bar{#alpha} + #pi^{0}"); + registry.get(HIST("hGenHyperHelium4SigmaCounter"))->GetXaxis()->SetBinLabel(6, "t + p + #pi^{0}"); + registry.get(HIST("hGenHyperHelium4SigmaCounter"))->GetXaxis()->SetBinLabel(7, "#bar{t} + #bar{p} + #pi^{0}"); + registry.get(HIST("hGenHyperHelium4SigmaCounter"))->GetXaxis()->SetBinLabel(8, "t + n + #pi^{+}"); + registry.get(HIST("hGenHyperHelium4SigmaCounter"))->GetXaxis()->SetBinLabel(9, "#bar{t} + #bar{n} + #pi^{+}"); + registry.get(HIST("hGenHyperHelium4SigmaCounter"))->GetXaxis()->SetBinLabel(10, "Unexpected"); + + auto hEvtSelectedHyperHelium4SigmaCounter = registry.add("hEvtSelectedHyperHelium4SigmaCounter", "", HistType::kTH1F, {{2, 0.f, 2.f}}); + registry.get(HIST("hEvtSelectedHyperHelium4SigmaCounter"))->GetXaxis()->SetBinLabel(1, "Generated"); + registry.get(HIST("hEvtSelectedHyperHelium4SigmaCounter"))->GetXaxis()->SetBinLabel(2, "Survived"); + + registry.add("hGenHyperHelium4SigmaPt", "", HistType::kTH1F, {ptAxis}); + registry.add("hGenHyperHelium4SigmaCt", "", HistType::kTH1F, {ctAxis}); + registry.add("hMcRecoInvMass", "", HistType::kTH1F, {invMassAxis}); + + registry.add("hDauHelium4TPCNSigma", "", HistType::kTH2F, {rigidityAxis, nsigmaAxis}); + registry.add("hDauTritonTPCNSigma", "", HistType::kTH2F, {rigidityAxis, nsigmaAxis}); + registry.add("hDauProtonTPCNSigma", "", HistType::kTH2F, {rigidityAxis, nsigmaAxis}); + } + + // Configurable eventSel8Cut{"eventSel8Cut", true, "flag to enable event sel8 selection"}; + Configurable mcEventCut{"mcEventCut", true, "flag to enable mc event selection: kIsTriggerTVX and kNoTimeFrameBorder"}; + Configurable eventPosZCut{"eventPosZCut", true, "flag to enable event posZ selection"}; + Configurable maxPosZ{"maxPosZ", 10.f, "max pv posZ for event selection"}; + + Preslice permcCollision = o2::aod::mcparticle::mcCollisionId; + + std::vector mcPartIndices; + template + void setTrackIDForMC(aod::McParticles const& particlesMC, TTrackTable const& tracks) + { + mcPartIndices.clear(); + mcPartIndices.resize(particlesMC.size()); + std::fill(mcPartIndices.begin(), mcPartIndices.end(), -1); + for (const auto& track : tracks) { + if (track.has_mcParticle()) { + auto mcparticle = track.template mcParticle_as(); + if (mcPartIndices[mcparticle.globalIndex()] == -1) { + mcPartIndices[mcparticle.globalIndex()] = track.globalIndex(); + } else { + auto candTrack = tracks.rawIteratorAt(mcPartIndices[mcparticle.globalIndex()]); + // Use the track which has innest information (also best quality? + if (track.x() < candTrack.x()) { + mcPartIndices[mcparticle.globalIndex()] = track.globalIndex(); + } + } + } + } + } + + void process(aod::McCollisions const& mcCollisions, aod::McParticles const& particlesMC, o2::soa::Join const& collisions, MCLabeledTracksIU const& tracks) + { + setTrackIDForMC(particlesMC, tracks); + std::vector selectedEvents(collisions.size()); + int nevts = 0; + for (const auto& collision : collisions) { + registry.fill(HIST("hCollCounter"), 0.5); + if (mcEventCut && (!collision.selection_bit(aod::evsel::kIsTriggerTVX) || !collision.selection_bit(aod::evsel::kNoTimeFrameBorder))) { + continue; + } + if (eventPosZCut && std::abs(collision.posZ()) > maxPosZ) { // 10cm + continue; + } + registry.fill(HIST("hCollCounter"), 1.5); + selectedEvents[nevts++] = collision.mcCollision_as().globalIndex(); + } + selectedEvents.resize(nevts); + + for (const auto& mcCollision : mcCollisions) { + registry.fill(HIST("hMcCollCounter"), 0.5); + const auto evtReconstructedAndSelected = std::find(selectedEvents.begin(), selectedEvents.end(), mcCollision.globalIndex()) != selectedEvents.end(); + if (evtReconstructedAndSelected) { // Check that the event is reconstructed and that the reconstructed events pass the selection + registry.fill(HIST("hMcCollCounter"), 1.5); + } else { + // continue; + } + + const auto& dparticlesMC = particlesMC.sliceBy(permcCollision, mcCollision.globalIndex()); + + for (const auto& mcparticle : dparticlesMC) { + + bool isMatter; + if (mcparticle.pdgCode() == o2::constants::physics::Pdg::kHyperHelium4Sigma) { + registry.fill(HIST("hGenHyperHelium4SigmaCounter"), 1.5); + isMatter = true; + } else if (mcparticle.pdgCode() == -o2::constants::physics::Pdg::kHyperHelium4Sigma) { + registry.fill(HIST("hGenHyperHelium4SigmaCounter"), 2.5); + isMatter = false; + } else { + continue; + } + + registry.fill(HIST("hGenHyperHelium4SigmaCounter"), 0.5); + registry.fill(HIST("hEvtSelectedHyperHelium4SigmaCounter"), 0.5); + if (evtReconstructedAndSelected) { + registry.fill(HIST("hEvtSelectedHyperHelium4SigmaCounter"), 1.5); + } + + double svPos[3] = {-999, -999, -999}; + double dauHelium4Mom[3] = {-999, -999, -999}; + double dauTritonMom[3] = {-999, -999, -999}; + double dauProtonMom[3] = {-999, -999, -999}; + double dauNeuteronMom[3] = {-999, -999, -999}; + double dauChargedPionMom[3] = {-999, -999, -999}; + double dauPion0Mom[3] = {-999, -999, -999}; + auto dChannel = getDecayChannelH4S(mcparticle); + if (dChannel == kNDecayChannel) { + registry.fill(HIST("hGenHyperHelium4SigmaCounter"), 9.5); + continue; + } + for (const auto& mcparticleDaughter : mcparticle.daughters_as()) { + if (std::abs(mcparticleDaughter.pdgCode()) == o2::constants::physics::Pdg::kAlpha) { + dauHelium4Mom[0] = mcparticleDaughter.px(); + dauHelium4Mom[1] = mcparticleDaughter.py(); + dauHelium4Mom[2] = mcparticleDaughter.pz(); + + // get SV position for 2body decay + svPos[0] = mcparticleDaughter.vx(); + svPos[1] = mcparticleDaughter.vy(); + svPos[2] = mcparticleDaughter.vz(); + + if (mcPartIndices[mcparticleDaughter.globalIndex()] != -1) { + auto track = tracks.rawIteratorAt(mcPartIndices[mcparticleDaughter.globalIndex()]); + registry.fill(HIST("hDauHelium4TPCNSigma"), track.p() * track.sign(), track.tpcNSigmaAl()); + } + } else if (std::abs(mcparticleDaughter.pdgCode()) == o2::constants::physics::Pdg::kTriton) { + dauTritonMom[0] = mcparticleDaughter.px(); + dauTritonMom[1] = mcparticleDaughter.py(); + dauTritonMom[2] = mcparticleDaughter.pz(); + + // get SV position for 3body decay + svPos[0] = mcparticleDaughter.vx(); + svPos[1] = mcparticleDaughter.vy(); + svPos[2] = mcparticleDaughter.vz(); + + if (mcPartIndices[mcparticleDaughter.globalIndex()] != -1) { + auto track = tracks.rawIteratorAt(mcPartIndices[mcparticleDaughter.globalIndex()]); + registry.fill(HIST("hDauTritonTPCNSigma"), track.p() * track.sign(), track.tpcNSigmaTr()); + } + } else if (std::abs(mcparticleDaughter.pdgCode()) == PDG_t::kProton) { + dauProtonMom[0] = mcparticleDaughter.px(); + dauProtonMom[1] = mcparticleDaughter.py(); + dauProtonMom[2] = mcparticleDaughter.pz(); + + if (mcPartIndices[mcparticleDaughter.globalIndex()] != -1) { + auto track = tracks.rawIteratorAt(mcPartIndices[mcparticleDaughter.globalIndex()]); + registry.fill(HIST("hDauProtonTPCNSigma"), track.p() * track.sign(), track.tpcNSigmaPr()); + } + } else if (std::abs(mcparticleDaughter.pdgCode()) == PDG_t::kNeutron) { + dauNeuteronMom[0] = mcparticleDaughter.px(); + dauNeuteronMom[1] = mcparticleDaughter.py(); + dauNeuteronMom[2] = mcparticleDaughter.pz(); + } else if (std::abs(mcparticleDaughter.pdgCode()) == PDG_t::kPiPlus) { + dauChargedPionMom[0] = mcparticleDaughter.px(); + dauChargedPionMom[1] = mcparticleDaughter.py(); + dauChargedPionMom[2] = mcparticleDaughter.pz(); + } else if (mcparticleDaughter.pdgCode() == PDG_t::kPi0) { + dauPion0Mom[0] = mcparticleDaughter.px(); + dauPion0Mom[1] = mcparticleDaughter.py(); + dauPion0Mom[2] = mcparticleDaughter.pz(); + } + } + + registry.fill(HIST("hGenHyperHelium4SigmaPt"), mcparticle.pt()); + double ct = RecoDecay::sqrtSumOfSquares(svPos[0] - mcparticle.vx(), svPos[1] - mcparticle.vy(), svPos[2] - mcparticle.vz()) * o2::constants::physics::MassHyperHelium4Sigma / mcparticle.p(); + registry.fill(HIST("hGenHyperHelium4SigmaCt"), ct); + + if (dChannel == k2body) { + if (isMatter) { + registry.fill(HIST("hGenHyperHelium4SigmaCounter"), 3.5); + } else { + registry.fill(HIST("hGenHyperHelium4SigmaCounter"), 4.5); + } + double hyperHelium4SigmaMCMass = RecoDecay::m(std::array{std::array{dauHelium4Mom[0], dauHelium4Mom[1], dauHelium4Mom[2]}, std::array{dauPion0Mom[0], dauPion0Mom[1], dauPion0Mom[2]}}, std::array{o2::constants::physics::MassAlpha, o2::constants::physics::MassPi0}); + registry.fill(HIST("hMcRecoInvMass"), hyperHelium4SigmaMCMass); + } else if (dChannel == k3body_p) { + if (isMatter) { + registry.fill(HIST("hGenHyperHelium4SigmaCounter"), 5.5); + } else { + registry.fill(HIST("hGenHyperHelium4SigmaCounter"), 6.5); + } + double hyperHelium4SigmaMCMass = RecoDecay::m(std::array{std::array{dauTritonMom[0], dauTritonMom[1], dauTritonMom[2]}, std::array{dauProtonMom[0], dauProtonMom[1], dauProtonMom[2]}, std::array{dauPion0Mom[0], dauPion0Mom[1], dauPion0Mom[2]}}, std::array{o2::constants::physics::MassTriton, o2::constants::physics::MassProton, o2::constants::physics::MassPi0}); + registry.fill(HIST("hMcRecoInvMass"), hyperHelium4SigmaMCMass); + } else if (dChannel == k3body_n) { + if (isMatter) { + registry.fill(HIST("hGenHyperHelium4SigmaCounter"), 7.5); + } else { + registry.fill(HIST("hGenHyperHelium4SigmaCounter"), 8.5); + } + double hyperHelium4SigmaMCMass = RecoDecay::m(std::array{std::array{dauTritonMom[0], dauTritonMom[1], dauTritonMom[2]}, std::array{dauNeuteronMom[0], dauNeuteronMom[1], dauNeuteronMom[2]}, std::array{dauChargedPionMom[0], dauChargedPionMom[1], dauChargedPionMom[2]}}, std::array{o2::constants::physics::MassTriton, o2::constants::physics::MassNeutron, o2::constants::physics::MassPionCharged}); + registry.fill(HIST("hMcRecoInvMass"), hyperHelium4SigmaMCMass); + } + } + } + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc), + }; +} diff --git a/PWGLF/Tasks/QC/CMakeLists.txt b/PWGLF/Tasks/QC/CMakeLists.txt index dd0c14d1c91..f8c8e35cafa 100644 --- a/PWGLF/Tasks/QC/CMakeLists.txt +++ b/PWGLF/Tasks/QC/CMakeLists.txt @@ -111,7 +111,7 @@ o2physics_add_dpl_workflow(mcinelgt0 COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(tracked-cascade-properties - SOURCES tracked_cascade_properties.cxx + SOURCES trackedCascadeProperties.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) diff --git a/PWGLF/Tasks/QC/strderivedGenQA.cxx b/PWGLF/Tasks/QC/strderivedGenQA.cxx index 7e232b1dd97..201dcd99ac2 100644 --- a/PWGLF/Tasks/QC/strderivedGenQA.cxx +++ b/PWGLF/Tasks/QC/strderivedGenQA.cxx @@ -320,6 +320,7 @@ struct strderivedGenQA { histos.add("MCV0/Gamma/hdcaDau", "hdcaDau", kTH1F, {axisDCAdau}); histos.add("MCV0/Gamma/hdcaNegtopv", "hdcaNegtopv", kTH1F, {axisDCAToPV}); histos.add("MCV0/Gamma/hdcaPostopv", "hdcaPostopv", kTH1F, {axisDCAToPV}); + histos.add("MCV0/Gamma/hZ", "hZ", kTH1F, {{240, -120.0f, 120.0f}}); histos.add("MCV0/Lambda/h2dpTResolution", "h2dpTResolution", kTH2F, {axisPt, axisPtResolution}); histos.add("MCV0/Lambda/h2dMass", "h2dMass", kTH2F, {axisPt, axisMassLambda}); @@ -804,6 +805,7 @@ struct strderivedGenQA { histos.fill(HIST("MCV0/Gamma/hdcaDau"), v0.dcaV0daughters()); histos.fill(HIST("MCV0/Gamma/hdcaNegtopv"), v0.dcanegtopv()); histos.fill(HIST("MCV0/Gamma/hdcaPostopv"), v0.dcapostopv()); + histos.fill(HIST("MCV0/Gamma/hZ"), v0.z()); } if (v0MC.pdgCode() == 3122) { // IsLambda histos.fill(HIST("MCV0/h2dArmenterosP"), v0.alpha(), v0.qtarm()); diff --git a/PWGLF/Tasks/QC/tracked_cascade_properties.cxx b/PWGLF/Tasks/QC/trackedCascadeProperties.cxx similarity index 81% rename from PWGLF/Tasks/QC/tracked_cascade_properties.cxx rename to PWGLF/Tasks/QC/trackedCascadeProperties.cxx index e2f93dbe481..04c7250208c 100644 --- a/PWGLF/Tasks/QC/tracked_cascade_properties.cxx +++ b/PWGLF/Tasks/QC/trackedCascadeProperties.cxx @@ -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. +// +/// \file trackedCascadeProperties.cxx +/// +/// \brief task to study the average cluster size of tracked cascades /// /// \author Alberto Caliva (alberto.caliva@cern.ch), Francesca Ercolessi (francesca.ercolessi@cern.ch) /// \since May 31, 2024 -#include -#include #include #include #include @@ -21,6 +23,7 @@ #include #include #include +#include #include "Common/Core/RecoDecay.h" #include "Common/Core/trackUtilities.h" @@ -37,8 +40,6 @@ #include "PWGLF/DataModel/LFStrangenessTables.h" #include "ReconstructionDataFormats/Track.h" #include "ReconstructionDataFormats/DCA.h" -#define mXi 1.32171 -#define mOmega 1.67245 using namespace std; using namespace o2; @@ -51,7 +52,7 @@ using SelectedCollisions = soa::Join; using FullTracks = soa::Join; -struct tracked_cascade_properties { +struct TrackedCascadeProperties { // QC Histograms HistogramRegistry registryQC{ @@ -72,15 +73,11 @@ struct tracked_cascade_properties { // Global Parameters Configurable zVtx{"zVtx", 10.0f, "z vertex cut"}; - // Cascade Parameters - Configurable minimumCascRadius{"minimumCascRadius", 5.0f, "Minimum Cascade Radius"}; - Configurable maximumCascRadius{"maximumCascRadius", 18.0f, "Maximum Cascade Radius"}; - // Mass Cuts - Configurable mMin_xi{"mMin_xi", 1.315f, "mMin Xi"}; - Configurable mMax_xi{"mMax_xi", 1.328f, "mMax Xi"}; - Configurable mMin_omega{"mMin_omega", 1.665f, "mMin Omega"}; - Configurable mMax_omega{"mMax_omega", 1.680f, "mMax Omega"}; + Configurable massMinXi{"massMinXi", 1.315f, "mMin Xi"}; + Configurable massMaxXi{"massMaxXi", 1.328f, "mMax Xi"}; + Configurable massMinOmega{"massMinOmega", 1.665f, "mMin Omega"}; + Configurable massMaxOmega{"massMaxOmega", 1.680f, "mMax Omega"}; void init(InitContext const&) { @@ -118,17 +115,27 @@ struct tracked_cascade_properties { registryData.add("omega_mass_neg", "omega_mass_neg", HistType::kTH2F, {{100, 0.0, 10.0, "#it{p} (GeV/#it{c})"}, {200, 1.63, 1.71, "m_{p#piK} (GeV/#it{c}^{2})"}}); } - double track_inclination(double eta) + double trackInclination(double eta) { double lambda(0); - double theta = 2.0 * atan(exp(-eta)); - if (theta <= TMath::Pi() / 2.0) - lambda = 0.5 * TMath::Pi() - theta; - if (theta > TMath::Pi() / 2.0) - lambda = theta - 0.5 * TMath::Pi(); + double theta = 2.0 * std::atan(std::exp(-eta)); + if (theta <= o2::constants::math::PIHalf) + lambda = o2::constants::math::PIHalf - theta; + if (theta > o2::constants::math::PIHalf) + lambda = theta - o2::constants::math::PIHalf; return lambda; } + int findBin(const std::vector& edges, double value) + { + auto it = std::upper_bound(edges.begin(), edges.end(), value); + int index = static_cast(it - edges.begin()) - 1; + if (index < 0 || index >= static_cast(edges.size()) - 1) { + return -1; // value is out of bounds + } + return index; + } + void processData(SelectedCollisions::iterator const& collision, aod::AssignedTrackedCascades const& trackedCascades, aod::Cascades const&, FullTracks const&) { @@ -137,11 +144,13 @@ struct tracked_cascade_properties { return; registryData.fill(HIST("number_of_events_data"), 1.5); - if (abs(collision.posZ()) > zVtx) + if (std::abs(collision.posZ()) > zVtx) return; registryData.fill(HIST("number_of_events_data"), 2.5); + std::vector edgesItsLayers = {0.0, 2.2, 2.8, 3.6, 20.0, 22.0, 37.0, 39.0, 100.0}; + for (const auto& trackedCascade : trackedCascades) { const auto track = trackedCascade.track_as(); @@ -151,7 +160,9 @@ struct tracked_cascade_properties { registryQC.fill(HIST("deltaP"), track.p() - trackITS.p()); registryQC.fill(HIST("deltaEta"), track.eta() - trackITS.eta()); registryQC.fill(HIST("deltaNclsITS"), track.itsNCls() - trackITS.itsNCls()); - for (int i = 0; i < 7; i++) { + + const int nItsLayers = 7; + for (int i = 0; i < nItsLayers; i++) { registryQC.fill(HIST("deltaClsSize"), track.itsClsSizeInLayer(i) - trackITS.itsClsSizeInLayer(i)); } @@ -159,9 +170,8 @@ struct tracked_cascade_properties { const auto& btrack = casc.bachelor_as(); double dx = trackedCascade.decayX(); double dy = trackedCascade.decayY(); - double r = sqrt(dx * dx + dy * dy); - if (r < minimumCascRadius || r > maximumCascRadius) - continue; + double r = std::sqrt(dx * dx + dy * dy); + int nClsCascade = findBin(edgesItsLayers, r); registryQC.fill(HIST("matchingChi2"), trackedCascade.matchingChi2()); registryQC.fill(HIST("topologyChi2"), trackedCascade.topologyChi2()); @@ -170,7 +180,7 @@ struct tracked_cascade_properties { // Calculate (Average) Cluster Size double averageClusterSize(0); int nCls(0); - for (int i = 0; i < 7; i++) { + for (int i = 0; i < nClsCascade; i++) { int clusterSize = trackITS.itsClsSizeInLayer(i); averageClusterSize += static_cast(clusterSize); if (clusterSize > 0) @@ -190,20 +200,20 @@ struct tracked_cascade_properties { } // Track Inclination - double lambda = track_inclination(track.eta()); + double lambda = trackInclination(track.eta()); // Xi - if (trackedCascade.xiMass() > mMin_xi && trackedCascade.xiMass() < mMax_xi) { + if (trackedCascade.xiMass() > massMinXi && trackedCascade.xiMass() < massMaxXi) { registryQC.fill(HIST("nITScls_vs_p_xi"), track.p(), trackITS.itsNCls()); if (btrack.sign() > 0) { registryData.fill(HIST("xi_pos_avgclustersize"), track.p(), averageClusterSize, track.eta()); - registryData.fill(HIST("xi_pos_avgclustersize_cosL"), track.p(), averageClusterSize * cos(lambda)); - registryData.fill(HIST("xi_pos_avgclustersize_cosL_vs_betagamma"), track.p() / mXi, averageClusterSize * cos(lambda)); + registryData.fill(HIST("xi_pos_avgclustersize_cosL"), track.p(), averageClusterSize * std::cos(lambda)); + registryData.fill(HIST("xi_pos_avgclustersize_cosL_vs_betagamma"), track.p() / o2::constants::physics::MassXiPlusBar, averageClusterSize * std::cos(lambda)); } if (btrack.sign() < 0) { registryData.fill(HIST("xi_neg_avgclustersize"), track.p(), averageClusterSize, track.eta()); - registryData.fill(HIST("xi_neg_avgclustersize_cosL"), track.p(), averageClusterSize * cos(lambda)); - registryData.fill(HIST("xi_neg_avgclustersize_cosL_vs_betagamma"), track.p() / mXi, averageClusterSize * cos(lambda)); + registryData.fill(HIST("xi_neg_avgclustersize_cosL"), track.p(), averageClusterSize * std::cos(lambda)); + registryData.fill(HIST("xi_neg_avgclustersize_cosL_vs_betagamma"), track.p() / o2::constants::physics::MassXiMinus, averageClusterSize * std::cos(lambda)); } continue; } @@ -217,25 +227,25 @@ struct tracked_cascade_properties { } // Omega - if (trackedCascade.omegaMass() > mMin_omega && trackedCascade.omegaMass() < mMax_omega) { + if (trackedCascade.omegaMass() > massMinOmega && trackedCascade.omegaMass() < massMaxOmega) { registryQC.fill(HIST("nITScls_vs_p_omega"), track.p(), trackITS.itsNCls()); if (btrack.sign() > 0) { registryData.fill(HIST("omega_pos_avgclustersize"), track.p(), averageClusterSize, track.eta()); - registryData.fill(HIST("omega_pos_avgclustersize_cosL"), track.p(), averageClusterSize * cos(lambda)); - registryData.fill(HIST("omega_pos_avgclustersize_cosL_vs_betagamma"), track.p() / mOmega, averageClusterSize * cos(lambda)); + registryData.fill(HIST("omega_pos_avgclustersize_cosL"), track.p(), averageClusterSize * std::cos(lambda)); + registryData.fill(HIST("omega_pos_avgclustersize_cosL_vs_betagamma"), track.p() / o2::constants::physics::MassOmegaPlusBar, averageClusterSize * std::cos(lambda)); } if (btrack.sign() < 0) { registryData.fill(HIST("omega_neg_avgclustersize"), track.p(), averageClusterSize, track.eta()); - registryData.fill(HIST("omega_neg_avgclustersize_cosL"), track.p(), averageClusterSize * cos(lambda)); - registryData.fill(HIST("omega_neg_avgclustersize_cosL_vs_betagamma"), track.p() / mOmega, averageClusterSize * cos(lambda)); + registryData.fill(HIST("omega_neg_avgclustersize_cosL"), track.p(), averageClusterSize * std::cos(lambda)); + registryData.fill(HIST("omega_neg_avgclustersize_cosL_vs_betagamma"), track.p() / o2::constants::physics::MassOmegaMinus, averageClusterSize * std::cos(lambda)); } } } } - PROCESS_SWITCH(tracked_cascade_properties, processData, "Process data", true); + PROCESS_SWITCH(TrackedCascadeProperties, processData, "Process data", true); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { - return WorkflowSpec{adaptAnalysisTask(cfgc)}; + return WorkflowSpec{adaptAnalysisTask(cfgc)}; } diff --git a/PWGLF/Tasks/Resonances/doublephimeson.cxx b/PWGLF/Tasks/Resonances/doublephimeson.cxx index 23eb7a8043d..607b65b9fbd 100644 --- a/PWGLF/Tasks/Resonances/doublephimeson.cxx +++ b/PWGLF/Tasks/Resonances/doublephimeson.cxx @@ -45,19 +45,24 @@ struct doublephimeson { Configurable strategyPID2{"strategyPID2", 0, "PID strategy 2"}; Configurable minPhiMass{"minPhiMass", 1.01, "Minimum phi mass"}; Configurable maxPhiMass{"maxPhiMass", 1.03, "Maximum phi mass"}; + Configurable minExoticMass{"minExoticMass", 2.4, "Minimum Exotic mass"}; + Configurable maxExoticMass{"maxExoticMass", 3.2, "Maximum Exotic mass"}; Configurable additionalEvsel{"additionalEvsel", false, "Additional event selection"}; Configurable isDeep{"isDeep", true, "Store deep angle"}; Configurable cutMinNsigmaTPC{"cutMinNsigmaTPC", -2.5, "nsigma cut TPC"}; Configurable cutNsigmaTPC{"cutNsigmaTPC", 3.0, "nsigma cut TPC"}; Configurable cutNsigmaTOF{"cutNsigmaTOF", 3.0, "nsigma cut TOF"}; + Configurable momTOFCut{"momTOFCut", 1.8, "minimum pT cut for madnatory TOF"}; + Configurable maxKaonPt{"maxKaonPt", 100.0, "maximum kaon pt cut"}; // Event Mixing - Configurable nEvtMixing{"nEvtMixing", 10, "Number of events to mix"}; + Configurable nEvtMixing{"nEvtMixing", 1, "Number of events to mix"}; ConfigurableAxis CfgVtxBins{"CfgVtxBins", {10, -10, 10}, "Mixing bins - z-vertex"}; ConfigurableAxis CfgMultBins{"CfgMultBins", {VARIABLE_WIDTH, 0.0, 20.0, 40.0, 60.0, 80.0, 500.0}, "Mixing bins - number of contributor"}; // THnsparse bining ConfigurableAxis configThnAxisInvMass{"configThnAxisInvMass", {1500, 2.0, 3.5}, "#it{M} (GeV/#it{c}^{2})"}; ConfigurableAxis configThnAxisInvMassPhi{"configThnAxisInvMassPhi", {20, 1.01, 1.03}, "#it{M} (GeV/#it{c}^{2})"}; + ConfigurableAxis configThnAxisInvMassDeltaPhi{"configThnAxisInvMassDeltaPhi", {80, 0.0, 0.08}, "#it{M} (GeV/#it{c}^{2})"}; ConfigurableAxis configThnAxisDaugherPt{"configThnAxisDaugherPt", {25, 0.0, 50.}, "#it{p}_{T} (GeV/#it{c})"}; ConfigurableAxis configThnAxisPt{"configThnAxisPt", {40, 0.0, 20.}, "#it{p}_{T} (GeV/#it{c})"}; ConfigurableAxis configThnAxisKstar{"configThnAxisKstar", {200, 0.0, 2.0}, "#it{k}^{*} (GeV/#it{c})"}; @@ -71,17 +76,21 @@ struct doublephimeson { // register histograms histos.add("hnsigmaTPCKaonPlus", "hnsigmaTPCKaonPlus", kTH2F, {{1000, -3.0, 3.0f}, {100, 0.0f, 10.0f}}); histos.add("hnsigmaTPCKaonMinus", "hnsigmaTPCKaonMinus", kTH2F, {{1000, -3.0, 3.0f}, {100, 0.0f, 10.0f}}); + histos.add("hnsigmaTPCTOFKaon", "hnsigmaTPCTOFKaon", kTH3F, {{500, -3.0, 3.0f}, {500, -3.0, 3.0f}, {100, 0.0f, 10.0f}}); histos.add("hPhiMass", "hPhiMass", kTH2F, {{40, 1.0, 1.04f}, {100, 0.0f, 10.0f}}); + histos.add("hPhiMass2", "hPhiMass2", kTH2F, {{40, 1.0, 1.04f}, {40, 1.0f, 1.04f}}); const AxisSpec thnAxisInvMass{configThnAxisInvMass, "#it{M} (GeV/#it{c}^{2})"}; const AxisSpec thnAxisInvMassPhi{configThnAxisInvMassPhi, "#it{M} (GeV/#it{c}^{2})"}; + const AxisSpec thnAxisInvMassDeltaPhi{configThnAxisInvMassDeltaPhi, "#it{M} (GeV/#it{c}^{2})"}; const AxisSpec thnAxisPt{configThnAxisPt, "#it{p}_{T} (GeV/#it{c})"}; const AxisSpec thnAxisDeltaR{configThnAxisDeltaR, "#Delta R)"}; const AxisSpec thnAxisCosTheta{configThnAxisCosTheta, "cos #theta"}; const AxisSpec thnAxisNumPhi{configThnAxisNumPhi, "Number of phi meson"}; - histos.add("SEMassUnlike", "SEMassUnlike", HistType::kTHnSparseF, {thnAxisInvMass, thnAxisPt, thnAxisDeltaR, thnAxisCosTheta, thnAxisInvMassPhi, thnAxisInvMassPhi, thnAxisNumPhi}); - histos.add("MEMassUnlike", "MEMassUnlike", HistType::kTHnSparseF, {thnAxisInvMass, thnAxisPt, thnAxisDeltaR, thnAxisCosTheta, thnAxisInvMassPhi, thnAxisInvMassPhi, thnAxisNumPhi}); + histos.add("SEMassUnlike", "SEMassUnlike", HistType::kTHnSparseF, {thnAxisInvMass, thnAxisPt, thnAxisDeltaR, thnAxisInvMassPhi, thnAxisInvMassPhi, thnAxisNumPhi}); + // histos.add("SEMassLike", "SEMassLike", HistType::kTHnSparseF, {thnAxisInvMass, thnAxisPt, thnAxisDeltaR, thnAxisInvMassPhi, thnAxisInvMassPhi, thnAxisNumPhi}); + histos.add("MEMassUnlike", "MEMassUnlike", HistType::kTHnSparseF, {thnAxisInvMass, thnAxisPt, thnAxisDeltaR, thnAxisInvMassPhi, thnAxisInvMassPhi}); } // get kstar @@ -107,6 +116,20 @@ struct doublephimeson { return 0.5 * trackRelK.P(); } + float deepangle2(const ROOT::Math::PtEtaPhiMVector candidate1, + const ROOT::Math::PtEtaPhiMVector candidate2) + { + double pt1, pt2, pz1, pz2, p1, p2, angle; + pt1 = candidate1.Pt(); + pt2 = candidate2.Pt(); + pz1 = candidate1.Pz(); + pz2 = candidate2.Pz(); + p1 = candidate1.P(); + p2 = candidate2.P(); + angle = TMath::ACos((pt1 * pt2 + pz1 * pz2) / (p1 * p2)); + return angle; + } + float deepangle(const TLorentzVector candidate1, const TLorentzVector candidate2) { @@ -141,35 +164,122 @@ struct doublephimeson { bool selectionPID(float nsigmaTPC, float nsigmaTOF, int TOFHit, int PIDStrategy, float ptcand) { + // optimized TPC TOF if (PIDStrategy == 0) { + if (ptcand < 0.4) { + if (nsigmaTPC > -3.0 && nsigmaTPC < 3.0) { + return true; + } + } else if (ptcand >= 0.4 && ptcand < 0.5) { + if (nsigmaTPC > -2.0 && nsigmaTPC < 3.0) { + return true; + } + } else if (ptcand >= 0.5 && ptcand < 5.0 && TOFHit == 1) { + if (ptcand < 2.0 && TMath::Sqrt(nsigmaTOF * nsigmaTOF + nsigmaTPC * nsigmaTPC) < 2.5) { + return true; + } + if (ptcand >= 2.0 && TMath::Sqrt(nsigmaTOF * nsigmaTOF + nsigmaTPC * nsigmaTPC) < 2.0) { + return true; + } + } else if (ptcand >= 0.5 && ptcand < 5.0 && TOFHit != 1) { + if (ptcand >= 0.5 && ptcand < 0.6 && nsigmaTPC > -1.5 && nsigmaTPC < 2.0) { + return true; + } + if (ptcand >= 0.6 && ptcand < 0.7 && nsigmaTPC > -1.0 && nsigmaTPC < 2.0) { + return true; + } + if (ptcand >= 0.7 && ptcand < 0.8 && nsigmaTPC > -0.4 && nsigmaTPC < 2.0) { + return true; + } + if (ptcand >= 0.8 && ptcand < 1.0 && nsigmaTPC > -0.0 && nsigmaTPC < 2.0) { + return true; + } + if (ptcand >= 1.0 && ptcand < 1.8 && nsigmaTPC > -2.0 && nsigmaTPC < 2.0) { + return true; + } + if (ptcand >= 1.8 && ptcand < 2.0 && nsigmaTPC > -2.0 && nsigmaTPC < 1.5) { + return true; + } + if (ptcand >= 2.0 && nsigmaTPC > -2.0 && nsigmaTPC < 1.0) { + return true; + } + } else if (ptcand >= 5.0 && nsigmaTPC > -2.0 && nsigmaTPC < 2.0) { + return true; + } + } + // optimized TPC TOF combined + if (PIDStrategy == 1) { + if (ptcand < 0.4) { + if (nsigmaTPC > cutMinNsigmaTPC && nsigmaTPC < cutNsigmaTPC) { + return true; + } + } else if (ptcand >= 0.4 && ptcand < 0.5) { + if (nsigmaTPC > -2.0 && nsigmaTPC < cutNsigmaTPC) { + return true; + } + } else if (ptcand >= 0.5 && ptcand < 5.0 && TOFHit == 1) { + if (ptcand < 2.0 && TMath::Sqrt(nsigmaTOF * nsigmaTOF + nsigmaTPC * nsigmaTPC) < 2.5) { + return true; + } + if (ptcand >= 2.0 && TMath::Sqrt(nsigmaTOF * nsigmaTOF + nsigmaTPC * nsigmaTPC) < 2.0) { + return true; + } + } else if (ptcand >= 5.0 && nsigmaTPC > -2.0 && nsigmaTPC < 2.0) { + return true; + } + } + + if (PIDStrategy == 2) { if (ptcand < 0.5) { if (nsigmaTPC > cutMinNsigmaTPC && nsigmaTPC < cutNsigmaTPC) { return true; } } if (ptcand >= 0.5) { - if (TOFHit != 1) { - if (nsigmaTPC > cutMinNsigmaTPC && nsigmaTPC < cutNsigmaTPC) { + if (TOFHit != 1 && ptcand < momTOFCut) { + if (ptcand >= 0.5 && ptcand < 0.6 && nsigmaTPC > -1.5 && nsigmaTPC < cutNsigmaTPC) { + return true; + } + if (ptcand >= 0.6 && ptcand < 0.7 && nsigmaTPC > -1.0 && nsigmaTPC < cutNsigmaTPC) { + return true; + } + if (ptcand >= 0.7 && ptcand < 0.8 && nsigmaTPC > -0.4 && nsigmaTPC < cutNsigmaTPC) { + return true; + } + if (ptcand >= 0.8 && ptcand < 1.0 && nsigmaTPC > -0.0 && nsigmaTPC < cutNsigmaTPC) { + return true; + } + if (ptcand >= 1.0 && ptcand < 1.8 && nsigmaTPC > -2.0 && nsigmaTPC < 2.0) { + return true; + } + if (ptcand >= 1.8 && ptcand < 2.0 && nsigmaTPC > -2.0 && nsigmaTPC < 1.5) { + return true; + } + if (ptcand >= 2.0 && nsigmaTPC > -2.0 && nsigmaTPC < 1.0) { return true; } } if (TOFHit == 1) { - if (nsigmaTPC > cutMinNsigmaTPC && nsigmaTPC < cutNsigmaTPC && TMath::Abs(nsigmaTOF) < cutNsigmaTOF) { + if (TMath::Sqrt((nsigmaTPC * nsigmaTPC + nsigmaTOF * nsigmaTOF) / 2.0) < cutNsigmaTOF) { return true; } } } } - - if (PIDStrategy == 1) { + if (PIDStrategy == 3) { if (ptcand < 0.5) { if (nsigmaTPC > cutMinNsigmaTPC && nsigmaTPC < cutNsigmaTPC) { return true; } } if (ptcand >= 0.5) { + if (TOFHit != 1) { + if (nsigmaTPC > cutMinNsigmaTPC && nsigmaTPC < cutNsigmaTPC) { + return true; + } + } if (TOFHit == 1) { - if (nsigmaTPC > cutMinNsigmaTPC && nsigmaTPC < cutNsigmaTPC && TMath::Abs(nsigmaTOF) < cutNsigmaTOF) { + if (TMath::Sqrt((nsigmaTPC * nsigmaTPC + nsigmaTOF * nsigmaTOF) / 2.0) < cutNsigmaTOF) { return true; } } @@ -179,41 +289,71 @@ struct doublephimeson { } TLorentzVector exotic, Phid1, Phid2; + // TLorentzVector exoticlike, Phi1kaonplus, Phi1kaonminus, Phi2kaonplus, Phi2kaonminus, Phid1like, Phid2like; // TLorentzVector exoticRot, Phid1Rot; - void process(aod::RedPhiEvents::iterator const& collision, aod::PhiTracks const& phitracks) + void processSE(aod::RedPhiEvents::iterator const& collision, aod::PhiTracks const& phitracks) { if (additionalEvsel && (collision.numPos() < 2 || collision.numNeg() < 2)) { return; } - auto phimult = phitracks.size(); + int phimult = 0; for (auto phitrackd1 : phitracks) { if (phitrackd1.phiMass() < minPhiMass || phitrackd1.phiMass() > maxPhiMass) { continue; } auto kaonplusd1pt = TMath::Sqrt(phitrackd1.phid1Px() * phitrackd1.phid1Px() + phitrackd1.phid1Py() * phitrackd1.phid1Py()); auto kaonminusd1pt = TMath::Sqrt(phitrackd1.phid2Px() * phitrackd1.phid2Px() + phitrackd1.phid2Py() * phitrackd1.phid2Py()); + if (kaonplusd1pt > maxKaonPt) { + continue; + } + if (kaonminusd1pt > maxKaonPt) { + continue; + } if (!selectionPID(phitrackd1.phid1TPC(), phitrackd1.phid1TOF(), phitrackd1.phid1TOFHit(), strategyPID1, kaonplusd1pt)) { continue; } if (!selectionPID(phitrackd1.phid2TPC(), phitrackd1.phid2TOF(), phitrackd1.phid2TOFHit(), strategyPID1, kaonminusd1pt)) { continue; } - auto phid1id = phitrackd1.index(); - Phid1.SetXYZM(phitrackd1.phiPx(), phitrackd1.phiPy(), phitrackd1.phiPz(), phitrackd1.phiMass()); + phimult = phimult + 1; + } + for (auto phitrackd1 : phitracks) { + auto kaonplusd1pt = TMath::Sqrt(phitrackd1.phid1Px() * phitrackd1.phid1Px() + phitrackd1.phid1Py() * phitrackd1.phid1Py()); + auto kaonminusd1pt = TMath::Sqrt(phitrackd1.phid2Px() * phitrackd1.phid2Px() + phitrackd1.phid2Py() * phitrackd1.phid2Py()); + if (kaonplusd1pt > maxKaonPt) { + continue; + } + if (kaonminusd1pt > maxKaonPt) { + continue; + } + if (!selectionPID(phitrackd1.phid1TPC(), phitrackd1.phid1TOF(), phitrackd1.phid1TOFHit(), strategyPID1, kaonplusd1pt)) { + continue; + } + histos.fill(HIST("hnsigmaTPCTOFKaon"), phitrackd1.phid1TPC(), phitrackd1.phid1TOF(), kaonplusd1pt); histos.fill(HIST("hnsigmaTPCKaonPlus"), phitrackd1.phid1TPC(), kaonplusd1pt); + if (!selectionPID(phitrackd1.phid2TPC(), phitrackd1.phid2TOF(), phitrackd1.phid2TOFHit(), strategyPID1, kaonminusd1pt)) { + continue; + } histos.fill(HIST("hnsigmaTPCKaonMinus"), phitrackd1.phid2TPC(), kaonminusd1pt); histos.fill(HIST("hPhiMass"), Phid1.M(), Phid1.Pt()); + auto phid1id = phitrackd1.index(); + Phid1.SetXYZM(phitrackd1.phiPx(), phitrackd1.phiPy(), phitrackd1.phiPz(), phitrackd1.phiMass()); + // Phi1kaonplus.SetXYZM(phitrackd1.phid1Px(), phitrackd1.phid1Py(), phitrackd1.phid1Pz(), 0.493); + // Phi1kaonminus.SetXYZM(phitrackd1.phid2Px(), phitrackd1.phid2Py(), phitrackd1.phid2Pz(), 0.493); for (auto phitrackd2 : phitracks) { auto phid2id = phitrackd2.index(); if (phid2id <= phid1id) { continue; } - if (phitrackd2.phiMass() < minPhiMass || phitrackd2.phiMass() > maxPhiMass) { - continue; - } auto kaonplusd2pt = TMath::Sqrt(phitrackd2.phid1Px() * phitrackd2.phid1Px() + phitrackd2.phid1Py() * phitrackd2.phid1Py()); auto kaonminusd2pt = TMath::Sqrt(phitrackd2.phid2Px() * phitrackd2.phid2Px() + phitrackd2.phid2Py() * phitrackd2.phid2Py()); + if (kaonplusd2pt > maxKaonPt) { + continue; + } + if (kaonminusd2pt > maxKaonPt) { + continue; + } if (!selectionPID(phitrackd2.phid1TPC(), phitrackd2.phid1TOF(), phitrackd2.phid1TOFHit(), strategyPID2, kaonplusd2pt)) { continue; } @@ -227,20 +367,220 @@ struct doublephimeson { continue; } Phid2.SetXYZM(phitrackd2.phiPx(), phitrackd2.phiPy(), phitrackd2.phiPz(), phitrackd2.phiMass()); + // Phi2kaonplus.SetXYZM(phitrackd2.phid1Px(), phitrackd2.phid1Py(), phitrackd2.phid1Pz(), 0.493); + // Phi2kaonminus.SetXYZM(phitrackd2.phid2Px(), phitrackd2.phid2Py(), phitrackd2.phid2Pz(), 0.493); + + /* + // Like + Phid1like = Phi1kaonplus + Phi2kaonplus; + Phid2like = Phi1kaonminus + Phi2kaonminus; + exoticlike = Phid1like + Phid2like; + auto deltaRlike = TMath::Sqrt(TMath::Power(Phid1like.Phi() - Phid2like.Phi(), 2.0) + TMath::Power(Phid1like.Eta() - Phid2like.Eta(), 2.0)); + auto costhetalike = (Phid1like.Px() * Phid2like.Px() + Phid1like.Py() * Phid2like.Py() + Phid1like.Pz() * Phid2like.Pz()) / (Phid1like.P() * Phid2like.P()); + auto deltamlike = TMath::Sqrt(TMath::Power(Phid1like.M() - 1.0192, 2.0) + TMath::Power(Phid2like.M() - 1.0192, 2.0)); + if (!isDeep) { + histos.fill(HIST("SEMassLike"), exoticlike.M(), exoticlike.Pt(), deltaRlike, costhetalike, deltamlike, phimult); + } + if (isDeep) { + histos.fill(HIST("SEMassLike"), exoticlike.M(), exoticlike.Pt(), deltaRlike, deepangle(Phid1like, Phid2like), deltamlike, phimult); + } + */ + // Unlike + if (phitrackd2.phiMass() < minPhiMass || phitrackd2.phiMass() > maxPhiMass) { + continue; + } + if (phitrackd1.phiMass() < minPhiMass || phitrackd1.phiMass() > maxPhiMass) { + continue; + } exotic = Phid1 + Phid2; + if (exotic.M() < minExoticMass || exotic.M() > maxExoticMass) { + continue; + } // auto cosThetaStar = getCosTheta(exotic, Phid1); // auto kstar = getkstar(Phid1, Phid2); auto deltaR = TMath::Sqrt(TMath::Power(Phid1.Phi() - Phid2.Phi(), 2.0) + TMath::Power(Phid1.Eta() - Phid2.Eta(), 2.0)); - auto costheta = (Phid1.Px() * Phid2.Px() + Phid1.Py() * Phid2.Py() + Phid1.Pz() * Phid2.Pz()) / (Phid1.P() * Phid2.P()); + // auto costheta = (Phid1.Px() * Phid2.Px() + Phid1.Py() * Phid2.Py() + Phid1.Pz() * Phid2.Pz()) / (Phid1.P() * Phid2.P()); + // auto deltam = TMath::Sqrt(TMath::Power(Phid1.M() - 1.0192, 2.0) + TMath::Power(Phid2.M() - 1.0192, 2.0)); + histos.fill(HIST("hPhiMass2"), Phid1.M(), Phid2.M()); if (!isDeep) { - histos.fill(HIST("SEMassUnlike"), exotic.M(), exotic.Pt(), deltaR, costheta, Phid1.M(), Phid2.M(), phimult); + histos.fill(HIST("SEMassUnlike"), exotic.M(), exotic.Pt(), deltaR, Phid1.M(), Phid2.M(), phimult); } if (isDeep) { - histos.fill(HIST("SEMassUnlike"), exotic.M(), exotic.Pt(), deltaR, deepangle(Phid1, Phid2), Phid1.M(), Phid2.M(), phimult); + histos.fill(HIST("SEMassUnlike"), exotic.M(), exotic.Pt(), deltaR, Phid1.M(), Phid2.M(), phimult); } } } } + PROCESS_SWITCH(doublephimeson, processSE, "Process Same Event", false); + void processopti(aod::RedPhiEvents::iterator const& collision, aod::PhiTracks const& phitracks) + { + std::vector exoticresonance, phiresonanced1, phiresonanced2; + std::vector d1trackid = {}; + std::vector d2trackid = {}; + std::vector d3trackid = {}; + std::vector d4trackid = {}; + if (additionalEvsel && (collision.numPos() < 2 || collision.numNeg() < 2)) { + return; + } + int phimult = 0; + + for (auto phitrackd1 : phitracks) { + if (phitrackd1.phiMass() < minPhiMass || phitrackd1.phiMass() > maxPhiMass) { + continue; + } + auto kaonplusd1pt = TMath::Sqrt(phitrackd1.phid1Px() * phitrackd1.phid1Px() + phitrackd1.phid1Py() * phitrackd1.phid1Py()); + auto kaonminusd1pt = TMath::Sqrt(phitrackd1.phid2Px() * phitrackd1.phid2Px() + phitrackd1.phid2Py() * phitrackd1.phid2Py()); + if (kaonplusd1pt > maxKaonPt) { + continue; + } + if (kaonminusd1pt > maxKaonPt) { + continue; + } + if (!selectionPID(phitrackd1.phid1TPC(), phitrackd1.phid1TOF(), phitrackd1.phid1TOFHit(), strategyPID1, kaonplusd1pt)) { + continue; + } + if (!selectionPID(phitrackd1.phid2TPC(), phitrackd1.phid2TOF(), phitrackd1.phid2TOFHit(), strategyPID1, kaonminusd1pt)) { + continue; + } + phimult = phimult + 1; + } + for (auto phitrackd1 : phitracks) { + auto kaonplusd1pt = TMath::Sqrt(phitrackd1.phid1Px() * phitrackd1.phid1Px() + phitrackd1.phid1Py() * phitrackd1.phid1Py()); + auto kaonminusd1pt = TMath::Sqrt(phitrackd1.phid2Px() * phitrackd1.phid2Px() + phitrackd1.phid2Py() * phitrackd1.phid2Py()); + if (kaonplusd1pt > maxKaonPt) { + continue; + } + if (kaonminusd1pt > maxKaonPt) { + continue; + } + if (!selectionPID(phitrackd1.phid1TPC(), phitrackd1.phid1TOF(), phitrackd1.phid1TOFHit(), strategyPID1, kaonplusd1pt)) { + continue; + } + histos.fill(HIST("hnsigmaTPCTOFKaon"), phitrackd1.phid1TPC(), phitrackd1.phid1TOF(), kaonplusd1pt); + histos.fill(HIST("hnsigmaTPCKaonPlus"), phitrackd1.phid1TPC(), kaonplusd1pt); + if (!selectionPID(phitrackd1.phid2TPC(), phitrackd1.phid2TOF(), phitrackd1.phid2TOFHit(), strategyPID1, kaonminusd1pt)) { + continue; + } + histos.fill(HIST("hnsigmaTPCKaonMinus"), phitrackd1.phid2TPC(), kaonminusd1pt); + histos.fill(HIST("hPhiMass"), Phid1.M(), Phid1.Pt()); + auto phid1id = phitrackd1.index(); + Phid1.SetXYZM(phitrackd1.phiPx(), phitrackd1.phiPy(), phitrackd1.phiPz(), phitrackd1.phiMass()); + // Phi1kaonplus.SetXYZM(phitrackd1.phid1Px(), phitrackd1.phid1Py(), phitrackd1.phid1Pz(), 0.493); + // Phi1kaonminus.SetXYZM(phitrackd1.phid2Px(), phitrackd1.phid2Py(), phitrackd1.phid2Pz(), 0.493); + for (auto phitrackd2 : phitracks) { + auto phid2id = phitrackd2.index(); + if (phid2id <= phid1id) { + continue; + } + auto kaonplusd2pt = TMath::Sqrt(phitrackd2.phid1Px() * phitrackd2.phid1Px() + phitrackd2.phid1Py() * phitrackd2.phid1Py()); + auto kaonminusd2pt = TMath::Sqrt(phitrackd2.phid2Px() * phitrackd2.phid2Px() + phitrackd2.phid2Py() * phitrackd2.phid2Py()); + if (kaonplusd2pt > maxKaonPt) { + continue; + } + if (kaonminusd2pt > maxKaonPt) { + continue; + } + if (!selectionPID(phitrackd2.phid1TPC(), phitrackd2.phid1TOF(), phitrackd2.phid1TOFHit(), strategyPID2, kaonplusd2pt)) { + continue; + } + if (!selectionPID(phitrackd2.phid2TPC(), phitrackd2.phid2TOF(), phitrackd2.phid2TOFHit(), strategyPID2, kaonminusd2pt)) { + continue; + } + if ((phitrackd1.phid1Index() == phitrackd2.phid1Index()) || (phitrackd1.phid2Index() == phitrackd2.phid2Index())) { + continue; + } + Phid2.SetXYZM(phitrackd2.phiPx(), phitrackd2.phiPy(), phitrackd2.phiPz(), phitrackd2.phiMass()); + // Phi2kaonplus.SetXYZM(phitrackd2.phid1Px(), phitrackd2.phid1Py(), phitrackd2.phid1Pz(), 0.493); + // Phi2kaonminus.SetXYZM(phitrackd2.phid2Px(), phitrackd2.phid2Py(), phitrackd2.phid2Pz(), 0.493); + /* + // Like + Phid1like = Phi1kaonplus + Phi2kaonplus; + Phid2like = Phi1kaonminus + Phi2kaonminus; + exoticlike = Phid1like + Phid2like; + auto deltaRlike = TMath::Sqrt(TMath::Power(Phid1like.Phi() - Phid2like.Phi(), 2.0) + TMath::Power(Phid1like.Eta() - Phid2like.Eta(), 2.0)); + auto costhetalike = (Phid1like.Px() * Phid2like.Px() + Phid1like.Py() * Phid2like.Py() + Phid1like.Pz() * Phid2like.Pz()) / (Phid1like.P() * Phid2like.P()); + auto deltamlike = TMath::Sqrt(TMath::Power(Phid1like.M() - 1.0192, 2.0) + TMath::Power(Phid2like.M() - 1.0192, 2.0)); + if (!isDeep) { + histos.fill(HIST("SEMassLike"), exoticlike.M(), exoticlike.Pt(), deltaRlike, costhetalike, deltamlike, phimult); + } + if (isDeep) { + histos.fill(HIST("SEMassLike"), exoticlike.M(), exoticlike.Pt(), deltaRlike, deepangle(Phid1like, Phid2like), deltamlike, phimult); + } + */ + // unlike + if (phitrackd1.phiMass() < minPhiMass || phitrackd1.phiMass() > maxPhiMass) { + continue; + } + if (phitrackd2.phiMass() < minPhiMass || phitrackd2.phiMass() > maxPhiMass) { + continue; + } + exotic = Phid1 + Phid2; + if (exotic.M() < minExoticMass || exotic.M() > maxExoticMass) { + continue; + } + ROOT::Math::PtEtaPhiMVector temp1(exotic.Pt(), exotic.Eta(), exotic.Phi(), exotic.M()); + ROOT::Math::PtEtaPhiMVector temp2(Phid1.Pt(), Phid1.Eta(), Phid1.Phi(), Phid1.M()); + ROOT::Math::PtEtaPhiMVector temp3(Phid2.Pt(), Phid2.Eta(), Phid2.Phi(), Phid2.M()); + exoticresonance.push_back(temp1); + phiresonanced1.push_back(temp2); + phiresonanced2.push_back(temp3); + d1trackid.push_back(phitrackd1.phid1Index()); + d2trackid.push_back(phitrackd2.phid1Index()); + d3trackid.push_back(phitrackd1.phid2Index()); + d4trackid.push_back(phitrackd2.phid2Index()); + } + } + if (exoticresonance.size() == 0) { + return; + } + // LOGF(info, "Total number of exotic: %d", exoticresonance.size()); + if (exoticresonance.size() == 2) { + for (auto if1 = exoticresonance.begin(); if1 != exoticresonance.end(); ++if1) { + auto i5 = std::distance(exoticresonance.begin(), if1); + auto exotic1phi1 = phiresonanced1.at(i5); + auto exotic1phi2 = phiresonanced2.at(i5); + auto exotic1 = exoticresonance.at(i5); + auto deltam1 = TMath::Sqrt(TMath::Power(exotic1phi1.M() - 1.0192, 2.0) + TMath::Power(exotic1phi2.M() - 1.0192, 2.0)); + auto deltaR1 = TMath::Sqrt(TMath::Power(exotic1phi1.Phi() - exotic1phi2.Phi(), 2.0) + TMath::Power(exotic1phi1.Eta() - exotic1phi2.Eta(), 2.0)); + for (auto if2 = if1 + 1; if2 != exoticresonance.end(); ++if2) { + auto i6 = std::distance(exoticresonance.begin(), if2); + auto exotic2phi1 = phiresonanced1.at(i6); + auto exotic2phi2 = phiresonanced2.at(i6); + auto exotic2 = exoticresonance.at(i6); + auto deltam2 = TMath::Sqrt(TMath::Power(exotic2phi1.M() - 1.0192, 2.0) + TMath::Power(exotic2phi2.M() - 1.0192, 2.0)); + auto deltaR2 = TMath::Sqrt(TMath::Power(exotic2phi1.Phi() - exotic2phi2.Phi(), 2.0) + TMath::Power(exotic2phi1.Eta() - exotic2phi2.Eta(), 2.0)); + // LOGF(info, "exotic 1 kaon ids %d , %d, %d, %d", d1trackid.at(i5), d2trackid.at(i5), d3trackid.at(i5), d4trackid.at(i5)); + // LOGF(info, "exotic 2 kaon ids %d , %d, %d, %d", d1trackid.at(i6), d2trackid.at(i6), d3trackid.at(i6), d4trackid.at(i6)); + if ((d1trackid.at(i5) == d1trackid.at(i6) || d1trackid.at(i5) == d2trackid.at(i6)) && + (d2trackid.at(i5) == d1trackid.at(i6) || d2trackid.at(i5) == d2trackid.at(i6)) && + (d3trackid.at(i5) == d3trackid.at(i6) || d3trackid.at(i5) == d4trackid.at(i6)) && + (d4trackid.at(i5) == d3trackid.at(i6) || d4trackid.at(i5) == d4trackid.at(i6))) { + // LOGF(info, "Find Pair %f %f", deltam2, deltam1); + if (deltam2 < deltam1) { + histos.fill(HIST("SEMassUnlike"), exotic2.M(), exotic2.Pt(), deltaR2, exotic2phi1.M(), exotic2phi2.M(), phimult); + // LOGF(info, "Fill exotic Id %d which is pair of Id %d", i6, i5); + } else { + histos.fill(HIST("SEMassUnlike"), exotic1.M(), exotic1.Pt(), deltaR1, exotic1phi1.M(), exotic1phi2.M(), phimult); + // LOGF(info, "Fill exotic Id %d which is pair of Id %d", i6, i5); + } + } else { + histos.fill(HIST("SEMassUnlike"), exotic1.M(), exotic1.Pt(), deltaR1, exotic1phi1.M(), exotic1phi2.M(), phimult); + } + } + } + } else { + for (auto if1 = exoticresonance.begin(); if1 != exoticresonance.end(); ++if1) { + auto i5 = std::distance(exoticresonance.begin(), if1); + auto exotic1phi1 = phiresonanced1.at(i5); + auto exotic1phi2 = phiresonanced2.at(i5); + auto exotic1 = exoticresonance.at(i5); + // auto deltam1 = TMath::Sqrt(TMath::Power(exotic1phi1.M() - 1.0192, 2.0) + TMath::Power(exotic1phi2.M() - 1.0192, 2.0)); + auto deltaR1 = TMath::Sqrt(TMath::Power(exotic1phi1.Phi() - exotic1phi2.Phi(), 2.0) + TMath::Power(exotic1phi1.Eta() - exotic1phi2.Eta(), 2.0)); + histos.fill(HIST("SEMassUnlike"), exotic1.M(), exotic1.Pt(), deltaR1, exotic1phi1.M(), exotic1phi2.M(), phimult); + } + } + } + PROCESS_SWITCH(doublephimeson, processopti, "Process Optimized same event", false); SliceCache cache; using BinningTypeVertexContributor = ColumnBinningPolicy; @@ -254,7 +594,6 @@ struct doublephimeson { if (collision1.index() == collision2.index()) { continue; } - auto phimult = tracks1.size(); for (auto& [phitrackd1, phitrackd2] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(tracks1, tracks2))) { if (phitrackd1.phiMass() < minPhiMass || phitrackd1.phiMass() > maxPhiMass) { continue; @@ -266,6 +605,18 @@ struct doublephimeson { auto kaonminusd1pt = TMath::Sqrt(phitrackd1.phid2Px() * phitrackd1.phid2Px() + phitrackd1.phid2Py() * phitrackd1.phid2Py()); auto kaonplusd2pt = TMath::Sqrt(phitrackd2.phid1Px() * phitrackd2.phid1Px() + phitrackd2.phid1Py() * phitrackd2.phid1Py()); auto kaonminusd2pt = TMath::Sqrt(phitrackd2.phid2Px() * phitrackd2.phid2Px() + phitrackd2.phid2Py() * phitrackd2.phid2Py()); + if (kaonplusd1pt > maxKaonPt) { + continue; + } + if (kaonminusd1pt > maxKaonPt) { + continue; + } + if (kaonplusd2pt > maxKaonPt) { + continue; + } + if (kaonminusd2pt > maxKaonPt) { + continue; + } if (!selectionPID(phitrackd1.phid1TPC(), phitrackd1.phid1TOF(), phitrackd1.phid1TOFHit(), strategyPID1, kaonplusd1pt)) { continue; } @@ -282,12 +633,13 @@ struct doublephimeson { Phid2.SetXYZM(phitrackd2.phiPx(), phitrackd2.phiPy(), phitrackd2.phiPz(), phitrackd2.phiMass()); exotic = Phid1 + Phid2; auto deltaR = TMath::Sqrt(TMath::Power(Phid1.Phi() - Phid2.Phi(), 2.0) + TMath::Power(Phid1.Eta() - Phid2.Eta(), 2.0)); - auto costheta = (Phid1.Px() * Phid2.Px() + Phid1.Py() * Phid2.Py() + Phid1.Pz() * Phid2.Pz()) / (Phid1.P() * Phid2.P()); + // auto costheta = (Phid1.Px() * Phid2.Px() + Phid1.Py() * Phid2.Py() + Phid1.Pz() * Phid2.Pz()) / (Phid1.P() * Phid2.P()); + // auto deltam = TMath::Sqrt(TMath::Power(Phid1.M() - 1.0192, 2.0) + TMath::Power(Phid2.M() - 1.0192, 2.0)); if (!isDeep) { - histos.fill(HIST("MEMassUnlike"), exotic.M(), exotic.Pt(), deltaR, costheta, Phid1.M(), Phid2.M(), phimult); + histos.fill(HIST("MEMassUnlike"), exotic.M(), exotic.Pt(), deltaR, Phid1.M(), Phid2.M()); } if (isDeep) { - histos.fill(HIST("MEMassUnlike"), exotic.M(), exotic.Pt(), deltaR, deepangle(Phid1, Phid2), Phid1.M(), Phid2.M(), phimult); + histos.fill(HIST("MEMassUnlike"), exotic.M(), exotic.Pt(), deltaR, Phid1.M(), Phid2.M()); } } } diff --git a/PWGLF/Tasks/Resonances/f0980pbpbanalysis.cxx b/PWGLF/Tasks/Resonances/f0980pbpbanalysis.cxx index 9bc3c7d40f9..4602483e636 100644 --- a/PWGLF/Tasks/Resonances/f0980pbpbanalysis.cxx +++ b/PWGLF/Tasks/Resonances/f0980pbpbanalysis.cxx @@ -61,7 +61,6 @@ #include "CCDB/BasicCCDBManager.h" // from phi -#include "PWGLF/DataModel/EPCalibrationTables.h" #include "Common/DataModel/PIDResponseITS.h" using namespace o2; @@ -85,8 +84,8 @@ struct F0980pbpbanalysis { Configurable cfgCutVertex{"cfgCutVertex", 10.0, "PV selection"}; Configurable cfgQvecSel{"cfgQvecSel", true, "Reject events when no QVector"}; Configurable cfgOccupancySel{"cfgOccupancySel", false, "Occupancy selection"}; - Configurable cfgMaxOccupancy{"cfgMaxOccupancy", 999999, "maximum occupancy of tracks in neighbouring collisions in a given time range"}; - Configurable cfgMinOccupancy{"cfgMinOccupancy", -100, "maximum occupancy of tracks in neighbouring collisions in a given time range"}; + Configurable cfgOccupancyMax{"cfgOccupancyMax", 999999, "maximum occupancy of tracks in neighbouring collisions in a given time range"}; + Configurable cfgOccupancyMin{"cfgOccupancyMin", -100, "minimum occupancy of tracks in neighbouring collisions in a given time range"}; Configurable cfgNCollinTR{"cfgNCollinTR", false, "Additional selection for the number of coll in time range"}; Configurable cfgPVSel{"cfgPVSel", false, "Additional PV selection flag for syst"}; Configurable cfgPV{"cfgPV", 8.0, "Additional PV selection range for syst"}; @@ -101,8 +100,8 @@ struct F0980pbpbanalysis { Configurable cfgTPCcluster{"cfgTPCcluster", 70, "Number of TPC cluster"}; Configurable cfgRatioTPCRowsOverFindableCls{"cfgRatioTPCRowsOverFindableCls", 0.8, "TPC Crossed Rows to Findable Clusters"}; - Configurable cfgMinRap{"cfgMinRap", -0.5, "Minimum rapidity for pair"}; - Configurable cfgMaxRap{"cfgMaxRap", 0.5, "Maximum rapidity for pair"}; + Configurable cfgRapMin{"cfgRapMin", -0.5, "Minimum rapidity for pair"}; + Configurable cfgRapMax{"cfgRapMax", 0.5, "Maximum rapidity for pair"}; Configurable cfgPrimaryTrack{"cfgPrimaryTrack", true, "Primary track selection"}; Configurable cfgGlobalWoDCATrack{"cfgGlobalWoDCATrack", true, "Global track selection without DCA"}; @@ -115,24 +114,23 @@ struct F0980pbpbanalysis { Configurable cfgSelectPID{"cfgSelectPID", 0, "PID selection type"}; Configurable cfgSelectPtl{"cfgSelectPtl", 0, "Particle selection type"}; - Configurable cfgnMods{"cfgnMods", 1, "The number of modulations of interest starting from 2"}; + Configurable cfgNMods{"cfgNMods", 1, "The number of modulations of interest starting from 2"}; Configurable cfgNQvec{"cfgNQvec", 7, "The number of total Qvectors for looping over the task"}; Configurable cfgQvecDetName{"cfgQvecDetName", "FT0C", "The name of detector to be analyzed"}; Configurable cfgQvecRefAName{"cfgQvecRefAName", "TPCpos", "The name of detector for reference A"}; Configurable cfgQvecRefBName{"cfgQvecRefBName", "TPCneg", "The name of detector for reference B"}; - Configurable cfgRotBkg{"cfgRotBkg", true, "flag to construct rotational backgrounds"}; - Configurable cfgNRotBkg{"cfgNRotBkg", 10, "the number of rotational backgrounds"}; + Configurable cfgRotBkgSel{"cfgRotBkgSel", true, "flag to construct rotational backgrounds"}; + Configurable cfgRotBkgNum{"cfgRotBkgNum", 10, "the number of rotational backgrounds"}; // for phi test Configurable cfgTPCFinableClsSel{"cfgTPCFinableClsSel", true, "TPC Crossed Rows to Findable Clusters selection flag"}; Configurable cfgITSClsSel{"cfgITSClsSel", false, "ITS cluster selection flag"}; Configurable cfgITScluster{"cfgITScluster", 0, "Number of ITS cluster"}; - Configurable cfgpTDepPID{"cfgpTDepPID", false, "pT dependent PID"}; - Configurable cfgBetaCutSel{"cfgBetaCutSel", false, "TOF beta cut selection flag"}; - Configurable cfgCutTOFBeta{"cfgCutTOFBeta", 0.0, "cut TOF beta"}; - Configurable isDeepAngle{"isDeepAngle", true, "Deep Angle cut"}; + Configurable cfgTOFBetaSel{"cfgTOFBetaSel", false, "TOF beta cut selection flag"}; + Configurable cfgTOFBetaCut{"cfgTOFBetaCut", 0.0, "cut TOF beta"}; + Configurable cfgDeepAngleSel{"cfgDeepAngleSel", true, "Deep Angle cut"}; Configurable cfgDeepAngle{"cfgDeepAngle", 0.04, "Deep Angle cut value"}; ConfigurableAxis massAxis{"massAxis", {400, 0.2, 2.2}, "Invariant mass axis"}; @@ -186,8 +184,7 @@ struct F0980pbpbanalysis { // Filter PIDcutFilter = nabs(aod::pidtpc::tpcNSigmaKa) < cMaxTPCnSigmaPion; // Filter PIDcutFilter = nabs(aod::pidTPCFullKa::tpcNSigmaKa) < cMaxTPCnSigmaPion; - using EventCandidates = soa::Filtered>; - // aod::EPCalibrationTables 추가됨 + using EventCandidates = soa::Filtered>; using TrackCandidates = soa::Filtered>; // aod::pidTOFbeta 추가됨 @@ -239,7 +236,7 @@ struct F0980pbpbanalysis { if (cfgQvecSel && (collision.qvecAmp()[detId] < 1e-4 || collision.qvecAmp()[refAId] < 1e-4 || collision.qvecAmp()[refBId] < 1e-4)) { return 0; } - if (cfgOccupancySel && (collision.trackOccupancyInTimeRange() > cfgMaxOccupancy || collision.trackOccupancyInTimeRange() < cfgMinOccupancy)) { + if (cfgOccupancySel && (collision.trackOccupancyInTimeRange() > cfgOccupancyMax || collision.trackOccupancyInTimeRange() < cfgOccupancyMin)) { return 0; } if (cfgNCollinTR && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { @@ -349,7 +346,7 @@ struct F0980pbpbanalysis { p1 = track1.p(); p2 = track2.p(); angle = std::acos((pt1 * pt2 + pz1 * pz2) / (p1 * p2)); - if (isDeepAngle && angle < cfgDeepAngle) { + if (cfgDeepAngleSel && angle < cfgDeepAngle) { return 0; } return 1; @@ -434,7 +431,7 @@ struct F0980pbpbanalysis { pion2.SetXYZM(trk2.px(), trk2.py(), trk2.pz(), massPtl); reco = pion1 + pion2; - if (reco.Rapidity() > cfgMaxRap || reco.Rapidity() < cfgMinRap) { + if (reco.Rapidity() > cfgRapMax || reco.Rapidity() < cfgRapMin) { continue; } @@ -448,8 +445,8 @@ struct F0980pbpbanalysis { histos.fill(HIST("hInvMass_f0980_LSmm_EPA"), reco.M(), reco.Pt(), centrality, relPhi); } - if (cfgRotBkg && trk1.sign() * trk2.sign() < 0) { - for (int nr = 0; nr < cfgNRotBkg; nr++) { + if (cfgRotBkgSel && trk1.sign() * trk2.sign() < 0) { + for (int nr = 0; nr < cfgRotBkgNum; nr++) { auto randomPhi = rn->Uniform(o2::constants::math::PI * 5.0 / 6.0, o2::constants::math::PI * 7.0 / 6.0); randomPhi += pion2.Phi(); pion2Rot.SetXYZM(pion2.Pt() * std::cos(randomPhi), pion2.Pt() * std::sin(randomPhi), trk2.pz(), massPtl); diff --git a/PWGLF/Tasks/Resonances/kstarpbpb.cxx b/PWGLF/Tasks/Resonances/kstarpbpb.cxx index b6a0cfb453b..cd2ddf8d0c0 100644 --- a/PWGLF/Tasks/Resonances/kstarpbpb.cxx +++ b/PWGLF/Tasks/Resonances/kstarpbpb.cxx @@ -651,7 +651,9 @@ struct kstarpbpb { auto angleend = confMaxRot; auto anglestep = (angleend - anglestart) / (1.0 * (nBkgRotations - 1)); auto rotangle = anglestart + nrotbkg * anglestep; - histos.fill(HIST("hRotation"), rotangle); + if (!fillSA) { + histos.fill(HIST("hRotation"), rotangle); + } auto rotkaonPx = track1.px() * std::cos(rotangle) - track1.py() * std::sin(rotangle); auto rotkaonPy = track1.px() * std::sin(rotangle) + track1.py() * std::cos(rotangle); kaonrot = ROOT::Math::PxPyPzMVector(rotkaonPx, rotkaonPy, track1.pz(), massKa); @@ -667,9 +669,9 @@ struct kstarpbpb { if (!useSP) { v2Rot = TMath::Cos(2.0 * phiminuspsiRot); } - if (!fillSA) + if (!fillSA) { histos.fill(HIST("hSparseV2SASameEventRotational_V2"), kstarrot.M(), kstarrot.Pt(), v2Rot, centrality); - + } if (fillSA) { if (track1Sign * track2Sign < 0) { ROOT::Math::Boost boost{kstarrot.BoostToCM()}; diff --git a/PWGLF/Tasks/Resonances/xi1530Analysisqa.cxx b/PWGLF/Tasks/Resonances/xi1530Analysisqa.cxx old mode 100755 new mode 100644 index 2361457f620..53e7f283150 --- a/PWGLF/Tasks/Resonances/xi1530Analysisqa.cxx +++ b/PWGLF/Tasks/Resonances/xi1530Analysisqa.cxx @@ -13,7 +13,8 @@ /// \brief Reconstruction of Xi* resonance. /// /// \author Min-jae Kim , Bong-Hwi Lim -#include +// #include +#include "Math/Vector4D.h" #include "TF1.h" #include "TRandom3.h" @@ -34,6 +35,7 @@ using namespace o2::framework; using namespace o2::framework::expressions; using namespace o2::soa; using namespace o2::constants::physics; +using LorentzVectorPtEtaPhiMass = ROOT::Math::PtEtaPhiMVector; // Service pdgDB; enum { @@ -53,8 +55,8 @@ struct Xi1530Analysisqa { // Basic set-up // SliceCache cache; - // Preslice perRCol = aod::resodaughter::resoCollisionId; - // Preslice perCollision = aod::track::collisionId; + Preslice perRCol = aod::resodaughter::resoCollisionId; + Preslice perCollision = aod::track::collisionId; HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; using ResoMCCols = soa::Join; @@ -72,10 +74,7 @@ struct Xi1530Analysisqa { Configurable invMass1D{"invMass1D", true, "Invariant mass 1D"}; Configurable studyAntiparticle{"studyAntiparticle", true, "Study anti-particles separately"}; Configurable pidPlots{"pidPlots", true, "Make TPC and TOF PID plots"}; - Configurable additionalQAplots{"additionalQAplots", true, "Additional QA plots"}; - Configurable additionalQAeventPlots{"additionalQAeventPlots", true, "Additional QA event plots"}; - Configurable additionalMEPlots{"additionalMEPlots", true, "Additional Mixed event plots"}; // Event Mixing Configurable nEvtMixing{"nEvtMixing", 10, "Number of events to mix"}; @@ -96,7 +95,7 @@ struct Xi1530Analysisqa { Configurable tofAtHighPt{"tofAtHighPt", false, "Use TOF at high pT"}; Configurable cfgTPCcluster{"cfgTPCcluster", 1, "Minimum Number of TPC cluster"}; // Minmimum - Configurable cfgTPCRows{"cfgTPCRows", 70, "Minimum Number of TPC Crossed Rows "}; + Configurable cfgTPCRows{"cfgTPCRows", 80, "Minimum Number of TPC Crossed Rows "}; Configurable cfgRatioTPCRowsOverFindableCls{"cfgRatioTPCRowsOverFindableCls", 0.8, "Minimum of TPC Crossed Rows to Findable Clusters"}; // Minmimum Configurable cfgUseTPCRefit{"cfgUseTPCRefit", true, "Require TPC Refit"}; @@ -159,6 +158,8 @@ struct Xi1530Analysisqa { Configurable cPIDBound{"cPIDBound", 6.349, "configurable for replacing to .has"}; + Configurable cMinTOFpt{"cMinTOFpt", 0.5, "Maximum TOF pt cut"}; + // PID Selections for Pion First Configurable cMaxtpcnSigmaPionFirst{"cMaxtpcnSigmaPionFirst", 4.0, "TPC nSigma cut for Pion First"}; Configurable cMaxtofnSigmaPionFirst{"cMaxtofnSigmaPionFirst", 3.0, "TOF nSigma cut for Pion First"}; @@ -236,7 +237,7 @@ struct Xi1530Analysisqa { AxisSpec pidQAAxis = {65, -6.5, 6.5}; AxisSpec flagAxis = {9, 0, 9, "Flags"}; - if (additionalQAeventPlots) { + { // Test on Mixed event histos.add("TestME/hCollisionIndexSameE", "coll index sameE", HistType::kTH1F, {{500, 0.0f, 500.0f}}); histos.add("TestME/hCollisionIndexMixedE", "coll index mixedE", HistType::kTH1F, {{500, 0.0f, 500.0f}}); @@ -268,15 +269,11 @@ struct Xi1530Analysisqa { } } - if (additionalMEPlots) { + if (doprocessMEDF || doprocessMEMicro) { histos.add("Xi1530invmassME_DS", "Invariant mass of Xi(1530)0 mixed event DS", kTH1F, {invMassAxis}); histos.add("Xi1530invmassME_DSAnti", "Invariant mass of Xi(1530)0 mixed event DSAnti", kTH1F, {invMassAxis}); } - // TPC ncluster distirbutions - // histos.add("TPCncluster/TPCnclusterpifirst", "TPC ncluster distribution", kTH1F, {{160, 0, 160, "TPC nCluster"}}); - // histos.add("TPCncluster/TPCnclusterPhipifirst", "TPC ncluster vs phi", kTH2F, {{160, 0, 160, "TPC nCluster"}, {63, 0, 6.28, "#phi"}}); - // DCA QA to candidates for first pion and Xi- histos.add("QAbefore/trkDCAxy_pi", "DCAxy distribution of pion track candidates", HistType::kTH2F, {ptAxis, dcaxyAxis}); histos.add("QAbefore/trkDCAxy_Xi", "DCAxy distribution of Xi- track candidates", HistType::kTH2F, {ptAxis, dcaxyAxis}); @@ -350,7 +347,7 @@ struct Xi1530Analysisqa { histos.add("h3XiinvmassLSAnti", "Invariant mass of Anti-Xi- same sign", kTHnSparseF, {centAxis, ptAxis, invMassAxisCasc, flagAxis}); } - if (additionalMEPlots) { + if (doprocessMEDF || doprocessMEMicro) { histos.add("h3Xi1530invmassME_DS", "Invariant mass of Xi(1530)0 mixed event DS", kTHnSparseF, {centAxis, ptAxis, invMassAxis, flagAxis}); histos.add("h3XiinvmassME_DS", "Invariant mass of Xi- mixed event DS", kTHnSparseF, {centAxis, ptAxis, invMassAxisCasc, flagAxis}); @@ -550,19 +547,31 @@ struct Xi1530Analysisqa { return true; } - bool pidSelector(float TPCNsigma, float TOFNsigma, const PidSelectionParam& params, bool tofAtHighPt) + bool pidSelector(float TPCNsigma, float TOFNsigma, const PidSelectionParam& params, bool tofAtHighPt, float trackPt) { bool tpcPIDPassed{false}, tofPIDPassed{false}; - if (tofAtHighPt) { - // TOF based PID - if (hasSubsystemInfo(TOFNsigma) && std::abs(TOFNsigma) < params.cMaxTOFnSigma) { - return true; + if (tofAtHighPt && trackPt > cMinTOFpt) { + if (std::abs(TPCNsigma) < params.cMaxTPCnSigma) { + tpcPIDPassed = true; } - if (!hasSubsystemInfo(TOFNsigma) && std::abs(TPCNsigma) < params.cMaxTPCnSigma) { + + if (params.cByPassTOF && tpcPIDPassed) { return true; } - return false; + + if (hasSubsystemInfo(TOFNsigma)) { + if (std::abs(TOFNsigma) < params.cMaxTOFnSigma) { + tofPIDPassed = true; + } + if ((params.nsigmaCutCombined > 0) && + (TPCNsigma * TPCNsigma + TOFNsigma * TOFNsigma < params.nsigmaCutCombined * params.nsigmaCutCombined)) { + tofPIDPassed = true; + } + } else { + tofPIDPassed = true; + } + return tpcPIDPassed && tofPIDPassed; } else { if (std::abs(TPCNsigma) < params.cMaxTPCnSigma) { @@ -594,7 +603,8 @@ struct Xi1530Analysisqa { bool selectionPIDPionFirst(const T& candidate) { - static float tpcNsigmaPionFirst, tofNsigmaPionFirst; + float tpcNsigmaPionFirst, tofNsigmaPionFirst; + float trackPt = candidate.pt(); if constexpr (IsResoMicrotrack) { tpcNsigmaPionFirst = o2::aod::resodmciroaughter::PidNSigma::getTPCnSigma(candidate.pidNSigmaPiFlag()); @@ -606,7 +616,7 @@ struct Xi1530Analysisqa { PidSelectionParam pionFirstParams = {cMaxtpcnSigmaPionFirst, cMaxtofnSigmaPionFirst, cByPassTOFPionFirst, nsigmaCutCombinedPionFirst}; - return pidSelector(tpcNsigmaPionFirst, tofNsigmaPionFirst, pionFirstParams, tofAtHighPt); + return pidSelector(tpcNsigmaPionFirst, tofNsigmaPionFirst, pionFirstParams, tofAtHighPt, trackPt); } template @@ -617,6 +627,7 @@ struct Xi1530Analysisqa { float tpcNsigmaBachelor, tofNsigmaBachelor; float tpcNsigmaPion, tofNsigmaPion; float tpcNsigmaProton, tofNsigmaProton; + float trackPt = candidate.pt(); if (candidate.sign() < 0) { // Xi- candidates tpcNsigmaBachelor = candidate.daughterTPCNSigmaBachPi(); @@ -643,9 +654,9 @@ struct Xi1530Analysisqa { PidSelectionParam pionParams = {cMaxtpcnSigmaPion, cMaxtofnSigmaPion, cByPassTOFPion, nsigmaCutCombinedPion}; PidSelectionParam protonParams = {cMaxtpcnSigmaProton, cMaxtofnSigmaProton, cByPassTOFProton, nsigmaCutCombinedProton}; - lConsistentWithXi = pidSelector(tpcNsigmaBachelor, tofNsigmaBachelor, bachelorParams, tofAtHighPt); - lConsistentWithPion = pidSelector(tpcNsigmaPion, tofNsigmaPion, pionParams, tofAtHighPt); - lConsistentWithProton = pidSelector(tpcNsigmaProton, tofNsigmaProton, protonParams, tofAtHighPt); + lConsistentWithXi = pidSelector(tpcNsigmaBachelor, tofNsigmaBachelor, bachelorParams, tofAtHighPt, trackPt); + lConsistentWithPion = pidSelector(tpcNsigmaPion, tofNsigmaPion, pionParams, tofAtHighPt, trackPt); + lConsistentWithProton = pidSelector(tpcNsigmaProton, tofNsigmaProton, protonParams, tofAtHighPt, trackPt); lConsistentWithLambda = lConsistentWithProton && lConsistentWithPion; @@ -657,7 +668,7 @@ struct Xi1530Analysisqa { { auto multiplicity = collision.cent(); - if (additionalQAeventPlots) { + { if constexpr (!IsMix) { histos.fill(HIST("QAevent/hVertexZSameE"), collision.posZ()); histos.fill(HIST("QAevent/hMultiplicityPercentSameE"), collision.cent()); @@ -671,11 +682,11 @@ struct Xi1530Analysisqa { } } - TLorentzVector lDecayDaughter1, lDecayDaughter2, lResonance; // It will be replaced to use RecoDecay (In fixing...) + LorentzVectorPtEtaPhiMass lDecayDaughter1, lDecayDaughter2, lResonance; // It will be replaced to use RecoDecay (In fixing...) for (const auto& [trk1, trk2] : combinations(CombinationsFullIndexPolicy(dTracks1, dTracks2))) { - if (additionalQAeventPlots) { + { if constexpr (!IsMix) { histos.fill(HIST("TestME/hPairsCounterSameE"), 1.0); } else { @@ -873,8 +884,8 @@ struct Xi1530Analysisqa { } } - lDecayDaughter1.SetPtEtaPhiM(trk1ptPi, trk1.eta(), trk1.phi(), massPi); - lDecayDaughter2.SetPtEtaPhiM(trk2ptXi, trk2.eta(), trk2.phi(), trk2.mXi()); + lDecayDaughter1 = LorentzVectorPtEtaPhiMass(trk1ptPi, trk1.eta(), trk1.phi(), massPi); + lDecayDaughter2 = LorentzVectorPtEtaPhiMass(trk2ptXi, trk2.eta(), trk2.phi(), trk2.mXi()); lResonance = lDecayDaughter1 + lDecayDaughter2; auto lResonancePt = lResonance.Pt(); @@ -1039,8 +1050,8 @@ struct Xi1530Analysisqa { void processData(aod::ResoCollision const& resoCollision, aod::ResoTracks const& resoTracks, aod::ResoCascades const& cascTracks) { - if (additionalQAeventPlots) - histos.fill(HIST("QAevent/hEvtCounterSameE"), 1.0); + + histos.fill(HIST("QAevent/hEvtCounterSameE"), 1.0); fillHistograms(resoCollision, resoTracks, cascTracks); } @@ -1106,12 +1117,35 @@ struct Xi1530Analysisqa { void processDataMicro(aod::ResoCollision const& resoCollision, aod::ResoMicroTracks const& resomicrotracks, aod::ResoCascades const& cascTracks) { - if (additionalQAeventPlots) - histos.fill(HIST("QAevent/hEvtCounterSameE"), 1.0); + + histos.fill(HIST("QAevent/hEvtCounterSameE"), 1.0); fillHistograms(resoCollision, resomicrotracks, cascTracks); } using BinningTypeVtxZT0M = ColumnBinningPolicy; + Preslice perRColdf = aod::resodaughter::resoCollisionDFId; + Preslice perRColdfCasc = aod::resodaughter::resoCollisionDFId; + + void processMEDF(aod::ResoCollisionDFs const& resoCollisions, aod::ResoTrackDFs const& resotracks, aod::ResoCascadeDFs const& cascTracks) + { + + auto tracksTuple = std::make_tuple(resotracks, cascTracks); + + BinningTypeVtxZT0M colBinning{{cfgVtxBins, cfgMultBins}, true}; + Pair pairs{colBinning, nEvtMixing, -1, resoCollisions, tracksTuple, &cache}; + + for (const auto& [collision1, tracks1, collision2, tracks2] : pairs) { + + histos.fill(HIST("QAevent/hEvtCounterMixedE"), 1.0); + fillHistograms(collision1, tracks1, tracks2); + } + } + void processDataDF(aod::ResoCollisionDF const& resoCollision, aod::ResoTrackDFs const& resotracks, aod::ResoCascadeDFs const& cascTracks) + { + + fillHistograms(resoCollision, resotracks, cascTracks); + } + void processMEMicro(aod::ResoCollisions const& resoCollisions, aod::ResoMicroTracks const& resomicrotracks, aod::ResoCascades const& cascTracks) { auto tracksTuple = std::make_tuple(resomicrotracks, cascTracks); @@ -1120,8 +1154,8 @@ struct Xi1530Analysisqa { Pair pairs{colBinning, nEvtMixing, -1, resoCollisions, tracksTuple, &cache}; for (const auto& [collision1, tracks1, collision2, tracks2] : pairs) { - if (additionalQAeventPlots) - histos.fill(HIST("QAevent/hEvtCounterMixedE"), 1.0); + + histos.fill(HIST("QAevent/hEvtCounterMixedE"), 1.0); fillHistograms(collision1, tracks1, tracks2); } } @@ -1129,8 +1163,10 @@ struct Xi1530Analysisqa { PROCESS_SWITCH(Xi1530Analysisqa, processData, "Process Event for Data", false); PROCESS_SWITCH(Xi1530Analysisqa, processMC, "Process Event for MC (Reconstructed)", false); PROCESS_SWITCH(Xi1530Analysisqa, processMCTrue, "Process Event for MC (Generated)", false); - PROCESS_SWITCH(Xi1530Analysisqa, processDataMicro, "Process Event for Data (MicroTrack for first pion)", true); - PROCESS_SWITCH(Xi1530Analysisqa, processMEMicro, "Process EventMixing", true); + PROCESS_SWITCH(Xi1530Analysisqa, processDataMicro, "Process Event for Data (MicroTrack)", false); + PROCESS_SWITCH(Xi1530Analysisqa, processMEMicro, "Process EventMixing (MicroTrack) ", false); + PROCESS_SWITCH(Xi1530Analysisqa, processMEDF, "Process EventMixing (DF) ", true); + PROCESS_SWITCH(Xi1530Analysisqa, processDataDF, "Process Event for Data (DF) ", true); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGLF/Tasks/Strangeness/cascadeanalysisMC.cxx b/PWGLF/Tasks/Strangeness/cascadeanalysisMC.cxx index 896d366a1fa..b9f32b8600c 100644 --- a/PWGLF/Tasks/Strangeness/cascadeanalysisMC.cxx +++ b/PWGLF/Tasks/Strangeness/cascadeanalysisMC.cxx @@ -31,6 +31,11 @@ // david.dobrigkeit.chinellato@cern.ch // +#include +#include +#include +#include + #include "Framework/runDataProcessing.h" #include "Framework/AnalysisTask.h" #include "Framework/AnalysisDataModel.h" @@ -49,13 +54,8 @@ #include #include #include -#include #include #include -#include -#include -#include -#include "Framework/ASoAHelpers.h" using namespace o2; using namespace o2::framework; @@ -469,7 +469,7 @@ struct cascadeAnalysisMC { } PROCESS_SWITCH(cascadeAnalysisMC, processRun2VsMultiplicity, "Process Run 2 data vs multiplicity", false); - void processRun3WithPID(soa::Join::iterator const& collision, soa::Filtered const& Cascades, aod::V0sLinked const&, FullTracksExtIUWithPID const&, aod::McParticles const&) + void processRun3WithPID(soa::Join::iterator const& collision, soa::Filtered const& Cascades, FullTracksExtIUWithPID const&, aod::McParticles const&) // process function subscribing to Run 3-like analysis objects { // Run 3 event selection criteria @@ -484,7 +484,7 @@ struct cascadeAnalysisMC { } PROCESS_SWITCH(cascadeAnalysisMC, processRun3WithPID, "Process Run 3 data with PID", false); - void processRun2WithPID(soa::Join::iterator const& collision, soa::Filtered const& Cascades, aod::V0sLinked const&, FullTracksExtWithPID const&, aod::McParticles const&) + void processRun2WithPID(soa::Join::iterator const& collision, soa::Filtered const& Cascades, FullTracksExtWithPID const&, aod::McParticles const&) // process function subscribing to Run 3-like analysis objects { // Run 2 event selection criteria diff --git a/PWGLF/Tasks/Strangeness/cascadecorrelations.cxx b/PWGLF/Tasks/Strangeness/cascadecorrelations.cxx index ebeed8a76a0..7c988dbb4ca 100644 --- a/PWGLF/Tasks/Strangeness/cascadecorrelations.cxx +++ b/PWGLF/Tasks/Strangeness/cascadecorrelations.cxx @@ -104,6 +104,7 @@ struct CascadeSelector { Configurable minTPCCrossedRows{"minTPCCrossedRows", 80, "min N TPC crossed rows"}; // TODO: finetune! 80 > 159/2, so no split tracks? Configurable minITSClusters{"minITSClusters", 4, "minimum number of ITS clusters"}; Configurable etaTracks{"etaTracks", 1.0, "min/max of eta for tracks"}; + Configurable etaCascades{"etaCascades", 0.8, "min/max of eta for cascades"}; // Selection criteria - compatible with core wagon autodetect - copied from cascadeanalysis.cxx //*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+* @@ -181,8 +182,9 @@ struct CascadeSelector { h->GetXaxis()->SetBinLabel(3, "nITS OK"); h->GetXaxis()->SetBinLabel(4, "Topo OK"); h->GetXaxis()->SetBinLabel(5, "Track eta OK"); - h->GetXaxis()->SetBinLabel(6, "V0 PID OK"); - h->GetXaxis()->SetBinLabel(7, "Bach PID OK"); + h->GetXaxis()->SetBinLabel(6, "Cascade eta OK"); + h->GetXaxis()->SetBinLabel(7, "V0 PID OK"); + h->GetXaxis()->SetBinLabel(8, "Bach PID OK"); auto hEventSel = registry.add("hEventSel", "hEventSel", HistType::kTH1I, {{10, 0, 10, "selection criteria"}}); hEventSel->GetXaxis()->SetBinLabel(1, "All"); @@ -300,6 +302,12 @@ struct CascadeSelector { } registry.fill(HIST("hSelectionStatus"), 4); // passes track eta + if (TMath::Abs(casc.eta()) > etaCascades) { + cascflags(0); + continue; + } + registry.fill(HIST("hSelectionStatus"), 5); // passes candidate eta + // TODO: TOF (for pT > 2 GeV per track?) //// TPC PID //// @@ -327,7 +335,7 @@ struct CascadeSelector { continue; } } - registry.fill(HIST("hSelectionStatus"), 5); // passes V0 daughters PID + registry.fill(HIST("hSelectionStatus"), 6); // passes V0 daughters PID // registry.fill(HIST("hMassXi4"), casc.mXi(), casc.pt()); // Bachelor check @@ -335,7 +343,7 @@ struct CascadeSelector { if (TMath::Abs(bachTrack.tpcNSigmaKa()) < tpcNsigmaBachelor) { // consistent with both! cascflags(2); - registry.fill(HIST("hSelectionStatus"), 6); // passes bach PID + registry.fill(HIST("hSelectionStatus"), 7); // passes bach PID // registry.fill(HIST("hMassXi5"), casc.mXi(), casc.pt()); if (casc.sign() < 0) { registry.fill(HIST("hMassXiMinus"), casc.mXi(), casc.pt(), casc.yXi()); @@ -347,7 +355,7 @@ struct CascadeSelector { continue; } cascflags(1); - registry.fill(HIST("hSelectionStatus"), 6); // passes bach PID + registry.fill(HIST("hSelectionStatus"), 7); // passes bach PID // registry.fill(HIST("hMassXi5"), casc.mXi(), casc.pt()); if (casc.sign() < 0) { registry.fill(HIST("hMassXiMinus"), casc.mXi(), casc.pt(), casc.yXi()); @@ -357,7 +365,7 @@ struct CascadeSelector { continue; } else if (TMath::Abs(bachTrack.tpcNSigmaKa()) < tpcNsigmaBachelor) { cascflags(3); - registry.fill(HIST("hSelectionStatus"), 6); // passes bach PID + registry.fill(HIST("hSelectionStatus"), 7); // passes bach PID if (casc.sign() < 0) { registry.fill(HIST("hMassOmegaMinus"), casc.mOmega(), casc.pt(), casc.yOmega()); } else { @@ -427,10 +435,10 @@ struct CascadeCorrelations { mCounter.mSelectPrimaries = true; } - double getEfficiency(TH1D* h, double pT) - { // TODO: make 2D (rapidity) + double getEfficiency(TH1* h, double pT, double y = 0) + { // This function returns the value of histogram h corresponding to the x-coordinate pT - return h->GetBinContent(h->GetXaxis()->FindFixBin(pT)); + return h->GetBinContent(h->FindFixBin(pT, y)); } HistogramRegistry registry{ diff --git a/PWGLF/Tasks/Strangeness/derivedupcanalysis.cxx b/PWGLF/Tasks/Strangeness/derivedupcanalysis.cxx index af47c618d7a..3704d58ab57 100644 --- a/PWGLF/Tasks/Strangeness/derivedupcanalysis.cxx +++ b/PWGLF/Tasks/Strangeness/derivedupcanalysis.cxx @@ -17,11 +17,11 @@ #include #include #include -#include #include #include #include #include +#include #include "Framework/runDataProcessing.h" #include "Framework/AnalysisTask.h" @@ -45,6 +45,8 @@ using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; +using namespace o2::aod::rctsel; + using std::array; using DauTracks = soa::Join; @@ -56,6 +58,8 @@ using V0CandidatesMC = soa::Join; using CascadeCandidatesMC = soa::Join; +using NeutronsMC = soa::Join; + using CascMCCoresFull = soa::Join; using StraCollisonFull = soa::Join::iterator; @@ -81,18 +85,27 @@ struct Derivedupcanalysis { Configurable> generatorIds{"generatorIds", std::vector{-1}, "MC generatorIds to process"}; // Event selections - Configurable rejectITSROFBorder{"rejectITSROFBorder", true, "reject events at ITS ROF border"}; - Configurable rejectTFBorder{"rejectTFBorder", true, "reject events at TF border"}; - Configurable rejectSameBunchPileup{"rejectSameBunchPileup", true, "reject collisions in case of pileup with another collision in the same foundBC"}; - Configurable requireIsTriggerTVX{"requireIsTriggerTVX", false, "require coincidence in FT0A and FT0C"}; - Configurable requireIsVertexITSTPC{"requireIsVertexITSTPC", false, "require events with at least one ITS-TPC track"}; - Configurable requireIsGoodZvtxFT0VsPV{"requireIsGoodZvtxFT0VsPV", false, "require events with PV position along z consistent (within 1 cm) between PV reconstructed using tracks and PV using FT0 A-C time difference"}; - Configurable requireIsVertexTOFmatched{"requireIsVertexTOFmatched", false, "require events with at least one of vertex contributors matched to TOF"}; - Configurable requireIsVertexTRDmatched{"requireIsVertexTRDmatched", false, "require events with at least one of vertex contributors matched to TRD"}; - Configurable requireNoCollInTimeRangeStd{"requireNoCollInTimeRangeStd", false, "reject collisions corrupted by the cannibalism, with other collisions within +/- 10 microseconds"}; - Configurable requireNoCollInTimeRangeNarrow{"requireNoCollInTimeRangeNarrow", true, "reject collisions corrupted by the cannibalism, with other collisions within +/- 10 microseconds"}; - Configurable studyUPConly{"studyUPConly", true, "is UPC-only analysis"}; - Configurable useUPCflag{"useUPCflag", false, "select UPC flagged events"}; + struct : ConfigurableGroup { + Configurable rejectITSROFBorder{"rejectITSROFBorder", true, "reject events at ITS ROF border"}; + Configurable rejectTFBorder{"rejectTFBorder", true, "reject events at TF border"}; + Configurable rejectSameBunchPileup{"rejectSameBunchPileup", true, "reject collisions in case of pileup with another collision in the same foundBC"}; + Configurable requireIsTriggerTVX{"requireIsTriggerTVX", false, "require coincidence in FT0A and FT0C"}; + Configurable requireIsVertexITSTPC{"requireIsVertexITSTPC", false, "require events with at least one ITS-TPC track"}; + Configurable requireIsGoodZvtxFT0VsPV{"requireIsGoodZvtxFT0VsPV", false, "require events with PV position along z consistent (within 1 cm) between PV reconstructed using tracks and PV using FT0 A-C time difference"}; + Configurable requireIsVertexTOFmatched{"requireIsVertexTOFmatched", false, "require events with at least one of vertex contributors matched to TOF"}; + Configurable requireIsVertexTRDmatched{"requireIsVertexTRDmatched", false, "require events with at least one of vertex contributors matched to TRD"}; + Configurable requireNoCollInTimeRangeStd{"requireNoCollInTimeRangeStd", false, "reject collisions corrupted by the cannibalism, with other collisions within +/- 10 microseconds"}; + Configurable requireNoCollInTimeRangeNarrow{"requireNoCollInTimeRangeNarrow", true, "reject collisions corrupted by the cannibalism, with other collisions within +/- 10 microseconds"}; + Configurable studyUPConly{"studyUPConly", true, "is UPC-only analysis"}; + Configurable useUPCflag{"useUPCflag", false, "select UPC flagged events"}; + + Configurable requireRCTFlagChecker{"requireRCTFlagChecker", true, "Check event quality in run condition table"}; + Configurable cfgEvtRCTFlagCheckerLabel{"cfgEvtRCTFlagCheckerLabel", "CBT_hadronPID", "Evt sel: RCT flag checker label"}; + Configurable cfgEvtRCTFlagCheckerZDCCheck{"cfgEvtRCTFlagCheckerZDCCheck", true, "Evt sel: RCT flag checker ZDC check"}; + Configurable cfgEvtRCTFlagCheckerLimitAcceptAsBad{"cfgEvtRCTFlagCheckerLimitAcceptAsBad", false, "Evt sel: RCT flag checker treat Limited Acceptance As Bad"}; + } evSels; + + RCTFlagsChecker rctChecker; Configurable verbose{"verbose", false, "additional printouts"}; @@ -115,8 +128,8 @@ struct Derivedupcanalysis { Configurable armPodCut{"armPodCut", 5.0f, "pT * (cut) > |alpha|, AP cut. Negative: no cut"}; Configurable v0TypeSelection{"v0TypeSelection", 1, "select on a certain V0 type (leave negative if no selection desired)"}; } v0cuts; - static constexpr float kLifetimeCutsV0[1][2] = {{30., 20.}}; - Configurable> lifetimecutV0{"lifetimecutV0", {kLifetimeCutsV0[0], 2, {"lifetimecutLambda", "lifetimecutK0S"}}, "lifetimecutV0"}; + static constexpr float kNCtauCutsV0[1][2] = {{6, 6.}}; + Configurable> nCtauCutV0{"nCtauCutV0", {kNCtauCutsV0[0], 2, {"lifetimecutLambda", "lifetimecutK0S"}}, "nCtauCutV0"}; // Standard cascade topological criteria struct : ConfigurableGroup { @@ -185,6 +198,7 @@ struct Derivedupcanalysis { struct : ConfigurableGroup { ConfigurableAxis axisFT0Aampl{"axisFT0Aampl", {100, 0.0f, 2000.0f}, "FT0Aamplitude"}; ConfigurableAxis axisFT0Campl{"axisFT0Campl", {100, 0.0f, 2000.0f}, "FT0Camplitude"}; + ConfigurableAxis axisFT0ampl{"axisFT0ampl", {2002, -1.5f, 2000.5f}, "axisFT0ampl"}; ConfigurableAxis axisFV0Aampl{"axisFV0Aampl", {100, 0.0f, 2000.0f}, "FV0Aamplitude"}; ConfigurableAxis axisFDDAampl{"axisFDDAampl", {100, 0.0f, 2000.0f}, "FDDAamplitude"}; ConfigurableAxis axisFDDCampl{"axisFDDCampl", {100, 0.0f, 2000.0f}, "FDDCamplitude"}; @@ -197,8 +211,10 @@ struct Derivedupcanalysis { Configurable doTreatPiToMuon{"doTreatPiToMuon", false, "Take pi decay into muon into account in MC"}; Configurable calculateFeeddownMatrix{"calculateFeeddownMatrix", true, "fill feeddown matrix if MC"}; ConfigurableAxis axisGeneratorIds{"axisGeneratorIds", {256, -0.5f, 255.5f}, "axis for generatorIds"}; + Configurable checkNeutronsInMC{"checkNeutronsInMC", true, "require no neutrons for single-gap in MC"}; + Configurable neutronEtaCut{"neutronEtaCut", 8.8, "ZN acceptance"}; - // fast check on occupancy + // Occupancy cut Configurable minOccupancy{"minOccupancy", -1, "minimum occupancy from neighbouring collisions"}; Configurable maxOccupancy{"maxOccupancy", 1000, "maximum occupancy from neighbouring collisions"}; @@ -262,13 +278,14 @@ struct Derivedupcanalysis { // Topological variable QA axes ConfigurableAxis axisDCAtoPV{"axisDCAtoPV", {80, -4.0f, 4.0f}, "DCA (cm)"}; - ConfigurableAxis axisDCAdau{"axisDCAdau", {24, 0.0f, 1.2f}, "DCA (cm)"}; + ConfigurableAxis axisDCAdau{"axisDCAdau", {48, 0.0f, 1.2f}, "DCA (cm)"}; ConfigurableAxis axisPointingAngle{"axisPointingAngle", {100, 0.0f, 0.5f}, "pointing angle (rad)"}; - ConfigurableAxis axisV0Radius{"axisV0Radius", {60, 0.0f, 60.0f}, "V0 2D radius (cm)"}; + ConfigurableAxis axisCosPA{"axisCosPA", {300, 0.97f, 1.0f}, "cosPA"}; + ConfigurableAxis axisV0Radius{"axisV0Radius", {100, 0.0f, 10.0f}, "V0 2D radius (cm)"}; ConfigurableAxis axisNsigmaTPC{"axisNsigmaTPC", {200, -10.0f, 10.0f}, "N sigma TPC"}; ConfigurableAxis axisTPCsignal{"axisTPCsignal", {200, 0.0f, 200.0f}, "TPC signal"}; ConfigurableAxis axisTOFdeltaT{"axisTOFdeltaT", {200, -5000.0f, 5000.0f}, "TOF Delta T (ps)"}; - ConfigurableAxis axisNctau{"axisNctau", {100, 0.0f, 10.0f}, "n c x tau"}; + ConfigurableAxis axisCtau{"axisCtau", {200, 0.0f, 20.0f}, "c x tau (cm)"}; static constexpr std::string_view kParticlenames[] = {"K0Short", "Lambda", "AntiLambda", "Xi", "AntiXi", "Omega", "AntiOmega"}; @@ -295,7 +312,7 @@ struct Derivedupcanalysis { histos.add(Form("%s/hDCAV0Daughters", kParticlenames[partID].data()), "hDCAV0Daughters", kTH2F, {axisPtCoarse, axisDCAdau}); histos.add(Form("%s/hDCAV0ToPV", kParticlenames[partID].data()), "hDCAV0ToPV", kTH2F, {axisPtCoarse, {44, 0.0f, 2.2f}}); histos.add(Form("%s/hMassLambdaDau", kParticlenames[partID].data()), "hMassLambdaDau", kTH2F, {axisPtCoarse, axisLambdaMass}); - histos.add(Form("%s/hNctau", kParticlenames[partID].data()), "hNctau", kTH2F, {axisPtCoarse, axisNctau}); + histos.add(Form("%s/hCtau", kParticlenames[partID].data()), "hCtau", kTH2F, {axisPtCoarse, axisCtau}); if (doBachelorBaryonCut) { histos.add(Form("%s/hBachBaryonCosPA", kParticlenames[partID].data()), "hBachBaryonCosPA", kTH2F, {axisPtCoarse, {100, 0.0f, 1.0f}}); histos.add(Form("%s/hBachBaryonDCAxyToPV", kParticlenames[partID].data()), "hBachBaryonDCAxyToPV", kTH2F, {axisPtCoarse, {300, -3.0f, 3.0f}}); @@ -305,9 +322,11 @@ struct Derivedupcanalysis { histos.add(Form("%s/hNegDCAToPV", kParticlenames[partID].data()), "hNegDCAToPV", kTH1F, {axisDCAtoPV}); histos.add(Form("%s/hDCADaughters", kParticlenames[partID].data()), "hDCADaughters", kTH1F, {axisDCAdau}); histos.add(Form("%s/hPointingAngle", kParticlenames[partID].data()), "hPointingAngle", kTH1F, {axisPointingAngle}); + histos.add(Form("%s/hCosPA", kParticlenames[partID].data()), "hCosPA", kTH1F, {axisCosPA}); histos.add(Form("%s/hV0Radius", kParticlenames[partID].data()), "hV0Radius", kTH1F, {axisV0Radius}); histos.add(Form("%s/h2dPositiveITSvsTPCpts", kParticlenames[partID].data()), "h2dPositiveITSvsTPCpts", kTH2F, {axisTPCrows, axisITSclus}); histos.add(Form("%s/h2dNegativeITSvsTPCpts", kParticlenames[partID].data()), "h2dNegativeITSvsTPCpts", kTH2F, {axisTPCrows, axisITSclus}); + histos.add(Form("%s/hCtau", kParticlenames[partID].data()), "hCtau", kTH2F, {axisPtCoarse, axisCtau}); } } @@ -315,30 +334,30 @@ struct Derivedupcanalysis { void addTPCQAHistograms(HistogramRegistry& histos) { const bool isCascade = (partID > 2.5) ? true : false; - histos.add(Form("%s/h3dPosNsigmaTPC", kParticlenames[partID].data()), "h3dPosNsigmaTPC", kTH3F, {axisFT0C, axisPtCoarse, axisNsigmaTPC}); - histos.add(Form("%s/h3dNegNsigmaTPC", kParticlenames[partID].data()), "h3dNegNsigmaTPC", kTH3F, {axisFT0C, axisPtCoarse, axisNsigmaTPC}); - histos.add(Form("%s/h3dPosTPCsignal", kParticlenames[partID].data()), "h3dPosTPCsignal", kTH3F, {axisFT0C, axisPtCoarse, axisTPCsignal}); - histos.add(Form("%s/h3dNegTPCsignal", kParticlenames[partID].data()), "h3dNegTPCsignal", kTH3F, {axisFT0C, axisPtCoarse, axisTPCsignal}); + histos.add(Form("%s/h3dPosNsigmaTPC", kParticlenames[partID].data()), "h3dPosNsigmaTPC", kTH3F, {axisDetectors.axisFT0ampl, axisPtCoarse, axisNsigmaTPC}); + histos.add(Form("%s/h3dNegNsigmaTPC", kParticlenames[partID].data()), "h3dNegNsigmaTPC", kTH3F, {axisDetectors.axisFT0ampl, axisPtCoarse, axisNsigmaTPC}); + histos.add(Form("%s/h3dPosTPCsignal", kParticlenames[partID].data()), "h3dPosTPCsignal", kTH3F, {axisDetectors.axisFT0ampl, axisPtCoarse, axisTPCsignal}); + histos.add(Form("%s/h3dNegTPCsignal", kParticlenames[partID].data()), "h3dNegTPCsignal", kTH3F, {axisDetectors.axisFT0ampl, axisPtCoarse, axisTPCsignal}); - histos.add(Form("%s/h3dPosNsigmaTPCvsTrackPtot", kParticlenames[partID].data()), "h3dPosNsigmaTPCvsTrackPtot", kTH3F, {axisFT0C, axisPtCoarse, axisNsigmaTPC}); - histos.add(Form("%s/h3dNegNsigmaTPCvsTrackPtot", kParticlenames[partID].data()), "h3dNegNsigmaTPCvsTrackPtot", kTH3F, {axisFT0C, axisPtCoarse, axisNsigmaTPC}); + histos.add(Form("%s/h3dPosNsigmaTPCvsTrackPtot", kParticlenames[partID].data()), "h3dPosNsigmaTPCvsTrackPtot", kTH3F, {axisDetectors.axisFT0ampl, axisPtCoarse, axisNsigmaTPC}); + histos.add(Form("%s/h3dNegNsigmaTPCvsTrackPtot", kParticlenames[partID].data()), "h3dNegNsigmaTPCvsTrackPtot", kTH3F, {axisDetectors.axisFT0ampl, axisPtCoarse, axisNsigmaTPC}); - histos.add(Form("%s/h3dPosTPCsignalVsTrackPtot", kParticlenames[partID].data()), "h3dPosTPCsignalVsTrackPtot", kTH3F, {axisFT0C, axisPtCoarse, axisTPCsignal}); - histos.add(Form("%s/h3dNegTPCsignalVsTrackPtot", kParticlenames[partID].data()), "h3dNegTPCsignalVsTrackPtot", kTH3F, {axisFT0C, axisPtCoarse, axisTPCsignal}); + histos.add(Form("%s/h3dPosTPCsignalVsTrackPtot", kParticlenames[partID].data()), "h3dPosTPCsignalVsTrackPtot", kTH3F, {axisDetectors.axisFT0ampl, axisPtCoarse, axisTPCsignal}); + histos.add(Form("%s/h3dNegTPCsignalVsTrackPtot", kParticlenames[partID].data()), "h3dNegTPCsignalVsTrackPtot", kTH3F, {axisDetectors.axisFT0ampl, axisPtCoarse, axisTPCsignal}); - histos.add(Form("%s/h3dPosNsigmaTPCvsTrackPt", kParticlenames[partID].data()), "h3dPosNsigmaTPCvsTrackPt", kTH3F, {axisFT0C, axisPtCoarse, axisNsigmaTPC}); - histos.add(Form("%s/h3dNegNsigmaTPCvsTrackPt", kParticlenames[partID].data()), "h3dNegNsigmaTPCvsTrackPt", kTH3F, {axisFT0C, axisPtCoarse, axisNsigmaTPC}); + histos.add(Form("%s/h3dPosNsigmaTPCvsTrackPt", kParticlenames[partID].data()), "h3dPosNsigmaTPCvsTrackPt", kTH3F, {axisDetectors.axisFT0ampl, axisPtCoarse, axisNsigmaTPC}); + histos.add(Form("%s/h3dNegNsigmaTPCvsTrackPt", kParticlenames[partID].data()), "h3dNegNsigmaTPCvsTrackPt", kTH3F, {axisDetectors.axisFT0ampl, axisPtCoarse, axisNsigmaTPC}); - histos.add(Form("%s/h3dPosTPCsignalVsTrackPt", kParticlenames[partID].data()), "h3dPosTPCsignalVsTrackPt", kTH3F, {axisFT0C, axisPtCoarse, axisTPCsignal}); - histos.add(Form("%s/h3dNegTPCsignalVsTrackPt", kParticlenames[partID].data()), "h3dNegTPCsignalVsTrackPt", kTH3F, {axisFT0C, axisPtCoarse, axisTPCsignal}); + histos.add(Form("%s/h3dPosTPCsignalVsTrackPt", kParticlenames[partID].data()), "h3dPosTPCsignalVsTrackPt", kTH3F, {axisDetectors.axisFT0ampl, axisPtCoarse, axisTPCsignal}); + histos.add(Form("%s/h3dNegTPCsignalVsTrackPt", kParticlenames[partID].data()), "h3dNegTPCsignalVsTrackPt", kTH3F, {axisDetectors.axisFT0ampl, axisPtCoarse, axisTPCsignal}); if (isCascade) { - histos.add(Form("%s/h3dBachTPCsignal", kParticlenames[partID].data()), "h3dBachTPCsignal", kTH3F, {axisFT0C, axisPtCoarse, axisTPCsignal}); - histos.add(Form("%s/h3dBachNsigmaTPC", kParticlenames[partID].data()), "h3dBachNsigmaTPC", kTH3F, {axisFT0C, axisPtCoarse, axisNsigmaTPC}); - histos.add(Form("%s/h3dBachNsigmaTPCvsTrackPtot", kParticlenames[partID].data()), "h3dBachNsigmaTPCvsTrackPtot", kTH3F, {axisFT0C, axisPtCoarse, axisNsigmaTPC}); - histos.add(Form("%s/h3dBachTPCsignalVsTrackPtot", kParticlenames[partID].data()), "h3dBachTPCsignalVsTrackPtot", kTH3F, {axisFT0C, axisPtCoarse, axisTPCsignal}); - histos.add(Form("%s/h3dBachNsigmaTPCvsTrackPt", kParticlenames[partID].data()), "h3dBachNsigmaTPCvsTrackPt", kTH3F, {axisFT0C, axisPtCoarse, axisNsigmaTPC}); - histos.add(Form("%s/h3dBachTPCsignalVsTrackPt", kParticlenames[partID].data()), "h3dBachTPCsignalVsTrackPt", kTH3F, {axisFT0C, axisPtCoarse, axisTPCsignal}); + histos.add(Form("%s/h3dBachTPCsignal", kParticlenames[partID].data()), "h3dBachTPCsignal", kTH3F, {axisDetectors.axisFT0ampl, axisPtCoarse, axisTPCsignal}); + histos.add(Form("%s/h3dBachNsigmaTPC", kParticlenames[partID].data()), "h3dBachNsigmaTPC", kTH3F, {axisDetectors.axisFT0ampl, axisPtCoarse, axisNsigmaTPC}); + histos.add(Form("%s/h3dBachNsigmaTPCvsTrackPtot", kParticlenames[partID].data()), "h3dBachNsigmaTPCvsTrackPtot", kTH3F, {axisDetectors.axisFT0ampl, axisPtCoarse, axisNsigmaTPC}); + histos.add(Form("%s/h3dBachTPCsignalVsTrackPtot", kParticlenames[partID].data()), "h3dBachTPCsignalVsTrackPtot", kTH3F, {axisDetectors.axisFT0ampl, axisPtCoarse, axisTPCsignal}); + histos.add(Form("%s/h3dBachNsigmaTPCvsTrackPt", kParticlenames[partID].data()), "h3dBachNsigmaTPCvsTrackPt", kTH3F, {axisDetectors.axisFT0ampl, axisPtCoarse, axisNsigmaTPC}); + histos.add(Form("%s/h3dBachTPCsignalVsTrackPt", kParticlenames[partID].data()), "h3dBachTPCsignalVsTrackPt", kTH3F, {axisDetectors.axisFT0ampl, axisPtCoarse, axisTPCsignal}); } } @@ -346,16 +365,16 @@ struct Derivedupcanalysis { void addTOFQAHistograms(HistogramRegistry& histos) { const bool isCascade = (partID > 2.5) ? true : false; - histos.add(Form("%s/h3dPosTOFdeltaT", kParticlenames[partID].data()), "h3dPosTOFdeltaT", kTH3F, {axisFT0C, axisPtCoarse, axisTOFdeltaT}); - histos.add(Form("%s/h3dNegTOFdeltaT", kParticlenames[partID].data()), "h3dNegTOFdeltaT", kTH3F, {axisFT0C, axisPtCoarse, axisTOFdeltaT}); - histos.add(Form("%s/h3dPosTOFdeltaTvsTrackPtot", kParticlenames[partID].data()), "h3dPosTOFdeltaTvsTrackPtot", kTH3F, {axisFT0C, axisPtCoarse, axisTOFdeltaT}); - histos.add(Form("%s/h3dNegTOFdeltaTvsTrackPtot", kParticlenames[partID].data()), "h3dNegTOFdeltaTvsTrackPtot", kTH3F, {axisFT0C, axisPtCoarse, axisTOFdeltaT}); - histos.add(Form("%s/h3dPosTOFdeltaTvsTrackPt", kParticlenames[partID].data()), "h3dPosTOFdeltaTvsTrackPt", kTH3F, {axisFT0C, axisPtCoarse, axisTOFdeltaT}); - histos.add(Form("%s/h3dNegTOFdeltaTvsTrackPt", kParticlenames[partID].data()), "h3dNegTOFdeltaTvsTrackPt", kTH3F, {axisFT0C, axisPtCoarse, axisTOFdeltaT}); + histos.add(Form("%s/h3dPosTOFdeltaT", kParticlenames[partID].data()), "h3dPosTOFdeltaT", kTH3F, {axisDetectors.axisFT0ampl, axisPtCoarse, axisTOFdeltaT}); + histos.add(Form("%s/h3dNegTOFdeltaT", kParticlenames[partID].data()), "h3dNegTOFdeltaT", kTH3F, {axisDetectors.axisFT0ampl, axisPtCoarse, axisTOFdeltaT}); + histos.add(Form("%s/h3dPosTOFdeltaTvsTrackPtot", kParticlenames[partID].data()), "h3dPosTOFdeltaTvsTrackPtot", kTH3F, {axisDetectors.axisFT0ampl, axisPtCoarse, axisTOFdeltaT}); + histos.add(Form("%s/h3dNegTOFdeltaTvsTrackPtot", kParticlenames[partID].data()), "h3dNegTOFdeltaTvsTrackPtot", kTH3F, {axisDetectors.axisFT0ampl, axisPtCoarse, axisTOFdeltaT}); + histos.add(Form("%s/h3dPosTOFdeltaTvsTrackPt", kParticlenames[partID].data()), "h3dPosTOFdeltaTvsTrackPt", kTH3F, {axisDetectors.axisFT0ampl, axisPtCoarse, axisTOFdeltaT}); + histos.add(Form("%s/h3dNegTOFdeltaTvsTrackPt", kParticlenames[partID].data()), "h3dNegTOFdeltaTvsTrackPt", kTH3F, {axisDetectors.axisFT0ampl, axisPtCoarse, axisTOFdeltaT}); if (isCascade) { - histos.add(Form("%s/h3dBachTOFdeltaT", kParticlenames[partID].data()), "h3dBachTOFdeltaT", kTH3F, {axisFT0C, axisPtCoarse, axisTOFdeltaT}); - histos.add(Form("%s/h3dBachTOFdeltaTvsTrackPtot", kParticlenames[partID].data()), "h3dBachTOFdeltaTvsTrackPtot", kTH3F, {axisFT0C, axisPtCoarse, axisTOFdeltaT}); - histos.add(Form("%s/h3dBachTOFdeltaTvsTrackPt", kParticlenames[partID].data()), "h3dBachTOFdeltaTvsTrackPt", kTH3F, {axisFT0C, axisPtCoarse, axisTOFdeltaT}); + histos.add(Form("%s/h3dBachTOFdeltaT", kParticlenames[partID].data()), "h3dBachTOFdeltaT", kTH3F, {axisDetectors.axisFT0ampl, axisPtCoarse, axisTOFdeltaT}); + histos.add(Form("%s/h3dBachTOFdeltaTvsTrackPtot", kParticlenames[partID].data()), "h3dBachTOFdeltaTvsTrackPtot", kTH3F, {axisDetectors.axisFT0ampl, axisPtCoarse, axisTOFdeltaT}); + histos.add(Form("%s/h3dBachTOFdeltaTvsTrackPt", kParticlenames[partID].data()), "h3dBachTOFdeltaTvsTrackPt", kTH3F, {axisDetectors.axisFT0ampl, axisPtCoarse, axisTOFdeltaT}); } } @@ -377,30 +396,30 @@ struct Derivedupcanalysis { const bool isCascade = (partID > 2.5) ? true : false; if (doDetectPropQA == 1) { if (isCascade) { - histos.add(Form("%s/h8dDetectPropVsCentrality", kParticlenames[partID].data()), "h8dDetectPropVsCentrality", kTHnSparseF, {axisFT0C, axisDetMapCoarse, axisITScluMapCoarse, axisDetMapCoarse, axisITScluMapCoarse, axisDetMapCoarse, axisITScluMapCoarse, axisPtCoarse}); + histos.add(Form("%s/h8dDetectPropVsCentrality", kParticlenames[partID].data()), "h8dDetectPropVsCentrality", kTHnSparseF, {axisDetectors.axisFT0ampl, axisDetMapCoarse, axisITScluMapCoarse, axisDetMapCoarse, axisITScluMapCoarse, axisDetMapCoarse, axisITScluMapCoarse, axisPtCoarse}); } else { - histos.add(Form("%s/h6dDetectPropVsCentrality", kParticlenames[partID].data()), "h6dDetectPropVsCentrality", kTHnSparseF, {axisFT0C, axisDetMapCoarse, axisITScluMapCoarse, axisDetMapCoarse, axisITScluMapCoarse, axisPtCoarse}); + histos.add(Form("%s/h6dDetectPropVsCentrality", kParticlenames[partID].data()), "h6dDetectPropVsCentrality", kTHnSparseF, {axisDetectors.axisFT0ampl, axisDetMapCoarse, axisITScluMapCoarse, axisDetMapCoarse, axisITScluMapCoarse, axisPtCoarse}); } - histos.add(Form("%s/h4dPosDetectPropVsCentrality", kParticlenames[partID].data()), "h4dPosDetectPropVsCentrality", kTHnSparseF, {axisFT0C, axisDetMap, axisITScluMap, axisPtCoarse}); - histos.add(Form("%s/h4dNegDetectPropVsCentrality", kParticlenames[partID].data()), "h4dNegDetectPropVsCentrality", kTHnSparseF, {axisFT0C, axisDetMap, axisITScluMap, axisPtCoarse}); - histos.add(Form("%s/h4dBachDetectPropVsCentrality", kParticlenames[partID].data()), "h4dBachDetectPropVsCentrality", kTHnSparseF, {axisFT0C, axisDetMap, axisITScluMap, axisPtCoarse}); + histos.add(Form("%s/h4dPosDetectPropVsCentrality", kParticlenames[partID].data()), "h4dPosDetectPropVsCentrality", kTHnSparseF, {axisDetectors.axisFT0ampl, axisDetMap, axisITScluMap, axisPtCoarse}); + histos.add(Form("%s/h4dNegDetectPropVsCentrality", kParticlenames[partID].data()), "h4dNegDetectPropVsCentrality", kTHnSparseF, {axisDetectors.axisFT0ampl, axisDetMap, axisITScluMap, axisPtCoarse}); + histos.add(Form("%s/h4dBachDetectPropVsCentrality", kParticlenames[partID].data()), "h4dBachDetectPropVsCentrality", kTHnSparseF, {axisDetectors.axisFT0ampl, axisDetMap, axisITScluMap, axisPtCoarse}); } if (doDetectPropQA == 2) { if (isCascade) { - histos.add(Form("%s/h9dDetectPropVsCentrality", kParticlenames[partID].data()), "h9dDetectPropVsCentrality", kTHnSparseF, {axisFT0C, axisDetMapCoarse, axisITScluMapCoarse, axisDetMapCoarse, axisITScluMapCoarse, axisDetMapCoarse, axisITScluMapCoarse, axisPtCoarse, axisInvMass.at(partID)}); + histos.add(Form("%s/h9dDetectPropVsCentrality", kParticlenames[partID].data()), "h9dDetectPropVsCentrality", kTHnSparseF, {axisDetectors.axisFT0ampl, axisDetMapCoarse, axisITScluMapCoarse, axisDetMapCoarse, axisITScluMapCoarse, axisDetMapCoarse, axisITScluMapCoarse, axisPtCoarse, axisInvMass.at(partID)}); } else { - histos.add(Form("%s/h7dDetectPropVsCentrality", kParticlenames[partID].data()), "h7dDetectPropVsCentrality", kTHnSparseF, {axisFT0C, axisDetMapCoarse, axisITScluMapCoarse, axisDetMapCoarse, axisITScluMapCoarse, axisPtCoarse, axisInvMass.at(partID)}); + histos.add(Form("%s/h7dDetectPropVsCentrality", kParticlenames[partID].data()), "h7dDetectPropVsCentrality", kTHnSparseF, {axisDetectors.axisFT0ampl, axisDetMapCoarse, axisITScluMapCoarse, axisDetMapCoarse, axisITScluMapCoarse, axisPtCoarse, axisInvMass.at(partID)}); } - histos.add(Form("%s/h5dPosDetectPropVsCentrality", kParticlenames[partID].data()), "h5dPosDetectPropVsCentrality", kTHnSparseF, {axisFT0C, axisDetMap, axisITScluMap, axisPtCoarse, axisInvMass.at(partID)}); - histos.add(Form("%s/h5dNegDetectPropVsCentrality", kParticlenames[partID].data()), "h5dNegDetectPropVsCentrality", kTHnSparseF, {axisFT0C, axisDetMap, axisITScluMap, axisPtCoarse, axisInvMass.at(partID)}); - histos.add(Form("%s/h5dBachDetectPropVsCentrality", kParticlenames[partID].data()), "h5dBachDetectPropVsCentrality", kTHnSparseF, {axisFT0C, axisDetMap, axisITScluMap, axisPtCoarse, axisInvMass.at(partID)}); + histos.add(Form("%s/h5dPosDetectPropVsCentrality", kParticlenames[partID].data()), "h5dPosDetectPropVsCentrality", kTHnSparseF, {axisDetectors.axisFT0ampl, axisDetMap, axisITScluMap, axisPtCoarse, axisInvMass.at(partID)}); + histos.add(Form("%s/h5dNegDetectPropVsCentrality", kParticlenames[partID].data()), "h5dNegDetectPropVsCentrality", kTHnSparseF, {axisDetectors.axisFT0ampl, axisDetMap, axisITScluMap, axisPtCoarse, axisInvMass.at(partID)}); + histos.add(Form("%s/h5dBachDetectPropVsCentrality", kParticlenames[partID].data()), "h5dBachDetectPropVsCentrality", kTHnSparseF, {axisDetectors.axisFT0ampl, axisDetMap, axisITScluMap, axisPtCoarse, axisInvMass.at(partID)}); } } template void addHistograms(HistogramRegistry& histos) { - histos.add(Form("%s/h7dMass", kParticlenames[partID].data()), "h7dMass", kTHnSparseF, {axisFT0C, axisPt, axisInvMass.at(partID), axisSelGap, axisNchInvMass, axisRap, axisEta}); + histos.add(Form("%s/h7dMass", kParticlenames[partID].data()), "h7dMass", kTHnSparseF, {axisDetectors.axisFT0ampl, axisPt, axisInvMass.at(partID), axisSelGap, axisNchInvMass, axisRap, axisEta}); histos.add(Form("%s/h2dMass", kParticlenames[partID].data()), "h2dMass", kTH2F, {axisInvMass.at(partID), axisSelGap}); if (doPlainTopoQA) { addTopoHistograms(histos); @@ -421,10 +440,18 @@ struct Derivedupcanalysis { void fillHistogramsV0(TCand cand, TCollision coll, int gap) { float invMass = 0; - float centrality = coll.centFT0C(); + float ft0ampl = -1.f; + if (gap == 0) { + ft0ampl = coll.totalFT0AmplitudeC(); + } else if (gap == 1) { + ft0ampl = coll.totalFT0AmplitudeA(); + } float pT = cand.pt(); float rapidity = 1e6; + // c x tau + float ctau = 0; + float tpcNsigmaPos = 0; float tpcNsigmaNeg = 0; float tofDeltaTPos = 0; @@ -445,6 +472,7 @@ struct Derivedupcanalysis { histos.fill(HIST("generalQA/h2dArmenterosSelected"), cand.alpha(), cand.qtarm()); invMass = cand.mK0Short(); rapidity = cand.yK0Short(); + ctau = cand.distovertotmom(coll.posX(), coll.posY(), coll.posZ()) * o2::constants::physics::MassK0Short; if (PIDConfigurations.doTOFQA) { tofDeltaTPos = cand.posTOFDeltaTK0Pi(); tofDeltaTNeg = cand.negTOFDeltaTK0Pi(); @@ -456,6 +484,7 @@ struct Derivedupcanalysis { } else if (partID == 1) { invMass = cand.mLambda(); rapidity = cand.yLambda(); + ctau = cand.distovertotmom(coll.posX(), coll.posY(), coll.posZ()) * o2::constants::physics::MassLambda0; if (PIDConfigurations.doTOFQA) { tofDeltaTPos = cand.posTOFDeltaTLaPr(); tofDeltaTNeg = cand.negTOFDeltaTLaPi(); @@ -467,6 +496,7 @@ struct Derivedupcanalysis { } else if (partID == 2) { invMass = cand.mAntiLambda(); rapidity = cand.yLambda(); + ctau = cand.distovertotmom(coll.posX(), coll.posY(), coll.posZ()) * o2::constants::physics::MassLambda0Bar; if (PIDConfigurations.doTOFQA) { tofDeltaTPos = cand.posTOFDeltaTLaPi(); tofDeltaTNeg = cand.negTOFDeltaTLaPr(); @@ -480,7 +510,7 @@ struct Derivedupcanalysis { } histos.fill(HIST(kParticlenames[partID]) + HIST("/h2dMass"), invMass, gap); - histos.fill(HIST(kParticlenames[partID]) + HIST("/h7dMass"), centrality, pT, invMass, gap, coll.multNTracksGlobal(), rapidity, cand.eta()); + histos.fill(HIST(kParticlenames[partID]) + HIST("/h7dMass"), ft0ampl, pT, invMass, gap, coll.multNTracksGlobal(), rapidity, cand.eta()); if (doKienmaticQA) { histos.fill(HIST(kParticlenames[partID]) + HIST("/h3dPosEtaPt"), pT, cand.positiveeta(), gap); histos.fill(HIST(kParticlenames[partID]) + HIST("/h3dNegEtaPt"), pT, cand.negativeeta(), gap); @@ -491,49 +521,56 @@ struct Derivedupcanalysis { histos.fill(HIST(kParticlenames[partID]) + HIST("/hNegDCAToPV"), cand.dcanegtopv()); histos.fill(HIST(kParticlenames[partID]) + HIST("/hDCADaughters"), cand.dcaV0daughters()); histos.fill(HIST(kParticlenames[partID]) + HIST("/hPointingAngle"), std::acos(cand.v0cosPA())); + histos.fill(HIST(kParticlenames[partID]) + HIST("/hCosPA"), cand.v0cosPA()); histos.fill(HIST(kParticlenames[partID]) + HIST("/hV0Radius"), cand.v0radius()); histos.fill(HIST(kParticlenames[partID]) + HIST("/h2dPositiveITSvsTPCpts"), posTrackExtra.tpcCrossedRows(), posTrackExtra.itsNCls()); histos.fill(HIST(kParticlenames[partID]) + HIST("/h2dNegativeITSvsTPCpts"), negTrackExtra.tpcCrossedRows(), negTrackExtra.itsNCls()); + histos.fill(HIST(kParticlenames[partID]) + HIST("/hCtau"), pT, ctau); } if (doDetectPropQA == 1) { - histos.fill(HIST(kParticlenames[partID]) + HIST("/h6dDetectPropVsCentrality"), centrality, posDetMap, posITSclusMap, negDetMap, negITSclusMap, pT); - histos.fill(HIST(kParticlenames[partID]) + HIST("/h4dPosDetectPropVsCentrality"), centrality, posTrackExtra.detectorMap(), posTrackExtra.itsClusterMap(), pT); - histos.fill(HIST(kParticlenames[partID]) + HIST("/h4dNegDetectPropVsCentrality"), centrality, negTrackExtra.detectorMap(), negTrackExtra.itsClusterMap(), pT); + histos.fill(HIST(kParticlenames[partID]) + HIST("/h6dDetectPropVsCentrality"), ft0ampl, posDetMap, posITSclusMap, negDetMap, negITSclusMap, pT); + histos.fill(HIST(kParticlenames[partID]) + HIST("/h4dPosDetectPropVsCentrality"), ft0ampl, posTrackExtra.detectorMap(), posTrackExtra.itsClusterMap(), pT); + histos.fill(HIST(kParticlenames[partID]) + HIST("/h4dNegDetectPropVsCentrality"), ft0ampl, negTrackExtra.detectorMap(), negTrackExtra.itsClusterMap(), pT); } if (doDetectPropQA == 2) { - histos.fill(HIST(kParticlenames[partID]) + HIST("/h7dPosDetectPropVsCentrality"), centrality, posDetMap, posITSclusMap, negDetMap, negITSclusMap, pT, invMass); - histos.fill(HIST(kParticlenames[partID]) + HIST("/h5dPosDetectPropVsCentrality"), centrality, posTrackExtra.detectorMap(), posTrackExtra.itsClusterMap(), pT, invMass); - histos.fill(HIST(kParticlenames[partID]) + HIST("/h5dNegDetectPropVsCentrality"), centrality, negTrackExtra.detectorMap(), negTrackExtra.itsClusterMap(), pT, invMass); + histos.fill(HIST(kParticlenames[partID]) + HIST("/h7dPosDetectPropVsCentrality"), ft0ampl, posDetMap, posITSclusMap, negDetMap, negITSclusMap, pT, invMass); + histos.fill(HIST(kParticlenames[partID]) + HIST("/h5dPosDetectPropVsCentrality"), ft0ampl, posTrackExtra.detectorMap(), posTrackExtra.itsClusterMap(), pT, invMass); + histos.fill(HIST(kParticlenames[partID]) + HIST("/h5dNegDetectPropVsCentrality"), ft0ampl, negTrackExtra.detectorMap(), negTrackExtra.itsClusterMap(), pT, invMass); } if (PIDConfigurations.doTPCQA) { - histos.fill(HIST(kParticlenames[partID]) + HIST("/h3dPosTPCsignal"), centrality, pT, posTrackExtra.tpcSignal()); - histos.fill(HIST(kParticlenames[partID]) + HIST("/h3dNegTPCsignal"), centrality, pT, negTrackExtra.tpcSignal()); - histos.fill(HIST(kParticlenames[partID]) + HIST("/h3dPosTPCsignalVsTrackPtot"), centrality, cand.positivept() * std::cosh(cand.positiveeta()), posTrackExtra.tpcSignal()); - histos.fill(HIST(kParticlenames[partID]) + HIST("/h3dNegTPCsignalVsTrackPtot"), centrality, cand.negativept() * std::cosh(cand.negativeeta()), negTrackExtra.tpcSignal()); - histos.fill(HIST(kParticlenames[partID]) + HIST("/h3dPosTPCsignalVsTrackPt"), centrality, cand.positivept(), posTrackExtra.tpcSignal()); - histos.fill(HIST(kParticlenames[partID]) + HIST("/h3dNegTPCsignalVsTrackPt"), centrality, cand.negativept(), negTrackExtra.tpcSignal()); - histos.fill(HIST(kParticlenames[partID]) + HIST("/h3dPosNsigmaTPCvsTrackPt"), centrality, cand.positivept(), posTrackExtra.tpcNSigmaPi()); - histos.fill(HIST(kParticlenames[partID]) + HIST("/h3dNegNsigmaTPCvsTrackPt"), centrality, cand.negativept(), negTrackExtra.tpcNSigmaPi()); - histos.fill(HIST(kParticlenames[partID]) + HIST("/h3dPosNsigmaTPCvsTrackPtot"), centrality, cand.positivept() * std::cosh(cand.positiveeta()), tpcNsigmaPos); - histos.fill(HIST(kParticlenames[partID]) + HIST("/h3dNegNsigmaTPCvsTrackPtot"), centrality, cand.negativept() * std::cosh(cand.negativeeta()), tpcNsigmaNeg); - histos.fill(HIST(kParticlenames[partID]) + HIST("/h3dPosNsigmaTPC"), centrality, pT, tpcNsigmaPos); - histos.fill(HIST(kParticlenames[partID]) + HIST("/h3dNegNsigmaTPC"), centrality, pT, tpcNsigmaNeg); + histos.fill(HIST(kParticlenames[partID]) + HIST("/h3dPosTPCsignal"), ft0ampl, pT, posTrackExtra.tpcSignal()); + histos.fill(HIST(kParticlenames[partID]) + HIST("/h3dNegTPCsignal"), ft0ampl, pT, negTrackExtra.tpcSignal()); + histos.fill(HIST(kParticlenames[partID]) + HIST("/h3dPosTPCsignalVsTrackPtot"), ft0ampl, cand.positivept() * std::cosh(cand.positiveeta()), posTrackExtra.tpcSignal()); + histos.fill(HIST(kParticlenames[partID]) + HIST("/h3dNegTPCsignalVsTrackPtot"), ft0ampl, cand.negativept() * std::cosh(cand.negativeeta()), negTrackExtra.tpcSignal()); + histos.fill(HIST(kParticlenames[partID]) + HIST("/h3dPosTPCsignalVsTrackPt"), ft0ampl, cand.positivept(), posTrackExtra.tpcSignal()); + histos.fill(HIST(kParticlenames[partID]) + HIST("/h3dNegTPCsignalVsTrackPt"), ft0ampl, cand.negativept(), negTrackExtra.tpcSignal()); + histos.fill(HIST(kParticlenames[partID]) + HIST("/h3dPosNsigmaTPCvsTrackPt"), ft0ampl, cand.positivept(), posTrackExtra.tpcNSigmaPi()); + histos.fill(HIST(kParticlenames[partID]) + HIST("/h3dNegNsigmaTPCvsTrackPt"), ft0ampl, cand.negativept(), negTrackExtra.tpcNSigmaPi()); + histos.fill(HIST(kParticlenames[partID]) + HIST("/h3dPosNsigmaTPCvsTrackPtot"), ft0ampl, cand.positivept() * std::cosh(cand.positiveeta()), tpcNsigmaPos); + histos.fill(HIST(kParticlenames[partID]) + HIST("/h3dNegNsigmaTPCvsTrackPtot"), ft0ampl, cand.negativept() * std::cosh(cand.negativeeta()), tpcNsigmaNeg); + histos.fill(HIST(kParticlenames[partID]) + HIST("/h3dPosNsigmaTPC"), ft0ampl, pT, tpcNsigmaPos); + histos.fill(HIST(kParticlenames[partID]) + HIST("/h3dNegNsigmaTPC"), ft0ampl, pT, tpcNsigmaNeg); } if (PIDConfigurations.doTOFQA) { - histos.fill(HIST(kParticlenames[partID]) + HIST("/h3dPosTOFdeltaTvsTrackPt"), centrality, cand.positivept(), tofDeltaTPos); - histos.fill(HIST(kParticlenames[partID]) + HIST("/h3dNegTOFdeltaTvsTrackPt"), centrality, cand.negativept(), tofDeltaTNeg); - histos.fill(HIST(kParticlenames[partID]) + HIST("/h3dPosTOFdeltaT"), centrality, pT, tofDeltaTPos); - histos.fill(HIST(kParticlenames[partID]) + HIST("/h3dNegTOFdeltaT"), centrality, pT, tofDeltaTNeg); - histos.fill(HIST(kParticlenames[partID]) + HIST("/h3dPosTOFdeltaTvsTrackPtot"), centrality, cand.positivept() * std::cosh(cand.positiveeta()), tofDeltaTPos); - histos.fill(HIST(kParticlenames[partID]) + HIST("/h3dNegTOFdeltaTvsTrackPtot"), centrality, cand.negativept() * std::cosh(cand.negativeeta()), tofDeltaTNeg); + histos.fill(HIST(kParticlenames[partID]) + HIST("/h3dPosTOFdeltaTvsTrackPt"), ft0ampl, cand.positivept(), tofDeltaTPos); + histos.fill(HIST(kParticlenames[partID]) + HIST("/h3dNegTOFdeltaTvsTrackPt"), ft0ampl, cand.negativept(), tofDeltaTNeg); + histos.fill(HIST(kParticlenames[partID]) + HIST("/h3dPosTOFdeltaT"), ft0ampl, pT, tofDeltaTPos); + histos.fill(HIST(kParticlenames[partID]) + HIST("/h3dNegTOFdeltaT"), ft0ampl, pT, tofDeltaTNeg); + histos.fill(HIST(kParticlenames[partID]) + HIST("/h3dPosTOFdeltaTvsTrackPtot"), ft0ampl, cand.positivept() * std::cosh(cand.positiveeta()), tofDeltaTPos); + histos.fill(HIST(kParticlenames[partID]) + HIST("/h3dNegTOFdeltaTvsTrackPtot"), ft0ampl, cand.negativept() * std::cosh(cand.negativeeta()), tofDeltaTNeg); } } template - void fillHistogramsCasc(TCand cand, TCollision coll, int gap) + void fillHistogramsCasc(TCand cand, TCollision coll, const int gap) { float invMass = 0; - float centrality = coll.centFT0C(); + float centrality = -1.f; + if (gap == 0) { + centrality = coll.totalFT0AmplitudeC(); + } else if (gap == 1) { + centrality = coll.totalFT0AmplitudeA(); + } float pT = cand.pt(); float rapidity = 1e6; @@ -649,7 +686,7 @@ struct Derivedupcanalysis { histos.fill(HIST(kParticlenames[partID]) + HIST("/hDCAV0Daughters"), pT, cand.dcaV0daughters()); histos.fill(HIST(kParticlenames[partID]) + HIST("/hDCAV0ToPV"), pT, std::fabs(cand.dcav0topv(coll.posX(), coll.posY(), coll.posZ()))); histos.fill(HIST(kParticlenames[partID]) + HIST("/hMassLambdaDau"), pT, cand.mLambda()); - histos.fill(HIST(kParticlenames[partID]) + HIST("/hNctau"), pT, ctau); + histos.fill(HIST(kParticlenames[partID]) + HIST("/hCtau"), pT, ctau); } if (PIDConfigurations.doTPCQA) { histos.fill(HIST(kParticlenames[partID]) + HIST("/h3dPosNsigmaTPC"), centrality, pT, tpcNsigmaPos); @@ -706,6 +743,8 @@ struct Derivedupcanalysis { LOG(fatal) << "Cannot analyze both data and MC simultaneously. Please select one of them."; } + rctChecker.init(evSels.cfgEvtRCTFlagCheckerLabel, evSels.cfgEvtRCTFlagCheckerZDCCheck, evSels.cfgEvtRCTFlagCheckerLimitAcceptAsBad); + // initialise bit masks setBits(maskTopologicalV0, {selV0CosPA, selDCANegToPV, selDCAPosToPV, selDCAV0Dau, selV0Radius, selV0RadiusMax}); setBits(maskTopologicalCasc, {selCascCosPA, selDCACascDau, selCascRadius, selCascRadiusMax, selBachToPV, selMesonToPV, selBaryonToPV, @@ -842,7 +881,7 @@ struct Derivedupcanalysis { secondaryMaskSelectionAntiLambda = maskTopologicalV0 | maskKinematicV0 | maskTrackPropertiesV0 | maskAntiLambdaSpecific; // Event Counter - histos.add("eventQA/hEventSelection", "hEventSelection", kTH1F, {{16, -0.5f, +15.5f}}); + histos.add("eventQA/hEventSelection", "hEventSelection", kTH1F, {{17, -0.5f, 16.5f}}); histos.get(HIST("eventQA/hEventSelection"))->GetXaxis()->SetBinLabel(1, "All collisions"); histos.get(HIST("eventQA/hEventSelection"))->GetXaxis()->SetBinLabel(2, "kIsTriggerTVX"); histos.get(HIST("eventQA/hEventSelection"))->GetXaxis()->SetBinLabel(3, "posZ cut"); @@ -857,20 +896,23 @@ struct Derivedupcanalysis { histos.get(HIST("eventQA/hEventSelection"))->GetXaxis()->SetBinLabel(12, "kNoCollInTimeRangeNarrow"); histos.get(HIST("eventQA/hEventSelection"))->GetXaxis()->SetBinLabel(13, "Below min occup."); histos.get(HIST("eventQA/hEventSelection"))->GetXaxis()->SetBinLabel(14, "Above max occup."); - histos.get(HIST("eventQA/hEventSelection"))->GetXaxis()->SetBinLabel(15, "isUPC"); - histos.get(HIST("eventQA/hEventSelection"))->GetXaxis()->SetBinLabel(16, "has UPC flag"); + histos.get(HIST("eventQA/hEventSelection"))->GetXaxis()->SetBinLabel(15, "RCTFlagsChecker"); + histos.get(HIST("eventQA/hEventSelection"))->GetXaxis()->SetBinLabel(16, "isUPC"); + histos.get(HIST("eventQA/hEventSelection"))->GetXaxis()->SetBinLabel(17, "has UPC flag"); // Event QA + histos.add("eventQA/hCentralityVsFT0ampl", "hCentralityVsFT0ampl", kTH3F, {axisFT0Cqa, axisDetectors.axisFT0Aampl, axisSelGap}); histos.add("eventQA/hCentrality", "hCentrality", kTH2F, {axisFT0Cqa, axisSelGap}); + histos.add("eventQA/hFT0ampl", "hFT0ampl", kTH2F, {axisDetectors.axisFT0Aampl, axisSelGap}); histos.add("eventQA/hCentralityVsTracksPVeta1", "hCentralityVsTracksPVeta1", kTH3F, {axisFT0Cqa, axisNTracksPVeta1, axisSelGap}); histos.add("eventQA/hCentralityVsTracksTotalExceptITSonly", "hCentralityVsTracksTotalExceptITSonly", kTH3F, {axisFT0Cqa, axisNTracksTotalExceptITSonly, axisSelGap}); histos.add("eventQA/hOccupancy", "hOccupancy", kTH2F, {axisOccupancy, axisSelGap}); histos.add("eventQA/hCentralityVsOccupancy", "hCentralityVsOccupancy", kTH3F, {axisFT0Cqa, axisOccupancy, axisSelGap}); histos.add("eventQA/hTracksPVeta1VsTracksGlobal", "hTracksPVeta1VsTracksGlobal", kTH3F, {axisNTracksPVeta1, axisNTracksGlobal, axisSelGap}); histos.add("eventQA/hCentralityVsTracksGlobal", "hCentralityVsTracksGlobal", kTH3F, {axisFT0Cqa, axisNTracksGlobal, axisSelGap}); - histos.add("eventQA/hGapSide", "Gap side; Entries", kTH1F, {{5, -0.5, 4.5}}); + histos.add("eventQA/hFT0amplVsTracksGlobal", "hFT0amplVsTracksGlobal", kTH3F, {axisDetectors.axisFT0Aampl, axisNTracksGlobal, axisSelGap}); histos.add("eventQA/hRawGapSide", "Raw Gap side; Entries", kTH1F, {{6, -1.5, 4.5}}); - histos.add("eventQA/hSelGapSide", "Selected gap side; Entries", kTH1F, {axisSelGap}); + histos.add("eventQA/hSelGapSide", "Selected gap side (with n); Entries", kTH1F, {axisSelGap}); histos.add("eventQA/hPosX", "Vertex position in x", kTH2F, {{100, -0.1, 0.1}, axisSelGap}); histos.add("eventQA/hPosY", "Vertex position in y", kTH2F, {{100, -0.1, 0.1}, axisSelGap}); histos.add("eventQA/hPosZ", "Vertex position in z", kTH2F, {{100, -20., 20.}, axisSelGap}); @@ -883,34 +925,36 @@ struct Derivedupcanalysis { histos.get(HIST("eventQA/mc/hEventSelectionMC"))->GetXaxis()->SetBinLabel(1, "All collisions"); histos.get(HIST("eventQA/mc/hEventSelectionMC"))->GetXaxis()->SetBinLabel(2, "posZ cut"); histos.get(HIST("eventQA/mc/hEventSelectionMC"))->GetXaxis()->SetBinLabel(3, "rec. at least once"); - - histos.add("eventQA/mc/hTracksGlobalvsMCNParticlesEta10gen", "hTracksGlobalvsMCNParticlesEta10gen", kTH2F, {axisNTracksGlobal, axisNTracksPVeta1}); + histos.add("eventQA/mc/hTracksGlobalvsMCNParticlesEta08gen", "hTracksGlobalvsMCNParticlesEta08gen", kTH2F, {axisNTracksGlobal, axisNTracksGlobal}); histos.add("eventQA/mc/hTracksGlobalVsNcoll_beforeEvSel", "hTracksGlobalVsNcoll_beforeEvSel", kTH2F, {axisNTracksGlobal, axisNAssocColl}); histos.add("eventQA/mc/hTracksGlobalVsNcoll_afterEvSel", "hTracksGlobalVsNcoll_afterEvSel", kTH2F, {axisNTracksGlobal, axisNAssocColl}); histos.add("eventQA/mc/hTracksGlobalVsPVzMC", "hTracksGlobalVsPVzMC", kTH2F, {axisNTracksGlobal, {100, -20., 20.}}); histos.add("eventQA/mc/hEventPVzMC", "hEventPVzMC", kTH1F, {{100, -20., 20.}}); + histos.add("eventQA/mc/hGenEventFT0ampl", "hGenEventFT0ampl", kTH1F, {axisDetectors.axisFT0Aampl}); histos.add("eventQA/mc/hGenEventCentrality", "hGenEventCentrality", kTH1F, {axisFT0Cqa}); + histos.add("eventQA/mc/hGeneratorsId", "hGeneratorsId", kTH1F, {axisGeneratorIds}); } if (doprocessV0sMC || doprocessCascadesMC) { // Event QA histos.add("eventQA/mc/hFakeEvents", "hFakeEvents", {kTH1F, {{1, -0.5f, 0.5f}}}); - histos.add("eventQA/mc/hNTracksGlobalvsMCNParticlesEta10rec", "hNTracksGlobalvsMCNParticlesEta10rec", kTH2F, {axisNTracksGlobal, axisNTracksPVeta1}); + histos.add("eventQA/mc/hNTracksGlobalvsMCNParticlesEta08rec", "hNTracksGlobalvsMCNParticlesEta08rec", kTH2F, {axisNTracksGlobal, axisNTracksGlobal}); histos.add("eventQA/mc/hNTracksPVeta1vsMCNParticlesEta10rec", "hNTracksPVeta1vsMCNParticlesEta10rec", kTH2F, {axisNTracksPVeta1, axisNTracksPVeta1}); histos.add("eventQA/mc/hNTracksGlobalvstotalMultMCParticles", "hNTracksGlobalvstotalMultMCParticles", kTH2F, {axisNTracksGlobal, axisNchInvMass}); histos.add("eventQA/mc/hNTracksPVeta1vstotalMultMCParticles", "hNTracksPVeta1vstotalMultMCParticles", kTH2F, {axisNTracksPVeta1, axisNchInvMass}); + histos.add("eventQA/hSelGapSideNoNeutrons", "Selected gap side (no n); Entries", kTH1F, {{5, -0.5, 4.5}}); } if (doprocessV0sMC) { if (analyseLambda && calculateFeeddownMatrix) - histos.add(Form("%s/h3dLambdaFeeddown", kParticlenames[1].data()), "h3dLambdaFeeddown", kTH3F, {axisNTracksGlobal, axisPt, axisPtXi}); + histos.add(Form("%s/h3dLambdaFeeddown", kParticlenames[1].data()), "h3dLambdaFeeddown", kTH3F, {axisNTracksGlobal, axisPt, axisPt}); if (analyseAntiLambda && calculateFeeddownMatrix) - histos.add(Form("%s/h3dAntiLambdaFeeddown", kParticlenames[2].data()), "h3dAntiLambdaFeeddown", kTH3F, {axisNTracksGlobal, axisPt, axisPtXi}); + histos.add(Form("%s/h3dAntiLambdaFeeddown", kParticlenames[2].data()), "h3dAntiLambdaFeeddown", kTH3F, {axisNTracksGlobal, axisPt, axisPt}); } if (doprocessGenerated) { for (int partID = 0; partID <= 6; partID++) { - histos.add(Form("%s/mc/h7dGen", kParticlenames[partID].data()), "h7dGen", kTHnSparseF, {axisFT0Cqa, axisNchInvMass, axisNchInvMass, axisPt, axisSelGap, axisRap, axisGeneratorIds}); + histos.add(Form("%s/mc/h7dGen", kParticlenames[partID].data()), "h7dGen", kTHnSparseF, {axisDetectors.axisFT0ampl, axisNchInvMass, axisNchInvMass, axisPt, axisSelGap, axisRap, axisGeneratorIds}); } } @@ -922,6 +966,7 @@ struct Derivedupcanalysis { histos.add("generalQA/hNegDCAToPV", "hNegDCAToPV", kTH1F, {axisDCAtoPV}); histos.add("generalQA/hDCADaughters", "hDCADaughters", kTH1F, {axisDCAdau}); histos.add("generalQA/hPointingAngle", "hPointingAngle", kTH1F, {axisPointingAngle}); + histos.add("generalQA/hCosPA", "hCosPA", kTH1F, {axisCosPA}); histos.add("generalQA/hV0Radius", "hV0Radius", kTH1F, {axisV0Radius}); histos.add("generalQA/h2dPositiveITSvsTPCpts", "h2dPositiveITSvsTPCpts", kTH2F, {axisTPCrows, axisITSclus}); histos.add("generalQA/h2dNegativeITSvsTPCpts", "h2dNegativeITSvsTPCpts", kTH2F, {axisTPCrows, axisITSclus}); @@ -992,16 +1037,9 @@ struct Derivedupcanalysis { } template - int getGapSide(TCollision const& collision, bool fillQA) + int getGapSide(TCollision const& collision) { int selGapSide = sgSelector.trueGap(collision, upcCuts.fv0a, upcCuts.ft0a, upcCuts.ft0c, upcCuts.zdc); - if (fillQA) { - histos.fill(HIST("eventQA/hGapSide"), collision.gapSide()); - histos.fill(HIST("eventQA/hSelGapSide"), selGapSide); - histos.fill(HIST("eventQA/hFT0"), collision.totalFT0AmplitudeA(), collision.totalFT0AmplitudeC(), selGapSide); - histos.fill(HIST("eventQA/hFDD"), collision.totalFDDAmplitudeA(), collision.totalFDDAmplitudeC(), selGapSide); - histos.fill(HIST("eventQA/hZN"), collision.energyCommonZNA(), collision.energyCommonZNC(), selGapSide); - } return selGapSide; } @@ -1010,16 +1048,32 @@ struct Derivedupcanalysis { { // QA histograms float centrality = collision.centFT0C(); + float ft0ampl = -1.f; + + if (gap == 0) { + ft0ampl = collision.totalFT0AmplitudeC(); + } else if (gap == 1) { + ft0ampl = collision.totalFT0AmplitudeA(); + } + + histos.fill(HIST("eventQA/hCentralityVsFT0ampl"), centrality, ft0ampl, gap); histos.fill(HIST("eventQA/hCentrality"), centrality, gap); + histos.fill(HIST("eventQA/hFT0ampl"), ft0ampl, gap); histos.fill(HIST("eventQA/hCentralityVsTracksTotalExceptITSonly"), centrality, collision.multAllTracksTPCOnly() + collision.multAllTracksITSTPC(), gap); histos.fill(HIST("eventQA/hCentralityVsTracksPVeta1"), centrality, collision.multNTracksPVeta1(), gap); histos.fill(HIST("eventQA/hOccupancy"), collision.trackOccupancyInTimeRange(), gap); histos.fill(HIST("eventQA/hCentralityVsOccupancy"), centrality, collision.trackOccupancyInTimeRange(), gap); histos.fill(HIST("eventQA/hTracksPVeta1VsTracksGlobal"), collision.multNTracksPVeta1(), collision.multNTracksGlobal(), gap); histos.fill(HIST("eventQA/hCentralityVsTracksGlobal"), centrality, collision.multNTracksGlobal(), gap); + histos.fill(HIST("eventQA/hFT0amplVsTracksGlobal"), ft0ampl, collision.multNTracksGlobal(), gap); histos.fill(HIST("eventQA/hPosX"), collision.posX(), gap); histos.fill(HIST("eventQA/hPosY"), collision.posY(), gap); histos.fill(HIST("eventQA/hPosZ"), collision.posZ(), gap); + + histos.fill(HIST("eventQA/hSelGapSide"), gap); + histos.fill(HIST("eventQA/hFT0"), collision.totalFT0AmplitudeA(), collision.totalFT0AmplitudeC(), gap); + histos.fill(HIST("eventQA/hFDD"), collision.totalFDDAmplitudeA(), collision.totalFDDAmplitudeC(), gap); + histos.fill(HIST("eventQA/hZN"), collision.energyCommonZNA(), collision.energyCommonZNC(), gap); } template @@ -1031,44 +1085,45 @@ struct Derivedupcanalysis { float qaBin; }; - const std::array checks = {{ - {true, true, 0.0}, // All collisions - {requireIsTriggerTVX, collision.selection_bit(aod::evsel::kIsTriggerTVX), 1.0}, // Triggered by FT0M - {true, std::fabs(collision.posZ()) < maxZVtxPosition, 2.0}, // Vertex-Z selected - {rejectITSROFBorder, collision.selection_bit(o2::aod::evsel::kNoITSROFrameBorder), 3.0}, // Not at ITS ROF border - {rejectTFBorder, collision.selection_bit(o2::aod::evsel::kNoTimeFrameBorder), 4.0}, // Not at TF border - {requireIsVertexITSTPC, collision.selection_bit(o2::aod::evsel::kIsVertexITSTPC), 5.0}, // At least one ITS-TPC track - {requireIsGoodZvtxFT0VsPV, collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV), 6.0}, // PV position consistency - {requireIsVertexTOFmatched, collision.selection_bit(o2::aod::evsel::kIsVertexTOFmatched), 7.0}, // PV with TOF match - {requireIsVertexTRDmatched, collision.selection_bit(o2::aod::evsel::kIsVertexTRDmatched), 8.0}, // PV with TRD match - {rejectSameBunchPileup, collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup), 9.0}, // No same-bunch pileup - {requireNoCollInTimeRangeStd, collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard), 10.0}, // No collision within +-10 µs - {requireNoCollInTimeRangeNarrow, collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeNarrow), 11.0}, // No collision within +-4 µs - {minOccupancy >= 0, collision.trackOccupancyInTimeRange() >= minOccupancy, 12.0}, // Above min occupancy - {maxOccupancy > 0, collision.trackOccupancyInTimeRange() < maxOccupancy, 13.0}, // Below max occupancy + const std::array selections = {{ + {true, true, 0.0}, // All collisions + {evSels.requireIsTriggerTVX, collision.selection_bit(aod::evsel::kIsTriggerTVX), 1.0}, // Triggered by FT0M + {true, std::fabs(collision.posZ()) < maxZVtxPosition, 2.0}, // Vertex-Z selected + {evSels.rejectITSROFBorder, collision.selection_bit(o2::aod::evsel::kNoITSROFrameBorder), 3.0}, // Not at ITS ROF border + {evSels.rejectTFBorder, collision.selection_bit(o2::aod::evsel::kNoTimeFrameBorder), 4.0}, // Not at TF border + {evSels.requireIsVertexITSTPC, collision.selection_bit(o2::aod::evsel::kIsVertexITSTPC), 5.0}, // At least one ITS-TPC track + {evSels.requireIsGoodZvtxFT0VsPV, collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV), 6.0}, // PV position consistency + {evSels.requireIsVertexTOFmatched, collision.selection_bit(o2::aod::evsel::kIsVertexTOFmatched), 7.0}, // PV with TOF match + {evSels.requireIsVertexTRDmatched, collision.selection_bit(o2::aod::evsel::kIsVertexTRDmatched), 8.0}, // PV with TRD match + {evSels.rejectSameBunchPileup, collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup), 9.0}, // No same-bunch pileup + {evSels.requireNoCollInTimeRangeStd, collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard), 10.0}, // No collision within +-10 µs + {evSels.requireNoCollInTimeRangeNarrow, collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeNarrow), 11.0}, // No collision within +-4 µs + {minOccupancy >= 0, collision.trackOccupancyInTimeRange() >= minOccupancy, 12.0}, // Above min occupancy + {maxOccupancy > 0, collision.trackOccupancyInTimeRange() < maxOccupancy, 13.0}, // Below max occupancy + {evSels.requireRCTFlagChecker, rctChecker(collision), 14.0}, // Verify collision in RCT }}; - for (const auto& check : checks) { - if (check.selection && !check.condition) { + for (const auto& sel : selections) { + if (sel.selection && !sel.condition) { return false; } - if (fillQA && check.selection) { - histos.fill(HIST("eventQA/hEventSelection"), check.qaBin); + if (fillQA && sel.selection) { + histos.fill(HIST("eventQA/hEventSelection"), sel.qaBin); } } - if (studyUPConly && !collision.isUPC()) { + if (evSels.studyUPConly && !collision.isUPC()) { return false; } else if (collision.isUPC() && fillQA) { - histos.fill(HIST("eventQA/hEventSelection"), 14.0); // is UPC compatible + histos.fill(HIST("eventQA/hEventSelection"), 15.0); // is UPC compatible } // Additional check for UPC collision flag - if (useUPCflag && collision.flags() < 1) { + if (evSels.useUPCflag && collision.flags() < 1) { return false; } if (collision.flags() >= 1 && fillQA) { - histos.fill(HIST("eventQA/hEventSelection"), 15.0); // UPC event + histos.fill(HIST("eventQA/hEventSelection"), 16.0); // UPC event } return true; @@ -1383,6 +1438,10 @@ struct Derivedupcanalysis { if (std::fabs(v0.positiveeta()) < daughterEtaCut) bitMap.set(selPosEta); + // c x tau + float ctauK0short = v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassK0Short; + float ctauLambda = v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassLambda0; + auto posTrackExtra = v0.template posTrackExtra_as(); auto negTrackExtra = v0.template negTrackExtra_as(); @@ -1466,9 +1525,9 @@ struct Derivedupcanalysis { bitMap.set(selNegNotTPCOnly); // proper lifetime - if (v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassLambda0 < lifetimecutV0->get("lifetimecutLambda")) + if (ctauLambda < nCtauCutV0->get("lifetimecutLambda") * ctaulambdaPDG) bitMap.set(selLambdaCTau); - if (v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassK0Short < lifetimecutV0->get("lifetimecutK0S")) + if (ctauK0short < nCtauCutV0->get("lifetimecutK0S") * ctauk0shortPDG) bitMap.set(selK0ShortCTau); // armenteros @@ -1630,6 +1689,7 @@ struct Derivedupcanalysis { histos.fill(HIST("generalQA/hNegDCAToPV"), v0.dcanegtopv()); histos.fill(HIST("generalQA/hDCADaughters"), v0.dcaV0daughters()); histos.fill(HIST("generalQA/hPointingAngle"), std::acos(v0.v0cosPA())); + histos.fill(HIST("generalQA/hCosPA"), v0.v0cosPA()); histos.fill(HIST("generalQA/hV0Radius"), v0.v0radius()); histos.fill(HIST("generalQA/h2dPositiveITSvsTPCpts"), posTrackExtra.tpcCrossedRows(), posTrackExtra.itsNCls()); histos.fill(HIST("generalQA/h2dNegativeITSvsTPCpts"), negTrackExtra.tpcCrossedRows(), negTrackExtra.itsNCls()); @@ -1654,9 +1714,11 @@ struct Derivedupcanalysis { } PresliceUnsorted perMcCollision = aod::v0data::straMCCollisionId; + PresliceUnsorted neutronsPerMcCollision = aod::zdcneutrons::straMCCollisionId; std::vector getListOfRecoCollIds(StraMCCollisionsFull const& mcCollisions, - StraCollisonsFullMC const& collisions) + StraCollisonsFullMC const& collisions, + NeutronsMC const& neutrons) { std::vector listBestCollisionIds(mcCollisions.size(), -1); @@ -1664,7 +1726,10 @@ struct Derivedupcanalysis { if (std::find(generatorIds->begin(), generatorIds->end(), mcCollision.generatorsID()) == generatorIds->end()) { continue; } + + // Group collisions and neutrons by MC collision index auto groupedCollisions = collisions.sliceBy(perMcCollision, mcCollision.globalIndex()); + auto groupedNeutrons = neutrons.sliceBy(neutronsPerMcCollision, mcCollision.globalIndex()); // Find the collision with the biggest nbr of PV contributors // Follows what was done here: https://github.com/AliceO2Group/O2Physics/blob/master/Common/TableProducer/mcCollsExtra.cxx#L93 int biggestNContribs = -1; @@ -1674,8 +1739,33 @@ struct Derivedupcanalysis { continue; } - int selGapSide = collision.isUPC() ? getGapSide(collision, false) : -1; - if (studyUPConly && (selGapSide < -0.5)) + int selGapSide = collision.isUPC() ? getGapSide(collision) : -1; + if (checkNeutronsInMC) { + for (const auto& neutron : groupedNeutrons) { + if (selGapSide < -0.5) + break; + + const float eta = neutron.eta(); + switch (selGapSide) { + case 0: // SGA + if (eta > neutronEtaCut) + selGapSide = -1; + break; + case 1: // SGC + if (eta < -neutronEtaCut) + selGapSide = -1; + break; + case 2: // DG + if (eta > neutronEtaCut) + selGapSide = 1; + else if (eta < -neutronEtaCut) + selGapSide = 0; + break; + } + } + } + + if (evSels.studyUPConly && (selGapSide != static_cast(upcCuts.genGapSide))) continue; if (biggestNContribs < collision.multPVTotalContributors()) { @@ -1689,26 +1779,32 @@ struct Derivedupcanalysis { return listBestCollisionIds; } - void fillGenMCHistogramsQA(StraMCCollisionsFull const& mcCollisions, StraCollisonsFullMC const& collisions) + void fillGenMCHistogramsQA(StraMCCollisionsFull const& mcCollisions, + StraCollisonsFullMC const& collisions, + NeutronsMC const& neutrons) { for (auto const& mcCollision : mcCollisions) { // LOGF(info, "Generator ID is %i", mcCollision.generatorsID()); + histos.fill(HIST("eventQA/mc/hGeneratorsId"), mcCollision.generatorsID()); + if (std::find(generatorIds->begin(), generatorIds->end(), mcCollision.generatorsID()) == generatorIds->end()) { continue; } - histos.fill(HIST("eventQA/mc/hEventSelectionMC"), 0.0, mcCollision.multMCNParticlesEta10(), mcCollision.generatorsID()); + histos.fill(HIST("eventQA/mc/hEventSelectionMC"), 0.0, mcCollision.multMCNParticlesEta08(), mcCollision.generatorsID()); if (std::abs(mcCollision.posZ()) > maxZVtxPosition) continue; - histos.fill(HIST("eventQA/mc/hEventSelectionMC"), 1.0, mcCollision.multMCNParticlesEta10(), mcCollision.generatorsID()); + histos.fill(HIST("eventQA/mc/hEventSelectionMC"), 1.0, mcCollision.multMCNParticlesEta08(), mcCollision.generatorsID()); - // Group collisions by MC collision index + // Group collisions and neutrons by MC collision index auto groupedCollisions = collisions.sliceBy(perMcCollision, mcCollision.globalIndex()); + auto groupedNeutrons = neutrons.sliceBy(neutronsPerMcCollision, mcCollision.globalIndex()); bool atLeastOne = false; float centrality = -1.f; + float ft0ampl = -1.f; int nCollisions = 0; int biggestNContribs = -1; int nTracksGlobal = -1; @@ -1719,8 +1815,33 @@ struct Derivedupcanalysis { continue; } - int selGapSide = collision.isUPC() ? getGapSide(collision, false) : -1; - if (studyUPConly && (selGapSide < -0.5)) + int selGapSide = collision.isUPC() ? getGapSide(collision) : -1; + if (checkNeutronsInMC) { + for (const auto& neutron : groupedNeutrons) { + if (selGapSide < -0.5) + break; + + const float eta = neutron.eta(); + switch (selGapSide) { + case 0: // SGA + if (eta > neutronEtaCut) + selGapSide = -1; + break; + case 1: // SGC + if (eta < -neutronEtaCut) + selGapSide = -1; + break; + case 2: // DG + if (eta > neutronEtaCut) + selGapSide = 1; + else if (eta < -neutronEtaCut) + selGapSide = 0; + break; + } + } + } + + if (evSels.studyUPConly && (selGapSide != static_cast(upcCuts.genGapSide))) continue; ++nCollisions; @@ -1728,7 +1849,13 @@ struct Derivedupcanalysis { if (biggestNContribs < collision.multPVTotalContributors()) { biggestNContribs = collision.multPVTotalContributors(); - centrality = collision.centFT0C(); + if (static_cast(upcCuts.genGapSide) == 0) { + ft0ampl = collision.totalFT0AmplitudeC(); + centrality = collision.centFT0C(); + } else if (static_cast(upcCuts.genGapSide) == 1) { + ft0ampl = collision.totalFT0AmplitudeA(); + centrality = collision.centFT0A(); + } nTracksGlobal = collision.multNTracksGlobal(); } } @@ -1736,13 +1863,14 @@ struct Derivedupcanalysis { // Fill histograms histos.fill(HIST("eventQA/mc/hTracksGlobalVsNcoll_beforeEvSel"), nTracksGlobal, groupedCollisions.size()); histos.fill(HIST("eventQA/mc/hTracksGlobalVsNcoll_afterEvSel"), nTracksGlobal, nCollisions); - histos.fill(HIST("eventQA/mc/hTracksGlobalvsMCNParticlesEta10gen"), nTracksGlobal, mcCollision.multMCNParticlesEta10()); + histos.fill(HIST("eventQA/mc/hTracksGlobalvsMCNParticlesEta08gen"), nTracksGlobal, mcCollision.multMCNParticlesEta08()); histos.fill(HIST("eventQA/mc/hTracksGlobalVsPVzMC"), nTracksGlobal, mcCollision.posZ()); histos.fill(HIST("eventQA/mc/hEventPVzMC"), mcCollision.posZ()); if (atLeastOne) { - histos.fill(HIST("eventQA/mc/hEventSelectionMC"), 2.0, mcCollision.multMCNParticlesEta10(), mcCollision.generatorsID()); + histos.fill(HIST("eventQA/mc/hEventSelectionMC"), 2.0, mcCollision.multMCNParticlesEta08(), mcCollision.generatorsID()); histos.fill(HIST("eventQA/mc/hGenEventCentrality"), centrality); + histos.fill(HIST("eventQA/mc/hGenEventFT0ampl"), ft0ampl); } } } @@ -1754,7 +1882,11 @@ struct Derivedupcanalysis { return; } - auto v0mother = v0.motherMCPart(); + const auto v0mother = v0.template motherMCPart_as(); + if (v0mother.size() < 1) { + return; + } + const float rapidityXi = RecoDecay::y(std::array{v0mother.px(), v0mother.py(), v0mother.pz()}, o2::constants::physics::MassXiMinus); if (std::fabs(rapidityXi) > 0.5f) { return; @@ -1765,13 +1897,13 @@ struct Derivedupcanalysis { const float motherPt = std::hypot(v0mother.px(), v0mother.py()); if (analyseLambda && verifyMask(selMap, secondaryMaskSelectionLambda) && - v0mother.pdgCode() == PDG_t::kXiMinus && v0mother.isPhysicalPrimary()) { - histos.fill(HIST("h3dLambdaFeeddown"), mult, v0pt, motherPt); + (v0mother.pdgCode() == PDG_t::kXiMinus) && v0mother.isPhysicalPrimary()) { + histos.fill(HIST(kParticlenames[1]) + HIST("/h3dLambdaFeeddown"), mult, v0pt, motherPt); } if (analyseAntiLambda && verifyMask(selMap, secondaryMaskSelectionAntiLambda) && - v0mother.pdgCode() == PDG_t::kXiPlusBar && v0mother.isPhysicalPrimary()) { - histos.fill(HIST("h3dAntiLambdaFeeddown"), mult, v0pt, motherPt); + (v0mother.pdgCode() == PDG_t::kXiPlusBar) && v0mother.isPhysicalPrimary()) { + histos.fill(HIST(kParticlenames[2]) + HIST("/h3dAntiLambdaFeeddown"), mult, v0pt, motherPt); } } @@ -1783,8 +1915,8 @@ struct Derivedupcanalysis { histos.fill(HIST("eventQA/hRawGapSide"), collision.gapSide()); - int selGapSide = collision.isUPC() ? getGapSide(collision, true) : -1; - if (studyUPConly && (selGapSide < -0.5)) + int selGapSide = collision.isUPC() ? getGapSide(collision) : -1; + if (evSels.studyUPConly && (selGapSide < -0.5)) return; fillHistogramsQA(collision, selGapSide); @@ -1808,15 +1940,18 @@ struct Derivedupcanalysis { DauTracks const&, aod::MotherMCParts const&, StraMCCollisionsFull const&, - V0MCCoresFull const&) + V0MCCoresFull const&, + NeutronsMC const& neutrons) { if (!collision.has_straMCCollision()) { histos.fill(HIST("eventQA/mc/hFakeEvents"), 0); // no assoc. MC collisions - } else { - const auto& mcCollision = collision.straMCCollision_as(); - if (std::find(generatorIds->begin(), generatorIds->end(), mcCollision.generatorsID()) == generatorIds->end()) { - return; - } + return; + } + + const auto& mcCollision = collision.straMCCollision_as(); // take gen. collision associated to the rec. collision + + if (std::find(generatorIds->begin(), generatorIds->end(), mcCollision.generatorsID()) == generatorIds->end()) { + return; } if (!acceptEvent(collision, true)) { @@ -1825,19 +1960,45 @@ struct Derivedupcanalysis { histos.fill(HIST("eventQA/hRawGapSide"), collision.gapSide()); - int selGapSide = collision.isUPC() ? getGapSide(collision, true) : -1; - if (studyUPConly && (selGapSide < -0.5)) + int selGapSide = collision.isUPC() ? getGapSide(collision) : -1; + int selGapSideNoNeutrons = selGapSide; + + auto groupedNeutrons = neutrons.sliceBy(neutronsPerMcCollision, mcCollision.globalIndex()); + if (checkNeutronsInMC) { + for (const auto& neutron : groupedNeutrons) { + if (selGapSide < -0.5) + break; + + const float eta = neutron.eta(); + switch (selGapSide) { + case 0: // SGA + if (eta > neutronEtaCut) + selGapSide = -1; + break; + case 1: // SGC + if (eta < -neutronEtaCut) + selGapSide = -1; + break; + case 2: // DG + if (eta > neutronEtaCut) + selGapSide = 1; + else if (eta < -neutronEtaCut) + selGapSide = 0; + break; + } + } + } + + if (evSels.studyUPConly && (selGapSide < -0.5)) return; + histos.fill(HIST("eventQA/hSelGapSideNoNeutrons"), selGapSideNoNeutrons); fillHistogramsQA(collision, selGapSide); - if (collision.has_straMCCollision()) { - const auto& mcCollision = collision.straMCCollision_as(); - histos.fill(HIST("eventQA/mc/hNTracksGlobalvsMCNParticlesEta10rec"), collision.multNTracksGlobal(), mcCollision.multMCNParticlesEta10()); - histos.fill(HIST("eventQA/mc/hNTracksPVeta1vsMCNParticlesEta10rec"), collision.multNTracksPVeta1(), mcCollision.multMCNParticlesEta10()); - histos.fill(HIST("eventQA/mc/hNTracksGlobalvstotalMultMCParticles"), collision.multNTracksGlobal(), mcCollision.totalMultMCParticles()); - histos.fill(HIST("eventQA/mc/hNTracksPVeta1vstotalMultMCParticles"), collision.multNTracksPVeta1(), mcCollision.totalMultMCParticles()); - } + histos.fill(HIST("eventQA/mc/hNTracksGlobalvsMCNParticlesEta08rec"), collision.multNTracksGlobal(), mcCollision.multMCNParticlesEta08()); + histos.fill(HIST("eventQA/mc/hNTracksPVeta1vsMCNParticlesEta10rec"), collision.multNTracksPVeta1(), mcCollision.multMCNParticlesEta10()); + histos.fill(HIST("eventQA/mc/hNTracksGlobalvstotalMultMCParticles"), collision.multNTracksGlobal(), mcCollision.totalMultMCParticles()); + histos.fill(HIST("eventQA/mc/hNTracksPVeta1vstotalMultMCParticles"), collision.multNTracksPVeta1(), mcCollision.totalMultMCParticles()); for (const auto& v0 : fullV0s) { if ((v0.v0Type() != v0cuts.v0TypeSelection) && (v0cuts.v0TypeSelection > 0)) @@ -1873,8 +2034,8 @@ struct Derivedupcanalysis { histos.fill(HIST("eventQA/hRawGapSide"), collision.gapSide()); - int selGapSide = collision.isUPC() ? getGapSide(collision, true) : -1; - if (studyUPConly && (selGapSide < -0.5)) + int selGapSide = collision.isUPC() ? getGapSide(collision) : -1; + if (evSels.studyUPConly && (selGapSide < -0.5)) return; fillHistogramsQA(collision, selGapSide); @@ -1894,15 +2055,18 @@ struct Derivedupcanalysis { DauTracks const&, aod::MotherMCParts const&, StraMCCollisionsFull const&, - CascMCCoresFull const&) + CascMCCoresFull const&, + NeutronsMC const& neutrons) { if (!collision.has_straMCCollision()) { histos.fill(HIST("eventQA/mc/hFakeEvents"), 0); // no assoc. MC collisions - } else { - const auto& mcCollision = collision.straMCCollision_as(); - if (std::find(generatorIds->begin(), generatorIds->end(), mcCollision.generatorsID()) == generatorIds->end()) { - return; - } + return; + } + + const auto& mcCollision = collision.straMCCollision_as(); // take gen. collision associated to the rec. collision + + if (std::find(generatorIds->begin(), generatorIds->end(), mcCollision.generatorsID()) == generatorIds->end()) { + return; } if (!acceptEvent(collision, true)) { @@ -1911,19 +2075,45 @@ struct Derivedupcanalysis { histos.fill(HIST("eventQA/hRawGapSide"), collision.gapSide()); - int selGapSide = collision.isUPC() ? getGapSide(collision, true) : -1; - if (studyUPConly && (selGapSide < -0.5)) + int selGapSide = collision.isUPC() ? getGapSide(collision) : -1; + int selGapSideNoNeutrons = selGapSide; + + auto groupedNeutrons = neutrons.sliceBy(neutronsPerMcCollision, mcCollision.globalIndex()); + if (checkNeutronsInMC) { + for (const auto& neutron : groupedNeutrons) { + if (selGapSide < -0.5) + break; + + const float eta = neutron.eta(); + switch (selGapSide) { + case 0: // SGA + if (eta > neutronEtaCut) + selGapSide = -1; + break; + case 1: // SGC + if (eta < -neutronEtaCut) + selGapSide = -1; + break; + case 2: // DG + if (eta > neutronEtaCut) + selGapSide = 1; + else if (eta < -neutronEtaCut) + selGapSide = 0; + break; + } + } + } + + if (evSels.studyUPConly && (selGapSide < -0.5)) return; + histos.fill(HIST("eventQA/hSelGapSideNoNeutrons"), selGapSideNoNeutrons); fillHistogramsQA(collision, selGapSide); - if (collision.has_straMCCollision()) { - const auto& mcCollision = collision.straMCCollision_as(); - histos.fill(HIST("eventQA/mc/hNTracksGlobalvsMCNParticlesEta10rec"), collision.multNTracksGlobal(), mcCollision.multMCNParticlesEta10()); - histos.fill(HIST("eventQA/mc/hNTracksPVeta1vsMCNParticlesEta10rec"), collision.multNTracksPVeta1(), mcCollision.multMCNParticlesEta10()); - histos.fill(HIST("eventQA/mc/hNTracksGlobalvstotalMultMCParticles"), collision.multNTracksGlobal(), mcCollision.totalMultMCParticles()); - histos.fill(HIST("eventQA/mc/hNTracksPVeta1vstotalMultMCParticles"), collision.multNTracksPVeta1(), mcCollision.totalMultMCParticles()); - } + histos.fill(HIST("eventQA/mc/hNTracksGlobalvsMCNParticlesEta08rec"), collision.multNTracksGlobal(), mcCollision.multMCNParticlesEta08()); + histos.fill(HIST("eventQA/mc/hNTracksPVeta1vsMCNParticlesEta10rec"), collision.multNTracksPVeta1(), mcCollision.multMCNParticlesEta10()); + histos.fill(HIST("eventQA/mc/hNTracksGlobalvstotalMultMCParticles"), collision.multNTracksGlobal(), mcCollision.totalMultMCParticles()); + histos.fill(HIST("eventQA/mc/hNTracksPVeta1vstotalMultMCParticles"), collision.multNTracksPVeta1(), mcCollision.totalMultMCParticles()); for (const auto& casc : fullCascades) { std::bitset selMap = computeBitmapCascade(casc, collision); @@ -1946,10 +2136,11 @@ struct Derivedupcanalysis { void processGenerated(StraMCCollisionsFull const& mcCollisions, V0MCCoresFull const& V0MCCores, CascMCCoresFull const& CascMCCores, - StraCollisonsFullMC const& collisions) + StraCollisonsFullMC const& collisions, + NeutronsMC const& neutrons) { - fillGenMCHistogramsQA(mcCollisions, collisions); - std::vector listBestCollisionIds = getListOfRecoCollIds(mcCollisions, collisions); + fillGenMCHistogramsQA(mcCollisions, collisions, neutrons); + std::vector listBestCollisionIds = getListOfRecoCollIds(mcCollisions, collisions, neutrons); // V0 start for (auto const& v0MC : V0MCCores) { // Consider only primaries @@ -1961,12 +2152,12 @@ struct Derivedupcanalysis { float ymc = 1e3; if (v0MC.pdgCode() == PDG_t::kK0Short) ymc = v0MC.rapidityMC(0); - else if (std::abs(v0MC.pdgCode()) == PDG_t::kLambda0) + else if ((v0MC.pdgCode() == PDG_t::kLambda0) || (v0MC.pdgCode() == PDG_t::kLambda0Bar)) ymc = v0MC.rapidityMC(1); if (std::abs(ymc) > rapidityCut) continue; - auto mcCollision = v0MC.straMCCollision_as(); // take gen. collision + const auto& mcCollision = v0MC.straMCCollision_as(); // take gen. collision if (std::abs(mcCollision.posZ()) > maxZVtxPosition) continue; @@ -1976,24 +2167,39 @@ struct Derivedupcanalysis { continue; } - float centrality = -1.f; + // float centrality = -1.f; + float ft0ampl = -1.f; int nTracksGlobal = -1; if (listBestCollisionIds[mcCollision.globalIndex()] > -1) { auto collision = collisions.iteratorAt(listBestCollisionIds[mcCollision.globalIndex()]); - centrality = collision.centFT0C(); + // centrality = collision.centFT0C(); + if (static_cast(upcCuts.genGapSide) == 0) { + ft0ampl = collision.totalFT0AmplitudeC(); + } else if (static_cast(upcCuts.genGapSide) == 1) { + ft0ampl = collision.totalFT0AmplitudeA(); + } nTracksGlobal = collision.multNTracksGlobal(); } + const int pdgPos = v0MC.pdgCodePositive(); + const int pdgNeg = v0MC.pdgCodeNegative(); + const int pdgV0 = v0MC.pdgCode(); + + const bool isPositiveProton = (pdgPos == PDG_t::kProton); + const bool isPositivePion = (pdgPos == PDG_t::kPiPlus) || (doTreatPiToMuon && pdgPos == PDG_t::kMuonPlus); + const bool isNegativeProton = (pdgNeg == kProtonBar); + const bool isNegativePion = (pdgNeg == PDG_t::kPiMinus) || (doTreatPiToMuon && pdgNeg == PDG_t::kMuonMinus); + // Fill histograms - if (v0MC.pdgCode() == PDG_t::kK0Short) { - histos.fill(HIST(kParticlenames[0]) + HIST("/mc/h7dGen"), centrality, nTracksGlobal, mcCollision.multMCNParticlesEta10(), pTmc, static_cast(upcCuts.genGapSide), ymc, mcCollision.generatorsID()); + if ((pdgV0 == PDG_t::kK0Short) && isPositivePion && isNegativePion) { + histos.fill(HIST(kParticlenames[0]) + HIST("/mc/h7dGen"), ft0ampl, nTracksGlobal, mcCollision.multMCNParticlesEta08(), pTmc, static_cast(upcCuts.genGapSide), ymc, mcCollision.generatorsID()); } - if (v0MC.pdgCode() == PDG_t::kLambda0) { - histos.fill(HIST(kParticlenames[1]) + HIST("/mc/h7dGen"), centrality, nTracksGlobal, mcCollision.multMCNParticlesEta10(), pTmc, static_cast(upcCuts.genGapSide), ymc, mcCollision.generatorsID()); + if ((pdgV0 == PDG_t::kLambda0) && isPositiveProton && isNegativePion) { + histos.fill(HIST(kParticlenames[1]) + HIST("/mc/h7dGen"), ft0ampl, nTracksGlobal, mcCollision.multMCNParticlesEta08(), pTmc, static_cast(upcCuts.genGapSide), ymc, mcCollision.generatorsID()); } - if (v0MC.pdgCode() == PDG_t::kLambda0Bar) { - histos.fill(HIST(kParticlenames[2]) + HIST("/mc/h7dGen"), centrality, nTracksGlobal, mcCollision.multMCNParticlesEta10(), pTmc, static_cast(upcCuts.genGapSide), ymc, mcCollision.generatorsID()); + if ((pdgV0 == PDG_t::kLambda0Bar) && isPositivePion && isNegativeProton) { + histos.fill(HIST(kParticlenames[2]) + HIST("/mc/h7dGen"), ft0ampl, nTracksGlobal, mcCollision.multMCNParticlesEta08(), pTmc, static_cast(upcCuts.genGapSide), ymc, mcCollision.generatorsID()); } } // V0 end @@ -2005,38 +2211,62 @@ struct Derivedupcanalysis { // Kinematics (|y| < rapidityCut) float pTmc = cascMC.ptMC(); float ymc = 1e3; - if (std::abs(cascMC.pdgCode()) == PDG_t::kXiMinus) - ymc = RecoDecay::y(std::array{cascMC.pxMC(), cascMC.pyMC(), cascMC.pzMC()}, o2::constants::physics::MassXiMinus); - else if (std::abs(cascMC.pdgCode()) == PDG_t::kOmegaMinus) - ymc = RecoDecay::y(std::array{cascMC.pxMC(), cascMC.pyMC(), cascMC.pzMC()}, o2::constants::physics::MassOmegaMinus); + if ((cascMC.pdgCode() == PDG_t::kXiMinus) || (cascMC.pdgCode() == PDG_t::kXiPlusBar)) { + ymc = cascMC.rapidityMC(0); + } else if ((cascMC.pdgCode() == PDG_t::kOmegaMinus) || (cascMC.pdgCode() == PDG_t::kOmegaPlusBar)) { + ymc = cascMC.rapidityMC(2); + } if (std::abs(ymc) > rapidityCut) continue; - auto mcCollision = cascMC.straMCCollision_as(); // take gen. collision + const auto& mcCollision = cascMC.straMCCollision_as(); // take gen. collision if (std::abs(mcCollision.posZ()) > maxZVtxPosition) continue; - float centrality = -1.f; + // float centrality = -1.f; + float ft0ampl = -1.f; int nTracksGlobal = -1; if (listBestCollisionIds[mcCollision.globalIndex()] > -1) { auto collision = collisions.iteratorAt(listBestCollisionIds[mcCollision.globalIndex()]); - centrality = collision.centFT0C(); - nTracksGlobal = collision.multNTracksGlobal(); + // centrality = collision.centFT0C(); + if (static_cast(upcCuts.genGapSide) == 0) { + ft0ampl = collision.totalFT0AmplitudeC(); + } else if (static_cast(upcCuts.genGapSide) == 1) { + ft0ampl = collision.totalFT0AmplitudeA(); + } } + const int pdgPos = cascMC.pdgCodePositive(); + const int pdgNeg = cascMC.pdgCodeNegative(); + const int pdgBach = cascMC.pdgCodeBachelor(); + const int pdgCasc = cascMC.pdgCode(); + + const bool isPositiveProton = (pdgPos == PDG_t::kProton); + + const bool isPositivePion = (pdgPos == PDG_t::kPiPlus); + const bool isBachelorPositivePion = (pdgBach == PDG_t::kPiPlus); + + const bool isNegativeProton = (pdgNeg == kProtonBar); + + const bool isNegativePion = (pdgNeg == PDG_t::kPiMinus); + const bool isBachelorNegativePion = (pdgBach == PDG_t::kPiMinus); + + const bool isBachelorPositiveKaon = (pdgBach == PDG_t::kKPlus); + const bool isBachelorNegativeKaon = (pdgBach == PDG_t::kKMinus); + // Fill histograms - if (cascMC.pdgCode() == PDG_t::kXiMinus) { - histos.fill(HIST(kParticlenames[3]) + HIST("/mc/h7dGen"), centrality, nTracksGlobal, mcCollision.multMCNParticlesEta10(), pTmc, static_cast(upcCuts.genGapSide), ymc, mcCollision.generatorsID()); + if ((pdgCasc == PDG_t::kXiMinus) && isPositiveProton && isNegativePion && isBachelorNegativePion) { + histos.fill(HIST(kParticlenames[3]) + HIST("/mc/h7dGen"), ft0ampl, nTracksGlobal, mcCollision.multMCNParticlesEta08(), pTmc, static_cast(upcCuts.genGapSide), ymc, mcCollision.generatorsID()); } - if (cascMC.pdgCode() == PDG_t::kXiPlusBar) { - histos.fill(HIST(kParticlenames[4]) + HIST("/mc/h7dGen"), centrality, nTracksGlobal, mcCollision.multMCNParticlesEta10(), pTmc, static_cast(upcCuts.genGapSide), ymc, mcCollision.generatorsID()); + if ((pdgCasc == PDG_t::kXiPlusBar) && isNegativeProton && isPositivePion && isBachelorPositivePion) { + histos.fill(HIST(kParticlenames[4]) + HIST("/mc/h7dGen"), ft0ampl, nTracksGlobal, mcCollision.multMCNParticlesEta08(), pTmc, static_cast(upcCuts.genGapSide), ymc, mcCollision.generatorsID()); } - if (cascMC.pdgCode() == PDG_t::kOmegaMinus) { - histos.fill(HIST(kParticlenames[5]) + HIST("/mc/h7dGen"), centrality, nTracksGlobal, mcCollision.multMCNParticlesEta10(), pTmc, static_cast(upcCuts.genGapSide), ymc, mcCollision.generatorsID()); + if ((pdgCasc == PDG_t::kOmegaMinus) && isPositiveProton && isNegativePion && isBachelorNegativeKaon) { + histos.fill(HIST(kParticlenames[5]) + HIST("/mc/h7dGen"), ft0ampl, nTracksGlobal, mcCollision.multMCNParticlesEta08(), pTmc, static_cast(upcCuts.genGapSide), ymc, mcCollision.generatorsID()); } - if (cascMC.pdgCode() == PDG_t::kOmegaPlusBar) { - histos.fill(HIST(kParticlenames[6]) + HIST("/mc/h7dGen"), centrality, nTracksGlobal, mcCollision.multMCNParticlesEta10(), pTmc, static_cast(upcCuts.genGapSide), ymc, mcCollision.generatorsID()); + if ((pdgCasc == PDG_t::kOmegaPlusBar) && isNegativeProton && isPositivePion && isBachelorPositiveKaon) { + histos.fill(HIST(kParticlenames[6]) + HIST("/mc/h7dGen"), ft0ampl, nTracksGlobal, mcCollision.multMCNParticlesEta08(), pTmc, static_cast(upcCuts.genGapSide), ymc, mcCollision.generatorsID()); } } // Cascade end } diff --git a/PWGLF/Tasks/Strangeness/lambdalambda.cxx b/PWGLF/Tasks/Strangeness/lambdalambda.cxx index 01fe793e2df..bf8579f105d 100644 --- a/PWGLF/Tasks/Strangeness/lambdalambda.cxx +++ b/PWGLF/Tasks/Strangeness/lambdalambda.cxx @@ -144,8 +144,7 @@ struct lambdalambda { ConfigurableAxis RadiusAxis{"RadiusAxis", {100, 0, 5}, "radius of v0v0"}; ConfigurableAxis CPAAxis{"CPAAxis", {102, -1.02, 1.02}, "CPA of v0v0"}; ConfigurableAxis DistanceAxis{"DistanceAxis", {100, 0, 10}, "distance of v0v0"}; - ConfigurableAxis DCARAxis{"DCARAxis", {100, 0, 2}, "DCA of v0v0R"}; - ConfigurableAxis DCAZAxis{"DCAZAxis", {100, -2, 2}, "DCA of v0v0Z"}; + ConfigurableAxis DCAAxis{"DCAAxis", {100, 0, 2}, "DCA of v0v0R"}; TF1* fMultPVCutLow = nullptr; TF1* fMultPVCutHigh = nullptr; @@ -169,14 +168,12 @@ struct lambdalambda { histos.add("Radius_V0V0_full", "", {HistType::kTHnSparseF, {massAxis, ptAxis, RadiusAxis, combAxis}}); histos.add("CPA_V0V0_full", "", {HistType::kTHnSparseF, {massAxis, ptAxis, CPAAxis, combAxis}}); histos.add("Distance_V0V0_full", "", {HistType::kTHnSparseF, {massAxis, ptAxis, DistanceAxis, combAxis}}); - histos.add("DCAR_V0V0_full", "", {HistType::kTHnSparseF, {massAxis, ptAxis, DCARAxis, combAxis}}); - histos.add("DCAZ_V0V0_full", "", {HistType::kTHnSparseF, {massAxis, ptAxis, DCAZAxis, combAxis}}); + histos.add("DCA_V0V0_full", "", {HistType::kTHnSparseF, {massAxis, ptAxis, DCAAxis, combAxis}}); histos.add("Radius_V0V0_sel", "", {HistType::kTHnSparseF, {massAxis, ptAxis, RadiusAxis, combAxis}}); histos.add("CPA_V0V0_sel", "", {HistType::kTHnSparseF, {massAxis, ptAxis, CPAAxis, combAxis}}); histos.add("Distance_V0V0_sel", "", {HistType::kTHnSparseF, {massAxis, ptAxis, DistanceAxis, combAxis}}); - histos.add("DCAR_V0V0_sel", "", {HistType::kTHnSparseF, {massAxis, ptAxis, DCARAxis, combAxis}}); - histos.add("DCAZ_V0V0_sel", "", {HistType::kTHnSparseF, {massAxis, ptAxis, DCAZAxis, combAxis}}); + histos.add("DCA_V0V0_sel", "", {HistType::kTHnSparseF, {massAxis, ptAxis, DCAAxis, combAxis}}); histos.add("h_InvMass_same", "", {HistType::kTHnSparseF, {massAxis, ptAxis, centAxis, combAxis}}); histos.add("h_InvMass_mixed", "", {HistType::kTHnSparseF, {massAxis, ptAxis, centAxis, combAxis}}); diff --git a/PWGLF/Tasks/Strangeness/sigmaanalysis.cxx b/PWGLF/Tasks/Strangeness/sigmaanalysis.cxx index f2e04920d50..2e88ccc50b4 100644 --- a/PWGLF/Tasks/Strangeness/sigmaanalysis.cxx +++ b/PWGLF/Tasks/Strangeness/sigmaanalysis.cxx @@ -37,7 +37,6 @@ #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/PIDResponse.h" -#include "Common/CCDB/ctpRateFetcher.h" #include "PWGLF/DataModel/LFStrangenessTables.h" #include "PWGLF/DataModel/LFStrangenessPIDTables.h" #include "PWGLF/DataModel/LFStrangenessMLTables.h" @@ -58,47 +57,31 @@ using std::array; using V0MCSigmas = soa::Join; using V0Sigmas = soa::Join; +static const std::vector PhotonSels = {"NoSel", "V0Type", "DaupT", "DCADauToPV", + "DCADau", "DauTPCCR", "TPCNSigmaEl", "V0pT", + "Y", "V0Radius", "RZCut", "Armenteros", "CosPA", + "PsiPair", "Phi", "Mass"}; + +static const std::vector LambdaSels = {"NoSel", "V0Radius", "DCADau", "Armenteros", + "CosPA", "Y", "TPCCR", "DauITSCls", "Lifetime", + "TPCTOFPID", "DCADauToPV", "Mass"}; + +static const std::vector DirList = {"BeforeSel", "AfterSel"}; + struct sigmaanalysis { - Service ccdb; - ctpRateFetcher rateFetcher; HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + Configurable fillQAhistos{"fillQAhistos", false, "if true, fill QA histograms"}; + Configurable fillBkgQAhistos{"fillBkgQAhistos", false, "if true, fill MC QA histograms for Bkg study. Only works with MC."}; + Configurable fillpTResoQAhistos{"fillpTResoQAhistos", false, "if true, fill MC QA histograms for pT resolution study. Only works with MC."}; + // Interaction rate selection: - // Event selection - Configurable doPPAnalysis{"doPPAnalysis", true, "if in pp, set to true"}; Configurable fGetIR{"fGetIR", false, "Flag to retrieve the IR info."}; - Configurable irSource{"irSource", "T0VTX", "Estimator of the interaction rate (Recommended: pp --> T0VTX, Pb-Pb --> ZNC hadronic)"}; Configurable minIR{"minIR", -1, "Min Interaction Rate (kHz). Leave -1 if no selection desired."}; Configurable maxIR{"maxIR", -1, "Max Interaction Rate (kHz). Leave -1 if no selection desired."}; - struct : ConfigurableGroup { - Configurable requireSel8{"requireSel8", true, "require sel8 event selection"}; - Configurable requireTriggerTVX{"requireTriggerTVX", true, "require FT0 vertex (acceptable FT0C-FT0A time difference) at trigger level"}; - Configurable rejectITSROFBorder{"rejectITSROFBorder", true, "reject events at ITS ROF border"}; - Configurable rejectTFBorder{"rejectTFBorder", true, "reject events at TF border"}; - Configurable requireIsVertexITSTPC{"requireIsVertexITSTPC", true, "require events with at least one ITS-TPC track"}; - Configurable requireIsGoodZvtxFT0VsPV{"requireIsGoodZvtxFT0VsPV", true, "require events with PV position along z consistent (within 1 cm) between PV reconstructed using tracks and PV using FT0 A-C time difference"}; - Configurable requireIsVertexTOFmatched{"requireIsVertexTOFmatched", false, "require events with at least one of vertex contributors matched to TOF"}; - Configurable requireIsVertexTRDmatched{"requireIsVertexTRDmatched", false, "require events with at least one of vertex contributors matched to TRD"}; - Configurable rejectSameBunchPileup{"rejectSameBunchPileup", false, "reject collisions in case of pileup with another collision in the same foundBC"}; - Configurable requireNoCollInTimeRangeStd{"requireNoCollInTimeRangeStd", false, "reject collisions corrupted by the cannibalism, with other collisions within +/- 2 microseconds or mult above a certain threshold in -4 - -2 microseconds"}; - Configurable requireNoCollInTimeRangeStrict{"requireNoCollInTimeRangeStrict", false, "reject collisions corrupted by the cannibalism, with other collisions within +/- 10 microseconds"}; - Configurable requireNoCollInTimeRangeNarrow{"requireNoCollInTimeRangeNarrow", false, "reject collisions corrupted by the cannibalism, with other collisions within +/- 2 microseconds"}; - Configurable requireNoCollInTimeRangeVzDep{"requireNoCollInTimeRangeVzDep", false, "reject collisions corrupted by the cannibalism, with other collisions with pvZ of drifting TPC tracks from past/future collisions within 2.5 cm the current pvZ"}; - Configurable requireNoCollInROFStd{"requireNoCollInROFStd", false, "reject collisions corrupted by the cannibalism, with other collisions within the same ITS ROF with mult. above a certain threshold"}; - Configurable requireNoCollInROFStrict{"requireNoCollInROFStrict", false, "reject collisions corrupted by the cannibalism, with other collisions within the same ITS ROF"}; - Configurable requireINEL0{"requireINEL0", false, "require INEL>0 event selection"}; - Configurable requireINEL1{"requireINEL1", false, "require INEL>1 event selection"}; - Configurable maxZVtxPosition{"maxZVtxPosition", 10., "max Z vtx position"}; - Configurable useFT0CbasedOccupancy{"useFT0CbasedOccupancy", false, "Use sum of FT0-C amplitudes for estimating occupancy? (if not, use track-based definition)"}; - // fast check on occupancy - Configurable minOccupancy{"minOccupancy", -1, "minimum occupancy from neighbouring collisions"}; - Configurable maxOccupancy{"maxOccupancy", -1, "maximum occupancy from neighbouring collisions"}; - } eventSelections; - // Analysis strategy: Configurable fUseMLSel{"fUseMLSel", false, "Flag to use ML selection. If False, the standard selection is applied."}; - Configurable fProcessMonteCarlo{"fProcessMonteCarlo", false, "Flag to process MC data."}; Configurable fselLambdaTPCPID{"fselLambdaTPCPID", true, "Flag to select lambda-like candidates using TPC NSigma."}; Configurable fselLambdaTOFPID{"fselLambdaTOFPID", false, "Flag to select lambda-like candidates using TOF NSigma."}; Configurable doMCAssociation{"doMCAssociation", false, "Flag to process only signal candidates. Use only with processMonteCarlo!"}; @@ -143,8 +126,6 @@ struct sigmaanalysis { Configurable PhotonMinTPCCrossedRows{"PhotonMinTPCCrossedRows", 30, "Min daughter TPC Crossed Rows"}; Configurable PhotonMinTPCNSigmas{"PhotonMinTPCNSigmas", -7, "Min TPC NSigmas for daughters"}; Configurable PhotonMaxTPCNSigmas{"PhotonMaxTPCNSigmas", 7, "Max TPC NSigmas for daughters"}; - Configurable PiMaxTPCNSigmas{"PiMaxTPCNSigmas", 1, "Max TPC NSigmas for pi rejection"}; - Configurable piMaxpT{"piMaxpT", 3.5, "Max pT for pi rejection"}; Configurable PhotonMinPt{"PhotonMinPt", 0.0, "Min photon pT (GeV/c)"}; Configurable PhotonMaxPt{"PhotonMaxPt", 50.0, "Max photon pT (GeV/c)"}; Configurable PhotonMaxRap{"PhotonMaxRap", 0.5, "Max photon rapidity"}; @@ -158,10 +139,10 @@ struct sigmaanalysis { Configurable PhotonPsiPairMax{"PhotonPsiPairMax", 1e+9, "maximum psi angle of the track pair"}; Configurable PhotonMaxDauEta{"PhotonMaxDauEta", 0.8, "Max pseudorapidity of daughter tracks"}; Configurable PhotonLineCutZ0{"PhotonLineCutZ0", 7.0, "The offset for the linecute used in the Z vs R plot"}; - Configurable PhotonPhiMin1{"PhotonPhiMin1", -1, "Phi min value for photons, region 1 (leave negative if no selection desired)"}; - Configurable PhotonPhiMax1{"PhotonPhiMax1", -1, "Phi max value for photons, region 1 (leave negative if no selection desired)"}; - Configurable PhotonPhiMin2{"PhotonPhiMin2", -1, "Phi max value for photons, region 2 (leave negative if no selection desired)"}; - Configurable PhotonPhiMax2{"PhotonPhiMax2", -1, "Phi min value for photons, region 2 (leave negative if no selection desired)"}; + Configurable PhotonPhiMin1{"PhotonPhiMin1", -1, "Phi min value to reject photons, region 1 (leave negative if no selection desired)"}; + Configurable PhotonPhiMax1{"PhotonPhiMax1", -1, "Phi max value to reject photons, region 1 (leave negative if no selection desired)"}; + Configurable PhotonPhiMin2{"PhotonPhiMin2", -1, "Phi max value to reject photons, region 2 (leave negative if no selection desired)"}; + Configurable PhotonPhiMax2{"PhotonPhiMax2", -1, "Phi min value to reject photons, region 2 (leave negative if no selection desired)"}; Configurable SigmaMaxRap{"SigmaMaxRap", 0.5, "Max sigma0 rapidity"}; @@ -172,12 +153,12 @@ struct sigmaanalysis { ConfigurableAxis axisInvPt{"axisInvPt", {VARIABLE_WIDTH, 0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 2.0, 5.0, 10.0, 20.0, 50.0}, ""}; ConfigurableAxis axisDeltaPt{"axisDeltaPt", {400, -50.0, 50.0}, ""}; ConfigurableAxis axisRapidity{"axisRapidity", {100, -2.0f, 2.0f}, "Rapidity"}; - ConfigurableAxis axisIRBinning{"axisIRBinning", {5000, 0, 1500}, "Binning for the interaction rate (kHz)"}; + ConfigurableAxis axisIRBinning{"axisIRBinning", {150, 0, 1500}, "Binning for the interaction rate (kHz)"}; // Invariant Mass - ConfigurableAxis axisSigmaMass{"axisSigmaMass", {1000, 1.10f, 1.30f}, "M_{#Sigma^{0}} (GeV/c^{2})"}; + ConfigurableAxis axisSigmaMass{"axisSigmaMass", {500, 1.10f, 1.30f}, "M_{#Sigma^{0}} (GeV/c^{2})"}; ConfigurableAxis axisLambdaMass{"axisLambdaMass", {200, 1.05f, 1.151f}, "M_{#Lambda} (GeV/c^{2})"}; - ConfigurableAxis axisPhotonMass{"axisPhotonMass", {600, -0.1f, 0.5f}, "M_{#Gamma}"}; + ConfigurableAxis axisPhotonMass{"axisPhotonMass", {200, -0.1f, 0.5f}, "M_{#Gamma}"}; // AP plot axes ConfigurableAxis axisAPAlpha{"axisAPAlpha", {220, -1.1f, 1.1f}, "V0 AP alpha"}; @@ -189,422 +170,711 @@ struct sigmaanalysis { ConfigurableAxis axisChi2PerNcl{"axisChi2PerNcl", {80, -40, 40}, "Chi2 Per Ncl"}; ConfigurableAxis axisTPCNSigma{"axisTPCNSigma", {120, -30, 30}, "TPC NSigma"}; ConfigurableAxis axisTOFNSigma{"axisTOFNSigma", {120, -30, 30}, "TOF NSigma"}; - ConfigurableAxis axisLifetime{"axisLifetime", {200, 0, 200}, "Chi2 Per Ncl"}; + ConfigurableAxis axisLifetime{"axisLifetime", {100, 0, 100}, "Chi2 Per Ncl"}; // topological variable QA axes ConfigurableAxis axisRadius{"axisRadius", {240, 0.0f, 120.0f}, "V0 radius (cm)"}; ConfigurableAxis axisDCAtoPV{"axisDCAtoPV", {500, 0.0f, 50.0f}, "DCA (cm)"}; ConfigurableAxis axisDCAdau{"axisDCAdau", {50, 0.0f, 5.0f}, "DCA (cm)"}; ConfigurableAxis axisCosPA{"axisCosPA", {200, 0.5f, 1.0f}, "Cosine of pointing angle"}; - ConfigurableAxis axisPsiPair{"axisPsiPair", {500, -5.0f, 5.0f}, "Psipair for photons"}; - ConfigurableAxis axisCandSel{"axisCandSel", {32, 0.5f, +32.5f}, "Candidate Selection"}; + ConfigurableAxis axisPA{"axisPA", {100, 0.0f, 1}, "Pointing angle"}; + ConfigurableAxis axisPsiPair{"axisPsiPair", {250, -5.0f, 5.0f}, "Psipair for photons"}; + ConfigurableAxis axisPhi{"axisPhi", {200, 0, 2 * o2::constants::math::PI}, "Phi for photons"}; + ConfigurableAxis axisZ{"axisZ", {120, -120.0f, 120.0f}, "V0 Z position (cm)"}; + + ConfigurableAxis axisCandSel{"axisCandSel", {20, 0.5f, +20.5f}, "Candidate Selection"}; // ML ConfigurableAxis MLProb{"MLOutput", {100, 0.0f, 1.0f}, ""}; - int nSigmaCandidates = 0; + void init(InitContext const&) { - // setting CCDB service - ccdb->setURL("http://alice-ccdb.cern.ch"); - ccdb->setCaching(true); - ccdb->setFatalWhenNull(false); - - // Event Counters - histos.add("hEventSelection", "hEventSelection", kTH1F, {{20, -0.5f, +18.5f}}); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(1, "All collisions"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(2, "sel8 cut"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(3, "kIsTriggerTVX"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(4, "kNoITSROFrameBorder"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(5, "kNoTimeFrameBorder"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(6, "posZ cut"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(7, "kIsVertexITSTPC"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(8, "kIsGoodZvtxFT0vsPV"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(9, "kIsVertexTOFmatched"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(10, "kIsVertexTRDmatched"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(11, "kNoSameBunchPileup"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(12, "kNoCollInTimeRangeStd"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(13, "kNoCollInTimeRangeStrict"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(14, "kNoCollInTimeRangeNarrow"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(15, "kNoCollInRofStd"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(16, "kNoCollInRofStrict"); - if (doPPAnalysis) { - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(17, "INEL>0"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(18, "INEL>1"); + + for (const auto& histodir : DirList) { + + histos.add(histodir + "/Photon/hTrackCode", "hTrackCode", kTH1F, {{11, 0.5f, 11.5f}}); + histos.add(histodir + "/Photon/hV0Type", "hV0Type", kTH1F, {{8, 0.5f, 8.5f}}); + histos.add(histodir + "/Photon/hNegpT", "hNegpT", kTH1F, {axisPt}); + histos.add(histodir + "/Photon/hPospT", "hPospT", kTH1F, {axisPt}); + histos.add(histodir + "/Photon/hDCANegToPV", "hDCANegToPV", kTH1F, {axisDCAtoPV}); + histos.add(histodir + "/Photon/hDCAPosToPV", "hDCAPosToPV", kTH1F, {axisDCAtoPV}); + histos.add(histodir + "/Photon/hDCADau", "hDCADau", kTH1F, {axisDCAdau}); + histos.add(histodir + "/Photon/hPosTPCCR", "hPosTPCCR", kTH1F, {axisTPCrows}); + histos.add(histodir + "/Photon/hNegTPCCR", "hNegTPCCR", kTH1F, {axisTPCrows}); + histos.add(histodir + "/Photon/h2dPosTPCNSigmaEl", "h2dPosTPCNSigmaEl", kTH2F, {axisPt, axisTPCNSigma}); + histos.add(histodir + "/Photon/h2dNegTPCNSigmaEl", "h2dNegTPCNSigmaEl", kTH2F, {axisPt, axisTPCNSigma}); + histos.add(histodir + "/Photon/h2dPosTPCNSigmaPi", "h2dPosTPCNSigmaPi", kTH2F, {axisPt, axisTPCNSigma}); + histos.add(histodir + "/Photon/h2dNegTPCNSigmaPi", "h2dNegTPCNSigmaPi", kTH2F, {axisPt, axisTPCNSigma}); + histos.add(histodir + "/Photon/hpT", "hpT", kTH1F, {axisPt}); + histos.add(histodir + "/Photon/hY", "hY", kTH1F, {axisRapidity}); + histos.add(histodir + "/Photon/hPosEta", "hPosEta", kTH1F, {axisRapidity}); + histos.add(histodir + "/Photon/hNegEta", "hNegEta", kTH1F, {axisRapidity}); + histos.add(histodir + "/Photon/hRadius", "hRadius", kTH1F, {axisRadius}); + histos.add(histodir + "/Photon/hZ", "hZ", kTH1F, {axisZ}); + histos.add(histodir + "/Photon/h2dRZCut", "h2dRZCut", kTH2F, {axisZ, axisRadius}); + histos.add(histodir + "/Photon/h2dRZPlane", "h2dRZPlane", kTH2F, {axisZ, axisRadius}); + histos.add(histodir + "/Photon/hCosPA", "hCosPA", kTH1F, {axisCosPA}); + histos.add(histodir + "/Photon/hPsiPair", "hPsiPair", kTH1F, {axisPsiPair}); + histos.add(histodir + "/Photon/hPhi", "hPhi", kTH1F, {axisPhi}); + histos.add(histodir + "/Photon/h3dMass", "h3dMass", kTH3F, {axisCentrality, axisPt, axisPhotonMass}); + histos.add(histodir + "/Photon/hMass", "hMass", kTH1F, {axisPhotonMass}); + + histos.add(histodir + "/Lambda/hTrackCode", "hTrackCode", kTH1F, {{11, 0.5f, 11.5f}}); + histos.add(histodir + "/Lambda/hRadius", "hRadius", kTH1F, {axisRadius}); + histos.add(histodir + "/Lambda/hDCADau", "hDCADau", kTH1F, {axisDCAdau}); + histos.add(histodir + "/Lambda/hCosPA", "hCosPA", kTH1F, {axisCosPA}); + histos.add(histodir + "/Lambda/hY", "hY", kTH1F, {axisRapidity}); + histos.add(histodir + "/Lambda/hPosEta", "hPosEta", kTH1F, {axisRapidity}); + histos.add(histodir + "/Lambda/hNegEta", "hNegEta", kTH1F, {axisRapidity}); + histos.add(histodir + "/Lambda/hPosTPCCR", "hPosTPCCR", kTH1F, {axisTPCrows}); + histos.add(histodir + "/Lambda/hNegTPCCR", "hNegTPCCR", kTH1F, {axisTPCrows}); + histos.add(histodir + "/Lambda/hPosITSCls", "hPosITSCls", kTH1F, {axisNCls}); + histos.add(histodir + "/Lambda/hNegITSCls", "hNegITSCls", kTH1F, {axisNCls}); + histos.add(histodir + "/Lambda/hPosChi2PerNc", "hPosChi2PerNc", kTH1F, {axisChi2PerNcl}); + histos.add(histodir + "/Lambda/hNegChi2PerNc", "hNegChi2PerNc", kTH1F, {axisChi2PerNcl}); + histos.add(histodir + "/Lambda/hLifeTime", "hLifeTime", kTH1F, {axisLifetime}); + histos.add(histodir + "/Lambda/h2dTPCvsTOFNSigma_LambdaPr", "h2dTPCvsTOFNSigma_LambdaPr", kTH2F, {axisTPCNSigma, axisTOFNSigma}); + histos.add(histodir + "/Lambda/h2dTPCvsTOFNSigma_LambdaPi", "h2dTPCvsTOFNSigma_LambdaPi", kTH2F, {axisTPCNSigma, axisTOFNSigma}); + histos.add(histodir + "/Lambda/hLambdaDCANegToPV", "hLambdaDCANegToPV", kTH1F, {axisDCAtoPV}); + histos.add(histodir + "/Lambda/hLambdaDCAPosToPV", "hLambdaDCAPosToPV", kTH1F, {axisDCAtoPV}); + histos.add(histodir + "/Lambda/hLambdapT", "hLambdapT", kTH1F, {axisPt}); + histos.add(histodir + "/Lambda/hLambdaMass", "hLambdaMass", kTH1F, {axisLambdaMass}); + histos.add(histodir + "/Lambda/h3dLambdaMass", "h3dLambdaMass", kTH3F, {axisCentrality, axisPt, axisLambdaMass}); + histos.add(histodir + "/Lambda/h2dTPCvsTOFNSigma_ALambdaPr", "h2dTPCvsTOFNSigma_ALambdaPr", kTH2F, {axisTPCNSigma, axisTOFNSigma}); + histos.add(histodir + "/Lambda/h2dTPCvsTOFNSigma_ALambdaPi", "h2dTPCvsTOFNSigma_ALambdaPi", kTH2F, {axisTPCNSigma, axisTOFNSigma}); + histos.add(histodir + "/Lambda/hALambdaDCANegToPV", "hALambdaDCANegToPV", kTH1F, {axisDCAtoPV}); + histos.add(histodir + "/Lambda/hALambdaDCAPosToPV", "hALambdaDCAPosToPV", kTH1F, {axisDCAtoPV}); + histos.add(histodir + "/Lambda/hALambdapT", "hALambdapT", kTH1F, {axisPt}); + histos.add(histodir + "/Lambda/hAntiLambdaMass", "hAntiLambdaMass", kTH1F, {axisLambdaMass}); + histos.add(histodir + "/Lambda/h3dAntiLambdaMass", "h3dAntiLambdaMass", kTH3F, {axisCentrality, axisPt, axisLambdaMass}); + + histos.add(histodir + "/h2dArmenteros", "h2dArmenteros", kTH2F, {axisAPAlpha, axisAPQt}); + + histos.add(histodir + "/Sigma0/hMass", "hMass", kTH1F, {axisSigmaMass}); + histos.add(histodir + "/Sigma0/hPt", "hPt", kTH1F, {axisPt}); + histos.add(histodir + "/Sigma0/hY", "hY", kTH1F, {axisRapidity}); + histos.add(histodir + "/Sigma0/h3dMass", "h3dMass", kTH3F, {axisCentrality, axisPt, axisSigmaMass}); + histos.add(histodir + "/Sigma0/h3dPhotonRadiusVsMassSigma", "h3dPhotonRadiusVsMassSigma", kTH3F, {axisCentrality, axisRadius, axisSigmaMass}); + histos.add(histodir + "/Sigma0/h2dpTVsOPAngle", "h2dpTVsOPAngle", kTH2F, {axisPt, {140, 0.0f, +7.0f}}); + + histos.add(histodir + "/ASigma0/hMass", "hMass", kTH1F, {axisSigmaMass}); + histos.add(histodir + "/ASigma0/hPt", "hPt", kTH1F, {axisPt}); + histos.add(histodir + "/ASigma0/hY", "hY", kTH1F, {axisRapidity}); + histos.add(histodir + "/ASigma0/h3dMass", "h3dMass", kTH3F, {axisCentrality, axisPt, axisSigmaMass}); + histos.add(histodir + "/ASigma0/h3dPhotonRadiusVsMassSigma", "h3dPhotonRadiusVsMassSigma", kTH3F, {axisCentrality, axisRadius, axisSigmaMass}); + histos.add(histodir + "/ASigma0/h2dpTVsOPAngle", "h2dpTVsOPAngle", kTH2F, {axisPt, {140, 0.0f, +7.0f}}); + + // Process MC + if (doprocessMonteCarlo) { + histos.add(histodir + "/MC/Photon/hV0ToCollAssoc", "hV0ToCollAssoc", kTH1F, {{2, 0.0f, 2.0f}}); + histos.add(histodir + "/MC/Photon/hPt", "hPt", kTH1F, {axisPt}); + histos.add(histodir + "/MC/Photon/hMCPt", "hMCPt", kTH1F, {axisPt}); + histos.add(histodir + "/MC/Photon/h2dPosTPCNSigmaEl", "h2dPosTPCNSigmaEl", kTH2F, {axisPt, axisTPCNSigma}); + histos.add(histodir + "/MC/Photon/h2dNegTPCNSigmaEl", "h2dNegTPCNSigmaEl", kTH2F, {axisPt, axisTPCNSigma}); + histos.add(histodir + "/MC/Photon/h2dPosTPCNSigmaPi", "h2dPosTPCNSigmaPi", kTH2F, {axisPt, axisTPCNSigma}); + histos.add(histodir + "/MC/Photon/h2dNegTPCNSigmaPi", "h2dNegTPCNSigmaPi", kTH2F, {axisPt, axisTPCNSigma}); + histos.add(histodir + "/MC/Photon/h2dIRVsPt", "h2dIRVsPt", kTH2F, {axisIRBinning, axisPt}); + histos.add(histodir + "/MC/Photon/h3dPAVsIRVsPt", "h3dPAVsIRVsPt", kTH3F, {axisPA, axisIRBinning, axisPt}); + histos.add(histodir + "/MC/Photon/h2dIRVsPt_BadCollAssig", "h2dIRVsPt_BadCollAssig", kTH2F, {axisIRBinning, axisPt}); + histos.add(histodir + "/MC/Photon/h3dPAVsIRVsPt_BadCollAssig", "h3dPAVsIRVsPt_BadCollAssig", kTH3F, {axisPA, axisIRBinning, axisPt}); + + histos.add(histodir + "/MC/Lambda/hV0ToCollAssoc", "hV0ToCollAssoc", kTH1F, {{2, 0.0f, 2.0f}}); + histos.add(histodir + "/MC/Lambda/hPt", "hPt", kTH1F, {axisPt}); + histos.add(histodir + "/MC/Lambda/hMCPt", "hMCPt", kTH1F, {axisPt}); + histos.add(histodir + "/MC/Lambda/h3dTPCvsTOFNSigma_Pr", "h3dTPCvsTOFNSigma_Pr", kTH3F, {axisTPCNSigma, axisTOFNSigma, axisPt}); + histos.add(histodir + "/MC/Lambda/h3dTPCvsTOFNSigma_Pi", "h3dTPCvsTOFNSigma_Pi", kTH3F, {axisTPCNSigma, axisTOFNSigma, axisPt}); + + histos.add(histodir + "/MC/ALambda/hV0ToCollAssoc", "hV0ToCollAssoc", kTH1F, {{2, 0.0f, 2.0f}}); + histos.add(histodir + "/MC/ALambda/hPt", "hPt", kTH1F, {axisPt}); + histos.add(histodir + "/MC/ALambda/hMCPt", "hMCPt", kTH1F, {axisPt}); + histos.add(histodir + "/MC/ALambda/h3dTPCvsTOFNSigma_Pr", "h3dTPCvsTOFNSigma_Pr", kTH3F, {axisTPCNSigma, axisTOFNSigma, axisPt}); + histos.add(histodir + "/MC/ALambda/h3dTPCvsTOFNSigma_Pi", "h3dTPCvsTOFNSigma_Pi", kTH3F, {axisTPCNSigma, axisTOFNSigma, axisPt}); + + histos.add(histodir + "/MC/h2dArmenteros", "h2dArmenteros", kTH2F, {axisAPAlpha, axisAPQt}); + + histos.add(histodir + "/MC/Sigma0/hPt", "hPt", kTH1F, {axisPt}); + histos.add(histodir + "/MC/Sigma0/hMCPt", "hMCPt", kTH1F, {axisPt}); + histos.add(histodir + "/MC/Sigma0/h2dMCPtVsLambdaMCPt", "h2dMCPtVsLambdaMCPt", kTH2F, {axisPt, axisPt}); + histos.add(histodir + "/MC/Sigma0/h2dMCPtVsGammaMCPt", "h2dMCPtVsGammaMCPt", kTH2F, {axisPt, axisPt}); + histos.add(histodir + "/MC/Sigma0/hMass", "hMass", kTH1F, {axisSigmaMass}); + histos.add(histodir + "/MC/Sigma0/h3dMass", "h3dMass", kTH3F, {axisCentrality, axisPt, axisSigmaMass}); + + histos.add(histodir + "/MC/ASigma0/hPt", "hPt", kTH1F, {axisPt}); + histos.add(histodir + "/MC/ASigma0/hMCPt", "hMCPt", kTH1F, {axisPt}); + histos.add(histodir + "/MC/ASigma0/h2dMCPtVsLambdaMCPt", "h2dMCPtVsLambdaMCPt", kTH2F, {axisPt, axisPt}); + histos.add(histodir + "/MC/ASigma0/h2dMCPtVsPhotonMCPt", "h2dMCPtVsPhotonMCPt", kTH2F, {axisPt, axisPt}); + histos.add(histodir + "/MC/ASigma0/hMass", "hMass", kTH1F, {axisSigmaMass}); + histos.add(histodir + "/MC/ASigma0/h3dMass", "h3dMass", kTH3F, {axisCentrality, axisPt, axisSigmaMass}); + + // 1/pT Resolution: + if (fillpTResoQAhistos && histodir == "BeforeSel") { + histos.add(histodir + "/MC/pTReso/h3dGammaPtResoVsTPCCR", "h3dGammaPtResoVsTPCCR", kTH3F, {axisInvPt, axisDeltaPt, axisTPCrows}); + histos.add(histodir + "/MC/pTReso/h3dGammaPtResoVsTPCCR", "h3dGammaPtResoVsTPCCR", kTH3F, {axisInvPt, axisDeltaPt, axisTPCrows}); + histos.add(histodir + "/MC/pTReso/h2dGammaPtResolution", "h2dGammaPtResolution", kTH2F, {axisInvPt, axisDeltaPt}); + histos.add(histodir + "/MC/pTReso/h2dLambdaPtResolution", "h2dLambdaPtResolution", kTH2F, {axisInvPt, axisDeltaPt}); + histos.add(histodir + "/MC/pTReso/h3dLambdaPtResoVsTPCCR", "h3dLambdaPtResoVsTPCCR", kTH3F, {axisInvPt, axisDeltaPt, axisTPCrows}); + histos.add(histodir + "/MC/pTReso/h3dLambdaPtResoVsTPCCR", "h3dLambdaPtResoVsTPCCR", kTH3F, {axisInvPt, axisDeltaPt, axisTPCrows}); + histos.add(histodir + "/MC/pTReso/h2dAntiLambdaPtResolution", "h2dAntiLambdaPtResolution", kTH2F, {axisInvPt, axisDeltaPt}); + histos.add(histodir + "/MC/pTReso/h3dAntiLambdaPtResoVsTPCCR", "h3dAntiLambdaPtResoVsTPCCR", kTH3F, {axisInvPt, axisDeltaPt, axisTPCrows}); + histos.add(histodir + "/MC/pTReso/h3dAntiLambdaPtResoVsTPCCR", "h3dAntiLambdaPtResoVsTPCCR", kTH3F, {axisInvPt, axisDeltaPt, axisTPCrows}); + histos.add(histodir + "/MC/pTReso/h2dSigma0PtResolution", "h2dSigma0PtResolution", kTH2F, {axisInvPt, axisDeltaPt}); + histos.add(histodir + "/MC/pTReso/h2dAntiSigma0PtResolution", "h2dAntiSigma0PtResolution", kTH2F, {axisInvPt, axisDeltaPt}); + } + + // For background decomposition study + if (fillBkgQAhistos) { + histos.add(histodir + "/MC/BkgStudy/h2dPtVsMassSigma_All", "h2dPtVsMassSigma_All", kTH2F, {axisPt, axisSigmaMass}); + histos.add(histodir + "/MC/BkgStudy/h2dPtVsMassSigma_TrueDaughters", "h2dPtVsMassSigma_TrueDaughters", kTH2F, {axisPt, axisSigmaMass}); + histos.add(histodir + "/MC/BkgStudy/h2dTrueDaughtersMatrix", "h2dTrueDaughtersMatrix", kTHnSparseD, {{10001, -5000.5f, +5000.5f}, {10001, -5000.5f, +5000.5f}}); + histos.add(histodir + "/MC/BkgStudy/h2dPtVsMassSigma_TrueGammaFakeLambda", "h2dPtVsMassSigma_TrueGammaFakeLambda", kTH2F, {axisPt, axisSigmaMass}); + histos.add(histodir + "/MC/BkgStudy/h2dPtVsMassSigma_FakeGammaTrueLambda", "h2dPtVsMassSigma_FakeGammaTrueLambda", kTH2F, {axisPt, axisSigmaMass}); + histos.add(histodir + "/MC/BkgStudy/h2dPtVsMassSigma_FakeDaughters", "h2dPtVsMassSigma_FakeDaughters", kTH2F, {axisPt, axisSigmaMass}); + } + } + } + + // Selections + histos.add("Selection/Photon/hCandidateSel", "hCandidateSel", kTH1F, {axisCandSel}); + histos.add("Selection/Lambda/hCandidateSel", "hCandidateSel", kTH1F, {axisCandSel}); + + for (size_t i = 0; i < PhotonSels.size(); ++i) { + const auto& sel = PhotonSels[i]; + + histos.add(Form("Selection/Photon/h2d%s", sel.c_str()), ("h2d" + sel).c_str(), kTH2F, {axisPt, axisPhotonMass}); + histos.get(HIST("Selection/Photon/hCandidateSel"))->GetXaxis()->SetBinLabel(i + 1, sel.c_str()); + histos.add(Form("Selection/Sigma0/h2dPhoton%s", sel.c_str()), ("h2dPhoton" + sel).c_str(), kTH2F, {axisPt, axisSigmaMass}); + } + + for (size_t i = 0; i < LambdaSels.size(); ++i) { + const auto& sel = LambdaSels[i]; + + histos.add(Form("Selection/Lambda/h2d%s", sel.c_str()), ("h2d" + sel).c_str(), kTH2F, {axisPt, axisLambdaMass}); + histos.get(HIST("Selection/Lambda/hCandidateSel"))->GetXaxis()->SetBinLabel(i + 1, sel.c_str()); + histos.add(Form("Selection/Sigma0/h2dLambda%s", sel.c_str()), ("h2dLambda" + sel).c_str(), kTH2F, {axisPt, axisSigmaMass}); + } + } + + //__________________________________________ + template + int retrieveV0TrackCode(TV0Object const& sigma) + { + + int TrkCode = 10; // 1: TPC-only, 2: TPC+Something, 3: ITS-Only, 4: ITS+TPC + Something, 10: anything else + + if (isGamma) { + if (sigma.photonPosTrackCode() == 1 && sigma.photonNegTrackCode() == 1) + TrkCode = 1; + if ((sigma.photonPosTrackCode() != 1 && sigma.photonNegTrackCode() == 1) || (sigma.photonPosTrackCode() == 1 && sigma.photonNegTrackCode() != 1)) + TrkCode = 2; + if (sigma.photonPosTrackCode() == 3 && sigma.photonNegTrackCode() == 3) + TrkCode = 3; + if (sigma.photonPosTrackCode() == 2 || sigma.photonNegTrackCode() == 2) + TrkCode = 4; } else { - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(17, "Below min occup."); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(18, "Above max occup."); + if (sigma.lambdaPosTrackCode() == 1 && sigma.lambdaNegTrackCode() == 1) + TrkCode = 1; + if ((sigma.lambdaPosTrackCode() != 1 && sigma.lambdaNegTrackCode() == 1) || (sigma.lambdaPosTrackCode() == 1 && sigma.lambdaNegTrackCode() != 1)) + TrkCode = 2; + if (sigma.lambdaPosTrackCode() == 3 && sigma.lambdaNegTrackCode() == 3) + TrkCode = 3; + if (sigma.lambdaPosTrackCode() == 2 || sigma.lambdaNegTrackCode() == 2) + TrkCode = 4; } - // All candidates received - histos.add("GeneralQA/hInteractionRate", "hInteractionRate", kTH1F, {axisIRBinning}); - histos.add("GeneralQA/hInteractionRatePerColl", "hInteractionRatePerColl", kTH1F, {axisIRBinning}); - histos.add("GeneralQA/hCentralityVsInteractionRate", "hCentralityVsInteractionRate", kTH2F, {axisCentrality, axisIRBinning}); - histos.add("GeneralQA/hCentralityVsInteractionRatePerColl", "hCentralityVsInteractionRatePerColl", kTH2F, {axisCentrality, axisIRBinning}); - histos.add("GeneralQA/h2dArmenterosBeforeSel", "h2dArmenterosBeforeSel", {HistType::kTH2F, {axisAPAlpha, axisAPQt}}); - histos.add("GeneralQA/h2dArmenterosAfterSel", "h2dArmenterosAfterSel", {HistType::kTH2F, {axisAPAlpha, axisAPQt}}); - histos.add("GeneralQA/hMassSigma0BeforeSel", "hMassSigma0BeforeSel", kTH1F, {axisSigmaMass}); - - // Candidates Counters - histos.add("GeneralQA/hCandidateAnalysisSelection", "hCandidateAnalysisSelection", kTH1F, {axisCandSel}); - histos.get(HIST("GeneralQA/hCandidateAnalysisSelection"))->GetXaxis()->SetBinLabel(1, "No Sel"); - histos.get(HIST("GeneralQA/hCandidateAnalysisSelection"))->GetXaxis()->SetBinLabel(2, "Photon V0Type"); - histos.get(HIST("GeneralQA/hCandidateAnalysisSelection"))->GetXaxis()->SetBinLabel(3, "Photon DauPt"); - histos.get(HIST("GeneralQA/hCandidateAnalysisSelection"))->GetXaxis()->SetBinLabel(4, "Photon DCAToPV"); - histos.get(HIST("GeneralQA/hCandidateAnalysisSelection"))->GetXaxis()->SetBinLabel(5, "Photon DCADau"); - histos.get(HIST("GeneralQA/hCandidateAnalysisSelection"))->GetXaxis()->SetBinLabel(6, "Photon TPCCrossedRows"); - histos.get(HIST("GeneralQA/hCandidateAnalysisSelection"))->GetXaxis()->SetBinLabel(7, "Photon TPCNSigmaEl"); - histos.get(HIST("GeneralQA/hCandidateAnalysisSelection"))->GetXaxis()->SetBinLabel(8, "Photon TPCNSigmaPi"); - histos.get(HIST("GeneralQA/hCandidateAnalysisSelection"))->GetXaxis()->SetBinLabel(9, "Photon Pt"); - histos.get(HIST("GeneralQA/hCandidateAnalysisSelection"))->GetXaxis()->SetBinLabel(10, "Photon Y/Eta"); - histos.get(HIST("GeneralQA/hCandidateAnalysisSelection"))->GetXaxis()->SetBinLabel(11, "Photon Radius"); - histos.get(HIST("GeneralQA/hCandidateAnalysisSelection"))->GetXaxis()->SetBinLabel(12, "Photon RZ line"); - histos.get(HIST("GeneralQA/hCandidateAnalysisSelection"))->GetXaxis()->SetBinLabel(13, "Photon QT"); - histos.get(HIST("GeneralQA/hCandidateAnalysisSelection"))->GetXaxis()->SetBinLabel(14, "Photon Alpha"); - histos.get(HIST("GeneralQA/hCandidateAnalysisSelection"))->GetXaxis()->SetBinLabel(15, "Photon CosPA"); - histos.get(HIST("GeneralQA/hCandidateAnalysisSelection"))->GetXaxis()->SetBinLabel(16, "Photon PsiPair"); - histos.get(HIST("GeneralQA/hCandidateAnalysisSelection"))->GetXaxis()->SetBinLabel(17, "Photon Phi"); - histos.get(HIST("GeneralQA/hCandidateAnalysisSelection"))->GetXaxis()->SetBinLabel(18, "Photon Mass"); - histos.get(HIST("GeneralQA/hCandidateAnalysisSelection"))->GetXaxis()->SetBinLabel(19, "Lambda Radius"); - histos.get(HIST("GeneralQA/hCandidateAnalysisSelection"))->GetXaxis()->SetBinLabel(20, "Lambda DCADau"); - histos.get(HIST("GeneralQA/hCandidateAnalysisSelection"))->GetXaxis()->SetBinLabel(21, "Lambda QT"); - histos.get(HIST("GeneralQA/hCandidateAnalysisSelection"))->GetXaxis()->SetBinLabel(22, "Lambda Alpha"); - histos.get(HIST("GeneralQA/hCandidateAnalysisSelection"))->GetXaxis()->SetBinLabel(23, "Lambda CosPA"); - histos.get(HIST("GeneralQA/hCandidateAnalysisSelection"))->GetXaxis()->SetBinLabel(24, "Lambda Y/Eta"); - histos.get(HIST("GeneralQA/hCandidateAnalysisSelection"))->GetXaxis()->SetBinLabel(25, "Lambda TPCCrossedRows"); - histos.get(HIST("GeneralQA/hCandidateAnalysisSelection"))->GetXaxis()->SetBinLabel(26, "Lambda ITSNCls"); - histos.get(HIST("GeneralQA/hCandidateAnalysisSelection"))->GetXaxis()->SetBinLabel(27, "Lambda Lifetime"); - histos.get(HIST("GeneralQA/hCandidateAnalysisSelection"))->GetXaxis()->SetBinLabel(28, "Lambda/ALambda PID"); - histos.get(HIST("GeneralQA/hCandidateAnalysisSelection"))->GetXaxis()->SetBinLabel(29, "Lambda/ALambda DCAToPV"); - histos.get(HIST("GeneralQA/hCandidateAnalysisSelection"))->GetXaxis()->SetBinLabel(30, "Lambda/ALambda Mass"); - histos.get(HIST("GeneralQA/hCandidateAnalysisSelection"))->GetXaxis()->SetBinLabel(31, "Sigma Y"); - - // Photon Selection QA histos - histos.add("GeneralQA/hPhotonV0Type", "hPhotonV0Type", kTH1F, {{8, 0.5f, 8.5f}}); - histos.add("GeneralQA/hPhotonNegpT", "hPhotonNegpT", kTH1F, {axisPt}); - histos.add("GeneralQA/hPhotonPospT", "hPhotonPospT", kTH1F, {axisPt}); - histos.add("GeneralQA/hPhotonDCANegToPV", "hPhotonDCANegToPV", kTH1F, {axisDCAtoPV}); - histos.add("GeneralQA/hPhotonDCAPosToPV", "hPhotonDCAPosToPV", kTH1F, {axisDCAtoPV}); - histos.add("GeneralQA/hPhotonDCADau", "hPhotonDCADau", kTH1F, {axisDCAdau}); - histos.add("GeneralQA/hPhotonPosTPCCR", "hPhotonPosTPCCR", kTH1F, {axisTPCrows}); - histos.add("GeneralQA/hPhotonNegTPCCR", "hPhotonNegTPCCR", kTH1F, {axisTPCrows}); - histos.add("GeneralQA/h2dPhotonPosTPCNSigmaEl", "h2dPhotonPosTPCNSigmaEl", {HistType::kTH2F, {axisPt, {30, -15.0f, 15.0f}}}); - histos.add("GeneralQA/h2dPhotonNegTPCNSigmaEl", "h2dPhotonNegTPCNSigmaEl", {HistType::kTH2F, {axisPt, {30, -15.0f, 15.0f}}}); - histos.add("GeneralQA/h2dPhotonPosTPCNSigmaPi", "h2dPhotonPosTPCNSigmaPi", {HistType::kTH2F, {axisPt, {30, -15.0f, 15.0f}}}); - histos.add("GeneralQA/h2dPhotonNegTPCNSigmaPi", "h2dPhotonNegTPCNSigmaPi", {HistType::kTH2F, {axisPt, {30, -15.0f, 15.0f}}}); - histos.add("GeneralQA/hPhotonpT", "hPhotonpT", kTH1F, {axisPt}); - histos.add("GeneralQA/hPhotonY", "hPhotonY", kTH1F, {axisRapidity}); - histos.add("GeneralQA/hPhotonPosEta", "hPhotonPosEta", kTH1F, {axisRapidity}); - histos.add("GeneralQA/hPhotonNegEta", "hPhotonNegEta", kTH1F, {axisRapidity}); - histos.add("GeneralQA/hPhotonRadius", "hPhotonRadius", kTH1F, {axisRadius}); - histos.add("GeneralQA/hPhotonZ", "hPhotonZ", kTH1F, {{240, 0.0f, 120.0f}}); - histos.add("GeneralQA/h2dRZCut", "h2dRZCut", {HistType::kTH2F, {{240, -120.0f, 120.0f}, axisRadius}}); - histos.add("GeneralQA/h2dRZPlane", "h2dRZPlane", {HistType::kTH2F, {{240, -120.0f, 120.0f}, axisRadius}}); - histos.add("GeneralQA/h2dPhotonArmenteros", "h2dPhotonArmenteros", {HistType::kTH2F, {axisAPAlpha, axisAPQt}}); - histos.add("GeneralQA/hPhotonCosPA", "hPhotonCosPA", kTH1F, {axisCosPA}); - histos.add("GeneralQA/hPhotonPsiPair", "hPhotonPsiPair", kTH1F, {axisPsiPair}); - histos.add("GeneralQA/hPhotonPhi", "hPhotonPhi", kTH1F, {{200, 0, 2 * o2::constants::math::PI}}); - histos.add("GeneralQA/h3dPhotonMass", "h3dPhotonMass", kTH3F, {axisCentrality, axisPt, axisPhotonMass}); - - // Lambda Selection QA histos - histos.add("GeneralQA/hLambdaRadius", "hLambdaRadius", kTH1F, {axisRadius}); - histos.add("GeneralQA/hLambdaDCADau", "hLambdaDCADau", kTH1F, {axisDCAdau}); - histos.add("GeneralQA/h2dLambdaArmenteros", "h2dLambdaArmenteros", {HistType::kTH2F, {axisAPAlpha, axisAPQt}}); - histos.add("GeneralQA/hLambdaCosPA", "hLambdaCosPA", kTH1F, {axisCosPA}); - histos.add("GeneralQA/hLambdaY", "hLambdaY", kTH1F, {axisRapidity}); - histos.add("GeneralQA/hLambdaPosEta", "hLambdaPosEta", kTH1F, {axisRapidity}); - histos.add("GeneralQA/hLambdaNegEta", "hLambdaNegEta", kTH1F, {axisRapidity}); - histos.add("GeneralQA/hLambdaPosTPCCR", "hLambdaPosTPCCR", kTH1F, {axisTPCrows}); - histos.add("GeneralQA/hLambdaNegTPCCR", "hLambdaNegTPCCR", kTH1F, {axisTPCrows}); - histos.add("GeneralQA/hLambdaPosITSCls", "hLambdaPosITSCls", kTH1F, {axisNCls}); - histos.add("GeneralQA/hLambdaNegITSCls", "hLambdaNegITSCls", kTH1F, {axisNCls}); - histos.add("GeneralQA/hLambdaPosChi2PerNc", "hLambdaPosChi2PerNc", kTH1F, {axisChi2PerNcl}); - histos.add("GeneralQA/hLambdaNegChi2PerNc", "hLambdaNegChi2PerNc", kTH1F, {axisChi2PerNcl}); - histos.add("GeneralQA/hLambdaLifeTime", "hLambdaLifeTime", kTH1F, {axisLifetime}); - - histos.add("GeneralQA/h2dTPCvsTOFNSigma_LambdaPr", "h2dTPCvsTOFNSigma_LambdaPr", {HistType::kTH2F, {axisTPCNSigma, axisTOFNSigma}}); - histos.add("GeneralQA/h2dTPCvsTOFNSigma_LambdaPi", "h2dTPCvsTOFNSigma_LambdaPi", {HistType::kTH2F, {axisTPCNSigma, axisTOFNSigma}}); - histos.add("GeneralQA/hLambdaDCANegToPV", "hLambdaDCANegToPV", kTH1F, {axisDCAtoPV}); - histos.add("GeneralQA/hLambdaDCAPosToPV", "hLambdaDCAPosToPV", kTH1F, {axisDCAtoPV}); - histos.add("GeneralQA/h3dLambdaMass", "h3dLambdaMass", kTH3F, {axisCentrality, axisPt, axisLambdaMass}); - histos.add("GeneralQA/h2dTPCvsTOFNSigma_ALambdaPr", "h2dTPCvsTOFNSigma_ALambdaPr", {HistType::kTH2F, {axisTPCNSigma, axisTOFNSigma}}); - histos.add("GeneralQA/h2dTPCvsTOFNSigma_ALambdaPi", "h2dTPCvsTOFNSigma_ALambdaPi", {HistType::kTH2F, {axisTPCNSigma, axisTOFNSigma}}); - histos.add("GeneralQA/hALambdaDCANegToPV", "hALambdaDCANegToPV", kTH1F, {axisDCAtoPV}); - histos.add("GeneralQA/hALambdaDCAPosToPV", "hALambdaDCAPosToPV", kTH1F, {axisDCAtoPV}); - histos.add("GeneralQA/h3dAntiLambdaMass", "h3dAntiLambdaMass", kTH3F, {axisCentrality, axisPt, axisLambdaMass}); - - histos.add("GeneralQA/hPhotonMassSelected", "hPhotonMassSelected", kTH1F, {axisPhotonMass}); - histos.add("GeneralQA/hLambdaMassSelected", "hLambdaMassSelected", kTH1F, {axisLambdaMass}); - histos.add("GeneralQA/hAntiLambdaMassSelected", "hAntiLambdaMassSelected", kTH1F, {axisLambdaMass}); - - histos.add("GeneralQA/hSigmaY", "hSigmaY", kTH1F, {axisRapidity}); - histos.add("GeneralQA/hSigmaOPAngle", "hSigmaOPAngle", kTH1F, {{140, 0.0f, +7.0f}}); - - // Specific sigma0 QA - histos.add("SigmaSelQA/h2dPhotonV0Type", "h2dPhotonV0Type", {HistType::kTH2F, {axisPt, axisSigmaMass}}); - histos.add("SigmaSelQA/h2dPhotonMass", "h2dPhotonMass", {HistType::kTH2F, {axisPt, axisSigmaMass}}); - histos.add("SigmaSelQA/h2dPhotonDaupT", "h2dPhotonDaupT", {HistType::kTH2F, {axisPt, axisSigmaMass}}); - histos.add("SigmaSelQA/h2dPhotonDCADauToPV", "h2dPhotonDCADauToPV", {HistType::kTH2F, {axisPt, axisSigmaMass}}); - histos.add("SigmaSelQA/h2dPhotonDCADau", "h2dPhotonDCADau", {HistType::kTH2F, {axisPt, axisSigmaMass}}); - histos.add("SigmaSelQA/h2dPhotonDauTPCCR", "h2dPhotonDauTPCCR", {HistType::kTH2F, {axisPt, axisSigmaMass}}); - histos.add("SigmaSelQA/h2dPhotonTPCNSigmaEl", "h2dPhotonTPCNSigmaEl", {HistType::kTH2F, {axisPt, axisSigmaMass}}); - histos.add("SigmaSelQA/h2dPhotonpT", "h2dPhotonpT", {HistType::kTH2F, {axisPt, axisSigmaMass}}); // - histos.add("SigmaSelQA/h2dPhotonY", "h2dPhotonY", {HistType::kTH2F, {axisPt, axisSigmaMass}}); - histos.add("SigmaSelQA/h2dPhotonRadius", "h2dPhotonRadius", {HistType::kTH2F, {axisPt, axisSigmaMass}}); - histos.add("SigmaSelQA/h2dRZCut", "h2dRZCut", {HistType::kTH2F, {axisPt, axisSigmaMass}}); - histos.add("SigmaSelQA/h2dPhotonArmenteros", "h2dPhotonArmenteros", {HistType::kTH2F, {axisPt, axisSigmaMass}}); - histos.add("SigmaSelQA/h2dPhotonCosPA", "h2dPhotonCosPA", {HistType::kTH2F, {axisPt, axisSigmaMass}}); - histos.add("SigmaSelQA/h2dPhotonPsiPair", "h2dPhotonPsiPair", {HistType::kTH2F, {axisPt, axisSigmaMass}}); - histos.add("SigmaSelQA/h2dLambdaRadius", "h2dLambdaRadius", {HistType::kTH2F, {axisPt, axisSigmaMass}}); - histos.add("SigmaSelQA/h2dLambdaDCADau", "h2dLambdaDCADau", {HistType::kTH2F, {axisPt, axisSigmaMass}}); - histos.add("SigmaSelQA/h2dLambdaArmenteros", "h2dLambdaArmenteros", {HistType::kTH2F, {axisPt, axisSigmaMass}}); - histos.add("SigmaSelQA/h2dLambdaCosPA", "h2dLambdaCosPA", {HistType::kTH2F, {axisPt, axisSigmaMass}}); - histos.add("SigmaSelQA/h2dLambdaY", "h2dLambdaY", {HistType::kTH2F, {axisPt, axisSigmaMass}}); - histos.add("SigmaSelQA/h2dLambdaDauTPCCR", "h2dLambdaDauTPCCR", {HistType::kTH2F, {axisPt, axisSigmaMass}}); - histos.add("SigmaSelQA/h2dLambdaDauITSCls", "h2dLambdaDauITSCls", {HistType::kTH2F, {axisPt, axisSigmaMass}}); - histos.add("SigmaSelQA/h2dLambdaLifeTime", "h2dLambdaLifeTime", {HistType::kTH2F, {axisPt, axisSigmaMass}}); - histos.add("SigmaSelQA/h2dTPCvsTOFNSigma_Lambda", "h2dTPCvsTOFNSigma_Lambda", {HistType::kTH2F, {axisPt, axisSigmaMass}}); - histos.add("SigmaSelQA/h2dLambdaDCADauToPV", "h2dLambdaDCADauToPV", {HistType::kTH2F, {axisPt, axisSigmaMass}}); - histos.add("SigmaSelQA/h2dLambdaMass", "h2dLambdaMass", {HistType::kTH2F, {axisPt, axisSigmaMass}}); - histos.add("SigmaSelQA/h2dTPCvsTOFNSigma_ALambda", "h2dTPCvsTOFNSigma_ALambda", {HistType::kTH2F, {axisPt, axisSigmaMass}}); - histos.add("SigmaSelQA/h2dALambdaDCADauToPV", "h2dALambdaDCADauToPV", {HistType::kTH2F, {axisPt, axisSigmaMass}}); - histos.add("SigmaSelQA/h2dAntiLambdaMass", "h2dAntiLambdaMass", {HistType::kTH2F, {axisPt, axisSigmaMass}}); - histos.add("SigmaSelQA/h2dSigmaY", "h2dSigmaY", {HistType::kTH2F, {axisPt, axisSigmaMass}}); - - // Specific photon QA - histos.add("PhotonSelQA/h2dPhotonBaseline", "h2dPhotonBaseline", {HistType::kTH2F, {axisPt, axisPhotonMass}}); - histos.add("PhotonSelQA/h2dPhotonV0Type", "h2dPhotonV0Type", {HistType::kTH2F, {axisPt, axisPhotonMass}}); - histos.add("PhotonSelQA/h2dPhotonMass", "h2dPhotonMass", {HistType::kTH2F, {axisPt, axisPhotonMass}}); - histos.add("PhotonSelQA/h2dPhotonDaupT", "h2dPhotonDaupT", {HistType::kTH2F, {axisPt, axisPhotonMass}}); - histos.add("PhotonSelQA/h2dPhotonDCADauToPV", "h2dPhotonDCADauToPV", {HistType::kTH2F, {axisPt, axisPhotonMass}}); - histos.add("PhotonSelQA/h2dPhotonDCADau", "h2dPhotonDCADau", {HistType::kTH2F, {axisPt, axisPhotonMass}}); - histos.add("PhotonSelQA/h2dPhotonDauTPCCR", "h2dPhotonDauTPCCR", {HistType::kTH2F, {axisPt, axisPhotonMass}}); - histos.add("PhotonSelQA/h2dPhotonTPCNSigmaEl", "h2dPhotonTPCNSigmaEl", {HistType::kTH2F, {axisPt, axisPhotonMass}}); - histos.add("PhotonSelQA/h2dPhotonpT", "h2dPhotonpT", {HistType::kTH2F, {axisPt, axisPhotonMass}}); // - histos.add("PhotonSelQA/h2dPhotonY", "h2dPhotonY", {HistType::kTH2F, {axisPt, axisPhotonMass}}); - histos.add("PhotonSelQA/h2dPhotonRadius", "h2dPhotonRadius", {HistType::kTH2F, {axisPt, axisPhotonMass}}); - histos.add("PhotonSelQA/h2dRZCut", "h2dRZCut", {HistType::kTH2F, {axisPt, axisPhotonMass}}); - histos.add("PhotonSelQA/h2dPhotonArmenteros", "h2dPhotonArmenteros", {HistType::kTH2F, {axisPt, axisPhotonMass}}); - histos.add("PhotonSelQA/h2dPhotonCosPA", "h2dPhotonCosPA", {HistType::kTH2F, {axisPt, axisPhotonMass}}); - histos.add("PhotonSelQA/h2dPhotonPsiPair", "h2dPhotonPsiPair", {HistType::kTH2F, {axisPt, axisPhotonMass}}); - histos.add("PhotonSelQA/h2dPhotonPhi", "h2dPhotonPhi", {HistType::kTH2F, {axisPt, axisPhotonMass}}); - - // Specific Lambda/ALambda QA - histos.add("LambdaSelQA/h2dLambdaBaseline", "h2dLambdaBaseline", {HistType::kTH2F, {axisPt, axisLambdaMass}}); - histos.add("LambdaSelQA/h2dLambdaRadius", "h2dLambdaRadius", {HistType::kTH2F, {axisPt, axisLambdaMass}}); - histos.add("LambdaSelQA/h2dLambdaDCADau", "h2dLambdaDCADau", {HistType::kTH2F, {axisPt, axisLambdaMass}}); - histos.add("LambdaSelQA/h2dLambdaArmenteros", "h2dLambdaArmenteros", {HistType::kTH2F, {axisPt, axisLambdaMass}}); - histos.add("LambdaSelQA/h2dLambdaCosPA", "h2dLambdaCosPA", {HistType::kTH2F, {axisPt, axisLambdaMass}}); - histos.add("LambdaSelQA/h2dLambdaY", "h2dLambdaY", {HistType::kTH2F, {axisPt, axisLambdaMass}}); - histos.add("LambdaSelQA/h2dLambdaDauTPCCR", "h2dLambdaDauTPCCR", {HistType::kTH2F, {axisPt, axisLambdaMass}}); - histos.add("LambdaSelQA/h2dLambdaDauITSCls", "h2dLambdaDauITSCls", {HistType::kTH2F, {axisPt, axisLambdaMass}}); - histos.add("LambdaSelQA/h2dLambdaLifeTime", "h2dLambdaLifeTime", {HistType::kTH2F, {axisPt, axisLambdaMass}}); - histos.add("LambdaSelQA/h2dTPCvsTOFNSigma_Lambda", "h2dTPCvsTOFNSigma_Lambda", {HistType::kTH2F, {axisPt, axisLambdaMass}}); - histos.add("LambdaSelQA/h2dLambdaDCADauToPV", "h2dLambdaDCADauToPV", {HistType::kTH2F, {axisPt, axisLambdaMass}}); - histos.add("LambdaSelQA/h2dLambdaMass", "h2dLambdaMass", {HistType::kTH2F, {axisPt, axisLambdaMass}}); - - // For Signal Extraction - - // Sigma0 - histos.add("Sigma0/h3dMassSigma0", "h3dMassSigma0", kTH3F, {axisCentrality, axisPt, axisSigmaMass}); - histos.add("Sigma0/h3dPhotonRadiusVsMassSigma0", "h3dPhotonRadiusVsMassSigma0", kTH3F, {axisCentrality, axisRadius, axisSigmaMass}); - histos.add("Sigma0/hMassSigma0", "hMassSigma0", kTH1F, {axisSigmaMass}); - histos.add("Sigma0/hPtSigma0", "hPtSigma0", kTH1F, {axisPt}); - histos.add("Sigma0/hRapiditySigma0", "hRapiditySigma0", kTH1F, {axisRapidity}); - - // AntiSigma0 - histos.add("AntiSigma0/h3dMassAntiSigma0", "h3dMassAntiSigma0", kTH3F, {axisCentrality, axisPt, axisSigmaMass}); - histos.add("AntiSigma0/h3dPhotonRadiusVsMassAntiSigma0", "h3dPhotonRadiusVsMassAntiSigma0", kTH3F, {axisCentrality, axisRadius, axisSigmaMass}); - histos.add("AntiSigma0/hMassAntiSigma0", "hMassAntiSigma0", kTH1F, {axisSigmaMass}); - histos.add("AntiSigma0/hPtAntiSigma0", "hPtAntiSigma0", kTH1F, {axisPt}); - histos.add("AntiSigma0/hRapidityAntiSigma0", "hRapidityAntiSigma0", kTH1F, {axisRapidity}); - - if (fProcessMonteCarlo) { - - // Kinematic - histos.add("MC/h3dMassSigma0", "h3dMassSigma0", kTH3F, {axisCentrality, axisPt, axisSigmaMass}); - histos.add("MC/h3dMassAntiSigma0", "h3dMassSigma0", kTH3F, {axisCentrality, axisPt, axisSigmaMass}); - histos.add("MC/h3dMassAllSigma0sBeforesel", "h3dMassAllSigma0sBeforesel", kTH3F, {axisCentrality, axisPt, axisSigmaMass}); - histos.add("MC/h2dArmenterosBeforeSel", "h2dArmenterosBeforeSel", {HistType::kTH2F, {axisAPAlpha, axisAPQt}}); - histos.add("MC/h2dArmenterosAfterSel", "h2dArmenterosAfterSel", {HistType::kTH2F, {axisAPAlpha, axisAPQt}}); - - // Sigma0 QA - histos.add("MC/hMassSigma0BeforeSel", "hMassSigma0BeforeSel", kTH1F, {axisSigmaMass}); - histos.add("MC/hPtSigma0BeforeSel", "hPtSigma0BeforeSel", kTH1F, {axisPt}); - histos.add("MC/hMassSigma0", "hMassSigma0", kTH1F, {axisSigmaMass}); - histos.add("MC/hPtSigma0", "hPtSigma0", kTH1F, {axisPt}); - histos.add("MC/hMassAntiSigma0", "hMassAntiSigma0", kTH1F, {axisSigmaMass}); - histos.add("MC/hPtAntiSigma0", "hPtAntiSigma0", kTH1F, {axisPt}); - - // For background decomposition - histos.add("MC/h2dPtVsMassSigma_SignalBkg", "h2dPtVsMassSigma_SignalBkg", kTH2D, {axisPt, axisSigmaMass}); - histos.add("MC/h2dPtVsMassSigma_SignalOnly", "h2dPtVsMassSigma_SignalOnly", kTH2D, {axisPt, axisSigmaMass}); - histos.add("MC/h2dPtVsMassSigma_TrueDaughters", "h2dPtVsMassSigma_TrueDaughters", kTH2D, {axisPt, axisSigmaMass}); - histos.add("MC/h2dPtVsMassSigma_TrueGammaFakeLambda", "h2dPtVsMassSigma_TrueGammaFakeLambda", kTH2D, {axisPt, axisSigmaMass}); - histos.add("MC/h2dPtVsMassSigma_FakeGammaTrueLambda", "h2dPtVsMassSigma_FakeGammaTrueLambda", kTH2D, {axisPt, axisSigmaMass}); - histos.add("MC/h2dPtVsMassSigma_FakeDaughters", "h2dPtVsMassSigma_FakeDaughters", kTH2D, {axisPt, axisSigmaMass}); - histos.add("MC/h2dTrueDaughtersMatrix", "h2dTrueDaughtersMatrix", kTHnSparseD, {{10001, -5000.5f, +5000.5f}, {10001, -5000.5f, +5000.5f}}); - - // For new selection studies: - //// Opening angle between daughters - histos.add("MC/h2dPtVsOPAngle_SignalOnly", "h2dPtVsOPAngle_SignalOnly", kTH2D, {axisPt, {140, 0.0f, +7.0f}}); - histos.add("MC/h2dPtVsOPAngle_TrueDaughters", "h2dPtVsOPAngle_TrueDaughters", kTH2D, {axisPt, {140, 0.0f, +7.0f}}); - histos.add("MC/h2dPtVsMassSigma_AfterOPAngleSel", "h2dPtVsMassSigma_AfterOPAngleSel", kTH2D, {axisPt, axisSigmaMass}); - - // For efficiency/Purity studies - // Before any selection - histos.add("MC/hPtTrueLambda_BeforeSel", "hPtTrueLambda_BeforeSel", kTH1F, {axisPt}); // Signal only - histos.add("MC/hPtTrueAntiLambda_BeforeSel", "hPtTrueAntiLambda_BeforeSel", kTH1F, {axisPt}); // Signal only - histos.add("MC/hPtTrueGamma_BeforeSel", "hPtTrueGamma_BeforeSel", kTH1F, {axisPt}); // Signal only - histos.add("MC/hPtTrueSigma_BeforeSel", "hPtTrueSigma_BeforeSel", kTH1F, {axisPt}); // Signal only - histos.add("MC/hPtTrueAntiSigma_BeforeSel", "hPtTrueAntiSigma_BeforeSel", kTH1F, {axisPt}); // Signal only - histos.add("MC/hPtLambdaCand_BeforeSel", "hPtLambdaCand_BeforeSel", kTH1F, {axisPt}); // Bkg + Signal - histos.add("MC/hPtGammaCand_BeforeSel", "hPtGammaCand_BeforeSel", kTH1F, {axisPt}); // Bkg + Signal - histos.add("MC/hPtSigmaCand_BeforeSel", "hPtGammaCand_BeforeSel", kTH1F, {axisPt}); // Bkg + Signal - - // After analysis selections - histos.add("MC/hPtTrueLambda_AfterSel", "hPtTrueLambda_AfterSel", kTH1F, {axisPt}); // Signal only - histos.add("MC/hPtTrueAntiLambda_AfterSel", "hPtTrueAntiLambda_AfterSel", kTH1F, {axisPt}); // Signal only - histos.add("MC/hPtTrueGamma_AfterSel", "hPtTrueGamma_AfterSel", kTH1F, {axisPt}); // Signal only - histos.add("MC/hPtTrueSigma_AfterSel", "hPtTrueSigma_AfterSel", kTH1F, {axisPt}); // Signal only - - histos.add("MC/hPtLambdaCand_AfterSel", "hPtLambdaCand_AfterSel", kTH1F, {axisPt}); - histos.add("MC/hPtGammaCand_AfterSel", "hPtGammaCand_AfterSel", kTH1F, {axisPt}); - histos.add("MC/hPtSigmaCand_AfterSel", "hPtSigmaCand_AfterSel", kTH1F, {axisPt}); - - // TPC vs TOF N Sigmas distributions - histos.add("MC/h3dTPCvsTOFNSigma_LambdaPr", "h3dTPCvsTOFNSigma_LambdaPr", kTH3F, {axisTPCNSigma, axisTOFNSigma, axisPt}); - histos.add("MC/h3dTPCvsTOFNSigma_LambdaPi", "h3dTPCvsTOFNSigma_LambdaPi", kTH3F, {axisTPCNSigma, axisTOFNSigma, axisPt}); - histos.add("MC/h3dTPCvsTOFNSigma_TrueLambdaPr", "h3dTPCvsTOFNSigma_TrueLambdaPr", kTH3F, {axisTPCNSigma, axisTOFNSigma, axisPt}); - histos.add("MC/h3dTPCvsTOFNSigma_TrueLambdaPi", "h3dTPCvsTOFNSigma_TrueLambdaPi", kTH3F, {axisTPCNSigma, axisTOFNSigma, axisPt}); - histos.add("MC/h3dTPCvsTOFNSigma_TrueALambdaPr", "h3dTPCvsTOFNSigma_TrueALambdaPr", kTH3F, {axisTPCNSigma, axisTOFNSigma, axisPt}); - histos.add("MC/h3dTPCvsTOFNSigma_TrueALambdaPi", "h3dTPCvsTOFNSigma_TrueALambdaPi", kTH3F, {axisTPCNSigma, axisTOFNSigma, axisPt}); - - // QA of PID selections: - //// TPC PID - histos.add("MC/hPtTrueLambda_passedTPCPID", "hPtTrueLambda_passedTPCPID", kTH1F, {axisPt}); - histos.add("MC/hPtLambdaCandidates_passedTPCPID", "hPtLambdaCandidates_passedTPCPID", kTH1F, {axisPt}); - - //// TOF PID - histos.add("MC/hPtTrueLambda_passedTOFPID", "hPtTrueLambda_passedTOFPID", kTH1F, {axisPt}); - histos.add("MC/hPtLambdaCandidates_passedTOFPID", "hPtLambdaCandidates_passedTOFPID", kTH1F, {axisPt}); - - //// TPC+TOF PID - histos.add("MC/hPtTrueLambda_passedTPCTOFPID", "hPtTrueLambda_passedTPCTOFPID", kTH1F, {axisPt}); - histos.add("MC/hPtLambdaCandidates_passedTPCTOFPID", "hPtLambdaCandidates_passedTPCTOFPID", kTH1F, {axisPt}); - - // 1/pT Resolution: - histos.add("MC/h2dLambdaPtResolution", "h2dLambdaPtResolution", kTH2D, {axisInvPt, axisDeltaPt}); - histos.add("MC/h2dAntiLambdaPtResolution", "h2dAntiLambdaPtResolution", kTH2D, {axisInvPt, axisDeltaPt}); - histos.add("MC/h2dGammaPtResolution", "h2dGammaPtResolution", kTH2D, {axisInvPt, axisDeltaPt}); - histos.add("MC/h2dSigma0PtResolution", "h2dSigma0PtResolution", kTH2D, {axisInvPt, axisDeltaPt}); - histos.add("MC/h2dAntiSigma0PtResolution", "h2dAntiSigma0PtResolution", kTH2D, {axisInvPt, axisDeltaPt}); - histos.add("MC/h3dLambdaPtResoVsTPCCR", "h3dLambdaPtResoVsTPCCR", kTH3F, {axisInvPt, axisDeltaPt, {320, -160.0f, 160.0f}}); - histos.add("MC/h3dAntiLambdaPtResoVsTPCCR", "h3dAntiLambdaPtResoVsTPCCR", kTH3F, {axisInvPt, axisDeltaPt, {320, -160.0f, 160.0f}}); - histos.add("MC/h3dGammaPtResoVsTPCCR", "h3dGammaPtResoVsTPCCR", kTH3F, {axisInvPt, axisDeltaPt, {320, -160.0f, 160.0f}}); - - // pTMC info: - histos.add("MC/h2dSigmaMCPtVsLambdaMCPt", "h2dSigmaMCPtVsLambdaMCPt", kTH2D, {axisPt, axisPt}); - histos.add("MC/h2dSigmaMCPtVsGammaMCPt", "h2dSigmaMCPtVsGammaMCPt", kTH2D, {axisPt, axisPt}); + return TrkCode; + } + + template + void getpTResolution(TV0Object const& sigma) + { + + //_______________________________________ + // Gamma MC association + if (sigma.photonCandPDGCode() == 22) { + if (sigma.photonMCPt() > 0) { + histos.fill(HIST("BeforeSel/MC/pTReso/h3dGammaPtResoVsTPCCR"), 1.f / sigma.lambdaMCPt(), 1.f / sigma.lambdaPt() - 1.f / sigma.lambdaMCPt(), -1 * sigma.photonNegTPCCrossedRows()); // 1/pT resolution + histos.fill(HIST("BeforeSel/MC/pTReso/h3dGammaPtResoVsTPCCR"), 1.f / sigma.lambdaMCPt(), 1.f / sigma.lambdaPt() - 1.f / sigma.lambdaMCPt(), sigma.photonPosTPCCrossedRows()); // 1/pT resolution + histos.fill(HIST("BeforeSel/MC/pTReso/h2dGammaPtResolution"), 1.f / sigma.photonMCPt(), 1.f / sigma.photonPt() - 1.f / sigma.photonMCPt()); // pT resolution + } + } + + //_______________________________________ + // Lambda MC association + if (sigma.lambdaCandPDGCode() == 3122) { + if (sigma.lambdaMCPt() > 0) { + histos.fill(HIST("BeforeSel/MC/pTReso/h2dLambdaPtResolution"), 1.f / sigma.lambdaMCPt(), 1.f / sigma.lambdaPt() - 1.f / sigma.lambdaMCPt()); // 1/pT resolution + histos.fill(HIST("BeforeSel/MC/pTReso/h3dLambdaPtResoVsTPCCR"), 1.f / sigma.lambdaMCPt(), 1.f / sigma.lambdaPt() - 1.f / sigma.lambdaMCPt(), -1 * sigma.lambdaNegTPCCrossedRows()); // 1/pT resolution + histos.fill(HIST("BeforeSel/MC/pTReso/h3dLambdaPtResoVsTPCCR"), 1.f / sigma.lambdaMCPt(), 1.f / sigma.lambdaPt() - 1.f / sigma.lambdaMCPt(), sigma.lambdaPosTPCCrossedRows()); // 1/pT resolution + } + } + + //_______________________________________ + // AntiLambda MC association + if (sigma.lambdaCandPDGCode() == -3122) { + if (sigma.lambdaMCPt() > 0) { + histos.fill(HIST("BeforeSel/MC/pTReso/h2dAntiLambdaPtResolution"), 1.f / sigma.lambdaMCPt(), 1.f / sigma.lambdaPt() - 1.f / sigma.lambdaMCPt()); // pT resolution + histos.fill(HIST("BeforeSel/MC/pTReso/h3dAntiLambdaPtResoVsTPCCR"), 1.f / sigma.lambdaMCPt(), 1.f / sigma.lambdaPt() - 1.f / sigma.lambdaMCPt(), -1 * sigma.lambdaNegTPCCrossedRows()); // 1/pT resolution + histos.fill(HIST("BeforeSel/MC/pTReso/h3dAntiLambdaPtResoVsTPCCR"), 1.f / sigma.lambdaMCPt(), 1.f / sigma.lambdaPt() - 1.f / sigma.lambdaMCPt(), sigma.lambdaPosTPCCrossedRows()); // 1/pT resolution + } + } + + //_______________________________________ + // Sigma and AntiSigma MC association + if (sigma.isSigma()) { + if (sigma.sigmaMCPt() > 0) + histos.fill(HIST("BeforeSel/MC/pTReso/h2dSigma0PtResolution"), 1.f / sigma.sigmaMCPt(), 1.f / sigma.sigmapT() - 1.f / sigma.sigmaMCPt()); // pT resolution + } + if (sigma.isAntiSigma()) { + if (sigma.sigmaMCPt() > 0) + histos.fill(HIST("BeforeSel/MC/pTReso/h2dAntiSigma0PtResolution"), 1.f / sigma.sigmaMCPt(), 1.f / sigma.sigmapT() - 1.f / sigma.sigmaMCPt()); // pT resolution } } - template - bool IsEventAccepted(TCollision collision) - // check whether the collision passes our collision selections + // To save histograms for background analysis + template + void runBkgAnalysis(TV0Object const& sigma) { - histos.fill(HIST("hEventSelection"), 0. /* all collisions */); - if (eventSelections.requireSel8 && !collision.sel8()) { - return false; + // Check whether it is before or after selections + static constexpr std::string_view MainDir[] = {"BeforeSel", "AfterSel"}; + + bool fIsSigma = sigma.isSigma(); + bool fIsAntiSigma = sigma.isAntiSigma(); + int PhotonPDGCode = sigma.photonCandPDGCode(); + int PhotonPDGCodeMother = sigma.photonCandPDGCodeMother(); + int LambdaPDGCode = sigma.lambdaCandPDGCode(); + int LambdaPDGCodeMother = sigma.lambdaCandPDGCodeMother(); + float sigmapT = sigma.sigmapT(); + float sigmaMass = sigma.sigmaMass(); + + histos.fill(HIST(MainDir[mode]) + HIST("/MC/BkgStudy/h2dPtVsMassSigma_All"), sigmapT, sigmaMass); + + //_______________________________________ + // Real Gamma x Real Lambda - but not from the same sigma0/antisigma0! + if ((PhotonPDGCode == 22) && ((LambdaPDGCode == 3122) || (LambdaPDGCode == -3122)) && (!fIsSigma && !fIsAntiSigma)) { + histos.fill(HIST(MainDir[mode]) + HIST("/MC/BkgStudy/h2dPtVsMassSigma_TrueDaughters"), sigmapT, sigmaMass); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/BkgStudy/h2dTrueDaughtersMatrix"), LambdaPDGCodeMother, PhotonPDGCodeMother); } - histos.fill(HIST("hEventSelection"), 1 /* sel8 collisions */); - if (eventSelections.requireTriggerTVX && !collision.selection_bit(aod::evsel::kIsTriggerTVX)) { - return false; + + //_______________________________________ + // Real Gamma x fake Lambda + if ((PhotonPDGCode == 22) && (LambdaPDGCode != 3122) && (LambdaPDGCode != -3122)) + histos.fill(HIST(MainDir[mode]) + HIST("/MC/BkgStudy/h2dPtVsMassSigma_TrueGammaFakeLambda"), sigmapT, sigmaMass); + + //_______________________________________ + // Fake Gamma x Real Lambda + if ((PhotonPDGCode != 22) && ((LambdaPDGCode == 3122) || (LambdaPDGCode == -3122))) + histos.fill(HIST(MainDir[mode]) + HIST("/MC/BkgStudy/h2dPtVsMassSigma_FakeGammaTrueLambda"), sigmapT, sigmaMass); + + //_______________________________________ + // Fake Gamma x Fake Lambda + if ((PhotonPDGCode != 22) && (LambdaPDGCode != 3122) && (LambdaPDGCode != -3122)) + histos.fill(HIST(MainDir[mode]) + HIST("/MC/BkgStudy/h2dPtVsMassSigma_FakeDaughters"), sigmapT, sigmaMass); + } + + template + void fillQAHistos(TV0Object const& sigma) + { + + // Check whether it is before or after selections + // static std::string main_dir; + // main_dir = IsBeforeSel ? "BeforeSel" : "AfterSel"; + static constexpr std::string_view MainDir[] = {"BeforeSel", "AfterSel"}; + + // Get V0trackCode + int GammaTrkCode = retrieveV0TrackCode(sigma); + int LambdaTrkCode = retrieveV0TrackCode(sigma); + + float photonRZLineCut = TMath::Abs(sigma.photonZconv()) * TMath::Tan(2 * TMath::ATan(TMath::Exp(-PhotonMaxDauEta))) - PhotonLineCutZ0; + //_______________________________________ + // Photon + histos.fill(HIST(MainDir[mode]) + HIST("/Photon/hTrackCode"), GammaTrkCode); + histos.fill(HIST(MainDir[mode]) + HIST("/Photon/hV0Type"), sigma.photonV0Type()); + histos.fill(HIST(MainDir[mode]) + HIST("/Photon/hNegpT"), sigma.photonNegPt()); + histos.fill(HIST(MainDir[mode]) + HIST("/Photon/hPospT"), sigma.photonPosPt()); + histos.fill(HIST(MainDir[mode]) + HIST("/Photon/hDCANegToPV"), sigma.photonDCANegPV()); + histos.fill(HIST(MainDir[mode]) + HIST("/Photon/hDCAPosToPV"), sigma.photonDCAPosPV()); + histos.fill(HIST(MainDir[mode]) + HIST("/Photon/hDCADau"), sigma.photonDCADau()); + histos.fill(HIST(MainDir[mode]) + HIST("/Photon/hPosTPCCR"), sigma.photonPosTPCCrossedRows()); + histos.fill(HIST(MainDir[mode]) + HIST("/Photon/hNegTPCCR"), sigma.photonNegTPCCrossedRows()); + histos.fill(HIST(MainDir[mode]) + HIST("/Photon/h2dPosTPCNSigmaEl"), sigma.photonPosPt(), sigma.photonPosTPCNSigmaEl()); + histos.fill(HIST(MainDir[mode]) + HIST("/Photon/h2dNegTPCNSigmaEl"), sigma.photonNegPt(), sigma.photonNegTPCNSigmaEl()); + histos.fill(HIST(MainDir[mode]) + HIST("/Photon/h2dPosTPCNSigmaPi"), sigma.photonPosPt(), sigma.photonPosTPCNSigmaPi()); + histos.fill(HIST(MainDir[mode]) + HIST("/Photon/h2dNegTPCNSigmaPi"), sigma.photonNegPt(), sigma.photonNegTPCNSigmaPi()); + histos.fill(HIST(MainDir[mode]) + HIST("/Photon/hpT"), sigma.photonPt()); + histos.fill(HIST(MainDir[mode]) + HIST("/Photon/hY"), sigma.photonY()); + histos.fill(HIST(MainDir[mode]) + HIST("/Photon/hPosEta"), sigma.photonPosEta()); + histos.fill(HIST(MainDir[mode]) + HIST("/Photon/hNegEta"), sigma.photonNegEta()); + histos.fill(HIST(MainDir[mode]) + HIST("/Photon/hRadius"), sigma.photonRadius()); + histos.fill(HIST(MainDir[mode]) + HIST("/Photon/hZ"), sigma.photonZconv()); + histos.fill(HIST(MainDir[mode]) + HIST("/Photon/h2dRZCut"), sigma.photonRadius(), photonRZLineCut); + histos.fill(HIST(MainDir[mode]) + HIST("/Photon/h2dRZPlane"), sigma.photonZconv(), sigma.photonRadius()); + histos.fill(HIST(MainDir[mode]) + HIST("/Photon/hCosPA"), sigma.photonCosPA()); + histos.fill(HIST(MainDir[mode]) + HIST("/Photon/hPsiPair"), sigma.photonPsiPair()); + histos.fill(HIST(MainDir[mode]) + HIST("/Photon/hPhi"), sigma.photonPhi()); + histos.fill(HIST(MainDir[mode]) + HIST("/Photon/h3dMass"), sigma.sigmaCentrality(), sigma.photonPt(), sigma.photonMass()); + histos.fill(HIST(MainDir[mode]) + HIST("/Photon/hMass"), sigma.photonMass()); + + //_______________________________________ + // Lambdas + histos.fill(HIST(MainDir[mode]) + HIST("/Lambda/hTrackCode"), LambdaTrkCode); + histos.fill(HIST(MainDir[mode]) + HIST("/Lambda/hRadius"), sigma.lambdaRadius()); + histos.fill(HIST(MainDir[mode]) + HIST("/Lambda/hDCADau"), sigma.lambdaDCADau()); + histos.fill(HIST(MainDir[mode]) + HIST("/Lambda/hCosPA"), sigma.lambdaCosPA()); + histos.fill(HIST(MainDir[mode]) + HIST("/Lambda/hY"), sigma.lambdaY()); + histos.fill(HIST(MainDir[mode]) + HIST("/Lambda/hPosEta"), sigma.lambdaPosEta()); + histos.fill(HIST(MainDir[mode]) + HIST("/Lambda/hNegEta"), sigma.lambdaNegEta()); + histos.fill(HIST(MainDir[mode]) + HIST("/Lambda/hPosTPCCR"), sigma.lambdaPosTPCCrossedRows()); + histos.fill(HIST(MainDir[mode]) + HIST("/Lambda/hNegTPCCR"), sigma.lambdaNegTPCCrossedRows()); + histos.fill(HIST(MainDir[mode]) + HIST("/Lambda/hPosITSCls"), sigma.lambdaPosITSCls()); + histos.fill(HIST(MainDir[mode]) + HIST("/Lambda/hNegITSCls"), sigma.lambdaNegITSCls()); + histos.fill(HIST(MainDir[mode]) + HIST("/Lambda/hPosChi2PerNc"), sigma.lambdaPosChi2PerNcl()); + histos.fill(HIST(MainDir[mode]) + HIST("/Lambda/hNegChi2PerNc"), sigma.lambdaNegChi2PerNcl()); + histos.fill(HIST(MainDir[mode]) + HIST("/Lambda/hLifeTime"), sigma.lambdaLifeTime()); + + //_______________________________________ + // Sigmas and Lambdas + histos.fill(HIST(MainDir[mode]) + HIST("/h2dArmenteros"), sigma.photonAlpha(), sigma.photonQt()); + histos.fill(HIST(MainDir[mode]) + HIST("/h2dArmenteros"), sigma.lambdaAlpha(), sigma.lambdaQt()); + + if (sigma.lambdaAlpha() > 0) { + histos.fill(HIST(MainDir[mode]) + HIST("/Lambda/h2dTPCvsTOFNSigma_LambdaPr"), sigma.lambdaPosPrTPCNSigma(), sigma.lambdaPrTOFNSigma()); + histos.fill(HIST(MainDir[mode]) + HIST("/Lambda/h2dTPCvsTOFNSigma_LambdaPi"), sigma.lambdaNegPiTPCNSigma(), sigma.lambdaPiTOFNSigma()); + histos.fill(HIST(MainDir[mode]) + HIST("/Lambda/hLambdaDCANegToPV"), sigma.lambdaDCANegPV()); + histos.fill(HIST(MainDir[mode]) + HIST("/Lambda/hLambdaDCAPosToPV"), sigma.lambdaDCAPosPV()); + histos.fill(HIST(MainDir[mode]) + HIST("/Lambda/hLambdapT"), sigma.lambdaPt()); + histos.fill(HIST(MainDir[mode]) + HIST("/Lambda/hLambdaMass"), sigma.lambdaMass()); + histos.fill(HIST(MainDir[mode]) + HIST("/Lambda/h3dLambdaMass"), sigma.sigmaCentrality(), sigma.lambdaPt(), sigma.lambdaMass()); + + histos.fill(HIST(MainDir[mode]) + HIST("/Sigma0/hMass"), sigma.sigmaMass()); + histos.fill(HIST(MainDir[mode]) + HIST("/Sigma0/hPt"), sigma.sigmapT()); + histos.fill(HIST(MainDir[mode]) + HIST("/Sigma0/hY"), sigma.sigmaRapidity()); + histos.fill(HIST(MainDir[mode]) + HIST("/Sigma0/h3dMass"), sigma.sigmaCentrality(), sigma.sigmapT(), sigma.sigmaMass()); + histos.fill(HIST(MainDir[mode]) + HIST("/Sigma0/h3dPhotonRadiusVsMassSigma"), sigma.sigmaCentrality(), sigma.photonRadius(), sigma.sigmaMass()); + histos.fill(HIST(MainDir[mode]) + HIST("/Sigma0/h2dpTVsOPAngle"), sigma.sigmapT(), sigma.sigmaOPAngle()); + } else { + histos.fill(HIST(MainDir[mode]) + HIST("/Lambda/h2dTPCvsTOFNSigma_ALambdaPr"), sigma.lambdaNegPrTPCNSigma(), sigma.aLambdaPrTOFNSigma()); + histos.fill(HIST(MainDir[mode]) + HIST("/Lambda/h2dTPCvsTOFNSigma_ALambdaPi"), sigma.lambdaPosPiTPCNSigma(), sigma.aLambdaPiTOFNSigma()); + histos.fill(HIST(MainDir[mode]) + HIST("/Lambda/hALambdaDCANegToPV"), sigma.lambdaDCANegPV()); + histos.fill(HIST(MainDir[mode]) + HIST("/Lambda/hALambdaDCAPosToPV"), sigma.lambdaDCAPosPV()); + histos.fill(HIST(MainDir[mode]) + HIST("/Lambda/hALambdapT"), sigma.lambdaPt()); + histos.fill(HIST(MainDir[mode]) + HIST("/Lambda/hAntiLambdaMass"), sigma.antilambdaMass()); + histos.fill(HIST(MainDir[mode]) + HIST("/Lambda/h3dAntiLambdaMass"), sigma.sigmaCentrality(), sigma.lambdaPt(), sigma.antilambdaMass()); + + histos.fill(HIST(MainDir[mode]) + HIST("/ASigma0/hMass"), sigma.sigmaMass()); + histos.fill(HIST(MainDir[mode]) + HIST("/ASigma0/hPt"), sigma.sigmapT()); + histos.fill(HIST(MainDir[mode]) + HIST("/ASigma0/hY"), sigma.sigmaRapidity()); + histos.fill(HIST(MainDir[mode]) + HIST("/ASigma0/h3dMass"), sigma.sigmaCentrality(), sigma.sigmapT(), sigma.sigmaMass()); + histos.fill(HIST(MainDir[mode]) + HIST("/ASigma0/h3dPhotonRadiusVsMassSigma"), sigma.sigmaCentrality(), sigma.photonRadius(), sigma.sigmaMass()); + histos.fill(HIST(MainDir[mode]) + HIST("/ASigma0/h2dpTVsOPAngle"), sigma.sigmapT(), sigma.sigmaOPAngle()); } - histos.fill(HIST("hEventSelection"), 2 /* FT0 vertex (acceptable FT0C-FT0A time difference) collisions */); - if (eventSelections.rejectITSROFBorder && !collision.selection_bit(o2::aod::evsel::kNoITSROFrameBorder)) { - return false; + + //_______________________________________ + // MC specific + if (doprocessMonteCarlo) { + if constexpr (requires { sigma.lambdaCandPDGCode(); sigma.photonCandPDGCode(); }) { + + //_______________________________________ + // Gamma MC association + if (sigma.photonCandPDGCode() == 22) { + histos.fill(HIST(MainDir[mode]) + HIST("/MC/Photon/hV0ToCollAssoc"), sigma.photonIsCorrectlyAssoc()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/Photon/hPt"), sigma.photonPt()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/Photon/hMCPt"), sigma.photonMCPt()); + + histos.fill(HIST(MainDir[mode]) + HIST("/MC/Photon/h2dPosTPCNSigmaEl"), sigma.photonPosPt(), sigma.photonPosTPCNSigmaEl()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/Photon/h2dNegTPCNSigmaEl"), sigma.photonNegPt(), sigma.photonNegTPCNSigmaEl()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/Photon/h2dPosTPCNSigmaPi"), sigma.photonPosPt(), sigma.photonPosTPCNSigmaPi()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/Photon/h2dNegTPCNSigmaPi"), sigma.photonNegPt(), sigma.photonNegTPCNSigmaPi()); + + histos.fill(HIST(MainDir[mode]) + HIST("/MC/Photon/h2dIRVsPt"), sigma.sigmaIR(), sigma.photonMCPt()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/Photon/h3dPAVsIRVsPt"), TMath::ACos(sigma.photonCosPA()), sigma.sigmaIR(), sigma.photonMCPt()); + + if (!sigma.photonIsCorrectlyAssoc()) { + histos.fill(HIST(MainDir[mode]) + HIST("/MC/Photon/h2dIRVsPt_BadCollAssig"), sigma.sigmaIR(), sigma.photonMCPt()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/Photon/h3dPAVsIRVsPt_BadCollAssig"), TMath::ACos(sigma.photonCosPA()), sigma.sigmaIR(), sigma.photonMCPt()); + } + } + + //_______________________________________ + // Lambda MC association + if (sigma.lambdaCandPDGCode() == 3122) { + histos.fill(HIST(MainDir[mode]) + HIST("/MC/Lambda/hV0ToCollAssoc"), sigma.lambdaIsCorrectlyAssoc()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/Lambda/hPt"), sigma.lambdaPt()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/Lambda/hMCPt"), sigma.lambdaMCPt()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/Lambda/h3dTPCvsTOFNSigma_Pr"), sigma.lambdaPosPrTPCNSigma(), sigma.lambdaPrTOFNSigma(), sigma.lambdaPt()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/Lambda/h3dTPCvsTOFNSigma_Pi"), sigma.lambdaNegPiTPCNSigma(), sigma.lambdaPiTOFNSigma(), sigma.lambdaPt()); + } + + //_______________________________________ + // AntiLambda MC association + if (sigma.lambdaCandPDGCode() == -3122) { + histos.fill(HIST(MainDir[mode]) + HIST("/MC/ALambda/hV0ToCollAssoc"), sigma.lambdaIsCorrectlyAssoc()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/ALambda/hPt"), sigma.lambdaPt()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/ALambda/hMCPt"), sigma.lambdaMCPt()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/ALambda/h3dTPCvsTOFNSigma_Pr"), sigma.lambdaNegPrTPCNSigma(), sigma.aLambdaPrTOFNSigma(), sigma.lambdaPt()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/ALambda/h3dTPCvsTOFNSigma_Pi"), sigma.lambdaPosPiTPCNSigma(), sigma.aLambdaPiTOFNSigma(), sigma.lambdaPt()); + } + + //_______________________________________ + // Sigma0 MC association + if (sigma.isSigma()) { + histos.fill(HIST(MainDir[mode]) + HIST("/MC/h2dArmenteros"), sigma.photonAlpha(), sigma.photonQt()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/h2dArmenteros"), sigma.lambdaAlpha(), sigma.lambdaQt()); + + histos.fill(HIST(MainDir[mode]) + HIST("/MC/Sigma0/hPt"), sigma.sigmapT()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/Sigma0/hMCPt"), sigma.sigmaMCPt()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/Sigma0/h2dMCPtVsLambdaMCPt"), sigma.sigmaMCPt(), sigma.lambdaMCPt()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/Sigma0/h2dMCPtVsGammaMCPt"), sigma.sigmaMCPt(), sigma.photonMCPt()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/Sigma0/hMass"), sigma.sigmaMass()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/Sigma0/h3dMass"), sigma.sigmaCentrality(), sigma.sigmapT(), sigma.sigmaMass()); + } + + //_______________________________________ + // AntiSigma0 MC association + if (sigma.isAntiSigma()) { + histos.fill(HIST(MainDir[mode]) + HIST("/MC/h2dArmenteros"), sigma.photonAlpha(), sigma.photonQt()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/h2dArmenteros"), sigma.lambdaAlpha(), sigma.lambdaQt()); + + histos.fill(HIST(MainDir[mode]) + HIST("/MC/ASigma0/hPt"), sigma.sigmapT()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/ASigma0/hMCPt"), sigma.sigmaMCPt()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/ASigma0/h2dMCPtVsLambdaMCPt"), sigma.sigmaMCPt(), sigma.lambdaMCPt()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/ASigma0/h2dMCPtVsPhotonMCPt"), sigma.sigmaMCPt(), sigma.photonMCPt()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/ASigma0/hMass"), sigma.sigmaMass()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/ASigma0/h3dMass"), sigma.sigmaCentrality(), sigma.sigmapT(), sigma.sigmaMass()); + } + + // For background studies: + if (fillBkgQAhistos) + runBkgAnalysis(sigma); + + //_______________________________________ + // pT resolution histos + if ((mode == 0) && fillpTResoQAhistos) + getpTResolution(sigma); + } } - histos.fill(HIST("hEventSelection"), 3 /* Not at ITS ROF border */); - if (eventSelections.rejectTFBorder && !collision.selection_bit(o2::aod::evsel::kNoTimeFrameBorder)) { - return false; + } + + template + void fillSelHistos(TV0Object const& sigma, int PDGRequired) + { + + static constexpr std::string_view PhotonSelsLocal[] = {"NoSel", "V0Type", "DaupT", "DCADauToPV", + "DCADau", "DauTPCCR", "TPCNSigmaEl", "V0pT", + "Y", "V0Radius", "RZCut", "Armenteros", "CosPA", + "PsiPair", "Phi", "Mass"}; + + static constexpr std::string_view LambdaSelsLocal[] = {"NoSel", "V0Radius", "DCADau", "Armenteros", + "CosPA", "Y", "TPCCR", "DauITSCls", "Lifetime", + "TPCTOFPID", "DCADauToPV", "Mass"}; + + if (PDGRequired == 22) { + if constexpr (selection_index >= 0 && selection_index < (int)std::size(PhotonSelsLocal)) { + histos.fill(HIST("Selection/Photon/hCandidateSel"), selection_index); + histos.fill(HIST("Selection/Photon/h2d") + HIST(PhotonSelsLocal[selection_index]), sigma.photonPt(), sigma.photonMass()); + histos.fill(HIST("Selection/Sigma0/h2dPhoton") + HIST(PhotonSelsLocal[selection_index]), sigma.sigmapT(), sigma.sigmaMass()); + } } - histos.fill(HIST("hEventSelection"), 4 /* Not at TF border */); - if (std::abs(collision.posZ()) > eventSelections.maxZVtxPosition) { - return false; + + if (PDGRequired == 3122) { + if constexpr (selection_index >= 0 && selection_index < (int)std::size(LambdaSelsLocal)) { + histos.fill(HIST("Selection/Lambda/hCandidateSel"), selection_index); + histos.fill(HIST("Selection/Lambda/h2d") + HIST(LambdaSelsLocal[selection_index]), sigma.lambdaPt(), sigma.lambdaMass()); + histos.fill(HIST("Selection/Sigma0/h2dLambda") + HIST(LambdaSelsLocal[selection_index]), sigma.sigmapT(), sigma.sigmaMass()); + } } - histos.fill(HIST("hEventSelection"), 5 /* vertex-Z selected */); - if (eventSelections.requireIsVertexITSTPC && !collision.selection_bit(o2::aod::evsel::kIsVertexITSTPC)) { + } + + // Apply specific selections for photons + template + bool selectPhoton(TV0Object const& cand) + { + fillSelHistos<0>(cand, 22); + if (cand.photonV0Type() != Photonv0TypeSel && Photonv0TypeSel > -1) return false; - } - histos.fill(HIST("hEventSelection"), 6 /* Contains at least one ITS-TPC track */); - if (eventSelections.requireIsGoodZvtxFT0VsPV && !collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) { + + fillSelHistos<1>(cand, 22); + if ((cand.photonPosPt() < PhotonDauMinPt) || (cand.photonNegPt() < PhotonDauMinPt)) return false; - } - histos.fill(HIST("hEventSelection"), 7 /* PV position consistency check */); - if (eventSelections.requireIsVertexTOFmatched && !collision.selection_bit(o2::aod::evsel::kIsVertexTOFmatched)) { + + fillSelHistos<2>(cand, 22); + if ((TMath::Abs(cand.photonDCAPosPV()) < PhotonMinDCADauToPv) || (TMath::Abs(cand.photonDCANegPV()) < PhotonMinDCADauToPv)) return false; - } - histos.fill(HIST("hEventSelection"), 8 /* PV with at least one contributor matched with TOF */); - if (eventSelections.requireIsVertexTRDmatched && !collision.selection_bit(o2::aod::evsel::kIsVertexTRDmatched)) { + + fillSelHistos<3>(cand, 22); + if (TMath::Abs(cand.photonDCADau()) > PhotonMaxDCAV0Dau) return false; - } - histos.fill(HIST("hEventSelection"), 9 /* PV with at least one contributor matched with TRD */); - if (eventSelections.rejectSameBunchPileup && !collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) { + + fillSelHistos<4>(cand, 22); + if ((cand.photonPosTPCCrossedRows() < PhotonMinTPCCrossedRows) || (cand.photonNegTPCCrossedRows() < PhotonMinTPCCrossedRows)) return false; - } - histos.fill(HIST("hEventSelection"), 10 /* Not at same bunch pile-up */); - if (eventSelections.requireNoCollInTimeRangeStd && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { + + fillSelHistos<5>(cand, 22); + if (((cand.photonPosTPCNSigmaEl() < PhotonMinTPCNSigmas) || (cand.photonPosTPCNSigmaEl() > PhotonMaxTPCNSigmas))) return false; - } - histos.fill(HIST("hEventSelection"), 11 /* No other collision within +/- 2 microseconds or mult above a certain threshold in -4 - -2 microseconds*/); - if (eventSelections.requireNoCollInTimeRangeStrict && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStrict)) { + + if (((cand.photonNegTPCNSigmaEl() < PhotonMinTPCNSigmas) || (cand.photonNegTPCNSigmaEl() > PhotonMaxTPCNSigmas))) return false; - } - histos.fill(HIST("hEventSelection"), 12 /* No other collision within +/- 10 microseconds */); - if (eventSelections.requireNoCollInTimeRangeNarrow && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeNarrow)) { + + fillSelHistos<6>(cand, 22); + if ((cand.photonPt() < PhotonMinPt) || (cand.photonPt() > PhotonMaxPt)) return false; - } - histos.fill(HIST("hEventSelection"), 13 /* No other collision within +/- 2 microseconds */); - if (eventSelections.requireNoCollInROFStd && !collision.selection_bit(o2::aod::evsel::kNoCollInRofStandard)) { + + fillSelHistos<7>(cand, 22); + if ((TMath::Abs(cand.photonY()) > PhotonMaxRap) || (TMath::Abs(cand.photonPosEta()) > PhotonMaxDauEta) || (TMath::Abs(cand.photonNegEta()) > PhotonMaxDauEta)) return false; - } - histos.fill(HIST("hEventSelection"), 14 /* No other collision within the same ITS ROF with mult. above a certain threshold */); - if (eventSelections.requireNoCollInROFStrict && !collision.selection_bit(o2::aod::evsel::kNoCollInRofStrict)) { + + fillSelHistos<8>(cand, 22); + if ((cand.photonRadius() < PhotonMinRadius) || (cand.photonRadius() > PhotonMaxRadius)) return false; - } - histos.fill(HIST("hEventSelection"), 15 /* No other collision within the same ITS ROF */); - if (doPPAnalysis) { // we are in pp - if (eventSelections.requireINEL0 && collision.multNTracksPVeta1() < 1) { + + fillSelHistos<9>(cand, 22); + float photonRZLineCut = TMath::Abs(cand.photonZconv()) * TMath::Tan(2 * TMath::ATan(TMath::Exp(-PhotonMaxDauEta))) - PhotonLineCutZ0; + if ((TMath::Abs(cand.photonRadius()) < photonRZLineCut) || (TMath::Abs(cand.photonZconv()) > PhotonMaxZ)) + return false; + + fillSelHistos<10>(cand, 22); + if (cand.photonQt() > PhotonMaxQt) + return false; + + if (TMath::Abs(cand.photonAlpha()) > PhotonMaxAlpha) + return false; + + fillSelHistos<11>(cand, 22); + if (cand.photonCosPA() < PhotonMinV0cospa) + return false; + + fillSelHistos<12>(cand, 22); + if (TMath::Abs(cand.photonPsiPair()) > PhotonPsiPairMax) + return false; + + fillSelHistos<13>(cand, 22); + if ((((cand.photonPhi() > PhotonPhiMin1) && (cand.photonPhi() < PhotonPhiMax1)) || ((cand.photonPhi() > PhotonPhiMin2) && (cand.photonPhi() < PhotonPhiMax2))) && ((PhotonPhiMin1 != -1) && (PhotonPhiMax1 != -1) && (PhotonPhiMin2 != -1) && (PhotonPhiMax2 != -1))) + return false; + + fillSelHistos<14>(cand, 22); + if (TMath::Abs(cand.photonMass()) > PhotonMaxMass) + return false; + + fillSelHistos<15>(cand, 22); + return true; + } + + // Apply specific selections for lambdas + template + bool selectLambda(TV0Object const& cand) + { + fillSelHistos<0>(cand, 3122); + if ((cand.lambdaRadius() < LambdaMinv0radius) || (cand.lambdaRadius() > LambdaMaxv0radius)) + return false; + + fillSelHistos<1>(cand, 3122); + if (TMath::Abs(cand.lambdaDCADau()) > LambdaMaxDCAV0Dau) + return false; + + fillSelHistos<2>(cand, 3122); + if ((cand.lambdaQt() < LambdaMinQt) || (cand.lambdaQt() > LambdaMaxQt)) + return false; + + if ((TMath::Abs(cand.lambdaAlpha()) < LambdaMinAlpha) || (TMath::Abs(cand.lambdaAlpha()) > LambdaMaxAlpha)) + return false; + + fillSelHistos<3>(cand, 3122); + if (cand.lambdaCosPA() < LambdaMinv0cospa) + return false; + + fillSelHistos<4>(cand, 3122); + if ((TMath::Abs(cand.lambdaY()) > LambdaMaxRap) || (TMath::Abs(cand.lambdaPosEta()) > LambdaMaxDauEta) || (TMath::Abs(cand.lambdaNegEta()) > LambdaMaxDauEta)) + return false; + + fillSelHistos<5>(cand, 3122); + if ((cand.lambdaPosTPCCrossedRows() < LambdaMinTPCCrossedRows) || (cand.lambdaNegTPCCrossedRows() < LambdaMinTPCCrossedRows)) + return false; + + fillSelHistos<6>(cand, 3122); + // check minimum number of ITS clusters + reject ITS afterburner tracks if requested + bool posIsFromAfterburner = cand.lambdaPosChi2PerNcl() < 0; + bool negIsFromAfterburner = cand.lambdaNegChi2PerNcl() < 0; + if (cand.lambdaPosITSCls() < LambdaMinITSclusters && (!LambdaRejectPosITSafterburner || posIsFromAfterburner)) + return false; + if (cand.lambdaNegITSCls() < LambdaMinITSclusters && (!LambdaRejectNegITSafterburner || negIsFromAfterburner)) + return false; + + fillSelHistos<7>(cand, 3122); + if (cand.lambdaLifeTime() > LambdaMaxLifeTime) + return false; + + // Separating lambda and antilambda selections: + fillSelHistos<8>(cand, 3122); + if (cand.lambdaAlpha() > 0) { // Lambda selection + // TPC Selection + if (fselLambdaTPCPID && (TMath::Abs(cand.lambdaPosPrTPCNSigma()) > LambdaMaxTPCNSigmas)) return false; - } - histos.fill(HIST("hEventSelection"), 16 /* INEL > 0 */); - if (eventSelections.requireINEL1 && collision.multNTracksPVeta1() < 2) { + if (fselLambdaTPCPID && (TMath::Abs(cand.lambdaNegPiTPCNSigma()) > LambdaMaxTPCNSigmas)) return false; - } - histos.fill(HIST("hEventSelection"), 17 /* INEL > 1 */); - } else { // we are in Pb-Pb - float collisionOccupancy = eventSelections.useFT0CbasedOccupancy ? collision.ft0cOccupancyInTimeRange() : collision.trackOccupancyInTimeRange(); - if (eventSelections.minOccupancy >= 0 && collisionOccupancy < eventSelections.minOccupancy) { + + // TOF Selection + if (fselLambdaTOFPID && (TMath::Abs(cand.lambdaPrTOFNSigma()) > LambdaPrMaxTOFNSigmas)) return false; - } - histos.fill(HIST("hEventSelection"), 16 /* Below min occupancy */); - if (eventSelections.maxOccupancy >= 0 && collisionOccupancy > eventSelections.maxOccupancy) { + if (fselLambdaTOFPID && (TMath::Abs(cand.lambdaPiTOFNSigma()) > LambdaPiMaxTOFNSigmas)) return false; - } - histos.fill(HIST("hEventSelection"), 17 /* Above max occupancy */); + + // DCA Selection + fillSelHistos<9>(cand, 3122); + if ((TMath::Abs(cand.lambdaDCAPosPV()) < LambdaMinDCAPosToPv) || (TMath::Abs(cand.lambdaDCANegPV()) < LambdaMinDCANegToPv)) + return false; + + // Mass Selection + fillSelHistos<10>(cand, 3122); + if (TMath::Abs(cand.lambdaMass() - o2::constants::physics::MassLambda0) > LambdaWindow) + return false; + + fillSelHistos<11>(cand, 3122); + + } else { // AntiLambda selection + + // TPC Selection + if (fselLambdaTPCPID && (TMath::Abs(cand.lambdaPosPiTPCNSigma()) > LambdaMaxTPCNSigmas)) + return false; + if (fselLambdaTPCPID && (TMath::Abs(cand.lambdaNegPrTPCNSigma()) > LambdaMaxTPCNSigmas)) + return false; + + // TOF Selection + if (fselLambdaTOFPID && (TMath::Abs(cand.aLambdaPrTOFNSigma()) > LambdaPrMaxTOFNSigmas)) + return false; + if (fselLambdaTOFPID && (TMath::Abs(cand.aLambdaPiTOFNSigma()) > LambdaPiMaxTOFNSigmas)) + return false; + + // DCA Selection + fillSelHistos<9>(cand, 3122); + if ((TMath::Abs(cand.lambdaDCAPosPV()) < ALambdaMinDCAPosToPv) || (TMath::Abs(cand.lambdaDCANegPV()) < ALambdaMinDCANegToPv)) + return false; + + // Mass Selection + fillSelHistos<10>(cand, 3122); + if (TMath::Abs(cand.antilambdaMass() - o2::constants::physics::MassLambda0) > LambdaWindow) + return false; + + fillSelHistos<11>(cand, 3122); } + return true; } - // Apply selections in sigma candidates + // Apply selections in sigma0 candidates template - bool processSigmaCandidate(TV0Object const& cand, bool isLambdalike) + bool processSigmaCandidate(TV0Object const& cand) { + // Optionally Select on Interaction Rate + if (fGetIR && (maxIR != -1) && (minIR != -1) && ((cand.sigmaIR() <= minIR) || (cand.sigmaIR() >= maxIR))) { + return false; + } + + // Do ML analysis if (fUseMLSel) { if ((cand.gammaBDTScore() == -1) || (cand.lambdaBDTScore() == -1) || (cand.antilambdaBDTScore() == -1)) { LOGF(fatal, "ML Score is not available! Please, enable gamma and lambda selection with ML in sigmabuilder!"); } - // Gamma selection: + // Photon selection: if (cand.gammaBDTScore() <= Gamma_MLThreshold) return false; @@ -615,311 +885,25 @@ struct sigmaanalysis { // AntiLambda selection: if (cand.antilambdaBDTScore() <= AntiLambda_MLThreshold) return false; - } else { - bool isMCTrueLambda = false; - bool isMCTruePhoton = false; - if constexpr (requires { cand.lambdaCandPDGCode(); cand.photonCandPDGCode(); }) { - if (cand.photonCandPDGCode() == 22) - isMCTruePhoton = true; - if (cand.lambdaCandPDGCode() == 3122) - isMCTrueLambda = true; - } + } - // Photon Selections - histos.fill(HIST("GeneralQA/hCandidateAnalysisSelection"), 1.); - histos.fill(HIST("GeneralQA/hPhotonV0Type"), cand.photonV0Type()); - if ((isMCTruePhoton || doPhotonLambdaSelQA) && (TMath::Abs(cand.photonMass()) <= PhotonMaxMass)) - histos.fill(HIST("PhotonSelQA/h2dPhotonBaseline"), cand.photonPt(), cand.photonMass()); - if (cand.photonV0Type() != Photonv0TypeSel && Photonv0TypeSel > -1) - return false; - histos.fill(HIST("SigmaSelQA/h2dPhotonV0Type"), cand.sigmapT(), cand.sigmaMass()); - if ((isMCTruePhoton || doPhotonLambdaSelQA) && (TMath::Abs(cand.photonMass()) <= PhotonMaxMass)) - histos.fill(HIST("PhotonSelQA/h2dPhotonV0Type"), cand.photonPt(), cand.photonMass()); - - // histos.fill(HIST("GeneralQA/h3dPhotonMass"), cand.sigmaCentrality(), cand.photonPt(), cand.photonMass()); - // histos.fill(HIST("GeneralQA/hCandidateAnalysisSelection"), 2.); - // if (TMath::Abs(cand.photonMass()) > PhotonMaxMass) - // return false; - // histos.fill(HIST("SigmaSelQA/h2dPhotonMass"), cand.sigmapT(), cand.sigmaMass()); - // if (isMCTruePhoton || doPhotonLambdaSelQA) histos.fill(HIST("PhotonSelQA/h2dPhotonMass"), cand.photonPt(), cand.photonMass()); - - histos.fill(HIST("GeneralQA/hPhotonNegpT"), cand.photonNegPt()); - histos.fill(HIST("GeneralQA/hPhotonPospT"), cand.photonPosPt()); - histos.fill(HIST("GeneralQA/hCandidateAnalysisSelection"), 2.); - if ((cand.photonPosPt() < PhotonDauMinPt) || (cand.photonNegPt() < PhotonDauMinPt)) - return false; - histos.fill(HIST("SigmaSelQA/h2dPhotonDaupT"), cand.sigmapT(), cand.sigmaMass()); - if ((isMCTruePhoton || doPhotonLambdaSelQA) && (TMath::Abs(cand.photonMass()) <= PhotonMaxMass)) - histos.fill(HIST("PhotonSelQA/h2dPhotonDaupT"), cand.photonPt(), cand.photonMass()); - histos.fill(HIST("GeneralQA/hPhotonDCANegToPV"), cand.photonDCANegPV()); - histos.fill(HIST("GeneralQA/hPhotonDCAPosToPV"), cand.photonDCAPosPV()); - histos.fill(HIST("GeneralQA/hCandidateAnalysisSelection"), 3.); - if ((TMath::Abs(cand.photonDCAPosPV()) < PhotonMinDCADauToPv) || (TMath::Abs(cand.photonDCANegPV()) < PhotonMinDCADauToPv)) - return false; - histos.fill(HIST("SigmaSelQA/h2dPhotonDCADauToPV"), cand.sigmapT(), cand.sigmaMass()); - if ((isMCTruePhoton || doPhotonLambdaSelQA) && (TMath::Abs(cand.photonMass()) <= PhotonMaxMass)) - histos.fill(HIST("PhotonSelQA/h2dPhotonDCADauToPV"), cand.photonPt(), cand.photonMass()); - histos.fill(HIST("GeneralQA/hCandidateAnalysisSelection"), 4.); - histos.fill(HIST("GeneralQA/hPhotonDCADau"), cand.photonDCADau()); - if (TMath::Abs(cand.photonDCADau()) > PhotonMaxDCAV0Dau) - return false; - histos.fill(HIST("SigmaSelQA/h2dPhotonDCADau"), cand.sigmapT(), cand.sigmaMass()); - if ((isMCTruePhoton || doPhotonLambdaSelQA) && (TMath::Abs(cand.photonMass()) <= PhotonMaxMass)) - histos.fill(HIST("PhotonSelQA/h2dPhotonDCADau"), cand.photonPt(), cand.photonMass()); - histos.fill(HIST("GeneralQA/hPhotonPosTPCCR"), cand.photonPosTPCCrossedRows()); - histos.fill(HIST("GeneralQA/hPhotonNegTPCCR"), cand.photonNegTPCCrossedRows()); - histos.fill(HIST("GeneralQA/hCandidateAnalysisSelection"), 5.); - if ((cand.photonPosTPCCrossedRows() < PhotonMinTPCCrossedRows) || (cand.photonNegTPCCrossedRows() < PhotonMinTPCCrossedRows)) - return false; - histos.fill(HIST("SigmaSelQA/h2dPhotonDauTPCCR"), cand.sigmapT(), cand.sigmaMass()); - if ((isMCTruePhoton || doPhotonLambdaSelQA) && (TMath::Abs(cand.photonMass()) <= PhotonMaxMass)) - histos.fill(HIST("PhotonSelQA/h2dPhotonDauTPCCR"), cand.photonPt(), cand.photonMass()); - histos.fill(HIST("GeneralQA/h2dPhotonPosTPCNSigmaEl"), cand.photonPosPt(), cand.photonPosTPCNSigmaEl()); - histos.fill(HIST("GeneralQA/hCandidateAnalysisSelection"), 6.); - if (((cand.photonPosTPCNSigmaEl() < PhotonMinTPCNSigmas) || (cand.photonPosTPCNSigmaEl() > PhotonMaxTPCNSigmas))) - return false; - histos.fill(HIST("GeneralQA/h2dPhotonNegTPCNSigmaEl"), cand.photonNegPt(), cand.photonNegTPCNSigmaEl()); - if (((cand.photonNegTPCNSigmaEl() < PhotonMinTPCNSigmas) || (cand.photonNegTPCNSigmaEl() > PhotonMaxTPCNSigmas))) - return false; - histos.fill(HIST("SigmaSelQA/h2dPhotonTPCNSigmaEl"), cand.sigmapT(), cand.sigmaMass()); - if ((isMCTruePhoton || doPhotonLambdaSelQA) && (TMath::Abs(cand.photonMass()) <= PhotonMaxMass)) - histos.fill(HIST("PhotonSelQA/h2dPhotonTPCNSigmaEl"), cand.photonPt(), cand.photonMass()); - histos.fill(HIST("GeneralQA/h2dPhotonPosTPCNSigmaPi"), cand.photonPosPt(), cand.photonPosTPCNSigmaPi()); - histos.fill(HIST("GeneralQA/hCandidateAnalysisSelection"), 7.); - if (((TMath::Abs(cand.photonPosTPCNSigmaPi()) < PiMaxTPCNSigmas) && cand.photonPosPt() <= piMaxpT)) - return false; - histos.fill(HIST("GeneralQA/h2dPhotonNegTPCNSigmaPi"), cand.photonNegPt(), cand.photonNegTPCNSigmaPi()); - if (((TMath::Abs(cand.photonNegTPCNSigmaPi()) < PiMaxTPCNSigmas) && cand.photonNegPt() <= piMaxpT)) - return false; - histos.fill(HIST("GeneralQA/hPhotonpT"), cand.photonPt()); - histos.fill(HIST("GeneralQA/hCandidateAnalysisSelection"), 8.); - if ((cand.photonPt() < PhotonMinPt) || (cand.photonPt() > PhotonMaxPt)) - return false; - histos.fill(HIST("SigmaSelQA/h2dPhotonpT"), cand.sigmapT(), cand.sigmaMass()); - if ((isMCTruePhoton || doPhotonLambdaSelQA) && (TMath::Abs(cand.photonMass()) <= PhotonMaxMass)) - histos.fill(HIST("PhotonSelQA/h2dPhotonpT"), cand.photonPt(), cand.photonMass()); - histos.fill(HIST("GeneralQA/hPhotonY"), cand.photonY()); - histos.fill(HIST("GeneralQA/hPhotonPosEta"), cand.photonPosEta()); - histos.fill(HIST("GeneralQA/hPhotonNegEta"), cand.photonNegEta()); - histos.fill(HIST("GeneralQA/hCandidateAnalysisSelection"), 9.); - if ((TMath::Abs(cand.photonY()) > PhotonMaxRap) || (TMath::Abs(cand.photonPosEta()) > PhotonMaxDauEta) || (TMath::Abs(cand.photonNegEta()) > PhotonMaxDauEta)) - return false; - histos.fill(HIST("SigmaSelQA/h2dPhotonY"), cand.sigmapT(), cand.sigmaMass()); - if ((isMCTruePhoton || doPhotonLambdaSelQA) && (TMath::Abs(cand.photonMass()) <= PhotonMaxMass)) - histos.fill(HIST("PhotonSelQA/h2dPhotonY"), cand.photonPt(), cand.photonMass()); - histos.fill(HIST("GeneralQA/hPhotonRadius"), cand.photonRadius()); - histos.fill(HIST("GeneralQA/hCandidateAnalysisSelection"), 10.); - if ((cand.photonRadius() < PhotonMinRadius) || (cand.photonRadius() > PhotonMaxRadius)) - return false; - float photonRZLineCut = TMath::Abs(cand.photonZconv()) * TMath::Tan(2 * TMath::ATan(TMath::Exp(-PhotonMaxDauEta))) - PhotonLineCutZ0; - histos.fill(HIST("SigmaSelQA/h2dPhotonRadius"), cand.sigmapT(), cand.sigmaMass()); - if ((isMCTruePhoton || doPhotonLambdaSelQA) && (TMath::Abs(cand.photonMass()) <= PhotonMaxMass)) - histos.fill(HIST("PhotonSelQA/h2dPhotonRadius"), cand.photonPt(), cand.photonMass()); - histos.fill(HIST("GeneralQA/hPhotonZ"), cand.photonZconv()); - histos.fill(HIST("GeneralQA/h2dRZCut"), cand.photonRadius(), photonRZLineCut); - histos.fill(HIST("GeneralQA/h2dRZPlane"), cand.photonZconv(), cand.photonRadius()); - histos.fill(HIST("GeneralQA/hCandidateAnalysisSelection"), 11.); - if ((TMath::Abs(cand.photonRadius()) < photonRZLineCut) || (TMath::Abs(cand.photonZconv()) > PhotonMaxZ)) - return false; - histos.fill(HIST("SigmaSelQA/h2dRZCut"), cand.sigmapT(), cand.sigmaMass()); - if ((isMCTruePhoton || doPhotonLambdaSelQA) && (TMath::Abs(cand.photonMass()) <= PhotonMaxMass)) - histos.fill(HIST("PhotonSelQA/h2dRZCut"), cand.photonPt(), cand.photonMass()); - histos.fill(HIST("GeneralQA/h2dPhotonArmenteros"), cand.photonAlpha(), cand.photonQt()); - histos.fill(HIST("GeneralQA/hCandidateAnalysisSelection"), 12.); - if (cand.photonQt() > PhotonMaxQt) - return false; - histos.fill(HIST("GeneralQA/hCandidateAnalysisSelection"), 13.); - if (TMath::Abs(cand.photonAlpha()) > PhotonMaxAlpha) - return false; - histos.fill(HIST("SigmaSelQA/h2dPhotonArmenteros"), cand.sigmapT(), cand.sigmaMass()); - if ((isMCTruePhoton || doPhotonLambdaSelQA) && (TMath::Abs(cand.photonMass()) <= PhotonMaxMass)) - histos.fill(HIST("PhotonSelQA/h2dPhotonArmenteros"), cand.photonPt(), cand.photonMass()); - histos.fill(HIST("GeneralQA/hCandidateAnalysisSelection"), 14.); - histos.fill(HIST("GeneralQA/hPhotonCosPA"), cand.photonCosPA()); - if (cand.photonCosPA() < PhotonMinV0cospa) - return false; - histos.fill(HIST("SigmaSelQA/h2dPhotonCosPA"), cand.sigmapT(), cand.sigmaMass()); - if ((isMCTruePhoton || doPhotonLambdaSelQA) && (TMath::Abs(cand.photonMass()) <= PhotonMaxMass)) - histos.fill(HIST("PhotonSelQA/h2dPhotonCosPA"), cand.photonPt(), cand.photonMass()); - histos.fill(HIST("GeneralQA/hCandidateAnalysisSelection"), 15.); - histos.fill(HIST("GeneralQA/hPhotonPsiPair"), cand.photonPsiPair()); - if (TMath::Abs(cand.photonPsiPair()) > PhotonPsiPairMax) - return false; - histos.fill(HIST("SigmaSelQA/h2dPhotonPsiPair"), cand.sigmapT(), cand.sigmaMass()); - if ((isMCTruePhoton || doPhotonLambdaSelQA) && (TMath::Abs(cand.photonMass()) <= PhotonMaxMass)) - histos.fill(HIST("PhotonSelQA/h2dPhotonPsiPair"), cand.photonPt(), cand.photonMass()); + // Go for standard analysis + else { - histos.fill(HIST("GeneralQA/hCandidateAnalysisSelection"), 16.); - histos.fill(HIST("GeneralQA/hPhotonPhi"), cand.photonPhi()); - if (((cand.photonPhi() < PhotonPhiMin1) || ((cand.photonPhi() > PhotonPhiMax1) && (cand.photonPhi() < PhotonPhiMin2)) || ((cand.photonPhi() > PhotonPhiMax2) && (PhotonPhiMax2 != -1)))) - return false; - if ((isMCTruePhoton || doPhotonLambdaSelQA) && (TMath::Abs(cand.photonMass()) <= PhotonMaxMass)) - histos.fill(HIST("PhotonSelQA/h2dPhotonPhi"), cand.photonPt(), cand.photonMass()); - histos.fill(HIST("GeneralQA/h3dPhotonMass"), cand.sigmaCentrality(), cand.photonPt(), cand.photonMass()); - histos.fill(HIST("GeneralQA/hCandidateAnalysisSelection"), 17.); - if (TMath::Abs(cand.photonMass()) > PhotonMaxMass) - return false; - histos.fill(HIST("SigmaSelQA/h2dPhotonMass"), cand.sigmapT(), cand.sigmaMass()); - if (isMCTruePhoton || doPhotonLambdaSelQA) - histos.fill(HIST("PhotonSelQA/h2dPhotonMass"), cand.photonPt(), cand.photonMass()); - - // #### - // Lambda selections - histos.fill(HIST("GeneralQA/hCandidateAnalysisSelection"), 18.); - histos.fill(HIST("GeneralQA/hLambdaRadius"), cand.lambdaRadius()); - if ((isMCTrueLambda || doPhotonLambdaSelQA) && (TMath::Abs(cand.lambdaMass() - o2::constants::physics::MassLambda0) < LambdaWindow)) - histos.fill(HIST("LambdaSelQA/h2dLambdaBaseline"), cand.lambdaPt(), cand.lambdaMass()); - if ((cand.lambdaRadius() < LambdaMinv0radius) || (cand.lambdaRadius() > LambdaMaxv0radius)) - return false; - histos.fill(HIST("SigmaSelQA/h2dLambdaRadius"), cand.sigmapT(), cand.sigmaMass()); - if ((isMCTrueLambda || doPhotonLambdaSelQA) && (TMath::Abs(cand.lambdaMass() - o2::constants::physics::MassLambda0) < LambdaWindow)) - histos.fill(HIST("LambdaSelQA/h2dLambdaRadius"), cand.lambdaPt(), cand.lambdaMass()); - histos.fill(HIST("GeneralQA/hLambdaDCADau"), cand.lambdaDCADau()); - histos.fill(HIST("GeneralQA/hCandidateAnalysisSelection"), 19.); - if (TMath::Abs(cand.lambdaDCADau()) > LambdaMaxDCAV0Dau) - return false; - histos.fill(HIST("SigmaSelQA/h2dLambdaDCADau"), cand.sigmapT(), cand.sigmaMass()); - if ((isMCTrueLambda || doPhotonLambdaSelQA) && (TMath::Abs(cand.lambdaMass() - o2::constants::physics::MassLambda0) < LambdaWindow)) - histos.fill(HIST("LambdaSelQA/h2dLambdaDCADau"), cand.lambdaPt(), cand.lambdaMass()); - histos.fill(HIST("GeneralQA/h2dLambdaArmenteros"), cand.lambdaAlpha(), cand.lambdaQt()); - histos.fill(HIST("GeneralQA/hCandidateAnalysisSelection"), 20.); - if ((cand.lambdaQt() < LambdaMinQt) || (cand.lambdaQt() > LambdaMaxQt)) - return false; - histos.fill(HIST("GeneralQA/hCandidateAnalysisSelection"), 21.); - if ((TMath::Abs(cand.lambdaAlpha()) < LambdaMinAlpha) || (TMath::Abs(cand.lambdaAlpha()) > LambdaMaxAlpha)) - return false; - histos.fill(HIST("SigmaSelQA/h2dLambdaArmenteros"), cand.sigmapT(), cand.sigmaMass()); - if ((isMCTrueLambda || doPhotonLambdaSelQA) && (TMath::Abs(cand.lambdaMass() - o2::constants::physics::MassLambda0) < LambdaWindow)) - histos.fill(HIST("LambdaSelQA/h2dLambdaArmenteros"), cand.lambdaPt(), cand.lambdaMass()); - histos.fill(HIST("GeneralQA/hLambdaCosPA"), cand.lambdaCosPA()); - histos.fill(HIST("GeneralQA/hCandidateAnalysisSelection"), 22.); - if (cand.lambdaCosPA() < LambdaMinv0cospa) - return false; - histos.fill(HIST("SigmaSelQA/h2dLambdaCosPA"), cand.sigmapT(), cand.sigmaMass()); - if ((isMCTrueLambda || doPhotonLambdaSelQA) && (TMath::Abs(cand.lambdaMass() - o2::constants::physics::MassLambda0) < LambdaWindow)) - histos.fill(HIST("LambdaSelQA/h2dLambdaCosPA"), cand.lambdaPt(), cand.lambdaMass()); - histos.fill(HIST("GeneralQA/hLambdaY"), cand.lambdaY()); - histos.fill(HIST("GeneralQA/hLambdaPosEta"), cand.lambdaPosEta()); - histos.fill(HIST("GeneralQA/hLambdaNegEta"), cand.lambdaNegEta()); - histos.fill(HIST("GeneralQA/hCandidateAnalysisSelection"), 23.); - if ((TMath::Abs(cand.lambdaY()) > LambdaMaxRap) || (TMath::Abs(cand.lambdaPosEta()) > LambdaMaxDauEta) || (TMath::Abs(cand.lambdaNegEta()) > LambdaMaxDauEta)) + // Photon specific selections + if (!selectPhoton(cand)) return false; - histos.fill(HIST("SigmaSelQA/h2dLambdaY"), cand.sigmapT(), cand.sigmaMass()); - if ((isMCTrueLambda || doPhotonLambdaSelQA) && (TMath::Abs(cand.lambdaMass() - o2::constants::physics::MassLambda0) < LambdaWindow)) - histos.fill(HIST("LambdaSelQA/h2dLambdaY"), cand.lambdaPt(), cand.lambdaMass()); - histos.fill(HIST("GeneralQA/hLambdaPosTPCCR"), cand.lambdaPosTPCCrossedRows()); - histos.fill(HIST("GeneralQA/hLambdaNegTPCCR"), cand.lambdaNegTPCCrossedRows()); - histos.fill(HIST("GeneralQA/hCandidateAnalysisSelection"), 24.); - if ((cand.lambdaPosTPCCrossedRows() < LambdaMinTPCCrossedRows) || (cand.lambdaNegTPCCrossedRows() < LambdaMinTPCCrossedRows)) - return false; - histos.fill(HIST("SigmaSelQA/h2dLambdaDauTPCCR"), cand.sigmapT(), cand.sigmaMass()); - if ((isMCTrueLambda || doPhotonLambdaSelQA) && (TMath::Abs(cand.lambdaMass() - o2::constants::physics::MassLambda0) < LambdaWindow)) - histos.fill(HIST("LambdaSelQA/h2dLambdaDauTPCCR"), cand.lambdaPt(), cand.lambdaMass()); - histos.fill(HIST("GeneralQA/hLambdaPosITSCls"), cand.lambdaPosITSCls()); - histos.fill(HIST("GeneralQA/hLambdaNegITSCls"), cand.lambdaNegITSCls()); - histos.fill(HIST("GeneralQA/hLambdaPosChi2PerNc"), cand.lambdaPosChi2PerNcl()); - histos.fill(HIST("GeneralQA/hLambdaNegChi2PerNc"), cand.lambdaNegChi2PerNcl()); - histos.fill(HIST("GeneralQA/hCandidateAnalysisSelection"), 25.); - // check minimum number of ITS clusters + reject ITS afterburner tracks if requested - bool posIsFromAfterburner = cand.lambdaPosChi2PerNcl() < 0; - bool negIsFromAfterburner = cand.lambdaNegChi2PerNcl() < 0; - if (cand.lambdaPosITSCls() < LambdaMinITSclusters && (!LambdaRejectPosITSafterburner || posIsFromAfterburner)) - return false; - if (cand.lambdaNegITSCls() < LambdaMinITSclusters && (!LambdaRejectNegITSafterburner || negIsFromAfterburner)) - return false; - histos.fill(HIST("SigmaSelQA/h2dLambdaDauITSCls"), cand.sigmapT(), cand.sigmaMass()); - if ((isMCTrueLambda || doPhotonLambdaSelQA) && (TMath::Abs(cand.lambdaMass() - o2::constants::physics::MassLambda0) < LambdaWindow)) - histos.fill(HIST("LambdaSelQA/h2dLambdaDauITSCls"), cand.lambdaPt(), cand.lambdaMass()); - histos.fill(HIST("GeneralQA/hLambdaLifeTime"), cand.lambdaLifeTime()); - histos.fill(HIST("GeneralQA/hCandidateAnalysisSelection"), 26.); - if (cand.lambdaLifeTime() > LambdaMaxLifeTime) + + // Lambda specific selections + if (!selectLambda(cand)) return false; - histos.fill(HIST("SigmaSelQA/h2dLambdaLifeTime"), cand.sigmapT(), cand.sigmaMass()); - if ((isMCTrueLambda || doPhotonLambdaSelQA) && (TMath::Abs(cand.lambdaMass() - o2::constants::physics::MassLambda0) < LambdaWindow)) - histos.fill(HIST("LambdaSelQA/h2dLambdaLifeTime"), cand.lambdaPt(), cand.lambdaMass()); - histos.fill(HIST("GeneralQA/hCandidateAnalysisSelection"), 27.); - // Separating lambda and antilambda selections: - if (isLambdalike) { // Lambda selection - histos.fill(HIST("GeneralQA/h2dTPCvsTOFNSigma_LambdaPr"), cand.lambdaPosPrTPCNSigma(), cand.lambdaPrTOFNSigma()); - histos.fill(HIST("GeneralQA/h2dTPCvsTOFNSigma_LambdaPi"), cand.lambdaNegPiTPCNSigma(), cand.lambdaPiTOFNSigma()); - - // TPC Selection - if (fselLambdaTPCPID && (TMath::Abs(cand.lambdaPosPrTPCNSigma()) > LambdaMaxTPCNSigmas)) - return false; - if (fselLambdaTPCPID && (TMath::Abs(cand.lambdaNegPiTPCNSigma()) > LambdaMaxTPCNSigmas)) - return false; - - // TOF Selection - if (fselLambdaTOFPID && (TMath::Abs(cand.lambdaPrTOFNSigma()) > LambdaPrMaxTOFNSigmas)) - return false; - if (fselLambdaTOFPID && (TMath::Abs(cand.lambdaPiTOFNSigma()) > LambdaPiMaxTOFNSigmas)) - return false; - - histos.fill(HIST("SigmaSelQA/h2dTPCvsTOFNSigma_Lambda"), cand.sigmapT(), cand.sigmaMass()); - if ((isMCTrueLambda || doPhotonLambdaSelQA) && (TMath::Abs(cand.lambdaMass() - o2::constants::physics::MassLambda0) < LambdaWindow)) - histos.fill(HIST("LambdaSelQA/h2dTPCvsTOFNSigma_Lambda"), cand.lambdaPt(), cand.lambdaMass()); - // DCA Selection - histos.fill(HIST("GeneralQA/hLambdaDCANegToPV"), cand.lambdaDCANegPV()); - histos.fill(HIST("GeneralQA/hLambdaDCAPosToPV"), cand.lambdaDCAPosPV()); - histos.fill(HIST("GeneralQA/hCandidateAnalysisSelection"), 28.); - if ((TMath::Abs(cand.lambdaDCAPosPV()) < LambdaMinDCAPosToPv) || (TMath::Abs(cand.lambdaDCANegPV()) < LambdaMinDCANegToPv)) - return false; - histos.fill(HIST("SigmaSelQA/h2dLambdaDCADauToPV"), cand.sigmapT(), cand.sigmaMass()); - if ((isMCTrueLambda || doPhotonLambdaSelQA) && (TMath::Abs(cand.lambdaMass() - o2::constants::physics::MassLambda0) < LambdaWindow)) - histos.fill(HIST("LambdaSelQA/h2dLambdaDCADauToPV"), cand.lambdaPt(), cand.lambdaMass()); - - // Mass Selection - histos.fill(HIST("GeneralQA/hCandidateAnalysisSelection"), 29.); - histos.fill(HIST("GeneralQA/h3dLambdaMass"), cand.sigmaCentrality(), cand.lambdaPt(), cand.lambdaMass()); - if (TMath::Abs(cand.lambdaMass() - o2::constants::physics::MassLambda0) > LambdaWindow) - return false; - histos.fill(HIST("SigmaSelQA/h2dLambdaMass"), cand.sigmapT(), cand.sigmaMass()); - if (isMCTrueLambda || doPhotonLambdaSelQA) - histos.fill(HIST("LambdaSelQA/h2dLambdaMass"), cand.lambdaPt(), cand.lambdaMass()); - - } else { // AntiLambda selection - histos.fill(HIST("GeneralQA/h2dTPCvsTOFNSigma_ALambdaPr"), cand.lambdaNegPrTPCNSigma(), cand.aLambdaPrTOFNSigma()); - histos.fill(HIST("GeneralQA/h2dTPCvsTOFNSigma_ALambdaPi"), cand.lambdaPosPiTPCNSigma(), cand.aLambdaPiTOFNSigma()); - - // TPC Selection - if (fselLambdaTPCPID && (TMath::Abs(cand.lambdaPosPiTPCNSigma()) > LambdaMaxTPCNSigmas)) - return false; - if (fselLambdaTPCPID && (TMath::Abs(cand.lambdaNegPrTPCNSigma()) > LambdaMaxTPCNSigmas)) - return false; - - // TOF Selection - if (fselLambdaTOFPID && (TMath::Abs(cand.aLambdaPrTOFNSigma()) > LambdaPrMaxTOFNSigmas)) - return false; - if (fselLambdaTOFPID && (TMath::Abs(cand.aLambdaPiTOFNSigma()) > LambdaPiMaxTOFNSigmas)) - return false; - - histos.fill(HIST("SigmaSelQA/h2dTPCvsTOFNSigma_ALambda"), cand.sigmapT(), cand.sigmaMass()); - // DCA Selection - histos.fill(HIST("GeneralQA/hALambdaDCANegToPV"), cand.lambdaDCANegPV()); - histos.fill(HIST("GeneralQA/hALambdaDCAPosToPV"), cand.lambdaDCAPosPV()); - histos.fill(HIST("GeneralQA/hCandidateAnalysisSelection"), 28.); - if ((TMath::Abs(cand.lambdaDCAPosPV()) < ALambdaMinDCAPosToPv) || (TMath::Abs(cand.lambdaDCANegPV()) < ALambdaMinDCANegToPv)) - return false; - - histos.fill(HIST("SigmaSelQA/h2dALambdaDCADauToPV"), cand.sigmapT(), cand.sigmaMass()); - // Mass Selection - histos.fill(HIST("GeneralQA/hCandidateAnalysisSelection"), 29.); - histos.fill(HIST("GeneralQA/h3dAntiLambdaMass"), cand.sigmaCentrality(), cand.lambdaPt(), cand.antilambdaMass()); - if (TMath::Abs(cand.antilambdaMass() - o2::constants::physics::MassLambda0) > LambdaWindow) - return false; - histos.fill(HIST("SigmaSelQA/h2dAntiLambdaMass"), cand.sigmapT(), cand.sigmaMass()); - } - // Sigma0 selection - histos.fill(HIST("GeneralQA/hSigmaY"), cand.sigmaRapidity()); - histos.fill(HIST("GeneralQA/hCandidateAnalysisSelection"), 30.); + // Sigma0 specific selections if (TMath::Abs(cand.sigmaRapidity()) > SigmaMaxRap) return false; - histos.fill(HIST("SigmaSelQA/h2dSigmaY"), cand.sigmapT(), cand.sigmaMass()); - histos.fill(HIST("GeneralQA/hSigmaOPAngle"), cand.sigmaOPAngle()); - histos.fill(HIST("GeneralQA/hCandidateAnalysisSelection"), 31.); } + return true; } @@ -929,218 +913,37 @@ struct sigmaanalysis { if (doMCAssociation && !(sigma.isSigma() || sigma.isAntiSigma())) { continue; } - if (fGetIR) { - double interactionRate = rateFetcher.fetch(ccdb.service, sigma.sigmaTimestamp(), sigma.sigmaRunNumber(), irSource) * 1.e-3; - histos.fill(HIST("GeneralQA/hInteractionRate"), interactionRate); - histos.fill(HIST("GeneralQA/hCentralityVsInteractionRate"), sigma.sigmaCentrality(), interactionRate); - if ((maxIR != -1) && (minIR != -1) && ((interactionRate <= minIR) || (interactionRate >= maxIR))) { - continue; - } - } - - // Filling histos before analysis selection - histos.fill(HIST("MC/h2dSigmaMCPtVsLambdaMCPt"), sigma.sigmaMCPt(), sigma.lambdaMCPt()); - histos.fill(HIST("MC/h2dSigmaMCPtVsGammaMCPt"), sigma.sigmaMCPt(), sigma.photonMCPt()); - histos.fill(HIST("MC/h3dMassAllSigma0sBeforesel"), sigma.sigmaCentrality(), sigma.sigmapT(), sigma.sigmaMass()); - histos.fill(HIST("MC/h2dArmenterosBeforeSel"), sigma.photonAlpha(), sigma.photonQt()); - histos.fill(HIST("MC/h2dArmenterosBeforeSel"), sigma.lambdaAlpha(), sigma.lambdaQt()); - histos.fill(HIST("MC/hMassSigma0BeforeSel"), sigma.sigmaMass()); - histos.fill(HIST("MC/hPtSigma0BeforeSel"), sigma.sigmapT()); - histos.fill(HIST("MC/hPtGammaCand_BeforeSel"), sigma.photonPt()); - histos.fill(HIST("MC/hPtLambdaCand_BeforeSel"), sigma.lambdaPt()); - histos.fill(HIST("MC/hPtSigmaCand_BeforeSel"), sigma.sigmapT()); - - if (sigma.photonCandPDGCode() == 22) { - histos.fill(HIST("MC/hPtTrueGamma_BeforeSel"), sigma.photonPt()); - if (sigma.photonMCPt() > 0) { - histos.fill(HIST("MC/h3dGammaPtResoVsTPCCR"), 1.f / sigma.lambdaMCPt(), 1.f / sigma.lambdaPt() - 1.f / sigma.lambdaMCPt(), -1 * sigma.photonNegTPCCrossedRows()); // 1/pT resolution - histos.fill(HIST("MC/h3dGammaPtResoVsTPCCR"), 1.f / sigma.lambdaMCPt(), 1.f / sigma.lambdaPt() - 1.f / sigma.lambdaMCPt(), sigma.photonPosTPCCrossedRows()); // 1/pT resolution - histos.fill(HIST("MC/h2dGammaPtResolution"), 1.f / sigma.photonMCPt(), 1.f / sigma.photonPt() - 1.f / sigma.photonMCPt()); // pT resolution - } - } - if (sigma.lambdaCandPDGCode() == 3122) { - histos.fill(HIST("MC/hPtTrueLambda_BeforeSel"), sigma.lambdaPt()); - if (sigma.lambdaMCPt() > 0) { - histos.fill(HIST("MC/h2dLambdaPtResolution"), 1.f / sigma.lambdaMCPt(), 1.f / sigma.lambdaPt() - 1.f / sigma.lambdaMCPt()); // 1/pT resolution - histos.fill(HIST("MC/h3dLambdaPtResoVsTPCCR"), 1.f / sigma.lambdaMCPt(), 1.f / sigma.lambdaPt() - 1.f / sigma.lambdaMCPt(), -1 * sigma.lambdaNegTPCCrossedRows()); // 1/pT resolution - histos.fill(HIST("MC/h3dLambdaPtResoVsTPCCR"), 1.f / sigma.lambdaMCPt(), 1.f / sigma.lambdaPt() - 1.f / sigma.lambdaMCPt(), sigma.lambdaPosTPCCrossedRows()); // 1/pT resolution - } - } - if (sigma.lambdaCandPDGCode() == -3122) { - if (sigma.lambdaMCPt() > 0) { - histos.fill(HIST("MC/h2dAntiLambdaPtResolution"), 1.f / sigma.lambdaMCPt(), 1.f / sigma.lambdaPt() - 1.f / sigma.lambdaMCPt()); // pT resolution - histos.fill(HIST("MC/h3dAntiLambdaPtResoVsTPCCR"), 1.f / sigma.lambdaMCPt(), 1.f / sigma.lambdaPt() - 1.f / sigma.lambdaMCPt(), -1 * sigma.lambdaNegTPCCrossedRows()); // 1/pT resolution - histos.fill(HIST("MC/h3dAntiLambdaPtResoVsTPCCR"), 1.f / sigma.lambdaMCPt(), 1.f / sigma.lambdaPt() - 1.f / sigma.lambdaMCPt(), sigma.lambdaPosTPCCrossedRows()); // 1/pT resolution - } - histos.fill(HIST("MC/hPtTrueAntiLambda_BeforeSel"), sigma.lambdaPt()); - } - if (sigma.isSigma()) { - histos.fill(HIST("MC/hPtTrueSigma_BeforeSel"), sigma.sigmapT()); - if (sigma.sigmaMCPt() > 0) - histos.fill(HIST("MC/h2dSigma0PtResolution"), 1.f / sigma.sigmaMCPt(), 1.f / sigma.sigmapT() - 1.f / sigma.sigmaMCPt()); // pT resolution - } - if (sigma.isAntiSigma()) { - histos.fill(HIST("MC/hPtTrueAntiSigma_BeforeSel"), sigma.sigmapT()); - if (sigma.sigmaMCPt() > 0) - histos.fill(HIST("MC/h2dAntiSigma0PtResolution"), 1.f / sigma.sigmaMCPt(), 1.f / sigma.sigmapT() - 1.f / sigma.sigmaMCPt()); // pT resolution - } - - if (sigma.lambdaAlpha() > 0) { // Lambda Analysis - if (!processSigmaCandidate(sigma, true)) - continue; - // For Lambda PID Studies - histos.fill(HIST("MC/hPtLambdaCand_AfterSel"), sigma.lambdaPt()); - histos.fill(HIST("MC/h3dTPCvsTOFNSigma_LambdaPr"), sigma.lambdaPosPrTPCNSigma(), sigma.lambdaPrTOFNSigma(), sigma.lambdaPt()); - histos.fill(HIST("MC/h3dTPCvsTOFNSigma_LambdaPi"), sigma.lambdaNegPiTPCNSigma(), sigma.lambdaPiTOFNSigma(), sigma.lambdaPt()); - - if (sigma.lambdaCandPDGCode() == 3122) { - histos.fill(HIST("MC/hPtTrueLambda_AfterSel"), sigma.lambdaPt()); - histos.fill(HIST("MC/h3dTPCvsTOFNSigma_TrueLambdaPr"), sigma.lambdaPosPrTPCNSigma(), sigma.lambdaPrTOFNSigma(), sigma.lambdaPt()); - histos.fill(HIST("MC/h3dTPCvsTOFNSigma_TrueLambdaPi"), sigma.lambdaNegPiTPCNSigma(), sigma.lambdaPiTOFNSigma(), sigma.lambdaPt()); - } - histos.fill(HIST("GeneralQA/hLambdaMassSelected"), sigma.lambdaMass()); - histos.fill(HIST("Sigma0/hMassSigma0"), sigma.sigmaMass()); - histos.fill(HIST("Sigma0/hPtSigma0"), sigma.sigmapT()); - histos.fill(HIST("Sigma0/hRapiditySigma0"), sigma.sigmaRapidity()); - histos.fill(HIST("Sigma0/h3dMassSigma0"), sigma.sigmaCentrality(), sigma.sigmapT(), sigma.sigmaMass()); - histos.fill(HIST("Sigma0/h3dPhotonRadiusVsMassSigma0"), sigma.sigmaCentrality(), sigma.photonRadius(), sigma.sigmaMass()); - - if (sigma.isSigma()) { // Signal study - histos.fill(HIST("MC/h2dArmenterosAfterSel"), sigma.photonAlpha(), sigma.photonQt()); - histos.fill(HIST("MC/h2dArmenterosAfterSel"), sigma.lambdaAlpha(), sigma.lambdaQt()); - histos.fill(HIST("MC/hMassSigma0"), sigma.sigmaMass()); - histos.fill(HIST("MC/hPtSigma0"), sigma.sigmapT()); - histos.fill(HIST("MC/h3dMassSigma0"), sigma.sigmaCentrality(), sigma.sigmapT(), sigma.sigmaMass()); - histos.fill(HIST("MC/h2dPtVsMassSigma_SignalOnly"), sigma.sigmapT(), sigma.sigmaMass()); - histos.fill(HIST("MC/hPtTrueSigma_AfterSel"), sigma.sigmapT()); - } - } else { // AntiLambda Analysis - if (!processSigmaCandidate(sigma, false)) - continue; + // Fill histos before any selection + fillQAHistos<0>(sigma); - if (sigma.lambdaCandPDGCode() == -3122) { - histos.fill(HIST("MC/hPtTrueAntiLambda_AfterSel"), sigma.lambdaPt()); - histos.fill(HIST("MC/h3dTPCvsTOFNSigma_TrueALambdaPr"), sigma.lambdaNegPrTPCNSigma(), sigma.aLambdaPrTOFNSigma(), sigma.lambdaPt()); - histos.fill(HIST("MC/h3dTPCvsTOFNSigma_TrueALambdaPi"), sigma.lambdaPosPiTPCNSigma(), sigma.aLambdaPiTOFNSigma(), sigma.lambdaPt()); - } - histos.fill(HIST("GeneralQA/hAntiLambdaMassSelected"), sigma.antilambdaMass()); - histos.fill(HIST("AntiSigma0/hMassAntiSigma0"), sigma.sigmaMass()); - histos.fill(HIST("AntiSigma0/hPtAntiSigma0"), sigma.sigmapT()); - histos.fill(HIST("AntiSigma0/hRapidityAntiSigma0"), sigma.sigmaRapidity()); - histos.fill(HIST("AntiSigma0/h3dMassAntiSigma0"), sigma.sigmaCentrality(), sigma.sigmapT(), sigma.sigmaMass()); - histos.fill(HIST("AntiSigma0/h3dPhotonRadiusVsMassAntiSigma0"), sigma.sigmaCentrality(), sigma.photonRadius(), sigma.sigmaMass()); - if (sigma.isAntiSigma()) { // Signal study - histos.fill(HIST("MC/h2dArmenterosAfterSel"), sigma.photonAlpha(), sigma.photonQt()); - histos.fill(HIST("MC/h2dArmenterosAfterSel"), sigma.lambdaAlpha(), sigma.lambdaQt()); - histos.fill(HIST("MC/hMassAntiSigma0"), sigma.sigmaMass()); - histos.fill(HIST("MC/hPtAntiSigma0"), sigma.sigmapT()); - histos.fill(HIST("MC/h3dMassAntiSigma0"), sigma.sigmaCentrality(), sigma.sigmapT(), sigma.sigmaMass()); - histos.fill(HIST("MC/h2dPtVsMassSigma_SignalOnly"), sigma.sigmapT(), sigma.sigmaMass()); - histos.fill(HIST("MC/hPtTrueSigma_AfterSel"), sigma.sigmapT()); - } - } - - // Fill histos after selection, please - histos.fill(HIST("MC/hPtGammaCand_AfterSel"), sigma.photonPt()); - histos.fill(HIST("GeneralQA/hPhotonMassSelected"), sigma.photonMass()); - histos.fill(HIST("MC/hPtSigmaCand_AfterSel"), sigma.sigmapT()); - - if (sigma.photonCandPDGCode() == 22) { - histos.fill(HIST("MC/hPtTrueGamma_AfterSel"), sigma.photonPt()); - } - - // For background studies: - histos.fill(HIST("MC/h2dPtVsMassSigma_SignalBkg"), sigma.sigmapT(), sigma.sigmaMass()); - // Real Gamma x Real Lambda - but not from the same sigma0/antisigma0! - if ((sigma.photonCandPDGCode() == 22) && ((sigma.lambdaCandPDGCode() == 3122) || (sigma.lambdaCandPDGCode() == -3122)) && !(sigma.isSigma()) && !(sigma.isAntiSigma())) { - histos.fill(HIST("MC/h2dPtVsMassSigma_TrueDaughters"), sigma.sigmapT(), sigma.sigmaMass()); - histos.fill(HIST("MC/h2dTrueDaughtersMatrix"), sigma.lambdaCandPDGCodeMother(), sigma.photonCandPDGCodeMother()); - histos.fill(HIST("MC/h2dPtVsOPAngle_TrueDaughters"), sigma.sigmapT(), sigma.sigmaOPAngle()); - } - // Real Gamma x fake Lambda - if ((sigma.photonCandPDGCode() == 22) && (sigma.lambdaCandPDGCode() != 3122) && (sigma.lambdaCandPDGCode() != -3122)) - histos.fill(HIST("MC/h2dPtVsMassSigma_TrueGammaFakeLambda"), sigma.sigmapT(), sigma.sigmaMass()); - - // Fake Gamma x Real Lambda - if ((sigma.photonCandPDGCode() != 22) && ((sigma.lambdaCandPDGCode() == 3122) || (sigma.lambdaCandPDGCode() == -3122))) - histos.fill(HIST("MC/h2dPtVsMassSigma_FakeGammaTrueLambda"), sigma.sigmapT(), sigma.sigmaMass()); + // Select sigma0 candidates + if (!processSigmaCandidate(sigma)) + continue; - // Fake Gamma x Fake Lambda - if ((sigma.photonCandPDGCode() != 22) && (sigma.lambdaCandPDGCode() != 3122) && (sigma.lambdaCandPDGCode() != -3122)) - histos.fill(HIST("MC/h2dPtVsMassSigma_FakeDaughters"), sigma.sigmapT(), sigma.sigmaMass()); + // Fill histos after all selections + fillQAHistos<1>(sigma); } } void processRealData(V0Sigmas const& sigmas) { for (auto& sigma : sigmas) { // selecting Sigma0-like candidates - if (fGetIR) { - double interactionRate = rateFetcher.fetch(ccdb.service, sigma.sigmaTimestamp(), sigma.sigmaRunNumber(), irSource) * 1.e-3; - histos.fill(HIST("GeneralQA/hInteractionRate"), interactionRate); - histos.fill(HIST("GeneralQA/hCentralityVsInteractionRate"), sigma.sigmaCentrality(), interactionRate); - if ((maxIR != -1) && (minIR != -1) && ((interactionRate <= minIR) || (interactionRate >= maxIR))) { - continue; - } - } - histos.fill(HIST("GeneralQA/h2dArmenterosBeforeSel"), sigma.photonAlpha(), sigma.photonQt()); - histos.fill(HIST("GeneralQA/h2dArmenterosBeforeSel"), sigma.lambdaAlpha(), sigma.lambdaQt()); - histos.fill(HIST("GeneralQA/hMassSigma0BeforeSel"), sigma.sigmaMass()); - - nSigmaCandidates++; - if (nSigmaCandidates % 100000 == 0) { - LOG(info) << "Sigma0-like Candidates processed: " << nSigmaCandidates; - } - if (sigma.lambdaAlpha() > 0) { - // Perform analysis selection for sigma0 - if (!processSigmaCandidate(sigma, true)) - continue; - - histos.fill(HIST("GeneralQA/h2dArmenterosAfterSel"), sigma.photonAlpha(), sigma.photonQt()); - histos.fill(HIST("GeneralQA/h2dArmenterosAfterSel"), sigma.lambdaAlpha(), sigma.lambdaQt()); - histos.fill(HIST("GeneralQA/hLambdaMassSelected"), sigma.lambdaMass()); - histos.fill(HIST("Sigma0/hMassSigma0"), sigma.sigmaMass()); - histos.fill(HIST("Sigma0/hPtSigma0"), sigma.sigmapT()); - histos.fill(HIST("Sigma0/hRapiditySigma0"), sigma.sigmaRapidity()); - histos.fill(HIST("Sigma0/h3dMassSigma0"), sigma.sigmaCentrality(), sigma.sigmapT(), sigma.sigmaMass()); - histos.fill(HIST("Sigma0/h3dPhotonRadiusVsMassSigma0"), sigma.sigmaCentrality(), sigma.photonRadius(), sigma.sigmaMass()); - - } else { - - // Perform analysis selection for antisigma0 - if (!processSigmaCandidate(sigma, false)) - continue; - - histos.fill(HIST("GeneralQA/h2dArmenterosAfterSel"), sigma.photonAlpha(), sigma.photonQt()); - histos.fill(HIST("GeneralQA/h2dArmenterosAfterSel"), sigma.lambdaAlpha(), sigma.lambdaQt()); - histos.fill(HIST("GeneralQA/hAntiLambdaMassSelected"), sigma.antilambdaMass()); - histos.fill(HIST("AntiSigma0/hMassAntiSigma0"), sigma.sigmaMass()); - histos.fill(HIST("AntiSigma0/hPtAntiSigma0"), sigma.sigmapT()); - histos.fill(HIST("AntiSigma0/hRapidityAntiSigma0"), sigma.sigmaRapidity()); - histos.fill(HIST("AntiSigma0/h3dMassAntiSigma0"), sigma.sigmaCentrality(), sigma.sigmapT(), sigma.sigmaMass()); - histos.fill(HIST("AntiSigma0/h3dPhotonRadiusVsMassAntiSigma0"), sigma.sigmaCentrality(), sigma.photonRadius(), sigma.sigmaMass()); - } - histos.fill(HIST("GeneralQA/hPhotonMassSelected"), sigma.photonMass()); - } - } + // Fill histos before any selection + fillQAHistos<0>(sigma); - void processCollisions(soa::Join const& collisions) - { - for (const auto& coll : collisions) { - if (!IsEventAccepted(coll)) { + // Select sigma0 candidates + if (!processSigmaCandidate(sigma)) continue; - } - double interactionRate = rateFetcher.fetch(ccdb.service, coll.timestamp(), coll.runNumber(), irSource) * 1.e-3; - histos.fill(HIST("GeneralQA/hInteractionRatePerColl"), interactionRate); - histos.fill(HIST("GeneralQA/hCentralityVsInteractionRatePerColl"), coll.centFT0C(), interactionRate); + + // Fill histos after all selections + fillQAHistos<1>(sigma); } } - // PROCESS_SWITCH(sigmaanalysis, processCounterQA, "Check standard counter correctness", true); PROCESS_SWITCH(sigmaanalysis, processMonteCarlo, "Do Monte-Carlo-based analysis", false); PROCESS_SWITCH(sigmaanalysis, processRealData, "Do real data analysis", true); - PROCESS_SWITCH(sigmaanalysis, processCollisions, "Process collisions to retrieve IR info", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGLF/Tasks/Strangeness/taskLambdaSpinCorr.cxx b/PWGLF/Tasks/Strangeness/taskLambdaSpinCorr.cxx index 666296c1d90..737c3a253e1 100644 --- a/PWGLF/Tasks/Strangeness/taskLambdaSpinCorr.cxx +++ b/PWGLF/Tasks/Strangeness/taskLambdaSpinCorr.cxx @@ -38,6 +38,7 @@ #include "PWGLF/DataModel/LFStrangenessTables.h" #include "PWGLF/DataModel/LFStrangenessPIDTables.h" #include "Common/DataModel/FT0Corrected.h" +#include "PWGMM/Mult/DataModel/Index.h" // for Particles2Tracks table using namespace o2; using namespace o2::framework; @@ -51,12 +52,16 @@ struct LfTaskLambdaSpinCorr { // fill output Configurable additionalEvSel{"additionalEvSel", false, "additionalEvSel"}; Configurable additionalEvSel3{"additionalEvSel3", false, "additionalEvSel3"}; + Configurable fillGEN{"fillGEN", true, "filling generated histograms"}; // events Configurable cfgCutVertex{"cfgCutVertex", 10.0f, "Accepted z-vertex range"}; Configurable cfgCutCentralityMax{"cfgCutCentralityMax", 50.0f, "Accepted maximum Centrality"}; Configurable cfgCutCentralityMin{"cfgCutCentralityMin", 30.0f, "Accepted minimum Centrality"}; + // Configs for track + Configurable cfgCutPt{"cfgCutPt", 0.2, "Pt cut on daughter track"}; + Configurable cfgCutEta{"cfgCutEta", 0.8, "Eta cut on daughter track"}; // Configs for V0 Configurable confV0PtMin{"confV0PtMin", 0.f, "Minimum transverse momentum of V0"}; Configurable confV0Rap{"confV0Rap", 0.8f, "Rapidity range of V0"}; @@ -80,6 +85,9 @@ struct LfTaskLambdaSpinCorr { Configurable iMNbins{"iMNbins", 100, "Number of bins in invariant mass"}; Configurable lbinIM{"lbinIM", 1.0, "lower bin value in IM histograms"}; Configurable hbinIM{"hbinIM", 1.2, "higher bin value in IM histograms"}; + Configurable iMNbinspair{"iMNbinspair", 100, "Number of bins in invariant mass pair"}; + Configurable lbinIMpair{"lbinIMpair", 1.0, "lower bin value in IMpair histograms"}; + Configurable hbinIMpair{"hbinIMpair", 1.2, "higher bin value in IMpair histograms"}; ConfigurableAxis configcentAxis{"configcentAxis", {VARIABLE_WIDTH, 0.0, 10.0, 40.0, 80.0}, "Cent V0M"}; ConfigurableAxis configthnAxisPt{"configthnAxisPt", {VARIABLE_WIDTH, 0.2, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 4.0, 5.0, 6.5, 8.0, 10.0, 100.0}, "#it{p}_{T} (GeV/#it{c})"}; @@ -91,12 +99,27 @@ struct LfTaskLambdaSpinCorr { void init(o2::framework::InitContext&) { AxisSpec thnAxisInvMass{iMNbins, lbinIM, hbinIM, "#it{M} (GeV/#it{c}^{2})"}; + AxisSpec thnAxisInvMasspair{iMNbinspair, lbinIMpair, hbinIMpair, "#it{M} (GeV/#it{c}^{2})"}; histos.add("hCentrality", "Centrality distribution", kTH1F, {{configcentAxis}}); - histos.add("hSparseLambdaLambda", "hSparseLambdaLambda", HistType::kTHnSparseF, {thnAxisInvMass, thnAxisInvMass, configthnAxisPol, configcentAxis, configthnAxisPt, configthnAxisPt}, true); - histos.add("hSparseLambdaAntiLambda", "hSparseLambdaAntiLambda", HistType::kTHnSparseF, {thnAxisInvMass, thnAxisInvMass, configthnAxisPol, configcentAxis, configthnAxisPt, configthnAxisPt}, true); - histos.add("hSparseAntiLambdaAntiLambda", "hSparseAntiLambdaAntiLambda", HistType::kTHnSparseF, {thnAxisInvMass, thnAxisInvMass, configthnAxisPol, configcentAxis, configthnAxisPt, configthnAxisPt}, true); + histos.add("hSparseLambdaLambda", "hSparseLambdaLambda", HistType::kTHnSparseF, {thnAxisInvMass, thnAxisInvMass, configthnAxisPol, configcentAxis, thnAxisInvMasspair}, true); + histos.add("hSparseLambdaAntiLambda", "hSparseLambdaAntiLambda", HistType::kTHnSparseF, {thnAxisInvMass, thnAxisInvMass, configthnAxisPol, configcentAxis, thnAxisInvMasspair}, true); + histos.add("hSparseAntiLambdaAntiLambda", "hSparseAntiLambdaAntiLambda", HistType::kTHnSparseF, {thnAxisInvMass, thnAxisInvMass, configthnAxisPol, configcentAxis, thnAxisInvMasspair}, true); + + ///////// along quantization axes/////////// + histos.add("hSparseLambdaLambdaQA", "hSparseLambdaLambdaQA", HistType::kTHnSparseF, {thnAxisInvMass, thnAxisInvMass, configthnAxisPol, configcentAxis, thnAxisInvMasspair}, true); + histos.add("hSparseLambdaAntiLambdaQA", "hSparseLambdaAntiLambdaQA", HistType::kTHnSparseF, {thnAxisInvMass, thnAxisInvMass, configthnAxisPol, configcentAxis, thnAxisInvMasspair}, true); + histos.add("hSparseAntiLambdaAntiLambdaQA", "hSparseAntiLambdaAntiLambdaQA", HistType::kTHnSparseF, {thnAxisInvMass, thnAxisInvMass, configthnAxisPol, configcentAxis, thnAxisInvMasspair}, true); + if (fillGEN) { + histos.add("hSparseLambdaLambdaMC", "hSparseLambdaLambdaMC", HistType::kTHnSparseF, {thnAxisInvMass, thnAxisInvMass, configthnAxisPol, configcentAxis, thnAxisInvMasspair}, true); + histos.add("hSparseLambdaAntiLambdaMC", "hSparseLambdaAntiLambdaMC", HistType::kTHnSparseF, {thnAxisInvMass, thnAxisInvMass, configthnAxisPol, configcentAxis, thnAxisInvMasspair}, true); + histos.add("hSparseAntiLambdaAntiLambdaMC", "hSparseAntiLambdaAntiLambdaMC", HistType::kTHnSparseF, {thnAxisInvMass, thnAxisInvMass, configthnAxisPol, configcentAxis, thnAxisInvMasspair}, true); + + histos.add("hSparseLambdaLambdaMCQA", "hSparseLambdaLambdaMCQA", HistType::kTHnSparseF, {thnAxisInvMass, thnAxisInvMass, configthnAxisPol, configcentAxis, thnAxisInvMasspair}, true); + histos.add("hSparseLambdaAntiLambdaMCQA", "hSparseLambdaAntiLambdaMCQA", HistType::kTHnSparseF, {thnAxisInvMass, thnAxisInvMass, configthnAxisPol, configcentAxis, thnAxisInvMasspair}, true); + histos.add("hSparseAntiLambdaAntiLambdaMCQA", "hSparseAntiLambdaAntiLambdaMCQA", HistType::kTHnSparseF, {thnAxisInvMass, thnAxisInvMass, configthnAxisPol, configcentAxis, thnAxisInvMasspair}, true); + } } template @@ -135,6 +158,7 @@ struct LfTaskLambdaSpinCorr { } return true; } + template bool isSelectedV0Daughter(V0 const& candidate, T const& track, int pid) { @@ -192,7 +216,7 @@ struct LfTaskLambdaSpinCorr { void fillHistograms(bool tag1, bool tag2, bool tag3, bool tag4, const ROOT::Math::PxPyPzMVector& particlepair, const ROOT::Math::PxPyPzMVector& particle1, const ROOT::Math::PxPyPzMVector& particle2, const ROOT::Math::PxPyPzMVector& daughpart1, const ROOT::Math::PxPyPzMVector& daughpart2, - double centrality) + double centrality, bool datatype) { ROOT::Math::Boost boostPairToCM{particlepair.BoostToCM()}; // boosting vector for pair CM @@ -213,26 +237,90 @@ struct LfTaskLambdaSpinCorr { auto proton2LambdaRF = boostLambda2ToCM(proton2pairCM); // Method2 + /* ROOT::Math::XYZVector quantizationAxis = lambda1CM.Vect().Unit(); // Unit vector along Lambda1's direction in pair rest frame double cosTheta1 = proton1LambdaRF.Vect().Unit().Dot(quantizationAxis); double cosTheta2 = proton2LambdaRF.Vect().Unit().Dot(-quantizationAxis); // Opposite for Lambda2 double theta1 = std::acos(cosTheta1); // angle in radians double theta2 = std::acos(cosTheta2); // angle in radians - // Step 2: Compute sin(theta1) and sin(theta2) - // double sinTheta1 = std::sqrt(1 - cosTheta1 * cosTheta1); - // double sinTheta2 = std::sqrt(1 - cosTheta2 * cosTheta2); - - // Step 3: Calculate cos(theta1 - theta2) using the trigonometric identity - // double cosThetaDiff = cosTheta1 * cosTheta2 + sinTheta1 * sinTheta2; double cosThetaDiff = std::cos(theta1 - theta2); + */ + // STAR method + double cosThetaDiff = proton1LambdaRF.Vect().Unit().Dot(proton2LambdaRF.Vect().Unit()); + + auto lowptcut = 0.5; + auto highptcut = 10.0; + + if (datatype == 1) { + if (tag1 && tag3) + histos.fill(HIST("hSparseLambdaLambdaMC"), particle1.M(), particle2.M(), cosThetaDiff, centrality, particlepair.M()); + if (tag1 && tag4) + histos.fill(HIST("hSparseLambdaAntiLambdaMC"), particle1.M(), particle2.M(), cosThetaDiff, centrality, particlepair.M()); + if (tag2 && tag4) + histos.fill(HIST("hSparseAntiLambdaAntiLambdaMC"), particle1.M(), particle2.M(), cosThetaDiff, centrality, particlepair.M()); + } else { + if (particle1.Pt() > lowptcut && particle1.Pt() < highptcut && particle2.Pt() > lowptcut && particle2.Pt() < highptcut) { + if (tag1 && tag3) + histos.fill(HIST("hSparseLambdaLambda"), particle1.M(), particle2.M(), cosThetaDiff, centrality, particlepair.M()); + if (tag1 && tag4) + histos.fill(HIST("hSparseLambdaAntiLambda"), particle1.M(), particle2.M(), cosThetaDiff, centrality, particlepair.M()); + if (tag2 && tag4) + histos.fill(HIST("hSparseAntiLambdaAntiLambda"), particle1.M(), particle2.M(), cosThetaDiff, centrality, particlepair.M()); + } + } + } + + void fillHistograms2(bool tag1, bool tag2, bool tag3, bool tag4, const ROOT::Math::PxPyPzMVector& particlepair, + const ROOT::Math::PxPyPzMVector& particle1, const ROOT::Math::PxPyPzMVector& particle2, + const ROOT::Math::PxPyPzMVector& daughpart1, const ROOT::Math::PxPyPzMVector& daughpart2, + double centrality, bool datatype) + { + + ROOT::Math::Boost boostPairToCM{particlepair.BoostToCM()}; // boosting vector for pair CM + // Boosting both Lambdas to Lambda-Lambda pair rest frame + auto lambda1CM = boostPairToCM(particle1); + auto lambda2CM = boostPairToCM(particle2); + + // Step 2: Boost Each Lambda to its Own Rest Frame + ROOT::Math::Boost boostLambda1ToCM{lambda1CM.BoostToCM()}; + ROOT::Math::Boost boostLambda2ToCM{lambda2CM.BoostToCM()}; + + ROOT::Math::XYZVector quantizationAxis = lambda1CM.Vect().Unit(); // Unit vector along Lambda1's direction in pair rest frame + + // Also boost the daughter protons to the same frame + auto proton1pairCM = boostPairToCM(daughpart1); // proton1 to pair CM + auto proton2pairCM = boostPairToCM(daughpart2); // proton2 to pair CM - if (tag1 && tag3) - histos.fill(HIST("hSparseLambdaLambda"), particle1.M(), particle2.M(), cosThetaDiff, centrality, particle1.Pt(), particle2.Pt()); - if (tag1 && tag4) - histos.fill(HIST("hSparseLambdaAntiLambda"), particle1.M(), particle2.M(), cosThetaDiff, centrality, particle1.Pt(), particle2.Pt()); - if (tag2 && tag4) - histos.fill(HIST("hSparseAntiLambdaAntiLambda"), particle1.M(), particle2.M(), cosThetaDiff, centrality, particle1.Pt(), particle2.Pt()); + // Boost protons into their respective Lambda rest frames + auto proton1LambdaRF = boostLambda1ToCM(proton1pairCM); + auto proton2LambdaRF = boostLambda2ToCM(proton2pairCM); + + double cosTheta1 = proton1LambdaRF.Vect().Unit().Dot(quantizationAxis); + double cosTheta2 = proton2LambdaRF.Vect().Unit().Dot(quantizationAxis); + + double cosThetaDiff = cosTheta1 * cosTheta2; + + auto lowptcut = 0.5; + auto highptcut = 10.0; + + if (datatype == 1) { + if (tag1 && tag3) + histos.fill(HIST("hSparseLambdaLambdaMCQA"), particle1.M(), particle2.M(), cosThetaDiff, centrality, particlepair.M()); + if (tag1 && tag4) + histos.fill(HIST("hSparseLambdaAntiLambdaMCQA"), particle1.M(), particle2.M(), cosThetaDiff, centrality, particlepair.M()); + if (tag2 && tag4) + histos.fill(HIST("hSparseAntiLambdaAntiLambdaMCQA"), particle1.M(), particle2.M(), cosThetaDiff, centrality, particlepair.M()); + } else { + if (particle1.Pt() > lowptcut && particle1.Pt() < highptcut && particle2.Pt() > lowptcut && particle2.Pt() < highptcut) { + if (tag1 && tag3) + histos.fill(HIST("hSparseLambdaLambdaQA"), particle1.M(), particle2.M(), cosThetaDiff, centrality, particlepair.M()); + if (tag1 && tag4) + histos.fill(HIST("hSparseLambdaAntiLambdaQA"), particle1.M(), particle2.M(), cosThetaDiff, centrality, particlepair.M()); + if (tag2 && tag4) + histos.fill(HIST("hSparseAntiLambdaAntiLambdaQA"), particle1.M(), particle2.M(), cosThetaDiff, centrality, particlepair.M()); + } + } } std::tuple getLambdaTags(const auto& v0, const auto& collision) @@ -273,15 +361,59 @@ struct LfTaskLambdaSpinCorr { return {lambdaTag, aLambdaTag, true}; // Valid candidate } + std::tuple getLambdaTagsMC(const auto& v0, const auto& collision) + { + auto postrack = v0.template posTrack_as(); + auto negtrack = v0.template negTrack_as(); + + int lambdaTag = 0; + int aLambdaTag = 0; + + const auto signpos = postrack.sign(); + const auto signneg = negtrack.sign(); + + if (signpos < 0 || signneg > 0) { + return {0, 0, false}; // Invalid candidate + } + + if (isSelectedV0Daughter(v0, postrack, 0) && isSelectedV0Daughter(v0, negtrack, 1)) { + lambdaTag = 1; + } + if (isSelectedV0Daughter(v0, negtrack, 0) && isSelectedV0Daughter(v0, postrack, 1)) { + aLambdaTag = 1; + } + + if (!lambdaTag && !aLambdaTag) { + return {0, 0, false}; // No valid tags + } + + if (!selectionV0(collision, v0)) { + return {0, 0, false}; // Fails selection + } + + const auto netav = 0.8; + if (std::abs(v0.eta()) > netav) { + return {0, 0, false}; // Fails selection + } + + return {lambdaTag, aLambdaTag, true}; // Valid candidate + } + ROOT::Math::PxPyPzMVector lambda, antiLambda, lambdadummy, antiLambdadummy, proton, pion, antiProton, antiPion, fourVecDauCM; ROOT::Math::PxPyPzMVector lambda2, antiLambda2, lambdadummy2, antiLambdadummy2, proton2, pion2, antiProton2, antiPion2; ROOT::Math::PxPyPzMVector lambdaLambdapair, lambdaAntiLambdapair, antiLambdaAntiLambdapair; + ROOT::Math::PxPyPzMVector lambdamc, antiLambdamc, lambdadummymc, antiLambdadummymc, protonmc, pionmc, antiProtonmc, antiPionmc; + ROOT::Math::PxPyPzMVector lambda2mcmc, antiLambda2mc, lambdadummy2mc, antiLambdadummy2mc, proton2mc, pion2mc, antiProton2mc, antiPion2mc; + ROOT::Math::PxPyPzMVector lambdaLambdapairmc, lambdaAntiLambdapairmc, antiLambdaAntiLambdapairmc; + ROOT::Math::XYZVector threeVecDauCM, threeVecDauCMXY; Filter collisionFilter = nabs(aod::collision::posZ) < cfgCutVertex; Filter centralityFilter = (nabs(aod::cent::centFT0C) < cfgCutCentralityMax && nabs(aod::cent::centFT0C) > cfgCutCentralityMin); + // Filter acceptanceFilter = (nabs(aod::track::eta) < cfgCutEta && nabs(aod::track::pt) > cfgCutPt); - using EventCandidates = soa::Filtered>; + // using EventCandidates = soa::Filtered>; + using EventCandidates = soa::Filtered>; using AllTrackCandidates = soa::Join; using ResoV0s = aod::V0Datas; @@ -292,6 +424,9 @@ struct LfTaskLambdaSpinCorr { return; } auto centrality = collision.centFT0C(); + /*if (!collision.triggereventsp()) { + return; + }*/ if (additionalEvSel && (!collision.selection_bit(aod::evsel::kNoSameBunchPileup) || !collision.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV))) { return; @@ -327,6 +462,9 @@ struct LfTaskLambdaSpinCorr { int taga = lambdaTag; int tagb = aLambdaTag; + auto postrack1 = v0.template posTrack_as(); + auto negtrack1 = v0.template negTrack_as(); + // 2nd loop for combination of lambda lambda for (const auto& v02 : V0s) { @@ -355,12 +493,19 @@ struct LfTaskLambdaSpinCorr { int taga2 = lambdaTag2; int tagb2 = aLambdaTag2; + auto postrack2 = v02.template posTrack_as(); + auto negtrack2 = v02.template negTrack_as(); + + if (postrack1.globalIndex() == postrack2.globalIndex() || negtrack1.globalIndex() == negtrack2.globalIndex()) { + continue; // no shared decay products + } + if (lambdaTag && lambdaTag2) { lambdaLambdapair = lambdadummy + lambdadummy2; tagb = 0; tagb2 = 0; - // fillHistograms(taga, tagb, taga2, tagb2, LambdaLambdapair, Lambdadummy, Lambdadummy2, Proton, Proton2, centrality, LambdaLambdapair.M(), LambdaLambdapair.Pt()); - fillHistograms(taga, tagb, taga2, tagb2, lambdaLambdapair, lambdadummy, lambdadummy2, proton, proton2, centrality); + fillHistograms(taga, tagb, taga2, tagb2, lambdaLambdapair, lambdadummy, lambdadummy2, proton, proton2, centrality, 0); + fillHistograms2(taga, tagb, taga2, tagb2, lambdaLambdapair, lambdadummy, lambdadummy2, proton, proton2, centrality, 0); } tagb2 = aLambdaTag2; @@ -369,8 +514,8 @@ struct LfTaskLambdaSpinCorr { lambdaAntiLambdapair = lambdadummy + antiLambdadummy2; tagb = 0; taga2 = 0; - // fillHistograms(taga, tagb, taga2, tagb2, LambdaAntiLambdapair, Lambdadummy, AntiLambdadummy2, Proton, AntiProton2, centrality, LambdaAntiLambdapair.M(), LambdaAntiLambdapair.Pt()); - fillHistograms(taga, tagb, taga2, tagb2, lambdaAntiLambdapair, lambdadummy, antiLambdadummy2, proton, antiProton2, centrality); + fillHistograms(taga, tagb, taga2, tagb2, lambdaAntiLambdapair, lambdadummy, antiLambdadummy2, proton, antiProton2, centrality, 0); + fillHistograms2(taga, tagb, taga2, tagb2, lambdaAntiLambdapair, lambdadummy, antiLambdadummy2, proton, antiProton2, centrality, 0); } tagb = aLambdaTag; @@ -380,17 +525,260 @@ struct LfTaskLambdaSpinCorr { antiLambdaAntiLambdapair = antiLambdadummy + antiLambdadummy2; taga = 0; taga2 = 0; - // fillHistograms(taga, tagb, taga2, tagb2, AntiLambdaAntiLambdapair, AntiLambdadummy, AntiLambdadummy2, AntiProton, AntiProton2, centrality, AntiLambdaAntiLambdapair.M(), AntiLambdaAntiLambdapair.Pt()); - fillHistograms(taga, tagb, taga2, tagb2, antiLambdaAntiLambdapair, antiLambdadummy, antiLambdadummy2, antiProton, antiProton2, centrality); + fillHistograms(taga, tagb, taga2, tagb2, antiLambdaAntiLambdapair, antiLambdadummy, antiLambdadummy2, antiProton, antiProton2, centrality, 0); + fillHistograms2(taga, tagb, taga2, tagb2, antiLambdaAntiLambdapair, antiLambdadummy, antiLambdadummy2, antiProton, antiProton2, centrality, 0); } } } } PROCESS_SWITCH(LfTaskLambdaSpinCorr, processData, "Process data", true); + + using CollisionMCTrueTable = aod::McCollisions; + using TrackMCTrueTable = aod::McParticles; + + using CollisionMCRecTableCentFT0C = soa::SmallGroups>; + using TrackMCRecTable = soa::Join; + // using FilTrackMCRecTable = soa::Filtered; + using FilTrackMCRecTable = TrackMCRecTable; + Preslice perCollision = aod::track::collisionId; + using V0TrackCandidatesMC = soa::Join; + + void processMC(CollisionMCTrueTable::iterator const& /*TrueCollision*/, CollisionMCRecTableCentFT0C const& RecCollisions, TrackMCTrueTable const& GenParticles, FilTrackMCRecTable const& /*RecTracks*/, V0TrackCandidatesMC const& V0s) + { + + for (const auto& RecCollision : RecCollisions) { + if (!RecCollision.sel8()) { + continue; + } + + if (!RecCollision.selection_bit(aod::evsel::kNoTimeFrameBorder) || !RecCollision.selection_bit(aod::evsel::kNoITSROFrameBorder)) { + continue; + } + + if (std::abs(RecCollision.posZ()) > cfgCutVertex) { + continue; + } + + auto centrality = RecCollision.centFT0C(); + histos.fill(HIST("hCentrality"), centrality); + + for (const auto& v0 : V0s) { + + auto [lambdaTag, aLambdaTag, isValid] = getLambdaTagsMC(v0, RecCollision); + if (!isValid) + continue; + + if (lambdaTag) { + proton = ROOT::Math::PxPyPzMVector(v0.pxpos(), v0.pypos(), v0.pzpos(), o2::constants::physics::MassProton); + antiPion = ROOT::Math::PxPyPzMVector(v0.pxneg(), v0.pyneg(), v0.pzneg(), o2::constants::physics::MassPionCharged); + lambdadummy = proton + antiPion; + } + if (aLambdaTag) { + antiProton = ROOT::Math::PxPyPzMVector(v0.pxneg(), v0.pyneg(), v0.pzneg(), o2::constants::physics::MassProton); + pion = ROOT::Math::PxPyPzMVector(v0.pxpos(), v0.pypos(), v0.pzpos(), o2::constants::physics::MassPionCharged); + antiLambdadummy = antiProton + pion; + } + + if (shouldReject(lambdaTag, aLambdaTag, lambdadummy, antiLambdadummy)) { + continue; + } + + int taga = lambdaTag; + int tagb = aLambdaTag; + + auto postrack1 = v0.template posTrack_as(); + auto negtrack1 = v0.template negTrack_as(); + + // 2nd loop for combination of lambda lambda + for (const auto& v02 : V0s) { + + if (v0.v0Id() >= v02.v0Id()) + continue; + + auto [lambdaTag2, aLambdaTag2, isValid2] = getLambdaTagsMC(v02, RecCollision); + if (!isValid2) + continue; + + if (lambdaTag2) { + proton2 = ROOT::Math::PxPyPzMVector(v02.pxpos(), v02.pypos(), v02.pzpos(), o2::constants::physics::MassProton); + antiPion2 = ROOT::Math::PxPyPzMVector(v02.pxneg(), v02.pyneg(), v02.pzneg(), o2::constants::physics::MassPionCharged); + lambdadummy2 = proton2 + antiPion2; + } + if (aLambdaTag2) { + antiProton2 = ROOT::Math::PxPyPzMVector(v02.pxneg(), v02.pyneg(), v02.pzneg(), o2::constants::physics::MassProton); + pion2 = ROOT::Math::PxPyPzMVector(v02.pxpos(), v02.pypos(), v02.pzpos(), o2::constants::physics::MassPionCharged); + antiLambdadummy2 = antiProton2 + pion2; + } + + if (shouldReject(lambdaTag2, aLambdaTag2, lambdadummy2, antiLambdadummy2)) { + continue; + } + + int taga2 = lambdaTag2; + int tagb2 = aLambdaTag2; + + auto postrack2 = v02.template posTrack_as(); + auto negtrack2 = v02.template negTrack_as(); + + if (postrack1.globalIndex() == postrack2.globalIndex() || negtrack1.globalIndex() == negtrack2.globalIndex()) { + continue; // no shared decay products + } + + if (lambdaTag && lambdaTag2) { + lambdaLambdapair = lambdadummy + lambdadummy2; + tagb = 0; + tagb2 = 0; + fillHistograms(taga, tagb, taga2, tagb2, lambdaLambdapair, lambdadummy, lambdadummy2, proton, proton2, centrality, 0); + fillHistograms2(taga, tagb, taga2, tagb2, lambdaLambdapair, lambdadummy, lambdadummy2, proton, proton2, centrality, 0); + } + + tagb2 = aLambdaTag2; + + if (lambdaTag && aLambdaTag2) { + lambdaAntiLambdapair = lambdadummy + antiLambdadummy2; + tagb = 0; + taga2 = 0; + fillHistograms(taga, tagb, taga2, tagb2, lambdaAntiLambdapair, lambdadummy, antiLambdadummy2, proton, antiProton2, centrality, 0); + fillHistograms2(taga, tagb, taga2, tagb2, lambdaAntiLambdapair, lambdadummy, antiLambdadummy2, proton, antiProton2, centrality, 0); + } + + tagb = aLambdaTag; + taga2 = lambdaTag2; + + if (aLambdaTag && aLambdaTag2) { + antiLambdaAntiLambdapair = antiLambdadummy + antiLambdadummy2; + taga = 0; + taga2 = 0; + fillHistograms(taga, tagb, taga2, tagb2, antiLambdaAntiLambdapair, antiLambdadummy, antiLambdadummy2, antiProton, antiProton2, centrality, 0); + fillHistograms2(taga, tagb, taga2, tagb2, antiLambdaAntiLambdapair, antiLambdadummy, antiLambdadummy2, antiProton, antiProton2, centrality, 0); + } + } + } + + //*******generated**************** + for (const auto& mcParticle : GenParticles) { + if (std::abs(mcParticle.y()) > confV0Rap) { + continue; + } + if (std::abs(mcParticle.pdgCode()) != PDG_t::kLambda0) { + continue; + } + + int tagamc = 0; + int tagbmc = 0; + int taga2mc = 0; + int tagb2mc = 0; + + auto pdg1 = mcParticle.pdgCode(); + auto kDaughters = mcParticle.daughters_as(); + int daughsize = 2; + if (kDaughters.size() != daughsize) { + continue; + } + + for (const auto& kCurrentDaughter : kDaughters) { + + if (std::abs(kCurrentDaughter.pdgCode()) != PDG_t::kProton && std::abs(kCurrentDaughter.pdgCode()) != PDG_t::kPiPlus) { + continue; + } + + if (kCurrentDaughter.pdgCode() == PDG_t::kProton) { + protonmc = ROOT::Math::PxPyPzMVector(kCurrentDaughter.px(), kCurrentDaughter.py(), kCurrentDaughter.pz(), o2::constants::physics::MassProton); + } + if (kCurrentDaughter.pdgCode() == PDG_t::kPiMinus) { + antiPionmc = ROOT::Math::PxPyPzMVector(kCurrentDaughter.px(), kCurrentDaughter.py(), kCurrentDaughter.pz(), o2::constants::physics::MassPionCharged); + } + + if (kCurrentDaughter.pdgCode() == PDG_t::kProtonBar) { + antiProtonmc = ROOT::Math::PxPyPzMVector(kCurrentDaughter.px(), kCurrentDaughter.py(), kCurrentDaughter.pz(), o2::constants::physics::MassProton); + } + if (kCurrentDaughter.pdgCode() == PDG_t::kPiPlus) { + pionmc = ROOT::Math::PxPyPzMVector(kCurrentDaughter.px(), kCurrentDaughter.py(), kCurrentDaughter.pz(), o2::constants::physics::MassPionCharged); + } + } + if (pdg1 == PDG_t::kLambda0) { + tagamc = 1; + lambdadummymc = protonmc + antiPionmc; + } + + if (pdg1 == PDG_t::kLambda0Bar) { + tagbmc = 1; + antiLambdadummymc = antiProtonmc + pionmc; + } + + for (const auto& mcParticle2 : GenParticles) { + if (std::abs(mcParticle2.y()) > confV0Rap) { + continue; + } + if (std::abs(mcParticle2.pdgCode()) != PDG_t::kLambda0) { + continue; + } + if (mcParticle.globalIndex() >= mcParticle2.globalIndex()) { + continue; + } + + auto pdg2 = mcParticle2.pdgCode(); + auto kDaughters2 = mcParticle2.daughters_as(); + + if (kDaughters2.size() != daughsize) { + continue; + } + + for (const auto& kCurrentDaughter2 : kDaughters2) { + if (std::abs(kCurrentDaughter2.pdgCode()) != PDG_t::kProton && std::abs(kCurrentDaughter2.pdgCode()) != PDG_t::kPiPlus) { + continue; + } + + if (kCurrentDaughter2.pdgCode() == PDG_t::kProton) { + proton2mc = ROOT::Math::PxPyPzMVector(kCurrentDaughter2.px(), kCurrentDaughter2.py(), kCurrentDaughter2.pz(), o2::constants::physics::MassProton); + } + if (kCurrentDaughter2.pdgCode() == PDG_t::kPiMinus) { + antiPion2mc = ROOT::Math::PxPyPzMVector(kCurrentDaughter2.px(), kCurrentDaughter2.py(), kCurrentDaughter2.pz(), o2::constants::physics::MassPionCharged); + } + + if (kCurrentDaughter2.pdgCode() == PDG_t::kProtonBar) { + antiProton2mc = ROOT::Math::PxPyPzMVector(kCurrentDaughter2.px(), kCurrentDaughter2.py(), kCurrentDaughter2.pz(), o2::constants::physics::MassProton); + } + if (kCurrentDaughter2.pdgCode() == PDG_t::kPiPlus) { + pion2mc = ROOT::Math::PxPyPzMVector(kCurrentDaughter2.px(), kCurrentDaughter2.py(), kCurrentDaughter2.pz(), o2::constants::physics::MassPionCharged); + } + } + + if (pdg2 == PDG_t::kLambda0) { + taga2mc = 1; + lambdadummy2mc = proton2mc + antiPion2mc; + } + + if (pdg2 == PDG_t::kLambda0Bar) { + tagb2mc = 1; + antiLambdadummy2mc = antiProton2mc + pion2mc; + } + + if (tagamc && taga2mc) { + lambdaLambdapairmc = lambdadummymc + lambdadummy2mc; + fillHistograms(tagamc, tagbmc, taga2mc, tagb2mc, lambdaLambdapairmc, lambdadummymc, lambdadummy2mc, protonmc, proton2mc, centrality, 1); + fillHistograms2(tagamc, tagbmc, taga2mc, tagb2mc, lambdaLambdapairmc, lambdadummymc, lambdadummy2mc, protonmc, proton2mc, centrality, 1); + } + + if (tagamc && tagb2mc) { + lambdaAntiLambdapairmc = lambdadummymc + antiLambdadummy2mc; + fillHistograms(tagamc, tagbmc, taga2mc, tagb2mc, lambdaAntiLambdapairmc, lambdadummymc, antiLambdadummy2mc, protonmc, antiProton2mc, centrality, 1); + fillHistograms2(tagamc, tagbmc, taga2mc, tagb2mc, lambdaAntiLambdapairmc, lambdadummymc, antiLambdadummy2mc, protonmc, antiProton2mc, centrality, 1); + } + + if (tagbmc && tagb2mc) { + antiLambdaAntiLambdapairmc = antiLambdadummymc + antiLambdadummy2mc; + fillHistograms(tagamc, tagbmc, taga2mc, tagb2mc, antiLambdaAntiLambdapairmc, antiLambdadummymc, antiLambdadummy2mc, antiProtonmc, antiProton2mc, centrality, 1); + fillHistograms2(tagamc, tagbmc, taga2mc, tagb2mc, antiLambdaAntiLambdapairmc, antiLambdadummymc, antiLambdadummy2mc, antiProtonmc, antiProton2mc, centrality, 1); + } + } + } + } + } + + PROCESS_SWITCH(LfTaskLambdaSpinCorr, processMC, "Process montecarlo", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { - // return WorkflowSpec{ - // adaptAnalysisTask(cfgc, TaskName{"LambdaSpinCorrelation"})}; return WorkflowSpec{adaptAnalysisTask(cfgc)}; } diff --git a/PWGLF/Utils/strangenessMasks.h b/PWGLF/Utils/strangenessMasks.h index ef224c8e5fa..dbf84deacd6 100644 --- a/PWGLF/Utils/strangenessMasks.h +++ b/PWGLF/Utils/strangenessMasks.h @@ -119,9 +119,12 @@ enum SelectionsCombined : int { selV0CosPA = 0, static constexpr int kSelNum = static_cast(SelectionsCombined::selCount); -// constants -const float ctauxiPDG = 4.91; // from PDG -const float ctauomegaPDG = 2.461; // from PDG +// constants in cm +const float ctauxiPDG = 4.91; +const float ctauomegaPDG = 2.46; + +const float ctauk0shortPDG = 2.68; +const float ctaulambdaPDG = 7.85; // bit masks std::bitset maskTopologicalV0; diff --git a/PWGUD/DataModel/TauEventTables.h b/PWGUD/DataModel/TauEventTables.h new file mode 100644 index 00000000000..f508cbc2c4d --- /dev/null +++ b/PWGUD/DataModel/TauEventTables.h @@ -0,0 +1,224 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// 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. + +/// +/// \file TauEventTables.h +/// \author Roman Lavička +/// \since 2025-04-23 +/// \brief A table to store information about events preselected to be candidates for UPC gammagamma->tautau +/// + +#ifndef ALISW_TAUEVENTTABLES_H +#define ALISW_TAUEVENTTABLES_H + +#include "Framework/AnalysisDataModel.h" + +namespace o2::aod +{ +namespace tau_tree +{ +// event info +DECLARE_SOA_COLUMN(RunNumber, runNumber, int32_t); +DECLARE_SOA_COLUMN(Bc, bc, int); +DECLARE_SOA_COLUMN(TotalTracks, totalTracks, int); +DECLARE_SOA_COLUMN(NumContrib, numContrib, int); +DECLARE_SOA_COLUMN(GlobalNonPVtracks, globalNonPVtracks, int); +DECLARE_SOA_COLUMN(PosX, posX, float); +DECLARE_SOA_COLUMN(PosY, posY, float); +DECLARE_SOA_COLUMN(PosZ, posZ, float); +DECLARE_SOA_COLUMN(RecoMode, recoMode, int); +DECLARE_SOA_COLUMN(OccupancyInTime, occupancyInTime, int); +DECLARE_SOA_COLUMN(HadronicRate, hadronicRate, double); +DECLARE_SOA_COLUMN(Trs, trs, int); +DECLARE_SOA_COLUMN(Trofs, trofs, int); +DECLARE_SOA_COLUMN(Hmpr, hmpr, int); +DECLARE_SOA_COLUMN(Tfb, tfb, int); +DECLARE_SOA_COLUMN(ItsRofb, itsRofb, int); +DECLARE_SOA_COLUMN(Sbp, sbp, int); +DECLARE_SOA_COLUMN(ZvtxFT0vsPv, zvtxFT0vsPv, int); +DECLARE_SOA_COLUMN(VtxITSTPC, vtxITSTPC, int); +// FIT info +DECLARE_SOA_COLUMN(TotalFT0AmplitudeA, totalFT0AmplitudeA, float); +DECLARE_SOA_COLUMN(TotalFT0AmplitudeC, totalFT0AmplitudeC, float); +DECLARE_SOA_COLUMN(TotalFV0AmplitudeA, totalFV0AmplitudeA, float); +DECLARE_SOA_COLUMN(EnergyCommonZNA, energyCommonZNA, float); +DECLARE_SOA_COLUMN(EnergyCommonZNC, energyCommonZNC, float); +DECLARE_SOA_COLUMN(TimeFT0A, timeFT0A, float); +DECLARE_SOA_COLUMN(TimeFT0C, timeFT0C, float); +DECLARE_SOA_COLUMN(TimeFV0A, timeFV0A, float); +DECLARE_SOA_COLUMN(TimeZNA, timeZNA, float); +DECLARE_SOA_COLUMN(TimeZNC, timeZNC, float); +// tracks +DECLARE_SOA_COLUMN(TrkPx, trkPx, float[2]); +DECLARE_SOA_COLUMN(TrkPy, trkPy, float[2]); +DECLARE_SOA_COLUMN(TrkPz, trkPz, float[2]); +DECLARE_SOA_COLUMN(TrkSign, trkSign, int[2]); +DECLARE_SOA_COLUMN(TrkDCAxy, trkDCAxy, float[2]); +DECLARE_SOA_COLUMN(TrkDCAz, trkDCAz, float[2]); +DECLARE_SOA_COLUMN(TrkTimeRes, trkTimeRes, float[2]); +DECLARE_SOA_COLUMN(Trk1ITSclusterSizes, trk1ITSclusterSizes, uint32_t); +DECLARE_SOA_COLUMN(Trk2ITSclusterSizes, trk2ITSclusterSizes, uint32_t); +DECLARE_SOA_COLUMN(TrkTPCsignal, trkTPCsignal, float[2]); +DECLARE_SOA_COLUMN(TrkTPCnSigmaEl, trkTPCnSigmaEl, float[2]); +DECLARE_SOA_COLUMN(TrkTPCnSigmaMu, trkTPCnSigmaMu, float[2]); +DECLARE_SOA_COLUMN(TrkTPCnSigmaPi, trkTPCnSigmaPi, float[2]); +DECLARE_SOA_COLUMN(TrkTPCnSigmaKa, trkTPCnSigmaKa, float[2]); +DECLARE_SOA_COLUMN(TrkTPCnSigmaPr, trkTPCnSigmaPr, float[2]); +DECLARE_SOA_COLUMN(TrkTPCinnerParam, trkTPCinnerParam, float[2]); +DECLARE_SOA_COLUMN(TrkTOFsignal, trkTOFsignal, float[2]); +DECLARE_SOA_COLUMN(TrkTOFnSigmaEl, trkTOFnSigmaEl, float[2]); +DECLARE_SOA_COLUMN(TrkTOFnSigmaMu, trkTOFnSigmaMu, float[2]); +DECLARE_SOA_COLUMN(TrkTOFnSigmaPi, trkTOFnSigmaPi, float[2]); +DECLARE_SOA_COLUMN(TrkTOFnSigmaKa, trkTOFnSigmaKa, float[2]); +DECLARE_SOA_COLUMN(TrkTOFnSigmaPr, trkTOFnSigmaPr, float[2]); +DECLARE_SOA_COLUMN(TrkTOFexpMom, trkTOFexpMom, float[2]); +// truth event +DECLARE_SOA_COLUMN(TrueChannel, trueChannel, int); +DECLARE_SOA_COLUMN(TrueHasRecoColl, trueHasRecoColl, bool); +DECLARE_SOA_COLUMN(TruePosX, truePosX, float); +DECLARE_SOA_COLUMN(TruePosY, truePosY, float); +DECLARE_SOA_COLUMN(TruePosZ, truePosZ, float); +// truth particles +DECLARE_SOA_COLUMN(TrueTauPx, trueTauPx, float[2]); +DECLARE_SOA_COLUMN(TrueTauPy, trueTauPy, float[2]); +DECLARE_SOA_COLUMN(TrueTauPz, trueTauPz, float[2]); +DECLARE_SOA_COLUMN(TrueDaugPx, trueDaugPx, float[2]); +DECLARE_SOA_COLUMN(TrueDaugPy, trueDaugPy, float[2]); +DECLARE_SOA_COLUMN(TrueDaugPz, trueDaugPz, float[2]); +DECLARE_SOA_COLUMN(TrueDaugPdgCode, trueDaugPdgCode, int[2]); +// additional info +DECLARE_SOA_COLUMN(ProblematicEvent, problematicEvent, bool); + +} // namespace tau_tree +DECLARE_SOA_TABLE(TauTwoTracks, "AOD", "TAUTWOTRACK", + tau_tree::RunNumber, + tau_tree::Bc, + tau_tree::TotalTracks, + tau_tree::NumContrib, + tau_tree::GlobalNonPVtracks, + tau_tree::PosX, + tau_tree::PosY, + tau_tree::PosZ, + tau_tree::RecoMode, + tau_tree::OccupancyInTime, + tau_tree::HadronicRate, + tau_tree::Trs, + tau_tree::Trofs, + tau_tree::Hmpr, + tau_tree::Tfb, + tau_tree::ItsRofb, + tau_tree::Sbp, + tau_tree::ZvtxFT0vsPv, + tau_tree::VtxITSTPC, + tau_tree::TotalFT0AmplitudeA, + tau_tree::TotalFT0AmplitudeC, + tau_tree::TotalFV0AmplitudeA, + tau_tree::EnergyCommonZNA, + tau_tree::EnergyCommonZNC, + tau_tree::TimeFT0A, + tau_tree::TimeFT0C, + tau_tree::TimeFV0A, + tau_tree::TimeZNA, + tau_tree::TimeZNC, + tau_tree::TrkPx, + tau_tree::TrkPy, + tau_tree::TrkPz, + tau_tree::TrkSign, + tau_tree::TrkDCAxy, + tau_tree::TrkDCAz, + tau_tree::TrkTimeRes, + tau_tree::Trk1ITSclusterSizes, + tau_tree::Trk2ITSclusterSizes, + tau_tree::TrkTPCsignal, + tau_tree::TrkTPCnSigmaEl, + tau_tree::TrkTPCnSigmaMu, + tau_tree::TrkTPCnSigmaPi, + tau_tree::TrkTPCnSigmaKa, + tau_tree::TrkTPCnSigmaPr, + tau_tree::TrkTPCinnerParam, + tau_tree::TrkTOFsignal, + tau_tree::TrkTOFnSigmaEl, + tau_tree::TrkTOFnSigmaMu, + tau_tree::TrkTOFnSigmaPi, + tau_tree::TrkTOFnSigmaKa, + tau_tree::TrkTOFnSigmaPr, + tau_tree::TrkTOFexpMom); + +DECLARE_SOA_TABLE(TrueTauTwoTracks, "AOD", "TRUETAUTWOTRACK", + tau_tree::RunNumber, + tau_tree::Bc, + tau_tree::TotalTracks, + tau_tree::NumContrib, + tau_tree::GlobalNonPVtracks, + tau_tree::PosX, + tau_tree::PosY, + tau_tree::PosZ, + tau_tree::RecoMode, + tau_tree::OccupancyInTime, + tau_tree::HadronicRate, + tau_tree::Trs, + tau_tree::Trofs, + tau_tree::Hmpr, + tau_tree::Tfb, + tau_tree::ItsRofb, + tau_tree::Sbp, + tau_tree::ZvtxFT0vsPv, + tau_tree::VtxITSTPC, + tau_tree::TotalFT0AmplitudeA, + tau_tree::TotalFT0AmplitudeC, + tau_tree::TotalFV0AmplitudeA, + tau_tree::EnergyCommonZNA, + tau_tree::EnergyCommonZNC, + tau_tree::TimeFT0A, + tau_tree::TimeFT0C, + tau_tree::TimeFV0A, + tau_tree::TimeZNA, + tau_tree::TimeZNC, + tau_tree::TrkPx, + tau_tree::TrkPy, + tau_tree::TrkPz, + tau_tree::TrkSign, + tau_tree::TrkDCAxy, + tau_tree::TrkDCAz, + tau_tree::TrkTimeRes, + tau_tree::Trk1ITSclusterSizes, + tau_tree::Trk2ITSclusterSizes, + tau_tree::TrkTPCsignal, + tau_tree::TrkTPCnSigmaEl, + tau_tree::TrkTPCnSigmaMu, + tau_tree::TrkTPCnSigmaPi, + tau_tree::TrkTPCnSigmaKa, + tau_tree::TrkTPCnSigmaPr, + tau_tree::TrkTPCinnerParam, + tau_tree::TrkTOFsignal, + tau_tree::TrkTOFnSigmaEl, + tau_tree::TrkTOFnSigmaMu, + tau_tree::TrkTOFnSigmaPi, + tau_tree::TrkTOFnSigmaKa, + tau_tree::TrkTOFnSigmaPr, + tau_tree::TrkTOFexpMom, + tau_tree::TrueChannel, + tau_tree::TrueHasRecoColl, + tau_tree::TruePosX, + tau_tree::TruePosY, + tau_tree::TruePosZ, + tau_tree::TrueTauPx, + tau_tree::TrueTauPy, + tau_tree::TrueTauPz, + tau_tree::TrueDaugPx, + tau_tree::TrueDaugPy, + tau_tree::TrueDaugPz, + tau_tree::TrueDaugPdgCode, + tau_tree::ProblematicEvent); + +} // namespace o2::aod + +#endif // ALISW_TAUEVENTTABLES_H diff --git a/PWGUD/TableProducer/tauEventTableProducer.cxx b/PWGUD/TableProducer/tauEventTableProducer.cxx index 035cd4de860..8293a76fd4a 100644 --- a/PWGUD/TableProducer/tauEventTableProducer.cxx +++ b/PWGUD/TableProducer/tauEventTableProducer.cxx @@ -40,7 +40,7 @@ #include "Common/DataModel/TrackSelectionTables.h" #include "PWGUD/Core/UPCTauCentralBarrelHelperRL.h" #include "PWGUD/DataModel/UDTables.h" -#include "PWGUD/DataModel/UDIndex.h" // for UDMcParticles2UDTracks table +#include "PWGUD/DataModel/TauEventTables.h" #include "PWGUD/Core/SGSelector.h" // ROOT headers @@ -52,82 +52,9 @@ using namespace o2::framework; using namespace o2::framework::expressions; using namespace o2::constants::physics; -namespace o2::aod -{ -namespace tau_tree -{ -// event info -DECLARE_SOA_COLUMN(RunNumber, runNumber, int32_t); -DECLARE_SOA_COLUMN(Bc, bc, int); -DECLARE_SOA_COLUMN(TotalTracks, totalTracks, int); -DECLARE_SOA_COLUMN(NumContrib, numContrib, int); -DECLARE_SOA_COLUMN(GlobalNonPVtracks, globalNonPVtracks, int); -DECLARE_SOA_COLUMN(PosX, posX, float); -DECLARE_SOA_COLUMN(PosY, posY, float); -DECLARE_SOA_COLUMN(PosZ, posZ, float); -DECLARE_SOA_COLUMN(RecoMode, recoMode, int); -DECLARE_SOA_COLUMN(OccupancyInTime, occupancyInTime, int); -DECLARE_SOA_COLUMN(HadronicRate, hadronicRate, double); -DECLARE_SOA_COLUMN(Trs, trs, int); -DECLARE_SOA_COLUMN(Trofs, trofs, int); -DECLARE_SOA_COLUMN(Hmpr, hmpr, int); -DECLARE_SOA_COLUMN(Tfb, tfb, int); -DECLARE_SOA_COLUMN(ItsRofb, itsRofb, int); -DECLARE_SOA_COLUMN(Sbp, sbp, int); -DECLARE_SOA_COLUMN(ZvtxFT0vsPv, zvtxFT0vsPv, int); -DECLARE_SOA_COLUMN(VtxITSTPC, vtxITSTPC, int); -// FIT info -DECLARE_SOA_COLUMN(TotalFT0AmplitudeA, totalFT0AmplitudeA, float); -DECLARE_SOA_COLUMN(TotalFT0AmplitudeC, totalFT0AmplitudeC, float); -DECLARE_SOA_COLUMN(TotalFV0AmplitudeA, totalFV0AmplitudeA, float); -DECLARE_SOA_COLUMN(EnergyCommonZNA, energyCommonZNA, float); -DECLARE_SOA_COLUMN(EnergyCommonZNC, energyCommonZNC, float); -DECLARE_SOA_COLUMN(TimeFT0A, timeFT0A, float); -DECLARE_SOA_COLUMN(TimeFT0C, timeFT0C, float); -DECLARE_SOA_COLUMN(TimeFV0A, timeFV0A, float); -DECLARE_SOA_COLUMN(TimeZNA, timeZNA, float); -DECLARE_SOA_COLUMN(TimeZNC, timeZNC, float); -// tracks -DECLARE_SOA_COLUMN(TrkPx, trkPx, float[2]); -DECLARE_SOA_COLUMN(TrkPy, trkPy, float[2]); -DECLARE_SOA_COLUMN(TrkPz, trkPz, float[2]); -DECLARE_SOA_COLUMN(TrkSign, trkSign, int[2]); -DECLARE_SOA_COLUMN(TrkDCAxy, trkDCAxy, float[2]); -DECLARE_SOA_COLUMN(TrkDCAz, trkDCAz, float[2]); -DECLARE_SOA_COLUMN(TrkTimeRes, trkTimeRes, float[2]); -DECLARE_SOA_COLUMN(Trk1ITSclusterSizes, trk1ITSclusterSizes, uint32_t); -DECLARE_SOA_COLUMN(Trk2ITSclusterSizes, trk2ITSclusterSizes, uint32_t); -DECLARE_SOA_COLUMN(TrkTPCsignal, trkTPCsignal, float[2]); -DECLARE_SOA_COLUMN(TrkTPCnSigmaEl, trkTPCnSigmaEl, float[2]); -DECLARE_SOA_COLUMN(TrkTPCnSigmaMu, trkTPCnSigmaMu, float[2]); -DECLARE_SOA_COLUMN(TrkTPCnSigmaPi, trkTPCnSigmaPi, float[2]); -DECLARE_SOA_COLUMN(TrkTPCnSigmaKa, trkTPCnSigmaKa, float[2]); -DECLARE_SOA_COLUMN(TrkTPCnSigmaPr, trkTPCnSigmaPr, float[2]); -DECLARE_SOA_COLUMN(TrkTPCinnerParam, trkTPCinnerParam, float[2]); -DECLARE_SOA_COLUMN(TrkTOFsignal, trkTOFsignal, float[2]); -DECLARE_SOA_COLUMN(TrkTOFnSigmaEl, trkTOFnSigmaEl, float[2]); -DECLARE_SOA_COLUMN(TrkTOFnSigmaMu, trkTOFnSigmaMu, float[2]); -DECLARE_SOA_COLUMN(TrkTOFnSigmaPi, trkTOFnSigmaPi, float[2]); -DECLARE_SOA_COLUMN(TrkTOFnSigmaKa, trkTOFnSigmaKa, float[2]); -DECLARE_SOA_COLUMN(TrkTOFnSigmaPr, trkTOFnSigmaPr, float[2]); -DECLARE_SOA_COLUMN(TrkTOFexpMom, trkTOFexpMom, float[2]); - -} // namespace tau_tree -DECLARE_SOA_TABLE(TauTwoTracks, "AOD", "TAUTWOTRACK", - tau_tree::RunNumber, tau_tree::Bc, tau_tree::TotalTracks, tau_tree::NumContrib, tau_tree::GlobalNonPVtracks, tau_tree::PosX, tau_tree::PosY, tau_tree::PosZ, - tau_tree::RecoMode, tau_tree::OccupancyInTime, tau_tree::HadronicRate, - tau_tree::Trs, tau_tree::Trofs, tau_tree::Hmpr, tau_tree::Tfb, tau_tree::ItsRofb, tau_tree::Sbp, tau_tree::ZvtxFT0vsPv, tau_tree::VtxITSTPC, - tau_tree::TotalFT0AmplitudeA, tau_tree::TotalFT0AmplitudeC, tau_tree::TotalFV0AmplitudeA, tau_tree::EnergyCommonZNA, tau_tree::EnergyCommonZNC, - tau_tree::TimeFT0A, tau_tree::TimeFT0C, tau_tree::TimeFV0A, tau_tree::TimeZNA, tau_tree::TimeZNC, - tau_tree::TrkPx, tau_tree::TrkPy, tau_tree::TrkPz, tau_tree::TrkSign, tau_tree::TrkDCAxy, tau_tree::TrkDCAz, tau_tree::TrkTimeRes, - tau_tree::Trk1ITSclusterSizes, tau_tree::Trk2ITSclusterSizes, - tau_tree::TrkTPCsignal, tau_tree::TrkTPCnSigmaEl, tau_tree::TrkTPCnSigmaMu, tau_tree::TrkTPCnSigmaPi, tau_tree::TrkTPCnSigmaKa, tau_tree::TrkTPCnSigmaPr, tau_tree::TrkTPCinnerParam, - tau_tree::TrkTOFsignal, tau_tree::TrkTOFnSigmaEl, tau_tree::TrkTOFnSigmaMu, tau_tree::TrkTOFnSigmaPi, tau_tree::TrkTOFnSigmaKa, tau_tree::TrkTOFnSigmaPr, tau_tree::TrkTOFexpMom); - -} // namespace o2::aod - struct TauEventTableProducer { Produces tauTwoTracks; + Produces trueTauTwoTracks; // Global varialbes Service pdg; @@ -197,9 +124,6 @@ struct TauEventTableProducer { using FullMCUDTracks = soa::Join; using FullMCSGUDCollisions = soa::Join; using FullMCSGUDCollision = FullMCSGUDCollisions::iterator; - using UDMcParticlesWithUDTracks = soa::Join; - using UDMcCollisionsWithUDCollisions = soa::Join; - using UDMcCollisionsWithUDCollision = UDMcCollisionsWithUDCollisions::iterator; // init void init(InitContext&) @@ -209,6 +133,8 @@ struct TauEventTableProducer { mySetITShitsRule(cutGlobalTrack.cutITShitsRule); + histos.add("Truth/hTroubles", "Counter of unwanted issues;;Number of troubles (-)", HistType::kTH1D, {{15, 0.5, 15.5}}); + } // end init template @@ -480,16 +406,270 @@ struct TauEventTableProducer { } PROCESS_SWITCH(TauEventTableProducer, processDataSG, "Iterate UD tables with measured data created by SG-Candidate-Producer.", false); - void processMonteCarlo(UDMcCollisionsWithUDCollision const& mccollision, - FullMCSGUDCollisions const&, - FullUDTracks const&, - UDMcParticlesWithUDTracks const&) + PresliceUnsorted partPerMcCollision = aod::udmcparticle::udMcCollisionId; + PresliceUnsorted colPerMcCollision = aod::udcollision::udMcCollisionId; + PresliceUnsorted trackPerMcParticle = aod::udmctracklabel::udMcParticleId; + Preslice trackPerCollision = aod::udtrack::udCollisionId; // sorted preslice used because the pair track-collision is already sorted in processDataSG function + + void processMonteCarlo(aod::UDMcCollisions const& mccollisions, + aod::UDMcParticles const& parts, + FullMCSGUDCollisions const& recolls, + FullMCUDTracks const& trks) { - LOGF(info, "mccollision idx %i", mccollision.globalIndex()); - if (mccollision.has_udcollisions()) { - auto const& collFromMcColl = mccollision.udcollisions_as(); - LOGF(info, "collision size %i ", collFromMcColl.size()); - } + // start loop over generated collisions + for (const auto& mccoll : mccollisions) { + + // prepare local variables for output table + int32_t runNumber = -999; + int bc = -999; + int nTrks[3] = {-999, -999, -999}; // totalTracks, numContrib, globalNonPVtracks + float vtxPos[3] = {-999., -999., -999.}; + int recoMode = -999; + int occupancy = -999.; + double hadronicRate = -999.; + int bcSels[8] = {-999, -999, -999, -999, -999, -999, -999, -999}; + float amplitudesFIT[3] = {-999., -999., -999.}; // FT0A, FT0C, FV0 + float timesFIT[3] = {-999., -999., -999.}; // FT0A, FT0C, FV0 + + float px[2] = {-999., -999.}; + float py[2] = {-999., -999.}; + float pz[2] = {-999., -999.}; + int sign[2] = {-999, -999}; + float dcaxy[2] = {-999., -999.}; + float dcaz[2] = {-999., -999.}; + float trkTimeRes[2] = {-999., -999.}; + uint32_t itsClusterSizesTrk1 = 4294967295; + uint32_t itsClusterSizesTrk2 = 4294967295; + float tpcSignal[2] = {-999, -999}; + float tpcEl[2] = {-999, -999}; + float tpcMu[2] = {-999, -999}; + float tpcPi[2] = {-999, -999}; + float tpcKa[2] = {-999, -999}; + float tpcPr[2] = {-999, -999}; + float tpcIP[2] = {-999, -999}; + float tofSignal[2] = {-999, -999}; + float tofEl[2] = {-999, -999}; + float tofMu[2] = {-999, -999}; + float tofPi[2] = {-999, -999}; + float tofKa[2] = {-999, -999}; + float tofPr[2] = {-999, -999}; + float tofEP[2] = {-999, -999}; + + int trueChannel = -1; + bool trueHasRecoColl = false; + float trueTauX[2] = {-999., -999.}; + float trueTauY[2] = {-999., -999.}; + float trueTauZ[2] = {-999., -999.}; + float trueDaugX[2] = {-999., -999.}; + float trueDaugY[2] = {-999., -999.}; + float trueDaugZ[2] = {-999., -999.}; + int trueDaugPdgCode[2] = {-999, -999}; + bool problem = false; + + // find reconstructed collisions associated to the generated collision + auto const& collFromMcColls = recolls.sliceBy(colPerMcCollision, mccoll.globalIndex()); + // check the generated collision was reconstructed + if (collFromMcColls.size() > 0) { // get the truth and reco-level info + trueHasRecoColl = true; + // check there is exactly one reco-level collision associated to generated collision + if (collFromMcColls.size() > 1) { + if (verboseInfo) + printLargeMessage("Truth collision has more than 1 reco collision. Skipping this event."); + histos.get(HIST("Truth/hTroubles"))->Fill(1); + problem = true; + continue; + } + // grap reco-level collision + auto const& collFromMcColl = collFromMcColls.iteratorAt(0); + // grab tracks from the reco-level collision to get info to match measured data tables (processDataSG function) + auto const& trksFromColl = trks.sliceBy(trackPerCollision, collFromMcColl.globalIndex()); + int countTracksPerCollision = 0; + int countGoodNonPVtracks = 0; + for (auto const& trkFromColl : trksFromColl) { + countTracksPerCollision++; + if (!trkFromColl.isPVContributor()) { + countGoodNonPVtracks++; + continue; + } + } + + // fill info for reconstructed collision + runNumber = collFromMcColl.runNumber(); + bc = collFromMcColl.globalBC(); + nTrks[0] = countTracksPerCollision; + nTrks[1] = collFromMcColl.numContrib(); + nTrks[2] = countGoodNonPVtracks; + vtxPos[0] = collFromMcColl.posX(); + vtxPos[1] = collFromMcColl.posY(); + vtxPos[2] = collFromMcColl.posZ(); + recoMode = collFromMcColl.flags(); + occupancy = collFromMcColl.occupancyInTime(); + hadronicRate = collFromMcColl.hadronicRate(); + bcSels[0] = collFromMcColl.trs(); + bcSels[1] = collFromMcColl.trofs(); + bcSels[2] = collFromMcColl.hmpr(); + bcSels[3] = collFromMcColl.tfb(); + bcSels[4] = collFromMcColl.itsROFb(); + bcSels[5] = collFromMcColl.sbp(); + bcSels[6] = collFromMcColl.zVtxFT0vPV(); + bcSels[7] = collFromMcColl.vtxITSTPC(); + amplitudesFIT[0] = collFromMcColl.totalFT0AmplitudeA(); + amplitudesFIT[1] = collFromMcColl.totalFT0AmplitudeC(); + amplitudesFIT[2] = collFromMcColl.totalFV0AmplitudeA(); + timesFIT[0] = collFromMcColl.timeFT0A(); + timesFIT[1] = collFromMcColl.timeFT0C(); + timesFIT[2] = collFromMcColl.timeFV0A(); + + // get particles associated to generated collision + auto const& partsFromMcColl = parts.sliceBy(partPerMcCollision, mccoll.globalIndex()); + int countMothers = 0; + for (const auto& particle : partsFromMcColl) { + // select only tauons with checking if particle has no mother + if (particle.has_mothers()) + continue; + countMothers++; + // check the generated collision does not have more than 2 tauons + if (countMothers > 2) { + if (verboseInfo) + printLargeMessage("Truth collision has more than 2 no mother particles. Breaking the particle loop."); + histos.get(HIST("Truth/hTroubles"))->Fill(2); + problem = true; + break; + } + // fill info for each tau + trueTauX[countMothers - 1] = particle.px(); + trueTauY[countMothers - 1] = particle.py(); + trueTauZ[countMothers - 1] = particle.pz(); + + // get daughters of the tau + const auto& daughters = particle.daughters_as(); + int countDaughters = 0; + for (const auto& daughter : daughters) { + // check if it is the charged particle (= no pi0 or neutrino) + if (enumMyParticle(daughter.pdgCode()) == -1) + continue; + countDaughters++; + // check there is only 1 charged daughter related to 1 tau + if (countDaughters > 1) { + if (verboseInfo) + printLargeMessage("Truth collision has more than 1 charged daughters of no mother particles. Breaking the daughter loop."); + histos.get(HIST("Truth/hTroubles"))->Fill(3); + problem = true; + break; + } + // fill info for each daughter + trueDaugX[countMothers - 1] = daughter.px(); + trueDaugY[countMothers - 1] = daughter.py(); + trueDaugZ[countMothers - 1] = daughter.pz(); + trueDaugPdgCode[countMothers - 1] = daughter.pdgCode(); + + // get tracks associated to MC daughter (how well the daughter was reconstructed) + auto const& tracksFromDaughter = trks.sliceBy(trackPerMcParticle, daughter.globalIndex()); + // check there is exactly 1 track per 1 particle + if (tracksFromDaughter.size() > 1) { + if (verboseInfo) + printLargeMessage("Daughter has more than 1 associated track. Skipping this daughter."); + histos.get(HIST("Truth/hTroubles"))->Fill(4); + problem = true; + continue; + } + // grab the track and fill info for reconstructed track (should be done twice) + const auto& trk = tracksFromDaughter.iteratorAt(0); + px[countMothers - 1] = trk.px(); + py[countMothers - 1] = trk.py(); + pz[countMothers - 1] = trk.pz(); + sign[countMothers - 1] = trk.sign(); + dcaxy[countMothers - 1] = trk.dcaXY(); + dcaz[countMothers - 1] = trk.dcaZ(); + trkTimeRes[countMothers - 1] = trk.trackTimeRes(); + if (countMothers == 1) { + itsClusterSizesTrk1 = trk.itsClusterSizes(); + } else { + itsClusterSizesTrk2 = trk.itsClusterSizes(); + } + tpcSignal[countMothers - 1] = trk.tpcSignal(); + tpcEl[countMothers - 1] = trk.tpcNSigmaEl(); + tpcMu[countMothers - 1] = trk.tpcNSigmaMu(); + tpcPi[countMothers - 1] = trk.tpcNSigmaPi(); + tpcKa[countMothers - 1] = trk.tpcNSigmaKa(); + tpcPr[countMothers - 1] = trk.tpcNSigmaPr(); + tpcIP[countMothers - 1] = trk.tpcInnerParam(); + tofSignal[countMothers - 1] = trk.tofSignal(); + tofEl[countMothers - 1] = trk.tofNSigmaEl(); + tofMu[countMothers - 1] = trk.tofNSigmaMu(); + tofPi[countMothers - 1] = trk.tofNSigmaPi(); + tofKa[countMothers - 1] = trk.tofNSigmaKa(); + tofPr[countMothers - 1] = trk.tofNSigmaPr(); + tofEP[countMothers - 1] = trk.tofExpMom(); + } // daughters + } // particles + } else { // get only the truth information. The reco-level info is left on default + // get particles associated to generated collision + auto const& partsFromMcColl = parts.sliceBy(partPerMcCollision, mccoll.globalIndex()); + int countMothers = 0; + for (const auto& particle : partsFromMcColl) { + // select only tauons with checking if particle has no mother + if (particle.has_mothers()) + continue; + countMothers++; + // check the generated collision does not have more than 2 tauons + if (countMothers > 2) { + if (verboseInfo) + printLargeMessage("Truth collision has more than 2 no mother particles. Breaking the particle loop."); + histos.get(HIST("Truth/hTroubles"))->Fill(12); + problem = true; + break; + } + // fill info for each tau + trueTauX[countMothers - 1] = particle.px(); + trueTauY[countMothers - 1] = particle.py(); + trueTauZ[countMothers - 1] = particle.pz(); + + // get daughters of the tau + const auto& daughters = particle.daughters_as(); + int countDaughters = 0; + for (const auto& daughter : daughters) { + // select only the charged particle (= no pi0 or neutrino) + if (enumMyParticle(daughter.pdgCode()) == -1) + continue; + countDaughters++; + // check there is only 1 charged daughter related to 1 tau + if (countDaughters > 1) { + if (verboseInfo) + printLargeMessage("Truth collision has more than 1 charged daughters of no mother particles. Breaking the daughter loop."); + histos.get(HIST("Truth/hTroubles"))->Fill(13); + problem = true; + break; + } + // fill info for each daughter + trueDaugX[countMothers - 1] = daughter.px(); + trueDaugY[countMothers - 1] = daughter.py(); + trueDaugZ[countMothers - 1] = daughter.pz(); + trueDaugPdgCode[countMothers - 1] = daughter.pdgCode(); + } // daughters + } // particles + } // collisions + + // decide the channel and set the variable. Only two cahnnels suported now. + if ((enumMyParticle(trueDaugPdgCode[0]) == P_ELECTRON) && (enumMyParticle(trueDaugPdgCode[1]) == P_ELECTRON)) + trueChannel = CH_EE; + if ((enumMyParticle(trueDaugPdgCode[0]) == P_ELECTRON) && ((enumMyParticle(trueDaugPdgCode[1]) == P_PION) || (enumMyParticle(trueDaugPdgCode[1]) == P_MUON))) + trueChannel = CH_EMUPI; + if ((enumMyParticle(trueDaugPdgCode[1]) == P_ELECTRON) && ((enumMyParticle(trueDaugPdgCode[0]) == P_PION) || (enumMyParticle(trueDaugPdgCode[0]) == P_MUON))) + trueChannel = CH_EMUPI; + + trueTauTwoTracks(runNumber, bc, nTrks[0], nTrks[1], nTrks[2], vtxPos[0], vtxPos[1], vtxPos[2], + recoMode, occupancy, hadronicRate, bcSels[0], bcSels[1], bcSels[2], + bcSels[3], bcSels[4], bcSels[5], bcSels[6], bcSels[7], + amplitudesFIT[0], amplitudesFIT[1], amplitudesFIT[2], -999., -999., // no ZDC info in MC + timesFIT[0], timesFIT[1], timesFIT[2], -999., -999., // no ZDC info in MC + px, py, pz, sign, dcaxy, dcaz, trkTimeRes, + itsClusterSizesTrk1, itsClusterSizesTrk2, + tpcSignal, tpcEl, tpcMu, tpcPi, tpcKa, tpcPr, tpcIP, + tofSignal, tofEl, tofMu, tofPi, tofKa, tofPr, tofEP, + trueChannel, trueHasRecoColl, mccoll.posX(), mccoll.posY(), mccoll.posZ(), + trueTauX, trueTauY, trueTauZ, trueDaugX, trueDaugY, trueDaugZ, trueDaugPdgCode, problem); + } // mccollisions } PROCESS_SWITCH(TauEventTableProducer, processMonteCarlo, "Iterate UD tables with simulated data created by SG-Candidate-Producer.", false); }; diff --git a/Scripts/o2_linter.py b/Scripts/o2_linter.py index bf365180c5f..f5e8ce8c3e2 100644 --- a/Scripts/o2_linter.py +++ b/Scripts/o2_linter.py @@ -22,10 +22,28 @@ import re import sys from enum import Enum +from pathlib import Path from typing import Union github_mode = False # GitHub mode prefix_disable = "o2-linter: disable=" # prefix for disabling tests +file_config = "o2linter_config" # name of the configuration file (applied per directory) +# If this file exists in the path of the tested file, +# failures of tests listed in this file will not make the linter fail. + + +# issue severity levels +class Severity(Enum): + WARNING = 1 + ERROR = 2 + DEFAULT = ERROR + + +# strings for error messages +message_levels = { + Severity.WARNING: "warning", + Severity.ERROR: "error", +} class Reference(Enum): @@ -126,16 +144,6 @@ def camel_case_to_kebab_case(line: str) -> str: return "".join(new_line) -def print_error(path: str, line: Union[int, None], title: str, message: str): - """Format and print error message.""" - # return # Use to suppress error messages. - str_line = "" if line is None else f"{line}:" - print(f"{path}:{str_line} {message} [{title}]") # terminal format - if github_mode: - str_line = "" if line is None else f",line={line}" - print(f"::warning file={path}{str_line},title=[{title}]::{message}") # GitHub annotation format - - def is_comment_cpp(line: str) -> bool: """Test whether a line is a C++ comment.""" return line.strip().startswith(("//", "/*")) @@ -188,6 +196,23 @@ def direction(char: str) -> int: return list_ranges +def get_tolerated_tests(path: str) -> "list[str]": + """Get the list of tolerated tests. + + Looks for the configuration file. + Starts in the test file directory and iterates through parents. + """ + tests: list[str] = [] + for directory in Path(path).resolve().parents: + path_tests = directory / file_config + if path_tests.is_file(): + with path_tests.open() as content: + tests = [line.strip() for line in content.readlines() if line.strip()] + print(f"{path}:1: info: Tolerating tests from {path_tests}. {tests}") + break + return tests + + class TestSpec: """Prototype of a test class""" @@ -195,10 +220,14 @@ class TestSpec: message: str = "Test failed" # error message rationale: str = "Rationale missing" # brief rationale explanation references: "list[Reference]" = [] # list of references relevant for this rule + severity_default: Severity = Severity.DEFAULT + severity_current: Severity = Severity.DEFAULT suffixes: "list[str]" = [] # suffixes of files to test per_line: bool = True # Test lines separately one by one. + tolerated: bool = False # flag for tolerating issues n_issues: int = 0 # issue counter n_disabled: int = 0 # counter of disabled issues + n_tolerated: int = 0 # counter of tolerated issues def file_matches(self, path: str) -> bool: """Test whether the path matches the pattern for files to test.""" @@ -217,6 +246,16 @@ def is_disabled(self, line: str, prefix_comment="//") -> bool: return True return False + def print_error(self, path: str, line: Union[int, None], message: str): + """Format and print error message.""" + # return # Use to suppress error messages. + line = line or 1 + # terminal format + print(f"{path}:{line}: {message_levels[self.severity_current]}: {message} [{self.name}]") + if github_mode and not self.tolerated: # Annotate only not tolerated issues. + # GitHub annotation format + print(f"::{message_levels[self.severity_current]} file={path},line={line},title=[{self.name}]::{message}") + def test_line(self, line: str) -> bool: """Test a line.""" raise NotImplementedError() @@ -225,10 +264,11 @@ def test_file(self, path: str, content) -> bool: """Test a file in a way that cannot be done line by line.""" raise NotImplementedError() - def run(self, path: str, content) -> bool: + def run(self, path: str, content: "list[str]") -> bool: """Run the test.""" # print(content) passed = True + self.severity_current = Severity.WARNING if self.tolerated else self.severity_default if not self.file_matches(path): return passed # print(f"Running test {self.name} for {path} with {len(content)} lines") @@ -243,14 +283,20 @@ def run(self, path: str, content) -> bool: continue if not self.test_line(line): passed = False - self.n_issues += 1 - print_error(path, i + 1, self.name, self.message) + if self.tolerated: + self.n_tolerated += 1 + else: + self.n_issues += 1 + self.print_error(path, i + 1, self.message) else: passed = self.test_file(path, content) if not passed: - self.n_issues += 1 - print_error(path, None, self.name, self.message) - return passed + if self.tolerated: + self.n_tolerated += 1 + else: + self.n_issues += 1 + self.print_error(path, None, self.message) + return passed or self.tolerated ########################## @@ -627,15 +673,14 @@ def test_file(self, path: str, content) -> bool: words = line.split() if len(words) < 2: passed = False - print_error( + self.print_error( path, i + 1, - self.name, "Failed to get the process function name. Keep it on the same line as the switch.", ) continue names_functions.append(words[1][:-1]) # Remove the trailing comma. - # print_error(path, i + 1, self.name, f"Got process function name {words[1][:-1]}.") + # self.print_error(path, i + 1, f"Got process function name {words[1][:-1]}.") # Test process functions. for i, line in enumerate(content): line = line.strip() @@ -672,7 +717,7 @@ def test_file(self, path: str, content) -> bool: for arg in words: if not re.search(r"([\w>] const|const [\w<>:]+)&", arg): passed = False - print_error(path, i + 1, self.name, f"Argument {arg} is not const&.") + self.print_error(path, i + 1, f"Argument {arg} is not const&.") line_process = 0 return passed @@ -692,7 +737,7 @@ class TestWorkflowOptions(TestSpec): def test_file(self, path: str, content) -> bool: is_inside_define = False # Are we inside defineDataProcessing? - for i, line in enumerate(content): # pylint: disable=unused-variable + for _i, line in enumerate(content): # pylint: disable=unused-variable if not line.strip(): continue if self.is_disabled(line): @@ -784,7 +829,7 @@ def test_file(self, path: str, content) -> bool: for item in doc_items: if re.search(rf"^{doc_prefix} [\\@]{item['keyword']} +{item['pattern']}", line): item["found"] = True - # print_error(path, i + 1, self.name, f"Found \{item['keyword']}.") + # self.print_error(path, i + 1, f"Found \{item['keyword']}.") break if all(item["found"] for item in doc_items): # All items have been found. passed = True @@ -792,10 +837,9 @@ def test_file(self, path: str, content) -> bool: if not passed: for item in doc_items: if not item["found"]: - print_error( + self.print_error( path, last_doc_line, - self.name, f"Documentation for \\{item['keyword']} is missing, incorrect or misplaced.", ) return passed @@ -1203,14 +1247,14 @@ def test_file(self, path: str, content) -> bool: workflow_name = line.strip().split("(")[1].split()[0] if not is_kebab_case(workflow_name): passed = False - print_error(path, i + 1, self.name, f"Invalid workflow name: {workflow_name}.") + self.print_error(path, i + 1, f"Invalid workflow name: {workflow_name}.") continue # Extract workflow file name. next_line = content[i + 1].strip() words = next_line.split() if words[0] != "SOURCES": passed = False - print_error(path, i + 2, self.name, f"Did not find sources for workflow: {workflow_name}.") + self.print_error(path, i + 2, f"Did not find sources for workflow: {workflow_name}.") continue workflow_file_name = os.path.basename(words[1]) # the actual file name # Generate the file name matching the workflow name. @@ -1218,10 +1262,9 @@ def test_file(self, path: str, content) -> bool: # Compare the actual and expected file names. if expected_workflow_file_name != workflow_file_name: passed = False - print_error( + self.print_error( path, i + 1, - self.name, f"Workflow name {workflow_name} does not match its file name {workflow_file_name}. " f"(Matches {expected_workflow_file_name}.)", ) @@ -1273,7 +1316,7 @@ def test_file(self, path: str, content) -> bool: line = line[(index + len("adaptAnalysisTask<")) :] # Extract struct name. if not (match := re.match(r"([^>]+)", line)): - print_error(path, i + 1, self.name, f'Failed to extract struct name from "{line}".') + self.print_error(path, i + 1, f'Failed to extract struct name from "{line}".') return False struct_name = match.group(1) if (index := struct_name.find("<")) > -1: @@ -1294,7 +1337,7 @@ def test_file(self, path: str, content) -> bool: passed = False # Extract explicit task name. if not (match := re.search(r"TaskName\{\"([^\}]+)\"\}", line)): - print_error(path, i + 1, self.name, f'Failed to extract explicit task name from "{line}".') + self.print_error(path, i + 1, f'Failed to extract explicit task name from "{line}".') return False task_name = match.group(1) # print(f"{i + 1}: Got struct \"{struct_name}\" with task name \"{task_name}\".") @@ -1309,10 +1352,9 @@ def test_file(self, path: str, content) -> bool: device_name_from_task_name ) # struct name matching the TaskName if not is_kebab_case(device_name_from_task_name): - print_error( + self.print_error( path, i + 1, - self.name, f"Specified task name {task_name} produces an invalid device name " f"{device_name_from_task_name}.", ) @@ -1320,10 +1362,9 @@ def test_file(self, path: str, content) -> bool: elif device_name_from_struct_name == device_name_from_task_name: # If the task name results in the same device name as the struct name would, # TaskName is redundant and should be removed. - print_error( + self.print_error( path, i + 1, - self.name, f"Specified task name {task_name} and the struct name {struct_name} produce " f"the same device name {device_name_from_struct_name}. TaskName is redundant.", ) @@ -1332,10 +1373,9 @@ def test_file(self, path: str, content) -> bool: # If the device names generated from the task name and from the struct name differ in hyphenation, # capitalisation of the struct name should be fixed and TaskName should be removed. # (special cases: alice3-, -2prong) - print_error( + self.print_error( path, i + 1, - self.name, f"Device names {device_name_from_task_name} and {device_name_from_struct_name} generated " f"from the specified task name {task_name} and from the struct name {struct_name}, " f"respectively, differ in hyphenation. Consider fixing capitalisation of the struct name " @@ -1347,10 +1387,9 @@ def test_file(self, path: str, content) -> bool: # from the struct name, accept it if the struct is templated. If the struct is not templated, # extension is acceptable if adaptAnalysisTask is called multiple times for the same struct. if not struct_templated: - print_error( + self.print_error( path, i + 1, - self.name, f"Device name {device_name_from_task_name} from the specified task name " f"{task_name} is an extension of the device name {device_name_from_struct_name} " f"from the struct name {struct_name} but the struct is not templated. " @@ -1358,16 +1397,15 @@ def test_file(self, path: str, content) -> bool: ) passed = False # else: - # print_error(path, i + 1, self.name, f"Device name {device_name_from_task_name} from + # self.print_error(path, i + 1, f"Device name {device_name_from_task_name} from # the specified task name {task_name} is an extension of the device name # {device_name_from_struct_name} from the struct name {struct_name} and the struct is templated. # All good") else: # Other cases should be rejected. - print_error( + self.print_error( path, i + 1, - self.name, f"Specified task name {task_name} produces device name {device_name_from_task_name} " f"which does not match the device name {device_name_from_struct_name} from " f"the struct name {struct_name}. (Matching struct name {struct_name_from_device_name})", @@ -1580,10 +1618,9 @@ def test_file(self, path: str, content) -> bool: first_line < last_line_last_member ): # The current category starts before the end of the previous category. passed = False - print_error( + self.print_error( path, first_line, - self.name, f"{struct_name}: {member.strip()} appears too early " f"(before end of {self.member_order[index_last_member].strip()}).", ) @@ -1610,7 +1647,7 @@ def main(): global github_mode # pylint: disable=global-statement # noqa: PLW0603 github_mode = True - tests = [] # list of activated tests + tests: list[TestSpec] = [] # list of activated tests # Bad practice enable_bad_practice = True @@ -1687,8 +1724,10 @@ def main(): continue try: with open(path, encoding="utf-8") as file: + tolerated_tests = get_tolerated_tests(path) content = file.readlines() for test in tests: + test.tolerated = test.name in tolerated_tests result = test.run(path, content) if not result: n_files_bad[test.name] += 1 @@ -1698,20 +1737,29 @@ def main(): print(f'Failed to open file "{path}".') sys.exit(1) - # Report results for tests that failed or were disabled. - if not passed or any(n > 0 for n in (test.n_disabled for test in tests)): - print("\nResults for failed and disabled tests") + # Report results for tests that failed or were disabled or were tolerated. + n_issues, n_disabled, n_tolerated = 0, 0, 0 # global counters + if not passed or any(n > 0 for n in (test.n_disabled + test.n_tolerated for test in tests)): + print("\nResults for failed, tolerated and disabled tests") len_max = max(len(name) for name in test_names) - print(f"test{' ' * (len_max - len('test'))}\tissues\tdisabled\tbad files\trationale") + print(f"test{' ' * (len_max - len('test'))}\tissues\ttolerated\tdisabled\tbad files\trationale") + print("-" * len_max) ref_names = [] for test in tests: - if any(n > 0 for n in (test.n_issues, test.n_disabled, n_files_bad[test.name])): + if any(n > 0 for n in (test.n_issues, test.n_disabled, test.n_tolerated, n_files_bad[test.name])): ref_ids = [ref.value for ref in test.references] ref_names += test.references print( - f"{test.name}{' ' * (len_max - len(test.name))}\t{test.n_issues}\t{test.n_disabled}" - f"\t\t{n_files_bad[test.name]}\t\t{test.rationale} {ref_ids}" + f"{test.name}{' ' * (len_max - len(test.name))}\t{test.n_issues}\t{test.n_tolerated}" + f"\t\t{test.n_disabled}\t\t{n_files_bad[test.name]}\t\t{test.rationale} {ref_ids}" ) + n_issues += test.n_issues + n_disabled += test.n_disabled + n_tolerated += test.n_tolerated + print("-" * len_max) + # Print the totals. + name_total = "total" + print(f"{name_total}{' ' * (len_max - len(name_total))}\t{n_issues}\t{n_tolerated}\t\t{n_disabled}") # Print list of references for listed tests. print("\nReferences") ref_names = list(dict.fromkeys(ref_names)) @@ -1733,14 +1781,29 @@ def main(): f'Exceptionally, you can disable a test for a line by adding a comment with "{prefix_disable}"' " followed by the name of the test and parentheses with a reason for the exception." ) + msg_tolerate = f'To tolerate certain issues in a directory, add a line with the test name in "{file_config}".' if github_mode: print(f"\n::error title={title_result}::{msg_result}") print(f"::notice::{msg_disable}") + print(f"::notice::{msg_tolerate}") else: print(f"\n{title_result}: {msg_result}") print(msg_disable) + print(msg_tolerate) + + # Make results available to the GitHub actions. + if github_mode: + try: + with open(os.environ["GITHUB_OUTPUT"], "a", encoding="utf-8") as fh: + print(f"n_issues={n_issues}", file=fh) + print(f"n_disabled={n_disabled}", file=fh) + print(f"n_tolerated={n_tolerated}", file=fh) + except KeyError: + print("Skipping writing in GITHUB_OUTPUT.") + # Print tips. print("\nTip: You can run the O2 linter locally with: python3 Scripts/o2_linter.py ") + if not passed: sys.exit(1) diff --git a/Tools/PIDML/CMakeLists.txt b/Tools/PIDML/CMakeLists.txt index 8ac36a5c0df..d7be3345443 100644 --- a/Tools/PIDML/CMakeLists.txt +++ b/Tools/PIDML/CMakeLists.txt @@ -10,19 +10,19 @@ # or submit itself to any jurisdiction. o2physics_add_dpl_workflow(pid-ml-producer - SOURCES pidMLProducer.cxx + SOURCES pidMlProducer.cxx JOB_POOL analysis PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(pid-ml-batch-eff-and-pur-producer - SOURCES pidMLBatchEffAndPurProducer.cxx + SOURCES pidMlBatchEffAndPurProducer.cxx JOB_POOL analysis PUBLIC_LINK_LIBRARIES O2::Framework ONNXRuntime::ONNXRuntime O2::CCDB O2Physics::DataModel COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(pid-ml-eff-and-pur-producer - SOURCES pidMLEffAndPurProducer.cxx + SOURCES pidMlEffAndPurProducer.cxx JOB_POOL analysis PUBLIC_LINK_LIBRARIES O2::Framework ONNXRuntime::ONNXRuntime O2::CCDB O2Physics::DataModel COMPONENT_NAME Analysis) @@ -45,12 +45,6 @@ o2physics_add_dpl_workflow(qa-pid COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(qa-pid-ml - SOURCES qaPidML.cxx + SOURCES qaPidMl.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore ONNXRuntime::ONNXRuntime COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(kaon-pid-ml - SOURCES KaonPidTask.cxx - JOB_POOL analysis - PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore ONNXRuntime::ONNXRuntime O2::CCDB O2Physics::DataModel - COMPONENT_NAME Analysis) diff --git a/Tools/PIDML/KaonPidTask.cxx b/Tools/PIDML/KaonPidTask.cxx deleted file mode 100644 index acc29e47bee..00000000000 --- a/Tools/PIDML/KaonPidTask.cxx +++ /dev/null @@ -1,138 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// 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. - -/// This task produces invariant mass vs. momentum and dEdX in TPC vs. momentum -/// for Kaons using ML PID from the PID ML ONNX Model. - -#include -#include -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" -#include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/Multiplicity.h" -#include "TLorentzVector.h" -#include "TDatabasePDG.h" -#include "Framework/AnalysisDataModel.h" -#include "Tools/PIDML/pidOnnxModel.h" -#include "Common/DataModel/TrackSelectionTables.h" -#include "Common/DataModel/PIDResponse.h" -#include "CommonConstants/PhysicsConstants.h" -#include "TMath.h" - -using namespace o2; -using namespace o2::framework; -using namespace o2::framework::expressions; - -namespace o2::aod -{ -using MyCollisions = soa::Join; -using MyTracks = soa::Join; -using MyCollision = MyCollisions::iterator; -using MyTrack = MyTracks::iterator; -} // namespace o2::aod - -struct KaonPidTask { - SliceCache cache; - Preslice perCol = aod::track::collisionId; - - std::shared_ptr pidModel; // creates a shared pointer to a new instance 'pidmodel'. - HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; - - Configurable cfgZvtxCut{"cfgZvtxCut", 10, "Z vtx cut"}; - Configurable cfgEtaCut{"cfgEtaCut", 0.8, "Pseudorapidity cut"}; - Configurable cfgMaxPtCut{"cfgMaxPtCut", 3.0, "Max Pt cut"}; - Configurable cfgMinPtCut{"cfgMinPtCut", 0.5, "Min Pt cut"}; - Configurable cfgMinNSigmaTPCCut{"cfgMinNSigmaTPCCut", 3., "N-sigma TPC cut"}; - Configurable cfgChargeCut{"cfgChargeCut", 0., "N-sigma TPC cut"}; - Configurable cfgPathLocal{"local-path", ".", "base path to the local directory with ONNX models"}; - Configurable cfgPathCCDB{"ccdb-path", "Users/m/mkabus/PIDML", "base path to the CCDB directory with ONNX models"}; - Configurable cfgCCDBURL{"ccdb-url", "http://alice-ccdb.cern.ch", "URL of the CCDB repository"}; - Configurable cfgPid{"pid", 321, "PID to predict"}; - Configurable cfgCertainty{"certainty", 0.5, "Minimum certainty above which the model accepts a particular type of particle"}; - Configurable cfgTimestamp{"timestamp", 0, "Fixed timestamp"}; - Configurable cfgUseCCDB{"useCCDB", false, "Whether to autofetch ML model from CCDB. If false, local file will be used."}; - - o2::ccdb::CcdbApi ccdbApi; - - Filter collisionFilter = (nabs(aod::collision::posZ) < cfgZvtxCut); - Filter trackFilter = (nabs(aod::track::eta) < cfgEtaCut) && (aod::track::pt > cfgMinPtCut) && (aod::track::pt < cfgMaxPtCut); - - // Applying filters - using MyFilteredCollisions = soa::Filtered; - using MyFilteredCollision = MyFilteredCollisions::iterator; - - Partition positive = (nabs(aod::track::eta) < cfgEtaCut) && (aod::track::pt > cfgMinPtCut) && (aod::track::pt < cfgMaxPtCut) && (aod::track::signed1Pt > cfgChargeCut); - Partition negative = (nabs(aod::track::eta) < cfgEtaCut) && (aod::track::pt > cfgMinPtCut) && (aod::track::pt < cfgMaxPtCut) && (aod::track::signed1Pt < cfgChargeCut); - - void init(o2::framework::InitContext&) - { - AxisSpec vtxZAxis = {100, -20, 20}; - std::vector ptBinning = {0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.8, 2.0, 2.2, 2.4, 2.8, 3.2, 3.6, 4.}; - AxisSpec ptAxis = {ptBinning, "#it{p}_{T} (GeV/#it{c})"}; - - if (cfgUseCCDB) { - ccdbApi.init(cfgCCDBURL); // Initializes ccdbApi when cfgUseCCDB is set to 'true' - } - pidModel = std::make_shared(cfgPathLocal.value, cfgPathCCDB.value, cfgUseCCDB.value, ccdbApi, cfgTimestamp.value, cfgPid.value, cfgCertainty.value); - - histos.add("hChargePos", ";z;", kTH1F, {{3, -1.5, 1.5}}); - histos.add("hChargeNeg", ";z;", kTH1F, {{3, -1.5, 1.5}}); - histos.add("hInvariantMass", ";M_{k^{+}k^{-}} (GeV/#it{c}^{2});", kTH1F, {{100, 0., 2.}}); - histos.add("hdEdXvsMomentum", ";P_{K^{+}K^{-}}; dE/dx in TPC (keV/cm)", kTH2F, {{100, 0., 4.}, {200, 20., 400.}}); - } - - void process(MyFilteredCollision const& coll, o2::aod::MyTracks const& /*tracks*/) - { - auto groupPositive = positive->sliceByCached(aod::track::collisionId, coll.globalIndex(), cache); - auto groupNegative = negative->sliceByCached(aod::track::collisionId, coll.globalIndex(), cache); - for (auto track : groupPositive) { - histos.fill(HIST("hChargePos"), track.sign()); - if (pidModel.get()->applyModelBoolean(track)) { - histos.fill(HIST("hdEdXvsMomentum"), track.p(), track.tpcSignal()); - } - } - - for (auto track : groupNegative) { - histos.fill(HIST("hChargeNeg"), track.sign()); - if (pidModel.get()->applyModelBoolean(track)) { - histos.fill(HIST("hdEdXvsMomentum"), track.p(), track.tpcSignal()); - } - } - - for (auto& [pos, neg] : combinations(soa::CombinationsFullIndexPolicy(groupPositive, groupNegative))) { - if (!(pidModel.get()->applyModelBoolean(pos)) || !(pidModel.get()->applyModelBoolean(neg))) { - continue; - } - - TLorentzVector part1Vec; - TLorentzVector part2Vec; - float mMassOne = TDatabasePDG::Instance()->GetParticle(cfgPid.value)->Mass(); - float mMassTwo = TDatabasePDG::Instance()->GetParticle(cfgPid.value)->Mass(); - - part1Vec.SetPtEtaPhiM(pos.pt(), pos.eta(), pos.phi(), mMassOne); - part2Vec.SetPtEtaPhiM(neg.pt(), neg.eta(), neg.phi(), mMassTwo); - - TLorentzVector sumVec(part1Vec); - sumVec += part2Vec; - - histos.fill(HIST("hInvariantMass"), sumVec.M()); - } - } -}; - -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) -{ - WorkflowSpec workflow{adaptAnalysisTask(cfgc)}; - return workflow; -} diff --git a/Tools/PIDML/pidML.h b/Tools/PIDML/pidMl.h similarity index 82% rename from Tools/PIDML/pidML.h rename to Tools/PIDML/pidMl.h index 821da7efc42..935440e26f7 100644 --- a/Tools/PIDML/pidML.h +++ b/Tools/PIDML/pidMl.h @@ -9,7 +9,7 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -/// \file pidML.h +/// \file pidMl.h /// \brief Data model for PID ML training. /// /// \author Maja Kabus @@ -19,6 +19,8 @@ #include "Framework/AnalysisDataModel.h" #include "Common/DataModel/PIDResponse.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/Multiplicity.h" namespace o2::aod { @@ -32,16 +34,16 @@ DECLARE_SOA_COLUMN(Py, py, float); //! Non-dynam DECLARE_SOA_COLUMN(Pz, pz, float); //! Non-dynamic column with track z-momentum DECLARE_SOA_COLUMN(Sign, sign, float); //! Non-dynamic column with track sign DECLARE_SOA_COLUMN(IsPhysicalPrimary, isPhysicalPrimary, uint8_t); //! -DECLARE_SOA_COLUMN(TOFExpSignalDiffEl, tofExpSignalDiffEl, float); //! Difference between signal and expected for electron -DECLARE_SOA_COLUMN(TPCExpSignalDiffEl, tpcExpSignalDiffEl, float); //! Difference between signal and expected for electron -DECLARE_SOA_COLUMN(TOFExpSignalDiffMu, tofExpSignalDiffMu, float); //! Difference between signal and expected for muon -DECLARE_SOA_COLUMN(TPCExpSignalDiffMu, tpcExpSignalDiffMu, float); //! Difference between signal and expected for muon -DECLARE_SOA_COLUMN(TOFExpSignalDiffPi, tofExpSignalDiffPi, float); //! Difference between signal and expected for pion -DECLARE_SOA_COLUMN(TPCExpSignalDiffPi, tpcExpSignalDiffPi, float); //! Difference between signal and expected for pion -DECLARE_SOA_COLUMN(TOFExpSignalDiffKa, tofExpSignalDiffKa, float); //! Difference between signal and expected for kaon -DECLARE_SOA_COLUMN(TPCExpSignalDiffKa, tpcExpSignalDiffKa, float); //! Difference between signal and expected for kaon -DECLARE_SOA_COLUMN(TOFExpSignalDiffPr, tofExpSignalDiffPr, float); //! Difference between signal and expected for proton -DECLARE_SOA_COLUMN(TPCExpSignalDiffPr, tpcExpSignalDiffPr, float); //! Difference between signal and expected for proton +DECLARE_SOA_COLUMN(TofExpSignalDiffEl, tofExpSignalDiffEl, float); //! Difference between signal and expected for electron +DECLARE_SOA_COLUMN(TpcExpSignalDiffEl, tpcExpSignalDiffEl, float); //! Difference between signal and expected for electron +DECLARE_SOA_COLUMN(TofExpSignalDiffMu, tofExpSignalDiffMu, float); //! Difference between signal and expected for muon +DECLARE_SOA_COLUMN(TpcExpSignalDiffMu, tpcExpSignalDiffMu, float); //! Difference between signal and expected for muon +DECLARE_SOA_COLUMN(TofExpSignalDiffPi, tofExpSignalDiffPi, float); //! Difference between signal and expected for pion +DECLARE_SOA_COLUMN(TpcExpSignalDiffPi, tpcExpSignalDiffPi, float); //! Difference between signal and expected for pion +DECLARE_SOA_COLUMN(TofExpSignalDiffKa, tofExpSignalDiffKa, float); //! Difference between signal and expected for kaon +DECLARE_SOA_COLUMN(TpcExpSignalDiffKa, tpcExpSignalDiffKa, float); //! Difference between signal and expected for kaon +DECLARE_SOA_COLUMN(TofExpSignalDiffPr, tofExpSignalDiffPr, float); //! Difference between signal and expected for proton +DECLARE_SOA_COLUMN(TpcExpSignalDiffPr, tpcExpSignalDiffPr, float); //! Difference between signal and expected for proton } // namespace pidtracks DECLARE_SOA_TABLE(PidTracksDataMl, "AOD", "PIDTRACKSDATAML", //! Data tracks for prediction and domain adaptation aod::track::TPCSignal, @@ -63,7 +65,6 @@ DECLARE_SOA_TABLE(PidTracksDataMl, "AOD", "PIDTRACKSDATAML", //! Data tracks for aod::track::DcaXY, aod::track::DcaZ); DECLARE_SOA_TABLE(PidTracksData, "AOD", "PIDTRACKSDATA", //! Data tracks for comparative analysis - aod::cent::CentRun2V0M, aod::mult::MultFV0A, aod::mult::MultFV0C, pidtracks::MultFV0M, aod::mult::MultFT0A, aod::mult::MultFT0C, pidtracks::MultFT0M, aod::mult::MultZNA, aod::mult::MultZNC, @@ -90,34 +91,34 @@ DECLARE_SOA_TABLE(PidTracksData, "AOD", "PIDTRACKSDATA", //! Data tracks for com aod::track::DcaZ, pidtpc::TPCNSigmaEl, pidtpc::TPCExpSigmaEl, - pidtracks::TPCExpSignalDiffEl, + pidtracks::TpcExpSignalDiffEl, pidtof::TOFNSigmaEl, pidtof::TOFExpSigmaEl, - pidtracks::TOFExpSignalDiffEl, + pidtracks::TofExpSignalDiffEl, pidtpc::TPCNSigmaMu, pidtpc::TPCExpSigmaMu, - pidtracks::TPCExpSignalDiffMu, + pidtracks::TpcExpSignalDiffMu, pidtof::TOFNSigmaMu, pidtof::TOFExpSigmaMu, - pidtracks::TOFExpSignalDiffMu, + pidtracks::TofExpSignalDiffMu, pidtpc::TPCNSigmaPi, pidtpc::TPCExpSigmaPi, - pidtracks::TPCExpSignalDiffPi, + pidtracks::TpcExpSignalDiffPi, pidtof::TOFNSigmaPi, pidtof::TOFExpSigmaPi, - pidtracks::TOFExpSignalDiffPi, + pidtracks::TofExpSignalDiffPi, pidtpc::TPCNSigmaKa, pidtpc::TPCExpSigmaKa, - pidtracks::TPCExpSignalDiffKa, + pidtracks::TpcExpSignalDiffKa, pidtof::TOFNSigmaKa, pidtof::TOFExpSigmaKa, - pidtracks::TOFExpSignalDiffKa, + pidtracks::TofExpSignalDiffKa, pidtpc::TPCNSigmaPr, pidtpc::TPCExpSigmaPr, - pidtracks::TPCExpSignalDiffPr, + pidtracks::TpcExpSignalDiffPr, pidtof::TOFNSigmaPr, pidtof::TOFExpSigmaPr, - pidtracks::TOFExpSignalDiffPr); + pidtracks::TofExpSignalDiffPr); DECLARE_SOA_TABLE(PidTracksMcMl, "AOD", "PIDTRACKSMCML", //! MC tracks for training aod::track::TPCSignal, aod::track::TRDSignal, aod::track::TRDPattern, @@ -140,7 +141,6 @@ DECLARE_SOA_TABLE(PidTracksMcMl, "AOD", "PIDTRACKSMCML", //! MC tracks for train aod::mcparticle::PdgCode, pidtracks::IsPhysicalPrimary); DECLARE_SOA_TABLE(PidTracksMc, "AOD", "PIDTRACKSMC", //! MC tracks for comparative analysis - aod::cent::CentRun2V0M, aod::mult::MultFV0A, aod::mult::MultFV0C, pidtracks::MultFV0M, aod::mult::MultFT0A, aod::mult::MultFT0C, pidtracks::MultFT0M, aod::mult::MultZNA, aod::mult::MultZNC, @@ -167,34 +167,34 @@ DECLARE_SOA_TABLE(PidTracksMc, "AOD", "PIDTRACKSMC", //! MC tracks for comparati aod::track::DcaZ, pidtpc::TPCNSigmaEl, pidtpc::TPCExpSigmaEl, - pidtracks::TPCExpSignalDiffEl, + pidtracks::TpcExpSignalDiffEl, pidtof::TOFNSigmaEl, pidtof::TOFExpSigmaEl, - pidtracks::TOFExpSignalDiffEl, + pidtracks::TofExpSignalDiffEl, pidtpc::TPCNSigmaMu, pidtpc::TPCExpSigmaMu, - pidtracks::TPCExpSignalDiffMu, + pidtracks::TpcExpSignalDiffMu, pidtof::TOFNSigmaMu, pidtof::TOFExpSigmaMu, - pidtracks::TOFExpSignalDiffMu, + pidtracks::TofExpSignalDiffMu, pidtpc::TPCNSigmaPi, pidtpc::TPCExpSigmaPi, - pidtracks::TPCExpSignalDiffPi, + pidtracks::TpcExpSignalDiffPi, pidtof::TOFNSigmaPi, pidtof::TOFExpSigmaPi, - pidtracks::TOFExpSignalDiffPi, + pidtracks::TofExpSignalDiffPi, pidtpc::TPCNSigmaKa, pidtpc::TPCExpSigmaKa, - pidtracks::TPCExpSignalDiffKa, + pidtracks::TpcExpSignalDiffKa, pidtof::TOFNSigmaKa, pidtof::TOFExpSigmaKa, - pidtracks::TOFExpSignalDiffKa, + pidtracks::TofExpSignalDiffKa, pidtpc::TPCNSigmaPr, pidtpc::TPCExpSigmaPr, - pidtracks::TPCExpSignalDiffPr, + pidtracks::TpcExpSignalDiffPr, pidtof::TOFNSigmaPr, pidtof::TOFExpSigmaPr, - pidtracks::TOFExpSignalDiffPr, + pidtracks::TofExpSignalDiffPr, aod::mcparticle::PdgCode, pidtracks::IsPhysicalPrimary); } // namespace o2::aod diff --git a/Tools/PIDML/pidMLBatchEffAndPurProducer.cxx b/Tools/PIDML/pidMlBatchEffAndPurProducer.cxx similarity index 61% rename from Tools/PIDML/pidMLBatchEffAndPurProducer.cxx rename to Tools/PIDML/pidMlBatchEffAndPurProducer.cxx index 9a611ded269..86adb2cf238 100644 --- a/Tools/PIDML/pidMLBatchEffAndPurProducer.cxx +++ b/Tools/PIDML/pidMlBatchEffAndPurProducer.cxx @@ -9,9 +9,9 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -/// \file pidMLBatchEffAndPurProducer +/// \file pidMlBatchEffAndPurProducer.cxx /// \brief Batch PID execution task. It produces derived data needed for ROOT script, which -/// generates efficiency (recall) and purity (precision) analysis of ML Model PID +/// generate PIDML neural network performance benchmark plots. /// /// \author Michał Olędzki /// \author Marek Mytkowski @@ -19,6 +19,9 @@ #include #include #include +#include +#include +#include #include "Framework/AnalysisDataModel.h" #include "Framework/runDataProcessing.h" @@ -44,9 +47,9 @@ DECLARE_SOA_COLUMN(Pid, pid, int32_t); //! PDG particle ID to be t DECLARE_SOA_COLUMN(Pt, pt, float); //! particle's pt DECLARE_SOA_COLUMN(MlCertainty, mlCertainty, float); //! Machine learning model certainty value for track and pid DECLARE_SOA_COLUMN(NSigma, nSigma, float); //! nSigma value for track and pid -DECLARE_SOA_COLUMN(IsPidMC, isPidMc, bool); //! Is track's mcParticle recognized as "Pid" -DECLARE_SOA_COLUMN(HasTOF, hasTof, bool); //! Does track have TOF detector signal -DECLARE_SOA_COLUMN(HasTRD, hasTrd, bool); //! Does track have TRD detector signal +DECLARE_SOA_COLUMN(IsPidMC, isPidMC, bool); //! Is track's mcParticle recognized as "Pid" +DECLARE_SOA_COLUMN(HasTOF, hasTOF, bool); //! Does track have TOF detector signal +DECLARE_SOA_COLUMN(HasTRD, hasTRD, bool); //! Does track have TRD detector signal } // namespace effandpurpidresult DECLARE_SOA_TABLE(EffAndPurPidResult, "AOD", "PIDEFFANDPURRES", o2::soa::Index<>, @@ -58,49 +61,49 @@ struct PidMlBatchEffAndPurProducer { Produces effAndPurPIDResult; HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; - static constexpr int32_t currentRunNumber = -1; - static constexpr uint32_t kNPids = 6; - static constexpr int32_t kPids[kNPids] = {2212, 321, 211, -211, -321, -2212}; - static constexpr std::string_view kParticleLabels[kNPids] = {"2212", "321", "211", "0211", "0321", "02212"}; - static constexpr std::string_view kParticleNames[kNPids] = {"proton", "kaon", "pion", "antipion", "antikaon", "antiproton"}; + static constexpr int32_t CurrentRunNumber = -1; + static constexpr uint32_t KNPids = 6; + static constexpr int32_t KPids[KNPids] = {2212, 321, 211, -211, -321, -2212}; + static constexpr std::string_view KParticleLabels[KNPids] = {"2212", "321", "211", "0211", "0321", "02212"}; + static constexpr std::string_view KPatricleNames[KNPids] = {"proton", "kaon", "pion", "antipion", "antikaon", "antiproton"}; - std::array, kNPids> hTracked; - std::array, kNPids> hMCPositive; + std::array, KNPids> hTracked; + std::array, KNPids> hMCPositive; o2::ccdb::CcdbApi ccdbApi; - std::vector models; - Configurable> cfgPids{"pids", std::vector(kPids, kPids + kNPids), "PIDs to predict"}; - Configurable> cfgDetectorsPLimits{"detectors-p-limits", std::array(pidml_pt_cuts::defaultModelPLimits), "\"use {detector} when p >= y_{detector}\": array of 3 doubles [y_TPC, y_TOF, y_TRD]"}; - Configurable cfgPathCCDB{"ccdb-path", "Users/m/mkabus/PIDML", "base path to the CCDB directory with ONNX models"}; - Configurable cfgCCDBURL{"ccdb-url", "http://alice-ccdb.cern.ch", "URL of the CCDB repository"}; - Configurable cfgUseCCDB{"use-ccdb", true, "Whether to autofetch ML model from CCDB. If false, local file will be used."}; - Configurable cfgPathLocal{"local-path", "/home/mkabus/PIDML/", "base path to the local directory with ONNX models"}; - Configurable cfgUseFixedTimestamp{"use-fixed-timestamp", false, "Whether to use fixed timestamp from configurable instead of timestamp calculated from the data"}; - Configurable cfgTimestamp{"timestamp", 1524176895000, "Hardcoded timestamp for tests"}; + Configurable> pdgPids{"pdgPids", std::vector(KPids, KPids + KNPids), "list of PDG ids of particles to predict. Every subset of {2212, 321, 211, -211, -321, -2212} is correct value."}; + Configurable detectorMomentumLimits{"detectorMomentumLimits", MomentumLimitsMatrix(pidml_pt_cuts::defaultModelPLimits), "\"use {detector} when p >= y_{detector}\": array of 3 doubles [y_TPC, y_TOF, y_TRD]"}; + Configurable ccdbPath{"ccdbPath", "Users/m/mkabus/PIDML", "Base path to the CCDB directory with ONNX models"}; + Configurable ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "URL of the CCDB repository"}; + Configurable useCcdb{"useCcdb", true, "Whether to autofetch ML model from CCDB. If false, local file will be used."}; + Configurable localPath{"localPath", "/home/mkabus/PIDML/", "Base path to the local directory with ONNX models"}; + Configurable useFixedTimestamp{"useFixedTimestamp", false, "Whether to use fixed timestamp from configurable instead of timestamp calculated from the data"}; + Configurable fixedTimestamp{"fixedTimestamp", 1524176895000, "Hardcoded timestamp for tests"}; Filter trackFilter = requireGlobalTrackInFilter(); using BigTracks = soa::Filtered>; + std::vector> models; void initHistos() { static const AxisSpec axisPt{50, 0, 3.1, "pt"}; - static_for<0, kNPids - 1>([&](auto i) { - if (std::find(cfgPids.value.begin(), cfgPids.value.end(), kPids[i]) != cfgPids.value.end()) { - hTracked[i] = histos.add(Form("%s/hPtMCTracked", kParticleLabels[i].data()), Form("Tracked %ss vs pT", kParticleNames[i].data()), kTH1F, {axisPt}); - hMCPositive[i] = histos.add(Form("%s/hPtMCPositive", kParticleLabels[i].data()), Form("MC Positive %ss vs pT", kParticleNames[i].data()), kTH1F, {axisPt}); + static_for<0, KNPids - 1>([&](auto i) { + if (std::find(pdgPids.value.begin(), pdgPids.value.end(), KPids[i]) != pdgPids.value.end()) { + hTracked[i] = histos.add(Form("%s/hPtMCTracked", KParticleLabels[i].data()), Form("Tracked %ss vs pT", KPatricleNames[i].data()), kTH1F, {axisPt}); + hMCPositive[i] = histos.add(Form("%s/hPtMCPositive", KParticleLabels[i].data()), Form("MC Positive %ss vs pT", KPatricleNames[i].data()), kTH1F, {axisPt}); } }); } void init(InitContext const&) { - if (cfgUseCCDB) { - ccdbApi.init(cfgCCDBURL); + if (useCcdb) { + ccdbApi.init(ccdbUrl); } initHistos(); @@ -110,7 +113,7 @@ struct PidMlBatchEffAndPurProducer { { std::optional index; - if (std::find(cfgPids.value.begin(), cfgPids.value.end(), pdgCode) != cfgPids.value.end()) { + if (std::find(pdgPids.value.begin(), pdgPids.value.end(), pdgCode) != pdgPids.value.end()) { switch (pdgCode) { case 2212: index = 0; @@ -160,7 +163,7 @@ struct PidMlBatchEffAndPurProducer { { nSigma_t nSigma; - switch (TMath::Abs(cfgPid)) { + switch (std::abs(cfgPid)) { case 11: // electron nSigma.tof = track.tofNSigmaEl(); nSigma.tpc = track.tpcNSigmaEl(); @@ -183,10 +186,10 @@ struct PidMlBatchEffAndPurProducer { break; } - if (!inPLimit(track, cfgDetectorsPLimits.value[kTPCTOF]) || tofMissing(track)) { - nSigma.composed = TMath::Abs(nSigma.tpc); + if (!inPLimit(track, detectorMomentumLimits.value[kTPCTOF]) || tofMissing(track)) { + nSigma.composed = std::abs(nSigma.tpc); } else { - nSigma.composed = TMath::Hypot(nSigma.tof, nSigma.tpc); + nSigma.composed = std::hypot(nSigma.tof, nSigma.tpc); } int32_t sign = cfgPid > 0 ? 1 : -1; @@ -202,36 +205,36 @@ struct PidMlBatchEffAndPurProducer { effAndPurPIDResult.reserve(mcParticles.size()); auto bc = collisions.iteratorAt(0).bc_as(); - if (cfgUseCCDB && bc.runNumber() != currentRunNumber) { - uint64_t timestamp = cfgUseFixedTimestamp ? cfgTimestamp.value : bc.timestamp(); - for (const int32_t& pid : cfgPids.value) - models.emplace_back(PidONNXModel(cfgPathLocal.value, cfgPathCCDB.value, cfgUseCCDB.value, - ccdbApi, timestamp, pid, 1.1, &cfgDetectorsPLimits.value[0])); + if (useCcdb && bc.runNumber() != CurrentRunNumber) { + uint64_t timestamp = useFixedTimestamp ? fixedTimestamp.value : bc.timestamp(); + for (const int32_t& pid : pdgPids.value) + models.emplace_back(PidONNXModel(localPath.value, ccdbPath.value, useCcdb.value, + ccdbApi, timestamp, pid, 1.1, &detectorMomentumLimits.value[0])); } else { - for (int32_t& pid : cfgPids.value) - models.emplace_back(PidONNXModel(cfgPathLocal.value, cfgPathCCDB.value, cfgUseCCDB.value, - ccdbApi, -1, pid, 1.1, &cfgDetectorsPLimits.value[0])); + for (const int32_t& pid : pdgPids.value) + models.emplace_back(PidONNXModel(localPath.value, ccdbPath.value, useCcdb.value, + ccdbApi, -1, pid, 1.1, &detectorMomentumLimits.value[0])); } - for (auto& mcPart : mcParticles) { + for (const auto& mcPart : mcParticles) { // eta cut is done in requireGlobalTrackInFilter() so we cut it only here - if (mcPart.isPhysicalPrimary() && TMath::Abs(mcPart.eta()) < kGlobalEtaCut) { + if (mcPart.isPhysicalPrimary() && std::abs(mcPart.eta()) < kGlobalEtaCut) { fillMCPositiveHist(mcPart.pdgCode(), mcPart.pt()); } } - for (auto& track : tracks) { + for (const auto& track : tracks) { if (track.has_mcParticle()) { auto mcPart = track.mcParticle(); if (mcPart.isPhysicalPrimary()) { fillTrackedHist(mcPart.pdgCode(), track.pt()); - for (size_t i = 0; i < cfgPids.value.size(); ++i) { + for (size_t i = 0; i < pdgPids.value.size(); ++i) { float mlCertainty = models[i].applyModel(track); - nSigma_t nSigma = getNSigma(track, cfgPids.value[i]); - bool isMCPid = mcPart.pdgCode() == cfgPids.value[i]; + nSigma_t nSigma = getNSigma(track, pdgPids.value[i]); + bool isMCPid = mcPart.pdgCode() == pdgPids.value[i]; - effAndPurPIDResult(track.index(), cfgPids.value[i], track.pt(), mlCertainty, nSigma.composed, isMCPid, track.hasTOF(), track.hasTRD()); + effAndPurPIDResult(track.index(), pdgPids.value[i], track.pt(), mlCertainty, nSigma.composed, isMCPid, track.hasTOF(), track.hasTRD()); } } } diff --git a/Tools/PIDML/pidMLEffAndPurProducer.cxx b/Tools/PIDML/pidMlEffAndPurProducer.cxx similarity index 69% rename from Tools/PIDML/pidMLEffAndPurProducer.cxx rename to Tools/PIDML/pidMlEffAndPurProducer.cxx index 7e626a8d631..e3c57763dbf 100644 --- a/Tools/PIDML/pidMLEffAndPurProducer.cxx +++ b/Tools/PIDML/pidMlEffAndPurProducer.cxx @@ -9,7 +9,7 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -/// \file pidMLEffAndPurProducer.cxx +/// \file pidMlEffAndPurProducer.cxx /// \brief Produce pt histograms for tracks accepted by ML network and for MC mcParticles. /// /// \author Michał Olędzki @@ -24,7 +24,6 @@ #include "Common/DataModel/TrackSelectionTables.h" #include "Common/DataModel/PIDResponse.h" #include "Tools/PIDML/pidOnnxModel.h" -#include "pidOnnxModel.h" #include "Tools/PIDML/pidUtils.h" using namespace o2; @@ -35,19 +34,18 @@ using namespace pidml::pidutils; struct PidMlEffAndPurProducer { HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; - PidONNXModel pidModel; - Configurable cfgPid{"pid", 211, "PID to predict"}; - Configurable cfgNSigmaCut{"n-sigma-cut", 3.0f, "TPC and TOF PID nSigma cut"}; - Configurable> cfgDetectorsPLimits{"detectors-p-limits", std::array(pidml_pt_cuts::defaultModelPLimits), "\"use {detector} when p >= y_{detector}\": array of 3 doubles [y_TPC, y_TOF, y_TRD]"}; - Configurable cfgCertainty{"certainty", 0.5, "Min certainty of the model to accept given mcPart to be of given kind"}; + Configurable pdgPid{"pdgPid", 211, "PID to predict"}; + Configurable nSigmaCut{"nSigmaCut", 3.0f, "TPC and TOF PID nSigma cut"}; + Configurable detectorMomentumLimits{"detectorMomentumLimits", MomentumLimitsMatrix(pidml_pt_cuts::defaultModelPLimits), "use {detector} when p >= y_{detector}: array of 3 doubles [y_TPC, y_TOF, y_TRD]"}; + Configurable mlIdentCertaintyThreshold{"mlIdentCertaintyThreshold", 0.5, "Min certainty of the model to accept given mcPart to be of given kind"}; - Configurable cfgPathCCDB{"ccdb-path", "Users/m/mkabus/PIDML", "base path to the CCDB directory with ONNX models"}; - Configurable cfgCCDBURL{"ccdb-url", "http://alice-ccdb.cern.ch", "URL of the CCDB repository"}; - Configurable cfgUseCCDB{"use-ccdb", true, "Whether to autofetch ML model from CCDB. If false, local file will be used."}; - Configurable cfgPathLocal{"local-path", "/home/mkabus/PIDML", "base path to the local directory with ONNX models"}; + Configurable ccdbPath{"ccdbPath", "Users/m/mkabus/PIDML", "base path to the CCDB directory with ONNX models"}; + Configurable ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "URL of the CCDB repository"}; + Configurable useCcdb{"useCcdb", true, "Whether to autofetch ML model from CCDB. If false, local file will be used."}; + Configurable localPath{"localPath", "/home/mkabus/PIDML", "base path to the local directory with ONNX models"}; - Configurable cfgUseFixedTimestamp{"use-fixed-timestamp", false, "Whether to use fixed timestamp from configurable instead of timestamp calculated from the data"}; - Configurable cfgTimestamp{"timestamp", 1524176895000, "Hardcoded timestamp for tests"}; + Configurable useFixedTimestamp{"useFixedTimestamp", false, "Whether to use fixed timestamp from configurable instead of timestamp calculated from the data"}; + Configurable fixedTimestamp{"fixedTimestamp", 1524176895000, "Hardcoded timestamp for tests"}; o2::ccdb::CcdbApi ccdbApi; int currentRunNumber = -1; @@ -57,16 +55,17 @@ struct PidMlEffAndPurProducer { using BigTracks = soa::Filtered>; + PidONNXModel pidModel; typedef struct nSigma_t { double tpc, tof; } nSigma_t; - nSigma_t GetNSigma(const BigTracks::iterator& track) + nSigma_t getNSigma(const BigTracks::iterator& track) { nSigma_t nSigma; - switch (TMath::Abs(cfgPid)) { + switch (std::abs(pdgPid)) { case 11: // electron nSigma.tof = track.tofNSigmaEl(); nSigma.tpc = track.tpcNSigmaEl(); @@ -92,19 +91,19 @@ struct PidMlEffAndPurProducer { return nSigma; } - bool IsNSigmaAccept(const BigTracks::iterator& track, nSigma_t& nSigma) + bool isNSigmaAccept(const BigTracks::iterator& track, nSigma_t& nSigma) { // FIXME: for current particles it works, but there are some particles, // which can have different sign and pdgSign - int sign = cfgPid > 0 ? 1 : -1; + int sign = pdgPid > 0 ? 1 : -1; if (track.sign() != sign) return false; - if (!inPLimit(track, cfgDetectorsPLimits.value[kTPCTOF]) || tofMissing(track)) { - if (TMath::Abs(nSigma.tpc) >= cfgNSigmaCut) + if (!inPLimit(track, detectorMomentumLimits.value[kTPCTOF]) || tofMissing(track)) { + if (std::abs(nSigma.tpc) >= nSigmaCut) return false; } else { - if (TMath::Hypot(nSigma.tof, nSigma.tpc) >= cfgNSigmaCut) + if (std::hypot(nSigma.tof, nSigma.tpc) >= nSigmaCut) return false; } @@ -113,11 +112,11 @@ struct PidMlEffAndPurProducer { void init(InitContext const&) { - if (cfgUseCCDB) { - ccdbApi.init(cfgCCDBURL); + if (useCcdb) { + ccdbApi.init(ccdbUrl); } else { - pidModel = PidONNXModel(cfgPathLocal.value, cfgPathCCDB.value, cfgUseCCDB.value, ccdbApi, -1, - cfgPid.value, cfgCertainty.value, &cfgDetectorsPLimits.value[0]); + pidModel = PidONNXModel(localPath.value, ccdbPath.value, useCcdb.value, ccdbApi, -1, + pdgPid.value, mlIdentCertaintyThreshold.value, &detectorMomentumLimits.value[0]); } const AxisSpec axisPt{100, 0, 5.0, "pt"}; @@ -151,26 +150,26 @@ struct PidMlEffAndPurProducer { void process(aod::Collisions const& collisions, BigTracks const& tracks, aod::BCsWithTimestamps const&, aod::McParticles const& mcParticles) { auto bc = collisions.iteratorAt(0).bc_as(); - if (cfgUseCCDB && bc.runNumber() != currentRunNumber) { - uint64_t timestamp = cfgUseFixedTimestamp ? cfgTimestamp.value : bc.timestamp(); - pidModel = PidONNXModel(cfgPathLocal.value, cfgPathCCDB.value, cfgUseCCDB.value, ccdbApi, timestamp, - cfgPid.value, cfgCertainty.value, &cfgDetectorsPLimits.value[0]); + if (useCcdb && bc.runNumber() != currentRunNumber) { + uint64_t timestamp = useFixedTimestamp ? fixedTimestamp.value : bc.timestamp(); + pidModel = PidONNXModel(localPath.value, ccdbPath.value, useCcdb.value, ccdbApi, timestamp, + pdgPid.value, mlIdentCertaintyThreshold.value, &detectorMomentumLimits.value[0]); } - for (auto& mcPart : mcParticles) { + for (const auto& mcPart : mcParticles) { // eta cut is included in requireGlobalTrackInFilter() so we cut it only here - if (mcPart.isPhysicalPrimary() && TMath::Abs(mcPart.eta()) < kGlobalEtaCut && mcPart.pdgCode() == pidModel.mPid) { + if (mcPart.isPhysicalPrimary() && std::abs(mcPart.eta()) < kGlobalEtaCut && mcPart.pdgCode() == pidModel.mPid) { histos.fill(HIST("hPtMCPositive"), mcPart.pt()); } } - for (auto& track : tracks) { + for (const auto& track : tracks) { if (track.has_mcParticle()) { auto mcPart = track.mcParticle(); if (mcPart.isPhysicalPrimary()) { bool mlAccepted = pidModel.applyModelBoolean(track); - nSigma_t nSigma = GetNSigma(track); - bool nSigmaAccepted = IsNSigmaAccept(track, nSigma); + nSigma_t nSigma = getNSigma(track); + bool nSigmaAccepted = isNSigmaAccept(track, nSigma); LOGF(debug, "collision id: %d track id: %d mlAccepted: %d nSigmaAccepted: %d p: %.3f; x: %.3f, y: %.3f, z: %.3f", track.collisionId(), track.index(), mlAccepted, nSigmaAccepted, track.p(), track.x(), track.y(), track.z()); diff --git a/Tools/PIDML/pidMLProducer.cxx b/Tools/PIDML/pidMlProducer.cxx similarity index 82% rename from Tools/PIDML/pidMLProducer.cxx rename to Tools/PIDML/pidMlProducer.cxx index 67cf4308a5e..de1d65622d0 100644 --- a/Tools/PIDML/pidMLProducer.cxx +++ b/Tools/PIDML/pidMlProducer.cxx @@ -9,13 +9,14 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -/// \file pidMLProducer.cxx +/// \file pidMlProducer.cxx /// \brief Produce PID ML skimmed data from MC or data files. /// /// \author Maja Kabus /// \author Marek Mytkowski #include +#include #include "Framework/AnalysisTask.h" #include "Framework/StaticFor.h" #include "Framework/AnalysisDataModel.h" @@ -24,7 +25,7 @@ #include "Common/DataModel/Centrality.h" #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "Tools/PIDML/pidML.h" +#include "Tools/PIDML/pidMl.h" #include "Tools/PIDML/pidUtils.h" using namespace o2; @@ -53,36 +54,36 @@ struct PidMlProducer { using BigTracksMC = soa::Filtered>; using MyCollisionML = aod::Collisions::iterator; - using MyCollision = soa::Join::iterator; + using MyCollision = soa::Join::iterator; - static constexpr uint32_t nCharges = 2; + static constexpr uint32_t NCharges = 2; - static constexpr std::string_view histPrefixes[nCharges] = {"minus", "plus"}; + static constexpr std::string_view HistPrefixes[NCharges] = {"minus", "plus"}; // 2D - std::array, nCharges> hTPCSigvsP; - std::array, nCharges> hTOFBetavsP; - std::array, nCharges> hTOFSigvsP; - std::array, nCharges> hFilteredTOFSigvsP; - std::array, nCharges> hTRDPattvsP; - std::array, nCharges> hTRDSigvsP; + std::array, NCharges> hTPCSigvsP; + std::array, NCharges> hTOFBetavsP; + std::array, NCharges> hTOFSigvsP; + std::array, NCharges> hFilteredTOFSigvsP; + std::array, NCharges> hTRDPattvsP; + std::array, NCharges> hTRDSigvsP; // 1D - std::array, nCharges> hP; - std::array, nCharges> hPt; - std::array, nCharges> hPx; - std::array, nCharges> hPy; - std::array, nCharges> hPz; - std::array, nCharges> hX; - std::array, nCharges> hY; - std::array, nCharges> hZ; - std::array, nCharges> hAlpha; - std::array, nCharges> hTrackType; - std::array, nCharges> hTPCNClsShared; - std::array, nCharges> hDcaXY; - std::array, nCharges> hDcaZ; - std::array, nCharges> hPdgCode; - std::array, nCharges> hIsPrimary; + std::array, NCharges> hP; + std::array, NCharges> hPt; + std::array, NCharges> hPx; + std::array, NCharges> hPy; + std::array, NCharges> hPz; + std::array, NCharges> hX; + std::array, NCharges> hY; + std::array, NCharges> hZ; + std::array, NCharges> hAlpha; + std::array, NCharges> hTrackType; + std::array, NCharges> hTPCNClsShared; + std::array, NCharges> hDcaXY; + std::array, NCharges> hDcaZ; + std::array, NCharges> hPdgCode; + std::array, NCharges> hIsPrimary; HistogramRegistry registry{"registry", {}, OutputObjHandlingPolicy::AnalysisObject}; @@ -94,33 +95,33 @@ struct PidMlProducer { template void initHistSign() { - hTPCSigvsP[prefixInd] = registry.add(Form("%s/hTPCSigvsP", histPrefixes[prefixInd].data()), genTagvsP("TPC Signal"), HistType::kTH2F, {{500, 0., 10.}, {1000, 0., 600.}}); - hTOFBetavsP[prefixInd] = registry.add(Form("%s/hTOFBetavsP", histPrefixes[prefixInd].data()), genTagvsP("TOF beta"), HistType::kTH2F, {{500, 0., 10.}, {6000, -3., 3.}}); - hTOFSigvsP[prefixInd] = registry.add(Form("%s/hTOFSigvsP", histPrefixes[prefixInd].data()), genTagvsP("TOF signal"), HistType::kTH2F, {{500, 0., 10.}, {10000, -5000., 80000.}}); - hFilteredTOFSigvsP[prefixInd] = registry.add(Form("%s/filtered/hTOFSigvsP", histPrefixes[prefixInd].data()), genTagvsP("TOF signal (filtered)"), HistType::kTH2F, {{500, 0., 10.}, {10000, -5000., 80000.}}); - hTRDPattvsP[prefixInd] = registry.add(Form("%s/hTRDPattvsP", histPrefixes[prefixInd].data()), genTagvsP("TRD pattern"), HistType::kTH2F, {{500, 0., 10.}, {110, -10., 100.}}); - hTRDSigvsP[prefixInd] = registry.add(Form("%s/hTRDSigvsP", histPrefixes[prefixInd].data()), genTagvsP("TRD signal"), HistType::kTH2F, {{500, 0., 10.}, {2500, -2., 100.}}); - hP[prefixInd] = registry.add(Form("%s/hP", histPrefixes[prefixInd].data()), "#it{p};#it{p} (GeV/#it{c})", HistType::kTH1F, {{500, 0., 6.}}); - hPt[prefixInd] = registry.add(Form("%s/hPt", histPrefixes[prefixInd].data()), "#it{p}_{t};#it{p}_{t} (GeV/#it{c})", HistType::kTH1F, {{500, 0., 6.}}); - hPx[prefixInd] = registry.add(Form("%s/hPx", histPrefixes[prefixInd].data()), "#it{p}_{x};#it{p}_{x} (GeV/#it{c})", HistType::kTH1F, {{1000, -6., 6.}}); - hPy[prefixInd] = registry.add(Form("%s/hPy", histPrefixes[prefixInd].data()), "#it{p}_{y};#it{p}_{y} (GeV/#it{c})", HistType::kTH1F, {{1000, -6., 6.}}); - hPz[prefixInd] = registry.add(Form("%s/hPz", histPrefixes[prefixInd].data()), "#it{p}_{z};#it{p}_{z} (GeV/#it{c})", HistType::kTH1F, {{1000, -6., 6.}}); - hX[prefixInd] = registry.add(Form("%s/hX", histPrefixes[prefixInd].data()), "#it{x};#it{x}", HistType::kTH1F, {{1000, -2., 2.}}); - hY[prefixInd] = registry.add(Form("%s/hY", histPrefixes[prefixInd].data()), "#it{y};#it{y}", HistType::kTH1F, {{1000, -2., 2.}}); - hZ[prefixInd] = registry.add(Form("%s/hZ", histPrefixes[prefixInd].data()), "#it{z};#it{z}", HistType::kTH1F, {{1000, -10., 10.}}); - hAlpha[prefixInd] = registry.add(Form("%s/hAlpha", histPrefixes[prefixInd].data()), "alpha;alpha", HistType::kTH1F, {{1000, -5., 5.}}); - hTrackType[prefixInd] = registry.add(Form("%s/hTrackType", histPrefixes[prefixInd].data()), "Track Type;Track Type", HistType::kTH1F, {{300, 0., 300.}}); - hTPCNClsShared[prefixInd] = registry.add(Form("%s/hTPCNClsShared", histPrefixes[prefixInd].data()), "hTPCNClsShared;hTPCNClsShared", HistType::kTH1F, {{100, 0., 100.}}); - hDcaXY[prefixInd] = registry.add(Form("%s/hDcaXY", histPrefixes[prefixInd].data()), "#it{DcaXY};#it{DcaXY}", HistType::kTH1F, {{1000, -1., 1.}}); - hDcaZ[prefixInd] = registry.add(Form("%s/hDcaZ", histPrefixes[prefixInd].data()), "#it{DcaZ};#it{DcaZ}", HistType::kTH1F, {{1000, -1., 1.}}); + hTPCSigvsP[prefixInd] = registry.add(Form("%s/hTPCSigvsP", HistPrefixes[prefixInd].data()), genTagvsP("TPC Signal"), HistType::kTH2F, {{500, 0., 10.}, {1000, 0., 600.}}); + hTOFBetavsP[prefixInd] = registry.add(Form("%s/hTOFBetavsP", HistPrefixes[prefixInd].data()), genTagvsP("TOF beta"), HistType::kTH2F, {{500, 0., 10.}, {6000, -3., 3.}}); + hTOFSigvsP[prefixInd] = registry.add(Form("%s/hTOFSigvsP", HistPrefixes[prefixInd].data()), genTagvsP("TOF signal"), HistType::kTH2F, {{500, 0., 10.}, {10000, -5000., 80000.}}); + hFilteredTOFSigvsP[prefixInd] = registry.add(Form("%s/filtered/hTOFSigvsP", HistPrefixes[prefixInd].data()), genTagvsP("TOF signal (filtered)"), HistType::kTH2F, {{500, 0., 10.}, {10000, -5000., 80000.}}); + hTRDPattvsP[prefixInd] = registry.add(Form("%s/hTRDPattvsP", HistPrefixes[prefixInd].data()), genTagvsP("TRD pattern"), HistType::kTH2F, {{500, 0., 10.}, {110, -10., 100.}}); + hTRDSigvsP[prefixInd] = registry.add(Form("%s/hTRDSigvsP", HistPrefixes[prefixInd].data()), genTagvsP("TRD signal"), HistType::kTH2F, {{500, 0., 10.}, {2500, -2., 100.}}); + hP[prefixInd] = registry.add(Form("%s/hP", HistPrefixes[prefixInd].data()), "#it{p};#it{p} (GeV/#it{c})", HistType::kTH1F, {{500, 0., 6.}}); + hPt[prefixInd] = registry.add(Form("%s/hPt", HistPrefixes[prefixInd].data()), "#it{p}_{t};#it{p}_{t} (GeV/#it{c})", HistType::kTH1F, {{500, 0., 6.}}); + hPx[prefixInd] = registry.add(Form("%s/hPx", HistPrefixes[prefixInd].data()), "#it{p}_{x};#it{p}_{x} (GeV/#it{c})", HistType::kTH1F, {{1000, -6., 6.}}); + hPy[prefixInd] = registry.add(Form("%s/hPy", HistPrefixes[prefixInd].data()), "#it{p}_{y};#it{p}_{y} (GeV/#it{c})", HistType::kTH1F, {{1000, -6., 6.}}); + hPz[prefixInd] = registry.add(Form("%s/hPz", HistPrefixes[prefixInd].data()), "#it{p}_{z};#it{p}_{z} (GeV/#it{c})", HistType::kTH1F, {{1000, -6., 6.}}); + hX[prefixInd] = registry.add(Form("%s/hX", HistPrefixes[prefixInd].data()), "#it{x};#it{x}", HistType::kTH1F, {{1000, -2., 2.}}); + hY[prefixInd] = registry.add(Form("%s/hY", HistPrefixes[prefixInd].data()), "#it{y};#it{y}", HistType::kTH1F, {{1000, -2., 2.}}); + hZ[prefixInd] = registry.add(Form("%s/hZ", HistPrefixes[prefixInd].data()), "#it{z};#it{z}", HistType::kTH1F, {{1000, -10., 10.}}); + hAlpha[prefixInd] = registry.add(Form("%s/hAlpha", HistPrefixes[prefixInd].data()), "alpha;alpha", HistType::kTH1F, {{1000, -5., 5.}}); + hTrackType[prefixInd] = registry.add(Form("%s/hTrackType", HistPrefixes[prefixInd].data()), "Track Type;Track Type", HistType::kTH1F, {{300, 0., 300.}}); + hTPCNClsShared[prefixInd] = registry.add(Form("%s/hTPCNClsShared", HistPrefixes[prefixInd].data()), "hTPCNClsShared;hTPCNClsShared", HistType::kTH1F, {{100, 0., 100.}}); + hDcaXY[prefixInd] = registry.add(Form("%s/hDcaXY", HistPrefixes[prefixInd].data()), "#it{DcaXY};#it{DcaXY}", HistType::kTH1F, {{1000, -1., 1.}}); + hDcaZ[prefixInd] = registry.add(Form("%s/hDcaZ", HistPrefixes[prefixInd].data()), "#it{DcaZ};#it{DcaZ}", HistType::kTH1F, {{1000, -1., 1.}}); } template void initHistSignMC() { initHistSign(); - hPdgCode[prefixInd] = registry.add(Form("%s/hPdgCode", histPrefixes[prefixInd].data()), "#it{PdgCode};#it{PdgCode}", HistType::kTH1F, {{2500, 0., 2500.}}); - hIsPrimary[prefixInd] = registry.add(Form("%s/hIsPrimary", histPrefixes[prefixInd].data()), "#it{IsPrimary};#it{IsPrimary}", HistType::kTH1F, {{4, -0.5, 1.5}}); + hPdgCode[prefixInd] = registry.add(Form("%s/hPdgCode", HistPrefixes[prefixInd].data()), "#it{PdgCode};#it{PdgCode}", HistType::kTH1F, {{2500, 0., 2500.}}); + hIsPrimary[prefixInd] = registry.add(Form("%s/hIsPrimary", HistPrefixes[prefixInd].data()), "#it{IsPrimary};#it{IsPrimary}", HistType::kTH1F, {{4, -0.5, 1.5}}); } template @@ -235,8 +236,7 @@ struct PidMlProducer { void processDataAll(MyCollision const& collision, BigTracksData const& tracks) { for (const auto& track : tracks) { - pidTracksTableData(collision.centRun2V0M(), - collision.multFV0A(), collision.multFV0C(), collision.multFV0M(), + pidTracksTableData(collision.multFV0A(), collision.multFV0C(), collision.multFV0M(), collision.multFT0A(), collision.multFT0C(), collision.multFT0M(), collision.multZNA(), collision.multZNC(), collision.multTracklets(), collision.multTPC(), @@ -301,8 +301,7 @@ struct PidMlProducer { const auto mcParticle = track.mcParticle_as(); uint8_t isPrimary = static_cast(mcParticle.isPhysicalPrimary()); uint32_t pdgCode = mcParticle.pdgCode(); - pidTracksTableMC(collision.centRun2V0M(), - collision.multFV0A(), collision.multFV0C(), collision.multFV0M(), + pidTracksTableMC(collision.multFV0A(), collision.multFV0C(), collision.multFV0M(), collision.multFT0A(), collision.multFT0C(), collision.multFT0M(), collision.multZNA(), collision.multZNC(), collision.multTracklets(), collision.multTPC(), diff --git a/Tools/PIDML/pidOnnxInterface.h b/Tools/PIDML/pidOnnxInterface.h index 03e7bc19146..e97635468ee 100644 --- a/Tools/PIDML/pidOnnxInterface.h +++ b/Tools/PIDML/pidOnnxInterface.h @@ -9,7 +9,7 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -/// \file pidONNXInterface.h +/// \file pidOnnxInterface.h /// \brief A class that wraps PID ML ONNX model. See README.md for more detailed instructions. /// /// \author Maja Kabus @@ -27,15 +27,15 @@ namespace pidml_pt_cuts { -static constexpr int nPids = 6; -static constexpr int nCutVars = kNDetectors; -constexpr int pids[nPids] = {211, 321, 2212, -211, -321, -2212}; -auto pids_v = std::vector{pids, pids + nPids}; -constexpr double certainties[nPids] = {0.5, 0.5, 0.5, 0.5, 0.5, 0.5}; -auto certainties_v = std::vector{certainties, certainties + nPids}; +static constexpr int NPids = 6; +static constexpr int NCutVars = kNDetectors; +constexpr int Pids[NPids] = {211, 321, 2212, -211, -321, -2212}; +auto pidsV = std::vector{Pids, Pids + NPids}; +constexpr double Certainties[NPids] = {0.5, 0.5, 0.5, 0.5, 0.5, 0.5}; +auto certaintiesV = std::vector{Certainties, Certainties + NPids}; // default values for the cuts -constexpr double cuts[nPids][nCutVars] = {{0.0, 0.5, 0.8}, {0.0, 0.5, 0.8}, {0.0, 0.5, 0.8}, {0.0, 0.5, 0.8}, {0.0, 0.5, 0.8}, {0.0, 0.5, 0.8}}; +constexpr double Cuts[NPids][NCutVars] = {{0.0, 0.5, 0.8}, {0.0, 0.5, 0.8}, {0.0, 0.5, 0.8}, {0.0, 0.5, 0.8}, {0.0, 0.5, 0.8}, {0.0, 0.5, 0.8}}; // row labels static const std::vector pidLabels = { "211", "321", "2212", "0211", "0321", "02212"}; @@ -45,16 +45,17 @@ static const std::vector cutVarLabels = { } // namespace pidml_pt_cuts +template struct PidONNXInterface { - PidONNXInterface(std::string& localPath, std::string& ccdbPath, bool useCCDB, o2::ccdb::CcdbApi& ccdbApi, uint64_t timestamp, std::vector const& pids, o2::framework::LabeledArray const& pLimits, std::vector const& minCertainties, bool autoMode) : mNPids{pids.size()}, mPLimits{pLimits} + PidONNXInterface(std::string& localPath, std::string& ccdbPath, bool useCCDB, o2::ccdb::CcdbApi& ccdbApi, uint64_t timestamp, std::vector const& Pids, o2::framework::LabeledArray const& pLimits, std::vector const& minCertainties, bool autoMode) : mNPids{Pids.size()}, mPLimits{pLimits} { - if (pids.size() == 0) { + if (Pids.size() == 0) { LOG(fatal) << "PID ML Interface needs at least 1 output pid to predict"; } std::set tmp; - for (auto& pid : pids) { + for (const auto& pid : Pids) { if (!tmp.insert(pid).second) { - LOG(fatal) << "PID ML Interface: output pids cannot repeat!"; + LOG(fatal) << "PID ML Interface: output Pids cannot repeat!"; } } @@ -63,12 +64,12 @@ struct PidONNXInterface { fillDefaultConfiguration(minCertaintiesFilled); } else { if (minCertainties.size() != mNPids) { - LOG(fatal) << "PID ML Interface: min certainties vector must be of the same size as the output pids vector"; + LOG(fatal) << "PID ML Interface: min Certainties vector must be of the same size as the output Pids vector"; } minCertaintiesFilled = minCertainties; } for (std::size_t i = 0; i < mNPids; i++) { - mModels.emplace_back(localPath, ccdbPath, useCCDB, ccdbApi, timestamp, pids[i], minCertaintiesFilled[i], mPLimits[i]); + mModels.emplace_back(localPath, ccdbPath, useCCDB, ccdbApi, timestamp, Pids[i], minCertaintiesFilled[i], mPLimits[i]); } } PidONNXInterface() = default; @@ -78,8 +79,7 @@ struct PidONNXInterface { PidONNXInterface& operator=(const PidONNXInterface&) = delete; ~PidONNXInterface() = default; - template - float applyModel(const T& track, int pid) + float applyModel(const T::iterator& track, int pid) { for (std::size_t i = 0; i < mNPids; i++) { if (mModels[i].mPid == pid) { @@ -90,8 +90,7 @@ struct PidONNXInterface { return -1.0f; } - template - bool applyModelBoolean(const T& track, int pid) + bool applyModelBoolean(const T::iterator& track, int pid) { for (std::size_t i = 0; i < mNPids; i++) { if (mModels[i].mPid == pid) { @@ -106,11 +105,11 @@ struct PidONNXInterface { void fillDefaultConfiguration(std::vector& minCertainties) { // FIXME: A more sophisticated strategy should be based on pid values as well - mPLimits = o2::framework::LabeledArray{pidml_pt_cuts::cuts[0], pidml_pt_cuts::nPids, pidml_pt_cuts::nCutVars, pidml_pt_cuts::pidLabels, pidml_pt_cuts::cutVarLabels}; + mPLimits = o2::framework::LabeledArray{pidml_pt_cuts::Cuts[0], pidml_pt_cuts::NPids, pidml_pt_cuts::NCutVars, pidml_pt_cuts::pidLabels, pidml_pt_cuts::cutVarLabels}; minCertainties = std::vector(mNPids, 0.5); } - std::vector mModels; + std::vector> mModels; std::size_t mNPids; o2::framework::LabeledArray mPLimits; }; diff --git a/Tools/PIDML/pidOnnxModel.h b/Tools/PIDML/pidOnnxModel.h index 207bc18cd8e..1c48a84f2b8 100644 --- a/Tools/PIDML/pidOnnxModel.h +++ b/Tools/PIDML/pidOnnxModel.h @@ -9,7 +9,7 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -/// \file pidONNXModel.h +/// \file pidOnnxModel.h /// \brief A class that wraps PID ML ONNX model. See README.md for more detailed instructions. /// /// \author Maja Kabus @@ -17,12 +17,17 @@ #ifndef TOOLS_PIDML_PIDONNXMODEL_H_ #define TOOLS_PIDML_PIDONNXMODEL_H_ +#include #include +#include #include +#include +#include #include +#include #include -#include #include +#include #include #include #include @@ -37,8 +42,6 @@ #include "CCDB/CcdbApi.h" #include "Tools/PIDML/pidUtils.h" -using namespace pidml::pidutils; - enum PidMLDetector { kTPCOnly = 0, kTPCTOF, @@ -46,11 +49,13 @@ enum PidMLDetector { kNDetectors ///< number of available detectors configurations }; +using MomentumLimitsMatrix = std::array; + namespace pidml_pt_cuts { // TODO: for now first limit wouldn't be used, // network needs TPC, so we can either do not cut it by p or return 0.0f as prediction -constexpr std::array defaultModelPLimits({0.0, 0.5, 0.8}); +constexpr MomentumLimitsMatrix defaultModelPLimits({0.0, 0.5, 0.8}); } // namespace pidml_pt_cuts // TODO: Copied from cefpTask, shall we put it in some common utils code? @@ -73,6 +78,7 @@ bool readJsonFile(const std::string& config, rapidjson::Document& d) } } // namespace +template struct PidONNXModel { public: PidONNXModel(std::string& localPath, std::string& ccdbPath, bool useCCDB, o2::ccdb::CcdbApi& ccdbApi, uint64_t timestamp, @@ -135,14 +141,12 @@ struct PidONNXModel { PidONNXModel& operator=(const PidONNXModel&) = delete; ~PidONNXModel() = default; - template - float applyModel(const T& track) + float applyModel(const typename T::iterator& track) { return getModelOutput(track); } - template - bool applyModelBoolean(const T& track) + bool applyModelBoolean(const typename T::iterator& track) { return getModelOutput(track) >= mMinCertainty; } @@ -202,85 +206,84 @@ struct PidONNXModel { LOG(info) << "Using configuration files: " << localTrainColumnsPath << ", " << localScalingParamsPath; if (readJsonFile(localTrainColumnsPath, trainColumnsDoc)) { - for (auto& param : trainColumnsDoc["columns_for_training"].GetArray()) { - mTrainColumns.emplace_back(param.GetString()); + for (const auto& param : trainColumnsDoc["columns_for_training"].GetArray()) { + auto columnLabel = param.GetString(); + mTrainColumns.emplace_back(columnLabel); + mGetters.emplace_back(o2::soa::row_helpers::getColumnGetterByLabel(columnLabel)); } } if (readJsonFile(localScalingParamsPath, scalingParamsDoc)) { - for (auto& param : scalingParamsDoc["data"].GetArray()) { + for (const auto& param : scalingParamsDoc["data"].GetArray()) { mScalingParams[param[0].GetString()] = std::make_pair(param[1].GetFloat(), param[2].GetFloat()); } } } - template - std::vector createInputsSingle(const T& track) + static float scale(float value, const std::pair& scalingParams) { - // TODO: Hardcoded for now. Planning to implement RowView extension to get runtime access to selected columns - // sign is short, trackType and tpcNClsShared uint8_t + return (value - scalingParams.first) / scalingParams.second; + } - float scaledTPCSignal = (track.tpcSignal() - mScalingParams.at("fTPCSignal").first) / mScalingParams.at("fTPCSignal").second; + std::vector getValues(const typename T::iterator& track) + { + std::vector output; + output.reserve(mTrainColumns.size()); - std::vector inputValues{scaledTPCSignal}; + bool useTOF = !pidml::pidutils::tofMissing(track) && pidml::pidutils::inPLimit(track, mPLimits[kTPCTOF]); + bool useTRD = !pidml::pidutils::trdMissing(track) && pidml::pidutils::inPLimit(track, mPLimits[kTPCTOFTRD]); - // When TRD Signal shouldn't be used we pass quiet_NaNs to the network - if (!inPLimit(track, mPLimits[kTPCTOFTRD]) || trdMissing(track)) { - inputValues.push_back(std::numeric_limits::quiet_NaN()); - inputValues.push_back(std::numeric_limits::quiet_NaN()); - } else { - float scaledTRDSignal = (track.trdSignal() - mScalingParams.at("fTRDSignal").first) / mScalingParams.at("fTRDSignal").second; - inputValues.push_back(scaledTRDSignal); - inputValues.push_back(track.trdPattern()); - } + for (uint32_t i = 0; i < mTrainColumns.size(); ++i) { + auto& columnLabel = mTrainColumns[i]; - // When TOF Signal shouldn't be used we pass quiet_NaNs to the network - if (!inPLimit(track, mPLimits[kTPCTOF]) || tofMissing(track)) { - inputValues.push_back(std::numeric_limits::quiet_NaN()); - inputValues.push_back(std::numeric_limits::quiet_NaN()); - } else { - float scaledTOFSignal = (track.tofSignal() - mScalingParams.at("fTOFSignal").first) / mScalingParams.at("fTOFSignal").second; - float scaledBeta = (track.beta() - mScalingParams.at("fBeta").first) / mScalingParams.at("fBeta").second; - inputValues.push_back(scaledTOFSignal); - inputValues.push_back(scaledBeta); - } + if ( + ((columnLabel == "fTRDSignal" || columnLabel == "fTRDPattern") && !useTRD) || + ((columnLabel == "fTOFSignal" || columnLabel == "fBeta") && !useTOF)) { + output.push_back(std::numeric_limits::quiet_NaN()); + continue; + } + + std::optional> scalingParams = std::nullopt; + + auto scalingParamsEntry = mScalingParams.find(columnLabel); + if (scalingParamsEntry != mScalingParams.end()) { + scalingParams = scalingParamsEntry->second; + } + + float value = mGetters[i](track); - float scaledX = (track.x() - mScalingParams.at("fX").first) / mScalingParams.at("fX").second; - float scaledY = (track.y() - mScalingParams.at("fY").first) / mScalingParams.at("fY").second; - float scaledZ = (track.z() - mScalingParams.at("fZ").first) / mScalingParams.at("fZ").second; - float scaledAlpha = (track.alpha() - mScalingParams.at("fAlpha").first) / mScalingParams.at("fAlpha").second; - float scaledTPCNClsShared = (static_cast(track.tpcNClsShared()) - mScalingParams.at("fTPCNClsShared").first) / mScalingParams.at("fTPCNClsShared").second; - float scaledDcaXY = (track.dcaXY() - mScalingParams.at("fDcaXY").first) / mScalingParams.at("fDcaXY").second; - float scaledDcaZ = (track.dcaZ() - mScalingParams.at("fDcaZ").first) / mScalingParams.at("fDcaZ").second; + if (scalingParams) { + value = scale(value, scalingParams.value()); + } - inputValues.insert(inputValues.end(), {track.p(), track.pt(), track.px(), track.py(), track.pz(), static_cast(track.sign()), scaledX, scaledY, scaledZ, scaledAlpha, static_cast(track.trackType()), scaledTPCNClsShared, scaledDcaXY, scaledDcaZ}); + output.push_back(value); + } - return inputValues; + return output; } - template - float getModelOutput(const T& track) + float getModelOutput(const typename T::iterator& track) { // First rank of the expected model input is -1 which means that it is dynamic axis. // Axis is exported as dynamic to make it possible to run model inference with the batch of // tracks at once in the future (batch would need to have the same amount of quiet_NaNs in each row). // For now we hardcode 1. - static constexpr int64_t batch_size = 1; - auto input_shape = mInputShapes[0]; - input_shape[0] = batch_size; + static constexpr int64_t BatchSize = 1; + auto inputShape = mInputShapes[0]; + inputShape[0] = BatchSize; - std::vector inputTensorValues = createInputsSingle(track); + std::vector inputTensorValues = getValues(track); std::vector inputTensors; #if __has_include() - inputTensors.emplace_back(Ort::Experimental::Value::CreateTensor(inputTensorValues.data(), inputTensorValues.size(), input_shape)); + inputTensors.emplace_back(Ort::Experimental::Value::CreateTensor(inputTensorValues.data(), inputTensorValues.size(), inputShape)); #else - Ort::MemoryInfo mem_info = Ort::MemoryInfo::CreateCpu(OrtAllocatorType::OrtArenaAllocator, OrtMemType::OrtMemTypeDefault); - inputTensors.emplace_back(Ort::Value::CreateTensor(mem_info, inputTensorValues.data(), inputTensorValues.size(), input_shape.data(), input_shape.size())); + Ort::MemoryInfo memInfo = Ort::MemoryInfo::CreateCpu(OrtAllocatorType::OrtArenaAllocator, OrtMemType::OrtMemTypeDefault); + inputTensors.emplace_back(Ort::Value::CreateTensor(memInfo, inputTensorValues.data(), inputTensorValues.size(), inputShape.data(), inputShape.size())); #endif // Double-check the dimensions of the input tensor assert(inputTensors[0].IsTensor() && - inputTensors[0].GetTensorTypeAndShapeInfo().GetShape() == input_shape); + inputTensors[0].GetTensorTypeAndShapeInfo().GetShape() == inputShape); LOG(debug) << "input tensor shape: " << printShape(inputTensors[0].GetTensorTypeAndShapeInfo().GetShape()); try { @@ -303,8 +306,8 @@ struct PidONNXModel { assert(outputTensors.size() == mOutputNames.size() && outputTensors[0].IsTensor()); LOG(debug) << "output tensor shape: " << printShape(outputTensors[0].GetTensorTypeAndShapeInfo().GetShape()); - const float* output_value = outputTensors[0].GetTensorData(); - float certainty = *output_value; + const float* outputValue = outputTensors[0].GetTensorData(); + float certainty = *outputValue; return certainty; } catch (const Ort::Exception& exception) { LOG(error) << "Error running model inference: " << exception.what(); @@ -323,6 +326,7 @@ struct PidONNXModel { } std::vector mTrainColumns; + std::vector mGetters; std::map> mScalingParams; std::shared_ptr mEnv = nullptr; diff --git a/Tools/PIDML/qaPid.cxx b/Tools/PIDML/qaPid.cxx index 4efbbbc077a..3480ad7c366 100644 --- a/Tools/PIDML/qaPid.cxx +++ b/Tools/PIDML/qaPid.cxx @@ -9,6 +9,7 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. /// +/// \file qaPid.cxx /// \brief Task to check PID efficiency /// \author Łukasz Sawicki /// \since @@ -20,15 +21,16 @@ #include "Common/DataModel/TrackSelectionTables.h" #include "Common/DataModel/PIDResponse.h" #include +#include using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; -struct EvaluatePid { +struct QaPid { double combinedSignal(float val1, float val2) { - return sqrt(pow(val1, 2) + pow(val2, 2)); + return std::sqrt(std::pow(val1, 2) + std::pow(val2, 2)); } int indexOfSmallestElement(const float array[], int size) @@ -41,113 +43,119 @@ struct EvaluatePid { return index; } + enum ContaminationIn { + kPion, + kProton, + kKaon + }; + void fillContaminationRegistry(int i, int pdgCode, double pt) { - if (i == 0) { - if (pdgCode == 211) { + if (i == ContaminationIn::kPion) { + if (pdgCode == PDG_t::kPiPlus) { histReg.fill(HIST("contamination/211in211"), pt); } - if (pdgCode == -211) { + if (pdgCode == PDG_t::kPiMinus) { histReg.fill(HIST("contamination/0211in211"), pt); } - if (pdgCode == 2212) { + if (pdgCode == PDG_t::kProton) { histReg.fill(HIST("contamination/2212in211"), pt); } - if (pdgCode == -2212) { + if (pdgCode == PDG_t::kProtonBar) { histReg.fill(HIST("contamination/02212in211"), pt); } - if (pdgCode == 321) { + if (pdgCode == PDG_t::kKPlus) { histReg.fill(HIST("contamination/321in211"), pt); } - if (pdgCode == -321) { + if (pdgCode == PDG_t::kKMinus) { histReg.fill(HIST("contamination/0321in211"), pt); } - if (pdgCode == 11) { + if (pdgCode == PDG_t::kElectron) { histReg.fill(HIST("contamination/11in211"), pt); } - if (pdgCode == -11) { + if (pdgCode == PDG_t::kPositron) { histReg.fill(HIST("contamination/011in211"), pt); } - if (pdgCode == 13) { + if (pdgCode == PDG_t::kMuonMinus) { histReg.fill(HIST("contamination/13in211"), pt); } - if (pdgCode == -13) { + if (pdgCode == PDG_t::kMuonPlus) { histReg.fill(HIST("contamination/013in211"), pt); } - } else if (i == 1) { - if (pdgCode == 211) { + } else if (i == ContaminationIn::kProton) { + if (pdgCode == PDG_t::kPiPlus) { histReg.fill(HIST("contamination/211in2212"), pt); } - if (pdgCode == -211) { + if (pdgCode == PDG_t::kPiMinus) { histReg.fill(HIST("contamination/0211in2212"), pt); } - if (pdgCode == 2212) { + if (pdgCode == PDG_t::kProton) { histReg.fill(HIST("contamination/2212in2212"), pt); } - if (pdgCode == -2212) { + if (pdgCode == PDG_t::kProtonBar) { histReg.fill(HIST("contamination/02212in2212"), pt); } - if (pdgCode == 321) { + if (pdgCode == PDG_t::kKPlus) { histReg.fill(HIST("contamination/321in2212"), pt); } - if (pdgCode == -321) { + if (pdgCode == PDG_t::kKMinus) { histReg.fill(HIST("contamination/0321in2212"), pt); } - if (pdgCode == 11) { + if (pdgCode == PDG_t::kElectron) { histReg.fill(HIST("contamination/11in2212"), pt); } - if (pdgCode == -11) { + if (pdgCode == PDG_t::kPositron) { histReg.fill(HIST("contamination/011in2212"), pt); } - if (pdgCode == 13) { + if (pdgCode == PDG_t::kMuonMinus) { histReg.fill(HIST("contamination/13in2212"), pt); } - if (pdgCode == -13) { + if (pdgCode == PDG_t::kMuonPlus) { histReg.fill(HIST("contamination/013in2212"), pt); } - } else if (i == 2) { - if (pdgCode == 211) { + } else if (i == ContaminationIn::kKaon) { + if (pdgCode == PDG_t::kPiPlus) { histReg.fill(HIST("contamination/211in321"), pt); } - if (pdgCode == -211) { + if (pdgCode == PDG_t::kPiMinus) { histReg.fill(HIST("contamination/0211in321"), pt); } - if (pdgCode == 2212) { + if (pdgCode == PDG_t::kProton) { histReg.fill(HIST("contamination/2212in321"), pt); } - if (pdgCode == -2212) { + if (pdgCode == PDG_t::kProtonBar) { histReg.fill(HIST("contamination/02212in321"), pt); } - if (pdgCode == 321) { + if (pdgCode == PDG_t::kKPlus) { histReg.fill(HIST("contamination/321in321"), pt); } - if (pdgCode == -321) { + if (pdgCode == PDG_t::kKMinus) { histReg.fill(HIST("contamination/0321in321"), pt); } - if (pdgCode == 11) { + if (pdgCode == PDG_t::kElectron) { histReg.fill(HIST("contamination/11in321"), pt); } - if (pdgCode == -11) { + if (pdgCode == PDG_t::kPositron) { histReg.fill(HIST("contamination/011in321"), pt); } - if (pdgCode == 13) { + if (pdgCode == PDG_t::kMuonMinus) { histReg.fill(HIST("contamination/13in321"), pt); } - if (pdgCode == -13) { + if (pdgCode == PDG_t::kMuonPlus) { histReg.fill(HIST("contamination/013in321"), pt); } } @@ -157,13 +165,13 @@ struct EvaluatePid { void fillPidHistos(const T& track, const int pdgCode, bool isPidTrue) { if (isPidTrue) { - histReg.fill(HIST(pidTrueRegistryNames[i]), track.pt()); + histReg.fill(HIST(PidTrueRegistryNames[i]), track.pt()); histReg.fill(HIST(TPCPidTrueRegistryNames[i]), track.p(), track.tpcSignal()); histReg.fill(HIST("TPCSignalPidTrue"), track.p(), track.tpcSignal()); histReg.fill(HIST("TOFSignalPidTrue"), track.p(), track.beta()); histReg.fill(HIST(TOFPidTrueRegistryNames[i]), track.p(), track.beta()); } else { - histReg.fill(HIST(pidFalseRegistryNames[i]), track.pt()); + histReg.fill(HIST(PidFalseRegistryNames[i]), track.pt()); histReg.fill(HIST(TPCPidFalseRegistryNames[i]), track.p(), track.tpcSignal()); histReg.fill(HIST("TPCSignalPidFalse"), track.p(), track.tpcSignal()); histReg.fill(HIST("TOFSignalPidFalse"), track.p(), track.beta()); @@ -177,8 +185,8 @@ struct EvaluatePid { // nb of particles (5 particles - Pi, Pr, Ka, e, mu, and 5 antiparticles) static const int numParticles = 10; - static constexpr std::string_view pidTrueRegistryNames[numParticles] = {"pidTrue/211", "pidTrue/2212", "pidTrue/321", "pidTrue/11", "pidTrue/13", "pidTrue/0211", "pidTrue/02212", "pidTrue/0321", "pidTrue/011", "pidTrue/013"}; - static constexpr std::string_view pidFalseRegistryNames[numParticles] = {"pidFalse/211", "pidFalse/2212", "pidFalse/321", "pidFalse/11", "pidFalse/13", "pidFalse/0211", "pidFalse/02212", "pidFalse/0321", "pidFalse/011", "pidFalse/013"}; + static constexpr std::string_view PidTrueRegistryNames[numParticles] = {"pidTrue/211", "pidTrue/2212", "pidTrue/321", "pidTrue/11", "pidTrue/13", "pidTrue/0211", "pidTrue/02212", "pidTrue/0321", "pidTrue/011", "pidTrue/013"}; + static constexpr std::string_view PidFalseRegistryNames[numParticles] = {"pidFalse/211", "pidFalse/2212", "pidFalse/321", "pidFalse/11", "pidFalse/13", "pidFalse/0211", "pidFalse/02212", "pidFalse/0321", "pidFalse/011", "pidFalse/013"}; static constexpr std::string_view TPCPidTrueRegistryNames[numParticles] = {"TPCPidTrue/211", "TPCPidTrue/2212", "TPCPidTrue/321", "TPCPidTrue/11", "TPCPidTrue/13", "TPCPidTrue/0211", "TPCPidTrue/02212", "TPCPidTrue/0321", "TPCPidTrue/011", "TPCPidTrue/013"}; static constexpr std::string_view TPCPidFalseRegistryNames[numParticles] = {"TPCPidFalse/211", "TPCPidFalse/2212", "TPCPidFalse/321", "TPCPidFalse/11", "TPCPidFalse/13", "TPCPidFalse/0211", "TPCPidFalse/02212", "TPCPidFalse/0321", "TPCPidFalse/011", "TPCPidFalse/013"}; @@ -186,13 +194,13 @@ struct EvaluatePid { static constexpr std::string_view TOFPidTrueRegistryNames[numParticles] = {"TOFPidTrue/211", "TOFPidTrue/2212", "TOFPidTrue/321", "TOFPidTrue/11", "TOFPidTrue/13", "TOFPidTrue/0211", "TOFPidTrue/02212", "TOFPidTrue/0321", "TOFPidTrue/011", "TOFPidTrue/013"}; static constexpr std::string_view TOFPidFalseRegistryNames[numParticles] = {"TOFPidFalse/211", "TOFPidFalse/2212", "TOFPidFalse/321", "TOFPidFalse/11", "TOFPidFalse/13", "TOFPidFalse/0211", "TOFPidFalse/02212", "TOFPidFalse/0321", "TOFPidFalse/011", "TOFPidFalse/013"}; - static constexpr int pdgCodes[numParticles] = {211, 2212, 321, 11, 13, -211, -2212, -321, -11, -13}; - static constexpr int pidToPdg[numParticles] = {11, 13, 211, 321, 2212, -11, -13, -211, -321, -2212}; - // charge with index i corresponds to i-th particle from pdgCodes array - static constexpr int particleCharge[numParticles] = {1, 1, 1, -1, -1, -1, -1, -1, 1, 1}; + static constexpr int PdgCodes[numParticles] = {211, 2212, 321, 11, 13, -211, -2212, -321, -11, -13}; + static constexpr int PidToPdg[numParticles] = {11, 13, 211, 321, 2212, -11, -13, -211, -321, -2212}; + // charge with index i corresponds to i-th particle from PdgCodes array + static constexpr int ParticleCharge[numParticles] = {1, 1, 1, -1, -1, -1, -1, -1, 1, 1}; // momentum value when to switch from pid based only on TPC (below the value) to combination of TPC and TOF (above the value) // i-th momentum corresponds to the i-th particle - static constexpr float pSwitch[numParticles] = {0.5, 0.8, 0.5, 0.5, 0.5, 0.5, 0.8, 0.5, 0.5, 0.5}; + static constexpr float PSwitch[numParticles] = {0.5, 0.8, 0.5, 0.5, 0.5, 0.5, 0.8, 0.5, 0.5, 0.5}; static const int maxP = 5; // nb of bins for TH1 hists @@ -323,26 +331,26 @@ struct EvaluatePid { {"TOFPidFalse/011", "PID false e^{+};p (GeV/c); TOF #beta", {HistType::kTH2F, {{binsNb2D, 0.2, 10}, {110, 0, 1.1}}}}}}; template - void pidSimple(const T& track, const int pdgCode, const float tpcNSigmas[], const float tofNSigmas[], int /*arrLen*/) + void pidSimple(const T& track, const int pdgCode, const float tpcNSigmas[], const float tofNSigmas[]) { /* Simplest possible PID, accept particle when: TPCSignal < X if p < Value or - sqrt(TPCSignal^2 + TOFSignal^2) < X if p > Value + std::sqrt(TPCSignal^2 + TOFSignal^2) < X if p > Value */ const float p = track.p(); - if ((p < pSwitch[i]) & (track.sign() == particleCharge[i])) { - if (abs(tpcNSigmas[i]) < nsigmacut.value) { - if (pdgCode == pdgCodes[i]) { + if ((p < PSwitch[i]) & (track.sign() == ParticleCharge[i])) { + if (std::abs(tpcNSigmas[i]) < nsigmacut.value) { + if (pdgCode == PdgCodes[i]) { fillPidHistos(track, pdgCode, true); } else { fillPidHistos(track, pdgCode, false); } } - } else if ((p >= pSwitch[i]) & (track.sign() == particleCharge[i])) { - if (sqrt(pow(tpcNSigmas[i], 2) + pow(tofNSigmas[i], 2)) < nsigmacut.value) { - if (pdgCode == pdgCodes[i]) { + } else if ((p >= PSwitch[i]) & (track.sign() == ParticleCharge[i])) { + if (std::sqrt(std::pow(tpcNSigmas[i], 2) + std::pow(tofNSigmas[i], 2)) < nsigmacut.value) { + if (pdgCode == PdgCodes[i]) { fillPidHistos(track, pdgCode, true); } else { fillPidHistos(track, pdgCode, false); @@ -351,36 +359,36 @@ struct EvaluatePid { } } - template - void pidMinStrategy(const T& track, const int pdgCode, const float tpcNSigmas[], const float tofNSigmas[], int arrLen) + template + void pidMinStrategy(const T& track, const int pdgCode, const float tpcNSigmas[], const float tofNSigmas[]) { const float p = track.p(); // list of Nsigmas for particles - float particleNSigma[arrLen]; + float particleNSigma[kArrLen]; // calculate Nsigmas for every particle - for (int j = 0; j < arrLen; ++j) { - if (p < pSwitch[j]) { - particleNSigma[j] = abs(tpcNSigmas[j]); - } else if (p >= pSwitch[j]) { + for (int j = 0; j < kArrLen; ++j) { + if (p < PSwitch[j]) { + particleNSigma[j] = std::abs(tpcNSigmas[j]); + } else if (p >= PSwitch[j]) { particleNSigma[j] = combinedSignal(tpcNSigmas[j], tofNSigmas[j]); } } - if ((p < pSwitch[i]) & (track.sign() == particleCharge[i])) { - float tmp_NSigma = abs(tpcNSigmas[i]); - if ((tmp_NSigma < nsigmacut.value) & (indexOfSmallestElement(particleNSigma, arrLen) == i)) { - if (pdgCode == pdgCodes[i]) { + if ((p < PSwitch[i]) & (track.sign() == ParticleCharge[i])) { + float tmpNSigma = std::abs(tpcNSigmas[i]); + if ((tmpNSigma < nsigmacut.value) & (indexOfSmallestElement(particleNSigma, kArrLen) == i)) { + if (pdgCode == PdgCodes[i]) { fillPidHistos(track, pdgCode, true); } else { fillPidHistos(track, pdgCode, false); } } - } else if ((p >= pSwitch[i]) & (track.sign() == particleCharge[i])) { - float tmp_NSigma = combinedSignal(tpcNSigmas[i], tofNSigmas[i]); - if ((tmp_NSigma < nsigmacut.value) & (indexOfSmallestElement(particleNSigma, arrLen) == i)) { - if (pdgCode == pdgCodes[i]) { + } else if ((p >= PSwitch[i]) & (track.sign() == ParticleCharge[i])) { + float tmpNSigma = combinedSignal(tpcNSigmas[i], tofNSigmas[i]); + if ((tmpNSigma < nsigmacut.value) & (indexOfSmallestElement(particleNSigma, kArrLen) == i)) { + if (pdgCode == PdgCodes[i]) { fillPidHistos(track, pdgCode, true); } else { fillPidHistos(track, pdgCode, false); @@ -389,45 +397,45 @@ struct EvaluatePid { } } - template - void pidExclusiveStrategy(const T& track, const int pdgCode, const float tpcNSigmas[], const float tofNSigmas[], int arrLen) + template + void pidExclusiveStrategy(const T& track, const int pdgCode, const float tpcNSigmas[], const float tofNSigmas[]) { const float p = track.p(); // list of Nsigmas for particles - float particleNSigma[arrLen]; + float particleNSigma[kArrLen]; // calculate Nsigmas for every particle - for (int j = 0; j < arrLen; ++j) { - if (p < pSwitch[j]) { - particleNSigma[j] = abs(tpcNSigmas[j]); - } else if (p >= pSwitch[j]) { + for (int j = 0; j < kArrLen; ++j) { + if (p < PSwitch[j]) { + particleNSigma[j] = std::abs(tpcNSigmas[j]); + } else if (p >= PSwitch[j]) { particleNSigma[j] = combinedSignal(tpcNSigmas[j], tofNSigmas[j]); } } // check how many particles satisfy the condition int counts = 0; - for (int j = 0; j < arrLen; ++j) { + for (int j = 0; j < kArrLen; ++j) { if (particleNSigma[j] < nsigmacut.value) { counts++; } } if (counts == 1) { - if ((p < pSwitch[i]) & (track.sign() == particleCharge[i])) { - float tmp_NSigma = abs(tpcNSigmas[i]); - if ((tmp_NSigma < nsigmacut.value) & (indexOfSmallestElement(particleNSigma, arrLen) == i)) { - if (pdgCode == pdgCodes[i]) { + if ((p < PSwitch[i]) & (track.sign() == ParticleCharge[i])) { + float tmpNSigma = std::abs(tpcNSigmas[i]); + if ((tmpNSigma < nsigmacut.value) & (indexOfSmallestElement(particleNSigma, kArrLen) == i)) { + if (pdgCode == PdgCodes[i]) { fillPidHistos(track, pdgCode, true); } else { fillPidHistos(track, pdgCode, false); } } - } else if ((p >= pSwitch[i]) & (track.sign() == particleCharge[i])) { - float tmp_NSigma = combinedSignal(tpcNSigmas[i], tofNSigmas[i]); - if ((tmp_NSigma < nsigmacut.value) & (indexOfSmallestElement(particleNSigma, arrLen) == i)) { - if (pdgCode == pdgCodes[i]) { + } else if ((p >= PSwitch[i]) & (track.sign() == ParticleCharge[i])) { + float tmpNSigma = combinedSignal(tpcNSigmas[i], tofNSigmas[i]); + if ((tmpNSigma < nsigmacut.value) & (indexOfSmallestElement(particleNSigma, kArrLen) == i)) { + if (pdgCode == PdgCodes[i]) { fillPidHistos(track, pdgCode, true); } else { fillPidHistos(track, pdgCode, false); @@ -442,8 +450,8 @@ struct EvaluatePid { { // Convert PID to PDG code // We don't identify particles with PID bigger than Proton, putting dummy code so they will be skipped. - int bayesPdg = track.bayesID() > o2::track::PID::Proton ? 999 : pidToPdg[track.bayesID()]; - if (track.bayesID() <= o2::track::PID::Proton && track.sign() == -1 * particleCharge[track.bayesID()]) { // Check if antiparticle + int bayesPdg = track.bayesID() > o2::track::PID::Proton ? 999 : PidToPdg[track.bayesID()]; + if (track.bayesID() <= o2::track::PID::Proton && track.sign() == -1 * ParticleCharge[track.bayesID()]) { // Check if antiparticle bayesPdg += numParticles / 2; } return bayesPdg; @@ -453,7 +461,7 @@ struct EvaluatePid { void pidBayes(const T& track, const int pdgCode, const int bayesPdg) { if (bayesPdg == pdgCode) { - if (pdgCode == pdgCodes[i]) { + if (pdgCode == PdgCodes[i]) { fillPidHistos(track, pdgCode, true); } else { fillPidHistos(track, pdgCode, false); @@ -465,34 +473,25 @@ struct EvaluatePid { void fillMcHistos(const T& track, const int pdgCode) { // pions - if (pdgCode == 211) { + if (pdgCode == PDG_t::kPiPlus) { histReg.fill(HIST("MC/211"), track.pt()); - } else if (pdgCode == -211) { + } else if (pdgCode == PDG_t::kPiMinus) { histReg.fill(HIST("MC/0211"), track.pt()); - } - // protons - else if (pdgCode == 2212) { + } /* protons */ else if (pdgCode == PDG_t::kProton) { histReg.fill(HIST("MC/2212"), track.pt()); - } else if (pdgCode == -2212) { + } else if (pdgCode == PDG_t::kProtonBar) { histReg.fill(HIST("MC/02212"), track.pt()); - } - // kaons - else if (pdgCode == 321) { + } /* kaons */ else if (pdgCode == PDG_t::kKPlus) { histReg.fill(HIST("MC/321"), track.pt()); - } else if (pdgCode == -321) { + } else if (pdgCode == PDG_t::kKMinus) { histReg.fill(HIST("MC/0321"), track.pt()); - } - // electrons - else if (pdgCode == 11) { + } /* electrons */ else if (pdgCode == PDG_t::kElectron) { histReg.fill(HIST("MC/11"), track.pt()); - ; - } else if (pdgCode == -11) { + } else if (pdgCode == PDG_t::kPositron) { histReg.fill(HIST("MC/011"), track.pt()); - } - // muons - else if (pdgCode == 13) { + } /* muons */ else if (pdgCode == PDG_t::kMuonMinus) { histReg.fill(HIST("MC/13"), track.pt()); - } else if (pdgCode == -13) { + } else if (pdgCode == PDG_t::kMuonPlus) { histReg.fill(HIST("MC/013"), track.pt()); } else { histReg.fill(HIST("MC/else"), track.pt()); @@ -503,11 +502,18 @@ struct EvaluatePid { Configurable strategy{"strategy", 1, "1-PID with Nsigma method, 2-PID with NSigma and condition for minimal Nsigma value for particle, 3-Exclusive condition for NSigma, 4-Bayesian PID"}; Filter trackFilter = requireGlobalTrackInFilter(); - using pidTracks = soa::Filtered>; + using PidTracks = soa::Filtered>; + + enum PIDStrategy { + kSimple = 1, + kMin = 2, + kExclusive = 3, + kBayes = 4 + }; - void process(pidTracks const& tracks, aod::McParticles const& /*mcParticles*/) + void process(PidTracks const& tracks, aod::McParticles const& /*mcParticles*/) { - for (auto& track : tracks) { + for (const auto& track : tracks) { auto particle = track.mcParticle_as(); int pdgCode = particle.pdgCode(); @@ -518,22 +524,22 @@ struct EvaluatePid { const float tpcNSigmas[numParticles] = {track.tpcNSigmaPi(), track.tpcNSigmaPr(), track.tpcNSigmaKa(), track.tpcNSigmaEl(), track.tpcNSigmaMu()}; const float tofNSigmas[numParticles] = {track.tofNSigmaPi(), track.tofNSigmaPr(), track.tofNSigmaKa(), track.tofNSigmaEl(), track.tofNSigmaMu()}; - if (strategy.value == 1) { + if (strategy.value == PIDStrategy::kSimple) { // Simplest strategy. PID with Nsigma method only static_for<0, 9>([&](auto i) { - pidSimple(track, pdgCode, tpcNSigmas, tofNSigmas, 5); + pidSimple(track, pdgCode, tpcNSigmas, tofNSigmas); }); - } else if (strategy.value == 2) { + } else if (strategy.value == PIDStrategy::kMin) { // PID with Nsigma method and additional condition. Selected particle's Nsigma value must be the lowest in order to count particle static_for<0, 9>([&](auto i) { - pidMinStrategy(track, pdgCode, tpcNSigmas, tofNSigmas, 5); + pidMinStrategy(track, pdgCode, tpcNSigmas, tofNSigmas); }); - } else if (strategy.value == 3) { + } else if (strategy.value == PIDStrategy::kExclusive) { // Particle is counted only if one can satisfy the PID NSigma condition static_for<0, 9>([&](auto i) { - pidExclusiveStrategy(track, pdgCode, tpcNSigmas, tofNSigmas, 5); + pidExclusiveStrategy(track, pdgCode, tpcNSigmas, tofNSigmas); }); - } else if (strategy.value == 4) { + } else if (strategy.value == PIDStrategy::kBayes) { int bayesPdg = getPdgFromPid(track); static_for<0, 9>([&](auto i) { pidBayes(track, pdgCode, bayesPdg); @@ -546,6 +552,6 @@ struct EvaluatePid { WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{ - adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc), }; } diff --git a/Tools/PIDML/qaPidML.cxx b/Tools/PIDML/qaPidMl.cxx similarity index 77% rename from Tools/PIDML/qaPidML.cxx rename to Tools/PIDML/qaPidMl.cxx index 54cafc437ab..1fee5330de4 100644 --- a/Tools/PIDML/qaPidML.cxx +++ b/Tools/PIDML/qaPidMl.cxx @@ -9,6 +9,7 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. /// +/// \file qaPidMl.cxx /// \brief Task to check ML PID efficiency. Based on Maja's simpleApplyPidOnnxModel.cxx code /// \author Łukasz Sawicki /// \since @@ -22,13 +23,14 @@ #include "Common/DataModel/TrackSelectionTables.h" #include "Common/DataModel/PIDResponse.h" #include +#include #include "Tools/PIDML/pidOnnxModel.h" using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; -struct QaPidML { +struct QaPidMl { static const int maxP = 5; // nb of bins for TH1 hists static const int binsNb = 100; @@ -36,8 +38,8 @@ struct QaPidML { static const int binsNb2D = 1000; static const int numParticles = 3; - static constexpr std::string_view pidTrueRegistryNames[numParticles] = {"pidTrue/211", "pidTrue/2212", "pidTrue/321"}; - static constexpr std::string_view pidFalseRegistryNames[numParticles] = {"pidFalse/211", "pidFalse/2212", "pidFalse/321"}; + static constexpr std::string_view PidTrueRegistryNames[numParticles] = {"pidTrue/211", "pidTrue/2212", "pidTrue/321"}; + static constexpr std::string_view PidFalseRegistryNames[numParticles] = {"pidFalse/211", "pidFalse/2212", "pidFalse/321"}; static constexpr std::string_view TPCPidTrueRegistryNames[numParticles] = {"TPCPidTrue/211", "TPCPidTrue/2212", "TPCPidTrue/321"}; static constexpr std::string_view TPCPidFalseRegistryNames[numParticles] = {"TPCPidFalse/211", "TPCPidFalse/2212", "TPCPidFalse/321"}; @@ -46,11 +48,11 @@ struct QaPidML { static constexpr std::string_view TOFPidFalseRegistryNames[numParticles] = {"TOFPidFalse/211", "TOFPidFalse/2212", "TOFPidFalse/321"}; // available particles: 211, 2212, 321 - static constexpr int particlesPdgCode[numParticles] = {211, 2212, 321}; + static constexpr int ParticlesPdgCode[numParticles] = {211, 2212, 321}; // values of track momentum when to switch from only TPC signal to combined TPC and TOF signal and to TPC+TOF+TRD // i-th momentum corresponds to the i-th particle - static constexpr double pSwitchValue[numParticles][kNDetectors] = {{0.0, 0.5, 0.8}, {0.0, 0.8, 0.8}, {0.0, 0.5, 0.8}}; + static constexpr double PSwitchValue[numParticles][kNDetectors] = {{0.0, 0.5, 0.8}, {0.0, 0.8, 0.8}, {0.0, 0.5, 0.8}}; HistogramRegistry histReg{ "allHistograms", @@ -130,113 +132,119 @@ struct QaPidML { {"TOFPidFalse/2212", "PID false p;p (GeV/c); TOF #beta", {HistType::kTH2F, {{binsNb2D, 0.2, 10}, {110, 0, 1.1}}}}, {"TOFPidFalse/321", "PID false K^{+};p (GeV/c); TOF #beta", {HistType::kTH2F, {{binsNb2D, 0.2, 10}, {110, 0, 1.1}}}}}}; + enum ContaminationIn { + kPion, + kProton, + kKaon + }; + void fillContaminationRegistry(int i, int pdgCode, double pt) { - if (i == 0) { - if (pdgCode == 211) { + if (i == ContaminationIn::kPion) { + if (pdgCode == PDG_t::kPiPlus) { histReg.fill(HIST("contamination/211in211"), pt); } - if (pdgCode == -211) { + if (pdgCode == PDG_t::kPiMinus) { histReg.fill(HIST("contamination/0211in211"), pt); } - if (pdgCode == 2212) { + if (pdgCode == PDG_t::kProton) { histReg.fill(HIST("contamination/2212in211"), pt); } - if (pdgCode == -2212) { + if (pdgCode == PDG_t::kProtonBar) { histReg.fill(HIST("contamination/02212in211"), pt); } - if (pdgCode == 321) { + if (pdgCode == PDG_t::kKPlus) { histReg.fill(HIST("contamination/321in211"), pt); } - if (pdgCode == -321) { + if (pdgCode == PDG_t::kKMinus) { histReg.fill(HIST("contamination/0321in211"), pt); } - if (pdgCode == 11) { + if (pdgCode == PDG_t::kElectron) { histReg.fill(HIST("contamination/11in211"), pt); } - if (pdgCode == -11) { + if (pdgCode == PDG_t::kPositron) { histReg.fill(HIST("contamination/011in211"), pt); } - if (pdgCode == 13) { + if (pdgCode == PDG_t::kMuonMinus) { histReg.fill(HIST("contamination/13in211"), pt); } - if (pdgCode == -13) { + if (pdgCode == PDG_t::kMuonPlus) { histReg.fill(HIST("contamination/013in211"), pt); } - } else if (i == 1) { - if (pdgCode == 211) { + } else if (i == ContaminationIn::kProton) { + if (pdgCode == PDG_t::kPiPlus) { histReg.fill(HIST("contamination/211in2212"), pt); } - if (pdgCode == -211) { + if (pdgCode == PDG_t::kPiMinus) { histReg.fill(HIST("contamination/0211in2212"), pt); } - if (pdgCode == 2212) { + if (pdgCode == PDG_t::kProton) { histReg.fill(HIST("contamination/2212in2212"), pt); } - if (pdgCode == -2212) { + if (pdgCode == PDG_t::kProtonBar) { histReg.fill(HIST("contamination/02212in2212"), pt); } - if (pdgCode == 321) { + if (pdgCode == PDG_t::kKPlus) { histReg.fill(HIST("contamination/321in2212"), pt); } - if (pdgCode == -321) { + if (pdgCode == PDG_t::kKMinus) { histReg.fill(HIST("contamination/0321in2212"), pt); } - if (pdgCode == 11) { + if (pdgCode == PDG_t::kElectron) { histReg.fill(HIST("contamination/11in2212"), pt); } - if (pdgCode == -11) { + if (pdgCode == PDG_t::kPositron) { histReg.fill(HIST("contamination/011in2212"), pt); } - if (pdgCode == 13) { + if (pdgCode == PDG_t::kMuonMinus) { histReg.fill(HIST("contamination/13in2212"), pt); } - if (pdgCode == -13) { + if (pdgCode == PDG_t::kMuonPlus) { histReg.fill(HIST("contamination/013in2212"), pt); } - } else if (i == 2) { - if (pdgCode == 211) { + } else if (i == ContaminationIn::kKaon) { + if (pdgCode == PDG_t::kPiPlus) { histReg.fill(HIST("contamination/211in321"), pt); } - if (pdgCode == -211) { + if (pdgCode == PDG_t::kPiMinus) { histReg.fill(HIST("contamination/0211in321"), pt); } - if (pdgCode == 2212) { + if (pdgCode == PDG_t::kProton) { histReg.fill(HIST("contamination/2212in321"), pt); } - if (pdgCode == -2212) { + if (pdgCode == PDG_t::kProtonBar) { histReg.fill(HIST("contamination/02212in321"), pt); } - if (pdgCode == 321) { + if (pdgCode == PDG_t::kKPlus) { histReg.fill(HIST("contamination/321in321"), pt); } - if (pdgCode == -321) { + if (pdgCode == PDG_t::kKMinus) { histReg.fill(HIST("contamination/0321in321"), pt); } - if (pdgCode == 11) { + if (pdgCode == PDG_t::kElectron) { histReg.fill(HIST("contamination/11in321"), pt); } - if (pdgCode == -11) { + if (pdgCode == PDG_t::kPositron) { histReg.fill(HIST("contamination/011in321"), pt); } - if (pdgCode == 13) { + if (pdgCode == PDG_t::kMuonMinus) { histReg.fill(HIST("contamination/13in321"), pt); } - if (pdgCode == -13) { + if (pdgCode == PDG_t::kMuonPlus) { histReg.fill(HIST("contamination/013in321"), pt); } } @@ -245,34 +253,34 @@ struct QaPidML { template void fillMcHistos(const T& track, const int pdgCode) { - if (pdgCode == 211) { + if (pdgCode == PDG_t::kPiPlus) { // pions histReg.fill(HIST("MC/211"), track.pt()); - } else if (pdgCode == -211) { + } else if (pdgCode == PDG_t::kPiMinus) { // antipions histReg.fill(HIST("MC/0211"), track.pt()); - } else if (pdgCode == 2212) { + } else if (pdgCode == PDG_t::kProton) { // protons histReg.fill(HIST("MC/2212"), track.pt()); - } else if (pdgCode == -2212) { + } else if (pdgCode == PDG_t::kProtonBar) { // antiprotons histReg.fill(HIST("MC/02212"), track.pt()); - } else if (pdgCode == 321) { + } else if (pdgCode == PDG_t::kKPlus) { // kaons histReg.fill(HIST("MC/321"), track.pt()); - } else if (pdgCode == -321) { + } else if (pdgCode == PDG_t::kKMinus) { // antikaons histReg.fill(HIST("MC/0321"), track.pt()); - } else if (pdgCode == 11) { + } else if (pdgCode == PDG_t::kElectron) { // electrons histReg.fill(HIST("MC/11"), track.pt()); - } else if (pdgCode == -11) { + } else if (pdgCode == PDG_t::kPositron) { // positrons histReg.fill(HIST("MC/011"), track.pt()); - } else if (pdgCode == 13) { + } else if (pdgCode == PDG_t::kMuonMinus) { // muons histReg.fill(HIST("MC/13"), track.pt()); - } else if (pdgCode == -13) { + } else if (pdgCode == PDG_t::kMuonPlus) { // antimuons histReg.fill(HIST("MC/013"), track.pt()); } else { @@ -284,13 +292,13 @@ struct QaPidML { void fillPidHistos(const T& track, const int pdgCode, bool isPidTrue) { if (isPidTrue) { - histReg.fill(HIST(pidTrueRegistryNames[i]), track.pt()); + histReg.fill(HIST(PidTrueRegistryNames[i]), track.pt()); histReg.fill(HIST(TPCPidTrueRegistryNames[i]), track.p(), track.tpcSignal()); histReg.fill(HIST("TPCSignalPidTrue"), track.p(), track.tpcSignal()); histReg.fill(HIST("TOFSignalPidTrue"), track.p(), track.beta()); histReg.fill(HIST(TOFPidTrueRegistryNames[i]), track.p(), track.beta()); } else { - histReg.fill(HIST(pidFalseRegistryNames[i]), track.pt()); + histReg.fill(HIST(PidFalseRegistryNames[i]), track.pt()); histReg.fill(HIST(TPCPidFalseRegistryNames[i]), track.p(), track.tpcSignal()); histReg.fill(HIST("TPCSignalPidFalse"), track.p(), track.tpcSignal()); histReg.fill(HIST("TOFSignalPidFalse"), track.p(), track.beta()); @@ -301,26 +309,28 @@ struct QaPidML { } } + static constexpr float kCertaintyThreshold = 0.5f; + int getParticlePdg(float pidCertainties[]) { // index of the biggest value in an array int index = 0; // index of the second biggest value in an array - int smaller_index = 0; + int smallerIndex = 0; for (int j = 1; j < numParticles; j++) { if (pidCertainties[j] > pidCertainties[index]) { // assign new indexes - smaller_index = index; + smallerIndex = index; index = j; } } // return 0 if certainty with index 'index' is below 0.5 or two indexes have the same value, else map index to particle pdgCode - if ((pidCertainties[index] < 0.5f) | ((pidCertainties[index] == pidCertainties[smaller_index]) & (smaller_index != 0))) { + if ((pidCertainties[index] < kCertaintyThreshold) | ((pidCertainties[index] == pidCertainties[smallerIndex]) & (smallerIndex != 0))) { return 0; } else { - return particlesPdgCode[index]; + return ParticlesPdgCode[index]; } } @@ -333,8 +343,8 @@ struct QaPidML { pidCertainties[2] = model321.applyModel(track); int pid = getParticlePdg(pidCertainties); // condition for sign: we want to work only with pi, p and K, without antiparticles - if (pid == particlesPdgCode[i] && track.sign() == 1) { - if (pdgCodeMC == particlesPdgCode[i]) { + if (pid == ParticlesPdgCode[i] && track.sign() == 1) { + if (pdgCodeMC == ParticlesPdgCode[i]) { fillPidHistos(track, pdgCodeMC, true); } else { fillPidHistos(track, pdgCodeMC, false); @@ -342,42 +352,43 @@ struct QaPidML { } } - // one model for one particle - PidONNXModel model211; - PidONNXModel model2212; - PidONNXModel model321; - - Configurable cfgPathCCDB{"ccdb-path", "Users/m/mkabus/PIDML", "base path to the CCDB directory with ONNX models"}; - Configurable cfgCCDBURL{"ccdb-url", "http://alice-ccdb.cern.ch", "URL of the CCDB repository"}; - Configurable cfgUseCCDB{"useCCDB", true, "Whether to autofetch ML model from CCDB. If false, local file will be used."}; - Configurable cfgPathLocal{"local-path", "/home/mkabus/PIDML/", "base path to the local directory with ONNX models"}; + Configurable ccdbPath{"ccdbPath", "Users/m/mkabus/PIDML", "base path to the CCDB directory with ONNX models"}; + Configurable ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "URL of the CCDB repository"}; + Configurable useCcdb{"useCcdb", true, "Whether to autofetch ML model from CCDB. If false, local file will be used."}; + Configurable localPath{"localPath", "/home/mkabus/PIDML/", "base path to the local directory with ONNX models"}; o2::ccdb::CcdbApi ccdbApi; int currentRunNumber = -1; + Filter trackFilter = requireGlobalTrackInFilter(); + using PidTracks = soa::Filtered>; + + // one model for one particle + PidONNXModel model211; + PidONNXModel model2212; + PidONNXModel model321; + void init(InitContext const&) { - if (cfgUseCCDB) { - ccdbApi.init(cfgCCDBURL); + if (useCcdb) { + ccdbApi.init(ccdbUrl); } else { - model211 = PidONNXModel(cfgPathLocal.value, cfgPathCCDB.value, cfgUseCCDB.value, ccdbApi, -1, 211, 0.5f, pSwitchValue[0]); - model2212 = PidONNXModel(cfgPathLocal.value, cfgPathCCDB.value, cfgUseCCDB.value, ccdbApi, -1, 2211, 0.5f, pSwitchValue[1]); - model321 = PidONNXModel(cfgPathLocal.value, cfgPathCCDB.value, cfgUseCCDB.value, ccdbApi, -1, 321, 0.5f, pSwitchValue[2]); + model211 = PidONNXModel(localPath.value, ccdbPath.value, useCcdb.value, ccdbApi, -1, PDG_t::kPiPlus, 0.5f, PSwitchValue[0]); + model2212 = PidONNXModel(localPath.value, ccdbPath.value, useCcdb.value, ccdbApi, -1, PDG_t::kProton, 0.5f, PSwitchValue[1]); + model321 = PidONNXModel(localPath.value, ccdbPath.value, useCcdb.value, ccdbApi, -1, PDG_t::kKPlus, 0.5f, PSwitchValue[2]); } } - Filter trackFilter = requireGlobalTrackInFilter(); - using pidTracks = soa::Filtered>; - void process(aod::Collisions const& collisions, pidTracks const& tracks, aod::McParticles const& /*mcParticles*/, aod::BCsWithTimestamps const&) + void process(aod::Collisions const& collisions, PidTracks const& tracks, aod::McParticles const& /*mcParticles*/, aod::BCsWithTimestamps const&) { auto bc = collisions.iteratorAt(0).bc_as(); - if (cfgUseCCDB && bc.runNumber() != currentRunNumber) { - model211 = PidONNXModel(cfgPathLocal.value, cfgPathCCDB.value, cfgUseCCDB.value, ccdbApi, bc.timestamp(), 211, 0.5f, pSwitchValue[0]); - model2212 = PidONNXModel(cfgPathLocal.value, cfgPathCCDB.value, cfgUseCCDB.value, ccdbApi, bc.timestamp(), 2211, 0.5f, pSwitchValue[1]); - model321 = PidONNXModel(cfgPathLocal.value, cfgPathCCDB.value, cfgUseCCDB.value, ccdbApi, bc.timestamp(), 321, 0.5f, pSwitchValue[2]); + if (useCcdb && bc.runNumber() != currentRunNumber) { + model211 = PidONNXModel(localPath.value, ccdbPath.value, useCcdb.value, ccdbApi, bc.timestamp(), PDG_t::kPiPlus, 0.5f, PSwitchValue[0]); + model2212 = PidONNXModel(localPath.value, ccdbPath.value, useCcdb.value, ccdbApi, bc.timestamp(), PDG_t::kProton, 0.5f, PSwitchValue[1]); + model321 = PidONNXModel(localPath.value, ccdbPath.value, useCcdb.value, ccdbApi, bc.timestamp(), PDG_t::kKPlus, 0.5f, PSwitchValue[2]); } - for (auto& track : tracks) { + for (const auto& track : tracks) { auto particle = track.mcParticle_as(); int pdgCodeMC = particle.pdgCode(); @@ -394,6 +405,6 @@ struct QaPidML { WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{ - adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc), }; } diff --git a/Tools/PIDML/simpleApplyPidOnnxInterface.cxx b/Tools/PIDML/simpleApplyPidOnnxInterface.cxx index 82f644103ed..bcfb83cf354 100644 --- a/Tools/PIDML/simpleApplyPidOnnxInterface.cxx +++ b/Tools/PIDML/simpleApplyPidOnnxInterface.cxx @@ -9,12 +9,13 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -/// \file simpleApplyPidInterface +/// \file simpleApplyPidOnnxInterface.cxx /// \brief A simple example for using PID obtained from the PID ML ONNX Interface. See README.md for more detailed instructions. /// /// \author Maja Kabus #include +#include #include "Framework/runDataProcessing.h" #include "Framework/AnalysisTask.h" @@ -38,21 +39,19 @@ DECLARE_SOA_COLUMN(Accepted, accepted, bool); //! Whether the model accepted par DECLARE_SOA_TABLE(MlPidResults, "AOD", "MLPIDRESULTS", o2::soa::Index<>, mlpidresult::TrackId, mlpidresult::Pid, mlpidresult::Accepted); } // namespace o2::aod -struct SimpleApplyOnnxInterface { - PidONNXInterface pidInterface; // One instance to manage all needed ONNX models +struct SimpleApplyPidOnnxInterface { + Configurable> ptCuts{"ptCuts", {pidml_pt_cuts::Cuts[0], pidml_pt_cuts::NPids, pidml_pt_cuts::NCutVars, pidml_pt_cuts::pidLabels, pidml_pt_cuts::cutVarLabels}, "pT cuts for each output pid and each detector configuration"}; + Configurable> pdgPids{"pdgPids", std::vector{pidml_pt_cuts::pidsV}, "PIDs to predict"}; + Configurable> mlIdentCertaintyThresholds{"mlIdentCertaintyThresholds", std::vector{pidml_pt_cuts::certaintiesV}, "Min certainties of the models to accept given particle to be of given kind"}; + Configurable autoMode{"autoMode", true, "Use automatic model matching: default pT cuts and min certainties"}; - Configurable> cfgPTCuts{"pT_cuts", {pidml_pt_cuts::cuts[0], pidml_pt_cuts::nPids, pidml_pt_cuts::nCutVars, pidml_pt_cuts::pidLabels, pidml_pt_cuts::cutVarLabels}, "pT cuts for each output pid and each detector configuration"}; - Configurable> cfgPids{"pids", std::vector{pidml_pt_cuts::pids_v}, "PIDs to predict"}; - Configurable> cfgCertainties{"certainties", std::vector{pidml_pt_cuts::certainties_v}, "Min certainties of the models to accept given particle to be of given kind"}; - Configurable cfgAutoMode{"autoMode", true, "Use automatic model matching: default pT cuts and min certainties"}; + Configurable ccdbPath{"ccdbPath", "Users/m/mkabus/PIDML", "base path to the CCDB directory with ONNX models"}; + Configurable ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "URL of the CCDB repository"}; + Configurable useCcdb{"useCcdb", true, "Whether to autofetch ML model from CCDB. If false, local file will be used."}; + Configurable localPath{"localPath", "/home/mkabus/PIDML/", "base path to the local directory with ONNX models"}; - Configurable cfgPathCCDB{"ccdb-path", "Users/m/mkabus/PIDML", "base path to the CCDB directory with ONNX models"}; - Configurable cfgCCDBURL{"ccdb-url", "http://alice-ccdb.cern.ch", "URL of the CCDB repository"}; - Configurable cfgUseCCDB{"useCCDB", true, "Whether to autofetch ML model from CCDB. If false, local file will be used."}; - Configurable cfgPathLocal{"local-path", "/home/mkabus/PIDML/", "base path to the local directory with ONNX models"}; - - Configurable cfgUseFixedTimestamp{"use-fixed-timestamp", false, "Whether to use fixed timestamp from configurable instead of timestamp calculated from the data"}; - Configurable cfgTimestamp{"timestamp", 1524176895000, "Hardcoded timestamp for tests"}; + Configurable useFixedTimestamp{"useFixedTimestamp", false, "Whether to use fixed timestamp from configurable instead of timestamp calculated from the data"}; + Configurable fixedTimestamp{"fixedTimestamp", 1524176895000, "Hardcoded timestamp for tests"}; o2::ccdb::CcdbApi ccdbApi; int currentRunNumber = -1; @@ -65,25 +64,27 @@ struct SimpleApplyOnnxInterface { // Filter on isGlobalTrack (TracksSelection) using BigTracks = soa::Filtered>; + PidONNXInterface pidInterface; // One instance to manage all needed ONNX models + void init(InitContext const&) { - if (cfgUseCCDB) { - ccdbApi.init(cfgCCDBURL); + if (useCcdb) { + ccdbApi.init(ccdbUrl); } else { - pidInterface = PidONNXInterface(cfgPathLocal.value, cfgPathCCDB.value, cfgUseCCDB.value, ccdbApi, -1, cfgPids.value, cfgPTCuts.value, cfgCertainties.value, cfgAutoMode.value); + pidInterface = PidONNXInterface(localPath.value, ccdbPath.value, useCcdb.value, ccdbApi, -1, pdgPids.value, ptCuts.value, mlIdentCertaintyThresholds.value, autoMode.value); } } void processCollisions(aod::Collisions const& collisions, BigTracks const& tracks, aod::BCsWithTimestamps const&) { auto bc = collisions.iteratorAt(0).bc_as(); - if (cfgUseCCDB && bc.runNumber() != currentRunNumber) { - uint64_t timestamp = cfgUseFixedTimestamp ? cfgTimestamp.value : bc.timestamp(); - pidInterface = PidONNXInterface(cfgPathLocal.value, cfgPathCCDB.value, cfgUseCCDB.value, ccdbApi, timestamp, cfgPids.value, cfgPTCuts.value, cfgCertainties.value, cfgAutoMode.value); + if (useCcdb && bc.runNumber() != currentRunNumber) { + uint64_t timestamp = useFixedTimestamp ? fixedTimestamp.value : bc.timestamp(); + pidInterface = PidONNXInterface(localPath.value, ccdbPath.value, useCcdb.value, ccdbApi, timestamp, pdgPids.value, ptCuts.value, mlIdentCertaintyThresholds.value, autoMode.value); } - for (auto& track : tracks) { - for (int pid : cfgPids.value) { + for (const auto& track : tracks) { + for (const int& pid : pdgPids.value) { bool accepted = pidInterface.applyModelBoolean(track, pid); LOGF(info, "collision id: %d track id: %d pid: %d accepted: %d p: %.3f; x: %.3f, y: %.3f, z: %.3f", track.collisionId(), track.index(), pid, accepted, track.p(), track.x(), track.y(), track.z()); @@ -91,12 +92,12 @@ struct SimpleApplyOnnxInterface { } } } - PROCESS_SWITCH(SimpleApplyOnnxInterface, processCollisions, "Process with collisions and bcs for CCDB", true); + PROCESS_SWITCH(SimpleApplyPidOnnxInterface, processCollisions, "Process with collisions and bcs for CCDB", true); void processTracksOnly(BigTracks const& tracks) { - for (auto& track : tracks) { - for (int pid : cfgPids.value) { + for (const auto& track : tracks) { + for (const int& pid : pdgPids.value) { bool accepted = pidInterface.applyModelBoolean(track, pid); LOGF(info, "collision id: %d track id: %d pid: %d accepted: %d p: %.3f; x: %.3f, y: %.3f, z: %.3f", track.collisionId(), track.index(), pid, accepted, track.p(), track.x(), track.y(), track.z()); @@ -104,11 +105,11 @@ struct SimpleApplyOnnxInterface { } } } - PROCESS_SWITCH(SimpleApplyOnnxInterface, processTracksOnly, "Process with tracks only -- faster but no CCDB", false); + PROCESS_SWITCH(SimpleApplyPidOnnxInterface, processTracksOnly, "Process with tracks only -- faster but no CCDB", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{ - adaptAnalysisTask(cfgc)}; + adaptAnalysisTask(cfgc)}; } diff --git a/Tools/PIDML/simpleApplyPidOnnxModel.cxx b/Tools/PIDML/simpleApplyPidOnnxModel.cxx index e261c1e10bc..aab1a48fc28 100644 --- a/Tools/PIDML/simpleApplyPidOnnxModel.cxx +++ b/Tools/PIDML/simpleApplyPidOnnxModel.cxx @@ -9,7 +9,7 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -/// \file simpleApplyPidModel +/// \file simpleApplyPidOnnxModel.cxx /// \brief A simple example for using PID obtained from the PID ML ONNX Model. See README.md for more detailed instructions. /// /// \author Maja Kabus @@ -38,18 +38,17 @@ DECLARE_SOA_COLUMN(Accepted, accepted, bool); //! Whether the model accepted par DECLARE_SOA_TABLE(MlPidResults, "AOD", "MLPIDRESULTS", o2::soa::Index<>, mlpidresult::TrackId, mlpidresult::Pid, mlpidresult::Accepted); } // namespace o2::aod -struct SimpleApplyOnnxModel { - PidONNXModel pidModel; // One instance per model, e.g., one per each pid to predict - Configurable cfgPid{"pid", 211, "PID to predict"}; - Configurable cfgCertainty{"certainty", 0.5, "Min certainty of the model to accept given particle to be of given kind"}; +struct SimpleApplyPidOnnxModel { + Configurable pdgPid{"pdgPid", 211, "PID to predict"}; + Configurable certainty{"certainty", 0.5, "Min certainty of the model to accept given particle to be of given kind"}; - Configurable cfgPathCCDB{"ccdb-path", "Users/m/mkabus/PIDML", "base path to the CCDB directory with ONNX models"}; - Configurable cfgCCDBURL{"ccdb-url", "http://alice-ccdb.cern.ch", "URL of the CCDB repository"}; - Configurable cfgUseCCDB{"useCCDB", true, "Whether to autofetch ML model from CCDB. If false, local file will be used."}; - Configurable cfgPathLocal{"local-path", "/home/mkabus/PIDML", "base path to the local directory with ONNX models"}; + Configurable ccdbPath{"ccdbPath", "Users/m/mkabus/PIDML", "base path to the CCDB directory with ONNX models"}; + Configurable ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "URL of the CCDB repository"}; + Configurable useCcdb{"useCcdb", true, "Whether to autofetch ML model from CCDB. If false, local file will be used."}; + Configurable localPath{"localPath", "/home/mkabus/PIDML", "base path to the local directory with ONNX models"}; - Configurable cfgUseFixedTimestamp{"use-fixed-timestamp", false, "Whether to use fixed timestamp from configurable instead of timestamp calculated from the data"}; - Configurable cfgTimestamp{"timestamp", 1524176895000, "Hardcoded timestamp for tests"}; + Configurable useFixedTimestamp{"useFixedTimestamp", false, "Whether to use fixed timestamp from configurable instead of timestamp calculated from the data"}; + Configurable fixedTimestamp{"fixedTimestamp", 1524176895000, "Hardcoded timestamp for tests"}; o2::ccdb::CcdbApi ccdbApi; int currentRunNumber = -1; @@ -61,47 +60,48 @@ struct SimpleApplyOnnxModel { // TPC signal (FullTracks), TOF signal (TOFSignal), TOF beta (pidTOFbeta), dcaXY and dcaZ (TracksDCA) // Filter on isGlobalTrack (TracksSelection) using BigTracks = soa::Filtered>; + PidONNXModel pidModel; // One instance per model, e.g., one per each pid to predict void init(InitContext const&) { - if (cfgUseCCDB) { - ccdbApi.init(cfgCCDBURL); + if (useCcdb) { + ccdbApi.init(ccdbUrl); } else { - pidModel = PidONNXModel(cfgPathLocal.value, cfgPathCCDB.value, cfgUseCCDB.value, ccdbApi, -1, cfgPid.value, cfgCertainty.value); + pidModel = PidONNXModel(localPath.value, ccdbPath.value, useCcdb.value, ccdbApi, -1, pdgPid.value, certainty.value); } } void processCollisions(aod::Collisions const& collisions, BigTracks const& tracks, aod::BCsWithTimestamps const&) { auto bc = collisions.iteratorAt(0).bc_as(); - if (cfgUseCCDB && bc.runNumber() != currentRunNumber) { - uint64_t timestamp = cfgUseFixedTimestamp ? cfgTimestamp.value : bc.timestamp(); - pidModel = PidONNXModel(cfgPathLocal.value, cfgPathCCDB.value, cfgUseCCDB.value, ccdbApi, timestamp, cfgPid.value, cfgCertainty.value); + if (useCcdb && bc.runNumber() != currentRunNumber) { + uint64_t timestamp = useFixedTimestamp ? fixedTimestamp.value : bc.timestamp(); + pidModel = PidONNXModel(localPath.value, ccdbPath.value, useCcdb.value, ccdbApi, timestamp, pdgPid.value, certainty.value); } - for (auto& track : tracks) { + for (const auto& track : tracks) { bool accepted = pidModel.applyModelBoolean(track); LOGF(info, "collision id: %d track id: %d accepted: %d p: %.3f; x: %.3f, y: %.3f, z: %.3f", track.collisionId(), track.index(), accepted, track.p(), track.x(), track.y(), track.z()); - pidMLResults(track.index(), cfgPid.value, accepted); + pidMLResults(track.index(), pdgPid.value, accepted); } } - PROCESS_SWITCH(SimpleApplyOnnxModel, processCollisions, "Process with collisions and bcs for CCDB", true); + PROCESS_SWITCH(SimpleApplyPidOnnxModel, processCollisions, "Process with collisions and bcs for CCDB", true); void processTracksOnly(BigTracks const& tracks) { - for (auto& track : tracks) { + for (const auto& track : tracks) { bool accepted = pidModel.applyModelBoolean(track); LOGF(info, "collision id: %d track id: %d accepted: %d p: %.3f; x: %.3f, y: %.3f, z: %.3f", track.collisionId(), track.index(), accepted, track.p(), track.x(), track.y(), track.z()); - pidMLResults(track.index(), cfgPid.value, accepted); + pidMLResults(track.index(), pdgPid.value, accepted); } } - PROCESS_SWITCH(SimpleApplyOnnxModel, processTracksOnly, "Process with tracks only -- faster but no CCDB", false); + PROCESS_SWITCH(SimpleApplyPidOnnxModel, processTracksOnly, "Process with tracks only -- faster but no CCDB", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{ - adaptAnalysisTask(cfgc)}; + adaptAnalysisTask(cfgc)}; } diff --git a/Tutorials/src/eventMixing.cxx b/Tutorials/src/eventMixing.cxx index 676d6ba96e3..a1526740886 100644 --- a/Tutorials/src/eventMixing.cxx +++ b/Tutorials/src/eventMixing.cxx @@ -9,10 +9,13 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. /// +/// \file eventMixing.cxx /// \brief Example tasks for event mixing. -/// \author +/// \author Karwowska Maja /// \since +#include +#include "Framework/AnalysisDataModel.h" #include "Framework/runDataProcessing.h" #include "Framework/AnalysisTask.h" #include "Framework/ASoAHelpers.h" @@ -37,18 +40,18 @@ DECLARE_SOA_TABLE(MixingHashes, "AOD", "HASH", hash::Bin); struct MixedEvents { SliceCache cache; + Preslice perCollision = aod::track::collisionId; std::vector xBins{VARIABLE_WIDTH, -0.064, -0.062, -0.060, 0.066, 0.068, 0.070, 0.072}; std::vector yBins{VARIABLE_WIDTH, -0.320, -0.301, -0.300, 0.330, 0.340, 0.350, 0.360}; using BinningType = ColumnBinningPolicy; - BinningType binningOnPositions{{xBins, yBins}, true}; // true is for 'ignore overflows' (true by default) + BinningType binningOnPositions{{xBins, yBins}, true}; // true is for 'ignore overflows' (true by default) SameKindPair pair{binningOnPositions, 5, -1, &cache}; // indicates that 5 events should be mixed and under/overflow (-1) to be ignored - void process(aod::Collisions const& collisions, aod::Tracks const& tracks) { LOGF(info, "Input data Collisions %d, Tracks %d ", collisions.size(), tracks.size()); int count = 0; - for (auto& [c1, tracks1, c2, tracks2] : pair) { + for (const auto& [c1, tracks1, c2, tracks2] : pair) { // Example of using getBin() to check collisions bin // NOTE that it is a bit different for FlexibleBinning -- check in respective example int bin = binningOnPositions.getBin({c1.posX(), c1.posY()}); @@ -60,7 +63,7 @@ struct MixedEvents { // Example of using tracks from mixed events -- iterate over all track pairs from the two collisions int trackCount = 0; - for (auto& [t1, t2] : combinations(CombinationsFullIndexPolicy(tracks1, tracks2))) { + for (const auto& [t1, t2] : combinations(CombinationsFullIndexPolicy(tracks1, tracks2))) { LOGF(info, "Mixed event tracks pair: (%d, %d) from events (%d, %d), track event: (%d, %d)", t1.index(), t2.index(), c1.index(), c2.index(), t1.collision().index(), t2.collision().index()); trackCount++; if (trackCount == 10) @@ -72,12 +75,14 @@ struct MixedEvents { struct MixedEventsInsideProcess { SliceCache cache; + Preslice perCollision = aod::track::collisionId; std::vector xBins{VARIABLE_WIDTH, -0.064, -0.062, -0.060, 0.066, 0.068, 0.070, 0.072}; std::vector yBins{VARIABLE_WIDTH, -0.320, -0.301, -0.300, 0.330, 0.340, 0.350, 0.360}; using BinningType = ColumnBinningPolicy; BinningType binningOnPositions{{xBins, yBins}, true}; // true is for 'ignore overflows' (true by default) - void process(aod::Collisions& collisions, aod::Tracks& tracks) + void process(aod::Collisions const& collisions, aod::Tracks const& tracks) + { LOGF(info, "Input data Collisions %d, Tracks %d ", collisions.size(), tracks.size()); @@ -85,7 +90,7 @@ struct MixedEventsInsideProcess { SameKindPair pair{binningOnPositions, 5, -1, collisions, tracksTuple, &cache}; // indicates that 5 events should be mixed and under/overflow (-1) to be ignored int count = 0; - for (auto& [c1, tracks1, c2, tracks2] : pair) { + for (const auto& [c1, tracks1, c2, tracks2] : pair) { LOGF(info, "Mixed event collisions: (%d, %d)", c1.globalIndex(), c2.globalIndex()); count++; if (count == 10) @@ -93,7 +98,7 @@ struct MixedEventsInsideProcess { // Example of using tracks from mixed events -- iterate over all track pairs from the two collisions int trackCount = 0; - for (auto& [t1, t2] : combinations(CombinationsFullIndexPolicy(tracks1, tracks2))) { + for (const auto& [t1, t2] : combinations(CombinationsFullIndexPolicy(tracks1, tracks2))) { LOGF(info, "Mixed event tracks pair: (%d, %d) from events (%d, %d), track event: (%d, %d)", t1.index(), t2.index(), c1.index(), c2.index(), t1.collision().index(), t2.collision().index()); trackCount++; if (trackCount == 10) @@ -105,21 +110,22 @@ struct MixedEventsInsideProcess { struct MixedEventsFilteredTracks { SliceCache cache; + Preslice perCollision = aod::track::collisionId; Filter trackFilter = aod::track::eta < 1.0f; - using myTracks = soa::Filtered; + using MyTracks = soa::Filtered; std::vector xBins{VARIABLE_WIDTH, -0.064, -0.062, -0.060, 0.066, 0.068, 0.070, 0.072}; std::vector yBins{VARIABLE_WIDTH, -0.320, -0.301, -0.300, 0.330, 0.340, 0.350, 0.360}; using BinningType = ColumnBinningPolicy; - BinningType binningOnPositions{{xBins, yBins}, true}; // true is for 'ignore overflows' (true by default) - SameKindPair pair{binningOnPositions, 5, -1, &cache}; // indicates that 5 events should be mixed and under/overflow (-1) to be ignored + BinningType binningOnPositions{{xBins, yBins}, true}; // true is for 'ignore overflows' (true by default) + SameKindPair pair{binningOnPositions, 5, -1, &cache}; // indicates that 5 events should be mixed and under/overflow (-1) to be ignored - void process(aod::Collisions const& collisions, myTracks const& tracks) + void process(aod::Collisions const& collisions, MyTracks const& tracks) { LOGF(info, "Input data Collisions %d, Tracks %d ", collisions.size(), tracks.size()); int count = 0; - for (auto& [c1, tracks1, c2, tracks2] : pair) { + for (const auto& [c1, tracks1, c2, tracks2] : pair) { LOGF(info, "Mixed event collisions: (%d, %d)", c1.globalIndex(), c2.globalIndex()); count++; if (count == 100) @@ -127,7 +133,7 @@ struct MixedEventsFilteredTracks { // Example of using tracks from mixed events -- iterate over all track pairs from the two collisions int trackCount = 0; - for (auto& [t1, t2] : combinations(CombinationsFullIndexPolicy(tracks1, tracks2))) { + for (const auto& [t1, t2] : combinations(CombinationsFullIndexPolicy(tracks1, tracks2))) { LOGF(info, "Mixed event tracks pair: (%d, %d) (%.2f, %.2f) < 1.0f from events (%d, %d), track event: (%d, %d)", t1.index(), t2.index(), t1.eta(), t2.eta(), c1.index(), c2.index(), t1.collision().index(), t2.collision().index()); trackCount++; if (trackCount == 10) @@ -139,19 +145,20 @@ struct MixedEventsFilteredTracks { struct MixedEventsJoinedCollisions { SliceCache cache; - using aodCollisions = soa::Join; + Preslice perCollision = aod::track::collisionId; + using AODCollisions = soa::Join; std::vector xBins{VARIABLE_WIDTH, -0.064, -0.062, -0.060, 0.066, 0.068, 0.070, 0.072}; std::vector yBins{VARIABLE_WIDTH, -0.320, -0.301, -0.300, 0.330, 0.340, 0.350, 0.360}; using BinningType = ColumnBinningPolicy; - BinningType binningOnPositions{{xBins, yBins}, true}; // true is for 'ignore overflows' (true by default) - SameKindPair pair{binningOnPositions, 5, -1, &cache}; // indicates that 5 events should be mixed and under/overflow (-1) to be ignored + BinningType binningOnPositions{{xBins, yBins}, true}; // true is for 'ignore overflows' (true by default) + SameKindPair pair{binningOnPositions, 5, -1, &cache}; // indicates that 5 events should be mixed and under/overflow (-1) to be ignored - void process(aodCollisions& collisions, aod::Tracks const& tracks, aod::BCsWithTimestamps const&) + void process(AODCollisions const& collisions, aod::Tracks const& tracks, aod::BCsWithTimestamps const&) { LOGF(info, "Input data Collisions %d, Tracks %d ", collisions.size(), tracks.size()); int count = 0; - for (auto& [c1, tracks1, c2, tracks2] : pair) { + for (const auto& [c1, tracks1, c2, tracks2] : pair) { LOGF(info, "Mixed event collisions: (%d, %d)", c1.globalIndex(), c2.globalIndex()); count++; if (count == 10) @@ -159,8 +166,8 @@ struct MixedEventsJoinedCollisions { // Example of using tracks from mixed events -- iterate over all track pairs from the two collisions int trackCount = 0; - for (auto& [t1, t2] : combinations(CombinationsFullIndexPolicy(tracks1, tracks2))) { - LOGF(info, "Mixed event tracks pair: (%d, %d) from events (%d, %d), track event: (%d, %d)", t1.index(), t2.index(), c1.index(), c2.index(), t1.collision().index(), t2.collision().index()); + for (const auto& [t1, t2] : combinations(CombinationsFullIndexPolicy(tracks1, tracks2))) { + LOGF(info, "Mixed event tracks pair: (%d, %d) from events (%d, %d), track event: (%d, %d)", t1.index(), t2.index(), c1.index(), c2.index(), t1.collision_as().index(), t2.collision_as().index()); trackCount++; if (trackCount == 10) break; @@ -171,19 +178,20 @@ struct MixedEventsJoinedCollisions { struct MixedEventsDynamicColumns { SliceCache cache; - using aodCollisions = soa::Join; + Preslice perCollison = aod::track::collisionId; + using AODCollisions = soa::Join; std::vector zBins{7, -7, 7}; std::vector multBins{VARIABLE_WIDTH, 0, 5, 10, 20, 30, 40, 50, 100.1}; using BinningType = ColumnBinningPolicy>; - BinningType corrBinning{{zBins, multBins}, true}; // true is for 'ignore overflows' (true by default) - SameKindPair pair{corrBinning, 5, -1, &cache}; // indicates that 5 events should be mixed and under/overflow (-1) to be ignored + BinningType corrBinning{{zBins, multBins}, true}; // true is for 'ignore overflows' (true by default) + SameKindPair pair{corrBinning, 5, -1, &cache}; // indicates that 5 events should be mixed and under/overflow (-1) to be ignored - void process(aodCollisions& collisions, aod::Tracks const& tracks) + void process(AODCollisions const& collisions, aod::Tracks const& tracks) { LOGF(info, "Input data Collisions %d, Tracks %d ", collisions.size(), tracks.size()); int count = 0; - for (auto& [c1, tracks1, c2, tracks2] : pair) { + for (const auto& [c1, tracks1, c2, tracks2] : pair) { LOGF(info, "Mixed event collisions: (%d, %d)", c1.globalIndex(), c2.globalIndex()); count++; if (count == 10) @@ -191,8 +199,8 @@ struct MixedEventsDynamicColumns { // Example of using tracks from mixed events -- iterate over all track pairs from the two collisions int trackCount = 0; - for (auto& [t1, t2] : combinations(CombinationsFullIndexPolicy(tracks1, tracks2))) { - LOGF(info, "Mixed event tracks pair: (%d, %d) from events (%d, %d), track event: (%d, %d)", t1.index(), t2.index(), c1.index(), c2.index(), t1.collision().index(), t2.collision().index()); + for (const auto& [t1, t2] : combinations(CombinationsFullIndexPolicy(tracks1, tracks2))) { + LOGF(info, "Mixed event tracks pair: (%d, %d) from events (%d, %d), track event: (%d, %d)", t1.index(), t2.index(), c1.index(), c2.index(), t1.collision_as().index(), t2.collision_as().index()); trackCount++; if (trackCount == 10) break; @@ -203,10 +211,12 @@ struct MixedEventsDynamicColumns { struct MixedEventsVariousKinds { SliceCache cache; + Preslice perCollisionTrack = aod::track::collisionId; + Preslice perCollisionV0 = aod::v0::collisionId; std::vector xBins{VARIABLE_WIDTH, -0.064, -0.062, -0.060, 0.066, 0.068, 0.070, 0.072}; std::vector yBins{VARIABLE_WIDTH, -0.320, -0.301, -0.300, 0.330, 0.340, 0.350, 0.360}; using BinningType = ColumnBinningPolicy; - BinningType binningOnPositions{{xBins, yBins}, true}; // true is for 'ignore overflows' (true by default) + BinningType binningOnPositions{{xBins, yBins}, true}; // true is for 'ignore overflows' (true by default) Pair pair{binningOnPositions, 5, -1, &cache}; // indicates that 5 events should be mixed and under/overflow (-1) to be ignored void process(aod::Collisions const& collisions, aod::Tracks const& tracks, aod::V0s const& v0s) @@ -216,7 +226,7 @@ struct MixedEventsVariousKinds { int count = 0; // tracks1 is an aod::Tracks table of tracks belonging to collision c1 (aod::Collision::iterator) // tracks2 is an aod::V0s table of V0s belonging to collision c2 (aod::Collision::iterator) - for (auto& [c1, tracks1, c2, tracks2] : pair) { + for (const auto& [c1, tracks1, c2, tracks2] : pair) { LOGF(info, "Mixed event collisions: (%d, %d)", c1.globalIndex(), c2.globalIndex()); count++; if (count == 100) @@ -224,7 +234,7 @@ struct MixedEventsVariousKinds { // Example of using tracks from mixed events -- iterate over all track pairs from the two collisions int trackCount = 0; - for (auto& [t1, t2] : combinations(CombinationsFullIndexPolicy(tracks1, tracks2))) { + for (const auto& [t1, t2] : combinations(CombinationsFullIndexPolicy(tracks1, tracks2))) { LOGF(info, "Mixed event tracks pair: (%d, %d) from events (%d, %d), track event: (%d, %d)", t1.index(), t2.index(), c1.index(), c2.index(), t1.collision().index(), t2.collision().index()); trackCount++; if (trackCount == 10) @@ -236,11 +246,12 @@ struct MixedEventsVariousKinds { struct MixedEventsTriple { SliceCache cache; + Preslice perCollision = aod::track::collisionId; std::vector xBins{VARIABLE_WIDTH, -0.064, -0.062, -0.060, 0.066, 0.068, 0.070, 0.072}; std::vector yBins{VARIABLE_WIDTH, -0.320, -0.301, -0.300, 0.330, 0.340, 0.350, 0.360}; std::vector zBins{7, -7, 7}; using BinningType = ColumnBinningPolicy; - BinningType binningOnPositions{{xBins, yBins, zBins}, true}; // true is for 'ignore overflows' (true by default) + BinningType binningOnPositions{{xBins, yBins, zBins}, true}; // true is for 'ignore overflows' (true by default) SameKindTriple triple{binningOnPositions, 5, -1, &cache}; // indicates that 5 events should be mixed and under/overflow (-1) to be ignored void process(aod::Collisions const& collisions, aod::Tracks const& tracks) @@ -248,7 +259,7 @@ struct MixedEventsTriple { LOGF(info, "Input data Collisions %d, Tracks %d", collisions.size(), tracks.size()); int count = 0; - for (auto& [c1, tracks1, c2, tracks2, c3, tracks3] : triple) { + for (const auto& [c1, tracks1, c2, tracks2, c3, tracks3] : triple) { LOGF(info, "Mixed event collisions: (%d, %d, %d)", c1.globalIndex(), c2.globalIndex(), c3.globalIndex()); count++; if (count == 100) @@ -256,7 +267,7 @@ struct MixedEventsTriple { // Example of using tracks from mixed events -- iterate over all track triplets from the three collisions int trackCount = 0; - for (auto& [t1, t2, t3] : combinations(CombinationsFullIndexPolicy(tracks1, tracks2, tracks3))) { + for (const auto& [t1, t2, t3] : combinations(CombinationsFullIndexPolicy(tracks1, tracks2, tracks3))) { LOGF(info, "Mixed event tracks triple: (%d, %d, %d) from events (%d, %d, %d), track event: (%d, %d, %d)", t1.index(), t2.index(), t3.index(), c1.index(), c2.index(), c3.index(), t1.collision().index(), t2.collision().index(), t3.collision().index()); trackCount++; if (trackCount == 10) @@ -268,11 +279,13 @@ struct MixedEventsTriple { struct MixedEventsTripleVariousKinds { SliceCache cache; + Preslice perCollisionTrack = aod::track::collisionId; + Preslice perCollisionV0 = aod::v0::collisionId; std::vector xBins{VARIABLE_WIDTH, -0.064, -0.062, -0.060, 0.066, 0.068, 0.070, 0.072}; std::vector yBins{VARIABLE_WIDTH, -0.320, -0.301, -0.300, 0.330, 0.340, 0.350, 0.360}; std::vector zBins{7, -7, 7}; using BinningType = ColumnBinningPolicy; - BinningType binningOnPositions{{xBins, yBins, zBins}, true}; // true is for 'ignore overflows' (true by default) + BinningType binningOnPositions{{xBins, yBins, zBins}, true}; // true is for 'ignore overflows' (true by default) Triple triple{binningOnPositions, 5, -1, &cache}; // indicates that 5 events should be mixed and under/overflow (-1) to be ignored void process(aod::Collisions const& collisions, aod::Tracks const& tracks, aod::V0s const& v0s) @@ -283,7 +296,7 @@ struct MixedEventsTripleVariousKinds { // tracks1 is an aod::Tracks table of tracks belonging to collision c1 (aod::Collision::iterator) // tracks2 is an aod::V0s table of V0s belonging to collision c2 (aod::Collision::iterator) // tracks3 is an aod::Tracks table of tracks belonging to collision c3 (aod::Collision::iterator) - for (auto& [c1, tracks1, c2, tracks2, c3, tracks3] : triple) { + for (const auto& [c1, tracks1, c2, tracks2, c3, tracks3] : triple) { LOGF(info, "Mixed event collisions: (%d, %d, %d)", c1.globalIndex(), c2.globalIndex(), c3.globalIndex()); count++; if (count == 100) @@ -291,7 +304,7 @@ struct MixedEventsTripleVariousKinds { // Example of using tracks from mixed events -- iterate over all track triplets from the three collisions int trackCount = 0; - for (auto& [t1, t2, t3] : combinations(CombinationsFullIndexPolicy(tracks1, tracks2, tracks3))) { + for (const auto& [t1, t2, t3] : combinations(CombinationsFullIndexPolicy(tracks1, tracks2, tracks3))) { LOGF(info, "Mixed event tracks triple: (%d, %d, %d) from events (%d, %d, %d), track event: (%d, %d, %d)", t1.index(), t2.index(), t3.index(), c1.index(), c2.index(), c3.index(), t1.collision().index(), t2.collision().index(), t3.collision().index()); trackCount++; if (trackCount == 10) @@ -331,9 +344,9 @@ struct HashTask { void process(aod::Collisions const& collisions) { - for (auto& collision : collisions) { + for (const auto& collision : collisions) { int hash = getHash(xBins, yBins, collision.posX(), collision.posY()); - // LOGF(info, "Collision: %d (%f, %f, %f) hash: %d", collision.index(), collision.posX(), collision.posY(), collision.posZ(), hash); + LOGF(info, "Collision: %d (%f, %f, %f) hash: %d", collision.index(), collision.posX(), collision.posY(), collision.posZ(), hash); hashes(hash); } } @@ -341,16 +354,17 @@ struct HashTask { struct MixedEventsWithHashTask { SliceCache cache; - using myCollisions = soa::Join; + Preslice perCollision = aod::track::collisionId; + using MyCollision = soa::Join; NoBinningPolicy hashBin; - SameKindPair> pair{hashBin, 5, -1, &cache}; // indicates that 5 events should be mixed and under/overflow (-1) to be ignored + SameKindPair> pair{hashBin, 5, -1, &cache}; // indicates that 5 events should be mixed and under/overflow (-1) to be ignored - void process(myCollisions& collisions, aod::Tracks& tracks) + void process(MyCollision const& collisions, aod::Tracks const& tracks) { LOGF(info, "Input data Collisions %d, Tracks %d ", collisions.size(), tracks.size()); int count = 0; - for (auto& [c1, tracks1, c2, tracks2] : pair) { + for (const auto& [c1, tracks1, c2, tracks2] : pair) { LOGF(info, "Mixed event collisions: (%d, %d)", c1.globalIndex(), c2.globalIndex()); count++; if (count == 10) @@ -358,7 +372,7 @@ struct MixedEventsWithHashTask { // Example of using tracks from mixed events -- iterate over all track pairs from the two collisions int trackCount = 0; - for (auto& [t1, t2] : combinations(CombinationsFullIndexPolicy(tracks1, tracks2))) { + for (const auto& [t1, t2] : combinations(CombinationsFullIndexPolicy(tracks1, tracks2))) { LOGF(info, "Mixed event tracks pair: (%d, %d) from events (%d, %d)", t1.globalIndex(), t2.globalIndex(), c1.globalIndex(), c2.globalIndex()); trackCount++; if (trackCount == 10) @@ -370,27 +384,28 @@ struct MixedEventsWithHashTask { struct MixedEventsPartitionedTracks { SliceCache cache; + Preslice perCollision = aod::track::collisionId; Filter trackFilter = (aod::track::x > -0.8f) && (aod::track::x < 0.8f) && (aod::track::y > 1.0f); - using myTracks = soa::Filtered; + using MyTracks = soa::Filtered; - Configurable philow{"phiLow", 1.0f, "lowest phi"}; - Configurable phiup{"phiUp", 2.0f, "highest phi"}; + Configurable phiLow{"phiLow", 1.0f, "lowest phi"}; + Configurable phiUp{"phiUp", 2.0f, "highest phi"}; std::vector xBins{VARIABLE_WIDTH, -0.064, -0.062, -0.060, 0.066, 0.068, 0.070, 0.072}; std::vector yBins{VARIABLE_WIDTH, -0.320, -0.301, -0.300, 0.330, 0.340, 0.350, 0.360}; using BinningType = ColumnBinningPolicy; - BinningType binningOnPositions{{xBins, yBins}, true}; // true is for 'ignore overflows' (true by default) - SameKindPair pair{binningOnPositions, 5, -1, &cache}; // indicates that 5 events should be mixed and under/overflow (-1) to be ignored + BinningType binningOnPositions{{xBins, yBins}, true}; // true is for 'ignore overflows' (true by default) + SameKindPair pair{binningOnPositions, 5, -1, &cache}; // indicates that 5 events should be mixed and under/overflow (-1) to be ignored - void process(aod::Collisions const& collisions, myTracks const& tracks) + void process(aod::Collisions const& collisions, MyTracks const& tracks) { LOGF(info, "Input data Collisions %d, Tracks %d ", collisions.size(), tracks.size()); - for (auto& [c1, tracks1, c2, tracks2] : pair) { - Partition leftPhi1 = aod::track::phi < philow; - Partition leftPhi2 = aod::track::phi < philow; - Partition rightPhi1 = aod::track::phi >= phiup; - Partition rightPhi2 = aod::track::phi >= phiup; + for (const auto& [c1, tracks1, c2, tracks2] : pair) { + Partition leftPhi1 = aod::track::phi < phiLow; + Partition leftPhi2 = aod::track::phi < phiLow; + Partition rightPhi1 = aod::track::phi >= phiUp; + Partition rightPhi2 = aod::track::phi >= phiUp; leftPhi1.bindTable(tracks1); leftPhi2.bindTable(tracks2); rightPhi1.bindTable(tracks1); @@ -399,14 +414,14 @@ struct MixedEventsPartitionedTracks { LOGF(info, "Mixed event collisions: (%d, %d), tracks: (%d, %d), left phis: (%d, %d), right phis: (%d, %d)", c1.globalIndex(), c2.globalIndex(), tracks1.size(), tracks2.size(), leftPhi1.size(), leftPhi2.size(), rightPhi1.size(), rightPhi2.size()); // Example of using tracks from mixed events -- iterate over all track pairs from the two partitions from two collisions - for (auto& [t1, t2] : combinations(CombinationsFullIndexPolicy(leftPhi1, leftPhi2))) { - if (t1.phi() >= (float)philow || t2.phi() >= (float)philow) { - LOGF(info, "WRONG Mixed event left tracks pair: (%d, %d) from events (%d, %d), phi: (%.3f. %.3f) < %.3f", t1.index(), t2.index(), c1.index(), c2.index(), t1.phi(), t2.phi(), (float)philow); + for (const auto& [t1, t2] : combinations(CombinationsFullIndexPolicy(leftPhi1, leftPhi2))) { + if (t1.phi() >= static_cast(phiLow) || t2.phi() >= static_cast(phiLow)) { + LOGF(info, "WRONG Mixed event left tracks pair: (%d, %d) from events (%d, %d), phi: (%.3f. %.3f) < %.3f", t1.index(), t2.index(), c1.index(), c2.index(), t1.phi(), t2.phi(), (float)phiLow); } } - for (auto& [t1, t2] : combinations(CombinationsFullIndexPolicy(rightPhi1, rightPhi2))) { - if (t1.phi() < (float)phiup || t2.phi() < (float)phiup) { - LOGF(info, "WRONG Mixed event right tracks pair: (%d, %d) from events (%d, %d), phi: (%.3f. %.3f) >= %.3f", t1.index(), t2.index(), c1.index(), c2.index(), t1.phi(), t2.phi(), (float)phiup); + for (const auto& [t1, t2] : combinations(CombinationsFullIndexPolicy(rightPhi1, rightPhi2))) { + if (t1.phi() < static_cast(phiUp) || t2.phi() < static_cast(phiUp)) { + LOGF(info, "WRONG Mixed event right tracks pair: (%d, %d) from events (%d, %d), phi: (%.3f. %.3f) >= %.3f", t1.index(), t2.index(), c1.index(), c2.index(), t1.phi(), t2.phi(), (float)phiUp); } } } @@ -415,12 +430,12 @@ struct MixedEventsPartitionedTracks { struct MixedEventsLambdaBinning { SliceCache cache; - Preslice perCol = aod::track::collisionId; + Preslice perCollision = aod::track::collisionId; ConfigurableAxis axisVertex{"axisVertex", {14, -7, 7}, "vertex axis for histograms"}; ConfigurableAxis axisMultiplicity{"axisMultiplicity", {VARIABLE_WIDTH, 0.0, 2.750, 5.250, 7.750, 12.750, 17.750, 22.750, 27.750, 32.750, 37.750, 42.750, 47.750, 52.750, 57.750, 62.750, 67.750, 72.750, 77.750, 82.750, 87.750, 92.750, 97.750, 250.1}, "multiplicity axis for histograms"}; - void process(aod::Collisions& collisions, aod::Tracks& tracks) + void process(aod::Collisions const& collisions, aod::Tracks const& tracks) { LOGF(info, "Input data Collisions %d, Tracks %d ", collisions.size(), tracks.size()); @@ -437,7 +452,7 @@ struct MixedEventsLambdaBinning { SameKindPair pair{binningWithLambda, 5, -1, collisions, tracksTuple, &cache}; // indicates that 5 events should be mixed and under/overflow (-1) to be ignored int count = 0; - for (auto& [c1, tracks1, c2, tracks2] : pair) { + for (const auto& [c1, tracks1, c2, tracks2] : pair) { // NOTE that getBin() with FlexibleBinningPolicy needs explicit tuple construction int bin = binningWithLambda.getBin(std::tuple(getTracksSize(c1), c1.posZ())); @@ -448,7 +463,7 @@ struct MixedEventsLambdaBinning { // Example of using tracks from mixed events -- iterate over all track pairs from the two collisions int trackCount = 0; - for (auto& [t1, t2] : combinations(CombinationsFullIndexPolicy(tracks1, tracks2))) { + for (const auto& [t1, t2] : combinations(CombinationsFullIndexPolicy(tracks1, tracks2))) { LOGF(info, "Mixed event tracks pair: (%d, %d) from events (%d, %d), track event: (%d, %d)", t1.index(), t2.index(), c1.index(), c2.index(), t1.collision().index(), t2.collision().index()); trackCount++; if (trackCount == 10) @@ -463,6 +478,7 @@ struct MixedEventsCounters { // https://aliceo2group.github.io/analysis-framework/docs/tutorials/eventMixing.html#mixedeventscounters SliceCache cache; + Preslice perCollision = aod::track::collisionId; std::vector xBins{VARIABLE_WIDTH, -0.064, -0.062, -0.060, 0.066, 0.068, 0.070, 0.072}; std::vector yBins{VARIABLE_WIDTH, -0.320, -0.301, -0.300, 0.330, 0.340, 0.350, 0.360}; diff --git a/Tutorials/src/eventMixingValidation.cxx b/Tutorials/src/eventMixingValidation.cxx index 2db94b1d082..cc1933b0a25 100644 --- a/Tutorials/src/eventMixingValidation.cxx +++ b/Tutorials/src/eventMixingValidation.cxx @@ -9,11 +9,14 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. /// +/// \file eventMixingValidation.cxx /// \brief Validation tasks for event mixing. -/// \author +/// \author Karwowska Maja /// \since -#include +#include +#include "Framework/AnalysisDataModel.h" +#include "Framework/SliceCache.h" #include "Framework/runDataProcessing.h" #include "Framework/AnalysisTask.h" #include "Framework/ASoAHelpers.h" @@ -28,22 +31,23 @@ using namespace o2::soa; struct MixedEventsEmptyTables { SliceCache cache; + Preslice perCollision = aod::track::collisionId; // Dummy filter to enforce empty tables Filter trackFilter = (aod::track::x > -0.8f) && (aod::track::x < -0.8f); - using myTracks = soa::Filtered; + using MyTracks = soa::Filtered; std::vector xBins{VARIABLE_WIDTH, -0.064, -0.062, -0.060, 0.066, 0.068, 0.070, 0.072}; std::vector yBins{VARIABLE_WIDTH, -0.320, -0.301, -0.300, 0.330, 0.340, 0.350, 0.360}; using BinningType = ColumnBinningPolicy; BinningType binningOnPositions{{xBins, yBins}, true}; // true is for 'ignore overflows' (true by default) - SameKindPair pair{binningOnPositions, 5, -1, &cache}; // indicates that 5 events should be mixed and under/overflow (-1) to be ignored + SameKindPair pair{binningOnPositions, 5, -1, &cache}; // indicates that 5 events should be mixed and under/overflow (-1) to be ignored - void process(aod::Collisions const& collisions, myTracks const& tracks) + void process(aod::Collisions const& collisions, MyTracks const& tracks) { LOGF(info, "Input data Collisions %d, Tracks %d ", collisions.size(), tracks.size()); int count = 0; - for (auto& [c1, tracks1, c2, tracks2] : pair) { + for (const auto& [c1, tracks1, c2, tracks2] : pair) { LOGF(info, "Mixed event collisions: (%d, %d)", c1.globalIndex(), c2.globalIndex()); count++; if (count == 10) @@ -51,7 +55,7 @@ struct MixedEventsEmptyTables { // Example of using tracks from mixed events -- iterate over all track pairs from the two collisions int trackCount = 0; - for (auto& [t1, t2] : combinations(CombinationsFullIndexPolicy(tracks1, tracks2))) { + for (const auto& [t1, t2] : combinations(CombinationsFullIndexPolicy(tracks1, tracks2))) { LOGF(info, "Mixed event tracks pair: (%d, %d) from events (%d, %d), track event: (%d, %d)", t1.index(), t2.index(), c1.index(), c2.index(), t1.collision().index(), t2.collision().index()); trackCount++; if (trackCount == 10) @@ -63,6 +67,7 @@ struct MixedEventsEmptyTables { struct MixedEventsJoinedTracks { SliceCache cache; + Preslice perCollision = aod::track::collisionId; std::vector xBins{VARIABLE_WIDTH, -0.064, -0.062, -0.060, 0.066, 0.068, 0.070, 0.072}; std::vector yBins{VARIABLE_WIDTH, -0.320, -0.301, -0.300, 0.330, 0.340, 0.350, 0.360}; using BinningType = ColumnBinningPolicy; @@ -74,7 +79,7 @@ struct MixedEventsJoinedTracks { LOGF(info, "Input data Collisions %d, Tracks %d ", collisions.size(), tracks.size()); int count = 0; - for (auto& [c1, tracks1, c2, tracks2] : pair) { + for (const auto& [c1, tracks1, c2, tracks2] : pair) { LOGF(info, "Mixed event collisions: (%d, %d)", c1.globalIndex(), c2.globalIndex()); count++; if (count == 100) @@ -82,7 +87,7 @@ struct MixedEventsJoinedTracks { // Example of using tracks from mixed events -- iterate over all track pairs from the two collisions int trackCount = 0; - for (auto& [t1, t2] : combinations(CombinationsFullIndexPolicy(tracks1, tracks2))) { + for (const auto& [t1, t2] : combinations(CombinationsFullIndexPolicy(tracks1, tracks2))) { LOGF(info, "Mixed event tracks pair: (%d, %d) from events (%d, %d), track event: (%d, %d)", t1.index(), t2.index(), c1.index(), c2.index(), t1.collision().index(), t2.collision().index()); trackCount++; if (trackCount == 10) @@ -94,6 +99,7 @@ struct MixedEventsJoinedTracks { // It should not compile // struct MixedEventsBadSubscription { +// Preslice perCollision = aod::track::collisionId; // std::vector xBins{VARIABLE_WIDTH, -0.064, -0.062, -0.060, 0.066, 0.068, 0.070, 0.072}; // std::vector yBins{VARIABLE_WIDTH, -0.320, -0.301, -0.300, 0.330, 0.340, 0.350, 0.360}; // using BinningType = ColumnBinningPolicy; @@ -103,7 +109,7 @@ struct MixedEventsJoinedTracks { // void process(aod::Collisions const& collisions, aod::Tracks const& tracks) // { // int count = 0; -// for (auto& [c1, tracks1, c2, tracks2] : pair) { +// for (const auto& [c1, tracks1, c2, tracks2] : pair) { // LOGF(info, "Mixed event collisions: (%d, %d)", c1.globalIndex(), c2.globalIndex()); // count++; // if (count == 10) @@ -111,7 +117,7 @@ struct MixedEventsJoinedTracks { // // // Example of using tracks from mixed events -- iterate over all track pairs from the two collisions // int trackCount = 0; -// for (auto& [t1, t2] : combinations(CombinationsFullIndexPolicy(tracks1, tracks2))) { +// for (const auto& [t1, t2] : combinations(CombinationsFullIndexPolicy(tracks1, tracks2))) { // LOGF(info, "Mixed event tracks pair: (%d, %d) from events (%d, %d), track event: (%d, %d)", t1.index(), t2.index(), c1.index(), c2.index(), t1.collision().index(), t2.collision().index()); // trackCount++; // if (trackCount == 10)