ATLAS Offline Software
Loading...
Searching...
No Matches
StripDefectsEmulatorConfig.py
Go to the documentation of this file.
1#!/usr/bin/env python
2# Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3"""
4 Emulating strip defects by dropping elements from the RDO input container
5"""
6from AthenaConfiguration.AllConfigFlags import initConfigFlags
7from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
8from AthenaConfiguration.ComponentFactory import CompFactory
9
10from AthenaCommon.Constants import INFO
11
12# magic ranges indicating an even odd filter
13ODD_INDEX=[1,-2]
14EVEN_INDEX=[0,-2]
15
16def ordered_pairs(a_list) :
17 """
18 Return True if every two elements in a_list form a pair whose two elements are
19 in ascending order. The element pairs themselves may have an arbitrary order.
20 """
21 for i in range(0,len(a_list),2) :
22 if a_list[i]>a_list[i+1] :
23 if a_list != ODD_INDEX and a_list != EVEN_INDEX :
24 print (i,a_list)
25 return False
26 return True
27
28def makeCornerDefectParam(probability=1e-1,
29 min_rx=0.,
30 max_rx=4e-3,
31 min_ry=0.,
32 max_ry=4e-3,
33 min_sagitta=0.,
34 max_sagitta=2e-3) :
35 """
36 Convenience method to create a parameter set for module corner defects.
37 The corner defects have a circular shape and intersect the sensor edges at certain
38 points in x and y direction. The line between these two intersection points forms
39 a sagitta of the circle.
40 probability: Probability of a module to have one or more corner defects.
41 min_rx: minimum position from the corner in local x-direction of possible intersection points.
42 max_rx: maximum position from the corner in local x-direction of possible intersection points.
43 min_ry: minimum position from the corner in local y-direction of possible intersection points.
44 max_ry: maximum position from the corner in local x-direction of possible intersection points.
45 min_sagitta: minimum size of the sagitta (upper limit of circle radius)
46 max_sagitta: maximum size of the sagitta (lower limit of circle radius)
47 """
48 assert min_rx<max_rx
49 assert min_ry<max_ry
50 assert min_sagitta<max_sagitta
51 return [probability,
52 min_rx, max_rx-min_rx,
53 min_ry, max_ry-min_ry,
54 min_sagitta, max_sagitta-min_sagitta]
55
56def moduleDefect(bec=[-2,2],
57 layer=[0,8],
58 eta_range=[-99,99],
59 phi_range=[-99,99],
60 columns_or_strips=[0,2000],
61 column_or_strip_length=[0,1000000],
62 side_range=[0,1],
63 all_rows=True,
64 probability=[1e-2],
65 fractionsOfNDefects=[],
66 noiseProbability=None,
67 noiseShape=[],
68 cornerDefectParam=None,
69 cornerDefectNCornerFractions=None,
70 ) :
71 '''
72 Convenience function to create parameters for strip or pixel defects emulation conditions data
73 bec: range to select the bec identifier part (range is inclusive)
74 layer: range to select the layer/disc identifier part (range is inclusive)
75 eta_range: range to select the eta index identifier part (range is inclusive)
76 phi_range: range to select the phi index identifier part (range is inclusive)
77 columns_or_strips: match only modules with number of columns or strips in this range (range is inclusive)
78 column_or_strip_length: match the strip lengths in microns (range is inclusive)
79 side_range: to select both sides of a sensor [0,1], to select either side [0,0,1,1]
80 all_rows: to select individal modules (0), or all modules associated to the same physical sensor (1)
81 probabilities: module-defect, strip/pixel defect (for pixel additionally group defect probabilities:
82 at least one core-column defect, at least one defect circuit)
83 fractions: per group defect, fractions to have exactly 1..n group defects under the condition that there is
84 at least one such group defect. The first element are the fractions to have consecutive cell
85 defects of 1,2, ... n rows.
86 noiseProbability: None or probability of a strip (or pixel) to produce a spurious hit.
87 noiseShape: empty list or binned pdf used to compute one random number per spurious hit (time bin for strips, tot for pixel).
88 cornerDefectParam: None or parameters e.g. created with makeCornerDefectParam to create defects at module corners.
89 cornerDefectNCornerFractions: if cornerDefectParam is not None the fractions of 1 to 4 corners to have a defect if the module
90 has such defects.
91 '''
92 if len(fractionsOfNDefects)+2==len(probability) or len(fractionsOfNDefects) == 0:
93 # if there only fractionsOfNDefects for the group defects but not the cell defects
94 # then assume that each cell defect is only a cell defect not a defect of n-cells
95 # in consecutive rows
96 fractionsOfNDefects = [[1.]] + fractionsOfNDefects
97
98 # test that the ranges have coorect number of elements and that ranges are ordered
99 assert len(bec)%2==0 and len(bec) >= 2 and ordered_pairs(bec)
100 assert len(layer)%2==0 and len(layer) >= 2 and ordered_pairs(layer)
101 assert len(eta_range)%2==0 and len(eta_range) >= 2 and ordered_pairs(eta_range)
102 assert len(phi_range)%2==0 and len(phi_range) >= 2 and ordered_pairs(phi_range)
103 assert len(side_range)%2==0 and len(side_range) >= 2 and ordered_pairs(side_range)
104 assert len(columns_or_strips)%2==0 and len(columns_or_strips) >= 2 and ordered_pairs(columns_or_strips)
105 assert len(column_or_strip_length)%2==0 and len(column_or_strip_length) >= 2 and ordered_pairs(column_or_strip_length)
106 assert len(fractionsOfNDefects)==0 or len(fractionsOfNDefects)+1==len(probability)
107
108 assert cornerDefectParam is not None or cornerDefectNCornerFractions is None
109 assert cornerDefectParam is None or cornerDefectNCornerFractions is not None
110
111 length=[ l for l in set([len(bec),len(layer),len(eta_range),len(phi_range),len(side_range),len(columns_or_strips)]) ]
112 # every range must contain a multiple of the number of elements of every other range
113 for i in range(1,len(length)) :
114 for j in range(0,i) :
115 assert max(length[i],length[j])%min(length[i],length[j])==0
116
117 module_pattern=[]
118 prob=[]
119 fractions=[]
120 noiseProbList=[]
121 noiseShapeList=[]
122 cornerDefectList=[]
123 cornerDefectCornerFractionList=[]
124 if noiseProbability is not None and noiseProbability>0. :
125 # ensure that the the noise shape integral is 1.
126 shape_sum = sum(noiseShape)
127 noiseShape = [ elm/shape_sum for elm in noiseShape ]
128 else :
129 noiseProbability=None
130
131 for i in range(0,max(length),2) :
132 module_pattern+=[ [bec[i%len(bec)], bec[(i+1)%len(bec)],
133 layer[i%len(layer)], layer[(i+1)%len(layer)],
134 eta_range[i%len(eta_range)], eta_range[(i+1)%len(eta_range)],
135 phi_range[i%len(phi_range)], phi_range[(i+1)%len(phi_range)],
136 columns_or_strips[i%len(columns_or_strips)], columns_or_strips[(i+1)%len(columns_or_strips)],
137 column_or_strip_length[i%len(column_or_strip_length)], column_or_strip_length[(i+1)%len(column_or_strip_length)],
138 side_range[i%len(side_range)], side_range[(i+1)%len(side_range)],
139 1 if all_rows else 0] ]
140 prob += [ probability ]
141 fractions += [ [fraction for per_pattern in fractionsOfNDefects for fraction in per_pattern + [-1] ] ]
142 if noiseProbability is not None:
143 noiseProbList+=[noiseProbability]
144 noiseShapeList+=[noiseShape]
145 if cornerDefectParam is not None:
146 cornerDefectList+=[ cornerDefectParam ]
147 cornerDefectCornerFractionList+=[ cornerDefectNCornerFractions ]
148
149 return module_pattern, prob, fractions, noiseProbList, noiseShapeList, cornerDefectList, cornerDefectCornerFractionList
150
151def combineModuleDefects( defects ) :
152 '''
153 Convenience function to combine a list of outputs of calls of moduleDefect, to produce lists to
154 set the ModulePatterns, DefectProbabilities, and NDefectFractionsPerPattern etc. properties of the
155 pixel or strip DefectsEmulatorCondAlg.
156 '''
157 result=[]
158 for i in range(0,len(defects[0])) :
159 result.append( [ elm for sublist in defects for elm in sublist[i] ] )
160 return result
161
162def StripRDORemappingCfg(flags, InputKey="StripRDOs") :
163 """
164 Remapping service to rename the input strip RDO collection
165 """
166 acc = ComponentAccumulator()
167
168 from SGComps.AddressRemappingConfig import AddressRemappingCfg
169 renames = [ '%s#%s->%s' % ('SCT_RDO_Container', InputKey, f"{InputKey}_ORIG") ]
170 acc.merge(AddressRemappingCfg( renameMaps = renames ))
171 return acc
172
174 """
175 Remapping service to rename the input ITk strip RDO collection
176 """
177 return StripRDORemappingCfg(flags,"ITkStripRDOs")
178
179def DefectsHistSvcCfg(flags, HistogramGroup: str="StripDefects", FileName: str='strip_defects.root') -> ComponentAccumulator:
180 """
181 THistSvc to histogram some properties of emulated defects.
182 """
183 acc = ComponentAccumulator()
184 if HistogramGroup is not None and len(HistogramGroup) > 0 and FileName is not None and len(FileName) > 0 :
185 histSvc = CompFactory.THistSvc(Output = [f"{HistogramGroup} DATAFILE='{FileName}', OPT='RECREATE'"] )
186 acc.addService(histSvc)
187 return acc
188
189def ITkDefectsHistSvcCfg(flags, HistogramGroup="ITkStripDefects") -> ComponentAccumulator:
190 return DefectsHistSvcCfg(flags,HistogramGroup)
191
192
194 name: str = "StripDefectsEmulatorCondAlg",
195 **kwargs: dict) -> ComponentAccumulator:
196 """
197 Schedule conditions algorithm to create emulated strip defect conditions data
198 """
199 acc = ComponentAccumulator()
200 kwargs.setdefault("ModulePatterns", [[-2,2,0,99,-99,99,-99,99,0,9999,0,1,0]]) # ranges: barrel/ec, all layers, all eta, all phi, all column counts,
201 # all sides, don't auto-match connected rows
202 kwargs.setdefault("DefectProbabilities", [[0.,1.e-4]]) # only strip defects
203 kwargs.setdefault("DetEleCollKey", "StripDetectorElementCollection")
204 kwargs.setdefault("WriteKey", "StripEmulatedDefects")
205 kwargs.setdefault("IDName","SCT_ID")
206 kwargs.setdefault("HistogramGroupName","") # disable histogramming; enable: e.g. /StripDefects/EmulatedDefects/
207
208 kwargs.setdefault("RngPerDefectType",False) # If True use one RNG per defect type (module, chip-defects, core-column, pixel-defects, corner-defects)
209 kwargs.setdefault("DefectsInputFiles",[]) # If not empty read defects from input files and merge defects (root RNTuple/json; extension: .root .json")
210 kwargs.setdefault("DefectsOutputFile","") # If not empty write defects to a output file (root RNTuple/json; (extension: .root .json")
211 if "DefectsOutputFile" in kwargs and kwargs["DefectsOutputFile"] is None :
212 kwargs["DefectsOutputFile"]=""
213
214 acc.addCondAlgo(CompFactory.InDet.StripDefectsEmulatorCondAlg(name,**kwargs))
215 return acc
216
218 name: str = "ITkStripDefectsEmulatorCondAlg",
219 **kwargs: dict) -> ComponentAccumulator:
220 """
221 Schedule conditions algorithm to create emulated ITk strip defect conditions data
222 """
223 kwargs.setdefault("ModulePatterns", [[-2,2,0,99,-99,99,-99,99,0,9999,0,1,0]]) # ranges: barrel/ec, all layers, all eta, all phi,
224 # all sides, don't auto-match connected rows
225 kwargs.setdefault("DefectProbabilities", [[0.,1.e-4]]) # only strip defects
226 kwargs.setdefault("DetEleCollKey", "ITkStripDetectorElementCollection")
227 kwargs.setdefault("IDName","SCT_ID")
228 kwargs.setdefault("WriteKey", "ITkStripEmulatedDefects")
229
230 kwargs.setdefault("RngPerDefectType",False) # If True use one RNG per defect type (module, chip-defects, core-column, pixel-defects, corner-defects)
231 kwargs.setdefault("DefectsInputFiles",[]) # If not empty read defects from input files and merge defects (root RNTuple/json; extension: .root .json")
232 kwargs.setdefault("DefectsOutputFile","") # If not empty write defects to a output file (root RNTuple/json; (extension: .root .json")
233 if "DefectsOutputFile" in kwargs and kwargs["DefectsOutputFile"] is None :
234 kwargs["DefectsOutputFile"]=""
235
236 return StripDefectsEmulatorCondAlgCfg(flags,name,**kwargs)
237
238
240 name: str = "ITkStripDefectsEmulatorAlg",
241 **kwargs: dict) -> ComponentAccumulator:
242 """
243 Schedule algorithm to emulate strip defects by dropping RDOs overlapping with emulated
244 defects conditions data.
245 """
246 acc = ComponentAccumulator()
247
248 if "InputKey" not in kwargs :
249 # rename original RDO collection
250 acc.merge(StripRDORemappingCfg(flags))
251 kwargs.setdefault("InputKey","StripRDOs_ORIG")
252
253 if "EmulatedDefectsKey" not in kwargs :
254 # create defects conditions data
255 acc.merge( ITkStripDefectsEmulatorCondAlgCfg(flags))
256 kwargs.setdefault("EmulatedDefectsKey", "StripEmulatedDefects")
257 kwargs.setdefault("OutputKey","StripRDOs")
258 kwargs.setdefault("HistogramGroupName","") # disable histogramming, enable e.g. /StripDefects/RejectedRDOs/
259
260 acc.addEventAlgo(CompFactory.InDet.StripDefectsEmulatorAlg(name,**kwargs))
261 return acc
262
264 name: str = "ITkStripDefectsEmulatorAlg",
265 **kwargs: dict) -> ComponentAccumulator:
266 """
267 Schedule algorithm to emulate ITk strip defects by dropping RDOs overlapping with emulated
268 defects conditions data.
269 """
270 acc = ComponentAccumulator()
271 if "InputKey" not in kwargs :
272 # rename original RDO collection
273 acc.merge(ITkStripRDORemappingCfg(flags))
274 kwargs.setdefault("InputKey","ITkStripRDOs_ORIG")
275
276 if "EmulatedDefectsKey" not in kwargs :
277 # create defects conditions data
278 acc.merge( ITkStripDefectsEmulatorCondAlgCfg(flags))
279 kwargs.setdefault("EmulatedDefectsKey", "ITkStripEmulatedDefects")
280 kwargs.setdefault("OutputKey","ITkStripRDOs")
281
282 kwargs.setdefault("HistogramGroupName","") # disable histogramming, enable e.g. /StripDefects/RejectedRDOs/
283
284 acc.addEventAlgo(CompFactory.InDet.StripDefectsEmulatorAlg(name,**kwargs))
285 return acc
286
288 name: str = "ITkStripDefectsEmulatorToDetectorElementStatusCondAlgCfg",
289 **kwargs: dict) -> ComponentAccumulator:
290 acc = ComponentAccumulator()
291 kwargs.setdefault("EmulatedDefectsKey","ITkStripEmulatedDefects")
292 kwargs.setdefault("WriteKey","ITkStripDetectorElementStatusFromEmulatedDefects")
293 acc.addCondAlgo(CompFactory.InDet.StripEmulatedDefectsToDetectorElementStatusCondAlg(name,**kwargs))
294 return acc
295
296
297if __name__ == "__main__":
298 #
299 # Test ITk strip defect emulation
300 #
301 flags = initConfigFlags()
302
303 from AthenaConfiguration.Enums import ProductionStep
304 flags.Common.ProductionStep = ProductionStep.Simulation
305 from AthenaConfiguration.TestDefaults import defaultGeometryTags, defaultConditionsTags
306 flags.GeoModel.AtlasVersion = defaultGeometryTags.RUN4
307 flags.IOVDb.GlobalTag = defaultConditionsTags.RUN4_MC
308 flags.GeoModel.Align.Dynamic = False
309 flags.Input.Files = ['/cvmfs/atlas-nightlies.cern.ch/repo/data/data-art/PhaseIIUpgrade/RDO/ATLAS-P2-RUN4-03-00-00/mc21_14TeV.601229.PhPy8EG_A14_ttbar_hdamp258p75_SingleLep.recon.RDO.e8481_s4149_r14700/RDO.33629020._000047.pool.root.1']
310
311 flags.Detector.GeometryITkStrip = True
312 flags.Detector.GeometryITkStrip = True
313 flags.Detector.GeometryBpipe = True
314 flags.Detector.GeometryCalo = False
315
316 flags.Concurrency.NumThreads = 8
317 flags.Concurrency.NumConcurrentEvents = 8
318
319 flags.Exec.MaxEvents = 10
320
321 flags.lock()
322 flags.dump()
323
324 from AthenaConfiguration.MainServicesConfig import MainServicesCfg
325 acc = MainServicesCfg( flags )
326 from AthenaPoolCnvSvc.PoolReadConfig import PoolReadCfg
327 acc.merge(PoolReadCfg(flags))
328
329 # Need geometry
330 from ActsConfig.ActsGeometryConfig import ActsTrackingGeometrySvcCfg
331 acc.merge( ActsTrackingGeometrySvcCfg(flags,
332 OutputLevel=INFO,
333 RunConsistencyChecks=False,
334 ObjDebugOutput=False))
335
336 from SCT_ConditionsAlgorithms.ITkStripConditionsAlgorithmsConfig import ITkStripDetectorElementStatusCondAlgNoByteStreamErrorsCfg
337 acc.merge(ITkStripDetectorElementStatusCondAlgNoByteStreamErrorsCfg(flags))
338
339 # ITk strip defect configuration defined in post include
340 from StripDefectsEmulatorPostInclude import emulateITkStripDefects
341 emulateITkStripDefects(flags,acc)
342
343 acc.printConfig(withDetails=True, summariseProps=True,printDefaults=True)
344 sc = acc.run()
345
346 if sc.isFailure():
347 import sys
348 sys.exit(1)
#define min(a, b)
Definition cfImp.cxx:40
#define max(a, b)
Definition cfImp.cxx:41
STL class.
moduleDefect(bec=[-2, 2], layer=[0, 8], eta_range=[-99, 99], phi_range=[-99, 99], columns_or_strips=[0, 2000], column_or_strip_length=[0, 1000000], side_range=[0, 1], all_rows=True, probability=[1e-2], fractionsOfNDefects=[], noiseProbability=None, noiseShape=[], cornerDefectParam=None, cornerDefectNCornerFractions=None)
StripRDORemappingCfg(flags, InputKey="StripRDOs")
ComponentAccumulator ITkDefectsHistSvcCfg(flags, HistogramGroup="ITkStripDefects")
ComponentAccumulator ITkStripDefectsEmulatorToDetectorElementStatusCondAlgCfg(flags, str name="ITkStripDefectsEmulatorToDetectorElementStatusCondAlgCfg", **dict kwargs)
makeCornerDefectParam(probability=1e-1, min_rx=0., max_rx=4e-3, min_ry=0., max_ry=4e-3, min_sagitta=0., max_sagitta=2e-3)
ComponentAccumulator StripDefectsEmulatorAlgCfg(flags, str name="ITkStripDefectsEmulatorAlg", **dict kwargs)
ComponentAccumulator ITkStripDefectsEmulatorCondAlgCfg(flags, str name="ITkStripDefectsEmulatorCondAlg", **dict kwargs)
ComponentAccumulator ITkStripDefectsEmulatorAlgCfg(flags, str name="ITkStripDefectsEmulatorAlg", **dict kwargs)
ComponentAccumulator StripDefectsEmulatorCondAlgCfg(flags, str name="StripDefectsEmulatorCondAlg", **dict kwargs)
ComponentAccumulator DefectsHistSvcCfg(flags, str HistogramGroup="StripDefects", str FileName='strip_defects.root')