Belle II Software  release-05-02-19
EVEVisualization.cc
1 //For GFTrack visualisation:
2 /* Copyright 2011, Technische Universitaet Muenchen,
3  Author: Karl Bicker
4 
5  This file is part of GENFIT.
6 
7  GENFIT is free software: you can redistribute it and/or modify
8  it under the terms of the GNU Lesser General Public License as published
9  by the Free Software Foundation, either version 3 of the License, or
10  (at your option) any later version.
11 
12  GENFIT is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU Lesser General Public License for more details.
16 
17  You should have received a copy of the GNU Lesser General Public License
18  along with GENFIT. If not, see <http://www.gnu.org/licenses/>.
19 */
20 #include <display/EVEVisualization.h>
21 
22 #include <display/VisualRepMap.h>
23 #include <display/EveGeometry.h>
24 #include <display/EveVisBField.h>
25 #include <display/ObjectInfo.h>
26 
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>
38 
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>
49 
50 #include <framework/dataobjects/DisplayData.h>
51 #include <framework/logging/Logger.h>
52 #include <framework/utilities/ColorPalette.h>
53 
54 #include <TEveArrow.h>
55 #include <TEveBox.h>
56 #include <TEveCalo.h>
57 #include <TEveManager.h>
58 #include <TEveGeoShape.h>
59 #include <TEveLine.h>
60 #include <TEvePointSet.h>
61 #include <TEveSelection.h>
62 #include <TEveStraightLineSet.h>
63 #include <TEveTriangleSet.h>
64 #include <TEveText.h>
65 #include <TEveTrack.h>
66 #include <TEveTrackPropagator.h>
67 #include <TGeoEltu.h>
68 #include <TGeoMatrix.h>
69 #include <TGeoManager.h>
70 #include <TGeoSphere.h>
71 #include <TGeoTube.h>
72 #include <TGLLogicalShape.h>
73 #include <TParticle.h>
74 #include <TMath.h>
75 #include <TVectorD.h>
76 #include <TMatrixD.h>
77 #include <TMatrixDSymEigen.h>
78 
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>
84 
85 #include <cassert>
86 #include <cmath>
87 
88 using namespace Belle2;
89 using namespace Belle2::TangoPalette;
90 
91 namespace {
93  template <class T> void destroyEveElement(T*& el)
94  {
95  if (!el) return;
96  if (el->GetDenyDestroy() > 1)
97  B2WARNING("destroyEveElement(): Element " << el->GetName() << " has unexpected refcount " << el->GetDenyDestroy());
98 
99  el->DecDenyDestroy(); //also deletes el when refcount <= 0
100  el = nullptr;
101  }
102 
109  void fixGeoShapeRefCount(TEveGeoShape* eveshape)
110  {
111  TGeoShape* s = eveshape->GetShape();
112  //Remove(obj) usually takes about 20us, but since usually s is at the end, we can shorten this
113  if (gGeoManager->GetListOfShapes()->Last() == s)
114  gGeoManager->GetListOfShapes()->RemoveAt(gGeoManager->GetListOfShapes()->GetLast());
115  else
116  gGeoManager->GetListOfShapes()->Remove(s);
117  }
118 }
119 
120 const int EVEVisualization::c_recoHitColor = getTColorID("Orange", 1);
122 const int EVEVisualization::c_trackColor = getTColorID("Sky Blue", 2);
123 const int EVEVisualization::c_recoTrackColor = getTColorID("Sky Blue", 1);
124 const int EVEVisualization::c_trackMarkerColor = getTColorID("Chameleon", 3);
125 const int EVEVisualization::c_klmClusterColor = getTColorID("Chameleon", 1);
126 
128  m_assignToPrimaries(false),
129  m_eclData(0),
130  m_bfield(new EveVisBField())
131 {
132  setErrScale();
133 
134  TGLLogicalShape::SetIgnoreSizeForCameraInterest(kTRUE); // Allows the visualization of the "small" error ellipsoid.
135 
136  //create new containers
137  m_trackpropagator = new TEveTrackPropagator();
138  m_trackpropagator->IncDenyDestroy();
139  m_trackpropagator->SetMagFieldObj(m_bfield, false);
140  m_trackpropagator->SetFitDaughters(false); //most secondaries are no longer immediate daughters since we might discard those!
141  m_trackpropagator->SetMaxR(EveGeometry::getMaxR()); //don't draw tracks outside detector
142  //TODO is this actually needed?
143  m_trackpropagator->SetMaxStep(1.0); //make sure to reeval magnetic field often enough
144 
145  m_tracklist = new TEveTrackList(m_trackpropagator);
146  m_tracklist->IncDenyDestroy();
147  m_tracklist->SetName("MCParticles");
148  m_tracklist->SelectByP(c_minPCut, FLT_MAX); //don't show too many particles by default...
149 
150  m_gftrackpropagator = new TEveTrackPropagator();
151  m_gftrackpropagator->IncDenyDestroy();
152  m_gftrackpropagator->SetMagFieldObj(m_bfield, false);
153  m_gftrackpropagator->SetMaxOrbs(0.5); //stop after track markers
154 
155  m_consttrackpropagator = new TEveTrackPropagator();
156  m_consttrackpropagator->IncDenyDestroy();
157  m_consttrackpropagator->SetMagField(0, 0, -1.5);
159 
160  m_calo3d = new TEveCalo3D(NULL, "ECLClusters");
161  m_calo3d->SetBarrelRadius(125.80); //inner radius of ECL barrel
162  m_calo3d->SetForwardEndCapPos(196.5); //inner edge of forward endcap
163  m_calo3d->SetBackwardEndCapPos(-102.0); //inner edge of backward endcap
164  m_calo3d->SetMaxValAbs(2.1);
165  m_calo3d->SetRnrFrame(false, false); //don't show crystal grid
166  m_calo3d->IncDenyDestroy();
167 
168  //Stop eve from deleting contents... (which might already be deleted)
169  gEve->GetSelection()->IncDenyDestroy();
170  gEve->GetHighlight()->IncDenyDestroy();
171 
172  clearEvent();
173 }
174 
175 void EVEVisualization::setOptions(const std::string& opts) { m_options = opts; }
176 
177 void EVEVisualization::setErrScale(double errScale) { m_errorScale = errScale; }
178 
180 {
181  if (!gEve)
182  return; //objects are probably already freed by Eve
183 
184  //Eve objects
185  destroyEveElement(m_eclData);
186  destroyEveElement(m_unassignedRecoHits);
187  destroyEveElement(m_tracklist);
188  destroyEveElement(m_trackpropagator);
189  destroyEveElement(m_gftrackpropagator);
190  destroyEveElement(m_consttrackpropagator);
191  destroyEveElement(m_calo3d);
192  delete m_bfield;
193 }
194 
195 void EVEVisualization::addTrackCandidate(const std::string& collectionName,
196  const RecoTrack& recoTrack)
197 {
198  const TString label = ObjectInfo::getIdentifier(&recoTrack);
199  // parse the option string ------------------------------------------------------------------------
200  bool drawHits = false;
201 
202  if (m_options != "") {
203  for (size_t i = 0; i < m_options.length(); i++) {
204  if (m_options.at(i) == 'H') drawHits = true;
205  }
206  }
207  // finished parsing the option string -------------------------------------------------------------
208 
209 
210  //track seeds
211  TVector3 track_pos = recoTrack.getPositionSeed();
212  TVector3 track_mom = recoTrack.getMomentumSeed();
213 
214  TEveStraightLineSet* lines = new TEveStraightLineSet("RecoHits for " + label);
215  lines->SetMainColor(c_recoTrackColor);
216  lines->SetMarkerColor(c_recoTrackColor);
217  lines->SetMarkerStyle(6);
218  lines->SetMainTransparency(60);
219 
220  if (drawHits) {
221  // Loop over all hits in the track (three different types)
222  for (const RecoHitInformation::UsedPXDHit* pxdHit : recoTrack.getPXDHitList()) {
223  addRecoHit(pxdHit, lines);
224  }
225 
226  for (const RecoHitInformation::UsedSVDHit* svdHit : recoTrack.getSVDHitList()) {
227  addRecoHit(svdHit, lines);
228  }
229 
230  for (const RecoHitInformation::UsedCDCHit* cdcHit : recoTrack.getCDCHitList()) {
231  addRecoHit(cdcHit, lines);
232  }
233  }
234 
235  TEveRecTrack rectrack;
236  rectrack.fP.Set(track_mom);
237  rectrack.fV.Set(track_pos);
238 
239  TEveTrack* track_lines = new TEveTrack(&rectrack, m_gftrackpropagator);
240  track_lines->SetName(label); //popup label set at end of function
241  track_lines->SetPropagator(m_gftrackpropagator);
242  track_lines->SetLineColor(c_recoTrackColor);
243  track_lines->SetLineWidth(1);
244  track_lines->SetTitle(ObjectInfo::getTitle(&recoTrack));
245 
246  track_lines->SetCharge((int)recoTrack.getChargeSeed());
247 
248 
249  track_lines->AddElement(lines);
250  addToGroup(collectionName, track_lines);
251  addObject(&recoTrack, track_lines);
252 }
253 
254 void EVEVisualization::addTrackCandidateImproved(const std::string& collectionName,
255  const RecoTrack& recoTrack)
256 {
257  const TString label = ObjectInfo::getIdentifier(&recoTrack);
258  // parse the option string ------------------------------------------------------------------------
259  bool drawHits = false;
260 
261  if (m_options != "") {
262  for (size_t i = 0; i < m_options.length(); i++) {
263  if (m_options.at(i) == 'H') drawHits = true;
264  }
265  }
266  // finished parsing the option string -------------------------------------------------------------
267 
268  // Create a track as a polyline through reconstructed points
269  // FIXME this is snatched from PrimitivePlotter, need to add extrapolation out of CDC
270  TEveLine* track = new TEveLine(); // We are going to just add points with SetNextPoint
271  std::vector<TVector3> posPoints; // But first we'll have to sort them as in RecoHits axial and stereo come in blocks
272  track->SetName(label); //popup label set at end of function
273  track->SetLineColor(c_recoTrackColor);
274  track->SetLineWidth(3);
275  track->SetTitle(ObjectInfo::getTitle(&recoTrack));
276  track->SetSmooth(true);
277 
278  for (auto recoHit : recoTrack.getRecoHitInformations()) {
279  // skip for reco hits which have not been used in the fit (and therefore have no fitted information on the plane
280  if (!recoHit->useInFit())
281  continue;
282 
283  TVector3 pos;
284  TVector3 mom;
285  TMatrixDSym cov;
286 
287  try {
288  const auto* trackPoint = recoTrack.getCreatedTrackPoint(recoHit);
289  const auto* fittedResult = trackPoint->getFitterInfo();
290  if (not fittedResult) {
291  B2WARNING("Skipping unfitted track point");
292  continue;
293  }
294  const genfit::MeasuredStateOnPlane& state = fittedResult->getFittedState();
295  state.getPosMomCov(pos, mom, cov);
296  } catch (const genfit::Exception&) {
297  B2WARNING("Skipping state with strange pos, mom or cov");
298  continue;
299  }
300 
301  posPoints.push_back(TVector3(pos.X(), pos.Y(), pos.Z()));
302  }
303 
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();
307  });
308  for (auto vec : posPoints) {
309  track->SetNextPoint(vec.X(), vec.Y(), vec.Z());
310  }
311  // add corresponding hits ---------------------------------------------------------------------
312  TEveStraightLineSet* lines = new TEveStraightLineSet("RecoHits for " + label);
313  lines->SetMainColor(c_recoTrackColor);
314  lines->SetMarkerColor(c_recoTrackColor);
315  lines->SetMarkerStyle(6);
316  lines->SetMainTransparency(60);
317 
318  if (drawHits) {
319  // Loop over all hits in the track (three different types)
320  for (const RecoHitInformation::UsedPXDHit* pxdHit : recoTrack.getPXDHitList()) {
321  addRecoHit(pxdHit, lines);
322  }
323 
324  for (const RecoHitInformation::UsedSVDHit* svdHit : recoTrack.getSVDHitList()) {
325  addRecoHit(svdHit, lines);
326  }
327 
328  for (const RecoHitInformation::UsedCDCHit* cdcHit : recoTrack.getCDCHitList()) {
329  addRecoHit(cdcHit, lines);
330  }
331  }
332 
333  track->AddElement(lines);
334  addToGroup(collectionName, track);
335  addObject(&recoTrack, track);
336 }
337 
338 void EVEVisualization::addCDCTriggerTrack(const std::string& collectionName,
339  const CDCTriggerTrack& trgTrack)
340 {
341  const TString label = ObjectInfo::getIdentifier(&trgTrack);
342 
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);
347 
348  TEveRecTrack rectrack;
349  rectrack.fP.Set(track_mom);
350  rectrack.fV.Set(track_pos);
351 
352  TEveTrack* track_lines = new TEveTrack(&rectrack, m_consttrackpropagator);
353  track_lines->SetName(label); //popup label set at end of function
354  track_lines->SetPropagator(m_consttrackpropagator);
355  track_lines->SetLineColor(kOrange + 2);
356  track_lines->SetLineWidth(1);
357  track_lines->SetTitle(ObjectInfo::getTitle(&trgTrack) +
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,
363  trgTrack.getZ0()));
364 
365 
366  track_lines->SetCharge(trgTrack.getChargeSign());
367 
368  // show 2D tracks with dashed lines
369  if (trgTrack.getZ0() == 0 && trgTrack.getCotTheta() == 0)
370  track_lines->SetLineStyle(2);
371 
372  addToGroup(collectionName, track_lines);
373  addObject(&trgTrack, track_lines);
374 }
375 
377 {
378  // load the pion fit hypothesis or the hypothesis which is the closest in mass to a pion
379  // the tracking will not always successfully fit with a pion hypothesis
380  const TrackFitResult* fitResult = belle2Track->getTrackFitResultWithClosestMass(Const::pion);
381  if (!fitResult) {
382  B2ERROR("Track without TrackFitResult skipped.");
383  return;
384  }
385  const RecoTrack* track = belle2Track->getRelated<RecoTrack>();
386 
387  const TString label = ObjectInfo::getIdentifier(belle2Track) + " (" + ObjectInfo::getIdentifier(fitResult) + ")";
388 
389  // parse the option string ------------------------------------------------------------------------
390  bool drawDetectors = false;
391  bool drawHits = false;
392  bool drawPlanes = false;
393 
394  if (m_options != "") {
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;
399  }
400  }
401  // finished parsing the option string -------------------------------------------------------------
402 
403  // We loop over all points (scattering non-measurement points for GBL)
404  // and for Kalman we skip those with no measurements, which should
405  // not be there
406  bool isPruned = (track == nullptr);
407 
408 
409  TEveRecTrackD recTrack;
410  const TVector3& poca = fitResult->getPosition();
411  recTrack.fV.Set(poca);
412 
413  const TVector3& poca_momentum = fitResult->getMomentum();
414  if (std::isfinite(poca_momentum.Mag()))
415  recTrack.fP.Set(poca_momentum);
416  else //use 1TeV momentum for tracks without curvature
417  recTrack.fP.Set(fitResult->getHelix().getDirection() * 1000);
418 
419  recTrack.fSign = fitResult->getChargeSign();
420  TEveTrack* eveTrack = new TEveTrack(&recTrack, m_gftrackpropagator);
421  eveTrack->SetName(label);
422 
423 
424  if (track) {
425  const genfit::AbsTrackRep* representation;
426 
427  if (m_drawCardinalRep) {
428  representation = track->getCardinalRepresentation();
429  B2DEBUG(100, "Draw cardinal rep");
430  } else {
431  const auto& representations = track->getRepresentations();
432  if (representations.empty()) {
433  B2ERROR("No representations found in the reco track!");
434  return;
435  }
436  B2DEBUG(100, "Draw representation number 0.");
437  representation = representations.front();
438  }
439 
440  if (!track->hasTrackFitStatus(representation)) {
441  B2ERROR("RecoTrack without FitStatus: will be skipped!");
442  return;
443  }
444 
445  const genfit::FitStatus* fitStatus = track->getTrackFitStatus(representation);
446 
447  isPruned = fitStatus->isTrackPruned();
448 
449  // GBL and Kalman cannot mix in a track.
450  // What is 0 after first loop will stay 0:
451  genfit::KalmanFitterInfo* fi = 0;
452  genfit::KalmanFitterInfo* prevFi = 0;
453  genfit::GblFitterInfo* gfi = 0;
454  genfit::GblFitterInfo* prevGFi = 0;
455  const genfit::MeasuredStateOnPlane* fittedState(NULL);
456  const genfit::MeasuredStateOnPlane* prevFittedState(NULL);
457 
458 
459  const auto& hitPoints = track->getHitPointsWithMeasurement();
460  const unsigned int numpoints = hitPoints.size();
461 
462  int hitCounter = -1;
463  for (genfit::TrackPoint* tp : hitPoints) { // loop over all points in the track
464  hitCounter++;
465 
466  // get the fitter infos ------------------------------------------------------------------
467  if (! tp->hasFitterInfo(representation)) {
468  B2ERROR("trackPoint has no fitterInfo for rep");
469  continue;
470  }
471 
472  genfit::AbsFitterInfo* fitterInfo = tp->getFitterInfo(representation);
473 
474  fi = dynamic_cast<genfit::KalmanFitterInfo*>(fitterInfo);
475  gfi = dynamic_cast<genfit::GblFitterInfo*>(fitterInfo);
476 
477  if (!gfi && !fi) {
478  B2ERROR("Can only display KalmanFitterInfo or GblFitterInfo");
479  continue;
480  }
481 
482  if (gfi && fi)
483  B2FATAL("AbsFitterInfo dynamic-casted to both KalmanFitterInfo and GblFitterInfo!");
484 
485 
486  if (fi && ! tp->hasRawMeasurements()) {
487  B2ERROR("trackPoint has no raw measurements");
488  continue;
489  }
490 
491  if (fi && ! fi->hasPredictionsAndUpdates()) {
492  B2ERROR("KalmanFitterInfo does not have all predictions and updates");
493  continue;
494  }
495 
496  try {
497  if (gfi)
498  fittedState = &(gfi->getFittedState(true));
499  if (fi)
500  fittedState = &(fi->getFittedState(true));
501  } catch (genfit::Exception& e) {
502  B2ERROR(e.what() << " - can not get fitted state");
503  continue;
504  }
505 
506  TVector3 track_pos = representation->getPos(*fittedState);
507 
508  // draw track if corresponding option is set ------------------------------------------
509  if (prevFittedState != NULL) {
510 
511  TEvePathMark::EType_e markType = TEvePathMark::kReference;
512  if (hitCounter + 1 == static_cast<int>(numpoints)) //track should stop here.
513  markType = TEvePathMark::kDecay;
514 
515  // Kalman: non-null prevFi ensures that the previous fitter info was also KalmanFitterInfo
516  if (fi && prevFi) {
517  makeLines(eveTrack, prevFittedState, fittedState, representation, markType, m_drawErrors);
518  if (m_drawErrors) { // make sure to draw errors in both directions
519  makeLines(eveTrack, prevFittedState, fittedState, representation, markType, m_drawErrors, 0);
520  }
521  //these are currently disabled.
522  //TODO: if activated, I want to have a separate TEveStraightLineSet instead of eveTrack (different colors/options)
523  if (m_drawForward)
524  makeLines(eveTrack, prevFi->getForwardUpdate(), fi->getForwardPrediction(), representation, markType, m_drawErrors, 0);
525  if (m_drawBackward)
526  makeLines(eveTrack, prevFi->getBackwardPrediction(), fi->getBackwardUpdate(), representation, markType, m_drawErrors);
527  // draw reference track if corresponding option is set ------------------------------------------
528  if (m_drawRefTrack && fi->hasReferenceState() && prevFi->hasReferenceState())
529  makeLines(eveTrack, prevFi->getReferenceState(), fi->getReferenceState(), representation, markType, false);
530  }
531 
532  // GBL: non-null prevGFi ensures that the previous fitter info was also GblFitterInfo
533  if (gfi && prevGFi) {
534  makeLines(eveTrack, prevFittedState, fittedState, representation, markType, m_drawErrors);
535  if (m_drawErrors) {
536  makeLines(eveTrack, prevFittedState, fittedState, representation, markType, m_drawErrors, 0);
537  }
538 
539  if (m_drawRefTrack && gfi->hasReferenceState() && prevGFi->hasReferenceState()) {
540  genfit::StateOnPlane prevSop = prevGFi->getReferenceState();
542  makeLines(eveTrack, &prevSop, &sop, representation, markType, false);
543  }
544  }
545 
546  }
547  prevFi = fi; // Kalman
548  prevGFi = gfi; // GBL
549  prevFittedState = fittedState;
550 
551 
552  //loop over all measurements for this point (e.g. u and v-type strips)
553  const int numMeasurements = tp->getNumRawMeasurements();
554  for (int iMeasurement = 0; iMeasurement < numMeasurements; iMeasurement++) {
555  const genfit::AbsMeasurement* m = tp->getRawMeasurement(iMeasurement);
556 
557  TVectorT<double> hit_coords;
558  TMatrixTSym<double> hit_cov;
559 
560  if (fi) {
561  // Kalman
562  genfit::MeasurementOnPlane* mop = fi->getMeasurementOnPlane(iMeasurement);
563  hit_coords.ResizeTo(mop->getState());
564  hit_cov.ResizeTo(mop->getCov());
565  hit_coords = mop->getState();
566  hit_cov = mop->getCov();
567  }
568  if (gfi) {
569  // GBL - has only one measurement (other should be already merged before the track is constructed)
570  // That means tp->getNumRawMeasurements() returns 1 for tracks fitted by GBL, because GBLfit Module
571  // merges all corresponding SVD strips to 2D combined clusters.
573  hit_coords.ResizeTo(gblMeas.getState());
574  hit_cov.ResizeTo(gblMeas.getCov());
575  hit_coords = gblMeas.getState();
576  hit_cov = gblMeas.getCov();
577  }
578 
579  // finished getting the hit infos -----------------------------------------------------
580 
581  // sort hit infos into variables ------------------------------------------------------
582  TVector3 o = fittedState->getPlane()->getO();
583  TVector3 u = fittedState->getPlane()->getU();
584  TVector3 v = fittedState->getPlane()->getV();
585 
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;
591  double_t hit_u = 0;
592  double_t hit_v = 0;
593  double_t plane_size = 4;
594 
595  int hit_coords_dim = m->getDim();
596 
597  if (dynamic_cast<const genfit::PlanarMeasurement*>(m) != NULL) {
598  planar_hit = true;
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);
605  }
606  } else if (dynamic_cast<const genfit::SpacepointMeasurement*>(m) != NULL) {
607  space_hit = true;
608  plane_size = 4;
609  } else if (dynamic_cast<const CDCRecoHit*>(m)
610  || dynamic_cast<const genfit::WireMeasurement*>(m)
611  || dynamic_cast<const genfit::WireMeasurementNew*>(m)) {
612  wire_hit = true;
613  hit_u = fabs(hit_coords(0));
614  hit_v = v * (track_pos - o); // move the covariance tube so that the track goes through it
615  plane_size = 4;
616  if (dynamic_cast<const genfit::WirePointMeasurement*>(m) != NULL) {
617  wirepoint_hit = true;
618  hit_v = hit_coords(1);
619  }
620  } else {
621  B2ERROR("Hit " << hitCounter << ", Measurement " << iMeasurement << ": Unknown measurement type: skipping hit!");
622  break;
623  }
624 
625  if (plane_size < 4) plane_size = 4;
626  // finished setting variables ---------------------------------------------------------
627 
628  // draw planes if corresponding option is set -----------------------------------------
629  if (drawPlanes || (drawDetectors && planar_hit)) {
630  TVector3 move(0, 0, 0);
631  if (wire_hit) move = v * (v * (track_pos - o)); // move the plane along the wire until the track goes through it
632  TEveBox* box = boxCreator(o + move, u, v, plane_size, plane_size, 0.01);
633  if (drawDetectors && planar_hit) {
634  box->SetMainColor(kCyan);
635  } else {
636  box->SetMainColor(kGray);
637  }
638  box->SetMainTransparency(50);
639  eveTrack->AddElement(box);
640  }
641  // finished drawing planes ------------------------------------------------------------
642 
643  // draw detectors if option is set, only important for wire hits ----------------------
644  if (drawDetectors) {
645 
646  if (wire_hit) {
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);
650 
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()); // move the tube to the right place and rotate it correctly
655  TVector3 move = v * (v * (track_pos - o)); // move the tube along the wire until the track goes through it
656  TGeoCombiTrans det_trans(o(0) + move.X(),
657  o(1) + move.Y(),
658  o(2) + move.Z(),
659  &det_rot);
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);
665  }
666  }
667 
668  }
669  // finished drawing detectors ---------------------------------------------------------
670 
671  if (drawHits) {
672 
673  // draw planar hits, with distinction between strip and pixel hits ----------------
674  if (planar_hit) {
675  if (!planar_pixel_hit) {
676  //strip hit
678  const SVDRecoHit* recoHit = dynamic_cast<const SVDRecoHit*>(m);
679  if (!recoHit) {
680  B2WARNING("SVD recohit couldn't be converted... ");
681  continue;
682  }
683 
684  const VXD::SensorInfoBase& sensor = geo.get(recoHit->getSensorID());
685  double du, dv;
686  TVector3 a = o; //defines position of sensor plane
687  double hit_res_u = hit_cov(0, 0);
688  if (recoHit->isU()) {
689  du = std::sqrt(hit_res_u);
690  dv = sensor.getLength();
691  a += hit_u * u;
692  } else {
693  du = sensor.getWidth();
694  dv = std::sqrt(hit_res_u);
695  a += hit_u * v;
696  }
697  double depth = sensor.getThickness();
698  TEveBox* hit_box = boxCreator(a, u, v, du, dv, depth);
699  hit_box->SetName("SVDRecoHit");
700  hit_box->SetMainColor(c_recoHitColor);
701  hit_box->SetMainTransparency(0);
702  eveTrack->AddElement(hit_box);
703  } else {
704  //pixel hit
705  // calculate eigenvalues to draw error-ellipse ----------------------------
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();
710  double pseudo_res_0 = m_errorScale * std::sqrt(ev(0));
711  double pseudo_res_1 = m_errorScale * std::sqrt(ev(1));
712  // finished calcluating, got the values -----------------------------------
713 
714  // calculate the semiaxis of the error ellipse ----------------------------
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);
721  // finished calculating ---------------------------------------------------
722 
723  // rotate and translate everything correctly ------------------------------
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);
729  // finished rotating and translating --------------------------------------
730 
731  cov_shape->SetMainColor(c_recoHitColor);
732  cov_shape->SetMainTransparency(0);
733  eveTrack->AddElement(cov_shape);
734  }
735  }
736  // finished drawing planar hits ---------------------------------------------------
737 
738  // draw spacepoint hits -----------------------------------------------------------
739  if (space_hit) {
740 
741  // get eigenvalues of covariance to know how to draw the ellipsoid ------------
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);
752  // got everything we need -----------------------------------------------------
753 
754 
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()); // the rotation is already clear
758 
759  // set the scaled eigenvalues -------------------------------------------------
760  double pseudo_res_0 = m_errorScale * std::sqrt(ev(0));
761  double pseudo_res_1 = m_errorScale * std::sqrt(ev(1));
762  double pseudo_res_2 = m_errorScale * std::sqrt(ev(2));
763  // finished scaling -----------------------------------------------------------
764 
765  // rotate and translate -------------------------------------------------------
766  TGeoGenTrans det_trans(o(0), o(1), o(2),
767  //std::sqrt(pseudo_res_0/pseudo_res_1/pseudo_res_2), std::sqrt(pseudo_res_1/pseudo_res_0/pseudo_res_2), std::sqrt(pseudo_res_2/pseudo_res_0/pseudo_res_1), // this workaround is necessary due to the "normalization" performed in TGeoGenTrans::SetScale
768  //1/(pseudo_res_0),1/(pseudo_res_1),1/(pseudo_res_2),
769  pseudo_res_0, pseudo_res_1, pseudo_res_2,
770  &det_rot);
771  cov_shape->SetTransMatrix(det_trans);
772  // finished rotating and translating ------------------------------------------
773 
774  cov_shape->SetMainColor(c_recoHitColor);
775  cov_shape->SetMainTransparency(10);
776  eveTrack->AddElement(cov_shape);
777  }
778  // finished drawing spacepoint hits -----------------------------------------------
779 
780  // draw wire hits -----------------------------------------------------------------
781  if (wire_hit) {
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));
787 
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);
791 
792  // rotate and translate -------------------------------------------------------
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(),
799  &det_rot);
800  cov_shape->SetTransMatrix(det_trans);
801  // finished rotating and translating ------------------------------------------
802 
803  cov_shape->SetMainColor(c_recoHitColor);
804  cov_shape->SetMainTransparency(50);
805  eveTrack->AddElement(cov_shape);
806  }
807  // finished drawing wire hits -----------------------------------------------------
808  }
809 
810  }
811  }
812 
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)");
819  //last ref is better than first...
820  lastref.fType = TEvePathMarkD::kReference;
821  firstref.fType = TEvePathMarkD::kDecay;
822  std::reverse(eveTrack->RefPathMarks().begin(), eveTrack->RefPathMarks().end());
823  }
824  }
825  eveTrack->SetTitle(TString::Format("%s\n"
826  "pruned: %s\n"
827  "pT=%.3f, pZ=%.3f\n"
828  "pVal: %e",
829  label.Data(),
830  isPruned ? " yes" : "no",
831  poca_momentum.Pt(), poca_momentum.Pz(),
832  fitResult->getPValue()
833  ));
834  eveTrack->SetLineColor(c_trackColor);
835  eveTrack->SetLineStyle(1);
836  eveTrack->SetLineWidth(3.0);
837 
838 
839  addToGroup("Fitted Tracks", eveTrack);
840  if (track)
841  addObject(track, eveTrack);
842  addObject(belle2Track, eveTrack);
843 }
844 
845 TEveBox* EVEVisualization::boxCreator(const TVector3& o, TVector3 u, TVector3 v, float ud, float vd, float depth)
846 {
847  //force minimum width of polygon to deal with Eve limits
848  float min = 0.04;
849  if (vd < min)
850  vd = min;
851  if (ud < min)
852  ud = min;
853  if (depth < min)
854  depth = min;
855 
856  TEveBox* box = new TEveBox;
857  box->SetPickable(true);
858 
859  TVector3 norm = u.Cross(v);
860  u *= (0.5 * ud);
861  v *= (0.5 * vd);
862  norm *= (0.5 * depth);
863 
864 
865  for (int k = 0; k < 8; ++k) {
866  // Coordinates for all eight corners of the box
867  // as two parallel rectangles, with vertices specified in clockwise direction
868  int signU = ((k + 1) & 2) ? -1 : 1;
869  int signV = (k & 4) ? -1 : 1;
870  int signN = (k & 2) ? -1 : 1;
871  float vertex[3];
872  for (int i = 0; i < 3; ++i) {
873  vertex[i] = o(i) + signU * u(i) + signV * v(i) + signN * norm(i);
874  }
875  box->SetVertex(k, vertex);
876  }
877 
878  return box;
879 }
880 
881 void EVEVisualization::makeLines(TEveTrack* eveTrack, const genfit::StateOnPlane* prevState, const genfit::StateOnPlane* state,
882  const genfit::AbsTrackRep* rep,
883  TEvePathMark::EType_e markType, bool drawErrors, int markerPos)
884 {
885  using namespace genfit;
886 
887  TVector3 pos, dir, oldPos, oldDir;
888  rep->getPosDir(*state, pos, dir);
889  rep->getPosDir(*prevState, oldPos, oldDir);
890 
891  double distA = (pos - oldPos).Mag();
892  double distB = distA;
893  if ((pos - oldPos)*oldDir < 0)
894  distA *= -1.;
895  if ((pos - oldPos)*dir < 0)
896  distB *= -1.;
897 
898  TEvePathMark mark(
899  markType,
900  TEveVector(pos(0), pos(1), pos(2)),
901  TEveVector(dir(0), dir(1), dir(2))
902  );
903  eveTrack->AddPathMark(mark);
904 
905 
906  if (drawErrors) {
907  const MeasuredStateOnPlane* measuredState;
908  if (markerPos == 0)
909  measuredState = dynamic_cast<const MeasuredStateOnPlane*>(prevState);
910  else
911  measuredState = dynamic_cast<const MeasuredStateOnPlane*>(state);
912 
913  if (measuredState != NULL) {
914 
915  // step for evaluate at a distance from the original plane
916  TVector3 eval;
917  if (markerPos == 0)
918  eval = 0.2 * distA * oldDir;
919  else
920  eval = -0.2 * distB * dir;
921 
922 
923  // get cov at first plane
924  TMatrixDSym cov;
925  TVector3 position, direction;
926  rep->getPosMomCov(*measuredState, position, direction, cov);
927 
928  // get eigenvalues & -vectors
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;
933  // limit
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);
938 
939  // get two largest eigenvalues/-vectors
940  if (ev0 < ev1 && ev0 < ev2) {
941  eVec1.SetXYZ(eVec(0, 1), eVec(1, 1), eVec(2, 1));
942  eVec1 *= sqrt(ev1);
943  eVec2.SetXYZ(eVec(0, 2), eVec(1, 2), eVec(2, 2));
944  eVec2 *= sqrt(ev2);
945  } else if (ev1 < ev0 && ev1 < ev2) {
946  eVec1.SetXYZ(eVec(0, 0), eVec(1, 0), eVec(2, 0));
947  eVec1 *= sqrt(ev0);
948  eVec2.SetXYZ(eVec(0, 2), eVec(1, 2), eVec(2, 2));
949  eVec2 *= sqrt(ev2);
950  } else {
951  eVec1.SetXYZ(eVec(0, 0), eVec(1, 0), eVec(2, 0));
952  eVec1 *= sqrt(ev0);
953  eVec2.SetXYZ(eVec(0, 1), eVec(1, 1), eVec(2, 1));
954  eVec2 *= sqrt(ev1);
955  }
956 
957  if (eVec1.Cross(eVec2)*eval < 0)
958  eVec2 *= -1;
959  //assert(eVec1.Cross(eVec2)*eval > 0);
960 
961  TVector3 oldEVec1(eVec1);
962 
963  const int nEdges = 24;
964  std::vector<TVector3> vertices;
965 
966  vertices.push_back(position);
967 
968  // vertices at plane
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);
972  }
973 
974 
975 
976  SharedPlanePtr newPlane(new DetPlane(*(measuredState->getPlane())));
977  newPlane->setO(position + eval);
978 
979  MeasuredStateOnPlane stateCopy(*measuredState);
980  try {
981  rep->extrapolateToPlane(stateCopy, newPlane);
982  } catch (Exception& e) {
983  B2ERROR(e.what());
984  return;
985  }
986 
987  // get cov at 2nd plane
988  rep->getPosMomCov(stateCopy, position, direction, cov);
989 
990  // get eigenvalues & -vectors
991  {
992  TMatrixDSymEigen eigen_values2(cov.GetSub(0, 2, 0, 2));
993  const TVectorD& eVal = eigen_values2.GetEigenValues();
994  const TMatrixD& eVect = eigen_values2.GetEigenVectors();
995  // limit
996  ev0 = std::min(eVal(0), maxErr);
997  ev1 = std::min(eVal(1), maxErr);
998  ev2 = std::min(eVal(2), maxErr);
999 
1000  // get two largest eigenvalues/-vectors
1001  if (ev0 < ev1 && ev0 < ev2) {
1002  eVec1.SetXYZ(eVect(0, 1), eVect(1, 1), eVect(2, 1));
1003  eVec1 *= sqrt(ev1);
1004  eVec2.SetXYZ(eVect(0, 2), eVect(1, 2), eVect(2, 2));
1005  eVec2 *= sqrt(ev2);
1006  } else if (ev1 < ev0 && ev1 < ev2) {
1007  eVec1.SetXYZ(eVect(0, 0), eVect(1, 0), eVect(2, 0));
1008  eVec1 *= sqrt(ev0);
1009  eVec2.SetXYZ(eVect(0, 2), eVect(1, 2), eVect(2, 2));
1010  eVec2 *= sqrt(ev2);
1011  } else {
1012  eVec1.SetXYZ(eVect(0, 0), eVect(1, 0), eVect(2, 0));
1013  eVec1 *= sqrt(ev0);
1014  eVec2.SetXYZ(eVect(0, 1), eVect(1, 1), eVect(2, 1));
1015  } eVec2 *= sqrt(ev1);
1016  }
1017 
1018  if (eVec1.Cross(eVec2)*eval < 0)
1019  eVec2 *= -1;
1020  //assert(eVec1.Cross(eVec2)*eval > 0);
1021 
1022  if (oldEVec1 * eVec1 < 0) {
1023  eVec1 *= -1;
1024  eVec2 *= -1;
1025  }
1026 
1027  // vertices at 2nd plane
1028  double angle0 = eVec1.Angle(oldEVec1);
1029  if (eVec1 * (eval.Cross(oldEVec1)) < 0)
1030  angle0 *= -1;
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);
1034  }
1035 
1036  vertices.push_back(position);
1037 
1038 
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());
1042  }
1043 
1044  assert(vertices.size() == 2 * nEdges + 2);
1045 
1046  int iTri(0);
1047  for (int i = 0; i < nEdges; ++i) {
1048  //error_shape->SetTriangle(iTri++, 0, i+1, (i+1)%nEdges+1);
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);
1051  //error_shape->SetTriangle(iTri++, 2*nEdges+1, i+1+nEdges, (i+1)%nEdges+1+nEdges);
1052  }
1053 
1054  //assert(iTri == nEdges*4);
1055 
1056  error_shape->SetMainColor(c_trackColor);
1057  error_shape->SetMainTransparency(25);
1058  eveTrack->AddElement(error_shape);
1059  }
1060  }
1061 }
1062 
1063 void EVEVisualization::addSimHit(const CDCSimHit* hit, const MCParticle* particle)
1064 {
1065  addSimHit(hit->getPosWire(), particle);
1066 }
1067 void EVEVisualization::addSimHit(const PXDSimHit* hit, const MCParticle* particle)
1068 {
1069  static VXD::GeoCache& geo = VXD::GeoCache::getInstance();
1070  const TVector3& global_pos = geo.get(hit->getSensorID()).pointToGlobal(hit->getPosIn());
1071  addSimHit(global_pos, particle);
1072 }
1073 void EVEVisualization::addSimHit(const SVDSimHit* hit, const MCParticle* particle)
1074 {
1075  static VXD::GeoCache& geo = VXD::GeoCache::getInstance();
1076  const TVector3& global_pos = geo.get(hit->getSensorID()).pointToGlobal(hit->getPosIn());
1077  addSimHit(global_pos, particle);
1078 }
1079 void EVEVisualization::addSimHit(const BKLMSimHit* hit, const MCParticle* particle)
1080 {
1081  TVector3 global_pos;
1082  BKLMSimHitPosition* p = hit->getRelatedFrom<BKLMSimHitPosition>();
1083  if (p) global_pos = p->getPosition();
1084  addSimHit(global_pos, particle);
1085 }
1086 void EVEVisualization::addSimHit(const EKLMSimHit* hit, const MCParticle* particle)
1087 {
1088  const TVector3& global_pos = hit->getPosition();
1089  addSimHit(global_pos, particle);
1090 }
1091 void EVEVisualization::addSimHit(const TVector3& v, const MCParticle* particle)
1092 {
1093  MCTrack* track = addMCParticle(particle);
1094  if (!track)
1095  return; //hide hits from this particle
1096  track->simhits->SetNextPoint(v.x(), v.y(), v.z());
1097 }
1098 
1100 {
1101  if (!particle) {
1102  if (!m_mcparticleTracks[nullptr].simhits) {
1103  const TString pointsTitle("Unassigned SimHits");
1104  m_mcparticleTracks[nullptr].simhits = new TEvePointSet(pointsTitle);
1105  m_mcparticleTracks[nullptr].simhits->SetTitle(pointsTitle);
1106  m_mcparticleTracks[nullptr].simhits->SetMarkerStyle(6);
1107  m_mcparticleTracks[nullptr].simhits->SetMainColor(c_unassignedHitColor);
1108  //m_mcparticleTracks[nullptr].simhits->SetMainTransparency(50);
1109  m_mcparticleTracks[nullptr].track = NULL;
1110  }
1111  return &m_mcparticleTracks[nullptr];
1112  }
1113 
1114  if (m_hideSecondaries and !particle->hasStatus(MCParticle::c_PrimaryParticle)) {
1115  return NULL;
1116  }
1117  if (m_assignToPrimaries) {
1118  while (!particle->hasStatus(MCParticle::c_PrimaryParticle) and particle->getMother())
1119  particle = particle->getMother();
1120  }
1121 
1122  if (!m_mcparticleTracks[particle].track) {
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();
1136  m_mcparticleTracks[particle].track = new TEveTrack(&mctrack, m_trackpropagator);
1137 
1138  //Check if there is a trajectory stored for this particle
1139  const auto mcTrajectories = particle->getRelationsTo<MCParticleTrajectory>();
1140  bool hasTrajectory(false);
1141  for (auto rel : mcTrajectories.relations()) {
1142  //Trajectories with negative weight are from secondary daughters which
1143  //were ignored so we don't use them.
1144  if (rel.weight <= 0) continue;
1145  //Found one, let's add tose point as reference points to the TEveTrack.
1146  //This will force the track propagation to visit all points in order but
1147  //provide smooth helix interpolation between the points
1148  const MCParticleTrajectory& trajectory = dynamic_cast<const MCParticleTrajectory&>(*rel.object);
1149  for (const MCTrajectoryPoint& pt : trajectory) {
1150  m_mcparticleTracks[particle].track->AddPathMark(
1151  TEvePathMark(
1152  //Add the last trajectory point as decay point to prevent TEve to
1153  //propagate beyond the end of the track. So lets compare the adress
1154  //to the address of last point and choose the pathmark accordingly
1155  (&pt == &trajectory.back()) ? TEvePathMark::kDecay : TEvePathMark::kReference,
1156  TEveVector(pt.x, pt.y, pt.z),
1157  TEveVector(pt.px, pt.py, pt.pz)
1158  ));
1159  }
1160  //"There can only be One" -> found a trajectory, stop the loop
1161  hasTrajectory = true;
1162  break;
1163  }
1164 
1165  //If we have the full trajectory there is no need to add additional path marks
1166  if (!hasTrajectory) {
1167  //add daughter vertices - improves track rendering as lost momentum is taken into account
1168  for (int iDaughter = particle->getFirstDaughter(); iDaughter <= particle->getLastDaughter(); iDaughter++) {
1169  if (iDaughter == 0)
1170  continue; //no actual daughter
1171 
1172  const MCParticle* daughter = StoreArray<MCParticle>()[iDaughter - 1];
1173 
1174  TEvePathMarkD refMark(TEvePathMarkD::kDaughter);
1175  refMark.fV.Set(daughter->getProductionVertex());
1176  refMark.fP.Set(daughter->getMomentum());
1177  refMark.fTime = daughter->getProductionTime();
1178  m_mcparticleTracks[particle].track->AddPathMark(refMark);
1179  }
1180 
1181  //neutrals and very short-lived particles should stop somewhere
1182  //(can result in wrong shapes for particles stopped in the detector, so not used there)
1183  if ((TMath::Nint(particle->getCharge()) == 0 or !particle->hasStatus(MCParticle::c_StoppedInDetector))
1184  and mctrack.fDecayed) {
1185  TEvePathMarkD decayMark(TEvePathMarkD::kDecay);
1186  decayMark.fV.Set(particle->getDecayVertex());
1187  m_mcparticleTracks[particle].track->AddPathMark(decayMark);
1188  }
1189  }
1190  TString particle_name(mctrack.GetName());
1191 
1192  //set track title (for popup)
1193  const MCParticle* mom = particle->getMother();
1194  if (mom) {
1195  m_mcparticleTracks[particle].parentParticle = mom;
1196  addMCParticle(mom);
1197  }
1198 
1199  TString title = ObjectInfo::getTitle(particle);
1200  if (!hasTrajectory) {
1201  //Hijack the mother label to show that the track position is only
1202  //extrapolated, not known from simulation
1203  title += "\n(track estimated from initial momentum)";
1204  //Also, show those tracks with dashed lines
1205  m_mcparticleTracks[particle].track->SetLineStyle(2);
1206  }
1207 
1208  m_mcparticleTracks[particle].track->SetTitle(title);
1209 
1210  //add some color (avoid black & white)
1211  switch (abs(pdg)) {
1212  case 11:
1213  m_mcparticleTracks[particle].track->SetLineColor(kAzure);
1214  break;
1215  case 13:
1216  m_mcparticleTracks[particle].track->SetLineColor(kCyan + 1);
1217  break;
1218  case 22:
1219  m_mcparticleTracks[particle].track->SetLineColor(kSpring);
1220  break;
1221  case 211:
1222  m_mcparticleTracks[particle].track->SetLineColor(kGray + 1);
1223  break;
1224  case 321:
1225  m_mcparticleTracks[particle].track->SetLineColor(kRed + 1);
1226  break;
1227  case 2212:
1228  m_mcparticleTracks[particle].track->SetLineColor(kOrange - 2);
1229  break;
1230  default:
1231  m_mcparticleTracks[particle].track->SetLineColor(kMagenta);
1232  }
1233 
1234  //create point set for hits
1235  const TString pointsTitle = "SimHits for " + ObjectInfo::getIdentifier(particle) + " - " + particle_name;
1236  m_mcparticleTracks[particle].simhits = new TEvePointSet(pointsTitle);
1237  m_mcparticleTracks[particle].simhits->SetTitle(pointsTitle);
1238  m_mcparticleTracks[particle].simhits->SetMarkerStyle(6);
1239  m_mcparticleTracks[particle].simhits->SetMainColor(m_mcparticleTracks[particle].track->GetLineColor());
1240  //m_mcparticleTracks[particle].simhits->SetMainTransparency(50);
1241  addObject(particle, m_mcparticleTracks[particle].track);
1242  }
1243  return &m_mcparticleTracks[particle];
1244 }
1245 
1247 {
1248  for (auto& mcTrackPair : m_mcparticleTracks) {
1249  MCTrack& mcTrack = mcTrackPair.second;
1250  if (mcTrack.track) {
1251  if (mcTrack.simhits->Size() > 0) {
1252  mcTrack.track->AddElement(mcTrack.simhits);
1253  } else {
1254  //if we don't add it, remove empty collection
1255  destroyEveElement(mcTrack.simhits);
1256  }
1257 
1258  TEveElement* parent = m_tracklist;
1259  if (mcTrack.parentParticle) {
1260  const auto& parentIt = m_mcparticleTracks.find(mcTrack.parentParticle);
1261  if (parentIt != m_mcparticleTracks.end()) {
1262  parent = parentIt->second.track;
1263  }
1264  }
1265  parent->AddElement(mcTrack.track);
1266  } else { //add simhits directly
1267  gEve->AddElement(mcTrack.simhits);
1268  }
1269  }
1270  gEve->AddElement(m_tracklist);
1271  m_tracklist->MakeTracks();
1272  m_tracklist->SelectByP(c_minPCut, FLT_MAX); //don't show too many particles by default...
1273 
1274  for (size_t i = 0; i < m_options.length(); i++) {
1275  if (m_options.at(i) == 'M') {
1276  m_gftrackpropagator->SetRnrDaughters(true);
1277  m_gftrackpropagator->SetRnrReferences(true);
1278  //m_gftrackpropagator->SetRnrFV(true); //TODO: this crashes?
1279  TMarker m;
1280  m.SetMarkerColor(c_trackMarkerColor);
1281  m.SetMarkerStyle(1); //a single pixel
1282  m.SetMarkerSize(1); //ignored.
1283  m_gftrackpropagator->RefPMAtt() = m;
1284  m_gftrackpropagator->RefFVAtt() = m;
1285  }
1286  }
1287 
1288  m_consttrackpropagator->SetMagField(0, 0, -1.5);
1289 
1290  m_eclData->DataChanged(); //update limits (Empty() won't work otherwise)
1291  if (!m_eclData->Empty()) {
1292  m_eclData->SetAxisFromBins(0.0,
1293  0.0); //epsilon_x/y = 0 so we don't merge neighboring bins. This avoids some rendering issues with projections of small clusters.
1294  m_calo3d->SetData(m_eclData);
1295  }
1296  gEve->AddElement(m_calo3d);
1297 
1298  if (m_unassignedRecoHits) {
1300  gEve->AddElement(m_unassignedRecoHits);
1301  }
1302 
1303 }
1304 
1306 {
1307  if (!gEve)
1308  return;
1309 
1311  for (auto& groupPair : m_groups) {
1312  //store visibility, invalidate pointers
1313  if (groupPair.second.group)
1314  groupPair.second.visible = groupPair.second.group->GetRnrState();
1315  groupPair.second.group = nullptr;
1316  }
1317 
1318  m_mcparticleTracks.clear();
1319  m_shownRecohits.clear();
1320  m_tracklist->DestroyElements();
1321 
1322  //remove ECL data from event
1323  m_calo3d->SetData(NULL);
1324  m_calo3d->DestroyElements();
1325 
1326  //lower energy threshold for ECL
1327  float ecl_threshold = 0.01;
1328  if (m_eclData)
1329  ecl_threshold = m_eclData->GetSliceThreshold(0);
1330 
1331  destroyEveElement(m_eclData);
1332  m_eclData = new TEveCaloDataVec(1); //#slices
1333  m_eclData->IncDenyDestroy();
1334  m_eclData->RefSliceInfo(0).Setup("ECL", ecl_threshold, kRed);
1335 
1338  destroyEveElement(m_unassignedRecoHits);
1339 
1340  gEve->GetSelection()->RemoveElements();
1341  gEve->GetHighlight()->RemoveElements();
1342  //other things are cleaned up by TEve...
1343 }
1344 
1345 
1346 
1347 
1349 {
1350  TVector3 v = vertex->getPos();
1351  TEvePointSet* vertexPoint = new TEvePointSet(ObjectInfo::getInfo(vertex));
1352  //sadly, setting a title for a TEveGeoShape doesn't result in a popup...
1353  vertexPoint->SetTitle(ObjectInfo::getTitle(vertex));
1354  vertexPoint->SetMainColor(c_recoHitColor);
1355  vertexPoint->SetNextPoint(v.x(), v.y(), v.z());
1356 
1357  TMatrixDSymEigen eigen_values(vertex->getCov());
1358  TEveGeoShape* det_shape = new TEveGeoShape(ObjectInfo::getInfo(vertex) + " Error");
1359  det_shape->SetShape(new TGeoSphere(0., 1.)); //Initially created as a sphere, then "scaled" into an ellipsoid.
1360  fixGeoShapeRefCount(det_shape);
1361  const TVectorD& ev = eigen_values.GetEigenValues(); //Assigns the eigenvalues into the "ev" matrix.
1362  const TMatrixD& eVec = eigen_values.GetEigenVectors(); //Assigns the eigenvalues into the "eVec" matrix.
1363  TVector3 eVec1(eVec(0, 0), eVec(1, 0), eVec(2,
1364  0)); //Define the 3 eigenvectors of the covariance matrix as objects of the TVector3 class using constructor.
1365  TVector3 eVec2(eVec(0, 1), eVec(1, 1), eVec(2,
1366  1)); //eVec(i,j) uses the method/overloaded operator ( . ) of the TMatrixT class to return the matrix entry.
1367  TVector3 eVec3(eVec(0, 2), eVec(1, 2), eVec(2, 2));
1368  // got everything we need ----------------------------------------------------- //Eigenvalues(semi axis) of the covariance matrix accquired!
1369 
1370 
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()); // the rotation is already clear
1374 
1375  // set the scaled eigenvalues -------------------------------------------------
1376  //"Scaled" eigenvalues pseudo_res (lengths of the semi axis) are the sqrt of the eigenvalues.
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));
1380 
1381  //B2INFO("The pseudo_res_0/1/2 are " << pseudo_res_0 << "," << pseudo_res_1 << "," << pseudo_res_2); //shows the scaled eigenvalues
1382 
1383 
1384 
1385  // rotate and translate -------------------------------------------------------
1386  TGeoGenTrans det_trans(v(0), v(1), v(2), pseudo_res_0, pseudo_res_1, pseudo_res_2,
1387  &det_rot); //Puts the ellipsoid at the position of the vertex, v(0)=v.x(), operator () overloaded.
1388  det_shape->SetTransMatrix(det_trans);
1389  // finished rotating and translating ------------------------------------------
1390 
1391  det_shape->SetMainColor(kOrange); //The color of the error ellipsoid.
1392  det_shape->SetMainTransparency(0);
1393 
1394  vertexPoint->AddElement(det_shape);
1395  addToGroup("Vertices", vertexPoint);
1396  addObject(vertex, vertexPoint);
1397 }
1398 
1399 
1401 {
1402 
1403  // only display c_nPhotons hypothesis clusters
1404  if (cluster->hasHypothesis(ECLCluster::EHypothesisBit::c_nPhotons)) {
1405 
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;
1413  }
1414 
1415  if (!std::isfinite(dPhi) or !std::isfinite(dTheta)) {
1416  B2ERROR("ECLCluster phi or theta error is NaN or infinite, skipping cluster!");
1417  return;
1418  }
1419 
1420  //convert theta +- dTheta into eta +- dEta
1421  TVector3 thetaLow;
1422  thetaLow.SetPtThetaPhi(1.0, cluster->getTheta() - dTheta, phi);
1423  TVector3 thetaHigh;
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);
1429  }
1430 
1431  int id = m_eclData->AddTower(etaLow, etaHigh, phi - dPhi, phi + dPhi);
1432  m_eclData->FillSlice(0, cluster->getEnergy(ECLCluster::EHypothesisBit::c_nPhotons));
1434  }
1435 }
1436 
1438 {
1439  const double layerThicknessCm = 3.16; //TDR, Fig 10.2
1440  const double layerDistanceCm = 9.1 - layerThicknessCm;
1441 
1442  TVector3 startPos = cluster->getClusterPosition(); //position of first RPC plane
1443  TVector3 dir; //direction of cluster stack, Mag() == distance between planes
1444  TVector3 a, b; //defines RPC plane
1445  bool isBarrel = (startPos.Z() > -175.0 and startPos.Z() < 270.0);
1446  if (isBarrel) {
1447  //barrel
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);
1454 
1455  const double barrelRadiusCm = 204.0;
1456  startPos.SetMag(barrelRadiusCm / perp.Dot(startPos.Unit()));
1457 
1458  dir = startPos.Unit();
1459  dir.SetMag((layerDistanceCm + layerThicknessCm) / perp.Dot(dir));
1460  } else {
1461  //endcap
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;
1467 
1468  double scaleFac = endcapStartZ / startPos.z();
1469  startPos.SetMag(startPos.Mag() * scaleFac);
1470 
1471  dir = startPos.Unit();
1472  dir.SetMag((layerDistanceCm + layerThicknessCm) / fabs(dir.z()));
1473  }
1474 
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);
1479  layer->SetMainColor(c_klmClusterColor);
1480  layer->SetMainTransparency(70);
1481  layer->SetName(ObjectInfo::getIdentifier(cluster));
1482  layer->SetTitle(ObjectInfo::getTitle(cluster));
1483 
1484  addToGroup(std::string("KLMClusters/") + ObjectInfo::getIdentifier(cluster).Data(), layer);
1485  addObject(cluster, layer);
1486  }
1487 }
1488 
1490 {
1491  //TVector3 globalPosition= bklm2dhit->getGlobalPosition();
1493  const bklm::Module* module = m_GeoPar->findModule(bklm2dhit->getSection(), bklm2dhit->getSector(), bklm2dhit->getLayer());
1494 
1495  CLHEP::Hep3Vector global;
1496  //+++ global coordinates of the hit
1497  global[0] = bklm2dhit->getGlobalPosition()[0];
1498  global[1] = bklm2dhit->getGlobalPosition()[1];
1499  global[2] = bklm2dhit->getGlobalPosition()[2];
1500 
1501  //+++ local coordinates of the hit
1502  CLHEP::Hep3Vector local = module->globalToLocal(global);
1503  //double localU = local[1]; //phi
1504  //double localV = local[2]; //z
1505  int Nphistrip = bklm2dhit->getPhiStripMax() - bklm2dhit->getPhiStripMin() + 1;
1506  int Nztrip = bklm2dhit->getZStripMax() - bklm2dhit->getZStripMin() + 1;
1507  double du = module->getPhiStripWidth() * Nphistrip;
1508  double dv = module->getZStripWidth() * Nztrip;
1509 
1510  //Let's do some simple thing
1511  CLHEP::Hep3Vector localU(local[0], local[1] + 1.0, local[2]);
1512  CLHEP::Hep3Vector localV(local[0], local[1], local[2] + 1.0);
1513 
1514  CLHEP::Hep3Vector globalU = module->localToGlobal(localU);
1515  CLHEP::Hep3Vector globalV = module->localToGlobal(localV);
1516 
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]);
1520 
1521  //Lest's just assign the depth is 1.0 cm (thickness of a layer), better to update
1522  TEveBox* bklmbox = boxCreator(o, u - o, v - o, du, dv, 1.0);
1523 
1524  bklmbox->SetMainColor(kGreen);
1525  //bklmbox->SetName((std::to_string(hitModule)).c_str());
1526  bklmbox->SetName("BKLMHit2d");
1527 
1528  addToGroup("BKLM2dHits", bklmbox);
1529  addObject(bklm2dhit, bklmbox);
1530 }
1531 
1533 {
1534  const double du = 2.0;
1535  const double dv = 2.0;
1536  TVector3 o = eklm2dhit->getPosition();
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");
1542  addToGroup("EKLM2dHits", eklmbox);
1543  addObject(eklm2dhit, eklmbox);
1544 }
1545 
1547 {
1549 
1550  VxdID sensorID = roi->getSensorID();
1551  const VXD::SensorInfoBase& aSensorInfo = aGeometry.getSensorInfo(sensorID);
1552 
1553  double minU = aSensorInfo.getUCellPosition(roi->getMinUid(), roi->getMinVid());
1554  double minV = aSensorInfo.getVCellPosition(roi->getMinVid());
1555  double maxU = aSensorInfo.getUCellPosition(roi->getMaxUid(), roi->getMaxVid());
1556  double maxV = aSensorInfo.getVCellPosition(roi->getMaxVid());
1557 
1558 
1559  TVector3 localA(minU, minV, 0);
1560  TVector3 localB(minU, maxV, 0);
1561  TVector3 localC(maxU, minV, 0);
1562 
1563  TVector3 globalA = aSensorInfo.pointToGlobal(localA);
1564  TVector3 globalB = aSensorInfo.pointToGlobal(localB);
1565  TVector3 globalC = aSensorInfo.pointToGlobal(localC);
1566 
1567  TEveBox* ROIbox = boxCreator((globalB + globalC) * 0.5 , globalB - globalA, globalC - globalA, 1, 1, 0.01);
1568 
1569  ROIbox->SetName(ObjectInfo::getIdentifier(roi));
1570  ROIbox->SetMainColor(kSpring - 9);
1571  ROIbox->SetMainTransparency(50);
1572 
1573  addToGroup("ROIs", ROIbox);
1574  addObject(roi, ROIbox);
1575 }
1576 
1577 void EVEVisualization::addRecoHit(const SVDCluster* hit, TEveStraightLineSet* lines)
1578 {
1579  static VXD::GeoCache& geo = VXD::GeoCache::getInstance();
1580  const VXD::SensorInfoBase& sensor = geo.get(hit->getSensorID());
1581 
1582  TVector3 a, b;
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));
1587  } else {
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));
1591  }
1592 
1593  lines->AddLine(a.x(), a.y(), a.z(), b.x(), b.y(), b.z());
1594  m_shownRecohits.insert(hit);
1595 }
1596 
1597 void EVEVisualization::addRecoHit(const CDCHit* hit, TEveStraightLineSet* lines)
1598 {
1600  const TVector3& wire_pos_f = cdcgeo.wireForwardPosition(WireID(hit->getID()));
1601  const TVector3& wire_pos_b = cdcgeo.wireBackwardPosition(WireID(hit->getID()));
1602 
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());
1604  m_shownRecohits.insert(hit);
1605 
1606 }
1607 
1608 void EVEVisualization::addCDCHit(const CDCHit* hit, bool showTriggerHits)
1609 {
1611  const TVector3& wire_pos_f = cdcgeo.wireForwardPosition(WireID(hit->getID()));
1612  const TVector3& wire_pos_b = cdcgeo.wireBackwardPosition(WireID(hit->getID()));
1613  static CDC::RealisticTDCCountTranslator tdcTranslator;
1614  TEveGeoShape* cov_shape = new TEveGeoShape("cov_shape");
1615  //TODO: leftrightflag not set! (same for other parameters, unsure which ones should be set)
1616  double driftLength = tdcTranslator.getDriftLength(hit->getTDCCount(), WireID(hit->getID()));
1617  double driftLengthRes = tdcTranslator.getDriftLengthResolution(driftLength, WireID(hit->getID()));
1618  driftLengthRes = std::max(driftLengthRes, 0.005);
1619  const double lengthOfWireSection = 3.0;
1620 
1621  //z in wire direction, x,y orthogonal
1622  const TVector3 zaxis = wire_pos_b - wire_pos_f;
1623  const TVector3 xaxis = zaxis.Orthogonal();
1624  const TVector3 yaxis = xaxis.Cross(zaxis);
1625 
1626  // move to z=0
1627  const TVector3 midPoint = wire_pos_f - zaxis * (wire_pos_f.z() / zaxis.z());
1628 
1629  cov_shape->SetShape(new TGeoTube(std::max(0., (double)(driftLength - driftLengthRes)), driftLength + driftLengthRes,
1630  lengthOfWireSection));
1631  fixGeoShapeRefCount(cov_shape);
1632 
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()
1637  );
1638 
1639  TGeoCombiTrans det_trans(midPoint(0), midPoint(1), midPoint(2), &det_rot);
1640  cov_shape->SetTransMatrix(det_trans);
1641 
1642  // get relation to trigger track segments
1643  bool isPartOfTS = false;
1644  const auto segments = hit->getRelationsFrom<CDCTriggerSegmentHit>();
1645  if (showTriggerHits && segments.size() > 0) {
1646  isPartOfTS = true;
1647  }
1648 
1649  if (hit->getISuperLayer() % 2 == 0) {
1650  if (isPartOfTS)
1651  cov_shape->SetMainColor(kCyan + 3);
1652  else
1653  cov_shape->SetMainColor(kCyan);
1654  } else {
1655  if (isPartOfTS)
1656  cov_shape->SetMainColor(kPink + 6);
1657  else
1658  cov_shape->SetMainColor(kPink + 7);
1659  }
1660 
1661  cov_shape->SetMainTransparency(50);
1662  cov_shape->SetName(ObjectInfo::getIdentifier(hit));
1663  cov_shape->SetTitle(ObjectInfo::getInfo(hit) + TString::Format("\nWire ID: %d\nADC: %d\nTDC: %d",
1664  hit->getID(), hit->getADCCount(), hit->getTDCCount()));
1665 
1666  addToGroup("CDCHits", cov_shape);
1667  addObject(hit, cov_shape);
1668  if (isPartOfTS) {
1669  addToGroup("CDCTriggerSegmentHits", cov_shape);
1670  for (auto rel : segments.relations()) {
1671  addObject(rel.object, cov_shape);
1672  }
1673  }
1674 }
1675 
1676 void EVEVisualization::addCDCTriggerSegmentHit(const std::string& collectionName, const CDCTriggerSegmentHit* hit)
1677 {
1679  TEveStraightLineSet* shape = new TEveStraightLineSet();
1680 
1681  // get center wire
1682  unsigned iL = WireID(hit->getID()).getICLayer();
1683  if (hit->getPriorityPosition() < 3) iL -= 1;
1684  unsigned nWires = cdcgeo.nWiresInLayer(iL);
1685  unsigned iCenter = hit->getIWire();
1686  if (hit->getPriorityPosition() == 1) iCenter += 1;
1687 
1688  // a track segment consists of 11 wires (15 in SL0) in a special configuration
1689  // -> get the shift with respect to the center wire (*) for all wires
1690  // SL 1-8:
1691  // _ _ _
1692  // |_|_|_|
1693  // |_|_|
1694  // |*|
1695  // |_|_|
1696  // |_|_|_|
1697  std::vector<int> layershift = { -2, -1, 0, 1, 2};
1698  std::vector<std::vector<float>> cellshift = {
1699  { -1, 0, 1},
1700  { -0.5, 0.5},
1701  { 0},
1702  { -0.5, 0.5},
1703  { -1, 0, 1}
1704  };
1705  // SL 0:
1706  // _ _ _ _ _
1707  // |_|_|_|_|_|
1708  // |_|_|_|_|
1709  // |_|_|_|
1710  // |_|_|
1711  // |*|
1712  if (hit->getISuperLayer() == 0) {
1713  layershift = { 0, 1, 2, 3, 4};
1714  cellshift = {
1715  { 0},
1716  { -0.5, 0.5},
1717  { -1, 0, 1},
1718  { -1.5, -0.5, 0.5, 1.5},
1719  { -2, -1, 0, 1, 2}
1720  };
1721  }
1722 
1723  // draw all cells in segment
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;
1734 
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());
1739  }
1740  }
1741 
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);
1750  }
1751  }
1752 
1753  if (hit->getISuperLayer() % 2 == 0) {
1754  shape->SetMainColor(kCyan + 3);
1755  } else {
1756  shape->SetMainColor(kPink + 6);
1757  }
1758 
1759  shape->SetName(ObjectInfo::getIdentifier(hit));
1760  shape->SetTitle(ObjectInfo::getTitle(hit) +
1761  TString::Format("\nPriority: %d\nLeft/Right: %d",
1762  hit->getPriorityPosition(), hit->getLeftRight()));
1763  addToGroup(collectionName, shape);
1764  addObject(hit, shape);
1765 }
1766 
1768 {
1770 
1771  int hitModule = hit->getModule();
1772  float fi = arichGeo->getDetectorPlane().getSlotPhi(hitModule);
1773 
1774  TVector3 centerPos3D = hit->getPosition();
1775 
1776  TVector3 channelX(1, 0, 0); channelX.RotateZ(fi);
1777  TVector3 channelY(0, 1, 0); channelY.RotateZ(fi);
1778 
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());
1783 
1784  addToGroup("ARICHHits", arichbox);
1785  addObject(hit, arichbox);
1786 }
1787 
1789 {
1791  std::map<int, int> m_topSummary;
1792  for (const TOPDigit& hit : digits) {
1793  int mod = hit.getModuleID();
1794  ++m_topSummary[mod];
1795  }
1796  int maxcount = 0;
1797  for (auto modCountPair : m_topSummary) {
1798  if (modCountPair.second > maxcount)
1799  maxcount = modCountPair.second;
1800  }
1801  for (auto modCountPair : m_topSummary) {
1802  const auto& topmod = TOP::TOPGeometryPar::Instance()->getGeometry()->getModule(modCountPair.first);
1803  double phi = topmod.getPhi();
1804  double r_center = topmod.getRadius();
1805  double z = topmod.getZc();
1806 
1807  TVector3 centerPos3D;
1808  centerPos3D.SetMagThetaPhi(r_center, M_PI / 2, phi);
1809  centerPos3D.SetZ(z);
1810 
1811  TVector3 channelX(1, 0, 0); channelX.RotateZ(phi);
1812  TVector3 channelY(0, 1, 0); channelY.RotateZ(phi);
1813 
1814  //bar is a bit thicker so we can mouse over without getting the geometry
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));
1822 
1823  addToGroup("TOP Modules", moduleBox);
1824  //associate all TOPDigits with this module.
1825  for (const TOPDigit& hit : digits) {
1826  if (modCountPair.first == hit.getModuleID())
1827  addObject(&hit, moduleBox);
1828  }
1829  }
1830 }
1831 
1832 
1834 {
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());
1842  addToGroup("DisplayData", text);
1843  }
1844 
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());
1852  }
1853  addToGroup("DisplayData", points);
1854  }
1855 
1856  int randomColor = 2; //primary colours, changing rapidly with index
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;
1866  randomColor++;
1867  }
1868  eveArrow->SetMainColor(arrowColor);
1869 
1870  //add label
1871  TEveText* text = new TEveText(arrow.name.c_str());
1872  text->SetMainColor(arrowColor);
1873  //in middle of arrow, with some slight offset
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);
1877  addToGroup("DisplayData", eveArrow);
1878  }
1879 
1880 }
1881 void EVEVisualization::addObject(const TObject* dataStoreObject, TEveElement* visualRepresentation)
1882 {
1883  VisualRepMap::getInstance()->add(dataStoreObject, visualRepresentation);
1884 }
1885 
1886 void EVEVisualization::addToGroup(const std::string& name, TEveElement* elem)
1887 {
1888  //slashes at beginning and end are ignored
1889  const std::string& groupName = boost::algorithm::trim_copy_if(name, boost::algorithm::is_any_of("/"));
1890 
1891  TEveElementList* group = m_groups[groupName].group;
1892  if (!group) {
1893  group = new TEveElementList(groupName.c_str(), groupName.c_str());
1894  group->SetRnrState(m_groups[groupName].visible);
1895  m_groups[groupName].group = group;
1896 
1897  //if groupName contains '/', remove last bit and add to parent group
1898  //e.g. if groupName=A/B/C, call addToGroup("A/B", groupC)
1899  auto lastSlash = boost::algorithm::find_last(groupName, "/");
1900  if (lastSlash) {
1901  const std::string parentGroup(groupName.begin(), lastSlash.begin());
1902  const std::string thisGroup(lastSlash.end(), groupName.end());
1903  group->SetElementName(thisGroup.c_str());
1904  addToGroup(parentGroup, group);
1905  } else {
1906  gEve->AddElement(group);
1907  }
1908  }
1909  group->AddElement(elem);
1910 }
1911 
Belle2::EVEVisualization::m_drawCardinalRep
bool m_drawCardinalRep
Draw cardinal representation in addTrack.
Definition: EVEVisualization.h:364
genfit::Exception
Exception class for error handling in GENFIT (provides storage for diagnostic information)
Definition: Exception.h:48
genfit::TrackPoint
Object containing AbsMeasurement and AbsFitterInfo objects.
Definition: TrackPoint.h:46
Belle2::BKLMHit2d::getPhiStripMin
int getPhiStripMin() const
Get lowest phi-measuring strip number.
Definition: BKLMHit2d.h:95
Belle2::DisplayData::m_labels
std::vector< std::pair< std::string, TVector3 > > m_labels
text labels (to be shown at a given position).
Definition: DisplayData.h:119
genfit::WireMeasurementNew
Class for measurements in wire detectors (Straw tubes and drift chambers) which do not measure the co...
Definition: WireMeasurementNew.h:56
Belle2::EVEVisualization::addToGroup
void addToGroup(const std::string &name, TEveElement *elem)
Add 'elem' to the element group 'name' (created if necessary).
Definition: EVEVisualization.cc:1886
Belle2::WireID
Class to identify a wire inside the CDC.
Definition: WireID.h:44
Belle2::SVDRecoHit
SVDRecoHit - an extended form of SVDHit containing geometry information.
Definition: SVDRecoHit.h:57
Belle2::EVEVisualization::m_shownRecohits
std::set< const TObject * > m_shownRecohits
List of shown recohits (PXDCluster, SVDCluster, CDCHit).
Definition: EVEVisualization.h:353
Belle2::CDC::RealisticTDCCountTranslator::getDriftLengthResolution
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.
Definition: RealisticTDCCountTranslator.cc:140
genfit::SharedPlanePtr
std::shared_ptr< genfit::DetPlane > SharedPlanePtr
Shared Pointer to a DetPlane.
Definition: SharedPlanePtr.h:40
Belle2::MCParticle::c_StoppedInDetector
@ c_StoppedInDetector
bit 3: Particle was stopped in the detector (the simulation volume).
Definition: MCParticle.h:64
Belle2::EveGeometry::getMaxR
double getMaxR()
find a point that is inside the top node.
Definition: EveGeometry.cc:176
Belle2::VxdID
Class to uniquely identify a any structure of the PXD and SVD.
Definition: VxdID.h:43
Belle2::SVDSimHit
Class SVDSimHit - Geant4 simulated hit for the SVD.
Definition: SVDSimHit.h:28
Belle2::CDC::CDCGeometryPar::wireForwardPosition
const TVector3 wireForwardPosition(int layerId, int cellId, EWirePosition set=c_Base) const
Returns the forward position of the input sense wire.
Definition: CDCGeometryPar.cc:1625
Belle2::EVEVisualization::c_recoHitColor
const static int c_recoHitColor
Color for reco hits.
Definition: EVEVisualization.h:85
genfit::AbsTrackRep::getPosDir
void getPosDir(const StateOnPlane &state, TVector3 &pos, TVector3 &dir) const
Get cartesian position and direction vector of a state.
Definition: AbsTrackRep.h:252
Belle2::EVEVisualization::m_unassignedRecoHits
TEveStraightLineSet * m_unassignedRecoHits
Unassigned recohits.
Definition: EVEVisualization.h:356
genfit::GFRaveVertex
GFRaveVertex class.
Definition: GFRaveVertex.h:48
Belle2::EVEVisualization::~EVEVisualization
~EVEVisualization()
Destructor.
Definition: EVEVisualization.cc:179
Belle2::EVEVisualization::m_consttrackpropagator
TEveTrackPropagator * m_consttrackpropagator
Track propagator for CDCTriggerTracks (uses constant B field)
Definition: EVEVisualization.h:344
genfit::MeasuredStateOnPlane
#StateOnPlane with additional covariance matrix.
Definition: MeasuredStateOnPlane.h:39
genfit::AbsTrackRep::extrapolateToPlane
virtual double extrapolateToPlane(StateOnPlane &state, const genfit::SharedPlanePtr &plane, bool stopAtBoundary=false, bool calcJacobianNoise=false) const =0
Extrapolates the state to plane, and returns the extrapolation length and, via reference,...
Belle2::CDC::RealisticTDCCountTranslator
Translator mirroring the realistic Digitization.
Definition: RealisticTDCCountTranslator.h:36
genfit::FitStatus::isTrackPruned
bool isTrackPruned() const
Has the track been pruned after the fit?
Definition: FitStatus.h:116
Belle2::TrackFitResult::getMomentum
TVector3 getMomentum() const
Getter for vector of momentum at closest approach of track in r/phi projection.
Definition: TrackFitResult.h:116
Belle2::ECLCluster
ECL cluster data.
Definition: ECLCluster.h:39
Belle2::EVEVisualization::addECLCluster
void addECLCluster(const ECLCluster *cluster)
Add a reconstructed cluster in the ECL.
Definition: EVEVisualization.cc:1400
Belle2::RecoTrack::getSVDHitList
std::vector< Belle2::RecoTrack::UsedSVDHit * > getSVDHitList() const
Return an unsorted list of svd hits.
Definition: RecoTrack.h:449
genfit::AbsFitterInfo
This class collects all information needed and produced by a specific AbsFitter and is specific to on...
Definition: AbsFitterInfo.h:42
Belle2::VisualRepMap::clear
void clear()
Remove all contents in map.
Definition: VisualRepMap.cc:48
Belle2::VXD::GeoCache::get
static const SensorInfoBase & get(Belle2::VxdID id)
Return a reference to the SensorInfo of a given SensorID.
Definition: GeoCache.h:141
Belle2::CDCHit
Class containing the result of the unpacker in raw data and the result of the digitizer in simulation...
Definition: CDCHit.h:51
Belle2::RecoTrack::getCDCHitList
std::vector< Belle2::RecoTrack::UsedCDCHit * > getCDCHitList() const
Return an unsorted list of cdc hits.
Definition: RecoTrack.h:446
Belle2::MCTrajectoryPoint
Small struct to encode a position/momentum without additional overhead.
Definition: MCTrajectoryPoint.h:21
Belle2::VisualRepMap::add
void add(const TObject *dataStoreObject, TEveElement *visualRepresentation)
Generic function to keep track of which objects have which visual representation.
Definition: VisualRepMap.cc:136
Belle2::EVEVisualization::m_groups
std::map< std::string, ElementGroup > m_groups
name -> grouping element.
Definition: EVEVisualization.h:332
Belle2::TrackFitResult::getPValue
double getPValue() const
Getter for Chi2 Probability of the track fit.
Definition: TrackFitResult.h:163
Belle2::EVEVisualization::showUserData
void showUserData(const DisplayData &displayData)
Add user-defined data (labels, points, etc.)
Definition: EVEVisualization.cc:1833
genfit::StateOnPlane
A state with arbitrary dimension defined in a DetPlane.
Definition: StateOnPlane.h:47
genfit::WirePointMeasurement
Class for measurements in wire detectors (Straw tubes and drift chambers) which can measure the coord...
Definition: WirePointMeasurement.h:51
Belle2::EVEVisualization::addCDCTriggerSegmentHit
void addCDCTriggerSegmentHit(const std::string &collectionName, const CDCTriggerSegmentHit *hit)
show outline of track segments.
Definition: EVEVisualization.cc:1676
genfit
Defines for I/O streams used for error and debug printing.
Definition: AlignablePXDRecoHit.h:19
Belle2::EVEVisualization::m_tracklist
TEveTrackList * m_tracklist
parent object for MC tracks.
Definition: EVEVisualization.h:335
Belle2::BKLMHit2d::getSection
int getSection() const
Get section number.
Definition: BKLMHit2d.h:74
Belle2::EVEVisualization::makeTracks
void makeTracks()
Create visual representation of all tracks.
Definition: EVEVisualization.cc:1246
Belle2::CDCTriggerTrack
Track created by the CDC trigger.
Definition: CDCTriggerTrack.h:15
Belle2::EVEVisualization::c_trackMarkerColor
const static int c_trackMarkerColor
Color for track markers.
Definition: EVEVisualization.h:91
Belle2::EVEVisualization::c_minPCut
static constexpr double c_minPCut
don't show MCParticles with momentum below this cutoff.
Definition: EVEVisualization.h:361
Belle2::ECLCluster::EHypothesisBit::c_nPhotons
@ c_nPhotons
CR is split into n photons (N1)
Belle2::VXD::SensorInfoBase
Base class to provide Sensor Information for PXD and SVD.
Definition: SensorInfoBase.h:40
genfit::AbsTrackRep
Abstract base class for a track representation.
Definition: AbsTrackRep.h:66
Belle2::RelationsInterface::getRelated
T * getRelated(const std::string &name="", const std::string &namedRelation="") const
Get the object to or from which this object has a relation.
Definition: RelationsObject.h:280
Belle2::EVEVisualization::c_unassignedHitColor
const static int c_unassignedHitColor
Color for unassigned (reco)hits.
Definition: EVEVisualization.h:93
Belle2::EVEVisualization::MCTrack
Hold MC tracks and associated visualisation objects.
Definition: EVEVisualization.h:71
Belle2::EVEVisualization::c_trackColor
const static int c_trackColor
Color for tracks.
Definition: EVEVisualization.h:89
Belle2::CDCSimHit
Example Detector.
Definition: CDCSimHit.h:33
Belle2::EVEVisualization::m_drawBackward
bool m_drawBackward
draw backward in addTrack
Definition: EVEVisualization.h:376
Belle2::EVEVisualization::addTOPDigits
void addTOPDigits(const StoreArray< TOPDigit > &digits)
Add TOPDigits (shown aggregated per module).
Definition: EVEVisualization.cc:1788
Belle2::EVEVisualization::m_unassignedRecoHitsVisibility
bool m_unassignedRecoHitsVisibility
is m_unassignedRecoHits visible?
Definition: EVEVisualization.h:358
Belle2::BKLMHit2d::getZStripMin
int getZStripMin() const
Get lowest z-measuring strip number.
Definition: BKLMHit2d.h:116
Belle2::EVEVisualization::MCTrack::simhits
TEvePointSet * simhits
simhit positions.
Definition: EVEVisualization.h:73
Belle2::EVEVisualization::addBKLMHit2d
void addBKLMHit2d(const BKLMHit2d *bklm2dhit)
Add a reconstructed 2d hit in the BKLM.
Definition: EVEVisualization.cc:1489
genfit::GblFitterInfo::getFittedState
const MeasuredStateOnPlane & getFittedState(bool afterKink=true) const override
Get the prediction at this point Always biased in GBL (global fit) There are 2 states,...
Definition: GblFitterInfo.cc:398
Belle2::TrackFitResult
Values of the result of a track fit with a given particle hypothesis.
Definition: TrackFitResult.h:59
Belle2::bklm::Module
Define the geometry of a BKLM module Each sector [octant] contains Modules.
Definition: Module.h:86
Belle2::bklm::GeometryPar
Provides BKLM geometry parameters for simulation, reconstruction etc (from Gearbox or DataBase)
Definition: GeometryPar.h:48
Belle2::TrackFitResult::getPosition
TVector3 getPosition() const
Getter for vector of position at closest approach of track in r/phi projection.
Definition: TrackFitResult.h:109
genfit::PlanarMeasurement
Measurement class implementing a planar hit geometry (1 or 2D).
Definition: PlanarMeasurement.h:44
Belle2::EVEVisualization::addTrackCandidate
void addTrackCandidate(const std::string &collectionName, const RecoTrack &recoTrack)
Add a RecoTrack, to evaluate track finding.
Definition: EVEVisualization.cc:195
Belle2::EVEVisualization::m_assignToPrimaries
bool m_assignToPrimaries
If true, hits created by secondary particles (e.g.
Definition: EVEVisualization.h:323
Belle2::BKLMHit2d::getGlobalPosition
TVector3 getGlobalPosition(void) const
Get 3D hit position in global coordinates.
Definition: BKLMHit2d.h:187
Belle2::TOPGeometry::getModule
const TOPGeoModule & getModule(int moduleID) const
Returns module.
Definition: TOPGeometry.cc:44
Belle2::DBObjPtr
Class for accessing objects in the database.
Definition: DBObjPtr.h:31
Belle2::CDCRecoHit
This class is used to transfer CDC information to the track fit.
Definition: CDCRecoHit.h:43
Belle2::EVEVisualization::MCTrack::track
TEveTrack * track
the actual MC track.
Definition: EVEVisualization.h:72
Belle2::EVEVisualization::addRecoHit
void addRecoHit(const SomeVXDHit *hit, TEveStraightLineSet *lines)
adds given VXD hit to lines.
Definition: EVEVisualization.h:287
Belle2::VisualRepMap::addCluster
void addCluster(const TObject *dataStoreObject, TEveCaloData *caloData, int towerID)
Selection inside TEveCalo* is complicated, use this to keep track of ECL clusters.
Definition: VisualRepMap.cc:148
Belle2::RecoTrack::getCreatedTrackPoint
const genfit::TrackPoint * getCreatedTrackPoint(const RecoHitInformation *recoHitInformation) const
Get a pointer to the TrackPoint that was created from this hit.
Definition: RecoTrack.cc:220
Belle2::TOPDigit
Class to store TOP digitized hits (output of TOPDigitizer or raw data unpacker) relations to TOPSimHi...
Definition: TOPDigit.h:34
Belle2::TangoPalette::getTColorID
int getTColorID(const std::string &tangoName, int tangoId=1)
Get TColor ID for given name in tango colour palette.
Definition: ColorPalette.cc:31
Belle2::EKLMSimHit
Class EKLMSimHit stores information on particular Geant step; using information from TrackID and Pare...
Definition: EKLMSimHit.h:41
Belle2::EVEVisualization::MCTrack::parentParticle
const MCParticle * parentParticle
parent particle, or nullptr.
Definition: EVEVisualization.h:74
genfit::TrackPoint::getFitterInfo
AbsFitterInfo * getFitterInfo(const AbsTrackRep *rep=nullptr) const
Get fitterInfo for rep. Per default, use cardinal rep.
Definition: TrackPoint.cc:170
Belle2::EVEVisualization::EVEVisualization
EVEVisualization()
Constructor.
Definition: EVEVisualization.cc:127
Belle2::TOP::TOPGeometryPar::Instance
static TOPGeometryPar * Instance()
Static method to obtain the pointer to its instance.
Definition: TOPGeometryPar.cc:45
genfit::AbsMeasurement
Contains the measurement and covariance in raw detector coordinates.
Definition: AbsMeasurement.h:42
Belle2::MCParticleTrajectory
Class to save the full simulated trajectory of a particle.
Definition: MCParticleTrajectory.h:32
Belle2::RecoTrack
This is the Reconstruction Event-Data Model Track.
Definition: RecoTrack.h:78
Belle2::VisualRepMap::getInstance
static VisualRepMap * getInstance()
get instance pointer.
Definition: VisualRepMap.cc:38
Belle2::EVEVisualization::m_drawForward
bool m_drawForward
draw forward in addTrack
Definition: EVEVisualization.h:373
Belle2::CDC::CDCGeometryPar
The Class for CDC Geometry Parameters.
Definition: CDCGeometryPar.h:75
Belle2::Const::pion
static const ChargedStable pion
charged pion particle
Definition: Const.h:535
Belle2::EVEVisualization::m_drawErrors
bool m_drawErrors
Draw errors in addTrack.
Definition: EVEVisualization.h:367
Belle2::ARICHHit
Datastore class that holds photon hits. Input to the reconstruction.
Definition: ARICHHit.h:33
Belle2::ObjectInfo::getTitle
TString getTitle(const TObject *obj)
Get plain text for TEve object titles (shown on mouse-over).
Definition: ObjectInfo.cc:61
Belle2::RecoTrack::getPositionSeed
TVector3 getPositionSeed() const
Return the position seed stored in the reco track. ATTENTION: This is not the fitted position.
Definition: RecoTrack.h:477
Belle2::BKLMSimHitPosition
Store one simulation hit's global position as a ROOT object.
Definition: BKLMSimHitPosition.h:34
genfit::KalmanFitterInfo
Collects information needed and produced by a AbsKalmanFitter implementations and is specific to one ...
Definition: KalmanFitterInfo.h:44
Belle2::EVEVisualization::addROI
void addROI(const ROIid *roi)
Add a Region Of Interest, computed by the PXDDataReduction module.
Definition: EVEVisualization.cc:1546
Belle2::CDC::CDCGeometryPar::wireBackwardPosition
const TVector3 wireBackwardPosition(int layerId, int cellId, EWirePosition set=c_Base) const
Returns the backward position of the input sense wire.
Definition: CDCGeometryPar.cc:1662
Belle2::bklm::GeometryPar::instance
static GeometryPar * instance(void)
Static method to get a reference to the singleton GeometryPar instance.
Definition: GeometryPar.cc:30
Belle2::ObjectInfo::getInfo
TString getInfo(const TObject *obj)
Get object info HTML (e.g.
Definition: ObjectInfo.cc:48
Belle2::BKLMHit2d::getSector
int getSector() const
Get sector number.
Definition: BKLMHit2d.h:81
genfit::GblFitterInfo::getReferenceState
StateOnPlane getReferenceState() const
Returns (copy of) the stored reference 5D state at current plane with internal rep.
Definition: GblFitterInfo.h:213
Belle2::EVEVisualization::addCDCTriggerTrack
void addCDCTriggerTrack(const std::string &collectionName, const CDCTriggerTrack &track)
Add a CDCTriggerTrack.
Definition: EVEVisualization.cc:338
Belle2::CDC::CDCGeometryPar::Instance
static CDCGeometryPar & Instance(const CDCGeometry *=nullptr)
Static method to get a reference to the CDCGeometryPar instance.
Definition: CDCGeometryPar.cc:41
Belle2::EVEVisualization::addTrackCandidateImproved
void addTrackCandidateImproved(const std::string &collectionName, const RecoTrack &recoTrack)
Add a RecoTrack, but use stored genfit track representation to make visualisation objects.
Definition: EVEVisualization.cc:254
Belle2::VXD::SensorInfoBase::getVCellPosition
double getVCellPosition(int vID) const
Return the position of a specific strip/pixel in v direction.
Definition: SensorInfoBase.h:191
Belle2::ROIid
ROIid stores the U and V ids and the sensor id of the Region Of Interest.
Definition: ROIid.h:35
Belle2::VXD::GeoCache::getInstance
static GeoCache & getInstance()
Return a reference to the singleton instance.
Definition: GeoCache.cc:215
Belle2::Track::getTrackFitResultWithClosestMass
const TrackFitResult * getTrackFitResultWithClosestMass(const Const::ChargedStable &requestedType) const
Return the track fit for a fit hypothesis with the closest mass.
Definition: Track.cc:70
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
genfit::AbsTrackRep::getPosMomCov
virtual void getPosMomCov(const MeasuredStateOnPlane &state, TVector3 &pos, TVector3 &mom, TMatrixDSym &cov) const =0
Translates MeasuredStateOnPlane into 3D position, momentum and 6x6 covariance.
Belle2::DisplayData::m_arrows
std::vector< Arrow > m_arrows
List of arrows.
Definition: DisplayData.h:124
Belle2::EVEVisualization::addEKLMHit2d
void addEKLMHit2d(const EKLMHit2d *bklm2dhit)
Add a reconstructed 2d hit in the EKLM.
Definition: EVEVisualization.cc:1532
genfit::GblFitterInfo
Collects information needed and produced by a GblFitter/GBL and is specific to one AbsTrackRep of the...
Definition: GblFitterInfo.h:52
Belle2::SVDRecoHit::isU
bool isU() const
Is the coordinate u or v?
Definition: SVDRecoHit.h:100
Belle2::EVEVisualization::addObject
void addObject(const TObject *dataStoreObject, TEveElement *visualRepresentation)
Generic function to keep track of which objects have which visual representation.
Definition: EVEVisualization.cc:1881
Belle2::EVEVisualization::addCDCHit
void addCDCHit(const CDCHit *hit, bool showTriggerHits=false)
show CDCHits directly.
Definition: EVEVisualization.cc:1608
Belle2::EVEVisualization::addKLMCluster
void addKLMCluster(const KLMCluster *cluster)
Add a reconstructed cluster in the KLM.
Definition: EVEVisualization.cc:1437
Belle2::EVEVisualization::c_klmClusterColor
const static int c_klmClusterColor
Color for KLMCluster objects.
Definition: EVEVisualization.h:95
Belle2::EVEVisualization::addMCParticle
MCTrack * addMCParticle(const MCParticle *particle)
Return MCTrack for given particle, add it if it doesn't exist yet.
Definition: EVEVisualization.cc:1099
Belle2::CDC::CDCGeometryPar::fieldWireR
double fieldWireR(int layerId) const
Returns radius of field wire in each layer.
Definition: CDCGeometryPar.h:1246
Belle2::EVEVisualization::addARICHHit
void addARICHHit(const ARICHHit *hit)
Add recontructed hit in ARICH.
Definition: EVEVisualization.cc:1767
Belle2::EveVisBField
Provide magnetic field values for TEveTrackPropagator.
Definition: EveVisBField.h:12
Belle2::CDC::CDCGeometryPar::nShifts
int nShifts(int layerId) const
Returns number shift.
Definition: CDCGeometryPar.h:1201
Belle2::CDC::CDCGeometryPar::fieldWireFZ
double fieldWireFZ(int layerId) const
Returns forward z position of field wire in each layer.
Definition: CDCGeometryPar.h:1251
genfit::GblFitterInfo::getMeasurement
MeasurementOnPlane getMeasurement() const
Get the measurement on plane from stored measurement data (from last construction/update)
Definition: GblFitterInfo.cc:473
Belle2::EVEVisualization::addVertex
void addVertex(const genfit::GFRaveVertex *vertex)
Add a vertex point and its covariance matrix.
Definition: EVEVisualization.cc:1348
Belle2::EVEVisualization::m_options
std::string m_options
Option string for genfit::Track visualisation.
Definition: EVEVisualization.h:320
Belle2::CDC::RealisticTDCCountTranslator::getDriftLength
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.
Definition: RealisticTDCCountTranslator.cc:106
Belle2::EVEVisualization::m_gftrackpropagator
TEveTrackPropagator * m_gftrackpropagator
Track propagator for genfit::Tracks (different mainly because of drawing options)
Definition: EVEVisualization.h:341
genfit::AbsTrackRep::getPos
virtual TVector3 getPos(const StateOnPlane &state) const =0
Get the cartesian position of a state.
Belle2::DisplayData::m_pointSets
std::map< std::string, std::vector< TVector3 > > m_pointSets
name -> points map
Definition: DisplayData.h:118
Belle2::PXDCluster
The PXD Cluster class This class stores all information about reconstructed PXD clusters The position...
Definition: PXDCluster.h:41
Belle2::ObjectInfo::getIdentifier
TString getIdentifier(const TObject *obj)
Where is this object in the datastore?
Definition: ObjectInfo.cc:98
Belle2::KLMCluster
KLM cluster data.
Definition: KLMCluster.h:38
Belle2::EVEVisualization::m_trackpropagator
TEveTrackPropagator * m_trackpropagator
Track propagator for MCParticles.
Definition: EVEVisualization.h:338
Belle2::VXD::SensorInfoBase::pointToGlobal
TVector3 pointToGlobal(const TVector3 &local, bool reco=false) const
Convert a point from local to global coordinates.
Definition: SensorInfoBase.h:373
Belle2::eval
double eval(const std::vector< double > &spl, const std::vector< double > &vals, double x)
Evaluate spline (zero order or first order) in point x.
Definition: tools.h:118
Belle2::EVEVisualization::makeLines
void makeLines(TEveTrack *eveTrack, const genfit::StateOnPlane *prevState, const genfit::StateOnPlane *state, const genfit::AbsTrackRep *rep, TEvePathMark::EType_e markType, bool drawErrors, int markerPos=1)
Create hit visualisation for the given options, and add them to 'eveTrack'.
Definition: EVEVisualization.cc:881
Belle2::EVEVisualization::m_mcparticleTracks
std::map< const MCParticle *, MCTrack > m_mcparticleTracks
map MCParticles to MCTrack (so hits can be added to the correct track).
Definition: EVEVisualization.h:329
Belle2::BKLMHit2d::getZStripMax
int getZStripMax() const
Get highest z-measuring strip number.
Definition: BKLMHit2d.h:123
Belle2::SVDCluster
The SVD Cluster class This class stores all information about reconstructed SVD clusters.
Definition: SVDCluster.h:38
Belle2::EVEVisualization::setOptions
void setOptions(const std::string &opts)
Set the display options.
Definition: EVEVisualization.cc:175
Belle2::RecoTrack::getRecoHitInformations
std::vector< RecoHitInformation * > getRecoHitInformations(bool getSorted=false) const
Return a list of all RecoHitInformations associated with the RecoTrack.
Definition: RecoTrack.cc:531
Belle2::RecoTrack::getMomentumSeed
TVector3 getMomentumSeed() const
Return the momentum seed stored in the reco track. ATTENTION: This is not the fitted momentum.
Definition: RecoTrack.h:484
Belle2::VXD::GeoCache
Class to faciliate easy access to sensor information of the VXD like coordinate transformations or pi...
Definition: GeoCache.h:41
Belle2::EVEVisualization::c_recoTrackColor
const static int c_recoTrackColor
Color for TrackCandidates.
Definition: EVEVisualization.h:87
Belle2::DisplayData
Add custom information to the display.
Definition: DisplayData.h:65
Belle2::EVEVisualization::addSimHit
void addSimHit(const CDCSimHit *hit, const MCParticle *particle)
Add a CDCSimHit.
Definition: EVEVisualization.cc:1063
Belle2::CDC::CDCGeometryPar::nWiresInLayer
unsigned nWiresInLayer(int layerId) const
Returns wire numbers in a layer.
Definition: CDCGeometryPar.h:1211
Belle2::EVEVisualization::boxCreator
TEveBox * boxCreator(const TVector3 &o, TVector3 u, TVector3 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...
Definition: EVEVisualization.cc:845
Belle2::EVEVisualization::addTrack
void addTrack(const Belle2::Track *belle2Track)
Add this genfit::Track to event data.
Definition: EVEVisualization.cc:376
genfit::SpacepointMeasurement
Class for measurements implementing a space point hit geometry.
Definition: SpacepointMeasurement.h:46
genfit::DetPlane
Detector plane.
Definition: DetPlane.h:59
Belle2::VXD::SensorInfoBase::getUCellPosition
double getUCellPosition(int uID, int vID=-1) const
Return the position of a specific strip/pixel in u direction.
Definition: SensorInfoBase.h:179
Belle2::VXD::GeoCache::getSensorInfo
const SensorInfoBase & getSensorInfo(Belle2::VxdID id) const
Return a referecne to the SensorInfo of a given SensorID.
Definition: GeoCache.cc:68
Belle2::TOP::TOPGeometryPar::getGeometry
const TOPGeometry * getGeometry() const
Returns pointer to geometry object using Basf2 units.
Definition: TOPGeometryPar.cc:167
Belle2::CDC::CDCGeometryPar::fieldWireBZ
double fieldWireBZ(int layerId) const
Returns backward z position of field wire in each layer.
Definition: CDCGeometryPar.h:1256
Belle2::Track
Class that bundles various TrackFitResults.
Definition: Track.h:35
Belle2::EVEVisualization::m_eclData
TEveCaloDataVec * m_eclData
ECL cluster data.
Definition: EVEVisualization.h:347
Belle2::BKLMSimHit
Store one simulation hit as a ROOT object.
Definition: BKLMSimHit.h:35
Belle2::EKLMHitGlobalCoord::getPosition
TVector3 getPosition() const
Get hit global position.
Definition: EKLMHitGlobalCoord.h:92
Belle2::MCParticle
A Class to store the Monte Carlo particle information.
Definition: MCParticle.h:43
Belle2::RecoTrack::getChargeSeed
short int getChargeSeed() const
Return the charge seed stored in the reco track. ATTENTION: This is not the fitted charge.
Definition: RecoTrack.h:497
Belle2::StoreArray< MCParticle >
Belle2::EVEVisualization::m_calo3d
TEveCalo3D * m_calo3d
Object for the energy bar visualisation.
Definition: EVEVisualization.h:274
Belle2::EVEVisualization::clearEvent
void clearEvent()
clear event data.
Definition: EVEVisualization.cc:1305
Belle2::EVEVisualization::m_drawRefTrack
bool m_drawRefTrack
Draw reference track in addTrack.
Definition: EVEVisualization.h:370
Belle2::TrackFitResult::getHelix
Helix getHelix() const
Conversion to framework Helix (without covariance).
Definition: TrackFitResult.h:230
genfit::FitStatus
Class where important numbers and properties of a fit can be stored.
Definition: FitStatus.h:80
Belle2::EVEVisualization::m_hideSecondaries
bool m_hideSecondaries
If true, secondary MCParticles (and hits created by them) will not be shown.
Definition: EVEVisualization.h:326
Belle2::WireID::getICLayer
unsigned short getICLayer() const
Getter for continuous layer numbering.
Definition: WireID.cc:26
Belle2::Exception
Definition: Exception.h:13
Belle2::CDCTriggerSegmentHit
Combination of several CDCHits to a track segment hit for the trigger.
Definition: CDCTriggerSegmentHit.h:16
Belle2::bklm::GeometryPar::findModule
const Module * findModule(int section, int sector, int layer) const
Get the pointer to the definition of a module.
Definition: GeometryPar.cc:716
Belle2::SVDRecoHit::getSensorID
VxdID getSensorID() const
Get the compact ID.
Definition: SVDRecoHit.h:91
Belle2::BKLMHit2d
Store one BKLM strip hit as a ROOT object.
Definition: BKLMHit2d.h:42
Belle2::BKLMHit2d::getLayer
int getLayer() const
Get layer number.
Definition: BKLMHit2d.h:88
Belle2::TrackFitResult::getChargeSign
short getChargeSign() const
Return track charge (1 or -1).
Definition: TrackFitResult.h:160
Belle2::MCParticle::c_PrimaryParticle
@ c_PrimaryParticle
bit 0: Particle is primary particle.
Definition: MCParticle.h:58
genfit::MeasurementOnPlane
Measured coordinates on a plane.
Definition: MeasurementOnPlane.h:46
Belle2::EKLMHit2d
Class for 2d hits handling.
Definition: EKLMHit2d.h:39
Belle2::EVEVisualization::setErrScale
void setErrScale(double errScale=1.)
Set the scaling factor for the visualization of track hit errors.
Definition: EVEVisualization.cc:177
Belle2::TangoPalette
Implements a colour palette, see http://sobac.com/sobac/tangocolors.htm.
Definition: ColorPalette.h:16
Belle2::EVEVisualization::m_bfield
EveVisBField * m_bfield
The global magnetic field.
Definition: EVEVisualization.h:350
Belle2::EVEVisualization::m_errorScale
double m_errorScale
Rescale PXD/SVD errors with this factor to ensure visibility.
Definition: EVEVisualization.h:314
genfit::WireMeasurement
Class for measurements in wire detectors (Straw tubes and drift chambers) which do not measure the co...
Definition: WireMeasurement.h:52
Belle2::PXDSimHit
Class PXDSimHit - Geant4 simulated hit for the PXD.
Definition: PXDSimHit.h:28
Belle2::RecoTrack::getPXDHitList
std::vector< Belle2::RecoTrack::UsedPXDHit * > getPXDHitList() const
Return an unsorted list of pxd hits.
Definition: RecoTrack.h:452
Belle2::BKLMHit2d::getPhiStripMax
int getPhiStripMax() const
Get highest phi-measuring strip number.
Definition: BKLMHit2d.h:102