Skip to content

Commit 6b94db7

Browse files
nstrangmNicolas Strangmannalibuild
authored
[PWGEM/PhotonMeson,Trigger] Add Heavy Neutral Meson Software Trigger Task (AliceO2Group#10421)
Co-authored-by: Nicolas Strangmann <[email protected]> Co-authored-by: ALICE Action Bot <[email protected]>
1 parent ba909b9 commit 6b94db7

File tree

6 files changed

+425
-24
lines changed

6 files changed

+425
-24
lines changed

EventFiltering/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,11 @@ o2physics_add_dpl_workflow(em-photon-filter-qc
102102
PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2::DetectorsBase O2Physics::PWGEMPhotonMesonCore
103103
COMPONENT_NAME Analysis)
104104

105+
o2physics_add_dpl_workflow(heavy-neutral-meson-filter
106+
SOURCES PWGEM/HeavyNeutralMesonFilter.cxx
107+
PUBLIC_LINK_LIBRARIES O2::Framework O2::EMCALBase O2::EMCALCalib O2Physics::AnalysisCore O2Physics::PWGEMPhotonMesonCore
108+
COMPONENT_NAME Analysis)
109+
105110
o2physics_add_dpl_workflow(lf-f1proton-filter
106111
SOURCES PWGLF/filterf1proton.cxx
107112
PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2::DetectorsBase
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2+
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3+
// All rights not expressly granted are reserved.
4+
//
5+
// This software is distributed under the terms of the GNU General Public
6+
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7+
//
8+
// In applying this license CERN does not waive the privileges and immunities
9+
// granted to it by virtue of its status as an Intergovernmental Organization
10+
// or submit itself to any jurisdiction.
11+
///
12+
/// \file HeavyNeutralMesonFilter.cxx
13+
///
14+
/// \brief This code loops over collisions to filter events contaning heavy mesons (omega or eta') using EMCal clusters and V0s (PCM)
15+
///
16+
/// \author Nicolas Strangmann ([email protected]) - Goethe University Frankfurt
17+
///
18+
19+
#include <vector>
20+
21+
#include "PWGEM/PhotonMeson/Utils/HNMUtilities.h"
22+
23+
using namespace o2;
24+
using namespace o2::framework;
25+
using namespace o2::framework::expressions;
26+
using namespace o2::aod::pwgem::photonmeson;
27+
28+
using MyBCs = soa::Join<aod::BCs, aod::BcSels, aod::Timestamps>;
29+
using MyCollisions = soa::Join<aod::Collisions, aod::EvSels>;
30+
31+
using SelectedTracks = soa::Filtered<soa::Join<aod::FullTracks, aod::TrackSelection>>;
32+
33+
struct HeavyNeutralMesonFilter {
34+
Produces<aod::HeavyNeutralMesonFilters> tags;
35+
36+
HistogramRegistry mHistManager{"HeavyNeutralMesonFilterHistograms", {}, OutputObjHandlingPolicy::QAObject};
37+
38+
Configurable<float> cfgTrackMinPt{"cfgTrackMinPt", 0.1, "Minimum momentum of tracks (GeV/c)"};
39+
Configurable<int> cfgHNMMassCorrection{"cfgHNMMassCorrection", 1, "Use GG PDG mass to correct HNM mass (0 = off, 1 = subDeltaPi0, 2 = subLambda)"};
40+
static constexpr float defaultMassWindows[2][4] = {{0., 0.4, 0.6, 1.}, {0.4, 0.8, 0.8, 1.2}};
41+
Configurable<LabeledArray<float>> massWindowOmega{"massWindowOmega", {defaultMassWindows[0], 4, {"pi0_min", "pi0_max", "omega_min", "omega_max"}}, "Mass window for selected omegas and their decay pi0"};
42+
Configurable<LabeledArray<float>> massWindowEtaPrime{"massWindowEtaPrime", {defaultMassWindows[1], 4, {"eta_min", "eta_max", "etaprime_min", "etaprime_max"}}, "Mass window for selected eta' and their decay eta"};
43+
44+
static constexpr float defaultMinPts[4] = {1.8, 1.8, 2.6, 2.6};
45+
Configurable<LabeledArray<float>> minHNMPts{"minHNMPts", {defaultMinPts, 4, {"PCM_omega", "PCM_etaprime", "EMC_omega", "EMC_etaprime"}}, "Minimum pT values for the trigger decisions (GeV/c)"};
46+
47+
Filter trackPtFilter = aod::track::pt > cfgTrackMinPt;
48+
49+
std::vector<hnmutilities::GammaGammaPair> vGGs;
50+
std::vector<hnmutilities::HeavyNeutralMeson> vHNMs;
51+
52+
bool colContainsPCMOmega, colContainsEMCOmega, colContainsPCMEtaPrime, colContainsEMCEtaPrime = false;
53+
54+
emcal::Geometry* emcalGeom;
55+
56+
void init(InitContext const&)
57+
{
58+
emcalGeom = emcal::Geometry::GetInstanceFromRunNumber(300000);
59+
auto hCollisionCounter = mHistManager.add<TH1>("Event/hCollisionCounter", "Number of collisions;;#bf{#it{N}_{Coll}}", HistType::kTH1F, {{6, -0.5, 5.5}});
60+
hCollisionCounter->GetXaxis()->SetBinLabel(1, "all");
61+
hCollisionCounter->GetXaxis()->SetBinLabel(2, "kTVXinEMC");
62+
hCollisionCounter->GetXaxis()->SetBinLabel(3, "PCM #omega");
63+
hCollisionCounter->GetXaxis()->SetBinLabel(4, "EMC #omega");
64+
hCollisionCounter->GetXaxis()->SetBinLabel(5, "PCM #eta'");
65+
hCollisionCounter->GetXaxis()->SetBinLabel(6, "EMC #eta'");
66+
67+
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}});
68+
mHistManager.add("Event/nTracks", "Number of tracks;#bf{N_{tracks}};#bf{#it{N}_{Coll}}", HistType::kTH1F, {{51, -0.5, 50.5}});
69+
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}});
70+
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}});
71+
72+
mHistManager.add("GG/invMassVsPt_PCM", "Invariant mass and pT of gg candidates;#bf{#it{M}_{#gamma#gamma}};#bf{#it{N}_{#gamma#gamma}}", HistType::kTH2F, {{400, 0., 0.8}, {250, 0., 25.}});
73+
mHistManager.add("GG/invMassVsPt_PCMEMC", "Invariant mass and pT of gg candidates;#bf{#it{M}_{#gamma#gamma}};#bf{#it{N}_{#gamma#gamma}}", HistType::kTH2F, {{400, 0., 0.8}, {250, 0., 25.}});
74+
mHistManager.add("GG/invMassVsPt_EMC", "Invariant mass and pT of gg candidates;#bf{#it{M}_{#gamma#gamma}};#bf{#it{N}_{#gamma#gamma}}", HistType::kTH2F, {{400, 0., 0.8}, {250, 0., 25.}});
75+
76+
mHistManager.add("HeavyNeutralMeson/invMassVsPt_PCM", "Invariant mass and pT of HNM candidates;#bf{#it{M}_{#pi^{+}#pi^{-}#gamma#gamma}};#bf{#it{N}_{#pi^{+}#pi^{-}#gamma#gamma}}", HistType::kTH2F, {{600, 0.6, 1.2}, {250, 0., 25.}});
77+
mHistManager.add("HeavyNeutralMeson/invMassVsPt_PCMEMC", "Invariant mass and pT of HNM candidates;#bf{#it{M}_{#pi^{+}#pi^{-}#gamma#gamma}};#bf{#it{N}_{#pi^{+}#pi^{-}#gamma#gamma}}", HistType::kTH2F, {{600, 0.6, 1.2}, {250, 0., 25.}});
78+
mHistManager.add("HeavyNeutralMeson/invMassVsPt_EMC", "Invariant mass and pT of HNM candidates;#bf{#it{M}_{#pi^{+}#pi^{-}#gamma#gamma}};#bf{#it{N}_{#pi^{+}#pi^{-}#gamma#gamma}}", HistType::kTH2F, {{600, 0.6, 1.2}, {250, 0., 25.}});
79+
}
80+
81+
Preslice<aod::V0PhotonsKF> perCollision_pcm = aod::v0photonkf::collisionId;
82+
Preslice<aod::SkimEMCClusters> perCollision_emc = aod::skimmedcluster::collisionId;
83+
84+
void process(MyCollisions::iterator const& collision, MyBCs const&, aod::SkimEMCClusters const& clusters, aod::V0PhotonsKF const& v0s, SelectedTracks const& tracks)
85+
{
86+
mHistManager.fill(HIST("Event/hCollisionCounter"), 0.);
87+
88+
if (collision.foundBC_as<MyBCs>().alias_bit(kTVXinEMC))
89+
mHistManager.fill(HIST("Event/hCollisionCounter"), 1.);
90+
91+
auto v0sInThisCollision = v0s.sliceBy(perCollision_pcm, collision.globalIndex());
92+
auto clustersInThisCollision = clusters.sliceBy(perCollision_emc, collision.globalIndex());
93+
94+
mHistManager.fill(HIST("Event/nClustersVsV0s"), clustersInThisCollision.size(), v0sInThisCollision.size());
95+
mHistManager.fill(HIST("Event/nTracks"), tracks.size());
96+
97+
colContainsPCMOmega = colContainsEMCOmega = colContainsPCMEtaPrime = colContainsEMCEtaPrime = false;
98+
99+
hnmutilities::reconstructGGs(clustersInThisCollision, v0sInThisCollision, vGGs);
100+
processGGs(vGGs);
101+
hnmutilities::reconstructHeavyNeutralMesons(tracks, vGGs, vHNMs);
102+
processHNMs(vHNMs);
103+
104+
tags(colContainsPCMOmega, colContainsEMCOmega, colContainsPCMEtaPrime, colContainsEMCEtaPrime);
105+
}
106+
107+
/// \brief Loop over the GG candidates, fill the mass/pt histograms and set the isPi0/isEta flags based on the reconstructed mass
108+
void processGGs(std::vector<hnmutilities::GammaGammaPair>& vGGs)
109+
{
110+
int nGGsBeforeMassCuts = vGGs.size();
111+
for (unsigned int iGG = 0; iGG < vGGs.size(); iGG++) {
112+
auto lightMeson = &vGGs.at(iGG);
113+
114+
if (lightMeson->reconstructionType == photonpair::kPCMPCM) {
115+
mHistManager.fill(HIST("GG/invMassVsPt_PCM"), lightMeson->m(), lightMeson->pT());
116+
} else if (lightMeson->reconstructionType == photonpair::kEMCEMC) {
117+
mHistManager.fill(HIST("GG/invMassVsPt_EMC"), lightMeson->m(), lightMeson->pT());
118+
} else {
119+
mHistManager.fill(HIST("GG/invMassVsPt_PCMEMC"), lightMeson->m(), lightMeson->pT());
120+
}
121+
122+
if (lightMeson->m() > massWindowOmega->get("pi0_min") && lightMeson->m() < massWindowOmega->get("pi0_max")) {
123+
lightMeson->isPi0 = true;
124+
} else if (lightMeson->m() > massWindowEtaPrime->get("eta_min") && lightMeson->m() < massWindowEtaPrime->get("eta_max")) {
125+
lightMeson->isEta = true;
126+
} else {
127+
vGGs.erase(vGGs.begin() + iGG);
128+
iGG--;
129+
}
130+
}
131+
mHistManager.fill(HIST("Event/nGGs"), nGGsBeforeMassCuts, vGGs.size());
132+
}
133+
134+
/// \brief Loop over the heavy neutral meson candidates, fill the mass/pt histograms and set the trigger flags based on the reconstructed mass
135+
void processHNMs(std::vector<hnmutilities::HeavyNeutralMeson>& vHNMs)
136+
{
137+
int nHNMsBeforeMassCuts = vHNMs.size();
138+
for (unsigned int iHNM = 0; iHNM < vHNMs.size(); iHNM++) {
139+
auto heavyNeutralMeson = vHNMs.at(iHNM);
140+
141+
float massHNM = heavyNeutralMeson.m(cfgHNMMassCorrection);
142+
if (heavyNeutralMeson.gg->reconstructionType == photonpair::kPCMPCM) {
143+
mHistManager.fill(HIST("HeavyNeutralMeson/invMassVsPt_PCM"), massHNM, heavyNeutralMeson.pT());
144+
} else if (heavyNeutralMeson.gg->reconstructionType == photonpair::kEMCEMC) {
145+
mHistManager.fill(HIST("HeavyNeutralMeson/invMassVsPt_EMC"), massHNM, heavyNeutralMeson.pT());
146+
} else {
147+
mHistManager.fill(HIST("HeavyNeutralMeson/invMassVsPt_PCMEMC"), massHNM, heavyNeutralMeson.pT());
148+
}
149+
150+
if (heavyNeutralMeson.gg->isPi0 && massHNM > massWindowOmega->get("omega_min") && massHNM < massWindowOmega->get("omega_max")) {
151+
if (heavyNeutralMeson.gg->reconstructionType == photonpair::kPCMPCM && heavyNeutralMeson.pT() > minHNMPts->get("PCM_omega"))
152+
colContainsPCMOmega = true;
153+
else if (heavyNeutralMeson.gg->reconstructionType == photonpair::kEMCEMC && heavyNeutralMeson.pT() > minHNMPts->get("EMC_omega"))
154+
colContainsEMCOmega = true;
155+
} else if (heavyNeutralMeson.gg->isEta && massHNM > massWindowEtaPrime->get("etaprime_min") && massHNM < massWindowEtaPrime->get("etaprime_max")) {
156+
if (heavyNeutralMeson.gg->reconstructionType == photonpair::kPCMPCM && heavyNeutralMeson.pT() > minHNMPts->get("PCM_etaprime"))
157+
colContainsPCMEtaPrime = true;
158+
else if (heavyNeutralMeson.gg->reconstructionType == photonpair::kEMCEMC && heavyNeutralMeson.pT() > minHNMPts->get("EMC_etaprime"))
159+
colContainsEMCEtaPrime = true;
160+
} else {
161+
vHNMs.erase(vHNMs.begin() + iHNM);
162+
iHNM--;
163+
}
164+
}
165+
mHistManager.fill(HIST("Event/nHeavyNeutralMesons"), nHNMsBeforeMassCuts, vHNMs.size());
166+
167+
if (colContainsPCMOmega)
168+
mHistManager.fill(HIST("Event/hCollisionCounter"), 2.);
169+
if (colContainsEMCOmega)
170+
mHistManager.fill(HIST("Event/hCollisionCounter"), 3.);
171+
if (colContainsPCMEtaPrime)
172+
mHistManager.fill(HIST("Event/hCollisionCounter"), 4.);
173+
if (colContainsEMCEtaPrime)
174+
mHistManager.fill(HIST("Event/hCollisionCounter"), 5.);
175+
}
176+
};
177+
178+
WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& cfgc)
179+
{
180+
return WorkflowSpec{adaptAnalysisTask<HeavyNeutralMesonFilter>(cfgc)};
181+
}

EventFiltering/cefpTask.cxx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ struct centralEventFilterTask {
227227
FILTER_CONFIGURABLE(MultFilters);
228228
FILTER_CONFIGURABLE(FullJetFilters);
229229
FILTER_CONFIGURABLE(PhotonFilters);
230+
FILTER_CONFIGURABLE(HeavyNeutralMesonFilters);
230231

231232
void init(o2::framework::InitContext& initc)
232233
{

EventFiltering/filterTables.h

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,9 @@ namespace o2::aod
4646
{
4747
namespace filtering
4848
{
49-
DECLARE_SOA_COLUMN(H2, hasH2, bool); //! deuteron trigger for the helium normalisation (to be downscaled)
50-
DECLARE_SOA_COLUMN(He, hasHe, bool); //! helium
51-
DECLARE_SOA_COLUMN(H3L3Body, hasH3L3Body, bool); //! hypertriton 3body
49+
DECLARE_SOA_COLUMN(H2, hasH2, bool); //! deuteron trigger for the helium normalisation (to be downscaled)
50+
DECLARE_SOA_COLUMN(He, hasHe, bool); //! helium
51+
DECLARE_SOA_COLUMN(H3L3Body, hasH3L3Body, bool); //! hypertriton 3body
5252
DECLARE_SOA_COLUMN(ITSextremeIonisation, hasITSextremeIonisation, bool); //! ITS extreme ionisation
5353
DECLARE_SOA_COLUMN(ITSmildIonisation, hasITSmildIonisation, bool); //! ITS mild ionisation (normalisation of the extreme ionisation), to be downscaled
5454

@@ -175,6 +175,12 @@ DECLARE_SOA_COLUMN(PCMHighPtPhoton, hasPCMHighPtPhoton, bool); //! PCM high pT p
175175
// DECLARE_SOA_COLUMN(PCMEtaDalitz, hasPCMEtaDalitz, bool); //! PCM eta -> ee gamma
176176
// DECLARE_SOA_COLUMN(PCMEtaGG, hasPCMEtaGG, bool); //! PCM eta -> ee gamma
177177
DECLARE_SOA_COLUMN(PCMandEE, hasPCMandEE, bool); //! PCM and ee
178+
179+
// heavy meson filters
180+
DECLARE_SOA_COLUMN(PCMOmegaMeson, hasPCMOmegaMeson, bool); //! Omega meson candidate (3pi) in the collision
181+
DECLARE_SOA_COLUMN(EMCOmegaMeson, hasEMCOmegaMeson, bool); //! Omega meson candidate (3pi) in the collision
182+
DECLARE_SOA_COLUMN(PCMEtaPrimeMeson, hasPCMEtaPrimeMeson, bool); //! Eta' meson candidate (3pi) in the collision
183+
DECLARE_SOA_COLUMN(EMCEtaPrimeMeson, hasEMCEtaPrimeMeson, bool); //! Eta' meson candidate (3pi) in the collision
178184
} // namespace filtering
179185

180186
namespace decision
@@ -300,6 +306,13 @@ DECLARE_SOA_TABLE(PhotonFilters, "AOD", "PhotonFilters", //!
300306

301307
using PhotonFilter = PhotonFilters::iterator;
302308

309+
// heavy mesons
310+
DECLARE_SOA_TABLE(HeavyNeutralMesonFilters, "AOD", "HeavyNeutralMesonFilters", //!
311+
filtering::PCMOmegaMeson, filtering::EMCOmegaMeson,
312+
filtering::PCMEtaPrimeMeson, filtering::EMCEtaPrimeMeson);
313+
314+
using HeavyNeutralMesonFilter = HeavyNeutralMesonFilters::iterator;
315+
303316
// cefp decision
304317
DECLARE_SOA_TABLE(CefpDecisions, "AOD", "CefpDecision", //!
305318
decision::BCId, decision::GlobalBCId, decision::EvSelBC, decision::CollisionTime, decision::CollisionTimeRes, decision::CefpTriggered0, decision::CefpTriggered1, decision::CefpSelected0, decision::CefpSelected1);
@@ -311,11 +324,11 @@ DECLARE_SOA_TABLE(BCRanges, "AOD", "BCRanges", //!
311324
using BCRange = BCRanges::iterator;
312325

313326
/// List of the available filters, the description of their tables and the name of the tasks
314-
constexpr int NumberOfFilters{12};
315-
constexpr std::array<char[32], NumberOfFilters> AvailableFilters{"NucleiFilters", "DiffractionFilters", "DqFilters", "HfFilters", "CFFilters", "JetFilters", "JetHFFilters", "FullJetFilters", "StrangenessFilters", "MultFilters", "PhotonFilters", "F1ProtonFilters"};
316-
constexpr std::array<char[16], NumberOfFilters> FilterDescriptions{"NucleiFilters", "DiffFilters", "DqFilters", "HfFilters", "CFFilters", "JetFilters", "JetHFFilters", "FullJetFilters", "LFStrgFilters", "MultFilters", "PhotonFilters", "F1ProtonFilters"};
317-
constexpr std::array<char[128], NumberOfFilters> 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"};
318-
constexpr o2::framework::pack<NucleiFilters, DiffractionFilters, DqFilters, HfFilters, CFFilters, JetFilters, JetHFFilters, FullJetFilters, StrangenessFilters, MultFilters, PhotonFilters, F1ProtonFilters> FiltersPack;
327+
constexpr int NumberOfFilters{13};
328+
constexpr std::array<char[32], NumberOfFilters> AvailableFilters{"NucleiFilters", "DiffractionFilters", "DqFilters", "HfFilters", "CFFilters", "JetFilters", "JetHFFilters", "FullJetFilters", "StrangenessFilters", "MultFilters", "PhotonFilters", "F1ProtonFilters", "HeavyNeutralMesonFilters"};
329+
constexpr std::array<char[16], NumberOfFilters> FilterDescriptions{"NucleiFilters", "DiffFilters", "DqFilters", "HfFilters", "CFFilters", "JetFilters", "JetHFFilters", "FullJetFilters", "LFStrgFilters", "MultFilters", "PhotonFilters", "F1ProtonFilters", "HNMesonFilters"};
330+
constexpr std::array<char[128], NumberOfFilters> 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-heavy-meson-filter"};
331+
constexpr o2::framework::pack<NucleiFilters, DiffractionFilters, DqFilters, HfFilters, CFFilters, JetFilters, JetHFFilters, FullJetFilters, StrangenessFilters, MultFilters, PhotonFilters, F1ProtonFilters, HeavyNeutralMesonFilters> FiltersPack;
319332
static_assert(o2::framework::pack_size(FiltersPack) == NumberOfFilters);
320333

321334
template <typename T, typename C>

0 commit comments

Comments
 (0)