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