CMS 3D CMS Logo

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
FWGeometryTableManager.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: Core
4 // Class : FWGeometryTableManager
5 //
6 // Implementation:
7 // [Notes on implementation]
8 //
9 // Original Author: Alja Mrak-Tadel, Matevz Tadel
10 // Created: Thu Jan 27 14:50:57 CET 2011
11 // $Id: FWGeometryTableManager.cc,v 1.7 2011/02/14 22:27:59 amraktad Exp $
12 //
13 
14 //#define PERFTOOL
15 
16 // user include files
17 #include <iostream>
18 #include <boost/bind.hpp>
19 #include <stack>
20 #ifdef PERFTOOL
21 #include <google/profiler.h>
22 #endif
28 
29 #include "TMath.h"
30 #include "TGeoManager.h"
31 #include "TGeoVolume.h"
32 #include "TGeoMatrix.h"
33 #include "TGeoShape.h"
34 #include "TGeoBBox.h"
35 
36 static const char* redTxt = "\033[01;31m";
37 static const char* greenTxt = "\033[01;32m";
38 static const char* cyanTxt = "\033[22;36m";
39 //static const char* whiteTxt = "\033[0m";
40 
42 {
43  return m_node->GetName();
44 }
45 
48  m_width(1),
49  m_height(1),
50  m_color(0xffffff),
51  m_isSelected(false)
52 {
53  GCValues_t gval;
54  gval.fMask = kGCForeground | kGCBackground | kGCStipple | kGCFillStyle | kGCGraphicsExposures;
55  gval.fStipple = gClient->GetResourcePool()->GetCheckeredBitmap();
56  gval.fGraphicsExposures = kFALSE;
57  gval.fBackground = gVirtualX->GetPixel(kGray);
58  m_colorContext = gClient->GetResourcePool()->GetGCPool()->GetGC(&gval,kTRUE);
59 
60 }
61 
63 {
64  gClient->GetResourcePool()->GetGCPool()->FreeGC(m_colorContext->GetGC());
65 }
66 
68 {
69  m_color = gVirtualX->GetPixel(c);
70  m_isSelected = s;
71 }
72 
73 
74 void FWGeometryTableManager::ColorBoxRenderer::draw(Drawable_t iID, int iX, int iY, unsigned int iWidth, unsigned int iHeight)
75 {
78  iWidth += 2*FWTabularWidget::kTextBuffer;
79  iHeight += 2*FWTabularWidget::kTextBuffer;
80 
81  m_colorContext->SetFillStyle(kFillSolid);
82  m_colorContext->SetForeground(m_color);
83  gVirtualX->FillRectangle(iID, m_colorContext->GetGC(), iX, iY, iWidth, iHeight);
84 
85  if (m_isSelected)
86  {
87  m_colorContext->SetFillStyle(kFillOpaqueStippled);
88  gVirtualX->FillRectangle(iID, m_colorContext->GetGC(), iX, iY, iWidth, iHeight);
89  }
90 }
91 
92 //==============================================================================
93 //==============================================================================
94 //
95 // class FWGeometryTableManager
96 //
97 //==============================================================================
98 //==============================================================================
99 
101 : m_selectedRow(-1),
102  m_browser(browser),
103  m_geoManager(0),
104  m_autoExpand(0),
105  m_maxDaughters(10000),
107 {
110 
111  m_browser->m_mode.changed_.connect(boost::bind(&FWGeometryTableManager::updateMode,this));
115 
116  // debug
118 
119  // init here if no config
123 }
124 
126 {
127 }
128 
129 
131 {
132  return unsorted;
133 }
134 
136 {
137  return m_row_to_index.size();
138 }
139 
141 {
142  return kNumCol;
143 }
144 
145 
146 std::vector<std::string> FWGeometryTableManager::getTitles() const
147 {
148  std::vector<std::string> returnValue;
149  returnValue.reserve(numberOfColumns());
150 
151  if (m_modeVolume )
152  returnValue.push_back("Volume Name");
153  else
154  returnValue.push_back("Node Name");
155 
156  returnValue.push_back("Color");
157  returnValue.push_back("RnrSelf");
158  returnValue.push_back("RnrChildren");
159  returnValue.push_back("Material");
160  returnValue.push_back("Position");
161  returnValue.push_back("Diagonal");
162 
163  return returnValue;
164 }
165 
166 void FWGeometryTableManager::setSelection (int row, int column, int mask)
167 {
168 
169  changeSelection(row, column);
170 }
171 
172 const std::string FWGeometryTableManager::title() const
173 {
174  return "Geometry";
175 }
176 
178 {
179  return m_selectedRow;
180 }
181 
183 {
184  return m_selectedColumn;
185 }
186 
188 {
189  return m_selectedRow == row;
190 }
191 
192 void FWGeometryTableManager::changeSelection(int iRow, int iColumn)
193 {
194  if (iRow < 0) return;
195  if (iRow == m_selectedRow )
196  {
197  m_selectedRow = -1;
198  m_selectedColumn = -1;
199  }
200  else
201  {
202  m_selectedRow = iRow;
203  m_selectedColumn = iColumn;
204  }
205  indexSelected_(iRow, iColumn);
207 }
208 
209 
210 FWTableCellRendererBase* FWGeometryTableManager::cellRenderer(int iSortedRowNumber, int iCol) const
211 {
212  if (static_cast<int>(m_row_to_index.size()) <= iSortedRowNumber)
213  {
214  m_renderer.setData(std::string("FWGeometryTableManager::cellRenderer() Error!"), false);
215  return &m_renderer;
216  }
217 
218  FWTextTreeCellRenderer* renderer = &m_renderer;
219 
220 
221 
222  int unsortedRow = m_row_to_index[iSortedRowNumber];
223  const NodeInfo& data = m_entries[unsortedRow];
224  TGeoNode& gn = *data.m_node;
225 
226  bool isSelected = (!filterOff() && m_volumes[gn.GetVolume()].m_matches);//(m_selectedRow == unsortedRow);
227  if (0)
228  {
229  TGGC* gc = ( TGGC*)m_renderer.graphicsContext();
230 
231  if (!filterOff() && m_volumes[gn.GetVolume()].m_matches)
232  gc->SetForeground(gVirtualX->GetPixel(kRed));
233  else
234  gc->SetForeground(gVirtualX->GetPixel(kBlack));
235  }
236 
237  if (iCol == kName)
238  {
239  // printf("redere\n");
240  int nD = getNdaughtersLimited(data.m_node);
241  if (m_modeVolume)
242  renderer->setData(Form("%s [%d]", gn.GetVolume()->GetName(), nD), isSelected);
243  else
244  renderer->setData(Form("%s [%d]", gn.GetName(), nD ), isSelected);
245 
246  renderer->setIsParent((gn.GetNdaughters() > 0) && (filterOff() || m_volumes[gn.GetVolume()].accepted()));
247  // printf("%s isParent %d\n", gn.GetVolume()->GetName(), isParent);
248 
249  renderer->setIsOpen(data.m_expanded);
250  if (data.m_node->GetNdaughters())
251  renderer->setIndentation(10*data.m_level);
252  else
254 
255  return renderer;
256  }
257  else
258  {
259  // printf("title %s \n",data.m_node->GetTitle() );
260  renderer->setIsParent(false);
261  renderer->setIndentation(0);
262  if (iCol == kColor)
263  {
264  //renderer->setData(Form("level .. %d", data.m_level), isSelected);
265  m_colorBoxRenderer.setData(gn.GetVolume()->GetLineColor(), isSelected);
266  return &m_colorBoxRenderer;
267  }
268  else if (iCol == kVisSelf )
269  {
270  renderer->setData( gn.IsVisible() ? "on" : "off", isSelected);
271  return renderer;
272  }
273  else if (iCol == kVisChild )
274  {
275  renderer->setData( gn.IsVisDaughters() ? "on" : "off", isSelected);
276  return renderer;
277  }
278  else if (iCol == kMaterial )
279  {
280  renderer->setData( gn.GetVolume()->GetMaterial()->GetName(), isSelected);
281  return renderer;
282  }
283  else if (iCol == kPosition )
284  {
285  const Double_t* p = gn.GetMatrix()->GetTranslation();
286  renderer->setData(Form("[%.3f, %.3f, %.3f]", p[0], p[1], p[2]), isSelected);
287  return renderer;
288  }
289  else// if (iCol == kPosition )
290  {
291  TGeoBBox* gs = static_cast<TGeoBBox*>( gn.GetVolume()->GetShape());
292  renderer->setData( Form("%f", TMath::Sqrt(gs->GetDX()*gs->GetDX() + gs->GetDY()*gs->GetDY() +gs->GetDZ()*gs->GetDZ() )), isSelected);
293  return renderer;
294  }
295  }
296 }
297 //______________________________________________________________________________
299 {
300  if (row == -1)
301  return;
302 
303 
304  int idx = rowToIndex()[row];
305  // printf("click %s \n", m_entries[idx].name());
306  Entries_i it = m_entries.begin();
307  std::advance(it, idx);
308  NodeInfo& data = *it;
309  data.m_expanded = !data.m_expanded;
310  if (data.m_expanded && data.m_imported == false)
311  {
312  importChildren(idx, false);
313  }
314 
316  dataChanged();
318 }
319 
321 {
322  m_row_to_index.clear();
323 
324  for ( size_t i = 0, e = m_entries.size(); i != e; ++i )
325  {
326  NodeInfo &data = m_entries[i];
327  // printf("visiblity for %s \n", data.m_node->GetName() );
328  if (data.m_parent == -1)
329  {
330  data.m_visible = true;
331  }
332  else
333  {
334  data.m_visible = m_entries[data.m_parent].m_expanded && m_entries[data.m_parent].m_visible;
335  }
336  }
337 
338  // Put in the index only the entries which are visible.
339  for (size_t i = 0, e = m_entries.size(); i != e; ++i)
340  if (m_entries[i].m_visible)
341  m_row_to_index.push_back(i);
342 
343  // printf("entries %d \n", m_entries.size());
344 }
345 
346 
348 {
349  changeSelection(-1, -1);
351  dataChanged();
353 }
354 
355 
356 
357 //==============================================================================
358 
360 {
361  Volumes_i it = m_volumes.find(v);
362  if (it == m_volumes.end())
363  {
364  m_volumes.insert(std::make_pair(v, Match()));
365  }
366  for (int i =0, nD = v->GetNdaughters(); i != nD; ++i) {
367  checkUniqueVolume(v->GetNode(i)->GetVolume());
368  }
369 }
370 
371 void FWGeometryTableManager::loadGeometry(TGeoManager* geoManager)
372 {
373  m_geoManager = geoManager;
374 
375  m_volumes.clear();
376  checkUniqueVolume(geoManager->GetTopVolume());
377  if (!filterOff())
378  updateFilter();
379 
380  m_browser->updateStatusBar(Form("FWGeometryTableManager::loadGeometry() %d unique volumes", (int)m_volumes.size()));
381 
382  setTableContent();
383 }
384 //______________________________________________________________________________
385 
386 
388 {
389  // Prepare data for cell render.
390 
391  m_browser->updateStatusBar("Set table content ...");
392 
393 #ifdef PERFTOOL
394  if (filterOff())
395  ProfilerStart(Form("SetTableContent.expand_%d.modeV_%d", m_browser->m_autoExpand.value(), ( m_browser->m_mode.value() == FWGeometryBrowser::kVolume)));
396  else
397  ProfilerStart(Form("SetTableContent.expand_%d.modeV_%d.filter_%s", m_browser->m_autoExpand.value(), ( m_browser->m_mode.value() == FWGeometryBrowser::kVolume), m_browser->m_filter.value().c_str()));
398 
399 #endif
400  bool debug = 1;
401 
402  // clear entries
403  m_entries.clear();
404  m_row_to_index.clear();
405 
406  // cache browser values
410 
411  // add top node to init
412  NodeInfo topNodeInfo;
413  topNodeInfo.m_node = m_geoManager->GetTopNode();
414  topNodeInfo.m_level = 0;
415  topNodeInfo.m_parent = -1;
416  m_entries.push_back(topNodeInfo);
417 
418  importChildren(0, true);
419 
420  if (debug)
421  checkHierarchy();
422 
423  redrawTable();
424 
425 #ifdef PERFTOOL
426  ProfilerStop();
427 #endif
428 
429  if (filterOff())
430  {
431  m_browser->updateStatusBar(Form("%d entries imported ", (int)m_entries.size()));
432  }
433  else
434  {
435  {
436  // get status
437  int na = 0;
438  int n = 0;
439  for (Volumes_i i = m_volumes.begin(); i!= m_volumes.end(); ++i)
440  {
441  n++;
442  if ( i->second.m_matches)
443  {
444  na++;
445  // printf("[%d] %s matches material %s \n", na, i->first->GetName(), i->first->GetMaterial()->GetName());
446  }
447  }
448 
449  m_browser->updateStatusBar(Form("%d entries imported, filter: %d volumes (%.2f %%) selected ", (int)m_entries.size(), na, na*1.f/n));
450  }
451  }
452 }
453 
454 //==============================================================================
455 
456 
457 
458 void
459 FWGeometryTableManager::getNNodesTotal(TGeoNode* geoNode, int level, int& off, bool debug) const
460 {
461  // Get number of nested children recursively.
462 
463  if (debug) printf("getNNodesTotal %s %s (c:%d)\033[22;0m \n", cyanTxt, geoNode->GetName(), level);
464 
465  int nD = getNdaughtersLimited(geoNode);
466  std::vector<int> vi; vi.reserve(nD);
467  vi.reserve(nD);
468  for (int n = 0; n != nD; ++n)
469  {
470  TGeoVolume* vTmp = geoNode->GetDaughter(n)->GetVolume();
471  if (m_volumes[vTmp].accepted())
472  {
473  bool toAdd = true;
474  if (m_modeVolume)
475  {
476  for (std::vector<int>::iterator u = vi.begin(); u != vi.end(); ++u )
477  {
478  TGeoVolume* neighbourVolume = geoNode->GetDaughter(*u)->GetVolume();
479  if (neighbourVolume == vTmp)
480  {
481  toAdd = false;
482  break;
483  }
484  }
485  } // end volume mode
486  if (toAdd) vi.push_back(n);
487  }
488  }
489 
490  int nV = vi.size();
491  if (level < m_autoExpand)
492  {
493  off += nV;
494  for (int i = 0; i < nV; ++i )
495  {
496  getNNodesTotal(geoNode->GetDaughter(vi[i]), level+1, off, false);
497  }
498  if (debug) printf("%d \n", off);
499  }
500 }
501 
502 void FWGeometryTableManager::importChildren(int parent_idx, bool recurse)
503 {
504  bool debug = false;
505 
506  int nEntries = (int)m_entries.size();
507  assert( parent_idx < nEntries);
508 
509  // parnt index not valid in recursive import: save parent info here
510  NodeInfo& parent = m_entries[parent_idx];
511  TGeoNode* parentGeoNode = parent.m_node;
512  int parentLevel = parent.m_level;
513  if (debug) printf("%s START level[%d] > %s[%d] \033[0m\n" ,greenTxt, parentLevel+1, parentGeoNode->GetName(), parent_idx);
514 
515  parent.m_expanded = true;
516 
517  // get indices of accepted nodes
518  int nD = getNdaughtersLimited(parentGeoNode);
519  std::vector<int> vi;
520  vi.reserve(nD);
521  TGeoVolume* vTmp;
522 
523  for (int n = 0; n != nD; ++n)
524  {
525  vTmp = parentGeoNode->GetDaughter(n)->GetVolume();
526 
527  if (filterOff() || m_volumes[vTmp].accepted())
528  {
529  bool toAdd = true;
530  if (m_modeVolume)
531  {
532  // check duplicates in added
533  for (std::vector<int>::iterator u = vi.begin(); u != vi.end(); ++u )
534  {
535  TGeoVolume* neighbourVolume = parentGeoNode->GetDaughter(*u)->GetVolume();
536  if (neighbourVolume == vTmp)
537  {
538  toAdd = false;
539  break;
540  }
541  }
542  } // end volume mode
543  if (toAdd) vi.push_back(n);
544  } // end checke filters
545 
546 
547  } // end daughter loop
548  int nV = vi.size();
549 
550  // add accepted nodes
551  Entries_i it = m_entries.begin();
552  std::advance(it, parent_idx+1);
553  m_entries.insert(it, nV, NodeInfo());
554  nEntries += nV;
555  if (debug) printf(" accpted %d of %d entries size %d \n", nV, nD, (int)m_entries.size());
556 
557  // child nodes setup
558  for (int n = 0; n != nV; ++n)
559  {
560  int childIdx = vi[n];
561  NodeInfo &nodeInfo = m_entries[parent_idx + 1 + n ];
562  nodeInfo.m_node = parentGeoNode->GetDaughter(childIdx);
563  nodeInfo.m_level = parent.m_level + 1;
564  nodeInfo.m_parent = parent_idx;
565  if (debug) printf(" add %s\n", nodeInfo.name());
566  }
567 
568  if (recurse)
569  {
570  // change of autoExpand parameter
571  int dOff = 0;
572  if ((parent.m_level+1) < m_autoExpand)
573  {
574  for (int n = 0; n != nV; ++n)
575  {
576  importChildren(parent_idx + n + 1 + dOff, recurse);
577  if (parentGeoNode->GetNdaughters() > 0)
578  {
579  getNNodesTotal(parentGeoNode->GetDaughter(vi[n]), parentLevel+1, dOff, debug);
580  }
581 
582  }
583  }
584  }
585  else
586  {
587  // expand on double-click, possibly shift parents
588  if (debug) printf("\ncheck shhift for level evel %d import %s ", parent.m_level +1,parentGeoNode->GetName() );
589 
590  for (int i = (parent_idx + nV + 1); i < nEntries; ++i)
591  {
592  if (m_entries[i].m_parent > m_entries[parent_idx].m_parent)
593  {
594  if (debug) printf("%s %s", redTxt, m_entries[i].name());
595  m_entries[i].m_parent += nV;
596 
597  }
598  }
599  if (debug) printf(" \033[0m\n");
600  }
601 
602 
603  fflush(stdout);
604 }// end importChildren
605 
606 //==============================================================================
607 
609 {
610  // Used for debug: in a NodeInfo entry look TGeoNode children from parent index and check
611  // if child is found.
612 
613  for ( size_t i = 0, e = m_entries.size(); i != e; ++i )
614  {
615  if ( m_entries[i].m_level > 0)
616  {
617  TGeoNode* pn = m_entries[m_entries[i].m_parent].m_node;
618  bool ok = false;
619  for (int d = 0; d < pn->GetNdaughters(); ++d )
620  {
621  if (m_entries[i].m_node == pn->GetDaughter(d))
622  {
623  ok = true;
624  break;
625  }
626  }
627  if (!ok) printf("%s!!!!!! node %s has false parent %s \n", redTxt, m_entries[i].name(), pn->GetName());
628  }
629  }
630 }
631 
632 void FWGeometryTableManager::checkChildMatches(TGeoVolume* vol, std::vector<TGeoVolume*>& pstack)
633 {
634  if (m_volumes[vol].m_matches)
635  {
636  for (std::vector<TGeoVolume*>::iterator i = pstack.begin(); i!= pstack.end(); ++i)
637  {
638  Match& pm = m_volumes[*i];
639  // if (0 && pm.m_childMatches)
640  // break;
641 
642  pm.m_childMatches = true;
643  }
644  }
645 
646  pstack.push_back(vol);
647 
648  int nD = TMath::Min(m_maxDaughters, vol->GetNdaughters());
649  for (int i = 0; i!=nD; ++i)
650  checkChildMatches(vol->GetNode(i)->GetVolume(), pstack);
651 
652  pstack.pop_back();
653 }
654 
655 // callbacks ______________________________________________________________________________
656 
658 {
659  if (!m_geoManager) return;
660 
661 #ifdef PERFTOOL
662  ProfilerStart(m_browser->m_filter.value().c_str());
663 #endif
664 
665  for (Volumes_i i = m_volumes.begin(); i!= m_volumes.end(); ++i)
666  {
667  i->second.m_matches = m_browser->m_filter.value().empty() || strstr(i->first->GetMaterial()->GetName(), m_browser->m_filter.value().c_str());
668  i->second.m_childMatches = false;
669  }
670 
671  std::vector<TGeoVolume*> pstack;
672  checkChildMatches(m_geoManager->GetTopVolume(), pstack);
673 
674  // printf("filterChanged \n");
675 #ifdef PERFTOOL
676  ProfilerStop();
677 #endif
678  setTableContent();
679 }
680 
682 {
683  if (!m_geoManager) return;
684 
685  setTableContent();
686 }
687 
689 {
690  if (!m_geoManager) return;
691 
692  setTableContent();
693 }
694 
696 {
697  return m_browser->m_filter.value().empty();
698  // printf("%d empty off \n", m_browser->m_filter.value().empty());
699 }
static const char * cyanTxt
virtual UInt_t height() const
returns the minimum height of the cell to which the renderer is representing
int i
Definition: DBlmapReader.cc:9
virtual int unsortedRowNumber(int unsorted) const
when passed the index to the sorted order of the rows it returns the original row number from the und...
virtual std::vector< std::string > getTitles() const
returns the title names for each column
void updateStatusBar(const char *status)
list parent
Definition: dbtoconf.py:74
sigc::signal< void, int, int > indexSelected_
FWStringParameter m_filter
virtual FWTableCellRendererBase * cellRenderer(int iSortedRowNumber, int iCol) const
int getNdaughtersLimited(TGeoNode *) const
static const char * greenTxt
void getNNodesTotal(TGeoNode *geoNode, int level, int &off, bool debug) const
FWGeometryTableManager(FWGeometryBrowser *)
FWTextTreeCellRenderer m_renderer
void dataChanged()
Classes which inherit from FWTableManagerBase must call this when their underlying data changes...
sigc::signal< void, T > changed_
virtual bool rowIsSelected(int row) const
std::vector< int > rowToIndex()
ColorBoxRenderer m_colorBoxRenderer
std::vector< int > m_row_to_index
virtual const std::string title() const
FWLongParameter m_maxDaughters
virtual void draw(Drawable_t iID, int iX, int iY, unsigned int iWidth, unsigned int iHeight)
void importChildren(int parent_idx, bool recurse)
const TGGC * graphicsContext() const
static const char * redTxt
void loadGeometry(TGeoManager *geoManager)
virtual void setIndentation(int indentation=0)
void setSelection(int row, int column, int mask)
FWEnumParameter m_mode
void setData(const std::string &, bool isSelected)
Entries_v::iterator Entries_i
void checkChildMatches(TGeoVolume *v, std::vector< TGeoVolume * > &)
void checkUniqueVolume(TGeoVolume *v)
virtual int numberOfColumns() const
Number of columns in the table.
void visualPropertiesChanged()
Classes which inherit from FWTableManagerBase must call this when how the data is shown (e...
Volumes_t::iterator Volumes_i
FWGeometryBrowser * m_browser
FWLongParameter m_autoExpand
static const int kTextBuffer
tuple level
Definition: testEve_cfg.py:34
string s
Definition: asciidump.py:422
#define debug
Definition: MEtoEDMFormat.h:34
virtual int numberOfRows() const
Number of rows in the table.
mathSSE::Vec4< T > v
void changeSelection(int iRow, int iColumn)