99// granted to it by virtue of its status as an Intergovernmental Organization
1010// or submit itself to any jurisdiction.
1111
12- // / \author Maxim Virta (maxim.virta@cern.ch)
12+ // / \author Maxim Virta (maxim.virta@cern.ch), junlee kim (junlee.kim@cern.ch)
1313// / \brief flow measurement with q-vectors
1414// / \file jEPFlowAnalysis.cxx
1515// / \since Jul 2024
2020#include " Common/Core/EventPlaneHelper.h"
2121#include " Common/DataModel/Centrality.h"
2222#include " Common/DataModel/EventSelection.h"
23+ #include " Common/DataModel/FT0Corrected.h"
2324#include " Common/DataModel/Qvectors.h"
2425#include " Common/DataModel/TrackSelectionTables.h"
2526
2627#include < CCDB/BasicCCDBManager.h>
2728#include < CCDB/CcdbApi.h>
2829#include < CommonConstants/MathConstants.h>
30+ #include < FT0Base/Geometry.h>
31+ #include < FV0Base/Geometry.h>
2932#include < Framework/ASoA.h>
3033#include < Framework/AnalysisDataModel.h>
3134#include < Framework/AnalysisHelpers.h>
3942#include < Framework/OutputObjHeader.h>
4043#include < Framework/runDataProcessing.h>
4144
45+ #include < TComplex.h>
4246#include < THn.h>
4347#include < TPDGCode.h>
4448#include < TProfile3D.h>
@@ -56,7 +60,7 @@ using namespace o2::framework;
5660using namespace o2 ::framework::expressions;
5761using namespace std ;
5862
59- using MyCollisions = soa::Join<aod::Collisions, aod::EvSels, aod::Qvectors>;
63+ using MyCollisions = soa::Join<aod::Collisions, aod::EvSels, aod::Qvectors, aod::FT0sCorrected >;
6064using MyTracks = soa::Join<aod::Tracks, aod::TracksExtra, aod::TracksDCA, aod::TrackSelection>;
6165using MyCollisionsMC = soa::Join<aod::Collisions, aod::EvSels, aod::CentFT0Cs, aod::McCollisionLabels>;
6266using MyTracksMC = soa::Join<aod::Tracks, aod::TracksExtra, aod::TracksDCA, aod::TrackSelection, aod::McTrackLabels>;
@@ -67,6 +71,8 @@ struct JEPFlowAnalysis {
6771
6872 HistogramRegistry epFlowHistograms{" EPFlow" , {}, OutputObjHandlingPolicy::AnalysisObject, true , true };
6973 EventPlaneHelper helperEP;
74+ o2::ft0::Geometry ft0geom;
75+ o2::fv0::Geometry* fv0geom = nullptr ;
7076 FlowJHistManager histManager;
7177 bool debug = kFALSE ;
7278 Service<o2::ccdb::BasicCCDBManager> ccdb;
@@ -94,6 +100,9 @@ struct JEPFlowAnalysis {
94100 Configurable<bool > cfgEffCor{" cfgEffCor" , false , " flag for efficiency correction" };
95101 Configurable<std::string> cfgEffCorDir{" cfgEffCorDir" , " Users/n/nmallick/Run3OO/Eff/LHC25h3b_FT0C" , " path for efficiency correction" };
96102
103+ Configurable<bool > cfgGainEq{" cfgGainEq" , false , " flag for gain equalization" };
104+ Configurable<std::string> cfgGainEqPath{" cfgGainEqPath" , " Users/j/junlee/Qvector/GainEq" , " CCDB path for gain equalization constants" };
105+
97106 Configurable<bool > cfgTrkSelFlag{" cfgTrkSelFlag" , true , " flag for track selection" };
98107 Configurable<bool > cfgSystStudy{" cfgSystStudy" , false , " flag for syst study" };
99108 Configurable<int > cfgITSNCls{" cfgITSNCls" , 5 , " minimum number of its clusters" };
@@ -126,6 +135,8 @@ struct JEPFlowAnalysis {
126135 ConfigurableAxis cfgAxisCos{" cfgAxisCos" , {102 , -1.02 , 1.02 }, " " };
127136 ConfigurableAxis cfgAxisQvec{" cfgAxisQvec" , {200 , -5.0 , 5.0 }, " " };
128137 ConfigurableAxis cfgAxisQ2{" cfgAxisQ2" , {100 , 0 , 10 }, " " };
138+ ConfigurableAxis cfgAxisAmp{" cfgAxisAmp" , {100 , 0 , 1e5 }, " " };
139+ ConfigurableAxis cfgAxisAmpR{" cfgAxisAmpR" , {VARIABLE_WIDTH, 0.0 , 0.01 , 0.02 , 0.05 , 0.1 , 0.2 , 0.5 , 1.0 }, " " };
129140
130141 ConfigurableAxis cfgAxisCentMC{" cfgAxisCentMC" , {5 , 0 , 100 }, " " };
131142 ConfigurableAxis cfgAxisVtxZMC{" cfgAxisVtxZMC" , {20 , -10 , 10 }, " " };
@@ -148,12 +159,16 @@ struct JEPFlowAnalysis {
148159 float minQvecAmp = 1e-5 ;
149160 float minChg = 0.1 ;
150161 float q2Mag;
162+ float highestPt;
151163
152164 std::vector<TProfile3D*> shiftprofile{};
153165 std::string fullCCDBShiftCorrPath;
154166
155167 THn* effMap = nullptr ;
156168
169+ std::vector<float > ft0RelGainConst{};
170+ std::vector<float > fv0RelGainConst{};
171+
157172 bool q2sel (float q2, bool isHigh)
158173 {
159174 auto it = std::upper_bound (cfgMultq2SelBin->begin (), cfgMultq2SelBin->end (), cent);
@@ -230,6 +245,27 @@ struct JEPFlowAnalysis {
230245 return true ;
231246 }
232247
248+ template <typename Col>
249+ float calcFT0CRawQVecMag (const Col& coll, int nMode)
250+ {
251+ float ampFT0C = 0 .f ;
252+
253+ if (!coll.has_foundFT0 ()) {
254+ return false ;
255+ }
256+
257+ auto ft0 = coll.foundFT0 ();
258+ TComplex qVecFT0C (0 ., 0 .);
259+
260+ for (std::size_t iChC = 0 ; iChC < ft0.channelC ().size (); ++iChC) {
261+ int ft0CChId = ft0.channelC ()[iChC] + 96 ;
262+ float ampl = ft0.amplitudeC ()[iChC] / (cfgGainEq ? ft0RelGainConst[ft0CChId] : 1 .);
263+ helperEP.SumQvectors (0 , ft0CChId, ampl, nMode, qVecFT0C, ampFT0C, ft0geom, fv0geom);
264+ }
265+
266+ return qVecFT0C.Rho ();
267+ }
268+
233269 template <typename Trk>
234270 uint8_t trackSel (const Trk& track)
235271 {
@@ -346,10 +382,15 @@ struct JEPFlowAnalysis {
346382 }
347383 }
348384
385+ highestPt = 0.0 ;
349386 for (const auto & track : tracks) {
350387 if (cfgTrkSelFlag && trackSel (track))
351388 continue ;
352389
390+ if (highestPt < track.pt ()) {
391+ highestPt = track.pt ();
392+ }
393+
353394 if (cfgEffCor) {
354395 weight = getEfficiencyCorrection (effMap, track.eta (), track.pt (), cent, coll.posZ ());
355396 }
@@ -371,6 +412,13 @@ struct JEPFlowAnalysis {
371412 }
372413 }
373414 }
415+ if (i == 0 ) { // second harmonic only
416+ auto qOvecM = calcFT0CRawQVecMag (coll, i + 2 );
417+
418+ epFlowHistograms.fill (HIST (" hQoverM" ), cent, highestPt, qOvecM);
419+ epFlowHistograms.fill (HIST (" hQoverM2M" ), cent, coll.qvecAmp ()[detId], qOvecM);
420+ epFlowHistograms.fill (HIST (" hQoverM2Q2" ), cent, q2Mag, qOvecM);
421+ }
374422 }
375423 }
376424
@@ -393,6 +441,8 @@ struct JEPFlowAnalysis {
393441 ccdb->setLocalObjectValidityChecking ();
394442 ccdb->setCreatedNotAfter (std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now ().time_since_epoch ()).count ());
395443
444+ fv0geom = o2::fv0::Geometry::instance (o2::fv0::Geometry::eUninitialized);
445+
396446 detId = getdetId (cfgDetName);
397447 refAId = getdetId (cfgRefAName);
398448 refBId = getdetId (cfgRefBName);
@@ -407,6 +457,8 @@ struct JEPFlowAnalysis {
407457 AxisSpec axisCos{cfgAxisCos, " cos" };
408458 AxisSpec axisQvec{cfgAxisQvec, " Qvec" };
409459 AxisSpec axisQ2{cfgAxisQ2, " Q2" };
460+ AxisSpec axisAmp{cfgAxisAmp, " M" };
461+ AxisSpec axisAmpR{cfgAxisAmpR, " QoverM" };
410462
411463 AxisSpec axisCentMC{cfgAxisCentMC, " cent" };
412464 AxisSpec axisVtxZMC{cfgAxisVtxZMC, " vtxz" };
@@ -423,6 +475,9 @@ struct JEPFlowAnalysis {
423475 epFlowHistograms.add (" EpResRefARefB" , " " , {HistType::kTH3F , {axisMod, axisCent, axisEvtPl}});
424476
425477 epFlowHistograms.add (" hQ2" , " " , {HistType::kTH3F , {axisMod, axisCent, axisQ2}});
478+ epFlowHistograms.add (" hQoverM" , " " , {HistType::kTH3F , {axisCent, axisPt, axisAmpR}});
479+ epFlowHistograms.add (" hQoverM2M" , " " , {HistType::kTH3F , {axisCent, axisAmp, axisAmpR}});
480+ epFlowHistograms.add (" hQoverM2Q2" , " " , {HistType::kTH3F , {axisCent, axisQ2, axisAmpR}});
426481
427482 epFlowHistograms.add (" vncos" , " " , {HistType::kTHnSparseF , {axisMod, axisCent, axisPt, axisCos}});
428483 epFlowHistograms.add (" vnsin" , " " , {HistType::kTHnSparseF , {axisMod, axisCent, axisPt, axisCos}});
@@ -457,7 +512,7 @@ struct JEPFlowAnalysis {
457512 epFlowHistograms.add (" MC/hPartRec" , " " , {kTHnSparseF , {cfgAxisCentMC, cfgAxisVtxZMC, cfgAxisEtaMC, cfgAxisPhiMC, cfgAxisPtMC}});
458513 }
459514
460- void processDefault (MyCollisions::iterator const & coll, soa::Filtered<MyTracks> const & tracks, aod::BCsWithTimestamps const &)
515+ void processDefault (MyCollisions::iterator const & coll, soa::Filtered<MyTracks> const & tracks, aod::BCsWithTimestamps const &, aod::FT0s const & )
461516 {
462517 if (cfgAddEvtSel) {
463518 if (!eventSel (coll))
@@ -473,6 +528,46 @@ struct JEPFlowAnalysis {
473528 }
474529 }
475530
531+ if (cfgGainEq) {
532+ auto bc = coll.bc_as <aod::BCsWithTimestamps>();
533+ currentRunNumber = bc.runNumber ();
534+ auto timestamp = bc.timestamp ();
535+
536+ std::string fullPath;
537+ if (currentRunNumber != lastRunNumber) {
538+ ft0RelGainConst.clear ();
539+ fv0RelGainConst.clear ();
540+ ft0RelGainConst = {};
541+ fv0RelGainConst = {};
542+
543+ fullPath = cfgGainEqPath;
544+ fullPath += " /FT0" ;
545+ const int nPixelsFT0 = 208 ;
546+ const auto objft0Gain = ccdb->getForTimeStamp <std::vector<float >>(fullPath, timestamp);
547+ if (!objft0Gain) {
548+ for (auto i{0u }; i < nPixelsFT0; i++) {
549+ ft0RelGainConst.push_back (1 .);
550+ }
551+ } else {
552+ ft0RelGainConst = *(objft0Gain);
553+ }
554+
555+ fullPath = cfgGainEqPath;
556+ fullPath += " /FV0" ;
557+ const int nChannelsFV0 = 48 ;
558+ const auto objfv0Gain = ccdb->getForTimeStamp <std::vector<float >>(fullPath, timestamp);
559+ if (!objfv0Gain) {
560+ for (auto i{0u }; i < nChannelsFV0; i++) {
561+ fv0RelGainConst.push_back (1 .);
562+ }
563+ } else {
564+ fv0RelGainConst = *(objfv0Gain);
565+ }
566+
567+ lastRunNumber = currentRunNumber;
568+ }
569+ }
570+
476571 cent = coll.cent ();
477572 epFlowHistograms.fill (HIST (" hCentrality" ), cent);
478573 epFlowHistograms.fill (HIST (" hVertex" ), coll.posZ ());
0 commit comments