ROOT  6.07/01
Reference Guide
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
TSpider.cxx
Go to the documentation of this file.
1 // @(#)root/treeviewer:$Id: 2bb6def14de16b049d4c979e73ad2b08d0936520 $
2 // Author: Bastien Dalla Piazza 20/07/07
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 #include "TSpider.h"
13 #include "TAttFill.h"
14 #include "TAttText.h"
15 #include "TAttLine.h"
16 #include "TGraphPolargram.h"
17 #include "TPolyLine.h"
18 #include "TNtuple.h"
19 #include "TTreeFormula.h"
20 #include "TTreeFormulaManager.h"
21 #include "TList.h"
22 #include "TSelectorDraw.h"
23 #include "TROOT.h"
24 #include "TEntryList.h"
25 #include "TLatex.h"
26 #include "TPad.h"
27 #include "TMath.h"
28 #include "TCanvas.h"
29 #include "TArc.h"
30 #include "float.h"
31 #include "TEnv.h"
32 
34 
35 /** \class TSpider
36 Spider class.
37 
38 A spider view is a handy way to visualize a set of data stored in a TTree.
39 It draws as many polar axes as selected data members. For each of them, it draws
40 on the axis the position of the present event between the min and max of the
41 data member. Two modes are available:
42 
43  - The spider view: With each points on the axes is drawn a polyline.
44  - The segment view: For each data member is drawn an arc segment with the
45  radius corresponding to the event.
46 
47 The spider plot is available from the treeviewer called by
48 "atree->StartViewer()", or simply by calling its constructor and defining the
49 variables to display.
50 
51 Begin_Macro(source)
52 {
53  TCanvas *c1 = new TCanvas("c1","TSpider example",200,10,700,700);
54  TFile *f = new TFile("$(ROOTSYS)/tutorials/hsimple.root");
55  if (!f || f->IsZombie()) {
56  printf("Please run <ROOT location>/tutorials/hsimple.C before.");
57  return;
58  }
59  TNtuple* ntuple = (TNtuple*)f->Get("ntuple");
60  TString varexp = "px:py:pz:random:sin(px):log(px/py):log(pz)";
61  TString selectStr = "px>0 && py>0 && pz>0";
62  TString options = "average";
63  TSpider *spider = new TSpider(ntuple,varexp.Data(),selectStr.Data(),options.Data());
64  spider->Draw();
65  c1->ToggleEditor();
66  c1->Selected(c1,spider,1);
67  return c1;
68 }
69 End_Macro
70 */
71 
72 ////////////////////////////////////////////////////////////////////////////////
73 /// Default constructor.
74 
76 {
77  fDisplayAverage=kFALSE;
78  fForceDim=kFALSE;
79  fPolargram=NULL;
80  fInput=NULL;
81  fManager=NULL;
82  fNcols=0;
83  fNx=3;
84  fNy=4;
85  fPolyList=NULL;
86  fSelect=NULL;
87  fSelector=NULL;
88  fTree=NULL;
89  fMax=NULL;
90  fMin=NULL;
91  fAve=NULL;
92  fCanvas=NULL;
93  fAveragePoly=NULL;
94  fEntry=0;
95  fSuperposed=NULL;
96  fShowRange=kFALSE;
97  fAngularLabels=kFALSE;
98  fAverageSlices=NULL;
99  fSegmentDisplay=kFALSE;
100  fNentries=0;
101  fFirstEntry=0;
102  fArraySize=0;
103  fCurrentEntries = NULL;
104  fFormulas = NULL;
105 }
106 
107 ////////////////////////////////////////////////////////////////////////////////
108 /// Normal constructor. Options are:
109 /// - "average"
110 /// - "showrange"
111 /// - "segment"
112 
113 TSpider::TSpider(TTree* tree ,const char *varexp, const char *selection,
114  Option_t *option, Long64_t nentries, Long64_t firstentry)
115  : TAttFill(2,3003), TAttLine(1,1,1)
116 {
117  UInt_t ui=0;
118 
119  fArraySize = 16;
120  fTree=tree;
121  fSelector= new TSelectorDraw();
122  fFormulas= new TList();
123  fInput= new TList();
124  fInput->Add(new TNamed("varexp",""));
125  fInput->Add(new TNamed("selection",""));
127  gROOT->GetListOfCleanups()->Add(this);
128  fNx=2;
129  fNy=2;
131  fSelect=NULL;
132  fManager=NULL;
133  fCanvas=NULL;
142  if (firstentry < 0 || firstentry > tree->GetEstimate()) firstentry = 0;
143  fFirstEntry = firstentry;
144  if (nentries>0) fNentries = nentries;
145  else fNentries = nentries = tree->GetEstimate()-firstentry;
146 
148 
150  fPolyList=NULL;
151 
154  for(ui=0;ui<fNx*fNy;++ui) fCurrentEntries[ui]=0;
155 
156  TString opt = option;
157 
158  if (opt.Contains("average")) fDisplayAverage=kTRUE;
159  if (opt.Contains("showrange")) fShowRange=kTRUE;
160  if (opt.Contains("segment")) fSegmentDisplay=kTRUE;
161 
162  fNcols=8;
163 
164  SetVariablesExpression(varexp);
165  SetSelectionExpression(selection);
166  SyncFormulas();
167  InitVariables(firstentry,nentries);
168 }
169 
170 ////////////////////////////////////////////////////////////////////////////////
171 /// Destructor.
172 
174 {
175  delete [] fCurrentEntries;
176  if(fPolyList){
177  fPolyList->Delete();
178  delete fPolyList;
179  }
180  if(fAverageSlices)
181  delete [] fAverageSlices;
182  if(fFormulas){
183  fFormulas->Delete();
184  delete fFormulas;
185  }
186  if(fSelect) delete fSelect;
187  if(fSelector) delete fSelector;
188  if(fInput){
189  fInput->Delete();
190  delete fInput;
191  }
192  if(fMax) delete [] fMax;
193  if(fMin) delete [] fMin;
194  if(fAve) delete [] fAve;
195  if(fSuperposed){
196  fSuperposed->Delete();
197  delete fSuperposed;
198  }
199  if (fCanvas) fCanvas->cd(0);
200 }
201 
202 ////////////////////////////////////////////////////////////////////////////////
203 /// Allow to superpose several spider views.
204 
206 {
207  if(!fSuperposed) fSuperposed=new TList();
208  fSuperposed->Add(sp);
209 }
210 
211 ////////////////////////////////////////////////////////////////////////////////
212 /// Add a variable to the plot from its expression.
213 
214 void TSpider::AddVariable(const char* varexp)
215 {
216  if(!varexp[0]) return;
217  TTreeFormula *fvar = new TTreeFormula("Var1",varexp,fTree);
218  if(fvar->GetNdim() <= 0) return;
219 
220  fFormulas->AddAfter(fFormulas->At(fNcols-1),fvar);
221 
222  InitArrays(fNcols + 1);
223  ++fNcols;
224  SyncFormulas();
225 
226  UInt_t ui=0;
227  Long64_t notSkipped=0;
228  Int_t tnumber=-1;
229  Long64_t entryNumber;
231  Int_t entriesToDisplay = fNentries;
232  while(entriesToDisplay!=0){
233  entryNumber = fTree->GetEntryNumber(entry);
234  if(entryNumber < 0) break;
235  Long64_t localEntry = fTree->LoadTree(entryNumber);
236  if(localEntry < 0) break;
237  if(tnumber != fTree->GetTreeNumber()) {
238  tnumber = fTree->GetTreeNumber();
240  else {
241  for(Int_t i=0;i<=fFormulas->LastIndex();++i)
242  ((TTreeFormula*)fFormulas->At(i))->UpdateFormulaLeaves();
243  }
244  }
245  Int_t ndata=1;
246  if(fForceDim){
247  if(fManager)
248  ndata = fManager->GetNdata(kTRUE);
249  else {
250  for(ui=0;ui<fNcols;++ui){
251  if(ndata<((TTreeFormula*)fFormulas->At(ui))->GetNdata())
252  ndata = ((TTreeFormula*)fFormulas->At(ui))->GetNdata();
253  }
254  if(fSelect && fSelect->GetNdata() == 0)
255  ndata = 0;
256  }
257  }
258 
259  Bool_t loaded = kFALSE;
260  Bool_t skip = kFALSE;
261  // Loop over the instances of the selection condition
262  for(Int_t inst=0;inst<ndata;++inst){
263  if(fSelect){
264  if(fSelect->EvalInstance(inst) == 0){
265  skip = kTRUE;
266  ++entry;
267  }
268  }
269  if (!loaded) {
270  // EvalInstance(0) always needs to be called so that
271  // the proper branches are loaded.
272  ((TTreeFormula*)fFormulas->At(fNcols-1))->EvalInstance(0);
273  loaded = kTRUE;
274  } else if (inst == 0) {
275  loaded = kTRUE;
276  }
277  }
278  if(!skip){
279  fTree->LoadTree(entryNumber);
281  if(var->EvalInstance()>fMax[fNcols-1]) fMax[fNcols-1]=var->EvalInstance();
282  if(var->EvalInstance()<fMin[fNcols-1]) fMin[fNcols-1]=var->EvalInstance();
283  fAve[fNcols-1]+=var->EvalInstance();
284  ++notSkipped;
285  --entriesToDisplay;
286  ++entry;
287  }
288  }
289  if (notSkipped) fAve[fNcols-1]/=notSkipped;
290 
291  Color_t lc;
292  Style_t lt;
293  Width_t lw;
294  Color_t fc;
295  Style_t fs;
296 
297  if(fAverageSlices){
298  lc = fAverageSlices[0]->GetLineColor();
299  lt = fAverageSlices[0]->GetLineStyle();
300  lw = fAverageSlices[0]->GetLineWidth();
301  fc = fAverageSlices[0]->GetFillColor();
302  fs = fAverageSlices[0]->GetFillStyle();
303  } else {
304  lc = fAveragePoly->GetLineColor();
305  lt = fAveragePoly->GetLineStyle();
306  lw = fAveragePoly->GetLineWidth();
307  fc = fAveragePoly->GetFillColor();
308  fs = fAveragePoly->GetFillStyle();
309  }
310 
311  delete fPolargram;
312  fPolargram = NULL;
313 
314  if(fSegmentDisplay){
315  for(ui=0;ui<fNx*fNy;++ui) ((TList*)fPolyList->At(ui))->Delete();
316  if (fAverageSlices) for(ui=0;ui<fNcols-1;++ui) delete fAverageSlices[ui];
317  }
318  fPolyList->Delete();
319  delete fPolyList;
320  fPolyList = NULL;
321  delete [] fAverageSlices;
323  delete fAveragePoly;
324  fAveragePoly = NULL;
325 
326  if (fCanvas) {
327  fCanvas->Clear();
328  fCanvas->Divide(fNx,fNy);
329  }
330  Draw("");
331 
332  if(fAverageSlices){
333  for(ui = 0;ui<fNcols;++ui){
334  fAverageSlices[ui]->SetLineColor(lc);
335  fAverageSlices[ui]->SetLineStyle(lt);
336  fAverageSlices[ui]->SetLineWidth(lw);
337  fAverageSlices[ui]->SetFillColor(fc);
338  fAverageSlices[ui]->SetFillStyle(fs);
339  }
340  } else {
346  }
347 }
348 
349 ////////////////////////////////////////////////////////////////////////////////
350 /// Delete a variable from its expression.
351 
352 void TSpider::DeleteVariable(const char* varexp)
353 {
354  Int_t var=-1;
355  UInt_t ui=0;
356 
357  if(fNcols == 2) return;
358  for(ui=0; ui<fNcols;++ui){
359  if(!strcmp(varexp,((TTreeFormula*)fFormulas->At(ui))->GetTitle())) var = ui;
360  }
361  if(var<0) return;
362 
363  fFormulas->Remove(fFormulas->At(var));
364  SyncFormulas();
365 
366  for(ui=var+1;ui<fNcols;++ui){
367  fMin[ui-1] = fMin[ui];
368  fMax[ui-1] = fMax[ui];
369  fAve[ui-1] = fAve[ui];
370  }
371  fMin[fNcols-1] = DBL_MAX;
372  fMax[fNcols-1] = -DBL_MAX;
373  fAve[fNcols-1] = 0;
374  --fNcols;
375 
376  Color_t lc;
377  Style_t lt;
378  Width_t lw;
379  Color_t fc;
380  Style_t fs;
381 
382  if(fAverageSlices){
383  lc = fAverageSlices[0]->GetLineColor();
384  lt = fAverageSlices[0]->GetLineStyle();
385  lw = fAverageSlices[0]->GetLineWidth();
386  fc = fAverageSlices[0]->GetFillColor();
387  fs = fAverageSlices[0]->GetFillStyle();
388  } else {
389  lc = fAveragePoly->GetLineColor();
390  lt = fAveragePoly->GetLineStyle();
391  lw = fAveragePoly->GetLineWidth();
392  fc = fAveragePoly->GetFillColor();
393  fs = fAveragePoly->GetFillStyle();
394  }
395 
396  delete fPolargram;
397  fPolargram = NULL;
398 
399  if(fSegmentDisplay){
400  for(ui=0;ui<fNx*fNy;++ui) ((TList*)fPolyList->At(ui))->Delete();
401  if (fAverageSlices) for(ui=0;ui<=fNcols;++ui) delete fAverageSlices[ui];
402  }
403  fPolyList->Delete();
404  delete fPolyList;
405  fPolyList = NULL;
406  delete [] fAverageSlices;
408  delete fAveragePoly;
409  fAveragePoly = NULL;
410 
411  if (fCanvas) {
412  fCanvas->Clear();
413  fCanvas->Divide(fNx,fNy);
414  }
415  Draw("");
416  if(fNcols == 2) SetSegmentDisplay(kTRUE);
417 
418  if(fAverageSlices){
419  for(ui = 0;ui<fNcols;++ui){
420  fAverageSlices[ui]->SetLineColor(lc);
421  fAverageSlices[ui]->SetLineStyle(lt);
422  fAverageSlices[ui]->SetLineWidth(lw);
423  fAverageSlices[ui]->SetFillColor(fc);
424  fAverageSlices[ui]->SetFillStyle(fs);
425  }
426  } else {
432  }
433 }
434 
435 ////////////////////////////////////////////////////////////////////////////////
436 /// Compute the distance to the spider.
437 
439 {
440  if(!gPad) return 9999;
441  Double_t xx,yy,r2;
442  xx=gPad->AbsPixeltoX(px);
443  yy=gPad->AbsPixeltoY(py);
444  r2 = xx*xx + yy*yy;
445  if(r2>1 && r2<1.5)
446  return 0;
447  else return 9999;
448 }
449 
450 ////////////////////////////////////////////////////////////////////////////////
451 /// Draw the spider.
452 
453 void TSpider::Draw(Option_t *options)
454 {
455  UInt_t ui=0;
456 
457  gEnv->SetValue("Canvas.ShowEditor",1);
458  if(!gPad && !fCanvas){
459  fCanvas = new TCanvas("screen","Spider Plot",fNx*256,fNy*256);
460  if (fCanvas) fCanvas->Divide(fNx,fNy);
461  } else if(!fCanvas){
462  fCanvas = (TCanvas*)gPad;
463  if (fCanvas) fCanvas->Divide(fNx,fNy);
464  }
465  if(fPolargram) delete fPolargram;
466  fPolargram=new TGraphPolargram("fPolargram");
469  if (fCanvas) fCanvas->cd();
471  AppendPad(options);
472  for(ui=0;ui<fNx*fNy;++ui){
473  if (fCanvas) fCanvas->cd(ui+1);
474  fPolargram->Draw("pn");
476  if(fSegmentDisplay){
478  DrawSlices("");
479  } else {
481  DrawPoly("");
482  }
483  AppendPad();
484  }
485  if (fCanvas) fCanvas->Selected(fCanvas,this,1);
486 }
487 
488 ////////////////////////////////////////////////////////////////////////////////
489 /// Paint the Polygon representing the average value of the variables.
490 
492 {
493  Int_t linecolor=4;
494  Int_t fillstyle=0;
495  Int_t fillcolor=linecolor;
496  Int_t linewidth=1;
497  Int_t linestyle=1;
498 
499  UInt_t ui=0;
500  Double_t slice = 2*TMath::Pi()/fNcols;
501  Double_t *x = new Double_t[fNcols+1];
502  Double_t *y = new Double_t[fNcols+1];
503 
504  for(ui=0;ui<fNcols;++ui){
505  x[ui]=(fAve[ui]-fMin[ui])/(fMax[ui]-fMin[ui])*TMath::Cos(ui*slice);
506  y[ui]=(fAve[ui]-fMin[ui])/(fMax[ui]-fMin[ui])*TMath::Sin(ui*slice);
507  }
508  x[fNcols]=(fAve[0]-fMin[0])/(fMax[0]-fMin[0]);
509  y[fNcols]=0;
510 
511  if(!fAveragePoly){
512  fAveragePoly = new TPolyLine(fNcols+1,x,y);
513  fAveragePoly->SetLineColor(linecolor);
514  fAveragePoly->SetLineWidth(linewidth);
515  fAveragePoly->SetLineStyle(linestyle);
516  fAveragePoly->SetFillStyle(fillstyle);
517  fAveragePoly->SetFillColor(fillcolor);
518  }
519  fAveragePoly->Draw();
520  fAveragePoly->Draw("f");
521 
522  delete [] x;
523  delete [] y;
524 }
525 
526 ////////////////////////////////////////////////////////////////////////////////
527 /// Paint the polygon representing the current entry.
528 
529 void TSpider::DrawPoly(Option_t* /*options*/)
530 {
531  if(!fPolyList) fPolyList = new TList();
532  Double_t *x = new Double_t[fNcols+1];
533  Double_t *y = new Double_t[fNcols+1];
534 
535  Double_t slice = 2*TMath::Pi()/fNcols;
536  for(UInt_t i=0;i<fNcols;++i){
537  x[i]=(((TTreeFormula*)fFormulas->At(i))->EvalInstance()-fMin[i])/(fMax[i]-fMin[i])*TMath::Cos(i*slice);
538  y[i]=(((TTreeFormula*)fFormulas->At(i))->EvalInstance()-fMin[i])/(fMax[i]-fMin[i])*TMath::Sin(i*slice);
539  }
540  x[fNcols]=(((TTreeFormula*)fFormulas->At(0))->EvalInstance()-fMin[0])/(fMax[0]-fMin[0]);
541  y[fNcols]=0;
542 
543  TPolyLine* poly= new TPolyLine(fNcols+1,x,y);
544  poly->SetFillColor(GetFillColor());
545  poly->SetFillStyle(GetFillStyle());
546  poly->SetLineWidth(GetLineWidth());
547  poly->SetLineColor(GetLineColor());
548  poly->SetLineStyle(GetLineStyle());
549  poly->Draw("f");
550  poly->Draw();
551  fPolyList->Add(poly);
552  delete [] x;
553  delete [] y;
554 }
555 
556 ////////////////////////////////////////////////////////////////////////////////
557 /// Draw the slices of the segment plot.
558 
560 {
561  UInt_t ui=0;
562 
563  Double_t angle = 2*TMath::Pi()/fNcols;
564  Double_t conv = 180.0/TMath::Pi();
565 
566  if(!fPolyList) fPolyList = new TList;
567  TList* li = new TList();
568  for(ui=0;ui<fNcols;++ui){
569  Double_t r = (((TTreeFormula*)fFormulas->At(ui))->EvalInstance()-fMin[ui])/(fMax[ui]-fMin[ui]);
570  TArc* slice = new TArc(0,0,r,(ui-0.25)*angle*conv,(ui+0.25)*angle*conv);
571  slice->SetFillColor(GetFillColor());
572  slice->SetFillStyle(GetFillStyle());
573  slice->SetLineWidth(GetLineWidth());
574  slice->SetLineColor(GetLineColor());
575  slice->SetLineStyle(GetLineStyle());
576  li->Add(slice);
577  slice->Draw(options);
578  }
579  fPolyList->Add(li);
580 }
581 
582 ////////////////////////////////////////////////////////////////////////////////
583 /// Draw the slices representing the average for the segment plot.
584 
586 {
587  UInt_t ui=0;
588 
589  Int_t fillstyle=3002;
590  Int_t linecolor=4;
591  Int_t fillcolor=linecolor;
592  Int_t linewidth=1;
593  Int_t linestyle=1;
594 
595  Double_t angle = 2*TMath::Pi()/fNcols;
596  Double_t conv = 180.0/TMath::Pi();
597 
598  if(!fAverageSlices){
599  fAverageSlices = new TArc*[fNcols];
600  for(ui=0;ui<fNcols;++ui){
601  Double_t r = (fAve[ui]-fMin[ui])/(fMax[ui]-fMin[ui]);
602  fAverageSlices[ui] = new TArc(0,0,r,(ui-0.5)*angle*conv,(ui+0.5)*angle*conv);
603  fAverageSlices[ui]->SetFillColor(fillcolor);
604  fAverageSlices[ui]->SetFillStyle(fillstyle);
605  fAverageSlices[ui]->SetLineWidth(linewidth);
606  fAverageSlices[ui]->SetLineColor(linecolor);
607  fAverageSlices[ui]->SetLineStyle(linestyle);
608  }
609  }
610  for(ui=0;ui<fNcols;++ui) fAverageSlices[ui]->Draw();
611 }
612 
613 ////////////////////////////////////////////////////////////////////////////////
614 /// Get the LineStyle of the average.
615 
617 {
618  if(fAverageSlices) return fAverageSlices[0]->GetLineStyle();
619  else if(fAveragePoly) return fAveragePoly->GetLineStyle();
620  else return 0;
621 }
622 
623 ////////////////////////////////////////////////////////////////////////////////
624 /// Get the LineColor of the average.
625 
627 {
628  if(fAverageSlices) return fAverageSlices[0]->GetLineColor();
629  else if(fAveragePoly) return fAveragePoly->GetLineColor();
630  else return 0;
631 }
632 
633 ////////////////////////////////////////////////////////////////////////////////
634 /// Get the LineWidth of the average.
635 
637 {
638  if(fAverageSlices) return fAverageSlices[0]->GetLineWidth();
639  else if(fAveragePoly) return fAveragePoly->GetLineWidth();
640  else return 0;
641 }
642 
643 ////////////////////////////////////////////////////////////////////////////////
644 /// Get the Fill Color of the average.
645 
647 {
648  if(fAverageSlices) return fAverageSlices[0]->GetFillColor();
649  else if(fAveragePoly) return fAveragePoly->GetFillColor();
650  else return 0;
651 }
652 
653 ////////////////////////////////////////////////////////////////////////////////
654 /// Get the FillStyle of the average.
655 
657 {
658  if(fAverageSlices) return fAverageSlices[0]->GetFillStyle();
659  else if(fAveragePoly) return fAveragePoly->GetFillStyle();
660  else return 0;
661 }
662 
663 ////////////////////////////////////////////////////////////////////////////////
664 /// Execute the corresponding event.
665 
666 void TSpider::ExecuteEvent(Int_t /*event*/,Int_t /*px*/, Int_t /*py*/)
667 {
668  if (!gPad) return;
669  gPad->SetCursor(kHand);
670 }
671 
672 ////////////////////////////////////////////////////////////////////////////////
673 /// Find the alignement rule to apply for TText::SetTextAlign(Short_t).
674 
676 {
677  Double_t pi = TMath::Pi();
678 
679  while(angle < 0 || angle > 2*pi){
680  if(angle < 0) angle+=2*pi;
681  if(angle > 2*pi) angle-=2*pi;
682  }
683  if(!fAngularLabels){
684  if(angle > 0 && angle < pi/2) return 11;
685  else if(angle > pi/2 && angle < pi) return 31;
686  else if(angle > pi && angle < 3*pi/2) return 33;
687  else if(angle > 3*pi/2 && angle < 2*pi) return 13;
688  else if(angle == 0 || angle == 2*pi) return 12;
689  else if(angle == pi/2) return 21;
690  else if(angle == pi) return 32;
691  else if(angle == 3*pi/2) return 23;
692  else return 0;
693  }
694  else{
695  if(angle >= 0 && angle < pi) return 21;
696  else if(angle >=pi && angle <= 2*pi) return 23;
697  else return 0;
698  }
699 }
700 
701 ////////////////////////////////////////////////////////////////////////////////
702 /// Determine the orientation of the polar labels according to their angle.
703 
705 {
706  Double_t pi = TMath::Pi();
707  Double_t convraddeg = 180.0/pi;
708 
709  while(angle < 0 || angle > 2*pi){
710  if(angle < 0) angle+=2*pi;
711  if(angle > 2*pi) angle-=2*pi;
712  }
713 
714  if(angle >= 0 && angle <= pi/2) return angle*convraddeg - 90;
715  else if(angle > pi/2 && angle <= pi) return (angle + pi)*convraddeg + 90;
716  else if(angle > pi && angle <= 3*pi/2) return (angle - pi)*convraddeg - 90;
717  else if(angle > 3*pi/2 && angle <= 2*pi) return angle*convraddeg + 90;
718  else return 0;
719 }
720 
721 ////////////////////////////////////////////////////////////////////////////////
722 /// return the number of entries to be processed
723 /// this function checks that nentries is not bigger than the number
724 /// of entries in the Tree or in the associated TEventlist
725 
727 {
728  Long64_t lastentry = firstentry + nentries - 1;
729  if (lastentry > fTree->GetEntriesFriend()-1) {
730  lastentry = fTree->GetEntriesFriend() - 1;
731  nentries = lastentry - firstentry + 1;
732  }
733  //TEventList *elist = fTree->GetEventList();
734  //if (elist && elist->GetN() < nentries) nentries = elist->GetN();
735  TEntryList *elist = fTree->GetEntryList();
736  if (elist && elist->GetN() < nentries) nentries = elist->GetN();
737  return nentries;
738 }
739 
740 ////////////////////////////////////////////////////////////////////////////////
741 /// Go to a specified entry.
742 
744 {
745  if(e<fFirstEntry || e+fTree->GetScanField()>=fFirstEntry + fNentries) return;
746  fEntry = e;
748 }
749 
750 ////////////////////////////////////////////////////////////////////////////////
751 /// Go to the next entries.
752 
754 {
758 }
759 
760 ////////////////////////////////////////////////////////////////////////////////
761 /// Go to the previous entries.
762 
764 {
766  else fEntry -= fTree->GetScanField();
768 }
769 
770 ////////////////////////////////////////////////////////////////////////////////
771 /// Go to the next entry.
772 
774 {
775  if(fEntry + fTree->GetScanField() >= fFirstEntry + fNentries) return;
776  ++fEntry;
778 }
779 
780 ////////////////////////////////////////////////////////////////////////////////
781 /// Go to the last entry.
782 
784 {
785  if(fEntry - 1 < fFirstEntry) return;
786  --fEntry;
788 }
789 
790 ////////////////////////////////////////////////////////////////////////////////
791 /// Check if the arrays size is enough and reallocate them if not.
792 
794 {
795  if(newsize>fArraySize){
796 
797  Int_t i;
798  Int_t old = fArraySize;
799 
800  while(fArraySize<newsize) fArraySize*=2;
801 
802  Double_t *memmax = new Double_t[fArraySize];
803  Double_t *memmin = new Double_t[fArraySize];
804  Double_t *memave = new Double_t[fArraySize];
805 
806  for(i=0;i<fArraySize;++i){
807  if(i<old){
808  memmax[i] = fMax[i];
809  memmin[i] = fMin[i];
810  memave[i] = fAve[i];
811  } else {
812  memmax[i] = -DBL_MAX;
813  memmin[i] = DBL_MAX;
814  memave[i] = 0;
815  }
816  }
817 
818  delete [] fMax;
819  delete [] fMin;
820  delete [] fAve;
821 
822  fMax = memmax;
823  fMin = memmin;
824  fAve = memave;
825  }
826 }
827 
828 ////////////////////////////////////////////////////////////////////////////////
829 /// Browse the tree to set the min, max and average value of each variable of fVar.
830 
832 {
833  UInt_t ui=0;
834  Int_t i;
835 
836  fMax = new Double_t [fArraySize];
837  fMin= new Double_t [fArraySize];
838  fAve= new Double_t [fArraySize];
839 
840  for(i=0;i<fArraySize;++i){
841  fMax[i]= -DBL_MAX;
842  fMin[i]= DBL_MAX;
843  fAve[i]=0;
844  }
845 
846  Long64_t notSkipped=0;
847  Int_t tnumber=-1;
848  Long64_t entryNumber;
849  Long64_t entry = firstentry;
850  Int_t entriesToDisplay = nentries;
851  while(entriesToDisplay!=0){
852  entryNumber = fTree->GetEntryNumber(entry);
853  if(entryNumber < 0) break;
854  Long64_t localEntry = fTree->LoadTree(entryNumber);
855  if(localEntry < 0) break;
856  if(tnumber != fTree->GetTreeNumber()) {
857  tnumber = fTree->GetTreeNumber();
859  else {
860  for(i=0;i<=fFormulas->LastIndex();++i)
861  ((TTreeFormula*)fFormulas->At(i))->UpdateFormulaLeaves();
862  }
863  }
864  Int_t ndata=1;
865  if(fForceDim){
866  if(fManager)
867  ndata = fManager->GetNdata(kTRUE);
868  else {
869  for(ui=0;ui<fNcols;++ui){
870  if(ndata<((TTreeFormula*)fFormulas->At(ui))->GetNdata())
871  ndata = ((TTreeFormula*)fFormulas->At(ui))->GetNdata();
872  }
873  if(fSelect && fSelect->GetNdata() == 0)
874  ndata = 0;
875  }
876  }
877  Bool_t loaded = kFALSE;
878  Bool_t skip = kFALSE;
879  // Loop over the instances of the selection condition
880  for(Int_t inst=0;inst<ndata;++inst){
881  if(fSelect){
882  if(fSelect->EvalInstance(inst) == 0){
883  skip = kTRUE;
884  ++entry;
885  }
886  }
887  if (!loaded) {
888  // EvalInstance(0) always needs to be called so that
889  // the proper branches are loaded.
890  for (ui=0;ui<fNcols;ui++) {
891  ((TTreeFormula*)fFormulas->At(ui))->EvalInstance(0);
892  }
893  loaded = kTRUE;
894  } else if (inst == 0) {
895  loaded = kTRUE;
896  }
897  }
898  if(!skip){
899  fTree->LoadTree(entryNumber);
900  for(ui=0;ui<fNcols;++ui){
901  Double_t inst = ((TTreeFormula*)fFormulas->At(ui))->EvalInstance();
902  if(inst > fMax[ui]) fMax[ui] = inst;
903  if(inst < fMin[ui]) fMin[ui] = inst;
904  fAve[ui] += inst;
905  }
906  ++notSkipped;
907  --entriesToDisplay;
908  ++entry;
909  }
910  }
911  if (notSkipped) {for(ui=0;ui<fNcols;++ui) fAve[ui]/=notSkipped;}
912 }
913 
914 ////////////////////////////////////////////////////////////////////////////////
915 /// Paint the spider.
916 
917 void TSpider::Paint(Option_t* options)
918 {
919  UInt_t ui=0;
920  TString opt = options;
921 
922  if(opt.Contains("n")) return;
923 
924  Double_t slice = 2*TMath::Pi()/fNcols;
925  Double_t offset(1.0);
926  if (!fCanvas) {
927  if (gPad) fCanvas = gPad->GetCanvas();
928  else return;
929  }
930 
931  TLatex *txt = new TLatex();
932  for(ui=0;ui<fNx*fNy;++ui){
933  txt->SetTextAlign(13);
934  if (fCanvas) fCanvas->cd(ui+1);
935  if (fCurrentEntries) {
936  txt->PaintLatex(-1.2,1.2,0,0.08,Form("#%d",(int)fCurrentEntries[ui]));
937  }
938  txt->SetTextSize(0.035);
939  for(UInt_t var=0;var<fNcols;++var){ // Print labels.
940  if(ui==0){
941  txt->SetTextAlign(FindTextAlign(var*slice));
942  offset = 1.09 + txt->GetTextSize();
943  txt->PaintLatex(offset*TMath::Cos(var*slice),offset*TMath::Sin(var*slice),
944  FindTextAngle(var*slice),0.035,fFormulas->At(var)->GetTitle());
945  offset= 1.03;
946  txt->PaintLatex(offset*TMath::Cos(var*slice),offset*TMath::Sin(var*slice),
947  FindTextAngle(var*slice),0.035,Form("[%5.3f,%5.3f]",fMin[var],fMax[var]));
948  }
949  else {
950  txt->SetTextAlign(FindTextAlign(var*slice));
951  if(var*slice >=0 && var*slice <= TMath::Pi()) offset =1.13 + txt->GetTextSize();
952  else offset = 1.09 + txt->GetTextSize();
953  txt->PaintLatex(offset*TMath::Cos(var*slice),offset*TMath::Sin(var*slice),
954  FindTextAngle(var*slice),0.035,fFormulas->At(var)->GetTitle());
955  }
956  }
957  }
958  delete txt;
959 }
960 
961 ////////////////////////////////////////////////////////////////////////////////
962 /// Set the LineStyle of the average.
963 
965 {
966  UInt_t ui=0;
967 
968  if(fAverageSlices){
969  for(ui=0;ui<fNcols;++ui) fAverageSlices[ui]->SetLineStyle(sty);
970  } else if(fAveragePoly) fAveragePoly->SetLineStyle(sty);
971 }
972 
973 ////////////////////////////////////////////////////////////////////////////////
974 /// Set the LineColor of the average.
975 
977 {
978  UInt_t ui=0;
979 
980  if(fAverageSlices){
981  for(ui=0;ui<fNcols;++ui) fAverageSlices[ui]->SetLineColor(col);
982  } else if(fAveragePoly) fAveragePoly->SetLineColor(col);
983 }
984 
985 ////////////////////////////////////////////////////////////////////////////////
986 /// Set the LineWidth of the average.
987 
989 {
990  UInt_t ui=0;
991 
992  if(fAverageSlices){
993  for(ui=0;ui<fNcols;++ui) fAverageSlices[ui]->SetLineWidth(wid);
994  } else if(fAveragePoly) fAveragePoly->SetLineWidth(wid);
995 }
996 
997 ////////////////////////////////////////////////////////////////////////////////
998 /// Set the Fill Color of the average.
999 
1001 {
1002  UInt_t ui=0;
1003 
1004  if(fAverageSlices){
1005  for(ui=0;ui<fNcols;++ui) fAverageSlices[ui]->SetFillColor(col);
1006  } else if(fAveragePoly) fAveragePoly->SetFillColor(col);
1007 }
1008 
1009 ////////////////////////////////////////////////////////////////////////////////
1010 /// Set the FillStyle of the average.
1011 
1013 {
1014  UInt_t ui=0;
1015 
1016  if(fAverageSlices){
1017  for(ui=0;ui<fNcols;++ui) fAverageSlices[ui]->SetFillStyle(sty);
1018  } else if(fAveragePoly) fAveragePoly->SetFillStyle(sty);
1019 }
1020 
1021 ////////////////////////////////////////////////////////////////////////////////
1022 /// Display or not the average.
1023 
1025 {
1026  if(disp == fDisplayAverage) return;
1027 
1028  UInt_t ui=0;
1029 
1030  fDisplayAverage = disp;
1031  delete fAveragePoly;
1032  fAveragePoly = NULL;
1033  if(fAverageSlices){
1034  for(ui = 0;ui<fNcols;++ui) delete fAverageSlices[ui];
1035  }
1036  delete [] fAverageSlices;
1037  fAverageSlices = NULL;
1038 
1039  for(ui=0;ui<fNx*fNy;++ui){
1040  if (fCanvas) fCanvas->cd(ui+1);
1041  gPad->Clear();
1042  }
1043 
1044  for(ui = 0; ui < fNx*fNy; ++ui){
1045  if (fCanvas) fCanvas->cd(ui+1);
1046  fPolargram->Draw("pn");
1048  if(fSegmentDisplay){
1049  if(disp) DrawSlicesAverage("");
1050  DrawSlices("");
1051  } else {
1052  if(disp) DrawPolyAverage("");
1053  DrawPoly("");
1054  }
1055  AppendPad();
1056  }
1057  if (fCanvas) {
1058  fCanvas->Modified();
1059  fCanvas->Update();
1060  }
1061 }
1062 
1063 ////////////////////////////////////////////////////////////////////////////////
1064 /// Set the current selected entries.
1065 
1067 {
1068  Int_t i;
1069  UInt_t ui=0;
1070  Int_t tnumber=-1;
1071  Long64_t entryNumber;
1072  Long64_t entry = fEntry;
1073  Int_t entriesToDisplay = fTree->GetScanField();
1074 
1076 
1077  while(entriesToDisplay!=0){
1078  entryNumber = fTree->GetEntryNumber(entry);
1079  if(entryNumber < 0) break;
1080  Long64_t localEntry = fTree->LoadTree(entryNumber);
1081  if(localEntry < 0) break;
1082  if(tnumber != fTree->GetTreeNumber()) {
1083  tnumber = fTree->GetTreeNumber();
1085  else {
1086  for(i=0;i<=fFormulas->LastIndex();++i)
1087  ((TTreeFormula*)fFormulas->At(i))->UpdateFormulaLeaves();
1088  }
1089  }
1090  Int_t ndata=1;
1091  if(fForceDim){
1092  if(fManager)
1093  ndata = fManager->GetNdata(kTRUE);
1094  else {
1095  for(ui=0;ui<fNcols;++ui){
1096  if(ndata < ((TTreeFormula*)fFormulas->At(ui))->GetNdata())
1097  ndata = ((TTreeFormula*)fFormulas->At(ui))->GetNdata();
1098  }
1099  if(fSelect && fSelect->GetNdata() == 0)
1100  ndata = 0;
1101  }
1102  }
1103  Bool_t loaded = kFALSE;
1104  Bool_t skip = kFALSE;
1105  // Loop over the instances of the selection condition
1106  for(Int_t inst=0;inst<ndata;++inst){
1107  if(fSelect){
1108  if(fSelect->EvalInstance(inst) == 0){
1109  skip = kTRUE;
1110  ++entry;
1111  }
1112  }
1113  if (!loaded) {
1114  // EvalInstance(0) always needs to be called so that
1115  // the proper branches are loaded.
1116  for (ui=0;ui<fNcols;ui++) {
1117  ((TTreeFormula*)fFormulas->At(ui))->EvalInstance(0);
1118  }
1119  loaded = kTRUE;
1120  } else if (inst == 0) {
1121  loaded = kTRUE;
1122  }
1123  }
1124  if(!skip){
1125  fCurrentEntries[fTree->GetScanField()-entriesToDisplay] = entryNumber;
1126  --entriesToDisplay;
1127  ++entry;
1128  }
1129  }
1130  if(fPolyList) UpdateView();
1131 }
1132 
1133 ////////////////////////////////////////////////////////////////////////////////
1134 /// Set line style.
1135 
1137 {
1138  UInt_t ui=0;
1139 
1141  for(ui=0; ui<fNx*fNy;++ui){
1142  if(fSegmentDisplay){
1143  TList *li = (TList*)fPolyList->At(ui);
1144  for(UInt_t var=0;var<fNcols;++var) ((TArc*)li->At(var))->SetLineStyle(sty);
1145  } else ((TPolyLine*)fPolyList->At(ui))->SetLineStyle(sty);
1146  }
1147 }
1148 
1149 ////////////////////////////////////////////////////////////////////////////////
1150 /// Set lin color.
1151 
1153 {
1154  UInt_t ui=0;
1155 
1157  for(ui=0; ui<fNx*fNy;++ui){
1158  if(fSegmentDisplay){
1159  TList *li = (TList*)fPolyList->At(ui);
1160  for(UInt_t var=0;var<fNcols;++var) ((TArc*)li->At(var))->SetLineColor(col);
1161  } else ((TPolyLine*)fPolyList->At(ui))->SetLineColor(col);
1162  }
1163 }
1164 
1165 ////////////////////////////////////////////////////////////////////////////////
1166 ///Set line width.
1167 
1169 {
1170  UInt_t ui=0;
1171 
1173  for(ui=0; ui<fNx*fNy;++ui){
1174  if(fSegmentDisplay){
1175  TList *li = (TList*)fPolyList->At(ui);
1176  for(UInt_t var=0;var<fNcols;++var) ((TArc*)li->At(var))->SetLineWidth(wid);
1177  } else ((TPolyLine*)fPolyList->At(ui))->SetLineWidth(wid);
1178  }
1179 }
1180 
1181 ////////////////////////////////////////////////////////////////////////////////
1182 /// Set fill color.
1183 
1185 {
1186  UInt_t ui=0;
1187 
1189  for(ui=0; ui<fNx*fNy;++ui){
1190  if(fSegmentDisplay){
1191  TList *li = (TList*)fPolyList->At(ui);
1192  for(UInt_t var=0;var<fNcols;++var) ((TArc*)li->At(var))->SetFillColor(col);
1193  } else ((TPolyLine*)fPolyList->At(ui))->SetFillColor(col);
1194  }
1195 }
1196 
1197 ////////////////////////////////////////////////////////////////////////////////
1198 /// Set fill style.
1199 
1201 {
1202  UInt_t ui=0;
1203 
1205  for(ui=0; ui<fNx*fNy;++ui){
1206  if(fSegmentDisplay){
1207  TList *li = (TList*)fPolyList->At(ui);
1208  for(UInt_t var=0;var<fNcols;++var) ((TArc*)li->At(var))->SetFillStyle(sty);
1209  } else ((TPolyLine*)fPolyList->At(ui))->SetFillStyle(sty);
1210  }
1211 }
1212 
1213 ////////////////////////////////////////////////////////////////////////////////
1214 /// Set number of radial divisions.
1215 
1217 {
1218  if(fPolargram->GetNdivRadial() == ndiv) return;
1219  fPolargram->SetNdivRadial(ndiv);
1220 }
1221 
1222 ////////////////////////////////////////////////////////////////////////////////
1223 /// Set the X number of sub pads.
1224 
1226 {
1227  if(fNx == nx || nx <= 0) return;
1228  fEntry = fCurrentEntries[0];
1229 
1230  UInt_t ui=0;
1231  Color_t lc;
1232  Style_t lt;
1233  Width_t lw;
1234  Color_t fc;
1235  Style_t fs;
1236  if(fAverageSlices){
1237  lc = fAverageSlices[0]->GetLineColor();
1238  lt = fAverageSlices[0]->GetLineStyle();
1239  lw = fAverageSlices[0]->GetLineWidth();
1240  fc = fAverageSlices[0]->GetFillColor();
1241  fs = fAverageSlices[0]->GetFillStyle();
1242  } else {
1243  lc = fAveragePoly->GetLineColor();
1244  lt = fAveragePoly->GetLineStyle();
1245  lw = fAveragePoly->GetLineWidth();
1246  fc = fAveragePoly->GetFillColor();
1247  fs = fAveragePoly->GetFillStyle();
1248  }
1249 
1250  if(fSegmentDisplay){
1251  for(ui=0; ui<fNx*fNy;++ui) ((TList*)fPolyList->At(ui))->Delete();
1252  }
1253  fPolyList->Delete();
1254  delete fPolyList;
1255  fPolyList = NULL;
1256  delete [] fCurrentEntries;
1258 
1259  fNx = nx;
1260 
1263  if (fCanvas) {
1264  fCanvas->Clear();
1265  fCanvas->Divide(fNx,fNy);
1266  }
1267 
1268  for(ui=0; ui < fNx*fNy;++ui){
1269  if (fCanvas) fCanvas->cd(ui+1);
1270  fPolargram->Draw("pn");
1272  if(fSegmentDisplay){
1274  DrawSlices("");
1275  } else {
1277  DrawPoly("");
1278  }
1279  AppendPad();
1280  }
1281 
1282  if(fAverageSlices){
1283  for(ui = 0;ui<fNcols;++ui){
1284  fAverageSlices[ui]->SetLineColor(lc);
1285  fAverageSlices[ui]->SetLineStyle(lt);
1286  fAverageSlices[ui]->SetLineWidth(lw);
1287  fAverageSlices[ui]->SetFillColor(fc);
1288  fAverageSlices[ui]->SetFillStyle(fs);
1289  }
1290  } else {
1296  }
1297 }
1298 
1299 ////////////////////////////////////////////////////////////////////////////////
1300 /// Set the Y number of sub pads.
1301 
1303 {
1304  if(fNy == ny || ny <= 0) return;
1305  fEntry = fCurrentEntries[0];
1306 
1307  UInt_t ui=0;
1308  Color_t lc;
1309  Style_t lt;
1310  Width_t lw;
1311  Color_t fc;
1312  Style_t fs;
1313  if(fAverageSlices){
1314  lc = fAverageSlices[0]->GetLineColor();
1315  lt = fAverageSlices[0]->GetLineStyle();
1316  lw = fAverageSlices[0]->GetLineWidth();
1317  fc = fAverageSlices[0]->GetFillColor();
1318  fs = fAverageSlices[0]->GetFillStyle();
1319  } else {
1320  lc = fAveragePoly->GetLineColor();
1321  lt = fAveragePoly->GetLineStyle();
1322  lw = fAveragePoly->GetLineWidth();
1323  fc = fAveragePoly->GetFillColor();
1324  fs = fAveragePoly->GetFillStyle();
1325  }
1326 
1327  if(fSegmentDisplay){
1328  for(ui=0; ui<fNx*fNy;++ui) ((TList*)fPolyList->At(ui))->Delete();
1329  }
1330  fPolyList->Delete();
1331  delete fPolyList;
1332  fPolyList = NULL;
1333  delete [] fCurrentEntries;
1335 
1336  fNy = ny;
1337 
1340  if (fCanvas) {
1341  fCanvas->Clear();
1342  fCanvas->Divide(fNx,fNy);
1343  }
1344 
1345  for(ui=0; ui < fNx*fNy;++ui){
1346  if (fCanvas) fCanvas->cd(ui+1);
1347  fPolargram->Draw("pn");
1349  if(fSegmentDisplay){
1351  DrawSlices("");
1352  } else {
1354  DrawPoly("");
1355  }
1356  AppendPad();
1357  }
1358 
1359  if(fAverageSlices){
1360  for(ui = 0;ui<fNcols;++ui){
1361  fAverageSlices[ui]->SetLineColor(lc);
1362  fAverageSlices[ui]->SetLineStyle(lt);
1363  fAverageSlices[ui]->SetLineWidth(lw);
1364  fAverageSlices[ui]->SetFillColor(fc);
1365  fAverageSlices[ui]->SetFillStyle(fs);
1366  }
1367  } else {
1373  }
1374 }
1375 
1376 ////////////////////////////////////////////////////////////////////////////////
1377 /// Set the segment display or not.
1378 
1380 {
1381  if(seg == fSegmentDisplay) return;
1382 
1383  UInt_t ui=0;
1384 
1385  if(fSegmentDisplay){
1386  for(ui=0;ui<fNx*fNy;++ui){
1387  ((TList*)fPolyList->At(ui))->Delete();
1388  }
1389  }
1390  fPolyList->Delete();
1391 
1392  Color_t lc;
1393  Style_t lt;
1394  Width_t lw;
1395  Color_t fc;
1396  Style_t fs;
1397  if(fAverageSlices){
1398  lc = fAverageSlices[0]->GetLineColor();
1399  lt = fAverageSlices[0]->GetLineStyle();
1400  lw = fAverageSlices[0]->GetLineWidth();
1401  fc = fAverageSlices[0]->GetFillColor();
1402  fs = fAverageSlices[0]->GetFillStyle();
1403  } else {
1404  lc = fAveragePoly->GetLineColor();
1405  lt = fAveragePoly->GetLineStyle();
1406  lw = fAveragePoly->GetLineWidth();
1407  fc = fAveragePoly->GetFillColor();
1408  fs = fAveragePoly->GetFillStyle();
1409  }
1410  delete fPolyList;
1411  fPolyList = NULL;
1412  if(fAverageSlices){
1413  for(ui=0;ui<fNcols;++ui) delete fAverageSlices[ui];
1414  }
1415  delete [] fAverageSlices;
1416  fAverageSlices = NULL;
1417  delete fAveragePoly;
1418  fAveragePoly = NULL;
1419 
1420  for(ui=0;ui<fNx*fNy;++ui){
1421  if (fCanvas) fCanvas->cd(ui+1);
1422  gPad->Clear();
1423  }
1424 
1425  fSegmentDisplay = seg;
1426 
1427  for(ui=0; ui < fNx*fNy;++ui){
1428  if (fCanvas) fCanvas->cd(ui+1);
1429  fPolargram->Draw("pn");
1431  if(fSegmentDisplay){
1433  DrawSlices("");
1434  } else {
1436  DrawPoly("");
1437  }
1438  AppendPad();
1439  }
1440 
1441  if(fAverageSlices){
1442  for(ui=0;ui<fNcols;++ui){
1443  fAverageSlices[ui]->SetLineColor(lc);
1444  fAverageSlices[ui]->SetLineStyle(lt);
1445  fAverageSlices[ui]->SetLineWidth(lw);
1446  fAverageSlices[ui]->SetFillColor(fc);
1447  fAverageSlices[ui]->SetFillStyle(fs);
1448  }
1449  } else {
1455  }
1456  if (fCanvas) {
1457  fCanvas->Modified();
1458  fCanvas->Update();
1459  }
1460 }
1461 
1462 ////////////////////////////////////////////////////////////////////////////////
1463 /// Compile selection expression if there is one.
1464 
1465 void TSpider::SetSelectionExpression(const char* selection)
1466 {
1467  if (selection && strlen(selection)) {
1468  fSelect = new TTreeFormula("Selection",selection,fTree);
1469  // if (!fSelect) return -1;
1470  // if (!fSelect->GetNdim()) { delete fSelect; return -1; }
1471  fFormulas->Add(fSelect);
1472  }
1473 }
1474 
1475 ////////////////////////////////////////////////////////////////////////////////
1476 /// Compile the variables expression from the given string varexp.
1477 
1478 void TSpider::SetVariablesExpression(const char* varexp)
1479 {
1480  Int_t nch;
1481  fNcols=8;
1482 
1483  if (!varexp) return;
1484  TObjArray *leaves = fTree->GetListOfLeaves();
1485  UInt_t nleaves = leaves->GetEntriesFast();
1486  if (nleaves < fNcols) fNcols = nleaves;
1487  nch = strlen(varexp);
1488 
1489  // if varexp is empty, take first 8 columns by default
1490  Int_t allvar = 0;
1491  std::vector<TString> cnames;
1492  if (!strcmp(varexp, "*")) { fNcols = nleaves; allvar = 1; }
1493  if (nch == 0 || allvar) {
1494  UInt_t ncs = fNcols;
1495  fNcols = 0;
1496  for (UInt_t ui=0;ui<ncs;++ui) {
1497  TLeaf *lf = (TLeaf*)leaves->At(ui);
1498  if (lf->GetBranch()->GetListOfBranches()->GetEntries() > 0) continue;
1499  cnames.push_back(lf->GetName());
1500  fNcols++;
1501  }
1502  // otherwise select only the specified columns
1503  } else {
1504  fNcols = fSelector->SplitNames(varexp,cnames);
1505  }
1506 
1507  // Create the TreeFormula objects corresponding to each column
1508  for (UInt_t ui=0;ui<fNcols;ui++) {
1509  fFormulas->Add(new TTreeFormula("Var1",cnames[ui].Data(),fTree));
1510  }
1511 }
1512 
1513 ////////////////////////////////////////////////////////////////////////////////
1514 /// Create a TreeFormulaManager to coordinate the formulas.
1515 
1517 {
1518  Int_t i;
1519  if (fFormulas->LastIndex()>=0) {
1520  if (fSelect) {
1521  if (fSelect->GetManager()->GetMultiplicity() > 0 ) {
1523  for(i=0;i<=fFormulas->LastIndex();i++) {
1525  }
1526  fManager->Sync();
1527  }
1528  }
1529  for(i=0;i<=fFormulas->LastIndex();i++) {
1530  TTreeFormula *form = ((TTreeFormula*)fFormulas->At(i));
1531  switch( form->GetManager()->GetMultiplicity() ) {
1532  case 1:
1533  case 2:
1534  case -1:
1535  fForceDim = kTRUE;
1536  break;
1537  case 0:
1538  break;
1539  }
1540 
1541  }
1542  }
1543 }
1544 
1545 ////////////////////////////////////////////////////////////////////////////////
1546 /// Update the polylines or the arcs for the current entries.
1547 
1549 {
1550  Double_t slice = 2*TMath::Pi()/fNcols;
1551 
1552  Double_t x,y,r;
1553 
1554  for(UInt_t pad=1;pad <= fNx*fNy;++pad){
1556  for(UInt_t i=0;i<fNcols;++i){
1557  r = (((TTreeFormula*)fFormulas->At(i))->EvalInstance()-fMin[i])/(fMax[i]-fMin[i]);
1558  x=r*TMath::Cos(i*slice);
1559  y=r*TMath::Sin(i*slice);
1560  if(!fSegmentDisplay) ((TPolyLine*)fPolyList->At(pad-1))->SetPoint(i,x,y);
1561  else {
1562  ((TArc*)((TList*)fPolyList->At(pad-1))->At(i))->SetR1(r);
1563  ((TArc*)((TList*)fPolyList->At(pad-1))->At(i))->SetR2(r);
1564  }
1565  }
1566  x=(((TTreeFormula*)fFormulas->At(0))->EvalInstance()-fMin[0])/(fMax[0]-fMin[0]);
1567  y=0;
1568  if(!fSegmentDisplay) ((TPolyLine*)fPolyList->At(pad-1))->SetPoint(fNcols,x,y);
1569  }
1570 }
const int nx
Definition: kalman.C:16
const int ndata
virtual void SetLineColor(Color_t col)
Set lin color.
Definition: TSpider.cxx:1152
virtual Style_t GetLineStyle() const
Definition: TAttLine.h:48
void DrawPoly(Option_t *options)
Paint the polygon representing the current entry.
Definition: TSpider.cxx:529
virtual Style_t GetFillStyle() const
Definition: TAttFill.h:44
A TLeaf describes individual elements of a TBranch See TBranch structure in TTree.
Definition: TLeaf.h:37
virtual void SetLineWidth(Width_t lwidth)
Definition: TAttLine.h:57
Double_t * fMax
Definition: TSpider.h:63
An array of TObjects.
Definition: TObjArray.h:39
virtual void Selected(TVirtualPad *pad, TObject *obj, Int_t event)
Emit Selected() signal.
Definition: TCanvas.cxx:1503
TTree * fTree
Definition: TSpider.h:66
virtual void Delete(Option_t *option="")
Remove all objects from the list AND delete all heap based objects.
Definition: TList.cxx:405
void SetAverageLineStyle(Style_t sty)
Set the LineStyle of the average.
Definition: TSpider.cxx:964
virtual Int_t DistancetoPrimitive(Int_t px, Int_t py)
Compute the distance to the spider.
Definition: TSpider.cxx:438
long long Long64_t
Definition: RtypesCore.h:69
Long64_t fEntry
Definition: TSpider.h:58
void GotoPrevious()
Go to the previous entries.
Definition: TSpider.cxx:763
TList * fFormulas
Pointer to the mother pad.
Definition: TSpider.h:70
short Style_t
Definition: RtypesCore.h:76
const double pi
Long64_t GetEntriesToProcess(Long64_t firstentry, Long64_t nentries) const
return the number of entries to be processed this function checks that nentries is not bigger than th...
Definition: TSpider.cxx:726
const char Option_t
Definition: RtypesCore.h:62
Int_t FindTextAlign(Double_t theta)
Find the alignement rule to apply for TText::SetTextAlign(Short_t).
Definition: TSpider.cxx:675
virtual Bool_t Sync()
Synchronize all the formulae.
tuple offset
Definition: tree.py:93
virtual void ExecuteEvent(Int_t event, Int_t px, Int_t py)
Execute the corresponding event.
Definition: TSpider.cxx:666
Bool_t fSegmentDisplay
Definition: TSpider.h:80
TTreeFormulaManager * GetManager() const
Definition: TTreeFormula.h:184
virtual TEntryList * GetEntryList()
Returns the entry list, set to this tree.
Definition: TTree.cxx:5194
void SetSegmentDisplay(Bool_t seg)
Set the segment display or not.
Definition: TSpider.cxx:1379
Style_t GetAverageFillStyle() const
Get the FillStyle of the average.
Definition: TSpider.cxx:656
virtual void SetLineWidth(Width_t wid)
Set line width.
Definition: TSpider.cxx:1168
virtual Long64_t GetEntriesFriend() const
Return pointer to the 1st Leaf named name in any Branch of this Tree or any branch in the list of fri...
Definition: TTree.cxx:5020
Int_t LastIndex() const
void Draw(Option_t *options="")
Draw Polargram.
TVirtualPad * cd(Int_t subpadnumber=0)
Set current canvas & pad.
Definition: TCanvas.cxx:659
virtual Float_t GetTextSize() const
Definition: TAttText.h:50
void InitVariables(Long64_t firstentry, Long64_t nentries)
Browse the tree to set the min, max and average value of each variable of fVar.
Definition: TSpider.cxx:831
void DrawSlicesAverage(Option_t *options)
Draw the slices representing the average for the segment plot.
Definition: TSpider.cxx:585
Long64_t * fCurrentEntries
Definition: TSpider.h:61
#define gROOT
Definition: TROOT.h:344
UInt_t fNx
Definition: TSpider.h:54
Basic string class.
Definition: TString.h:137
virtual Int_t GetNdim() const
Definition: TFormula.h:243
~TSpider()
Destructor.
Definition: TSpider.cxx:173
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
const Bool_t kFALSE
Definition: Rtypes.h:92
TArc ** fAverageSlices
Definition: TSpider.h:68
virtual void SetFillStyle(Style_t fstyle)
Definition: TAttFill.h:52
TBranch * GetBranch() const
Definition: TLeaf.h:70
Bool_t fForceDim
Definition: TSpider.h:79
virtual Long64_t GetEntryNumber(Long64_t entry) const
Return entry number corresponding to entry.
Definition: TTree.cxx:5205
Int_t GetEntriesFast() const
Definition: TObjArray.h:66
virtual void UpdateFormulaLeaves()
This function could be called TTreePlayer::UpdateFormulaLeaves, itself called by TChain::LoadTree whe...
Float_t py
Definition: hprod.C:33
TList * fInput
Definition: TSpider.h:71
virtual Long64_t GetEstimate() const
Definition: TTree.h:390
Long64_t fNentries
Definition: TSpider.h:59
virtual void Add(TTreeFormula *)
Add a new formula to the list of formulas managed The manager of the formula will be changed and the ...
virtual void SetInputList(TList *input)
Definition: TSelector.h:73
virtual TObject * At(Int_t idx) const
Returns the object at position idx. Returns 0 if idx is out of range.
Definition: TList.cxx:311
void GotoNext()
Go to the next entries.
Definition: TSpider.cxx:753
void UpdateView()
Update the polylines or the arcs for the current entries.
Definition: TSpider.cxx:1548
Bool_t fShowRange
Definition: TSpider.h:81
void DeleteVariable(const char *varexp)
Delete a variable from its expression.
Definition: TSpider.cxx:352
virtual void SetValue(const char *name, const char *value, EEnvLevel level=kEnvChange, const char *type=0)
Set the value of a resource or create a new resource.
Definition: TEnv.cxx:749
virtual void AppendPad(Option_t *option="")
Append graphics object to current pad.
Definition: TObject.cxx:164
virtual Int_t GetMultiplicity() const
TList * fPolyList
Definition: TSpider.h:74
TCanvas * fCanvas
Average slices.
Definition: TSpider.h:69
static struct mg_connection * fc(struct mg_context *ctx)
Definition: civetweb.c:839
Fill Area Attributes class.
Definition: TAttFill.h:32
Double_t x[n]
Definition: legend1.C:17
Used to coordinate one or more TTreeFormula objects.
Long64_t fFirstEntry
Definition: TSpider.h:60
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:33
void SetNdivRadial(Int_t div)
Set number of radial divisions.
Definition: TSpider.cxx:1216
const int ny
Definition: kalman.C:17
virtual Long64_t LoadTree(Long64_t entry)
Set current entry.
Definition: TTree.cxx:5785
To draw Mathematical Formula.
Definition: TLatex.h:33
void Clear(Option_t *option="")
Remove all primitives from the canvas.
Definition: TCanvas.cxx:678
virtual void Paint(Option_t *options)
Paint the spider.
Definition: TSpider.cxx:917
void SetNx(UInt_t nx)
Set the X number of sub pads.
Definition: TSpider.cxx:1225
std::vector< std::vector< double > > Data
virtual void SetFillColor(Color_t col)
Set fill color.
Definition: TSpider.cxx:1184
Bool_t fDisplayAverage
Definition: TSpider.h:78
TObjArray * GetListOfBranches()
Definition: TBranch.h:177
virtual void PaintLatex(Double_t x, Double_t y, Double_t angle, Double_t size, const char *text)
Main drawing function.
Definition: TLatex.cxx:2025
void SetNdivRadial(Int_t Ndiv=508)
Set the number of radial divisions: enter a number ij with 0<i<99 and 0<j<99.
short Color_t
Definition: RtypesCore.h:79
virtual void Draw(Option_t *option="")
Draw this ellipse with its current attributes.
Definition: TEllipse.cxx:167
Used to pass a selection expression to the Tree drawing routine.
Definition: TTreeFormula.h:64
virtual void SetFillStyle(Style_t sty)
Set fill style.
Definition: TSpider.cxx:1200
virtual void SetTextAlign(Short_t align=11)
Definition: TAttText.h:55
A doubly linked list.
Definition: TList.h:47
void SetAverageLineWidth(Width_t wid)
Set the LineWidth of the average.
Definition: TSpider.cxx:988
Create an Arc.
Definition: TArc.h:29
virtual void SetLineColor(Color_t lcolor)
Definition: TAttLine.h:54
Double_t * fAve
[fNx*fNy] current selected entries;
Definition: TSpider.h:62
virtual void Delete(Option_t *option="")
Delete this object.
Definition: TObject.cxx:228
void InitArrays(Int_t newsize)
Check if the arrays size is enough and reallocate them if not.
Definition: TSpider.cxx:793
virtual void Draw(Option_t *option="")
Draw this polyline with its current attributes.
Definition: TPolyLine.cxx:232
Style_t GetAverageLineStyle() const
Get the LineStyle of the average.
Definition: TSpider.cxx:616
ROOT::R::TRInterface & r
Definition: Object.C:4
virtual void SetFillColor(Color_t fcolor)
Definition: TAttFill.h:50
virtual Int_t GetTreeNumber() const
Definition: TTree.h:438
virtual TObject * Remove(TObject *obj)
Remove object from the list.
Definition: TList.cxx:675
virtual Color_t GetFillColor() const
Definition: TAttFill.h:43
unsigned int UInt_t
Definition: RtypesCore.h:42
void SetNy(UInt_t ny)
Set the Y number of sub pads.
Definition: TSpider.cxx:1302
char * Form(const char *fmt,...)
TPolyLine * fAveragePoly
Definition: TSpider.h:67
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:51
To draw polar axis.
void SetVariablesExpression(const char *varexp)
Compile the variables expression from the given string varexp.
Definition: TSpider.cxx:1478
void SetAverageFillColor(Color_t col)
Set the Fill Color of the average.
Definition: TSpider.cxx:1000
tuple pad
Definition: first.py:38
virtual Color_t GetLineColor() const
Definition: TAttLine.h:47
Long64_t entry
Double_t * fMin
Definition: TSpider.h:64
TTreeFormula * fSelect
Definition: TSpider.h:75
Double_t Cos(Double_t)
Definition: TMath.h:424
A specialized TSelector for TTree::Draw.
Definition: TSelectorDraw.h:33
short Width_t
Definition: RtypesCore.h:78
Bool_t fAngularLabels
Selector.
Definition: TSpider.h:77
Double_t Pi()
Definition: TMath.h:44
void SetAverageFillStyle(Style_t sty)
Set the FillStyle of the average.
Definition: TSpider.cxx:1012
virtual Int_t GetNdata()
Return number of available instances in the formula.
The Canvas class.
Definition: TCanvas.h:48
tuple tree
Definition: tree.py:24
#define ClassImp(name)
Definition: Rtypes.h:279
double Double_t
Definition: RtypesCore.h:55
TGraphPolargram * fPolargram
Definition: TSpider.h:73
void GotoFollowing()
Go to the next entry.
Definition: TSpider.cxx:773
R__EXTERN TEnv * gEnv
Definition: TEnv.h:174
int nentries
Definition: THbookFile.cxx:89
Double_t y[n]
Definition: legend1.C:17
Width_t GetAverageLineWidth() const
Get the LineWidth of the average.
Definition: TSpider.cxx:636
virtual void Draw(Option_t *options="")
Draw the spider.
Definition: TSpider.cxx:453
void SetDisplayAverage(Bool_t disp)
Display or not the average.
Definition: TSpider.cxx:1024
void SyncFormulas()
Create a TreeFormulaManager to coordinate the formulas.
Definition: TSpider.cxx:1516
Int_t GetEntries() const
Return the number of objects in array (i.e.
Definition: TObjArray.cxx:494
void GotoPreceding()
Go to the last entry.
Definition: TSpider.cxx:783
UInt_t fNy
Definition: TSpider.h:55
T EvalInstance(Int_t i=0, const char *stringStack[]=0)
Evaluate this treeformula.
virtual void SetLineStyle(Style_t sty)
Set line style.
Definition: TSpider.cxx:1136
void AddSuperposed(TSpider *sp)
Allow to superpose several spider views.
Definition: TSpider.cxx:205
TList * fSuperposed
Definition: TSpider.h:65
virtual void SetLineStyle(Style_t lstyle)
Definition: TAttLine.h:56
virtual void AddAfter(const TObject *after, TObject *obj)
Insert object after object after in the list.
Definition: TList.cxx:221
virtual Long64_t GetN() const
Definition: TEntryList.h:77
TTreeFormulaManager * fManager
Definition: TSpider.h:72
Float_t px
Definition: hprod.C:33
void SetNdivPolar(Int_t Ndiv=508)
Set the number of Polar divisions: enter a number ij with 0<i<99 and 0<j<99.
virtual void Divide(Int_t nx=1, Int_t ny=1, Float_t xmargin=0.01, Float_t ymargin=0.01, Int_t color=0)
Automatic pad generation by division.
Definition: TPad.cxx:1073
virtual void Add(TObject *obj)
Definition: TList.h:81
void DrawSlices(Option_t *options)
Draw the slices of the segment plot.
Definition: TSpider.cxx:559
void AddVariable(const char *varexp)
Add a variable to the plot from its expression.
Definition: TSpider.cxx:214
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:567
Double_t Sin(Double_t)
Definition: TMath.h:421
Spider class.
Definition: TSpider.h:52
UInt_t fNcols
Definition: TSpider.h:56
#define NULL
Definition: Rtypes.h:82
Defined by an array on N points in a 2-D space.
Definition: TPolyLine.h:40
#define gPad
Definition: TVirtualPad.h:288
virtual UInt_t SplitNames(const TString &varexp, std::vector< TString > &names)
Build Index array for names in varexp.
A TTree object has a header with a name and a title.
Definition: TTree.h:98
virtual Int_t GetNdata(Bool_t forceLoadDim=kFALSE)
Return number of available instances in the formulas.
virtual void SetTextSize(Float_t tsize=1)
Definition: TAttText.h:60
TObject * At(Int_t idx) const
Definition: TObjArray.h:167
virtual void Update()
Update canvas pad buffers.
Definition: TCanvas.cxx:2179
Color_t GetAverageLineColor() const
Get the LineColor of the average.
Definition: TSpider.cxx:626
const Bool_t kTRUE
Definition: Rtypes.h:91
virtual Width_t GetLineWidth() const
Definition: TAttLine.h:49
virtual const char * GetTitle() const
Returns title of object.
Definition: TObject.cxx:459
A List of entry numbers in a TTree or TChain.
Definition: TEntryList.h:27
Color_t GetAverageFillColor() const
Get the Fill Color of the average.
Definition: TSpider.cxx:646
Double_t FindTextAngle(Double_t theta)
Determine the orientation of the polar labels according to their angle.
Definition: TSpider.cxx:704
Int_t fArraySize
Definition: TSpider.h:57
void GotoEntry(Long64_t e)
Go to a specified entry.
Definition: TSpider.cxx:743
static char * skip(char **buf, const char *delimiters)
Definition: civetweb.c:1014
virtual void SetScanField(Int_t n=50)
Definition: TTree.h:551
Line Attributes class.
Definition: TAttLine.h:32
void SetCurrentEntries()
Set the current selected entries.
Definition: TSpider.cxx:1066
void SetAverageLineColor(Color_t col)
Set the LineColor of the average.
Definition: TSpider.cxx:976
void Modified(Bool_t flag=1)
Definition: TPad.h:407
unsigned int r2[N_CITIES]
Definition: simanTSP.cxx:322
TSelectorDraw * fSelector
Definition: TSpider.h:76
virtual Int_t GetScanField() const
Definition: TTree.h:430
virtual TObjArray * GetListOfLeaves()
Definition: TTree.h:410
void DrawPolyAverage(Option_t *options)
Paint the Polygon representing the average value of the variables.
Definition: TSpider.cxx:491
void SetSelectionExpression(const char *selexp)
Compile selection expression if there is one.
Definition: TSpider.cxx:1465