Belle II Software  release-08-00-10
caf_cdcdedx.py
1 
8 
9 """
10 Airflow script for automatic CDC dEdx calibration. It is currently for the electron based
11 calibration, where at present only RunGain, injection time, Cosine and WireGain are implimented.
12 The remaining two 2D and 1D will be implimented in the near future.
13 
14 Second part called "Hadron calibration" are not compitable with CAF/AirFlow
15 and will be done offline for a while.
16 """
17 
18 import ROOT
19 from ROOT import gSystem
20 from ROOT.Belle2 import CDCDedxRunGainAlgorithm, CDCDedxCosineAlgorithm, CDCDedxWireGainAlgorithm
21 from ROOT.Belle2 import CDCDedxCosEdgeAlgorithm, CDCDedxBadWireAlgorithm, CDCDedxInjectTimeAlgorithm
22 from caf.framework import Calibration
23 from caf.strategies import SequentialRunByRun, SequentialBoundaries
24 from prompt import CalibrationSettings, INPUT_DATA_FILTERS
25 import reconstruction as recon
26 from random import seed
27 import basf2
28 
29 gSystem.Load('libreconstruction.so')
30 ROOT.gROOT.SetBatch(True)
31 
32 settings = CalibrationSettings(
33  name="CDC dedx",
34  expert_username="renu",
35  description=__doc__,
36  input_data_formats=["cdst"],
37  input_data_names=["bhabha_all_calib"],
38  expert_config={
39  "payload_boundaries": [],
40  "calib_datamode": False,
41  "maxevt_rg": 75000,
42  "maxevt_cc": 18e6,
43  "maxevt_wg": 18e6,
44  "adjustment": 1.00798,
45  "calib_mode": "full", # manual or predefined: quick or full
46  "calibration_procedure": {"rgtrail0": 0, "rgpre0": 0, "rg0": 0}
47  },
48  input_data_filters={
49  "bhabha_all_calib": [
50  INPUT_DATA_FILTERS['Run Type']['physics'],
51  INPUT_DATA_FILTERS['Data Tag']['bhabha_all_calib'],
52  INPUT_DATA_FILTERS['Data Quality Tag']['Good Or Recoverable'],
53  INPUT_DATA_FILTERS['Magnet']['On'],
54  INPUT_DATA_FILTERS['Beam Energy']['4S'],
55  INPUT_DATA_FILTERS['Beam Energy']['Continuum'],
56  INPUT_DATA_FILTERS['Beam Energy']['Scan']]},
57  depends_on=[])
58 
59 
60 def get_calibrations(input_data, **kwargs):
61  """ REQUIRED FUNCTION used by b2caf-prompt-run tool
62  This function return a list of Calibration
63  objects we assign to the CAF process
64  """
65 
66  import basf2
67  file_to_iov_physics = input_data["bhabha_all_calib"]
68 
69  expert_config = kwargs.get("expert_config")
70  calib_mode = expert_config["calib_mode"]
71 
72  # extracting parameters
73  fulldataMode = expert_config["calib_datamode"]
74  adjustment = expert_config["adjustment"]
75 
76  if fulldataMode:
77  input_files_rungain = list(file_to_iov_physics.keys())
78  input_files_coscorr = list(file_to_iov_physics.keys())
79  input_files_wiregain = list(file_to_iov_physics.keys())
80  else:
81  seed(271492)
82 
83  maxevt_rg = expert_config["maxevt_rg"]
84  maxevt_cc = expert_config["maxevt_cc"]
85  maxevt_wg = expert_config["maxevt_wg"]
86 
87  from prompt.utils import filter_by_max_events_per_run, filter_by_select_max_events_from_files
88 
89  # collection for rungains
90  max_files_for_maxevents = maxevt_rg # allevents to accp bhabha event ratio = 0.60
91  reduced_file_to_iov_rungain = filter_by_max_events_per_run(file_to_iov_physics, max_files_for_maxevents, True)
92  input_files_rungain = list(reduced_file_to_iov_rungain.keys())
93  basf2.B2INFO(f"Total number of files used for rungains = {len(input_files_rungain)}")
94 
95  # collection for cosinecorr
96  input_files_coscorr = filter_by_select_max_events_from_files(list(file_to_iov_physics.keys()), maxevt_cc)
97  basf2.B2INFO(f"Total number of files used for cosine = {len(input_files_coscorr)}")
98  if not input_files_coscorr:
99  raise ValueError(
100  f"Cosine: all requested ({maxevt_cc}) events not found")
101 
102  # collection for wiregain
103  if maxevt_wg == maxevt_cc:
104  input_files_wiregain = input_files_coscorr
105  else:
106  input_files_wiregain = filter_by_select_max_events_from_files(list(file_to_iov_physics.keys()), maxevt_wg)
107 
108  basf2.B2INFO(f"Total number of files used for wiregains = {len(input_files_wiregain)}")
109  if not input_files_wiregain:
110  raise ValueError(
111  f"WireGain: all requested ({maxevt_wg}) events not found")
112 
113  requested_iov = kwargs.get("requested_iov", None)
114  from caf.utils import ExpRun, IoV
115  output_iov = IoV(requested_iov.exp_low, requested_iov.run_low, -1, -1)
116 
117  payload_boundaries = [ExpRun(output_iov.exp_low, output_iov.run_low)]
118  payload_boundaries.extend([ExpRun(*boundary) for boundary in expert_config["payload_boundaries"]])
119  basf2.B2INFO(f"Expert set payload boundaries are: {expert_config['payload_boundaries']}")
120 
121  collector_granularity = 'all'
122  if expert_config["payload_boundaries"] is not None:
123  basf2.B2INFO('Found payload_boundaries: set collector granularity to run')
124  collector_granularity = 'run'
125 
126  if calib_mode == "full":
127  calibration_procedure = {
128  "rgtrail0": 0, # Run Gain trail (No Payload saving and take of effect of previous rungains)
129  "tgpre0": 0, # Injection time gain Pre (No payload saving)
130  "tg0": 0, # Injection time gain
131  "rgpre0": 0, # Run Gain Pre (No Payload saving)
132  "cc0": 0, # Cosine Corr Gain
133  "ce0": 0, # Cosine edge Corr Gain
134  "bd0": 0, # Bad wire
135  "wg0": 0, # WireGain Gain
136  "rg0": 0 # Final Run Gain to take Wire and Cosine correction in effect
137  }
138  elif calib_mode == "quick":
139  calibration_procedure = {
140  "rgtrail0": 0,
141  "tg0": 0,
142  "rgpre0": 0,
143  "cc0": 0,
144  "wg0": 0,
145  "rg0": 0
146  }
147  elif calib_mode == "manual":
148  calibration_procedure = expert_config["calibration_procedure"]
149  else:
150  basf2.B2FATAL(f"Calibration mode is not defined {calib_mode}, should be quick, full, or manual")
151 
152  calib_keys = list(calibration_procedure)
153  cals = [None]*len(calib_keys)
154  basf2.B2INFO(f"Run calibration mode = {calib_mode}:")
155  print(calib_keys)
156 
157  for i in range(len(cals)):
158  max_iter = calibration_procedure[calib_keys[i]]
159  alg = None
160  data_files = [input_files_rungain, input_files_coscorr, input_files_wiregain]
161  cal_name = ''.join([i for i in calib_keys[i] if not i.isdigit()])
162  if cal_name == "rg" or cal_name == "rgtrail" or cal_name == "rgpre":
163  alg = [rungain_algo(cal_name, adjustment)]
164  elif cal_name == "cc":
165  alg = [cos_algo()]
166  elif cal_name == "ce":
167  alg = [cosedge_algo()]
168  elif cal_name == "tg" or cal_name == "tgpre":
169  alg = [injection_time_algo()]
170  elif cal_name == "bd":
171  alg = [badwire_algo()]
172  elif cal_name == "wg":
173  alg = [wiregain_algo()]
174  else:
175  basf2.B2FATAL(f"The calibration is not defined, check spelling: calib {i}: {calib_keys[i]}")
176 
177  basf2.B2INFO(f"calibration for {calib_keys[i]} with number of iteration={max_iter}")
178 
179  cals[i] = CDCDedxCalibration(name=cal_name,
180  algorithms=alg,
181  input_file_dict=data_files,
182  max_iterations=max_iter,
183  collector_granularity=collector_granularity,
184  dependencies=[cals[i-1]] if i > 0 else None
185  )
186  if payload_boundaries:
187  basf2.B2INFO("Found payload_boundaries: calibration strategies set to SequentialBoundaries.")
188  if cal_name == "rg" or cal_name == "rgtrail" or cal_name == "rgpre" or cal_name == "tg" or cal_name == "tgpre":
189  cals[i].strategies = SequentialRunByRun
190  for algorithm in cals[i].algorithms:
191  algorithm.params = {"iov_coverage": output_iov}
192  if cal_name == "rgtrail" or cal_name == "rgpre" or cal_name == "tgpre":
193  cals[i].save_payloads = False
194  else:
195  cals[i].strategies = SequentialBoundaries
196  for algorithm in cals[i].algorithms:
197  algorithm.params = {"iov_coverage": output_iov, "payload_boundaries": payload_boundaries}
198 
199  else:
200  for algorithm in cals[i].algorithms:
201  algorithm.params = {"apply_iov": output_iov}
202 
203  return cals
204 
205 
206 # Precollector path
207 def pre_collector(name='rg'):
208  """
209  Define pre collection.
210  Parameters:
211  name : name of the calibration
212  rungain rg0 by Default.
213  Returns:
214  path : path for pre collection
215  """
216 
217  reco_path = basf2.create_path()
218  recon.prepare_cdst_analysis(path=reco_path)
219  if(name == "tg" or name == "tgpre"):
220  trg_bhabhaskim = reco_path.add_module("TriggerSkim", triggerLines=["software_trigger_cut&skim&accept_radee"])
221  trg_bhabhaskim.if_value("==0", basf2.Path(), basf2.AfterConditionPath.END)
222  # ps_bhabhaskim = reco_path.add_module("Prescale", prescale=0.80)
223  # ps_bhabhaskim.if_value("==0", basf2.Path(), basf2.AfterConditionPath.END)
224 
225  elif (name == "ce"):
226  trg_bhabhaskim = reco_path.add_module(
227  "TriggerSkim",
228  triggerLines=[
229  "software_trigger_cut&skim&accept_bhabha",
230  "software_trigger_cut&filter&ee_flat_90_180",
231  "software_trigger_cut&filter&ee_flat_0_19"])
232  trg_bhabhaskim.if_value("==0", basf2.Path(), basf2.AfterConditionPath.END)
233  else:
234  trg_bhabhaskim = reco_path.add_module("TriggerSkim", triggerLines=["software_trigger_cut&skim&accept_bhabha"])
235  trg_bhabhaskim.if_value("==0", basf2.Path(), basf2.AfterConditionPath.END)
236 
237  reco_path.add_module(
238  'CDCDedxCorrection',
239  relativeCorrections=False,
240  scaleCor=True,
241  runGain=True,
242  timeGain=True,
243  cosineCor=True,
244  wireGain=True,
245  twoDCell=True,
246  oneDCell=True)
247  return reco_path
248 
249 # Collector setup
250 
251 
252 def collector(granularity='all', name=''):
253  """
254  Create a cdcdedx calibration collector
255  Parameters:
256  name : name of calibration
257  granularity : granularity : all or run
258  Returns:
259  collector : collector module
260  """
261 
262  from basf2 import register_module
263  col = register_module('CDCDedxElectronCollector', cleanupCuts=True)
264  if name == "tg" or name == "tgpre":
265  CollParam = {'isRun': True, 'isInjTime': True, 'granularity': 'run'}
266 
267  elif name == "cc" or name == "ce":
268  CollParam = {'isCharge': True, 'isCosth': True, 'granularity': granularity}
269 
270  elif name == "bd":
271  isHit = True
272  CollParam = {'isWire': True, 'isDedxhit': isHit, 'isADCcorr': not isHit, 'granularity': granularity}
273 
274  elif name == "wg":
275  CollParam = {'isWire': True, 'isDedxhit': True, 'granularity': granularity}
276 
277  else:
278  CollParam = {'isRun': True, 'granularity': 'run'}
279 
280  col.param(CollParam)
281  return col
282 
283 # Rungain Algorithm setup
284 
285 
286 def rungain_algo(name, adjustment):
287  """
288  Create a rungain calibration algorithm.
289  Returns:
290  algo : rungain algorithm
291  """
292  algo = CDCDedxRunGainAlgorithm()
293  algo.setMonitoringPlots(True)
294  if name == "rg":
295  algo.setAdjustment(adjustment)
296  return algo
297 
298 # Injection Algorithm setup
299 
300 
301 def injection_time_algo():
302  """
303  Create a injection time calibration algorithm.
304  Returns:
305  algo : injection time algorithm
306  """
307  algo = CDCDedxInjectTimeAlgorithm()
308  algo.setMonitoringPlots(True)
309  return algo
310 
311 # Cosine Algorithm setup
312 
313 
314 def cos_algo():
315  """
316  Create a cosine calibration algorithm.
317  Returns:
318  algo : cosine algorithm
319  """
320  algo = CDCDedxCosineAlgorithm()
321  algo.setMonitoringPlots(True)
322  return algo
323 
324 # CosineEdge Algorithm setup
325 
326 
327 def cosedge_algo():
328  """
329  Create a cosine edge calibration algorithm.
330  Returns:
331  algo : cosine edge algorithm
332  """
333  algo = CDCDedxCosEdgeAlgorithm()
334  algo.setMonitoringPlots(True)
335  return algo
336 
337 # Badwire Algorithm setup
338 
339 
340 def badwire_algo():
341  """
342  Create a badwire calibration algorithm.
343  Returns:
344  algo : badwire algorithm
345  """
346  algo = CDCDedxBadWireAlgorithm()
347  # threshold (mean and rms) pars for dedx
348  algo.setHighFracThres(0.2)
349  algo.setMeanThres(0.4)
350  algo.setRMSThres(0.4)
351  algo.setHistPars(150, 0, 5)
352  algo.setMonitoringPlots(True)
353  return algo
354 
355 # WireGain Algorithm setup
356 
357 
358 def wiregain_algo():
359  """
360  Create a wire gain calibration algorithm.
361  Returns:
362  algo : wiregain algorithm
363  """
364  algo = CDCDedxWireGainAlgorithm()
365  algo.enableExtraPlots(True)
366  return algo
367 
368 
370  '''
371  CDCDedxCalibration is a specialized calibration for cdcdedx.
372  '''
373 
374  def __init__(self,
375  name,
376  algorithms,
377  input_file_dict,
378  max_iterations=5,
379  dependencies=None,
380  collector_granularity='All'):
381  '''
382  parameters:
383  name: name of calibration
384  algorithims: algorithm of calibration
385  input_file_dict: input files list
386  max_iterations: maximum number of iterations
387  dependenices: depends on the previous calibration
388  collector_granularity: granularity : all or run
389  '''
390  super().__init__(name=name,
391  algorithms=algorithms
392  )
393 
394  from caf.framework import Collection
395 
396  if name == "bd" or name == "wg":
397  collection = Collection(collector=collector(granularity=collector_granularity, name=name),
398  input_files=input_file_dict[2],
399  pre_collector_path=pre_collector(name)
400  )
401  elif name == "cc" or name == "ce":
402  collection = Collection(collector=collector(granularity=collector_granularity, name=name),
403  input_files=input_file_dict[1],
404  pre_collector_path=pre_collector(name)
405  )
406  else:
407  collection = Collection(collector=collector(granularity=collector_granularity, name=name),
408  input_files=input_file_dict[0],
409  pre_collector_path=pre_collector(name)
410  )
411  self.add_collection(name=name, collection=collection)
412 
413 
414  self.max_iterationsmax_iterations = max_iterations
415 
416  if dependencies is not None:
417  for dep in dependencies:
418  self.depends_on(dep)
max_iterations
maximum iterations
Definition: caf_cdcdedx.py:414
def __init__(self, name, algorithms, input_file_dict, max_iterations=5, dependencies=None, collector_granularity='All')
Definition: caf_cdcdedx.py:380