#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;
Bool_t opt5d = 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","");
}
if (opt.Contains("gl5d")) {
opt5d = kTRUE;
opt.ReplaceAll("gl5d","");
}
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 || opt5d)) {
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 || opt5d) {
if (optcandle) fAction = 7;
else if (opt5d) fAction = 8;
else fAction = 6;
}
if (hkeep) delete [] varexp;
if (hnamealloc) delete [] hnamealloc;
for(i=0;i<fValSize;++i)
fVarMultiple[i] = kFALSE;
fSelectMultiple = kFALSE;
for(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(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(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 == 8) {
}
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);
}