Belle II Software development
caf_top.py
1
8
9"""
10Airflow script for TOP post-tracking calibration:
11 BS13d carrier shifts, module T0 and common T0.
12 Histograms for validation are also prepared here.
13"""
14import basf2
15from prompt import CalibrationSettings, INPUT_DATA_FILTERS
16from caf.utils import IoV
17from caf.strategies import SequentialBoundaries
18from top_calibration import BS13d_calibration_cdst
19from top_calibration import moduleT0_calibration_DeltaT, moduleT0_calibration_LL
20from top_calibration import commonT0_calibration_BF
21from top_calibration import offset_calibration
22from top_calibration import photonYields_calibration
23from top_calibration import calibration_validation
24from prompt.calibrations.caf_top_pre import settings as top_pretracking
25from prompt.utils import filter_by_max_files_per_run
26
27
28settings = CalibrationSettings(
29 name="TOP post-tracking calibration",
30 expert_username="kohani",
31 subsystem="top",
32 description=__doc__,
33 input_data_formats=["cdst"],
34 input_data_names=["mumu_tight_or_highm_calib"],
35 input_data_filters={
36 "mumu_tight_or_highm_calib": [
37 INPUT_DATA_FILTERS["Data Tag"]["mumu_tight_or_highm_calib"],
38 INPUT_DATA_FILTERS["Run Type"]["physics"],
39 INPUT_DATA_FILTERS["Data Quality Tag"]["Good Or Recoverable"]]},
40 depends_on=[top_pretracking],
41 expert_config={
42 "max_files_per_run": 20,
43 "payload_boundaries": None,
44 "request_memory": "8 GB"},
45 produced_payloads=[
46 "TOPCalModuleT0",
47 "TOPCalCommonT0",
48 "TOPCalEventT0Offset",
49 "TOPCalFillPatternOffset",
50 "TOPCalPhotonYields",
51 "TOPCalChannelRQE"])
52
53
54# Required function
55def get_calibrations(input_data, **kwargs):
56 '''
57 Returns a list of calibration objects.
58 :input_data (dict): Contains every file name from the 'input_data_names' as a key.
59 :**kwargs: Configuration options to be sent in.
60 '''
61
62 file_to_iov = input_data["mumu_tight_or_highm_calib"]
63 sample = 'dimuon'
64 expert_config = kwargs.get("expert_config")
65 max_files_per_run = expert_config["max_files_per_run"]
66 min_events_per_file = 1
67 # Applying the min event per file to remove empty root files
68 reduced_file_to_iov = filter_by_max_files_per_run(file_to_iov, max_files_per_run, min_events_per_file, random_select=True)
69 inputFiles = list(reduced_file_to_iov.keys())
70 basf2.B2INFO(f"Total number of files actually used as input = {len(inputFiles)}")
71 requested_iov = kwargs.get("requested_iov", None)
72 output_iov = IoV(requested_iov.exp_low, requested_iov.run_low, -1, -1)
73
74 # Run 2 calibration chain differs a bit from that of Run 1 (take Run 2 chain if requested_iov is not given)
75 if requested_iov.exp_low > 26 or requested_iov.exp_low <= 0:
76 basf2.B2INFO("Running Run 2 calibration chain for TOP")
77 cal = [moduleT0_calibration_DeltaT(inputFiles), # this cal cannot span across experiments
78 moduleT0_calibration_LL(inputFiles, sample), # this cal cannot span across experiments
79 commonT0_calibration_BF(inputFiles), # this is run-dep
80 offset_calibration(inputFiles), # this is run-dep
81 photonYields_calibration(inputFiles, sample), # this cal cannot span across experiments
82 calibration_validation(inputFiles, sample)] # this is run-dep
83 cal[0].save_payloads = False # don't save the rough moduleT0 result
84 cal[5].save_payloads = False # in fact it does not make any payloads, but produces histograms for validation
85 else:
86 basf2.B2INFO("Running Run 1 calibration chain for TOP")
87 cal = [BS13d_calibration_cdst(inputFiles), # this is run-dep
88 moduleT0_calibration_DeltaT(inputFiles), # this cal cannot span across experiments
89 moduleT0_calibration_LL(inputFiles, sample), # this cal cannot span across experiments
90 commonT0_calibration_BF(inputFiles), # this is run-dep
91 offset_calibration(inputFiles), # this is run-dep
92 photonYields_calibration(inputFiles, sample), # this cal cannot span across experiments
93 calibration_validation(inputFiles, sample)] # this is run-dep
94 cal[1].save_payloads = False # don't save the rough moduleT0 result
95 cal[6].save_payloads = False # in fact it does not make any payloads, but produces histograms for validation
96
97 for c in cal:
98 # If it's a SequentialBoundary calibration, check if there is any boundary in the config file
99 if c.strategies[0] == SequentialBoundaries:
100
101 # Default boundaries. If there are no boundaries in the config file, this calibration will give a single IoV
102 payload_boundaries = [[output_iov.exp_low, output_iov.run_low]]
103
104 # user-defined boundaries are set here.
105 if expert_config["payload_boundaries"] is not None:
106 payload_boundaries = expert_config["payload_boundaries"]
107
108 # Set the actual boundaries.
109 for alg in c.algorithms:
110 alg.params = {"iov_coverage": output_iov, "payload_boundaries": payload_boundaries}
111
112 # If it's not a SequentialBoundary calbration, just set the IoV coverage
113 else:
114 for alg in c.algorithms:
115 alg.params = {"iov_coverage": output_iov}
116
117 for i in range(1, len(cal)):
118 cal[i].depends_on(cal[i - 1])
119
120 return cal