#include "TParallelCoord.h"
#include "TParallelCoordVar.h"
#include "TParallelCoordRange.h"
#include "Riostream.h"
#include "TROOT.h"
#include "TVirtualX.h"
#include "TPad.h"
#include "TPolyLine.h"
#include "TGraph.h"
#include "TPaveText.h"
#include "float.h"
#include "TMath.h"
#include "TBox.h"
#include "TH1.h"
#include "TStyle.h"
#include "TEntryList.h"
#include "TFrame.h"
#include "TTree.h"
#include "TTreePlayer.h"
#include "TSelectorDraw.h"
#include "TTreeFormula.h"
#include "TView.h"
#include "TRandom.h"
#include "TEnv.h"
#include "TCanvas.h"
#include "TGaxis.h"
#include "TFile.h"
ClassImp(TParallelCoord)
TParallelCoord::TParallelCoord()
   :TNamed()
{
   
   Init();
}
TParallelCoord::TParallelCoord(Long64_t nentries)
{
   
   
   
   Init();
   fNentries = nentries;
   fCurrentN = fNentries;
   fVarList = new TList();
   fSelectList = new TList();
   fCurrentSelection = new TParallelCoordSelect();
   fSelectList->Add(fCurrentSelection);
}
TParallelCoord::TParallelCoord(TTree* tree, Long64_t nentries)
   :TNamed("ParaCoord","ParaCoord")
{
   
   
   Init();
   fNentries = nentries;
   fCurrentN = fNentries;
   fTree = tree;
   fTreeName = fTree->GetName();
   if (fTree->GetCurrentFile()) fTreeFileName = fTree->GetCurrentFile()->GetName();
   else fTreeFileName = "";
   fVarList = new TList();
   fSelectList = new TList();
   fCurrentSelection = new TParallelCoordSelect();
   fSelectList->Add(fCurrentSelection);
}
TParallelCoord::~TParallelCoord()
{
   
   printf("TParallelCoord::~TParallelCoord()");
   if (fCurrentEntries) delete fCurrentEntries;
   if (fInitEntries != fCurrentEntries && fInitEntries != 0) delete fInitEntries;
   if (fVarList) {
      fVarList->Delete();
      delete fVarList;
   }
   if (fSelectList) {
      fSelectList->Delete();
      delete fSelectList;
   }
   if (fCandleAxis) delete fCandleAxis;
   SetDotsSpacing(0);
}
void TParallelCoord::AddVariable(Double_t* val, const char* title)
{
   
   ++fNvar;
   fVarList->Add(new TParallelCoordVar(val,title,fVarList->GetSize(),this));
   SetAxesPosition();
}
void TParallelCoord::AddVariable(const char* varexp)
{
   
   if(!fTree) return; 
   
   
   TEntryList *list = GetEntryList(kFALSE);
   fTree->SetEntryList(list);
   
   
   
   TString exp = varexp;
   
   if (exp.Contains(':') || exp.Contains(">>") || exp.Contains("<<")) {
      Warning("AddVariable","Only a single variable can be added at a time.");
      return;
   }
   if (exp == ""){
      Warning("AddVariable","Nothing to add");
      return;
   }
   
   Long64_t en = fTree->Draw(varexp,"","goff");
   if (en<0) {
      Warning("AddVariable","%s could not be evaluated",varexp);
      return;
   }
   
   AddVariable(fTree->GetV1(),varexp);
   TParallelCoordVar* var = (TParallelCoordVar*)fVarList->Last();
   var->Draw();
}
void TParallelCoord::AddSelection(const char* title)
{
   
   TParallelCoordSelect *sel = new TParallelCoordSelect(title);
   fSelectList->Add(sel);
   fCurrentSelection = sel;
}
void  TParallelCoord::ApplySelectionToTree()
{
   
   if(!fTree) return;
   if(fSelectList->GetSize() == 0) return;
   if(fCurrentSelection == 0) fCurrentSelection = (TParallelCoordSelect*)fSelectList->First();
   fCurrentEntries = GetEntryList();
   fNentries = fCurrentEntries->GetN();
   fCurrentFirst = 0;
   fCurrentN = fNentries;
   fTree->SetEntryList(fCurrentEntries);
   TString varexp = "";
   TIter next(fVarList);
   TParallelCoordVar* var;
   while ((var = (TParallelCoordVar*)next())) varexp.Append(Form(":%s",var->GetTitle()));
   varexp.Remove(TString::kLeading,':');
   TSelectorDraw* selector = (TSelectorDraw*)((TTreePlayer*)fTree->GetPlayer())->GetSelector();
   fTree->Draw(varexp.Data(),"","goff para");
   next.Reset();
   Int_t i = 0;
   while ((var = (TParallelCoordVar*)next())) {
      var->SetValues(fNentries, selector->GetVal(i));
      ++i;
   }
   if (fSelectList) {           
      fSelectList->Delete();    
      fCurrentSelection = 0;    
   }
   gPad->Modified();
   gPad->Update();
}
void  TParallelCoord::BuildParallelCoord(TSelectorDraw* selector, Bool_t candle)
{
   
   TParallelCoord* pc = new TParallelCoord(selector->GetTree(),selector->GetNfill());
   selector->SetObject(pc);
   TString varexp = "";
   for(Int_t i=0;i<selector->GetDimension();++i) {
      pc->AddVariable(selector->GetVal(i),selector->GetVar(i)->GetTitle());
      varexp.Append(Form(":%s",selector->GetVar(i)->GetTitle()));
   }
   varexp.Remove(TString::kLeading,':');
   if (selector->GetSelect()) varexp.Append(Form("{%s}",selector->GetSelect()->GetTitle()));
   pc->SetTitle(varexp.Data());
   if (!candle) pc->Draw();
   else pc->Draw("candle");
}
void TParallelCoord::CleanUpSelections(TParallelCoordRange* range)
{
   
   
   TIter next(fSelectList);
   TParallelCoordSelect* select;
   while ((select = (TParallelCoordSelect*)next())){
      if(select->Contains(range)) select->Remove(range);
   }
}
void TParallelCoord::DeleteSelection(TParallelCoordSelect * sel)
{
   
   fSelectList->Remove(sel);
   delete sel;
   if(fSelectList->GetSize() == 0) fCurrentSelection = 0;
   else fCurrentSelection = (TParallelCoordSelect*)fSelectList->At(0);
}
Int_t TParallelCoord::DistancetoPrimitive(Int_t px, Int_t py)
{
   
   if(!gPad) return 9999;
   
   TFrame *frame = gPad->GetFrame();
   
   Double_t x1,x2,y1,y2,xx,yy;
   
   x1 = frame->GetX1()+0.01;
   x2 = frame->GetX2()-0.01;
   y2 = frame->GetY2()-0.01;
   y1 = frame->GetY1()+0.01;
   
   xx = gPad->AbsPixeltoX(px);
   yy = gPad->AbsPixeltoY(py);
   
   if(xx>x1 && xx<x2 && yy>y1 && yy<y2) return 0;
   else                                 return 9999;
}
void TParallelCoord::Draw(Option_t* option)
{
   
   if (!GetTree()) return;
   if (!fCurrentEntries) fCurrentEntries = fInitEntries;
   Bool_t optcandle = kFALSE;
   TString opt = option;
   opt.ToLower();
   if(opt.Contains("candle")) {
      optcandle = kTRUE;
      opt.ReplaceAll("candle","");
   }
   if(optcandle) {
      SetBit(kPaintEntries,kFALSE);
      SetBit(kCandleChart,kTRUE);
      SetGlobalScale(kTRUE);
   }
   
   if (gPad) {
      if (!gPad->IsEditable()) gROOT->MakeDefCanvas();
   } else gROOT->MakeDefCanvas();
   TView *view = gPad->GetView();
   if(view){
      delete view;
      gPad->SetView(0);
   }
   gPad->Clear();
   if (!optcandle) {
      if (gPad && gPad->IsA() == TCanvas::Class()
         && !((TCanvas*)gPad)->GetShowEditor()) {
         ((TCanvas*)gPad)->ToggleEditor();
         ((TCanvas*)gPad)->ToggleEventStatus();
      }
   }
   
   gPad->SetBit(TGraph::kClipFrame,kTRUE);
   
   TFrame *frame = new TFrame(0.1,0.1,0.9,0.9);
   frame->SetBorderSize(0);
   frame->SetBorderMode(0);
   frame->SetFillStyle(0);
   frame->SetLineColor(gPad->GetFillColor());
   frame->Draw();
   AppendPad(option);
   TPaveText *title = new TPaveText(0.05,0.95,0.35,1);
   title->AddText(GetTitle());
   title->Draw();
   SetAxesPosition();
   TIter next(fVarList);
   TParallelCoordVar* var;
   while ((var = (TParallelCoordVar*)next())) {
      if(optcandle) {
         var->SetBoxPlot(kTRUE);
         var->SetHistogramHeight(0.5);
         var->SetHistogramLineWidth(0);
      }
      var->Draw();
   }
   
   if (optcandle) {
      if (TestBit(kVertDisplay)) fCandleAxis = new TGaxis(0.05,0.1,0.05,0.9,GetGlobalMin(),GetGlobalMax());
      else                       fCandleAxis = new TGaxis(0.1,0.05,0.9,0.05,GetGlobalMin(),GetGlobalMax());
      fCandleAxis->Draw();
   }
   
   if (gPad && gPad->IsA() == TCanvas::Class())
      ((TCanvas*)gPad)->Selected(gPad,this,1);
}
void TParallelCoord::ExecuteEvent(Int_t , Int_t , Int_t )
{
   
   gPad->SetCursor(kHand);
}
TParallelCoordSelect* TParallelCoord::GetCurrentSelection()
{
   
   if (!fSelectList) return 0;
   if (!fCurrentSelection) {
      fCurrentSelection = (TParallelCoordSelect*)fSelectList->First();
   }
   return fCurrentSelection;
}
TEntryList* TParallelCoord::GetEntryList(Bool_t sel)
{
   
   if(!sel || fCurrentSelection->GetSize() == 0){ 
      return fInitEntries;
   } else { 
      TEntryList *enlist = new TEntryList(fTree);
      TIter next(fVarList);
      for (Long64_t li=0;li<fNentries;++li) {
         next.Reset();
         Bool_t inrange=kTRUE;
         TParallelCoordVar* var;
         while((var = (TParallelCoordVar*)next())){
            if(!var->Eval(li,fCurrentSelection)) inrange = kFALSE;
         }
         if(!inrange) continue;
         enlist->Enter(fCurrentEntries->GetEntry(li));
      }
      return enlist;
   }
}
Double_t TParallelCoord::GetGlobalMax()
{
   
   Double_t gmax=-FLT_MAX;
   TIter next(fVarList);
   TParallelCoordVar* var;
   while ((var = (TParallelCoordVar*)next())) {
      if (gmax < var->GetCurrentMax()) gmax = var->GetCurrentMax();
   }
   return gmax;
}
Double_t TParallelCoord::GetGlobalMin()
{
   
   Double_t gmin=FLT_MAX;
   TIter next(fVarList);
   TParallelCoordVar* var;
   while ((var = (TParallelCoordVar*)next())) {
      if (gmin > var->GetCurrentMin()) gmin = var->GetCurrentMin();
   }
   return gmin;
}
Int_t TParallelCoord::GetNbins()
{
   
   
   return ((TParallelCoordVar*)fVarList->First())->GetNbins();
}
TParallelCoordSelect* TParallelCoord::GetSelection(const char* title)
{
   
   TIter next(fSelectList);
   TParallelCoordSelect* sel;
   while ((sel = (TParallelCoordSelect*)next()) && strcmp(title,sel->GetTitle())) { }
   return sel;
}
TTree* TParallelCoord::GetTree()
{
   
   
   
   if (fTree) return fTree;
   if (fTreeFileName=="" || fTreeName=="") {
      Error("GetTree","Cannot load the tree: no tree defined!");
      return 0;
   }
   TFile *f = TFile::Open(fTreeFileName.Data());
   if (!f) {
      Error("GetTree","Tree file name : \"%s\" does not exsist (Are you in the correct directory?).",fTreeFileName.Data());
      return 0;
   } else if (f->IsZombie()) {
      Error("GetTree","while opening \"%s\".",fTreeFileName.Data());
      return 0;
   } else {
      fTree = (TTree*)f->Get(fTreeName.Data());
      if (!fTree) {
         Error("GetTree","\"%s\" not found in \"%s\".", fTreeName.Data(), fTreeFileName.Data());
         return 0;
      } else {
         fTree->SetEntryList(fCurrentEntries);
         TString varexp = "";
         TIter next(fVarList);
         TParallelCoordVar* var;
         while ((var = (TParallelCoordVar*)next())) varexp.Append(Form(":%s",var->GetTitle()));
         varexp.Remove(TString::kLeading,':');
         fTree->Draw(varexp.Data(),"","goff para");
         TSelectorDraw* selector = (TSelectorDraw*)((TTreePlayer*)fTree->GetPlayer())->GetSelector();
         next.Reset();
         Int_t i = 0;
         while ((var = (TParallelCoordVar*)next())) {
            var->SetValues(fNentries, selector->GetVal(i));
            ++i;
         }
         return fTree;
      }
   }
}
      
Double_t* TParallelCoord::GetVariable(const char* vartitle)
{
   
   TIter next(fVarList);
   TParallelCoordVar* var = 0;
   while(((var = (TParallelCoordVar*)next()) != 0) && (var->GetTitle() != vartitle)) { }
   if(!var) return 0;
   else     return var->GetValues();
}
Double_t* TParallelCoord::GetVariable(Int_t i)
{
   
   if(i<0 || (UInt_t)i>fNvar) return 0;
   else return ((TParallelCoordVar*)fVarList->At(i))->GetValues();
}
void TParallelCoord::Init()
{
   
   fNentries = 0;
   fVarList = 0;
   fSelectList = 0;
   SetBit(kVertDisplay,kTRUE);
   SetBit(kCurveDisplay,kFALSE);
   SetBit(kPaintEntries,kTRUE);
   SetBit(kLiveUpdate,kFALSE);
   SetBit(kGlobalScale,kFALSE);
   SetBit(kCandleChart,kFALSE);
   SetBit(kGlobalLogScale,kFALSE);
   fTree = 0;
   fCurrentEntries = 0;
   fInitEntries = 0;
   fCurrentSelection = 0;
   fNvar = 0;
   fDotsSpacing = 0;
   fCurrentFirst = 0;
   fCurrentN = 0;
   fCandleAxis = 0;
   fWeightCut = 0;
   fLineWidth = 1;
   fLineColor = kGreen-8;
   fTreeName = "";
   fTreeFileName = "";
}
void TParallelCoord::Paint(Option_t* )
{
   
   if (!GetTree()) return;
   gPad->Range(0,0,1,1);
   TFrame *frame = gPad->GetFrame();
   frame->SetLineColor(gPad->GetFillColor());
   SetAxesPosition();
   if(TestBit(kPaintEntries)){
      PaintEntries(0);
      TIter next(fSelectList);
      TParallelCoordSelect* sel;
      while((sel = (TParallelCoordSelect*)next())) {
         if(sel->GetSize()>0 && sel->TestBit(TParallelCoordSelect::kActivated)) {
            PaintEntries(sel);
         }
      }
   }
   gPad->RangeAxis(0,0,1,1);
}
void TParallelCoord::PaintEntries(TParallelCoordSelect* sel)
{
   
   if (fVarList->GetSize() < 2) return;
   Int_t i=0;
   Long64_t n=0;
   
   Double_t *x = new Double_t[fNvar];
   Double_t *y = new Double_t[fNvar];
   
   TGraph    *gr     = 0;
   TPolyLine *pl     = 0;
   TAttLine  *evline = 0;
   
   if (TestBit (kCurveDisplay)) {gr = new TGraph(fNvar); evline = (TAttLine*)gr;}
   else                       {pl = new TPolyLine(fNvar); evline = (TAttLine*)pl;}
   
   if (fDotsSpacing == 0) evline->SetLineStyle(1);
   else                   evline->SetLineStyle(11);
   if (!sel){
      evline->SetLineWidth(GetLineWidth());
      evline->SetLineColor(GetLineColor());
   } else {
      evline->SetLineWidth(sel->GetLineWidth());
      evline->SetLineColor(sel->GetLineColor());
   }
   TParallelCoordVar *var;
   
   TFrame *frame = gPad->GetFrame();
   Double_t lx   = ((frame->GetX2() - frame->GetX1())/(fNvar-1));
   Double_t ly   = ((frame->GetY2() - frame->GetY1())/(fNvar-1));
   Double_t a,b;
   TRandom r;
   
   for (n=fCurrentFirst; n<fCurrentFirst+fCurrentN; ++n) {
      TListIter next(fVarList);
      Bool_t inrange = kTRUE;
      
      if (sel) {
         while ((var = (TParallelCoordVar*)next())){
            if (!var->Eval(n,sel)) inrange = kFALSE;
         }
      }
      if (fWeightCut > 0) {
         next.Reset();
         Int_t entryweight = 0;
         while ((var = (TParallelCoordVar*)next())) entryweight+=var->GetEntryWeight(n);
         if (entryweight/(Int_t)fNvar < fWeightCut) inrange = kFALSE;
      }
      if(!inrange) continue;
      i = 0;
      next.Reset();
      
      while ((var = (TParallelCoordVar*)next())) {
         var->GetEntryXY(n,x[i],y[i]);
         ++i;
      }
      
      
      if (fDotsSpacing != 0) {
         if (TestBit(kVertDisplay)) {
            a    = (y[1]-y[0])/(x[1]-x[0]);
            b    = y[0]-a*x[0];
            x[0] = x[0]+lx*r.Rndm(n);
            y[0] = a*x[0]+b;
         } else {
            a    = (x[1]-x[0])/(y[1]-y[0]);
            b    = x[0]-a*y[0];
            y[0] = y[0]+ly*r.Rndm(n);
            x[0] = a*y[0]+b;
         }
      }
      if (pl) pl->PaintPolyLine(fNvar,x,y);
      else    gr->PaintGraph(fNvar,x,y,"C");
   }
   
   if (pl) delete pl;
   if (gr) delete gr;
   delete [] x;
   delete [] y;
}
void TParallelCoord::RemoveVariable(TParallelCoordVar *var)
{
   
   fVarList->Remove(var);
   fNvar = fVarList->GetSize();
   SetAxesPosition();
}
TParallelCoordVar* TParallelCoord::RemoveVariable(const char* vartitle)
{
   
   TIter next(fVarList);
   TParallelCoordVar* var=0;
   while((var = (TParallelCoordVar*)next())) {
      if (!strcmp(var->GetTitle(),vartitle)) break;
   }
   if(!var) Error("RemoveVariable","\"%s\" not a variable",vartitle);
   fVarList->Remove(var);
   fNvar = fVarList->GetSize();
   SetAxesPosition();
   var->DeleteVariable();
   return var;
}
void TParallelCoord::ResetTree()
{
   
   if(!fTree) return;
   fTree->SetEntryList(fInitEntries);
   fCurrentEntries = fInitEntries;
   fNentries = fCurrentEntries->GetN();
   fCurrentFirst = 0;
   fCurrentN = fNentries;
   TString varexp = "";
   TIter next(fVarList);
   TParallelCoordVar* var;
   while ((var = (TParallelCoordVar*)next())) varexp.Append(Form(":%s",var->GetTitle()));
   varexp.Remove(TString::kLeading,':');
   fTree->Draw(varexp.Data(),"","goff para");
   next.Reset();
   TSelectorDraw* selector = (TSelectorDraw*)((TTreePlayer*)fTree->GetPlayer())->GetSelector();
   Int_t i = 0;
   while ((var = (TParallelCoordVar*)next())) {
      var->SetValues(fNentries, selector->GetVal(i));
      ++i;
   }
   if (fSelectList) {           
      fSelectList->Delete();    
      fCurrentSelection = 0;    
   }
   gPad->Modified();
   gPad->Update();
}
void TParallelCoord::SaveEntryLists(const char* filename, Bool_t overwrite)
{
   
   TString sfile = filename;
   if (sfile == "") sfile = Form("%s_parallelcoord_entries.root",fTree->GetName());
   
   TFile* f = TFile::Open(sfile.Data());
   if (f) {
      Warning("SaveEntryLists","%s already exists.", sfile.Data());
      if (!overwrite) return;
      else Warning("SaveEntryLists","Overwriting.");
      f = new TFile(sfile.Data(),"RECREATE");
   } else {
      f = new TFile(sfile.Data(),"CREATE");
   }
   gDirectory = f;
   fInitEntries->Write("initentries");
   fCurrentEntries->Write("currententries");
   Info("SaveEntryLists","File \"%s\" written.",sfile.Data());
}
void TParallelCoord::SavePrimitive(ostream & out, Option_t* options)
{
   
   TString opt = options;
   opt.ToLower();
   
   
   const char* filename = Form("%s_parallelcoord_entries.root",fTree->GetName());
   SaveEntryLists(filename,kTRUE); 
   SaveTree(fTreeFileName,kTRUE);  
   out<<"   // Create a TParallelCoord."<<endl;
   out<<"   TFile *f = TFile::Open(\""<<fTreeFileName.Data()<<"\");"<<endl;
   out<<"   TTree* tree = (TTree*)f->Get(\""<<fTreeName.Data()<<"\");"<<endl;
   out<<"   TParallelCoord* para = new TParallelCoord(tree,"<<fNentries<<");"<<endl;
   out<<"   // Load the entrylists."<<endl;
   out<<"   TFile *entries = TFile::Open(\""<<filename<<"\");"<<endl;
   out<<"   TEntryList *currententries = (TEntryList*)entries->Get(\"currententries\");"<<endl;
   out<<"   tree->SetEntryList(currententries);"<<endl;
   out<<"   para->SetInitEntries((TEntryList*)entries->Get(\"initentries\"));"<<endl;
   out<<"   para->SetCurrentEntries(currententries);"<<endl;
   TIter next(fSelectList);
   TParallelCoordSelect* sel;
   out<<"   TParallelCoordSelect* sel;"<<endl;
   out<<"   para->GetSelectList()->Delete();"<<endl;
   while ((sel = (TParallelCoordSelect*)next())) {
      out<<"   para->AddSelection(\""<<sel->GetTitle()<<"\");"<<endl;
      out<<"   sel = (TParallelCoordSelect*)para->GetSelectList()->Last();"<<endl;
      out<<"   sel->SetLineColor("<<sel->GetLineColor()<<");"<<endl;
      out<<"   sel->SetLineWidth("<<sel->GetLineWidth()<<");"<<endl;
   }
   TIter nextbis(fVarList);
   TParallelCoordVar* var;
   TString varexp = "";
   while ((var = (TParallelCoordVar*)nextbis())) varexp.Append(Form(":%s",var->GetTitle()));
   varexp.Remove(TString::kLeading,':');
   out<<"   tree->Draw(\""<<varexp.Data()<<"\",\"\",\"goff para\");"<<endl;
   out<<"   TSelectorDraw* selector = (TSelectorDraw*)((TTreePlayer*)tree->GetPlayer())->GetSelector();"<<endl;
   nextbis.Reset();
   Int_t i=0;
   out<<"   TParallelCoordVar* var;"<<endl;
   while ((var = (TParallelCoordVar*)nextbis())) {
      out<<"   //***************************************"<<endl;
      out<<"   // Create the axis \""<<var->GetTitle()<<"\"."<<endl;
      out<<"   para->AddVariable(selector->GetVal("<<i<<"),\""<<var->GetTitle()<<"\");"<<endl;
      out<<"   var = (TParallelCoordVar*)para->GetVarList()->Last();"<<endl;
      var->SavePrimitive(out,"pcalled");
      ++i;
   }
   out<<"   //***************************************"<<endl;
   out<<"   // Set the TParallelCoord parameters."<<endl;
   out<<"   para->SetCurrentFirst("<<fCurrentFirst<<");"<<endl;
   out<<"   para->SetCurrentN("<<fCurrentN<<");"<<endl;
   out<<"   para->SetWeightCut("<<fWeightCut<<");"<<endl;
   out<<"   para->SetDotsSpacing("<<fDotsSpacing<<");"<<endl;
   out<<"   para->SetLineColor("<<GetLineColor()<<");"<<endl;
   out<<"   para->SetLineWidth("<<GetLineWidth()<<");"<<endl;
   out<<"   para->SetBit(TParallelCoord::kVertDisplay,"<<TestBit(kVertDisplay)<<");"<<endl;
   out<<"   para->SetBit(TParallelCoord::kCurveDisplay,"<<TestBit(kCurveDisplay)<<");"<<endl;
   out<<"   para->SetBit(TParallelCoord::kPaintEntries,"<<TestBit(kPaintEntries)<<");"<<endl;
   out<<"   para->SetBit(TParallelCoord::kLiveUpdate,"<<TestBit(kLiveUpdate)<<");"<<endl;
   out<<"   para->SetBit(TParallelCoord::kGlobalLogScale,"<<TestBit(kGlobalLogScale)<<");"<<endl;
   if (TestBit(kGlobalScale)) out<<"   para->SetGlobalScale(kTRUE);"<<endl;
   if (TestBit(kCandleChart)) out<<"   para->SetCandleChart(kTRUE);"<<endl;
   if (TestBit(kGlobalLogScale)) out<<"   para->SetGlobalLogScale(kTRUE);"<<endl;
   out<<endl<<"   para->Draw();"<<endl;
}
void TParallelCoord::SaveTree(const char* filename, Bool_t overwrite)
{
   
   if (!(fTreeFileName=="")) return;
   TString sfile = filename;
   if (sfile == "") sfile = Form("%s.root",fTree->GetName());
   
   TFile* f = TFile::Open(sfile.Data());
   if (f) {
      Warning("SaveTree","%s already exists.", sfile.Data());
      if (!overwrite) return;
      else Warning("SaveTree","Overwriting.");
      f = new TFile(sfile.Data(),"RECREATE");
   } else {
      f = new TFile(sfile.Data(),"CREATE");
   }
   gDirectory = f;
   fTree->Write(fTreeName.Data());
   fTreeFileName = sfile;
   Info("SaveTree","File \"%s\" written.",sfile.Data());
}
void TParallelCoord::SetAxesPosition()
{
   
   if(!gPad) return;
   Bool_t vert          = TestBit (kVertDisplay);
   TFrame *frame        = gPad->GetFrame();
   if (fVarList->GetSize() > 1) {
      if (vert) {
         frame->SetX1(1.0/((Double_t)fVarList->GetSize()+1));
         frame->SetX2(1-frame->GetX1());
         frame->SetY1(0.1);
         frame->SetY2(0.9);
         gPad->RangeAxis(1.0/((Double_t)fVarList->GetSize()+1),0.1,1-frame->GetX1(),0.9);
      } else {
         frame->SetX1(0.1);
         frame->SetX2(0.9);
         frame->SetY1(1.0/((Double_t)fVarList->GetSize()+1));
         frame->SetY2(1-frame->GetY1());
         gPad->RangeAxis(0.1,1.0/((Double_t)fVarList->GetSize()+1),0.9,1-frame->GetY1());
      }
      
      Double_t horSpace    = (frame->GetX2() - frame->GetX1())/(fNvar-1);
      Double_t verSpace   = (frame->GetY2() - frame->GetY1())/(fNvar-1);
      Int_t i=0;
      TIter next(fVarList);
      
      TParallelCoordVar* var;
      while((var = (TParallelCoordVar*)next())){
         if (vert) var->SetX(gPad->GetFrame()->GetX1() + i*horSpace,TestBit(kGlobalScale));
         else      var->SetY(gPad->GetFrame()->GetY1() + i*verSpace,TestBit(kGlobalScale));
         ++i;
      }
   } else if (fVarList->GetSize()==1) {
      frame->SetX1(0.1);
      frame->SetX2(0.9);
      frame->SetY1(0.1);
      frame->SetY2(0.9);
      if (vert) ((TParallelCoordVar*)fVarList->First())->SetX(0.5,TestBit(kGlobalScale));
      else      ((TParallelCoordVar*)fVarList->First())->SetY(0.5,TestBit(kGlobalScale));
   }
}
void TParallelCoord::SetAxisHistogramBinning(Int_t n)
{
   
   TIter next(fVarList);
   TParallelCoordVar *var;
   while((var = (TParallelCoordVar*)next())) var->SetHistogramBinning(n);
}
void TParallelCoord::SetAxisHistogramHeight(Double_t h)
{
   
   TIter next(fVarList);
   TParallelCoordVar *var;
   while((var = (TParallelCoordVar*)next())) var->SetHistogramHeight(h);
}
void TParallelCoord::SetGlobalLogScale(Bool_t lt)
{
   
   if (lt == TestBit(kGlobalLogScale)) return;
   SetBit(kGlobalLogScale,lt);
   TIter next(fVarList);
   TParallelCoordVar* var;
   while ((var = (TParallelCoordVar*)next())) var->SetLogScale(lt);
   if (TestBit(kGlobalScale)) SetGlobalScale(kTRUE);
}
void TParallelCoord::SetGlobalScale(Bool_t gl)
{
   
   SetBit(kGlobalScale,gl);
   if (fCandleAxis) {
      delete fCandleAxis;
      fCandleAxis = 0;
   }
   if (gl) {
      Double_t min,max;
      min = GetGlobalMin();
      max = GetGlobalMax();
      if (TestBit(kGlobalLogScale) && min<=0) min = 0.00001*max;
      if (TestBit(kVertDisplay)) {
         if (!TestBit(kGlobalLogScale)) fCandleAxis = new TGaxis(0.05,0.1,0.05,0.9,min,max);
         else                           fCandleAxis = new TGaxis(0.05,0.1,0.05,0.9,min,max,510,"G");
      } else {
         if (!TestBit(kGlobalLogScale)) fCandleAxis = new TGaxis(0.1,0.05,0.9,0.05,min,max);
         else                           fCandleAxis = new TGaxis(0.1,0.05,0.9,0.05,min,max,510,"G");
      }
      fCandleAxis->Draw();
      SetGlobalMin(min);
      SetGlobalMax(max);
      TIter next(fVarList);
      TParallelCoordVar* var;
      while ((var = (TParallelCoordVar*)next())) var->GetHistogram();
   }
   gPad->Modified();
   gPad->Update();
}   
void TParallelCoord::SetAxisHistogramLineWidth(Int_t lw)
{
   
   TIter next(fVarList);
   TParallelCoordVar *var;
   while((var = (TParallelCoordVar*)next())) var->SetHistogramLineWidth(lw);
}
void TParallelCoord::SetCandleChart(Bool_t can)
{
   
   SetBit(kCandleChart,can);
   SetGlobalScale(can);
   TIter next(fVarList);
   TParallelCoordVar* var;
   while ((var = (TParallelCoordVar*)next())) {
      var->SetBoxPlot(can);
      var->SetHistogramLineWidth(0);
   }
   if (fCandleAxis) delete fCandleAxis;
   fCandleAxis = 0;
   SetBit(kPaintEntries,!can);
   if (can) {
      if (TestBit(kVertDisplay)) fCandleAxis = new TGaxis(0.05,0.1,0.05,0.9,GetGlobalMin(),GetGlobalMax());
      else                       fCandleAxis = new TGaxis(0.1,0.05,0.9,0.05,GetGlobalMin(),GetGlobalMax());
      fCandleAxis->Draw();
   } else {
      if (fCandleAxis) {
         delete fCandleAxis;
         fCandleAxis = 0;
      }
   }
   gPad->Modified();
   gPad->Update();
}
void TParallelCoord::SetCurrentFirst(Long64_t f)
{
   
   if(f<0 || f>fNentries) return;
   fCurrentFirst = f;
   if(fCurrentFirst + fCurrentN > fNentries) fCurrentN = fNentries-fCurrentFirst;
   TIter next(fVarList);
   TParallelCoordVar* var;
   while ((var = (TParallelCoordVar*)next())) {
      var->GetMinMaxMean();
      var->GetHistogram();
      if (var->TestBit(TParallelCoordVar::kShowBox)) var->GetQuantiles();
   }
}
void TParallelCoord::SetCurrentN(Long64_t n)
{
   
   if(n<=0) return;
   if(fCurrentFirst+n>fNentries) fCurrentN = fNentries-fCurrentFirst;
   else fCurrentN = n;
   TIter next(fVarList);
   TParallelCoordVar* var;
   while ((var = (TParallelCoordVar*)next())) {
      var->GetMinMaxMean();
      var->GetHistogram();
      if (var->TestBit(TParallelCoordVar::kShowBox)) var->GetQuantiles();
   }
}  
TParallelCoordSelect* TParallelCoord::SetCurrentSelection(const char* title)
{
   
   if (fCurrentSelection && fCurrentSelection->GetTitle() == title) return fCurrentSelection;
   TIter next(fSelectList);
   TParallelCoordSelect* sel;
   while((sel = (TParallelCoordSelect*)next()) && strcmp(sel->GetTitle(),title))
   if(!sel) return 0;
   fCurrentSelection = sel;
   return sel;
}
void TParallelCoord::SetCurrentSelection(TParallelCoordSelect* sel)
{
   
   if (fCurrentSelection == sel) return;
   fCurrentSelection = sel;
}
void TParallelCoord::SetDotsSpacing(Int_t s)
{
   
   if (s == fDotsSpacing) return;
   fDotsSpacing = s;
   gStyle->SetLineStyleString(11,Form("%d %d",4,s*8));
}
void TParallelCoord::SetEntryList(TParallelCoord* para, TEntryList* enlist)
{
   
   para->SetCurrentEntries(enlist);
   para->SetInitEntries(enlist);
}
void TParallelCoord::SetGlobalMax(Double_t max)
{
   
   TIter next(fVarList);
   TParallelCoordVar* var;
   while ((var = (TParallelCoordVar*)next())) {
      var->SetCurrentMax(max);
   }
}
void TParallelCoord::SetGlobalMin(Double_t min)
{
   
   TIter next(fVarList);
   TParallelCoordVar* var;
   while ((var = (TParallelCoordVar*)next())) {
      var->SetCurrentMin(min);
   }
}
void TParallelCoord::SetLiveRangesUpdate(Bool_t on)
{
   
   SetBit(kLiveUpdate,on);
   TIter next(fVarList);
   TParallelCoordVar* var;
   while((var = (TParallelCoordVar*)next())) var->SetLiveRangesUpdate(on);
}
void TParallelCoord::SetVertDisplay(Bool_t vert)
{
   
   if (vert == TestBit (kVertDisplay)) return;
   SetBit(kVertDisplay,vert);
   if (!gPad) return;
   UInt_t ui = 0;
   TFrame* frame = gPad->GetFrame();
   Double_t horaxisspace = (frame->GetX2() - frame->GetX1())/(fNvar-1);
   Double_t veraxisspace = (frame->GetY2() - frame->GetY1())/(fNvar-1);
   TIter next(fVarList);
   TParallelCoordVar* var;
   while ((var = (TParallelCoordVar*)next())) {
      if (vert) var->SetX(frame->GetX1() + ui*horaxisspace,TestBit(kGlobalScale));
      else      var->SetY(frame->GetY1() + ui*veraxisspace,TestBit(kGlobalScale));
      ++ui;
   }
   if (TestBit(kCandleChart)) {
      if (fCandleAxis) delete fCandleAxis;
      if (TestBit(kVertDisplay)) fCandleAxis = new TGaxis(0.05,0.1,0.05,0.9,GetGlobalMin(),GetGlobalMax());
      else                       fCandleAxis = new TGaxis(0.1,0.05,0.9,0.05,GetGlobalMin(),GetGlobalMax());
      fCandleAxis->Draw();
   }
   gPad->Modified();
   gPad->Update();
}
void TParallelCoord::UnzoomAll()
{
   
   TIter next(fVarList);
   TParallelCoordVar* var;
   while((var = (TParallelCoordVar*)next())) var->Unzoom();
}
Last change: Wed Jun 25 08:50:21 2008
Last generated: 2008-06-25 08:50
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.