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