Skip to content

Commit cb71885

Browse files
authored
GLO: add trending to MeanVertex post-processing (#1864)
* [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.
1 parent 42981ae commit cb71885

3 files changed

Lines changed: 175 additions & 7 deletions

File tree

Modules/GLO/include/GLO/LinkDef.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@
77
#pragma link C++ class o2::quality_control_modules::glo::ITSTPCMatchingTask + ;
88
#pragma link C++ class o2::quality_control_modules::glo::DataCompressionQcTask + ;
99

10-
#pragma link C++ class o2::quality_control_modules::glo::MeanVertexPostProcessing+;
10+
#pragma link C++ class o2::quality_control_modules::glo::MeanVertexPostProcessing + ;
1111
#endif

Modules/GLO/include/GLO/MeanVertexPostProcessing.h

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,32 @@
2020
#include "QualityControl/PostProcessingInterface.h"
2121
#include "CCDB/CcdbApi.h"
2222

23-
class TH1F;
23+
#include <TLine.h>
24+
#include <TH1F.h>
25+
#include <TGraph.h>
26+
#include <TCanvas.h>
2427

2528
namespace o2::quality_control_modules::glo
2629
{
2730

31+
class TrendGraph : public TCanvas
32+
{
33+
public:
34+
TrendGraph(std::string name, std::string title, std::string label, float rangeMin, float rangeMax);
35+
36+
~TrendGraph() override {}
37+
38+
void update(uint64_t time, float val);
39+
40+
private:
41+
float mRangeMin;
42+
float mRangeMax;
43+
std::string mAxisLabel;
44+
std::unique_ptr<TGraph> mGraph;
45+
std::unique_ptr<TGraph> mGraphHist;
46+
std::array<std::unique_ptr<TLine>, 2> mLines;
47+
};
48+
2849
/// \brief Postprocessing Task for Mean Vertex calibration
2950

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

6485
private:
86+
float mRangeX{ 0.1 };
87+
float mRangeY{ 0.1 };
88+
float mRangeZ{ 1.0 };
89+
float mRangeSigmaX{ 1.0 };
90+
float mRangeSigmaY{ 1.0 };
91+
float mRangeSigmaZ{ 10.0 };
92+
bool mResetHistos{ false };
93+
std::unique_ptr<TrendGraph> mGraphX;
94+
std::unique_ptr<TrendGraph> mGraphY;
95+
std::unique_ptr<TrendGraph> mGraphZ;
96+
std::unique_ptr<TrendGraph> mGraphSigmaX;
97+
std::unique_ptr<TrendGraph> mGraphSigmaY;
98+
std::unique_ptr<TrendGraph> mGraphSigmaZ;
6599
TH1F* mX = nullptr;
66100
TH1F* mY = nullptr;
67101
TH1F* mZ = nullptr;

Modules/GLO/src/MeanVertexPostProcessing.cxx

Lines changed: 139 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,76 @@
2020
#include "GLO/MeanVertexPostProcessing.h"
2121
#include "QualityControl/QcInfoLogger.h"
2222

23-
#include <TH1F.h>
23+
#include <TMath.h>
2424

2525
using namespace o2::quality_control::postprocessing;
2626

2727
namespace o2::quality_control_modules::glo
2828
{
2929

30+
TrendGraph::TrendGraph(std::string name, std::string title, std::string label, float rangeMin, float rangeMax)
31+
: TCanvas(name.c_str(), title.c_str()),
32+
mAxisLabel(label),
33+
mRangeMin(rangeMin),
34+
mRangeMax(rangeMax)
35+
{
36+
mGraphHist = std::make_unique<TGraph>(0);
37+
38+
mGraph = std::make_unique<TGraph>(0);
39+
mGraph->SetMarkerStyle(kCircle);
40+
mGraph->SetTitle(fmt::format("{};time;{}", title, label).c_str());
41+
mLines[0] = std::make_unique<TLine>(0, mRangeMin, 1, mRangeMin);
42+
mLines[1] = std::make_unique<TLine>(0, mRangeMax, 1, mRangeMax);
43+
mLines[0]->SetLineStyle(kDashed);
44+
mLines[1]->SetLineStyle(kDashed);
45+
}
46+
47+
void TrendGraph::update(uint64_t time, float val)
48+
{
49+
mGraph->AddPoint(time, val);
50+
mGraphHist->AddPoint(time, 0);
51+
52+
Clear();
53+
cd();
54+
55+
// Draw underlying histogram and format axes
56+
mGraphHist->Draw("A");
57+
auto hAxis = mGraphHist->GetHistogram();
58+
hAxis->SetTitle(GetTitle());
59+
hAxis->GetYaxis()->SetTitle(mAxisLabel.c_str());
60+
hAxis->GetXaxis()->SetTimeDisplay(1);
61+
hAxis->GetXaxis()->SetNdivisions(505);
62+
hAxis->GetXaxis()->SetTimeOffset(0.0);
63+
hAxis->GetXaxis()->SetTimeFormat("%Y-%m-%d %H:%M");
64+
65+
// Adjust vertical axis range
66+
Double_t min = mRangeMin;
67+
Double_t max = mRangeMax;
68+
min = TMath::Min(min, TMath::MinElement(mGraph->GetN(), mGraph->GetY()));
69+
max = TMath::Max(max, TMath::MaxElement(mGraph->GetN(), mGraph->GetY()));
70+
auto delta = max - min;
71+
min -= 0.1 * delta;
72+
max += 0.1 * delta;
73+
74+
// Update plot
75+
hAxis->SetMinimum(min);
76+
hAxis->SetMaximum(max);
77+
hAxis->Draw("AXIS");
78+
79+
// Draw graph
80+
mGraph->Draw("PL,SAME");
81+
82+
// Draw reference lines for acceptable ranges
83+
mLines[0]->SetX1(hAxis->GetXaxis()->GetXmin());
84+
mLines[1]->SetX1(hAxis->GetXaxis()->GetXmin());
85+
mLines[0]->SetX2(hAxis->GetXaxis()->GetXmax());
86+
mLines[1]->SetX2(hAxis->GetXaxis()->GetXmax());
87+
mLines[0]->Draw();
88+
mLines[1]->Draw();
89+
}
90+
91+
//_________________________________________________________________________________________
92+
3093
MeanVertexPostProcessing::~MeanVertexPostProcessing()
3194
{
3295
delete mX;
@@ -43,6 +106,27 @@ void MeanVertexPostProcessing::configure(const boost::property_tree::ptree& conf
43106
ILOG(Info, Support) << "MeanVertexCalib post-processing: getting customized CCDB url" << ENDM;
44107
mCcdbUrl = customConfig.second.get<std::string>("CcdbURL");
45108
}
109+
if (const auto& customNames = customConfig.second.get_child_optional("RangeX"); customNames.has_value()) {
110+
mRangeX = customConfig.second.get<float>("RangeX");
111+
}
112+
if (const auto& customNames = customConfig.second.get_child_optional("RangeY"); customNames.has_value()) {
113+
mRangeY = customConfig.second.get<float>("RangeY");
114+
}
115+
if (const auto& customNames = customConfig.second.get_child_optional("RangeZ"); customNames.has_value()) {
116+
mRangeZ = customConfig.second.get<float>("RangeZ");
117+
}
118+
if (const auto& customNames = customConfig.second.get_child_optional("RangeSigmaX"); customNames.has_value()) {
119+
mRangeSigmaX = customConfig.second.get<float>("RangeSigmaX");
120+
}
121+
if (const auto& customNames = customConfig.second.get_child_optional("RangeSigmaY"); customNames.has_value()) {
122+
mRangeSigmaY = customConfig.second.get<float>("RangeSigmaY");
123+
}
124+
if (const auto& customNames = customConfig.second.get_child_optional("RangeSigmaZ"); customNames.has_value()) {
125+
mRangeSigmaZ = customConfig.second.get<float>("RangeSigmaZ");
126+
}
127+
if (const auto& customNames = customConfig.second.get_child_optional("ResetHistos"); customNames.has_value()) {
128+
mResetHistos = customConfig.second.get<bool>("ResetHistos");
129+
}
46130
}
47131
}
48132
ILOG(Info, Support) << "MeanVertexCalib post-processing: CCDB url will be set to: " << mCcdbUrl << ENDM;
@@ -56,31 +140,74 @@ void MeanVertexPostProcessing::initialize(Trigger, framework::ServiceRegistryRef
56140
mY = new TH1F("mMeanVtxY", "Mean Vertex Y", 20, -100, 100);
57141
mZ = new TH1F("mMeanVtxZ", "Mean Vertex Z", 20, -100, 100);
58142
const long currentTime = o2::ccdb::getCurrentTimestamp();
59-
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
143+
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
60144
getObjectsManager()->startPublishing(mX);
61145
getObjectsManager()->startPublishing(mY);
62146
getObjectsManager()->startPublishing(mZ);
63147
getObjectsManager()->startPublishing(mStartValidity);
148+
mGraphX = std::make_unique<TrendGraph>("MeanVtxXTrending", "Mean Vertex X", "cm", -mRangeX, mRangeX);
149+
mGraphY = std::make_unique<TrendGraph>("MeanVtxYTrending", "Mean Vertex Y", "cm", -mRangeY, mRangeY);
150+
mGraphZ = std::make_unique<TrendGraph>("MeanVtxZTrending", "Mean Vertex Z", "cm", -mRangeZ, mRangeZ);
151+
152+
mGraphSigmaX = std::make_unique<TrendGraph>("MeanVtxSigmaXTrending", "Mean Vertex #sigma_{X}", "cm", 0, mRangeSigmaX);
153+
mGraphSigmaY = std::make_unique<TrendGraph>("MeanVtxSigmaYTrending", "Mean Vertex #sigma_{Y}", "cm", 0, mRangeSigmaY);
154+
mGraphSigmaZ = std::make_unique<TrendGraph>("MeanVtxSigmaZTrending", "Mean Vertex #sigma_{Z}", "cm", 0, mRangeSigmaZ);
155+
156+
getObjectsManager()->startPublishing(mGraphX.get());
157+
getObjectsManager()->startPublishing(mGraphY.get());
158+
getObjectsManager()->startPublishing(mGraphZ.get());
159+
160+
getObjectsManager()->startPublishing(mGraphSigmaX.get());
161+
getObjectsManager()->startPublishing(mGraphSigmaY.get());
162+
getObjectsManager()->startPublishing(mGraphSigmaZ.get());
163+
64164
ILOG(Info, Support) << "MeanVertexCalib post-processing: Initialization done";
65165
}
66166

67167
void MeanVertexPostProcessing::update(Trigger t, framework::ServiceRegistryRef)
68168
{
69169
ILOG(Info, Support) << "Trigger type is: " << t.triggerType << ", the timestamp is " << t.timestamp << ENDM;
70170
std::map<std::string, std::string> md, headers;
71-
long currentTime = o2::ccdb::getCurrentTimestamp();
72-
auto* meanVtx = mCcdbApi.retrieveFromTFileAny<o2::dataformats::MeanVertexObject>("GLO/Calib/MeanVertex", md, currentTime);
171+
auto* meanVtx = mCcdbApi.retrieveFromTFileAny<o2::dataformats::MeanVertexObject>("GLO/Calib/MeanVertex", md, t.timestamp);
172+
if (!meanVtx) {
173+
ILOG(Info, Support) << "MeanVertexCalib post-processing: null object received for " << t.timestamp << ENDM;
174+
return;
175+
}
176+
177+
if (mResetHistos) {
178+
mX->Reset();
179+
mY->Reset();
180+
mZ->Reset();
181+
mStartValidity->Reset();
182+
}
183+
184+
// get values
73185
auto x = meanVtx->getX();
74186
auto y = meanVtx->getY();
75187
auto z = meanVtx->getZ();
76-
headers = mCcdbApi.retrieveHeaders("GLO/Calib/MeanVertex", md, currentTime);
188+
auto sx = meanVtx->getSigmaX();
189+
auto sy = meanVtx->getSigmaY();
190+
auto sz = meanVtx->getSigmaZ();
191+
192+
// get time stamp
193+
headers = mCcdbApi.retrieveHeaders("GLO/Calib/MeanVertex", md, t.timestamp);
77194
const auto validFrom = headers.find("Valid-From");
78195
long startVal = std::stol(validFrom->second);
79196
ILOG(Info, Support) << "MeanVertexCalib post-processing: startValidity = " << startVal << " X = " << x << " Y = " << y << " Z = " << z << ENDM;
80197
mX->Fill(x);
81198
mY->Fill(y);
82199
mZ->Fill(z);
83200
mStartValidity->Fill(startVal);
201+
202+
// ROOT expects time in seconds
203+
startVal /= 1000;
204+
205+
mGraphX->update(startVal, x);
206+
mGraphY->update(startVal, y);
207+
mGraphZ->update(startVal, z);
208+
mGraphSigmaX->update(startVal, sx);
209+
mGraphSigmaY->update(startVal, sy);
210+
mGraphSigmaZ->update(startVal, sz);
84211
}
85212

86213
void MeanVertexPostProcessing::finalize(Trigger, framework::ServiceRegistryRef)
@@ -90,6 +217,13 @@ void MeanVertexPostProcessing::finalize(Trigger, framework::ServiceRegistryRef)
90217
getObjectsManager()->stopPublishing(mY);
91218
getObjectsManager()->stopPublishing(mZ);
92219
getObjectsManager()->stopPublishing(mStartValidity);
220+
getObjectsManager()->stopPublishing(mGraphX.get());
221+
getObjectsManager()->stopPublishing(mGraphY.get());
222+
getObjectsManager()->stopPublishing(mGraphZ.get());
223+
224+
getObjectsManager()->stopPublishing(mGraphSigmaX.get());
225+
getObjectsManager()->stopPublishing(mGraphSigmaY.get());
226+
getObjectsManager()->stopPublishing(mGraphSigmaZ.get());
93227
}
94228

95229
} // namespace o2::quality_control_modules::glo

0 commit comments

Comments
 (0)