28#include <display/EVEVisualization.h>
30#include <display/VisualRepMap.h>
31#include <display/EveGeometry.h>
32#include <display/EveVisBField.h>
33#include <display/ObjectInfo.h>
35#include <vxd/geometry/GeoCache.h>
36#include <klm/bklm/geometry/GeometryPar.h>
37#include <cdc/geometry/CDCGeometryPar.h>
38#include <cdc/dataobjects/CDCRecoHit.h>
39#include <cdc/translators/RealisticTDCCountTranslator.h>
40#include <arich/dbobjects/ARICHGeometryConfig.h>
41#include <simulation/dataobjects/MCParticleTrajectory.h>
42#include <svd/reconstruction/SVDRecoHit.h>
43#include <top/geometry/TOPGeometryPar.h>
45#include <genfit/AbsMeasurement.h>
46#include <genfit/PlanarMeasurement.h>
47#include <genfit/SpacepointMeasurement.h>
48#include <genfit/WireMeasurement.h>
49#include <genfit/WireMeasurementNew.h>
50#include <genfit/WirePointMeasurement.h>
51#include <genfit/DetPlane.h>
52#include <genfit/Exception.h>
53#include <genfit/KalmanFitterInfo.h>
54#include <genfit/GblFitterInfo.h>
56#include <framework/dataobjects/DisplayData.h>
57#include <framework/logging/Logger.h>
58#include <framework/utilities/ColorPalette.h>
59#include <framework/geometry/VectorUtil.h>
61#include <Math/VectorUtil.h>
65#include <TEveManager.h>
66#include <TEveGeoShape.h>
68#include <TEvePointSet.h>
69#include <TEveSelection.h>
70#include <TEveStraightLineSet.h>
71#include <TEveTriangleSet.h>
74#include <TEveTrackPropagator.h>
76#include <TGeoMatrix.h>
77#include <TGeoManager.h>
78#include <TGeoSphere.h>
80#include <TGLLogicalShape.h>
85#include <TMatrixDSymEigen.h>
87#include <boost/scoped_ptr.hpp>
88#include <boost/algorithm/string/find.hpp>
89#include <boost/algorithm/string/trim.hpp>
90#include <boost/algorithm/string/classification.hpp>
100 template <
class T>
void destroyEveElement(T*& el)
103 if (el->GetDenyDestroy() > 1)
104 B2WARNING(
"destroyEveElement(): Element " << el->GetName() <<
" has unexpected refcount " << el->GetDenyDestroy());
106 el->DecDenyDestroy();
116 void fixGeoShapeRefCount(TEveGeoShape* eveshape)
118 TGeoShape* s = eveshape->GetShape();
120 if (gGeoManager->GetListOfShapes()->Last() == s)
121 gGeoManager->GetListOfShapes()->RemoveAt(gGeoManager->GetListOfShapes()->GetLast());
123 gGeoManager->GetListOfShapes()->Remove(s);
141 TGLLogicalShape::SetIgnoreSizeForCameraInterest(kTRUE);
167 m_calo3d =
new TEveCalo3D(NULL,
"ECLClusters");
169 m_calo3d->SetForwardEndCapPos(196.5);
170 m_calo3d->SetBackwardEndCapPos(-102.0);
172 m_calo3d->SetRnrFrame(
false,
false);
176 gEve->GetSelection()->IncDenyDestroy();
177 gEve->GetHighlight()->IncDenyDestroy();
207 bool drawHits =
false;
210 for (
size_t i = 0; i <
m_options.length(); i++) {
211 if (
m_options.at(i) ==
'H') drawHits =
true;
221 TEveStraightLineSet* lines =
new TEveStraightLineSet(
"RecoHits for " + label);
224 lines->SetMarkerStyle(6);
225 lines->SetMainTransparency(60);
242 TEveRecTrack rectrack;
243 rectrack.fP.Set(track_mom);
244 rectrack.fV.Set(track_pos);
247 track_lines->SetName(label);
250 track_lines->SetLineWidth(1);
256 track_lines->AddElement(lines);
266 bool drawHits =
false;
269 for (
size_t i = 0; i <
m_options.length(); i++) {
270 if (
m_options.at(i) ==
'H') drawHits =
true;
277 TEveLine* track =
new TEveLine();
278 std::vector<ROOT::Math::XYZVector> posPoints;
279 track->SetName(label);
281 track->SetLineWidth(3);
283 track->SetSmooth(
true);
287 if (!recoHit->useInFit())
297 const auto* fittedResult = trackPoint->getFitterInfo();
298 if (not fittedResult) {
299 B2WARNING(
"Skipping unfitted track point");
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");
309 posPoints.push_back(ROOT::Math::XYZVector(pos.X(), pos.Y(), pos.Z()));
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();
316 for (
auto vec : posPoints) {
317 track->SetNextPoint(vec.X(), vec.Y(), vec.Z());
320 TEveStraightLineSet* lines =
new TEveStraightLineSet(
"RecoHits for " + label);
323 lines->SetMarkerStyle(6);
324 lines->SetMainTransparency(60);
341 track->AddElement(lines);
348template <
typename TriggerTrack>
350 const TriggerTrack& trgTrack)
355 B2Vector3D track_mom = (trgTrack.getChargeSign() == 0) ?
356 trgTrack.getDirection() * 1000 :
357 trgTrack.getMomentum(1.5);
359 TEveRecTrack rectrack;
360 rectrack.fP.Set(track_mom);
361 rectrack.fV.Set(track_pos);
364 track_lines->SetName(label);
366 track_lines->SetLineColor(kOrange + 2);
367 track_lines->SetLineWidth(1);
370 TString::Format(
"\ncharge: %d, phi: %.2fdeg, pt: %.2fGeV, theta: %.2fdeg, z: %.2fcm",
371 trgTrack.getChargeSign(),
372 trgTrack.getPhi0() * 180 / M_PI,
373 trgTrack.getTransverseMomentum(1.5),
374 trgTrack.getDirection().Theta() * 180 / M_PI,
377 track_lines->SetCharge(trgTrack.getChargeSign());
380 if (trgTrack.getZ0() == 0 && trgTrack.getCotTheta() == 0)
381 track_lines->SetLineStyle(2);
399 B2ERROR(
"Track without TrackFitResult skipped.");
407 bool drawDetectors =
false;
408 bool drawHits =
false;
409 bool drawPlanes =
false;
412 for (
size_t i = 0; i <
m_options.length(); i++) {
413 if (
m_options.at(i) ==
'D') drawDetectors =
true;
414 if (
m_options.at(i) ==
'H') drawHits =
true;
415 if (
m_options.at(i) ==
'P') drawPlanes =
true;
423 bool isPruned = (track ==
nullptr);
426 TEveRecTrackD recTrack;
428 recTrack.fV.Set(poca);
431 if (std::isfinite(poca_momentum.
Mag()))
432 recTrack.fP.Set(poca_momentum);
438 eveTrack->SetName(label);
442 const genfit::AbsTrackRep* representation;
445 representation = track->getCardinalRepresentation();
446 B2DEBUG(100,
"Draw cardinal rep");
448 const auto& representations = track->getRepresentations();
449 if (representations.empty()) {
450 B2ERROR(
"No representations found in the reco track!");
453 B2DEBUG(100,
"Draw representation number 0.");
454 representation = representations.front();
457 if (!track->hasTrackFitStatus(representation)) {
458 B2ERROR(
"RecoTrack without FitStatus: will be skipped!");
462 const genfit::FitStatus* fitStatus = track->getTrackFitStatus(representation);
464 isPruned = fitStatus->isTrackPruned();
468 genfit::KalmanFitterInfo* fi = 0;
469 genfit::KalmanFitterInfo* prevFi = 0;
470 genfit::GblFitterInfo* gfi = 0;
471 genfit::GblFitterInfo* prevGFi = 0;
472 const genfit::MeasuredStateOnPlane* fittedState(NULL);
473 const genfit::MeasuredStateOnPlane* prevFittedState(NULL);
476 const auto& hitPoints = track->getHitPointsWithMeasurement();
477 const unsigned int numpoints = hitPoints.size();
480 for (
const genfit::TrackPoint* tp : hitPoints) {
484 if (! tp->hasFitterInfo(representation)) {
485 B2ERROR(
"trackPoint has no fitterInfo for rep");
489 genfit::AbsFitterInfo* fitterInfo = tp->getFitterInfo(representation);
491 fi =
dynamic_cast<genfit::KalmanFitterInfo*
>(fitterInfo);
492 gfi =
dynamic_cast<genfit::GblFitterInfo*
>(fitterInfo);
495 B2ERROR(
"Can only display KalmanFitterInfo or GblFitterInfo");
500 B2FATAL(
"AbsFitterInfo dynamic-casted to both KalmanFitterInfo and GblFitterInfo!");
503 if (fi && ! tp->hasRawMeasurements()) {
504 B2ERROR(
"trackPoint has no raw measurements");
508 if (fi && ! fi->hasPredictionsAndUpdates()) {
509 B2ERROR(
"KalmanFitterInfo does not have all predictions and updates");
515 fittedState = &(gfi->getFittedState(
true));
517 fittedState = &(fi->getFittedState(
true));
518 }
catch (genfit::Exception& e) {
519 B2ERROR(e.what() <<
" - can not get fitted state");
523 ROOT::Math::XYZVector track_pos = ROOT::Math::XYZVector(representation->getPos(*fittedState));
526 if (prevFittedState != NULL) {
528 TEvePathMark::EType_e markType = TEvePathMark::kReference;
529 if (hitCounter + 1 ==
static_cast<int>(numpoints))
530 markType = TEvePathMark::kDecay;
541 makeLines(eveTrack, prevFi->getForwardUpdate(), fi->getForwardPrediction(), representation, markType,
m_drawErrors, 0);
543 makeLines(eveTrack, prevFi->getBackwardPrediction(), fi->getBackwardUpdate(), representation, markType,
m_drawErrors);
545 if (
m_drawRefTrack && fi->hasReferenceState() && prevFi->hasReferenceState())
546 makeLines(eveTrack, prevFi->getReferenceState(), fi->getReferenceState(), representation, markType,
false);
550 if (gfi && prevGFi) {
556 if (
m_drawRefTrack && gfi->hasReferenceState() && prevGFi->hasReferenceState()) {
557 genfit::StateOnPlane prevSop = prevGFi->getReferenceState();
558 genfit::StateOnPlane sop = gfi->getReferenceState();
559 makeLines(eveTrack, &prevSop, &sop, representation, markType,
false);
566 prevFittedState = fittedState;
570 const int numMeasurements = tp->getNumRawMeasurements();
571 for (
int iMeasurement = 0; iMeasurement < numMeasurements; iMeasurement++) {
572 const genfit::AbsMeasurement* m = tp->getRawMeasurement(iMeasurement);
574 TVectorT<double> hit_coords;
575 TMatrixTSym<double> hit_cov;
579 genfit::MeasurementOnPlane* mop = fi->getMeasurementOnPlane(iMeasurement);
580 hit_coords.ResizeTo(mop->getState());
581 hit_cov.ResizeTo(mop->getCov());
582 hit_coords = mop->getState();
583 hit_cov = mop->getCov();
589 genfit::MeasurementOnPlane gblMeas = gfi->getMeasurement();
590 hit_coords.ResizeTo(gblMeas.getState());
591 hit_cov.ResizeTo(gblMeas.getCov());
592 hit_coords = gblMeas.getState();
593 hit_cov = gblMeas.getCov();
599 ROOT::Math::XYZVector o = ROOT::Math::XYZVector(fittedState->getPlane()->getO());
600 ROOT::Math::XYZVector u = ROOT::Math::XYZVector(fittedState->getPlane()->getU());
601 ROOT::Math::XYZVector v = ROOT::Math::XYZVector(fittedState->getPlane()->getV());
603 bool planar_hit =
false;
604 bool planar_pixel_hit =
false;
605 bool space_hit =
false;
606 bool wire_hit =
false;
607 bool wirepoint_hit =
false;
610 double_t plane_size = 4;
612 if (
dynamic_cast<const genfit::PlanarMeasurement*
>(m) != NULL) {
613 int hit_coords_dim = m->getDim();
615 if (hit_coords_dim == 1) {
616 hit_u = hit_coords(0);
617 }
else if (hit_coords_dim == 2) {
618 planar_pixel_hit =
true;
619 hit_u = hit_coords(0);
620 hit_v = hit_coords(1);
622 }
else if (
dynamic_cast<const genfit::SpacepointMeasurement*
>(m) != NULL) {
625 ||
dynamic_cast<const genfit::WireMeasurement*
>(m)
626 ||
dynamic_cast<const genfit::WireMeasurementNew*
>(m)) {
628 hit_u = fabs(hit_coords(0));
629 hit_v = v.Dot(track_pos - o);
630 if (
dynamic_cast<const genfit::WirePointMeasurement*
>(m) != NULL) {
631 wirepoint_hit =
true;
632 hit_v = hit_coords(1);
635 B2ERROR(
"Hit " << hitCounter <<
", Measurement " << iMeasurement <<
": Unknown measurement type: skipping hit!");
642 if (drawPlanes || (drawDetectors && planar_hit)) {
643 ROOT::Math::XYZVector move(0, 0, 0);
644 if (wire_hit) move = v * (v.Dot(track_pos - o));
645 TEveBox* box =
boxCreator(o + move, u, v, plane_size, plane_size, 0.01);
646 if (drawDetectors && planar_hit) {
647 box->SetMainColor(kCyan);
649 box->SetMainColor(kGray);
651 box->SetMainTransparency(50);
652 eveTrack->AddElement(box);
660 TEveGeoShape* det_shape =
new TEveGeoShape(
"det_shape");
661 det_shape->SetShape(
new TGeoTube(std::max(0., (
double)(hit_u - 0.0105 / 2.)), hit_u + 0.0105 / 2., plane_size));
662 fixGeoShapeRefCount(det_shape);
664 ROOT::Math::XYZVector norm = u.Cross(v);
665 TGeoRotation det_rot(
"det_rot", (u.Theta() * 180) / TMath::Pi(), (u.Phi() * 180) / TMath::Pi(),
666 (norm.Theta() * 180) / TMath::Pi(), (norm.Phi() * 180) / TMath::Pi(),
667 (v.Theta() * 180) / TMath::Pi(), (v.Phi() * 180) / TMath::Pi());
668 ROOT::Math::XYZVector move = v * (v.Dot(track_pos - o));
669 TGeoCombiTrans det_trans(o.X() + move.X(),
673 det_shape->SetTransMatrix(det_trans);
674 det_shape->SetMainColor(kCyan);
675 det_shape->SetMainTransparency(25);
676 if ((drawHits && (hit_u + 0.0105 / 2 > 0)) || !drawHits) {
677 eveTrack->AddElement(det_shape);
688 if (!planar_pixel_hit) {
693 B2WARNING(
"SVD recohit couldn't be converted... ");
699 ROOT::Math::XYZVector a = o;
700 double hit_res_u = hit_cov(0, 0);
701 if (recoHit->
isU()) {
702 du = std::sqrt(hit_res_u);
703 dv = sensor.getLength();
706 du = sensor.getWidth();
707 dv = std::sqrt(hit_res_u);
710 double depth = sensor.getThickness();
711 TEveBox* hit_box =
boxCreator(a, u, v, du, dv, depth);
712 hit_box->SetName(
"SVDRecoHit");
714 hit_box->SetMainTransparency(0);
715 eveTrack->AddElement(hit_box);
719 TMatrixDSymEigen eigen_values(hit_cov);
720 TEveGeoShape* cov_shape =
new TEveGeoShape(
"PXDRecoHit");
721 const TVectorD& ev = eigen_values.GetEigenValues();
722 const TMatrixD& eVec = eigen_values.GetEigenVectors();
728 cov_shape->SetShape(
new TGeoEltu(pseudo_res_0, pseudo_res_1, 0.0105));
729 fixGeoShapeRefCount(cov_shape);
730 ROOT::Math::XYZVector pix_pos = o + hit_u * u + hit_v * v;
731 ROOT::Math::XYZVector u_semiaxis = (pix_pos + eVec(0, 0) * u + eVec(1, 0) * v) - pix_pos;
732 ROOT::Math::XYZVector v_semiaxis = (pix_pos + eVec(0, 1) * u + eVec(1, 1) * v) - pix_pos;
733 ROOT::Math::XYZVector norm = u.Cross(v);
737 TGeoRotation det_rot(
"det_rot", (u_semiaxis.Theta() * 180) / TMath::Pi(), (u_semiaxis.Phi() * 180) / TMath::Pi(),
738 (v_semiaxis.Theta() * 180) / TMath::Pi(), (v_semiaxis.Phi() * 180) / TMath::Pi(),
739 (norm.Theta() * 180) / TMath::Pi(), (norm.Phi() * 180) / TMath::Pi());
740 TGeoCombiTrans det_trans(pix_pos.X(), pix_pos.Y(), pix_pos.Z(), &det_rot);
741 cov_shape->SetTransMatrix(det_trans);
745 cov_shape->SetMainTransparency(0);
746 eveTrack->AddElement(cov_shape);
755 TMatrixDSymEigen eigen_values(m->getRawHitCov());
756 TEveGeoShape* cov_shape =
new TEveGeoShape(
"SpacePoint Hit");
757 cov_shape->SetShape(
new TGeoSphere(0., 1.));
758 fixGeoShapeRefCount(cov_shape);
759 const TVectorD& ev = eigen_values.GetEigenValues();
760 const TMatrixD& eVec = eigen_values.GetEigenVectors();
761 ROOT::Math::XYZVector eVec1(eVec(0, 0), eVec(1, 0), eVec(2, 0));
762 ROOT::Math::XYZVector eVec2(eVec(0, 1), eVec(1, 1), eVec(2, 1));
763 ROOT::Math::XYZVector eVec3(eVec(0, 2), eVec(1, 2), eVec(2, 2));
767 TGeoRotation det_rot(
"det_rot", (eVec1.Theta() * 180) / TMath::Pi(), (eVec1.Phi() * 180) / TMath::Pi(),
768 (eVec2.Theta() * 180) / TMath::Pi(), (eVec2.Phi() * 180) / TMath::Pi(),
769 (eVec3.Theta() * 180) / TMath::Pi(), (eVec3.Phi() * 180) / TMath::Pi());
778 TGeoGenTrans det_trans(o.X(), o.Y(), o.Z(),
781 pseudo_res_0, pseudo_res_1, pseudo_res_2,
783 cov_shape->SetTransMatrix(det_trans);
787 cov_shape->SetMainTransparency(10);
788 eveTrack->AddElement(cov_shape);
794 const double cdcErrorScale = 1.0;
795 TEveGeoShape* cov_shape =
new TEveGeoShape(
"CDCRecoHit");
796 double pseudo_res_0 = cdcErrorScale * std::sqrt(hit_cov(0, 0));
797 double pseudo_res_1 = plane_size;
798 if (wirepoint_hit) pseudo_res_1 = cdcErrorScale * std::sqrt(hit_cov(1, 1));
800 cov_shape->SetShape(
new TGeoTube(std::max(0., (
double)(hit_u - pseudo_res_0)), hit_u + pseudo_res_0, pseudo_res_1));
801 fixGeoShapeRefCount(cov_shape);
802 ROOT::Math::XYZVector norm = u.Cross(v);
805 TGeoRotation det_rot(
"det_rot", (u.Theta() * 180) / TMath::Pi(), (u.Phi() * 180) / TMath::Pi(),
806 (norm.Theta() * 180) / TMath::Pi(), (norm.Phi() * 180) / TMath::Pi(),
807 (v.Theta() * 180) / TMath::Pi(), (v.Phi() * 180) / TMath::Pi());
808 TGeoCombiTrans det_trans(o.X() + hit_v * v.X(),
809 o.Y() + hit_v * v.Y(),
810 o.Z() + hit_v * v.Z(),
812 cov_shape->SetTransMatrix(det_trans);
816 cov_shape->SetMainTransparency(50);
817 eveTrack->AddElement(cov_shape);
825 auto& firstref = eveTrack->RefPathMarks().front();
826 auto& lastref = eveTrack->RefPathMarks().back();
827 double f = firstref.fV.Distance(recTrack.fV);
828 double b = lastref.fV.Distance(recTrack.fV);
829 if (f > 100 and f > b) {
830 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)");
832 lastref.fType = TEvePathMarkD::kReference;
833 firstref.fType = TEvePathMarkD::kDecay;
834 std::reverse(eveTrack->RefPathMarks().begin(), eveTrack->RefPathMarks().end());
837 eveTrack->SetTitle(TString::Format(
"%s\n"
842 isPruned ?
" yes" :
"no",
843 poca_momentum.
Pt(), poca_momentum.
Pz(),
847 eveTrack->SetLineStyle(1);
848 eveTrack->SetLineWidth(3.0);
859 float vd,
float depth)
870 TEveBox* box =
new TEveBox;
871 box->SetPickable(
true);
873 ROOT::Math::XYZVector norm = u.Cross(v);
876 norm *= (0.5 * depth);
879 for (
int k = 0; k < 8; ++k) {
882 int signU = ((k + 1) & 2) ? -1 : 1;
883 int signV = (k & 4) ? -1 : 1;
884 int signN = (k & 2) ? -1 : 1;
889 vertex[0] = o.X() + signU * u.X() + signV * v.X() + signN * norm.X();
890 vertex[1] = o.Y() + signU * u.Y() + signV * v.Y() + signN * norm.Y();
891 vertex[2] = o.Z() + signU * u.Z() + signV * v.Z() + signN * norm.Z();
892 box->SetVertex(k, vertex);
899 const genfit::StateOnPlane* state,
900 const genfit::AbsTrackRep* rep,
901 TEvePathMark::EType_e markType,
bool drawErrors,
int markerPos)
903 using namespace genfit;
906 TVector3 pos, dir, oldPos, oldDir;
907 rep->getPosDir(*state, pos, dir);
908 rep->getPosDir(*prevState, oldPos, oldDir);
910 double distA = (pos - oldPos).Mag();
911 double distB = distA;
912 if ((pos - oldPos)*oldDir < 0)
914 if ((pos - oldPos)*dir < 0)
919 TEveVector(pos.X(), pos.Y(), pos.Z()),
920 TEveVector(dir.X(), dir.Y(), dir.Z())
922 eveTrack->AddPathMark(mark);
926 const MeasuredStateOnPlane* measuredState;
928 measuredState =
dynamic_cast<const MeasuredStateOnPlane*
>(prevState);
930 measuredState =
dynamic_cast<const MeasuredStateOnPlane*
>(state);
932 if (measuredState != NULL) {
935 ROOT::Math::XYZVector
eval;
937 eval = 0.2 * distA * oldDir;
939 eval = -0.2 * distB * dir;
945 TVector3 position, direction;
946 rep->getPosMomCov(*measuredState, position, direction, cov);
949 TMatrixDSymEigen eigen_values(cov.GetSub(0, 2, 0, 2));
950 const TVectorD& ev = eigen_values.GetEigenValues();
951 const TMatrixD& eVec = eigen_values.GetEigenVectors();
952 ROOT::Math::XYZVector eVec1, eVec2;
954 static const double maxErr = 1000.;
955 double ev0 = std::min(ev(0), maxErr);
956 double ev1 = std::min(ev(1), maxErr);
957 double ev2 = std::min(ev(2), maxErr);
960 if (ev0 < ev1 && ev0 < ev2) {
961 eVec1.SetXYZ(eVec(0, 1), eVec(1, 1), eVec(2, 1));
963 eVec2.SetXYZ(eVec(0, 2), eVec(1, 2), eVec(2, 2));
965 }
else if (ev1 < ev0 && ev1 < ev2) {
966 eVec1.SetXYZ(eVec(0, 0), eVec(1, 0), eVec(2, 0));
968 eVec2.SetXYZ(eVec(0, 2), eVec(1, 2), eVec(2, 2));
971 eVec1.SetXYZ(eVec(0, 0), eVec(1, 0), eVec(2, 0));
973 eVec2.SetXYZ(eVec(0, 1), eVec(1, 1), eVec(2, 1));
977 if (eVec1.Cross(eVec2).Dot(
eval) < 0)
981 ROOT::Math::XYZVector oldEVec1(eVec1);
983 const int nEdges = 24;
984 std::vector<ROOT::Math::XYZVector> vertices;
986 vertices.push_back(ROOT::Math::XYZVector(position));
989 for (
int i = 0; i < nEdges; ++i) {
990 const double angle = 2 * TMath::Pi() / nEdges * i;
991 vertices.push_back(ROOT::Math::XYZVector(position) + cos(angle)*eVec1 + sin(angle)*eVec2);
996 SharedPlanePtr newPlane(
new DetPlane(*(measuredState->getPlane())));
999 MeasuredStateOnPlane stateCopy(*measuredState);
1001 rep->extrapolateToPlane(stateCopy, newPlane);
1008 rep->getPosMomCov(stateCopy, position, direction, cov);
1012 TMatrixDSymEigen eigen_values2(cov.GetSub(0, 2, 0, 2));
1013 const TVectorD& eVal = eigen_values2.GetEigenValues();
1014 const TMatrixD& eVect = eigen_values2.GetEigenVectors();
1016 ev0 = std::min(eVal(0), maxErr);
1017 ev1 = std::min(eVal(1), maxErr);
1018 ev2 = std::min(eVal(2), maxErr);
1021 if (ev0 < ev1 && ev0 < ev2) {
1022 eVec1.SetXYZ(eVect(0, 1), eVect(1, 1), eVect(2, 1));
1024 eVec2.SetXYZ(eVect(0, 2), eVect(1, 2), eVect(2, 2));
1026 }
else if (ev1 < ev0 && ev1 < ev2) {
1027 eVec1.SetXYZ(eVect(0, 0), eVect(1, 0), eVect(2, 0));
1029 eVec2.SetXYZ(eVect(0, 2), eVect(1, 2), eVect(2, 2));
1032 eVec1.SetXYZ(eVect(0, 0), eVect(1, 0), eVect(2, 0));
1034 eVec2.SetXYZ(eVect(0, 1), eVect(1, 1), eVect(2, 1));
1035 } eVec2 *=
sqrt(ev1);
1038 if (eVec1.Cross(eVec2).Dot(
eval) < 0)
1042 if (oldEVec1.Dot(eVec1) < 0) {
1048 double angle0 = ROOT::Math::VectorUtil::Angle(eVec1, oldEVec1);
1049 if (eVec1.Dot(
eval.Cross(oldEVec1)) < 0)
1051 for (
int i = 0; i < nEdges; ++i) {
1052 const double angle = 2 * TMath::Pi() / nEdges * i - angle0;
1053 vertices.push_back(ROOT::Math::XYZVector(position) + cos(angle)*eVec1 + sin(angle)*eVec2);
1056 vertices.push_back(ROOT::Math::XYZVector(position));
1059 TEveTriangleSet* error_shape =
new TEveTriangleSet(vertices.size(), nEdges * 2);
1060 for (
unsigned int k = 0; k < vertices.size(); ++k) {
1061 error_shape->SetVertex(k, vertices[k].X(), vertices[k].Y(), vertices[k].Z());
1064 assert(vertices.size() == 2 * nEdges + 2);
1067 for (
int i = 0; i < nEdges; ++i) {
1069 error_shape->SetTriangle(iTri++, i + 1, i + 1 + nEdges, (i + 1) % nEdges + 1);
1070 error_shape->SetTriangle(iTri++, (i + 1) % nEdges + 1, i + 1 + nEdges, (i + 1) % nEdges + 1 + nEdges);
1077 error_shape->SetMainTransparency(25);
1078 eveTrack->AddElement(error_shape);
1101 const ROOT::Math::XYZVector& global_pos = hit->
getPosition();
1109 track->simhits->SetNextPoint(v.X(), v.Y(), v.Z());
1116 const TString pointsTitle(
"Unassigned SimHits");
1132 particle = particle->getMother();
1136 const ROOT::Math::XYZVector& p = particle->getMomentum();
1137 const ROOT::Math::XYZVector& vertex = particle->getProductionVertex();
1138 const int pdg = particle->getPDG();
1139 TParticle tparticle(pdg, particle->getStatus(),
1140 (particle->getMother() ? particle->getMother()->getIndex() : 0), 0, particle->getFirstDaughter(), particle->getLastDaughter(),
1141 p.X(), p.Y(), p.Z(), particle->getEnergy(),
1142 vertex.X(), vertex.Y(), vertex.Z(), particle->getProductionTime());
1143 TEveMCTrack mctrack;
1144 mctrack = tparticle;
1145 mctrack.fTDecay = particle->getDecayTime();
1146 mctrack.fVDecay.Set(
B2Vector3D(particle->getDecayVertex()));
1147 mctrack.fDecayed = !std::isinf(mctrack.fTDecay);
1148 mctrack.fIndex = particle->getIndex();
1153 bool hasTrajectory(
false);
1154 for (
auto rel : mcTrajectories.relations()) {
1157 if (rel.weight <= 0)
continue;
1168 (&pt == &trajectory.
back()) ? TEvePathMark::kDecay : TEvePathMark::kReference,
1169 TEveVector(pt.x, pt.y, pt.z),
1170 TEveVector(pt.px, pt.py, pt.pz)
1174 hasTrajectory =
true;
1179 if (!hasTrajectory) {
1181 for (
int iDaughter = particle->getFirstDaughter(); iDaughter <= particle->getLastDaughter(); iDaughter++) {
1187 TEvePathMarkD refMark(TEvePathMarkD::kDaughter);
1188 refMark.fV.Set(
B2Vector3D(daughter->getProductionVertex()));
1189 refMark.fP.Set(
B2Vector3D(daughter->getMomentum()));
1190 refMark.fTime = daughter->getProductionTime();
1197 and mctrack.fDecayed) {
1198 TEvePathMarkD decayMark(TEvePathMarkD::kDecay);
1199 decayMark.fV.Set(
B2Vector3D(particle->getDecayVertex()));
1203 TString particle_name(mctrack.GetName());
1206 const MCParticle* mom = particle->getMother();
1213 if (!hasTrajectory) {
1216 title +=
"\n(track estimated from initial momentum)";
1262 MCTrack& mcTrack = mcTrackPair.second;
1263 if (mcTrack.
track) {
1264 if (mcTrack.
simhits->Size() > 0) {
1268 destroyEveElement(mcTrack.
simhits);
1275 parent = parentIt->second.track;
1278 parent->AddElement(mcTrack.
track);
1280 gEve->AddElement(mcTrack.
simhits);
1287 for (
size_t i = 0; i <
m_options.length(); i++) {
1294 m.SetMarkerStyle(1);
1326 if (groupPair.second.group)
1327 groupPair.second.visible = groupPair.second.group->GetRnrState();
1328 groupPair.second.group =
nullptr;
1340 float ecl_threshold = 0.01;
1342 ecl_threshold =
m_eclData->GetSliceThreshold(0);
1347 m_eclData->RefSliceInfo(0).Setup(
"ECL", ecl_threshold, kRed);
1353 gEve->GetSelection()->RemoveElements();
1354 gEve->GetHighlight()->RemoveElements();
1363 ROOT::Math::XYZVector v = ROOT::Math::XYZVector(vertex->getPos());
1368 vertexPoint->SetNextPoint(v.X(), v.Y(), v.Z());
1370 TMatrixDSymEigen eigen_values(vertex->getCov());
1372 det_shape->SetShape(
new TGeoSphere(0., 1.));
1373 fixGeoShapeRefCount(det_shape);
1374 const TVectorD& ev = eigen_values.GetEigenValues();
1375 const TMatrixD& eVec = eigen_values.GetEigenVectors();
1377 ROOT::Math::XYZVector eVec1(eVec(0, 0), eVec(1, 0), eVec(2, 0));
1379 ROOT::Math::XYZVector eVec2(eVec(0, 1), eVec(1, 1), eVec(2, 1));
1380 ROOT::Math::XYZVector eVec3(eVec(0, 2), eVec(1, 2), eVec(2, 2));
1384 TGeoRotation det_rot(
"det_rot", (eVec1.Theta() * 180) / TMath::Pi(), (eVec1.Phi() * 180) / TMath::Pi(),
1385 (eVec2.Theta() * 180) / TMath::Pi(), (eVec2.Phi() * 180) / TMath::Pi(),
1386 (eVec3.Theta() * 180) / TMath::Pi(), (eVec3.Phi() * 180) / TMath::Pi());
1390 double pseudo_res_0 = std::sqrt(ev(0));
1391 double pseudo_res_1 = std::sqrt(ev(1));
1392 double pseudo_res_2 = std::sqrt(ev(2));
1399 TGeoGenTrans det_trans(v.X(), v.Y(), v.Z(), pseudo_res_0, pseudo_res_1, pseudo_res_2,
1401 det_shape->SetTransMatrix(det_trans);
1404 det_shape->SetMainColor(kOrange);
1405 det_shape->SetMainTransparency(0);
1407 vertexPoint->AddElement(det_shape);
1419 const float phi = cluster->getPhi();
1420 float dPhi = cluster->getUncertaintyPhi();
1421 float dTheta = cluster->getUncertaintyTheta();
1422 if (dPhi >= M_PI / 4 or dTheta >= M_PI / 4 or cluster->getUncertaintyEnergy() == 1.0) {
1423 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:");
1424 cluster->getCovarianceMatrix3x3().Print();
1425 dPhi = dTheta = 0.05;
1428 if (!std::isfinite(dPhi) or !std::isfinite(dTheta)) {
1429 B2ERROR(
"ECLCluster phi or theta error is NaN or infinite, skipping cluster!");
1434 ROOT::Math::XYZVector thetaLow;
1435 VectorUtil::setPtThetaPhi(thetaLow, 1.0, cluster->getTheta() - dTheta, phi);
1436 ROOT::Math::XYZVector thetaHigh;
1437 VectorUtil::setPtThetaPhi(thetaHigh, 1.0, cluster->getTheta() + dTheta, phi);
1438 float etaLow = thetaLow.Eta();
1439 float etaHigh = thetaHigh.Eta();
1440 if (etaLow > etaHigh) {
1441 std::swap(etaLow, etaHigh);
1444 int id =
m_eclData->AddTower(etaLow, etaHigh, phi - dPhi, phi + dPhi);
1452 const double layerThicknessCm = 3.16;
1453 const double layerDistanceCm = 9.1 - layerThicknessCm;
1456 ROOT::Math::XYZVector position = cluster->getClusterPosition();
1457 ROOT::Math::XYZVector startPos(position.X(), position.Y(), position.Z());
1458 ROOT::Math::XYZVector dir;
1459 ROOT::Math::XYZVector a, b;
1460 bool isBarrel = (startPos.Z() > -175.0 and startPos.Z() < 270.0);
1463 b = ROOT::Math::XYZVector(0, 0, 1);
1464 a = startPos.Cross(b).Unit();
1465 double c = M_PI / 4.0;
1466 double offset = c / 2.0 + M_PI;
1467 VectorUtil::setPhi(a,
int((a.Phi() + offset) / (c))*c - M_PI);
1468 ROOT::Math::XYZVector perp = b.Cross(a);
1470 const double barrelRadiusCm = 204.0;
1471 VectorUtil::setMag(startPos, barrelRadiusCm / perp.Dot(startPos.Unit()));
1473 dir = startPos.Unit();
1474 VectorUtil::setMag(dir, (layerDistanceCm + layerThicknessCm) / perp.Dot(dir));
1477 b = ROOT::Math::XYZVector(startPos.X(), startPos.Y(), 0).Unit();
1478 a = startPos.Cross(b).Unit();
1479 double endcapStartZ = 284;
1480 if (startPos.Z() < 0)
1481 endcapStartZ = -189.5;
1483 double scaleFac = endcapStartZ / startPos.Z();
1484 VectorUtil::setMag(startPos, startPos.R() * scaleFac);
1486 dir = startPos.Unit();
1487 VectorUtil::setMag(dir, (layerDistanceCm + layerThicknessCm) / fabs(dir.Z()));
1490 for (
int i = 0; i < cluster->getLayers(); i++) {
1491 ROOT::Math::XYZVector layerPos = startPos;
1492 layerPos += (cluster->getInnermostLayer() + i) * dir;
1493 auto* layer =
boxCreator(layerPos, a, b, 20.0, 20.0, layerThicknessCm / 2);
1495 layer->SetMainTransparency(70);
1509 CLHEP::Hep3Vector global;
1516 CLHEP::Hep3Vector local =
module->globalToLocal(global);
1521 double du =
module->getPhiStripWidth() * Nphistrip;
1522 double dv =
module->getZStripWidth() * Nztrip;
1525 CLHEP::Hep3Vector localU(local[0], local[1] + 1.0, local[2]);
1526 CLHEP::Hep3Vector localV(local[0], local[1], local[2] + 1.0);
1528 CLHEP::Hep3Vector globalU =
module->localToGlobal(localU);
1529 CLHEP::Hep3Vector globalV =
module->localToGlobal(localV);
1531 ROOT::Math::XYZVector o(global[0], global[1], global[2]);
1532 ROOT::Math::XYZVector u(globalU[0], globalU[1], globalU[2]);
1533 ROOT::Math::XYZVector v(globalV[0], globalV[1], globalV[2]);
1536 TEveBox* bklmbox =
boxCreator(o, u - o, v - o, du, dv, 1.0);
1538 bklmbox->SetMainColor(kGreen);
1540 bklmbox->SetName(
"BKLMHit2d");
1548 const double du = 2.0;
1549 const double dv = 2.0;
1550 ROOT::Math::XYZVector hitPosition = eklm2dhit->
getPosition();
1551 ROOT::Math::XYZVector o(hitPosition.X(), hitPosition.Y(), hitPosition.Z());
1552 ROOT::Math::XYZVector u(1.0, 0.0, 0.0);
1553 ROOT::Math::XYZVector v(0.0, 1.0, 0.0);
1554 TEveBox* eklmbox =
boxCreator(o, u, v, du, dv, 4.0);
1555 eklmbox->SetMainColor(kGreen);
1556 eklmbox->SetName(
"EKLMHit2d");
1565 VxdID sensorID = roi->getSensorID();
1568 double minU = aSensorInfo.
getUCellPosition(roi->getMinUid(), roi->getMinVid());
1570 double maxU = aSensorInfo.
getUCellPosition(roi->getMaxUid(), roi->getMaxVid());
1574 ROOT::Math::XYZVector localA(minU, minV, 0);
1575 ROOT::Math::XYZVector localB(minU, maxV, 0);
1576 ROOT::Math::XYZVector localC(maxU, minV, 0);
1578 ROOT::Math::XYZVector globalA = aSensorInfo.
pointToGlobal(localA);
1579 ROOT::Math::XYZVector globalB = aSensorInfo.
pointToGlobal(localB);
1580 ROOT::Math::XYZVector globalC = aSensorInfo.
pointToGlobal(localC);
1582 TEveBox* ROIbox =
boxCreator(globalB + globalC * 0.5, globalB - globalA, globalC - globalA, 1, 1, 0.01);
1585 ROIbox->SetMainColor(kSpring - 9);
1586 ROIbox->SetMainTransparency(50);
1597 ROOT::Math::XYZVector a, b;
1600 a = sensor.pointToGlobal(ROOT::Math::XYZVector(sensor.getBackwardWidth() / sensor.getWidth(0) * u, -0.5 * sensor.getLength(), 0.0));
1601 b = sensor.pointToGlobal(ROOT::Math::XYZVector(sensor.getForwardWidth() / sensor.getWidth(0) * u, +0.5 * sensor.getLength(), 0.0));
1604 a = sensor.pointToGlobal(ROOT::Math::XYZVector(-0.5 * sensor.getWidth(v), v, 0.0));
1605 b = sensor.pointToGlobal(ROOT::Math::XYZVector(+0.5 * sensor.getWidth(v), v, 0.0));
1608 lines->AddLine(a.X(), a.Y(), a.Z(), b.X(), b.Y(), b.Z());
1618 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());
1629 TEveGeoShape* cov_shape =
new TEveGeoShape(
"cov_shape");
1633 driftLengthRes = std::max(driftLengthRes, 0.005);
1634 const double lengthOfWireSection = 3.0;
1637 const B2Vector3D zaxis = wire_pos_b - wire_pos_f;
1642 const B2Vector3D midPoint = wire_pos_f - zaxis * (wire_pos_f.
Z() / zaxis.
Z());
1644 cov_shape->SetShape(
new TGeoTube(std::max(0., (
double)(driftLength - driftLengthRes)), driftLength + driftLengthRes,
1645 lengthOfWireSection));
1646 fixGeoShapeRefCount(cov_shape);
1648 TGeoRotation det_rot(
"det_rot",
1649 xaxis.
Theta() * 180 / TMath::Pi(), xaxis.
Phi() * 180 / TMath::Pi(),
1650 yaxis.
Theta() * 180 / TMath::Pi(), yaxis.
Phi() * 180 / TMath::Pi(),
1651 zaxis.
Theta() * 180 / TMath::Pi(), zaxis.
Phi() * 180 / TMath::Pi()
1654 TGeoCombiTrans det_trans(midPoint.
X(), midPoint.
Y(), midPoint.
Z(), &det_rot);
1655 cov_shape->SetTransMatrix(det_trans);
1658 bool isPartOfTS =
false;
1660 if (showTriggerHits && segments.size() > 0) {
1666 cov_shape->SetMainColor(kCyan + 3);
1668 cov_shape->SetMainColor(kCyan);
1671 cov_shape->SetMainColor(kPink + 6);
1673 cov_shape->SetMainColor(kPink + 7);
1676 cov_shape->SetMainTransparency(50);
1678 cov_shape->SetTitle(
ObjectInfo::getInfo(hit) + TString::Format(
"\nWire ID: %d\nADC: %d\nTDC: %d",
1684 addToGroup(
"CDCTriggerSegmentHits", cov_shape);
1685 for (
auto rel : segments.relations()) {
1694 TEveStraightLineSet* shape =
new TEveStraightLineSet();
1700 unsigned iCenter = hit->
getIWire();
1712 std::vector<int> layershift = { -2, -1, 0, 1, 2};
1713 std::vector<std::vector<float>> cellshift = {
1728 layershift = { 0, 1, 2, 3, 4};
1733 { -1.5, -0.5, 0.5, 1.5},
1739 for (
unsigned il = 0; il < layershift.size(); ++il) {
1740 for (
unsigned ic = 0; ic < cellshift[il].size(); ++ic) {
1741 ROOT::Math::XYZVector corners[2][2];
1742 for (
unsigned ir = 0; ir < 2; ++ir) {
1743 double r = cdcgeo.
fieldWireR(iL + layershift[il] - ir);
1744 double fz = cdcgeo.
fieldWireFZ(iL + layershift[il] - ir);
1745 double bz = cdcgeo.
fieldWireBZ(iL + layershift[il] - ir);
1746 for (
unsigned iphi = 0; iphi < 2; ++iphi) {
1747 double phib = (iCenter + cellshift[il][ic] + iphi - 0.5) * 2 * M_PI / nWires;
1748 double phif = phib + cdcgeo.
nShifts(iL + layershift[il]) * M_PI / nWires;
1750 ROOT::Math::XYZVector pos_f = ROOT::Math::XYZVector(cos(phif) * r, sin(phif) * r, fz);
1751 ROOT::Math::XYZVector pos_b = ROOT::Math::XYZVector(cos(phib) * r, sin(phib) * r, bz);
1752 ROOT::Math::XYZVector zaxis = pos_b - pos_f;
1753 corners[ir][iphi] = pos_f - zaxis * (pos_f.Z() / zaxis.Z());
1757 shape->AddLine(corners[0][0].X(), corners[0][0].Y(), 0,
1758 corners[0][1].X(), corners[0][1].Y(), 0);
1759 shape->AddLine(corners[0][1].X(), corners[0][1].Y(), 0,
1760 corners[1][1].X(), corners[1][1].Y(), 0);
1761 shape->AddLine(corners[1][1].X(), corners[1][1].Y(), 0,
1762 corners[1][0].X(), corners[1][0].Y(), 0);
1763 shape->AddLine(corners[1][0].X(), corners[1][0].Y(), 0,
1764 corners[0][0].X(), corners[0][0].Y(), 0);
1769 shape->SetMainColor(kCyan + 3);
1771 shape->SetMainColor(kPink + 6);
1776 TString::Format(
"\nPriority: %d\nLeft/Right: %d",
1787 float fi = arichGeo->getDetectorPlane().getSlotPhi(hitModule);
1789 ROOT::Math::XYZVector centerPos3D = hit->
getPosition();
1791 ROOT::Math::RotationZ rotZ(fi);
1792 ROOT::Math::XYZVector channelX(1, 0, 0);
1793 ROOT::Math::XYZVector channelY(0, 1, 0);
1794 channelX = rotZ * channelX;
1795 channelY = rotZ * channelY;
1798 arichGeo->getMasterVolume().momentumToGlobal(channelX),
1799 arichGeo->getMasterVolume().momentumToGlobal(channelY),
1801 arichbox->SetMainColor(kOrange + 10);
1802 arichbox->SetName((std::to_string(hitModule)).c_str());
1811 std::map<int, int> m_topSummary;
1812 for (
const TOPDigit& hit : digits) {
1813 int mod = hit.getModuleID();
1814 ++m_topSummary[mod];
1817 for (
auto modCountPair : m_topSummary) {
1818 if (modCountPair.second > maxcount)
1819 maxcount = modCountPair.second;
1821 for (
auto modCountPair : m_topSummary) {
1823 double phi = topmod.getPhi();
1824 double r_center = topmod.getRadius();
1825 double z = topmod.getZc();
1827 ROOT::Math::XYZVector centerPos3D;
1828 VectorUtil::setMagThetaPhi(centerPos3D, r_center, M_PI / 2, phi);
1829 centerPos3D.SetZ(z);
1835 auto* moduleBox =
boxCreator(centerPos3D, channelX, channelY,
1836 3.0 * topmod.getBarThickness(), topmod.getBarWidth(), topmod.getBarLength());
1837 moduleBox->SetMainColor(kAzure + 10);
1838 double weight = double(modCountPair.second) / maxcount;
1839 moduleBox->SetMainTransparency(90 - weight * 50);
1840 moduleBox->SetName((
"TOP module " + std::to_string(modCountPair.first)).c_str());
1841 moduleBox->SetTitle(TString::Format(
"#TOPDigits: %d ", modCountPair.second));
1845 for (
const TOPDigit& hit : digits) {
1846 if (modCountPair.first == hit.getModuleID())
1855 for (
const auto& labelPair : displayData.
m_labels) {
1856 TEveText* text =
new TEveText(labelPair.first.c_str());
1857 text->SetName(labelPair.first.c_str());
1858 text->SetTitle(labelPair.first.c_str());
1859 text->SetMainColor(kGray + 1);
1860 const ROOT::Math::XYZVector& p = labelPair.second;
1861 text->PtrMainTrans()->SetPos(p.X(), p.Y(), p.Z());
1865 for (
const auto& pointPair : displayData.
m_pointSets) {
1866 TEvePointSet* points =
new TEvePointSet(pointPair.first.c_str());
1867 points->SetTitle(pointPair.first.c_str());
1868 points->SetMarkerStyle(7);
1869 points->SetMainColor(kGreen);
1870 for (
const auto& p : pointPair.second) {
1871 points->SetNextPoint(p.X(), p.Y(), p.Z());
1876 int randomColor = 2;
1877 for (
const auto& arrow : displayData.
m_arrows) {
1878 const ROOT::Math::XYZVector pos = arrow.start;
1879 const ROOT::Math::XYZVector dir = arrow.end - pos;
1880 TEveArrow* eveArrow =
new TEveArrow(dir.X(), dir.Y(), dir.Z(), pos.X(), pos.Y(), pos.Z());
1881 eveArrow->SetName(arrow.name.c_str());
1882 eveArrow->SetTitle(arrow.name.c_str());
1883 int arrowColor = arrow.color;
1884 if (arrowColor == -1) {
1885 arrowColor = randomColor;
1888 eveArrow->SetMainColor(arrowColor);
1891 TEveText* text =
new TEveText(arrow.name.c_str());
1892 text->SetMainColor(arrowColor);
1895 ROOT::Math::XYZVector orthogonalDir;
1896 if (std::abs(dir.X()) < std::abs(dir.Y())) {
1897 if (std::abs(dir.X()) < std::abs(dir.Z())) {
1898 orthogonalDir.SetCoordinates(0, dir.Z(), -dir.Y());
1900 orthogonalDir.SetCoordinates(dir.Y(), -dir.X(), 0);
1903 if (std::abs(dir.Y()) < std::abs(dir.Z())) {
1904 orthogonalDir.SetCoordinates(-dir.Z(), 0, dir.X());
1906 orthogonalDir.SetCoordinates(dir.Y(), -dir.X(), 0);
1909 const ROOT::Math::XYZVector& labelPos = pos + 0.5 * dir + 0.1 * orthogonalDir;
1910 text->PtrMainTrans()->SetPos(labelPos.X(), labelPos.Y(), labelPos.Z());
1911 eveArrow->AddElement(text);
1925 const std::string& groupName = boost::algorithm::trim_copy_if(name, boost::algorithm::is_any_of(
"/"));
1927 TEveElementList* group =
m_groups[groupName].group;
1929 group =
new TEveElementList(groupName.c_str(), groupName.c_str());
1930 group->SetRnrState(
m_groups[groupName].visible);
1935 auto lastSlash = boost::algorithm::find_last(groupName,
"/");
1937 const std::string parentGroup(groupName.begin(), lastSlash.begin());
1938 const std::string thisGroup(lastSlash.end(), groupName.end());
1939 group->SetElementName(thisGroup.c_str());
1942 gEve->AddElement(group);
1945 group->AddElement(elem);
Datastore class that holds photon hits. Input to the reconstruction.
int getModule() const
Get module ID.
ROOT::Math::XYZVector getPosition() const
Get photon hit position.
DataType Phi() const
The azimuth angle.
DataType Pz() const
access variable Z (= .at(2) without boundary check)
DataType Z() const
access variable Z (= .at(2) without boundary check)
DataType Theta() const
The polar angle.
B2Vector3< DataType > Cross(const B2Vector3< DataType > &p) const
Cross product.
DataType X() const
access variable X (= .at(0) without boundary check)
B2Vector3< DataType > Orthogonal() const
Vector orthogonal to this one.
DataType Y() const
access variable Y (= .at(1) without boundary check)
DataType Mag() const
The magnitude (rho in spherical coordinate system).
void RotateZ(DataType angle)
Rotates the B2Vector3 around the z-axis.
DataType Pt() const
The transverse component (R in cylindrical coordinate system).
Class containing the result of the unpacker in raw data and the result of the digitizer in simulation...
short getTDCCount() const
Getter for TDC count.
unsigned short getID() const
Getter for encoded wire number.
unsigned short getADCCount() const
Getter for integrated charge.
unsigned short getISuperLayer() const
Getter for iSuperLayer.
This class is used to transfer CDC information to the track fit.
B2Vector3D getPosWire() const
The method to get position on wire.
Combination of several CDCHits to a track segment hit for the trigger.
unsigned short getPriorityPosition() const
get position of the priority cell within the track segment (0: no hit, 3: 1st priority,...
unsigned short getIWire() const
get wire number of priority wire within layer.
unsigned short getID() const
get the encoded wire number of the priority wire.
unsigned short getISuperLayer() const
get super layer number.
unsigned short getLeftRight() const
get position of the priority cell relative to the track (0: no hit, 1: right, 2: left,...
Track created by the CDC trigger.
The Class for CDC Geometry Parameters.
int nShifts(int layerId) const
Returns number shift.
double fieldWireR(int layerId) const
Returns radius of field wire in each layer.
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.
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.
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.
static const ChargedStable pion
charged pion particle
Class for accessing objects in the database.
Add custom information to the display.
std::vector< Arrow > m_arrows
List of arrows.
std::map< std::string, std::vector< ROOT::Math::XYZVector > > m_pointSets
name -> points map
std::vector< std::pair< std::string, ROOT::Math::XYZVector > > m_labels
text labels (to be shown at a given position).
@ c_nPhotons
CR is split into n photons (N1)
void clearEvent()
clear event data.
void setOptions(const std::string &opts)
Set the display options.
static constexpr double c_minPCut
don't show MCParticles with momentum below this cutoff.
void addTrackCandidateImproved(const std::string &collectionName, const RecoTrack &recoTrack)
Add a RecoTrack, but use stored genfit track representation to make visualisation objects.
EveVisBField * m_bfield
The global magnetic field.
static 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...
TEveStraightLineSet * m_unassignedRecoHits
Unassigned recohits.
static const int c_recoHitColor
Color for reco hits.
void addCDCHit(const CDCHit *hit, bool showTriggerHits=false)
show CDCHits directly.
std::map< const MCParticle *, MCTrack > m_mcparticleTracks
map MCParticles to MCTrack (so hits can be added to the correct track).
void addBKLMHit2d(const KLMHit2d *bklm2dhit)
Add a reconstructed 2d hit in the BKLM.
EVEVisualization()
Constructor.
void setErrScale(double errScale=1.)
Set the scaling factor for the visualization of track hit errors.
bool m_drawRefTrack
Draw reference track in addTrack.
void addVertex(const genfit::GFRaveVertex *vertex)
Add a vertex point and its covariance matrix.
bool m_drawForward
draw forward in addTrack
TEveCalo3D * m_calo3d
Object for the energy bar visualisation.
bool m_drawCardinalRep
Draw cardinal representation in addTrack.
void addCDCTriggerSegmentHit(const std::string &collectionName, const CDCTriggerSegmentHit *hit)
show outline of track segments.
TEveTrackPropagator * m_trackpropagator
Track propagator for MCParticles.
std::map< std::string, ElementGroup > m_groups
name -> grouping element.
void addSimHit(const CDCSimHit *hit, const MCParticle *particle)
Add a CDCSimHit.
void addECLCluster(const ECLCluster *cluster)
Add a reconstructed cluster in the ECL.
TEveTrackList * m_tracklist
parent object for MC tracks.
void addToGroup(const std::string &name, TEveElement *elem)
Add 'elem' to the element group 'name' (created if necessary).
void makeTracks()
Create visual representation of all tracks.
void addRecoHit(const SomeVXDHit *hit, TEveStraightLineSet *lines)
adds given VXD hit to lines.
void addTrack(const Belle2::Track *belle2Track)
Add this genfit::Track to event data.
bool m_unassignedRecoHitsVisibility
is m_unassignedRecoHits visible?
static const int c_trackMarkerColor
Color for track markers.
TEveTrackPropagator * m_gftrackpropagator
Track propagator for genfit::Tracks (different mainly because of drawing options)
std::string m_options
Option string for genfit::Track visualisation.
static const int c_trackColor
Color for tracks.
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.
void addEKLMHit2d(const KLMHit2d *eklm2dhit)
Add a reconstructed 2d hit in the EKLM.
void addARICHHit(const ARICHHit *hit)
Add reconstructed hit in ARICH.
void addCDCTriggerTrack(const std::string &collectionName, const TriggerTrack &trgTrack)
Add a CDCTriggerTrack or CDCTrigger3DHTrack.
void showUserData(const DisplayData &displayData)
Add user-defined data (labels, points, etc.)
std::set< const TObject * > m_shownRecohits
List of shown recohits (PXDCluster, SVDCluster, CDCHit).
bool m_drawBackward
draw backward in addTrack
TEveTrackPropagator * m_consttrackpropagator
Track propagator for CDCTriggerTracks (uses constant B field)
bool m_assignToPrimaries
If true, hits created by secondary particles (e.g.
~EVEVisualization()
Destructor.
bool m_drawErrors
Draw errors in addTrack.
double m_errorScale
Rescale PXD/SVD errors with this factor to ensure visibility.
void addTOPDigits(const StoreArray< TOPDigit > &digits)
Add TOPDigits (shown aggregated per module).
void addROI(const ROIid *roi)
Add a Region Of Interest, computed by the PXDDataReduction module.
void addKLMCluster(const KLMCluster *cluster)
Add a reconstructed cluster in the KLM.
static const int c_klmClusterColor
Color for KLMCluster objects.
MCTrack * addMCParticle(const MCParticle *particle)
Return MCTrack for given particle, add it if it doesn't exist yet.
TEveCaloDataVec * m_eclData
ECL cluster data.
static const int c_recoTrackColor
Color for TrackCandidates.
void addTrackCandidate(const std::string &collectionName, const RecoTrack &recoTrack)
Add a RecoTrack, to evaluate track finding.
static void addObject(const TObject *dataStoreObject, TEveElement *visualRepresentation)
Generic function to keep track of which objects have which visual representation.
static 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'.
Provide magnetic field values for TEveTrackPropagator.
int getLayer() const
Get layer number.
int getZStripMax() const
Get last strip number for z plane.
int getSection() const
Get section number.
float getPositionZ() const
Get hit global position z coordinate.
int getSector() const
Get sector number.
float getPositionX() const
Get hit global position x coordinate.
int getPhiStripMin() const
Get strip number for phi plane.
int getZStripMin() const
Get strip number for z plane.
ROOT::Math::XYZVector getPosition() const
Get hit global position.
int getPhiStripMax() const
Get last strip number for phi plane.
float getPositionY() const
Get hit global position y coordinate.
ROOT::Math::XYZVector getPosition() const
Get hit global position.
Class to save the full simulated trajectory of a particle.
const MCTrajectoryPoint & back() const
return reference to the last point
A Class to store the Monte Carlo particle information.
@ c_PrimaryParticle
bit 0: Particle is primary particle.
@ c_StoppedInDetector
bit 3: Particle was stopped in the detector (the simulation volume).
Class PXDSimHit - Geant4 simulated hit for the PXD.
ROIid stores the U and V ids and the sensor id of the Region Of Interest.
This is the Reconstruction Event-Data Model Track.
std::vector< Belle2::RecoTrack::UsedPXDHit * > getPXDHitList() const
Return an unsorted list of pxd hits.
std::vector< Belle2::RecoTrack::UsedSVDHit * > getSVDHitList() const
Return an unsorted list of svd hits.
std::vector< Belle2::RecoTrack::UsedCDCHit * > getCDCHitList() const
Return an unsorted list of cdc hits.
ROOT::Math::XYZVector getPositionSeed() const
Return the position seed stored in the reco track. ATTENTION: This is not the fitted position.
const genfit::TrackPoint * getCreatedTrackPoint(const RecoHitInformation *recoHitInformation) const
Get a pointer to the TrackPoint that was created from this hit.
std::vector< RecoHitInformation * > getRecoHitInformations(bool getSorted=false) const
Return a list of all RecoHitInformations associated with the RecoTrack.
short int getChargeSeed() const
Return the charge seed stored in the reco track. ATTENTION: This is not the fitted charge.
ROOT::Math::XYZVector getMomentumSeed() const
Return the momentum seed stored in the reco track. ATTENTION: This is not the fitted momentum.
RelationVector< FROM > getRelationsFrom(const std::string &name="", const std::string &namedRelation="") const
Get the relations that point from another store array to this object.
T * getRelated(const std::string &name="", const std::string &namedRelation="") const
Get the object to or from which this object has a relation.
The SVD Cluster class This class stores all information about reconstructed SVD clusters.
VxdID getSensorID() const
Get the sensor ID.
bool isUCluster() const
Get the direction of strips.
float getPosition(double v=0) const
Get the coordinate of reconstructed hit.
SVDRecoHit - an extended form of SVDHit containing geometry information.
bool isU() const
Is the coordinate u or v?
VxdID getSensorID() const
Get the compact ID.
Class SVDSimHit - Geant4 simulated hit for the SVD.
Accessor to arrays stored in the data store.
Class to store TOP digitized hits (output of TOPDigitizer or raw data unpacker) relations to TOPSimHi...
const TOPGeometry * getGeometry() const
Returns pointer to geometry object using basf2 units.
static TOPGeometryPar * Instance()
Static method to obtain the pointer to its instance.
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.
Class that bundles various TrackFitResults.
const TrackFitResult * getTrackFitResultWithClosestMass(const Const::ChargedStable &requestedType) const
Return the track fit for the fit hypothesis with the closest mass.
ROOT::Math::XYZVector getPosIn() const
Return the start point of the electron deposition in local coordinates.
VxdID getSensorID() const
Return the sensorID of the sensor the electron was deposited in.
Class to facilitate easy access to sensor information of the VXD like coordinate transformations or p...
const SensorInfoBase & getSensorInfo(Belle2::VxdID id) const
Return a reference to the SensorInfo of a given SensorID.
static GeoCache & getInstance()
Return a reference to the singleton instance.
Base class to provide Sensor Information for PXD and SVD.
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.
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.
void clear()
Remove all contents in map.
void add(const TObject *dataStoreObject, TEveElement *visualRepresentation)
Generic function to keep track of which objects have which visual representation.
Class to uniquely identify a any structure of the PXD and SVD.
Class to identify a wire inside the CDC.
unsigned short getICLayer() const
Getter for continuous layer numbering.
Provides BKLM geometry parameters for simulation, reconstruction etc (from Gearbox or DataBase)
const Module * findModule(int section, int sector, int layer) const
Get the pointer to the definition of a module.
static GeometryPar * instance(void)
Static method to get a reference to the singleton GeometryPar instance.
Define the geometry of a BKLM module Each sector [octant] contains Modules.
static constexpr auto XYZToTVector
Helper function to convert XYZVector to TVector3.
B2Vector3< double > B2Vector3D
typedef for common usage with double
double sqrt(double a)
sqrt for double
double eval(const std::vector< double > &spl, const std::vector< double > &vals, double x)
Evaluate spline (zero order or first order) in point x.
const TOPGeoModule & getModule(int moduleID) const
Returns module.
double getMaxR()
find a point that is inside the top node.
TString getIdentifier(const TObject *obj)
Where is this object in the datastore?
TString getInfo(const TObject *obj)
Get object info HTML (e.g.
TString getTitle(const TObject *obj)
Get plain text for TEve object titles (shown on mouse-over).
Implements a colour palette, see http://sobac.com/sobac/tangocolors.htm.
int getTColorID(const std::string &tangoName, int tangoId=1)
Get TColor ID for given name in tango colour palette.
Abstract base class for different kinds of events.
Hold MC tracks and associated visualisation objects.
TEvePointSet * simhits
simhit positions.
const MCParticle * parentParticle
parent particle, or nullptr.
TEveTrack * track
the actual MC track.
Small struct to encode a position/momentum without additional overhead.