8 from caf.utils
import ExpRun, IoV
9 from prompt
import CalibrationSettings, input_data_filters
20 from prompt.calibrations.vxdcdc_alignment
import settings
as vxdcdc_alignment
30 settings = CalibrationSettings(name=
"KLM alignmnent",
31 expert_username=
"oskin",
33 input_data_formats=[
"raw"],
34 input_data_names=[
"raw_physics",
"raw_cosmic"],
36 'raw_physics': [input_data_filters[
'Run Type'][
'physics'],
37 input_data_filters[
'Data Tag'][
'mumutight_calib'],
38 input_data_filters[
'Data Quality Tag'][
'Good Or Recoverable']],
39 'raw_cosmic': [input_data_filters[
'Run Type'][
'physics'],
40 input_data_filters[
'Data Tag'][
'cosmic_calib'],
41 input_data_filters[
'Data Quality Tag'][
'Good Or Recoverable']]
43 depends_on=[vxdcdc_alignment],
45 "required_events": 5000000,
46 "required_events_experiment": 500000,
47 "events_per_file": 1000,
48 "millepede_entries": 1000000,
49 "millepede_entries_exp7": 500000
56 def select_input_files(file_to_iov_physics, file_to_iov_cosmic,
57 reduced_file_to_iov_physics, reduced_file_to_iov_cosmic,
58 required_events, required_events_experiment,
62 files_to_iov_physics (dict): Dictionary {run : IOV} for physics data.
63 files_to_iov_cosmic (dict): Dictionary {run : IOV} for cosmic data.
64 reduced_file_to_iov_physics (dict): Selected physics data.
65 reduced_file_to_iov_cosmic (dict): Selected cosmic data.
66 required_events (int): Required total number of events.
67 required_events_experiment (int): Required number of events
69 events_per_file (int): Number of events per file. If non-positive, then
70 the number is not limited.
72 experiment_numbers = set()
73 run_to_files_physics = collections.defaultdict(list)
74 for input_file, file_iov
in file_to_iov_physics.items():
75 run = ExpRun(exp=file_iov.exp_low, run=file_iov.run_low)
76 run_to_files_physics[run].append(input_file)
77 experiment_numbers.add(file_iov.exp_low)
78 run_to_files_cosmic = collections.defaultdict(list)
79 for input_file, file_iov
in file_to_iov_cosmic.items():
80 run = ExpRun(exp=file_iov.exp_low, run=file_iov.run_low)
81 run_to_files_cosmic[run].append(input_file)
82 experiment_numbers.add(file_iov.exp_low)
84 for files
in run_to_files_physics.values():
85 files_per_run = len(files)
86 if files_per_run > max_files_per_run:
87 max_files_per_run = files_per_run
88 for files
in run_to_files_cosmic.values():
89 files_per_run = len(files)
90 if files_per_run > max_files_per_run:
91 max_files_per_run = files_per_run
94 collected_events_experiment = collections.defaultdict(int)
95 select_events_experiment = collections.defaultdict(bool)
96 for exp
in experiment_numbers:
97 collected_events_experiment[exp] = 0
98 select_events_experiment[exp] =
True
99 while files_per_run < max_files_per_run:
100 for run, files
in run_to_files_physics.items():
101 if not select_events_experiment[run.exp]:
103 if files_per_run >= len(files):
105 input_file = files[files_per_run]
106 events = events_in_basf2_file(input_file)
110 if events_per_file > 0
and events > events_per_file:
111 events = events_per_file
112 collected_events = collected_events + events
113 collected_events_experiment[run.exp] = \
114 collected_events_experiment[run.exp] + events
115 reduced_file_to_iov_physics[input_file] = IoV(*run, *run)
116 basf2.B2INFO(f
'File {input_file} with {events} events is selected.')
117 for run, files
in run_to_files_cosmic.items():
118 if not select_events_experiment[run.exp]:
120 if files_per_run >= len(files):
122 input_file = files[files_per_run]
123 events = events_in_basf2_file(input_file)
127 if events_per_file > 0
and events > events_per_file:
128 events = events_per_file
129 collected_events = collected_events + events
130 collected_events_experiment[run.exp] = \
131 collected_events_experiment[run.exp] + events
132 reduced_file_to_iov_cosmic[input_file] = IoV(*run, *run)
133 basf2.B2INFO(f
'File {input_file} with {events} events is selected.')
134 files_per_run = files_per_run + 1
135 if collected_events >= required_events:
136 all_experiments_selected =
True
137 for exp
in experiment_numbers:
138 if collected_events_experiment[exp] >= \
139 required_events_experiment:
140 select_events_experiment[exp] =
False
142 all_experiments_selected =
False
143 if all_experiments_selected:
145 basf2.B2INFO(f
'The total number of collected events is {collected_events}.')
158 def get_calibrations(input_data, **kwargs):
161 input_data (dict): Should contain every name from the 'input_data_names' variable as a key.
162 Each value is a dictionary with {"/path/to/file_e1_r5.root": IoV(1,5,1,5), ...}. Useful for
163 assigning to calibration.files_to_iov
165 **kwargs: Configuration options to be sent in. Since this may change we use kwargs as a way to help prevent
166 backwards compatibility problems. But you could use the correct arguments in b2caf-prompt-run for this
167 release explicitly if you want to.
169 Currently only kwargs["requested_iov"] is used. This is the output IoV range that your payloads should
170 correspond to. Generally your highest ExpRun payload should be open ended e.g. IoV(3,4,-1,-1)
173 list(caf.framework.Calibration): All of the calibration objects we want to assign to the CAF process
178 expert_config = kwargs.get(
"expert_config")
182 file_to_iov_physics = input_data[
"raw_physics"]
183 file_to_iov_cosmic = input_data[
"raw_cosmic"]
186 reduced_file_to_iov_physics = collections.OrderedDict()
187 reduced_file_to_iov_cosmic = collections.OrderedDict()
188 select_input_files(file_to_iov_physics, file_to_iov_cosmic,
189 reduced_file_to_iov_physics, reduced_file_to_iov_cosmic,
190 expert_config[
"required_events"],
191 expert_config[
"required_events_experiment"],
192 expert_config[
"events_per_file"])
194 input_files_physics = sorted(list(reduced_file_to_iov_physics.keys()))
195 basf2.B2INFO(f
"Total number of 'physics' files actually used as input = {len(input_files_physics)}")
197 input_files_cosmic = sorted(list(reduced_file_to_iov_cosmic.keys()))
198 basf2.B2INFO(f
"Total number of 'cosmic' files actually used as input = {len(input_files_cosmic)}")
200 if not input_files_physics
and not input_files_cosmic:
201 raise Exception(
"No valid input files found!")
205 requested_iov = kwargs[
"requested_iov"]
207 from caf.utils
import IoV
209 output_iov = IoV(requested_iov.exp_low, requested_iov.run_low, -1, -1)
214 from ROOT
import Belle2
215 from ROOT.Belle2
import KLMChannelIndex, KLMElementNumbers
216 from alignment
import MillepedeCalibration
219 millepede = MillepedeCalibration([
'BKLMAlignment',
'EKLMAlignment',
'EKLMSegmentAlignment'])
222 index = KLMChannelIndex(KLMChannelIndex.c_IndexLevelLayer)
223 index2 = KLMChannelIndex(KLMChannelIndex.c_IndexLevelLayer)
224 while (index != index2.end()):
225 module = index.getKLMModuleNumber()
226 if (index.getSubdetector() == KLMElementNumbers.c_BKLM):
227 for ipar
in [1, 2, 3, 4, 5, 6]:
229 if ipar
in [1, 2, 6]:
234 for ipar
in [1, 2, 6]:
242 index.setIndexLevel(KLMChannelIndex.c_IndexLevelStrip)
243 index2.setIndexLevel(KLMChannelIndex.c_IndexLevelStrip)
244 index = index2.beginEKLM()
245 index.useEKLMSegments()
246 while (index != index2.endEKLM()):
247 segment = index.getEKLMSegmentNumber()
249 millepede.fixGlobalParam(
254 cal_klm = millepede.create(
'KLMAlignment', [])
256 millepede.algo.ignoreUndeterminedParams(
True)
257 millepede.algo.invertSign()
262 from caf.framework
import Collection
267 from klm_calibration_utils
import get_alignment_pre_collector_path_physics, get_alignment_pre_collector_path_cosmic
270 if expert_config[
"events_per_file"] > 0:
271 last_entry = expert_config[
"events_per_file"]
272 entries = f
'0:{last_entry}'
274 if input_files_physics:
275 coll_physics = get_collector(
"raw_physics")
276 rec_path_physics = get_alignment_pre_collector_path_physics(entry_sequence=entries)
278 collection_physics =
Collection(collector=coll_physics,
279 input_files=input_files_physics,
280 pre_collector_path=rec_path_physics)
282 cal_klm.add_collection(name=
"physics", collection=collection_physics)
284 if input_files_cosmic:
285 coll_cosmic = get_collector(
"raw_cosmic")
286 rec_path_cosmic = get_alignment_pre_collector_path_cosmic(entry_sequence=entries)
288 collection_cosmic =
Collection(collector=coll_cosmic,
289 input_files=input_files_cosmic,
290 pre_collector_path=rec_path_cosmic)
292 cal_klm.add_collection(name=
"cosmic", collection=collection_cosmic)
297 from klm_alignment
import KLMAlignment
299 cal_klm.algorithms = [millepede.algo]
303 for algorithm
in cal_klm.algorithms:
304 fix_mille_paths_for_algo(algorithm)
306 for algorithm
in cal_klm.algorithms:
307 algorithm.strategy = KLMAlignment
309 "has_experiment_settings":
True,
310 "iov_coverage": output_iov,
311 "millepede_entries": expert_config[
"millepede_entries"],
312 "millepede_entries_exp7": expert_config[
"millepede_entries_exp7"]
321 def get_collector(input_data_name):
323 Return the correct MillepedeCollector module setup for each data type.
324 Placed here so it can be different for prompt compared to standard.
327 if input_data_name ==
"raw_physics":
328 return basf2.register_module(
329 'MillepedeCollector',
330 components=[
'BKLMAlignment',
'EKLMAlignment',
331 'EKLMSegmentAlignment'],
334 elif input_data_name ==
"raw_cosmic":
335 return basf2.register_module(
336 'MillepedeCollector',
337 components=[
'BKLMAlignment',
'EKLMAlignment',
338 'EKLMSegmentAlignment'],
342 raise Exception(
"Unknown input data name used when setting up collector")