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/math/special_functions/fpclassify.hpp>
88#include <boost/scoped_ptr.hpp>
89#include <boost/algorithm/string/find.hpp>
90#include <boost/algorithm/string/trim.hpp>
91#include <boost/algorithm/string/classification.hpp>
101 template <
class T>
void destroyEveElement(T*& el)
104 if (el->GetDenyDestroy() > 1)
105 B2WARNING(
"destroyEveElement(): Element " << el->GetName() <<
" has unexpected refcount " << el->GetDenyDestroy());
107 el->DecDenyDestroy();
117 void fixGeoShapeRefCount(TEveGeoShape* eveshape)
119 TGeoShape* s = eveshape->GetShape();
121 if (gGeoManager->GetListOfShapes()->Last() == s)
122 gGeoManager->GetListOfShapes()->RemoveAt(gGeoManager->GetListOfShapes()->GetLast());
124 gGeoManager->GetListOfShapes()->Remove(s);
136 m_assignToPrimaries(false),
142 TGLLogicalShape::SetIgnoreSizeForCameraInterest(kTRUE);
168 m_calo3d =
new TEveCalo3D(NULL,
"ECLClusters");
170 m_calo3d->SetForwardEndCapPos(196.5);
171 m_calo3d->SetBackwardEndCapPos(-102.0);
173 m_calo3d->SetRnrFrame(
false,
false);
177 gEve->GetSelection()->IncDenyDestroy();
178 gEve->GetHighlight()->IncDenyDestroy();
208 bool drawHits =
false;
211 for (
size_t i = 0; i <
m_options.length(); i++) {
212 if (
m_options.at(i) ==
'H') drawHits =
true;
222 TEveStraightLineSet* lines =
new TEveStraightLineSet(
"RecoHits for " + label);
225 lines->SetMarkerStyle(6);
226 lines->SetMainTransparency(60);
243 TEveRecTrack rectrack;
244 rectrack.fP.Set(track_mom);
245 rectrack.fV.Set(track_pos);
248 track_lines->SetName(label);
251 track_lines->SetLineWidth(1);
257 track_lines->AddElement(lines);
267 bool drawHits =
false;
270 for (
size_t i = 0; i <
m_options.length(); i++) {
271 if (
m_options.at(i) ==
'H') drawHits =
true;
278 TEveLine* track =
new TEveLine();
279 std::vector<ROOT::Math::XYZVector> posPoints;
280 track->SetName(label);
282 track->SetLineWidth(3);
284 track->SetSmooth(
true);
288 if (!recoHit->useInFit())
298 const auto* fittedResult = trackPoint->getFitterInfo();
299 if (not fittedResult) {
300 B2WARNING(
"Skipping unfitted track point");
303 const genfit::MeasuredStateOnPlane& state = fittedResult->getFittedState();
304 state.getPosMomCov(pos, mom, cov);
305 }
catch (
const genfit::Exception&) {
306 B2WARNING(
"Skipping state with strange pos, mom or cov");
310 posPoints.push_back(ROOT::Math::XYZVector(pos.X(), pos.Y(), pos.Z()));
313 sort(posPoints.begin(), posPoints.end(),
314 [](
const ROOT::Math::XYZVector & a,
const ROOT::Math::XYZVector & b) ->
bool {
315 return a.X() * a.X() + a.Y() * a.Y() > b.X() * b.X() + b.Y() * b.Y();
317 for (
auto vec : posPoints) {
318 track->SetNextPoint(vec.X(), vec.Y(), vec.Z());
321 TEveStraightLineSet* lines =
new TEveStraightLineSet(
"RecoHits for " + label);
324 lines->SetMarkerStyle(6);
325 lines->SetMainTransparency(60);
342 track->AddElement(lines);
353 B2Vector3D track_mom = (trgTrack.getChargeSign() == 0) ?
354 trgTrack.getDirection() * 1000 :
355 trgTrack.getMomentum(1.5);
357 TEveRecTrack rectrack;
358 rectrack.fP.Set(track_mom);
359 rectrack.fV.Set(track_pos);
362 track_lines->SetName(label);
364 track_lines->SetLineColor(kOrange + 2);
365 track_lines->SetLineWidth(1);
367 TString::Format(
"\ncharge: %d, phi: %.2fdeg, pt: %.2fGeV, theta: %.2fdeg, z: %.2fcm",
368 trgTrack.getChargeSign(),
369 trgTrack.getPhi0() * 180 / M_PI,
370 trgTrack.getTransverseMomentum(1.5),
371 trgTrack.getDirection().Theta() * 180 / M_PI,
375 track_lines->SetCharge(trgTrack.getChargeSign());
378 if (trgTrack.getZ0() == 0 && trgTrack.getCotTheta() == 0)
379 track_lines->SetLineStyle(2);
391 B2ERROR(
"Track without TrackFitResult skipped.");
399 bool drawDetectors =
false;
400 bool drawHits =
false;
401 bool drawPlanes =
false;
404 for (
size_t i = 0; i <
m_options.length(); i++) {
405 if (
m_options.at(i) ==
'D') drawDetectors =
true;
406 if (
m_options.at(i) ==
'H') drawHits =
true;
407 if (
m_options.at(i) ==
'P') drawPlanes =
true;
415 bool isPruned = (track ==
nullptr);
418 TEveRecTrackD recTrack;
420 recTrack.fV.Set(poca);
423 if (std::isfinite(poca_momentum.
Mag()))
424 recTrack.fP.Set(poca_momentum);
430 eveTrack->SetName(label);
434 const genfit::AbsTrackRep* representation;
437 representation = track->getCardinalRepresentation();
438 B2DEBUG(100,
"Draw cardinal rep");
440 const auto& representations = track->getRepresentations();
441 if (representations.empty()) {
442 B2ERROR(
"No representations found in the reco track!");
445 B2DEBUG(100,
"Draw representation number 0.");
446 representation = representations.front();
449 if (!track->hasTrackFitStatus(representation)) {
450 B2ERROR(
"RecoTrack without FitStatus: will be skipped!");
454 const genfit::FitStatus* fitStatus = track->getTrackFitStatus(representation);
456 isPruned = fitStatus->isTrackPruned();
460 genfit::KalmanFitterInfo* fi = 0;
461 genfit::KalmanFitterInfo* prevFi = 0;
462 genfit::GblFitterInfo* gfi = 0;
463 genfit::GblFitterInfo* prevGFi = 0;
464 const genfit::MeasuredStateOnPlane* fittedState(NULL);
465 const genfit::MeasuredStateOnPlane* prevFittedState(NULL);
468 const auto& hitPoints = track->getHitPointsWithMeasurement();
469 const unsigned int numpoints = hitPoints.size();
472 for (genfit::TrackPoint* tp : hitPoints) {
476 if (! tp->hasFitterInfo(representation)) {
477 B2ERROR(
"trackPoint has no fitterInfo for rep");
481 genfit::AbsFitterInfo* fitterInfo = tp->getFitterInfo(representation);
483 fi =
dynamic_cast<genfit::KalmanFitterInfo*
>(fitterInfo);
484 gfi =
dynamic_cast<genfit::GblFitterInfo*
>(fitterInfo);
487 B2ERROR(
"Can only display KalmanFitterInfo or GblFitterInfo");
492 B2FATAL(
"AbsFitterInfo dynamic-casted to both KalmanFitterInfo and GblFitterInfo!");
495 if (fi && ! tp->hasRawMeasurements()) {
496 B2ERROR(
"trackPoint has no raw measurements");
500 if (fi && ! fi->hasPredictionsAndUpdates()) {
501 B2ERROR(
"KalmanFitterInfo does not have all predictions and updates");
507 fittedState = &(gfi->getFittedState(
true));
509 fittedState = &(fi->getFittedState(
true));
510 }
catch (genfit::Exception& e) {
511 B2ERROR(e.what() <<
" - can not get fitted state");
515 ROOT::Math::XYZVector track_pos = ROOT::Math::XYZVector(representation->getPos(*fittedState));
518 if (prevFittedState != NULL) {
520 TEvePathMark::EType_e markType = TEvePathMark::kReference;
521 if (hitCounter + 1 ==
static_cast<int>(numpoints))
522 markType = TEvePathMark::kDecay;
533 makeLines(eveTrack, prevFi->getForwardUpdate(), fi->getForwardPrediction(), representation, markType,
m_drawErrors, 0);
535 makeLines(eveTrack, prevFi->getBackwardPrediction(), fi->getBackwardUpdate(), representation, markType,
m_drawErrors);
537 if (
m_drawRefTrack && fi->hasReferenceState() && prevFi->hasReferenceState())
538 makeLines(eveTrack, prevFi->getReferenceState(), fi->getReferenceState(), representation, markType,
false);
542 if (gfi && prevGFi) {
548 if (
m_drawRefTrack && gfi->hasReferenceState() && prevGFi->hasReferenceState()) {
549 genfit::StateOnPlane prevSop = prevGFi->getReferenceState();
550 genfit::StateOnPlane sop = gfi->getReferenceState();
551 makeLines(eveTrack, &prevSop, &sop, representation, markType,
false);
558 prevFittedState = fittedState;
562 const int numMeasurements = tp->getNumRawMeasurements();
563 for (
int iMeasurement = 0; iMeasurement < numMeasurements; iMeasurement++) {
564 const genfit::AbsMeasurement* m = tp->getRawMeasurement(iMeasurement);
566 TVectorT<double> hit_coords;
567 TMatrixTSym<double> hit_cov;
571 genfit::MeasurementOnPlane* mop = fi->getMeasurementOnPlane(iMeasurement);
572 hit_coords.ResizeTo(mop->getState());
573 hit_cov.ResizeTo(mop->getCov());
574 hit_coords = mop->getState();
575 hit_cov = mop->getCov();
581 genfit::MeasurementOnPlane gblMeas = gfi->getMeasurement();
582 hit_coords.ResizeTo(gblMeas.getState());
583 hit_cov.ResizeTo(gblMeas.getCov());
584 hit_coords = gblMeas.getState();
585 hit_cov = gblMeas.getCov();
591 ROOT::Math::XYZVector o = ROOT::Math::XYZVector(fittedState->getPlane()->getO());
592 ROOT::Math::XYZVector u = ROOT::Math::XYZVector(fittedState->getPlane()->getU());
593 ROOT::Math::XYZVector v = ROOT::Math::XYZVector(fittedState->getPlane()->getV());
595 bool planar_hit =
false;
596 bool planar_pixel_hit =
false;
597 bool space_hit =
false;
598 bool wire_hit =
false;
599 bool wirepoint_hit =
false;
602 double_t plane_size = 4;
604 int hit_coords_dim = m->getDim();
606 if (
dynamic_cast<const genfit::PlanarMeasurement*
>(m) != NULL) {
608 if (hit_coords_dim == 1) {
609 hit_u = hit_coords(0);
610 }
else if (hit_coords_dim == 2) {
611 planar_pixel_hit =
true;
612 hit_u = hit_coords(0);
613 hit_v = hit_coords(1);
615 }
else if (
dynamic_cast<const genfit::SpacepointMeasurement*
>(m) != NULL) {
618 ||
dynamic_cast<const genfit::WireMeasurement*
>(m)
619 ||
dynamic_cast<const genfit::WireMeasurementNew*
>(m)) {
621 hit_u = fabs(hit_coords(0));
622 hit_v = v.Dot(track_pos - o);
623 if (
dynamic_cast<const genfit::WirePointMeasurement*
>(m) != NULL) {
624 wirepoint_hit =
true;
625 hit_v = hit_coords(1);
628 B2ERROR(
"Hit " << hitCounter <<
", Measurement " << iMeasurement <<
": Unknown measurement type: skipping hit!");
635 if (drawPlanes || (drawDetectors && planar_hit)) {
636 ROOT::Math::XYZVector move(0, 0, 0);
637 if (wire_hit) move = v * (v.Dot(track_pos - o));
638 TEveBox* box =
boxCreator(o + move, u, v, plane_size, plane_size, 0.01);
639 if (drawDetectors && planar_hit) {
640 box->SetMainColor(kCyan);
642 box->SetMainColor(kGray);
644 box->SetMainTransparency(50);
645 eveTrack->AddElement(box);
653 TEveGeoShape* det_shape =
new TEveGeoShape(
"det_shape");
654 det_shape->SetShape(
new TGeoTube(std::max(0., (
double)(hit_u - 0.0105 / 2.)), hit_u + 0.0105 / 2., plane_size));
655 fixGeoShapeRefCount(det_shape);
657 ROOT::Math::XYZVector norm = u.Cross(v);
658 TGeoRotation det_rot(
"det_rot", (u.Theta() * 180) / TMath::Pi(), (u.Phi() * 180) / TMath::Pi(),
659 (norm.Theta() * 180) / TMath::Pi(), (norm.Phi() * 180) / TMath::Pi(),
660 (v.Theta() * 180) / TMath::Pi(), (v.Phi() * 180) / TMath::Pi());
661 ROOT::Math::XYZVector move = v * (v.Dot(track_pos - o));
662 TGeoCombiTrans det_trans(o.X() + move.X(),
666 det_shape->SetTransMatrix(det_trans);
667 det_shape->SetMainColor(kCyan);
668 det_shape->SetMainTransparency(25);
669 if ((drawHits && (hit_u + 0.0105 / 2 > 0)) || !drawHits) {
670 eveTrack->AddElement(det_shape);
681 if (!planar_pixel_hit) {
686 B2WARNING(
"SVD recohit couldn't be converted... ");
692 ROOT::Math::XYZVector a = o;
693 double hit_res_u = hit_cov(0, 0);
694 if (recoHit->
isU()) {
695 du = std::sqrt(hit_res_u);
696 dv = sensor.getLength();
699 du = sensor.getWidth();
700 dv = std::sqrt(hit_res_u);
703 double depth = sensor.getThickness();
704 TEveBox* hit_box =
boxCreator(a, u, v, du, dv, depth);
705 hit_box->SetName(
"SVDRecoHit");
707 hit_box->SetMainTransparency(0);
708 eveTrack->AddElement(hit_box);
712 TMatrixDSymEigen eigen_values(hit_cov);
713 TEveGeoShape* cov_shape =
new TEveGeoShape(
"PXDRecoHit");
714 const TVectorD& ev = eigen_values.GetEigenValues();
715 const TMatrixD& eVec = eigen_values.GetEigenVectors();
721 cov_shape->SetShape(
new TGeoEltu(pseudo_res_0, pseudo_res_1, 0.0105));
722 fixGeoShapeRefCount(cov_shape);
723 ROOT::Math::XYZVector pix_pos = o + hit_u * u + hit_v * v;
724 ROOT::Math::XYZVector u_semiaxis = (pix_pos + eVec(0, 0) * u + eVec(1, 0) * v) - pix_pos;
725 ROOT::Math::XYZVector v_semiaxis = (pix_pos + eVec(0, 1) * u + eVec(1, 1) * v) - pix_pos;
726 ROOT::Math::XYZVector norm = u.Cross(v);
730 TGeoRotation det_rot(
"det_rot", (u_semiaxis.Theta() * 180) / TMath::Pi(), (u_semiaxis.Phi() * 180) / TMath::Pi(),
731 (v_semiaxis.Theta() * 180) / TMath::Pi(), (v_semiaxis.Phi() * 180) / TMath::Pi(),
732 (norm.Theta() * 180) / TMath::Pi(), (norm.Phi() * 180) / TMath::Pi());
733 TGeoCombiTrans det_trans(pix_pos.X(), pix_pos.Y(), pix_pos.Z(), &det_rot);
734 cov_shape->SetTransMatrix(det_trans);
738 cov_shape->SetMainTransparency(0);
739 eveTrack->AddElement(cov_shape);
748 TMatrixDSymEigen eigen_values(m->getRawHitCov());
749 TEveGeoShape* cov_shape =
new TEveGeoShape(
"SpacePoint Hit");
750 cov_shape->SetShape(
new TGeoSphere(0., 1.));
751 fixGeoShapeRefCount(cov_shape);
752 const TVectorD& ev = eigen_values.GetEigenValues();
753 const TMatrixD& eVec = eigen_values.GetEigenVectors();
754 ROOT::Math::XYZVector eVec1(eVec(0, 0), eVec(1, 0), eVec(2, 0));
755 ROOT::Math::XYZVector eVec2(eVec(0, 1), eVec(1, 1), eVec(2, 1));
756 ROOT::Math::XYZVector eVec3(eVec(0, 2), eVec(1, 2), eVec(2, 2));
760 TGeoRotation det_rot(
"det_rot", (eVec1.Theta() * 180) / TMath::Pi(), (eVec1.Phi() * 180) / TMath::Pi(),
761 (eVec2.Theta() * 180) / TMath::Pi(), (eVec2.Phi() * 180) / TMath::Pi(),
762 (eVec3.Theta() * 180) / TMath::Pi(), (eVec3.Phi() * 180) / TMath::Pi());
771 TGeoGenTrans det_trans(o.X(), o.Y(), o.Z(),
774 pseudo_res_0, pseudo_res_1, pseudo_res_2,
776 cov_shape->SetTransMatrix(det_trans);
780 cov_shape->SetMainTransparency(10);
781 eveTrack->AddElement(cov_shape);
787 const double cdcErrorScale = 1.0;
788 TEveGeoShape* cov_shape =
new TEveGeoShape(
"CDCRecoHit");
789 double pseudo_res_0 = cdcErrorScale * std::sqrt(hit_cov(0, 0));
790 double pseudo_res_1 = plane_size;
791 if (wirepoint_hit) pseudo_res_1 = cdcErrorScale * std::sqrt(hit_cov(1, 1));
793 cov_shape->SetShape(
new TGeoTube(std::max(0., (
double)(hit_u - pseudo_res_0)), hit_u + pseudo_res_0, pseudo_res_1));
794 fixGeoShapeRefCount(cov_shape);
795 ROOT::Math::XYZVector norm = u.Cross(v);
798 TGeoRotation det_rot(
"det_rot", (u.Theta() * 180) / TMath::Pi(), (u.Phi() * 180) / TMath::Pi(),
799 (norm.Theta() * 180) / TMath::Pi(), (norm.Phi() * 180) / TMath::Pi(),
800 (v.Theta() * 180) / TMath::Pi(), (v.Phi() * 180) / TMath::Pi());
801 TGeoCombiTrans det_trans(o.X() + hit_v * v.X(),
802 o.Y() + hit_v * v.Y(),
803 o.Z() + hit_v * v.Z(),
805 cov_shape->SetTransMatrix(det_trans);
809 cov_shape->SetMainTransparency(50);
810 eveTrack->AddElement(cov_shape);
818 auto& firstref = eveTrack->RefPathMarks().front();
819 auto& lastref = eveTrack->RefPathMarks().back();
820 double f = firstref.fV.Distance(recTrack.fV);
821 double b = lastref.fV.Distance(recTrack.fV);
822 if (f > 100 and f > b) {
823 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)");
825 lastref.fType = TEvePathMarkD::kReference;
826 firstref.fType = TEvePathMarkD::kDecay;
827 std::reverse(eveTrack->RefPathMarks().begin(), eveTrack->RefPathMarks().end());
830 eveTrack->SetTitle(TString::Format(
"%s\n"
835 isPruned ?
" yes" :
"no",
836 poca_momentum.
Pt(), poca_momentum.
Pz(),
840 eveTrack->SetLineStyle(1);
841 eveTrack->SetLineWidth(3.0);
851 float vd,
float depth)
862 TEveBox* box =
new TEveBox;
863 box->SetPickable(
true);
865 ROOT::Math::XYZVector norm = u.Cross(v);
868 norm *= (0.5 * depth);
871 for (
int k = 0; k < 8; ++k) {
874 int signU = ((k + 1) & 2) ? -1 : 1;
875 int signV = (k & 4) ? -1 : 1;
876 int signN = (k & 2) ? -1 : 1;
881 vertex[0] = o.X() + signU * u.X() + signV * v.X() + signN * norm.X();
882 vertex[1] = o.Y() + signU * u.Y() + signV * v.Y() + signN * norm.Y();
883 vertex[2] = o.Z() + signU * u.Z() + signV * v.Z() + signN * norm.Z();
884 box->SetVertex(k, vertex);
891 const genfit::AbsTrackRep* rep,
892 TEvePathMark::EType_e markType,
bool drawErrors,
int markerPos)
894 using namespace genfit;
897 TVector3 pos, dir, oldPos, oldDir;
898 rep->getPosDir(*state, pos, dir);
899 rep->getPosDir(*prevState, oldPos, oldDir);
901 double distA = (pos - oldPos).Mag();
902 double distB = distA;
903 if ((pos - oldPos)*oldDir < 0)
905 if ((pos - oldPos)*dir < 0)
910 TEveVector(pos.X(), pos.Y(), pos.Z()),
911 TEveVector(dir.X(), dir.Y(), dir.Z())
913 eveTrack->AddPathMark(mark);
917 const MeasuredStateOnPlane* measuredState;
919 measuredState =
dynamic_cast<const MeasuredStateOnPlane*
>(prevState);
921 measuredState =
dynamic_cast<const MeasuredStateOnPlane*
>(state);
923 if (measuredState != NULL) {
926 ROOT::Math::XYZVector
eval;
928 eval = 0.2 * distA * oldDir;
930 eval = -0.2 * distB * dir;
936 TVector3 position, direction;
937 rep->getPosMomCov(*measuredState, position, direction, cov);
940 TMatrixDSymEigen eigen_values(cov.GetSub(0, 2, 0, 2));
941 const TVectorD& ev = eigen_values.GetEigenValues();
942 const TMatrixD& eVec = eigen_values.GetEigenVectors();
943 ROOT::Math::XYZVector eVec1, eVec2;
945 static const double maxErr = 1000.;
946 double ev0 = std::min(ev(0), maxErr);
947 double ev1 = std::min(ev(1), maxErr);
948 double ev2 = std::min(ev(2), maxErr);
951 if (ev0 < ev1 && ev0 < ev2) {
952 eVec1.SetXYZ(eVec(0, 1), eVec(1, 1), eVec(2, 1));
954 eVec2.SetXYZ(eVec(0, 2), eVec(1, 2), eVec(2, 2));
956 }
else if (ev1 < ev0 && ev1 < ev2) {
957 eVec1.SetXYZ(eVec(0, 0), eVec(1, 0), eVec(2, 0));
959 eVec2.SetXYZ(eVec(0, 2), eVec(1, 2), eVec(2, 2));
962 eVec1.SetXYZ(eVec(0, 0), eVec(1, 0), eVec(2, 0));
964 eVec2.SetXYZ(eVec(0, 1), eVec(1, 1), eVec(2, 1));
968 if (eVec1.Cross(eVec2).Dot(
eval) < 0)
972 ROOT::Math::XYZVector oldEVec1(eVec1);
974 const int nEdges = 24;
975 std::vector<ROOT::Math::XYZVector> vertices;
977 vertices.push_back(ROOT::Math::XYZVector(position));
980 for (
int i = 0; i < nEdges; ++i) {
981 const double angle = 2 * TMath::Pi() / nEdges * i;
982 vertices.push_back(ROOT::Math::XYZVector(position) + cos(angle)*eVec1 + sin(angle)*eVec2);
987 SharedPlanePtr newPlane(
new DetPlane(*(measuredState->getPlane())));
990 MeasuredStateOnPlane stateCopy(*measuredState);
992 rep->extrapolateToPlane(stateCopy, newPlane);
999 rep->getPosMomCov(stateCopy, position, direction, cov);
1003 TMatrixDSymEigen eigen_values2(cov.GetSub(0, 2, 0, 2));
1004 const TVectorD& eVal = eigen_values2.GetEigenValues();
1005 const TMatrixD& eVect = eigen_values2.GetEigenVectors();
1007 ev0 = std::min(eVal(0), maxErr);
1008 ev1 = std::min(eVal(1), maxErr);
1009 ev2 = std::min(eVal(2), maxErr);
1012 if (ev0 < ev1 && ev0 < ev2) {
1013 eVec1.SetXYZ(eVect(0, 1), eVect(1, 1), eVect(2, 1));
1015 eVec2.SetXYZ(eVect(0, 2), eVect(1, 2), eVect(2, 2));
1017 }
else if (ev1 < ev0 && ev1 < ev2) {
1018 eVec1.SetXYZ(eVect(0, 0), eVect(1, 0), eVect(2, 0));
1020 eVec2.SetXYZ(eVect(0, 2), eVect(1, 2), eVect(2, 2));
1023 eVec1.SetXYZ(eVect(0, 0), eVect(1, 0), eVect(2, 0));
1025 eVec2.SetXYZ(eVect(0, 1), eVect(1, 1), eVect(2, 1));
1026 } eVec2 *=
sqrt(ev1);
1029 if (eVec1.Cross(eVec2).Dot(
eval) < 0)
1033 if (oldEVec1.Dot(eVec1) < 0) {
1039 double angle0 = ROOT::Math::VectorUtil::Angle(eVec1, oldEVec1);
1040 if (eVec1.Dot(
eval.Cross(oldEVec1)) < 0)
1042 for (
int i = 0; i < nEdges; ++i) {
1043 const double angle = 2 * TMath::Pi() / nEdges * i - angle0;
1044 vertices.push_back(ROOT::Math::XYZVector(position) + cos(angle)*eVec1 + sin(angle)*eVec2);
1047 vertices.push_back(ROOT::Math::XYZVector(position));
1050 TEveTriangleSet* error_shape =
new TEveTriangleSet(vertices.size(), nEdges * 2);
1051 for (
unsigned int k = 0; k < vertices.size(); ++k) {
1052 error_shape->SetVertex(k, vertices[k].X(), vertices[k].Y(), vertices[k].Z());
1055 assert(vertices.size() == 2 * nEdges + 2);
1058 for (
int i = 0; i < nEdges; ++i) {
1060 error_shape->SetTriangle(iTri++, i + 1, i + 1 + nEdges, (i + 1) % nEdges + 1);
1061 error_shape->SetTriangle(iTri++, (i + 1) % nEdges + 1, i + 1 + nEdges, (i + 1) % nEdges + 1 + nEdges);
1068 error_shape->SetMainTransparency(25);
1069 eveTrack->AddElement(error_shape);
1076 addSimHit(ROOT::Math::XYZVector(hit->getPosWire()), particle);
1092 const ROOT::Math::XYZVector& global_pos = hit->getPosition();
1100 track->simhits->SetNextPoint(v.X(), v.Y(), v.Z());
1107 const TString pointsTitle(
"Unassigned SimHits");
1123 particle = particle->getMother();
1127 const ROOT::Math::XYZVector& p = particle->getMomentum();
1128 const ROOT::Math::XYZVector& vertex = particle->getProductionVertex();
1129 const int pdg = particle->getPDG();
1130 TParticle tparticle(pdg, particle->getStatus(),
1131 (particle->getMother() ? particle->getMother()->getIndex() : 0), 0, particle->getFirstDaughter(), particle->getLastDaughter(),
1132 p.X(), p.Y(), p.Z(), particle->getEnergy(),
1133 vertex.X(), vertex.Y(), vertex.Z(), particle->getProductionTime());
1134 TEveMCTrack mctrack;
1135 mctrack = tparticle;
1136 mctrack.fTDecay = particle->getDecayTime();
1137 mctrack.fVDecay.Set(
B2Vector3D(particle->getDecayVertex()));
1138 mctrack.fDecayed = !boost::math::isinf(mctrack.fTDecay);
1139 mctrack.fIndex = particle->getIndex();
1144 bool hasTrajectory(
false);
1145 for (
auto rel : mcTrajectories.relations()) {
1148 if (rel.weight <= 0)
continue;
1159 (&pt == &trajectory.
back()) ? TEvePathMark::kDecay : TEvePathMark::kReference,
1160 TEveVector(pt.x, pt.y, pt.z),
1161 TEveVector(pt.px, pt.py, pt.pz)
1165 hasTrajectory =
true;
1170 if (!hasTrajectory) {
1172 for (
int iDaughter = particle->getFirstDaughter(); iDaughter <= particle->getLastDaughter(); iDaughter++) {
1178 TEvePathMarkD refMark(TEvePathMarkD::kDaughter);
1179 refMark.fV.Set(
B2Vector3D(daughter->getProductionVertex()));
1180 refMark.fP.Set(
B2Vector3D(daughter->getMomentum()));
1181 refMark.fTime = daughter->getProductionTime();
1188 and mctrack.fDecayed) {
1189 TEvePathMarkD decayMark(TEvePathMarkD::kDecay);
1190 decayMark.fV.Set(
B2Vector3D(particle->getDecayVertex()));
1194 TString particle_name(mctrack.GetName());
1197 const MCParticle* mom = particle->getMother();
1204 if (!hasTrajectory) {
1207 title +=
"\n(track estimated from initial momentum)";
1253 MCTrack& mcTrack = mcTrackPair.second;
1254 if (mcTrack.
track) {
1255 if (mcTrack.
simhits->Size() > 0) {
1259 destroyEveElement(mcTrack.
simhits);
1266 parent = parentIt->second.track;
1269 parent->AddElement(mcTrack.
track);
1271 gEve->AddElement(mcTrack.
simhits);
1278 for (
size_t i = 0; i <
m_options.length(); i++) {
1285 m.SetMarkerStyle(1);
1317 if (groupPair.second.group)
1318 groupPair.second.visible = groupPair.second.group->GetRnrState();
1319 groupPair.second.group =
nullptr;
1331 float ecl_threshold = 0.01;
1333 ecl_threshold =
m_eclData->GetSliceThreshold(0);
1338 m_eclData->RefSliceInfo(0).Setup(
"ECL", ecl_threshold, kRed);
1344 gEve->GetSelection()->RemoveElements();
1345 gEve->GetHighlight()->RemoveElements();
1354 ROOT::Math::XYZVector v = ROOT::Math::XYZVector(vertex->getPos());
1359 vertexPoint->SetNextPoint(v.X(), v.Y(), v.Z());
1361 TMatrixDSymEigen eigen_values(vertex->getCov());
1363 det_shape->SetShape(
new TGeoSphere(0., 1.));
1364 fixGeoShapeRefCount(det_shape);
1365 const TVectorD& ev = eigen_values.GetEigenValues();
1366 const TMatrixD& eVec = eigen_values.GetEigenVectors();
1368 ROOT::Math::XYZVector eVec1(eVec(0, 0), eVec(1, 0), eVec(2, 0));
1370 ROOT::Math::XYZVector eVec2(eVec(0, 1), eVec(1, 1), eVec(2, 1));
1371 ROOT::Math::XYZVector eVec3(eVec(0, 2), eVec(1, 2), eVec(2, 2));
1375 TGeoRotation det_rot(
"det_rot", (eVec1.Theta() * 180) / TMath::Pi(), (eVec1.Phi() * 180) / TMath::Pi(),
1376 (eVec2.Theta() * 180) / TMath::Pi(), (eVec2.Phi() * 180) / TMath::Pi(),
1377 (eVec3.Theta() * 180) / TMath::Pi(), (eVec3.Phi() * 180) / TMath::Pi());
1381 double pseudo_res_0 = std::sqrt(ev(0));
1382 double pseudo_res_1 = std::sqrt(ev(1));
1383 double pseudo_res_2 = std::sqrt(ev(2));
1390 TGeoGenTrans det_trans(v.X(), v.Y(), v.Z(), pseudo_res_0, pseudo_res_1, pseudo_res_2,
1392 det_shape->SetTransMatrix(det_trans);
1395 det_shape->SetMainColor(kOrange);
1396 det_shape->SetMainTransparency(0);
1398 vertexPoint->AddElement(det_shape);
1410 const float phi = cluster->getPhi();
1411 float dPhi = cluster->getUncertaintyPhi();
1412 float dTheta = cluster->getUncertaintyTheta();
1413 if (dPhi >= M_PI / 4 or dTheta >= M_PI / 4 or cluster->getUncertaintyEnergy() == 1.0) {
1414 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:");
1415 cluster->getCovarianceMatrix3x3().Print();
1416 dPhi = dTheta = 0.05;
1419 if (!std::isfinite(dPhi) or !std::isfinite(dTheta)) {
1420 B2ERROR(
"ECLCluster phi or theta error is NaN or infinite, skipping cluster!");
1425 ROOT::Math::XYZVector thetaLow;
1426 VectorUtil::setPtThetaPhi(thetaLow, 1.0, cluster->getTheta() - dTheta, phi);
1427 ROOT::Math::XYZVector thetaHigh;
1428 VectorUtil::setPtThetaPhi(thetaHigh, 1.0, cluster->getTheta() + dTheta, phi);
1429 float etaLow = thetaLow.Eta();
1430 float etaHigh = thetaHigh.Eta();
1431 if (etaLow > etaHigh) {
1432 std::swap(etaLow, etaHigh);
1435 int id =
m_eclData->AddTower(etaLow, etaHigh, phi - dPhi, phi + dPhi);
1443 const double layerThicknessCm = 3.16;
1444 const double layerDistanceCm = 9.1 - layerThicknessCm;
1447 ROOT::Math::XYZVector position = cluster->getClusterPosition();
1448 ROOT::Math::XYZVector startPos(position.X(), position.Y(), position.Z());
1449 ROOT::Math::XYZVector dir;
1450 ROOT::Math::XYZVector a, b;
1451 bool isBarrel = (startPos.Z() > -175.0 and startPos.Z() < 270.0);
1454 b = ROOT::Math::XYZVector(0, 0, 1);
1455 a = startPos.Cross(b).Unit();
1456 double c = M_PI / 4.0;
1457 double offset = c / 2.0 + M_PI;
1458 VectorUtil::setPhi(a,
int((a.Phi() + offset) / (c))*c - M_PI);
1459 ROOT::Math::XYZVector perp = b.Cross(a);
1461 const double barrelRadiusCm = 204.0;
1462 VectorUtil::setMag(startPos, barrelRadiusCm / perp.Dot(startPos.Unit()));
1464 dir = startPos.Unit();
1465 VectorUtil::setMag(dir, (layerDistanceCm + layerThicknessCm) / perp.Dot(dir));
1468 b = ROOT::Math::XYZVector(startPos.X(), startPos.Y(), 0).Unit();
1469 a = startPos.Cross(b).Unit();
1470 double endcapStartZ = 284;
1471 if (startPos.Z() < 0)
1472 endcapStartZ = -189.5;
1474 double scaleFac = endcapStartZ / startPos.Z();
1475 VectorUtil::setMag(startPos, startPos.R() * scaleFac);
1477 dir = startPos.Unit();
1478 VectorUtil::setMag(dir, (layerDistanceCm + layerThicknessCm) / fabs(dir.Z()));
1481 for (
int i = 0; i < cluster->getLayers(); i++) {
1482 ROOT::Math::XYZVector layerPos = startPos;
1483 layerPos += (cluster->getInnermostLayer() + i) * dir;
1484 auto* layer =
boxCreator(layerPos, a, b, 20.0, 20.0, layerThicknessCm / 2);
1486 layer->SetMainTransparency(70);
1500 CLHEP::Hep3Vector global;
1507 CLHEP::Hep3Vector local = module->globalToLocal(global);
1512 double du = module->getPhiStripWidth() * Nphistrip;
1513 double dv = module->getZStripWidth() * Nztrip;
1516 CLHEP::Hep3Vector localU(local[0], local[1] + 1.0, local[2]);
1517 CLHEP::Hep3Vector localV(local[0], local[1], local[2] + 1.0);
1519 CLHEP::Hep3Vector globalU = module->localToGlobal(localU);
1520 CLHEP::Hep3Vector globalV = module->localToGlobal(localV);
1522 ROOT::Math::XYZVector o(global[0], global[1], global[2]);
1523 ROOT::Math::XYZVector u(globalU[0], globalU[1], globalU[2]);
1524 ROOT::Math::XYZVector v(globalV[0], globalV[1], globalV[2]);
1527 TEveBox* bklmbox =
boxCreator(o, u - o, v - o, du, dv, 1.0);
1529 bklmbox->SetMainColor(kGreen);
1531 bklmbox->SetName(
"BKLMHit2d");
1539 const double du = 2.0;
1540 const double dv = 2.0;
1541 ROOT::Math::XYZVector hitPosition = eklm2dhit->
getPosition();
1542 ROOT::Math::XYZVector o(hitPosition.X(), hitPosition.Y(), hitPosition.Z());
1543 ROOT::Math::XYZVector u(1.0, 0.0, 0.0);
1544 ROOT::Math::XYZVector v(0.0, 1.0, 0.0);
1545 TEveBox* eklmbox =
boxCreator(o, u, v, du, dv, 4.0);
1546 eklmbox->SetMainColor(kGreen);
1547 eklmbox->SetName(
"EKLMHit2d");
1556 VxdID sensorID = roi->getSensorID();
1559 double minU = aSensorInfo.
getUCellPosition(roi->getMinUid(), roi->getMinVid());
1561 double maxU = aSensorInfo.
getUCellPosition(roi->getMaxUid(), roi->getMaxVid());
1565 ROOT::Math::XYZVector localA(minU, minV, 0);
1566 ROOT::Math::XYZVector localB(minU, maxV, 0);
1567 ROOT::Math::XYZVector localC(maxU, minV, 0);
1569 ROOT::Math::XYZVector globalA = aSensorInfo.
pointToGlobal(localA);
1570 ROOT::Math::XYZVector globalB = aSensorInfo.
pointToGlobal(localB);
1571 ROOT::Math::XYZVector globalC = aSensorInfo.
pointToGlobal(localC);
1573 TEveBox* ROIbox =
boxCreator(globalB + globalC * 0.5, globalB - globalA, globalC - globalA, 1, 1, 0.01);
1576 ROIbox->SetMainColor(kSpring - 9);
1577 ROIbox->SetMainTransparency(50);
1588 ROOT::Math::XYZVector a, b;
1589 if (hit->isUCluster()) {
1590 const float u = hit->getPosition();
1591 a = sensor.pointToGlobal(ROOT::Math::XYZVector(sensor.getBackwardWidth() / sensor.getWidth(0) * u, -0.5 * sensor.getLength(), 0.0));
1592 b = sensor.pointToGlobal(ROOT::Math::XYZVector(sensor.getForwardWidth() / sensor.getWidth(0) * u, +0.5 * sensor.getLength(), 0.0));
1594 const float v = hit->getPosition();
1595 a = sensor.pointToGlobal(ROOT::Math::XYZVector(-0.5 * sensor.getWidth(v), v, 0.0));
1596 b = sensor.pointToGlobal(ROOT::Math::XYZVector(+0.5 * sensor.getWidth(v), v, 0.0));
1599 lines->AddLine(a.X(), a.Y(), a.Z(), b.X(), b.Y(), b.Z());
1609 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());
1620 TEveGeoShape* cov_shape =
new TEveGeoShape(
"cov_shape");
1624 driftLengthRes = std::max(driftLengthRes, 0.005);
1625 const double lengthOfWireSection = 3.0;
1628 const B2Vector3D zaxis = wire_pos_b - wire_pos_f;
1633 const B2Vector3D midPoint = wire_pos_f - zaxis * (wire_pos_f.
Z() / zaxis.
Z());
1635 cov_shape->SetShape(
new TGeoTube(std::max(0., (
double)(driftLength - driftLengthRes)), driftLength + driftLengthRes,
1636 lengthOfWireSection));
1637 fixGeoShapeRefCount(cov_shape);
1639 TGeoRotation det_rot(
"det_rot",
1640 xaxis.
Theta() * 180 / TMath::Pi(), xaxis.
Phi() * 180 / TMath::Pi(),
1641 yaxis.
Theta() * 180 / TMath::Pi(), yaxis.
Phi() * 180 / TMath::Pi(),
1642 zaxis.
Theta() * 180 / TMath::Pi(), zaxis.
Phi() * 180 / TMath::Pi()
1645 TGeoCombiTrans det_trans(midPoint.
X(), midPoint.
Y(), midPoint.
Z(), &det_rot);
1646 cov_shape->SetTransMatrix(det_trans);
1649 bool isPartOfTS =
false;
1651 if (showTriggerHits && segments.size() > 0) {
1655 if (hit->getISuperLayer() % 2 == 0) {
1657 cov_shape->SetMainColor(kCyan + 3);
1659 cov_shape->SetMainColor(kCyan);
1662 cov_shape->SetMainColor(kPink + 6);
1664 cov_shape->SetMainColor(kPink + 7);
1667 cov_shape->SetMainTransparency(50);
1669 cov_shape->SetTitle(
ObjectInfo::getInfo(hit) + TString::Format(
"\nWire ID: %d\nADC: %d\nTDC: %d",
1670 hit->getID(), hit->getADCCount(), hit->getTDCCount()));
1675 addToGroup(
"CDCTriggerSegmentHits", cov_shape);
1676 for (
auto rel : segments.relations()) {
1685 TEveStraightLineSet* shape =
new TEveStraightLineSet();
1689 if (hit->getPriorityPosition() < 3) iL -= 1;
1691 unsigned iCenter = hit->getIWire();
1692 if (hit->getPriorityPosition() == 1) iCenter += 1;
1703 std::vector<int> layershift = { -2, -1, 0, 1, 2};
1704 std::vector<std::vector<float>> cellshift = {
1718 if (hit->getISuperLayer() == 0) {
1719 layershift = { 0, 1, 2, 3, 4};
1724 { -1.5, -0.5, 0.5, 1.5},
1730 for (
unsigned il = 0; il < layershift.size(); ++il) {
1731 for (
unsigned ic = 0; ic < cellshift[il].size(); ++ic) {
1732 ROOT::Math::XYZVector corners[2][2];
1733 for (
unsigned ir = 0; ir < 2; ++ir) {
1734 double r = cdcgeo.
fieldWireR(iL + layershift[il] - ir);
1735 double fz = cdcgeo.
fieldWireFZ(iL + layershift[il] - ir);
1736 double bz = cdcgeo.
fieldWireBZ(iL + layershift[il] - ir);
1737 for (
unsigned iphi = 0; iphi < 2; ++iphi) {
1738 double phib = (iCenter + cellshift[il][ic] + iphi - 0.5) * 2 * M_PI / nWires;
1739 double phif = phib + cdcgeo.
nShifts(iL + layershift[il]) * M_PI / nWires;
1741 ROOT::Math::XYZVector pos_f = ROOT::Math::XYZVector(cos(phif) * r, sin(phif) * r, fz);
1742 ROOT::Math::XYZVector pos_b = ROOT::Math::XYZVector(cos(phib) * r, sin(phib) * r, bz);
1743 ROOT::Math::XYZVector zaxis = pos_b - pos_f;
1744 corners[ir][iphi] = pos_f - zaxis * (pos_f.Z() / zaxis.Z());
1748 shape->AddLine(corners[0][0].X(), corners[0][0].Y(), 0,
1749 corners[0][1].X(), corners[0][1].Y(), 0);
1750 shape->AddLine(corners[0][1].X(), corners[0][1].Y(), 0,
1751 corners[1][1].X(), corners[1][1].Y(), 0);
1752 shape->AddLine(corners[1][1].X(), corners[1][1].Y(), 0,
1753 corners[1][0].X(), corners[1][0].Y(), 0);
1754 shape->AddLine(corners[1][0].X(), corners[1][0].Y(), 0,
1755 corners[0][0].X(), corners[0][0].Y(), 0);
1759 if (hit->getISuperLayer() % 2 == 0) {
1760 shape->SetMainColor(kCyan + 3);
1762 shape->SetMainColor(kPink + 6);
1767 TString::Format(
"\nPriority: %d\nLeft/Right: %d",
1768 hit->getPriorityPosition(), hit->getLeftRight()));
1777 int hitModule = hit->getModule();
1778 float fi = arichGeo->getDetectorPlane().getSlotPhi(hitModule);
1780 ROOT::Math::XYZVector centerPos3D = hit->getPosition();
1782 ROOT::Math::RotationZ rotZ(fi);
1783 ROOT::Math::XYZVector channelX(1, 0, 0);
1784 ROOT::Math::XYZVector channelY(0, 1, 0);
1785 channelX = rotZ * channelX;
1786 channelY = rotZ * channelY;
1789 arichGeo->getMasterVolume().momentumToGlobal(channelX),
1790 arichGeo->getMasterVolume().momentumToGlobal(channelY),
1792 arichbox->SetMainColor(kOrange + 10);
1793 arichbox->SetName((std::to_string(hitModule)).c_str());
1802 std::map<int, int> m_topSummary;
1803 for (
const TOPDigit& hit : digits) {
1804 int mod = hit.getModuleID();
1805 ++m_topSummary[mod];
1808 for (
auto modCountPair : m_topSummary) {
1809 if (modCountPair.second > maxcount)
1810 maxcount = modCountPair.second;
1812 for (
auto modCountPair : m_topSummary) {
1814 double phi = topmod.getPhi();
1815 double r_center = topmod.getRadius();
1816 double z = topmod.getZc();
1818 ROOT::Math::XYZVector centerPos3D;
1819 VectorUtil::setMagThetaPhi(centerPos3D, r_center, M_PI / 2, phi);
1820 centerPos3D.SetZ(z);
1826 auto* moduleBox =
boxCreator(centerPos3D, channelX, channelY,
1827 3.0 * topmod.getBarThickness(), topmod.getBarWidth(), topmod.getBarLength());
1828 moduleBox->SetMainColor(kAzure + 10);
1829 double weight = double(modCountPair.second) / maxcount;
1830 moduleBox->SetMainTransparency(90 - weight * 50);
1831 moduleBox->SetName((
"TOP module " + std::to_string(modCountPair.first)).c_str());
1832 moduleBox->SetTitle(TString::Format(
"#TOPDigits: %d ", modCountPair.second));
1836 for (
const TOPDigit& hit : digits) {
1837 if (modCountPair.first == hit.getModuleID())
1846 for (
const auto& labelPair : displayData.
m_labels) {
1847 TEveText* text =
new TEveText(labelPair.first.c_str());
1848 text->SetName(labelPair.first.c_str());
1849 text->SetTitle(labelPair.first.c_str());
1850 text->SetMainColor(kGray + 1);
1851 const ROOT::Math::XYZVector& p = labelPair.second;
1852 text->PtrMainTrans()->SetPos(p.X(), p.Y(), p.Z());
1856 for (
const auto& pointPair : displayData.
m_pointSets) {
1857 TEvePointSet* points =
new TEvePointSet(pointPair.first.c_str());
1858 points->SetTitle(pointPair.first.c_str());
1859 points->SetMarkerStyle(7);
1860 points->SetMainColor(kGreen);
1861 for (
const auto& p : pointPair.second) {
1862 points->SetNextPoint(p.X(), p.Y(), p.Z());
1867 int randomColor = 2;
1868 for (
const auto& arrow : displayData.
m_arrows) {
1869 const ROOT::Math::XYZVector pos = arrow.start;
1870 const ROOT::Math::XYZVector dir = arrow.end - pos;
1871 TEveArrow* eveArrow =
new TEveArrow(dir.X(), dir.Y(), dir.Z(), pos.X(), pos.Y(), pos.Z());
1872 eveArrow->SetName(arrow.name.c_str());
1873 eveArrow->SetTitle(arrow.name.c_str());
1874 int arrowColor = arrow.color;
1875 if (arrowColor == -1) {
1876 arrowColor = randomColor;
1879 eveArrow->SetMainColor(arrowColor);
1882 TEveText* text =
new TEveText(arrow.name.c_str());
1883 text->SetMainColor(arrowColor);
1886 ROOT::Math::XYZVector orthogonalDir;
1887 if (std::abs(dir.X()) < std::abs(dir.Y())) {
1888 if (std::abs(dir.X()) < std::abs(dir.Z())) {
1889 orthogonalDir.SetCoordinates(0, dir.Z(), -dir.Y());
1891 orthogonalDir.SetCoordinates(dir.Y(), -dir.X(), 0);
1894 if (std::abs(dir.Y()) < std::abs(dir.Z())) {
1895 orthogonalDir.SetCoordinates(-dir.Z(), 0, dir.X());
1897 orthogonalDir.SetCoordinates(dir.Y(), -dir.X(), 0);
1900 const ROOT::Math::XYZVector& labelPos = pos + 0.5 * dir + 0.1 * orthogonalDir;
1901 text->PtrMainTrans()->SetPos(labelPos.X(), labelPos.Y(), labelPos.Z());
1902 eveArrow->AddElement(text);
1915 const std::string& groupName = boost::algorithm::trim_copy_if(name, boost::algorithm::is_any_of(
"/"));
1917 TEveElementList* group =
m_groups[groupName].group;
1919 group =
new TEveElementList(groupName.c_str(), groupName.c_str());
1920 group->SetRnrState(
m_groups[groupName].visible);
1925 auto lastSlash = boost::algorithm::find_last(groupName,
"/");
1927 const std::string parentGroup(groupName.begin(), lastSlash.begin());
1928 const std::string thisGroup(lastSlash.end(), groupName.end());
1929 group->SetElementName(thisGroup.c_str());
1932 gEve->AddElement(group);
1935 group->AddElement(elem);
Datastore class that holds photon hits. Input to the reconstruction.
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...
This class is used to transfer CDC information to the track fit.
Combination of several CDCHits to a track segment hit for the trigger.
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.
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 addCDCTriggerTrack(const std::string &collectionName, const CDCTriggerTrack &track)
Add a CDCTriggerTrack.
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 recontructed hit in ARICH.
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.
void addObject(const TObject *dataStoreObject, TEveElement *visualRepresentation)
Generic function to keep track of which objects have which visual representation.
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.
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).
The PXD Cluster class This class stores all information about reconstructed PXD clusters The position...
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.
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.
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 a fit hypothesis with the closest mass.
Class to faciliate easy access to sensor information of the VXD like coordinate transformations or pi...
const SensorInfoBase & getSensorInfo(Belle2::VxdID id) const
Return a referecne 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.