#include "TSelectorDraw.h"
#include "TROOT.h"
#include "TH2.h"
#include "TH3.h"
#include "TView.h"
#include "TGraph.h"
#include "TPolyMarker3D.h"
#include "TDirectory.h"
#include "TVirtualPad.h"
#include "TProfile.h"
#include "TProfile2D.h"
#include "TTreeFormulaManager.h"
#include "TEnv.h"
#include "TTree.h"
#include "TCut.h"
#include "TEntryList.h"
#include "TEventList.h"
#include "THLimitsFinder.h"
#include "TStyle.h"
#include "TClass.h"
ClassImp(TSelectorDraw)
const Int_t kCustomHistogram = BIT(17);
TSelectorDraw::TSelectorDraw()
{
   
   fTree           = 0;
   fW              = 0;
   fValSize        = 4;
   fVal            = new Double_t*[fValSize];
   fVmin           = new Double_t[fValSize];
   fVmax           = new Double_t[fValSize];
   fNbins          = new Int_t[fValSize];
   fVarMultiple    = new Bool_t[fValSize];
   fVar            = new TTreeFormula*[fValSize];
   for(Int_t i=0;i<fValSize;++i){
      fVal[i] = 0;
      fVar[i] = 0;
   }
   fManager        = 0;
   fMultiplicity   = 0;
   fSelect         = 0;
   fSelectedRows   = 0;
   fDraw           = 0;
   fObject         = 0;
   fOldHistogram   = 0;
   fObjEval        = kFALSE;
   fSelectMultiple = kFALSE;
   fCleanElist     = kFALSE;
   fTreeElist      = 0;
   fAction         = 0;
   fNfill          = 0;
   fDimension      = 0;
   fOldEstimate    = 0;
   fForceRead      = 0;
   fWeight         = 1;
}
TSelectorDraw::~TSelectorDraw()
{
   
   ClearFormula();
   delete [] fVar;
   if(fVal){
      for(Int_t i=0;i<fValSize;++i)
         delete [] fVal[i];
      delete [] fVal;
   }
   if(fVmin) delete [] fVmin;
   if(fVmax) delete [] fVmax;
   if(fNbins) delete [] fNbins;
   if(fVarMultiple) delete [] fVarMultiple;
   if (fW)     delete [] fW;
}
void TSelectorDraw::Begin(TTree *tree)
{
   
   SetStatus(0);
   ResetBit(kCustomHistogram);
   fSelectedRows   = 0;
   fTree = tree;
   fDimension = 0;
   const char *varexp0   = fInput->FindObject("varexp")->GetTitle();
   const char *selection = fInput->FindObject("selection")->GetTitle();
   const char *option    = GetOption();
   TString  opt;
   char *hdefault = (char *)"htemp";
   char *varexp;
   Int_t i,j,hkeep;
   opt = option;
   opt.ToLower();
   fOldHistogram = 0;
   TEntryList *enlist = 0;
   TEventList *evlist = 0;
   TString htitle;
   Bool_t profile = kFALSE;
   Bool_t optSame = kFALSE;
   Bool_t optEnlist = kFALSE;
   Bool_t optpara = kFALSE;
   Bool_t optcandle = kFALSE;
   if (opt.Contains("same")) {
      optSame = kTRUE;
      opt.ReplaceAll("same","");
   }
   if (opt.Contains("entrylist")){
      optEnlist = kTRUE;
      opt.ReplaceAll("entrylist", "");
   }
   if (opt.Contains("para")){
      optpara = kTRUE;
      opt.ReplaceAll("para","");
   }
   if (opt.Contains("candle")) {
      optcandle = kTRUE;
      opt.ReplaceAll("candle","");
   }
   TCut realSelection(selection);
   
   TEntryList *inElist = fTree->GetEntryList();
   evlist = fTree->GetEventList();
   if (evlist && inElist){
      
      
      
      
      inElist->SetBit(kCanDelete, kTRUE);
   }
   fCleanElist = kFALSE;
   fTreeElist = inElist;
   if ( inElist && inElist->GetReapplyCut() ) {
      realSelection *= inElist->GetTitle();
   }
   
   
   
   
   
   
   
   
   
   Bool_t canRebin = kTRUE;
   if (optSame) canRebin = kFALSE;
   Int_t nbinsx=0, nbinsy=0, nbinsz=0;
   Double_t xmin=0, xmax=0, ymin=0, ymax=0, zmin=0, zmax=0;
   fObject  = 0;
   char *hname = 0;
   char *hnamealloc = 0;
   i = 0;
   if (varexp0 && strlen(varexp0)) {
      for(UInt_t k=strlen(varexp0)-1;k>0;k--) {
         if (varexp0[k]=='>' && varexp0[k-1]=='>') {
            i = (int)( &(varexp0[k-1]) - varexp0 );  
            hnamealloc = new char[strlen(&(varexp0[k+1]))+1];
            hname = hnamealloc;
            strcpy(hname,&(varexp0[k+1]));
            break;
         }
      }
   }
   
   if (hname) {
      hkeep  = 1;
      varexp = new char[i+1];
      varexp[0] = 0; 
      Bool_t hnameplus = kFALSE;
      while (*hname == ' ') hname++;
      if (*hname == '+') {
         hnameplus = kTRUE;
         hname++;
         while (*hname == ' ') hname++; 
      }
      j = strlen(hname) - 1;   
      while (j) {
         if (hname[j] != ' ') break;
         hname[j] = 0;
         j--;
      }
      if (i) {
         strncpy(varexp,varexp0,i); varexp[i]=0;
         Int_t mustdelete=0;
         SetBit(kCustomHistogram);
         
         
         
         
         
         
         char *pstart;    
         char *pend;      
         char *cdummy;    
         int ncomma;      
         int ncols;       
         Double_t value;  
         const Int_t maxvalues=9;
         pstart= strchr(hname,'(');
         pend =  strchr(hname,')');
         if (pstart != 0 ) {  
            mustdelete=1;
            
            if (pstart == strrchr(hname,'(')  &&  pend == strrchr(hname,')')) {
               
               ncomma=0;
               cdummy = pstart;
               cdummy = strchr(&cdummy[1],',');
               while (cdummy != 0) {
                  cdummy = strchr(&cdummy[1],',');
                  ncomma++;
               }
               if (ncomma+1 > maxvalues) {
                  Error("DrawSelect","ncomma+1>maxvalues, ncomma=%d, maxvalues=%d",ncomma,maxvalues);
                  ncomma=maxvalues-1;
               }
               ncomma++; 
               cdummy = pstart;
               
               ncols  = 1;
               for (j=0;j<i;j++) {
                  if (varexp[j] == ':'
                      && ! ( (j>0&&varexp[j-1]==':') || varexp[j+1]==':' )
                      ) {
                     ncols++;
                  }
               }
               if (ncols > 3 ) {  
                  Error("DrawSelect","ncols > 3, ncols=%d",ncols);
                  ncols = 0;
               }
               
               if (ncols*3 < ncomma) {
                  Error("DrawSelect","ncols*3 < ncomma ncols=%d, ncomma=%d",ncols,ncomma);
                  ncomma = ncols*3;
               }
               
               for (j=0;j<ncomma;j++) {
                  cdummy++;  
                  if (sscanf(cdummy," %lf ",&value) == 1) {
                     cdummy=strchr(&cdummy[1],',');
                     switch (j) {  
                        case 0:  
                           nbinsx = (Int_t)value;
                           if      (ncols<2) {
                              gEnv->SetValue("Hist.Binning.1D.x",nbinsx);
                           } else if (ncols<3) {
                              gEnv->SetValue("Hist.Binning.2D.x",nbinsx);
                              gEnv->SetValue("Hist.Binning.2D.Prof",nbinsx);
                           } else {
                              gEnv->SetValue("Hist.Binning.3D.x",nbinsx);
                              gEnv->SetValue("Hist.Binning.3D.Profx",nbinsx);
                           }
                           break;
                        case 1:  
                           xmin = value;
                           break;
                        case 2:  
                           xmax = value;
                           break;
                        case 3:  
                           nbinsy = (Int_t)value;
                           if (ncols<3) gEnv->SetValue("Hist.Binning.2D.y",nbinsy);
                           else {
                              gEnv->SetValue("Hist.Binning.3D.y",nbinsy);
                              gEnv->SetValue("Hist.Binning.3D.Profy",nbinsy);
                           }
                           break;
                        case 4:  
                           ymin = value;
                           break;
                        case 5:  
                           ymax = value;
                           break;
                        case 6:  
                           nbinsz = (Int_t)value;
                           gEnv->SetValue("Hist.Binning.3D.z",nbinsz);
                           break;
                        case 7:  
                           zmin = value;
                           break;
                        case 8:  
                           zmax = value;
                           break;
                        default:
                           Error("DrawSelect","j>8");
                           break;
                     }
                  }  
               } 
            } else {
               Error("Begin","Two open or close brackets found, hname=%s",hname);
            }
            
            pstart[0]='\0';   
         } 
         j = strlen(hname) - 1; 
         while (j) {
            if (hname[j] != ' ') break; 
            hname[j] = 0;
            j--;
         }
         TObject *oldObject = gDirectory->Get(hname);  
         fOldHistogram = oldObject ? dynamic_cast<TH1*>(oldObject) : 0;
         if (!fOldHistogram && oldObject && !oldObject->InheritsFrom(TH1::Class())) {
            Error("Begin","An object of type '%s' has the same name as the requested histo (%s)",oldObject->IsA()->GetName(),hname);
            SetStatus(-1);
            return;
         }
         if (fOldHistogram && !hnameplus) fOldHistogram->Reset();  
         if (mustdelete) {
            if (gDebug) {
               Warning("Begin","Deleting old histogram, since (possibly new) limits and binnings have been given");
            }
            delete fOldHistogram; fOldHistogram=0;
         }
      } else {
         
         TObject *oldObject = gDirectory->Get(hname);
         if (optEnlist){
            
            enlist = oldObject ? dynamic_cast<TEntryList*>(oldObject) : 0;
            if (!enlist && oldObject) {
               Error("Begin","An object of type '%s' has the same name as the requested event list (%s)",
                  oldObject->IsA()->GetName(),hname);
               SetStatus(-1);
               return;
            }
            if (!enlist) {
               enlist = new TEntryList(hname, realSelection.GetTitle());
            }
            if (enlist) {
               if (!hnameplus) {
                  if (enlist==inElist) {
                     
                     
                     inElist = new TEntryList(*enlist);
                     fCleanElist = kTRUE;
                     fTree->SetEntryList(inElist);
                  }
                  enlist->Reset();
                  enlist->SetTitle(realSelection.GetTitle());
               } else {
                  TCut old = enlist->GetTitle();
                  TCut upd = old || realSelection.GetTitle();
                  enlist->SetTitle(upd.GetTitle());
               }
            }
         }
         else {
            
            evlist = oldObject ? dynamic_cast<TEventList*>(oldObject) : 0;
            if (!evlist && oldObject) {
               Error("Begin","An object of type '%s' has the same name as the requested event list (%s)",
                  oldObject->IsA()->GetName(),hname);
               SetStatus(-1);
               return;
            }
            if (!evlist) {
               evlist = new TEventList(hname,realSelection.GetTitle(),1000,0);
            }
            if (evlist) {
               if (!hnameplus) {
                  if (evlist==fTree->GetEventList()) {
                     
                     
                     Error("Begin", "Input and output lists are the same!\n");
                     SetStatus(-1);
                     return;
                  }
                  evlist->Reset();
                  evlist->SetTitle(realSelection.GetTitle());
               } else {
                  TCut old = evlist->GetTitle();
                  TCut upd = old || realSelection.GetTitle();
                  evlist->SetTitle(upd.GetTitle());
               }
            }
         }
      }  
   } else { 
      hname  = hdefault;
      hkeep  = 0;
      varexp = (char*)varexp0;
      if (gDirectory) {
         fOldHistogram = (TH1*)gDirectory->Get(hname);
         if (fOldHistogram) { fOldHistogram->Delete(); fOldHistogram = 0;}
      }
   }
   
   if (!CompileVariables(varexp, realSelection.GetTitle())) {SetStatus(-1); return;}
   if (fDimension > 4 && !(optpara || optcandle)) {
      Error("Begin","Too many variables. Use the option \"para\" or \"candle\" to display more than 4 variables.");
      SetStatus(-1);
      return;
   }
   
   Int_t nsel = strlen(selection);
   if (nsel > 1) {
      htitle.Form("%s {%s}",varexp,selection);
   } else {
      htitle = varexp;
   }
   if (fOldHistogram) {
      Int_t olddim = fOldHistogram->GetDimension();
      Int_t mustdelete = 0;
      if (fOldHistogram->InheritsFrom("TProfile")) {
         profile = kTRUE;
         olddim = 2;
      }
      if (fOldHistogram->InheritsFrom("TProfile2D")) {
         profile = kTRUE;
         olddim = 3;
      }
      if (opt.Contains("prof") && fDimension>1) {
         
         if (!profile || olddim != fDimension) mustdelete = 1;
      } else {
         if (olddim != fDimension) mustdelete = 1;
      }
      if (mustdelete) {
         Warning("Begin","Deleting old histogram with different dimensions");
         delete fOldHistogram; fOldHistogram = 0;
      }
   }
   
   fDraw = 0;
   if (!gPad && !opt.Contains("goff") && fDimension > 0) {
      gROOT->MakeDefCanvas();
      if (!gPad)   {SetStatus(-1); return;}
   }
   
   TH1 *hist;
   if (fDimension == 1) {
      fAction = 1;
      if (!fOldHistogram) {
         fNbins[0] = gEnv->GetValue("Hist.Binning.1D.x",100);
         if (gPad && optSame) {
            TListIter np(gPad->GetListOfPrimitives());
            TObject *op;
            TH1 *oldhtemp = 0;
            while ((op = np()) && !oldhtemp) {
               if (op->InheritsFrom("TH1")) oldhtemp = (TH1 *)op;
            }
            if (oldhtemp) {
               fNbins[0] = oldhtemp->GetXaxis()->GetNbins();
               fVmin[0]  = oldhtemp->GetXaxis()->GetXmin();
               fVmax[0]  = oldhtemp->GetXaxis()->GetXmax();
            } else {
               fVmin[0]  = gPad->GetUxmin();
               fVmax[0]  = gPad->GetUxmax();
            }
         } else {
            fAction   = -1;
            fVmin[0] = xmin;
            fVmax[0] = xmax;
            if (xmin < xmax) canRebin = kFALSE;
         }
      }
      if (fOldHistogram) {
         hist    = fOldHistogram;
         fNbins[0] = hist->GetXaxis()->GetNbins();
      } else {
         hist = new TH1F(hname,htitle.Data(),fNbins[0],fVmin[0],fVmax[0]);
         hist->SetLineColor(fTree->GetLineColor());
         hist->SetLineWidth(fTree->GetLineWidth());
         hist->SetLineStyle(fTree->GetLineStyle());
         hist->SetFillColor(fTree->GetFillColor());
         hist->SetFillStyle(fTree->GetFillStyle());
         hist->SetMarkerStyle(fTree->GetMarkerStyle());
         hist->SetMarkerColor(fTree->GetMarkerColor());
         hist->SetMarkerSize(fTree->GetMarkerSize());
         if (canRebin)hist->SetBit(TH1::kCanRebin);
         if (!hkeep) {
            hist->GetXaxis()->SetTitle(fVar[0]->GetTitle());
            hist->SetBit(kCanDelete);
            if (!opt.Contains("goff")) hist->SetDirectory(0);
         }
         if (opt.Length() && opt.Contains("e")) hist->Sumw2();
      }
      fVar[0]->SetAxis(hist->GetXaxis());
      fObject = hist;
      
   } else if (fDimension == 2 && !(optpara || optcandle)) {
      fAction = 2;
      if (!fOldHistogram || !optSame) {
         fNbins[0] = gEnv->GetValue("Hist.Binning.2D.y",40);
         fNbins[1] = gEnv->GetValue("Hist.Binning.2D.x",40);
         if (opt.Contains("prof")) fNbins[1] = gEnv->GetValue("Hist.Binning.2D.Prof",100);
         if (optSame) {
            TH1 *oldhtemp = (TH1*)gPad->FindObject(hdefault);
            if (oldhtemp) {
               fNbins[1] = oldhtemp->GetXaxis()->GetNbins();
               fVmin[1]  = oldhtemp->GetXaxis()->GetXmin();
               fVmax[1]  = oldhtemp->GetXaxis()->GetXmax();
               fNbins[0] = oldhtemp->GetYaxis()->GetNbins();
               fVmin[0]  = oldhtemp->GetYaxis()->GetXmin();
               fVmax[0]  = oldhtemp->GetYaxis()->GetXmax();
            } else {
               fNbins[1] = gEnv->GetValue("Hist.Binning.2D.x",40);
               fVmin[1]  = gPad->GetUxmin();
               fVmax[1]  = gPad->GetUxmax();
               fNbins[0] = gEnv->GetValue("Hist.Binning.2D.y",40);
               fVmin[0]  = gPad->GetUymin();
               fVmax[0]  = gPad->GetUymax();
            }
         } else {
            if (!fOldHistogram) fAction = -2;
            fVmin[1] = xmin;
            fVmax[1] = xmax;
            fVmin[0] = ymin;
            fVmax[0] = ymax;
            if (xmin < xmax && ymin < ymax) canRebin = kFALSE;
         }
      }
      if (profile || opt.Contains("prof")) {
         TProfile *hp;
         if (fOldHistogram) {
            fAction = 4;
            hp = (TProfile*)fOldHistogram;
         } else {
            if (fAction < 0) {
               fAction = -4;
               fVmin[1] = xmin;
               fVmax[1] = xmax;
               if (xmin < xmax) canRebin = kFALSE;
            }
            if (fAction == 2) {
               
               fAction = -4;
               TH1 *oldhtemp = (TH1*)gPad->FindObject(hdefault);
               if (oldhtemp) {
                  fNbins[1] = oldhtemp->GetXaxis()->GetNbins();
                  fVmin[1]  = oldhtemp->GetXaxis()->GetXmin();
                  fVmax[1]  = oldhtemp->GetXaxis()->GetXmax();
               }
            }
            if (opt.Contains("profs")) {
               hp = new TProfile(hname,htitle.Data(),fNbins[1],fVmin[1], fVmax[1],"s");
            } else if (opt.Contains("profi")) {
               hp = new TProfile(hname,htitle.Data(),fNbins[1],fVmin[1], fVmax[1],"i");
            } else if (opt.Contains("profg")) {
               hp = new TProfile(hname,htitle.Data(),fNbins[1],fVmin[1], fVmax[1],"g");
            } else {
               hp = new TProfile(hname,htitle.Data(),fNbins[1],fVmin[1], fVmax[1],"");
            }
            if (!hkeep) {
               hp->SetBit(kCanDelete);
               if (!opt.Contains("goff")) hp->SetDirectory(0);
            }
            hp->SetLineColor(fTree->GetLineColor());
            hp->SetLineWidth(fTree->GetLineWidth());
            hp->SetLineStyle(fTree->GetLineStyle());
            hp->SetFillColor(fTree->GetFillColor());
            hp->SetFillStyle(fTree->GetFillStyle());
            hp->SetMarkerStyle(fTree->GetMarkerStyle());
            hp->SetMarkerColor(fTree->GetMarkerColor());
            hp->SetMarkerSize(fTree->GetMarkerSize());
            if (canRebin)hp->SetBit(TH1::kCanRebin);
         }
         fVar[1]->SetAxis(hp->GetXaxis());
         fObject = hp;
      } else {
         TH2F *h2;
         if (fOldHistogram) {
            h2 = (TH2F*)fOldHistogram;
         } else {
            h2 = new TH2F(hname,htitle.Data(),fNbins[1],fVmin[1], fVmax[1], fNbins[0], fVmin[0], fVmax[0]);
            h2->SetLineColor(fTree->GetLineColor());
            h2->SetFillColor(fTree->GetFillColor());
            h2->SetFillStyle(fTree->GetFillStyle());
            h2->SetMarkerStyle(fTree->GetMarkerStyle());
            h2->SetMarkerColor(fTree->GetMarkerColor());
            h2->SetMarkerSize(fTree->GetMarkerSize());
            if (canRebin)h2->SetBit(TH1::kCanRebin);
            if (!hkeep) {
               h2->GetXaxis()->SetTitle(fVar[1]->GetTitle());
               h2->GetYaxis()->SetTitle(fVar[0]->GetTitle());
               h2->SetBit(TH1::kNoStats);
               h2->SetBit(kCanDelete);
               if (!opt.Contains("goff")) h2->SetDirectory(0);
            }
         }
         fVar[0]->SetAxis(h2->GetYaxis());
         fVar[1]->SetAxis(h2->GetXaxis());
         Bool_t graph = kFALSE;
         Int_t l = opt.Length();
         if (l == 0 || optSame) graph = kTRUE;
         if (opt.Contains("p")     || opt.Contains("*")    || opt.Contains("l"))    graph = kTRUE;
         if (opt.Contains("surf")  || opt.Contains("lego") || opt.Contains("cont")) graph = kFALSE;
         if (opt.Contains("col")   || opt.Contains("hist") || opt.Contains("scat")) graph = kFALSE;
         if (opt.Contains("box"))                                                   graph = kFALSE;
         fObject = h2;
         if (graph) {
            fAction = 12;
            if (!fOldHistogram && !optSame) fAction = -12;
         }
      }
      
   } else if ((fDimension == 3 || fDimension == 4) && !(optpara || optcandle)) {
      fAction = 3;
      if (fDimension == 4) fAction = 40;
      if (!fOldHistogram || !optSame) {
         fNbins[0] = gEnv->GetValue("Hist.Binning.3D.z",20);
         fNbins[1] = gEnv->GetValue("Hist.Binning.3D.y",20);
         fNbins[2] = gEnv->GetValue("Hist.Binning.3D.x",20);
         if (fDimension == 3 && opt.Contains("prof")) {
            fNbins[1] = gEnv->GetValue("Hist.Binning.3D.Profy",20);
            fNbins[2] = gEnv->GetValue("Hist.Binning.3D.Profx",20);
         }
         if (optSame) {
            TH1 *oldhtemp = (TH1*)gPad->FindObject(hdefault);
            if (oldhtemp) {
               fNbins[2] = oldhtemp->GetXaxis()->GetNbins();
               fVmin[2]  = oldhtemp->GetXaxis()->GetXmin();
               fVmax[2]  = oldhtemp->GetXaxis()->GetXmax();
               fNbins[1] = oldhtemp->GetYaxis()->GetNbins();
               fVmin[1]  = oldhtemp->GetYaxis()->GetXmin();
               fVmax[1]  = oldhtemp->GetYaxis()->GetXmax();
               fNbins[0] = oldhtemp->GetZaxis()->GetNbins();
               fVmin[0]  = oldhtemp->GetZaxis()->GetXmin();
               fVmax[0]  = oldhtemp->GetZaxis()->GetXmax();
            } else {
               TView *view = gPad->GetView();
               Double_t *rmin = view->GetRmin();
               Double_t *rmax = view->GetRmax();
               fNbins[2] = gEnv->GetValue("Hist.Binning.3D.z",20);
               fVmin[2]  = rmin[0];
               fVmax[2]  = rmax[0];
               fNbins[1] = gEnv->GetValue("Hist.Binning.3D.y",20);
               fVmin[1]  = rmin[1];
               fVmax[1]  = rmax[1];
               fNbins[0] = gEnv->GetValue("Hist.Binning.3D.x",20);
               fVmin[0]  = rmin[2];
               fVmax[0]  = rmax[2];
            }
         } else {
            if (!fOldHistogram && fDimension ==3) fAction = -3;
            fVmin[2] = xmin;
            fVmax[2] = xmax;
            fVmin[1] = ymin;
            fVmax[1] = ymax;
            fVmin[0] = zmin;
            fVmax[0] = zmax;
            if (xmin < xmax && ymin < ymax && zmin < zmax) canRebin = kFALSE;
         }
      }
      if ((fDimension == 3) && (profile || opt.Contains("prof"))) {
         TProfile2D *hp;
         if (fOldHistogram) {
            fAction = 23;
            hp = (TProfile2D*)fOldHistogram;
         } else {
            if (fAction < 0) {
               fAction = -23;
               fVmin[2] = xmin;
               fVmax[2] = xmax;
               fVmin[1] = ymin;
               fVmax[1] = ymax;
               if (xmin < xmax && ymin < ymax) canRebin = kFALSE;
            }
            if (opt.Contains("profs")) {
               hp = new TProfile2D(hname,htitle.Data(),fNbins[2],fVmin[2], fVmax[2],fNbins[1],fVmin[1], fVmax[1],"s");
            } else if (opt.Contains("profi")) {
               hp = new TProfile2D(hname,htitle.Data(),fNbins[2],fVmin[2], fVmax[2],fNbins[1],fVmin[1], fVmax[1],"i");
            } else if (opt.Contains("profg")) {
               hp = new TProfile2D(hname,htitle.Data(),fNbins[2],fVmin[2], fVmax[2],fNbins[1],fVmin[1], fVmax[1],"g");
            } else {
               hp = new TProfile2D(hname,htitle.Data(),fNbins[2],fVmin[2], fVmax[2],fNbins[1],fVmin[1], fVmax[1],"");
            }
            if (!hkeep) {
               hp->SetBit(kCanDelete);
               if (!opt.Contains("goff")) hp->SetDirectory(0);
            }
            hp->SetLineColor(fTree->GetLineColor());
            hp->SetLineWidth(fTree->GetLineWidth());
            hp->SetLineStyle(fTree->GetLineStyle());
            hp->SetFillColor(fTree->GetFillColor());
            hp->SetFillStyle(fTree->GetFillStyle());
            hp->SetMarkerStyle(fTree->GetMarkerStyle());
            hp->SetMarkerColor(fTree->GetMarkerColor());
            hp->SetMarkerSize(fTree->GetMarkerSize());
            if (canRebin)hp->SetBit(TH1::kCanRebin);
         }
         fVar[1]->SetAxis(hp->GetYaxis());
         fVar[2]->SetAxis(hp->GetXaxis());
         fObject = hp;
      } else if (fDimension == 3 && opt.Contains("col")) {
         TH2F *h2;
         if (fOldHistogram) {
            h2 = (TH2F*)fOldHistogram;
         } else {
            h2 = new TH2F(hname,htitle.Data(),fNbins[1],fVmin[1], fVmax[1], fNbins[0], fVmin[0], fVmax[0]);
            h2->SetLineColor(fTree->GetLineColor());
            h2->SetFillColor(fTree->GetFillColor());
            h2->SetFillStyle(fTree->GetFillStyle());
            h2->SetMarkerStyle(fTree->GetMarkerStyle());
            h2->SetMarkerColor(fTree->GetMarkerColor());
            h2->SetMarkerSize(fTree->GetMarkerSize());
            if (canRebin)h2->SetBit(TH1::kCanRebin);
            if (!hkeep) {
               h2->GetXaxis()->SetTitle(fVar[1]->GetTitle());
               h2->GetZaxis()->SetTitle(fVar[0]->GetTitle());
               h2->SetBit(TH1::kNoStats);
               h2->SetBit(kCanDelete);
               if (!opt.Contains("goff")) h2->SetDirectory(0);
            }
         }
         fVar[0]->SetAxis(h2->GetYaxis());
         fVar[1]->SetAxis(h2->GetXaxis());
         fObject = h2;
         fAction = 33;
      } else {
         TH3F *h3;
         if (fOldHistogram) {
            h3 = (TH3F*)fOldHistogram;
         } else {
            h3 = new TH3F(hname,htitle.Data(),fNbins[2],fVmin[2], fVmax[2],fNbins[1],fVmin[1], fVmax[1], fNbins[0], fVmin[0], fVmax[0]);
            h3->SetLineColor(fTree->GetLineColor());
            h3->SetFillColor(fTree->GetFillColor());
            h3->SetFillStyle(fTree->GetFillStyle());
            h3->SetMarkerStyle(fTree->GetMarkerStyle());
            h3->SetMarkerColor(fTree->GetMarkerColor());
            h3->SetMarkerSize(fTree->GetMarkerSize());
            if (canRebin)h3->SetBit(TH1::kCanRebin);
            if (!hkeep) {
               
               Double_t xoffset = h3->GetXaxis()->GetTitleOffset();
               Double_t yoffset = h3->GetYaxis()->GetTitleOffset();
               h3->GetXaxis()->SetTitleOffset(1.2*xoffset);
               h3->GetYaxis()->SetTitleOffset(1.2*yoffset);
               h3->GetXaxis()->SetTitle(fVar[2]->GetTitle());
               h3->GetYaxis()->SetTitle(fVar[1]->GetTitle());
               h3->GetZaxis()->SetTitle(fVar[0]->GetTitle());
               h3->SetBit(kCanDelete);
               h3->SetBit(TH1::kNoStats);
               if (!opt.Contains("goff")) h3->SetDirectory(0);
            }
         }
         fVar[0]->SetAxis(h3->GetZaxis());
         fVar[1]->SetAxis(h3->GetYaxis());
         fVar[2]->SetAxis(h3->GetXaxis());
         fObject = h3;
         Int_t noscat = strlen(option);
         if (optSame) noscat -= 4;
         if (!noscat && fDimension ==3) {
            fAction = 13;
            if (!fOldHistogram && !optSame) fAction = -13;
         }
      }
      
   } else if (enlist) {
      fAction = 5;
      fOldEstimate = fTree->GetEstimate();
      fTree->SetEstimate(1);
      fObject = enlist;
   } else if (evlist) {
      fAction = 5;
      fOldEstimate = fTree->GetEstimate();
      fTree->SetEstimate(1);
      fObject = evlist;
   } else if (optcandle || optpara) {
      if (optcandle) fAction = 7;
      else           fAction = 6;
   }
   if (hkeep) delete [] varexp;
   if (hnamealloc) delete [] hnamealloc;
   for(Int_t i=0;i<fValSize;++i)
      fVarMultiple[i] = kFALSE;
   fSelectMultiple = kFALSE;
   for(Int_t i=0;i<fDimension;++i){
      if(fVar[i] && fVar[i]->GetMultiplicity()) fVarMultiple[i] = kTRUE;
   }
   if (fSelect && fSelect->GetMultiplicity()) fSelectMultiple = kTRUE;
   fForceRead = fTree->TestBit(TTree::kForceRead);
   fWeight  = fTree->GetWeight();
   fNfill   = 0;
   for(Int_t i=0;i<fDimension;++i){
      if(!fVal[i] && fVar[i]){
         fVal[i] = new Double_t[(Int_t)fTree->GetEstimate()];
      }
   }
   if (!fW)             fW  = new Double_t[(Int_t)fTree->GetEstimate()];
   for(Int_t i=0;i<fValSize;++i){
      fVmin[i] = FLT_MAX;
      fVmax[i] = -FLT_MAX;
   }
}
void TSelectorDraw::ClearFormula()
{
   
   ResetBit(kWarn);
   for (Int_t i=0;i<fValSize;++i){
      delete fVar[i];
      fVar[i] = 0;
   }
   delete fSelect; fSelect = 0;
   fManager = 0;
   fMultiplicity = 0;
}
Bool_t TSelectorDraw::CompileVariables(const char *varexp, const char *selection)
{
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   TString title;
   Int_t i,nch,ncols;
   
   fDimension = 0;
   ClearFormula();
   fMultiplicity = 0;
   fObjEval = kFALSE;
   if (strlen(selection)) {
      fSelect = new TTreeFormula("Selection",selection,fTree);
      fSelect->SetQuickLoad(kTRUE);
      if (!fSelect->GetNdim()) {delete fSelect; fSelect = 0; return kFALSE; }
   }
   
   nch = strlen(varexp);
   if (nch == 0) {
      fDimension = 0;
      fManager = new TTreeFormulaManager();
      if (fSelect) fManager->Add(fSelect);
      fTree->ResetBit(TTree::kForceRead);
      fManager->Sync();
      if (fManager->GetMultiplicity()==-1) fTree->SetBit(TTree::kForceRead);
      if (fManager->GetMultiplicity()>=1) fMultiplicity = fManager->GetMultiplicity();
      return kTRUE;
   }
   title = varexp;
   
   ncols  = 1;
   for (i=0;i<nch;i++)  if (title[i] == ':' && ! ( (i>0&&title[i-1]==':') || title[i+1]==':' ) ) ncols++;
   Int_t *index;
   index = new Int_t[ncols+1];
   MakeIndex(title,index);
   InitArrays(ncols);
   fManager = new TTreeFormulaManager();
   if (fSelect) fManager->Add(fSelect);
   fTree->ResetBit(TTree::kForceRead);
   for(i=0; i<ncols;++i){
      fVar[i] = new TTreeFormula(Form("Var%i",i+1),GetNameByIndex(title,index,i),fTree);
      fVar[i]->SetQuickLoad(kTRUE);
      if(!fVar[i]->GetNdim()) { ClearFormula(); delete [] index; return kFALSE; }
      fManager->Add(fVar[i]);
   }
   fManager->Sync();
   if (fManager->GetMultiplicity()==-1) fTree->SetBit(TTree::kForceRead);
   if (fManager->GetMultiplicity()>=1) fMultiplicity = fManager->GetMultiplicity();
   fDimension    = ncols;
   if (ncols==1) {
      TClass *cl = fVar[0]->EvalClass();
      if (cl) {
         fObjEval = kTRUE;
      }
   }
   delete [] index;
   return kTRUE;
}
const char *TSelectorDraw::GetNameByIndex(TString &varexp, Int_t *index,Int_t colindex)
{
   
   
   
   
   Int_t i1,n;
   static TString column;
   if (colindex<0 ) return "";
   i1 = index[colindex] + 1;
   n  = index[colindex+1] - i1;
   column = varexp(i1,n);
   return column.Data();
}
Double_t* TSelectorDraw::GetVal(Int_t i) const
{
   
   if(i<0 || i >= fDimension)
      return 0;
   else
      return fVal[i];
}
TTreeFormula* TSelectorDraw::GetVar(Int_t i) const
{
   
   if(i<0 || i>=fDimension)
      return 0;
   else
      return fVar[i];
}
void TSelectorDraw::InitArrays(Int_t newsize)
{
   
   if(newsize>fValSize){
      Int_t oldsize = fValSize;
      while(fValSize<newsize)
         fValSize*=2;            
      if(fNbins) delete [] fNbins;
      if(fVmin) delete [] fVmin;
      if(fVmax) delete [] fVmax;
      if(fVarMultiple) delete [] fVarMultiple;
      fNbins = new Int_t[fValSize];
      fVmin = new Double_t[fValSize];
      fVmax = new Double_t[fValSize];
      fVarMultiple = new Bool_t[fValSize];
      for(Int_t i=0;i<oldsize;++i)
         delete [] fVal[i];
      delete [] fVal;
      delete [] fVar;
      fVal = new Double_t*[fValSize];
      fVar = new TTreeFormula*[fValSize];
      for(Int_t i=0;i<fValSize;++i){
         fVal[i] = 0;
         fVar[i] = 0;
      }
   }
}
void TSelectorDraw::MakeIndex(TString &varexp, Int_t *index)
{
   
   Int_t ivar = 1;
   index[0]  = -1;
   for (Int_t i=0;i<varexp.Length();i++) {
      if (varexp[i] == ':'
          && ! ( (i>0&&varexp[i-1]==':') || varexp[i+1]==':' )
          ) {
         index[ivar] = i;
         ivar++;
      }
   }
   index[ivar] = varexp.Length();
}
Bool_t TSelectorDraw::Notify()
{
   
   if (fTree) fWeight  = fTree->GetWeight();
   if(fVar){
      for(Int_t i=0;i<fDimension;++i){
         if(fVar[i]) fVar[i]->UpdateFormulaLeaves();
      }
   }
   if (fSelect) fSelect->UpdateFormulaLeaves();
   return kTRUE;
}
void TSelectorDraw::ProcessFill(Long64_t entry)
{
   
   if (fObjEval) {
      ProcessFillObject(entry);
      return;
   }
   if (fMultiplicity) {
      ProcessFillMultiple(entry);
      return;
   }
   
   if ( fForceRead && fManager->GetNdata() <= 0) return;
   if (fSelect) {
      fW[fNfill] = fWeight*fSelect->EvalInstance(0);
      if (!fW[fNfill]) return;
   } else fW[fNfill] = fWeight;
   if(fVal){
      for(Int_t i=0;i<fDimension;++i){
         if(fVar[i]) fVal[i][fNfill] = fVar[i]->EvalInstance(0);
      }
   }
   fNfill++;
   if (fNfill >= fTree->GetEstimate()) {
      TakeAction();
      fNfill = 0;
   }
}
void TSelectorDraw::ProcessFillMultiple(Long64_t )
{
   
   
   
   Int_t ndata = fManager->GetNdata();
   
   if (!ndata) return;
   Int_t nfill0 = fNfill;
   
   if (fSelect) {
      fW[fNfill] = fWeight*fSelect->EvalInstance(0);
      if (!fW[fNfill] && !fSelectMultiple) return;
   } else fW[fNfill] = fWeight;
   
   
   if (fW[fNfill]) {
      for(Int_t i=0;i<fDimension;++i){
         if(fVar[i]) fVal[i][fNfill] = fVar[i]->EvalInstance(0);
      }
      fNfill++;
      if (fNfill >= fTree->GetEstimate()) {
         TakeAction();
         fNfill = 0;
      }
   } else {
      for(Int_t i=0;i<fDimension;++i){
         if(fVar[i]) fVar[i]->ResetLoading();
      }
   }
   Double_t ww = fW[nfill0];
   for (Int_t i=1;i<ndata;i++) {
      if (fSelectMultiple) {
         ww = fWeight*fSelect->EvalInstance(i);
         if (ww == 0) continue;
         if (fNfill == nfill0) {
            for(Int_t k=0;k<fDimension;++k){
               if(!fVarMultiple[k]) fVal[k][fNfill] = fVar[k]->EvalInstance(0);
            }
         }
      }
      for(Int_t k=0;k<fDimension;++k){
         if(fVarMultiple[k]) fVal[k][fNfill] = fVar[k]->EvalInstance(i);
         else                fVal[k][fNfill] = fVal[k][nfill0];
      }
      fW[fNfill] = ww;
      fNfill++;
      if (fNfill >= fTree->GetEstimate()) {
         TakeAction();
         fNfill = 0;
      }
   }
}
void TSelectorDraw::ProcessFillObject(Long64_t )
{
   
   
   
   
   Int_t ndata = fManager->GetNdata();
   
   if (!ndata) return;
   Int_t nfill0 = fNfill;
   Double_t ww = 0;
   for (Int_t i=0;i<ndata;i++) {
      if (i==0) {
         if (fSelect) {
            fW[fNfill] = fWeight*fSelect->EvalInstance(0);
            if (!fW[fNfill] && !fSelectMultiple) return;
         } else fW[fNfill] = fWeight;
         ww = fW[nfill0];
      } else if (fSelectMultiple) {
         ww = fWeight*fSelect->EvalInstance(i);
         if (ww == 0) continue;
      }
      if (fDimension >= 1 && fVar[0]) {
         TClass *cl = fVar[0]->EvalClass();
         if (cl==TBits::Class()) {
            void *obj = fVar[0]->EvalObject(i);
            TBits *bits = (TBits*)obj;
            Int_t nbits = bits->GetNbits();
            Int_t nextbit = -1;
            while(1) {
               nextbit = bits->FirstSetBit(nextbit+1);
               if (nextbit >= nbits) break;
               fVal[0][fNfill] = nextbit;
               fW[fNfill] =  ww;
               fNfill++;
            }
         } else {
            if (!TestBit(kWarn)) {
               Warning("ProcessFillObject",
                       "Not implemented for %s",
                       cl?cl->GetName():"unknown class");
               SetBit(kWarn);
            }
         }
      }
      if (fNfill >= fTree->GetEstimate()) {
         TakeAction();
         fNfill = 0;
      }
   }
}
void TSelectorDraw::SetEstimate(Long64_t)
{
   
   if(fVal){
      for(Int_t i=0;i<fValSize;++i){
         delete [] fVal[i];
         fVal[i] = 0;
      }
   }
   delete [] fW;   fW  = 0;
}
void TSelectorDraw::TakeAction()
{
   
   Int_t i;
   
   if      (fAction ==  1) ((TH1*)fObject)->FillN(fNfill,fVal[0],fW);
   
   else if (fAction ==  2) {
      TH2 *h2 = (TH2*)fObject;
      for(i=0;i<fNfill;i++) h2->Fill(fVal[1][i],fVal[0][i],fW[i]);
   }
   
   else if (fAction ==  4) ((TProfile*)fObject)->FillN(fNfill,fVal[1],fVal[0],fW);
   
   else if (fAction ==  5) {
      if (fObject->InheritsFrom("TEntryList")){
         TEntryList *enlist = (TEntryList*)fObject;
         Long64_t enumb = fTree->GetTree()->GetReadEntry();
         enlist->Enter(enumb);
      }
      else {
         TEventList *evlist = (TEventList*)fObject;
         Long64_t enumb = fTree->GetChainOffset() + fTree->GetTree()->GetReadEntry();
         if (evlist->GetIndex(enumb) < 0) evlist->Enter(enumb);
      }
   }
   
   else if (fAction == 12) {
      TH2 *h2 = (TH2*)fObject;
      if (h2->TestBit(TH1::kCanRebin) && h2->TestBit(kCanDelete)) {
         for (i=0;i<fNfill;i++) {
            if (fVmin[0] > fVal[0][i]) fVmin[0] = fVal[0][i];
            if (fVmax[0] < fVal[0][i]) fVmax[0] = fVal[0][i];
            if (fVmin[1] > fVal[1][i]) fVmin[1] = fVal[1][i];
            if (fVmax[1] < fVal[1][i]) fVmax[1] = fVal[1][i];
         }
         THLimitsFinder::GetLimitsFinder()->FindGoodLimits(h2,fVmin[1],fVmax[1],fVmin[0],fVmax[0]);
      }
      TGraph *pm = new TGraph(fNfill,fVal[1],fVal[0]);
      pm->SetEditable(kFALSE);
      pm->SetBit(kCanDelete);
      pm->SetMarkerStyle(fTree->GetMarkerStyle());
      pm->SetMarkerColor(fTree->GetMarkerColor());
      pm->SetMarkerSize(fTree->GetMarkerSize());
      pm->SetLineColor(fTree->GetLineColor());
      pm->SetLineStyle(fTree->GetLineStyle());
      pm->SetFillColor(fTree->GetFillColor());
      pm->SetFillStyle(fTree->GetFillStyle());
      if (!fDraw && !strstr(fOption.Data(),"goff")) {
         if (fOption.Length() == 0 || fOption == "same")  pm->Draw("p");
         else                                             pm->Draw(fOption.Data());
      }
      if (!h2->TestBit(kCanDelete)) {
         for (i=0;i<fNfill;i++) h2->Fill(fVal[1][i],fVal[0][i],fW[i]);
      }
   }
   
   else if (fAction ==  3) {
      TH3 *h3 =(TH3*)fObject;
      for(i=0;i<fNfill;i++) h3->Fill(fVal[2][i],fVal[1][i],fVal[0][i],fW[i]);
   }
   else if (fAction == 13) {
      TPolyMarker3D *pm3d = new TPolyMarker3D(fNfill);
      pm3d->SetMarkerStyle(fTree->GetMarkerStyle());
      pm3d->SetMarkerColor(fTree->GetMarkerColor());
      pm3d->SetMarkerSize(fTree->GetMarkerSize());
      for (i=0;i<fNfill;i++) { pm3d->SetPoint(i,fVal[2][i],fVal[1][i],fVal[0][i]);}
      pm3d->Draw();
      TH3 *h3 =(TH3*)fObject;
      for(i=0;i<fNfill;i++) h3->Fill(fVal[2][i],fVal[1][i],fVal[0][i],fW[i]);
   }
   
   else if (fAction == 33) {
      TH2 *h2 = (TH2*)fObject;
      TakeEstimate();
      Int_t ncolors  = gStyle->GetNumberOfColors();
      TObjArray *grs = (TObjArray*)h2->GetListOfFunctions()->FindObject("graphs");
      Int_t col;
      TGraph *gr;
      if (!grs) {
         grs = new TObjArray(ncolors);
         grs->SetOwner();
         grs->SetName("graphs");
         h2->GetListOfFunctions()->Add(grs, "P");
         for (col=0;col<ncolors;col++) {
            gr = new TGraph();
            gr->SetMarkerColor(gStyle->GetColorPalette(col));
            gr->SetMarkerStyle(fTree->GetMarkerStyle());
            gr->SetMarkerSize(fTree->GetMarkerSize());
            grs->AddAt(gr,col);
         }
      }
      h2->SetEntries(fNfill);
      h2->SetMinimum(fVmin[2]);
      h2->SetMaximum(fVmax[2]);
      
      for (i=0;i<fNfill;i++) {
         col = Int_t(ncolors*((fVal[2][i]-fVmin[2])/(fVmax[2]-fVmin[2])));
         if (col < 0) col = 0;
         if (col > ncolors-1) col = ncolors-1;
         gr = (TGraph*)grs->UncheckedAt(col);
         if (gr) gr->SetPoint(gr->GetN(),fVal[1][i],fVal[0][i]);
      }
      
      for (col=0;col<ncolors;col++) {
         gr = (TGraph*)grs->At(col);
         if (gr && gr->GetN() <= 0) grs->Remove(gr);
      }
   }
   
   else if (fAction == 23) {
      TProfile2D *hp2 =(TProfile2D*)fObject;
      for(i=0;i<fNfill;i++) hp2->Fill(fVal[2][i],fVal[1][i],fVal[0][i],fW[i]);
   }
   
   else if (fAction ==  40) {
      TakeEstimate();
      TH3 *h3 =(TH3*)fObject;
      Int_t ncolors  = gStyle->GetNumberOfColors();
      TObjArray *pms = (TObjArray*)h3->GetListOfFunctions()->FindObject("polymarkers");
      Int_t col;
      TPolyMarker3D *pm3d;
      if (!pms) {
         pms = new TObjArray(ncolors);
         pms->SetOwner();
         pms->SetName("polymarkers");
         h3->GetListOfFunctions()->Add(pms);
         for (col=0;col<ncolors;col++) {
            pm3d = new TPolyMarker3D();
            pm3d->SetMarkerColor(gStyle->GetColorPalette(col));
            pm3d->SetMarkerStyle(fTree->GetMarkerStyle());
            pm3d->SetMarkerSize(fTree->GetMarkerSize());
            pms->AddAt(pm3d,col);
         }
      }
      h3->SetEntries(fNfill);
      h3->SetMinimum(fVmin[3]);
      h3->SetMaximum(fVmax[3]);
      for (i=0;i<fNfill;i++) {
         col = Int_t(ncolors*((fVal[3][i]-fVmin[3])/(fVmax[3]-fVmin[3])));
         if (col < 0) col = 0;
         if (col > ncolors-1) col = ncolors-1;
         pm3d = (TPolyMarker3D*)pms->UncheckedAt(col);
         pm3d->SetPoint(pm3d->GetLastPoint()+1,fVal[2][i],fVal[1][i],fVal[0][i]);
      }
   }
   
   else if (fAction == 6 || fAction == 7){
   TakeEstimate();
   Bool_t candle = (fAction==7);
   
   if (!fOption.Contains("goff"))
      gROOT->ProcessLineFast(Form("TParallelCoord::BuildParallelCoord((TSelectorDraw*)0x%lx,0x%lx",
                                  this, candle));
   }
   
   else if (fAction < 0) {
      fAction = -fAction;
      TakeEstimate();
   }
   
   fSelectedRows += fNfill;
   if (!fTree->GetUpdate()) return;
   if (fSelectedRows > fDraw+fTree->GetUpdate()) {
      if (fDraw) gPad->Modified();
      else       fObject->Draw(fOption.Data());
      gPad->Update();
      fDraw = fSelectedRows;
   }
}
void TSelectorDraw::TakeEstimate()
{
   
   Int_t i;
   Double_t rmin[3],rmax[3];
   Double_t vminOld[4], vmaxOld[4];
   for (i = 0; i < fValSize && i < 4; i++) {
      vminOld[i] = fVmin[i];
      vmaxOld[i] = fVmax[i];
   }
   for(i=0;i<fValSize;++i){
      fVmin[i] = FLT_MAX;
      fVmax[i] = - FLT_MAX;
   }
   
   if      (fAction ==  1) {
      TH1 *h1 = (TH1*)fObject;
      if (fObject->TestBit(TH1::kCanRebin)) {
         for (i=0;i<fNfill;i++) {
            if (fVmin[0] > fVal[0][i]) fVmin[0] = fVal[0][i];
            if (fVmax[0] < fVal[0][i]) fVmax[0] = fVal[0][i];
         }
         THLimitsFinder::GetLimitsFinder()->FindGoodLimits(h1,fVmin[0],fVmax[0]);
      }
      h1->FillN(fNfill, fVal[0], fW);
   
   } else if (fAction ==  2) {
      TH2 *h2 = (TH2*)fObject;
      if (fObject->TestBit(TH1::kCanRebin)) {
         for (i=0;i<fNfill;i++) {
            if (fVmin[0] > fVal[0][i]) fVmin[0] = fVal[0][i];
            if (fVmax[0] < fVal[0][i]) fVmax[0] = fVal[0][i];
            if (fVmin[1] > fVal[1][i]) fVmin[1] = fVal[1][i];
            if (fVmax[1] < fVal[1][i]) fVmax[1] = fVal[1][i];
         }
         THLimitsFinder::GetLimitsFinder()->FindGoodLimits(h2,fVmin[1],fVmax[1],fVmin[0],fVmax[0]);
      }
      for(i=0;i<fNfill;i++) h2->Fill(fVal[1][i],fVal[0][i],fW[i]);
   
   } else if (fAction ==  4) {
      TProfile *hp = (TProfile*)fObject;
      if (fObject->TestBit(TH1::kCanRebin)) {
         for (i=0;i<fNfill;i++) {
            if (fVmin[0] > fVal[0][i]) fVmin[0] = fVal[0][i];
            if (fVmax[0] < fVal[0][i]) fVmax[0] = fVal[0][i];
            if (fVmin[1] > fVal[1][i]) fVmin[1] = fVal[1][i];
            if (fVmax[1] < fVal[1][i]) fVmax[1] = fVal[1][i];
         }
         THLimitsFinder::GetLimitsFinder()->FindGoodLimits(hp,fVmin[1],fVmax[1]);
      }
      hp->FillN(fNfill, fVal[1], fVal[0], fW);
   
   } else if (fAction == 12) {
      TH2 *h2 = (TH2*)fObject;
      if (h2->TestBit(TH1::kCanRebin)) {
         for (i=0;i<fNfill;i++) {
            if (fVmin[0] > fVal[0][i]) fVmin[0] = fVal[0][i];
            if (fVmax[0] < fVal[0][i]) fVmax[0] = fVal[0][i];
            if (fVmin[1] > fVal[1][i]) fVmin[1] = fVal[1][i];
            if (fVmax[1] < fVal[1][i]) fVmax[1] = fVal[1][i];
         }
         THLimitsFinder::GetLimitsFinder()->FindGoodLimits(h2,fVmin[1],fVmax[1],fVmin[0],fVmax[0]);
      }
      if (!strstr(fOption.Data(),"same") && !strstr(fOption.Data(),"goff")) {
         if (!h2->TestBit(kCanDelete)) {
            
            
            
            
            TH1 *h2c = h2->DrawCopy(fOption.Data());
            h2c->SetStats(kFALSE);
         } else {
            
            
            
            h2->Draw();
         }
         gPad->Update();
      }
      TGraph *pm = new TGraph(fNfill,fVal[1],fVal[0]);
      pm->SetEditable(kFALSE);
      pm->SetBit(kCanDelete);
      pm->SetMarkerStyle(fTree->GetMarkerStyle());
      pm->SetMarkerColor(fTree->GetMarkerColor());
      pm->SetMarkerSize(fTree->GetMarkerSize());
      pm->SetLineColor(fTree->GetLineColor());
      pm->SetLineStyle(fTree->GetLineStyle());
      pm->SetFillColor(fTree->GetFillColor());
      pm->SetFillStyle(fTree->GetFillStyle());
      if (!fDraw && !strstr(fOption.Data(),"goff")) {
         if (fOption.Length() == 0 || fOption == "same")  pm->Draw("p");
         else                                             pm->Draw(fOption.Data());
      }
      if (!h2->TestBit(kCanDelete)) {
         for (i=0;i<fNfill;i++) h2->Fill(fVal[1][i],fVal[0][i],fW[i]);
      }
   
   } else if (fAction == 33) {
      TH2 *h2 = (TH2*)fObject;
      Bool_t process2 = kFALSE;
      if (h2->TestBit(TH1::kCanRebin)) {
         if (vminOld[2] == FLT_MAX)
            process2 = kTRUE;
         for (i = 0; i < fValSize && i < 4; i++) {
            fVmin[i] = vminOld[i];
            fVmax[i] = vmaxOld[i];
         }
         for (i=0;i<fNfill;i++) {
            if (fVmin[0] > fVal[0][i]) fVmin[0] = fVal[0][i];
            if (fVmax[0] < fVal[0][i]) fVmax[0] = fVal[0][i];
            if (fVmin[1] > fVal[1][i]) fVmin[1] = fVal[1][i];
            if (fVmax[1] < fVal[1][i]) fVmax[1] = fVal[1][i];
            if (process2) {
               if (fVmin[2] > fVal[2][i]) fVmin[2] = fVal[2][i];
               if (fVmax[2] < fVal[2][i]) fVmax[2] = fVal[2][i];
            }
         }
         THLimitsFinder::GetLimitsFinder()->FindGoodLimits(h2,fVmin[1],fVmax[1],fVmin[0],fVmax[0]);
      }
   
   } else if (fAction == 3 || fAction == 13) {
      TH3 *h3 = (TH3*)fObject;
      if (fObject->TestBit(TH1::kCanRebin)) {
         for (i=0;i<fNfill;i++) {
            if (fVmin[0] > fVal[0][i]) fVmin[0] = fVal[0][i];
            if (fVmax[0] < fVal[0][i]) fVmax[0] = fVal[0][i];
            if (fVmin[1] > fVal[1][i]) fVmin[1] = fVal[1][i];
            if (fVmax[1] < fVal[1][i]) fVmax[1] = fVal[1][i];
            if (fVmin[2] > fVal[2][i]) fVmin[2] = fVal[2][i];
            if (fVmax[2] < fVal[2][i]) fVmax[2] = fVal[2][i];
         }
         THLimitsFinder::GetLimitsFinder()->FindGoodLimits(h3,fVmin[2],fVmax[2],fVmin[1],fVmax[1],fVmin[0],fVmax[0]);
      }
      if (fAction == 3) {
         for (i=0;i<fNfill;i++) h3->Fill(fVal[2][i],fVal[1][i],fVal[0][i],fW[i]);
         return;
      }
      if (!strstr(fOption.Data(),"same") && !strstr(fOption.Data(),"goff")) {
         if (!h3->TestBit(kCanDelete)) {
            
            
            
            
            TH1 *h3c = h3->DrawCopy(fOption.Data());
            h3c->SetStats(kFALSE);
         } else {
            
            
            
            h3->Draw(fOption.Data());
         }
         gPad->Update();
      } else {
         rmin[0] = fVmin[2]; rmin[1] = fVmin[1]; rmin[2] = fVmin[0];
         rmax[0] = fVmax[2]; rmax[1] = fVmax[1]; rmax[2] = fVmax[0];
         gPad->Clear();
         gPad->Range(-1,-1,1,1);
         TView::CreateView(1, rmin,rmax);
      }
      TPolyMarker3D *pm3d = new TPolyMarker3D(fNfill);
      pm3d->SetMarkerStyle(fTree->GetMarkerStyle());
      pm3d->SetMarkerColor(fTree->GetMarkerColor());
      pm3d->SetMarkerSize(fTree->GetMarkerSize());
      for (i=0;i<fNfill;i++) { pm3d->SetPoint(i,fVal[2][i],fVal[1][i],fVal[0][i]);}
      if (!fDraw && !strstr(fOption.Data(),"goff")) pm3d->Draw();
      if (!h3->TestBit(kCanDelete)) {
         for (i=0;i<fNfill;i++) h3->Fill(fVal[2][i],fVal[1][i],fVal[0][i],fW[i]);
      }
   
   } else if (fAction == 23) {
      TProfile2D *hp = (TProfile2D*)fObject;
      if (hp->TestBit(TH1::kCanRebin)) {
         for (i=0;i<fNfill;i++) {
            if (fVmin[0] > fVal[0][i]) fVmin[0] = fVal[0][i];
            if (fVmax[0] < fVal[0][i]) fVmax[0] = fVal[0][i];
            if (fVmin[1] > fVal[1][i]) fVmin[1] = fVal[1][i];
            if (fVmax[1] < fVal[1][i]) fVmax[1] = fVal[1][i];
            if (fVmin[2] > fVal[2][i]) fVmin[2] = fVal[2][i];
            if (fVmax[2] < fVal[2][i]) fVmax[2] = fVal[2][i];
         }
         THLimitsFinder::GetLimitsFinder()->FindGoodLimits(hp,fVmin[2],fVmax[2],fVmin[1],fVmax[1]);
      }
      for (i=0;i<fNfill;i++) hp->Fill(fVal[2][i],fVal[1][i],fVal[0][i],fW[i]);
   
   } else if (fAction == 40) {
      TH3 *h3 = (TH3*)fObject;
      if (fObject->TestBit(TH1::kCanRebin)) {
         for (i = 0; i < fValSize && i < 4; i++) {
            fVmin[i] = vminOld[i];
            fVmax[i] = vmaxOld[i];
         }
         for (i=0;i<fNfill;i++) {
            if (fVmin[0] > fVal[0][i]) fVmin[0] = fVal[0][i];
            if (fVmax[0] < fVal[0][i]) fVmax[0] = fVal[0][i];
            if (fVmin[1] > fVal[1][i]) fVmin[1] = fVal[1][i];
            if (fVmax[1] < fVal[1][i]) fVmax[1] = fVal[1][i];
            if (fVmin[2] > fVal[2][i]) fVmin[2] = fVal[2][i];
            if (fVmax[2] < fVal[2][i]) fVmax[2] = fVal[2][i];
            if (fVmin[3] > fVal[3][i]) fVmin[3] = fVal[3][i];
            if (fVmax[3] < fVal[3][i]) fVmax[3] = fVal[3][i];
         }
         THLimitsFinder::GetLimitsFinder()->FindGoodLimits(h3,fVmin[2],fVmax[2],fVmin[1],fVmax[1],fVmin[0],fVmax[0]);
      }
   }
   
   else if (fAction == 6 || fAction == 7){
      for(i=0;i<fDimension;++i){
         for (Long64_t entry=0;entry<fNfill;entry++){
            if (fVmin[i] > fVal[i][entry]) fVmin[i] = fVal[i][entry];
            if (fVmax[i] < fVal[i][entry]) fVmax[i] = fVal[i][entry];
         }
      }
   }
}
void TSelectorDraw::Terminate()
{
   
   if (fNfill) TakeAction();
   if ((fSelectedRows == 0) && (TestBit(kCustomHistogram) == 0)) fDraw = 1; 
   SetStatus(fSelectedRows);
}
Last update: Thu Jan 17 09:03:15 2008
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.