Skip to content
Merged
Show file tree
Hide file tree
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
1 change: 1 addition & 0 deletions Modules/FT0/include/FT0/BasicPPTask.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class BasicPPTask final : public quality_control::postprocessing::PostProcessing
void finalize(quality_control::postprocessing::Trigger, framework::ServiceRegistry&) override;

private:
std::string mPathDigitQcTask;
std::string mCycleDurationMoName;
int mNumOrbitsInTF;

Expand Down
1 change: 1 addition & 0 deletions Modules/FT0/include/FT0/DigitQcTask.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ class DigitQcTask final : public TaskInterface
void endOfActivity(Activity& activity) override;
void reset() override;
constexpr static std::size_t sOrbitsPerTF = 256;
constexpr static uint8_t sDataIsValidBitPos = 7;

private:
// three ways of computing cycle duration:
Expand Down
2 changes: 2 additions & 0 deletions Modules/FT0/include/FT0/OutOfBunchCollTask.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ class OutOfBunchCollTask final : public quality_control::postprocessing::PostPro
void configure(std::string, const boost::property_tree::ptree&) override;

private:
std::string mPathDigitQcTask;
std::string mPathBunchFilling;
o2::quality_control::repository::DatabaseInterface* mDatabase = nullptr;
std::string mCcdbUrl;
o2::ccdb::CcdbApi mCcdbApi;
Expand Down
141 changes: 77 additions & 64 deletions Modules/FT0/src/BasicPPTask.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,15 @@ void BasicPPTask::configure(std::string, const boost::property_tree::ptree& conf
mCycleDurationMoName = "CycleDurationNTF";
ILOG(Info, Support) << "configure() : using default cycleDurationMoName = \"" << mCycleDurationMoName << "\"" << ENDM;
}

node = config.get_child_optional(Form("%s.custom.pathDigitQcTask", configPath));
if (node) {
mPathDigitQcTask = node.get_ptr()->get_child("").get_value<std::string>();
ILOG(Info, Support) << "configure() : using pathDigitQcTask = \"" << mPathDigitQcTask << "\"" << ENDM;
} else {
mPathDigitQcTask = "qc/FT0/MO/DigitQcTask/";
ILOG(Info, Support) << "configure() : using default pathDigitQcTask = \"" << mPathDigitQcTask << "\"" << ENDM;
}
}

void BasicPPTask::initialize(Trigger, framework::ServiceRegistry& services)
Expand Down Expand Up @@ -107,87 +116,91 @@ void BasicPPTask::initialize(Trigger, framework::ServiceRegistry& services)

void BasicPPTask::update(Trigger, framework::ServiceRegistry&)
{
auto mo = mDatabase->retrieveMO("qc/FT0/MO/DigitQcTask/", "Triggers");
auto hTriggers = (TH1F*)mo->getObject();
auto mo = mDatabase->retrieveMO(mPathDigitQcTask, "Triggers");
auto hTriggers = mo ? (TH1F*)mo->getObject() : nullptr;
if (!hTriggers) {
ILOG(Error) << "MO \"Triggers\" NOT retrieved!!!" << ENDM;
}

auto mo2 = mDatabase->retrieveMO("qc/FT0/MO/DigitQcTask/", mCycleDurationMoName);
auto hCycleDuration = (TH1D*)mo2->getObject();
auto mo2 = mDatabase->retrieveMO(mPathDigitQcTask, mCycleDurationMoName);
auto hCycleDuration = mo2 ? (TH1D*)mo2->getObject() : nullptr;
if (!hCycleDuration) {
ILOG(Error) << "MO \"" << mCycleDurationMoName << "\" NOT retrieved!!!" << ENDM;
}

double cycleDurationMS = 0;
if (mCycleDurationMoName == "CycleDuration" || mCycleDurationMoName == "CycleDurationRange")
// assume MO stores cycle duration in ns
cycleDurationMS = hCycleDuration->GetBinContent(1) / 1e6; // ns -> ms
else if (mCycleDurationMoName == "CycleDurationNTF")
// assume MO stores cycle duration in number of TF
cycleDurationMS = hCycleDuration->GetBinContent(1) * mNumOrbitsInTF * o2::constants::lhc::LHCOrbitNS / 1e6; // ns ->ms

int n = mRateOrA->GetN();

double eps = 1e-8;
if (cycleDurationMS < eps) {
ILOG(Warning) << "cycle duration = " << cycleDurationMS << " ms, almost zero - cannot compute trigger rates!" << ENDM;
} else {
mRateOrA->SetPoint(n, n, hTriggers->GetBinContent(hTriggers->GetXaxis()->FindBin("OrA")) / cycleDurationMS);
mRateOrC->SetPoint(n, n, hTriggers->GetBinContent(hTriggers->GetXaxis()->FindBin("OrC")) / cycleDurationMS);
mRateVertex->SetPoint(n, n, hTriggers->GetBinContent(hTriggers->GetXaxis()->FindBin("Vertex")) / cycleDurationMS);
mRateCentral->SetPoint(n, n, hTriggers->GetBinContent(hTriggers->GetXaxis()->FindBin("Central")) / cycleDurationMS);
mRateSemiCentral->SetPoint(n, n, hTriggers->GetBinContent(hTriggers->GetXaxis()->FindBin("SemiCentral")) / cycleDurationMS);
if (hTriggers && hCycleDuration) {
double cycleDurationMS = 0;
if (mCycleDurationMoName == "CycleDuration" || mCycleDurationMoName == "CycleDurationRange")
// assume MO stores cycle duration in ns
cycleDurationMS = hCycleDuration->GetBinContent(1) / 1e6; // ns -> ms
else if (mCycleDurationMoName == "CycleDurationNTF")
// assume MO stores cycle duration in number of TF
cycleDurationMS = hCycleDuration->GetBinContent(1) * mNumOrbitsInTF * o2::constants::lhc::LHCOrbitNS / 1e6; // ns ->ms

int n = mRateOrA->GetN();

double eps = 1e-8;
if (cycleDurationMS < eps) {
ILOG(Warning) << "cycle duration = " << cycleDurationMS << " ms, almost zero - cannot compute trigger rates!" << ENDM;
} else {
mRateOrA->SetPoint(n, n, hTriggers->GetBinContent(hTriggers->GetXaxis()->FindBin("OrA")) / cycleDurationMS);
mRateOrC->SetPoint(n, n, hTriggers->GetBinContent(hTriggers->GetXaxis()->FindBin("OrC")) / cycleDurationMS);
mRateVertex->SetPoint(n, n, hTriggers->GetBinContent(hTriggers->GetXaxis()->FindBin("Vertex")) / cycleDurationMS);
mRateCentral->SetPoint(n, n, hTriggers->GetBinContent(hTriggers->GetXaxis()->FindBin("Central")) / cycleDurationMS);
mRateSemiCentral->SetPoint(n, n, hTriggers->GetBinContent(hTriggers->GetXaxis()->FindBin("SemiCentral")) / cycleDurationMS);
}

mRatesCanv->cd();
float vmin = std::min({ mRateOrA->GetYaxis()->GetXmin(), mRateOrC->GetYaxis()->GetXmin(), mRateVertex->GetYaxis()->GetXmin(), mRateCentral->GetYaxis()->GetXmin(), mRateSemiCentral->GetYaxis()->GetXmin() });
float vmax = std::max({ mRateOrA->GetYaxis()->GetXmax(), mRateOrC->GetYaxis()->GetXmax(), mRateVertex->GetYaxis()->GetXmax(), mRateCentral->GetYaxis()->GetXmax(), mRateSemiCentral->GetYaxis()->GetXmax() });

auto hAxis = mRateOrA->GetHistogram();
hAxis->GetYaxis()->SetTitleOffset(1.4);
hAxis->SetMinimum(vmin);
hAxis->SetMaximum(vmax * 1.1);
hAxis->SetTitle("FT0 trigger rates");
hAxis->SetLineWidth(0);
hAxis->Draw("AXIS");

mRateOrA->Draw("PL,SAME");
mRateOrC->Draw("PL,SAME");
mRateVertex->Draw("PL,SAME");
mRateCentral->Draw("PL,SAME");
mRateSemiCentral->Draw("PL,SAME");
TLegend* leg = gPad->BuildLegend();
leg->SetFillStyle(1);
}

mRatesCanv->cd();
float vmin = std::min({ mRateOrA->GetYaxis()->GetXmin(), mRateOrC->GetYaxis()->GetXmin(), mRateVertex->GetYaxis()->GetXmin(), mRateCentral->GetYaxis()->GetXmin(), mRateSemiCentral->GetYaxis()->GetXmin() });
float vmax = std::max({ mRateOrA->GetYaxis()->GetXmax(), mRateOrC->GetYaxis()->GetXmax(), mRateVertex->GetYaxis()->GetXmax(), mRateCentral->GetYaxis()->GetXmax(), mRateSemiCentral->GetYaxis()->GetXmax() });

auto hAxis = mRateOrA->GetHistogram();
hAxis->GetYaxis()->SetTitleOffset(1.4);
hAxis->SetMinimum(vmin);
hAxis->SetMaximum(vmax * 1.1);
hAxis->SetTitle("FT0 trigger rates");
hAxis->SetLineWidth(0);
hAxis->Draw("AXIS");

mRateOrA->Draw("PL,SAME");
mRateOrC->Draw("PL,SAME");
mRateVertex->Draw("PL,SAME");
mRateCentral->Draw("PL,SAME");
mRateSemiCentral->Draw("PL,SAME");
TLegend* leg = gPad->BuildLegend();
leg->SetFillStyle(1);

auto mo3 = mDatabase->retrieveMO("qc/FT0/MO/DigitQcTask/", "AmpPerChannel");
auto hAmpPerChannel = (TH2D*)mo3->getObject();
auto mo3 = mDatabase->retrieveMO(mPathDigitQcTask, "AmpPerChannel");
auto hAmpPerChannel = mo3 ? (TH2D*)mo3->getObject() : nullptr;
if (!hAmpPerChannel) {
ILOG(Error) << "\nMO \"AmpPerChannel\" NOT retrieved!!!\n"
ILOG(Error) << "MO \"AmpPerChannel\" NOT retrieved!!!"
<< ENDM;
}
auto mo4 = mDatabase->retrieveMO("qc/FT0/MO/DigitQcTask/", "TimePerChannel");
auto hTimePerChannel = (TH2D*)mo4->getObject();
auto mo4 = mDatabase->retrieveMO(mPathDigitQcTask, "TimePerChannel");
auto hTimePerChannel = mo4 ? (TH2D*)mo4->getObject() : nullptr;
if (!hTimePerChannel) {
ILOG(Error) << "\nMO \"TimePerChannel\" NOT retrieved!!!\n"
ILOG(Error) << "MO \"TimePerChannel\" NOT retrieved!!!"
<< ENDM;
}

mAmpl = hAmpPerChannel->ProfileX("MeanAmplPerChannel");
mTime = hTimePerChannel->ProfileX("MeanTimePerChannel");
mAmpl->SetErrorOption("s");
mTime->SetErrorOption("s");
// for some reason the styling is not preserved after assigning result of ProfileX/Y() to already existing object
mAmpl->SetMarkerStyle(8);
mTime->SetMarkerStyle(8);
mAmpl->SetLineColor(kBlack);
mTime->SetLineColor(kBlack);
mAmpl->SetDrawOption("P");
mTime->SetDrawOption("P");
mAmpl->GetXaxis()->SetTitleOffset(1);
mTime->GetXaxis()->SetTitleOffset(1);
mAmpl->GetYaxis()->SetTitleOffset(1);
mTime->GetYaxis()->SetTitleOffset(1);
if (hAmpPerChannel && hTimePerChannel) {
mAmpl = hAmpPerChannel->ProfileX("MeanAmplPerChannel");
mTime = hTimePerChannel->ProfileX("MeanTimePerChannel");
mAmpl->SetErrorOption("s");
mTime->SetErrorOption("s");
// for some reason the styling is not preserved after assigning result of ProfileX/Y() to already existing object
mAmpl->SetMarkerStyle(8);
mTime->SetMarkerStyle(8);
mAmpl->SetLineColor(kBlack);
mTime->SetLineColor(kBlack);
mAmpl->SetDrawOption("P");
mTime->SetDrawOption("P");
mAmpl->GetXaxis()->SetTitleOffset(1);
mTime->GetXaxis()->SetTitleOffset(1);
mAmpl->GetYaxis()->SetTitleOffset(1);
mTime->GetYaxis()->SetTitleOffset(1);
}
}

void BasicPPTask::finalize(Trigger, framework::ServiceRegistry&)
Expand Down
14 changes: 13 additions & 1 deletion Modules/FT0/src/DigitQcTask.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@ void DigitQcTask::initialize(o2::framework::InitContext& /*ctx*/)
mMapDigitTrgNames.insert({ o2::ft0::Triggers::bitVertex, "Vertex" });
mMapDigitTrgNames.insert({ o2::ft0::Triggers::bitCen, "Central" });
mMapDigitTrgNames.insert({ o2::ft0::Triggers::bitSCen, "SemiCentral" });
mMapDigitTrgNames.insert({ 5, "Laser" });
mMapDigitTrgNames.insert({ 6, "OutputsAreBlocked" });
mMapDigitTrgNames.insert({ 7, "DataIsValid" });

mHistTime2Ch = std::make_unique<TH2F>("TimePerChannel", "Time vs Channel;Channel;Time", o2::ft0::Constants::sNCHANNELS_PM, 0, o2::ft0::Constants::sNCHANNELS_PM, 4100, -2050, 2050);
mHistTime2Ch->SetOption("colz");
Expand Down Expand Up @@ -148,6 +151,12 @@ void DigitQcTask::initialize(o2::framework::InitContext& /*ctx*/)
continue;
}
auto moduleName = lutEntry.mModuleName;
if (moduleName == "TCM") {
if (mMapPmModuleChannels.find(moduleName) == mMapPmModuleChannels.end()) {
mMapPmModuleChannels.insert({ moduleName, std::vector<int>{} });
}
continue;
}
if (mMapPmModuleChannels.find(moduleName) != mMapPmModuleChannels.end()) {
mMapPmModuleChannels[moduleName].push_back(chId);
} else {
Expand Down Expand Up @@ -335,7 +344,7 @@ void DigitQcTask::monitorData(o2::framework::ProcessingContext& ctx)

if (digit.mTriggers.amplA == -5000 && digit.mTriggers.amplC == -5000 && digit.mTriggers.timeA == -5000 && digit.mTriggers.timeC == -5000)
isTCM = false;
mHistOrbit2BC->Fill(digit.getOrbit() - firstOrbit, digit.getBC());
mHistOrbit2BC->Fill(digit.getIntRecord().orbit % sOrbitsPerTF, digit.getIntRecord().bc);
mHistBC->Fill(digit.getBC());

if (isTCM && !digit.mTriggers.getLaserBit()) {
Expand Down Expand Up @@ -368,6 +377,9 @@ void DigitQcTask::monitorData(o2::framework::ProcessingContext& ctx)
break;
}
}
if (entry.first == "TCM" && isTCM && (digit.getTriggers().triggersignals & (1 << sDataIsValidBitPos))) {
mMapPmModuleBcOrbit[entry.first]->Fill(digit.getIntRecord().orbit % sOrbitsPerTF, digit.getIntRecord().bc);
}
}

for (const auto& chData : vecChData) {
Expand Down
17 changes: 10 additions & 7 deletions Modules/FT0/src/OutOfBunchCollCheck.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ Quality OutOfBunchCollCheck::check(std::map<std::string, std::shared_ptr<Monitor
{
Quality result = Quality::Null;
TH2F* hOutOfBunchColl = 0;
float countsBcOrbitMap = 0;
float countsOutOfBunchColl = 0;
float integralBcOrbitMap = 0;
float integralOutOfBunchColl = 0;
bool metadataFound = false;
std::string metadataKey = "BcOrbitMapIntegral";

Expand All @@ -66,15 +66,15 @@ Quality OutOfBunchCollCheck::check(std::map<std::string, std::shared_ptr<Monitor
hOutOfBunchColl = dynamic_cast<TH2F*>(mo->getObject());
for (auto metainfo : mo->getMetadataMap()) {
if (metainfo.first == metadataKey) {
countsBcOrbitMap = std::stof(metainfo.second);
integralBcOrbitMap = std::stof(metainfo.second);
metadataFound = true;
}
}
}
}
std::string reason = "";
if (!countsBcOrbitMap)
reason = Form("Cannot compute quality due to zero counts in BcOrbitMap");
if (!integralBcOrbitMap)
reason = Form("Cannot compute quality due to zero integ in BcOrbitMap");
if (!metadataFound)
reason = Form("Cannot compute quality due to missing metadata: %s", metadataKey.c_str());
if (!hOutOfBunchColl)
Expand All @@ -90,8 +90,11 @@ Quality OutOfBunchCollCheck::check(std::map<std::string, std::shared_ptr<Monitor
mFractionOutOfBunchColl = 0;
mNumNonEmptyBins = 0;

countsOutOfBunchColl = hOutOfBunchColl->Integral();
mFractionOutOfBunchColl = countsOutOfBunchColl / countsBcOrbitMap;
integralOutOfBunchColl = hOutOfBunchColl->Integral();
mFractionOutOfBunchColl = integralOutOfBunchColl / integralBcOrbitMap;

ILOG(Debug, Support) << "in checker: integralBcOrbitMap:" << integralBcOrbitMap << " integralOutOfBunchColl: " << integralOutOfBunchColl << " -> fraction: " << mFractionOutOfBunchColl << ENDM;

if (mFractionOutOfBunchColl > mThreshError) {
result.set(Quality::Bad);
result.addReason(FlagReasonFactory::Unknown(),
Expand Down
33 changes: 28 additions & 5 deletions Modules/FT0/src/OutOfBunchCollTask.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,26 @@ OutOfBunchCollTask::~OutOfBunchCollTask()
void OutOfBunchCollTask::configure(std::string, const boost::property_tree::ptree& config)
{
mCcdbUrl = config.get_child("qc.config.conditionDB.url").get_value<std::string>();

const char* configPath = Form("qc.postprocessing.%s", getName().c_str());
ILOG(Info, Support) << "configPath = " << configPath << ENDM;
auto node = config.get_child_optional(Form("%s.custom.pathDigitQcTask", configPath));
if (node) {
mPathDigitQcTask = node.get_ptr()->get_child("").get_value<std::string>();
ILOG(Info, Support) << "configure() : using pathDigitQcTask = \"" << mPathDigitQcTask << "\"" << ENDM;
} else {
mPathDigitQcTask = "qc/FT0/MO/DigitQcTask/";
ILOG(Info, Support) << "configure() : using default pathDigitQcTask = \"" << mPathDigitQcTask << "\"" << ENDM;
}

node = config.get_child_optional(Form("%s.custom.pathBunchFilling", configPath));
if (node) {
mPathBunchFilling = node.get_ptr()->get_child("").get_value<std::string>();
ILOG(Info, Support) << "configure() : using pathBunchFilling = \"" << mPathBunchFilling << "\"" << ENDM;
} else {
mPathBunchFilling = "GLO/GRP/BunchFilling";
ILOG(Info, Support) << "configure() : using default pathBunchFilling = \"" << mPathBunchFilling << "\"" << ENDM;
}
}

void OutOfBunchCollTask::initialize(Trigger, framework::ServiceRegistry& services)
Expand Down Expand Up @@ -71,10 +91,11 @@ void OutOfBunchCollTask::update(Trigger, framework::ServiceRegistry&)
{
std::map<std::string, std::string> metadata;
std::map<std::string, std::string> headers;
const auto* bcPattern = mCcdbApi.retrieveFromTFileAny<o2::BunchFilling>("GLO/GRP/BunchFilling", metadata, -1, &headers);
const auto* bcPattern = mCcdbApi.retrieveFromTFileAny<o2::BunchFilling>(mPathBunchFilling, metadata, -1, &headers);
if (!bcPattern) {
ILOG(Error, Support) << "\nMO \"BunchFilling\" NOT retrieved!!!\n"
ILOG(Error, Support) << "object \"" << mPathBunchFilling << "\" NOT retrieved!!!"
<< ENDM;
return;
}
const int nBc = 3564;
const int nOrbits = 256;
Expand All @@ -85,11 +106,12 @@ void OutOfBunchCollTask::update(Trigger, framework::ServiceRegistry&)

for (auto& entry : mMapOutOfBunchColl) {
auto moName = Form("BcOrbitMap_Trg%s", mMapDigitTrgNames.at(entry.first).c_str());
auto mo = mDatabase->retrieveMO("qc/FT0/MO/DigitQcTask/", moName);
auto hBcOrbitMapTrg = (TH2F*)mo->getObject();
auto mo = mDatabase->retrieveMO(mPathDigitQcTask, moName);
auto hBcOrbitMapTrg = mo ? (TH2F*)mo->getObject() : nullptr;
if (!hBcOrbitMapTrg) {
ILOG(Error, Support) << "\nMO \"" << moName << "\" NOT retrieved!!!\n"
ILOG(Error, Support) << "MO \"" << moName << "\" NOT retrieved!!!"
<< ENDM;
continue;
}
entry.second->Reset();
// scale bc pattern by vmax to make sure the difference is non positive
Expand All @@ -101,6 +123,7 @@ void OutOfBunchCollTask::update(Trigger, framework::ServiceRegistry&)
entry.second->SetBinContent(j + 1, i + 1, 0); // is it too slow?
entry.second->SetEntries(entry.second->Integral());
getObjectsManager()->addMetadata(entry.second->GetName(), "BcOrbitMapIntegral", std::to_string(hBcOrbitMapTrg->Integral()));
ILOG(Debug, Support) << "Trg: " << moName << " Integrals BcOrbitMap: " << hBcOrbitMapTrg->Integral() << ", OutOfBunchColl:" << entry.second->Integral() << ENDM;
}
}

Expand Down
1 change: 1 addition & 0 deletions Modules/FV0/include/FV0/BasicPPTask.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ class BasicPPTask final : public quality_control::postprocessing::PostProcessing
constexpr static std::size_t sNCHANNELS_PM = 60; //48(for PM) + 12(just in case for possible PM-LCS)

private:
std::string mPathDigitQcTask;
std::string mCycleDurationMoName;
int mNumOrbitsInTF;

Expand Down
1 change: 1 addition & 0 deletions Modules/FV0/include/FV0/DigitQcTask.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ class DigitQcTask final : public TaskInterface
constexpr static std::size_t sNCHANNELS_PM = 60; //48(for PM) + 12(just in case for possible PM-LCS)
constexpr static std::size_t sOrbitsPerTF = 256;
constexpr static uint8_t sLaserBitPos = 5;
constexpr static uint8_t sDataIsValidBitPos = 7;

private:
// three ways of computing cycle duration:
Expand Down
2 changes: 2 additions & 0 deletions Modules/FV0/include/FV0/OutOfBunchCollTask.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ class OutOfBunchCollTask final : public quality_control::postprocessing::PostPro
kInnerRing
};

std::string mPathDigitQcTask;
std::string mPathBunchFilling;
o2::quality_control::repository::DatabaseInterface* mDatabase = nullptr;
std::string mCcdbUrl;
o2::ccdb::CcdbApi mCcdbApi;
Expand Down
Loading