Belle II Software development
testCosmicT0Finder.py
1#!/usr/bin/env python
2
3
10
11# ---------------------------------------------------------------------------------
12# Test of performance and validation of TOPCosmicT0Finder with simulation
13# Input file can be prepared with top/examples/simGCRData.py
14# Output ntuple to cosmicT0FinderNtuple.root
15# ---------------------------------------------------------------------------------
16
17import basf2 as b2
18from ROOT import Belle2
19from ROOT import TH1F
20from ROOT import gROOT, addressof
21import math
22import ROOT
23from ROOT.Math import XYZVector
24
25timeShift = 100 # ns (can be arbitrary chosen)
26
27
28class ShiftDigits(b2.Module):
29 ''' shift digits in time by timeShift'''
30
31 def event(self):
32 ''' event processing '''
33
34 digits = Belle2.PyStoreArray('TOPDigits')
35 for digit in digits:
36 digit.setTime(digit.getTime() + timeShift)
37
38
39gROOT.ProcessLine('struct TreeStruct {\
40 int slot; /* slot number */ \
41 int nfot; /* number of photons in the slot */ \
42 int pdg; /* PDG code from barHit */ \
43 float x; /* local x from barHit */ \
44 float y; /* local y from barHit */ \
45 float z; /* local z from barHit */ \
46 float t; /* time from barHit */ \
47 float p; /* momentum from barHit */ \
48 float theta; /* momentum theta [deg] from barHit */ \
49 float phi; /* momentum local phi [deg] from barHit */ \
50 float dx; /* extHit - barHit difference in local x */ \
51 float dy; /* extHit - barHit difference in local y */ \
52 float dz; /* extHit - barHit difference in local z */ \
53 float dt; /* extHit - barHit difference in time */ \
54 float dp; /* extHit - barHit difference in momentum */ \
55 float dtheta; /* extHit - barHit difference in theta [deg] */ \
56 float dphi; /* extHit - barHit difference in local phi [deg] */ \
57 float t0; /* t0 determined by TOPCosmicT0Finder */ \
58 float t0err; /* error on t0 */ \
59 float timeShift; /* time shift applied to TOPDigits */ \
60 float dt0; /* difference: dt + t0 - timeShift */ \
61};')
62
63from ROOT import TreeStruct # noqa
64
65
66class Ntuple(b2.Module):
67 ''' makes ntuple for MC studies of TOPCosmicT0Finder performance '''
68
69 def initialize(self):
70 ''' initialize '''
71
72
73 self.file = ROOT.TFile('cosmicT0FinderNtuple.root', 'recreate')
74
75 self.tree = ROOT.TTree('tree', '')
76
77 self.data = TreeStruct()
78
79 for key in TreeStruct.__dict__.keys():
80 if '__' not in key:
81 formstring = '/F'
82 if isinstance(self.data.__getattribute__(key), int):
83 formstring = '/I'
84 self.tree.Branch(key, addressof(self.data, key), key + formstring)
85
86
87 self.reso = TH1F('reso', 'T0 residuals', 200, -1.0, 1.0)
88 self.reso.SetXTitle('#Delta t0 [ns]')
89
90 self.pull = TH1F('pull', 'T0 pulls', 200, -10.0, 10.0)
91
92 def event(self):
93 ''' event processing: fill ntuple and histograms '''
94
95 mcParticles = Belle2.PyStoreArray('MCParticles')
96 timeZeros = Belle2.PyStoreArray('TOPTimeZeros')
97 geo = Belle2.TOP.TOPGeometryPar.Instance().getGeometry()
98 for timeZero in timeZeros:
99 extHit = timeZero.getRelated('ExtHits')
100 if not extHit:
101 b2.B2WARNING('no related extHits')
102 continue
103 barHit = None
104 for barhit in mcParticles[0].getRelationsWith('TOPBarHits'):
105 if barhit.getModuleID() == extHit.getCopyID():
106 barHit = barhit
107 if not barHit:
108 b2.B2WARNING('no corresponding TOPBarHit')
109 continue
110
111 moduleID = timeZero.getModuleID()
112 if extHit.getCopyID() != moduleID:
113 b2.B2ERROR('moduleID in extHit differs: ' + str(extHit.getCopyID()) +
114 ' ' + str(moduleID))
115 if barHit.getModuleID() != moduleID:
116 b2.B2ERROR('moduleID in barHit differs: ' + str(barHit.getModuleID()) +
117 ' ' + str(moduleID))
118
119 self.data.slot = moduleID
120 self.data.nfot = timeZero.getNumPhotons()
121 self.data.pdg = barHit.getPDG()
122 pos = barHit.getLocalPosition()
123 self.data.x = pos.X()
124 self.data.y = pos.Y()
125 self.data.z = pos.Z()
126 self.data.t = barHit.getTime()
127 module = geo.getModule(moduleID)
128 mom = module.momentumToLocal(barHit.getMomentum())
129 self.data.p = mom.R()
130 self.data.theta = math.degrees(mom.Theta())
131 self.data.phi = math.degrees(mom.Phi())
132 dr = module.momentumToLocal(extHit.getPosition() - XYZVector(barHit.getPosition()))
133 self.data.dx = dr.X()
134 self.data.dy = dr.Y()
135 self.data.dz = dr.Z()
136 self.data.dt = extHit.getTOF() - self.data.t
137 momExt = module.momentumToLocal(extHit.getMomentum())
138 self.data.dp = momExt.R() - self.data.p
139 self.data.dtheta = math.degrees(momExt.Theta()) - self.data.theta
140 self.data.dphi = math.degrees(momExt.Phi()) - self.data.phi
141 self.data.t0 = timeZero.getTime()
142 self.data.t0err = timeZero.getError()
143 self.data.timeShift = timeShift
144 self.data.dt0 = self.data.dt + self.data.t0 - self.data.timeShift
145 self.file.cd()
146 self.tree.Fill()
147 self.reso.Fill(self.data.dt0)
148 self.pull.Fill(self.data.dt0/self.data.t0err)
149 if timeZero.getChi2().GetEntries() > 0:
150 timeZero.getChi2().Write()
151 timeZero.getPDF().Write()
152 timeZero.getHits().Write()
153
154 def terminate(self):
155 ''' terminate: write and close root file '''
156
157 self.file.cd()
158 self.file.Write()
159 self.file.Close()
160
161
162# Suppress messages and warnings during processing:
163b2.set_log_level(b2.LogLevel.WARNING)
164
165# Create path
166main = b2.create_path()
167
168# input
169roinput = b2.register_module('RootInput')
170main.add_module(roinput)
171
172# Initialize TOP geometry parameters (creation of Geant geometry is not needed)
173main.add_module('TOPGeometryParInitializer')
174
175# shift digits in time
176main.add_module(ShiftDigits())
177
178# t0 finder
179finder = b2.register_module('TOPCosmicT0Finder')
180finder.param('useIncomingTrack', False) # or True
181# finder.param('saveHistograms', True)
182main.add_module(finder)
183
184# ntuple
185main.add_module(Ntuple())
186
187# Print progress
188main.add_module('Progress')
189
190# Process events
191b2.process(main)
192
193# Print statistics
194print(b2.statistics)
A (simplified) python wrapper for StoreArray.
Definition: PyStoreArray.h:72
static TOPGeometryPar * Instance()
Static method to obtain the pointer to its instance.
data
data structure to be written to tree
reso
histogram of t0 residuals
pull
histogram of t0 pulls