22from ROOT
import Belle2
23from ROOT
import TH1F, TH2F
24from ROOT
import addressof, gROOT
33b2.conditions.override_globaltags()
34b2.conditions.append_globaltag(
'patch_main_release-07_noTOP')
35b2.conditions.append_globaltag(
'data_reprocessing_proc13')
37b2.conditions.append_globaltag(
'online')
40gROOT.ProcessLine(
'struct TreeStruct {\
41 int run; /* run number */ \
42 int itrk; /* track counter */ \
43 float offset; /* current bunch offset */ \
44 int usedTrk; /* number of tracks used for bunch reconstruction */ \
45 int slot; /* slot ID */ \
46 float p; /* extHit momentum */ \
47 float cth; /* extHit local cos(theta) (global must be pretty much the same) */ \
48 float phi; /* extHit local phi */ \
49 float z; /* extHit local z */ \
50 float x; /* extHit local x */ \
51 float tof; /* extHit time-of-flight */ \
52 int charge; /* particle charge */ \
53 float poca_x; /* POCA x */ \
54 float poca_y; /* POCA y */ \
55 float poca_z; /* POCA z */ \
56 int hitsCDC; /* number of CDC hits */ \
57 float Ecms; /* CMS energy of muon */ \
58 float rec_t0; /* t0 of this track determined with bunch finder */ \
59 int valid_t0; /* reconstruction status of t0 */ \
60 int nfot; /* number of photons */ \
61 int channel[1000]; /* channel */ \
62 int pixel[1000] ; /* pixel ID */ \
63 float time[1000]; /* photon time */ \
64 float timeErr[1000]; /* photon time uncertainty */ \
65 int pulseHeight[1000]; /* photon pulse height */ \
66 float pulseWidth[1000]; /* photon pulse width */ \
67 int sample[1000]; /* sample number modulo 256 */ \
68 int status[1000]; /* calibration status bits */ \
69 float t0[1000]; /* leading PDF peak: position */ \
70 float wid0[1000]; /* leading PDF peak: width w/o TTS */ \
71 float t1[1000]; /* next to leading PDF peak: position */ \
72 float t_pdf[1000]; /* associated pdf peak time */ \
73 float wid[1000]; /* associated pdf peak width */ \
74 int type[1000]; /* 0 bkg, 1 direct, 2 reflected */ \
75 int nx[1000]; /* total number of reflections in x */ \
76 int ny[1000]; /* total number of reflections in y */ \
77 int nxm[1000]; /* number of reflections in x before mirror */ \
78 int nym[1000]; /* number of reflections in y before mirror */ \
79 int nxe[1000]; /* number of reflections in x in prism */ \
80 int nye[1000]; /* number of reflections in y in prism */ \
81 int nys[1000]; /* number of reflections on slanted surface of prism */ \
82 float fic[1000]; /* Cherenkov azimuthal angle in degrees */ \
83 float xd[1000]; /* unfolded x coordinate of a pixel */ \
84 float yd[1000]; /* unfolded y coordinate of a pixel */ \
85 float xm[1000]; /* unfolded x coordinate of a reconstructed point on mirror */ \
86 float kx[1000]; /* reconstructed photon direction in x at emission */ \
87 float ky[1000]; /* reconstructed photon direction in y at emission */ \
88 float alpha[1000]; /* impact angle on photo-cathode [degrees] */ \
91int_arrays = [
'channel',
'pixel',
'pulseHeight',
'sample',
'status',
'type',
'nx',
'ny',
92 'nxm',
'nym',
'nxe',
'nye',
'nys']
93float_arrays = [
'time',
'timeErr',
'pulseWidth',
't0',
'wid0',
't1',
't_pdf',
'wid',
'alpha',
'fic',
94 'xd',
'yd',
'xm',
'kx',
'ky']
96from ROOT
import TreeStruct
100 ''' Makes a flat ntuple '''
106 ''' initialize: open root file, construct ntuple '''
109 expNo = evtMetaData.obj().getExperiment()
110 runNo = evtMetaData.obj().getRun()
111 exp_run =
'-e' + f
'{expNo:04d}' +
'-r' + f
'{runNo:05d}'
112 outName =
'timeResoNtuple' + exp_run +
'.root'
121 self.
file = ROOT.TFile(outName,
'recreate')
124 self.
bunchOffset = TH1F(
"bunchOffset",
"bunch offset", 100, -1.0, 1.0)
127 self.
h_cth_vs_p = TH2F(
"cth_vs_p",
"local cos #theta vs. p", 100, 0.0, 10.0,
132 self.
h_momentum = TH1F(
"momentum",
"momentum", 100, 0.0, 10.0)
135 self.
h_cth = TH1F(
"cos_theta",
"local cos #theta", 100, -1.0, 1.0)
136 self.
h_cth.SetXTitle(
"cos #theta")
138 self.
h_phi = TH1F(
"local_phi",
"local phi", 100, -math.pi, math.pi)
139 self.
h_phi.SetXTitle(
"local #phi")
141 self.
h_z = TH1F(
"local_z",
"local z", 100, -140.0, 140.0)
142 self.
h_z.SetXTitle(
"local z [cm]")
144 self.
h_x = TH1F(
"local_x",
"local x", 100, -23.0, 23.0)
145 self.
h_x.SetXTitle(
"local x [cm]")
147 self.
h_charge = TH1F(
"charge",
"charge", 3, -1.5, 1.5)
150 self.
h_poca_xy = TH2F(
"poca_xy",
"POCA distribution in x-y", 100, -1.0, 1.0,
155 self.
h_poca_z = TH1F(
"poca_z",
"POCA distribution in z", 100, -2.0, 2.0)
158 self.
h_hitsCDC = TH1F(
"cdc_hits",
"CDC hits", 100, 0.0, 100.0)
159 self.
h_hitsCDC.SetXTitle(
"number of CDC hits")
161 self.
h_Ecms = TH1F(
"Ecms",
"c.m.s. energy of muon", 300, 4.5, 6.0)
162 self.
h_Ecms.SetXTitle(
"E_{cm} [GeV/c]")
165 self.
tree = ROOT.TTree(
'tree',
'time resolution')
170 for key
in TreeStruct.__dict__.keys():
173 if isinstance(self.
data.__getattribute__(key), int):
175 if key
in int_arrays:
176 formstring =
'[nfot]/I'
177 elif key
in float_arrays:
178 formstring =
'[nfot]/F'
179 self.
tree.Branch(key, addressof(self.
data, key), key + formstring)
182 ''' sort PDF peaks according to their positions '''
184 py_list = [x
for x
in unsortedPeaks]
185 return sorted(py_list, key=
lambda x: (x.mean))
188 ''' make histogram of PDF peak positions for the first 20 tracks '''
193 h = TH2F(
'pdf' + str(self.
nhisto),
'muon PDF, itrk = ' + str(self.
data.itrk),
194 512, 0.0, 512.0, 1000, 0.0, 75.0)
195 h.SetXTitle(
'pixelID - 1')
196 h.SetYTitle(
'peak positions [ns]')
204 ''' event processing '''
208 b2.B2ERROR(
'no TOPRecBunch')
210 if not recBunch.isReconstructed():
215 self.
data.run = evtMetaData.getRun()
216 self.
data.offset = recBunch.getCurrentOffset()
217 self.
data.usedTrk = recBunch.getUsedTracks()
221 if not trk.isValid():
225 pdfs = track.getRelated(
'TOPPDFCollections')
228 self.
data.slot = pdfs.getModuleID()
229 momentum = pdfs.getAssociatedLocalMomentum()
230 position = pdfs.getAssociatedLocalHit()
231 self.
data.p = momentum.R()
232 self.
data.cth = math.cos(momentum.Theta())
233 self.
data.phi = momentum.Phi()
234 self.
data.z = position.Z()
235 self.
data.x = position.X()
236 self.
data.tof = trk.getTOF(Belle2.Const.muon)
238 tfit = track.getTrackFitResultWithClosestMass(Belle2.Const.muon)
239 except BaseException:
240 b2.B2ERROR(
"No trackFitResult available")
242 self.
data.charge = tfit.getChargeSign()
243 pocaPosition = tfit.getPosition()
244 self.
data.poca_x = pocaPosition.X()
245 self.
data.poca_y = pocaPosition.Y()
246 self.
data.poca_z = pocaPosition.Z()
247 self.
data.hitsCDC = tfit.getHitPatternCDC().getNHits()
250 extHit = trk.getExtHit()
251 timeZero = extHit.getRelated(
'TOPTimeZeros')
252 self.
data.rec_t0 = timeZero.getTime()
253 self.
data.valid_t0 = timeZero.isValid()
254 except BaseException:
256 self.
data.valid_t0 = 0
270 pdf = pdfs.getHypothesisPDF(13)
271 except BaseException:
272 b2.B2ERROR(
"No PDF available for PDG = 13")
276 emi = trk.getEmissionPoint()
277 x0 = emi.position.X()
278 z0 = emi.position.Y()
281 if digit.getModuleID() == self.
data.slot
and digit.getHitQuality() == 1:
286 self.
data.channel[k] = digit.getChannel()
287 self.
data.pixel[k] = digit.getPixelID()
288 self.
data.time[k] = digit.getTime()
289 self.
data.timeErr[k] = digit.getTimeError()
290 self.
data.pulseHeight[k] = digit.getPulseHeight()
291 self.
data.pulseWidth[k] = digit.getPulseWidth()
292 self.
data.sample[k] = digit.getModulo256Sample()
293 self.
data.status[k] = digit.getStatus()
294 peaks = pdf[digit.getPixelID() - 1]
297 self.
data.wid0[k] = 0
301 self.
data.t0[k] = sorted_peaks[0].mean
302 self.
data.wid0[k] = sorted_peaks[0].width
303 self.
data.t1[k] = self.
data.t0[k] + 100
305 self.
data.t1[k] = sorted_peaks[1].mean
306 self.
data.t_pdf[k] = 0
309 self.
data.type[k] = 0
322 self.
data.alpha[k] = 0
323 assocPDF = digit.getRelated(
'TOPAssociatedPDFs')
325 pik = assocPDF.getSinglePeak()
327 self.
data.t_pdf[k] = pik.position
328 self.
data.wid[k] = pik.width
329 self.
data.fic[k] = math.degrees(pik.fic)
330 self.
data.type[k] = pik.type
331 self.
data.nx[k] = pik.nx
332 self.
data.ny[k] = pik.ny
333 self.
data.nxm[k] = pik.nxm
334 self.
data.nym[k] = pik.nym
335 self.
data.nxe[k] = pik.nxe
336 self.
data.nye[k] = pik.nye
338 self.
data.nys[k] = int(pik.nye / 2)
340 self.
data.nys[k] = int((pik.nye + 1) / 2)
341 self.
data.xd[k] = pik.xd
342 self.
data.yd[k] = pik.yd
344 self.
data.xm[k] = x0 + pik.kxe / pik.kze * (130.0 - z0)
345 self.
data.kx[k] = pik.kxe
346 self.
data.ky[k] = pik.kye
347 self.
data.alpha[k] = math.degrees(math.acos(abs(pik.kzd)))
352 ''' terminate: close root file '''
360main = b2.create_path()
363main.add_module(
'RootInput')
366main.add_module(
'Gearbox')
367main.add_module(
'Geometry')
368main.add_module(
'Ext')
369main.add_module(
'TOPUnpacker')
370main.add_module(
'TOPRawDigitConverter')
371main.add_module(
'TOPChannelMasker')
372main.add_module(
'TOPBunchFinder')
375main.add_module(
'TOPPDFDebugger', pdgCodes=[13])
381progress = b2.register_module(
'Progress')
382main.add_module(progress)
A (simplified) python wrapper for StoreArray.
a (simplified) python wrapper for StoreObjPtr.
Reconstructed track at TOP.
Utility for the track selection - used in various calibration modules.
trk_selector
track selector - selection of muons from ee->mumu events
def sortPeaks(self, unsortedPeaks)
h_cth
histogram of cos(theta)
int nhisto
histogram counter
h_cth_vs_p
histogram cos(theta) vs, momentum
h_phi
histogram of local phi
h_charge
histogram of charge
h_hitsCDC
histogram of number of hits in CDC
def pdfHistogram(self, pdf)
h_poca_xy
histogram of POCA x-y
h_poca_z
histogram of POCA z
h_momentum
histogram of momentum
bunchOffset
histogram of bunch offset