@@ -113,15 +113,18 @@ struct LumiStabilityPP {
113113 std::bitset<o2::constants::lhc::LHCMaxBunches> bcPatternA, bcPatternC, bcPatternB, bcPatternE, bcPatternL;
114114 const int nBCsPerOrbit = o2::constants::lhc::LHCMaxBunches;
115115
116+ o2::framework::Service<o2::ccdb::BasicCCDBManager> ccdb;
116117 parameters::GRPLHCIFData* mLHCIFdata = nullptr ;
117118 int runNumber{-1 };
119+ bool isData23{false };
118120 ctpRateFetcher mRateFetcher ;
119121 std::string injectionScheme;
120122
121- HistogramRegistry registry{" registry" };
123+ HistogramRegistry registry{" registry" };
122124
123125 std::array<std::array<std::map<int , std::shared_ptr<TH1>>, NBCCategories>, NTriggerAliases> histBcVsTime;
124126 std::array<std::array<std::map<int , std::shared_ptr<TH1>>, NBCCategories>, NTriggerAliases> histBcVsBcId;
127+ std::array<std::array<std::map<int , std::shared_ptr<TH1>>, NBCCategories>, NTriggerAliases> histMu;
125128 std::map<int , std::shared_ptr<TH1>> histNBcsVsTime;
126129 std::map<int , std::shared_ptr<TH1>> histNBcsVsBcId;
127130 std::map<int , std::shared_ptr<TH1>> histTfPerMin;
@@ -143,6 +146,12 @@ struct LumiStabilityPP {
143146 {" FT0CE/BC_A/nBCsVsBCID" , " FT0CE/BC_B/nBCsVsBCID" , " FT0CE/BC_C/nBCsVsBCID" , " FT0CE/BC_E/nBCsVsBCID" , " FT0CE/BC_L/nBCsVsBCID" , " FT0CE/BC_SL/nBCsVsBCID" },
144147 {" FDD/BC_A/nBCsVsBCID" , " FDD/BC_B/nBCsVsBCID" , " FDD/BC_C/nBCsVsBCID" , " FDD/BC_E/nBCsVsBCID" , " FDD/BC_L/nBCsVsBCID" , " FDD/BC_SL/nBCsVsBCID" }};
145148
149+ static constexpr std::string_view MuHistNames[NTriggerAliases][NBCCategories-1 ] =
150+ {{" AllBCs/BC_A/Mu" , " AllBCs/BC_B/Mu" , " AllBCs/BC_C/Mu" , " AllBCs/BC_E/Mu" , " AllBCs/BC_L/Mu" },
151+ {" FT0VTx/BC_A/Mu" , " FT0VTx/BC_B/Mu" , " FT0VTx/BC_C/Mu" , " FT0VTx/BC_E/Mu" , " FT0VTx/BC_L/Mu" },
152+ {" FT0CE/BC_A/Mu" , " FT0CE/BC_B/Mu" , " FT0CE/BC_C/Mu" , " FT0CE/BC_E/Mu" , " FT0CE/BC_L/Mu" },
153+ {" FDD/BC_A/Mu" , " FDD/BC_B/Mu" , " FDD/BC_C/Mu" , " FDD/BC_E/Mu" , " FDD/BC_L/Mu" }};
154+
146155 const AxisSpec timeAxis{2880 , 0 ., 2880 ., " #bf{t-t_{SOF} (min)}" }, bcIDAxis{nBCsPerOrbit, -0.5 , static_cast <float >(nBCsPerOrbit) - 0.5 , " #bf{BC ID in orbit}" };
147156
148157 int64_t bcSOR;
@@ -180,29 +189,31 @@ struct LumiStabilityPP {
180189 if ((iBCCategory == BCA && doBCA) || (iBCCategory == BCB && doBCB) || (iBCCategory == BCC && doBCC) || (iBCCategory == BCE && doBCE) || (iBCCategory == BCL && doBCL) || (iBCCategory == BCSL && doBCSL)) {
181190 histBcVsTime[iTrigger][iBCCategory][runNumber] = registry.add <TH1>(Form (" %d/%s" , runNumber, std::string (NBCsVsTimeHistNames[iTrigger][iBCCategory]).c_str ()), " Time of triggered BCs since the start of fill;#bf{t-t_{SOF} (min)};#bf{#it{N}_{BC}}" , HistType::kTH1D , {timeAxis});
182191 histBcVsBcId[iTrigger][iBCCategory][runNumber] = registry.add <TH1>(Form (" %d/%s" , runNumber, std::string (NBCsVsBCIDHistNames[iTrigger][iBCCategory]).c_str ()), " BC ID of triggered BCs;#bf{BC ID in orbit};#bf{#it{N}_{BC}}" , HistType::kTH1D , {bcIDAxis});
192+ if (iBCCategory != BCSL) { // we do not do it for superleading because it is not easy to define the number of inspected BCs
193+ histMu[iTrigger][iBCCategory][runNumber] = registry.add <TH1>(Form (" %d/%s" , runNumber, std::string (MuHistNames[iTrigger][iBCCategory]).c_str ()), " pile-up #mu of different triggers;#mu;counts" , HistType::kTH1D , {500 , 0 ., 0.1 });
194+ }
183195 }
184196 }
185197 }
186198 }
187199
188- bool setLHCIFData (const auto & bc)
200+ void setLHCIFData (const auto & bc)
189201 {
190- bool isData23{false };
202+
203+ if (runNumber == bc.runNumber ()) {
204+ return ;
205+ }
206+
191207 const int runStart2023{535069 };
192208 const int runStop2023{539908 };
193209 if (bc.runNumber () >= runStart2023 && bc.runNumber () <= runStop2023) {
194210 isData23 = true ;
195211 }
196212
197- if (runNumber == bc.runNumber ()) {
198- return isData23;
199- }
200-
201- auto & ccdbMgr = o2::ccdb::BasicCCDBManager::instance ();
202213 uint64_t timeStamp = bc.timestamp ();
203214
204215 std::map<std::string, std::string> metadata;
205- mLHCIFdata = ccdbMgr. getSpecific <o2::parameters::GRPLHCIFData>(" GLO/Config/GRPLHCIF" , timeStamp, metadata);
216+ mLHCIFdata = ccdb. service -> getSpecific <o2::parameters::GRPLHCIFData>(" GLO/Config/GRPLHCIF" , timeStamp, metadata);
206217 if (mLHCIFdata == nullptr ) {
207218 LOG (fatal) << " GRPLHCIFData not in database, timestamp:" << timeStamp;
208219 }
@@ -251,35 +262,52 @@ struct LumiStabilityPP {
251262 LOG (info) << " BC SOR: " << bcSOR << " (orbit SOR: " << runInfo.orbitSOR << " ) NBCs per orbit: " << nBCsPerOrbit;
252263 nBCsPerTF = runInfo.orbitsPerTF * nBCsPerOrbit; // duration of TF in bcs
253264
254- return isData23 ;
265+ return ;
255266 }
256267
257268 float getTimeSinceSOF (const auto & bc)
258269 {
259270 return (bc.timestamp () - mLHCIFdata ->getFillNumberTime ()) / 1e3 / 60 ; // Convert to minutes
260271 }
261272
273+ float getMu (double triggerRate, int nbc)
274+ {
275+ if (nbc == 0 ) {
276+ return 0 .;
277+ }
278+ return -std::log (1 .f - triggerRate / nbc / constants::lhc::LHCRevFreq);
279+ }
280+
262281 template <int iTrigger, int iBCCategory>
263- void fillHistograms (float timeSinceSOF, int64_t localBC)
282+ void fillHistograms (float timeSinceSOF, int64_t localBC, int & nTriggers )
264283 {
284+ nTriggers += 1 ;
265285 histBcVsTime[iTrigger][iBCCategory][runNumber]->Fill (timeSinceSOF);
266286 histBcVsBcId[iTrigger][iBCCategory][runNumber]->Fill (localBC);
267287 }
268288
289+ void fillMuHistograms (int iTrigger, int iBCCategory, float mu)
290+ {
291+ histMu[iTrigger][iBCCategory][runNumber]->Fill (mu);
292+ }
293+
269294 void process (BCsWithTimeStamps const & bcs,
270295 aod::FT0s const &,
271296 aod::FDDs const &)
272297 {
273298 int64_t globalBCIdOfLastBCWithActivity = 0 ;
299+ int nBCs[2 ] = {0 , 0 };
300+ float timeStartSinceSOF{-1 .f }, timeStopSinceSOF{-1 .f };
301+ int nTriggersPerDf[NTriggerAliases][NBCCategories];
274302 for (const auto & bc : bcs) {
275303
276304 if (bc.timestamp () == 0 ) {
277305 continue ;
278306 }
279307
280- bool isData23 = setLHCIFData (bc);
308+ setLHCIFData (bc);
281309 BCsWithTimeStamps::iterator bcFDD;
282- auto idxBc = bc.globalIndex ()
310+ auto idxBc = bc.globalIndex ();
283311 if (isData23) {
284312 if (idxBc < bcShiftFDDForData2023) { // we need to skip the first 15 because of the FDD-FT0 shift
285313 continue ;
@@ -290,17 +318,26 @@ struct LumiStabilityPP {
290318 }
291319
292320 float timeSinceSOF = getTimeSinceSOF (bc);
321+ if (timeStartSinceSOF < 0 .) {
322+ timeStartSinceSOF = timeSinceSOF;
323+ }
324+ if (timeStopSinceSOF < timeSinceSOF) {
325+ timeStopSinceSOF = timeSinceSOF;
326+ }
327+
293328 bool isTriggerTVX = (bc.has_ft0 () ? TESTBIT (bc.ft0 ().triggerMask (), o2::ft0::Triggers::bitVertex) : false );
294329
295330 if (isTriggerTVX) {
296331 histNBcsVsTime[runNumber]->Fill (timeSinceSOF);
297- histInteractionRate[runNumber]->Fill (mRateFetcher .fetch (ccdbMgr , bc.timestamp (), bc.runNumber (), std::string (" T0VTX" ), true ));
332+ histInteractionRate[runNumber]->Fill (mRateFetcher .fetch (ccdb. service , bc.timestamp (), bc.runNumber (), std::string (" T0VTX" ), true ) * 1 . e - 3 ); // kHz
298333 }
299334
300335 int64_t globalBC = bc.globalBC ();
301- int64_t globalBCFDD = bcFDD.globalBC ();
302336 int localBC = globalBC % nBCsPerOrbit;
303- int localBCFDD = globalBCFDD % nBCsPerOrbit;
337+ nBCs[0 ]++;
338+ if (bcPatternL[localBC]) {
339+ nBCs[1 ]++;
340+ }
304341
305342 bool isSuperLeadingBc{true };
306343 if (globalBC - globalBCIdOfLastBCWithActivity < numEmptyBCsBeforeLeadingBC) {
@@ -333,65 +370,81 @@ struct LumiStabilityPP {
333370 if ((iBCCategory == BCA && doBCA) || (iBCCategory == BCB && doBCB) || (iBCCategory == BCC && doBCC) || (iBCCategory == BCE && doBCE) || (iBCCategory == BCL && doBCL) || (iBCCategory == BCSL && doBCSL)) {
334371 if (iTrigger == AllBCs) {
335372 if (iBCCategory == BCA && bcPatternA[localBC])
336- fillHistograms<AllBCs, BCA>(timeSinceSOF, localBC);
373+ fillHistograms<AllBCs, BCA>(timeSinceSOF, localBC, nTriggersPerDf[iTrigger][iBCCategory] );
337374 if (iBCCategory == BCB && bcPatternB[localBC])
338- fillHistograms<AllBCs, BCB>(timeSinceSOF, localBC);
375+ fillHistograms<AllBCs, BCB>(timeSinceSOF, localBC, nTriggersPerDf[iTrigger][iBCCategory] );
339376 if (iBCCategory == BCC && bcPatternC[localBC])
340- fillHistograms<AllBCs, BCC>(timeSinceSOF, localBC);
377+ fillHistograms<AllBCs, BCC>(timeSinceSOF, localBC, nTriggersPerDf[iTrigger][iBCCategory] );
341378 if (iBCCategory == BCE && bcPatternE[localBC])
342- fillHistograms<AllBCs, BCE>(timeSinceSOF, localBC);
379+ fillHistograms<AllBCs, BCE>(timeSinceSOF, localBC, nTriggersPerDf[iTrigger][iBCCategory] );
343380 if (iBCCategory == BCL && bcPatternL[localBC])
344- fillHistograms<AllBCs, BCL>(timeSinceSOF, localBC);
381+ fillHistograms<AllBCs, BCL>(timeSinceSOF, localBC, nTriggersPerDf[iTrigger][iBCCategory] );
345382 if (iBCCategory == BCSL && isSuperLeadingBc)
346- fillHistograms<AllBCs, BCSL>(timeSinceSOF, localBC);
383+ fillHistograms<AllBCs, BCSL>(timeSinceSOF, localBC, nTriggersPerDf[iTrigger][iBCCategory] );
347384 }
348385 if (iTrigger == FT0Vtx && ctpInputMask.test (2 )) {
349386 if (iBCCategory == BCA && bcPatternA[localBC])
350- fillHistograms<FT0Vtx, BCA>(timeSinceSOF, localBC);
387+ fillHistograms<FT0Vtx, BCA>(timeSinceSOF, localBC, nTriggersPerDf[iTrigger][iBCCategory] );
351388 if (iBCCategory == BCB && bcPatternB[localBC])
352- fillHistograms<FT0Vtx, BCB>(timeSinceSOF, localBC);
389+ fillHistograms<FT0Vtx, BCB>(timeSinceSOF, localBC, nTriggersPerDf[iTrigger][iBCCategory] );
353390 if (iBCCategory == BCC && bcPatternC[localBC])
354- fillHistograms<FT0Vtx, BCC>(timeSinceSOF, localBC);
391+ fillHistograms<FT0Vtx, BCC>(timeSinceSOF, localBC, nTriggersPerDf[iTrigger][iBCCategory] );
355392 if (iBCCategory == BCE && bcPatternE[localBC])
356- fillHistograms<FT0Vtx, BCE>(timeSinceSOF, localBC);
393+ fillHistograms<FT0Vtx, BCE>(timeSinceSOF, localBC, nTriggersPerDf[iTrigger][iBCCategory] );
357394 if (iBCCategory == BCL && bcPatternL[localBC])
358- fillHistograms<FT0Vtx, BCL>(timeSinceSOF, localBC);
395+ fillHistograms<FT0Vtx, BCL>(timeSinceSOF, localBC, nTriggersPerDf[iTrigger][iBCCategory] );
359396 if (iBCCategory == BCSL && isSuperLeadingBc)
360- fillHistograms<FT0Vtx, BCSL>(timeSinceSOF, localBC);
397+ fillHistograms<FT0Vtx, BCSL>(timeSinceSOF, localBC, nTriggersPerDf[iTrigger][iBCCategory] );
361398 }
362399 if (iTrigger == FT0CE && ctpInputMask.test (4 )) {
363400 if (iBCCategory == BCA && bcPatternA[localBC])
364- fillHistograms<FT0CE, BCA>(timeSinceSOF, localBC);
401+ fillHistograms<FT0CE, BCA>(timeSinceSOF, localBC, nTriggersPerDf[iTrigger][iBCCategory] );
365402 if (iBCCategory == BCB && bcPatternB[localBC])
366- fillHistograms<FT0CE, BCB>(timeSinceSOF, localBC);
403+ fillHistograms<FT0CE, BCB>(timeSinceSOF, localBC, nTriggersPerDf[iTrigger][iBCCategory] );
367404 if (iBCCategory == BCC && bcPatternC[localBC])
368- fillHistograms<FT0CE, BCC>(timeSinceSOF, localBC);
405+ fillHistograms<FT0CE, BCC>(timeSinceSOF, localBC, nTriggersPerDf[iTrigger][iBCCategory] );
369406 if (iBCCategory == BCE && bcPatternE[localBC])
370- fillHistograms<FT0CE, BCE>(timeSinceSOF, localBC);
407+ fillHistograms<FT0CE, BCE>(timeSinceSOF, localBC, nTriggersPerDf[iTrigger][iBCCategory] );
371408 if (iBCCategory == BCL && bcPatternL[localBC])
372- fillHistograms<FT0CE, BCL>(timeSinceSOF, localBC);
409+ fillHistograms<FT0CE, BCL>(timeSinceSOF, localBC, nTriggersPerDf[iTrigger][iBCCategory] );
373410 if (iBCCategory == BCSL && isSuperLeadingBc)
374- fillHistograms<FT0CE, BCSL>(timeSinceSOF, localBC);
411+ fillHistograms<FT0CE, BCSL>(timeSinceSOF, localBC, nTriggersPerDf[iTrigger][iBCCategory] );
375412 }
376413 if (iTrigger == FDD && ctpInputMaskFDD.test (15 )) {
377- if (iBCCategory == BCA && bcPatternA[localBCFDD ])
378- fillHistograms<FDD, BCA>(timeSinceSOF, localBCFDD );
379- if (iBCCategory == BCB && bcPatternB[localBCFDD ])
380- fillHistograms<FDD, BCB>(timeSinceSOF, localBCFDD );
381- if (iBCCategory == BCC && bcPatternC[localBCFDD ])
382- fillHistograms<FDD, BCC>(timeSinceSOF, localBCFDD );
383- if (iBCCategory == BCE && bcPatternE[localBCFDD ])
384- fillHistograms<FDD, BCE>(timeSinceSOF, localBCFDD );
385- if (iBCCategory == BCL && bcPatternL[localBCFDD ])
386- fillHistograms<FDD, BCL>(timeSinceSOF, localBCFDD );
414+ if (iBCCategory == BCA && bcPatternA[localBC ])
415+ fillHistograms<FDD, BCA>(timeSinceSOF, localBC, nTriggersPerDf[iTrigger][iBCCategory] );
416+ if (iBCCategory == BCB && bcPatternB[localBC ])
417+ fillHistograms<FDD, BCB>(timeSinceSOF, localBC, nTriggersPerDf[iTrigger][iBCCategory] );
418+ if (iBCCategory == BCC && bcPatternC[localBC ])
419+ fillHistograms<FDD, BCC>(timeSinceSOF, localBC, nTriggersPerDf[iTrigger][iBCCategory] );
420+ if (iBCCategory == BCE && bcPatternE[localBC ])
421+ fillHistograms<FDD, BCE>(timeSinceSOF, localBC, nTriggersPerDf[iTrigger][iBCCategory] );
422+ if (iBCCategory == BCL && bcPatternL[localBC ])
423+ fillHistograms<FDD, BCL>(timeSinceSOF, localBC, nTriggersPerDf[iTrigger][iBCCategory] );
387424 if (iBCCategory == BCSL && isSuperLeadingBc)
388- fillHistograms<FDD, BCSL>(timeSinceSOF, localBCFDD );
425+ fillHistograms<FDD, BCSL>(timeSinceSOF, localBC, nTriggersPerDf[iTrigger][iBCCategory] );
389426 }
390427 }
391428 }
392429 }
393430 histNBcsVsBcId[runNumber]->Fill (localBC);
394431 }
432+ // fill histogram for mu
433+ float deltaTime = timeStopSinceSOF - timeStartSinceSOF;
434+ for (int iTrigger{0 }; iTrigger < NTriggerAliases; ++iTrigger) {
435+ for (int iBCCategory{0 }; iBCCategory < NBCCategories; ++iBCCategory) {
436+ if (iBCCategory == BCSL) { // we do not do it for superleading because it is not easy to define the number of inspected BCs
437+ continue ;
438+ }
439+ float mu{0 .};
440+ if (iBCCategory != BCSL) {
441+ mu = getMu (nTriggersPerDf[iTrigger][iBCCategory]/deltaTime, nBCs[0 ]);
442+ } else {
443+ mu = getMu (nTriggersPerDf[iTrigger][iBCCategory]/deltaTime, nBCs[1 ]);
444+ }
445+ fillMuHistograms (iTrigger, iBCCategory, mu);
446+ }
447+ }
395448 }
396449};
397450
0 commit comments