BBQ
vistpc.cxx
Go to the documentation of this file.
1 #include "vistpc.h"
2 
3 // C++ STL
4 
5 #include <iostream>
6 #include <string>
7 #include <sstream>
8 #include <iomanip>
9 
10 #include <cmath>
11 
12 #include <map>
13 
14 // ROOT
15 
16 #include <TSystem.h>
17 #include <TColor.h>
18 #include <TList.h>
19 #include <TStyle.h>
20 #include <TRandom.h>
21 #include <TMath.h>
22 
23 #include <TEveBoxSet.h>
24 #include <TEveBrowser.h>
25 #include <TEveCompound.h>
26 #include <TEveGeoNode.h>
27 #include <TEveManager.h>
28 #include <TEveRGBAPalette.h>
29 #include <TEvePointSet.h>
30 #include <TEveQuadSet.h>
31 #include <TEveStraightLineSet.h>
32 #include <TEveTrack.h>
33 #include <TEveTrackPropagator.h>
34 #include <TEveVSDStructs.h>
35 
36 #include <TGeometry.h>
37 #include <TGeoManager.h>
38 #include <TGeoMaterial.h>
39 #include <TGeoMatrix.h>
40 #include <TGeoTube.h>
41 #include <TGeoXtru.h>
42 
43 #include <TGListBox.h>
44 #include <TGListTree.h>
45 #include <TGMenu.h>
46 
47 // GEAR
48 
49 #include <gearimpl/Util.h>
50 #include <gearxml/GearXML.h>
51 #include <gear/GearMgr.h>
52 #include <gear/GEAR.h>
53 #include <gear/TPCParameters.h>
54 
55 // LCIO
56 
57 #include "lcio.h"
58 
59 #include "EVENT/LCIO.h"
60 #include "IO/LCReader.h"
61 #include "IO/LCWriter.h"
62 #include "IMPL/LCEventImpl.h"
63 #include "IMPL/LCCollectionVec.h"
64 #include "EVENT/Track.h"
65 #include "EVENT/TrackerData.h"
66 #include "EVENT/TrackerHit.h"
67 #include "EVENT/TrackerPulse.h"
68 #include "Exceptions.h"
69 
70 using namespace lcio;
71 using namespace gear;
72 
73 //==============================================================================
74 // Constructor / Destructor
75 //------------------------------------------------------------------------------
76 
77 
78 VisTPC::VisTPC(gear::GearMgr * aGearMgr) :
79  debug(1),
80  readoutFrequency(40.),
81  driftVelocity(79.),
82  maxPoints(0)
83 {
84  // to avoid code duplication this code is in a helper function
85  updateGearMgr( aGearMgr );
86 
87  TStyle* style = new TStyle();
88  TGeoManager* geom = new TGeoManager("DetectorGeometry", "detector geometry");
89 
90  //--- define some materials
91  materials["Vacuum"] = new TGeoMaterial("Vacuum", 0,0,0);
92  materials["Al"] = new TGeoMaterial("Al", 26.98,13,2.7);
93 
94  //--- define some media
95  media["Vacuum"] = new TGeoMedium("Vacuum", 1, materials["Vacuum"]);
96  media["Al"] = new TGeoMedium("Aluminium", 2, materials["Al"]);
97 
98  // default options
99  options["module.parallelBorders"] = 0;
100  options["module.drawPadsByDefault"] = kFALSE;
101  options["module.drawOutlineByDefault"] = kTRUE;
102 }
103 
104 //==============================================================================
105 // Methods (Alphabetical order)
106 //------------------------------------------------------------------------------
107 
108 void VisTPC::drawCircularPolygon(TEveStraightLineSet* ls, float r, int nDivisions, float z) {
109  drawCircularPolygon(ls, r, 0, 2 * TMath::Pi(), nDivisions, z);
110 }
111 
112 void VisTPC::drawCircularPolygon(TEveStraightLineSet* ls, float r, float phi_min, float phi_max, int nDivisions, float z) {
113 
114  // Checks of the arguments
115 
116  if (nDivisions == 0) {
117  return;
118  }
119 
120  if (r == 0) {
121  return;
122  }
123 
124  // Implementation 1
125  /*
126  float phi = phi_min;
127  float dPhi = (phi_max - phi_min) / nDivisions;
128 
129  while (phi + dPhi <= phi_max) {
130  ls->AddLine(r*cos(phi), r*sin(phi), z,
131  r*cos(phi+dPhi), r*sin(phi+dPhi), z);
132 
133  phi += dPhi;
134  }
135  */
136 
137  // Implementation 2
138 
139  float dPhi = (phi_max - phi_min) / nDivisions;
140  int j = 0;
141 
142  while (j < nDivisions) {
143  ls->AddLine(r*cos(dPhi*j + phi_min), r*sin(dPhi*j + phi_min), z,
144  r*cos(dPhi*(j+1) + phi_min), r*sin(dPhi*(j+1) + phi_min), z);
145 
146  ++j;
147  }
148 }
149 
150 void VisTPC::drawEvent(EVENT::LCEvent* event, TList &selectedEntries, TEveElement* parent, const char* name) {
151  std::vector<std::string> entries;
152 
153  TIter next(&selectedEntries);
154  while (TGTextLBEntry* entry = (TGTextLBEntry*) next()) {
155  entries.push_back(entry->GetTitle());
156  }
157 
158  drawEvent(event, entries, parent, name);
159 }
160 
161 void VisTPC::drawEvent(EVENT::LCEvent* event, std::vector<std::string> &selectedEntries, TEveElement* parent, const char* name) {
162  TEveElementList *eveNode = new TEveElementList(name);
163  TEveElement *eveChild = NULL;
164  TGListTreeItem *listTreeItem = 0;
165 
166  LCCollectionVec *collection = 0;
167 
168  //
169 
170  eveNode->SetRnrSelfChildren(kFALSE, kFALSE);
171 
172  //
173 
174  for (
175  std::vector<std::string>::iterator it = selectedEntries.begin();
176  it != selectedEntries.end();
177  ++it
178  ) {
179 
180  try {
181 
182  //std::cout << "Trying collection \"" << *it
183  // << "\"." << std::endl;
184 
185  collection = dynamic_cast<LCCollectionVec*>(event->getCollection(*it));
186 
187  //std::cout << "Going to draw " << *it << " "
188  // << "of type "
189  // << collection->getTypeName()
190  // << "("
191  // << gBBQ->getCollectionType(collection->getTypeName())
192  // << ")."
193  // << std::endl;
194 
195  } catch (DataNotAvailableException &) {
196 
197  std::cout << "Collection \"" << *it
198  << "\" not available" << std::endl;
199 
200  continue;
201 
202  }
203 
204  switch (
205  getCollectionType(collection->getTypeName())
206  ) {
207  case kUNDEFINEDTYPE:
208  break;
209 
210  case kHIT:
211  eveChild = drawHits(collection);
212  eveChild->SetElementName(it->c_str());
213 
214  if (parent) {
215  parent->AddElement(eveChild);
216  } else {
217  gEve->AddElement(eveChild);
218  }
219 
220  break;
221 
222  case kPULSE:
223  eveChild = drawPulses(collection);
224  eveChild->SetElementName(it->c_str());
225  eveChild->SetRnrSelf(kFALSE);
226 
227  if (parent) {
228  parent->AddElement(eveChild);
229  } else {
230  gEve->AddElement(eveChild);
231  }
232 
233  break;
234 
235  case kTRACK:
236  eveChild = drawTracks(collection, parent);
237  eveChild->SetElementName(it->c_str());
238 
239  // Rename "All hits" to "<collection name> - All hits"
240  // "All hits" contains all the hits of all the tracks in the
241  // current collection. This is done inside drawTracks().
242 
243  try {
244 
245  // This can be replaced by (UNTESTED!)
246  // listTreeItem = ListTree->FindItemByObj(ListTree->GetFirstItem(), eveChild)->GetNextSibling
247 
248  listTreeItem = gEve->GetListTree()->FindItemByPathname("/Event/All hits");
249 
250  if (listTreeItem) {
251  eveChild = static_cast<TEveElement*>( listTreeItem->GetUserData() );
252 
253  it->append(" - All hits");
254  eveChild->SetElementName(it->c_str());
255  }
256 
257  } catch (...) {
258  //
259  }
260 
261  break;
262 
263  default:
264  break;
265  }
266 
267  }
268 }
269 
270 void VisTPC::drawHit(EVENT::TrackerHit* hit, TEvePointSet* parent, int wantTooltip) {
271 
272  if (!parent)
273  throw "VisTPC::drawHit() : parent can't be null.";
274 
275  TEvePointSet *point = 0;
276 
277  const double *pos = hit->getPosition();
278  const FloatVec &covariance = hit->getCovMatrix();
279 
280  double position[3];
281 
282  switch (tpcParameters->getCoordinateType())
283  {
284  case PadRowLayout2D::CARTESIAN:
285  position[0] = pos[0];
286  position[1] = pos[1];
287  position[2] = pos[2];
288  break;
289 
290  case PadRowLayout2D::POLAR:
291  position[0] = pos[0]*cos(pos[1]);
292  position[1] = pos[0]*sin(pos[1]);
293  position[2] = pos[2];
294  break;
295  default:
296  throw "Unknown coordinate type.";
297  }
298 
299  std::stringstream tooltip;
300 
301  if (wantTooltip) {
302 
303  tooltip
304  << "Position [mm]: ("
305  << position[0] << ", "
306  << position[1] << ", "
307  << position[2] << ")"
308  << std::endl
309  << "Covariance: ("
310  << covariance[0] << ", "
311  << covariance[1] << ", "
312  << covariance[2] << ")"
313  << std::endl
314  << "Energy [GeV]: " << hit->getEDep() << std::endl
315  << "Time [ns]: " << hit->getTime() << std::endl
316  << "Type: " << hit->getType() << std::endl
317  << "Quality: " << hit->getQuality() << std::endl;
318 
319  point = new TEvePointSet();
320  point->SetOwnIds(kTRUE);
321  point->SetMarkerSize(0.2);
322  point->SetMarkerStyle(2);
323  point->SetMarkerColor(kMagenta);
324  point->SetElementTitle(tooltip.str().c_str());
325 
326  parent->AddElement(point);
327 
328  parent = point;
329 
330  }
331 
332  //
333 
334  parent->SetNextPoint(position[0], position[1], position[2]);
335 
336  // Add one projected to the end cap
337 
338  parent->SetNextPoint(position[0], position[1], maxDriftLength + 1);
339 }
340 
341 TEveElement* VisTPC::drawHits(IMPL::LCCollectionVec* hits, int wantTooltip) {
342 
343  TEvePointSet* ps = new TEvePointSet();
344  TrackerHit* th;
345  const double* pos = NULL;
346 
347  //===========================================================================
348 
349  ps->SetOwnIds(kTRUE);
350  ps->SetMarkerColor(kMagenta);
351  ps->SetMarkerSize(0.2);
352  ps->SetMarkerStyle(2);
353 
354  int j = 0;
355  for (
356  LCCollectionVec::iterator inputHitsIter = hits->begin();
357  inputHitsIter < hits->end();
358  inputHitsIter++
359  ) {
360  if (maxPoints && j++ > maxPoints) {
361  break;
362  }
363 
364  th = dynamic_cast<TrackerHit *>( *inputHitsIter );
365 
366  drawHit(th, ps, wantTooltip);
367  }
368 
369  return ps;
370 }
371 
372 TEveElement* VisTPC::drawHits(const EVENT::TrackerHitVec& hits, int wantTooltip) {
373 
374  TEvePointSet* ps = new TEvePointSet();
375  TrackerHit* th;
376  const double* pos = NULL;
377 
378  //===========================================================================
379 
380  ps->SetOwnIds(kTRUE);
381  ps->SetMarkerColor(kMagenta);
382  ps->SetMarkerSize(0.2);
383  ps->SetMarkerStyle(2);
384 
385  int j = 0;
386  for (
387  TrackerHitVec::const_iterator inputHitsIter = hits.begin();
388  inputHitsIter != hits.end();
389  inputHitsIter++
390  ) {
391  if (maxPoints && j++ > maxPoints) {
392  break;
393  }
394 
395  th = *inputHitsIter;
396 
397  drawHit(th, ps, wantTooltip);
398  }
399 
400  return ps;
401 }
402 
403 void VisTPC::drawModule(TPCModule * aModule, TEveElement* parent) {
404 
405  const std::vector<double>& extent = aModule->getLocalPadLayout().getPlaneExtent();
406  double border = aModule->getBorderWidth();
407 
408  // Cartesian: [x_min, x_max, y_min, y_max]
409  // Polar : [r_min, r_max, phi_min, phi_max]
410 
411  float x1_min = extent[0];
412  float x1_max = extent[1];
413  float x2_min = extent[2];
414  float x2_max = extent[3];
415 
416  float r_min, phi_min, r_max, phi_max = 0.;
417 
418  float pos_z = 0;
419  int nDivisions = 100;
420 
421  TEveStraightLineSet* module_outline = new TEveStraightLineSet("Outline");
422  std::stringstream tooltip;
423 
424  //===========================================================================
425  // Draw outline
426 
427  module_outline->SetLineColor(kBlue);
428  module_outline->SetRnrSelf(options["module.drawOutlineByDefault"]);
429 
430  switch (aModule->getLocalPadLayout().getCoordinateType()) {
431  case PadRowLayout2D::CARTESIAN:
432 
433  x1_min -= border;
434  x1_max += border;
435  x2_min -= border;
436  x2_max += border;
437 
438  module_outline->AddLine(x1_min, x2_min, pos_z,
439  x1_min, x2_max, pos_z);
440 
441  module_outline->AddLine(x1_max, x2_min, pos_z,
442  x1_max, x2_max, pos_z);
443 
444  module_outline->AddLine(x1_min, x2_min, pos_z,
445  x1_max, x2_min, pos_z);
446 
447  module_outline->AddLine(x1_min, x2_max, pos_z,
448  x1_max, x2_max, pos_z);
449  break;
450  case PadRowLayout2D::POLAR:
451 
452  x1_min -= border;
453  x1_max += border;
454 
455  // When not a full circle
456 
457  if (fabs((x2_max - x2_min) - 2*TMath::Pi()) > 1e-5) {
458 
459  if (!options["module.parallelBorders"]) {
460 
461  // Draw border at constant phi
462 
463  x2_min -= border / x1_min;
464  x2_max += border / x1_min;
465 
466  drawCircularPolygon(module_outline, x1_min, x2_min, x2_max, nDivisions, pos_z);
467  drawCircularPolygon(module_outline, x1_max, x2_min, x2_max, nDivisions, pos_z);
468 
469  module_outline->AddLine(x1_min*cos(x2_min), x1_min*sin(x2_min), pos_z,
470  x1_max*cos(x2_min), x1_max*sin(x2_min), pos_z);
471 
472  module_outline->AddLine(x1_min*cos(x2_max), x1_min*sin(x2_max), pos_z,
473  x1_max*cos(x2_max), x1_max*sin(x2_max), pos_z);
474 
475  } else {
476 
477  //=====================================
478  // Draw border parallel to plane extent
479 
480  // Two arcs
481 
482  drawCircularPolygon(module_outline, x1_min, x2_min, x2_max, nDivisions, pos_z);
483  drawCircularPolygon(module_outline, x1_max, x2_min, x2_max, nDivisions, pos_z);
484 
485  // Parallel border at right side with two lines perpendicular to
486  // the border connecting to the arcs.
487 
488  phi_min = x2_min - border / x1_min;
489  r_min = x1_min / cos(border / x1_min);
490 
491  phi_max = x2_min - border / x1_max;
492  r_max = x1_max / cos(border / x1_max);
493 
494  module_outline->AddLine(r_min*cos(phi_min), r_min*sin(phi_min), pos_z,
495  r_max*cos(phi_max), r_max*sin(phi_max), pos_z);
496 
497  module_outline->AddLine(x1_min*cos(x2_min), x1_min*sin(x2_min), pos_z,
498  r_min*cos(phi_min), r_min*sin(phi_min), pos_z);
499 
500  module_outline->AddLine(x1_max*cos(x2_min), x1_min*sin(x2_min), pos_z,
501  r_max*cos(phi_max), r_max*sin(phi_max), pos_z);
502 
503 
504  // Parallel border at left side with two lines perpendicular to
505  // the border connecting to the arcs.
506 
507  phi_min = x2_max + border / x1_min;
508  r_min = x1_min / cos(border / x1_min);
509 
510  phi_max = x2_max + border / x1_max;
511  r_max = x1_max / cos(border / x1_max);
512 
513  module_outline->AddLine(r_min*cos(phi_min), r_min*sin(phi_min), pos_z,
514  r_max*cos(phi_max), r_max*sin(phi_max), pos_z);
515 
516  module_outline->AddLine(x1_min*cos(x2_max), x1_min*sin(x2_max), pos_z,
517  r_min*cos(phi_min), r_min*sin(phi_min), pos_z);
518 
519  module_outline->AddLine(x1_max*cos(x2_max), x1_max*sin(x2_max), pos_z,
520  r_max*cos(phi_max), r_max*sin(phi_max), pos_z);
521 
522  }
523 
524  } else {
525 
526  drawCircularPolygon(module_outline, x1_min, x2_min, x2_max, nDivisions, pos_z);
527  drawCircularPolygon(module_outline, x1_max, x2_min, x2_max, nDivisions, pos_z);
528 
529  }
530 
531  break;
532 
533  default:
534  throw "Unknown coordinate type.";
535  }
536 
537  toGlobal(aModule, module_outline);
538 
539  if (parent) {
540 
541  parent->AddElement(module_outline);
542 
543  tooltip << parent->GetElementName() << " outline";
544  module_outline->SetElementTitle(tooltip.str().c_str());
545 
546  } else {
547  gEve->AddGlobalElement(module_outline);
548  }
549 
550  //===========================================================================
551  // Pads
552 
553  drawPads(aModule, parent);
554 }
555 
556 void VisTPC::drawModules(TEveElement* parent) {
557 
558  // 1. Loop over all modules.
559  // 2. Draw each module.
560  // 3. Add tooltip for each module.
561 
562  //===========================================================================
563  // Variables
564 
565  const std::vector<TPCModule *> & tpcModules = tpcParameters->getModules();
566  TPCModule* tpcModule;
567  TEveElementList* elements = NULL;
568  int i = 0;
569 
570  //===========================================================================
571  // Debug
572 
573  if (debug) {
574  std::cout << tpcParameters->getNModules() << " Module(s)" << std::endl;
575  }
576 
577  //===========================================================================
578  // 1. Loop over all modules.
579 
580  for (
581  std::vector<TPCModule *>::const_iterator iterator = tpcModules.begin();
582  iterator != tpcModules.end();
583  ++iterator
584  ) {
585  tpcModule = *iterator;
586 
587  elements = new TEveElementList(Form("Module %i", tpcModule->getModuleID()));
588  elements->SetPickable(kFALSE);
589 
590  // 2. Draw each module.
591 
592  drawModule(tpcModule, elements);
593 
594  //
595 
596  if (parent) {
597  parent->AddElement(elements);
598  } else {
599  gEve->AddGlobalElement(elements);
600  }
601  }
602 
603  //
604 
605  gEve->Redraw3D();
606 
607  // Finalize
608 
609  tpcModule = NULL;
610  elements = NULL;
611 }
612 
613 void VisTPC::drawNearestPad(const gear::TPCModule& tpcModule, TEveElement* parent, int padIndex, const gear::Vector2D& position, int i) {
614  // Initialize variables
615 
616  TEveElementList* node = new TEveElementList(Form("%i", i));
617  TEvePointSet* point = new TEvePointSet(Form("Test hit %i", i));
618  TEvePointSet* padcenter = 0;
619  TEveQuadSet* pad = new TEveQuadSet(Form("Pad %i", i));
620  TEveStraightLineSet* line = new TEveStraightLineSet(Form("Line %i", i));
621 
622  PadMetric padMetric;
623 
624  float a_pos, b_pos;
625  float z_pos = maxDriftLength;
626 
627  Vector2D padPos;
628  const PadRowLayout2D &layout = tpcModule.getLocalPadLayout();
629 
630  std::stringstream tooltip;
631 
632  // Initialize new graphical elements
633 
634  point->SetOwnIds(kTRUE);
635  point->SetMarkerColor(kRed);
636  point->SetMarkerSize(0.2);
637  point->SetMarkerStyle(2);
638 
639  pad->Reset(TEveQuadSet::kQT_FreeQuad, kTRUE, 32);
640  pad->RefitPlex();
641  pad->SetOwnIds(kTRUE);
642 
643  tooltip.str("");
644 
645  padcenter = new TEvePointSet(Form("padcenter %i", i));
646  padcenter->SetOwnIds(kTRUE);
647  padcenter->SetMarkerColor(kGreen);
648  padcenter->SetMarkerSize(0.2);
649  padcenter->SetMarkerStyle(2);
650 
651  line->SetLineColor(kYellow);
652  //line->SetLineColor(kMagenta);
653 
654  // Get pad using random point in local coordinate
655 
656  a_pos = position[0];
657  b_pos = position[1];
658 
659  tooltip << "Test hit: (" << a_pos << ", " << b_pos << ")" << std::endl;
660 
661  padPos = layout.getPadCenter(padIndex);
662 
663  tooltip << "Padcenter: (" << padPos[0] << ", " << padPos[1] << ")" << std::endl;
664 
665  tooltip << "Difference: ("
666  << a_pos - padPos[0] << ", "
667  << b_pos - padPos[1] << ")"
668  << std::endl;
669 
670  // Draw point in local coordinate
671 
672  if (layout.getCoordinateType() == PadRowLayout2D::POLAR) {
673  float x, y;
674 
675  x = a_pos*cos(b_pos);
676  y = a_pos*sin(b_pos);
677 
678  a_pos = x;
679  b_pos = y;
680  }
681 
682  tooltip << "Test hit (cartesian): (" << a_pos << ", " << b_pos << ")" << std::endl;
683 
684  point->SetNextPoint(a_pos, b_pos, 1);
685 
686  // Draw pad in local coordinate
687 
688  getLocalPadMetric(&tpcModule, padIndex, padMetric);
689 
690  padcenter->SetNextPoint(padMetric.center_x, padMetric.center_y, 1);
691 
692  tooltip << "padMetric.center(cartesian): (" << padMetric.center_x << ", " << padMetric.center_y << ")" << std::endl;
693 
694  drawPadQuad(padMetric, 0, pad);
695  pad->QuadColor(kBlack);
696 
697  // Connect the pad and hit with a line
698 
699  line->AddLine(
700  a_pos, b_pos, 1,
701  padMetric.center_x, padMetric.center_y, 1
702  );
703 
704  // Transform everything into global coordinate system
705 
706  toGlobal(&tpcModule, dynamic_cast<TEveElement*>(point));
707  toGlobal(&tpcModule, dynamic_cast<TEveElement*>(pad));
708  toGlobal(&tpcModule, dynamic_cast<TEveElement*>(padcenter));
709  toGlobal(&tpcModule, dynamic_cast<TEveElement*>(line));
710 
711  //
712 
713  node->SetElementTitle(Form("%i\n%s", i, tooltip.str().c_str()));
714  point->SetElementTitle(Form("Test hit %i\n%s", i, tooltip.str().c_str()));
715  pad->SetElementTitle(Form("Pad %i\n%s", i, tooltip.str().c_str()));
716  padcenter->SetElementTitle(Form("Pad center %i\n%s", i, tooltip.str().c_str()));
717  line->SetElementTitle(Form("Line %i\n%s", i, tooltip.str().c_str()));
718 
719  node->AddElement(point);
720  node->AddElement(pad);
721  node->AddElement(padcenter);
722  node->AddElement(line);
723 
724  if (parent)
725  parent->AddElement(node);
726  else
727  gEve->AddElement(node);
728 }
729 
730 void VisTPC::drawPadBox(const PadMetric& pad, float z_front, float z_back, TEveBoxSet* bs) {
731  float boxCorners[24];
732 
733  // top back left
734  boxCorners[0] = pad.corners_cartesian[6];
735  boxCorners[1] = pad.corners_cartesian[7];
736  boxCorners[2] = z_back;
737 
738  // top back right
739  boxCorners[3] = pad.corners_cartesian[4];
740  boxCorners[4] = pad.corners_cartesian[5];
741  boxCorners[5] = z_back;
742 
743  // top front right
744  boxCorners[6] = pad.corners_cartesian[4];
745  boxCorners[7] = pad.corners_cartesian[5];
746  boxCorners[8] = z_front;
747 
748  // top front left
749  boxCorners[9] = pad.corners_cartesian[6];
750  boxCorners[10] = pad.corners_cartesian[7];
751  boxCorners[11] = z_front;
752 
753  // bottom back left
754  boxCorners[12] = pad.corners_cartesian[0];
755  boxCorners[13] = pad.corners_cartesian[1];
756  boxCorners[14] = z_back;
757 
758  // bottom back right
759  boxCorners[15] = pad.corners_cartesian[2];
760  boxCorners[16] = pad.corners_cartesian[3];
761  boxCorners[17] = z_back;
762 
763  // bottom front right
764  boxCorners[18] = pad.corners_cartesian[2];
765  boxCorners[19] = pad.corners_cartesian[3];
766  boxCorners[20] = z_front;
767 
768  // bottom front left
769  boxCorners[21] = pad.corners_cartesian[0];
770  boxCorners[22] = pad.corners_cartesian[1];
771  boxCorners[23] = z_front;
772 
773  bs->AddBox(boxCorners);
774 }
775 
776 void VisTPC::drawPadQuad(const PadMetric& pad, float z, TEveQuadSet* qs) {
777  float quadCorners[12];
778 
779  // bottom left
780  quadCorners[0] = pad.corners_cartesian[0];
781  quadCorners[1] = pad.corners_cartesian[1];
782  quadCorners[2] = z;
783 
784  // bottom right
785  quadCorners[3] = pad.corners_cartesian[2];
786  quadCorners[4] = pad.corners_cartesian[3];
787  quadCorners[5] = z;
788 
789  // top right
790  quadCorners[6] = pad.corners_cartesian[4];
791  quadCorners[7] = pad.corners_cartesian[5];
792  quadCorners[8] = z;
793 
794  // top left
795  quadCorners[9] = pad.corners_cartesian[6];
796  quadCorners[10] = pad.corners_cartesian[7];
797  quadCorners[11] = z;
798 
799  qs->AddQuad(quadCorners);
800 }
801 
802 void VisTPC::drawPads(TPCModule * aModule, TEveElement* parent) {
803 
804  // 1. Loop over all rows.
805  // 2. Draw radial lines and a center marker of each pad.
806  // 3. Draw circular lines of each row.
807 
808  //===========================================================================
809  // Variables
810 
811  const PadRowLayout2D &layout = aModule->getLocalPadLayout();
812  PadMetric pad;
813  std::stringstream tooltip;
814 
815  // 1. Loop over all rows.
816 
817  int nRows = layout.getNRows();
818  //nRows = nRows > 25 ? 25 : nRows; // CHANGE: Just for rapid prototyping. Showing full module is slow process
819 
820  // 2. Draw radial lines of each pad.
821 
822  const std::vector<int> * padsInRow = NULL;
823  std::vector<int>::const_iterator iterator;
824 
825  TEveStraightLineSet* ls = new TEveStraightLineSet("Pad borders");
826  TEvePointSet* ps = new TEvePointSet("Pad centers");
827 
828  float x_pos, y_pos = 0.;
829  float z_pos = 0.;
830 
831  // 3. Draw circular lines of each row.
832 
833  const std::vector<double>& extent = layout.getPlaneExtent();
834 
835  int nPadsInRow = 0;
836  int nDivisions = 0;
837  double row_extent_min = 0.;
838  double row_extent_max = 0.;
839  double padRowHeightDiff = 0.;
840  double padGap = 0.;
841 
842  // Debug output
843 
844  //std::cout << "Rows: " << nRows << std::endl;
845 
846  //===========================================================================
847 
848  ls->SetRnrSelf(options["module.drawPadsByDefault"]);
849  ls->SetLineColor(kRed);
850  ls->SetPickable(kFALSE);
851 
852  ps->SetRnrSelf(kFALSE);
853  ps->SetOwnIds(kTRUE);
854  ps->SetMarkerColor(kGreen);
855  ps->SetMarkerSize(1);
856  ps->SetMarkerStyle(1);
857  ps->SetPickable(kFALSE);
858 
859  //
860 
861  switch (layout.getCoordinateType()) {
862  case PadRowLayout2D::CARTESIAN:
863  row_extent_min = extent[0];
864  row_extent_max = extent[1];
865  break;
866 
867  case PadRowLayout2D::POLAR:
868  row_extent_min = extent[2];
869  row_extent_max = extent[3];
870  break;
871 
872  default:
873  throw "Unknown coordinate type.";
874  }
875 
876  // 1. Loop over all rows.
877 
878  for (int i = 0; i < nRows; i++) {
879  padsInRow = &layout.getPadsInRow(i);
880  iterator = padsInRow->begin();
881  nPadsInRow = padsInRow->size();
882 
883  x_pos = 0;
884  y_pos = 0;
885  z_pos = 0;
886 
887  // Debug
888 
889  //std::cout <<"Cols[" << i << "]: " << nPadsInRow << std::endl;
890 
891  // 2. Draw radial lines of each pad.
892 
893  padGap = layout.getPadPitch(*(padsInRow->begin())) - layout.getPadWidth(*(padsInRow->begin()));
894 
895  while (iterator != padsInRow->end()) {
896  getLocalPadMetric(aModule, *iterator, pad);
897 
898  //if (debug) {
899  // std::cout << "Pad corners: (" << pad.corners_cartesian[0] << ", " << pad.corners_cartesian[1] << ")" << std::endl
900  // << " (" << pad.corners_cartesian[2] << ", " << pad.corners_cartesian[3] << ")" << std::endl
901  // << " (" << pad.corners_cartesian[4] << ", " << pad.corners_cartesian[5] << ")" << std::endl
902  // << " (" << pad.corners_cartesian[6] << ", " << pad.corners_cartesian[7] << ")" << std::endl;
903  //}
904 
905  x_pos = pad.center_x;
906  y_pos = pad.center_y;
907 
908  switch (layout.getCoordinateType()) {
909  case PadRowLayout2D::CARTESIAN:
910  if (iterator == padsInRow->begin() || padGap > 1e-6) {
911  ls->AddLine(pad.corners_cartesian[0], pad.corners_cartesian[1], z_pos,
912  pad.corners_cartesian[6], pad.corners_cartesian[7], z_pos);
913  }
914 
915  ls->AddLine(pad.corners_cartesian[2], pad.corners_cartesian[3], z_pos,
916  pad.corners_cartesian[4], pad.corners_cartesian[5], z_pos);
917 
918  break;
919 
920  case PadRowLayout2D::POLAR:
921  if (iterator == padsInRow->begin() || padGap > 1e-6) {
922  ls->AddLine(pad.corners_cartesian[0], pad.corners_cartesian[1], z_pos,
923  pad.corners_cartesian[2], pad.corners_cartesian[3], z_pos);
924  }
925 
926  ls->AddLine(pad.corners_cartesian[6], pad.corners_cartesian[7], z_pos,
927  pad.corners_cartesian[4], pad.corners_cartesian[5], z_pos);
928 
929  break;
930 
931  default:
932  throw "Unknown coordinate type.";
933  }
934 
935  // 2. and the center marker
936 
937  ps->SetNextPoint(x_pos, y_pos, z_pos);
938 
939  //
940 
941  ++iterator;
942  }
943 
944  // 3. Draw row lines of each row.
945 
946  padRowHeightDiff = layout.getRowHeight(i) - layout.getPadHeight(*(padsInRow->begin()));
947 
948  switch (layout.getCoordinateType()) {
949  case PadRowLayout2D::CARTESIAN:
950  ls->AddLine(row_extent_min, pad.corners_cartesian[1], z_pos,
951  row_extent_max, pad.corners_cartesian[1], z_pos);
952 
953  if (i == nRows - 1 || padRowHeightDiff > 1e-6) {
954  ls->AddLine(row_extent_min, pad.corners_cartesian[7], z_pos,
955  row_extent_max, pad.corners_cartesian[7], z_pos);
956  }
957 
958  break;
959 
960  case PadRowLayout2D::POLAR:
961  nDivisions = ceil(nPadsInRow / 5.);
962 
963  drawCircularPolygon(ls, pad.corners_polar[0], row_extent_min, row_extent_max, nDivisions, z_pos);
964 
965  if (i == nRows - 1 || padRowHeightDiff > 1e-6) {
966  drawCircularPolygon(ls, pad.corners_polar[4], row_extent_min, row_extent_max, nDivisions, z_pos);
967  }
968 
969  break;
970 
971  default:
972  throw "Unknown coordinate type.";
973  }
974 
975  }
976 
977  toGlobal(aModule, ls);
978  toGlobal(aModule, ps);
979 
980  // Add Line set to Eve
981 
982  if (parent) {
983 
984  parent->AddElement(ls);
985  parent->AddElement(ps);
986 
987  tooltip << parent->GetElementName() << " pads";
988  ls->SetElementTitle(tooltip.str().c_str());
989 
990  tooltip.str("");
991  tooltip << parent->GetElementName() << " pads";
992  ps->SetElementTitle(tooltip.str().c_str());
993 
994  } else {
995  gEve->AddGlobalElement(ls);
996  gEve->AddGlobalElement(ps);
997  }
998 }
999 
1000 TEveElement* VisTPC::drawPulses(IMPL::LCCollectionVec* pulses) {
1001 
1002  // 1. Loop over all pulses.
1003  // 2. Calculate the 8 box corners of the pad projected into 3D space.
1004  // 3. Draw the box and marker.
1005  // 4. Draw global max charges.
1006 
1007  //===========================================================================
1008  // Variables
1009 
1010  TEveRGBAPalette* pal = new TEveRGBAPalette();
1011 
1012  TEveElementList* topElement = new TEveElementList();
1013 
1014  TEveElementList* el = new TEveElementList("Pulses");
1015  TEveBoxSet* bs = new TEveBoxSet ("Boxes");
1016  TEvePointSet* ps = new TEvePointSet ("Markers");
1017 
1018  TEveElementList* el2 = new TEveElementList("Max charge deposit");
1019  TEveBoxSet* bs2 = new TEveBoxSet ("3D lego");
1020  TEveQuadSet* qs2 = new TEveQuadSet ("2D projection");
1021  TEvePointSet* ps2 = new TEvePointSet ("Markers");
1022 
1023  //
1024 
1025  TrackerPulse* tp;
1026  TrackerData* td;
1027  int moduleId = 0;
1028  int padId = 0;
1029  float time = 0.;
1030  float localMaxCharge = 0.;
1031  float overallCharge = 0.;
1032  float startTime = 0.;
1033  float endTime = 0.;
1034 
1035  typedef std::map<int, float> MapPadCharge;
1036  typedef std::map<int, MapPadCharge> MapModulePadCharge;
1037 
1038  MapModulePadCharge globalCharge;
1039  MapPadCharge* moduleCharge;
1040 
1041  //
1042 
1043  const TPCModule* tpcModule = NULL;
1044 
1045  PadMetric pad;
1046  float x_pos, y_pos = 0;
1047  float z_pos = maxDriftLength;
1048 
1049  //
1050 
1051  //===========================================================================
1052 
1053  // Setup the visualization stuffs
1054 
1055  gStyle->SetPalette(1, 0);
1056  pal->SetMinMax(0, 1023);
1057  pal->SetInterpolate(kTRUE);
1058  pal->SetOverColor(kWhite);
1059  pal->SetOverflowAction(TEveRGBAPalette::kLA_Mark);
1060  pal->SetUnderColor(kBlack);
1061  pal->SetUnderflowAction(TEveRGBAPalette::kLA_Mark);
1062 
1063  bs->Reset(TEveBoxSet::kBT_FreeBox, kFALSE, 64);
1064  //bs->SetRnrSelf(kFALSE);
1065  bs->SetMainAlpha(0.9);
1066  bs->SetPalette(pal);
1067 
1068  ps->SetRnrSelf(kFALSE);
1069  //ps->SetOwnIds(kTRUE);
1070  ps->SetMarkerColor(kYellow);
1071  ps->SetMarkerSize(0.2);
1072  ps->SetMarkerStyle(2);
1073 
1074  bs2->Reset(TEveBoxSet::kBT_FreeBox, kFALSE, 64);
1075  bs2->SetRnrSelf(kFALSE);
1076  //bs2->SetMainAlpha(0.5);
1077  bs2->SetPalette(pal);
1078 
1079  ps2->SetRnrSelf(kFALSE);
1080  //ps2->SetOwnIds(kTRUE);
1081  ps2->SetMarkerColor(kYellow);
1082  ps2->SetMarkerSize(0.2);
1083  ps2->SetMarkerStyle(2);
1084 
1085  qs2->Reset(TEveQuadSet::kQT_FreeQuad, kFALSE, 32);
1086  qs2->SetPalette(pal);
1087 
1088  // 1. Loop over all pulses.
1089 
1090  int j = 0;
1091  for (
1092  LCCollectionVec::iterator inputPulsIter = pulses->begin();
1093  inputPulsIter < pulses->end();
1094  inputPulsIter++
1095  ) {
1096  if (maxPoints && j++ > maxPoints) {
1097  break;
1098  }
1099 
1100  tp = dynamic_cast<TrackerPulse *>( *inputPulsIter );
1101  td = tp->getTrackerData();
1102 
1103  //
1104 
1105  moduleId = tp->getCellID1();
1106  padId = tp->getCellID0();
1107 
1108  time = tp->getTime();
1109  localMaxCharge = 0;
1110  startTime = td->getTime() / readoutFrequency;
1111  endTime = startTime + td->getChargeValues().size() / readoutFrequency;
1112  tpcModule = &tpcParameters->getModule(moduleId);
1113 
1114  // 2. Calculate the 8 box corners of the pad projected into 3D space.
1115 
1116  getGlobalPadMetric(tpcModule, padId, pad);
1117 
1118  x_pos = pad.center_x;
1119  y_pos = pad.center_y;
1120 
1121  // Find max charge
1122 
1123  for (
1124  FloatVec::const_iterator i = td->getChargeValues().begin();
1125  i != td->getChargeValues().end();
1126  ++i
1127  ) {
1128  if (*i > localMaxCharge) {
1129  localMaxCharge = *i;
1130  }
1131  }
1132 
1133  if (!globalCharge.count(moduleId)) {
1134  globalCharge[moduleId] = MapPadCharge();
1135  }
1136 
1137  moduleCharge = &globalCharge[moduleId];
1138 
1139  if (!moduleCharge->count(padId)) {
1140  (*moduleCharge)[padId] = 0;
1141  }
1142 
1143  if ((*moduleCharge)[padId] < localMaxCharge) {
1144  (*moduleCharge)[padId] = localMaxCharge;
1145  }
1146 
1147  // 3. Draw the marker and box.
1148 
1149  ps->SetNextPoint(x_pos, y_pos, z_pos - startTime* driftVelocity);
1150 
1151  drawPadBox(
1152  pad,
1153  z_pos - endTime * driftVelocity,
1154  z_pos - startTime * driftVelocity,
1155  bs
1156  );
1157  bs->DigitValue(localMaxCharge);
1158  }
1159 
1160  // 4. Draw global max charges.
1161 
1162  for (
1163  MapModulePadCharge::iterator j = globalCharge.begin();
1164  j != globalCharge.end();
1165  ++j
1166  ) {
1167 
1168  moduleId = (*j).first;
1169  tpcModule = &tpcParameters->getModule(moduleId);
1170 
1171  for (
1172  MapPadCharge::iterator k = (*j).second.begin();
1173  k != (*j).second.end();
1174  ++k
1175  ) {
1176 
1177  padId = (*k).first;
1178  localMaxCharge = (*k).second;
1179 
1180  getGlobalPadMetric(tpcModule, padId, pad);
1181 
1182  x_pos = pad.center_x;
1183  y_pos = pad.center_y;
1184 
1185  // 2D
1186 
1187  drawPadQuad(pad, z_pos, qs2);
1188  qs2->DigitValue(localMaxCharge);
1189 
1190  ps2->SetNextPoint(x_pos, y_pos, z_pos + 1);
1191 
1192  // 3D lego
1193 
1194  drawPadBox(pad, z_pos, z_pos + localMaxCharge / 10, bs2);
1195  bs2->DigitValue(localMaxCharge);
1196 
1197  //ps2->SetNextPoint(x_pos, y_pos, z_pos + 50 + localMaxCharge);
1198  }
1199 
1200  }
1201 
1202  //
1203 
1204  bs->RefitPlex();
1205  bs2->RefitPlex();
1206  qs2->RefitPlex();
1207 
1208  topElement->AddElement(el);
1209  el->AddElement(bs);
1210  el->AddElement(ps);
1211 
1212  topElement->AddElement(el2);
1213  el2->AddElement(bs2);
1214  el2->AddElement(ps2);
1215  el2->AddElement(qs2);
1216 
1217  return topElement;
1218 }
1219 
1221 
1222  volumes["top"] = gGeoManager->MakeBox("Detector", media["Vacuum"],
1225  3*maxDriftLength);
1226 
1227  // Make a tube as TPC.
1228  volumes["TPC"] = gGeoManager->MakeTube("TPC", media["Al"], innerFieldCageRadius,
1230 
1231  volumes["TPC"]->SetTransparency(75);
1232  volumes["top"]->AddNode(volumes["TPC"], 0, new TGeoTranslation(0,0,0));
1233 
1234  gGeoManager->SetTopVolume(volumes["top"]);
1235 
1236  TGeoNode* node = gGeoManager->GetTopNode();
1237  TEveGeoTopNode* en = new TEveGeoTopNode(gGeoManager, node);
1238 
1239  en->SetVisLevel(1);
1240  en->GetNode()->GetVolume()->SetVisibility(kFALSE);
1241 
1242  gEve->AddGlobalElement(en);
1243 
1244  drawModules(en);
1245 
1246  //---------------------------------------------------------------------------
1247  // Close the geometry
1248 
1249  //gGeoManager->CloseGeometry();
1250 
1251  gEve->Redraw3D();
1252 }
1253 
1254 TEveElement* VisTPC::drawTracks(LCCollectionVec* tracks, TEveElement* parent) {
1255 
1256  //---------------------------------------------------------------------------
1257  // Contents
1258  //---------------------------------------------------------------------------
1259  // 1. Declarations & initializations
1260  // 2. Init stuffs
1261  // 3. Draw tracks
1262  // 4. Add tracks to parent or global
1263  //---------------------------------------------------------------------------
1264 
1265  //---------------------------------------------------------------------------
1266  // 1. Declarations & initializations
1267  //---------------------------------------------------------------------------
1268 
1269  const float cm = 1.;
1270  const float mm = 0.1 * cm;
1271 
1272  Track *lcio_track = NULL;
1273  const TrackerHitVec *lcio_hits = NULL;
1274 
1275  //TEveElementList *eveNodeEvent = new TEveElementList(name);
1276 
1277  TEveTrackList *track_list = new TEveTrackList();
1278  TEveTrackPropagator *propagator = track_list->GetPropagator();
1279  TEveRecTrack *eve_track_rec = NULL;
1280  TEveTrack *eve_track = NULL;
1281  TEveStraightLineSet *eve_line = NULL;
1282  TEveElement *eve_hits = NULL;
1283  TEveElementList *eve_all_hits = new TEveElementList("All hits");
1284 
1285  Vector3D b_field(0,0,0);
1286 
1287  float p_transversal = 0.;
1288 
1289  const float *reference_point = NULL;
1290  float start_point[3];
1291  float d0, phi0, z0, tanLambda, omega = 0.;
1292  int charge = 0;
1293 
1294  int j = 0;
1295 
1296  // const std::vector<double>& extent = tpcParameters->getPlaneExtent();
1297  // float rmin = 0.;
1298  // float rmax = 0.;
1299 
1300  // 30 = TrackFitterBase::FITFAILEDBIT
1301  const int FITFAILEDBIT = 30;
1302  bool fitFailed = 0;
1303 
1304  //---------------------------------------------------------------------------
1305  // 2. Init stuffs
1306  //---------------------------------------------------------------------------
1307 
1308  try{
1309  b_field = gearMgr->getBField().at(Vector3D(0, 0, 0));
1310  }
1311  catch (UnknownParameterException & e) {
1312  std::cout << "WARNING:" << e.what() << std::endl;
1313  std::cout << "B field is assumed to be 0" << std::endl;
1314  }
1315 
1316  // Set properties of the propagator used for reconstructing the tracks.
1317 
1318  propagator->SetMagFieldObj(
1319  new TEveMagFieldConst(
1320  b_field.x(),
1321  b_field.y(),
1322  b_field.z()
1323  )
1324  );
1325 
1326  propagator->SetMaxR(outerFieldCageRadius);
1327  propagator->SetMaxZ(maxDriftLength);
1328  propagator->SetMaxOrbs(50);
1329 
1330  //---------------------------------------------------------------------------
1331  // 3. Draw tracks
1332  //---------------------------------------------------------------------------
1333 
1334  for (
1335  LCCollectionVec::iterator tracksIter = tracks->begin();
1336  tracksIter != tracks->end();
1337  ++tracksIter
1338  ) {
1339  if (maxPoints && j++ > maxPoints) {
1340  break;
1341  }
1342 
1343  lcio_track = dynamic_cast<Track*>( *tracksIter );
1344 
1345  //
1346 
1347  reference_point = lcio_track->getReferencePoint();
1348  d0 = lcio_track->getD0();
1349  omega = lcio_track->getOmega();
1350  phi0 = lcio_track->getPhi();
1351  tanLambda = lcio_track->getTanLambda();
1352  z0 = lcio_track->getZ0();
1353 
1354  start_point[0] = reference_point[0] - d0 * sin(phi0);
1355  start_point[1] = reference_point[1] + d0 * cos(phi0);
1356  start_point[2] = reference_point[2] + z0;
1357 
1358  fitFailed = (lcio_track->getType() >> FITFAILEDBIT) & 0x1 ? 1 : 0;
1359  //fitFailed = lcio_track->getType() & (1<<FITFAILEDBIT) ;
1360 
1361  // Do some necessary calculations
1362 
1363  if (omega) {
1364  charge = b_field.z() / omega >= 0. ? 1 : -1;
1365  } else {
1366  charge = 0;
1367  }
1368 
1369  // MouseOver tooltip
1370 
1371  std::stringstream tooltip;
1372 
1373  tooltip << std::left << "d0 = " << d0 << std::endl
1374  << std::left << "omega = " << omega << std::endl
1375  << std::left << "phi0 = " << phi0 << std::endl
1376  << std::left << "tanLambda = " << tanLambda << std::endl
1377  << std::left << "starting point = ("
1378  << start_point[0] << ", "
1379  << start_point[1] << ", "
1380  << start_point[2] << ")" << std::endl
1381  << std::left << "fitFailed = " << fitFailed << std::endl;
1382 
1383  // First draw the hits, otherwise it would require a second if-else
1384  // construction
1385 
1386  lcio_hits = &lcio_track->getTrackerHits();
1387 
1388  eve_hits = drawHits(*lcio_hits);
1389  ((TEvePointSet*) eve_hits)->SetMarkerColor(!fitFailed ? kRed : kGreen);
1390  ((TEvePointSet*) eve_hits)->SetRnrSelfChildren(kFALSE, kFALSE);
1391 
1392  eve_all_hits->AddElement(eve_hits);
1393 
1394  // Make a distinction between a magnetic field (tracks)
1395  // and an absent magnetic field (straight line) because
1396  // TEveTrack apparently doesn't work with absent magnetic
1397  // field.
1398  //
1399  // Without a B field there is no p_transversal -> No track.
1400  // With omega=0 p_transversal is infinite (divide-by-zero).
1401  //
1402  // TODO: Investigate the possibility of using TEveTrackPropagator for
1403  // both curved and straight tracks. It has code to do that, just need to
1404  // find out how to implement it here. It would simplify the code here.
1405 
1406  if (fabs(b_field.z()) > 0. && omega) {
1407 
1408  // in case the particle does not come from the IP just starting
1409  // the particle at the PCA is not enough. Draw a second arm into
1410  // the direction where it came from (negative momentum with same start point)
1411  // This is only done if there is no inner field cage, otherwise the
1412  // particle will (most probably) come from the vertex.
1413 
1414  for (
1415  int direction = 0;
1416  direction < ( innerFieldCageRadius==0?2:1 );
1417  direction++
1418  ) {
1419 
1420  //-------------------------------------
1421  // Initial vertex location of the track
1422 
1423  eve_track_rec = new TEveRecTrack();
1424  eve_track_rec->fV.Set(
1425  start_point[0],
1426  start_point[1],
1427  start_point[2]
1428  );
1429 
1430  //-----------------
1431  // Initial momentum
1432 
1433  // 1. fV without *mm, but fP with *mm.. not really consistent.
1434  // 2. When two tracks are needed the drawn, the first track gets the
1435  // correct momentum and the second track opposite momentum and
1436  // charge as if it's an anti particle. This will create two tracks
1437  // that goes smooth in each other such that it looks like one
1438  // track.
1439 
1440  p_transversal = 3. * pow(10, -2) * fabs(b_field.z() / omega);
1441 
1442  eve_track_rec->fP.Set(
1443  static_cast<float>( (direction?-1:1) * p_transversal * cos(phi0) ) * mm,
1444  static_cast<float>( (direction?-1:1) * p_transversal * sin(phi0) ) * mm,
1445  static_cast<float>( (direction?-1:1) * p_transversal * tanLambda ) * mm
1446  );
1447  eve_track_rec->fSign = (direction?1:-1) * charge;
1448 
1449  //
1450 
1451  eve_track = new TEveTrack(eve_track_rec, propagator);
1452  eve_track->SetElementTitle(tooltip.str().c_str());
1453  eve_track->SetLineColor(fitFailed ? kRed : kGreen);
1454  eve_track->SetLineWidth(1);
1455 
1456  //
1457 
1458  track_list->AddElement(eve_track);
1459  eve_track->MakeTrack();
1460 
1461  eve_track->AddElement(eve_hits);
1462 
1463  }
1464 
1465  } else {
1466 
1467  if ( eve_line == NULL ) {
1468  eve_line = new TEveStraightLineSet();
1469  }
1470 
1471  // Calculate how much we have to multiply our vector to hit the
1472  // detector's boundaries.
1473 
1474  float scaling_min_xy = sqrt(pow(start_point[0] + cos(phi0) * innerFieldCageRadius, 2)
1475  + pow(start_point[1] + sin(phi0) * innerFieldCageRadius, 2));
1476  float scaling_min_z = (maxDriftLength - start_point[2]) / tanLambda;
1477  float scaling_min = tanLambda * scaling_min_xy > maxDriftLength ? scaling_min_z : scaling_min_xy;
1478 
1479  float scaling_max_xy = sqrt(pow(start_point[0] + cos(phi0) * outerFieldCageRadius, 2)
1480  + pow(start_point[1] + sin(phi0) * outerFieldCageRadius, 2));
1481  float scaling_max_z = (maxDriftLength - start_point[2]) / tanLambda;
1482  float scaling_max = tanLambda * scaling_max_xy > maxDriftLength ? scaling_max_z : scaling_max_xy;
1483 
1484  eve_line->AddLine(
1485  start_point[0] + cos(phi0) * scaling_min,
1486  start_point[1] + sin(phi0) * scaling_min,
1487  start_point[2] + tanLambda * scaling_min,
1488  start_point[0] + cos(phi0) * scaling_max,
1489  start_point[1] + sin(phi0) * scaling_max,
1490  start_point[2] + tanLambda * scaling_max
1491  );
1492 
1493  eve_line->SetElementTitle(tooltip.str().c_str());
1494  eve_line->SetLineColor(fitFailed ? kRed : kGreen);
1495  eve_line->SetLineWidth(1);
1496 
1497  //track_list->AddElement(eve_line);
1498 
1499  eve_line->AddElement(eve_hits);
1500 
1501  } // end if
1502 
1503  } // end for
1504 
1505  //---------------------------------------------------------------------------
1506  // 4. Add tracks to parent or global
1507  //---------------------------------------------------------------------------
1508 
1509  if (parent) {
1510  if (track_list) parent->AddElement(track_list);
1511  if (eve_line) parent->AddElement(eve_line);
1512  if (eve_all_hits) parent->AddElement(eve_all_hits);
1513  } else {
1514  if (track_list) gEve->AddElement(track_list);
1515  if (eve_line) gEve->AddElement(eve_line);
1516  if (eve_all_hits) gEve->AddElement(eve_all_hits);
1517  }
1518 
1519  return track_list;
1520 }
1521 
1522 void VisTPC::drawTwoConnectingPads(const gear::TPCModule& tpcModule, TEveElement* parent, int pad1, int pad2, LeftRight_enum leftright) {
1523 
1524  const PadRowLayout2D &layout = tpcModule.getLocalPadLayout();
1525 
1526  TEveElementList* eNode = 0;
1527  TEveQuadSet* ePad = new TEveQuadSet(Form("Pad %i", pad1));
1528  TEveQuadSet* eNeighbour = new TEveQuadSet(Form("Neighbour %i - %i", pad1, pad2));
1529  TEveStraightLineSet* eLine = new TEveStraightLineSet(Form("Line %i", pad1));
1530 
1531  if (leftright == kLEFT) {
1532  eNode = new TEveElementList(Form("Left %i", pad1));
1533  } else {
1534  eNode = new TEveElementList(Form("Right %i", pad1));
1535  }
1536 
1537  PadMetric padMetric;
1538  Vector2D padPos = layout.getPadCenter(pad1);
1539  Vector2D neighbourPos = layout.getPadCenter(pad2);
1540 
1541  //
1542 
1543  ePad->Reset(TEveQuadSet::kQT_FreeQuad, kTRUE, 32);
1544  ePad->RefitPlex();
1545  ePad->SetOwnIds(kTRUE);
1546 
1547  eNeighbour->Reset(TEveQuadSet::kQT_FreeQuad, kTRUE, 32);
1548  eNeighbour->RefitPlex();
1549  eNeighbour->SetOwnIds(kTRUE);
1550 
1551  // Draw test pad
1552 
1553  getLocalPadMetric(&tpcModule, pad1, padMetric);
1554  drawPadQuad(padMetric, 0, ePad);
1555  ePad->QuadColor(kYellow);
1556 
1557  // Draw neighbour pad
1558 
1559  getLocalPadMetric(&tpcModule, pad2, padMetric);
1560  drawPadQuad(padMetric, 0, eNeighbour);
1561  eNeighbour->QuadColor(kRed);
1562 
1563  // Draw connecting line
1564 
1565  if (layout.getCoordinateType() == PadRowLayout2D::POLAR) {
1566  float x, y;
1567 
1568  x = padPos[0]*cos(padPos[1]);
1569  y = padPos[0]*sin(padPos[1]);
1570 
1571  padPos[0] = x;
1572  padPos[1] = y;
1573 
1574  x = neighbourPos[0]*cos(neighbourPos[1]);
1575  y = neighbourPos[0]*sin(neighbourPos[1]);
1576 
1577  neighbourPos[0] = x;
1578  neighbourPos[1] = y;
1579  }
1580 
1581  eLine->AddLine(
1582  padPos[0], padPos[1], 1,
1583  neighbourPos[0], neighbourPos[1], 1
1584  );
1585  eLine->SetLineColor(kCyan);
1586 
1587  //
1588 
1589  toGlobal(&tpcModule, dynamic_cast<TEveElement*>(ePad));
1590  toGlobal(&tpcModule, dynamic_cast<TEveElement*>(eNeighbour));
1591  toGlobal(&tpcModule, dynamic_cast<TEveElement*>(eLine));
1592 
1593  //
1594 
1595  eNode->AddElement(ePad);
1596  eNode->AddElement(eNeighbour);
1597  eNode->AddElement(eLine);
1598 
1599  if (parent)
1600  parent->AddElement(eNode);
1601  else
1602  gEve->AddElement(eNode);
1603 }
1604 
1605 const VisTPC::LCCollectionType_enum VisTPC::getCollectionType(const std::string& collectionType) {
1606  if (!strcmp(collectionType.c_str(), EVENT::LCIO::TRACKERHIT)) {return kHIT;}
1607  else if (!strcmp(collectionType.c_str(), EVENT::LCIO::TRACKERPULSE)) {return kPULSE;}
1608  else if (!strcmp(collectionType.c_str(), EVENT::LCIO::TRACK)) {return kTRACK;}
1609 
1610  return kUNDEFINEDTYPE;
1611 }
1612 
1613 void VisTPC::getLocalPadMetric(const TPCModule * aModule, const int padIndex, PadMetric& pad) {
1614  const PadRowLayout2D* layout = &aModule->getLocalPadLayout();
1615  Vector2D center = layout->getPadCenter(padIndex);
1616 
1617  // TODO
1618  // Add caching
1619 
1620  //
1621 
1622  pad.height = layout->getPadHeight(padIndex);
1623  pad.width = layout->getPadWidth(padIndex);
1624 
1625  float x1_min = 0.;
1626  float x1_max = 0.;
1627  float x2_min = 0.;
1628  float x2_max = 0.;
1629 
1630  switch (layout->getCoordinateType()) {
1631  case PadRowLayout2D::CARTESIAN:
1632 
1633  pad.coordinate_system = PadRowLayout2D::CARTESIAN;
1634 
1635  x1_min = center[0] - pad.width / 2.;
1636  x1_max = center[0] + pad.width / 2.;
1637  x2_min = center[1] - pad.height / 2.;
1638  x2_max = center[1] + pad.height / 2.;
1639 
1640  pad.center_x = center[0];
1641  pad.center_y = center[1];
1642 
1643  pad.corners_cartesian[0] = x1_min;
1644  pad.corners_cartesian[1] = x2_min;
1645  pad.corners_cartesian[2] = x1_max;
1646  pad.corners_cartesian[3] = x2_min;
1647  pad.corners_cartesian[4] = x1_max;
1648  pad.corners_cartesian[5] = x2_max;
1649  pad.corners_cartesian[6] = x1_min;
1650  pad.corners_cartesian[7] = x2_max;
1651 
1652  // Polar coordinates are not needed in drawings when
1653  // we work in cartesian coordinate system.
1654 
1655  pad.corners_polar[0] = 0;
1656  pad.corners_polar[1] = 0;
1657  pad.corners_polar[2] = 0;
1658  pad.corners_polar[3] = 0;
1659  pad.corners_polar[4] = 0;
1660  pad.corners_polar[5] = 0;
1661  pad.corners_polar[6] = 0;
1662  pad.corners_polar[7] = 0;
1663 
1664  break;
1665 
1666  case PadRowLayout2D::POLAR:
1667 
1668  x1_min = center[0] - pad.height / 2.;
1669  x1_max = center[0] + pad.height / 2.;
1670  x2_min = center[1] - pad.width / 2.;
1671  x2_max = center[1] + pad.width / 2.;
1672 
1673  pad.coordinate_system = PadRowLayout2D::POLAR;
1674 
1675  pad.center_x = center[0] * cos(center[1]);
1676  pad.center_y = center[0] * sin(center[1]);
1677 
1678  pad.center_r = center[0];
1679  pad.center_phi = center[1];
1680 
1681  pad.corners_polar[0] = x1_min;
1682  pad.corners_polar[1] = x2_min;
1683  pad.corners_polar[2] = x1_max;
1684  pad.corners_polar[3] = x2_min;
1685  pad.corners_polar[4] = x1_max;
1686  pad.corners_polar[5] = x2_max;
1687  pad.corners_polar[6] = x1_min;
1688  pad.corners_polar[7] = x2_max;
1689 
1690  pad.corners_cartesian[0] = x1_min*cos(x2_min);
1691  pad.corners_cartesian[1] = x1_min*sin(x2_min);
1692  pad.corners_cartesian[2] = x1_max*cos(x2_min);
1693  pad.corners_cartesian[3] = x1_max*sin(x2_min);
1694  pad.corners_cartesian[4] = x1_max*cos(x2_max);
1695  pad.corners_cartesian[5] = x1_max*sin(x2_max);
1696  pad.corners_cartesian[6] = x1_min*cos(x2_max);
1697  pad.corners_cartesian[7] = x1_min*sin(x2_max);
1698 
1699  break;
1700  default:
1701  throw "Unknown coordinate type.";
1702  }
1703 }
1704 
1705 void VisTPC::getGlobalPadMetric(const TPCModule * aModule, const int padIndex, PadMetric& pad) {
1706  double angle = aModule->getAngle();
1707  const Vector2D offset = aModule->getOffset();
1708  Vector2D center = aModule->getPadCenter(padIndex);
1709 
1710 
1711  //Vector2D global;
1712 
1713  // TODO
1714  // Add caching
1715 
1716  //
1717 
1718  getLocalPadMetric(aModule, padIndex, pad);
1719 
1720  //
1721 
1722  // To global coordinate
1723 
1724  switch (pad.coordinate_system) {
1725  case PadRowLayout2D::CARTESIAN:
1726  pad.center_x = center[0];
1727  pad.center_y = center[1];
1728  break;
1729 
1730  case PadRowLayout2D::POLAR:
1731  pad.center_x = center[0] * cos(center[1]);
1732  pad.center_y = center[0] * sin(center[1]);
1733  break;
1734  default:
1735  throw "Unknown coordinate type.";
1736  }
1737 
1738  // Rotation first..
1739 
1740  PadMetric tempPad = pad;
1741  double sinangle = sin(angle);
1742  double cosangle = cos(angle);
1743  tempPad.corners_cartesian[0] = pad.corners_cartesian[0] * cosangle - pad.corners_cartesian[1] * sinangle;
1744  tempPad.corners_cartesian[1] = pad.corners_cartesian[0] * sinangle + pad.corners_cartesian[1] * cosangle;
1745  tempPad.corners_cartesian[2] = pad.corners_cartesian[2] * cosangle - pad.corners_cartesian[3] * sinangle;
1746  tempPad.corners_cartesian[3] = pad.corners_cartesian[2] * sinangle + pad.corners_cartesian[3] * cosangle;
1747  tempPad.corners_cartesian[4] = pad.corners_cartesian[4] * cosangle - pad.corners_cartesian[5] * sinangle;
1748  tempPad.corners_cartesian[5] = pad.corners_cartesian[4] * sinangle + pad.corners_cartesian[5] * cosangle;
1749  tempPad.corners_cartesian[6] = pad.corners_cartesian[6] * cosangle - pad.corners_cartesian[7] * sinangle;
1750  tempPad.corners_cartesian[7] = pad.corners_cartesian[6] * sinangle + pad.corners_cartesian[7] * cosangle;
1751 
1752  pad = tempPad;
1753 
1754  if (pad.coordinate_system == PadRowLayout2D::POLAR) {
1755  pad.corners_polar [1] += angle;
1756  pad.corners_polar [3] += angle;
1757  pad.corners_polar [5] += angle;
1758  pad.corners_polar [7] += angle;
1759  }
1760 
1761  // and then translation.
1762 
1763  pad.corners_cartesian[0] += offset[0]; pad.corners_cartesian[1] += offset[1];
1764  pad.corners_cartesian[2] += offset[0]; pad.corners_cartesian[3] += offset[1];
1765  pad.corners_cartesian[4] += offset[0]; pad.corners_cartesian[5] += offset[1];
1766  pad.corners_cartesian[6] += offset[0]; pad.corners_cartesian[7] += offset[1];
1767 
1768  if (pad.coordinate_system == PadRowLayout2D::POLAR) {
1769  // TODO for pad.corners_polar[]
1770  }
1771 }
1772 
1774  Vector2D padPos;
1775  const TPCModule &tpcModule = tpcParameters->getModule(moduleID);
1776  const PadRowLayout2D &layout = tpcModule.getLocalPadLayout();
1777 
1778  std::vector<int> pads;
1779 
1780  //
1781 
1782  for (
1783  int nRow = 0;
1784  nRow < layout.getNRows();
1785  ++nRow
1786  ) {
1787 
1788  const std::vector<int> &padsInRow = layout.getPadsInRow(nRow);
1789 
1790  for (
1791  std::vector<int>::const_iterator it = padsInRow.begin();
1792  it != padsInRow.end();
1793  ++it
1794  ) {
1795 
1796  pads.push_back(*it);
1797 
1798  }
1799 
1800  }
1801 
1802  testLeftRightNeighbourWithPads(moduleID, pads, kLEFT);
1803  testLeftRightNeighbourWithPads(moduleID, pads, kRIGHT);
1804 }
1805 
1806 void VisTPC::testLeftRightNeighbourWithPads(int moduleID, const std::vector<int>& pads, LeftRight_enum leftright) {
1807  // Initialize variables
1808 
1809  const TPCModule &tpcModule = tpcParameters->getModule(moduleID);
1810  const PadRowLayout2D &layout = tpcModule.getLocalPadLayout();
1811 
1812  int pad = 0;
1813  int neighbour = 0;
1814  Vector2D padPos;
1815  Vector2D neighbourPos;
1816 
1817  double distance;
1818  double threshold;
1819 
1820  // Initialize TEve variables
1821 
1822  TEveElementList* eParent = 0;
1823 
1824  if (leftright == kLEFT) {
1825  eParent = new TEveElementList("Test getLeftNeighbour");
1826  } else {
1827  eParent = new TEveElementList("Test getRightNeighbour");
1828  }
1829 
1830  //
1831 
1832  for (
1833  std::vector<int>::const_iterator it = pads.begin();
1834  it != pads.end();
1835  ++it
1836  ) {
1837 
1838  try {
1839 
1840  pad = *it;
1841 
1842  if (leftright == kLEFT)
1843  neighbour = layout.getLeftNeighbour(pad);
1844  else
1845  neighbour = layout.getRightNeighbour(pad);
1846 
1847  padPos = layout.getPadCenter(pad);
1848  neighbourPos = layout.getPadCenter(neighbour);
1849 
1850  // calculate distance between pad and neighbour
1851 
1852  switch (layout.getCoordinateType()) {
1853  case PadRowLayout2D::CARTESIAN:
1854  distance = sqrt(
1855  pow(padPos[0] - neighbourPos[0], 2)
1856  + pow(padPos[1] - neighbourPos[1], 2)
1857  );
1858 
1859  threshold = 1.5 * layout.getPadWidth(pad);
1860 
1861  break;
1862 
1863  case PadRowLayout2D::POLAR:
1864  distance = sqrt(
1865  pow(padPos[0], 2)
1866  + pow(neighbourPos[0], 2)
1867  - 2*padPos[0]*neighbourPos[0]*cos(padPos[1] - neighbourPos[1])
1868  );
1869 
1870  threshold = 1.5 * padPos[0] * layout.getPadWidth(pad);
1871 
1872  break;
1873 
1874  default:
1875  distance = 1000;
1876  break;
1877  }
1878 
1879  if (distance > threshold)
1880  throw pad;
1881 
1882  } catch (gear::Exception e) {
1883 
1884  int rowNumber = layout.getRowNumber(*it);
1885 
1886  int firstPad = layout.getPadIndex(rowNumber, 0);
1887  int lastPad = firstPad + layout.getPadsInRow(rowNumber).size() - 1;
1888 
1889  // Last pad should give an exception when getLeftNeighbour
1890 
1891  if (
1892  (leftright == kLEFT)
1893  && (*it == lastPad)
1894  ) {
1895  //std::cout << "left: it's ok to have no neighbour." << std::endl;
1896  }
1897 
1898  // First pad should give an exception when getRightNeighbour
1899 
1900  else if (
1901  (leftright == kRIGHT)
1902  && (*it == firstPad)
1903  ) {
1904  //std::cout << "right: it's ok to have no neighbour." << std::endl;
1905  }
1906 
1907  // The middle pads shouldn't give exception, so let's visualize.
1908 
1909  else {
1910  drawTwoConnectingPads(tpcModule, eParent, pad, neighbour, leftright);
1911  }
1912 
1913  } catch (int pad) {
1914 
1915  drawTwoConnectingPads(tpcModule, eParent, pad, neighbour, leftright);
1916 
1917  } catch (...) {
1918 
1919  std::cout << "exception on pad " << pad << std::endl;
1920 
1921  }
1922 
1923  }
1924 
1925  gEve->AddElement(eParent);
1926  gEve->Redraw3D();
1927 }
1928 
1929 void VisTPC::testNearestPad(int moduleID) {
1930  // Initialize variables
1931 
1932  Vector2D padPos;
1933  const TPCModule &tpcModule = tpcParameters->getModule(moduleID);
1934  const PadRowLayout2D &layout = tpcModule.getLocalPadLayout();
1935 
1936  const std::vector<double> &planeExtent = layout.getPlaneExtent();
1937  std::vector<double> testExtent;
1938 
1939  std::vector<Vector2D> points;
1940 
1941  // Initialize random generator
1942 
1943  if (!gRandom)
1944  gRandom = new TRandom(0);
1945 
1946  TRandom& r= *gRandom;
1947  r.SetSeed(0);
1948 
1949  // Extend the plane extent
1950 
1951  testExtent.resize(4);
1952  testExtent[0] = planeExtent[0] - (planeExtent[1] - planeExtent[0]) / 10;
1953  testExtent[1] = planeExtent[1] + (planeExtent[1] - planeExtent[0]) / 10;
1954  testExtent[2] = planeExtent[2] - (planeExtent[3] - planeExtent[2]) / 10;
1955  testExtent[3] = planeExtent[3] + (planeExtent[3] - planeExtent[2]) / 10;
1956 
1957  //if (tpcModule.getPadLayoutType() == PadRowLayout2D::POLAR) {
1958  // if (testExtent[0] < 0.)
1959  // testExtent[0] = 0.;
1960  //}
1961 
1962  // Constant in one coordinate
1963 
1964  for (int i = 0; i < 25; i++) {
1965  points.push_back(Vector2D(
1966  testExtent[0],
1967  r.Uniform(testExtent[2], testExtent[3])
1968  ));
1969  }
1970 
1971  for (int i = 0; i < 100; i++) {
1972  points.push_back(Vector2D(
1973  (planeExtent[0] + planeExtent[1]) / 2,
1974  r.Uniform(planeExtent[2], planeExtent[3])
1975  ));
1976  }
1977 
1978  for (int i = 0; i < 25; i++) {
1979  points.push_back(Vector2D(
1980  testExtent[1],
1981  r.Uniform(testExtent[2], testExtent[3])
1982  ));
1983  }
1984 
1985  // Constant in the other coordinate
1986 
1987  for (int i = 0; i < 25; i++) {
1988  points.push_back(Vector2D(
1989  r.Uniform(testExtent[0], testExtent[1]),
1990  testExtent[2]
1991  ));
1992  }
1993 
1994  for (int i = 0; i < 100; i++) {
1995  points.push_back(Vector2D(
1996  r.Uniform(planeExtent[0], planeExtent[1]),
1997  (planeExtent[2] + planeExtent[3]) / 2
1998  ));
1999  }
2000 
2001  for (int i = 0; i < 25; i++) {
2002  points.push_back(Vector2D(
2003  r.Uniform(testExtent[0], testExtent[1]),
2004  testExtent[3]
2005  ));
2006  }
2007 
2008  // Random points
2009 
2010  for (int i = 0; i < 100; i++) {
2011  points.push_back(Vector2D(
2012  r.Uniform(testExtent[0], testExtent[1]),
2013  r.Uniform(testExtent[2], testExtent[3])
2014  ));
2015  }
2016 
2017  try {
2018  testNearestPadWithPoints(moduleID, points);
2019  } catch (std::out_of_range e) {
2020  std::cout << e.what() << std::endl;
2021  }
2022 }
2023 
2024 void VisTPC::testNearestPadWithPoints(int moduleID, const std::vector<Vector2D>& points) {
2025  // Initialize variables
2026 
2027  TEveElementList* parent = new TEveElementList("Test getNearestPad (module)");
2028 
2029  const TPCModule &tpcModule = tpcParameters->getModule(moduleID);
2030  const PadRowLayout2D &layout = tpcModule.getLocalPadLayout();
2031 
2032  std::stringstream tooltip;
2033 
2034  int padIndex;
2035 
2036  //
2037 
2038  int i = 0;
2039 
2040  for (
2041  std::vector<Vector2D>::const_iterator it = points.begin();
2042  it != points.end();
2043  ++it
2044  ) {
2045  ++i;
2046 
2047  padIndex = layout.getNearestPad((*it)[0], (*it)[1]);
2048 
2049  drawNearestPad(tpcModule, (TEveElement*) parent, padIndex, *it, i);
2050  }
2051 
2052  gEve->AddElement(parent);
2053 
2054  gEve->Redraw3D();
2055 }
2056 
2058  // Initialize variables
2059 
2060  const std::vector<double> &planeExtent = tpcParameters->getPlaneExtent();
2061  std::vector<double> testExtent;
2062 
2063  std::vector<Vector2D> points;
2064 
2065  // Initialize random generator
2066 
2067  if (!gRandom)
2068  gRandom = new TRandom(0);
2069 
2070  TRandom& r= *gRandom;
2071  r.SetSeed(0);
2072 
2073  // Extend the plane extent
2074 
2075  testExtent.resize(4);
2076  testExtent[0] = planeExtent[0] - (planeExtent[1] - planeExtent[0]) / 10;
2077  testExtent[1] = planeExtent[1] + (planeExtent[1] - planeExtent[0]) / 10;
2078  testExtent[2] = planeExtent[2] - (planeExtent[3] - planeExtent[2]) / 10;
2079  testExtent[3] = planeExtent[3] + (planeExtent[3] - planeExtent[2]) / 10;
2080 
2081  //if (tpcModule.getPadLayoutType() == PadRowLayout2D::POLAR) {
2082  // if (testExtent[0] < 0.)
2083  // testExtent[0] = 0.;
2084  //}
2085 
2086  // Random points
2087 
2088  for (int i = 0; i < 5000; i++) {
2089  points.push_back(Vector2D(
2090  r.Uniform(testExtent[0], testExtent[1]),
2091  r.Uniform(testExtent[2], testExtent[3])
2092  ));
2093  }
2094 
2095  try {
2097  } catch (std::out_of_range e) {
2098  std::cout << e.what() << std::endl;
2099  }
2100 }
2101 
2102 void VisTPC::testNearestPadGlobalWithPoints(const std::vector<Vector2D>& points) {
2103  // Initialize variables
2104 
2105  TEveElementList* parent = new TEveElementList("Test getNearestPad (global)");
2106 
2107  const TPCModule *tpcModule = 0;
2108  Vector2D local;
2109 
2110  //
2111 
2112  int i = 0;
2113 
2114  for (
2115  std::vector<Vector2D>::const_iterator it = points.begin();
2116  it != points.end();
2117  ++it
2118  ) {
2119  ++i;
2120 
2121  GlobalPadIndex gpi = tpcParameters->getNearestPad((*it)[0], (*it)[1]);
2122 
2123  tpcModule = & tpcParameters->getModule(gpi.getModuleID());
2124  local = tpcModule->globalToLocal((*it)[0], (*it)[1]);
2125 
2126  drawNearestPad(*tpcModule, (TEveElement*) parent, gpi.getPadIndex(), local, i);
2127  }
2128 
2129  gEve->AddElement(parent);
2130 
2131  gEve->Redraw3D();
2132 }
2133 
2134 void VisTPC::toGlobal(const TPCModule * aModule, TEveElement* element) {
2135  TEveTrans* transformation = NULL;
2136 
2137  const Vector2D* offset = &aModule->getOffset();
2138  double angle = aModule->getAngle();
2139  double x_pos, y_pos = 0.;
2140  float z_pos = maxDriftLength;
2141 
2142  switch (aModule->getTPCCoordinateType()) {
2143  case PadRowLayout2D::CARTESIAN:
2144  x_pos = (*offset)[0];
2145  y_pos = (*offset)[1];
2146  break;
2147  case PadRowLayout2D::POLAR:
2148  x_pos = (*offset)[0] * cos((*offset)[1]);
2149  y_pos = (*offset)[0] * sin((*offset)[1]);
2150  break;
2151  default:
2152  throw "Unknown coordinate type.";
2153  }
2154 
2155  transformation = element->PtrMainTrans();
2156  transformation->SetRotByAngles(angle, 0., 0.);
2157  transformation->Move3PF(x_pos, y_pos, z_pos);
2158 
2159  // Finalize
2160 
2161  transformation = NULL;
2162 }
2163 
2164 void VisTPC::updateGearMgr( gear::GearMgr * aGearMgr )
2165 {
2166  gearMgr = aGearMgr;
2167 
2168  // set the class to a safe state in case the GearMgr is 0 (default constructor)
2169  if ( gearMgr == 0 )
2170  {
2171  tpcParameters=0;
2174  maxDriftLength=0;
2175  return;
2176  }
2177 
2178  // the GearMgr is valid, set the variables
2179  tpcParameters = &(gearMgr->getTPCParameters());
2180  maxDriftLength = tpcParameters->getMaxDriftLength();
2181 
2182  const std::vector<double>& extent = tpcParameters->getPlaneExtent();
2183  switch (tpcParameters->getCoordinateType())
2184  {
2185  // for cartesian coordinates we take the edge that is farthest away from 0,0
2186  case PadRowLayout2D::CARTESIAN:
2187  {
2188  // only draw one cylinder, inner radius is 0
2190  // test all four corners of the plane extent for max radius
2191  double rMaxSquare = extent[0]*extent[0] + extent[2]*extent[2];// xMin^2 + yMin^2
2192 
2193  double rSquare = (extent[0]*extent[0] + extent[3]*extent[3]); //check xMin^2 + yMax^2
2194  if ( rSquare > rMaxSquare ) rMaxSquare = rSquare;
2195 
2196  rSquare = (extent[1]*extent[1] + extent[2]*extent[2]); //check xMax^2 + yMin^2
2197  if ( rSquare > rMaxSquare ) rMaxSquare = rSquare;
2198 
2199  rSquare = (extent[1]*extent[1] + extent[3]*extent[3]); //check xMax^2 + yMax^2
2200  if ( rSquare > rMaxSquare ) rMaxSquare = rSquare;
2201 
2202  outerFieldCageRadius = sqrt( rMaxSquare );
2203  }
2204  break;
2205 
2206  case PadRowLayout2D::POLAR:
2207  innerFieldCageRadius = extent[0];
2208  outerFieldCageRadius = extent[1];
2209  break;
2210 
2211  default:
2212  throw gear::Exception("Unknown coordinate type in TPCParameters");
2213  }
2214 
2215 }
void drawModule(gear::TPCModule *aModule, TEveElement *parent=NULL)
Definition: vistpc.cxx:403
TEveElement * drawTracks(IMPL::LCCollectionVec *tracks, TEveElement *parent=NULL)
Definition: vistpc.cxx:1254
float driftVelocity
Definition: vistpc.h:312
void testNearestPadGlobal()
Definition: vistpc.cxx:2057
void drawPadBox(const PadMetric &pad, float z_front, float z_back, TEveBoxSet *bs)
Definition: vistpc.cxx:730
std::map< std::string, TGeoMedium * > media
Definition: vistpc.h:299
void toGlobal(const gear::TPCModule *aModule, TEveElement *element)
Transform a TEveElement to the global coordinate system of the detector using OpenGL matrix transform...
Definition: vistpc.cxx:2134
TEveElement * drawHits(IMPL::LCCollectionVec *hits, int wantTooltip=true)
Definition: vistpc.cxx:341
int maxPoints
Definition: vistpc.h:335
void drawPadQuad(const PadMetric &pad, float z, TEveQuadSet *qs)
Definition: vistpc.cxx:776
void drawNearestPad(const gear::TPCModule &aModule, TEveElement *parent, int padIndex, const gear::Vector2D &position, int i)
Definition: vistpc.cxx:613
int coordinate_system
Definition: vistpc.h:113
The PadMetric is used for holding the geometric properties of a pad.
Definition: vistpc.h:112
float center_r
Definition: vistpc.h:121
float corners_cartesian[8]
Definition: vistpc.h:125
float center_y
Definition: vistpc.h:119
void testLeftRightNeighbour(int moduleID=0)
Definition: vistpc.cxx:1773
LCCollectionType_enum
Definition: vistpc.h:71
void drawTPC()
Definition: vistpc.cxx:1220
void testNearestPad(int moduleID=0)
Definition: vistpc.cxx:1929
LeftRight_enum
Definition: vistpc.h:84
std::map< std::string, int > options
Definition: vistpc.h:331
float maxDriftLength
This is used for the z-position of the endcap/modules.
Definition: vistpc.h:321
float center_x
Definition: vistpc.h:118
void drawCircularPolygon(TEveStraightLineSet *ls, float r, int nDivisions, float z)
Definition: vistpc.cxx:108
void drawTwoConnectingPads(const gear::TPCModule &aModule, TEveElement *parent, int pad1, int pad2, LeftRight_enum leftright)
Definition: vistpc.cxx:1522
std::map< std::string, TGeoMaterial * > materials
Definition: vistpc.h:298
float outerFieldCageRadius
Radius of the outer field cage cylinder.
Definition: vistpc.h:337
TEveElement * drawPulses(IMPL::LCCollectionVec *pulses)
Definition: vistpc.cxx:1000
float center_phi
Definition: vistpc.h:122
void updateGearMgr(gear::GearMgr *aGearMgr)
A function to update the vistpc with information from a new gear file.
Definition: vistpc.cxx:2164
std::map< std::string, TGeoVolume * > volumes
Definition: vistpc.h:300
void getGlobalPadMetric(const gear::TPCModule *aModule, const int padIndex, PadMetric &pad)
Get the pad geometric properties in the global coordinate system of the detector. ...
Definition: vistpc.cxx:1705
VisTPC(gear::GearMgr *aGearMgr=0)
Definition: vistpc.cxx:78
void testNearestPadGlobalWithPoints(const std::vector< gear::Vector2D > &points)
Definition: vistpc.cxx:2102
const LCCollectionType_enum getCollectionType(const std::string &)
Definition: vistpc.cxx:1605
void drawModules(TEveElement *parent=NULL)
Definition: vistpc.cxx:556
gear::TPCParameters const * tpcParameters
Definition: vistpc.h:288
void testLeftRightNeighbourWithPads(int moduleID, const std::vector< int > &pads, LeftRight_enum leftright)
Definition: vistpc.cxx:1806
float innerFieldCageRadius
Radius of the inner field cage cylinder.
Definition: vistpc.h:338
float readoutFrequency
Definition: vistpc.h:311
void getLocalPadMetric(const gear::TPCModule *aModule, const int padIndex, PadMetric &pad)
Get the pad geometric properties in the local coordinate system of the module.
Definition: vistpc.cxx:1613
void drawHit(EVENT::TrackerHit *hit, TEvePointSet *parent, int wantTooltip=false)
Definition: vistpc.cxx:270
float corners_polar[8]
Definition: vistpc.h:124
void drawEvent(EVENT::LCEvent *event, std::vector< std::string > &selectedEntries, TEveElement *parent=NULL, const char *name="Event")
Definition: vistpc.cxx:161
gear::GearMgr * gearMgr
Definition: vistpc.h:287
void drawPads(gear::TPCModule *aModule, TEveElement *parent=NULL)
Definition: vistpc.cxx:802
void testNearestPadWithPoints(int moduleID, const std::vector< gear::Vector2D > &points)
Definition: vistpc.cxx:2024
int debug
Definition: vistpc.h:282