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