GEMC  1.8
Geant4 Monte-Carlo Framework
detector_tree.cc
Go to the documentation of this file.
1 // %%%%%%%%%%
2 // Qt headers
3 // %%%%%%%%%%
4 #include <QActionGroup>
5 #include <QColorDialog>
6 #include <QMenu>
7 
8 // %%%%%%%%%%%%%
9 // gemc headers
10 // %%%%%%%%%%%%%
11 #include "detector_tree.h"
12 #include "detector_editor.h"
13 #include "MDetectorConstruction.h"
15 #include "usage.h"
16 #include "string_utilities.h"
17 
18 //
19 // %%%%%%%%%%%
20 // C++ headers
21 // %%%%%%%%%%%
22 #include <sys/stat.h>
23 #include <vector>
24 #include <string>
25 
26 detector_tree::detector_tree(map<string, detector> *Map, gemc_opts Opts,
27  G4RunManager* RM, G4VisManager* VM, G4UImanager* UIM,
28  map<string, G4Material*> MMap)
29 {
30  runManager = RM;
31  visManager = VM;
32  UImanager = UIM;
33  Hall_Map = Map;
34  MMats = &MMap;
35 
36  setWindowTitle("Volumes Tree");
37  setGeometry(200, 200, 400, 700);
38 
39  gemcOpt = Opts;
40  createActions();
41 
42  // idea for tree:
43  // gray = present but not visible
44 
45  treeWidget = new QTreeWidget(this);
46  treeWidget->setGeometry(0, 0, 400, 700);
47 
48  treeWidget->setColumnCount(1);
49  QStringList headers;
50  headers << tr("Volumes") ;
51  treeWidget->setHeaderLabels(headers);
52 
53  // in case the geometry changes need to reload the tree
54  // in case it doesn't, no need to load the tree
55  tree_map = read_geometry(treeWidget);
56  treeWidget->setContextMenuPolicy( Qt::ActionsContextMenu );
57  treeWidget-> addAction( Switch_visibility );
58  treeWidget-> addAction( Switch_visibility_daughters );
59  treeWidget-> addAction( Switch_wiresolid );
60  treeWidget-> addAction( Switch_color );
61  treeWidget-> addAction( Edit_Detector );
62  treeWidget-> addAction( Write_GDML_File );
63 }
64 
66 {
67  string hd_msg = gemcOpt.args["LOG_MSG"].args ;
68  double VERB = gemcOpt.args["GEO_VERBOSITY"].arg ;
69  if(VERB>2)
70  cout << hd_msg << " Detector Widget Tree Deleted." << endl;
71 
72  delete Switch_visibility;
73  delete Switch_wiresolid;
74  delete treeWidget;
75 }
76 
77 map<string, tree_item> detector_tree::read_geometry(QTreeWidget *motherWidget)
78 {
79  string hd_msg = gemcOpt.args["LOG_MSG"].args + " Detector Tree >> " ;
80  double VERB = gemcOpt.args["GEO_VERBOSITY"].arg ;
81 
82  map<string, tree_item> tree_map;
83  tree_item item;
84 
85 
86  if(VERB > 2)
87  {
88  cout << endl;
89  cout << hd_msg << " Building Detector Widget Tree from Geometry STL Map..." << endl << endl;
90  cout << hd_msg << " Experimenta Hall has " << Hall_Map->size() << " components." << endl << endl;
91  }
92 
93 
94  // fills the volumes tree map
95  // initialize the Hall_Map member QTreeWidgetItem pointer and built variable to zero
96  for(map<string, detector>::iterator i = Hall_Map->begin(); i != Hall_Map->end(); i++)
97  {
98  item.volume = i->second.name;
99  item.mother = i->second.mother;
100  item.treeItem = NULL;
101  item.scanned = 0;
102  item.sensitive = 0;
103  if(i->second.sensitivity != "no")
104  item.sensitive = 1;
105 
106  item.exist = i->second.exist;
107  item.visible = i->second.visible;
108  item.wiresolid = i->second.style;
109 
110  if(i->second.name != "root" && i->second.GetLogical())
111  {
112  tree_map.insert(map<string, tree_item>::value_type(i->second.name, item));
113  if(VERB > 3) cout << hd_msg << " Mapping Detector " << i->first << endl;
114  }
115  }
116 
117  if(VERB > 3) cout << endl << endl;
118 
119  ActiveGrad = QLinearGradient(QPointF(1, 100), QPointF(180, 70));
120  ActiveGrad.setColorAt(0, QColor( 80, 80, 255));
121  ActiveGrad.setColorAt(1, QColor(245, 245, 245));
122 
123  SensitiveGrad = QLinearGradient(QPointF(1, 100), QPointF(180, 20));
124  SensitiveGrad.setColorAt(0, QColor(255, 80, 80));
125  SensitiveGrad.setColorAt(1, QColor(245, 245, 245));
126 
127  NonActiveGrad = QLinearGradient(QPointF(1, 100), QPointF(10, 30));
128  NonActiveGrad.setColorAt(0, QColor(255, 20, 20));
129  NonActiveGrad.setColorAt(1, QColor(245, 245, 245));
130 
131  NonVisibleGrad = QLinearGradient(QPointF(1, 100), QPointF(60, 30));
132  NonVisibleGrad.setColorAt(0, QColor(5, 5, 5));
133  NonVisibleGrad.setColorAt(1, QColor(240, 240, 240));
134 
135  ActiveBrush = QBrush(ActiveGrad);
136  SensitiveBrush = QBrush(SensitiveGrad);
137  NonActiveBrush = QBrush (NonActiveGrad);
138  NonVisibleBrush = QBrush (NonVisibleGrad);
139 
140 
141  // now build the actual QTreeWidgetItem
142  // if a kid has no mom, its mom will be built first
143  vector<string> relatives;
144  string mom, kid;
145  if(VERB > 2) cout << endl << hd_msg << " Reordering Tree Elements..." << endl << endl;
146  for(map<string, tree_item>::iterator i = tree_map.begin(); i != tree_map.end(); i++)
147  {
148  if(i->first != "" && i->first != "root") relatives.push_back(i->second.volume);
149 
150  while(relatives.size() > 0 && relatives.size() < 100)
151  {
152  mom = tree_map[relatives.back()].mother;
153  kid = tree_map[relatives.back()].volume;
154 
155 
156  if(VERB > 3)
157  {
158  for(unsigned int i=0; i<relatives.size()-1; i++) cout << "\t";
159  cout << hd_msg << " Checking " << kid << ", child of " << mom
160  << ", for a living ancestor. This Geneaology Depth is " << relatives.size() << "." << endl;
161  }
162 
163  // Mom is <root>. Can build the kid.
164  if(tree_map[kid].scanned == 0 && mom.find("root", 0) != string::npos)
165  {
166  if(VERB > 3)
167  {
168  for(unsigned int i=0; i<relatives.size()-1; i++) cout << "\t";
169  cout << hd_msg << " Found: " << relatives.back()
170  << " has <root> as mom and it's not built yet. Building " << kid << "..." << endl;
171  }
172  tree_map[kid].treeItem = new QTreeWidgetItem(motherWidget);
173  tree_map[kid].treeItem->setText(0, kid.c_str());
174  tree_map[kid].scanned = 1;
175  }
176 
177  // Mom (not root) is built, kid not built yet. Build the kid.
178  if(tree_map[kid].scanned == 0 && tree_map[mom].scanned == 1)
179  {
180  if(VERB > 3)
181  {
182  for(unsigned int i=0; i<relatives.size()-1; i++) cout << "\t";
183  cout << hd_msg << " Found: " << kid
184  << " is not built yet but its mommie " << mom << " is. Building " << kid << "..." << endl;
185  }
186 
187  tree_map[kid].treeItem = new QTreeWidgetItem(tree_map[mom].treeItem);
188  tree_map[kid].treeItem->setText(0, kid.c_str());
189  tree_map[kid].scanned = 1;
190  }
191 
192  // if the kid still doesn't exists it means its mom doesn't exist. Need to go up one level.
193  if(tree_map[kid].scanned == 0) relatives.push_back(mom);
194 
195  // the kid has been built. Can go down one step in geneaology
196  if(tree_map[kid].scanned == 1 && relatives.size())
197  {
198  if(VERB > 3)
199  cout << hd_msg << " " << kid << " is built." << endl << endl;
200 
201  if(tree_map[kid].exist == 1) tree_map[kid].treeItem->setBackground(0, ActiveBrush );
202  if(tree_map[kid].exist == 0) tree_map[kid].treeItem->setBackground(0, NonActiveBrush );
203  if(tree_map[kid].visible == 1) tree_map[kid].treeItem->setBackground(0, ActiveBrush );
204  if(tree_map[kid].sensitive == 1) tree_map[kid].treeItem->setBackground(0, SensitiveBrush );
205  if(tree_map[kid].visible == 0) tree_map[kid].treeItem->setBackground(0, NonVisibleBrush );
206  relatives.pop_back();
207  }
208 
209  }
210 
211  }
212 
213  return tree_map;
214 }
215 
216 
217 void detector_tree::switch_visibility()
218 {
219 
220  QTreeWidgetItem *CurrentItem = treeWidget->currentItem();
221  string name = gemc_tostring(CurrentItem->text(0));
222  tree_map[name].visible == 1 ? tree_map[name].visible = 0 : tree_map[name].visible = 1;
223  tree_map[name].visible == 1 ? CurrentItem->setBackground(0, ActiveBrush )
224  : CurrentItem->setBackground(0, NonVisibleBrush);
225  char command[100];
226  sprintf(command, "/vis/geometry/set/visibility %s 0 %d", name.c_str(), tree_map[name].visible);
227  UImanager->ApplyCommand(command);
228 
229  // cout << name << " " << tree_map[name].visible << endl;
230 }
231 
232 void detector_tree::switch_visibility_daughters()
233 {
234  string name = gemc_tostring(treeWidget->currentItem()->text(0));
235  int vis = 0;
236  for(map<string, tree_item>::iterator it = tree_map.begin(); it != tree_map.end(); it++)
237  if(it->second.mother == name)
238  {
239  it->second.visible == 1 ? it->second.visible = 0 : it->second.visible = 1;
240  it->second.visible == 1 ? it->second.treeItem->setBackground(0, ActiveBrush )
241  : it->second.treeItem->setBackground(0, NonVisibleBrush);
242  vis = it->second.visible;
243  }
244 
245  char command[100];
246  sprintf(command, "/vis/geometry/set/daughtersInvisible %s 0 %d", name.c_str(), !vis);
247  UImanager->ApplyCommand(command);
248 
249 }
250 
251 void detector_tree::switch_wiresolid()
252 {
253  string name = gemc_tostring(treeWidget->currentItem()->text(0));
254  tree_map[name].wiresolid == 1 ? tree_map[name].wiresolid = 0 : tree_map[name].wiresolid = 1;
255 
256  char command[100];
257  if( tree_map[name].wiresolid == 1) sprintf(command, "/vis/geometry/set/forceSolid %s 0 1", name.c_str());
258  if( tree_map[name].wiresolid == 0) sprintf(command, "/vis/geometry/set/forceWireframe %s 0 1", name.c_str());
259  UImanager->ApplyCommand(command);
260 }
261 
262 
263 
264 
265 void detector_tree::switch_color()
266 {
267  int r, g, b;
268  string name = gemc_tostring(treeWidget->currentItem()->text(0));
269  QColor color = QColorDialog::getColor(Qt::green, this);
270  color.getRgb(&r, &g, &b);
271  char command[100];
272  sprintf(command, "/vis/geometry/set/colour %s 0 %3.2f %3.2f %3.2f", name.c_str(), r/255.0, g/255.0, b/255.0);
273  UImanager->ApplyCommand(command);
274 }
275 
276 
277 void detector_tree::edit_detector()
278 {
279 
280  string hd_msg = gemcOpt.args["LOG_MSG"].args + " Editor >> " ;
281  string name = gemc_tostring(treeWidget->currentItem()->text(0));
282  detector detect = (*Hall_Map)[name];
283  DetectorEditor detector_editor(&detect, this);
284  detector_editor.exec();
285 
286  // have to overload "=" to make this happen
287  // if((*Hall_Map)[name] != detect)
288  cout << hd_msg << " Old detector: " << (*Hall_Map)[name];
289  (*Hall_Map)[name] = detect;
290  cout << hd_msg << " New detector: " << (*Hall_Map)[name];
291 
292  // need mother to remove it
293  string mother = (*Hall_Map)[name].mother;
294  //(*Hall_Map)[name].create_solid(gemcOpt, Hall_Map);
295  //(*Hall_Map)[name].create_logical_volume(MMats, gemcOpt);
296  //(*Hall_Map)[mother].RemoveDaughter( (*Hall_Map)[name].GetPhysical());
297  //(*Hall_Map)[name].create_physical_volumes(gemcOpt, (*Hall_Map)[mother].GetLogical());
298  (*Hall_Map)[name].SetTranslation(detect.pos);
299 
300 // runManager->DefineWorldVolume( (*Hall_Map)["root"].GetPhysical() );
301 // runManager->GeometryHasBeenModified();
302 
303  char command[100];
304  sprintf(command, "/vis/geometry/set/visibility root 0 0");
305 // sprintf(command, "/vis/geometry/set/visibility %s 0 %d", name.c_str(), 1);
306  UImanager->ApplyCommand(command);
307 
308 }
309 
310 
311 void detector_tree::write_gdml_file()
312 {
313  string name = gemc_tostring(treeWidget->currentItem()->text(0));
314  string fileout=name;
315  detector detect = (*Hall_Map)[name];
316  fileout.append(".gdml");
317  struct stat stFileInfo;
318  if(stat(fileout.c_str(),&stFileInfo)==0) // Check if file exists already.
319  {
320  if(remove(fileout.c_str())){ // Remove file, otherwise parser throws trap.
321  cout << "ERROR -- Could not remove file " << fileout << " cannot write new one.\n";
322  return;
323  }
324  }
325 
326  G4GDMLParser parser;
327  parser.Write(fileout.c_str(),detect.GetPhysical(),false);
328 
329 }
330 
331 
332 void detector_tree::createActions()
333 {
334 
335  // Toggle visibility
336  Switch_visibility = new QAction(tr("&Switch Visibility"), this);
337  Switch_visibility->setShortcut(tr("Ctrl+V"));
338  Switch_visibility->setStatusTip(tr("Switch Visibility"));
339  connect(Switch_visibility, SIGNAL(triggered()), this, SLOT(switch_visibility()));
340 
341  // Toggle daughters' visibility
342  Switch_visibility_daughters = new QAction(tr("&Switch Visibility of Daughters"), this);
343  Switch_visibility_daughters->setShortcut(tr("Ctrl+D"));
344  Switch_visibility_daughters->setStatusTip(tr("Switch Visibility for the daughters"));
345  connect(Switch_visibility_daughters, SIGNAL(triggered()), this, SLOT(switch_visibility_daughters()));
346 
347  // Toggle wireframe/solid
348  Switch_wiresolid = new QAction(tr("&Switch Wireframe / Solid"), this);
349  Switch_wiresolid->setShortcut(tr("Ctrl+W"));
350  Switch_wiresolid->setStatusTip(tr("Switch Wireframe / Solid"));
351  connect(Switch_wiresolid, SIGNAL(triggered()), this, SLOT(switch_wiresolid()));
352 
353  // Pick Volume Color
354  Switch_color = new QAction(tr("&Pick Volume Color"), this);
355  Switch_color->setShortcut(tr("Ctrl+L"));
356  Switch_color->setStatusTip(tr("Pick Volume Color"));
357  connect(Switch_color, SIGNAL(triggered()), this, SLOT(switch_color()));
358 
359  // Edit Detector
360  Edit_Detector = new QAction(tr("&Edit Detector"), this);
361  Edit_Detector->setShortcut(tr("Ctrl+E"));
362  Edit_Detector->setStatusTip(tr("Edit Detector"));
363  connect(Edit_Detector, SIGNAL(triggered()), this, SLOT(edit_detector()));
364 
365  // Write GDML File
366  Write_GDML_File = new QAction(tr("Write GDML File"), this);
367  Write_GDML_File->setShortcut(tr("Ctrl+G"));
368  Write_GDML_File->setStatusTip(tr("Write file name.gdml to current directory"));
369  connect(Write_GDML_File,SIGNAL(triggered()), this, SLOT(write_gdml_file()));
370 
371 }
372 
373 
374 
map< string, tree_item > read_geometry(QTreeWidget *motherWidget)
string volume
Definition: detector_tree.h:43
QBrush NonActiveBrush
Definition: detector_tree.h:81
QLinearGradient NonActiveGrad
Definition: detector_tree.h:76
string gemc_tostring(QString input)
QTreeWidgetItem * treeItem
Definition: detector_tree.h:45
map< string, tree_item > tree_map
Definition: detector_tree.h:70
QBrush ActiveBrush
Definition: detector_tree.h:79
QBrush SensitiveBrush
Definition: detector_tree.h:80
QBrush NonVisibleBrush
Definition: detector_tree.h:82
QLinearGradient NonVisibleGrad
Definition: detector_tree.h:77
map< string, opts > args
Options map.
Definition: usage.h:68
map< string, detector > * Hall_Map
Definition: detector_tree.h:68
G4VPhysicalVolume * GetPhysical()
Returns Physical Volume pointer.
Definition: detector.h:94
QLinearGradient SensitiveGrad
Definition: detector_tree.h:75
gemc_opts gemcOpt
Definition: detector_tree.h:67
double r
Definition: dc12geom.h:54
string mother
Definition: detector_tree.h:44
QLinearGradient ActiveGrad
Definition: detector_tree.h:74
map< string, G4Material * > * MMats
Definition: detector_tree.h:72