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);
135 m_assignToPrimaries(false),
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);
352 B2Vector3D track_mom = (trgTrack.getChargeSign() == 0) ?
353 trgTrack.getDirection() * 1000 :
354 trgTrack.getMomentum(1.5);
356 TEveRecTrack rectrack;
357 rectrack.fP.Set(track_mom);
358 rectrack.fV.Set(track_pos);
361 track_lines->SetName(label);
363 track_lines->SetLineColor(kOrange + 2);
364 track_lines->SetLineWidth(1);
366 TString::Format(
"\ncharge: %d, phi: %.2fdeg, pt: %.2fGeV, theta: %.2fdeg, z: %.2fcm",
367 trgTrack.getChargeSign(),
368 trgTrack.getPhi0() * 180 / M_PI,
369 trgTrack.getTransverseMomentum(1.5),
370 trgTrack.getDirection().Theta() * 180 / M_PI,
374 track_lines->SetCharge(trgTrack.getChargeSign());
377 if (trgTrack.getZ0() == 0 && trgTrack.getCotTheta() == 0)
378 track_lines->SetLineStyle(2);
390 B2ERROR(
"Track without TrackFitResult skipped.");
398 bool drawDetectors =
false;
399 bool drawHits =
false;
400 bool drawPlanes =
false;
403 for (
size_t i = 0; i <
m_options.length(); i++) {
404 if (
m_options.at(i) ==
'D') drawDetectors =
true;
405 if (
m_options.at(i) ==
'H') drawHits =
true;
406 if (
m_options.at(i) ==
'P') drawPlanes =
true;
414 bool isPruned = (track ==
nullptr);
417 TEveRecTrackD recTrack;
419 recTrack.fV.Set(poca);
422 if (std::isfinite(poca_momentum.
Mag()))
423 recTrack.fP.Set(poca_momentum);
429 eveTrack->SetName(label);
433 const genfit::AbsTrackRep* representation;
436 representation = track->getCardinalRepresentation();
437 B2DEBUG(100,
"Draw cardinal rep");
439 const auto& representations = track->getRepresentations();
440 if (representations.empty()) {
441 B2ERROR(
"No representations found in the reco track!");
444 B2DEBUG(100,
"Draw representation number 0.");
445 representation = representations.front();
448 if (!track->hasTrackFitStatus(representation)) {
449 B2ERROR(
"RecoTrack without FitStatus: will be skipped!");
453 const genfit::FitStatus* fitStatus = track->getTrackFitStatus(representation);
455 isPruned = fitStatus->isTrackPruned();
459 genfit::KalmanFitterInfo* fi = 0;
460 genfit::KalmanFitterInfo* prevFi = 0;
461 genfit::GblFitterInfo* gfi = 0;
462 genfit::GblFitterInfo* prevGFi = 0;
463 const genfit::MeasuredStateOnPlane* fittedState(NULL);
464 const genfit::MeasuredStateOnPlane* prevFittedState(NULL);
467 const auto& hitPoints = track->getHitPointsWithMeasurement();
468 const unsigned int numpoints = hitPoints.size();
471 for (genfit::TrackPoint* tp : hitPoints) {
475 if (! tp->hasFitterInfo(representation)) {
476 B2ERROR(
"trackPoint has no fitterInfo for rep");
480 genfit::AbsFitterInfo* fitterInfo = tp->getFitterInfo(representation);
482 fi =
dynamic_cast<genfit::KalmanFitterInfo*
>(fitterInfo);
483 gfi =
dynamic_cast<genfit::GblFitterInfo*
>(fitterInfo);
486 B2ERROR(
"Can only display KalmanFitterInfo or GblFitterInfo");
491 B2FATAL(
"AbsFitterInfo dynamic-casted to both KalmanFitterInfo and GblFitterInfo!");
494 if (fi && ! tp->hasRawMeasurements()) {
495 B2ERROR(
"trackPoint has no raw measurements");
499 if (fi && ! fi->hasPredictionsAndUpdates()) {
500 B2ERROR(
"KalmanFitterInfo does not have all predictions and updates");
506 fittedState = &(gfi->getFittedState(
true));
508 fittedState = &(fi->getFittedState(
true));
509 }
catch (genfit::Exception& e) {
510 B2ERROR(e.what() <<
" - can not get fitted state");
514 ROOT::Math::XYZVector track_pos = ROOT::Math::XYZVector(representation->getPos(*fittedState));
517 if (prevFittedState != NULL) {
519 TEvePathMark::EType_e markType = TEvePathMark::kReference;
520 if (hitCounter + 1 ==
static_cast<int>(numpoints))
521 markType = TEvePathMark::kDecay;
532 makeLines(eveTrack, prevFi->getForwardUpdate(), fi->getForwardPrediction(), representation, markType,
m_drawErrors, 0);
534 makeLines(eveTrack, prevFi->getBackwardPrediction(), fi->getBackwardUpdate(), representation, markType,
m_drawErrors);
536 if (
m_drawRefTrack && fi->hasReferenceState() && prevFi->hasReferenceState())
537 makeLines(eveTrack, prevFi->getReferenceState(), fi->getReferenceState(), representation, markType,
false);
541 if (gfi && prevGFi) {
547 if (
m_drawRefTrack && gfi->hasReferenceState() && prevGFi->hasReferenceState()) {
548 genfit::StateOnPlane prevSop = prevGFi->getReferenceState();
549 genfit::StateOnPlane sop = gfi->getReferenceState();
550 makeLines(eveTrack, &prevSop, &sop, representation, markType,
false);
557 prevFittedState = fittedState;
561 const int numMeasurements = tp->getNumRawMeasurements();
562 for (
int iMeasurement = 0; iMeasurement < numMeasurements; iMeasurement++) {
563 const genfit::AbsMeasurement* m = tp->getRawMeasurement(iMeasurement);
565 TVectorT<double> hit_coords;
566 TMatrixTSym<double> hit_cov;
570 genfit::MeasurementOnPlane* mop = fi->getMeasurementOnPlane(iMeasurement);
571 hit_coords.ResizeTo(mop->getState());
572 hit_cov.ResizeTo(mop->getCov());
573 hit_coords = mop->getState();
574 hit_cov = mop->getCov();
580 genfit::MeasurementOnPlane gblMeas = gfi->getMeasurement();
581 hit_coords.ResizeTo(gblMeas.getState());
582 hit_cov.ResizeTo(gblMeas.getCov());
583 hit_coords = gblMeas.getState();
584 hit_cov = gblMeas.getCov();
590 ROOT::Math::XYZVector o = ROOT::Math::XYZVector(fittedState->getPlane()->getO());
591 ROOT::Math::XYZVector u = ROOT::Math::XYZVector(fittedState->getPlane()->getU());
592 ROOT::Math::XYZVector v = ROOT::Math::XYZVector(fittedState->getPlane()->getV());
594 bool planar_hit =
false;
595 bool planar_pixel_hit =
false;
596 bool space_hit =
false;
597 bool wire_hit =
false;
598 bool wirepoint_hit =
false;
601 double_t plane_size = 4;
603 int hit_coords_dim = m->getDim();
605 if (
dynamic_cast<const genfit::PlanarMeasurement*
>(m) != NULL) {
607 if (hit_coords_dim == 1) {
608 hit_u = hit_coords(0);
609 }
else if (hit_coords_dim == 2) {
610 planar_pixel_hit =
true;
611 hit_u = hit_coords(0);
612 hit_v = hit_coords(1);
614 }
else if (
dynamic_cast<const genfit::SpacepointMeasurement*
>(m) != NULL) {
617 ||
dynamic_cast<const genfit::WireMeasurement*
>(m)
618 ||
dynamic_cast<const genfit::WireMeasurementNew*
>(m)) {
620 hit_u = fabs(hit_coords(0));
621 hit_v = v.Dot(track_pos - o);
622 if (
dynamic_cast<const genfit::WirePointMeasurement*
>(m) != NULL) {
623 wirepoint_hit =
true;
624 hit_v = hit_coords(1);
627 B2ERROR(
"Hit " << hitCounter <<
", Measurement " << iMeasurement <<
": Unknown measurement type: skipping hit!");
634 if (drawPlanes || (drawDetectors && planar_hit)) {
635 ROOT::Math::XYZVector move(0, 0, 0);
636 if (wire_hit) move = v * (v.Dot(track_pos - o));
637 TEveBox* box =
boxCreator(o + move, u, v, plane_size, plane_size, 0.01);
638 if (drawDetectors && planar_hit) {
639 box->SetMainColor(kCyan);
641 box->SetMainColor(kGray);
643 box->SetMainTransparency(50);
644 eveTrack->AddElement(box);
652 TEveGeoShape* det_shape =
new TEveGeoShape(
"det_shape");
653 det_shape->SetShape(
new TGeoTube(std::max(0., (
double)(hit_u - 0.0105 / 2.)), hit_u + 0.0105 / 2., plane_size));
654 fixGeoShapeRefCount(det_shape);
656 ROOT::Math::XYZVector norm = u.Cross(v);
657 TGeoRotation det_rot(
"det_rot", (u.Theta() * 180) / TMath::Pi(), (u.Phi() * 180) / TMath::Pi(),
658 (norm.Theta() * 180) / TMath::Pi(), (norm.Phi() * 180) / TMath::Pi(),
659 (v.Theta() * 180) / TMath::Pi(), (v.Phi() * 180) / TMath::Pi());
660 ROOT::Math::XYZVector move = v * (v.Dot(track_pos - o));
661 TGeoCombiTrans det_trans(o.X() + move.X(),
665 det_shape->SetTransMatrix(det_trans);
666 det_shape->SetMainColor(kCyan);
667 det_shape->SetMainTransparency(25);
668 if ((drawHits && (hit_u + 0.0105 / 2 > 0)) || !drawHits) {
669 eveTrack->AddElement(det_shape);
680 if (!planar_pixel_hit) {
685 B2WARNING(
"SVD recohit couldn't be converted... ");
691 ROOT::Math::XYZVector a = o;
692 double hit_res_u = hit_cov(0, 0);
693 if (recoHit->
isU()) {
694 du = std::sqrt(hit_res_u);
695 dv = sensor.getLength();
698 du = sensor.getWidth();
699 dv = std::sqrt(hit_res_u);
702 double depth = sensor.getThickness();
703 TEveBox* hit_box =
boxCreator(a, u, v, du, dv, depth);
704 hit_box->SetName(
"SVDRecoHit");
706 hit_box->SetMainTransparency(0);
707 eveTrack->AddElement(hit_box);
711 TMatrixDSymEigen eigen_values(hit_cov);
712 TEveGeoShape* cov_shape =
new TEveGeoShape(
"PXDRecoHit");
713 const TVectorD& ev = eigen_values.GetEigenValues();
714 const TMatrixD& eVec = eigen_values.GetEigenVectors();
720 cov_shape->SetShape(
new TGeoEltu(pseudo_res_0, pseudo_res_1, 0.0105));
721 fixGeoShapeRefCount(cov_shape);
722 ROOT::Math::XYZVector pix_pos = o + hit_u * u + hit_v * v;
723 ROOT::Math::XYZVector u_semiaxis = (pix_pos + eVec(0, 0) * u + eVec(1, 0) * v) - pix_pos;
724 ROOT::Math::XYZVector v_semiaxis = (pix_pos + eVec(0, 1) * u + eVec(1, 1) * v) - pix_pos;
725 ROOT::Math::XYZVector norm = u.Cross(v);
729 TGeoRotation det_rot(
"det_rot", (u_semiaxis.Theta() * 180) / TMath::Pi(), (u_semiaxis.Phi() * 180) / TMath::Pi(),
730 (v_semiaxis.Theta() * 180) / TMath::Pi(), (v_semiaxis.Phi() * 180) / TMath::Pi(),
731 (norm.Theta() * 180) / TMath::Pi(), (norm.Phi() * 180) / TMath::Pi());
732 TGeoCombiTrans det_trans(pix_pos.X(), pix_pos.Y(), pix_pos.Z(), &det_rot);
733 cov_shape->SetTransMatrix(det_trans);
737 cov_shape->SetMainTransparency(0);
738 eveTrack->AddElement(cov_shape);
747 TMatrixDSymEigen eigen_values(m->getRawHitCov());
748 TEveGeoShape* cov_shape =
new TEveGeoShape(
"SpacePoint Hit");
749 cov_shape->SetShape(
new TGeoSphere(0., 1.));
750 fixGeoShapeRefCount(cov_shape);
751 const TVectorD& ev = eigen_values.GetEigenValues();
752 const TMatrixD& eVec = eigen_values.GetEigenVectors();
753 ROOT::Math::XYZVector eVec1(eVec(0, 0), eVec(1, 0), eVec(2, 0));
754 ROOT::Math::XYZVector eVec2(eVec(0, 1), eVec(1, 1), eVec(2, 1));
755 ROOT::Math::XYZVector eVec3(eVec(0, 2), eVec(1, 2), eVec(2, 2));
759 TGeoRotation det_rot(
"det_rot", (eVec1.Theta() * 180) / TMath::Pi(), (eVec1.Phi() * 180) / TMath::Pi(),
760 (eVec2.Theta() * 180) / TMath::Pi(), (eVec2.Phi() * 180) / TMath::Pi(),
761 (eVec3.Theta() * 180) / TMath::Pi(), (eVec3.Phi() * 180) / TMath::Pi());
770 TGeoGenTrans det_trans(o.X(), o.Y(), o.Z(),
773 pseudo_res_0, pseudo_res_1, pseudo_res_2,
775 cov_shape->SetTransMatrix(det_trans);
779 cov_shape->SetMainTransparency(10);
780 eveTrack->AddElement(cov_shape);
786 const double cdcErrorScale = 1.0;
787 TEveGeoShape* cov_shape =
new TEveGeoShape(
"CDCRecoHit");
788 double pseudo_res_0 = cdcErrorScale * std::sqrt(hit_cov(0, 0));
789 double pseudo_res_1 = plane_size;
790 if (wirepoint_hit) pseudo_res_1 = cdcErrorScale * std::sqrt(hit_cov(1, 1));
792 cov_shape->SetShape(
new TGeoTube(std::max(0., (
double)(hit_u - pseudo_res_0)), hit_u + pseudo_res_0, pseudo_res_1));
793 fixGeoShapeRefCount(cov_shape);
794 ROOT::Math::XYZVector norm = u.Cross(v);
797 TGeoRotation det_rot(
"det_rot", (u.Theta() * 180) / TMath::Pi(), (u.Phi() * 180) / TMath::Pi(),
798 (norm.Theta() * 180) / TMath::Pi(), (norm.Phi() * 180) / TMath::Pi(),
799 (v.Theta() * 180) / TMath::Pi(), (v.Phi() * 180) / TMath::Pi());
800 TGeoCombiTrans det_trans(o.X() + hit_v * v.X(),
801 o.Y() + hit_v * v.Y(),
802 o.Z() + hit_v * v.Z(),
804 cov_shape->SetTransMatrix(det_trans);
808 cov_shape->SetMainTransparency(50);
809 eveTrack->AddElement(cov_shape);
817 auto& firstref = eveTrack->RefPathMarks().front();
818 auto& lastref = eveTrack->RefPathMarks().back();
819 double f = firstref.fV.Distance(recTrack.fV);
820 double b = lastref.fV.Distance(recTrack.fV);
821 if (f > 100 and f > b) {
822 B2WARNING(
"Decay vertex is much closer to POCA than first vertex, reversing order of track points... (this is intended for cosmic tracks, if you see this message in other context it might indicate a problem)");
824 lastref.fType = TEvePathMarkD::kReference;
825 firstref.fType = TEvePathMarkD::kDecay;
826 std::reverse(eveTrack->RefPathMarks().begin(), eveTrack->RefPathMarks().end());
829 eveTrack->SetTitle(TString::Format(
"%s\n"
834 isPruned ?
" yes" :
"no",
835 poca_momentum.
Pt(), poca_momentum.
Pz(),
839 eveTrack->SetLineStyle(1);
840 eveTrack->SetLineWidth(3.0);
850 float vd,
float depth)
861 TEveBox* box =
new TEveBox;
862 box->SetPickable(
true);
864 ROOT::Math::XYZVector norm = u.Cross(v);
867 norm *= (0.5 * depth);
870 for (
int k = 0; k < 8; ++k) {
873 int signU = ((k + 1) & 2) ? -1 : 1;
874 int signV = (k & 4) ? -1 : 1;
875 int signN = (k & 2) ? -1 : 1;
880 vertex[0] = o.X() + signU * u.X() + signV * v.X() + signN * norm.X();
881 vertex[1] = o.Y() + signU * u.Y() + signV * v.Y() + signN * norm.Y();
882 vertex[2] = o.Z() + signU * u.Z() + signV * v.Z() + signN * norm.Z();
883 box->SetVertex(k, vertex);
890 const genfit::AbsTrackRep* rep,
891 TEvePathMark::EType_e markType,
bool drawErrors,
int markerPos)
893 using namespace genfit;
896 TVector3 pos, dir, oldPos, oldDir;
897 rep->getPosDir(*state, pos, dir);
898 rep->getPosDir(*prevState, oldPos, oldDir);
900 double distA = (pos - oldPos).Mag();
901 double distB = distA;
902 if ((pos - oldPos)*oldDir < 0)
904 if ((pos - oldPos)*dir < 0)
909 TEveVector(pos.X(), pos.Y(), pos.Z()),
910 TEveVector(dir.X(), dir.Y(), dir.Z())
912 eveTrack->AddPathMark(mark);
916 const MeasuredStateOnPlane* measuredState;
918 measuredState =
dynamic_cast<const MeasuredStateOnPlane*
>(prevState);
920 measuredState =
dynamic_cast<const MeasuredStateOnPlane*
>(state);
922 if (measuredState != NULL) {
925 ROOT::Math::XYZVector
eval;
927 eval = 0.2 * distA * oldDir;
929 eval = -0.2 * distB * dir;
935 TVector3 position, direction;
936 rep->getPosMomCov(*measuredState, position, direction, cov);
939 TMatrixDSymEigen eigen_values(cov.GetSub(0, 2, 0, 2));
940 const TVectorD& ev = eigen_values.GetEigenValues();
941 const TMatrixD& eVec = eigen_values.GetEigenVectors();
942 ROOT::Math::XYZVector eVec1, eVec2;
944 static const double maxErr = 1000.;
945 double ev0 = std::min(ev(0), maxErr);
946 double ev1 = std::min(ev(1), maxErr);
947 double ev2 = std::min(ev(2), maxErr);
950 if (ev0 < ev1 && ev0 < ev2) {
951 eVec1.SetXYZ(eVec(0, 1), eVec(1, 1), eVec(2, 1));
953 eVec2.SetXYZ(eVec(0, 2), eVec(1, 2), eVec(2, 2));
955 }
else if (ev1 < ev0 && ev1 < ev2) {
956 eVec1.SetXYZ(eVec(0, 0), eVec(1, 0), eVec(2, 0));
958 eVec2.SetXYZ(eVec(0, 2), eVec(1, 2), eVec(2, 2));
961 eVec1.SetXYZ(eVec(0, 0), eVec(1, 0), eVec(2, 0));
963 eVec2.SetXYZ(eVec(0, 1), eVec(1, 1), eVec(2, 1));
967 if (eVec1.Cross(eVec2).Dot(
eval) < 0)
971 ROOT::Math::XYZVector oldEVec1(eVec1);
973 const int nEdges = 24;
974 std::vector<ROOT::Math::XYZVector> vertices;
976 vertices.push_back(ROOT::Math::XYZVector(position));
979 for (
int i = 0; i < nEdges; ++i) {
980 const double angle = 2 * TMath::Pi() / nEdges * i;
981 vertices.push_back(ROOT::Math::XYZVector(position) + cos(angle)*eVec1 + sin(angle)*eVec2);
986 SharedPlanePtr newPlane(
new DetPlane(*(measuredState->getPlane())));
989 MeasuredStateOnPlane stateCopy(*measuredState);
991 rep->extrapolateToPlane(stateCopy, newPlane);
998 rep->getPosMomCov(stateCopy, position, direction, cov);
1002 TMatrixDSymEigen eigen_values2(cov.GetSub(0, 2, 0, 2));
1003 const TVectorD& eVal = eigen_values2.GetEigenValues();
1004 const TMatrixD& eVect = eigen_values2.GetEigenVectors();
1006 ev0 = std::min(eVal(0), maxErr);
1007 ev1 = std::min(eVal(1), maxErr);
1008 ev2 = std::min(eVal(2), maxErr);
1011 if (ev0 < ev1 && ev0 < ev2) {
1012 eVec1.SetXYZ(eVect(0, 1), eVect(1, 1), eVect(2, 1));
1014 eVec2.SetXYZ(eVect(0, 2), eVect(1, 2), eVect(2, 2));
1016 }
else if (ev1 < ev0 && ev1 < ev2) {
1017 eVec1.SetXYZ(eVect(0, 0), eVect(1, 0), eVect(2, 0));
1019 eVec2.SetXYZ(eVect(0, 2), eVect(1, 2), eVect(2, 2));
1022 eVec1.SetXYZ(eVect(0, 0), eVect(1, 0), eVect(2, 0));
1024 eVec2.SetXYZ(eVect(0, 1), eVect(1, 1), eVect(2, 1));
1025 } eVec2 *=
sqrt(ev1);
1028 if (eVec1.Cross(eVec2).Dot(
eval) < 0)
1032 if (oldEVec1.Dot(eVec1) < 0) {
1038 double angle0 = ROOT::Math::VectorUtil::Angle(eVec1, oldEVec1);
1039 if (eVec1.Dot(
eval.Cross(oldEVec1)) < 0)
1041 for (
int i = 0; i < nEdges; ++i) {
1042 const double angle = 2 * TMath::Pi() / nEdges * i - angle0;
1043 vertices.push_back(ROOT::Math::XYZVector(position) + cos(angle)*eVec1 + sin(angle)*eVec2);
1046 vertices.push_back(ROOT::Math::XYZVector(position));
1049 TEveTriangleSet* error_shape =
new TEveTriangleSet(vertices.size(), nEdges * 2);
1050 for (
unsigned int k = 0; k < vertices.size(); ++k) {
1051 error_shape->SetVertex(k, vertices[k].X(), vertices[k].Y(), vertices[k].Z());
1054 assert(vertices.size() == 2 * nEdges + 2);
1057 for (
int i = 0; i < nEdges; ++i) {
1059 error_shape->SetTriangle(iTri++, i + 1, i + 1 + nEdges, (i + 1) % nEdges + 1);
1060 error_shape->SetTriangle(iTri++, (i + 1) % nEdges + 1, i + 1 + nEdges, (i + 1) % nEdges + 1 + nEdges);
1067 error_shape->SetMainTransparency(25);
1068 eveTrack->AddElement(error_shape);
1075 addSimHit(ROOT::Math::XYZVector(hit->getPosWire()), particle);
1091 const ROOT::Math::XYZVector& global_pos = hit->getPosition();
1099 track->simhits->SetNextPoint(v.X(), v.Y(), v.Z());
1106 const TString pointsTitle(
"Unassigned SimHits");
1122 particle = particle->getMother();
1126 const ROOT::Math::XYZVector& p = particle->getMomentum();
1127 const ROOT::Math::XYZVector& vertex = particle->getProductionVertex();
1128 const int pdg = particle->getPDG();
1129 TParticle tparticle(pdg, particle->getStatus(),
1130 (particle->getMother() ? particle->getMother()->getIndex() : 0), 0, particle->getFirstDaughter(), particle->getLastDaughter(),
1131 p.X(), p.Y(), p.Z(), particle->getEnergy(),
1132 vertex.X(), vertex.Y(), vertex.Z(), particle->getProductionTime());
1133 TEveMCTrack mctrack;
1134 mctrack = tparticle;
1135 mctrack.fTDecay = particle->getDecayTime();
1136 mctrack.fVDecay.Set(
B2Vector3D(particle->getDecayVertex()));
1137 mctrack.fDecayed = !std::isinf(mctrack.fTDecay);
1138 mctrack.fIndex = particle->getIndex();
1143 bool hasTrajectory(
false);
1144 for (
auto rel : mcTrajectories.relations()) {
1147 if (rel.weight <= 0)
continue;
1158 (&pt == &trajectory.
back()) ? TEvePathMark::kDecay : TEvePathMark::kReference,
1159 TEveVector(pt.x, pt.y, pt.z),
1160 TEveVector(pt.px, pt.py, pt.pz)
1164 hasTrajectory =
true;
1169 if (!hasTrajectory) {
1171 for (
int iDaughter = particle->getFirstDaughter(); iDaughter <= particle->getLastDaughter(); iDaughter++) {
1177 TEvePathMarkD refMark(TEvePathMarkD::kDaughter);
1178 refMark.fV.Set(
B2Vector3D(daughter->getProductionVertex()));
1179 refMark.fP.Set(
B2Vector3D(daughter->getMomentum()));
1180 refMark.fTime = daughter->getProductionTime();
1187 and mctrack.fDecayed) {
1188 TEvePathMarkD decayMark(TEvePathMarkD::kDecay);
1189 decayMark.fV.Set(
B2Vector3D(particle->getDecayVertex()));
1193 TString particle_name(mctrack.GetName());
1196 const MCParticle* mom = particle->getMother();
1203 if (!hasTrajectory) {
1206 title +=
"\n(track estimated from initial momentum)";
1252 MCTrack& mcTrack = mcTrackPair.second;
1253 if (mcTrack.
track) {
1254 if (mcTrack.
simhits->Size() > 0) {
1258 destroyEveElement(mcTrack.
simhits);
1265 parent = parentIt->second.track;
1268 parent->AddElement(mcTrack.
track);
1270 gEve->AddElement(mcTrack.
simhits);
1277 for (
size_t i = 0; i <
m_options.length(); i++) {
1284 m.SetMarkerStyle(1);
1316 if (groupPair.second.group)
1317 groupPair.second.visible = groupPair.second.group->GetRnrState();
1318 groupPair.second.group =
nullptr;
1330 float ecl_threshold = 0.01;
1332 ecl_threshold =
m_eclData->GetSliceThreshold(0);
1337 m_eclData->RefSliceInfo(0).Setup(
"ECL", ecl_threshold, kRed);
1343 gEve->GetSelection()->RemoveElements();
1344 gEve->GetHighlight()->RemoveElements();
1353 ROOT::Math::XYZVector v = ROOT::Math::XYZVector(vertex->getPos());
1358 vertexPoint->SetNextPoint(v.X(), v.Y(), v.Z());
1360 TMatrixDSymEigen eigen_values(vertex->getCov());
1362 det_shape->SetShape(
new TGeoSphere(0., 1.));
1363 fixGeoShapeRefCount(det_shape);
1364 const TVectorD& ev = eigen_values.GetEigenValues();
1365 const TMatrixD& eVec = eigen_values.GetEigenVectors();
1367 ROOT::Math::XYZVector eVec1(eVec(0, 0), eVec(1, 0), eVec(2, 0));
1369 ROOT::Math::XYZVector eVec2(eVec(0, 1), eVec(1, 1), eVec(2, 1));
1370 ROOT::Math::XYZVector eVec3(eVec(0, 2), eVec(1, 2), eVec(2, 2));
1374 TGeoRotation det_rot(
"det_rot", (eVec1.Theta() * 180) / TMath::Pi(), (eVec1.Phi() * 180) / TMath::Pi(),
1375 (eVec2.Theta() * 180) / TMath::Pi(), (eVec2.Phi() * 180) / TMath::Pi(),
1376 (eVec3.Theta() * 180) / TMath::Pi(), (eVec3.Phi() * 180) / TMath::Pi());
1380 double pseudo_res_0 = std::sqrt(ev(0));
1381 double pseudo_res_1 = std::sqrt(ev(1));
1382 double pseudo_res_2 = std::sqrt(ev(2));
1389 TGeoGenTrans det_trans(v.X(), v.Y(), v.Z(), pseudo_res_0, pseudo_res_1, pseudo_res_2,
1391 det_shape->SetTransMatrix(det_trans);
1394 det_shape->SetMainColor(kOrange);
1395 det_shape->SetMainTransparency(0);
1397 vertexPoint->AddElement(det_shape);
1409 const float phi = cluster->getPhi();
1410 float dPhi = cluster->getUncertaintyPhi();
1411 float dTheta = cluster->getUncertaintyTheta();
1412 if (dPhi >= M_PI / 4 or dTheta >= M_PI / 4 or cluster->getUncertaintyEnergy() == 1.0) {
1413 B2WARNING(
"Found ECL cluster with broken errors (unit matrix or too large). Using 0.05 as error in phi/theta. The 3x3 error matrix previously was:");
1414 cluster->getCovarianceMatrix3x3().Print();
1415 dPhi = dTheta = 0.05;
1418 if (!std::isfinite(dPhi) or !std::isfinite(dTheta)) {
1419 B2ERROR(
"ECLCluster phi or theta error is NaN or infinite, skipping cluster!");
1424 ROOT::Math::XYZVector thetaLow;
1425 VectorUtil::setPtThetaPhi(thetaLow, 1.0, cluster->getTheta() - dTheta, phi);
1426 ROOT::Math::XYZVector thetaHigh;
1427 VectorUtil::setPtThetaPhi(thetaHigh, 1.0, cluster->getTheta() + dTheta, phi);
1428 float etaLow = thetaLow.Eta();
1429 float etaHigh = thetaHigh.Eta();
1430 if (etaLow > etaHigh) {
1431 std::swap(etaLow, etaHigh);
1434 int id =
m_eclData->AddTower(etaLow, etaHigh, phi - dPhi, phi + dPhi);
1442 const double layerThicknessCm = 3.16;
1443 const double layerDistanceCm = 9.1 - layerThicknessCm;
1446 ROOT::Math::XYZVector position = cluster->getClusterPosition();
1447 ROOT::Math::XYZVector startPos(position.X(), position.Y(), position.Z());
1448 ROOT::Math::XYZVector dir;
1449 ROOT::Math::XYZVector a, b;
1450 bool isBarrel = (startPos.Z() > -175.0 and startPos.Z() < 270.0);
1453 b = ROOT::Math::XYZVector(0, 0, 1);
1454 a = startPos.Cross(b).Unit();
1455 double c = M_PI / 4.0;
1456 double offset = c / 2.0 + M_PI;
1457 VectorUtil::setPhi(a,
int((a.Phi() + offset) / (c))*c - M_PI);
1458 ROOT::Math::XYZVector perp = b.Cross(a);
1460 const double barrelRadiusCm = 204.0;
1461 VectorUtil::setMag(startPos, barrelRadiusCm / perp.Dot(startPos.Unit()));
1463 dir = startPos.Unit();
1464 VectorUtil::setMag(dir, (layerDistanceCm + layerThicknessCm) / perp.Dot(dir));
1467 b = ROOT::Math::XYZVector(startPos.X(), startPos.Y(), 0).Unit();
1468 a = startPos.Cross(b).Unit();
1469 double endcapStartZ = 284;
1470 if (startPos.Z() < 0)
1471 endcapStartZ = -189.5;
1473 double scaleFac = endcapStartZ / startPos.Z();
1474 VectorUtil::setMag(startPos, startPos.R() * scaleFac);
1476 dir = startPos.Unit();
1477 VectorUtil::setMag(dir, (layerDistanceCm + layerThicknessCm) / fabs(dir.Z()));
1480 for (
int i = 0; i < cluster->getLayers(); i++) {
1481 ROOT::Math::XYZVector layerPos = startPos;
1482 layerPos += (cluster->getInnermostLayer() + i) * dir;
1483 auto* layer =
boxCreator(layerPos, a, b, 20.0, 20.0, layerThicknessCm / 2);
1485 layer->SetMainTransparency(70);
1499 CLHEP::Hep3Vector global;
1506 CLHEP::Hep3Vector local = module->globalToLocal(global);
1511 double du = module->getPhiStripWidth() * Nphistrip;
1512 double dv = module->getZStripWidth() * Nztrip;
1515 CLHEP::Hep3Vector localU(local[0], local[1] + 1.0, local[2]);
1516 CLHEP::Hep3Vector localV(local[0], local[1], local[2] + 1.0);
1518 CLHEP::Hep3Vector globalU = module->localToGlobal(localU);
1519 CLHEP::Hep3Vector globalV = module->localToGlobal(localV);
1521 ROOT::Math::XYZVector o(global[0], global[1], global[2]);
1522 ROOT::Math::XYZVector u(globalU[0], globalU[1], globalU[2]);
1523 ROOT::Math::XYZVector v(globalV[0], globalV[1], globalV[2]);
1526 TEveBox* bklmbox =
boxCreator(o, u - o, v - o, du, dv, 1.0);
1528 bklmbox->SetMainColor(kGreen);
1530 bklmbox->SetName(
"BKLMHit2d");
1538 const double du = 2.0;
1539 const double dv = 2.0;
1540 ROOT::Math::XYZVector hitPosition = eklm2dhit->
getPosition();
1541 ROOT::Math::XYZVector o(hitPosition.X(), hitPosition.Y(), hitPosition.Z());
1542 ROOT::Math::XYZVector u(1.0, 0.0, 0.0);
1543 ROOT::Math::XYZVector v(0.0, 1.0, 0.0);
1544 TEveBox* eklmbox =
boxCreator(o, u, v, du, dv, 4.0);
1545 eklmbox->SetMainColor(kGreen);
1546 eklmbox->SetName(
"EKLMHit2d");
1555 VxdID sensorID = roi->getSensorID();
1558 double minU = aSensorInfo.
getUCellPosition(roi->getMinUid(), roi->getMinVid());
1560 double maxU = aSensorInfo.
getUCellPosition(roi->getMaxUid(), roi->getMaxVid());
1564 ROOT::Math::XYZVector localA(minU, minV, 0);
1565 ROOT::Math::XYZVector localB(minU, maxV, 0);
1566 ROOT::Math::XYZVector localC(maxU, minV, 0);
1568 ROOT::Math::XYZVector globalA = aSensorInfo.
pointToGlobal(localA);
1569 ROOT::Math::XYZVector globalB = aSensorInfo.
pointToGlobal(localB);
1570 ROOT::Math::XYZVector globalC = aSensorInfo.
pointToGlobal(localC);
1572 TEveBox* ROIbox =
boxCreator(globalB + globalC * 0.5, globalB - globalA, globalC - globalA, 1, 1, 0.01);
1575 ROIbox->SetMainColor(kSpring - 9);
1576 ROIbox->SetMainTransparency(50);
1587 ROOT::Math::XYZVector a, b;
1588 if (hit->isUCluster()) {
1589 const float u = hit->getPosition();
1590 a = sensor.pointToGlobal(ROOT::Math::XYZVector(sensor.getBackwardWidth() / sensor.getWidth(0) * u, -0.5 * sensor.getLength(), 0.0));
1591 b = sensor.pointToGlobal(ROOT::Math::XYZVector(sensor.getForwardWidth() / sensor.getWidth(0) * u, +0.5 * sensor.getLength(), 0.0));
1593 const float v = hit->getPosition();
1594 a = sensor.pointToGlobal(ROOT::Math::XYZVector(-0.5 * sensor.getWidth(v), v, 0.0));
1595 b = sensor.pointToGlobal(ROOT::Math::XYZVector(+0.5 * sensor.getWidth(v), v, 0.0));
1598 lines->AddLine(a.X(), a.Y(), a.Z(), b.X(), b.Y(), b.Z());
1608 lines->AddLine(wire_pos_f.X(), wire_pos_f.Y(), wire_pos_f.Z(), wire_pos_b.X(), wire_pos_b.Y(), wire_pos_b.Z());
1619 TEveGeoShape* cov_shape =
new TEveGeoShape(
"cov_shape");
1623 driftLengthRes = std::max(driftLengthRes, 0.005);
1624 const double lengthOfWireSection = 3.0;
1627 const B2Vector3D zaxis = wire_pos_b - wire_pos_f;
1632 const B2Vector3D midPoint = wire_pos_f - zaxis * (wire_pos_f.
Z() / zaxis.
Z());
1634 cov_shape->SetShape(
new TGeoTube(std::max(0., (
double)(driftLength - driftLengthRes)), driftLength + driftLengthRes,
1635 lengthOfWireSection));
1636 fixGeoShapeRefCount(cov_shape);
1638 TGeoRotation det_rot(
"det_rot",
1639 xaxis.
Theta() * 180 / TMath::Pi(), xaxis.
Phi() * 180 / TMath::Pi(),
1640 yaxis.
Theta() * 180 / TMath::Pi(), yaxis.
Phi() * 180 / TMath::Pi(),
1641 zaxis.
Theta() * 180 / TMath::Pi(), zaxis.
Phi() * 180 / TMath::Pi()
1644 TGeoCombiTrans det_trans(midPoint.
X(), midPoint.
Y(), midPoint.
Z(), &det_rot);
1645 cov_shape->SetTransMatrix(det_trans);
1648 bool isPartOfTS =
false;
1650 if (showTriggerHits && segments.size() > 0) {
1654 if (hit->getISuperLayer() % 2 == 0) {
1656 cov_shape->SetMainColor(kCyan + 3);
1658 cov_shape->SetMainColor(kCyan);
1661 cov_shape->SetMainColor(kPink + 6);
1663 cov_shape->SetMainColor(kPink + 7);
1666 cov_shape->SetMainTransparency(50);
1668 cov_shape->SetTitle(
ObjectInfo::getInfo(hit) + TString::Format(
"\nWire ID: %d\nADC: %d\nTDC: %d",
1669 hit->getID(), hit->getADCCount(), hit->getTDCCount()));
1674 addToGroup(
"CDCTriggerSegmentHits", cov_shape);
1675 for (
auto rel : segments.relations()) {
1684 TEveStraightLineSet* shape =
new TEveStraightLineSet();
1688 if (hit->getPriorityPosition() < 3) iL -= 1;
1690 unsigned iCenter = hit->getIWire();
1691 if (hit->getPriorityPosition() == 1) iCenter += 1;
1702 std::vector<int> layershift = { -2, -1, 0, 1, 2};
1703 std::vector<std::vector<float>> cellshift = {
1717 if (hit->getISuperLayer() == 0) {
1718 layershift = { 0, 1, 2, 3, 4};
1723 { -1.5, -0.5, 0.5, 1.5},
1729 for (
unsigned il = 0; il < layershift.size(); ++il) {
1730 for (
unsigned ic = 0; ic < cellshift[il].size(); ++ic) {
1731 ROOT::Math::XYZVector corners[2][2];
1732 for (
unsigned ir = 0; ir < 2; ++ir) {
1733 double r = cdcgeo.
fieldWireR(iL + layershift[il] - ir);
1734 double fz = cdcgeo.
fieldWireFZ(iL + layershift[il] - ir);
1735 double bz = cdcgeo.
fieldWireBZ(iL + layershift[il] - ir);
1736 for (
unsigned iphi = 0; iphi < 2; ++iphi) {
1737 double phib = (iCenter + cellshift[il][ic] + iphi - 0.5) * 2 * M_PI / nWires;
1738 double phif = phib + cdcgeo.
nShifts(iL + layershift[il]) * M_PI / nWires;
1740 ROOT::Math::XYZVector pos_f = ROOT::Math::XYZVector(cos(phif) * r, sin(phif) * r, fz);
1741 ROOT::Math::XYZVector pos_b = ROOT::Math::XYZVector(cos(phib) * r, sin(phib) * r, bz);
1742 ROOT::Math::XYZVector zaxis = pos_b - pos_f;
1743 corners[ir][iphi] = pos_f - zaxis * (pos_f.Z() / zaxis.Z());
1747 shape->AddLine(corners[0][0].X(), corners[0][0].Y(), 0,
1748 corners[0][1].X(), corners[0][1].Y(), 0);
1749 shape->AddLine(corners[0][1].X(), corners[0][1].Y(), 0,
1750 corners[1][1].X(), corners[1][1].Y(), 0);
1751 shape->AddLine(corners[1][1].X(), corners[1][1].Y(), 0,
1752 corners[1][0].X(), corners[1][0].Y(), 0);
1753 shape->AddLine(corners[1][0].X(), corners[1][0].Y(), 0,
1754 corners[0][0].X(), corners[0][0].Y(), 0);
1758 if (hit->getISuperLayer() % 2 == 0) {
1759 shape->SetMainColor(kCyan + 3);
1761 shape->SetMainColor(kPink + 6);
1766 TString::Format(
"\nPriority: %d\nLeft/Right: %d",
1767 hit->getPriorityPosition(), hit->getLeftRight()));
1776 int hitModule = hit->getModule();
1777 float fi = arichGeo->getDetectorPlane().getSlotPhi(hitModule);
1779 ROOT::Math::XYZVector centerPos3D = hit->getPosition();
1781 ROOT::Math::RotationZ rotZ(fi);
1782 ROOT::Math::XYZVector channelX(1, 0, 0);
1783 ROOT::Math::XYZVector channelY(0, 1, 0);
1784 channelX = rotZ * channelX;
1785 channelY = rotZ * channelY;
1788 arichGeo->getMasterVolume().momentumToGlobal(channelX),
1789 arichGeo->getMasterVolume().momentumToGlobal(channelY),
1791 arichbox->SetMainColor(kOrange + 10);
1792 arichbox->SetName((std::to_string(hitModule)).c_str());
1801 std::map<int, int> m_topSummary;
1802 for (
const TOPDigit& hit : digits) {
1803 int mod = hit.getModuleID();
1804 ++m_topSummary[mod];
1807 for (
auto modCountPair : m_topSummary) {
1808 if (modCountPair.second > maxcount)
1809 maxcount = modCountPair.second;
1811 for (
auto modCountPair : m_topSummary) {
1813 double phi = topmod.getPhi();
1814 double r_center = topmod.getRadius();
1815 double z = topmod.getZc();
1817 ROOT::Math::XYZVector centerPos3D;
1818 VectorUtil::setMagThetaPhi(centerPos3D, r_center, M_PI / 2, phi);
1819 centerPos3D.SetZ(z);
1825 auto* moduleBox =
boxCreator(centerPos3D, channelX, channelY,
1826 3.0 * topmod.getBarThickness(), topmod.getBarWidth(), topmod.getBarLength());
1827 moduleBox->SetMainColor(kAzure + 10);
1828 double weight = double(modCountPair.second) / maxcount;
1829 moduleBox->SetMainTransparency(90 - weight * 50);
1830 moduleBox->SetName((
"TOP module " + std::to_string(modCountPair.first)).c_str());
1831 moduleBox->SetTitle(TString::Format(
"#TOPDigits: %d ", modCountPair.second));
1835 for (
const TOPDigit& hit : digits) {
1836 if (modCountPair.first == hit.getModuleID())
1845 for (
const auto& labelPair : displayData.
m_labels) {
1846 TEveText* text =
new TEveText(labelPair.first.c_str());
1847 text->SetName(labelPair.first.c_str());
1848 text->SetTitle(labelPair.first.c_str());
1849 text->SetMainColor(kGray + 1);
1850 const ROOT::Math::XYZVector& p = labelPair.second;
1851 text->PtrMainTrans()->SetPos(p.X(), p.Y(), p.Z());
1855 for (
const auto& pointPair : displayData.
m_pointSets) {
1856 TEvePointSet* points =
new TEvePointSet(pointPair.first.c_str());
1857 points->SetTitle(pointPair.first.c_str());
1858 points->SetMarkerStyle(7);
1859 points->SetMainColor(kGreen);
1860 for (
const auto& p : pointPair.second) {
1861 points->SetNextPoint(p.X(), p.Y(), p.Z());
1866 int randomColor = 2;
1867 for (
const auto& arrow : displayData.
m_arrows) {
1868 const ROOT::Math::XYZVector pos = arrow.start;
1869 const ROOT::Math::XYZVector dir = arrow.end - pos;
1870 TEveArrow* eveArrow =
new TEveArrow(dir.X(), dir.Y(), dir.Z(), pos.X(), pos.Y(), pos.Z());
1871 eveArrow->SetName(arrow.name.c_str());
1872 eveArrow->SetTitle(arrow.name.c_str());
1873 int arrowColor = arrow.color;
1874 if (arrowColor == -1) {
1875 arrowColor = randomColor;
1878 eveArrow->SetMainColor(arrowColor);
1881 TEveText* text =
new TEveText(arrow.name.c_str());
1882 text->SetMainColor(arrowColor);
1885 ROOT::Math::XYZVector orthogonalDir;
1886 if (std::abs(dir.X()) < std::abs(dir.Y())) {
1887 if (std::abs(dir.X()) < std::abs(dir.Z())) {
1888 orthogonalDir.SetCoordinates(0, dir.Z(), -dir.Y());
1890 orthogonalDir.SetCoordinates(dir.Y(), -dir.X(), 0);
1893 if (std::abs(dir.Y()) < std::abs(dir.Z())) {
1894 orthogonalDir.SetCoordinates(-dir.Z(), 0, dir.X());
1896 orthogonalDir.SetCoordinates(dir.Y(), -dir.X(), 0);
1899 const ROOT::Math::XYZVector& labelPos = pos + 0.5 * dir + 0.1 * orthogonalDir;
1900 text->PtrMainTrans()->SetPos(labelPos.X(), labelPos.Y(), labelPos.Z());
1901 eveArrow->AddElement(text);
1914 const std::string& groupName = boost::algorithm::trim_copy_if(name, boost::algorithm::is_any_of(
"/"));
1916 TEveElementList* group =
m_groups[groupName].group;
1918 group =
new TEveElementList(groupName.c_str(), groupName.c_str());
1919 group->SetRnrState(
m_groups[groupName].visible);
1924 auto lastSlash = boost::algorithm::find_last(groupName,
"/");
1926 const std::string parentGroup(groupName.begin(), lastSlash.begin());
1927 const std::string thisGroup(lastSlash.end(), groupName.end());
1928 group->SetElementName(thisGroup.c_str());
1931 gEve->AddElement(group);
1934 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 the 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.