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