]> git.uio.no Git - u/mrichter/AliRoot.git/blob - EVE/Reve/PointSet.cxx
0cc32cac4e00c49bc2d9fb410fd0a749019e5998
[u/mrichter/AliRoot.git] / EVE / Reve / PointSet.cxx
1 // $Header$
2
3 #include "PointSet.h"
4
5 #include <Reve/ReveManager.h>
6 #include <Reve/NLTProjector.h>
7
8 #include <TTree.h>
9 #include <TTreePlayer.h>
10 #include <TF3.h>
11
12 #include <TColor.h>
13 #include <TCanvas.h>
14
15 using namespace Reve;
16
17 //______________________________________________________________________
18 // PointSet
19 //
20 // PointSet is a render-element holding a collection of 3D points with
21 // optional per-point TRef and an arbitrary number of integer ids (to
22 // be used for signal, volume-id, track-id, etc).
23 //
24 // 3D point representation is implemented in base-class TPolyMarker3D.
25 // Per-point TRef is implemented in base-class TPointSet3D.
26 //
27 // By using the TPointSelector the points and integer ids can be
28 // filled directly from a TTree holding the source data.
29 // Setting of per-point TRef's is not supported.
30 //
31 // PointSet is a NLTProjectable: it can be projected by using the
32 // NLTProjector class.
33
34 ClassImp(PointSet)
35
36 //______________________________________________________________________________
37 PointSet::PointSet(Int_t n_points, TreeVarType_e tv_type) :
38   RenderElement(fMarkerColor),
39   TPointSet3D(n_points),
40   TPointSelectorConsumer(tv_type),
41
42   fTitle          (),
43   fIntIds         (0),
44   fIntIdsPerPoint (0)
45 {
46   // Constructor.
47
48   fMarkerStyle = 20;
49 }
50
51 //______________________________________________________________________________
52 PointSet::PointSet(const Text_t* name, Int_t n_points, TreeVarType_e tv_type) :
53   RenderElement(fMarkerColor),
54   TPointSet3D(n_points),
55   TPointSelectorConsumer(tv_type),
56   TQObject(),
57
58   fTitle          (),
59   fIntIds         (0),
60   fIntIdsPerPoint (0)
61 {
62   // Constructor.
63
64   fMarkerStyle = 20;
65   SetName(name);
66 }
67
68 //______________________________________________________________________________
69 PointSet::~PointSet()
70 {
71   // Destructor.
72
73   delete fIntIds;
74 }
75
76 /**************************************************************************/
77
78 //______________________________________________________________________________
79 void PointSet::ComputeBBox()
80 {
81   // Override of virtual method from TAttBBox.
82
83   TPointSet3D::ComputeBBox();
84   AssertBBoxExtents(0.1);
85 }
86
87 //______________________________________________________________________________
88 void PointSet::Reset(Int_t n_points, Int_t n_int_ids)
89 {
90   // Drop all data and set-up the data structures to recive new data.
91   // n_points   specifies the initial size of the arrays.
92   // n_int_ids  specifies the number of integer ids per point.
93
94   delete [] fP; fP = 0;
95   fN = n_points;
96   if(fN) fP = new Float_t [3*fN];
97   memset(fP, 0, 3*fN*sizeof(Float_t));
98   fLastPoint = -1;
99   ClearIds();
100   delete fIntIds; fIntIds = 0;
101   fIntIdsPerPoint = n_int_ids;
102   if (fIntIdsPerPoint > 0) fIntIds = new TArrayI(fIntIdsPerPoint*fN);
103   ResetBBox();
104 }
105
106 //______________________________________________________________________________
107 Int_t PointSet::GrowFor(Int_t n_points)
108 {
109   // Resizes internal array to allow additional n_points to be stored.
110   // Returns the old size which is also the location where one can
111   // start storing new data.
112   // The caller is *obliged* to fill the new point slots.
113
114   Int_t old_size = Size();
115   Int_t new_size = old_size + n_points;
116   SetPoint(new_size - 1, 0, 0, 0);
117   if (fIntIds)
118     fIntIds->Set(fIntIdsPerPoint * new_size);
119   return old_size;
120 }
121
122 /**************************************************************************/
123
124 //______________________________________________________________________________
125 inline void PointSet::AssertIntIdsSize()
126 {
127   // Assert that size of IntId array is compatible with the size of
128   // the point array.
129
130   Int_t exp_size = GetN()*fIntIdsPerPoint;
131   if (fIntIds->GetSize() < exp_size)
132     fIntIds->Set(exp_size);
133 }
134
135 //______________________________________________________________________________
136 Int_t* PointSet::GetPointIntIds(Int_t p) const
137 {
138   // Return a pointer to integer ids of point with index p.
139   // Existence of integer id array is checked, 0 is returned if it
140   // does not exist.
141   // Validity of p is *not* checked.
142
143   if (fIntIds)
144     return fIntIds->GetArray() + p*fIntIdsPerPoint;
145   return 0;
146 }
147
148 //______________________________________________________________________________
149 Int_t PointSet::GetPointIntId(Int_t p, Int_t i) const
150 {
151   // Return i-th integer id of point with index p.
152   // Existence of integer id array is checked, kMinInt is returned if
153   // it does not exist.
154   // Validity of p and i is *not* checked.
155
156   if (fIntIds)
157     return * (fIntIds->GetArray() + p*fIntIdsPerPoint + i);
158   return kMinInt;
159 }
160
161 //______________________________________________________________________________
162 void PointSet::SetPointIntIds(Int_t* ids)
163 {
164   // Set integer ids for the last point that was registerd (most
165   // probably via TPolyMarker3D::SetNextPoint(x,y,z)).
166
167   SetPointIntIds(fLastPoint, ids);
168 }
169
170 //______________________________________________________________________________
171 void PointSet::SetPointIntIds(Int_t n, Int_t* ids)
172 {
173   // Set integer ids for point with index n.
174
175   if (!fIntIds) return;
176   AssertIntIdsSize();
177   Int_t* x = fIntIds->GetArray() + n*fIntIdsPerPoint;
178   for (Int_t i=0; i<fIntIdsPerPoint; ++i)
179     x[i] = ids[i];
180 }
181
182 /**************************************************************************/
183
184 //______________________________________________________________________________
185 void PointSet::SetRnrElNameTitle(const Text_t* name, const Text_t* title)
186 {
187   // Set name and title of point-set.
188   // Virtual in RenderElement.
189
190   SetName(name);
191   SetTitle(title);
192 }
193
194 /******************************************************************************/
195
196 //______________________________________________________________________________
197 void PointSet::Paint(Option_t* option)
198 {
199   // Paint point-set.
200
201   if(fRnrSelf == kFALSE) return;
202
203   TPointSet3D::Paint(option);
204 }
205
206 /**************************************************************************/
207
208 //______________________________________________________________________________
209 void PointSet::InitFill(Int_t subIdNum)
210 {
211   // Initialize point-set for new filling.
212   // subIdNum gives the number of integer ids that can be assigned to
213   // each point.
214
215   if (subIdNum > 0) {
216     fIntIdsPerPoint = subIdNum;
217     if (!fIntIds)
218       fIntIds = new TArrayI(fIntIdsPerPoint*GetN());
219     else
220       fIntIds->Set(fIntIdsPerPoint*GetN());
221   } else {
222     delete fIntIds; fIntIds = 0;
223     fIntIdsPerPoint = 0;
224   }
225 }
226
227 //______________________________________________________________________________
228 void PointSet::TakeAction(TPointSelector* sel)
229 {
230   // Called from TPointSelector when internal arrays of the tree-selector
231   // are filled up and need to be processed.
232   // Virtual from TPointSelectorConsumer.
233
234   static const Exc_t eH("PointSet::TakeAction ");
235
236   if(sel == 0)
237     throw(eH + "selector is <null>.");
238
239   Int_t    n = sel->GetNfill();
240   Int_t  beg = GrowFor(n);
241
242   // printf("PointSet::TakeAction beg=%d n=%d size=%d nsubid=%d dim=%d\n",
243   //        beg, n, Size(), sel->GetSubIdNum(), sel->GetDimension());
244
245   Double_t *vx = sel->GetV1(), *vy = sel->GetV2(), *vz = sel->GetV3();
246   Float_t  *p  = fP + 3*beg;
247
248   switch(fSourceCS) {
249   case TVT_XYZ:
250     while(n-- > 0) {
251       p[0] = *vx; p[1] = *vy; p[2] = *vz;
252       p += 3;
253       ++vx; ++vy; ++vz;
254     }
255     break;
256   case TVT_RPhiZ:
257     while(n-- > 0) {
258       p[0] = *vx * TMath::Cos(*vy); p[1] = *vx * TMath::Sin(*vy); p[2] = *vz;
259       p += 3;
260       ++vx; ++vy; ++vz;
261     }
262     break;
263   default:
264     throw(eH + "unknown tree variable type.");
265   }
266
267   if (fIntIds) {
268     Double_t** subarr = new Double_t* [fIntIdsPerPoint];
269     for (Int_t i=0; i<fIntIdsPerPoint; ++i) {
270       subarr[i] = sel->GetVal(sel->GetDimension() - fIntIdsPerPoint + i);
271       if (subarr[i] == 0)
272         throw(eH + "sub-id array not available.");
273     }
274     Int_t* ids = fIntIds->GetArray() + fIntIdsPerPoint*beg;
275     n = sel->GetNfill();
276     while (n-- > 0) {
277       for (Int_t i=0; i<fIntIdsPerPoint; ++i) {
278         ids[i] = TMath::Nint(*subarr[i]);
279         ++subarr[i];
280       }
281       ids += fIntIdsPerPoint;
282     }
283     delete [] subarr;
284   }
285 }
286
287 /**************************************************************************/
288
289 //______________________________________________________________________________
290 TClass* PointSet::ProjectedClass() const
291 {
292   // Virtual from NLTProjectable, returns NLTPointSet class.
293
294   return NLTPointSet::Class();
295 }
296
297 //______________________________________________________________________________
298 void PointSet::PointSelected(Int_t id)
299 {
300   // Virtual method of base class TPointSet3D. The fuction call is invoked with secondary selection 
301   // in TPointSet3DGL.
302
303   PointCtrlClicked(this, id);
304 }
305 //______________________________________________________________________________
306 void PointSet::PointCtrlClicked(PointSet* ps, Int_t id)
307 {
308   // Emits "PointCtrlClicked()" signal.
309
310   Long_t args[2];
311   args[0] = (Long_t) ps;
312   args[1] = (Long_t) id;
313
314   TQObject::Emit("PointCtrlClicked(Reve::PointSet*,Int_t)", args);
315 }
316
317 /**************************************************************************/
318 /**************************************************************************/
319
320 //______________________________________________________________________________
321 // PointSetArray
322 //
323 // An array of point-sets with each point-set playing a role of a bin
324 // in a histogram. When a new point is added to a PointSetArray, an
325 // additional separating quantity needs to be specified: it determines
326 // into which PointSet (bin) the point will actually be stored.
327 //
328 // By using the TPointSelector the points and the separating
329 // quantities can be filled directly from a TTree holding the source
330 // data.
331 // Setting of per-point TRef's is not supported.
332 //
333 // After the filling, the range of separating variable can be
334 // controlled with a slider to choose a sub-set of PointSets that are
335 // actually shown.
336 //
337
338 ClassImp(PointSetArray)
339
340 //______________________________________________________________________________
341 PointSetArray::PointSetArray(const Text_t* name,
342                              const Text_t* title) :
343   RenderElement(fMarkerColor),
344   TNamed(name, title),
345
346   fBins(0), fDefPointSetCapacity(128), fNBins(0), fLastBin(-1),
347   fMin(0), fCurMin(0), fMax(0), fCurMax(0),
348   fBinWidth(0),
349   fQuantName()
350 {
351   // Constructor.
352 }
353
354 //______________________________________________________________________________
355 PointSetArray::~PointSetArray()
356 {
357   // Destructor: deletes the fBins array. Actual removal of
358   // elements done by RenderElement.
359
360   // printf("PointSetArray::~PointSetArray()\n");
361   delete [] fBins; fBins = 0;
362 }
363
364 //______________________________________________________________________________
365 void PointSetArray::Paint(Option_t* option)
366 {
367   // Paint the subjugated PointSet's.
368
369   if (fRnrSelf) {
370     for (List_i i=fChildren.begin(); i!=fChildren.end(); ++i) {
371       if ((*i)->GetRnrSelf())
372         (*i)->GetObject()->Paint(option);
373     }
374   }
375 }
376
377 //______________________________________________________________________________
378 void PointSetArray::RemoveElementLocal(RenderElement* el)
379 {
380   // Virtual from RenderElement, provide bin management.
381
382   for (Int_t i=0; i<fNBins; ++i) {
383     if (fBins[i] == el) {
384       fBins[i] = 0;
385       break;
386     }
387   }
388 }
389
390 //______________________________________________________________________________
391 void PointSetArray::RemoveElementsLocal()
392 {
393   // Virtual from RenderElement, provide bin management.
394
395   delete [] fBins; fBins = 0; fLastBin = -1;
396 }
397
398 /**************************************************************************/
399
400 //______________________________________________________________________________
401 void PointSetArray::SetMarkerColor(Color_t tcolor)
402 {
403   for (List_i i=fChildren.begin(); i!=fChildren.end(); ++i) {
404     TAttMarker* m = dynamic_cast<TAttMarker*>((*i)->GetObject());
405     if (m && m->GetMarkerColor() == fMarkerColor)
406       m->SetMarkerColor(tcolor);
407   }
408   TAttMarker::SetMarkerColor(tcolor);
409 }
410
411 //______________________________________________________________________________
412 void PointSetArray::SetMarkerStyle(Style_t mstyle)
413 {
414   for (List_i i=fChildren.begin(); i!=fChildren.end(); ++i) {
415     TAttMarker* m = dynamic_cast<TAttMarker*>((*i)->GetObject());
416     if (m && m->GetMarkerStyle() == fMarkerStyle)
417       m->SetMarkerStyle(mstyle);
418   }
419   TAttMarker::SetMarkerStyle(mstyle);
420 }
421
422 //______________________________________________________________________________
423 void PointSetArray::SetMarkerSize(Size_t msize)
424 {
425   for (List_i i=fChildren.begin(); i!=fChildren.end(); ++i) {
426     TAttMarker* m = dynamic_cast<TAttMarker*>((*i)->GetObject());
427     if (m && m->GetMarkerSize() == fMarkerSize)
428       m->SetMarkerSize(msize);
429   }
430   TAttMarker::SetMarkerSize(msize);
431 }
432
433 /**************************************************************************/
434
435 //______________________________________________________________________________
436 void PointSetArray::TakeAction(TPointSelector* sel)
437 {
438   // Called from TPointSelector when internal arrays of the tree-selector
439   // are filled up and need to be processed.
440   // Virtual from TPointSelectorConsumer.
441
442   static const Exc_t eH("PointSetArray::TakeAction ");
443
444   if (sel == 0)
445     throw(eH + "selector is <null>.");
446
447   Int_t n = sel->GetNfill();
448
449   // printf("PointSetArray::TakeAction n=%d\n", n);
450
451   Double_t *vx = sel->GetV1(), *vy = sel->GetV2(), *vz = sel->GetV3();
452   Double_t *qq = sel->GetV4();
453
454   if(qq == 0)
455     throw(eH + "requires 4-d varexp.");
456
457   switch(fSourceCS) {
458   case TVT_XYZ:
459     while(n-- > 0) {
460       Fill(*vx, *vy, *vz, *qq);
461       ++vx; ++vy; ++vz; ++qq;
462     }
463     break;
464   case TVT_RPhiZ:
465     while(n-- > 0) {
466       Fill(*vx * TMath::Cos(*vy), *vx * TMath::Sin(*vy), *vz, *qq);
467       ++vx; ++vy; ++vz; ++qq;
468     }
469     break;
470   default:
471     throw(eH + "unknown tree variable type.");
472   }
473 }
474
475 /**************************************************************************/
476
477 //______________________________________________________________________________
478 void PointSetArray::InitBins(const Text_t* quant_name,
479                              Int_t nbins, Double_t min, Double_t max,
480                              Bool_t addRe)
481 {
482   static const Exc_t eH("PointSetArray::InitBins ");
483
484   if (nbins < 1) throw(eH + "nbins < 1.");
485   if (min > max) throw(eH + "min > max.");
486
487   RemoveElements();
488
489   fQuantName = quant_name;
490   fNBins     = nbins;
491   fLastBin   = -1;
492   fMin = fCurMin = min;
493   fMax = fCurMax = max;
494   fBinWidth  = (fMax - fMin)/fNBins;
495
496   fBins = new Reve::PointSet*[fNBins];
497   for (Int_t i=0; i<fNBins; ++i) {
498     fBins[i] = new Reve::PointSet
499       (Form("Slice %d [%4.3lf, %4.3lf]", i, fMin + i*fBinWidth, fMin + (i+1)*fBinWidth),
500        fDefPointSetCapacity);
501     fBins[i]->SetMarkerColor(fMarkerColor);
502     fBins[i]->SetMarkerStyle(fMarkerStyle);
503     fBins[i]->SetMarkerSize(fMarkerSize);
504     if (addRe)
505       gReve->AddRenderElement(fBins[i], this);
506     else
507       AddElement(fBins[i]);
508   }
509 }
510
511 //______________________________________________________________________________
512 void PointSetArray::Fill(Double_t x, Double_t y, Double_t z, Double_t quant)
513 {
514   fLastBin = Int_t( (quant - fMin)/fBinWidth );
515   if (fLastBin >= 0 && fLastBin < fNBins && fBins[fLastBin] != 0)
516     fBins[fLastBin]->SetNextPoint(x, y, z);
517   else
518     fLastBin = -1;
519 }
520
521 //______________________________________________________________________________
522 void PointSetArray::SetPointId(TObject* id)
523 {
524   if (fLastBin >= 0)
525     fBins[fLastBin]->SetPointId(id);
526 }
527
528 //______________________________________________________________________________
529 void PointSetArray::CloseBins()
530 {
531   for (Int_t i=0; i<fNBins; ++i) {
532     if (fBins[i] != 0) {
533       // HACK! PolyMarker3D does half-management of array size.
534       // In fact, the error is mine, in pointset3d(gl) i use fN instead of Size().
535       // Fixed in my root, but not elsewhere.
536       fBins[i]->fN = fBins[i]->fLastPoint;
537
538       fBins[i]->ComputeBBox();
539     }
540   }
541   fLastBin = -1;
542 }
543
544 /**************************************************************************/
545
546 //______________________________________________________________________________
547 void PointSetArray::SetOwnIds(Bool_t o)
548 {
549   for (Int_t i=0; i<fNBins; ++i)
550   {
551     if (fBins[i] != 0)
552       fBins[i]->SetOwnIds(o);
553   }
554 }
555
556 /**************************************************************************/
557
558 //______________________________________________________________________________
559 void PointSetArray::SetRange(Double_t min, Double_t max)
560 {
561   using namespace TMath;
562
563   fCurMin = min; fCurMax = max;
564   Int_t  low_b = (Int_t) Max(Double_t(0),       Floor((min-fMin)/fBinWidth));
565   Int_t high_b = (Int_t) Min(Double_t(fNBins-1), Ceil((max-fMin)/fBinWidth));
566   for (Int_t i=0; i<fNBins; ++i) {
567     if (fBins[i] != 0)
568       fBins[i]->SetRnrSelf(i>=low_b && i<=high_b);
569   }
570 }
571
572
573 /******************************************************************************/
574 /******************************************************************************/
575
576 //______________________________________________________________________________
577 // NLTPointSet
578 //
579
580 ClassImp(NLTPointSet)
581
582 //______________________________________________________________________________
583 NLTPointSet::NLTPointSet() :
584   PointSet     (),
585   NLTProjected ()
586 {
587   // Default contructor.
588 }
589
590 //______________________________________________________________________________
591 void NLTPointSet::SetProjection(NLTProjector* proj, NLTProjectable* model)
592 {
593   NLTProjected::SetProjection(proj, model);
594
595   * (TAttMarker*)this = * dynamic_cast<TAttMarker*>(fProjectable);
596 }
597
598 //______________________________________________________________________________
599 void NLTPointSet::UpdateProjection()
600 {
601   NLTProjection& proj = * fProjector->GetProjection();
602   PointSet     & ps   = * dynamic_cast<PointSet*>(fProjectable);
603
604   Int_t n = ps.GetN();
605   Reset(n);
606   Float_t *o = ps.GetP(), *p = GetP();
607   for (Int_t i = 0; i < n; ++i, o+=3, p+=3)
608   {
609     p[0] = o[0]; p[1] = o[1]; p[2] = o[2];
610     proj.ProjectPoint(p[0], p[1], p[2]);
611     p[2] = fDepth;
612   }
613   fLastPoint = n - 1;
614 }