Belle II Software development
nntd.py
1
8
9import basf2
10
11import os
12import pickle
13
14
15class nntd(basf2.Module):
16 '''
17 This class represents a dataset.
18 '''
19 version = 2 # changes, when form of self.array changes
20 maxtracks = 100 # max number of tracks per event to be stored
21 # dict to store the content for each entry in a track vector
22 varnum = {}
23 varnum["recoz"] = [0, r'$Z_{Reco}$', r'$[cm]$']
24 varnum["recotheta"] = [1, r'$\theta_{Reco}$', r'$[°]$']
25 varnum["recophi"] = [2, r'$\phi_{Reco}$', r'$[°]$']
26 varnum["recopt"] = [3, r'$P_{t, Reco}$', r'$[GeV]$']
27 varnum["recop"] = [4, r'$P_{Reco}$', r'$[GeV]$']
28 varnum["neuroz"] = [5, r'$Z_{Neuro}$', r'$[cm]$']
29 varnum["neurotheta"] = [6, r'$\theta_{Neuro}$', r'$[°]$']
30 varnum["neurophi"] = [7, r'$\phi_{Neuro}$', r'$[°]$']
31 varnum["neuropt"] = [8, r'$P_{Neuro}$', r'$[GeV]$']
32 varnum["neurop"] = [9, r'$P_{t, Neuro}$', r'$[GeV]$']
33 varnum["neuroval"] = [10, r'Validity', '']
34 varnum["neuroqual"] = [11, r'Quality', '']
35 varnum["neurots"] = [12, r'TSVector', '']
36 varnum["neuroexp"] = [13, r'Expert Number', '']
37 varnum["neurodriftth"] = [14, r'Driftthreshold', '']
38 varnum["neuroquad"] = [15, r'Quadrant', '']
39 varnum["neurofp"] = [16, r'Fastestpriority Eventtime', 'clocks']
40 varnum["neuroetf"] = [17, r'ETF Eventtime', 'clocks']
41 varnum["twodphi"] = [18, r'$\phi_{2D}$', r'$[°]$']
42 varnum["twodpt"] = [19, r'$P_{t, 2D}$', r'$[GeV]$']
43 varnum["twodfot"] = [20, r'FoundOldTrack', '']
44 varnum["hwneuroz"] = [21, r'$Z_{HWNeuro}$', r'$[cm]$']
45 varnum["hwneurotheta"] = [22, r'$\theta_{HWNeuro}$', r'$[°]$']
46 varnum["hwneurophi"] = [23, r'$\phi_{HWNeuro}$', r'$[°]$']
47 varnum["hwneuropt"] = [24, r'$P_{t, HWNeuro}$', r'$[GeV]$']
48 varnum["hwneurop"] = [25, r'$P_{HWNeuro}$', r'$[GeV]$']
49 varnum["hwneuroval"] = [26, r'Validity', '']
50 varnum["hwneuroqual"] = [27, r'Quality', '']
51 varnum["hwneurots"] = [28, r'TSVector', '']
52 varnum["hwneuroexp"] = [29, r'Expert Number', '']
53 varnum["hwneurodriftth"] = [30, r'Driftthreshold', '']
54 varnum["hwneuroquad"] = [31, r'Quadrant', '']
55 varnum["hwneurofp"] = [32, r'Fastestpriority Eventtime', 'clocks']
56 varnum["hwneuroetf"] = [33, r'ETF Eventtime', 'clocks']
57 varnum["swneuroz"] = [34, r'$Z_{SWNeuro}$', r'$[cm]$']
58 varnum["swneurotheta"] = [35, r'$\theta_{SWNeuro}$', r'$[°]$']
59 varnum["swneurophi"] = [36, r'$\phi_{SWNeuro}$', r'$[°]$']
60 varnum["swneuropt"] = [37, r'$P_{t, SWNeuro}$', r'$[GeV]$']
61 varnum["swneurop"] = [38, r'$P_{SWNeuro}$', r'$[GeV]$']
62 varnum["swneuroval"] = [39, r'Validity', '']
63 varnum["swneuroqual"] = [40, r'Quality', '']
64 varnum["swneurots"] = [41, r'TSVector', '']
65 varnum["swneuroexp"] = [42, r'Expert Number', '']
66 varnum["swneurodriftth"] = [43, r'Driftthreshold', '']
67 varnum["swneuroquad"] = [44, r'Quadrant', '']
68 varnum["swneurofp"] = [45, r'Fastestpriority Eventtime', 'clocks']
69 varnum["swneuroetf"] = [46, r'ETF Eventtime', 'clocks']
70 varnum["swtwodphi"] = [47, r'$\phi_{SW2D}$', r'$[°]$']
71 varnum["swtwodpt"] = [48, r'$P_{t, SW2D}$', r'$[GeV]$']
72 varnum["swtwodfot"] = [49, r'FoundOldTrack', '']
73 varnum["neuroats"] = [50, r'NumberOfAxials', '']
74 varnum["hwneuroats"] = [51, r'NumberOfAxials', '']
75 varnum["swneuroats"] = [52, r'NumberOfAxials', '']
76 varnum["neuroetfcc"] = [53, r'ETF Eventtime from CC', 'clocks']
77 varnum["neurohwtime"] = [54, r'Reconstructed HW Eventtime', 'clocks']
78 varnum["hwneuroetfcc"] = [55, r'ETF Eventtime', 'clocks']
79 varnum["hwneurohwtime"] = [56, r'Reconstructed HW Eventtime', 'clocks']
80 nonelist = []
81 for x in varnum:
82 nonelist.append(None)
83
84 def param(self, params):
85 for key, value in params.items():
86 setattr(self, key, value)
87
88 def initialize(self):
89 from ROOT import Belle2 # noqa
90 # TODO:
91 # check if folder is present or create it
92 # initialize all plots somehow
93 # initialize filters somehow, so they can be looped over in the evetn function
94 # setup histograms
95 self.data = None
96 self.eventlist = []
97 self.networkname = "unspecified net"
98 self.dataname = "unspecified runs"
99 # TODO
100 # # dict of plots, which should be plotted during the processing and updated every 5000 events.
101 # self.plotdict = {}
102 self.recotracksname = "RecoTracks" # recotracksname
103 # if not hasattr(self, "neurotracksname"):
104 self.neurotracksname = "TSimNeuroTracks" # "TRGCDCNeuroTracks" # neurotracksname
105 self.hwneurotracksname = "CDCTriggerNeuroTracks" # "TRGCDCNeuroTracks" # neurotracksname
106 self.swneurotracksname = "TRGCDCNeuroTracks" # neurotracksname
107 self.twodtracksname = "CDCTriggerNNInput2DFinderTracks" # "TRGCDC2DFinderTracks" # twodtracksname
108 self.swtwodtracksname = "TRGCDC2DFinderTracks" # twodtracksname
109 self.etfname = "CDCTriggerNeuroETFT0"
110 self.tsname = "CDCTriggerNNInputSegmentHits"
111
112 # storearrays
114 try:
116 except ValueError:
117 self.neurotracks = None
118 try:
120 except ValueError:
121 self.hwneurotracks = None
122 try:
124 except ValueError:
125 self.swneurotracks = None
126 try:
128 except ValueError:
129 self.twodtracks = None
130 try:
132 except ValueError:
133 self.swtwodtracks = None
134 try:
135 self.ts = Belle2.PyStoreArray(self.tsname)
136 except ValueError:
137 self.ts = None
138 try:
139 self.etf = Belle2.PyStoreObj(self.etfname)
140 except ValueError:
141 self.etf = None
142
143 self.varnum = nntd.varnum
144
145 self.debuglist = []
146# if not self.networkname: self.networknamne = "default"
147# if not self.filename: self.filename = "default.pkl"
148
149 def costotheta(self, x):
150 import numpy as np # noqa
151 if isinstance(x, list):
152 ret = []
153 for y in x:
154 ret.append(self.costotheta(y))
155 return ret
156 else:
157 ret = None
158 if not x:
159 return None
160 else:
161 if x < -1 or x > 1:
162 x = np.round(x)
163 return 180. / np.pi * np.arccos(x)
164
165 def getrecovalsold(self, evlist, fitres):
166 if fitres:
167 evlist[self.varnum["recoz"][0]] = fitres.getPosition().Z()
168 evlist[self.varnum["recotheta"][0]] = fitres.getMomentum().Theta() # self.costotheta(fitres.getMomentum().CosTheta())
169 evlist[self.varnum["recophi"][0]] = fitres.getMomentum().Phi()
170 evlist[self.varnum["recopt"][0]] = fitres.getTransverseMomentum()
171 evlist[self.varnum["recop"][0]] = fitres.getMomentum().R()
172 return evlist
173
174 def getrecovals(self, evlist, state):
175 if state:
176 evlist[self.varnum["recoz"][0]] = state.getPos().Z()
177 evlist[self.varnum["recotheta"][0]] = state.getMom().Theta() # self.costotheta(fitres.getMomentum().CosTheta())
178 evlist[self.varnum["recophi"][0]] = state.getMom().Phi()
179 evlist[self.varnum["recopt"][0]] = state.getMom().Pt()
180 evlist[self.varnum["recop"][0]] = state.getMomMag()
181 return evlist
182
183 def getneurovals(self, evlist, neuro, status=""):
184 from ROOT import Belle2 # noqa
185 import numpy as np # noqa
186 pre = status
187 if neuro:
188
189 evlist[self.varnum[pre + "neuroz"][0]] = neuro.getZ0()
190 evlist[self.varnum[pre + "neurotheta"][0]] = self.costotheta(neuro.getCotTheta() / np.sqrt(1 + neuro.getCotTheta()**2))
191 evlist[self.varnum[pre + "neurophi"][0]] = neuro.getPhi0()
192 evlist[self.varnum[pre + "neuropt"][0]] = neuro.getPt()
193 evlist[self.varnum[pre + "neurop"][0]] = neuro.getPt()/np.sin(self.costotheta(neuro.getCotTheta() /
194 np.sqrt(1 + neuro.getCotTheta()**2)))
195 evlist[self.varnum[pre + "neuroval"][0]] = neuro.getValidStereoBit()
196 evlist[self.varnum[pre + "neuroqual"][0]] = neuro.getQualityVector()
197 evlist[self.varnum[pre + "neurots"][0]] = int("".join([str(x) for x in neuro.getTSVector()]))
198 xx = sum([int(i != 0) for i in neuro.getTSVector()][::2])
199 if xx is None:
200 xx = 0
201 evlist[self.varnum[pre + "neuroats"][0]] = xx
202 evlist[self.varnum[pre + "neuroexp"][0]] = neuro.getExpert()
203 evlist[self.varnum[pre + "neurodriftth"][0]] = int("".join([str(int(x)) for x in neuro.getDriftThreshold()]))
204 evlist[self.varnum[pre + "neuroquad"][0]] = neuro.getQuadrant()
205 fpt = 9999
206 for ts in neuro.getRelationsTo(self.tsname):
207 if ts.priorityTime() < fpt:
208 fpt = ts.priorityTime()
209 if self.etf.hasBinnedEventT0(Belle2.Const.CDC):
210 eft = self.etf.getBinnedEventT0(Belle2.Const.CDC)
211 else:
212 eft = None
213
214 # overwrite the etf temporarily with the etfcc
215
216 evlist[self.varnum[pre + "neurofp"][0]] = fpt
217 evlist[self.varnum[pre + "neuroetf"][0]] = eft
218 if pre != "sw":
219 evlist[self.varnum[pre + "neuroetfcc"][0]] = neuro.getETF_unpacked()
220 evlist[self.varnum[pre + "neurohwtime"][0]] = neuro.getETF_recalced()
221 return evlist
222
223 def gettwodvals(self, evlist, twod):
224 if twod:
225 evlist[self.varnum["twodphi"][0]] = twod.getPhi0()
226 evlist[self.varnum["twodpt"][0]] = twod.getPt()
227 # evlist[self.varnum["twodfot"][0]] = int(twod.getFoundOldTrack())
228 return evlist
229
230 def getswtwodvals(self, evlist, twod):
231 if twod:
232 evlist[self.varnum["swtwodphi"][0]] = twod.getPhi0()
233 evlist[self.varnum["swtwodpt"][0]] = twod.getPt()
234 # evlist[self.varnum["twodfot"][0]] = int(twod.getFoundOldTrack())
235 return evlist
236
237 def event(self):
238 from ROOT import Belle2, TVector3, XYZVector # noqa
239 # TODO: update the plots every nth time
240 # if self.showplots != 0:
241 # if eventnumber % self.showplots = 0:
242 # show plots
243
244 # loop over events
245 event = []
246 for reco in self.recotracks:
247 track = reco.getRelatedFrom("Tracks")
248
249 fitres = None
250 state = None
251
252 # method should be either 'old' for the old method or anything else for the new one
253 method = 'old'
254
255 if method == 'old':
256 # # old way: ########################################################################
257
258 if not track:
259 print("no track found for recotrack")
260 continue
261 whishPdg = 211 # pion
262 fitres = track.getTrackFitResultWithClosestMass(Belle2.Const.ChargedStable(whishPdg))
263 if not fitres:
264 continue
265 else:
266 # # new way: ########################################################################
267
268 reps = reco.getRepresentations()
269 irep = 0
270 for irep, rep in enumerate(reps):
271 if not reco.wasFitSuccessful(rep):
272 continue
273 try:
274 state = reco.getMeasuredStateOnPlaneClosestTo(XYZVector(0, 0, 0), rep)
275 rep.extrapolateToLine(state, TVector3(0, 0, -1000), TVector3(0, 0, 2000))
276 except BaseException:
277 continue
278 if not state:
279 continue
280
281
282
283 neuro = reco.getRelatedTo(self.neurotracksname)
284 event.append(self.nonelist.copy())
285 try:
286 neuro = reco.getRelatedTo(self.neurotracksname)
287 except BaseException:
288 neuro = None
289 try:
290 swneuro = reco.getRelatedTo(self.swneurotracksname)
291 except BaseException:
292 swneuro = None
293 try:
294 hwneuro = neuro.getRelatedFrom(self.hwneurotracksname)
295 except BaseException:
296 hwneuro = None
297 try:
298 twod = reco.getRelatedTo(self.twodtracksname)
299 except BaseException:
300 twod = None
301 if method == 'old':
302 event[-1] = self.getrecovalsold(event[-1], fitres)
303 else:
304 event[-1] = self.getrecovals(event[-1], state)
305 event[-1] = self.getneurovals(event[-1], neuro)
306 event[-1] = self.gettwodvals(event[-1], twod)
307 event[-1] = self.getneurovals(event[-1], hwneuro, status="hw")
308 event[-1] = self.getneurovals(event[-1], swneuro, status="sw")
309
310 for neuro in self.neurotracks:
311 # print("neuroloop")
312 # print(len(neuro.getRelationsFrom(self.recotracksname)))
313 if len(neuro.getRelationsFrom(self.recotracksname)) > 0:
314 # this track is already stored in a recoline
315 # print("skipping...")
316 continue
317 event.append(self.nonelist.copy())
318 try:
319 twod = reco.getRelatedTo(self.twodtracksname)
320 except BaseException:
321 twod = None
322 try:
323 hwneuro = neuro.getRelatedFrom(self.hwneurotracksname)
324 except BaseException:
325 hwneuro = None
326 event[-1] = self.getneurovals(event[-1], neuro)
327 event[-1] = self.gettwodvals(event[-1], twod)
328 event[-1] = self.getneurovals(event[-1], hwneuro, status="hw")
329 for swneuro in self.swneurotracks:
330 # print("neuroloop")
331 # print(len(neuro.getRelationsFrom(self.recotracksname)))
332 if len(swneuro.getRelationsFrom(self.recotracksname)) > 0:
333 # this track is already stored in a recoline
334 # print("skipping...")
335 continue
336 event.append(self.nonelist.copy())
337 try:
338 swtwod = reco.getRelatedTo(self.swtwodtracksname)
339 except BaseException:
340 swtwod = None
341 event[-1] = self.getneurovals(event[-1], swneuro, status="sw")
342 event[-1] = self.getswtwodvals(event[-1], swtwod)
343 for twod in self.twodtracks:
344 # print("twodloop")
345 # print(len(twod.getRelationsFrom(self.neurotracksname)))
346 if len(twod.getRelationsFrom(self.neurotracksname)) > 0:
347 # print("skipping...")
348 # this track is already stored in a recoline or twodline
349 continue
350 event.append(self.nonelist.copy())
351 event[-1] = self.gettwodvals(event[-1], twod)
352 for swtwod in self.swtwodtracks:
353 # print("twodloop")
354 # print(len(twod.getRelationsFrom(self.neurotracksname)))
355 if len(swtwod.getRelationsFrom(self.swneurotracksname)) > 0:
356 # print("skipping...")
357 # this track is already stored in a recoline or twodline
358 continue
359 event.append(self.nonelist.copy())
360 event[-1] = self.getswtwodvals(event[-1], swtwod)
361
362 # attach an array for every event
363 if len(event) > self.maxtracks:
364 event = event[0:self.maxtracks]
365 elif len(event) < self.maxtracks:
366 for i in range(self.maxtracks - len(event)):
367 event.append(self.nonelist.copy())
368 self.eventlist.append(event)
369
370 def terminate(self):
371 # self.eventfilters()
372 # self.makearray(self.eventlist)
373 # convert eventlist to data array
374 # initialize histograms and fill them
375 # both save histograms to file and show them in the plots
376 self.save()
377
378 def save(self, filename=None, netname=None, dataname=None):
379 if not filename:
380 filename = self.filename
381 if not netname:
382 netname = self.netname
383 if not dataname:
384 dataname = self.dataname
385 # save the dataset as an array, the corresponding varnum,
386 # and a description about the dataset into a pickle file
387 savedict = {}
388 savedict["eventlist"] = self.eventlist
389 savedict["varnum"] = self.varnum
390 savedict["networkname"] = netname
391 savedict["dataname"] = dataname
392 savedict["version"] = nntd.version
393 f = open(filename, 'wb')
394 pickle.dump(savedict, f)
395 f.close()
396 print('file ' + filename + ' has been saved. ')
397
398 def loadmore(self, filenames):
399 # first, check the amount of events and limit them to NNTD_EVLIMIT
400 evlim = 0
401 evnumber = 0
402 skipev = 0
403 if "NNTD_EVLIMIT" in os.environ:
404 evlim = int(os.environ["NNTD_EVLIMIT"])
405 else:
406 evlim = 50000
407 for i, x in enumerate(filenames):
408 print("checking file: " + str(i) + "/" + str(len(filenames)))
409 f = open(x, 'rb')
410 evnumber += len(pickle.load(f)["eventlist"])
411 if evnumber > evlim:
412 print("total number of available events is " + str(evnumber))
413 skipev = int(evnumber/evlim)
414 print("Number of events more than " + str(evlim) + " only taking every " + str(skipev) + " event")
415 else:
416 skipev = 1
417 for x in filenames:
418 f = open(x, 'rb')
419 savedict = pickle.load(f)
420 f.close()
421 if self.version != savedict["version"]:
422 print("Error! loaded file was made with different version of nntd! exiting ... ")
423 exit()
424 self.networkname = savedict["networkname"]
425 if "dataname" in savedict:
426 self.dataname = savedict["dataname"]
427 templim = evlim-len(self.eventlist)
428 self.eventlist += savedict["eventlist"][::skipev][:templim]
429 self.varnum = savedict["varnum"]
430 print("Loaded file: " + x)
431 print("length of eventlist: " + str(len(self.eventlist)))
432 if evlim <= len(self.eventlist):
433 print("stop loading, maximum event number reached")
434 break
435 self.makearray(self.eventlist)
436 print("all files loaded, array.size: " + str(self.data.size) + ", array.shape: " + str(self.data.shape))
437
438 def load(self, filename):
439 # load a given pickle file
440 f = open(filename, 'rb')
441 savedict = pickle.load(f)
442 f.close()
443 if self.version != savedict["version"]:
444 print("Error! loaded file was made with different version of nntd! exiting ... ")
445 exit()
446 self.eventlist = savedict["eventlist"]
447 self.varnum = savedict["varnum"]
448 self.networkname = savedict["networkname"]
449 self.dataname = savedict["dataname"]
450 # self.eventfilters()
451 self.makearray(self.eventlist)
452
453 def makearray(self, evlist):
454 import numpy as np # noqa
455 # TODO: apply filters
456 self.data = np.array(evlist)
Provides a type-safe way to pass members of the chargedStableSet set.
Definition Const.h:589
A (simplified) python wrapper for StoreArray.
a (simplified) python wrapper for StoreObjPtr.
Definition PyStoreObj.h:67
costotheta(self, x)
Definition nntd.py:149
str tsname
Definition nntd.py:110
list nonelist
Definition nntd.py:80
getswtwodvals(self, evlist, twod)
Definition nntd.py:230
str etfname
Definition nntd.py:109
getrecovals(self, evlist, state)
Definition nntd.py:174
gettwodvals(self, evlist, twod)
Definition nntd.py:223
str neurotracksname
Definition nntd.py:104
str recotracksname
Definition nntd.py:102
list eventlist
Definition nntd.py:96
str twodtracksname
Definition nntd.py:107
swtwodtracks
Definition nntd.py:131
str swtwodtracksname
Definition nntd.py:108
str dataname
Definition nntd.py:98
neurotracks
Definition nntd.py:115
swneurotracks
Definition nntd.py:123
getneurovals(self, evlist, neuro, status="")
Definition nntd.py:183
str swneurotracksname
Definition nntd.py:106
getrecovalsold(self, evlist, fitres)
Definition nntd.py:165
str networkname
Definition nntd.py:97
int maxtracks
Definition nntd.py:20
int version
Definition nntd.py:19
str hwneurotracksname
Definition nntd.py:105
hwneurotracks
Definition nntd.py:119
makearray(self, evlist)
Definition nntd.py:453
dict varnum
Definition nntd.py:22
list debuglist
Definition nntd.py:145
save(self, filename=None, netname=None, dataname=None)
Definition nntd.py:378
recotracks
Definition nntd.py:113
twodtracks
Definition nntd.py:127