Belle II Software development
path_utils.py
1
2
9
10from pybasf2 import B2WARNING, B2FATAL
11
12from ROOT import Belle2 # noqa: make the Belle2 namespace available
13
14from basf2 import register_module
15from geometry import is_detector_present, are_detectors_present, is_any_detector_present
16from ckf.path_functions import add_pxd_ckf, add_ckf_based_merger, add_svd_ckf, add_cosmics_svd_ckf, add_cosmics_pxd_ckf
17from pxd import add_pxd_reconstruction
18from svd import add_svd_reconstruction
19from tracking.adjustments import adjust_module
20
21
22def use_local_sectormap(path, pathToLocalSM):
23 """ Helper function that sets up the SectorMapBootstrapModule in that way that a local sectormap will be
24 loaded instead the one from the DB. Has to be applied on the path after the SectorMapBootstrap was
25 put into the path (usually in add_reconstructin)
26
27 :param path: The path the SectorMapBootstrapModule is in.
28 :param pathToLocalSM: the local storage position of the sectormap (including the name)
29
30 """
31 B2WARNING("Warning will load local SectorMap from: " + pathToLocalSM)
32 adjust_module(path, 'SectorMapBootstrap', **{"ReadSecMapFromDB": False,
33 "ReadSectorMap": True, "SectorMapsInputFile": pathToLocalSM})
34
35
36def add_geometry_modules(path, components=None):
37 """
38 Helper function to add the geometry related modules needed for tracking
39 to the path.
40
41 :param path: The path to add the tracking reconstruction modules to
42 :param components: the list of geometry components in use or None for all components.
43 """
44 # check for detector geometry, necessary for track extrapolation in genfit
45 if 'Geometry' not in path:
46 path.add_module('Geometry', useDB=True)
47 if components is not None:
48 B2WARNING("Custom detector components specified: Will still build full geometry")
49
50 # Material effects for all track extrapolations
51 if 'SetupGenfitExtrapolation' not in path:
52 path.add_module('SetupGenfitExtrapolation',
53 energyLossBrems=False, noiseBrems=False)
54
55
56def add_hit_preparation_modules(path, components=None, pxd_filtering_offline=False, create_intercepts_for_pxd_ckf=False):
57 """
58 Helper function to prepare the hit information to be used by tracking.
59
60 :param path: The path to add the tracking reconstruction modules to
61 :param components: the list of geometry components in use or None for all components.
62 :param pxd_filtering_offline: PXD data reduction is performed after CDC and SVD tracking,
63 so PXD reconstruction has to wait until the ROIs are calculated.
64 :param create_intercepts_for_pxd_ckf: If True, the PXDROIFinder is added to the path to create PXDIntercepts to be used
65 for hit filtering when creating the CKF relations. This independent of the offline PXD digit filtering which is
66 steered by 'pxd_filtering_offline'. This can be applied for both data and MC.
67 """
68
69 # Preparation of the SVD clusters
70 if is_detector_present("SVD", components):
71 add_svd_reconstruction(path)
72
73 # Preparation of the PXD clusters
74 if is_detector_present("PXD", components) and not pxd_filtering_offline and not create_intercepts_for_pxd_ckf:
75 add_pxd_reconstruction(path)
76
77
78def add_track_fit_and_track_creator(path, components=None, pruneTracks=False, trackFitHypotheses=None,
79 reco_tracks="RecoTracks", add_mva_quality_indicator=False, v0_finding=True):
80 """
81 Helper function to add the modules performing the
82 track fit, the V0 fit and the Belle2 track creation to the path.
83
84 :param path: The path to add the tracking reconstruction modules to
85 :param components: the list of geometry components in use or None for all components.
86 :param pruneTracks: Delete all hits expect the first and the last from the found tracks.
87 :param reco_tracks: Name of the StoreArray where the reco tracks should be stored
88 :param v0_finding: if false, the V0Finder module is not executed
89 :param add_mva_quality_indicator: If true, add the MVA track quality estimation
90 to the path that sets the quality indicator property of the found tracks.
91 """
92
93 add_prefilter_track_fit_and_track_creator(path, components=components,
94 trackFitHypotheses=trackFitHypotheses,
95 reco_tracks=reco_tracks,
96 add_mva_quality_indicator=add_mva_quality_indicator)
97
98 # V0 finding
99 if v0_finding:
100 path.add_module('V0Finder', RecoTracks=reco_tracks, v0FitterMode=1)
101
102 if pruneTracks:
103 add_prune_tracks(path, components=components, reco_tracks=reco_tracks)
104
105
106def add_prefilter_track_fit_and_track_creator(path, components=None, trackFitHypotheses=None,
107 reco_tracks="RecoTracks", add_mva_quality_indicator=False):
108 """
109 Helper function to add only the modules required to calculate HLT filter decision:
110 performing the track fit and the Belle2 track creation to the path.
111
112 :param path: The path to add the tracking reconstruction modules to
113 :param components: the list of geometry components in use or None for all components.
114 :param reco_tracks: Name of the StoreArray where the reco tracks should be stored
115 :param add_mva_quality_indicator: If true, add the MVA track quality estimation
116 to the path that sets the quality indicator property of the found tracks.
117 """
118
119 # Correct time seed
120 path.add_module("IPTrackTimeEstimator",
121 recoTracksStoreArrayName=reco_tracks, useFittedInformation=False)
122 # track fitting
123 path.add_module("DAFRecoFitter", recoTracksStoreArrayName=reco_tracks).set_name(
124 "Combined_DAFRecoFitter")
125 # Add MVA classifier that uses information not included in the calculation of the fit p-value
126 # to add a track quality indicator for classification of fake vs. MC-matched tracks
127
128 if add_mva_quality_indicator:
129 path.add_module("TrackQualityEstimatorMVA", collectEventFeatures=True)
130 # create Belle2 Tracks from the genfit Tracks
131 # The following particle hypothesis will be fitted: Pion, Kaon and Proton
132 # Muon fit is working but gives very similar as the Pion due to the closeness of masses
133 # -> therefore not in the default fit list
134 # Electron fit has as systematic bias and therefore not done here. Therefore, pion fits
135 # will be used for electrons which gives a better result as GenFit's current electron
136 # implementation.
137 path.add_module('TrackCreator', recoTrackColName=reco_tracks,
138 pdgCodes=[211, 321, 2212] if not trackFitHypotheses else trackFitHypotheses)
139
140
141def add_cr_track_fit_and_track_creator(path, components=None,
142 prune_tracks=False, event_timing_extraction=True,
143 reco_tracks="RecoTracks", tracks=""):
144 """
145 Helper function to add the modules performing the cdc cr track fit
146 and track creation to the path.
147
148 :param path: The path to which to add the tracking reconstruction modules
149 :param components: the list of geometry components in use or None for all components.
150 :param reco_tracks: The name of the reco tracks to use
151 :param tracks: the name of the output Belle tracks
152 :param prune_tracks: Delete all hits expect the first and the last from the found tracks.
153 :param event_timing_extraction: extract the event time
154 """
155
156 # Time seed
157 path.add_module("PlaneTriggerTrackTimeEstimator",
158 recoTracksStoreArrayName=reco_tracks,
159 pdgCodeToUseForEstimation=13,
160 triggerPlanePosition=[0., 0., 0.],
161 triggerPlaneDirection=[0., 1., 0.],
162 useFittedInformation=False)
163
164 # Initial track fitting
165 path.add_module("DAFRecoFitter",
166 recoTracksStoreArrayName=reco_tracks,
167 probCut=0.00001,
168 pdgCodesToUseForFitting=13).set_name(f"DAFRecoFitter {reco_tracks}")
169
170 # Correct time seed
171 path.add_module("PlaneTriggerTrackTimeEstimator",
172 recoTracksStoreArrayName=reco_tracks,
173 pdgCodeToUseForEstimation=13,
174 triggerPlanePosition=[0., 0., 0.],
175 triggerPlaneDirection=[0., 1., 0.],
176 useFittedInformation=True)
177
178 # Final Track fitting
179 path.add_module("DAFRecoFitter",
180 recoTracksStoreArrayName=reco_tracks,
181 pdgCodesToUseForFitting=13
182 ).set_name(f"DAFRecoFitter {reco_tracks}")
183
184 if event_timing_extraction:
185 # Extract the time
186 path.add_module("FullGridChi2TrackTimeExtractor",
187 RecoTracksStoreArrayName=reco_tracks,
188 GridMaximalT0Value=40,
189 GridMinimalT0Value=-40,
190 GridGridSteps=6
191 )
192
193 # Track fitting
194 path.add_module("DAFRecoFitter",
195 # probCut=0.00001,
196 recoTracksStoreArrayName=reco_tracks,
197 pdgCodesToUseForFitting=13
198 ).set_name(f"DAFRecoFitter {reco_tracks}")
199
200 # Create Belle2 Tracks from the genfit Tracks
201 path.add_module('TrackCreator',
202 pdgCodes=[13],
203 recoTrackColName=reco_tracks,
204 trackColName=tracks,
205 useClosestHitToIP=True,
206 useBFieldAtHit=True
207 )
208
209 # Prune genfit tracks
210 if prune_tracks:
211 add_prune_tracks(path=path, components=components, reco_tracks=reco_tracks)
212
213
214def add_mc_matcher(path, components=None, mc_reco_tracks="MCRecoTracks",
215 reco_tracks="RecoTracks", use_second_cdc_hits=False,
216 split_after_delta_t=-1.0, matching_method="hit",
217 relate_tracks_to_mcparticles=True,
218 chi2_cutoffs=[128024, 95, 173, 424, 90, 424],
219 chi2_linalg=False):
220 """
221 Match the tracks to the MC truth. The matching works based on
222 the output of the TrackFinderMCTruthRecoTracks.
223 Alternatively one can use the Chi2MCTrackMatcher based on chi2 values
224 calculated from the helixparameters of Tracks and MCParticles.
225
226 :param path: The path to add the tracking reconstruction modules to
227 :param components: the list of geometry components in use or None for all components.
228 :param mc_reco_tracks: Name of the StoreArray where the mc reco tracks will be stored
229 :param reco_tracks: Name of the StoreArray where the reco tracks should be stored
230 :param use_second_cdc_hits: If true, the second hit information will be used in the CDC track finding.
231 :param split_after_delta_t: If positive, split MCRecoTrack into multiple MCRecoTracks if the time
232 distance between two adjacent SimHits is more than the given value
233 :param matching_method: hit: uses the hit-matching
234 chi2: uses the chi2-matching
235 :param relate_tracks_to_mcparticles: If True (default), Tracks are related to MCParticles. Only works
236 if the TrackCreator is in the path before. Needs to be set to False
237 if only track finding is performed, but no Tracks are created.
238 :param chi2_cutoffs: If chi2 matching method is used, this list defines the individual cut-off values
239 for the chi2 values. Thereby each charged stable particle gets its cut-off
240 value. The order of the pdgs is [11,13,211,2212,321,1000010020]. The default
241 values are determined from a small study investigating chi2 value distribution of
242 trivial matching pairs.
243 :param chi2_linalg: If chi2 matching is used, this defines package used to invert the covariance5
244 matrix. ROOT has been shown to be faster than eigen. If False ROOT is used. If True
245 eigen is used.
246 """
247 if (matching_method == "hit"):
248 path.add_module('TrackFinderMCTruthRecoTracks',
249 RecoTracksStoreArrayName=mc_reco_tracks,
250 WhichParticles=[],
251 UseSecondCDCHits=use_second_cdc_hits,
252 UsePXDHits=is_detector_present("PXD", components),
253 UseSVDHits=is_detector_present("SVD", components),
254 UseCDCHits=is_detector_present("CDC", components),
255 SplitAfterDeltaT=split_after_delta_t)
256
257 path.add_module('MCRecoTracksMatcher',
258 mcRecoTracksStoreArrayName=mc_reco_tracks,
259 prRecoTracksStoreArrayName=reco_tracks,
260 UsePXDHits=is_detector_present("PXD", components),
261 UseSVDHits=is_detector_present("SVD", components),
262 UseCDCHits=is_detector_present("CDC", components))
263
264 if relate_tracks_to_mcparticles:
265 path.add_module('TrackToMCParticleRelator')
266
267 elif (matching_method == "chi2"):
268 print("Warning: The Chi2MCTrackMatcherModule is currently not fully developed and tested!")
269 path.add_module('Chi2MCTrackMatcherModule',
270 CutOffs=chi2_cutoffs,
271 linalg=chi2_linalg)
272
273
274def add_prune_tracks(path, components=None, reco_tracks="RecoTracks"):
275 """
276 Adds removal of the intermediate states at each measurement from the fitted tracks.
277
278 :param path: The path to add the tracking reconstruction modules to
279 :param components: the list of geometry components in use or None for all components.
280 :param reco_tracks: Name of the StoreArray where the reco tracks should be stored
281 """
282
283 # do not add any pruning, if no tracking detectors are in the components
284 if components and not is_any_detector_present(["SVD", "CDC"], components):
285 return
286
287 path.add_module('PruneRecoTracks', storeArrayName=reco_tracks).set_name("PruneRecoTracks " + reco_tracks)
288 path.add_module("PruneGenfitTracks")
289
290
291def add_flipping_of_recoTracks(
292 path,
293 fit_tracks=True,
294 reco_tracks="RecoTracks",
295 trackFitHypotheses=None,
296 reco_tracks_flipped="RecoTracks_flipped"):
297 """
298 This function adds the mva based selections and the flipping of the recoTracks
299
300 :param path: The path to add the tracking reconstruction modules to
301 :param fit_tracks: fit the flipped recotracks or not
302 :param reco_tracks: Name of the StoreArray where the reco tracks should be flipped
303 :param trackFitHypotheses: Which pdg hypothesis to fit. Defaults to [211, 321, 2212].
304 :param reco_tracks_flipped: Name of the temporary StoreArray for the flipped RecoTracks
305 """
306
307 path.add_module("FlipQuality", recoTracksStoreArrayName=reco_tracks,
308 identifier='TRKTrackFlipAndRefit_MVA1_weightfile',
309 indexOfFlippingMVA=1).set_name("FlipQuality_1stMVA")
310
311 path.add_module("RecoTracksReverter", inputStoreArrayName=reco_tracks,
312 outputStoreArrayName=reco_tracks_flipped)
313 if fit_tracks:
314 path.add_module("DAFRecoFitter", recoTracksStoreArrayName=reco_tracks_flipped).set_name("Combined_DAFRecoFitter_flipped")
315 path.add_module("IPTrackTimeEstimator",
316 recoTracksStoreArrayName=reco_tracks_flipped, useFittedInformation=False)
317 path.add_module("TrackCreator", trackColName="Tracks_flipped",
318 trackFitResultColName="TrackFitResults_flipped",
319 recoTrackColName=reco_tracks_flipped,
320 pdgCodes=[
321 211,
322 321,
323 2212] if not trackFitHypotheses else trackFitHypotheses).set_name("TrackCreator_flipped")
324 path.add_module("FlipQuality", recoTracksStoreArrayName=reco_tracks,
325 identifier='TRKTrackFlipAndRefit_MVA2_weightfile',
326 indexOfFlippingMVA=2).set_name("FlipQuality_2ndMVA")
327 path.add_module("FlippedRecoTracksMerger",
328 inputStoreArrayName=reco_tracks,
329 inputStoreArrayNameFlipped=reco_tracks_flipped)
330
331
332def add_pxd_track_finding(path, components, input_reco_tracks, output_reco_tracks, use_mc_truth=False,
333 add_both_directions=False, temporary_reco_tracks="PXDRecoTracks", **kwargs):
334 """Add the pxd track finding to the path"""
335 if not is_detector_present("PXD", components):
336 return
337
338 if use_mc_truth:
339 # MC CKF needs MC matching information
340 path.add_module("MCRecoTracksMatcher", UsePXDHits=False,
341 UseSVDHits=is_detector_present("SVD", components), UseCDCHits=is_detector_present("CDC", components),
342 mcRecoTracksStoreArrayName="MCRecoTracks",
343 prRecoTracksStoreArrayName=input_reco_tracks)
344
345 add_pxd_ckf(path, svd_cdc_reco_tracks=input_reco_tracks, pxd_reco_tracks=temporary_reco_tracks,
346 direction="backward", use_mc_truth=use_mc_truth, **kwargs)
347
348 if add_both_directions:
349 add_pxd_ckf(path, svd_cdc_reco_tracks=input_reco_tracks, pxd_reco_tracks=temporary_reco_tracks,
350 direction="forward", use_mc_truth=use_mc_truth, **kwargs)
351
352 path.add_module("RelatedTracksCombiner", CDCRecoTracksStoreArrayName=input_reco_tracks,
353 VXDRecoTracksStoreArrayName=temporary_reco_tracks, recoTracksStoreArrayName=output_reco_tracks)
354
355
356def add_pxd_cr_track_finding(path, components, input_reco_tracks, output_reco_tracks, use_mc_truth=False,
357 add_both_directions=False, temporary_reco_tracks="PXDRecoTracks", **kwargs):
358 """Add the pxd track finding to the path"""
359 if not is_detector_present("PXD", components):
360 return
361
362 if use_mc_truth:
363 # MC CKF needs MC matching information
364 path.add_module("MCRecoTracksMatcher", UsePXDHits=False,
365 UseSVDHits=is_detector_present("SVD", components), UseCDCHits=is_detector_present("CDC", components),
366 mcRecoTracksStoreArrayName="MCRecoTracks",
367 prRecoTracksStoreArrayName=input_reco_tracks)
368
369 add_cosmics_pxd_ckf(path, svd_cdc_reco_tracks=input_reco_tracks, pxd_reco_tracks=temporary_reco_tracks,
370 direction="backward", use_mc_truth=use_mc_truth, **kwargs)
371
372 if add_both_directions:
373 add_cosmics_pxd_ckf(path, svd_cdc_reco_tracks=input_reco_tracks, pxd_reco_tracks=temporary_reco_tracks,
374 direction="forward", use_mc_truth=use_mc_truth, **kwargs)
375
376 path.add_module("RelatedTracksCombiner", CDCRecoTracksStoreArrayName=input_reco_tracks,
377 VXDRecoTracksStoreArrayName=temporary_reco_tracks, recoTracksStoreArrayName=output_reco_tracks)
378
379
380def add_svd_track_finding(
381 path,
382 components,
383 input_reco_tracks,
384 output_reco_tracks,
385 svd_ckf_mode="SVD_after",
386 use_mc_truth=False,
387 add_both_directions=True,
388 temporary_reco_tracks="SVDRecoTracks",
389 temporary_svd_cdc_reco_tracks="SVDPlusCDCStandaloneRecoTracks",
390 use_svd_to_cdc_ckf=True,
391 prune_temporary_tracks=True,
392 add_mva_quality_indicator=False,
393 svd_standalone_mode="VXDTF2",
394 **kwargs,
395):
396 """
397 Add SVD track finding to the path.
398
399 :param path: The path to add the tracking reconstruction modules to
400 :param components: The list of geometry components in use or None for all components.
401 :param input_reco_tracks: Name of the StoreArray with the input reco tracks (usually from CDC) that are used in the
402 CKF track finding and are merged with the newly found SVD tracks into the ``output_reco_tracks``.
403 :param output_reco_tracks: Name of the StoreArray where the reco tracks outputted by the SVD track finding should be
404 stored.
405 :param svd_ckf_mode: String designating the mode of the CDC-to-SVD CKF, that is how it is combined with the SVD
406 standalone track finding. One of "SVD_after", "SVD_before", "SVD_before_with_second_ckf",
407 "only_ckf", "ckf_merger_plus_spacepoint_ckf", "SVD_alone", "cosmics".
408 :param use_mc_truth: Add mc matching and use the MC information in the CKF (but not in the VXDTF2)
409 :param add_both_directions: Whether to add the CKF with both forward and backward extrapolation directions instead
410 of just one.
411 :param temporary_reco_tracks: Intermediate store array where the SVD tracks from the SVD standalone track finding
412 are stored, before they are merged with CDC tracks and extended via the CKF tracking.
413 :param temporary_svd_cdc_reco_tracks: Intermediate store array where the combination of ``temporary_reco_tracks``
414 (from SVD) and ``input_reco_tracks`` (from CDC standalone) is stored, before the CKF is applied.
415 It is only used if ``use_svd_to_cdc_ckf`` is true. Otherwise, the combination is stored directly in
416 ``output_reco_tracks``.
417 :param use_svd_to_cdc_ckf: Whether to enable the CKF extrapolation from the SVD into the CDC.
418 That CKF application is not affected by ``svd_ckf_mode``.
419 :param prune_temporary_tracks: Delete all hits expect the first and last from intermediate track objects.
420 :param add_mva_quality_indicator: Add the VXDQualityEstimatorMVA module to set the quality indicator
421 property for tracks from VXDTF2 standalone tracking
422 (ATTENTION: Standard triplet QI of VXDTF2 is replaced in this case
423 -> setting this option to 'True' will have some influence on the final track collection)
424 :param svd_standalone_mode: Which SVD standalone tracking is used.
425 Options are "VXDTF2", "SVDHough", "VXDTF2_and_SVDHough", and "SVDHough_and_VXDTF2".
426 Defaults to "VXDTF2"
427 """
428
429 if not is_detector_present("SVD", components):
430 return
431
432 if not input_reco_tracks or input_reco_tracks == "":
433 # We do not have an input track store array. So lets just add SVD standalone track finding
434 add_svd_standalone_tracking(path, components=["SVD"],
435 svd_standalone_mode=svd_standalone_mode,
436 reco_tracks=output_reco_tracks,
437 add_mva_quality_indicator=add_mva_quality_indicator)
438 return
439
440 if use_mc_truth:
441 # MC CKF needs MC matching information
442 path.add_module("MCRecoTracksMatcher", UsePXDHits=False, UseSVDHits=False,
443 UseCDCHits=is_detector_present("CDC", components),
444 mcRecoTracksStoreArrayName="MCRecoTracks",
445 prRecoTracksStoreArrayName=input_reco_tracks)
446
447 if svd_ckf_mode == "SVD_before":
448 add_svd_standalone_tracking(path, components=["SVD"],
449 svd_standalone_mode=svd_standalone_mode,
450 reco_tracks=temporary_reco_tracks,
451 add_mva_quality_indicator=add_mva_quality_indicator)
452 add_ckf_based_merger(path, cdc_reco_tracks=input_reco_tracks, svd_reco_tracks=temporary_reco_tracks,
453 use_mc_truth=use_mc_truth, direction="backward", **kwargs)
454 if add_both_directions:
455 add_ckf_based_merger(path, cdc_reco_tracks=input_reco_tracks, svd_reco_tracks=temporary_reco_tracks,
456 use_mc_truth=use_mc_truth, direction="forward", **kwargs)
457
458 elif svd_ckf_mode == "SVD_before_with_second_ckf":
459 add_svd_standalone_tracking(path, components=["SVD"],
460 svd_standalone_mode=svd_standalone_mode,
461 reco_tracks=temporary_reco_tracks,
462 add_mva_quality_indicator=add_mva_quality_indicator)
463 add_ckf_based_merger(path, cdc_reco_tracks=input_reco_tracks, svd_reco_tracks=temporary_reco_tracks,
464 use_mc_truth=use_mc_truth, direction="backward", **kwargs)
465 if add_both_directions:
466 add_ckf_based_merger(path, cdc_reco_tracks=input_reco_tracks, svd_reco_tracks=temporary_reco_tracks,
467 use_mc_truth=use_mc_truth, direction="forward", **kwargs)
468 add_svd_ckf(path, cdc_reco_tracks=input_reco_tracks, svd_reco_tracks=temporary_reco_tracks,
469 use_mc_truth=use_mc_truth, direction="backward", **kwargs)
470 if add_both_directions:
471 add_svd_ckf(path, cdc_reco_tracks=input_reco_tracks, svd_reco_tracks=temporary_reco_tracks,
472 use_mc_truth=use_mc_truth, direction="forward", **kwargs)
473
474 elif svd_ckf_mode == "only_ckf":
475 add_svd_ckf(path, cdc_reco_tracks=input_reco_tracks, svd_reco_tracks=temporary_reco_tracks,
476 use_mc_truth=use_mc_truth, direction="backward", **kwargs)
477 if add_both_directions:
478 add_svd_ckf(path, cdc_reco_tracks=input_reco_tracks, svd_reco_tracks=temporary_reco_tracks,
479 use_mc_truth=use_mc_truth, direction="forward", **kwargs)
480
481 # option for inside-out tracking when we start with SVD tracking
482 elif svd_ckf_mode == "ckf_merger_plus_spacepoint_ckf":
483 add_ckf_based_merger(path, cdc_reco_tracks=input_reco_tracks, svd_reco_tracks=temporary_reco_tracks,
484 use_mc_truth=use_mc_truth, direction="backward", **kwargs)
485 if add_both_directions:
486 add_ckf_based_merger(path, cdc_reco_tracks=input_reco_tracks, svd_reco_tracks=temporary_reco_tracks,
487 use_mc_truth=use_mc_truth, direction="forward", **kwargs)
488 add_svd_ckf(path, cdc_reco_tracks=input_reco_tracks, svd_reco_tracks=temporary_reco_tracks,
489 use_mc_truth=use_mc_truth, direction="backward", **kwargs)
490 if add_both_directions:
491 add_svd_ckf(path, cdc_reco_tracks=input_reco_tracks, svd_reco_tracks=temporary_reco_tracks,
492 use_mc_truth=use_mc_truth, direction="forward", **kwargs)
493
494 elif svd_ckf_mode == "SVD_after":
495 add_svd_ckf(path, cdc_reco_tracks=input_reco_tracks, svd_reco_tracks=temporary_reco_tracks,
496 use_mc_truth=use_mc_truth, direction="backward", **kwargs)
497 if add_both_directions:
498 add_svd_ckf(path, cdc_reco_tracks=input_reco_tracks, svd_reco_tracks=temporary_reco_tracks,
499 use_mc_truth=use_mc_truth, direction="forward", **kwargs)
500
501 add_svd_standalone_tracking(path, components=["SVD"],
502 svd_standalone_mode=svd_standalone_mode,
503 reco_tracks=temporary_reco_tracks,
504 add_mva_quality_indicator=add_mva_quality_indicator)
505 add_ckf_based_merger(path, cdc_reco_tracks=input_reco_tracks, svd_reco_tracks=temporary_reco_tracks,
506 use_mc_truth=use_mc_truth, direction="backward", **kwargs)
507 if add_both_directions:
508 add_ckf_based_merger(path, cdc_reco_tracks=input_reco_tracks, svd_reco_tracks=temporary_reco_tracks,
509 use_mc_truth=use_mc_truth, direction="forward", **kwargs)
510
511 elif svd_ckf_mode == "SVD_alone":
512 add_svd_standalone_tracking(path, components=["SVD"],
513 svd_standalone_mode=svd_standalone_mode,
514 reco_tracks=temporary_reco_tracks,
515 add_mva_quality_indicator=add_mva_quality_indicator)
516 path.add_module('VXDCDCTrackMerger',
517 CDCRecoTrackColName=input_reco_tracks,
518 VXDRecoTrackColName=temporary_reco_tracks)
519
520 elif svd_ckf_mode == "cosmics":
521 add_cosmics_svd_ckf(path, cdc_reco_tracks=input_reco_tracks, svd_reco_tracks=temporary_reco_tracks,
522 use_mc_truth=use_mc_truth, direction="backward", **kwargs)
523 if add_both_directions:
524 add_cosmics_svd_ckf(path, cdc_reco_tracks=input_reco_tracks, svd_reco_tracks=temporary_reco_tracks,
525 use_mc_truth=use_mc_truth, direction="forward", **kwargs)
526
527 else:
528 raise ValueError(f"Do not understand the svd_ckf_mode {svd_ckf_mode}")
529
530 if use_svd_to_cdc_ckf:
531 combined_svd_cdc_standalone_tracks = temporary_svd_cdc_reco_tracks
532 else:
533 combined_svd_cdc_standalone_tracks = output_reco_tracks
534
535 # Write out the combinations of tracks
536 path.add_module("RelatedTracksCombiner", VXDRecoTracksStoreArrayName=temporary_reco_tracks,
537 CDCRecoTracksStoreArrayName=input_reco_tracks,
538 recoTracksStoreArrayName=combined_svd_cdc_standalone_tracks)
539
540 if use_svd_to_cdc_ckf:
541 path.add_module("ToCDCCKF",
542 inputWireHits="CDCWireHitVector",
543 inputRecoTrackStoreArrayName=combined_svd_cdc_standalone_tracks,
544 relatedRecoTrackStoreArrayName="CKFCDCRecoTracks",
545 relationCheckForDirection="backward",
546 ignoreTracksWithCDChits=True,
547 outputRecoTrackStoreArrayName="CKFCDCRecoTracks",
548 outputRelationRecoTrackStoreArrayName=combined_svd_cdc_standalone_tracks,
549 writeOutDirection="backward",
550 stateBasicFilterParameters={"maximalHitDistance": 0.15},
551 pathFilter="arc_length",
552 maximalLayerJump=4)
553
554 path.add_module("CDCCKFTracksCombiner",
555 CDCRecoTracksStoreArrayName="CKFCDCRecoTracks",
556 VXDRecoTracksStoreArrayName=combined_svd_cdc_standalone_tracks,
557 recoTracksStoreArrayName=output_reco_tracks)
558
559 if prune_temporary_tracks:
560 for temp_reco_track in [combined_svd_cdc_standalone_tracks, "CKFCDCRecoTracks"]:
561 path.add_module('PruneRecoTracks', storeArrayName=temp_reco_track).set_name("PruneRecoTracks " + temp_reco_track)
562
563
564def add_svd_standalone_tracking(path,
565 components=["SVD"],
566 svd_clusters="",
567 svd_standalone_mode="VXDTF2",
568 reco_tracks="SVDRecoTracks",
569 add_mva_quality_indicator=False,
570 suffix=""):
571 """
572 Convenience function to add the SVD standalone tracking
573
574 :param path: basf2 path
575 :param components: components to use, defaults to SVD
576 :param svd_clusters: Name of the SVDClusters StoreArray used for tracking
577 :param svd_standalone_mode: Which SVD standalone tracking is used.
578 Options are "VXDTF2", "SVDHough", "VXDTF2_and_SVDHough", and "SVDHough_and_VXDTF2".
579 Defaults to "VXDTF2"
580 :param reco_tracks: In case the only SVD standalone tracking is performed, these are the final RecoTracks,
581 otherwise it's an intermediate StoreaArray where the SVD tracks from the SVD standalone track finding
582 are stored, before they are merged with CDC tracks and extended via the CKF tracking.
583 :param add_mva_quality_indicator: Add the VXDQualityEstimatorMVA module to set the quality indicator
584 property for tracks from VXDTF2 standalone tracking
585 (ATTENTION: Standard triplet QI of VXDTF2 is replaced in this case
586 -> setting this option to 'True' will have some influence on the final track collection)
587 :param suffix: all names of intermediate Storearrays will have the suffix appended. Useful in cases someone needs to
588 put several instances of track finding in one path.
589 """
590 if svd_standalone_mode == "VXDTF2":
591 add_vxd_track_finding_vxdtf2(path, components=components, svd_clusters=svd_clusters, reco_tracks=reco_tracks,
592 add_mva_quality_indicator=add_mva_quality_indicator, suffix=suffix)
593
594 elif svd_standalone_mode == "SVDHough":
595 add_svd_hough_tracking(path, reco_tracks=reco_tracks, suffix=suffix)
596
597 elif svd_standalone_mode == "VXDTF2_and_SVDHough":
598 add_vxd_track_finding_vxdtf2(path,
599 components=components,
600 svd_clusters=svd_clusters,
601 nameSPTCs="SPTrackCands"+"VXDTF2",
602 reco_tracks=reco_tracks+"VXDTF2",
603 add_mva_quality_indicator=add_mva_quality_indicator,
604 suffix=suffix)
605 add_svd_hough_tracking(path,
606 reco_tracks=reco_tracks+"Hough",
607 svd_space_point_track_candidates="SPTrackCands"+"Hough",
608 suffix=suffix)
609
610 path.add_module('RecoTrackStoreArrayCombiner',
611 Temp1RecoTracksStoreArrayName=reco_tracks+"VXDTF2",
612 Temp2RecoTracksStoreArrayName=reco_tracks+"Hough",
613 recoTracksStoreArrayName=reco_tracks)
614 path.add_module('PruneRecoTracks', storeArrayName=reco_tracks+"VXDTF2").set_name("PruneRecoTracks " + reco_tracks+"VXDTF2")
615 path.add_module('PruneRecoTracks', storeArrayName=reco_tracks+"Hough").set_name("PruneRecoTracks " + reco_tracks+"Hough")
616
617 elif svd_standalone_mode == "SVDHough_and_VXDTF2":
618 add_svd_hough_tracking(path,
619 reco_tracks=reco_tracks+"Hough",
620 svd_space_point_track_candidates="SPTrackCands"+"Hough",
621 suffix=suffix)
622 add_vxd_track_finding_vxdtf2(path,
623 components=components,
624 svd_clusters=svd_clusters,
625 nameSPTCs="SPTrackCands"+"VXDTF2",
626 reco_tracks=reco_tracks+"VXDTF2",
627 add_mva_quality_indicator=add_mva_quality_indicator,
628 suffix=suffix)
629
630 path.add_module('RecoTrackStoreArrayCombiner',
631 Temp1RecoTracksStoreArrayName=reco_tracks+"Hough",
632 Temp2RecoTracksStoreArrayName=reco_tracks+"VXDTF2",
633 recoTracksStoreArrayName=reco_tracks)
634 path.add_module('PruneRecoTracks', storeArrayName=reco_tracks+"Hough").set_name("PruneRecoTracks " + reco_tracks+"Hough")
635 path.add_module('PruneRecoTracks', storeArrayName=reco_tracks+"VXDTF2").set_name("PruneRecoTracks " + reco_tracks+"VXDTF2")
636
637 else:
638 raise ValueError(f"Do not understand the svd_standalone_mode {svd_standalone_mode}")
639
640
641def add_cdc_track_finding(path, output_reco_tracks="RecoTracks", with_cdc_cellular_automaton=False,
642 use_second_hits=False, add_mva_quality_indicator=True,
643 reattach_hits=False, skip_WireHitPreparer=False):
644 """
645 Convenience function for adding all cdc track finder modules
646 to the path.
647
648 The result is a StoreArray with name @param reco_tracks full of RecoTracks (not TrackCands any more!).
649 Use the GenfitTrackCandidatesCreator Module to convert back.
650
651 :param path: basf2 path
652 :param output_reco_tracks: Name of the output RecoTracks. Defaults to RecoTracks.
653 :param with_cdc_cellular_automaton: If true, the cellular automaton track finder algorithm will be used too,
654 after the global algorithm (Legendre)
655 :param use_second_hits: If true, the second hit information will be used in the CDC track finding.
656 :param add_mva_quality_indicator: Add the TFCDC_TrackQualityEstimator module to set the CDC quality
657 indicator property of the CDC ``output_reco_tracks``
658 :param cdc_quality_estimator_weightfile: Weightfile identifier for the TFCDC_TrackQualityEstimator
659 :param reattach_hits: if true, use the ReattachCDCWireHitsToRecoTracks module at the end of the CDC track finding
660 to read hits with bad ADC or TOT rejected by the TFCDC_WireHitPreparer module.
661 :param skip_WireHitPreparer: if True, the TFCDC_WireHitPreparer will be skipped. This is necessary if for instance
662 the SVD tracking and the ToCDCCKF are run before the full CDC tracking, as the ToCDCCKF already reqires the WireHits
663 to be present. Defaults to False, as for the default tracking chain it is required.
664 """
665 # add EventLevelTrackinginfo for logging errors
666 if 'RegisterEventLevelTrackingInfo' not in path:
667 path.add_module('RegisterEventLevelTrackingInfo')
668
669 # Init the geometry for cdc tracking and the hits and cut low ADC hits
670 if not skip_WireHitPreparer:
671 path.add_module("TFCDC_WireHitPreparer",
672 wirePosition="aligned",
673 useSecondHits=use_second_hits,
674 flightTimeEstimation="outwards",
675 filter="combined",
676 filterParameters={'DBPayloadName': 'trackfindingcdc_WireHitBackgroundDetectorParameters'})
677
678 # Constructs clusters
679 path.add_module("TFCDC_ClusterPreparer",
680 ClusterFilter="all",
681 ClusterFilterParameters={})
682
683 # Find segments within the clusters
684 path.add_module("TFCDC_SegmentFinderFacetAutomaton",
685 SegmentRelationFilterParameters={'DBPayloadName': 'trackfindingcdc_RealisticSegmentRelationFilterParameters'})
686
687 # Find axial tracks
688 path.add_module("TFCDC_AxialTrackFinderLegendre")
689
690 # Improve the quality of the axial tracks
691 path.add_module("TFCDC_TrackQualityAsserter",
692 corrections=["B2B"])
693
694 # Find the stereo hits to those axial tracks
695 path.add_module('TFCDC_StereoHitFinder')
696
697 # Combine segments with axial tracks
698 path.add_module('TFCDC_SegmentTrackCombiner',
699 segmentTrackFilter="mva",
700 segmentTrackFilterParameters={'DBPayloadName': 'trackfindingcdc_SegmentTrackFilterParameters'},
701 trackFilter="mva",
702 trackFilterParameters={'DBPayloadName': 'trackfindingcdc_TrackFilterParameters'})
703
704 output_tracks = "CDCTrackVector"
705
706 if with_cdc_cellular_automaton:
707 output_tracks = "CombinedCDCTrackVector"
708 path.add_module("TFCDC_TrackFinderSegmentPairAutomaton",
709 tracks="CDCTrackVector2")
710
711 # Overwrites the origin CDCTrackVector
712 path.add_module("TFCDC_TrackCombiner",
713 inputTracks="CDCTrackVector",
714 secondaryInputTracks="CDCTrackVector2",
715 tracks=output_tracks)
716
717 # Improve the quality of all tracks and output
718 path.add_module("TFCDC_TrackQualityAsserter",
719 inputTracks=output_tracks,
720 corrections=[
721 "LayerBreak",
722 "OneSuperlayer",
723 "Small",
724 ])
725
726 if with_cdc_cellular_automaton:
727 # Add curlers in the axial inner most superlayer
728 path.add_module("TFCDC_TrackCreatorSingleSegments",
729 inputTracks=output_tracks,
730 MinimalHitsBySuperLayerId={0: 15})
731
732 if add_mva_quality_indicator:
733 # Add CDC-specific mva method to set the quality indicator for the CDC tracks
734 path.add_module(
735 "TFCDC_TrackQualityEstimator",
736 inputTracks=output_tracks,
737 filter='mva',
738 filterParameters={'DBPayloadName': 'trackfindingcdc_TrackQualityEstimatorParameters'},
739 deleteTracks=True,
740 resetTakenFlag=True
741 )
742
743 # Export CDCTracks to RecoTracks representation
744 path.add_module("TFCDC_TrackExporter",
745 inputTracks=output_tracks,
746 RecoTracksStoreArrayName="CDCRecoTracksBeforeReattaching" if reattach_hits else output_reco_tracks)
747
748 if reattach_hits:
749 # The ReattachCDCWireHitsToRecoTracks module (below) requires the SetupGenfitExtrapolation module
750 if 'SetupGenfitExtrapolation' not in path:
751 # Prepare Genfit extrapolation
752 path.add_module('SetupGenfitExtrapolation')
753
754 # Loop over low-ADC/TOT CDCWireHits and RecoTracks and reattach the hits to the tracks if they are close enough
755 path.add_module("ReattachCDCWireHitsToRecoTracks",
756 inputRecoTracksStoreArrayName="CDCRecoTracksBeforeReattaching",
757 outputRecoTracksStoreArrayName=output_reco_tracks)
758
759 # Correct time seed (only necessary for the CDC tracks)
760 path.add_module("IPTrackTimeEstimator",
761 useFittedInformation=False,
762 recoTracksStoreArrayName=output_reco_tracks)
763
764 # run fast t0 estimation from CDC hits only
765 path.add_module("CDCHitBasedT0Extraction")
766
767 # prepare mdst event level info
768 path.add_module("CDCTrackingEventLevelMdstInfoFillerFromHits")
769 path.add_module("CDCTrackingEventLevelMdstInfoFillerFromSegments")
770
771
772def add_eclcdc_track_finding(path, components, output_reco_tracks="RecoTracks", prune_temporary_tracks=True):
773 """
774 Convenience function for adding all track finder modules to the path that are based on ecl seeds.
775
776 The result is a StoreArray with name @param reco_tracks full of RecoTracks.
777 Use the GenfitTrackCandidatesCreator Module to convert back.
778
779 :param path: basf2 path
780 :param components: the list of geometry components in use or None for all components.
781 :param output_reco_tracks: Name of the output RecoTracks. Defaults to RecoTracks.
782 :param pruneTracks: Delete all hits expect the first and the last from the found tracks.
783 """
784 if not are_detectors_present(["CDC", "ECL"], components):
785 return
786
787 ecl_cdc_reco_tracks = "ECLCDCRecoTracks"
788
789 if not is_detector_present("SVD", components):
790 ecl_cdc_reco_tracks = output_reco_tracks
791
792 # collections that will be pruned
793 temporary_reco_track_list = []
794
795 path.add_module("ToCDCFromEclCKF",
796 inputWireHits="CDCWireHitVector",
797 minimalEnRequirementCluster=0.3,
798 eclSeedRecoTrackStoreArrayName='EclSeedRecoTracks',
799 hitFindingDirection="backward",
800 outputRecoTrackStoreArrayName="CDCRecoTracksFromEcl",
801 outputRelationRecoTrackStoreArrayName="EclSeedRecoTracks",
802 writeOutDirection="forward",
803 stateBasicFilterParameters={"maximalHitDistance": 7.5, "maximalHitDistanceEclSeed": 75.0},
804 stateExtrapolationFilterParameters={"direction": "backward"},
805 pathFilter="arc_length_fromEcl",
806 inputECLshowersStoreArrayName="ECLShowers",
807 trackFindingDirection="backward",
808 setTakenFlag=False,
809 seedComponent="ECL"
810 )
811
812 path.add_module("ToCDCCKF",
813 inputWireHits="CDCWireHitVector",
814 inputRecoTrackStoreArrayName="CDCRecoTracksFromEcl",
815 relatedRecoTrackStoreArrayName=ecl_cdc_reco_tracks,
816 relationCheckForDirection="backward",
817 outputRecoTrackStoreArrayName=ecl_cdc_reco_tracks,
818 outputRelationRecoTrackStoreArrayName="CDCRecoTracksFromEcl",
819 writeOutDirection="backward",
820 stateBasicFilterParameters={"maximalHitDistance": 0.75},
821 stateExtrapolationFilterParameters={"direction": "forward"},
822 pathFilter="arc_length",
823 seedComponent="ECL"
824 )
825 # "EclSeedRecoTracks" don't have to be added to the list as these do not contain any hits
826 temporary_reco_track_list.append('CDCRecoTracksFromEcl')
827
828 # Do the following modules have to be added as these are executed already after
829 # the CDC standalone?
830 # If so: they also have to be included in the new SVD->CDC CKF (see add_svd_track_finding(..) above)
831
832 # Correct time seed (only necessary for the CDC tracks)
833 # path.add_module("IPTrackTimeEstimator",
834 # useFittedInformation=False,
835 # recoTracksStoreArrayName=ecl_cdc_reco_tracks)
836
837 # run fast t0 estimation from CDC hits only
838 # path.add_module("CDCHitBasedT0Extraction")
839
840 # prepare mdst event level info
841 # path.add_module("CDCTrackingEventLevelMdstInfoFiller")
842
843 if is_detector_present("SVD", components):
844 add_svd_track_finding(path, components=components, input_reco_tracks=ecl_cdc_reco_tracks,
845 output_reco_tracks=output_reco_tracks, use_mc_truth=False,
846 svd_ckf_mode="only_ckf", add_both_directions=False,
847 temporary_reco_tracks="ECLSVDRecoTracks", use_svd_to_cdc_ckf=False,
848 prune_temporary_tracks=prune_temporary_tracks)
849 temporary_reco_track_list.append(ecl_cdc_reco_tracks)
850 temporary_reco_track_list.append('ECLSVDRecoTracks')
851
852 if prune_temporary_tracks:
853 for temporary_reco_track_name in temporary_reco_track_list:
854 if temporary_reco_track_name != output_reco_tracks:
855 path.add_module(
856 'PruneRecoTracks',
857 storeArrayName=temporary_reco_track_name).set_name(
858 "PruneRecoTracks " +
859 temporary_reco_track_name)
860
861
862def add_cdc_cr_track_finding(path, output_reco_tracks="RecoTracks", trigger_point=(0, 0, 0), merge_tracks=True,
863 use_second_cdc_hits=False):
864 """
865 Convenience function for adding all cdc track finder modules currently dedicated for the CDC-TOP testbeam
866 to the path.
867
868 The result is a StoreArray with name @param reco_tracks full of RecoTracks (not TrackCands any more!).
869
870 Arguments
871 ---------
872 path: basf2.Path
873 The path to be filled
874 output_reco_tracks: str
875 Name of the output RecoTracks. Defaults to RecoTracks.
876 merge_tracks: bool
877 The upper and lower half of the tracks should be merged together in one track
878 use_second_hits: bool
879 If true, the second hit information will be used in the CDC track finding.
880 """
881
882 # Init the geometry for cdc tracking and the hits
883 path.add_module("TFCDC_WireHitPreparer",
884 useSecondHits=use_second_cdc_hits,
885 flightTimeEstimation="downwards",
886 filter="cuts_from_DB",
887 triggerPoint=trigger_point)
888
889 # Constructs clusters and reduce background hits
890 path.add_module("TFCDC_ClusterPreparer",
891 ClusterFilter="mva_bkg",
892 ClusterFilterParameters={'DBPayloadName': 'trackfindingcdc_ClusterFilterParameters'})
893
894 # Find segments within the clusters
895 path.add_module("TFCDC_SegmentFinderFacetAutomaton",
896 SegmentOrientation="downwards")
897
898 # Find axial tracks
899 path.add_module("TFCDC_AxialTrackFinderLegendre")
900
901 # Improve the quality of the axial tracks
902 path.add_module("TFCDC_TrackQualityAsserter",
903 corrections=["B2B"])
904
905 # Find the stereo hits to those axial tracks
906 path.add_module('TFCDC_StereoHitFinder')
907
908 # Combine segments with axial tracks
909 path.add_module('TFCDC_SegmentTrackCombiner',
910 segmentTrackFilter="mva",
911 segmentTrackFilterParameters={'DBPayloadName': 'trackfindingcdc_SegmentTrackFilterParameters'},
912 trackFilter="mva",
913 trackFilterParameters={'DBPayloadName': 'trackfindingcdc_TrackFilterParameters'})
914
915 # Improve the quality of all tracks and output
916 path.add_module("TFCDC_TrackQualityAsserter",
917 corrections=["LayerBreak", "OneSuperlayer", "Small"],
918 )
919
920 # Flip track orientation to always point downwards
921 path.add_module("TFCDC_TrackOrienter",
922 inputTracks="CDCTrackVector",
923 tracks="OrientedCDCTrackVector",
924 TrackOrientation="downwards",
925 )
926
927 output_tracks = "OrientedCDCTrackVector"
928
929 if merge_tracks:
930 # Merge tracks together if needed
931 path.add_module("TFCDC_TrackLinker",
932 inputTracks="OrientedCDCTrackVector",
933 tracks="MergedCDCTrackVector",
934 filter="phi",
935 )
936 output_tracks = "MergedCDCTrackVector"
937
938 # However, we also want to export the non merged tracks
939 # Correct time seed - assumes velocity near light speed
940 path.add_module("TFCDC_TrackFlightTimeAdjuster",
941 inputTracks="OrientedCDCTrackVector",
942 )
943
944 # Export CDCTracks to RecoTracks representation
945 path.add_module("TFCDC_TrackExporter",
946 inputTracks="OrientedCDCTrackVector",
947 RecoTracksStoreArrayName="NonMergedRecoTracks")
948
949 # Correct time seed - assumes velocity near light speed
950 path.add_module("TFCDC_TrackFlightTimeAdjuster",
951 inputTracks=output_tracks,
952 )
953
954 # Export CDCTracks to RecoTracks representation
955 path.add_module("TFCDC_TrackExporter",
956 inputTracks=output_tracks,
957 RecoTracksStoreArrayName=output_reco_tracks)
958
959 # run fast t0 estimation from CDC hits only
960 path.add_module("CDCHitBasedT0Extraction")
961
962
963def add_vxd_track_finding_vxdtf2(
964 path,
965 svd_clusters="",
966 reco_tracks="RecoTracks",
967 nameSPTCs='SPTrackCands',
968 components=None,
969 suffix="",
970 useTwoStepSelection=True,
971 PXDminSVDSPs=3,
972 sectormap_file=None,
973 custom_setup_name=None,
974 min_SPTC_quality=0.,
975 filter_overlapping=True,
976 add_mva_quality_indicator=False,
977):
978 """
979 Convenience function for adding all vxd track finder Version 2 modules
980 to the path.
981
982 The result is a StoreArray with name @param reco_tracks full of RecoTracks (not TrackCands any more!).
983 Use the GenfitTrackCandidatesCreator Module to convert back.
984
985 :param path: basf2 path
986 :param svd_clusters: SVDCluster collection name
987 :param reco_tracks: Name of the output RecoTracks, Defaults to RecoTracks.
988 :param nameSPTCs: Name of the SpacePointTrackCands StoreArray
989 :param components: List of the detector components to be used in the reconstruction. Defaults to None which means
990 all components.
991 :param suffix: all names of intermediate Storearrays will have the suffix appended. Useful in cases someone needs to
992 put several instances of track finding in one path.
993 :param useTwoStepSelection: if True Families will be defined during path creation and will be used to create only
994 the best candidate per family.
995 :param PXDminSVDSPs: When using PXD require at least this number of SVD SPs for the SPTCs
996 :param sectormap_file: if set to a finite value, a file will be used instead of the sectormap in the database.
997 :param custom_setup_name: Set a custom setup name for the tree in the sector map.
998 :param min_SPTC_quality: minimal qualityIndicator value to keeps SPTCs after the QualityEstimation.
999 0 means no cut. Default: 0
1000 :param filter_overlapping: Whether to use SVDOverlapResolver, Default: True
1001 :param add_mva_quality_indicator: Whether to use the MVA Quality Estimator module for VXDTF2 tracks to set the
1002 quality_indicator property of the found ``reco_tracks``. Default: False.
1003 """
1004
1007
1008 # setting different for pxd and svd:
1009 if is_detector_present("PXD", components):
1010 setup_name = "SVDPXDDefault"
1011 db_sec_map_file = "VXDSectorMap_v000.root"
1012 use_pxd = True
1013 else:
1014 setup_name = "SVDOnlyDefault"
1015 db_sec_map_file = "SVDSectorMap_v000.root"
1016 use_pxd = False
1017
1018
1022
1023 # setup the event level tracking info to log errors and stuff
1024 nameTrackingInfoModule = "RegisterEventLevelTrackingInfo" + suffix
1025 nameEventTrackingInfo = "EventLevelTrackingInfo" + suffix
1026 if nameTrackingInfoModule not in path:
1027 # Use modified name of module and created StoreObj as module might be added twice (PXDDataReduction)
1028 registerEventlevelTrackingInfo = register_module('RegisterEventLevelTrackingInfo')
1029 registerEventlevelTrackingInfo.set_name(nameTrackingInfoModule)
1030 registerEventlevelTrackingInfo.param('EventLevelTrackingInfoName', nameEventTrackingInfo)
1031 path.add_module(registerEventlevelTrackingInfo)
1032
1033 nameSPs = 'SpacePoints' + suffix
1034
1035 pxdSPCreatorName = 'PXDSpacePointCreator' + suffix
1036 if pxdSPCreatorName not in [e.name() for e in path.modules()]:
1037 if use_pxd:
1038 spCreatorPXD = register_module('PXDSpacePointCreator')
1039 spCreatorPXD.set_name(pxdSPCreatorName)
1040 spCreatorPXD.param('NameOfInstance', 'PXDSpacePoints')
1041 spCreatorPXD.param('SpacePoints', "PXD" + nameSPs)
1042 path.add_module(spCreatorPXD)
1043
1044 # SecMap Bootstrap
1045 secMapBootStrap = register_module('SectorMapBootstrap')
1046 secMapBootStrap.param('ReadSectorMap', sectormap_file is not None) # read from file
1047 secMapBootStrap.param('ReadSecMapFromDB', sectormap_file is None) # this will override ReadSectorMap
1048 secMapBootStrap.param('SectorMapsInputFile', sectormap_file or db_sec_map_file)
1049 secMapBootStrap.param('SetupToRead', custom_setup_name or setup_name)
1050 secMapBootStrap.param('WriteSectorMap', False)
1051 path.add_module(secMapBootStrap)
1052
1053
1057
1058 spacePointArrayNames = ["SVD" + nameSPs]
1059 if use_pxd:
1060 spacePointArrayNames += ["PXD" + nameSPs]
1061
1062 nameSegNet = 'SegmentNetwork' + suffix
1063
1064 segNetProducer = register_module('SegmentNetworkProducer')
1065 segNetProducer.param('NetworkOutputName', nameSegNet)
1066 segNetProducer.param('SpacePointsArrayNames', spacePointArrayNames)
1067 segNetProducer.param('sectorMapName', custom_setup_name or setup_name)
1068 segNetProducer.param('EventLevelTrackingInfoName', nameEventTrackingInfo)
1069 path.add_module(segNetProducer)
1070
1071
1075
1076 # append a suffix to the storearray name
1077 nameSPTCs += suffix
1078
1079 trackFinder = register_module('TrackFinderVXDCellOMat')
1080 trackFinder.param('NetworkName', nameSegNet)
1081 trackFinder.param('SpacePointTrackCandArrayName', nameSPTCs)
1082 trackFinder.param('printNetworks', False)
1083 trackFinder.param('setFamilies', useTwoStepSelection)
1084 trackFinder.param('selectBestPerFamily', useTwoStepSelection)
1085 trackFinder.param('xBestPerFamily', 30)
1086 trackFinder.param('EventLevelTrackingInfoName', nameEventTrackingInfo)
1087 path.add_module(trackFinder)
1088
1089 if useTwoStepSelection:
1090 subSetModule = register_module('AddVXDTrackCandidateSubSets')
1091 subSetModule.param('NameSpacePointTrackCands', nameSPTCs)
1092 path.add_module(subSetModule)
1093
1094
1098
1099 # When using PXD require at least PXDminSVDSPs SVD SPs for the SPTCs
1100 if use_pxd:
1101 pxdSVDCut = register_module('PXDSVDCut')
1102 pxdSVDCut.param('minSVDSPs', PXDminSVDSPs)
1103 pxdSVDCut.param('SpacePointTrackCandsStoreArrayName', nameSPTCs)
1104 path.add_module(pxdSVDCut)
1105
1106 if add_mva_quality_indicator:
1107 path.add_module(
1108 "VXDQualityEstimatorMVA",
1109 SpacePointTrackCandsStoreArrayName=nameSPTCs,
1110 )
1111 else:
1112 path.add_module(
1113 'QualityEstimatorVXD',
1114 EstimationMethod='tripletFit',
1115 SpacePointTrackCandsStoreArrayName=nameSPTCs,
1116 )
1117
1118 if min_SPTC_quality > 0.:
1119 qualityIndicatorCutter = register_module('VXDTrackCandidatesQualityIndicatorCutter')
1120 qualityIndicatorCutter.param('minRequiredQuality', min_SPTC_quality)
1121 qualityIndicatorCutter.param('NameSpacePointTrackCands', nameSPTCs)
1122 path.add_module(qualityIndicatorCutter)
1123
1124 # will discard track candidates (with low quality estimators) if the number of TC is above threshold
1125 maxCandidateSelection = register_module('BestVXDTrackCandidatesSelector')
1126 maxCandidateSelection.param('NameSpacePointTrackCands', nameSPTCs)
1127 maxCandidateSelection.param('NewNameSpacePointTrackCands', nameSPTCs)
1128 maxCandidateSelection.param('SubsetCreation', False)
1129 path.add_module(maxCandidateSelection)
1130
1131 # Properties
1132 vIPRemover = register_module('SPTCvirtualIPRemover')
1133 vIPRemover.param('tcArrayName', nameSPTCs)
1134 # want to remove virtualIP for any track length
1135 vIPRemover.param('maxTCLengthForVIPKeeping', 0)
1136 path.add_module(vIPRemover)
1137
1138
1142
1143 if filter_overlapping:
1144 overlapResolver = register_module('SVDOverlapResolver')
1145 overlapResolver.param('NameSpacePointTrackCands', nameSPTCs)
1146 overlapResolver.param('ResolveMethod', 'greedy') # other option is 'hopfield'
1147 overlapResolver.param('NameSVDClusters', svd_clusters)
1148 path.add_module(overlapResolver)
1149
1150
1154
1155 momSeedRetriever = register_module('SPTCmomentumSeedRetriever')
1156 momSeedRetriever.param('tcArrayName', nameSPTCs)
1157 path.add_module(momSeedRetriever)
1158
1159 converter = register_module('SPTC2RTConverter')
1160 converter.param('recoTracksStoreArrayName', reco_tracks)
1161 converter.param('spacePointsTCsStoreArrayName', nameSPTCs)
1162 converter.param('svdClustersName', svd_clusters)
1163 converter.param('svdHitsStoreArrayName', svd_clusters)
1164 path.add_module(converter)
1165
1166
1167def add_svd_hough_tracking(path,
1168 svd_space_points='SVDSpacePoints',
1169 svd_clusters='SVDClusters',
1170 reco_tracks='RecoTracks',
1171 svd_space_point_track_candidates='SPTrackCands',
1172 suffix=''):
1173 """
1174 Convenience function to add the SVDHoughTracking to the path.
1175 :param path: The path to add the SVDHoughTracking module to.
1176 :param svd_space_points: Name of the StoreArray containing the SVDSpacePoints
1177 :param svd_clusters: Name of the StoreArray containing the SVDClusters
1178 :param reco_tracks: Name of the StoreArray containing the RecoTracks
1179 :param svd_space_point_track_candidates: Name of the StoreArray containing the SpacePointTrackCandidates
1180 :param suffix: all names of intermediate StoreArrays will have the suffix appended. Useful in cases someone needs to
1181 put several instances of track finding in one path.
1182 """
1183
1184 path.add_module('SVDHoughTracking',
1185 SVDSpacePointStoreArrayName=svd_space_points + suffix,
1186 SVDClustersStoreArrayName=svd_clusters + suffix,
1187 finalOverlapResolverNameSVDClusters=svd_clusters + suffix,
1188 refinerOverlapResolverNameSVDClusters=svd_clusters + suffix,
1189 RecoTracksStoreArrayName=reco_tracks + suffix,
1190 SVDSpacePointTrackCandsStoreArrayName=svd_space_point_track_candidates + suffix,
1191 relationFilter='angleAndTime',
1192 twoHitUseNBestHits=2,
1193 threeHitUseNBestHits=3,
1194 fourHitUseNBestHits=3,
1195 fiveHitUseNBestHits=2,
1196 )
1197
1198
1199def add_default_cdc_svd_tracking_chain(path,
1200 components,
1201 svd_reco_tracks,
1202 cdc_reco_tracks,
1203 output_reco_tracks,
1204 with_cdc_cellular_automaton=False,
1205 use_second_cdc_hits=False,
1206 add_cdcTrack_QI=True,
1207 use_mc_truth=False,
1208 svd_ckf_mode="SVD_after",
1209 add_both_directions=True,
1210 use_svd_to_cdc_ckf=True,
1211 svd_standalone_mode="VXDTF2",
1212 add_vxdTrack_QI=False,
1213 prune_temporary_tracks=True,
1214 ):
1215 """
1216 Add the default CDC based tracking chain to the path, i.e. CDC standalone followed by the ToSVDSpacePointCKF, the SVD standalone
1217 track finding, a CKF based merger for standalone tracks, and finally the SVDToCDCCKF (if setup as such).
1218
1219 :param path: The path to add the tracking reconstruction modules to
1220 :param components: the list of geometry components in use or None for all components.
1221 :param svd_reco_tracks: name of the SVD standalone RecoTracks StoreArray
1222 :param cdc_reco_tracks: name of the CDC standalone RecoTracks StoreArray
1223 :param output_reco_tracks: name of the combined CDC+SVD RecoTracks StoreArray that is the final result of this tracking path
1224 :param with_cdc_cellular_automaton: If true, in the CDC track finding the cellular automaton algorithm will be used too,
1225 after the global algorithm (Legendre)
1226 :param use_second_cdc_hits: whether to use the secondary CDC hit during CDC track finding or not
1227 :param add_cdcTrack_QI: If true, add the MVA track quality estimation
1228 to the path that sets the quality indicator property of the found CDC standalone tracks
1229 :param use_mc_truth: Use the truth information in the CKF modules
1230 :param svd_ckf_mode: how to apply the CKF (with or without SVD standalone tracking). Defaults to "SVD_after".
1231 :param add_both_directions: Curlers may be found in the wrong orientation by the CDC track finder, so try to
1232 extrapolate also in the other direction.
1233 :param use_svd_to_cdc_ckf: if true, add SVD to CDC CKF module.
1234 :param svd_standalone_mode: Which SVD standalone tracking is used.
1235 Options are "VXDTF2", "SVDHough", "VXDTF2_and_SVDHough", and "SVDHough_and_VXDTF2".
1236 Defaults to "VXDTF2"
1237 :param add_vxdTrack_QI: If true, add the MVA track quality estimation
1238 to the path that sets the quality indicator property of the found VXDTF2 tracks
1239 (ATTENTION: Standard triplet QI of VXDTF2 is replaced in this case
1240 -> setting this option to 'True' will have some influence on the final track collection)
1241 :param prune_temporary_tracks: If false, store all information of the single CDC and VXD tracks before merging.
1242 If true, prune them.
1243 """
1244
1245 # collections that will be pruned
1246 temporary_reco_track_list = []
1247
1248 # the name of the most recent track collection
1249 latest_reco_tracks = None
1250
1251 if is_detector_present("CDC", components):
1252 add_cdc_track_finding(
1253 path,
1254 with_cdc_cellular_automaton=with_cdc_cellular_automaton,
1255 use_second_hits=use_second_cdc_hits,
1256 output_reco_tracks=cdc_reco_tracks,
1257 add_mva_quality_indicator=add_cdcTrack_QI)
1258 temporary_reco_track_list.append(cdc_reco_tracks)
1259 latest_reco_tracks = cdc_reco_tracks
1260
1261 if is_detector_present("SVD", components):
1262 add_svd_track_finding(path,
1263 components=components,
1264 input_reco_tracks=latest_reco_tracks,
1265 output_reco_tracks=output_reco_tracks,
1266 use_mc_truth=use_mc_truth,
1267 temporary_reco_tracks=svd_reco_tracks,
1268 svd_ckf_mode=svd_ckf_mode,
1269 add_both_directions=add_both_directions,
1270 use_svd_to_cdc_ckf=use_svd_to_cdc_ckf,
1271 prune_temporary_tracks=prune_temporary_tracks,
1272 add_mva_quality_indicator=add_vxdTrack_QI,
1273 svd_standalone_mode=svd_standalone_mode)
1274 temporary_reco_track_list.append(svd_reco_tracks)
1275 temporary_reco_track_list.append(output_reco_tracks)
1276 latest_reco_tracks = output_reco_tracks
1277
1278 return (latest_reco_tracks, temporary_reco_track_list)
1279
1280
1281def add_inverted_svd_cdc_tracking_chain(path,
1282 components,
1283 svd_reco_tracks,
1284 cdc_reco_tracks,
1285 svd_cdc_reco_tracks,
1286 cdcckf_reco_tracks="CKFCDCRecoTracks",
1287 output_reco_tracks="CombinedSVDCDCRecoTracks",
1288 add_vxdTrack_QI=True,
1289 svd_standalone_mode="VXDTF2",
1290 with_cdc_cellular_automaton=False,
1291 use_second_cdc_hits=False,
1292 add_cdcTrack_QI=True,
1293 use_mc_truth=False,
1294 add_both_directions=True,
1295 prune_temporary_tracks=True,
1296 temporary_reco_tracks_merging_strategy='before_ToSVDCKF',
1297 **kwargs,):
1298 """
1299 Add an inverted SVD based tracking chain to the path, i.e. SVD standalone followed by the ToCDCCKF, the CDC standalone
1300 track finding, a CKF based merger for standalone tracks, and finally the CDCToSVDSpacePointCKF.
1301
1302 ATTENTION: The inverted tracking chain is neither optimised nor guaranteed to be bug free.
1303 ATTENTION: Please remove this comment once the inverted tracking has been optimised and is assumed to be bug-free.
1304
1305 :param path: The path to add the tracking reconstruction modules to
1306 :param components: the list of geometry components in use or None for all components.
1307 :param svd_reco_tracks: name of the SVD standalone RecoTracks StoreArray
1308 :param cdc_reco_tracks: name of the CDC standalone RecoTracks StoreArray
1309 :param svd_cdc_reco_tracks: name of the intermediate combined CDC+SVD RecoTracks StoreArray
1310 :param cdcckf_reco_tracks: name of the intermediate RecoTracks StoreArray from the SVDToCDCCKF
1311 :param output_reco_tracks: name of the combined CDC+SVD RecoTracks StoreArray that is the final result of this tracking path
1312 :param add_vxdTrack_QI: If true, add the MVA track quality estimation
1313 to the path that sets the quality indicator property of the found VXDTF2 tracks
1314 (ATTENTION: Standard triplet QI of VXDTF2 is replaced in this case
1315 -> setting this option to 'True' will have some influence on the final track collection)
1316 :param svd_standalone_mode: Which SVD standalone tracking is used.
1317 Options are "VXDTF2", "SVDHough", "VXDTF2_and_SVDHough", and "SVDHough_and_VXDTF2".
1318 Defaults to "VXDTF2"
1319 :param with_cdc_cellular_automaton: If true, in the CDC track finding the cellular automaton algorithm will be used too,
1320 after the global algorithm (Legendre)
1321 :param use_second_cdc_hits: whether to use the secondary CDC hit during CDC track finding or not
1322 :param add_cdcTrack_QI: If true, add the MVA track quality estimation
1323 to the path that sets the quality indicator property of the found CDC standalone tracks
1324 :param use_mc_truth: Use the truth information in the CKF modules
1325 :param add_both_directions: Curlers may be found in the wrong orientation by the CDC track finder, so try to
1326 extrapolate also in the other direction.
1327 :param prune_temporary_tracks: If false, store all information of the single CDC and VXD tracks before merging.
1328 If true, prune them.
1329 :param temporary_reco_tracks_merging_strategy: When are the temporary CDC RecoTracks merged? Before or after the ToSVDCKF?
1330 Allowed options: \"before_ToSVDCKF\" (default) and \"after_ToCDCCKF\".
1331 """
1332
1333 B2WARNING("ATTENTION: The inverted tracking chain starting from SVD is an experimental feature. "
1334 "It is neither well optimised nor tested for the time being. "
1335 "Please be careful when interpreting the results!")
1336
1337 if temporary_reco_tracks_merging_strategy not in ["before_ToSVDCKF", "after_ToCDCCKF"]:
1338 B2FATAL("Invalid option for 'temporary_reco_tracks_merging_strategy'. "
1339 "Allowed options are 'before_ToSVDCKF' and 'after_ToCDCCKF'.")
1340
1341 # collections that will be pruned
1342 temporary_reco_track_list = []
1343
1344 # the name of the most recent track collection
1345 latest_reco_tracks = None
1346
1347 if is_detector_present("SVD", components):
1348 add_svd_track_finding(path,
1349 components=components,
1350 input_reco_tracks="",
1351 output_reco_tracks=svd_reco_tracks,
1352 add_mva_quality_indicator=add_vxdTrack_QI,
1353 svd_standalone_mode=svd_standalone_mode)
1354 temporary_reco_track_list.append(svd_reco_tracks)
1355 latest_reco_tracks = svd_reco_tracks
1356
1357 path.add_module("DAFRecoFitter", recoTracksStoreArrayName=svd_reco_tracks).set_name(f"DAFRecoFitter {svd_reco_tracks}")
1358
1359 if is_detector_present("CDC", components):
1360 path.add_module("TFCDC_WireHitPreparer",
1361 wirePosition="aligned",
1362 useSecondHits=use_second_cdc_hits,
1363 flightTimeEstimation="outwards",
1364 filter="combined",
1365 filterParameters={'DBPayloadName': 'trackfindingcdc_WireHitBackgroundDetectorParameters'})
1366
1367 path.add_module("ToCDCCKF",
1368 inputWireHits="CDCWireHitVector",
1369 inputRecoTrackStoreArrayName=svd_reco_tracks,
1370 relatedRecoTrackStoreArrayName=cdcckf_reco_tracks,
1371 relationCheckForDirection="backward",
1372 ignoreTracksWithCDChits=True,
1373 outputRecoTrackStoreArrayName=cdcckf_reco_tracks,
1374 outputRelationRecoTrackStoreArrayName=svd_reco_tracks,
1375 writeOutDirection="backward",
1376 stateBasicFilterParameters={"maximalHitDistance": 0.15},
1377 pathFilter="arc_length",
1378 maximalLayerJump=4)
1379
1380 path.add_module("CDCCKFTracksCombiner",
1381 CDCRecoTracksStoreArrayName=cdcckf_reco_tracks,
1382 VXDRecoTracksStoreArrayName=svd_reco_tracks,
1383 recoTracksStoreArrayName=svd_cdc_reco_tracks)
1384
1385 temporary_reco_track_list.append(cdcckf_reco_tracks)
1386 temporary_reco_track_list.append(svd_cdc_reco_tracks)
1387 latest_reco_tracks = svd_cdc_reco_tracks
1388
1389 add_cdc_track_finding(path,
1390 with_cdc_cellular_automaton=with_cdc_cellular_automaton,
1391 use_second_hits=use_second_cdc_hits,
1392 output_reco_tracks=cdc_reco_tracks,
1393 add_mva_quality_indicator=add_cdcTrack_QI,
1394 skip_WireHitPreparer=True)
1395 temporary_reco_track_list.append(cdc_reco_tracks)
1396 latest_reco_tracks = cdc_reco_tracks
1397
1398 if temporary_reco_tracks_merging_strategy == "before_ToSVDCKF":
1399 path.add_module("RecoTrackStoreArrayCombiner",
1400 Temp1RecoTracksStoreArrayName=latest_reco_tracks,
1401 Temp2RecoTracksStoreArrayName=svd_cdc_reco_tracks,
1402 recoTracksStoreArrayName="CombinedCDCSVDRecoTracks")
1403 temporary_reco_track_list.append("CombinedCDCSVDRecoTracks")
1404 latest_reco_tracks = "CombinedCDCSVDRecoTracks"
1405
1406 if is_detector_present("SVD", components):
1407 # combined_reco_tracks_name is only relevant in the 'after_ToCDCCKF' option
1408 combined_reco_tracks_name = "CDCSVDRecoTracks"
1409
1410 # The output of the additional SVD tracking (ToSVDCKF in this case) depends on whether
1411 # the CKF is the last or second to last algorithm to run. If it's the last one, use 'output_reco_tracks',
1412 # else use 'CDCSVDRecoTracks'
1413 tmp_output_reco_tracks = output_reco_tracks if "before_ToSVDCKF" else combined_reco_tracks_name
1414 add_svd_track_finding(path,
1415 components=components,
1416 input_reco_tracks=latest_reco_tracks,
1417 output_reco_tracks=tmp_output_reco_tracks,
1418 temporary_reco_tracks=svd_reco_tracks,
1419 use_mc_truth=use_mc_truth,
1420 svd_ckf_mode="ckf_merger_plus_spacepoint_ckf",
1421 add_both_directions=add_both_directions,
1422 use_svd_to_cdc_ckf=False,
1423 prune_temporary_tracks=prune_temporary_tracks)
1424 if temporary_reco_tracks_merging_strategy == "before_ToSVDCKF":
1425 temporary_reco_track_list.append(output_reco_tracks)
1426 latest_reco_tracks = output_reco_tracks
1427 elif temporary_reco_tracks_merging_strategy == "after_ToSVDCKF":
1428 temporary_reco_track_list.append(combined_reco_tracks_name)
1429 latest_reco_tracks = combined_reco_tracks_name
1430
1431 if temporary_reco_tracks_merging_strategy == "after_ToSVDCKF":
1432 path.add_module("RecoTrackStoreArrayCombiner",
1433 Temp1RecoTracksStoreArrayName=latest_reco_tracks,
1434 Temp2RecoTracksStoreArrayName=svd_cdc_reco_tracks,
1435 recoTracksStoreArrayName=output_reco_tracks)
1436 temporary_reco_track_list.append(output_reco_tracks)
1437 latest_reco_tracks = output_reco_tracks
1438
1439 return (latest_reco_tracks, temporary_reco_track_list)