Belle II Software  release-08-00-10
caf_svd_time.py
1 #!/usr/bin/env python3
2 
3 
10 '''
11 Script to perform the svd time calibration with the CoG6, CoG3 and ELS3 algorithms
12 '''
13 
14 import sys
15 import datetime
16 import random
17 
18 from ROOT.Belle2 import SVDCoGTimeCalibrationAlgorithm
19 from ROOT.Belle2 import SVD3SampleCoGTimeCalibrationAlgorithm
20 from ROOT.Belle2 import SVD3SampleELSTimeCalibrationAlgorithm
21 from ROOT.Belle2 import SVDClusterTimeShifterAlgorithm
22 from ROOT.Belle2 import SVDTimeValidationAlgorithm
23 
24 import basf2 as b2
25 
26 import rawdata as raw
27 from softwaretrigger.constants import HLT_INPUT_OBJECTS
28 from tracking import add_tracking_reconstruction
29 
30 from caf.framework import Calibration
31 from caf import strategies
32 from caf.utils import IoV
33 from prompt import CalibrationSettings, INPUT_DATA_FILTERS
34 from prompt.utils import filter_by_max_events_per_run
35 
36 b2.set_log_level(b2.LogLevel.INFO)
37 
38 random.seed(42)
39 
40 now = datetime.datetime.now()
41 
42 settings = CalibrationSettings(name="caf_svd_time",
43  expert_username="gdujany",
44  description=__doc__,
45  input_data_formats=["raw"],
46  input_data_names=["hadron_calib"],
47  input_data_filters={"hadron_calib": [INPUT_DATA_FILTERS["Data Tag"]["hadron_calib"],
48  INPUT_DATA_FILTERS["Beam Energy"]["4S"],
49  INPUT_DATA_FILTERS["Beam Energy"]["Continuum"],
50  INPUT_DATA_FILTERS["Run Type"]["physics"],
51  INPUT_DATA_FILTERS["Magnet"]["On"]]},
52  depends_on=[],
53  expert_config={
54  "timeAlgorithms": ["CoG3", "ELS3", "CoG6"],
55  "listOfMutedCalibrations": [], # "rawTimeCalibration", "timeShiftCalibration", "timeValidation"
56  "max_events_per_run": 10000,
57  "max_events_per_file": 5000,
58  "isMC": False,
59  "linearCutsOnCoG3": False,
60  "upperLineParameters": [-94.0, 1.264],
61  "lowerLineParameters": [-134.0, 1.264],
62  "rangeRawTimeForIoVCoG6": [20., 80.],
63  "rangeRawTimeForIoVCoG3": [70., 140.],
64  "rangeRawTimeForIoVELS3": [20., 80.],
65  "useRawtimeForTracking": False,
66  "useSVDGrouping": True
67  })
68 
69 
71 
72 
73 def remove_module(path, name):
74 
75  new_path = b2.create_path()
76  for m in path.modules():
77  if name != m.name():
78  new_path.add_module(m)
79  return new_path
80 
81 
82 
83 NEW_RECO_DIGITS_NAME = "SVDRecoDigitsFromTracks"
84 NEW_SHAPER_DIGITS_NAME = "SVDShaperDigitsFromTracks"
85 
86 
87 def create_collector(name="SVDTimeCalibrationCollector",
88  clusters="SVDClustersFromTracks",
89  event_info="SVDEventInfo",
90  event_t0="EventT0",
91  rawBinWidth=2,
92  granularity="run",
93  minRawTimeForIoV=0.,
94  maxRawTimeForIoV=150.):
95  """
96  Simply creates a SVDTimeCalibrationCollector module with some options.
97 
98  Returns:
99  pybasf2.Module
100  """
101 
102  collector = b2.register_module("SVDTimeCalibrationCollector")
103  collector.set_name(name)
104  collector.param("SVDClustersFromTracksName", clusters)
105  collector.param("SVDEventInfoName", event_info)
106  collector.param("EventT0Name", event_t0)
107  collector.param("granularity", granularity)
108  collector.param("RawCoGBinWidth", rawBinWidth)
109  collector.param("RawTimeIoVMin", minRawTimeForIoV)
110  collector.param("RawTimeIoVMax", maxRawTimeForIoV)
111 
112  return collector
113 
114 
115 def create_validation_collector(name="SVDTimeValidationCollector",
116  clusters="SVDClusters",
117  clusters_onTracks="SVDClustersOnTracks",
118  event_t0="EventT0",
119  granularity="run"):
120  """
121  Simply creates a SVDTimeCalibrationCollector module with some options.
122 
123  Returns:
124  pybasf2.Module
125  """
126 
127  collector = b2.register_module("SVDTimeValidationCollector")
128  collector.set_name(name)
129  collector.param("SVDClustersName", clusters)
130  collector.param("SVDClustersOnTracksName", clusters_onTracks)
131  collector.param("EventT0Name", event_t0)
132  collector.param("granularity", granularity)
133 
134  return collector
135 
136 
137 def create_algorithm(
138  unique_id,
139  prefix="",
140  min_entries=10000,
141  linearCutsOnCoG3=False,
142  interceptUpperLine=-94.0,
143  angularCoefficientUpperLine=1.264,
144  interceptLowerLine=-134.0,
145  angularCoefficientLowerLine=1.264):
146  """
147  Simply creates a SVDCoGTimeCalibrationAlgorithm class with some options.
148 
149  Returns:
150  ROOT.Belle2.SVDCoGTimeCalibrationAlgorithm
151  """
152  if "CoG6" in prefix:
153  algorithm = SVDCoGTimeCalibrationAlgorithm(unique_id)
154  if "CoG3" in prefix:
155  algorithm = SVD3SampleCoGTimeCalibrationAlgorithm(unique_id)
156  algorithm.setTwoLineSelectionParameters(
157  linearCutsOnCoG3,
158  interceptUpperLine,
159  angularCoefficientUpperLine,
160  interceptLowerLine,
161  angularCoefficientLowerLine)
162  if "ELS3" in prefix:
163  algorithm = SVD3SampleELSTimeCalibrationAlgorithm(unique_id)
164  if prefix:
165  algorithm.setPrefix(prefix)
166  algorithm.setMinEntries(min_entries)
167 
168  return algorithm
169 
170 
171 def create_validation_algorithm(prefix="", min_entries=10000):
172  """
173  Simply creates a SVDCoGTimeValidationAlgorithm class with some options.
174 
175  Returns:
176  ROOT.Belle2.SVDCoGTimeValidationAlgorithm
177  """
178  algorithm = SVDTimeValidationAlgorithm()
179  if prefix:
180  algorithm.setPrefix(prefix)
181  algorithm.setMinEntries(min_entries)
182 
183  return algorithm
184 
185 
186 def create_svd_clusterizer(name="ClusterReconstruction",
187  clusters="SVDClustersFromTracks",
188  reco_digits=None,
189  shaper_digits=None,
190  time_algorithm="CoG6",
191  get_3sample_raw_time=False,
192  shiftSVDClusterTime=None):
193  """
194  Simply creates a SVDClusterizer module with some options.
195 
196  Returns:
197  pybasf2.Module
198  """
199 
200  cluster = b2.register_module("SVDClusterizer")
201  cluster.set_name(name)
202  cluster.param("Clusters", clusters)
203  if shaper_digits is not None:
204  cluster.param("ShaperDigits", shaper_digits)
205  cluster.param("timeAlgorithm6Samples", time_algorithm)
206  if shiftSVDClusterTime is not None:
207  cluster.param("shiftSVDClusterTime", shiftSVDClusterTime)
208  cluster.param("useDB", False)
209  if get_3sample_raw_time:
210  cluster.param("returnClusterRawTime", True)
211  return cluster
212 
213 
214 def create_pre_collector_path(
215  clusterizers,
216  isMC=False,
217  max_events_per_run=10000,
218  max_events_per_file=10000,
219  useSVDGrouping=True,
220  useRawtimeForTracking=False,
221  is_validation=False):
222  """
223  Create a basf2 path that runs a common reconstruction path and also runs several SVDSimpleClusterizer
224  modules with different configurations. This way they re-use the same reconstructed objects.
225 
226  Parameters:
227  clusterizers (list[pybasf2.Module]): All the differently configured
228  SVDSimpleClusterizer modules. They should output to different datastore objects.
229  max_events_per_run (int, optional): Max events read per run. Defaults to 10000.
230  is_validation (bool, optional): Is used to produce the validation plots. Defaults to False.
231 
232  returns:
233  pybasf2.Path
234  """
235  # Set-up re-processing path
236  path = b2.create_path()
237 
238  # Read from file only what is needed
239  if not isMC:
240  path.add_module("RootInput", branchNames=HLT_INPUT_OBJECTS, entrySequences=[f'0:{max_events_per_file - 1}'])
241  else:
242  path.add_module("RootInput")
243 
244  # unpack raw data to do the tracking
245  if not isMC:
246  raw.add_unpackers(path, components=['PXD', 'SVD', 'CDC'])
247  else:
248  path.add_module("Gearbox")
249  path.add_module("Geometry")
250 
251  # proceed only if we acquired 6-sample strips
252  skim6SampleEvents = b2.register_module("SVD6SampleEventSkim")
253  path.add_module(skim6SampleEvents)
254  emptypath = b2.create_path()
255  skim6SampleEvents.if_false(emptypath)
256 
257  if not isMC:
258  # run tracking reconstruction
259  add_tracking_reconstruction(path, append_full_grid_cdc_eventt0=True)
260  path = remove_module(path, "V0Finder")
261  if not is_validation:
262  # if we would like using the grouping (True by default), we should use the calibrated cluster time
263  # if we would like to use the raw time, than the cluster grouping parameters are OK only for CoG3
264  # in the reconstruction (default in reconstruction)
265  b2.set_module_parameters(path, 'SVDClusterizer', returnClusterRawTime=useRawtimeForTracking)
266  if useSVDGrouping:
267  if useRawtimeForTracking:
268  b2.set_module_parameters(path, 'SVDTimeGrouping',
269  forceGroupingFromDB=False,
270  useParamFromDB=False,
271  isEnabledIn6Samples=True,
272  acceptSigmaN=5,
273  expectedSignalTimeCenter=100,
274  expectedSignalTimeMin=70, expectedSignalTimeMax=130,
275  tRangeLow=-20, tRangeHigh=220)
276  b2.set_module_parameters(path, 'SVDSpacePointCreator',
277  forceGroupingFromDB=False,
278  useParamFromDB=False,
279  useSVDGroupInfoIn6Sample=True,
280  numberOfSignalGroups=2, formSingleSignalGroup=True)
281  else:
282  b2.set_module_parameters(path, 'SVDTimeGrouping',
283  forceGroupingFromDB=False,
284  useParamFromDB=False,
285  isEnabledIn6Samples=True, acceptSigmaN=3,
286  expectedSignalTimeMin=-30, expectedSignalTimeMax=30)
287  b2.set_module_parameters(path, 'SVDSpacePointCreator',
288  forceGroupingFromDB=False,
289  useSVDGroupInfoIn6Sample=True)
290  else:
291  b2.set_module_parameters(path, 'SVDTimeGrouping', forceGroupingFromDB=False, isEnabledIn6Samples=False)
292  b2.set_module_parameters(path, 'SVDSpacePointCreator', forceGroupingFromDB=False, useSVDGroupInfoIn6Sample=False)
293 
294  # repeat svd reconstruction using only SVDShaperDigitsFromTracks
295  path.add_module("SVDShaperDigitsFromTracks")
296 
297  for cluster in clusterizers:
298  path.add_module(cluster)
299 
300  path = remove_module(path, "SVDMissingAPVsClusterCreator")
301 
302  return path
303 
304 
305 def get_calibrations(input_data, **kwargs):
306 
307  file_to_iov_physics = input_data["hadron_calib"]
308  expert_config = kwargs.get("expert_config")
309  timeAlgorithms = expert_config["timeAlgorithms"]
310  listOfMutedCalibrations = expert_config["listOfMutedCalibrations"]
311  max_events_per_run = expert_config["max_events_per_run"] # Maximum number of events selected per each run
312  max_events_per_file = expert_config["max_events_per_file"] # Maximum number of events selected per each file
313  isMC = expert_config["isMC"]
314  linearCutsOnCoG3 = expert_config["linearCutsOnCoG3"]
315  upperLineParameters = expert_config["upperLineParameters"]
316  lowerLineParameters = expert_config["lowerLineParameters"]
317  rangeRawTimeForIoVCoG6 = expert_config["rangeRawTimeForIoVCoG6"]
318  rangeRawTimeForIoVCoG3 = expert_config["rangeRawTimeForIoVCoG3"]
319  rangeRawTimeForIoVELS3 = expert_config["rangeRawTimeForIoVELS3"]
320  useSVDGrouping = expert_config["useSVDGrouping"]
321  useRawtimeForTracking = expert_config["useRawtimeForTracking"]
322 
323  reduced_file_to_iov_physics = filter_by_max_events_per_run(file_to_iov_physics,
324  max_events_per_run, random_select=True,
325  max_events_per_file=max_events_per_file)
326  good_input_files = list(reduced_file_to_iov_physics.keys())
327 
328  b2.B2INFO(f"Total number of files used as input = {len(good_input_files)}")
329 
330  exps = [i.exp_low for i in reduced_file_to_iov_physics.values()]
331  runs = sorted([i.run_low for i in reduced_file_to_iov_physics.values()])
332 
333  firstRun = runs[0]
334  lastRun = runs[-1]
335  expNum = exps[0]
336 
337  if not len(good_input_files):
338  print("No good input files found! Check that the input files have entries != 0!")
339  sys.exit(1)
340 
341  cog6_suffix = "_CoG6"
342  cog3_suffix = "_CoG3"
343  els3_suffix = "_ELS3"
344 
345  calType = "Prompt"
346  if isMC:
347  calType = "MC"
348  unique_id_cog6 = f"SVDCoGTimeCalibrations_{calType}_{now.isoformat()}_INFO:_3rdOrderPol_TBindep_" \
349  f"Exp{expNum}_runsFrom{firstRun}to{lastRun}"
350  print(f"\nUniqueID_CoG6:\n{unique_id_cog6}")
351 
352  unique_id_cog3 = f"SVD3SampleCoGTimeCalibrations_{calType}_{now.isoformat()}_INFO:_3rdOrderPol_TBindep_" \
353  f"Exp{expNum}_runsFrom{firstRun}to{lastRun}"
354  print(f"\nUniqueID_CoG3:\n{unique_id_cog3}")
355 
356  unique_id_els3 = f"SVD3SampleELSTimeCalibrations_{calType}_{now.isoformat()}_INFO:_TBindep_" \
357  f"Exp{expNum}_runsFrom{firstRun}to{lastRun}"
358  print(f"\nUniqueID_ELS3:\n{unique_id_els3}")
359 
360  requested_iov = kwargs.get("requested_iov", None)
361  output_iov = IoV(requested_iov.exp_low, requested_iov.run_low, -1, -1)
362 
363 
367  list_of_calibrations = []
368 
369 
372 
373  cog6 = create_svd_clusterizer(
374  name=f"ClusterReconstruction{cog6_suffix}",
375  clusters=f"SVDClustersFromTracks{cog6_suffix}",
376  reco_digits=NEW_RECO_DIGITS_NAME,
377  shaper_digits=NEW_SHAPER_DIGITS_NAME,
378  time_algorithm="CoG6",
379  get_3sample_raw_time=True)
380 
381  cog3 = create_svd_clusterizer(
382  name=f"ClusterReconstruction{cog3_suffix}",
383  clusters=f"SVDClustersFromTracks{cog3_suffix}",
384  reco_digits=NEW_RECO_DIGITS_NAME,
385  shaper_digits=NEW_SHAPER_DIGITS_NAME,
386  time_algorithm="CoG3",
387  get_3sample_raw_time=True)
388 
389  els3 = create_svd_clusterizer(
390  name=f"ClusterReconstruction{els3_suffix}",
391  clusters=f"SVDClustersFromTracks{els3_suffix}",
392  reco_digits=NEW_RECO_DIGITS_NAME,
393  shaper_digits=NEW_SHAPER_DIGITS_NAME,
394  time_algorithm="ELS3",
395  get_3sample_raw_time=True)
396 
397 
400  eventInfo = "SVDEventInfo"
401  if isMC:
402  eventInfo = "SVDEventInfoSim"
403 
404  coll_cog6 = create_collector(
405  name=f"SVDTimeCalibrationCollector{cog6_suffix}",
406  clusters=f"SVDClustersFromTracks{cog6_suffix}",
407  event_info=eventInfo,
408  event_t0="EventT0",
409  minRawTimeForIoV=rangeRawTimeForIoVCoG6[0],
410  maxRawTimeForIoV=rangeRawTimeForIoVCoG6[1])
411 
412  algo_cog6 = create_algorithm(
413  unique_id_cog6,
414  prefix=coll_cog6.name(),
415  min_entries=10000)
416 
417  coll_cog3 = create_collector(
418  name=f"SVDTimeCalibrationCollector{cog3_suffix}",
419  clusters=f"SVDClustersFromTracks{cog3_suffix}",
420  event_info=eventInfo,
421  rawBinWidth=1,
422  event_t0="EventT0",
423  minRawTimeForIoV=rangeRawTimeForIoVCoG3[0],
424  maxRawTimeForIoV=rangeRawTimeForIoVCoG3[1])
425 
426  algo_cog3 = create_algorithm(
427  unique_id_cog3,
428  prefix=coll_cog3.name(),
429  min_entries=10000,
430  linearCutsOnCoG3=linearCutsOnCoG3,
431  interceptUpperLine=upperLineParameters[0],
432  angularCoefficientUpperLine=upperLineParameters[1],
433  interceptLowerLine=lowerLineParameters[0],
434  angularCoefficientLowerLine=lowerLineParameters[1])
435 
436  coll_els3 = create_collector(
437  name=f"SVDTimeCalibrationCollector{els3_suffix}",
438  clusters=f"SVDClustersFromTracks{els3_suffix}",
439  event_info=eventInfo,
440  event_t0="EventT0",
441  minRawTimeForIoV=rangeRawTimeForIoVELS3[0],
442  maxRawTimeForIoV=rangeRawTimeForIoVELS3[1])
443 
444  algo_els3 = create_algorithm(
445  unique_id_els3,
446  prefix=coll_els3.name(),
447  min_entries=10000)
448 
449 
453 
454  # Check what time algorithms (CoG6, CoG3, ELS3) will be calibrated according to expert input
455  list_of_clusterizers = []
456  list_of_algorithms = []
457  for a in timeAlgorithms:
458  if a == "CoG3":
459  list_of_clusterizers.append(cog3)
460  list_of_algorithms.append(algo_cog3)
461  if a == "CoG6":
462  list_of_clusterizers.append(cog6)
463  list_of_algorithms.append(algo_cog6)
464  if a == "ELS3":
465  list_of_clusterizers.append(els3)
466  list_of_algorithms.append(algo_els3)
467 
468  pre_collector_path = create_pre_collector_path(
469  clusterizers=list_of_clusterizers,
470  isMC=isMC, max_events_per_run=max_events_per_run,
471  max_events_per_file=max_events_per_file,
472  useSVDGrouping=useSVDGrouping, useRawtimeForTracking=useRawtimeForTracking)
473 
474  # Decide what collector will be "managed" by the CAF
475  collector_managed_by_CAF = coll_els3
476  if "ELS3" in timeAlgorithms:
477  collector_managed_by_CAF = coll_els3
478  if "CoG6" in timeAlgorithms:
479  pre_collector_path.add_module(coll_cog6)
480  if "CoG3" in timeAlgorithms:
481  pre_collector_path.add_module(coll_cog3)
482  # We leave the coll_els3 to be the one "managed" by the CAF
483 
484  elif "CoG3" in timeAlgorithms:
485  collector_managed_by_CAF = coll_cog3
486  if "CoG6" in timeAlgorithms:
487  pre_collector_path.add_module(coll_cog6)
488  else:
489  collector_managed_by_CAF = coll_cog6
490 
491  # calibration setup
492  calibration = Calibration("SVDTime",
493  collector=collector_managed_by_CAF, # The other collectors are in the pre_collector_path itself
494  algorithms=list_of_algorithms,
495  input_files=good_input_files,
496  pre_collector_path=pre_collector_path)
497 
498  calibration.strategies = strategies.SequentialBoundaries
499 
500  for algorithm in calibration.algorithms:
501  algorithm.params = {"iov_coverage": output_iov}
502 
503  if "rawTimeCalibration" not in listOfMutedCalibrations:
504  list_of_calibrations.append(calibration)
505 
506 
509 
510  SVDClustersOnTrackPrefix = "SVDClustersOnTrack"
511 
512  shift_clusterizers_onTracks = []
513  for alg in timeAlgorithms:
514  cluster = create_svd_clusterizer(
515  name=f"ClusterReconstruction_{alg}",
516  clusters=f"{SVDClustersOnTrackPrefix}_{alg}",
517  shaper_digits=NEW_SHAPER_DIGITS_NAME,
518  time_algorithm=alg,
519  shiftSVDClusterTime=False)
520  shift_clusterizers_onTracks.append(cluster)
521 
522  shift_pre_collector_path = create_pre_collector_path(
523  clusterizers=shift_clusterizers_onTracks,
524  isMC=isMC, max_events_per_run=max_events_per_run,
525  max_events_per_file=max_events_per_file,
526  useSVDGrouping=useSVDGrouping)
527 
528  shift_collector = b2.register_module("SVDClusterTimeShifterCollector")
529  shift_collector.set_name("SVDClusterTimeShifterCollector")
530  shift_collector.param("MaxClusterSize", 6)
531  shift_collector.param("EventT0Name", "EventT0")
532  shift_collector.param("SVDClustersOnTrackPrefix", f"{SVDClustersOnTrackPrefix}")
533  shift_collector.param("TimeAlgorithms", timeAlgorithms)
534 
535  shift_algo = SVDClusterTimeShifterAlgorithm(f"{calType}_{now.isoformat()}_INFO:_"
536  f"Exp{expNum}_runsFrom{firstRun}to{lastRun}")
537  shift_algo.setMinEntries(100)
538  shift_algo.setMaximumAllowedShift(15.)
539  shift_algo.setTimeAlgorithm(timeAlgorithms)
540 
541  shift_calibration = Calibration("SVDClusterTimeShifter",
542  collector=shift_collector,
543  algorithms=shift_algo,
544  input_files=good_input_files,
545  pre_collector_path=shift_pre_collector_path)
546 
547  shift_calibration.strategies = strategies.SingleIOV
548 
549  for algorithm in shift_calibration.algorithms:
550  algorithm.params = {"apply_iov": output_iov}
551 
552  if "timeShiftCalibration" not in listOfMutedCalibrations:
553  list_of_calibrations.append(shift_calibration)
554 
555 
558 
559  val_cog6 = create_svd_clusterizer(
560  name=f"ClusterReconstruction{cog6_suffix}",
561  clusters=f"SVDClusters{cog6_suffix}",
562  time_algorithm="CoG6")
563 
564  val_cog6_onTracks = create_svd_clusterizer(
565  name=f"ClusterReconstruction{cog6_suffix}_onTracks",
566  clusters=f"SVDClusters{cog6_suffix}_onTracks",
567  reco_digits=NEW_RECO_DIGITS_NAME,
568  shaper_digits=NEW_SHAPER_DIGITS_NAME,
569  time_algorithm="CoG6")
570 
571  val_cog3 = create_svd_clusterizer(
572  name=f"ClusterReconstruction{cog3_suffix}",
573  clusters=f"SVDClusters{cog3_suffix}",
574  time_algorithm="CoG3")
575 
576  val_cog3_onTracks = create_svd_clusterizer(
577  name=f"ClusterReconstruction{cog3_suffix}_onTracks",
578  clusters=f"SVDClusters{cog3_suffix}_onTracks",
579  reco_digits=NEW_RECO_DIGITS_NAME,
580  shaper_digits=NEW_SHAPER_DIGITS_NAME,
581  time_algorithm="CoG3")
582 
583  val_els3 = create_svd_clusterizer(
584  name=f"ClusterReconstruction{els3_suffix}",
585  clusters=f"SVDClusters{els3_suffix}",
586  time_algorithm="ELS3")
587 
588  val_els3_onTracks = create_svd_clusterizer(
589  name=f"ClusterReconstruction{els3_suffix}_onTracks",
590  clusters=f"SVDClusters{els3_suffix}_onTracks",
591  reco_digits=NEW_RECO_DIGITS_NAME,
592  shaper_digits=NEW_SHAPER_DIGITS_NAME,
593  time_algorithm="ELS3")
594 
595  val_coll_cog6 = create_validation_collector(
596  name=f"SVDTimeValidationCollector{cog6_suffix}",
597  clusters=f"SVDClusters{cog6_suffix}",
598  clusters_onTracks=f"SVDClusters{cog6_suffix}_onTracks",
599  event_t0="EventT0")
600 
601  val_algo_cog6 = create_validation_algorithm(
602  prefix=val_coll_cog6.name(),
603  min_entries=10000)
604 
605  val_coll_cog3 = create_validation_collector(
606  name=f"SVDTimeValidationCollector{cog3_suffix}",
607  clusters=f"SVDClusters{cog3_suffix}",
608  clusters_onTracks=f"SVDClusters{cog3_suffix}_onTracks",
609  event_t0="EventT0")
610 
611  val_algo_cog3 = create_validation_algorithm(
612  prefix=val_coll_cog3.name(),
613  min_entries=10000)
614 
615  val_coll_els3 = create_validation_collector(
616  name=f"SVDTimeValidationCollector{els3_suffix}",
617  clusters=f"SVDClusters{els3_suffix}",
618  clusters_onTracks=f"SVDClusters{els3_suffix}_onTracks",
619  event_t0="EventT0")
620 
621  val_algo_els3 = create_validation_algorithm(
622  prefix=val_coll_els3.name(),
623  min_entries=10000)
624 
625  list_of_val_clusterizers = []
626  list_of_val_algorithms = []
627  for a in timeAlgorithms:
628  if a == "CoG3":
629  list_of_val_clusterizers.append(val_cog3)
630  list_of_val_clusterizers.append(val_cog3_onTracks)
631  list_of_val_algorithms.append(val_algo_cog3)
632  if a == "CoG6":
633  list_of_val_clusterizers.append(val_cog6)
634  list_of_val_clusterizers.append(val_cog6_onTracks)
635  list_of_val_algorithms.append(val_algo_cog6)
636  if a == "ELS3":
637  list_of_val_clusterizers.append(val_els3)
638  list_of_val_clusterizers.append(val_els3_onTracks)
639  list_of_val_algorithms.append(val_algo_els3)
640 
641  val_pre_collector_path = create_pre_collector_path(
642  clusterizers=list_of_val_clusterizers,
643  isMC=isMC, max_events_per_run=max_events_per_run,
644  max_events_per_file=max_events_per_file,
645  useSVDGrouping=useSVDGrouping, useRawtimeForTracking=useRawtimeForTracking,
646  is_validation=True)
647 
648  val_collector_managed_by_CAF = val_coll_els3
649  if "ELS3" in timeAlgorithms:
650  val_collector_managed_by_CAF = val_coll_els3
651  if "CoG6" in timeAlgorithms:
652  val_pre_collector_path.add_module(val_coll_cog6)
653  if "CoG3" in timeAlgorithms:
654  val_pre_collector_path.add_module(val_coll_cog3)
655  elif "CoG3" in timeAlgorithms:
656  val_collector_managed_by_CAF = val_coll_cog3
657  if "CoG6" in timeAlgorithms:
658  val_pre_collector_path.add_module(val_coll_cog6)
659  else:
660  val_collector_managed_by_CAF = val_coll_cog6
661 
662  val_calibration = Calibration("SVDTimeValidation",
663  collector=val_collector_managed_by_CAF,
664  algorithms=list_of_val_algorithms,
665  input_files=good_input_files,
666  pre_collector_path=val_pre_collector_path)
667 
668  val_calibration.strategies = strategies.SequentialRunByRun
669 
670  for algorithm in val_calibration.algorithms:
671  algorithm.params = {"iov_coverage": output_iov}
672 
673  if "timeValidation" not in listOfMutedCalibrations:
674  list_of_calibrations.append(val_calibration)
675 
676  for item in range(len(list_of_calibrations) - 1):
677  list_of_calibrations[item + 1].depends_on(list_of_calibrations[item])
678 
679  return list_of_calibrations