13 <contact>Benjamin.Schwenker@phys.uni-goettingen.de</contact>
15 Plot the efficiency to find a cluster
for a given truehit
for all layers of
25from ROOT import Belle2
26b2.set_log_level(b2.LogLevel.ERROR)
28b2.set_random_seed(10346)
30# momenta to generate the plots for
33theta_params = [90, 0.1]
36class ClusterEfficiency(b2.Module):
38 Plot Efficiency to find a U and V cluster
for each given truehit.
43 Create ROOT TProfiles for all layers
and momenta.
48 self.
rfile = ROOT.TFile(
"ClusterEfficiency.root",
"RECREATE")
55 def profile(name, title, text, contact):
56 """small helper function to create a phi profile and set the names
58 prof = ROOT.TProfile(name, title, 60, -180, 180)
59 prof.GetListOfFunctions().Add(ROOT.TNamed("Description", text))
60 prof.GetListOfFunctions().Add(ROOT.TNamed(
"Contact", contact))
61 prof.GetListOfFunctions().Add(ROOT.TNamed(
"Check",
"Should be close to 1 everywhere"))
67 prof_name =
"ClusterEfficiency_layer{layer}_{p:.1f}GeV"
68 prof_title =
"Cluster Efficiency in #phi, layer={layer}, "\
69 +
"p={p:.1f} GeV;#phi in degrees;efficiency"
70 prof_text =
"Efficiency to find a U and V cluster for any given truehit "\
71 +
"in layer {layer} when simulation muons with p={p:.1f} GeV uniformly "\
72 +
"in phi and theta={theta[0]}+-{theta[1]} degree. phi is the angle "\
73 +
"of the generated particle, not the truehit position."
76 True:
"Benjamin Schwenker <Benjamin.Schwenker@phys.uni-goettingen.de>",
77 False:
"Andrzej Bozek <bozek@belle2.ifj.edu.pl>",
81 for layer
in range(1, 7):
84 name = prof_name.format(p=p, layer=layer)
85 title = prof_title.format(p=p, layer=layer)
86 text = prof_text.format(p=p, layer=layer, theta=theta_params)
87 self.
eff[layer][p] = profile(name, title, text, prof_contact[layer < 3])
91 Format all profiles and write the ROOT file.
97 minBin = prof.GetMinimumBin()
99 minVal = min(minVal, (prof.GetBinContent(minBin) - prof.GetBinError(minBin)) * 0.95)
103 prof.SetMinimum(max(0, minVal))
104 prof.SetMaximum(1.02)
112 Loop over all truehits for a track
with the given angle phi
and momentum
113 p
and update the efficiency profiles.
116 for i, truehit
in enumerate(truehits):
118 if truehits.weight(i) < 0:
122 layer = truehit.getSensorID().getLayerNumber()
125 clusters = truehit.getRelationsFrom(
"SVDClusters")
128 clusters = truehit.getRelationsFrom(
"PXDClusters")
131 has_cluster = {
False: 0,
True: 0}
132 for j, cls
in enumerate(clusters):
135 if clusters.weight(j) < 100:
141 has_cluster[
True] = 1
142 has_cluster[
False] = 1
146 has_cluster[cls.isUCluster()] = 1
149 self.
eff[layer][p].Fill(phi, has_cluster[
True] & has_cluster[
False])
153 Update the efficiencies by iterating over all primary particles
156 for mcp
in mcparticles:
158 if not mcp.hasStatus(1):
163 p = mcp.getMomentum()
166 if abs(p.R() - i) < 0.05:
172 b2.B2WARNING(f
"Strange particle momentum: {p.R():f}, expected one of {', '.join('' for p in momenta)}")
176 pxdtruehits = mcp.getRelationsTo(
"PXDTrueHits")
177 self.
fill_truehits(math.degrees(p.Phi()), p_gen, pxdtruehits)
178 svdtruehits = mcp.getRelationsTo(
"SVDTrueHits")
179 self.
fill_truehits(math.degrees(p.Phi()), p_gen, svdtruehits)
184main = b2.create_path()
185main.add_module(
"EventInfoSetter", evtNumList=[10000])
186main.add_module(
"Gearbox")
188main.add_module(
"Geometry", components=[
'MagneticFieldConstant4LimitedRSVD',
189 'BeamPipe',
'PXD',
'SVD'])
190particlegun = main.add_module(
"ParticleGun")
193 "pdgCodes": [13, -13],
195 "momentumGeneration":
'discrete',
196 "momentumParams": momenta + [1]*len(momenta),
197 "thetaGeneration":
'normal',
198 "thetaParams": theta_params,
200main.add_module(
"FullSim")
207main.add_module(clusterefficiency)
208main.add_module(
"Progress")
A (simplified) python wrapper for StoreArray.
Class SVDTrueHit - Records of tracks that either enter or leave the sensitive volume.
eff
layer/momentum hierarchy of all profiles
rfile
Output file to store all plots.
profiles
flat list of all profiles for easy access
def fill_truehits(self, phi, p, truehits)
def add_pxd_simulation(path, digitsName=None, activatePixelMasks=True, activateGainCorrection=True)
def add_pxd_reconstruction(path, clusterName=None, digitsName=None, usePXDClusterShapes=False, spacePointsName='PXDSpacePoints')
def add_svd_simulation(path, useConfigFromDB=False, daqMode=2, relativeShift=9)
def add_svd_reconstruction(path, isROIsimulation=False, createRecoDigits=False, applyMasking=False)