FairShip
Loading...
Searching...
No Matches
shipStrawTracking Namespace Reference

Functions

int get_n_hits (hits)
 
def cmp (a, int b)
 
def run_track_pattern_recognition (input_file, geo_file, output_file, method, dy=None)
 
def extrapolateToPlane (fT, z)
 
def fracMCsame (trackids)
 
def getReconstructibleTracks (int iEvent, sTree, sGeo, ShipGeo)
 
def getPtruthFirst (sTree, mcPartKey)
 
None save_hists (h, path)
 Helping functions #####################################################.
 
def init_book_hist ()
 

Variables

ArgumentParser parser = ArgumentParser(description=__doc__)
 Main ###############################################################.
 
 help
 
 required
 
 default
 
 choices
 
ArgumentParser options = parser.parse_args()
 
def metrics = run_track_pattern_recognition(options.input, options.geo, options.output, options.method)
 

Detailed Description

Script to run and test tracking in the straw tubes

Function Documentation

◆ cmp()

def shipStrawTracking.cmp (   a,
int  b 
)

Definition at line 26 of file shipStrawTracking.py.

26def cmp(a, b: int):
27 return (a > b) - (a < b)
28
29

◆ extrapolateToPlane()

def shipStrawTracking.extrapolateToPlane (   fT,
  z 
)

Definition at line 513 of file shipStrawTracking.py.

513def extrapolateToPlane(fT, z):
514 # etrapolate to a plane perpendicular to beam direction (z)
515 rc, pos, mom = False, None, None
516 parallelToZ = ROOT.TVector3(0.0, 0.0, 1.0)
517 fst = fT.getFitStatus()
518 if fst.isFitConverged():
519 # test for fit status for each point
520 if fT.getPoint(0).getFitterInfo() and fT.getPoint(1).getFitterInfo():
521 fstate0, fstate1 = fT.getFittedState(0), fT.getFittedState(1)
522 fPos0, fPos1 = fstate0.getPos(), fstate1.getPos()
523 if abs(z - fPos0.z()) < abs(z - fPos1.z()):
524 fstate = fstate0
525 else:
526 fstate = fstate1
527 zs = z
528 NewPosition = ROOT.TVector3(0.0, 0.0, zs)
529 rep = ROOT.genfit.RKTrackRep(13 * cmp(fstate.getPDG(), 0))
530 state = ROOT.genfit.StateOnPlane(rep)
531 pos, mom = fstate.getPos(), fstate.getMom()
532 rep.setPosMom(state, pos, mom)
533 detPlane = ROOT.genfit.DetPlane(NewPosition, parallelToZ)
534 detPlanePtr = ROOT.genfit.SharedPlanePtr(detPlane)
535 try:
536 rep.extrapolateToPlane(state, detPlanePtr)
537 pos, mom = state.getPos(), state.getMom()
538 rc = True
539 except Exception:
540 print("error with extrapolation")
541 if not rc:
542 # use linear extrapolation
543 px, py, pz = mom.X(), mom.Y(), mom.Z()
544 lam = (z - pos.Z()) / pz
545 pos = ROOT.TVector3(pos.X() + lam * px, pos.Y() + lam * py, z)
546 return rc, pos, mom
547
548

◆ fracMCsame()

def shipStrawTracking.fracMCsame (   trackids)
Estimates max fraction of true hit labels for a recognized track.
trackids : array_like
    hit indexes of a recognized track
Returns
-------
frac : float
    Max fraction of true hit labels.
tmax : int
    True hit label with max fraction in a recognized track.

Definition at line 552 of file shipStrawTracking.py.

552def fracMCsame(trackids):
553 """
554 Estimates max fraction of true hit labels for a recognized track.
555 trackids : array_like
556 hit indexes of a recognized track
557 Returns
558 -------
559 frac : float
560 Max fraction of true hit labels.
561 tmax : int
562 True hit label with max fraction in a recognized track.
563 """
564
565 track = {}
566 nh = len(trackids)
567
568 for tid in trackids:
569 if tid in track:
570 track[tid] += 1
571 else:
572 track[tid] = 1
573
574 # now get track with largest number of hits
575 if track != {}:
576 tmax = max(track, key=track.get)
577 else:
578 track = {-999: 0}
579 tmax = -999
580
581 frac = 0.0
582 if nh > 0:
583 frac = float(track[tmax]) / float(nh)
584
585 return frac, tmax
586
587

◆ get_n_hits()

int shipStrawTracking.get_n_hits (   hits)

Definition at line 22 of file shipStrawTracking.py.

22def get_n_hits(hits) -> int:
23 return len(hits)
24
25

◆ getPtruthFirst()

def shipStrawTracking.getPtruthFirst (   sTree,
  mcPartKey 
)

Definition at line 786 of file shipStrawTracking.py.

786def getPtruthFirst(sTree, mcPartKey):
787 Ptruth, Ptruthx, Ptruthy, Ptruthz = -1.0, -1.0, -1.0, -1.0
788 for ahit in sTree.strawtubesPoint:
789 if ahit.GetTrackID() == mcPartKey:
790 Ptruthx, Ptruthy, Ptruthz = ahit.GetPx(), ahit.GetPy(), ahit.GetPz()
791 Ptruth = ROOT.TMath.Sqrt(Ptruthx**2 + Ptruthy**2 + Ptruthz**2)
792 break
793 return Ptruth, Ptruthx, Ptruthy, Ptruthz
794
795

◆ getReconstructibleTracks()

def shipStrawTracking.getReconstructibleTracks ( int  iEvent,
  sTree,
  sGeo,
  ShipGeo 
)
Estimates reconstructible tracks of an event.
Parameters
----------
iEvent : int
    Event id.
stree : root file
    Events in raw format.
fGeo : object
    Contains SHiP detector geometry.
ShipGeo : object
    Contains SHiP detector geometry.
Returns
-------
MCTrackIDs : array-like
    List of reconstructible track ids.

Definition at line 591 of file shipStrawTracking.py.

591def getReconstructibleTracks(iEvent: int, sTree, sGeo, ShipGeo):
592 """
593 Estimates reconstructible tracks of an event.
594 Parameters
595 ----------
596 iEvent : int
597 Event id.
598 stree : root file
599 Events in raw format.
600 fGeo : object
601 Contains SHiP detector geometry.
602 ShipGeo : object
603 Contains SHiP detector geometry.
604 Returns
605 -------
606 MCTrackIDs : array-like
607 List of reconstructible track ids.
608 """
609
610 TStationz = ShipGeo.TrackStation1.z
611 Zpos = (
612 TStationz - 3.0 / 2.0 * ShipGeo.strawtubes_geo.delta_z_view - 1.0 / 2.0 * ShipGeo.strawtubes_geo.delta_z_layer
613 )
614 TStation1StartZ = Zpos - ShipGeo.strawtubes_geo.outer_straw_diameter / 2.0
615
616 TStationz = ShipGeo.TrackStation4.z
617 Zpos = (
618 TStationz + 3.0 / 2.0 * ShipGeo.strawtubes_geo.delta_z_view + 1.0 / 2.0 * ShipGeo.strawtubes_geo.delta_z_layer
619 )
620 TStation4EndZ = Zpos + ShipGeo.strawtubes_geo.outer_straw_diameter / 2.0
621
622 ROOT.TDatabasePDG.Instance()
623
624 # returns a list of reconstructible tracks for this event
625 # call this routine once for each event before smearing
626 MCTrackIDs = []
627 sTree.GetEvent(iEvent)
628 nMCTracks = sTree.MCTrack.GetEntriesFast()
629
630 # 1. MCTrackIDs: list of tracks decaying after the last tstation and originating before the first
631 for i in reversed(range(nMCTracks)):
632 atrack = sTree.MCTrack.At(i)
633 # track endpoint after tstations?
634 if atrack.GetStartZ() > TStation4EndZ:
635 motherId = atrack.GetMotherId()
636 if motherId > -1:
637 mothertrack = sTree.MCTrack.At(motherId)
638 mothertrackZ = mothertrack.GetStartZ()
639 # this mother track is a HNL decay
640 # track starts inside the decay volume? (before 1 st tstation)
641 if mothertrackZ < TStation1StartZ and motherId not in MCTrackIDs:
642 MCTrackIDs.append(motherId)
643
644 if len(MCTrackIDs) == 0:
645 return MCTrackIDs
646
647 # 2. hitsinTimeDet: list of tracks with hits in TimeDet
648 # nVetoHits = sTree.vetoPoint.GetEntriesFast()
649 # hitsinTimeDet=[]
650 # for i in range(nVetoHits):
651 # avetohit = sTree.vetoPoint.At(i)
652 # #hit in TimeDet?
653 # if sGeo.FindNode(avetohit.GetX(), avetohit.GetY(), avetohit.GetZ()).GetName() == 'TimeDet_1':
654 # if avetohit.GetTrackID() not in hitsinTimeDet:
655 # hitsinTimeDet.append(avetohit.GetTrackID())
656
657 # 3. Remove tracks from MCTrackIDs that are not in hitsinTimeDet
658 # itemstoremove = []
659 # for item in MCTrackIDs:
660 # if item not in hitsinTimeDet:
661 # itemstoremove.append(item)
662 # for item in itemstoremove:
663 # MCTrackIDs.remove(item)
664
665 # if len(MCTrackIDs)==0:
666 # return MCTrackIDs
667
668 # 4. Find straws that have multiple hits
669 nHits = sTree.strawtubesPoint.GetEntriesFast()
670 hitstraws = {}
671 duplicatestrawhit = []
672
673 for i in range(nHits):
674 ahit = sTree.strawtubesPoint[i]
675 strawname = str(ahit.GetDetectorID())
676
677 if strawname in hitstraws:
678 # straw was already hit
679 if ahit.GetX() > hitstraws[strawname][1]:
680 # this hit has higher x, discard it
681 duplicatestrawhit.append(i)
682 else:
683 # del hitstraws[strawname]
684 duplicatestrawhit.append(hitstraws[strawname][0])
685 hitstraws[strawname] = [i, ahit.GetX()]
686 else:
687 hitstraws[strawname] = [i, ahit.GetX()]
688
689 # 5. Split hits up by station and outside stations
690 hits1 = {}
691 hits2 = {}
692 hits3 = {}
693 hits4 = {}
694 trackoutsidestations = []
695
696 for i in range(nHits):
697 if i in duplicatestrawhit:
698 continue
699
700 ahit = sTree.strawtubesPoint[i]
701
702 # is hit inside acceptance? if not mark the track as bad
703 if ((ahit.GetX() / 245.0) ** 2 + (ahit.GetY() / 495.0) ** 2) >= 1.0:
704 if ahit.GetTrackID() not in trackoutsidestations:
705 trackoutsidestations.append(ahit.GetTrackID())
706
707 if ahit.GetTrackID() not in MCTrackIDs:
708 # hit on not reconstructible track
709 continue
710
711 # group hits per tracking station, key = trackid
712 if str(ahit.GetDetectorID())[:1] == "1":
713 if ahit.GetTrackID() in hits1:
714 hits1[ahit.GetTrackID()] = [hits1[ahit.GetTrackID()][0], i]
715 else:
716 hits1[ahit.GetTrackID()] = [i]
717
718 if str(ahit.GetDetectorID())[:1] == "2":
719 if ahit.GetTrackID() in hits2:
720 hits2[ahit.GetTrackID()] = [hits2[ahit.GetTrackID()][0], i]
721 else:
722 hits2[ahit.GetTrackID()] = [i]
723
724 if str(ahit.GetDetectorID())[:1] == "3":
725 if ahit.GetTrackID() in hits3:
726 hits3[ahit.GetTrackID()] = [hits3[ahit.GetTrackID()][0], i]
727 else:
728 hits3[ahit.GetTrackID()] = [i]
729
730 if str(ahit.GetDetectorID())[:1] == "4":
731 if ahit.GetTrackID() in hits4:
732 hits4[ahit.GetTrackID()] = [hits4[ahit.GetTrackID()][0], i]
733 else:
734 hits4[ahit.GetTrackID()] = [i]
735
736 # 6. Make list of tracks with hits in in station 1,2,3 & 4
737 tracks_with_hits_in_all_stations = []
738
739 for key in hits1:
740 if (key in hits2 and key in hits3) and key in hits4:
741 if key not in tracks_with_hits_in_all_stations and key not in trackoutsidestations:
742 tracks_with_hits_in_all_stations.append(key)
743
744 for key in hits2:
745 if (key in hits1 and key in hits3) and key in hits4:
746 if key not in tracks_with_hits_in_all_stations and key not in trackoutsidestations:
747 tracks_with_hits_in_all_stations.append(key)
748
749 for key in hits3:
750 if (key in hits2 and key in hits1) and key in hits4:
751 if key not in tracks_with_hits_in_all_stations and key not in trackoutsidestations:
752 tracks_with_hits_in_all_stations.append(key)
753
754 for key in hits4:
755 if (key in hits2 and key in hits3) and key in hits1:
756 if key not in tracks_with_hits_in_all_stations and key not in trackoutsidestations:
757 tracks_with_hits_in_all_stations.append(key)
758
759 # 7. Remove tracks from MCTrackIDs with hits outside acceptance or doesn't have hits in all stations
760 itemstoremove = []
761
762 for item in MCTrackIDs:
763 if item not in tracks_with_hits_in_all_stations:
764 itemstoremove.append(item)
765
766 for item in itemstoremove:
767 MCTrackIDs.remove(item)
768
769 if len(MCTrackIDs) == 0:
770 return MCTrackIDs
771
772 itemstoremove = []
773
774 for item in MCTrackIDs:
775 atrack = sTree.MCTrack.At(item)
776 motherId = atrack.GetMotherId()
777 if motherId != 2: #!!!!
778 itemstoremove.append(item)
779
780 for item in itemstoremove:
781 MCTrackIDs.remove(item)
782
783 return MCTrackIDs
784
785

◆ init_book_hist()

def shipStrawTracking.init_book_hist ( )
Creates empty plots.
Returns
-------
h : dict
    Dictionary of plots.

Definition at line 822 of file shipStrawTracking.py.

822def init_book_hist():
823 """
824 Creates empty plots.
825 Returns
826 -------
827 h : dict
828 Dictionary of plots.
829 """
830
831 h = {} # dictionary of histograms
832
833 ut.bookHist(h, "TracksPassed", "Tracks passing the pattern recognition", 8, -0.5, 7.5)
834 h["TracksPassed"].GetXaxis().SetBinLabel(1, "Reconstructible tracks")
835 h["TracksPassed"].GetXaxis().SetBinLabel(2, "Y view station 1&2")
836 h["TracksPassed"].GetXaxis().SetBinLabel(3, "Stereo station 1&2")
837 h["TracksPassed"].GetXaxis().SetBinLabel(4, "station 1&2")
838 h["TracksPassed"].GetXaxis().SetBinLabel(5, "Y view station 3&4")
839 h["TracksPassed"].GetXaxis().SetBinLabel(6, "Stereo station 3&4")
840 h["TracksPassed"].GetXaxis().SetBinLabel(7, "station 3&4")
841 h["TracksPassed"].GetXaxis().SetBinLabel(8, "Combined stations 1&2/3&4")
842
843 ut.bookHist(h, "TracksPassedU", "Tracks passing the pattern recognition. No clones.", 8, -0.5, 7.5)
844 h["TracksPassedU"].GetXaxis().SetBinLabel(1, "Reconstructible tracks")
845 h["TracksPassedU"].GetXaxis().SetBinLabel(2, "Y view station 1&2")
846 h["TracksPassedU"].GetXaxis().SetBinLabel(3, "Stereo station 1&2")
847 h["TracksPassedU"].GetXaxis().SetBinLabel(4, "station 1&2")
848 h["TracksPassedU"].GetXaxis().SetBinLabel(5, "Y view station 3&4")
849 h["TracksPassedU"].GetXaxis().SetBinLabel(6, "Stereo station 3&4")
850 h["TracksPassedU"].GetXaxis().SetBinLabel(7, "station 3&4")
851 h["TracksPassedU"].GetXaxis().SetBinLabel(8, "Combined stations 1&2/3&4")
852
853 ut.bookProf(h, "TracksPassed_p", "Tracks passing the pattern recognition from momentum", 30, 0, 150)
854 h["TracksPassed_p"].GetXaxis().SetTitle("Momentum")
855 h["TracksPassed_p"].GetYaxis().SetTitle("N")
856
857 ut.bookHist(h, "ptrue-p/ptrue", "(p - p-true)/p", 200, -0.25, 0.25)
858 ut.bookHist(h, "pttrue-pt/pttrue", "(pt - pt-true)/pt", 200, -0.25, 0.25)
859 ut.bookHist(h, "pxtrue-px/pxtrue", "(px - px-true)/px", 200, -0.25, 0.25)
860 ut.bookHist(h, "pytrue-py/pytrue", "(py - py-true)/py", 200, -0.25, 0.25)
861 ut.bookHist(h, "pztrue-pz/pztrue", "(pz - pz-true)/pz", 200, -0.25, 0.25)
862
863 ut.bookHist(h, "n_hits_reco", "Number of recognized hits per track, total", 64, 0.0, 64.01)
864 ut.bookHist(h, "n_hits_reco_12", "Number of recognized hits per track, station 1&2", 32, 0.0, 32.01)
865 ut.bookHist(h, "n_hits_reco_y12", "Number of recognized hits per track, Y view station 1&2", 32, 0.0, 32.01)
866 ut.bookHist(
867 h, "n_hits_reco_stereo12", "Number of recognized hits per track, Stereo view station 1&2", 32, 0.0, 32.01
868 )
869 ut.bookHist(h, "n_hits_reco_34", "Number of recognized hits per track, station 3&4", 32, 0.0, 32.01)
870 ut.bookHist(h, "n_hits_reco_y34", "Number of recognized hits per track, Y view station 3&4", 32, 0.0, 32.01)
871 ut.bookHist(
872 h, "n_hits_reco_stereo34", "Number of recognized hits per track, Stereo view station 3&4", 32, 0.0, 32.01
873 )
874
875 # Momentum dependences
876 ut.bookProf(h, "n_hits_total", "Number of recognized hits per track, total", 30, 0, 150)
877 h["n_hits_total"].GetXaxis().SetTitle("Momentum")
878 h["n_hits_total"].GetYaxis().SetTitle("N")
879
880 ut.bookProf(h, "n_hits_y12", "Number of recognized hits per track, Y view station 1&2", 30, 0, 150)
881 h["n_hits_y12"].GetXaxis().SetTitle("Momentum")
882 h["n_hits_y12"].GetYaxis().SetTitle("N")
883
884 ut.bookProf(h, "n_hits_stereo12", "Number of recognized hits per track, Stereo view station 1&2", 30, 0, 150)
885 h["n_hits_stereo12"].GetXaxis().SetTitle("Momentum")
886 h["n_hits_stereo12"].GetYaxis().SetTitle("N")
887
888 ut.bookProf(h, "n_hits_12", "Number of recognized hits per track, station 1&2", 30, 0, 150)
889 h["n_hits_12"].GetXaxis().SetTitle("Momentum")
890 h["n_hits_12"].GetYaxis().SetTitle("N")
891
892 ut.bookProf(h, "n_hits_y34", "Number of recognized hits per track, Y view station 3&4", 30, 0, 150)
893 h["n_hits_y34"].GetXaxis().SetTitle("Momentum")
894 h["n_hits_y34"].GetYaxis().SetTitle("N")
895
896 ut.bookProf(h, "n_hits_stereo34", "Number of recognized hits per track, Stereo view station 3&4", 30, 0, 150)
897 h["n_hits_stereo34"].GetXaxis().SetTitle("Momentum")
898 h["n_hits_stereo34"].GetYaxis().SetTitle("N")
899
900 ut.bookProf(h, "n_hits_34", "Number of recognized hits per track, station 3&4", 30, 0, 150)
901 h["n_hits_34"].GetXaxis().SetTitle("Momentum")
902 h["n_hits_34"].GetYaxis().SetTitle("N")
903
904 ut.bookProf(h, "perr", "(p - p-true)/p", 30, 0, 150)
905 h["perr"].GetXaxis().SetTitle("Momentum")
906 h["perr"].GetYaxis().SetTitle("(p - p-true)/p")
907
908 ut.bookProf(h, "perr_direction", "(p - p-true)/p from track direction in YZ plane", 20, 0, 10.01)
909 h["perr_direction"].GetXaxis().SetTitle("Degree")
910 h["perr_direction"].GetYaxis().SetTitle("(p - p-true)/p")
911
912 ut.bookProf(h, "frac_total", "Fraction of hits the same as MC hits, total", 30, 0, 150)
913 h["frac_total"].GetXaxis().SetTitle("Momentum")
914 h["frac_total"].GetYaxis().SetTitle("Fraction")
915
916 ut.bookProf(h, "frac_y12", "Fraction of hits the same as MC hits, Y view station 1&2", 30, 0, 150)
917 h["frac_y12"].GetXaxis().SetTitle("Momentum")
918 h["frac_y12"].GetYaxis().SetTitle("Fraction")
919
920 ut.bookProf(h, "frac_stereo12", "Fraction of hits the same as MC hits, Stereo view station 1&2", 30, 0, 150)
921 h["frac_stereo12"].GetXaxis().SetTitle("Momentum")
922 h["frac_stereo12"].GetYaxis().SetTitle("Fraction")
923
924 ut.bookProf(h, "frac_12", "Fraction of hits the same as MC hits, station 1&2", 30, 0, 150)
925 h["frac_12"].GetXaxis().SetTitle("Momentum")
926 h["frac_12"].GetYaxis().SetTitle("Fraction")
927
928 ut.bookProf(h, "frac_y34", "Fraction of hits the same as MC hits, Y view station 3&4", 30, 0, 150)
929 h["frac_y34"].GetXaxis().SetTitle("Momentum")
930 h["frac_y34"].GetYaxis().SetTitle("Fraction")
931
932 ut.bookProf(h, "frac_stereo34", "Fraction of hits the same as MC hits, Stereo view station 3&4", 30, 0, 150)
933 h["frac_stereo34"].GetXaxis().SetTitle("Momentum")
934 h["frac_stereo34"].GetYaxis().SetTitle("Fraction")
935
936 ut.bookProf(h, "frac_34", "Fraction of hits the same as MC hits, station 3&4", 30, 0, 150)
937 h["frac_34"].GetXaxis().SetTitle("Momentum")
938 h["frac_34"].GetYaxis().SetTitle("Fraction")
939
940 ut.bookHist(h, "frac_y12_dist", "Fraction of hits the same as MC hits, Y view station 1&2", 50, 0.5, 1.001)
941 ut.bookHist(
942 h, "frac_stereo12_dist", "Fraction of hits the same as MC hits, Stereo view station 1&2", 50, 0.5, 1.001
943 )
944 ut.bookHist(h, "frac_12_dist", "Fraction of hits the same as MC hits, station 1&2", 50, 0.5, 1.001)
945 ut.bookHist(h, "frac_y34_dist", "Fraction of hits the same as MC hits, Y view station 3&4", 50, 0.5, 1.001)
946 ut.bookHist(
947 h, "frac_stereo34_dist", "Fraction of hits the same as MC hits, Stereo view station 3&4", 50, 0.5, 1.001
948 )
949 ut.bookHist(h, "frac_34_dist", "Fraction of hits the same as MC hits, station 3&4", 50, 0.5, 1.001)
950 ut.bookHist(h, "frac_total_dist", "Fraction of hits the same as MC hits, total", 50, 0.5, 1.001)
951
952 ut.bookHist(
953 h, "Reco_tracks", "Number of recognized tracks, clones and ghosts for reconstructible tracks.", 5, -0.5, 4.5
954 )
955 h["Reco_tracks"].GetXaxis().SetBinLabel(1, "N total")
956 h["Reco_tracks"].GetXaxis().SetBinLabel(2, "N recognized tracks")
957 h["Reco_tracks"].GetXaxis().SetBinLabel(3, "N clones")
958 h["Reco_tracks"].GetXaxis().SetBinLabel(4, "N ghosts")
959 h["Reco_tracks"].GetXaxis().SetBinLabel(5, "N others")
960
961 # Fitted values
962 ut.bookHist(h, "chi2fittedtracks", "Chi^2 per NDOF for fitted tracks", 210, -0.05, 20.05)
963 ut.bookHist(h, "pvalfittedtracks", "pval for fitted tracks", 110, -0.05, 1.05)
964 ut.bookHist(h, "momentumfittedtracks", "momentum for fitted tracks", 251, -0.05, 250.05)
965 ut.bookHist(h, "xdirectionfittedtracks", "x-direction for fitted tracks", 91, -0.5, 90.5)
966 ut.bookHist(h, "ydirectionfittedtracks", "y-direction for fitted tracks", 91, -0.5, 90.5)
967 ut.bookHist(h, "zdirectionfittedtracks", "z-direction for fitted tracks", 91, -0.5, 90.5)
968 ut.bookHist(h, "massfittedtracks", "mass fitted tracks", 210, -0.005, 0.205)
969 ut.bookHist(h, "pvspfitted", "p-patrec vs p-fitted", 401, -200.5, 200.5, 401, -200.5, 200.5)
970
971 ut.bookHist(h, "abs(x - x-true)", "Hits abs(x - x-true)", 260, -0.05, 5.05)
972 ut.bookHist(h, "abs(y - y-true)", "Hits abs(y - y-true)", 260, -0.05, 5.05)
973
974 ut.bookHist(h, "rmse_x", "Hits x fit rmse", 260, -0.05, 5.05)
975 ut.bookHist(h, "rmse_y", "Hits y fit rmse", 260, -0.05, 5.05)
976
977 return h
978
979

◆ run_track_pattern_recognition()

def shipStrawTracking.run_track_pattern_recognition (   input_file,
  geo_file,
  output_file,
  method,
  dy = None 
)
Runs all steps of track pattern recognition.
Parameters
----------
input_file : string
    Path to an input .root file with events.
geo_file : string
    Path to a file with SHiP geometry.
output_file : string
    Path to an output .root file with quality plots.
method : string
    Name of a track pattern recognition method.

Definition at line 30 of file shipStrawTracking.py.

30def run_track_pattern_recognition(input_file, geo_file, output_file, method, dy=None):
31 """
32 Runs all steps of track pattern recognition.
33 Parameters
34 ----------
35 input_file : string
36 Path to an input .root file with events.
37 geo_file : string
38 Path to a file with SHiP geometry.
39 output_file : string
40 Path to an output .root file with quality plots.
41 method : string
42 Name of a track pattern recognition method.
43 """
44
45
46
47 # Check geo file
48 try:
49 fgeo = ROOT.TFile(geo_file)
50 except Exception:
51 print("An error with opening the ship geo file.")
52 raise
53
54 sGeo = fgeo.Get("FAIRGeom")
55
56 # Prepare ShipGeo dictionary
57 if not fgeo.FindKey("ShipGeo"):
58 if dy:
59 ShipGeo = geometry_config.create_config(Yheight=dy)
60 else:
62 else:
63 ShipGeo = load_from_root_file(fgeo, "ShipGeo")
64
65 # Globals
66 global_variables.ShipGeo = ShipGeo
67
68
69
70 run = ROOT.FairRunSim()
71 run.SetName("TGeant4") # Transport engine
72 # Create dummy output file as the input file is updated directly and
73 # histograms are written to output file (hists.root by default)
74 run.SetSink(ROOT.FairRootFileSink(ROOT.TMemFile("output", "recreate")))
75 run.SetUserConfig("g4Config_basic.C") # geant4 transport not used, only needed for the mag field
76 run.GetRuntimeDb()
77
78 shipDet_conf.configure(run, ShipGeo)
79 run.Init()
80
81 # run = ROOT.FairRunSim()
82 # modules = shipDet_conf.configure(run,ShipGeo)
83
84
85
86 import geomGeant4
87
88 if hasattr(ShipGeo.Bfield, "fieldMap"):
89 fieldMaker = geomGeant4.addVMCFields(ShipGeo, "", True, withVirtualMC=False)
90 else:
91 print("no fieldmap given, geofile too old, not anymore support")
92 exit(-1)
93 sGeo = fgeo.Get("FAIRGeom")
94 geoMat = ROOT.genfit.TGeoMaterialInterface()
95 ROOT.genfit.MaterialEffects.getInstance().init(geoMat)
96 bfield = ROOT.genfit.FairShipFields()
97 bfield.setField(fieldMaker.getGlobalField())
98 fM = ROOT.genfit.FieldManager.getInstance()
99 fM.init(bfield)
100
101
102
103 # Check input file
104 try:
105 fn = ROOT.TFile(input_file, "update")
106 except Exception:
107 print("An error with opening the input data file.")
108 raise
109
110 sTree = fn.Get("cbmsim")
111 sTree.Write()
112
113
114
115 h = init_book_hist()
116
117
118
119 # Init book of hists for the quality measurements
120 metrics = {
121 "n_hits": [],
122 "reconstructible": 0,
123 "passed_y12": 0,
124 "passed_stereo12": 0,
125 "passed_12": 0,
126 "passed_y34": 0,
127 "passed_stereo34": 0,
128 "passed_34": 0,
129 "passed_combined": 0,
130 "reco_passed": 0,
131 "reco_passed_no_clones": 0,
132 "frac_y12": [],
133 "frac_stereo12": [],
134 "frac_12": [],
135 "frac_y34": [],
136 "frac_stereo34": [],
137 "frac_34": [],
138 "reco_frac_tot": [],
139 "reco_mc_p": [],
140 "reco_mc_theta": [],
141 "fitted_p": [],
142 "fitted_pval": [],
143 "fitted_chi": [],
144 "fitted_x": [],
145 "fitted_y": [],
146 "fitted_z": [],
147 "fitted_mass": [],
148 }
149
150 # Start event loop
151 nEvents = sTree.GetEntries()
152
153 for iEvent in range(nEvents):
154 if iEvent % 1000 == 0:
155 print("Event ", iEvent)
156
157
158
159 sTree.GetEvent(iEvent)
160
161
162
163 reconstructible_tracks = getReconstructibleTracks(iEvent, sTree, sGeo, ShipGeo)
164
165 metrics["reconstructible"] += len(reconstructible_tracks)
166 for i_reco in reconstructible_tracks:
167 h["TracksPassed"].Fill("Reconstructible tracks", 1)
168 h["TracksPassedU"].Fill("Reconstructible tracks", 1)
169
170 in_y12 = []
171 in_stereo12 = []
172 in_12 = []
173 in_y34 = []
174 in_stereo34 = []
175 in_34 = []
176 in_combo = []
177
178 found_track_ids = []
179 n_tracks = len(reconstructible_tracks)
180 n_recognized = 0
181 n_clones = 0
182 n_ghosts = 0
183 n_others = 0
184
185 min_eff = 0.0
186
187
188
189 nTracklets = sTree.Tracklets.GetEntriesFast()
190
191 for i_track in range(nTracklets):
192 atracklet = sTree.Tracklets[i_track]
193
194 if atracklet.getType() != 1: # this is a not full track (tracklet)
195 continue
196
197 atrack = atracklet.getList()
198
199 if len(atrack) == 0:
200 continue
201
202 hits = {
203 "X": [],
204 "Y": [],
205 "Z": [],
206 "DetID": [],
207 "TrackID": [],
208 "Pz": [],
209 "Px": [],
210 "Py": [],
211 "dist2Wire": [],
212 "Pdg": [],
213 }
214
215 for ihit in atrack:
216 ahit = sTree.strawtubesPoint[ihit]
217 hits["X"] += [ahit.GetX()]
218 hits["Y"] += [ahit.GetY()]
219 hits["Z"] += [ahit.GetZ()]
220 hits["DetID"] += [ahit.GetDetectorID()]
221 hits["TrackID"] += [ahit.GetTrackID()]
222 hits["Pz"] += [ahit.GetPz()]
223 hits["Px"] += [ahit.GetPx()]
224 hits["Py"] += [ahit.GetPy()]
225 hits["dist2Wire"] += [ahit.dist2Wire()]
226 hits["Pdg"] += [ahit.PdgCode()]
227
228 # List to numpy arrays
229 for key in hits:
230 hits[key] = numpy.array(hits[key])
231
232 # Decoding
233 decode = global_variables.modules["strawtubes"].StrawDecode(hits["DetID"])
234 # StrawDecode returns a tuple of (statnb, vnb, lnb, snb).
235 is_stereo = (decode[1] == 1) + (decode[1] == 2)
236 is_y = (decode[1] == 0) + (decode[1] == 3)
237 is_before = (decode[0] == 1) + (decode[0] == 2)
238 is_after = (decode[0] == 3) + (decode[0] == 4)
239
240 # Metrics
241 metrics["n_hits"] += [get_n_hits(hits["TrackID"])]
242
243 # Tracks passed
244 frac_y12, tmax_y12 = fracMCsame(hits["TrackID"][is_before * is_y])
245 n_hits_y12 = get_n_hits(hits["TrackID"][is_before * is_y])
246 frac_stereo12, tmax_stereo12 = fracMCsame(hits["TrackID"][is_before * is_stereo])
247 n_hits_stereo12 = get_n_hits(hits["TrackID"][is_before * is_stereo])
248 frac_12, tmax_12 = fracMCsame(hits["TrackID"][is_before])
249 n_hits_12 = get_n_hits(hits["TrackID"][is_before])
250
251 frac_y34, tmax_y34 = fracMCsame(hits["TrackID"][is_after * is_y])
252 n_hits_y34 = get_n_hits(hits["TrackID"][is_after * is_y])
253 frac_stereo34, tmax_stereo34 = fracMCsame(hits["TrackID"][is_after * is_stereo])
254 n_hits_stereo34 = get_n_hits(hits["TrackID"][is_after * is_stereo])
255 frac_34, tmax_34 = fracMCsame(hits["TrackID"][is_after])
256 n_hits_34 = get_n_hits(hits["TrackID"][is_after])
257 frac_tot, tmax_tot = fracMCsame(hits["TrackID"])
258 n_hits_tot = get_n_hits(hits["TrackID"])
259
260 if tmax_y12 == tmax_stereo12 and tmax_y12 == tmax_y34 and tmax_y12 == tmax_stereo34:
261 if (
262 frac_y12 >= min_eff
263 and frac_stereo12 >= min_eff
264 and frac_y34 >= min_eff
265 and frac_stereo34 >= min_eff
266 ):
267 if tmax_y12 in reconstructible_tracks and tmax_y12 not in found_track_ids:
268 n_recognized += 1
269 found_track_ids.append(tmax_y12)
270 elif tmax_y12 in reconstructible_tracks and tmax_y12 in found_track_ids:
271 n_clones += 1
272 elif tmax_y12 not in reconstructible_tracks:
273 n_others += 1
274
275 else:
276 n_ghosts += 1
277 else:
278 n_ghosts += 1
279
280 is_reconstructed = 0
281
282 if tmax_y12 in reconstructible_tracks:
283 metrics["passed_y12"] += 1
284 metrics["frac_y12"] += [frac_y12]
285 h["TracksPassed"].Fill("Y view station 1&2", 1)
286 if tmax_y12 not in in_y12:
287 h["TracksPassedU"].Fill("Y view station 1&2", 1)
288 in_y12.append(tmax_y12)
289
290 if tmax_stereo12 == tmax_y12:
291 metrics["passed_stereo12"] += 1
292 metrics["frac_stereo12"] += [frac_stereo12]
293 h["TracksPassed"].Fill("Stereo station 1&2", 1)
294 if tmax_stereo12 not in in_stereo12:
295 h["TracksPassedU"].Fill("Stereo station 1&2", 1)
296 in_stereo12.append(tmax_stereo12)
297
298 if tmax_12 == tmax_y12:
299 metrics["passed_12"] += 1
300 metrics["frac_12"] += [frac_12]
301 h["TracksPassed"].Fill("station 1&2", 1)
302 if tmax_12 not in in_12:
303 h["TracksPassedU"].Fill("station 1&2", 1)
304 in_12.append(tmax_12)
305
306 if tmax_y34 in reconstructible_tracks:
307 metrics["passed_y34"] += 1
308 metrics["frac_y34"] += [frac_y34]
309 h["TracksPassed"].Fill("Y view station 3&4", 1)
310 if tmax_y34 not in in_y34:
311 h["TracksPassedU"].Fill("Y view station 3&4", 1)
312 in_y34.append(tmax_y34)
313
314 if tmax_stereo34 == tmax_y34:
315 metrics["passed_stereo34"] += 1
316 metrics["frac_stereo34"] += [frac_stereo34]
317 h["TracksPassed"].Fill("Stereo station 3&4", 1)
318 if tmax_stereo34 not in in_stereo34:
319 h["TracksPassedU"].Fill("Stereo station 3&4", 1)
320 in_stereo34.append(tmax_stereo34)
321
322 if tmax_34 == tmax_y34:
323 metrics["passed_34"] += 1
324 metrics["frac_34"] += [frac_34]
325 h["TracksPassed"].Fill("station 3&4", 1)
326 if tmax_34 not in in_34:
327 h["TracksPassedU"].Fill("station 3&4", 1)
328 in_34.append(tmax_34)
329
330 if tmax_12 == tmax_34:
331 metrics["passed_combined"] += 1
332 h["TracksPassed"].Fill("Combined stations 1&2/3&4", 1)
333 metrics["reco_passed"] += 1
334 is_reconstructed = 1
335 if tmax_34 not in in_combo:
336 h["TracksPassedU"].Fill("Combined stations 1&2/3&4", 1)
337 metrics["reco_passed_no_clones"] += 1
338 in_combo.append(tmax_34)
339
340 # For reconstructed tracks
341 if is_reconstructed == 0:
342 continue
343
344 metrics["reco_frac_tot"] += [frac_tot]
345
346 # Momentum
347 hits["Pz"]
348 hits["Px"]
349 hits["Py"]
350
351 p, px, py, pz = getPtruthFirst(sTree, tmax_tot)
352 pt = math.sqrt(px**2 + py**2)
353
354 Z_true = []
355 X_true = []
356 Y_true = []
357 for ahit in sTree.strawtubesPoint:
358 if ahit.GetTrackID() == tmax_tot:
359 az, ax, ay = ahit.GetZ(), ahit.GetX(), ahit.GetY()
360 Z_true.append(az)
361 X_true.append(ax)
362 Y_true.append(ay)
363
364 metrics["reco_mc_p"] += [p]
365 h["TracksPassed_p"].Fill(p, 1)
366
367 # Direction
368 Z = hits["Z"][(hits["TrackID"] == tmax_tot) * is_before]
369 X = hits["X"][(hits["TrackID"] == tmax_tot) * is_before]
370 Y = hits["Y"][(hits["TrackID"] == tmax_tot) * is_before]
371 Z = Z - Z[0]
372 X = X - X[0]
373 Y = Y - Y[0]
374 R = numpy.sqrt(X**2 + Y**2 + Z**2)
375 Theta = numpy.arccos(Z[1:] / R[1:])
376 theta = numpy.mean(Theta)
377
378 metrics["reco_mc_theta"] += [theta]
379
380 h["n_hits_reco_y12"].Fill(n_hits_y12)
381 h["n_hits_reco_stereo12"].Fill(n_hits_stereo12)
382 h["n_hits_reco_12"].Fill(n_hits_12)
383 h["n_hits_reco_y34"].Fill(n_hits_y34)
384 h["n_hits_reco_stereo34"].Fill(n_hits_stereo34)
385 h["n_hits_reco_34"].Fill(n_hits_34)
386 h["n_hits_reco"].Fill(n_hits_tot)
387
388 h["n_hits_y12"].Fill(p, n_hits_y12)
389 h["n_hits_stereo12"].Fill(p, n_hits_stereo12)
390 h["n_hits_12"].Fill(p, n_hits_12)
391 h["n_hits_y34"].Fill(p, n_hits_y34)
392 h["n_hits_stereo34"].Fill(p, n_hits_stereo34)
393 h["n_hits_34"].Fill(p, n_hits_34)
394 h["n_hits_total"].Fill(p, n_hits_tot)
395
396 h["frac_y12"].Fill(p, frac_y12)
397 h["frac_stereo12"].Fill(p, frac_stereo12)
398 h["frac_12"].Fill(p, frac_12)
399 h["frac_y34"].Fill(p, frac_y34)
400 h["frac_stereo34"].Fill(p, frac_stereo34)
401 h["frac_34"].Fill(p, frac_34)
402 h["frac_total"].Fill(p, frac_tot)
403
404 h["frac_y12_dist"].Fill(frac_y12)
405 h["frac_stereo12_dist"].Fill(frac_stereo12)
406 h["frac_12_dist"].Fill(frac_12)
407 h["frac_y34_dist"].Fill(frac_y34)
408 h["frac_stereo34_dist"].Fill(frac_stereo34)
409 h["frac_34_dist"].Fill(frac_34)
410 h["frac_total_dist"].Fill(frac_tot)
411
412 # Fitted track
413
414 thetrack = sTree.FitTracks[i_track]
415
416 fitStatus = thetrack.getFitStatus()
417
418 nmeas = fitStatus.getNdf()
419 pval = fitStatus.getPVal()
420 chi2 = fitStatus.getChi2() / nmeas
421
422 metrics["fitted_pval"] += [pval]
423 metrics["fitted_chi"] += [chi2]
424
425 h["chi2fittedtracks"].Fill(chi2)
426 h["pvalfittedtracks"].Fill(pval)
427
428 try:
429 fittedState = thetrack.getFittedState()
430 fittedMom = fittedState.getMomMag()
431 fittedMom = fittedMom # *int(charge)
432
433 px_fit, py_fit, pz_fit = fittedState.getMom().x(), fittedState.getMom().y(), fittedState.getMom().z()
434 p_fit = fittedMom
435 pt_fit = math.sqrt(px_fit**2 + py_fit**2)
436
437 metrics["fitted_p"] += [p_fit]
438 perr = (p - p_fit) / p
439 h["ptrue-p/ptrue"].Fill(perr)
440 h["perr"].Fill(p, perr)
441 h["perr_direction"].Fill(numpy.rad2deg(theta), perr)
442
443 pterr = (pt - pt_fit) / pt
444 h["pttrue-pt/pttrue"].Fill(pterr)
445
446 pxerr = (px - px_fit) / px
447 h["pxtrue-px/pxtrue"].Fill(pxerr)
448
449 pyerr = (py - py_fit) / py
450 h["pytrue-py/pytrue"].Fill(pyerr)
451
452 pzerr = (pz - pz_fit) / pz
453 h["pztrue-pz/pztrue"].Fill(pzerr)
454
455 if math.fabs(p) > 0.0:
456 h["pvspfitted"].Fill(p, fittedMom)
457 fittedtrackDir = fittedState.getDir()
458 fittedx = math.degrees(math.acos(fittedtrackDir[0]))
459 fittedy = math.degrees(math.acos(fittedtrackDir[1]))
460 fittedz = math.degrees(math.acos(fittedtrackDir[2]))
461 fittedmass = fittedState.getMass()
462 h["momentumfittedtracks"].Fill(fittedMom)
463 h["xdirectionfittedtracks"].Fill(fittedx)
464 h["ydirectionfittedtracks"].Fill(fittedy)
465 h["zdirectionfittedtracks"].Fill(fittedz)
466 h["massfittedtracks"].Fill(fittedmass)
467
468 metrics["fitted_x"] += [fittedx]
469 metrics["fitted_y"] += [fittedy]
470 metrics["fitted_z"] += [fittedz]
471 metrics["fitted_mass"] += [fittedmass]
472
473 Z_fit = []
474 X_fit = []
475 Y_fit = []
476 for az in Z_true:
477 _rc, pos, _mom = extrapolateToPlane(thetrack, az)
478 Z_fit.append(pos.Z())
479 X_fit.append(pos.X())
480 Y_fit.append(pos.Y())
481
482 for i in range(len(Z_true)):
483 xerr = abs(X_fit[i] - X_true[i])
484 yerr = abs(Y_fit[i] - Y_true[i])
485 h["abs(x - x-true)"].Fill(xerr)
486 h["abs(y - y-true)"].Fill(yerr)
487
488 rmse_x = numpy.sqrt(numpy.mean((numpy.array(X_fit) - numpy.array(X_true)) ** 2))
489 rmse_y = numpy.sqrt(numpy.mean((numpy.array(Y_fit) - numpy.array(Y_true)) ** 2))
490 h["rmse_x"].Fill(rmse_x)
491 h["rmse_y"].Fill(rmse_y)
492
493 except Exception:
494 print("Problem with fitted state.")
495
496 h["Reco_tracks"].Fill("N total", n_tracks)
497 h["Reco_tracks"].Fill("N recognized tracks", n_recognized)
498 h["Reco_tracks"].Fill("N clones", n_clones)
499 h["Reco_tracks"].Fill("N ghosts", n_ghosts)
500 h["Reco_tracks"].Fill("N others", n_others)
501
502
503
504 save_hists(h, output_file)
505
506 return metrics
507
508
def addVMCFields(shipGeo, str controlFile="", bool verbose=False, bool withVirtualMC=True)
Definition: geomGeant4.py:165
def create_config(str DecayVolumeMedium="helium", float Yheight=6.0, int strawDesign=10, muShieldGeo=None, str shieldName="New_HA_Design", int nuTargetPassive=1, bool SND=True, SND_design=None, TARGET_YAML=None)
def configure(run, ship_geo)

◆ save_hists()

None shipStrawTracking.save_hists (   h,
  path 
)

Helping functions #####################################################.

Main functions ##############################################################

Save book of plots.
Parameters
----------
h : dict
    Dictionary of plots.
path : string
    Path where the plots will be saved.

Definition at line 809 of file shipStrawTracking.py.

809def save_hists(h, path) -> None:
810 """
811 Save book of plots.
812 Parameters
813 ----------
814 h : dict
815 Dictionary of plots.
816 path : string
817 Path where the plots will be saved.
818 """
819 ut.writeHists(h, path)
820
821

Variable Documentation

◆ choices

shipStrawTracking.choices

Definition at line 993 of file shipStrawTracking.py.

◆ default

shipStrawTracking.default

Definition at line 988 of file shipStrawTracking.py.

◆ help

shipStrawTracking.help

Definition at line 986 of file shipStrawTracking.py.

◆ metrics

def shipStrawTracking.metrics = run_track_pattern_recognition(options.input, options.geo, options.output, options.method)

Definition at line 998 of file shipStrawTracking.py.

◆ options

ArgumentParser shipStrawTracking.options = parser.parse_args()

Definition at line 996 of file shipStrawTracking.py.

◆ parser

ArgumentParser shipStrawTracking.parser = ArgumentParser(description=__doc__)

Main ###############################################################.

Definition at line 985 of file shipStrawTracking.py.

◆ required

shipStrawTracking.required

Definition at line 986 of file shipStrawTracking.py.