Belle II Software release-09-00-00
caf_hotpixel_sequential.py
1#!/usr/bin/env python3
2
3
10
11# This steering file computes PXD hotpixel and deadpixel masks from root formatted raw data
12# running the CAF
13#
14# Before running, you have to put a file to IoV mapping called 'file_iov_map.pkl' in your
15# working directory. You can create such a map file by using the tool b2caf-filemap.
16# See also the option --help.
17#
18# b2caf-filemap -m raw -p "/hsm/belle2/bdata/Data/Raw/e0003/r*/**/*.root"
19#
20# This will try to compute hot pixel masks, dead pixel masks and occupancy maps for each run
21# in the given IoV range.
22#
23# The results will be collected in a folder 'pxd_calibration_results_range_XY'. In order to complete the
24# process, the check and uploads the outputdbs to a global tag (GT).
25#
26# b2conditionsdb upload Calibration_Offline_Development ./database.txt
27#
28# The option --help provides extensive help for the b2conditionsdb tool.
29
30import argparse
31from caf.strategies import SequentialRunByRun
32from caf.utils import ExpRun, IoV
33from caf import backends
34from caf.framework import Calibration, CAF
35from ROOT.Belle2 import PXDHotPixelMaskCalibrationAlgorithm
36import pickle
37import basf2 as b2
38b2.set_log_level(b2.LogLevel.INFO)
39
40
41parser = argparse.ArgumentParser(
42 description="Compute hot pixel masks for PXD from rawhit occupancy")
43parser.add_argument(
44 '--runLow',
45 default=0,
46 type=int,
47 help='Compute mask for specific IoV')
48parser.add_argument('--runHigh', default=-1, type=int,
49 help='Compute mask for specific IoV')
50parser.add_argument(
51 '--expNo',
52 default=3,
53 type=int,
54 help='Compute mask for specific IoV')
55parser.add_argument('--maxSubRuns', default=20, type=int,
56 help='Maximum number of subruns to use')
57args = parser.parse_args()
58
59
60# Ignoring runs
61pxd_ignore_run_list = [ExpRun(3, 484), ExpRun(3, 485), ExpRun(3, 486), ExpRun(3, 524)]
62
63# Set the IoV range for this calibration
64iov_to_calibrate = IoV(
65 exp_low=args.expNo,
66 run_low=args.runLow,
67 exp_high=args.expNo,
68 run_high=args.runHigh)
69
70map_file_path = "file_iov_map.pkl"
71with open(map_file_path, 'br') as map_file:
72 files_to_iovs = pickle.load(map_file)
73
74
75input_file_iov_set = set(files_to_iovs.values())
76print(f'Number of distinct iovs {len(input_file_iov_set)}')
77
78
79input_files = []
80
81for file_iov in input_file_iov_set:
82 if iov_to_calibrate.contains(file_iov):
83 subruns = [k for k, v in files_to_iovs.items() if v == file_iov]
84 input_files.extend(subruns[:args.maxSubRuns])
85
86
87print(f'Number selected input files: {len(input_files)}')
88
89# Create and configure the collector and its pre collector path
90hotpixelcollector = b2.register_module("PXDRawHotPixelMaskCollector")
91hotpixelcollector.param("granularity", "run")
92
93# The pre collector path must contain geometry and unpacker
94gearbox = b2.register_module('Gearbox')
95gearbox.param('fileName', 'geometry/Beast2_phase2.xml')
96geometry = b2.register_module('Geometry')
97geometry.param('components', ['PXD'])
98pre_collector_path = b2.create_path()
99pre_collector_path.add_module(gearbox)
100pre_collector_path.add_module(geometry)
101pre_collector_path.add_module('PXDUnpacker')
102
103
104# Create and configure the calibration algorithm
105# Getting a calibration algorithm instance
106hotpixelkiller = PXDHotPixelMaskCalibrationAlgorithm()
107# We can play around with hotpixelkiller parameters
108# Continue masking even when few/no events were collected
109hotpixelkiller.forceContinueMasking = False
110# Minimum number of collected events for masking
111hotpixelkiller.minEvents = 30000
112# Only consider dead pixel masking when median number of hits per pixel is
113# higher
114hotpixelkiller.minHits = 15
115# Occupancy threshold is median occupancy x multiplier
116hotpixelkiller.pixelMultiplier = 7
117# Set True to allow masking of hot drain lines
118hotpixelkiller.maskDrains = True
119# Occupancy threshold is median occupancy x multiplier
120hotpixelkiller.drainMultiplier = 7
121# Set True to allow masking of hot rows
122hotpixelkiller.maskRows = True
123# Occupancy threshold is median occupancy x multiplier
124hotpixelkiller.rowMultiplier = 7
125# We want to use a specific collector collecting from raw hits
126hotpixelkiller.setPrefix("PXDRawHotPixelMaskCollector")
127
128# Create a calibration
129cal = Calibration(
130 name="PXDHotPixelMaskCalibrationAlgorithm",
131 collector=hotpixelcollector,
132 algorithms=hotpixelkiller,
133 input_files=input_files)
134cal.pre_collector_path = pre_collector_path
135
136# Apply the map to this calibration, now the CAF doesn't have to do it
137cal.files_to_iovs = files_to_iovs
138
139# The SequentialRunByRun strategy executes your algorithm over runs
140# individually to give you payloads for each one (if successful)
141cal.strategies = SequentialRunByRun
142
143cal.ignored_runs = pxd_ignore_run_list
144cal.algorithms[0].params["iov_coverage"] = iov_to_calibrate
145
146cal.max_files_per_collector_job = 1
147
148# Create a CAF instance and add the calibration to it.
149cal_fw = CAF()
150cal_fw.add_calibration(cal)
151# cal_fw.backend = backends.LSF()
152cal_fw.backend = backends.Local(max_processes=20)
153# Time between polling checks to the CAF to see if a step (algorithm,
154# collector jobs) is complete
155cal_fw.heartbeat = 30
156# Can change where your calibration runs
157cal_fw.output_dir = f'calibration_results_range_{args.runLow}_{args.runHigh}'
158cal_fw.run(iov=iov_to_calibrate)
159# Should have created a directory called 'calibration_results'