2 from collections
import namedtuple
5 prompt_script_package =
"prompt.calibrations."
6 prompt_script_dir =
"calibration/scripts/prompt/calibrations"
8 prompt_validation_script_package =
"prompt.validations."
9 prompt_validation_script_dir =
"calibration/scripts/prompt/validations"
11 input_data_filters = {
"Magnet": {
"On":
"On",
14 "Beam Energy": {
"No Beam":
"No Beam",
16 "Continuum":
"Continuum",
18 "Run Type": {
"beam":
"beam",
20 "debug":
"debug",
"null":
"null",
21 "physics":
"physics"},
22 "Data Tag": {
"hlt_skim":
"hlt_skim",
23 "bhabha_all_calib":
"bhabha_all_calib",
24 "cosmic_calib":
"cosmic_calib",
25 "gamma_gamma_calib":
"gamma_gamma_calib",
26 "hadron_calib":
"hadron_calib",
27 "mumutight_calib":
"mumutight_calib",
28 "offip_calib":
"offip_calib",
29 "radmumu_calib":
"radmumu_calib",
30 "random_calib":
"random_calib"},
31 "Data Quality Tag": {
">=30 Minute Run":
">=30 Minute Run",
32 "Bad For Alignment":
"Bad For Alignment",
34 "Good Shifter":
"Good Shifter",
35 "Good For PXD":
"Good For PXD",
36 "Good Or Recoverable":
"Good Or Recoverable",
37 "Good Or Recoverable Shifter":
"Good Or Recoverable Shifter"}
41 class CalibrationSettings(namedtuple(
'CalSet_Factory', [
"name",
50 Simple class to hold and display required information for a prompt calibration script (process).
53 name (str): The unique calibration name, not longer than 64 characters.
55 expert_username (str): The JIRA username of the expert to contact about this script.
56 This username will be used to assign the default responsible person for submitting and checking prompt
59 description (str): Long form description of the calibration and what it does. Feel free to make this as long as you need.
61 input_data_formats (frozenset(str)): The data formats {'raw', 'cdst', 'mdst', 'udst'} of the input files
62 that should be used as input to the process. Used to figure out if this calibration should occur
63 before the relevant data production e.g. before cDST files are created.
65 input_data_names (frozenset(str)): The names that you will use when accessing the input data given to the
66 prompt calibration process i.e. Use these in the ``get_calibrations`` function to access the correct input
67 data files. e.g. input_data_names=["all_events", "offres_photon_events"]
69 input_data_filters (dict): The data selection for the data input names, used for automated calibration.
70 The keys should correspond to one of the ``input_data_names`` with the values being a list of the various data
71 filters, e.g. Data Tag, Beam Energy, Run Type, Run Quality Tag and Magnet. All available filters can be found in the
72 input_data_filters dictionary e.g. from prompt import input_data_filters with details about data tags and run quality
73 tags found at: https://calibration.belle2.org/belle2/data_tags/list/.
74 To exclude specific filters, pre-append with *NOT* e.g.
75 {"all_events": ["mumutight_calib", "hadron_calib", "Good", "On"],
76 "offres_photon_events": ["gamma_gamma_calib", "Good", "NOT On"]}.
77 Not selecting a specfic filters (e.g. Magnet) is equivalent to not having any requirements, e.g. (Either)
79 depends_on (list(CalibrationSettings)): The settings variables of the other prompt calibrations that you want
80 want to depend on. This will allow the external automatic system to understand the overall ordering of
81 scripts to run. If you encounter an import error when trying to run your prompt calibration script, it is
82 likely that you have introduced a circular dependency.
84 expert_config (dict): Default expert configuration for this calibration script. This is an optional dictionary
85 (which must be JSON compliant) of configuration options for your get_calibrations(...) function.
86 This is supposed to be used as a catch-all place to send in options for your calibration setup. For example,
87 you may want to have an optional list of IoV boundaries so that your prompt script knows that it should split the
88 input data between different IoV ranges. Or you might want to send if options like the maximum events per
89 input file to process. The value in your settings object will be the *default*, but you can override the value via
90 the caf_config.json sent into ``b2caf-prompt-run``.
96 allowed_data_formats = frozenset({
"raw",
"cdst",
"mdst",
"udst"})
98 def __new__(cls, name, expert_username, description,
99 input_data_formats=None, input_data_names=None, input_data_filters=None, depends_on=None, expert_config=None):
101 The special method to create the tuple instance. Returning the instance
102 calls the __init__ method
105 raise ValueError(
"name cannot be longer than 64 characters!")
106 if not input_data_formats:
107 raise ValueError(
"You must specify at least one input data format")
108 input_data_formats = frozenset(map(
lambda x: x.lower(), input_data_formats))
110 raise ValueError(
"There was a data format that is not in the allowed_data_formats attribute.")
111 if not input_data_names:
112 raise ValueError(
"You must specify at least one input data name")
113 input_data_names = frozenset(input_data_names)
117 if not isinstance(expert_config, dict):
118 raise TypeError(
"expert_config must be a dictionary")
121 json.dumps(expert_config)
122 except TypeError
as e:
123 basf2.B2ERROR(
"expert_config could not be serialised to JSON. "
124 "Most likely you used a non-supported type e.g. datetime.")
130 for calibration_settings
in depends_on:
131 if not isinstance(calibration_settings, cls):
132 raise TypeError(f
"A list of {str(cls)} object is required when setting the 'depends_on' keyword.")
136 return super().
__new__(cls, name, expert_username, description,
137 input_data_formats, input_data_names, input_data_filters, depends_on, expert_config)
142 str: A valid JSON format string of the attributes.
144 depends_on_names = [calibration_settings.name
for calibration_settings
in self.depends_on]
145 return json.dumps({
"name": self.name,
146 "expert_username": self.expert_username,
147 "input_data_formats": list(self.input_data_formats),
148 "input_data_names": list(self.input_data_names),
149 "input_data_filters": self.input_data_filters,
150 "depends_on": list(depends_on_names),
151 "description": self.description,
152 "expert_config": self.expert_config
156 depends_on_names = [calibration_settings.name
for calibration_settings
in self.depends_on]
157 output_str = str(self.__class__.__name__) + f
"(name='{self.name}'):\n"
158 output_str += f
" expert_username='{self.expert_username}'\n"
159 output_str += f
" input_data_formats={list(self.input_data_formats)}\n"
160 output_str += f
" input_data_names={list(self.input_data_names)}\n"
161 output_str += f
" input_data_filters={list(self.input_data_filters)}\n"
162 output_str += f
" depends_on={list(depends_on_names)}\n"
163 output_str += f
" description='{self.description}'\n"
164 output_str += f
" expert_config={self.expert_config}"
168 class ValidationSettings(namedtuple(
'ValSet_Factory', [
"name",
"description",
"download_files",
"expert_config"])):
170 Simple class to hold and display required information for a validation calibration script (process).
173 name (str): The unique name that must match the corresponding calibration, not longer than 64 characters.
175 description (str): Long form description of the validation and what it does. Feel free to make this as long as you need.
177 download_files (list): The names of the files you want downloaded, e.g. mycalibration_stdout. If multiple files of
178 the same name are found, all files are downloaded and appended with the folder they were in.
180 expert_config (dict): Default expert configuration for this validation script. This is an optional dictionary
181 (which must be JSON compliant) of configuration options for validation script.
182 This is supposed to be used as a catch-all place to send in options for your calibration setup. For example,
183 you may want to have an optional list of IoV boundaries so that your validation script knows that it should split the
184 input data between different IoV ranges. Or you might want to send if options like the maximum events per
185 input file to process. The value in your settings object will be the *default*, but you can override the value via
186 the caf_config.json sent into ``b2caf-prompt-run``.
189 def __new__(cls, name, description, download_files=None, expert_config=None):
191 The special method to create the tuple instance. Returning the instance
192 calls the __init__ method
195 raise ValueError(
"name cannot be longer than 64 characters!")
199 if not isinstance(expert_config, dict):
200 raise TypeError(
"expert_config must be a dictionary")
203 json.dumps(expert_config)
204 except TypeError
as e:
205 basf2.B2ERROR(
"expert_config could not be serialised to JSON. "
206 "Most likely you used a non-supported type e.g. datetime.")
211 return super().
__new__(cls, name, description, download_files, expert_config)
216 str: A valid JSON format string of the attributes.
218 return json.dumps({
"name": self.name,
219 "description": self.description,
220 "download_files": self.download_files,
221 "expert_config": self.expert_config
225 output_str = str(self.__class__.__name__) + f
"(name='{self.name}'):\n"
226 output_str += f
" description='{self.description}'\n"
227 output_str += f
" download_files='{self.download_files}'\n"
228 output_str += f
" expert_config={self.expert_config}"