Belle II Software  release-06-01-15
caf_klm_channel_status.py
1 # -*- coding: utf-8 -*-
2 
3 
10 
11 """
12 Calibration of KLM channel status. It provides calibration constants for the KLMChannelStatus
13 database object.
14 """
15 
16 import collections
17 
18 import basf2
19 from caf.utils import ExpRun, IoV
20 from prompt import CalibrationSettings, INPUT_DATA_FILTERS
21 from prompt.utils import events_in_basf2_file
22 
23 
30 
31 
32 settings = CalibrationSettings(
33  name='KLM channel status',
34  expert_username='zhai',
35  description=__doc__,
36  input_data_formats=['raw'],
37  input_data_names=['raw_beam', 'raw_cosmic', 'raw_physics'],
38  input_data_filters={
39  'raw_beam': [INPUT_DATA_FILTERS['Run Type']['beam'],
40  INPUT_DATA_FILTERS['Data Quality Tag']['Good Or Recoverable']],
41  'raw_cosmic': [INPUT_DATA_FILTERS['Run Type']['cosmic'],
42  INPUT_DATA_FILTERS['Data Quality Tag']['Good Or Recoverable']],
43  'raw_physics': [INPUT_DATA_FILTERS['Run Type']['physics'],
44  f"NOT {INPUT_DATA_FILTERS['Data Tag']['random_calib']}",
45  INPUT_DATA_FILTERS['Data Tag']['bhabha_all_calib'],
46  INPUT_DATA_FILTERS['Data Tag']['gamma_gamma_calib'],
47  INPUT_DATA_FILTERS['Data Tag']['hadron_calib'],
48  INPUT_DATA_FILTERS['Data Tag']['mumu_tight_or_highm_calib'],
49  INPUT_DATA_FILTERS['Data Tag']['radmumu_calib'],
50  INPUT_DATA_FILTERS['Data Quality Tag']['Good Or Recoverable']]
51  },
52  depends_on=[])
53 
54 
55 
56 
57 def select_input_files(file_to_iov):
58  """
59  Parameters:
60  files_to_iov (dict): Dictionary {run : IOV}.
61  reduced_file_to_iov (dict): Selected data.
62  """
63  run_to_files = collections.defaultdict(list)
64  for input_file, file_iov in file_to_iov.items():
65  run = ExpRun(exp=file_iov.exp_low, run=file_iov.run_low)
66  # Reject files without events.
67  if events_in_basf2_file(input_file) > 0:
68  run_to_files[run].append(input_file)
69  reduced_file_to_iov = collections.OrderedDict()
70  for run, files in run_to_files.items():
71  for input_file in files:
72  reduced_file_to_iov[input_file] = IoV(*run, *run)
73  return reduced_file_to_iov
74 
75 
84 
85 
86 def get_calibrations(input_data, **kwargs):
87  """
88  Parameters:
89  input_data (dict): Should contain every name from the 'input_data_names' variable as a key.
90  Each value is a dictionary with {"/path/to/file_e1_r5.root": IoV(1,5,1,5), ...}. Useful for
91  assigning to calibration.files_to_iov
92 
93  **kwargs: Configuration options to be sent in. Since this may change we use kwargs as a way to help prevent
94  backwards compatibility problems. But you could use the correct arguments in b2caf-prompt-run for this
95  release explicitly if you want to.
96 
97  Currently only kwargs["requested_iov"] is used. This is the output IoV range that your payloads should
98  correspond to. Generally your highest ExpRun payload should be open ended e.g. IoV(3,4,-1,-1)
99 
100  Returns:
101  list(caf.framework.Calibration): All of the calibration objects we want to assign to the CAF process
102  """
103  # Set up config options
104 
105  # In this script we want to use one sources of input data.
106  # Get the input files from the input_data variable
107  file_to_iov_raw_beam = input_data['raw_beam']
108  file_to_iov_raw_cosmic = input_data['raw_cosmic']
109  file_to_iov_raw_physics = input_data['raw_physics']
110 
111  # Select input files (all data are necessary, only removes empty files).
112  reduced_file_to_iov_raw_beam = select_input_files(file_to_iov_raw_beam)
113  reduced_file_to_iov_raw_cosmic = select_input_files(file_to_iov_raw_cosmic)
114  reduced_file_to_iov_raw_physics = select_input_files(file_to_iov_raw_physics)
115 
116  # Merge all input data.
117  input_files_raw = list(reduced_file_to_iov_raw_beam.keys())
118  input_files_raw.extend(list(reduced_file_to_iov_raw_cosmic.keys()))
119  input_files_raw.extend(list(reduced_file_to_iov_raw_physics.keys()))
120  input_files_raw.sort()
121  basf2.B2INFO(f'Total number of raw-data files used as input = {len(input_files_raw)}')
122 
123  if not input_files_raw:
124  raise Exception('No valid input files found!')
125 
126  # Get the overall IoV we our process should cover. Includes the end values that we may want to ignore since our output
127  # IoV should be open ended. We could also use this as part of the input data selection in some way.
128  requested_iov = kwargs['requested_iov']
129 
130  from caf.utils import IoV
131  # The actual value our output IoV payload should have. Notice that we've set it open ended.
132  output_iov = IoV(requested_iov.exp_low, requested_iov.run_low, -1, -1)
133 
134 
136 
137  from ROOT.Belle2 import KLMChannelStatusAlgorithm
138 
139  alg = KLMChannelStatusAlgorithm()
140 
141 
143 
144  from caf.framework import Calibration, Collection
145 
146  cal_klm = Calibration('KLMChannelStatus')
147 
148 
150 
151  from klm_calibration_utils import get_channel_status_pre_collector_path
152 
153  if input_files_raw:
154  coll_raw = get_collector('raw')
155  rec_path_raw = get_channel_status_pre_collector_path()
156 
157  collection_raw = Collection(collector=coll_raw,
158  input_files=input_files_raw,
159  pre_collector_path=rec_path_raw)
160 
161  cal_klm.add_collection(name='raw', collection=collection_raw)
162 
163 
165 
166  cal_klm.algorithms = [alg]
167 
168  from klm_channel_status import KLMChannelStatus
169 
170  for algorithm in cal_klm.algorithms:
171  algorithm.strategy = KLMChannelStatus
172  algorithm.params = {'iov_coverage': output_iov}
173 
174  # You must return all calibrations you want to run in the prompt process, even if it's only one
175  return [cal_klm]
176 
177 
178 
179 
180 def get_collector(input_data_name):
181  """
182  Return the correct KLMChannelStatusCollector module setup for each data type.
183  Placed here so it can be different for prompt compared to standard.
184  """
185 
186  if input_data_name == 'raw':
187  return basf2.register_module('KLMChannelStatusCollector')
188  raise Exception("Unknown input data name used when setting up collector")