Classes for TPC calibration visualization (Marian, Lars, Stefan)
authormarian <marian@f7af4fe6-9843-0410-8265-dc069ae4e863>
Tue, 22 May 2007 15:37:47 +0000 (15:37 +0000)
committermarian <marian@f7af4fe6-9843-0410-8265-dc069ae4e863>
Tue, 22 May 2007 15:37:47 +0000 (15:37 +0000)
TPC/AliTPCCalibViewer.cxx [new file with mode: 0644]
TPC/AliTPCCalibViewer.h [new file with mode: 0644]
TPC/AliTPCCalibViewerGUI.cxx [new file with mode: 0644]
TPC/AliTPCCalibViewerGUI.h [new file with mode: 0644]

diff --git a/TPC/AliTPCCalibViewer.cxx b/TPC/AliTPCCalibViewer.cxx
new file mode 100644 (file)
index 0000000..f71a4db
--- /dev/null
@@ -0,0 +1,1018 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+
+///////////////////////////////////////////////////////////////////////////////
+//                                                                           //
+//  Class for viewing/visualizing TPC calibration data                       //
+//  base on  TTree functionality for visualization                           //
+///////////////////////////////////////////////////////////////////////////////
+
+//
+// ROOT includes 
+//
+#include <iostream>
+#include <TString.h>
+#include <TRandom.h>
+#include <TLegend.h>
+#include <TLine.h>
+#include <TCanvas.h>
+#include <TROOT.h>
+#include <TStyle.h>
+#include <TH1F.h>
+#include <THashTable.h>
+#include <TObjString.h>
+#include "TTreeStream.h"
+#include "TFile.h"
+#include "TKey.h"
+
+
+//
+// AliRoot includes
+//
+#include "AliTPCCalibViewer.h"
+
+ClassImp(AliTPCCalibViewer)
+
+AliTPCCalibViewer::AliTPCCalibViewer()
+                  :TObject(),
+                   fTree(0),
+                   fFile(0),
+                   fListOfObjectsToBeDeleted(0)
+{
+  //
+  // Default constructor
+  //
+
+}
+
+//_____________________________________________________________________________
+AliTPCCalibViewer::AliTPCCalibViewer(const AliTPCCalibViewer &c)
+                  :TObject(c),
+                   fTree(0),
+                   fFile(0),
+                   fListOfObjectsToBeDeleted(0)
+{
+  //
+  // dummy AliTPCCalibViewer copy constructor
+  // not yet working!!!
+  //
+  fTree = c.fTree;
+  //fFile = new TFile(*(c.fFile));
+  fListOfObjectsToBeDeleted = c.fListOfObjectsToBeDeleted;
+}
+
+//_____________________________________________________________________________
+AliTPCCalibViewer::AliTPCCalibViewer(TTree* tree)
+                  :TObject(),
+                   fTree(0),
+                   fFile(0),
+                   fListOfObjectsToBeDeleted(0)
+{
+  //
+  // Constructor that initializes the calibration viewer
+  //
+  fTree = tree;
+  fListOfObjectsToBeDeleted = new TObjArray();
+}
+
+//_____________________________________________________________________________
+AliTPCCalibViewer::AliTPCCalibViewer(char* fileName, char* treeName)
+                  :TObject(),
+                   fTree(0),
+                   fFile(0),
+                   fListOfObjectsToBeDeleted(0)
+{
+   //
+   // Constructor to initialize the calibration viewer
+   // the file 'fileName' contains the tree 'treeName'
+   //
+   fFile = new TFile(fileName, "read");
+   fTree = (TTree*) fFile->Get(treeName);
+   fListOfObjectsToBeDeleted = new TObjArray();
+}
+                   
+//____________________________________________________________________________
+AliTPCCalibViewer & AliTPCCalibViewer::operator =(const AliTPCCalibViewer & param)
+{
+   //
+   // assignment operator - dummy
+   // not yet working!!!
+   //
+   fTree = param.fTree;
+   //fFile = new TFile(*(param.fFile));
+   fListOfObjectsToBeDeleted = param.fListOfObjectsToBeDeleted;
+   return (*this);
+}
+
+//_____________________________________________________________________________
+AliTPCCalibViewer::~AliTPCCalibViewer()
+{
+   //
+   // AliTPCCalibViewer destructor
+   // all objects will be deleted, the file will be closed, the pictures will disapear
+   //
+   /*if (fTree) {
+      delete fTree;
+      fTree = 0;
+   }*/
+   if (fFile) {
+      fFile->Close();
+      fFile = 0;
+   }
+
+   for (Int_t i = fListOfObjectsToBeDeleted->GetEntriesFast()-1; i >= 0; i--) {
+      //cout << "Index " << i << " trying to delete the following object: " << fListOfObjectsToBeDeleted->At(i)->GetName() << "..."<< endl;
+      delete fListOfObjectsToBeDeleted->At(i);
+   }
+   delete fListOfObjectsToBeDeleted;
+}
+
+//_____________________________________________________________________________
+Int_t AliTPCCalibViewer::EasyDraw(const char* drawCommand, const char* sector, const char* cuts, const char* drawOptions, Bool_t writeDrawCommand) const {
+  //
+  // easy drawing of data, use '~' for abbreviation of '.fElements'
+  // example: EasyDraw("CETmean~-CETmean_mean", "A", "(CETmean~-CETmean_mean)>0")
+ // sector: sector-number - only the specified sector will be drwawn
+  //         'A'/'C' or 'a'/'c' - side A/C will be drawn
+  //         'ALL' - whole TPC will be drawn, projected on one side
+  // cuts: specifies cuts
+  // drawOptions: draw options like 'same'
+  // writeDrawCommand: write the command, that is passed to TTree::Draw
+  //
+   TString drawStr(drawCommand);
+   TString sectorStr(sector);
+   sectorStr.ToUpper();
+   TString cutStr("");
+   TString drawOptionsStr("profcolz ");
+   TRandom rnd(0);
+   Int_t rndNumber = rnd.Integer(10000);
+   if (drawOptions && drawOptions != "")
+      drawOptionsStr += drawOptions;
+
+   if (sectorStr == "A") {
+      drawStr += ":gy.fElements:gx.fElements>>prof";
+      drawStr += rndNumber;
+      drawStr += "(330,-250,250,330,-250,250)";
+      cutStr += "(sector/18)%2==0 ";
+   }
+   else if  (sectorStr == "C") {
+      drawStr += ":gy.fElements:gx.fElements>>prof";
+      drawStr += rndNumber;
+      drawStr += "(330,-250,250,330,-250,250)";
+      cutStr += "(sector/18)%2==1 ";
+   }
+   else if  (sectorStr == "ALL") {
+      drawStr += ":gy.fElements:gx.fElements>>prof";
+      drawStr += rndNumber;
+      drawStr += "(330,-250,250,330,-250,250)";
+   }
+   else if (sectorStr.IsDigit()) {
+      Int_t isec = sectorStr.Atoi();
+      drawStr += ":rpad.fElements:row.fElements>>prof";
+      drawStr += rndNumber;
+      if (isec < 36 && isec >= 0)
+         drawStr += "(63,0,63,108,-54,54)";
+      else if (isec < 72 && isec >= 36)
+         drawStr += "(96,0,96,140,-70,70)";
+      else {
+         Error("EasyDraw","The TPC contains only sectors between 0 and 71.");
+         return -1;
+      }
+      cutStr += "(sector==";
+      cutStr += isec;
+      cutStr += ") ";
+   }
+
+   if (cuts && cuts[0] != 0) {
+      if (cutStr.Length() != 0) cutStr += "&& ";
+      cutStr += "(";
+      cutStr += cuts;
+      cutStr += ")";
+   }
+   drawStr.ReplaceAll("~", ".fElements");
+   cutStr.ReplaceAll("~", ".fElements");
+   if (writeDrawCommand) std::cout << "fTree->Draw(\"" << drawStr << "\", \"" <<  cutStr << "\", \"" << drawOptionsStr << "\");" << std::endl;
+   return fTree->Draw(drawStr.Data(), cutStr.Data(), drawOptionsStr.Data());
+}
+
+Int_t AliTPCCalibViewer::EasyDraw(const char* drawCommand, Int_t sector, const char* cuts, const char* drawOptions, Bool_t writeDrawCommand) const {
+  //
+  // easy drawing of data, use '~' for abbreviation of '.fElements'
+  // example: EasyDraw("CETmean~-CETmean_mean", 34, "(CETmean~-CETmean_mean)>0")
+  // sector: sector-number - only the specified sector will be drwawn
+  // cuts: specifies cuts
+  // drawOptions: draw options like 'same'
+  // writeDrawCommand: write the command, that is passed to TTree::Draw
+  //
+   if (sector >= 0 && sector < 72) {
+      char sectorChr[3];
+      sprintf(sectorChr, "%i", sector);
+      return EasyDraw(drawCommand, sectorChr, cuts, drawOptions, writeDrawCommand);
+   }
+   Error("EasyDraw","The TPC contains only sectors between 0 and 71.");
+   return -1;
+}
+
+//_____________________________________________________________________________
+Int_t AliTPCCalibViewer::EasyDraw1D(const char* drawCommand, const char* sector, const char* cuts, const char* drawOptions, Bool_t writeDrawCommand) const {
+  //
+  // easy drawing of data, use '~' for abbreviation of '.fElements'
+  // example: EasyDraw("CETmean~-CETmean_mean", "A", "(CETmean~-CETmean_mean)>0")
+  // sector: sector-number - the specified sector will be drwawn
+  //         'A'/'C' or 'a'/'c' - side A/C will be drawn
+  //         'ALL' - whole TPC will be drawn, projected on one side
+  // cuts: specifies cuts
+  // drawOptions: draw options like 'same'
+  // writeDrawCommand: write the command, that is passed to TTree::Draw
+  //
+
+   TString drawStr(drawCommand);
+   TString sectorStr(sector);
+   TString drawOptionsStr(drawOptions);
+   sectorStr.ToUpper();
+   TString cutStr("");
+
+   if (sectorStr == "A")
+      cutStr += "(sector/18)%2==0 ";
+   else if  (sectorStr == "C")
+      cutStr += "(sector/18)%2==1 ";
+   else if (sectorStr.IsDigit()) {
+      Int_t isec = sectorStr.Atoi();
+      if (isec < 0 || isec > 71) {
+         Error("EasyDraw","The TPC contains only sectors between 0 and 71.");
+         return -1;
+      }
+      cutStr += "(sector==";
+      cutStr += isec;
+      cutStr += ") ";
+   }
+
+   if (cuts && cuts[0] != 0) {
+      if (cutStr.Length() != 0) cutStr += "&& ";
+      cutStr += "(";
+      cutStr += cuts;
+      cutStr += ")";
+   }
+
+   drawStr.ReplaceAll("~", ".fElements");
+   cutStr.ReplaceAll("~", ".fElements");
+   if (writeDrawCommand) std::cout << "fTree->Draw(\"" << drawStr << "\", \"" <<  cutStr << "\", \"" << drawOptionsStr << "\");" << std::endl;
+   return fTree->Draw(drawStr.Data(), cutStr.Data(), drawOptionsStr.Data());
+}
+
+Int_t AliTPCCalibViewer::EasyDraw1D(const char* drawCommand, Int_t sector, const char* cuts, const char* drawOptions, Bool_t writeDrawCommand) const {
+  //
+  // easy drawing of data, use '~' for abbreviation of '.fElements'
+  // example: EasyDraw("CETmean~-CETmean_mean", 34, "(CETmean~-CETmean_mean)>0")
+  // sector: sector-number - the specified sector will be drwawn
+  // cuts: specifies cuts
+  // drawOptions: draw options like 'same'
+  // writeDrawCommand: write the command, that is passed to TTree::Draw
+  //
+
+   if (sector >= 0 && sector < 72) {
+      char sectorChr[3];
+      sprintf(sectorChr, "%i", sector);
+      return EasyDraw1D(drawCommand, sectorChr, cuts, drawOptions, writeDrawCommand);
+   }
+  Error("EasyDraw","The TPC contains only sectors between 0 and 71.");
+  return -1;
+}
+
+//_____________________________________________________________________________
+Int_t AliTPCCalibViewer::DrawHisto1D(const char* type, Int_t sector, TVectorF& nsigma, Bool_t plotMean, Bool_t plotMedian, Bool_t plotLTM) const {
+  //
+  // draws a 1-dimensional histogram of 'type' for sector 'sector'
+  // TVectorF nsigma: Specifies, for which distances from the mean/median/LTM lines should be drawn, in units of sigma
+  // example: nsigma={2, 4, 6}: Three lines will be drawn, distance to mean/median/LTM: 2, 3 and 6 sigma
+  // plotMean, plotMedian, plotLTM: specifies, if mean, median and LTM should be drawn as lines into the histogram
+  //
+
+   TString typeStr(type);
+   TString sectorStr("sector==");
+   sectorStr += sector;
+
+   TCanvas* canvas = ((TCanvas*)gROOT->GetListOfCanvases()->Last());
+   Int_t oldOptStat = gStyle->GetOptStat();
+   gStyle->SetOptStat(0000000);
+
+   if (!canvas) {
+      canvas = new TCanvas();
+      fListOfObjectsToBeDeleted->Add(canvas);
+   }
+   
+   char c[500];
+   sprintf(c, "%s, sector: %i", type, sector);
+   TLegend * legend = new TLegend(.8,.6, .99, .99, c);
+   fListOfObjectsToBeDeleted->Add(legend);
+
+   Int_t nentries = fTree->Draw((typeStr+".fElements").Data(), sectorStr.Data(), "");
+   ((TH1F*)canvas->GetPrimitive("htemp"))->SetTitle("");
+      
+   //****************************************************************
+   //!!!!!!!!!!!!!!!!! Needs further investigaton !!!!!!!!!!!!!!!!!!!
+   //****************************************************************
+   //fListOfObjectsToBeDeleted->Add(canvas->GetPrimitive("htemp"));
+/*
+  By default the temporary histogram created is called "htemp", but only in
+  the one dimensional Draw("e1") it contains the TTree's data points. For
+  a two dimensional Draw, the data is filled into a TGraph which is named
+  "Graph". They can be retrieved by calling
+    TH1F *htemp = (TH1F*)gPad->GetPrimitive("htemp"); // 1D
+    TGraph *graph = (TGraph*)gPad->GetPrimitive("Graph"); // 2D
+*/
+   
+   canvas->Update();
+   Double_t sigma = 0;
+
+   if (plotMean) {
+      fTree->Draw((typeStr+"_Mean").Data(), sectorStr.Data(), "goff");
+      Double_t lineX = fTree->GetV1()[0];
+      fTree->Draw((typeStr+"_RMS").Data(), sectorStr.Data(), "goff");
+      sigma = fTree->GetV1()[0];
+      TLine* line = new TLine(lineX, 0, lineX, canvas->GetUymax());
+      fListOfObjectsToBeDeleted->Add(line);
+      line->SetLineColor(kRed);
+      line->SetLineWidth(2);
+      line->SetLineStyle(1);
+      line->Draw();
+      sprintf(c, "Mean: %f", lineX);
+      legend->AddEntry(line, c, "l");
+
+      for (Int_t i = 0; i < nsigma.GetNoElements(); i++) {
+         TLine* linePlusSigma = new TLine(lineX+nsigma[i]*sigma, 0, lineX+nsigma[i]*sigma, canvas->GetUymax());
+         fListOfObjectsToBeDeleted->Add(linePlusSigma);
+         linePlusSigma->SetLineColor(kRed);
+         linePlusSigma->SetLineStyle(2+i);
+         linePlusSigma->Draw();
+   
+         TLine* lineMinusSigma = new TLine(lineX-nsigma[i]*sigma, 0, lineX-nsigma[i]*sigma, canvas->GetUymax());
+         fListOfObjectsToBeDeleted->Add(lineMinusSigma);
+         lineMinusSigma->SetLineColor(kRed);
+         lineMinusSigma->SetLineStyle(2+i);
+         lineMinusSigma->Draw();
+         sprintf(c, "%i #sigma = %f",(Int_t)(nsigma[i]), (Float_t)(nsigma[i]*sigma));
+        std::cout << "nsigma-char*: " << c << std::endl;
+         legend->AddEntry(lineMinusSigma, c, "l");
+      }
+   }
+
+   if (plotMedian) {
+      fTree->Draw((typeStr+"_Median").Data(), sectorStr.Data(), "goff");
+      Double_t lineX = fTree->GetV1()[0];
+      fTree->Draw((typeStr+"_RMS").Data(), sectorStr.Data(), "goff");
+      sigma = fTree->GetV1()[0];
+      TLine* line = new TLine(lineX, 0, lineX, canvas->GetUymax());
+      fListOfObjectsToBeDeleted->Add(line);
+      line->SetLineColor(kBlue);
+      line->SetLineWidth(2);
+      line->SetLineStyle(1);
+      line->Draw();
+      sprintf(c, "Median: %f", lineX);
+      legend->AddEntry(line, c, "l");
+      
+      for (Int_t i = 0; i < nsigma.GetNoElements(); i++) {
+         TLine* linePlusSigma = new TLine(lineX+nsigma[i]*sigma, 0, lineX+nsigma[i]*sigma, canvas->GetUymax());
+         fListOfObjectsToBeDeleted->Add(linePlusSigma);
+         linePlusSigma->SetLineColor(kBlue);
+         linePlusSigma->SetLineStyle(2+i);
+         linePlusSigma->Draw();
+   
+         TLine* lineMinusSigma = new TLine(lineX-nsigma[i]*sigma, 0, lineX-nsigma[i]*sigma, canvas->GetUymax());
+         fListOfObjectsToBeDeleted->Add(lineMinusSigma);
+         lineMinusSigma->SetLineColor(kBlue);
+         lineMinusSigma->SetLineStyle(2+i);
+         lineMinusSigma->Draw();
+         sprintf(c, "%i #sigma = %f",(Int_t)(nsigma[i]), (Float_t)(nsigma[i]*sigma));
+         legend->AddEntry(lineMinusSigma, c, "l");
+      }
+   }
+   
+   if (plotLTM) {
+      fTree->Draw((typeStr+"_LTM").Data(), sectorStr.Data(), "goff");
+      Double_t lineX = fTree->GetV1()[0];
+      fTree->Draw((typeStr+"_RMS_LTM").Data(), sectorStr.Data(), "goff");
+      sigma = fTree->GetV1()[0];
+      TLine* line = new TLine(lineX, 0, lineX, canvas->GetUymax());
+      fListOfObjectsToBeDeleted->Add(line);
+      line->SetLineColor(kGreen+2);
+      line->SetLineWidth(2);
+      line->SetLineStyle(1);
+      line->Draw();
+      sprintf(c, "LTM: %f", lineX);
+      legend->AddEntry(line, c, "l");
+
+      for (Int_t i = 0; i < nsigma.GetNoElements(); i++) {
+         TLine* linePlusSigma = new TLine(lineX+nsigma[i]*sigma, 0, lineX+nsigma[i]*sigma, canvas->GetUymax());
+         fListOfObjectsToBeDeleted->Add(linePlusSigma);
+         linePlusSigma->SetLineColor(kGreen+2);
+         linePlusSigma->SetLineStyle(2+i);
+         linePlusSigma->Draw();
+   
+         TLine* lineMinusSigma = new TLine(lineX-nsigma[i]*sigma, 0, lineX-nsigma[i]*sigma, canvas->GetUymax());
+         fListOfObjectsToBeDeleted->Add(lineMinusSigma);
+         lineMinusSigma->SetLineColor(kGreen+2);
+         lineMinusSigma->SetLineStyle(2+i);
+         lineMinusSigma->Draw();
+         sprintf(c, "%i #sigma = %f", (Int_t)(nsigma[i]), (Float_t)(nsigma[i]*sigma));
+         legend->AddEntry(lineMinusSigma, c, "l");
+      }
+   }
+   legend->Draw();
+   gStyle->SetOptStat(oldOptStat);
+   return nentries;
+}
+
+//_____________________________________________________________________________
+void AliTPCCalibViewer::SigmaCut(const char* type, Int_t sector, Float_t sigmaMax, Float_t sigmaStep, Bool_t plotMean, Bool_t plotMedian, Bool_t plotLTM) const {
+  //
+  // Creates a histogram, where you can see, how much of the data are inside sigma-intervals around the mean/median/LTM
+  // type: For which type of data the histogram is generated, e.g. 'CEQmean'
+  // sector: For which sector the histogram is generated
+  // sigmaMax: up to which sigma around the mean/median/LTM the histogram is generated
+  // sigmaStep: the binsize of the generated histogram
+  // plotMean/plotMedian/plotLTM: specifies where to put the center
+  //
+   Int_t oldOptStat = gStyle->GetOptStat();
+   gStyle->SetOptStat(0000000);
+
+   TString typeStr(type);
+   TString sectorStr("sector==");
+   sectorStr += sector;
+   Int_t entries = fTree->Draw((typeStr+".fElements").Data(), sectorStr.Data(), "goff");
+   char headline[500];
+   sprintf(headline, "%s in sector %i; Multiples of #sigma; Fraction of used pads", type, sector);
+   TH1F *histMean =   new TH1F("histMean",headline, (Int_t)(sigmaMax/sigmaStep+1), 0, sigmaMax+sigmaStep);
+   sprintf(headline, "%s in sector %i; Multiples of #sigma; Fraction of used pads", type, sector);
+   TH1F *histMedian = new TH1F("histMedian",headline, (Int_t)(sigmaMax/sigmaStep+1), 0, sigmaMax+sigmaStep);
+   sprintf(headline, "%s in sector %i; Multiples of #sigma; Fraction of used pads", type, sector);
+   TH1F *histLTM =    new TH1F("histLTM",headline, (Int_t)(sigmaMax/sigmaStep+1), 0, sigmaMax+sigmaStep);                                                                   
+   histMean->SetDirectory(0);
+   histMedian->SetDirectory(0);
+   histLTM->SetDirectory(0);
+   fListOfObjectsToBeDeleted->Add(histMean);
+   fListOfObjectsToBeDeleted->Add(histMedian);
+   fListOfObjectsToBeDeleted->Add(histLTM);
+
+   
+   // example-cut: sector==34 && TMath::Abs(CEQmean.fElements - CEQmean_Mean) < nsigma * CEQmean_RMS
+   for (Float_t nsigma = 0; nsigma <= sigmaMax; nsigma += sigmaStep) {
+     std::cout << "Calculating histograms,  step: " << (Int_t)(nsigma/sigmaStep) << " of: " << (Int_t)(sigmaMax/sigmaStep) << "\r" << std::flush;
+      char cuts[5000];
+      
+      if (plotMean) {
+         sprintf(cuts, "sector==%i && ( %s.fElements - %s_Median) < %f * %s_RMS", sector, type, type, nsigma, type );
+         sprintf(cuts,         "%s && (-%s.fElements + %s_Median) < %f * %s_RMS",   cuts, type, type, nsigma, type );
+         Float_t value = (Float_t)fTree->Draw((typeStr+".fElements").Data(), cuts, "goff")/entries;
+         histMean->Fill(nsigma, value);
+      }
+      if (plotMedian) {
+         sprintf(cuts, "sector==%i && ( %s.fElements - %s_Mean) < %f * %s_RMS", sector, type, type, nsigma, type );
+         sprintf(cuts,         "%s && (-%s.fElements + %s_Mean) < %f * %s_RMS",   cuts, type, type, nsigma, type );
+         Float_t value = (Float_t)fTree->Draw((typeStr+".fElements").Data(), cuts, "goff")/entries;
+         histMedian->Fill(nsigma, value);
+      }
+      if (plotLTM) {
+         sprintf(cuts, "sector==%i && ( %s.fElements - %s_LTM) < %f * %s_RMS_LTM", sector, type, type, nsigma, type );
+         sprintf(cuts,         "%s && (-%s.fElements + %s_LTM) < %f * %s_RMS_LTM",   cuts, type, type, nsigma, type );
+         Float_t value = (Float_t)fTree->Draw((typeStr+".fElements").Data(), cuts, "goff")/entries;
+         histLTM->Fill(nsigma, value);
+      }
+   }
+   
+   char c[500];
+   sprintf(c, "Sigma Cut");
+   TLegend * legend = new TLegend(.85,.8, .99, .99, c);
+   fListOfObjectsToBeDeleted->Add(legend);
+   
+   if (plotMean){
+      histMean->SetLineColor(kBlack);
+      sprintf(c, "Mean");
+      legend->AddEntry(histMean, c, "l");
+      histMean->Draw();
+   }
+   if (plotMedian){
+      histMedian->SetLineColor(kRed);
+      sprintf(c, "Median");
+      legend->AddEntry(histMedian, c, "l");
+      histMedian->Draw("same");
+   }
+   if (plotLTM){
+      histLTM->SetLineColor(kBlue);
+      sprintf(c, "LTM");
+      legend->AddEntry(histLTM, c, "l");
+      histLTM->Draw("same");
+   }   
+
+   legend->Draw();
+   gStyle->SetOptStat(oldOptStat);
+}
+
+
+//_____________________________________________________________________________
+AliTPCCalPad* AliTPCCalibViewer::GetCalPad(const char* desiredData, char* cuts, char* calPadName) const {
+  //
+  // creates a AliTPCCalPad out of the 'desiredData'
+  // the functionality of EasyDraw1D is used
+  // calPadName specifies the name of the created AliTPCCalPad
+  //  - this takes a while -
+  //
+   TString drawStr(desiredData);
+   drawStr.Append(":channel~");
+   AliTPCCalPad * createdCalPad = new AliTPCCalPad(calPadName, calPadName);
+   Int_t entries = 0;
+   for (Int_t sec = 0; sec < 72; sec++) {
+      entries = EasyDraw1D(drawStr.Data(), (Int_t)sec, cuts, "goff");
+      for (Int_t i = 0; i < entries; i++) 
+         createdCalPad->GetCalROC(sec)->SetValue((UInt_t)(fTree->GetV2()[i]), (Float_t)(fTree->GetV1()[i]));
+   }
+   return createdCalPad;   
+}
+
+//_____________________________________________________________________________
+AliTPCCalROC* AliTPCCalibViewer::GetCalROC(const char* desiredData, UInt_t sector, char* cuts) const {
+  //
+  // creates a AliTPCCalROC out of the desiredData
+  // the functionality of EasyDraw1D is used
+  // sector specifies the sector of the created AliTPCCalROC
+  //
+   TString drawStr(desiredData);
+   drawStr.Append(":channel~");
+   Int_t entries = EasyDraw1D(drawStr.Data(), (Int_t)sector, cuts, "goff");
+   AliTPCCalROC * createdROC = new AliTPCCalROC(sector);
+   for (Int_t i = 0; i < entries; i++) 
+      createdROC->SetValue((UInt_t)(fTree->GetV2()[i]), fTree->GetV1()[i]);
+   return createdROC;
+}
+
+
+TObjArray* AliTPCCalibViewer::GetListOfVariables(Bool_t printList) {
+  //
+  // scan the tree  - produces a list of available variables in the tree
+  // printList: print the list to the screen, after the scan is done
+  //
+   TObjArray* arr = new TObjArray();
+   TObjString* str = 0;
+   Int_t nentries = fTree->GetListOfBranches()->GetEntries();
+   for (Int_t i = 0; i < nentries; i++) {
+      str = new TObjString(fTree->GetListOfBranches()->At(i)->GetName());
+      str->String().ReplaceAll("_Median", "");
+      str->String().ReplaceAll("_Mean", "");
+      str->String().ReplaceAll("_RMS", "");
+      str->String().ReplaceAll("_LTM", "");
+      str->String().ReplaceAll("_OutlierCutted", "");
+      str->String().ReplaceAll(".", "");
+      if (!arr->FindObject(str) && 
+          !(str->String() == "channel" || str->String() == "gx" || str->String() == "gy" || 
+            str->String() == "lx" || str->String() == "ly" || str->String() == "pad" || 
+            str->String() == "row" || str->String() == "rpad" || str->String() == "sector"  ))
+         arr->Add(str);
+   }
+   arr->Sort();
+
+   if (printList) {
+      TIterator* iter = arr->MakeIterator();
+      iter->Reset();
+      TObjString* currentStr = 0;
+      while ( (currentStr = (TObjString*)(iter->Next())) ) {
+         std::cout << currentStr->GetString().Data() << std::endl;
+      }
+      delete iter;
+   }
+   return arr;
+}
+
+
+TObjArray* AliTPCCalibViewer::GetListOfNormalizationVariables(Bool_t printList) {
+  //
+  // produces a list of available variables for normalization in the tree
+  // printList: print the list to the screen, after the scan is done
+  //
+   TObjArray* arr = new TObjArray();
+   arr->Add(new TObjString("_Mean"));
+   arr->Add(new TObjString("_Mean_OutlierCutted"));
+   arr->Add(new TObjString("_Median"));
+   arr->Add(new TObjString("_Median_OutlierCutted"));
+   arr->Add(new TObjString("_LTM"));
+   arr->Add(new TObjString("_LTM_OutlierCutted"));
+   arr->Add(new TObjString("LFitIntern_4_8.fElements"));
+   arr->Add(new TObjString("GFitIntern_Lin.fElements"));
+   arr->Add(new TObjString("GFitIntern_Par.fElements"));
+
+   if (printList) {
+      TIterator* iter = arr->MakeIterator();
+      iter->Reset();
+      TObjString* currentStr = 0;
+      while ((currentStr = (TObjString*)(iter->Next()))) {
+         std::cout << currentStr->GetString().Data() << std::endl;
+      }
+      delete iter;
+   }
+   return arr;
+}
+
+
+TFriendElement* AliTPCCalibViewer::AddReferenceTree(const char* filename, const char* treename, const char* refname){
+  //
+  // add a reference tree to the current tree
+  // by default the treename is 'calPads' and the reference treename is 'R'
+  //
+   TFile *file = new TFile(filename);
+   fListOfObjectsToBeDeleted->Add(file);
+   TTree * tree = (TTree*)file->Get(treename);
+   return AddFriend(tree, refname);
+}
+
+
+TObjArray* AliTPCCalibViewer::GetArrayOfCalPads(){
+  //
+  // Returns a TObjArray with all AliTPCCalPads that are stored in the tree
+  //  - this takes a while - 
+  //
+   TObjArray *listOfCalPads = GetListOfVariables();
+   TObjArray *calPadsArray = new TObjArray();
+   Int_t numberOfCalPads = listOfCalPads->GetEntries();
+   for (Int_t i = 0; i < numberOfCalPads; i++) {
+     std::cout << "Creating calPad " << (i+1) << " of " << numberOfCalPads << "\r" << std::flush;
+      char* calPadName = (char*)((TObjString*)(listOfCalPads->At(i)))->GetString().Data();
+      TString drawCommand = ((TObjString*)(listOfCalPads->At(i)))->GetString();
+      drawCommand.Append("~");
+      AliTPCCalPad* calPad = GetCalPad(drawCommand.Data(), "", calPadName); 
+      calPadsArray->Add(calPad); 
+   }
+   std::cout << std::endl;
+   listOfCalPads->Delete();
+   delete listOfCalPads;
+   return calPadsArray;
+}
+
+
+void AliTPCCalibViewer::MakeTreeWithObjects(const char * fileName, TObjArray * array, const char * mapFileName) {
+  //
+  // Write tree with all available information
+  // im mapFileName is speciefied, the Map information are also written to the tree
+  // AliTPCCalPad-Objects are written directly to the tree, so that they can be accessd later on
+  // (does not work!!!)
+  //
+   AliTPCROC* tpcROCinstance = AliTPCROC::Instance();
+
+   TObjArray* mapIROCs = 0;
+   TObjArray* mapOROCs = 0;
+   TVectorF *mapIROCArray = 0;
+   TVectorF *mapOROCArray = 0;
+   Int_t mapEntries = 0;
+   TString* mapNames = 0;
+   
+   if (mapFileName) {
+      TFile mapFile(mapFileName, "read");
+      
+      TList* listOfROCs = mapFile.GetListOfKeys();
+      mapEntries = listOfROCs->GetEntries()/2;
+      mapIROCs = new TObjArray(mapEntries*2);
+      mapOROCs = new TObjArray(mapEntries*2);
+      mapIROCArray = new TVectorF[mapEntries];
+      mapOROCArray = new TVectorF[mapEntries];
+      
+      mapNames = new TString[mapEntries];
+      for (Int_t ivalue = 0; ivalue < mapEntries; ivalue++) {
+         TString ROCname(((TKey*)(listOfROCs->At(ivalue*2)))->GetName());
+         ROCname.Remove(ROCname.Length()-4, 4);
+         mapIROCs->AddAt((AliTPCCalROC*)mapFile.Get((ROCname + "IROC").Data()), ivalue);
+         mapOROCs->AddAt((AliTPCCalROC*)mapFile.Get((ROCname + "OROC").Data()), ivalue);
+         mapNames[ivalue].Append(ROCname);
+      }
+      
+      for (Int_t ivalue = 0; ivalue < mapEntries; ivalue++) {
+         mapIROCArray[ivalue].ResizeTo(tpcROCinstance->GetNChannels(0));
+         mapOROCArray[ivalue].ResizeTo(tpcROCinstance->GetNChannels(36));
+      
+         for (UInt_t ichannel = 0; ichannel < tpcROCinstance->GetNChannels(0); ichannel++)
+            (mapIROCArray[ivalue])[ichannel] = ((AliTPCCalROC*)(mapIROCs->At(ivalue)))->GetValue(ichannel);
+         for (UInt_t ichannel = 0; ichannel < tpcROCinstance->GetNChannels(36); ichannel++)
+            (mapOROCArray[ivalue])[ichannel] = ((AliTPCCalROC*)(mapOROCs->At(ivalue)))->GetValue(ichannel);
+      }
+
+   } //  if (mapFileName)
+  
+   TTreeSRedirector cstream(fileName);
+   Int_t arrayEntries = array->GetEntries();
+   
+   // Read names of AliTPCCalPads and save them in names[]
+   TString* names = new TString[arrayEntries];
+   for (Int_t ivalue = 0; ivalue < arrayEntries; ivalue++)
+      names[ivalue].Append(((AliTPCCalPad*)array->At(ivalue))->GetName());
+
+   for (UInt_t isector = 0; isector < tpcROCinstance->GetNSectors(); isector++) {
+      
+      TVectorF *vectorArray = new TVectorF[arrayEntries];
+      for (Int_t ivalue = 0; ivalue < arrayEntries; ivalue++)
+         vectorArray[ivalue].ResizeTo(tpcROCinstance->GetNChannels(isector));
+            
+      
+      //
+      // fill vectors of variable per pad
+      //
+      TVectorF *posArray = new TVectorF[8];
+      for (Int_t ivalue = 0; ivalue < 8; ivalue++)
+         posArray[ivalue].ResizeTo(tpcROCinstance->GetNChannels(isector));
+
+      Float_t posG[3] = {0};
+      Float_t posL[3] = {0};
+      Int_t ichannel = 0;
+      for (UInt_t irow = 0; irow < tpcROCinstance->GetNRows(isector); irow++) {
+         for (UInt_t ipad = 0; ipad < tpcROCinstance->GetNPads(isector, irow); ipad++) {
+            tpcROCinstance->GetPositionLocal(isector, irow, ipad, posL);
+            tpcROCinstance->GetPositionGlobal(isector, irow, ipad, posG);
+            posArray[0][ichannel] = irow;
+            posArray[1][ichannel] = ipad;
+            posArray[2][ichannel] = posL[0];
+            posArray[3][ichannel] = posL[1];
+            posArray[4][ichannel] = posG[0];
+            posArray[5][ichannel] = posG[1];
+            posArray[6][ichannel] = (Int_t)(ipad - (Double_t)(tpcROCinstance->GetNPads(isector, irow))/2);
+            posArray[7][ichannel] = ichannel;
+            
+            // loop over array containing AliTPCCalPads
+            for (Int_t ivalue = 0; ivalue < arrayEntries; ivalue++) {
+               AliTPCCalPad* calPad = (AliTPCCalPad*) array->At(ivalue);
+               AliTPCCalROC* calROC = calPad->GetCalROC(isector);
+               if (calROC)
+                  (vectorArray[ivalue])[ichannel] = calROC->GetValue(irow, ipad);
+               else
+                  (vectorArray[ivalue])[ichannel] = 0;
+            }
+            ichannel++;
+         }
+      }
+      AliTPCCalROC dummyROC(0);
+      for  (Int_t ivalue = 0; ivalue < arrayEntries; ivalue++) {
+         AliTPCCalROC *roc = ((AliTPCCalPad*)array->At(ivalue))->GetCalROC(isector);
+         if (!roc) roc = &dummyROC;
+         cstream << "calPads" <<
+            (Char_t*)((names[ivalue] + ".=").Data()) << &vectorArray[ivalue];
+         cstream << "calPads" << 
+            (Char_t*)((names[ivalue] + "Pad.=").Data()) << roc;
+      }
+
+      if (mapFileName) {
+         for  (Int_t ivalue = 0; ivalue < mapEntries; ivalue++) {
+            if (isector < 36)
+               cstream << "calPads" <<
+                  (Char_t*)((mapNames[ivalue] + ".=").Data()) << &mapIROCArray[ivalue];
+            else
+               cstream << "calPads" <<
+                  (Char_t*)((mapNames[ivalue] + ".=").Data()) << &mapOROCArray[ivalue];
+         }
+      }
+      
+      cstream << "calPads" <<
+         "sector=" << isector;
+
+      cstream << "calPads" <<
+         "row.=" << &posArray[0] <<
+         "pad.=" << &posArray[1] <<
+         "lx.=" << &posArray[2] <<
+         "ly.=" << &posArray[3] <<
+         "gx.=" << &posArray[4] <<
+         "gy.=" << &posArray[5] <<
+         "rpad.=" << &posArray[6] <<
+         "channel.=" << &posArray[7];
+
+      cstream << "calPads" <<
+         "\n";
+
+      delete[] posArray;
+      delete[] vectorArray;
+   } //for (UInt_t isector = 0; isector < tpcROCinstance->GetNSectors(); isector++)
+
+   delete[] names;
+   if (mapFileName) {
+      delete mapIROCs;
+      delete mapOROCs;
+      delete[] mapIROCArray;
+      delete[] mapOROCArray;
+      delete[] mapNames;
+   }
+}
+
+void AliTPCCalibViewer::MakeTree(const char * fileName, TObjArray * array, const char * mapFileName, AliTPCCalPad* outlierPad, Float_t ltmFraction) {
+  //
+  // Write a tree with all available information
+  // im mapFileName is speciefied, the Map information are also written to the tree
+  // pads specified in outlierPad are not used for calculating statistics
+  //  - the same function as AliTPCCalPad::MakeTree - 
+  //
+   AliTPCROC* tpcROCinstance = AliTPCROC::Instance();
+
+   TObjArray* mapIROCs = 0;
+   TObjArray* mapOROCs = 0;
+   TVectorF *mapIROCArray = 0;
+   TVectorF *mapOROCArray = 0;
+   Int_t mapEntries = 0;
+   TString* mapNames = 0;
+   
+   if (mapFileName) {
+      TFile mapFile(mapFileName, "read");
+      
+      TList* listOfROCs = mapFile.GetListOfKeys();
+      mapEntries = listOfROCs->GetEntries()/2;
+      mapIROCs = new TObjArray(mapEntries*2);
+      mapOROCs = new TObjArray(mapEntries*2);
+      mapIROCArray = new TVectorF[mapEntries];
+      mapOROCArray = new TVectorF[mapEntries];
+      
+      mapNames = new TString[mapEntries];
+      for (Int_t ivalue = 0; ivalue < mapEntries; ivalue++) {
+         TString ROCname(((TKey*)(listOfROCs->At(ivalue*2)))->GetName());
+         ROCname.Remove(ROCname.Length()-4, 4);
+         mapIROCs->AddAt((AliTPCCalROC*)mapFile.Get((ROCname + "IROC").Data()), ivalue);
+         mapOROCs->AddAt((AliTPCCalROC*)mapFile.Get((ROCname + "OROC").Data()), ivalue);
+         mapNames[ivalue].Append(ROCname);
+      }
+      
+      for (Int_t ivalue = 0; ivalue < mapEntries; ivalue++) {
+         mapIROCArray[ivalue].ResizeTo(tpcROCinstance->GetNChannels(0));
+         mapOROCArray[ivalue].ResizeTo(tpcROCinstance->GetNChannels(36));
+      
+         for (UInt_t ichannel = 0; ichannel < tpcROCinstance->GetNChannels(0); ichannel++)
+            (mapIROCArray[ivalue])[ichannel] = ((AliTPCCalROC*)(mapIROCs->At(ivalue)))->GetValue(ichannel);
+         for (UInt_t ichannel = 0; ichannel < tpcROCinstance->GetNChannels(36); ichannel++)
+            (mapOROCArray[ivalue])[ichannel] = ((AliTPCCalROC*)(mapOROCs->At(ivalue)))->GetValue(ichannel);
+      }
+
+   } //  if (mapFileName)
+  
+   TTreeSRedirector cstream(fileName);
+   Int_t arrayEntries = array->GetEntries();
+   
+   TString* names = new TString[arrayEntries];
+   for (Int_t ivalue = 0; ivalue < arrayEntries; ivalue++)
+      names[ivalue].Append(((AliTPCCalPad*)array->At(ivalue))->GetName());
+
+   for (UInt_t isector = 0; isector < tpcROCinstance->GetNSectors(); isector++) {
+      //
+      // get statistic for given sector
+      //
+      TVectorF median(arrayEntries);
+      TVectorF mean(arrayEntries);
+      TVectorF rms(arrayEntries);
+      TVectorF ltm(arrayEntries);
+      TVectorF ltmrms(arrayEntries);
+      TVectorF medianWithOut(arrayEntries);
+      TVectorF meanWithOut(arrayEntries);
+      TVectorF rmsWithOut(arrayEntries);
+      TVectorF ltmWithOut(arrayEntries);
+      TVectorF ltmrmsWithOut(arrayEntries);
+      
+      TVectorF *vectorArray = new TVectorF[arrayEntries];
+      for (Int_t ivalue = 0; ivalue < arrayEntries; ivalue++)
+         vectorArray[ivalue].ResizeTo(tpcROCinstance->GetNChannels(isector));
+      
+      for (Int_t ivalue = 0; ivalue < arrayEntries; ivalue++) {
+         AliTPCCalPad* calPad = (AliTPCCalPad*) array->At(ivalue);
+         AliTPCCalROC* calROC = calPad->GetCalROC(isector);
+         AliTPCCalROC* outlierROC = 0;
+         if (outlierPad) outlierROC = outlierPad->GetCalROC(isector);
+         if (calROC) {
+            median[ivalue] = calROC->GetMedian();
+            mean[ivalue] = calROC->GetMean();
+            rms[ivalue] = calROC->GetRMS();
+            Double_t ltmrmsValue = 0;
+            ltm[ivalue] = calROC->GetLTM(&ltmrmsValue, ltmFraction);
+            ltmrms[ivalue] = ltmrmsValue;
+            if (outlierROC) {
+               medianWithOut[ivalue] = calROC->GetMedian(outlierROC);
+               meanWithOut[ivalue] = calROC->GetMean(outlierROC);
+               rmsWithOut[ivalue] = calROC->GetRMS(outlierROC);
+               ltmrmsValue = 0;
+               ltmWithOut[ivalue] = calROC->GetLTM(&ltmrmsValue, ltmFraction, outlierROC);
+               ltmrmsWithOut[ivalue] = ltmrmsValue;
+            }
+         }
+         else {
+            median[ivalue] = 0.;
+            mean[ivalue] = 0.;
+            rms[ivalue] = 0.;
+            ltm[ivalue] = 0.;
+            ltmrms[ivalue] = 0.;
+            medianWithOut[ivalue] = 0.;
+            meanWithOut[ivalue] = 0.;
+            rmsWithOut[ivalue] = 0.;
+            ltmWithOut[ivalue] = 0.;
+            ltmrmsWithOut[ivalue] = 0.;
+         }
+      }
+      
+      //
+      // fill vectors of variable per pad
+      //
+      TVectorF *posArray = new TVectorF[8];
+      for (Int_t ivalue = 0; ivalue < 8; ivalue++)
+         posArray[ivalue].ResizeTo(tpcROCinstance->GetNChannels(isector));
+
+      Float_t posG[3] = {0};
+      Float_t posL[3] = {0};
+      Int_t ichannel = 0;
+      for (UInt_t irow = 0; irow < tpcROCinstance->GetNRows(isector); irow++) {
+         for (UInt_t ipad = 0; ipad < tpcROCinstance->GetNPads(isector, irow); ipad++) {
+            tpcROCinstance->GetPositionLocal(isector, irow, ipad, posL);
+            tpcROCinstance->GetPositionGlobal(isector, irow, ipad, posG);
+            posArray[0][ichannel] = irow;
+            posArray[1][ichannel] = ipad;
+            posArray[2][ichannel] = posL[0];
+            posArray[3][ichannel] = posL[1];
+            posArray[4][ichannel] = posG[0];
+            posArray[5][ichannel] = posG[1];
+            posArray[6][ichannel] = (Int_t)(ipad - (Double_t)(tpcROCinstance->GetNPads(isector, irow))/2);
+            posArray[7][ichannel] = ichannel;
+            
+            // loop over array containing AliTPCCalPads
+            for (Int_t ivalue = 0; ivalue < arrayEntries; ivalue++) {
+               AliTPCCalPad* calPad = (AliTPCCalPad*) array->At(ivalue);
+               AliTPCCalROC* calROC = calPad->GetCalROC(isector);
+               if (calROC)
+                  (vectorArray[ivalue])[ichannel] = calROC->GetValue(irow, ipad);
+               else
+                  (vectorArray[ivalue])[ichannel] = 0;
+            }
+            ichannel++;
+         }
+      }
+      
+      cstream << "calPads" <<
+         "sector=" << isector;
+      
+      for  (Int_t ivalue = 0; ivalue < arrayEntries; ivalue++) {
+         cstream << "calPads" <<
+            (Char_t*)((names[ivalue] + "_Median=").Data()) << median[ivalue] <<
+            (Char_t*)((names[ivalue] + "_Mean=").Data()) << mean[ivalue] <<
+            (Char_t*)((names[ivalue] + "_RMS=").Data()) << rms[ivalue] <<
+            (Char_t*)((names[ivalue] + "_LTM=").Data()) << ltm[ivalue] <<
+            (Char_t*)((names[ivalue] + "_RMS_LTM=").Data()) << ltmrms[ivalue];
+         if (outlierPad) {
+            cstream << "calPads" <<
+               (Char_t*)((names[ivalue] + "_Median_OutlierCutted=").Data()) << medianWithOut[ivalue] <<
+               (Char_t*)((names[ivalue] + "_Mean_OutlierCutted=").Data()) << meanWithOut[ivalue] <<
+               (Char_t*)((names[ivalue] + "_RMS_OutlierCutted=").Data()) << rmsWithOut[ivalue] <<
+               (Char_t*)((names[ivalue] + "_LTM_OutlierCutted=").Data()) << ltmWithOut[ivalue] <<
+               (Char_t*)((names[ivalue] + "_RMS_LTM_OutlierCutted=").Data()) << ltmrmsWithOut[ivalue];
+         }
+      }
+
+      for  (Int_t ivalue = 0; ivalue < arrayEntries; ivalue++) {
+         cstream << "calPads" <<
+            (Char_t*)((names[ivalue] + ".=").Data()) << &vectorArray[ivalue];
+      }
+
+      if (mapFileName) {
+         for  (Int_t ivalue = 0; ivalue < mapEntries; ivalue++) {
+            if (isector < 36)
+               cstream << "calPads" <<
+                  (Char_t*)((mapNames[ivalue] + ".=").Data()) << &mapIROCArray[ivalue];
+            else
+               cstream << "calPads" <<
+                  (Char_t*)((mapNames[ivalue] + ".=").Data()) << &mapOROCArray[ivalue];
+         }
+      }
+
+      cstream << "calPads" <<
+         "row.=" << &posArray[0] <<
+         "pad.=" << &posArray[1] <<
+         "lx.=" << &posArray[2] <<
+         "ly.=" << &posArray[3] <<
+         "gx.=" << &posArray[4] <<
+         "gy.=" << &posArray[5] <<
+         "rpad.=" << &posArray[6] <<
+         "channel.=" << &posArray[7];
+         
+      cstream << "calPads" <<
+         "\n";
+
+      delete[] posArray;
+      delete[] vectorArray;
+   }
+   
+
+   delete[] names;
+   if (mapFileName) {
+      delete mapIROCs;
+      delete mapOROCs;
+      delete[] mapIROCArray;
+      delete[] mapOROCArray;
+      delete[] mapNames;
+   }
+}
+
diff --git a/TPC/AliTPCCalibViewer.h b/TPC/AliTPCCalibViewer.h
new file mode 100644 (file)
index 0000000..a7507b1
--- /dev/null
@@ -0,0 +1,65 @@
+#ifndef ALITPCCALIBVIEWER_H
+#define ALITPCCALIBVIEWER_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+/* $Id: AliTPCCalibViewer.h,v */
+
+///////////////////////////////////////////////////
+//                                               //
+//  TPC calibration viewer/visualization class   //
+//  use Tree for visualization                   //
+///////////////////////////////////////////////////
+
+#include <TObject.h>
+#include <TTree.h>
+#include <TFile.h>
+#include "AliTPCCalPad.h"
+#include "AliTPCCalROC.h"
+#include "TFriendElement.h"
+
+
+class AliTPCCalibViewer : public TObject {
+public:
+   AliTPCCalibViewer();
+   AliTPCCalibViewer(const AliTPCCalibViewer &c);
+   AliTPCCalibViewer(TTree* tree);
+   AliTPCCalibViewer(char* fileName, char* treeName = "calPads");
+   AliTPCCalibViewer &operator = (const AliTPCCalibViewer & param);
+   virtual ~AliTPCCalibViewer();
+   
+   virtual void     Draw(Option_t* opt="") { fTree->Draw(opt); }
+   virtual Long64_t Draw(const char* varexp, const TCut& selection, Option_t* option = "", Long64_t nentries = 1000000000, Long64_t firstentry = 0) { return fTree->Draw(varexp, selection, option, nentries, firstentry); };
+   virtual Long64_t Draw(const char* varexp, const char* selection, Option_t* option = "", Long64_t nentries = 1000000000, Long64_t firstentry = 0) { return fTree->Draw(varexp, selection, option, nentries, firstentry); };
+
+   Int_t EasyDraw(const char* drawCommand, const char* sector, const char* cuts = 0, const char* drawOptions = 0, Bool_t writeDrawCommand = kFALSE) const;   // easy drawing of data, use '~' for abbreviation of '.fElements'
+   Int_t EasyDraw(const char* drawCommand, Int_t sector, const char* cuts = 0, const char* drawOptions = 0, Bool_t writeDrawCommand = kFALSE) const;   // easy drawing of data, use '~' for abbreviation of '.fElements'
+   Int_t EasyDraw1D(const char* drawCommand, const char* sector, const char* cuts = 0, const char* drawOptions = 0, Bool_t writeDrawCommand = kFALSE) const;   // easy drawing of data, use '~' for abbreviation of '.fElements'
+   Int_t EasyDraw1D(const char* drawCommand, Int_t sector, const char* cuts = 0, const char* drawOptions = 0, Bool_t writeDrawCommand = kFALSE) const;   // easy drawing of data, use '~' for abbreviation of '.fElements'
+   Int_t DrawHisto1D(const char* type, Int_t sector, TVectorF& nsigma, Bool_t plotMean = kTRUE, Bool_t plotMedian = kTRUE, Bool_t plotLTM = kTRUE) const; // draws 1d histograms and superimposes mean, median, ltm and several sigma cuts
+   void SigmaCut(const char* type, Int_t sector, Float_t sigmaMax = 5, Float_t sigmaStep = 0.5, Bool_t plotMean = kTRUE, Bool_t plotMedian = kTRUE, Bool_t plotLTM = kTRUE) const;    // draws fraction of used pads over different sigma cuts
+   
+   AliTPCCalPad* GetCalPad(const char* desiredData, char* cuts = "", char* calPadName = "NoName") const;     // returns an AliTPCCalPad object containing the specified data with cuts applied
+   AliTPCCalROC* GetCalROC(const char* desiredData, UInt_t sector, char* cuts = "") const;  // returns an AliTPCCalROC object containing the specified data for sector with cuts applied
+   
+   TObjArray* GetArrayOfCalPads();
+   TObjArray* GetListOfVariables(Bool_t printList = kFALSE);
+   TObjArray* GetListOfNormalizationVariables(Bool_t printList = kFALSE);
+   
+   static void MakeTreeWithObjects(const char * fileName, TObjArray * array, const char * mapFileName = 0);
+   static void MakeTree(const char * fileName, TObjArray * array, const char * mapFileName = 0, AliTPCCalPad* outlierPad = 0, Float_t ltmFraction = 0.9);
+   
+   TFriendElement* AddReferenceTree(const char* filename, const char* treename = "calPads", const char* refname = "R");
+   TFriendElement* AddFriend(const char* treename, const char* filename) {return fTree->AddFriend(treename, filename);};
+   TFriendElement* AddFriend(TTree* tree, const char* alias, Bool_t warn=kFALSE) {return fTree->AddFriend(tree, alias, warn);};
+   TFriendElement* AddFriend(const char* treename, TFile* file) {return fTree->AddFriend(treename, file);};
+   
+protected:
+   TTree* fTree;     // tree containing visualization data (e.g. written by AliTPCCalPad::MakeTree(...)
+   TFile* fFile;     // file that contains a calPads tree (e.g. written by AliTPCCalPad::MakeTree(...)
+   TObjArray* fListOfObjectsToBeDeleted;  //Objects, that will be deleted when the destructor ist called
+   
+   ClassDef(AliTPCCalibViewer,1)    //  TPC calibration viewer class
+};
+
+#endif
diff --git a/TPC/AliTPCCalibViewerGUI.cxx b/TPC/AliTPCCalibViewerGUI.cxx
new file mode 100644 (file)
index 0000000..a72a1f2
--- /dev/null
@@ -0,0 +1,490 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+
+///////////////////////////////////////////////////////////////////////////////
+//                                                                           //
+//  GUI for the AliTPCCalibViewer                                            //
+//  used for the calibration monitor   
+//  Example usage: 
+/*
+  aliroot
+
+  AliTPCCalibViewerGUI v(gClient->GetRoot(), 1000, 600, "/u/sgaertne/calibration/localFit/AliTPCCalibViewer/allInOne6.root")
+
+ - Resize windows - (BUG to BE FIXED)
+
+*/                                      //
+//                                                                           //
+///////////////////////////////////////////////////////////////////////////////
+
+
+#include "AliTPCCalibViewerGUI.h"
+
+#include <TCanvas.h>
+#include <TPad.h>
+#include <TVirtualPad.h>
+
+#include <TObjArray.h>
+#include <TObjString.h>
+#include <TVector.h>
+
+ClassImp(AliTPCCalibViewerGUI)
+
+AliTPCCalibViewerGUI::AliTPCCalibViewerGUI(const TGWindow *p, UInt_t w, UInt_t h, char* fileName)
+  : TGMainFrame(p, w, h),
+    fViewer(0),
+    fContAll(0),
+    fContLeft(0),
+    fContRight(0),
+    fContCenter(0),
+    fContPlotOpt(0),
+    fContDrawOpt(0),
+    fContNormalized(0),
+    fContCustom(0),
+    fContCuts(0),
+    fContSector(0),
+    fContAddCuts(0),
+    fListVariables(0),
+    fBtnDraw(0),
+    fCanvMain(0),
+    fRadioRaw(0),
+    fRadioNormalized(0),
+    fRadioCustom(0),
+    fRadio1D(0),
+    fRadio2D(0),
+    fRadioTPC(0),
+    fRadioSideA(0),
+    fRadioSideC(0),
+    fRadioSector(0),
+    fChkAuto(0),
+    fComboMethod(0),
+    fListNormalization(0),
+    fTxtCustom(0),
+    fNmbSector(0),
+    fChkAddCuts(0),
+    fTxtAddCuts(0)
+//
+// AliTPCCalibViewerGUI constructor; fileName specifies the ROOT tree used for drawing
+//
+{
+   SetCleanup(kDeepCleanup);
+   
+   // ************************* content of this MainFrame *************************
+   // top level container with horizontal layout
+   fContAll = new TGCompositeFrame(this, w, h, kHorizontalFrame | kFixedWidth | kFixedHeight);
+   AddFrame(fContAll, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY, 0, 0, 0, 0));
+
+   // ************************* content of fContAll *************************
+   // left container
+   fContLeft = new TGCompositeFrame(fContAll, 200, 200, kVerticalFrame | kFixedWidth | kFitHeight);
+   fContAll->AddFrame(fContLeft, new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsExpandY, 5, 3, 3, 3));
+   
+   // left vertical splitter
+   TGVSplitter *splitLeft = new TGVSplitter(fContAll);
+   splitLeft->SetFrame(fContLeft, kTRUE);
+   fContAll->AddFrame(splitLeft, new TGLayoutHints(kLHintsLeft | kLHintsExpandY, 0, 0, 0, 0));
+
+   // right container
+   fContRight = new TGCompositeFrame(fContAll, 150, 200, kVerticalFrame | kFixedWidth | kFitHeight);
+   fContAll->AddFrame(fContRight, new TGLayoutHints(kLHintsTop | kLHintsRight | kLHintsExpandY, 3, 5, 3, 3));
+   
+   // center container
+   fContCenter = new TGCompositeFrame(fContAll, 200, 200, kVerticalFrame | kFixedWidth | kFitHeight);
+   fContAll->AddFrame(fContCenter, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY, 0, 0, 0, 0));
+
+   // right vertical splitter
+   TGVSplitter *splitRight = new TGVSplitter(fContAll);
+   splitRight->SetFrame(fContRight, kFALSE);
+   fContAll->AddFrame(splitRight, new TGLayoutHints(kLHintsLeft | kLHintsExpandY, 0, 0, 0, 0));
+   
+   // ************************* content of fContLeft *************************
+   // list of variables
+   fListVariables = new TGListBox(fContLeft);
+   fContLeft->AddFrame(fListVariables, new TGLayoutHints(kLHintsNormal | kLHintsExpandX | kLHintsExpandY, 0, 0, 0, 0));
+   fListVariables->Connect("Selected(Int_t)", "AliTPCCalibViewerGUI", this, "DoNewSelection()");
+
+   // plot options container
+   //fContPlotOpt = new TGCompositeFrame(fContLeft, 200, 200, kVerticalFrame | kFitWidth | kFitHeight);
+   fContPlotOpt = new TGGroupFrame(fContLeft, "Plot options", kVerticalFrame | kFitWidth | kFitHeight);
+   fContLeft->AddFrame(fContPlotOpt, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY, 0, 0, 0, 0));
+
+   // draw options container
+   fContDrawOpt = new TGCompositeFrame(fContLeft, 200, 20, kHorizontalFrame | kFitWidth | kFixedHeight);
+   fContLeft->AddFrame(fContDrawOpt, new TGLayoutHints(kLHintsExpandX, 0, 0, 10, 0));
+   
+   // draw button
+   fBtnDraw = new TGTextButton(fContLeft, "&Draw");
+   fContLeft->AddFrame(fBtnDraw, new TGLayoutHints(kLHintsExpandX, 0, 0, 0, 0));
+   //fBtnDraw->Connect("Clicked()", "AliTPCCalibViewerGUI", this, "DoTest(=\"fBtnDraw clicked\")");
+   fBtnDraw->Connect("Clicked()", "AliTPCCalibViewerGUI", this, "DoDraw()");
+   
+   // ************************* content of fContRight *************************
+   // cut options container
+   //fContCuts = new TGCompositeFrame(fContRight, 200, 200, kVerticalFrame | kFitWidth | kFitHeight);
+   fContCuts = new TGGroupFrame(fContRight, "Cuts", kVerticalFrame | kFitWidth | kFitHeight);
+   fContRight->AddFrame(fContCuts, new TGLayoutHints(kLHintsExpandX, 0, 0, 0, 0));
+
+   // ************************* content of fContCenter *************************
+   // main drawing canvas
+   fCanvMain = new TRootEmbeddedCanvas("Main Canvas", fContCenter, 200, 200, kFitWidth | kFitHeight);
+   fContCenter->AddFrame(fCanvMain, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY, 0, 0, 0, 0));
+   
+
+   // ************************* content of fContPlotOpt *************************
+   //TGButtonGroup *fBtngrpPlotOpt = new TGButtonGroup(fContPlotOpt, "Plot options", 
+   // raw radio button
+   fRadioRaw = new TGRadioButton(fContPlotOpt, "Raw", 10);
+   fContPlotOpt->AddFrame(fRadioRaw, new TGLayoutHints(kLHintsExpandX, 0, 0, 0, 0));
+   fRadioRaw->Connect("Clicked()", "AliTPCCalibViewerGUI", this, "HandleButtons()");
+
+   // normalized radio button
+   fRadioNormalized = new TGRadioButton(fContPlotOpt, "Normalized", 11);
+   fContPlotOpt->AddFrame(fRadioNormalized, new TGLayoutHints(kLHintsExpandX, 0, 0, 0, 0));
+   fRadioNormalized->Connect("Clicked()", "AliTPCCalibViewerGUI", this, "HandleButtons()");
+
+   //fContPlotOpt->Show();
+
+   // normalized options container
+   fContNormalized = new TGCompositeFrame(fContPlotOpt, 200, 200, kVerticalFrame | kFitWidth | kFitHeight);
+   fContPlotOpt->AddFrame(fContNormalized, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY, 15, 0, 0, 0));
+
+   // custom radio button
+   fRadioCustom = new TGRadioButton(fContPlotOpt, "Custom", 12);
+   fContPlotOpt->AddFrame(fRadioCustom, new TGLayoutHints(kLHintsExpandX, 0, 0, 0, 0));
+   fRadioCustom->Connect("Clicked()", "AliTPCCalibViewerGUI", this, "HandleButtons()");
+
+   // custom options container
+   fContCustom = new TGCompositeFrame(fContPlotOpt, 200, 200, kVerticalFrame | kFitWidth | kFitHeight);
+   fContPlotOpt->AddFrame(fContCustom, new TGLayoutHints(kLHintsExpandX, 15, 0, 0, 0));
+
+   // ************************* content of fContDrawOpt *************************
+   // 1D radio button
+   fRadio1D = new TGRadioButton(fContDrawOpt, "1D", 30);
+   fContDrawOpt->AddFrame(fRadio1D, new TGLayoutHints(kLHintsNormal, 2, 2, 0, 0));
+   fRadio1D->Connect("Clicked()", "AliTPCCalibViewerGUI", this, "HandleButtons()");
+   
+   // 2D radio button
+   fRadio2D = new TGRadioButton(fContDrawOpt, "2D", 31);
+   fContDrawOpt->AddFrame(fRadio2D, new TGLayoutHints(kLHintsNormal, 2, 2, 0, 0));
+   fRadio2D->Connect("Clicked()", "AliTPCCalibViewerGUI", this, "HandleButtons()");
+
+   // automatic redraw check button
+   fChkAuto = new TGCheckButton(fContDrawOpt, "auto redraw");
+   fContDrawOpt->AddFrame(fChkAuto, new TGLayoutHints(kLHintsNormal, 2, 2, 0, 0));
+
+   // ************************* content of fContCuts *************************
+   // TPC radio button
+   fRadioTPC = new TGRadioButton(fContCuts, "whole TPC", 20);
+   fContCuts->AddFrame(fRadioTPC, new TGLayoutHints(kLHintsExpandX, 0, 0, 0, 0));
+   fRadioTPC->Connect("Clicked()", "AliTPCCalibViewerGUI", this, "HandleButtons()");
+
+   // side A radio button
+   fRadioSideA = new TGRadioButton(fContCuts, "side A", 21);
+   fContCuts->AddFrame(fRadioSideA, new TGLayoutHints(kLHintsExpandX, 0, 0, 0, 0));
+   fRadioSideA->Connect("Clicked()", "AliTPCCalibViewerGUI", this, "HandleButtons()");
+
+   // side C radio button
+   fRadioSideC = new TGRadioButton(fContCuts, "side C", 22);
+   fContCuts->AddFrame(fRadioSideC, new TGLayoutHints(kLHintsExpandX, 0, 0, 0, 0));
+   fRadioSideC->Connect("Clicked()", "AliTPCCalibViewerGUI", this, "HandleButtons()");
+
+   // sector radio button
+   fRadioSector = new TGRadioButton(fContCuts, "sector", 23);
+   fContCuts->AddFrame(fRadioSector, new TGLayoutHints(kLHintsExpandX, 0, 0, 0, 0));
+   fRadioSector->Connect("Clicked()", "AliTPCCalibViewerGUI", this, "HandleButtons()");
+
+   // sector options container
+   fContSector = new TGCompositeFrame(fContCuts, 200, 200, kVerticalFrame | kFitWidth | kFitHeight);
+   fContCuts->AddFrame(fContSector, new TGLayoutHints(kLHintsExpandX, 15, 0, 0, 0));
+   
+   // additional cuts check button
+   fChkAddCuts = new TGCheckButton(fContCuts, "additional cuts");
+   fContCuts->AddFrame(fChkAddCuts, new TGLayoutHints(kLHintsNormal, 0, 0, 0, 0));
+   fChkAddCuts->Connect("Clicked()", "AliTPCCalibViewerGUI", this, "DoNewSelection()");
+
+   // additional cuts container
+   fContAddCuts = new TGCompositeFrame(fContCuts, 200, 200, kVerticalFrame | kFitWidth | kFitHeight);
+   fContCuts->AddFrame(fContAddCuts, new TGLayoutHints(kLHintsExpandX, 15, 0, 0, 0));
+   
+   // ************************* content of fContNormalized *************************
+   // method drop down combo box
+   fComboMethod = new TGComboBox(fContNormalized);
+   fComboMethod->Resize(0, fBtnDraw->GetDefaultHeight());
+   fContNormalized->AddFrame(fComboMethod, new TGLayoutHints(kLHintsNormal | kLHintsExpandX, 0, 0, 0, 0));
+   fComboMethod->Connect("Selected(Int_t)", "AliTPCCalibViewerGUI", this, "DoNewSelection()");
+
+   // list of normalization variables
+   fListNormalization = new TGListBox(fContNormalized);
+   fContNormalized->AddFrame(fListNormalization, new TGLayoutHints(kLHintsNormal | kLHintsExpandX | kLHintsExpandY, 0, 0, 0, 0));
+   fListNormalization->Connect("Selected(Int_t)", "AliTPCCalibViewerGUI", this, "DoNewSelection()");
+
+   // ************************* content of fContCustom *************************
+   // text field for custom draw command
+   fTxtCustom = new TGTextEntry(fContCustom);
+   fContCustom->AddFrame(fTxtCustom, new TGLayoutHints(kLHintsNormal | kLHintsExpandX, 0, 0, 0, 0));
+   fTxtCustom->Connect("ReturnPressed()", "AliTPCCalibViewerGUI", this, "DoNewSelection()");
+   
+   // ************************* content of fContSector *************************
+   // sector number entry
+   fNmbSector = new TGNumberEntry(fContSector, 0, 1, -1, TGNumberFormat::kNESInteger, TGNumberFormat::kNEANonNegative, TGNumberFormat::kNELLimitMinMax, 0, 71);
+   fContSector->AddFrame(fNmbSector, new TGLayoutHints(kLHintsNormal | kLHintsExpandX, 0, 0, 0, 0));
+   fNmbSector->Connect("ValueSet(Long_t)", "AliTPCCalibViewerGUI", this, "DoNewSelection()");
+   
+   // ************************* content of fContAddCuts *************************
+   // text field for additional cuts
+   fTxtAddCuts = new TGTextEntry(fContAddCuts);
+   fContAddCuts->AddFrame(fTxtAddCuts, new TGLayoutHints(kLHintsNormal | kLHintsExpandX, 0, 0, 0, 0));
+   fTxtAddCuts->Connect("ReturnPressed()", "AliTPCCalibViewerGUI", this, "DoNewSelection()");
+
+   // Display everything
+   Initialize(fileName);
+   SetWindowName("AliTPCCalibViewer GUI");
+   MapSubwindows();
+   Resize(GetDefaultSize());
+   MapWindow();
+}
+
+AliTPCCalibViewerGUI::AliTPCCalibViewerGUI(const AliTPCCalibViewerGUI &c)
+   : TGMainFrame(c.fParent, c.fWidth, c.fHeight),
+    fViewer(0),
+    fContAll(0),
+    fContLeft(0),
+    fContRight(0),
+    fContCenter(0),
+    fContPlotOpt(0),
+    fContDrawOpt(0),
+    fContNormalized(0),
+    fContCustom(0),
+    fContCuts(0),
+    fContSector(0),
+    fContAddCuts(0),
+    fListVariables(0),
+    fBtnDraw(0),
+    fCanvMain(0),
+    fRadioRaw(0),
+    fRadioNormalized(0),
+    fRadioCustom(0),
+    fRadio1D(0),
+    fRadio2D(0),
+    fRadioTPC(0),
+    fRadioSideA(0),
+    fRadioSideC(0),
+    fRadioSector(0),
+    fChkAuto(0),
+    fComboMethod(0),
+    fListNormalization(0),
+    fTxtCustom(0),
+    fNmbSector(0),
+    fChkAddCuts(0),
+    fTxtAddCuts(0)
+{
+  //
+  // dummy AliTPCCalibViewerGUI copy constructor
+  //
+}
+
+AliTPCCalibViewerGUI & AliTPCCalibViewerGUI::operator =(const AliTPCCalibViewerGUI & param) {
+   //
+   // dummy assignment operator
+   //
+   return (*this);
+}
+
+AliTPCCalibViewerGUI::~AliTPCCalibViewerGUI() {
+   Cleanup();
+}
+
+void AliTPCCalibViewerGUI::CloseWindow() {
+   DeleteWindow();
+}
+
+void AliTPCCalibViewerGUI::Initialize(char* fileName) {
+   //
+   // initializes the GUI with default settings and opens tree for drawing
+   //
+   
+   // create AliTPCCalibViewer object, which will be used for generating all drawings
+   fViewer = new AliTPCCalibViewer(fileName);
+
+   // fill fListVariables
+   TObjArray* arr = fViewer->GetListOfVariables();
+   TIterator* iter = arr->MakeIterator();
+   iter->Reset();
+   TObjString* currentStr = 0;
+   Int_t id = 0;
+   while (currentStr = (TObjString*)(iter->Next())) {
+      fListVariables->AddEntry(currentStr->GetString().Data(), id);
+      id++;
+   }
+   delete iter;
+   arr->Delete();
+   delete arr;
+
+   // fill fComboMethod
+   fComboMethod->AddEntry("subtract", 0);
+   fComboMethod->AddEntry("divide by", 1);
+
+   // fill fListNorm
+   arr = fViewer->GetListOfNormalizationVariables();
+   iter = arr->MakeIterator();
+   iter->Reset();
+   currentStr = 0;
+   id = 0;
+   while (currentStr = (TObjString*)(iter->Next())) {
+      fListNormalization->AddEntry(currentStr->GetString().Data(), id);
+      id++;
+   }
+   delete iter;
+   arr->Delete();
+   delete arr;
+
+   // set default button states
+   fRadioRaw->SetState(kButtonDown);
+   fRadioTPC->SetState(kButtonDown);
+   //fRadioCustom->SetState(kButtonDisabled);
+   fRadio1D->SetState(kButtonDown);
+   fChkAuto->SetState(kButtonDown);
+   fChkAddCuts->SetState(kButtonUp);
+   fListVariables->Select(0);
+   fListNormalization->Select(0);
+   fComboMethod->Select(0);
+}
+
+void AliTPCCalibViewerGUI::HandleButtons(Int_t id) {
+   //
+   // handles mutual radio button exclusions
+   //
+   if (id == -1) {
+      TGButton *btn = (TGButton *) gTQSender;
+      id = btn->WidgetId();
+   }
+   
+   switch (id) {
+      case 10:             // fRadioRaw
+         fRadioNormalized->SetState(kButtonUp);
+         fRadioCustom->SetState(kButtonUp);
+         //fComboMethod->UnmapWindow();
+         //fListNormalization->UnmapWindow();
+         break;
+      case 11:             // fRadioNormalized
+         fRadioRaw->SetState(kButtonUp);
+         fRadioCustom->SetState(kButtonUp);
+         break;
+      case 12:             // fRadioCustom
+         fRadioRaw->SetState(kButtonUp);
+         fRadioNormalized->SetState(kButtonUp);
+         break;
+      //--------
+      case 20:             // fRadioTPC
+         fRadioSideA->SetState(kButtonUp);
+         fRadioSideC->SetState(kButtonUp);
+         fRadioSector->SetState(kButtonUp);
+         break;
+      case 21:             // fRadioSideA
+         fRadioTPC->SetState(kButtonUp);
+         fRadioSideC->SetState(kButtonUp);
+         fRadioSector->SetState(kButtonUp);
+         break;
+      case 22:             // fRadioSideC
+         fRadioTPC->SetState(kButtonUp);
+         fRadioSideA->SetState(kButtonUp);
+         fRadioSector->SetState(kButtonUp);
+         break;
+      case 23:             // fRadioSector
+         fRadioTPC->SetState(kButtonUp);
+         fRadioSideA->SetState(kButtonUp);
+         fRadioSideC->SetState(kButtonUp);
+         break;
+      //--------
+      case 30:             // fRadio1D
+         fRadio2D->SetState(kButtonUp);
+         break;
+      case 31:             // fRadio2D
+         fRadio1D->SetState(kButtonUp);
+         break;
+   }
+   //fRadioCustom->SetState(kButtonDisabled);
+
+   if (fChkAuto->GetState() == kButtonDown) DoDraw();
+}
+
+void AliTPCCalibViewerGUI::DoNewSelection() {
+   //
+   // decides whether to redraw if user makes another selection
+   //
+   
+   if (fChkAuto->GetState() == kButtonDown) DoDraw();
+}
+
+void AliTPCCalibViewerGUI::DoDraw() {
+   //
+   // main method for drawing according to user selection
+   //
+   
+   // specify data to plot
+   TString desiredData("");
+   desiredData += ((TGTextLBEntry*)(fListVariables->GetSelectedEntry()))->GetTitle();
+   desiredData += ".fElements";
+
+   // specify normalization
+   if (fRadioNormalized->GetState() == kButtonDown) {
+      TString op("");
+      switch (fComboMethod->GetSelected()) {
+         case 0:        // subtraction
+            op += "-";
+            break;
+         case 1:        // division
+            op += "/";
+            break;
+      }
+      TString normalizationData("");
+      normalizationData += ((TGTextLBEntry*)(fListNormalization->GetSelectedEntry()))->GetTitle();
+      desiredData += op;
+      desiredData += ((TGTextLBEntry*)(fListVariables->GetSelectedEntry()))->GetTitle();
+      //desiredData += "_";
+      desiredData += normalizationData;
+   }
+   else if (fRadioCustom->GetState() == kButtonDown) {
+      desiredData = fTxtCustom->GetText();
+      if (desiredData == "") return;
+   }
+
+   // specify cuts
+   TString sectorStr("");
+   if (fRadioTPC->GetState() == kButtonDown)
+      sectorStr += "ALL";
+   if (fRadioSideA->GetState() == kButtonDown)
+      sectorStr += "A"; //cuts += "(sector/18)%2==0";
+   if (fRadioSideC->GetState() == kButtonDown)
+      sectorStr+= "C"; //cuts += "(sector/18)%2==1";
+   if (fRadioSector->GetState() == kButtonDown) {
+      Int_t sector = (Int_t)(fNmbSector->GetNumber());
+      sectorStr += sector; //cuts += "sector==";
+   }
+   TString cutsStr("");
+   if (fChkAddCuts->GetState() == kButtonDown)
+      cutsStr += fTxtAddCuts->GetText();
+   
+   // draw finally
+   fCanvMain->GetCanvas()->cd();
+   //fViewer->Draw(desiredData.Data(), cuts.Data());
+   if (fRadio1D->GetState() == kButtonDown)
+      fViewer->EasyDraw1D(desiredData.Data(), sectorStr.Data(), cutsStr.Data());
+   else if (fRadio2D->GetState() == kButtonDown)
+      fViewer->EasyDraw(desiredData.Data(), sectorStr.Data(), cutsStr.Data());
+   
+   fCanvMain->GetCanvas()->Update();
+}
diff --git a/TPC/AliTPCCalibViewerGUI.h b/TPC/AliTPCCalibViewerGUI.h
new file mode 100644 (file)
index 0000000..deaf016
--- /dev/null
@@ -0,0 +1,86 @@
+#ifndef ALITPCCALIBVIEWERGUI
+#define ALITPCCALIBVIEWERGUI
+
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+/* $Id: AliTPCCalibViewerGUI.h,v */
+
+///////////////////////////////////////////////////////////////////////////////
+//                                                                           //
+//  GUI for the AliTPCCalibViewer                                            //
+//  used for the calibration monitor                                         //
+//                                                                           //
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef ROOT_TGButton
+#include "TGWidget.h"
+#endif
+#ifndef ROOT_TGFrame
+#include "TGFrame.h"
+#endif
+
+#include <TGButton.h>
+#include <TGListBox.h>
+#include <TGComboBox.h>
+#include <TGNumberEntry.h>
+#include <TRootEmbeddedCanvas.h>
+#include <TGSplitter.h>
+#include <TGButtonGroup.h>
+
+#include <iostream>
+#include "AliTPCCalibViewer.h"
+
+
+class AliTPCCalibViewerGUI : public TGMainFrame {
+protected:
+   AliTPCCalibViewer   *fViewer;             // CalibViewer object used for drawing
+
+   TGCompositeFrame    *fContAll;            // container for all GUI elements
+   TGCompositeFrame    *fContLeft;           // container for GUI elements on left side
+   TGCompositeFrame    *fContRight;          // container for GUI elements on right side
+   TGCompositeFrame    *fContCenter;         // container for GUI elements at the center
+   TGCompositeFrame    *fContPlotOpt;        // container for plot options GUI elements
+   TGCompositeFrame    *fContDrawOpt;        // container for draw options GUI elements
+   TGCompositeFrame    *fContNormalized;     // container for normalization options GUI elements
+   TGCompositeFrame    *fContCustom;         // container for custom draw command GUI elements
+   TGCompositeFrame    *fContCuts;           // container for cut options GUI elements
+   TGCompositeFrame    *fContSector;         // container for sector GUI elements
+   TGCompositeFrame    *fContAddCuts;        // container for additional cut command GUI elements
+   TGListBox           *fListVariables;      // listbox with possible variables
+   TGTextButton        *fBtnDraw;            // draw button
+   TRootEmbeddedCanvas *fCanvMain;           // main drawing canvas
+   TGRadioButton       *fRadioRaw;           // raw radio button
+   TGRadioButton       *fRadioNormalized;    // normalized radio button
+   TGRadioButton       *fRadioCustom;        // custom radio button
+   TGRadioButton       *fRadio1D;            // 1D radio button
+   TGRadioButton       *fRadio2D;            // 2D radio button
+   TGRadioButton       *fRadioTPC;           // TPC radio button
+   TGRadioButton       *fRadioSideA;         // side A radio button
+   TGRadioButton       *fRadioSideC;         // side C radio button
+   TGRadioButton       *fRadioSector;        // sector radio button
+   TGCheckButton       *fChkAuto;            // automatic redraw checkbox
+   TGComboBox          *fComboMethod;        // normalization methods dropdown box
+   TGListBox           *fListNormalization;  // listbox with possible normalization variables
+   TGTextEntry         *fTxtCustom;          // text box for custom draw command
+   TGNumberEntry       *fNmbSector;          // number entry box for specifying the sector
+   TGCheckButton       *fChkAddCuts;         // additional cuts check box
+   TGTextEntry         *fTxtAddCuts;         // additional cuts text box
+
+   void Initialize(char* fileName);          // initializes the GUI with default settings and opens tree for drawing
+   
+public:
+   AliTPCCalibViewerGUI(const TGWindow *p, UInt_t w, UInt_t h, char* fileName);  // constructor; fileName specifies the ROOT tree used for drawing
+   AliTPCCalibViewerGUI(const AliTPCCalibViewerGUI &c);                          // copy constructor
+   AliTPCCalibViewerGUI &operator = (const AliTPCCalibViewerGUI &param);         // assignment operator
+
+   virtual ~AliTPCCalibViewerGUI();
+   virtual void CloseWindow();
+
+   void HandleButtons(Int_t id = -1);        // handles mutual radio button exclusions
+   void DoNewSelection();                    // decides whether to redraw if user makes another selection
+   void DoDraw();                            // main method for drawing according to user selection
+   ClassDef(AliTPCCalibViewerGUI, 0)
+};
+
+#endif