11Script to perform the SVD dE/dx calibration
13from prompt
import CalibrationSettings, INPUT_DATA_FILTERS
17import modularAnalysis
as ma
19import reconstruction
as re
20from reconstruction
import prepare_user_cdst_analysis, DIGITS_OBJECTS
22settings = CalibrationSettings(
24 expert_username=
"lisovskyi",
27 input_data_formats=[
"cdst"],
28 input_data_names=[
"hadron_calib"],
29 input_data_filters={
"hadron_calib": [INPUT_DATA_FILTERS[
"Data Tag"][
"hadron_calib"],
30 INPUT_DATA_FILTERS[
"Beam Energy"][
"4S"],
31 INPUT_DATA_FILTERS[
"Beam Energy"][
"Continuum"],
32 INPUT_DATA_FILTERS[
"Run Type"][
"physics"],
33 INPUT_DATA_FILTERS[
"Magnet"][
"On"]]},
37 "listOfMutedCalibrations": [],
40 "rerun_reco_val":
False,
42 "rerun_pid_val":
True,
44 "validation_mode":
"basic",
46 "MaxFilesPerRunValidation": 6,
48 "MaxEvtsPerFile": 20000,
49 "MinEvtsPerTree": 100,
56 "CustomProfile":
True,
58 "FixUnstableFitParameter":
True,
60 "NEventsToGenerate": 5e5,
61 "UsePionBGFunctionForEverything":
False,
63 "UseProtonBGFunctionForEverything":
False,
66 "MaxROCMomentum": 2.5,
72 produced_payloads=[
"SVDdEdxPDFs"])
75def create_path(rerun_reco, rerun_pid, isMC, expert_config):
79 max_events_per_file = expert_config[
"MaxEvtsPerFile"]
85 branchNames=HLT_INPUT_OBJECTS,
86 entrySequences=[f
'0:{max_events_per_file - 1}'],
87 logLevel=b2.LogLevel.ERROR)
88 re.add_unpackers(path=rec_path)
90 rec_path.add_module(
'RootInput', branchNames=list(DIGITS_OBJECTS) + [
92 'EventLevelTriggerTimeInfo',
93 'SoftwareTriggerResult',
94 'TRGSummary'], entrySequences=[f
'0:{max_events_per_file - 1}'])
95 rec_path.add_module(
"Gearbox")
96 rec_path.add_module(
"Geometry")
98 re.add_reconstruction(path=rec_path, pruneTracks=
False)
99 rec_path.add_module(
'VXDDedxPID')
101 rec_path.add_module(
'RootInput', entrySequences=[f
'0:{max_events_per_file - 1}'])
102 prepare_user_cdst_analysis(rec_path, mc=isMC)
104 rec_path.add_module(
'RootInput')
107 ma.fillParticleList(
"pi+:all",
"", path=rec_path)
108 ma.fillParticleList(
"pi+:lambda",
"nCDCHits > 0", path=rec_path)
109 ma.fillParticleList(
"pi+:cut",
"abs(dr) < 0.5 and abs(dz) < 2 and nSVDHits > 1",
112 ma.fillParticleList(
'K-:cut', cut=
'abs(dr) < 0.5 and abs(dz) < 2 and nSVDHits > 1', path=rec_path)
113 ma.fillParticleList(
'e+:cut', cut=
'nSVDHits > 0', path=rec_path)
115 ma.fillParticleList(
'p+:lambda', cut=
'nCDCHits > 0 and nSVDHits > 0 and p > 0.135', path=rec_path)
118 ma.reconstructDecay(decayString=
'D0:kpi -> K-:cut pi+:cut', cut=
'1.7 < M < 2.', path=rec_path)
120 decayString=
'D*+:myDstar -> D0:kpi pi+:all',
121 cut=
'1.95 < M <2.05 and massDifference(0) < 0.16',
125 ma.reconstructDecay(
'Lambda0:myLambda -> p+:lambda pi-:lambda',
'1.1 < M < 1.3', path=rec_path)
128 ma.reconstructDecay(
'gamma:myGamma -> e+:cut e-:cut',
'0.0 < M < 0.5', path=rec_path)
132 vx.treeFit(list_name=
'D*+:myDstar', conf_level=0, ipConstraint=
True, updateAllDaughters=
True, path=rec_path)
133 vx.treeFit(list_name=
'Lambda0:myLambda', conf_level=0, ipConstraint=
True, updateAllDaughters=
True, path=rec_path)
134 vx.treeFit(list_name=
'gamma:myGamma', conf_level=0, path=rec_path)
145 outputListName=
'Lambda0:cut',
146 inputListName=
'Lambda0:myLambda',
148 "1.10 < InvM < 1.13 and chiProb > 0.001 and distance > 1.0 and "
149 "cosAngleBetweenMomentumAndVertexVector > 0 and "
150 "formula(daughter(0,p)) > formula(daughter(1,p)) and convertedPhotonInvariantMass(0,1) > 0.02 and "
151 "[[formula((((daughter(0, px)**2+daughter(0, py)**2+daughter(0, pz)**2 + 0.13957**2)**0.5+"
152 "daughter(1, E))*((daughter(0, px)**2+daughter(0, py)**2+daughter(0, pz)**2 + 0.13957**2)**0.5+"
153 "daughter(1, E))-(daughter(0, px)+daughter(1, px))*(daughter(0, px)+daughter(1, px))-(daughter(0, py)+"
154 "daughter(1, py))*(daughter(0, py)+daughter(1, py))-(daughter(0, pz)+daughter(1, pz))*(daughter(0, pz)+"
155 "daughter(1, pz)))**0.5) < 0.488]"
156 "or [formula((((daughter(0, px)**2+daughter(0, py)**2+daughter(0, pz)**2 + 0.13957**2)**0.5+"
157 "daughter(1, E))*((daughter(0, px)**2+daughter(0, py)**2+daughter(0, pz)**2 + 0.13957**2)**0.5+"
158 "daughter(1, E))-(daughter(0, px)+daughter(1, px))*(daughter(0, px)+daughter(1, px))-(daughter(0, py)+"
159 "daughter(1, py))*(daughter(0, py)+daughter(1, py))-(daughter(0, pz)+daughter(1, pz))*(daughter(0, pz)+"
160 "daughter(1, pz)))**0.5) > 0.513]]"
170 outputListName=
'D*+:cut',
171 inputListName=
'D*+:myDstar',
172 cut=(
'massDifference(0) < 0.151 and 1.85 < daughter(0, InvM) < 1.88 and '
173 '1.95 < InvM < 2.05 and chiProb > 0.001 and '
174 'formula(daughter(0,cosAngleBetweenMomentumAndVertexVector))>-0.75'),
185 outputListName=
'gamma:cut',
186 inputListName=
'gamma:myGamma',
187 cut=(
'chiProb > 0.001 and 1 < dr < 12 and InvM < 0.01'
188 ' and cosAngleBetweenMomentumAndVertexVector > 0.995'
189 ' and convertedPhotonInvariantMass(0,1) < 0.005'
190 ' and -0.05 < convertedPhotonDelR(0,1) < 0.15'
191 ' and -0.05 < convertedPhotonDelZ(0,1) < 0.05'
197def get_calibrations(input_data, **kwargs):
200 input_data (dict): Should contain every name from the 'input_data_names' variable as a key.
201 Each value is a dictionary with {"/path/to/file_e1_r5.root": IoV(1,5,1,5), ...}. Useful for
202 assigning to calibration.files_to_iov
204 **kwargs: Configuration options to be sent in. Since this may change we use kwargs as a way to help prevent
205 backwards compatibility problems. But you could use the correct arguments in b2caf-prompt-run for this
206 release explicitly if you want to.
208 Currently only kwargs["requested_iov"] and kwargs["expert_config"] are used.
210 "requested_iov" is the IoV range of the bucket and your payloads should correspond to this range.
211 However your highest payload IoV should be open ended e.g. IoV(3,4,-1,-1)
213 "expert_config" is the input configuration. It takes default values from your `CalibrationSettings` but these are
214 overwritten by values from the 'expert_config' key in your input `caf_config.json` file when running ``b2caf-prompt-run``.
217 list(caf.framework.Calibration): All of the calibration objects we want to assign to the CAF process
224 file_to_iov_hadron_calib = input_data[
"hadron_calib"]
226 expert_config = kwargs.get(
"expert_config")
228 isMC = expert_config[
"isMC"]
229 listOfMutedCalibrations = expert_config[
"listOfMutedCalibrations"]
230 rerun_reco = expert_config[
"rerun_reco"]
231 rerun_reco_val = expert_config[
"rerun_reco_val"]
232 rerun_pid_val = expert_config[
"rerun_pid_val"]
233 max_files_per_run = expert_config[
"MaxFilesPerRun"]
234 max_files_per_run_validation = expert_config[
"MaxFilesPerRunValidation"]
237 validation_mode = 1
if expert_config[
"validation_mode"] ==
"full" else 0
242 min_events_per_file = expert_config[
"MinEvtsPerFile"]
246 reduced_file_to_iov_hadron_calib = filter_by_max_files_per_run(file_to_iov_hadron_calib, max_files_per_run, min_events_per_file)
247 input_files_hadron_calib = list(reduced_file_to_iov_hadron_calib.keys())
248 basf2.B2INFO(f
"Total number of files actually used as input for calibration = {len(input_files_hadron_calib)}")
250 if "dEdxValidation" not in listOfMutedCalibrations:
251 reduced_file_to_iov_hadron_validation = filter_by_max_files_per_run(
252 file_to_iov_hadron_calib, max_files_per_run_validation, min_events_per_file)
253 input_files_hadron_validation = list(reduced_file_to_iov_hadron_validation.keys())
254 basf2.B2INFO(f
"Total number of files actually used as input for validation = {len(input_files_hadron_validation)}")
257 requested_iov = kwargs.get(
"requested_iov",
None)
259 from caf.utils
import IoV
261 output_iov = IoV(requested_iov.exp_low, requested_iov.run_low, -1, -1)
265 from ROOT
import Belle2
266 from ROOT.Belle2
import SVDdEdxCalibrationAlgorithm, SVDdEdxValidationAlgorithm
268 algo = SVDdEdxCalibrationAlgorithm()
269 algo.setMonitoringPlots(
True)
270 algo.setNumPBins(expert_config[
'NBinsP'])
271 algo.setNumDEdxBins(expert_config[
'NBinsdEdx'])
272 algo.setDEdxCutoff(expert_config[
'dedxCutoff'])
273 algo.setMinEvtsPerTree(expert_config[
'MinEvtsPerTree'])
274 algo.setNEventsToGenerate(int(expert_config[
'NEventsToGenerate']))
275 algo.setUsePionBGFunctionForEverything(expert_config[
'UsePionBGFunctionForEverything'])
276 algo.setUseProtonBGFunctionForEverything(expert_config[
'UseProtonBGFunctionForEverything'])
277 algo.setCustomProfile(expert_config[
'CustomProfile'])
278 algo.setFixUnstableFitParameter(expert_config[
'FixUnstableFitParameter'])
280 if "dEdxValidation" not in listOfMutedCalibrations:
281 algo_val = SVDdEdxValidationAlgorithm()
282 algo_val.setMonitoringPlots(
True)
283 algo_val.setMinEvtsPerTree(expert_config[
'MinEvtsPerTree'])
284 algo_val.setNumROCpoints(expert_config[
'NumROCpoints'])
285 algo_val.setMinROCMomentum(expert_config[
'MinROCMomentum'])
286 algo_val.setMaxROCMomentum(expert_config[
'MaxROCMomentum'])
287 algo_val.setNumEffBins(expert_config[
'NumEffBins'])
288 algo_val.setMaxEffMomentum(expert_config[
'MaxEffMomentum'])
289 algo_val.validationMode(validation_mode)
294 from caf.framework
import Calibration
296 rec_path = create_path(rerun_reco,
False, isMC, expert_config)
297 rec_path_validation = create_path(rerun_reco_val, rerun_pid_val, isMC, expert_config)
299 dedx_calibration = Calibration(
"SVDdEdxCalibration",
300 collector=
"SVDdEdxCollector",
302 input_files=input_files_hadron_calib,
303 pre_collector_path=rec_path)
305 if "dEdxValidation" not in listOfMutedCalibrations:
306 dedx_validation = Calibration(
"SVDdEdxValidation",
307 collector=
"SVDdEdxValidationCollector",
308 algorithms=[algo_val],
309 input_files=input_files_hadron_validation,
310 pre_collector_path=rec_path_validation)
313 for algorithm
in dedx_calibration.algorithms:
314 algorithm.params = {
"apply_iov": output_iov}
319 if "dEdxValidation" not in listOfMutedCalibrations:
320 dedx_validation.depends_on(dedx_calibration)
322 list_of_calibrations = []
323 if "dEdxCalibration" not in listOfMutedCalibrations:
324 list_of_calibrations.append(dedx_calibration)
325 if "dEdxValidation" not in listOfMutedCalibrations:
326 list_of_calibrations.append(dedx_validation)
328 return list_of_calibrations