10Calibration of KLM alignment. It provides calibration constants for the BKLMAlignment
11and EKLMAlignment database objects.
17from caf.utils
import ExpRun, IoV
18from prompt
import CalibrationSettings, INPUT_DATA_FILTERS
29from prompt.calibrations.vxdcdc_alignment
import settings
as vxdcdc_alignment
39settings = CalibrationSettings(name=
"KLM alignmnent",
40 expert_username=
"oskin",
42 input_data_formats=[
"raw"],
43 input_data_names=[
"raw_physics",
"raw_cosmic"],
45 'raw_physics': [INPUT_DATA_FILTERS[
'Run Type'][
'physics'],
46 INPUT_DATA_FILTERS[
'Data Tag'][
'mumu_tight_or_highm_calib'],
47 INPUT_DATA_FILTERS[
'Data Quality Tag'][
'Good Or Recoverable']],
48 'raw_cosmic': [INPUT_DATA_FILTERS[
'Run Type'][
'physics'],
49 INPUT_DATA_FILTERS[
'Data Tag'][
'cosmic_calib'],
50 INPUT_DATA_FILTERS[
'Data Quality Tag'][
'Good Or Recoverable']]
52 depends_on=[vxdcdc_alignment],
54 "required_events": 5000000,
55 "required_events_experiment": 500000,
56 "events_per_file": 1000,
57 "millepede_entries": 1000000,
58 "millepede_entries_exp7": 500000
65def select_input_files(file_to_iov_physics, file_to_iov_cosmic,
66 reduced_file_to_iov_physics, reduced_file_to_iov_cosmic,
67 required_events, required_events_experiment,
71 files_to_iov_physics (dict): Dictionary {run : IOV} for physics data.
72 files_to_iov_cosmic (dict): Dictionary {run : IOV}
for cosmic data.
73 reduced_file_to_iov_physics (dict): Selected physics data.
74 reduced_file_to_iov_cosmic (dict): Selected cosmic data.
75 required_events (int): Required total number of events.
76 required_events_experiment (int): Required number of events
78 events_per_file (int): Number of events per file. If non-positive, then
79 the number
is not limited.
81 experiment_numbers = set()
82 run_to_files_physics = collections.defaultdict(list)
83 for input_file, file_iov
in file_to_iov_physics.items():
84 run = ExpRun(exp=file_iov.exp_low, run=file_iov.run_low)
85 run_to_files_physics[run].append(input_file)
86 experiment_numbers.add(file_iov.exp_low)
87 run_to_files_cosmic = collections.defaultdict(list)
88 for input_file, file_iov
in file_to_iov_cosmic.items():
89 run = ExpRun(exp=file_iov.exp_low, run=file_iov.run_low)
90 run_to_files_cosmic[run].append(input_file)
91 experiment_numbers.add(file_iov.exp_low)
93 for files
in run_to_files_physics.values():
94 files_per_run = len(files)
95 if files_per_run > max_files_per_run:
96 max_files_per_run = files_per_run
97 for files
in run_to_files_cosmic.values():
98 files_per_run = len(files)
99 if files_per_run > max_files_per_run:
100 max_files_per_run = files_per_run
103 collected_events_experiment = collections.defaultdict(int)
104 select_events_experiment = collections.defaultdict(bool)
105 for exp
in experiment_numbers:
106 collected_events_experiment[exp] = 0
107 select_events_experiment[exp] =
True
108 while files_per_run < max_files_per_run:
109 for run, files
in run_to_files_physics.items():
110 if not select_events_experiment[run.exp]:
112 if files_per_run >= len(files):
114 input_file = files[files_per_run]
115 events = events_in_basf2_file(input_file)
119 if events_per_file > 0
and events > events_per_file:
120 events = events_per_file
121 collected_events = collected_events + events
122 collected_events_experiment[run.exp] = \
123 collected_events_experiment[run.exp] + events
124 reduced_file_to_iov_physics[input_file] = IoV(*run, *run)
125 basf2.B2INFO(f
'File {input_file} with {events} events is selected.')
126 for run, files
in run_to_files_cosmic.items():
127 if not select_events_experiment[run.exp]:
129 if files_per_run >= len(files):
131 input_file = files[files_per_run]
132 events = events_in_basf2_file(input_file)
136 if events_per_file > 0
and events > events_per_file:
137 events = events_per_file
138 collected_events = collected_events + events
139 collected_events_experiment[run.exp] = \
140 collected_events_experiment[run.exp] + events
141 reduced_file_to_iov_cosmic[input_file] = IoV(*run, *run)
142 basf2.B2INFO(f
'File {input_file} with {events} events is selected.')
143 files_per_run = files_per_run + 1
144 if collected_events >= required_events:
145 all_experiments_selected =
True
146 for exp
in experiment_numbers:
147 if collected_events_experiment[exp] >= \
148 required_events_experiment:
149 select_events_experiment[exp] =
False
151 all_experiments_selected =
False
152 if all_experiments_selected:
154 basf2.B2INFO(f
'The total number of collected events is {collected_events}.')
167def get_calibrations(input_data, **kwargs):
170 input_data (dict): Should contain every name from the
'input_data_names' variable
as a key.
171 Each value
is a dictionary
with {
"/path/to/file_e1_r5.root": IoV(1,5,1,5), ...}. Useful
for
172 assigning to calibration.files_to_iov
174 **kwargs: Configuration options to be sent
in. Since this may change we use kwargs
as a way to help prevent
175 backwards compatibility problems. But you could use the correct arguments
in b2caf-prompt-run
for this
176 release explicitly
if you want to.
178 Currently only kwargs[
"requested_iov"]
is used. This
is the output IoV range that your payloads should
179 correspond to. Generally your highest ExpRun payload should be open ended e.g. IoV(3,4,-1,-1)
182 list(caf.framework.Calibration): All of the calibration objects we want to assign to the CAF process
187 expert_config = kwargs.get(
"expert_config")
191 file_to_iov_physics = input_data[
"raw_physics"]
192 file_to_iov_cosmic = input_data[
"raw_cosmic"]
195 reduced_file_to_iov_physics = collections.OrderedDict()
196 reduced_file_to_iov_cosmic = collections.OrderedDict()
197 select_input_files(file_to_iov_physics, file_to_iov_cosmic,
198 reduced_file_to_iov_physics, reduced_file_to_iov_cosmic,
199 expert_config[
"required_events"],
200 expert_config[
"required_events_experiment"],
201 expert_config[
"events_per_file"])
203 input_files_physics = sorted(list(reduced_file_to_iov_physics.keys()))
204 basf2.B2INFO(f
"Total number of 'physics' files actually used as input = {len(input_files_physics)}")
206 input_files_cosmic = sorted(list(reduced_file_to_iov_cosmic.keys()))
207 basf2.B2INFO(f
"Total number of 'cosmic' files actually used as input = {len(input_files_cosmic)}")
209 if not input_files_physics
and not input_files_cosmic:
210 raise Exception(
"No valid input files found!")
214 requested_iov = kwargs[
"requested_iov"]
216 from caf.utils
import IoV
218 output_iov = IoV(requested_iov.exp_low, requested_iov.run_low, -1, -1)
223 from ROOT
import Belle2
224 from ROOT.Belle2
import KLMChannelIndex, KLMElementNumbers
225 from alignment
import MillepedeCalibration
228 millepede = MillepedeCalibration([
'BKLMAlignment',
'EKLMAlignment',
'EKLMSegmentAlignment'])
231 index = KLMChannelIndex(KLMChannelIndex.c_IndexLevelLayer)
232 index2 = KLMChannelIndex(KLMChannelIndex.c_IndexLevelLayer)
233 while (index != index2.end()):
234 module = index.getKLMModuleNumber()
235 if (index.getSubdetector() == KLMElementNumbers.c_BKLM):
236 for ipar
in [1, 2, 3, 4, 5, 6]:
238 if ipar
in [1, 2, 6]:
243 for ipar
in [1, 2, 6]:
251 index.setIndexLevel(KLMChannelIndex.c_IndexLevelStrip)
252 index2.setIndexLevel(KLMChannelIndex.c_IndexLevelStrip)
253 index = index2.beginEKLM()
254 index.useEKLMSegments()
255 while (index != index2.endEKLM()):
256 segment = index.getEKLMSegmentNumber()
258 millepede.fixGlobalParam(
263 cal_klm = millepede.create(
'KLMAlignment', [])
265 millepede.algo.ignoreUndeterminedParams(
True)
266 millepede.algo.invertSign()
271 from caf.framework
import Collection
276 from klm_calibration_utils
import get_alignment_pre_collector_path_physics, get_alignment_pre_collector_path_cosmic
279 if expert_config[
"events_per_file"] > 0:
280 last_entry = expert_config[
"events_per_file"]
281 entries = f
'0:{last_entry}'
283 if input_files_physics:
284 coll_physics = get_collector(
"raw_physics")
285 rec_path_physics = get_alignment_pre_collector_path_physics(entry_sequence=entries)
287 tmp = basf2.create_path()
288 for m
in rec_path_physics.modules():
289 if m.name()
not in [
"CDCDedxPID",
"TOPBunchFinder",
"VXDDedxPID"]:
291 elif m.name() ==
"CDCDedxPID":
292 basf2.B2INFO(
'removed CDCDedxPID')
293 elif m.name() ==
"TOPBunchFinder":
294 basf2.B2INFO(
'removed TOPBunchFinder')
295 rec_path_physics = tmp
297 collection_physics =
Collection(collector=coll_physics,
298 input_files=input_files_physics,
299 pre_collector_path=rec_path_physics)
301 cal_klm.add_collection(name=
"physics", collection=collection_physics)
303 if input_files_cosmic:
304 coll_cosmic = get_collector(
"raw_cosmic")
305 rec_path_cosmic = get_alignment_pre_collector_path_cosmic(entry_sequence=entries)
307 tmp = basf2.create_path()
308 for m
in rec_path_cosmic.modules():
309 if m.name()
not in [
"CDCDedxPID",
"TOPBunchFinder",
"VXDDedxPID"]:
311 elif m.name() ==
"CDCDedxPID":
312 basf2.B2INFO(
'removed CDCDedxPID')
313 elif m.name() ==
"TOPBunchFinder":
314 basf2.B2INFO(
'removed TOPBunchFinder')
315 rec_path_cosmic = tmp
317 collection_cosmic =
Collection(collector=coll_cosmic,
318 input_files=input_files_cosmic,
319 pre_collector_path=rec_path_cosmic)
321 cal_klm.add_collection(name=
"cosmic", collection=collection_cosmic)
326 from klm_alignment
import KLMAlignment
328 cal_klm.algorithms = [millepede.algo]
332 for algorithm
in cal_klm.algorithms:
333 fix_mille_paths_for_algo(algorithm)
335 for algorithm
in cal_klm.algorithms:
336 algorithm.strategy = KLMAlignment
338 "has_experiment_settings":
True,
339 "iov_coverage": output_iov,
340 "millepede_entries": expert_config[
"millepede_entries"],
341 "millepede_entries_exp7": expert_config[
"millepede_entries_exp7"]
350def get_collector(input_data_name):
352 Return the correct MillepedeCollector module setup for each data type.
353 Placed here so it can be different
for prompt compared to standard.
356 if input_data_name ==
"raw_physics":
357 return basf2.register_module(
358 'MillepedeCollector',
359 components=[
'BKLMAlignment',
'EKLMAlignment',
360 'EKLMSegmentAlignment'],
363 elif input_data_name ==
"raw_cosmic":
364 return basf2.register_module(
365 'MillepedeCollector',
366 components=[
'BKLMAlignment',
'EKLMAlignment',
367 'EKLMSegmentAlignment'],
371 raise Exception(
"Unknown input data name used when setting up collector")
static unsigned short getGlobalUniqueID()
Get global unique identifier.
static unsigned short getGlobalUniqueID()
Get global unique identifier.