8#include <tracking/trackFindingCDC/display/EventDataPlotter.h>
10#include <tracking/trackFindingCDC/display/SVGPrimitivePlotter.h>
11#include <tracking/trackFindingCDC/display/BoundingBox.h>
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>
18#include <tracking/trackingUtilities/eventdata/segments/CDCWireHitCluster.h>
19#include <tracking/trackingUtilities/eventdata/segments/CDCSegment2D.h>
20#include <tracking/trackingUtilities/eventdata/segments/CDCSegment3D.h>
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>
27#include <cdc/topology/CDCWireTopology.h>
29#include <tracking/trackingUtilities/geometry/Circle2D.h>
30#include <tracking/trackingUtilities/geometry/VectorUtil.h>
32#include <cdc/dataobjects/CDCSimHit.h>
33#include <cdc/dataobjects/CDCHit.h>
35#include <framework/logging/Logger.h>
37#include <tracking/dataobjects/RecoTrack.h>
38#include <mdst/dataobjects/MCParticle.h>
40#include <Math/Vector3D.h>
41#include <TMatrixDSym.h>
47using namespace TrackFindingCDC;
48using namespace TrackingUtilities;
52 AttributeMap{{
"stroke",
"orange"}, {
"stroke-width",
"0.55"}, {
"fill",
"none"}}))
54, m_forwardFade(forwardFade)
65 B2ASSERT(
"EventDataPlotter initialized with nullptr. Using default backend SVGPrimitivePlotter.",
80 return primitivePlotter.
save(fileName);
90 return primitivePlotter.
clear();
174 primitivePlotter.
startGroup(groupAttributeMap);
188 const CDCHit& hit = *ptrHit;
202 ROOT::Math::XYVector center(0.0, 0.0);
205 const Circle2D interactionPoint(center, radius);
207 AttributeMap attributeMap{{
"fill",
"black"}, {
"stroke-width",
"0"}};
209 draw(interactionPoint, attributeMap);
225 primitivePlotter.
drawCircle(centerX, centerY, innerR, attributeMap);
241 primitivePlotter.
drawCircle(centerX, centerY, outerR, attributeMap);
254 float outerR = wireSuperLayer.getInnerCylindricalR();
255 primitivePlotter.
drawCircle(centerX, centerY, outerR, attributeMap);
269 primitivePlotter.
drawLine(startX, startY, endX, endY, attributeMap);
278 float radius = circle.
radius();
280 if (not attributeMap.count(
"fill") or attributeMap[
"fill"] !=
"") {
281 if (attributeMap.count(
"stroke")) {
282 attributeMap[
"fill"] = attributeMap[
"stroke"];
283 attributeMap.erase(
"stroke");
287 const ROOT::Math::XYVector& pos = circle.
center();
292 primitivePlotter.
drawCircle(x, y, radius, attributeMap);
298 const float wireRadius = 0.25;
299 const ROOT::Math::XYVector& refPos = wire.
getRefPos2D();
313 for (
const CDCWire& wire : wireLayer) {
325 wireSuperLayer.isAxial() ?
"black" :
"gray"
332 superLayerAttributeMap.insert(defaultSuperLayerAttributeMap.begin(),
333 defaultSuperLayerAttributeMap.end());
334 draw(wireSuperLayer, superLayerAttributeMap);
347 ROOT::Math::XYZVector position = simHit.
getPosTrack();
348 float x = position.X();
349 float y = position.Y();
352 primitivePlotter.
drawCircle(x, y, radius, attributeMap);
355 const float momentumToArrowLength = 1.5;
357 ROOT::Math::XYZVector momentum = simHit.
getMomentum();
358 float endX = x + momentum.X() * momentumToArrowLength;
359 float endY = y + momentum.Y() * momentumToArrowLength;
361 primitivePlotter.
drawArrow(x, y, endX, endY, attributeMap);
370 draw(wireHit, attributeMap);
381 const ROOT::Math::XYVector& refPos = wireHit.
getRefPos2D();
383 float x = refPos.x();
384 float y = refPos.y();
387 if (fabs(radius) < 100) {
388 primitivePlotter.
drawCircle(x, y, radius, attributeMap);
404 const ROOT::Math::XYVector& refPos2D = wireHit.
getRefPos2D();
405 const ROOT::Math::XYVector& recoPos2D = recoHit2D.
getRecoPos2D();
407 float x = refPos2D.x();
408 float y = refPos2D.y();
410 primitivePlotter.
drawCircle(x, y, radius, attributeMap);
412 if (not VectorUtil::hasNAN(recoPos2D)) {
413 float supportPointRadius = 0.2;
414 Circle2D supportPoint(recoPos2D, supportPointRadius);
415 draw(supportPoint, attributeMap);
428 const float fromX = fromPos.x();
429 const float fromY = fromPos.y();
432 const float toX = toPos.x();
433 const float toY = toPos.y();
435 primitivePlotter.
drawLine(fromX, fromY, toX, toY, attributeMap);
437 float touchPointRadius = 0.015;
438 const Circle2D fromTouchPoint(fromPos, touchPointRadius);
439 draw(fromTouchPoint, attributeMap);
441 const Circle2D toTouchPoint(toPos, touchPointRadius);
442 draw(toTouchPoint, attributeMap);
462 defaultAttributeMap[
"stroke"] =
"red";
463 }
else if (charge < 0) {
464 defaultAttributeMap[
"stroke"] =
"blue";
466 defaultAttributeMap[
"stroke"] =
"green";
470 attributeMap.insert(defaultAttributeMap.begin(), defaultAttributeMap.end());
472 ROOT::Math::XYVector trajectoryExit = trajectory2D.
getOuterExit();
473 if (VectorUtil::hasNAN(trajectoryExit)) {
481 if (VectorUtil::hasNAN(trajectoryExit)) {
486 float centerX = center.x();
487 float centerY = center.y();
489 primitivePlotter.
drawCircle(centerX, centerY, radius);
493 const ROOT::Math::XYVector start = trajectory2D.
getSupport();
494 float startX = start.x();
495 float startY = start.y();
497 float endX = trajectoryExit.x();
498 float endY = trajectoryExit.y();
500 const int curvature = -charge;
501 const bool sweepFlag = curvature > 0;
505 const bool longArc = (trajectory2D.
calcArcLength2D(trajectoryExit) > 0) ? false :
true;
517 if (VectorUtil::hasNAN(trajectoryExit)) {
518 B2WARNING(
"Could not compute point off exit in a straight line case.");
520 const ROOT::Math::XYVector start = trajectory2D.
getSupport();
521 float startX = start.x();
522 float startY = start.y();
524 float endX = trajectoryExit.x();
525 float endY = trajectoryExit.y();
526 primitivePlotter.
drawLine(startX, startY, endX, endY, attributeMap);
563 if (not ptrFromSegment or not ptrToSegment)
return;
568 const ROOT::Math::XYVector& fromPos = fromSegment.back().getWire().getRefPos2D();
569 const ROOT::Math::XYVector& toPos = toSegment.front().getWire().getRefPos2D();
571 if (VectorUtil::hasNAN(fromPos)) {
572 B2WARNING(
"Center of mass of first segment in a pair contains NAN values.");
576 if (VectorUtil::hasNAN(toPos)) {
577 B2WARNING(
"Center of mass of second segment in a pair contains NAN values.");
581 const float fromX = fromPos.x();
582 const float fromY = fromPos.y();
584 const float toX = toPos.x();
585 const float toY = toPos.y();
587 primitivePlotter.
drawArrow(fromX, fromY, toX, toY, attributeMap);
598 if (not ptrFromSegment or not ptrToSegment)
return;
603 const ROOT::Math::XYVector& fromPos = fromSegment.back().getWire().getRefPos2D();
604 const ROOT::Math::XYVector& toPos = toSegment.front().getWire().getRefPos2D();
606 if (VectorUtil::hasNAN(fromPos)) {
607 B2WARNING(
"Center of mass of first segment in a pair contains NAN values.");
611 if (VectorUtil::hasNAN(toPos)) {
612 B2WARNING(
"Center of mass of second segment in a pair contains NAN values.");
616 const float fromX = fromPos.x();
617 const float fromY = fromPos.y();
619 const float toX = toPos.x();
620 const float toY = toPos.y();
622 primitivePlotter.
drawArrow(fromX, fromY, toX, toY, attributeMap);
634 if (not ptrStartSegment or not ptrMiddleSegment or not ptrEndSegment)
return;
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();
645 if (VectorUtil::hasNAN(startBackPos2D)) {
646 B2WARNING(
"Back position of start segment in a triple contains NAN values.");
650 if (VectorUtil::hasNAN(middleFrontPos2D)) {
651 B2WARNING(
"Front position of middle segment in a triple contains NAN values.");
655 if (VectorUtil::hasNAN(middleBackPos2D)) {
656 B2WARNING(
"Back position of middle segment in a triple contains NAN values.");
660 if (VectorUtil::hasNAN(endFrontPos2D)) {
661 B2WARNING(
"Front position of end segment in a triple contains NAN values.");
665 const float startBackX = startBackPos2D.x();
666 const float startBackY = startBackPos2D.y();
668 const float middleFrontX = middleFrontPos2D.x();
669 const float middleFrontY = middleFrontPos2D.y();
671 primitivePlotter.
drawArrow(startBackX, startBackY, middleFrontX, middleFrontY, attributeMap);
673 const float middleBackX = middleBackPos2D.x();
674 const float middleBackY = middleBackPos2D.y();
676 const float endFrontX = endFrontPos2D.x();
677 const float endFrontY = endFrontPos2D.y();
679 primitivePlotter.
drawArrow(middleBackX, middleBackY, endFrontX, endFrontY, attributeMap);
699 const CDCHit& hit = *ptrHit;
709 ROOT::Math::XYZVector pos(mcParticle.
getVertex());
710 ROOT::Math::XYZVector mom(mcParticle.
getMomentum());
713 CDCTrajectory2D trajectory2D(VectorUtil::getXYVector(pos), time, VectorUtil::getXYVector(mom), charge);
714 draw(trajectory2D, attributeMap);
720 draw(segment.getTrajectory2D(), attributeMap);
731 draw(track.getStartTrajectory3D().getTrajectory2D(), attributeMap);
743 std::vector<std::array<float, 2>> points;
744 std::vector<std::array<float, 2>> tangents;
748 if (!recoHit->useInFit())
757 const auto* fittedResult = trackPoint->getFitterInfo();
758 if (not fittedResult) {
759 B2WARNING(
"Skipping unfitted track point");
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");
774 points.push_back({{x, y}});
775 tangents.push_back({{px, py}});
777 primitivePlotter.
drawCurve(points, tangents, attributeMap);
Class containing the result of the unpacker in raw data and the result of the digitizer in simulation...
double getFlightTime() const
The method to get flight time.
B2Vector3D getPosTrack() const
The method to get position on the track.
B2Vector3D getMomentum() const
The method to get momentum.
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.
const ROOT::Math::XYVector & getRefPos2D() const
Getter for the wire reference position for 2D tracking Gives the wire's reference position projected ...
A Class to store the Monte Carlo particle information.
ROOT::Math::XYZVector getVertex() const
Return production vertex position, shorthand for getProductionVertex().
float getCharge() const
Return the particle charge defined in TDatabasePDG.
float getProductionTime() const
Return production time in ns.
ROOT::Math::XYZVector getMomentum() const
Return momentum.
This is the Reconstruction Event-Data Model Track.
const std::vector< genfit::AbsTrackRep * > & getRepresentations() const
Return a list of track representations. You are not allowed to modify or delete them!
bool wasFitSuccessful(const genfit::AbsTrackRep *representation=nullptr) const
Returns true if the last fit with the given representation was successful.
std::vector< Belle2::RecoTrack::UsedCDCHit * > getCDCHitList() const
Return an unsorted list of cdc hits.
const genfit::TrackPoint * getCreatedTrackPoint(const RecoHitInformation *recoHitInformation) const
Get a pointer to the TrackPoint that was created from this hit.
std::vector< RecoHitInformation * > getRecoHitInformations(bool getSorted=false) const
Return a list of all RecoHitInformations associated with the RecoTrack.
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.
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.
const ROOT::Math::XYVector & getFromRecoPos2D() const
Getter for the touching point of the tangent to the first drift circle.
ROOT::Math::XYVector getToRecoPos2D() const
Getter for the touching point of the tangent to the second drift circle.
Class representing a sequence of three dimensional reconstructed hits.
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.
An aggregation of CDCWireHits.
Class representing a hit wire in the central drift chamber.
const CDCHit * getHit() const
Getter for the CDCHit pointer into the StoreArray.
double getRefDriftLength() const
Getter for the drift length at the reference position of the wire.
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.
double radius() const
Getter for the signed radius.
ROOT::Math::XYVector center() const
Getter for the central point of the circle.
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,...
Abstract base class for different kinds of events.