diff --git a/Hlt/RecoConf/python/RecoConf/hlt2_tracking.py b/Hlt/RecoConf/python/RecoConf/hlt2_tracking.py index 7c7ea16016c78b8a1eb10c40f6504bdb1b2157db..310cd6225cc9f37647722876e54069e6e031714f 100644 --- a/Hlt/RecoConf/python/RecoConf/hlt2_tracking.py +++ b/Hlt/RecoConf/python/RecoConf/hlt2_tracking.py @@ -35,6 +35,7 @@ from PyConf.Algorithms import ( PrLongLivedTracking, PrMatchNN, PrResidualPrUTHits, + PrResidualPrUTHits_v1Tracks, PrResidualSciFiHits, PrResidualSeedingLong, PrResidualVeloTracks, @@ -43,6 +44,7 @@ from PyConf.Algorithms import ( TrackCloneKiller, TrackContainersMerger, TrackContainerSplitter, + TrackContainersSharedMerger, TrackEventFitter, TrackSelectionMerger, TrackSelectionToContainer, @@ -505,6 +507,7 @@ def make_PrLongLivedTracking_tracks( scifi_tracks, make_ut_hits=make_PrStorePrUTHits_hits, clusters_on_track_tool=get_global_clusters_on_track_tool, + highMassTunings=False, ): """Makes downstream tracks from SciFi seed tracks and UT hits using PrLongLivedTracking. @@ -516,9 +519,25 @@ def make_PrLongLivedTracking_tracks( Returns: A dict mapping v1 and v2 downstream tracks to ``'v1'`` and ``'v2'`` respectively. """ - downstream_tracks = PrLongLivedTracking( - InputLocation=scifi_tracks["Pr"], UTHits=make_ut_hits() - ).OutputLocation + if highMassTunings: + downstream_tracks = PrLongLivedTracking( + InputLocation=scifi_tracks["Pr"], + UTHits=make_ut_hits(), + UseHighMassTunings=highMassTunings, + XPredTolConst=220000.0, + XPredTolOffset=6.6, + GhostProbCut=0.65, + YPredTolConst=10.0, + YPredTolOffset=2.7, + MinPt=200.0, + InitialMinPt=100.0, + WeightsFileName="paramfile://data/GhostProbability/hlt2_PrLongLivedTracking_MLP_w_BSM.json", + ).OutputLocation + + else: + downstream_tracks = PrLongLivedTracking( + InputLocation=scifi_tracks["Pr"], UTHits=make_ut_hits() + ).OutputLocation downstream_tracks_v1 = fromPrDownstreamTracksV1Tracks( InputTracksLocation=downstream_tracks, @@ -1377,7 +1396,6 @@ def make_pr_kf_light_reco_best_tracks( Returns: DataHandles: dictionary of BestLong, BestDownstream, BestUpstream, SeedDecloned, BestSeed, BestVelo, BestVeloBackward """ - from PyConf.Algorithms import ( PrCloneKillerDown, PrCloneKillerLong, @@ -1463,7 +1481,7 @@ def make_pr_kf_light_reco_best_tracks( hits_ft=ft_hits, ) - best_down = make_TrackBestTrackCreator_tracks( + best_down1 = make_TrackBestTrackCreator_tracks( tracks=[fitted_down], name="TBTC_down_{hash}", get_ghost_tools=get_GhostProbabilityTools(track_type="Downstream"), @@ -1476,9 +1494,78 @@ def make_pr_kf_light_reco_best_tracks( TracksRefContainer=best_long, ).TracksOutContainer - seed_decloned_pr = PrCloneKillerSeedDown( + seed_vs_bestlong_down1 = PrCloneKillerSeedDown( TracksInContainer=seed_vs_bestlong, - TracksRefContainer=best_down, + TracksRefContainer=best_down1, + ).TracksOutContainer + + # NOTE: This de-cloning seemingly costs a lot of efficiency in "notLong" + # categories, particularly at p > 5 GeV. This is because we actually have + # a correct Long track matched to a MC particle, but it is *not* tagged + # Long-reconstructible and therefore falls into the "notLong" Upstream category. + # So this is correct behaviour because we rather want to keep a reconstructed-but- + # not-reconstructible Long track than an Upstream track which actually made it to + # a Long track. + declonned_up = PrCloneKillerUp( + TracksInContainer=tracks["Upstream"]["Pr"], + TracksRefContainer=best_long, + ).TracksOutContainer + + fitted_up = make_PrKalmanFilter_Upstream_tracks( + input_tracks=declonned_up, hits_ut=ut_hits, hits_vp=vp_hits + ) + + best_up = make_TrackBestTrackCreator_tracks( + tracks=[fitted_up], + name="TBTC_up_{hash}", + get_ghost_tools=get_GhostProbabilityTools(track_type="Upstream"), + do_not_refit=True, + fit_tracks=False, + )["Best"] + + ### second pass for non-SM long-lived / Downstream stracks + + # NOTE! the 'v1' tracks here are only for reference, not decloned at all + seed_for_leftover_down = {"Pr": seed_vs_bestlong_down1, "v1": tracks["Seed"]["v1"]} + + make_residual_uthits = partial( + make_ReducePrUTHits_fromV1, + { + "v1": TrackContainersSharedMerger( + InputLocations=[best_long, best_down1, best_up] + ).OutputLocation + }, + ) + + leftover_down = make_PrLongLivedTracking_tracks( + seed_for_leftover_down, make_ut_hits=make_residual_uthits, highMassTunings=True + ) + + fitted_leftover_down = make_PrKalmanFilter_Downstream_tracks( + input_tracks=leftover_down["Pr"], + hits_ut=make_residual_uthits(), + hits_ft=ft_hits, + ) + + best_down2 = make_TrackBestTrackCreator_tracks( + tracks=[fitted_leftover_down], + name="TBTC_leftover_down_{hash}", + get_ghost_tools=get_GhostProbabilityTools(track_type="Downstream"), + do_not_refit=True, + fit_tracks=False, + )["Best"] + + # combine with default Downstream to form one container + # history flag can be used to separate them afterwards + best_down = TrackContainersMerger( + InputLocations=[best_down1, best_down2] + ).OutputLocation + + ### + + seed_decloned_pr = PrCloneKillerSeedDown( + TracksInContainer=seed_vs_bestlong_down1, + TracksRefContainer=best_down2, ).TracksOutContainer seed_decloned = fromPrSeedingTracksV1Tracks( @@ -1503,6 +1590,7 @@ def make_pr_kf_light_reco_best_tracks( input_tracks=seed_decloned_pr, hits_ft=ft_hits ) + # these are used in selections decloned_filtered_seed_pr = TtracksMVAFilter( InputLocation=seed_decloned_pr ).OutputTracks @@ -1514,29 +1602,7 @@ def make_pr_kf_light_reco_best_tracks( input_tracks=decloned_filtered_seed_pr, hits_ft=ft_hits ) - # NOTE: This de-cloning seemingly costs a lot of efficiency in "notLong" - # categories, particularly at p > 5 GeV. This is because we actually have - # a correct Long track matched to a MC particle, but it is *not* tagged - # Long-reconstructible and therefore falls into the "notLong" Upstream category. - # So this is correct behaviour because we rather want to keep a reconstructed-but- - # not-reconstructible Long track than an Upstream track which actually made it to - # a Long track. - declonned_up = PrCloneKillerUp( - TracksInContainer=tracks["Upstream"]["Pr"], - TracksRefContainer=best_long, - ).TracksOutContainer - - fitted_up = make_PrKalmanFilter_Upstream_tracks( - input_tracks=declonned_up, hits_ut=ut_hits, hits_vp=vp_hits - ) - - best_up = make_TrackBestTrackCreator_tracks( - tracks=[fitted_up], - name="TBTC_up_{hash}", - get_ghost_tools=get_GhostProbabilityTools(track_type="Upstream"), - do_not_refit=True, - fit_tracks=False, - )["Best"] + ### velo_fitted = make_PrKalmanFilter_Velo_tracks( input_tracks=tracks["Velo"]["Pr"], @@ -1894,6 +1960,16 @@ def make_ReducePrUTHits_fromLong(input_tracks, make_ut_hits=make_PrStorePrUTHits ).PrUTHitsOutput +@configurable +def make_ReducePrUTHits_fromV1(input_tracks, make_ut_hits=make_PrStorePrUTHits_hits): + """ + Function to remove PrUTHits used by Long tracks and create a new PrUTHits container for the residual PrUTHits, which are later used as input to PrLongLivedTracking or PrForwardTracking + """ + return PrResidualPrUTHits_v1Tracks( + TracksLocation=input_tracks["v1"], PrUTHitsLocation=make_ut_hits() + ).PrUTHitsOutput + + def get_fast_hlt2_tracks(): """Function to get fast set of tracks reconstructed in HLT2