1010// or submit itself to any jurisdiction.
1111
1212// / \file flowZdcEnergy.cxx
13- // / \author Kegang Xiong (kegang.xiong@cern.ch)
13+ // / \author Kegang Xiong
1414// / \since 03/2026
15- // / \brief A try to use the znc energy .
15+ // / \brief Study ZDC energy observables versus centrality for Run 2 / Run 3 .
1616
17- #include " Common/Core/EventPlaneHelper.h"
18- #include " Common/Core/RecoDecay.h"
19- #include " Common/Core/TrackSelection.h"
2017#include " Common/DataModel/Centrality.h"
2118#include " Common/DataModel/EventSelection.h"
2219#include " Common/DataModel/Multiplicity.h"
23- #include " Common/DataModel/Qvectors.h"
24- #include " Common/DataModel/TrackSelectionTables.h"
2520
2621#include " CCDB/BasicCCDBManager.h"
27- #include " DataFormatsParameters/GRPLHCIFData.h"
28- #include " DataFormatsParameters/GRPMagField.h"
29- #include " Framework/ASoAHelpers.h"
3022#include " Framework/AnalysisTask.h"
3123#include " Framework/HistogramRegistry.h"
3224#include " Framework/RunningWorkflowInfo.h"
3325#include " Framework/runDataProcessing.h"
3426
35- #include " TF1.h"
36- #include " TPDGCode.h"
37-
38- #include < algorithm>
39- #include < map>
40- #include < numeric>
41- #include < string>
42- #include < unordered_map>
43- #include < utility>
44- #include < vector>
27+ #include < chrono>
28+ #include < cmath>
29+ #include < cstdint>
4530
4631using namespace o2 ;
4732using namespace o2 ::framework;
48- using namespace o2 ::framework::expressions;
49- using namespace o2 ::aod::rctsel;
50- // using namespace o2::analysis;
5133
5234#define O2_DEFINE_CONFIGURABLE (NAME, TYPE, DEFAULT, HELP ) Configurable<TYPE> NAME{#NAME, DEFAULT, HELP};
5335
5436struct flowZdcEnergy {
5537
56- struct : ConfigurableGroup {
57- // Additional event selections
58- O2_DEFINE_CONFIGURABLE (cfgCentMin, float , 0 , " Minimum cenrality for selected events" );
59- O2_DEFINE_CONFIGURABLE (cfgCentMax, float , 90 , " Maximum cenrality for selected events" );
60- O2_DEFINE_CONFIGURABLE (cfgVtxZ, float , 10 .0f , " Accepted z-vertex range for selected events" )
61- } EvSel;
62-
63- // Configurables containing vector
64- O2_DEFINE_CONFIGURABLE (cfgEtaMax, float , 0 .8f , " Maximum track #eta" )
65- O2_DEFINE_CONFIGURABLE (cfgPtMin, float , 0 .2f , " Minimum track #P_{t}" )
66- O2_DEFINE_CONFIGURABLE (cfgPtMax, float , 10 .0f , " Maximum track #P_{t}" )
67- O2_DEFINE_CONFIGURABLE (cfgDcaXYMax, float , 0 .2f , " Maximum DCAxy" )
68- O2_DEFINE_CONFIGURABLE (cfgDcaZMax, float , 2 .0f , " Maximum DCAz" )
69-
70- enum SelectionCriteria {
71- evSel_AllEvent,
72- evSel_sel8,
73- evSel_Zvtx,
74- evSel_CentCuts,
75- evSel_BCHasZDC,
76- evSel_isSelectedZDC,
77- nEventSelections
38+ struct : ConfigurableGroup{
39+ O2_DEFINE_CONFIGURABLE (cfgCentMin, float , 0 .f, " Minimum centrality for selected events" )
40+ O2_DEFINE_CONFIGURABLE (cfgCentMax, float , 90 .f, " Maximum centrality for selected events" )
41+ O2_DEFINE_CONFIGURABLE (cfgVtxZ, float , 10 .f, " Accepted z-vertex range" )} evsel;
42+
43+ ConfigurableAxis axisCent{" axisCent" , {90 , 0 , 90 }, " Centrality (%)" };
44+ ConfigurableAxis axisMult{" axisMult" , {100 , 0 , 100000 }, " Multiplicity" };
45+ ConfigurableAxis axisEnergy{" axisEnergy" , {300 , 0 , 300 }, " Energy" };
46+ ConfigurableAxis axisRescaledDiff{" axisRescaledDiff" , {400 , -1 , 1 }, " (EA-EC)/(EA+EC)" };
47+
48+ // Event counter bins
49+ enum SelectionCriteria : uint8_t {
50+ kAllEvents = 0 ,
51+ kSeln ,
52+ kZvtx ,
53+ kCentrality ,
54+ kBCHasZDC ,
55+ kSelectedZDC ,
56+ kNSelections
7857 };
7958
80- ConfigurableAxis axisCent = {" axisCent" , {100 , 0 , 100 }, " Centrality(%)" };
81- ConfigurableAxis axisEnergy = {" axisEnergy" , {300 , 0 , 300 }, " Energy" };
82- ConfigurableAxis axisRescaledDiff = {" axisRescaledDiff" , {400 , -1 , 1 }, " (#E_{A}-#E_{C}) / (#E_{A}+#E_{C})" };
83-
84- // Filter trackFilter = nabs(aod::track::eta) < cfgEtaMax && aod::track::pt > cfgPtMin&& aod::track::pt < cfgPtMax && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true)) && nabs(aod::track::dcaXY) < cfgDcaXYMax&& nabs(aod::track::dcaZ) < cfgDcaZMax;
85-
86- // using UsedTracks = soa::Filtered<soa::Join<aod::Tracks, aod::TracksExtra, aod::TrackSelection, aod::TracksDCA>>;
87- using ZDCCollisions = soa::Join<aod::Collisions, aod::EvSels, aod::Mults, aod::CentFT0Cs>;
88- using BCsRun3 = soa::Join<aod::BCs, aod::Timestamps, aod::BcSels, aod::Run3MatchedToBCSparse>;
89-
90- // Connect to ccdb
9159 Service<ccdb::BasicCCDBManager> ccdb;
92-
9360 HistogramRegistry registry{" registry" };
9461
62+ // Run 3
63+ using CollisionsRun3 = soa::Join<aod::Collisions, aod::EvSels, aod::Mults, aod::CentFT0Cs>;
64+ using BCsRun3 = soa::Join<aod::BCs, aod::Timestamps, aod::BcSels, aod::Run3MatchedToBCSparse>;
65+ // Run 2
66+ using CollisionsRun2 = soa::Join<aod::Collisions, aod::EvSels, aod::Mults, aod::CentRun2V0Ms>;
67+ using BCsRun2 = soa::Join<aod::BCs, aod::Timestamps, aod::BcSels, aod::Run2MatchedToBCSparse>;
68+
9569 void init (InitContext const &)
9670 {
9771 ccdb->setURL (" http://alice-ccdb.cern.ch" );
9872 ccdb->setCaching (true );
9973 ccdb->setLocalObjectValidityChecking ();
10074
101- int64_t now = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now ().time_since_epoch ()).count ();
75+ auto now = std::chrono::duration_cast<std::chrono::milliseconds>(
76+ std::chrono::system_clock::now ().time_since_epoch ())
77+ .count ();
10278 ccdb->setCreatedNotAfter (now);
10379
104- // QA hist
105- registry.add (" hEventCount" , " Number of Event; Cut; #Events Passed Cut" , {HistType::kTH1D , {{nEventSelections, 0 , nEventSelections}}});
106- registry.get <TH1>(HIST (" hEventCount" ))->GetXaxis ()->SetBinLabel (evSel_AllEvent + 1 , " All events" );
107- registry.get <TH1>(HIST (" hEventCount" ))->GetXaxis ()->SetBinLabel (evSel_sel8 + 1 , " Sel8" );
108- registry.get <TH1>(HIST (" hEventCount" ))->GetXaxis ()->SetBinLabel (evSel_Zvtx + 1 , " Z vertex cut event" );
109- registry.get <TH1>(HIST (" hEventCount" ))->GetXaxis ()->SetBinLabel (evSel_CentCuts + 1 , " Cenrality range" );
110- registry.get <TH1>(HIST (" hEventCount" ))->GetXaxis ()->SetBinLabel (evSel_BCHasZDC + 1 , " BCHasZDC" );
111- registry.get <TH1>(HIST (" hEventCount" ))->GetXaxis ()->SetBinLabel (evSel_isSelectedZDC + 1 , " isSelected" );
112- // ana hist
80+ registry.add (" hEventCount" , " Event counter;Selection;Events" , {HistType::kTH1D , {{kNSelections , 0 , kNSelections }}});
81+ auto hCount = registry.get <TH1>(HIST (" hEventCount" ));
82+ hCount->GetXaxis ()->SetBinLabel (kAllEvents + 1 , " All events" );
83+ hCount->GetXaxis ()->SetBinLabel (kSeln + 1 , " Sel7/8" );
84+ hCount->GetXaxis ()->SetBinLabel (kZvtx + 1 , " Zvtx" );
85+ hCount->GetXaxis ()->SetBinLabel (kCentrality + 1 , " Centrality" );
86+ hCount->GetXaxis ()->SetBinLabel (kBCHasZDC + 1 , " BC has ZDC" );
87+ hCount->GetXaxis ()->SetBinLabel (kSelectedZDC + 1 , " Selected ZDC" );
88+
89+ registry.add (" hCentrality" , " " , {HistType::kTH1D , {axisCent}});
90+ registry.add (" hMultiplicity" , " " , {HistType::kTH1D , {axisMult}});
91+
11392 registry.add (" hEnergyWithCent_ZNA_Common" , " " , {HistType::kTH2D , {axisEnergy, axisCent}});
11493 registry.add (" hEnergyWithCent_ZNC_Common" , " " , {HistType::kTH2D , {axisEnergy, axisCent}});
11594 registry.add (" hEnergyWithCent_RescaledDiff" , " " , {HistType::kTH2D , {axisRescaledDiff, axisCent}});
@@ -126,65 +105,124 @@ struct flowZdcEnergy {
126105 registry.add (" hEnergyWithCent_RescaledSumDiff" , " " , {HistType::kTH2D , {axisRescaledDiff, axisCent}});
127106 }
128107
129- void process (ZDCCollisions::iterator const & collision, BCsRun3 const & /* bcs*/ , aod::Zdcs const & /* zdcs*/ )
108+ // Helper: event selection
109+ template <typename TCollision>
110+ bool acceptEvent (TCollision const & collision, float centrality, const int runmode)
130111 {
112+ registry.fill (HIST (" hEventCount" ), kAllEvents );
131113
132- double centrality = collision.centFT0C ();
133- // event selection
134- registry.fill (HIST (" hEventCount" ), evSel_AllEvent);
135- if (!collision.sel8 ()) {
136- return ;
114+ if (runmode == 2 && !collision.sel7 ()) {
115+ return false ;
137116 }
138- registry.fill (HIST (" hEventCount" ), evSel_sel8);
139- if (std::abs (collision.posZ ()) > EvSel.cfgVtxZ ) {
140- return ;
117+ if (runmode == 3 && !collision.sel8 ()) {
118+ return false ;
141119 }
142- registry.fill (HIST (" hEventCount" ), evSel_Zvtx);
143- if (centrality < EvSel.cfgCentMin || centrality > EvSel.cfgCentMax ) {
144- return ;
120+ registry.fill (HIST (" hEventCount" ), kSeln );
121+
122+ if (std::abs (collision.posZ ()) > evsel.cfgVtxZ ) {
123+ return false ;
124+ }
125+ registry.fill (HIST (" hEventCount" ), kZvtx );
126+
127+ if (centrality < evsel.cfgCentMin || centrality > evsel.cfgCentMax ) {
128+ return false ;
145129 }
146- registry.fill (HIST (" hEventCount" ), evSel_CentCuts );
130+ registry.fill (HIST (" hEventCount" ), kCentrality );
147131
148- const auto & foundBC = collision.foundBC_as <BCsRun3>();
132+ return true ;
133+ }
134+
135+ // Helper: fill ZDC observables
136+ template <typename TCollision, typename TBCs>
137+ void fillZDCObservables (TCollision const & collision, float centrality)
138+ {
139+ const auto & foundBC = collision.template foundBC_as <TBCs>();
149140 if (!foundBC.has_zdc ()) {
150141 return ;
151142 }
152- registry.fill (HIST (" hEventCount" ), evSel_BCHasZDC );
143+ registry.fill (HIST (" hEventCount" ), kBCHasZDC );
153144
154- const auto & zdcCol = foundBC.zdc ();
155- if (zdcCol .energyCommonZNA () <= 0 || zdcCol .energyCommonZNC () <= 0 ) {
145+ const auto & zdc = foundBC.zdc ();
146+ if (zdc .energyCommonZNA () <= 1 . f || zdc .energyCommonZNC () <= 1 . f ) {
156147 return ;
157148 }
158- registry.fill (HIST (" hEventCount" ), evSel_isSelectedZDC);
149+ registry.fill (HIST (" hEventCount" ), kSelectedZDC );
150+
151+ const float energyCommonZNA = zdc.energyCommonZNA ();
152+ const float energyCommonZNC = zdc.energyCommonZNC ();
153+ const float energySectorZNA1 = zdc.energySectorZNA ()[0 ];
154+ const float energySectorZNA2 = zdc.energySectorZNA ()[1 ];
155+ const float energySectorZNA3 = zdc.energySectorZNA ()[2 ];
156+ const float energySectorZNA4 = zdc.energySectorZNA ()[3 ];
157+ const float energySectorZNC1 = zdc.energySectorZNC ()[0 ];
158+ const float energySectorZNC2 = zdc.energySectorZNC ()[1 ];
159+ const float energySectorZNC3 = zdc.energySectorZNC ()[2 ];
160+ const float energySectorZNC4 = zdc.energySectorZNC ()[3 ];
161+
162+ const float sumEnergyZNA = energySectorZNA1 + energySectorZNA2 + energySectorZNA3 + energySectorZNA4;
163+ const float sumEnergyZNC = energySectorZNC1 + energySectorZNC2 + energySectorZNC3 + energySectorZNC4;
164+
165+ const float commonDen = energyCommonZNA + energyCommonZNC;
166+ const float sumDen = sumEnergyZNA + sumEnergyZNC;
167+
168+ registry.fill (HIST (" hEnergyWithCent_ZNA_Common" ), energyCommonZNA, centrality);
169+ registry.fill (HIST (" hEnergyWithCent_ZNC_Common" ), energyCommonZNC, centrality);
170+ registry.fill (HIST (" hEnergyWithCent_ZNA_1" ), energySectorZNA1, centrality);
171+ registry.fill (HIST (" hEnergyWithCent_ZNA_2" ), energySectorZNA2, centrality);
172+ registry.fill (HIST (" hEnergyWithCent_ZNA_3" ), energySectorZNA3, centrality);
173+ registry.fill (HIST (" hEnergyWithCent_ZNA_4" ), energySectorZNA4, centrality);
174+ registry.fill (HIST (" hEnergyWithCent_ZNC_1" ), energySectorZNC1, centrality);
175+ registry.fill (HIST (" hEnergyWithCent_ZNC_2" ), energySectorZNC2, centrality);
176+ registry.fill (HIST (" hEnergyWithCent_ZNC_3" ), energySectorZNC3, centrality);
177+ registry.fill (HIST (" hEnergyWithCent_ZNC_4" ), energySectorZNC4, centrality);
178+ registry.fill (HIST (" hEnergyWithCent_ZNA_SumSectors" ), sumEnergyZNA, centrality);
179+ registry.fill (HIST (" hEnergyWithCent_ZNC_SumSectors" ), sumEnergyZNC, centrality);
180+
181+ if (commonDen > 1 .e -6f ) {
182+ registry.fill (HIST (" hEnergyWithCent_RescaledDiff" ), (energyCommonZNA - energyCommonZNC) / commonDen, centrality);
183+ }
184+ if (sumDen > 1 .e -6f ) {
185+ registry.fill (HIST (" hEnergyWithCent_RescaledSumDiff" ), (sumEnergyZNA - sumEnergyZNC) / sumDen, centrality);
186+ }
187+ }
159188
160- double SumEnergyZNA = zdcCol.energySectorZNA ()[0 ] + zdcCol.energySectorZNA ()[1 ] + zdcCol.energySectorZNA ()[2 ] + zdcCol.energySectorZNA ()[3 ];
161- double SumEnergyZNC = zdcCol.energySectorZNC ()[0 ] + zdcCol.energySectorZNC ()[1 ] + zdcCol.energySectorZNC ()[2 ] + zdcCol.energySectorZNC ()[3 ];
162- double commonDen = zdcCol.energyCommonZNA () + zdcCol.energyCommonZNC ();
163- double sumDen = SumEnergyZNA + SumEnergyZNC;
189+ // Run 3 process
190+ void processRun3 (CollisionsRun3::iterator const & collision,
191+ BCsRun3 const &,
192+ aod::Zdcs const &)
193+ {
194+ const float centrality = collision.centFT0C ();
195+ const float multi = collision.multFT0C ();
164196
165- if (commonDen > 1e-3 ) {
166- registry.fill (HIST (" hEnergyWithCent_RescaledDiff" ),
167- (zdcCol.energyCommonZNA () - zdcCol.energyCommonZNC ()) / commonDen,
168- centrality);
197+ if (!acceptEvent (collision, centrality, 3 )) {
198+ return ;
169199 }
170- if (sumDen > 1e-3 ) {
171- registry.fill (HIST (" hEnergyWithCent_RescaledSumDiff" ),
172- (SumEnergyZNA - SumEnergyZNC) / sumDen,
173- centrality);
200+ registry.fill (HIST (" hCentrality" ), centrality);
201+ registry.fill (HIST (" hMultiplicity" ), multi);
202+
203+ fillZDCObservables<CollisionsRun3::iterator, BCsRun3>(collision, centrality);
204+ }
205+
206+ // Run 2 process
207+ void processRun2 (CollisionsRun2::iterator const & collision,
208+ BCsRun2 const &,
209+ aod::Zdcs const &)
210+ {
211+ const float centrality = collision.centRun2V0M ();
212+ const float multi = collision.multFV0M ();
213+
214+ if (!acceptEvent (collision, centrality, 2 )) {
215+ return ;
174216 }
175- registry.fill (HIST (" hEnergyWithCent_ZNA_Common" ), zdcCol.energyCommonZNA (), centrality);
176- registry.fill (HIST (" hEnergyWithCent_ZNC_Common" ), zdcCol.energyCommonZNC (), centrality);
177- registry.fill (HIST (" hEnergyWithCent_ZNA_1" ), zdcCol.energySectorZNA ()[0 ], centrality);
178- registry.fill (HIST (" hEnergyWithCent_ZNA_2" ), zdcCol.energySectorZNA ()[1 ], centrality);
179- registry.fill (HIST (" hEnergyWithCent_ZNA_3" ), zdcCol.energySectorZNA ()[2 ], centrality);
180- registry.fill (HIST (" hEnergyWithCent_ZNA_4" ), zdcCol.energySectorZNA ()[3 ], centrality);
181- registry.fill (HIST (" hEnergyWithCent_ZNC_1" ), zdcCol.energySectorZNC ()[0 ], centrality);
182- registry.fill (HIST (" hEnergyWithCent_ZNC_2" ), zdcCol.energySectorZNC ()[1 ], centrality);
183- registry.fill (HIST (" hEnergyWithCent_ZNC_3" ), zdcCol.energySectorZNC ()[2 ], centrality);
184- registry.fill (HIST (" hEnergyWithCent_ZNC_4" ), zdcCol.energySectorZNC ()[3 ], centrality);
185- registry.fill (HIST (" hEnergyWithCent_ZNA_SumSectors" ), SumEnergyZNA, centrality);
186- registry.fill (HIST (" hEnergyWithCent_ZNC_SumSectors" ), SumEnergyZNC, centrality);
217+ registry.fill (HIST (" hCentrality" ), centrality);
218+ registry.fill (HIST (" hMultiplicity" ), multi);
219+
220+ fillZDCObservables<CollisionsRun2::iterator, BCsRun2>(collision, centrality);
187221 }
222+
223+ // Process switches
224+ PROCESS_SWITCH (flowZdcEnergy, processRun3, " Process Run 3 data" , true );
225+ PROCESS_SWITCH (flowZdcEnergy, processRun2, " Process Run 2 data" , false );
188226};
189227
190228WorkflowSpec defineDataProcessing (ConfigContext const & cfgc)
0 commit comments