Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions PWGEM/PhotonMeson/Core/EMCPhotonCut.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,12 @@ void EMCPhotonCut::SetUseSecondaryTM(bool flag)
LOG(info) << "EM Photon Cluster Cut, using secondary TM cut is set to : " << mUseTM;
}

void EMCPhotonCut::SetDoQA(bool flag)
{
mDoQA = flag;
LOG(info) << "EM Photon Cluster Cut, QA is set to: " << mUseTM;
}

void EMCPhotonCut::print() const
{
LOG(info) << "EMCal Photon Cut:";
Expand Down
151 changes: 145 additions & 6 deletions PWGEM/PhotonMeson/Core/EMCPhotonCut.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "PWGEM/PhotonMeson/DataModel/gammaTables.h"

#include <Framework/ASoA.h>
#include <Framework/HistogramRegistry.h>

#include <TNamed.h>

Expand Down Expand Up @@ -92,7 +93,7 @@ class EMCPhotonCut : public TNamed
EMCPhotonCut() = default;
EMCPhotonCut(const char* name, const char* title) : TNamed(name, title) {}

enum class EMCPhotonCuts : int {
enum class EMCPhotonCuts : std::uint8_t {
// cluster cut
kDefinition = 0,
kEnergy,
Expand All @@ -105,6 +106,12 @@ class EMCPhotonCut : public TNamed
kNCuts
};

enum class TrackType : std::uint8_t {
// cluster cut
kPrimary = 0,
kSecondary,
};

static const char* mCutNames[static_cast<int>(EMCPhotonCuts::kNCuts)];

constexpr auto getClusterId(o2::soa::is_iterator auto const& t) const
Expand All @@ -126,7 +133,7 @@ class EMCPhotonCut : public TNamed
/// \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) const
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()) {
Expand All @@ -150,29 +157,137 @@ class EMCPhotonCut : public TNamed
(dPhi > GetPhiCut(trackpt)) ||
(applyEoverP && cluster.e() / trackp >= mMinEoverP);
if (!fail) {
if (mDoQA && fRegistry != nullptr) {
switch (trackType) {
case TrackType::kPrimary:
fRegistry->fill(HIST("Cluster/hTrackdEtadPhi"), dEta, dPhi);
fRegistry->fill(HIST("Cluster/hTrackdEtaPt"), dEta, trackpt);
fRegistry->fill(HIST("Cluster/hTrackdPhiPt"), dPhi, trackpt);
break;
case TrackType::kSecondary:
fRegistry->fill(HIST("Cluster/hSecTrackdEtadPhi"), dEta, dPhi);
fRegistry->fill(HIST("Cluster/hSecTrackdEtaPt"), dEta, trackpt);
fRegistry->fill(HIST("Cluster/hSecTrackdPhiPt"), dPhi, trackpt);
break;
default:
break;
}
}
return false; // cluster got a track matche to it
}
++emcmatchedtrack;
}
return true; // all tracks checked, cluster survives
}

void fillBeforeClusterHistogram(o2::soa::is_iterator auto const& cluster, o2::framework::HistogramRegistry* fRegistry = nullptr)
{

if (mDoQA == false || fRegistry == nullptr) {
return;
}

fRegistry->fill(HIST("Cluster/hClusterQualityCuts"), 0, cluster.e());
fRegistry->fill(HIST("Cluster/before/hE"), 0, cluster.e());
fRegistry->fill(HIST("Cluster/before/hPt"), 0, cluster.pt());
fRegistry->fill(HIST("Cluster/before/hEtaPhi"), 0, cluster.eta(), cluster.phi());
fRegistry->fill(HIST("Cluster/before/hNCell"), 0, cluster.nCells(), cluster.e());
fRegistry->fill(HIST("Cluster/before/hM02"), 0, cluster.m02(), cluster.e());
fRegistry->fill(HIST("Cluster/before/hTime"), 0, cluster.time(), cluster.e());
}

void fillAfterClusterHistogram(o2::soa::is_iterator auto const& cluster, o2::framework::HistogramRegistry* fRegistry = nullptr)
{

if (mDoQA == false || fRegistry == nullptr) {
return;
}

fRegistry->fill(HIST("Cluster/hClusterQualityCuts"), 0, cluster.e());
fRegistry->fill(HIST("Cluster/before/hE"), 0, cluster.e());
fRegistry->fill(HIST("Cluster/before/hPt"), 0, cluster.pt());
fRegistry->fill(HIST("Cluster/before/hEtaPhi"), 0, cluster.eta(), cluster.phi());
fRegistry->fill(HIST("Cluster/before/hNCell"), 0, cluster.nCells(), cluster.e());
fRegistry->fill(HIST("Cluster/before/hM02"), 0, cluster.m02(), cluster.e());
fRegistry->fill(HIST("Cluster/before/hTime"), 0, cluster.time(), cluster.e());
}

/// \brief check if given clusters survives all cuts
/// \param flags EMBitFlags where results will be stored
/// \param cluster cluster table to check
/// \param matchedTracks matched primary tracks table
/// \param matchedSecondaries matched secondary tracks table
void AreSelectedRunning(EMBitFlags& flags, o2::soa::is_table auto const& clusters, IsTrackContainer auto const& emcmatchedtracks, IsTrackContainer auto const& secondaries) const
/// \param fRegistry 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)
{
auto emcmatchedtrackIter = emcmatchedtracks.begin();
auto emcmatchedtrackEnd = emcmatchedtracks.end();
auto secondaryIter = secondaries.begin();
auto secondaryEnd = secondaries.end();
size_t iCluster = 0;

// Check if we want to do QA and provided proper histogram registry
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("Cluster/before/hE", "E_{cluster};#it{E}_{cluster} (GeV);#it{N}_{cluster}", o2::framework::kTH1F, {thAxisClusterEnergy}, true);
fRegistry->add("Cluster/before/hPt", "Transverse momenta of clusters;#it{p}_{T} (GeV/c);#it{N}_{cluster}", o2::framework::kTH1F, {thAxisClusterEnergy}, true);
fRegistry->add("Cluster/before/hNgamma", "Number of #gamma candidates per collision;#it{N}_{#gamma} per collision;#it{N}_{collisions}", o2::framework::kTH1F, {{1001, -0.5f, 1000.5f}}, true);
fRegistry->add("Cluster/before/hEtaPhi", "#eta vs #varphi;#eta;#varphi (rad.)", o2::framework::kTH2F, {thAxisEta, thAxisPhi}, true);
fRegistry->add("Cluster/before/hNCell", "#it{N}_{cells};N_{cells} (GeV);#it{E}_{cluster} (GeV)", o2::framework::kTH2F, {thAxisNCell, thAxisClusterEnergy}, true);
fRegistry->add("Cluster/before/hM02", "Long ellipse axis;#it{M}_{02} (cm);#it{E}_{cluster} (GeV)", o2::framework::kTH2F, {thAxisM02, thAxisClusterEnergy}, true);
fRegistry->add("Cluster/before/hTime", "Cluster time;#it{t}_{cls} (ns);#it{E}_{cluster} (GeV)", o2::framework::kTH2F, {thAxisTime, thAxisClusterEnergy}, true);

fRegistry->addClone("Cluster/before/", "Cluster/after/");

auto hClusterQualityCuts = fRegistry->add<TH2>("Cluster/hClusterQualityCuts", "Energy at which clusters are removed by a given cut;;#it{E} (GeV)", o2::framework::kTH2F, {{static_cast<int>(EMCPhotonCut::EMCPhotonCuts::kNCuts) + 2, -0.5, static_cast<double>(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("Cluster/hTrackdEtadPhi", "d#eta vs. d#varphi of matched tracks;d#eta;d#varphi (rad.)", o2::framework::kTH2F, {thAxisDEta, thAxisDPhi}, true);
fRegistry->add("Cluster/hTrackdEtaPt", "d#eta vs. track pT of matched tracks;d#eta;d#varphi (rad.)", o2::framework::kTH2F, {thAxisDEta, thAxisMomentum}, true);
fRegistry->add("Cluster/hTrackdPhiPt", "d#varphi vs. track pT of matched tracks;d#eta;d#varphi (rad.)", o2::framework::kTH2F, {thAxisDPhi, thAxisMomentum}, true);
fRegistry->add("Cluster/hSecTrackdEtadPhi", "d#eta vs. d#varphi of matched secondary tracks;d#eta;d#varphi (rad.)", o2::framework::kTH2F, {thAxisDEta, thAxisDPhi}, true);
fRegistry->add("Cluster/hSecTrackdEtaPt", "d#eta vs. track pT of matched secondary tracks;d#eta;d#varphi (rad.)", o2::framework::kTH2F, {thAxisDEta, thAxisMomentum}, true);
fRegistry->add("Cluster/hSecTrackdPhiPt", "d#varphi vs. track pT of matched secondary tracks;d#eta;d#varphi (rad.)", o2::framework::kTH2F, {thAxisDPhi, thAxisMomentum}, true);
}

nTotClusterPerColl = 0;
currentCollID = clusters.iteratorAt(0).emeventId();
for (const auto& cluster : clusters) {
if (currentCollID == cluster.emeventId()) {
++nTotClusterPerColl;
} else {
fRegistry->fill(HIST("Cluster/before/hNgamma"), nTotClusterPerColl);
nTotClusterPerColl = 0;
}
if (mDoQA == true || fRegistry != nullptr) {
fillBeforeClusterHistogram(cluster, fRegistry);
}
if (!IsSelectedRunning(cluster, emcmatchedtrackIter, emcmatchedtrackEnd, secondaryIter, secondaryEnd)) {
flags.set(iCluster);
} else if (mDoQA == true || fRegistry != nullptr) {
fillAfterClusterHistogram(cluster, fRegistry);
}
currentCollID = cluster.emeventId();
++iCluster;
}
}
Expand All @@ -184,32 +299,47 @@ 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) const
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)
{
if (!IsSelectedEMCalRunning(EMCPhotonCuts::kDefinition, cluster)) {
fRegistry->fill(HIST("Cluster/hClusterQualityCuts"), static_cast<int>(EMCPhotonCuts::kDefinition) + 1, cluster.e());
return false;
}
if (!IsSelectedEMCalRunning(EMCPhotonCuts::kEnergy, cluster)) {
fRegistry->fill(HIST("Cluster/hClusterQualityCuts"), static_cast<int>(EMCPhotonCuts::kEnergy) + 1, cluster.e());
return false;
}
if (!IsSelectedEMCalRunning(EMCPhotonCuts::kNCell, cluster)) {
fRegistry->fill(HIST("Cluster/hClusterQualityCuts"), static_cast<int>(EMCPhotonCuts::kNCell) + 1, cluster.e());
return false;
}
if (!IsSelectedEMCalRunning(EMCPhotonCuts::kM02, cluster)) {
fRegistry->fill(HIST("Cluster/hClusterQualityCuts"), static_cast<int>(EMCPhotonCuts::kM02) + 1, cluster.e());
return false;
}
if (!IsSelectedEMCalRunning(EMCPhotonCuts::kTiming, cluster)) {
fRegistry->fill(HIST("Cluster/hClusterQualityCuts"), static_cast<int>(EMCPhotonCuts::kTiming) + 1, cluster.e());
return false;
}
if (mUseTM && (!IsSelectedEMCalRunning(EMCPhotonCuts::kTM, cluster, emcmatchedtrackIter, emcmatchedtrackEnd))) {
fRegistry->fill(HIST("Cluster/hClusterQualityCuts"), static_cast<int>(EMCPhotonCuts::kTM) + 1, cluster.e());
return false;
}
if (mUseSecondaryTM && (!IsSelectedEMCalRunning(EMCPhotonCuts::kSecondaryTM, cluster, secondaryIter, secondaryEnd))) {
fRegistry->fill(HIST("Cluster/hClusterQualityCuts"), static_cast<int>(EMCPhotonCuts::kSecondaryTM) + 1, cluster.e());
return false;
}
if (!IsSelectedEMCalRunning(EMCPhotonCuts::kExotic, cluster)) {
fRegistry->fill(HIST("Cluster/hClusterQualityCuts"), static_cast<int>(EMCPhotonCuts::kExotic) + 1, cluster.e());
return false;
}
fRegistry->fill(HIST("Cluster/hClusterQualityCuts"), static_cast<int>(EMCPhotonCuts::kNCuts) + 1, cluster.e());
if (currentCollID == cluster.emeventId()) {
++nAccClusterPerColl;
} else {
fRegistry->fill(HIST("Cluster/before/hNgamma"), nAccClusterPerColl);
nAccClusterPerColl = 0;
}
return true;
}

Expand Down Expand Up @@ -439,6 +569,10 @@ class EMCPhotonCut : public TNamed
/// \param flag flag to use secondary track matching
void SetUseSecondaryTM(bool flag = false);

/// \brief Set flag to do QA
/// \param flag flag to do QA
void SetDoQA(bool flag = false);

/// \brief Set parameters for track matching delta eta = a + (pT + b)^c
/// \param a a in a + (pT + b)^c
/// \param b b in a + (pT + b)^c
Expand Down Expand Up @@ -517,8 +651,13 @@ class EMCPhotonCut : public TNamed
float mMaxTime{25.f}; ///< maximum cluster timing
float mMinEoverP{1.75f}; ///< minimum cluster energy over track momentum ratio needed for the pair to be considered matched
bool mUseExoticCut{true}; ///< flag to decide if the exotic cluster cut is to be checked or not
bool mUseTM{true}; ///< flag to decide if track matching cut is to be checek or not
bool mUseSecondaryTM{false}; ///< flag to decide if seconary track matching cut is to be checek or not
bool mUseTM{true}; ///< flag to decide if track matching cut is to be check or not
bool mUseSecondaryTM{false}; ///< flag to decide if seconary track matching cut is to be check or not
bool mDoQA{false}; ///< flag to decide if QA should be done or not

uint nTotClusterPerColl{0}; ///< running number of all cluster per collision used for QA
uint nAccClusterPerColl{0}; ///< running number of accepted cluster per collision used for QA
int currentCollID{-1}; ///< running collision ID of clusters used for QA

TrackMatchingParams mTrackMatchingEtaParams = {-1.f, 0.f, 0.f};
TrackMatchingParams mTrackMatchingPhiParams = {-1.f, 0.f, 0.f};
Expand Down
5 changes: 3 additions & 2 deletions PWGEM/PhotonMeson/Tasks/taskPi0FlowEMC.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,7 @@ struct TaskPi0FlowEMC {
fEMCCut.SetClusterizer(emccuts.clusterDefinition);
fEMCCut.SetUseTM(emccuts.cfgEMCUseTM.value); // disables or enables TM
fEMCCut.SetUseSecondaryTM(emccuts.emcUseSecondaryTM.value); // disables or enables secondary TM
fEMCCut.SetDoQA(emccuts.cfgEnableQA.value);
}

void definePCMCut()
Expand Down Expand Up @@ -1095,7 +1096,7 @@ struct TaskPi0FlowEMC {
void processEMCal(CollsWithQvecs const& collisions, EMCalPhotons const& clusters, MinMTracks const& matchedPrims, MinMSTracks const& matchedSeconds)
{
EMBitFlags flags(clusters.size());
fEMCCut.AreSelectedRunning(flags, clusters, matchedPrims, matchedSeconds);
fEMCCut.AreSelectedRunning(flags, clusters, matchedPrims, matchedSeconds, &registry);

if (cfgDoReverseScaling.value) {
energyCorrectionFactor = 1.0505f;
Expand Down Expand Up @@ -1238,7 +1239,7 @@ struct TaskPi0FlowEMC {
void processEMCalPCMC(CollsWithQvecs const& collisions, EMCalPhotons const& clusters, PCMPhotons const& photons, aod::V0Legs const&, MinMTracks const& matchedPrims, MinMSTracks const& matchedSeconds)
{
EMBitFlags emcFlags(clusters.size());
fEMCCut.AreSelectedRunning(emcFlags, clusters, matchedPrims, matchedSeconds);
fEMCCut.AreSelectedRunning(emcFlags, clusters, matchedPrims, matchedSeconds, &registry);

if (cfgDoReverseScaling.value) {
energyCorrectionFactor = 1.0505f;
Expand Down
Loading