CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_4_5_patch3/src/Alignment/OfflineValidation/scripts/compareAlignments.cc

Go to the documentation of this file.
00001 #include <string.h>
00002 #include <cstring>
00003 #include "TChain.h"
00004 #include "TFile.h"
00005 #include "TH1.h"
00006 #include "TTree.h"
00007 #include "TKey.h"
00008 #include "Riostream.h"
00009 #include <vector>
00010 #include <sstream>
00011 #include "TCanvas.h"
00012 #include "TLegend.h"
00013 #include "TROOT.h"
00014 #include "TPaveStats.h"
00015 #include "TObjArray.h"
00016 #include "TObjString.h"
00017 #include "TStyle.h"
00018 #include "TEnv.h"
00019 
00020 
00021 TList *FileList;
00022 TList *LabelList;
00023 TFile *Target;
00024 std::vector< std::string > lowestlevels;
00025 std::vector< int > theColors;
00026 std::vector< int > theStyles;
00027 
00028 void MergeRootfile( TDirectory *target, TList *sourcelist, TList *labellist );
00029 void nicePad(Int_t logx,Int_t logy);
00030 void SetMinMaxRange(TObjArray *hists);
00031 
00032 void ColourStatsBoxes(TObjArray *hists);
00033 
00034 void compareAlignments(TString namesandlabels="readFromFile") 
00035 {
00036   cout << "Comparing using: >"<<namesandlabels<<"<"<<endl;
00037 
00038   gStyle->SetOptStat(111110);
00039   gStyle->SetTitleFillColor(10);
00040   gStyle->SetTitleBorderSize(0);
00041 
00042   Target = TFile::Open( "result.root", "RECREATE" );
00043   FileList = new TList();
00044   LabelList = new TList();
00045   
00046   int formatCounter = 1;
00047   //TObjArray* stringarray = namesandlabels.Tokenize(",");  
00048   TObjArray *nameandlabelpairs = namesandlabels.Tokenize(",");
00049   for (Int_t i = 0; i < nameandlabelpairs->GetEntries(); ++i) {
00050     TObjArray *aFileLegPair = TString(nameandlabelpairs->At(i)->GetName()).Tokenize("=");
00051     
00052     if(aFileLegPair->GetEntries() == 2) {
00053       TFile* currentFile = TFile::Open(aFileLegPair->At(0)->GetName());
00054       if( currentFile != NULL && !currentFile->IsZombie() ){
00055         FileList->Add( currentFile  );  // 2
00056         if(TString(aFileLegPair->At(1)->GetName()).Contains("|")){
00057           TObjArray* formatedLegendEntry = TString(aFileLegPair->At(1)->GetName()).Tokenize("|");
00058           LabelList->Add( formatedLegendEntry->At(0) );
00059           if(formatedLegendEntry->GetEntries() > 1){
00060             theColors.push_back(atoi(formatedLegendEntry->At(1)->GetName()));
00061             
00062             if(formatedLegendEntry->GetEntries() > 2)
00063               theStyles.push_back(atoi(formatedLegendEntry->At(2)->GetName()));
00064             else 
00065               theStyles.push_back( formatCounter );
00066           }else{
00067           std::cout <<"if you give a \"|\" in the legend name you will need to at least give a int for the color"<<std::endl;
00068           }
00069           formatCounter++;
00070         }else{
00071           LabelList->Add( aFileLegPair->At(1) );
00072           theColors.push_back(formatCounter);
00073           theStyles.push_back(formatCounter);
00074           formatCounter++;
00075         }
00076       }else{
00077         std::cout << "Could not open: "<<aFileLegPair->At(0)->GetName()<<std::endl;
00078       }
00079     }
00080     else {
00081       std::cout << "Please give file name and legend entry in the following form:\n" 
00082                 << " filename1=legendentry1,filename2=legendentry2[|color[|style]]"<<std::endl;
00083 
00084     }
00085     
00086   }
00087 
00088   // ************************************************************
00089   // List of Files
00090   //FileList->Add( TFile::Open("../test/AlignmentValidation_Elliptical.root") ); 
00091   //FileList->Add( TFile::Open("../test/AlignmentValidation_10pb.root")  );  // 2
00092   //FileList->Add( TFile::Open("../test/AlignmentValidation_custom.root")  );  // 2
00093   // ************************************************************
00094 
00095   // put here the lowest level up to which you want to combine the 
00096   // histogramms
00097   lowestlevels.push_back("TPBLadder");
00098   lowestlevels.push_back("TPEPanel");
00099   lowestlevels.push_back("TIBHalfShell");
00100   lowestlevels.push_back("TIDRing");
00101   lowestlevels.push_back("TOBRod");
00102   lowestlevels.push_back("TECSide");
00103 //  lowestlevels.push_back("Det");
00104   
00105   
00106   
00107    MergeRootfile( Target, FileList, LabelList );
00108 
00109 }
00110 
00111 void MergeRootfile( TDirectory *target, TList *sourcelist, TList *labellist ) {
00112 
00113   if( sourcelist->GetSize() == 0){
00114     std::cout<< "Cowardly refuse to merge empty SourceList! " <<std::endl;
00115     return;
00116   }
00117 
00118   TString path( (char*)strstr( target->GetPath(), ":" ) );
00119   path.Remove( 0, 2 );
00120 
00121   TFile *first_source = (TFile*)sourcelist->First();
00122   TObjString *first_label = (TObjString*)labellist->First();
00123 
00124   first_source->cd( path );
00125   TDirectory *current_sourcedir = gDirectory;
00126   //gain time, do not add the objects in the list in memory
00127   Bool_t status = TH1::AddDirectoryStatus();
00128   TH1::AddDirectory(kFALSE);
00129 
00130   // loop over all keys in this directory
00131 
00132   TIter nextkey( current_sourcedir->GetListOfKeys() );
00133   TKey *key, *oldkey=0;
00134   while ( (key = (TKey*)nextkey())) {
00135 
00136     //keep only the highest cycle number for each key
00137     if (oldkey && !strcmp(oldkey->GetName(),key->GetName())) continue;
00138 
00139     // read object from first source file
00140     first_source->cd( path );
00141     TObject *obj = key->ReadObj();
00142 
00143     if ( obj->IsA()->InheritsFrom( TH1::Class() ) ) {
00144       // descendant of TH1 -> merge it
00145       TCanvas c(obj->GetName(),obj->GetName(),500,500);
00146       c.SetFillColor(10);
00147       
00148       bool is2d = false;
00149       if(strstr(obj->ClassName() ,"TH2") != NULL )
00150         is2d = true;
00151       TH1 *h1 = static_cast<TH1*>(obj);
00152 
00153       int q = 1; 
00154       TObjArray *histarray = new TObjArray;
00155       
00156       h1->SetLineStyle(theStyles.at(q-1));
00157       h1->SetLineWidth(2);
00158    
00159       h1->SetLineColor(theColors.at(q-1));
00160       h1->GetYaxis()->SetTitleOffset(1.5);
00161       if(strstr(h1->GetName(),"summary") != NULL )
00162         h1->Draw("x0e1*H");
00163       else if(is2d)
00164         h1->Draw();
00165       else 
00166         h1->Draw();
00167 
00168       TLegend leg(0.2,0.85,0.775,0.93);
00169       leg.AddEntry(h1,first_label->String().Data(),"L");
00170       leg.SetBorderSize(0);
00171       leg.SetFillColor(10);
00172       // loop over all source files and add the content of the
00173       // correspondant histogram to the one pointed to by "h1"
00174       TFile *nextsource = (TFile*)sourcelist->After( first_source );
00175       TObjString *nextlabel = (TObjString*)labellist->After( labellist->First() );
00176       
00177       histarray->Add(h1);
00178       while ( nextsource ) {
00179 
00180         // make sure we are at the correct directory level by cd'ing to path
00181         
00182         nextsource->cd( path );
00183         TKey *key2 = (TKey*)gDirectory->GetListOfKeys()->FindObject(h1->GetName());
00184         if (key2) {
00185           ++q;
00186           TH1 *h2 = (TH1*)key2->ReadObj();        
00187 
00188           if(!is2d){
00189             h2->SetLineStyle(theStyles.at(q-1));
00190             h2->SetLineWidth(2);
00191           }
00192 
00193           h2->SetLineColor(theColors.at(q-1));
00194           std::stringstream newname;
00195           newname << h2->GetName() << q;
00196           
00197           h2->SetName(newname.str().c_str());
00198           if(strstr(newname.str().c_str(),"summary") != NULL )      
00199             h2->DrawClone("x0*He1sames");
00200           else if(is2d) 
00201             h2->DrawClone("sames");
00202           else
00203             h2->DrawClone("sames");
00204           leg.AddEntry(c.FindObject(h2->GetName()),nextlabel->String().Data(),"L");
00205           histarray->Add(c.FindObject(h2->GetName()));
00206           delete h2;      
00207         } else {
00208           std::cerr << "Histogram "<< key2->GetTitle() << " is not present in file " << nextsource->GetName() << std::endl;
00209         }
00210         
00211         nextsource = (TFile*)sourcelist->After( nextsource );
00212         nextlabel = (TObjString*)labellist->After(nextlabel);
00213       }
00214       nicePad(0,0);
00215       leg.Draw();
00216       c.Update();
00217       if(strstr(h1->GetName(),"summary") == NULL )
00218         SetMinMaxRange(histarray);
00219       ColourStatsBoxes(histarray);
00220       target->cd();
00221       c.Write();
00222       histarray->Delete();
00223       
00224 
00225       
00226 
00227     } else if ( obj->IsA()->InheritsFrom( TDirectory::Class() ) ) {
00228       // it's a subdirectory
00229 
00230       std::string dirname = obj->GetName();
00231       for( std::vector< std::string >::const_iterator lowlevelit = lowestlevels.begin(), 
00232              lowlevelitend = lowestlevels.end(); lowlevelit != lowlevelitend; ++lowlevelit) 
00233         if(   dirname.find(*lowlevelit) != std::string::npos ) 
00234           return;
00235           
00236       // create a new subdir of same name and title in the target file
00237       target->cd();
00238       TDirectory *newdir = target->mkdir( obj->GetName(), obj->GetTitle() );
00239       
00240       // newdir is now the starting point of another round of merging
00241       // newdir still knows its depth within the target file via
00242       // GetPath(), so we can still figure out where we are in the recursion
00243       MergeRootfile( newdir, sourcelist, labellist );
00244       
00245 
00246     } else {
00247 
00248       // object is of no type that we know or can handle
00249       cout << "Unknown object type, name: "
00250            << obj->GetName() << " title: " << obj->GetTitle() << endl;
00251     }
00252 
00253 
00254   } // while ( ( TKey *key = (TKey*)nextkey() ) )
00255 
00256   // save modifications to target file
00257   target->SaveSelf(kTRUE);
00258   TH1::AddDirectory(status);
00259 }
00260 
00261 
00262 
00263 
00264 void nicePad(Int_t logx,Int_t logy)
00265 {
00266     gPad->SetBottomMargin(0.10);
00267     gPad->SetRightMargin(0.1);
00268     gPad->SetLeftMargin(0.15);
00269     gPad->SetTopMargin(0.15);
00270     gPad->SetTickx(1);
00271     gPad->SetTicky(1);
00272     if(logy==1)
00273       {
00274         gPad->SetLogy();
00275       }
00276     else
00277       {
00278         gPad->SetLogy(0);
00279       }
00280     if(logx==1)
00281       {
00282         gPad->SetLogx();
00283       }
00284     else
00285       {
00286         gPad->SetLogx(0);
00287       }
00288 }
00289 
00290 
00291 void ColourStatsBoxes(TObjArray *hists) 
00292 {
00293 
00294   Double_t fStatsX1 = 0.85, fStatsX2 = 1., fStatsY1 = 0.85, fStatsY2 = 1.;
00295   // colours stats boxes like hists' line colors and moves the next to each other
00296   if (!hists) return;
00297   Double_t x1 = fStatsX1, x2 = fStatsX2, y1 = fStatsY1, y2 = fStatsY2;
00298   for (Int_t iH = 0; iH < hists->GetEntries(); ++iH) {
00299     TH1 *h = static_cast<TH1*>(hists->At(iH));
00300     if (!h) continue;
00301     TObject *statObj = h->GetListOfFunctions()->FindObject("stats");
00302     if (statObj && statObj->InheritsFrom(TPaveStats::Class())) {
00303       TPaveStats *stats = static_cast<TPaveStats*>(statObj);
00304       stats->SetLineColor(static_cast<TH1*>(hists->At(iH))->GetLineColor());
00305       stats->SetTextColor(static_cast<TH1*>(hists->At(iH))->GetLineColor());
00306       stats->SetFillColor(10);
00307       stats->SetX1NDC(x1);
00308       stats->SetX2NDC(x2);
00309       stats->SetY1NDC(y1);
00310       stats->SetY2NDC(y2);
00311       y2 = y1 - 0.005; // shift down 2
00312       y1 = y2 - (fStatsY2 - fStatsY1); // shift down 1
00313       if (y1 < 0.) {
00314         y1 = fStatsY1; y2 = fStatsY2; // restart y-positions
00315         x2 = x1 - 0.005; // shift left 2
00316         x1 = x2 - (fStatsX2 - fStatsX1); // shift left 1
00317         if (x1 < 0.) { // give up, start again:
00318           x1 = fStatsX1, x2 = fStatsX2, y1 = fStatsY1, y2 = fStatsY2;
00319         }
00320       }
00321       //} else if (gStyle->GetOptStat() != 0) { // failure in case changed in list via TExec....
00322       //this->Warning("ColourStatsBoxes", "No stats found for %s", hists->At(iH)->GetName());
00323     }
00324   }
00325 }
00326 
00327 
00328 void SetMinMaxRange(TObjArray *hists)
00329 {
00330   Double_t min = 100000;
00331   Double_t max = -100000;
00332    for (Int_t iH = 0; iH < hists->GetEntries(); ++iH) {
00333      TH1 *h = static_cast<TH1*>(hists->At(iH));
00334      if (!h) continue;
00335      for(int i = 1; i <= h->GetNbinsX(); ++i) {
00336        if(h->GetBinContent(i) + h->GetBinError(i) > max ) max = h->GetBinContent(i) + h->GetBinError(i);
00337        if(h->GetBinContent(i) - h->GetBinError(i) < min ) min = h->GetBinContent(i) - h->GetBinError(i);
00338      }
00339    }
00340 
00341    TH1 *h_first = static_cast<TH1*>(hists->At(0));
00342    h_first->SetMaximum(max+max*0.1);
00343    if(min = 0.) {
00344      min = -1111;
00345      h_first->SetMinimum(min);
00346    } else {
00347      h_first->SetMinimum(min-min*0.1);
00348    }
00349 }