Belle II Software  release-05-02-19
caf_cdc.py
1 # -*- coding: utf-8 -*-
2 
3 """CDC tracking calibration. Performs the T0 determination using HLT skimmed raw data."""
4 
5 from prompt import CalibrationSettings, input_data_filters
6 from prompt.utils import events_in_basf2_file, ExpRun
7 import basf2
8 from random import choice
9 from caf.framework import Calibration
10 from caf import strategies
11 
12 
13 
14 settings = CalibrationSettings(name="CDC Tracking",
15  expert_username="eberthol",
16  description=__doc__,
17  input_data_formats=["raw"],
18  input_data_names=["mumutight_calib", "hadron_calib", "cosmic_calib"],
19  input_data_filters={"mumutight_calib": [input_data_filters["Data Tag"]["mumutight_calib"],
20  input_data_filters["Data Quality Tag"]["Good"],
21  input_data_filters["Magnet"]["On"]],
22  "hadron_calib": [input_data_filters["Data Tag"]["hadron_calib"],
23  input_data_filters["Data Quality Tag"]["Good"],
24  input_data_filters["Magnet"]["On"]],
25  "cosmic_calib": [input_data_filters["Data Tag"]["cosmic_calib"],
26  input_data_filters["Data Quality Tag"]["Good"],
27  input_data_filters["Magnet"]["On"]]},
28  depends_on=[],
29  expert_config={
30  "max_files_per_run": 100000,
31  "min_events_per_file": 1,
32  "max_events_per_calibration": 200000,
33  "max_events_per_calibration_for_xt_sr": 1000000,
34  "max_events_per_file": 5000,
35  "max_events_per_file_hadron": 2500,
36  "payload_boundaries": [],
37  "request_memory": 4
38  })
39 
40 
41 def select_files(all_input_files, min_events, max_processed_events_per_file):
42  basf2.B2INFO("Attempting to choose a good subset of files")
43  # Let's iterate, taking a sample of files from the total (no repeats or replacement) until we get enough events
44  total_events = 0
45  chosen_files = []
46  while total_events < min_events:
47  # If the set is empty we must have used all available files. Here we break and continue. But you may want to
48  # raise an Error...
49  if not all_input_files:
50  break
51  # Randomly select a file
52  new_file_choice = choice(all_input_files)
53  # Remove it from the list so it can't be chosen again
54  all_input_files.remove(new_file_choice)
55  # Find the number of events in the file
56  total_events_in_file = events_in_basf2_file(new_file_choice)
57  if not total_events_in_file:
58  # Uh Oh! Zero event file, skip it
59  continue
60  events_contributed = 0
61  if total_events_in_file < max_processed_events_per_file:
62  # The file contains less than the max amount we have set (entrySequences)
63  events_contributed = total_events_in_file
64  else:
65  events_contributed = max_processed_events_per_file
66  chosen_files.append(new_file_choice)
67  total_events += events_contributed
68 
69  basf2.B2INFO(f"Total chosen files = {len(chosen_files)}")
70  basf2.B2INFO(f"Total events in chosen files = {total_events}")
71  if total_events < min_events:
72  raise ValueError(
73  f"There weren't enough files events selected when max_processed_events_per_file={max_processed_events_per_file}")
74  return chosen_files
75 
76 
77 
80 
81 
82 def get_calibrations(input_data, **kwargs):
83  import basf2
84  from prompt.utils import filter_by_max_files_per_run
85  # Gets the input files and IoV objects associated with the files.
86  file_to_iov_mumu = input_data["mumutight_calib"]
87  file_to_iov_hadron = input_data["hadron_calib"]
88  file_to_iov_Bcosmics = input_data["cosmic_calib"]
89 
90  # read expert_config values
91  expert_config = kwargs.get("expert_config")
92  max_files_per_run = expert_config["max_files_per_run"]
93  min_events_per_file = expert_config["min_events_per_file"]
94  max_events_per_calibration = expert_config["max_events_per_calibration"] # for t0, tw calib.
95  max_events_per_calibration_for_xt_sr = expert_config["max_events_per_calibration_for_xt_sr"] # for xt, sr calib.
96  max_events_per_file = expert_config["max_events_per_file"]
97  max_events_per_file_hadron = expert_config["max_events_per_file_hadron"]
98  payload_boundaries = []
99  payload_boundaries.extend([ExpRun(*boundary) for boundary in expert_config["payload_boundaries"]])
100  basf2.B2INFO(f"Payload boundaries from expert_config: {payload_boundaries}")
101 
102  reduced_file_to_iov_mumu = filter_by_max_files_per_run(file_to_iov_mumu, max_files_per_run, min_events_per_file)
103  input_files_mumu = list(reduced_file_to_iov_mumu.keys())
104  basf2.B2INFO(f"Total number of mumutight_calib files actually used as input = {len(input_files_mumu)}")
105  chosen_files_mumu = select_files(input_files_mumu[:], max_events_per_calibration, max_events_per_file)
106  chosen_files_mumu_for_xt_sr = select_files(input_files_mumu[:], max_events_per_calibration_for_xt_sr, max_events_per_file)
107 
108  reduced_file_to_iov_hadron = filter_by_max_files_per_run(file_to_iov_hadron, max_files_per_run, min_events_per_file)
109  input_files_hadron = list(reduced_file_to_iov_hadron.keys())
110  basf2.B2INFO(f"Total number of hadron_calib files actually used as input = {len(input_files_hadron)}")
111  chosen_files_hadron = select_files(input_files_hadron[:], max_events_per_calibration, max_events_per_file_hadron)
112  chosen_files_hadron_for_xt_sr = select_files(input_files_hadron[:],
113  max_events_per_calibration_for_xt_sr, max_events_per_file_hadron)
114 
115  reduced_file_to_iov_Bcosmics = filter_by_max_files_per_run(file_to_iov_Bcosmics, max_files_per_run, min_events_per_file)
116  input_files_Bcosmics = list(reduced_file_to_iov_Bcosmics.keys())
117  basf2.B2INFO(f"Total number of cosmic_calib files actually used as input = {len(input_files_Bcosmics)}")
118  chosen_files_Bcosmics = select_files(input_files_Bcosmics[:], max_events_per_calibration, max_events_per_file)
119  chosen_files_Bcosmics_for_xt_sr = select_files(
120  input_files_Bcosmics[:],
121  max_events_per_calibration_for_xt_sr,
122  max_events_per_file)
123 
124  input_file_dict = {
125  "mumutight_calib": chosen_files_mumu_for_xt_sr,
126  "hadron_calib": chosen_files_hadron_for_xt_sr,
127  "cosmic_calib": chosen_files_Bcosmics_for_xt_sr
128  }
129 
130  chosen_file_dict = {
131  "mumutight_calib": chosen_files_mumu,
132  "hadron_calib": chosen_files_hadron,
133  "cosmic_calib": chosen_files_Bcosmics
134  }
135 
136  # Get the overall IoV we want to cover, including the end values
137  requested_iov = kwargs.get("requested_iov", None)
138 
139  from caf.utils import IoV
140  # The actual IoV we want for any prompt request is open-ended
141  output_iov = IoV(requested_iov.exp_low, requested_iov.run_low, -1, -1)
142 
143  # for SingleIOV stratrgy, it's better to set the granularity to 'all' so that the collector jobs will run faster
144  collector_granularity = 'all'
145  if payload_boundaries:
146  basf2.B2INFO('Found payload_boundaries: set collector granularity to run')
147  collector_granularity = 'run'
148 
149  # t0
150  cal0 = CDCCalibration(name='tz0',
151  algorithms=[tz_algo()],
152  input_file_dict=chosen_file_dict,
153  max_iterations=4,
154  max_events=max_events_per_file,
155  collector_granularity=collector_granularity
156  )
157 
158  # tw
159  cal1 = CDCCalibration(name='tw0',
160  algorithms=[tw_algo()],
161  input_file_dict=chosen_file_dict,
162  max_iterations=2,
163  max_events=max_events_per_file,
164  collector_granularity=collector_granularity,
165  dependencies=[cal0]
166  )
167 
168  cal2 = CDCCalibration(name='tz1',
169  algorithms=[tz_algo()],
170  input_file_dict=chosen_file_dict,
171  max_iterations=4,
172  max_events=max_events_per_file,
173  collector_granularity=collector_granularity,
174  dependencies=[cal1]
175  )
176 
177  # xt
178  cal3 = CDCCalibration(name='xt0',
179  algorithms=[xt_algo()],
180  input_file_dict=input_file_dict,
181  max_iterations=1,
182  collector_granularity=collector_granularity,
183  dependencies=[cal2]
184  )
185 
186  # space resolution
187  cal4 = CDCCalibration(name='sr0',
188  algorithms=[sr_algo()],
189  input_file_dict=input_file_dict,
190  max_iterations=1,
191  collector_granularity=collector_granularity,
192  dependencies=[cal3]
193  )
194  # t0
195  cal5 = CDCCalibration(name='tz2',
196  algorithms=[tz_algo()],
197  input_file_dict=chosen_file_dict,
198  max_iterations=4,
199  max_events=max_events_per_file,
200  collector_granularity=collector_granularity,
201  dependencies=[cal4]
202  )
203 
204  if payload_boundaries:
205  basf2.B2INFO("Found payload_boundaries: calibration strategies set to SequentialBoundaries.")
206  cal0.strategies = strategies.SequentialBoundaries
207  for algorithm in cal0.algorithms:
208  algorithm.params = {"iov_coverage": output_iov, "payload_boundaries": payload_boundaries}
209  for algorithm in cal1.algorithms:
210  algorithm.params = {"iov_coverage": output_iov, "payload_boundaries": payload_boundaries}
211  for algorithm in cal2.algorithms:
212  algorithm.params = {"iov_coverage": output_iov, "payload_boundaries": payload_boundaries}
213  for algorithm in cal3.algorithms:
214  algorithm.params = {"iov_coverage": output_iov, "payload_boundaries": payload_boundaries}
215  for algorithm in cal4.algorithms:
216  algorithm.params = {"iov_coverage": output_iov, "payload_boundaries": payload_boundaries}
217  for algorithm in cal5.algorithms:
218  algorithm.params = {"iov_coverage": output_iov, "payload_boundaries": payload_boundaries}
219  else:
220  # Force the output payload IoV to be correct.
221  # It may be different if you are using another strategy like SequentialRunByRun
222  for algorithm in cal0.algorithms:
223  algorithm.params = {"apply_iov": output_iov}
224  for algorithm in cal1.algorithms:
225  algorithm.params = {"apply_iov": output_iov}
226  for algorithm in cal2.algorithms:
227  algorithm.params = {"apply_iov": output_iov}
228  for algorithm in cal3.algorithms:
229  algorithm.params = {"apply_iov": output_iov}
230  for algorithm in cal4.algorithms:
231  algorithm.params = {"apply_iov": output_iov}
232  for algorithm in cal5.algorithms:
233  algorithm.params = {"apply_iov": output_iov}
234 
235  return [cal0, cal1, cal2, cal3, cal4, cal5]
236 
237 
238 
239 
240 def pre_collector(max_events=None):
241  """
242  Define pre collection (reconstruction in our purpose).
243  Probably, we need only CDC and ECL data.
244  Parameters:
245  max_events [int] : number of events to be processed.
246  All events by Default.
247  Returns:
248  path : path for pre collection
249  """
250  from basf2 import create_path, register_module
251  from softwaretrigger.constants import HLT_INPUT_OBJECTS
252  reco_path = create_path()
253  if max_events is None:
254  root_input = register_module(
255  'RootInput',
256  branchNames=HLT_INPUT_OBJECTS
257  )
258  else:
259  root_input = register_module(
260  'RootInput',
261  branchNames=HLT_INPUT_OBJECTS,
262  entrySequences=[
263  '0:{}'.format(max_events)])
264  reco_path.add_module(root_input)
265 
266  gearbox = register_module('Gearbox')
267  reco_path.add_module(gearbox)
268  reco_path.add_module('Geometry', useDB=True)
269 
270  from rawdata import add_unpackers
271  # unpack raw data
272  add_unpackers(reco_path)
273 
274  from reconstruction import add_reconstruction
275  add_reconstruction(reco_path,
276  add_trigger_calculation=False,
277  trackFitHypotheses=[211, 13],
278  pruneTracks=False)
279 
280  return reco_path
281 
282 
283 def pre_collector_cr(max_events=None):
284  """
285  Define pre collection (reconstruction in our purpose).
286  Probably, we need only CDC and ECL data.
287  Parameters:
288  max_events [int] : number of events to be processed.
289  All events by Default.
290  Returns:
291  path : path for pre collection
292  """
293  from basf2 import create_path, register_module
294  from softwaretrigger.constants import HLT_INPUT_OBJECTS
295  reco_path = create_path()
296  if max_events is None:
297  root_input = register_module(
298  'RootInput',
299  branchNames=HLT_INPUT_OBJECTS
300  )
301  else:
302  root_input = register_module(
303  'RootInput',
304  branchNames=HLT_INPUT_OBJECTS,
305  entrySequences=[
306  '0:{}'.format(max_events)])
307  reco_path.add_module(root_input)
308 
309  gearbox = register_module('Gearbox')
310  reco_path.add_module(gearbox)
311  reco_path.add_module('Geometry', useDB=True)
312 
313  from rawdata import add_unpackers
314  # unpack raw data
315  add_unpackers(reco_path)
316 
317  from reconstruction import add_cosmics_reconstruction
318  add_cosmics_reconstruction(reco_path,
319  components=['CDC', 'ECL'],
320  merge_tracks=False,
321  pruneTracks=False,
322  data_taking_period='normal'
323  )
324  return reco_path
325 
326 
327 def collector(bField=True, is_cosmic=False, granularity='all'):
328  """
329  Create a cdc calibration collector
330  Parameters:
331  bField [bool] : True if B field is on, else False
332  isCosmic [bool] : True if cosmic events,
333  else (collision) False.
334  Returns:
335  collector : collector module
336  """
337  from basf2 import register_module
338  col = register_module('CDCCalibrationCollector',
339  granularity=granularity,
340  calExpectedDriftTime=True,
341  eventT0Extraction=True,
342  bField=bField,
343  isCosmic=is_cosmic
344  )
345  return col
346 
347 
348 def tz_algo():
349  """
350  Create a T0 calibration algorithm.
351  Returns:
352  algo : T0 algorithm
353  """
354  from ROOT import Belle2
356  algo.storeHisto(True)
357  algo.setMaxMeanDt(0.5)
358  algo.setMaxRMSDt(0.1)
359  algo.setMinimumNDF(20)
360  return algo
361 
362 
363 def tw_algo():
364  """
365  Create a time walk calibration algorithm.
366  Returns:
367  algo : TW algorithm
368  """
369  from ROOT import Belle2
371  algo.setStoreHisto(True)
372  algo.setMode(1)
373  return algo
374 
375 
376 def xt_algo():
377  """
378  Create a XT calibration algorithm.
379  Parameters:
380  prefix : prefixed name for algorithm,
381  which should be consistent with one of collector..
382  Returns:
383  algo : XT algorithm
384  """
385  from ROOT import Belle2
387  algo.setStoreHisto(True)
388  algo.setLRSeparate(True)
389  algo.setThreshold(0.55)
390  return algo
391 
392 
393 def sr_algo():
394  """
395  Create a Spacial resolution calibration algorithm.
396  Parameters:
397  prefix : prefixed name for algorithm,
398  which should be consistent with one of collector..
399  Returns:
400  algo : Spacial algorithm
401  """
402  from ROOT import Belle2
404  algo.setStoreHisto(True)
405  algo.setThreshold(0.4)
406  return algo
407 
408 
410  '''
411  CDCCalibration is a specialized calibration class for cdc.
412  Since collector is same in all elements, no need to specify it.
413  '''
414 
415  def __init__(self,
416  name,
417  algorithms,
418  input_file_dict,
419  max_iterations=5,
420  dependencies=None,
421  max_events=5000,
422  collector_granularity='All'):
423  for algo in algorithms:
424  algo.setHistFileName(name)
425 
426  super().__init__(name=name,
427  algorithms=algorithms
428  )
429 
430  from caf.framework import Collection
431 
432  for skim_type, file_list in input_file_dict.items():
433  if skim_type == "Bcosmics":
434  collection = Collection(collector=collector(granularity=collector_granularity),
435  input_files=file_list,
436  pre_collector_path=pre_collector_cr(max_events=max_events),
437  )
438  else:
439  collection = Collection(collector=collector(granularity=collector_granularity),
440  input_files=file_list,
441  pre_collector_path=pre_collector(max_events=max_events),
442  )
443  self.add_collection(name=skim_type, collection=collection)
444 
445  self.max_iterations = max_iterations
446 
447  if dependencies is not None:
448  for dep in dependencies:
449  self.depends_on(dep)
prompt.utils
Definition: utils.py:1
Belle2::CDC::XTCalibrationAlgorithm
Class to perform xt calibration for drift chamber.
Definition: XTCalibrationAlgorithm.h:61
caf_cdc.CDCCalibration.max_iterations
max_iterations
Definition: caf_cdc.py:438
Belle2::CDC::T0CalibrationAlgorithm
Class for T0 Correction .
Definition: T0CalibrationAlgorithm.h:34
softwaretrigger.constants
Definition: constants.py:1
Belle2::CDC::TimeWalkCalibrationAlgorithm
Class for Time walk calibration.
Definition: TimeWalkCalibrationAlgorithm.h:37
strategies.SequentialBoundaries
Definition: strategies.py:647
caf_cdc.CDCCalibration
Definition: caf_cdc.py:409
collector
Definition: collector.py:1
Collection
Definition: Collection.py:1
Calibration
Definition: Calibration.py:1
Belle2::CDC::SpaceResolutionCalibrationAlgorithm
Class for Space resolution calibration.
Definition: SpaceResolutionCalibrationAlgorithm.h:38