37 TGeoTrack::TGeoTrack()
47 TGeoTrack::TGeoTrack(Int_t
id, Int_t pdgcode, TVirtualGeoTrack *parent, TObject *particle)
48 :TVirtualGeoTrack(id,pdgcode,parent,particle)
71 TGeoTrack::TGeoTrack(
const TGeoTrack& other)
72 :TVirtualGeoTrack(other),
73 fPointsSize(other.fPointsSize),
74 fNpoints(other.fNpoints),
75 fPoints(other.fPoints)
82 TGeoTrack& TGeoTrack::operator=(
const TGeoTrack& gv)
85 TVirtualGeoTrack::operator=(gv);
86 fPointsSize=gv.fPointsSize;
96 TGeoTrack::~TGeoTrack()
98 if (fPoints)
delete [] fPoints;
105 TVirtualGeoTrack *TGeoTrack::AddDaughter(Int_t
id, Int_t pdgcode, TObject *particle)
107 if (!fTracks) fTracks =
new TObjArray(1);
108 Int_t index = fTracks->GetEntriesFast();
109 TGeoTrack *daughter =
new TGeoTrack(
id,pdgcode,
this,particle);
110 fTracks->AddAtAndExpand(daughter,index);
117 Int_t TGeoTrack::AddDaughter(TVirtualGeoTrack *other)
119 if (!fTracks) fTracks =
new TObjArray(1);
120 Int_t index = fTracks->GetEntriesFast();
121 fTracks->AddAtAndExpand(other,index);
122 other->SetParent(
this);
129 void TGeoTrack::AnimateTrack(Double_t tmin, Double_t tmax, Double_t nframes, Option_t *option)
131 if (tmin<0 || tmin>=tmax || nframes<1)
return;
132 gGeoManager->SetAnimateTracks();
133 gGeoManager->SetVisLevel(1);
135 gGeoManager->GetMasterVolume()->Draw();
137 TList *list = gPad->GetListOfPrimitives();
140 while ((obj = next())) {
141 if (!strcmp(obj->ClassName(),
"TGeoTrack")) list->Remove(obj);
143 Double_t dt = (tmax-tmin)/Double_t(nframes);
144 Double_t delt = 2E-9;
146 Bool_t geomanim = kFALSE;
147 Bool_t issave = kFALSE;
151 if (opt.Contains(
"/G")) geomanim = kTRUE;
152 if (opt.Contains(
"/S")) issave = kTRUE;
154 TVirtualGeoPainter *p = gGeoManager->GetGeomPainter();
155 Double_t *box = p->GetViewBox();
156 box[0] = box[1] = box[2] = 0;
157 box[3] = box[4] = box[5] = 100;
158 gGeoManager->SetTminTmax(0,0);
160 Double_t start[6], end[6];
162 Double_t dlat=0, dlong=0, dpsi=0;
163 Double_t dd[6] = {0,0,0,0,0,0};
165 p->EstimateCameraMove(tmin+5*dt, tmin+15*dt, start, end);
166 for (i=0; i<3; i++) {
167 start[i+3] = 20 + 1.3*start[i+3];
168 end[i+3] = 20 + 0.9*end[i+3];
170 for (i=0; i<6; i++) {
171 dd[i] = (end[i]-start[i])/10.;
173 memcpy(box, start, 6*
sizeof(Double_t));
174 p->GetViewAngles(dlong,dlat,dpsi);
175 dlong = (-206-dlong)/Double_t(nframes);
176 dlat = (126-dlat)/Double_t(nframes);
177 dpsi = (75-dpsi)/Double_t(nframes);
181 for (i=0; i<nframes; i++) {
182 if (t-delt<0) gGeoManager->SetTminTmax(0,t);
183 else gGeoManager->SetTminTmax(t-delt,t);
185 for (j=0; j<6; j++) box[j]+=dd[j];
186 p->GrabFocus(1,dlong,dlat,dpsi);
192 fname = TString::Format(
"anim%04d.gif", i);
197 gGeoManager->SetAnimateTracks(kFALSE);
203 void TGeoTrack::AddPoint(Double_t x, Double_t y, Double_t z, Double_t t)
207 fPoints =
new Double_t[fPointsSize];
209 if (fNpoints>=fPointsSize) {
210 Double_t *temp =
new Double_t[2*fPointsSize];
211 memcpy(temp, fPoints, fNpoints*
sizeof(Double_t));
217 fPoints[fNpoints++] = x;
218 fPoints[fNpoints++] = y;
219 fPoints[fNpoints++] = z;
220 fPoints[fNpoints++] = t;
226 void TGeoTrack::Browse(TBrowser *b)
229 Int_t nd = GetNdaughters();
234 for (Int_t i=0; i<nd; i++)
235 b->Add(GetDaughter(i));
242 Int_t TGeoTrack::DistancetoPrimitive(Int_t px, Int_t py)
244 const Int_t inaxis = 7;
245 const Int_t maxdist = 5;
249 Int_t puxmin = gPad->XtoAbsPixel(gPad->GetUxmin());
250 Int_t puymin = gPad->YtoAbsPixel(gPad->GetUymin());
251 Int_t puxmax = gPad->XtoAbsPixel(gPad->GetUxmax());
252 Int_t puymax = gPad->YtoAbsPixel(gPad->GetUymax());
255 if (px < puxmin - inaxis)
return dist;
256 if (py > puymin + inaxis)
return dist;
257 if (px > puxmax + inaxis)
return dist;
258 if (py < puymax - inaxis)
return dist;
260 TView *view = gPad->GetView();
261 if (!view)
return dist;
263 if (TObject::TestBit(kGeoPDrawn) && Size(imin,imax)>=2) {
265 Double_t x1,y1,x2,y2;
267 Int_t np = fNpoints>>2;
269 if (imax>np-1) imax=np-1;
270 for (i=imin;i<imax;i++) {
271 view->WCtoNDC(&fPoints[i<<2], xndc);
274 view->WCtoNDC(&fPoints[(i+1)<<2], xndc);
277 dsegment = DistancetoLine(px,py,x1,y1,x2,y2);
279 if (dsegment < dist) {
282 gPad->SetSelected(
this);
289 Int_t nd = GetNdaughters();
290 if (!nd)
return dist;
292 for (Int_t
id=0;
id<nd;
id++) {
293 track = (TGeoTrack*)GetDaughter(
id);
294 dist = track->DistancetoPrimitive(px,py);
295 if (dist<maxdist)
return 0;
312 void TGeoTrack::Draw(Option_t *option)
314 if (!gPad) gGeoManager->GetMasterVolume()->Draw();
315 char *opt1 = Compress(option);
317 Bool_t is_default = kTRUE;
318 Bool_t is_onelevel = kFALSE;
319 Bool_t is_all = kFALSE;
320 Bool_t is_type = kFALSE;
321 if (opt.Contains(
"/D")) {
325 if (opt.Contains(
"/*")) {
329 if (opt.Contains(
"/N")) {
331 Int_t ist = opt.Index(
"/N")+2;
332 Int_t ilast = opt.Index(
"/",ist);
333 if (ilast<0) ilast=opt.Length();
334 TString type = opt(ist, ilast-ist);
335 gGeoManager->SetParticleName(type.Data());
337 SetBits(is_default, is_onelevel, is_all, is_type);
339 if (!gGeoManager->IsAnimatingTracks()) {
350 void TGeoTrack::ExecuteEvent(Int_t , Int_t , Int_t )
353 gPad->SetCursor(kHand);
359 char *TGeoTrack::GetObjectInfo(Int_t , Int_t )
const
362 Double_t x=0,y=0,z=0,t=0;
364 info = TString::Format(
"%s (%g, %g, %g) tof=%g", GetName(),x,y,z,t);
365 return (
char*)info.Data();
371 Int_t TGeoTrack::GetPoint(Int_t i, Double_t &x, Double_t &y, Double_t &z, Double_t &t)
const
373 Int_t np = fNpoints>>2;
375 Error(
"GetPoint",
"no point %i, indmax=%d", i, np-1);
389 const Double_t *TGeoTrack::GetPoint(Int_t i)
const
391 if (!fNpoints)
return 0;
392 return (&fPoints[i<<2]);
399 Int_t TGeoTrack::GetPoint(Double_t tof, Double_t *point, Int_t istart)
const
401 Int_t np = fNpoints>>2;
402 if (istart>(np-2))
return (np-1);
403 Int_t ip = SearchPoint(tof, istart);
404 if (ip<0 || ip>(np-2))
return ip;
409 Double_t dt = tof-fPoints[j+3];
410 Double_t ddt = fPoints[k+3]-fPoints[j+3];
411 for (i=0; i<3; i++) point[i] = fPoints[j+i] +(fPoints[k+i]-fPoints[j+i])*dt/ddt;
418 void TGeoTrack::Paint(Option_t *option)
420 Bool_t is_default = TObject::TestBit(kGeoPDefault);
421 Bool_t is_onelevel = TObject::TestBit(kGeoPOnelevel);
422 Bool_t is_all = TObject::TestBit(kGeoPAllDaughters);
423 Bool_t is_type = TObject::TestBit(kGeoPType);
424 Bool_t match_type = kTRUE;
425 TObject::SetBit(kGeoPDrawn, kFALSE);
427 const char *type = gGeoManager->GetParticleName();
428 if (strlen(type) && strcmp(type, GetName())) match_type=kFALSE;
431 if (is_default || is_onelevel || is_all) PaintTrack(option);
434 Int_t nd = GetNdaughters();
435 if (!nd || is_default)
return;
437 for (Int_t i=0; i<nd; i++) {
438 track = (TGeoTrack*)GetDaughter(i);
439 if (track->IsInTimeRange()) {
440 track->SetBits(is_default,kFALSE,is_all,is_type);
441 track->Paint(option);
449 void TGeoTrack::PaintCollect(Double_t time, Double_t *box)
451 Bool_t is_default = TObject::TestBit(kGeoPDefault);
452 Bool_t is_onelevel = TObject::TestBit(kGeoPOnelevel);
453 Bool_t is_all = TObject::TestBit(kGeoPAllDaughters);
454 Bool_t is_type = TObject::TestBit(kGeoPType);
455 Bool_t match_type = kTRUE;
457 const char *type = gGeoManager->GetParticleName();
458 if (strlen(type) && strcmp(type, GetName())) match_type=kFALSE;
461 if (is_default || is_onelevel || is_all) PaintCollectTrack(time, box);
464 Int_t nd = GetNdaughters();
465 if (!nd || is_default)
return;
467 for (Int_t i=0; i<nd; i++) {
468 track = (TGeoTrack*)GetDaughter(i);
469 if (track) track->PaintCollect(time, box);
476 void TGeoTrack::PaintCollectTrack(Double_t time, Double_t *box)
478 TVirtualGeoPainter *painter = gGeoManager->GetGeomPainter();
479 if (!painter)
return;
480 Int_t np = fNpoints>>2;
481 Double_t point[3], local[3];
482 Bool_t convert = (gGeoManager->GetTopVolume() == gGeoManager->GetMasterVolume())?kFALSE:kTRUE;
483 Int_t ip = GetPoint(time, point);
484 if (ip>=0 && ip<np-1) {
485 if (convert) gGeoManager->MasterToTop(point, local);
486 else memcpy(local, point, 3*
sizeof(Double_t));
487 painter->AddTrackPoint(local, box);
494 void TGeoTrack::PaintMarker(Double_t *point, Option_t *)
498 TView *view = gPad->GetView();
500 view->WCtoNDC(point, xndc);
501 if (xndc[0] < gPad->GetX1() || xndc[0] > gPad->GetX2())
return;
502 if (xndc[1] < gPad->GetY1() || xndc[1] > gPad->GetY2())
return;
503 p.fX = gPad->XtoPixel(xndc[0]);
504 p.fY = gPad->YtoPixel(xndc[1]);
505 TAttMarker::Modify();
506 gVirtualX->DrawPolyMarker(1, &p);
512 void TGeoTrack::PaintTrack(Option_t *option)
523 TObject::SetBit(kGeoPDrawn, kFALSE);
524 if (opt.Contains(
"x"))
return;
525 Int_t np = fNpoints>>2;
529 Double_t start[3] = {0.,0.,0.};
530 Double_t end[3] = {0.,0.,0.};
531 Double_t seg[6] = {0.,0.,0.,0.,0.,0.};
532 Bool_t convert = (gGeoManager->GetTopVolume() == gGeoManager->GetMasterVolume())?kFALSE:kTRUE;
533 Double_t tmin=0.,tmax=0.;
534 Bool_t is_time = gGeoManager->GetTminTmax(tmin,tmax);
536 imin = GetPoint(tmin, start);
537 if (imin>=0 && imin<np-1) {
539 imax = GetPoint(tmax, end, imin);
546 gGeoManager->MasterToTop(start, &seg[0]);
547 gGeoManager->MasterToTop(end, &seg[3]);
548 gPad->PaintLine3D(&seg[0], &seg[3]);
550 gPad->PaintLine3D(start, end);
556 gGeoManager->MasterToTop(start, &seg[0]);
557 gGeoManager->MasterToTop(&fPoints[(imin+1)<<2], &seg[3]);
558 gPad->PaintLine3D(&seg[0], &seg[3]);
559 gGeoManager->MasterToTop(&fPoints[imax<<2], &seg[0]);
560 gGeoManager->MasterToTop(end, &seg[3]);
561 gPad->PaintLine3D(&seg[0], &seg[3]);
562 for (ip=imin+1; ip<imax; ip++) {
563 gGeoManager->MasterToTop(&fPoints[ip<<2], &seg[0]);
564 gGeoManager->MasterToTop(&fPoints[(ip+1)<<2], &seg[3]);
565 gPad->PaintLine3D(&seg[0], &seg[3]);
568 gPad->PaintLine3D(start, &fPoints[(imin+1)<<2]);
569 gPad->PaintLine3D(&fPoints[imax<<2], end);
570 for (ip=imin+1; ip<imax; ip++) {
571 gPad->PaintLine3D(&fPoints[ip<<2], &fPoints[(ip+1)<<2]);
576 gGeoManager->MasterToTop(end, &seg[0]);
577 PaintMarker(&seg[0]);
584 gGeoManager->MasterToTop(start, &seg[0]);
585 gGeoManager->MasterToTop(&fPoints[(imin+1)<<2], &seg[3]);
586 gPad->PaintLine3D(&seg[0], &seg[3]);
587 for (ip=imin+1; ip<np-2; ip++) {
588 gGeoManager->MasterToTop(&fPoints[ip<<2], &seg[0]);
589 gGeoManager->MasterToTop(&fPoints[(ip+1)<<2], &seg[3]);
590 gPad->PaintLine3D(&seg[0], &seg[3]);
593 gPad->PaintLine3D(start, &fPoints[(imin+1)<<2]);
594 for (ip=imin+1; ip<np-2; ip++) {
595 gPad->PaintLine3D(&fPoints[ip<<2], &fPoints[(ip+1)<<2]);
600 imax = GetPoint(tmax, end);
601 if (imax<0 || imax>=(np-1))
return;
605 for (ip=0; ip<imax-1; ip++) {
606 gGeoManager->MasterToTop(&fPoints[ip<<2], &seg[0]);
607 gGeoManager->MasterToTop(&fPoints[(ip+1)<<2], &seg[3]);
608 gPad->PaintLine3D(&seg[0], &seg[3]);
611 for (ip=0; ip<imax-1; ip++) {
612 gPad->PaintLine3D(&fPoints[ip<<2], &fPoints[(ip+1)<<2]);
616 gGeoManager->MasterToTop(&fPoints[imax<<2], &seg[0]);
617 gGeoManager->MasterToTop(end, &seg[3]);
618 gPad->PaintLine3D(&seg[0], &seg[3]);
619 PaintMarker(&seg[3]);
621 gPad->PaintLine3D(&fPoints[imax<<2], end);
625 TObject::SetBit(kGeoPDrawn);
630 TObject::SetBit(kGeoPDrawn);
632 for (ip=imin; ip<imax; ip++) {
633 gPad->PaintLine3D(&fPoints[ip<<2], &fPoints[(ip+1)<<2]);
640 void TGeoTrack::Print(Option_t * )
const
642 Int_t np = fNpoints>>2;
643 printf(
" TGeoTrack%6i : %s ===============================\n", fId,GetName());
644 printf(
" parent =%6i nd =%3i\n", (fParent)?fParent->GetId():-1, GetNdaughters());
645 Double_t x=0,y=0,z=0,t=0;
647 printf(
" production vertex : (%g, %g, %g) at tof=%g\n", x,y,z,t);
648 GetPoint(np-1,x,y,z,t);
649 printf(
" Npoints =%6i, last : (%g, %g, %g) at tof=%g\n\n", np,x,y,z,t);
656 Int_t TGeoTrack::Size(Int_t &imin, Int_t &imax)
659 Int_t np = fNpoints>>2;
663 if (!gGeoManager->GetTminTmax(tmin, tmax))
return size;
664 imin = SearchPoint(tmin);
665 imax = SearchPoint(tmax, imin);
666 return (imax-imin+1);
673 Int_t TGeoTrack::SearchPoint(Double_t time, Int_t istart)
const
675 Int_t nabove, nbelow, middle, midloc;
676 Int_t np = fNpoints>>2;
679 while (nabove-nbelow > 1) {
680 middle = (nabove+nbelow)/2;
681 midloc = ((middle-1)<<2)+3;
682 if (time == fPoints[midloc])
return middle-1;
683 if (time < fPoints[midloc]) nabove = middle;
684 else nbelow = middle;
692 void TGeoTrack::SetBits(Bool_t is_default, Bool_t is_onelevel,
693 Bool_t is_all, Bool_t is_type)
695 TObject::SetBit(kGeoPDefault, is_default);
696 TObject::SetBit(kGeoPOnelevel, is_onelevel);
697 TObject::SetBit(kGeoPAllDaughters, is_all);
698 TObject::SetBit(kGeoPType, is_type);
704 void TGeoTrack::Sizeof3D()
const
711 void TGeoTrack::ResetTrack()
715 if (fTracks) {fTracks->Delete();
delete fTracks;}
717 if (fPoints)
delete [] fPoints;