43 auto* pNumerator =
static_cast<const TH1*
>(
fvpObjects[iVersion]);
44 auto* pDenominator =
static_cast<const TH1*
>(
fvpObjects[
fpObjDB->GetDefaultID()]);
45 if (pNumerator->GetNbinsX() != pDenominator->GetNbinsX() || pNumerator->GetNbinsY() != pDenominator->GetNbinsY()
46 || pNumerator->GetNbinsZ() != pDenominator->GetNbinsZ()) {
54 bool bEqualExactly{
true};
55 bool bEqualByRatio{
true};
60 if (bCompareExact || bCompareRatio) {
61 bool bRatioMayBeWrong =
63 for (
int iBinX{0}; iBinX <= pNumerator->GetNbinsX(); ++iBinX) {
64 for (
int iBinY{0}; iBinY <= pNumerator->GetNbinsY(); ++iBinY) {
65 for (
int iBinZ{0}; iBinZ <= pNumerator->GetNbinsZ(); ++iBinZ) {
66 auto numBinContent{pNumerator->GetBinContent(iBinX, iBinY, iBinZ)};
67 auto denBinContent{pDenominator->GetBinContent(iBinX, iBinY, iBinZ)};
68 double ratio{
static_cast<double>(numBinContent) / denBinContent};
70 if (!TMath::IsNaN(numBinContent) && !TMath::IsNaN(denBinContent)) {
71 if (numBinContent != denBinContent) {
72 bEqualExactly =
false;
74 bool numEmpty{numBinContent < 1.e-4};
75 bool denEmpty{denBinContent < 1.e-4};
76 if (numEmpty || denEmpty) {
77 bRatioMayBeWrong &= (!numEmpty || !denEmpty);
80 ratioLo = std::min(ratioLo, ratio);
81 ratioUp = std::max(ratioUp, ratio);
86 if (TMath::IsNaN(numBinContent) != TMath::IsNaN(denBinContent)) {
87 bEqualExactly =
false;
90 auto numBinError{pNumerator->GetBinError(iBinX, iBinY, iBinZ)};
91 auto denBinError{pDenominator->GetBinError(iBinX, iBinY, iBinZ)};
93 if (!TMath::IsNaN(numBinError) && !TMath::IsNaN(denBinError)) {
94 if (numBinError != denBinError) {
95 bEqualExactly =
false;
99 if (TMath::IsNaN(numBinError) != TMath::IsNaN(denBinError)) {
100 bEqualExactly =
false;
107 if (bCompareExact && bEqualExactly) {
111 if (bRatioMayBeWrong && (std::fabs(1 - 1.e-4) < ratioLo) && std::fabs(1 + 1.e+4) > ratioUp) {
113 <<
", object: " << pNumerator->GetName()
114 <<
" has a ratio equal to 1., but some of bins are still different "
115 <<
"(empty/non-empty bin case)";
119 bEqualByRatio = (ratioLo >=
fpObjDB->GetRatioRangeMin() && ratioUp <= fpObjDB->GetRatioRangeMax());
123 bool bEqualByChi2{
true};
126 auto currErrorLevel{gErrorIgnoreLevel};
127 gErrorIgnoreLevel = kFatal;
131 pVal = pDenominator->Chi2TestX(pNumerator, chi2, ndf, igood);
132 bEqualByChi2 = (pVal >=
fpObjDB->GetPvalThreshold());
133 gErrorIgnoreLevel = currErrorLevel;
139 bEqualExactly = !bCompareExact || bEqualExactly;
140 bEqualByRatio = !bCompareRatio || bEqualByRatio;
141 bEqualByChi2 = !bCompareChi2 || bEqualByChi2;
142 bool bEqualStrongly = bEqualExactly && bEqualByRatio && bEqualByChi2;
143 bool bEqualWeakly = bEqualExactly || bEqualByRatio || bEqualByChi2;
148 auto ResultMsg = [](
bool flag) -> std::string {
149 constexpr const char* kEqual =
"\e[1;32mconsistent\e[0m";
150 constexpr const char* kDiff =
"\e[1;31minconsistent\e[0m";
151 return flag ? kEqual : kDiff;
153 std::stringstream msg;
157 msg <<
"\texact -> " << ResultMsg(bEqualExactly) <<
'\n';
160 msg <<
"\tratio -> " << ResultMsg(bEqualByRatio) <<
"(lo: " << ratioLo <<
", up: " << ratioUp <<
")\n";
163 msg <<
"\tchi2 -> " << ResultMsg(bEqualByChi2) <<
"(p-val: " << pVal <<
")\n";
165 msg <<
"Inference: " <<
ToString(res);
167 LOG(info) << msg.str();
177 int nVersions =
fpObjDB->GetNofVersions();
178 int iDef =
fpObjDB->GetDefaultID();
181 std::string sOption = opt;
182 for (
auto& ch : sOption) {
183 ch = std::tolower(ch);
185 bool bDrawRatio = sOption.find(
"r") != std::string::npos;
186 bool bDrawDiff = sOption.find(
"d") != std::string::npos;
187 int nPads =
static_cast<int>(bDrawRatio) +
static_cast<int>(bDrawDiff) + 1;
190 std::string sCanvName =
fsBaseName +
"_cmp_canvas";
191 std::string sCanvTitle =
"Comparison result for \"" +
fsBaseName +
"\"";
192 fpCanvas = std::make_shared<TCanvas>(sCanvName.data(), sCanvTitle.data(), 500 * nPads, 500);
195 TPad* pPadOrig =
nullptr;
196 TPad* pPadRatio =
nullptr;
197 TPad* pPadDiff =
nullptr;
199 double xPadSize = 1.0 / nPads;
202 pPadOrig =
new TPad(
"p1",
"p1", 0.0, 0.0, xPadSize, 1.0);
203 pPadOrig->SetMargin(0.20, 0.05, 0.20, 0.10);
208 pPadRatio =
new TPad(
"p2",
"p2", xNext, 0.0, xNext + xPadSize, 1.0);
209 pPadRatio->SetMargin(0.20, 0.05, 0.20, 0.10);
215 pPadDiff =
new TPad(
"p3",
"p3", xNext, 0.0, xNext + xPadSize, 1.0);
216 pPadDiff->SetMargin(0.20, 0.05, 0.20, 0.10);
222 const char* title =
fvpObjects[0]->GetTitle();
223 const char* titleRatio = Form(
"Ratio to %s",
fpObjDB->GetVersionLabel(iDef).data());
224 const char* titleDiff = Form(
"Difference from %s",
fpObjDB->GetVersionLabel(iDef).data());
225 const char* xAxisTitle =
static_cast<TH1*
>(
fvpObjects[0])->GetXaxis()->GetTitle();
226 const char* yAxisTitle =
static_cast<TH1*
>(
fvpObjects[0])->GetYaxis()->GetTitle();
230 auto* pMultiGraphOrig =
new TMultiGraph(
fsBaseName.data(), title);
231 for (
int iV = 0; iV < nVersions; ++iV) {
232 auto* pCopy =
new TGraphAsymmErrors((TH1*)
fvpObjects[iV]);
233 pCopy->SetMarkerStyle(20);
234 pCopy->SetTitle(
fpObjDB->GetVersionLabel(iV).data());
235 pMultiGraphOrig->Add(pCopy,
"P");
237 pMultiGraphOrig->GetXaxis()->SetTitle(xAxisTitle);
238 pMultiGraphOrig->GetYaxis()->SetTitle(yAxisTitle);
239 pMultiGraphOrig->Draw(
"A pmc plc");
240 pPadOrig->BuildLegend();
242 auto* pDefault =
static_cast<TH1*
>(
fvpObjects[iDef]);
247 auto* pMultiGraphRatio =
new TMultiGraph((
fsBaseName +
"_ratio").data(), titleRatio);
248 for (
int iV = 0; iV < nVersions; ++iV) {
252 auto* pRatio =
static_cast<TH1*
>(
fvpObjects[iV]->Clone());
254 auto currErrorLevel = gErrorIgnoreLevel;
255 gErrorIgnoreLevel = kError;
256 auto* pCopy =
new TGraphAsymmErrors(pRatio, pDefault,
"pois");
257 gErrorIgnoreLevel = currErrorLevel;
258 pCopy->SetMarkerStyle(20);
259 pMultiGraphRatio->Add(pCopy,
"P");
265 pMultiGraphRatio->GetYaxis()->SetTitle(
"ratio");
266 pMultiGraphRatio->GetXaxis()->SetTitle(xAxisTitle);
267 pMultiGraphRatio->Draw(
"A pmc plc");
273 auto* pMultiGraphDiff =
new TMultiGraph((
fsBaseName +
"_diff").data(), titleDiff);
274 for (
int iV = 0; iV < nVersions; ++iV) {
278 auto* pDiff =
static_cast<TH1*
>(
fvpObjects[iV]->Clone());
280 pDiff->Add(pDefault, -1.);
281 auto* pCopy =
new TGraphAsymmErrors(pDiff);
282 pCopy->SetMarkerStyle(20);
283 pMultiGraphDiff->Add(pCopy,
"P");
289 pMultiGraphDiff->GetYaxis()->SetTitle(
"difference");
290 pMultiGraphDiff->GetXaxis()->SetTitle(xAxisTitle);
291 pMultiGraphDiff->Draw(
"A pmc plc");
295 if (pPadRatio) pPadRatio->Draw();
296 if (pPadDiff) pPadDiff->Draw();