20 #include <display/EVEVisualization.h>
22 #include <display/VisualRepMap.h>
23 #include <display/EveGeometry.h>
24 #include <display/EveVisBField.h>
25 #include <display/ObjectInfo.h>
27 #include <vxd/geometry/GeoCache.h>
28 #include <klm/dataobjects/bklm/BKLMSimHitPosition.h>
29 #include <klm/dataobjects/bklm/BKLMHit2d.h>
30 #include <klm/bklm/geometry/GeometryPar.h>
31 #include <cdc/geometry/CDCGeometryPar.h>
32 #include <cdc/dataobjects/CDCRecoHit.h>
33 #include <cdc/translators/RealisticTDCCountTranslator.h>
34 #include <arich/dbobjects/ARICHGeometryConfig.h>
35 #include <simulation/dataobjects/MCParticleTrajectory.h>
36 #include <svd/reconstruction/SVDRecoHit.h>
37 #include <top/geometry/TOPGeometryPar.h>
39 #include <genfit/AbsMeasurement.h>
40 #include <genfit/PlanarMeasurement.h>
41 #include <genfit/SpacepointMeasurement.h>
42 #include <genfit/WireMeasurement.h>
43 #include <genfit/WireMeasurementNew.h>
44 #include <genfit/WirePointMeasurement.h>
45 #include <genfit/DetPlane.h>
46 #include <genfit/Exception.h>
47 #include <genfit/KalmanFitterInfo.h>
48 #include <genfit/GblFitterInfo.h>
50 #include <framework/dataobjects/DisplayData.h>
51 #include <framework/logging/Logger.h>
52 #include <framework/utilities/ColorPalette.h>
54 #include <TEveArrow.h>
57 #include <TEveManager.h>
58 #include <TEveGeoShape.h>
60 #include <TEvePointSet.h>
61 #include <TEveSelection.h>
62 #include <TEveStraightLineSet.h>
63 #include <TEveTriangleSet.h>
65 #include <TEveTrack.h>
66 #include <TEveTrackPropagator.h>
68 #include <TGeoMatrix.h>
69 #include <TGeoManager.h>
70 #include <TGeoSphere.h>
72 #include <TGLLogicalShape.h>
73 #include <TParticle.h>
77 #include <TMatrixDSymEigen.h>
79 #include <boost/math/special_functions/fpclassify.hpp>
80 #include <boost/scoped_ptr.hpp>
81 #include <boost/algorithm/string/find.hpp>
82 #include <boost/algorithm/string/trim.hpp>
83 #include <boost/algorithm/string/classification.hpp>
93 template <
class T>
void destroyEveElement(T*& el)
96 if (el->GetDenyDestroy() > 1)
97 B2WARNING(
"destroyEveElement(): Element " << el->GetName() <<
" has unexpected refcount " << el->GetDenyDestroy());
109 void fixGeoShapeRefCount(TEveGeoShape* eveshape)
111 TGeoShape* s = eveshape->GetShape();
113 if (gGeoManager->GetListOfShapes()->Last() == s)
114 gGeoManager->GetListOfShapes()->RemoveAt(gGeoManager->GetListOfShapes()->GetLast());
116 gGeoManager->GetListOfShapes()->Remove(s);
128 m_assignToPrimaries(false),
134 TGLLogicalShape::SetIgnoreSizeForCameraInterest(kTRUE);
160 m_calo3d =
new TEveCalo3D(NULL,
"ECLClusters");
162 m_calo3d->SetForwardEndCapPos(196.5);
163 m_calo3d->SetBackwardEndCapPos(-102.0);
165 m_calo3d->SetRnrFrame(
false,
false);
169 gEve->GetSelection()->IncDenyDestroy();
170 gEve->GetHighlight()->IncDenyDestroy();
200 bool drawHits =
false;
203 for (
size_t i = 0; i <
m_options.length(); i++) {
204 if (
m_options.at(i) ==
'H') drawHits =
true;
214 TEveStraightLineSet* lines =
new TEveStraightLineSet(
"RecoHits for " + label);
217 lines->SetMarkerStyle(6);
218 lines->SetMainTransparency(60);
235 TEveRecTrack rectrack;
236 rectrack.fP.Set(track_mom);
237 rectrack.fV.Set(track_pos);
240 track_lines->SetName(label);
243 track_lines->SetLineWidth(1);
249 track_lines->AddElement(lines);
259 bool drawHits =
false;
262 for (
size_t i = 0; i <
m_options.length(); i++) {
263 if (
m_options.at(i) ==
'H') drawHits =
true;
270 TEveLine* track =
new TEveLine();
271 std::vector<TVector3> posPoints;
272 track->SetName(label);
274 track->SetLineWidth(3);
276 track->SetSmooth(
true);
280 if (!recoHit->useInFit())
290 if (not fittedResult) {
291 B2WARNING(
"Skipping unfitted track point");
295 state.getPosMomCov(pos, mom, cov);
297 B2WARNING(
"Skipping state with strange pos, mom or cov");
301 posPoints.push_back(TVector3(pos.X(), pos.Y(), pos.Z()));
304 sort(posPoints.begin(), posPoints.end(),
305 [](
const TVector3 & a,
const TVector3 & b) ->
bool {
306 return a.X() * a.X() + a.Y() * a.Y() > b.X() * b.X() + b.Y() * b.Y();
308 for (
auto vec : posPoints) {
309 track->SetNextPoint(vec.X(), vec.Y(), vec.Z());
312 TEveStraightLineSet* lines =
new TEveStraightLineSet(
"RecoHits for " + label);
315 lines->SetMarkerStyle(6);
316 lines->SetMainTransparency(60);
333 track->AddElement(lines);
343 TVector3 track_pos = TVector3(0, 0, trgTrack.getZ0());
344 TVector3 track_mom = (trgTrack.getChargeSign() == 0) ?
345 trgTrack.getDirection() * 1000 :
346 trgTrack.getMomentum(1.5);
348 TEveRecTrack rectrack;
349 rectrack.fP.Set(track_mom);
350 rectrack.fV.Set(track_pos);
353 track_lines->SetName(label);
355 track_lines->SetLineColor(kOrange + 2);
356 track_lines->SetLineWidth(1);
358 TString::Format(
"\ncharge: %d, phi: %.2fdeg, pt: %.2fGeV, theta: %.2fdeg, z: %.2fcm",
359 trgTrack.getChargeSign(),
360 trgTrack.getPhi0() * 180 / M_PI,
361 trgTrack.getTransverseMomentum(1.5),
362 trgTrack.getDirection().Theta() * 180 / M_PI,
366 track_lines->SetCharge(trgTrack.getChargeSign());
369 if (trgTrack.getZ0() == 0 && trgTrack.getCotTheta() == 0)
370 track_lines->SetLineStyle(2);
382 B2ERROR(
"Track without TrackFitResult skipped.");
390 bool drawDetectors =
false;
391 bool drawHits =
false;
392 bool drawPlanes =
false;
395 for (
size_t i = 0; i <
m_options.length(); i++) {
396 if (
m_options.at(i) ==
'D') drawDetectors =
true;
397 if (
m_options.at(i) ==
'H') drawHits =
true;
398 if (
m_options.at(i) ==
'P') drawPlanes =
true;
406 bool isPruned = (track ==
nullptr);
409 TEveRecTrackD recTrack;
411 recTrack.fV.Set(poca);
413 const TVector3& poca_momentum = fitResult->
getMomentum();
414 if (std::isfinite(poca_momentum.Mag()))
415 recTrack.fP.Set(poca_momentum);
417 recTrack.fP.Set(fitResult->
getHelix().getDirection() * 1000);
421 eveTrack->SetName(label);
428 representation = track->getCardinalRepresentation();
429 B2DEBUG(100,
"Draw cardinal rep");
431 const auto& representations = track->getRepresentations();
432 if (representations.empty()) {
433 B2ERROR(
"No representations found in the reco track!");
436 B2DEBUG(100,
"Draw representation number 0.");
437 representation = representations.front();
440 if (!track->hasTrackFitStatus(representation)) {
441 B2ERROR(
"RecoTrack without FitStatus: will be skipped!");
459 const auto& hitPoints = track->getHitPointsWithMeasurement();
460 const unsigned int numpoints = hitPoints.size();
467 if (! tp->hasFitterInfo(representation)) {
468 B2ERROR(
"trackPoint has no fitterInfo for rep");
478 B2ERROR(
"Can only display KalmanFitterInfo or GblFitterInfo");
483 B2FATAL(
"AbsFitterInfo dynamic-casted to both KalmanFitterInfo and GblFitterInfo!");
486 if (fi && ! tp->hasRawMeasurements()) {
487 B2ERROR(
"trackPoint has no raw measurements");
491 if (fi && ! fi->hasPredictionsAndUpdates()) {
492 B2ERROR(
"KalmanFitterInfo does not have all predictions and updates");
500 fittedState = &(fi->getFittedState(
true));
502 B2ERROR(e.what() <<
" - can not get fitted state");
506 TVector3 track_pos = representation->
getPos(*fittedState);
509 if (prevFittedState != NULL) {
511 TEvePathMark::EType_e markType = TEvePathMark::kReference;
512 if (hitCounter + 1 ==
static_cast<int>(numpoints))
513 markType = TEvePathMark::kDecay;
524 makeLines(eveTrack, prevFi->getForwardUpdate(), fi->getForwardPrediction(), representation, markType,
m_drawErrors, 0);
526 makeLines(eveTrack, prevFi->getBackwardPrediction(), fi->getBackwardUpdate(), representation, markType,
m_drawErrors);
528 if (
m_drawRefTrack && fi->hasReferenceState() && prevFi->hasReferenceState())
529 makeLines(eveTrack, prevFi->getReferenceState(), fi->getReferenceState(), representation, markType,
false);
533 if (gfi && prevGFi) {
539 if (
m_drawRefTrack && gfi->hasReferenceState() && prevGFi->hasReferenceState()) {
542 makeLines(eveTrack, &prevSop, &sop, representation, markType,
false);
549 prevFittedState = fittedState;
553 const int numMeasurements = tp->getNumRawMeasurements();
554 for (
int iMeasurement = 0; iMeasurement < numMeasurements; iMeasurement++) {
557 TVectorT<double> hit_coords;
558 TMatrixTSym<double> hit_cov;
563 hit_coords.ResizeTo(mop->getState());
564 hit_cov.ResizeTo(mop->getCov());
565 hit_coords = mop->getState();
566 hit_cov = mop->getCov();
573 hit_coords.ResizeTo(gblMeas.getState());
574 hit_cov.ResizeTo(gblMeas.getCov());
575 hit_coords = gblMeas.getState();
576 hit_cov = gblMeas.getCov();
582 TVector3 o = fittedState->getPlane()->getO();
583 TVector3 u = fittedState->getPlane()->getU();
584 TVector3 v = fittedState->getPlane()->getV();
586 bool planar_hit =
false;
587 bool planar_pixel_hit =
false;
588 bool space_hit =
false;
589 bool wire_hit =
false;
590 bool wirepoint_hit =
false;
593 double_t plane_size = 4;
595 int hit_coords_dim = m->getDim();
599 if (hit_coords_dim == 1) {
600 hit_u = hit_coords(0);
601 }
else if (hit_coords_dim == 2) {
602 planar_pixel_hit =
true;
603 hit_u = hit_coords(0);
604 hit_v = hit_coords(1);
613 hit_u = fabs(hit_coords(0));
614 hit_v = v * (track_pos - o);
617 wirepoint_hit =
true;
618 hit_v = hit_coords(1);
621 B2ERROR(
"Hit " << hitCounter <<
", Measurement " << iMeasurement <<
": Unknown measurement type: skipping hit!");
625 if (plane_size < 4) plane_size = 4;
629 if (drawPlanes || (drawDetectors && planar_hit)) {
630 TVector3 move(0, 0, 0);
631 if (wire_hit) move = v * (v * (track_pos - o));
632 TEveBox* box =
boxCreator(o + move, u, v, plane_size, plane_size, 0.01);
633 if (drawDetectors && planar_hit) {
634 box->SetMainColor(kCyan);
636 box->SetMainColor(kGray);
638 box->SetMainTransparency(50);
639 eveTrack->AddElement(box);
647 TEveGeoShape* det_shape =
new TEveGeoShape(
"det_shape");
648 det_shape->SetShape(
new TGeoTube(std::max(0., (
double)(hit_u - 0.0105 / 2.)), hit_u + 0.0105 / 2., plane_size));
649 fixGeoShapeRefCount(det_shape);
651 TVector3 norm = u.Cross(v);
652 TGeoRotation det_rot(
"det_rot", (u.Theta() * 180) / TMath::Pi(), (u.Phi() * 180) / TMath::Pi(),
653 (norm.Theta() * 180) / TMath::Pi(), (norm.Phi() * 180) / TMath::Pi(),
654 (v.Theta() * 180) / TMath::Pi(), (v.Phi() * 180) / TMath::Pi());
655 TVector3 move = v * (v * (track_pos - o));
656 TGeoCombiTrans det_trans(o(0) + move.X(),
660 det_shape->SetTransMatrix(det_trans);
661 det_shape->SetMainColor(kCyan);
662 det_shape->SetMainTransparency(25);
663 if ((drawHits && (hit_u + 0.0105 / 2 > 0)) || !drawHits) {
664 eveTrack->AddElement(det_shape);
675 if (!planar_pixel_hit) {
680 B2WARNING(
"SVD recohit couldn't be converted... ");
687 double hit_res_u = hit_cov(0, 0);
688 if (recoHit->
isU()) {
689 du = std::sqrt(hit_res_u);
690 dv = sensor.getLength();
693 du = sensor.getWidth();
694 dv = std::sqrt(hit_res_u);
697 double depth = sensor.getThickness();
698 TEveBox* hit_box =
boxCreator(a, u, v, du, dv, depth);
699 hit_box->SetName(
"SVDRecoHit");
701 hit_box->SetMainTransparency(0);
702 eveTrack->AddElement(hit_box);
706 TMatrixDSymEigen eigen_values(hit_cov);
707 TEveGeoShape* cov_shape =
new TEveGeoShape(
"PXDRecoHit");
708 const TVectorD& ev = eigen_values.GetEigenValues();
709 const TMatrixD& eVec = eigen_values.GetEigenVectors();
715 cov_shape->SetShape(
new TGeoEltu(pseudo_res_0, pseudo_res_1, 0.0105));
716 fixGeoShapeRefCount(cov_shape);
717 TVector3 pix_pos = o + hit_u * u + hit_v * v;
718 TVector3 u_semiaxis = (pix_pos + eVec(0, 0) * u + eVec(1, 0) * v) - pix_pos;
719 TVector3 v_semiaxis = (pix_pos + eVec(0, 1) * u + eVec(1, 1) * v) - pix_pos;
720 TVector3 norm = u.Cross(v);
724 TGeoRotation det_rot(
"det_rot", (u_semiaxis.Theta() * 180) / TMath::Pi(), (u_semiaxis.Phi() * 180) / TMath::Pi(),
725 (v_semiaxis.Theta() * 180) / TMath::Pi(), (v_semiaxis.Phi() * 180) / TMath::Pi(),
726 (norm.Theta() * 180) / TMath::Pi(), (norm.Phi() * 180) / TMath::Pi());
727 TGeoCombiTrans det_trans(pix_pos(0), pix_pos(1), pix_pos(2), &det_rot);
728 cov_shape->SetTransMatrix(det_trans);
732 cov_shape->SetMainTransparency(0);
733 eveTrack->AddElement(cov_shape);
742 TMatrixDSymEigen eigen_values(m->getRawHitCov());
743 TEveGeoShape* cov_shape =
new TEveGeoShape(
"SpacePoint Hit");
744 cov_shape->SetShape(
new TGeoSphere(0., 1.));
745 fixGeoShapeRefCount(cov_shape);
746 const TVectorD& ev = eigen_values.GetEigenValues();
747 const TMatrixD& eVec = eigen_values.GetEigenVectors();
748 TVector3 eVec1(eVec(0, 0), eVec(1, 0), eVec(2, 0));
749 TVector3 eVec2(eVec(0, 1), eVec(1, 1), eVec(2, 1));
750 TVector3 eVec3(eVec(0, 2), eVec(1, 2), eVec(2, 2));
751 TVector3 norm = u.Cross(v);
755 TGeoRotation det_rot(
"det_rot", (eVec1.Theta() * 180) / TMath::Pi(), (eVec1.Phi() * 180) / TMath::Pi(),
756 (eVec2.Theta() * 180) / TMath::Pi(), (eVec2.Phi() * 180) / TMath::Pi(),
757 (eVec3.Theta() * 180) / TMath::Pi(), (eVec3.Phi() * 180) / TMath::Pi());
766 TGeoGenTrans det_trans(o(0), o(1), o(2),
769 pseudo_res_0, pseudo_res_1, pseudo_res_2,
771 cov_shape->SetTransMatrix(det_trans);
775 cov_shape->SetMainTransparency(10);
776 eveTrack->AddElement(cov_shape);
782 const double cdcErrorScale = 1.0;
783 TEveGeoShape* cov_shape =
new TEveGeoShape(
"CDCRecoHit");
784 double pseudo_res_0 = cdcErrorScale * std::sqrt(hit_cov(0, 0));
785 double pseudo_res_1 = plane_size;
786 if (wirepoint_hit) pseudo_res_1 = cdcErrorScale * std::sqrt(hit_cov(1, 1));
788 cov_shape->SetShape(
new TGeoTube(std::max(0., (
double)(hit_u - pseudo_res_0)), hit_u + pseudo_res_0, pseudo_res_1));
789 fixGeoShapeRefCount(cov_shape);
790 TVector3 norm = u.Cross(v);
793 TGeoRotation det_rot(
"det_rot", (u.Theta() * 180) / TMath::Pi(), (u.Phi() * 180) / TMath::Pi(),
794 (norm.Theta() * 180) / TMath::Pi(), (norm.Phi() * 180) / TMath::Pi(),
795 (v.Theta() * 180) / TMath::Pi(), (v.Phi() * 180) / TMath::Pi());
796 TGeoCombiTrans det_trans(o(0) + hit_v * v.X(),
797 o(1) + hit_v * v.Y(),
798 o(2) + hit_v * v.Z(),
800 cov_shape->SetTransMatrix(det_trans);
804 cov_shape->SetMainTransparency(50);
805 eveTrack->AddElement(cov_shape);
813 auto& firstref = eveTrack->RefPathMarks().front();
814 auto& lastref = eveTrack->RefPathMarks().back();
815 double f = firstref.fV.Distance(recTrack.fV);
816 double b = lastref.fV.Distance(recTrack.fV);
817 if (f > 100 and f > b) {
818 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)");
820 lastref.fType = TEvePathMarkD::kReference;
821 firstref.fType = TEvePathMarkD::kDecay;
822 std::reverse(eveTrack->RefPathMarks().begin(), eveTrack->RefPathMarks().end());
825 eveTrack->SetTitle(TString::Format(
"%s\n"
830 isPruned ?
" yes" :
"no",
831 poca_momentum.Pt(), poca_momentum.Pz(),
835 eveTrack->SetLineStyle(1);
836 eveTrack->SetLineWidth(3.0);
856 TEveBox* box =
new TEveBox;
857 box->SetPickable(
true);
859 TVector3 norm = u.Cross(v);
862 norm *= (0.5 * depth);
865 for (
int k = 0; k < 8; ++k) {
868 int signU = ((k + 1) & 2) ? -1 : 1;
869 int signV = (k & 4) ? -1 : 1;
870 int signN = (k & 2) ? -1 : 1;
872 for (
int i = 0; i < 3; ++i) {
873 vertex[i] = o(i) + signU * u(i) + signV * v(i) + signN * norm(i);
875 box->SetVertex(k, vertex);
883 TEvePathMark::EType_e markType,
bool drawErrors,
int markerPos)
887 TVector3 pos, dir, oldPos, oldDir;
889 rep->
getPosDir(*prevState, oldPos, oldDir);
891 double distA = (pos - oldPos).Mag();
892 double distB = distA;
893 if ((pos - oldPos)*oldDir < 0)
895 if ((pos - oldPos)*dir < 0)
900 TEveVector(pos(0), pos(1), pos(2)),
901 TEveVector(dir(0), dir(1), dir(2))
903 eveTrack->AddPathMark(mark);
913 if (measuredState != NULL) {
918 eval = 0.2 * distA * oldDir;
920 eval = -0.2 * distB * dir;
925 TVector3 position, direction;
926 rep->
getPosMomCov(*measuredState, position, direction, cov);
929 TMatrixDSymEigen eigen_values(cov.GetSub(0, 2, 0, 2));
930 const TVectorD& ev = eigen_values.GetEigenValues();
931 const TMatrixD& eVec = eigen_values.GetEigenVectors();
932 TVector3 eVec1, eVec2;
934 static const double maxErr = 1000.;
935 double ev0 = std::min(ev(0), maxErr);
936 double ev1 = std::min(ev(1), maxErr);
937 double ev2 = std::min(ev(2), maxErr);
940 if (ev0 < ev1 && ev0 < ev2) {
941 eVec1.SetXYZ(eVec(0, 1), eVec(1, 1), eVec(2, 1));
943 eVec2.SetXYZ(eVec(0, 2), eVec(1, 2), eVec(2, 2));
945 }
else if (ev1 < ev0 && ev1 < ev2) {
946 eVec1.SetXYZ(eVec(0, 0), eVec(1, 0), eVec(2, 0));
948 eVec2.SetXYZ(eVec(0, 2), eVec(1, 2), eVec(2, 2));
951 eVec1.SetXYZ(eVec(0, 0), eVec(1, 0), eVec(2, 0));
953 eVec2.SetXYZ(eVec(0, 1), eVec(1, 1), eVec(2, 1));
957 if (eVec1.Cross(eVec2)*
eval < 0)
961 TVector3 oldEVec1(eVec1);
963 const int nEdges = 24;
964 std::vector<TVector3> vertices;
966 vertices.push_back(position);
969 for (
int i = 0; i < nEdges; ++i) {
970 const double angle = 2 * TMath::Pi() / nEdges * i;
971 vertices.push_back(position + cos(angle)*eVec1 + sin(angle)*eVec2);
977 newPlane->setO(position +
eval);
992 TMatrixDSymEigen eigen_values2(cov.GetSub(0, 2, 0, 2));
993 const TVectorD& eVal = eigen_values2.GetEigenValues();
994 const TMatrixD& eVect = eigen_values2.GetEigenVectors();
996 ev0 = std::min(eVal(0), maxErr);
997 ev1 = std::min(eVal(1), maxErr);
998 ev2 = std::min(eVal(2), maxErr);
1001 if (ev0 < ev1 && ev0 < ev2) {
1002 eVec1.SetXYZ(eVect(0, 1), eVect(1, 1), eVect(2, 1));
1004 eVec2.SetXYZ(eVect(0, 2), eVect(1, 2), eVect(2, 2));
1006 }
else if (ev1 < ev0 && ev1 < ev2) {
1007 eVec1.SetXYZ(eVect(0, 0), eVect(1, 0), eVect(2, 0));
1009 eVec2.SetXYZ(eVect(0, 2), eVect(1, 2), eVect(2, 2));
1012 eVec1.SetXYZ(eVect(0, 0), eVect(1, 0), eVect(2, 0));
1014 eVec2.SetXYZ(eVect(0, 1), eVect(1, 1), eVect(2, 1));
1015 } eVec2 *= sqrt(ev1);
1018 if (eVec1.Cross(eVec2)*
eval < 0)
1022 if (oldEVec1 * eVec1 < 0) {
1028 double angle0 = eVec1.Angle(oldEVec1);
1029 if (eVec1 * (
eval.Cross(oldEVec1)) < 0)
1031 for (
int i = 0; i < nEdges; ++i) {
1032 const double angle = 2 * TMath::Pi() / nEdges * i - angle0;
1033 vertices.push_back(position + cos(angle)*eVec1 + sin(angle)*eVec2);
1036 vertices.push_back(position);
1039 TEveTriangleSet* error_shape =
new TEveTriangleSet(vertices.size(), nEdges * 2);
1040 for (
unsigned int k = 0; k < vertices.size(); ++k) {
1041 error_shape->SetVertex(k, vertices[k].X(), vertices[k].Y(), vertices[k].Z());
1044 assert(vertices.size() == 2 * nEdges + 2);
1047 for (
int i = 0; i < nEdges; ++i) {
1049 error_shape->SetTriangle(iTri++, i + 1, i + 1 + nEdges, (i + 1) % nEdges + 1);
1050 error_shape->SetTriangle(iTri++, (i + 1) % nEdges + 1, i + 1 + nEdges, (i + 1) % nEdges + 1 + nEdges);
1057 error_shape->SetMainTransparency(25);
1058 eveTrack->AddElement(error_shape);
1070 const TVector3& global_pos = geo.
get(hit->getSensorID()).
pointToGlobal(hit->getPosIn());
1076 const TVector3& global_pos = geo.
get(hit->getSensorID()).
pointToGlobal(hit->getPosIn());
1081 TVector3 global_pos;
1083 if (p) global_pos = p->getPosition();
1088 const TVector3& global_pos = hit->getPosition();
1096 track->simhits->SetNextPoint(v.x(), v.y(), v.z());
1103 const TString pointsTitle(
"Unassigned SimHits");
1119 particle = particle->getMother();
1123 const TVector3& p = particle->getMomentum();
1124 const TVector3& vertex = particle->getProductionVertex();
1125 const int pdg = particle->getPDG();
1126 TParticle tparticle(pdg, particle->getStatus(),
1127 (particle->getMother() ? particle->getMother()->getIndex() : 0), 0, particle->getFirstDaughter(), particle->getLastDaughter(),
1128 p.x(), p.y(), p.z(), particle->getEnergy(),
1129 vertex.x(), vertex.y(), vertex.z(), particle->getProductionTime());
1130 TEveMCTrack mctrack;
1131 mctrack = tparticle;
1132 mctrack.fTDecay = particle->getDecayTime();
1133 mctrack.fVDecay.Set(particle->getDecayVertex());
1134 mctrack.fDecayed = !boost::math::isinf(mctrack.fTDecay);
1135 mctrack.fIndex = particle->getIndex();
1140 bool hasTrajectory(
false);
1141 for (
auto rel : mcTrajectories.relations()) {
1144 if (rel.weight <= 0)
continue;
1155 (&pt == &trajectory.back()) ? TEvePathMark::kDecay : TEvePathMark::kReference,
1156 TEveVector(pt.x, pt.y, pt.z),
1157 TEveVector(pt.px, pt.py, pt.pz)
1161 hasTrajectory =
true;
1166 if (!hasTrajectory) {
1168 for (
int iDaughter = particle->getFirstDaughter(); iDaughter <= particle->getLastDaughter(); iDaughter++) {
1174 TEvePathMarkD refMark(TEvePathMarkD::kDaughter);
1175 refMark.fV.Set(daughter->getProductionVertex());
1176 refMark.fP.Set(daughter->getMomentum());
1177 refMark.fTime = daughter->getProductionTime();
1184 and mctrack.fDecayed) {
1185 TEvePathMarkD decayMark(TEvePathMarkD::kDecay);
1186 decayMark.fV.Set(particle->getDecayVertex());
1190 TString particle_name(mctrack.GetName());
1193 const MCParticle* mom = particle->getMother();
1200 if (!hasTrajectory) {
1203 title +=
"\n(track estimated from initial momentum)";
1249 MCTrack& mcTrack = mcTrackPair.second;
1250 if (mcTrack.
track) {
1251 if (mcTrack.
simhits->Size() > 0) {
1255 destroyEveElement(mcTrack.
simhits);
1262 parent = parentIt->second.track;
1265 parent->AddElement(mcTrack.
track);
1267 gEve->AddElement(mcTrack.
simhits);
1274 for (
size_t i = 0; i <
m_options.length(); i++) {
1281 m.SetMarkerStyle(1);
1313 if (groupPair.second.group)
1314 groupPair.second.visible = groupPair.second.group->GetRnrState();
1315 groupPair.second.group =
nullptr;
1327 float ecl_threshold = 0.01;
1329 ecl_threshold =
m_eclData->GetSliceThreshold(0);
1334 m_eclData->RefSliceInfo(0).Setup(
"ECL", ecl_threshold, kRed);
1340 gEve->GetSelection()->RemoveElements();
1341 gEve->GetHighlight()->RemoveElements();
1350 TVector3 v = vertex->getPos();
1355 vertexPoint->SetNextPoint(v.x(), v.y(), v.z());
1357 TMatrixDSymEigen eigen_values(vertex->getCov());
1359 det_shape->SetShape(
new TGeoSphere(0., 1.));
1360 fixGeoShapeRefCount(det_shape);
1361 const TVectorD& ev = eigen_values.GetEigenValues();
1362 const TMatrixD& eVec = eigen_values.GetEigenVectors();
1363 TVector3 eVec1(eVec(0, 0), eVec(1, 0), eVec(2,
1365 TVector3 eVec2(eVec(0, 1), eVec(1, 1), eVec(2,
1367 TVector3 eVec3(eVec(0, 2), eVec(1, 2), eVec(2, 2));
1371 TGeoRotation det_rot(
"det_rot", (eVec1.Theta() * 180) / TMath::Pi(), (eVec1.Phi() * 180) / TMath::Pi(),
1372 (eVec2.Theta() * 180) / TMath::Pi(), (eVec2.Phi() * 180) / TMath::Pi(),
1373 (eVec3.Theta() * 180) / TMath::Pi(), (eVec3.Phi() * 180) / TMath::Pi());
1377 double pseudo_res_0 = std::sqrt(ev(0));
1378 double pseudo_res_1 = std::sqrt(ev(1));
1379 double pseudo_res_2 = std::sqrt(ev(2));
1386 TGeoGenTrans det_trans(v(0), v(1), v(2), pseudo_res_0, pseudo_res_1, pseudo_res_2,
1388 det_shape->SetTransMatrix(det_trans);
1391 det_shape->SetMainColor(kOrange);
1392 det_shape->SetMainTransparency(0);
1394 vertexPoint->AddElement(det_shape);
1406 const float phi = cluster->getPhi();
1407 float dPhi = cluster->getUncertaintyPhi();
1408 float dTheta = cluster->getUncertaintyTheta();
1409 if (dPhi >= M_PI / 4 or dTheta >= M_PI / 4 or cluster->getUncertaintyEnergy() == 1.0) {
1410 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:");
1411 cluster->getCovarianceMatrix3x3().Print();
1412 dPhi = dTheta = 0.05;
1415 if (!std::isfinite(dPhi) or !std::isfinite(dTheta)) {
1416 B2ERROR(
"ECLCluster phi or theta error is NaN or infinite, skipping cluster!");
1422 thetaLow.SetPtThetaPhi(1.0, cluster->getTheta() - dTheta, phi);
1424 thetaHigh.SetPtThetaPhi(1.0, cluster->getTheta() + dTheta, phi);
1425 float etaLow = thetaLow.Eta();
1426 float etaHigh = thetaHigh.Eta();
1427 if (etaLow > etaHigh) {
1428 std::swap(etaLow, etaHigh);
1431 int id =
m_eclData->AddTower(etaLow, etaHigh, phi - dPhi, phi + dPhi);
1439 const double layerThicknessCm = 3.16;
1440 const double layerDistanceCm = 9.1 - layerThicknessCm;
1442 TVector3 startPos = cluster->getClusterPosition();
1445 bool isBarrel = (startPos.Z() > -175.0 and startPos.Z() < 270.0);
1448 b = TVector3(0, 0, 1);
1449 a = startPos.Cross(b).Unit();
1450 double c = M_PI / 4.0;
1451 double offset = c / 2.0 + M_PI;
1452 a.SetPhi(
int((a.Phi() + offset) / (c))*c - M_PI);
1453 TVector3 perp = b.Cross(a);
1455 const double barrelRadiusCm = 204.0;
1456 startPos.SetMag(barrelRadiusCm / perp.Dot(startPos.Unit()));
1458 dir = startPos.Unit();
1459 dir.SetMag((layerDistanceCm + layerThicknessCm) / perp.Dot(dir));
1462 b = TVector3(startPos.x(), startPos.y(), 0).Unit();
1463 a = startPos.Cross(b).Unit();
1464 double endcapStartZ = 284;
1465 if (startPos.z() < 0)
1466 endcapStartZ = -189.5;
1468 double scaleFac = endcapStartZ / startPos.z();
1469 startPos.SetMag(startPos.Mag() * scaleFac);
1471 dir = startPos.Unit();
1472 dir.SetMag((layerDistanceCm + layerThicknessCm) / fabs(dir.z()));
1475 for (
int i = 0; i < cluster->getLayers(); i++) {
1476 TVector3 layerPos = startPos;
1477 layerPos += (cluster->getInnermostLayer() + i) * dir;
1478 auto* layer =
boxCreator(layerPos, a, b, 20.0, 20.0, layerThicknessCm / 2);
1480 layer->SetMainTransparency(70);
1495 CLHEP::Hep3Vector global;
1502 CLHEP::Hep3Vector local = module->globalToLocal(global);
1507 double du = module->getPhiStripWidth() * Nphistrip;
1508 double dv = module->getZStripWidth() * Nztrip;
1511 CLHEP::Hep3Vector localU(local[0], local[1] + 1.0, local[2]);
1512 CLHEP::Hep3Vector localV(local[0], local[1], local[2] + 1.0);
1514 CLHEP::Hep3Vector globalU = module->localToGlobal(localU);
1515 CLHEP::Hep3Vector globalV = module->localToGlobal(localV);
1517 TVector3 o(global[0], global[1], global[2]);
1518 TVector3 u(globalU[0], globalU[1], globalU[2]);
1519 TVector3 v(globalV[0], globalV[1], globalV[2]);
1522 TEveBox* bklmbox =
boxCreator(o, u - o, v - o, du, dv, 1.0);
1524 bklmbox->SetMainColor(kGreen);
1526 bklmbox->SetName(
"BKLMHit2d");
1534 const double du = 2.0;
1535 const double dv = 2.0;
1537 TVector3 u(1.0, 0.0, 0.0);
1538 TVector3 v(0.0, 1.0, 0.0);
1539 TEveBox* eklmbox =
boxCreator(o, u, v, du, dv, 4.0);
1540 eklmbox->SetMainColor(kGreen);
1541 eklmbox->SetName(
"EKLMHit2d");
1550 VxdID sensorID = roi->getSensorID();
1553 double minU = aSensorInfo.
getUCellPosition(roi->getMinUid(), roi->getMinVid());
1555 double maxU = aSensorInfo.
getUCellPosition(roi->getMaxUid(), roi->getMaxVid());
1559 TVector3 localA(minU, minV, 0);
1560 TVector3 localB(minU, maxV, 0);
1561 TVector3 localC(maxU, minV, 0);
1567 TEveBox* ROIbox =
boxCreator((globalB + globalC) * 0.5 , globalB - globalA, globalC - globalA, 1, 1, 0.01);
1570 ROIbox->SetMainColor(kSpring - 9);
1571 ROIbox->SetMainTransparency(50);
1583 if (hit->isUCluster()) {
1584 const float u = hit->getPosition();
1585 a = sensor.pointToGlobal(TVector3(sensor.getBackwardWidth() / sensor.getWidth(0) * u, -0.5 * sensor.getLength(), 0.0));
1586 b = sensor.pointToGlobal(TVector3(sensor.getForwardWidth() / sensor.getWidth(0) * u, +0.5 * sensor.getLength(), 0.0));
1588 const float v = hit->getPosition();
1589 a = sensor.pointToGlobal(TVector3(-0.5 * sensor.getWidth(v), v, 0.0));
1590 b = sensor.pointToGlobal(TVector3(+0.5 * sensor.getWidth(v), v, 0.0));
1593 lines->AddLine(a.x(), a.y(), a.z(), b.x(), b.y(), b.z());
1603 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());
1614 TEveGeoShape* cov_shape =
new TEveGeoShape(
"cov_shape");
1618 driftLengthRes = std::max(driftLengthRes, 0.005);
1619 const double lengthOfWireSection = 3.0;
1622 const TVector3 zaxis = wire_pos_b - wire_pos_f;
1623 const TVector3 xaxis = zaxis.Orthogonal();
1624 const TVector3 yaxis = xaxis.Cross(zaxis);
1627 const TVector3 midPoint = wire_pos_f - zaxis * (wire_pos_f.z() / zaxis.z());
1629 cov_shape->SetShape(
new TGeoTube(std::max(0., (
double)(driftLength - driftLengthRes)), driftLength + driftLengthRes,
1630 lengthOfWireSection));
1631 fixGeoShapeRefCount(cov_shape);
1633 TGeoRotation det_rot(
"det_rot",
1634 xaxis.Theta() * 180 / TMath::Pi(), xaxis.Phi() * 180 / TMath::Pi(),
1635 yaxis.Theta() * 180 / TMath::Pi(), yaxis.Phi() * 180 / TMath::Pi(),
1636 zaxis.Theta() * 180 / TMath::Pi(), zaxis.Phi() * 180 / TMath::Pi()
1639 TGeoCombiTrans det_trans(midPoint(0), midPoint(1), midPoint(2), &det_rot);
1640 cov_shape->SetTransMatrix(det_trans);
1643 bool isPartOfTS =
false;
1645 if (showTriggerHits && segments.size() > 0) {
1649 if (hit->getISuperLayer() % 2 == 0) {
1651 cov_shape->SetMainColor(kCyan + 3);
1653 cov_shape->SetMainColor(kCyan);
1656 cov_shape->SetMainColor(kPink + 6);
1658 cov_shape->SetMainColor(kPink + 7);
1661 cov_shape->SetMainTransparency(50);
1663 cov_shape->SetTitle(
ObjectInfo::getInfo(hit) + TString::Format(
"\nWire ID: %d\nADC: %d\nTDC: %d",
1664 hit->getID(), hit->getADCCount(), hit->getTDCCount()));
1669 addToGroup(
"CDCTriggerSegmentHits", cov_shape);
1670 for (
auto rel : segments.relations()) {
1679 TEveStraightLineSet* shape =
new TEveStraightLineSet();
1683 if (hit->getPriorityPosition() < 3) iL -= 1;
1685 unsigned iCenter = hit->getIWire();
1686 if (hit->getPriorityPosition() == 1) iCenter += 1;
1697 std::vector<int> layershift = { -2, -1, 0, 1, 2};
1698 std::vector<std::vector<float>> cellshift = {
1712 if (hit->getISuperLayer() == 0) {
1713 layershift = { 0, 1, 2, 3, 4};
1718 { -1.5, -0.5, 0.5, 1.5},
1724 for (
unsigned il = 0; il < layershift.size(); ++il) {
1725 for (
unsigned ic = 0; ic < cellshift[il].size(); ++ic) {
1726 TVector3 corners[2][2];
1727 for (
unsigned ir = 0; ir < 2; ++ir) {
1728 double r = cdcgeo.
fieldWireR(iL + layershift[il] - ir);
1729 double fz = cdcgeo.
fieldWireFZ(iL + layershift[il] - ir);
1730 double bz = cdcgeo.
fieldWireBZ(iL + layershift[il] - ir);
1731 for (
unsigned iphi = 0; iphi < 2; ++iphi) {
1732 double phib = (iCenter + cellshift[il][ic] + iphi - 0.5) * 2 * M_PI / nWires;
1733 double phif = phib + cdcgeo.
nShifts(iL + layershift[il]) * M_PI / nWires;
1735 TVector3 pos_f = TVector3(cos(phif) * r, sin(phif) * r, fz);
1736 TVector3 pos_b = TVector3(cos(phib) * r, sin(phib) * r, bz);
1737 TVector3 zaxis = pos_b - pos_f;
1738 corners[ir][iphi] = pos_f - zaxis * (pos_f.z() / zaxis.z());
1742 shape->AddLine(corners[0][0].x(), corners[0][0].y(), 0,
1743 corners[0][1].x(), corners[0][1].y(), 0);
1744 shape->AddLine(corners[0][1].x(), corners[0][1].y(), 0,
1745 corners[1][1].x(), corners[1][1].y(), 0);
1746 shape->AddLine(corners[1][1].x(), corners[1][1].y(), 0,
1747 corners[1][0].x(), corners[1][0].y(), 0);
1748 shape->AddLine(corners[1][0].x(), corners[1][0].y(), 0,
1749 corners[0][0].x(), corners[0][0].y(), 0);
1753 if (hit->getISuperLayer() % 2 == 0) {
1754 shape->SetMainColor(kCyan + 3);
1756 shape->SetMainColor(kPink + 6);
1761 TString::Format(
"\nPriority: %d\nLeft/Right: %d",
1762 hit->getPriorityPosition(), hit->getLeftRight()));
1771 int hitModule = hit->getModule();
1772 float fi = arichGeo->getDetectorPlane().getSlotPhi(hitModule);
1774 TVector3 centerPos3D = hit->getPosition();
1776 TVector3 channelX(1, 0, 0); channelX.RotateZ(fi);
1777 TVector3 channelY(0, 1, 0); channelY.RotateZ(fi);
1779 auto* arichbox =
boxCreator(centerPos3D, arichGeo->getMasterVolume().momentumToGlobal(channelX),
1780 arichGeo->getMasterVolume().momentumToGlobal(channelY), 0.49, 0.49, 0.05);
1781 arichbox->SetMainColor(kOrange + 10);
1782 arichbox->SetName((std::to_string(hitModule)).c_str());
1791 std::map<int, int> m_topSummary;
1792 for (
const TOPDigit& hit : digits) {
1793 int mod = hit.getModuleID();
1794 ++m_topSummary[mod];
1797 for (
auto modCountPair : m_topSummary) {
1798 if (modCountPair.second > maxcount)
1799 maxcount = modCountPair.second;
1801 for (
auto modCountPair : m_topSummary) {
1803 double phi = topmod.getPhi();
1804 double r_center = topmod.getRadius();
1805 double z = topmod.getZc();
1807 TVector3 centerPos3D;
1808 centerPos3D.SetMagThetaPhi(r_center, M_PI / 2, phi);
1809 centerPos3D.SetZ(z);
1811 TVector3 channelX(1, 0, 0); channelX.RotateZ(phi);
1812 TVector3 channelY(0, 1, 0); channelY.RotateZ(phi);
1815 auto* moduleBox =
boxCreator(centerPos3D, channelX, channelY,
1816 3.0 * topmod.getBarThickness(), topmod.getBarWidth() , topmod.getBarLength());
1817 moduleBox->SetMainColor(kAzure + 10);
1818 double weight = double(modCountPair.second) / maxcount;
1819 moduleBox->SetMainTransparency(90 - weight * 50);
1820 moduleBox->SetName((
"TOP module " + std::to_string(modCountPair.first)).c_str());
1821 moduleBox->SetTitle(TString::Format(
"#TOPDigits: %d ", modCountPair.second));
1825 for (
const TOPDigit& hit : digits) {
1826 if (modCountPair.first == hit.getModuleID())
1835 for (
const auto& labelPair : displayData.
m_labels) {
1836 TEveText* text =
new TEveText(labelPair.first.c_str());
1837 text->SetName(labelPair.first.c_str());
1838 text->SetTitle(labelPair.first.c_str());
1839 text->SetMainColor(kGray + 1);
1840 const TVector3& p = labelPair.second;
1841 text->PtrMainTrans()->SetPos(p.x(), p.y(), p.z());
1845 for (
const auto& pointPair : displayData.
m_pointSets) {
1846 TEvePointSet* points =
new TEvePointSet(pointPair.first.c_str());
1847 points->SetTitle(pointPair.first.c_str());
1848 points->SetMarkerStyle(7);
1849 points->SetMainColor(kGreen);
1850 for (
const TVector3& p : pointPair.second) {
1851 points->SetNextPoint(p.x(), p.y(), p.z());
1856 int randomColor = 2;
1857 for (
const auto& arrow : displayData.
m_arrows) {
1858 const TVector3 pos = arrow.start;
1859 const TVector3 dir = arrow.end - pos;
1860 TEveArrow* eveArrow =
new TEveArrow(dir.x(), dir.y(), dir.z(), pos.x(), pos.y(), pos.z());
1861 eveArrow->SetName(arrow.name.c_str());
1862 eveArrow->SetTitle(arrow.name.c_str());
1863 int arrowColor = arrow.color;
1864 if (arrowColor == -1) {
1865 arrowColor = randomColor;
1868 eveArrow->SetMainColor(arrowColor);
1871 TEveText* text =
new TEveText(arrow.name.c_str());
1872 text->SetMainColor(arrowColor);
1874 const TVector3& labelPos = pos + 0.5 * dir + 0.1 * dir.Orthogonal();
1875 text->PtrMainTrans()->SetPos(labelPos.x(), labelPos.y(), labelPos.z());
1876 eveArrow->AddElement(text);
1889 const std::string& groupName = boost::algorithm::trim_copy_if(name, boost::algorithm::is_any_of(
"/"));
1891 TEveElementList* group =
m_groups[groupName].group;
1893 group =
new TEveElementList(groupName.c_str(), groupName.c_str());
1894 group->SetRnrState(
m_groups[groupName].visible);
1899 auto lastSlash = boost::algorithm::find_last(groupName,
"/");
1901 const std::string parentGroup(groupName.begin(), lastSlash.begin());
1902 const std::string thisGroup(lastSlash.end(), groupName.end());
1903 group->SetElementName(thisGroup.c_str());
1906 gEve->AddElement(group);
1909 group->AddElement(elem);