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