Belle II Software development
__init__.py
1#!/usr/bin/env python3
2
3
10
11from .svgdrawing import attributemaps
12from . import svgdrawing
13from datetime import datetime
14import subprocess
15import tempfile
16import os.path
17import os
18from ROOT import Belle2 # make Belle2 namespace available
19import basf2
20
21from ROOT import gSystem
22# @cond internal_test
23gSystem.Load('libframework') # for PyStoreArray
24gSystem.Load('libcdc') # for CDCSimHit
25gSystem.Load('libtracking') # for CDCHit and so on
26
27
28class CDCSVGDisplayModule(basf2.Module):
29
30 """
31 Personal two dimensional event display based on scalable vector graphics
32 """
33
34 def __init__(self, output_folder=tempfile.gettempdir(), interactive=True):
35 """
36 Constructor method
37
38 Parameters
39 ----------
40 output_folder : str
41 Target folder for the output
42 interactive : bool, optional
43 Switch to display each event to the user and ask to continue after each event
44 Defaults to True
45 """
46
47 super().__init__()
48 # call constructor of base class, required!
49
50
51 self.interactive = interactive
52
53
54 self.output_folder = output_folder
55
56 # List of drawing options
57
58 # Animate the display by uncovering the drawn objects in order of their time of flight
59 # This can be seen in most standard browsers. Note however that you should switch of
60 # the wires in this case to reduce the rendering load.
61
62 self.animate = False
63
64
65 self.forward_fade = False
66
67 # The following options can be used independent of the track finder
68 # to view Monte Carlo information after the simulation is done
69
70
71 self.use_cpp = True
72
73
74 self.use_python = False
75
76
77 self._draw_wires = True
78 # This is wrapped by an extra property,
79 # because it should always be deactivated in case the scene is animated
80
81
82 self.draw_interaction_point = True
83
84
85 self.draw_superlayer_boundaries = False
86
87
88 self.draw_walls = False
89
90
91 self.draw_hits = True
92
93
94 self.draw_takenflag = False
95
96
97 self.draw_mcparticle_id = False
98
99
100 self.draw_mcparticle_pdgcode = False
101
102
103 self.draw_mcparticle_primary = False
104
105
106 self.draw_mcparticle_trajectories = False
107
108
109 self.draw_simhits = False
110
111
112 self.draw_simhit_tof = False
113
114
115 self.draw_simhit_posflag = False
116
117
118 self.draw_simhit_pdgcode = False
119
120
122 self.draw_simhit_bkgtag = False
123
124
125 self.draw_simhit_isbkg = False
126
127
128 self.draw_nloops = False
129
130
133 self.draw_connect_tof = False
134
135
137 self.draw_rlinfo = False
138
139
142 self.draw_reassigned = False
143
144
145 self.draw_mcsegments = False
146
147
148 self.draw_mcaxialsegmentpairs = False
149
150
151 self.draw_mcsegmentpairs = False # <- not implemented at the moment
152
153
154 self.draw_mcsegmenttriples = False
155
156 # Those are only available if the local track finder is in the module chain
157 # and specific compile time flags enable to transportation of this data
158
159
160 self.draw_superclusters = False
161
162
163 self.draw_clusters = False
164
165
166 self.draw_segments = False
167
168
169 self.draw_segment_trajectories = False
170
171
172 self.draw_tangentsegments = False
173
174
175 self.draw_segment_mctrackids = False
176
177
179 self.draw_segment_fbinfos = False
180
181
182 self.draw_segment_firstInTrackIds = False
183
184
185 self.draw_segment_lastInTrackIds = False
186
187
189 self.draw_segment_firstNPassedSuperLayers = False
190
191
193 self.draw_segment_lastNPassedSuperLayers = False
194
195
196 self.draw_axialsegmentpairs = False
197
198
199 self.draw_segmentpairs = False
200
201
202 self.draw_segmenttriples = False
203
204
205 self.draw_segmenttriple_trajectories = False
206
207
208 self.draw_tracks = False
209
210
211 self.draw_track_trajectories = False
212
213 # Those are only available, if any track finder is in the module chain (not tested for others than the local track finder)
214
215
216 self.draw_recotracks = False
217
218
219 self.draw_mcrecotracks = False
220
221
222 self.draw_recotrack_matching = False
223
224
225 self.draw_mcrecotrack_matching = False
226
227
228 self.draw_recotrack_seed_trajectories = False
229
230
231 self.draw_recotrack_fit_trajectories = False
232
233
234 self.draw_wrong_rl_infos_in_segments = False
235
236
237 self.draw_wrong_rl_infos_in_tracks = False
238
239
240 self.cdc_hits_store_array_name = "CDCHits"
241
242
243 self.reco_tracks_store_array_name = "RecoTracks"
244
245
246 self.mc_reco_tracks_store_array_name = "MCRecoTracks"
247
248
249 self.cdc_wire_hit_cluster_store_obj_name = "CDCWireHitClusterVector"
250
251
252 self.cdc_segment_vector_store_obj_name = 'CDCSegment2DVector'
253
254
255 self.file_number = 0
256
257
258 self.filename_prefix = "CDCDisplay"
259
260
261 self.use_time_in_filename = False
262
263 @property
264 def drawoptions(self):
265 """
266 Property that collects the various names of the draw options to a list
267 that are not related to the CDC cellular automaton track finder.
268 @return list of strings naming the different switches that can be activated.
269 """
270 result = [
271 'animate',
272 'forward_fade',
273 'draw_superlayer_boundaries',
274 'draw_walls',
275 'draw_interaction_point',
276 'draw_mcparticle_id',
277 'draw_mcparticle_pdgcode',
278 'draw_mcparticle_primary',
279 'draw_mcparticle_trajectories',
280 'draw_mcsegments',
281 'draw_simhits',
282 'draw_simhit_tof',
283 'draw_simhit_posflag',
284 'draw_simhit_pdgcode',
285 'draw_simhit_bkgtag',
286 'draw_simhit_isbkg',
287 'draw_nloops',
288 'draw_connect_tof',
289 'draw_rlinfo',
290 'draw_reassigned',
291 'draw_recotracks',
292 'draw_mcrecotracks',
293 'draw_recotrack_matching',
294 'draw_mcrecotrack_matching',
295 'draw_recotrack_seed_trajectories',
296 'draw_recotrack_fit_trajectories',
297 # Specialised options to be used in the CDC local tracking context
298 # obtain them from the all_drawoptions property
299 # 'draw_takenflag',
300 # 'draw_superclusters',
301 # 'draw_clusters',
302 # 'draw_tangentsegments',
303 # 'draw_segment_trajectories',
304 # 'draw_segments',
305 # 'draw_segment_mctrackids',
306 # 'draw_segment_fbinfos',
307 # 'draw_segment_firstInTrackIds',
308 # 'draw_segment_lastInTrackIds',
309 # 'draw_segment_firstNPassedSuperLayers',
310 # 'draw_segment_lastNPassedSuperLayers',
311 # 'draw_segmentpairs'
312 # 'draw_mcsegmentpairs',
313 # 'draw_axialsegmentpairs'
314 # 'draw_mcaxialsegmentpairs',
315 # 'draw_segmenttriples',
316 # 'draw_segmenttriple_trajectories',
317 # 'draw_mcsegmenttriples',
318 # 'draw_tracks',
319 # 'draw_track_trajectories',
320 ]
321 for name in result:
322 if not hasattr(self, name):
323 raise NameError('%s is not a valid draw option. Fix the misspelling.'
324 % name)
325
326 return result
327
328 @property
329 def all_drawoptions(self):
330 """
331 Property that collects the all names of the draw options to a list.
332 Note that some draw options only make sense after running the CDC
333 cellular automaton track finder.
334 @return list of strings naming the different switches that can be activated.
335 """
336 result = self.drawoptions
337
338 # Add all attributes that start with draw
339 draw_options = [option for option in self.__dict__
340 if option.startswith('draw_')]
341 _draw_options = [option[1:] for option in self.__dict__
342 if option.startswith('_draw_')]
343
344 result.extend(draw_options)
345 result.extend(_draw_options)
346
347 return set(result)
348
349 @property
350 def draw_wires(self):
351 """
352 Getter for the draw option that indicates if all wires shall be drawn.
353 Since this has some performance impact in animated events the wires
354 are prevented from being drawn in this case.
355 """
356
357 return self._draw_wires and not self.animate
358
359 @draw_wires.setter
360 def draw_wires(self, draw_wires):
361 """
362 Setter for the option to draw all wires.
363 """
364
365 self._draw_wires = draw_wires
366
367 def initialize(self):
368 """
369 Initialisation method of the module.
370 Creates the output folder if it is not present yet.
371 """
372
373 output_folder = self.output_folder
374 if not os.path.exists(output_folder):
375 print("CDCSVGDisplay.__init__ : Output folder '", output_folder,
376 "' does not exist.")
377 answer = input('Create it? (y or n)')
378 if answer == 'y':
379 os.makedirs(output_folder)
380
381 # Make sure at least one backend is available
382 if not self.use_cpp and not self.use_python:
383 self.use_cpp = True
384
385 if self.use_cpp:
386 cppplotter = Belle2.TrackFindingCDC.CDCSVGPlotter(self.animate, self.forward_fade)
387 if self.use_python:
388 plotter = svgdrawing.CDCSVGPlotter(animate=self.animate)
389
390 # ######### CDCWires ##########
391 # Draw wires from cdcwire objects
392 # Now preferred way of plotting the wires
393 if self.draw_wires:
394 theCDCWireTopology = \
396
397 if self.use_cpp:
398 cppplotter.drawWires(theCDCWireTopology)
399 if self.use_python:
400 plotter.draw(theCDCWireTopology)
401
402 if self.use_cpp:
403
404 self.prefilled_cppplotter = cppplotter
405 if self.use_python:
406
407 self.prefilled_plotter = plotter
408
410 segment_relation_filter.initialize()
411
412 def beginRun(self):
413 """
414 Begin run method of the module. Empty here.
415 """
416
417 pass
418
419 def event(self):
420 """
421 Event method of the module. Draws the event into a new svg file.
422 """
423
424 # Clone the plotter that contains the wires already
425 if self.use_cpp:
426 cppplotter = self.prefilled_cppplotter.clone()
427 if self.use_python:
428 plotter = self.prefilled_plotter.clone()
429
430 self.file_number += 1
431
432 # if self.draw_wires:
433 # theCDCWireTopology = \
434 # Belle2.TrackFindingCDC.CDCWireTopology.getInstance()
435 # cppplotter.draw(theCDCWireTopology)
436
437 # Plotter instance receiving drawable tracking objects.
438 # self.plotter = plotter
439
440 # Construct additional information from basic Monte Carlo data, if it is available from the DataStore
441 # Belle2.TrackFindingCDC.CDCMCHitLookUp.getInstance().fill()
442
443 # Skip empty events
444 if Belle2.PyStoreArray(self.cdc_hits_store_array_name).getEntries() == 0:
445 basf2.B2INFO("Skip empty event")
446 return
447
448 # ######### CDCHits ##########
449 # Draw the raw CDCHits
450 if self.draw_hits:
451 if self.use_cpp:
452 cppplotter.drawHits(self.cdc_hits_store_array_name, 'ZeroDriftLengthColorMap', 'ZeroDriftLengthStrokeWidthMap')
453 if self.use_python:
454 styleDict = {'stroke': attributemaps.ZeroDriftLengthColorMap(),
455 'stroke-width': attributemaps.ZeroDriftLengthStrokeWidthMap()}
456 plotter.draw_storearray(self.cdc_hits_store_array_name, **styleDict)
457
458 # Draw the CDCHits colored by the taken flag from the CDCWireHit.
459 if self.draw_takenflag:
460 if self.use_cpp:
461 cppplotter.drawHits(self.cdc_hits_store_array_name, 'TakenFlagColorMap', '')
462 if self.use_python:
463 styleDict = {'stroke': attributemaps.TakenFlagColorMap(), }
464 plotter.draw_storearray(self.cdc_hits_store_array_name, **styleDict)
465
466 # Draw mcparticle id
467 if self.draw_mcparticle_id:
468 if self.use_cpp:
469 cppplotter.drawHits(self.cdc_hits_store_array_name, 'MCParticleColorMap', '')
470 if self.use_python:
471 styleDict = {'stroke': attributemaps.MCParticleColorMap()}
472 plotter.draw_storearray(self.cdc_hits_store_array_name, **styleDict)
473
474 # Draw monte carlo pdg codes
475 if self.draw_mcparticle_pdgcode:
476 if self.use_cpp:
477 cppplotter.drawHits(self.cdc_hits_store_array_name, 'MCPDGCodeColorMap', '')
478 if self.use_python:
479 styleDict = {'stroke': attributemaps.MCPDGCodeColorMap()}
480 plotter.draw_storearray(self.cdc_hits_store_array_name, **styleDict)
481
482 # Draw monte carlo pdg codes
483 if self.draw_mcparticle_primary:
484 if self.use_cpp:
485 cppplotter.drawHits(self.cdc_hits_store_array_name, 'MCPrimaryColorMap', '')
486 if self.use_python:
487 styleDict = {'stroke': attributemaps.MCPrimaryColorMap()}
488 plotter.draw_storearray(self.cdc_hits_store_array_name, **styleDict)
489
490 # Draw SimHits
491 if self.draw_simhits:
492 if self.use_cpp:
493 cppplotter.drawSimHits(self.cdc_hits_store_array_name, '', '.2')
494 if self.use_python:
495 hit_storearray = Belle2.PyStoreArray(self.cdc_hits_store_array_name)
496 if hit_storearray:
497 simHits_related_to_hits = [hit.getRelated('CDCSimHits')
498 for hit in hit_storearray]
499 styleDict = {'stroke-width': '0.2'}
500 plotter.draw_iterable(simHits_related_to_hits, **styleDict)
501
502 # Draw RL MC info
503 if self.draw_simhit_posflag:
504 if self.use_cpp:
505 cppplotter.drawHits(self.cdc_hits_store_array_name, 'PosFlagColorMap', '')
506 if self.use_python:
507 styleDict = {'stroke': attributemaps.PosFlagColorMap()}
508 plotter.draw_storearray(self.cdc_hits_store_array_name, **styleDict)
509
510 # Draw local RL info
511 if self.draw_rlinfo:
513 if self.use_cpp:
514 cppplotter.drawHits(self.cdc_hits_store_array_name, 'RLColorMap', '')
515 if self.use_python:
516 styleDict = {'stroke': attributemaps.RLColorMap()}
517 plotter.draw_storearray(self.cdc_hits_store_array_name, **styleDict)
518
519 # Draw tof info
520 if self.draw_simhit_tof:
521 if self.use_cpp:
522 cppplotter.drawHits(self.cdc_hits_store_array_name, 'TOFColorMap', '')
523 if self.use_python:
524 styleDict = {'stroke': attributemaps.TOFColorMap()}
525 plotter.draw_storearray(self.cdc_hits_store_array_name, **styleDict)
526
527 # Draw pdg code of simhits
528 if self.draw_simhit_pdgcode:
529 if self.use_cpp:
530 cppplotter.drawHits(self.cdc_hits_store_array_name, "SimHitPDGCodeColorMap", "")
531 if self.use_python:
532 def color_map(iHit, hit):
533 simHit = hit.getRelated('CDCSimHits')
534 pdgCode = simHit.getPDGCode()
535 color = \
536 attributemaps.MCPDGCodeColorMap.color_by_pdgcode.get(pdgCode,
537 'orange')
538 return color
539
540 styleDict = {'stroke': color_map}
541 plotter.draw_storearray(self.cdc_hits_store_array_name, **styleDict)
542
543 # Draw background tag of related simhits
544 if self.draw_simhit_bkgtag:
545 if self.use_cpp:
546 cppplotter.drawHits(self.cdc_hits_store_array_name, 'BackgroundTagColorMap', '')
547 if self.use_python:
548 styleDict = {'stroke': attributemaps.BackgroundTagColorMap()}
549 plotter.draw_storearray(self.cdc_hits_store_array_name, **styleDict)
550
551 # Draw background tag != bg_none of related simhits
552 if self.draw_simhit_isbkg:
553 if self.use_cpp:
554 cppplotter.drawHits(self.cdc_hits_store_array_name, 'SimHitIsBkgColorMap', '')
555 if self.use_python:
556 def color_map(iHit, hit):
557 simHit = hit.getRelated('CDCSimHits')
558 bkgTag = simHit.getBackgroundTag()
559 color = ('gray' if bkgTag else 'red')
560 return color
561
562 styleDict = {'stroke': color_map}
563 plotter.draw_storearray(self.cdc_hits_store_array_name, **styleDict)
564
565 # Draw background tag != bg_none of related simhits
566 if self.draw_nloops:
567 if self.use_cpp:
569 cppplotter.drawHits(self.cdc_hits_store_array_name, 'NLoops', '')
570 if self.use_python:
571 print('No Python-function defined')
572
573 if self.draw_connect_tof:
574 if self.use_cpp:
575 cppplotter.drawSimHitsConnectByToF(self.cdc_hits_store_array_name, "black", ".2")
576 if self.use_python:
577 cdchits_storearray = Belle2.PyStoreArray(self.cdc_hits_store_array_name)
578 if cdchits_storearray:
579 simhits_related_to_cdchit = [cdchit.getRelated('CDCSimHits')
580 for cdchit in cdchits_storearray]
581
582 # group them by their mcparticle id
583 simhits_by_mcparticle = {}
584 for simhit in simhits_related_to_cdchit:
585 mcparticle = simhit.getRelated('MCParticles')
586 if not mcparticle == None: # noqa
587 mcTrackId = mcparticle.getArrayIndex()
588 simhits_by_mcparticle.setdefault(mcTrackId, [])
589 simhits_by_mcparticle[mcTrackId].append(simhit)
590
591 for simhits_for_mcparticle in list(simhits_by_mcparticle.values()):
592 simhits_for_mcparticle.sort(key=lambda simhit:
593 simhit.getFlightTime())
594
595 nSimHits = len(simhits_for_mcparticle)
596 for iSimHit in range(nSimHits - 1):
597 fromSimHit = simhits_for_mcparticle[iSimHit]
598 toSimHit = simhits_for_mcparticle[iSimHit + 1]
599
600 styleDict = {'stroke-width': '0.2', "stroke": "black"}
601
602 fromHit = fromSimHit.getRelated(self.cdc_hits_store_array_name)
603 toHit = toSimHit.getRelated(self.cdc_hits_store_array_name)
604
605 fromWireHit = Belle2.TrackFindingCDC.CDCWireHit(fromHit)
606 toWireHit = Belle2.TrackFindingCDC.CDCWireHit(toHit)
607
608 fromRLWireHit = Belle2.TrackFindingCDC.CDCRLWireHit(fromWireHit, 0)
609 toRLWireHit = Belle2.TrackFindingCDC.CDCRLWireHit(toWireHit, 0)
610
611 fromDisplacement = Belle2.TrackFindingCDC.Vector3D(fromSimHit.getPosTrack() - fromSimHit.getPosWire())
612 toDisplacement = Belle2.TrackFindingCDC.Vector3D(toSimHit.getPosTrack() - toSimHit.getPosWire())
613
614 fromRecoHit2D = Belle2.TrackFindingCDC.CDCRecoHit2D(fromRLWireHit, fromDisplacement.xy())
615 toRecoHit2D = Belle2.TrackFindingCDC.CDCRecoHit2D(toRLWireHit, toDisplacement.xy())
616
617 tangent = Belle2.TrackFindingCDC.CDCTangent(fromRecoHit2D, toRecoHit2D)
618 plotter.draw(tangent, **styleDict)
619
620 # Draw the reassignment information of hits
621 if self.draw_reassigned:
622 if self.use_cpp:
623 cppplotter.drawHits(self.cdc_hits_store_array_name, 'ReassignedSecondaryMap', '')
624 if self.use_python:
625 styleDict = {'stroke': attributemaps.ReassignedSecondaryMap()}
626 plotter.draw_storearray(self.cdc_hits_store_array_name, **styleDict)
627
628 # Draw the in track segment id
629 if self.draw_mcsegments:
631 if self.use_cpp:
632 cppplotter.drawHits(self.cdc_hits_store_array_name, 'MCSegmentIdColorMap', '')
633 if self.use_python:
634 styleDict = {'stroke': attributemaps.MCSegmentIdColorMap()}
635 plotter.draw_storearray(self.cdc_hits_store_array_name, **styleDict)
636
637 # Draw superclusters
638 if self.draw_superclusters:
639 if self.use_cpp:
640 cppplotter.drawClusters('CDCWireHitSuperClusterVector',
641 '', '')
642 if self.use_python:
643 styleDict = {'stroke': attributemaps.listColors}
644 plotter.draw_storevector('CDCWireHitSuperClusterVector', **styleDict)
645
646 # Draw clusters
647 if self.draw_clusters:
648 if self.use_cpp:
649 cppplotter.drawClusters(self.cdc_wire_hit_cluster_store_obj_name,
650 '', '')
651 if self.use_python:
652 styleDict = {'stroke': attributemaps.listColors}
653 plotter.draw_storevector(self.cdc_wire_hit_cluster_store_obj_name, **styleDict)
654
655 # ######### CDCSegments2D ##########
656 # Draw Segments
657 if self.draw_segments:
658 if self.use_cpp:
659 cppplotter.drawSegments(self.cdc_segment_vector_store_obj_name,
660 "ListColors", "")
661 if self.use_python:
662 styleDict = {'stroke': attributemaps.listColors}
663 plotter.draw_storevector(self.cdc_segment_vector_store_obj_name, **styleDict)
664
665 if self.draw_segment_mctrackids:
667 if self.use_cpp:
668 cppplotter.drawSegments(self.cdc_segment_vector_store_obj_name,
669 "SegmentMCTrackIdColorMap", "")
670 if self.use_python:
671 styleDict = {'stroke': attributemaps.SegmentMCTrackIdColorMap()}
672 plotter.draw_storevector(self.cdc_segment_vector_store_obj_name, **styleDict)
673
674 if self.draw_segment_fbinfos:
675 if self.use_cpp:
676 cppplotter.drawSegments(self.cdc_segment_vector_store_obj_name,
677 "SegmentFBInfoColorMap", "")
678 if self.use_python:
679 styleDict = {'stroke': attributemaps.SegmentFBInfoColorMap()}
680 plotter.draw_storevector(self.cdc_segment_vector_store_obj_name, **styleDict)
681
682 if self.draw_segment_firstInTrackIds:
683 if self.use_cpp:
684 cppplotter.drawSegments(self.cdc_segment_vector_store_obj_name,
685 "SegmentFirstInTrackIdColorMap", "")
686 if self.use_python:
687 styleDict = \
688 {'stroke': attributemaps.SegmentFirstInTrackIdColorMap()}
689 plotter.draw_storevector(self.cdc_segment_vector_store_obj_name, **styleDict)
690
691 if self.draw_segment_lastInTrackIds:
692 if self.use_cpp:
693 cppplotter.drawSegments(self.cdc_segment_vector_store_obj_name,
694 "SegmentLastInTrackIdColorMap", "")
695 if self.use_python:
696 styleDict = \
697 {'stroke': attributemaps.SegmentLastInTrackIdColorMap()}
698 plotter.draw_storevector(self.cdc_segment_vector_store_obj_name, **styleDict)
699
700 if self.draw_segment_firstNPassedSuperLayers:
702 if self.use_cpp:
703 cppplotter.drawSegments(self.cdc_segment_vector_store_obj_name,
704 "SegmentFirstNPassedSuperLayersColorMap", "")
705 if self.use_python:
706 styleDict = \
707 {'stroke': attributemaps.SegmentFirstNPassedSuperLayersColorMap()}
708 plotter.draw_storevector(self.cdc_segment_vector_store_obj_name, **styleDict)
709
710 if self.draw_segment_lastNPassedSuperLayers:
712 if self.use_cpp:
713 cppplotter.drawSegments(self.cdc_segment_vector_store_obj_name,
714 "SegmentLastNPassedSuperLayersColorMap", "")
715 if self.use_python:
716 styleDict = \
717 {'stroke': attributemaps.SegmentLastNPassedSuperLayersColorMap()}
718 plotter.draw_storevector(self.cdc_segment_vector_store_obj_name, **styleDict)
719
720 if self.draw_segmentpairs:
721 if self.use_cpp:
722 cppplotter.drawSegmentPairs('CDCSegmentPairs', 'black', '')
723 if self.use_python:
724 styleDict = {"stroke": "black"}
725 plotter.draw_storearray('CDCSegmentPairs', **styleDict)
726
727 # Mimic axial to axial pair selection
728 if self.draw_mcaxialsegmentpairs:
729 if self.use_cpp:
730 cppplotter.drawMCAxialSegmentPairs(self.cdc_segment_vector_store_obj_name, "black", '')
731 if self.use_python:
732 segment_storevector = Belle2.PyStoreObj(self.cdc_segment_vector_store_obj_name)
733 if segment_storevector:
734 segments = segment_storevector.obj().unwrap()
735 axial_segments = [segment for segment in segments
736 if segment.getStereoType() == 0]
737
738 mc_axial_segment_pair_segment_filter = \
740 axial_segment_pair_relations = \
741 (Belle2.TrackFindingCDC.CDCAxialSegmentPair(startSegment, endSegment)
742 for startSegment in axial_segments
743 for endSegment in axial_segments)
744
745 def is_good_pair(pair):
746 weight = mc_axial_segment_pair_segment_filter(pair)
747 return weight == weight # not nan
748
749 good_axial_segment_pair_relations = [pair for pair in
750 axial_segment_pair_relations if is_good_pair(pair)]
751 styleDict = {"stroke": "black"}
752 plotter.draw_iterable(good_axial_segment_pair_relations, **styleDict)
753
754 if self.draw_mcsegmentpairs:
755 if self.use_cpp:
756 cppplotter.drawMCSegmentPairs(self.cdc_segment_vector_store_obj_name, "black", '')
757 if self.use_python:
758 print('No Python-function defined')
759
760 if self.draw_mcsegmenttriples:
761 if self.use_cpp:
762 cppplotter.drawMCSegmentTriples(self.cdc_segment_vector_store_obj_name, '', '')
763 if self.use_python:
764 segment_storevector = Belle2.PyStoreObj(self.cdc_segment_vector_store_obj_name)
765 if segment_storevector:
766 segments = segment_storevector.obj().unwrap()
767 axial_segments = [segment for segment in segments
768 if segment.getStereoType() == 0]
769
770 stereo_segments = [segment for segment in segments
771 if segment.getStereoType() != 0]
772
773 # Misuse this a bit but still does what we want
774 mc_axial_segment_pair_segment_filter = \
776 mc_segment_lookup = \
778
779 segment_triples = \
781 middleSegment, endSegment) for startSegment in
782 axial_segments for middleSegment in stereo_segments
783 for endSegment in axial_segments)
784
785 def is_good_triple(triple):
786 start = triple.getStartSegment()
787 middle = triple.getMiddleSegment()
788 end = triple.getEndSegment()
789
790 pairWeight = \
791 mc_axial_segment_pair_segment_filter(triple)
792
793 if not pairWeight == pairWeight:
794 return False
795
796 startToMiddleFBInfo = \
797 mc_segment_lookup.areAlignedInMCTrack(start, middle)
798 if abs(startToMiddleFBInfo) > 1:
799 return False
800
801 middleToEndFBInfo = \
802 mc_segment_lookup.areAlignedInMCTrack(middle, end)
803 if abs(middleToEndFBInfo) > 1:
804 return False
805
806 if startToMiddleFBInfo == middleToEndFBInfo:
807 return True
808 else:
809 return False
810
811 good_segment_triples = [triple for triple in segment_triples
812 if is_good_triple(triple)]
813
814 styleDict = {"stroke": "black"}
815 plotter.draw_iterable(good_segment_triples, **styleDict)
816
817 # Draw Tangent segments
818 if self.draw_tangentsegments:
819 if self.use_cpp:
820 print('No CPP-function defined')
821 if self.use_python:
822 styleDict = {'stroke-width': '0.2'}
823 plotter.draw_storearray('CDCTangentSegments', **styleDict)
824
825 # Draw axial axial segment pairs
826 if self.draw_axialsegmentpairs:
827 if self.use_cpp:
828 cppplotter.drawAxialSegmentPairs('CDCAxialSegmentPairVector', '', '')
829 if self.use_python:
830 styleDict = {'stroke': attributemaps.listColors}
831 plotter.draw_storevector('CDCAxialSegmentPairVector', **styleDict)
832
833 # Draw segment triples
834 if self.draw_segmenttriples:
835 if self.use_cpp:
836 cppplotter.drawSegmentTriples('CDCSegmentTripleVector', '', '')
837 if self.use_python:
838 styleDict = {'stroke': attributemaps.listColors}
839 plotter.draw_storevector('CDCSegmentTriples', **styleDict)
840
841 # Draw Tracks
842 if self.draw_tracks:
843 if self.use_cpp:
844 cppplotter.drawTracks('CDCTrackVector', '', '')
845 if self.use_python:
846 styleDict = {'stroke': attributemaps.listColors}
847 plotter.draw_storevector('CDCTrackVector', **styleDict)
848
849 # Wrong RL Info
850 if self.draw_wrong_rl_infos_in_tracks:
851 if self.use_cpp:
853 cppplotter.drawWrongRLHitsInTracks('CDCTrackVector')
854 if self.use_python:
855 styleDict = {'stroke': attributemaps.WrongRLColorMap()}
856 pystoreobj = Belle2.PyStoreObj('CDCTrackVector')
857
858 if pystoreobj:
859 # Wrapper around std::vector like
860 wrapped_vector = pystoreobj.obj()
861 vector = wrapped_vector.get()
862
863 for track in vector:
864 plotter.draw_iterable(list(track.items()), **styleDict)
865
866 if self.draw_wrong_rl_infos_in_segments:
867 if self.use_cpp:
869 cppplotter.drawWrongRLHitsInSegments(self.cdc_segment_vector_store_obj_name)
870 if self.use_python:
871 styleDict = {'stroke': attributemaps.WrongRLColorMap()}
872 pystoreobj = Belle2.PyStoreObj(self.cdc_segment_vector_store_obj_name)
873
874 if pystoreobj:
875 # Wrapper around std::vector like
876 wrapped_vector = pystoreobj.obj()
877 vector = wrapped_vector.get()
878
879 for track in vector:
880 plotter.draw_iterable(list(track.items()), **styleDict)
881
882 # Draw the RecoTracks
883 if self.draw_recotracks:
884 if self.use_cpp:
885 cppplotter.drawRecoTracks(self.reco_tracks_store_array_name, 'ListColors', '')
886 if self.use_python:
887 styleDict = {'stroke': attributemaps.listColors}
888 plotter.draw_storearray(self.reco_tracks_store_array_name, **styleDict)
889
890 # Draw the MCRecoTracks
891 if self.draw_mcrecotracks:
892 if self.use_cpp:
893 cppplotter.drawRecoTracks(self.mc_reco_tracks_store_array_name, 'ListColors', '')
894 if self.use_python:
895 styleDict = {'stroke': attributemaps.listColors}
896 plotter.draw_storearray(self.mc_reco_tracks_store_array_name, **styleDict)
897
898 # Draw the RecoTracks matching status
899 if self.draw_recotrack_matching:
900 if self.use_cpp:
901 cppplotter.drawRecoTracks(self.reco_tracks_store_array_name, 'MatchingStatus', '')
902 if self.use_python:
903 print('No Python-function defined')
904
905 # Draw the Monte Carlo reference RecoTracks matching status
906 if self.draw_mcrecotrack_matching:
907 if self.use_cpp:
908 cppplotter.drawRecoTracks(self.mc_reco_tracks_store_array_name, 'MCMatchingStatus', '')
909 if self.use_python:
910 print('No Python-function defined')
911
912 # Draw interaction point
913 if self.draw_interaction_point:
914 if self.use_cpp:
915 cppplotter.drawInteractionPoint()
916 if self.use_python:
917 plotter.draw_interaction_point()
918
919 # Draw the superlayer boundaries
920 if self.draw_superlayer_boundaries:
921 if self.use_cpp:
922 cppplotter.drawSuperLayerBoundaries()
923 if self.use_python:
924 plotter.draw_superlayer_boundaries()
925
926 # Draw the outer and inner wall of the cdc.
927 if self.draw_walls:
928 if self.use_cpp:
929 cppplotter.drawOuterCDCWall('black')
930 cppplotter.drawInnerCDCWall('black')
931 if self.use_python:
932 styleDict = {'stroke': 'black'}
933 plotter.draw_outer_cdc_wall(**styleDict)
934 plotter.draw_inner_cdc_wall(**styleDict)
935
936 # Draw the trajectories of the reco tracks
937 if self.draw_mcparticle_trajectories:
938 if self.use_cpp:
939 cppplotter.drawMCParticleTrajectories("MCParticles", 'black', '')
940 if self.use_python:
941 print("Python backend can not draw mc particles")
942
943 # Draw the fits to the segments
944 if self.draw_segment_trajectories:
945 if self.use_cpp:
946 cppplotter.drawSegmentTrajectories(self.cdc_segment_vector_store_obj_name,
947 "ListColors", "")
948 if self.use_python:
949 segment_storevector = Belle2.PyStoreObj(self.cdc_segment_vector_store_obj_name)
950 if segment_storevector:
951 segments = segment_storevector.obj().unwrap()
952
953 iterTrajectories = (segment.getTrajectory2D() for segment in segments)
954 plotter.draw_iterable(iterTrajectories)
955
956 # Draw segment triples fits
957 if self.draw_segmenttriple_trajectories:
958 cppplotter.drawSegmentTripleTrajectories("CDCSegmentTriples",
959 "ListColors", "")
960
961 if self.use_python:
962 segmentTriple_storearray = Belle2.PyStoreArray('CDCSegmentTriples')
963 if segmentTriple_storearray:
964 iterSegmentTriples = iter(segmentTriple_storearray)
965 iterTrajectories = (segmentTriple.getTrajectory2D()
966 for segmentTriple in iterSegmentTriples)
967 plotter.draw_iterable(iterTrajectories)
968
969 # Draw Track Trajectories
970 if self.draw_track_trajectories:
971 if self.use_cpp:
972 cppplotter.drawTrackTrajectories("CDCTrackVector",
973 "ListColors", "")
974 if self.use_python:
975 styleDict = {'stroke': attributemaps.listColors}
976 track_storevector = Belle2.PyStoreObj('CDCTrackVector')
977 if track_storevector:
978 tracks = track_storevector.obj().unwrap()
979 iterTrajectories = (cdcTrack.getStartTrajectory3D().getTrajectory2D()
980 for cdcTrack in tracks)
981 plotter.draw_iterable(iterTrajectories, **styleDict)
982
983 # Draw the trajectories of the reco tracks
984 if self.draw_recotrack_seed_trajectories:
985 if self.use_python:
986 recotrack_storearray = Belle2.PyStoreArray(self.reco_tracks_store_array_name)
987 if recotrack_storearray:
988 def color_map(iTrajectory, trajectory):
989 # return "black"
990 return attributemaps.listColors[iTrajectory
991 % len(attributemaps.listColors)]
992
993 styleDict = {'stroke': color_map}
994
995 trajectories = []
996 for recotrack in recotrack_storearray:
997 tMomentum = recotrack.getMomentumSeed()
998 charge = recotrack.getChargeSeed()
999 tPosition = recotrack.getPositionSeed()
1000 time = recotrack.getTimeSeed()
1001
1002 momentum = Belle2.TrackFindingCDC.Vector2D(tMomentum.X(),
1003 tMomentum.Y())
1004 position = Belle2.TrackFindingCDC.Vector2D(tPosition.X(),
1005 tPosition.Y())
1006
1007 trajectory = \
1009 momentum, charge)
1010 trajectories.append(trajectory)
1011
1012 plotter.draw_iterable(trajectories, **styleDict)
1013
1014 if self.use_cpp:
1015 raise NotImplementedError
1016
1017 if self.draw_recotrack_fit_trajectories:
1018 if self.use_cpp:
1019 cppplotter.drawRecoTrackTrajectories(self.reco_tracks_store_array_name, '', '')
1020
1021 if self.use_python:
1022 raise NotImplementedError
1023
1024 fileName = self.new_output_filename()
1025 cppfileName = self.new_output_filename()
1026
1027 if self.use_cpp:
1028 cppplotter.saveFile(cppfileName)
1029 if self.use_python:
1030 plotter.saveSVGFile(fileName)
1031
1032 if self.interactive:
1033 if self.use_python:
1034 print(" Use the 'display' command to show the svg file", fileName,
1035 'generated for the last event')
1036 if self.use_cpp:
1037 print(" Use the 'display' command to show the svg file", cppfileName,
1038 'generated for the last event with cpp')
1039
1040 # 'display' is part of the ImageMagic package commonly installed in linux
1041 if self.use_python:
1042 subprocess.Popen(['eog', fileName])
1043 if self.use_cpp:
1044 subprocess.Popen(['eog', cppfileName])
1045 # procDisplay = subprocess.Popen(['display','-background','white',
1046 # '-flatten',fileName])
1047 # procConverter = subprocess.Popen(['rsvg', root + '.svg', root + '.png'])
1048 input('Hit enter for next event')
1049
1050 def endRun(self):
1051 """
1052 endRun method of the module. Empty here.
1053 """
1054
1055 pass
1056
1057 def terminate(self):
1058 """
1059 terminate method of the module. Empty here.
1060 """
1061
1062 pass
1063
1064 def new_output_basename(self):
1065 """
1066 Generates a new unique name for the current event without the folder prefix
1067 """
1068
1069 if self.use_time_in_filename:
1070 output_basename = datetime.now().isoformat() + '.svg'
1071 else:
1072 output_basename = self.filename_prefix + str(self.file_number).zfill(4) + '.svg'
1073 return output_basename
1074
1075 def new_output_filename(self):
1076 """
1077 Generates a new unique name for the current event with the folder prefix
1078 """
1079
1080 return os.path.join(self.output_folder, self.new_output_basename())
1081
1082# @endcond
A (simplified) python wrapper for StoreArray.
a (simplified) python wrapper for StoreObjPtr.
Definition PyStoreObj.h:67
Class representing a pair of reconstructed axial segments in adjacent superlayer.
static const CDCMCHitLookUp & getInstance()
Getter for the singletone instance.
static const CDCMCSegment2DLookUp & getInstance()
Getter for the singletone instance.
Class representing an oriented hit wire including a hypotheses whether the causing track passes left ...
Class representing a two dimensional reconstructed hit in the central drift chamber.
Helper class to generated the svg image from the various tracking objects.
Class representing a triple of reconstructed segments in adjacent superlayer.
Class representing a linear track piece between two oriented wire hits.
Definition CDCTangent.h:40
Particle trajectory as it is seen in xy projection represented as a circle.
Class representing a hit wire in the central drift chamber.
Definition CDCWireHit.h:55
static CDCWireTopology & getInstance()
Getter for the singleton instance of the wire topology.
Filter for the construction of axial to axial segment pairs based on simple criteria.
Filter for the construction of segment pairs based on simple criteria without the common fit.
A two dimensional vector which is equipped with functions for correct handling of orientation relate...
Definition Vector2D.h:32
A three dimensional vector.
Definition Vector3D.h:33