9 """Full CDC tracking calibration."""
10 from prompt
import CalibrationSettings, INPUT_DATA_FILTERS
13 from ROOT
import Belle2
14 from random
import choice
15 from caf.framework
import Calibration
16 from caf
import strategies
20 settings = CalibrationSettings(name=
"CDC Tracking",
21 expert_username=
"eberthol",
23 input_data_formats=[
"raw"],
24 input_data_names=[
"mumu_tight_or_highm_calib",
"hadron_calib",
"cosmic_calib"],
25 input_data_filters={
"mumu_tight_or_highm_calib":
26 [INPUT_DATA_FILTERS[
"Data Tag"][
"mumu_tight_or_highm_calib"],
27 INPUT_DATA_FILTERS[
"Data Quality Tag"][
"Good"],
28 INPUT_DATA_FILTERS[
"Magnet"][
"On"]],
30 [INPUT_DATA_FILTERS[
"Data Tag"][
"hadron_calib"],
31 INPUT_DATA_FILTERS[
"Data Quality Tag"][
"Good"],
32 INPUT_DATA_FILTERS[
"Magnet"][
"On"]],
34 [INPUT_DATA_FILTERS[
"Data Tag"][
"cosmic_calib"],
35 INPUT_DATA_FILTERS[
"Data Quality Tag"][
"Good"],
36 INPUT_DATA_FILTERS[
"Magnet"][
"On"]]},
39 "min_events_per_file": 500,
40 "max_events_per_file": 20000,
41 "max_events_per_file_hadron_for_tz_tw": 5000,
42 "max_events_per_file_hadron_for_xt_sr": 12000,
43 "min_events_for_tz_tw_calibration": 500000,
44 "max_events_for_tz_tw_calibration": 1000000,
45 "min_events_for_xt_sr_calibration": 1000000,
46 "max_events_for_xt_sr_calibration": 10000000,
47 "fractions_for_each_type": [0.5, 1, 0.5],
48 "max_job_for_each_type": [400, 700, 400],
49 "calib_mode":
"quick",
50 "calibration_procedure": {
"tz0": 1,
"xt0": 0,
"sr_tz0": 0,
"tz2": 0},
51 "payload_boundaries": [],
52 "backend_args": {
"request_memory":
"4 GB"}
56 def select_files(all_input_files, min_events, max_events, max_processed_events_per_file, max_job=800, min_events_per_file=500):
57 basf2.B2INFO(f
"Minimum number of events: {min_events}")
58 basf2.B2INFO(f
"Maximum number of events: {max_events}")
59 basf2.B2INFO(f
"Conditions: ({min_events_per_file} < #Event/file < {max_processed_events_per_file}) and max_job = {max_job}")
64 while total_events < max_events
and njob < max_job:
67 if not all_input_files:
70 new_file_choice = choice(all_input_files)
72 all_input_files.remove(new_file_choice)
74 total_events_in_file = events_in_basf2_file(new_file_choice)
75 if not total_events_in_file
or total_events_in_file < min_events_per_file:
78 events_contributed = 0
79 if total_events_in_file < max_processed_events_per_file:
81 events_contributed = total_events_in_file
83 events_contributed = max_processed_events_per_file
84 chosen_files.append(new_file_choice)
85 total_events += events_contributed
88 basf2.B2INFO(f
"Total chosen files = {len(chosen_files)}")
89 basf2.B2INFO(f
"Total events in chosen files = {total_events}")
90 if total_events < min_events:
92 f
"There is not enough required events with setup max_processed_events_per_file = {max_processed_events_per_file}")
101 def get_calibrations(input_data, **kwargs):
107 expert_config = kwargs.get(
"expert_config")
108 calib_mode = expert_config[
"calib_mode"]
110 min_events_per_file = expert_config[
"min_events_per_file"]
111 max_events_per_file = expert_config[
"max_events_per_file"]
113 min_events_for_tz_tw = expert_config[
"min_events_for_tz_tw_calibration"]
114 max_events_for_tz_tw = expert_config[
"max_events_for_tz_tw_calibration"]
115 max_events_per_file_hadron_for_tz_tw = expert_config[
"max_events_per_file_hadron_for_tz_tw"]
117 min_events_for_xt_sr = expert_config[
"min_events_for_xt_sr_calibration"]
118 max_events_for_xt_sr = expert_config[
"max_events_for_xt_sr_calibration"]
119 max_events_per_file_hadron_for_xt_sr = expert_config[
"max_events_per_file_hadron_for_xt_sr"]
121 Max_events_per_file_for_tz_tw = [max_events_per_file, max_events_per_file_hadron_for_tz_tw, max_events_per_file]
122 Max_events_per_file_for_xt_sr = [max_events_per_file, max_events_per_file_hadron_for_xt_sr, max_events_per_file]
124 fraction_of_event_for_types = expert_config[
"fractions_for_each_type"]
125 max_jobs = expert_config[
"max_job_for_each_type"]
126 basf2.B2INFO(f
"Number of job for each type are limitted at [di-muon, hadron, cosmic]: {max_jobs}")
127 basf2.B2INFO(f
"Fraction for [di-muon, hadron, cosmic]: {fraction_of_event_for_types}")
128 if len(fraction_of_event_for_types) != 3:
129 basf2.B2FATAL(
"fraction of event must be an array with the size of 3, with order [mumu, hadron, cosmic]")
131 payload_boundaries = []
132 payload_boundaries.extend([ExpRun(*boundary)
for boundary
in expert_config[
"payload_boundaries"]])
133 basf2.B2INFO(f
"Payload boundaries from expert_config: {payload_boundaries}")
135 files_for_xt_sr_dict = {}
136 files_for_tz_tw_dict = {}
139 if fraction_of_event_for_types[1] > 0:
140 basf2.B2INFO(
"*********************** Select Hadron data for calibration ****************")
141 min_hadron_events_for_tz_tw = fraction_of_event_for_types[1] * min_events_for_tz_tw
142 max_hadron_events_for_tz_tw = fraction_of_event_for_types[1] * max_events_for_tz_tw
143 min_hadron_events_for_xt_sr = fraction_of_event_for_types[1] * min_events_for_xt_sr
144 max_hadron_events_for_xt_sr = fraction_of_event_for_types[1] * max_events_for_xt_sr
146 file_to_iov_hadron = input_data[
"hadron_calib"]
148 basf2.B2INFO(
"----> For T0 and Time walk correction")
149 chosen_files_hadron_for_tz_tw = select_files(list(file_to_iov_hadron.keys()),
150 min_hadron_events_for_tz_tw,
151 max_hadron_events_for_tz_tw,
152 max_events_per_file_hadron_for_tz_tw,
156 basf2.B2INFO(
"----> For XT, space resolution calib")
157 chosen_files_hadron_for_xt_sr = select_files(list(file_to_iov_hadron.keys()),
158 min_hadron_events_for_xt_sr,
159 max_hadron_events_for_xt_sr,
160 max_events_per_file_hadron_for_xt_sr,
164 files_for_xt_sr_dict[
"hadron_calib"] = chosen_files_hadron_for_xt_sr
165 files_for_tz_tw_dict[
"hadron_calib"] = chosen_files_hadron_for_tz_tw
167 if fraction_of_event_for_types[0] > 0:
168 basf2.B2INFO(
"***********************Select di-muon data for calibration ***************")
169 min_mumu_events_for_xt_sr = fraction_of_event_for_types[0] * min_events_for_xt_sr
170 max_mumu_events_for_xt_sr = fraction_of_event_for_types[0] * max_events_for_xt_sr
171 min_mumu_events_for_tz_tw = fraction_of_event_for_types[0] * min_events_for_tz_tw
172 max_mumu_events_for_tz_tw = fraction_of_event_for_types[0] * max_events_for_tz_tw
173 file_to_iov_mumu = input_data[
"mumu_tight_or_highm_calib"]
174 basf2.B2INFO(
"----> For T0 and Time walk correction")
175 chosen_files_mumu_for_tz_tw = select_files(list(file_to_iov_mumu.keys()),
176 min_mumu_events_for_tz_tw,
177 max_mumu_events_for_tz_tw,
183 basf2.B2INFO(
"----> For XT, space resolution calib")
185 chosen_files_mumu_for_xt_sr = select_files(list(file_to_iov_mumu.keys()),
186 min_mumu_events_for_xt_sr,
187 max_mumu_events_for_xt_sr,
192 files_for_xt_sr_dict[
"mumu_tight_or_highm_calib"] = chosen_files_mumu_for_xt_sr
193 files_for_tz_tw_dict[
"mumu_tight_or_highm_calib"] = chosen_files_mumu_for_tz_tw
195 ''' For cosmic data '''
196 if fraction_of_event_for_types[2] > 0:
197 basf2.B2INFO(
"********************* Select cosmic data for calibration *******************")
198 min_cosmic_events_for_tz_tw = fraction_of_event_for_types[2] * min_events_for_tz_tw
199 max_cosmic_events_for_tz_tw = fraction_of_event_for_types[2] * max_events_for_tz_tw
200 min_cosmic_events_for_xt_sr = fraction_of_event_for_types[2] * min_events_for_xt_sr
201 max_cosmic_events_for_xt_sr = fraction_of_event_for_types[2] * max_events_for_xt_sr
203 file_to_iov_cosmic = input_data[
"cosmic_calib"]
206 basf2.B2INFO(
"---->For T0 and Time walk correction")
207 chosen_files_cosmic_for_tz_tw = select_files(list(file_to_iov_cosmic.keys()),
208 min_cosmic_events_for_tz_tw,
209 max_cosmic_events_for_tz_tw,
215 basf2.B2INFO(
"----> For T0 and Time walk correction")
216 chosen_files_cosmic_for_xt_sr = select_files(list(file_to_iov_cosmic.keys()),
217 min_cosmic_events_for_xt_sr,
218 max_cosmic_events_for_xt_sr,
222 files_for_xt_sr_dict[
"cosmic_calib"] = chosen_files_cosmic_for_xt_sr
223 files_for_tz_tw_dict[
"cosmic_calib"] = chosen_files_cosmic_for_tz_tw
225 basf2.B2INFO(
"Complete input data selection.")
228 requested_iov = kwargs.get(
"requested_iov",
None)
230 from caf.utils
import IoV
232 output_iov = IoV(requested_iov.exp_low, requested_iov.run_low, -1, -1)
235 collector_granularity =
'all'
236 if payload_boundaries:
237 basf2.B2INFO(
'Found payload_boundaries: set collector granularity to run')
238 collector_granularity =
'run'
239 if calib_mode ==
"full":
240 calibration_procedure = {
252 elif calib_mode ==
"quick":
253 calibration_procedure = {
263 elif calib_mode ==
"manual":
264 calibration_procedure = expert_config[
"calibration_procedure"]
266 basf2.B2FATAL(f
"Calibration mode is not defined {calib_mode}, should be quick, full, or manual")
268 calib_keys = list(calibration_procedure)
269 cals = [
None]*len(calib_keys)
270 basf2.B2INFO(f
"Run calibration mode = {calib_mode}:")
272 for i
in range(len(cals)):
273 max_iter = calibration_procedure[calib_keys[i]]
276 cal_name =
''.join([i
for i
in calib_keys[i]
if not i.isdigit()])
279 elif cal_name ==
"tw":
281 elif cal_name ==
"xt":
283 elif cal_name ==
"sr_tz":
284 alg = [sr_algo(), tz_algo()]
286 basf2.B2FATAL(f
"The calibration is not defined, check spelling: calib {i}: {calib_keys[i]}")
288 if cal_name ==
"xt" or cal_name ==
"sr_tz":
289 max_event = Max_events_per_file_for_xt_sr
290 data_files = files_for_xt_sr_dict
292 max_event = Max_events_per_file_for_tz_tw
293 data_files = files_for_tz_tw_dict
294 basf2.B2INFO(f
"calibration for {calib_keys[i]} with number of iteration={max_iter}")
295 cals[i] = CDCCalibration(name=calib_keys[i],
297 input_file_dict=data_files,
298 max_iterations=max_iter,
299 max_events=max_event,
300 use_badWires=
True if calib_keys[i] ==
"tz" else False,
301 collector_granularity=collector_granularity,
302 backend_args=expert_config[
"backend_args"],
303 dependencies=[cals[i-1]]
if i > 0
else None
305 if payload_boundaries:
306 basf2.B2INFO(
"Found payload_boundaries: calibration strategies set to SequentialBoundaries.")
309 for algorithm
in alg.algorithms:
310 algorithm.params = {
"iov_coverage": output_iov,
"payload_boundaries": payload_boundaries}
314 for algorithm
in alg.algorithms:
315 algorithm.params = {
"apply_iov": output_iov}
321 def pre_collector(max_events=None, is_cosmic=False, use_badWires=False):
323 Define pre collection (reconstruction in our purpose).
324 Probably, we need only CDC and ECL data.
326 max_events [int] : number of events to be processed.
327 All events by Default.
329 path : path for pre collection
331 from basf2
import create_path, register_module
333 reco_path = create_path()
334 if max_events
is None:
335 root_input = register_module(
337 branchNames=HLT_INPUT_OBJECTS
340 root_input = register_module(
342 branchNames=HLT_INPUT_OBJECTS,
344 '0:{}'.format(max_events)])
345 reco_path.add_module(root_input)
347 gearbox = register_module(
'Gearbox')
348 reco_path.add_module(gearbox)
349 reco_path.add_module(
'Geometry', useDB=
True)
350 Components = [
'CDC',
'ECL']
352 from rawdata
import add_unpackers
353 add_unpackers(reco_path, components=Components)
356 from reconstruction
import add_cosmics_reconstruction
358 add_cosmics_reconstruction(path=reco_path,
359 components=Components,
364 from reconstruction
import default_event_abort
365 from tracking
import add_prefilter_tracking_reconstruction
368 doom = reco_path.add_module(
"EventsOfDoomBuster")
369 default_event_abort(doom,
">=1", Belle2.EventMetaData.c_ReconstructionAbort)
370 reco_path.add_module(
'StatisticsSummary').set_name(
'Sum_EventsofDoomBuster')
373 add_prefilter_tracking_reconstruction(path=reco_path,
374 components=Components,
375 trackFitHypotheses=[211],
376 prune_temporary_tracks=
False, fit_tracks=
True)
377 reco_path.add_module(
'StatisticsSummary').set_name(
'Sum_Tracking')
379 reco_path.add_module(
'Progress')
381 for module
in reco_path.modules():
382 if module.name() ==
"TFCDC_WireHitPreparer":
383 module.param({
"useBadWires": use_badWires})
388 def collector(bField=True, is_cosmic=False, granularity='all'):
390 Create a cdc calibration collector
392 bField [bool] : True if B field is on, else False
393 isCosmic [bool] : True if cosmic events,
394 else (collision) False.
396 collector : collector module
398 from basf2
import register_module
399 col = register_module(
'CDCCalibrationCollector',
400 granularity=granularity,
401 calExpectedDriftTime=
True,
402 eventT0Extraction=
True,
409 def tz_algo(max_rmsDt=0.25, max_badChannel=50):
411 Create a T0 calibration algorithm.
415 from ROOT
import Belle2
417 algo.storeHisto(
True)
418 algo.setMaxMeanDt(0.2)
419 algo.setMaxRMSDt(max_rmsDt)
420 algo.setMaxBadChannel(max_badChannel)
421 algo.setMinimumNDF(25)
428 Create a time walk calibration algorithm.
432 from ROOT
import Belle2
434 algo.setStoreHisto(
True)
441 Create a XT calibration algorithm.
443 prefix : prefixed name for algorithm,
444 which should be consistent with one of collector..
448 from ROOT
import Belle2
450 algo.setStoreHisto(
True)
451 algo.setLRSeparate(
True)
452 algo.setThreshold(0.1)
458 Create a Spacial resolution calibration algorithm.
460 prefix : prefixed name for algorithm,
461 which should be consistent with one of collector..
463 algo : Spacial algorithm
465 from ROOT
import Belle2
467 algo.setStoreHisto(
True)
468 algo.setThreshold(0.1)
474 CDCCalibration is a specialized calibration class for cdc.
475 Since collector is same in all elements, no need to specify it.
484 max_events=[20000, 10000, 20000],
486 collector_granularity='All',
488 for algo
in algorithms:
489 algo.setHistFileName(name)
491 super().__init__(name=name,
492 algorithms=algorithms
495 from caf.framework
import Collection
497 for skim_type, file_list
in input_file_dict.items():
498 if skim_type ==
"cosmic_calib":
500 granularity=collector_granularity),
501 input_files=file_list,
502 pre_collector_path=pre_collector(max_events=max_events[2],
504 use_badWires=use_badWires),
505 backend_args=backend_args)
506 elif skim_type ==
"hadron_calib":
508 input_files=file_list,
509 pre_collector_path=pre_collector(max_events=max_events[1],
510 use_badWires=use_badWires),
511 backend_args=backend_args)
514 input_files=file_list,
515 pre_collector_path=pre_collector(max_events=max_events[0],
516 use_badWires=use_badWires),
517 backend_args=backend_args)
519 self.add_collection(name=skim_type, collection=collection)
523 if dependencies
is not None:
524 for dep
in dependencies:
Class for Space resolution calibration.
Class for T0 Correction .
Class for Time walk calibration.
Class to perform xt calibration for drift chamber.