5 #include <Reve/ReveManager.h>
6 #include <Reve/NLTProjector.h>
9 #include <TTreePlayer.h>
17 //______________________________________________________________________
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).
24 // 3D point representation is implemented in base-class TPolyMarker3D.
25 // Per-point TRef is implemented in base-class TPointSet3D.
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.
31 // PointSet is a NLTProjectable: it can be projected by using the
32 // NLTProjector class.
36 //______________________________________________________________________________
37 PointSet::PointSet(Int_t n_points, TreeVarType_e tv_type) :
38 RenderElement(fMarkerColor),
39 TPointSet3D(n_points),
40 TPointSelectorConsumer(tv_type),
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),
68 //______________________________________________________________________________
76 /**************************************************************************/
78 //______________________________________________________________________________
79 void PointSet::ComputeBBox()
81 // Override of virtual method from TAttBBox.
83 TPointSet3D::ComputeBBox();
84 AssertBBoxExtents(0.1);
87 //______________________________________________________________________________
88 void PointSet::Reset(Int_t n_points, Int_t n_int_ids)
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.
96 if(fN) fP = new Float_t [3*fN];
97 memset(fP, 0, 3*fN*sizeof(Float_t));
100 delete fIntIds; fIntIds = 0;
101 fIntIdsPerPoint = n_int_ids;
102 if (fIntIdsPerPoint > 0) fIntIds = new TArrayI(fIntIdsPerPoint*fN);
106 //______________________________________________________________________________
107 Int_t PointSet::GrowFor(Int_t n_points)
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.
114 Int_t old_size = Size();
115 Int_t new_size = old_size + n_points;
116 SetPoint(new_size - 1, 0, 0, 0);
118 fIntIds->Set(fIntIdsPerPoint * new_size);
122 /**************************************************************************/
124 //______________________________________________________________________________
125 inline void PointSet::AssertIntIdsSize()
127 // Assert that size of IntId array is compatible with the size of
130 Int_t exp_size = GetN()*fIntIdsPerPoint;
131 if (fIntIds->GetSize() < exp_size)
132 fIntIds->Set(exp_size);
135 //______________________________________________________________________________
136 Int_t* PointSet::GetPointIntIds(Int_t p) const
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
141 // Validity of p is *not* checked.
144 return fIntIds->GetArray() + p*fIntIdsPerPoint;
148 //______________________________________________________________________________
149 Int_t PointSet::GetPointIntId(Int_t p, Int_t i) const
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.
157 return * (fIntIds->GetArray() + p*fIntIdsPerPoint + i);
161 //______________________________________________________________________________
162 void PointSet::SetPointIntIds(Int_t* ids)
164 // Set integer ids for the last point that was registerd (most
165 // probably via TPolyMarker3D::SetNextPoint(x,y,z)).
167 SetPointIntIds(fLastPoint, ids);
170 //______________________________________________________________________________
171 void PointSet::SetPointIntIds(Int_t n, Int_t* ids)
173 // Set integer ids for point with index n.
175 if (!fIntIds) return;
177 Int_t* x = fIntIds->GetArray() + n*fIntIdsPerPoint;
178 for (Int_t i=0; i<fIntIdsPerPoint; ++i)
182 /**************************************************************************/
184 //______________________________________________________________________________
185 void PointSet::SetRnrElNameTitle(const Text_t* name, const Text_t* title)
187 // Set name and title of point-set.
188 // Virtual in RenderElement.
194 /******************************************************************************/
196 //______________________________________________________________________________
197 void PointSet::Paint(Option_t* option)
201 if(fRnrSelf == kFALSE) return;
203 TPointSet3D::Paint(option);
206 /**************************************************************************/
208 //______________________________________________________________________________
209 void PointSet::InitFill(Int_t subIdNum)
211 // Initialize point-set for new filling.
212 // subIdNum gives the number of integer ids that can be assigned to
216 fIntIdsPerPoint = subIdNum;
218 fIntIds = new TArrayI(fIntIdsPerPoint*GetN());
220 fIntIds->Set(fIntIdsPerPoint*GetN());
222 delete fIntIds; fIntIds = 0;
227 //______________________________________________________________________________
228 void PointSet::TakeAction(TPointSelector* sel)
230 // Called from TPointSelector when internal arrays of the tree-selector
231 // are filled up and need to be processed.
232 // Virtual from TPointSelectorConsumer.
234 static const Exc_t eH("PointSet::TakeAction ");
237 throw(eH + "selector is <null>.");
239 Int_t n = sel->GetNfill();
240 Int_t beg = GrowFor(n);
242 // printf("PointSet::TakeAction beg=%d n=%d size=%d nsubid=%d dim=%d\n",
243 // beg, n, Size(), sel->GetSubIdNum(), sel->GetDimension());
245 Double_t *vx = sel->GetV1(), *vy = sel->GetV2(), *vz = sel->GetV3();
246 Float_t *p = fP + 3*beg;
251 p[0] = *vx; p[1] = *vy; p[2] = *vz;
258 p[0] = *vx * TMath::Cos(*vy); p[1] = *vx * TMath::Sin(*vy); p[2] = *vz;
264 throw(eH + "unknown tree variable type.");
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);
272 throw(eH + "sub-id array not available.");
274 Int_t* ids = fIntIds->GetArray() + fIntIdsPerPoint*beg;
277 for (Int_t i=0; i<fIntIdsPerPoint; ++i) {
278 ids[i] = TMath::Nint(*subarr[i]);
281 ids += fIntIdsPerPoint;
287 /**************************************************************************/
289 //______________________________________________________________________________
290 TClass* PointSet::ProjectedClass() const
292 // Virtual from NLTProjectable, returns NLTPointSet class.
294 return NLTPointSet::Class();
297 //______________________________________________________________________________
298 void PointSet::PointSelected(Int_t id)
300 // Virtual method of base class TPointSet3D. The fuction call is invoked with secondary selection
303 PointCtrlClicked(this, id);
305 //______________________________________________________________________________
306 void PointSet::PointCtrlClicked(PointSet* ps, Int_t id)
308 // Emits "PointCtrlClicked()" signal.
311 args[0] = (Long_t) ps;
312 args[1] = (Long_t) id;
314 TQObject::Emit("PointCtrlClicked(Reve::PointSet*,Int_t)", args);
317 /**************************************************************************/
318 /**************************************************************************/
320 //______________________________________________________________________________
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.
328 // By using the TPointSelector the points and the separating
329 // quantities can be filled directly from a TTree holding the source
331 // Setting of per-point TRef's is not supported.
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
338 ClassImp(PointSetArray)
340 //______________________________________________________________________________
341 PointSetArray::PointSetArray(const Text_t* name,
342 const Text_t* title) :
343 RenderElement(fMarkerColor),
346 fBins(0), fDefPointSetCapacity(128), fNBins(0), fLastBin(-1),
347 fMin(0), fCurMin(0), fMax(0), fCurMax(0),
354 //______________________________________________________________________________
355 PointSetArray::~PointSetArray()
357 // Destructor: deletes the fBins array. Actual removal of
358 // elements done by RenderElement.
360 // printf("PointSetArray::~PointSetArray()\n");
361 delete [] fBins; fBins = 0;
364 //______________________________________________________________________________
365 void PointSetArray::Paint(Option_t* option)
367 // Paint the subjugated PointSet's.
370 for (List_i i=fChildren.begin(); i!=fChildren.end(); ++i) {
371 if ((*i)->GetRnrSelf())
372 (*i)->GetObject()->Paint(option);
377 //______________________________________________________________________________
378 void PointSetArray::RemoveElementLocal(RenderElement* el)
380 // Virtual from RenderElement, provide bin management.
382 for (Int_t i=0; i<fNBins; ++i) {
383 if (fBins[i] == el) {
390 //______________________________________________________________________________
391 void PointSetArray::RemoveElementsLocal()
393 // Virtual from RenderElement, provide bin management.
395 delete [] fBins; fBins = 0; fLastBin = -1;
398 /**************************************************************************/
400 //______________________________________________________________________________
401 void PointSetArray::SetMarkerColor(Color_t tcolor)
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);
408 TAttMarker::SetMarkerColor(tcolor);
411 //______________________________________________________________________________
412 void PointSetArray::SetMarkerStyle(Style_t mstyle)
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);
419 TAttMarker::SetMarkerStyle(mstyle);
422 //______________________________________________________________________________
423 void PointSetArray::SetMarkerSize(Size_t msize)
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);
430 TAttMarker::SetMarkerSize(msize);
433 /**************************************************************************/
435 //______________________________________________________________________________
436 void PointSetArray::TakeAction(TPointSelector* sel)
438 // Called from TPointSelector when internal arrays of the tree-selector
439 // are filled up and need to be processed.
440 // Virtual from TPointSelectorConsumer.
442 static const Exc_t eH("PointSetArray::TakeAction ");
445 throw(eH + "selector is <null>.");
447 Int_t n = sel->GetNfill();
449 // printf("PointSetArray::TakeAction n=%d\n", n);
451 Double_t *vx = sel->GetV1(), *vy = sel->GetV2(), *vz = sel->GetV3();
452 Double_t *qq = sel->GetV4();
455 throw(eH + "requires 4-d varexp.");
460 Fill(*vx, *vy, *vz, *qq);
461 ++vx; ++vy; ++vz; ++qq;
466 Fill(*vx * TMath::Cos(*vy), *vx * TMath::Sin(*vy), *vz, *qq);
467 ++vx; ++vy; ++vz; ++qq;
471 throw(eH + "unknown tree variable type.");
475 /**************************************************************************/
477 //______________________________________________________________________________
478 void PointSetArray::InitBins(const Text_t* quant_name,
479 Int_t nbins, Double_t min, Double_t max,
482 static const Exc_t eH("PointSetArray::InitBins ");
484 if (nbins < 1) throw(eH + "nbins < 1.");
485 if (min > max) throw(eH + "min > max.");
489 fQuantName = quant_name;
492 fMin = fCurMin = min;
493 fMax = fCurMax = max;
494 fBinWidth = (fMax - fMin)/fNBins;
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);
505 gReve->AddRenderElement(fBins[i], this);
507 AddElement(fBins[i]);
511 //______________________________________________________________________________
512 void PointSetArray::Fill(Double_t x, Double_t y, Double_t z, Double_t quant)
514 fLastBin = Int_t( (quant - fMin)/fBinWidth );
515 if (fLastBin >= 0 && fLastBin < fNBins && fBins[fLastBin] != 0)
516 fBins[fLastBin]->SetNextPoint(x, y, z);
521 //______________________________________________________________________________
522 void PointSetArray::SetPointId(TObject* id)
525 fBins[fLastBin]->SetPointId(id);
528 //______________________________________________________________________________
529 void PointSetArray::CloseBins()
531 for (Int_t i=0; i<fNBins; ++i) {
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;
538 fBins[i]->ComputeBBox();
544 /**************************************************************************/
546 //______________________________________________________________________________
547 void PointSetArray::SetOwnIds(Bool_t o)
549 for (Int_t i=0; i<fNBins; ++i)
552 fBins[i]->SetOwnIds(o);
556 /**************************************************************************/
558 //______________________________________________________________________________
559 void PointSetArray::SetRange(Double_t min, Double_t max)
561 using namespace TMath;
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) {
568 fBins[i]->SetRnrSelf(i>=low_b && i<=high_b);
573 /******************************************************************************/
574 /******************************************************************************/
576 //______________________________________________________________________________
580 ClassImp(NLTPointSet)
582 //______________________________________________________________________________
583 NLTPointSet::NLTPointSet() :
587 // Default contructor.
590 //______________________________________________________________________________
591 void NLTPointSet::SetProjection(NLTProjector* proj, NLTProjectable* model)
593 NLTProjected::SetProjection(proj, model);
595 * (TAttMarker*)this = * dynamic_cast<TAttMarker*>(fProjectable);
598 //______________________________________________________________________________
599 void NLTPointSet::UpdateProjection()
601 NLTProjection& proj = * fProjector->GetProjection();
602 PointSet & ps = * dynamic_cast<PointSet*>(fProjectable);
606 Float_t *o = ps.GetP(), *p = GetP();
607 for (Int_t i = 0; i < n; ++i, o+=3, p+=3)
609 p[0] = o[0]; p[1] = o[1]; p[2] = o[2];
610 proj.ProjectPoint(p[0], p[1], p[2]);