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