NCFS-Pack
A generic (astro)particle physics analysis framework
 
Loading...
Searching...
No Matches
NcHelix.cxx
Go to the documentation of this file.
1
31
33
171
172#include "NcHelix.h"
173#include "Riostream.h"
174
175ClassImp(NcHelix); // Class implementation to enable ROOT I/O
176
179{
185
186 fRefresh=0;
187 fCurves=0;
188 fExt=0;
189 fTofmax=1e-8;
190 fMstyle=-1;
191 fMsize=0;
192 fMcol=0;
193 fEnduse=1;
194
195 fLineWidth=2;
196 fLineColor=-1;
197}
198
200{
206
207 if (fCurves)
208 {
209 delete fCurves;
210 fCurves=0;
211 }
212 if (fExt)
213 {
214 delete fExt;
215 fExt=0;
216 }
217}
218
219NcHelix::NcHelix(const NcHelix& h) : THelix(h)
220{
226
227 fB=h.fB;
231 fMsize=h.fMsize;
232 fMcol=h.fMcol;
234}
235
237{
243
244 fB=b;
245
246 if (fB.GetNorm()>0)
247 {
248 Double_t axis[3];
249 fB.GetVector(axis,"car");
250 SetAxis(axis);
251 }
252}
253
255{
261
262 return fB;
263}
264
265void NcHelix::SetTofmax(Float_t tof)
266{
279
280 fTofmax=tof;
281}
282
283Float_t NcHelix::GetTofmax() const
284{
290
291 return fTofmax;
292}
293
294void NcHelix::SetMarker(Int_t style,Float_t size,Int_t col)
295{
305
306 fMstyle=style;
307 fMsize=size;
308 fMcol=col;
309}
310
311void NcHelix::UseEndPoint(Int_t mode)
312{
324
325 if (mode==0 || mode==1) fEnduse=mode;
326}
327
328void NcHelix::MakeCurve(NcTrack* t,Double_t* range,Int_t iaxis,Double_t scale)
329{
369
370 SetPolyLine(0); // Reset the polyline data points
371
372 if (!t || (range && !iaxis)) return;
373
374 Double_t energy=t->GetEnergy(1); // Track energy in GeV
375 Double_t betanorm=t->GetBeta();
376
377 if (energy<=0 || betanorm<=0) return;
378
379 NcPosition* rbeg=t->GetBeginPoint();
380 NcPosition* rend=0;
381 if (fEnduse) rend=t->GetEndPoint();
382 NcPosition* rref=t->GetReferencePoint();
383
384 // Magnetic field vector or default Z-direction
385 Double_t bvec[3]={0,0,1};
386 if (fB.GetNorm()>0) fB.GetVector(bvec,"car");
387
388 // The unit scale for locations if not specified by the user
389 if (scale<=0)
390 {
391 scale=1; // Set default to meter
392 if (rbeg)
393 {
394 scale=rbeg->GetUnitScale();
395 }
396 else if (rend)
397 {
398 scale=rend->GetUnitScale();
399 }
400 else if (rref)
401 {
402 scale=rref->GetUnitScale();
403 }
404 }
405
406 Double_t c=2.99792458e8/scale; // Lightspeed in the selected unit scale
407
408 // The helix angular frequency
409 Double_t w=9e7*(t->GetCharge()*fB.GetNorm())/energy;
410
411 // The particle velocity in the LAB frame
412 Nc3Vector beta=t->GetBetaVector();
413 Nc3Vector v=beta*c;
414 Double_t vel[3];
415 v.GetVector(vel,"car");
416
417 // The particle velocity in the Helix frame
418 Nc3Vector betaprim=beta.GetPrimed(fRotMat);
419 v=v.GetPrimed(fRotMat);
420 Double_t velprim[3];
421 v.GetVector(velprim,"car");
422
423 // Check compatibility of velocity and range specification.
424 if (range)
425 {
426 Double_t betavec[3];
427 if (iaxis>0) beta.GetVector(betavec,"car");
428 if (iaxis<0) betaprim.GetVector(betavec,"car");
429 if (fabs(betavec[abs(iaxis)-1])/betanorm<1e-10) return;
430 }
431
432 // The LAB location in which the velocity of the particle is defined
433 Double_t loc[3]={0,0,0};
434 Nc3Vector rx;
435 Double_t scalex=-1;
436 if (rref)
437 {
438 rx=(Nc3Vector)(*rref);
439 scalex=rref->GetUnitScale();
440 }
441 else if (rbeg)
442 {
443 rx=(Nc3Vector)(*rbeg);
444 scalex=rbeg->GetUnitScale();
445 }
446 else if (rend)
447 {
448 rx=(Nc3Vector)(*rend);
449 scalex=rend->GetUnitScale();
450 }
451
452 if (scalex>0 && (scalex/scale>1.1 || scale/scalex>1.1)) rx*=scalex/scale;
453 rx.GetVector(loc,"car");
454
455 // Initialisation of Helix kinematics
456 SetHelix(loc,vel,w,0,kUnchanged,bvec);
457
458 Int_t bend=0;
459 if (fabs(w)>0 && fabs(fVt)>0) bend=1;
460
461 // Flight time boundaries.
462 // The time origin t=0 is chosen to indicate the position in which
463 // the particle velocity was defined.
464 // The total flight time is initialised to the (user specified) tofmax.
465 Double_t tmin=0,tmax=0;
466 Double_t tof=fTofmax;
467 Double_t dum=0;
468
469 // The trajectory begin and end points
470 Double_t vec1[3]={0,0,0};
471 Double_t vec2[3]={0,0,0};
472 Nc3Vector r1;
473 Nc3Vector r2;
474 Double_t scale1=1;
475 Double_t scale2=1;
476
477 if (!bend)
478 {
480 // Treatment of straight trajectories //
482 Nc3Vector r;
483 if (range) // Specified range allows for exact flight time boundaries
484 {
485 if (iaxis>0)
486 {
487 tmin=(range[0]-loc[iaxis-1])/vel[iaxis-1];
488 tmax=(range[1]-loc[iaxis-1])/vel[iaxis-1];
489 }
490 else
491 {
492 loc[0]=fX0;
493 loc[1]=fY0;
494 loc[2]=fZ0;
495 tmin=(range[0]-loc[abs(iaxis)-1])/velprim[abs(iaxis)-1];
496 tmax=(range[1]-loc[abs(iaxis)-1])/velprim[abs(iaxis)-1];
497 }
498 if (tmax<tmin)
499 {
500 dum=tmin;
501 tmin=tmax;
502 tmax=dum;
503 }
504 // Make the 'curve' in the LAB frame and exit.
505 // Use the parametrisation : r(t)=r0+t*v
506 // using the range based flight time boundaries.
507 // An additional point in the middle of the trajectory is
508 // generated in view of accuracy in the case of extrapolations.
509 tof=tmax-tmin;
510 v=beta*c;
511 r1=rx;
512 r=v*tmin;
513 r1=r1+r;
514 r1.GetVector(vec1,"car");
515 SetNextPoint(float(vec1[0]),float(vec1[1]),float(vec1[2]));
516 r=v*(tof/2.);
517 r2=r1+r;
518 r2.GetVector(vec2,"car");
519 SetNextPoint(float(vec2[0]),float(vec2[1]),float(vec2[2]));
520 r=v*tof;
521 r2=r1+r;
522 r2.GetVector(vec2,"car");
523 SetNextPoint(float(vec2[0]),float(vec2[1]),float(vec2[2]));
524 }
525 else // Automatic range determination
526 {
527 // Initially the point with Z=0 in the Helix frame is taken as a starting point.
528 // In case this point can't be reached, the point in which the particle velocity
529 // was defined is taken as the starting point.
530 // The endpoint is initially obtained by applying the tofmax from the start point.
531 tmin=0;
532 if (fabs(fVz)>0) tmin=-fZ0/fVz;
533 v=beta*c;
534 r1=rx;
535 r=v*tmin;
536 r1=r1+r;
537
538 // Override the initial begin and endpoint settings by the track data
539 if (rbeg)
540 {
541 r1=(Nc3Vector)(*rbeg);
542 scale1=rbeg->GetUnitScale();
543 // All coordinates in the selected unit scale
544 if (scale1/scale>1.1 || scale/scale1>1.1) r1*=scale1/scale;
545 }
546
547 r=v*fTofmax;
548 r2=r1+r;
549 if (rend)
550 {
551 r2=(Nc3Vector)(*rend);
552 scale2=rend->GetUnitScale();
553 // All coordinates in the selected unit scale
554 if (scale2/scale>1.1 || scale/scale2>1.1) r2*=scale2/scale;
555 }
556
557 r1.GetVector(vec1,"car");
558 r2.GetVector(vec2,"car");
559
560 // Make the 'curve' in the LAB frame and exit.
561 SetNextPoint(float(vec1[0]),float(vec1[1]),float(vec1[2]));
562 SetNextPoint(float(vec2[0]),float(vec2[1]),float(vec2[2]));
563 }
564 }
565 else
566 {
568 // Treatment of curved trajectories //
570
571 // Initialisation of the flight time boundaries.
572 // Based on the constant motion of the particle along the Helix Z-axis,
573 // the parametrisation z(t)=z0+fVz*t in the Helix frame is used.
574 // If possible the point with Z=0 in the Helix frame is taken as a starting point.
575 // In case this point can't be reached, the point in which the particle velocity
576 // was defined is taken as the starting point.
577 tmin=0;
578 if (fabs(fVz)>0) tmin=-fZ0/fVz;
579 tmax=tmin+fTofmax;
580
581 if (tmax<tmin)
582 {
583 dum=tmin;
584 tmin=tmax;
585 tmax=dum;
586 }
587
588 // Determination of the range in the helix frame
589
590 if (!range) // Automatic range determination
591 {
592 scale1=1;
593 scale2=1;
594 if (rbeg)
595 {
596 r1=rbeg->GetPrimed(fRotMat);
597 scale1=rbeg->GetUnitScale();
598 // All coordinates in the selected unit scale
599 if (scale1/scale>1.1 || scale/scale1>1.1) r1*=scale1/scale;
600 // Re-calculate the tmin for this new starting point
601 r1.GetVector(vec1,"car");
602 if (fabs(fVz)>0) tmin=(vec1[2]-fZ0)/fVz;
603 tmax=tmin+fTofmax;
604 }
605 if (rend)
606 {
607 r2=rend->GetPrimed(fRotMat);
608 scale2=rend->GetUnitScale();
609 // All coordinates in the selected unit scale
610 if (scale2/scale>1.1 || scale/scale2>1.1) r2*=scale2/scale;
611 r2.GetVector(vec2,"car");
612 if (fabs(fVz)>0) tmax=(vec2[2]-fZ0)/fVz;
613 }
614 // Make the curve on basis of the flight time boundaries and exit
615 if (tmax<tmin)
616 {
617 dum=tmin;
618 tmin=tmax;
619 tmax=dum;
620 }
621 SetRange(tmin,tmax,kHelixT);
622 }
623 else // User explicitly specified range
624 {
625 vec1[abs(iaxis)-1]=range[0];
626 vec2[abs(iaxis)-1]=range[1];
627 r1.SetVector(vec1,"car");
628 r2.SetVector(vec2,"car");
629 if (iaxis>0) // Range specified in LAB frame
630 {
631 r1=r1.GetPrimed(fRotMat);
632 r1.GetVector(vec1,"car");
633 r2=r2.GetPrimed(fRotMat);
634 r2.GetVector(vec2,"car");
635 }
636 // Determination of the axis component with the
637 // largest range difference
638 Double_t dmax=0;
639 Int_t imax=0;
640 Double_t test=0;
641 for (Int_t i=0; i<3; i++)
642 {
643 test=fabs(vec1[i]-vec2[i]);
644 if (test>dmax)
645 {
646 dmax=test;
647 imax=i;
648 }
649 }
650
651 Double_t rmin=vec1[imax];
652 Double_t rmax=vec2[imax];
653 if (rmax<rmin)
654 {
655 dum=rmin;
656 rmin=rmax;
657 rmax=dum;
658 }
659
660 // The kinematic range boundaries in the helix frame
661 Double_t xmin=fX0-fVt/fW;
662 Double_t xmax=fX0+fVt/fW;
663 Double_t ymin=fY0-fVt/fW;
664 Double_t ymax=fY0+fVt/fW;
665
666 if (xmax<xmin)
667 {
668 dum=xmin;
669 xmin=xmax;
670 xmax=dum;
671 }
672 if (ymax<ymin)
673 {
674 dum=ymin;
675 ymin=ymax;
676 ymax=dum;
677 }
678
679 // Set the range for the helix
680 if (imax==2 && dmax>0) SetRange(rmin,rmax,kHelixZ);
681 if (imax==1)
682 {
683 // Limit range to kinematic boundaries if needed
684 if (rmin<=ymin) rmin=ymin+1e-6*dmax;
685 if (rmax>=ymax) rmax=ymax-1e-6*dmax;
686 if (rmin<rmax) SetRange(rmin,rmax,kHelixY);
687 }
688 if (imax==0)
689 {
690 // Limit range to kinematic boundaries if needed
691 if (rmin<=xmin) rmin=xmin+1e-6*dmax;
692 if (rmax>=xmax) rmax=xmax-1e-6*dmax;
693 if (rmin<rmax) SetRange(rmin,rmax,kHelixX);
694 }
695 }
696 }
697 return;
698}
699
700void NcHelix::Display(NcTrack* t,Double_t* range,Int_t iaxis,Double_t scale)
701{
752
753 if (!t || (range && !iaxis)) return;
754
755 MakeCurve(t,range,iaxis,scale);
756
757 if (fRefresh>0) Refresh(fRefresh);
758
759 Int_t np=GetLastPoint()+1;
760 if (!np) return;
761
762 Float_t* points=GetP();
763 TPolyLine3D* curve=new TPolyLine3D(np,points);
764
765 curve->SetLineWidth(fLineWidth);
766 if (fLineColor<0)
767 {
768 Float_t q=t->GetCharge();
769 curve->SetLineColor(kGreen);
770 if (q>0) curve->SetLineColor(kRed);
771 if (q<0) curve->SetLineColor(kBlue);
772 }
773 else
774 {
775 curve->SetLineColor(fLineColor);
776 }
777 curve->Draw();
778
779 if (!fCurves)
780 {
781 fCurves=new TObjArray();
782 fCurves->SetOwner();
783 }
784 fCurves->Add(curve);
785
786 // Display the marker for the track starting point
787 if (fMstyle>0)
788 {
789 TPolyMarker3D* m=new TPolyMarker3D();
790 m->SetPoint(0,points[0],points[1],points[2]);
791 m->SetMarkerStyle(fMstyle);
792 m->SetMarkerSize(fMsize);
793 Int_t col=curve->GetLineColor();
794 if (fMcol>0) col=fMcol;
795 m->SetMarkerColor(col);
796 m->Draw();
797 fCurves->Add(m);
798 }
799}
800
801void NcHelix::Refresh(Int_t mode)
802{
816
817 if (abs(mode)<2) fRefresh=mode;
818 if (fCurves) fCurves->Delete();
819}
820
821void NcHelix::Display(NcEvent* evt,Double_t* range,Int_t iaxis,Double_t scale)
822{
847
848 if (!evt) return;
849
850 if (fRefresh<0) Refresh(fRefresh);
851
852 Int_t ntk=evt->GetNtracks();
853 for (Int_t jtk=1; jtk<=ntk; jtk++)
854 {
855 NcTrack* tx=evt->GetTrack(jtk);
856 if (tx) Display(tx,range,iaxis,scale);
857 }
858}
859
860void NcHelix::Display(TObjArray* arr,Double_t* range,Int_t iaxis,Double_t scale)
861{
888
889 if (!arr) return;
890
891 Int_t ntk=arr->GetEntries();
892 for (Int_t jtk=0; jtk<ntk; jtk++)
893 {
894 TObject* obj=arr->At(jtk);
895 if (!obj) continue;
896 if (!(obj->InheritsFrom("NcTrack"))) continue;
897 NcTrack* tx=(NcTrack*)obj;
898 Display(tx,range,iaxis,scale);
899 }
900}
901
902NcPosition* NcHelix::Extrapolate(NcTrack* t,Double_t* pars,Double_t scale)
903{
945
946 if (fExt)
947 {
948 delete fExt;
949 fExt=0;
950 }
951
952 if (!t || !pars) return fExt;
953
954 NcPosition* rbeg=t->GetBeginPoint();
955 NcPosition* rend=t->GetEndPoint();
956 NcPosition* rref=t->GetReferencePoint();
957
958 // The unit scale for locations if not specified by the user
959 if (scale<=0)
960 {
961 scale=1; // Set default to meter
962 if (rbeg)
963 {
964 scale=rbeg->GetUnitScale();
965 }
966 else if (rend)
967 {
968 scale=rend->GetUnitScale();
969 }
970 else if (rref)
971 {
972 scale=rref->GetUnitScale();
973 }
974 }
975
976 Double_t range[2];
977 range[0]=pars[0]-fabs(pars[1])/2.;
978 range[1]=pars[0]+fabs(pars[1])/2.;
979
980 Int_t iaxis=int(pars[2]);
981
982 MakeCurve(t,range,iaxis,scale);
983
984 Int_t np=GetLastPoint()+1;
985 if (!np) return fExt;
986
987 Float_t* points=GetP();
988
989 // First point of the curve around the impact
990 Int_t ip=0;
991 Float_t first[3]={points[3*ip],points[3*ip+1],points[3*ip+2]};
992
993 // Last point of the curve around the impact
994 ip=GetLastPoint();
995 Float_t last[3]={points[3*ip],points[3*ip+1],points[3*ip+2]};
996
997 // The accuracy on the impact point
998 Float_t err[3];
999 err[0]=fabs(first[0]-last[0]);
1000 err[1]=fabs(first[1]-last[1]);
1001 err[2]=fabs(first[2]-last[2]);
1002
1003 // Take the middle point as impact location
1004 ip=np/2;
1005 Float_t imp[3]={points[3*ip],points[3*ip+1],points[3*ip+2]};
1006
1007 fExt=new NcPosition();
1008 fExt->SetUnitScale(scale);
1009 fExt->SetPosition(imp,"car");
1010 fExt->SetPositionErrors(err,"car");
1011
1012 return fExt;
1013}
1014
ClassImp(NcHelix)
Handling of 3-vectors in various reference frames.
Definition Nc3Vector.h:15
void SetVector(Double_t *v, TString f, TString u="rad")
void GetVector(Double_t *v, TString f, TString u="rad") const
Nc3Vector GetPrimed(TRotMatrix *m) const
Nc3Vector GetBetaVector() const
Double_t GetBeta()
Creation and investigation of an NCFS generic event structure.
Definition NcEvent.h:15
Representation and extrapolation of NcTracks in a magnetic field.
Definition NcHelix.h:17
void UseEndPoint(Int_t mode=1)
Definition NcHelix.cxx:311
Nc3Vector & GetB()
Definition NcHelix.cxx:254
void SetTofmax(Float_t tof)
Definition NcHelix.cxx:265
NcPosition * Extrapolate(NcTrack *t, Double_t *pars=0, Double_t scale=-1)
Definition NcHelix.cxx:902
Int_t fMstyle
Definition NcHelix.h:39
Int_t fMcol
Definition NcHelix.h:41
TObjArray * fCurves
! Temp. storage for the curves on the drawing
Definition NcHelix.h:43
void Display(NcTrack *t, Double_t *range=0, Int_t iaxis=3, Double_t scale=-1)
Definition NcHelix.cxx:700
Float_t fTofmax
Definition NcHelix.h:37
Nc3Vector fB
Definition NcHelix.h:36
Float_t fMsize
Definition NcHelix.h:40
void SetB(Nc3Vector &b)
Definition NcHelix.cxx:236
void MakeCurve(NcTrack *t, Double_t *range=0, Int_t iaxis=3, Double_t scale=-1)
Definition NcHelix.cxx:328
void SetMarker(Int_t marker=8, Float_t size=0.2, Int_t color=-1)
Definition NcHelix.cxx:294
Int_t fRefresh
Definition NcHelix.h:38
void Refresh(Int_t mode=0)
Definition NcHelix.cxx:801
Int_t fEnduse
Definition NcHelix.h:42
NcPosition * fExt
! The extrapolation result
Definition NcHelix.h:44
virtual ~NcHelix()
Definition NcHelix.cxx:199
Float_t GetTofmax() const
Definition NcHelix.cxx:283
Int_t GetNtracks(Int_t idmode=0, Int_t chmode=2, Int_t pcode=0)
Definition NcJet.cxx:564
NcTrack * GetTrack(Int_t i) const
Definition NcJet.cxx:751
Handling of positions (with timestamps) in various reference frames.
Definition NcPosition.h:18
Float_t GetUnitScale() const
Handling of the attributes of a reconstructed particle track.
Definition NcTrack.h:19
NcPosition * GetEndPoint()
Definition NcTrack.cxx:1458
NcPosition * GetBeginPoint()
Definition NcTrack.cxx:1435
Double_t GetEnergy(Float_t scale=-1)
Definition NcTrack.cxx:721
NcPosition * GetReferencePoint()
Definition NcTrack.cxx:1485
Float_t GetCharge() const
Definition NcTrack.cxx:710