1515// / \author Gyula Bencedi, gyula.bencedi@cern.ch
1616// / \since Nov 2024
1717
18- #include < algorithm>
19- #include < chrono>
20- #include < cmath>
21- #include < numeric>
22- #include < vector>
23- #include < string>
18+ #include " Functions.h"
19+ #include " Index.h"
20+ #include " bestCollisionTable.h"
2421
25- #include " CCDB/BasicCCDBManager.h"
22+ #include " Common/CCDB/ctpRateFetcher.h"
23+ #include " Common/DataModel/Centrality.h"
24+ #include " Common/DataModel/CollisionAssociationTables.h"
25+ #include " Common/DataModel/EventSelection.h"
26+ #include " Common/DataModel/Multiplicity.h"
27+ #include " Common/DataModel/TrackSelectionTables.h"
2628
29+ #include " CCDB/BasicCCDBManager.h"
30+ #include " CommonConstants/MathConstants.h"
2731#include " Framework/ASoAHelpers.h"
2832#include " Framework/AnalysisDataModel.h"
2933#include " Framework/AnalysisTask.h"
3034#include " Framework/Configurable.h"
3135#include " Framework/O2DatabasePDGPlugin.h"
3236#include " Framework/RuntimeError.h"
3337#include " Framework/runDataProcessing.h"
34-
35- #include " Common/CCDB/ctpRateFetcher.h"
36- #include " Common/DataModel/Centrality.h"
37- #include " Common/DataModel/CollisionAssociationTables.h"
38- #include " Common/DataModel/EventSelection.h"
39- #include " Common/DataModel/Multiplicity.h"
40- #include " Common/DataModel/TrackSelectionTables.h"
41- #include " CommonConstants/MathConstants.h"
42-
4338#include " MathUtils/Utils.h"
4439#include " ReconstructionDataFormats/GlobalTrackID.h"
40+
4541#include " TPDGCode.h"
4642
47- #include " Functions.h"
48- #include " Index.h"
49- #include " bestCollisionTable.h"
43+ #include < algorithm>
44+ #include < chrono>
45+ #include < cmath>
46+ #include < numeric>
47+ #include < string>
48+ #include < unordered_map>
49+ #include < vector>
5050
5151using namespace o2 ;
5252using namespace o2 ::framework;
@@ -65,6 +65,7 @@ AxisSpec dcaxyAxis = {500, -1, 50};
6565AxisSpec phiAxis = {629 , 0 , TwoPI, " Rad" , " #phi" };
6666AxisSpec etaAxis = {20 , -4 ., -2 .};
6767AxisSpec centAxis{100 , 0 , 100 , " centrality" };
68+ AxisSpec chiSqAxis = {100 , 0 ., 1000 .};
6869
6970struct DndetaMFTPbPb {
7071 SliceCache cache;
@@ -83,6 +84,11 @@ struct DndetaMFTPbPb {
8384 false ,
8485 true };
8586
87+ Configurable<bool > cfgDoIR{" cfgDoIR" , false , " Flag to retrieve Interaction rate from CCDB" };
88+ Configurable<bool > cfgUseIRCut{" cfgUseIRCut" , false , " Flag to cut on IR rate" };
89+ Configurable<bool > cfgIRCrashOnNull{" cfgIRCrashOnNull" , false , " Flag to avoid CTP RateFetcher crash" };
90+ Configurable<std::string> cfgIRSource{" cfgIRSource" , " T0VTX" , " Estimator of the interaction rate (Pb-Pb: ZNC hadronic)" };
91+
8692 struct : ConfigurableGroup {
8793 Configurable<bool > usephiCut{" usephiCut" , false , " use azimuthal angle cut" };
8894 Configurable<float > phiCut{" phiCut" , 0 .1f ,
@@ -93,6 +99,7 @@ struct DndetaMFTPbPb {
9399 Configurable<float > maxEta{" maxEta" , -2 .5f , " " };
94100 Configurable<int > minNclusterMft{" minNclusterMft" , 5 ,
95101 " minimum number of MFT clusters" };
102+ Configurable<bool > useChi2Cut{" useChi2Cut" , false , " use track chi2 cut" };
96103 Configurable<float > maxChi2{" maxChi2" , 10 .f , " " };
97104 Configurable<double > minPt{" minPt" , 0 ., " minimum pT of the MFT tracks" };
98105 Configurable<bool > requireCA{
@@ -127,7 +134,6 @@ struct DndetaMFTPbPb {
127134 " minOccupancy" , -1 , " minimum occupancy from neighbouring collisions" };
128135 Configurable<float > maxOccupancy{
129136 " maxOccupancy" , -1 , " maximum occupancy from neighbouring collisions" };
130- Configurable<bool > cfgSelInteractionRate{" cfgSelInteractionRate" , false , " Get Interaction rate from CCDB" };
131137 Configurable<float > minIR{" minIR" , -1 , " minimum IR (kHz) collisions" };
132138 Configurable<float > maxIR{" maxIR" , -1 , " maximum IR (kHz) collisions" };
133139 } eventCuts;
@@ -154,7 +160,13 @@ struct DndetaMFTPbPb {
154160 " latest acceptable timestamp of creation for the object" };
155161 Configurable<std::string> ccdbUrl{" ccdbUrl" , " http://alice-ccdb.cern.ch" ,
156162 " url of the ccdb repository" };
163+
164+ int mRunNumber {-1 };
165+ uint64_t mSOR {0 };
166+ double mMinSeconds {-1 .};
167+ std::unordered_map<int , TH2*> gHadronicRate ;
157168 ctpRateFetcher rateFetcher;
169+ TH2* gCurrentHadronicRate ;
158170
159171 // / @brief init function, definition of histograms
160172 void init (InitContext&)
@@ -221,7 +233,7 @@ struct DndetaMFTPbPb {
221233 }
222234
223235 auto hev = registry.add <TH1>(" hEvtSel" , " hEvtSel" , HistType::kTH1F ,
224- {{16 , -0 .5f , +15 .5f }});
236+ {{14 , -0 .5f , +13 .5f }});
225237 hev->GetXaxis ()->SetBinLabel (1 , " All collisions" );
226238 hev->GetXaxis ()->SetBinLabel (2 , " Ev. sel." );
227239 hev->GetXaxis ()->SetBinLabel (3 , " kIsGoodZvtxFT0vsPV" );
@@ -235,8 +247,6 @@ struct DndetaMFTPbPb {
235247 hev->GetXaxis ()->SetBinLabel (11 , " kNoHighMultCollInPrevRof" );
236248 hev->GetXaxis ()->SetBinLabel (12 , " Below min occup." );
237249 hev->GetXaxis ()->SetBinLabel (13 , " Above max occup." );
238- hev->GetXaxis ()->SetBinLabel (14 , " Below min IR (kHz)" );
239- hev->GetXaxis ()->SetBinLabel (15 , " Above max IR (kHz)" );
240250
241251 auto hBcSel = registry.add <TH1>(" hBcSel" , " hBcSel" , HistType::kTH1F ,
242252 {{3 , -0 .5f , +2 .5f }});
@@ -257,9 +267,6 @@ struct DndetaMFTPbPb {
257267 x->SetBinLabel (1 , " All" );
258268 x->SetBinLabel (2 , " Selected" );
259269
260- qaregistry.add (" hOccIRate" , " hOccIRate" , HistType::kTH2F ,
261- {occupancyAxis, irBins});
262-
263270 registry.add ({" Events/NtrkZvtx" ,
264271 " ; N_{trk}; Z_{vtx} (cm); occupancy" ,
265272 {HistType::kTHnSparseF , {multAxis, zAxis, occupancyAxis}}});
@@ -274,10 +281,10 @@ struct DndetaMFTPbPb {
274281 qaregistry.add (
275282 {" Tracks/Chi2Eta" ,
276283 " ; #chi^{2}; #it{#eta}; occupancy" ,
277- {HistType::kTHnSparseF , {{ 600 , 0 , 20 } , etaAxis, occupancyAxis}}});
284+ {HistType::kTHnSparseF , {chiSqAxis , etaAxis, occupancyAxis}}});
278285 qaregistry.add ({" Tracks/Chi2" ,
279286 " ; #chi^{2};" ,
280- {HistType::kTH2F , {{ 600 , 0 , 20 } , occupancyAxis}}});
287+ {HistType::kTH2F , {chiSqAxis , occupancyAxis}}});
281288 qaregistry.add (
282289 {" Tracks/NclustersEta" ,
283290 " ; nClusters; #eta; occupancy" ,
@@ -343,9 +350,6 @@ struct DndetaMFTPbPb {
343350 hstat->GetAxis (0 )->SetBinLabel (1 , " All" );
344351 hstat->GetAxis (0 )->SetBinLabel (2 , " Selected" );
345352
346- qaregistry.add (" hCentOccIRate" , " hCentOccIRate" , HistType::kTHnSparseF ,
347- {centralityAxis, occupancyAxis, irBins});
348-
349353 qaregistry.add ({" Events/Centrality/hCent" ,
350354 " ; centrality; occupancy" ,
351355 {HistType::kTH2F , {centAxis, occupancyAxis}},
@@ -375,11 +379,11 @@ struct DndetaMFTPbPb {
375379 {" Tracks/Centrality/Chi2Eta" ,
376380 " ; #chi^{2}; #it{#eta}; centrality; occupancy" ,
377381 {HistType::kTHnSparseF ,
378- {{ 600 , 0 , 20 } , etaAxis, centralityAxis, occupancyAxis}}});
382+ {chiSqAxis , etaAxis, centralityAxis, occupancyAxis}}});
379383 qaregistry.add ({" Tracks/Centrality/Chi2" ,
380384 " ; #chi^{2}; centrality; occupancy" ,
381385 {HistType::kTHnSparseF ,
382- {{ 600 , 0 , 20 } , centralityAxis, occupancyAxis}}});
386+ {chiSqAxis , centralityAxis, occupancyAxis}}});
383387 qaregistry.add ({" Tracks/Centrality/NclustersEta" ,
384388 " ; nClusters; #eta; centrality; occupancy" ,
385389 {HistType::kTHnSparseF ,
@@ -735,35 +739,15 @@ struct DndetaMFTPbPb {
735739 using FiltBestTracks = soa::Filtered<aod::BestCollisionsFwd>;
736740 using FiltParticles = soa::Filtered<aod::McParticles>;
737741
738- bool isIRSelected (CollBCs::iterator const & bc, bool fillHis = false )
739- {
740- double ir = (eventCuts.minIR >= 0 || eventCuts.maxIR >= 0 )
741- ? rateFetcher.fetch (ccdb.service , bc.timestamp (),
742- bc.runNumber (), " ZNC hadronic" ) *
743- 1 .e -3
744- : -1 ;
745- if (eventCuts.minIR >= 0 && ir < eventCuts.minIR ) {
746- return false ;
747- }
748- if (fillHis) {
749- registry.fill (HIST (" hEvtSel" ), 13 );
750- }
751- if (eventCuts.maxIR >= 0 && ir > eventCuts.maxIR ) {
752- return false ;
753- }
754- if (fillHis) {
755- registry.fill (HIST (" hEvtSel" ), 14 );
756- }
757- return true ;
758- }
759-
760742 template <typename T>
761743 bool isTrackSelected (const T& track)
762744 {
763745 if (track.eta () < trackCuts.minEta || track.eta () > trackCuts.maxEta )
764746 return false ;
765- if (track.chi2 () > trackCuts.maxChi2 )
766- return false ;
747+ if (trackCuts.useChi2Cut ) {
748+ if (track.chi2 () > trackCuts.maxChi2 )
749+ return false ;
750+ }
767751 if (trackCuts.requireCA && !track.isCA ())
768752 return false ;
769753 if (track.nClusters () < trackCuts.minNclusterMft )
@@ -928,6 +912,24 @@ struct DndetaMFTPbPb {
928912 return -1 .f ;
929913 }
930914
915+ void initHadronicRate (CollBCs::iterator const & bc)
916+ {
917+ if (mRunNumber == bc.runNumber ()) {
918+ return ;
919+ }
920+ mRunNumber = bc.runNumber ();
921+ if (gHadronicRate .find (mRunNumber ) == gHadronicRate .end ()) {
922+ auto runDuration = ccdb->getRunDuration (mRunNumber );
923+ mSOR = runDuration.first ;
924+ mMinSeconds = std::floor (mSOR * 1 .e -3 ); // / round tsSOR to the highest integer lower than tsSOR
925+ double maxSec = std::ceil (runDuration.second * 1 .e -3 ); // / round tsEOR to the lowest integer higher than tsEOR
926+ const AxisSpec axisSeconds{static_cast <int >((maxSec - mMinSeconds ) / 20 .f ), 0 , maxSec - mMinSeconds , " Seconds since SOR" };
927+ int hadronicRateBins = static_cast <int >(eventCuts.maxIR - eventCuts.minIR );
928+ gHadronicRate [mRunNumber ] = registry.add <TH2>(Form (" HadronicRate/%i" , mRunNumber ), " ;Time since SOR (s);Hadronic rate (kHz)" , kTH2D , {axisSeconds, {hadronicRateBins, eventCuts.minIR , eventCuts.maxIR }}).get ();
929+ }
930+ gCurrentHadronicRate = gHadronicRate [mRunNumber ];
931+ }
932+
931933 template <bool fillHis = false , typename C>
932934 bool isGoodEvent (C const & collision)
933935 {
@@ -1110,10 +1112,6 @@ struct DndetaMFTPbPb {
11101112 auto occ = getOccupancy (collision, eventCuts.occupancyEstimator );
11111113 float c = getRecoCent (collision);
11121114 auto bc = collision.template foundBC_as <CollBCs>();
1113- double ir = rateFetcher.fetch (ccdb.service , bc.timestamp (), bc.runNumber (),
1114- " ZNC hadronic" ) *
1115- 1 .e -3 ;
1116-
11171115 if constexpr (has_reco_cent<C>) {
11181116 registry.fill (HIST (" Events/Centrality/Selection" ), 1 ., c, occ);
11191117 } else {
@@ -1123,21 +1121,23 @@ struct DndetaMFTPbPb {
11231121 if (!isGoodEvent<true >(collision)) {
11241122 return ;
11251123 }
1126- if (eventCuts.cfgSelInteractionRate ) {
1127- if (!isIRSelected (bc, true )) {
1124+
1125+ if (cfgDoIR) {
1126+ initHadronicRate (bc);
1127+ double ir = rateFetcher.fetch (ccdb.service , bc.timestamp (), bc.runNumber (), cfgIRSource, cfgIRCrashOnNull) * 1 .e -3 ;
1128+ double seconds = bc.timestamp () * 1 .e -3 - mMinSeconds ;
1129+ if (cfgUseIRCut && (ir < eventCuts.minIR || ir > eventCuts.maxIR )) { // cut on hadronic rate
11281130 return ;
11291131 }
1132+ gCurrentHadronicRate ->Fill (seconds, ir);
11301133 }
11311134
11321135 auto z = collision.posZ ();
11331136 if constexpr (has_reco_cent<C>) {
11341137 registry.fill (HIST (" Events/Centrality/Selection" ), 2 ., c, occ);
11351138 qaregistry.fill (HIST (" Events/Centrality/hZvtxCent" ), z, c, occ);
11361139 qaregistry.fill (HIST (" Events/Centrality/hCent" ), c, occ);
1137- qaregistry.fill (HIST (" hCentOccIRate" ), c, occ, ir);
1138-
11391140 } else {
1140- qaregistry.fill (HIST (" hOccIRate" ), occ, ir);
11411141 registry.fill (HIST (" Events/Selection" ), 2 ., occ);
11421142 }
11431143
@@ -1155,16 +1155,11 @@ struct DndetaMFTPbPb {
11551155 template <typename C>
11561156 void processDatawBestTracks (
11571157 typename C::iterator const & collision, FiltMftTracks const & tracks,
1158- soa::SmallGroups<aod::BestCollisionsFwd> const & besttracks,
1159- CollBCs const & /* bcs*/ )
1158+ soa::SmallGroups<aod::BestCollisionsFwd> const & besttracks, CollBCs const & /* bcs*/ )
11601159 {
11611160 auto occ = getOccupancy (collision, eventCuts.occupancyEstimator );
11621161 float c = getRecoCent (collision);
11631162 auto bc = collision.template foundBC_as <CollBCs>();
1164- double ir = rateFetcher.fetch (ccdb.service , bc.timestamp (), bc.runNumber (),
1165- " ZNC hadronic" ) *
1166- 1 .e -3 ;
1167-
11681163 if constexpr (has_reco_cent<C>) {
11691164 registry.fill (HIST (" Events/Centrality/Selection" ), 1 ., c, occ);
11701165 } else {
@@ -1174,19 +1169,22 @@ struct DndetaMFTPbPb {
11741169 if (!isGoodEvent<false >(collision)) {
11751170 return ;
11761171 }
1177- if (eventCuts.cfgSelInteractionRate ) {
1178- if (!isIRSelected (bc, true )) {
1172+
1173+ if (cfgDoIR) {
1174+ initHadronicRate (bc);
1175+ double ir = rateFetcher.fetch (ccdb.service , bc.timestamp (), bc.runNumber (), cfgIRSource, cfgIRCrashOnNull) * 1 .e -3 ;
1176+ double seconds = bc.timestamp () * 1 .e -3 - mMinSeconds ;
1177+ if (cfgUseIRCut && (ir < eventCuts.minIR || ir > eventCuts.maxIR )) { // cut on hadronic rate
11791178 return ;
11801179 }
1180+ gCurrentHadronicRate ->Fill (seconds, ir);
11811181 }
11821182
11831183 auto z = collision.posZ ();
11841184 if constexpr (has_reco_cent<C>) {
11851185 registry.fill (HIST (" Events/Centrality/Selection" ), 2 ., c, occ);
1186- qaregistry.fill (HIST (" hCentOccIRate" ), c, occ, ir);
11871186 } else {
11881187 registry.fill (HIST (" Events/Selection" ), 2 ., occ);
1189- qaregistry.fill (HIST (" hOccIRate" ), occ, ir);
11901188 }
11911189
11921190 auto nBestTrks = countBestTracks<C, true >(tracks, besttracks, z, c, occ);
@@ -1256,8 +1254,7 @@ struct DndetaMFTPbPb {
12561254
12571255 void processDatawBestTracksInclusive (
12581256 Colls::iterator const & collision, FiltMftTracks const & tracks,
1259- soa::SmallGroups<aod::BestCollisionsFwd> const & besttracks,
1260- CollBCs const & bcs)
1257+ soa::SmallGroups<aod::BestCollisionsFwd> const & besttracks, CollBCs const & bcs)
12611258 {
12621259 processDatawBestTracks<Colls>(collision, tracks, besttracks, bcs);
12631260 }
@@ -1268,8 +1265,7 @@ struct DndetaMFTPbPb {
12681265
12691266 void processDatawBestTracksCentFT0C (
12701267 CollsCentFT0C::iterator const & collision, FiltMftTracks const & tracks,
1271- soa::SmallGroups<aod::BestCollisionsFwd> const & besttracks,
1272- CollBCs const & bcs)
1268+ soa::SmallGroups<aod::BestCollisionsFwd> const & besttracks, CollBCs const & bcs)
12731269 {
12741270 processDatawBestTracks<CollsCentFT0C>(collision, tracks, besttracks, bcs);
12751271 }
@@ -1281,11 +1277,9 @@ struct DndetaMFTPbPb {
12811277 void processDatawBestTracksCentFT0CVariant1 (
12821278 CollsCentFT0CVariant1::iterator const & collision,
12831279 FiltMftTracks const & tracks,
1284- soa::SmallGroups<aod::BestCollisionsFwd> const & besttracks,
1285- CollBCs const & bcs)
1280+ soa::SmallGroups<aod::BestCollisionsFwd> const & besttracks, CollBCs const & bcs)
12861281 {
1287- processDatawBestTracks<CollsCentFT0CVariant1>(collision, tracks, besttracks,
1288- bcs);
1282+ processDatawBestTracks<CollsCentFT0CVariant1>(collision, tracks, besttracks, bcs);
12891283 }
12901284
12911285 PROCESS_SWITCH (DndetaMFTPbPb, processDatawBestTracksCentFT0CVariant1,
@@ -1295,8 +1289,7 @@ struct DndetaMFTPbPb {
12951289
12961290 void processDatawBestTracksCentFT0M (
12971291 CollsCentFT0M::iterator const & collision, FiltMftTracks const & tracks,
1298- soa::SmallGroups<aod::BestCollisionsFwd> const & besttracks,
1299- CollBCs const & bcs)
1292+ soa::SmallGroups<aod::BestCollisionsFwd> const & besttracks, CollBCs const & bcs)
13001293 {
13011294 processDatawBestTracks<CollsCentFT0M>(collision, tracks, besttracks, bcs);
13021295 }
@@ -1307,11 +1300,9 @@ struct DndetaMFTPbPb {
13071300
13081301 void processDatawBestTracksCentNGlobal (
13091302 CollsCentNGlobal::iterator const & collision, FiltMftTracks const & tracks,
1310- soa::SmallGroups<aod::BestCollisionsFwd> const & besttracks,
1311- CollBCs const & bcs)
1303+ soa::SmallGroups<aod::BestCollisionsFwd> const & besttracks, CollBCs const & bcs)
13121304 {
1313- processDatawBestTracks<CollsCentNGlobal>(collision, tracks, besttracks,
1314- bcs);
1305+ processDatawBestTracks<CollsCentNGlobal>(collision, tracks, besttracks, bcs);
13151306 }
13161307
13171308 PROCESS_SWITCH (DndetaMFTPbPb, processDatawBestTracksCentNGlobal,
@@ -1321,8 +1312,7 @@ struct DndetaMFTPbPb {
13211312
13221313 void processDatawBestTracksCentMFT (
13231314 CollsCentMFT::iterator const & collision, FiltMftTracks const & tracks,
1324- soa::SmallGroups<aod::BestCollisionsFwd> const & besttracks,
1325- CollBCs const & bcs)
1315+ soa::SmallGroups<aod::BestCollisionsFwd> const & besttracks, CollBCs const & bcs)
13261316 {
13271317 processDatawBestTracks<CollsCentMFT>(collision, tracks, besttracks, bcs);
13281318 }
0 commit comments