9 """Per-particle position-net plots for true multiplicity n."""
10 g = helper.addGroup(alg, f
'PixelNNPosN{n}',
11 f
'/PixelNNMonitor/PositionNet/{n}Particle/')
13 g.defineHistogram(
'resX;h_resX', type=
'TH1F',
14 title=f
'{n}-particle residual X (NN - truth);#Deltax [#mum];Entries',
15 xbins=100, xmin=-rng, xmax=rng)
16 g.defineHistogram(
'resY;h_resY', type=
'TH1F',
17 title=f
'{n}-particle residual Y (NN - truth);#Deltay [#mum];Entries',
18 xbins=100, xmin=-rng, xmax=rng)
19 g.defineHistogram(
'pullX;h_pullX', type=
'TH1F',
20 title=f
'{n}-particle pull X (NN - truth)/#sigma_{{NN}};pull_{{X}};Entries',
21 xbins=100, xmin=-5, xmax=5)
22 g.defineHistogram(
'pullY;h_pullY', type=
'TH1F',
23 title=f
'{n}-particle pull Y (NN - truth)/#sigma_{{NN}};pull_{{Y}};Entries',
24 xbins=100, xmin=-5, xmax=5)
25 g.defineHistogram(
'errX;h_errX', type=
'TH1F',
26 title=f
'{n}-particle predicted #sigma_{{X}};#sigma_{{X}} [#mum];Entries',
27 xbins=100, xmin=0, xmax=60)
28 g.defineHistogram(
'errY;h_errY', type=
'TH1F',
29 title=f
'{n}-particle predicted #sigma_{{Y}};#sigma_{{Y}} [#mum];Entries',
30 xbins=100, xmin=0, xmax=60)
31 g.defineHistogram(
'eta,pullY;h_pullY_vs_eta', type=
'TH2F',
32 title=f
'{n}-particle pull Y vs #eta;#eta;pull_{{Y}}',
33 xbins=30, xmin=-3, xmax=3, ybins=50, ymin=-5, ymax=5)
34 g.defineHistogram(
'nCell,pullX;h_pullX_vs_nCell', type=
'TH2F',
35 title=f
'{n}-particle pull X vs cluster size;N_{{cells}};pull_{{X}}',
36 xbins=15, xmin=0.5, xmax=15.5, ybins=50, ymin=-5, ymax=5)
37 g.defineHistogram(
'nCell,pullY;h_pullY_vs_nCell', type=
'TH2F',
38 title=f
'{n}-particle pull Y vs cluster size;N_{{cells}};pull_{{Y}}',
39 xbins=15, xmin=0.5, xmax=15.5, ybins=50, ymin=-5, ymax=5)
43 """Pixel-NN performance histograms.
45 NumberNet/ - number-of-particles (cluster-splitting) classification.
46 PositionNet/ - per-particle position residual / pull vs the Geant4 truth,
47 split by true multiplicity (1/2/3 particle). The position net
48 is run with the track estimate as input (as in on-track reco)
49 but the residual is always against truth, never the track.
53 num = helper.addGroup(alg,
'PixelNNNumber',
'/PixelNNMonitor/NumberNet/')
54 num.defineHistogram(
'predN;h_predN', type=
'TH1I',
55 title=
'Predicted N particles;N_{pred};Clusters', xbins=3, xmin=0.5, xmax=3.5)
57 num.defineHistogram(f
'prob{p};h_prob{p}', type=
'TH1F',
58 title=f
'P({p} particle);P({p});Clusters', xbins=100, xmin=0, xmax=1)
59 num.defineHistogram(
'nClusters;h_nClusters', type=
'TH1I',
60 title=
'Clusters per event;N_{clusters};Events', xbins=200, xmin=0, xmax=20000)
62 num.defineHistogram(
'trueN,predNconf;h_confusion', type=
'TH2I',
63 title=
'Number-net confusion;N_{true};N_{pred}',
64 xbins=3, xmin=0.5, xmax=3.5, ybins=3, ymin=0.5, ymax=3.5)
65 num.defineHistogram(
'isCorrect;h_correct', type=
'TH1I',
66 title=
'Correctly classified;correct;Clusters', xbins=2, xmin=-0.5, xmax=1.5)
67 num.defineHistogram(
'eta,isCorrect;h_acc_vs_eta', type=
'TProfile',
68 title=
'Classification accuracy vs #eta;#eta;accuracy', xbins=50, xmin=-3, xmax=3)
69 num.defineHistogram(
'nCell,isCorrect;h_acc_vs_nCell', type=
'TProfile',
70 title=
'Classification accuracy vs cluster size;N_{cells};accuracy',
71 xbins=15, xmin=0.5, xmax=15.5)
72 num.defineHistogram(
'trueN,probMulti;h_probMulti_vs_trueN', type=
'TH2F',
73 title=
'Split discriminant P(#geq2) vs N_{true};N_{true};P(#geq2)',
74 xbins=3, xmin=0.5, xmax=3.5, ybins=50, ymin=0, ymax=1)
80 sf = helper.addGroup(alg,
'PixelNNSplitFrac',
'/PixelNNMonitor/SplitFraction/')
81 ptEdges = [0.5 * 100.0 ** (i / 20.0)
for i
in range(21)]
82 for var, edges, label
in (
83 (
'trackPt', ptEdges,
'p_{T}^{lead} [GeV]'),
84 (
'trkPhi', {
'nb': 24,
'lo': -0.6,
'hi': 0.6},
'track incidence #phi [rad]'),
85 (
'trkTheta', {
'nb': 24,
'lo': -1.2,
'hi': 1.2},
'track incidence #theta [rad]'),
86 (
'clusEta', {
'nb': 40,
'lo': -4.0,
'hi': 4.0},
'cluster #eta')):
87 for curve, cname
in ((
'truthSplit',
'Truth'), (
'nnSplit',
'NN'),
88 (
'recoSplit',
'Reco')):
89 binning = ({
'xbins': edges}
if isinstance(edges, list)
else
90 {
'xbins': edges[
'nb'],
'xmin': edges[
'lo'],
92 sf.defineHistogram(f
'{var},{curve};h_{curve}_vs_{var}',
94 title=f
'{cname} split fraction;{label};split fraction',
100 dq = helper.addGroup(alg,
'PixelNNPosDQ',
'/PixelNNMonitor/PositionNet/DQ/')
101 dq.defineHistogram(
'posDeltaXWide;h_deltaX_wide', type=
'TH1F',
102 title=
'#DeltaX wide range;#DeltaX [mm];Entries', xbins=200, xmin=-1.0, xmax=1.0)
103 dq.defineHistogram(
'posDeltaYWide;h_deltaY_wide', type=
'TH1F',
104 title=
'#DeltaY wide range;#DeltaY [mm];Entries', xbins=200, xmin=-5.0, xmax=5.0)
105 dq.defineHistogram(
'posErrXWide;h_errX_wide', type=
'TH1F',
106 title=
'#sigma_{X} wide range;#sigma_{X} [mm];Entries', xbins=200, xmin=0, xmax=1.0)
107 dq.defineHistogram(
'posErrYWide;h_errY_wide', type=
'TH1F',
108 title=
'#sigma_{Y} wide range;#sigma_{Y} [mm];Entries', xbins=200, xmin=0, xmax=5.0)
109 dq.defineHistogram(
'posPrecX;h_precX', type=
'TH1F',
110 title=
'Precision X (1/#sigma^{2}_{X});Prec_{X} [mm^{-2}];Entries', xbins=200, xmin=0, xmax=1e6)
111 dq.defineHistogram(
'posPrecY;h_precY', type=
'TH1F',
112 title=
'Precision Y (1/#sigma^{2}_{Y});Prec_{Y} [mm^{-2}];Entries', xbins=200, xmin=0, xmax=1e5)
115 ex = helper.addGroup(alg,
'PixelNNExtremes',
'/PixelNNMonitor/Extremes/')
116 ex.defineHistogram(
'evtMinErrX;h_evtMinErrX', type=
'TH1F',
117 title=
'Per-event min #sigma_{X};min #sigma_{X} [mm];Events', xbins=100, xmin=0, xmax=0.05)
118 ex.defineHistogram(
'evtMaxErrX;h_evtMaxErrX', type=
'TH1F',
119 title=
'Per-event max #sigma_{X};max #sigma_{X} [mm];Events', xbins=100, xmin=0, xmax=0.5)
120 ex.defineHistogram(
'evtMinErrY;h_evtMinErrY', type=
'TH1F',
121 title=
'Per-event min #sigma_{Y};min #sigma_{Y} [mm];Events', xbins=100, xmin=0, xmax=0.1)
122 ex.defineHistogram(
'evtMaxErrY;h_evtMaxErrY', type=
'TH1F',
123 title=
'Per-event max #sigma_{Y};max #sigma_{Y} [mm];Events', xbins=100, xmin=0, xmax=2.0)
124 ex.defineHistogram(
'evtMaxAbsDeltaX;h_evtMaxAbsDeltaX', type=
'TH1F',
125 title=
'Per-event max |#DeltaX|;max |#DeltaX| [mm];Events', xbins=100, xmin=0, xmax=0.5)
126 ex.defineHistogram(
'evtMaxAbsDeltaY;h_evtMaxAbsDeltaY', type=
'TH1F',
127 title=
'Per-event max |#DeltaY|;max |#DeltaY| [mm];Events', xbins=100, xmin=0, xmax=2.0)
128 ex.defineHistogram(
'evtMaxProb2;h_evtMaxProb2', type=
'TH1F',
129 title=
'Per-event max P(2);max P(2);Events', xbins=100, xmin=0, xmax=1)
134 summ = helper.addGroup(alg,
'PixelNNPosSummary',
135 '/PixelNNMonitor/PositionNet/Summary/')
136 summ.defineHistogram(
'posN,pullX;h_pullX_vs_N', type=
'TH2F',
137 title=
'Pull X vs multiplicity;N_{true};pull_{X}',
138 xbins=3, xmin=0.5, xmax=3.5, ybins=50, ymin=-5, ymax=5)
139 summ.defineHistogram(
'posN,pullY;h_pullY_vs_N', type=
'TH2F',
140 title=
'Pull Y vs multiplicity;N_{true};pull_{Y}',
141 xbins=3, xmin=0.5, xmax=3.5, ybins=50, ymin=-5, ymax=5)
142 summ.defineHistogram(
'posN,errX;h_errX_vs_N', type=
'TProfile',
143 title=
'Mean #sigma_{X} vs multiplicity;N_{true};#sigma_{X} [#mum]',
144 xbins=3, xmin=0.5, xmax=3.5)
145 summ.defineHistogram(
'posN,errY;h_errY_vs_N', type=
'TProfile',
146 title=
'Mean #sigma_{Y} vs multiplicity;N_{true};#sigma_{Y} [#mum]',
147 xbins=3, xmin=0.5, xmax=3.5)
151 name="ITkPixelNNMonitorFactory"):
152 """NnClusterizationFactory for ITk, running the NN via local ONNX models.
154 Mirrors ITkNnClusterizationFactoryCfg (ITk charge-calib conditions, ITk
155 Lorentz tool, ITkPixelChargeCalibCondData key) but loads the networks from
156 ONNX files instead of the PixelClusterNNJSON COOL folder, which is not
157 available for the Run4 conditions tags.
159 from PixelConditionsAlgorithms.ITkPixelConditionsConfig
import (
160 ITkPixelChargeCalibCondAlgCfg)
161 acc = ITkPixelChargeCalibCondAlgCfg(flags)
163 from InDetConfig.SiClusterizationToolConfig
import OnnxNNCondAlgCfg
164 acc.merge(OnnxNNCondAlgCfg(flags, **onnxPaths))
166 from SiLorentzAngleTool.ITkPixelLorentzAngleConfig
import (
167 ITkPixelLorentzAngleToolCfg)
168 lorentz = acc.popToolsAndMerge(ITkPixelLorentzAngleToolCfg(flags))
170 acc.setPrivateTools(CompFactory.InDet.NnClusterizationFactory(
172 PixelLorentzAngleTool=lorentz,
175 useXPitches=useXPitches,
176 NnCollectionReadKey=
"",
177 NnCollectionWithTrackReadKey=
"",
178 NnCollectionJSONReadKey=
"",
179 NnCollectionONNXReadKey=
"PixelClusterNNONNX",
180 PixelChargeCalibCondData=
"ITkPixelChargeCalibCondData"))
185 """Configure PixelNNMonitorAlg."""
186 acc = ComponentAccumulator()
187 helper = AthMonitorCfgHelper(flags,
"PixelNNMonitoring")
189 alg = helper.addAlgorithm(CompFactory.InDet.PixelNNMonitorAlg,
'PixelNNMonitorAlg')
191 useXPitches = kwargs.pop(
"useXPitches",
False)
193 for key
in [
"useONNX",
"NumberNetworkPath",
"PositionNetwork1Path",
194 "PositionNetwork2Path",
"PositionNetwork3Path"]:
196 nnFactoryKwargs[key] = kwargs.pop(key)
198 from AthenaConfiguration.Enums
import LHCPeriod
199 isITk = flags.GeoModel.Run >= LHCPeriod.Run4
204 if nnFactoryKwargs.get(
"NumberNetworkPath"):
205 onnxPaths = {k: v
for k, v
in nnFactoryKwargs.items()
if k !=
"useONNX"}
206 nnFactory = acc.popToolsAndMerge(
208 useXPitches=useXPitches))
210 from InDetConfig.SiClusterizationToolConfig
import (
211 ITkNnClusterizationFactoryCfg)
212 nnFactory = acc.popToolsAndMerge(ITkNnClusterizationFactoryCfg(flags))
213 alg.PixelClusterContainer =
"ITkPixelClusters"
214 alg.TrackCollection =
"CombinedITkTracks"
215 alg.SiHitCollection =
"ITkPixelHits"
216 alg.ClusterSplitProbContainer =
"ITkAmbiguityProcessorSplitProb"
217 from SiLorentzAngleTool.ITkPixelLorentzAngleConfig
import (
218 ITkPixelLorentzAngleToolCfg)
219 alg.PixelLorentzAngleTool = acc.popToolsAndMerge(
220 ITkPixelLorentzAngleToolCfg(flags))
222 from InDetConfig.SiClusterizationToolConfig
import (
223 NnClusterizationFactoryCfg)
224 nnFactory = acc.popToolsAndMerge(
225 NnClusterizationFactoryCfg(flags, **nnFactoryKwargs))
226 alg.SiHitCollection =
"PixelHits"
227 alg.ClusterSplitProbContainer =
"InDetAmbiguityProcessorSplitProb"
228 from SiLorentzAngleTool.PixelLorentzAngleConfig
import (
229 PixelLorentzAngleToolCfg)
230 alg.PixelLorentzAngleTool = acc.popToolsAndMerge(
231 PixelLorentzAngleToolCfg(flags))
232 alg.NnClusterizationFactory = nnFactory
234 alg.doTruth = flags.Input.isMC
238 acc.merge(helper.result())