]>
Commit | Line | Data |
---|---|---|
b2a297fa | 1 | /************************************************************************* |
2 | * Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. * | |
3 | * * | |
4 | * Author: The ALICE Off-line Project. * | |
5 | * Contributors are mentioned in the code where appropriate. * | |
6 | * * | |
7 | * Permission to use, copy, modify and distribute this software and its * | |
8 | * documentation strictly for non-commercial purposes is hereby granted * | |
9 | * without fee, provided that the above copyright notice appears in all * | |
10 | * copies and that both the copyright notice and this permission notice * | |
11 | * appear in the supporting documentation. The authors make no claims * | |
12 | * about the suitability of this software for any purpose. It is * | |
13 | * provided "as is" without express or implied warranty. * | |
14 | **************************************************************************/ | |
15 | ||
16 | // | |
17 | // Generic Histogram container with support for groups and filling of groups by passing | |
18 | // a vector of data | |
19 | // | |
20 | // Authors: | |
21 | // Jens Wiechula <Jens.Wiechula@cern.ch> | |
22 | // | |
23 | ||
24 | #include <TH1.h> | |
25 | #include <TH1F.h> | |
26 | #include <TH2.h> | |
27 | #include <TH3.h> | |
28 | #include <TCollection.h> | |
29 | #include <THashList.h> | |
30 | #include <TString.h> | |
31 | #include <TObjArray.h> | |
32 | #include <TFile.h> | |
33 | #include <TError.h> | |
34 | #include <TCanvas.h> | |
35 | #include <TMath.h> | |
36 | #include <TROOT.h> | |
37 | #include <TLegend.h> | |
38 | #include <TKey.h> | |
39 | // #include <TVectorD.h> | |
40 | ||
41 | #include "AliDielectronHistos.h" | |
42 | ||
43 | ||
44 | ClassImp(AliDielectronHistos) | |
45 | ||
46 | ||
47 | AliDielectronHistos::AliDielectronHistos() : | |
48 | // TCollection(), | |
49 | TNamed("AliDielectronHistos","Dielectron Histogram Container"), | |
50 | fHistoList(), | |
51 | fReservedWords(new TString) | |
52 | { | |
53 | // | |
54 | // Default constructor | |
55 | // | |
56 | fHistoList.SetOwner(kTRUE); | |
57 | fHistoList.SetName("Dielectron_Histos"); | |
58 | } | |
59 | ||
60 | //_____________________________________________________________________________ | |
61 | AliDielectronHistos::AliDielectronHistos(const char* name, const char* title) : | |
62 | // TCollection(), | |
63 | TNamed(name, title), | |
64 | fHistoList(), | |
65 | fReservedWords(new TString) | |
66 | { | |
67 | // | |
68 | // TNamed constructor | |
69 | // | |
70 | fHistoList.SetOwner(kTRUE); | |
71 | fHistoList.SetName(name); | |
72 | } | |
73 | ||
74 | //_____________________________________________________________________________ | |
75 | AliDielectronHistos::~AliDielectronHistos() | |
76 | { | |
77 | // | |
78 | // Destructor | |
79 | // | |
80 | fHistoList.Delete(); | |
81 | delete fReservedWords; | |
82 | } | |
83 | ||
84 | //_____________________________________________________________________________ | |
85 | void AliDielectronHistos::UserHistogram(const char* histClass,const char *name, const char* title, | |
86 | Int_t nbinsX, Double_t xmin, Double_t xmax, | |
87 | UInt_t valTypeX) | |
88 | { | |
89 | // | |
90 | // Default histogram creation 1D case | |
91 | // | |
92 | if (!IsHistogramOk(histClass,name)) return; | |
93 | ||
94 | TH1* hist=new TH1F(name,title,nbinsX,xmin,xmax); | |
95 | Bool_t isReserved=fReservedWords->Contains(histClass); | |
96 | if (isReserved) | |
97 | UserHistogramReservedWords(histClass, hist, valTypeX); | |
98 | else | |
99 | UserHistogram(histClass, hist, valTypeX); | |
100 | } | |
101 | ||
102 | //_____________________________________________________________________________ | |
103 | void AliDielectronHistos::UserHistogram(const char* histClass,const char *name, const char* title, | |
104 | Int_t nbinsX, Double_t xmin, Double_t xmax, | |
105 | Int_t nbinsY, Double_t ymin, Double_t ymax, | |
106 | UInt_t valTypeX, UInt_t valTypeY) | |
107 | { | |
108 | // | |
109 | // Default histogram creation 2D case | |
110 | // | |
111 | if (!IsHistogramOk(histClass,name)) return; | |
112 | ||
113 | TH1* hist=new TH2F(name,title,nbinsX,xmin,xmax,nbinsY,ymin,ymax); | |
114 | Bool_t isReserved=fReservedWords->Contains(histClass); | |
115 | if (isReserved) | |
116 | UserHistogramReservedWords(histClass, hist, valTypeX+100*valTypeY); | |
117 | else | |
118 | UserHistogram(histClass, hist, valTypeX+100*valTypeY); | |
119 | } | |
120 | ||
121 | ||
122 | //_____________________________________________________________________________ | |
123 | void AliDielectronHistos::UserHistogram(const char* histClass,const char *name, const char* title, | |
124 | Int_t nbinsX, Double_t xmin, Double_t xmax, | |
125 | Int_t nbinsY, Double_t ymin, Double_t ymax, | |
126 | Int_t nbinsZ, Double_t zmin, Double_t zmax, | |
127 | UInt_t valTypeX, UInt_t valTypeY, UInt_t valTypeZ) | |
128 | { | |
129 | // | |
130 | // Default histogram creation 3D case | |
131 | // | |
132 | if (!IsHistogramOk(histClass,name)) return; | |
133 | ||
134 | TH1* hist=new TH3F(name,title,nbinsX,xmin,xmax,nbinsY,ymin,ymax,nbinsZ,zmin,zmax); | |
135 | Bool_t isReserved=fReservedWords->Contains(histClass); | |
136 | if (isReserved) | |
137 | UserHistogramReservedWords(histClass, hist, valTypeX+100*valTypeY+10000*valTypeZ); | |
138 | else | |
139 | UserHistogram(histClass, hist, valTypeX+100*valTypeY+10000*valTypeZ); | |
140 | } | |
141 | ||
142 | //_____________________________________________________________________________ | |
143 | void AliDielectronHistos::UserHistogram(const char* histClass, TH1* hist, UInt_t valTypes) | |
144 | { | |
145 | // | |
146 | // Add any type of user histogram | |
147 | // | |
148 | ||
149 | //special case for the calss Pair. where histograms will be created for all pair classes | |
150 | Bool_t isReserved=fReservedWords->Contains(histClass); | |
151 | if (isReserved) { | |
152 | UserHistogramReservedWords(histClass, hist, valTypes); | |
153 | return; | |
154 | } | |
155 | ||
156 | if (!IsHistogramOk(histClass,hist->GetName())) return; | |
157 | ||
158 | THashList *classTable=(THashList*)fHistoList.FindObject(histClass); | |
159 | hist->SetDirectory(0); | |
160 | hist->SetUniqueID(valTypes); | |
161 | classTable->Add(hist); | |
162 | } | |
163 | ||
164 | //_____________________________________________________________________________ | |
165 | void AliDielectronHistos::AddClass(const char* histClass) | |
166 | { | |
167 | // | |
168 | // Add a class of histograms | |
169 | // Several classes can be added by separating them by a ';' e.g. 'class1;class2;class3' | |
170 | // | |
171 | TString hists(histClass); | |
172 | TObjArray *arr=hists.Tokenize(";"); | |
173 | TIter next(arr); | |
174 | TObject *o=0; | |
175 | while ( (o=next()) ){ | |
176 | if (fHistoList.FindObject(o->GetName())){ | |
177 | Warning("AddClass","Cannot create class '%s' it already exists.",histClass); | |
178 | continue; | |
179 | } | |
180 | if (fReservedWords->Contains(o->GetName())){ | |
181 | Error("AddClass","Pair is a reserved word, please use another name"); | |
182 | continue; | |
183 | } | |
184 | THashList *table=new THashList; | |
185 | table->SetOwner(kTRUE); | |
186 | table->SetName(o->GetName()); | |
187 | fHistoList.Add(table); | |
188 | } | |
189 | delete arr; | |
190 | } | |
191 | ||
192 | //_____________________________________________________________________________ | |
193 | void AliDielectronHistos::Fill(const char* histClass, const char* name, Double_t xval) | |
194 | { | |
195 | // | |
196 | // Fill function 1D case | |
197 | // | |
198 | THashList *classTable=(THashList*)fHistoList.FindObject(histClass); | |
199 | TH1* hist=0; | |
200 | if (!classTable || !(hist=(TH1*)classTable->FindObject(name)) ){ | |
201 | Warning("Fill","Cannot fill histogram. Either class '%s' or histogram '%s' not existing.",histClass,name); | |
202 | return; | |
203 | } | |
204 | hist->Fill(xval); | |
205 | } | |
206 | ||
207 | //_____________________________________________________________________________ | |
208 | void AliDielectronHistos::Fill(const char* histClass, const char* name, Double_t xval, Double_t yval) | |
209 | { | |
210 | // | |
211 | // Fill function 2D case | |
212 | // | |
213 | THashList *classTable=(THashList*)fHistoList.FindObject(histClass); | |
214 | TH2* hist=0; | |
215 | if (!classTable || !(hist=(TH2*)classTable->FindObject(name)) ){ | |
216 | Warning("UserHistogram","Cannot fill histogram. Either class '%s' or histogram '%s' not existing.",histClass,name); | |
217 | return; | |
218 | } | |
219 | hist->Fill(xval,yval); | |
220 | } | |
221 | ||
222 | //_____________________________________________________________________________ | |
223 | void AliDielectronHistos::Fill(const char* histClass, const char* name, Double_t xval, Double_t yval, Double_t zval) | |
224 | { | |
225 | // | |
226 | // Fill function 3D case | |
227 | // | |
228 | THashList *classTable=(THashList*)fHistoList.FindObject(histClass); | |
229 | TH3* hist=0; | |
230 | if (!classTable || !(hist=(TH3*)classTable->FindObject(name)) ){ | |
231 | Warning("UserHistogram","Cannot fill histogram. Either class '%s' or histogram '%s' not existing.",histClass,name); | |
232 | return; | |
233 | } | |
234 | hist->Fill(xval,yval,zval); | |
235 | } | |
236 | ||
237 | //_____________________________________________________________________________ | |
238 | void AliDielectronHistos::FillClass(const char* histClass, Int_t nValues, const Double_t *values) | |
239 | { | |
240 | // | |
241 | // Fill class 'histClass' (by name) | |
242 | // | |
243 | ||
244 | THashList *classTable=(THashList*)fHistoList.FindObject(histClass); | |
245 | if (!classTable){ | |
246 | Warning("FillClass","Cannot fill class '%s' its not defined.",histClass); | |
247 | return; | |
248 | } | |
249 | ||
250 | TIter nextHist(classTable); | |
251 | TH1 *hist=0; | |
252 | while ( (hist=(TH1*)nextHist()) ){ | |
253 | UInt_t valueTypes=hist->GetUniqueID(); | |
254 | if (valueTypes==(UInt_t)kNoAutoFill) continue; | |
255 | UInt_t value1=valueTypes%100; //last two digits | |
256 | UInt_t value2=valueTypes/100%100; //second last two digits | |
257 | UInt_t value3=valueTypes/10000%100; //third last two digits | |
258 | if (value1>=(UInt_t)nValues||value2>=(UInt_t)nValues||value3>=(UInt_t)nValues) { | |
259 | Warning("FillClass","One of the values is out of range. Not filling histogram '%s/%s'.", histClass, hist->GetName()); | |
260 | continue; | |
261 | } | |
262 | switch (hist->GetDimension()){ | |
263 | case 1: | |
264 | hist->Fill(values[value1]); | |
265 | break; | |
266 | case 2: | |
267 | ((TH2*)hist)->Fill(values[value1],values[value2]); | |
268 | break; | |
269 | case 3: | |
270 | ((TH3*)hist)->Fill(values[value1],values[value2],values[value3]); | |
271 | break; | |
272 | } | |
273 | } | |
274 | } | |
275 | ||
276 | //_____________________________________________________________________________ | |
277 | // void AliDielectronHistos::FillClass(const char* histClass, const TVectorD &vals) | |
278 | // { | |
279 | // // | |
280 | // // | |
281 | // // | |
282 | // FillClass(histClass, vals.GetNrows(), vals.GetMatrixArray()); | |
283 | // } | |
284 | ||
285 | //_____________________________________________________________________________ | |
286 | void AliDielectronHistos::UserHistogramReservedWords(const char* histClass, TH1 *hist, UInt_t valTypes) | |
287 | { | |
288 | // | |
289 | // Creation of histogram for all pair types | |
290 | // | |
291 | TString title(hist->GetTitle()); | |
292 | // Same Event Like Sign | |
293 | TIter nextClass(&fHistoList); | |
294 | THashList *l=0; | |
295 | while ( (l=static_cast<THashList*>(nextClass())) ){ | |
296 | TString name(l->GetName()); | |
297 | if (name.Contains(histClass)){ | |
298 | TH1 *h=static_cast<TH1*>(hist->Clone()); | |
299 | h->SetDirectory(0); | |
300 | h->SetTitle(Form("%s %s",title.Data(),l->GetName())); | |
301 | UserHistogram(l->GetName(),h,valTypes); | |
302 | } | |
303 | } | |
304 | delete hist; | |
305 | } | |
306 | ||
307 | //_____________________________________________________________________________ | |
308 | void AliDielectronHistos::DumpToFile(const char* file) | |
309 | { | |
310 | // | |
311 | // Dump the histogram list to a newly created root file | |
312 | // | |
313 | TFile f(file,"recreate"); | |
314 | fHistoList.Write(fHistoList.GetName(),TObject::kSingleKey); | |
315 | f.Close(); | |
316 | } | |
317 | ||
318 | //_____________________________________________________________________________ | |
319 | TH1* AliDielectronHistos::GetHistogram(const char* histClass, const char* name) const | |
320 | { | |
321 | // | |
322 | // return histogram 'name' in 'histClass' | |
323 | // | |
324 | THashList *classTable=(THashList*)fHistoList.FindObject(histClass); | |
325 | if (!classTable) return 0x0; | |
326 | return (TH1*)classTable->FindObject(name); | |
327 | } | |
328 | ||
329 | //_____________________________________________________________________________ | |
330 | void AliDielectronHistos::Draw(const Option_t* option) | |
331 | { | |
332 | // | |
333 | // Draw histograms | |
334 | // | |
335 | ||
37e9382d | 336 | TString drawStr(option); |
337 | drawStr.ToLower(); | |
b2a297fa | 338 | //options |
339 | // Bool_t same=drawOpt.Contains("same"); //FIXME not yet implemented | |
340 | ||
341 | TIter nextClass(&fHistoList); | |
342 | THashList *classTable=0; | |
343 | while ( (classTable=(THashList*)nextClass()) ){ | |
344 | //optimised division | |
345 | Int_t nPads = classTable->GetEntries(); | |
346 | Int_t nCols = (Int_t)TMath::Ceil( TMath::Sqrt(nPads) ); | |
347 | Int_t nRows = (Int_t)TMath::Ceil( (Double_t)nPads/(Double_t)nCols ); | |
348 | ||
349 | //create canvas | |
350 | TString canvasName; | |
351 | canvasName.Form("c%s",classTable->GetName()); | |
352 | TCanvas *c=(TCanvas*)gROOT->FindObject(canvasName.Data()); | |
353 | if (!c) c=new TCanvas(canvasName.Data(),classTable->GetName()); | |
354 | c->Clear(); | |
355 | c->Divide(nCols,nRows); | |
356 | ||
357 | //loop over histograms and draw them | |
358 | TIter nextHist(classTable); | |
359 | Int_t iPad=0; | |
360 | TH1 *h=0; | |
361 | while ( (h=(TH1*)nextHist()) ){ | |
362 | TString drawOpt; | |
363 | if ( (h->InheritsFrom(TH2::Class())) ) drawOpt="colz"; | |
364 | c->cd(++iPad); | |
365 | h->Draw(drawOpt.Data()); | |
366 | } | |
367 | } | |
368 | } | |
369 | ||
370 | //_____________________________________________________________________________ | |
371 | void AliDielectronHistos::Print(const Option_t* option) const | |
372 | { | |
373 | // | |
374 | // Print classes and histograms | |
375 | // | |
376 | TString optString(option); | |
377 | ||
378 | if (optString.IsNull()) PrintStructure(); | |
379 | ||
380 | ||
381 | ||
382 | } | |
383 | ||
384 | //_____________________________________________________________________________ | |
385 | void AliDielectronHistos::PrintStructure() const | |
386 | { | |
387 | // | |
388 | // Print classes and histograms in the class to stdout | |
389 | // | |
390 | TIter nextClass(&fHistoList); | |
391 | THashList *classTable=0; | |
392 | while ( (classTable=(THashList*)nextClass()) ){ | |
393 | TIter nextHist(classTable); | |
394 | TObject *o=0; | |
395 | printf("+ %s\n",classTable->GetName()); | |
396 | while ( (o=nextHist()) ) | |
397 | printf("| ->%s\n",o->GetName()); | |
398 | } | |
399 | ||
400 | } | |
401 | ||
402 | //_____________________________________________________________________________ | |
403 | void AliDielectronHistos::SetHistogramList(THashList &list) | |
404 | { | |
405 | // | |
406 | // set histogram classes and histograms to this instance. It will take onwnership! | |
407 | // | |
408 | TIter next(&list); | |
409 | TObject *o; | |
410 | while ( (o=next()) ){ | |
411 | fHistoList.Add(o); | |
412 | } | |
413 | list.SetOwner(kFALSE); | |
414 | fHistoList.SetOwner(kTRUE); | |
415 | } | |
416 | ||
417 | //_____________________________________________________________________________ | |
418 | Bool_t AliDielectronHistos::IsHistogramOk(const char* histClass, const char* name) | |
419 | { | |
420 | // | |
421 | // check whether the histogram class exists and the histogram itself does not exist yet | |
422 | // | |
423 | Bool_t isReserved=fReservedWords->Contains(histClass); | |
424 | if (!fHistoList.FindObject(histClass)&&!isReserved){ | |
425 | Warning("IsHistogramOk","Cannot create histogram. Class '%s' not defined. Please create it using AddClass before.",histClass); | |
426 | return kFALSE; | |
427 | } | |
428 | if (GetHistogram(histClass,name)){ | |
429 | Warning("IsHistogramOk","Cannot create histogram '%s' in class '%s': It already exists!",name,histClass); | |
430 | return kFALSE; | |
431 | } | |
432 | return kTRUE; | |
433 | } | |
434 | ||
435 | // //_____________________________________________________________________________ | |
436 | // TIterator* AliDielectronHistos::MakeIterator(Bool_t dir) const | |
437 | // { | |
438 | // // | |
439 | // // | |
440 | // // | |
441 | // return new TListIter(&fHistoList, dir); | |
442 | // } | |
443 | ||
444 | //_____________________________________________________________________________ | |
445 | void AliDielectronHistos::ReadFromFile(const char* file) | |
446 | { | |
447 | // | |
448 | // Read histos from file | |
449 | // | |
450 | TFile f(file); | |
451 | TIter nextKey(f.GetListOfKeys()); | |
452 | TKey *key=0; | |
453 | while ( (key=(TKey*)nextKey()) ){ | |
454 | TObject *o=f.Get(key->GetName()); | |
455 | THashList *list=dynamic_cast<THashList*>(o); | |
456 | if (!list) continue; | |
457 | SetHistogramList(*list); | |
458 | break; | |
459 | } | |
460 | f.Close(); | |
461 | } | |
462 | ||
463 | void AliDielectronHistos::DrawSame(const char* histName, const Option_t *opt) | |
464 | { | |
465 | // | |
466 | // Draw all histograms with the same name into one canvas | |
467 | // if option contains 'leg' a legend will be created with the class name as caption | |
468 | // if option contains 'can' a new canvas is created | |
469 | // | |
470 | ||
471 | TString optString(opt); | |
472 | optString.ToLower(); | |
473 | Bool_t optLeg=optString.Contains("leg"); | |
474 | Bool_t optCan=optString.Contains("can"); | |
475 | ||
476 | TLegend *leg=0; | |
477 | TCanvas *c=0; | |
478 | if (optCan){ | |
479 | c=(TCanvas*)gROOT->FindObject(Form("c%s",histName)); | |
480 | if (!c) c=new TCanvas(Form("c%s",histName),Form("All '%s' histograms",histName)); | |
481 | c->Clear(); | |
482 | c->cd(); | |
483 | } | |
484 | ||
485 | if (optLeg) leg=new TLegend(.8,.3,.99,.9); | |
486 | ||
487 | Int_t i=0; | |
488 | TIter next(&fHistoList); | |
489 | THashList *classTable=0; | |
490 | Double_t max=-1e10; | |
491 | TH1 *hFirst=0x0; | |
492 | while ( (classTable=(THashList*)next()) ){ | |
493 | if ( TH1 *h=(TH1*)classTable->FindObject(histName) ){ | |
494 | if (i==0) hFirst=h; | |
495 | h->SetLineColor(i+1); | |
496 | h->SetMarkerColor(i+1); | |
497 | h->Draw(i>0?"same":""); | |
498 | if (leg) leg->AddEntry(h,classTable->GetName(),"lp"); | |
499 | ++i; | |
500 | max=TMath::Max(max,h->GetMaximum()); | |
501 | } | |
502 | } | |
503 | if (leg){ | |
504 | leg->SetFillColor(10); | |
505 | leg->SetY1(.9-i*.05); | |
506 | leg->Draw(); | |
507 | } | |
508 | if (hFirst&&(hFirst->GetYaxis()->GetXmax()<max)){ | |
509 | hFirst->SetMaximum(max); | |
510 | } | |
511 | } | |
512 | ||
513 | //_____________________________________________________________________________ | |
514 | void AliDielectronHistos::SetReservedWords(const char* words) | |
515 | { | |
516 | // | |
517 | // set reserved words | |
518 | // | |
519 | ||
520 | (*fReservedWords)=words; | |
521 | } | |
522 |