12PXD calibration APIs for CAF
13Author: qingyuan.liu@desy.de
16from basf2
import register_module, create_path
17from ROOT
import Belle2
18from ROOT.Belle2
import PXDHotPixelMaskCalibrationAlgorithm, PXDAnalyticGainCalibrationAlgorithm
19from ROOT.Belle2
import PXDValidationAlgorithm
20from caf.framework
import Calibration
21from caf.strategies
import SequentialRunByRun, SimpleRunByRun
23run_types = [
'beam',
'physics',
'cosmic',
'all']
24gain_methods = [
'analytic',
'generic_mc',
'cluster_sim',
'']
27def hot_pixel_mask_calibration(
29 cal_name="PXDHotPixelMaskCalibration",
36 input_files (list): A list of input files to be assigned to calibration.input_files
38 run_type ( str): The run type which will define different calibration parameters.
39 Should be in [
'beam',
'physics',
'cosmic',
'all']
41 global_tags (list): A list of
global tags
43 local_dbs (list): A list of local databases
45 **kwargs: Additional configuration to support extentions without changing scripts
in calibration folder.
46 Supported options are listed below:
48 "activate_masking" is a boolean to activate existing masking
in the payload.
49 PXDHotPixelMaskCollector will be used then instead of PXDRawHotPixelMaskCollector
51 "debug_hist" is the flag to save a ROOT file
for debug histograms.
52 "inefficientPixelMultiplier" is the multiplier on median occupancy to define an inefficient pixel.
53 0 means only dead pixels are marked
as dead.
54 A value > 0 means any pixels
with occupancy below the threshold will be marked
as dead.
55 "minInefficientPixels" is the minimum number of pixels to define a dead
or inefficient row.
56 The rows
with inefficient pixels >= this value will be marked
as dead rows
for now.
57 "deadPixelPayloadName" is the payload name used
for more defective pixel types. The default
is PXDDeadPixelPar.
60 A caf.framework.Calibration obj.
63 if global_tags
is None:
69 if not isinstance(run_type, str)
or run_type.lower()
not in run_types:
70 raise ValueError(f
"run_type not found in run_types : {run_type}")
71 activate_masking = kwargs.get(
"activate_masking",
False)
72 if not isinstance(activate_masking, bool):
73 raise ValueError(
"activate_masking is not a boolean!")
74 debug_hist = kwargs.get(
"debug_hist",
True)
75 if not isinstance(debug_hist, bool):
76 raise ValueError(
"debug_hist is not a boolean!")
77 inefficientPixelMultiplier = kwargs.get(
"inefficientPixelMultiplier", 0.)
78 if not isinstance(inefficientPixelMultiplier, float):
79 raise ValueError(
"inefficientPixelMultiplier is not a float!")
80 minInefficientPixels = kwargs.get(
"minInefficientPixels", 250)
81 if not isinstance(minInefficientPixels, int):
82 raise ValueError(
"minInefficientPixels is not an int!")
83 deadPixelPayloadName = kwargs.get(
"deadPixelPayloadName",
"PXDDeadPixelPar")
84 if not isinstance(deadPixelPayloadName, str):
85 raise ValueError(
"deadPixelPayloadName is not a str!")
89 gearbox = register_module(
'Gearbox')
90 geometry = register_module(
'Geometry')
91 geometry.param(
'components', [
'PXD'])
92 pxdunpacker = register_module(
'PXDUnpacker')
94 checker = register_module(
'PXDPostErrorChecker')
98 main.add_module(gearbox)
99 main.add_module(geometry)
100 main.add_module(pxdunpacker)
101 main.add_module(checker)
103 main.add_module(
"ActivatePXDPixelMasker")
104 main.add_module(
"PXDRawHitSorter")
107 collector_name =
"PXDRawHotPixelMaskCollector"
109 collector_name =
"PXDHotPixelMaskCollector"
110 collector = register_module(collector_name)
111 collector.param(
"granularity",
"run")
115 algorithm = PXDHotPixelMaskCalibrationAlgorithm()
116 algorithm.forceContinueMasking =
False
117 algorithm.minEvents = 30000
118 algorithm.minHits = 15
119 algorithm.pixelMultiplier = 7
120 algorithm.maskDrains =
True
121 algorithm.drainMultiplier = 7
122 algorithm.maskRows =
True
123 algorithm.rowMultiplier = 7
125 algorithm.inefficientPixelMultiplier = inefficientPixelMultiplier
127 algorithm.minInefficientPixels = minInefficientPixels
128 algorithm.deadPixelPayloadName = deadPixelPayloadName
129 algorithm.setDebugHisto(debug_hist)
130 algorithm.setPrefix(collector_name)
131 if run_type.lower() ==
'cosmic':
132 algorithm.forceContinueMasking =
True
139 algorithms=[algorithm],
140 input_files=input_files)
141 for global_tag
in global_tags:
142 cal.use_central_database(global_tag)
143 for local_db
in local_dbs:
144 cal.use_local_database(local_db)
145 cal.pre_collector_path = main
146 cal.strategies = SequentialRunByRun
150 if run_type.lower() ==
'cosmic':
151 cal.strategies = SimpleRunByRun
156def gain_calibration(input_files, cal_name="PXDGainCalibration",
157 boundaries=None, global_tags=None, local_dbs=None,
158 gain_method="Analytic", validation=True, **kwargs):
161 input_files (list): A list of input files to be assigned to calibration.input_files
163 boundaries (c++ std::vector): boundaries for iov creation
165 global_tags (list): A list of
global tags
167 local_dbs (list): A list of local databases
169 gain_method (str): A string of gain algorithm
in
170 [
'analytic',
'generic_mc',
'cluster_sim',
'']. Empty str means to skip gain
171 calibration
and validation has to be
True otherwise no algorithm will be used.
172 Caveat: Only the analytic method
is now implemented.
174 validation (bool): Adding validation algorithm
if True (default)
176 **kwargs: Additional configuration to support extentions without changing scripts
in calibration folder.
177 Supported options are listed below:
179 "collector_prefix": a string indicating which collector to be used
for gain calibration. The supported
181 PXDPerformanceVariablesCollector (default),
182 PXDPerformanceCollector(using RAVE package
for vertexing, obsolete)
183 "useClusterPosition": Flag to use cluster postion rather than track point to group pixels
for calibration.
184 "particle_type": Particle type assigned to tracks.
"e" by default.
185 "track_cuts_4gain": Track cuts used
for gain calibration.
186 "track_cuts_4eff": Track cuts used
for efficiency study.
187 "track_cuts_4res": Track cuts used
for resolution study.
190 A caf.framework.Calibration obj.
193 if global_tags
is None:
195 if local_dbs
is None:
197 if gain_method
is None:
198 gain_method =
'analytic'
199 if not isinstance(gain_method, str)
or gain_method.lower()
not in gain_methods:
200 raise ValueError(f
"gain_method not found in gain_methods : {gain_method}")
201 collector_prefix = kwargs.get(
"collector_prefix",
"PXDPerformanceVariablesCollector")
202 supported_collectors = [
"PXDPerformanceVariablesCollector",
"PXDPerformanceCollector"]
203 if not isinstance(collector_prefix, str)
or collector_prefix
not in supported_collectors:
204 raise ValueError(f
"collector_prefix not found in {supported_collectors}")
205 useClusterPosition = kwargs.get(
"useClusterPosition",
False)
206 if not isinstance(useClusterPosition, bool):
207 raise ValueError(
"useClusterPosition has to be a boolean!")
208 particle_type = kwargs.get(
"particle_type",
"e")
209 track_cuts_4gain = kwargs.get(
"track_cuts_4gain",
"p > 1.0")
210 track_cuts_4eff = kwargs.get(
"track_cuts_4eff",
"pt > 2.0")
211 track_cuts_4res = kwargs.get(
"track_cuts_4res",
"Note2019")
215 gearbox = register_module(
'Gearbox')
216 geometry = register_module(
'Geometry', useDB=
True)
217 genFitExtrapolation = register_module(
'SetupGenfitExtrapolation')
218 roiFinder = register_module(
'PXDROIFinder')
221 main.add_module(gearbox)
222 main.add_module(geometry)
223 main.add_module(genFitExtrapolation)
224 main.add_module(roiFinder)
225 main.add_module(
"ActivatePXDPixelMasker")
228 collector = register_module(collector_prefix)
229 if collector_prefix ==
"PXDPerformanceCollector":
230 main.add_module(
"PXDPerformance")
231 collector.param(
"fillEventTree",
False)
233 import modularAnalysis
as ana
237 ana.fillParticleList(f
'{p}+:gain', track_cuts_4gain, path=main)
241 ana.fillParticleList(f
'{p}+:eff', track_cuts_4eff, path=main)
243 ana.reconstructDecay(f
'vpho:eff -> {p}+:eff {p}-:eff',
'9.5<M<11.5', path=main)
252 track_cuts_4res_note2019 =
'pt>1.0 and abs(dz)<1.0 and dr<0.3'
253 track_cuts_4res_note2019 +=
' and nCDCHits>20 and nSVDHits>=8 and nPXDHits>=1'
254 track_cuts_4res_note2019 +=
' and [abs(atan(tanLambda)) < 0.5]'
255 track_cuts_4res_note2019 +=
' and [formula(pt * (1./(1. + tanLambda**2)**0.5)**0.5) > 2.0]'
258 if track_cuts_4res ==
"Note2019":
259 track_cuts_4res = track_cuts_4res_note2019
260 ana.fillParticleList(f
'{p}+:res', track_cuts_4res, path=main)
261 ana.reconstructDecay(f
'vpho:res -> {p}+:res {p}-:res',
'9.5<M<11.5', path=main)
263 ana.applyCuts(
'vpho:res',
'nParticlesInList(vpho:res)==1', path=main)
266 collector.param(
"PList4GainName", f
"{p}+:gain")
267 collector.param(
"PList4EffName",
"vpho:eff")
268 collector.param(
"PList4ResName",
"vpho:res")
269 collector.param(
"maskedDistance", 3)
270 collector.param(
"useClusterPosition", useClusterPosition)
272 collector.param(
"granularity",
"run")
273 collector.param(
"minClusterCharge", 8)
274 collector.param(
"minClusterSize", 1)
275 collector.param(
"maxClusterSize", 10)
276 collector.param(
"nBinsU", 4)
277 collector.param(
"nBinsV", 6)
278 collector.param(
"fillChargeRatioHistogram",
True)
283 validation_alg = PXDValidationAlgorithm()
284 validation_alg.setPrefix(collector_prefix)
285 validation_alg.minTrackPoints = 10
286 validation_alg.save2DHists =
True
287 validation_alg.saveD0Z0 = kwargs.get(
"saveD0Z0",
False)
288 algorithms.append(validation_alg)
291 if (gain_method !=
''):
292 algorithm = PXDAnalyticGainCalibrationAlgorithm()
293 algorithm.minClusters = 200
294 algorithm.safetyFactor = 11
295 algorithm.forceContinue =
False
296 algorithm.strategy = 0
297 algorithm.correctForward =
True
298 algorithm.useChargeRatioHistogram =
True
299 algorithm.setPrefix(collector_prefix)
301 algorithms.append(algorithm)
308 algorithms=algorithms,
309 input_files=input_files)
310 for global_tag
in global_tags:
311 cal.use_central_database(global_tag)
312 for local_db
in local_dbs:
313 cal.use_local_database(local_db)
314 cal.pre_collector_path = main
316 cal.strategies = SequentialRunByRun
def kFit(list_name, conf_level, fit_type='vertex', constraint='', daughtersUpdate=False, decay_string='', massConstraint=[], recoilMass=0, smearing=0, path=None)