Skip to content

Commit

Permalink
GLO: add trending to MeanVertex post-processing (#1864)
Browse files Browse the repository at this point in the history
* [GLO] add trending to MeanVertex post-processing

- trending graphs for vertex position and sigma are implemented into the MeanVertexPostProcessing task, taking values and time stamps directly from the CCDB calibration objects
- the calibration objects are retrieved using the post-processing trigger time stamp instead of the current time

* [GLO] added virtual destructor to TrendGraph

* [GLO] added back histograms with optional reset

The histograms are aded back to preserve the possibility to run the original post-processing.
The histograms can be optionally reset at each post-processing trigger.
  • Loading branch information
aferrero2707 authored Jul 6, 2023
1 parent 42981ae commit cb71885
Show file tree
Hide file tree
Showing 3 changed files with 175 additions and 7 deletions.
2 changes: 1 addition & 1 deletion Modules/GLO/include/GLO/LinkDef.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@
#pragma link C++ class o2::quality_control_modules::glo::ITSTPCMatchingTask + ;
#pragma link C++ class o2::quality_control_modules::glo::DataCompressionQcTask + ;

#pragma link C++ class o2::quality_control_modules::glo::MeanVertexPostProcessing+;
#pragma link C++ class o2::quality_control_modules::glo::MeanVertexPostProcessing + ;
#endif
36 changes: 35 additions & 1 deletion Modules/GLO/include/GLO/MeanVertexPostProcessing.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,32 @@
#include "QualityControl/PostProcessingInterface.h"
#include "CCDB/CcdbApi.h"

class TH1F;
#include <TLine.h>
#include <TH1F.h>
#include <TGraph.h>
#include <TCanvas.h>

namespace o2::quality_control_modules::glo
{

class TrendGraph : public TCanvas
{
public:
TrendGraph(std::string name, std::string title, std::string label, float rangeMin, float rangeMax);

~TrendGraph() override {}

void update(uint64_t time, float val);

private:
float mRangeMin;
float mRangeMax;
std::string mAxisLabel;
std::unique_ptr<TGraph> mGraph;
std::unique_ptr<TGraph> mGraphHist;
std::array<std::unique_ptr<TLine>, 2> mLines;
};

/// \brief Postprocessing Task for Mean Vertex calibration

class MeanVertexPostProcessing final : public quality_control::postprocessing::PostProcessingInterface
Expand Down Expand Up @@ -62,6 +83,19 @@ class MeanVertexPostProcessing final : public quality_control::postprocessing::P
void finalize(quality_control::postprocessing::Trigger, framework::ServiceRegistryRef) override;

private:
float mRangeX{ 0.1 };
float mRangeY{ 0.1 };
float mRangeZ{ 1.0 };
float mRangeSigmaX{ 1.0 };
float mRangeSigmaY{ 1.0 };
float mRangeSigmaZ{ 10.0 };
bool mResetHistos{ false };
std::unique_ptr<TrendGraph> mGraphX;
std::unique_ptr<TrendGraph> mGraphY;
std::unique_ptr<TrendGraph> mGraphZ;
std::unique_ptr<TrendGraph> mGraphSigmaX;
std::unique_ptr<TrendGraph> mGraphSigmaY;
std::unique_ptr<TrendGraph> mGraphSigmaZ;
TH1F* mX = nullptr;
TH1F* mY = nullptr;
TH1F* mZ = nullptr;
Expand Down
144 changes: 139 additions & 5 deletions Modules/GLO/src/MeanVertexPostProcessing.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,76 @@
#include "GLO/MeanVertexPostProcessing.h"
#include "QualityControl/QcInfoLogger.h"

#include <TH1F.h>
#include <TMath.h>

using namespace o2::quality_control::postprocessing;

namespace o2::quality_control_modules::glo
{

TrendGraph::TrendGraph(std::string name, std::string title, std::string label, float rangeMin, float rangeMax)
: TCanvas(name.c_str(), title.c_str()),
mAxisLabel(label),
mRangeMin(rangeMin),
mRangeMax(rangeMax)
{
mGraphHist = std::make_unique<TGraph>(0);

mGraph = std::make_unique<TGraph>(0);
mGraph->SetMarkerStyle(kCircle);
mGraph->SetTitle(fmt::format("{};time;{}", title, label).c_str());
mLines[0] = std::make_unique<TLine>(0, mRangeMin, 1, mRangeMin);
mLines[1] = std::make_unique<TLine>(0, mRangeMax, 1, mRangeMax);
mLines[0]->SetLineStyle(kDashed);
mLines[1]->SetLineStyle(kDashed);
}

void TrendGraph::update(uint64_t time, float val)
{
mGraph->AddPoint(time, val);
mGraphHist->AddPoint(time, 0);

Clear();
cd();

// Draw underlying histogram and format axes
mGraphHist->Draw("A");
auto hAxis = mGraphHist->GetHistogram();
hAxis->SetTitle(GetTitle());
hAxis->GetYaxis()->SetTitle(mAxisLabel.c_str());
hAxis->GetXaxis()->SetTimeDisplay(1);
hAxis->GetXaxis()->SetNdivisions(505);
hAxis->GetXaxis()->SetTimeOffset(0.0);
hAxis->GetXaxis()->SetTimeFormat("%Y-%m-%d %H:%M");

// Adjust vertical axis range
Double_t min = mRangeMin;
Double_t max = mRangeMax;
min = TMath::Min(min, TMath::MinElement(mGraph->GetN(), mGraph->GetY()));
max = TMath::Max(max, TMath::MaxElement(mGraph->GetN(), mGraph->GetY()));
auto delta = max - min;
min -= 0.1 * delta;
max += 0.1 * delta;

// Update plot
hAxis->SetMinimum(min);
hAxis->SetMaximum(max);
hAxis->Draw("AXIS");

// Draw graph
mGraph->Draw("PL,SAME");

// Draw reference lines for acceptable ranges
mLines[0]->SetX1(hAxis->GetXaxis()->GetXmin());
mLines[1]->SetX1(hAxis->GetXaxis()->GetXmin());
mLines[0]->SetX2(hAxis->GetXaxis()->GetXmax());
mLines[1]->SetX2(hAxis->GetXaxis()->GetXmax());
mLines[0]->Draw();
mLines[1]->Draw();
}

//_________________________________________________________________________________________

MeanVertexPostProcessing::~MeanVertexPostProcessing()
{
delete mX;
Expand All @@ -43,6 +106,27 @@ void MeanVertexPostProcessing::configure(const boost::property_tree::ptree& conf
ILOG(Info, Support) << "MeanVertexCalib post-processing: getting customized CCDB url" << ENDM;
mCcdbUrl = customConfig.second.get<std::string>("CcdbURL");
}
if (const auto& customNames = customConfig.second.get_child_optional("RangeX"); customNames.has_value()) {
mRangeX = customConfig.second.get<float>("RangeX");
}
if (const auto& customNames = customConfig.second.get_child_optional("RangeY"); customNames.has_value()) {
mRangeY = customConfig.second.get<float>("RangeY");
}
if (const auto& customNames = customConfig.second.get_child_optional("RangeZ"); customNames.has_value()) {
mRangeZ = customConfig.second.get<float>("RangeZ");
}
if (const auto& customNames = customConfig.second.get_child_optional("RangeSigmaX"); customNames.has_value()) {
mRangeSigmaX = customConfig.second.get<float>("RangeSigmaX");
}
if (const auto& customNames = customConfig.second.get_child_optional("RangeSigmaY"); customNames.has_value()) {
mRangeSigmaY = customConfig.second.get<float>("RangeSigmaY");
}
if (const auto& customNames = customConfig.second.get_child_optional("RangeSigmaZ"); customNames.has_value()) {
mRangeSigmaZ = customConfig.second.get<float>("RangeSigmaZ");
}
if (const auto& customNames = customConfig.second.get_child_optional("ResetHistos"); customNames.has_value()) {
mResetHistos = customConfig.second.get<bool>("ResetHistos");
}
}
}
ILOG(Info, Support) << "MeanVertexCalib post-processing: CCDB url will be set to: " << mCcdbUrl << ENDM;
Expand All @@ -56,31 +140,74 @@ void MeanVertexPostProcessing::initialize(Trigger, framework::ServiceRegistryRef
mY = new TH1F("mMeanVtxY", "Mean Vertex Y", 20, -100, 100);
mZ = new TH1F("mMeanVtxZ", "Mean Vertex Z", 20, -100, 100);
const long currentTime = o2::ccdb::getCurrentTimestamp();
mStartValidity = new TH1F("mStartValidity", "Start Validity of Mean Vertex object", 600, currentTime - 1000, currentTime - 1000 + 60 * 1000 * 10 * 600); // 10 hours, with bins of 1 minutes
mStartValidity = new TH1F("mStartValidity", "Start Validity of Mean Vertex object", 600, currentTime - 1000 * 600, currentTime - 1000 + 60 * 1000 * 10 * 600); // 10 hours, with bins of 1 minutes, starting 10 minutes in the past
getObjectsManager()->startPublishing(mX);
getObjectsManager()->startPublishing(mY);
getObjectsManager()->startPublishing(mZ);
getObjectsManager()->startPublishing(mStartValidity);
mGraphX = std::make_unique<TrendGraph>("MeanVtxXTrending", "Mean Vertex X", "cm", -mRangeX, mRangeX);
mGraphY = std::make_unique<TrendGraph>("MeanVtxYTrending", "Mean Vertex Y", "cm", -mRangeY, mRangeY);
mGraphZ = std::make_unique<TrendGraph>("MeanVtxZTrending", "Mean Vertex Z", "cm", -mRangeZ, mRangeZ);

mGraphSigmaX = std::make_unique<TrendGraph>("MeanVtxSigmaXTrending", "Mean Vertex #sigma_{X}", "cm", 0, mRangeSigmaX);
mGraphSigmaY = std::make_unique<TrendGraph>("MeanVtxSigmaYTrending", "Mean Vertex #sigma_{Y}", "cm", 0, mRangeSigmaY);
mGraphSigmaZ = std::make_unique<TrendGraph>("MeanVtxSigmaZTrending", "Mean Vertex #sigma_{Z}", "cm", 0, mRangeSigmaZ);

getObjectsManager()->startPublishing(mGraphX.get());
getObjectsManager()->startPublishing(mGraphY.get());
getObjectsManager()->startPublishing(mGraphZ.get());

getObjectsManager()->startPublishing(mGraphSigmaX.get());
getObjectsManager()->startPublishing(mGraphSigmaY.get());
getObjectsManager()->startPublishing(mGraphSigmaZ.get());

ILOG(Info, Support) << "MeanVertexCalib post-processing: Initialization done";
}

void MeanVertexPostProcessing::update(Trigger t, framework::ServiceRegistryRef)
{
ILOG(Info, Support) << "Trigger type is: " << t.triggerType << ", the timestamp is " << t.timestamp << ENDM;
std::map<std::string, std::string> md, headers;
long currentTime = o2::ccdb::getCurrentTimestamp();
auto* meanVtx = mCcdbApi.retrieveFromTFileAny<o2::dataformats::MeanVertexObject>("GLO/Calib/MeanVertex", md, currentTime);
auto* meanVtx = mCcdbApi.retrieveFromTFileAny<o2::dataformats::MeanVertexObject>("GLO/Calib/MeanVertex", md, t.timestamp);
if (!meanVtx) {
ILOG(Info, Support) << "MeanVertexCalib post-processing: null object received for " << t.timestamp << ENDM;
return;
}

if (mResetHistos) {
mX->Reset();
mY->Reset();
mZ->Reset();
mStartValidity->Reset();
}

// get values
auto x = meanVtx->getX();
auto y = meanVtx->getY();
auto z = meanVtx->getZ();
headers = mCcdbApi.retrieveHeaders("GLO/Calib/MeanVertex", md, currentTime);
auto sx = meanVtx->getSigmaX();
auto sy = meanVtx->getSigmaY();
auto sz = meanVtx->getSigmaZ();

// get time stamp
headers = mCcdbApi.retrieveHeaders("GLO/Calib/MeanVertex", md, t.timestamp);
const auto validFrom = headers.find("Valid-From");
long startVal = std::stol(validFrom->second);
ILOG(Info, Support) << "MeanVertexCalib post-processing: startValidity = " << startVal << " X = " << x << " Y = " << y << " Z = " << z << ENDM;
mX->Fill(x);
mY->Fill(y);
mZ->Fill(z);
mStartValidity->Fill(startVal);

// ROOT expects time in seconds
startVal /= 1000;

mGraphX->update(startVal, x);
mGraphY->update(startVal, y);
mGraphZ->update(startVal, z);
mGraphSigmaX->update(startVal, sx);
mGraphSigmaY->update(startVal, sy);
mGraphSigmaZ->update(startVal, sz);
}

void MeanVertexPostProcessing::finalize(Trigger, framework::ServiceRegistryRef)
Expand All @@ -90,6 +217,13 @@ void MeanVertexPostProcessing::finalize(Trigger, framework::ServiceRegistryRef)
getObjectsManager()->stopPublishing(mY);
getObjectsManager()->stopPublishing(mZ);
getObjectsManager()->stopPublishing(mStartValidity);
getObjectsManager()->stopPublishing(mGraphX.get());
getObjectsManager()->stopPublishing(mGraphY.get());
getObjectsManager()->stopPublishing(mGraphZ.get());

getObjectsManager()->stopPublishing(mGraphSigmaX.get());
getObjectsManager()->stopPublishing(mGraphSigmaY.get());
getObjectsManager()->stopPublishing(mGraphSigmaZ.get());
}

} // namespace o2::quality_control_modules::glo

0 comments on commit cb71885

Please sign in to comment.