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