Corrected UInt_t <-> Int_t conversion
[u/mrichter/AliRoot.git] / TPC / AliTPCCalibViewer.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, 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 ///////////////////////////////////////////////////////////////////////////////
18 //                                                                           //
19 //  Class for viewing/visualizing TPC calibration data                       //
20 //  base on  TTree functionality for visualization                           //
21 //                                                                           //
22 //  Create a list of AliTPCCalPads, arrange them in an TObjArray.            //
23 //  Pass this TObjArray to MakeTree and create the calibration Tree          //
24 //  While craating this tree some statistical information are calculated     //
25 //  Open the viewer with this Tree: AliTPCCalibViewer v("CalibTree.root")    //
26 //  Have fun!                                                                //
27 //  EasyDraw("CETmean~-CETmean_mean", "A", "(CETmean~-CETmean_mean)>0")      //
28 //                                                                           //
29 //  If you like to click, we recommand you the                               //
30 //    AliTPCCalibViewerGUI                                                   //
31 //                                                                           //
32 //    THE DOCUMENTATION IS STILL NOT COMPLETED !!!!                          //
33 //                                                                           //
34 ///////////////////////////////////////////////////////////////////////////////
35
36 //
37 // ROOT includes 
38 //
39
40 #include <fstream>
41 #include <iostream>
42
43 #include <TFile.h>
44 #include <TFriendElement.h>
45 #include <TGraph.h>
46 #include <TKey.h>
47 #include <TPad.h>
48 //#include <TCanvas.h>
49 #include <TH1.h> 
50 #include <TH1F.h>
51 #include <TLegend.h>
52 #include <TLine.h>
53 #include <TMath.h>
54 #include <TObjString.h>
55 //#include <TROOT.h>
56 #include <TRandom.h>
57 #include <TString.h>
58 #include <TStyle.h>
59 #include <TTreeStream.h>
60
61 #include "AliTPCCalibCE.h"
62 #include "AliMathBase.h"
63 #include "AliTPCCalPad.h"
64 #include "AliTPCCalROC.h"
65 #include "AliTPCCalibPedestal.h"
66 #include "AliTPCCalibPulser.h"
67
68 //
69 // AliRoot includes
70 //
71 #include "AliTPCCalibViewer.h"
72
73 ClassImp(AliTPCCalibViewer)
74
75
76 AliTPCCalibViewer::AliTPCCalibViewer()
77                   :TObject(),
78                    fTree(0),
79                    fFile(0),
80                    fListOfObjectsToBeDeleted(0),
81                    fTreeMustBeDeleted(0), 
82                    fAbbreviation(0), 
83                    fAppendString(0)
84 {
85   //
86   // Default constructor
87   //
88
89 }
90
91 //_____________________________________________________________________________
92 AliTPCCalibViewer::AliTPCCalibViewer(const AliTPCCalibViewer &c)
93                   :TObject(c),
94                    fTree(0),
95                    fFile(0),
96                    fListOfObjectsToBeDeleted(0),
97                    fTreeMustBeDeleted(0),
98                    fAbbreviation(0), 
99                    fAppendString(0)
100 {
101   //
102   // dummy AliTPCCalibViewer copy constructor
103   // not yet working!!!
104   //
105   fTree = c.fTree;
106   fTreeMustBeDeleted = c.fTreeMustBeDeleted;
107   //fFile = new TFile(*(c.fFile));
108   fListOfObjectsToBeDeleted = c.fListOfObjectsToBeDeleted;
109   fAbbreviation = c.fAbbreviation;
110   fAppendString = c.fAppendString;
111 }
112
113 //_____________________________________________________________________________
114 AliTPCCalibViewer::AliTPCCalibViewer(TTree *const tree)
115                   :TObject(),
116                    fTree(0),
117                    fFile(0),
118                    fListOfObjectsToBeDeleted(0),
119                    fTreeMustBeDeleted(0),
120                    fAbbreviation(0), 
121                    fAppendString(0)
122 {
123   //
124   // Constructor that initializes the calibration viewer
125   //
126   fTree = tree;
127   fTreeMustBeDeleted = kFALSE;
128   fListOfObjectsToBeDeleted = new TObjArray();
129   fAbbreviation = "~";
130   fAppendString = ".fElements";
131 }
132
133 //_____________________________________________________________________________
134 AliTPCCalibViewer::AliTPCCalibViewer(const char* fileName, const char* treeName)
135                   :TObject(),
136                    fTree(0),
137                    fFile(0),
138                    fListOfObjectsToBeDeleted(0),
139                    fTreeMustBeDeleted(0),
140                    fAbbreviation(0), 
141                    fAppendString(0)
142                    
143 {
144    //
145    // Constructor to initialize the calibration viewer
146    // the file 'fileName' contains the tree 'treeName'
147    //
148    fFile = new TFile(fileName, "read");
149    fTree = (TTree*) fFile->Get(treeName);
150    fTreeMustBeDeleted = kTRUE;
151    fListOfObjectsToBeDeleted = new TObjArray();
152    fAbbreviation = "~";
153    fAppendString = ".fElements";
154 }
155                    
156 //____________________________________________________________________________
157 AliTPCCalibViewer & AliTPCCalibViewer::operator =(const AliTPCCalibViewer & param)
158 {
159    //
160    // assignment operator - dummy
161    // not yet working!!!
162    //
163    fTree = param.fTree;
164    fTreeMustBeDeleted = param.fTreeMustBeDeleted;
165    //fFile = new TFile(*(param.fFile));
166    fListOfObjectsToBeDeleted = param.fListOfObjectsToBeDeleted;
167    fAbbreviation = param.fAbbreviation;
168    fAppendString = param.fAppendString;
169    return (*this);
170 }
171
172 //_____________________________________________________________________________
173 AliTPCCalibViewer::~AliTPCCalibViewer()
174 {
175    //
176    // AliTPCCalibViewer destructor
177    // all objects will be deleted, the file will be closed, the pictures will disappear
178    //
179    if (fTree && fTreeMustBeDeleted) {
180       fTree->SetCacheSize(0);
181       fTree->Delete();
182       //delete fTree;
183    }
184    if (fFile) {
185       fFile->Close();
186       fFile = 0;
187    }
188
189    for (Int_t i = fListOfObjectsToBeDeleted->GetEntriesFast()-1; i >= 0; i--) {
190       //cout << "Index " << i << " trying to delete the following object: " << fListOfObjectsToBeDeleted->At(i)->GetName() << "..."<< endl;
191       delete fListOfObjectsToBeDeleted->At(i);
192    }
193    delete fListOfObjectsToBeDeleted;
194 }
195
196 //_____________________________________________________________________________
197 void AliTPCCalibViewer::Delete(Option_t* option) {
198    //
199    // Should be called from AliTPCCalibViewerGUI class only.
200    // If you use Delete() do not call the destructor.
201    // All objects (except those contained in fListOfObjectsToBeDeleted) will be deleted, the file will be closed.
202    //
203    
204    option = option;  // to avoid warnings on compiling   
205    if (fTree && fTreeMustBeDeleted) {
206       fTree->SetCacheSize(0);
207       fTree->Delete();
208    }
209    if (fFile)
210       delete fFile;
211    delete fListOfObjectsToBeDeleted;
212 }
213
214
215 const char* AliTPCCalibViewer::AddAbbreviations(const Char_t *c, Bool_t printDrawCommand){ 
216    // Replace all "<variable>" with "<variable><fAbbreviation>" (Adds forgotten "~")
217    // but take care on the statistical information, like "CEQmean_Mean"
218    // and also take care on correct given variables, like "CEQmean~"
219    // 
220    // For each variable out of "listOfVariables":
221    // - 'Save' correct items:
222    //   - form <replaceString>, take <variable>'s first char, add <removeString>, add rest of <variable>, e.g. "C!#EQmean" (<removeString> = "!#")
223    //   - For each statistical information in "listOfNormalizationVariables":
224    //     - ReplaceAll <variable><statistical_Information> with <replaceString><statistical_Information>
225    //   - ReplaceAll <variable><abbreviation> with <replaceString><abbreviation>, e.g. "CEQmean~" -> "C!#EQmean~"
226    //   - ReplaceAll <variable><appendStr> with <replaceString><appendStr>, e.g. "CEQmean.fElements" -> "C!#EQmean.fElements"
227    //
228    // - Do actual replacing:
229    //   - ReplaceAll <variable> with <variable><fAbbreviation>, e.g. "CEQmean" -> "CEQmean~"
230    //
231    // - Undo saving:
232    //   - For each statistical information in "listOfNormalizationVariables":
233    //     - ReplaceAll <replaceString><statistical_Information> with <variable><statistical_Information> 
234    //   - ReplaceAll <replaceString><abbreviation> with <variable><abbreviation>, e.g. "C!#EQmean~" -> "CEQmean~"
235    //   - ReplaceAll <replaceString><appendStr> with <variable><appendStr>, e.g. "C!#EQmean.fElements" -> "CEQmean.fElements"
236    // 
237    // Now all the missing "~" should be added.
238    
239    TString str(c);
240    TString removeString = "!#";  // very unpropable combination of chars
241    TString replaceString = "";
242    TString searchString = "";
243    TString normString = "";
244    TObjArray *listOfVariables = GetListOfVariables();
245    listOfVariables->Add(new TObjString("channel"));
246    listOfVariables->Add(new TObjString("gx"));
247    listOfVariables->Add(new TObjString("gy"));
248    listOfVariables->Add(new TObjString("lx"));
249    listOfVariables->Add(new TObjString("ly"));
250    listOfVariables->Add(new TObjString("pad"));
251    listOfVariables->Add(new TObjString("row"));
252    listOfVariables->Add(new TObjString("rpad"));
253    listOfVariables->Add(new TObjString("sector"));
254    TObjArray *listOfNormalizationVariables = GetListOfNormalizationVariables();
255    Int_t nVariables = listOfVariables->GetEntriesFast();
256    Int_t nNorm = listOfNormalizationVariables->GetEntriesFast();
257    
258    Int_t *varLengths = new Int_t[nVariables];
259    for (Int_t i = 0; i < nVariables; i++) {
260       varLengths[i] = ((TObjString*)listOfVariables->At(i))->String().Length();
261    }
262    Int_t *normLengths = new Int_t[nNorm];
263    for (Int_t i = 0; i < nNorm; i++) {
264       normLengths[i] = ((TObjString*)listOfNormalizationVariables->At(i))->String().Length();
265       // printf("normLengths[%i] (%s) = %i \n", i,((TObjString*)listOfNormalizationVariables->At(i))->String().Data(), normLengths[i]);
266    }
267    Int_t *varSort = new Int_t[nVariables];
268    TMath::Sort(nVariables, varLengths, varSort, kTRUE);
269    Int_t *normSort = new Int_t[nNorm];
270    TMath::Sort(nNorm, normLengths, normSort, kTRUE);
271    // for (Int_t i = 0; i<nNorm; i++)  printf("normLengths: %i\n", normLengths[normSort[i]]);
272    // for (Int_t i = 0; i<nVariables; i++) printf("varLengths: %i\n", varLengths[varSort[i]]);
273    
274    for (Int_t ivar = 0; ivar < nVariables; ivar++) {
275       // ***** save correct tokens *****
276       // first get the next variable:
277       searchString = ((TObjString*)listOfVariables->At(varSort[ivar]))->String();
278       // printf("searchString: %s ++++++++++++++\n", searchString.Data());
279       // form replaceString:
280       replaceString = "";
281       for (Int_t i = 0; i < searchString.Length(); i++) {
282          replaceString.Append(searchString[i]);
283          if (i == 0) replaceString.Append(removeString);
284       }
285       // go through normalization:
286       // printf("go through normalization\n");
287       for (Int_t inorm = 0; inorm < nNorm; inorm++) {
288          // printf(" inorm=%i, nNorm=%i, normSort[inorm]=%i \n", inorm, nNorm, normSort[inorm]);
289          normString = ((TObjString*)listOfNormalizationVariables->At(normSort[inorm]))->String();
290          // printf(" walking in normalization, i=%i, normString=%s \n", inorm, normString.Data());
291          str.ReplaceAll(searchString + normString, replaceString + normString);
292          // like: str.ReplaceAll("CEQmean_Mean", "C!EQmean_Mean");
293       }
294       str.ReplaceAll(searchString + fAbbreviation, replaceString + fAbbreviation);
295       // like: str.ReplaceAll("CEQmean~", "C!EQmean~");
296       str.ReplaceAll(searchString + fAppendString,    replaceString + fAppendString);
297       // like: str.ReplaceAll("CEQmean.fElements", "C!EQmean.fElements");
298       
299       // ***** add missing extensions *****
300       str.ReplaceAll(searchString, replaceString + fAbbreviation);
301       // like: str.ReplaceAll("CEQmean", "C!EQmean~");
302    }
303    
304    // ***** undo saving *****
305    str.ReplaceAll(removeString, "");
306   
307    if (printDrawCommand) std::cout << "The string looks now like: " << str.Data() << std::endl;
308    delete [] varLengths;
309    delete [] normLengths;
310    delete [] varSort;
311    delete [] normSort;
312    return str.Data();
313 }
314
315
316
317
318 //_____________________________________________________________________________
319 Int_t AliTPCCalibViewer::EasyDraw(const char* drawCommand, const char* sector, const char* cuts, const char* drawOptions, Bool_t writeDrawCommand) const {
320   //
321   // easy drawing of data, use '~' for abbreviation of '.fElements'
322   // example: EasyDraw("CETmean~-CETmean_mean", "A", "(CETmean~-CETmean_mean)>0")
323  // sector: sector-number - only the specified sector will be drwawn
324   //         'A'/'C' or 'a'/'c' - side A/C will be drawn
325   //         'ALL' - whole TPC will be drawn, projected on one side
326   // cuts: specifies cuts
327   // drawOptions: draw options like 'same'
328   // writeDrawCommand: write the command, that is passed to TTree::Draw
329   //
330
331    TString drawStr(drawCommand);
332    TString sectorStr(sector);
333    sectorStr.ToUpper();
334    TString cutStr("");
335    //TString drawOptionsStr("profcolz ");
336    Bool_t dangerousToDraw = drawStr.Contains(":") || drawStr.Contains(">>");
337    if (dangerousToDraw) {
338       Warning("EasyDraw", "The draw string must not contain ':' or '>>'. Using only first variable for drawing!");
339 //      return -1;
340 //      drawStr.Resize(drawStr.First(">"));
341       drawStr.Resize(drawStr.First(":"));
342    }
343
344    TString drawOptionsStr("");
345    TRandom rnd(0);
346    Int_t rndNumber = rnd.Integer(10000);
347
348    if (drawOptions && strcmp(drawOptions, "") != 0)
349       drawOptionsStr += drawOptions;
350    else
351       drawOptionsStr += "profcolz";
352
353    if (sectorStr == "A") {
354       drawStr += Form(":gy%s:gx%s>>prof", fAppendString.Data(), fAppendString.Data());
355       drawStr += rndNumber;
356       drawStr += "(330,-250,250,330,-250,250)";
357       cutStr += "(sector/18)%2==0 ";
358    }
359    else if  (sectorStr == "C") {
360       drawStr += Form(":gy%s:gx%s>>prof", fAppendString.Data(), fAppendString.Data());
361       drawStr += rndNumber;
362       drawStr += "(330,-250,250,330,-250,250)";
363       cutStr += "(sector/18)%2==1 ";
364    }
365    else if  (sectorStr == "ALL") {
366       drawStr += Form(":gy%s:gx%s>>prof", fAppendString.Data(), fAppendString.Data());
367       drawStr += rndNumber;
368       drawStr += "(330,-250,250,330,-250,250)";
369    }
370    else if  (sectorStr.Contains("S")) {
371       drawStr += Form(":rpad%s:row%s+(sector>35)*63>>prof", fAppendString.Data(), fAppendString.Data());
372       drawStr += rndNumber;
373       drawStr += "(159,0,159,140,-70,70)";
374       TString sec=sectorStr;
375       sec.Remove(0,1);
376       cutStr += "sector%36=="+sec+" ";
377    }
378    else if (sectorStr.IsDigit()) {
379       Int_t isec = sectorStr.Atoi();
380       drawStr += Form(":rpad%s:row%s>>prof", fAppendString.Data(), fAppendString.Data());
381       drawStr += rndNumber;
382       if (isec < 36 && isec >= 0)
383          drawStr += "(63,0,63,108,-54,54)";
384       else if (isec < 72 && isec >= 36)
385          drawStr += "(96,0,96,140,-70,70)";
386       else {
387          Error("EasyDraw","The TPC contains only sectors between 0 and 71.");
388          return -1;
389       }
390       cutStr += "(sector==";
391       cutStr += isec;
392       cutStr += ") ";
393    }
394
395    if (cuts && cuts[0] != 0) {
396       if (cutStr.Length() != 0) cutStr += "&& ";
397       cutStr += "(";
398       cutStr += cuts;
399       cutStr += ")";
400    }
401    drawStr.ReplaceAll(fAbbreviation, fAppendString);
402    cutStr.ReplaceAll(fAbbreviation, fAppendString);
403    if (writeDrawCommand) std::cout << "fTree->Draw(\"" << drawStr << "\", \"" <<  cutStr << "\", \"" << drawOptionsStr << "\");" << std::endl;
404    Int_t returnValue = fTree->Draw(drawStr.Data(), cutStr.Data(), drawOptionsStr.Data());
405    TString profName("prof");
406    profName += rndNumber;
407    TObject *obj = gDirectory->Get(profName.Data());
408    if (obj && obj->InheritsFrom("TH1")) FormatHistoLabels((TH1*)obj);
409    return returnValue;
410 }
411
412
413 Int_t AliTPCCalibViewer::EasyDraw(const char* drawCommand, Int_t sector, const char* cuts, const char* drawOptions, Bool_t writeDrawCommand) const {
414   //
415   // easy drawing of data, use '~' for abbreviation of '.fElements'
416   // example: EasyDraw("CETmean~-CETmean_mean", 34, "(CETmean~-CETmean_mean)>0")
417   // sector: sector-number - only the specified sector will be drwawn
418   // cuts: specifies cuts
419   // drawOptions: draw options like 'same'
420   // writeDrawCommand: write the command, that is passed to TTree::Draw
421   //
422    if (sector >= 0 && sector < 72) {
423       return EasyDraw(drawCommand, Form("%i", sector), cuts, drawOptions, writeDrawCommand);
424    }
425    Error("EasyDraw","The TPC contains only sectors between 0 and 71.");
426    return -1;
427 }
428
429
430 //_____________________________________________________________________________
431 Int_t AliTPCCalibViewer::EasyDraw1D(const char* drawCommand, const char* sector, const char* cuts, const char* drawOptions, Bool_t writeDrawCommand) const {
432   //
433   // easy drawing of data, use '~' for abbreviation of '.fElements'
434   // example: EasyDraw("CETmean~-CETmean_mean", "A", "(CETmean~-CETmean_mean)>0")
435   // sector: sector-number - the specified sector will be drwawn
436   //         'A'/'C' or 'a'/'c' - side A/C will be drawn
437   //         'ALL' - whole TPC will be drawn, projected on one side
438   // cuts: specifies cuts
439   // drawOptions: draw options like 'same'
440   // writeDrawCommand: write the command, that is passed to TTree::Draw
441   //
442
443    TString drawStr(drawCommand);
444    TString sectorStr(sector);
445    TString drawOptionsStr(drawOptions);
446    sectorStr.ToUpper();
447    TString cutStr("");
448
449    if (sectorStr == "A")
450       cutStr += "(sector/18)%2==0 ";
451    else if  (sectorStr == "C")
452       cutStr += "(sector/18)%2==1 ";
453    else if (sectorStr.IsDigit()) {
454       Int_t isec = sectorStr.Atoi();
455       if (isec < 0 || isec > 71) {
456          Error("EasyDraw","The TPC contains only sectors between 0 and 71.");
457          return -1;
458       }
459       cutStr += "(sector==";
460       cutStr += isec;
461       cutStr += ") ";
462    }
463    else if  (sectorStr.Contains("S")) {
464       TString sec=sectorStr;
465       sec.Remove(0,1);
466       cutStr += "sector%36=="+sec+" ";
467    }
468
469    if (cuts && cuts[0] != 0) {
470       if (cutStr.Length() != 0) cutStr += "&& ";
471       cutStr += "(";
472       cutStr += cuts;
473       cutStr += ")";
474    }
475
476    drawStr.ReplaceAll(fAbbreviation, fAppendString);
477    cutStr.ReplaceAll(fAbbreviation, fAppendString);
478    if (writeDrawCommand) std::cout << "fTree->Draw(\"" << drawStr << "\", \"" <<  cutStr << "\", \"" << drawOptionsStr << "\");" << std::endl;
479    Int_t returnValue = fTree->Draw(drawStr.Data(), cutStr.Data(), drawOptionsStr.Data());
480    if (returnValue == -1) return -1;
481    
482    TObject *obj = (gPad) ? gPad->GetPrimitive("htemp") : 0; 
483    if (!obj) obj = (TH1F*)gDirectory->Get("htemp");
484    if (!obj) obj = gPad->GetPrimitive("tempHist");
485    if (!obj) obj = (TH1F*)gDirectory->Get("tempHist");
486    if (!obj) obj = gPad->GetPrimitive("Graph");
487    if (!obj) obj = (TH1F*)gDirectory->Get("Graph");
488    if (obj && obj->InheritsFrom("TH1")) FormatHistoLabels((TH1*)obj);
489    return returnValue;
490 }
491
492
493 Int_t AliTPCCalibViewer::EasyDraw1D(const char* drawCommand, Int_t sector, const char* cuts, const char* drawOptions, Bool_t writeDrawCommand) const {
494   //
495   // easy drawing of data, use '~' for abbreviation of '.fElements'
496   // example: EasyDraw("CETmean~-CETmean_mean", 34, "(CETmean~-CETmean_mean)>0")
497   // sector: sector-number - the specified sector will be drwawn
498   // cuts: specifies cuts
499   // drawOptions: draw options like 'same'
500   // writeDrawCommand: write the command, that is passed to TTree::Draw
501   //
502
503    if (sector >= 0 && sector < 72) {
504       return EasyDraw1D(drawCommand, Form("%i",sector), cuts, drawOptions, writeDrawCommand);
505    }
506   Error("EasyDraw","The TPC contains only sectors between 0 and 71.");
507   return -1;
508 }
509
510
511 void AliTPCCalibViewer::FormatHistoLabels(TH1 *histo) const {
512    // 
513    // formats title and axis labels of histo 
514    // removes '.fElements'
515    // 
516    if (!histo) return;
517    TString replaceString(fAppendString.Data());
518    TString *str = new TString(histo->GetTitle());
519    str->ReplaceAll(replaceString, "");
520    histo->SetTitle(str->Data());
521    delete str;
522    if (histo->GetXaxis()) {
523       str = new TString(histo->GetXaxis()->GetTitle());
524       str->ReplaceAll(replaceString, "");
525       histo->GetXaxis()->SetTitle(str->Data());
526       delete str;
527    }
528    if (histo->GetYaxis()) {
529       str = new TString(histo->GetYaxis()->GetTitle());
530       str->ReplaceAll(replaceString, "");
531       histo->GetYaxis()->SetTitle(str->Data());
532       delete str;
533    }
534    if (histo->GetZaxis()) {
535       str = new TString(histo->GetZaxis()->GetTitle());
536       str->ReplaceAll(replaceString, "");
537       histo->GetZaxis()->SetTitle(str->Data());
538       delete str;
539    }
540 }
541
542
543 Int_t  AliTPCCalibViewer::DrawHisto1D(const char* drawCommand, Int_t sector, const char* cuts, const char *sigmas, Bool_t plotMean, Bool_t plotMedian, Bool_t plotLTM) const {
544    // 
545    // Easy drawing of data, in principle the same as EasyDraw1D
546    // Difference: A line for the mean / median / LTM is drawn 
547    // in 'sigmas' you can specify in which distance to the mean/median/LTM you want to see a line in sigma-units, separated by ';'
548    // example: sigmas = "2; 4; 6;"  at Begin_Latex 2 #sigma End_Latex, Begin_Latex 4 #sigma End_Latex and Begin_Latex 6 #sigma End_Latex  a line is drawn.
549    // "plotMean", "plotMedian" and "plotLTM": what kind of lines do you want to see?
550    // 
551    if (sector >= 0 && sector < 72) {
552       return DrawHisto1D(drawCommand, Form("%i", sector), cuts, sigmas, plotMean, plotMedian, plotLTM);
553    }
554    Error("DrawHisto1D","The TPC contains only sectors between 0 and 71.");
555    return -1;
556 }   
557
558
559 Int_t  AliTPCCalibViewer::DrawHisto1D(const char* drawCommand, const char* sector, const char* cuts, const char *sigmas, Bool_t plotMean, Bool_t plotMedian, Bool_t plotLTM) const {
560    // 
561    // Easy drawing of data, in principle the same as EasyDraw1D
562    // Difference: A line for the mean / median / LTM is drawn 
563    // in 'sigmas' you can specify in which distance to the mean/median/LTM you want to see a line in sigma-units, separated by ';'
564    // example: sigmas = "2; 4; 6;"  at Begin_Latex 2 #sigma End_Latex, Begin_Latex 4 #sigma End_Latex and Begin_Latex 6 #sigma End_Latex  a line is drawn.
565    // "plotMean", "plotMedian" and "plotLTM": what kind of lines do you want to see?
566    // 
567    Int_t oldOptStat = gStyle->GetOptStat();
568    gStyle->SetOptStat(0000000);
569    Double_t ltmFraction = 0.8;
570    
571    TObjArray *sigmasTokens = TString(sigmas).Tokenize(";");  
572    TVectorF nsigma(sigmasTokens->GetEntriesFast());
573    for (Int_t i = 0; i < sigmasTokens->GetEntriesFast(); i++) {
574       TString str(((TObjString*)sigmasTokens->At(i))->GetString());
575       Double_t sig = (str.IsFloat()) ? str.Atof() : 0;
576       nsigma[i] = sig;
577    }
578    
579    TString drawStr(drawCommand);
580    Bool_t dangerousToDraw = drawStr.Contains(":") || drawStr.Contains(">>");
581    if (dangerousToDraw) {
582       Warning("DrawHisto1D", "The draw string must not contain ':' or '>>'.");
583       return -1;
584    }
585    drawStr += " >> tempHist";
586    Int_t entries = EasyDraw1D(drawStr.Data(), sector, cuts);
587    TH1F *htemp = (TH1F*)gDirectory->Get("tempHist");
588    // FIXME is this histogram deleted automatically?
589    Double_t *values = fTree->GetV1();  // value is the array containing 'entries' numbers
590    
591    Double_t mean = TMath::Mean(entries, values);
592    Double_t median = TMath::Median(entries, values);
593    Double_t sigma = TMath::RMS(entries, values);
594    Double_t maxY = htemp->GetMaximum();
595    
596    TLegend * legend = new TLegend(.7,.7, .99, .99, "Statistical information");
597    //fListOfObjectsToBeDeleted->Add(legend);
598
599    if (plotMean) {
600       // draw Mean
601       TLine* line = new TLine(mean, 0, mean, maxY);
602       //fListOfObjectsToBeDeleted->Add(line);
603       line->SetLineColor(kRed);
604       line->SetLineWidth(2);
605       line->SetLineStyle(1);
606       line->Draw();
607       legend->AddEntry(line, Form("Mean: %f", mean), "l");
608       // draw sigma lines
609       for (Int_t i = 0; i < nsigma.GetNoElements(); i++) {
610          TLine* linePlusSigma = new TLine(mean + nsigma[i] * sigma, 0, mean + nsigma[i] * sigma, maxY);
611          //fListOfObjectsToBeDeleted->Add(linePlusSigma);
612          linePlusSigma->SetLineColor(kRed);
613          linePlusSigma->SetLineStyle(2 + i);
614          linePlusSigma->Draw();
615          TLine* lineMinusSigma = new TLine(mean - nsigma[i] * sigma, 0, mean - nsigma[i] * sigma, maxY);
616          //fListOfObjectsToBeDeleted->Add(lineMinusSigma);
617          lineMinusSigma->SetLineColor(kRed);
618          lineMinusSigma->SetLineStyle(2 + i);
619          lineMinusSigma->Draw();
620          legend->AddEntry(lineMinusSigma, Form("%i #sigma = %f",(Int_t)(nsigma[i]), (Float_t)(nsigma[i] * sigma)), "l");
621       }
622    }
623    if (plotMedian) {
624       // draw median
625       TLine* line = new TLine(median, 0, median, maxY);
626       //fListOfObjectsToBeDeleted->Add(line);
627       line->SetLineColor(kBlue);
628       line->SetLineWidth(2);
629       line->SetLineStyle(1);
630       line->Draw();
631       legend->AddEntry(line, Form("Median: %f", median), "l");
632       // draw sigma lines
633       for (Int_t i = 0; i < nsigma.GetNoElements(); i++) {
634          TLine* linePlusSigma = new TLine(median + nsigma[i] * sigma, 0, median + nsigma[i]*sigma, maxY);
635          //fListOfObjectsToBeDeleted->Add(linePlusSigma);
636          linePlusSigma->SetLineColor(kBlue);
637          linePlusSigma->SetLineStyle(2 + i);
638          linePlusSigma->Draw();
639          TLine* lineMinusSigma = new TLine(median - nsigma[i] * sigma, 0, median - nsigma[i]*sigma, maxY);
640          //fListOfObjectsToBeDeleted->Add(lineMinusSigma);
641          lineMinusSigma->SetLineColor(kBlue);
642          lineMinusSigma->SetLineStyle(2 + i);
643          lineMinusSigma->Draw();
644          legend->AddEntry(lineMinusSigma, Form("%i #sigma = %f",(Int_t)(nsigma[i]), (Float_t)(nsigma[i] * sigma)), "l");
645       }
646    }
647    if (plotLTM) {
648       // draw LTM
649       Double_t ltmRms = 0;
650       Double_t ltm = GetLTM(entries, values, &ltmRms, ltmFraction);
651       TLine* line = new TLine(ltm, 0, ltm, maxY);
652       //fListOfObjectsToBeDeleted->Add(line);
653       line->SetLineColor(kGreen+2);
654       line->SetLineWidth(2);
655       line->SetLineStyle(1);
656       line->Draw();
657       legend->AddEntry(line, Form("LTM: %f", ltm), "l");
658       // draw sigma lines
659       for (Int_t i = 0; i < nsigma.GetNoElements(); i++) {
660          TLine* linePlusSigma = new TLine(ltm + nsigma[i] * ltmRms, 0, ltm + nsigma[i] * ltmRms, maxY);
661          //fListOfObjectsToBeDeleted->Add(linePlusSigma);
662          linePlusSigma->SetLineColor(kGreen+2);
663          linePlusSigma->SetLineStyle(2+i);
664          linePlusSigma->Draw();
665    
666          TLine* lineMinusSigma = new TLine(ltm - nsigma[i] * ltmRms, 0, ltm - nsigma[i] * ltmRms, maxY);
667          //fListOfObjectsToBeDeleted->Add(lineMinusSigma);
668          lineMinusSigma->SetLineColor(kGreen+2);
669          lineMinusSigma->SetLineStyle(2+i);
670          lineMinusSigma->Draw();
671          legend->AddEntry(lineMinusSigma, Form("%i #sigma = %f", (Int_t)(nsigma[i]), (Float_t)(nsigma[i] * ltmRms)), "l");
672       }
673    }
674    if (!plotMean && !plotMedian && !plotLTM) return -1;
675    legend->Draw();
676    gStyle->SetOptStat(oldOptStat);
677    return 1;
678 }
679
680
681 Int_t AliTPCCalibViewer::SigmaCut(const char* drawCommand, Int_t sector, const char* cuts, Float_t sigmaMax, Bool_t plotMean, Bool_t plotMedian, Bool_t plotLTM, Bool_t pm, const char *sigmas, Float_t sigmaStep) const {
682    //
683    // Creates a histogram Begin_Latex S(t, #mu, #sigma) End_Latex, where you can see, how much of the data are inside sigma-intervals around the mean value
684    // The data of the distribution Begin_Latex f(x, #mu, #sigma) End_Latex are given in 'array', 'n' specifies the length of the array
685    // 'mean' and 'sigma' are Begin_Latex #mu End_Latex and  Begin_Latex #sigma End_Latex of the distribution in 'array', to be specified by the user
686    // 'nbins': number of bins, 'binLow': first bin, 'binUp': last bin
687    // sigmaMax: up to which sigma around the mean/median/LTM the histogram is generated (in units of sigma, Begin_Latex t #sigma End_Latex)
688    // sigmaStep: the binsize of the generated histogram
689    // Begin_Latex 
690    // f(x, #mu, #sigma)     #Rightarrow       S(t, #mu, #sigma) = (#int_{#mu}^{#mu + t #sigma} f(x, #mu, #sigma) dx + #int_{#mu}^{#mu - t #sigma} f(x, #mu, #sigma) dx) / (#int_{-#infty}^{+#infty} f(x, #mu, #sigma) dx)
691    // End_Latex
692    // 
693    //
694    // Creates a histogram, where you can see, how much of the data are inside sigma-intervals 
695    // around the mean/median/LTM
696    // with drawCommand, sector and cuts you specify your input data, see EasyDraw
697    // sigmaMax: up to which sigma around the mean/median/LTM the histogram is generated (in units of sigma)
698    // sigmaStep: the binsize of the generated histogram
699    // plotMean/plotMedian/plotLTM: specifies where to put the center
700    //
701    if (sector >= 0 && sector < 72) {
702       return SigmaCut(drawCommand, Form("%i", sector), cuts, sigmaMax, plotMean, plotMedian, plotLTM, pm, sigmas, sigmaStep);
703    }
704    Error("SigmaCut","The TPC contains only sectors between 0 and 71.");
705    return -1;
706 }
707
708
709 Int_t AliTPCCalibViewer::SigmaCut(const char* drawCommand, const char* sector, const char* cuts, Float_t sigmaMax, Bool_t plotMean, Bool_t plotMedian, Bool_t plotLTM, Bool_t pm, const char *sigmas, Float_t sigmaStep) const {
710    //
711    // Creates a histogram, where you can see, how much of the data are inside sigma-intervals 
712    // around the mean/median/LTM
713    // with drawCommand, sector and cuts you specify your input data, see EasyDraw
714    // sigmaMax: up to which sigma around the mean/median/LTM the histogram is generated (in units of sigma)
715    // sigmaStep: the binsize of the generated histogram
716    // plotMean/plotMedian/plotLTM: specifies where to put the center
717    //
718   
719    Double_t ltmFraction = 0.8;
720    
721    TString drawStr(drawCommand);
722    Bool_t dangerousToDraw = drawStr.Contains(":") || drawStr.Contains(">>");
723    if (dangerousToDraw) {
724       Warning("SigmaCut", "The draw string must not contain ':' or '>>'.");
725       return -1;
726    }
727    drawStr += " >> tempHist";
728    
729    Int_t entries = EasyDraw1D(drawStr.Data(), sector, cuts, "goff");
730    TH1F *htemp = (TH1F*)gDirectory->Get("tempHist");
731    // FIXME is this histogram deleted automatically?
732    Double_t *values = fTree->GetV1();  // value is the array containing 'entries' numbers
733    
734    Double_t mean = TMath::Mean(entries, values);
735    Double_t median = TMath::Median(entries, values);
736    Double_t sigma = TMath::RMS(entries, values);
737    
738    TLegend * legend = new TLegend(.7,.7, .99, .99, "Cumulative");
739    //fListOfObjectsToBeDeleted->Add(legend);
740    TH1F *cutHistoMean = 0;
741    TH1F *cutHistoMedian = 0;
742    TH1F *cutHistoLTM = 0;
743    
744    TObjArray *sigmasTokens = TString(sigmas).Tokenize(";");  
745    TVectorF nsigma(sigmasTokens->GetEntriesFast());
746    for (Int_t i = 0; i < sigmasTokens->GetEntriesFast(); i++) {
747       TString str(((TObjString*)sigmasTokens->At(i))->GetString());
748       Double_t sig = (str.IsFloat()) ? str.Atof() : 0;
749       nsigma[i] = sig;
750    }
751   
752    if (plotMean) {
753       cutHistoMean = AliTPCCalibViewer::SigmaCut(htemp, mean, sigma, sigmaMax, sigmaStep, pm);
754       if (cutHistoMean) {
755          //fListOfObjectsToBeDeleted->Add(cutHistoMean);
756          cutHistoMean->SetLineColor(kRed);
757          legend->AddEntry(cutHistoMean, "Mean", "l");
758          cutHistoMean->SetTitle(Form("%s, cumulative; Multiples of #sigma; Fraction of included data", htemp->GetTitle()));
759          cutHistoMean->Draw();
760          DrawLines(cutHistoMean, nsigma, legend, kRed, pm);
761       } // if (cutHistoMean)
762        
763    }
764    if (plotMedian) {
765       cutHistoMedian = AliTPCCalibViewer::SigmaCut(htemp, median, sigma, sigmaMax, sigmaStep, pm);
766       if (cutHistoMedian) {
767          //fListOfObjectsToBeDeleted->Add(cutHistoMedian);
768          cutHistoMedian->SetLineColor(kBlue);
769          legend->AddEntry(cutHistoMedian, "Median", "l");
770          cutHistoMedian->SetTitle(Form("%s, cumulative; Multiples of #sigma; Fraction of included data", htemp->GetTitle()));
771          if (plotMean && cutHistoMean) cutHistoMedian->Draw("same");
772             else cutHistoMedian->Draw();
773          DrawLines(cutHistoMedian, nsigma, legend, kBlue, pm);
774       }  // if (cutHistoMedian)
775    }
776    if (plotLTM) {
777       Double_t ltmRms = 0;
778       Double_t ltm = GetLTM(entries, values, &ltmRms, ltmFraction);
779       cutHistoLTM = AliTPCCalibViewer::SigmaCut(htemp, ltm, ltmRms, sigmaMax, sigmaStep, pm);
780       if (cutHistoLTM) {
781          //fListOfObjectsToBeDeleted->Add(cutHistoLTM);
782          cutHistoLTM->SetLineColor(kGreen+2);
783          legend->AddEntry(cutHistoLTM, "LTM", "l");
784          cutHistoLTM->SetTitle(Form("%s, cumulative; Multiples of #sigma; Fraction of included data", htemp->GetTitle()));
785          if ((plotMean && cutHistoMean) || (plotMedian && cutHistoMedian)) cutHistoLTM->Draw("same");
786             else cutHistoLTM->Draw();
787          DrawLines(cutHistoLTM, nsigma, legend, kGreen+2, pm);
788       }
789    }
790    if (!plotMean && !plotMedian && !plotLTM) return -1;
791    legend->Draw();
792    return 1;
793 }
794
795
796 Int_t AliTPCCalibViewer::SigmaCutNew(const char* drawCommand, const char* sector, const char* cuts, Float_t sigmaMax, Bool_t plotMean, Bool_t plotMedian, Bool_t plotLTM, Bool_t pm, const char *sigmas, Float_t sigmaStep) const {
797    //
798    // Creates a histogram, where you can see, how much of the data are inside sigma-intervals 
799    // around the mean/median/LTM
800    // with drawCommand, sector and cuts you specify your input data, see EasyDraw
801    // sigmaMax: up to which sigma around the mean/median/LTM the histogram is generated (in units of sigma)
802    // sigmaStep: the binsize of the generated histogram
803    // plotMean/plotMedian/plotLTM: specifies where to put the center
804    //
805   
806    // Double_t ltmFraction = 0.8;  //unused
807    // avoid compiler warnings:
808    sigmaMax = sigmaMax;
809    pm = pm;
810    sigmaStep = sigmaStep;
811    
812    TString drawStr(drawCommand);
813    drawStr += " >> tempHist";
814    
815    Int_t entries = EasyDraw1D(drawStr.Data(), sector, cuts, "goff");
816    TH1F *htemp = (TH1F*)gDirectory->Get("tempHist");
817    TGraph *cutGraphMean   = 0;
818    // TGraph *cutGraphMedian = 0;
819    // TGraph *cutGraphLTM    = 0;
820    Double_t *values = fTree->GetV1();  // value is the array containing 'entries' numbers
821    Int_t    *index  = new Int_t[entries];
822    Float_t  *xarray = new Float_t[entries];
823    Float_t  *yarray = new Float_t[entries];
824    TMath::Sort(entries, values, index, kFALSE);
825    
826    Double_t mean = TMath::Mean(entries, values);
827    // Double_t median = TMath::Median(entries, values);
828    Double_t sigma = TMath::RMS(entries, values);
829    
830    TLegend * legend = new TLegend(.7,.7, .99, .99, "Cumulative");
831    //fListOfObjectsToBeDeleted->Add(legend);
832    
833    // parse sigmas string
834    TObjArray *sigmasTokens = TString(sigmas).Tokenize(";");  
835    TVectorF nsigma(sigmasTokens->GetEntriesFast());
836    for (Int_t i = 0; i < sigmasTokens->GetEntriesFast(); i++) {
837       TString str(((TObjString*)sigmasTokens->At(i))->GetString());
838       Double_t sig = (str.IsFloat()) ? str.Atof() : 0;
839       nsigma[i] = sig;
840    }
841    
842    if (plotMean) {
843       for (Int_t i = 0; i < entries; i++) {
844          xarray[i] = TMath::Abs(values[index[i]] - mean) / sigma; 
845          yarray[i] = float(i) / float(entries);
846       }
847       cutGraphMean = new TGraph(entries, xarray, yarray);
848       if (cutGraphMean) {
849          //fListOfObjectsToBeDeleted->Add(cutGraphMean);
850          cutGraphMean->SetLineColor(kRed);
851          legend->AddEntry(cutGraphMean, "Mean", "l");
852          cutGraphMean->SetTitle(Form("%s, Cumulative; Multiples of #sigma; Fraction of included data", htemp->GetTitle()));
853          cutGraphMean->Draw("alu");
854          DrawLines(cutGraphMean, nsigma, legend, kRed, kTRUE);
855       }
856    }
857   delete [] index;
858   delete [] xarray;
859   delete [] yarray;
860    /*
861    if (plotMedian) {
862       cutHistoMedian = AliTPCCalibViewer::SigmaCut(htemp, median, sigma, sigmaMax, sigmaStep, pm);
863       if (cutHistoMedian) {
864          fListOfObjectsToBeDeleted->Add(cutHistoMedian);
865          cutHistoMedian->SetLineColor(kBlue);
866          legend->AddEntry(cutHistoMedian, "Median", "l");
867          cutHistoMedian->SetTitle(Form("%s, cumulative; Multiples of #sigma; Fraction of included data", htemp->GetTitle()));
868          if (plotMean && cutHistoMean) cutHistoMedian->Draw("same");
869             else cutHistoMedian->Draw();
870          DrawLines(cutHistoMedian, nsigma, legend, kBlue, pm);
871       }  // if (cutHistoMedian)
872    }
873    if (plotLTM) {
874       Double_t ltmRms = 0;
875       Double_t ltm = GetLTM(entries, values, &ltmRms, ltmFraction);
876       cutHistoLTM = AliTPCCalibViewer::SigmaCut(htemp, ltm, ltmRms, sigmaMax, sigmaStep, pm);
877       if (cutHistoLTM) {
878          fListOfObjectsToBeDeleted->Add(cutHistoLTM);
879          cutHistoLTM->SetLineColor(kGreen+2);
880          legend->AddEntry(cutHistoLTM, "LTM", "l");
881          cutHistoLTM->SetTitle(Form("%s, cumulative; Multiples of #sigma; Fraction of included data", htemp->GetTitle()));
882          if (plotMean && cutHistoMean || plotMedian && cutHistoMedian) cutHistoLTM->Draw("same");
883             else cutHistoLTM->Draw();
884          DrawLines(cutHistoLTM, nsigma, legend, kGreen+2, pm);
885       }
886    }*/
887    if (!plotMean && !plotMedian && !plotLTM) return -1;
888    legend->Draw();
889    return 1;
890 }
891
892
893 Int_t AliTPCCalibViewer::Integrate(const char* drawCommand,       Int_t sector, const char* cuts, Float_t sigmaMax, Bool_t plotMean, Bool_t plotMedian, Bool_t plotLTM, const char *sigmas, Float_t sigmaStep) const {
894    //
895    // Creates an integrated histogram Begin_Latex S(t, #mu, #sigma) End_Latex, out of the input distribution distribution Begin_Latex f(x, #mu, #sigma) End_Latex, given in "histogram"   
896    // "mean" and "sigma" are Begin_Latex #mu End_Latex and  Begin_Latex #sigma End_Latex of the distribution in "histogram", to be specified by the user
897    // sigmaMax: up to which sigma around the mean/median/LTM you want to integrate 
898    // if "igma == 0" and "sigmaMax == 0" the whole histogram is integrated
899    // "sigmaStep": the binsize of the generated histogram, -1 means, that the maximal reasonable stepsize is used
900    // The actual work is done on the array.
901    /* Begin_Latex 
902          f(x, #mu, #sigma)     #Rightarrow       S(t, #mu, #sigma) = #int_{-#infty}^{#mu + t #sigma} f(x, #mu, #sigma) dx / #int_{-#infty}^{+#infty} f(x, #mu, #sigma) dx
903       End_Latex  
904    */
905    if (sector >= 0 && sector < 72) {
906       return Integrate(drawCommand, Form("%i", sector), cuts, sigmaMax, plotMean, plotMedian, plotLTM, sigmas, sigmaStep);
907    }
908    Error("Integrate","The TPC contains only sectors between 0 and 71.");
909    return -1;
910    
911 }
912
913
914 Int_t AliTPCCalibViewer::IntegrateOld(const char* drawCommand, const char* sector, const char* cuts, Float_t sigmaMax, Bool_t plotMean, Bool_t plotMedian, Bool_t plotLTM, const char *sigmas, Float_t sigmaStep) const {
915    //
916    // Creates an integrated histogram Begin_Latex S(t, #mu, #sigma) End_Latex, out of the input distribution distribution Begin_Latex f(x, #mu, #sigma) End_Latex, given in "histogram"   
917    // "mean" and "sigma" are Begin_Latex #mu End_Latex and  Begin_Latex #sigma End_Latex of the distribution in "histogram", to be specified by the user
918    // sigmaMax: up to which sigma around the mean/median/LTM you want to integrate 
919    // if "igma == 0" and "sigmaMax == 0" the whole histogram is integrated
920    // "sigmaStep": the binsize of the generated histogram, -1 means, that the maximal reasonable stepsize is used
921    // The actual work is done on the array.
922    /* Begin_Latex 
923          f(x, #mu, #sigma)     #Rightarrow       S(t, #mu, #sigma) = #int_{-#infty}^{#mu + t #sigma} f(x, #mu, #sigma) dx / #int_{-#infty}^{+#infty} f(x, #mu, #sigma) dx
924       End_Latex  
925    */
926    
927    Double_t ltmFraction = 0.8;
928    
929    TString drawStr(drawCommand);
930    drawStr += " >> tempHist";
931    
932    Int_t entries = EasyDraw1D(drawStr.Data(), sector, cuts, "goff");
933    TH1F *htemp = (TH1F*)gDirectory->Get("tempHist");
934    // FIXME is this histogram deleted automatically?
935    Double_t *values = fTree->GetV1();  // value is the array containing 'entries' numbers
936    
937    Double_t mean = TMath::Mean(entries, values);
938    Double_t median = TMath::Median(entries, values);
939    Double_t sigma = TMath::RMS(entries, values);
940     
941    TObjArray *sigmasTokens = TString(sigmas).Tokenize(";");  
942    TVectorF nsigma(sigmasTokens->GetEntriesFast());
943    for (Int_t i = 0; i < sigmasTokens->GetEntriesFast(); i++) {
944       TString str(((TObjString*)sigmasTokens->At(i))->GetString());
945       Double_t sig = (str.IsFloat()) ? str.Atof() : 0;
946       nsigma[i] = sig;
947    }
948   
949    TLegend * legend = new TLegend(.7,.7, .99, .99, "Integrated histogram");
950    //fListOfObjectsToBeDeleted->Add(legend);
951    TH1F *integralHistoMean = 0;
952    TH1F *integralHistoMedian = 0;
953    TH1F *integralHistoLTM = 0;
954   
955    if (plotMean) {
956       integralHistoMean = AliTPCCalibViewer::Integrate(htemp, mean, sigma, sigmaMax, sigmaStep);
957       if (integralHistoMean) {
958          //fListOfObjectsToBeDeleted->Add(integralHistoMean);
959          integralHistoMean->SetLineColor(kRed);
960          legend->AddEntry(integralHistoMean, "Mean", "l");
961          integralHistoMean->SetTitle(Form("%s, integrated; Multiples of #sigma; Fraction of included data", htemp->GetTitle()));
962          integralHistoMean->Draw();
963          DrawLines(integralHistoMean, nsigma, legend, kRed, kTRUE);
964       }
965    }
966    if (plotMedian) {
967       integralHistoMedian = AliTPCCalibViewer::Integrate(htemp, median, sigma, sigmaMax, sigmaStep);
968       if (integralHistoMedian) {
969          //fListOfObjectsToBeDeleted->Add(integralHistoMedian);
970          integralHistoMedian->SetLineColor(kBlue);
971          legend->AddEntry(integralHistoMedian, "Median", "l");
972          integralHistoMedian->SetTitle(Form("%s, integrated; Multiples of #sigma; Fraction of included data", htemp->GetTitle()));
973          if (plotMean && integralHistoMean) integralHistoMedian->Draw("same");
974             else integralHistoMedian->Draw();
975          DrawLines(integralHistoMedian, nsigma, legend, kBlue, kTRUE);
976       }
977    }
978    if (plotLTM) {
979       Double_t ltmRms = 0;
980       Double_t ltm = GetLTM(entries, values, &ltmRms, ltmFraction);
981       integralHistoLTM = AliTPCCalibViewer::Integrate(htemp, ltm, ltmRms, sigmaMax, sigmaStep);
982       if (integralHistoLTM) {
983          //fListOfObjectsToBeDeleted->Add(integralHistoLTM);
984          integralHistoLTM->SetLineColor(kGreen+2);
985          legend->AddEntry(integralHistoLTM, "LTM", "l");
986          integralHistoLTM->SetTitle(Form("%s, integrated; Multiples of #sigma; Fraction of included data", htemp->GetTitle()));
987          if ((plotMean && integralHistoMean) || (plotMedian && integralHistoMedian)) integralHistoLTM->Draw("same");
988             else integralHistoLTM->Draw();
989          DrawLines(integralHistoLTM, nsigma, legend, kGreen+2, kTRUE);
990       }
991    }
992    if (!plotMean && !plotMedian && !plotLTM) return -1;
993    legend->Draw();
994    return 1;
995 }
996
997
998 Int_t AliTPCCalibViewer::Integrate(const char* drawCommand, const char* sector, const char* cuts, Float_t sigmaMax, Bool_t plotMean, Bool_t plotMedian, Bool_t plotLTM, const char *sigmas, Float_t sigmaStep) const {
999    //
1000    // Creates an integrated histogram Begin_Latex S(t, #mu, #sigma) End_Latex, out of the input distribution distribution Begin_Latex f(x, #mu, #sigma) End_Latex, given in "histogram"   
1001    // "mean" and "sigma" are Begin_Latex #mu End_Latex and  Begin_Latex #sigma End_Latex of the distribution in "histogram", to be specified by the user
1002    // sigmaMax: up to which sigma around the mean/median/LTM you want to integrate 
1003    // if "igma == 0" and "sigmaMax == 0" the whole histogram is integrated
1004    // "sigmaStep": the binsize of the generated histogram, -1 means, that the maximal reasonable stepsize is used
1005    // The actual work is done on the array.
1006    /* Begin_Latex 
1007          f(x, #mu, #sigma)     #Rightarrow       S(t, #mu, #sigma) = #int_{-#infty}^{#mu + t #sigma} f(x, #mu, #sigma) dx / #int_{-#infty}^{+#infty} f(x, #mu, #sigma) dx
1008       End_Latex  
1009    */
1010    
1011    Double_t ltmFraction = 0.8;
1012    // avoid compiler warnings:
1013    sigmaMax = sigmaMax;
1014    sigmaStep = sigmaStep;
1015    
1016    TString drawStr(drawCommand);
1017    Bool_t dangerousToDraw = drawStr.Contains(":") || drawStr.Contains(">>");
1018    if (dangerousToDraw) {
1019       Warning("Integrate", "The draw string must not contain ':' or '>>'.");
1020       return -1;
1021    }
1022    drawStr += " >> tempHist";
1023    
1024    Int_t entries = EasyDraw1D(drawStr.Data(), sector, cuts, "goff");
1025    TH1F *htemp = (TH1F*)gDirectory->Get("tempHist");
1026    TGraph *integralGraphMean   = 0;
1027    TGraph *integralGraphMedian = 0;
1028    TGraph *integralGraphLTM    = 0;
1029    Double_t *values = fTree->GetV1();  // value is the array containing 'entries' numbers
1030    Int_t    *index  = new Int_t[entries];
1031    Float_t  *xarray = new Float_t[entries];
1032    Float_t  *yarray = new Float_t[entries];
1033    TMath::Sort(entries, values, index, kFALSE);
1034    
1035    Double_t mean = TMath::Mean(entries, values);
1036    Double_t median = TMath::Median(entries, values);
1037    Double_t sigma = TMath::RMS(entries, values);
1038    
1039    // parse sigmas string
1040    TObjArray *sigmasTokens = TString(sigmas).Tokenize(";");  
1041    TVectorF nsigma(sigmasTokens->GetEntriesFast());
1042    for (Int_t i = 0; i < sigmasTokens->GetEntriesFast(); i++) {
1043       TString str(((TObjString*)sigmasTokens->At(i))->GetString());
1044       Double_t sig = (str.IsFloat()) ? str.Atof() : 0;
1045       nsigma[i] = sig;
1046    }
1047   
1048    TLegend * legend = new TLegend(.7,.7, .99, .99, "Integrated histogram");
1049    //fListOfObjectsToBeDeleted->Add(legend);
1050   
1051    if (plotMean) {
1052       for (Int_t i = 0; i < entries; i++) {
1053          xarray[i] = (values[index[i]] - mean) / sigma; 
1054          yarray[i] = float(i) / float(entries);
1055       }
1056       integralGraphMean = new TGraph(entries, xarray, yarray);
1057       if (integralGraphMean) {
1058          //fListOfObjectsToBeDeleted->Add(integralGraphMean);
1059          integralGraphMean->SetLineColor(kRed);
1060          legend->AddEntry(integralGraphMean, "Mean", "l");
1061          integralGraphMean->SetTitle(Form("%s, integrated; Multiples of #sigma; Fraction of included data", htemp->GetTitle()));
1062          integralGraphMean->Draw("alu");
1063          DrawLines(integralGraphMean, nsigma, legend, kRed, kTRUE);
1064       }
1065    }
1066    if (plotMedian) {
1067       for (Int_t i = 0; i < entries; i++) {
1068          xarray[i] = (values[index[i]] - median) / sigma; 
1069          yarray[i] = float(i) / float(entries);
1070       }
1071       integralGraphMedian = new TGraph(entries, xarray, yarray);
1072       if (integralGraphMedian) {
1073          //fListOfObjectsToBeDeleted->Add(integralGraphMedian);
1074          integralGraphMedian->SetLineColor(kBlue);
1075          legend->AddEntry(integralGraphMedian, "Median", "l");
1076          integralGraphMedian->SetTitle(Form("%s, integrated; Multiples of #sigma; Fraction of included data", htemp->GetTitle()));
1077          if (plotMean && integralGraphMean) integralGraphMedian->Draw("samelu");
1078             else integralGraphMedian->Draw("alu");
1079          DrawLines(integralGraphMedian, nsigma, legend, kBlue, kTRUE);
1080       }
1081    }
1082    if (plotLTM) {
1083       Double_t ltmRms = 0;
1084       Double_t ltm = GetLTM(entries, values, &ltmRms, ltmFraction);
1085       for (Int_t i = 0; i < entries; i++) {
1086          xarray[i] = (values[index[i]] - ltm) / ltmRms; 
1087          yarray[i] = float(i) / float(entries);
1088       }
1089       integralGraphLTM = new TGraph(entries, xarray, yarray);
1090       if (integralGraphLTM) {
1091          //fListOfObjectsToBeDeleted->Add(integralGraphLTM);
1092          integralGraphLTM->SetLineColor(kGreen+2);
1093          legend->AddEntry(integralGraphLTM, "LTM", "l");
1094          integralGraphLTM->SetTitle(Form("%s, integrated; Multiples of #sigma; Fraction of included data", htemp->GetTitle()));
1095          if ((plotMean && integralGraphMean) || (plotMedian && integralGraphMedian)) integralGraphLTM->Draw("samelu");
1096             else integralGraphLTM->Draw("alu");
1097          DrawLines(integralGraphLTM, nsigma, legend, kGreen+2, kTRUE);
1098       }
1099    }
1100    delete [] index;
1101    delete [] xarray;
1102    delete [] yarray;
1103   
1104    if (!plotMean && !plotMedian && !plotLTM) return -1;
1105    legend->Draw();
1106    return entries;
1107 }
1108
1109
1110 void AliTPCCalibViewer::DrawLines(TH1F *histogram, TVectorF nsigma, TLegend *legend, Int_t color, Bool_t pm) const {
1111    // 
1112    // Private function for SigmaCut(...) and Integrate(...)
1113    // Draws lines into the given histogram, specified by "nsigma", the lines are addeed to the legend
1114    // 
1115    
1116    // start to draw the lines, loop over requested sigmas
1117    for (Int_t i = 0; i < nsigma.GetNoElements(); i++) {
1118       if (!pm) { 
1119          Int_t bin = histogram->GetXaxis()->FindBin(nsigma[i]);
1120          TLine* lineUp = new TLine(nsigma[i], 0, nsigma[i], histogram->GetBinContent(bin));
1121          //fListOfObjectsToBeDeleted->Add(lineUp);
1122          lineUp->SetLineColor(color);
1123          lineUp->SetLineStyle(2 + i);
1124          lineUp->Draw();
1125          TLine* lineLeft = new TLine(nsigma[i], histogram->GetBinContent(bin), 0, histogram->GetBinContent(bin));
1126          //fListOfObjectsToBeDeleted->Add(lineLeft);
1127          lineLeft->SetLineColor(color);
1128          lineLeft->SetLineStyle(2 + i);
1129          lineLeft->Draw();
1130          legend->AddEntry(lineLeft, Form("Fraction(%f #sigma) = %f",nsigma[i], histogram->GetBinContent(bin)), "l");
1131       }
1132       else { // if (pm)
1133          Int_t bin = histogram->GetXaxis()->FindBin(nsigma[i]);
1134          TLine* lineUp1 = new TLine(nsigma[i], 0, nsigma[i], histogram->GetBinContent(bin));
1135          //fListOfObjectsToBeDeleted->Add(lineUp1);
1136          lineUp1->SetLineColor(color);
1137          lineUp1->SetLineStyle(2 + i);
1138          lineUp1->Draw();
1139          TLine* lineLeft1 = new TLine(nsigma[i], histogram->GetBinContent(bin), histogram->GetBinLowEdge(0)+histogram->GetBinWidth(0), histogram->GetBinContent(bin));
1140          //fListOfObjectsToBeDeleted->Add(lineLeft1);
1141          lineLeft1->SetLineColor(color);
1142          lineLeft1->SetLineStyle(2 + i);
1143          lineLeft1->Draw();
1144          legend->AddEntry(lineLeft1, Form("Fraction(+%f #sigma) = %f",nsigma[i], histogram->GetBinContent(bin)), "l");
1145          bin = histogram->GetXaxis()->FindBin(-nsigma[i]);
1146          TLine* lineUp2 = new TLine(-nsigma[i], 0, -nsigma[i], histogram->GetBinContent(bin));
1147          //fListOfObjectsToBeDeleted->Add(lineUp2);
1148          lineUp2->SetLineColor(color);
1149          lineUp2->SetLineStyle(2 + i);
1150          lineUp2->Draw();
1151          TLine* lineLeft2 = new TLine(-nsigma[i], histogram->GetBinContent(bin), histogram->GetBinLowEdge(0)+histogram->GetBinWidth(0), histogram->GetBinContent(bin));
1152          //fListOfObjectsToBeDeleted->Add(lineLeft2);
1153          lineLeft2->SetLineColor(color);
1154          lineLeft2->SetLineStyle(2 + i);
1155          lineLeft2->Draw();
1156          legend->AddEntry(lineLeft2, Form("Fraction(-%f #sigma) = %f",nsigma[i], histogram->GetBinContent(bin)), "l");
1157       }
1158    }  // for (Int_t i = 0; i < nsigma.GetNoElements(); i++)   
1159 }
1160
1161
1162 void AliTPCCalibViewer::DrawLines(TGraph *graph, TVectorF nsigma, TLegend *legend, Int_t color, Bool_t pm) const {
1163    // 
1164    // Private function for SigmaCut(...) and Integrate(...)
1165    // Draws lines into the given histogram, specified by "nsigma", the lines are addeed to the legend
1166    // 
1167    
1168    // start to draw the lines, loop over requested sigmas
1169    for (Int_t i = 0; i < nsigma.GetNoElements(); i++) {
1170       if (!pm) { 
1171          TLine* lineUp = new TLine(nsigma[i], 0, nsigma[i], graph->Eval(nsigma[i]));
1172          //fListOfObjectsToBeDeleted->Add(lineUp);
1173          lineUp->SetLineColor(color);
1174          lineUp->SetLineStyle(2 + i);
1175          lineUp->Draw();
1176          TLine* lineLeft = new TLine(nsigma[i], graph->Eval(nsigma[i]), 0, graph->Eval(nsigma[i]));
1177          //fListOfObjectsToBeDeleted->Add(lineLeft);
1178          lineLeft->SetLineColor(color);
1179          lineLeft->SetLineStyle(2 + i);
1180          lineLeft->Draw();
1181          legend->AddEntry(lineLeft, Form("Fraction(%f #sigma) = %f",nsigma[i], graph->Eval(nsigma[i])), "l");
1182       }
1183       else { // if (pm)
1184          TLine* lineUp1 = new TLine(nsigma[i], 0, nsigma[i], graph->Eval(nsigma[i]));
1185          //fListOfObjectsToBeDeleted->Add(lineUp1);
1186          lineUp1->SetLineColor(color);
1187          lineUp1->SetLineStyle(2 + i);
1188          lineUp1->Draw();
1189          TLine* lineLeft1 = new TLine(nsigma[i], graph->Eval(nsigma[i]), graph->GetHistogram()->GetXaxis()->GetBinLowEdge(0), graph->Eval(nsigma[i]));
1190          //fListOfObjectsToBeDeleted->Add(lineLeft1);
1191          lineLeft1->SetLineColor(color);
1192          lineLeft1->SetLineStyle(2 + i);
1193          lineLeft1->Draw();
1194          legend->AddEntry(lineLeft1, Form("Fraction(+%f #sigma) = %f",nsigma[i], graph->Eval(nsigma[i])), "l");
1195          TLine* lineUp2 = new TLine(-nsigma[i], 0, -nsigma[i], graph->Eval(-nsigma[i]));
1196          //fListOfObjectsToBeDeleted->Add(lineUp2);
1197          lineUp2->SetLineColor(color);
1198          lineUp2->SetLineStyle(2 + i);
1199          lineUp2->Draw();
1200          TLine* lineLeft2 = new TLine(-nsigma[i], graph->Eval(-nsigma[i]), graph->GetHistogram()->GetXaxis()->GetBinLowEdge(0), graph->Eval(-nsigma[i]));
1201          //fListOfObjectsToBeDeleted->Add(lineLeft2);
1202          lineLeft2->SetLineColor(color);
1203          lineLeft2->SetLineStyle(2 + i);
1204          lineLeft2->Draw();
1205          legend->AddEntry(lineLeft2, Form("Fraction(-%f #sigma) = %f",nsigma[i], graph->Eval(-nsigma[i])), "l");
1206       }
1207    }  // for (Int_t i = 0; i < nsigma.GetNoElements(); i++)   
1208 }
1209
1210
1211
1212
1213
1214 /////////////////
1215 // Array tools //
1216 /////////////////
1217
1218
1219 Int_t AliTPCCalibViewer::GetBin(Float_t value, Int_t nbins, Double_t binLow, Double_t binUp){
1220    // Returns the 'bin' for 'value'
1221    // The interval between 'binLow' and 'binUp' is divided into 'nbins' equidistant bins
1222    // avoid index out of bounds error: 'if (bin < binLow) bin = binLow' and vice versa
1223    /* Begin_Latex
1224          GetBin(value) = #frac{nbins - 1}{binUp - binLow} #upoint (value - binLow) +1
1225       End_Latex
1226    */
1227    
1228    Int_t bin =  TMath::Nint( (Float_t)(value - binLow) / (Float_t)(binUp - binLow) * (nbins-1) ) + 1;
1229    // avoid index out of bounds:   
1230    if (value < binLow) bin = 0;
1231    if (value > binUp)  bin = nbins + 1;
1232    return bin;
1233    
1234 }   
1235
1236
1237 Double_t AliTPCCalibViewer::GetLTM(Int_t n, const Double_t *const array, Double_t *const sigma, Double_t fraction){
1238    //
1239    //  returns the LTM and sigma
1240    //
1241    Double_t *ddata = new Double_t[n];
1242    Double_t mean = 0, lsigma = 0;
1243    UInt_t nPoints = 0;
1244    for (UInt_t i = 0; i < (UInt_t)n; i++) {
1245          ddata[nPoints]= array[nPoints];
1246          nPoints++;
1247    }
1248    Int_t hh = TMath::Min(TMath::Nint(fraction * nPoints), Int_t(n));
1249    AliMathBase::EvaluateUni(nPoints, ddata, mean, lsigma, hh);
1250    if (sigma) *sigma = lsigma;
1251    delete [] ddata;
1252    return mean;
1253 }
1254
1255
1256 TH1F* AliTPCCalibViewer::SigmaCut(TH1F *const histogram, Float_t mean, Float_t sigma, Float_t sigmaMax, Float_t sigmaStep, Bool_t pm) {
1257    //
1258    // Creates a cumulative histogram Begin_Latex S(t, #mu, #sigma) End_Latex, where you can see, how much of the data are inside sigma-intervals around the mean value
1259    // The data of the distribution Begin_Latex f(x, #mu, #sigma) End_Latex are given in 'histogram'
1260    // 'mean' and 'sigma' are Begin_Latex #mu End_Latex and  Begin_Latex #sigma End_Latex of the distribution in 'histogram', to be specified by the user
1261    // sigmaMax: up to which sigma around the mean/median/LTM the histogram is generated (in units of sigma, Begin_Latex t #sigma End_Latex)
1262    // sigmaStep: the binsize of the generated histogram, -1 means, that the maximal reasonable stepsize is used
1263    // pm: Decide weather Begin_Latex t > 0 End_Latex (first case) or Begin_Latex t End_Latex arbitrary (secound case)
1264    // The actual work is done on the array.
1265    /* Begin_Latex 
1266          f(x, #mu, #sigma)     #Rightarrow       S(t, #mu, #sigma) = (#int_{#mu}^{#mu + t #sigma} f(x, #mu, #sigma) dx + #int_{#mu}^{#mu - t #sigma} f(x, #mu, #sigma) dx) / (#int_{-#infty}^{+#infty} f(x, #mu, #sigma) dx),    for  t > 0    
1267          or      
1268          f(x, #mu, #sigma)     #Rightarrow       S(t, #mu, #sigma) = #int_{#mu}^{#mu + t #sigma} f(x, #mu, #sigma) dx / #int_{-#infty}^{+#infty} f(x, #mu, #sigma) dx
1269       End_Latex  
1270       Begin_Macro(source)
1271       {
1272          Float_t mean = 0;
1273          Float_t sigma = 1.5;
1274          Float_t sigmaMax = 4;
1275          gROOT->SetStyle("Plain");
1276          TH1F *distribution = new TH1F("Distrib1", "Distribution f(x, #mu, #sigma)", 1000,-5,5);
1277          TRandom rand(23);
1278          for (Int_t i = 0; i <50000;i++) distribution->Fill(rand.Gaus(mean, sigma));
1279          Float_t *ar = distribution->GetArray();
1280          
1281          TCanvas* macro_example_canvas = new TCanvas("cAliTPCCalibViewer1", "", 350, 350);
1282          macro_example_canvas->Divide(0,3);
1283          TVirtualPad *pad1 = macro_example_canvas->cd(1);
1284          pad1->SetGridy();
1285          pad1->SetGridx();
1286          distribution->Draw();
1287          TVirtualPad *pad2 = macro_example_canvas->cd(2);
1288          pad2->SetGridy();
1289          pad2->SetGridx();
1290          
1291          TH1F *shist = AliTPCCalibViewer::SigmaCut(distribution, mean, sigma, sigmaMax);
1292          shist->SetNameTitle("Cumulative","Cumulative S(t, #mu, #sigma)");
1293          shist->Draw();  
1294          TVirtualPad *pad3 = macro_example_canvas->cd(3);
1295          pad3->SetGridy();
1296          pad3->SetGridx();
1297          TH1F *shistPM = AliTPCCalibViewer::SigmaCut(distribution, mean, sigma, sigmaMax, -1, kTRUE);
1298          shistPM->Draw();   
1299          return macro_example_canvas;
1300       }  
1301       End_Macro
1302    */ 
1303    
1304    Float_t *array = histogram->GetArray();
1305    Int_t    nbins = histogram->GetXaxis()->GetNbins();
1306    Float_t binLow = histogram->GetXaxis()->GetXmin();
1307    Float_t binUp  = histogram->GetXaxis()->GetXmax();
1308    return AliTPCCalibViewer::SigmaCut(nbins, array, mean, sigma, nbins, binLow, binUp, sigmaMax, sigmaStep, pm);
1309 }   
1310    
1311
1312 TH1F* AliTPCCalibViewer::SigmaCut(Int_t n, const Float_t *array, Float_t mean, Float_t sigma, Int_t nbins, Float_t binLow, Float_t binUp, Float_t sigmaMax, Float_t sigmaStep, Bool_t pm){
1313    //
1314    // Creates a histogram Begin_Latex S(t, #mu, #sigma) End_Latex, where you can see, how much of the data are inside sigma-intervals around the mean value
1315    // The data of the distribution Begin_Latex f(x, #mu, #sigma) End_Latex are given in 'array', 'n' specifies the length of the array
1316    // 'mean' and 'sigma' are Begin_Latex #mu End_Latex and  Begin_Latex #sigma End_Latex of the distribution in 'array', to be specified by the user
1317    // 'nbins': number of bins, 'binLow': first bin, 'binUp': last bin
1318    // sigmaMax: up to which sigma around the mean/median/LTM the histogram is generated (in units of sigma, Begin_Latex t #sigma End_Latex)
1319    // sigmaStep: the binsize of the generated histogram
1320    // Here the actual work is done.
1321    
1322    if (sigma == 0) return 0;
1323    Float_t binWidth = (binUp-binLow)/(nbins - 1);
1324    if (sigmaStep <= 0) sigmaStep = binWidth;
1325    Int_t kbins = (Int_t)(sigmaMax * sigma / sigmaStep) + 1; // + 1  due to overflow bin in histograms
1326    if (pm) kbins = 2 * (Int_t)(sigmaMax * sigma / sigmaStep) + 1;
1327    Float_t kbinLow = !pm ? 0 : -sigmaMax;
1328    Float_t kbinUp  = sigmaMax;
1329    TH1F *hist = new TH1F("sigmaCutHisto","Cumulative; Multiples of #sigma; Fraction of included data", kbins, kbinLow, kbinUp); 
1330    hist->SetDirectory(0);
1331    hist->Reset();
1332    
1333    // calculate normalization
1334    Double_t normalization = 0;
1335    for (Int_t i = 0; i <= n; i++) {
1336         normalization += array[i];
1337    }
1338    
1339    // given units: units from given histogram
1340    // sigma units: in units of sigma
1341    // iDelta: integrate in interval (mean +- iDelta), given units
1342    // x:      ofset from mean for integration, given units
1343    // hist:   needs 
1344    
1345 //    printf("nbins: %i, binLow: %f, binUp: %f \n", nbins, binLow, binUp);
1346    // fill histogram
1347    for (Float_t iDelta = 0; iDelta <= sigmaMax * sigma; iDelta += sigmaStep) {
1348       // integrate array
1349       Double_t valueP = array[GetBin(mean, nbins, binLow, binUp)];
1350       Double_t valueM = array[GetBin(mean-binWidth, nbins, binLow, binUp)];
1351       // add bin of mean value only once to the histogram
1352 //       printf("++ adding bins: ");
1353       for (Float_t x = binWidth; x <= iDelta; x += binWidth) {
1354          valueP += (mean + x <= binUp)  ? array[GetBin(mean + x, nbins, binLow, binUp)] : 0;
1355          valueM += (mean-binWidth - x >= binLow) ? array[GetBin(mean-binWidth - x, nbins, binLow, binUp)] : 0; 
1356 //          printf("%i, ", GetBin(mean + x, nbins, binLow, binUp));        
1357       }
1358 //       printf("\n");
1359       if (valueP / normalization > 100) printf("+++ Error, value to big: %f, normalization with %f will fail  +++ \n", valueP, normalization);
1360       if (valueP / normalization > 100) return hist;
1361       if (valueM / normalization > 100) printf("+++ Error, value to big: %f, normalization with %f will fail  +++ \n", valueM, normalization);
1362       if (valueM / normalization > 100) return hist;
1363       valueP = (valueP / normalization);
1364       valueM = (valueM / normalization);
1365       if (pm) {
1366          Int_t bin = GetBin(iDelta/sigma, kbins, kbinLow, kbinUp);
1367          hist->SetBinContent(bin, valueP);
1368          bin = GetBin(-iDelta/sigma, kbins, kbinLow, kbinUp);
1369          hist->SetBinContent(bin, valueM);
1370       }
1371       else { // if (!pm)
1372          Int_t bin = GetBin(iDelta/sigma, kbins, kbinLow, kbinUp);
1373          hist->SetBinContent(bin, valueP + valueM);
1374 //          printf("  first integration bin: %i, last integration bin in + direction: %i \n", GetBin(mean+binWidth, nbins, binLow, binUp), GetBin(iDelta, nbins, binLow, binUp));
1375 //          printf("  first integration bin: %i, last integration bin in - direction: %i \n", GetBin(mean+binWidth, nbins, binLow, binUp), GetBin(-iDelta, nbins, binLow, binUp));
1376 //          printf("  value: %f, normalization: %f, iDelta: %f, Bin: %i \n", valueP+valueM, normalization, iDelta, bin);
1377       }
1378    }
1379    //hist->SetMaximum(0.7);
1380    if (!pm) hist->SetMaximum(1.2);
1381    return hist;
1382 }
1383
1384
1385 TH1F* AliTPCCalibViewer::SigmaCut(Int_t n, const Double_t *array, Double_t mean, Double_t sigma, Int_t nbins, const Double_t *xbins, Double_t sigmaMax){
1386    // 
1387    // SigmaCut for variable binsize
1388    // NOT YET IMPLEMENTED !!!
1389    // 
1390    printf("SigmaCut with variable binsize, Not yet implemented\n");
1391    // avoid compiler warnings:
1392    n=n;
1393    mean=mean;
1394    sigma=sigma;
1395    nbins=nbins;
1396    sigmaMax=sigmaMax;
1397    array=array;
1398    xbins=xbins;
1399    
1400    return 0;
1401 }   
1402
1403
1404 TH1F* AliTPCCalibViewer::Integrate(TH1F *const histogram, Float_t mean, Float_t sigma, Float_t sigmaMax, Float_t sigmaStep){
1405    //
1406    // Creates an integrated histogram Begin_Latex S(t, #mu, #sigma) End_Latex, out of the input distribution distribution Begin_Latex f(x, #mu, #sigma) End_Latex, given in "histogram"   
1407    // "mean" and "sigma" are Begin_Latex #mu End_Latex and  Begin_Latex #sigma End_Latex of the distribution in "histogram", to be specified by the user
1408    // sigmaMax: up to which sigma around the mean/median/LTM you want to integrate 
1409    // if "igma == 0" and "sigmaMax == 0" the whole histogram is integrated
1410    // "sigmaStep": the binsize of the generated histogram, -1 means, that the maximal reasonable stepsize is used
1411    // The actual work is done on the array.
1412    /* Begin_Latex 
1413          f(x, #mu, #sigma)     #Rightarrow       S(t, #mu, #sigma) = #int_{-#infty}^{#mu + t #sigma} f(x, #mu, #sigma) dx / #int_{-#infty}^{+#infty} f(x, #mu, #sigma) dx
1414       End_Latex  
1415       Begin_Macro(source)
1416       {
1417          Float_t mean = 0;
1418          Float_t sigma = 1.5;
1419          Float_t sigmaMax = 4;
1420          gROOT->SetStyle("Plain");
1421          TH1F *distribution = new TH1F("Distrib2", "Distribution f(x, #mu, #sigma)", 1000,-5,5);
1422          TRandom rand(23);
1423          for (Int_t i = 0; i <50000;i++) distribution->Fill(rand.Gaus(mean, sigma));
1424          Float_t *ar = distribution->GetArray();
1425          
1426          TCanvas* macro_example_canvas = new TCanvas("cAliTPCCalibViewer2", "", 350, 350);
1427          macro_example_canvas->Divide(0,2);
1428          TVirtualPad *pad1 = macro_example_canvas->cd(1);
1429          pad1->SetGridy();
1430          pad1->SetGridx();
1431          distribution->Draw();
1432          TVirtualPad *pad2 = macro_example_canvas->cd(2);
1433          pad2->SetGridy();
1434          pad2->SetGridx();
1435          TH1F *shist = AliTPCCalibViewer::Integrate(distribution, mean, sigma, sigmaMax);
1436          shist->SetNameTitle("Cumulative","Cumulative S(t, #mu, #sigma)");
1437          shist->Draw();  
1438          
1439          return macro_example_canvas_Integrate;
1440       }  
1441       End_Macro
1442    */ 
1443
1444    
1445    Float_t *array = histogram->GetArray();
1446    Int_t    nbins = histogram->GetXaxis()->GetNbins();
1447    Float_t binLow = histogram->GetXaxis()->GetXmin();
1448    Float_t binUp  = histogram->GetXaxis()->GetXmax();
1449    return AliTPCCalibViewer::Integrate(nbins, array, nbins, binLow, binUp, mean, sigma, sigmaMax, sigmaStep);
1450 }   
1451
1452
1453 TH1F* AliTPCCalibViewer::Integrate(Int_t n, const Float_t *const array, Int_t nbins, Float_t binLow, Float_t binUp, Float_t mean, Float_t sigma, Float_t sigmaMax, Float_t sigmaStep){
1454    // Creates an integrated histogram Begin_Latex S(t, #mu, #sigma) End_Latex, out of the input distribution distribution Begin_Latex f(x, #mu, #sigma) End_Latex, given in "histogram"   
1455    // "mean" and "sigma" are Begin_Latex #mu End_Latex and  Begin_Latex #sigma End_Latex of the distribution in "histogram", to be specified by the user
1456    // sigmaMax: up to which sigma around the mean/median/LTM you want to integrate 
1457    // if "igma == 0" and "sigmaMax == 0" the whole histogram is integrated
1458    // "sigmaStep": the binsize of the generated histogram, -1 means, that the maximal reasonable stepsize is used
1459    // Here the actual work is done.
1460       
1461    Bool_t givenUnits = kTRUE;
1462    if (sigma != 0 && sigmaMax != 0) givenUnits = kFALSE;
1463    if (givenUnits) {
1464       sigma = 1;
1465       sigmaMax = (binUp - binLow) / 2.;
1466    }
1467    
1468    Float_t binWidth = (binUp-binLow)/(nbins - 1);
1469    if (sigmaStep <= 0) sigmaStep = binWidth;
1470    Int_t kbins =  (Int_t)(sigmaMax * sigma / sigmaStep) + 1;  // + 1  due to overflow bin in histograms
1471    Float_t kbinLow = givenUnits ? binLow : -sigmaMax;
1472    Float_t kbinUp  = givenUnits ? binUp  : sigmaMax;
1473    TH1F *hist = 0; 
1474    if (givenUnits)  hist = new TH1F("integratedHisto","Integrated Histogram; Given x; Fraction of included data", kbins, kbinLow, kbinUp); 
1475    if (!givenUnits) hist = new TH1F("integratedHisto","Integrated Histogram; Multiples of #sigma; Fraction of included data", kbins, kbinLow, kbinUp); 
1476    hist->SetDirectory(0);
1477    hist->Reset();
1478    
1479    // calculate normalization
1480  //  printf("calculating normalization, integrating from bin 1 to %i \n", n);
1481    Double_t normalization = 0;
1482    for (Int_t i = 1; i <= n; i++) {
1483         normalization += array[i];
1484    }
1485  //  printf("normalization: %f \n", normalization);
1486    
1487    // given units: units from given histogram
1488    // sigma units: in units of sigma
1489    // iDelta: integrate in interval (mean +- iDelta), given units
1490    // x:      ofset from mean for integration, given units
1491    // hist:   needs 
1492    
1493    // fill histogram
1494    for (Float_t iDelta = mean - sigmaMax * sigma; iDelta <= mean + sigmaMax * sigma; iDelta += sigmaStep) {
1495       // integrate array
1496       Double_t value = 0;
1497       for (Float_t x = mean - sigmaMax * sigma; x <= iDelta; x += binWidth) {
1498          value += (x <= binUp && x >= binLow)  ? array[GetBin(x, nbins, binLow, binUp)] : 0;
1499       }
1500       if (value / normalization > 100) printf("+++ Error, value to big: %f, normalization with %f will fail  +++ \n", value, normalization);
1501       if (value / normalization > 100) return hist;
1502       Int_t bin = GetBin(iDelta/sigma, kbins, kbinLow, kbinUp);
1503     //  printf("first integration bin: %i, last integration bin: %i \n", GetBin(mean - sigmaMax * sigma, nbins, binLow, binUp), GetBin(iDelta, nbins, binLow, binUp));
1504     //  printf("value: %f, normalization: %f, normalized value: %f, iDelta: %f, Bin: %i \n", value, normalization, value/normalization, iDelta, bin);
1505       value = (value / normalization);
1506       hist->SetBinContent(bin, value);
1507    }
1508    return hist;
1509 }
1510
1511
1512
1513
1514
1515 ////////////////////////
1516 // end of Array tools //
1517 ////////////////////////
1518
1519
1520
1521 //_____________________________________________________________________________
1522 AliTPCCalPad* AliTPCCalibViewer::GetCalPadOld(const char* desiredData, const char* cuts, const char* calPadName) const {
1523   //
1524   // creates a AliTPCCalPad out of the 'desiredData'
1525   // the functionality of EasyDraw1D is used
1526   // calPadName specifies the name of the created AliTPCCalPad
1527   //  - this takes a while -
1528   //
1529    TString drawStr(desiredData);
1530    drawStr.Append(":channel");
1531    drawStr.Append(fAbbreviation);
1532    AliTPCCalPad * createdCalPad = new AliTPCCalPad(calPadName, calPadName);
1533    Int_t entries = 0;
1534    for (Int_t sec = 0; sec < 72; sec++) {
1535      AliTPCCalROC * roc = createdCalPad->GetCalROC(sec);
1536       entries = EasyDraw1D(drawStr.Data(), (Int_t)sec, cuts, "goff");
1537       if (entries == -1) return 0;
1538       const Double_t *pchannel = fTree->GetV2();
1539       const Double_t *pvalue   = fTree->GetV1();
1540       for (Int_t i = 0; i < entries; i++) 
1541          roc->SetValue((UInt_t)(pchannel[i]), (Float_t)(pvalue[i]));
1542    }
1543    return createdCalPad;   
1544 }
1545
1546
1547 //_____________________________________________________________________________
1548 AliTPCCalPad* AliTPCCalibViewer::GetCalPad(const char* desiredData, const char* cuts, const char* calPadName) const {
1549   //
1550   // creates a AliTPCCalPad out of the 'desiredData'
1551   // the functionality of EasyDraw1D is used
1552   // calPadName specifies the name of the created AliTPCCalPad
1553   //  - this takes a while -
1554   //
1555    TString drawStr(desiredData);
1556    drawStr.Append(":channel.fElements:sector");
1557    AliTPCCalPad * createdCalPad = new AliTPCCalPad(calPadName, calPadName);
1558    //
1559    Int_t entries = fTree->Draw(drawStr, cuts,"goff");
1560    const Double_t *pvalue   = fTree->GetV1();
1561    const Double_t *pchannel = fTree->GetV2();
1562    const Double_t *psector  = fTree->GetV3();
1563
1564    for (Int_t ientry=0; ientry<entries; ientry++){
1565      Int_t sector= TMath::Nint(psector[ientry]);
1566      AliTPCCalROC * roc = createdCalPad->GetCalROC(sector);
1567      if (roc) roc->SetValue((UInt_t)(pchannel[ientry]), (Float_t)(pvalue[ientry]));
1568    }
1569
1570   //  for (Int_t sec = 0; sec < 72; sec++) {
1571 //      AliTPCCalROC * roc = createdCalPad->GetCalROC(sec);
1572 //       entries = EasyDraw1D(drawStr.Data(), (Int_t)sec, cuts, "goff");
1573 //       if (entries == -1) return 0;
1574 //       for (Int_t i = 0; i < entries; i++) 
1575 //          roc->SetValue((UInt_t)(pchannel[i]), (Float_t)(pvalue[i]));
1576 //    }
1577    return createdCalPad;   
1578 }
1579
1580 //_____________________________________________________________________________
1581 AliTPCCalROC* AliTPCCalibViewer::GetCalROC(const char* desiredData, UInt_t sector, const char* cuts) const {
1582   //
1583   // creates a AliTPCCalROC out of the desiredData
1584   // the functionality of EasyDraw1D is used
1585   // sector specifies the sector of the created AliTPCCalROC
1586   //
1587    TString drawStr(desiredData);
1588    drawStr.Append(":channel");
1589    drawStr.Append(fAbbreviation);
1590    Int_t entries = EasyDraw1D(drawStr.Data(), (Int_t)sector, cuts, "goff");
1591    if (entries == -1) return 0;
1592    AliTPCCalROC * createdROC = new AliTPCCalROC(sector);
1593    for (Int_t i = 0; i < entries; i++) 
1594       createdROC->SetValue((UInt_t)(fTree->GetV2()[i]), fTree->GetV1()[i]);
1595    return createdROC;
1596 }
1597
1598
1599 TObjArray* AliTPCCalibViewer::GetListOfVariables(Bool_t printList) {
1600   //
1601   // scan the tree  - produces a list of available variables in the tree
1602   // printList: print the list to the screen, after the scan is done
1603   //
1604    TObjArray* arr = new TObjArray();
1605    TObjString* str = 0;
1606    if (!fTree) return 0;
1607    Int_t nentries = fTree->GetListOfBranches()->GetEntries();
1608    for (Int_t i = 0; i < nentries; i++) {
1609       str = new TObjString(fTree->GetListOfBranches()->At(i)->GetName());
1610       str->String().ReplaceAll("_Median", "");
1611       str->String().ReplaceAll("_Mean", "");
1612       str->String().ReplaceAll("_RMS", "");
1613       str->String().ReplaceAll("_LTM", "");
1614       str->String().ReplaceAll("_OutlierCutted", "");
1615       str->String().ReplaceAll(".", "");
1616       if (!arr->FindObject(str) && 
1617           !(str->String() == "channel" || str->String() == "gx" || str->String() == "gy" || 
1618             str->String() == "lx" || str->String() == "ly" || str->String() == "pad" || 
1619             str->String() == "row" || str->String() == "rpad" || str->String() == "sector"  ))
1620          arr->Add(str);
1621    }
1622    
1623    // loop over all friends (if there are some) and add them to the list
1624    if (fTree->GetListOfFriends()) {
1625       for (Int_t ifriend = 0; ifriend < fTree->GetListOfFriends()->GetEntries(); ifriend++){
1626          // printf("iterating through friendlist, currently at %i\n", ifriend);
1627          // printf("working with %s\n", fTree->GetListOfFriends()->At(ifriend)->ClassName());
1628          if (TString(fTree->GetListOfFriends()->At(ifriend)->ClassName()) != "TFriendElement") continue; // no friendElement found
1629          TFriendElement *friendElement = (TFriendElement*)fTree->GetListOfFriends()->At(ifriend);
1630          if (friendElement->GetTree() == 0) continue; // no tree found in friendElement
1631          // printf("friend found \n");
1632          for (Int_t i = 0; i < friendElement->GetTree()->GetListOfBranches()->GetEntries(); i++) {
1633             // printf("iterating through friendelement entries, currently at %i\n", i);
1634             str = new TObjString(friendElement->GetTree()->GetListOfBranches()->At(i)->GetName());
1635             str->String().ReplaceAll("_Median", "");
1636             str->String().ReplaceAll("_Mean", "");
1637             str->String().ReplaceAll("_RMS", "");
1638             str->String().ReplaceAll("_LTM", "");
1639             str->String().ReplaceAll("_OutlierCutted", "");
1640             str->String().ReplaceAll(".", "");
1641             if (!(str->String() == "channel" || str->String() == "gx" || str->String() == "gy" || 
1642                   str->String() == "lx" || str->String() == "ly" || str->String() == "pad" || 
1643                   str->String() == "row" || str->String() == "rpad" || str->String() == "sector"  )){
1644                // insert "<friendName>." at the beginning: (<friendName> is per default "R")
1645                str->String().Insert(0, ".");
1646                str->String().Insert(0, friendElement->GetName());
1647                if (!arr->FindObject(str)) arr->Add(str);
1648                // printf("added string %s \n", str->String().Data());
1649             }
1650          }
1651       }
1652    } // if (fTree->GetListOfFriends())
1653    
1654    arr->Sort();
1655 //   ((TFriendElement*)gui->GetViewer()->GetTree()->GetListOfFriends()->At(0))->GetTree()->GetListOfBranches()->At(0)->GetName()
1656 // ((TFriendElement*)gui->GetViewer()->GetTree()->GetListOfFriends()->At(0))->GetTree()->GetListOfBranches()
1657
1658
1659    if (printList) {
1660       TIterator* iter = arr->MakeIterator();
1661       iter->Reset();
1662       TObjString* currentStr = 0;
1663       while ( (currentStr = (TObjString*)(iter->Next())) ) {
1664          std::cout << currentStr->GetString().Data() << std::endl;
1665       }
1666       delete iter;
1667    }
1668    return arr;
1669 }
1670
1671
1672 TObjArray* AliTPCCalibViewer::GetListOfNormalizationVariables(Bool_t printList) const{
1673   //
1674   // produces a list of available variables for normalization in the tree
1675   // printList: print the list to the screen, after the scan is done
1676   //
1677    TObjArray* arr = new TObjArray();
1678    arr->Add(new TObjString("_Mean"));
1679    arr->Add(new TObjString("_Mean_OutlierCutted"));
1680    arr->Add(new TObjString("_Median"));
1681    arr->Add(new TObjString("_Median_OutlierCutted"));
1682    arr->Add(new TObjString("_LTM"));
1683    arr->Add(new TObjString("_LTM_OutlierCutted"));
1684    arr->Add(new TObjString(Form("LFitIntern_4_8%s", fAppendString.Data())));
1685    arr->Add(new TObjString(Form("GFitIntern_Lin%s", fAppendString.Data())));
1686    arr->Add(new TObjString(Form("GFitIntern_Par%s", fAppendString.Data())));
1687    arr->Add(new TObjString("FitLinLocal"));
1688    arr->Add(new TObjString("FitLinGlobal"));
1689    arr->Add(new TObjString("FitParLocal"));
1690    arr->Add(new TObjString("FitParGlobal"));
1691
1692    if (printList) {
1693       TIterator* iter = arr->MakeIterator();
1694       iter->Reset();
1695       TObjString* currentStr = 0;
1696       while ((currentStr = (TObjString*)(iter->Next()))) {
1697          std::cout << currentStr->GetString().Data() << std::endl;
1698       }
1699       delete iter;
1700    }
1701    return arr;
1702 }
1703
1704
1705 TFriendElement* AliTPCCalibViewer::AddReferenceTree(const char* filename, const char* treename, const char* refname){
1706   //
1707   // add a reference tree to the current tree
1708   // by default the treename is 'calPads' and the reference treename is 'R'
1709   //
1710    TFile *file = new TFile(filename);
1711    fListOfObjectsToBeDeleted->Add(file);
1712    TTree * tree = (TTree*)file->Get(treename);
1713    return AddFriend(tree, refname);
1714 }
1715
1716
1717 TObjArray* AliTPCCalibViewer::GetArrayOfCalPads(){
1718   //
1719   // Returns a TObjArray with all AliTPCCalPads that are stored in the tree
1720   //  - this takes a while - 
1721   //
1722    TObjArray *listOfCalPads = GetListOfVariables();
1723    TObjArray *calPadsArray = new TObjArray();
1724    Int_t numberOfCalPads = listOfCalPads->GetEntries();
1725    for (Int_t i = 0; i < numberOfCalPads; i++) {
1726       std::cout << "Creating calPad " << (i+1) << " of " << numberOfCalPads << "\r" << std::flush;
1727       char* calPadName = (char*)((TObjString*)(listOfCalPads->At(i)))->GetString().Data();
1728       TString drawCommand = ((TObjString*)(listOfCalPads->At(i)))->GetString();
1729       drawCommand.Append(fAbbreviation.Data());
1730       AliTPCCalPad* calPad = GetCalPad(drawCommand.Data(), "", calPadName); 
1731       calPadsArray->Add(calPad); 
1732    }
1733    std::cout << std::endl;
1734    listOfCalPads->Delete();
1735    delete listOfCalPads;
1736    return calPadsArray;
1737 }
1738
1739
1740 TString* AliTPCCalibViewer::Fit(const char* drawCommand, const char* formula, const char* cuts, Double_t & chi2, TVectorD &fitParam, TMatrixD &covMatrix){
1741    //
1742    // fit an arbitrary function, specified by formula into the data, specified by drawCommand and cuts
1743    // returns chi2, fitParam and covMatrix
1744    // returns TString with fitted formula
1745    //
1746    
1747    TString formulaStr(formula); 
1748    TString drawStr(drawCommand);
1749    TString cutStr(cuts);
1750    
1751    // abbreviations:
1752    drawStr.ReplaceAll(fAbbreviation, fAppendString);
1753    cutStr.ReplaceAll(fAbbreviation, fAppendString);
1754    formulaStr.ReplaceAll(fAbbreviation, fAppendString);
1755    
1756    formulaStr.ReplaceAll("++", fAbbreviation);
1757    TObjArray* formulaTokens = formulaStr.Tokenize(fAbbreviation.Data()); 
1758    Int_t dim = formulaTokens->GetEntriesFast();
1759    
1760    fitParam.ResizeTo(dim);
1761    covMatrix.ResizeTo(dim,dim);
1762    
1763    TLinearFitter* fitter = new TLinearFitter(dim+1, Form("hyp%d",dim));
1764    fitter->StoreData(kTRUE);   
1765    fitter->ClearPoints();
1766    
1767    Int_t entries = Draw(drawStr.Data(), cutStr.Data(), "goff");
1768    if (entries == -1) return new TString("An ERROR has occured during fitting!");
1769    Double_t **values = new Double_t*[dim+1] ; 
1770    
1771    for (Int_t i = 0; i < dim + 1; i++){
1772       Int_t centries = 0;
1773       if (i < dim) centries = fTree->Draw(((TObjString*)formulaTokens->At(i))->GetName(), cutStr.Data(), "goff");
1774       else  centries = fTree->Draw(drawStr.Data(), cutStr.Data(), "goff");
1775       
1776       if (entries != centries) {
1777         delete [] values;
1778         return new TString("An ERROR has occured during fitting!");
1779       }
1780       values[i] = new Double_t[entries];
1781       memcpy(values[i],  fTree->GetV1(), entries*sizeof(Double_t)); 
1782    }
1783    
1784    // add points to the fitter
1785    for (Int_t i = 0; i < entries; i++){
1786       Double_t x[1000];
1787       for (Int_t j=0; j<dim;j++) x[j]=values[j][i];
1788       fitter->AddPoint(x, values[dim][i], 1);
1789    }
1790
1791    fitter->Eval();
1792    fitter->GetParameters(fitParam);
1793    fitter->GetCovarianceMatrix(covMatrix);
1794    chi2 = fitter->GetChisquare();
1795 //    chi2 = chi2;
1796    
1797    TString *preturnFormula = new TString(Form("( %e+",fitParam[0])), &returnFormula = *preturnFormula;
1798    
1799    for (Int_t iparam = 0; iparam < dim; iparam++) {
1800      returnFormula.Append(Form("%s*(%e)",((TObjString*)formulaTokens->At(iparam))->GetName(),fitParam[iparam+1]));
1801      if (iparam < dim-1) returnFormula.Append("+");
1802    }
1803    returnFormula.Append(" )");
1804    delete formulaTokens;
1805    delete fitter;
1806    for (Int_t i = 0; i < dim + 1; i++){
1807      delete [] values[i];
1808    }
1809    delete [] values;
1810    return preturnFormula;
1811 }
1812
1813
1814 void AliTPCCalibViewer::MakeTreeWithObjects(const char *fileName, const TObjArray *const array, const char * mapFileName) {
1815   //
1816   // Write tree with all available information
1817   // im mapFileName is speciefied, the Map information are also written to the tree
1818   // AliTPCCalPad-Objects are written directly to the tree, so that they can be accessd later on
1819   // (does not work!!!)
1820   //
1821    AliTPCROC* tpcROCinstance = AliTPCROC::Instance();
1822
1823    TObjArray* mapIROCs = 0;
1824    TObjArray* mapOROCs = 0;
1825    TVectorF *mapIROCArray = 0;
1826    TVectorF *mapOROCArray = 0;
1827    Int_t mapEntries = 0;
1828    TString* mapNames = 0;
1829    
1830    if (mapFileName) {
1831       TFile mapFile(mapFileName, "read");
1832       
1833       TList* listOfROCs = mapFile.GetListOfKeys();
1834       mapEntries = listOfROCs->GetEntries()/2;
1835       mapIROCs = new TObjArray(mapEntries*2);
1836       mapOROCs = new TObjArray(mapEntries*2);
1837       mapIROCArray = new TVectorF[mapEntries];
1838       mapOROCArray = new TVectorF[mapEntries];
1839       
1840       mapNames = new TString[mapEntries];
1841       for (Int_t ivalue = 0; ivalue < mapEntries; ivalue++) {
1842          TString rocName(((TKey*)(listOfROCs->At(ivalue*2)))->GetName());
1843          rocName.Remove(rocName.Length()-4, 4);
1844          mapIROCs->AddAt((AliTPCCalROC*)mapFile.Get((rocName + "IROC").Data()), ivalue);
1845          mapOROCs->AddAt((AliTPCCalROC*)mapFile.Get((rocName + "OROC").Data()), ivalue);
1846          mapNames[ivalue].Append(rocName);
1847       }
1848       
1849       for (Int_t ivalue = 0; ivalue < mapEntries; ivalue++) {
1850          mapIROCArray[ivalue].ResizeTo(tpcROCinstance->GetNChannels(0));
1851          mapOROCArray[ivalue].ResizeTo(tpcROCinstance->GetNChannels(36));
1852       
1853          for (UInt_t ichannel = 0; ichannel < tpcROCinstance->GetNChannels(0); ichannel++)
1854             (mapIROCArray[ivalue])[ichannel] = ((AliTPCCalROC*)(mapIROCs->At(ivalue)))->GetValue(ichannel);
1855          for (UInt_t ichannel = 0; ichannel < tpcROCinstance->GetNChannels(36); ichannel++)
1856             (mapOROCArray[ivalue])[ichannel] = ((AliTPCCalROC*)(mapOROCs->At(ivalue)))->GetValue(ichannel);
1857       }
1858
1859    } //  if (mapFileName)
1860   
1861    TTreeSRedirector cstream(fileName);
1862    Int_t arrayEntries = array->GetEntries();
1863    
1864    // Read names of AliTPCCalPads and save them in names[]
1865    TString* names = new TString[arrayEntries];
1866    for (Int_t ivalue = 0; ivalue < arrayEntries; ivalue++)
1867       names[ivalue].Append(((AliTPCCalPad*)array->At(ivalue))->GetName());
1868
1869    for (UInt_t isector = 0; isector < tpcROCinstance->GetNSectors(); isector++) {
1870       
1871       TVectorF *vectorArray = new TVectorF[arrayEntries];
1872       for (Int_t ivalue = 0; ivalue < arrayEntries; ivalue++)
1873          vectorArray[ivalue].ResizeTo(tpcROCinstance->GetNChannels(isector));
1874             
1875       
1876       //
1877       // fill vectors of variable per pad
1878       //
1879       TVectorF *posArray = new TVectorF[8];
1880       for (Int_t ivalue = 0; ivalue < 8; ivalue++)
1881          posArray[ivalue].ResizeTo(tpcROCinstance->GetNChannels(isector));
1882
1883       Float_t posG[3] = {0};
1884       Float_t posL[3] = {0};
1885       Int_t ichannel = 0;
1886       for (UInt_t irow = 0; irow < tpcROCinstance->GetNRows(isector); irow++) {
1887          for (UInt_t ipad = 0; ipad < tpcROCinstance->GetNPads(isector, irow); ipad++) {
1888             tpcROCinstance->GetPositionLocal(isector, irow, ipad, posL);
1889             tpcROCinstance->GetPositionGlobal(isector, irow, ipad, posG);
1890             posArray[0][ichannel] = irow;
1891             posArray[1][ichannel] = ipad;
1892             posArray[2][ichannel] = posL[0];
1893             posArray[3][ichannel] = posL[1];
1894             posArray[4][ichannel] = posG[0];
1895             posArray[5][ichannel] = posG[1];
1896             posArray[6][ichannel] = (Int_t)(ipad - (Double_t)(tpcROCinstance->GetNPads(isector, irow))/2);
1897             posArray[7][ichannel] = ichannel;
1898             
1899             // loop over array containing AliTPCCalPads
1900             for (Int_t ivalue = 0; ivalue < arrayEntries; ivalue++) {
1901                AliTPCCalPad* calPad = (AliTPCCalPad*) array->At(ivalue);
1902                AliTPCCalROC* calROC = calPad->GetCalROC(isector);
1903                if (calROC)
1904                   (vectorArray[ivalue])[ichannel] = calROC->GetValue(irow, ipad);
1905                else
1906                   (vectorArray[ivalue])[ichannel] = 0;
1907             }
1908             ichannel++;
1909          }
1910       }
1911       AliTPCCalROC dummyROC(0);
1912       for  (Int_t ivalue = 0; ivalue < arrayEntries; ivalue++) {
1913          AliTPCCalROC *roc = ((AliTPCCalPad*)array->At(ivalue))->GetCalROC(isector);
1914          if (!roc) roc = &dummyROC;
1915          cstream << "calPads" <<
1916             (Char_t*)((names[ivalue] + ".=").Data()) << &vectorArray[ivalue];
1917          cstream << "calPads" << 
1918             (Char_t*)((names[ivalue] + "Pad.=").Data()) << roc;
1919       }
1920
1921       if (mapFileName) {
1922          for  (Int_t ivalue = 0; ivalue < mapEntries; ivalue++) {
1923             if (isector < 36)
1924                cstream << "calPads" <<
1925                   (Char_t*)((mapNames[ivalue] + ".=").Data()) << &mapIROCArray[ivalue];
1926             else
1927                cstream << "calPads" <<
1928                   (Char_t*)((mapNames[ivalue] + ".=").Data()) << &mapOROCArray[ivalue];
1929          }
1930       }
1931       
1932       cstream << "calPads" <<
1933          "sector=" << isector;
1934
1935       cstream << "calPads" <<
1936          "row.=" << &posArray[0] <<
1937          "pad.=" << &posArray[1] <<
1938          "lx.=" << &posArray[2] <<
1939          "ly.=" << &posArray[3] <<
1940          "gx.=" << &posArray[4] <<
1941          "gy.=" << &posArray[5] <<
1942          "rpad.=" << &posArray[6] <<
1943          "channel.=" << &posArray[7];
1944
1945       cstream << "calPads" <<
1946          "\n";
1947
1948       delete[] posArray;
1949       delete[] vectorArray;
1950    } //for (UInt_t isector = 0; isector < tpcROCinstance->GetNSectors(); isector++)
1951
1952    delete[] names;
1953    if (mapFileName) {
1954       delete mapIROCs;
1955       delete mapOROCs;
1956       delete[] mapIROCArray;
1957       delete[] mapOROCArray;
1958       delete[] mapNames;
1959    }
1960 }
1961
1962
1963 void AliTPCCalibViewer::MakeTree(const char * fileName, TObjArray * array, const char * mapFileName, AliTPCCalPad *const outlierPad, Float_t ltmFraction) {
1964   //
1965   // Write a tree with all available information
1966   // if mapFileName is speciefied, the Map information are also written to the tree
1967   // pads specified in outlierPad are not used for calculating statistics
1968   // The following statistical information on the basis of a ROC are calculated: 
1969   // "_Median", "_Mean", "_LTM", "_RMS_LTM"
1970   // "_Median_OutlierCutted", "_Mean_OutlierCutted", "_RMS_OutlierCutted", "_LTM_OutlierCutted", "_RMS_LTM_OutlierCutted"
1971   // The following position variables are available:
1972   // "row", "pad", "lx", "ly", "gx", "gy", "rpad", "channel"
1973   // 
1974   // The tree out of this function is the basis for the AliTPCCalibViewer and the AliTPCCalibViewerGUI.
1975    
1976   AliTPCROC* tpcROCinstance = AliTPCROC::Instance();
1977
1978   TObjArray* mapIROCs = 0;
1979   TObjArray* mapOROCs = 0;
1980   TVectorF *mapIROCArray = 0;
1981   TVectorF *mapOROCArray = 0;
1982   Int_t mapEntries = 0;
1983   TString* mapNames = 0;
1984   
1985   if (mapFileName) {
1986     TFile mapFile(mapFileName, "read");
1987     
1988     TList* listOfROCs = mapFile.GetListOfKeys();
1989     mapEntries = listOfROCs->GetEntries()/2;
1990     mapIROCs = new TObjArray(mapEntries*2);
1991     mapOROCs = new TObjArray(mapEntries*2);
1992     mapIROCArray = new TVectorF[mapEntries];
1993     mapOROCArray = new TVectorF[mapEntries];
1994     
1995     mapNames = new TString[mapEntries];
1996     for (Int_t ivalue = 0; ivalue < mapEntries; ivalue++) {
1997       TString rocName(((TKey*)(listOfROCs->At(ivalue*2)))->GetName());
1998       rocName.Remove(rocName.Length()-4, 4);
1999       mapIROCs->AddAt((AliTPCCalROC*)mapFile.Get((rocName + "IROC").Data()), ivalue);
2000       mapOROCs->AddAt((AliTPCCalROC*)mapFile.Get((rocName + "OROC").Data()), ivalue);
2001       mapNames[ivalue].Append(rocName);
2002     }
2003     
2004     for (Int_t ivalue = 0; ivalue < mapEntries; ivalue++) {
2005       mapIROCArray[ivalue].ResizeTo(tpcROCinstance->GetNChannels(0));
2006       mapOROCArray[ivalue].ResizeTo(tpcROCinstance->GetNChannels(36));
2007       
2008       for (UInt_t ichannel = 0; ichannel < tpcROCinstance->GetNChannels(0); ichannel++)
2009         (mapIROCArray[ivalue])[ichannel] = ((AliTPCCalROC*)(mapIROCs->At(ivalue)))->GetValue(ichannel);
2010       for (UInt_t ichannel = 0; ichannel < tpcROCinstance->GetNChannels(36); ichannel++)
2011         (mapOROCArray[ivalue])[ichannel] = ((AliTPCCalROC*)(mapOROCs->At(ivalue)))->GetValue(ichannel);
2012     }
2013     
2014   } //  if (mapFileName)
2015   
2016   TTreeSRedirector cstream(fileName);
2017   Int_t arrayEntries = 0;
2018   if (array) arrayEntries = array->GetEntries();
2019   
2020   TString* names = new TString[arrayEntries];
2021   for (Int_t ivalue = 0; ivalue < arrayEntries; ivalue++)
2022     names[ivalue].Append(((AliTPCCalPad*)array->At(ivalue))->GetName());
2023   
2024   for (UInt_t isector = 0; isector < tpcROCinstance->GetNSectors(); isector++) {
2025       //
2026       // get statistic for given sector
2027       //
2028     TVectorF median(arrayEntries);
2029     TVectorF mean(arrayEntries);
2030     TVectorF rms(arrayEntries);
2031     TVectorF ltm(arrayEntries);
2032     TVectorF ltmrms(arrayEntries);
2033     TVectorF medianWithOut(arrayEntries);
2034     TVectorF meanWithOut(arrayEntries);
2035     TVectorF rmsWithOut(arrayEntries);
2036     TVectorF ltmWithOut(arrayEntries);
2037     TVectorF ltmrmsWithOut(arrayEntries);
2038     
2039     TVectorF *vectorArray = new TVectorF[arrayEntries];
2040     for (Int_t ivalue = 0; ivalue < arrayEntries; ivalue++){
2041       vectorArray[ivalue].ResizeTo(tpcROCinstance->GetNChannels(isector));
2042       vectorArray[ivalue].SetUniqueID(array->UncheckedAt(ivalue)->GetUniqueID());
2043 //       printf("UniqueID: %d\n",vectorArray[ivalue].GetUniqueID());
2044     }
2045     
2046     for (Int_t ivalue = 0; ivalue < arrayEntries; ivalue++) {
2047       AliTPCCalPad* calPad = (AliTPCCalPad*) array->At(ivalue);
2048       AliTPCCalROC* calROC = calPad->GetCalROC(isector);
2049       AliTPCCalROC* outlierROC = 0;
2050       if (outlierPad) outlierROC = outlierPad->GetCalROC(isector);
2051       if (calROC) {
2052         median[ivalue] = calROC->GetMedian();
2053         mean[ivalue] = calROC->GetMean();
2054         rms[ivalue] = calROC->GetRMS();
2055         Double_t ltmrmsValue = 0;
2056         ltm[ivalue] = calROC->GetLTM(&ltmrmsValue, ltmFraction);
2057         ltmrms[ivalue] = ltmrmsValue;
2058         if (outlierROC) {
2059           medianWithOut[ivalue] = calROC->GetMedian(outlierROC);
2060           meanWithOut[ivalue] = calROC->GetMean(outlierROC);
2061           rmsWithOut[ivalue] = calROC->GetRMS(outlierROC);
2062           ltmrmsValue = 0;
2063           ltmWithOut[ivalue] = calROC->GetLTM(&ltmrmsValue, ltmFraction, outlierROC);
2064           ltmrmsWithOut[ivalue] = ltmrmsValue;
2065         }
2066       }
2067       else {
2068         median[ivalue] = 0.;
2069         mean[ivalue] = 0.;
2070         rms[ivalue] = 0.;
2071         ltm[ivalue] = 0.;
2072         ltmrms[ivalue] = 0.;
2073         medianWithOut[ivalue] = 0.;
2074         meanWithOut[ivalue] = 0.;
2075         rmsWithOut[ivalue] = 0.;
2076         ltmWithOut[ivalue] = 0.;
2077         ltmrmsWithOut[ivalue] = 0.;
2078       }
2079     }
2080     
2081       //
2082       // fill vectors of variable per pad
2083       //
2084     TVectorF *posArray = new TVectorF[8];
2085     for (Int_t ivalue = 0; ivalue < 8; ivalue++)
2086       posArray[ivalue].ResizeTo(tpcROCinstance->GetNChannels(isector));
2087     
2088     Float_t posG[3] = {0};
2089     Float_t posL[3] = {0};
2090     Int_t ichannel = 0;
2091     for (UInt_t irow = 0; irow < tpcROCinstance->GetNRows(isector); irow++) {
2092       for (UInt_t ipad = 0; ipad < tpcROCinstance->GetNPads(isector, irow); ipad++) {
2093         tpcROCinstance->GetPositionLocal(isector, irow, ipad, posL);
2094         tpcROCinstance->GetPositionGlobal(isector, irow, ipad, posG);
2095         posArray[0][ichannel] = irow;
2096         posArray[1][ichannel] = ipad;
2097         posArray[2][ichannel] = posL[0];
2098         posArray[3][ichannel] = posL[1];
2099         posArray[4][ichannel] = posG[0];
2100         posArray[5][ichannel] = posG[1];
2101         posArray[6][ichannel] = (Int_t)(ipad - (Double_t)(tpcROCinstance->GetNPads(isector, irow))/2);
2102         posArray[7][ichannel] = ichannel;
2103         
2104             // loop over array containing AliTPCCalPads
2105         for (Int_t ivalue = 0; ivalue < arrayEntries; ivalue++) {
2106           AliTPCCalPad* calPad = (AliTPCCalPad*) array->At(ivalue);
2107           AliTPCCalROC* calROC = calPad->GetCalROC(isector);
2108                 if (calROC)
2109                   (vectorArray[ivalue])[ichannel] = calROC->GetValue(irow, ipad);
2110           else
2111             (vectorArray[ivalue])[ichannel] = 0;
2112         }
2113         ichannel++;
2114       }
2115     }
2116     
2117     cstream << "calPads" <<
2118       "sector=" << isector;
2119     
2120     for  (Int_t ivalue = 0; ivalue < arrayEntries; ivalue++) {
2121       cstream << "calPads" <<
2122         (Char_t*)((names[ivalue] + "_Median=").Data()) << median[ivalue] <<
2123         (Char_t*)((names[ivalue] + "_Mean=").Data()) << mean[ivalue] <<
2124         (Char_t*)((names[ivalue] + "_RMS=").Data()) << rms[ivalue] <<
2125         (Char_t*)((names[ivalue] + "_LTM=").Data()) << ltm[ivalue] <<
2126         (Char_t*)((names[ivalue] + "_RMS_LTM=").Data()) << ltmrms[ivalue];
2127       if (outlierPad) {
2128         cstream << "calPads" <<
2129           (Char_t*)((names[ivalue] + "_Median_OutlierCutted=").Data()) << medianWithOut[ivalue] <<
2130           (Char_t*)((names[ivalue] + "_Mean_OutlierCutted=").Data()) << meanWithOut[ivalue] <<
2131           (Char_t*)((names[ivalue] + "_RMS_OutlierCutted=").Data()) << rmsWithOut[ivalue] <<
2132           (Char_t*)((names[ivalue] + "_LTM_OutlierCutted=").Data()) << ltmWithOut[ivalue] <<
2133           (Char_t*)((names[ivalue] + "_RMS_LTM_OutlierCutted=").Data()) << ltmrmsWithOut[ivalue];
2134       }
2135         //timestamp and run, if given in title
2136 /*      TString title(((AliTPCCalPad*) array->At(ivalue))->GetTitle());
2137       TObjArray *arrtitle=title.Tokenize(",");
2138       Int_t run=-1;
2139       UInt_t time=0;
2140       TIter next(arrtitle);
2141       TObject *o=0;
2142       while ( (o=next()) ){
2143         TString &entry=((TObjString*)o)->GetString();
2144         entry.Remove(TString::kBoth,' ');
2145         entry.Remove(TString::kBoth,'\t');
2146         if (entry.BeginsWith("Run:")) {
2147           run=entry(4,entry.Length()).Atoi();
2148         } else if (entry.BeginsWith("Time:")) {
2149           time=entry(6,entry.Length()).Atoi();
2150         }
2151       }
2152       delete arrtitle;*/
2153       
2154     }
2155     
2156     for  (Int_t ivalue = 0; ivalue < arrayEntries; ivalue++) {
2157       cstream << "calPads" <<
2158         (Char_t*)((names[ivalue] + ".=").Data()) << &vectorArray[ivalue];
2159     }
2160     
2161     if (mapFileName) {
2162           for  (Int_t ivalue = 0; ivalue < mapEntries; ivalue++) {
2163             if (isector < 36)
2164               cstream << "calPads" <<
2165               (Char_t*)((mapNames[ivalue] + ".=").Data()) << &mapIROCArray[ivalue];
2166             else
2167                 cstream << "calPads" <<
2168               (Char_t*)((mapNames[ivalue] + ".=").Data()) << &mapOROCArray[ivalue];
2169          }
2170     }
2171
2172     cstream << "calPads" <<
2173       "row.=" << &posArray[0] <<
2174       "pad.=" << &posArray[1] <<
2175       "lx.=" << &posArray[2] <<
2176       "ly.=" << &posArray[3] <<
2177       "gx.=" << &posArray[4] <<
2178       "gy.=" << &posArray[5] <<
2179       "rpad.=" << &posArray[6] <<
2180       "channel.=" << &posArray[7];
2181     
2182     cstream << "calPads" <<
2183       "\n";
2184     
2185     delete[] posArray;
2186     delete[] vectorArray;
2187   }
2188   
2189   
2190   delete[] names;
2191   if (mapFileName) {
2192     delete mapIROCs;
2193     delete mapOROCs;
2194     delete[] mapIROCArray;
2195     delete[] mapOROCArray;
2196     delete[] mapNames;
2197   }
2198 }
2199
2200
2201 void AliTPCCalibViewer::MakeTree(const char *outPutFileName, const Char_t *inputFileName, AliTPCCalPad *outlierPad, Float_t ltmFraction, const char *mapFileName ){
2202    // 
2203    // Function to create a calibration Tree with all available information.
2204    // See also documentation to MakeTree   
2205    // the file "inputFileName" must be in the following format (see also CreateObjectList):
2206    // (each colum separated by tabs, "dependingOnType" can have 2 or 3 colums)
2207    // 
2208    // type      path    dependingOnType
2209    // 
2210    // type == "CE":
2211    // dependingOnType = CETmean CEQmean CETrms
2212    // 
2213    // type == "Pulser":
2214    // dependingOnType = PulserTmean     PulsterQmean    PulserTrms
2215    // 
2216    // type == "Pedestals":
2217    // dependingOnType = Pedestals       Noise
2218    // 
2219    // type == "CalPad":
2220    // dependingOnType = NameInFile      NameToWriteToFile
2221    // 
2222    // 
2223    TObjArray objArray;
2224    CreateObjectList(inputFileName, &objArray);
2225    MakeTree(outPutFileName, &objArray, mapFileName, outlierPad, ltmFraction);   
2226 }
2227
2228
2229 void AliTPCCalibViewer::CreateObjectList(const Char_t *filename, TObjArray *calibObjects){
2230    // 
2231    // Function to create a TObjArray out of a given file
2232    // the file must be in the following format:
2233    // (each colum separated by tabs, "dependingOnType" can have 2 or 3 colums)
2234    // 
2235    // 
2236    // type      path    dependingOnType
2237    // 
2238    // type == "CE":
2239    // dependingOnType = CETmean CEQmean CETrms
2240    // 
2241    // type == "Pulser":
2242    // dependingOnType = PulserTmean     PulsterQmean    PulserTrms
2243    // 
2244    // type == "Pedestals":
2245    // dependingOnType = Pedestals       Noise
2246    // 
2247    // type == "CalPad":
2248    // dependingOnType = NameInFile      NameToWriteToFile
2249    // 
2250    // 
2251    // 
2252    if ( calibObjects == 0x0 ) return;
2253    ifstream in;
2254    in.open(filename);
2255    if ( !in.is_open() ){
2256       fprintf(stderr,"Error: cannot open list file '%s'", filename);
2257       return;
2258    }
2259    
2260    AliTPCCalPad *calPad=0x0;
2261    
2262    TString sFile;
2263    sFile.ReadFile(in);
2264    in.close();
2265    
2266    TObjArray *arrFileLine = sFile.Tokenize("\n");
2267    TIter nextLine(arrFileLine);
2268    
2269    TObjString *sObjLine = 0x0;
2270    while ( (sObjLine = (TObjString*)nextLine()) ){
2271       TString sLine(sObjLine->GetString());
2272       
2273       TObjArray *arrCol = sLine.Tokenize("\t");
2274       Int_t nCols = arrCol->GetEntriesFast();
2275       
2276       TObjString *sObjType     = (TObjString*)(arrCol->At(0));
2277       TObjString *sObjFileName = (TObjString*)(arrCol->At(1));
2278       TObjString *sObjName = 0x0;
2279       
2280       if ( !sObjType || !sObjFileName ) continue;
2281       TString sType(sObjType->GetString());
2282       TString sFileName(sObjFileName->GetString());
2283       printf("Type %s, opening %s \n", sType.Data(), sFileName.Data());
2284       TFile *fIn = TFile::Open(sFileName);
2285       if ( !fIn ){
2286          fprintf(stderr,"File not found: '%s'", sFileName.Data());
2287          continue;
2288       }
2289       
2290       if ( sType == "CE" ){  // next three colums are the names for CETmean, CEQmean and CETrms
2291          AliTPCCalibCE *ce = (AliTPCCalibCE*)fIn->Get("AliTPCCalibCE");
2292          calPad = new AliTPCCalPad((TObjArray*)ce->GetCalPadT0());         
2293          if (nCols > 2) {  // check, if the name is provided
2294             sObjName = (TObjString*)(arrCol->At(2));
2295             calPad->SetNameTitle(sObjName->GetString().Data(), sObjName->GetString().Data());
2296          }
2297          else calPad->SetNameTitle("CETmean","CETmean");
2298          calibObjects->Add(calPad);
2299          
2300          calPad = new AliTPCCalPad((TObjArray*)ce->GetCalPadQ());         
2301          if (nCols > 3) {  // check, if the name is provided
2302             sObjName = (TObjString*)(arrCol->At(3));
2303             calPad->SetNameTitle(sObjName->GetString().Data(), sObjName->GetString().Data());
2304          }
2305          else calPad->SetNameTitle("CEQmean","CEQmean");
2306          calibObjects->Add(calPad);        
2307          
2308          calPad = new AliTPCCalPad((TObjArray*)ce->GetCalPadRMS());
2309          if (nCols > 4) {  // check, if the name is provided
2310             sObjName = (TObjString*)(arrCol->At(4));
2311             calPad->SetNameTitle(sObjName->GetString().Data(), sObjName->GetString().Data());
2312          }
2313          else calPad->SetNameTitle("CETrms","CETrms");
2314          calibObjects->Add(calPad);         
2315                   
2316       } else if ( sType == "Pulser") {
2317          AliTPCCalibPulser *sig = (AliTPCCalibPulser*)fIn->Get("AliTPCCalibPulser");
2318          
2319          calPad = new AliTPCCalPad((TObjArray*)sig->GetCalPadT0());         
2320          if (nCols > 2) {
2321             sObjName = (TObjString*)(arrCol->At(2));
2322             calPad->SetNameTitle(sObjName->GetString().Data(), sObjName->GetString().Data());
2323          }
2324          else calPad->SetNameTitle("PulserTmean","PulserTmean");
2325          calibObjects->Add(calPad);
2326          
2327          calPad = new AliTPCCalPad((TObjArray*)sig->GetCalPadQ());         
2328          if (nCols > 3) {
2329             sObjName = (TObjString*)(arrCol->At(3));
2330             calPad->SetNameTitle(sObjName->GetString().Data(), sObjName->GetString().Data());
2331          }
2332          else calPad->SetNameTitle("PulserQmean","PulserQmean");
2333          calibObjects->Add(calPad);        
2334          
2335          calPad = new AliTPCCalPad((TObjArray*)sig->GetCalPadRMS());
2336          if (nCols > 4) {
2337             sObjName = (TObjString*)(arrCol->At(4));
2338             calPad->SetNameTitle(sObjName->GetString().Data(), sObjName->GetString().Data());
2339          }
2340          else calPad->SetNameTitle("PulserTrms","PulserTrms");
2341          calibObjects->Add(calPad);         
2342       
2343       } else if ( sType == "Pedestals") {
2344          AliTPCCalibPedestal *ped = (AliTPCCalibPedestal*)fIn->Get("AliTPCCalibPedestal");
2345          
2346          calPad = new AliTPCCalPad((TObjArray*)ped->GetCalPadPedestal());         
2347          if (nCols > 2) {
2348             sObjName = (TObjString*)(arrCol->At(2));
2349             calPad->SetNameTitle(sObjName->GetString().Data(), sObjName->GetString().Data());
2350          }
2351          else calPad->SetNameTitle("Pedestals","Pedestals");
2352          calibObjects->Add(calPad);
2353          
2354          calPad = new AliTPCCalPad((TObjArray*)ped->GetCalPadRMS());         
2355          if (nCols > 3) {
2356             sObjName = (TObjString*)(arrCol->At(3));
2357             calPad->SetNameTitle(sObjName->GetString().Data(), sObjName->GetString().Data());
2358          }
2359          else calPad->SetNameTitle("Noise","Noise");
2360          calibObjects->Add(calPad);        
2361      
2362       } else if ( sType == "CalPad") {
2363          if (nCols > 2) sObjName = (TObjString*)(arrCol->At(2));
2364          else continue;
2365          calPad = new AliTPCCalPad(*(AliTPCCalPad*)fIn->Get(sObjName->GetString().Data()));
2366          if (nCols > 3) {
2367             sObjName = (TObjString*)(arrCol->At(3));
2368             calPad->SetNameTitle(sObjName->GetString().Data(), sObjName->GetString().Data());
2369          }
2370          calibObjects->Add(calPad);
2371       } else {
2372          fprintf(stderr,"Undefined Type: '%s'",sType.Data());
2373       }
2374       delete fIn;
2375    }
2376 }
2377
2378
2379