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 Framework/include/QualityControl/TrendingTask.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ class TrendingTask : public PostProcessingInterface
static void formatTimeXAxis(TH1* background);
static void formatRunNumberXAxis(TH1* background);
static std::string deduceGraphLegendOptions(const TrendingTaskConfig::Graph& graphConfig);
static void applyStyleToGraph(TGraph* graph, const TrendingTaskConfig::GraphStyle& style);

/// returns true only if all datasources were available to update reductor
bool trendValues(const Trigger& t, repository::DatabaseInterface&);
Expand Down
27 changes: 27 additions & 0 deletions Framework/include/QualityControl/TrendingTaskConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,25 @@ struct TrendingTaskConfig : PostProcessingConfig {
TrendingTaskConfig(std::string name, const boost::property_tree::ptree& config);
~TrendingTaskConfig() = default;

// graph style configuration
// colors as defined by ROOT TColor class:
// https://root.cern/doc/master/classTColor.html
// marker colors and styles are as defined by ROOT TAttMarker class
// https://root.cern/doc/master/classTAttMarker.html
// line styles are as defined by ROOT TAttLine class
// https://root.cern/doc/master/classTAttLine.html
// WARNING: Any parameters in this struct will override colliding parameters in option
struct GraphStyle {
int lineColor = -1;
int lineStyle = -1;
int lineWidth = -1;
int markerColor = -1;
int markerStyle = -1;
float markerSize = -1.f;
int fillColor = -1;
int fillStyle = -1;
};

// this corresponds to one TTree::Draw() call, i.e. one graph or histogram drawing
struct Graph {
std::string name;
Expand All @@ -40,6 +59,13 @@ struct TrendingTaskConfig : PostProcessingConfig {
std::string selection;
std::string option; // the list of possible options are documented in TGraphPainter and THistPainter
std::string errors;
GraphStyle style;
};

// legend configuration
struct LegendConfig {
int nColumns{ 1 };
float x1{ -1.f }, y1{ -1.f }, x2{ -1.f }, y2{ -1.f }; // NDC coords
};

// this corresponds to one canvas which can include multiple graphs
Expand All @@ -49,6 +75,7 @@ struct TrendingTaskConfig : PostProcessingConfig {
std::string graphAxisLabel;
std::string graphYRange;
int colorPalette = 0;
LegendConfig legend;
std::vector<Graph> graphs;
};

Expand Down
78 changes: 69 additions & 9 deletions Framework/src/TrendingTask.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,40 @@ void TrendingTask::initializeTrend(o2::quality_control::repository::DatabaseInte
}
}

void TrendingTask::applyStyleToGraph(TGraph* graph, const TrendingTaskConfig::GraphStyle& style)
{
if (!graph) {
return;
}

if (style.lineColor >= 0) {
graph->SetLineColor(style.lineColor);
}
if (style.lineStyle >= 0) {
graph->SetLineStyle(style.lineStyle);
}
if (style.lineWidth >= 0) {
graph->SetLineWidth(style.lineWidth);
}

if (style.markerColor >= 0) {
graph->SetMarkerColor(style.markerColor);
}
if (style.markerStyle >= 0) {
graph->SetMarkerStyle(style.markerStyle);
}
if (style.markerSize >= 0.f) {
graph->SetMarkerSize(style.markerSize);
}

if (style.fillColor >= 0) {
graph->SetFillColor(style.fillColor);
}
if (style.fillStyle >= 0) {
graph->SetFillStyle(style.fillStyle);
}
}

void TrendingTask::initialize(Trigger, framework::ServiceRegistryRef services)
{
// removing leftovers from any previous runs
Expand Down Expand Up @@ -310,19 +344,31 @@ std::string TrendingTask::deduceGraphLegendOptions(const TrendingTaskConfig::Gra
TCanvas* TrendingTask::drawPlot(const TrendingTaskConfig::Plot& plotConfig)
{
auto* c = new TCanvas();
auto* legend = new TLegend(0.3, 0.2);

// Legend
TLegend* legend = nullptr;
if (plotConfig.legend.x1 >= 0 && plotConfig.legend.y1 >= 0 && plotConfig.legend.x2 >= 0 && plotConfig.legend.y2 >= 0) {
legend = new TLegend(plotConfig.legend.x1, plotConfig.legend.y1,
plotConfig.legend.x2, plotConfig.legend.y2,
nullptr, "NDC");
if (plotConfig.legend.nColumns > 0) {
legend->SetNColumns(plotConfig.legend.nColumns);
}
} else {
legend = new TLegend(0.3, 0.2);
}
legend->SetBorderSize(0);
legend->SetFillStyle(0);
legend->SetTextSize(0.03);
legend->SetMargin(0.15);

// Keep palette behavior unless user forces explicit colors via per-graph style
if (plotConfig.colorPalette != 0) {
// this will work just once until we bump ROOT to a version which contains this commit:
// https://github.com/root-project/root/commit/0acdbd5be80494cec98ff60ba9a73cfe70a9a57a
// and enable the commented out line
// perhaps JSROOT >7.7.1 will allow us to retain the palette as well.
gStyle->SetPalette(plotConfig.colorPalette);
// This makes ROOT store the selected palette for each generated plot.
// TColor::DefinedColors(1); // TODO enable when available
} else {
// we set the default palette
gStyle->SetPalette();
gStyle->SetPalette(); // default
}

// regardless whether we draw a graph or a histogram, a histogram is always used by TTree::Draw to draw axes and title
Expand All @@ -337,6 +383,7 @@ TCanvas* TrendingTask::drawPlot(const TrendingTaskConfig::Plot& plotConfig)
// having "SAME" at the first TTree::Draw() call will not work, we have to add it only in subsequent Draw calls
std::string option = firstGraphInPlot ? graphConfig.option : "SAME " + graphConfig.option;

// Draw main series
mTrend->Draw(graphConfig.varexp.c_str(), graphConfig.selection.c_str(), option.c_str());

// For graphs, we allow to draw errors if they are specified.
Expand All @@ -357,11 +404,23 @@ TCanvas* TrendingTask::drawPlot(const TrendingTaskConfig::Plot& plotConfig)
}
}

// Legend entry and styling for graphs
if (auto graph = dynamic_cast<TGraph*>(c->FindObject("Graph"))) {
if (plotOrder >= 2) {
// Style objects after Draw so we override palette/auto styling when requested
applyStyleToGraph(graph, graphConfig.style);
// Keep errors visually consistent with the main series
if (graphErrors) {
applyStyleToGraph(graphErrors, graphConfig.style);
}
}
graph->SetName(graphConfig.name.c_str());
graph->SetTitle(graphConfig.title.c_str());
legend->AddEntry(graph, graphConfig.title.c_str(), deduceGraphLegendOptions(graphConfig).c_str());
legend->AddEntry(graph, graphConfig.title.c_str(),
deduceGraphLegendOptions(graphConfig).c_str());
}

// Legend entry and styling for histograms
if (auto htemp = dynamic_cast<TH1*>(c->FindObject("htemp"))) {
if (plotOrder == 1) {
htemp->SetName(graphConfig.name.c_str());
Expand All @@ -376,7 +435,7 @@ TCanvas* TrendingTask::drawPlot(const TrendingTaskConfig::Plot& plotConfig)
// so we have to do it here.
htemp->BufferEmpty();
// we keep the pointer to bg histogram for later postprocessing
if (background == nullptr) {
if (!background) {
background = htemp;
}
}
Expand Down Expand Up @@ -430,6 +489,7 @@ TCanvas* TrendingTask::drawPlot(const TrendingTaskConfig::Plot& plotConfig)
} else {
delete legend;
}

c->Modified();
c->Update();

Expand Down
31 changes: 30 additions & 1 deletion Framework/src/TrendingTaskConfig.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -36,26 +36,55 @@ TrendingTaskConfig::TrendingTaskConfig(std::string id, const boost::property_tre
for (const auto& [_, graphConfig] : graphsConfig.value()) {
// first we use name of the graph, if absent, we use graph title, if absent, we use plot (object) name.
const auto& name = graphConfig.get<std::string>("name", graphConfig.get<std::string>("title", plotConfig.get<std::string>("name")));
GraphStyle style;
style.lineColor = graphConfig.get<int>("style.lineColor", -1);
style.lineStyle = graphConfig.get<int>("style.lineStyle", -1);
style.lineWidth = graphConfig.get<int>("style.lineWidth", -1);
style.markerColor = graphConfig.get<int>("style.markerColor", -1);
style.markerStyle = graphConfig.get<int>("style.markerStyle", -1);
style.markerSize = graphConfig.get<float>("style.markerSize", -1.f);
style.fillColor = graphConfig.get<int>("style.fillColor", -1);
style.fillStyle = graphConfig.get<int>("style.fillStyle", -1);

graphs.push_back({ name,
graphConfig.get<std::string>("title", ""),
graphConfig.get<std::string>("varexp"),
graphConfig.get<std::string>("selection", ""),
graphConfig.get<std::string>("option", ""),
graphConfig.get<std::string>("graphErrors", "") });
graphConfig.get<std::string>("graphErrors", ""),
style });
}
} else {
GraphStyle style;
style.lineColor = plotConfig.get<int>("style.lineColor", -1);
style.lineStyle = plotConfig.get<int>("style.lineStyle", -1);
style.lineWidth = plotConfig.get<int>("style.lineWidth", -1);
style.markerColor = plotConfig.get<int>("style.markerColor", -1);
style.markerStyle = plotConfig.get<int>("style.markerStyle", -1);
style.markerSize = plotConfig.get<float>("style.markerSize", -1.f);
style.fillColor = plotConfig.get<int>("style.fillColor", -1);
style.fillStyle = plotConfig.get<int>("style.fillStyle", -1);
graphs.push_back({ plotConfig.get<std::string>("name", ""),
plotConfig.get<std::string>("title", ""),
plotConfig.get<std::string>("varexp"),
plotConfig.get<std::string>("selection", ""),
plotConfig.get<std::string>("option", ""),
plotConfig.get<std::string>("graphErrors", "") });
}

LegendConfig leg;
leg.nColumns = plotConfig.get<int>("legend.nColumns", 1);
leg.x1 = plotConfig.get<float>("legend.x1", -1.f);
leg.y1 = plotConfig.get<float>("legend.y1", -1.f);
leg.x2 = plotConfig.get<float>("legend.x2", -1.f);
leg.y2 = plotConfig.get<float>("legend.y2", -1.f);

plots.push_back({ plotConfig.get<std::string>("name"),
plotConfig.get<std::string>("title", ""),
plotConfig.get<std::string>("graphAxisLabel", ""),
plotConfig.get<std::string>("graphYRange", ""),
plotConfig.get<int>("colorPalette", 0),
leg,
graphs });
}

Expand Down
56 changes: 56 additions & 0 deletions Modules/FIT/FT0/etc/ft0-post-processing.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,33 @@
"url": ""
}
},
"tasks": {
"Digits": {
"active": "true",
"className": "o2::quality_control_modules::ft0::DigitQcTask",
"moduleName": "QcFT0",
"detectorName": "FT0",
"cycleDurationSeconds": "60",
"resetAfterCycles": "1",
"dataSource": {
"type": "direct",
"query": "digits:FT0/DIGITSBC/0;channels:FT0/DIGITSCH/0"
},
"taskParameters": {
"#ChannelIDs": "0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215",
"ChannelIDsAmpVsTime": "0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215",
"trgThresholdTimeLow": "-100",
"trgThresholdTimeHigh": "100",
"trgModeSide": "A+C",
"trgModeThresholdVar": "Ampl",
"trgThresholdSCenA": "20",
"trgThresholdCenA": "40",
"trgOrGate": "153",
"trgChargeLevelLow": "0",
"trgChargeLevelHigh": "4095"
}
}
},
"checks": {
"ASideInnerMIPCheck": {
"active": "true",
Expand Down Expand Up @@ -416,6 +443,7 @@
"className": "o2::quality_control::postprocessing::TrendingTask",
"moduleName": "QcFT0",
"detectorName": "FT0",
"resumeTrend": "true",
"dataSources": [
{
"type": "repository",
Expand All @@ -431,6 +459,34 @@
}
],
"plots": [
{
"name": "trend_cycle_duration_ntf_corr",
"title": "cycle duration: ns/TF;time;cycle duration [ns/TimeFrames]",
"legend": { "enabled": true, "x1": 0.70, "y1": 0.70, "x2": 0.93, "y2": 0.90, "nColumns": 1 },
"graphs": [
{
"title": "cycle duration [ns]",
"varexp": "CycleDuration.entries:time",
"selection": "",
"option": "*LP",
"style": { "lineColor": 38, "markerColor": 4, "markerStyle": 20, "lineWidth": 2 }
},
{
"title": "cycle duration [TimeFrames]",
"varexp": "CycleDurationNTF.entries:time",
"selection": "",
"option": "*LP",
"style": { "lineColor": 8, "markerColor": 3, "markerStyle": 30, "lineWidth": 2 }
},
{
"title": "cycle duration: ns/TF;time;cycle duration [ns/TimeFrames]",
"varexp": "CycleDuration.entries/CycleDurationNTF.entries:time",
"selection": "",
"option": "*LP",
"style": { "lineColor": 31, "markerColor": 30, "markerStyle": 23, "lineWidth": 2 }
}
]
},
{
"name": "trend_cycle_duration",
"title": "cycle duration [ns]",
Expand Down
Loading