CMS 3D CMS Logo

compareAlignments.cc
Go to the documentation of this file.
1 #include <string.h>
2 #include <cstring>
3 #include "TChain.h"
4 #include "TFile.h"
5 #include "TH1.h"
6 #include "TTree.h"
7 #include "TKey.h"
8 #include "TMath.h"
9 #include "Riostream.h"
10 #include <vector>
11 #include <sstream>
12 #include "TCanvas.h"
13 #include "TLegend.h"
14 #include "TROOT.h"
15 #include "TPaveStats.h"
16 #include "TObjArray.h"
17 #include "TObjString.h"
18 #include "TStyle.h"
19 #include "TEnv.h"
20 
22 
23 
24 TList *FileList;
25 TList *LabelList;
26 TFile *Target;
27 std::vector< std::string > lowestlevels;
28 std::vector< int > theColors;
29 std::vector< int > theStyles;
30 std::vector< int > phases;
31 
32 void MergeRootfile( TDirectory *target, TList *sourcelist, TList *labellist, bool bigtext );
33 void nicePad(Int_t logx,Int_t logy);
34 void SetMinMaxRange(TObjArray *hists);
35 
36 void ColourStatsBoxes(TObjArray *hists);
37 
38 void compareAlignments(TString namesandlabels="readFromFile", TString legendheader = "", TString lefttitle = "", TString righttitle = "", bool bigtext = false)
39 {
40  cout << "Comparing using: >"<<namesandlabels<<"<"<<endl;
41 
42  TkAlStyle::legendheader = legendheader;
43  TkAlStyle::set(CUSTOM, NONE, lefttitle, righttitle);
44  gStyle->SetOptStat(111110);
45  gStyle->SetOptTitle(0);
46 
47  Target = TFile::Open( "result.root", "RECREATE" );
48  FileList = new TList();
49  LabelList = new TList();
50 
51  int formatCounter = 1;
52  //TObjArray* stringarray = namesandlabels.Tokenize(",");
53  TObjArray *nameandlabelpairs = namesandlabels.Tokenize(",");
54  for (Int_t i = 0; i < nameandlabelpairs->GetEntries(); ++i) {
55  TObjArray *aFileLegPair = TString(nameandlabelpairs->At(i)->GetName()).Tokenize("=");
56 
57  if(aFileLegPair->GetEntries() == 2) {
58  TFile* currentFile = TFile::Open(aFileLegPair->At(0)->GetName());
59  if( currentFile != NULL && !currentFile->IsZombie() ){
60  FileList->Add( currentFile ); // 2
61  if ( currentFile->Get("TrackerOfflineValidationStandalone/Pixel/P1PXBBarrel_1") ) {
62  phases.push_back(1);
63  } else if ( currentFile->Get("TrackerOfflineValidationStandalone/Pixel/TPBBarrel_1") ) {
64  phases.push_back(0);
65  } else {
66  cout << "Unknown phase for file " << aFileLegPair->At(0)->GetName() << endl;
67  assert(false);
68  }
69  if(TString(aFileLegPair->At(1)->GetName()).Contains("|")){
70  TObjArray* formatedLegendEntry = TString(aFileLegPair->At(1)->GetName()).Tokenize("|");
71  LabelList->Add( formatedLegendEntry->At(0) );
72  if(formatedLegendEntry->GetEntries() > 1){
73  theColors.push_back(atoi(formatedLegendEntry->At(1)->GetName()));
74 
75  if(formatedLegendEntry->GetEntries() > 2)
76  theStyles.push_back(atoi(formatedLegendEntry->At(2)->GetName())%100);
77  else
78  theStyles.push_back( formatCounter );
79  }else{
80  std::cout <<"if you give a \"|\" in the legend name you will need to at least give a int for the color"<<std::endl;
81  }
82  formatCounter++;
83  }else{
84  LabelList->Add( aFileLegPair->At(1) );
85  theColors.push_back(formatCounter);
86  theStyles.push_back(formatCounter);
87  formatCounter++;
88  }
89  }else{
90  std::cout << "Could not open: "<<aFileLegPair->At(0)->GetName()<<std::endl;
91  }
92  }
93  else {
94  std::cout << "Please give file name and legend entry in the following form:\n"
95  << " filename1=legendentry1,filename2=legendentry2[|color[|style]]"<<std::endl;
96 
97  }
98 
99  }
100 
101  // ************************************************************
102  // List of Files
103  //FileList->Add( TFile::Open("../test/AlignmentValidation_Elliptical.root") );
104  //FileList->Add( TFile::Open("../test/AlignmentValidation_10pb.root") ); // 2
105  //FileList->Add( TFile::Open("../test/AlignmentValidation_custom.root") ); // 2
106  // ************************************************************
107 
108  // put here the lowest level up to which you want to combine the
109  // histograms
110  lowestlevels.push_back("TPBLadder");
111  lowestlevels.push_back("TPEPanel");
112  lowestlevels.push_back("TIBHalfShell");
113  lowestlevels.push_back("TIDRing");
114  lowestlevels.push_back("TOBRod");
115  lowestlevels.push_back("TECSide");
116  // phase 1
117  // it checks each one independently so no harm in having
118  // both phase 0 and 1 together in the vector
119  lowestlevels.push_back("P1PXBLadder");
120  lowestlevels.push_back("P1PXECPanel");
121 
122 
123  MergeRootfile( Target, FileList, LabelList, bigtext );
124 
125 }
126 
127 void MergeRootfile( TDirectory *target, TList *sourcelist, TList *labellist, bool bigtext ) {
128 
129  if( sourcelist->GetSize() == 0){
130  std::cout<< "Cowardly refuse to merge empty SourceList! " <<std::endl;
131  return;
132  }
133 
134  TString path( (char*)strstr( target->GetPath(), ":" ) );
135  path.Remove( 0, 2 );
136 
137  TFile *first_source = (TFile*)sourcelist->First();
138  TObjString *first_label = (TObjString*)labellist->First();
139 
140  first_source->cd( path );
141  TDirectory *current_sourcedir = gDirectory;
142  //gain time, do not add the objects in the list in memory
143  Bool_t status = TH1::AddDirectoryStatus();
144  TH1::AddDirectory(kFALSE);
145 
146  // loop over all keys in this directory
147 
148  TIter nextkey( current_sourcedir->GetListOfKeys() );
149  TKey *key, *oldkey=0;
150  while ( (key = (TKey*)nextkey())) {
151 
152  //keep only the highest cycle number for each key
153  if (oldkey && !strcmp(oldkey->GetName(),key->GetName())) continue;
154 
155  // read object from first source file
156  first_source->cd( path );
157  TObject *obj = key->ReadObj();
158 
159  auto itphase = phases.begin();
160  int firstfilephase = *itphase;
161 
162  if ( obj->IsA()->InheritsFrom( TH1::Class() ) ) {
163  // descendant of TH1 -> merge it
164  TCanvas c(obj->GetName(),obj->GetName());
165  c.SetFillColor(10);
166 
167  bool is2d = false;
168  if(strstr(obj->ClassName() ,"TH2") != NULL )
169  is2d = true;
170  TH1 *h1 = static_cast<TH1*>(obj);
171 
172  int q = 1;
173  TObjArray *histarray = new TObjArray;
174 
175  h1->SetLineStyle(theStyles.at(q-1));
176  h1->SetLineWidth(2);
177 
178  h1->SetTitle("");
179 
180  h1->SetLineColor(theColors.at(q-1));
181  h1->GetYaxis()->SetTitleOffset(1.5);
182  if(strstr(h1->GetName(),"summary") != NULL )
183  h1->Draw("x0e1*H");
184  else if(is2d)
185  h1->Draw();
186  else
187  h1->Draw();
188 
189  double max = h1->GetMaximum();
190  double scale = 1;
191  if (max > 1000) {
192  int power = (int)(TMath::Log10(max / 100));
193  scale = 1/TMath::Power(10, power);
194  h1->GetYaxis()->SetTitle(((TString(h1->GetYaxis()->GetTitle()) + " [#times 10^{") += (int)power) + "}]");
195  }
196  h1->Scale(scale);
197 
198  int nPlots = sourcelist->GetSize();
199  double legendY = 0.80;
200  if (nPlots > 3) { legendY -= 0.01 * (nPlots - 3); }
201  if (bigtext) { legendY -= 0.05; }
202  if (legendY < 0.6) {
203  std::cerr << "Warning: Huge legend!" << std::endl;
204  legendY = 0.6;
205  }
206  TLegend leg(0.17, legendY, 0.85, 0.88);
207  bool hasheader = (TkAlStyle::legendheader != "");
208  if (hasheader) leg.SetHeader(TkAlStyle::legendheader);
209  if (bigtext) leg.SetTextSize(TkAlStyle::textSize);
210  leg.AddEntry(h1,first_label->String().Data(),"L");
211  leg.SetBorderSize(0);
212  leg.SetFillColor(10);
213  // loop over all source files and add the content of the
214  // correspondant histogram to the one pointed to by "h1"
215  TFile *nextsource = (TFile*)sourcelist->After( first_source );
216  TObjString *nextlabel = (TObjString*)labellist->After( labellist->First() );
217 
218  histarray->Add(h1);
219  while ( nextsource ) {
220 
221  TKey *key2;
222  bool wrongphase = false;
223  ++itphase;
224 
225  if (firstfilephase != *itphase && path.Contains("TrackerOfflineValidationStandalone/Pixel")) {
226  //skip this one
227  key2 = 0;
228  wrongphase = true;
229  } else {
230  // make sure we are at the correct directory level by cd'ing to path
231  nextsource->cd( path );
232  key2 = (TKey*)gDirectory->GetListOfKeys()->FindObject(h1->GetName());
233  }
234  if (key2) {
235  ++q;
236  TH1 *h2 = (TH1*)key2->ReadObj();
237 
238  if(!is2d){
239  h2->SetLineStyle(theStyles.at(q-1));
240  h2->SetLineWidth(2);
241  }
242 
243  h2->SetLineColor(theColors.at(q-1));
244  std::stringstream newname;
245  newname << h2->GetName() << q;
246  h2->Scale(scale);
247 
248  h2->SetName(newname.str().c_str());
249  if(strstr(newname.str().c_str(),"summary") != NULL )
250  h2->DrawClone("x0*He1sames");
251  else if(is2d)
252  h2->DrawClone("sames");
253  else
254  h2->DrawClone("sames");
255  leg.AddEntry(c.FindObject(h2->GetName()),nextlabel->String().Data(),"L");
256  histarray->Add(c.FindObject(h2->GetName()));
257  delete h2;
258  } else if (wrongphase) {
259  //nothing
260  } else {
261  std::cerr << "Histogram "<< key2->GetTitle() << " is not present in file " << nextsource->GetName() << std::endl;
262  }
263 
264  nextsource = (TFile*)sourcelist->After( nextsource );
265  nextlabel = (TObjString*)labellist->After(nextlabel);
266  }
267  nicePad(0,0);
268  leg.Draw();
270  c.Update();
271  if(strstr(h1->GetName(),"summary") == NULL )
272  SetMinMaxRange(histarray);
273  ColourStatsBoxes(histarray);
274  target->cd();
275  c.Update();
276  c.Write();
277  histarray->Delete();
278 
279 
280 
281 
282  } else if ( obj->IsA()->InheritsFrom( TDirectory::Class() ) ) {
283  // it's a subdirectory
284 
285  std::string dirname = obj->GetName();
286  for( std::vector< std::string >::const_iterator lowlevelit = lowestlevels.begin(),
287  lowlevelitend = lowestlevels.end(); lowlevelit != lowlevelitend; ++lowlevelit)
288  if( dirname.find(*lowlevelit) != std::string::npos )
289  return;
290 
291  // create a new subdir of same name and title in the target file
292  target->cd();
293  TDirectory *newdir = target->mkdir( obj->GetName(), obj->GetTitle() );
294 
295  // newdir is now the starting point of another round of merging
296  // newdir still knows its depth within the target file via
297  // GetPath(), so we can still figure out where we are in the recursion
298  MergeRootfile( newdir, sourcelist, labellist, bigtext );
299 
300 
301  } else {
302 
303  // object is of no type that we know or can handle
304  cout << "Unknown object type, name: "
305  << obj->GetName() << " title: " << obj->GetTitle() << endl;
306  }
307 
308 
309  } // while ( ( TKey *key = (TKey*)nextkey() ) )
310 
311  // save modifications to target file
312  target->SaveSelf(kTRUE);
313  TH1::AddDirectory(status);
314 }
315 
316 
317 
318 
319 void nicePad(Int_t logx,Int_t logy)
320 {
321 /*
322  gPad->SetBottomMargin(0.10);
323  gPad->SetRightMargin(0.1);
324  gPad->SetLeftMargin(0.15);
325  gPad->SetTopMargin(0.15);
326  gPad->SetTickx(1);
327  gPad->SetTicky(1);
328 */
329  if(logy==1)
330  {
331  gPad->SetLogy();
332  }
333  else
334  {
335  gPad->SetLogy(0);
336  }
337  if(logx==1)
338  {
339  gPad->SetLogx();
340  }
341  else
342  {
343  gPad->SetLogx(0);
344  }
345 }
346 
347 
348 void ColourStatsBoxes(TObjArray *hists)
349 {
350 
351  Double_t fStatsX1 = 0.85, fStatsX2 = 1., fStatsY1 = 0.77, fStatsY2 = 0.92;
352  // colours stats boxes like hists' line colors and moves the next to each other
353  if (!hists) return;
354  Double_t x1 = fStatsX1, x2 = fStatsX2, y1 = fStatsY1, y2 = fStatsY2;
355  for (Int_t iH = 0; iH < hists->GetEntries(); ++iH) {
356  TH1 *h = static_cast<TH1*>(hists->At(iH));
357  if (!h) continue;
358  TObject *statObj = h->GetListOfFunctions()->FindObject("stats");
359  if (statObj && statObj->InheritsFrom(TPaveStats::Class())) {
360  TPaveStats *stats = static_cast<TPaveStats*>(statObj);
361  stats->SetLineColor(static_cast<TH1*>(hists->At(iH))->GetLineColor());
362  stats->SetTextColor(static_cast<TH1*>(hists->At(iH))->GetLineColor());
363  stats->SetFillColor(10);
364  stats->SetX1NDC(x1);
365  stats->SetX2NDC(x2);
366  stats->SetY1NDC(y1);
367  stats->SetY2NDC(y2);
368  y2 = y1 - 0.005; // shift down 2
369  y1 = y2 - (fStatsY2 - fStatsY1); // shift down 1
370  if (y1 < 0.) {
371  y1 = fStatsY1; y2 = fStatsY2; // restart y-positions
372  x2 = x1 - 0.005; // shift left 2
373  x1 = x2 - (fStatsX2 - fStatsX1); // shift left 1
374  if (x1 < 0.) { // give up, start again:
375  x1 = fStatsX1, x2 = fStatsX2, y1 = fStatsY1, y2 = fStatsY2;
376  }
377  }
378  stats->DrawClone();
379  //} else if (gStyle->GetOptStat() != 0) { // failure in case changed in list via TExec....
380  //this->Warning("ColourStatsBoxes", "No stats found for %s", hists->At(iH)->GetName());
381  }
382  }
383 }
384 
385 
386 void SetMinMaxRange(TObjArray *hists)
387 {
388  Double_t min = 100000;
389  Double_t max = -100000;
390  for (Int_t iH = 0; iH < hists->GetEntries(); ++iH) {
391  TH1 *h = static_cast<TH1*>(hists->At(iH));
392  if (!h) continue;
393  for(int i = 1; i <= h->GetNbinsX(); ++i) {
394  if(h->GetBinContent(i) + h->GetBinError(i) > max ) max = h->GetBinContent(i) + h->GetBinError(i);
395  if(h->GetBinContent(i) - h->GetBinError(i) < min ) min = h->GetBinContent(i) - h->GetBinError(i);
396  }
397  }
398 
399  TH1 *h_first = static_cast<TH1*>(hists->At(0));
400  h_first->SetMaximum(max*1.3);
401  if(min == 0.) {
402  min = -1111;
403  h_first->SetMinimum(min);
404  } else {
405  h_first->SetMinimum(min-min*0.1);
406  }
407 }
std::vector< int > theStyles
std::vector< int > theColors
#define NULL
Definition: scimark2.h:8
static double textSize
Definition: TkAlStyle.cc:104
void ColourStatsBoxes(TObjArray *hists)
static void set(const PublicationStatus status, const Era era=NONE, const TString customTitle="", const TString customRightTitle="")
Definition: TkAlStyle.cc:401
static void drawStandardTitle()
Definition: TkAlStyle.cc:75
void MergeRootfile(TDirectory *target, TList *sourcelist, TList *labellist, bool bigtext)
static TString legendheader
Definition: TkAlStyle.cc:102
TList * LabelList
T min(T a, T b)
Definition: MathUtil.h:58
TFile * Target
void SetMinMaxRange(TObjArray *hists)
std::vector< int > phases
std::vector< std::string > lowestlevels
void compareAlignments(TString namesandlabels="readFromFile", TString legendheader="", TString lefttitle="", TString righttitle="", bool bigtext=false)
void nicePad(Int_t logx, Int_t logy)
TList * FileList