Belle II Software  release-05-01-25
collections.py
1 import basf2
2 import rawdata as raw
3 import reconstruction as reco
4 import modularAnalysis as ana
5 import vertex as vtx
6 
7 from collections import namedtuple
8 
9 MillepedeCollection = namedtuple('MillepedeCollection', ['name', 'files', 'path', 'params'])
10 
11 
12 def make_collection(name, files=None, path=None, **argk):
13  """
14  Handy function to make a collection configuration
15  to be passed in 'collections' argument of the create(...) function
16 
17  Parameters
18  ----------
19  name : str
20  Collection name
21  files : list(str)
22  List of input data files
23  path : basf2.Path
24  pre-collector path
25  argk : dict
26  Dictionary of collector parameters specific for collection
27 
28  Returns
29  -------
30  namedtuple('MillepedeCollection', ['name', 'files', 'path', 'params'])
31 
32  """
33  if files is None:
34  files = []
35  if path is None:
36  path = basf2.Path()
37 
38  return MillepedeCollection(name=name, path=path, files=files, params=argk)
39 
40 
41 def physicsTracks(name="physicsTracks", files=None, add_unpackers=True, klm=False, prescale=1.):
42  """
43  Standard collection of all RecoTracks with standard reconstruction
44 
45  Parameters
46  ----------
47  name : str
48  Collection name
49  files : list(str)
50  List of input data files
51  add_unpackers : bool
52  Whether to add unpacking (set to False for MC)
53  klm : bool
54  Whether to add muid hits to the track fit
55  prescale : float
56  Process only 'prescale' fraction of events
57  """
58  path = basf2.create_path()
59 
60  path.add_module('Progress')
61  path.add_module('RootInput')
62  if prescale != 1.:
63  path.add_module('Prescale', prescale=prescale).if_false(basf2.Path(), basf2.AfterConditionPath.END)
64  path.add_module('Gearbox')
65  path.add_module('Geometry')
66 
67  if add_unpackers:
68  raw.add_unpackers(path)
69 
70  reco.add_reconstruction(path, pruneTracks=False, add_muid_hits=klm)
71 
72  # teporary (?) fix : TODO: still needed?
73  tmp = basf2.create_path()
74  for m in path.modules():
75  if m.name() == "PXDPostErrorChecker":
76  m.param('CriticalErrorMask', 0)
77  if m.name() == "SVDSpacePointCreator":
78  m.param("MinClusterTime", -999)
79  tmp.add_module(m)
80  path = tmp
81  path.add_module('DAFRecoFitter')
82 
83  return make_collection(name, files=files, path=path, tracks=['RecoTracks'])
84 
85 
86 def cosmicTracks(name="cosmicTracks",
87  files=None,
88  add_unpackers=True,
89  skim_hlt_cosmic=False,
90  cut='[z0 <= 57. or abs(d0) >= 26.5] and abs(dz) > 0.4 and nTracks == 1',
91  klm=False,
92  prescale=1.):
93  """
94  Standard collection of all RecoTracks with cosmic reconstruction
95 
96  Parameters
97  ----------
98  name : str
99  Collection name
100  files : list(str)
101  List of input data files
102  add_unpackers : bool
103  Whether to add unpacking (set to False for MC)
104  skim_hlt_cosmic : bool
105  Whether to add TriggerSkim module and process only events with cosmic TRG
106  cut : str
107  Cut string to select GOOD events. By default set to avoid region of poorly described magnetic
108  field around QCS magnets + remove the 'background' from physics around IP
109  klm : bool
110  Whether to add muid hits to the track fit
111  prescale : float
112  Process only 'prescale' fraction of events
113  """
114  path = basf2.create_path()
115 
116  path.add_module('Progress')
117  path.add_module('RootInput')
118  if prescale != 1.:
119  path.add_module('Prescale', prescale=prescale).if_false(basf2.Path(), basf2.AfterConditionPath.END)
120 
121  if skim_hlt_cosmic:
122  path.add_module(
123  "TriggerSkim",
124  triggerLines=["software_trigger_cut&filter&cosmic"]).if_value(
125  "==0",
126  basf2.Path(),
127  basf2.AfterConditionPath.END)
128 
129  path.add_module('Gearbox')
130  path.add_module('Geometry')
131 
132  if add_unpackers:
133  raw.add_unpackers(path)
134 
135  path.add_module('SetupGenfitExtrapolation')
136  reco.add_cosmics_reconstruction(
137  path,
138  pruneTracks=False,
139  skipGeometryAdding=True,
140  data_taking_period='early_phase3',
141  merge_tracks=True,
142  add_muid_hits=klm
143  )
144 
145  # teporary (?) fix : TODO: still needed?
146  tmp = basf2.create_path()
147  for m in path.modules():
148  if m.name() == "PXDPostErrorChecker":
149  m.param('CriticalErrorMask', 0)
150  if m.name() == "SVDSpacePointCreator":
151  m.param("MinClusterTime", -999)
152  tmp.add_module(m)
153  path = tmp
154 
155  path.add_module('SetRecoTrackMomentum', automatic=True)
156  path.add_module('DAFRecoFitter', resortHits=True, pdgCodesToUseForFitting=[13])
157 
158  if cut is not None:
159  ana.fillParticleList('mu+:good_cosmics', cut, path=path)
160  # ana.variablesToNtuple('mu+:good_cosmics', variables=track_variables, filename='analysis_cosmics.root', path=path)
161  path.add_module('SkimFilter', particleLists=['mu+:good_cosmics']).if_false(basf2.create_path())
162 
163  return make_collection(name, files=files, path=path, tracks=['RecoTracks'])
164 
165 
166 def diMuonsIP(
167  name="diMuonsIP",
168  files=None,
169  add_unpackers=True,
170  skim_mumu_2trk=False,
171  muon_cut='p > 1.0 and abs(dz) < 2.0 and dr < 0.5',
172  dimuon_cut='',
173  klm=False,
174  prescale=1.):
175  """
176  Di-muons with vertex+beam constraint collection
177 
178  Parameters
179  ----------
180  name : str
181  Collection name
182  files : list(str)
183  List of input data files
184  add_unpackers : bool
185  Whether to add unpacking (set to False for MC)
186  skim_hlt_cosmic : bool
187  Whether to add TriggerSkim module and process only events with accept_mumu_2trk TRG
188  muon_cut : str
189  Cut string to select daughter muons
190  dimuon_cut : str
191  Cut string to apply for reconstructed di-muon decay
192  klm : bool
193  Whether to add muid hits to the track fit
194  prescale : float
195  Process only 'prescale' fraction of events
196  """
197  path = basf2.create_path()
198  path.add_module('Progress')
199  path.add_module('RootInput')
200  if prescale != 1.:
201  path.add_module('Prescale', prescale=prescale).if_false(basf2.Path(), basf2.AfterConditionPath.END)
202 
203  path.add_module('Gearbox')
204  path.add_module('Geometry')
205 
206  if skim_mumu_2trk:
207  path.add_module(
208  "TriggerSkim",
209  triggerLines=["software_trigger_cut&skim&accept_mumu_2trk"]).if_value(
210  "==0",
211  basf2.Path(),
212  basf2.AfterConditionPath.END)
213 
214  if add_unpackers:
215  raw.add_unpackers(path)
216 
217  reco.add_reconstruction(path, pruneTracks=False, add_muid_hits=klm)
218 
219  # teporary (?) fix : TODO: still needed?
220  tmp = basf2.create_path()
221  for m in path.modules():
222  if m.name() == "PXDPostErrorChecker":
223  m.param('CriticalErrorMask', 0)
224  if m.name() == "SVDSpacePointCreator":
225  m.param("MinClusterTime", -999)
226  tmp.add_module(m)
227  path = tmp
228 
229  path.add_module('DAFRecoFitter', pdgCodesToUseForFitting=[13])
230 
231  ana.fillParticleList(f"mu+:{name}", muon_cut, path=path)
232  ana.reconstructDecay(f"Upsilon(4S):{name} -> mu+:{name} mu-:{name}", dimuon_cut, path=path)
233 
234  vtx.raveFit(f"Upsilon(4S):{name}", 0.001, daughtersUpdate=True, silence_warning=True, path=path)
235 
236  return make_collection(name, files=files, path=path, primaryVertices=[f"Upsilon(4S):{name}"])