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