Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 12:46:00

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