Belle II Software  release-06-01-15
path_utils.py
1 
8 
9 from pybasf2 import B2WARNING
10 
11 from basf2 import register_module
12 from ckf.path_functions import add_pxd_ckf, add_ckf_based_merger, add_svd_ckf, add_cosmics_svd_ckf, add_cosmics_pxd_ckf
13 from pxd import add_pxd_reconstruction
14 from svd import add_svd_reconstruction
15 from tracking.adjustments import adjust_module
16 
17 
18 def use_local_sectormap(path, pathToLocalSM):
19  """
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 
33 def 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 
53 def add_hit_preparation_modules(path, components=None):
54  """
55  Helper fucntion to prepare the hit information to be used by tracking.
56  """
57 
58  # Preparation of the SVD clusters
59  if is_svd_used(components):
60  add_svd_reconstruction(path)
61 
62  # Preparation of the PXD clusters
63  if is_pxd_used(components):
64  add_pxd_reconstruction(path)
65 
66 
67 def add_track_fit_and_track_creator(path, components=None, pruneTracks=False, trackFitHypotheses=None,
68  reco_tracks="RecoTracks", add_mva_quality_indicator=False):
69  """
70  Helper function to add the modules performing the
71  track fit, the V0 fit and the Belle2 track creation to the path.
72 
73  :param path: The path to add the tracking reconstruction modules to
74  :param components: the list of geometry components in use or None for all components.
75  :param pruneTracks: Delete all hits expect the first and the last from the found tracks.
76  :param reco_tracks: Name of the StoreArray where the reco tracks should be stored
77  :param add_mva_quality_indicator: If true, add the MVA track quality estimation
78  to the path that sets the quality indicator property of the found tracks.
79  """
80 
81  add_prefilter_track_fit_and_track_creator(path,
82  trackFitHypotheses=trackFitHypotheses,
83  reco_tracks=reco_tracks,
84  add_mva_quality_indicator=add_mva_quality_indicator)
85 
86  add_postfilter_track_fit(path, components=components, pruneTracks=pruneTracks, reco_tracks=reco_tracks)
87 
88 
89 def add_prefilter_track_fit_and_track_creator(path, trackFitHypotheses=None,
90  reco_tracks="RecoTracks", add_mva_quality_indicator=False):
91  """
92  Helper function to add only the modules required to calculate HLT filter decision:
93  performing the track fit and the Belle2 track creation to the path.
94 
95  :param path: The path to add the tracking reconstruction modules to
96  :param reco_tracks: Name of the StoreArray where the reco tracks should be stored
97  :param add_mva_quality_indicator: If true, add the MVA track quality estimation
98  to the path that sets the quality indicator property of the found tracks.
99  """
100 
101  # Correct time seed
102  path.add_module("IPTrackTimeEstimator",
103  recoTracksStoreArrayName=reco_tracks, useFittedInformation=False)
104  # track fitting
105  path.add_module("DAFRecoFitter", recoTracksStoreArrayName=reco_tracks).set_name(
106  "Combined_DAFRecoFitter")
107  # Add MVA classifier that uses information not included in the calculation of the fit p-value
108  # to add a track quality indicator for classification of fake vs. MC-matched tracks
109  if add_mva_quality_indicator:
110  path.add_module("TrackQualityEstimatorMVA", collectEventFeatures=True)
111  # create Belle2 Tracks from the genfit Tracks
112  # The following particle hypothesis will be fitted: Pion, Kaon and Proton
113  # Muon fit is working but gives very similar as the Pion due to the closeness of masses
114  # -> therefore not in the default fit list
115  # Electron fit has as systematic bias and therefore not done here. Therefore, pion fits
116  # will be used for electrons which gives a better result as GenFit's current electron
117  # implementation.
118  path.add_module('TrackCreator', recoTrackColName=reco_tracks,
119  pdgCodes=[211, 321, 2212] if not trackFitHypotheses else trackFitHypotheses)
120 
121 
122 def add_postfilter_track_fit(path, components=None, pruneTracks=False, reco_tracks="RecoTracks"):
123  """
124  Helper function to add the modules not requred to calcualte HLT filter decision: performing
125  the V0 fit to the path.
126 
127  :param path: The path to add the tracking reconstruction modules to
128  :param components: the list of geometry components in use or None for all components.
129  :param pruneTracks: Delete all hits expect the first and the last from the found tracks.
130  :param reco_tracks: Name of the StoreArray where the reco tracks should be stored
131  """
132 
133  # V0 finding
134  path.add_module('V0Finder', RecoTracks=reco_tracks, v0FitterMode=1)
135 
136  # prune genfit tracks
137  if pruneTracks:
138  add_prune_tracks(path, components=components, reco_tracks=reco_tracks)
139 
140 
141 def add_cr_track_fit_and_track_creator(path, components=None,
142  prune_tracks=False, event_timing_extraction=True,
143  reco_tracks="RecoTracks", tracks=""):
144  """
145  Helper function to add the modules performing the cdc cr track fit
146  and track creation to the path.
147 
148  :param path: The path to which to add the tracking reconstruction modules
149  :param components: the list of geometry components in use or None for all components.
150  :param reco_tracks: The name of the reco tracks to use
151  :param tracks: the name of the output Belle tracks
152  :param prune_tracks: Delete all hits expect the first and the last from the found tracks.
153  :param event_timing_extraction: extract the event time
154  """
155 
156  # Time seed
157  path.add_module("PlaneTriggerTrackTimeEstimator",
158  recoTracksStoreArrayName=reco_tracks,
159  pdgCodeToUseForEstimation=13,
160  triggerPlanePosition=[0., 0., 0.],
161  triggerPlaneDirection=[0., 1., 0.],
162  useFittedInformation=False)
163 
164  # Initial track fitting
165  path.add_module("DAFRecoFitter",
166  recoTracksStoreArrayName=reco_tracks,
167  probCut=0.00001,
168  pdgCodesToUseForFitting=13)
169 
170  # Correct time seed
171  path.add_module("PlaneTriggerTrackTimeEstimator",
172  recoTracksStoreArrayName=reco_tracks,
173  pdgCodeToUseForEstimation=13,
174  triggerPlanePosition=[0., 0., 0.],
175  triggerPlaneDirection=[0., 1., 0.],
176  useFittedInformation=True)
177 
178  # Final Track fitting
179  path.add_module("DAFRecoFitter",
180  recoTracksStoreArrayName=reco_tracks,
181  pdgCodesToUseForFitting=13
182  )
183 
184  if event_timing_extraction:
185  # Extract the time
186  path.add_module("FullGridChi2TrackTimeExtractor",
187  RecoTracksStoreArrayName=reco_tracks,
188  GridMaximalT0Value=40,
189  GridMinimalT0Value=-40,
190  GridGridSteps=6
191  )
192 
193  # Track fitting
194  path.add_module("DAFRecoFitter",
195  # probCut=0.00001,
196  recoTracksStoreArrayName=reco_tracks,
197  pdgCodesToUseForFitting=13
198  )
199 
200  # Create Belle2 Tracks from the genfit Tracks
201  path.add_module('TrackCreator',
202  pdgCodes=[13],
203  recoTrackColName=reco_tracks,
204  trackColName=tracks,
205  useClosestHitToIP=True,
206  useBFieldAtHit=True
207  )
208 
209  # Prune genfit tracks
210  if prune_tracks:
211  add_prune_tracks(path=path, components=components,
212  reco_tracks=reco_tracks)
213 
214 
215 def add_mc_matcher(path, components=None, mc_reco_tracks="MCRecoTracks",
216  reco_tracks="RecoTracks", use_second_cdc_hits=False,
217  split_after_delta_t=-1.0):
218  """
219  Match the tracks to the MC truth. The matching works based on
220  the output of the TrackFinderMCTruthRecoTracks.
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 adjecent SimHits is more than the given value
229  """
230  path.add_module('TrackFinderMCTruthRecoTracks',
231  RecoTracksStoreArrayName=mc_reco_tracks,
232  WhichParticles=[],
233  UseSecondCDCHits=use_second_cdc_hits,
234  UsePXDHits=is_pxd_used(components),
235  UseSVDHits=is_svd_used(components),
236  UseCDCHits=is_cdc_used(components),
237  SplitAfterDeltaT=split_after_delta_t)
238 
239  path.add_module('MCRecoTracksMatcher',
240  mcRecoTracksStoreArrayName=mc_reco_tracks,
241  prRecoTracksStoreArrayName=reco_tracks,
242  UsePXDHits=is_pxd_used(components),
243  UseSVDHits=is_svd_used(components),
244  UseCDCHits=is_cdc_used(components))
245 
246 
247 def add_prune_tracks(path, components=None, reco_tracks="RecoTracks"):
248  """
249  Adds removal of the intermediate states at each measurement from the fitted tracks.
250 
251  :param path: The path to add the tracking reconstruction modules to
252  :param components: the list of geometry components in use or None for all components.
253  :param reco_tracks: Name of the StoreArray where the reco tracks should be stored
254  """
255 
256  # do not add any pruning, if no tracking detectors are in the components
257  if components and not ('SVD' in components or 'CDC' in components):
258  return
259 
260  path.add_module('PruneRecoTracks', storeArrayName=reco_tracks)
261  path.add_module("PruneGenfitTracks")
262 
263 
264 def add_pxd_track_finding(path, components, input_reco_tracks, output_reco_tracks, use_mc_truth=False,
265  add_both_directions=False, temporary_reco_tracks="PXDRecoTracks", **kwargs):
266  """Add the pxd track finding to the path"""
267  if not is_pxd_used(components):
268  return
269 
270  if use_mc_truth:
271  # MC CKF needs MC matching information
272  path.add_module("MCRecoTracksMatcher", UsePXDHits=False,
273  UseSVDHits=is_svd_used(components), UseCDCHits=is_cdc_used(components),
274  mcRecoTracksStoreArrayName="MCRecoTracks",
275  prRecoTracksStoreArrayName=input_reco_tracks)
276 
277  add_pxd_ckf(path, svd_cdc_reco_tracks=input_reco_tracks, pxd_reco_tracks=temporary_reco_tracks,
278  direction="backward", use_mc_truth=use_mc_truth, **kwargs)
279 
280  if add_both_directions:
281  add_pxd_ckf(path, svd_cdc_reco_tracks=input_reco_tracks, pxd_reco_tracks=temporary_reco_tracks,
282  direction="forward", use_mc_truth=use_mc_truth, **kwargs)
283 
284  path.add_module("RelatedTracksCombiner", CDCRecoTracksStoreArrayName=input_reco_tracks,
285  VXDRecoTracksStoreArrayName=temporary_reco_tracks, recoTracksStoreArrayName=output_reco_tracks)
286 
287 
288 def add_pxd_cr_track_finding(path, components, input_reco_tracks, output_reco_tracks, use_mc_truth=False,
289  add_both_directions=False, temporary_reco_tracks="PXDRecoTracks", **kwargs):
290  """Add the pxd track finding to the path"""
291  if not is_pxd_used(components):
292  return
293 
294  if use_mc_truth:
295  # MC CKF needs MC matching information
296  path.add_module("MCRecoTracksMatcher", UsePXDHits=False,
297  UseSVDHits=is_svd_used(components), UseCDCHits=is_cdc_used(components),
298  mcRecoTracksStoreArrayName="MCRecoTracks",
299  prRecoTracksStoreArrayName=input_reco_tracks)
300 
301  add_cosmics_pxd_ckf(path, svd_cdc_reco_tracks=input_reco_tracks, pxd_reco_tracks=temporary_reco_tracks,
302  direction="backward", use_mc_truth=use_mc_truth, **kwargs)
303 
304  if add_both_directions:
305  add_cosmics_pxd_ckf(path, svd_cdc_reco_tracks=input_reco_tracks, pxd_reco_tracks=temporary_reco_tracks,
306  direction="forward", use_mc_truth=use_mc_truth, **kwargs)
307 
308  path.add_module("RelatedTracksCombiner", CDCRecoTracksStoreArrayName=input_reco_tracks,
309  VXDRecoTracksStoreArrayName=temporary_reco_tracks, recoTracksStoreArrayName=output_reco_tracks)
310 
311 
312 def add_svd_track_finding(
313  path,
314  components,
315  input_reco_tracks,
316  output_reco_tracks,
317  svd_ckf_mode="VXDTF2_after",
318  use_mc_truth=False,
319  add_both_directions=True,
320  temporary_reco_tracks="SVDRecoTracks",
321  temporary_svd_cdc_reco_tracks="SVDPlusCDCStandaloneRecoTracks",
322  use_svd_to_cdc_ckf=True,
323  prune_temporary_tracks=True,
324  add_mva_quality_indicator=False,
325  **kwargs,
326 ):
327  """
328  Add SVD track finding to the path.
329 
330  :param path: The path to add the tracking reconstruction modules to
331  :param components: The list of geometry components in use or None for all components.
332  :param input_reco_tracks: Name of the StoreArray with the input reco tracks (usually from CDC) that are used in the
333  CKF track finding and are merged with the newly found SVD tracks into the ``output_reco_tracks``.
334  :param output_reco_tracks: Name of the StoreArray where the reco tracks outputted by the SVD track finding should be
335  stored.
336  :param svd_ckf_mode: String designating the mode of the CDC-to-SVD CKF, that is how it is combined with the VXDTF2
337  standalone track finding. One of "VXDTF2_after", "VXDTF2_before", "VXDTF2_before_with_second_ckf",
338  "only_ckf", "VXDTF2_alone", "cosmics".
339  :param use_mc_truth: Add mc matching and use the MC information in the CKF (but not in the VXDTF2)
340  :param add_both_directions: Whether to add the CKF with both forward and backward extrapolation directions instead
341  of just one.
342  :param temporary_reco_tracks: Intermediate store array where the SVD tracks from the VXDTF2 standalone track finding
343  are stored, before they are merged with CDC tracks and extended via the CKF tracking.
344  :param temporary_svd_cdc_reco_tracks: Intermediate store array where the combination of ``temporary_reco_tracks``
345  (from SVD) and ``input_reco_tracks`` (from CDC standalone) is stored, before the CKF is applied.
346  It is only used if ``use_svd_to_cdc_ckf`` is true. Otherwise, the combination is stored directly in
347  ``output_reco_tracks``.
348  :param use_svd_to_cdc_ckf: Whether to enable the CKF extrapolation from the SVD into the CDC.
349  That CKF application is not affected by ``svd_ckf_mode``.
350  :param prune_temporary_tracks: Delete all hits expect the first and last from intermediate track objects.
351  :param add_mva_quality_indicator: Add the VVXDQualityEstimatorMVA module to set the quality indicator
352  property for tracks from VXDTF2 standalone tracking
353  (ATTENTION: Standard triplet QI of VXDTF2 is replaced in this case
354  -> setting this option to 'True' will have some influence on the final track collection)
355  """
356 
357  if not is_svd_used(components):
358  return
359 
360  if not input_reco_tracks:
361  # We do not have an input track store array. So lets just add vxdtf track finding
362  add_vxd_track_finding_vxdtf2(path, components=["SVD"], reco_tracks=output_reco_tracks,
363  add_mva_quality_indicator=add_mva_quality_indicator)
364  return
365 
366  if use_mc_truth:
367  # MC CKF needs MC matching information
368  path.add_module("MCRecoTracksMatcher", UsePXDHits=False, UseSVDHits=False,
369  UseCDCHits=is_cdc_used(components),
370  mcRecoTracksStoreArrayName="MCRecoTracks",
371  prRecoTracksStoreArrayName=input_reco_tracks)
372 
373  if svd_ckf_mode == "VXDTF2_before":
374  add_vxd_track_finding_vxdtf2(path, components=["SVD"], reco_tracks=temporary_reco_tracks,
375  add_mva_quality_indicator=add_mva_quality_indicator)
376  add_ckf_based_merger(path, cdc_reco_tracks=input_reco_tracks, svd_reco_tracks=temporary_reco_tracks,
377  use_mc_truth=use_mc_truth, direction="backward", **kwargs)
378  if add_both_directions:
379  add_ckf_based_merger(path, cdc_reco_tracks=input_reco_tracks, svd_reco_tracks=temporary_reco_tracks,
380  use_mc_truth=use_mc_truth, direction="forward", **kwargs)
381 
382  elif svd_ckf_mode == "VXDTF2_before_with_second_ckf":
383  add_vxd_track_finding_vxdtf2(path, components=["SVD"], reco_tracks=temporary_reco_tracks,
384  add_mva_quality_indicator=add_mva_quality_indicator)
385  add_ckf_based_merger(path, cdc_reco_tracks=input_reco_tracks, svd_reco_tracks=temporary_reco_tracks,
386  use_mc_truth=use_mc_truth, direction="backward", **kwargs)
387  if add_both_directions:
388  add_ckf_based_merger(path, cdc_reco_tracks=input_reco_tracks, svd_reco_tracks=temporary_reco_tracks,
389  use_mc_truth=use_mc_truth, direction="forward", **kwargs)
390  add_svd_ckf(path, cdc_reco_tracks=input_reco_tracks, svd_reco_tracks=temporary_reco_tracks,
391  use_mc_truth=use_mc_truth, direction="backward", **kwargs)
392  if add_both_directions:
393  add_svd_ckf(path, cdc_reco_tracks=input_reco_tracks, svd_reco_tracks=temporary_reco_tracks,
394  use_mc_truth=use_mc_truth, direction="forward", filter_cut=0.01, **kwargs)
395 
396  elif svd_ckf_mode == "only_ckf":
397  add_svd_ckf(path, cdc_reco_tracks=input_reco_tracks, svd_reco_tracks=temporary_reco_tracks,
398  use_mc_truth=use_mc_truth, direction="backward", **kwargs)
399  if add_both_directions:
400  add_svd_ckf(path, cdc_reco_tracks=input_reco_tracks, svd_reco_tracks=temporary_reco_tracks,
401  use_mc_truth=use_mc_truth, direction="forward", filter_cut=0.01, **kwargs)
402 
403  elif svd_ckf_mode == "VXDTF2_after":
404  add_svd_ckf(path, cdc_reco_tracks=input_reco_tracks, svd_reco_tracks=temporary_reco_tracks,
405  use_mc_truth=use_mc_truth, direction="backward", **kwargs)
406  if add_both_directions:
407  add_svd_ckf(path, cdc_reco_tracks=input_reco_tracks, svd_reco_tracks=temporary_reco_tracks,
408  use_mc_truth=use_mc_truth, direction="forward", filter_cut=0.01, **kwargs)
409 
410  add_vxd_track_finding_vxdtf2(path, components=["SVD"], reco_tracks=temporary_reco_tracks,
411  add_mva_quality_indicator=add_mva_quality_indicator)
412  add_ckf_based_merger(path, cdc_reco_tracks=input_reco_tracks, svd_reco_tracks=temporary_reco_tracks,
413  use_mc_truth=use_mc_truth, direction="backward", **kwargs)
414  if add_both_directions:
415  add_ckf_based_merger(path, cdc_reco_tracks=input_reco_tracks, svd_reco_tracks=temporary_reco_tracks,
416  use_mc_truth=use_mc_truth, direction="forward", **kwargs)
417 
418  elif svd_ckf_mode == "VXDTF2_alone":
419  add_vxd_track_finding_vxdtf2(path, components=["SVD"], reco_tracks=temporary_reco_tracks,
420  add_mva_quality_indicator=add_mva_quality_indicator)
421  path.add_module('VXDCDCTrackMerger',
422  CDCRecoTrackColName=input_reco_tracks,
423  VXDRecoTrackColName=temporary_reco_tracks)
424 
425  elif svd_ckf_mode == "cosmics":
426  add_cosmics_svd_ckf(path, cdc_reco_tracks=input_reco_tracks, svd_reco_tracks=temporary_reco_tracks,
427  use_mc_truth=use_mc_truth, direction="backward", **kwargs)
428  if add_both_directions:
429  add_cosmics_svd_ckf(path, cdc_reco_tracks=input_reco_tracks, svd_reco_tracks=temporary_reco_tracks,
430  use_mc_truth=use_mc_truth, direction="forward", **kwargs)
431 
432  else:
433  raise ValueError(f"Do not understand the svd_ckf_mode {svd_ckf_mode}")
434 
435  if use_svd_to_cdc_ckf:
436  combined_svd_cdc_standalone_tracks = temporary_svd_cdc_reco_tracks
437  else:
438  combined_svd_cdc_standalone_tracks = output_reco_tracks
439 
440  # Write out the combinations of tracks
441  path.add_module("RelatedTracksCombiner", VXDRecoTracksStoreArrayName=temporary_reco_tracks,
442  CDCRecoTracksStoreArrayName=input_reco_tracks,
443  recoTracksStoreArrayName=combined_svd_cdc_standalone_tracks)
444 
445  if use_svd_to_cdc_ckf:
446  path.add_module("ToCDCCKF",
447  inputWireHits="CDCWireHitVector",
448  inputRecoTrackStoreArrayName=combined_svd_cdc_standalone_tracks,
449  relatedRecoTrackStoreArrayName="CKFCDCRecoTracks",
450  relationCheckForDirection="backward",
451  ignoreTracksWithCDChits=True,
452  outputRecoTrackStoreArrayName="CKFCDCRecoTracks",
453  outputRelationRecoTrackStoreArrayName=combined_svd_cdc_standalone_tracks,
454  writeOutDirection="backward",
455  stateBasicFilterParameters={"maximalHitDistance": 0.15},
456  pathFilter="arc_length",
457  maximalLayerJump=4)
458 
459  path.add_module("CDCCKFTracksCombiner",
460  CDCRecoTracksStoreArrayName="CKFCDCRecoTracks",
461  VXDRecoTracksStoreArrayName=combined_svd_cdc_standalone_tracks,
462  recoTracksStoreArrayName=output_reco_tracks)
463 
464  if prune_temporary_tracks:
465  for temp_reco_track in [combined_svd_cdc_standalone_tracks, "CKFCDCRecoTracks"]:
466  path.add_module('PruneRecoTracks', storeArrayName=temp_reco_track)
467 
468 
469 def add_cdc_track_finding(path, output_reco_tracks="RecoTracks", with_ca=False,
470  use_second_hits=False, add_mva_quality_indicator=True,
471  reattach_hits=False):
472  """
473  Convenience function for adding all cdc track finder modules
474  to the path.
475 
476  The result is a StoreArray with name @param reco_tracks full of RecoTracks (not TrackCands any more!).
477  Use the GenfitTrackCandidatesCreator Module to convert back.
478 
479  :param path: basf2 path
480  :param output_reco_tracks: Name of the output RecoTracks. Defaults to RecoTracks.
481  :param use_second_hits: If true, the second hit information will be used in the CDC track finding.
482  :param add_mva_quality_indicator: Add the TFCDC_TrackQualityEstimator module to set the CDC quality
483  indicator property of the CDC ``output_reco_tracks``
484  :param cdc_quality_estimator_weightfile: Weightfile identifier for the TFCDC_TrackQualityEstimator
485  :param reattach_hits: if true, use the ReattachCDCWireHitsToRecoTracks module at the end of the CDC track finding
486  to readd hits with bad ADC or TOT rejected by the TFCDC_WireHitPreparer module.
487  """
488  # add EventLevelTrackinginfo for logging errors
489  if 'RegisterEventLevelTrackingInfo' not in path:
490  path.add_module('RegisterEventLevelTrackingInfo')
491 
492  # Init the geometry for cdc tracking and the hits and cut low ADC hits
493  path.add_module("TFCDC_WireHitPreparer",
494  wirePosition="aligned",
495  useSecondHits=use_second_hits,
496  flightTimeEstimation="outwards",
497  filter="cuts_from_DB")
498 
499  # Constructs clusters
500  path.add_module("TFCDC_ClusterPreparer",
501  ClusterFilter="all",
502  ClusterFilterParameters={})
503 
504  # Find segments within the clusters
505  path.add_module("TFCDC_SegmentFinderFacetAutomaton")
506 
507  # Find axial tracks
508  path.add_module("TFCDC_AxialTrackFinderLegendre")
509 
510  # Improve the quality of the axial tracks
511  path.add_module("TFCDC_TrackQualityAsserter",
512  corrections=["B2B"])
513 
514  # Find the stereo hits to those axial tracks
515  path.add_module('TFCDC_StereoHitFinder')
516 
517  # Combine segments with axial tracks
518  path.add_module('TFCDC_SegmentTrackCombiner',
519  segmentTrackFilter="mva",
520  segmentTrackFilterParameters={"cut": 0.74},
521  trackFilter="mva",
522  trackFilterParameters={"cut": 0.1})
523 
524  output_tracks = "CDCTrackVector"
525 
526  if with_ca:
527  output_tracks = "CombinedCDCTrackVector"
528  path.add_module("TFCDC_TrackFinderSegmentPairAutomaton",
529  tracks="CDCTrackVector2")
530 
531  # Overwrites the origin CDCTrackVector
532  path.add_module("TFCDC_TrackCombiner",
533  inputTracks="CDCTrackVector",
534  secondaryInputTracks="CDCTrackVector2",
535  tracks=output_tracks)
536 
537  # Improve the quality of all tracks and output
538  path.add_module("TFCDC_TrackQualityAsserter",
539  inputTracks=output_tracks,
540  corrections=[
541  "LayerBreak",
542  "OneSuperlayer",
543  "Small",
544  ])
545 
546  if with_ca:
547  # Add curlers in the axial inner most superlayer
548  path.add_module("TFCDC_TrackCreatorSingleSegments",
549  inputTracks=output_tracks,
550  MinimalHitsBySuperLayerId={0: 15})
551 
552  if add_mva_quality_indicator:
553  # Add CDC-specific mva method to set the quality indicator for the CDC tracks
554  path.add_module(
555  "TFCDC_TrackQualityEstimator",
556  inputTracks=output_tracks,
557  filter='mva',
558  filterParameters={"cut": 0.7},
559  deleteTracks=True,
560  resetTakenFlag=True
561  )
562 
563  # Export CDCTracks to RecoTracks representation
564  path.add_module("TFCDC_TrackExporter",
565  inputTracks=output_tracks,
566  RecoTracksStoreArrayName="CDCRecoTracksBeforeReattaching" if reattach_hits else output_reco_tracks)
567 
568  if reattach_hits:
569  # The ReattachCDCWireHitsToRecoTracks module (below) requires the SetupGenfitExtrapolation module
570  if 'SetupGenfitExtrapolation' not in path:
571  # Prepare Genfit extrapolation
572  path.add_module('SetupGenfitExtrapolation')
573 
574  # Loop over low-ADC/TOT CDCWireHits and RecoTracks and reattach the hits to the tracks if they are close enough
575  path.add_module("ReattachCDCWireHitsToRecoTracks",
576  inputRecoTracksStoreArrayName="CDCRecoTracksBeforeReattaching",
577  outputRecoTracksStoreArrayName=output_reco_tracks)
578 
579  # Correct time seed (only necessary for the CDC tracks)
580  path.add_module("IPTrackTimeEstimator",
581  useFittedInformation=False,
582  recoTracksStoreArrayName=output_reco_tracks)
583 
584  # run fast t0 estimation from CDC hits only
585  path.add_module("CDCHitBasedT0Extraction")
586 
587  # prepare mdst event level info
588  path.add_module("CDCTrackingEventLevelMdstInfoFiller")
589 
590 
591 def add_eclcdc_track_finding(path, components, output_reco_tracks="RecoTracks", prune_temporary_tracks=True):
592  """
593  Convenience function for adding all track finder modules to the path that are based on ecl seeds.
594 
595  The result is a StoreArray with name @param reco_tracks full of RecoTracks.
596  Use the GenfitTrackCandidatesCreator Module to convert back.
597 
598  :param path: basf2 path
599  :param components: the list of geometry components in use or None for all components.
600  :param output_reco_tracks: Name of the output RecoTracks. Defaults to RecoTracks.
601  :param pruneTracks: Delete all hits expect the first and the last from the found tracks.
602  """
603  if not is_cdc_used(components) or not is_ecl_used(components):
604  return
605 
606  ecl_cdc_reco_tracks = "ECLCDCRecoTracks"
607 
608  if not is_svd_used(components):
609  ecl_cdc_reco_tracks = output_reco_tracks
610 
611  # collections that will be pruned
612  temporary_reco_track_list = []
613 
614  path.add_module("ToCDCFromEclCKF",
615  inputWireHits="CDCWireHitVector",
616  minimalEnRequirementCluster=0.3,
617  eclSeedRecoTrackStoreArrayName='EclSeedRecoTracks',
618  hitFindingDirection="backward",
619  outputRecoTrackStoreArrayName="CDCRecoTracksFromEcl",
620  outputRelationRecoTrackStoreArrayName="EclSeedRecoTracks",
621  writeOutDirection="forward",
622  stateBasicFilterParameters={"maximalHitDistance": 7.5, "maximalHitDistanceEclSeed": 75.0},
623  stateExtrapolationFilterParameters={"direction": "backward"},
624  pathFilter="arc_length_fromEcl",
625  inputECLshowersStoreArrayName="ECLShowers",
626  trackFindingDirection="backward",
627  setTakenFlag=False,
628  seedComponent="ECL"
629  )
630 
631  path.add_module("ToCDCCKF",
632  inputWireHits="CDCWireHitVector",
633  inputRecoTrackStoreArrayName="CDCRecoTracksFromEcl",
634  relatedRecoTrackStoreArrayName=ecl_cdc_reco_tracks,
635  relationCheckForDirection="backward",
636  outputRecoTrackStoreArrayName=ecl_cdc_reco_tracks,
637  outputRelationRecoTrackStoreArrayName="CDCRecoTracksFromEcl",
638  writeOutDirection="backward",
639  stateBasicFilterParameters={"maximalHitDistance": 0.75},
640  stateExtrapolationFilterParameters={"direction": "forward"},
641  pathFilter="arc_length",
642  seedComponent="ECL"
643  )
644  # "EclSeedRecoTracks" don't have to be added to the list as these do not contain any hits
645  temporary_reco_track_list.append('CDCRecoTracksFromEcl')
646 
647  # Do the following modules have to be added as these are executed already after
648  # the CDC standalone?
649  # If so: they also have to be included in the new SVD->CDC CKF (see add_svd_track_finding(..) above)
650 
651  # Correct time seed (only necessary for the CDC tracks)
652  # path.add_module("IPTrackTimeEstimator",
653  # useFittedInformation=False,
654  # recoTracksStoreArrayName=ecl_cdc_reco_tracks)
655 
656  # run fast t0 estimation from CDC hits only
657  # path.add_module("CDCHitBasedT0Extraction")
658 
659  # prepare mdst event level info
660  # path.add_module("CDCTrackingEventLevelMdstInfoFiller")
661 
662  if is_svd_used(components):
663  add_svd_track_finding(path, components=components, input_reco_tracks=ecl_cdc_reco_tracks,
664  output_reco_tracks=output_reco_tracks, use_mc_truth=False,
665  svd_ckf_mode="only_ckf", add_both_directions=False,
666  temporary_reco_tracks="ECLSVDRecoTracks", use_svd_to_cdc_ckf=False,
667  prune_temporary_tracks=prune_temporary_tracks)
668  temporary_reco_track_list.append(ecl_cdc_reco_tracks)
669  temporary_reco_track_list.append('ECLSVDRecoTracks')
670 
671  if prune_temporary_tracks:
672  for temporary_reco_track_name in temporary_reco_track_list:
673  if temporary_reco_track_name != output_reco_tracks:
674  path.add_module('PruneRecoTracks', storeArrayName=temporary_reco_track_name)
675 
676 
677 def add_cdc_cr_track_finding(path, output_reco_tracks="RecoTracks", trigger_point=(0, 0, 0), merge_tracks=True,
678  use_second_cdc_hits=False):
679  """
680  Convenience function for adding all cdc track finder modules currently dedicated for the CDC-TOP testbeam
681  to the path.
682 
683  The result is a StoreArray with name @param reco_tracks full of RecoTracks (not TrackCands any more!).
684 
685  Arguments
686  ---------
687  path: basf2.Path
688  The path to be filled
689  output_reco_tracks: str
690  Name of the output RecoTracks. Defaults to RecoTracks.
691  merge_tracks: bool
692  The upper and lower half of the tracks should be merged together in one track
693  use_second_hits: bool
694  If true, the second hit information will be used in the CDC track finding.
695  """
696 
697  # Init the geometry for cdc tracking and the hits
698  path.add_module("TFCDC_WireHitPreparer",
699  useSecondHits=use_second_cdc_hits,
700  flightTimeEstimation="downwards",
701  filter="cuts_from_DB",
702  triggerPoint=trigger_point)
703 
704  # Constructs clusters and reduce background hits
705  path.add_module("TFCDC_ClusterPreparer",
706  ClusterFilter="mva_bkg",
707  ClusterFilterParameters={"cut": 0.2})
708 
709  # Find segments within the clusters
710  path.add_module("TFCDC_SegmentFinderFacetAutomaton",
711  SegmentOrientation="downwards")
712 
713  # Find axial tracks
714  path.add_module("TFCDC_AxialTrackFinderLegendre")
715 
716  # Improve the quality of the axial tracks
717  path.add_module("TFCDC_TrackQualityAsserter",
718  corrections=["B2B"])
719 
720  # Find the stereo hits to those axial tracks
721  path.add_module('TFCDC_StereoHitFinder')
722 
723  # Combine segments with axial tracks
724  path.add_module('TFCDC_SegmentTrackCombiner',
725  segmentTrackFilter="mva",
726  segmentTrackFilterParameters={"cut": 0.74},
727  trackFilter="mva",
728  trackFilterParameters={"cut": 0.1})
729 
730  # Improve the quality of all tracks and output
731  path.add_module("TFCDC_TrackQualityAsserter",
732  corrections=["LayerBreak", "OneSuperlayer", "Small"],
733  )
734 
735  # Flip track orientation to always point downwards
736  path.add_module("TFCDC_TrackOrienter",
737  inputTracks="CDCTrackVector",
738  tracks="OrientedCDCTrackVector",
739  TrackOrientation="downwards",
740  )
741 
742  output_tracks = "OrientedCDCTrackVector"
743 
744  if merge_tracks:
745  # Merge tracks together if needed
746  path.add_module("TFCDC_TrackLinker",
747  inputTracks="OrientedCDCTrackVector",
748  tracks="MergedCDCTrackVector",
749  filter="phi",
750  )
751  output_tracks = "MergedCDCTrackVector"
752 
753  # However, we also want to export the non merged tracks
754  # Correct time seed - assumes velocity near light speed
755  path.add_module("TFCDC_TrackFlightTimeAdjuster",
756  inputTracks="OrientedCDCTrackVector",
757  )
758 
759  # Export CDCTracks to RecoTracks representation
760  path.add_module("TFCDC_TrackExporter",
761  inputTracks="OrientedCDCTrackVector",
762  RecoTracksStoreArrayName="NonMergedRecoTracks")
763 
764  # Correct time seed - assumes velocity near light speed
765  path.add_module("TFCDC_TrackFlightTimeAdjuster",
766  inputTracks=output_tracks,
767  )
768 
769  # Export CDCTracks to RecoTracks representation
770  path.add_module("TFCDC_TrackExporter",
771  inputTracks=output_tracks,
772  RecoTracksStoreArrayName=output_reco_tracks)
773 
774  # run fast t0 estimation from CDC hits only
775  path.add_module("CDCHitBasedT0Extraction")
776 
777 
778 def add_vxd_track_finding_vxdtf2(
779  path,
780  svd_clusters="",
781  reco_tracks="RecoTracks",
782  components=None,
783  suffix="",
784  useTwoStepSelection=True,
785  PXDminSVDSPs=3,
786  sectormap_file=None,
787  custom_setup_name=None,
788  min_SPTC_quality=0.,
789  filter_overlapping=True,
790  add_mva_quality_indicator=False,
791 ):
792  """
793  Convenience function for adding all vxd track finder Version 2 modules
794  to the path.
795 
796  The result is a StoreArray with name @param reco_tracks full of RecoTracks (not TrackCands any more!).
797  Use the GenfitTrackCandidatesCreator Module to convert back.
798 
799  :param path: basf2 path
800  :param svd_clusters: SVDCluster collection name
801  :param reco_tracks: Name of the output RecoTracks, Defaults to RecoTracks.
802  :param components: List of the detector components to be used in the reconstruction. Defaults to None which means
803  all components.
804  :param suffix: all names of intermediate Storearrays will have the suffix appended. Useful in cases someone needs to
805  put several instances of track finding in one path.
806  :param useTwoStepSelection: if True Families will be defined during path creation and will be used to create only
807  the best candidate per family.
808  :param PXDminSVDSPs: When using PXD require at least this number of SVD SPs for the SPTCs
809  :param sectormap_file: if set to a finite value, a file will be used instead of the sectormap in the database.
810  :param custom_setup_name: Set a custom setup name for the tree in the sector map.
811  :param min_SPTC_quality: minimal qualityIndicator value to keeps SPTCs after the QualityEstimation.
812  0 means no cut. Default: 0
813  :param filter_overlapping: Whether to use SVDOverlapResolver, Default: True
814  :param add_mva_quality_indicator: Whether to use the MVA Quality Estimator module for VXDTF2 tracks to set the
815  quality_indicator property of the found ``reco_tracks``. Default: False.
816  """
817 
820 
821  # setting different for pxd and svd:
822  if is_pxd_used(components):
823  setup_name = "SVDPXDDefault"
824  db_sec_map_file = "VXDSectorMap_v000.root"
825  use_pxd = True
826  else:
827  setup_name = "SVDOnlyDefault"
828  db_sec_map_file = "SVDSectorMap_v000.root"
829  use_pxd = False
830 
831 
835 
836  # setup the event level tracking info to log errors and stuff
837  nameTrackingInfoModule = "RegisterEventLevelTrackingInfo" + suffix
838  nameEventTrackingInfo = "EventLevelTrackingInfo" + suffix
839  if nameTrackingInfoModule not in path:
840  # Use modified name of module and created StoreObj as module might be added twice (PXDDataReduction)
841  registerEventlevelTrackingInfo = register_module('RegisterEventLevelTrackingInfo')
842  registerEventlevelTrackingInfo.set_name(nameTrackingInfoModule)
843  registerEventlevelTrackingInfo.param('EventLevelTrackingInfoName', nameEventTrackingInfo)
844  path.add_module(registerEventlevelTrackingInfo)
845 
846  nameSPs = 'SpacePoints' + suffix
847 
848  pxdSPCreatorName = 'PXDSpacePointCreator' + suffix
849  if pxdSPCreatorName not in [e.name() for e in path.modules()]:
850  if use_pxd:
851  spCreatorPXD = register_module('PXDSpacePointCreator')
852  spCreatorPXD.set_name(pxdSPCreatorName)
853  spCreatorPXD.param('NameOfInstance', 'PXDSpacePoints')
854  spCreatorPXD.param('SpacePoints', "PXD" + nameSPs)
855  path.add_module(spCreatorPXD)
856 
857  # SecMap Bootstrap
858  secMapBootStrap = register_module('SectorMapBootstrap')
859  secMapBootStrap.param('ReadSectorMap', sectormap_file is not None) # read from file
860  secMapBootStrap.param('ReadSecMapFromDB', sectormap_file is None) # this will override ReadSectorMap
861  secMapBootStrap.param('SectorMapsInputFile', sectormap_file or db_sec_map_file)
862  secMapBootStrap.param('SetupToRead', custom_setup_name or setup_name)
863  secMapBootStrap.param('WriteSectorMap', False)
864  path.add_module(secMapBootStrap)
865 
866 
870 
871  spacePointArrayNames = ["SVD" + nameSPs]
872  if use_pxd:
873  spacePointArrayNames += ["PXD" + nameSPs]
874 
875  nameSegNet = 'SegmentNetwork' + suffix
876 
877  segNetProducer = register_module('SegmentNetworkProducer')
878  segNetProducer.param('NetworkOutputName', nameSegNet)
879  segNetProducer.param('SpacePointsArrayNames', spacePointArrayNames)
880  segNetProducer.param('sectorMapName', custom_setup_name or setup_name)
881  segNetProducer.param('EventLevelTrackingInfoName', nameEventTrackingInfo)
882  path.add_module(segNetProducer)
883 
884 
888 
889  # append a suffix to the storearray name
890  nameSPTCs = 'SPTrackCands' + suffix
891 
892  trackFinder = register_module('TrackFinderVXDCellOMat')
893  trackFinder.param('NetworkName', nameSegNet)
894  trackFinder.param('SpacePointTrackCandArrayName', nameSPTCs)
895  trackFinder.param('printNetworks', False)
896  trackFinder.param('setFamilies', useTwoStepSelection)
897  trackFinder.param('selectBestPerFamily', useTwoStepSelection)
898  trackFinder.param('xBestPerFamily', 30)
899  trackFinder.param('EventLevelTrackingInfoName', nameEventTrackingInfo)
900  path.add_module(trackFinder)
901 
902  if useTwoStepSelection:
903  subSetModule = register_module('AddVXDTrackCandidateSubSets')
904  subSetModule.param('NameSpacePointTrackCands', nameSPTCs)
905  path.add_module(subSetModule)
906 
907 
911 
912  # When using PXD require at least PXDminSVDSPs SVD SPs for the SPTCs
913  if use_pxd:
914  pxdSVDCut = register_module('PXDSVDCut')
915  pxdSVDCut.param('minSVDSPs', PXDminSVDSPs)
916  pxdSVDCut.param('SpacePointTrackCandsStoreArrayName', nameSPTCs)
917  path.add_module(pxdSVDCut)
918 
919  if add_mva_quality_indicator:
920  path.add_module(
921  "VXDQualityEstimatorMVA",
922  SpacePointTrackCandsStoreArrayName=nameSPTCs,
923  )
924  else:
925  path.add_module(
926  'QualityEstimatorVXD',
927  EstimationMethod='tripletFit',
928  SpacePointTrackCandsStoreArrayName=nameSPTCs,
929  )
930 
931  if min_SPTC_quality > 0.:
932  qualityIndicatorCutter = register_module('VXDTrackCandidatesQualityIndicatorCutter')
933  qualityIndicatorCutter.param('minRequiredQuality', min_SPTC_quality)
934  qualityIndicatorCutter.param('NameSpacePointTrackCands', nameSPTCs)
935  path.add_module(qualityIndicatorCutter)
936 
937  # will discard track candidates (with low quality estimators) if the number of TC is above threshold
938  maxCandidateSelection = register_module('BestVXDTrackCandidatesSelector')
939  maxCandidateSelection.param('NameSpacePointTrackCands', nameSPTCs)
940  maxCandidateSelection.param('NewNameSpacePointTrackCands', nameSPTCs)
941  maxCandidateSelection.param('SubsetCreation', False)
942  path.add_module(maxCandidateSelection)
943 
944  # Properties
945  vIPRemover = register_module('SPTCvirtualIPRemover')
946  vIPRemover.param('tcArrayName', nameSPTCs)
947  # want to remove virtualIP for any track length
948  vIPRemover.param('maxTCLengthForVIPKeeping', 0)
949  path.add_module(vIPRemover)
950 
951 
955 
956  if filter_overlapping:
957  overlapResolver = register_module('SVDOverlapResolver')
958  overlapResolver.param('NameSpacePointTrackCands', nameSPTCs)
959  overlapResolver.param('ResolveMethod', 'greedy') # other option is 'hopfield'
960  overlapResolver.param('NameSVDClusters', svd_clusters)
961  path.add_module(overlapResolver)
962 
963 
967 
968  momSeedRetriever = register_module('SPTCmomentumSeedRetriever')
969  momSeedRetriever.param('tcArrayName', nameSPTCs)
970  path.add_module(momSeedRetriever)
971 
972  converter = register_module('SPTC2RTConverter')
973  converter.param('recoTracksStoreArrayName', reco_tracks)
974  converter.param('spacePointsTCsStoreArrayName', nameSPTCs)
975  converter.param('svdClustersName', svd_clusters)
976  converter.param('svdHitsStoreArrayName', svd_clusters)
977  path.add_module(converter)
978 
979 
980 def is_svd_used(components):
981  """Return true, if the SVD is present in the components list"""
982  return components is None or 'SVD' in components
983 
984 
985 def is_pxd_used(components):
986  """Return true, if the PXD is present in the components list"""
987  return components is None or 'PXD' in components
988 
989 
990 def is_cdc_used(components):
991  """Return true, if the CDC is present in the components list"""
992  return components is None or 'CDC' in components
993 
994 
995 def is_ecl_used(components):
996  """Return true, if the ECL is present in the components list"""
997  return components is None or 'ECL' in components