3838#include < Framework/AnalysisHelpers.h>
3939#include < Framework/AnalysisTask.h>
4040#include < Framework/BinningPolicy.h>
41+ #include < Framework/Concepts.h>
4142#include < Framework/Configurable.h>
4243#include < Framework/Expressions.h>
4344#include < Framework/GroupedCombinations.h>
@@ -172,6 +173,7 @@ struct TaskPi0FlowEMC {
172173 Configurable<bool > cfgEMCUseTM{" cfgEMCUseTM" , false , " flag to use EMCal track matching cut or not" };
173174 Configurable<bool > emcUseSecondaryTM{" emcUseSecondaryTM" , false , " flag to use EMCal secondary track matching cut or not" };
174175 Configurable<bool > cfgEnableQA{" cfgEnableQA" , false , " flag to turn QA plots on/off" };
176+ Configurable<bool > separateEMCalDCal{" separateEMCalDCal" , false , " flag to only pair EMCal with EMCal and DCal with DCal clusters" };
175177 } emccuts;
176178
177179 V0PhotonCut fV0PhotonCut ;
@@ -251,6 +253,8 @@ struct TaskPi0FlowEMC {
251253 int runNow = 0 ;
252254 int runBefore = -1 ;
253255
256+ static constexpr float MaxPhiEMCal = 3 .5f ;
257+
254258 // Filter clusterFilter = aod::skimmedcluster::time >= emccuts.cfgEMCminTime && aod::skimmedcluster::time <= emccuts.cfgEMCmaxTime && aod::skimmedcluster::m02 >= emccuts.cfgEMCminM02 && aod::skimmedcluster::m02 <= emccuts.cfgEMCmaxM02 && aod::skimmedcluster::e >= emccuts.cfgEMCminE;
255259 Filter collisionFilter = (nabs(aod::collision::posZ) <= eventcuts.cfgZvtxMax) && (aod::evsel::ft0cOccupancyInTimeRange <= eventcuts.cfgFT0COccupancyMax) && (aod::evsel::ft0cOccupancyInTimeRange >= eventcuts.cfgFT0COccupancyMin);
256260 // using FilteredEMCalPhotons = soa::Filtered<soa::Join<aod::EMCEMEventIds, aod::MinClusters>>;
@@ -260,10 +264,13 @@ struct TaskPi0FlowEMC {
260264 using CollsWithQvecs = soa::Join<aod::PMEvents, aod::EMEventsAlias, aod::EMEventsMult_000, aod::EMEventsCent_000, aod::EMEventsQvec_001>;
261265 using Colls = soa::Join<aod::PMEvents, aod::EMEventsAlias, aod::EMEventsMult_000, aod::EMEventsCent_000>;
262266
267+ Partition<EMCalPhotons> emcalPhotons = aod::mincluster::storedPhi < std::lround(MaxPhiEMCal * emcdownscaling::downscalingFactors[emcdownscaling::kPhi ]);
268+ Partition<EMCalPhotons> dcalPhotons = aod::mincluster::storedPhi >= std::lround(MaxPhiEMCal * emcdownscaling::downscalingFactors[emcdownscaling::kPhi ]);
269+
263270 static constexpr std::size_t NQVecEntries = 6 ;
264271
265- PresliceOptional<EMCalPhotons > perCollisionEMC = o2::aod::emccluster::pmeventId;
266- PresliceOptional<PCMPhotons > perCollisionPCM = aod::v0photonkf::pmeventId;
272+ PresliceOptional<aod::EMCEMEventIds > perCollisionEMC = o2::aod::emccluster::pmeventId;
273+ PresliceOptional<aod::V0KFEMEventIds > perCollisionPCM = aod::v0photonkf::pmeventId;
267274 PresliceOptional<MinMTracks> perEMCClusterMT = o2::aod::mintm::minClusterId;
268275 PresliceOptional<MinMSTracks> perEMCClusterMS = o2::aod::mintm::minClusterId;
269276
@@ -481,6 +488,13 @@ struct TaskPi0FlowEMC {
481488
482489 }; // end init
483490
491+ // / \brief Check whether a photon (by its phi) falls in the EMCal or DCal acceptance
492+ // / \param phi azimuthal angle of the photon
493+ static bool isEMCalRegion (float phi)
494+ {
495+ return phi < MaxPhiEMCal;
496+ }
497+
484498 // / Change radians to degree
485499 // / \param angle in radians
486500 // / \return angle in degree
@@ -1047,7 +1061,7 @@ struct TaskPi0FlowEMC {
10471061 continue ;
10481062 }
10491063 if (rotationConfig.cfgDoRotation .value && nColl % rotationConfig.cfgDownsampling == 0 ) {
1050- rotationBackground<EMCalPhotons >(vMeson, v1, v2, photons1, g1.globalIndex (), g2.globalIndex (), collision);
1064+ rotationBackground<TPhotons1 >(vMeson, v1, v2, photons1, g1.globalIndex (), g2.globalIndex (), collision);
10511065 }
10521066 if (thnConfigAxisInvMass.value [1 ] > vMeson.M () || thnConfigAxisInvMass.value .back () < vMeson.M ()) {
10531067 registry.fill (HIST (" hMesonCuts" ), 3 );
@@ -1093,6 +1107,8 @@ struct TaskPi0FlowEMC {
10931107 }
10941108
10951109 auto photonsPerCollision = clusters.sliceBy (perCollisionEMC, collision.globalIndex ());
1110+ auto emcalPhotonsPerCollision = emcalPhotons.sliceBy (perCollisionEMC, collision.globalIndex ());
1111+ auto dcalPhotonsPerCollision = dcalPhotons.sliceBy (perCollisionEMC, collision.globalIndex ());
10961112
10971113 if (emccuts.cfgEnableQA .value ) {
10981114 for (const auto & photon : photonsPerCollision) {
@@ -1108,7 +1124,12 @@ struct TaskPi0FlowEMC {
11081124 registry.fill (HIST (" clusterQA/hClusterEtaPhiAfter" ), photon.phi (), photon.eta ()); // after cuts
11091125 }
11101126 }
1111- runPairingLoop (collision, photonsPerCollision, photonsPerCollision, flags, flags);
1127+ if (emccuts.separateEMCalDCal .value ) {
1128+ runPairingLoop (collision, emcalPhotonsPerCollision, emcalPhotonsPerCollision, flags, flags);
1129+ runPairingLoop (collision, dcalPhotonsPerCollision, dcalPhotonsPerCollision, flags, flags);
1130+ } else {
1131+ runPairingLoop (collision, photonsPerCollision, photonsPerCollision, flags, flags);
1132+ }
11121133 if (rotationConfig.cfgDoRotation .value ) {
11131134 if (nColl % rotationConfig.cfgDownsampling == 0 ) {
11141135 nColl = 1 ; // reset counter
@@ -1163,6 +1184,10 @@ struct TaskPi0FlowEMC {
11631184 if (!(flags.test (g1.globalIndex ())) || !(flags.test (g2.globalIndex ()))) {
11641185 continue ;
11651186 }
1187+ if (emccuts.separateEMCalDCal .value && isEMCalRegion (g1.phi ()) != isEMCalRegion (g2.phi ())) {
1188+ continue ; // only pair EMCal-EMCal or DCal-DCal
1189+ }
1190+
11661191 // Cut edge clusters away, similar to rotation method to ensure same acceptance is used
11671192 if (cfgDistanceToEdge.value > 0 ) {
11681193 if (checkEtaPhi1D (g1.eta (), RecoDecay::constrainAngle (g1.phi ())) >= cfgEMCalMapLevelBackground.value ) {
0 commit comments