00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <iostream>
00018 #include <boost/bind.hpp>
00019 #include <stack>
00020 #ifdef PERFTOOL
00021 #include <google/profiler.h>
00022 #endif
00023 #include "Fireworks/Core/interface/FWGeometryTableManager.h"
00024 #include "Fireworks/Core/interface/FWGeometryBrowser.h"
00025 #include "Fireworks/Core/src/FWColorBoxIcon.h"
00026 #include "Fireworks/TableWidget/interface/GlobalContexts.h"
00027 #include "Fireworks/TableWidget/src/FWTabularWidget.h"
00028
00029 #include "TMath.h"
00030 #include "TGeoManager.h"
00031 #include "TGeoVolume.h"
00032 #include "TGeoMatrix.h"
00033 #include "TGeoShape.h"
00034 #include "TGeoBBox.h"
00035
00036 static const char* redTxt = "\033[01;31m";
00037 static const char* greenTxt = "\033[01;32m";
00038 static const char* cyanTxt = "\033[22;36m";
00039
00040
00041 const char* FWGeometryTableManager::NodeInfo::name() const
00042 {
00043 return m_node->GetName();
00044 }
00045
00046 FWGeometryTableManager::ColorBoxRenderer::ColorBoxRenderer():
00047 FWTableCellRendererBase(),
00048 m_width(1),
00049 m_height(1),
00050 m_color(0xffffff),
00051 m_isSelected(false)
00052 {
00053 GCValues_t gval;
00054 gval.fMask = kGCForeground | kGCBackground | kGCStipple | kGCFillStyle | kGCGraphicsExposures;
00055 gval.fStipple = gClient->GetResourcePool()->GetCheckeredBitmap();
00056 gval.fGraphicsExposures = kFALSE;
00057 gval.fBackground = gVirtualX->GetPixel(kGray);
00058 m_colorContext = gClient->GetResourcePool()->GetGCPool()->GetGC(&gval,kTRUE);
00059
00060 }
00061
00062 FWGeometryTableManager::ColorBoxRenderer::~ColorBoxRenderer()
00063 {
00064 gClient->GetResourcePool()->GetGCPool()->FreeGC(m_colorContext->GetGC());
00065 }
00066
00067 void FWGeometryTableManager::ColorBoxRenderer::setData(Color_t c, bool s)
00068 {
00069 m_color = gVirtualX->GetPixel(c);
00070 m_isSelected = s;
00071 }
00072
00073
00074 void FWGeometryTableManager::ColorBoxRenderer::draw(Drawable_t iID, int iX, int iY, unsigned int iWidth, unsigned int iHeight)
00075 {
00076 iX -= FWTabularWidget::kTextBuffer;
00077 iY -= FWTabularWidget::kTextBuffer;
00078 iWidth += 2*FWTabularWidget::kTextBuffer;
00079 iHeight += 2*FWTabularWidget::kTextBuffer;
00080
00081 m_colorContext->SetFillStyle(kFillSolid);
00082 m_colorContext->SetForeground(m_color);
00083 gVirtualX->FillRectangle(iID, m_colorContext->GetGC(), iX, iY, iWidth, iHeight);
00084
00085 if (m_isSelected)
00086 {
00087 m_colorContext->SetFillStyle(kFillOpaqueStippled);
00088 gVirtualX->FillRectangle(iID, m_colorContext->GetGC(), iX, iY, iWidth, iHeight);
00089 }
00090 }
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100 FWGeometryTableManager::FWGeometryTableManager(FWGeometryBrowser* browser)
00101 : m_selectedRow(-1),
00102 m_browser(browser),
00103 m_geoManager(0),
00104 m_autoExpand(0),
00105 m_maxDaughters(10000),
00106 m_modeVolume(false)
00107 {
00108 m_colorBoxRenderer.m_width = 50;
00109 m_colorBoxRenderer.m_height = m_renderer.height();
00110
00111 m_browser->m_mode.changed_.connect(boost::bind(&FWGeometryTableManager::updateMode,this));
00112 m_browser->m_autoExpand.changed_.connect(boost::bind(&FWGeometryTableManager::updateAutoExpand,this));
00113 m_browser->m_maxDaughters.changed_.connect(boost::bind(&FWGeometryTableManager::updateAutoExpand,this));
00114 m_browser->m_filter.changed_.connect(boost::bind(&FWGeometryTableManager::updateFilter,this));
00115
00116
00117 m_browser->m_maxDaughters.changed_.connect(boost::bind(&FWGeometryTableManager::updateAutoExpand,this));
00118
00119
00120 m_modeVolume = m_browser->m_mode.value();
00121 m_autoExpand = m_browser->m_autoExpand.value();
00122 m_maxDaughters = m_browser->m_maxDaughters.value();
00123 }
00124
00125 FWGeometryTableManager::~FWGeometryTableManager()
00126 {
00127 }
00128
00129
00130 int FWGeometryTableManager::unsortedRowNumber(int unsorted) const
00131 {
00132 return unsorted;
00133 }
00134
00135 int FWGeometryTableManager::numberOfRows() const
00136 {
00137 return m_row_to_index.size();
00138 }
00139
00140 int FWGeometryTableManager::numberOfColumns() const
00141 {
00142 return kNumCol;
00143 }
00144
00145
00146 std::vector<std::string> FWGeometryTableManager::getTitles() const
00147 {
00148 std::vector<std::string> returnValue;
00149 returnValue.reserve(numberOfColumns());
00150
00151 if (m_modeVolume )
00152 returnValue.push_back("Volume Name");
00153 else
00154 returnValue.push_back("Node Name");
00155
00156 returnValue.push_back("Color");
00157 returnValue.push_back("RnrSelf");
00158 returnValue.push_back("RnrChildren");
00159 returnValue.push_back("Material");
00160 returnValue.push_back("Position");
00161 returnValue.push_back("Diagonal");
00162
00163 return returnValue;
00164 }
00165
00166 void FWGeometryTableManager::setSelection (int row, int column, int mask)
00167 {
00168
00169 changeSelection(row, column);
00170 }
00171
00172 const std::string FWGeometryTableManager::title() const
00173 {
00174 return "Geometry";
00175 }
00176
00177 int FWGeometryTableManager::selectedRow() const
00178 {
00179 return m_selectedRow;
00180 }
00181
00182 int FWGeometryTableManager::selectedColumn() const
00183 {
00184 return m_selectedColumn;
00185 }
00186
00187 bool FWGeometryTableManager::rowIsSelected(int row) const
00188 {
00189 return m_selectedRow == row;
00190 }
00191
00192 void FWGeometryTableManager::changeSelection(int iRow, int iColumn)
00193 {
00194 if (iRow < 0) return;
00195 if (iRow == m_selectedRow )
00196 {
00197 m_selectedRow = -1;
00198 m_selectedColumn = -1;
00199 }
00200 else
00201 {
00202 m_selectedRow = iRow;
00203 m_selectedColumn = iColumn;
00204 }
00205 indexSelected_(iRow, iColumn);
00206 visualPropertiesChanged();
00207 }
00208
00209
00210 FWTableCellRendererBase* FWGeometryTableManager::cellRenderer(int iSortedRowNumber, int iCol) const
00211 {
00212 if (static_cast<int>(m_row_to_index.size()) <= iSortedRowNumber)
00213 {
00214 m_renderer.setData(std::string("FWGeometryTableManager::cellRenderer() Error!"), false);
00215 return &m_renderer;
00216 }
00217
00218 FWTextTreeCellRenderer* renderer = &m_renderer;
00219
00220
00221
00222 int unsortedRow = m_row_to_index[iSortedRowNumber];
00223 const NodeInfo& data = m_entries[unsortedRow];
00224 TGeoNode& gn = *data.m_node;
00225
00226 bool isSelected = (!filterOff() && m_volumes[gn.GetVolume()].m_matches);
00227 if (0)
00228 {
00229 TGGC* gc = ( TGGC*)m_renderer.graphicsContext();
00230
00231 if (!filterOff() && m_volumes[gn.GetVolume()].m_matches)
00232 gc->SetForeground(gVirtualX->GetPixel(kRed));
00233 else
00234 gc->SetForeground(gVirtualX->GetPixel(kBlack));
00235 }
00236
00237 if (iCol == kName)
00238 {
00239
00240 int nD = getNdaughtersLimited(data.m_node);
00241 if (m_modeVolume)
00242 renderer->setData(Form("%s [%d]", gn.GetVolume()->GetName(), nD), isSelected);
00243 else
00244 renderer->setData(Form("%s [%d]", gn.GetName(), nD ), isSelected);
00245
00246 renderer->setIsParent((gn.GetNdaughters() > 0) && (filterOff() || m_volumes[gn.GetVolume()].accepted()));
00247
00248
00249 renderer->setIsOpen(data.m_expanded);
00250 if (data.m_node->GetNdaughters())
00251 renderer->setIndentation(10*data.m_level);
00252 else
00253 renderer->setIndentation(10*data.m_level + FWTextTreeCellRenderer::iconWidth());
00254
00255 return renderer;
00256 }
00257 else
00258 {
00259
00260 renderer->setIsParent(false);
00261 renderer->setIndentation(0);
00262 if (iCol == kColor)
00263 {
00264
00265 m_colorBoxRenderer.setData(gn.GetVolume()->GetLineColor(), isSelected);
00266 return &m_colorBoxRenderer;
00267 }
00268 else if (iCol == kVisSelf )
00269 {
00270 renderer->setData( gn.IsVisible() ? "on" : "off", isSelected);
00271 return renderer;
00272 }
00273 else if (iCol == kVisChild )
00274 {
00275 renderer->setData( gn.IsVisDaughters() ? "on" : "off", isSelected);
00276 return renderer;
00277 }
00278 else if (iCol == kMaterial )
00279 {
00280 renderer->setData( gn.GetVolume()->GetMaterial()->GetName(), isSelected);
00281 return renderer;
00282 }
00283 else if (iCol == kPosition )
00284 {
00285 const Double_t* p = gn.GetMatrix()->GetTranslation();
00286 renderer->setData(Form("[%.3f, %.3f, %.3f]", p[0], p[1], p[2]), isSelected);
00287 return renderer;
00288 }
00289 else
00290 {
00291 TGeoBBox* gs = static_cast<TGeoBBox*>( gn.GetVolume()->GetShape());
00292 renderer->setData( Form("%f", TMath::Sqrt(gs->GetDX()*gs->GetDX() + gs->GetDY()*gs->GetDY() +gs->GetDZ()*gs->GetDZ() )), isSelected);
00293 return renderer;
00294 }
00295 }
00296 }
00297
00298 void FWGeometryTableManager::firstColumnClicked(int row)
00299 {
00300 if (row == -1)
00301 return;
00302
00303
00304 int idx = rowToIndex()[row];
00305
00306 Entries_i it = m_entries.begin();
00307 std::advance(it, idx);
00308 NodeInfo& data = *it;
00309 data.m_expanded = !data.m_expanded;
00310 if (data.m_expanded && data.m_imported == false)
00311 {
00312 importChildren(idx, false);
00313 }
00314
00315 recalculateVisibility();
00316 dataChanged();
00317 visualPropertiesChanged();
00318 }
00319
00320 void FWGeometryTableManager::recalculateVisibility()
00321 {
00322 m_row_to_index.clear();
00323
00324 for ( size_t i = 0, e = m_entries.size(); i != e; ++i )
00325 {
00326 NodeInfo &data = m_entries[i];
00327
00328 if (data.m_parent == -1)
00329 {
00330 data.m_visible = true;
00331 }
00332 else
00333 {
00334 data.m_visible = m_entries[data.m_parent].m_expanded && m_entries[data.m_parent].m_visible;
00335 }
00336 }
00337
00338
00339 for (size_t i = 0, e = m_entries.size(); i != e; ++i)
00340 if (m_entries[i].m_visible)
00341 m_row_to_index.push_back(i);
00342
00343
00344 }
00345
00346
00347 void FWGeometryTableManager::redrawTable()
00348 {
00349 changeSelection(-1, -1);
00350 recalculateVisibility();
00351 dataChanged();
00352 visualPropertiesChanged();
00353 }
00354
00355
00356
00357
00358
00359 void FWGeometryTableManager::checkUniqueVolume(TGeoVolume* v)
00360 {
00361 Volumes_i it = m_volumes.find(v);
00362 if (it == m_volumes.end())
00363 {
00364 m_volumes.insert(std::make_pair(v, Match()));
00365 }
00366 for (int i =0, nD = v->GetNdaughters(); i != nD; ++i) {
00367 checkUniqueVolume(v->GetNode(i)->GetVolume());
00368 }
00369 }
00370
00371 void FWGeometryTableManager::loadGeometry(TGeoManager* geoManager)
00372 {
00373 m_geoManager = geoManager;
00374
00375 m_volumes.clear();
00376 checkUniqueVolume(geoManager->GetTopVolume());
00377 if (!filterOff())
00378 updateFilter();
00379
00380 m_browser->updateStatusBar(Form("FWGeometryTableManager::loadGeometry() %d unique volumes", (int)m_volumes.size()));
00381
00382 setTableContent();
00383 }
00384
00385
00386
00387 void FWGeometryTableManager::setTableContent()
00388 {
00389
00390
00391 m_browser->updateStatusBar("Set table content ...");
00392
00393 #ifdef PERFTOOL
00394 if (filterOff())
00395 ProfilerStart(Form("SetTableContent.expand_%d.modeV_%d", m_browser->m_autoExpand.value(), ( m_browser->m_mode.value() == FWGeometryBrowser::kVolume)));
00396 else
00397 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()));
00398
00399 #endif
00400 bool debug = 1;
00401
00402
00403 m_entries.clear();
00404 m_row_to_index.clear();
00405
00406
00407 m_autoExpand = m_browser->m_autoExpand.value();
00408 m_maxDaughters = m_browser->m_maxDaughters.value();
00409 m_modeVolume = m_browser->m_mode.value() == FWGeometryBrowser::kVolume;
00410
00411
00412 NodeInfo topNodeInfo;
00413 topNodeInfo.m_node = m_geoManager->GetTopNode();
00414 topNodeInfo.m_level = 0;
00415 topNodeInfo.m_parent = -1;
00416 m_entries.push_back(topNodeInfo);
00417
00418 importChildren(0, true);
00419
00420 if (debug)
00421 checkHierarchy();
00422
00423 redrawTable();
00424
00425 #ifdef PERFTOOL
00426 ProfilerStop();
00427 #endif
00428
00429 if (filterOff())
00430 {
00431 m_browser->updateStatusBar(Form("%d entries imported ", (int)m_entries.size()));
00432 }
00433 else
00434 {
00435 {
00436
00437 int na = 0;
00438 int n = 0;
00439 for (Volumes_i i = m_volumes.begin(); i!= m_volumes.end(); ++i)
00440 {
00441 n++;
00442 if ( i->second.m_matches)
00443 {
00444 na++;
00445
00446 }
00447 }
00448
00449 m_browser->updateStatusBar(Form("%d entries imported, filter: %d volumes (%.2f %%) selected ", (int)m_entries.size(), na, na*1.f/n));
00450 }
00451 }
00452 }
00453
00454
00455
00456
00457
00458 void
00459 FWGeometryTableManager::getNNodesTotal(TGeoNode* geoNode, int level, int& off, bool debug) const
00460 {
00461
00462
00463 if (debug) printf("getNNodesTotal %s %s (c:%d)\033[22;0m \n", cyanTxt, geoNode->GetName(), level);
00464
00465 int nD = getNdaughtersLimited(geoNode);
00466 std::vector<int> vi; vi.reserve(nD);
00467 vi.reserve(nD);
00468 for (int n = 0; n != nD; ++n)
00469 {
00470 TGeoVolume* vTmp = geoNode->GetDaughter(n)->GetVolume();
00471 if (m_volumes[vTmp].accepted())
00472 {
00473 bool toAdd = true;
00474 if (m_modeVolume)
00475 {
00476 for (std::vector<int>::iterator u = vi.begin(); u != vi.end(); ++u )
00477 {
00478 TGeoVolume* neighbourVolume = geoNode->GetDaughter(*u)->GetVolume();
00479 if (neighbourVolume == vTmp)
00480 {
00481 toAdd = false;
00482 break;
00483 }
00484 }
00485 }
00486 if (toAdd) vi.push_back(n);
00487 }
00488 }
00489
00490 int nV = vi.size();
00491 if (level < m_autoExpand)
00492 {
00493 off += nV;
00494 for (int i = 0; i < nV; ++i )
00495 {
00496 getNNodesTotal(geoNode->GetDaughter(vi[i]), level+1, off, false);
00497 }
00498 if (debug) printf("%d \n", off);
00499 }
00500 }
00501
00502 void FWGeometryTableManager::importChildren(int parent_idx, bool recurse)
00503 {
00504 bool debug = false;
00505
00506 int nEntries = (int)m_entries.size();
00507 assert( parent_idx < nEntries);
00508
00509
00510 NodeInfo& parent = m_entries[parent_idx];
00511 TGeoNode* parentGeoNode = parent.m_node;
00512 int parentLevel = parent.m_level;
00513 if (debug) printf("%s START level[%d] > %s[%d] \033[0m\n" ,greenTxt, parentLevel+1, parentGeoNode->GetName(), parent_idx);
00514
00515 parent.m_expanded = true;
00516
00517
00518 int nD = getNdaughtersLimited(parentGeoNode);
00519 std::vector<int> vi;
00520 vi.reserve(nD);
00521 TGeoVolume* vTmp;
00522
00523 for (int n = 0; n != nD; ++n)
00524 {
00525 vTmp = parentGeoNode->GetDaughter(n)->GetVolume();
00526
00527 if (filterOff() || m_volumes[vTmp].accepted())
00528 {
00529 bool toAdd = true;
00530 if (m_modeVolume)
00531 {
00532
00533 for (std::vector<int>::iterator u = vi.begin(); u != vi.end(); ++u )
00534 {
00535 TGeoVolume* neighbourVolume = parentGeoNode->GetDaughter(*u)->GetVolume();
00536 if (neighbourVolume == vTmp)
00537 {
00538 toAdd = false;
00539 break;
00540 }
00541 }
00542 }
00543 if (toAdd) vi.push_back(n);
00544 }
00545
00546
00547 }
00548 int nV = vi.size();
00549
00550
00551 Entries_i it = m_entries.begin();
00552 std::advance(it, parent_idx+1);
00553 m_entries.insert(it, nV, NodeInfo());
00554 nEntries += nV;
00555 if (debug) printf(" accpted %d of %d entries size %d \n", nV, nD, (int)m_entries.size());
00556
00557
00558 for (int n = 0; n != nV; ++n)
00559 {
00560 int childIdx = vi[n];
00561 NodeInfo &nodeInfo = m_entries[parent_idx + 1 + n ];
00562 nodeInfo.m_node = parentGeoNode->GetDaughter(childIdx);
00563 nodeInfo.m_level = parent.m_level + 1;
00564 nodeInfo.m_parent = parent_idx;
00565 if (debug) printf(" add %s\n", nodeInfo.name());
00566 }
00567
00568 if (recurse)
00569 {
00570
00571 int dOff = 0;
00572 if ((parent.m_level+1) < m_autoExpand)
00573 {
00574 for (int n = 0; n != nV; ++n)
00575 {
00576 importChildren(parent_idx + n + 1 + dOff, recurse);
00577 if (parentGeoNode->GetNdaughters() > 0)
00578 {
00579 getNNodesTotal(parentGeoNode->GetDaughter(vi[n]), parentLevel+1, dOff, debug);
00580 }
00581
00582 }
00583 }
00584 }
00585 else
00586 {
00587
00588 if (debug) printf("\ncheck shhift for level evel %d import %s ", parent.m_level +1,parentGeoNode->GetName() );
00589
00590 for (int i = (parent_idx + nV + 1); i < nEntries; ++i)
00591 {
00592 if (m_entries[i].m_parent > m_entries[parent_idx].m_parent)
00593 {
00594 if (debug) printf("%s %s", redTxt, m_entries[i].name());
00595 m_entries[i].m_parent += nV;
00596
00597 }
00598 }
00599 if (debug) printf(" \033[0m\n");
00600 }
00601
00602
00603 fflush(stdout);
00604 }
00605
00606
00607
00608 void FWGeometryTableManager::checkHierarchy()
00609 {
00610
00611
00612
00613 for ( size_t i = 0, e = m_entries.size(); i != e; ++i )
00614 {
00615 if ( m_entries[i].m_level > 0)
00616 {
00617 TGeoNode* pn = m_entries[m_entries[i].m_parent].m_node;
00618 bool ok = false;
00619 for (int d = 0; d < pn->GetNdaughters(); ++d )
00620 {
00621 if (m_entries[i].m_node == pn->GetDaughter(d))
00622 {
00623 ok = true;
00624 break;
00625 }
00626 }
00627 if (!ok) printf("%s!!!!!! node %s has false parent %s \n", redTxt, m_entries[i].name(), pn->GetName());
00628 }
00629 }
00630 }
00631
00632 void FWGeometryTableManager::checkChildMatches(TGeoVolume* vol, std::vector<TGeoVolume*>& pstack)
00633 {
00634 if (m_volumes[vol].m_matches)
00635 {
00636 for (std::vector<TGeoVolume*>::iterator i = pstack.begin(); i!= pstack.end(); ++i)
00637 {
00638 Match& pm = m_volumes[*i];
00639
00640
00641
00642 pm.m_childMatches = true;
00643 }
00644 }
00645
00646 pstack.push_back(vol);
00647
00648 int nD = TMath::Min(m_maxDaughters, vol->GetNdaughters());
00649 for (int i = 0; i!=nD; ++i)
00650 checkChildMatches(vol->GetNode(i)->GetVolume(), pstack);
00651
00652 pstack.pop_back();
00653 }
00654
00655
00656
00657 void FWGeometryTableManager::updateFilter()
00658 {
00659 if (!m_geoManager) return;
00660
00661 #ifdef PERFTOOL
00662 ProfilerStart(m_browser->m_filter.value().c_str());
00663 #endif
00664
00665 for (Volumes_i i = m_volumes.begin(); i!= m_volumes.end(); ++i)
00666 {
00667 i->second.m_matches = m_browser->m_filter.value().empty() || strstr(i->first->GetMaterial()->GetName(), m_browser->m_filter.value().c_str());
00668 i->second.m_childMatches = false;
00669 }
00670
00671 std::vector<TGeoVolume*> pstack;
00672 checkChildMatches(m_geoManager->GetTopVolume(), pstack);
00673
00674
00675 #ifdef PERFTOOL
00676 ProfilerStop();
00677 #endif
00678 setTableContent();
00679 }
00680
00681 void FWGeometryTableManager::updateAutoExpand()
00682 {
00683 if (!m_geoManager) return;
00684
00685 setTableContent();
00686 }
00687
00688 void FWGeometryTableManager::updateMode()
00689 {
00690 if (!m_geoManager) return;
00691
00692 setTableContent();
00693 }
00694
00695 bool FWGeometryTableManager::filterOff() const
00696 {
00697 return m_browser->m_filter.value().empty();
00698
00699 }