File indexing completed on 2024-04-06 12:33:13
0001 #include "include/PlotCompareUtility.h"
0002
0003 #include "include/Plot1D.h"
0004 #include "include/Plot2D.h"
0005 #include "include/PlotTypes.h"
0006 #include "include/Style.h"
0007
0008 #include <fstream>
0009
0010 #include <TCanvas.h>
0011 #include <TFile.h>
0012 #include <TGaxis.h>
0013 #include <TH1F.h>
0014 #include <TH2F.h>
0015 #include <TLine.h>
0016 #include <TPave.h>
0017 #include <TStyle.h>
0018 #include <TText.h>
0019 using namespace std;
0020
0021 PlotCompareUtility::PlotCompareUtility(std::string Reference,
0022 std::string New,
0023 std::string NewBasePath,
0024 std::string NewPrefix,
0025 std::string RefBasePath,
0026 std::string RefPrefix) {
0027
0028 cout << refFile << " " << newFile << endl;
0029 refFile = new TFile(Reference.c_str(), "READ");
0030 newFile = new TFile(New.c_str(), "READ");
0031
0032
0033 newBasePath = NewBasePath;
0034 newPrefix = NewPrefix;
0035 refBasePath = RefBasePath;
0036 refPrefix = RefPrefix;
0037
0038
0039 ksThreshold = 0;
0040 chi2Threshold = 0;
0041
0042
0043 summaryWidth = 700;
0044 summaryBarsThickness = 20;
0045 summaryTopMargin = 60;
0046 summaryLeftMargin = 250;
0047 summaryRightMargin = 60;
0048 summaryBottomMargin = 60;
0049
0050
0051 projectionsHeight = 340;
0052 projectionsBarsThickness = 20;
0053 projectionsTopMargin = 20;
0054 projectionsBottomMargin = 60;
0055 projectionsLeftMargin = 100;
0056 projectionsRightMargin = 40;
0057
0058
0059 plotsWidth = 680;
0060 plotsHeight = 500;
0061 plotsTopMargin = 50;
0062 plotsBottomMargin = 80;
0063 plotsLeftMargin = 100;
0064 plotsRightMargin = 40;
0065
0066
0067 finalResult = true;
0068
0069
0070 static TStyle style = genStyle();
0071 style.cd();
0072 }
0073
0074 PlotCompareUtility::~PlotCompareUtility() {
0075
0076 if (refFile != nullptr)
0077 refFile->Close();
0078 if (newFile != nullptr)
0079 newFile->Close();
0080 }
0081
0082 void PlotCompareUtility::dump() {
0083 cout << "RefFile = " << refFile->GetName() << endl
0084 << "RefBasePath = " << refBasePath << endl
0085 << "RefPrefix = " << refPrefix << endl
0086 << "NewFile = " << newFile->GetName() << endl
0087 << "NewBasePath = " << newBasePath << endl
0088 << "NewPrefix = " << newPrefix << endl
0089 << "NumHistos = " << histos.size() << endl;
0090 }
0091
0092 bool PlotCompareUtility::compare(HistoData *HD) {
0093 bool retval = false;
0094 switch (HD->getType()) {
0095 case Plot1D:
0096 retval = compare<Plot1D>(HD);
0097 break;
0098 case Plot2D:
0099 retval = compare<Plot2D>(HD);
0100 break;
0101 }
0102
0103 finalResult &= retval;
0104 return retval;
0105 }
0106
0107 void PlotCompareUtility::makePlots(HistoData *HD) {
0108 switch (HD->getType()) {
0109 case Plot1D:
0110 makePlots<Plot1D>(HD);
0111 break;
0112 case Plot2D:
0113 makePlots<Plot2D>(HD);
0114 break;
0115 }
0116 }
0117
0118 void PlotCompareUtility::makeHTML(HistoData *HD) {
0119 switch (HD->getType()) {
0120 case Plot1D:
0121 makeHTML<Plot1D>(HD);
0122 break;
0123 case Plot2D:
0124 makeHTML<Plot2D>(HD);
0125 break;
0126 }
0127 }
0128
0129 HistoData *PlotCompareUtility::addHistoData(string NewName, string RefName, int Type) {
0130
0131 static int bin = 0;
0132 bin++;
0133
0134
0135 string newPath = newBasePath + "/" + newPrefix + "/" + NewName;
0136 string refPath = refBasePath + "/" + refPrefix + "/" + RefName;
0137 cout << "NewPath = " << newPath << endl;
0138 cout << "RefPath = " << refPath << endl;
0139
0140 HistoData hd(NewName, Type, bin, newPath, newFile, refPath, refFile);
0141 histos.push_back(hd);
0142
0143 return &(*histos.rbegin());
0144 }
0145
0146 HistoData *PlotCompareUtility::addProjectionXData(
0147 HistoData *Parent, std::string Name, int Type, int Bin, TH1 *NewHisto, TH1 *RefHisto) {
0148
0149 HistoData hd(Name, Type, Bin, NewHisto, RefHisto);
0150 projectionsX[Parent].push_back(hd);
0151 return &(*projectionsX[Parent].rbegin());
0152 }
0153
0154 HistoData *PlotCompareUtility::addProjectionYData(
0155 HistoData *Parent, std::string Name, int Type, int Bin, TH1 *NewHisto, TH1 *RefHisto) {
0156
0157 HistoData hd(Name, Type, Bin, NewHisto, RefHisto);
0158 projectionsY[Parent].push_back(hd);
0159 return &(*projectionsY[Parent].rbegin());
0160 }
0161
0162 bool PlotCompareUtility::isValid() const {
0163 string newPath = newBasePath + "/" + newPrefix;
0164 string refPath = refBasePath + "/" + refPrefix;
0165
0166 bool refValid = (refFile != nullptr) && (refFile->Get(refPath.c_str()) != nullptr);
0167 bool newValid = (newFile != nullptr) && (newFile->Get(newPath.c_str()) != nullptr);
0168
0169 return refValid && newValid;
0170 }
0171
0172 void PlotCompareUtility::centerRebin(TH1 *H1, TH1 *H2) {
0173
0174 float h1RMS = H1->GetRMS();
0175 float h2RMS = H2->GetRMS();
0176 float rms = TMath::Max(h1RMS, h2RMS);
0177 float h1Mean = H1->GetMean();
0178 float h2Mean = H2->GetMean();
0179 float mean = 0.5 * (h1Mean + h2Mean);
0180 float nBins = H2->GetNbinsX();
0181 float minX = H2->GetXaxis()->GetXmin();
0182 float maxX = H2->GetXaxis()->GetXmax();
0183 float dX = maxX - minX;
0184 float dNdX = 1;
0185 float newMinX = 0;
0186 float newMaxX = 1;
0187
0188 if (rms > 0) {
0189 dNdX = 100. / (10 * rms);
0190 newMinX = mean - 5 * rms;
0191 newMaxX = mean + 5 * rms;
0192 }
0193
0194
0195 H1->GetXaxis()->SetRangeUser(newMinX, newMaxX);
0196 H2->GetXaxis()->SetRangeUser(newMinX, newMaxX);
0197
0198
0199 if (dX * dNdX > 0) {
0200 int rebinning = (int)(float(nBins) / (dX * dNdX));
0201 H1->Rebin(rebinning);
0202 H2->Rebin(rebinning);
0203 }
0204
0205
0206 float maxY1 = H1->GetMaximum();
0207 float maxY2 = H2->GetMaximum();
0208 float newMinY = 1e-1;
0209 float newMaxY = maxY1 > maxY2 ? maxY1 : maxY2;
0210 newMaxY *= 2;
0211
0212
0213 H1->GetYaxis()->SetRangeUser(newMinY, newMaxY);
0214 H2->GetYaxis()->SetRangeUser(newMinY, newMaxY);
0215 }
0216
0217 void PlotCompareUtility::renormalize(TH1 *H1, TH1 *H2) {
0218
0219 H2->SetNormFactor(H1->GetEntries());
0220 }
0221
0222 double PlotCompareUtility::getThreshold() const {
0223 double threshold;
0224
0225
0226 if (ksThreshold > 0 && chi2Threshold > 0)
0227 threshold = ksThreshold < chi2Threshold ? ksThreshold : chi2Threshold;
0228 else
0229 threshold = ksThreshold > 0 ? ksThreshold : chi2Threshold;
0230
0231 return threshold;
0232 }
0233
0234 void PlotCompareUtility::makeSummary(string Name) {
0235
0236 makeSummaryPlot(Name);
0237 makeSummaryHTML(Name);
0238 }
0239
0240 void PlotCompareUtility::makeDefaultPlots() {
0241
0242 TCanvas noDataCanvas("noDataCanvas", "noDataCanvas", plotsWidth, plotsHeight);
0243 noDataCanvas.SetFrameFillColor(10);
0244 noDataCanvas.Draw();
0245 TText noData(0.5, 0.5, "No Data");
0246 noData.Draw();
0247 noDataCanvas.Print("NoData_Results.gif");
0248 }
0249
0250 void PlotCompareUtility::makeSummaryPlot(string Name) {
0251
0252 int numHistos = histos.size();
0253 summaryHeight = summaryBottomMargin + summaryTopMargin + int(float(numHistos * summaryBarsThickness) * 1.5);
0254
0255
0256
0257 int summaryCanvasWidth = summaryWidth + 4;
0258 int summaryCanvasHeight = summaryHeight + 28;
0259
0260
0261 TCanvas summaryCanvas("summaryCanvas", "summaryCanvas", summaryCanvasWidth, summaryCanvasHeight);
0262 summaryCanvas.SetFrameFillColor(10);
0263 summaryCanvas.SetLogx(1);
0264 summaryCanvas.SetGrid();
0265 summaryCanvas.SetTopMargin(float(summaryTopMargin) / summaryHeight);
0266 summaryCanvas.SetLeftMargin(float(summaryLeftMargin) / summaryWidth);
0267 summaryCanvas.SetRightMargin(float(summaryRightMargin) / summaryWidth);
0268 summaryCanvas.SetBottomMargin(float(summaryBottomMargin) / summaryHeight);
0269 summaryCanvas.Draw();
0270
0271
0272 TH1F summary("summary", "Compatibility with Reference Histograms", numHistos, 1, numHistos + 1);
0273 summary.GetXaxis()->SetLabelSize(float(summaryLeftMargin) / (11 * summaryWidth));
0274 summary.GetYaxis()->SetLabelSize(summary.GetXaxis()->GetLabelSize());
0275 summary.GetYaxis()->SetTitle("Compatibility");
0276 summary.SetStats(false);
0277 summary.GetYaxis()->SetRangeUser(getThreshold() / 10, 2);
0278 summary.Draw("hbar0");
0279
0280
0281 vector<HistoData>::iterator hd;
0282 for (hd = histos.begin(); hd != histos.end(); hd++)
0283 hd->drawResult(&summary, false, true);
0284
0285
0286 TLine passLine(getThreshold(), 1, getThreshold(), numHistos + 1);
0287 passLine.SetLineColor(kRed);
0288 passLine.SetLineWidth(2);
0289 passLine.SetLineStyle(2);
0290 passLine.Draw("SAME");
0291
0292
0293 string gifName = Name + ".gif";
0294 summaryCanvas.Print(gifName.c_str());
0295 }
0296
0297 void PlotCompareUtility::makeSummaryHTML(string Name) {
0298
0299 string gifName = Name + ".gif";
0300 string html = "index.html";
0301 ofstream fout(html.c_str());
0302
0303
0304 fout << "<!DOCTYPE gif PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">" << endl
0305 << "<html>" << endl
0306 << endl
0307 << " <head>" << endl
0308 << " <script type=\"text/javascript\">" << endl
0309 << " function tn(target, image) {" << endl
0310 << " document.getElementById(\"thumblink\").href = target" << endl
0311 << " document.getElementById(\"thumb\").src = image" << endl
0312 << " }" << endl
0313 << " </script>" << endl
0314 << " </head>" << endl
0315 << endl
0316 << " <body>" << endl
0317 << endl
0318 << " <style type=\"text/css\">" << endl
0319 << " #thumb_d {position: absolute; position: fixed; left: 5px; "
0320 "top: 80px; text-align: center; }"
0321 << endl
0322 << " #main_d {position: relative; left: 175px; }" << endl
0323 << " </style>" << endl
0324 << endl
0325 << " <!-- added for IE compatibility (untested)" << endl
0326 << " <script language=\"JScript\">" << endl
0327 << " if (document.recalc && document.body.attachEvent) {" << endl
0328 << " theDiv.style.setExpression(\"top\", "
0329 "\"document.body.scrollTop + 150\"); "
0330 << endl
0331 << " document.body.onscroll = function() { document.recalc(true) "
0332 "}; "
0333 << endl
0334 << " }" << endl
0335 << " </script> -->" << endl
0336 << endl
0337 << " <div id=\"main_d\">" << endl
0338 << " <img src=\"" << gifName << "\" usemap=\"#" << Name << "\" alt=\"\" style=\"border-style: none;\""
0339 << " height=" << summaryHeight << " width=" << summaryWidth << " border=0>" << endl
0340 << " <map id=\"" << Name << "\" name=\"" << Name << "\">" << endl;
0341
0342
0343 vector<HistoData>::iterator hd;
0344 for (hd = histos.begin(); hd != histos.end(); hd++) {
0345
0346 int bin = hd->getBin();
0347 int x1 = summaryLeftMargin;
0348 int y1 = summaryHeight - summaryBottomMargin - int(float(bin * 1.5 - .25) * summaryBarsThickness) + 2;
0349 int x2 = summaryWidth - summaryRightMargin;
0350 int y2 = y1 + summaryBarsThickness;
0351 string image = hd->getResultImage();
0352 string target = hd->getResultTarget();
0353
0354
0355 fout << " <area shape=\"rect\" alt=\"\" coords=\"" << x1 << "," << y1 << "," << x2 << "," << y2
0356 << "\" href=\"" << target << "\" onMouseOver=\"tn('" << target << "','" << image << "')\">" << endl;
0357 }
0358
0359
0360 fout << " <area shape=\"default\" nohref=\"nohref\" alt=\"\">" << endl
0361 << " </map>" << endl
0362 << " </div>" << endl
0363 << endl
0364 << " <div id=\"thumb_d\">" << endl
0365 << " <a href=\"#\" id=\"thumblink\"><img src=\"NoData_Results.gif\" "
0366 "id=\"thumb\" width=200 height=150 border=0></a>"
0367 << endl
0368 << " <br><a href=\"log.txt\">Root Output</a>" << endl
0369 << " <br><a href=\"err.txt\">Root Warnings</a>" << endl
0370 << " </div>" << endl
0371 << endl
0372 << " </body>" << endl
0373 << endl
0374 << "</html>" << endl;
0375
0376
0377 fout.close();
0378 }