Belle II Software  release-05-02-19
EventDataPlotter.cc
1 /**************************************************************************
2  * BASF2 (Belle Analysis Framework 2) *
3  * Copyright(C) 2015 - Belle II Collaboration *
4  * *
5  * Author: The Belle II Collaboration *
6  * Contributors: Oliver Frost *
7  * *
8  * This software is provided "as is" without any warranty. *
9  **************************************************************************/
10 #include <tracking/trackFindingCDC/display/EventDataPlotter.h>
11 
12 #include <tracking/trackFindingCDC/display/SVGPrimitivePlotter.h>
13 #include <tracking/trackFindingCDC/display/BoundingBox.h>
14 
15 #include <tracking/trackFindingCDC/eventdata/tracks/CDCSegmentPair.h>
16 #include <tracking/trackFindingCDC/eventdata/tracks/CDCAxialSegmentPair.h>
17 #include <tracking/trackFindingCDC/eventdata/tracks/CDCSegmentTriple.h>
18 #include <tracking/trackFindingCDC/eventdata/tracks/CDCTrack.h>
19 
20 #include <tracking/trackFindingCDC/eventdata/segments/CDCWireHitCluster.h>
21 #include <tracking/trackFindingCDC/eventdata/segments/CDCSegment2D.h>
22 #include <tracking/trackFindingCDC/eventdata/segments/CDCSegment3D.h>
23 
24 #include <tracking/trackFindingCDC/eventdata/hits/CDCTangent.h>
25 #include <tracking/trackFindingCDC/eventdata/hits/CDCRecoHit3D.h>
26 #include <tracking/trackFindingCDC/eventdata/hits/CDCRecoHit2D.h>
27 #include <tracking/trackFindingCDC/eventdata/hits/CDCWireHit.h>
28 
29 #include <tracking/trackFindingCDC/topology/CDCWireTopology.h>
30 
31 #include <tracking/trackFindingCDC/geometry/Circle2D.h>
32 
33 #include <cdc/dataobjects/CDCSimHit.h>
34 #include <cdc/dataobjects/CDCHit.h>
35 
36 #include <framework/logging/Logger.h>
37 
38 #include <tracking/dataobjects/RecoTrack.h>
39 #include <mdst/dataobjects/MCParticle.h>
40 
41 #include <TMatrixDSym.h>
42 
43 #include <cmath>
44 
45 using namespace Belle2;
46 using namespace TrackFindingCDC;
47 
48 EventDataPlotter::EventDataPlotter(bool animate, bool forwardFade)
49  : m_ptrPrimitivePlotter(new SVGPrimitivePlotter(
50  AttributeMap{{"stroke", "orange"}, {"stroke-width", "0.55"}, {"fill", "none"}}))
51 , m_animate(animate)
52 , m_forwardFade(forwardFade)
53 {
54 }
55 
56 EventDataPlotter::EventDataPlotter(std::unique_ptr<PrimitivePlotter> ptrPrimitivePlotter,
57  bool animate,
58  bool forwardFade)
59  : m_ptrPrimitivePlotter(std::move(ptrPrimitivePlotter))
60  , m_animate(animate)
61  , m_forwardFade(forwardFade)
62 {
63  B2ASSERT("EventDataPlotter initialized with nullptr. Using default backend SVGPrimitivePlotter.",
64  m_ptrPrimitivePlotter);
65 }
66 
68  : m_ptrPrimitivePlotter(eventDataPlotter.m_ptrPrimitivePlotter->clone())
69  , m_animate(eventDataPlotter.m_animate)
70  , m_forwardFade(eventDataPlotter.m_forwardFade)
71 {
72 }
73 
74 const std::string EventDataPlotter::save(const std::string& fileName)
75 {
77  PrimitivePlotter& primitivePlotter = *m_ptrPrimitivePlotter;
78  return primitivePlotter.save(fileName);
79  } else {
80  return "";
81  }
82 }
83 
85 {
87  PrimitivePlotter& primitivePlotter = *m_ptrPrimitivePlotter;
88  return primitivePlotter.clear();
89  }
90 }
91 
93 {
95  PrimitivePlotter& primitivePlotter = *m_ptrPrimitivePlotter;
96  return primitivePlotter.getBoundingBox();
97  } else {
98  return BoundingBox(0, 0, 0, 0);
99  }
100 }
101 
103 {
104  if (m_ptrPrimitivePlotter) {
105  PrimitivePlotter& primitivePlotter = *m_ptrPrimitivePlotter;
106  return primitivePlotter.setBoundingBox(boundingBox);
107  }
108 }
109 
111 {
112  if (m_ptrPrimitivePlotter) {
113  PrimitivePlotter& primitivePlotter = *m_ptrPrimitivePlotter;
114  return primitivePlotter.getCanvasWidth();
115  } else {
116  return NAN;
117  }
118 }
119 
121 {
122  if (m_ptrPrimitivePlotter) {
123  PrimitivePlotter& primitivePlotter = *m_ptrPrimitivePlotter;
124  return primitivePlotter.getCanvasHeight();
125  } else {
126  return NAN;
127  }
128 }
129 
131 {
132  if (m_ptrPrimitivePlotter) {
133  PrimitivePlotter& primitivePlotter = *m_ptrPrimitivePlotter;
134  primitivePlotter.setCanvasWidth(width);
135  }
136 }
137 
139 {
140  if (m_ptrPrimitivePlotter) {
141  PrimitivePlotter& primitivePlotter = *m_ptrPrimitivePlotter;
142  primitivePlotter.setCanvasHeight(height);
143  }
144 }
145 
147 {
148  if (m_ptrPrimitivePlotter) {
149  PrimitivePlotter& primitivePlotter = *m_ptrPrimitivePlotter;
150  primitivePlotter.startGroup(attributeMap);
151  }
152 }
153 
155 {
156  if (m_ptrPrimitivePlotter) {
157  PrimitivePlotter& primitivePlotter = *m_ptrPrimitivePlotter;
158  primitivePlotter.endGroup();
159  }
160 }
161 
163 {
164  // In case the event should be animated
165  // uncover the group of elements at the time of flight of the CDCSimHit.
166  if (not m_ptrPrimitivePlotter) return;
167  PrimitivePlotter& primitivePlotter = *m_ptrPrimitivePlotter;
168 
169  if (m_animate) {
170  float tof = simHit.getFlightTime();
171  AttributeMap groupAttributeMap{{"_showAt", getAnimationTimeFromNanoSeconds(tof)}};
172  primitivePlotter.startGroup(groupAttributeMap);
173 
174  } else {
175  primitivePlotter.startGroup();
176  }
177 }
178 
180 {
181  if (not m_ptrPrimitivePlotter) return;
182  PrimitivePlotter& primitivePlotter = *m_ptrPrimitivePlotter;
183 
184  if (m_animate) {
185  if (ptrHit) {
186  const CDCHit& hit = *ptrHit;
187  const CDCSimHit* ptrSimHit = hit.getRelated<CDCSimHit>();
188  if (ptrSimHit) {
189  const CDCSimHit& simHit = *ptrSimHit;
190  startAnimationGroup(simHit);
191  return;
192  }
193  }
194  }
195  primitivePlotter.startGroup();
196 }
197 
199 {
200  Vector2D center(0.0, 0.0);
201  float radius = 1.0;
202 
203  const Circle2D interactionPoint(center, radius);
204 
205  AttributeMap attributeMap{{"fill", "black"}, {"stroke-width", "0"}};
206 
207  draw(interactionPoint, attributeMap);
208 }
209 
211 {
212  if (not m_ptrPrimitivePlotter) return;
213  PrimitivePlotter& primitivePlotter = *m_ptrPrimitivePlotter;
214 
215  const CDCWireTopology& wireTopology = CDCWireTopology::getInstance();
216 
217  const CDCWireSuperLayer& wireSuperLayer = wireTopology.getWireSuperLayers().front();
218 
219  float centerX = 0.0;
220  float centerY = 0.0;
221  float innerR = wireSuperLayer.getInnerCylindricalR();
222 
223  primitivePlotter.drawCircle(centerX, centerY, innerR, attributeMap);
224 }
225 
227 {
228  if (not m_ptrPrimitivePlotter) return;
229  PrimitivePlotter& primitivePlotter = *m_ptrPrimitivePlotter;
230 
231  const CDCWireTopology& wireTopology = CDCWireTopology::getInstance();
232 
233  const CDCWireSuperLayer& wireSuperLayer = wireTopology.getWireSuperLayers().back();
234 
235  float centerX = 0.0;
236  float centerY = 0.0;
237  float outerR = wireSuperLayer.getOuterCylindricalR();
238 
239  primitivePlotter.drawCircle(centerX, centerY, outerR, attributeMap);
240 }
241 
243 {
244  if (not m_ptrPrimitivePlotter) return;
245  PrimitivePlotter& primitivePlotter = *m_ptrPrimitivePlotter;
246 
247  const CDCWireTopology& wireTopology = CDCWireTopology::getInstance();
248 
249  for (const CDCWireSuperLayer& wireSuperLayer : wireTopology.getWireSuperLayers()) {
250  float centerX = 0.0;
251  float centerY = 0.0;
252  float outerR = wireSuperLayer.getInnerCylindricalR();
253  primitivePlotter.drawCircle(centerX, centerY, outerR, attributeMap);
254  }
255  drawOuterCDCWall(attributeMap);
256 }
257 
258 void EventDataPlotter::drawLine(float startX,
259  float startY,
260  float endX,
261  float endY,
262  const AttributeMap& attributeMap)
263 {
264  if (not m_ptrPrimitivePlotter) return;
265  PrimitivePlotter& primitivePlotter = *m_ptrPrimitivePlotter;
266 
267  primitivePlotter.drawLine(startX, startY, endX, endY, attributeMap);
268 }
269 
271 void EventDataPlotter::draw(const Circle2D& circle, AttributeMap attributeMap)
272 {
273  if (not m_ptrPrimitivePlotter) return;
274  PrimitivePlotter& primitivePlotter = *m_ptrPrimitivePlotter;
275 
276  float radius = circle.radius();
277 
278  if (not attributeMap.count("fill") or attributeMap["fill"] != "") {
279  if (attributeMap.count("stroke")) {
280  attributeMap["fill"] = attributeMap["stroke"];
281  attributeMap.erase("stroke");
282  }
283  }
284 
285  const Vector2D& pos = circle.center();
286 
287  float x = pos.x();
288  float y = pos.y();
289 
290  primitivePlotter.drawCircle(x, y, radius, attributeMap);
291 }
292 
294 void EventDataPlotter::draw(const CDCWire& wire, const AttributeMap& attributeMap)
295 {
296  const float wireRadius = 0.25;
297  const Vector2D& refPos = wire.getRefPos2D();
298 
299  draw(Circle2D(refPos, wireRadius), attributeMap);
300 }
301 
303 void EventDataPlotter::draw(const CDCWireSuperLayer& wireSuperLayer,
304  const AttributeMap& attributeMap)
305 {
306  if (not m_ptrPrimitivePlotter) return;
307  PrimitivePlotter& primitivePlotter = *m_ptrPrimitivePlotter;
308 
309  primitivePlotter.startGroup(attributeMap);
310  for (const CDCWireLayer& wireLayer : wireSuperLayer) {
311  for (const CDCWire& wire : wireLayer) {
312  draw(wire);
313  }
314  }
315  primitivePlotter.endGroup();
316 }
317 
319 void EventDataPlotter::draw(const CDCWireTopology& wireTopology, AttributeMap attributeMap)
320 {
321  for (const CDCWireSuperLayer& wireSuperLayer : wireTopology.getWireSuperLayers()) {
322  AttributeMap defaultSuperLayerAttributeMap{{"fill",
323  wireSuperLayer.isAxial() ? "black" : "gray"
324  },
325  {"stroke", "none"}};
326 
327  AttributeMap superLayerAttributeMap(attributeMap);
328 
329  // Insert the values as defaults. Does not overwrite attributes with the same name.
330  superLayerAttributeMap.insert(defaultSuperLayerAttributeMap.begin(),
331  defaultSuperLayerAttributeMap.end());
332  draw(wireSuperLayer, superLayerAttributeMap);
333  }
334 }
335 
337 void EventDataPlotter::draw(const CDCSimHit& simHit, const AttributeMap& attributeMap)
338 {
339  if (not m_ptrPrimitivePlotter) return;
340  PrimitivePlotter& primitivePlotter = *m_ptrPrimitivePlotter;
341 
342  startAnimationGroup(simHit);
343 
344  // Draw hit position as a small circle
345  TVector3 position = simHit.getPosTrack();
346  float x = position.X();
347  float y = position.Y();
348  float radius = 0.2;
349 
350  primitivePlotter.drawCircle(x, y, radius, attributeMap);
351 
352  // Draw momentum as an arrow proportional to the transverse component of the momentum
353  const float momentumToArrowLength = 1.5;
354 
355  TVector3 momentum = simHit.getMomentum();
356  float endX = x + momentum.X() * momentumToArrowLength;
357  float endY = y + momentum.Y() * momentumToArrowLength;
358 
359  primitivePlotter.drawArrow(x, y, endX, endY, attributeMap);
360 
361  primitivePlotter.endGroup();
362 }
363 
365 void EventDataPlotter::draw(const CDCHit& hit, const AttributeMap& attributeMap)
366 {
367  CDCWireHit wireHit(&hit);
368  draw(wireHit, attributeMap);
369 }
370 
372 void EventDataPlotter::draw(const CDCWireHit& wireHit, const AttributeMap& attributeMap)
373 {
374  if (not m_ptrPrimitivePlotter) return;
375  PrimitivePlotter& primitivePlotter = *m_ptrPrimitivePlotter;
376 
377  startAnimationGroup(wireHit.getHit());
378 
379  const Vector2D& refPos = wireHit.getRefPos2D();
380 
381  float x = refPos.x();
382  float y = refPos.y();
383  float radius = wireHit.getRefDriftLength();
384 
385  if (fabs(radius) < 100) {
386  primitivePlotter.drawCircle(x, y, radius, attributeMap);
387  }
388 
389  primitivePlotter.endGroup();
390 }
391 
393 void EventDataPlotter::draw(const CDCRecoHit2D& recoHit2D, const AttributeMap& attributeMap)
394 {
395  if (not m_ptrPrimitivePlotter) return;
396  PrimitivePlotter& primitivePlotter = *m_ptrPrimitivePlotter;
397 
398  const CDCWireHit& wireHit = recoHit2D.getWireHit();
399 
400  startAnimationGroup(wireHit.getHit());
401 
402  const Vector2D& refPos2D = wireHit.getRefPos2D();
403  const Vector2D& recoPos2D = recoHit2D.getRecoPos2D();
404 
405  float x = refPos2D.x();
406  float y = refPos2D.y();
407  float radius = wireHit.getRefDriftLength();
408  primitivePlotter.drawCircle(x, y, radius, attributeMap);
409 
410  if (not recoPos2D.hasNAN()) {
411  float supportPointRadius = 0.2;
412  Circle2D supportPoint(recoPos2D, supportPointRadius);
413  draw(supportPoint, attributeMap);
414  }
415 
416  primitivePlotter.endGroup();
417 }
418 
420 void EventDataPlotter::draw(const CDCTangent& tangent, const AttributeMap& attributeMap)
421 {
422  if (not m_ptrPrimitivePlotter) return;
423  PrimitivePlotter& primitivePlotter = *m_ptrPrimitivePlotter;
424 
425  const Vector2D fromPos = tangent.getFromRecoPos2D();
426  const float fromX = fromPos.x();
427  const float fromY = fromPos.y();
428 
429  const Vector2D toPos = tangent.getToRecoPos2D();
430  const float toX = toPos.x();
431  const float toY = toPos.y();
432 
433  primitivePlotter.drawLine(fromX, fromY, toX, toY, attributeMap);
434 
435  float touchPointRadius = 0.015;
436  const Circle2D fromTouchPoint(fromPos, touchPointRadius);
437  draw(fromTouchPoint, attributeMap);
438 
439  const Circle2D toTouchPoint(toPos, touchPointRadius);
440  draw(toTouchPoint, attributeMap);
441 }
442 
444  const AttributeMap& attributeMap)
445 {
446  draw(recoHit3D.getRecoHit2D(), attributeMap);
447 }
448 
450 void EventDataPlotter::draw(const CDCTrajectory2D& trajectory2D, AttributeMap attributeMap)
451 {
452  if (not m_ptrPrimitivePlotter) return;
453  PrimitivePlotter& primitivePlotter = *m_ptrPrimitivePlotter;
454 
455  AttributeMap defaultAttributeMap{};
456 
457  // Make the default color charge dependent
458  int charge = trajectory2D.getChargeSign();
459  if (charge > 0) {
460  defaultAttributeMap["stroke"] = "red";
461  } else if (charge < 0) {
462  defaultAttributeMap["stroke"] = "blue";
463  } else {
464  defaultAttributeMap["stroke"] = "green";
465  }
466 
467  // Add attributes if not present
468  attributeMap.insert(defaultAttributeMap.begin(), defaultAttributeMap.end());
469 
470  Vector2D trajectoryExit = trajectory2D.getOuterExit();
471  if (trajectoryExit.hasNAN()) {
472  // Curlers do not leave the CDC
473  // Stop the trajectory at the inner wall to be able to
474  // see the start point
475  trajectoryExit = trajectory2D.getInnerExit();
476  }
477 
478  if (trajectory2D.getLocalCircle()->isCircle()) {
479  if (trajectoryExit.hasNAN()) {
480  // No exit point out of the cdc could be detected.
481  // Draw full circle
482  const float radius = trajectory2D.getLocalCircle()->absRadius();
483  const Vector2D center = trajectory2D.getGlobalCircle().center();
484  float centerX = center.x();
485  float centerY = center.y();
486 
487  primitivePlotter.drawCircle(centerX, centerY, radius);
488 
489  } else {
490  const float radius = trajectory2D.getLocalCircle()->absRadius();
491  const Vector2D start = trajectory2D.getSupport();
492  float startX = start.x();
493  float startY = start.y();
494 
495  float endX = trajectoryExit.x();
496  float endY = trajectoryExit.y();
497 
498  const int curvature = -charge;
499  const bool sweepFlag = curvature > 0;
500 
501  // check if exit point is on the close or
502  // on the far side of the circle
503  const bool longArc = (trajectory2D.calcArcLength2D(trajectoryExit) > 0) ? false : true;
504  primitivePlotter.drawCircleArc(startX,
505  startY,
506  endX,
507  endY,
508  radius,
509  longArc,
510  sweepFlag,
511  attributeMap);
512  }
513  } else {
514  // trajectory is a straight line
515  if (trajectoryExit.hasNAN()) {
516  B2WARNING("Could not compute point off exit in a straight line case.");
517  } else {
518  const Vector2D start = trajectory2D.getSupport();
519  float startX = start.x();
520  float startY = start.y();
521 
522  float endX = trajectoryExit.x();
523  float endY = trajectoryExit.y();
524  primitivePlotter.drawLine(startX, startY, endX, endY, attributeMap);
525  }
526  }
527 }
528 
529 void EventDataPlotter::draw(const CDCWireHitCluster& wireHitCluster, const AttributeMap& attributeMap)
530 {
531  drawRange(wireHitCluster, attributeMap);
532 }
533 
534 void EventDataPlotter::draw(const CDCSegment2D& segment2D, const AttributeMap& attributeMap)
535 {
536  if (m_forwardFade) {
537  drawRangeWithFade(segment2D, attributeMap);
538  } else {
539  drawRange(segment2D, attributeMap);
540  }
541 }
542 
543 void EventDataPlotter::draw(const CDCSegment3D& segment3D, const AttributeMap& attributeMap)
544 {
545  if (m_forwardFade) {
546  drawRange(segment3D, attributeMap);
547  } else {
548  drawRange(segment3D, attributeMap);
549  }
550 }
551 
552 void EventDataPlotter::draw(const CDCAxialSegmentPair& axialSegmentPair,
553  const AttributeMap& attributeMap)
554 {
555  if (not m_ptrPrimitivePlotter) return;
556  PrimitivePlotter& primitivePlotter = *m_ptrPrimitivePlotter;
557 
558  const CDCSegment2D* ptrFromSegment = axialSegmentPair.getStartSegment();
559  const CDCSegment2D* ptrToSegment = axialSegmentPair.getEndSegment();
560 
561  if (not ptrFromSegment or not ptrToSegment) return;
562 
563  const CDCSegment2D& fromSegment = *ptrFromSegment;
564  const CDCSegment2D& toSegment = *ptrToSegment;
565 
566  const Vector2D& fromPos = fromSegment.back().getWire().getRefPos2D();
567  const Vector2D& toPos = toSegment.front().getWire().getRefPos2D();
568 
569  if (fromPos.hasNAN()) {
570  B2WARNING("Center of mass of first segment in a pair contains NAN values.");
571  return;
572  }
573 
574  if (toPos.hasNAN()) {
575  B2WARNING("Center of mass of second segment in a pair contains NAN values.");
576  return;
577  }
578 
579  const float fromX = fromPos.x();
580  const float fromY = fromPos.y();
581 
582  const float toX = toPos.x();
583  const float toY = toPos.y();
584 
585  primitivePlotter.drawArrow(fromX, fromY, toX, toY, attributeMap);
586 }
587 
588 void EventDataPlotter::draw(const CDCSegmentPair& segmentPair, const AttributeMap& attributeMap)
589 {
590  if (not m_ptrPrimitivePlotter) return;
591  PrimitivePlotter& primitivePlotter = *m_ptrPrimitivePlotter;
592 
593  const CDCSegment2D* ptrFromSegment = segmentPair.getFromSegment();
594  const CDCSegment2D* ptrToSegment = segmentPair.getToSegment();
595 
596  if (not ptrFromSegment or not ptrToSegment) return;
597 
598  const CDCSegment2D& fromSegment = *ptrFromSegment;
599  const CDCSegment2D& toSegment = *ptrToSegment;
600 
601  const Vector2D& fromPos = fromSegment.back().getWire().getRefPos2D();
602  const Vector2D& toPos = toSegment.front().getWire().getRefPos2D();
603 
604  if (fromPos.hasNAN()) {
605  B2WARNING("Center of mass of first segment in a pair contains NAN values.");
606  return;
607  }
608 
609  if (toPos.hasNAN()) {
610  B2WARNING("Center of mass of second segment in a pair contains NAN values.");
611  return;
612  }
613 
614  const float fromX = fromPos.x();
615  const float fromY = fromPos.y();
616 
617  const float toX = toPos.x();
618  const float toY = toPos.y();
619 
620  primitivePlotter.drawArrow(fromX, fromY, toX, toY, attributeMap);
621 }
622 
623 void EventDataPlotter::draw(const CDCSegmentTriple& segmentTriple, const AttributeMap& attributeMap)
624 {
625  if (not m_ptrPrimitivePlotter) return;
626  PrimitivePlotter& primitivePlotter = *m_ptrPrimitivePlotter;
627 
628  const CDCSegment2D* ptrStartSegment = segmentTriple.getStartSegment();
629  const CDCSegment2D* ptrMiddleSegment = segmentTriple.getMiddleSegment();
630  const CDCSegment2D* ptrEndSegment = segmentTriple.getEndSegment();
631 
632  if (not ptrStartSegment or not ptrMiddleSegment or not ptrEndSegment) return;
633 
634  const CDCSegment2D& startSegment = *ptrStartSegment;
635  const CDCSegment2D& middleSegment = *ptrMiddleSegment;
636  const CDCSegment2D& endSegment = *ptrEndSegment;
637 
638  const Vector2D& startBackPos2D = startSegment.back().getRefPos2D();
639  const Vector2D& middleFrontPos2D = middleSegment.front().getRefPos2D();
640  const Vector2D& middleBackPos2D = middleSegment.back().getRefPos2D();
641  const Vector2D& endFrontPos2D = endSegment.front().getRefPos2D();
642 
643  if (startBackPos2D.hasNAN()) {
644  B2WARNING("Back position of start segment in a triple contains NAN values.");
645  return;
646  }
647 
648  if (middleFrontPos2D.hasNAN()) {
649  B2WARNING("Front position of middle segment in a triple contains NAN values.");
650  return;
651  }
652 
653  if (middleBackPos2D.hasNAN()) {
654  B2WARNING("Back position of middle segment in a triple contains NAN values.");
655  return;
656  }
657 
658  if (endFrontPos2D.hasNAN()) {
659  B2WARNING("Front position of end segment in a triple contains NAN values.");
660  return;
661  }
662 
663  const float startBackX = startBackPos2D.x();
664  const float startBackY = startBackPos2D.y();
665 
666  const float middleFrontX = middleFrontPos2D.x();
667  const float middleFrontY = middleFrontPos2D.y();
668 
669  primitivePlotter.drawArrow(startBackX, startBackY, middleFrontX, middleFrontY, attributeMap);
670 
671  const float middleBackX = middleBackPos2D.x();
672  const float middleBackY = middleBackPos2D.y();
673 
674  const float endFrontX = endFrontPos2D.x();
675  const float endFrontY = endFrontPos2D.y();
676 
677  primitivePlotter.drawArrow(middleBackX, middleBackY, endFrontX, endFrontY, attributeMap);
678 }
679 
680 void EventDataPlotter::draw(const CDCTrack& track, const AttributeMap& attributeMap)
681 {
682  if (m_forwardFade) {
683  drawRangeWithFade(track, attributeMap);
684  } else {
685  drawRange(track, attributeMap);
686  }
687 }
688 
689 void EventDataPlotter::draw(const RecoTrack& recoTrack, const AttributeMap& attributeMap)
690 {
691  StoreArray<CDCHit> storedHits;
692 
693  if (not m_ptrPrimitivePlotter) return;
694  PrimitivePlotter& primitivePlotter = *m_ptrPrimitivePlotter;
695 
696  primitivePlotter.startGroup(attributeMap);
697  for (const CDCHit* ptrHit : recoTrack.getCDCHitList()) {
698  if (ptrHit) {
699  const CDCHit& hit = *ptrHit;
700  draw(hit);
701  }
702  }
703  primitivePlotter.endGroup();
704 }
705 
706 void EventDataPlotter::drawTrajectory(const MCParticle& mcParticle, const AttributeMap& attributeMap)
707 {
708  if (not mcParticle.isPrimaryParticle()) return;
709  Vector3D pos(mcParticle.getVertex());
710  Vector3D mom(mcParticle.getMomentum());
711  double charge = mcParticle.getCharge();
712  double time = mcParticle.getProductionTime();
713  CDCTrajectory2D trajectory2D(pos.xy(), time, mom.xy(), charge);
714  draw(trajectory2D, attributeMap);
715 }
716 
717 void EventDataPlotter::drawTrajectory(const CDCSegment2D& segment,
718  const AttributeMap& attributeMap)
719 {
720  draw(segment.getTrajectory2D(), attributeMap);
721 }
722 
723 void EventDataPlotter::drawTrajectory(const CDCSegmentTriple& segmentTriple,
724  const AttributeMap& attributeMap)
725 {
726  draw(segmentTriple.getTrajectory3D().getTrajectory2D(), attributeMap);
727 }
728 
729 void EventDataPlotter::drawTrajectory(const CDCTrack& track, const AttributeMap& attributeMap)
730 {
731  draw(track.getStartTrajectory3D().getTrajectory2D(), attributeMap);
732 }
733 
734 void EventDataPlotter::drawTrajectory(const RecoTrack& recoTrack, const AttributeMap& attributeMap)
735 {
736  if (not m_ptrPrimitivePlotter) return;
737  PrimitivePlotter& primitivePlotter = *m_ptrPrimitivePlotter;
738 
739  primitivePlotter.startGroup(attributeMap);
740 
741  bool fitSuccessful = not recoTrack.getRepresentations().empty() and recoTrack.wasFitSuccessful();
742  if (fitSuccessful) {
743  std::vector<std::array<float, 2>> points;
744  std::vector<std::array<float, 2>> tangents;
745 
746  for (auto recoHit : recoTrack.getRecoHitInformations()) {
747  // skip for reco hits which have not been used in the fit (and therefore have no fitted information on the plane
748  if (!recoHit->useInFit())
749  continue;
750 
751  TVector3 pos;
752  TVector3 mom;
753  TMatrixDSym cov;
754 
755  try {
756  const auto* trackPoint = recoTrack.getCreatedTrackPoint(recoHit);
757  const auto* fittedResult = trackPoint->getFitterInfo();
758  if (not fittedResult) {
759  B2WARNING("Skipping unfitted track point");
760  continue;
761  }
762  const genfit::MeasuredStateOnPlane& state = fittedResult->getFittedState();
763  state.getPosMomCov(pos, mom, cov);
764  } catch (const genfit::Exception&) {
765  B2WARNING("Skipping state with strange pos, mom or cov");
766  continue;
767  }
768 
769  float x = pos.X();
770  float y = pos.Y();
771  float px = mom.X();
772  float py = mom.Y();
773 
774  points.push_back({{x, y}});
775  tangents.push_back({{px, py}});
776  }
777  primitivePlotter.drawCurve(points, tangents, attributeMap);
778  }
779 
780  primitivePlotter.endGroup();
781 }
Belle2::EvtPDLUtil::charge
double charge(int pdgCode)
Returns electric charge of a particle with given pdg code.
Definition: EvtPDLUtil.cc:46
Belle2::TrackFindingCDC::PrimitivePlotter::drawCircle
virtual void drawCircle(float centerX, float centerY, float radius, const AttributeMap &attributeMap=AttributeMap())
Adds a circle to the plot.
Definition: PrimitivePlotter.cc:54
Belle2::CDCSimHit::getFlightTime
double getFlightTime() const
The method to get flight time.
Definition: CDCSimHit.h:201
Belle2::TrackFindingCDC::EventDataPlotter
A class that can plot event related data types.
Definition: EventDataPlotter.h:64
genfit::Exception
Exception class for error handling in GENFIT (provides storage for diagnostic information)
Definition: Exception.h:48
Belle2::TrackFindingCDC::EventDataPlotter::startAnimationGroup
void startAnimationGroup(const Belle2::CDCSimHit &simHit)
Start a group in the underlying plotter with an animation uncovering the elements at the time of flig...
Definition: EventDataPlotter.cc:162
Belle2::Vector3D
HepGeom::Vector3D< double > Vector3D
3D Vector
Definition: Cell.h:35
Belle2::MCParticle::getCharge
float getCharge() const
Return the particle charge defined in TDatabasePDG.
Definition: MCParticle.cc:35
Belle2::TrackFindingCDC::CDCRecoHit3D
Class representing a three dimensional reconstructed hit.
Definition: CDCRecoHit3D.h:62
Belle2::RecoTrack::wasFitSuccessful
bool wasFitSuccessful(const genfit::AbsTrackRep *representation=nullptr) const
Returns true if the last fit with the given representation was successful.
Definition: RecoTrack.cc:326
Belle2::TrackFindingCDC::PrimitivePlotter::getCanvasHeight
float getCanvasHeight()
Getter for the canvas height in pixels.
Definition: PrimitivePlotter.h:218
Belle2::TrackFindingCDC::EventDataPlotter::m_animate
bool m_animate
Memory for the flag if the event data should be animated. If animation is supported is backend depend...
Definition: EventDataPlotter.h:315
Belle2::CDCSimHit::getPosTrack
TVector3 getPosTrack() const
The method to get position on the track.
Definition: CDCSimHit.h:234
Belle2::TrackFindingCDC::Vector2D
A two dimensional vector which is equipped with functions for correct handeling of orientation relat...
Definition: Vector2D.h:37
Belle2::TrackFindingCDC::PrimitivePlotter::endGroup
virtual void endGroup()
Indicates the end of a group of drawn elements.
Definition: PrimitivePlotter.cc:102
genfit::MeasuredStateOnPlane
#StateOnPlane with additional covariance matrix.
Definition: MeasuredStateOnPlane.h:39
Belle2::TrackFindingCDC::CDCWireHit::getRefDriftLength
double getRefDriftLength() const
Getter for the drift length at the reference position of the wire.
Definition: CDCWireHit.h:232
Belle2::CDCHit
Class containing the result of the unpacker in raw data and the result of the digitizer in simulation...
Definition: CDCHit.h:51
Belle2::RecoTrack::getCDCHitList
std::vector< Belle2::RecoTrack::UsedCDCHit * > getCDCHitList() const
Return an unsorted list of cdc hits.
Definition: RecoTrack.h:446
Belle2::TrackFindingCDC::EventDataPlotter::m_ptrPrimitivePlotter
std::unique_ptr< PrimitivePlotter > m_ptrPrimitivePlotter
Reference to the primitivePlotter instance used as backend for the draw commands.
Definition: EventDataPlotter.h:312
Belle2::TrackFindingCDC::CDCWireHit::getRefPos2D
const Vector2D & getRefPos2D() const
The two dimensional reference position (z=0) of the underlying wire.
Definition: CDCWireHit.cc:214
Belle2::TrackFindingCDC::CDCWireTopology::getInstance
static CDCWireTopology & getInstance()
Getter for the singleton instance of the wire topology.
Definition: CDCWireTopology.cc:22
Belle2::TrackFindingCDC::EventDataPlotter::setCanvasWidth
void setCanvasWidth(float width)
Setter for the canvas width in pixels.
Definition: EventDataPlotter.cc:130
Belle2::TrackFindingCDC::EventDataPlotter::EventDataPlotter
EventDataPlotter(bool animate=false, bool forwardFade=false)
Default constructor for ROOT compatibility. Uses an SVGPrimitivePlotter as backend.
Belle2::TrackFindingCDC::CDCWireHit::getHit
const CDCHit * getHit() const
Getter for the CDCHit pointer into the StoreArray.
Definition: CDCWireHit.h:167
Belle2::TrackFindingCDC::EventDataPlotter::drawRange
void drawRange(const ARange &range, const AttributeMap &attributeMap=AttributeMap())
Draws a range iterable collection of drawable elements.
Definition: EventDataPlotter.h:278
Belle2::TrackFindingCDC::Circle2D
A two dimensional circle in its natural representation using center and radius as parameters.
Definition: Circle2D.h:36
Belle2::RecoTrack::getRepresentations
const std::vector< genfit::AbsTrackRep * > & getRepresentations() const
Return a list of track representations. You are not allowed to modify or delete them!
Definition: RecoTrack.h:554
Belle2::CDCSimHit
Example Detector.
Definition: CDCSimHit.h:33
Belle2::TrackFindingCDC::Circle2D::radius
double radius() const
Getter for the signed radius.
Definition: Circle2D.h:207
Belle2::TrackFindingCDC::EventDataPlotter::getCanvasWidth
float getCanvasWidth() const
Getter for the canvas width in pixels.
Definition: EventDataPlotter.cc:110
Belle2::TrackFindingCDC::PrimitivePlotter::getBoundingBox
const BoundingBox & getBoundingBox() const
Getter for the bounding box of all drawed objects.
Definition: PrimitivePlotter.h:199
Belle2::TrackFindingCDC::EventDataPlotter::save
const std::string save(const std::string &fileName)
Saves the current plot stead to a file.
Definition: EventDataPlotter.cc:74
Belle2::MCParticle::isPrimaryParticle
bool isPrimaryParticle() const
Check if particle is a primary particle which was created by the generator (and not,...
Definition: MCParticle.h:588
Belle2::TrackFindingCDC::EventDataPlotter::draw
void draw(const Belle2::TrackFindingCDC::Circle2D &circle, AttributeMap attributeMap=AttributeMap())
Draws a filled circle.
Belle2::TrackFindingCDC::PrimitivePlotter::setCanvasHeight
void setCanvasHeight(float height)
Setter for the canvas height in pixels The canvas height denotes the size of the image being produced...
Definition: PrimitivePlotter.h:240
Belle2::TrackFindingCDC::EventDataPlotter::m_forwardFade
bool m_forwardFade
Memory for the flag whether the orientation of tracks segments etc should be shown as diming opacity.
Definition: EventDataPlotter.h:318
Belle2::RecoTrack::getCreatedTrackPoint
const genfit::TrackPoint * getCreatedTrackPoint(const RecoHitInformation *recoHitInformation) const
Get a pointer to the TrackPoint that was created from this hit.
Definition: RecoTrack.cc:220
Belle2::TrackFindingCDC::EventDataPlotter::drawTrajectory
void drawTrajectory(const MCParticle &mcParticle, const AttributeMap &attributeMap=AttributeMap())
Draws the trajectory that is represented by the MC particle.
Belle2::TrackFindingCDC::PrimitivePlotter::setCanvasWidth
void setCanvasWidth(float width)
Setter for the canvas width in pixels.
Definition: PrimitivePlotter.h:229
Belle2::TrackFindingCDC::EventDataPlotter::startGroup
void startGroup(const AttributeMap &attributeMap=AttributeMap())
Indicates the start of a group of drawn elements.
Definition: EventDataPlotter.cc:146
Belle2::TrackFindingCDC::EventDataPlotter::drawOuterCDCWall
void drawOuterCDCWall(const AttributeMap &attributeMap=AttributeMap())
Draw the outer wall of the CDC.
Definition: EventDataPlotter.cc:226
genfit::TrackPoint::getFitterInfo
AbsFitterInfo * getFitterInfo(const AbsTrackRep *rep=nullptr) const
Get fitterInfo for rep. Per default, use cardinal rep.
Definition: TrackPoint.cc:170
Belle2::TrackFindingCDC::EventDataPlotter::clear
void clear()
Clears all drawed elements from the plotter.
Definition: EventDataPlotter.cc:84
Belle2::RecoTrack
This is the Reconstruction Event-Data Model Track.
Definition: RecoTrack.h:78
Belle2::TrackFindingCDC::EventDataPlotter::endGroup
void endGroup()
Indicates the end of a group of drawn elements.
Definition: EventDataPlotter.cc:154
Belle2::TrackFindingCDC::EventDataPlotter::AttributeMap
PrimitivePlotter::AttributeMap AttributeMap
Forward the Attributre map from the primitive plotter.
Definition: EventDataPlotter.h:69
Belle2::TrackFindingCDC::EventDataPlotter::getAnimationTimeFromNanoSeconds
std::string getAnimationTimeFromNanoSeconds(float nanoseconds)
Converts a time given in nanoseconds to a time sting of the from "%fs".
Definition: EventDataPlotter.h:144
Belle2::TrackFindingCDC::PrimitivePlotter::startGroup
virtual void startGroup(const AttributeMap &attributeMap=AttributeMap())
Indicates the start of a group of drawn elements.
Definition: PrimitivePlotter.cc:97
Belle2::TrackFindingCDC::CDCWireTopology::getWireSuperLayers
const std::vector< Belle2::TrackFindingCDC::CDCWireSuperLayer > & getWireSuperLayers() const
Getter for the underlying storing superlayer vector.
Definition: CDCWireTopology.h:191
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::MCParticle::getVertex
TVector3 getVertex() const
Return production vertex position, shorthand for getProductionVertex().
Definition: MCParticle.h:194
Belle2::TrackFindingCDC::EventDataPlotter::drawSuperLayerBoundaries
void drawSuperLayerBoundaries(const AttributeMap &attributeMap=AttributeMap())
Draw the super layer bounds of the CDC.
Definition: EventDataPlotter.cc:242
Belle2::TrackFindingCDC::PrimitivePlotter::drawLine
virtual void drawLine(float startX, float startY, float endX, float endY, const AttributeMap &attributeMap=AttributeMap())
Adds a line to the plot.
Definition: PrimitivePlotter.cc:34
Belle2::TrackFindingCDC::EventDataPlotter::drawRangeWithFade
void drawRangeWithFade(const ARange &range, const AttributeMap &attributeMap=AttributeMap())
Draws a range iterable collection of drawable elements.
Definition: EventDataPlotter.h:291
Belle2::TrackFindingCDC::PrimitivePlotter
A base class for plots of primitive objects.
Definition: PrimitivePlotter.h:35
Belle2::TrackFindingCDC::EventDataPlotter::setCanvasHeight
void setCanvasHeight(float height)
Setter for the canvas height in pixels The canvas height denotes the size of the image being produced...
Definition: EventDataPlotter.cc:138
Belle2::TrackFindingCDC::CDCWireSuperLayer
Class representating a sense wire superlayer in the central drift chamber.
Definition: CDCWireSuperLayer.h:53
Belle2::TrackFindingCDC::Circle2D::center
Vector2D center() const
Getter for the central point of the circle.
Definition: Circle2D.h:231
Belle2::TrackFindingCDC::EventDataPlotter::drawLine
void drawLine(float startX, float startY, float endX, float endY, const AttributeMap &attributeMap=AttributeMap())
Draws a straight Line.
Definition: EventDataPlotter.cc:258
Belle2::RecoTrack::getRecoHitInformations
std::vector< RecoHitInformation * > getRecoHitInformations(bool getSorted=false) const
Return a list of all RecoHitInformations associated with the RecoTrack.
Definition: RecoTrack.cc:531
Belle2::TrackFindingCDC::EventDataPlotter::drawInteractionPoint
void drawInteractionPoint()
Marks the position of the interaction point with a filled circle.
Definition: EventDataPlotter.cc:198
Belle2::MCParticle::getMomentum
TVector3 getMomentum() const
Return momentum.
Definition: MCParticle.h:209
Belle2::TrackFindingCDC::PrimitivePlotter::setBoundingBox
void setBoundingBox(const BoundingBox &boundingBox)
Setter for the bounding box of all drawed objects.
Definition: PrimitivePlotter.h:205
Belle2::CDCSimHit::getMomentum
TVector3 getMomentum() const
The method to get momentum.
Definition: CDCSimHit.h:210
Belle2::TrackFindingCDC::BoundingBox
A two dimensional rectangle that keeps track of the extend of a drawing.
Definition: BoundingBox.h:31
Belle2::MCParticle
A Class to store the Monte Carlo particle information.
Definition: MCParticle.h:43
Belle2::TrackFindingCDC::EventDataPlotter::getBoundingBox
BoundingBox getBoundingBox() const
Getter for the current bounding box.
Definition: EventDataPlotter.cc:92
Belle2::StoreArray
Accessor to arrays stored in the data store.
Definition: ECLMatchingPerformanceExpertModule.h:33
Belle2::TrackFindingCDC::CDCWireHit
Class representing a hit wire in the central drift chamber.
Definition: CDCWireHit.h:65
Belle2::TrackFindingCDC::CDCWireSuperLayer::getInnerCylindricalR
double getInnerCylindricalR() const
Getter for the inner radius of the layer as retrived from the CDCGeometryPar by the inner most layer.
Definition: CDCWireSuperLayer.h:138
Belle2::TrackFindingCDC::PrimitivePlotter::getCanvasWidth
float getCanvasWidth()
Getter for the canvas width in pixels.
Definition: PrimitivePlotter.h:212
Belle2::TrackFindingCDC::CDCWireSuperLayer::getOuterCylindricalR
double getOuterCylindricalR() const
Getter for the outer radius of the layer as retrived from the CDCGeometryPar by the outer most layer.
Definition: CDCWireSuperLayer.h:142
Belle2::TrackFindingCDC::PrimitivePlotter::save
virtual const std::string save(const std::string &fileName)
Saves the current plot state to a file.
Definition: PrimitivePlotter.cc:107
Belle2::TrackFindingCDC::CDCWireTopology
Class representating the sense wire arrangement in the whole of the central drift chamber.
Definition: CDCWireTopology.h:54
Belle2::TrackFindingCDC::EventDataPlotter::setBoundingBox
void setBoundingBox(const BoundingBox &boundingBox)
Setter for the bounding box of all drawed objects.
Definition: EventDataPlotter.cc:102
Belle2::MCParticle::getProductionTime
float getProductionTime() const
Return production time in ns.
Definition: MCParticle.h:170
Belle2::TrackFindingCDC::CDCRecoHit3D::getRecoHit2D
CDCRecoHit2D getRecoHit2D() const
Constructs a two dimensional reconstructed hit by carrying out the stereo ! projection to the wire re...
Definition: CDCRecoHit3D.cc:199
Belle2::TrackFindingCDC::EventDataPlotter::getCanvasHeight
float getCanvasHeight() const
Getter for the canvas height in pixels.
Definition: EventDataPlotter.cc:120
Belle2::TrackFindingCDC::EventDataPlotter::drawInnerCDCWall
void drawInnerCDCWall(const AttributeMap &attributeMap=AttributeMap())
Draw the inner wall of the CDC.
Definition: EventDataPlotter.cc:210
Belle2::TrackFindingCDC::PrimitivePlotter::clear
virtual void clear()
Clears all drawed elements from the plotter.
Definition: PrimitivePlotter.cc:113