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