Belle II Software  release-06-01-15
testCosmicT0Finder.py
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3 
4 
11 
12 # ---------------------------------------------------------------------------------
13 # Test of performance and validation of TOPCosmicT0Finder with simulation
14 # Input file can be prepared with top/examples/simGCRData.py
15 # Output ntuple to cosmicT0FinderNtuple.root
16 # ---------------------------------------------------------------------------------
17 
18 import basf2 as b2
19 from ROOT import Belle2
20 from ROOT import TH1F
21 from ROOT import gROOT, AddressOf
22 import math
23 import ROOT
24 
25 timeShift = 100 # ns (can be arbitrary chosen)
26 
27 
28 class 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 
39 gROOT.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 
63 from ROOT import TreeStruct # noqa
64 
65 
66 class Ntuple(b2.Module):
67  ''' makes ntuple for MC studies of TOPCosmicT0Finder performance '''
68 
69  def initialize(self):
70  ''' initialize '''
71 
72 
73  self.filefile = ROOT.TFile('cosmicT0FinderNtuple.root', 'recreate')
74 
75  self.treetree = ROOT.TTree('tree', '')
76 
77  self.datadata = TreeStruct()
78 
79  for key in TreeStruct.__dict__.keys():
80  if '__' not in key:
81  formstring = '/F'
82  if isinstance(self.datadata.__getattribute__(key), int):
83  formstring = '/I'
84  self.treetree.Branch(key, AddressOf(self.datadata, key), key + formstring)
85 
86 
87  self.resoreso = TH1F('reso', 'T0 residuals', 200, -1.0, 1.0)
88  self.resoreso.SetXTitle('#Delta t0 [ns]')
89 
90  self.pullpull = 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  for timeZero in timeZeros:
98  extHit = timeZero.getRelated('ExtHits')
99  if not extHit:
100  b2.B2WARNING('no related extHits')
101  continue
102  barHit = None
103  for barhit in mcParticles[0].getRelationsWith('TOPBarHits'):
104  if barhit.getModuleID() == extHit.getCopyID():
105  barHit = barhit
106  if not barHit:
107  b2.B2WARNING('no corresponding TOPBarHit')
108  continue
109 
110  moduleID = timeZero.getModuleID()
111  if extHit.getCopyID() != moduleID:
112  b2.B2ERROR('moduleID in extHit differs: ' + str(extHit.getCopyID()) +
113  ' ' + str(moduleID))
114  if barHit.getModuleID() != moduleID:
115  b2.B2ERROR('moduleID in barHit differs: ' + str(barHit.getModuleID()) +
116  ' ' + str(moduleID))
117 
118  self.datadata.slot = moduleID
119  self.datadata.nfot = timeZero.getNumPhotons()
120  self.datadata.pdg = barHit.getPDG()
121  pos = barHit.getLocalPosition()
122  self.datadata.x = pos.x()
123  self.datadata.y = pos.y()
124  self.datadata.z = pos.z()
125  self.datadata.t = barHit.getTime()
126  phiBar = math.pi / 2 - math.pi / 8 * (moduleID - 0.5)
127  mom = barHit.getMomentum()
128  mom.RotateZ(phiBar)
129  self.datadata.p = mom.Mag()
130  self.datadata.theta = math.degrees(mom.Theta())
131  self.datadata.phi = math.degrees(mom.Phi())
132  dr = extHit.getPosition() - barHit.getPosition()
133  dr.RotateZ(phiBar)
134  self.datadata.dx = dr.x()
135  self.datadata.dy = dr.y()
136  self.datadata.dz = dr.z()
137  self.datadata.dt = extHit.getTOF() - self.datadata.t
138  momExt = extHit.getMomentum()
139  momExt.RotateZ(phiBar)
140  self.datadata.dp = momExt.Mag() - self.datadata.p
141  self.datadata.dtheta = math.degrees(momExt.Theta()) - self.datadata.theta
142  self.datadata.dphi = math.degrees(momExt.Phi()) - self.datadata.phi
143  self.datadata.t0 = timeZero.getTime()
144  self.datadata.t0err = timeZero.getError()
145  self.datadata.timeShift = timeShift
146  self.datadata.dt0 = self.datadata.dt + self.datadata.t0 - self.datadata.timeShift
147  self.filefile.cd()
148  self.treetree.Fill()
149  self.resoreso.Fill(self.datadata.dt0)
150  self.pullpull.Fill(self.datadata.dt0/self.datadata.t0err)
151  if timeZero.getChi2().GetEntries() > 0:
152  timeZero.getChi2().Write()
153  timeZero.getPDF().Write()
154  timeZero.getHits().Write()
155 
156  def terminate(self):
157  ''' terminate: write and close root file '''
158 
159  self.filefile.cd()
160  self.filefile.Write()
161  self.filefile.Close()
162 
163 
164 # Suppress messages and warnings during processing:
165 b2.set_log_level(b2.LogLevel.WARNING)
166 
167 # Define a global tag (note: the one given bellow will become out-dated!)
168 b2.use_central_database('data_reprocessing_proc8')
169 
170 # Create path
171 main = b2.create_path()
172 
173 # input
174 roinput = b2.register_module('RootInput')
175 main.add_module(roinput)
176 
177 # Initialize TOP geometry parameters (creation of Geant geometry is not needed)
178 main.add_module('TOPGeometryParInitializer')
179 
180 # shift digits in time
181 main.add_module(ShiftDigits())
182 
183 # t0 finder
184 finder = b2.register_module('TOPCosmicT0Finder')
185 finder.param('useIncomingTrack', False) # or True
186 # finder.param('saveHistograms', True)
187 main.add_module(finder)
188 
189 # ntuple
190 main.add_module(Ntuple())
191 
192 # Print progress
193 main.add_module('Progress')
194 
195 # Process events
196 b2.process(main)
197 
198 # Print statistics
199 print(b2.statistics)
a (simplified) python wrapper for StoreArray.
Definition: PyStoreArray.h:56
data
data structure to be written to tree
reso
histogram of t0 residuals
pull
histogram of t0 pulls