39 ClassImp(TSelectorDraw);
41 const Int_t kCustomHistogram = BIT(17);
46 TSelectorDraw::TSelectorDraw()
51 fVal =
new Double_t*[fValSize];
52 fVmin =
new Double_t[fValSize];
53 fVmax =
new Double_t[fValSize];
54 fNbins =
new Int_t[fValSize];
55 fVarMultiple =
new Bool_t[fValSize];
56 fVar =
new TTreeFormula*[fValSize];
57 for (Int_t i = 0; i < fValSize; ++i) {
69 fSelectMultiple = kFALSE;
78 fCurrentSubEntry = -1;
85 TSelectorDraw::~TSelectorDraw()
90 for (Int_t i = 0; i < fValSize; ++i)
94 if (fVmin)
delete [] fVmin;
95 if (fVmax)
delete [] fVmax;
96 if (fNbins)
delete [] fNbins;
97 if (fVarMultiple)
delete [] fVarMultiple;
104 void TSelectorDraw::Begin(TTree *tree)
108 ResetBit(kCustomHistogram);
114 TObject *obj = fInput->FindObject(
"varexp");
115 const char *varexp0 = obj ? obj->GetTitle() :
"";
116 obj = fInput->FindObject(
"selection");
117 const char *selection = obj ? obj->GetTitle() :
"";
118 const char *option = GetOption();
121 char *hdefault = (
char *)
"htemp";
122 char *varexp =
nullptr;
127 TEntryList *enlist = 0;
128 TEventList *evlist = 0;
130 Bool_t profile = kFALSE;
131 Bool_t optSame = kFALSE;
132 Bool_t optEnlist = kFALSE;
133 Bool_t optEnlistArray = kFALSE;
134 Bool_t optpara = kFALSE;
135 Bool_t optcandle = kFALSE;
136 Bool_t opt5d = kFALSE;
137 if (opt.Contains(
"same")) {
139 opt.ReplaceAll(
"same",
"");
141 if (opt.Contains(
"entrylist")) {
143 if (opt.Contains(
"entrylistarray")) {
144 optEnlistArray = kTRUE;
145 opt.ReplaceAll(
"entrylistarray",
"");
147 opt.ReplaceAll(
"entrylist",
"");
150 if (opt.Contains(
"para")) {
152 opt.ReplaceAll(
"para",
"");
154 if (opt.Contains(
"candle")) {
156 opt.ReplaceAll(
"candle",
"");
158 if (opt.Contains(
"gl5d")) {
160 opt.ReplaceAll(
"gl5d",
"");
162 TCut realSelection(selection);
164 TEntryList *inElist = fTree->GetEntryList();
165 evlist = fTree->GetEventList();
166 if (evlist && inElist) {
172 inElist->SetBit(kCanDelete, kTRUE);
174 fCleanElist = kFALSE;
175 fTreeElist = inElist;
177 fTreeElistArray = inElist ?
dynamic_cast<TEntryListArray*
>(fTreeElist) : 0;
180 if (inElist && inElist->GetReapplyCut()) {
181 realSelection *= inElist->GetTitle();
194 Bool_t canExtend = kTRUE;
195 if (optSame) canExtend = kFALSE;
197 Int_t nbinsx = 0, nbinsy = 0, nbinsz = 0;
198 Double_t xmin = 0, xmax = 0, ymin = 0, ymax = 0, zmin = 0, zmax = 0;
202 char *hnamealloc = 0;
204 if (varexp0 && strlen(varexp0)) {
205 for (UInt_t k = strlen(varexp0) - 1; k > 0; k--) {
206 if (varexp0[k] ==
'>' && varexp0[k-1] ==
'>') {
207 i = (int)(&(varexp0[k-1]) - varexp0);
208 hnamealloc =
new char[strlen(&(varexp0[k+1])) + 1];
210 strcpy(hname, &(varexp0[k+1]));
218 varexp =
new char[i+1];
220 Bool_t hnameplus = kFALSE;
221 while (*hname ==
' ') hname++;
225 while (*hname ==
' ') hname++;
227 j = strlen(hname) - 1;
229 if (hname[j] !=
' ')
break;
235 strlcpy(varexp,varexp0,i+1);
237 Int_t mustdelete = 0;
238 SetBit(kCustomHistogram);
254 const Int_t maxvalues = 9;
256 pstart = strchr(hname,
'(');
257 pend = strchr(hname,
')');
263 if (pstart == strrchr(hname,
'(') && pend == strrchr(hname,
')')) {
268 cdummy = strchr(&cdummy[1],
',');
269 while (cdummy != 0) {
270 cdummy = strchr(&cdummy[1],
',');
274 if (ncomma + 1 > maxvalues) {
275 Error(
"DrawSelect",
"ncomma+1>maxvalues, ncomma=%d, maxvalues=%d", ncomma, maxvalues);
276 ncomma = maxvalues - 1;
284 for (j = 0; j < i; j++) {
286 && !((j > 0 && varexp[j-1] ==
':') || varexp[j+1] ==
':')
292 Error(
"DrawSelect",
"ncols > 3, ncols=%d", ncols);
297 if (ncols * 3 < ncomma) {
298 Error(
"DrawSelect",
"ncols*3 < ncomma ncols=%d, ncomma=%d", ncols, ncomma);
303 for (j = 0; j < ncomma; j++) {
305 if (sscanf(cdummy,
" %lf ", &value) == 1) {
306 cdummy = strchr(&cdummy[1],
',');
310 nbinsx = (Int_t)value;
312 gEnv->SetValue(
"Hist.Binning.1D.x", nbinsx);
313 }
else if (ncols < 3) {
314 gEnv->SetValue(
"Hist.Binning.2D.x", nbinsx);
315 gEnv->SetValue(
"Hist.Binning.2D.Prof", nbinsx);
317 gEnv->SetValue(
"Hist.Binning.3D.x", nbinsx);
318 gEnv->SetValue(
"Hist.Binning.3D.Profx", nbinsx);
329 nbinsy = (Int_t)value;
330 if (ncols < 3) gEnv->SetValue(
"Hist.Binning.2D.y", nbinsy);
332 gEnv->SetValue(
"Hist.Binning.3D.y", nbinsy);
333 gEnv->SetValue(
"Hist.Binning.3D.Profy", nbinsy);
343 nbinsz = (Int_t)value;
344 gEnv->SetValue(
"Hist.Binning.3D.z", nbinsz);
353 Error(
"DrawSelect",
"j>8");
359 Error(
"Begin",
"Two open or close brackets found, hname=%s", hname);
366 j = strlen(hname) - 1;
368 if (hname[j] !=
' ')
break;
373 TObject *oldObject = gDirectory->Get(hname);
374 fOldHistogram = oldObject ?
dynamic_cast<TH1*
>(oldObject) : 0;
376 if (!fOldHistogram && oldObject && !oldObject->InheritsFrom(TH1::Class())) {
377 abrt.Form(
"An object of type '%s' has the same name as the requested histo (%s)", oldObject->IsA()->GetName(), hname);
382 if (fOldHistogram && !hnameplus) fOldHistogram->Reset();
386 Warning(
"Begin",
"Deleting old histogram, since (possibly new) limits and binnings have been given");
388 delete fOldHistogram; fOldHistogram=0;
393 TObject *oldObject = gDirectory->Get(hname);
396 enlist = oldObject ?
dynamic_cast<TEntryList*
>(oldObject) : 0;
398 if (!enlist && oldObject) {
399 abrt.Form(
"An object of type '%s' has the same name as the requested event list (%s)",
400 oldObject->IsA()->GetName(), hname);
406 if (optEnlistArray) {
407 enlist =
new TEntryListArray(hname, realSelection.GetTitle());
409 enlist =
new TEntryList(hname, realSelection.GetTitle());
414 if (enlist == inElist) {
417 if (optEnlistArray) {
418 inElist =
new TEntryListArray(*enlist);
420 inElist =
new TEntryList(*enlist);
423 fTree->SetEntryList(inElist);
426 enlist->SetTitle(realSelection.GetTitle());
428 TCut old = enlist->GetTitle();
429 TCut upd = old || realSelection.GetTitle();
430 enlist->SetTitle(upd.GetTitle());
435 evlist = oldObject ?
dynamic_cast<TEventList*
>(oldObject) : 0;
437 if (!evlist && oldObject) {
438 abrt.Form(
"An object of type '%s' has the same name as the requested event list (%s)",
439 oldObject->IsA()->GetName(), hname);
444 evlist =
new TEventList(hname, realSelection.GetTitle(), 1000, 0);
448 if (evlist == fTree->GetEventList()) {
451 Abort(
"Input and output lists are the same!");
456 evlist->SetTitle(realSelection.GetTitle());
458 TCut old = evlist->GetTitle();
459 TCut upd = old || realSelection.GetTitle();
460 evlist->SetTitle(upd.GetTitle());
469 const size_t varexpLen = strlen(varexp0) + 1;
470 varexp =
new char[varexpLen];
471 strlcpy(varexp, varexp0, varexpLen);
473 fOldHistogram = (TH1*)gDirectory->Get(hname);
474 if (fOldHistogram) { fOldHistogram->Delete(); fOldHistogram = 0;}
479 if (!CompileVariables(varexp, realSelection.GetTitle())) {
480 abrt.Form(
"Variable compilation failed: {%s,%s}", varexp, realSelection.GetTitle());
485 if (fDimension > 4 && !(optpara || optcandle || opt5d || opt.Contains(
"goff"))) {
486 Abort(
"Too many variables. Use the option \"para\", \"gl5d\" or \"candle\" to display more than 4 variables.");
490 if (fDimension < 2 && (optpara || optcandle)) {
491 Abort(
"The options \"para\" and \"candle\" require at least 2 variables.");
497 Int_t nsel = strlen(selection);
499 htitle.Form(
"%s {%s}", varexp, selection);
504 Int_t olddim = fOldHistogram->GetDimension();
505 Int_t mustdelete = 0;
506 if (fOldHistogram->InheritsFrom(TProfile::Class())) {
510 if (fOldHistogram->InheritsFrom(TProfile2D::Class())) {
514 if (opt.Contains(
"prof") && fDimension > 1) {
516 if (!profile || olddim != fDimension) mustdelete = 1;
517 }
else if (opt.Contains(
"col") && fDimension>2) {
518 if (olddim+1 != fDimension) mustdelete = 1;
520 if (olddim != fDimension) mustdelete = 1;
523 Warning(
"Begin",
"Deleting old histogram with different dimensions");
524 delete fOldHistogram;
531 if (!gPad && !opt.Contains(
"goff") && fDimension > 0) {
532 gROOT->MakeDefCanvas();
534 Abort(
"Creation of default canvas failed");
542 if (fDimension == 1) {
544 if (!fOldHistogram) {
545 fNbins[0] = gEnv->GetValue(
"Hist.Binning.1D.x", 100);
546 if (gPad && optSame) {
547 TListIter np(gPad->GetListOfPrimitives());
550 while ((op = np()) && !oldhtemp) {
551 if (op->InheritsFrom(TH1::Class())) oldhtemp = (TH1 *)op;
554 fNbins[0] = oldhtemp->GetXaxis()->GetNbins();
555 fVmin[0] = oldhtemp->GetXaxis()->GetXmin();
556 fVmax[0] = oldhtemp->GetXaxis()->GetXmax();
558 fVmin[0] = gPad->GetUxmin();
559 fVmax[0] = gPad->GetUxmax();
565 if (xmin < xmax) canExtend = kFALSE;
569 hist = fOldHistogram;
570 fNbins[0] = hist->GetXaxis()->GetNbins();
572 TString precision = gEnv->GetValue(
"Hist.Precision.1D",
"float");
573 if (precision.Contains(
"float")) {
574 hist =
new TH1F(hname, htitle.Data(), fNbins[0], fVmin[0], fVmax[0]);
576 hist =
new TH1D(hname, htitle.Data(), fNbins[0], fVmin[0], fVmax[0]);
578 hist->SetLineColor(fTree->GetLineColor());
579 hist->SetLineWidth(fTree->GetLineWidth());
580 hist->SetLineStyle(fTree->GetLineStyle());
581 hist->SetFillColor(fTree->GetFillColor());
582 hist->SetFillStyle(fTree->GetFillStyle());
583 hist->SetMarkerStyle(fTree->GetMarkerStyle());
584 hist->SetMarkerColor(fTree->GetMarkerColor());
585 hist->SetMarkerSize(fTree->GetMarkerSize());
586 if (canExtend) hist->SetCanExtend(TH1::kAllAxes);
588 hist->GetXaxis()->SetTitle(fVar[0]->GetTitle());
589 hist->SetBit(kCanDelete);
590 if (!opt.Contains(
"goff")) hist->SetDirectory(0);
592 if (opt.Length() && opt.Contains(
"e")) hist->Sumw2();
594 fVar[0]->SetAxis(hist->GetXaxis());
598 }
else if (fDimension == 2 && !(optpara || optcandle)) {
600 if (!fOldHistogram || !optSame) {
601 fNbins[0] = gEnv->GetValue(
"Hist.Binning.2D.y", 40);
602 fNbins[1] = gEnv->GetValue(
"Hist.Binning.2D.x", 40);
603 if (opt.Contains(
"prof")) fNbins[1] = gEnv->GetValue(
"Hist.Binning.2D.Prof", 100);
605 TH1 *oldhtemp = (TH1*)gPad->FindObject(hdefault);
607 fNbins[1] = oldhtemp->GetXaxis()->GetNbins();
608 fVmin[1] = oldhtemp->GetXaxis()->GetXmin();
609 fVmax[1] = oldhtemp->GetXaxis()->GetXmax();
610 fNbins[0] = oldhtemp->GetYaxis()->GetNbins();
611 fVmin[0] = oldhtemp->GetYaxis()->GetXmin();
612 fVmax[0] = oldhtemp->GetYaxis()->GetXmax();
614 fNbins[1] = gEnv->GetValue(
"Hist.Binning.2D.x", 40);
615 fVmin[1] = gPad->GetUxmin();
616 fVmax[1] = gPad->GetUxmax();
617 fNbins[0] = gEnv->GetValue(
"Hist.Binning.2D.y", 40);
618 fVmin[0] = gPad->GetUymin();
619 fVmax[0] = gPad->GetUymax();
622 if (!fOldHistogram) fAction = -2;
627 if (xmin < xmax && ymin < ymax) canExtend = kFALSE;
630 if (profile || opt.Contains(
"prof")) {
634 hp = (TProfile*)fOldHistogram;
640 if (xmin < xmax) canExtend = kFALSE;
645 TH1 *oldhtemp = (TH1*)gPad->FindObject(hdefault);
647 fNbins[1] = oldhtemp->GetXaxis()->GetNbins();
648 fVmin[1] = oldhtemp->GetXaxis()->GetXmin();
649 fVmax[1] = oldhtemp->GetXaxis()->GetXmax();
652 if (opt.Contains(
"profs")) {
653 hp =
new TProfile(hname, htitle.Data(), fNbins[1], fVmin[1], fVmax[1],
"s");
654 }
else if (opt.Contains(
"profi")) {
655 hp =
new TProfile(hname, htitle.Data(), fNbins[1], fVmin[1], fVmax[1],
"i");
656 }
else if (opt.Contains(
"profg")) {
657 hp =
new TProfile(hname, htitle.Data(), fNbins[1], fVmin[1], fVmax[1],
"g");
659 hp =
new TProfile(hname, htitle.Data(), fNbins[1], fVmin[1], fVmax[1],
"");
662 hp->SetBit(kCanDelete);
663 if (!opt.Contains(
"goff")) hp->SetDirectory(0);
665 hp->SetLineColor(fTree->GetLineColor());
666 hp->SetLineWidth(fTree->GetLineWidth());
667 hp->SetLineStyle(fTree->GetLineStyle());
668 hp->SetFillColor(fTree->GetFillColor());
669 hp->SetFillStyle(fTree->GetFillStyle());
670 hp->SetMarkerStyle(fTree->GetMarkerStyle());
671 hp->SetMarkerColor(fTree->GetMarkerColor());
672 hp->SetMarkerSize(fTree->GetMarkerSize());
673 if (canExtend) hp->SetCanExtend(TH1::kAllAxes);
675 fVar[1]->SetAxis(hp->GetXaxis());
681 h2 = (TH2F*)fOldHistogram;
683 TString precision = gEnv->GetValue(
"Hist.Precision.2D",
"float");
684 if (precision.Contains(
"float")) {
685 h2 =
new TH2F(hname, htitle.Data(), fNbins[1], fVmin[1], fVmax[1], fNbins[0], fVmin[0], fVmax[0]);
687 h2 =
new TH2D(hname, htitle.Data(), fNbins[1], fVmin[1], fVmax[1], fNbins[0], fVmin[0], fVmax[0]);
689 h2->SetLineColor(fTree->GetLineColor());
690 h2->SetLineWidth(fTree->GetLineWidth());
691 h2->SetLineStyle(fTree->GetLineStyle());
692 h2->SetFillColor(fTree->GetFillColor());
693 h2->SetFillStyle(fTree->GetFillStyle());
694 h2->SetMarkerStyle(fTree->GetMarkerStyle());
695 h2->SetMarkerColor(fTree->GetMarkerColor());
696 h2->SetMarkerSize(fTree->GetMarkerSize());
697 if (canExtend) h2->SetCanExtend(TH1::kAllAxes);
699 h2->GetXaxis()->SetTitle(fVar[1]->GetTitle());
700 h2->GetYaxis()->SetTitle(fVar[0]->GetTitle());
701 h2->SetBit(TH1::kNoStats);
702 h2->SetBit(kCanDelete);
703 if (!opt.Contains(
"goff")) h2->SetDirectory(0);
706 fVar[0]->SetAxis(h2->GetYaxis());
707 fVar[1]->SetAxis(h2->GetXaxis());
708 Bool_t graph = kFALSE;
709 Int_t l = opt.Length();
710 if (l == 0 || optSame) graph = kTRUE;
711 if (opt.Contains(
"p") || opt.Contains(
"*") || opt.Contains(
"l")) graph = kTRUE;
712 if (opt.Contains(
"surf") || opt.Contains(
"lego") || opt.Contains(
"cont")) graph = kFALSE;
713 if (opt.Contains(
"col") || opt.Contains(
"hist") || opt.Contains(
"scat")) graph = kFALSE;
714 if (opt.Contains(
"box")) graph = kFALSE;
718 if (!fOldHistogram && !optSame) fAction = -12;
723 }
else if ((fDimension == 3 || fDimension == 4) && !(optpara || optcandle)) {
725 if (fDimension == 4) fAction = 40;
726 if (!fOldHistogram || !optSame) {
727 fNbins[0] = gEnv->GetValue(
"Hist.Binning.3D.z", 20);
728 fNbins[1] = gEnv->GetValue(
"Hist.Binning.3D.y", 20);
729 fNbins[2] = gEnv->GetValue(
"Hist.Binning.3D.x", 20);
730 if (fDimension == 3 && opt.Contains(
"prof")) {
731 fNbins[1] = gEnv->GetValue(
"Hist.Binning.3D.Profy", 20);
732 fNbins[2] = gEnv->GetValue(
"Hist.Binning.3D.Profx", 20);
733 }
else if (fDimension == 3 && opt.Contains(
"col")) {
734 fNbins[0] = gEnv->GetValue(
"Hist.Binning.2D.y", 40);
735 fNbins[1] = gEnv->GetValue(
"Hist.Binning.2D.x", 40);
738 TH1 *oldhtemp = (TH1*)gPad->FindObject(hdefault);
740 fNbins[2] = oldhtemp->GetXaxis()->GetNbins();
741 fVmin[2] = oldhtemp->GetXaxis()->GetXmin();
742 fVmax[2] = oldhtemp->GetXaxis()->GetXmax();
743 fNbins[1] = oldhtemp->GetYaxis()->GetNbins();
744 fVmin[1] = oldhtemp->GetYaxis()->GetXmin();
745 fVmax[1] = oldhtemp->GetYaxis()->GetXmax();
746 fNbins[0] = oldhtemp->GetZaxis()->GetNbins();
747 fVmin[0] = oldhtemp->GetZaxis()->GetXmin();
748 fVmax[0] = oldhtemp->GetZaxis()->GetXmax();
750 TView *view = gPad->GetView();
752 Error(
"Begin",
"You cannot use option same when no 3D view exists");
753 fVmin[0] = fVmin[1] = fVmin[2] = -1;
754 fVmax[0] = fVmax[1] = fVmax[2] = 1;
755 view = TView::CreateView(1, fVmin, fVmax);
757 Double_t *rmin = view->GetRmin();
758 Double_t *rmax = view->GetRmax();
759 fNbins[2] = gEnv->GetValue(
"Hist.Binning.3D.z", 20);
762 fNbins[1] = gEnv->GetValue(
"Hist.Binning.3D.y", 20);
765 fNbins[0] = gEnv->GetValue(
"Hist.Binning.3D.x", 20);
770 if (!fOldHistogram && fDimension == 3) fAction = -3;
777 if (xmin < xmax && ymin < ymax && zmin < zmax) canExtend = kFALSE;
780 if ((fDimension == 3) && (profile || opt.Contains(
"prof"))) {
784 hp = (TProfile2D*)fOldHistogram;
792 if (xmin < xmax && ymin < ymax) canExtend = kFALSE;
794 if (opt.Contains(
"profs")) {
795 hp =
new TProfile2D(hname, htitle.Data(), fNbins[2], fVmin[2], fVmax[2], fNbins[1], fVmin[1], fVmax[1],
"s");
796 }
else if (opt.Contains(
"profi")) {
797 hp =
new TProfile2D(hname, htitle.Data(), fNbins[2], fVmin[2], fVmax[2], fNbins[1], fVmin[1], fVmax[1],
"i");
798 }
else if (opt.Contains(
"profg")) {
799 hp =
new TProfile2D(hname, htitle.Data(), fNbins[2], fVmin[2], fVmax[2], fNbins[1], fVmin[1], fVmax[1],
"g");
801 hp =
new TProfile2D(hname, htitle.Data(), fNbins[2], fVmin[2], fVmax[2], fNbins[1], fVmin[1], fVmax[1],
"");
804 hp->SetBit(kCanDelete);
805 if (!opt.Contains(
"goff")) hp->SetDirectory(0);
807 hp->SetLineColor(fTree->GetLineColor());
808 hp->SetLineWidth(fTree->GetLineWidth());
809 hp->SetLineStyle(fTree->GetLineStyle());
810 hp->SetFillColor(fTree->GetFillColor());
811 hp->SetFillStyle(fTree->GetFillStyle());
812 hp->SetMarkerStyle(fTree->GetMarkerStyle());
813 hp->SetMarkerColor(fTree->GetMarkerColor());
814 hp->SetMarkerSize(fTree->GetMarkerSize());
815 if (canExtend) hp->SetCanExtend(TH1::kAllAxes);
817 fVar[1]->SetAxis(hp->GetYaxis());
818 fVar[2]->SetAxis(hp->GetXaxis());
820 }
else if (fDimension == 3 && opt.Contains(
"col")) {
823 h2 = (TH2F*)fOldHistogram;
825 h2 =
new TH2F(hname, htitle.Data(), fNbins[1], fVmin[1], fVmax[1], fNbins[0], fVmin[0], fVmax[0]);
826 h2->SetLineColor(fTree->GetLineColor());
827 h2->SetLineWidth(fTree->GetLineWidth());
828 h2->SetLineStyle(fTree->GetLineStyle());
829 h2->SetFillColor(fTree->GetFillColor());
830 h2->SetFillStyle(fTree->GetFillStyle());
831 h2->SetMarkerStyle(fTree->GetMarkerStyle());
832 h2->SetMarkerColor(fTree->GetMarkerColor());
833 h2->SetMarkerSize(fTree->GetMarkerSize());
834 if (canExtend) h2->SetCanExtend(TH1::kAllAxes);
836 h2->GetXaxis()->SetTitle(fVar[1]->GetTitle());
837 h2->GetYaxis()->SetTitle(fVar[0]->GetTitle());
838 h2->GetZaxis()->SetTitle(fVar[2]->GetTitle());
839 h2->SetBit(TH1::kNoStats);
840 h2->SetBit(kCanDelete);
841 if (!opt.Contains(
"goff")) h2->SetDirectory(0);
844 fVar[0]->SetAxis(h2->GetYaxis());
845 fVar[1]->SetAxis(h2->GetXaxis());
851 h3 = (TH3F*)fOldHistogram;
853 TString precision = gEnv->GetValue(
"Hist.Precision.3D",
"float");
854 if (precision.Contains(
"float")) {
855 h3 =
new TH3F(hname, htitle.Data(), fNbins[2], fVmin[2], fVmax[2], fNbins[1], fVmin[1], fVmax[1], fNbins[0], fVmin[0], fVmax[0]);
857 h3 =
new TH3D(hname, htitle.Data(), fNbins[2], fVmin[2], fVmax[2], fNbins[1], fVmin[1], fVmax[1], fNbins[0], fVmin[0], fVmax[0]);
859 h3->SetLineColor(fTree->GetLineColor());
860 h3->SetLineWidth(fTree->GetLineWidth());
861 h3->SetLineStyle(fTree->GetLineStyle());
862 h3->SetFillColor(fTree->GetFillColor());
863 h3->SetFillStyle(fTree->GetFillStyle());
864 h3->SetMarkerStyle(fTree->GetMarkerStyle());
865 h3->SetMarkerColor(fTree->GetMarkerColor());
866 h3->SetMarkerSize(fTree->GetMarkerSize());
867 if (canExtend) h3->SetCanExtend(TH1::kAllAxes);
870 Double_t xoffset = h3->GetXaxis()->GetTitleOffset();
871 Double_t yoffset = h3->GetYaxis()->GetTitleOffset();
872 h3->GetXaxis()->SetTitleOffset(1.2 * xoffset);
873 h3->GetYaxis()->SetTitleOffset(1.2 * yoffset);
874 h3->GetXaxis()->SetTitle(fVar[2]->GetTitle());
875 h3->GetYaxis()->SetTitle(fVar[1]->GetTitle());
876 h3->GetZaxis()->SetTitle(fVar[0]->GetTitle());
877 h3->SetBit(kCanDelete);
878 h3->SetBit(TH1::kNoStats);
879 if (!opt.Contains(
"goff")) h3->SetDirectory(0);
882 fVar[0]->SetAxis(h3->GetZaxis());
883 fVar[1]->SetAxis(h3->GetYaxis());
884 fVar[2]->SetAxis(h3->GetXaxis());
886 Int_t noscat = strlen(option);
887 if (optSame) noscat -= 4;
888 if (!noscat && fDimension == 3) {
890 if (!fOldHistogram && !optSame) fAction = -13;
896 fOldEstimate = fTree->GetEstimate();
897 fTree->SetEstimate(1);
901 fOldEstimate = fTree->GetEstimate();
902 fTree->SetEstimate(1);
904 }
else if (optcandle || optpara || opt5d) {
905 if (optcandle) fAction = 7;
906 else if (opt5d) fAction = 8;
909 if (varexp)
delete[] varexp;
910 if (hnamealloc)
delete[] hnamealloc;
911 for (i = 0; i < fValSize; ++i)
912 fVarMultiple[i] = kFALSE;
913 fSelectMultiple = kFALSE;
914 for (i = 0; i < fDimension; ++i) {
915 if (fVar[i] && fVar[i]->GetMultiplicity()) fVarMultiple[i] = kTRUE;
918 if (fSelect && fSelect->GetMultiplicity()) fSelectMultiple = kTRUE;
920 fForceRead = fTree->TestBit(TTree::kForceRead);
921 fWeight = fTree->GetWeight();
924 for (i = 0; i < fDimension; ++i) {
925 if (!fVal[i] && fVar[i]) {
926 fVal[i] =
new Double_t[(Int_t)fTree->GetEstimate()];
930 if (!fW) fW =
new Double_t[(Int_t)fTree->GetEstimate()];
932 for (i = 0; i < fValSize; ++i) {
941 void TSelectorDraw::ClearFormula()
944 for (Int_t i = 0; i < fValSize; ++i) {
948 delete fSelect; fSelect = 0;
976 Bool_t TSelectorDraw::CompileVariables(
const char *varexp,
const char *selection)
986 if (strlen(selection)) {
987 fSelect =
new TTreeFormula(
"Selection", selection, fTree);
988 fSelect->SetQuickLoad(kTRUE);
989 if (!fSelect->GetNdim()) {
997 nch = strlen(varexp);
1001 fManager = fSelect->GetManager();
1003 fTree->ResetBit(TTree::kForceRead);
1008 if (fManager->GetMultiplicity() == -1) fTree->SetBit(TTree::kForceRead);
1009 if (fManager->GetMultiplicity() >= 1) fMultiplicity = fManager->GetMultiplicity();
1016 std::vector<TString> varnames;
1017 ncols = SplitNames(varexp, varnames);
1021 fManager =
new TTreeFormulaManager();
1022 if (fSelect) fManager->Add(fSelect);
1023 fTree->ResetBit(TTree::kForceRead);
1024 for (i = 0; i < ncols; ++i) {
1025 fVar[i] =
new TTreeFormula(TString::Format(
"Var%i", i + 1), varnames[i].Data(), fTree);
1026 fVar[i]->SetQuickLoad(kTRUE);
1027 if(!fVar[i]->GetNdim()) { ClearFormula();
return kFALSE; }
1028 fManager->Add(fVar[i]);
1032 if (fManager->GetMultiplicity() == -1) fTree->SetBit(TTree::kForceRead);
1033 if (fManager->GetMultiplicity() >= 1) fMultiplicity = fManager->GetMultiplicity();
1038 TClass *cl = fVar[0]->EvalClass();
1069 Double_t* TSelectorDraw::GetVal(Int_t i)
const
1071 if (i < 0 || i >= fDimension)
1081 TTreeFormula* TSelectorDraw::GetVar(Int_t i)
const
1083 if (i < 0 || i >= fDimension)
1092 void TSelectorDraw::InitArrays(Int_t newsize)
1094 if (newsize > fValSize) {
1095 Int_t oldsize = fValSize;
1096 while (fValSize < newsize)
1098 if (fNbins)
delete [] fNbins;
1099 if (fVmin)
delete [] fVmin;
1100 if (fVmax)
delete [] fVmax;
1101 if (fVarMultiple)
delete [] fVarMultiple;
1103 fNbins =
new Int_t[fValSize];
1104 fVmin =
new Double_t[fValSize];
1105 fVmax =
new Double_t[fValSize];
1106 fVarMultiple =
new Bool_t[fValSize];
1108 for (Int_t i = 0; i < oldsize; ++i)
1112 fVal =
new Double_t*[fValSize];
1113 fVar =
new TTreeFormula*[fValSize];
1114 for (Int_t i = 0; i < fValSize; ++i) {
1125 UInt_t TSelectorDraw::SplitNames(
const TString &varexp, std::vector<TString> &names)
1129 Bool_t ternary = kFALSE;
1131 for (Int_t i = 0; i < varexp.Length(); i++) {
1132 if (varexp[i] ==
':'
1133 && !((i > 0 && varexp[i-1] ==
':') || varexp[i+1] ==
':')
1138 names.push_back(varexp(prev, i - prev));
1142 if (varexp[i] ==
'?') {
1146 names.push_back(varexp(prev, varexp.Length() - prev));
1147 return names.size();
1154 Bool_t TSelectorDraw::Notify()
1156 if (fTree) fWeight = fTree->GetWeight();
1158 for (Int_t i = 0; i < fDimension; ++i) {
1159 if (fVar[i]) fVar[i]->UpdateFormulaLeaves();
1162 if (fSelect) fSelect->UpdateFormulaLeaves();
1169 void TSelectorDraw::ProcessFill(Long64_t entry)
1172 ProcessFillObject(entry);
1176 if (fMultiplicity) {
1177 ProcessFillMultiple(entry);
1182 if (fForceRead && fManager->GetNdata() <= 0)
return;
1185 fW[fNfill] = fWeight * fSelect->EvalInstance(0);
1186 if (!fW[fNfill])
return;
1187 }
else fW[fNfill] = fWeight;
1189 for (Int_t i = 0; i < fDimension; ++i) {
1190 if (fVar[i]) fVal[i][fNfill] = fVar[i]->EvalInstance(0);
1194 if (fNfill >= fTree->GetEstimate()) {
1204 void TSelectorDraw::ProcessFillMultiple(Long64_t entry)
1207 Int_t ndata = fManager->GetNdata();
1213 TEntryList *subList = 0;
1214 if (fTreeElistArray) {
1215 subList = fTreeElistArray->GetSubListForEntry(entry, fTree->GetTree());
1218 Int_t nfill0 = fNfill;
1223 fW[fNfill] = fWeight * fSelect->EvalInstance(0);
1224 if (!fW[fNfill] && !fSelectMultiple)
return;
1225 }
else fW[fNfill] = fWeight;
1229 if (fW[fNfill] && (!subList || subList->Contains(0))) {
1230 if (fDimension == 0 && fSelectMultiple) fCurrentSubEntry = (Long64_t) 0;
1231 for (Int_t i = 0; i < fDimension; ++i) {
1232 if (fVar[i]) fVal[i][fNfill] = fVar[i]->EvalInstance(0);
1235 if (fNfill >= fTree->GetEstimate()) {
1240 for (Int_t i = 0; i < fDimension; ++i) {
1241 if (fVar[i]) fVar[i]->ResetLoading();
1244 Double_t ww = fW[nfill0];
1246 for (Int_t i = 1; i < ndata; i++) {
1247 if (subList && !subList->Contains(i))
continue;
1248 if (fSelectMultiple) {
1250 ww = fWeight * fSelect->EvalInstance(i);
1251 if (ww == 0)
continue;
1252 if (fNfill == nfill0) {
1253 for (Int_t k = 0; k < fDimension; ++k) {
1254 if (!fVarMultiple[k]) fVal[k][fNfill] = fVar[k]->EvalInstance(0);
1257 if (fDimension == 0) fCurrentSubEntry = (Long64_t) i;
1259 for (Int_t k = 0; k < fDimension; ++k) {
1260 if (fVarMultiple[k]) fVal[k][fNfill] = fVar[k]->EvalInstance(i);
1261 else fVal[k][fNfill] = fVal[k][nfill0];
1266 if (fNfill >= fTree->GetEstimate()) {
1277 void TSelectorDraw::ProcessFillObject(Long64_t )
1282 Int_t ndata = fManager->GetNdata();
1287 Int_t nfill0 = fNfill;
1290 for (Int_t i = 0; i < ndata; i++) {
1293 fW[fNfill] = fWeight * fSelect->EvalInstance(0);
1294 if (!fW[fNfill] && !fSelectMultiple)
return;
1295 }
else fW[fNfill] = fWeight;
1297 }
else if (fSelectMultiple) {
1298 ww = fWeight * fSelect->EvalInstance(i);
1299 if (ww == 0)
continue;
1301 if (fDimension >= 1 && fVar[0]) {
1302 TClass *cl = fVar[0]->EvalClass();
1303 if (cl == TBits::Class()) {
1305 void *obj = fVar[0]->EvalObject(i);
1308 TBits *bits = (TBits*)obj;
1309 Int_t nbits = bits->GetNbits();
1313 nextbit = bits->FirstSetBit(nextbit + 1);
1314 if (nextbit >= nbits)
break;
1315 fVal[0][fNfill] = nextbit;
1323 if (!TestBit(kWarn)) {
1324 Warning(
"ProcessFillObject",
1325 "Not implemented for %s",
1326 cl ? cl->GetName() :
"unknown class");
1332 if (fNfill >= fTree->GetEstimate()) {
1343 void TSelectorDraw::SetEstimate(Long64_t)
1346 for (Int_t i = 0; i < fValSize; ++i) {
1351 delete [] fW; fW = 0;
1357 void TSelectorDraw::TakeAction()
1361 if (fAction == 1)((TH1*)fObject)->FillN(fNfill, fVal[0], fW);
1363 else if (fAction == 2) {
1364 TH2 *h2 = (TH2*)fObject;
1365 for (i = 0; i < fNfill; i++) h2->Fill(fVal[1][i], fVal[0][i], fW[i]);
1368 else if (fAction == 4)((TProfile*)fObject)->FillN(fNfill, fVal[1], fVal[0], fW);
1370 else if (fAction == 5) {
1371 if (fObject->InheritsFrom(TEntryListArray::Class())) {
1372 TEntryListArray *enlistarray = (TEntryListArray*)fObject;
1373 Long64_t enumb = fTree->GetTree()->GetReadEntry();
1374 enlistarray->Enter(enumb, 0, fCurrentSubEntry);
1375 }
else if (fObject->InheritsFrom(TEntryList::Class())) {
1376 TEntryList *enlist = (TEntryList*)fObject;
1377 Long64_t enumb = fTree->GetTree()->GetReadEntry();
1378 enlist->Enter(enumb);
1380 TEventList *evlist = (TEventList*)fObject;
1381 Long64_t enumb = fTree->GetChainOffset() + fTree->GetTree()->GetReadEntry();
1382 if (evlist->GetIndex(enumb) < 0) evlist->Enter(enumb);
1386 else if (fAction == 12) {
1387 TH2 *h2 = (TH2*)fObject;
1388 if (h2->CanExtendAllAxes() && h2->TestBit(kCanDelete)) {
1389 for (i = 0; i < fNfill; i++) {
1390 if (fVmin[0] > fVal[0][i]) fVmin[0] = fVal[0][i];
1391 if (fVmax[0] < fVal[0][i]) fVmax[0] = fVal[0][i];
1392 if (fVmin[1] > fVal[1][i]) fVmin[1] = fVal[1][i];
1393 if (fVmax[1] < fVal[1][i]) fVmax[1] = fVal[1][i];
1395 THLimitsFinder::GetLimitsFinder()->FindGoodLimits(h2, fVmin[1], fVmax[1], fVmin[0], fVmax[0]);
1397 TGraph *pm =
new TGraph(fNfill, fVal[1], fVal[0]);
1398 pm->SetEditable(kFALSE);
1399 pm->SetBit(kCanDelete);
1400 pm->SetMarkerStyle(fTree->GetMarkerStyle());
1401 pm->SetMarkerColor(fTree->GetMarkerColor());
1402 pm->SetMarkerSize(fTree->GetMarkerSize());
1403 pm->SetLineColor(fTree->GetLineColor());
1404 pm->SetLineWidth(fTree->GetLineWidth());
1405 pm->SetLineStyle(fTree->GetLineStyle());
1406 pm->SetFillColor(fTree->GetFillColor());
1407 pm->SetFillStyle(fTree->GetFillStyle());
1409 if (!fDraw && !strstr(fOption.Data(),
"goff")) {
1410 if (fOption.Length() == 0 || strcasecmp(fOption.Data(),
"same") == 0) pm->Draw(
"p");
1411 else pm->Draw(fOption.Data());
1413 if (!h2->TestBit(kCanDelete)) {
1414 for (i = 0; i < fNfill; i++) h2->Fill(fVal[1][i], fVal[0][i], fW[i]);
1418 else if (fAction == 3) {
1419 TH3 *h3 = (TH3*)fObject;
1420 if (!h3->TestBit(kCanDelete)) {
1421 for (i = 0; i < fNfill; i++) h3->Fill(fVal[2][i], fVal[1][i], fVal[0][i], fW[i]);
1423 }
else if (fAction == 13) {
1424 TPolyMarker3D *pm3d =
new TPolyMarker3D(fNfill);
1425 pm3d->SetMarkerStyle(fTree->GetMarkerStyle());
1426 pm3d->SetMarkerColor(fTree->GetMarkerColor());
1427 pm3d->SetMarkerSize(fTree->GetMarkerSize());
1428 for (i = 0; i < fNfill; i++) {
1429 pm3d->SetPoint(i, fVal[2][i], fVal[1][i], fVal[0][i]);
1432 TH3 *h3 = (TH3*)fObject;
1433 if (!h3->TestBit(kCanDelete)) {
1434 for (i = 0; i < fNfill; i++) h3->Fill(fVal[2][i], fVal[1][i], fVal[0][i], fW[i]);
1438 else if (fAction == 33) {
1439 TH2 *h2 = (TH2*)fObject;
1441 Int_t ncolors = gStyle->GetNumberOfColors();
1442 TObjArray *grs = (TObjArray*)h2->GetListOfFunctions()->FindObject(
"graphs");
1446 grs =
new TObjArray(ncolors);
1448 grs->SetName(
"graphs");
1449 h2->GetListOfFunctions()->Add(grs,
"P");
1450 for (col = 0; col < ncolors; col++) {
1452 gr->SetMarkerColor(gStyle->GetColorPalette(col));
1453 gr->SetMarkerStyle(fTree->GetMarkerStyle());
1454 gr->SetMarkerSize(fTree->GetMarkerSize());
1455 grs->AddAt(gr, col);
1458 h2->SetEntries(fNfill);
1459 h2->SetMinimum(fVmin[2]);
1460 h2->SetMaximum(fVmax[2]);
1462 for (i = 0; i < fNfill; i++) {
1463 col = Int_t(ncolors * ((fVal[2][i] - fVmin[2]) / (fVmax[2] - fVmin[2])));
1464 if (col < 0) col = 0;
1465 if (col > ncolors - 1) col = ncolors - 1;
1466 gr = (TGraph*)grs->UncheckedAt(col);
1467 if (gr) gr->SetPoint(gr->GetN(), fVal[1][i], fVal[0][i]);
1470 for (col = 0; col < ncolors; col++) {
1471 gr = (TGraph*)grs->At(col);
1472 if (gr && gr->GetN() <= 0) grs->Remove(gr);
1476 else if (fAction == 23) {
1477 TProfile2D *hp2 = (TProfile2D*)fObject;
1478 for (i = 0; i < fNfill; i++) hp2->Fill(fVal[2][i], fVal[1][i], fVal[0][i], fW[i]);
1481 else if (fAction == 40) {
1483 TH3 *h3 = (TH3*)fObject;
1484 Int_t ncolors = gStyle->GetNumberOfColors();
1486 TColor::InitializeColors();
1487 ncolors = gStyle->GetNumberOfColors();
1489 TObjArray *pms = (TObjArray*)h3->GetListOfFunctions()->FindObject(
"polymarkers");
1491 TPolyMarker3D *pm3d;
1493 pms =
new TObjArray(ncolors);
1495 pms->SetName(
"polymarkers");
1496 h3->GetListOfFunctions()->Add(pms);
1497 for (col = 0; col < ncolors; col++) {
1498 pm3d =
new TPolyMarker3D();
1499 pm3d->SetMarkerColor(gStyle->GetColorPalette(col));
1500 pm3d->SetMarkerStyle(fTree->GetMarkerStyle());
1501 pm3d->SetMarkerSize(fTree->GetMarkerSize());
1502 pms->AddAt(pm3d, col);
1505 h3->SetEntries(fNfill);
1506 h3->SetMinimum(fVmin[3]);
1507 h3->SetMaximum(fVmax[3]);
1508 for (i = 0; i < fNfill; i++) {
1509 col = Int_t(ncolors * ((fVal[3][i] - fVmin[3]) / (fVmax[3] - fVmin[3])));
1510 if (col > ncolors-1) col = ncolors-1;
1511 if (col < 0) col = 0;
1512 pm3d = (TPolyMarker3D*)pms->UncheckedAt(col);
1513 pm3d->SetPoint(pm3d->GetLastPoint() + 1, fVal[2][i], fVal[1][i], fVal[0][i]);
1517 else if (fAction == 6 || fAction == 7) {
1519 Bool_t candle = (fAction == 7);
1521 if (!fOption.Contains(
"goff"))
1522 gROOT->ProcessLine(TString::Format(
"TParallelCoord::BuildParallelCoord((TSelectorDraw*)0x%lx,0x%lx)",
1523 (ULong_t)
this, (ULong_t)candle));
1524 }
else if (fAction == 8) {
1528 else if (fAction < 0) {
1534 fSelectedRows += fNfill;
1535 if (!fTree->GetUpdate())
return;
1536 if (fSelectedRows > fDraw + fTree->GetUpdate()) {
1537 if (fDraw) gPad->Modified();
1538 else fObject->Draw(fOption.Data());
1540 fDraw = fSelectedRows;
1547 void TSelectorDraw::TakeEstimate()
1550 Double_t rmin[3], rmax[3];
1551 Double_t vminOld[4], vmaxOld[4];
1552 for (i = 0; i < fValSize && i < 4; i++) {
1553 vminOld[i] = fVmin[i];
1554 vmaxOld[i] = fVmax[i];
1556 for (i = 0; i < fValSize; ++i) {
1558 fVmax[i] = - DBL_MAX;
1562 TH1 *h1 = (TH1*)fObject;
1563 if (h1->CanExtendAllAxes()) {
1564 for (i = 0; i < fNfill; i++) {
1565 if (fVmin[0] > fVal[0][i]) fVmin[0] = fVal[0][i];
1566 if (fVmax[0] < fVal[0][i]) fVmax[0] = fVal[0][i];
1568 THLimitsFinder::GetLimitsFinder()->FindGoodLimits(h1, fVmin[0], fVmax[0]);
1570 h1->FillN(fNfill, fVal[0], fW);
1572 }
else if (fAction == 2) {
1573 TH2 *h2 = (TH2*)fObject;
1574 if (h2->CanExtendAllAxes()) {
1575 for (i = 0; i < fNfill; i++) {
1576 if (fVmin[0] > fVal[0][i]) fVmin[0] = fVal[0][i];
1577 if (fVmax[0] < fVal[0][i]) fVmax[0] = fVal[0][i];
1578 if (fVmin[1] > fVal[1][i]) fVmin[1] = fVal[1][i];
1579 if (fVmax[1] < fVal[1][i]) fVmax[1] = fVal[1][i];
1581 THLimitsFinder::GetLimitsFinder()->FindGoodLimits(h2, fVmin[1], fVmax[1], fVmin[0], fVmax[0]);
1583 for (i = 0; i < fNfill; i++) h2->Fill(fVal[1][i], fVal[0][i], fW[i]);
1585 }
else if (fAction == 4) {
1586 TProfile *hp = (TProfile*)fObject;
1587 if (hp->CanExtendAllAxes()) {
1588 for (i = 0; i < fNfill; i++) {
1589 if (fVmin[0] > fVal[0][i]) fVmin[0] = fVal[0][i];
1590 if (fVmax[0] < fVal[0][i]) fVmax[0] = fVal[0][i];
1591 if (fVmin[1] > fVal[1][i]) fVmin[1] = fVal[1][i];
1592 if (fVmax[1] < fVal[1][i]) fVmax[1] = fVal[1][i];
1594 THLimitsFinder::GetLimitsFinder()->FindGoodLimits(hp, fVmin[1], fVmax[1]);
1596 hp->FillN(fNfill, fVal[1], fVal[0], fW);
1598 }
else if (fAction == 12) {
1599 TH2 *h2 = (TH2*)fObject;
1600 if (h2->CanExtendAllAxes()) {
1601 for (i = 0; i < fNfill; i++) {
1602 if (fVmin[0] > fVal[0][i]) fVmin[0] = fVal[0][i];
1603 if (fVmax[0] < fVal[0][i]) fVmax[0] = fVal[0][i];
1604 if (fVmin[1] > fVal[1][i]) fVmin[1] = fVal[1][i];
1605 if (fVmax[1] < fVal[1][i]) fVmax[1] = fVal[1][i];
1607 THLimitsFinder::GetLimitsFinder()->FindGoodLimits(h2, fVmin[1], fVmax[1], fVmin[0], fVmax[0]);
1610 TAxis *aX = h2->GetXaxis();
1611 TAxis *aY = h2->GetYaxis();
1612 Double_t xmin = aX->GetXmin();
1613 Double_t ymin = aY->GetXmin();
1614 if (xmin == 0 || ymin == 0) {
1615 if (aX->GetBinUpEdge(aX->FindFixBin(0.01*aX->GetBinWidth(aX->GetFirst()))) > fVmin[1]) xmin = fVmin[1];
1616 if (aY->GetBinUpEdge(aY->FindFixBin(0.01*aY->GetBinWidth(aY->GetFirst()))) > fVmin[0]) ymin = fVmin[0];
1617 h2->SetBins(aX->GetNbins(), xmin, aX->GetXmax(), aY->GetNbins(), ymin, aY->GetXmax());
1621 if (!strstr(fOption.Data(),
"same") && !strstr(fOption.Data(),
"goff")) {
1622 if (!h2->TestBit(kCanDelete)) {
1627 TH1 *h2c = h2->DrawCopy(fOption.Data(),
"");
1628 if (h2c) h2c->SetStats(kFALSE);
1637 TGraph *pm =
new TGraph(fNfill, fVal[1], fVal[0]);
1638 pm->SetEditable(kFALSE);
1639 pm->SetBit(kCanDelete);
1640 pm->SetMarkerStyle(fTree->GetMarkerStyle());
1641 pm->SetMarkerColor(fTree->GetMarkerColor());
1642 pm->SetMarkerSize(fTree->GetMarkerSize());
1643 pm->SetLineColor(fTree->GetLineColor());
1644 pm->SetLineWidth(fTree->GetLineWidth());
1645 pm->SetLineStyle(fTree->GetLineStyle());
1646 pm->SetFillColor(fTree->GetFillColor());
1647 pm->SetFillStyle(fTree->GetFillStyle());
1648 if (!fDraw && !strstr(fOption.Data(),
"goff")) {
1649 if (fOption.Length() == 0 || strcasecmp(fOption.Data(),
"same")==0) {
1653 TString opt = fOption;
1655 if (opt.Contains(
"a")) {
1657 temp.ReplaceAll(
"same",
"");
1658 if (temp.Contains(
"a")) {
1659 if (h2->TestBit(kCanDelete)) {
1666 pm->Draw(fOption.Data());
1669 if (h2 && !h2->TestBit(kCanDelete)) {
1670 for (i = 0; i < fNfill; i++) h2->Fill(fVal[1][i], fVal[0][i], fW[i]);
1673 }
else if (fAction == 33) {
1674 TH2 *h2 = (TH2*)fObject;
1675 Bool_t process2 = kFALSE;
1676 if (h2->CanExtendAllAxes()) {
1677 if (vminOld[2] == DBL_MAX)
1679 for (i = 0; i < fValSize && i < 4; i++) {
1680 fVmin[i] = vminOld[i];
1681 fVmax[i] = vmaxOld[i];
1683 for (i = 0; i < fNfill; i++) {
1684 if (fVmin[0] > fVal[0][i]) fVmin[0] = fVal[0][i];
1685 if (fVmax[0] < fVal[0][i]) fVmax[0] = fVal[0][i];
1686 if (fVmin[1] > fVal[1][i]) fVmin[1] = fVal[1][i];
1687 if (fVmax[1] < fVal[1][i]) fVmax[1] = fVal[1][i];
1689 if (fVmin[2] > fVal[2][i]) fVmin[2] = fVal[2][i];
1690 if (fVmax[2] < fVal[2][i]) fVmax[2] = fVal[2][i];
1693 THLimitsFinder::GetLimitsFinder()->FindGoodLimits(h2, fVmin[1], fVmax[1], fVmin[0], fVmax[0]);
1696 TAxis *aX = h2->GetXaxis();
1697 TAxis *aY = h2->GetYaxis();
1698 Double_t xmin = aX->GetXmin();
1699 Double_t ymin = aY->GetXmin();
1700 if (xmin == 0 || ymin == 0) {
1701 if (aX->GetBinUpEdge(aX->FindFixBin(0.01*aX->GetBinWidth(aX->GetFirst()))) > fVmin[1]) xmin = fVmin[1];
1702 if (aY->GetBinUpEdge(aY->FindFixBin(0.01*aY->GetBinWidth(aY->GetFirst()))) > fVmin[0]) ymin = fVmin[0];
1703 h2->SetBins(aX->GetNbins(), xmin, aX->GetXmax(), aY->GetNbins(), ymin, aY->GetXmax());
1706 for (i = 0; i < fNfill; i++) {
1707 if (fVmin[2] > fVal[2][i]) fVmin[2] = fVal[2][i];
1708 if (fVmax[2] < fVal[2][i]) fVmax[2] = fVal[2][i];
1712 }
else if (fAction == 3 || fAction == 13) {
1713 TH3 *h3 = (TH3*)fObject;
1714 if (h3->CanExtendAllAxes()) {
1715 for (i = 0; i < fNfill; i++) {
1716 if (fVmin[0] > fVal[0][i]) fVmin[0] = fVal[0][i];
1717 if (fVmax[0] < fVal[0][i]) fVmax[0] = fVal[0][i];
1718 if (fVmin[1] > fVal[1][i]) fVmin[1] = fVal[1][i];
1719 if (fVmax[1] < fVal[1][i]) fVmax[1] = fVal[1][i];
1720 if (fVmin[2] > fVal[2][i]) fVmin[2] = fVal[2][i];
1721 if (fVmax[2] < fVal[2][i]) fVmax[2] = fVal[2][i];
1723 THLimitsFinder::GetLimitsFinder()->FindGoodLimits(h3, fVmin[2], fVmax[2], fVmin[1], fVmax[1], fVmin[0], fVmax[0]);
1726 for (i = 0; i < fNfill; i++) h3->Fill(fVal[2][i], fVal[1][i], fVal[0][i], fW[i]);
1729 if (!strstr(fOption.Data(),
"same") && !strstr(fOption.Data(),
"goff")) {
1730 if (!h3->TestBit(kCanDelete)) {
1735 TH1 *h3c = h3->DrawCopy(fOption.Data(),
"");
1736 if (h3c) h3c->SetStats(kFALSE);
1741 h3->Draw(fOption.Data());
1745 rmin[0] = fVmin[2]; rmin[1] = fVmin[1]; rmin[2] = fVmin[0];
1746 rmax[0] = fVmax[2]; rmax[1] = fVmax[1]; rmax[2] = fVmax[0];
1748 gPad->Range(-1, -1, 1, 1);
1749 TView::CreateView(1, rmin, rmax);
1751 TPolyMarker3D *pm3d =
new TPolyMarker3D(fNfill);
1752 pm3d->SetMarkerStyle(fTree->GetMarkerStyle());
1753 pm3d->SetMarkerColor(fTree->GetMarkerColor());
1754 pm3d->SetMarkerSize(fTree->GetMarkerSize());
1755 for (i = 0; i < fNfill; i++) {
1756 pm3d->SetPoint(i, fVal[2][i], fVal[1][i], fVal[0][i]);
1758 if (!fDraw && !strstr(fOption.Data(),
"goff")) pm3d->Draw();
1759 if (!h3->TestBit(kCanDelete)) {
1760 for (i = 0; i < fNfill; i++) h3->Fill(fVal[2][i], fVal[1][i], fVal[0][i], fW[i]);
1764 }
else if (fAction == 23) {
1765 TProfile2D *hp = (TProfile2D*)fObject;
1766 if (hp->CanExtendAllAxes()) {
1767 for (i = 0; i < fNfill; i++) {
1768 if (fVmin[0] > fVal[0][i]) fVmin[0] = fVal[0][i];
1769 if (fVmax[0] < fVal[0][i]) fVmax[0] = fVal[0][i];
1770 if (fVmin[1] > fVal[1][i]) fVmin[1] = fVal[1][i];
1771 if (fVmax[1] < fVal[1][i]) fVmax[1] = fVal[1][i];
1772 if (fVmin[2] > fVal[2][i]) fVmin[2] = fVal[2][i];
1773 if (fVmax[2] < fVal[2][i]) fVmax[2] = fVal[2][i];
1775 THLimitsFinder::GetLimitsFinder()->FindGoodLimits(hp, fVmin[2], fVmax[2], fVmin[1], fVmax[1]);
1777 for (i = 0; i < fNfill; i++) hp->Fill(fVal[2][i], fVal[1][i], fVal[0][i], fW[i]);
1779 }
else if (fAction == 40) {
1780 TH3 *h3 = (TH3*)fObject;
1781 if (h3->CanExtendAllAxes()) {
1782 for (i = 0; i < fValSize && i < 4; i++) {
1783 fVmin[i] = vminOld[i];
1784 fVmax[i] = vmaxOld[i];
1786 for (i = 0; i < fNfill; i++) {
1787 if (fVmin[0] > fVal[0][i]) fVmin[0] = fVal[0][i];
1788 if (fVmax[0] < fVal[0][i]) fVmax[0] = fVal[0][i];
1789 if (fVmin[1] > fVal[1][i]) fVmin[1] = fVal[1][i];
1790 if (fVmax[1] < fVal[1][i]) fVmax[1] = fVal[1][i];
1791 if (fVmin[2] > fVal[2][i]) fVmin[2] = fVal[2][i];
1792 if (fVmax[2] < fVal[2][i]) fVmax[2] = fVal[2][i];
1793 if (fVmin[3] > fVal[3][i]) fVmin[3] = fVal[3][i];
1794 if (fVmax[3] < fVal[3][i]) fVmax[3] = fVal[3][i];
1796 THLimitsFinder::GetLimitsFinder()->FindGoodLimits(h3, fVmin[2], fVmax[2], fVmin[1], fVmax[1], fVmin[0], fVmax[0]);
1798 for (i = 0; i < fNfill; i++) {
1799 if (fVmin[3] > fVal[3][i]) fVmin[3] = fVal[3][i];
1800 if (fVmax[3] < fVal[3][i]) fVmax[3] = fVal[3][i];
1805 else if (fAction == 6 || fAction == 7) {
1806 for (i = 0; i < fDimension; ++i) {
1807 for (Long64_t entry = 0; entry < fNfill; entry++) {
1808 if (fVmin[i] > fVal[i][entry]) fVmin[i] = fVal[i][entry];
1809 if (fVmax[i] < fVal[i][entry]) fVmax[i] = fVal[i][entry];
1818 void TSelectorDraw::Terminate()
1820 if (fNfill) TakeAction();
1822 if ((fSelectedRows == 0) && (TestBit(kCustomHistogram) == 0)) fDraw = 1;
1824 SetStatus(fSelectedRows);