EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
EventDisplay.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file EventDisplay.cc
1 
2 #include "EventDisplay.h"
3 
4 #include <assert.h>
5 #include <algorithm>
6 #include <cmath>
7 #include <exception>
8 #include <iostream>
9 #include <sys/time.h>
10 
11 #include "AbsMeasurement.h"
12 #include "FullMeasurement.h"
13 #include "PlanarMeasurement.h"
15 #include "SpacepointMeasurement.h"
16 #include "WireMeasurement.h"
17 #include "WirePointMeasurement.h"
18 #include "AbsTrackRep.h"
19 #include "ConstField.h"
20 #include "DetPlane.h"
21 #include "Exception.h"
22 #include "FieldManager.h"
23 #include "Tools.h"
24 #include "KalmanFitterInfo.h"
25 #include "KalmanFitter.h"
26 #include "DAF.h"
27 #include "KalmanFitterRefTrack.h"
28 #include "RKTrackRep.h"
29 
30 #include <TApplication.h>
31 #include <TEveBrowser.h>
32 #include <TEveManager.h>
33 #include <TEveEventManager.h>
34 #include <TEveGeoNode.h>
35 #include <TEveGeoShape.h>
36 #include <TEveStraightLineSet.h>
37 #include <TEveTriangleSet.h>
38 #include <TDecompSVD.h>
39 #include <TGButton.h>
40 #include <TGLabel.h>
41 #include <TGNumberEntry.h>
42 #include <TGeoEltu.h>
43 #include <TGeoManager.h>
44 #include <TGeoMatrix.h>
45 #include <TGeoNode.h>
46 #include <TGeoSphere.h>
47 #include <TGeoTube.h>
48 #include <TMath.h>
49 #include <TMatrixT.h>
50 #include <TMatrixTSym.h>
51 #include <TMatrixDSymEigen.h>
52 #include <TROOT.h>
53 #include <TVector2.h>
54 #include <TVectorD.h>
55 #include <TSystem.h>
56 
57 #include <memory>
58 
59 namespace genfit {
60 
61 
62 EventDisplay* EventDisplay::eventDisplay_ = nullptr;
63 
65  errorScale_(1.),
66  drawGeometry_(false),
67  drawDetectors_(true),
68  drawHits_(true),
69  drawErrors_(true),
70  drawPlanes_(true),
71  drawTrackMarkers_(true),
72  drawTrack_(true),
73  drawRefTrack_(true),
74  drawForward_(true),
75  drawBackward_(true),
76  drawAutoScale_(true),
77  drawScaleMan_(false),
78  drawSilent_(false),
79  drawCardinalRep_(true),
80  repId_(0),
81  drawAllTracks_(true),
82  trackId_(0),
83  refit_(false),
84  debugLvl_(0),
85  fitterId_(SimpleKalman),
86  mmHandling_(weightedAverage),
87  squareRootFormalism_(false),
88  dPVal_(1.E-3),
89  dRelChi2_(0.2),
90  dChi2Ref_(1.),
91  nMinIter_(2),
92  nMaxIter_(4),
93  nMaxFailed_(-1),
94  resort_(false)
95 {
96 
97  if((!gApplication) || (gApplication && gApplication->TestBit(TApplication::kDefaultApplication))) {
98  std::cout << "In EventDisplay ctor: gApplication not found, creating..." << std::flush;
99  new TApplication("ROOT_application", 0, 0);
100  std::cout << "done!" << std::endl;
101  }
102  if(!gEve) {
103  std::cout << "In EventDisplay ctor: gEve not found, creating..." << std::flush;
104  TEveManager::Create();
105  std::cout << "done!" << std::endl;
106  }
107 
108  eventId_ = 0;
109 
110 }
111 
112 void EventDisplay::setOptions(std::string opts) {
113 
114  if(opts != "") {
115  for(size_t i = 0; i < opts.length(); ++i) {
116  if(opts[i] == 'A') drawAutoScale_ = true;
117  if(opts[i] == 'B') drawBackward_ = true;
118  if(opts[i] == 'D') drawDetectors_ = true;
119  if(opts[i] == 'E') drawErrors_ = true;
120  if(opts[i] == 'F') drawForward_ = true;
121  if(opts[i] == 'H') drawHits_ = true;
122  if(opts[i] == 'M') drawTrackMarkers_ = true;
123  if(opts[i] == 'P') drawPlanes_ = true;
124  if(opts[i] == 'S') drawScaleMan_ = true;
125  if(opts[i] == 'T') drawTrack_ = true;
126  if(opts[i] == 'X') drawSilent_ = true;
127  if(opts[i] == 'G') drawGeometry_ = true;
128  }
129  }
130 
131 }
132 
133 void EventDisplay::setErrScale(double errScale) { errorScale_ = errScale; }
134 
136 
138 
139  if(eventDisplay_ == nullptr) {
140  eventDisplay_ = new EventDisplay();
141  }
142  return eventDisplay_;
143 
144 }
145 
147 
149 
150  for(unsigned int i = 0; i < events_.size(); i++) {
151 
152  for(unsigned int j = 0; j < events_[i]->size(); j++) {
153 
154  delete events_[i]->at(j);
155 
156  }
157  delete events_[i];
158  }
159 
160  events_.clear();
161 }
162 
163 
164 void EventDisplay::addEvent(std::vector<Track*>& tracks) {
165 
166  std::vector<Track*>* vec = new std::vector<Track*>;
167 
168  for(unsigned int i = 0; i < tracks.size(); i++) {
169  vec->push_back(new Track(*(tracks[i])));
170  }
171 
172  events_.push_back(vec);
173 }
174 
175 
176 void EventDisplay::addEvent(std::vector<const Track*>& tracks) {
177 
178  std::vector<Track*>* vec = new std::vector<Track*>;
179 
180  for(unsigned int i = 0; i < tracks.size(); i++) {
181  vec->push_back(new Track(*(tracks[i])));
182  }
183 
184  events_.push_back(vec);
185 }
186 
187 
188 void EventDisplay::addEvent(const Track* tr) {
189 
190  std::vector<Track*>* vec = new std::vector<Track*>;
191  vec->push_back(new Track(*tr));
192  events_.push_back(vec);
193 }
194 
195 
196 void EventDisplay::next(unsigned int stp) {
197 
198  gotoEvent(eventId_ + stp);
199 
200 }
201 
202 void EventDisplay::prev(unsigned int stp) {
203 
204  if(events_.size() == 0) return;
205  if(eventId_ < stp) {
206  gotoEvent(0);
207  } else {
208  gotoEvent(eventId_ - stp);
209  }
210 
211 }
212 
213 int EventDisplay::getNEvents() { return events_.size(); }
214 
215 
216 void EventDisplay::gotoEvent(unsigned int id) {
217 
218  if (events_.size() == 0)
219  return;
220  else if(id >= events_.size())
221  id = events_.size() - 1;
222 
223  bool resetCam = true;
224 
225  if (id == eventId_)
226  resetCam = false;
227 
228  eventId_ = id;
229 
230  std::cout << "At event " << id << std::endl;
231  if (gEve->GetCurrentEvent()) {
232  gEve->GetCurrentEvent()->DestroyElements();
233  }
234  double old_error_scale = errorScale_;
235  drawEvent(eventId_, resetCam);
236  if(old_error_scale != errorScale_) {
237  if (gEve->GetCurrentEvent()) {
238  gEve->GetCurrentEvent()->DestroyElements();
239  }
240  drawEvent(eventId_, resetCam); // if autoscaling changed the error, draw again.
241  }
242  errorScale_ = old_error_scale;
243 
244 }
245 
247 
248  std::cout << "EventDisplay::open(); " << getNEvents() << " events loaded" << std::endl;
249 
250  if(getNEvents() > 0) {
251  double old_error_scale = errorScale_;
252  drawEvent(0);
253  if(old_error_scale != errorScale_) {
254  std::cout << "autoscaling changed the error, draw again." << std::endl;
255  gotoEvent(0); // if autoscaling changed the error, draw again.
256  }
257  errorScale_ = old_error_scale;
258  }
259 
260 
261  if(!drawSilent_) {
262  makeGui();
263  gApplication->Run(kTRUE);
264  }
265 
266  std::cout << "opened" << std::endl;
267 
268 }
269 
270 
271 void EventDisplay::drawEvent(unsigned int id, bool resetCam) {
272 
273  std::cout << "EventDisplay::drawEvent(" << id << ")" << std::endl;
274 
275 
276  // draw the geometry, does not really work yet. If it's fixed, the docu in the header file should be changed.
277  if(drawGeometry_) {
278  TGeoNode* top_node = gGeoManager->GetTopNode();
279  assert(top_node != nullptr);
280 
281  //Set transparency & color of geometry
282  TObjArray* volumes = gGeoManager->GetListOfVolumes();
283  for(int i = 0; i < volumes->GetEntriesFast(); i++) {
284  TGeoVolume* volume = dynamic_cast<TGeoVolume*>(volumes->At(i));
285  assert(volume != nullptr);
286  volume->SetLineColor(12);
287  volume->SetTransparency(50);
288  }
289 
290  TEveGeoTopNode* eve_top_node = new TEveGeoTopNode(gGeoManager, top_node);
291  eve_top_node->IncDenyDestroy();
292  gEve->AddElement(eve_top_node);
293  }
294 
295 
296  for(unsigned int i = 0; i < events_.at(id)->size(); i++) { // loop over all tracks in an event
297 
298  if (!drawAllTracks_ && trackId_ != i)
299  continue;
300 
301  Track* track = events_[id]->at(i);
302  try {
303  track->checkConsistency();
304  } catch (genfit::Exception& e) {
305  std::cerr<< e.getExcString() <<std::endl;
306  continue;
307  }
308 
309  std::unique_ptr<Track> refittedTrack(nullptr);
310  if (refit_) {
311 
312  std::cout << "Refit track:" << std::endl;
313 
314  std::unique_ptr<AbsKalmanFitter> fitter;
315  switch (fitterId_) {
316  case SimpleKalman:
317  fitter.reset(new KalmanFitter(nMaxIter_, dPVal_));
318  fitter->setMultipleMeasurementHandling(mmHandling_);
319  (static_cast<KalmanFitter*>(fitter.get()))->useSquareRootFormalism(squareRootFormalism_);
320  break;
321 
322  case RefKalman:
323  fitter.reset(new KalmanFitterRefTrack(nMaxIter_, dPVal_));
324  fitter->setMultipleMeasurementHandling(mmHandling_);
325  static_cast<KalmanFitterRefTrack*>(fitter.get())->setDeltaChi2Ref(dChi2Ref_);
326  break;
327 
328  case DafSimple:
329  fitter.reset(new DAF(false));
330  ( static_cast<KalmanFitter*>( (static_cast<DAF*>(fitter.get()))->getKalman() ) )->useSquareRootFormalism(squareRootFormalism_);
331  break;
332  case DafRef:
333  fitter.reset(new DAF());
334  ( static_cast<KalmanFitterRefTrack*>( (static_cast<DAF*>(fitter.get()))->getKalman() ) )->setDeltaChi2Ref(dChi2Ref_);
335  break;
336 
337  }
338  fitter->setDebugLvl(std::max(0, (int)debugLvl_-1));
339  fitter->setMinIterations(nMinIter_);
340  fitter->setMaxIterations(nMaxIter_);
341  fitter->setRelChi2Change(dRelChi2_);
342  fitter->setMaxFailedHits(nMaxFailed_);
343 
344 
345  refittedTrack.reset(new Track(*track));
346  refittedTrack->deleteFitterInfo();
347 
348  if (debugLvl_>0)
349  refittedTrack->Print("C");
350 
351  timeval startcputime, endcputime;
352 
353  try{
354  gettimeofday(&startcputime, nullptr);
355  fitter->processTrack(refittedTrack.get(), resort_);
356  gettimeofday(&endcputime, nullptr);
357  }
358  catch(genfit::Exception& e){
359  std::cerr << e.what();
360  std::cerr << "Exception, could not refit track" << std::endl;
361  continue;
362  }
363 
364  int microseconds = 1000000*(endcputime.tv_sec - startcputime.tv_sec) + (endcputime.tv_usec - startcputime.tv_usec);
365  std::cout << "it took " << double(microseconds) / 1000 << " ms of CPU to fit the track\n";
366 
367  try {
368  refittedTrack->checkConsistency();
369  } catch (genfit::Exception& e) {
370  std::cerr<< e.getExcString() <<std::endl;
371  continue;
372  }
373 
374  track = refittedTrack.get();
375  }
376 
377 
378 
379 
380  AbsTrackRep* rep;
381 
382  if (drawCardinalRep_) {
383  rep = track->getCardinalRep();
384  std::cout << "Draw cardinal rep" << std::endl;
385  }
386  else {
387  if (repId_ >= track->getNumReps())
388  repId_ = track->getNumReps() - 1;
389  rep = track->getTrackRep(repId_);
390  std::cout << "Draw rep" << repId_ << std::endl;
391  }
392 
393  if (debugLvl_>0) {
394  std::cout << "track " << i << std::endl;
395  //track->Print();
396  track->Print("C");
397  track->getFitStatus(rep)->Print();
398 
399  if (track->getFitStatus(rep)->isFitted()) {
400  try {
401  std::cout << "fitted state: \n";
402  track->getFittedState().Print();
403  }
404  catch (Exception& e) {
405  std::cerr << e.what();
406  }
407  }
408  }
409 
410 
411 
412  rep->setPropDir(0);
413 
414  unsigned int numhits = track->getNumPointsWithMeasurement();
415 
416  KalmanFitterInfo* fi;
417  KalmanFitterInfo* prevFi = 0;
418  const MeasuredStateOnPlane* fittedState(nullptr);
419  const MeasuredStateOnPlane* prevFittedState(nullptr);
420 
421  for(unsigned int j = 0; j < numhits; j++) { // loop over all hits in the track
422 
423  fittedState = nullptr;
424 
425  TrackPoint* tp = track->getPointWithMeasurement(j);
426  if (! tp->hasRawMeasurements()) {
427  std::cerr<<"trackPoint has no raw measurements"<<std::endl;
428  continue;
429  }
430 
431  const AbsMeasurement* m = tp->getRawMeasurement();
432  int hit_coords_dim = m->getDim();
433 
434  // check if multiple AbsMeasurements are of same type
435  if (tp->getNumRawMeasurements() > 1) {
436  bool sameTypes(true);
437  for (unsigned int iM=1; iM<tp->getNumRawMeasurements(); ++iM) {
438  if (typeid(*(tp->getRawMeasurement(iM))) != typeid(*m))
439  sameTypes = false;
440  }
441  if (!sameTypes) {
442  std::cerr<<"cannot draw trackpoint containing multiple Measurements of differend types"<<std::endl;
443  continue;
444  }
445  }
446 
447 
448 
449  // get the fitter infos ------------------------------------------------------------------
450  if (! tp->hasFitterInfo(rep)) {
451  std::cerr<<"trackPoint has no fitterInfo for rep"<<std::endl;
452  continue;
453  }
454 
455  AbsFitterInfo* fitterInfo = tp->getFitterInfo(rep);
456 
457  fi = dynamic_cast<KalmanFitterInfo*>(fitterInfo);
458  if(fi == nullptr) {
459  std::cerr<<"can only display KalmanFitterInfo"<<std::endl;
460  continue;
461  }
462  if (! fi->hasPredictionsAndUpdates()) {
463  std::cerr<<"KalmanFitterInfo does not have all predictions and updates"<<std::endl;
464  //continue;
465  }
466  else {
467  try {
468  fittedState = &(fi->getFittedState(true));
469  }
470  catch (Exception& e) {
471  std::cerr << e.what();
472  std::cerr<<"can not get fitted state"<<std::endl;
473  fittedState = nullptr;
474  prevFi = fi;
475  prevFittedState = fittedState;
476  continue;
477  }
478  }
479 
480  if (fittedState == nullptr) {
481  if (fi->hasForwardUpdate()) {
482  fittedState = fi->getForwardUpdate();
483  }
484  else if (fi->hasBackwardUpdate()) {
485  fittedState = fi->getBackwardUpdate();
486  }
487  else if (fi->hasForwardPrediction()) {
488  fittedState = fi->getForwardPrediction();
489  }
490  else if (fi->hasBackwardPrediction()) {
491  fittedState = fi->getBackwardPrediction();
492  }
493  }
494 
495  if (fittedState == nullptr) {
496  std::cout << "cannot get any state from fitterInfo, continue.\n";
497  prevFi = fi;
498  prevFittedState = fittedState;
499  continue;
500  }
501 
502  TVector3 track_pos = fittedState->getPos();
503  double charge = fittedState->getCharge();
504 
505  //std::cout << "trackPos: "; track_pos.Print();
506 
507 
508  // determine measurement type
509  bool full_hit = (dynamic_cast<const FullMeasurement*>(m) != nullptr);
510  bool planar_hit = (dynamic_cast<const PlanarMeasurement*>(m) != nullptr);
511  bool planar_pixel_hit = planar_hit && hit_coords_dim == 2;
512  bool space_hit = (dynamic_cast<const SpacepointMeasurement*>(m) != nullptr);
513  bool wire_hit = m && m->isLeftRightMeasurement();
514  bool wirepoint_hit = wire_hit && (dynamic_cast<const WirePointMeasurement*>(m) != nullptr);
515  if (!full_hit && !planar_hit && !planar_pixel_hit && !space_hit && !wire_hit && !wirepoint_hit) {
516  std::cout << "Track " << i << ", Hit " << j << ": Unknown measurement type: skipping hit!" << std::endl;
517  continue;
518  }
519 
520 
521  // loop over MeasurementOnPlanes
522  unsigned int nMeas = fi->getNumMeasurements();
523  for (unsigned int iMeas = 0; iMeas < nMeas; ++iMeas) {
524 
525  if (iMeas > 0 && wire_hit)
526  break;
527 
528  const MeasurementOnPlane* mop = fi->getMeasurementOnPlane(iMeas);
529  const TVectorT<double>& hit_coords = mop->getState();
530  const TMatrixTSym<double>& hit_cov = mop->getCov();
531 
532  // finished getting the hit infos -----------------------------------------------------
533 
534  // sort hit infos into variables ------------------------------------------------------
535  TVector3 o = fittedState->getPlane()->getO();
536  TVector3 u = fittedState->getPlane()->getU();
537  TVector3 v = fittedState->getPlane()->getV();
538 
539  double_t hit_u = 0;
540  double_t hit_v = 0;
541  double_t plane_size = 4;
542  TVector2 stripDir(1,0);
543 
544  if(planar_hit) {
545  if(!planar_pixel_hit) {
546  if (dynamic_cast<RKTrackRep*>(rep) != nullptr) {
547  const TMatrixD& H = mop->getHMatrix()->getMatrix();
548  stripDir.Set(H(0,3), H(0,4));
549  }
550  hit_u = hit_coords(0);
551  } else {
552  hit_u = hit_coords(0);
553  hit_v = hit_coords(1);
554  }
555  } else if (wire_hit) {
556  hit_u = fabs(hit_coords(0));
557  hit_v = v*(track_pos-o); // move the covariance tube so that the track goes through it
558  if (wirepoint_hit) {
559  hit_v = hit_coords(1);
560  }
561  }
562 
563  if(plane_size < 4) plane_size = 4;
564  // finished setting variables ---------------------------------------------------------
565 
566  // draw planes if corresponding option is set -----------------------------------------
567  if(iMeas == 0 &&
568  (drawPlanes_ || (drawDetectors_ && planar_hit))) {
569  TVector3 move(0,0,0);
570  if (planar_hit) move = track_pos-o;
571  if (wire_hit) move = v*(v*(track_pos-o)); // move the plane along the wire until the track goes through it
572  TEveBox* box = boxCreator(o + move, u, v, plane_size, plane_size, 0.01);
573  if (drawDetectors_ && planar_hit) {
574  box->SetMainColor(kCyan);
575  } else {
576  box->SetMainColor(kGray);
577  }
578  box->SetMainTransparency(50);
579  gEve->AddElement(box);
580  }
581  // finished drawing planes ------------------------------------------------------------
582 
583  // draw track if corresponding option is set ------------------------------------------
584  try {
585  if (j == 0) {
586  if (drawBackward_) {
588  update.extrapolateBy(-3.);
589  makeLines(&update, fi->getBackwardUpdate(), rep, kMagenta, 1, drawTrackMarkers_, drawErrors_, 1);
590  }
591  }
592  if (j > 0 && prevFi != nullptr) {
593  if(drawTrack_) {
594  makeLines(prevFittedState, fittedState, rep, charge > 0 ? kRed : kBlue, 1, drawTrackMarkers_, drawErrors_, 3);
595  if (drawErrors_) { // make sure to draw errors in both directions
596  makeLines(prevFittedState, fittedState, rep, charge > 0 ? kRed : kBlue, 1, false, drawErrors_, 0, 0);
597  }
598  }
599  if (drawForward_) {
600  makeLines(prevFi->getForwardUpdate(), fi->getForwardPrediction(), rep, kCyan, 1, drawTrackMarkers_, drawErrors_, 1, 0);
601  if (j == numhits-1) {
603  update.extrapolateBy(3.);
604  makeLines(fi->getForwardUpdate(), &update, rep, kCyan, 1, drawTrackMarkers_, drawErrors_, 1, 0);
605  }
606  }
607  if (drawBackward_) {
608  makeLines(prevFi->getBackwardPrediction(), fi->getBackwardUpdate(), rep, kMagenta, 1, drawTrackMarkers_, drawErrors_, 1);
609  }
610  // draw reference track if corresponding option is set ------------------------------------------
611  if(drawRefTrack_ && fi->hasReferenceState() && prevFi->hasReferenceState())
612  makeLines(prevFi->getReferenceState(), fi->getReferenceState(), rep, charge > 0 ? kRed + 2 : kBlue + 2, 2, drawTrackMarkers_, false, 3);
613  }
614  else if (j > 0 && prevFi == nullptr) {
615  std::cout << "previous FitterInfo == nullptr \n";
616  }
617  }
618  catch (Exception& e) {
619  std::cerr << "extrapolation failed, cannot draw track" << std::endl;
620  std::cerr << e.what();
621  }
622 
623  // draw detectors if option is set, only important for wire hits ----------------------
624  if(drawDetectors_) {
625 
626  if(wire_hit) {
627  TEveGeoShape* det_shape = new TEveGeoShape("det_shape");
628  det_shape->IncDenyDestroy();
629  det_shape->SetShape(new TGeoTube(std::max(0., (double)(hit_u-0.0105/2.)), hit_u+0.0105/2., plane_size));
630 
631  TVector3 norm = u.Cross(v);
632  TGeoRotation det_rot("det_rot", (u.Theta()*180)/TMath::Pi(), (u.Phi()*180)/TMath::Pi(),
633  (norm.Theta()*180)/TMath::Pi(), (norm.Phi()*180)/TMath::Pi(),
634  (v.Theta()*180)/TMath::Pi(), (v.Phi()*180)/TMath::Pi()); // move the tube to the right place and rotate it correctly
635  TVector3 move = v*(v*(track_pos-o)); // move the tube along the wire until the track goes through it
636  TGeoCombiTrans det_trans(o(0) + move.X(),
637  o(1) + move.Y(),
638  o(2) + move.Z(),
639  &det_rot);
640  det_shape->SetTransMatrix(det_trans);
641  det_shape->SetMainColor(kCyan);
642  det_shape->SetMainTransparency(25);
643  if((drawHits_ && (hit_u+0.0105/2 > 0)) || !drawHits_) {
644  gEve->AddElement(det_shape);
645  }
646  }
647 
648  }
649  // finished drawing detectors ---------------------------------------------------------
650 
651  if(drawHits_) {
652 
653  // draw planar hits, with distinction between strip and pixel hits ----------------
654  if (full_hit) {
655 
656  StateOnPlane dummy(rep);
657  StateOnPlane dummy2(TVectorD(rep->getDim()), static_cast<const FullMeasurement*>(m)->constructPlane(dummy), rep);
658  MeasuredStateOnPlane sop = *(static_cast<const FullMeasurement*>(m)->constructMeasurementsOnPlane(dummy2)[0]);
659  sop.getCov()*=errorScale_;
660 
661  MeasuredStateOnPlane prevSop(sop);
662  prevSop.extrapolateBy(-3);
663  makeLines(&sop, &prevSop, rep, kYellow, 1, false, true, 0, 0);
664 
665  prevSop = sop;
666  prevSop.extrapolateBy(3);
667  makeLines(&sop, &prevSop, rep, kYellow, 1, false, true, 0, 0);
668  }
669 
670  if(planar_hit) {
671  if(!planar_pixel_hit) {
672  TEveBox* hit_box;
673  TVector3 stripDir3 = stripDir.X()*u + stripDir.Y()*v;
674  TVector3 stripDir3perp = stripDir.Y()*u - stripDir.X()*v;
675  TVector3 move = stripDir3perp*(stripDir3perp*(track_pos-o));
676  hit_box = boxCreator((o + move + hit_u*stripDir3), stripDir3, stripDir3perp, errorScale_*std::sqrt(hit_cov(0,0)), plane_size, 0.0105);
677  hit_box->SetMainColor(kYellow);
678  hit_box->SetMainTransparency(0);
679  gEve->AddElement(hit_box);
680  } else {
681  // calculate eigenvalues to draw error-ellipse ----------------------------
682  TMatrixDSymEigen eigen_values(hit_cov);
683  TEveGeoShape* cov_shape = new TEveGeoShape("cov_shape");
684  cov_shape->IncDenyDestroy();
685  TVectorT<double> ev = eigen_values.GetEigenValues();
686  TMatrixT<double> eVec = eigen_values.GetEigenVectors();
687  double pseudo_res_0 = errorScale_*std::sqrt(ev(0));
688  double pseudo_res_1 = errorScale_*std::sqrt(ev(1));
689  // finished calcluating, got the values -----------------------------------
690 
691  // do autoscaling if necessary --------------------------------------------
692  if(drawAutoScale_) {
693  double min_cov = std::min(pseudo_res_0,pseudo_res_1);
694  if(min_cov < 1e-5) {
695  std::cout << "Track " << i << ", Hit " << j << ": Invalid covariance matrix (Eigenvalue < 1e-5), autoscaling not possible!" << std::endl;
696  } else {
697  if(min_cov < 0.049) {
698  double cor = 0.05 / min_cov;
699  std::cout << "Track " << i << ", Hit " << j << ": Pixel covariance too small, rescaling by " << cor;
700  errorScale_ *= cor;
701  pseudo_res_0 *= cor;
702  pseudo_res_1 *= cor;
703  std::cout << " to " << errorScale_ << std::endl;
704  }
705  }
706  }
707  // finished autoscaling ---------------------------------------------------
708 
709  // calculate the semiaxis of the error ellipse ----------------------------
710  cov_shape->SetShape(new TGeoEltu(pseudo_res_0, pseudo_res_1, 0.0105));
711  TVector3 pix_pos = o + hit_u*u + hit_v*v;
712  TVector3 u_semiaxis = (pix_pos + eVec(0,0)*u + eVec(1,0)*v)-pix_pos;
713  TVector3 v_semiaxis = (pix_pos + eVec(0,1)*u + eVec(1,1)*v)-pix_pos;
714  TVector3 norm = u.Cross(v);
715  // finished calculating ---------------------------------------------------
716 
717  // rotate and translate everything correctly ------------------------------
718  TGeoRotation det_rot("det_rot", (u_semiaxis.Theta()*180)/TMath::Pi(), (u_semiaxis.Phi()*180)/TMath::Pi(),
719  (v_semiaxis.Theta()*180)/TMath::Pi(), (v_semiaxis.Phi()*180)/TMath::Pi(),
720  (norm.Theta()*180)/TMath::Pi(), (norm.Phi()*180)/TMath::Pi());
721  TGeoCombiTrans det_trans(pix_pos(0),pix_pos(1),pix_pos(2), &det_rot);
722  cov_shape->SetTransMatrix(det_trans);
723  // finished rotating and translating --------------------------------------
724 
725  cov_shape->SetMainColor(kYellow);
726  cov_shape->SetMainTransparency(0);
727  gEve->AddElement(cov_shape);
728  }
729  }
730  // finished drawing planar hits ---------------------------------------------------
731 
732  // draw spacepoint hits -----------------------------------------------------------
733  if(space_hit) {
734  {
735  // get eigenvalues of covariance to know how to draw the ellipsoid ------------
736  TMatrixDSymEigen eigen_values(m->getRawHitCov());
737  TEveGeoShape* cov_shape = new TEveGeoShape("cov_shape");
738  cov_shape->IncDenyDestroy();
739  cov_shape->SetShape(new TGeoSphere(0.,1.));
740  TVectorT<double> ev = eigen_values.GetEigenValues();
741  TMatrixT<double> eVec = eigen_values.GetEigenVectors();
742  TVector3 eVec1(eVec(0,0),eVec(1,0),eVec(2,0));
743  TVector3 eVec2(eVec(0,1),eVec(1,1),eVec(2,1));
744  TVector3 eVec3(eVec(0,2),eVec(1,2),eVec(2,2));
745  const TVector3 norm = u.Cross(v);
746  // got everything we need -----------------------------------------------------
747 
748  static const double radDeg(180./TMath::Pi());
749  TGeoRotation det_rot("det_rot", eVec1.Theta()*radDeg, eVec1.Phi()*radDeg,
750  eVec2.Theta()*radDeg, eVec2.Phi()*radDeg,
751  eVec3.Theta()*radDeg, eVec3.Phi()*radDeg);
752 
753  if (! det_rot.IsValid()){
754  // hackish fix if eigenvectors are not orthonogonal
755  if (fabs(eVec2*eVec3) > 1.e-10)
756  eVec3 = eVec1.Cross(eVec2);
757 
758  det_rot.SetAngles(eVec1.Theta()*radDeg, eVec1.Phi()*radDeg,
759  eVec2.Theta()*radDeg, eVec2.Phi()*radDeg,
760  eVec3.Theta()*radDeg, eVec3.Phi()*radDeg);
761  }
762 
763  // set the scaled eigenvalues -------------------------------------------------
764  double pseudo_res_0 = errorScale_*std::sqrt(ev(0));
765  double pseudo_res_1 = errorScale_*std::sqrt(ev(1));
766  double pseudo_res_2 = errorScale_*std::sqrt(ev(2));
767  if(drawScaleMan_) { // override again if necessary
768  pseudo_res_0 = errorScale_*0.5;
769  pseudo_res_1 = errorScale_*0.5;
770  pseudo_res_2 = errorScale_*0.5;
771  }
772  // finished scaling -----------------------------------------------------------
773 
774  // autoscale if necessary -----------------------------------------------------
775  if(drawAutoScale_) {
776  double min_cov = std::min(pseudo_res_0,std::min(pseudo_res_1,pseudo_res_2));
777  if(min_cov < 1e-5) {
778  std::cout << "Track " << i << ", Hit " << j << ": Invalid covariance matrix (Eigenvalue < 1e-5), autoscaling not possible!" << std::endl;
779  } else {
780  if(min_cov <= 0.149) {
781  double cor = 0.15 / min_cov;
782  std::cout << "Track " << i << ", Hit " << j << ": Space hit covariance too small, rescaling by " << cor;
783  errorScale_ *= cor;
784  pseudo_res_0 *= cor;
785  pseudo_res_1 *= cor;
786  pseudo_res_2 *= cor;
787  std::cout << " to " << errorScale_ << std::endl;
788 
789  }
790  }
791  }
792  // finished autoscaling -------------------------------------------------------
793 
794  // rotate and translate -------------------------------------------------------
795  TGeoGenTrans det_trans(o(0),o(1),o(2),
796  //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
797  //1/(pseudo_res_0),1/(pseudo_res_1),1/(pseudo_res_2),
798  pseudo_res_0, pseudo_res_1, pseudo_res_2,
799  &det_rot);
800  cov_shape->SetTransMatrix(det_trans);
801  // finished rotating and translating ------------------------------------------
802 
803  cov_shape->SetMainColor(kYellow);
804  cov_shape->SetMainTransparency(10);
805  gEve->AddElement(cov_shape);
806  }
807 
808 
809  {
810  // calculate eigenvalues to draw error-ellipse ----------------------------
811  TMatrixDSymEigen eigen_values(hit_cov);
812  TEveGeoShape* cov_shape = new TEveGeoShape("cov_shape");
813  cov_shape->IncDenyDestroy();
814  TVectorT<double> ev = eigen_values.GetEigenValues();
815  TMatrixT<double> eVec = eigen_values.GetEigenVectors();
816  double pseudo_res_0 = errorScale_*std::sqrt(ev(0));
817  double pseudo_res_1 = errorScale_*std::sqrt(ev(1));
818  // finished calcluating, got the values -----------------------------------
819 
820  // do autoscaling if necessary --------------------------------------------
821  if(drawAutoScale_) {
822  double min_cov = std::min(pseudo_res_0,pseudo_res_1);
823  if(min_cov < 1e-5) {
824  std::cout << "Track " << i << ", Hit " << j << ": Invalid covariance matrix (Eigenvalue < 1e-5), autoscaling not possible!" << std::endl;
825  } else {
826  if(min_cov < 0.049) {
827  double cor = 0.05 / min_cov;
828  std::cout << "Track " << i << ", Hit " << j << ": Pixel covariance too small, rescaling by " << cor;
829  errorScale_ *= cor;
830  pseudo_res_0 *= cor;
831  pseudo_res_1 *= cor;
832  std::cout << " to " << errorScale_ << std::endl;
833  }
834  }
835  }
836  // finished autoscaling ---------------------------------------------------
837 
838  // calculate the semiaxis of the error ellipse ----------------------------
839  cov_shape->SetShape(new TGeoEltu(pseudo_res_0, pseudo_res_1, 0.0105));
840  TVector3 pix_pos = o + hit_u*u + hit_v*v;
841  TVector3 u_semiaxis = (pix_pos + eVec(0,0)*u + eVec(1,0)*v)-pix_pos;
842  TVector3 v_semiaxis = (pix_pos + eVec(0,1)*u + eVec(1,1)*v)-pix_pos;
843  TVector3 norm = u.Cross(v);
844  // finished calculating ---------------------------------------------------
845 
846  // rotate and translate everything correctly ------------------------------
847  static const double radDeg(180./TMath::Pi());
848  TGeoRotation det_rot("det_rot", u_semiaxis.Theta()*radDeg, u_semiaxis.Phi()*radDeg,
849  v_semiaxis.Theta()*radDeg, v_semiaxis.Phi()*radDeg,
850  norm.Theta()*radDeg, norm.Phi()*radDeg);
851  /*if (! det_rot.IsValid()){
852  u_semiaxis.Print();
853  v_semiaxis.Print();
854  norm.Print();
855  }*/
856  TGeoCombiTrans det_trans(pix_pos(0),pix_pos(1),pix_pos(2), &det_rot);
857  cov_shape->SetTransMatrix(det_trans);
858  // finished rotating and translating --------------------------------------
859 
860  cov_shape->SetMainColor(kYellow);
861  cov_shape->SetMainTransparency(0);
862  gEve->AddElement(cov_shape);
863  }
864  }
865  // finished drawing spacepoint hits -----------------------------------------------
866 
867  // draw wire hits -----------------------------------------------------------------
868  if(wire_hit) {
869  TEveGeoShape* cov_shape = new TEveGeoShape("cov_shape");
870  cov_shape->IncDenyDestroy();
871  double pseudo_res_0 = errorScale_*std::sqrt(hit_cov(0,0));
872  double pseudo_res_1 = plane_size;
873  if (wirepoint_hit) pseudo_res_1 = errorScale_*std::sqrt(hit_cov(1,1));
874 
875  // autoscale if necessary -----------------------------------------------------
876  if(drawAutoScale_) {
877  if(pseudo_res_0 < 1e-5) {
878  std::cout << "Track " << i << ", Hit " << j << ": Invalid wire resolution (< 1e-5), autoscaling not possible!" << std::endl;
879  } else {
880  if(pseudo_res_0 < 0.0049) {
881  double cor = 0.005 / pseudo_res_0;
882  std::cout << "Track " << i << ", Hit " << j << ": Wire covariance too small, rescaling by " << cor;
883  errorScale_ *= cor;
884  pseudo_res_0 *= cor;
885  std::cout << " to " << errorScale_ << std::endl;
886  }
887  }
888 
889  if(wirepoint_hit && pseudo_res_1 < 1e-5) {
890  std::cout << "Track " << i << ", Hit " << j << ": Invalid wire resolution (< 1e-5), autoscaling not possible!" << std::endl;
891  } else {
892  if(pseudo_res_1 < 0.0049) {
893  double cor = 0.005 / pseudo_res_1;
894  std::cout << "Track " << i << ", Hit " << j << ": Wire covariance too small, rescaling by " << cor;
895  errorScale_ *= cor;
896  pseudo_res_1 *= cor;
897  std::cout << " to " << errorScale_ << std::endl;
898  }
899  }
900  }
901  // finished autoscaling -------------------------------------------------------
902 
903  TEveBox* hit_box;
904  TVector3 move = v*(v*(track_pos-o));
905  hit_box = boxCreator((o + move + hit_u*u), u, v, errorScale_*std::sqrt(hit_cov(0,0)), pseudo_res_1, 0.0105);
906  hit_box->SetMainColor(kYellow);
907  hit_box->SetMainTransparency(0);
908  gEve->AddElement(hit_box);
909 
910  hit_box = boxCreator((o + move - hit_u*u), u, v, errorScale_*std::sqrt(hit_cov(0,0)), pseudo_res_1, 0.0105);
911  hit_box->SetMainColor(kYellow);
912  hit_box->SetMainTransparency(0);
913  gEve->AddElement(hit_box);
914  }
915  // finished drawing wire hits -----------------------------------------------------
916 
917  } // finished drawing hits
918 
919  } // finished looping over MeasurmentOnPlanes
920 
921 
922  prevFi = fi;
923  prevFittedState = fittedState;
924 
925  }
926 
927  }
928 
929  gEve->Redraw3D(resetCam);
930 
931 }
932 
933 
934 
935 
936 TEveBox* EventDisplay::boxCreator(TVector3 o, TVector3 u, TVector3 v, float ud, float vd, float depth) {
937 
938  TEveBox* box = new TEveBox("detPlane_shape");
939  float vertices[24];
940 
941  TVector3 norm = u.Cross(v);
942  u *= (0.5*ud);
943  v *= (0.5*vd);
944  norm *= (0.5*depth);
945 
946  vertices[0] = o(0) - u(0) - v(0) - norm(0);
947  vertices[1] = o(1) - u(1) - v(1) - norm(1);
948  vertices[2] = o(2) - u(2) - v(2) - norm(2);
949 
950  vertices[3] = o(0) + u(0) - v(0) - norm(0);
951  vertices[4] = o(1) + u(1) - v(1) - norm(1);
952  vertices[5] = o(2) + u(2) - v(2) - norm(2);
953 
954  vertices[6] = o(0) + u(0) - v(0) + norm(0);
955  vertices[7] = o(1) + u(1) - v(1) + norm(1);
956  vertices[8] = o(2) + u(2) - v(2) + norm(2);
957 
958  vertices[9] = o(0) - u(0) - v(0) + norm(0);
959  vertices[10] = o(1) - u(1) - v(1) + norm(1);
960  vertices[11] = o(2) - u(2) - v(2) + norm(2);
961 
962  vertices[12] = o(0) - u(0) + v(0) - norm(0);
963  vertices[13] = o(1) - u(1) + v(1) - norm(1);
964  vertices[14] = o(2) - u(2) + v(2) - norm(2);
965 
966  vertices[15] = o(0) + u(0) + v(0) - norm(0);
967  vertices[16] = o(1) + u(1) + v(1) - norm(1);
968  vertices[17] = o(2) + u(2) + v(2) - norm(2);
969 
970  vertices[18] = o(0) + u(0) + v(0) + norm(0);
971  vertices[19] = o(1) + u(1) + v(1) + norm(1);
972  vertices[20] = o(2) + u(2) + v(2) + norm(2);
973 
974  vertices[21] = o(0) - u(0) + v(0) + norm(0);
975  vertices[22] = o(1) - u(1) + v(1) + norm(1);
976  vertices[23] = o(2) - u(2) + v(2) + norm(2);
977 
978 
979  for(int k = 0; k < 24; k += 3) box->SetVertex((k/3), vertices[k], vertices[k+1], vertices[k+2]);
980 
981  return box;
982 
983 }
984 
985 
986 void EventDisplay::makeLines(const StateOnPlane* prevState, const StateOnPlane* state, const AbsTrackRep* rep,
987  const Color_t& color, const Style_t& style, bool drawMarkers, bool drawErrors, double lineWidth, int markerPos)
988 {
989  if (prevState == nullptr || state == nullptr) {
990  std::cerr << "prevState == nullptr || state == nullptr\n";
991  return;
992  }
993 
994  TVector3 pos, dir, oldPos, oldDir;
995  rep->getPosDir(*state, pos, dir);
996  rep->getPosDir(*prevState, oldPos, oldDir);
997 
998  double distA = (pos-oldPos).Mag();
999  double distB = distA;
1000  if ((pos-oldPos)*oldDir < 0)
1001  distA *= -1.;
1002  if ((pos-oldPos)*dir < 0)
1003  distB *= -1.;
1004  TVector3 intermediate1 = oldPos + 0.3 * distA * oldDir;
1005  TVector3 intermediate2 = pos - 0.3 * distB * dir;
1006  TEveStraightLineSet* lineSet = new TEveStraightLineSet;
1007  lineSet->AddLine(oldPos(0), oldPos(1), oldPos(2), intermediate1(0), intermediate1(1), intermediate1(2));
1008  lineSet->AddLine(intermediate1(0), intermediate1(1), intermediate1(2), intermediate2(0), intermediate2(1), intermediate2(2));
1009  lineSet->AddLine(intermediate2(0), intermediate2(1), intermediate2(2), pos(0), pos(1), pos(2));
1010  lineSet->SetLineColor(color);
1011  lineSet->SetLineStyle(style);
1012  lineSet->SetLineWidth(lineWidth);
1013  if (drawMarkers) {
1014  if (markerPos == 0)
1015  lineSet->AddMarker(oldPos(0), oldPos(1), oldPos(2));
1016  else
1017  lineSet->AddMarker(pos(0), pos(1), pos(2));
1018  }
1019 
1020  if (lineWidth > 0)
1021  gEve->AddElement(lineSet);
1022 
1023 
1024  if (drawErrors) {
1025  const MeasuredStateOnPlane* measuredState;
1026  if (markerPos == 0)
1027  measuredState = dynamic_cast<const MeasuredStateOnPlane*>(prevState);
1028  else
1029  measuredState = dynamic_cast<const MeasuredStateOnPlane*>(state);
1030 
1031  if (measuredState != nullptr) {
1032 
1033  // step for evaluate at a distance from the original plane
1034  TVector3 eval;
1035  if (markerPos == 0) {
1036  if (fabs(distA) < 1.) {
1037  distA < 0 ? distA = -1 : distA = 1;
1038  }
1039  eval = 0.2 * distA * oldDir;
1040  }
1041  else {
1042  if (fabs(distB) < 1.) {
1043  distB < 0 ? distB = -1 : distB = 1;
1044  }
1045  eval = -0.2 * distB * dir;
1046  }
1047 
1048 
1049  // get cov at first plane
1050  TMatrixDSym cov;
1051  TVector3 position, direction;
1052  rep->getPosMomCov(*measuredState, position, direction, cov);
1053 
1054  // get eigenvalues & -vectors
1055  TMatrixDSymEigen eigen_values(cov.GetSub(0,2, 0,2));
1056  TVectorT<double> ev = eigen_values.GetEigenValues();
1057  TMatrixT<double> eVec = eigen_values.GetEigenVectors();
1058  TVector3 eVec1, eVec2;
1059  // limit
1060  static const double maxErr = 1000.;
1061  double ev0 = std::min(ev(0), maxErr);
1062  double ev1 = std::min(ev(1), maxErr);
1063  double ev2 = std::min(ev(2), maxErr);
1064 
1065  // get two largest eigenvalues/-vectors
1066  if (ev0 < ev1 && ev0 < ev2) {
1067  eVec1.SetXYZ(eVec(0,1),eVec(1,1),eVec(2,1));
1068  eVec1 *= sqrt(ev1);
1069  eVec2.SetXYZ(eVec(0,2),eVec(1,2),eVec(2,2));
1070  eVec2 *= sqrt(ev2);
1071  }
1072  else if (ev1 < ev0 && ev1 < ev2) {
1073  eVec1.SetXYZ(eVec(0,0),eVec(1,0),eVec(2,0));
1074  eVec1 *= sqrt(ev0);
1075  eVec2.SetXYZ(eVec(0,2),eVec(1,2),eVec(2,2));
1076  eVec2 *= sqrt(ev2);
1077  }
1078  else {
1079  eVec1.SetXYZ(eVec(0,0),eVec(1,0),eVec(2,0));
1080  eVec1 *= sqrt(ev0);
1081  eVec2.SetXYZ(eVec(0,1),eVec(1,1),eVec(2,1));
1082  eVec2 *= sqrt(ev1);
1083  }
1084 
1085  if (eVec1.Cross(eVec2)*eval < 0)
1086  eVec2 *= -1;
1087  //assert(eVec1.Cross(eVec2)*eval > 0);
1088 
1089  const TVector3 oldEVec1(eVec1);
1090  const TVector3 oldEVec2(eVec2);
1091 
1092  const int nEdges = 24;
1093  std::vector<TVector3> vertices;
1094 
1095  vertices.push_back(position);
1096 
1097  // vertices at plane
1098  for (int i=0; i<nEdges; ++i) {
1099  const double angle = 2*TMath::Pi()/nEdges * i;
1100  vertices.push_back(position + cos(angle)*eVec1 + sin(angle)*eVec2);
1101  }
1102 
1103 
1104 
1105  DetPlane* newPlane = new DetPlane(*(measuredState->getPlane()));
1106  newPlane->setO(position + eval);
1107 
1108  MeasuredStateOnPlane stateCopy(*measuredState);
1109  try{
1110  rep->extrapolateToPlane(stateCopy, SharedPlanePtr(newPlane));
1111  }
1112  catch(Exception& e){
1113  std::cerr<<e.what();
1114  return;
1115  }
1116 
1117  // get cov at 2nd plane
1118  rep->getPosMomCov(stateCopy, position, direction, cov);
1119 
1120  // get eigenvalues & -vectors
1121  TMatrixDSymEigen eigen_values2(cov.GetSub(0,2, 0,2));
1122  ev = eigen_values2.GetEigenValues();
1123  eVec = eigen_values2.GetEigenVectors();
1124  // limit
1125  ev0 = std::min(ev(0), maxErr);
1126  ev1 = std::min(ev(1), maxErr);
1127  ev2 = std::min(ev(2), maxErr);
1128 
1129  // get two largest eigenvalues/-vectors
1130  if (ev0 < ev1 && ev0 < ev2) {
1131  eVec1.SetXYZ(eVec(0,1),eVec(1,1),eVec(2,1));
1132  eVec1 *= sqrt(ev1);
1133  eVec2.SetXYZ(eVec(0,2),eVec(1,2),eVec(2,2));
1134  eVec2 *= sqrt(ev2);
1135  }
1136  else if (ev1 < ev0 && ev1 < ev2) {
1137  eVec1.SetXYZ(eVec(0,0),eVec(1,0),eVec(2,0));
1138  eVec1 *= sqrt(ev0);
1139  eVec2.SetXYZ(eVec(0,2),eVec(1,2),eVec(2,2));
1140  eVec2 *= sqrt(ev2);
1141  }
1142  else {
1143  eVec1.SetXYZ(eVec(0,0),eVec(1,0),eVec(2,0));
1144  eVec1 *= sqrt(ev0);
1145  eVec2.SetXYZ(eVec(0,1),eVec(1,1),eVec(2,1));
1146  eVec2 *= sqrt(ev1);
1147  }
1148 
1149  if (eVec1.Cross(eVec2)*eval < 0)
1150  eVec2 *= -1;
1151  //assert(eVec1.Cross(eVec2)*eval > 0);
1152 
1153  if (oldEVec1*eVec1 < 0) {
1154  eVec1 *= -1;
1155  eVec2 *= -1;
1156  }
1157 
1158  // vertices at 2nd plane
1159  double angle0 = eVec1.Angle(oldEVec1);
1160  if (eVec1*(eval.Cross(oldEVec1)) < 0)
1161  angle0 *= -1;
1162  for (int i=0; i<nEdges; ++i) {
1163  const double angle = 2*TMath::Pi()/nEdges * i - angle0;
1164  vertices.push_back(position + cos(angle)*eVec1 + sin(angle)*eVec2);
1165  }
1166 
1167  vertices.push_back(position);
1168 
1169 
1170  TEveTriangleSet* error_shape = new TEveTriangleSet(vertices.size(), nEdges*2);
1171  for(unsigned int k = 0; k < vertices.size(); ++k) {
1172  error_shape->SetVertex(k, vertices[k].X(), vertices[k].Y(), vertices[k].Z());
1173  }
1174 
1175  assert(vertices.size() == 2*nEdges+2);
1176 
1177  int iTri(0);
1178  for (int i=0; i<nEdges; ++i) {
1179  //error_shape->SetTriangle(iTri++, 0, i+1, (i+1)%nEdges+1);
1180  error_shape->SetTriangle(iTri++, i+1, i+1+nEdges, (i+1)%nEdges+1);
1181  error_shape->SetTriangle(iTri++, (i+1)%nEdges+1, i+1+nEdges, (i+1)%nEdges+1+nEdges);
1182  //error_shape->SetTriangle(iTri++, 2*nEdges+1, i+1+nEdges, (i+1)%nEdges+1+nEdges);
1183  }
1184 
1185  //assert(iTri == nEdges*4);
1186 
1187  error_shape->SetMainColor(color);
1188  error_shape->SetMainTransparency(25);
1189  gEve->AddElement(error_shape);
1190  }
1191  }
1192 }
1193 
1194 
1196 
1197  TEveBrowser* browser = gEve->GetBrowser();
1198  browser->StartEmbedding(TRootBrowser::kLeft);
1199 
1200  TGMainFrame* frmMain = new TGMainFrame(gClient->GetRoot(), 1000, 600);
1201  frmMain->SetWindowName("XX GUI");
1202  frmMain->SetCleanup(kDeepCleanup);
1203 
1204  TGLabel* lbl = 0;
1205  TGTextButton* tb = 0;
1207 
1208  TGHorizontalFrame* hf = new TGHorizontalFrame(frmMain); {
1209  // evt number entry
1210  lbl = new TGLabel(hf, "Go to event: ");
1211  hf->AddFrame(lbl);
1212  guiEvent = new TGNumberEntry(hf, 0, 9,999, TGNumberFormat::kNESInteger,
1213  TGNumberFormat::kNEANonNegative,
1214  TGNumberFormat::kNELLimitMinMax,
1215  0, 99999);
1216  hf->AddFrame(guiEvent);
1217  guiEvent->Connect("ValueSet(Long_t)", "genfit::EventDisplay", fh, "guiGoto()");
1218 
1219  // redraw button
1220  tb = new TGTextButton(hf, "Redraw Event");
1221  hf->AddFrame(tb);
1222  tb->Connect("Clicked()", "genfit::EventDisplay", fh, "guiGoto()");
1223  }
1224  frmMain->AddFrame(hf);
1225 
1226  // draw options
1227  hf = new TGHorizontalFrame(frmMain); {
1228  lbl = new TGLabel(hf, "\n Draw Options");
1229  hf->AddFrame(lbl);
1230  }
1231  frmMain->AddFrame(hf);
1232 
1233  hf = new TGHorizontalFrame(frmMain); {
1234  guiDrawGeometry_ = new TGCheckButton(hf, "Draw geometry");
1235  if(drawGeometry_) guiDrawGeometry_->Toggle();
1236  hf->AddFrame(guiDrawGeometry_);
1237  guiDrawGeometry_->Connect("Toggled(Bool_t)", "genfit::EventDisplay", fh, "guiSetDrawParams()");
1238  }
1239  frmMain->AddFrame(hf);
1240 
1241  hf = new TGHorizontalFrame(frmMain); {
1242  guiDrawDetectors_ = new TGCheckButton(hf, "Draw detectors");
1243  if(drawDetectors_) guiDrawDetectors_->Toggle();
1244  hf->AddFrame(guiDrawDetectors_);
1245  guiDrawDetectors_->Connect("Toggled(Bool_t)", "genfit::EventDisplay", fh, "guiSetDrawParams()");
1246  }
1247  frmMain->AddFrame(hf);
1248 
1249  hf = new TGHorizontalFrame(frmMain); {
1250  guiDrawHits_ = new TGCheckButton(hf, "Draw hits");
1251  if(drawHits_) guiDrawHits_->Toggle();
1252  hf->AddFrame(guiDrawHits_);
1253  guiDrawHits_->Connect("Toggled(Bool_t)", "genfit::EventDisplay", fh, "guiSetDrawParams()");
1254  }
1255  frmMain->AddFrame(hf);
1256 
1257 
1258 
1259  hf = new TGHorizontalFrame(frmMain); {
1260  guiDrawPlanes_ = new TGCheckButton(hf, "Draw planes");
1261  if(drawPlanes_) guiDrawPlanes_->Toggle();
1262  hf->AddFrame(guiDrawPlanes_);
1263  guiDrawPlanes_->Connect("Toggled(Bool_t)", "genfit::EventDisplay", fh, "guiSetDrawParams()");
1264  }
1265  frmMain->AddFrame(hf);
1266 
1267  hf = new TGHorizontalFrame(frmMain); {
1268  guiDrawTrackMarkers_ = new TGCheckButton(hf, "Draw track markers");
1270  hf->AddFrame(guiDrawTrackMarkers_);
1271  guiDrawTrackMarkers_->Connect("Toggled(Bool_t)", "genfit::EventDisplay", fh, "guiSetDrawParams()");
1272  }
1273  frmMain->AddFrame(hf);
1274 
1275 
1276  hf = new TGHorizontalFrame(frmMain); {
1277  guiDrawTrack_ = new TGCheckButton(hf, "Draw track");
1278  if(drawTrack_) guiDrawTrack_->Toggle();
1279  hf->AddFrame(guiDrawTrack_);
1280  guiDrawTrack_->Connect("Toggled(Bool_t)", "genfit::EventDisplay", fh, "guiSetDrawParams()");
1281  }
1282  frmMain->AddFrame(hf);
1283 
1284  hf = new TGHorizontalFrame(frmMain); {
1285  guiDrawRefTrack_ = new TGCheckButton(hf, "Draw reference track");
1286  if(drawRefTrack_) guiDrawRefTrack_->Toggle();
1287  hf->AddFrame(guiDrawRefTrack_);
1288  guiDrawRefTrack_->Connect("Toggled(Bool_t)", "genfit::EventDisplay", fh, "guiSetDrawParams()");
1289  }
1290  frmMain->AddFrame(hf);
1291 
1292  hf = new TGHorizontalFrame(frmMain); {
1293  guiDrawErrors_ = new TGCheckButton(hf, "Draw track errors");
1294  if(drawErrors_) guiDrawErrors_->Toggle();
1295  hf->AddFrame(guiDrawErrors_);
1296  guiDrawErrors_->Connect("Toggled(Bool_t)", "genfit::EventDisplay", fh, "guiSetDrawParams()");
1297  }
1298  frmMain->AddFrame(hf);
1299 
1300  hf = new TGHorizontalFrame(frmMain); {
1301  guiDrawForward_ = new TGCheckButton(hf, "Draw forward fit");
1302  if(drawForward_) guiDrawForward_->Toggle();
1303  hf->AddFrame(guiDrawForward_);
1304  guiDrawForward_->Connect("Toggled(Bool_t)", "genfit::EventDisplay", fh, "guiSetDrawParams()");
1305  }
1306  frmMain->AddFrame(hf);
1307 
1308  hf = new TGHorizontalFrame(frmMain); {
1309  guiDrawBackward_ = new TGCheckButton(hf, "Draw backward fit");
1310  if(drawBackward_) guiDrawBackward_->Toggle();
1311  hf->AddFrame(guiDrawBackward_);
1312  guiDrawBackward_->Connect("Toggled(Bool_t)", "genfit::EventDisplay", fh, "guiSetDrawParams()");
1313  }
1314  frmMain->AddFrame(hf);
1315 
1316 
1317  hf = new TGHorizontalFrame(frmMain); {
1318  guiDrawAutoScale_ = new TGCheckButton(hf, "Auto-scale errors");
1319  if(drawAutoScale_) guiDrawAutoScale_->Toggle();
1320  hf->AddFrame(guiDrawAutoScale_);
1321  guiDrawAutoScale_->Connect("Toggled(Bool_t)", "genfit::EventDisplay", fh, "guiSetDrawParams()");
1322  }
1323  frmMain->AddFrame(hf);
1324 
1325  hf = new TGHorizontalFrame(frmMain); {
1326  guiDrawScaleMan_ = new TGCheckButton(hf, "Manually scale errors");
1327  if(drawScaleMan_) guiDrawScaleMan_->Toggle();
1328  hf->AddFrame(guiDrawScaleMan_);
1329  guiDrawScaleMan_->Connect("Toggled(Bool_t)", "genfit::EventDisplay", fh, "guiSetDrawParams()");
1330  }
1331  frmMain->AddFrame(hf);
1332 
1333  hf = new TGHorizontalFrame(frmMain); {
1334  guiErrorScale_ = new TGNumberEntry(hf, errorScale_, 6,999, TGNumberFormat::kNESReal,
1335  TGNumberFormat::kNEANonNegative,
1336  TGNumberFormat::kNELLimitMinMax,
1337  1.E-4, 1.E5);
1338  hf->AddFrame(guiErrorScale_);
1339  guiErrorScale_->Connect("ValueSet(Long_t)", "genfit::EventDisplay", fh, "guiSetDrawParams()");
1340  lbl = new TGLabel(hf, "Error scale");
1341  hf->AddFrame(lbl);
1342  }
1343  frmMain->AddFrame(hf);
1344 
1345 
1346 
1347  hf = new TGHorizontalFrame(frmMain); {
1348  lbl = new TGLabel(hf, "\n TrackRep options");
1349  hf->AddFrame(lbl);
1350  }
1351  frmMain->AddFrame(hf);
1352 
1353  hf = new TGHorizontalFrame(frmMain); {
1354  guiDrawCardinalRep_ = new TGCheckButton(hf, "Draw cardinal rep");
1355  if(drawCardinalRep_) guiDrawCardinalRep_->Toggle();
1356  hf->AddFrame(guiDrawCardinalRep_);
1357  guiDrawCardinalRep_->Connect("Toggled(Bool_t)", "genfit::EventDisplay", fh, "guiSetDrawParams()");
1358  }
1359  frmMain->AddFrame(hf);
1360 
1361  hf = new TGHorizontalFrame(frmMain); {
1362  guiRepId_ = new TGNumberEntry(hf, repId_, 6,999, TGNumberFormat::kNESInteger,
1363  TGNumberFormat::kNEANonNegative,
1364  TGNumberFormat::kNELLimitMinMax,
1365  0, 99);
1366  hf->AddFrame(guiRepId_);
1367  guiRepId_->Connect("ValueSet(Long_t)", "genfit::EventDisplay", fh, "guiSetDrawParams()");
1368  lbl = new TGLabel(hf, "Else draw rep with id");
1369  hf->AddFrame(lbl);
1370  }
1371  frmMain->AddFrame(hf);
1372 
1373  hf = new TGHorizontalFrame(frmMain); {
1374  guiDrawAllTracks_ = new TGCheckButton(hf, "Draw all tracks");
1375  if(drawAllTracks_) guiDrawAllTracks_->Toggle();
1376  hf->AddFrame(guiDrawAllTracks_);
1377  guiDrawAllTracks_->Connect("Toggled(Bool_t)", "genfit::EventDisplay", fh, "guiSetDrawParams()");
1378  }
1379  frmMain->AddFrame(hf);
1380 
1381  hf = new TGHorizontalFrame(frmMain); {
1382  guiTrackId_ = new TGNumberEntry(hf, trackId_, 6,999, TGNumberFormat::kNESInteger,
1383  TGNumberFormat::kNEANonNegative,
1384  TGNumberFormat::kNELLimitMinMax,
1385  0, 99);
1386  hf->AddFrame(guiTrackId_);
1387  guiTrackId_->Connect("ValueSet(Long_t)", "genfit::EventDisplay", fh, "guiSetDrawParams()");
1388  lbl = new TGLabel(hf, "Else draw track nr. ");
1389  hf->AddFrame(lbl);
1390  }
1391  frmMain->AddFrame(hf);
1392 
1393 
1394 
1395  frmMain->MapSubwindows();
1396  frmMain->Resize();
1397  frmMain->MapWindow();
1398 
1399  browser->StopEmbedding();
1400  browser->SetTabTitle("Draw Control", 0);
1401 
1402 
1403  browser->StartEmbedding(TRootBrowser::kLeft);
1404  TGMainFrame* frmMain2 = new TGMainFrame(gClient->GetRoot(), 1000, 600);
1405  frmMain2->SetWindowName("XX GUI");
1406  frmMain2->SetCleanup(kDeepCleanup);
1407 
1408  hf = new TGHorizontalFrame(frmMain2); {
1409  // evt number entry
1410  lbl = new TGLabel(hf, "Go to event: ");
1411  hf->AddFrame(lbl);
1412  guiEvent2 = new TGNumberEntry(hf, 0, 9,999, TGNumberFormat::kNESInteger,
1413  TGNumberFormat::kNEANonNegative,
1414  TGNumberFormat::kNELLimitMinMax,
1415  0, 99999);
1416  hf->AddFrame(guiEvent2);
1417  guiEvent2->Connect("ValueSet(Long_t)", "genfit::EventDisplay", fh, "guiGoto2()");
1418 
1419  // redraw button
1420  tb = new TGTextButton(hf, "Redraw Event");
1421  hf->AddFrame(tb);
1422  tb->Connect("Clicked()", "genfit::EventDisplay", fh, "guiGoto()");
1423  }
1424  frmMain2->AddFrame(hf);
1425 
1426  hf = new TGHorizontalFrame(frmMain2); {
1427  lbl = new TGLabel(hf, "\n Fitting options");
1428  hf->AddFrame(lbl);
1429  }
1430  frmMain2->AddFrame(hf);
1431 
1432  hf = new TGHorizontalFrame(frmMain2); {
1433  guiRefit_ = new TGCheckButton(hf, "Refit");
1434  if(refit_) guiRefit_->Toggle();
1435  hf->AddFrame(guiRefit_);
1436  guiRefit_->Connect("Toggled(Bool_t)", "genfit::EventDisplay", fh, "guiSetDrawParams()");
1437  }
1438  frmMain2->AddFrame(hf);
1439 
1440  hf = new TGHorizontalFrame(frmMain2); {
1441  guiDebugLvl_ = new TGNumberEntry(hf, debugLvl_, 6,999, TGNumberFormat::kNESInteger,
1442  TGNumberFormat::kNEANonNegative,
1443  TGNumberFormat::kNELLimitMinMax,
1444  0, 999);
1445  hf->AddFrame(guiDebugLvl_);
1446  guiDebugLvl_->Connect("ValueSet(Long_t)", "genfit::EventDisplay", fh, "guiSetDrawParams()");
1447  lbl = new TGLabel(hf, "debug level");
1448  hf->AddFrame(lbl);
1449  }
1450  frmMain2->AddFrame(hf);
1451 
1452  hf = new TGHorizontalFrame(frmMain2); {
1453  guiFitterId_ = new TGButtonGroup(hf,"Fitter type:");
1454  guiFitterId_->Connect("Clicked(Int_t)","genfit::EventDisplay", fh, "guiSelectFitterId(int)");
1455  hf->AddFrame(guiFitterId_, new TGLayoutHints(kLHintsTop));
1456  TGRadioButton* fitterId_button = new TGRadioButton(guiFitterId_, "Simple Kalman");
1457  new TGRadioButton(guiFitterId_, "Reference Kalman");
1458  new TGRadioButton(guiFitterId_, "DAF w/ simple Kalman");
1459  new TGRadioButton(guiFitterId_, "DAF w/ reference Kalman");
1460  fitterId_button->SetDown(true, false);
1461  guiFitterId_->Show();
1462  }
1463  frmMain2->AddFrame(hf);
1464 
1465  hf = new TGHorizontalFrame(frmMain2); {
1466  guiMmHandling_ = new TGButtonGroup(hf,"Multiple measurement handling in Kalman:");
1467  guiMmHandling_->Connect("Clicked(Int_t)","genfit::EventDisplay", fh, "guiSelectMmHandling(int)");
1468  hf->AddFrame(guiMmHandling_, new TGLayoutHints(kLHintsTop));
1469  TGRadioButton* mmHandling_button = new TGRadioButton(guiMmHandling_, "weighted average");
1470  new TGRadioButton(guiMmHandling_, "unweighted average");
1471  new TGRadioButton(guiMmHandling_, "weighted, closest to reference");
1472  new TGRadioButton(guiMmHandling_, "unweighted, closest to reference");
1473  new TGRadioButton(guiMmHandling_, "weighted, closest to prediction");
1474  new TGRadioButton(guiMmHandling_, "unweighted, closest to prediction");
1475  new TGRadioButton(guiMmHandling_, "weighted, closest to reference for WireMeasurements, weighted average else");
1476  new TGRadioButton(guiMmHandling_, "unweighted, closest to reference for WireMeasurements, unweighted average else");
1477  new TGRadioButton(guiMmHandling_, "weighted, closest to prediction for WireMeasurements, weighted average else");
1478  new TGRadioButton(guiMmHandling_, "unweighted, closest to prediction for WireMeasurements, unweighted average else");
1479  mmHandling_button->SetDown(true, false);
1480  guiMmHandling_->Show();
1481  }
1482  frmMain2->AddFrame(hf);
1483 
1484  hf = new TGHorizontalFrame(frmMain2); {
1485  guiSquareRootFormalism_ = new TGCheckButton(hf, "Use square root formalism (simple Kalman/simple DAF)");
1487  hf->AddFrame(guiSquareRootFormalism_);
1488  guiSquareRootFormalism_->Connect("Toggled(Bool_t)", "genfit::EventDisplay", fh, "guiSetDrawParams()");
1489  }
1490  frmMain2->AddFrame(hf);
1491 
1492  hf = new TGHorizontalFrame(frmMain2); {
1493  guiDPVal_ = new TGNumberEntry(hf, dPVal_, 6,9999, TGNumberFormat::kNESReal,
1494  TGNumberFormat::kNEANonNegative,
1495  TGNumberFormat::kNELLimitMinMax,
1496  0, 999);
1497  hf->AddFrame(guiDPVal_);
1498  guiDPVal_->Connect("ValueSet(Long_t)", "genfit::EventDisplay", fh, "guiSetDrawParams()");
1499  lbl = new TGLabel(hf, "delta pVal (convergence criterium)");
1500  hf->AddFrame(lbl);
1501  }
1502  frmMain2->AddFrame(hf);
1503 
1504  hf = new TGHorizontalFrame(frmMain2); {
1505  guiRelChi2_ = new TGNumberEntry(hf, dRelChi2_, 6,9999, TGNumberFormat::kNESReal,
1506  TGNumberFormat::kNEANonNegative,
1507  TGNumberFormat::kNELLimitMinMax,
1508  0, 999);
1509  hf->AddFrame(guiRelChi2_);
1510  guiRelChi2_->Connect("ValueSet(Long_t)", "genfit::EventDisplay", fh, "guiSetDrawParams()");
1511  lbl = new TGLabel(hf, "rel chi^2 change (non-convergence criterium)");
1512  hf->AddFrame(lbl);
1513  }
1514  frmMain2->AddFrame(hf);
1515 
1516  hf = new TGHorizontalFrame(frmMain2); {
1517  guiDChi2Ref_ = new TGNumberEntry(hf, dChi2Ref_, 6,9999, TGNumberFormat::kNESReal,
1518  TGNumberFormat::kNEANonNegative,
1519  TGNumberFormat::kNELLimitMinMax,
1520  0, 999);
1521  hf->AddFrame(guiDChi2Ref_);
1522  guiDChi2Ref_->Connect("ValueSet(Long_t)", "genfit::EventDisplay", fh, "guiSetDrawParams()");
1523  lbl = new TGLabel(hf, "min chi^2 change for re-calculating reference track (Ref Kalman)");
1524  hf->AddFrame(lbl);
1525  }
1526  frmMain2->AddFrame(hf);
1527 
1528  hf = new TGHorizontalFrame(frmMain2); {
1529  guiNMinIter_ = new TGNumberEntry(hf, nMinIter_, 6,999, TGNumberFormat::kNESInteger,
1530  TGNumberFormat::kNEANonNegative,
1531  TGNumberFormat::kNELLimitMinMax,
1532  1, 100);
1533  hf->AddFrame(guiNMinIter_);
1534  guiNMinIter_->Connect("ValueSet(Long_t)", "genfit::EventDisplay", fh, "guiSetDrawParams()");
1535  lbl = new TGLabel(hf, "Minimum nr of iterations");
1536  hf->AddFrame(lbl);
1537  }
1538  frmMain2->AddFrame(hf);
1539 
1540  hf = new TGHorizontalFrame(frmMain2); {
1541  guiNMaxIter_ = new TGNumberEntry(hf, nMaxIter_, 6,999, TGNumberFormat::kNESInteger,
1542  TGNumberFormat::kNEANonNegative,
1543  TGNumberFormat::kNELLimitMinMax,
1544  1, 100);
1545  hf->AddFrame(guiNMaxIter_);
1546  guiNMaxIter_->Connect("ValueSet(Long_t)", "genfit::EventDisplay", fh, "guiSetDrawParams()");
1547  lbl = new TGLabel(hf, "Maximum nr of iterations");
1548  hf->AddFrame(lbl);
1549  }
1550  frmMain2->AddFrame(hf);
1551 
1552  hf = new TGHorizontalFrame(frmMain2); {
1553  guiNMaxFailed_ = new TGNumberEntry(hf, nMaxFailed_, 6,999, TGNumberFormat::kNESInteger,
1554  TGNumberFormat::kNEAAnyNumber,
1555  TGNumberFormat::kNELLimitMinMax,
1556  -1, 1000);
1557  hf->AddFrame(guiNMaxFailed_);
1558  guiNMaxFailed_->Connect("ValueSet(Long_t)", "genfit::EventDisplay", fh, "guiSetDrawParams()");
1559  lbl = new TGLabel(hf, "Maximum nr of failed hits");
1560  hf->AddFrame(lbl);
1561  }
1562  frmMain2->AddFrame(hf);
1563 
1564 
1565  hf = new TGHorizontalFrame(frmMain2); {
1566  guiResort_ = new TGCheckButton(hf, "Resort track");
1567  if(resort_) guiResort_->Toggle();
1568  hf->AddFrame(guiResort_);
1569  guiResort_->Connect("Toggled(Bool_t)", "genfit::EventDisplay", fh, "guiSetDrawParams()");
1570  }
1571  frmMain2->AddFrame(hf);
1572 
1573 
1574 
1575 
1576  frmMain2->MapSubwindows();
1577  frmMain2->Resize();
1578  frmMain2->MapWindow();
1579 
1580  browser->StopEmbedding();
1581  browser->SetTabTitle("Refit Control", 0);
1582 }
1583 
1584 
1586  Long_t n = guiEvent->GetNumberEntry()->GetIntNumber();
1587  guiEvent2->SetIntNumber(n);
1588  gotoEvent(n);
1589 }
1590 
1592  Long_t n = guiEvent2->GetNumberEntry()->GetIntNumber();
1593  guiEvent->SetIntNumber(n);
1594  gotoEvent(n);
1595 }
1596 
1597 
1599 
1600  drawGeometry_ = guiDrawGeometry_->IsOn();
1602  drawHits_ = guiDrawHits_->IsOn();
1603  drawErrors_ = guiDrawErrors_->IsOn();
1604 
1605  drawPlanes_ = guiDrawPlanes_->IsOn();
1607  drawTrack_ = guiDrawTrack_->IsOn();
1608  drawRefTrack_ = guiDrawRefTrack_->IsOn();
1609  drawForward_ = guiDrawForward_->IsOn();
1610  drawBackward_ = guiDrawBackward_->IsOn();
1611 
1613  drawScaleMan_ = guiDrawScaleMan_->IsOn();
1614 
1615  errorScale_ = guiErrorScale_->GetNumberEntry()->GetNumber();
1616 
1618  repId_ = guiRepId_->GetNumberEntry()->GetNumber();
1619 
1621  trackId_ = guiTrackId_->GetNumberEntry()->GetNumber();
1622 
1623 
1624  refit_ = guiRefit_->IsOn();
1625  debugLvl_ = guiDebugLvl_->GetNumberEntry()->GetNumber();
1626 
1628  dPVal_ = guiDPVal_->GetNumberEntry()->GetNumber();
1629  dRelChi2_ = guiRelChi2_->GetNumberEntry()->GetNumber();
1630  dChi2Ref_ = guiDChi2Ref_->GetNumberEntry()->GetNumber();
1631  nMinIter_ = guiNMinIter_->GetNumberEntry()->GetNumber();
1632  nMaxIter_ = guiNMaxIter_->GetNumberEntry()->GetNumber();
1633  nMaxFailed_ = guiNMaxFailed_->GetNumberEntry()->GetNumber();
1634  resort_ = guiResort_->IsOn();
1635 
1637 }
1638 
1639 
1641  fitterId_ = eFitterType(val-1);
1643 }
1644 
1648 }
1649 
1650 
1651 } // end of namespace genfit