]> git.uio.no Git - u/mrichter/AliRoot.git/blob - EVE/Reve/PointSet.cxx
Merged EVE-dev-after-merge to EVE-dev into HEAD. Requires ROOT-5.17.04.
[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 PointSet::PointSet(Int_t n_points, TreeVarType_e tv_type) :
37   RenderElement(fMarkerColor),
38   TPointSet3D(n_points),
39   TPointSelectorConsumer(tv_type),
40
41   fTitle          (),
42   fIntIds         (0),
43   fIntIdsPerPoint (0)
44 {
45   // Constructor.
46
47   fMarkerStyle = 20;
48 }
49
50 PointSet::PointSet(const Text_t* name, Int_t n_points, TreeVarType_e tv_type) :
51   RenderElement(fMarkerColor),
52   TPointSet3D(n_points),
53   TPointSelectorConsumer(tv_type),
54
55   fTitle          (),
56   fIntIds         (0),
57   fIntIdsPerPoint (0)
58 {
59   // Constructor.
60
61   fMarkerStyle = 20;
62   SetName(name);
63 }
64
65 PointSet::~PointSet()
66 {
67   // Destructor.
68
69   delete fIntIds;
70 }
71
72 /**************************************************************************/
73
74 void PointSet::ComputeBBox()
75 {
76   // Override of virtual method from TAttBBox.
77
78   TPointSet3D::ComputeBBox();
79   AssertBBoxExtents(0.1);
80 }
81
82 void PointSet::Reset(Int_t n_points, Int_t n_int_ids)
83 {
84   // Drop all data and set-up the data structures to recive new data.
85   // n_points   specifies the initial size of the arrays.
86   // n_int_ids  specifies the number of integer ids per point.
87
88   delete [] fP; fP = 0;
89   fN = n_points;
90   if(fN) fP = new Float_t [3*fN];
91   memset(fP, 0, 3*fN*sizeof(Float_t));
92   fLastPoint = -1;
93   ClearIds();
94   delete fIntIds; fIntIds = 0;
95   fIntIdsPerPoint = n_int_ids;
96   if (fIntIdsPerPoint > 0) fIntIds = new TArrayI(fIntIdsPerPoint*fN);
97   ResetBBox();
98 }
99
100 Int_t PointSet::GrowFor(Int_t n_points)
101 {
102   // Resizes internal array to allow additional n_points to be stored.
103   // Returns the old size which is also the location where one can
104   // start storing new data.
105   // The caller is *obliged* to fill the new point slots.
106
107   Int_t old_size = Size();
108   Int_t new_size = old_size + n_points;
109   SetPoint(new_size - 1, 0, 0, 0);
110   if (fIntIds)
111     fIntIds->Set(fIntIdsPerPoint * new_size);
112   return old_size;
113 }
114
115 /**************************************************************************/
116
117 inline void PointSet::AssertIntIdsSize()
118 {
119   // Assert that size of IntId array is compatible with the size of
120   // the point array.
121
122   Int_t exp_size = GetN()*fIntIdsPerPoint;
123   if (fIntIds->GetSize() < exp_size)
124     fIntIds->Set(exp_size);
125 }
126
127 Int_t* PointSet::GetPointIntIds(Int_t p) const
128 {
129   // Return a pointer to integer ids of point with index p.
130   // Existence of integer id array is checked, 0 is returned if it
131   // does not exist.
132   // Validity of p is *not* checked.
133
134   if (fIntIds)
135     return fIntIds->GetArray() + p*fIntIdsPerPoint;
136   return 0;
137 }
138
139 Int_t PointSet::GetPointIntId(Int_t p, Int_t i) const
140 {
141   // Return i-th integer id of point with index p.
142   // Existence of integer id array is checked, kMinInt is returned if
143   // it does not exist.
144   // Validity of p and i is *not* checked.
145
146   if (fIntIds)
147     return * (fIntIds->GetArray() + p*fIntIdsPerPoint + i);
148   return kMinInt;
149 }
150
151 void PointSet::SetPointIntIds(Int_t* ids)
152 {
153   // Set integer ids for the last point that was registerd (most
154   // probably via TPolyMarker3D::SetNextPoint(x,y,z)).
155
156   SetPointIntIds(fLastPoint, ids);
157 }
158
159 void PointSet::SetPointIntIds(Int_t n, Int_t* ids)
160 {
161   if (!fIntIds) return;
162   AssertIntIdsSize();
163   Int_t* x = fIntIds->GetArray() + n*fIntIdsPerPoint;
164   for (Int_t i=0; i<fIntIdsPerPoint; ++i)
165     x[i] = ids[i];
166 }
167
168 /**************************************************************************/
169
170 void PointSet::SetRnrElNameTitle(const Text_t* name, const Text_t* title)
171 {
172   SetName(name);
173   SetTitle(title);
174 }
175
176 /**************************************************************************/
177
178 void PointSet::Paint(Option_t* option)
179 {
180   if(fRnrSelf == kFALSE) return;
181
182   TPointSet3D::Paint(option);
183 }
184
185 /**************************************************************************/
186
187 void PointSet::InitFill(Int_t subIdNum)
188 {
189   if (subIdNum > 0) {
190     fIntIdsPerPoint = subIdNum;
191     if (!fIntIds)
192       fIntIds = new TArrayI(fIntIdsPerPoint*GetN());
193     else
194       fIntIds->Set(fIntIdsPerPoint*GetN());
195   } else {
196     delete fIntIds; fIntIds = 0;
197     fIntIdsPerPoint = 0;
198   }
199 }
200
201 void PointSet::TakeAction(TPointSelector* sel)
202 {
203   static const Exc_t eH("PointSet::TakeAction ");
204
205   if(sel == 0)
206     throw(eH + "selector is <null>.");
207
208   Int_t    n = sel->GetNfill();
209   Int_t  beg = GrowFor(n);
210
211   // printf("PointSet::TakeAction beg=%d n=%d size=%d nsubid=%d dim=%d\n",
212   //        beg, n, Size(), sel->GetSubIdNum(), sel->GetDimension());
213
214   Double_t *vx = sel->GetV1(), *vy = sel->GetV2(), *vz = sel->GetV3();
215   Float_t  *p  = fP + 3*beg;
216
217   switch(fSourceCS) {
218   case TVT_XYZ:
219     while(n-- > 0) {
220       p[0] = *vx; p[1] = *vy; p[2] = *vz;
221       p += 3;
222       ++vx; ++vy; ++vz;
223     }
224     break;
225   case TVT_RPhiZ:
226     while(n-- > 0) {
227       p[0] = *vx * TMath::Cos(*vy); p[1] = *vx * TMath::Sin(*vy); p[2] = *vz;
228       p += 3;
229       ++vx; ++vy; ++vz;
230     }
231     break;
232   default:
233     throw(eH + "unknown tree variable type.");
234   }
235
236   if (fIntIds) {
237     Double_t** subarr = new Double_t* [fIntIdsPerPoint];
238     for (Int_t i=0; i<fIntIdsPerPoint; ++i) {
239       subarr[i] = sel->GetVal(sel->GetDimension() - fIntIdsPerPoint + i);
240       if (subarr[i] == 0)
241         throw(eH + "sub-id array not available.");
242     }
243     Int_t* ids = fIntIds->GetArray() + fIntIdsPerPoint*beg;
244     n = sel->GetNfill();
245     while (n-- > 0) {
246       for (Int_t i=0; i<fIntIdsPerPoint; ++i) {
247         ids[i] = TMath::Nint(*subarr[i]);
248         ++subarr[i];
249       }
250       ids += fIntIdsPerPoint;
251     }
252     delete [] subarr;
253   }
254 }
255
256 /**************************************************************************/
257
258 TClass* PointSet::ProjectedClass() const
259 {
260   return NLTPointSet::Class();
261 }
262
263
264 /**************************************************************************/
265 /**************************************************************************/
266
267 //______________________________________________________________________
268 // PointSetArray
269 //
270
271 ClassImp(PointSetArray)
272
273 PointSetArray::PointSetArray(const Text_t* name,
274                              const Text_t* title) :
275   RenderElement(fMarkerColor),
276   TNamed(name, title),
277
278   fBins(0), fDefPointSetCapacity(128), fNBins(0), fLastBin(-1),
279   fMin(0), fCurMin(0), fMax(0), fCurMax(0),
280   fBinWidth(0),
281   fQuantName()
282 {}
283
284 PointSetArray::~PointSetArray()
285 {
286   // Destructor: deletes the fBins array. Actual removal of
287   // elements done by RenderElement.
288
289   // printf("PointSetArray::~PointSetArray()\n");
290   delete [] fBins; fBins = 0;
291 }
292
293 void PointSetArray::Paint(Option_t* option)
294 {
295   if(fRnrSelf) {
296     for(List_i i=fChildren.begin(); i!=fChildren.end(); ++i) {
297       if((*i)->GetRnrSelf())
298         (*i)->GetObject()->Paint(option);
299     }
300   }
301 }
302
303 void PointSetArray::RemoveElementLocal(RenderElement* el)
304 {
305   for(Int_t i=0; i<fNBins; ++i) {
306     if(fBins[i] == el) {
307       fBins[i] = 0;
308       break;
309     }
310   }
311 }
312
313 void PointSetArray::RemoveElementsLocal()
314 {
315   delete [] fBins; fBins = 0; fLastBin = -1;
316 }
317
318 /**************************************************************************/
319
320 void PointSetArray::SetMarkerColor(Color_t tcolor)
321 {
322   for(List_i i=fChildren.begin(); i!=fChildren.end(); ++i) {
323     TAttMarker* m = dynamic_cast<TAttMarker*>((*i)->GetObject());
324     if(m && m->GetMarkerColor() == fMarkerColor)
325       m->SetMarkerColor(tcolor);
326   }
327   TAttMarker::SetMarkerColor(tcolor);
328 }
329
330 void PointSetArray::SetMarkerStyle(Style_t mstyle)
331 {
332   for(List_i i=fChildren.begin(); i!=fChildren.end(); ++i) {
333     TAttMarker* m = dynamic_cast<TAttMarker*>((*i)->GetObject());
334     if(m && m->GetMarkerStyle() == fMarkerStyle)
335       m->SetMarkerStyle(mstyle);
336   }
337   TAttMarker::SetMarkerStyle(mstyle);
338 }
339
340 void PointSetArray::SetMarkerSize(Size_t msize)
341 {
342   for(List_i i=fChildren.begin(); i!=fChildren.end(); ++i) {
343     TAttMarker* m = dynamic_cast<TAttMarker*>((*i)->GetObject());
344     if(m && m->GetMarkerSize() == fMarkerSize)
345       m->SetMarkerSize(msize);
346   }
347   TAttMarker::SetMarkerSize(msize);
348 }
349
350 /**************************************************************************/
351
352 void PointSetArray::TakeAction(TPointSelector* sel)
353 {
354   static const Exc_t eH("PointSetArray::TakeAction ");
355
356   if(sel == 0)
357     throw(eH + "selector is <null>.");
358
359   Int_t n = sel->GetNfill();
360
361   // printf("PointSetArray::TakeAction n=%d\n", n);
362
363   Double_t *vx = sel->GetV1(), *vy = sel->GetV2(), *vz = sel->GetV3();
364   Double_t *qq = sel->GetV4();
365
366   if(qq == 0)
367     throw(eH + "requires 4-d varexp.");
368
369   switch(fSourceCS) {
370   case TVT_XYZ:
371     while(n-- > 0) {
372       Fill(*vx, *vy, *vz, *qq);
373       ++vx; ++vy; ++vz; ++qq;
374     }
375     break;
376   case TVT_RPhiZ:
377     while(n-- > 0) {
378       Fill(*vx * TMath::Cos(*vy), *vx * TMath::Sin(*vy), *vz, *qq);
379       ++vx; ++vy; ++vz; ++qq;
380     }
381     break;
382   default:
383     throw(eH + "unknown tree variable type.");
384   }
385 }
386
387 /**************************************************************************/
388
389 void PointSetArray::InitBins(const Text_t* quant_name,
390                              Int_t nbins, Double_t min, Double_t max,
391                              Bool_t addRe)
392 {
393   static const Exc_t eH("PointSetArray::InitBins ");
394
395   if(nbins < 1) throw(eH + "nbins < 1.");
396   if(min > max) throw(eH + "min > max.");
397
398   RemoveElements();
399
400   fQuantName = quant_name;
401   fNBins     = nbins;
402   fLastBin   = -1;
403   fMin = fCurMin = min;
404   fMax = fCurMax = max;
405   fBinWidth  = (fMax - fMin)/fNBins;
406
407   fBins = new Reve::PointSet*[fNBins];
408   for(Int_t i=0; i<fNBins; ++i) {
409     fBins[i] = new Reve::PointSet
410       (Form("Slice %d [%4.3lf, %4.3lf]", i, fMin + i*fBinWidth, fMin + (i+1)*fBinWidth),
411        fDefPointSetCapacity);
412     fBins[i]->SetMarkerColor(fMarkerColor);
413     fBins[i]->SetMarkerStyle(fMarkerStyle);
414     fBins[i]->SetMarkerSize(fMarkerSize);
415     if(addRe)
416       gReve->AddRenderElement(fBins[i], this);
417     else
418       AddElement(fBins[i]);
419   }
420 }
421
422 void PointSetArray::Fill(Double_t x, Double_t y, Double_t z, Double_t quant)
423 {
424   fLastBin = Int_t( (quant - fMin)/fBinWidth );
425   if(fLastBin >= 0 && fLastBin < fNBins && fBins[fLastBin] != 0)
426     fBins[fLastBin]->SetNextPoint(x, y, z);
427   else
428     fLastBin = -1;
429 }
430
431 void PointSetArray::SetPointId(TObject* id)
432 {
433   if (fLastBin >= 0)
434     fBins[fLastBin]->SetPointId(id);
435 }
436
437 void PointSetArray::CloseBins()
438 {
439   for(Int_t i=0; i<fNBins; ++i) {
440     if(fBins[i] != 0) {
441       // HACK! PolyMarker3D does half-management of array size.
442       // In fact, the error is mine, in pointset3d(gl) i use fN instead of Size().
443       // Fixed in my root, but not elsewhere.
444       fBins[i]->fN = fBins[i]->fLastPoint;
445
446       fBins[i]->ComputeBBox();
447     }
448   }
449   fLastBin = -1;
450 }
451
452 /**************************************************************************/
453
454 void PointSetArray::SetOwnIds(Bool_t o)
455 {
456   for(Int_t i=0; i<fNBins; ++i)
457   {
458     if(fBins[i] != 0)
459       fBins[i]->SetOwnIds(o);
460   }
461 }
462
463 /**************************************************************************/
464
465 void PointSetArray::SetRange(Double_t min, Double_t max)
466 {
467   using namespace TMath;
468
469   fCurMin = min; fCurMax = max;
470   Int_t  low_b = (Int_t) Max(Double_t(0),       Floor((min-fMin)/fBinWidth));
471   Int_t high_b = (Int_t) Min(Double_t(fNBins-1), Ceil((max-fMin)/fBinWidth));
472   for(Int_t i=0; i<fNBins; ++i) {
473     if(fBins[i] != 0)
474       fBins[i]->SetRnrSelf(i>=low_b && i<=high_b);
475   }
476 }
477
478
479 /**************************************************************************/
480 /**************************************************************************/
481
482
483 //______________________________________________________________________
484 // NLTPointSet
485 //
486
487 ClassImp(NLTPointSet)
488
489 NLTPointSet::NLTPointSet() :
490   PointSet     (),
491   NLTProjected ()
492 {}
493
494 void NLTPointSet::SetProjection(NLTProjector* proj, NLTProjectable* model)
495 {
496   NLTProjected::SetProjection(proj, model);
497
498   * (TAttMarker*)this = * dynamic_cast<TAttMarker*>(fProjectable);
499 }
500
501 void NLTPointSet::UpdateProjection()
502 {
503   NLTProjection& proj = * fProjector->GetProjection();
504   PointSet     & ps   = * dynamic_cast<PointSet*>(fProjectable);
505
506   Int_t n = ps.GetN();
507   Reset(n);
508   Float_t *o = ps.GetP(), *p = GetP();
509   for(Int_t i = 0; i < n; ++i, o+=3, p+=3)
510   {
511     p[0] = o[0]; p[1] = o[1]; p[2] = o[2];
512     proj.ProjectPoint(p[0], p[1], p[2]);
513     p[2] = fDepth;
514   }
515   fLastPoint = n - 1;
516 }