Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
137 changes: 107 additions & 30 deletions PWGMM/Lumi/Tasks/lumiStabilityPP.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -107,27 +107,32 @@ struct LumiStabilityPP {
Configurable<bool> doBCSL{"doBCSL", false, "Create and fill histograms for super-leading BCs (no preceding FT0/FDD activity) of type B"};
Configurable<int> numEmptyBCsBeforeLeadingBC{"numEmptyBCsBeforeLeadingBC", 5, "Number of empty BCs before a leading BC"};
Configurable<bool> requireNoT0ForSLBC{"requireNoT0ForSLBC", false, "Require no T0 signal for definition of super leading BC (otherwise only no FDD)"};
Configurable<int> bcShiftFDDForData2023{"bcShiftFDDForData2023", -15, "Number of bc to shift for FDD to be applied for 2023 data only"};

std::bitset<o2::constants::lhc::LHCMaxBunches> beamPatternA, beamPatternC;
std::bitset<o2::constants::lhc::LHCMaxBunches> bcPatternA, bcPatternC, bcPatternB, bcPatternE, bcPatternL;
const int nBCsPerOrbit = o2::constants::lhc::LHCMaxBunches;

o2::framework::Service<o2::ccdb::BasicCCDBManager> ccdb;
parameters::GRPLHCIFData* mLHCIFdata = nullptr;
int runNumber{-1};
bool isData23{false};
ctpRateFetcher mRateFetcher;
std::string injectionScheme;

HistogramRegistry registry{"registry"};

std::array<std::array<std::map<int, std::shared_ptr<TH1>>, NBCCategories>, NTriggerAliases> histBcVsTime;
std::array<std::array<std::map<int, std::shared_ptr<TH1>>, NBCCategories>, NTriggerAliases> histBcVsBcId;
std::array<std::array<std::map<int, std::shared_ptr<TH1>>, NBCCategories>, NTriggerAliases> histMu;
std::map<int, std::shared_ptr<TH1>> histNBcsVsTime;
std::map<int, std::shared_ptr<TH1>> histNBcsVsBcId;
std::map<int, std::shared_ptr<TH1>> histTfPerMin;
std::map<int, std::shared_ptr<TH1>> histBcHasFT0;
std::map<int, std::shared_ptr<TH1>> histBcHasFDD;
std::map<int, std::shared_ptr<TH1>> histFillingScheme;
std::map<int, std::shared_ptr<TH1>> histFillTime;
std::map<int, std::shared_ptr<TH1>> histInteractionRate;

static constexpr std::string_view NBCsVsTimeHistNames[NTriggerAliases][NBCCategories] =
{{"AllBCs/BC_A/nBCsVsTime", "AllBCs/BC_B/nBCsVsTime", "AllBCs/BC_C/nBCsVsTime", "AllBCs/BC_E/nBCsVsTime", "AllBCs/BC_L/nBCsVsTime", "AllBCs/BC_SL/nBCsVsTime"},
Expand All @@ -141,6 +146,12 @@ struct LumiStabilityPP {
{"FT0CE/BC_A/nBCsVsBCID", "FT0CE/BC_B/nBCsVsBCID", "FT0CE/BC_C/nBCsVsBCID", "FT0CE/BC_E/nBCsVsBCID", "FT0CE/BC_L/nBCsVsBCID", "FT0CE/BC_SL/nBCsVsBCID"},
{"FDD/BC_A/nBCsVsBCID", "FDD/BC_B/nBCsVsBCID", "FDD/BC_C/nBCsVsBCID", "FDD/BC_E/nBCsVsBCID", "FDD/BC_L/nBCsVsBCID", "FDD/BC_SL/nBCsVsBCID"}};

static constexpr std::string_view MuHistNames[NTriggerAliases][NBCCategories - 1] =
{{"AllBCs/BC_A/Mu", "AllBCs/BC_B/Mu", "AllBCs/BC_C/Mu", "AllBCs/BC_E/Mu", "AllBCs/BC_L/Mu"},
{"FT0VTx/BC_A/Mu", "FT0VTx/BC_B/Mu", "FT0VTx/BC_C/Mu", "FT0VTx/BC_E/Mu", "FT0VTx/BC_L/Mu"},
{"FT0CE/BC_A/Mu", "FT0CE/BC_B/Mu", "FT0CE/BC_C/Mu", "FT0CE/BC_E/Mu", "FT0CE/BC_L/Mu"},
{"FDD/BC_A/Mu", "FDD/BC_B/Mu", "FDD/BC_C/Mu", "FDD/BC_E/Mu", "FDD/BC_L/Mu"}};

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}"};

int64_t bcSOR;
Expand All @@ -160,6 +171,7 @@ struct LumiStabilityPP {
histTfPerMin[runNumber] = registry.add<TH1>(Form("%d/TFsPerMinute", runNumber), "TFs seen in this minute (to account for failed jobs);#bf{t-t_{SOF} (min)};#bf{#it{N}_{TFs}}", HistType::kTH1D, {timeAxis});
histFillingScheme[runNumber] = registry.add<TH1>(Form("%d/FillingScheme", runNumber), "Filling Scheme;Filling Scheme;", HistType::kTH1D, {{1, 0, 1}});
histFillTime[runNumber] = registry.add<TH1>(Form("%d/FillTime", runNumber), "Fill time;Fill time;", HistType::kTH1D, {{1, 0, 1}});
histInteractionRate[runNumber] = registry.add<TH1>(Form("%d/InteractionRate", runNumber), "Interaction rate (kHz);Interaction rate (kHz);", HistType::kTH1D, {{3000, 0., 3000.}});

histBcHasFT0[runNumber] = registry.add<TH2>(Form("%d/FITQA/BCHasFT0", runNumber), "Does the BC have FT0?;BC has FT0;TVX triggered according to CTP;#bf{#it{N}_{BC}}", HistType::kTH2D, {{2, -0.5, 1.5}, {2, -0.5, 1.5}});
histBcHasFT0[runNumber]->GetYaxis()->SetBinLabel(1, "No CTP trigger");
Expand All @@ -177,22 +189,31 @@ struct LumiStabilityPP {
if ((iBCCategory == BCA && doBCA) || (iBCCategory == BCB && doBCB) || (iBCCategory == BCC && doBCC) || (iBCCategory == BCE && doBCE) || (iBCCategory == BCL && doBCL) || (iBCCategory == BCSL && doBCSL)) {
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});
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});
if (iBCCategory != BCSL) { // we do not do it for superleading because it is not easy to define the number of inspected BCs
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}});
}
}
}
}
}

void setLHCIFData(const auto& bc)
{

if (runNumber == bc.runNumber()) {
return;
}

auto& ccdbMgr = o2::ccdb::BasicCCDBManager::instance();
const int runStart2023{535069};
const int runStop2023{539908};
if (bc.runNumber() >= runStart2023 && bc.runNumber() <= runStop2023) {
isData23 = true;
}

uint64_t timeStamp = bc.timestamp();

std::map<std::string, std::string> metadata;
mLHCIFdata = ccdbMgr.getSpecific<o2::parameters::GRPLHCIFData>("GLO/Config/GRPLHCIF", timeStamp, metadata);
mLHCIFdata = ccdb.service->getSpecific<o2::parameters::GRPLHCIFData>("GLO/Config/GRPLHCIF", timeStamp, metadata);
if (mLHCIFdata == nullptr) {
LOG(fatal) << "GRPLHCIFData not in database, timestamp:" << timeStamp;
}
Expand Down Expand Up @@ -249,42 +270,81 @@ struct LumiStabilityPP {
return (bc.timestamp() - mLHCIFdata->getFillNumberTime()) / 1e3 / 60; // Convert to minutes
}

float getMu(double triggerRate, int nbc)
{
if (nbc == 0) {
return 0.;
}
return -std::log(1.f - triggerRate / nbc / constants::lhc::LHCRevFreq);
}

template <int iTrigger, int iBCCategory>
void fillHistograms(float timeSinceSOF, int64_t localBC)
void fillHistograms(float timeSinceSOF, int64_t localBC, int& nTriggers)
{
nTriggers += 1;
histBcVsTime[iTrigger][iBCCategory][runNumber]->Fill(timeSinceSOF);
histBcVsBcId[iTrigger][iBCCategory][runNumber]->Fill(localBC);
}

void fillMuHistograms(int iTrigger, int iBCCategory, float mu)
{
histMu[iTrigger][iBCCategory][runNumber]->Fill(mu);
}

void process(BCsWithTimeStamps const& bcs,
aod::FT0s const&,
aod::FDDs const&)
{
int64_t globalBCIdOfLastBCWithActivity = 0;
int nBCs[2] = {0, 0};
float timeStartSinceSOF{-1.f}, timeStopSinceSOF{-1.f};
int nTriggersPerDf[NTriggerAliases][NBCCategories];
for (const auto& bc : bcs) {

if (bc.timestamp() == 0) {
continue;
}

setLHCIFData(bc);
BCsWithTimeStamps::iterator bcFDD;
auto idxBc = bc.globalIndex();
if (isData23) {
if (idxBc < bcShiftFDDForData2023) { // we need to skip the first 15 because of the FDD-FT0 shift
continue;
}
bcFDD = bcs.rawIteratorAt(idxBc + bcShiftFDDForData2023);
} else {
bcFDD = bc;
}

float timeSinceSOF = getTimeSinceSOF(bc);
if (timeStartSinceSOF < 0.) {
timeStartSinceSOF = timeSinceSOF;
}
if (timeStopSinceSOF < timeSinceSOF) {
timeStopSinceSOF = timeSinceSOF;
}

bool isTriggerTVX = (bc.has_ft0() ? TESTBIT(bc.ft0().triggerMask(), o2::ft0::Triggers::bitVertex) : false);

if (isTriggerTVX) {
histNBcsVsTime[runNumber]->Fill(timeSinceSOF);
histInteractionRate[runNumber]->Fill(mRateFetcher.fetch(ccdb.service, bc.timestamp(), bc.runNumber(), std::string("T0VTX"), true) * 1.e-3); // kHz
}

int64_t globalBC = bc.globalBC();
int localBC = globalBC % nBCsPerOrbit;
nBCs[0]++;
if (bcPatternL[localBC]) {
nBCs[1]++;
}

bool isSuperLeadingBc{true};
if (globalBC - globalBCIdOfLastBCWithActivity < numEmptyBCsBeforeLeadingBC) {
isSuperLeadingBc = false; // not a super-leading BC
}

if (bc.has_fdd() || (requireNoT0ForSLBC && bc.has_ft0())) {
if (bcFDD.has_fdd() || (requireNoT0ForSLBC && bc.has_ft0())) {
globalBCIdOfLastBCWithActivity = globalBC;
}

Expand All @@ -300,74 +360,91 @@ struct LumiStabilityPP {
}

std::bitset<64> ctpInputMask(bc.inputMask());
std::bitset<64> ctpInputMaskFDD(bcFDD.inputMask());

histBcHasFT0[runNumber]->Fill(bc.has_ft0(), ctpInputMask.test(2));
histBcHasFDD[runNumber]->Fill(bc.has_fdd(), ctpInputMask.test(15));
histBcHasFDD[runNumber]->Fill(bcFDD.has_fdd(), ctpInputMaskFDD.test(15));

for (int iTrigger{0}; iTrigger < NTriggerAliases; ++iTrigger) {
for (int iBCCategory{0}; iBCCategory < NBCCategories; ++iBCCategory) {
if ((iBCCategory == BCA && doBCA) || (iBCCategory == BCB && doBCB) || (iBCCategory == BCC && doBCC) || (iBCCategory == BCE && doBCE) || (iBCCategory == BCL && doBCL) || (iBCCategory == BCSL && doBCSL)) {
if (iTrigger == AllBCs) {
if (iBCCategory == BCA && bcPatternA[localBC])
fillHistograms<AllBCs, BCA>(timeSinceSOF, localBC);
fillHistograms<AllBCs, BCA>(timeSinceSOF, localBC, nTriggersPerDf[iTrigger][iBCCategory]);
if (iBCCategory == BCB && bcPatternB[localBC])
fillHistograms<AllBCs, BCB>(timeSinceSOF, localBC);
fillHistograms<AllBCs, BCB>(timeSinceSOF, localBC, nTriggersPerDf[iTrigger][iBCCategory]);
if (iBCCategory == BCC && bcPatternC[localBC])
fillHistograms<AllBCs, BCC>(timeSinceSOF, localBC);
fillHistograms<AllBCs, BCC>(timeSinceSOF, localBC, nTriggersPerDf[iTrigger][iBCCategory]);
if (iBCCategory == BCE && bcPatternE[localBC])
fillHistograms<AllBCs, BCE>(timeSinceSOF, localBC);
fillHistograms<AllBCs, BCE>(timeSinceSOF, localBC, nTriggersPerDf[iTrigger][iBCCategory]);
if (iBCCategory == BCL && bcPatternL[localBC])
fillHistograms<AllBCs, BCL>(timeSinceSOF, localBC);
fillHistograms<AllBCs, BCL>(timeSinceSOF, localBC, nTriggersPerDf[iTrigger][iBCCategory]);
if (iBCCategory == BCSL && isSuperLeadingBc)
fillHistograms<AllBCs, BCSL>(timeSinceSOF, localBC);
fillHistograms<AllBCs, BCSL>(timeSinceSOF, localBC, nTriggersPerDf[iTrigger][iBCCategory]);
}
if (iTrigger == FT0Vtx && ctpInputMask.test(2)) {
if (iBCCategory == BCA && bcPatternA[localBC])
fillHistograms<FT0Vtx, BCA>(timeSinceSOF, localBC);
fillHistograms<FT0Vtx, BCA>(timeSinceSOF, localBC, nTriggersPerDf[iTrigger][iBCCategory]);
if (iBCCategory == BCB && bcPatternB[localBC])
fillHistograms<FT0Vtx, BCB>(timeSinceSOF, localBC);
fillHistograms<FT0Vtx, BCB>(timeSinceSOF, localBC, nTriggersPerDf[iTrigger][iBCCategory]);
if (iBCCategory == BCC && bcPatternC[localBC])
fillHistograms<FT0Vtx, BCC>(timeSinceSOF, localBC);
fillHistograms<FT0Vtx, BCC>(timeSinceSOF, localBC, nTriggersPerDf[iTrigger][iBCCategory]);
if (iBCCategory == BCE && bcPatternE[localBC])
fillHistograms<FT0Vtx, BCE>(timeSinceSOF, localBC);
fillHistograms<FT0Vtx, BCE>(timeSinceSOF, localBC, nTriggersPerDf[iTrigger][iBCCategory]);
if (iBCCategory == BCL && bcPatternL[localBC])
fillHistograms<FT0Vtx, BCL>(timeSinceSOF, localBC);
fillHistograms<FT0Vtx, BCL>(timeSinceSOF, localBC, nTriggersPerDf[iTrigger][iBCCategory]);
if (iBCCategory == BCSL && isSuperLeadingBc)
fillHistograms<FT0Vtx, BCSL>(timeSinceSOF, localBC);
fillHistograms<FT0Vtx, BCSL>(timeSinceSOF, localBC, nTriggersPerDf[iTrigger][iBCCategory]);
}
if (iTrigger == FT0CE && ctpInputMask.test(4)) {
if (iBCCategory == BCA && bcPatternA[localBC])
fillHistograms<FT0CE, BCA>(timeSinceSOF, localBC);
fillHistograms<FT0CE, BCA>(timeSinceSOF, localBC, nTriggersPerDf[iTrigger][iBCCategory]);
if (iBCCategory == BCB && bcPatternB[localBC])
fillHistograms<FT0CE, BCB>(timeSinceSOF, localBC);
fillHistograms<FT0CE, BCB>(timeSinceSOF, localBC, nTriggersPerDf[iTrigger][iBCCategory]);
if (iBCCategory == BCC && bcPatternC[localBC])
fillHistograms<FT0CE, BCC>(timeSinceSOF, localBC);
fillHistograms<FT0CE, BCC>(timeSinceSOF, localBC, nTriggersPerDf[iTrigger][iBCCategory]);
if (iBCCategory == BCE && bcPatternE[localBC])
fillHistograms<FT0CE, BCE>(timeSinceSOF, localBC);
fillHistograms<FT0CE, BCE>(timeSinceSOF, localBC, nTriggersPerDf[iTrigger][iBCCategory]);
if (iBCCategory == BCL && bcPatternL[localBC])
fillHistograms<FT0CE, BCL>(timeSinceSOF, localBC);
fillHistograms<FT0CE, BCL>(timeSinceSOF, localBC, nTriggersPerDf[iTrigger][iBCCategory]);
if (iBCCategory == BCSL && isSuperLeadingBc)
fillHistograms<FT0CE, BCSL>(timeSinceSOF, localBC);
fillHistograms<FT0CE, BCSL>(timeSinceSOF, localBC, nTriggersPerDf[iTrigger][iBCCategory]);
}
if (iTrigger == FDD && ctpInputMask.test(15)) {
if (iTrigger == FDD && ctpInputMaskFDD.test(15)) {
if (iBCCategory == BCA && bcPatternA[localBC])
fillHistograms<FDD, BCA>(timeSinceSOF, localBC);
fillHistograms<FDD, BCA>(timeSinceSOF, localBC, nTriggersPerDf[iTrigger][iBCCategory]);
if (iBCCategory == BCB && bcPatternB[localBC])
fillHistograms<FDD, BCB>(timeSinceSOF, localBC);
fillHistograms<FDD, BCB>(timeSinceSOF, localBC, nTriggersPerDf[iTrigger][iBCCategory]);
if (iBCCategory == BCC && bcPatternC[localBC])
fillHistograms<FDD, BCC>(timeSinceSOF, localBC);
fillHistograms<FDD, BCC>(timeSinceSOF, localBC, nTriggersPerDf[iTrigger][iBCCategory]);
if (iBCCategory == BCE && bcPatternE[localBC])
fillHistograms<FDD, BCE>(timeSinceSOF, localBC);
fillHistograms<FDD, BCE>(timeSinceSOF, localBC, nTriggersPerDf[iTrigger][iBCCategory]);
if (iBCCategory == BCL && bcPatternL[localBC])
fillHistograms<FDD, BCL>(timeSinceSOF, localBC);
fillHistograms<FDD, BCL>(timeSinceSOF, localBC, nTriggersPerDf[iTrigger][iBCCategory]);
if (iBCCategory == BCSL && isSuperLeadingBc)
fillHistograms<FDD, BCSL>(timeSinceSOF, localBC);
fillHistograms<FDD, BCSL>(timeSinceSOF, localBC, nTriggersPerDf[iTrigger][iBCCategory]);
}
}
}
}
histNBcsVsBcId[runNumber]->Fill(localBC);
}
// fill histogram for mu
float deltaTime = timeStopSinceSOF - timeStartSinceSOF;
for (int iTrigger{0}; iTrigger < NTriggerAliases; ++iTrigger) {
for (int iBCCategory{0}; iBCCategory < NBCCategories; ++iBCCategory) {
if (iBCCategory == BCSL) { // we do not do it for superleading because it is not easy to define the number of inspected BCs
continue;
}
float mu{0.};
if (iBCCategory != BCSL) {
mu = getMu(nTriggersPerDf[iTrigger][iBCCategory] / deltaTime, nBCs[0]);
} else {
mu = getMu(nTriggersPerDf[iTrigger][iBCCategory] / deltaTime, nBCs[1]);
}
fillMuHistograms(iTrigger, iBCCategory, mu);
}
}
}
};

Expand Down
Loading