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