Skip to content
Merged
Changes from all commits
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
103 changes: 60 additions & 43 deletions PWGEM/PhotonMeson/Tasks/taskPi0FlowEMC.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,14 @@
#include <Math/GenVector/AxisAngle.h>
#include <Math/GenVector/Rotation3D.h>
#include <Math/Vector4D.h> // IWYU pragma: keep
#include <TF1.h>
#include <TH1.h>
#include <TString.h>

#include <array>
#include <cmath>
#include <cstdint>
#include <memory>
#include <numbers>
#include <string>
#include <string_view>
Expand Down Expand Up @@ -100,6 +102,8 @@ enum Harmonics {
};

struct TaskPi0FlowEMC {
static constexpr float MinEnergy = 0.7f;

// configurable for flow
Configurable<int> harmonic{"harmonic", 2, "harmonic number"};
Configurable<int> qvecDetector{"qvecDetector", 0, "Detector for Q vector estimation (FT0M: 0, FT0A: 1, FT0C: 2, TPC Pos: 3, TPC Neg: 4, TPC Tot: 5)"};
Expand Down Expand Up @@ -129,6 +133,7 @@ struct TaskPi0FlowEMC {
ConfigurableAxis thnConfigAxisCosDeltaPhi{"thnConfigAxisCosDeltaPhi", {8, -1., 1.}, ""};
ConfigurableAxis thnConfigAxisScalarProd{"thnConfigAxisScalarProd", {100, -5., 5.}, ""};
ConfigurableAxis thnConfigAxisM02{"thnConfigAxisM02", {200, 0., 5.}, ""};
ConfigurableAxis thnConfigAxisEnergyCalib{"thnConfigAxisEnergyCalib", {200, 0., 20.}, ""};

EMPhotonEventCut fEMEventCut;
struct : ConfigurableGroup {
Expand Down Expand Up @@ -195,6 +200,7 @@ struct TaskPi0FlowEMC {
Configurable<std::string> cfgSpresoPath{"cfgSpresoPath", "Users/m/mhemmer/EM/Flow/Resolution", "Path to SP resolution file"};
Configurable<int> cfgApplySPresolution{"cfgApplySPresolution", 0, "Apply resolution correction"};
Configurable<bool> doEMCalCalib{"doEMCalCalib", 0, "Produce output for EMCal calibration"};
Configurable<bool> cfgEnableNonLin{"cfgEnableNonLin", false, "flag to turn extra non linear energy calibration on/off"};
} correctionConfig;

SliceCache cache;
Expand All @@ -209,6 +215,7 @@ struct TaskPi0FlowEMC {
using EMCalPhotons = soa::Join<aod::EMCEMEventIds, aod::SkimEMCClusters>;
using FilteredCollsWithQvecs = soa::Filtered<soa::Join<aod::EMEvents, aod::EMEventsMult, aod::EMEventsCent, aod::EMEventsQvec>>;
using CollsWithQvecs = soa::Join<aod::EMEvents, aod::EMEventsMult, aod::EMEventsCent, aod::EMEventsQvec>;
using Colls = soa::Join<aod::EMEvents, aod::EMEventsMult, aod::EMEventsCent>;

Preslice<EMCalPhotons> perCollisionEMC = aod::emccluster::emeventId;

Expand All @@ -230,6 +237,9 @@ struct TaskPi0FlowEMC {
// static constexpr
static constexpr int64_t NMinPhotonRotBkg = 3;

// Usage when cfgEnableNonLin is enabled
std::unique_ptr<TF1> fEMCalCorrectionFactor; // ("fEMCalCorrectionFactor","(1 + [0]/x + [1]/x^2) / (1 + [2]/x)", 0.3, 100.);

// To access the 1D array
inline int getIndex(int iEta, int iPhi)
{
Expand Down Expand Up @@ -308,10 +318,10 @@ struct TaskPi0FlowEMC {
const AxisSpec thnAxisM02{thnConfigAxisM02, "M_{02}"};
const AxisSpec thAxisTanThetaPhi{mesonConfig.thConfigAxisTanThetaPhi, "atan(#Delta#theta/#Delta#varphi)"};
const AxisSpec thAxisClusterEnergy{thnConfigAxisPt, "#it{E} (GeV)"};
const AxisSpec thAxisEnergyCalib{thnConfigAxisEnergyCalib, "#it{E}_{clus} (GeV)"};
const AxisSpec thAxisAlpha{100, -1., +1, "#alpha"};
const AxisSpec thAxisMult{1000, 0., +1000, "#it{N}_{ch}"};
const AxisSpec thAxisEnergy{1000, 0., 100., "#it{E}_{clus} (GeV)"};
const AxisSpec thAxisEnergyCalib{400, 0., 20., "#it{E}_{clus} (GeV)"};
const AxisSpec thAxisTime{1500, -600, 900, "#it{t}_{cl} (ns)"};
const AxisSpec thAxisEta{320, -0.8, 0.8, "#eta"};
const AxisSpec thAxisPhi{500, 0, 2 * 3.14159, "phi"};
Expand Down Expand Up @@ -439,6 +449,9 @@ struct TaskPi0FlowEMC {

LOG(info) << "thnConfigAxisInvMass.value[1] = " << thnConfigAxisInvMass.value[1] << " thnConfigAxisInvMass.value.back() = " << thnConfigAxisInvMass.value.back();
LOG(info) << "thnConfigAxisPt.value[1] = " << thnConfigAxisPt.value[1] << " thnConfigAxisPt.value.back() = " << thnConfigAxisPt.value.back();

fEMCalCorrectionFactor = std::make_unique<TF1>("fEMCalCorrectionFactor", "(1 + [0]/x + [1]/x^2) / (1 + [2]/x)", 0.3, 100.);
fEMCalCorrectionFactor->SetParameters(-5.33426e-01, 1.40144e-02, -5.24434e-01);
}; // end init

/// Change radians to degree
Expand Down Expand Up @@ -475,7 +488,8 @@ struct TaskPi0FlowEMC {

/// Get the centrality
/// \param collision is the collision with the centrality information
float getCentrality(CollsWithQvecs::iterator const& collision)
template <typename TCollision>
float getCentrality(TCollision const& collision)
{
float cent = -999.;
switch (centEstimator) {
Expand Down Expand Up @@ -728,7 +742,11 @@ struct TaskPi0FlowEMC {
if (checkEtaPhi1D(photon.eta(), RecoDecay::constrainAngle(photon.phi())) >= cfgEMCalMapLevelBackground.value) {
continue;
}
ROOT::Math::PtEtaPhiMVector photon3(photon.pt(), photon.eta(), photon.phi(), 0.);
float energyCorrectionFactor = 1.f;
if (correctionConfig.cfgEnableNonLin.value) {
energyCorrectionFactor = fEMCalCorrectionFactor->Eval(photon.e() > MinEnergy ? photon.e() : MinEnergy);
}
ROOT::Math::PtEtaPhiMVector photon3(energyCorrectionFactor * photon.pt(), photon.eta(), photon.phi(), 0.);
if (iCellIDPhoton1 >= 0) {
ROOT::Math::PtEtaPhiMVector mother1 = photon1 + photon3;
float openingAngle1 = std::acos(photon1.Vect().Dot(photon3.Vect()) / (photon1.P() * photon3.P()));
Expand Down Expand Up @@ -780,8 +798,8 @@ struct TaskPi0FlowEMC {
}

/// \brief Calculate background using rotation background method for calib
template <typename TPhotons>
void rotationBackgroundCalib(const ROOT::Math::PtEtaPhiMVector& meson, ROOT::Math::PtEtaPhiMVector photon1, ROOT::Math::PtEtaPhiMVector photon2, TPhotons const& photons_coll, unsigned int ig1, unsigned int ig2, CollsWithQvecs::iterator const& collision)
template <typename TPhotons, typename TCollision>
void rotationBackgroundCalib(const ROOT::Math::PtEtaPhiMVector& meson, ROOT::Math::PtEtaPhiMVector photon1, ROOT::Math::PtEtaPhiMVector photon2, TPhotons const& photons_coll, unsigned int ig1, unsigned int ig2, TCollision const& collision)
{
// if less than 3 clusters are present skip event since we need at least 3 clusters
if (photons_coll.size() < NMinPhotonRotBkg) {
Expand Down Expand Up @@ -817,7 +835,11 @@ struct TaskPi0FlowEMC {
if (checkEtaPhi1D(photon.eta(), RecoDecay::constrainAngle(photon.phi())) >= cfgEMCalMapLevelBackground.value) {
continue;
}
ROOT::Math::PtEtaPhiMVector photon3(photon.pt(), photon.eta(), photon.phi(), 0.);
float energyCorrectionFactor = 1.f;
if (correctionConfig.cfgEnableNonLin.value) {
energyCorrectionFactor = fEMCalCorrectionFactor->Eval(photon.e() > MinEnergy ? photon.e() : MinEnergy);
}
ROOT::Math::PtEtaPhiMVector photon3(energyCorrectionFactor * photon.pt(), photon.eta(), photon.phi(), 0.);
if (iCellIDPhoton1 >= 0) {
if (std::fabs((photon1.E() - photon3.E()) / (photon1.E() + photon3.E()) < cfgMaxAsymmetry)) { // only use symmetric decays
ROOT::Math::PtEtaPhiMVector mother1 = photon1 + photon3;
Expand Down Expand Up @@ -893,6 +915,10 @@ struct TaskPi0FlowEMC {
void processEMCal(CollsWithQvecs const& collisions, EMCalPhotons const& clusters)
{
int nColl = 1;
float energyCorrectionFactor = 1.f;
if (cfgDoReverseScaling.value) {
energyCorrectionFactor = 1.0505f;
}
for (const auto& collision : collisions) {
auto photonsPerCollision = clusters.sliceBy(perCollisionEMC, collision.globalIndex());

Expand Down Expand Up @@ -971,18 +997,14 @@ struct TaskPi0FlowEMC {
continue;
}
}

ROOT::Math::PtEtaPhiMVector v1(g1.pt(), g1.eta(), g1.phi(), 0.);
ROOT::Math::PtEtaPhiMVector v2(g2.pt(), g2.eta(), g2.phi(), 0.);
if (cfgDoReverseScaling.value) {
// Convert to PxPyPzEVector to modify energy
ROOT::Math::PxPyPzEVector v1Mod(v1);
v1Mod.SetE(v1Mod.E() * 1.0505);
v1 = ROOT::Math::PtEtaPhiMVector(v1Mod.Pt(), v1Mod.Eta(), v1Mod.Phi(), 0.);
ROOT::Math::PxPyPzEVector v2Mod(v2);
v2Mod.SetE(v2Mod.E() * 1.0505);
v2 = ROOT::Math::PtEtaPhiMVector(v2Mod.Pt(), v2Mod.Eta(), v2Mod.Phi(), 0.);
if (correctionConfig.cfgEnableNonLin.value) {
energyCorrectionFactor = fEMCalCorrectionFactor->Eval(g1.e() > MinEnergy ? g1.e() : MinEnergy);
}
ROOT::Math::PtEtaPhiMVector v1(energyCorrectionFactor * g1.pt(), g1.eta(), g1.phi(), 0.);
if (correctionConfig.cfgEnableNonLin.value) {
energyCorrectionFactor = fEMCalCorrectionFactor->Eval(g2.e() > MinEnergy ? g2.e() : MinEnergy);
}
ROOT::Math::PtEtaPhiMVector v2(energyCorrectionFactor * g2.pt(), g2.eta(), g2.phi(), 0.);
ROOT::Math::PtEtaPhiMVector vMeson = v1 + v2;
float dTheta = v1.Theta() - v2.Theta();
float dPhi = v1.Phi() - v2.Phi();
Expand Down Expand Up @@ -1031,6 +1053,10 @@ struct TaskPi0FlowEMC {
// Pi0 from EMCal
void processEMCalMixed(FilteredCollsWithQvecs const& collisions, FilteredEMCalPhotons const& clusters)
{
float energyCorrectionFactor = 1.f;
if (cfgDoReverseScaling.value) {
energyCorrectionFactor = 1.0505f;
}
auto getClustersSize =
[&clusters, this](FilteredCollsWithQvecs::iterator const& col) {
auto associatedClusters = clusters.sliceByCached(emccluster::emeventId, col.globalIndex(), this->cache); // it's cached, so slicing/grouping happens only once
Expand Down Expand Up @@ -1079,18 +1105,14 @@ struct TaskPi0FlowEMC {
continue;
}
}
ROOT::Math::PtEtaPhiMVector v1(g1.pt(), g1.eta(), g1.phi(), 0.);
ROOT::Math::PtEtaPhiMVector v2(g2.pt(), g2.eta(), g2.phi(), 0.);

if (cfgDoReverseScaling.value) {
// Convert to PxPyPzEVector to modify energy
ROOT::Math::PxPyPzEVector v1Mod(v1);
v1Mod.SetE(v1Mod.E() * 1.0505);
v1 = ROOT::Math::PtEtaPhiMVector(v1Mod.Pt(), v1Mod.Eta(), v1Mod.Phi(), 0.);
ROOT::Math::PxPyPzEVector v2Mod(v2);
v2Mod.SetE(v2Mod.E() * 1.0505);
v2 = ROOT::Math::PtEtaPhiMVector(v2Mod.Pt(), v2Mod.Eta(), v2Mod.Phi(), 0.);
if (correctionConfig.cfgEnableNonLin.value) {
energyCorrectionFactor = fEMCalCorrectionFactor->Eval(g1.e() > MinEnergy ? g1.e() : MinEnergy);
}
ROOT::Math::PtEtaPhiMVector v1(energyCorrectionFactor * g1.pt(), g1.eta(), g1.phi(), 0.);
if (correctionConfig.cfgEnableNonLin.value) {
energyCorrectionFactor = fEMCalCorrectionFactor->Eval(g2.e() > MinEnergy ? g2.e() : MinEnergy);
}
ROOT::Math::PtEtaPhiMVector v2(energyCorrectionFactor * g2.pt(), g2.eta(), g2.phi(), 0.);
ROOT::Math::PtEtaPhiMVector vMeson = v1 + v2;

float dTheta = v1.Theta() - v2.Theta();
Expand Down Expand Up @@ -1247,8 +1269,9 @@ struct TaskPi0FlowEMC {
PROCESS_SWITCH(TaskPi0FlowEMC, processResolution, "Process resolution", false);

// EMCal calibration
void processEMCalCalib(CollsWithQvecs const& collisions, EMCalPhotons const& clusters)
void processEMCalCalib(Colls const& collisions, EMCalPhotons const& clusters)
{
float energyCorrectionFactor = 1.f;
if (!correctionConfig.doEMCalCalib) {
return;
}
Expand All @@ -1269,10 +1292,6 @@ struct TaskPi0FlowEMC {
// event selection
continue;
}
if (!isQvecGood(getAllQvec(collision))) {
// selection based on QVector
continue;
}
runNow = collision.runNumber();
if (runNow != runBefore) {
initCCDB(collision);
Expand Down Expand Up @@ -1306,18 +1325,16 @@ struct TaskPi0FlowEMC {
}
}

ROOT::Math::PtEtaPhiMVector v1(g1.pt(), g1.eta(), g1.phi(), 0.);
ROOT::Math::PtEtaPhiMVector v2(g2.pt(), g2.eta(), g2.phi(), 0.);
if (cfgDoReverseScaling.value) {
// Convert to PxPyPzEVector to modify energy
ROOT::Math::PxPyPzEVector v1Mod(v1);
v1Mod.SetE(v1Mod.E() * 1.0505);
v1 = ROOT::Math::PtEtaPhiMVector(v1Mod.Pt(), v1Mod.Eta(), v1Mod.Phi(), 0.);
ROOT::Math::PxPyPzEVector v2Mod(v2);
v2Mod.SetE(v2Mod.E() * 1.0505);
v2 = ROOT::Math::PtEtaPhiMVector(v2Mod.Pt(), v2Mod.Eta(), v2Mod.Phi(), 0.);
if (correctionConfig.cfgEnableNonLin.value) {
energyCorrectionFactor = fEMCalCorrectionFactor->Eval(g1.e() > MinEnergy ? g1.e() : MinEnergy);
}
ROOT::Math::PtEtaPhiMVector v1(energyCorrectionFactor * g1.pt(), g1.eta(), g1.phi(), 0.);
if (correctionConfig.cfgEnableNonLin.value) {
energyCorrectionFactor = fEMCalCorrectionFactor->Eval(g2.e() > MinEnergy ? g2.e() : MinEnergy);
}
ROOT::Math::PtEtaPhiMVector v2(energyCorrectionFactor * g2.pt(), g2.eta(), g2.phi(), 0.);
ROOT::Math::PtEtaPhiMVector vMeson = v1 + v2;

float dTheta = v1.Theta() - v2.Theta();
float dPhi = v1.Phi() - v2.Phi();
float openingAngle = std::acos(v1.Vect().Dot(v2.Vect()) / (v1.P() * v2.P()));
Expand Down
Loading