12"""Full CDC tracking calibration."""
13from prompt
import CalibrationSettings, INPUT_DATA_FILTERS
16from random
import choice
17from caf.framework
import Calibration
18from caf
import strategies
21settings = CalibrationSettings(name=
"CDC Tracking",
22 expert_username=
"guanyu",
25 input_data_formats=[
"raw"],
26 input_data_names=[
"mumu_tight_or_highm_calib",
"hadron_calib",
"cosmic_calib"],
27 input_data_filters={
"mumu_tight_or_highm_calib":
28 [INPUT_DATA_FILTERS[
"Data Tag"][
"mumu_tight_or_highm_calib"],
29 INPUT_DATA_FILTERS[
"Data Quality Tag"][
"Good"],
30 INPUT_DATA_FILTERS[
"Magnet"][
"On"]],
32 [INPUT_DATA_FILTERS[
"Data Tag"][
"hadron_calib"],
33 INPUT_DATA_FILTERS[
"Data Quality Tag"][
"Good"],
34 INPUT_DATA_FILTERS[
"Magnet"][
"On"]],
36 [INPUT_DATA_FILTERS[
"Data Tag"][
"cosmic_calib"],
37 INPUT_DATA_FILTERS[
"Data Quality Tag"][
"Good"],
38 INPUT_DATA_FILTERS[
"Magnet"][
"On"]]},
41 "min_events_per_file": 500,
42 "max_events_per_file": 20000,
43 "max_events_per_file_hadron_for_tz_tw": 5000,
44 "max_events_per_file_hadron_for_xt_sr": 12000,
45 "min_events_for_tz_tw_calibration": 500000,
46 "max_events_for_tz_tw_calibration": 15000000,
47 "min_events_for_xt_sr_calibration": 1000000,
48 "max_events_for_xt_sr_calibration": 10000000,
49 "fractions_for_each_type": [0.5, 1, 0.5],
50 "max_job_for_each_type": [400, 700, 400],
51 "calib_mode":
"quick",
52 "calibration_procedure": {
"tz0": 1,
"xt0": 0,
"sr_tz0": 0,
"tz2": 0},
53 "payload_boundaries": [],
54 "backend_args": {
"request_memory":
"4 GB"},
55 "physics_mode":
"yes"},
56 produced_payloads=[
"CDCTimeZeros",
"CDCTimeWalks",
"CDCXtRelations",
"CDCSpaceResols"])
59def select_files(all_input_files, min_events, max_events, max_processed_events_per_file, max_job=800, min_events_per_file=500):
60 basf2.B2INFO(f
"Minimum number of events: {min_events}")
61 basf2.B2INFO(f
"Maximum number of events: {max_events}")
62 basf2.B2INFO(f
"Conditions: ({min_events_per_file} < #Event/file < {max_processed_events_per_file}) and max_job = {max_job}")
67 while total_events < max_events
and njob < max_job:
70 if not all_input_files:
73 new_file_choice = choice(all_input_files)
75 all_input_files.remove(new_file_choice)
77 total_events_in_file = events_in_basf2_file(new_file_choice)
78 if not total_events_in_file
or total_events_in_file < min_events_per_file:
81 events_contributed = 0
82 if total_events_in_file < max_processed_events_per_file:
84 events_contributed = total_events_in_file
86 events_contributed = max_processed_events_per_file
87 chosen_files.append(new_file_choice)
88 total_events += events_contributed
91 basf2.B2INFO(f
"Total chosen files = {len(chosen_files)}")
92 basf2.B2INFO(f
"Total events in chosen files = {total_events}")
93 if total_events < min_events:
95 f
"There is not enough required events with setup max_processed_events_per_file = {max_processed_events_per_file}")
104def get_calibrations(input_data, **kwargs):
108 expert_config = kwargs.get(
"expert_config")
109 calib_mode = expert_config[
"calib_mode"]
110 physics_mode = expert_config[
"physics_mode"]
112 min_events_per_file = expert_config[
"min_events_per_file"]
113 max_events_per_file = expert_config[
"max_events_per_file"]
115 min_events_for_tz_tw = expert_config[
"min_events_for_tz_tw_calibration"]
116 max_events_for_tz_tw = expert_config[
"max_events_for_tz_tw_calibration"]
117 max_events_per_file_hadron_for_tz_tw = expert_config[
"max_events_per_file_hadron_for_tz_tw"]
119 min_events_for_xt_sr = expert_config[
"min_events_for_xt_sr_calibration"]
120 max_events_for_xt_sr = expert_config[
"max_events_for_xt_sr_calibration"]
121 max_events_per_file_hadron_for_xt_sr = expert_config[
"max_events_per_file_hadron_for_xt_sr"]
123 Max_events_per_file_for_tz_tw = [max_events_per_file, max_events_per_file_hadron_for_tz_tw, max_events_per_file]
124 Max_events_per_file_for_xt_sr = [max_events_per_file, max_events_per_file_hadron_for_xt_sr, max_events_per_file]
126 fraction_of_event_for_types = expert_config[
"fractions_for_each_type"]
127 max_jobs = expert_config[
"max_job_for_each_type"]
128 basf2.B2INFO(f
"Number of job for each type are limited at [di-muon, hadron, cosmic]: {max_jobs}")
129 basf2.B2INFO(f
"Fraction for [di-muon, hadron, cosmic]: {fraction_of_event_for_types}")
130 if len(fraction_of_event_for_types) != 3:
131 basf2.B2FATAL(
"fraction of event must be an array with the size of 3, with order [mumu, hadron, cosmic]")
133 payload_boundaries = []
134 payload_boundaries.extend([ExpRun(*boundary)
for boundary
in expert_config[
"payload_boundaries"]])
135 basf2.B2INFO(f
"Payload boundaries from expert_config: {payload_boundaries}")
137 files_for_xt_sr_dict = {}
138 files_for_tz_tw_dict = {}
141 if fraction_of_event_for_types[1] > 0:
142 basf2.B2INFO(
"*********************** Select Hadron data for calibration ****************")
143 min_hadron_events_for_tz_tw = fraction_of_event_for_types[1] * min_events_for_tz_tw
144 max_hadron_events_for_tz_tw = fraction_of_event_for_types[1] * max_events_for_tz_tw
145 min_hadron_events_for_xt_sr = fraction_of_event_for_types[1] * min_events_for_xt_sr
146 max_hadron_events_for_xt_sr = fraction_of_event_for_types[1] * max_events_for_xt_sr
148 file_to_iov_hadron = input_data[
"hadron_calib"]
150 basf2.B2INFO(
"----> Hadron for T0 and Time walk correction")
151 chosen_files_hadron_for_tz_tw = select_files(list(file_to_iov_hadron.keys()),
152 min_hadron_events_for_tz_tw,
153 max_hadron_events_for_tz_tw,
154 max_events_per_file_hadron_for_tz_tw,
158 basf2.B2INFO(
"----> Hadron for XT, space resolution calib")
159 chosen_files_hadron_for_xt_sr = select_files(list(file_to_iov_hadron.keys()),
160 min_hadron_events_for_xt_sr,
161 max_hadron_events_for_xt_sr,
162 max_events_per_file_hadron_for_xt_sr,
166 files_for_xt_sr_dict[
"hadron_calib"] = chosen_files_hadron_for_xt_sr
167 files_for_tz_tw_dict[
"hadron_calib"] = chosen_files_hadron_for_tz_tw
169 if fraction_of_event_for_types[0] > 0:
170 basf2.B2INFO(
"***********************Select di-muon data for calibration ***************")
171 min_mumu_events_for_xt_sr = fraction_of_event_for_types[0] * min_events_for_xt_sr
172 max_mumu_events_for_xt_sr = fraction_of_event_for_types[0] * max_events_for_xt_sr
173 min_mumu_events_for_tz_tw = fraction_of_event_for_types[0] * min_events_for_tz_tw
174 max_mumu_events_for_tz_tw = fraction_of_event_for_types[0] * max_events_for_tz_tw
175 file_to_iov_mumu = input_data[
"mumu_tight_or_highm_calib"]
176 basf2.B2INFO(
"----> Mumu for T0 and Time walk correction")
177 chosen_files_mumu_for_tz_tw = select_files(list(file_to_iov_mumu.keys()),
178 min_mumu_events_for_tz_tw,
179 max_mumu_events_for_tz_tw,
185 basf2.B2INFO(
"----> Mumu for XT, space resolution calib")
187 chosen_files_mumu_for_xt_sr = select_files(list(file_to_iov_mumu.keys()),
188 min_mumu_events_for_xt_sr,
189 max_mumu_events_for_xt_sr,
194 files_for_xt_sr_dict[
"mumu_tight_or_highm_calib"] = chosen_files_mumu_for_xt_sr
195 files_for_tz_tw_dict[
"mumu_tight_or_highm_calib"] = chosen_files_mumu_for_tz_tw
197 ''' For cosmic data '''
198 if fraction_of_event_for_types[2] > 0:
199 basf2.B2INFO(
"********************* Select cosmic data for calibration *******************")
200 min_cosmic_events_for_tz_tw = fraction_of_event_for_types[2] * min_events_for_tz_tw
201 max_cosmic_events_for_tz_tw = fraction_of_event_for_types[2] * max_events_for_tz_tw
202 min_cosmic_events_for_xt_sr = fraction_of_event_for_types[2] * min_events_for_xt_sr
203 max_cosmic_events_for_xt_sr = fraction_of_event_for_types[2] * max_events_for_xt_sr
205 file_to_iov_cosmic = input_data[
"cosmic_calib"]
208 basf2.B2INFO(
"----> Cosmic for T0 and Time walk correction")
209 if physics_mode ==
"no":
210 basf2.B2INFO(
"---->In non-physics mode, still use cosmic for t0 calibration")
211 chosen_files_cosmic_for_tz_tw = select_files(list(file_to_iov_cosmic.keys()),
212 min_cosmic_events_for_tz_tw,
213 max_cosmic_events_for_tz_tw,
218 basf2.B2INFO(
"---->In physics mode, do not use cosmic for t0 calibration")
219 chosen_files_cosmic_for_tz_tw = {}
222 basf2.B2INFO(
"----> Cosmic for XT, space resolution calib")
223 chosen_files_cosmic_for_xt_sr = select_files(list(file_to_iov_cosmic.keys()),
224 min_cosmic_events_for_xt_sr,
225 max_cosmic_events_for_xt_sr,
229 files_for_xt_sr_dict[
"cosmic_calib"] = chosen_files_cosmic_for_xt_sr
230 files_for_tz_tw_dict[
"cosmic_calib"] = chosen_files_cosmic_for_tz_tw
232 basf2.B2INFO(
"Complete input data selection.")
235 requested_iov = kwargs.get(
"requested_iov",
None)
237 from caf.utils
import IoV
239 output_iov = IoV(requested_iov.exp_low, requested_iov.run_low, -1, -1)
242 collector_granularity =
'all'
243 if payload_boundaries:
244 basf2.B2INFO(
'Found payload_boundaries: set collector granularity to run')
245 collector_granularity =
'run'
246 if calib_mode ==
"full":
247 calibration_procedure = {
259 elif calib_mode ==
"quick":
260 calibration_procedure = {
270 elif calib_mode ==
"manual":
271 calibration_procedure = expert_config[
"calibration_procedure"]
273 basf2.B2FATAL(f
"Calibration mode is not defined {calib_mode}, should be quick, full, or manual")
275 calib_keys = list(calibration_procedure)
276 cals = [
None]*len(calib_keys)
277 basf2.B2INFO(f
"Run calibration mode = {calib_mode}:")
279 for i
in range(len(cals)):
280 max_iter = calibration_procedure[calib_keys[i]]
283 cal_name =
''.join([i
for i
in calib_keys[i]
if not i.isdigit()])
286 elif cal_name ==
"tw":
288 elif cal_name ==
"xt":
290 elif cal_name ==
"sr_tz":
291 alg = [sr_algo(), tz_algo()]
293 basf2.B2FATAL(f
"The calibration is not defined, check spelling: calib {i}: {calib_keys[i]}")
295 if cal_name ==
"xt" or cal_name ==
"sr_tz":
296 max_event = Max_events_per_file_for_xt_sr
297 data_files = files_for_xt_sr_dict
299 max_event = Max_events_per_file_for_tz_tw
300 data_files = files_for_tz_tw_dict
301 basf2.B2INFO(f
"calibration for {calib_keys[i]} with number of iteration={max_iter}")
302 cals[i] = CDCCalibration(name=calib_keys[i],
304 input_file_dict=data_files,
305 max_iterations=max_iter,
306 max_events=max_event,
307 use_badWires=
True if calib_keys[i] ==
"tz" else False,
308 collector_granularity=collector_granularity,
309 backend_args=expert_config[
"backend_args"],
310 dependencies=[cals[i-1]]
if i > 0
else None
312 if payload_boundaries:
313 basf2.B2INFO(
"Found payload_boundaries: calibration strategies set to SequentialBoundaries.")
316 for algorithm
in alg.algorithms:
317 algorithm.params = {
"iov_coverage": output_iov,
"payload_boundaries": payload_boundaries}
321 for algorithm
in alg.algorithms:
322 algorithm.params = {
"apply_iov": output_iov}
328def pre_collector(max_events=None, is_cosmic=False, use_badWires=False):
330 Define pre collection (reconstruction in our purpose).
331 Probably, we need only CDC and ECL data.
333 max_events [int] : number of events to be processed.
334 All events by Default.
336 path : path for pre collection
338 from basf2
import create_path, register_module
340 reco_path = create_path()
341 if max_events
is None:
342 root_input = register_module(
344 branchNames=HLT_INPUT_OBJECTS
347 root_input = register_module(
349 branchNames=HLT_INPUT_OBJECTS,
352 reco_path.add_module(root_input)
354 gearbox = register_module(
'Gearbox')
355 reco_path.add_module(gearbox)
356 reco_path.add_module(
'Geometry', useDB=
True)
357 Components = [
'CDC',
'ECL']
359 from rawdata
import add_unpackers
360 add_unpackers(reco_path, components=Components)
363 from reconstruction
import add_cosmics_reconstruction
365 add_cosmics_reconstruction(path=reco_path,
366 components=Components,
371 from reconstruction
import add_prefilter_pretracking_reconstruction
372 from tracking
import add_prefilter_tracking_reconstruction
376 add_prefilter_module(reco_path)
379 add_prefilter_pretracking_reconstruction(reco_path, components=Components)
382 add_prefilter_tracking_reconstruction(path=reco_path,
383 components=Components,
384 trackFitHypotheses=[211],
385 prune_temporary_tracks=
False,
387 append_full_grid_cdc_eventt0=
True,
388 skip_full_grid_cdc_eventt0_if_svd_time_present=
False)
389 reco_path.add_module(
'StatisticsSummary').set_name(
'Sum_Tracking')
391 reco_path.add_module(
'Progress')
393 for module
in reco_path.modules():
394 if module.name() ==
"TFCDC_WireHitPreparer":
395 module.param({
"useBadWires": use_badWires})
400def collector(is_cosmic=False, granularity='all'):
402 Create a cdc calibration collector
404 bField [bool] : True if B field is on, else False
405 isCosmic [bool] : True if cosmic events,
406 else (collision) False.
408 collector : collector module
410 from basf2
import register_module
411 col = register_module(
'CDCCalibrationCollector',
412 granularity=granularity,
413 calExpectedDriftTime=
True,
414 eventT0Extraction=
True,
420def tz_algo(max_rmsDt=0.25, max_badChannel=50):
422 Create a T0 calibration algorithm.
426 from ROOT
import Belle2
428 algo.storeHisto(
True)
429 algo.setMaxMeanDt(0.2)
430 algo.setMaxRMSDt(max_rmsDt)
431 algo.setMaxBadChannel(max_badChannel)
432 algo.setMinimumNDF(25)
439 Create a time walk calibration algorithm.
443 from ROOT
import Belle2
445 algo.setStoreHisto(
True)
452 Create a XT calibration algorithm.
454 prefix : prefixed name for algorithm,
455 which should be consistent with one of collector..
459 from ROOT
import Belle2
461 algo.setStoreHisto(
True)
462 algo.setLRSeparate(
True)
463 algo.setThreshold(0.1)
469 Create a Spacial resolution calibration algorithm.
471 prefix : prefixed name for algorithm,
472 which should be consistent with one of collector..
474 algo : Spacial algorithm
476 from ROOT
import Belle2
478 algo.setStoreHisto(
True)
479 algo.setThreshold(0.1)
483class CDCCalibration(Calibration):
485 CDCCalibration is a specialized calibration class for cdc.
486 Since collector is same in all elements, no need to specify it.
495 max_events=[20000, 10000, 20000],
497 collector_granularity='All',
501 for algo
in algorithms:
502 algo.setHistFileName(name)
504 super().__init__(name=name,
505 algorithms=algorithms
508 from caf.framework
import Collection
510 for skim_type, file_list
in input_file_dict.items():
511 if skim_type ==
"cosmic_calib":
513 granularity=collector_granularity),
514 input_files=file_list,
515 pre_collector_path=pre_collector(max_events=max_events[2],
517 use_badWires=use_badWires),
518 backend_args=backend_args)
519 elif skim_type ==
"hadron_calib":
521 input_files=file_list,
522 pre_collector_path=pre_collector(max_events=max_events[1],
523 use_badWires=use_badWires),
524 backend_args=backend_args)
527 input_files=file_list,
528 pre_collector_path=pre_collector(max_events=max_events[0],
529 use_badWires=use_badWires),
530 backend_args=backend_args)
532 self.add_collection(name=skim_type, collection=collection)
535 self.max_iterations = max_iterations
537 if dependencies
is not None:
538 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.