Belle II Software  release-06-01-15
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  } else if (dynamic_cast<const CDCRecoHit*>(m)
609  || dynamic_cast<const genfit::WireMeasurement*>(m)
610  || dynamic_cast<const genfit::WireMeasurementNew*>(m)) {
611  wire_hit = true;
612  hit_u = fabs(hit_coords(0));
613  hit_v = v * (track_pos - o); // move the covariance tube so that the track goes through it
614  if (dynamic_cast<const genfit::WirePointMeasurement*>(m) != NULL) {
615  wirepoint_hit = true;
616  hit_v = hit_coords(1);
617  }
618  } else {
619  B2ERROR("Hit " << hitCounter << ", Measurement " << iMeasurement << ": Unknown measurement type: skipping hit!");
620  break;
621  }
622 
623  // finished setting variables ---------------------------------------------------------
624 
625  // draw planes if corresponding option is set -----------------------------------------
626  if (drawPlanes || (drawDetectors && planar_hit)) {
627  TVector3 move(0, 0, 0);
628  if (wire_hit) move = v * (v * (track_pos - o)); // move the plane along the wire until the track goes through it
629  TEveBox* box = boxCreator(o + move, u, v, plane_size, plane_size, 0.01);
630  if (drawDetectors && planar_hit) {
631  box->SetMainColor(kCyan);
632  } else {
633  box->SetMainColor(kGray);
634  }
635  box->SetMainTransparency(50);
636  eveTrack->AddElement(box);
637  }
638  // finished drawing planes ------------------------------------------------------------
639 
640  // draw detectors if option is set, only important for wire hits ----------------------
641  if (drawDetectors) {
642 
643  if (wire_hit) {
644  TEveGeoShape* det_shape = new TEveGeoShape("det_shape");
645  det_shape->SetShape(new TGeoTube(std::max(0., (double)(hit_u - 0.0105 / 2.)), hit_u + 0.0105 / 2., plane_size));
646  fixGeoShapeRefCount(det_shape);
647 
648  TVector3 norm = u.Cross(v);
649  TGeoRotation det_rot("det_rot", (u.Theta() * 180) / TMath::Pi(), (u.Phi() * 180) / TMath::Pi(),
650  (norm.Theta() * 180) / TMath::Pi(), (norm.Phi() * 180) / TMath::Pi(),
651  (v.Theta() * 180) / TMath::Pi(), (v.Phi() * 180) / TMath::Pi()); // move the tube to the right place and rotate it correctly
652  TVector3 move = v * (v * (track_pos - o)); // move the tube along the wire until the track goes through it
653  TGeoCombiTrans det_trans(o(0) + move.X(),
654  o(1) + move.Y(),
655  o(2) + move.Z(),
656  &det_rot);
657  det_shape->SetTransMatrix(det_trans);
658  det_shape->SetMainColor(kCyan);
659  det_shape->SetMainTransparency(25);
660  if ((drawHits && (hit_u + 0.0105 / 2 > 0)) || !drawHits) {
661  eveTrack->AddElement(det_shape);
662  }
663  }
664 
665  }
666  // finished drawing detectors ---------------------------------------------------------
667 
668  if (drawHits) {
669 
670  // draw planar hits, with distinction between strip and pixel hits ----------------
671  if (planar_hit) {
672  if (!planar_pixel_hit) {
673  //strip hit
675  const SVDRecoHit* recoHit = dynamic_cast<const SVDRecoHit*>(m);
676  if (!recoHit) {
677  B2WARNING("SVD recohit couldn't be converted... ");
678  continue;
679  }
680 
681  const VXD::SensorInfoBase& sensor = geo.get(recoHit->getSensorID());
682  double du, dv;
683  TVector3 a = o; //defines position of sensor plane
684  double hit_res_u = hit_cov(0, 0);
685  if (recoHit->isU()) {
686  du = std::sqrt(hit_res_u);
687  dv = sensor.getLength();
688  a += hit_u * u;
689  } else {
690  du = sensor.getWidth();
691  dv = std::sqrt(hit_res_u);
692  a += hit_u * v;
693  }
694  double depth = sensor.getThickness();
695  TEveBox* hit_box = boxCreator(a, u, v, du, dv, depth);
696  hit_box->SetName("SVDRecoHit");
697  hit_box->SetMainColor(c_recoHitColor);
698  hit_box->SetMainTransparency(0);
699  eveTrack->AddElement(hit_box);
700  } else {
701  //pixel hit
702  // calculate eigenvalues to draw error-ellipse ----------------------------
703  TMatrixDSymEigen eigen_values(hit_cov);
704  TEveGeoShape* cov_shape = new TEveGeoShape("PXDRecoHit");
705  const TVectorD& ev = eigen_values.GetEigenValues();
706  const TMatrixD& eVec = eigen_values.GetEigenVectors();
707  double pseudo_res_0 = m_errorScale * std::sqrt(ev(0));
708  double pseudo_res_1 = m_errorScale * std::sqrt(ev(1));
709  // finished calcluating, got the values -----------------------------------
710 
711  // calculate the semiaxis of the error ellipse ----------------------------
712  cov_shape->SetShape(new TGeoEltu(pseudo_res_0, pseudo_res_1, 0.0105));
713  fixGeoShapeRefCount(cov_shape);
714  TVector3 pix_pos = o + hit_u * u + hit_v * v;
715  TVector3 u_semiaxis = (pix_pos + eVec(0, 0) * u + eVec(1, 0) * v) - pix_pos;
716  TVector3 v_semiaxis = (pix_pos + eVec(0, 1) * u + eVec(1, 1) * v) - pix_pos;
717  TVector3 norm = u.Cross(v);
718  // finished calculating ---------------------------------------------------
719 
720  // rotate and translate everything correctly ------------------------------
721  TGeoRotation det_rot("det_rot", (u_semiaxis.Theta() * 180) / TMath::Pi(), (u_semiaxis.Phi() * 180) / TMath::Pi(),
722  (v_semiaxis.Theta() * 180) / TMath::Pi(), (v_semiaxis.Phi() * 180) / TMath::Pi(),
723  (norm.Theta() * 180) / TMath::Pi(), (norm.Phi() * 180) / TMath::Pi());
724  TGeoCombiTrans det_trans(pix_pos(0), pix_pos(1), pix_pos(2), &det_rot);
725  cov_shape->SetTransMatrix(det_trans);
726  // finished rotating and translating --------------------------------------
727 
728  cov_shape->SetMainColor(c_recoHitColor);
729  cov_shape->SetMainTransparency(0);
730  eveTrack->AddElement(cov_shape);
731  }
732  }
733  // finished drawing planar hits ---------------------------------------------------
734 
735  // draw spacepoint hits -----------------------------------------------------------
736  if (space_hit) {
737 
738  // get eigenvalues of covariance to know how to draw the ellipsoid ------------
739  TMatrixDSymEigen eigen_values(m->getRawHitCov());
740  TEveGeoShape* cov_shape = new TEveGeoShape("SpacePoint Hit");
741  cov_shape->SetShape(new TGeoSphere(0., 1.));
742  fixGeoShapeRefCount(cov_shape);
743  const TVectorD& ev = eigen_values.GetEigenValues();
744  const TMatrixD& eVec = eigen_values.GetEigenVectors();
745  TVector3 eVec1(eVec(0, 0), eVec(1, 0), eVec(2, 0));
746  TVector3 eVec2(eVec(0, 1), eVec(1, 1), eVec(2, 1));
747  TVector3 eVec3(eVec(0, 2), eVec(1, 2), eVec(2, 2));
748  TVector3 norm = u.Cross(v);
749  // got everything we need -----------------------------------------------------
750 
751 
752  TGeoRotation det_rot("det_rot", (eVec1.Theta() * 180) / TMath::Pi(), (eVec1.Phi() * 180) / TMath::Pi(),
753  (eVec2.Theta() * 180) / TMath::Pi(), (eVec2.Phi() * 180) / TMath::Pi(),
754  (eVec3.Theta() * 180) / TMath::Pi(), (eVec3.Phi() * 180) / TMath::Pi()); // the rotation is already clear
755 
756  // set the scaled eigenvalues -------------------------------------------------
757  double pseudo_res_0 = m_errorScale * std::sqrt(ev(0));
758  double pseudo_res_1 = m_errorScale * std::sqrt(ev(1));
759  double pseudo_res_2 = m_errorScale * std::sqrt(ev(2));
760  // finished scaling -----------------------------------------------------------
761 
762  // rotate and translate -------------------------------------------------------
763  TGeoGenTrans det_trans(o(0), o(1), o(2),
764  //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
765  //1/(pseudo_res_0),1/(pseudo_res_1),1/(pseudo_res_2),
766  pseudo_res_0, pseudo_res_1, pseudo_res_2,
767  &det_rot);
768  cov_shape->SetTransMatrix(det_trans);
769  // finished rotating and translating ------------------------------------------
770 
771  cov_shape->SetMainColor(c_recoHitColor);
772  cov_shape->SetMainTransparency(10);
773  eveTrack->AddElement(cov_shape);
774  }
775  // finished drawing spacepoint hits -----------------------------------------------
776 
777  // draw wire hits -----------------------------------------------------------------
778  if (wire_hit) {
779  const double cdcErrorScale = 1.0;
780  TEveGeoShape* cov_shape = new TEveGeoShape("CDCRecoHit");
781  double pseudo_res_0 = cdcErrorScale * std::sqrt(hit_cov(0, 0));
782  double pseudo_res_1 = plane_size;
783  if (wirepoint_hit) pseudo_res_1 = cdcErrorScale * std::sqrt(hit_cov(1, 1));
784 
785  cov_shape->SetShape(new TGeoTube(std::max(0., (double)(hit_u - pseudo_res_0)), hit_u + pseudo_res_0, pseudo_res_1));
786  fixGeoShapeRefCount(cov_shape);
787  TVector3 norm = u.Cross(v);
788 
789  // rotate and translate -------------------------------------------------------
790  TGeoRotation det_rot("det_rot", (u.Theta() * 180) / TMath::Pi(), (u.Phi() * 180) / TMath::Pi(),
791  (norm.Theta() * 180) / TMath::Pi(), (norm.Phi() * 180) / TMath::Pi(),
792  (v.Theta() * 180) / TMath::Pi(), (v.Phi() * 180) / TMath::Pi());
793  TGeoCombiTrans det_trans(o(0) + hit_v * v.X(),
794  o(1) + hit_v * v.Y(),
795  o(2) + hit_v * v.Z(),
796  &det_rot);
797  cov_shape->SetTransMatrix(det_trans);
798  // finished rotating and translating ------------------------------------------
799 
800  cov_shape->SetMainColor(c_recoHitColor);
801  cov_shape->SetMainTransparency(50);
802  eveTrack->AddElement(cov_shape);
803  }
804  // finished drawing wire hits -----------------------------------------------------
805  }
806 
807  }
808  }
809 
810  auto& firstref = eveTrack->RefPathMarks().front();
811  auto& lastref = eveTrack->RefPathMarks().back();
812  double f = firstref.fV.Distance(recTrack.fV);
813  double b = lastref.fV.Distance(recTrack.fV);
814  if (f > 100 and f > b) {
815  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)");
816  //last ref is better than first...
817  lastref.fType = TEvePathMarkD::kReference;
818  firstref.fType = TEvePathMarkD::kDecay;
819  std::reverse(eveTrack->RefPathMarks().begin(), eveTrack->RefPathMarks().end());
820  }
821  }
822  eveTrack->SetTitle(TString::Format("%s\n"
823  "pruned: %s\n"
824  "pT=%.3f, pZ=%.3f\n"
825  "pVal: %e",
826  label.Data(),
827  isPruned ? " yes" : "no",
828  poca_momentum.Pt(), poca_momentum.Pz(),
829  fitResult->getPValue()
830  ));
831  eveTrack->SetLineColor(c_trackColor);
832  eveTrack->SetLineStyle(1);
833  eveTrack->SetLineWidth(3.0);
834 
835 
836  addToGroup("Fitted Tracks", eveTrack);
837  if (track)
838  addObject(track, eveTrack);
839  addObject(belle2Track, eveTrack);
840 }
841 
842 TEveBox* EVEVisualization::boxCreator(const TVector3& o, TVector3 u, TVector3 v, float ud, float vd, float depth)
843 {
844  //force minimum width of polygon to deal with Eve limits
845  float min = 0.04;
846  if (vd < min)
847  vd = min;
848  if (ud < min)
849  ud = min;
850  if (depth < min)
851  depth = min;
852 
853  TEveBox* box = new TEveBox;
854  box->SetPickable(true);
855 
856  TVector3 norm = u.Cross(v);
857  u *= (0.5 * ud);
858  v *= (0.5 * vd);
859  norm *= (0.5 * depth);
860 
861 
862  for (int k = 0; k < 8; ++k) {
863  // Coordinates for all eight corners of the box
864  // as two parallel rectangles, with vertices specified in clockwise direction
865  int signU = ((k + 1) & 2) ? -1 : 1;
866  int signV = (k & 4) ? -1 : 1;
867  int signN = (k & 2) ? -1 : 1;
868  float vertex[3];
869  for (int i = 0; i < 3; ++i) {
870  vertex[i] = o(i) + signU * u(i) + signV * v(i) + signN * norm(i);
871  }
872  box->SetVertex(k, vertex);
873  }
874 
875  return box;
876 }
877 
878 void EVEVisualization::makeLines(TEveTrack* eveTrack, const genfit::StateOnPlane* prevState, const genfit::StateOnPlane* state,
879  const genfit::AbsTrackRep* rep,
880  TEvePathMark::EType_e markType, bool drawErrors, int markerPos)
881 {
882  using namespace genfit;
883 
884  TVector3 pos, dir, oldPos, oldDir;
885  rep->getPosDir(*state, pos, dir);
886  rep->getPosDir(*prevState, oldPos, oldDir);
887 
888  double distA = (pos - oldPos).Mag();
889  double distB = distA;
890  if ((pos - oldPos)*oldDir < 0)
891  distA *= -1.;
892  if ((pos - oldPos)*dir < 0)
893  distB *= -1.;
894 
895  TEvePathMark mark(
896  markType,
897  TEveVector(pos(0), pos(1), pos(2)),
898  TEveVector(dir(0), dir(1), dir(2))
899  );
900  eveTrack->AddPathMark(mark);
901 
902 
903  if (drawErrors) {
904  const MeasuredStateOnPlane* measuredState;
905  if (markerPos == 0)
906  measuredState = dynamic_cast<const MeasuredStateOnPlane*>(prevState);
907  else
908  measuredState = dynamic_cast<const MeasuredStateOnPlane*>(state);
909 
910  if (measuredState != NULL) {
911 
912  // step for evaluate at a distance from the original plane
913  TVector3 eval;
914  if (markerPos == 0)
915  eval = 0.2 * distA * oldDir;
916  else
917  eval = -0.2 * distB * dir;
918 
919 
920  // get cov at first plane
921  TMatrixDSym cov;
922  TVector3 position, direction;
923  rep->getPosMomCov(*measuredState, position, direction, cov);
924 
925  // get eigenvalues & -vectors
926  TMatrixDSymEigen eigen_values(cov.GetSub(0, 2, 0, 2));
927  const TVectorD& ev = eigen_values.GetEigenValues();
928  const TMatrixD& eVec = eigen_values.GetEigenVectors();
929  TVector3 eVec1, eVec2;
930  // limit
931  static const double maxErr = 1000.;
932  double ev0 = std::min(ev(0), maxErr);
933  double ev1 = std::min(ev(1), maxErr);
934  double ev2 = std::min(ev(2), maxErr);
935 
936  // get two largest eigenvalues/-vectors
937  if (ev0 < ev1 && ev0 < ev2) {
938  eVec1.SetXYZ(eVec(0, 1), eVec(1, 1), eVec(2, 1));
939  eVec1 *= sqrt(ev1);
940  eVec2.SetXYZ(eVec(0, 2), eVec(1, 2), eVec(2, 2));
941  eVec2 *= sqrt(ev2);
942  } else if (ev1 < ev0 && ev1 < ev2) {
943  eVec1.SetXYZ(eVec(0, 0), eVec(1, 0), eVec(2, 0));
944  eVec1 *= sqrt(ev0);
945  eVec2.SetXYZ(eVec(0, 2), eVec(1, 2), eVec(2, 2));
946  eVec2 *= sqrt(ev2);
947  } else {
948  eVec1.SetXYZ(eVec(0, 0), eVec(1, 0), eVec(2, 0));
949  eVec1 *= sqrt(ev0);
950  eVec2.SetXYZ(eVec(0, 1), eVec(1, 1), eVec(2, 1));
951  eVec2 *= sqrt(ev1);
952  }
953 
954  if (eVec1.Cross(eVec2)*eval < 0)
955  eVec2 *= -1;
956  //assert(eVec1.Cross(eVec2)*eval > 0);
957 
958  TVector3 oldEVec1(eVec1);
959 
960  const int nEdges = 24;
961  std::vector<TVector3> vertices;
962 
963  vertices.push_back(position);
964 
965  // vertices at plane
966  for (int i = 0; i < nEdges; ++i) {
967  const double angle = 2 * TMath::Pi() / nEdges * i;
968  vertices.push_back(position + cos(angle)*eVec1 + sin(angle)*eVec2);
969  }
970 
971 
972 
973  SharedPlanePtr newPlane(new DetPlane(*(measuredState->getPlane())));
974  newPlane->setO(position + eval);
975 
976  MeasuredStateOnPlane stateCopy(*measuredState);
977  try {
978  rep->extrapolateToPlane(stateCopy, newPlane);
979  } catch (Exception& e) {
980  B2ERROR(e.what());
981  return;
982  }
983 
984  // get cov at 2nd plane
985  rep->getPosMomCov(stateCopy, position, direction, cov);
986 
987  // get eigenvalues & -vectors
988  {
989  TMatrixDSymEigen eigen_values2(cov.GetSub(0, 2, 0, 2));
990  const TVectorD& eVal = eigen_values2.GetEigenValues();
991  const TMatrixD& eVect = eigen_values2.GetEigenVectors();
992  // limit
993  ev0 = std::min(eVal(0), maxErr);
994  ev1 = std::min(eVal(1), maxErr);
995  ev2 = std::min(eVal(2), maxErr);
996 
997  // get two largest eigenvalues/-vectors
998  if (ev0 < ev1 && ev0 < ev2) {
999  eVec1.SetXYZ(eVect(0, 1), eVect(1, 1), eVect(2, 1));
1000  eVec1 *= sqrt(ev1);
1001  eVec2.SetXYZ(eVect(0, 2), eVect(1, 2), eVect(2, 2));
1002  eVec2 *= sqrt(ev2);
1003  } else if (ev1 < ev0 && ev1 < ev2) {
1004  eVec1.SetXYZ(eVect(0, 0), eVect(1, 0), eVect(2, 0));
1005  eVec1 *= sqrt(ev0);
1006  eVec2.SetXYZ(eVect(0, 2), eVect(1, 2), eVect(2, 2));
1007  eVec2 *= sqrt(ev2);
1008  } else {
1009  eVec1.SetXYZ(eVect(0, 0), eVect(1, 0), eVect(2, 0));
1010  eVec1 *= sqrt(ev0);
1011  eVec2.SetXYZ(eVect(0, 1), eVect(1, 1), eVect(2, 1));
1012  } eVec2 *= sqrt(ev1);
1013  }
1014 
1015  if (eVec1.Cross(eVec2)*eval < 0)
1016  eVec2 *= -1;
1017  //assert(eVec1.Cross(eVec2)*eval > 0);
1018 
1019  if (oldEVec1 * eVec1 < 0) {
1020  eVec1 *= -1;
1021  eVec2 *= -1;
1022  }
1023 
1024  // vertices at 2nd plane
1025  double angle0 = eVec1.Angle(oldEVec1);
1026  if (eVec1 * (eval.Cross(oldEVec1)) < 0)
1027  angle0 *= -1;
1028  for (int i = 0; i < nEdges; ++i) {
1029  const double angle = 2 * TMath::Pi() / nEdges * i - angle0;
1030  vertices.push_back(position + cos(angle)*eVec1 + sin(angle)*eVec2);
1031  }
1032 
1033  vertices.push_back(position);
1034 
1035 
1036  TEveTriangleSet* error_shape = new TEveTriangleSet(vertices.size(), nEdges * 2);
1037  for (unsigned int k = 0; k < vertices.size(); ++k) {
1038  error_shape->SetVertex(k, vertices[k].X(), vertices[k].Y(), vertices[k].Z());
1039  }
1040 
1041  assert(vertices.size() == 2 * nEdges + 2);
1042 
1043  int iTri(0);
1044  for (int i = 0; i < nEdges; ++i) {
1045  //error_shape->SetTriangle(iTri++, 0, i+1, (i+1)%nEdges+1);
1046  error_shape->SetTriangle(iTri++, i + 1, i + 1 + nEdges, (i + 1) % nEdges + 1);
1047  error_shape->SetTriangle(iTri++, (i + 1) % nEdges + 1, i + 1 + nEdges, (i + 1) % nEdges + 1 + nEdges);
1048  //error_shape->SetTriangle(iTri++, 2*nEdges+1, i+1+nEdges, (i+1)%nEdges+1+nEdges);
1049  }
1050 
1051  //assert(iTri == nEdges*4);
1052 
1053  error_shape->SetMainColor(c_trackColor);
1054  error_shape->SetMainTransparency(25);
1055  eveTrack->AddElement(error_shape);
1056  }
1057  }
1058 }
1059 
1060 void EVEVisualization::addSimHit(const CDCSimHit* hit, const MCParticle* particle)
1061 {
1062  addSimHit(hit->getPosWire(), particle);
1063 }
1064 void EVEVisualization::addSimHit(const PXDSimHit* hit, const MCParticle* particle)
1065 {
1066  static VXD::GeoCache& geo = VXD::GeoCache::getInstance();
1067  const TVector3& global_pos = geo.get(hit->getSensorID()).pointToGlobal(hit->getPosIn());
1068  addSimHit(global_pos, particle);
1069 }
1070 void EVEVisualization::addSimHit(const SVDSimHit* hit, const MCParticle* particle)
1071 {
1072  static VXD::GeoCache& geo = VXD::GeoCache::getInstance();
1073  const TVector3& global_pos = geo.get(hit->getSensorID()).pointToGlobal(hit->getPosIn());
1074  addSimHit(global_pos, particle);
1075 }
1076 void EVEVisualization::addSimHit(const BKLMSimHit* hit, const MCParticle* particle)
1077 {
1078  TVector3 global_pos;
1079  BKLMSimHitPosition* p = hit->getRelatedFrom<BKLMSimHitPosition>();
1080  if (p) global_pos = p->getPosition();
1081  addSimHit(global_pos, particle);
1082 }
1083 void EVEVisualization::addSimHit(const EKLMSimHit* hit, const MCParticle* particle)
1084 {
1085  const TVector3& global_pos = hit->getPosition();
1086  addSimHit(global_pos, particle);
1087 }
1088 void EVEVisualization::addSimHit(const TVector3& v, const MCParticle* particle)
1089 {
1090  MCTrack* track = addMCParticle(particle);
1091  if (!track)
1092  return; //hide hits from this particle
1093  track->simhits->SetNextPoint(v.x(), v.y(), v.z());
1094 }
1095 
1097 {
1098  if (!particle) {
1099  if (!m_mcparticleTracks[nullptr].simhits) {
1100  const TString pointsTitle("Unassigned SimHits");
1101  m_mcparticleTracks[nullptr].simhits = new TEvePointSet(pointsTitle);
1102  m_mcparticleTracks[nullptr].simhits->SetTitle(pointsTitle);
1103  m_mcparticleTracks[nullptr].simhits->SetMarkerStyle(6);
1104  m_mcparticleTracks[nullptr].simhits->SetMainColor(c_unassignedHitColor);
1105  //m_mcparticleTracks[nullptr].simhits->SetMainTransparency(50);
1106  m_mcparticleTracks[nullptr].track = NULL;
1107  }
1108  return &m_mcparticleTracks[nullptr];
1109  }
1110 
1111  if (m_hideSecondaries and !particle->hasStatus(MCParticle::c_PrimaryParticle)) {
1112  return NULL;
1113  }
1114  if (m_assignToPrimaries) {
1115  while (!particle->hasStatus(MCParticle::c_PrimaryParticle) and particle->getMother())
1116  particle = particle->getMother();
1117  }
1118 
1119  if (!m_mcparticleTracks[particle].track) {
1120  const TVector3& p = particle->getMomentum();
1121  const TVector3& vertex = particle->getProductionVertex();
1122  const int pdg = particle->getPDG();
1123  TParticle tparticle(pdg, particle->getStatus(),
1124  (particle->getMother() ? particle->getMother()->getIndex() : 0), 0, particle->getFirstDaughter(), particle->getLastDaughter(),
1125  p.x(), p.y(), p.z(), particle->getEnergy(),
1126  vertex.x(), vertex.y(), vertex.z(), particle->getProductionTime());
1127  TEveMCTrack mctrack;
1128  mctrack = tparticle;
1129  mctrack.fTDecay = particle->getDecayTime();
1130  mctrack.fVDecay.Set(particle->getDecayVertex());
1131  mctrack.fDecayed = !boost::math::isinf(mctrack.fTDecay);
1132  mctrack.fIndex = particle->getIndex();
1133  m_mcparticleTracks[particle].track = new TEveTrack(&mctrack, m_trackpropagator);
1134 
1135  //Check if there is a trajectory stored for this particle
1136  const auto mcTrajectories = particle->getRelationsTo<MCParticleTrajectory>();
1137  bool hasTrajectory(false);
1138  for (auto rel : mcTrajectories.relations()) {
1139  //Trajectories with negative weight are from secondary daughters which
1140  //were ignored so we don't use them.
1141  if (rel.weight <= 0) continue;
1142  //Found one, let's add tose point as reference points to the TEveTrack.
1143  //This will force the track propagation to visit all points in order but
1144  //provide smooth helix interpolation between the points
1145  const MCParticleTrajectory& trajectory = dynamic_cast<const MCParticleTrajectory&>(*rel.object);
1146  for (const MCTrajectoryPoint& pt : trajectory) {
1147  m_mcparticleTracks[particle].track->AddPathMark(
1148  TEvePathMark(
1149  //Add the last trajectory point as decay point to prevent TEve to
1150  //propagate beyond the end of the track. So lets compare the adress
1151  //to the address of last point and choose the pathmark accordingly
1152  (&pt == &trajectory.back()) ? TEvePathMark::kDecay : TEvePathMark::kReference,
1153  TEveVector(pt.x, pt.y, pt.z),
1154  TEveVector(pt.px, pt.py, pt.pz)
1155  ));
1156  }
1157  //"There can only be One" -> found a trajectory, stop the loop
1158  hasTrajectory = true;
1159  break;
1160  }
1161 
1162  //If we have the full trajectory there is no need to add additional path marks
1163  if (!hasTrajectory) {
1164  //add daughter vertices - improves track rendering as lost momentum is taken into account
1165  for (int iDaughter = particle->getFirstDaughter(); iDaughter <= particle->getLastDaughter(); iDaughter++) {
1166  if (iDaughter == 0)
1167  continue; //no actual daughter
1168 
1169  const MCParticle* daughter = StoreArray<MCParticle>()[iDaughter - 1];
1170 
1171  TEvePathMarkD refMark(TEvePathMarkD::kDaughter);
1172  refMark.fV.Set(daughter->getProductionVertex());
1173  refMark.fP.Set(daughter->getMomentum());
1174  refMark.fTime = daughter->getProductionTime();
1175  m_mcparticleTracks[particle].track->AddPathMark(refMark);
1176  }
1177 
1178  //neutrals and very short-lived particles should stop somewhere
1179  //(can result in wrong shapes for particles stopped in the detector, so not used there)
1180  if ((TMath::Nint(particle->getCharge()) == 0 or !particle->hasStatus(MCParticle::c_StoppedInDetector))
1181  and mctrack.fDecayed) {
1182  TEvePathMarkD decayMark(TEvePathMarkD::kDecay);
1183  decayMark.fV.Set(particle->getDecayVertex());
1184  m_mcparticleTracks[particle].track->AddPathMark(decayMark);
1185  }
1186  }
1187  TString particle_name(mctrack.GetName());
1188 
1189  //set track title (for popup)
1190  const MCParticle* mom = particle->getMother();
1191  if (mom) {
1192  m_mcparticleTracks[particle].parentParticle = mom;
1193  addMCParticle(mom);
1194  }
1195 
1196  TString title = ObjectInfo::getTitle(particle);
1197  if (!hasTrajectory) {
1198  //Hijack the mother label to show that the track position is only
1199  //extrapolated, not known from simulation
1200  title += "\n(track estimated from initial momentum)";
1201  //Also, show those tracks with dashed lines
1202  m_mcparticleTracks[particle].track->SetLineStyle(2);
1203  }
1204 
1205  m_mcparticleTracks[particle].track->SetTitle(title);
1206 
1207  //add some color (avoid black & white)
1208  switch (abs(pdg)) {
1209  case 11:
1210  m_mcparticleTracks[particle].track->SetLineColor(kAzure);
1211  break;
1212  case 13:
1213  m_mcparticleTracks[particle].track->SetLineColor(kCyan + 1);
1214  break;
1215  case 22:
1216  m_mcparticleTracks[particle].track->SetLineColor(kSpring);
1217  break;
1218  case 211:
1219  m_mcparticleTracks[particle].track->SetLineColor(kGray + 1);
1220  break;
1221  case 321:
1222  m_mcparticleTracks[particle].track->SetLineColor(kRed + 1);
1223  break;
1224  case 2212:
1225  m_mcparticleTracks[particle].track->SetLineColor(kOrange - 2);
1226  break;
1227  default:
1228  m_mcparticleTracks[particle].track->SetLineColor(kMagenta);
1229  }
1230 
1231  //create point set for hits
1232  const TString pointsTitle = "SimHits for " + ObjectInfo::getIdentifier(particle) + " - " + particle_name;
1233  m_mcparticleTracks[particle].simhits = new TEvePointSet(pointsTitle);
1234  m_mcparticleTracks[particle].simhits->SetTitle(pointsTitle);
1235  m_mcparticleTracks[particle].simhits->SetMarkerStyle(6);
1236  m_mcparticleTracks[particle].simhits->SetMainColor(m_mcparticleTracks[particle].track->GetLineColor());
1237  //m_mcparticleTracks[particle].simhits->SetMainTransparency(50);
1238  addObject(particle, m_mcparticleTracks[particle].track);
1239  }
1240  return &m_mcparticleTracks[particle];
1241 }
1242 
1244 {
1245  for (auto& mcTrackPair : m_mcparticleTracks) {
1246  MCTrack& mcTrack = mcTrackPair.second;
1247  if (mcTrack.track) {
1248  if (mcTrack.simhits->Size() > 0) {
1249  mcTrack.track->AddElement(mcTrack.simhits);
1250  } else {
1251  //if we don't add it, remove empty collection
1252  destroyEveElement(mcTrack.simhits);
1253  }
1254 
1255  TEveElement* parent = m_tracklist;
1256  if (mcTrack.parentParticle) {
1257  const auto& parentIt = m_mcparticleTracks.find(mcTrack.parentParticle);
1258  if (parentIt != m_mcparticleTracks.end()) {
1259  parent = parentIt->second.track;
1260  }
1261  }
1262  parent->AddElement(mcTrack.track);
1263  } else { //add simhits directly
1264  gEve->AddElement(mcTrack.simhits);
1265  }
1266  }
1267  gEve->AddElement(m_tracklist);
1268  m_tracklist->MakeTracks();
1269  m_tracklist->SelectByP(c_minPCut, FLT_MAX); //don't show too many particles by default...
1270 
1271  for (size_t i = 0; i < m_options.length(); i++) {
1272  if (m_options.at(i) == 'M') {
1273  m_gftrackpropagator->SetRnrDaughters(true);
1274  m_gftrackpropagator->SetRnrReferences(true);
1275  //m_gftrackpropagator->SetRnrFV(true); //TODO: this crashes?
1276  TMarker m;
1277  m.SetMarkerColor(c_trackMarkerColor);
1278  m.SetMarkerStyle(1); //a single pixel
1279  m.SetMarkerSize(1); //ignored.
1280  m_gftrackpropagator->RefPMAtt() = m;
1281  m_gftrackpropagator->RefFVAtt() = m;
1282  }
1283  }
1284 
1285  m_consttrackpropagator->SetMagField(0, 0, -1.5);
1286 
1287  m_eclData->DataChanged(); //update limits (Empty() won't work otherwise)
1288  if (!m_eclData->Empty()) {
1289  m_eclData->SetAxisFromBins(0.0,
1290  0.0); //epsilon_x/y = 0 so we don't merge neighboring bins. This avoids some rendering issues with projections of small clusters.
1291  m_calo3d->SetData(m_eclData);
1292  }
1293  gEve->AddElement(m_calo3d);
1294 
1295  if (m_unassignedRecoHits) {
1297  gEve->AddElement(m_unassignedRecoHits);
1298  }
1299 
1300 }
1301 
1303 {
1304  if (!gEve)
1305  return;
1306 
1308  for (auto& groupPair : m_groups) {
1309  //store visibility, invalidate pointers
1310  if (groupPair.second.group)
1311  groupPair.second.visible = groupPair.second.group->GetRnrState();
1312  groupPair.second.group = nullptr;
1313  }
1314 
1315  m_mcparticleTracks.clear();
1316  m_shownRecohits.clear();
1317  m_tracklist->DestroyElements();
1318 
1319  //remove ECL data from event
1320  m_calo3d->SetData(NULL);
1321  m_calo3d->DestroyElements();
1322 
1323  //lower energy threshold for ECL
1324  float ecl_threshold = 0.01;
1325  if (m_eclData)
1326  ecl_threshold = m_eclData->GetSliceThreshold(0);
1327 
1328  destroyEveElement(m_eclData);
1329  m_eclData = new TEveCaloDataVec(1); //#slices
1330  m_eclData->IncDenyDestroy();
1331  m_eclData->RefSliceInfo(0).Setup("ECL", ecl_threshold, kRed);
1332 
1335  destroyEveElement(m_unassignedRecoHits);
1336 
1337  gEve->GetSelection()->RemoveElements();
1338  gEve->GetHighlight()->RemoveElements();
1339  //other things are cleaned up by TEve...
1340 }
1341 
1342 
1343 
1344 
1346 {
1347  TVector3 v = vertex->getPos();
1348  TEvePointSet* vertexPoint = new TEvePointSet(ObjectInfo::getInfo(vertex));
1349  //sadly, setting a title for a TEveGeoShape doesn't result in a popup...
1350  vertexPoint->SetTitle(ObjectInfo::getTitle(vertex));
1351  vertexPoint->SetMainColor(c_recoHitColor);
1352  vertexPoint->SetNextPoint(v.x(), v.y(), v.z());
1353 
1354  TMatrixDSymEigen eigen_values(vertex->getCov());
1355  TEveGeoShape* det_shape = new TEveGeoShape(ObjectInfo::getInfo(vertex) + " Error");
1356  det_shape->SetShape(new TGeoSphere(0., 1.)); //Initially created as a sphere, then "scaled" into an ellipsoid.
1357  fixGeoShapeRefCount(det_shape);
1358  const TVectorD& ev = eigen_values.GetEigenValues(); //Assigns the eigenvalues into the "ev" matrix.
1359  const TMatrixD& eVec = eigen_values.GetEigenVectors(); //Assigns the eigenvalues into the "eVec" matrix.
1360  TVector3 eVec1(eVec(0, 0), eVec(1, 0), eVec(2,
1361  0)); //Define the 3 eigenvectors of the covariance matrix as objects of the TVector3 class using constructor.
1362  TVector3 eVec2(eVec(0, 1), eVec(1, 1), eVec(2,
1363  1)); //eVec(i,j) uses the method/overloaded operator ( . ) of the TMatrixT class to return the matrix entry.
1364  TVector3 eVec3(eVec(0, 2), eVec(1, 2), eVec(2, 2));
1365  // got everything we need ----------------------------------------------------- //Eigenvalues(semi axis) of the covariance matrix accquired!
1366 
1367 
1368  TGeoRotation det_rot("det_rot", (eVec1.Theta() * 180) / TMath::Pi(), (eVec1.Phi() * 180) / TMath::Pi(),
1369  (eVec2.Theta() * 180) / TMath::Pi(), (eVec2.Phi() * 180) / TMath::Pi(),
1370  (eVec3.Theta() * 180) / TMath::Pi(), (eVec3.Phi() * 180) / TMath::Pi()); // the rotation is already clear
1371 
1372  // set the scaled eigenvalues -------------------------------------------------
1373  //"Scaled" eigenvalues pseudo_res (lengths of the semi axis) are the sqrt of the eigenvalues.
1374  double pseudo_res_0 = std::sqrt(ev(0));
1375  double pseudo_res_1 = std::sqrt(ev(1));
1376  double pseudo_res_2 = std::sqrt(ev(2));
1377 
1378  //B2INFO("The pseudo_res_0/1/2 are " << pseudo_res_0 << "," << pseudo_res_1 << "," << pseudo_res_2); //shows the scaled eigenvalues
1379 
1380 
1381 
1382  // rotate and translate -------------------------------------------------------
1383  TGeoGenTrans det_trans(v(0), v(1), v(2), pseudo_res_0, pseudo_res_1, pseudo_res_2,
1384  &det_rot); //Puts the ellipsoid at the position of the vertex, v(0)=v.x(), operator () overloaded.
1385  det_shape->SetTransMatrix(det_trans);
1386  // finished rotating and translating ------------------------------------------
1387 
1388  det_shape->SetMainColor(kOrange); //The color of the error ellipsoid.
1389  det_shape->SetMainTransparency(0);
1390 
1391  vertexPoint->AddElement(det_shape);
1392  addToGroup("Vertices", vertexPoint);
1393  addObject(vertex, vertexPoint);
1394 }
1395 
1396 
1398 {
1399 
1400  // only display c_nPhotons hypothesis clusters
1401  if (cluster->hasHypothesis(ECLCluster::EHypothesisBit::c_nPhotons)) {
1402 
1403  const float phi = cluster->getPhi();
1404  float dPhi = cluster->getUncertaintyPhi();
1405  float dTheta = cluster->getUncertaintyTheta();
1406  if (dPhi >= M_PI / 4 or dTheta >= M_PI / 4 or cluster->getUncertaintyEnergy() == 1.0) {
1407  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:");
1408  cluster->getCovarianceMatrix3x3().Print();
1409  dPhi = dTheta = 0.05;
1410  }
1411 
1412  if (!std::isfinite(dPhi) or !std::isfinite(dTheta)) {
1413  B2ERROR("ECLCluster phi or theta error is NaN or infinite, skipping cluster!");
1414  return;
1415  }
1416 
1417  //convert theta +- dTheta into eta +- dEta
1418  TVector3 thetaLow;
1419  thetaLow.SetPtThetaPhi(1.0, cluster->getTheta() - dTheta, phi);
1420  TVector3 thetaHigh;
1421  thetaHigh.SetPtThetaPhi(1.0, cluster->getTheta() + dTheta, phi);
1422  float etaLow = thetaLow.Eta();
1423  float etaHigh = thetaHigh.Eta();
1424  if (etaLow > etaHigh) {
1425  std::swap(etaLow, etaHigh);
1426  }
1427 
1428  int id = m_eclData->AddTower(etaLow, etaHigh, phi - dPhi, phi + dPhi);
1429  m_eclData->FillSlice(0, cluster->getEnergy(ECLCluster::EHypothesisBit::c_nPhotons));
1431  }
1432 }
1433 
1435 {
1436  const double layerThicknessCm = 3.16; //TDR, Fig 10.2
1437  const double layerDistanceCm = 9.1 - layerThicknessCm;
1438 
1439  TVector3 startPos = cluster->getClusterPosition(); //position of first RPC plane
1440  TVector3 dir; //direction of cluster stack, Mag() == distance between planes
1441  TVector3 a, b; //defines RPC plane
1442  bool isBarrel = (startPos.Z() > -175.0 and startPos.Z() < 270.0);
1443  if (isBarrel) {
1444  //barrel
1445  b = TVector3(0, 0, 1);
1446  a = startPos.Cross(b).Unit();
1447  double c = M_PI / 4.0;
1448  double offset = c / 2.0 + M_PI;
1449  a.SetPhi(int((a.Phi() + offset) / (c))*c - M_PI);
1450  TVector3 perp = b.Cross(a);
1451 
1452  const double barrelRadiusCm = 204.0;
1453  startPos.SetMag(barrelRadiusCm / perp.Dot(startPos.Unit()));
1454 
1455  dir = startPos.Unit();
1456  dir.SetMag((layerDistanceCm + layerThicknessCm) / perp.Dot(dir));
1457  } else {
1458  //endcap
1459  b = TVector3(startPos.x(), startPos.y(), 0).Unit();
1460  a = startPos.Cross(b).Unit();
1461  double endcapStartZ = 284;
1462  if (startPos.z() < 0)
1463  endcapStartZ = -189.5;
1464 
1465  double scaleFac = endcapStartZ / startPos.z();
1466  startPos.SetMag(startPos.Mag() * scaleFac);
1467 
1468  dir = startPos.Unit();
1469  dir.SetMag((layerDistanceCm + layerThicknessCm) / fabs(dir.z()));
1470  }
1471 
1472  for (int i = 0; i < cluster->getLayers(); i++) {
1473  TVector3 layerPos = startPos;
1474  layerPos += (cluster->getInnermostLayer() + i) * dir;
1475  auto* layer = boxCreator(layerPos, a, b, 20.0, 20.0, layerThicknessCm / 2);
1476  layer->SetMainColor(c_klmClusterColor);
1477  layer->SetMainTransparency(70);
1478  layer->SetName(ObjectInfo::getIdentifier(cluster));
1479  layer->SetTitle(ObjectInfo::getTitle(cluster));
1480 
1481  addToGroup(std::string("KLMClusters/") + ObjectInfo::getIdentifier(cluster).Data(), layer);
1482  addObject(cluster, layer);
1483  }
1484 }
1485 
1487 {
1488  //TVector3 globalPosition= bklm2dhit->getGlobalPosition();
1490  const bklm::Module* module = m_GeoPar->findModule(bklm2dhit->getSection(), bklm2dhit->getSector(), bklm2dhit->getLayer());
1491 
1492  CLHEP::Hep3Vector global;
1493  //+++ global coordinates of the hit
1494  global[0] = bklm2dhit->getGlobalPosition()[0];
1495  global[1] = bklm2dhit->getGlobalPosition()[1];
1496  global[2] = bklm2dhit->getGlobalPosition()[2];
1497 
1498  //+++ local coordinates of the hit
1499  CLHEP::Hep3Vector local = module->globalToLocal(global);
1500  //double localU = local[1]; //phi
1501  //double localV = local[2]; //z
1502  int Nphistrip = bklm2dhit->getPhiStripMax() - bklm2dhit->getPhiStripMin() + 1;
1503  int Nztrip = bklm2dhit->getZStripMax() - bklm2dhit->getZStripMin() + 1;
1504  double du = module->getPhiStripWidth() * Nphistrip;
1505  double dv = module->getZStripWidth() * Nztrip;
1506 
1507  //Let's do some simple thing
1508  CLHEP::Hep3Vector localU(local[0], local[1] + 1.0, local[2]);
1509  CLHEP::Hep3Vector localV(local[0], local[1], local[2] + 1.0);
1510 
1511  CLHEP::Hep3Vector globalU = module->localToGlobal(localU);
1512  CLHEP::Hep3Vector globalV = module->localToGlobal(localV);
1513 
1514  TVector3 o(global[0], global[1], global[2]);
1515  TVector3 u(globalU[0], globalU[1], globalU[2]);
1516  TVector3 v(globalV[0], globalV[1], globalV[2]);
1517 
1518  //Lest's just assign the depth is 1.0 cm (thickness of a layer), better to update
1519  TEveBox* bklmbox = boxCreator(o, u - o, v - o, du, dv, 1.0);
1520 
1521  bklmbox->SetMainColor(kGreen);
1522  //bklmbox->SetName((std::to_string(hitModule)).c_str());
1523  bklmbox->SetName("BKLMHit2d");
1524 
1525  addToGroup("BKLM2dHits", bklmbox);
1526  addObject(bklm2dhit, bklmbox);
1527 }
1528 
1530 {
1531  const double du = 2.0;
1532  const double dv = 2.0;
1533  TVector3 o = eklm2dhit->getPosition();
1534  TVector3 u(1.0, 0.0, 0.0);
1535  TVector3 v(0.0, 1.0, 0.0);
1536  TEveBox* eklmbox = boxCreator(o, u, v, du, dv, 4.0);
1537  eklmbox->SetMainColor(kGreen);
1538  eklmbox->SetName("EKLMHit2d");
1539  addToGroup("EKLM2dHits", eklmbox);
1540  addObject(eklm2dhit, eklmbox);
1541 }
1542 
1544 {
1545  const VXD::GeoCache& aGeometry = VXD::GeoCache::getInstance();
1546 
1547  VxdID sensorID = roi->getSensorID();
1548  const VXD::SensorInfoBase& aSensorInfo = aGeometry.getSensorInfo(sensorID);
1549 
1550  double minU = aSensorInfo.getUCellPosition(roi->getMinUid(), roi->getMinVid());
1551  double minV = aSensorInfo.getVCellPosition(roi->getMinVid());
1552  double maxU = aSensorInfo.getUCellPosition(roi->getMaxUid(), roi->getMaxVid());
1553  double maxV = aSensorInfo.getVCellPosition(roi->getMaxVid());
1554 
1555 
1556  TVector3 localA(minU, minV, 0);
1557  TVector3 localB(minU, maxV, 0);
1558  TVector3 localC(maxU, minV, 0);
1559 
1560  TVector3 globalA = aSensorInfo.pointToGlobal(localA);
1561  TVector3 globalB = aSensorInfo.pointToGlobal(localB);
1562  TVector3 globalC = aSensorInfo.pointToGlobal(localC);
1563 
1564  TEveBox* ROIbox = boxCreator((globalB + globalC) * 0.5 , globalB - globalA, globalC - globalA, 1, 1, 0.01);
1565 
1566  ROIbox->SetName(ObjectInfo::getIdentifier(roi));
1567  ROIbox->SetMainColor(kSpring - 9);
1568  ROIbox->SetMainTransparency(50);
1569 
1570  addToGroup("ROIs", ROIbox);
1571  addObject(roi, ROIbox);
1572 }
1573 
1574 void EVEVisualization::addRecoHit(const SVDCluster* hit, TEveStraightLineSet* lines)
1575 {
1576  static VXD::GeoCache& geo = VXD::GeoCache::getInstance();
1577  const VXD::SensorInfoBase& sensor = geo.get(hit->getSensorID());
1578 
1579  TVector3 a, b;
1580  if (hit->isUCluster()) {
1581  const float u = hit->getPosition();
1582  a = sensor.pointToGlobal(TVector3(sensor.getBackwardWidth() / sensor.getWidth(0) * u, -0.5 * sensor.getLength(), 0.0));
1583  b = sensor.pointToGlobal(TVector3(sensor.getForwardWidth() / sensor.getWidth(0) * u, +0.5 * sensor.getLength(), 0.0));
1584  } else {
1585  const float v = hit->getPosition();
1586  a = sensor.pointToGlobal(TVector3(-0.5 * sensor.getWidth(v), v, 0.0));
1587  b = sensor.pointToGlobal(TVector3(+0.5 * sensor.getWidth(v), v, 0.0));
1588  }
1589 
1590  lines->AddLine(a.x(), a.y(), a.z(), b.x(), b.y(), b.z());
1591  m_shownRecohits.insert(hit);
1592 }
1593 
1594 void EVEVisualization::addRecoHit(const CDCHit* hit, TEveStraightLineSet* lines)
1595 {
1597  const TVector3& wire_pos_f = cdcgeo.wireForwardPosition(WireID(hit->getID()));
1598  const TVector3& wire_pos_b = cdcgeo.wireBackwardPosition(WireID(hit->getID()));
1599 
1600  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());
1601  m_shownRecohits.insert(hit);
1602 
1603 }
1604 
1605 void EVEVisualization::addCDCHit(const CDCHit* hit, bool showTriggerHits)
1606 {
1608  const TVector3& wire_pos_f = cdcgeo.wireForwardPosition(WireID(hit->getID()));
1609  const TVector3& wire_pos_b = cdcgeo.wireBackwardPosition(WireID(hit->getID()));
1610  static CDC::RealisticTDCCountTranslator tdcTranslator;
1611  TEveGeoShape* cov_shape = new TEveGeoShape("cov_shape");
1612  //TODO: leftrightflag not set! (same for other parameters, unsure which ones should be set)
1613  double driftLength = tdcTranslator.getDriftLength(hit->getTDCCount(), WireID(hit->getID()));
1614  double driftLengthRes = tdcTranslator.getDriftLengthResolution(driftLength, WireID(hit->getID()));
1615  driftLengthRes = std::max(driftLengthRes, 0.005);
1616  const double lengthOfWireSection = 3.0;
1617 
1618  //z in wire direction, x,y orthogonal
1619  const TVector3 zaxis = wire_pos_b - wire_pos_f;
1620  const TVector3 xaxis = zaxis.Orthogonal();
1621  const TVector3 yaxis = xaxis.Cross(zaxis);
1622 
1623  // move to z=0
1624  const TVector3 midPoint = wire_pos_f - zaxis * (wire_pos_f.z() / zaxis.z());
1625 
1626  cov_shape->SetShape(new TGeoTube(std::max(0., (double)(driftLength - driftLengthRes)), driftLength + driftLengthRes,
1627  lengthOfWireSection));
1628  fixGeoShapeRefCount(cov_shape);
1629 
1630  TGeoRotation det_rot("det_rot",
1631  xaxis.Theta() * 180 / TMath::Pi(), xaxis.Phi() * 180 / TMath::Pi(),
1632  yaxis.Theta() * 180 / TMath::Pi(), yaxis.Phi() * 180 / TMath::Pi(),
1633  zaxis.Theta() * 180 / TMath::Pi(), zaxis.Phi() * 180 / TMath::Pi()
1634  );
1635 
1636  TGeoCombiTrans det_trans(midPoint(0), midPoint(1), midPoint(2), &det_rot);
1637  cov_shape->SetTransMatrix(det_trans);
1638 
1639  // get relation to trigger track segments
1640  bool isPartOfTS = false;
1641  const auto segments = hit->getRelationsFrom<CDCTriggerSegmentHit>();
1642  if (showTriggerHits && segments.size() > 0) {
1643  isPartOfTS = true;
1644  }
1645 
1646  if (hit->getISuperLayer() % 2 == 0) {
1647  if (isPartOfTS)
1648  cov_shape->SetMainColor(kCyan + 3);
1649  else
1650  cov_shape->SetMainColor(kCyan);
1651  } else {
1652  if (isPartOfTS)
1653  cov_shape->SetMainColor(kPink + 6);
1654  else
1655  cov_shape->SetMainColor(kPink + 7);
1656  }
1657 
1658  cov_shape->SetMainTransparency(50);
1659  cov_shape->SetName(ObjectInfo::getIdentifier(hit));
1660  cov_shape->SetTitle(ObjectInfo::getInfo(hit) + TString::Format("\nWire ID: %d\nADC: %d\nTDC: %d",
1661  hit->getID(), hit->getADCCount(), hit->getTDCCount()));
1662 
1663  addToGroup("CDCHits", cov_shape);
1664  addObject(hit, cov_shape);
1665  if (isPartOfTS) {
1666  addToGroup("CDCTriggerSegmentHits", cov_shape);
1667  for (auto rel : segments.relations()) {
1668  addObject(rel.object, cov_shape);
1669  }
1670  }
1671 }
1672 
1673 void EVEVisualization::addCDCTriggerSegmentHit(const std::string& collectionName, const CDCTriggerSegmentHit* hit)
1674 {
1676  TEveStraightLineSet* shape = new TEveStraightLineSet();
1677 
1678  // get center wire
1679  unsigned iL = WireID(hit->getID()).getICLayer();
1680  if (hit->getPriorityPosition() < 3) iL -= 1;
1681  unsigned nWires = cdcgeo.nWiresInLayer(iL);
1682  unsigned iCenter = hit->getIWire();
1683  if (hit->getPriorityPosition() == 1) iCenter += 1;
1684 
1685  // a track segment consists of 11 wires (15 in SL0) in a special configuration
1686  // -> get the shift with respect to the center wire (*) for all wires
1687  // SL 1-8:
1688  // _ _ _
1689  // |_|_|_|
1690  // |_|_|
1691  // |*|
1692  // |_|_|
1693  // |_|_|_|
1694  std::vector<int> layershift = { -2, -1, 0, 1, 2};
1695  std::vector<std::vector<float>> cellshift = {
1696  { -1, 0, 1},
1697  { -0.5, 0.5},
1698  { 0},
1699  { -0.5, 0.5},
1700  { -1, 0, 1}
1701  };
1702  // SL 0:
1703  // _ _ _ _ _
1704  // |_|_|_|_|_|
1705  // |_|_|_|_|
1706  // |_|_|_|
1707  // |_|_|
1708  // |*|
1709  if (hit->getISuperLayer() == 0) {
1710  layershift = { 0, 1, 2, 3, 4};
1711  cellshift = {
1712  { 0},
1713  { -0.5, 0.5},
1714  { -1, 0, 1},
1715  { -1.5, -0.5, 0.5, 1.5},
1716  { -2, -1, 0, 1, 2}
1717  };
1718  }
1719 
1720  // draw all cells in segment
1721  for (unsigned il = 0; il < layershift.size(); ++il) {
1722  for (unsigned ic = 0; ic < cellshift[il].size(); ++ic) {
1723  TVector3 corners[2][2];
1724  for (unsigned ir = 0; ir < 2; ++ir) {
1725  double r = cdcgeo.fieldWireR(iL + layershift[il] - ir);
1726  double fz = cdcgeo.fieldWireFZ(iL + layershift[il] - ir);
1727  double bz = cdcgeo.fieldWireBZ(iL + layershift[il] - ir);
1728  for (unsigned iphi = 0; iphi < 2; ++iphi) {
1729  double phib = (iCenter + cellshift[il][ic] + iphi - 0.5) * 2 * M_PI / nWires;
1730  double phif = phib + cdcgeo.nShifts(iL + layershift[il]) * M_PI / nWires;
1731 
1732  TVector3 pos_f = TVector3(cos(phif) * r, sin(phif) * r, fz);
1733  TVector3 pos_b = TVector3(cos(phib) * r, sin(phib) * r, bz);
1734  TVector3 zaxis = pos_b - pos_f;
1735  corners[ir][iphi] = pos_f - zaxis * (pos_f.z() / zaxis.z());
1736  }
1737  }
1738 
1739  shape->AddLine(corners[0][0].x(), corners[0][0].y(), 0,
1740  corners[0][1].x(), corners[0][1].y(), 0);
1741  shape->AddLine(corners[0][1].x(), corners[0][1].y(), 0,
1742  corners[1][1].x(), corners[1][1].y(), 0);
1743  shape->AddLine(corners[1][1].x(), corners[1][1].y(), 0,
1744  corners[1][0].x(), corners[1][0].y(), 0);
1745  shape->AddLine(corners[1][0].x(), corners[1][0].y(), 0,
1746  corners[0][0].x(), corners[0][0].y(), 0);
1747  }
1748  }
1749 
1750  if (hit->getISuperLayer() % 2 == 0) {
1751  shape->SetMainColor(kCyan + 3);
1752  } else {
1753  shape->SetMainColor(kPink + 6);
1754  }
1755 
1756  shape->SetName(ObjectInfo::getIdentifier(hit));
1757  shape->SetTitle(ObjectInfo::getTitle(hit) +
1758  TString::Format("\nPriority: %d\nLeft/Right: %d",
1759  hit->getPriorityPosition(), hit->getLeftRight()));
1760  addToGroup(collectionName, shape);
1761  addObject(hit, shape);
1762 }
1763 
1765 {
1767 
1768  int hitModule = hit->getModule();
1769  float fi = arichGeo->getDetectorPlane().getSlotPhi(hitModule);
1770 
1771  TVector3 centerPos3D = hit->getPosition();
1772 
1773  TVector3 channelX(1, 0, 0); channelX.RotateZ(fi);
1774  TVector3 channelY(0, 1, 0); channelY.RotateZ(fi);
1775 
1776  auto* arichbox = boxCreator(centerPos3D, arichGeo->getMasterVolume().momentumToGlobal(channelX),
1777  arichGeo->getMasterVolume().momentumToGlobal(channelY), 0.49, 0.49, 0.05);
1778  arichbox->SetMainColor(kOrange + 10);
1779  arichbox->SetName((std::to_string(hitModule)).c_str());
1780 
1781  addToGroup("ARICHHits", arichbox);
1782  addObject(hit, arichbox);
1783 }
1784 
1786 {
1788  std::map<int, int> m_topSummary;
1789  for (const TOPDigit& hit : digits) {
1790  int mod = hit.getModuleID();
1791  ++m_topSummary[mod];
1792  }
1793  int maxcount = 0;
1794  for (auto modCountPair : m_topSummary) {
1795  if (modCountPair.second > maxcount)
1796  maxcount = modCountPair.second;
1797  }
1798  for (auto modCountPair : m_topSummary) {
1799  const auto& topmod = TOP::TOPGeometryPar::Instance()->getGeometry()->getModule(modCountPair.first);
1800  double phi = topmod.getPhi();
1801  double r_center = topmod.getRadius();
1802  double z = topmod.getZc();
1803 
1804  TVector3 centerPos3D;
1805  centerPos3D.SetMagThetaPhi(r_center, M_PI / 2, phi);
1806  centerPos3D.SetZ(z);
1807 
1808  TVector3 channelX(1, 0, 0); channelX.RotateZ(phi);
1809  TVector3 channelY(0, 1, 0); channelY.RotateZ(phi);
1810 
1811  //bar is a bit thicker so we can mouse over without getting the geometry
1812  auto* moduleBox = boxCreator(centerPos3D, channelX, channelY,
1813  3.0 * topmod.getBarThickness(), topmod.getBarWidth() , topmod.getBarLength());
1814  moduleBox->SetMainColor(kAzure + 10);
1815  double weight = double(modCountPair.second) / maxcount;
1816  moduleBox->SetMainTransparency(90 - weight * 50);
1817  moduleBox->SetName(("TOP module " + std::to_string(modCountPair.first)).c_str());
1818  moduleBox->SetTitle(TString::Format("#TOPDigits: %d ", modCountPair.second));
1819 
1820  addToGroup("TOP Modules", moduleBox);
1821  //associate all TOPDigits with this module.
1822  for (const TOPDigit& hit : digits) {
1823  if (modCountPair.first == hit.getModuleID())
1824  addObject(&hit, moduleBox);
1825  }
1826  }
1827 }
1828 
1829 
1831 {
1832  for (const auto& labelPair : displayData.m_labels) {
1833  TEveText* text = new TEveText(labelPair.first.c_str());
1834  text->SetName(labelPair.first.c_str());
1835  text->SetTitle(labelPair.first.c_str());
1836  text->SetMainColor(kGray + 1);
1837  const TVector3& p = labelPair.second;
1838  text->PtrMainTrans()->SetPos(p.x(), p.y(), p.z());
1839  addToGroup("DisplayData", text);
1840  }
1841 
1842  for (const auto& pointPair : displayData.m_pointSets) {
1843  TEvePointSet* points = new TEvePointSet(pointPair.first.c_str());
1844  points->SetTitle(pointPair.first.c_str());
1845  points->SetMarkerStyle(7);
1846  points->SetMainColor(kGreen);
1847  for (const TVector3& p : pointPair.second) {
1848  points->SetNextPoint(p.x(), p.y(), p.z());
1849  }
1850  addToGroup("DisplayData", points);
1851  }
1852 
1853  int randomColor = 2; //primary colours, changing rapidly with index
1854  for (const auto& arrow : displayData.m_arrows) {
1855  const TVector3 pos = arrow.start;
1856  const TVector3 dir = arrow.end - pos;
1857  TEveArrow* eveArrow = new TEveArrow(dir.x(), dir.y(), dir.z(), pos.x(), pos.y(), pos.z());
1858  eveArrow->SetName(arrow.name.c_str());
1859  eveArrow->SetTitle(arrow.name.c_str());
1860  int arrowColor = arrow.color;
1861  if (arrowColor == -1) {
1862  arrowColor = randomColor;
1863  randomColor++;
1864  }
1865  eveArrow->SetMainColor(arrowColor);
1866 
1867  //add label
1868  TEveText* text = new TEveText(arrow.name.c_str());
1869  text->SetMainColor(arrowColor);
1870  //in middle of arrow, with some slight offset
1871  const TVector3& labelPos = pos + 0.5 * dir + 0.1 * dir.Orthogonal();
1872  text->PtrMainTrans()->SetPos(labelPos.x(), labelPos.y(), labelPos.z());
1873  eveArrow->AddElement(text);
1874  addToGroup("DisplayData", eveArrow);
1875  }
1876 
1877 }
1878 void EVEVisualization::addObject(const TObject* dataStoreObject, TEveElement* visualRepresentation)
1879 {
1880  VisualRepMap::getInstance()->add(dataStoreObject, visualRepresentation);
1881 }
1882 
1883 void EVEVisualization::addToGroup(const std::string& name, TEveElement* elem)
1884 {
1885  //slashes at beginning and end are ignored
1886  const std::string& groupName = boost::algorithm::trim_copy_if(name, boost::algorithm::is_any_of("/"));
1887 
1888  TEveElementList* group = m_groups[groupName].group;
1889  if (!group) {
1890  group = new TEveElementList(groupName.c_str(), groupName.c_str());
1891  group->SetRnrState(m_groups[groupName].visible);
1892  m_groups[groupName].group = group;
1893 
1894  //if groupName contains '/', remove last bit and add to parent group
1895  //e.g. if groupName=A/B/C, call addToGroup("A/B", groupC)
1896  auto lastSlash = boost::algorithm::find_last(groupName, "/");
1897  if (lastSlash) {
1898  const std::string parentGroup(groupName.begin(), lastSlash.begin());
1899  const std::string thisGroup(lastSlash.end(), groupName.end());
1900  group->SetElementName(thisGroup.c_str());
1901  addToGroup(parentGroup, group);
1902  } else {
1903  gEve->AddElement(group);
1904  }
1905  }
1906  group->AddElement(elem);
1907 }
1908 
Datastore class that holds photon hits. Input to the reconstruction.
Definition: ARICHHit.h:23
Store one BKLM strip hit as a ROOT object.
Definition: BKLMHit2d.h:32
int getLayer() const
Get layer number.
Definition: BKLMHit2d.h:80
int getZStripMax() const
Get highest z-measuring strip number.
Definition: BKLMHit2d.h:115
int getSection() const
Get section number.
Definition: BKLMHit2d.h:66
int getSector() const
Get sector number.
Definition: BKLMHit2d.h:73
int getPhiStripMin() const
Get lowest phi-measuring strip number.
Definition: BKLMHit2d.h:87
int getZStripMin() const
Get lowest z-measuring strip number.
Definition: BKLMHit2d.h:108
int getPhiStripMax() const
Get highest phi-measuring strip number.
Definition: BKLMHit2d.h:94
TVector3 getGlobalPosition(void) const
Get 3D hit position in global coordinates.
Definition: BKLMHit2d.h:179
Store one simulation hit's global position as a ROOT object.
Store one simulation hit as a ROOT object.
Definition: BKLMSimHit.h:25
Class containing the result of the unpacker in raw data and the result of the digitizer in simulation...
Definition: CDCHit.h:40
This class is used to transfer CDC information to the track fit.
Definition: CDCRecoHit.h:32
Example Detector.
Definition: CDCSimHit.h:22
Combination of several CDCHits to a track segment hit for the trigger.
Track created by the CDC trigger.
The Class for CDC Geometry Parameters.
const TVector3 wireBackwardPosition(int layerId, int cellId, EWirePosition set=c_Base) const
Returns the backward position of the input sense wire.
int nShifts(int layerId) const
Returns number shift.
const TVector3 wireForwardPosition(int layerId, int cellId, EWirePosition set=c_Base) const
Returns the forward position of the input sense wire.
double fieldWireR(int layerId) const
Returns radius of field wire in each layer.
unsigned nWiresInLayer(int layerId) const
Returns wire numbers in a layer.
double fieldWireBZ(int layerId) const
Returns backward z position of field wire in each layer.
double fieldWireFZ(int layerId) const
Returns forward z position of field wire in each layer.
static CDCGeometryPar & Instance(const CDCGeometry *=nullptr)
Static method to get a reference to the CDCGeometryPar instance.
Translator mirroring the realistic Digitization.
double getDriftLength(unsigned short tdcCount, const WireID &wireID=WireID(), double timeOfFlightEstimator=0, bool leftRight=false, double z=0, double alpha=0, double theta=static_cast< double >(TMath::Pi()/2.), unsigned short adcCount=0) override
Get Drift length.
double getDriftLengthResolution(double driftLength, const WireID &wireID=WireID(), bool leftRight=false, double z=0, double alpha=0, double=static_cast< double >(TMath::Pi()/2.)) override
Get position resolution^2 corresponding to the drift length from getDriftLength of this class.
static const ChargedStable pion
charged pion particle
Definition: Const.h:542
Class for accessing objects in the database.
Definition: DBObjPtr.h:21
Add custom information to the display.
Definition: DisplayData.h:55
std::map< std::string, std::vector< TVector3 > > m_pointSets
name -> points map
Definition: DisplayData.h:108
std::vector< Arrow > m_arrows
List of arrows.
Definition: DisplayData.h:114
std::vector< std::pair< std::string, TVector3 > > m_labels
text labels (to be shown at a given position).
Definition: DisplayData.h:109
ECL cluster data.
Definition: ECLCluster.h:27
@ c_nPhotons
CR is split into n photons (N1)
Class for 2d hits handling.
Definition: EKLMHit2d.h:30
TVector3 getPosition() const
Get hit global position.
Class EKLMSimHit stores information on particular Geant step; using information from TrackID and Pare...
Definition: EKLMSimHit.h:32
void clearEvent()
clear event data.
void setOptions(const std::string &opts)
Set the display options.
static constexpr double c_minPCut
don't show MCParticles with momentum below this cutoff.
void addTrackCandidateImproved(const std::string &collectionName, const RecoTrack &recoTrack)
Add a RecoTrack, but use stored genfit track representation to make visualisation objects.
EveVisBField * m_bfield
The global magnetic field.
TEveStraightLineSet * m_unassignedRecoHits
Unassigned recohits.
static const int c_recoHitColor
Color for reco hits.
void addCDCHit(const CDCHit *hit, bool showTriggerHits=false)
show CDCHits directly.
std::map< const MCParticle *, MCTrack > m_mcparticleTracks
map MCParticles to MCTrack (so hits can be added to the correct track).
void setErrScale(double errScale=1.)
Set the scaling factor for the visualization of track hit errors.
void addBKLMHit2d(const BKLMHit2d *bklm2dhit)
Add a reconstructed 2d hit in the BKLM.
bool m_drawRefTrack
Draw reference track in addTrack.
void addVertex(const genfit::GFRaveVertex *vertex)
Add a vertex point and its covariance matrix.
bool m_drawForward
draw forward in addTrack
TEveCalo3D * m_calo3d
Object for the energy bar visualisation.
bool m_drawCardinalRep
Draw cardinal representation in addTrack.
void addCDCTriggerTrack(const std::string &collectionName, const CDCTriggerTrack &track)
Add a CDCTriggerTrack.
void addCDCTriggerSegmentHit(const std::string &collectionName, const CDCTriggerSegmentHit *hit)
show outline of track segments.
TEveTrackPropagator * m_trackpropagator
Track propagator for MCParticles.
std::map< std::string, ElementGroup > m_groups
name -> grouping element.
void addSimHit(const CDCSimHit *hit, const MCParticle *particle)
Add a CDCSimHit.
void addECLCluster(const ECLCluster *cluster)
Add a reconstructed cluster in the ECL.
void addEKLMHit2d(const EKLMHit2d *bklm2dhit)
Add a reconstructed 2d hit in the EKLM.
TEveTrackList * m_tracklist
parent object for MC tracks.
void addToGroup(const std::string &name, TEveElement *elem)
Add 'elem' to the element group 'name' (created if necessary).
void makeTracks()
Create visual representation of all tracks.
void addRecoHit(const SomeVXDHit *hit, TEveStraightLineSet *lines)
adds given VXD hit to lines.
void addTrack(const Belle2::Track *belle2Track)
Add this genfit::Track to event data.
bool m_unassignedRecoHitsVisibility
is m_unassignedRecoHits visible?
static const int c_trackMarkerColor
Color for track markers.
TEveTrackPropagator * m_gftrackpropagator
Track propagator for genfit::Tracks (different mainly because of drawing options)
std::string m_options
Option string for genfit::Track visualisation.
static const int c_trackColor
Color for tracks.
static const int c_unassignedHitColor
Color for unassigned (reco)hits.
bool m_hideSecondaries
If true, secondary MCParticles (and hits created by them) will not be shown.
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...
void addARICHHit(const ARICHHit *hit)
Add recontructed hit in ARICH.
void showUserData(const DisplayData &displayData)
Add user-defined data (labels, points, etc.)
std::set< const TObject * > m_shownRecohits
List of shown recohits (PXDCluster, SVDCluster, CDCHit).
bool m_drawBackward
draw backward in addTrack
TEveTrackPropagator * m_consttrackpropagator
Track propagator for CDCTriggerTracks (uses constant B field)
bool m_assignToPrimaries
If true, hits created by secondary particles (e.g.
bool m_drawErrors
Draw errors in addTrack.
double m_errorScale
Rescale PXD/SVD errors with this factor to ensure visibility.
void addTOPDigits(const StoreArray< TOPDigit > &digits)
Add TOPDigits (shown aggregated per module).
void addROI(const ROIid *roi)
Add a Region Of Interest, computed by the PXDDataReduction module.
void addKLMCluster(const KLMCluster *cluster)
Add a reconstructed cluster in the KLM.
static const int c_klmClusterColor
Color for KLMCluster objects.
MCTrack * addMCParticle(const MCParticle *particle)
Return MCTrack for given particle, add it if it doesn't exist yet.
TEveCaloDataVec * m_eclData
ECL cluster data.
static const int c_recoTrackColor
Color for TrackCandidates.
void addTrackCandidate(const std::string &collectionName, const RecoTrack &recoTrack)
Add a RecoTrack, to evaluate track finding.
void addObject(const TObject *dataStoreObject, TEveElement *visualRepresentation)
Generic function to keep track of which objects have which visual representation.
void makeLines(TEveTrack *eveTrack, const genfit::StateOnPlane *prevState, const genfit::StateOnPlane *state, const genfit::AbsTrackRep *rep, TEvePathMark::EType_e markType, bool drawErrors, int markerPos=1)
Create hit visualisation for the given options, and add them to 'eveTrack'.
Provide magnetic field values for TEveTrackPropagator.
Definition: EveVisBField.h:19
KLM cluster data.
Definition: KLMCluster.h:28
Class to save the full simulated trajectory of a particle.
const MCTrajectoryPoint & back() const
return reference to the last point
A Class to store the Monte Carlo particle information.
Definition: MCParticle.h:32
@ c_PrimaryParticle
bit 0: Particle is primary particle.
Definition: MCParticle.h:47
@ c_StoppedInDetector
bit 3: Particle was stopped in the detector (the simulation volume).
Definition: MCParticle.h:53
The PXD Cluster class This class stores all information about reconstructed PXD clusters The position...
Definition: PXDCluster.h:30
Class PXDSimHit - Geant4 simulated hit for the PXD.
Definition: PXDSimHit.h:24
ROIid stores the U and V ids and the sensor id of the Region Of Interest.
Definition: ROIid.h:25
This is the Reconstruction Event-Data Model Track.
Definition: RecoTrack.h:76
std::vector< Belle2::RecoTrack::UsedSVDHit * > getSVDHitList() const
Return an unsorted list of svd hits.
Definition: RecoTrack.h:448
std::vector< Belle2::RecoTrack::UsedPXDHit * > getPXDHitList() const
Return an unsorted list of pxd hits.
Definition: RecoTrack.h:451
std::vector< Belle2::RecoTrack::UsedCDCHit * > getCDCHitList() const
Return an unsorted list of cdc hits.
Definition: RecoTrack.h:445
TVector3 getMomentumSeed() const
Return the momentum seed stored in the reco track. ATTENTION: This is not the fitted momentum.
Definition: RecoTrack.h:483
const genfit::TrackPoint * getCreatedTrackPoint(const RecoHitInformation *recoHitInformation) const
Get a pointer to the TrackPoint that was created from this hit.
Definition: RecoTrack.cc:227
std::vector< RecoHitInformation * > getRecoHitInformations(bool getSorted=false) const
Return a list of all RecoHitInformations associated with the RecoTrack.
Definition: RecoTrack.cc:538
TVector3 getPositionSeed() const
Return the position seed stored in the reco track. ATTENTION: This is not the fitted position.
Definition: RecoTrack.h:476
short int getChargeSeed() const
Return the charge seed stored in the reco track. ATTENTION: This is not the fitted charge.
Definition: RecoTrack.h:496
T * getRelated(const std::string &name="", const std::string &namedRelation="") const
Get the object to or from which this object has a relation.
The SVD Cluster class This class stores all information about reconstructed SVD clusters.
Definition: SVDCluster.h:28
SVDRecoHit - an extended form of SVDHit containing geometry information.
Definition: SVDRecoHit.h:47
bool isU() const
Is the coordinate u or v?
Definition: SVDRecoHit.h:91
VxdID getSensorID() const
Get the compact ID.
Definition: SVDRecoHit.h:82
Class SVDSimHit - Geant4 simulated hit for the SVD.
Definition: SVDSimHit.h:26
Class to store TOP digitized hits (output of TOPDigitizer or raw data unpacker) relations to TOPSimHi...
Definition: TOPDigit.h:24
const TOPGeometry * getGeometry() const
Returns pointer to geometry object using basf2 units.
static TOPGeometryPar * Instance()
Static method to obtain the pointer to its instance.
Values of the result of a track fit with a given particle hypothesis.
Helix getHelix() const
Conversion to framework Helix (without covariance).
short getChargeSign() const
Return track charge (1 or -1).
double getPValue() const
Getter for Chi2 Probability of the track fit.
TVector3 getMomentum() const
Getter for vector of momentum at closest approach of track in r/phi projection.
TVector3 getPosition() const
Getter for vector of position at closest approach of track in r/phi projection.
Class that bundles various TrackFitResults.
Definition: Track.h:25
const TrackFitResult * getTrackFitResultWithClosestMass(const Const::ChargedStable &requestedType) const
Return the track fit for a fit hypothesis with the closest mass.
Definition: Track.cc:68
Class to faciliate easy access to sensor information of the VXD like coordinate transformations or pi...
Definition: GeoCache.h:39
const SensorInfoBase & getSensorInfo(Belle2::VxdID id) const
Return a referecne to the SensorInfo of a given SensorID.
Definition: GeoCache.cc:66
static GeoCache & getInstance()
Return a reference to the singleton instance.
Definition: GeoCache.cc:213
static const SensorInfoBase & get(Belle2::VxdID id)
Return a reference to the SensorInfo of a given SensorID.
Definition: GeoCache.h:139
Base class to provide Sensor Information for PXD and SVD.
double getVCellPosition(int vID) const
Return the position of a specific strip/pixel in v direction.
double getUCellPosition(int uID, int vID=-1) const
Return the position of a specific strip/pixel in u direction.
TVector3 pointToGlobal(const TVector3 &local, bool reco=false) const
Convert a point from local to global coordinates.
void addCluster(const TObject *dataStoreObject, TEveCaloData *caloData, int towerID)
Selection inside TEveCalo* is complicated, use this to keep track of ECL clusters.
static VisualRepMap * getInstance()
get instance pointer.
Definition: VisualRepMap.cc:36
void clear()
Remove all contents in map.
Definition: VisualRepMap.cc:46
void add(const TObject *dataStoreObject, TEveElement *visualRepresentation)
Generic function to keep track of which objects have which visual representation.
Class to uniquely identify a any structure of the PXD and SVD.
Definition: VxdID.h:33
Class to identify a wire inside the CDC.
Definition: WireID.h:34
unsigned short getICLayer() const
Getter for continuous layer numbering.
Definition: WireID.cc:24
Provides BKLM geometry parameters for simulation, reconstruction etc (from Gearbox or DataBase)
Definition: GeometryPar.h:38
const Module * findModule(int section, int sector, int layer) const
Get the pointer to the definition of a module.
Definition: GeometryPar.cc:727
static GeometryPar * instance(void)
Static method to get a reference to the singleton GeometryPar instance.
Definition: GeometryPar.cc:28
Define the geometry of a BKLM module Each sector [octant] contains Modules.
Definition: Module.h:76
This class collects all information needed and produced by a specific AbsFitter and is specific to on...
Definition: AbsFitterInfo.h:42
Contains the measurement and covariance in raw detector coordinates.
Abstract base class for a track representation.
Definition: AbsTrackRep.h:66
void getPosDir(const StateOnPlane &state, TVector3 &pos, TVector3 &dir) const
Get cartesian position and direction vector of a state.
Definition: AbsTrackRep.h:252
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,...
virtual TVector3 getPos(const StateOnPlane &state) const =0
Get the cartesian position of a state.
virtual void getPosMomCov(const MeasuredStateOnPlane &state, TVector3 &pos, TVector3 &mom, TMatrixDSym &cov) const =0
Translates MeasuredStateOnPlane into 3D position, momentum and 6x6 covariance.
Detector plane.
Definition: DetPlane.h:59
Exception class for error handling in GENFIT (provides storage for diagnostic information)
Definition: Exception.h:48
Class where important numbers and properties of a fit can be stored.
Definition: FitStatus.h:80
bool isTrackPruned() const
Has the track been pruned after the fit?
Definition: FitStatus.h:116
GFRaveVertex class.
Definition: GFRaveVertex.h:48
Collects information needed and produced by a GblFitter/GBL and is specific to one AbsTrackRep of the...
Definition: GblFitterInfo.h:52
const MeasuredStateOnPlane & getFittedState(bool afterKink=true) const override
Get the prediction at this point Always biased in GBL (global fit) There are 2 states,...
MeasurementOnPlane getMeasurement() const
Get the measurement on plane from stored measurement data (from last construction/update)
StateOnPlane getReferenceState() const
Returns (copy of) the stored reference 5D state at current plane with internal rep.
Collects information needed and produced by a AbsKalmanFitter implementations and is specific to one ...
#StateOnPlane with additional covariance matrix.
Measured coordinates on a plane.
Measurement class implementing a planar hit geometry (1 or 2D).
Class for measurements implementing a space point hit geometry.
A state with arbitrary dimension defined in a DetPlane.
Definition: StateOnPlane.h:47
Object containing AbsMeasurement and AbsFitterInfo objects.
Definition: TrackPoint.h:46
AbsFitterInfo * getFitterInfo(const AbsTrackRep *rep=nullptr) const
Get fitterInfo for rep. Per default, use cardinal rep.
Definition: TrackPoint.cc:170
Class for measurements in wire detectors (Straw tubes and drift chambers) which do not measure the co...
Class for measurements in wire detectors (Straw tubes and drift chambers) which do not measure the co...
Class for measurements in wire detectors (Straw tubes and drift chambers) which can measure the coord...
const TOPGeoModule & getModule(int moduleID) const
Returns module.
Definition: TOPGeometry.cc:42
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:115
double getMaxR()
find a point that is inside the top node.
Definition: EveGeometry.cc:184
TString getIdentifier(const TObject *obj)
Where is this object in the datastore?
Definition: ObjectInfo.cc:105
TString getInfo(const TObject *obj)
Get object info HTML (e.g.
Definition: ObjectInfo.cc:55
TString getTitle(const TObject *obj)
Get plain text for TEve object titles (shown on mouse-over).
Definition: ObjectInfo.cc:68
Implements a colour palette, see http://sobac.com/sobac/tangocolors.htm.
Definition: ColorPalette.h:23
int getTColorID(const std::string &tangoName, int tangoId=1)
Get TColor ID for given name in tango colour palette.
Definition: ColorPalette.cc:39
Abstract base class for different kinds of events.
Defines for I/O streams used for error and debug printing.
std::shared_ptr< genfit::DetPlane > SharedPlanePtr
Shared Pointer to a DetPlane.
Hold MC tracks and associated visualisation objects.
TEvePointSet * simhits
simhit positions.
const MCParticle * parentParticle
parent particle, or nullptr.
TEveTrack * track
the actual MC track.
Small struct to encode a position/momentum without additional overhead.