Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-11-11 00:04:08

0001 #include "Alignment/OfflineValidation/interface/CompareAlignments.h"
0002 
0003 void CompareAlignments::doComparison(TString namesandlabels,
0004                                      TString legendheader,
0005                                      TString lefttitle,
0006                                      TString righttitle,
0007                                      PublicationStatus status,
0008                                      bool bigtext) {
0009   std::cout << "Comparing using: >" << namesandlabels << "<" << std::endl;
0010 
0011   TkAlStyle::legendheader = legendheader;
0012   TkAlStyle::set(status, NONE, lefttitle, righttitle);
0013   gStyle->SetOptStat(111110);
0014   gStyle->SetOptTitle(0);
0015 
0016   Target = TFile::Open((outPath + "/result.root").c_str(), "RECREATE");
0017   FileList = new TList();
0018   LabelList = new TList();
0019 
0020   int formatCounter = 1;
0021   //TObjArray* stringarray = namesandlabels.Tokenize(",");
0022   TObjArray *nameandlabelpairs = namesandlabels.Tokenize(",");
0023   for (Int_t i = 0; i < nameandlabelpairs->GetEntries(); ++i) {
0024     TObjArray *aFileLegPair = TString(nameandlabelpairs->At(i)->GetName()).Tokenize("=");
0025 
0026     if (aFileLegPair->GetEntries() == 2) {
0027       TFile *currentFile = TFile::Open(aFileLegPair->At(0)->GetName());
0028       if (currentFile != nullptr && !currentFile->IsZombie()) {
0029         FileList->Add(currentFile);  // 2
0030         if (currentFile->Get("TrackerOfflineValidation/Pixel/P1PXBBarrel_1")) {
0031           phases.push_back(1);
0032         } else if (currentFile->Get("TrackerOfflineValidation/Pixel/TPBBarrel_1")) {
0033           phases.push_back(0);
0034         } else {
0035           std::cout << "Unknown phase for file " << aFileLegPair->At(0)->GetName() << std::endl;
0036           assert(false);
0037         }
0038         if (TString(aFileLegPair->At(1)->GetName()).Contains("|")) {
0039           TObjArray *formatedLegendEntry = TString(aFileLegPair->At(1)->GetName()).Tokenize("|");
0040           LabelList->Add(formatedLegendEntry->At(0));
0041           if (formatedLegendEntry->GetEntries() > 1) {
0042             theColors.push_back(atoi(formatedLegendEntry->At(1)->GetName()));
0043 
0044             if (formatedLegendEntry->GetEntries() > 2)
0045               theStyles.push_back(atoi(formatedLegendEntry->At(2)->GetName()) % 100);
0046             else
0047               theStyles.push_back(formatCounter);
0048           } else {
0049             std::cout << "if you give a \"|\" in the legend name you will need to at least give a int for the color"
0050                       << std::endl;
0051           }
0052           formatCounter++;
0053         } else {
0054           LabelList->Add(aFileLegPair->At(1));
0055           theColors.push_back(formatCounter);
0056           theStyles.push_back(formatCounter);
0057           formatCounter++;
0058         }
0059       } else {
0060         std::cout << "Could not open: " << aFileLegPair->At(0)->GetName() << std::endl;
0061       }
0062     } else {
0063       std::cout << "Please give file name and legend entry in the following form:\n"
0064                 << " filename1=legendentry1,filename2=legendentry2[|color[|style]]" << std::endl;
0065     }
0066   }
0067 
0068   // ************************************************************
0069   // List of Files
0070   //FileList->Add( TFile::Open("../test/AlignmentValidation_Elliptical.root") );
0071   //FileList->Add( TFile::Open("../test/AlignmentValidation_10pb.root")  );  // 2
0072   //FileList->Add( TFile::Open("../test/AlignmentValidation_custom.root")  );  // 2
0073   // ************************************************************
0074 
0075   // put here the lowest level up to which you want to combine the
0076   // histograms
0077   lowestlevels.push_back("TPBLadder");
0078   lowestlevels.push_back("TPEPanel");
0079   lowestlevels.push_back("TIBHalfShell");
0080   lowestlevels.push_back("TIDRing");
0081   lowestlevels.push_back("TOBRod");
0082   lowestlevels.push_back("TECSide");
0083   // phase 1
0084   // it checks each one independently so no harm in having
0085   // both phase 0 and 1 together in the vector
0086   lowestlevels.push_back("P1PXBLadder");
0087   lowestlevels.push_back("P1PXECPanel");
0088 
0089   MergeRootfile(Target, FileList, LabelList, bigtext);
0090 }
0091 
0092 void CompareAlignments::MergeRootfile(TDirectory *target, TList *sourcelist, TList *labellist, bool bigtext) {
0093   if (sourcelist->GetSize() == 0) {
0094     std::cout << "Cowardly refuse to merge empty SourceList! " << std::endl;
0095     return;
0096   }
0097 
0098   TString path((char *)strstr(target->GetPath(), ":"));
0099   path.Remove(0, 2);
0100 
0101   TFile *first_source = (TFile *)sourcelist->First();
0102   TObjString *first_label = (TObjString *)labellist->First();
0103 
0104   first_source->cd(path);
0105   TDirectory *current_sourcedir = gDirectory;
0106   //gain time, do not add the objects in the list in memory
0107   Bool_t status = TH1::AddDirectoryStatus();
0108   TH1::AddDirectory(kFALSE);
0109 
0110   // loop over all keys in this directory
0111 
0112   TIter nextkey(current_sourcedir->GetListOfKeys());
0113   TKey *key, *oldkey = nullptr;
0114   while ((key = (TKey *)nextkey())) {
0115     //keep only the highest cycle number for each key
0116     if (oldkey && !strcmp(oldkey->GetName(), key->GetName()))
0117       continue;
0118 
0119     // read object from first source file
0120     first_source->cd(path);
0121     TObject *obj = key->ReadObj();
0122 
0123     auto itphase = phases.begin();
0124     int firstfilephase = *itphase;
0125 
0126     if (obj->IsA()->InheritsFrom(TH1::Class())) {
0127       // descendant of TH1 -> merge it
0128       TCanvas c(obj->GetName(), obj->GetName());
0129       c.SetFillColor(10);
0130 
0131       bool is2d = false;
0132       if (strstr(obj->ClassName(), "TH2") != nullptr)
0133         is2d = true;
0134       TH1 *h1 = static_cast<TH1 *>(obj);
0135 
0136       int q = 1;
0137       TObjArray *histarray = new TObjArray;
0138 
0139       h1->SetLineStyle(theStyles.at(q - 1));
0140       h1->SetLineWidth(2);
0141 
0142       h1->SetTitle("");
0143 
0144       h1->SetLineColor(theColors.at(q - 1));
0145       h1->GetYaxis()->SetTitleOffset(1.5);
0146       if (strstr(h1->GetName(), "summary") != nullptr)
0147         h1->Draw("x0e1*H");
0148       else if (is2d)
0149         h1->Draw();
0150       else
0151         h1->Draw();
0152 
0153       double max = h1->GetMaximum();
0154       double scale = 1;
0155       if (max > 1000) {
0156         int power = (int)(TMath::Log10(max / 100));
0157         scale = 1 / TMath::Power(10, power);
0158         h1->GetYaxis()->SetTitle(((TString(h1->GetYaxis()->GetTitle()) + " [#times 10^{") += (int)power) + "}]");
0159       }
0160       h1->Scale(scale);
0161 
0162       int nPlots = sourcelist->GetSize();
0163       double legendY = 0.80;
0164       if (nPlots > 3) {
0165         legendY -= 0.01 * (nPlots - 3);
0166       }
0167       if (bigtext) {
0168         legendY -= 0.05;
0169       }
0170       if (legendY < 0.6) {
0171         std::cerr << "Warning: Huge legend!" << std::endl;
0172         legendY = 0.6;
0173       }
0174       TLegend leg(0.17, legendY, 0.85, 0.88);
0175       bool hasheader = (TkAlStyle::legendheader != "");
0176       if (hasheader)
0177         leg.SetHeader(TkAlStyle::legendheader);
0178       if (bigtext)
0179         leg.SetTextSize(TkAlStyle::textSize);
0180       leg.AddEntry(h1, first_label->String().Data(), "L");
0181       leg.SetBorderSize(0);
0182       leg.SetFillColor(10);
0183       // loop over all source files and add the content of the
0184       // correspondant histogram to the one pointed to by "h1"
0185       TFile *nextsource = (TFile *)sourcelist->After(first_source);
0186       TObjString *nextlabel = (TObjString *)labellist->After(labellist->First());
0187 
0188       histarray->Add(h1);
0189       while (nextsource) {
0190         TKey *key2;
0191         bool wrongphase = false;
0192         ++itphase;
0193 
0194         if (firstfilephase != *itphase && path.Contains("TrackerOfflineValidation/Pixel")) {
0195           //skip this one
0196           key2 = nullptr;
0197           wrongphase = true;
0198         } else {
0199           // make sure we are at the correct directory level by cd'ing to path
0200           nextsource->cd(path);
0201           key2 = (TKey *)gDirectory->GetListOfKeys()->FindObject(h1->GetName());
0202         }
0203         if (key2) {
0204           ++q;
0205           TH1 *h2 = (TH1 *)key2->ReadObj();
0206 
0207           if (!is2d) {
0208             h2->SetLineStyle(theStyles.at(q - 1));
0209             h2->SetLineWidth(2);
0210           }
0211 
0212           h2->SetLineColor(theColors.at(q - 1));
0213           std::stringstream newname;
0214           newname << h2->GetName() << q;
0215           h2->Scale(scale);
0216 
0217           h2->SetName(newname.str().c_str());
0218           if (strstr(newname.str().c_str(), "summary") != nullptr)
0219             h2->DrawClone("x0*He1sames");
0220           else if (is2d)
0221             h2->DrawClone("sames");
0222           else
0223             h2->DrawClone("sames");
0224           leg.AddEntry(c.FindObject(h2->GetName()), nextlabel->String().Data(), "L");
0225           histarray->Add(c.FindObject(h2->GetName()));
0226           delete h2;
0227         } else if (wrongphase) {
0228           //nothing
0229         } else {
0230           std::cerr << "Histogram " << path << " is not present in file " << nextsource->GetName() << std::endl;
0231         }
0232 
0233         nextsource = (TFile *)sourcelist->After(nextsource);
0234         nextlabel = (TObjString *)labellist->After(nextlabel);
0235       }
0236       nicePad(0, 0);
0237       leg.Draw();
0238       TkAlStyle::drawStandardTitle();
0239       c.Update();
0240       if (strstr(h1->GetName(), "summary") == nullptr)
0241         SetMinMaxRange(histarray);
0242       ColourStatsBoxes(histarray);
0243       target->cd();
0244       c.Update();
0245       c.Write();
0246       histarray->Delete();
0247 
0248     } else if (obj->IsA()->InheritsFrom(TDirectory::Class())) {
0249       // it's a subdirectory
0250 
0251       std::string dirname = obj->GetName();
0252       for (std::vector<std::string>::const_iterator lowlevelit = lowestlevels.begin(),
0253                                                     lowlevelitend = lowestlevels.end();
0254            lowlevelit != lowlevelitend;
0255            ++lowlevelit)
0256         if (dirname.find(*lowlevelit) != std::string::npos)
0257           return;
0258 
0259       // create a new subdir of same name and title in the target file
0260       target->cd();
0261       TDirectory *newdir = target->mkdir(obj->GetName(), obj->GetTitle());
0262 
0263       // newdir is now the starting point of another round of merging
0264       // newdir still knows its depth within the target file via
0265       // GetPath(), so we can still figure out where we are in the recursion
0266       MergeRootfile(newdir, sourcelist, labellist, bigtext);
0267 
0268     } else {
0269       // object is of no type that we know or can handle
0270       std::cout << "Unknown object type, name: " << obj->GetName() << " title: " << obj->GetTitle() << std::endl;
0271     }
0272 
0273   }  // while ( ( TKey *key = (TKey*)nextkey() ) )
0274 
0275   // save modifications to target file
0276   target->SaveSelf(kTRUE);
0277   TH1::AddDirectory(status);
0278 }
0279 
0280 void CompareAlignments::nicePad(Int_t logx, Int_t logy) {
0281   /*
0282     gPad->SetBottomMargin(0.10);
0283     gPad->SetRightMargin(0.1);
0284     gPad->SetLeftMargin(0.15);
0285     gPad->SetTopMargin(0.15);
0286     gPad->SetTickx(1);
0287     gPad->SetTicky(1);
0288 */
0289   if (logy == 1) {
0290     gPad->SetLogy();
0291   } else {
0292     gPad->SetLogy(0);
0293   }
0294   if (logx == 1) {
0295     gPad->SetLogx();
0296   } else {
0297     gPad->SetLogx(0);
0298   }
0299 }
0300 
0301 void CompareAlignments::ColourStatsBoxes(TObjArray *hists) {
0302   Double_t fStatsX1 = 0.85, fStatsX2 = 1., fStatsY1 = 0.77, fStatsY2 = 0.92;
0303   // colours stats boxes like hists' line colors and moves the next to each other
0304   if (!hists)
0305     return;
0306   Double_t x1 = fStatsX1, x2 = fStatsX2, y1 = fStatsY1, y2 = fStatsY2;
0307   for (Int_t iH = 0; iH < hists->GetEntries(); ++iH) {
0308     TH1 *h = static_cast<TH1 *>(hists->At(iH));
0309     if (!h)
0310       continue;
0311     TObject *statObj = h->GetListOfFunctions()->FindObject("stats");
0312     if (statObj && statObj->InheritsFrom(TPaveStats::Class())) {
0313       TPaveStats *stats = static_cast<TPaveStats *>(statObj);
0314       stats->SetLineColor(static_cast<TH1 *>(hists->At(iH))->GetLineColor());
0315       stats->SetTextColor(static_cast<TH1 *>(hists->At(iH))->GetLineColor());
0316       stats->SetFillColor(10);
0317       stats->SetX1NDC(x1);
0318       stats->SetX2NDC(x2);
0319       stats->SetY1NDC(y1);
0320       stats->SetY2NDC(y2);
0321       y2 = y1 - 0.005;                  // shift down 2
0322       y1 = y2 - (fStatsY2 - fStatsY1);  // shift down 1
0323       if (y1 < 0.) {
0324         y1 = fStatsY1;
0325         y2 = fStatsY2;                    // restart y-positions
0326         x2 = x1 - 0.005;                  // shift left 2
0327         x1 = x2 - (fStatsX2 - fStatsX1);  // shift left 1
0328         if (x1 < 0.) {                    // give up, start again:
0329           x1 = fStatsX1, x2 = fStatsX2, y1 = fStatsY1, y2 = fStatsY2;
0330         }
0331       }
0332       stats->DrawClone();
0333       //} else if (gStyle->GetOptStat() != 0) { // failure in case changed in list via TExec....
0334       //this->Warning("ColourStatsBoxes", "No stats found for %s", hists->At(iH)->GetName());
0335     }
0336   }
0337 }
0338 
0339 void CompareAlignments::SetMinMaxRange(TObjArray *hists) {
0340   Double_t min = 100000;
0341   Double_t max = -100000;
0342   for (Int_t iH = 0; iH < hists->GetEntries(); ++iH) {
0343     TH1 *h = static_cast<TH1 *>(hists->At(iH));
0344     if (!h)
0345       continue;
0346     for (int i = 1; i <= h->GetNbinsX(); ++i) {
0347       if (h->GetBinContent(i) + h->GetBinError(i) > max)
0348         max = h->GetBinContent(i) + h->GetBinError(i);
0349       if (h->GetBinContent(i) - h->GetBinError(i) < min)
0350         min = h->GetBinContent(i) - h->GetBinError(i);
0351     }
0352   }
0353 
0354   TH1 *h_first = static_cast<TH1 *>(hists->At(0));
0355   h_first->SetMaximum(max * 1.3);
0356   if (min == 0.) {
0357     min = -1111;
0358     h_first->SetMinimum(min);
0359   } else {
0360     h_first->SetMinimum(min - min * 0.1);
0361   }
0362 }