Belle II Software development
EVEVisualization Class Reference

Produces visualisation for MCParticles, simhits, genfit::Tracks, geometry and other things. More...

#include <EVEVisualization.h>

Classes

struct  ElementGroup
 Group of TEveElements, remembers wether user wants it visible or not. More...
 
struct  MCTrack
 Hold MC tracks and associated visualisation objects. More...
 

Public Member Functions

 EVEVisualization ()
 Constructor.
 
 EVEVisualization (const EVEVisualization &)=delete
 disabled.
 
EVEVisualizationoperator= (const EVEVisualization &)=delete
 disabled assignment
 
 ~EVEVisualization ()
 Destructor.
 
void addTrack (const Belle2::Track *belle2Track)
 Add this genfit::Track to event data.
 
void addTrackCandidate (const std::string &collectionName, const RecoTrack &recoTrack)
 Add a RecoTrack, to evaluate track finding.
 
void addTrackCandidateImproved (const std::string &collectionName, const RecoTrack &recoTrack)
 Add a RecoTrack, but use stored genfit track representation to make visualisation objects.
 
void addCDCTriggerTrack (const std::string &collectionName, const CDCTriggerTrack &track)
 Add a CDCTriggerTrack.
 
template<class T >
void addSimHits (const StoreArray< T > &hits)
 Add all entries in the given 'hits' array (and the corresponding MCParticles) to the event scene.
 
void addSimHit (const CDCSimHit *hit, const MCParticle *particle)
 Add a CDCSimHit.
 
void addSimHit (const PXDSimHit *hit, const MCParticle *particle)
 Add a PXDSimHit.
 
void addSimHit (const SVDSimHit *hit, const MCParticle *particle)
 Add a SVDSimHit.
 
void addSimHit (const KLMSimHit *hit, const MCParticle *particle)
 Add a KLMSimHit.
 
void addSimHit (const ROOT::Math::XYZVector &v, const MCParticle *particle)
 Add simhit as a simple point.
 
MCTrackaddMCParticle (const MCParticle *particle)
 Return MCTrack for given particle, add it if it doesn't exist yet.
 
void addVertex (const genfit::GFRaveVertex *vertex)
 Add a vertex point and its covariance matrix.
 
void addECLCluster (const ECLCluster *cluster)
 Add a reconstructed cluster in the ECL.
 
void addKLMCluster (const KLMCluster *cluster)
 Add a reconstructed cluster in the KLM.
 
void addBKLMHit2d (const KLMHit2d *bklm2dhit)
 Add a reconstructed 2d hit in the BKLM.
 
void addEKLMHit2d (const KLMHit2d *eklm2dhit)
 Add a reconstructed 2d hit in the EKLM.
 
void addARICHHit (const ARICHHit *hit)
 Add recontructed hit in ARICH.
 
void addROI (const ROIid *roi)
 Add a Region Of Interest, computed by the PXDDataReduction module.
 
template<class T >
void addUnassignedRecoHits (const StoreArray< T > &hits)
 After adding recohits for tracks/candidates, this function adds the remaining hits in a global collection.
 
void addCDCHit (const CDCHit *hit, bool showTriggerHits=false)
 show CDCHits directly.
 
void addCDCTriggerSegmentHit (const std::string &collectionName, const CDCTriggerSegmentHit *hit)
 show outline of track segments.
 
void addTOPDigits (const StoreArray< TOPDigit > &digits)
 Add TOPDigits (shown aggregated per module).
 
void addObject (const TObject *dataStoreObject, TEveElement *visualRepresentation)
 Generic function to keep track of which objects have which visual representation.
 
void showUserData (const DisplayData &displayData)
 Add user-defined data (labels, points, etc.)
 
void makeTracks ()
 Create visual representation of all tracks.
 
void clearEvent ()
 clear event data.
 
void setOptions (const std::string &opts)
 Set the display options.
 
void setErrScale (double errScale=1.)
 Set the scaling factor for the visualization of track hit errors.
 
void setAssignToPrimaries (bool on)
 If true, hits created by secondary particles (e.g.
 
void setHideSecondaries (bool on)
 If true, secondary MCParticles (and hits created by them) will not be shown.
 

Private Types

enum  eFitterType {
  SimpleKalman ,
  RefKalman ,
  DafSimple ,
  DafRef ,
  Gbl
}
 Fitter type to be used for addTrack(). More...
 

Private Member Functions

TEveBox * boxCreator (const ROOT::Math::XYZVector &o, ROOT::Math::XYZVector u, ROOT::Math::XYZVector v, float ud, float vd, float depth)
 Create a box around o, oriented along u and v with widths ud, vd and depth and return a pointer to the box object.
 
void makeLines (TEveTrack *eveTrack, const genfit::StateOnPlane *prevState, const genfit::StateOnPlane *state, const genfit::AbsTrackRep *rep, TEvePathMark::EType_e markType, bool drawErrors, int markerPos=1)
 Create hit visualisation for the given options, and add them to 'eveTrack'.
 
template<class SomeVXDHit >
void addRecoHit (const SomeVXDHit *hit, TEveStraightLineSet *lines)
 adds given VXD hit to lines.
 
void addRecoHit (const SVDCluster *hit, TEveStraightLineSet *lines)
 specialisation for SVDCluster
 
void addRecoHit (const CDCHit *hit, TEveStraightLineSet *lines)
 specialisation for CDCHit.
 
void addToGroup (const std::string &name, TEveElement *elem)
 Add 'elem' to the element group 'name' (created if necessary).
 

Private Attributes

TEveCalo3D * m_calo3d
 Object for the energy bar visualisation.
 
double m_errorScale
 Rescale PXD/SVD errors with this factor to ensure visibility.
 
std::string m_options
 Option string for genfit::Track visualisation.
 
bool m_assignToPrimaries
 If true, hits created by secondary particles (e.g.
 
bool m_hideSecondaries {false}
 If true, secondary MCParticles (and hits created by them) will not be shown.
 
std::map< const MCParticle *, MCTrackm_mcparticleTracks
 map MCParticles to MCTrack (so hits can be added to the correct track).
 
std::map< std::string, ElementGroupm_groups
 name -> grouping element.
 
TEveTrackList * m_tracklist
 parent object for MC tracks.
 
TEveTrackPropagator * m_trackpropagator
 Track propagator for MCParticles.
 
TEveTrackPropagator * m_gftrackpropagator
 Track propagator for genfit::Tracks (different mainly because of drawing options)
 
TEveTrackPropagator * m_consttrackpropagator
 Track propagator for CDCTriggerTracks (uses constant B field)
 
TEveCaloDataVec * m_eclData
 ECL cluster data.
 
EveVisBFieldm_bfield
 The global magnetic field.
 
std::set< const TObject * > m_shownRecohits
 List of shown recohits (PXDCluster, SVDCluster, CDCHit).
 
TEveStraightLineSet * m_unassignedRecoHits = nullptr
 Unassigned recohits.
 
bool m_unassignedRecoHitsVisibility = true
 is m_unassignedRecoHits visible?
 
bool m_drawCardinalRep = true
 Draw cardinal representation in addTrack.
 
bool m_drawErrors = false
 Draw errors in addTrack.
 
bool m_drawRefTrack = false
 Draw reference track in addTrack.
 
bool m_drawForward = false
 draw forward in addTrack
 
bool m_drawBackward = false
 draw backward in addTrack
 

Static Private Attributes

static const int c_recoHitColor = getTColorID("Orange", 1)
 Color for reco hits.
 
static const int c_recoTrackColor = getTColorID("Sky Blue", 1)
 Color for TrackCandidates.
 
static const int c_trackColor = getTColorID("Sky Blue", 2)
 Color for tracks.
 
static const int c_trackMarkerColor = getTColorID("Chameleon", 3)
 Color for track markers.
 
static const int c_unassignedHitColor = getTColorID("Plum", 1)
 Color for unassigned (reco)hits.
 
static const int c_klmClusterColor = getTColorID("Chameleon", 1)
 Color for KLMCluster objects.
 
static constexpr double c_minPCut = 0.00
 don't show MCParticles with momentum below this cutoff.
 

Detailed Description

Produces visualisation for MCParticles, simhits, genfit::Tracks, geometry and other things.

Creates TEve objects from the given data, and adds them to the global or event scene.

See also
DisplayModule

Definition at line 63 of file EVEVisualization.h.

Member Enumeration Documentation

◆ eFitterType

enum eFitterType
private

Fitter type to be used for addTrack().

Definition at line 65 of file EVEVisualization.h.

65 {
66 SimpleKalman,
67 RefKalman,
68 DafSimple,
69 DafRef,
70 Gbl
71 };

Constructor & Destructor Documentation

◆ EVEVisualization()

EVEVisualization ( )
explicit

Constructor.

Definition at line 134 of file EVEVisualization.cc.

134 :
135 m_assignToPrimaries(false),
136 m_eclData(0),
138{
139 setErrScale();
140
141 TGLLogicalShape::SetIgnoreSizeForCameraInterest(kTRUE); // Allows the visualization of the "small" error ellipsoid.
142
143 //create new containers
144 m_trackpropagator = new TEveTrackPropagator();
145 m_trackpropagator->IncDenyDestroy();
146 m_trackpropagator->SetMagFieldObj(m_bfield, false);
147 m_trackpropagator->SetFitDaughters(false); //most secondaries are no longer immediate daughters since we might discard those!
148 m_trackpropagator->SetMaxR(EveGeometry::getMaxR()); //don't draw tracks outside detector
149 //TODO is this actually needed?
150 m_trackpropagator->SetMaxStep(1.0); //make sure to reeval magnetic field often enough
151
152 m_tracklist = new TEveTrackList(m_trackpropagator);
153 m_tracklist->IncDenyDestroy();
154 m_tracklist->SetName("MCParticles");
155 m_tracklist->SelectByP(c_minPCut, FLT_MAX); //don't show too many particles by default...
156
157 m_gftrackpropagator = new TEveTrackPropagator();
158 m_gftrackpropagator->IncDenyDestroy();
159 m_gftrackpropagator->SetMagFieldObj(m_bfield, false);
160 m_gftrackpropagator->SetMaxOrbs(0.5); //stop after track markers
161
162 m_consttrackpropagator = new TEveTrackPropagator();
163 m_consttrackpropagator->IncDenyDestroy();
164 m_consttrackpropagator->SetMagField(0, 0, -1.5);
166
167 m_calo3d = new TEveCalo3D(NULL, "ECLClusters");
168 m_calo3d->SetBarrelRadius(125.80); //inner radius of ECL barrel
169 m_calo3d->SetForwardEndCapPos(196.5); //inner edge of forward endcap
170 m_calo3d->SetBackwardEndCapPos(-102.0); //inner edge of backward endcap
171 m_calo3d->SetMaxValAbs(2.1);
172 m_calo3d->SetRnrFrame(false, false); //don't show crystal grid
173 m_calo3d->IncDenyDestroy();
174
175 //Stop eve from deleting contents... (which might already be deleted)
176 gEve->GetSelection()->IncDenyDestroy();
177 gEve->GetHighlight()->IncDenyDestroy();
178
179 clearEvent();
180}
void clearEvent()
clear event data.
static constexpr double c_minPCut
don't show MCParticles with momentum below this cutoff.
EveVisBField * m_bfield
The global magnetic field.
void setErrScale(double errScale=1.)
Set the scaling factor for the visualization of track hit errors.
TEveCalo3D * m_calo3d
Object for the energy bar visualisation.
TEveTrackPropagator * m_trackpropagator
Track propagator for MCParticles.
TEveTrackList * m_tracklist
parent object for MC tracks.
TEveTrackPropagator * m_gftrackpropagator
Track propagator for genfit::Tracks (different mainly because of drawing options)
TEveTrackPropagator * m_consttrackpropagator
Track propagator for CDCTriggerTracks (uses constant B field)
bool m_assignToPrimaries
If true, hits created by secondary particles (e.g.
TEveCaloDataVec * m_eclData
ECL cluster data.
Provide magnetic field values for TEveTrackPropagator.
Definition: EveVisBField.h:19
double getMaxR()
find a point that is inside the top node.
Definition: EveGeometry.cc:184

◆ ~EVEVisualization()

Destructor.

Definition at line 186 of file EVEVisualization.cc.

187{
188 if (!gEve)
189 return; //objects are probably already freed by Eve
190
191 //Eve objects
192 destroyEveElement(m_eclData);
193 destroyEveElement(m_unassignedRecoHits);
194 destroyEveElement(m_tracklist);
195 destroyEveElement(m_trackpropagator);
196 destroyEveElement(m_gftrackpropagator);
197 destroyEveElement(m_consttrackpropagator);
198 destroyEveElement(m_calo3d);
199 delete m_bfield;
200}
TEveStraightLineSet * m_unassignedRecoHits
Unassigned recohits.

Member Function Documentation

◆ addARICHHit()

void addARICHHit ( const ARICHHit hit)

Add recontructed hit in ARICH.

Definition at line 1772 of file EVEVisualization.cc.

1773{
1775
1776 int hitModule = hit->getModule();
1777 float fi = arichGeo->getDetectorPlane().getSlotPhi(hitModule);
1778
1779 ROOT::Math::XYZVector centerPos3D = hit->getPosition();
1780
1781 ROOT::Math::RotationZ rotZ(fi);
1782 ROOT::Math::XYZVector channelX(1, 0, 0);
1783 ROOT::Math::XYZVector channelY(0, 1, 0);
1784 channelX = rotZ * channelX;
1785 channelY = rotZ * channelY;
1786
1787 auto* arichbox = boxCreator(centerPos3D,
1788 arichGeo->getMasterVolume().momentumToGlobal(channelX),
1789 arichGeo->getMasterVolume().momentumToGlobal(channelY),
1790 0.49, 0.49, 0.05);
1791 arichbox->SetMainColor(kOrange + 10);
1792 arichbox->SetName((std::to_string(hitModule)).c_str());
1793
1794 addToGroup("ARICHHits", arichbox);
1795 addObject(hit, arichbox);
1796}
Class for accessing objects in the database.
Definition: DBObjPtr.h:21
TEveBox * boxCreator(const ROOT::Math::XYZVector &o, ROOT::Math::XYZVector u, ROOT::Math::XYZVector v, float ud, float vd, float depth)
Create a box around o, oriented along u and v with widths ud, vd and depth and return a pointer to th...
void addToGroup(const std::string &name, TEveElement *elem)
Add 'elem' to the element group 'name' (created if necessary).
void addObject(const TObject *dataStoreObject, TEveElement *visualRepresentation)
Generic function to keep track of which objects have which visual representation.

◆ addBKLMHit2d()

void addBKLMHit2d ( const KLMHit2d bklm2dhit)

Add a reconstructed 2d hit in the BKLM.

Definition at line 1494 of file EVEVisualization.cc.

1495{
1497 const bklm::Module* module = m_GeoPar->findModule(bklm2dhit->getSection(), bklm2dhit->getSector(), bklm2dhit->getLayer());
1498
1499 CLHEP::Hep3Vector global;
1500 //+++ global coordinates of the hit
1501 global[0] = bklm2dhit->getPositionX();
1502 global[1] = bklm2dhit->getPositionY();
1503 global[2] = bklm2dhit->getPositionZ();
1504
1505 //+++ local coordinates of the hit
1506 CLHEP::Hep3Vector local = module->globalToLocal(global);
1507 //double localU = local[1]; //phi
1508 //double localV = local[2]; //z
1509 int Nphistrip = bklm2dhit->getPhiStripMax() - bklm2dhit->getPhiStripMin() + 1;
1510 int Nztrip = bklm2dhit->getZStripMax() - bklm2dhit->getZStripMin() + 1;
1511 double du = module->getPhiStripWidth() * Nphistrip;
1512 double dv = module->getZStripWidth() * Nztrip;
1513
1514 //Let's do some simple thing
1515 CLHEP::Hep3Vector localU(local[0], local[1] + 1.0, local[2]);
1516 CLHEP::Hep3Vector localV(local[0], local[1], local[2] + 1.0);
1517
1518 CLHEP::Hep3Vector globalU = module->localToGlobal(localU);
1519 CLHEP::Hep3Vector globalV = module->localToGlobal(localV);
1520
1521 ROOT::Math::XYZVector o(global[0], global[1], global[2]);
1522 ROOT::Math::XYZVector u(globalU[0], globalU[1], globalU[2]);
1523 ROOT::Math::XYZVector v(globalV[0], globalV[1], globalV[2]);
1524
1525 //Lest's just assign the depth is 1.0 cm (thickness of a layer), better to update
1526 TEveBox* bklmbox = boxCreator(o, u - o, v - o, du, dv, 1.0);
1527
1528 bklmbox->SetMainColor(kGreen);
1529 //bklmbox->SetName((std::to_string(hitModule)).c_str());
1530 bklmbox->SetName("BKLMHit2d");
1531
1532 addToGroup("BKLM2dHits", bklmbox);
1533 addObject(bklm2dhit, bklmbox);
1534}
int getLayer() const
Get layer number.
Definition: KLMHit2d.h:132
int getZStripMax() const
Get last strip number for z plane.
Definition: KLMHit2d.h:202
int getSection() const
Get section number.
Definition: KLMHit2d.h:96
float getPositionZ() const
Get hit global position z coordinate.
Definition: KLMHit2d.h:306
int getSector() const
Get sector number.
Definition: KLMHit2d.h:114
float getPositionX() const
Get hit global position x coordinate.
Definition: KLMHit2d.h:288
int getPhiStripMin() const
Get strip number for phi plane.
Definition: KLMHit2d.h:218
int getZStripMin() const
Get strip number for z plane.
Definition: KLMHit2d.h:194
int getPhiStripMax() const
Get last strip number for phi plane.
Definition: KLMHit2d.h:226
float getPositionY() const
Get hit global position y coordinate.
Definition: KLMHit2d.h:297
Provides BKLM geometry parameters for simulation, reconstruction etc (from Gearbox or DataBase)
Definition: GeometryPar.h:37
const Module * findModule(int section, int sector, int layer) const
Get the pointer to the definition of a module.
Definition: GeometryPar.cc:721
static GeometryPar * instance(void)
Static method to get a reference to the singleton GeometryPar instance.
Definition: GeometryPar.cc:27
Define the geometry of a BKLM module Each sector [octant] contains Modules.
Definition: Module.h:76

◆ addCDCHit()

void addCDCHit ( const CDCHit hit,
bool  showTriggerHits = false 
)

show CDCHits directly.

Definition at line 1613 of file EVEVisualization.cc.

1614{
1616 const B2Vector3D& wire_pos_f = cdcgeo.wireForwardPosition(WireID(hit->getID()));
1617 const B2Vector3D& wire_pos_b = cdcgeo.wireBackwardPosition(WireID(hit->getID()));
1618 static CDC::RealisticTDCCountTranslator tdcTranslator;
1619 TEveGeoShape* cov_shape = new TEveGeoShape("cov_shape");
1620 //TODO: leftrightflag not set! (same for other parameters, unsure which ones should be set)
1621 double driftLength = tdcTranslator.getDriftLength(hit->getTDCCount(), WireID(hit->getID()));
1622 double driftLengthRes = tdcTranslator.getDriftLengthResolution(driftLength, WireID(hit->getID()));
1623 driftLengthRes = std::max(driftLengthRes, 0.005);
1624 const double lengthOfWireSection = 3.0;
1625
1626 //z in wire direction, x,y orthogonal
1627 const B2Vector3D zaxis = wire_pos_b - wire_pos_f;
1628 const B2Vector3D xaxis = zaxis.Orthogonal();
1629 const B2Vector3D yaxis = xaxis.Cross(zaxis);
1630
1631 // move to z=0
1632 const B2Vector3D midPoint = wire_pos_f - zaxis * (wire_pos_f.Z() / zaxis.Z());
1633
1634 cov_shape->SetShape(new TGeoTube(std::max(0., (double)(driftLength - driftLengthRes)), driftLength + driftLengthRes,
1635 lengthOfWireSection));
1636 fixGeoShapeRefCount(cov_shape);
1637
1638 TGeoRotation det_rot("det_rot",
1639 xaxis.Theta() * 180 / TMath::Pi(), xaxis.Phi() * 180 / TMath::Pi(),
1640 yaxis.Theta() * 180 / TMath::Pi(), yaxis.Phi() * 180 / TMath::Pi(),
1641 zaxis.Theta() * 180 / TMath::Pi(), zaxis.Phi() * 180 / TMath::Pi()
1642 );
1643
1644 TGeoCombiTrans det_trans(midPoint.X(), midPoint.Y(), midPoint.Z(), &det_rot);
1645 cov_shape->SetTransMatrix(det_trans);
1646
1647 // get relation to trigger track segments
1648 bool isPartOfTS = false;
1649 const auto segments = hit->getRelationsFrom<CDCTriggerSegmentHit>();
1650 if (showTriggerHits && segments.size() > 0) {
1651 isPartOfTS = true;
1652 }
1653
1654 if (hit->getISuperLayer() % 2 == 0) {
1655 if (isPartOfTS)
1656 cov_shape->SetMainColor(kCyan + 3);
1657 else
1658 cov_shape->SetMainColor(kCyan);
1659 } else {
1660 if (isPartOfTS)
1661 cov_shape->SetMainColor(kPink + 6);
1662 else
1663 cov_shape->SetMainColor(kPink + 7);
1664 }
1665
1666 cov_shape->SetMainTransparency(50);
1667 cov_shape->SetName(ObjectInfo::getIdentifier(hit));
1668 cov_shape->SetTitle(ObjectInfo::getInfo(hit) + TString::Format("\nWire ID: %d\nADC: %d\nTDC: %d",
1669 hit->getID(), hit->getADCCount(), hit->getTDCCount()));
1670
1671 addToGroup("CDCHits", cov_shape);
1672 addObject(hit, cov_shape);
1673 if (isPartOfTS) {
1674 addToGroup("CDCTriggerSegmentHits", cov_shape);
1675 for (auto rel : segments.relations()) {
1676 addObject(rel.object, cov_shape);
1677 }
1678 }
1679}
DataType Phi() const
The azimuth angle.
Definition: B2Vector3.h:151
DataType Z() const
access variable Z (= .at(2) without boundary check)
Definition: B2Vector3.h:435
DataType Theta() const
The polar angle.
Definition: B2Vector3.h:153
B2Vector3< DataType > Cross(const B2Vector3< DataType > &p) const
Cross product.
Definition: B2Vector3.h:296
DataType X() const
access variable X (= .at(0) without boundary check)
Definition: B2Vector3.h:431
B2Vector3< DataType > Orthogonal() const
Vector orthogonal to this one.
Definition: B2Vector3.h:277
DataType Y() const
access variable Y (= .at(1) without boundary check)
Definition: B2Vector3.h:433
Combination of several CDCHits to a track segment hit for the trigger.
The Class for CDC Geometry Parameters.
const B2Vector3D wireForwardPosition(uint layerId, int cellId, EWirePosition set=c_Base) const
Returns the forward position of the input sense wire.
const B2Vector3D wireBackwardPosition(uint layerId, int cellId, EWirePosition set=c_Base) const
Returns the backward position of the input sense wire.
static CDCGeometryPar & Instance(const CDCGeometry *=nullptr)
Static method to get a reference to the CDCGeometryPar instance.
Translator mirroring the realistic Digitization.
double getDriftLength(unsigned short tdcCount, const WireID &wireID=WireID(), double timeOfFlightEstimator=0, bool leftRight=false, double z=0, double alpha=0, double theta=static_cast< double >(TMath::Pi()/2.), unsigned short adcCount=0) override
Get Drift length.
double getDriftLengthResolution(double driftLength, const WireID &wireID=WireID(), bool leftRight=false, double z=0, double alpha=0, double=static_cast< double >(TMath::Pi()/2.)) override
Get position resolution^2 corresponding to the drift length from getDriftLength of this class.
Class to identify a wire inside the CDC.
Definition: WireID.h:34
TString getIdentifier(const TObject *obj)
Where is this object in the datastore?
Definition: ObjectInfo.cc:105
TString getInfo(const TObject *obj)
Get object info HTML (e.g.
Definition: ObjectInfo.cc:55

◆ addCDCTriggerSegmentHit()

void addCDCTriggerSegmentHit ( const std::string &  collectionName,
const CDCTriggerSegmentHit hit 
)

show outline of track segments.

Definition at line 1681 of file EVEVisualization.cc.

1682{
1684 TEveStraightLineSet* shape = new TEveStraightLineSet();
1685
1686 // get center wire
1687 unsigned iL = WireID(hit->getID()).getICLayer();
1688 if (hit->getPriorityPosition() < 3) iL -= 1;
1689 unsigned nWires = cdcgeo.nWiresInLayer(iL);
1690 unsigned iCenter = hit->getIWire();
1691 if (hit->getPriorityPosition() == 1) iCenter += 1;
1692
1693 // a track segment consists of 11 wires (15 in SL0) in a special configuration
1694 // -> get the shift with respect to the center wire (*) for all wires
1695 // SL 1-8:
1696 // _ _ _
1697 // |_|_|_|
1698 // |_|_|
1699 // |*|
1700 // |_|_|
1701 // |_|_|_|
1702 std::vector<int> layershift = { -2, -1, 0, 1, 2};
1703 std::vector<std::vector<float>> cellshift = {
1704 { -1, 0, 1},
1705 { -0.5, 0.5},
1706 { 0},
1707 { -0.5, 0.5},
1708 { -1, 0, 1}
1709 };
1710 // SL 0:
1711 // _ _ _ _ _
1712 // |_|_|_|_|_|
1713 // |_|_|_|_|
1714 // |_|_|_|
1715 // |_|_|
1716 // |*|
1717 if (hit->getISuperLayer() == 0) {
1718 layershift = { 0, 1, 2, 3, 4};
1719 cellshift = {
1720 { 0},
1721 { -0.5, 0.5},
1722 { -1, 0, 1},
1723 { -1.5, -0.5, 0.5, 1.5},
1724 { -2, -1, 0, 1, 2}
1725 };
1726 }
1727
1728 // draw all cells in segment
1729 for (unsigned il = 0; il < layershift.size(); ++il) {
1730 for (unsigned ic = 0; ic < cellshift[il].size(); ++ic) {
1731 ROOT::Math::XYZVector corners[2][2];
1732 for (unsigned ir = 0; ir < 2; ++ir) {
1733 double r = cdcgeo.fieldWireR(iL + layershift[il] - ir);
1734 double fz = cdcgeo.fieldWireFZ(iL + layershift[il] - ir);
1735 double bz = cdcgeo.fieldWireBZ(iL + layershift[il] - ir);
1736 for (unsigned iphi = 0; iphi < 2; ++iphi) {
1737 double phib = (iCenter + cellshift[il][ic] + iphi - 0.5) * 2 * M_PI / nWires;
1738 double phif = phib + cdcgeo.nShifts(iL + layershift[il]) * M_PI / nWires;
1739
1740 ROOT::Math::XYZVector pos_f = ROOT::Math::XYZVector(cos(phif) * r, sin(phif) * r, fz);
1741 ROOT::Math::XYZVector pos_b = ROOT::Math::XYZVector(cos(phib) * r, sin(phib) * r, bz);
1742 ROOT::Math::XYZVector zaxis = pos_b - pos_f;
1743 corners[ir][iphi] = pos_f - zaxis * (pos_f.Z() / zaxis.Z());
1744 }
1745 }
1746
1747 shape->AddLine(corners[0][0].X(), corners[0][0].Y(), 0,
1748 corners[0][1].X(), corners[0][1].Y(), 0);
1749 shape->AddLine(corners[0][1].X(), corners[0][1].Y(), 0,
1750 corners[1][1].X(), corners[1][1].Y(), 0);
1751 shape->AddLine(corners[1][1].X(), corners[1][1].Y(), 0,
1752 corners[1][0].X(), corners[1][0].Y(), 0);
1753 shape->AddLine(corners[1][0].X(), corners[1][0].Y(), 0,
1754 corners[0][0].X(), corners[0][0].Y(), 0);
1755 }
1756 }
1757
1758 if (hit->getISuperLayer() % 2 == 0) {
1759 shape->SetMainColor(kCyan + 3);
1760 } else {
1761 shape->SetMainColor(kPink + 6);
1762 }
1763
1764 shape->SetName(ObjectInfo::getIdentifier(hit));
1765 shape->SetTitle(ObjectInfo::getTitle(hit) +
1766 TString::Format("\nPriority: %d\nLeft/Right: %d",
1767 hit->getPriorityPosition(), hit->getLeftRight()));
1768 addToGroup(collectionName, shape);
1769 addObject(hit, shape);
1770}
int nShifts(int layerId) const
Returns number shift.
double fieldWireR(int layerId) const
Returns radius of field wire in each layer.
unsigned nWiresInLayer(int layerId) const
Returns wire numbers in a layer.
double fieldWireBZ(int layerId) const
Returns backward z position of field wire in each layer.
double fieldWireFZ(int layerId) const
Returns forward z position of field wire in each layer.
unsigned short getICLayer() const
Getter for continuous layer numbering.
Definition: WireID.cc:24
TString getTitle(const TObject *obj)
Get plain text for TEve object titles (shown on mouse-over).
Definition: ObjectInfo.cc:68

◆ addCDCTriggerTrack()

void addCDCTriggerTrack ( const std::string &  collectionName,
const CDCTriggerTrack track 
)

Add a CDCTriggerTrack.

Definition at line 346 of file EVEVisualization.cc.

348{
349 const TString label = ObjectInfo::getIdentifier(&trgTrack);
350
351 B2Vector3D track_pos = B2Vector3D(0, 0, trgTrack.getZ0());
352 B2Vector3D track_mom = (trgTrack.getChargeSign() == 0) ?
353 trgTrack.getDirection() * 1000 :
354 trgTrack.getMomentum(1.5);
355
356 TEveRecTrack rectrack;
357 rectrack.fP.Set(track_mom);
358 rectrack.fV.Set(track_pos);
359
360 TEveTrack* track_lines = new TEveTrack(&rectrack, m_consttrackpropagator);
361 track_lines->SetName(label); //popup label set at end of function
362 track_lines->SetPropagator(m_consttrackpropagator);
363 track_lines->SetLineColor(kOrange + 2);
364 track_lines->SetLineWidth(1);
365 track_lines->SetTitle(ObjectInfo::getTitle(&trgTrack) +
366 TString::Format("\ncharge: %d, phi: %.2fdeg, pt: %.2fGeV, theta: %.2fdeg, z: %.2fcm",
367 trgTrack.getChargeSign(),
368 trgTrack.getPhi0() * 180 / M_PI,
369 trgTrack.getTransverseMomentum(1.5),
370 trgTrack.getDirection().Theta() * 180 / M_PI,
371 trgTrack.getZ0()));
372
373
374 track_lines->SetCharge(trgTrack.getChargeSign());
375
376 // show 2D tracks with dashed lines
377 if (trgTrack.getZ0() == 0 && trgTrack.getCotTheta() == 0)
378 track_lines->SetLineStyle(2);
379
380 addToGroup(collectionName, track_lines);
381 addObject(&trgTrack, track_lines);
382}
B2Vector3< double > B2Vector3D
typedef for common usage with double
Definition: B2Vector3.h:516

◆ addECLCluster()

void addECLCluster ( const ECLCluster cluster)

Add a reconstructed cluster in the ECL.

Definition at line 1403 of file EVEVisualization.cc.

1404{
1405
1406 // only display c_nPhotons hypothesis clusters
1407 if (cluster->hasHypothesis(ECLCluster::EHypothesisBit::c_nPhotons)) {
1408
1409 const float phi = cluster->getPhi();
1410 float dPhi = cluster->getUncertaintyPhi();
1411 float dTheta = cluster->getUncertaintyTheta();
1412 if (dPhi >= M_PI / 4 or dTheta >= M_PI / 4 or cluster->getUncertaintyEnergy() == 1.0) {
1413 B2WARNING("Found ECL cluster with broken errors (unit matrix or too large). Using 0.05 as error in phi/theta. The 3x3 error matrix previously was:");
1414 cluster->getCovarianceMatrix3x3().Print();
1415 dPhi = dTheta = 0.05;
1416 }
1417
1418 if (!std::isfinite(dPhi) or !std::isfinite(dTheta)) {
1419 B2ERROR("ECLCluster phi or theta error is NaN or infinite, skipping cluster!");
1420 return;
1421 }
1422
1423 //convert theta +- dTheta into eta +- dEta
1424 ROOT::Math::XYZVector thetaLow;
1425 VectorUtil::setPtThetaPhi(thetaLow, 1.0, cluster->getTheta() - dTheta, phi);
1426 ROOT::Math::XYZVector thetaHigh;
1427 VectorUtil::setPtThetaPhi(thetaHigh, 1.0, cluster->getTheta() + dTheta, phi);
1428 float etaLow = thetaLow.Eta();
1429 float etaHigh = thetaHigh.Eta();
1430 if (etaLow > etaHigh) {
1431 std::swap(etaLow, etaHigh);
1432 }
1433
1434 int id = m_eclData->AddTower(etaLow, etaHigh, phi - dPhi, phi + dPhi);
1435 m_eclData->FillSlice(0, cluster->getEnergy(ECLCluster::EHypothesisBit::c_nPhotons));
1437 }
1438}
@ c_nPhotons
CR is split into n photons (N1)
void addCluster(const TObject *dataStoreObject, TEveCaloData *caloData, int towerID)
Selection inside TEveCalo* is complicated, use this to keep track of ECL clusters.
static VisualRepMap * getInstance()
get instance pointer.
Definition: VisualRepMap.cc:36

◆ addEKLMHit2d()

void addEKLMHit2d ( const KLMHit2d eklm2dhit)

Add a reconstructed 2d hit in the EKLM.

Definition at line 1536 of file EVEVisualization.cc.

1537{
1538 const double du = 2.0;
1539 const double dv = 2.0;
1540 ROOT::Math::XYZVector hitPosition = eklm2dhit->getPosition();
1541 ROOT::Math::XYZVector o(hitPosition.X(), hitPosition.Y(), hitPosition.Z());
1542 ROOT::Math::XYZVector u(1.0, 0.0, 0.0);
1543 ROOT::Math::XYZVector v(0.0, 1.0, 0.0);
1544 TEveBox* eklmbox = boxCreator(o, u, v, du, dv, 4.0);
1545 eklmbox->SetMainColor(kGreen);
1546 eklmbox->SetName("EKLMHit2d");
1547 addToGroup("EKLM2dHits", eklmbox);
1548 addObject(eklm2dhit, eklmbox);
1549}
ROOT::Math::XYZVector getPosition() const
Get hit global position.
Definition: KLMHit2d.h:315

◆ addKLMCluster()

void addKLMCluster ( const KLMCluster cluster)

Add a reconstructed cluster in the KLM.

Definition at line 1440 of file EVEVisualization.cc.

1441{
1442 const double layerThicknessCm = 3.16; //TDR, Fig 10.2
1443 const double layerDistanceCm = 9.1 - layerThicknessCm;
1444
1445 // Pposition of first RPC plane.
1446 ROOT::Math::XYZVector position = cluster->getClusterPosition();
1447 ROOT::Math::XYZVector startPos(position.X(), position.Y(), position.Z());
1448 ROOT::Math::XYZVector dir; //direction of cluster stack, Mag() == distance between planes
1449 ROOT::Math::XYZVector a, b; //defines RPC plane
1450 bool isBarrel = (startPos.Z() > -175.0 and startPos.Z() < 270.0);
1451 if (isBarrel) {
1452 //barrel
1453 b = ROOT::Math::XYZVector(0, 0, 1);
1454 a = startPos.Cross(b).Unit();
1455 double c = M_PI / 4.0;
1456 double offset = c / 2.0 + M_PI;
1457 VectorUtil::setPhi(a, int((a.Phi() + offset) / (c))*c - M_PI);
1458 ROOT::Math::XYZVector perp = b.Cross(a);
1459
1460 const double barrelRadiusCm = 204.0;
1461 VectorUtil::setMag(startPos, barrelRadiusCm / perp.Dot(startPos.Unit()));
1462
1463 dir = startPos.Unit();
1464 VectorUtil::setMag(dir, (layerDistanceCm + layerThicknessCm) / perp.Dot(dir));
1465 } else {
1466 //endcap
1467 b = ROOT::Math::XYZVector(startPos.X(), startPos.Y(), 0).Unit();
1468 a = startPos.Cross(b).Unit();
1469 double endcapStartZ = 284;
1470 if (startPos.Z() < 0)
1471 endcapStartZ = -189.5;
1472
1473 double scaleFac = endcapStartZ / startPos.Z();
1474 VectorUtil::setMag(startPos, startPos.R() * scaleFac);
1475
1476 dir = startPos.Unit();
1477 VectorUtil::setMag(dir, (layerDistanceCm + layerThicknessCm) / fabs(dir.Z()));
1478 }
1479
1480 for (int i = 0; i < cluster->getLayers(); i++) {
1481 ROOT::Math::XYZVector layerPos = startPos;
1482 layerPos += (cluster->getInnermostLayer() + i) * dir;
1483 auto* layer = boxCreator(layerPos, a, b, 20.0, 20.0, layerThicknessCm / 2);
1484 layer->SetMainColor(c_klmClusterColor);
1485 layer->SetMainTransparency(70);
1486 layer->SetName(ObjectInfo::getIdentifier(cluster));
1487 layer->SetTitle(ObjectInfo::getTitle(cluster));
1488
1489 addToGroup(std::string("KLMClusters/") + ObjectInfo::getIdentifier(cluster).Data(), layer);
1490 addObject(cluster, layer);
1491 }
1492}
static const int c_klmClusterColor
Color for KLMCluster objects.
bool isBarrel(int cellId)
Check whether the crystal is in barrel ECL.

◆ addMCParticle()

EVEVisualization::MCTrack * addMCParticle ( const MCParticle particle)

Return MCTrack for given particle, add it if it doesn't exist yet.

If particle is NULL, a dummy MCTrack (with track=0) is created which can accept otherwise unassigned hits. Returns NULL if this particle and its hits shouldn't be shown.

Definition at line 1102 of file EVEVisualization.cc.

1103{
1104 if (!particle) {
1105 if (!m_mcparticleTracks[nullptr].simhits) {
1106 const TString pointsTitle("Unassigned SimHits");
1107 m_mcparticleTracks[nullptr].simhits = new TEvePointSet(pointsTitle);
1108 m_mcparticleTracks[nullptr].simhits->SetTitle(pointsTitle);
1109 m_mcparticleTracks[nullptr].simhits->SetMarkerStyle(6);
1110 m_mcparticleTracks[nullptr].simhits->SetMainColor(c_unassignedHitColor);
1111 //m_mcparticleTracks[nullptr].simhits->SetMainTransparency(50);
1112 m_mcparticleTracks[nullptr].track = NULL;
1113 }
1114 return &m_mcparticleTracks[nullptr];
1115 }
1116
1117 if (m_hideSecondaries and !particle->hasStatus(MCParticle::c_PrimaryParticle)) {
1118 return NULL;
1119 }
1120 if (m_assignToPrimaries) {
1121 while (!particle->hasStatus(MCParticle::c_PrimaryParticle) and particle->getMother())
1122 particle = particle->getMother();
1123 }
1124
1125 if (!m_mcparticleTracks[particle].track) {
1126 const ROOT::Math::XYZVector& p = particle->getMomentum();
1127 const ROOT::Math::XYZVector& vertex = particle->getProductionVertex();
1128 const int pdg = particle->getPDG();
1129 TParticle tparticle(pdg, particle->getStatus(),
1130 (particle->getMother() ? particle->getMother()->getIndex() : 0), 0, particle->getFirstDaughter(), particle->getLastDaughter(),
1131 p.X(), p.Y(), p.Z(), particle->getEnergy(),
1132 vertex.X(), vertex.Y(), vertex.Z(), particle->getProductionTime());
1133 TEveMCTrack mctrack;
1134 mctrack = tparticle;
1135 mctrack.fTDecay = particle->getDecayTime();
1136 mctrack.fVDecay.Set(B2Vector3D(particle->getDecayVertex()));
1137 mctrack.fDecayed = !std::isinf(mctrack.fTDecay);
1138 mctrack.fIndex = particle->getIndex();
1139 m_mcparticleTracks[particle].track = new TEveTrack(&mctrack, m_trackpropagator);
1140
1141 //Check if there is a trajectory stored for this particle
1142 const auto mcTrajectories = particle->getRelationsTo<MCParticleTrajectory>();
1143 bool hasTrajectory(false);
1144 for (auto rel : mcTrajectories.relations()) {
1145 //Trajectories with negative weight are from secondary daughters which
1146 //were ignored so we don't use them.
1147 if (rel.weight <= 0) continue;
1148 //Found one, let's add tose point as reference points to the TEveTrack.
1149 //This will force the track propagation to visit all points in order but
1150 //provide smooth helix interpolation between the points
1151 const MCParticleTrajectory& trajectory = dynamic_cast<const MCParticleTrajectory&>(*rel.object);
1152 for (const MCTrajectoryPoint& pt : trajectory) {
1153 m_mcparticleTracks[particle].track->AddPathMark(
1154 TEvePathMark(
1155 //Add the last trajectory point as decay point to prevent TEve to
1156 //propagate beyond the end of the track. So lets compare the adress
1157 //to the address of last point and choose the pathmark accordingly
1158 (&pt == &trajectory.back()) ? TEvePathMark::kDecay : TEvePathMark::kReference,
1159 TEveVector(pt.x, pt.y, pt.z),
1160 TEveVector(pt.px, pt.py, pt.pz)
1161 ));
1162 }
1163 //"There can only be One" -> found a trajectory, stop the loop
1164 hasTrajectory = true;
1165 break;
1166 }
1167
1168 //If we have the full trajectory there is no need to add additional path marks
1169 if (!hasTrajectory) {
1170 //add daughter vertices - improves track rendering as lost momentum is taken into account
1171 for (int iDaughter = particle->getFirstDaughter(); iDaughter <= particle->getLastDaughter(); iDaughter++) {
1172 if (iDaughter == 0)
1173 continue; //no actual daughter
1174
1175 const MCParticle* daughter = StoreArray<MCParticle>()[iDaughter - 1];
1176
1177 TEvePathMarkD refMark(TEvePathMarkD::kDaughter);
1178 refMark.fV.Set(B2Vector3D(daughter->getProductionVertex()));
1179 refMark.fP.Set(B2Vector3D(daughter->getMomentum()));
1180 refMark.fTime = daughter->getProductionTime();
1181 m_mcparticleTracks[particle].track->AddPathMark(refMark);
1182 }
1183
1184 //neutrals and very short-lived particles should stop somewhere
1185 //(can result in wrong shapes for particles stopped in the detector, so not used there)
1186 if ((TMath::Nint(particle->getCharge()) == 0 or !particle->hasStatus(MCParticle::c_StoppedInDetector))
1187 and mctrack.fDecayed) {
1188 TEvePathMarkD decayMark(TEvePathMarkD::kDecay);
1189 decayMark.fV.Set(B2Vector3D(particle->getDecayVertex()));
1190 m_mcparticleTracks[particle].track->AddPathMark(decayMark);
1191 }
1192 }
1193 TString particle_name(mctrack.GetName());
1194
1195 //set track title (for popup)
1196 const MCParticle* mom = particle->getMother();
1197 if (mom) {
1198 m_mcparticleTracks[particle].parentParticle = mom;
1199 addMCParticle(mom);
1200 }
1201
1202 TString title = ObjectInfo::getTitle(particle);
1203 if (!hasTrajectory) {
1204 //Hijack the mother label to show that the track position is only
1205 //extrapolated, not known from simulation
1206 title += "\n(track estimated from initial momentum)";
1207 //Also, show those tracks with dashed lines
1208 m_mcparticleTracks[particle].track->SetLineStyle(2);
1209 }
1210
1211 m_mcparticleTracks[particle].track->SetTitle(title);
1212
1213 //add some color (avoid black & white)
1214 switch (abs(pdg)) {
1215 case 11:
1216 m_mcparticleTracks[particle].track->SetLineColor(kAzure);
1217 break;
1218 case 13:
1219 m_mcparticleTracks[particle].track->SetLineColor(kCyan + 1);
1220 break;
1221 case 22:
1222 m_mcparticleTracks[particle].track->SetLineColor(kSpring);
1223 break;
1224 case 211:
1225 m_mcparticleTracks[particle].track->SetLineColor(kGray + 1);
1226 break;
1227 case 321:
1228 m_mcparticleTracks[particle].track->SetLineColor(kRed + 1);
1229 break;
1230 case 2212:
1231 m_mcparticleTracks[particle].track->SetLineColor(kOrange - 2);
1232 break;
1233 default:
1234 m_mcparticleTracks[particle].track->SetLineColor(kMagenta);
1235 }
1236
1237 //create point set for hits
1238 const TString pointsTitle = "SimHits for " + ObjectInfo::getIdentifier(particle) + " - " + particle_name;
1239 m_mcparticleTracks[particle].simhits = new TEvePointSet(pointsTitle);
1240 m_mcparticleTracks[particle].simhits->SetTitle(pointsTitle);
1241 m_mcparticleTracks[particle].simhits->SetMarkerStyle(6);
1242 m_mcparticleTracks[particle].simhits->SetMainColor(m_mcparticleTracks[particle].track->GetLineColor());
1243 //m_mcparticleTracks[particle].simhits->SetMainTransparency(50);
1244 addObject(particle, m_mcparticleTracks[particle].track);
1245 }
1246 return &m_mcparticleTracks[particle];
1247}
std::map< const MCParticle *, MCTrack > m_mcparticleTracks
map MCParticles to MCTrack (so hits can be added to the correct track).
static const int c_unassignedHitColor
Color for unassigned (reco)hits.
bool m_hideSecondaries
If true, secondary MCParticles (and hits created by them) will not be shown.
MCTrack * addMCParticle(const MCParticle *particle)
Return MCTrack for given particle, add it if it doesn't exist yet.
Class to save the full simulated trajectory of a particle.
A Class to store the Monte Carlo particle information.
Definition: MCParticle.h:32
@ c_PrimaryParticle
bit 0: Particle is primary particle.
Definition: MCParticle.h:47
@ c_StoppedInDetector
bit 3: Particle was stopped in the detector (the simulation volume).
Definition: MCParticle.h:53
Accessor to arrays stored in the data store.
Definition: StoreArray.h:113
Small struct to encode a position/momentum without additional overhead.

◆ addObject()

void addObject ( const TObject *  dataStoreObject,
TEveElement *  visualRepresentation 
)

Generic function to keep track of which objects have which visual representation.

Should be called by functions adding TEveElements to the event scene (Hits are currently excluded).

Definition at line 1906 of file EVEVisualization.cc.

1907{
1908 VisualRepMap::getInstance()->add(dataStoreObject, visualRepresentation);
1909}
void add(const TObject *dataStoreObject, TEveElement *visualRepresentation)
Generic function to keep track of which objects have which visual representation.

◆ addRecoHit() [1/3]

void addRecoHit ( const CDCHit hit,
TEveStraightLineSet *  lines 
)
private

specialisation for CDCHit.

Definition at line 1602 of file EVEVisualization.cc.

1603{
1605 const ROOT::Math::XYZVector& wire_pos_f = cdcgeo.wireForwardPosition(WireID(hit->getID()));
1606 const ROOT::Math::XYZVector& wire_pos_b = cdcgeo.wireBackwardPosition(WireID(hit->getID()));
1607
1608 lines->AddLine(wire_pos_f.X(), wire_pos_f.Y(), wire_pos_f.Z(), wire_pos_b.X(), wire_pos_b.Y(), wire_pos_b.Z());
1609 m_shownRecohits.insert(hit);
1610
1611}
std::set< const TObject * > m_shownRecohits
List of shown recohits (PXDCluster, SVDCluster, CDCHit).

◆ addRecoHit() [2/3]

void addRecoHit ( const SomeVXDHit *  hit,
TEveStraightLineSet *  lines 
)
inlineprivate

adds given VXD hit to lines.

Definition at line 289 of file EVEVisualization.h.

290 {
291 static VXD::GeoCache& geo = VXD::GeoCache::getInstance();
292
293 const ROOT::Math::XYZVector local_pos(hit->getU(), hit->getV(), 0.0); //z-component is height over the center of the detector plane
294 const VXD::SensorInfoBase& sensor = geo.getSensorInfo(hit->getSensorID());
295 const ROOT::Math::XYZVector global_pos = sensor.pointToGlobal(local_pos);
296 lines->AddMarker(global_pos.X(), global_pos.Y(), global_pos.Z());
297
298 m_shownRecohits.insert(hit);
299 }
static GeoCache & getInstance()
Return a reference to the singleton instance.
Definition: GeoCache.cc:214

◆ addRecoHit() [3/3]

void addRecoHit ( const SVDCluster hit,
TEveStraightLineSet *  lines 
)
private

specialisation for SVDCluster

Definition at line 1582 of file EVEVisualization.cc.

1583{
1585 const VXD::SensorInfoBase& sensor = geo.getSensorInfo(hit->getSensorID());
1586
1587 ROOT::Math::XYZVector a, b;
1588 if (hit->isUCluster()) {
1589 const float u = hit->getPosition();
1590 a = sensor.pointToGlobal(ROOT::Math::XYZVector(sensor.getBackwardWidth() / sensor.getWidth(0) * u, -0.5 * sensor.getLength(), 0.0));
1591 b = sensor.pointToGlobal(ROOT::Math::XYZVector(sensor.getForwardWidth() / sensor.getWidth(0) * u, +0.5 * sensor.getLength(), 0.0));
1592 } else {
1593 const float v = hit->getPosition();
1594 a = sensor.pointToGlobal(ROOT::Math::XYZVector(-0.5 * sensor.getWidth(v), v, 0.0));
1595 b = sensor.pointToGlobal(ROOT::Math::XYZVector(+0.5 * sensor.getWidth(v), v, 0.0));
1596 }
1597
1598 lines->AddLine(a.X(), a.Y(), a.Z(), b.X(), b.Y(), b.Z());
1599 m_shownRecohits.insert(hit);
1600}
Class to faciliate easy access to sensor information of the VXD like coordinate transformations or pi...
Definition: GeoCache.h:39
const SensorInfoBase & getSensorInfo(Belle2::VxdID id) const
Return a referecne to the SensorInfo of a given SensorID.
Definition: GeoCache.cc:67
Base class to provide Sensor Information for PXD and SVD.

◆ addROI()

void addROI ( const ROIid roi)

Add a Region Of Interest, computed by the PXDDataReduction module.

Definition at line 1551 of file EVEVisualization.cc.

1552{
1553 const VXD::GeoCache& aGeometry = VXD::GeoCache::getInstance();
1554
1555 VxdID sensorID = roi->getSensorID();
1556 const VXD::SensorInfoBase& aSensorInfo = aGeometry.getSensorInfo(sensorID);
1557
1558 double minU = aSensorInfo.getUCellPosition(roi->getMinUid(), roi->getMinVid());
1559 double minV = aSensorInfo.getVCellPosition(roi->getMinVid());
1560 double maxU = aSensorInfo.getUCellPosition(roi->getMaxUid(), roi->getMaxVid());
1561 double maxV = aSensorInfo.getVCellPosition(roi->getMaxVid());
1562
1563
1564 ROOT::Math::XYZVector localA(minU, minV, 0);
1565 ROOT::Math::XYZVector localB(minU, maxV, 0);
1566 ROOT::Math::XYZVector localC(maxU, minV, 0);
1567
1568 ROOT::Math::XYZVector globalA = aSensorInfo.pointToGlobal(localA);
1569 ROOT::Math::XYZVector globalB = aSensorInfo.pointToGlobal(localB);
1570 ROOT::Math::XYZVector globalC = aSensorInfo.pointToGlobal(localC);
1571
1572 TEveBox* ROIbox = boxCreator(globalB + globalC * 0.5, globalB - globalA, globalC - globalA, 1, 1, 0.01);
1573
1574 ROIbox->SetName(ObjectInfo::getIdentifier(roi));
1575 ROIbox->SetMainColor(kSpring - 9);
1576 ROIbox->SetMainTransparency(50);
1577
1578 addToGroup("ROIs", ROIbox);
1579 addObject(roi, ROIbox);
1580}
double getVCellPosition(int vID) const
Return the position of a specific strip/pixel in v direction.
double getUCellPosition(int uID, int vID=-1) const
Return the position of a specific strip/pixel in u direction.
ROOT::Math::XYZVector pointToGlobal(const ROOT::Math::XYZVector &local, bool reco=false) const
Convert a point from local to global coordinates.
Class to uniquely identify a any structure of the PXD and SVD.
Definition: VxdID.h:33

◆ addSimHit() [1/5]

void addSimHit ( const CDCSimHit hit,
const MCParticle particle 
)

Add a CDCSimHit.

Definition at line 1073 of file EVEVisualization.cc.

1074{
1075 addSimHit(ROOT::Math::XYZVector(hit->getPosWire()), particle);
1076}
void addSimHit(const CDCSimHit *hit, const MCParticle *particle)
Add a CDCSimHit.

◆ addSimHit() [2/5]

void addSimHit ( const KLMSimHit hit,
const MCParticle particle 
)

Add a KLMSimHit.

Definition at line 1089 of file EVEVisualization.cc.

1090{
1091 const ROOT::Math::XYZVector& global_pos = hit->getPosition();
1092 addSimHit(global_pos, particle);
1093}

◆ addSimHit() [3/5]

void addSimHit ( const PXDSimHit hit,
const MCParticle particle 
)

Add a PXDSimHit.

Definition at line 1077 of file EVEVisualization.cc.

1078{
1080 const ROOT::Math::XYZVector& global_pos = geo.getSensorInfo(hit->getSensorID()).pointToGlobal(hit->getPosIn());
1081 addSimHit(global_pos, particle);
1082}

◆ addSimHit() [4/5]

void addSimHit ( const ROOT::Math::XYZVector &  v,
const MCParticle particle 
)

Add simhit as a simple point.

Definition at line 1094 of file EVEVisualization.cc.

1095{
1096 MCTrack* track = addMCParticle(particle);
1097 if (!track)
1098 return; //hide hits from this particle
1099 track->simhits->SetNextPoint(v.X(), v.Y(), v.Z());
1100}

◆ addSimHit() [5/5]

void addSimHit ( const SVDSimHit hit,
const MCParticle particle 
)

Add a SVDSimHit.

Definition at line 1083 of file EVEVisualization.cc.

1084{
1086 const ROOT::Math::XYZVector& global_pos = geo.getSensorInfo(hit->getSensorID()).pointToGlobal(hit->getPosIn());
1087 addSimHit(global_pos, particle);
1088}

◆ addSimHits()

void addSimHits ( const StoreArray< T > &  hits)
inline

Add all entries in the given 'hits' array (and the corresponding MCParticles) to the event scene.

Definition at line 135 of file EVEVisualization.h.

136 {
137 const int numHits = hits.getEntries();
138 for (int i = 0; i < numHits; i++) {
139 const RelationsObject* rel = hits[i];
140 const MCParticle* mcpart = rel->getRelatedFrom<MCParticle>();
141
142 addSimHit(hits[i], mcpart);
143 }
144 }
FROM * getRelatedFrom(const std::string &name="", const std::string &namedRelation="") const
Get the object from which this object has a relation.
RelationsInterface< TObject > RelationsObject
Provides interface for getting/adding relations to objects in StoreArrays.

◆ addToGroup()

void addToGroup ( const std::string &  name,
TEveElement *  elem 
)
private

Add 'elem' to the element group 'name' (created if necessary).

name can also be a path, e.g. MyOwnStuff/SpecialObject A, which will automatically create sub-groups.

slashes at beginning and end of name are ignored.

Definition at line 1911 of file EVEVisualization.cc.

1912{
1913 //slashes at beginning and end are ignored
1914 const std::string& groupName = boost::algorithm::trim_copy_if(name, boost::algorithm::is_any_of("/"));
1915
1916 TEveElementList* group = m_groups[groupName].group;
1917 if (!group) {
1918 group = new TEveElementList(groupName.c_str(), groupName.c_str());
1919 group->SetRnrState(m_groups[groupName].visible);
1920 m_groups[groupName].group = group;
1921
1922 //if groupName contains '/', remove last bit and add to parent group
1923 //e.g. if groupName=A/B/C, call addToGroup("A/B", groupC)
1924 auto lastSlash = boost::algorithm::find_last(groupName, "/");
1925 if (lastSlash) {
1926 const std::string parentGroup(groupName.begin(), lastSlash.begin());
1927 const std::string thisGroup(lastSlash.end(), groupName.end());
1928 group->SetElementName(thisGroup.c_str());
1929 addToGroup(parentGroup, group);
1930 } else {
1931 gEve->AddElement(group);
1932 }
1933 }
1934 group->AddElement(elem);
1935}
std::map< std::string, ElementGroup > m_groups
name -> grouping element.

◆ addTOPDigits()

void addTOPDigits ( const StoreArray< TOPDigit > &  digits)

Add TOPDigits (shown aggregated per module).

Definition at line 1798 of file EVEVisualization.cc.

1799{
1800 /* TOP module ID -> #digits */
1801 std::map<int, int> m_topSummary;
1802 for (const TOPDigit& hit : digits) {
1803 int mod = hit.getModuleID();
1804 ++m_topSummary[mod];
1805 }
1806 int maxcount = 0;
1807 for (auto modCountPair : m_topSummary) {
1808 if (modCountPair.second > maxcount)
1809 maxcount = modCountPair.second;
1810 }
1811 for (auto modCountPair : m_topSummary) {
1812 const auto& topmod = TOP::TOPGeometryPar::Instance()->getGeometry()->getModule(modCountPair.first);
1813 double phi = topmod.getPhi();
1814 double r_center = topmod.getRadius();
1815 double z = topmod.getZc();
1816
1817 ROOT::Math::XYZVector centerPos3D;
1818 VectorUtil::setMagThetaPhi(centerPos3D, r_center, M_PI / 2, phi);
1819 centerPos3D.SetZ(z);
1820
1821 B2Vector3D channelX(1, 0, 0); channelX.RotateZ(phi);
1822 B2Vector3D channelY(0, 1, 0); channelY.RotateZ(phi);
1823
1824 //bar is a bit thicker so we can mouse over without getting the geometry
1825 auto* moduleBox = boxCreator(centerPos3D, channelX, channelY,
1826 3.0 * topmod.getBarThickness(), topmod.getBarWidth(), topmod.getBarLength());
1827 moduleBox->SetMainColor(kAzure + 10);
1828 double weight = double(modCountPair.second) / maxcount;
1829 moduleBox->SetMainTransparency(90 - weight * 50);
1830 moduleBox->SetName(("TOP module " + std::to_string(modCountPair.first)).c_str());
1831 moduleBox->SetTitle(TString::Format("#TOPDigits: %d ", modCountPair.second));
1832
1833 addToGroup("TOP Modules", moduleBox);
1834 //associate all TOPDigits with this module.
1835 for (const TOPDigit& hit : digits) {
1836 if (modCountPair.first == hit.getModuleID())
1837 addObject(&hit, moduleBox);
1838 }
1839 }
1840}
Class to store TOP digitized hits (output of TOPDigitizer or raw data unpacker) relations to TOPSimHi...
Definition: TOPDigit.h:24
const TOPGeometry * getGeometry() const
Returns pointer to geometry object using basf2 units.
static TOPGeometryPar * Instance()
Static method to obtain the pointer to its instance.
const TOPGeoModule & getModule(int moduleID) const
Returns module.
Definition: TOPGeometry.cc:42

◆ addTrack()

void addTrack ( const Belle2::Track belle2Track)

Add this genfit::Track to event data.

Adapted from GenfitDisplay, originally written by Karl Bicker.

Definition at line 384 of file EVEVisualization.cc.

385{
386 // load the pion fit hypothesis or the hypothesis which is the closest in mass to a pion
387 // the tracking will not always successfully fit with a pion hypothesis
388 const TrackFitResult* fitResult = belle2Track->getTrackFitResultWithClosestMass(Const::pion);
389 if (!fitResult) {
390 B2ERROR("Track without TrackFitResult skipped.");
391 return;
392 }
393 const RecoTrack* track = belle2Track->getRelated<RecoTrack>();
394
395 const TString label = ObjectInfo::getIdentifier(belle2Track) + " (" + ObjectInfo::getIdentifier(fitResult) + ")";
396
397 // parse the option string ------------------------------------------------------------------------
398 bool drawDetectors = false;
399 bool drawHits = false;
400 bool drawPlanes = false;
401
402 if (m_options != "") {
403 for (size_t i = 0; i < m_options.length(); i++) {
404 if (m_options.at(i) == 'D') drawDetectors = true;
405 if (m_options.at(i) == 'H') drawHits = true;
406 if (m_options.at(i) == 'P') drawPlanes = true;
407 }
408 }
409 // finished parsing the option string -------------------------------------------------------------
410
411 // We loop over all points (scattering non-measurement points for GBL)
412 // and for Kalman we skip those with no measurements, which should
413 // not be there
414 bool isPruned = (track == nullptr);
415
416
417 TEveRecTrackD recTrack;
418 const B2Vector3D& poca = fitResult->getPosition();
419 recTrack.fV.Set(poca);
420
421 const B2Vector3D& poca_momentum = fitResult->getMomentum();
422 if (std::isfinite(poca_momentum.Mag()))
423 recTrack.fP.Set(poca_momentum);
424 else //use 1TeV momentum for tracks without curvature
425 recTrack.fP.Set(B2Vector3D(fitResult->getHelix().getDirection() * 1000));
426
427 recTrack.fSign = fitResult->getChargeSign();
428 TEveTrack* eveTrack = new TEveTrack(&recTrack, m_gftrackpropagator);
429 eveTrack->SetName(label);
430
431
432 if (track) {
433 const genfit::AbsTrackRep* representation;
434
435 if (m_drawCardinalRep) {
436 representation = track->getCardinalRepresentation();
437 B2DEBUG(100, "Draw cardinal rep");
438 } else {
439 const auto& representations = track->getRepresentations();
440 if (representations.empty()) {
441 B2ERROR("No representations found in the reco track!");
442 return;
443 }
444 B2DEBUG(100, "Draw representation number 0.");
445 representation = representations.front();
446 }
447
448 if (!track->hasTrackFitStatus(representation)) {
449 B2ERROR("RecoTrack without FitStatus: will be skipped!");
450 return;
451 }
452
453 const genfit::FitStatus* fitStatus = track->getTrackFitStatus(representation);
454
455 isPruned = fitStatus->isTrackPruned();
456
457 // GBL and Kalman cannot mix in a track.
458 // What is 0 after first loop will stay 0:
459 genfit::KalmanFitterInfo* fi = 0;
460 genfit::KalmanFitterInfo* prevFi = 0;
461 genfit::GblFitterInfo* gfi = 0;
462 genfit::GblFitterInfo* prevGFi = 0;
463 const genfit::MeasuredStateOnPlane* fittedState(NULL);
464 const genfit::MeasuredStateOnPlane* prevFittedState(NULL);
465
466
467 const auto& hitPoints = track->getHitPointsWithMeasurement();
468 const unsigned int numpoints = hitPoints.size();
469
470 int hitCounter = -1;
471 for (genfit::TrackPoint* tp : hitPoints) { // loop over all points in the track
472 hitCounter++;
473
474 // get the fitter infos ------------------------------------------------------------------
475 if (! tp->hasFitterInfo(representation)) {
476 B2ERROR("trackPoint has no fitterInfo for rep");
477 continue;
478 }
479
480 genfit::AbsFitterInfo* fitterInfo = tp->getFitterInfo(representation);
481
482 fi = dynamic_cast<genfit::KalmanFitterInfo*>(fitterInfo);
483 gfi = dynamic_cast<genfit::GblFitterInfo*>(fitterInfo);
484
485 if (!gfi && !fi) {
486 B2ERROR("Can only display KalmanFitterInfo or GblFitterInfo");
487 continue;
488 }
489
490 if (gfi && fi)
491 B2FATAL("AbsFitterInfo dynamic-casted to both KalmanFitterInfo and GblFitterInfo!");
492
493
494 if (fi && ! tp->hasRawMeasurements()) {
495 B2ERROR("trackPoint has no raw measurements");
496 continue;
497 }
498
499 if (fi && ! fi->hasPredictionsAndUpdates()) {
500 B2ERROR("KalmanFitterInfo does not have all predictions and updates");
501 continue;
502 }
503
504 try {
505 if (gfi)
506 fittedState = &(gfi->getFittedState(true));
507 if (fi)
508 fittedState = &(fi->getFittedState(true));
509 } catch (genfit::Exception& e) {
510 B2ERROR(e.what() << " - can not get fitted state");
511 continue;
512 }
513
514 ROOT::Math::XYZVector track_pos = ROOT::Math::XYZVector(representation->getPos(*fittedState));
515
516 // draw track if corresponding option is set ------------------------------------------
517 if (prevFittedState != NULL) {
518
519 TEvePathMark::EType_e markType = TEvePathMark::kReference;
520 if (hitCounter + 1 == static_cast<int>(numpoints)) //track should stop here.
521 markType = TEvePathMark::kDecay;
522
523 // Kalman: non-null prevFi ensures that the previous fitter info was also KalmanFitterInfo
524 if (fi && prevFi) {
525 makeLines(eveTrack, prevFittedState, fittedState, representation, markType, m_drawErrors);
526 if (m_drawErrors) { // make sure to draw errors in both directions
527 makeLines(eveTrack, prevFittedState, fittedState, representation, markType, m_drawErrors, 0);
528 }
529 //these are currently disabled.
530 //TODO: if activated, I want to have a separate TEveStraightLineSet instead of eveTrack (different colors/options)
531 if (m_drawForward)
532 makeLines(eveTrack, prevFi->getForwardUpdate(), fi->getForwardPrediction(), representation, markType, m_drawErrors, 0);
533 if (m_drawBackward)
534 makeLines(eveTrack, prevFi->getBackwardPrediction(), fi->getBackwardUpdate(), representation, markType, m_drawErrors);
535 // draw reference track if corresponding option is set ------------------------------------------
536 if (m_drawRefTrack && fi->hasReferenceState() && prevFi->hasReferenceState())
537 makeLines(eveTrack, prevFi->getReferenceState(), fi->getReferenceState(), representation, markType, false);
538 }
539
540 // GBL: non-null prevGFi ensures that the previous fitter info was also GblFitterInfo
541 if (gfi && prevGFi) {
542 makeLines(eveTrack, prevFittedState, fittedState, representation, markType, m_drawErrors);
543 if (m_drawErrors) {
544 makeLines(eveTrack, prevFittedState, fittedState, representation, markType, m_drawErrors, 0);
545 }
546
547 if (m_drawRefTrack && gfi->hasReferenceState() && prevGFi->hasReferenceState()) {
548 genfit::StateOnPlane prevSop = prevGFi->getReferenceState();
549 genfit::StateOnPlane sop = gfi->getReferenceState();
550 makeLines(eveTrack, &prevSop, &sop, representation, markType, false);
551 }
552 }
553
554 }
555 prevFi = fi; // Kalman
556 prevGFi = gfi; // GBL
557 prevFittedState = fittedState;
558
559
560 //loop over all measurements for this point (e.g. u and v-type strips)
561 const int numMeasurements = tp->getNumRawMeasurements();
562 for (int iMeasurement = 0; iMeasurement < numMeasurements; iMeasurement++) {
563 const genfit::AbsMeasurement* m = tp->getRawMeasurement(iMeasurement);
564
565 TVectorT<double> hit_coords;
566 TMatrixTSym<double> hit_cov;
567
568 if (fi) {
569 // Kalman
570 genfit::MeasurementOnPlane* mop = fi->getMeasurementOnPlane(iMeasurement);
571 hit_coords.ResizeTo(mop->getState());
572 hit_cov.ResizeTo(mop->getCov());
573 hit_coords = mop->getState();
574 hit_cov = mop->getCov();
575 }
576 if (gfi) {
577 // GBL - has only one measurement (other should be already merged before the track is constructed)
578 // That means tp->getNumRawMeasurements() returns 1 for tracks fitted by GBL, because GBLfit Module
579 // merges all corresponding SVD strips to 2D combined clusters.
580 genfit::MeasurementOnPlane gblMeas = gfi->getMeasurement();
581 hit_coords.ResizeTo(gblMeas.getState());
582 hit_cov.ResizeTo(gblMeas.getCov());
583 hit_coords = gblMeas.getState();
584 hit_cov = gblMeas.getCov();
585 }
586
587 // finished getting the hit infos -----------------------------------------------------
588
589 // sort hit infos into variables ------------------------------------------------------
590 ROOT::Math::XYZVector o = ROOT::Math::XYZVector(fittedState->getPlane()->getO());
591 ROOT::Math::XYZVector u = ROOT::Math::XYZVector(fittedState->getPlane()->getU());
592 ROOT::Math::XYZVector v = ROOT::Math::XYZVector(fittedState->getPlane()->getV());
593
594 bool planar_hit = false;
595 bool planar_pixel_hit = false;
596 bool space_hit = false;
597 bool wire_hit = false;
598 bool wirepoint_hit = false;
599 double_t hit_u = 0;
600 double_t hit_v = 0;
601 double_t plane_size = 4;
602
603 int hit_coords_dim = m->getDim();
604
605 if (dynamic_cast<const genfit::PlanarMeasurement*>(m) != NULL) {
606 planar_hit = true;
607 if (hit_coords_dim == 1) {
608 hit_u = hit_coords(0);
609 } else if (hit_coords_dim == 2) {
610 planar_pixel_hit = true;
611 hit_u = hit_coords(0);
612 hit_v = hit_coords(1);
613 }
614 } else if (dynamic_cast<const genfit::SpacepointMeasurement*>(m) != NULL) {
615 space_hit = true;
616 } else if (dynamic_cast<const CDCRecoHit*>(m)
617 || dynamic_cast<const genfit::WireMeasurement*>(m)
618 || dynamic_cast<const genfit::WireMeasurementNew*>(m)) {
619 wire_hit = true;
620 hit_u = fabs(hit_coords(0));
621 hit_v = v.Dot(track_pos - o); // move the covariance tube so that the track goes through it
622 if (dynamic_cast<const genfit::WirePointMeasurement*>(m) != NULL) {
623 wirepoint_hit = true;
624 hit_v = hit_coords(1);
625 }
626 } else {
627 B2ERROR("Hit " << hitCounter << ", Measurement " << iMeasurement << ": Unknown measurement type: skipping hit!");
628 break;
629 }
630
631 // finished setting variables ---------------------------------------------------------
632
633 // draw planes if corresponding option is set -----------------------------------------
634 if (drawPlanes || (drawDetectors && planar_hit)) {
635 ROOT::Math::XYZVector move(0, 0, 0);
636 if (wire_hit) move = v * (v.Dot(track_pos - o)); // move the plane along the wire until the track goes through it
637 TEveBox* box = boxCreator(o + move, u, v, plane_size, plane_size, 0.01);
638 if (drawDetectors && planar_hit) {
639 box->SetMainColor(kCyan);
640 } else {
641 box->SetMainColor(kGray);
642 }
643 box->SetMainTransparency(50);
644 eveTrack->AddElement(box);
645 }
646 // finished drawing planes ------------------------------------------------------------
647
648 // draw detectors if option is set, only important for wire hits ----------------------
649 if (drawDetectors) {
650
651 if (wire_hit) {
652 TEveGeoShape* det_shape = new TEveGeoShape("det_shape");
653 det_shape->SetShape(new TGeoTube(std::max(0., (double)(hit_u - 0.0105 / 2.)), hit_u + 0.0105 / 2., plane_size));
654 fixGeoShapeRefCount(det_shape);
655
656 ROOT::Math::XYZVector norm = u.Cross(v);
657 TGeoRotation det_rot("det_rot", (u.Theta() * 180) / TMath::Pi(), (u.Phi() * 180) / TMath::Pi(),
658 (norm.Theta() * 180) / TMath::Pi(), (norm.Phi() * 180) / TMath::Pi(),
659 (v.Theta() * 180) / TMath::Pi(), (v.Phi() * 180) / TMath::Pi()); // move the tube to the right place and rotate it correctly
660 ROOT::Math::XYZVector move = v * (v.Dot(track_pos - o)); // move the tube along the wire until the track goes through it
661 TGeoCombiTrans det_trans(o.X() + move.X(),
662 o.Y() + move.Y(),
663 o.Z() + move.Z(),
664 &det_rot);
665 det_shape->SetTransMatrix(det_trans);
666 det_shape->SetMainColor(kCyan);
667 det_shape->SetMainTransparency(25);
668 if ((drawHits && (hit_u + 0.0105 / 2 > 0)) || !drawHits) {
669 eveTrack->AddElement(det_shape);
670 }
671 }
672
673 }
674 // finished drawing detectors ---------------------------------------------------------
675
676 if (drawHits) {
677
678 // draw planar hits, with distinction between strip and pixel hits ----------------
679 if (planar_hit) {
680 if (!planar_pixel_hit) {
681 //strip hit
683 const SVDRecoHit* recoHit = dynamic_cast<const SVDRecoHit*>(m);
684 if (!recoHit) {
685 B2WARNING("SVD recohit couldn't be converted... ");
686 continue;
687 }
688
689 const VXD::SensorInfoBase& sensor = geo.getSensorInfo(recoHit->getSensorID());
690 double du, dv;
691 ROOT::Math::XYZVector a = o; //defines position of sensor plane
692 double hit_res_u = hit_cov(0, 0);
693 if (recoHit->isU()) {
694 du = std::sqrt(hit_res_u);
695 dv = sensor.getLength();
696 a += hit_u * u;
697 } else {
698 du = sensor.getWidth();
699 dv = std::sqrt(hit_res_u);
700 a += hit_u * v;
701 }
702 double depth = sensor.getThickness();
703 TEveBox* hit_box = boxCreator(a, u, v, du, dv, depth);
704 hit_box->SetName("SVDRecoHit");
705 hit_box->SetMainColor(c_recoHitColor);
706 hit_box->SetMainTransparency(0);
707 eveTrack->AddElement(hit_box);
708 } else {
709 //pixel hit
710 // calculate eigenvalues to draw error-ellipse ----------------------------
711 TMatrixDSymEigen eigen_values(hit_cov);
712 TEveGeoShape* cov_shape = new TEveGeoShape("PXDRecoHit");
713 const TVectorD& ev = eigen_values.GetEigenValues();
714 const TMatrixD& eVec = eigen_values.GetEigenVectors();
715 double pseudo_res_0 = m_errorScale * std::sqrt(ev(0));
716 double pseudo_res_1 = m_errorScale * std::sqrt(ev(1));
717 // finished calcluating, got the values -----------------------------------
718
719 // calculate the semiaxis of the error ellipse ----------------------------
720 cov_shape->SetShape(new TGeoEltu(pseudo_res_0, pseudo_res_1, 0.0105));
721 fixGeoShapeRefCount(cov_shape);
722 ROOT::Math::XYZVector pix_pos = o + hit_u * u + hit_v * v;
723 ROOT::Math::XYZVector u_semiaxis = (pix_pos + eVec(0, 0) * u + eVec(1, 0) * v) - pix_pos;
724 ROOT::Math::XYZVector v_semiaxis = (pix_pos + eVec(0, 1) * u + eVec(1, 1) * v) - pix_pos;
725 ROOT::Math::XYZVector norm = u.Cross(v);
726 // finished calculating ---------------------------------------------------
727
728 // rotate and translate everything correctly ------------------------------
729 TGeoRotation det_rot("det_rot", (u_semiaxis.Theta() * 180) / TMath::Pi(), (u_semiaxis.Phi() * 180) / TMath::Pi(),
730 (v_semiaxis.Theta() * 180) / TMath::Pi(), (v_semiaxis.Phi() * 180) / TMath::Pi(),
731 (norm.Theta() * 180) / TMath::Pi(), (norm.Phi() * 180) / TMath::Pi());
732 TGeoCombiTrans det_trans(pix_pos.X(), pix_pos.Y(), pix_pos.Z(), &det_rot);
733 cov_shape->SetTransMatrix(det_trans);
734 // finished rotating and translating --------------------------------------
735
736 cov_shape->SetMainColor(c_recoHitColor);
737 cov_shape->SetMainTransparency(0);
738 eveTrack->AddElement(cov_shape);
739 }
740 }
741 // finished drawing planar hits ---------------------------------------------------
742
743 // draw spacepoint hits -----------------------------------------------------------
744 if (space_hit) {
745
746 // get eigenvalues of covariance to know how to draw the ellipsoid ------------
747 TMatrixDSymEigen eigen_values(m->getRawHitCov());
748 TEveGeoShape* cov_shape = new TEveGeoShape("SpacePoint Hit");
749 cov_shape->SetShape(new TGeoSphere(0., 1.));
750 fixGeoShapeRefCount(cov_shape);
751 const TVectorD& ev = eigen_values.GetEigenValues();
752 const TMatrixD& eVec = eigen_values.GetEigenVectors();
753 ROOT::Math::XYZVector eVec1(eVec(0, 0), eVec(1, 0), eVec(2, 0));
754 ROOT::Math::XYZVector eVec2(eVec(0, 1), eVec(1, 1), eVec(2, 1));
755 ROOT::Math::XYZVector eVec3(eVec(0, 2), eVec(1, 2), eVec(2, 2));
756 // got everything we need -----------------------------------------------------
757
758
759 TGeoRotation det_rot("det_rot", (eVec1.Theta() * 180) / TMath::Pi(), (eVec1.Phi() * 180) / TMath::Pi(),
760 (eVec2.Theta() * 180) / TMath::Pi(), (eVec2.Phi() * 180) / TMath::Pi(),
761 (eVec3.Theta() * 180) / TMath::Pi(), (eVec3.Phi() * 180) / TMath::Pi()); // the rotation is already clear
762
763 // set the scaled eigenvalues -------------------------------------------------
764 double pseudo_res_0 = m_errorScale * std::sqrt(ev(0));
765 double pseudo_res_1 = m_errorScale * std::sqrt(ev(1));
766 double pseudo_res_2 = m_errorScale * std::sqrt(ev(2));
767 // finished scaling -----------------------------------------------------------
768
769 // rotate and translate -------------------------------------------------------
770 TGeoGenTrans det_trans(o.X(), o.Y(), o.Z(),
771 //std::sqrt(pseudo_res_0/pseudo_res_1/pseudo_res_2), std::sqrt(pseudo_res_1/pseudo_res_0/pseudo_res_2), std::sqrt(pseudo_res_2/pseudo_res_0/pseudo_res_1), // this workaround is necessary due to the "normalization" performed in TGeoGenTrans::SetScale
772 //1/(pseudo_res_0),1/(pseudo_res_1),1/(pseudo_res_2),
773 pseudo_res_0, pseudo_res_1, pseudo_res_2,
774 &det_rot);
775 cov_shape->SetTransMatrix(det_trans);
776 // finished rotating and translating ------------------------------------------
777
778 cov_shape->SetMainColor(c_recoHitColor);
779 cov_shape->SetMainTransparency(10);
780 eveTrack->AddElement(cov_shape);
781 }
782 // finished drawing spacepoint hits -----------------------------------------------
783
784 // draw wire hits -----------------------------------------------------------------
785 if (wire_hit) {
786 const double cdcErrorScale = 1.0;
787 TEveGeoShape* cov_shape = new TEveGeoShape("CDCRecoHit");
788 double pseudo_res_0 = cdcErrorScale * std::sqrt(hit_cov(0, 0));
789 double pseudo_res_1 = plane_size;
790 if (wirepoint_hit) pseudo_res_1 = cdcErrorScale * std::sqrt(hit_cov(1, 1));
791
792 cov_shape->SetShape(new TGeoTube(std::max(0., (double)(hit_u - pseudo_res_0)), hit_u + pseudo_res_0, pseudo_res_1));
793 fixGeoShapeRefCount(cov_shape);
794 ROOT::Math::XYZVector norm = u.Cross(v);
795
796 // rotate and translate -------------------------------------------------------
797 TGeoRotation det_rot("det_rot", (u.Theta() * 180) / TMath::Pi(), (u.Phi() * 180) / TMath::Pi(),
798 (norm.Theta() * 180) / TMath::Pi(), (norm.Phi() * 180) / TMath::Pi(),
799 (v.Theta() * 180) / TMath::Pi(), (v.Phi() * 180) / TMath::Pi());
800 TGeoCombiTrans det_trans(o.X() + hit_v * v.X(),
801 o.Y() + hit_v * v.Y(),
802 o.Z() + hit_v * v.Z(),
803 &det_rot);
804 cov_shape->SetTransMatrix(det_trans);
805 // finished rotating and translating ------------------------------------------
806
807 cov_shape->SetMainColor(c_recoHitColor);
808 cov_shape->SetMainTransparency(50);
809 eveTrack->AddElement(cov_shape);
810 }
811 // finished drawing wire hits -----------------------------------------------------
812 }
813
814 }
815 }
816
817 auto& firstref = eveTrack->RefPathMarks().front();
818 auto& lastref = eveTrack->RefPathMarks().back();
819 double f = firstref.fV.Distance(recTrack.fV);
820 double b = lastref.fV.Distance(recTrack.fV);
821 if (f > 100 and f > b) {
822 B2WARNING("Decay vertex is much closer to POCA than first vertex, reversing order of track points... (this is intended for cosmic tracks, if you see this message in other context it might indicate a problem)");
823 //last ref is better than first...
824 lastref.fType = TEvePathMarkD::kReference;
825 firstref.fType = TEvePathMarkD::kDecay;
826 std::reverse(eveTrack->RefPathMarks().begin(), eveTrack->RefPathMarks().end());
827 }
828 }
829 eveTrack->SetTitle(TString::Format("%s\n"
830 "pruned: %s\n"
831 "pT=%.3f, pZ=%.3f\n"
832 "pVal: %e",
833 label.Data(),
834 isPruned ? " yes" : "no",
835 poca_momentum.Pt(), poca_momentum.Pz(),
836 fitResult->getPValue()
837 ));
838 eveTrack->SetLineColor(c_trackColor);
839 eveTrack->SetLineStyle(1);
840 eveTrack->SetLineWidth(3.0);
841
842
843 addToGroup("Fitted Tracks", eveTrack);
844 if (track)
845 addObject(track, eveTrack);
846 addObject(belle2Track, eveTrack);
847}
DataType Pz() const
access variable Z (= .at(2) without boundary check)
Definition: B2Vector3.h:441
DataType Mag() const
The magnitude (rho in spherical coordinate system).
Definition: B2Vector3.h:159
DataType Pt() const
The transverse component (R in cylindrical coordinate system).
Definition: B2Vector3.h:198
This class is used to transfer CDC information to the track fit.
Definition: CDCRecoHit.h:32
static const ChargedStable pion
charged pion particle
Definition: Const.h:661
static const int c_recoHitColor
Color for reco hits.
bool m_drawRefTrack
Draw reference track in addTrack.
bool m_drawForward
draw forward in addTrack
bool m_drawCardinalRep
Draw cardinal representation in addTrack.
std::string m_options
Option string for genfit::Track visualisation.
static const int c_trackColor
Color for tracks.
bool m_drawBackward
draw backward in addTrack
bool m_drawErrors
Draw errors in addTrack.
double m_errorScale
Rescale PXD/SVD errors with this factor to ensure visibility.
void makeLines(TEveTrack *eveTrack, const genfit::StateOnPlane *prevState, const genfit::StateOnPlane *state, const genfit::AbsTrackRep *rep, TEvePathMark::EType_e markType, bool drawErrors, int markerPos=1)
Create hit visualisation for the given options, and add them to 'eveTrack'.
This is the Reconstruction Event-Data Model Track.
Definition: RecoTrack.h:79
T * getRelated(const std::string &name="", const std::string &namedRelation="") const
Get the object to or from which this object has a relation.
SVDRecoHit - an extended form of SVDHit containing geometry information.
Definition: SVDRecoHit.h:47
bool isU() const
Is the coordinate u or v?
Definition: SVDRecoHit.h:91
VxdID getSensorID() const
Get the compact ID.
Definition: SVDRecoHit.h:82
Values of the result of a track fit with a given particle hypothesis.
Helix getHelix() const
Conversion to framework Helix (without covariance).
short getChargeSign() const
Return track charge (1 or -1).
double getPValue() const
Getter for Chi2 Probability of the track fit.
ROOT::Math::XYZVector getMomentum() const
Getter for vector of momentum at closest approach of track in r/phi projection.
ROOT::Math::XYZVector getPosition() const
Getter for vector of position at closest approach of track in r/phi projection.
const TrackFitResult * getTrackFitResultWithClosestMass(const Const::ChargedStable &requestedType) const
Return the track fit for the fit hypothesis with the closest mass.
Definition: Track.cc:104
ROOT::Math::XYZVector poca(ROOT::Math::XYZVector const &trackPos, ROOT::Math::XYZVector const &trackP, ROOT::Math::XYZVector const &vtxPos)
Returns the Point Of Closest Approach of a track to a vertex.

◆ addTrackCandidate()

void addTrackCandidate ( const std::string &  collectionName,
const RecoTrack recoTrack 
)

Add a RecoTrack, to evaluate track finding.

Definition at line 202 of file EVEVisualization.cc.

204{
205 const TString label = ObjectInfo::getIdentifier(&recoTrack);
206 // parse the option string ------------------------------------------------------------------------
207 bool drawHits = false;
208
209 if (m_options != "") {
210 for (size_t i = 0; i < m_options.length(); i++) {
211 if (m_options.at(i) == 'H') drawHits = true;
212 }
213 }
214 // finished parsing the option string -------------------------------------------------------------
215
216
217 //track seeds
218 const B2Vector3D& track_pos = recoTrack.getPositionSeed();
219 const B2Vector3D& track_mom = recoTrack.getMomentumSeed();
220
221 TEveStraightLineSet* lines = new TEveStraightLineSet("RecoHits for " + label);
222 lines->SetMainColor(c_recoTrackColor);
223 lines->SetMarkerColor(c_recoTrackColor);
224 lines->SetMarkerStyle(6);
225 lines->SetMainTransparency(60);
226
227 if (drawHits) {
228 // Loop over all hits in the track (three different types)
229 for (const RecoHitInformation::UsedPXDHit* pxdHit : recoTrack.getPXDHitList()) {
230 addRecoHit(pxdHit, lines);
231 }
232
233 for (const RecoHitInformation::UsedSVDHit* svdHit : recoTrack.getSVDHitList()) {
234 addRecoHit(svdHit, lines);
235 }
236
237 for (const RecoHitInformation::UsedCDCHit* cdcHit : recoTrack.getCDCHitList()) {
238 addRecoHit(cdcHit, lines);
239 }
240 }
241
242 TEveRecTrack rectrack;
243 rectrack.fP.Set(track_mom);
244 rectrack.fV.Set(track_pos);
245
246 TEveTrack* track_lines = new TEveTrack(&rectrack, m_gftrackpropagator);
247 track_lines->SetName(label); //popup label set at end of function
248 track_lines->SetPropagator(m_gftrackpropagator);
249 track_lines->SetLineColor(c_recoTrackColor);
250 track_lines->SetLineWidth(1);
251 track_lines->SetTitle(ObjectInfo::getTitle(&recoTrack));
252
253 track_lines->SetCharge((int)recoTrack.getChargeSeed());
254
255
256 track_lines->AddElement(lines);
257 addToGroup(collectionName, track_lines);
258 addObject(&recoTrack, track_lines);
259}
Class containing the result of the unpacker in raw data and the result of the digitizer in simulation...
Definition: CDCHit.h:40
void addRecoHit(const SomeVXDHit *hit, TEveStraightLineSet *lines)
adds given VXD hit to lines.
static const int c_recoTrackColor
Color for TrackCandidates.
The PXD Cluster class This class stores all information about reconstructed PXD clusters The position...
Definition: PXDCluster.h:30
std::vector< Belle2::RecoTrack::UsedPXDHit * > getPXDHitList() const
Return an unsorted list of pxd hits.
Definition: RecoTrack.h:449
std::vector< Belle2::RecoTrack::UsedSVDHit * > getSVDHitList() const
Return an unsorted list of svd hits.
Definition: RecoTrack.h:452
std::vector< Belle2::RecoTrack::UsedCDCHit * > getCDCHitList() const
Return an unsorted list of cdc hits.
Definition: RecoTrack.h:455
ROOT::Math::XYZVector getPositionSeed() const
Return the position seed stored in the reco track. ATTENTION: This is not the fitted position.
Definition: RecoTrack.h:480
short int getChargeSeed() const
Return the charge seed stored in the reco track. ATTENTION: This is not the fitted charge.
Definition: RecoTrack.h:508
ROOT::Math::XYZVector getMomentumSeed() const
Return the momentum seed stored in the reco track. ATTENTION: This is not the fitted momentum.
Definition: RecoTrack.h:487
The SVD Cluster class This class stores all information about reconstructed SVD clusters.
Definition: SVDCluster.h:29

◆ addTrackCandidateImproved()

void addTrackCandidateImproved ( const std::string &  collectionName,
const RecoTrack recoTrack 
)

Add a RecoTrack, but use stored genfit track representation to make visualisation objects.

FIXME this is mostly just a workaround for monopoles.

Definition at line 261 of file EVEVisualization.cc.

263{
264 const TString label = ObjectInfo::getIdentifier(&recoTrack);
265 // parse the option string ------------------------------------------------------------------------
266 bool drawHits = false;
267
268 if (m_options != "") {
269 for (size_t i = 0; i < m_options.length(); i++) {
270 if (m_options.at(i) == 'H') drawHits = true;
271 }
272 }
273 // finished parsing the option string -------------------------------------------------------------
274
275 // Create a track as a polyline through reconstructed points
276 // FIXME this is snatched from PrimitivePlotter, need to add extrapolation out of CDC
277 TEveLine* track = new TEveLine(); // We are going to just add points with SetNextPoint
278 std::vector<ROOT::Math::XYZVector> posPoints; // But first we'll have to sort them as in RecoHits axial and stereo come in blocks
279 track->SetName(label); //popup label set at end of function
280 track->SetLineColor(c_recoTrackColor);
281 track->SetLineWidth(3);
282 track->SetTitle(ObjectInfo::getTitle(&recoTrack));
283 track->SetSmooth(true);
284
285 for (auto recoHit : recoTrack.getRecoHitInformations()) {
286 // skip for reco hits which have not been used in the fit (and therefore have no fitted information on the plane
287 if (!recoHit->useInFit())
288 continue;
289
290 // Need TVector3 here for genfit interface below
291 TVector3 pos;
292 TVector3 mom;
293 TMatrixDSym cov;
294
295 try {
296 const auto* trackPoint = recoTrack.getCreatedTrackPoint(recoHit);
297 const auto* fittedResult = trackPoint->getFitterInfo();
298 if (not fittedResult) {
299 B2WARNING("Skipping unfitted track point");
300 continue;
301 }
302 const genfit::MeasuredStateOnPlane& state = fittedResult->getFittedState();
303 state.getPosMomCov(pos, mom, cov);
304 } catch (const genfit::Exception&) {
305 B2WARNING("Skipping state with strange pos, mom or cov");
306 continue;
307 }
308
309 posPoints.push_back(ROOT::Math::XYZVector(pos.X(), pos.Y(), pos.Z()));
310 }
311
312 sort(posPoints.begin(), posPoints.end(),
313 [](const ROOT::Math::XYZVector & a, const ROOT::Math::XYZVector & b) -> bool {
314 return a.X() * a.X() + a.Y() * a.Y() > b.X() * b.X() + b.Y() * b.Y();
315 });
316 for (auto vec : posPoints) {
317 track->SetNextPoint(vec.X(), vec.Y(), vec.Z());
318 }
319 // add corresponding hits ---------------------------------------------------------------------
320 TEveStraightLineSet* lines = new TEveStraightLineSet("RecoHits for " + label);
321 lines->SetMainColor(c_recoTrackColor);
322 lines->SetMarkerColor(c_recoTrackColor);
323 lines->SetMarkerStyle(6);
324 lines->SetMainTransparency(60);
325
326 if (drawHits) {
327 // Loop over all hits in the track (three different types)
328 for (const RecoHitInformation::UsedPXDHit* pxdHit : recoTrack.getPXDHitList()) {
329 addRecoHit(pxdHit, lines);
330 }
331
332 for (const RecoHitInformation::UsedSVDHit* svdHit : recoTrack.getSVDHitList()) {
333 addRecoHit(svdHit, lines);
334 }
335
336 for (const RecoHitInformation::UsedCDCHit* cdcHit : recoTrack.getCDCHitList()) {
337 addRecoHit(cdcHit, lines);
338 }
339 }
340
341 track->AddElement(lines);
342 addToGroup(collectionName, track);
343 addObject(&recoTrack, track);
344}
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

◆ addUnassignedRecoHits()

void addUnassignedRecoHits ( const StoreArray< T > &  hits)
inline

After adding recohits for tracks/candidates, this function adds the remaining hits in a global collection.

Definition at line 190 of file EVEVisualization.h.

191 {
192 if (hits.getEntries() == 0)
193 return;
195 m_unassignedRecoHits = new TEveStraightLineSet("Unassigned RecoHits");
196 m_unassignedRecoHits->SetTitle("Unassigned RecoHits");
199 m_unassignedRecoHits->SetMarkerStyle(6);
200 //m_unassignedRecoHits->SetMainTransparency(60);
201 }
202 for (const T& hit : hits) {
203 if (m_shownRecohits.count(&hit) == 0) {
205 }
206 }
207 }

◆ addVertex()

void addVertex ( const genfit::GFRaveVertex *  vertex)

Add a vertex point and its covariance matrix.

Definition at line 1351 of file EVEVisualization.cc.

1352{
1353 ROOT::Math::XYZVector v = ROOT::Math::XYZVector(vertex->getPos());
1354 TEvePointSet* vertexPoint = new TEvePointSet(ObjectInfo::getInfo(vertex));
1355 //sadly, setting a title for a TEveGeoShape doesn't result in a popup...
1356 vertexPoint->SetTitle(ObjectInfo::getTitle(vertex));
1357 vertexPoint->SetMainColor(c_recoHitColor);
1358 vertexPoint->SetNextPoint(v.X(), v.Y(), v.Z());
1359
1360 TMatrixDSymEigen eigen_values(vertex->getCov());
1361 TEveGeoShape* det_shape = new TEveGeoShape(ObjectInfo::getInfo(vertex) + " Error");
1362 det_shape->SetShape(new TGeoSphere(0., 1.)); //Initially created as a sphere, then "scaled" into an ellipsoid.
1363 fixGeoShapeRefCount(det_shape);
1364 const TVectorD& ev = eigen_values.GetEigenValues(); //Assigns the eigenvalues into the "ev" matrix.
1365 const TMatrixD& eVec = eigen_values.GetEigenVectors(); //Assigns the eigenvalues into the "eVec" matrix.
1366 //Define the 3 eigenvectors of the covariance matrix as objects of the ROOT::Math::XYZVector class using constructor.
1367 ROOT::Math::XYZVector eVec1(eVec(0, 0), eVec(1, 0), eVec(2, 0));
1368 //eVec(i,j) uses the method/overloaded operator ( . ) of the TMatrixT class to return the matrix entry.
1369 ROOT::Math::XYZVector eVec2(eVec(0, 1), eVec(1, 1), eVec(2, 1));
1370 ROOT::Math::XYZVector eVec3(eVec(0, 2), eVec(1, 2), eVec(2, 2));
1371 // got everything we need ----------------------------------------------------- //Eigenvalues(semi axis) of the covariance matrix accquired!
1372
1373
1374 TGeoRotation det_rot("det_rot", (eVec1.Theta() * 180) / TMath::Pi(), (eVec1.Phi() * 180) / TMath::Pi(),
1375 (eVec2.Theta() * 180) / TMath::Pi(), (eVec2.Phi() * 180) / TMath::Pi(),
1376 (eVec3.Theta() * 180) / TMath::Pi(), (eVec3.Phi() * 180) / TMath::Pi()); // the rotation is already clear
1377
1378 // set the scaled eigenvalues -------------------------------------------------
1379 //"Scaled" eigenvalues pseudo_res (lengths of the semi axis) are the sqrt of the eigenvalues.
1380 double pseudo_res_0 = std::sqrt(ev(0));
1381 double pseudo_res_1 = std::sqrt(ev(1));
1382 double pseudo_res_2 = std::sqrt(ev(2));
1383
1384 //B2INFO("The pseudo_res_0/1/2 are " << pseudo_res_0 << "," << pseudo_res_1 << "," << pseudo_res_2); //shows the scaled eigenvalues
1385
1386
1387
1388 // rotate and translate -------------------------------------------------------
1389 TGeoGenTrans det_trans(v.X(), v.Y(), v.Z(), pseudo_res_0, pseudo_res_1, pseudo_res_2,
1390 &det_rot); //Puts the ellipsoid at the position of the vertex, v(0)=v.X(), operator () overloaded.
1391 det_shape->SetTransMatrix(det_trans);
1392 // finished rotating and translating ------------------------------------------
1393
1394 det_shape->SetMainColor(kOrange); //The color of the error ellipsoid.
1395 det_shape->SetMainTransparency(0);
1396
1397 vertexPoint->AddElement(det_shape);
1398 addToGroup("Vertices", vertexPoint);
1399 addObject(vertex, vertexPoint);
1400}

◆ boxCreator()

TEveBox * boxCreator ( const ROOT::Math::XYZVector &  o,
ROOT::Math::XYZVector  u,
ROOT::Math::XYZVector  v,
float  ud,
float  vd,
float  depth 
)
private

Create a box around o, oriented along u and v with widths ud, vd and depth and return a pointer to the box object.

Definition at line 849 of file EVEVisualization.cc.

851{
852 //force minimum width of polygon to deal with Eve limits
853 float min = 0.04;
854 if (vd < min)
855 vd = min;
856 if (ud < min)
857 ud = min;
858 if (depth < min)
859 depth = min;
860
861 TEveBox* box = new TEveBox;
862 box->SetPickable(true);
863
864 ROOT::Math::XYZVector norm = u.Cross(v);
865 u *= (0.5 * ud);
866 v *= (0.5 * vd);
867 norm *= (0.5 * depth);
868
869
870 for (int k = 0; k < 8; ++k) {
871 // Coordinates for all eight corners of the box
872 // as two parallel rectangles, with vertices specified in clockwise direction
873 int signU = ((k + 1) & 2) ? -1 : 1;
874 int signV = (k & 4) ? -1 : 1;
875 int signN = (k & 2) ? -1 : 1;
876 float vertex[3];
877 // for (int i = 0; i < 3; ++i) {
878 // vertex[i] = o(i) + signU * u(i) + signV * v(i) + signN * norm(i);
879 // }
880 vertex[0] = o.X() + signU * u.X() + signV * v.X() + signN * norm.X();
881 vertex[1] = o.Y() + signU * u.Y() + signV * v.Y() + signN * norm.Y();
882 vertex[2] = o.Z() + signU * u.Z() + signV * v.Z() + signN * norm.Z();
883 box->SetVertex(k, vertex);
884 }
885
886 return box;
887}

◆ clearEvent()

void clearEvent ( )

clear event data.

Definition at line 1308 of file EVEVisualization.cc.

1309{
1310 if (!gEve)
1311 return;
1312
1314 for (auto& groupPair : m_groups) {
1315 //store visibility, invalidate pointers
1316 if (groupPair.second.group)
1317 groupPair.second.visible = groupPair.second.group->GetRnrState();
1318 groupPair.second.group = nullptr;
1319 }
1320
1321 m_mcparticleTracks.clear();
1322 m_shownRecohits.clear();
1323 m_tracklist->DestroyElements();
1324
1325 //remove ECL data from event
1326 m_calo3d->SetData(NULL);
1327 m_calo3d->DestroyElements();
1328
1329 //lower energy threshold for ECL
1330 float ecl_threshold = 0.01;
1331 if (m_eclData)
1332 ecl_threshold = m_eclData->GetSliceThreshold(0);
1333
1334 destroyEveElement(m_eclData);
1335 m_eclData = new TEveCaloDataVec(1); //#slices
1336 m_eclData->IncDenyDestroy();
1337 m_eclData->RefSliceInfo(0).Setup("ECL", ecl_threshold, kRed);
1338
1341 destroyEveElement(m_unassignedRecoHits);
1342
1343 gEve->GetSelection()->RemoveElements();
1344 gEve->GetHighlight()->RemoveElements();
1345 //other things are cleaned up by TEve...
1346}
bool m_unassignedRecoHitsVisibility
is m_unassignedRecoHits visible?
void clear()
Remove all contents in map.
Definition: VisualRepMap.cc:46

◆ makeLines()

void makeLines ( TEveTrack *  eveTrack,
const genfit::StateOnPlane *  prevState,
const genfit::StateOnPlane *  state,
const genfit::AbsTrackRep *  rep,
TEvePathMark::EType_e  markType,
bool  drawErrors,
int  markerPos = 1 
)
private

Create hit visualisation for the given options, and add them to 'eveTrack'.

Definition at line 889 of file EVEVisualization.cc.

892{
893 using namespace genfit;
894
895 // Need TVector3 for genfit interface
896 TVector3 pos, dir, oldPos, oldDir;
897 rep->getPosDir(*state, pos, dir);
898 rep->getPosDir(*prevState, oldPos, oldDir);
899
900 double distA = (pos - oldPos).Mag();
901 double distB = distA;
902 if ((pos - oldPos)*oldDir < 0)
903 distA *= -1.;
904 if ((pos - oldPos)*dir < 0)
905 distB *= -1.;
906
907 TEvePathMark mark(
908 markType,
909 TEveVector(pos.X(), pos.Y(), pos.Z()),
910 TEveVector(dir.X(), dir.Y(), dir.Z())
911 );
912 eveTrack->AddPathMark(mark);
913
914
915 if (drawErrors) {
916 const MeasuredStateOnPlane* measuredState;
917 if (markerPos == 0)
918 measuredState = dynamic_cast<const MeasuredStateOnPlane*>(prevState);
919 else
920 measuredState = dynamic_cast<const MeasuredStateOnPlane*>(state);
921
922 if (measuredState != NULL) {
923
924 // step for evaluate at a distance from the original plane
925 ROOT::Math::XYZVector eval;
926 if (markerPos == 0)
927 eval = 0.2 * distA * oldDir;
928 else
929 eval = -0.2 * distB * dir;
930
931
932 // get cov at first plane
933 TMatrixDSym cov;
934 // Need TVector3 for genfit interface
935 TVector3 position, direction;
936 rep->getPosMomCov(*measuredState, position, direction, cov);
937
938 // get eigenvalues & -vectors
939 TMatrixDSymEigen eigen_values(cov.GetSub(0, 2, 0, 2));
940 const TVectorD& ev = eigen_values.GetEigenValues();
941 const TMatrixD& eVec = eigen_values.GetEigenVectors();
942 ROOT::Math::XYZVector eVec1, eVec2;
943 // limit
944 static const double maxErr = 1000.;
945 double ev0 = std::min(ev(0), maxErr);
946 double ev1 = std::min(ev(1), maxErr);
947 double ev2 = std::min(ev(2), maxErr);
948
949 // get two largest eigenvalues/-vectors
950 if (ev0 < ev1 && ev0 < ev2) {
951 eVec1.SetXYZ(eVec(0, 1), eVec(1, 1), eVec(2, 1));
952 eVec1 *= sqrt(ev1);
953 eVec2.SetXYZ(eVec(0, 2), eVec(1, 2), eVec(2, 2));
954 eVec2 *= sqrt(ev2);
955 } else if (ev1 < ev0 && ev1 < ev2) {
956 eVec1.SetXYZ(eVec(0, 0), eVec(1, 0), eVec(2, 0));
957 eVec1 *= sqrt(ev0);
958 eVec2.SetXYZ(eVec(0, 2), eVec(1, 2), eVec(2, 2));
959 eVec2 *= sqrt(ev2);
960 } else {
961 eVec1.SetXYZ(eVec(0, 0), eVec(1, 0), eVec(2, 0));
962 eVec1 *= sqrt(ev0);
963 eVec2.SetXYZ(eVec(0, 1), eVec(1, 1), eVec(2, 1));
964 eVec2 *= sqrt(ev1);
965 }
966
967 if (eVec1.Cross(eVec2).Dot(eval) < 0)
968 eVec2 *= -1;
969 //assert(eVec1.Cross(eVec2)*eval > 0);
970
971 ROOT::Math::XYZVector oldEVec1(eVec1);
972
973 const int nEdges = 24;
974 std::vector<ROOT::Math::XYZVector> vertices;
975
976 vertices.push_back(ROOT::Math::XYZVector(position));
977
978 // vertices at plane
979 for (int i = 0; i < nEdges; ++i) {
980 const double angle = 2 * TMath::Pi() / nEdges * i;
981 vertices.push_back(ROOT::Math::XYZVector(position) + cos(angle)*eVec1 + sin(angle)*eVec2);
982 }
983
984
985
986 SharedPlanePtr newPlane(new DetPlane(*(measuredState->getPlane())));
987 newPlane->setO(position + XYZToTVector(eval));
988
989 MeasuredStateOnPlane stateCopy(*measuredState);
990 try {
991 rep->extrapolateToPlane(stateCopy, newPlane);
992 } catch (Exception& e) {
993 B2ERROR(e.what());
994 return;
995 }
996
997 // get cov at 2nd plane
998 rep->getPosMomCov(stateCopy, position, direction, cov);
999
1000 // get eigenvalues & -vectors
1001 {
1002 TMatrixDSymEigen eigen_values2(cov.GetSub(0, 2, 0, 2));
1003 const TVectorD& eVal = eigen_values2.GetEigenValues();
1004 const TMatrixD& eVect = eigen_values2.GetEigenVectors();
1005 // limit
1006 ev0 = std::min(eVal(0), maxErr);
1007 ev1 = std::min(eVal(1), maxErr);
1008 ev2 = std::min(eVal(2), maxErr);
1009
1010 // get two largest eigenvalues/-vectors
1011 if (ev0 < ev1 && ev0 < ev2) {
1012 eVec1.SetXYZ(eVect(0, 1), eVect(1, 1), eVect(2, 1));
1013 eVec1 *= sqrt(ev1);
1014 eVec2.SetXYZ(eVect(0, 2), eVect(1, 2), eVect(2, 2));
1015 eVec2 *= sqrt(ev2);
1016 } else if (ev1 < ev0 && ev1 < ev2) {
1017 eVec1.SetXYZ(eVect(0, 0), eVect(1, 0), eVect(2, 0));
1018 eVec1 *= sqrt(ev0);
1019 eVec2.SetXYZ(eVect(0, 2), eVect(1, 2), eVect(2, 2));
1020 eVec2 *= sqrt(ev2);
1021 } else {
1022 eVec1.SetXYZ(eVect(0, 0), eVect(1, 0), eVect(2, 0));
1023 eVec1 *= sqrt(ev0);
1024 eVec2.SetXYZ(eVect(0, 1), eVect(1, 1), eVect(2, 1));
1025 } eVec2 *= sqrt(ev1);
1026 }
1027
1028 if (eVec1.Cross(eVec2).Dot(eval) < 0)
1029 eVec2 *= -1;
1030 //assert(eVec1.Cross(eVec2)*eval > 0);
1031
1032 if (oldEVec1.Dot(eVec1) < 0) {
1033 eVec1 *= -1;
1034 eVec2 *= -1;
1035 }
1036
1037 // vertices at 2nd plane
1038 double angle0 = ROOT::Math::VectorUtil::Angle(eVec1, oldEVec1);
1039 if (eVec1.Dot(eval.Cross(oldEVec1)) < 0)
1040 angle0 *= -1;
1041 for (int i = 0; i < nEdges; ++i) {
1042 const double angle = 2 * TMath::Pi() / nEdges * i - angle0;
1043 vertices.push_back(ROOT::Math::XYZVector(position) + cos(angle)*eVec1 + sin(angle)*eVec2);
1044 }
1045
1046 vertices.push_back(ROOT::Math::XYZVector(position));
1047
1048
1049 TEveTriangleSet* error_shape = new TEveTriangleSet(vertices.size(), nEdges * 2);
1050 for (unsigned int k = 0; k < vertices.size(); ++k) {
1051 error_shape->SetVertex(k, vertices[k].X(), vertices[k].Y(), vertices[k].Z());
1052 }
1053
1054 assert(vertices.size() == 2 * nEdges + 2);
1055
1056 int iTri(0);
1057 for (int i = 0; i < nEdges; ++i) {
1058 //error_shape->SetTriangle(iTri++, 0, i+1, (i+1)%nEdges+1);
1059 error_shape->SetTriangle(iTri++, i + 1, i + 1 + nEdges, (i + 1) % nEdges + 1);
1060 error_shape->SetTriangle(iTri++, (i + 1) % nEdges + 1, i + 1 + nEdges, (i + 1) % nEdges + 1 + nEdges);
1061 //error_shape->SetTriangle(iTri++, 2*nEdges+1, i+1+nEdges, (i+1)%nEdges+1+nEdges);
1062 }
1063
1064 //assert(iTri == nEdges*4);
1065
1066 error_shape->SetMainColor(c_trackColor);
1067 error_shape->SetMainTransparency(25);
1068 eveTrack->AddElement(error_shape);
1069 }
1070 }
1071}
static constexpr auto XYZToTVector
Helper function to convert XYZVector to TVector3.
Definition: VectorUtil.h:24
double sqrt(double a)
sqrt for double
Definition: beamHelpers.h:28
double eval(const std::vector< double > &spl, const std::vector< double > &vals, double x)
Evaluate spline (zero order or first order) in point x.
Definition: tools.h:115

◆ makeTracks()

void makeTracks ( )

Create visual representation of all tracks.

Needs to be called after all hits / tracks are added.

Definition at line 1249 of file EVEVisualization.cc.

1250{
1251 for (auto& mcTrackPair : m_mcparticleTracks) {
1252 MCTrack& mcTrack = mcTrackPair.second;
1253 if (mcTrack.track) {
1254 if (mcTrack.simhits->Size() > 0) {
1255 mcTrack.track->AddElement(mcTrack.simhits);
1256 } else {
1257 //if we don't add it, remove empty collection
1258 destroyEveElement(mcTrack.simhits);
1259 }
1260
1261 TEveElement* parent = m_tracklist;
1262 if (mcTrack.parentParticle) {
1263 const auto& parentIt = m_mcparticleTracks.find(mcTrack.parentParticle);
1264 if (parentIt != m_mcparticleTracks.end()) {
1265 parent = parentIt->second.track;
1266 }
1267 }
1268 parent->AddElement(mcTrack.track);
1269 } else { //add simhits directly
1270 gEve->AddElement(mcTrack.simhits);
1271 }
1272 }
1273 gEve->AddElement(m_tracklist);
1274 m_tracklist->MakeTracks();
1275 m_tracklist->SelectByP(c_minPCut, FLT_MAX); //don't show too many particles by default...
1276
1277 for (size_t i = 0; i < m_options.length(); i++) {
1278 if (m_options.at(i) == 'M') {
1279 m_gftrackpropagator->SetRnrDaughters(true);
1280 m_gftrackpropagator->SetRnrReferences(true);
1281 //m_gftrackpropagator->SetRnrFV(true); //TODO: this crashes?
1282 TMarker m;
1283 m.SetMarkerColor(c_trackMarkerColor);
1284 m.SetMarkerStyle(1); //a single pixel
1285 m.SetMarkerSize(1); //ignored.
1286 m_gftrackpropagator->RefPMAtt() = m;
1287 m_gftrackpropagator->RefFVAtt() = m;
1288 }
1289 }
1290
1291 m_consttrackpropagator->SetMagField(0, 0, -1.5);
1292
1293 m_eclData->DataChanged(); //update limits (Empty() won't work otherwise)
1294 if (!m_eclData->Empty()) {
1295 m_eclData->SetAxisFromBins(0.0,
1296 0.0); //epsilon_x/y = 0 so we don't merge neighboring bins. This avoids some rendering issues with projections of small clusters.
1297 m_calo3d->SetData(m_eclData);
1298 }
1299 gEve->AddElement(m_calo3d);
1300
1303 gEve->AddElement(m_unassignedRecoHits);
1304 }
1305
1306}
static const int c_trackMarkerColor
Color for track markers.

◆ setAssignToPrimaries()

void setAssignToPrimaries ( bool  on)
inline

If true, hits created by secondary particles (e.g.

delta electrons) will be assigned to the original primary particle.

Definition at line 267 of file EVEVisualization.h.

267{ m_assignToPrimaries = on; }

◆ setErrScale()

void setErrScale ( double  errScale = 1.)

Set the scaling factor for the visualization of track hit errors.

(only affects PXD and SpacePoint hits, which are somewhat small

Definition at line 184 of file EVEVisualization.cc.

184{ m_errorScale = errScale; }

◆ setHideSecondaries()

void setHideSecondaries ( bool  on)
inline

If true, secondary MCParticles (and hits created by them) will not be shown.

Definition at line 270 of file EVEVisualization.h.

270{ m_hideSecondaries = on; }

◆ setOptions()

void setOptions ( const std::string &  opts)

Set the display options.

The option string lets you steer the way the events are displayed. The following options are available:

'D': Draw detectors. This causes a simple representation for all detectors to be drawn. For planar detectors, this is a plane with the same position and orientation of the real detector plane, but with different size. For wires, this is a tube whose diameter is equal to the value measured by the wire. Spacepoint hits are not affected by this option.

'H': Draw hits. This causes the hits to be visualized. Normally, the size of the hit representation is connected to the covariance matrix of the hit, scaled by the value set in setErrScale which is normally 1. Normally used in connection with 'D'.

'M': Draw track markers. Draw the intersection points between the track and the virtual (and/or real) detector planes. 'P': Draw detector planes. Draws the virtual (and/or real) detector planes.

Definition at line 182 of file EVEVisualization.cc.

182{ m_options = opts; }

◆ showUserData()

void showUserData ( const DisplayData displayData)

Add user-defined data (labels, points, etc.)

Definition at line 1843 of file EVEVisualization.cc.

1844{
1845 for (const auto& labelPair : displayData.m_labels) {
1846 TEveText* text = new TEveText(labelPair.first.c_str());
1847 text->SetName(labelPair.first.c_str());
1848 text->SetTitle(labelPair.first.c_str());
1849 text->SetMainColor(kGray + 1);
1850 const ROOT::Math::XYZVector& p = labelPair.second;
1851 text->PtrMainTrans()->SetPos(p.X(), p.Y(), p.Z());
1852 addToGroup("DisplayData", text);
1853 }
1854
1855 for (const auto& pointPair : displayData.m_pointSets) {
1856 TEvePointSet* points = new TEvePointSet(pointPair.first.c_str());
1857 points->SetTitle(pointPair.first.c_str());
1858 points->SetMarkerStyle(7);
1859 points->SetMainColor(kGreen);
1860 for (const auto& p : pointPair.second) {
1861 points->SetNextPoint(p.X(), p.Y(), p.Z());
1862 }
1863 addToGroup("DisplayData", points);
1864 }
1865
1866 int randomColor = 2; //primary colours, changing rapidly with index
1867 for (const auto& arrow : displayData.m_arrows) {
1868 const ROOT::Math::XYZVector pos = arrow.start;
1869 const ROOT::Math::XYZVector dir = arrow.end - pos;
1870 TEveArrow* eveArrow = new TEveArrow(dir.X(), dir.Y(), dir.Z(), pos.X(), pos.Y(), pos.Z());
1871 eveArrow->SetName(arrow.name.c_str());
1872 eveArrow->SetTitle(arrow.name.c_str());
1873 int arrowColor = arrow.color;
1874 if (arrowColor == -1) {
1875 arrowColor = randomColor;
1876 randomColor++;
1877 }
1878 eveArrow->SetMainColor(arrowColor);
1879
1880 //add label
1881 TEveText* text = new TEveText(arrow.name.c_str());
1882 text->SetMainColor(arrowColor);
1883 //place label in middle of arrow, with some slight offset
1884 // orthogonal direction is arbitrary, set smallest component zero
1885 ROOT::Math::XYZVector orthogonalDir;
1886 if (std::abs(dir.X()) < std::abs(dir.Y())) {
1887 if (std::abs(dir.X()) < std::abs(dir.Z())) {
1888 orthogonalDir.SetCoordinates(0, dir.Z(), -dir.Y());
1889 } else {
1890 orthogonalDir.SetCoordinates(dir.Y(), -dir.X(), 0);
1891 }
1892 } else {
1893 if (std::abs(dir.Y()) < std::abs(dir.Z())) {
1894 orthogonalDir.SetCoordinates(-dir.Z(), 0, dir.X());
1895 } else {
1896 orthogonalDir.SetCoordinates(dir.Y(), -dir.X(), 0);
1897 }
1898 }
1899 const ROOT::Math::XYZVector& labelPos = pos + 0.5 * dir + 0.1 * orthogonalDir;
1900 text->PtrMainTrans()->SetPos(labelPos.X(), labelPos.Y(), labelPos.Z());
1901 eveArrow->AddElement(text);
1902 addToGroup("DisplayData", eveArrow);
1903 }
1904
1905}
std::vector< Arrow > m_arrows
List of arrows.
Definition: DisplayData.h:114
std::map< std::string, std::vector< ROOT::Math::XYZVector > > m_pointSets
name -> points map
Definition: DisplayData.h:108
std::vector< std::pair< std::string, ROOT::Math::XYZVector > > m_labels
text labels (to be shown at a given position).
Definition: DisplayData.h:109

Member Data Documentation

◆ c_klmClusterColor

const int c_klmClusterColor = getTColorID("Chameleon", 1)
staticprivate

Color for KLMCluster objects.

Definition at line 99 of file EVEVisualization.h.

◆ c_minPCut

constexpr double c_minPCut = 0.00
staticconstexprprivate

don't show MCParticles with momentum below this cutoff.

Definition at line 363 of file EVEVisualization.h.

◆ c_recoHitColor

const int c_recoHitColor = getTColorID("Orange", 1)
staticprivate

Color for reco hits.

Definition at line 89 of file EVEVisualization.h.

◆ c_recoTrackColor

const int c_recoTrackColor = getTColorID("Sky Blue", 1)
staticprivate

Color for TrackCandidates.

Definition at line 91 of file EVEVisualization.h.

◆ c_trackColor

const int c_trackColor = getTColorID("Sky Blue", 2)
staticprivate

Color for tracks.

Definition at line 93 of file EVEVisualization.h.

◆ c_trackMarkerColor

const int c_trackMarkerColor = getTColorID("Chameleon", 3)
staticprivate

Color for track markers.

Definition at line 95 of file EVEVisualization.h.

◆ c_unassignedHitColor

const int c_unassignedHitColor = getTColorID("Plum", 1)
staticprivate

Color for unassigned (reco)hits.

Definition at line 97 of file EVEVisualization.h.

◆ m_assignToPrimaries

bool m_assignToPrimaries
private

If true, hits created by secondary particles (e.g.

delta electrons) will be assigned to the original primary particle.

Definition at line 325 of file EVEVisualization.h.

◆ m_bfield

EveVisBField* m_bfield
private

The global magnetic field.

Definition at line 352 of file EVEVisualization.h.

◆ m_calo3d

TEveCalo3D* m_calo3d
private

Object for the energy bar visualisation.

Definition at line 275 of file EVEVisualization.h.

◆ m_consttrackpropagator

TEveTrackPropagator* m_consttrackpropagator
private

Track propagator for CDCTriggerTracks (uses constant B field)

Definition at line 346 of file EVEVisualization.h.

◆ m_drawBackward

bool m_drawBackward = false
private

draw backward in addTrack

Definition at line 378 of file EVEVisualization.h.

◆ m_drawCardinalRep

bool m_drawCardinalRep = true
private

Draw cardinal representation in addTrack.

Definition at line 366 of file EVEVisualization.h.

◆ m_drawErrors

bool m_drawErrors = false
private

Draw errors in addTrack.

Definition at line 369 of file EVEVisualization.h.

◆ m_drawForward

bool m_drawForward = false
private

draw forward in addTrack

Definition at line 375 of file EVEVisualization.h.

◆ m_drawRefTrack

bool m_drawRefTrack = false
private

Draw reference track in addTrack.

Definition at line 372 of file EVEVisualization.h.

◆ m_eclData

TEveCaloDataVec* m_eclData
private

ECL cluster data.

Definition at line 349 of file EVEVisualization.h.

◆ m_errorScale

double m_errorScale
private

Rescale PXD/SVD errors with this factor to ensure visibility.

Definition at line 316 of file EVEVisualization.h.

◆ m_gftrackpropagator

TEveTrackPropagator* m_gftrackpropagator
private

Track propagator for genfit::Tracks (different mainly because of drawing options)

Definition at line 343 of file EVEVisualization.h.

◆ m_groups

std::map<std::string, ElementGroup> m_groups
private

name -> grouping element.

Definition at line 334 of file EVEVisualization.h.

◆ m_hideSecondaries

bool m_hideSecondaries {false}
private

If true, secondary MCParticles (and hits created by them) will not be shown.

Definition at line 328 of file EVEVisualization.h.

◆ m_mcparticleTracks

std::map<const MCParticle*, MCTrack> m_mcparticleTracks
private

map MCParticles to MCTrack (so hits can be added to the correct track).

Definition at line 331 of file EVEVisualization.h.

◆ m_options

std::string m_options
private

Option string for genfit::Track visualisation.

See also
setOptions

Definition at line 322 of file EVEVisualization.h.

◆ m_shownRecohits

std::set<const TObject*> m_shownRecohits
private

List of shown recohits (PXDCluster, SVDCluster, CDCHit).

Definition at line 355 of file EVEVisualization.h.

◆ m_tracklist

TEveTrackList* m_tracklist
private

parent object for MC tracks.

Definition at line 337 of file EVEVisualization.h.

◆ m_trackpropagator

TEveTrackPropagator* m_trackpropagator
private

Track propagator for MCParticles.

Definition at line 340 of file EVEVisualization.h.

◆ m_unassignedRecoHits

TEveStraightLineSet* m_unassignedRecoHits = nullptr
private

Unassigned recohits.

Definition at line 358 of file EVEVisualization.h.

◆ m_unassignedRecoHitsVisibility

bool m_unassignedRecoHitsVisibility = true
private

is m_unassignedRecoHits visible?

Definition at line 360 of file EVEVisualization.h.


The documentation for this class was generated from the following files: