diff --git a/Common/Core/fwdtrackUtilities.h b/Common/Core/fwdtrackUtilities.h index 53d5f74f931..bc947d588f6 100644 --- a/Common/Core/fwdtrackUtilities.h +++ b/Common/Core/fwdtrackUtilities.h @@ -18,7 +18,6 @@ #ifndef COMMON_CORE_FWDTRACKUTILITIES_H_ #define COMMON_CORE_FWDTRACKUTILITIES_H_ -#include #include #include #include @@ -48,6 +47,16 @@ using SMatrix55 = ROOT::Math::SMatrix; using SMatrix5 = ROOT::Math::SVector; +template +concept is_fwd_track = requires(T t) { + { t.rAtAbsorberEnd() } -> std::same_as; +}; + +template +concept is_fwd_cov = requires(T t) { + { t.sigmaX() } -> std::same_as; +}; + /// Produce TrackParCovFwds for MFT and FwdTracks, w/ or w/o cov, with z shift template o2::track::TrackParCovFwd getTrackParCovFwdShift(TFwdTrack const& track, float zshift, TCovariance const&... covOpt) @@ -55,7 +64,7 @@ o2::track::TrackParCovFwd getTrackParCovFwdShift(TFwdTrack const& track, float z double chi2 = track.chi2(); if constexpr (sizeof...(covOpt) == 0) { // No covariance passed - if constexpr (std::is_same_v, aod::FwdTracks::iterator>) { + if constexpr (is_fwd_track) { if (track.trackType() == o2::aod::fwdtrack::ForwardTrackTypeEnum::MuonStandaloneTrack) { chi2 = track.chi2() * (2.f * track.nClusters() - 5.f); } @@ -63,7 +72,7 @@ o2::track::TrackParCovFwd getTrackParCovFwdShift(TFwdTrack const& track, float z } else { // Covariance passed using TCov = std::decay_t; - if constexpr (std::is_same_v) { + if constexpr (is_fwd_cov) { if (track.trackType() == o2::aod::fwdtrack::ForwardTrackTypeEnum::MuonStandaloneTrack) { chi2 = track.chi2() * (2.f * track.nClusters() - 5.f); } diff --git a/PWGDQ/Core/MixingHandler.h b/PWGDQ/Core/MixingHandler.h index 581ceba7725..bcff36bbf6d 100644 --- a/PWGDQ/Core/MixingHandler.h +++ b/PWGDQ/Core/MixingHandler.h @@ -24,7 +24,6 @@ #include -#include #include #include #include diff --git a/PWGEM/Dilepton/Core/EMEventCut.h b/PWGEM/Dilepton/Core/EMEventCut.h index b0450f5b575..d9671356e24 100644 --- a/PWGEM/Dilepton/Core/EMEventCut.h +++ b/PWGEM/Dilepton/Core/EMEventCut.h @@ -16,7 +16,7 @@ #ifndef PWGEM_DILEPTON_CORE_EMEVENTCUT_H_ #define PWGEM_DILEPTON_CORE_EMEVENTCUT_H_ -#include "PWGEM/Dilepton/DataModel/dileptonTables.h" +#include "PWGEM/Dilepton/DataModel/EvSelFlags.h" #include diff --git a/PWGEM/Dilepton/DataModel/EvSelFlags.h b/PWGEM/Dilepton/DataModel/EvSelFlags.h new file mode 100644 index 00000000000..0b05ff288eb --- /dev/null +++ b/PWGEM/Dilepton/DataModel/EvSelFlags.h @@ -0,0 +1,40 @@ +// Copyright 2019-2026 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. + +#ifndef PWGEM_DILEPTON_CORE_EVSELFLAGS_H +#define PWGEM_DILEPTON_CORE_EVSELFLAGS_H + +namespace o2::aod::emevsel +{ +// Event selection criteria. See O2Physics/Common/CCDB/EventSelectionParams.h +enum EventSelectionFlags { + kIsTriggerTVX = 0, // FT0 vertex (acceptable FT0C-FT0A time difference) at trigger level + kNoITSROFrameBorder, // bunch crossing is far from ITS RO Frame border + kNoTimeFrameBorder, // bunch crossing is far from Time Frame borders + kNoSameBunchPileup, // reject collisions in case of pileup with another collision in the same foundBC + kIsGoodZvtxFT0vsPV, // small difference between z-vertex from PV and from FT0 + kIsVertexITSTPC, // at least one ITS-TPC track (reject vertices built from ITS-only tracks) + kIsVertexTOFmatched, // at least one of vertex contributors is matched to TOF + kIsVertexTRDmatched, // at least one of vertex contributors is matched to TRD + kNoCollInTimeRangeNarrow, // no other collisions in specified time range (narrower than Strict) + kNoCollInTimeRangeStrict, // no other collisions in specified time range + kNoCollInTimeRangeStandard, // no other collisions in specified time range with per-collision multiplicity above threshold + kNoCollInRofStrict, // no other collisions in this Readout Frame + kNoCollInRofStandard, // no other collisions in this Readout Frame with per-collision multiplicity above threshold + kNoHighMultCollInPrevRof, // veto an event if FT0C amplitude in previous ITS ROF is above threshold + kIsGoodITSLayer3, // number of inactive chips on ITS layer 3 is below maximum allowed value + kIsGoodITSLayer0123, // numbers of inactive chips on ITS layers 0-3 are below maximum allowed values + kIsGoodITSLayersAll, // numbers of inactive chips on all ITS layers are below maximum allowed values + kNsel // counter +}; +} // namespace o2::aod::emevsel + +#endif // PWGEM_DILEPTON_CORE_EVSELFLAGS_H diff --git a/PWGEM/Dilepton/DataModel/dileptonTables.h b/PWGEM/Dilepton/DataModel/dileptonTables.h index aa65acc3893..b1c306f17fe 100644 --- a/PWGEM/Dilepton/DataModel/dileptonTables.h +++ b/PWGEM/Dilepton/DataModel/dileptonTables.h @@ -9,6 +9,8 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. +#include "EvSelFlags.h" + #include "Common/CCDB/EventSelectionParams.h" #include "Common/Core/RecoDecay.h" #include "Common/DataModel/Centrality.h" @@ -66,28 +68,6 @@ namespace o2::aod namespace emevsel { -// Event selection criteria. See O2Physics/Common/CCDB/EventSelectionParams.h -enum EventSelectionFlags { - kIsTriggerTVX = 0, // FT0 vertex (acceptable FT0C-FT0A time difference) at trigger level - kNoITSROFrameBorder, // bunch crossing is far from ITS RO Frame border - kNoTimeFrameBorder, // bunch crossing is far from Time Frame borders - kNoSameBunchPileup, // reject collisions in case of pileup with another collision in the same foundBC - kIsGoodZvtxFT0vsPV, // small difference between z-vertex from PV and from FT0 - kIsVertexITSTPC, // at least one ITS-TPC track (reject vertices built from ITS-only tracks) - kIsVertexTOFmatched, // at least one of vertex contributors is matched to TOF - kIsVertexTRDmatched, // at least one of vertex contributors is matched to TRD - kNoCollInTimeRangeNarrow, // no other collisions in specified time range (narrower than Strict) - kNoCollInTimeRangeStrict, // no other collisions in specified time range - kNoCollInTimeRangeStandard, // no other collisions in specified time range with per-collision multiplicity above threshold - kNoCollInRofStrict, // no other collisions in this Readout Frame - kNoCollInRofStandard, // no other collisions in this Readout Frame with per-collision multiplicity above threshold - kNoHighMultCollInPrevRof, // veto an event if FT0C amplitude in previous ITS ROF is above threshold - kIsGoodITSLayer3, // number of inactive chips on ITS layer 3 is below maximum allowed value - kIsGoodITSLayer0123, // numbers of inactive chips on ITS layers 0-3 are below maximum allowed values - kIsGoodITSLayersAll, // numbers of inactive chips on all ITS layers are below maximum allowed values - kNsel // counter -}; - DECLARE_SOA_BITMAP_COLUMN(Selection, selection, 32); //! Bitmask of selection flags DECLARE_SOA_DYNAMIC_COLUMN(Sel8, sel8, [](uint32_t selection_bit) -> bool { return (selection_bit & BIT(o2::aod::emevsel::kIsTriggerTVX)) && (selection_bit & BIT(o2::aod::emevsel::kNoTimeFrameBorder)) && (selection_bit & BIT(o2::aod::emevsel::kNoITSROFrameBorder)); }); @@ -149,7 +129,6 @@ uint32_t reduceSelectionBit(TBC const& bc) } return bitMap; } - } // namespace emevsel namespace emevent diff --git a/PWGEM/PhotonMeson/Core/DalitzEECut.h b/PWGEM/PhotonMeson/Core/DalitzEECut.h index 293a52424c0..94b13b32612 100644 --- a/PWGEM/PhotonMeson/Core/DalitzEECut.h +++ b/PWGEM/PhotonMeson/Core/DalitzEECut.h @@ -18,9 +18,9 @@ #include "PWGEM/Dilepton/Utils/EMTrackUtilities.h" #include "PWGEM/Dilepton/Utils/PairUtilities.h" +#include "PWGEM/PhotonMeson/Utils/TrackSelection.h" #include -#include #include // IWYU pragma: keep (do not replace with Math/Vector4Dfwd.h) #include @@ -71,7 +71,7 @@ class DalitzEECut : public TNamed kTPConly = 1, }; - template + template bool IsSelected(TTrack1 const& t1, TTrack2 const& t2, float bz) const { if (!IsSelectedTrack(t1) || !IsSelectedTrack(t2)) { @@ -85,7 +85,7 @@ class DalitzEECut : public TNamed return true; } - template + template bool IsSelectedPair(TTrack1 const& t1, TTrack2 const& t2, const float bz) const { ROOT::Math::PtEtaPhiMVector v1(t1.pt(), t1.eta(), t1.phi(), o2::constants::physics::MassElectron); @@ -107,7 +107,7 @@ class DalitzEECut : public TNamed return true; } - template + template bool IsSelectedTrack(TTrack const& track, TCollision const& = 0) const { if (!track.hasITS()) { @@ -193,7 +193,7 @@ class DalitzEECut : public TNamed return true; } - template + template bool PassPID(T const& track) const { switch (mPIDScheme) { @@ -211,7 +211,7 @@ class DalitzEECut : public TNamed } } - template + template bool PassTPConly(T const& track) const { bool is_el_included_TPC = mMinTPCNsigmaEl < track.tpcNSigmaEl() && track.tpcNSigmaEl() < mMaxTPCNsigmaEl; @@ -219,7 +219,7 @@ class DalitzEECut : public TNamed return is_el_included_TPC && is_pi_excluded_TPC; } - template + template bool PassTOFif(T const& track) const { bool is_el_included_TPC = mMinTPCNsigmaEl < track.tpcNSigmaEl() && track.tpcNSigmaEl() < mMaxTPCNsigmaEl; @@ -228,7 +228,7 @@ class DalitzEECut : public TNamed return is_el_included_TPC && is_pi_excluded_TPC && is_el_included_TOF; } - template + template bool IsSelectedTrack(T const& track, const DalitzEECuts& cut) const { switch (cut) { diff --git a/PWGEM/PhotonMeson/Core/EMCPhotonCut.cxx b/PWGEM/PhotonMeson/Core/EMCPhotonCut.cxx index 9e75d9e558e..e10d0398c7a 100644 --- a/PWGEM/PhotonMeson/Core/EMCPhotonCut.cxx +++ b/PWGEM/PhotonMeson/Core/EMCPhotonCut.cxx @@ -17,6 +17,7 @@ #include "PWGJE/DataModel/EMCALClusters.h" +#include #include #include @@ -27,6 +28,52 @@ ClassImp(EMCPhotonCut); const char* EMCPhotonCut::mCutNames[static_cast(EMCPhotonCut::EMCPhotonCuts::kNCuts)] = {"Definition", "Energy", "NCell", "M02", "Timing", "TrackMatching", "SecTrackMatching", "Exotic"}; +void EMCPhotonCut::addQAHistograms(o2::framework::HistogramRegistry* fRegistry) const +{ + if (mDoQA && fRegistry != nullptr) { + const o2::framework::AxisSpec thAxisClusterEnergy{500, 0, 50, "#it{E}_{cls} (GeV)"}; + const o2::framework::AxisSpec thAxisMomentum{250, 0., 25., "#it{p}_{T} (GeV/#it{c})"}; + const o2::framework::AxisSpec thAxisDEta{200, -0.1, 0.1, "#Delta#eta"}; + const o2::framework::AxisSpec thAxisDPhi{200, -0.1, 0.1, "#Delta#varphi (rad)"}; + const o2::framework::AxisSpec thAxisEnergy{500, 0., 50., "#it{E} (GeV)"}; + const o2::framework::AxisSpec thAxisEta{320, -0.8, 0.8, "#eta"}; + const o2::framework::AxisSpec thAxisPhi{500, 0, o2::constants::math::TwoPI, "#varphi (rad)"}; + const o2::framework::AxisSpec thAxisNCell{51, -0.5, 50.5, "#it{N}_{cell}"}; + const o2::framework::AxisSpec thAxisM02{200, 0, 2.0, "#it{M}_{02}"}; + const o2::framework::AxisSpec thAxisTime{300, -150, +150, "#it{t}_{cls} (ns)"}; + const o2::framework::AxisSpec thAxisEoverP{400, 0, 10., "#it{E}_{cls}/#it{p}_{track} (#it{c})"}; + + fRegistry->add("QA/Cluster/before/hE", "E_{cluster};#it{E}_{cluster} (GeV);#it{N}_{cluster}", o2::framework::HistType::kTH1D, {thAxisClusterEnergy}, true); + fRegistry->add("QA/Cluster/before/hPt", "Transverse momenta of clusters;#it{p}_{T} (GeV/c);#it{N}_{cluster}", o2::framework::HistType::kTH1D, {thAxisClusterEnergy}, true); + fRegistry->add("QA/Cluster/before/hNgamma", "Number of #gamma candidates per collision;#it{N}_{#gamma} per collision;#it{N}_{collisions}", o2::framework::HistType::kTH1D, {{1001, -0.5f, 1000.5f}}, true); + fRegistry->add("QA/Cluster/before/hEtaPhi", "#eta vs #varphi;#eta;#varphi (rad.)", o2::framework::HistType::kTH2F, {thAxisEta, thAxisPhi}, true); + fRegistry->add("QA/Cluster/before/hNCell", "#it{N}_{cells};N_{cells} (GeV);#it{E}_{cluster} (GeV)", o2::framework::HistType::kTH2F, {thAxisNCell, thAxisClusterEnergy}, true); + fRegistry->add("QA/Cluster/before/hM02", "Long ellipse axis;#it{M}_{02} (cm);#it{E}_{cluster} (GeV)", o2::framework::HistType::kTH2F, {thAxisM02, thAxisClusterEnergy}, true); + fRegistry->add("QA/Cluster/before/hTime", "Cluster time;#it{t}_{cls} (ns);#it{E}_{cluster} (GeV)", o2::framework::HistType::kTH2F, {thAxisTime, thAxisClusterEnergy}, true); + + fRegistry->addClone("QA/Cluster/before/", "QA/Cluster/after/"); + + auto hClusterQualityCuts = fRegistry->add("QA/Cluster/hClusterQualityCuts", "Energy at which clusters are removed by a given cut;;#it{E} (GeV)", o2::framework::HistType::kTH2F, {{static_cast(EMCPhotonCut::EMCPhotonCuts::kNCuts) + 2, -0.5, static_cast(EMCPhotonCut::EMCPhotonCuts::kNCuts) + 1.5}, thAxisClusterEnergy}, true); + hClusterQualityCuts->GetXaxis()->SetBinLabel(1, "In"); + hClusterQualityCuts->GetXaxis()->SetBinLabel(2, "Definition"); + hClusterQualityCuts->GetXaxis()->SetBinLabel(3, "Energy"); + hClusterQualityCuts->GetXaxis()->SetBinLabel(4, "NCell"); + hClusterQualityCuts->GetXaxis()->SetBinLabel(5, "M02"); + hClusterQualityCuts->GetXaxis()->SetBinLabel(6, "Timing"); + hClusterQualityCuts->GetXaxis()->SetBinLabel(7, "TM"); + hClusterQualityCuts->GetXaxis()->SetBinLabel(8, "Sec. TM"); + hClusterQualityCuts->GetXaxis()->SetBinLabel(9, "Exotic"); + hClusterQualityCuts->GetXaxis()->SetBinLabel(10, "Out"); + + fRegistry->add("QA/Cluster/hTrackdEtadPhi", "d#eta vs. d#varphi of matched tracks;d#eta;d#varphi (rad.)", o2::framework::HistType::kTH2F, {thAxisDEta, thAxisDPhi}, true); + fRegistry->add("QA/Cluster/hTrackdEtaPt", "d#eta vs. track pT of matched tracks;d#eta;d#varphi (rad.)", o2::framework::HistType::kTH2F, {thAxisDEta, thAxisMomentum}, true); + fRegistry->add("QA/Cluster/hTrackdPhiPt", "d#varphi vs. track pT of matched tracks;d#eta;d#varphi (rad.)", o2::framework::HistType::kTH2F, {thAxisDPhi, thAxisMomentum}, true); + fRegistry->add("QA/Cluster/hSecTrackdEtadPhi", "d#eta vs. d#varphi of matched secondary tracks;d#eta;d#varphi (rad.)", o2::framework::HistType::kTH2F, {thAxisDEta, thAxisDPhi}, true); + fRegistry->add("QA/Cluster/hSecTrackdEtaPt", "d#eta vs. track pT of matched secondary tracks;d#eta;d#varphi (rad.)", o2::framework::HistType::kTH2F, {thAxisDEta, thAxisMomentum}, true); + fRegistry->add("QA/Cluster/hSecTrackdPhiPt", "d#varphi vs. track pT of matched secondary tracks;d#eta;d#varphi (rad.)", o2::framework::HistType::kTH2F, {thAxisDPhi, thAxisMomentum}, true); + } +} + void EMCPhotonCut::SetClusterizer(std::string clusterDefinitionString) { mDefinition = static_cast(o2::aod::emcalcluster::getClusterDefinitionFromString(clusterDefinitionString)); diff --git a/PWGEM/PhotonMeson/Core/EMCPhotonCut.h b/PWGEM/PhotonMeson/Core/EMCPhotonCut.h index bba559ed8cb..d22f19ef786 100644 --- a/PWGEM/PhotonMeson/Core/EMCPhotonCut.h +++ b/PWGEM/PhotonMeson/Core/EMCPhotonCut.h @@ -17,10 +17,9 @@ #define PWGEM_PHOTONMESON_CORE_EMCPHOTONCUT_H_ #include "PWGEM/PhotonMeson/Core/EMBitFlags.h" -#include "PWGEM/PhotonMeson/DataModel/gammaTables.h" +#include "PWGEM/PhotonMeson/Utils/TrackSelection.h" #include -#include #include #include @@ -39,9 +38,6 @@ #include #include -template -concept is_optional_table = o2::soa::is_table || std::is_same_v; - template static constexpr bool HasPrimaries = !std::is_same_v; @@ -49,21 +45,21 @@ template static constexpr bool HasSecondaries = !std::is_same_v; template -concept IsNonLinIterator = o2::soa::is_iterator && requires(T t) { +concept IsNonLinIterator = requires(T t) { // Check that the *elements* of the container have the required methods: { t.corrE() } -> std::same_as; { t.corrPt() } -> std::same_as; }; template -concept IsNonLinContainer = o2::soa::is_table && requires(T t) { +concept IsNonLinContainer = requires(T t) { // Check that the *elements* of the container have the required methods: { t.begin().corrE() } -> std::same_as; { t.begin().corrPt() } -> std::same_as; }; template -concept IsTrackIterator = o2::soa::is_iterator && requires(T t) { +concept IsTrackIterator = requires(T t) { // Check that the *elements* of the container have the required methods: { t.deltaEta() } -> std::same_as; { t.deltaPhi() } -> std::same_as; @@ -72,7 +68,7 @@ concept IsTrackIterator = o2::soa::is_iterator && requires(T t) { }; template -concept IsTrackContainer = o2::soa::is_table && requires(T t) { +concept IsTrackContainer = requires(T t) { // Check that the *elements* of the container have the required methods: { t.begin().deltaEta() } -> std::same_as; { t.begin().deltaPhi() } -> std::same_as; @@ -82,7 +78,6 @@ concept IsTrackContainer = o2::soa::is_table && requires(T t) { template concept HasTrackMatching = - o2::soa::is_iterator && requires(Cluster cluster) { // requires that the following are valid calls: { cluster.deltaEta() } -> std::convertible_to>; @@ -93,7 +88,6 @@ concept HasTrackMatching = template concept HasSecondaryMatching = - o2::soa::is_iterator && requires(Cluster cluster) { // requires that the following are valid calls: { cluster.deltaEtaSec() } -> std::convertible_to>; @@ -135,7 +129,7 @@ class EMCPhotonCut : public TNamed static const char* mCutNames[static_cast(EMCPhotonCuts::kNCuts)]; - static constexpr auto getClusterId(o2::soa::is_iterator auto const& t) + static constexpr auto getClusterId(IsTrackIterator auto const& t) { if constexpr (requires { t.emEmcClusterId(); }) { return t.emEmcClusterId(); @@ -148,51 +142,7 @@ class EMCPhotonCut : public TNamed /// \brief add histograms to registry /// \param fRegistry pointer to histogram registry - void addQAHistograms(o2::framework::HistogramRegistry* fRegistry = nullptr) const - { - if (mDoQA && fRegistry != nullptr) { - const o2::framework::AxisSpec thAxisClusterEnergy{500, 0, 50, "#it{E}_{cls} (GeV)"}; - const o2::framework::AxisSpec thAxisMomentum{250, 0., 25., "#it{p}_{T} (GeV/#it{c})"}; - const o2::framework::AxisSpec thAxisDEta{200, -0.1, 0.1, "#Delta#eta"}; - const o2::framework::AxisSpec thAxisDPhi{200, -0.1, 0.1, "#Delta#varphi (rad)"}; - const o2::framework::AxisSpec thAxisEnergy{500, 0., 50., "#it{E} (GeV)"}; - const o2::framework::AxisSpec thAxisEta{320, -0.8, 0.8, "#eta"}; - const o2::framework::AxisSpec thAxisPhi{500, 0, o2::constants::math::TwoPI, "#varphi (rad)"}; - const o2::framework::AxisSpec thAxisNCell{51, -0.5, 50.5, "#it{N}_{cell}"}; - const o2::framework::AxisSpec thAxisM02{200, 0, 2.0, "#it{M}_{02}"}; - const o2::framework::AxisSpec thAxisTime{300, -150, +150, "#it{t}_{cls} (ns)"}; - const o2::framework::AxisSpec thAxisEoverP{400, 0, 10., "#it{E}_{cls}/#it{p}_{track} (#it{c})"}; - - fRegistry->add("QA/Cluster/before/hE", "E_{cluster};#it{E}_{cluster} (GeV);#it{N}_{cluster}", o2::framework::HistType::kTH1D, {thAxisClusterEnergy}, true); - fRegistry->add("QA/Cluster/before/hPt", "Transverse momenta of clusters;#it{p}_{T} (GeV/c);#it{N}_{cluster}", o2::framework::HistType::kTH1D, {thAxisClusterEnergy}, true); - fRegistry->add("QA/Cluster/before/hNgamma", "Number of #gamma candidates per collision;#it{N}_{#gamma} per collision;#it{N}_{collisions}", o2::framework::HistType::kTH1D, {{1001, -0.5f, 1000.5f}}, true); - fRegistry->add("QA/Cluster/before/hEtaPhi", "#eta vs #varphi;#eta;#varphi (rad.)", o2::framework::HistType::kTH2F, {thAxisEta, thAxisPhi}, true); - fRegistry->add("QA/Cluster/before/hNCell", "#it{N}_{cells};N_{cells} (GeV);#it{E}_{cluster} (GeV)", o2::framework::HistType::kTH2F, {thAxisNCell, thAxisClusterEnergy}, true); - fRegistry->add("QA/Cluster/before/hM02", "Long ellipse axis;#it{M}_{02} (cm);#it{E}_{cluster} (GeV)", o2::framework::HistType::kTH2F, {thAxisM02, thAxisClusterEnergy}, true); - fRegistry->add("QA/Cluster/before/hTime", "Cluster time;#it{t}_{cls} (ns);#it{E}_{cluster} (GeV)", o2::framework::HistType::kTH2F, {thAxisTime, thAxisClusterEnergy}, true); - - fRegistry->addClone("QA/Cluster/before/", "QA/Cluster/after/"); - - auto hClusterQualityCuts = fRegistry->add("QA/Cluster/hClusterQualityCuts", "Energy at which clusters are removed by a given cut;;#it{E} (GeV)", o2::framework::HistType::kTH2F, {{static_cast(EMCPhotonCut::EMCPhotonCuts::kNCuts) + 2, -0.5, static_cast(EMCPhotonCut::EMCPhotonCuts::kNCuts) + 1.5}, thAxisClusterEnergy}, true); - hClusterQualityCuts->GetXaxis()->SetBinLabel(1, "In"); - hClusterQualityCuts->GetXaxis()->SetBinLabel(2, "Definition"); - hClusterQualityCuts->GetXaxis()->SetBinLabel(3, "Energy"); - hClusterQualityCuts->GetXaxis()->SetBinLabel(4, "NCell"); - hClusterQualityCuts->GetXaxis()->SetBinLabel(5, "M02"); - hClusterQualityCuts->GetXaxis()->SetBinLabel(6, "Timing"); - hClusterQualityCuts->GetXaxis()->SetBinLabel(7, "TM"); - hClusterQualityCuts->GetXaxis()->SetBinLabel(8, "Sec. TM"); - hClusterQualityCuts->GetXaxis()->SetBinLabel(9, "Exotic"); - hClusterQualityCuts->GetXaxis()->SetBinLabel(10, "Out"); - - fRegistry->add("QA/Cluster/hTrackdEtadPhi", "d#eta vs. d#varphi of matched tracks;d#eta;d#varphi (rad.)", o2::framework::HistType::kTH2F, {thAxisDEta, thAxisDPhi}, true); - fRegistry->add("QA/Cluster/hTrackdEtaPt", "d#eta vs. track pT of matched tracks;d#eta;d#varphi (rad.)", o2::framework::HistType::kTH2F, {thAxisDEta, thAxisMomentum}, true); - fRegistry->add("QA/Cluster/hTrackdPhiPt", "d#varphi vs. track pT of matched tracks;d#eta;d#varphi (rad.)", o2::framework::HistType::kTH2F, {thAxisDPhi, thAxisMomentum}, true); - fRegistry->add("QA/Cluster/hSecTrackdEtadPhi", "d#eta vs. d#varphi of matched secondary tracks;d#eta;d#varphi (rad.)", o2::framework::HistType::kTH2F, {thAxisDEta, thAxisDPhi}, true); - fRegistry->add("QA/Cluster/hSecTrackdEtaPt", "d#eta vs. track pT of matched secondary tracks;d#eta;d#varphi (rad.)", o2::framework::HistType::kTH2F, {thAxisDEta, thAxisMomentum}, true); - fRegistry->add("QA/Cluster/hSecTrackdPhiPt", "d#varphi vs. track pT of matched secondary tracks;d#eta;d#varphi (rad.)", o2::framework::HistType::kTH2F, {thAxisDPhi, thAxisMomentum}, true); - } - } + void addQAHistograms(o2::framework::HistogramRegistry* fRegistry = nullptr) const; /// \brief performs check if track is matched with given cluster /// \param cluster cluster to be checked @@ -201,7 +151,7 @@ class EMCPhotonCut : public TNamed /// \param GetEtaCut lambda to get the eta cut value /// \param GetPhiCut lambda to get the phi cut value /// \param applyEoverP bool to check if E/p should be checked (for secondaries we do not check this!) - bool checkTrackMatching(o2::soa::is_iterator auto const& cluster, IsTrackIterator auto& emcmatchedtrack, o2::soa::RowViewSentinel const emcmatchedtrackEnd, bool applyEoverP, auto GetEtaCut, auto GetPhiCut, o2::framework::HistogramRegistry* fRegistry = nullptr, TrackType trackType = TrackType::kPrimary) const + bool checkTrackMatching(is_iterator auto const& cluster, IsTrackIterator auto& emcmatchedtrack, is_sentinel auto const emcmatchedtrackEnd, bool applyEoverP, auto GetEtaCut, auto GetPhiCut, o2::framework::HistogramRegistry* fRegistry = nullptr, TrackType trackType = TrackType::kPrimary) const { // advance to cluster while (emcmatchedtrack != emcmatchedtrackEnd && getClusterId(emcmatchedtrack) < cluster.globalIndex()) { @@ -250,7 +200,7 @@ class EMCPhotonCut : public TNamed return true; // all tracks checked, cluster survives } - void fillBeforeClusterHistogram(o2::soa::is_iterator auto const& cluster, o2::framework::HistogramRegistry* fRegistry = nullptr) const + void fillBeforeClusterHistogram(is_iterator auto const& cluster, o2::framework::HistogramRegistry* fRegistry = nullptr) const { if (mDoQA == false || fRegistry == nullptr) { @@ -266,7 +216,7 @@ class EMCPhotonCut : public TNamed fRegistry->fill(HIST("QA/Cluster/before/hTime"), cluster.time(), cluster.e()); } - void fillAfterClusterHistogram(o2::soa::is_iterator auto const& cluster, o2::framework::HistogramRegistry* fRegistry = nullptr) const + void fillAfterClusterHistogram(is_iterator auto const& cluster, o2::framework::HistogramRegistry* fRegistry = nullptr) const { if (mDoQA == false || fRegistry == nullptr) { @@ -288,7 +238,7 @@ class EMCPhotonCut : public TNamed /// \param matchedTracks matched primary tracks table /// \param matchedSecondaries matched secondary tracks table /// \param fRegistry o2::framework::HistogramRegistry pointer of the main task - void AreSelectedRunning(EMBitFlags& flags, o2::soa::is_table auto const& clusters, IsTrackContainer auto const& emcmatchedtracks, IsTrackContainer auto const& secondaries, o2::framework::HistogramRegistry* fRegistry = nullptr) const + void AreSelectedRunning(EMBitFlags& flags, auto const& clusters, IsTrackContainer auto const& emcmatchedtracks, IsTrackContainer auto const& secondaries, o2::framework::HistogramRegistry* fRegistry = nullptr) const { if (clusters.size() <= 0) { return; @@ -332,7 +282,7 @@ class EMCPhotonCut : public TNamed /// \param secondaryIter current iterator of matched secondary tracks /// \param secondaryEnd end iterator of matched secondary tracks /// \return true if cluster survives all cuts else false - bool IsSelectedRunning(o2::soa::is_iterator auto const& cluster, IsTrackIterator auto& emcmatchedtrackIter, o2::soa::RowViewSentinel const emcmatchedtrackEnd, IsTrackIterator auto& secondaryIter, o2::soa::RowViewSentinel const secondaryEnd, o2::framework::HistogramRegistry* fRegistry = nullptr) const + bool IsSelectedRunning(is_iterator auto const& cluster, IsTrackIterator auto& emcmatchedtrackIter, is_sentinel auto const emcmatchedtrackEnd, IsTrackIterator auto& secondaryIter, is_sentinel auto const secondaryEnd, o2::framework::HistogramRegistry* fRegistry = nullptr) const { const bool doQA = mDoQA && fRegistry != nullptr; if (!IsSelectedEMCalRunning(EMCPhotonCuts::kDefinition, cluster)) { @@ -398,7 +348,7 @@ class EMCPhotonCut : public TNamed /// \param cut enum of the cluster cut to check /// \param cluster cluster to check /// \return true if cluster survives cut else false - bool IsSelectedEMCalRunning(const EMCPhotonCuts& cut, o2::soa::is_iterator auto const& cluster) const + bool IsSelectedEMCalRunning(const EMCPhotonCuts& cut, is_iterator auto const& cluster) const { switch (cut) { case EMCPhotonCuts::kDefinition: @@ -440,7 +390,7 @@ class EMCPhotonCut : public TNamed /// \param matchedTrackIter current iterator of matched primary or secondary tracks /// \param matchedTrackEnd end iterator of matched primary or secondary tracks /// \return true if cluster survives cut else false - bool IsSelectedEMCalRunning(const EMCPhotonCuts& cut, o2::soa::is_iterator auto const& cluster, IsTrackIterator auto& matchedTrackIter, o2::soa::RowViewSentinel const matchedTrackEnd, o2::framework::HistogramRegistry* fRegistry = nullptr) const + bool IsSelectedEMCalRunning(const EMCPhotonCuts& cut, is_iterator auto const& cluster, IsTrackIterator auto& matchedTrackIter, is_sentinel auto const matchedTrackEnd, o2::framework::HistogramRegistry* fRegistry = nullptr) const { switch (cut) { case EMCPhotonCuts::kTM: @@ -459,7 +409,7 @@ class EMCPhotonCut : public TNamed /// \param matchedTracks subtable of the matched primary tracks (optional) /// \param matchedSecondaries subtable of the matched secondary tracks (optional) /// \return true if cluster survives all cuts else false - template + template bool IsSelected(Cluster const& cluster, TMatchedTracks const& emcmatchedtracks = nullptr, TMatchedSecondaries const& secondaries = nullptr) const { if (!IsSelectedEMCal(EMCPhotonCuts::kDefinition, cluster)) { @@ -495,7 +445,7 @@ class EMCPhotonCut : public TNamed /// \param matchedTracks subtable of the matched primary tracks (optional) /// \param matchedSecondaries subtable of the matched secondary tracks (optional) /// \return true if cluster survives cut else false - template + template bool IsSelectedEMCal(const EMCPhotonCuts& cut, Cluster const& cluster, TMatchedTracks const& emcmatchedtracks = nullptr) const { switch (cut) { diff --git a/PWGEM/PhotonMeson/Core/PHOSPhotonCut.h b/PWGEM/PhotonMeson/Core/PHOSPhotonCut.h index ea7fd3440ab..8c0287bc71b 100644 --- a/PWGEM/PhotonMeson/Core/PHOSPhotonCut.h +++ b/PWGEM/PhotonMeson/Core/PHOSPhotonCut.h @@ -16,7 +16,7 @@ #ifndef PWGEM_PHOTONMESON_CORE_PHOSPHOTONCUT_H_ #define PWGEM_PHOTONMESON_CORE_PHOSPHOTONCUT_H_ -#include +#include "PWGEM/PhotonMeson/Utils/TrackSelection.h" #include @@ -38,7 +38,7 @@ class PHOSPhotonCut : public TNamed static const char* mCutNames[static_cast(PHOSPhotonCuts::kNCuts)]; // Temporary function to check if track passes selection criteria. To be replaced by framework filters. - template + template bool IsSelected(Cluster const& cluster) const { // auto track = cluster.template MatchedTrack_as(); //please implement a column to point matched track index (DECLARE_SOA_ARRAY_INDEX_COLUMN) in SkimPHOSClusters table. @@ -71,7 +71,7 @@ class PHOSPhotonCut : public TNamed } // Temporary function to check if track passes a given selection criteria. To be replaced by framework filters. - template + template bool IsSelectedCluster(Cluster const& cls, const PHOSPhotonCuts& cut) const { switch (cut) { diff --git a/PWGEM/PhotonMeson/Core/V0PhotonCut.h b/PWGEM/PhotonMeson/Core/V0PhotonCut.h index 741f72f8df9..c371b2e0a71 100644 --- a/PWGEM/PhotonMeson/Core/V0PhotonCut.h +++ b/PWGEM/PhotonMeson/Core/V0PhotonCut.h @@ -23,7 +23,6 @@ #include #include -#include #include #include #include @@ -158,12 +157,17 @@ namespace o2::analysis::em::v0 { template -concept IsNonLinIterator = o2::soa::is_iterator && requires(T t) { +concept IsNonLinIterator = requires(T t) { // Check that the *elements* of the container have the required methods: { t.corrPt() } -> std::same_as; }; } // namespace o2::analysis::em::v0 +template +concept is_table = requires(T t) { + { t.begin() } -> std::same_as::iterator>; +}; + class V0PhotonCut : public TNamed { public: @@ -302,7 +306,7 @@ class V0PhotonCut : public TNamed } } - template + template void fillBeforePhotonHistogram(TV0 const& v0, TLeg1 const& pos, TLeg2 const& ele, o2::framework::HistogramRegistry* fRegistry = nullptr) const { @@ -332,7 +336,7 @@ class V0PhotonCut : public TNamed fRegistry->fill(HIST("QA/V0Photon/before/Neg/hTPCHits"), ele.tpcNClsFound(), ele.tpcNClsCrossedRows()); } - template + template void fillAfterPhotonHistogram(TV0 const& v0, TLeg1 const& pos, TLeg2 const& ele, o2::framework::HistogramRegistry* fRegistry = nullptr) const { @@ -364,7 +368,7 @@ class V0PhotonCut : public TNamed /// \brief creates a mask for the V0s if they are too close to another V0 and have higher chi^2 /// \param v0s V0 table - template + template void createCloseV0CutMask(TV0 const& v0s) const { const bool useDistance3D = (mTooCloseType == TooCloseCuts::kDistance3D); @@ -478,7 +482,7 @@ class V0PhotonCut : public TNamed /// \brief check if given v0 photon survives all cuts /// \param flags EMBitFlags where results will be stored /// \param v0s v0 photon table to check - template + template void AreSelectedRunning(EMBitFlags& flags, TV0 const& v0s, o2::framework::HistogramRegistry* fRegistry = nullptr) const { if (v0s.size() <= 0) { @@ -512,7 +516,7 @@ class V0PhotonCut : public TNamed } } - template + template bool IsSelected(TV0 const& v0, o2::framework::HistogramRegistry* fRegistry = nullptr) const { auto pos = v0.template posTrack_as(); @@ -820,7 +824,7 @@ class V0PhotonCut : public TNamed return true; } - template + template bool IsSelectedV0(T const& v0, const V0PhotonCuts& cut) const { switch (cut) { @@ -1064,7 +1068,7 @@ class V0PhotonCut : public TNamed return mMlBDTScores; } - template + template bool IsConversionPointInAcceptance(TMCPhoton const& mcphoton, float convRadius) const { // eta cut diff --git a/PWGEM/PhotonMeson/Tasks/photonhbt.cxx b/PWGEM/PhotonMeson/Tasks/photonhbt.cxx index d8f2c5c7da8..7bdf150f66b 100644 --- a/PWGEM/PhotonMeson/Tasks/photonhbt.cxx +++ b/PWGEM/PhotonMeson/Tasks/photonhbt.cxx @@ -133,7 +133,7 @@ static constexpr float kMinSigma = 1e-9; struct Photonhbt { - template + template static inline V0Combo classifyV0Combo(TGamma const& g) { const auto pos = g.template posTrack_as(); diff --git a/PWGEM/PhotonMeson/Utils/ClusterHistograms.h b/PWGEM/PhotonMeson/Utils/ClusterHistograms.h index 6e51d09ab40..57703d5b229 100644 --- a/PWGEM/PhotonMeson/Utils/ClusterHistograms.h +++ b/PWGEM/PhotonMeson/Utils/ClusterHistograms.h @@ -105,7 +105,7 @@ inline void fillTrackQA2D( reg->fill(histbase + HIST("hTrackdPhiPt"), dPhi, pt, w); } -template +template inline void fillClusterHistograms(o2::framework::HistogramRegistry* fRegistry, TCluster cluster, bool do2DQA, float weight = 1.f, TMatchedTracks const& primTracks = nullptr, TMatchedSecondaries const& secTracks = nullptr) { const auto e = cluster.e(); diff --git a/PWGEM/PhotonMeson/Utils/TrackSelection.h b/PWGEM/PhotonMeson/Utils/TrackSelection.h index 941a7ea2bc0..1d63c2d3770 100644 --- a/PWGEM/PhotonMeson/Utils/TrackSelection.h +++ b/PWGEM/PhotonMeson/Utils/TrackSelection.h @@ -16,11 +16,34 @@ #ifndef PWGEM_PHOTONMESON_UTILS_TRACKSELECTION_H_ #define PWGEM_PHOTONMESON_UTILS_TRACKSELECTION_H_ -#include - #include #include +#include +#include + +template +concept is_iterator = requires(T t) { + typename std::decay_t::policy_t; + typename std::decay_t::all_columns; + t.getIndexBindings(); +}; + +template +concept is_sentinel = requires(T t) { + requires(std::same_as); +}; + +template +concept is_track_with_extra = requires(T t) { + { t.hasITS() } -> std::same_as; + { t.hasTPC() } -> std::same_as; +}; + +template +concept is_mc_particle = requires(T t) { + { t.pdgCode() } -> std::same_as; +}; namespace o2::pwgem::photonmeson { @@ -32,7 +55,7 @@ namespace o2::pwgem::photonmeson * @param track track * @return true if has both */ -template +template inline bool isITSTPCTrack(TTrack const& track) { return track.hasITS() && track.hasTPC(); @@ -45,7 +68,7 @@ inline bool isITSTPCTrack(TTrack const& track) * @param track track * @return true if has both */ -template +template inline bool isTPCTRDTrack(TTrack const& track) { return !track.hasITS() && track.hasTPC() && track.hasTRD() && !track.hasTOF(); @@ -58,7 +81,7 @@ inline bool isTPCTRDTrack(TTrack const& track) * @param track track * @return true if has all */ -template +template inline bool isITSTPCTRDTrack(TTrack const& track) { return track.hasITS() && track.hasTPC() && track.hasTRD() && !track.hasTOF(); @@ -70,7 +93,7 @@ inline bool isITSTPCTRDTrack(TTrack const& track) * @param track track * @return true if has both */ -template +template inline bool isTPCTOFTrack(TTrack const& track) { return !track.hasITS() && track.hasTPC() && !track.hasTRD() && track.hasTOF(); @@ -82,7 +105,7 @@ inline bool isTPCTOFTrack(TTrack const& track) * @param track track * @return true if has all */ -template +template inline bool isTPCTRDTOFTrack(TTrack const& track) { return !track.hasITS() && track.hasTPC() && track.hasTRD() && track.hasTOF(); @@ -94,7 +117,7 @@ inline bool isTPCTRDTOFTrack(TTrack const& track) * @param track track * @return true if has all */ -template +template inline bool isITSTPCTRDTOFTrack(TTrack const& track) { return track.hasITS() && track.hasTPC() && track.hasTRD() && track.hasTOF(); @@ -107,7 +130,7 @@ inline bool isITSTPCTRDTOFTrack(TTrack const& track) * @param track track * @return true if tracks is TPC-only */ -template +template inline bool isTPConlyTrack(TTrack const& track) { return !track.hasITS() && track.hasTPC() && !track.hasTRD() && !track.hasTOF(); @@ -120,7 +143,7 @@ inline bool isTPConlyTrack(TTrack const& track) * @param track track * @return true if tracks is ITS-only */ -template +template inline bool isITSonlyTrack(TTrack const& track) { return track.hasITS() && !track.hasTPC() && !track.hasTRD() && !track.hasTOF(); @@ -134,7 +157,7 @@ inline bool isITSonlyTrack(TTrack const& track) * @param track1 track from daughter 1 * @return true if V0 pairs are ITSTPC-tracks */ -template +template inline bool isITSTPC_ITSTPC(TTrack const& track0, TTrack const& track1) { return isITSTPCTrack(track0) && isITSTPCTrack(track1); @@ -148,7 +171,7 @@ inline bool isITSTPC_ITSTPC(TTrack const& track0, TTrack const& track1) * @param track1 track from daughter 1 * @return true if one is TPC-only and the other ITSTPC */ -template +template inline bool isITSTPC_TPConly(TTrack const& track0, TTrack const& track1) { return (isITSTPCTrack(track0) && isTPConlyTrack(track1)) || (isITSTPCTrack(track1) && isTPConlyTrack(track0)); @@ -162,7 +185,7 @@ inline bool isITSTPC_TPConly(TTrack const& track0, TTrack const& track1) * @param track1 track from daughter 1 * @return true if one is ITS-only and the other ITSTPC */ -template +template inline bool isITSTPC_ITSonly(TTrack const& track0, TTrack const& track1) { return (isITSTPCTrack(track0) && isITSonlyTrack(track1)) || (isITSTPCTrack(track1) && isITSonlyTrack(track0)); @@ -176,7 +199,7 @@ inline bool isITSTPC_ITSonly(TTrack const& track0, TTrack const& track1) * @param track1 track from daughter 1 * @return true if both are TPC-only tracks */ -template +template inline bool isTPConly_TPConly(TTrack const& track0, TTrack const& track1) { return isTPConlyTrack(track0) && isTPConlyTrack(track1); @@ -190,7 +213,7 @@ inline bool isTPConly_TPConly(TTrack const& track0, TTrack const& track1) * @param track1 track from daughter 1 * @return true if both are ITS-only tracks */ -template +template inline bool isITSonly_ITSonly(TTrack const& track0, TTrack const& track1) { return isITSonlyTrack(track0) && isITSonlyTrack(track1); @@ -204,7 +227,7 @@ inline bool isITSonly_ITSonly(TTrack const& track0, TTrack const& track1) * @param track1 track from daughter 1 * @return true if either one is ITS-only while the other one is TPC-only */ -template +template inline bool isTPConly_ITSonly(TTrack const& track0, TTrack const& track1) { return (isTPConlyTrack(track0) && isITSonlyTrack(track1)) || (isTPConlyTrack(track1) && isITSonlyTrack(track0)); @@ -217,7 +240,7 @@ inline bool isTPConly_ITSonly(TTrack const& track0, TTrack const& track1) * @param mc2 MCParticle 1 * @return true if the mother particle is the expected type and the same for both */ -template +template inline bool checkMCParticles(T const& mc1, T const& mc2) { if (std::abs(mc1.pdgCode()) != kElectron || std::abs(mc2.pdgCode()) != kElectron) { diff --git a/PWGJE/Core/CMakeLists.txt b/PWGJE/Core/CMakeLists.txt index b6ccafb2be2..a7713c9900d 100644 --- a/PWGJE/Core/CMakeLists.txt +++ b/PWGJE/Core/CMakeLists.txt @@ -23,7 +23,6 @@ o2physics_target_root_dictionary(PWGJECore FastJetUtilities.h JetTaggingUtilities.h JetBkgSubUtils.h - JetDerivedDataUtilities.h emcalCrossTalkEmulation.h utilsTrackMatchingEMC.h LINKDEF PWGJECoreLinkDef.h) diff --git a/PWGUD/Core/decayTree.cxx b/PWGUD/Core/decayTree.cxx index ded7c2fa329..058c85f4caf 100644 --- a/PWGUD/Core/decayTree.cxx +++ b/PWGUD/Core/decayTree.cxx @@ -1228,4 +1228,162 @@ std::vector> decayTree::combinations(int nPool) return copes; } +void decayTree::createHistograms(o2::framework::HistogramRegistry& registry) +{ + // definitions + auto etax = o2::framework::AxisSpec(100, -1.5, 1.5); + auto nSax = o2::framework::AxisSpec(300, -15.0, 15.0); + auto chi2ax = o2::framework::AxisSpec(100, 0.0, 5.0); + auto nClax = o2::framework::AxisSpec(170, 0.0, 170.0); + auto angax = o2::framework::AxisSpec(315, 0.0, 3.15); + auto dcaxyax = o2::framework::AxisSpec(400, -0.2, 0.2); + auto dcazax = o2::framework::AxisSpec(600, -0.3, 0.3); + auto sTPCax = o2::framework::AxisSpec(1000, 0., 1000.); + + std::string base; + std::string hname; + std::string annot; + fhistPointers.clear(); + for (const auto& res : getResonances()) { + auto max = o2::framework::AxisSpec(res->nmassBins(), res->massHistRange()[0], res->massHistRange()[1]); + auto momax = o2::framework::AxisSpec(res->nmomBins(), res->momHistRange()[0], res->momHistRange()[1]); + + // M-pT, M-eta, pT-eta + for (const auto& cc : fccs) { + base = cc; + base.append("/").append(res->name()).append("/"); + hname = base + "mpt"; + annot = "M versus pT; M (" + res->name() + ") GeV/c^{2}; pT (" + res->name() + ") GeV/c"; + fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH2F, {max, momax}})}); + hname = base + "meta"; + annot = "M versus eta; M (" + res->name() + ") GeV/c^{2}; eta (" + res->name() + ")"; + fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH2F, {max, etax}})}); + hname = base + "pteta"; + annot = "pT versus eta; pT (" + res->name() + ") GeV/c; eta (" + res->name() + ")"; + fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH2F, {momax, etax}})}); + + // M versus daughters + auto daughs = res->getDaughters(); + auto ndaughs = daughs.size(); + for (auto i = 0; i < static_cast(ndaughs); i++) { + auto d1 = getResonance(daughs[i]); + + // M vs pT daughter + hname = base; + hname.append("MvspT_").append(res->name()).append(d1->name()); + annot = "M versus pT; M (" + res->name() + ") GeV/c^{2}; pT (" + d1->name() + ") GeV/c"; + auto momax1 = o2::framework::AxisSpec(d1->nmomBins(), d1->momHistRange()[0], d1->momHistRange()[1]); + fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH2F, {max, momax1}})}); + + // M vs eta daughter + hname = base; + hname.append("Mvseta_").append(res->name()).append(d1->name()); + annot = "M versus eta; M (" + res->name() + ") GeV/c^{2}; eta (" + d1->name() + ")"; + fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH2F, {max, etax}})}); + + if (d1->isFinal()) { + // M vs dcaXYZ + hname = base; + hname.append("MvsdcaXY_").append(res->name()).append(d1->name()); + annot = "M versus dcaXY; M (" + res->name() + ") GeV/c^{2}; dca_{XY} (" + d1->name() + ") #mu m"; + fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH2F, {max, dcaxyax}})}); + hname = base; + hname.append("MvsdcaZ_").append(res->name()).append(d1->name()); + annot = "M versus dcaZ; M (" + res->name() + ") GeV/c^{2}; dca_{Z} (" + d1->name() + ") #mu m"; + fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH2F, {max, dcazax}})}); + + // M vs chi2 track + hname = base; + hname.append("Mvschi2_").append(res->name()).append(d1->name()); + annot = "M versus chi2; M (" + res->name() + ") GeV/c^{2}; chi2 (" + d1->name() + ")"; + fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH2F, {max, chi2ax}})}); + + // M vs nCl track + hname = base; + hname.append("MvsnCl_").append(res->name()).append(d1->name()); + annot = "M versus nCl; M (" + res->name() + ") GeV/c^{2}; nCl (" + d1->name() + ")"; + fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH2F, {max, nClax}})}); + + // M versus detector hits + hname = base; + hname.append("MvsdetHits_").append(res->name()).append(d1->name()); + annot = "M versus detector hits; M (" + res->name() + ") GeV/c^{2}; ITS + 2*TPC + 4*TRD + 8*TOF (" + d1->name() + ")"; + fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH2F, {max, {16, -0.5, 15.5}}})}); + } else { + // M vs Mi + hname = base; + hname.append("MvsM_").append(res->name()).append(d1->name()); + annot = "M versus M; M (" + res->name() + ") GeV/c^{2}; M (" + d1->name() + ") GeV/c^{2}"; + auto max1 = o2::framework::AxisSpec(res->nmassBins(), d1->massHistRange()[0], d1->massHistRange()[1]); + fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH2F, {max, max1}})}); + } + } + + // daughters vs daughters + for (auto i = 0; i < static_cast(ndaughs - 1); i++) { + auto d1 = getResonance(daughs[i]); + auto max1 = o2::framework::AxisSpec(d1->nmassBins(), d1->massHistRange()[0], d1->massHistRange()[1]); + for (auto j = i + 1; j < static_cast(ndaughs); j++) { + auto d2 = getResonance(daughs[j]); + auto max2 = o2::framework::AxisSpec(d2->nmassBins(), d2->massHistRange()[0], d2->massHistRange()[1]); + + // M1 vs M2 + hname = base; + hname.append("MvsM_").append(d1->name()).append(d2->name()); + annot = std::string("M versus M; M (").append(d1->name()).append(") GeV/c^{2}; M (").append(d2->name()).append(") GeV/c^{2}"); + fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH2F, {max1, max2}})}); + + // angle(d1, d2) + hname = base; + hname.append("angle_").append(d1->name()).append(d2->name()); + annot = std::string("angle; Angle (").append(d1->name()).append(", ").append(d2->name()).append(")"); + fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH1F, {angax}})}); + + // M vs angle(d1, d2) + hname = base; + hname.append("Mvsangle_").append(d1->name()).append(d2->name()); + annot = std::string("M versus angle; M (").append(res->name()).append(") GeV/c^{2}; Angle (").append(d1->name()).append(", ").append(d2->name()).append(")"); + fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH2F, {max, angax}})}); + + // both daughters are finals + if (d1->isFinal() && d2->isFinal()) { + hname = base; + hname.append("TPCsignal_").append(d1->name()).append(d2->name()); + annot = std::string("TPC signal of both tracks; TPCsignal (").append(d1->name()).append("); TPCsignal (").append(d2->name()).append(")"); + fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH2F, {sTPCax, sTPCax}})}); + } + } + } + + // for finals only + if (res->isFinal()) { + // dca + hname = base; + hname.append("dcaXY"); + annot = std::string("dcaXY; dca_{XY}(").append(res->name()).append(")"); + fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH1F, {dcaxyax}})}); + hname = base; + hname.append("dcaZ"); + annot = std::string("dcaZ; dca_{Z}(").append(res->name()).append(")"); + fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH1F, {dcazax}})}); + + // nSIgma[TPC, TOF] vs pT + for (const auto& det : fdets) { + for (const auto& part : fparts) { + hname = base; + hname.append("nS").append(part).append(det); + annot = std::string("nSigma_").append(det).append(" versus p; p (").append(res->name()).append(") GeV/c; nSigma_{").append(det).append(", ").append(part).append("} (").append(res->name()).append(")"); + fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH2F, {momax, nSax}})}); + } + } + + // detector hits + hname = base; + hname.append("detectorHits"); + annot = std::string("detectorHits; Detector(").append(res->name()).append(")"); + fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH1F, {{4, 0.5, 4.5}}})}); + } + } + } +} // ----------------------------------------------------------------------------- diff --git a/PWGUD/Core/decayTree.h b/PWGUD/Core/decayTree.h index 162a1859181..05cd97968c0 100644 --- a/PWGUD/Core/decayTree.h +++ b/PWGUD/Core/decayTree.h @@ -12,7 +12,6 @@ #ifndef PWGUD_CORE_DECAYTREE_H_ #define PWGUD_CORE_DECAYTREE_H_ -#include #include #include @@ -29,6 +28,11 @@ #include #include +namespace o2::framework +{ +class HistogramRegistry; +} + // ----------------------------------------------------------------------------- class pidSelector { @@ -835,164 +839,7 @@ class decayTree } // create histograms - void createHistograms(o2::framework::HistogramRegistry& registry) - { - // definitions - auto etax = o2::framework::AxisSpec(100, -1.5, 1.5); - auto nSax = o2::framework::AxisSpec(300, -15.0, 15.0); - auto chi2ax = o2::framework::AxisSpec(100, 0.0, 5.0); - auto nClax = o2::framework::AxisSpec(170, 0.0, 170.0); - auto angax = o2::framework::AxisSpec(315, 0.0, 3.15); - auto dcaxyax = o2::framework::AxisSpec(400, -0.2, 0.2); - auto dcazax = o2::framework::AxisSpec(600, -0.3, 0.3); - auto sTPCax = o2::framework::AxisSpec(1000, 0., 1000.); - - std::string base; - std::string hname; - std::string annot; - fhistPointers.clear(); - for (const auto& res : getResonances()) { - auto max = o2::framework::AxisSpec(res->nmassBins(), res->massHistRange()[0], res->massHistRange()[1]); - auto momax = o2::framework::AxisSpec(res->nmomBins(), res->momHistRange()[0], res->momHistRange()[1]); - - // M-pT, M-eta, pT-eta - for (const auto& cc : fccs) { - base = cc; - base.append("/").append(res->name()).append("/"); - hname = base + "mpt"; - annot = "M versus pT; M (" + res->name() + ") GeV/c^{2}; pT (" + res->name() + ") GeV/c"; - fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH2F, {max, momax}})}); - hname = base + "meta"; - annot = "M versus eta; M (" + res->name() + ") GeV/c^{2}; eta (" + res->name() + ")"; - fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH2F, {max, etax}})}); - hname = base + "pteta"; - annot = "pT versus eta; pT (" + res->name() + ") GeV/c; eta (" + res->name() + ")"; - fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH2F, {momax, etax}})}); - - // M versus daughters - auto daughs = res->getDaughters(); - auto ndaughs = daughs.size(); - for (auto i = 0; i < static_cast(ndaughs); i++) { - auto d1 = getResonance(daughs[i]); - - // M vs pT daughter - hname = base; - hname.append("MvspT_").append(res->name()).append(d1->name()); - annot = "M versus pT; M (" + res->name() + ") GeV/c^{2}; pT (" + d1->name() + ") GeV/c"; - auto momax1 = o2::framework::AxisSpec(d1->nmomBins(), d1->momHistRange()[0], d1->momHistRange()[1]); - fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH2F, {max, momax1}})}); - - // M vs eta daughter - hname = base; - hname.append("Mvseta_").append(res->name()).append(d1->name()); - annot = "M versus eta; M (" + res->name() + ") GeV/c^{2}; eta (" + d1->name() + ")"; - fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH2F, {max, etax}})}); - - if (d1->isFinal()) { - // M vs dcaXYZ - hname = base; - hname.append("MvsdcaXY_").append(res->name()).append(d1->name()); - annot = "M versus dcaXY; M (" + res->name() + ") GeV/c^{2}; dca_{XY} (" + d1->name() + ") #mu m"; - fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH2F, {max, dcaxyax}})}); - hname = base; - hname.append("MvsdcaZ_").append(res->name()).append(d1->name()); - annot = "M versus dcaZ; M (" + res->name() + ") GeV/c^{2}; dca_{Z} (" + d1->name() + ") #mu m"; - fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH2F, {max, dcazax}})}); - - // M vs chi2 track - hname = base; - hname.append("Mvschi2_").append(res->name()).append(d1->name()); - annot = "M versus chi2; M (" + res->name() + ") GeV/c^{2}; chi2 (" + d1->name() + ")"; - fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH2F, {max, chi2ax}})}); - - // M vs nCl track - hname = base; - hname.append("MvsnCl_").append(res->name()).append(d1->name()); - annot = "M versus nCl; M (" + res->name() + ") GeV/c^{2}; nCl (" + d1->name() + ")"; - fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH2F, {max, nClax}})}); - - // M versus detector hits - hname = base; - hname.append("MvsdetHits_").append(res->name()).append(d1->name()); - annot = "M versus detector hits; M (" + res->name() + ") GeV/c^{2}; ITS + 2*TPC + 4*TRD + 8*TOF (" + d1->name() + ")"; - fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH2F, {max, {16, -0.5, 15.5}}})}); - } else { - // M vs Mi - hname = base; - hname.append("MvsM_").append(res->name()).append(d1->name()); - annot = "M versus M; M (" + res->name() + ") GeV/c^{2}; M (" + d1->name() + ") GeV/c^{2}"; - auto max1 = o2::framework::AxisSpec(res->nmassBins(), d1->massHistRange()[0], d1->massHistRange()[1]); - fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH2F, {max, max1}})}); - } - } - - // daughters vs daughters - for (auto i = 0; i < static_cast(ndaughs - 1); i++) { - auto d1 = getResonance(daughs[i]); - auto max1 = o2::framework::AxisSpec(d1->nmassBins(), d1->massHistRange()[0], d1->massHistRange()[1]); - for (auto j = i + 1; j < static_cast(ndaughs); j++) { - auto d2 = getResonance(daughs[j]); - auto max2 = o2::framework::AxisSpec(d2->nmassBins(), d2->massHistRange()[0], d2->massHistRange()[1]); - - // M1 vs M2 - hname = base; - hname.append("MvsM_").append(d1->name()).append(d2->name()); - annot = std::string("M versus M; M (").append(d1->name()).append(") GeV/c^{2}; M (").append(d2->name()).append(") GeV/c^{2}"); - fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH2F, {max1, max2}})}); - - // angle(d1, d2) - hname = base; - hname.append("angle_").append(d1->name()).append(d2->name()); - annot = std::string("angle; Angle (").append(d1->name()).append(", ").append(d2->name()).append(")"); - fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH1F, {angax}})}); - - // M vs angle(d1, d2) - hname = base; - hname.append("Mvsangle_").append(d1->name()).append(d2->name()); - annot = std::string("M versus angle; M (").append(res->name()).append(") GeV/c^{2}; Angle (").append(d1->name()).append(", ").append(d2->name()).append(")"); - fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH2F, {max, angax}})}); - - // both daughters are finals - if (d1->isFinal() && d2->isFinal()) { - hname = base; - hname.append("TPCsignal_").append(d1->name()).append(d2->name()); - annot = std::string("TPC signal of both tracks; TPCsignal (").append(d1->name()).append("); TPCsignal (").append(d2->name()).append(")"); - fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH2F, {sTPCax, sTPCax}})}); - } - } - } - - // for finals only - if (res->isFinal()) { - // dca - hname = base; - hname.append("dcaXY"); - annot = std::string("dcaXY; dca_{XY}(").append(res->name()).append(")"); - fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH1F, {dcaxyax}})}); - hname = base; - hname.append("dcaZ"); - annot = std::string("dcaZ; dca_{Z}(").append(res->name()).append(")"); - fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH1F, {dcazax}})}); - - // nSIgma[TPC, TOF] vs pT - for (const auto& det : fdets) { - for (const auto& part : fparts) { - hname = base; - hname.append("nS").append(part).append(det); - annot = std::string("nSigma_").append(det).append(" versus p; p (").append(res->name()).append(") GeV/c; nSigma_{").append(det).append(", ").append(part).append("} (").append(res->name()).append(")"); - fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH2F, {momax, nSax}})}); - } - } - - // detector hits - hname = base; - hname.append("detectorHits"); - annot = std::string("detectorHits; Detector(").append(res->name()).append(")"); - fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH1F, {{4, 0.5, 4.5}}})}); - } - } - } - } + void createHistograms(o2::framework::HistogramRegistry& registry); // ClassDefNV(decayTree, 1); }; diff --git a/Tutorials/src/histogramRegistry.cxx b/Tutorials/src/histogramRegistry.cxx index 9e61566af5b..620bc91ab60 100644 --- a/Tutorials/src/histogramRegistry.cxx +++ b/Tutorials/src/histogramRegistry.cxx @@ -59,22 +59,22 @@ struct EtaPhiHistograms { } }; -struct FilteredHistograms { - /// Construct a registry object with direct declaration - HistogramRegistry registry{ - "registry", - { - {"eta", "#eta", {HistType::kTH1F, {{102, -2.01, 2.01}}}}, // - {"ptToPt", "#ptToPt", {HistType::kTH2F, {{100, -0.01, 10.01}, {100, -0.01, 10.01}}}} // - } // - }; - - void process(aod::Tracks const& tracks) - { - registry.fill(HIST("eta"), tracks, aod::track::eta > 0.0f); - registry.fill(HIST("ptToPt"), tracks, aod::track::pt < 5.0f); - } -}; +// struct FilteredHistograms { +// /// Construct a registry object with direct declaration +// HistogramRegistry registry{ +// "registry", +// { +// {"eta", "#eta", {HistType::kTH1F, {{102, -2.01, 2.01}}}}, // +// {"ptToPt", "#ptToPt", {HistType::kTH2F, {{100, -0.01, 10.01}, {100, -0.01, 10.01}}}} // +// } // +// }; + +// void process(aod::Tracks const& tracks) +// { +// registry.fill(HIST("eta"), tracks, aod::track::eta > 0.0f); +// registry.fill(HIST("ptToPt"), tracks, aod::track::pt < 5.0f); +// } +// }; struct DimensionTest { @@ -118,19 +118,19 @@ struct DimensionTest { void process(aod::Tracks const& tracks) { using namespace aod::track; - // does not work with dynamic columns (e.g. Charge, NormalizedPhi) - registry.fill(HIST("1d"), tracks, eta > -0.7f); - registry.fill(HIST("3d"), tracks, eta > 0.f); - registry.fill(HIST("5d"), tracks, pt > 0.15f); - registry.fill(HIST("7d"), tracks, pt > 0.15f); - registry.fill(HIST("2d-profile"), tracks, eta > -0.5f); + // // does not work with dynamic columns (e.g. Charge, NormalizedPhi) + // registry.fill(HIST("1d"), tracks, eta > -0.7f); + // registry.fill(HIST("3d"), tracks, eta > 0.f); + // registry.fill(HIST("5d"), tracks, pt > 0.15f); + // registry.fill(HIST("7d"), tracks, pt > 0.15f); + // registry.fill(HIST("2d-profile"), tracks, eta > -0.5f); - // fill 4d histogram with weight (column X) - registry.fill(HIST("4d-weight"), tracks, eta > 0.f); + // // fill 4d histogram with weight (column X) + // registry.fill(HIST("4d-weight"), tracks, eta > 0.f); - registry.fill(HIST("2d-weight"), tracks, eta > 0.f); + // registry.fill(HIST("2d-weight"), tracks, eta > 0.f); - registry.fill(HIST("1d-profile-weight"), tracks, eta > 0.f); + // registry.fill(HIST("1d-profile-weight"), tracks, eta > 0.f); for (auto& track : tracks) { registry.fill(HIST("2d"), track.eta(), track.pt()); @@ -218,8 +218,8 @@ struct RealisticExample { { using namespace aod::track; - etaStudy.fill(HIST("positive"), tracks, eta > 0.f); - etaStudy.fill(HIST("negative"), tracks, eta < 0.f); + // etaStudy.fill(HIST("positive"), tracks, eta > 0.f); + // etaStudy.fill(HIST("negative"), tracks, eta < 0.f); for (auto& track : tracks) { spectra.fill(HIST("myControlHist"), track.pt(), track.eta()); @@ -329,7 +329,7 @@ WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) return WorkflowSpec{ adaptAnalysisTask(cfgc), adaptAnalysisTask(cfgc), - adaptAnalysisTask(cfgc), + // adaptAnalysisTask(cfgc), adaptAnalysisTask(cfgc), adaptAnalysisTask(cfgc), adaptAnalysisTask(cfgc),