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