@@ -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