Skip to content

Commit 3b3a577

Browse files
Benedikt Volkelchiarazampolli
authored andcommitted
Add labels to overlay plots, few adjustments
* by default, legends in overlay plots show "batch_i" and "batch_j" * with rel-val --labels label1 label2 these can be overwritten * bit of tidying up
1 parent 6806153 commit 3b3a577

2 files changed

Lines changed: 35 additions & 53 deletions

File tree

RelVal/ReleaseValidation.C

Lines changed: 27 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,6 @@
44
#include <vector>
55
#include <filesystem>
66

7-
TFile* fileSummaryOutput = nullptr;
8-
TFile* fileTestSummary = nullptr;
9-
10-
TString prefix = "";
11-
int correlationCase = 0; // at the moment I assume no error correlation ..
12-
137
struct TestResult {
148
double value = 0.0;
159
bool comparable = true;
@@ -42,8 +36,8 @@ int maxUserTests()
4236
// define a global epsilon
4337
double EPSILON = 0.00001;
4438

45-
void CompareHistos(TH1* hA, TH1* hB, int whichTests, bool firstComparison, bool finalComparison, std::unordered_map<std::string, std::vector<TestResult>>& allTests);
46-
void PlotOverlayAndRatio(TH1* hA, TH1* hB, TLegend& legend, TString& compLabel, int color);
39+
void CompareHistos(TH1* hA, TH1* hB, int whichTests, std::unordered_map<std::string, std::vector<TestResult>>& allTests, std::string const& labelA, std::string const& labelB);
40+
void PlotOverlayAndRatio(TH1* hA, TH1* hB, TLegend& legendMetrics, int color, std::string const& labelA, std::string const& labelB);
4741
bool PotentiallySameHistograms(TH1*, TH1*);
4842
TestResult CompareChiSquare(TH1* hA, TH1* hB, bool areComparable);
4943
TestResult CompareKolmogorov(TH1* hA, TH1* hB, bool areComparable);
@@ -84,7 +78,7 @@ int isEmptyHisto(TH1* h)
8478
}
8579

8680
// overlay 2 1D histograms
87-
void overlay1D(TH1* hA, TH1* hB, TLegend& legend, TString& compLabel, int color, std::string const& outputDir)
81+
void overlay1D(TH1* hA, TH1* hB, std::string const& labelA, std::string const& labelB, TLegend& legend, int color, std::string const& outputDir)
8882
{
8983
TCanvas c("overlay", "", 800, 800);
9084
c.cd();
@@ -100,14 +94,14 @@ void overlay1D(TH1* hA, TH1* hB, TLegend& legend, TString& compLabel, int color,
10094
TRatioPlot rp(hA, hB);
10195
rp.Draw("same");
10296
rp.GetUpperPad()->cd();
103-
TLatex toutc(0.2, 0.85, compLabel.Data());
104-
toutc.SetNDC();
105-
toutc.SetTextColor(color);
106-
toutc.SetTextFont(62);
107-
toutc.Draw();
10897
legend.Draw();
10998
rp.GetLowerRefGraph()->SetMinimum(0.);
11099
rp.GetLowerRefGraph()->SetMaximum(10.);
100+
TLegend legendOverlay(0.2, 0.6, 0.5, 0.8);
101+
legendOverlay.SetFillStyle(0);
102+
legendOverlay.AddEntry(hA, labelA.c_str());
103+
legendOverlay.AddEntry(hB, labelB.c_str());
104+
legendOverlay.Draw("same");
111105

112106
auto graph = rp.GetLowerRefGraph();
113107
auto xLow = hA->GetBinCenter(std::min(hA->FindFirstBinAbove(), hB->FindFirstBinAbove()));
@@ -127,8 +121,12 @@ void overlay1D(TH1* hA, TH1* hB, TLegend& legend, TString& compLabel, int color,
127121
}
128122

129123
// overlay 2 1D histograms
130-
void overlay2D(TH2* hA, TH2* hB, TLegend& legend, TString& compLabel, int color, std::string const& outputDir)
124+
void overlay2D(TH2* hA, TH2* hB, std::string const& labelA, std::string const& labelB, TLegend& legend, int color, std::string const& outputDir)
131125
{
126+
auto newTitleA = std::string(hA->GetTitle()) + "(" + labelA + ")";
127+
auto newTitleB = std::string(hB->GetTitle()) + "(" + labelB + ")";
128+
hA->SetTitle(newTitleA.c_str());
129+
hB->SetTitle(newTitleB.c_str());
132130
TCanvas c("overlay", "", 2400, 800);
133131
c.Divide(3, 1);
134132
c.cd(1);
@@ -141,11 +139,6 @@ void overlay2D(TH2* hA, TH2* hB, TLegend& legend, TString& compLabel, int color,
141139
hDiv->Divide(hB);
142140
c.cd(3);
143141
hDiv->Draw("colz");
144-
TLatex toutc(0.2, 0.85, compLabel.Data());
145-
toutc.SetNDC();
146-
toutc.SetTextColor(color);
147-
toutc.SetTextFont(62);
148-
toutc.Draw();
149142
legend.Draw();
150143

151144
auto savePath = outputDir + "/" + hA->GetName() + ".png";
@@ -154,7 +147,7 @@ void overlay2D(TH2* hA, TH2* hB, TLegend& legend, TString& compLabel, int color,
154147
}
155148

156149
// entry point for overlay plots
157-
void PlotOverlayAndRatio(TH1* hA, TH1* hB, TLegend& legend, TString& compLabel, int color)
150+
void PlotOverlayAndRatio(TH1* hA, TH1* hB, TLegend& legendMetrics, int color, std::string const& labelA, std::string const& labelB)
158151
{
159152
std::string outputDir("overlayPlots");
160153
if (!std::filesystem::exists(outputDir)) {
@@ -173,11 +166,11 @@ void PlotOverlayAndRatio(TH1* hA, TH1* hB, TLegend& legend, TString& compLabel,
173166
if (hA2D && hB2D) {
174167
// could be casted to 2D, so plot that
175168
// overlay2D(hA2D, hB2D, outputDir);
176-
overlay2D(hA2D, hB2D, legend, compLabel, color, outputDir);
169+
overlay2D(hA2D, hB2D, labelA, labelB, legendMetrics, color, outputDir);
177170
return;
178171
}
179172

180-
overlay1D(hA, hB, legend, compLabel, color, outputDir);
173+
overlay1D(hA, hB, labelA, labelB, legendMetrics, color, outputDir);
181174
}
182175

183176
// what to give as input:
@@ -188,7 +181,7 @@ void PlotOverlayAndRatio(TH1* hA, TH1* hB, TLegend& legend, TString& compLabel,
188181
// 6) select if files have to be taken from the grid or not
189182
// 7) choose if specific critic plots have to be saved in a second .pdf file
190183

191-
void ReleaseValidation(std::string const& filename1, std::string const& filename2, int whichTests)
184+
void ReleaseValidation(std::string const& filename1, std::string const& filename2, int whichTests, std::string const& labelA="batch_i", std::string const& labelB="batch_j")
192185
{
193186
gROOT->SetBatch();
194187

@@ -207,11 +200,6 @@ void ReleaseValidation(std::string const& filename1, std::string const& filename
207200
// collect test results to store them as JSON later
208201
std::unordered_map<std::string, std::vector<TestResult>> allTestsMap;
209202

210-
// open the two files (just created), look at the histograms and make statistical tests
211-
bool isLastComparison = false; // It is true only when the last histogram of the file is considered,
212-
// in order to properly close the pdf
213-
bool isFirstComparison = true; // to properly open the pdf file
214-
215203
TIter next(extractedFile1.GetListOfKeys());
216204
TKey* key{};
217205
int nSimilarHistos{};
@@ -225,9 +213,6 @@ void ReleaseValidation(std::string const& filename1, std::string const& filename
225213
auto oname = key->GetName();
226214
auto hB = static_cast<TH1*>(extractedFile2.Get(oname));
227215

228-
if (nComparisons + nNotFound == nkeys - 1)
229-
isLastComparison = true;
230-
231216
if (!hB) {
232217
// That could still happen in case we compare either comletely different file by accident or something has been changed/added/removed
233218
std::cerr << "ERROR: Histogram " << oname << " not found in second batch continue with next\n";
@@ -242,11 +227,9 @@ void ReleaseValidation(std::string const& filename1, std::string const& filename
242227

243228
std::cout << "Comparing " << hA->GetName() << " and " << hB->GetName() << "\n";
244229

245-
CompareHistos(hA, hB, whichTests, isFirstComparison, isLastComparison, allTestsMap);
230+
CompareHistos(hA, hB, whichTests, allTestsMap, labelA, labelB);
246231

247232
nComparisons++;
248-
if (nComparisons == 1)
249-
isFirstComparison = false;
250233
}
251234
std::cout << "\n##### Summary #####\nNumber of histograms compared: " << nComparisons
252235
<< "\nNumber of potentially same histograms: " << nSimilarHistos << "\n";
@@ -375,13 +358,12 @@ void RegisterTestResult(std::unordered_map<std::string, std::vector<TestResult>>
375358
allTests[histogramName].push_back(testResult);
376359
}
377360

378-
void CompareHistos(TH1* hA, TH1* hB, int whichTests, bool firstComparison, bool finalComparison, std::unordered_map<std::string, std::vector<TestResult>>& allTests)
361+
void CompareHistos(TH1* hA, TH1* hB, int whichTests, std::unordered_map<std::string, std::vector<TestResult>>& allTests, std::string const& labelA, std::string const& labelB)
379362
{
380363

381364
double integralA = hA->Integral();
382365
double integralB = hB->Integral();
383366

384-
TString outc = "";
385367
int colt = 1;
386368

387369
// Bit Mask
@@ -390,8 +372,9 @@ void CompareHistos(TH1* hA, TH1* hB, int whichTests, bool firstComparison, bool
390372

391373
auto areComparable = CheckComparable(hA, hB);
392374

393-
TLegend legendOverlayPlot(0.6, 0.6, 0.9, 0.8);
394-
legendOverlayPlot.SetBorderSize(1);
375+
TLegend legendMetricsOverlayPlot(0.6, 0.6, 0.9, 0.8);
376+
legendMetricsOverlayPlot.SetBorderSize(1);
377+
legendMetricsOverlayPlot.SetFillStyle(0);
395378

396379
// test if each of the 3 bits is turned on in subset ‘i = whichTests’?
397380
// if yes, process the bit
@@ -400,31 +383,31 @@ void CompareHistos(TH1* hA, TH1* hB, int whichTests, bool firstComparison, bool
400383
auto testResult = CompareChiSquare(hA, hB, areComparable);
401384
RegisterTestResult(allTests, hA->GetName(), testResult);
402385
if (testResult.comparable) {
403-
legendOverlayPlot.AddEntry((TObject*)nullptr, Form("#chi^{2} / N_{bins} = %f", testResult.value), "");
386+
legendMetricsOverlayPlot.AddEntry((TObject*)nullptr, Form("#chi^{2} / N_{bins} = %f", testResult.value), "");
404387
}
405388
}
406389

407390
if (shouldRunTest(whichTests, TestFlag::KOLMOGOROV)) {
408391
auto testResult = CompareKolmogorov(hA, hB, areComparable);
409392
RegisterTestResult(allTests, hA->GetName(), testResult);
410393
if (testResult.comparable) {
411-
legendOverlayPlot.AddEntry((TObject*)nullptr, Form("Kolmogorov prob. = %f", testResult.value), "");
394+
legendMetricsOverlayPlot.AddEntry((TObject*)nullptr, Form("Kolmogorov prob. = %f", testResult.value), "");
412395
}
413396
}
414397

415398
if (shouldRunTest(whichTests, TestFlag::NENTRIES)) {
416399
auto testResult = CompareNentr(hA, hB, areComparable);
417400
RegisterTestResult(allTests, hA->GetName(), testResult);
418401
if (testResult.comparable) {
419-
legendOverlayPlot.AddEntry((TObject*)nullptr, Form("entriesdiff = %f", testResult.value), "");
402+
legendMetricsOverlayPlot.AddEntry((TObject*)nullptr, Form("entriesdiff = %f", testResult.value), "");
420403
}
421404
}
422405

423406
if (isEmptyHisto(hA) == 2 || isEmptyHisto(hB) == 2) {
424407
std::cerr << "WARNING: Cannot draw histograms due to the fact that all entries are in under- or overflow bins\n";
425408
return;
426409
}
427-
PlotOverlayAndRatio(hA, hB, legendOverlayPlot, outc, colt);
410+
PlotOverlayAndRatio(hA, hB, legendMetricsOverlayPlot, colt, labelA, labelB);
428411
}
429412

430413
// chi2
@@ -481,7 +464,7 @@ TestResult CompareNentr(TH1* hA, TH1* hB, bool areComparable)
481464
double entriesdiff = TMath::Abs(integralA - integralB) / error;
482465
*/
483466
res.value = entriesdiff;
484-
467+
485468
return res;
486469
}
487470

RelVal/o2dpg_release_validation.py

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -416,7 +416,7 @@ def plot_compare_summaries(summaries, fields, out_dir, *, labels=None, include_p
416416
ax.set_xticks(range(len(histogram_names_intersection)))
417417
ax.set_xticklabels(histogram_names_intersection, rotation=90)
418418
ax.tick_params("both", labelsize=20)
419-
save_path = join(out_dir, f"plot_{test_name}_{'_'.join(labels)}.png")
419+
save_path = join(out_dir, f"values_thresholds_{test_name}.png")
420420
figure.tight_layout()
421421
figure.savefig(save_path)
422422
plt.close(figure)
@@ -659,7 +659,7 @@ def run_macro(cmd, log_file):
659659
cmd = f"root -l -b -q {ROOT_MACRO_EXTRACT}{cmd}"
660660
run_macro(cmd, log_file_extract)
661661

662-
cmd = f"\\(\\\"{file_1}\\\",\\\"{file_2}\\\",{args.test}\\)"
662+
cmd = f"\\(\\\"{file_1}\\\",\\\"{file_2}\\\",{args.test},\\\"{args.labels[0]}\\\",\\\"{args.labels[1]}\\\"\\)"
663663
cmd = f"root -l -b -q {ROOT_MACRO_RELVAL}{cmd}"
664664
print("Running RelVal on extracted objects")
665665
run_macro(cmd, log_file_rel_val)
@@ -737,7 +737,6 @@ def make_global_summary(in_dir):
737737
type_specific = relpath(rel_val_path, in_dir)
738738
rel_path_plot = join(type_specific, "overlayPlots")
739739
type_global = type_specific.split("/")[0]
740-
make_summary = {}
741740
for histo_name, tests in current_summary.items():
742741
summary[histo_name] = tests
743742
# loop over tests done
@@ -807,7 +806,7 @@ def rel_val(args):
807806
makedirs(args.output)
808807
if isdir(args.input1[0]) and isdir(args.input2[0]):
809808
if len(args.input1) > 1 or len(args.input2) > 1:
810-
print("ERROR: When you want to validate the contents of directories, you can only compare excatly one directory to exactly on other directory.")
809+
print("ERROR: When you want to validate the contents of directories, you can only compare exactly one directory to exactly on other directory.")
811810
return 1
812811
if not args.dir_config:
813812
print("ERROR: RelVal to be run on 2 directories. Please provide a configuration what to validate.")
@@ -1056,16 +1055,17 @@ def main():
10561055
common_file_parser = argparse.ArgumentParser(add_help=False)
10571056
common_file_parser.add_argument("-i", "--input1", nargs="*", help="EITHER first set of input files for comparison OR first input directory from simulation for comparison", required=True)
10581057
common_file_parser.add_argument("-j", "--input2", nargs="*", help="EITHER second set of input files for comparison OR second input directory from simulation for comparison", required=True)
1058+
common_file_parser.add_argument("--labels", nargs=2, help="labels you want to appear in the plot legends in case of overlay plots from batches -i and -j", default=("batch_i", "batch_j"))
10591059

10601060
common_threshold_parser = argparse.ArgumentParser(add_help=False)
10611061
common_threshold_parser.add_argument("--use-values-as-thresholds", nargs="*", dest="use_values_as_thresholds", help="Use values from another run as thresholds for this one")
10621062
common_threshold_parser.add_argument("--combine-thresholds", dest="combine_thresholds", choices=["mean", "max/min"], help="Arithmetic mean or maximum/minimum is chosen as threshold value", default="mean")
10631063
for test, thresh in zip(REL_VAL_TEST_NAMES, REL_VAL_TEST_DEFAULT_THRESHOLDS):
1064-
test_dahsed = test.replace("_", "-")
1065-
common_threshold_parser.add_argument(f"--with-test-{test_dahsed}", dest=f"with_{test}", action="store_true", help=f"run {test} test")
1066-
common_threshold_parser.add_argument(f"--test-{test_dahsed}-threshold", dest=f"{test}_threshold", type=float, help=f"{test} threshold", default=thresh)
1064+
test_dashed = test.replace("_", "-")
1065+
common_threshold_parser.add_argument(f"--with-test-{test_dashed}", dest=f"with_{test}", action="store_true", help=f"run {test} test")
1066+
common_threshold_parser.add_argument(f"--test-{test_dashed}-threshold", dest=f"{test}_threshold", type=float, help=f"{test} threshold", default=thresh)
10671067
# The following only take effect for thresholds given via an input file
1068-
common_threshold_parser.add_argument(f"--test-{test_dahsed}-threshold-margin", dest=f"{test}_threshold_margin", type=float, help=f"Margin to apply to the {test} threshold extracted from file", default=1.0)
1068+
common_threshold_parser.add_argument(f"--test-{test_dashed}-threshold-margin", dest=f"{test}_threshold_margin", type=float, help=f"Margin to apply to the {test} threshold extracted from file", default=1.0)
10691069

10701070
common_pattern_parser = argparse.ArgumentParser(add_help=False)
10711071
common_pattern_parser.add_argument("--include-patterns", dest="include_patterns", nargs="*", help="include objects whose name includes at least one of the given patterns (takes precedence)")
@@ -1093,7 +1093,6 @@ def main():
10931093
inspect_parser.set_defaults(func=inspect)
10941094

10951095
compare_parser = sub_parsers.add_parser("compare", parents=[common_file_parser, common_pattern_parser])
1096-
compare_parser.add_argument("--labels", nargs=2, help="labels you want to appear in the plot legend (if --plot is given) of the value-threshold comparison plot", default=("rel_val_1", "rel_val_2"))
10971096
compare_parser.add_argument("--output", "-o", help="output directory", default="rel_val_comparison")
10981097
compare_parser.add_argument("--difference", action="store_true", help="plot histograms with different severity")
10991098
compare_parser.add_argument("--compare-values", action="store_true", help="plot value and threshold comparisons of RelVals")

0 commit comments

Comments
 (0)